@burdenoff/microfe-movethewheels 2026.930.4 → 2026.1010.1

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 (377) hide show
  1. package/dist/MoveTheWheelsRoot.js +177 -102
  2. package/dist/MoveTheWheelsRoutes.js +55 -11
  3. package/dist/_virtual/_rolldown/runtime.js +1 -1
  4. package/dist/components/ContainerEvidencePicker.js +143 -0
  5. package/dist/components/FreeTimeAgreementForm.js +496 -0
  6. package/dist/components/ReturnInstructionForm.js +108 -0
  7. package/dist/components/ReuseControls.js +91 -0
  8. package/dist/components/ReusePermissionForm.js +114 -0
  9. package/dist/components/ReuseProposalForm.js +455 -0
  10. package/dist/components/ReuseSourceFields.js +78 -0
  11. package/dist/components/consolidation/ConsolidationHistory.js +244 -0
  12. package/dist/components/consolidation/ConsolidationLotEditor.js +133 -0
  13. package/dist/components/consolidation/ConsolidationManifestWorkbench.js +143 -0
  14. package/dist/components/consolidation/ConsolidationPlanForm.js +172 -0
  15. package/dist/components/consolidation/ConsolidationPlanWorkbench.js +321 -0
  16. package/dist/components/consolidation/ConsolidationReportForm.js +94 -0
  17. package/dist/components/consolidation/ConsolidationReportsWorkbench.js +195 -0
  18. package/dist/components/consolidation/ConsolidationSummary.js +76 -0
  19. package/dist/components/consolidation/OriginalConsolidationHistory.js +112 -0
  20. package/dist/components/freight-cost/FreightDraftForm.js +213 -0
  21. package/dist/components/freight-cost/FreightFields.js +70 -0
  22. package/dist/components/freight-cost/FreightFxEditor.js +90 -0
  23. package/dist/components/freight-cost/FreightHistory.js +164 -0
  24. package/dist/components/freight-cost/FreightLineEditor.js +191 -0
  25. package/dist/components/freight-cost/FreightScopeEditor.js +72 -0
  26. package/dist/components/freight-cost/FreightTotals.js +66 -0
  27. package/dist/components/logistics-procedure/ProcedureDecisionForm.js +197 -0
  28. package/dist/components/logistics-procedure/ProcedureFields.js +31 -0
  29. package/dist/components/logistics-procedure/ProcedureHistory.js +177 -0
  30. package/dist/components/logistics-procedure/ProcedurePolicyForm.js +227 -0
  31. package/dist/components/logistics-procedure/ProcedurePolicyWorkbench.js +155 -0
  32. package/dist/components/logistics-procedure/ProcedureReviewWorkbench.js +221 -0
  33. package/dist/components/logistics-procedure/ProcedureRunWorkbench.js +190 -0
  34. package/dist/components/logistics-procedure/ProcedureSubjectPicker.js +130 -0
  35. package/dist/components/pending-pick/PendingPickDraft.js +84 -0
  36. package/dist/components/pending-pick/PendingPickHistory.js +113 -0
  37. package/dist/components/pending-pick/PickCapture.js +166 -0
  38. package/dist/components/pending-pick/PickLineSelection.js +111 -0
  39. package/dist/components/stock-binding/StockAssessmentDraft.js +48 -0
  40. package/dist/components/stock-binding/StockAssessmentHistory.js +61 -0
  41. package/dist/components/stock-binding/StockAssessmentSummary.js +199 -0
  42. package/dist/components/stock-binding/StockFactForm.js +232 -0
  43. package/dist/components/stock-observation/StockIssueForm.js +148 -0
  44. package/dist/components/stock-observation/StockIssueHistory.js +116 -0
  45. package/dist/components/stock-observation/StockIssueReadPanel.js +70 -0
  46. package/dist/components/trip-utilization/TripReportForm.js +118 -0
  47. package/dist/components/trip-utilization/TripReportHistory.js +54 -0
  48. package/dist/components/trip-utilization/TripReportSummary.js +216 -0
  49. package/dist/components/trip-utilization/TripSegmentFields.js +166 -0
  50. package/dist/generated/consolidation-operations.d.ts +1060 -0
  51. package/dist/generated/container-condition-operations.d.ts +868 -0
  52. package/dist/generated/container-operations.d.ts +356 -0
  53. package/dist/generated/empty-reuse-operations.d.ts +1578 -0
  54. package/dist/generated/free-time-operations.d.ts +938 -0
  55. package/dist/generated/freight-cost-operations.d.ts +716 -0
  56. package/dist/generated/logistics-procedure-operations.d.ts +938 -0
  57. package/dist/generated/pending-pick-operations.d.ts +1969 -0
  58. package/dist/generated/stock-binding-operations.d.ts +930 -0
  59. package/dist/generated/stock-observation-operations.d.ts +476 -0
  60. package/dist/generated/trip-utilization-operations.d.ts +651 -0
  61. package/dist/generated/wspace-operations.d.ts +143 -50
  62. package/dist/hooks/useConsolidationAction.js +119 -0
  63. package/dist/hooks/useContainerCondition.js +105 -0
  64. package/dist/hooks/useContainerLifecycle.js +192 -0
  65. package/dist/hooks/useEmptyReuseAction.js +45 -0
  66. package/dist/hooks/useFreightRecoveryAction.js +117 -0
  67. package/dist/hooks/useInventory.js +12 -1
  68. package/dist/hooks/useProcedureAction.js +119 -0
  69. package/dist/hooks/useProcedureSelection.js +53 -0
  70. package/dist/hooks/useReuseRecoveryAction.js +116 -0
  71. package/dist/movethewheels/components/ContainerEvidencePicker.d.ts +10 -0
  72. package/dist/movethewheels/components/FreeTimeAgreementForm.d.ts +14 -0
  73. package/dist/movethewheels/components/ReturnInstructionForm.d.ts +8 -0
  74. package/dist/movethewheels/components/ReuseControls.d.ts +42 -0
  75. package/dist/movethewheels/components/ReusePermissionForm.d.ts +9 -0
  76. package/dist/movethewheels/components/ReuseProposalForm.d.ts +11 -0
  77. package/dist/movethewheels/components/ReuseSourceFields.d.ts +9 -0
  78. package/dist/movethewheels/components/consolidation/ConsolidationHistory.d.ts +13 -0
  79. package/dist/movethewheels/components/consolidation/ConsolidationLotEditor.d.ts +6 -0
  80. package/dist/movethewheels/components/consolidation/ConsolidationManifestWorkbench.d.ts +8 -0
  81. package/dist/movethewheels/components/consolidation/ConsolidationPlanForm.d.ts +8 -0
  82. package/dist/movethewheels/components/consolidation/ConsolidationPlanWorkbench.d.ts +5 -0
  83. package/dist/movethewheels/components/consolidation/ConsolidationReportForm.d.ts +9 -0
  84. package/dist/movethewheels/components/consolidation/ConsolidationReportsWorkbench.d.ts +7 -0
  85. package/dist/movethewheels/components/consolidation/ConsolidationSummary.d.ts +6 -0
  86. package/dist/movethewheels/components/consolidation/OriginalConsolidationHistory.d.ts +8 -0
  87. package/dist/movethewheels/components/freight-cost/FreightDraftForm.d.ts +8 -0
  88. package/dist/movethewheels/components/freight-cost/FreightFields.d.ts +23 -0
  89. package/dist/movethewheels/components/freight-cost/FreightFxEditor.d.ts +6 -0
  90. package/dist/movethewheels/components/freight-cost/FreightHistory.d.ts +5 -0
  91. package/dist/movethewheels/components/freight-cost/FreightLineEditor.d.ts +8 -0
  92. package/dist/movethewheels/components/freight-cost/FreightScopeEditor.d.ts +6 -0
  93. package/dist/movethewheels/components/freight-cost/FreightTotals.d.ts +6 -0
  94. package/dist/movethewheels/components/logistics-procedure/ProcedureDecisionForm.d.ts +20 -0
  95. package/dist/movethewheels/components/logistics-procedure/ProcedureFields.d.ts +17 -0
  96. package/dist/movethewheels/components/logistics-procedure/ProcedureHistory.d.ts +7 -0
  97. package/dist/movethewheels/components/logistics-procedure/ProcedurePolicyForm.d.ts +10 -0
  98. package/dist/movethewheels/components/logistics-procedure/ProcedurePolicyWorkbench.d.ts +5 -0
  99. package/dist/movethewheels/components/logistics-procedure/ProcedureReviewWorkbench.d.ts +5 -0
  100. package/dist/movethewheels/components/logistics-procedure/ProcedureRunWorkbench.d.ts +6 -0
  101. package/dist/movethewheels/components/logistics-procedure/ProcedureSubjectPicker.d.ts +7 -0
  102. package/dist/movethewheels/components/pending-pick/PendingPickDraft.d.ts +16 -0
  103. package/dist/movethewheels/components/pending-pick/PendingPickHistory.d.ts +5 -0
  104. package/dist/movethewheels/components/pending-pick/PickCapture.d.ts +6 -0
  105. package/dist/movethewheels/components/pending-pick/PickLineSelection.d.ts +17 -0
  106. package/dist/movethewheels/components/stock-binding/StockAssessmentDraft.d.ts +13 -0
  107. package/dist/movethewheels/components/stock-binding/StockAssessmentHistory.d.ts +18 -0
  108. package/dist/movethewheels/components/stock-binding/StockAssessmentSummary.d.ts +9 -0
  109. package/dist/movethewheels/components/stock-binding/StockFactForm.d.ts +6 -0
  110. package/dist/movethewheels/components/stock-observation/StockIssueForm.d.ts +7 -0
  111. package/dist/movethewheels/components/stock-observation/StockIssueHistory.d.ts +7 -0
  112. package/dist/movethewheels/components/stock-observation/StockIssueReadPanel.d.ts +5 -0
  113. package/dist/movethewheels/components/trip-utilization/TripReportForm.d.ts +6 -0
  114. package/dist/movethewheels/components/trip-utilization/TripReportHistory.d.ts +14 -0
  115. package/dist/movethewheels/components/trip-utilization/TripReportSummary.d.ts +5 -0
  116. package/dist/movethewheels/components/trip-utilization/TripSegmentFields.d.ts +9 -0
  117. package/dist/movethewheels/hooks/useConsolidationAction.d.ts +19 -0
  118. package/dist/movethewheels/hooks/useContainerCondition.d.ts +21 -0
  119. package/dist/movethewheels/hooks/useContainerLifecycle.d.ts +40 -0
  120. package/dist/movethewheels/hooks/useEmptyReuseAction.d.ts +14 -0
  121. package/dist/movethewheels/hooks/useFreightRecoveryAction.d.ts +23 -0
  122. package/dist/movethewheels/hooks/useProcedureAction.d.ts +18 -0
  123. package/dist/movethewheels/hooks/useProcedureSelection.d.ts +51 -0
  124. package/dist/movethewheels/hooks/useReuseRecoveryAction.d.ts +18 -0
  125. package/dist/movethewheels/pages/ConsolidationPage.d.ts +1 -0
  126. package/dist/movethewheels/pages/ContainerConditionPage.d.ts +1 -0
  127. package/dist/movethewheels/pages/ContainersPage.d.ts +2 -0
  128. package/dist/movethewheels/pages/EmptyReusePage.d.ts +1 -0
  129. package/dist/movethewheels/pages/FreeTimePage.d.ts +1 -0
  130. package/dist/movethewheels/pages/FreightEstimatePage.d.ts +1 -0
  131. package/dist/movethewheels/pages/LogisticsProceduresPage.d.ts +1 -0
  132. package/dist/movethewheels/pages/PendingPickPage.d.ts +1 -0
  133. package/dist/movethewheels/pages/StockBindingPage.d.ts +1 -0
  134. package/dist/movethewheels/pages/StockObservationsPage.d.ts +1 -0
  135. package/dist/movethewheels/pages/TripUtilizationPage.d.ts +1 -0
  136. package/dist/movethewheels/utils/consolidationHistoryTarget.d.ts +12 -0
  137. package/dist/movethewheels/utils/consolidationInput.d.ts +15 -0
  138. package/dist/movethewheels/utils/consolidationLot.d.ts +3 -0
  139. package/dist/movethewheels/utils/consolidationPins.d.ts +20 -0
  140. package/dist/movethewheels/utils/consolidationRecovery.d.ts +5 -0
  141. package/dist/movethewheels/utils/consolidationReportHead.d.ts +5 -0
  142. package/dist/movethewheels/utils/freeTimeDate.d.ts +1 -0
  143. package/dist/movethewheels/utils/freightAcknowledgement.d.ts +2 -0
  144. package/dist/movethewheels/utils/freightDraft.d.ts +36 -0
  145. package/dist/movethewheels/utils/freightRecovery.d.ts +5 -0
  146. package/dist/movethewheels/utils/graphqlClient.d.ts +2 -1
  147. package/dist/movethewheels/utils/pendingPickDraft.d.ts +8 -0
  148. package/dist/movethewheels/utils/procedureInput.d.ts +18 -0
  149. package/dist/movethewheels/utils/procedureRecovery.d.ts +5 -0
  150. package/dist/movethewheels/utils/reuseAttempt.d.ts +7 -0
  151. package/dist/movethewheels/utils/reuseForm.d.ts +6 -0
  152. package/dist/movethewheels/utils/reuseRecovery.d.ts +26 -0
  153. package/dist/movethewheels/utils/stockBindingForm.d.ts +23 -0
  154. package/dist/movethewheels/utils/stockBindingLabels.d.ts +10 -0
  155. package/dist/movethewheels/utils/stockObservationForm.d.ts +5 -0
  156. package/dist/movethewheels/utils/tripDraftContext.d.ts +25 -0
  157. package/dist/movethewheels/utils/tripUtilizationForm.d.ts +6 -0
  158. package/dist/node_modules/@react-leaflet/core/lib/component.js +5 -5
  159. package/dist/node_modules/fast-equals/dist/es/index.js +87 -74
  160. package/dist/node_modules/leaflet/dist/leaflet-src.js +8 -5
  161. package/dist/node_modules/lodash/_Stack.js +2 -1
  162. package/dist/node_modules/lucide-react/dist/esm/icons/clipboard-list.js +35 -0
  163. package/dist/node_modules/lucide-react/dist/esm/icons/repeat-2.js +22 -0
  164. package/dist/node_modules/react-leaflet/lib/MapContainer.js +3 -3
  165. package/dist/node_modules/react-smooth/es6/Animate.js +2 -2
  166. package/dist/node_modules/recharts/es6/cartesian/Area.js +13 -13
  167. package/dist/node_modules/recharts/es6/cartesian/Bar.js +9 -9
  168. package/dist/node_modules/recharts/es6/cartesian/Brush.js +12 -12
  169. package/dist/node_modules/recharts/es6/cartesian/CartesianAxis.js +7 -7
  170. package/dist/node_modules/recharts/es6/cartesian/CartesianGrid.js +13 -13
  171. package/dist/node_modules/recharts/es6/cartesian/ErrorBar.js +4 -4
  172. package/dist/node_modules/recharts/es6/cartesian/Line.js +10 -10
  173. package/dist/node_modules/recharts/es6/cartesian/ReferenceArea.js +3 -3
  174. package/dist/node_modules/recharts/es6/cartesian/ReferenceDot.js +3 -3
  175. package/dist/node_modules/recharts/es6/cartesian/ReferenceLine.js +4 -4
  176. package/dist/node_modules/recharts/es6/cartesian/XAxis.js +3 -3
  177. package/dist/node_modules/recharts/es6/cartesian/YAxis.js +3 -3
  178. package/dist/node_modules/recharts/es6/chart/AccessibilityManager.js +1 -1
  179. package/dist/node_modules/recharts/es6/chart/generateCategoricalChart.js +22 -22
  180. package/dist/node_modules/recharts/es6/component/Cursor.js +1 -1
  181. package/dist/node_modules/recharts/es6/component/DefaultLegendContent.js +11 -11
  182. package/dist/node_modules/recharts/es6/component/DefaultTooltipContent.js +6 -6
  183. package/dist/node_modules/recharts/es6/component/Label.js +14 -14
  184. package/dist/node_modules/recharts/es6/component/LabelList.js +6 -6
  185. package/dist/node_modules/recharts/es6/component/Legend.js +5 -5
  186. package/dist/node_modules/recharts/es6/component/ResponsiveContainer.js +3 -3
  187. package/dist/node_modules/recharts/es6/component/Text.js +2 -2
  188. package/dist/node_modules/recharts/es6/component/Tooltip.js +3 -3
  189. package/dist/node_modules/recharts/es6/component/TooltipBoundingBox.js +2 -2
  190. package/dist/node_modules/recharts/es6/container/Layer.js +2 -2
  191. package/dist/node_modules/recharts/es6/container/Surface.js +2 -2
  192. package/dist/node_modules/recharts/es6/context/chartLayoutContext.js +2 -2
  193. package/dist/node_modules/recharts/es6/polar/Pie.js +13 -13
  194. package/dist/node_modules/recharts/es6/polar/PolarAngleAxis.js +8 -8
  195. package/dist/node_modules/recharts/es6/polar/PolarRadiusAxis.js +6 -6
  196. package/dist/node_modules/recharts/es6/shape/Cross.js +1 -1
  197. package/dist/node_modules/recharts/es6/shape/Curve.js +1 -1
  198. package/dist/node_modules/recharts/es6/shape/Dot.js +1 -1
  199. package/dist/node_modules/recharts/es6/shape/Polygon.js +4 -4
  200. package/dist/node_modules/recharts/es6/shape/Rectangle.js +4 -4
  201. package/dist/node_modules/recharts/es6/shape/Sector.js +1 -1
  202. package/dist/node_modules/recharts/es6/shape/Symbols.js +1 -1
  203. package/dist/node_modules/recharts/es6/shape/Trapezoid.js +4 -4
  204. package/dist/node_modules/recharts/es6/util/ActiveShapeUtils.js +9 -9
  205. package/dist/node_modules/recharts/es6/util/BarUtils.js +1 -1
  206. package/dist/node_modules/recharts/es6/util/CartesianUtils.js +1 -1
  207. package/dist/node_modules/recharts/es6/util/PolarUtils.js +1 -1
  208. package/dist/node_modules/recharts/es6/util/ReactUtils.js +2 -2
  209. package/dist/node_modules/recharts/es6/util/ReduceCSSCalc.js +1 -1
  210. package/dist/node_modules/recharts/es6/util/types.js +1 -1
  211. package/dist/node_modules/{react-is → recharts/node_modules/react-is}/cjs/react-is.development.js +2 -2
  212. package/dist/node_modules/{react-is → recharts/node_modules/react-is}/cjs/react-is.production.min.js +2 -2
  213. package/dist/node_modules/{react-is → recharts/node_modules/react-is}/index.js +2 -2
  214. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +97 -18
  215. package/dist/node_modules/zustand/esm/middleware.js +2 -2
  216. package/dist/pages/ConsolidationPage.js +76 -0
  217. package/dist/pages/ContainerConditionPage.js +972 -0
  218. package/dist/pages/ContainersPage.js +522 -0
  219. package/dist/pages/EmptyReusePage.js +777 -0
  220. package/dist/pages/FreeTimePage.js +657 -0
  221. package/dist/pages/FreightEstimatePage.js +284 -0
  222. package/dist/pages/InventoryPage.js +77 -73
  223. package/dist/pages/LogisticsProceduresPage.js +100 -0
  224. package/dist/pages/PendingPickPage.js +155 -0
  225. package/dist/pages/StockBindingPage.js +236 -0
  226. package/dist/pages/StockObservationsPage.js +168 -0
  227. package/dist/pages/TripUtilizationPage.js +227 -0
  228. package/dist/src/generated/consolidation-operations.js +505 -0
  229. package/dist/src/generated/container-condition-operations.js +208 -0
  230. package/dist/src/generated/container-operations.js +101 -0
  231. package/dist/src/generated/empty-reuse-operations.js +749 -0
  232. package/dist/src/generated/free-time-operations.js +235 -0
  233. package/dist/src/generated/freight-cost-operations.js +325 -0
  234. package/dist/src/generated/logistics-procedure-operations.js +362 -0
  235. package/dist/src/generated/pending-pick-operations.js +1128 -0
  236. package/dist/src/generated/stock-binding-operations.js +175 -0
  237. package/dist/src/generated/stock-observation-operations.js +93 -0
  238. package/dist/src/generated/trip-utilization-operations.js +140 -0
  239. package/dist/src/generated/wspace-operations.js +708 -0
  240. package/dist/utils/consolidationHistoryTarget.js +27 -0
  241. package/dist/utils/consolidationInput.js +21 -0
  242. package/dist/utils/consolidationLot.js +29 -0
  243. package/dist/utils/consolidationPins.js +13 -0
  244. package/dist/utils/consolidationRecovery.js +40 -0
  245. package/dist/utils/consolidationReportHead.js +18 -0
  246. package/dist/utils/freeTimeDate.js +26 -0
  247. package/dist/utils/freightAcknowledgement.js +8 -0
  248. package/dist/utils/freightDraft.js +125 -0
  249. package/dist/utils/freightRecovery.js +36 -0
  250. package/dist/utils/graphqlClient.js +28 -28
  251. package/dist/utils/pendingPickDraft.js +46 -0
  252. package/dist/utils/procedureInput.js +43 -0
  253. package/dist/utils/procedureRecovery.js +42 -0
  254. package/dist/utils/reuseAttempt.js +20 -0
  255. package/dist/utils/reuseForm.js +25 -0
  256. package/dist/utils/reuseRecovery.js +71 -0
  257. package/dist/utils/stockBindingForm.js +142 -0
  258. package/dist/utils/stockBindingLabels.js +23 -0
  259. package/dist/utils/stockObservationForm.js +55 -0
  260. package/dist/utils/tripDraftContext.js +19 -0
  261. package/dist/utils/tripUtilizationForm.js +60 -0
  262. package/package.json +19 -5
  263. package/src/generated/consolidation-operations.ts +1138 -0
  264. package/src/generated/container-condition-operations.ts +771 -0
  265. package/src/generated/container-operations.ts +376 -0
  266. package/src/generated/empty-reuse-operations.ts +1648 -0
  267. package/src/generated/free-time-operations.ts +814 -0
  268. package/src/generated/freight-cost-operations.ts +753 -0
  269. package/src/generated/logistics-procedure-operations.ts +1047 -0
  270. package/src/generated/pending-pick-operations.ts +1508 -0
  271. package/src/generated/stock-binding-operations.ts +631 -0
  272. package/src/generated/stock-observation-operations.ts +373 -0
  273. package/src/generated/trip-utilization-operations.ts +500 -0
  274. package/src/generated/wspace-operations.ts +116 -0
  275. package/src/movethewheels/MoveTheWheelsRoot.tsx +79 -0
  276. package/src/movethewheels/MoveTheWheelsRoutes.tsx +22 -0
  277. package/src/movethewheels/components/ContainerEvidencePicker.tsx +146 -0
  278. package/src/movethewheels/components/FreeTimeAgreementForm.tsx +483 -0
  279. package/src/movethewheels/components/ReturnInstructionForm.tsx +102 -0
  280. package/src/movethewheels/components/ReuseControls.tsx +138 -0
  281. package/src/movethewheels/components/ReusePermissionForm.tsx +123 -0
  282. package/src/movethewheels/components/ReuseProposalForm.tsx +484 -0
  283. package/src/movethewheels/components/ReuseSourceFields.tsx +80 -0
  284. package/src/movethewheels/components/consolidation/ConsolidationHistory.tsx +159 -0
  285. package/src/movethewheels/components/consolidation/ConsolidationLotEditor.tsx +144 -0
  286. package/src/movethewheels/components/consolidation/ConsolidationManifestWorkbench.tsx +168 -0
  287. package/src/movethewheels/components/consolidation/ConsolidationPlanForm.tsx +185 -0
  288. package/src/movethewheels/components/consolidation/ConsolidationPlanWorkbench.tsx +395 -0
  289. package/src/movethewheels/components/consolidation/ConsolidationReportForm.tsx +124 -0
  290. package/src/movethewheels/components/consolidation/ConsolidationReportsWorkbench.tsx +233 -0
  291. package/src/movethewheels/components/consolidation/ConsolidationSummary.tsx +84 -0
  292. package/src/movethewheels/components/consolidation/OriginalConsolidationHistory.tsx +133 -0
  293. package/src/movethewheels/components/freight-cost/FreightDraftForm.tsx +224 -0
  294. package/src/movethewheels/components/freight-cost/FreightFields.tsx +91 -0
  295. package/src/movethewheels/components/freight-cost/FreightFxEditor.tsx +98 -0
  296. package/src/movethewheels/components/freight-cost/FreightHistory.tsx +91 -0
  297. package/src/movethewheels/components/freight-cost/FreightLineEditor.tsx +192 -0
  298. package/src/movethewheels/components/freight-cost/FreightScopeEditor.tsx +64 -0
  299. package/src/movethewheels/components/freight-cost/FreightTotals.tsx +68 -0
  300. package/src/movethewheels/components/logistics-procedure/ProcedureDecisionForm.tsx +204 -0
  301. package/src/movethewheels/components/logistics-procedure/ProcedureFields.tsx +43 -0
  302. package/src/movethewheels/components/logistics-procedure/ProcedureHistory.tsx +102 -0
  303. package/src/movethewheels/components/logistics-procedure/ProcedurePolicyForm.tsx +226 -0
  304. package/src/movethewheels/components/logistics-procedure/ProcedurePolicyWorkbench.tsx +174 -0
  305. package/src/movethewheels/components/logistics-procedure/ProcedureReviewWorkbench.tsx +278 -0
  306. package/src/movethewheels/components/logistics-procedure/ProcedureRunWorkbench.tsx +292 -0
  307. package/src/movethewheels/components/logistics-procedure/ProcedureSubjectPicker.tsx +111 -0
  308. package/src/movethewheels/components/pending-pick/PendingPickDraft.tsx +82 -0
  309. package/src/movethewheels/components/pending-pick/PendingPickHistory.tsx +93 -0
  310. package/src/movethewheels/components/pending-pick/PickCapture.tsx +70 -0
  311. package/src/movethewheels/components/pending-pick/PickLineSelection.tsx +130 -0
  312. package/src/movethewheels/components/stock-binding/StockAssessmentDraft.tsx +52 -0
  313. package/src/movethewheels/components/stock-binding/StockAssessmentHistory.tsx +56 -0
  314. package/src/movethewheels/components/stock-binding/StockAssessmentSummary.tsx +108 -0
  315. package/src/movethewheels/components/stock-binding/StockFactForm.tsx +186 -0
  316. package/src/movethewheels/components/stock-observation/StockIssueForm.tsx +103 -0
  317. package/src/movethewheels/components/stock-observation/StockIssueHistory.tsx +96 -0
  318. package/src/movethewheels/components/stock-observation/StockIssueReadPanel.tsx +72 -0
  319. package/src/movethewheels/components/trip-utilization/TripReportForm.tsx +116 -0
  320. package/src/movethewheels/components/trip-utilization/TripReportHistory.tsx +51 -0
  321. package/src/movethewheels/components/trip-utilization/TripReportSummary.tsx +127 -0
  322. package/src/movethewheels/components/trip-utilization/TripSegmentFields.tsx +118 -0
  323. package/src/movethewheels/hooks/useConsolidationAction.ts +196 -0
  324. package/src/movethewheels/hooks/useContainerCondition.ts +129 -0
  325. package/src/movethewheels/hooks/useContainerLifecycle.ts +291 -0
  326. package/src/movethewheels/hooks/useEmptyReuseAction.ts +72 -0
  327. package/src/movethewheels/hooks/useFreightRecoveryAction.ts +201 -0
  328. package/src/movethewheels/hooks/useInventory.ts +2 -20
  329. package/src/movethewheels/hooks/useProcedureAction.ts +196 -0
  330. package/src/movethewheels/hooks/useProcedureSelection.ts +75 -0
  331. package/src/movethewheels/hooks/useReuseRecoveryAction.ts +192 -0
  332. package/src/movethewheels/pages/ConsolidationPage.tsx +70 -0
  333. package/src/movethewheels/pages/ContainerConditionPage.tsx +959 -0
  334. package/src/movethewheels/pages/ContainersPage.tsx +490 -0
  335. package/src/movethewheels/pages/EmptyReusePage.tsx +823 -0
  336. package/src/movethewheels/pages/FreeTimePage.tsx +720 -0
  337. package/src/movethewheels/pages/FreightEstimatePage.tsx +353 -0
  338. package/src/movethewheels/pages/InventoryPage.tsx +16 -2
  339. package/src/movethewheels/pages/LogisticsProceduresPage.tsx +86 -0
  340. package/src/movethewheels/pages/PendingPickPage.tsx +226 -0
  341. package/src/movethewheels/pages/StockBindingPage.tsx +299 -0
  342. package/src/movethewheels/pages/StockObservationsPage.tsx +181 -0
  343. package/src/movethewheels/pages/TripUtilizationPage.tsx +315 -0
  344. package/src/movethewheels/utils/consolidationHistoryTarget.ts +39 -0
  345. package/src/movethewheels/utils/consolidationInput.ts +70 -0
  346. package/src/movethewheels/utils/consolidationLot.ts +24 -0
  347. package/src/movethewheels/utils/consolidationPins.ts +52 -0
  348. package/src/movethewheels/utils/consolidationRecovery.ts +88 -0
  349. package/src/movethewheels/utils/consolidationReportHead.ts +29 -0
  350. package/src/movethewheels/utils/freeTimeDate.ts +31 -0
  351. package/src/movethewheels/utils/freightAcknowledgement.ts +31 -0
  352. package/src/movethewheels/utils/freightDraft.ts +170 -0
  353. package/src/movethewheels/utils/freightRecovery.ts +79 -0
  354. package/src/movethewheels/utils/graphqlClient.ts +14 -5
  355. package/src/movethewheels/utils/pendingPickDraft.ts +61 -0
  356. package/src/movethewheels/utils/procedureInput.ts +98 -0
  357. package/src/movethewheels/utils/procedureRecovery.ts +92 -0
  358. package/src/movethewheels/utils/reuseAttempt.ts +29 -0
  359. package/src/movethewheels/utils/reuseForm.ts +30 -0
  360. package/src/movethewheels/utils/reuseRecovery.ts +151 -0
  361. package/src/movethewheels/utils/stockBindingForm.ts +209 -0
  362. package/src/movethewheels/utils/stockBindingLabels.ts +41 -0
  363. package/src/movethewheels/utils/stockObservationForm.ts +73 -0
  364. package/src/movethewheels/utils/tripDraftContext.ts +61 -0
  365. package/src/movethewheels/utils/tripUtilizationForm.ts +105 -0
  366. package/src/operations/condition/container-condition.graphql +41 -0
  367. package/src/operations/consolidation/consolidation.graphql +490 -0
  368. package/src/operations/container/container-lifecycle.graphql +80 -0
  369. package/src/operations/empty-reuse/empty-reuse.graphql +737 -0
  370. package/src/operations/free-time/free-time.graphql +47 -0
  371. package/src/operations/freight-cost/freight.graphql +6 -0
  372. package/src/operations/logistics-procedure/procedure.graphql +15 -0
  373. package/src/operations/pending-pick/pending-pick.graphql +1122 -0
  374. package/src/operations/stock-binding/stock-binding.graphql +160 -0
  375. package/src/operations/stock-observation/stock-observation.graphql +20 -0
  376. package/src/operations/trip-utilization/trip-utilization.graphql +126 -0
  377. package/src/operations/wspace/container-evidence.graphql +6 -0
@@ -0,0 +1,823 @@
1
+ import { reuseText } from '../utils/reuseForm';
2
+ import { useState } from 'react';
3
+ import { Repeat2 } from 'lucide-react';
4
+ import { PageLayout } from '../components/PageLayout';
5
+ import { Button } from '../components/ui';
6
+ import {
7
+ PinnedSelect,
8
+ ReuseField,
9
+ ReusePager,
10
+ ReuseState,
11
+ reuseCard,
12
+ } from '../components/ReuseControls';
13
+ import { ReturnInstructionForm } from '../components/ReturnInstructionForm';
14
+ import { ReuseProposalForm } from '../components/ReuseProposalForm';
15
+ import { ReusePermissionForm } from '../components/ReusePermissionForm';
16
+ import { useConditionQuery } from '../hooks/useContainerCondition';
17
+ import { useReuseRecoveryAction } from '../hooks/useReuseRecoveryAction';
18
+ import {
19
+ ReuseContainersDocument,
20
+ ReuseCyclesDocument,
21
+ ReturnInstructionsDocument,
22
+ BoundReturnInstructionDocument,
23
+ ReuseProposalsDocument,
24
+ ReuseApprovalsDocument,
25
+ ReuseEligibilityDocument,
26
+ ReuseReservationsDocument,
27
+ ReuseReservationTransitionsDocument,
28
+ RecordReturnInstructionDocument,
29
+ RecordReuseProposalDocument,
30
+ RecordReuseApprovalDocument,
31
+ AcceptReuseReservationDocument,
32
+ TerminateReuseReservationDocument,
33
+ type ReuseContainersQuery,
34
+ type ReuseCyclesQuery,
35
+ type ReturnInstructionsQuery,
36
+ type BoundReturnInstructionQuery,
37
+ type ReuseProposalsQuery,
38
+ type ReuseApprovalsQuery,
39
+ type ReuseEligibilityQuery,
40
+ type ReuseReservationsQuery,
41
+ type ReuseReservationTransitionsQuery,
42
+ type ReturnInstructionFieldsFragment,
43
+ type ReuseProposalFieldsFragment,
44
+ type ReuseApprovalFieldsFragment,
45
+ type ReuseReservationFieldsFragment,
46
+ type RecordReturnInstructionMutation,
47
+ type RecordReuseProposalMutation,
48
+ type RecordReuseApprovalMutation,
49
+ type AcceptReuseReservationMutation,
50
+ type TerminateReuseReservationMutation,
51
+ } from '../../generated/empty-reuse-operations';
52
+
53
+ type ContainerRow = ReuseContainersQuery['mtwContainerPage']['items'][number];
54
+ type CycleRow = ReuseCyclesQuery['mtwContainerCyclePage']['items'][number];
55
+ const page = (offset: number) => ({ limit: 25, offset });
56
+ function EvidenceHistory({
57
+ evidence,
58
+ }: {
59
+ evidence: { fileId: string; versionId: string; sha256Hash: string; checkedAt: string }[];
60
+ }) {
61
+ return (
62
+ <details>
63
+ <summary>Exact evidence versions ({evidence.length})</summary>
64
+ <ul className="space-y-2 text-xs">
65
+ {evidence.map((item) => (
66
+ <li key={item.versionId} className="break-all">
67
+ File {item.fileId}; version {item.versionId}; SHA256 {item.sha256Hash}; checked{' '}
68
+ {item.checkedAt}
69
+ </li>
70
+ ))}
71
+ </ul>
72
+ </details>
73
+ );
74
+ }
75
+ function ProposalHistory({ row }: { row: ReuseProposalFieldsFragment }) {
76
+ return (
77
+ <details className="space-y-2 text-sm">
78
+ <summary>Inspect immutable planning revision</summary>
79
+ <p>
80
+ Actual event {row.emptyEventId}; condition {row.inspectionId}; instruction{' '}
81
+ {row.instructionId}; route {row.transportRouteId}, updated {row.transportRouteUpdatedAt}.
82
+ </p>
83
+ <p>
84
+ Export booking {row.exportBookingReference}; recipient {row.exporterReference}; handoff{' '}
85
+ {row.handoffLocationReference}: {row.handoffFrom}–{row.handoffUntil}. Equipment{' '}
86
+ {row.requiredEquipmentType}; cargo {row.cargoCategory}.
87
+ </p>
88
+ <p>
89
+ Proposal scope fingerprint:{' '}
90
+ <span className="break-all">{row.assessment.scopeFingerprint}</span>. Qualification{' '}
91
+ {row.assessment.conditionQualificationId ?? 'UNKNOWN'}, version{' '}
92
+ {row.assessment.conditionQualificationVersion ?? 'UNKNOWN'}.
93
+ </p>
94
+ {Object.entries(row.assessment.sources)
95
+ .filter(([name]) => name !== '__typename')
96
+ .map(([name, source]) => (
97
+ <div key={name} className="rounded border p-3">
98
+ <strong>{name}</strong>
99
+ {source && typeof source === 'object' && 'sourceReference' in source ? (
100
+ <>
101
+ <p>
102
+ {source.purpose}: {source.sourceReference}, revision {source.sourceRevision};
103
+ observed {source.observedAt}; valid {source.validFrom}–{source.validUntil};
104
+ recorded {source.recordedAt} by {source.recordedByActorId}.
105
+ </p>
106
+ <p className="break-all">Purpose scope: {source.scopeFingerprint}</p>
107
+ <EvidenceHistory evidence={source.evidence} />
108
+ </>
109
+ ) : (
110
+ <p>UNKNOWN: no purpose-specific source</p>
111
+ )}
112
+ </div>
113
+ ))}
114
+ <p>
115
+ Timing{' '}
116
+ {row.assessment.timing
117
+ ? `departure ${row.assessment.timing.departureAt}, travel ≤${row.assessment.timing.maxTravelSeconds}s, wait ≤${row.assessment.timing.maxWaitSeconds}s, full leg ≤${row.assessment.timing.maxFullReuseAndReturnSeconds}s; return ${row.assessment.timing.plannedReturnFrom}–${row.assessment.timing.plannedReturnUntil}`
118
+ : 'UNKNOWN'}
119
+ . Route binding{' '}
120
+ {row.assessment.routeBinding
121
+ ? `waypoints ${row.assessment.routeBinding.handoffWaypointIndex} → ${row.assessment.routeBinding.returnWaypointIndex}`
122
+ : 'UNKNOWN'}
123
+ .
124
+ </p>
125
+ <EvidenceHistory evidence={row.evidence} />
126
+ </details>
127
+ );
128
+ }
129
+ export default function EmptyReusePage() {
130
+ const mutations = useReuseRecoveryAction();
131
+ return (
132
+ <PageLayout
133
+ title="Empty return and reuse planning"
134
+ subtitle="Sourced obligations, planning revisions and separate dispatch-review reservations."
135
+ icon={<Repeat2 aria-hidden="true" />}
136
+ >
137
+ <ReuseWorkbench key={mutations.contextKey} mutations={mutations} />
138
+ </PageLayout>
139
+ );
140
+ }
141
+ function ReuseWorkbench({ mutations }: { mutations: ReturnType<typeof useReuseRecoveryAction> }) {
142
+ const [container, setContainer] = useState<ContainerRow | null>(null);
143
+ const [selectedCycle, setSelectedCycle] = useState<{ row: CycleRow; offset: number } | null>(
144
+ null
145
+ );
146
+ const [containerOffset, setContainerOffset] = useState(0);
147
+ const [cycleOffset, setCycleOffset] = useState(0);
148
+ const [instructionOffset, setInstructionOffset] = useState(0);
149
+ const [proposalOffset, setProposalOffset] = useState(0);
150
+ const [approvalOffset, setApprovalOffset] = useState(0);
151
+ const [reservationOffset, setReservationOffset] = useState(0);
152
+ const [instruction, setInstruction] = useState<ReturnInstructionFieldsFragment | null>(null);
153
+ const [proposal, setProposal] = useState<ReuseProposalFieldsFragment | null>(null);
154
+ const [approval, setApproval] = useState<ReuseApprovalFieldsFragment | null>(null);
155
+ const [selectedReservation, setReservation] = useState<ReuseReservationFieldsFragment | null>(
156
+ null
157
+ );
158
+ const [selectedReservationOffset, setSelectedReservationOffset] = useState(0);
159
+ const [transitionOffset, setTransitionOffset] = useState(0);
160
+ const [action, setAction] = useState<'instruction' | 'draft' | 'revise' | 'permission'>(
161
+ 'instruction'
162
+ );
163
+ const [reviewCount, setReviewCount] = useState(0);
164
+ const [error, setError] = useState<string | null>(null);
165
+ const cycleId = selectedCycle?.row.id ?? '';
166
+ const containers = useConditionQuery<ReuseContainersQuery>(
167
+ ReuseContainersDocument,
168
+ { pagination: page(containerOffset) },
169
+ mutations.revision
170
+ );
171
+ const cycles = useConditionQuery<ReuseCyclesQuery>(
172
+ ReuseCyclesDocument,
173
+ container ? { containerId: container.id, pagination: page(cycleOffset) } : null,
174
+ mutations.revision
175
+ );
176
+ const pinnedCyclePage = useConditionQuery<ReuseCyclesQuery>(
177
+ ReuseCyclesDocument,
178
+ container && selectedCycle && selectedCycle.offset !== cycleOffset
179
+ ? { containerId: container.id, pagination: page(selectedCycle.offset) }
180
+ : null,
181
+ mutations.revision
182
+ );
183
+ const cycle = (
184
+ selectedCycle?.offset === cycleOffset ? cycles.data : pinnedCyclePage.data
185
+ )?.mtwContainerCyclePage.items.find((item) => item.id === cycleId);
186
+ const instructions = useConditionQuery<ReturnInstructionsQuery>(
187
+ ReturnInstructionsDocument,
188
+ cycleId ? { cycleId, pagination: page(instructionOffset) } : null,
189
+ mutations.revision
190
+ );
191
+ const currentInstructions = useConditionQuery<ReturnInstructionsQuery>(
192
+ ReturnInstructionsDocument,
193
+ cycleId && instructionOffset !== 0 ? { cycleId, pagination: { limit: 1, offset: 0 } } : null,
194
+ mutations.revision
195
+ );
196
+ const currentInstruction = (
197
+ instructionOffset === 0 ? instructions.data : currentInstructions.data
198
+ )?.mtwEmptyReturnInstructionPage.items[0];
199
+ const boundInstruction = useConditionQuery<BoundReturnInstructionQuery>(
200
+ BoundReturnInstructionDocument,
201
+ proposal ? { id: proposal.instructionId } : null,
202
+ mutations.revision
203
+ );
204
+ const proposalInstruction = boundInstruction.data?.mtwEmptyReturnInstruction;
205
+ const proposals = useConditionQuery<ReuseProposalsQuery>(
206
+ ReuseProposalsDocument,
207
+ cycleId ? { cycleId, pagination: page(proposalOffset) } : null,
208
+ mutations.revision
209
+ );
210
+ const approvals = useConditionQuery<ReuseApprovalsQuery>(
211
+ ReuseApprovalsDocument,
212
+ proposal ? { proposalId: proposal.id, pagination: page(approvalOffset) } : null,
213
+ mutations.revision
214
+ );
215
+ const reservations = useConditionQuery<ReuseReservationsQuery>(
216
+ ReuseReservationsDocument,
217
+ cycleId ? { cycleId, pagination: page(reservationOffset) } : null,
218
+ mutations.revision
219
+ );
220
+ const pinnedReservationPage = useConditionQuery<ReuseReservationsQuery>(
221
+ ReuseReservationsDocument,
222
+ selectedReservation && selectedReservationOffset !== reservationOffset
223
+ ? { cycleId, pagination: page(selectedReservationOffset) }
224
+ : null,
225
+ mutations.revision
226
+ );
227
+ const reservation = (
228
+ selectedReservationOffset === reservationOffset ? reservations.data : pinnedReservationPage.data
229
+ )?.mtwReuseReservationPage.items.find((item) => item.id === selectedReservation?.id);
230
+ const transitions = useConditionQuery<ReuseReservationTransitionsQuery>(
231
+ ReuseReservationTransitionsDocument,
232
+ selectedReservation
233
+ ? { reservationId: selectedReservation.id, pagination: page(transitionOffset) }
234
+ : null,
235
+ mutations.revision
236
+ );
237
+ const eligibility = useConditionQuery<ReuseEligibilityQuery>(
238
+ ReuseEligibilityDocument,
239
+ proposal && reviewCount ? { proposalId: proposal.id, approvalId: approval?.id } : null,
240
+ mutations.revision + reviewCount
241
+ );
242
+ const assessment = eligibility.data?.mtwReuseEligibility;
243
+ const clearPlanning = () => {
244
+ setInstruction(null);
245
+ setProposal(null);
246
+ setApproval(null);
247
+ setReservation(null);
248
+ setTransitionOffset(0);
249
+ setSelectedReservationOffset(0);
250
+ setInstructionOffset(0);
251
+ setProposalOffset(0);
252
+ setApprovalOffset(0);
253
+ setReservationOffset(0);
254
+ setReviewCount(0);
255
+ setError(null);
256
+ setAction('instruction');
257
+ };
258
+ const selectProposal = (row: ReuseProposalFieldsFragment | null) => {
259
+ setProposal(row);
260
+ setApproval(null);
261
+ setApprovalOffset(0);
262
+ setReviewCount(0);
263
+ setAction('revise');
264
+ setError(null);
265
+ };
266
+ const requireCycle = () => {
267
+ if (mutations.uncertain)
268
+ throw new Error('Resolve the original request before starting another.');
269
+ if (!cycle || cycle.status !== 'OPEN')
270
+ throw new Error('Refresh and select a current open usage cycle.');
271
+ return cycle;
272
+ };
273
+ const approvalRows = approvals.data?.mtwEquipmentReuseApprovalPage.items ?? [];
274
+ const pinnedApprovalRows =
275
+ approval && !approvalRows.some((item) => item.id === approval.id)
276
+ ? [approval, ...approvalRows]
277
+ : approvalRows;
278
+ return (
279
+ <div className="space-y-6">
280
+ <p className="rounded-lg border p-4 text-sm">
281
+ Planning only. A sourced grant does not reserve equipment. Readiness is a point-in-time
282
+ server review of named constraints; a separate reservation rechecks current records. No
283
+ street-turn execution, depot-return event, cargo completion or free-time clock stop is
284
+ recorded here.
285
+ </p>
286
+ <section className={reuseCard} aria-label="Choose equipment and usage cycle">
287
+ <PinnedSelect
288
+ label="Physical container"
289
+ value={container?.id ?? ''}
290
+ disabled={mutations.busy}
291
+ onChange={(id) => {
292
+ setContainer(
293
+ containers.data?.mtwContainerPage.items.find((item) => item.id === id) ?? null
294
+ );
295
+ setSelectedCycle(null);
296
+ setCycleOffset(0);
297
+ clearPlanning();
298
+ }}
299
+ options={
300
+ containers.data?.mtwContainerPage.items.map((item) => ({
301
+ id: item.id,
302
+ label: `${item.containerNumber} — ${item.equipmentType} — ${item.ownerName ?? 'Owner unrecorded'}`,
303
+ })) ?? []
304
+ }
305
+ />
306
+ <ReuseState {...containers} />
307
+ <ReusePager
308
+ page={containers.data?.mtwContainerPage}
309
+ offset={containerOffset}
310
+ onChange={setContainerOffset}
311
+ busy={containers.loading || mutations.busy}
312
+ />
313
+ <PinnedSelect
314
+ label="Usage cycle"
315
+ value={cycleId}
316
+ disabled={!container || mutations.busy}
317
+ onChange={(id) => {
318
+ const row = cycles.data?.mtwContainerCyclePage.items.find((item) => item.id === id);
319
+ setSelectedCycle(row ? { row, offset: cycleOffset } : null);
320
+ clearPlanning();
321
+ }}
322
+ options={
323
+ cycles.data?.mtwContainerCyclePage.items.map((item) => ({
324
+ id: item.id,
325
+ label: `${item.bookingReference ?? item.id} — ${item.status} — v${item.version}`,
326
+ })) ?? []
327
+ }
328
+ />
329
+ <ReuseState {...cycles} />
330
+ <ReuseState {...pinnedCyclePage} />
331
+ <ReusePager
332
+ page={cycles.data?.mtwContainerCyclePage}
333
+ offset={cycleOffset}
334
+ onChange={setCycleOffset}
335
+ busy={cycles.loading || mutations.busy}
336
+ />
337
+ {selectedCycle && (
338
+ <p>
339
+ Selected cycle {cycleId}:{' '}
340
+ {cycle
341
+ ? `${cycle.status}, current version ${cycle.version}`
342
+ : 'Current revision unavailable; writes blocked until refresh.'}
343
+ </p>
344
+ )}
345
+ <Button
346
+ type="button"
347
+ variant="outline"
348
+ disabled={mutations.busy || mutations.uncertain}
349
+ onClick={() => {
350
+ mutations.refresh();
351
+ setError(null);
352
+ }}
353
+ >
354
+ Refresh current records
355
+ </Button>
356
+ </section>
357
+ {cycleId && (
358
+ <>
359
+ <section className={reuseCard} aria-label="Return instruction history">
360
+ <h2 className="text-lg font-semibold">Sourced return instructions</h2>
361
+ <p>
362
+ Current instruction{' '}
363
+ {currentInstruction
364
+ ? `v${currentInstruction.version}: ${currentInstruction.locationReference}`
365
+ : 'not loaded / not recorded'}
366
+ . Earlier versions remain immutable.
367
+ </p>
368
+ <ReuseState {...instructions} />
369
+ <ReuseState {...currentInstructions} />
370
+ {instructions.data?.mtwEmptyReturnInstructionPage.items.map((row) => (
371
+ <article key={row.id} className="space-y-2 rounded border p-3 text-sm">
372
+ <p>
373
+ v{row.version} — {row.ownerReference} — booking {row.bookingReference}; depot{' '}
374
+ {row.depotReference}, location {row.locationReference}.
375
+ </p>
376
+ <p>
377
+ {row.returnFrom}–{row.returnUntil}; effective {row.effectiveAt}; recorded{' '}
378
+ {row.recordedAt}.
379
+ </p>
380
+ <p>
381
+ Instruction id {row.id}; source {row.sourceReference}; reason {row.changeReason};
382
+ supersedes {row.supersedesInstructionId ?? 'none'}.
383
+ </p>
384
+ <EvidenceHistory evidence={row.evidence} />
385
+ <Button
386
+ type="button"
387
+ variant="outline"
388
+ disabled={mutations.busy || mutations.uncertain}
389
+ onClick={() => setInstruction(row)}
390
+ >
391
+ Inspect/select instruction v{row.version}
392
+ </Button>
393
+ </article>
394
+ ))}
395
+ <ReusePager
396
+ page={instructions.data?.mtwEmptyReturnInstructionPage}
397
+ offset={instructionOffset}
398
+ onChange={setInstructionOffset}
399
+ busy={instructions.loading || mutations.busy}
400
+ />
401
+ {instruction && (
402
+ <p className="break-words">
403
+ Pinned history selection: v{instruction.version}, {instruction.locationReference};
404
+ id{instruction.id}. Drafts use the separately loaded current instruction.
405
+ </p>
406
+ )}
407
+ </section>
408
+ <section className={reuseCard} aria-label="Planning proposal history">
409
+ <h2 className="text-lg font-semibold">Immutable planning revisions</h2>
410
+ <ReuseState {...proposals} />
411
+ {proposals.data?.mtwReuseProposalPage.items.map((row) => (
412
+ <article key={row.id} className="space-y-3 rounded border p-3">
413
+ <p>
414
+ {row.proposalReference} — revision{row.revision}, recorded {row.recordedAt}
415
+ </p>
416
+ <ProposalHistory row={row} />
417
+ <Button
418
+ type="button"
419
+ variant="outline"
420
+ disabled={mutations.busy || mutations.uncertain}
421
+ onClick={() => selectProposal(row)}
422
+ >
423
+ Select revision{row.revision}
424
+ </Button>
425
+ </article>
426
+ ))}
427
+ <ReusePager
428
+ page={proposals.data?.mtwReuseProposalPage}
429
+ offset={proposalOffset}
430
+ onChange={setProposalOffset}
431
+ busy={proposals.loading || mutations.busy}
432
+ />
433
+ {proposal && (
434
+ <div className="rounded border p-3">
435
+ <p>
436
+ Pinned selection {proposal.proposalReference}, revision{proposal.revision}, id
437
+ {proposal.id}.
438
+ </p>
439
+ <ProposalHistory row={proposal} />
440
+ </div>
441
+ )}
442
+ </section>
443
+ <section className={reuseCard} aria-label="Record planning evidence">
444
+ <h2 className="text-lg font-semibold">Record planning evidence</h2>
445
+ <PinnedSelect
446
+ label="Planning action"
447
+ value={action}
448
+ disabled={mutations.busy || mutations.uncertain}
449
+ onChange={(value) => {
450
+ const next = (['instruction', 'draft', 'revise', 'permission'] as const).find(
451
+ (item) => item === value
452
+ );
453
+ if (next) {
454
+ setAction(next);
455
+ setError(null);
456
+ }
457
+ }}
458
+ options={[
459
+ { id: 'instruction', label: 'Record/amend current return instruction' },
460
+ { id: 'draft', label: 'Record a new proposal reference' },
461
+ { id: 'revise', label: 'Revise selected proposal reference' },
462
+ { id: 'permission', label: 'Record external permission/rejection/revocation' },
463
+ ]}
464
+ />
465
+ {action === 'instruction' && (
466
+ <ReturnInstructionForm
467
+ key={`instruction:${cycleId}:${currentInstruction?.id}`}
468
+ current={currentInstruction}
469
+ busy={
470
+ mutations.busy ||
471
+ mutations.uncertain ||
472
+ !cycle ||
473
+ instructions.loading ||
474
+ currentInstructions.loading
475
+ }
476
+ onSubmit={async (draft) => {
477
+ const current = requireCycle();
478
+ await mutations.run<RecordReturnInstructionMutation>(
479
+ RecordReturnInstructionDocument,
480
+ {
481
+ ...draft,
482
+ cycleId,
483
+ expectedCycleVersion: current.version,
484
+ currentInstructionId: currentInstruction?.id,
485
+ },
486
+ 'Immutable sourced instruction recorded.'
487
+ );
488
+ }}
489
+ />
490
+ )}
491
+ {(action === 'draft' || action === 'revise') &&
492
+ (currentInstruction && container && (action === 'draft' || proposal) ? (
493
+ <ReuseProposalForm
494
+ key={`${action}:${cycleId}:${currentInstruction.id}:${action === 'revise' ? proposal?.id : 'new'}`}
495
+ cycleId={cycleId}
496
+ containerId={container.id}
497
+ instruction={currentInstruction}
498
+ initial={action === 'revise' ? (proposal ?? undefined) : undefined}
499
+ busy={mutations.busy || mutations.uncertain || !cycle}
500
+ onSubmit={async (draft) => {
501
+ const current = requireCycle();
502
+ const result = await mutations.run<RecordReuseProposalMutation>(
503
+ RecordReuseProposalDocument,
504
+ { ...draft, cycleId, expectedCycleVersion: current.version },
505
+ 'Immutable proposal revision recorded; permission and reservation remain separate.'
506
+ );
507
+ if (result) selectProposal(result.recordMtwReuseProposal);
508
+ }}
509
+ />
510
+ ) : (
511
+ <p>
512
+ Load current return instruction and, for revision, choose an immutable proposal.
513
+ </p>
514
+ ))}
515
+ {action === 'permission' && <ReuseState {...boundInstruction} />}
516
+ {action === 'permission' &&
517
+ (proposal && proposalInstruction ? (
518
+ <ReusePermissionForm
519
+ key={`permission:${proposal.id}`}
520
+ approvals={pinnedApprovalRows}
521
+ ownerReference={proposalInstruction.ownerReference}
522
+ busy={mutations.busy || mutations.uncertain || !cycle}
523
+ onSubmit={async (draft) => {
524
+ const current = requireCycle();
525
+ const result = await mutations.run<RecordReuseApprovalMutation>(
526
+ RecordReuseApprovalDocument,
527
+ { ...draft, proposalId: proposal.id, expectedCycleVersion: current.version },
528
+ 'Sourced external decision recorded; no reservation created.'
529
+ );
530
+ if (result) {
531
+ setApproval(
532
+ result.recordMtwEquipmentReuseApproval.kind === 'APPROVED'
533
+ ? result.recordMtwEquipmentReuseApproval
534
+ : null
535
+ );
536
+ setReviewCount(0);
537
+ }
538
+ }}
539
+ />
540
+ ) : (
541
+ <p>
542
+ Select an exact proposal revision. Its immutable instruction must load
543
+ successfully: {proposal?.instructionId ?? 'no proposal selected'}. The bound owner
544
+ must be read from that instruction, independently of the latest instruction.
545
+ </p>
546
+ ))}
547
+ </section>
548
+ {proposal && (
549
+ <section className={reuseCard} aria-label="Permission history and server eligibility">
550
+ <h2 className="text-lg font-semibold">External permission and server review</h2>
551
+ <ReuseState {...approvals} />
552
+ {approvalRows.map((row) => (
553
+ <article key={row.id} className="space-y-2 rounded border p-3 text-sm">
554
+ <p>
555
+ {row.kind} — {row.counterpartyReference}; source {row.sourceReference};{' '}
556
+ {row.validFrom ?? 'No validity start'}–{row.validUntil ?? 'No validity end'}.
557
+ </p>
558
+ <p>
559
+ {row.note}; recorded {row.recordedAt}; targeted grant {row.approvalId ?? 'none'}
560
+ .
561
+ </p>
562
+ <EvidenceHistory evidence={row.evidence} />
563
+ </article>
564
+ ))}
565
+ <ReusePager
566
+ page={approvals.data?.mtwEquipmentReuseApprovalPage}
567
+ offset={approvalOffset}
568
+ onChange={setApprovalOffset}
569
+ busy={approvals.loading || mutations.busy}
570
+ />
571
+ <PinnedSelect
572
+ label="Exact grant for eligibility and reservation"
573
+ required={false}
574
+ value={approval?.id ?? ''}
575
+ disabled={mutations.busy || mutations.uncertain}
576
+ onChange={(id) => {
577
+ setApproval(pinnedApprovalRows.find((row) => row.id === id) ?? null);
578
+ setReviewCount(0);
579
+ }}
580
+ options={pinnedApprovalRows
581
+ .filter((row) => row.kind === 'APPROVED')
582
+ .map((row) => ({
583
+ id: row.id,
584
+ label: `${row.counterpartyReference} — ${row.sourceReference} — ${row.validUntil}`,
585
+ }))}
586
+ />
587
+ <Button
588
+ type="button"
589
+ variant="outline"
590
+ disabled={mutations.busy || mutations.uncertain || eligibility.loading}
591
+ onClick={() => setReviewCount((value) => value + 1)}
592
+ >
593
+ Review server eligibility
594
+ </Button>
595
+ <ReuseState {...eligibility} />
596
+ {assessment && (
597
+ <>
598
+ <p>
599
+ {assessment.status === 'BLOCKED'
600
+ ? 'Blocked'
601
+ : 'Ready for separate dispatch review'}{' '}
602
+ — evaluated {assessment.evaluatedAt}.
603
+ </p>
604
+ <ul className="space-y-2">
605
+ {assessment.blockers.map((item) => (
606
+ <li key={item.code} className="rounded border p-3">
607
+ <strong>
608
+ {item.certainty}: {item.code}
609
+ </strong>
610
+ <p>{item.reason}</p>
611
+ </li>
612
+ ))}
613
+ </ul>
614
+ <p className="text-sm">
615
+ This result is not allocation authority. Acceptance rechecks latest proposal
616
+ revision, cycle, instruction, evidence and constraints under a container lock.
617
+ </p>
618
+ <Button
619
+ type="button"
620
+ disabled={
621
+ mutations.busy ||
622
+ mutations.uncertain ||
623
+ eligibility.loading ||
624
+ assessment.status !== 'READY_FOR_DISPATCH_REVIEW' ||
625
+ !approval ||
626
+ !cycle
627
+ }
628
+ onClick={async () => {
629
+ setError(null);
630
+ try {
631
+ const current = requireCycle();
632
+ if (!approval) throw new Error('Select exact sourced grant.');
633
+ const result = await mutations.run<AcceptReuseReservationMutation>(
634
+ AcceptReuseReservationDocument,
635
+ {
636
+ proposalId: proposal.id,
637
+ approvalId: approval.id,
638
+ expectedCycleVersion: current.version,
639
+ expectedProposalRevision: proposal.revision,
640
+ },
641
+ 'Planning reservation accepted; equipment has not moved.'
642
+ );
643
+ if (result) {
644
+ setReservation(result.acceptMtwReuseReservation);
645
+ setReservationOffset(0);
646
+ setSelectedReservationOffset(0);
647
+ setTransitionOffset(0);
648
+ }
649
+ } catch (failure) {
650
+ setError(failure instanceof Error ? failure.message : 'Unable to reserve.');
651
+ }
652
+ }}
653
+ >
654
+ Accept separate planning reservation
655
+ </Button>
656
+ </>
657
+ )}
658
+ </section>
659
+ )}
660
+ <section className={reuseCard} aria-label="Planning reservation history">
661
+ <h2 className="text-lg font-semibold">Planning reservations</h2>
662
+ <ReuseState {...reservations} />
663
+ {reservations.data?.mtwReuseReservationPage.items.map((row) => (
664
+ <article key={row.id} className="space-y-2 rounded border p-3 text-sm">
665
+ <p>
666
+ {row.status} — v{row.version}; proposal {row.proposalId}; grant {row.approvalId};
667
+ handoff until {row.handoffUntil}.
668
+ </p>
669
+ <p>
670
+ Created {row.createdAt}; updated {row.updatedAt}.
671
+ </p>
672
+ <Button
673
+ type="button"
674
+ variant="outline"
675
+ disabled={mutations.busy || mutations.uncertain}
676
+ onClick={() => {
677
+ setReservation(row);
678
+ setSelectedReservationOffset(reservationOffset);
679
+ setTransitionOffset(0);
680
+ }}
681
+ >
682
+ Inspect reservation
683
+ </Button>
684
+ </article>
685
+ ))}
686
+ <ReusePager
687
+ page={reservations.data?.mtwReuseReservationPage}
688
+ offset={reservationOffset}
689
+ onChange={setReservationOffset}
690
+ busy={reservations.loading || mutations.busy}
691
+ />
692
+ <ReuseState {...pinnedReservationPage} />
693
+ {selectedReservation && !reservation && (
694
+ <p>
695
+ Selected reservation {selectedReservation.id}. Current state unavailable; refresh
696
+ its original history page before taking action.
697
+ </p>
698
+ )}
699
+ {selectedReservation && (
700
+ <div className="space-y-2">
701
+ <h3 className="font-semibold">Recorded cancellation and expiry decisions</h3>
702
+ <ReuseState {...transitions} />
703
+ {transitions.data?.mtwReuseReservationTransitionPage.items.map((item) => (
704
+ <article key={item.id} className="rounded border p-3">
705
+ <p>
706
+ {item.previousStatus} → {item.status}; {item.recordedAt}; recorded by{' '}
707
+ {item.createdBy}.
708
+ </p>
709
+ <p>{item.reason}</p>
710
+ </article>
711
+ ))}
712
+ <ReusePager
713
+ page={transitions.data?.mtwReuseReservationTransitionPage}
714
+ offset={transitionOffset}
715
+ onChange={setTransitionOffset}
716
+ busy={transitions.loading || mutations.busy}
717
+ />
718
+ </div>
719
+ )}
720
+ {reservation && (
721
+ <div className="space-y-3 rounded border p-4">
722
+ <p>
723
+ Pinned reservation {reservation.id}: {reservation.status}, version
724
+ {reservation.version}. A terminal reservation does not record return acceptance or
725
+ execution completion.
726
+ </p>
727
+ {reservation.status === 'ACTIVE' && (
728
+ <form
729
+ className="space-y-3"
730
+ onSubmit={async (event) => {
731
+ event.preventDefault();
732
+ setError(null);
733
+ try {
734
+ const values = new FormData(event.currentTarget);
735
+ const status = reuseText(values, 'terminalStatus');
736
+ if (status !== 'CANCELLED' && status !== 'EXPIRED')
737
+ throw new Error('Choose cancellation or expiry.');
738
+ const result = await mutations.run<TerminateReuseReservationMutation>(
739
+ TerminateReuseReservationDocument,
740
+ {
741
+ reservationId: reservation.id,
742
+ expectedVersion: reservation.version,
743
+ status,
744
+ reason: reuseText(values, 'reason'),
745
+ },
746
+ 'Terminal planning decision recorded; operational clocks unchanged.'
747
+ );
748
+ if (result) setReservation(result.terminateMtwReuseReservation);
749
+ } catch (failure) {
750
+ setError(
751
+ failure instanceof Error ? failure.message : 'Unable to terminate.'
752
+ );
753
+ }
754
+ }}
755
+ >
756
+ <fieldset
757
+ disabled={mutations.busy || mutations.uncertain}
758
+ className="space-y-3"
759
+ >
760
+ <label className="block">
761
+ Terminal planning decision
762
+ <select name="terminalStatus" className="mt-1 w-full rounded border p-2">
763
+ <option value="CANCELLED">Cancel</option>
764
+ <option value="EXPIRED">
765
+ Record expiry (server checks deadline elapsed)
766
+ </option>
767
+ </select>
768
+ </label>
769
+ <ReuseField
770
+ label="Cancellation or expiry reason"
771
+ name="reason"
772
+ maxLength={2000}
773
+ />
774
+ <Button type="submit">Record terminal decision</Button>
775
+ </fieldset>
776
+ </form>
777
+ )}
778
+ </div>
779
+ )}
780
+ </section>
781
+ </>
782
+ )}
783
+ {(error || mutations.error) && <p role="alert">{error ?? mutations.error}</p>}
784
+ {mutations.notice && <p role="status">{mutations.notice}</p>}
785
+ {mutations.uncertain && (
786
+ <div className="space-y-3 rounded border p-4">
787
+ <p>
788
+ {mutations.recoveryInvalid &&
789
+ 'The saved request cannot be read safely. Check history before abandoning it. '}
790
+ Result may be uncertain. Refresh history before retrying. “Retry original request”
791
+ reuses its original body, expected revisions and idempotency key; it does not use edited
792
+ form fields. The saved request stays available when context changes. Return to its
793
+ original account, workspace and project to retry. Resolve or explicitly abandon it
794
+ before starting another request.
795
+ </p>
796
+ <Button
797
+ type="button"
798
+ variant="outline"
799
+ disabled={mutations.busy}
800
+ onClick={mutations.refresh}
801
+ >
802
+ Refresh history after uncertain result
803
+ </Button>
804
+ <Button
805
+ type="button"
806
+ disabled={mutations.busy || !mutations.canRetry}
807
+ onClick={mutations.retryOriginal}
808
+ >
809
+ Retry original request
810
+ </Button>
811
+ <Button
812
+ type="button"
813
+ variant="outline"
814
+ disabled={mutations.busy}
815
+ onClick={mutations.discardAttempt}
816
+ >
817
+ Abandon retry after checking history — the server may have saved it
818
+ </Button>
819
+ </div>
820
+ )}
821
+ </div>
822
+ );
823
+ }