perf(composables) : add smart cache to usePieces and useComposants
Align with useProducts pattern: loaded flag, cache-first return, loading guard, and clearCache helper to avoid redundant API calls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -40,11 +40,13 @@ interface LoadComposantsOptions {
|
|||||||
itemsPerPage?: number
|
itemsPerPage?: number
|
||||||
orderBy?: string
|
orderBy?: string
|
||||||
orderDir?: 'asc' | 'desc'
|
orderDir?: 'asc' | 'desc'
|
||||||
|
force?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const composants = ref<Composant[]>([])
|
const composants = ref<Composant[]>([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
const loaded = ref(false)
|
||||||
|
|
||||||
const extractTotal = (payload: unknown, fallbackLength: number): number => {
|
const extractTotal = (payload: unknown, fallbackLength: number): number => {
|
||||||
const p = payload as Record<string, unknown> | null
|
const p = payload as Record<string, unknown> | null
|
||||||
@@ -98,15 +100,31 @@ export function useComposants() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const loadComposants = async (options: LoadComposantsOptions = {}): Promise<ComposantListResult> => {
|
const loadComposants = async (options: LoadComposantsOptions = {}): Promise<ComposantListResult> => {
|
||||||
|
const {
|
||||||
|
search = '',
|
||||||
|
page = 1,
|
||||||
|
itemsPerPage = 30,
|
||||||
|
orderBy = 'name',
|
||||||
|
orderDir = 'asc',
|
||||||
|
force = false,
|
||||||
|
} = options
|
||||||
|
|
||||||
|
if (!force && loaded.value && !search && page === 1) {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: { items: composants.value, total: total.value, page, itemsPerPage },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loading.value) {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: { items: composants.value, total: total.value, page, itemsPerPage },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const {
|
|
||||||
search = '',
|
|
||||||
page = 1,
|
|
||||||
itemsPerPage = 30,
|
|
||||||
orderBy = 'name',
|
|
||||||
orderDir = 'asc',
|
|
||||||
} = options
|
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
params.set('itemsPerPage', String(itemsPerPage))
|
params.set('itemsPerPage', String(itemsPerPage))
|
||||||
@@ -124,6 +142,7 @@ export function useComposants() {
|
|||||||
const enrichedItems = await Promise.all(items.map((item) => withResolvedConstructeurs(item)))
|
const enrichedItems = await Promise.all(items.map((item) => withResolvedConstructeurs(item)))
|
||||||
composants.value = enrichedItems
|
composants.value = enrichedItems
|
||||||
total.value = extractTotal(result.data, items.length)
|
total.value = extractTotal(result.data, items.length)
|
||||||
|
loaded.value = true
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
@@ -216,15 +235,23 @@ export function useComposants() {
|
|||||||
const getComposants = () => composants.value
|
const getComposants = () => composants.value
|
||||||
const isLoading = () => loading.value
|
const isLoading = () => loading.value
|
||||||
|
|
||||||
|
const clearComposantsCache = () => {
|
||||||
|
composants.value = []
|
||||||
|
total.value = 0
|
||||||
|
loaded.value = false
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
composants,
|
composants,
|
||||||
total,
|
total,
|
||||||
loading,
|
loading,
|
||||||
|
loaded,
|
||||||
loadComposants,
|
loadComposants,
|
||||||
createComposant,
|
createComposant,
|
||||||
updateComposant: updateComposantData,
|
updateComposant: updateComposantData,
|
||||||
deleteComposant,
|
deleteComposant,
|
||||||
getComposants,
|
getComposants,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
clearComposantsCache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,11 +41,13 @@ interface LoadPiecesOptions {
|
|||||||
itemsPerPage?: number
|
itemsPerPage?: number
|
||||||
orderBy?: string
|
orderBy?: string
|
||||||
orderDir?: 'asc' | 'desc'
|
orderDir?: 'asc' | 'desc'
|
||||||
|
force?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const pieces = ref<Piece[]>([])
|
const pieces = ref<Piece[]>([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
const loaded = ref(false)
|
||||||
|
|
||||||
const extractTotal = (payload: unknown, fallbackLength: number): number => {
|
const extractTotal = (payload: unknown, fallbackLength: number): number => {
|
||||||
const p = payload as Record<string, unknown> | null
|
const p = payload as Record<string, unknown> | null
|
||||||
@@ -108,15 +110,31 @@ export function usePieces() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const loadPieces = async (options: LoadPiecesOptions = {}): Promise<PieceListResult> => {
|
const loadPieces = async (options: LoadPiecesOptions = {}): Promise<PieceListResult> => {
|
||||||
|
const {
|
||||||
|
search = '',
|
||||||
|
page = 1,
|
||||||
|
itemsPerPage = 30,
|
||||||
|
orderBy = 'name',
|
||||||
|
orderDir = 'asc',
|
||||||
|
force = false,
|
||||||
|
} = options
|
||||||
|
|
||||||
|
if (!force && loaded.value && !search && page === 1) {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: { items: pieces.value, total: total.value, page, itemsPerPage },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loading.value) {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: { items: pieces.value, total: total.value, page, itemsPerPage },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const {
|
|
||||||
search = '',
|
|
||||||
page = 1,
|
|
||||||
itemsPerPage = 30,
|
|
||||||
orderBy = 'name',
|
|
||||||
orderDir = 'asc',
|
|
||||||
} = options
|
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
params.set('itemsPerPage', String(itemsPerPage))
|
params.set('itemsPerPage', String(itemsPerPage))
|
||||||
@@ -134,6 +152,7 @@ export function usePieces() {
|
|||||||
const enrichedItems = await Promise.all(items.map((item) => withResolvedConstructeurs(item)))
|
const enrichedItems = await Promise.all(items.map((item) => withResolvedConstructeurs(item)))
|
||||||
pieces.value = enrichedItems
|
pieces.value = enrichedItems
|
||||||
total.value = extractTotal(result.data, items.length)
|
total.value = extractTotal(result.data, items.length)
|
||||||
|
loaded.value = true
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
@@ -226,15 +245,23 @@ export function usePieces() {
|
|||||||
const getPieces = () => pieces.value
|
const getPieces = () => pieces.value
|
||||||
const isLoading = () => loading.value
|
const isLoading = () => loading.value
|
||||||
|
|
||||||
|
const clearPiecesCache = () => {
|
||||||
|
pieces.value = []
|
||||||
|
total.value = 0
|
||||||
|
loaded.value = false
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pieces,
|
pieces,
|
||||||
total,
|
total,
|
||||||
loading,
|
loading,
|
||||||
|
loaded,
|
||||||
loadPieces,
|
loadPieces,
|
||||||
createPiece,
|
createPiece,
|
||||||
updatePiece: updatePieceData,
|
updatePiece: updatePieceData,
|
||||||
deletePiece,
|
deletePiece,
|
||||||
getPieces,
|
getPieces,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
clearPiecesCache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user