@flowselections/logistiek-engine 1.0.34 → 1.0.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/dist-lib/components/AfrondWachtrijCard.d.ts +2 -0
  2. package/dist-lib/components/AfrondWachtrijCard.d.ts.map +1 -0
  3. package/dist-lib/components/AfrondWachtrijCard.js +27 -0
  4. package/dist-lib/components/BeladingsafwijkingenCard.d.ts +2 -0
  5. package/dist-lib/components/BeladingsafwijkingenCard.d.ts.map +1 -0
  6. package/dist-lib/components/BeladingsafwijkingenCard.js +44 -0
  7. package/dist-lib/components/FlowCanvas.d.ts +34 -0
  8. package/dist-lib/components/FlowCanvas.d.ts.map +1 -0
  9. package/dist-lib/components/FlowCanvas.js +490 -0
  10. package/dist-lib/components/FlowOrders.d.ts +8 -0
  11. package/dist-lib/components/FlowOrders.d.ts.map +1 -0
  12. package/dist-lib/components/FlowOrders.js +171 -0
  13. package/dist-lib/components/FlowPage.d.ts +2 -0
  14. package/dist-lib/components/FlowPage.d.ts.map +1 -0
  15. package/dist-lib/components/FlowPage.js +310 -0
  16. package/dist-lib/components/GeblokkeerdeOrdersCard.d.ts.map +1 -1
  17. package/dist-lib/components/GeblokkeerdeOrdersCard.js +21 -2
  18. package/dist-lib/components/InklapbaarVenster.d.ts +9 -0
  19. package/dist-lib/components/InklapbaarVenster.d.ts.map +1 -0
  20. package/dist-lib/components/InklapbaarVenster.js +10 -0
  21. package/dist-lib/components/KardekkingCard.d.ts +2 -0
  22. package/dist-lib/components/KardekkingCard.d.ts.map +1 -0
  23. package/dist-lib/components/KardekkingCard.js +29 -0
  24. package/dist-lib/components/LogistiekEnginePage.d.ts.map +1 -1
  25. package/dist-lib/components/LogistiekEnginePage.js +15 -3
  26. package/dist-lib/components/LogistiekEngineQueuePage.d.ts +2 -0
  27. package/dist-lib/components/LogistiekEngineQueuePage.d.ts.map +1 -0
  28. package/dist-lib/components/LogistiekEngineQueuePage.js +13 -0
  29. package/dist-lib/components/NodeTracePanel.d.ts +14 -0
  30. package/dist-lib/components/NodeTracePanel.d.ts.map +1 -0
  31. package/dist-lib/components/NodeTracePanel.js +46 -0
  32. package/dist-lib/components/OrderJourneyBar.d.ts +9 -0
  33. package/dist-lib/components/OrderJourneyBar.d.ts.map +1 -0
  34. package/dist-lib/components/OrderJourneyBar.js +26 -0
  35. package/dist-lib/components/OrderLogboek.d.ts +10 -0
  36. package/dist-lib/components/OrderLogboek.d.ts.map +1 -0
  37. package/dist-lib/components/OrderLogboek.js +92 -0
  38. package/dist-lib/components/OrderStopBanner.d.ts +12 -0
  39. package/dist-lib/components/OrderStopBanner.d.ts.map +1 -0
  40. package/dist-lib/components/OrderStopBanner.js +36 -0
  41. package/dist-lib/components/OrderTraceDetails.d.ts +22 -0
  42. package/dist-lib/components/OrderTraceDetails.d.ts.map +1 -0
  43. package/dist-lib/components/OrderTraceDetails.js +88 -0
  44. package/dist-lib/components/PlanWachtrijPage.d.ts +2 -0
  45. package/dist-lib/components/PlanWachtrijPage.d.ts.map +1 -0
  46. package/dist-lib/components/PlanWachtrijPage.js +99 -0
  47. package/dist-lib/components/PlannerDiffCard.d.ts +2 -0
  48. package/dist-lib/components/PlannerDiffCard.d.ts.map +1 -0
  49. package/dist-lib/components/PlannerDiffCard.js +25 -0
  50. package/dist-lib/components/RegiePage.d.ts.map +1 -1
  51. package/dist-lib/components/RegiePage.js +28 -78
  52. package/dist-lib/components/TaakGezondheidCard.d.ts +2 -0
  53. package/dist-lib/components/TaakGezondheidCard.d.ts.map +1 -0
  54. package/dist-lib/components/TaakGezondheidCard.js +31 -0
  55. package/dist-lib/components/WerktijdenCard.d.ts +2 -0
  56. package/dist-lib/components/WerktijdenCard.d.ts.map +1 -0
  57. package/dist-lib/components/WerktijdenCard.js +37 -0
  58. package/dist-lib/components/WerkwijzeHerindelingCard.d.ts.map +1 -1
  59. package/dist-lib/components/WerkwijzeHerindelingCard.js +100 -6
  60. package/dist-lib/hooks/useAfrondWachtrij.d.ts +28 -0
  61. package/dist-lib/hooks/useAfrondWachtrij.d.ts.map +1 -0
  62. package/dist-lib/hooks/useAfrondWachtrij.js +88 -0
  63. package/dist-lib/hooks/useBeladingsafwijkingen.d.ts +39 -0
  64. package/dist-lib/hooks/useBeladingsafwijkingen.d.ts.map +1 -0
  65. package/dist-lib/hooks/useBeladingsafwijkingen.js +119 -0
  66. package/dist-lib/hooks/useGeblokkeerdeOrders.d.ts +7 -0
  67. package/dist-lib/hooks/useGeblokkeerdeOrders.d.ts.map +1 -1
  68. package/dist-lib/hooks/useGeblokkeerdeOrders.js +28 -2
  69. package/dist-lib/hooks/useLogisticsTrace.d.ts +78 -0
  70. package/dist-lib/hooks/useLogisticsTrace.d.ts.map +1 -0
  71. package/dist-lib/hooks/useLogisticsTrace.js +152 -0
  72. package/dist-lib/hooks/useOrderNodeTrace.d.ts +11 -0
  73. package/dist-lib/hooks/useOrderNodeTrace.d.ts.map +1 -0
  74. package/dist-lib/hooks/useOrderNodeTrace.js +26 -0
  75. package/dist-lib/hooks/useOrderTrace.d.ts +74 -0
  76. package/dist-lib/hooks/useOrderTrace.d.ts.map +1 -0
  77. package/dist-lib/hooks/useOrderTrace.js +134 -0
  78. package/dist-lib/hooks/useOrderVersies.d.ts +47 -0
  79. package/dist-lib/hooks/useOrderVersies.d.ts.map +1 -0
  80. package/dist-lib/hooks/useOrderVersies.js +194 -0
  81. package/dist-lib/hooks/usePlanWachtrij.d.ts +33 -0
  82. package/dist-lib/hooks/usePlanWachtrij.d.ts.map +1 -0
  83. package/dist-lib/hooks/usePlanWachtrij.js +104 -0
  84. package/dist-lib/hooks/useRecalcJob.js +1 -1
  85. package/dist-lib/hooks/useRuleEngine.d.ts +1 -0
  86. package/dist-lib/hooks/useRuleEngine.d.ts.map +1 -1
  87. package/dist-lib/hooks/useRuleEngine.js +1 -0
  88. package/dist-lib/hooks/useShippingNoteDiagnose.d.ts +20 -0
  89. package/dist-lib/hooks/useShippingNoteDiagnose.d.ts.map +1 -0
  90. package/dist-lib/hooks/useShippingNoteDiagnose.js +52 -0
  91. package/dist-lib/hooks/useShippingNoteStatus.d.ts +29 -0
  92. package/dist-lib/hooks/useShippingNoteStatus.d.ts.map +1 -0
  93. package/dist-lib/hooks/useShippingNoteStatus.js +107 -0
  94. package/dist-lib/hooks/useTaakGezondheid.d.ts +16 -0
  95. package/dist-lib/hooks/useTaakGezondheid.d.ts.map +1 -0
  96. package/dist-lib/hooks/useTaakGezondheid.js +43 -0
  97. package/dist-lib/hooks/useWerktijden.d.ts +33 -0
  98. package/dist-lib/hooks/useWerktijden.d.ts.map +1 -0
  99. package/dist-lib/hooks/useWerktijden.js +88 -0
  100. package/dist-lib/hooks/useWerkwijzeStatus.d.ts +12 -1
  101. package/dist-lib/hooks/useWerkwijzeStatus.d.ts.map +1 -1
  102. package/dist-lib/hooks/useWerkwijzeStatus.js +61 -5
  103. package/dist-lib/index.d.ts +23 -0
  104. package/dist-lib/index.d.ts.map +1 -1
  105. package/dist-lib/index.js +23 -0
  106. package/dist-lib/integrations/supabase/auth-middleware.d.ts +4993 -459
  107. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  108. package/dist-lib/integrations/supabase/client.server.d.ts +4993 -459
  109. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  110. package/dist-lib/integrations/supabase/client.server.js +1 -1
  111. package/dist-lib/integrations/supabase/moduleClient.d.ts +4993 -459
  112. package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
  113. package/dist-lib/integrations/supabase/previewAuthStorage.d.ts +1 -1
  114. package/dist-lib/integrations/supabase/previewAuthStorage.d.ts.map +1 -1
  115. package/dist-lib/integrations/supabase/previewAuthStorage.js +8 -1
  116. package/dist-lib/integrations/supabase/types.d.ts +5022 -432
  117. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  118. package/dist-lib/lib/attachAuthToken.js +1 -1
  119. package/dist-lib/lib/bufferDecision.test.d.ts +2 -0
  120. package/dist-lib/lib/bufferDecision.test.d.ts.map +1 -0
  121. package/dist-lib/lib/bufferDecision.test.js +104 -0
  122. package/dist-lib/lib/cartCoverage.functions.d.ts +30820 -0
  123. package/dist-lib/lib/cartCoverage.functions.d.ts.map +1 -0
  124. package/dist-lib/lib/cartCoverage.functions.js +20 -0
  125. package/dist-lib/lib/cartPlanRequests.server.d.ts +1 -1
  126. package/dist-lib/lib/cartPlanRequests.server.d.ts.map +1 -1
  127. package/dist-lib/lib/cartPlanRequests.server.js +49 -8
  128. package/dist-lib/lib/floridayDocuments.functions.d.ts +13623 -21
  129. package/dist-lib/lib/floridayDocuments.functions.d.ts.map +1 -1
  130. package/dist-lib/lib/floridayDocuments.functions.js +5 -5
  131. package/dist-lib/lib/floridayDocuments.server.d.ts +14 -0
  132. package/dist-lib/lib/floridayDocuments.server.d.ts.map +1 -1
  133. package/dist-lib/lib/floridayDocuments.server.js +58 -0
  134. package/dist-lib/lib/floridayGuard.server.d.ts +1 -1
  135. package/dist-lib/lib/floridayGuard.server.d.ts.map +1 -1
  136. package/dist-lib/lib/floridayGuard.server.js +6 -3
  137. package/dist-lib/lib/floridayPush.functions.d.ts +4993 -459
  138. package/dist-lib/lib/floridayPush.functions.d.ts.map +1 -1
  139. package/dist-lib/lib/floridayPush.functions.js +3 -3
  140. package/dist-lib/lib/flowGraph.d.ts +43 -0
  141. package/dist-lib/lib/flowGraph.d.ts.map +1 -0
  142. package/dist-lib/lib/flowGraph.js +153 -0
  143. package/dist-lib/lib/flowJourney.d.ts +40 -0
  144. package/dist-lib/lib/flowJourney.d.ts.map +1 -0
  145. package/dist-lib/lib/flowJourney.js +156 -0
  146. package/dist-lib/lib/flowNodes.d.ts +26 -0
  147. package/dist-lib/lib/flowNodes.d.ts.map +1 -0
  148. package/dist-lib/lib/flowNodes.js +64 -0
  149. package/dist-lib/lib/flowRoute.d.ts +117 -0
  150. package/dist-lib/lib/flowRoute.d.ts.map +1 -0
  151. package/dist-lib/lib/flowRoute.js +583 -0
  152. package/dist-lib/lib/flowTree.d.ts +149 -0
  153. package/dist-lib/lib/flowTree.d.ts.map +1 -0
  154. package/dist-lib/lib/flowTree.js +908 -0
  155. package/dist-lib/lib/foutTekst.d.ts +4 -0
  156. package/dist-lib/lib/foutTekst.d.ts.map +1 -0
  157. package/dist-lib/lib/foutTekst.js +43 -0
  158. package/dist-lib/lib/handlers/index.d.ts +1 -0
  159. package/dist-lib/lib/handlers/index.d.ts.map +1 -1
  160. package/dist-lib/lib/handlers/index.js +1 -0
  161. package/dist-lib/lib/handlers/logistics-shipping-note-now.server.d.ts +3 -0
  162. package/dist-lib/lib/handlers/logistics-shipping-note-now.server.d.ts.map +1 -0
  163. package/dist-lib/lib/handlers/logistics-shipping-note-now.server.js +100 -0
  164. package/dist-lib/lib/handlers/logistics-tick.server.d.ts +2 -0
  165. package/dist-lib/lib/handlers/logistics-tick.server.d.ts.map +1 -1
  166. package/dist-lib/lib/handlers/logistics-tick.server.js +153 -2
  167. package/dist-lib/lib/handlers/logistics-tick.test.d.ts +2 -0
  168. package/dist-lib/lib/handlers/logistics-tick.test.d.ts.map +1 -0
  169. package/dist-lib/lib/handlers/logistics-tick.test.js +63 -0
  170. package/dist-lib/lib/loadCarrierPlanner.d.ts +2 -0
  171. package/dist-lib/lib/loadCarrierPlanner.d.ts.map +1 -1
  172. package/dist-lib/lib/loadCarrierPlanner.js +18 -0
  173. package/dist-lib/lib/loadCarrierPlanning.functions.d.ts +22705 -35
  174. package/dist-lib/lib/loadCarrierPlanning.functions.d.ts.map +1 -1
  175. package/dist-lib/lib/loadCarrierPlanning.functions.js +7 -7
  176. package/dist-lib/lib/loadCarrierPlanning.server.d.ts +33 -12
  177. package/dist-lib/lib/loadCarrierPlanning.server.d.ts.map +1 -1
  178. package/dist-lib/lib/loadCarrierPlanning.server.js +534 -228
  179. package/dist-lib/lib/logisticsPlanner.d.ts.map +1 -1
  180. package/dist-lib/lib/logisticsPlanner.js +14 -2
  181. package/dist-lib/lib/logisticsRecalcJob.functions.d.ts +9082 -14
  182. package/dist-lib/lib/logisticsRecalcJob.functions.d.ts.map +1 -1
  183. package/dist-lib/lib/logisticsRecalcJob.functions.js +4 -4
  184. package/dist-lib/lib/logisticsRecalcJob.server.d.ts.map +1 -1
  185. package/dist-lib/lib/logisticsRecalcJob.server.js +17 -2
  186. package/dist-lib/lib/logisticsRecalculate.functions.d.ts +4993 -459
  187. package/dist-lib/lib/logisticsRecalculate.functions.d.ts.map +1 -1
  188. package/dist-lib/lib/logisticsRecalculate.functions.js +2 -2
  189. package/dist-lib/lib/modulePrompts.d.ts.map +1 -1
  190. package/dist-lib/lib/modulePrompts.js +893 -0
  191. package/dist-lib/lib/nodeTrace.d.ts +65 -0
  192. package/dist-lib/lib/nodeTrace.d.ts.map +1 -0
  193. package/dist-lib/lib/nodeTrace.js +182 -0
  194. package/dist-lib/lib/pickQueueCleanup.server.d.ts +14 -0
  195. package/dist-lib/lib/pickQueueCleanup.server.d.ts.map +1 -0
  196. package/dist-lib/lib/pickQueueCleanup.server.js +80 -0
  197. package/dist-lib/lib/planQueue.server.d.ts.map +1 -1
  198. package/dist-lib/lib/planQueue.server.js +164 -3
  199. package/dist-lib/lib/plannerDiff.d.ts +37 -0
  200. package/dist-lib/lib/plannerDiff.d.ts.map +1 -0
  201. package/dist-lib/lib/plannerDiff.functions.d.ts +30821 -0
  202. package/dist-lib/lib/plannerDiff.functions.d.ts.map +1 -0
  203. package/dist-lib/lib/plannerDiff.functions.js +21 -0
  204. package/dist-lib/lib/plannerDiff.js +74 -0
  205. package/dist-lib/lib/plannerDiff.server.d.ts +5 -0
  206. package/dist-lib/lib/plannerDiff.server.d.ts.map +1 -0
  207. package/dist-lib/lib/plannerDiff.server.js +60 -0
  208. package/dist-lib/lib/plannerDiff.test.d.ts +2 -0
  209. package/dist-lib/lib/plannerDiff.test.d.ts.map +1 -0
  210. package/dist-lib/lib/plannerDiff.test.js +41 -0
  211. package/dist-lib/lib/resolveBuffer.test.d.ts +2 -0
  212. package/dist-lib/lib/resolveBuffer.test.d.ts.map +1 -0
  213. package/dist-lib/lib/resolveBuffer.test.js +38 -0
  214. package/dist-lib/lib/ruleEngineImpact.d.ts.map +1 -1
  215. package/dist-lib/lib/ruleEngineImpact.js +11 -4
  216. package/dist-lib/lib/ruleEngineSchema.d.ts.map +1 -1
  217. package/dist-lib/lib/ruleEngineSchema.js +102 -6
  218. package/dist-lib/lib/ruleEngineWizard.d.ts.map +1 -1
  219. package/dist-lib/lib/ruleEngineWizard.js +3 -1
  220. package/dist-lib/lib/shippingNoteQueue.server.d.ts +18 -0
  221. package/dist-lib/lib/shippingNoteQueue.server.d.ts.map +1 -0
  222. package/dist-lib/lib/shippingNoteQueue.server.js +304 -0
  223. package/dist-lib/lib/stopReden.d.ts +43 -0
  224. package/dist-lib/lib/stopReden.d.ts.map +1 -0
  225. package/dist-lib/lib/stopReden.js +197 -0
  226. package/dist-lib/lib/taskCounts.d.ts +2 -0
  227. package/dist-lib/lib/taskCounts.d.ts.map +1 -0
  228. package/dist-lib/lib/taskCounts.js +15 -0
  229. package/dist-lib/lib/taskCounts.test.d.ts +2 -0
  230. package/dist-lib/lib/taskCounts.test.d.ts.map +1 -0
  231. package/dist-lib/lib/taskCounts.test.js +12 -0
  232. package/dist-lib/lib/trace.server.d.ts +75 -0
  233. package/dist-lib/lib/trace.server.d.ts.map +1 -0
  234. package/dist-lib/lib/trace.server.js +78 -0
  235. package/dist-lib/lib/vakUitleg.d.ts +19 -0
  236. package/dist-lib/lib/vakUitleg.d.ts.map +1 -0
  237. package/dist-lib/lib/vakUitleg.js +133 -0
  238. package/package.json +158 -131
  239. package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts +0 -2
  240. package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts.map +0 -1
  241. package/dist-lib/components/rule-engine/FloridayConnectionBanner.js +0 -41
  242. package/dist-lib/integrations/supabase/client.d.ts +0 -20293
  243. package/dist-lib/integrations/supabase/client.d.ts.map +0 -1
  244. package/dist-lib/integrations/supabase/client.js +0 -13
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { useServerFn } from "@tanstack/react-start";
4
+ import { Badge, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@flowselections/core";
5
+ import { getCartCoverage } from "../lib/cartCoverage.functions";
6
+ const LABEL = {
7
+ gelijk: "Gelijk",
8
+ gelijk_afgerond: "Gelijk (afgerond op fust)",
9
+ verkeerde_karinhoud: "Op verkeerde kar",
10
+ geblokkeerd: "Geblokkeerd",
11
+ geen_kar: "Geen kar",
12
+ echt_verschil: "Echt verschil",
13
+ };
14
+ function Telling({ titel, data }) {
15
+ const keys = Object.keys(LABEL).filter((k) => (data[k] ?? 0) > 0);
16
+ return (_jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-sm font-medium", children: titel }), keys.length === 0 ? (_jsx("p", { className: "text-xs text-muted-foreground", children: "Geen regels." })) : (_jsx("div", { className: "flex flex-wrap gap-2", children: keys.map((k) => (_jsxs(Badge, { variant: k === "gelijk" || k === "gelijk_afgerond" ? "secondary" : "destructive", children: [LABEL[k], ": ", data[k]] }, k))) }))] }));
17
+ }
18
+ export function KardekkingCard() {
19
+ const fetchCoverage = useServerFn(getCartCoverage);
20
+ const { data, isLoading, error } = useQuery({ queryKey: ["kardekking"], queryFn: () => fetchCoverage() });
21
+ if (isLoading)
22
+ return _jsx(Skeleton, { className: "h-24 w-full" });
23
+ if (error || !data)
24
+ return _jsx("p", { className: "text-sm text-destructive", children: "Kon de controle niet ophalen." });
25
+ const lijst = Array.isArray(data.afwijkingen) ? data.afwijkingen : [];
26
+ return (_jsxs("div", { className: "space-y-4", children: [_jsx(Telling, { titel: "Lopende orders", data: data.lopend }), _jsx(Telling, { titel: "Afgehandelde orders", data: data.afgehandeld }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Regels met een dubbel product op dezelfde order: ", data.dubbeleRegels, " (opgelost via de Verkoop-module)."] }), lijst.length > 0 && (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Order" }), _jsx(TableHead, { children: "Uitkomst" }), _jsx(TableHead, { className: "text-right", children: "Besteld" }), _jsx(TableHead, { className: "text-right", children: "Op kar" }), _jsx(TableHead, { children: "Opmerking" })] }) }), _jsx(TableBody, { children: lijst.slice(0, 200).map((r, i) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: r.order }), _jsx(TableCell, { children: LABEL[r.klasse] ?? r.klasse }), _jsx(TableCell, { className: "text-right", children: r.besteld ?? "—" }), _jsx(TableCell, { className: "text-right", children: r.planten ?? "—" }), _jsx(TableCell, { className: "text-xs text-muted-foreground", children: [r.afgehandeld ? "afgehandeld" : null, r.dubbel ? "dubbele regel" : null, r.blokkade]
27
+ .filter(Boolean)
28
+ .join(" · ") })] }, `${r.order}-${i}`))) })] }))] }));
29
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"LogistiekEnginePage.d.ts","sourceRoot":"","sources":["../../src/components/LogistiekEnginePage.tsx"],"names":[],"mappings":"AAuEA,wBAAgB,mBAAmB,gCAkPlC"}
1
+ {"version":3,"file":"LogistiekEnginePage.d.ts","sourceRoot":"","sources":["../../src/components/LogistiekEnginePage.tsx"],"names":[],"mappings":"AAuFA,wBAAgB,mBAAmB,gCAgPlC"}
@@ -7,11 +7,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
7
  // ============================================================================
8
8
  import { useState } from "react";
9
9
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Badge, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Skeleton, } from "@flowselections/core";
10
- import { Container, Pencil, Plus, Puzzle, SlidersHorizontal, Trash2, Workflow } from "lucide-react";
10
+ import { Container, GitBranch, ListChecks, Pencil, Plus, Puzzle, SlidersHorizontal, Trash2, Workflow } from "lucide-react";
11
11
  import { Link } from "@tanstack/react-router";
12
12
  import { StrategieDialog } from "./StrategieDialog";
13
13
  import { WerkwijzeHerindelingCard } from "./WerkwijzeHerindelingCard";
14
- import { FloridayPoortCard } from "./FloridayPoortCard";
14
+ import { WerktijdenCard } from "./WerktijdenCard";
15
15
  import { useLogistiekStrategieen, } from "../hooks/useLogistiekStrategieen";
16
16
  const SNELKOPPELINGEN = [
17
17
  {
@@ -20,6 +20,18 @@ const SNELKOPPELINGEN = [
20
20
  titel: "Werkwijze instellen",
21
21
  uitleg: "Bepaal stap voor stap hoe orders worden verzameld, gepickt en klaargezet.",
22
22
  },
23
+ {
24
+ to: "/logistiek-engine/flow",
25
+ icon: GitBranch,
26
+ titel: "Flow",
27
+ uitleg: "Volg per order de reis door de flow en pas de werkwijze aan.",
28
+ },
29
+ {
30
+ to: "/logistiek-engine/wachtrij",
31
+ icon: ListChecks,
32
+ titel: "Wachtrij",
33
+ uitleg: "Orders die nog een karrenindeling moeten krijgen, opnieuw proberen of resetten.",
34
+ },
23
35
  {
24
36
  to: "/logistiek-engine/regie",
25
37
  icon: Workflow,
@@ -64,7 +76,7 @@ export function LogistiekEnginePage() {
64
76
  setEditing(item);
65
77
  setDialogOpen(true);
66
78
  };
67
- return (_jsxs("main", { className: "p-6 space-y-6", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: "Hier bepaal je hoe orders in je bedrijf logistiek worden afgehandeld." }), _jsx("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-4", children: SNELKOPPELINGEN.map(({ to, icon: Icon, titel, uitleg }) => (_jsx(Link, { to: to, className: "group", children: _jsx(Card, { className: "h-full transition-colors group-hover:border-primary", children: _jsxs(CardHeader, { className: "p-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary", children: _jsx(Icon, { className: "h-4 w-4" }) }), _jsx(CardTitle, { className: "text-sm font-semibold leading-tight", children: titel })] }), _jsx(CardDescription, { className: "pt-1 text-xs leading-relaxed", children: uitleg })] }) }) }, to))) }), _jsx(WerkwijzeHerindelingCard, {}), _jsx(FloridayPoortCard, {}), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx(CardTitle, { children: "Werkwijzen" }), _jsx(CardDescription, { children: "Alleen een werkwijze die aan staat wordt op je orders toegepast." })] }), _jsxs(Button, { size: "sm", onClick: openNew, children: [_jsx(Plus, { className: "h-4 w-4" }), "Nieuwe werkwijze"] })] }) }), _jsx(CardContent, { children: loading ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-8 w-full" }), _jsx(Skeleton, { className: "h-8 w-full" }), _jsx(Skeleton, { className: "h-8 w-full" })] })) : error ? (_jsx("p", { className: "text-sm text-destructive", children: "Kon de gegevens niet ophalen. Probeer het over een moment opnieuw." })) : safeItems.length === 0 ? (_jsxs("div", { className: "space-y-3", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: "Je hebt nog geen werkwijze ingesteld." }), _jsxs(Button, { variant: "outline", size: "sm", onClick: openNew, children: [_jsx(Plus, { className: "h-4 w-4" }), "Eerste werkwijze aanmaken"] })] })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Naam" }), _jsx(TableHead, { children: "Status" }), _jsx(TableHead, { className: "w-48 text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: safeItems.map((item) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "h-3 w-3 shrink-0 rounded-full border border-border", style: { backgroundColor: item.color ?? "#3b82f6" } }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: item.name ?? "—" }), item.description && (_jsx("p", { className: "text-xs text-muted-foreground", children: item.description }))] })] }) }), _jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx("input", { type: "radio", name: "actieve-werkwijze", className: "h-4 w-4 accent-primary", checked: !!item.is_active, disabled: saving, onChange: () => kiesWerkwijze(item), "aria-label": `${item.name ?? "Werkwijze"} als actieve werkwijze kiezen` }), _jsx("span", { className: "sr-only", children: "Actief" })] }), _jsx(Badge, { variant: item.is_active ? "default" : "secondary", children: item.is_active ? "Actief" : "Uit" }), item.is_active && (_jsx(Button, { size: "sm", variant: "ghost", disabled: saving, onClick: () => void clearActive(), children: "Uitzetten" }))] }) }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsxs(Link, { to: "/logistiek-engine/rule-engine", search: { strategy: String(item.id), naam: item.name ?? "" }, children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Instellen"] }) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: () => openEdit(item), "aria-label": "Bewerken", children: _jsx(Pencil, { className: "h-4 w-4" }) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: () => setDeleting(item), "aria-label": "Verwijderen", children: _jsx(Trash2, { className: "h-4 w-4" }) })] }) })] }, String(item.id)))) })] })) })] }), _jsx(StrategieDialog, { open: dialogOpen, onOpenChange: setDialogOpen, strategie: editing, saving: saving, onSubmit: (input) => (editing ? update(editing.id, input) : create(input)) }), _jsx(AlertDialog, { open: !!deleting, onOpenChange: (open) => !open && setDeleting(null), children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Werkwijze verwijderen?" }), _jsxs(AlertDialogDescription, { children: ["\"", deleting?.name, "\" wordt definitief verwijderd. Dit kan niet ongedaan worden gemaakt."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Annuleren" }), _jsx(AlertDialogAction, { onClick: async () => {
79
+ return (_jsxs("main", { className: "p-6 space-y-6", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: "Hier bepaal je hoe orders in je bedrijf logistiek worden afgehandeld." }), _jsx("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-4", children: SNELKOPPELINGEN.map(({ to, icon: Icon, titel, uitleg }) => (_jsx(Link, { to: to, className: "group", children: _jsx(Card, { className: "h-full transition-colors group-hover:border-primary", children: _jsxs(CardHeader, { className: "p-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary", children: _jsx(Icon, { className: "h-4 w-4" }) }), _jsx(CardTitle, { className: "text-sm font-semibold leading-tight", children: titel })] }), _jsx(CardDescription, { className: "pt-1 text-xs leading-relaxed", children: uitleg })] }) }) }, to))) }), _jsx(WerkwijzeHerindelingCard, {}), _jsx(WerktijdenCard, {}), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx(CardTitle, { children: "Werkwijzen" }), _jsx(CardDescription, { children: "Alleen een werkwijze die aan staat wordt op je orders toegepast." })] }), _jsxs(Button, { size: "sm", onClick: openNew, children: [_jsx(Plus, { className: "h-4 w-4" }), "Nieuwe werkwijze"] })] }) }), _jsx(CardContent, { children: loading ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-8 w-full" }), _jsx(Skeleton, { className: "h-8 w-full" }), _jsx(Skeleton, { className: "h-8 w-full" })] })) : error ? (_jsx("p", { className: "text-sm text-destructive", children: "Kon de gegevens niet ophalen. Probeer het over een moment opnieuw." })) : safeItems.length === 0 ? (_jsxs("div", { className: "space-y-3", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: "Je hebt nog geen werkwijze ingesteld." }), _jsxs(Button, { variant: "outline", size: "sm", onClick: openNew, children: [_jsx(Plus, { className: "h-4 w-4" }), "Eerste werkwijze aanmaken"] })] })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Naam" }), _jsx(TableHead, { children: "Status" }), _jsx(TableHead, { className: "w-48 text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: safeItems.map((item) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "h-3 w-3 shrink-0 rounded-full border border-border", style: { backgroundColor: item.color ?? "#3b82f6" } }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: item.name ?? "—" }), item.description && (_jsx("p", { className: "text-xs text-muted-foreground", children: item.description }))] })] }) }), _jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx("input", { type: "radio", name: "actieve-werkwijze", className: "h-4 w-4 accent-primary", checked: !!item.is_active, disabled: saving, onChange: () => kiesWerkwijze(item), "aria-label": `${item.name ?? "Werkwijze"} als actieve werkwijze kiezen` }), _jsx("span", { className: "sr-only", children: "Actief" })] }), _jsx(Badge, { variant: item.is_active ? "default" : "secondary", children: item.is_active ? "Actief" : "Uit" }), item.is_active && (_jsx(Button, { size: "sm", variant: "ghost", disabled: saving, onClick: () => void clearActive(), children: "Uitzetten" }))] }) }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsxs(Link, { to: "/logistiek-engine/rule-engine", search: { strategy: String(item.id), naam: item.name ?? "" }, children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Instellen"] }) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: () => openEdit(item), "aria-label": "Bewerken", children: _jsx(Pencil, { className: "h-4 w-4" }) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: () => setDeleting(item), "aria-label": "Verwijderen", children: _jsx(Trash2, { className: "h-4 w-4" }) })] }) })] }, String(item.id)))) })] })) })] }), _jsx(StrategieDialog, { open: dialogOpen, onOpenChange: setDialogOpen, strategie: editing, saving: saving, onSubmit: (input) => (editing ? update(editing.id, input) : create(input)) }), _jsx(AlertDialog, { open: !!deleting, onOpenChange: (open) => !open && setDeleting(null), children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Werkwijze verwijderen?" }), _jsxs(AlertDialogDescription, { children: ["\"", deleting?.name, "\" wordt definitief verwijderd. Dit kan niet ongedaan worden gemaakt."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Annuleren" }), _jsx(AlertDialogAction, { onClick: async () => {
68
80
  if (deleting)
69
81
  await remove(deleting.id);
70
82
  setDeleting(null);
@@ -0,0 +1,2 @@
1
+ export declare function LogistiekEngineQueuePage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=LogistiekEngineQueuePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogistiekEngineQueuePage.d.ts","sourceRoot":"","sources":["../../src/components/LogistiekEngineQueuePage.tsx"],"names":[],"mappings":"AAWA,wBAAgB,wBAAwB,gCAYvC"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/LogistiekEngineQueuePage.tsx — Queue: de volledige orderflow
4
+ // ============================================================================
5
+ // Gebruikt hetzelfde orderlogboek als het overzicht, zodat er één weergave is.
6
+ // GEEN <Header /> hier — die levert de shell.
7
+ // ============================================================================
8
+ import { OrderLogboek } from "./OrderLogboek";
9
+ import { AfrondWachtrijCard } from "./AfrondWachtrijCard";
10
+ import { TaakGezondheidCard } from "./TaakGezondheidCard";
11
+ export function LogistiekEngineQueuePage() {
12
+ return (_jsxs("div", { className: "space-y-4 p-4", children: [_jsx(AfrondWachtrijCard, {}), _jsx(TaakGezondheidCard, {}), _jsx(OrderLogboek, { titel: "Queue \u2014 volledige orderflow", omschrijving: "Per order precies wat de Logistiek Engine heeft gedaan, waarom, en wat er is gewijzigd. Alleen echt vastgelegde stappen; er wordt niets aangevuld." })] }));
13
+ }
@@ -0,0 +1,14 @@
1
+ import { type NodeTraceGroep } from "../lib/nodeTrace";
2
+ import type { StopReden } from "../lib/stopReden";
3
+ interface Props {
4
+ groep: NodeTraceGroep;
5
+ /** Gevuld als de reis van de order bij dit vakje ophoudt. */
6
+ stop?: StopReden | null;
7
+ orderLabel: string | null;
8
+ debug: boolean;
9
+ onDebug: (aan: boolean) => void;
10
+ onClose: () => void;
11
+ }
12
+ export declare function NodeTracePanel({ groep, stop, orderLabel, debug, onDebug, onClose }: Props): import("react").JSX.Element;
13
+ export {};
14
+ //# sourceMappingURL=NodeTracePanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeTracePanel.d.ts","sourceRoot":"","sources":["../../src/components/NodeTracePanel.tsx"],"names":[],"mappings":"AAcA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAYlD,UAAU,KAAK;IACb,KAAK,EAAE,cAAc,CAAC;IACtB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAChC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA+CD,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,IAAW,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,+BA0LhG"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/NodeTracePanel.tsx — wat er in dit vakje met de order gebeurde
4
+ // ============================================================================
5
+ // Klik je op een vakje van de flowkaart, dan staat hier eerst een korte
6
+ // samenvatting van de besluitvorming, en daarna alleen de gebeurtenissen die
7
+ // bij dit vakje horen. Automatische database-regels worden gebundeld.
8
+ // Alleen lezen.
9
+ // ============================================================================
10
+ import { useMemo, useState } from "react";
11
+ import { Badge, Button } from "@flowselections/core";
12
+ import { ChevronDown, ChevronRight, X } from "lucide-react";
13
+ import { flowNodeLabel } from "../lib/flowNodes";
14
+ import { bundelGebeurtenissen, samenvatVak, } from "../lib/nodeTrace";
15
+ import { vakUitleg } from "../lib/vakUitleg";
16
+ import { FOUTSOORT_LABEL, FOUTSOORT_UITLEG, STATUS_KLEUR, Stap, Veld, duur, tijd, } from "./OrderTraceDetails";
17
+ const EERSTE_AANTAL = 20;
18
+ function Bundel({ item, debug }) {
19
+ const [open, setOpen] = useState(false);
20
+ const [toon, setToon] = useState(10);
21
+ const items = Array.isArray(item.events) ? item.events : [];
22
+ return (_jsxs("div", { className: "rounded-lg border bg-muted/30", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-start gap-3 p-3 text-left", children: [open ? (_jsx(ChevronDown, { className: "mt-1 h-4 w-4 shrink-0" })) : (_jsx(ChevronRight, { className: "mt-1 h-4 w-4 shrink-0" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium", children: item.label }), _jsxs(Badge, { variant: "outline", children: [item.aantal, "x"] })] }), _jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: ["Automatische gegevenswijziging \u00B7 laatste ", tijd(item.laatste)] })] })] }), open ? (_jsxs("div", { className: "space-y-2 border-t px-3 py-3", children: [items.slice(0, toon).map((e) => (_jsx(Stap, { e: e, debug: debug }, e.id))), items.length > toon ? (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => setToon((n) => n + 25), children: ["Toon meer (", items.length - toon, ")"] })) : null] })) : null] }));
23
+ }
24
+ export function NodeTracePanel({ groep, stop = null, orderLabel, debug, onDebug, onClose }) {
25
+ const events = Array.isArray(groep.events) ? groep.events : [];
26
+ const [toon, setToon] = useState(EERSTE_AANTAL);
27
+ const samenvatting = useMemo(() => samenvatVak(groep), [groep]);
28
+ const uitleg = useMemo(() => vakUitleg(groep), [groep]);
29
+ const regels = useMemo(() => (debug ? [] : bundelGebeurtenissen(events)), [events, debug]);
30
+ const ruw = useMemo(() => (debug ? [...events].sort((a, b) => (a.createdAt < b.createdAt ? 1 : -1)) : []), [events, debug]);
31
+ const zichtbaar = debug ? ruw.slice(0, toon) : regels.slice(0, toon);
32
+ const totaal = debug ? ruw.length : regels.length;
33
+ const calc = samenvatting.berekening;
34
+ return (_jsxs("div", { className: "pointer-events-auto absolute right-3 top-16 bottom-16 z-30 flex w-[26rem] max-w-[90%] flex-col rounded-xl border border-border bg-background shadow-xl", children: [_jsxs("div", { className: "flex items-start justify-between gap-2 border-b border-border px-3 py-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "truncate text-sm font-semibold", children: flowNodeLabel(groep.nodeId) }), _jsx("p", { className: "truncate text-xs text-muted-foreground", children: orderLabel ?? "Order" })] }), _jsx(Button, { variant: "ghost", size: "icon", "aria-label": "Sluiten", onClick: onClose, children: _jsx(X, { className: "h-4 w-4" }) })] }), _jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [stop ? (_jsxs("div", { className: `border-b px-3 py-3 ${stop.soort === "mislukt"
35
+ ? "border-destructive/40 bg-destructive/5"
36
+ : stop.soort === "klaar"
37
+ ? "border-border bg-primary/5"
38
+ : stop.soort === "nietvastgelegd"
39
+ ? "border-border bg-muted/40"
40
+ : "border-amber-500/40 bg-amber-500/5"}`, children: [_jsx("p", { className: "text-sm font-semibold", children: stop.titel }), _jsx("p", { className: "mt-1 text-sm", children: stop.reden }), stop.feiten.length > 0 ? (_jsx("ul", { className: "mt-2 space-y-0.5 text-xs text-muted-foreground", children: stop.feiten.map((f) => (_jsx("li", { children: f }, f))) })) : null, stop.volgendeStap ? (_jsxs("p", { className: "mt-2 text-xs text-muted-foreground", children: ["Wat er moet gebeuren: ", stop.volgendeStap] })) : null, stop.verouderd ? (_jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Let op: een instelling is sindsdien gewijzigd, de route kan daardoor afwijken." })) : null] })) : null, _jsxs("div", { className: "space-y-2 border-b border-border px-3 py-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Badge, { className: STATUS_KLEUR[groep.status] ?? "", children: groep.status }), samenvatting.errorClass ? (_jsx(Badge, { variant: "outline", children: FOUTSOORT_LABEL[samenvatting.errorClass] ?? samenvatting.errorClass })) : null] }), _jsxs("div", { className: "space-y-1", children: [_jsx(Veld, { label: "Beslissing", children: uitleg.beslissing }), _jsx(Veld, { label: "Waarom", children: uitleg.waarom }), uitleg.feiten.length > 0 ? (_jsx(Veld, { label: "Bepalend", children: _jsx("span", { className: "block", children: uitleg.feiten.map((f) => (_jsx("span", { className: "block", children: f }, f))) }) })) : null, _jsx(Veld, { label: "Regel", children: uitleg.regel ?? samenvatting.regel }), _jsx(Veld, { label: "Hierna", children: samenvatting.volgendeStap }), uitleg.afgeleid ? (_jsx("p", { className: "text-xs text-muted-foreground", children: "Afgeleid uit de registraties: de Engine legde hier nog geen besluit met reden vast." })) : null] }), calc ? (_jsxs("div", { className: "rounded-md border bg-muted/40 p-2", children: [_jsx("p", { className: "text-sm font-medium", children: "Berekening" }), _jsx(Veld, { label: "Instelling", children: calc.setting }), _jsx(Veld, { label: "Rekenstap", children: calc.formula }), _jsx(Veld, { label: "Uitkomst", children: calc.result }), _jsx(Veld, { label: "Conclusie", children: calc.conclusion })] })) : null, samenvatting.fout ? (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 p-2", children: [_jsx(Veld, { label: "Fout", children: samenvatting.fout }), _jsx(Veld, { label: "Uitleg", children: samenvatting.errorClass ? FOUTSOORT_UITLEG[samenvatting.errorClass] ?? null : null })] })) : null, _jsxs("div", { className: "space-y-1", children: [_jsx(Veld, { label: "Eerste", children: tijd(groep.eerste) }), _jsx(Veld, { label: "Laatste", children: tijd(groep.laatste) }), _jsx(Veld, { label: "Totale duur", children: groep.duurMs === null ? null : duur(groep.duurMs) }), _jsx(Veld, { label: "Pogingen", children: samenvatting.pogingen > 0 ? String(samenvatting.pogingen) : null }), _jsx(Veld, { label: "Volgende poging", children: samenvatting.volgendePoging ? tijd(samenvatting.volgendePoging) : null })] }), _jsxs("p", { className: "text-xs text-muted-foreground", children: [samenvatting.aantalBeslissingen, " beslismoment", samenvatting.aantalBeslissingen === 1 ? "" : "en", " van de Engine", samenvatting.aantalAutomatisch > 0
41
+ ? ` · ${samenvatting.aantalAutomatisch} automatische gegevenswijziging${samenvatting.aantalAutomatisch === 1 ? "" : "en"}`
42
+ : ""] })] }), _jsxs("div", { className: "flex items-center justify-between px-3 py-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Stappen in dit vakje" }), _jsx(Button, { size: "sm", variant: debug ? "default" : "outline", onClick: () => {
43
+ setToon(EERSTE_AANTAL);
44
+ onDebug(!debug);
45
+ }, children: "Technische details" })] }), _jsxs("div", { className: "space-y-2 px-3 pb-3", children: [totaal === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog niets vastgelegd in dit vakje." })) : debug ? (zichtbaar.map((e) => _jsx(Stap, { e: e, debug: true }, e.id))) : (zichtbaar.map((item) => item.event ? (_jsx(Stap, { e: item.event, debug: false }, item.key)) : (_jsx(Bundel, { item: item, debug: false }, item.key)))), totaal > toon ? (_jsxs(Button, { size: "sm", variant: "outline", className: "w-full", onClick: () => setToon((n) => n + EERSTE_AANTAL), children: ["Toon meer (", totaal - toon, ")"] })) : null] })] })] }));
46
+ }
@@ -0,0 +1,9 @@
1
+ import type { NodeTraceGroep } from "../lib/nodeTrace";
2
+ interface Props {
3
+ reis: NodeTraceGroep[];
4
+ actiefNodeId: string | null;
5
+ onKies: (nodeId: string) => void;
6
+ }
7
+ export declare function OrderJourneyBar({ reis, actiefNodeId, onKies }: Props): import("react").JSX.Element | null;
8
+ export {};
9
+ //# sourceMappingURL=OrderJourneyBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrderJourneyBar.d.ts","sourceRoot":"","sources":["../../src/components/OrderJourneyBar.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,UAAU,KAAK;IACb,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,KAAK,sCAsCpE"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/OrderJourneyBar.tsx — de reis van de order als balk
4
+ // ============================================================================
5
+ // Elk vakje dat de order echt gepasseerd is, op volgorde van tijd. Klikken
6
+ // opent datzelfde vakje op de kaart. Alleen lezen.
7
+ // ============================================================================
8
+ import { AlertTriangle, CheckCircle2, ChevronRight, Clock } from "lucide-react";
9
+ import { flowNodeLabel } from "../lib/flowNodes";
10
+ import { duur, klok } from "./OrderTraceDetails";
11
+ export function OrderJourneyBar({ reis, actiefNodeId, onKies }) {
12
+ const veilig = Array.isArray(reis) ? reis : [];
13
+ if (veilig.length === 0)
14
+ return null;
15
+ return (_jsxs("div", { className: "flex flex-wrap items-center gap-1 rounded-lg border border-border bg-background px-2 py-2", children: [_jsx("span", { className: "mr-1 text-xs font-medium text-muted-foreground", children: "Reis van de order:" }), veilig.map((g, i) => {
16
+ const fout = g.status === "mislukt";
17
+ const wacht = g.status === "wachtend" || g.status === "waarschuwing";
18
+ const Icoon = fout ? AlertTriangle : wacht ? Clock : CheckCircle2;
19
+ const actief = g.nodeId === actiefNodeId;
20
+ return (_jsxs("span", { className: "flex items-center gap-1", children: [i > 0 && _jsx(ChevronRight, { className: "h-3 w-3 text-muted-foreground" }), _jsxs("button", { type: "button", onClick: () => onKies(g.nodeId), className: `flex items-center gap-1 rounded-md border px-2 py-1 text-[11px] ${fout
21
+ ? "border-destructive/50 bg-destructive/10 text-destructive"
22
+ : wacht
23
+ ? "border-amber-500/50 bg-amber-500/10 text-amber-700 dark:text-amber-300"
24
+ : "border-border bg-muted/40 text-foreground"} ${actief ? "ring-2 ring-primary" : ""}`, title: g.reden ?? undefined, children: [_jsx(Icoon, { className: "h-3 w-3" }), _jsx("span", { className: "max-w-[10rem] truncate font-medium", children: flowNodeLabel(g.nodeId) }), _jsx("span", { className: "text-muted-foreground", children: klok(g.eerste) }), g.duurMs !== null && _jsxs("span", { className: "text-muted-foreground", children: ["\u00B7 ", duur(g.duurMs)] }), g.aantal > 1 && _jsxs("span", { className: "text-muted-foreground", children: ["\u00B7 ", g.aantal, "\u00D7"] })] })] }, g.nodeId));
25
+ })] }));
26
+ }
@@ -0,0 +1,10 @@
1
+ import { type TraceEventRow } from "../hooks/useLogisticsTrace";
2
+ export declare function Gebeurtenis({ event }: {
3
+ event: TraceEventRow;
4
+ }): import("react").JSX.Element;
5
+ export interface OrderLogboekProps {
6
+ titel?: string;
7
+ omschrijving?: string;
8
+ }
9
+ export declare function OrderLogboek({ titel, omschrijving, }: OrderLogboekProps): import("react").JSX.Element;
10
+ //# sourceMappingURL=OrderLogboek.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrderLogboek.d.ts","sourceRoot":"","sources":["../../src/components/OrderLogboek.tsx"],"names":[],"mappings":"AAgCA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,4BAA4B,CAAC;AAsDpC,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,+BAoG9D;AAyBD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAA8B,EAC9B,YAAsI,GACvI,EAAE,iBAAiB,+BAmGnB"}
@@ -0,0 +1,92 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/OrderLogboek.tsx — alle binnengekomen orders met volledig log
4
+ // ============================================================================
5
+ // Eén lijst met binnengekomen orders. Per order de volledige tijdlijn van de
6
+ // Logistiek Engine: elke stap, beslissing, foutcode, document, databaseregel
7
+ // en uitwisseling met Floriday. Uitsluitend echt vastgelegde gebeurtenissen.
8
+ // GEEN <Header /> hier — die levert de shell.
9
+ // ============================================================================
10
+ import { useMemo, useState } from "react";
11
+ import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, Skeleton, } from "@flowselections/core";
12
+ import { AlertTriangle, ChevronDown, ChevronRight, Clock, Database, ExternalLink, FileText, RefreshCw, Search, } from "lucide-react";
13
+ import { useLogisticsTrace, useLogisticsTraceTimeline, } from "../hooks/useLogisticsTrace";
14
+ const STATUS_FILTERS = [
15
+ { waarde: "", label: "Alles" },
16
+ { waarde: "bezig", label: "Bezig" },
17
+ { waarde: "wachtend", label: "Wachtend" },
18
+ { waarde: "geblokkeerd", label: "Geblokkeerd" },
19
+ { waarde: "fout", label: "Fout" },
20
+ { waarde: "afgerond", label: "Afgerond" },
21
+ ];
22
+ const FASE_LABEL = {
23
+ ontvangst: "Ontvangst",
24
+ validatie: "Controle van gegevens",
25
+ regels: "Regels",
26
+ karindeling: "Karindeling",
27
+ vrijgave: "Vrijgave",
28
+ pakbon: "Pakbon",
29
+ verzendbrief: "Verzendbrief",
30
+ printen: "Printen",
31
+ database: "Databasewijziging",
32
+ controle: "Controle",
33
+ afgerond: "Afronding",
34
+ onbekend: "Overig",
35
+ };
36
+ function tijd(waarde) {
37
+ if (!waarde)
38
+ return "—";
39
+ const d = new Date(waarde);
40
+ return Number.isNaN(d.getTime())
41
+ ? "—"
42
+ : d.toLocaleString("nl-NL", { dateStyle: "short", timeStyle: "medium" });
43
+ }
44
+ function statusKleur(status) {
45
+ if (status === "mislukt" || status === "fout" || status === "geblokkeerd")
46
+ return "destructive";
47
+ if (status === "wachtend" || status === "waarschuwing")
48
+ return "secondary";
49
+ if (status === "overgeslagen")
50
+ return "outline";
51
+ return "default";
52
+ }
53
+ function Blok({ titel, waarde }) {
54
+ if (waarde === null || waarde === undefined)
55
+ return null;
56
+ if (typeof waarde === "object" && Object.keys(waarde).length === 0)
57
+ return null;
58
+ return (_jsxs("div", { className: "rounded-md bg-muted/50 p-3", children: [_jsx("p", { className: "mb-1 text-xs font-medium text-muted-foreground", children: titel }), _jsx("pre", { className: "overflow-x-auto whitespace-pre-wrap break-words text-xs", children: typeof waarde === "string" ? waarde : JSON.stringify(waarde, null, 2) })] }));
59
+ }
60
+ export function Gebeurtenis({ event }) {
61
+ const [open, setOpen] = useState(false);
62
+ const heeftDetails = event.input ||
63
+ event.output ||
64
+ event.reads ||
65
+ event.values ||
66
+ event.dbOld ||
67
+ event.dbNew ||
68
+ event.externalResponse ||
69
+ event.decision ||
70
+ event.rule ||
71
+ event.slipRef ||
72
+ event.dbTable ||
73
+ event.externalSystem;
74
+ return (_jsxs("div", { className: "border-l-2 border-muted pl-4", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-start gap-2 py-2 text-left", children: [heeftDetails ? (open ? (_jsx(ChevronDown, { className: "mt-1 h-4 w-4 shrink-0 text-muted-foreground" })) : (_jsx(ChevronRight, { className: "mt-1 h-4 w-4 shrink-0 text-muted-foreground" }))) : (_jsx("span", { className: "mt-1 h-4 w-4 shrink-0" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium", children: event.step }), _jsx(Badge, { variant: statusKleur(event.status), children: event.status }), _jsx(Badge, { variant: "outline", children: FASE_LABEL[event.phase] ?? event.phase }), event.attempts > 0 && _jsxs(Badge, { variant: "outline", children: ["poging ", event.attempts] }), event.durationMs !== null && (_jsxs("span", { className: "text-xs text-muted-foreground", children: [event.durationMs, " ms"] }))] }), _jsxs("p", { className: "text-xs text-muted-foreground", children: [tijd(event.createdAt), event.actor ? ` · ${event.actor}` : "", event.cartRef ? ` · kar ${event.cartRef}` : "", event.slipRef ? ` · pakbon ${event.slipRef}` : ""] }), event.reason && _jsx("p", { className: "mt-1 text-sm", children: event.reason }), event.error && (_jsxs("p", { className: "mt-1 flex items-start gap-1 text-sm text-destructive", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }), _jsx("span", { children: event.error })] }))] })] }), open && (_jsxs("div", { className: "mb-3 space-y-2", children: [event.decision && (_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Beslissing: ", event.decision] })), event.rule && _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Regel: ", event.rule] }), event.slipRef && (_jsxs("p", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(FileText, { className: "h-3.5 w-3.5" }), " Document: ", event.slipRef] })), event.dbTable && (_jsxs("p", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(Database, { className: "h-3.5 w-3.5" }), event.dbAction, " in ", event.dbTable, event.dbRecord ? ` (${event.dbRecord})` : ""] })), event.externalSystem && (_jsxs("p", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5" }), event.externalSystem, " \u00B7 ", event.externalAction ?? "—", event.externalRef ? ` · ${event.externalRef}` : "", event.externalStatus ? ` · antwoord ${event.externalStatus}` : ""] })), event.nextAttemptAt && (_jsxs("p", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(Clock, { className: "h-3.5 w-3.5" }), " Volgende poging: ", tijd(event.nextAttemptAt)] })), _jsx(Blok, { titel: "Invoer", waarde: event.input }), _jsx(Blok, { titel: "Gelezen gegevens", waarde: event.reads }), _jsx(Blok, { titel: "Gebruikte waarden", waarde: event.values }), _jsx(Blok, { titel: "Resultaat", waarde: event.output }), _jsx(Blok, { titel: "Waarde v\u00F3\u00F3r wijziging", waarde: event.dbOld }), _jsx(Blok, { titel: "Waarde n\u00E1 wijziging", waarde: event.dbNew }), _jsx(Blok, { titel: "Antwoord extern systeem", waarde: event.externalResponse })] }))] }));
75
+ }
76
+ function Tijdlijn({ orderRef }) {
77
+ const { events, loading, error } = useLogisticsTraceTimeline(orderRef);
78
+ const veilig = Array.isArray(events) ? events : [];
79
+ if (loading)
80
+ return _jsx(Skeleton, { className: "h-24 w-full" });
81
+ if (error)
82
+ return _jsx("p", { className: "text-sm text-destructive", children: error });
83
+ if (veilig.length === 0)
84
+ return (_jsx("p", { className: "text-sm text-muted-foreground", children: "Voor deze order zijn nog geen stappen vastgelegd." }));
85
+ return (_jsxs("div", { className: "space-y-1", children: [_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Volgnummer: ", veilig[0]?.traceId ?? "—"] }), veilig.map((e) => (_jsx(Gebeurtenis, { event: e }, e.id)))] }));
86
+ }
87
+ export function OrderLogboek({ titel = "Binnengekomen orders", omschrijving = "Klik een order open voor elke stap, beslissing, foutmelding en elk document dat de Logistiek Engine heeft vastgelegd.", }) {
88
+ const { orders, loading, error, search, setSearch, status, setStatus, hours, setHours, refresh } = useLogisticsTrace();
89
+ const [open, setOpen] = useState(null);
90
+ const veilig = useMemo(() => (Array.isArray(orders) ? orders : []), [orders]);
91
+ return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: titel }), _jsx(CardDescription, { children: omschrijving })] }), _jsxs(CardContent, { className: "space-y-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "relative min-w-[220px] flex-1", children: [_jsx(Search, { className: "absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" }), _jsx(Input, { value: search, onChange: (e) => setSearch(e.target.value), placeholder: "Zoek op order, kar, pakbon of foutmelding", className: "pl-8" })] }), _jsxs("select", { value: String(hours), onChange: (e) => setHours(Number(e.target.value)), className: "h-9 rounded-md border bg-background px-2 text-sm", children: [_jsx("option", { value: "6", children: "Laatste 6 uur" }), _jsx("option", { value: "24", children: "Laatste 24 uur" }), _jsx("option", { value: "48", children: "Laatste 2 dagen" }), _jsx("option", { value: "168", children: "Laatste week" })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void refresh(), children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), " Verversen"] })] }), _jsx("div", { className: "flex flex-wrap gap-2", children: STATUS_FILTERS.map((f) => (_jsx(Button, { size: "sm", variant: status === f.waarde ? "default" : "outline", onClick: () => setStatus(f.waarde), children: f.label }, f.waarde || "alles"))) }), error && _jsx("p", { className: "text-sm text-destructive", children: error }), loading && veilig.length === 0 && _jsx(Skeleton, { className: "h-32 w-full" }), !loading && veilig.length === 0 && !error && (_jsx("p", { className: "text-sm text-muted-foreground", children: "Er zijn in deze periode nog geen stappen vastgelegd." })), _jsx("div", { className: "space-y-2", children: veilig.map((o) => (_jsxs("div", { className: "rounded-lg border", children: [_jsxs("button", { type: "button", className: "flex w-full items-center gap-3 p-3 text-left", onClick: () => setOpen((v) => (v === o.orderRef ? null : o.orderRef)), children: [open === o.orderRef ? (_jsx(ChevronDown, { className: "h-4 w-4 shrink-0" })) : (_jsx(ChevronRight, { className: "h-4 w-4 shrink-0" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium", children: o.orderRef }), _jsx(Badge, { variant: statusKleur(o.state), children: o.state }), o.orderSource && _jsx(Badge, { variant: "outline", children: o.orderSource }), o.errors > 0 && _jsxs(Badge, { variant: "destructive", children: [o.errors, " fout"] }), o.waiting > 0 && _jsxs(Badge, { variant: "secondary", children: [o.waiting, " wachtend"] })] }), _jsxs("p", { className: "truncate text-xs text-muted-foreground", children: [o.lastStep ?? "—", " \u00B7 ", tijd(o.lastAt)] }), o.lastReason && (_jsx("p", { className: "truncate text-sm text-muted-foreground", children: o.lastReason }))] })] }), open === o.orderRef && (_jsx("div", { className: "border-t p-3", children: _jsx(Tijdlijn, { orderRef: o.orderRef }) }))] }, o.orderRef))) })] })] }));
92
+ }
@@ -0,0 +1,12 @@
1
+ import { type StopReden } from "../lib/stopReden";
2
+ interface Props {
3
+ orderRef: string;
4
+ /** De reden bij het laatste vakje van de route (uit de flowkaart). */
5
+ stop?: StopReden | null;
6
+ /** Het vakje waar de reis ophoudt. */
7
+ stopNode?: string | null;
8
+ onNode?: (nodeId: string) => void;
9
+ }
10
+ export declare function OrderStopBanner({ orderRef, stop, stopNode, onNode }: Props): import("react").JSX.Element | null;
11
+ export {};
12
+ //# sourceMappingURL=OrderStopBanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrderStopBanner.d.ts","sourceRoot":"","sources":["../../src/components/OrderStopBanner.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7D,UAAU,KAAK;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAkBD,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAW,EAAE,QAAe,EAAE,MAAM,EAAE,EAAE,KAAK,sCAqCxF"}
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/OrderStopBanner.tsx — waar staat deze order stil, en waarom?
4
+ // ============================================================================
5
+ // Boven de flowkaart: bij welk vakje de reis van de order ophoudt, waarom dat
6
+ // zo is, wat de bepalende gegevens zijn en wat er moet gebeuren. Alleen lezen.
7
+ // ============================================================================
8
+ import { AlertTriangle, CheckCircle2, Clock } from "lucide-react";
9
+ import { useOrderTraceStand } from "../hooks/useOrderTrace";
10
+ import { flowNodeLabel } from "../lib/flowNodes";
11
+ import { stopReden } from "../lib/stopReden";
12
+ import { Veld, sinds, tijd } from "./OrderTraceDetails";
13
+ const KLEUR = {
14
+ mislukt: "border-destructive/50 bg-destructive/5",
15
+ wachtrij: "border-amber-500/40 bg-amber-500/5",
16
+ handeling: "border-amber-500/40 bg-amber-500/5",
17
+ nietvastgelegd: "border-border bg-muted/40",
18
+ klaar: "border-primary/40 bg-primary/5",
19
+ };
20
+ const KOP = {
21
+ mislukt: "ORDER GESTOPT BIJ",
22
+ wachtrij: "ORDER WACHT BIJ",
23
+ handeling: "ORDER WACHT BIJ",
24
+ nietvastgelegd: "FLOW STOPT BIJ",
25
+ klaar: "FLOW EINDIGT BIJ",
26
+ };
27
+ export function OrderStopBanner({ orderRef, stop = null, stopNode = null, onNode }) {
28
+ const { stand } = useOrderTraceStand(orderRef);
29
+ // Komt de reden niet uit de kaart, dan leiden we hem af uit de stand.
30
+ const node = stopNode ?? stand?.stuckNode ?? stand?.lastNode ?? null;
31
+ const reden = stop ?? (node ? stopReden({ nodeId: node, stand: stand ?? null }) : null);
32
+ if (!reden)
33
+ return null;
34
+ const Icoon = reden.soort === "mislukt" ? AlertTriangle : reden.soort === "klaar" ? CheckCircle2 : Clock;
35
+ return (_jsxs("div", { className: `rounded-lg border p-3 ${KLEUR[reden.soort]}`, children: [_jsxs("p", { className: "flex flex-wrap items-center gap-2 text-sm font-semibold", children: [_jsx(Icoon, { className: "h-4 w-4" }), KOP[reden.soort], ": ", node ? flowNodeLabel(node) : stand?.stuckStep ?? "onbekende stap", node && onNode ? (_jsx("button", { type: "button", className: "text-xs font-normal underline", onClick: () => onNode(node), children: "toon dit vakje" })) : null] }), _jsx("p", { className: "mt-1 text-sm", children: reden.reden }), reden.feiten.length > 0 ? (_jsx("ul", { className: "mt-2 space-y-0.5 text-xs text-muted-foreground", children: reden.feiten.map((f) => (_jsx("li", { children: f }, f))) })) : null, _jsx(Veld, { label: "Geblokkeerd sinds", children: stand?.blockedSince ? `${tijd(stand.blockedSince)} (${sinds(stand.blockedSince)})` : null }), _jsx(Veld, { label: "Wat moet er gebeuren", children: reden.volgendeStap }), _jsx(Veld, { label: "Wachtrij", children: stand?.queueStatus ?? null })] }));
36
+ }
@@ -0,0 +1,22 @@
1
+ import type { TraceEventRow } from "../hooks/useLogisticsTrace";
2
+ export declare const FOUTSOORT_LABEL: Record<string, string>;
3
+ export declare const FOUTSOORT_UITLEG: Record<string, string>;
4
+ export declare const STATUS_KLEUR: Record<string, string>;
5
+ export declare function tijd(v: string | null | undefined): string;
6
+ export declare function klok(v: string | null | undefined): string;
7
+ export declare function duur(ms: number | null | undefined): string;
8
+ export declare function sinds(v: string | null | undefined): string;
9
+ export declare function Json({ waarde }: {
10
+ waarde: unknown;
11
+ }): import("react").JSX.Element | null;
12
+ export declare function Veld({ label, children }: {
13
+ label: string;
14
+ children: React.ReactNode;
15
+ }): import("react").JSX.Element | null;
16
+ /** Eén gebeurtenis van de Engine, uitklapbaar met alle vastgelegde details. */
17
+ export declare function Stap({ e, debug, open: standaardOpen }: {
18
+ e: TraceEventRow;
19
+ debug: boolean;
20
+ open?: boolean;
21
+ }): import("react").JSX.Element;
22
+ //# sourceMappingURL=OrderTraceDetails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrderTraceDetails.d.ts","sourceRoot":"","sources":["../../src/components/OrderTraceDetails.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMlD,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMnD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAM/C,CAAC;AAEF,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAIzD;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAKzD;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAK1D;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAS1D;AAED,wBAAgB,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,sCAOnD;AAED,wBAAgB,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,sCAQrF;AAED,+EAA+E;AAC/E,wBAAgB,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE;IAAE,CAAC,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,+BAyJ3G"}
@@ -0,0 +1,88 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/OrderTraceDetails.tsx — bouwstenen om één gebeurtenis te tonen
4
+ // ============================================================================
5
+ // Gedeelde weergave van wat de Engine bij een stap heeft vastgelegd: de
6
+ // beslissing, de berekening, de fout, gewijzigde gegevens en extern verkeer.
7
+ // Alleen lezen. GEEN <Header /> hier — die levert de shell.
8
+ // ============================================================================
9
+ import { useState } from "react";
10
+ import { Badge } from "@flowselections/core";
11
+ import { AlertTriangle, ChevronDown, ChevronRight, Database, ExternalLink } from "lucide-react";
12
+ import { flowNodeLabel } from "../lib/flowNodes";
13
+ import { foutTekst } from "../lib/foutTekst";
14
+ export const FOUTSOORT_LABEL = {
15
+ technisch: "Technische fout",
16
+ ontbrekende_gegevens: "Ontbrekende gegevens",
17
+ configuratie: "Configuratiefout",
18
+ regel: "Bewuste regel",
19
+ extern: "Extern systeem",
20
+ };
21
+ export const FOUTSOORT_UITLEG = {
22
+ technisch: "Er ging iets stuk in de database, een koppeling of de printer.",
23
+ ontbrekende_gegevens: "De order of de stamgegevens missen iets dat de Engine nodig heeft.",
24
+ configuratie: "Een instelling of koppeling in de werkwijze staat niet goed.",
25
+ regel: "De Engine mag bewust niet verder vanwege een ingestelde regel.",
26
+ extern: "Een extern systeem heeft nog niets teruggegeven.",
27
+ };
28
+ export const STATUS_KLEUR = {
29
+ geslaagd: "bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",
30
+ wachtend: "bg-amber-500/15 text-amber-700 dark:text-amber-300",
31
+ waarschuwing: "bg-amber-500/15 text-amber-700 dark:text-amber-300",
32
+ overgeslagen: "bg-muted text-muted-foreground",
33
+ mislukt: "bg-destructive/15 text-destructive",
34
+ };
35
+ export function tijd(v) {
36
+ if (!v)
37
+ return "—";
38
+ const d = new Date(v);
39
+ return Number.isNaN(d.getTime()) ? String(v) : d.toLocaleString("nl-NL");
40
+ }
41
+ export function klok(v) {
42
+ if (!v)
43
+ return "—";
44
+ const d = new Date(v);
45
+ if (Number.isNaN(d.getTime()))
46
+ return String(v);
47
+ return d.toLocaleTimeString("nl-NL", { hour: "2-digit", minute: "2-digit" });
48
+ }
49
+ export function duur(ms) {
50
+ if (ms === null || ms === undefined)
51
+ return "—";
52
+ if (ms < 1000)
53
+ return `${ms} ms`;
54
+ if (ms < 60000)
55
+ return `${(ms / 1000).toFixed(1)} s`;
56
+ return `${Math.round(ms / 60000)} min`;
57
+ }
58
+ export function sinds(v) {
59
+ if (!v)
60
+ return "—";
61
+ const start = new Date(v).getTime();
62
+ if (Number.isNaN(start))
63
+ return "—";
64
+ const min = Math.max(Math.round((Date.now() - start) / 60000), 0);
65
+ if (min < 60)
66
+ return `${min} minuten`;
67
+ const u = Math.floor(min / 60);
68
+ if (u < 24)
69
+ return `${u} uur en ${min % 60} minuten`;
70
+ return `${Math.floor(u / 24)} dagen en ${u % 24} uur`;
71
+ }
72
+ export function Json({ waarde }) {
73
+ if (waarde === null || waarde === undefined)
74
+ return null;
75
+ return (_jsx("pre", { className: "mt-1 max-h-56 overflow-auto rounded-md bg-muted/60 p-2 text-xs leading-relaxed", children: JSON.stringify(waarde, null, 2) }));
76
+ }
77
+ export function Veld({ label, children }) {
78
+ if (children === null || children === undefined || children === "")
79
+ return null;
80
+ return (_jsxs("div", { className: "text-sm", children: [_jsxs("span", { className: "font-medium text-foreground", children: [label, ": "] }), _jsx("span", { className: "text-muted-foreground", children: children })] }));
81
+ }
82
+ /** Eén gebeurtenis van de Engine, uitklapbaar met alle vastgelegde details. */
83
+ export function Stap({ e, debug, open: standaardOpen }) {
84
+ const [open, setOpen] = useState(standaardOpen ?? e.status === "mislukt");
85
+ const calc = (e.calc ?? null);
86
+ const fout = e.status === "mislukt";
87
+ return (_jsxs("div", { className: `rounded-lg border ${fout ? "border-destructive/50 bg-destructive/5" : "bg-card"}`, children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-start gap-3 p-3 text-left", children: [open ? _jsx(ChevronDown, { className: "mt-1 h-4 w-4 shrink-0" }) : _jsx(ChevronRight, { className: "mt-1 h-4 w-4 shrink-0" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium", children: e.step }), _jsx(Badge, { className: STATUS_KLEUR[e.status] ?? "", children: e.status }), e.errorClass ? _jsx(Badge, { variant: "outline", children: FOUTSOORT_LABEL[e.errorClass] ?? e.errorClass }) : null, e.nodeId ? _jsx(Badge, { variant: "outline", children: flowNodeLabel(e.nodeId) }) : null] }), _jsxs("div", { className: "mt-1 flex flex-wrap gap-x-4 text-xs text-muted-foreground", children: [_jsx("span", { children: tijd(e.createdAt) }), _jsxs("span", { children: ["Duur: ", duur(e.durationMs)] }), e.actor ? _jsxs("span", { children: ["Door: ", e.actor] }) : null, e.attempts > 0 ? _jsxs("span", { children: ["Poging ", e.attempts] }) : null] }), e.reason || e.decision ? (_jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: e.reason ?? e.decision })) : null] })] }), open ? (_jsxs("div", { className: "space-y-3 border-t px-3 py-3", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(Veld, { label: "Beslissing", children: e.decision }), _jsx(Veld, { label: "Waarom", children: e.reason }), _jsx(Veld, { label: "Regel", children: e.rule }), _jsx(Veld, { label: "Volgende stap", children: e.nextStep }), _jsx(Veld, { label: "Volgende poging", children: e.nextAttemptAt ? tijd(e.nextAttemptAt) : null })] }), calc ? (_jsxs("div", { className: "rounded-md border bg-muted/40 p-3", children: [_jsx("p", { className: "text-sm font-medium", children: "Berekening" }), _jsx(Veld, { label: "Instelling", children: calc.setting }), _jsx(Veld, { label: "Rekenstap", children: calc.formula }), _jsx(Veld, { label: "Uitkomst", children: calc.result }), _jsx(Veld, { label: "Conclusie", children: calc.conclusion }), calc.values ? _jsx(Json, { waarde: calc.values }) : null] })) : null, fout ? (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 p-3", children: [_jsxs("p", { className: "flex items-center gap-2 text-sm font-medium text-destructive", children: [_jsx(AlertTriangle, { className: "h-4 w-4" }), " Fout bij deze stap"] }), _jsx(Veld, { label: "Soort", children: e.errorClass ? FOUTSOORT_LABEL[e.errorClass] ?? e.errorClass : "Technische fout" }), _jsx(Veld, { label: "Uitleg", children: e.errorClass ? FOUTSOORT_UITLEG[e.errorClass] ?? null : null }), _jsx(Veld, { label: "Melding", children: foutTekst(e.error) }), e.error && foutTekst(e.error) !== e.error ? (_jsxs("details", { className: "mt-1", children: [_jsx("summary", { className: "cursor-pointer text-xs text-muted-foreground", children: "Technische details" }), _jsx("p", { className: "mt-1 break-words text-xs text-muted-foreground", children: e.error })] })) : null, _jsx(Veld, { label: "Pogingen", children: e.attempts > 0 ? String(e.attempts) : null })] })) : null, e.dbTable ? (_jsxs("div", { className: "rounded-md border p-3", children: [_jsxs("p", { className: "flex items-center gap-2 text-sm font-medium", children: [_jsx(Database, { className: "h-4 w-4" }), " Gegevens gewijzigd"] }), _jsx(Veld, { label: "Tabel", children: e.dbTable }), _jsx(Veld, { label: "Actie", children: e.dbAction }), e.dbOld ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "mt-2 text-xs font-medium", children: "Voor" }), _jsx(Json, { waarde: e.dbOld })] })) : null, e.dbNew ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "mt-2 text-xs font-medium", children: "Na" }), _jsx(Json, { waarde: e.dbNew })] })) : null] })) : null, e.externalSystem ? (_jsxs("div", { className: "rounded-md border p-3", children: [_jsxs("p", { className: "flex items-center gap-2 text-sm font-medium", children: [_jsx(ExternalLink, { className: "h-4 w-4" }), " Extern systeem"] }), _jsx(Veld, { label: "Systeem", children: e.externalSystem }), _jsx(Veld, { label: "Actie", children: e.externalAction }), _jsx(Veld, { label: "Kenmerk", children: e.externalRef }), _jsx(Veld, { label: "Resultaat", children: e.externalStatus }), _jsx(Json, { waarde: e.externalResponse })] })) : null, e.reads ? (_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium", children: "Gelezen gegevens" }), _jsx(Json, { waarde: e.reads })] })) : null, e.values ? (_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium", children: "Gebruikte waarden" }), _jsx(Json, { waarde: e.values })] })) : null, debug ? (_jsxs("div", { className: "rounded-md border border-dashed p-3", children: [_jsx("p", { className: "text-sm font-medium", children: "Technische gegevens" }), _jsx(Veld, { label: "Trace ID", children: e.traceId }), _jsx(Veld, { label: "Gebeurtenis ID", children: e.id }), _jsx(Veld, { label: "Vakje", children: e.nodeId }), _jsx(Veld, { label: "Fase", children: e.phase }), _jsx(Veld, { label: "Kar", children: e.cartRef }), _jsx(Veld, { label: "Pakbon", children: e.slipRef }), _jsx(Veld, { label: "Regel in database", children: e.dbRecord }), _jsxs("div", { className: "mt-2 grid gap-2 md:grid-cols-2", children: [_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium", children: "Invoer" }), _jsx(Json, { waarde: e.input })] }), _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium", children: "Uitvoer" }), _jsx(Json, { waarde: e.output })] })] })] })) : null] })) : null] }));
88
+ }
@@ -0,0 +1,2 @@
1
+ export declare function PlanWachtrijPage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=PlanWachtrijPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanWachtrijPage.d.ts","sourceRoot":"","sources":["../../src/components/PlanWachtrijPage.tsx"],"names":[],"mappings":"AAsEA,wBAAgB,gBAAgB,gCA0N/B"}