75 lines
2.8 KiB
JavaScript
75 lines
2.8 KiB
JavaScript
/* Spalte "Zeit" der Ticketliste: Arbeitszeit je Ticket, in Bloecken nachgeladen.
|
||
Nur Lesezugriffe. Eine Zelle ohne Ergebnis (laedt noch, Fehler, 0 min, abgeschnitten,
|
||
jenseits der ersten 200 Zeilen) zeigt immer "–", nie eine falsche Zahl. */
|
||
|
||
import { sumWorksheetMinutes } from './worksheetView'
|
||
import { stepLabel } from './timeSteps'
|
||
|
||
export const TIME_BLOCK = 100 // woids je Abfrage
|
||
export const TIME_QUERY_LIMIT = 5000 // Dokumente je Abfrage
|
||
export const TIME_MAX_ROWS = 200 // nur die ersten Zeilen bekommen eine Zeit
|
||
export const TIME_PARALLEL = 3 // gleichzeitige Abfragen
|
||
|
||
export function chunk(list, size) {
|
||
const out = []
|
||
for (let i = 0; i < list.length; i += size) out.push(list.slice(i, i + size))
|
||
return out
|
||
}
|
||
|
||
// Welche woids sind noch zu laden? Erste 200 Zeilen, ohne leere, doppelte und schon bekannte.
|
||
export function planTimeLoad(tickets, known = new Set()) {
|
||
const list = tickets || []
|
||
const seen = new Set()
|
||
const woids = []
|
||
for (const ticket of list.slice(0, TIME_MAX_ROWS)) {
|
||
const woid = String(ticket?.woid ?? '').trim()
|
||
if (!woid || seen.has(woid) || known.has(woid)) continue
|
||
seen.add(woid)
|
||
woids.push(woid)
|
||
}
|
||
return { blocks: chunk(woids, TIME_BLOCK), capped: list.length > TIME_MAX_ROWS }
|
||
}
|
||
|
||
// Minuten je woid eines Blocks. Wurde die Antwort abgeschnitten (Limit erreicht oder
|
||
// mehr Treffer als geliefert), ist keine Summe verlaesslich: null.
|
||
export function blockMinutes(woids, documents, total, limit = TIME_QUERY_LIMIT) {
|
||
const docs = documents || []
|
||
if (docs.length >= limit) return null
|
||
if (typeof total === 'number' && total > docs.length) return null
|
||
const byWoid = new Map()
|
||
for (const doc of docs) {
|
||
const key = String(doc?.woid ?? '').trim()
|
||
if (!byWoid.has(key)) byWoid.set(key, [])
|
||
byWoid.get(key).push(doc)
|
||
}
|
||
return Object.fromEntries(woids.map((woid) => [woid, sumWorksheetMinutes(byWoid.get(woid) || [])]))
|
||
}
|
||
|
||
// Worker-Pool: hoechstens `limit` gleichzeitig, Ergebnisse in Eingabereihenfolge, verwirft nie
|
||
export async function mapLimit(items, limit, fn) {
|
||
const results = new Array(items.length)
|
||
let next = 0
|
||
const worker = async () => {
|
||
while (next < items.length) {
|
||
const index = next
|
||
next += 1
|
||
try {
|
||
results[index] = { ok: true, value: await fn(items[index], index) }
|
||
} catch (error) {
|
||
results[index] = { ok: false, error }
|
||
}
|
||
}
|
||
}
|
||
await Promise.all(Array.from({ length: Math.min(Math.max(1, limit), items.length) }, worker))
|
||
return results
|
||
}
|
||
|
||
export function minutesCellText(ticket, index, byWoid) {
|
||
if (index >= TIME_MAX_ROWS) return '–'
|
||
const woid = String(ticket?.woid ?? '').trim()
|
||
if (!woid) return '–'
|
||
const minutes = byWoid?.get(woid)
|
||
if (typeof minutes !== 'number' || !(minutes > 0)) return '–'
|
||
return stepLabel(minutes)
|
||
}
|