55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
type DashboardCoreData = {
|
|
createdDocuments: any[]
|
|
incomingInvoices: any[]
|
|
}
|
|
|
|
const CACHE_TTL_MS = 30_000
|
|
|
|
type DashboardCacheEntry = {
|
|
cachedAt: number
|
|
data: DashboardCoreData | null
|
|
pendingRequest: Promise<DashboardCoreData> | null
|
|
}
|
|
|
|
const tenantCaches = new Map<string, DashboardCacheEntry>()
|
|
|
|
/**
|
|
* Bündelt die großen, von mehreren Dashboard-Karten benötigten Abfragen.
|
|
* So werden identische Requests beim parallelen Mounten nur einmal ausgeführt.
|
|
*/
|
|
export const useDashboardData = () => {
|
|
const auth = useAuthStore()
|
|
|
|
const getTenantKey = () => String(auth.activeTenant || auth.activeTenantData?.id || "default")
|
|
|
|
const loadCoreData = async (force = false): Promise<DashboardCoreData> => {
|
|
const tenantKey = getTenantKey()
|
|
const cache = tenantCaches.get(tenantKey) || { cachedAt: 0, data: null, pendingRequest: null }
|
|
tenantCaches.set(tenantKey, cache)
|
|
const cacheIsFresh = cache.data && Date.now() - cache.cachedAt < CACHE_TTL_MS
|
|
|
|
if (!force && cacheIsFresh) return cache.data
|
|
if (!force && cache.pendingRequest) return cache.pendingRequest
|
|
|
|
cache.pendingRequest = Promise.all([
|
|
useEntities("createddocuments").select("*, statementallocations(*), customer(id,name), linkedDocument(*)"),
|
|
useEntities("incominginvoices").select()
|
|
])
|
|
.then(([createdDocuments, incomingInvoices]) => {
|
|
cache.data = {
|
|
createdDocuments: createdDocuments || [],
|
|
incomingInvoices: incomingInvoices || []
|
|
}
|
|
cache.cachedAt = Date.now()
|
|
return cache.data
|
|
})
|
|
.finally(() => {
|
|
cache.pendingRequest = null
|
|
})
|
|
|
|
return cache.pendingRequest
|
|
}
|
|
|
|
return { loadCoreData }
|
|
}
|