import type { QueryClient } from '@tanstack/react-query'; import { WORK_ORDER_STATUS_LABELS, WORK_ORDER_TRANSITIONS, type ChecklistState, type ReportUpsert, type WorkOrderDetail, type WorkOrderStatus, } from '@siop/shared'; import { enfiler, lireFile } from './store'; import { rejouer } from './synchro'; /** Chaque geste terrain = une saisie en file + un patch OPTIMISTE du cache * (le technicien voit son travail tout de suite, même en mode avion — le * cache persisté garde ce patch après redémarrage). En ligne, la file se * vide dans la foulée : le comportement R4.2 est conservé. */ function patchDetail( queryClient: QueryClient, otId: string, patch: (ot: WorkOrderDetail) => WorkOrderDetail, ): void { queryClient.setQueryData(['work-orders', otId], (courant) => courant ? patch(courant) : courant, ); } export function enfilerTransition( queryClient: QueryClient, ot: WorkOrderDetail, to: WorkOrderStatus, ): void { enfiler({ type: 'TRANSITION', otId: ot.id, otReference: ot.reference, libelle: to === 'DONE' ? 'Clôture de l’intervention' : `Passage à « ${WORK_ORDER_STATUS_LABELS[to]} »`, baseUpdatedAt: ot.updatedAt, payload: { to }, }); patchDetail(queryClient, ot.id, (c) => ({ ...c, status: to, allowedTransitions: WORK_ORDER_TRANSITIONS[to], })); void rejouer(queryClient); } export function enfilerCoche( queryClient: QueryClient, ot: WorkOrderDetail, item: { id: string; label: string }, state: ChecklistState, ): void { enfiler({ type: 'COCHE', otId: ot.id, otReference: ot.reference, libelle: `Coche « ${item.label} » → ${state === 'DONE' ? 'fait' : state === 'NA' ? 'N/A' : 'à faire'}`, baseUpdatedAt: ot.updatedAt, payload: { itemId: item.id, state }, }); patchDetail(queryClient, ot.id, (c) => ({ ...c, checklist: c.checklist.map((i) => (i.id === item.id ? { ...i, state } : i)), })); void rejouer(queryClient); } export function enfilerBilan( queryClient: QueryClient, ot: WorkOrderDetail, corps: Omit, labels: Partial>, ): void { enfiler({ type: 'BILAN', otId: ot.id, otReference: ot.reference, libelle: 'Bilan d’intervention codé', baseUpdatedAt: ot.updatedAt, payload: corps, }); patchDetail(queryClient, ot.id, (c) => ({ ...c, report: { note: c.report?.note ?? null, doorState: labels.doorStateId !== undefined ? (labels.doorStateId ?? null) : (c.report?.doorState ?? null), cabinPosition: labels.cabinPositionId !== undefined ? (labels.cabinPositionId ?? null) : (c.report?.cabinPosition ?? null), anomaly: labels.anomalyId !== undefined ? (labels.anomalyId ?? null) : (c.report?.anomaly ?? null), externalCause: labels.externalCauseId !== undefined ? (labels.externalCauseId ?? null) : (c.report?.externalCause ?? null), actionTaken: labels.actionTakenId !== undefined ? (labels.actionTakenId ?? null) : (c.report?.actionTaken ?? null), componentConcerned: labels.componentConcernedId !== undefined ? (labels.componentConcernedId ?? null) : (c.report?.componentConcerned ?? null), }, })); void rejouer(queryClient); } export function enfilerPhoto( queryClient: QueryClient, ot: WorkOrderDetail, fichier: { uri: string; nom: string; mime: string }, ): void { enfiler({ type: 'PHOTO', otId: ot.id, otReference: ot.reference, libelle: `Photo — ${fichier.nom}`, baseUpdatedAt: ot.updatedAt, payload: fichier, }); void rejouer(queryClient); } /** Ce que la file porte encore pour cet OT — chips « en file » des écrans. */ export function saisiesPour(otId: string) { return lireFile().filter((s) => s.otId === otId); }