Tickets: Hooks useWorkorder, Zaehler und Zeitsummen; useWorkorders verwirft veraltete Antworten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0b53fc825a
commit
ab42918bbc
4 files changed
+206
-2
No files matched your search
@@ -0,0 +1,58 @@
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { databases, DATABASE_ID, COLLECTIONS, Query } from '../lib/appwrite'
|
||||
import { planTimeLoad, blockMinutes, mapLimit, TIME_PARALLEL, TIME_QUERY_LIMIT } from '../lib/ticketTimes'
|
||||
|
||||
// Spalte "Zeit" der Ticketliste: Arbeitszeit je woid, in Bloecken nachgeladen (nur Lesen).
|
||||
// byWoid ist eine Map woid -> Minuten (null = nicht zu ermitteln). Sie wird an Ort und Stelle
|
||||
// ergaenzt, `version` zaehlt hoch, wenn sich etwas geaendert hat (fuer useMemo-Abhaengigkeiten).
|
||||
// Der Zwischenspeicher gilt nur fuer die Lebensdauer der Seite: wer von einer Ticketseite
|
||||
// zurueckkehrt, sieht frische Zahlen.
|
||||
export function useTicketMinutes(tickets) {
|
||||
const cache = useRef(new Map())
|
||||
const inFlight = useRef(new Set())
|
||||
const mounted = useRef(true)
|
||||
const [version, setVersion] = useState(0)
|
||||
const [capped, setCapped] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
mounted.current = true
|
||||
return () => { mounted.current = false }
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const byWoid = cache.current
|
||||
const running = inFlight.current
|
||||
// Ein woid, dessen Abfrage noch laeuft, gilt als bekannt (kein Block doppelt anfragen)
|
||||
const known = { has: (woid) => byWoid.has(woid) || running.has(woid) }
|
||||
const plan = planTimeLoad(tickets, known)
|
||||
setCapped(plan.capped)
|
||||
if (plan.blocks.length === 0) return
|
||||
|
||||
for (const block of plan.blocks) {
|
||||
for (const woid of block) running.add(woid)
|
||||
}
|
||||
|
||||
// Auch wenn sich `tickets` inzwischen geaendert hat, wird das Ergebnis eingetragen:
|
||||
// sonst bliebe das woid ungeladen und ohne Abfrage.
|
||||
mapLimit(plan.blocks, TIME_PARALLEL, async (block) => {
|
||||
const response = await databases.listDocuments(DATABASE_ID, COLLECTIONS.WORKSHEETS, [
|
||||
Query.equal('woid', block),
|
||||
Query.select(['woid', 'totalTime', 'supporters', 'isComment']),
|
||||
Query.limit(TIME_QUERY_LIMIT),
|
||||
])
|
||||
return blockMinutes(block, response.documents, response.total)
|
||||
}).then((results) => {
|
||||
results.forEach((result, index) => {
|
||||
const sums = result.ok ? result.value : null
|
||||
if (!sums) console.warn('Zeitsummen nicht geladen:', result.ok ? 'Antwort abgeschnitten' : result.error)
|
||||
for (const woid of plan.blocks[index]) {
|
||||
byWoid.set(woid, sums ? sums[woid] ?? null : null)
|
||||
running.delete(woid)
|
||||
}
|
||||
})
|
||||
if (mounted.current) setVersion((v) => v + 1)
|
||||
})
|
||||
}, [tickets])
|
||||
|
||||
return { byWoid: cache.current, capped, version }
|
||||
}
|
||||
Reference in new issue
Block a user