/* 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) }