@burdenoff/microfe-movethewheels 2026.930.5 → 2026.1010.2
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.
- package/dist/MoveTheWheelsRoot.js +177 -102
- package/dist/MoveTheWheelsRoutes.js +55 -11
- package/dist/_virtual/_rolldown/runtime.js +1 -1
- package/dist/components/ContainerEvidencePicker.js +143 -0
- package/dist/components/FreeTimeAgreementForm.js +496 -0
- package/dist/components/ReturnInstructionForm.js +108 -0
- package/dist/components/ReuseControls.js +91 -0
- package/dist/components/ReusePermissionForm.js +114 -0
- package/dist/components/ReuseProposalForm.js +455 -0
- package/dist/components/ReuseSourceFields.js +78 -0
- package/dist/components/consolidation/ConsolidationHistory.js +244 -0
- package/dist/components/consolidation/ConsolidationLotEditor.js +133 -0
- package/dist/components/consolidation/ConsolidationManifestWorkbench.js +143 -0
- package/dist/components/consolidation/ConsolidationPlanForm.js +172 -0
- package/dist/components/consolidation/ConsolidationPlanWorkbench.js +321 -0
- package/dist/components/consolidation/ConsolidationReportForm.js +94 -0
- package/dist/components/consolidation/ConsolidationReportsWorkbench.js +195 -0
- package/dist/components/consolidation/ConsolidationSummary.js +76 -0
- package/dist/components/consolidation/OriginalConsolidationHistory.js +112 -0
- package/dist/components/freight-cost/FreightDraftForm.js +213 -0
- package/dist/components/freight-cost/FreightFields.js +70 -0
- package/dist/components/freight-cost/FreightFxEditor.js +90 -0
- package/dist/components/freight-cost/FreightHistory.js +164 -0
- package/dist/components/freight-cost/FreightLineEditor.js +191 -0
- package/dist/components/freight-cost/FreightScopeEditor.js +72 -0
- package/dist/components/freight-cost/FreightTotals.js +66 -0
- package/dist/components/logistics-procedure/ProcedureDecisionForm.js +197 -0
- package/dist/components/logistics-procedure/ProcedureFields.js +31 -0
- package/dist/components/logistics-procedure/ProcedureHistory.js +177 -0
- package/dist/components/logistics-procedure/ProcedurePolicyForm.js +227 -0
- package/dist/components/logistics-procedure/ProcedurePolicyWorkbench.js +155 -0
- package/dist/components/logistics-procedure/ProcedureReviewWorkbench.js +221 -0
- package/dist/components/logistics-procedure/ProcedureRunWorkbench.js +190 -0
- package/dist/components/logistics-procedure/ProcedureSubjectPicker.js +130 -0
- package/dist/components/pending-pick/PendingPickDraft.js +84 -0
- package/dist/components/pending-pick/PendingPickHistory.js +113 -0
- package/dist/components/pending-pick/PickCapture.js +166 -0
- package/dist/components/pending-pick/PickLineSelection.js +111 -0
- package/dist/components/stock-binding/StockAssessmentDraft.js +48 -0
- package/dist/components/stock-binding/StockAssessmentHistory.js +61 -0
- package/dist/components/stock-binding/StockAssessmentSummary.js +199 -0
- package/dist/components/stock-binding/StockFactForm.js +232 -0
- package/dist/components/stock-observation/StockIssueForm.js +148 -0
- package/dist/components/stock-observation/StockIssueHistory.js +116 -0
- package/dist/components/stock-observation/StockIssueReadPanel.js +70 -0
- package/dist/components/trip-utilization/TripReportForm.js +118 -0
- package/dist/components/trip-utilization/TripReportHistory.js +54 -0
- package/dist/components/trip-utilization/TripReportSummary.js +216 -0
- package/dist/components/trip-utilization/TripSegmentFields.js +166 -0
- package/dist/generated/consolidation-operations.d.ts +1060 -0
- package/dist/generated/container-condition-operations.d.ts +868 -0
- package/dist/generated/container-operations.d.ts +356 -0
- package/dist/generated/empty-reuse-operations.d.ts +1578 -0
- package/dist/generated/free-time-operations.d.ts +938 -0
- package/dist/generated/freight-cost-operations.d.ts +716 -0
- package/dist/generated/logistics-procedure-operations.d.ts +938 -0
- package/dist/generated/pending-pick-operations.d.ts +1969 -0
- package/dist/generated/stock-binding-operations.d.ts +930 -0
- package/dist/generated/stock-observation-operations.d.ts +476 -0
- package/dist/generated/trip-utilization-operations.d.ts +651 -0
- package/dist/generated/wspace-operations.d.ts +143 -50
- package/dist/hooks/useConsolidationAction.js +119 -0
- package/dist/hooks/useContainerCondition.js +105 -0
- package/dist/hooks/useContainerLifecycle.js +192 -0
- package/dist/hooks/useEmptyReuseAction.js +45 -0
- package/dist/hooks/useFreightRecoveryAction.js +117 -0
- package/dist/hooks/useMultiModalShipments.js +1 -1
- package/dist/hooks/useProcedureAction.js +119 -0
- package/dist/hooks/useProcedureSelection.js +53 -0
- package/dist/hooks/useReuseRecoveryAction.js +116 -0
- package/dist/movethewheels/components/ContainerEvidencePicker.d.ts +10 -0
- package/dist/movethewheels/components/FreeTimeAgreementForm.d.ts +14 -0
- package/dist/movethewheels/components/ReturnInstructionForm.d.ts +8 -0
- package/dist/movethewheels/components/ReuseControls.d.ts +42 -0
- package/dist/movethewheels/components/ReusePermissionForm.d.ts +9 -0
- package/dist/movethewheels/components/ReuseProposalForm.d.ts +11 -0
- package/dist/movethewheels/components/ReuseSourceFields.d.ts +9 -0
- package/dist/movethewheels/components/consolidation/ConsolidationHistory.d.ts +13 -0
- package/dist/movethewheels/components/consolidation/ConsolidationLotEditor.d.ts +6 -0
- package/dist/movethewheels/components/consolidation/ConsolidationManifestWorkbench.d.ts +8 -0
- package/dist/movethewheels/components/consolidation/ConsolidationPlanForm.d.ts +8 -0
- package/dist/movethewheels/components/consolidation/ConsolidationPlanWorkbench.d.ts +5 -0
- package/dist/movethewheels/components/consolidation/ConsolidationReportForm.d.ts +9 -0
- package/dist/movethewheels/components/consolidation/ConsolidationReportsWorkbench.d.ts +7 -0
- package/dist/movethewheels/components/consolidation/ConsolidationSummary.d.ts +6 -0
- package/dist/movethewheels/components/consolidation/OriginalConsolidationHistory.d.ts +8 -0
- package/dist/movethewheels/components/freight-cost/FreightDraftForm.d.ts +8 -0
- package/dist/movethewheels/components/freight-cost/FreightFields.d.ts +23 -0
- package/dist/movethewheels/components/freight-cost/FreightFxEditor.d.ts +6 -0
- package/dist/movethewheels/components/freight-cost/FreightHistory.d.ts +5 -0
- package/dist/movethewheels/components/freight-cost/FreightLineEditor.d.ts +8 -0
- package/dist/movethewheels/components/freight-cost/FreightScopeEditor.d.ts +6 -0
- package/dist/movethewheels/components/freight-cost/FreightTotals.d.ts +6 -0
- package/dist/movethewheels/components/logistics-procedure/ProcedureDecisionForm.d.ts +20 -0
- package/dist/movethewheels/components/logistics-procedure/ProcedureFields.d.ts +17 -0
- package/dist/movethewheels/components/logistics-procedure/ProcedureHistory.d.ts +7 -0
- package/dist/movethewheels/components/logistics-procedure/ProcedurePolicyForm.d.ts +10 -0
- package/dist/movethewheels/components/logistics-procedure/ProcedurePolicyWorkbench.d.ts +5 -0
- package/dist/movethewheels/components/logistics-procedure/ProcedureReviewWorkbench.d.ts +5 -0
- package/dist/movethewheels/components/logistics-procedure/ProcedureRunWorkbench.d.ts +6 -0
- package/dist/movethewheels/components/logistics-procedure/ProcedureSubjectPicker.d.ts +7 -0
- package/dist/movethewheels/components/pending-pick/PendingPickDraft.d.ts +16 -0
- package/dist/movethewheels/components/pending-pick/PendingPickHistory.d.ts +5 -0
- package/dist/movethewheels/components/pending-pick/PickCapture.d.ts +6 -0
- package/dist/movethewheels/components/pending-pick/PickLineSelection.d.ts +17 -0
- package/dist/movethewheels/components/stock-binding/StockAssessmentDraft.d.ts +13 -0
- package/dist/movethewheels/components/stock-binding/StockAssessmentHistory.d.ts +18 -0
- package/dist/movethewheels/components/stock-binding/StockAssessmentSummary.d.ts +9 -0
- package/dist/movethewheels/components/stock-binding/StockFactForm.d.ts +6 -0
- package/dist/movethewheels/components/stock-observation/StockIssueForm.d.ts +7 -0
- package/dist/movethewheels/components/stock-observation/StockIssueHistory.d.ts +7 -0
- package/dist/movethewheels/components/stock-observation/StockIssueReadPanel.d.ts +5 -0
- package/dist/movethewheels/components/trip-utilization/TripReportForm.d.ts +6 -0
- package/dist/movethewheels/components/trip-utilization/TripReportHistory.d.ts +14 -0
- package/dist/movethewheels/components/trip-utilization/TripReportSummary.d.ts +5 -0
- package/dist/movethewheels/components/trip-utilization/TripSegmentFields.d.ts +9 -0
- package/dist/movethewheels/hooks/useConsolidationAction.d.ts +19 -0
- package/dist/movethewheels/hooks/useContainerCondition.d.ts +21 -0
- package/dist/movethewheels/hooks/useContainerLifecycle.d.ts +40 -0
- package/dist/movethewheels/hooks/useEmptyReuseAction.d.ts +14 -0
- package/dist/movethewheels/hooks/useFreightRecoveryAction.d.ts +23 -0
- package/dist/movethewheels/hooks/useProcedureAction.d.ts +18 -0
- package/dist/movethewheels/hooks/useProcedureSelection.d.ts +51 -0
- package/dist/movethewheels/hooks/useReuseRecoveryAction.d.ts +18 -0
- package/dist/movethewheels/pages/ConsolidationPage.d.ts +1 -0
- package/dist/movethewheels/pages/ContainerConditionPage.d.ts +1 -0
- package/dist/movethewheels/pages/ContainersPage.d.ts +2 -0
- package/dist/movethewheels/pages/EmptyReusePage.d.ts +1 -0
- package/dist/movethewheels/pages/FreeTimePage.d.ts +1 -0
- package/dist/movethewheels/pages/FreightEstimatePage.d.ts +1 -0
- package/dist/movethewheels/pages/LogisticsProceduresPage.d.ts +1 -0
- package/dist/movethewheels/pages/PendingPickPage.d.ts +1 -0
- package/dist/movethewheels/pages/StockBindingPage.d.ts +1 -0
- package/dist/movethewheels/pages/StockObservationsPage.d.ts +1 -0
- package/dist/movethewheels/pages/TripUtilizationPage.d.ts +1 -0
- package/dist/movethewheels/utils/consolidationHistoryTarget.d.ts +12 -0
- package/dist/movethewheels/utils/consolidationInput.d.ts +15 -0
- package/dist/movethewheels/utils/consolidationLot.d.ts +3 -0
- package/dist/movethewheels/utils/consolidationPins.d.ts +20 -0
- package/dist/movethewheels/utils/consolidationRecovery.d.ts +5 -0
- package/dist/movethewheels/utils/consolidationReportHead.d.ts +5 -0
- package/dist/movethewheels/utils/freeTimeDate.d.ts +1 -0
- package/dist/movethewheels/utils/freightAcknowledgement.d.ts +2 -0
- package/dist/movethewheels/utils/freightDraft.d.ts +36 -0
- package/dist/movethewheels/utils/freightRecovery.d.ts +5 -0
- package/dist/movethewheels/utils/graphqlClient.d.ts +2 -1
- package/dist/movethewheels/utils/pendingPickDraft.d.ts +8 -0
- package/dist/movethewheels/utils/procedureInput.d.ts +18 -0
- package/dist/movethewheels/utils/procedureRecovery.d.ts +5 -0
- package/dist/movethewheels/utils/reuseAttempt.d.ts +7 -0
- package/dist/movethewheels/utils/reuseForm.d.ts +6 -0
- package/dist/movethewheels/utils/reuseRecovery.d.ts +26 -0
- package/dist/movethewheels/utils/stockBindingForm.d.ts +23 -0
- package/dist/movethewheels/utils/stockBindingLabels.d.ts +10 -0
- package/dist/movethewheels/utils/stockObservationForm.d.ts +5 -0
- package/dist/movethewheels/utils/tripDraftContext.d.ts +25 -0
- package/dist/movethewheels/utils/tripUtilizationForm.d.ts +6 -0
- package/dist/node_modules/@react-leaflet/core/lib/component.js +5 -5
- package/dist/node_modules/fast-equals/dist/es/index.js +87 -74
- package/dist/node_modules/leaflet/dist/leaflet-src.js +8 -5
- package/dist/node_modules/lodash/_Stack.js +2 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/clipboard-list.js +35 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/repeat-2.js +22 -0
- package/dist/node_modules/react-leaflet/lib/MapContainer.js +3 -3
- package/dist/node_modules/react-smooth/es6/Animate.js +2 -2
- package/dist/node_modules/recharts/es6/cartesian/Area.js +13 -13
- package/dist/node_modules/recharts/es6/cartesian/Bar.js +9 -9
- package/dist/node_modules/recharts/es6/cartesian/Brush.js +12 -12
- package/dist/node_modules/recharts/es6/cartesian/CartesianAxis.js +7 -7
- package/dist/node_modules/recharts/es6/cartesian/CartesianGrid.js +13 -13
- package/dist/node_modules/recharts/es6/cartesian/ErrorBar.js +4 -4
- package/dist/node_modules/recharts/es6/cartesian/Line.js +10 -10
- package/dist/node_modules/recharts/es6/cartesian/ReferenceArea.js +3 -3
- package/dist/node_modules/recharts/es6/cartesian/ReferenceDot.js +3 -3
- package/dist/node_modules/recharts/es6/cartesian/ReferenceLine.js +4 -4
- package/dist/node_modules/recharts/es6/cartesian/XAxis.js +3 -3
- package/dist/node_modules/recharts/es6/cartesian/YAxis.js +3 -3
- package/dist/node_modules/recharts/es6/chart/AccessibilityManager.js +1 -1
- package/dist/node_modules/recharts/es6/chart/generateCategoricalChart.js +22 -22
- package/dist/node_modules/recharts/es6/component/Cursor.js +1 -1
- package/dist/node_modules/recharts/es6/component/DefaultLegendContent.js +11 -11
- package/dist/node_modules/recharts/es6/component/DefaultTooltipContent.js +6 -6
- package/dist/node_modules/recharts/es6/component/Label.js +14 -14
- package/dist/node_modules/recharts/es6/component/LabelList.js +6 -6
- package/dist/node_modules/recharts/es6/component/Legend.js +5 -5
- package/dist/node_modules/recharts/es6/component/ResponsiveContainer.js +3 -3
- package/dist/node_modules/recharts/es6/component/Text.js +2 -2
- package/dist/node_modules/recharts/es6/component/Tooltip.js +3 -3
- package/dist/node_modules/recharts/es6/component/TooltipBoundingBox.js +2 -2
- package/dist/node_modules/recharts/es6/container/Layer.js +2 -2
- package/dist/node_modules/recharts/es6/container/Surface.js +2 -2
- package/dist/node_modules/recharts/es6/context/chartLayoutContext.js +2 -2
- package/dist/node_modules/recharts/es6/polar/Pie.js +13 -13
- package/dist/node_modules/recharts/es6/polar/PolarAngleAxis.js +8 -8
- package/dist/node_modules/recharts/es6/polar/PolarRadiusAxis.js +6 -6
- package/dist/node_modules/recharts/es6/shape/Cross.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Curve.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Dot.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Polygon.js +4 -4
- package/dist/node_modules/recharts/es6/shape/Rectangle.js +4 -4
- package/dist/node_modules/recharts/es6/shape/Sector.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Symbols.js +1 -1
- package/dist/node_modules/recharts/es6/shape/Trapezoid.js +4 -4
- package/dist/node_modules/recharts/es6/util/ActiveShapeUtils.js +9 -9
- package/dist/node_modules/recharts/es6/util/BarUtils.js +1 -1
- package/dist/node_modules/recharts/es6/util/CartesianUtils.js +1 -1
- package/dist/node_modules/recharts/es6/util/PolarUtils.js +1 -1
- package/dist/node_modules/recharts/es6/util/ReactUtils.js +2 -2
- package/dist/node_modules/recharts/es6/util/ReduceCSSCalc.js +1 -1
- package/dist/node_modules/recharts/es6/util/types.js +1 -1
- package/dist/node_modules/{react-is → recharts/node_modules/react-is}/cjs/react-is.development.js +2 -2
- package/dist/node_modules/{react-is → recharts/node_modules/react-is}/cjs/react-is.production.min.js +2 -2
- package/dist/node_modules/{react-is → recharts/node_modules/react-is}/index.js +2 -2
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +97 -18
- package/dist/node_modules/zustand/esm/middleware.js +2 -2
- package/dist/pages/ConsolidationPage.js +76 -0
- package/dist/pages/ContainerConditionPage.js +972 -0
- package/dist/pages/ContainersPage.js +522 -0
- package/dist/pages/EmptyReusePage.js +777 -0
- package/dist/pages/FreeTimePage.js +657 -0
- package/dist/pages/FreightEstimatePage.js +284 -0
- package/dist/pages/LogisticsProceduresPage.js +100 -0
- package/dist/pages/PendingPickPage.js +155 -0
- package/dist/pages/StockBindingPage.js +236 -0
- package/dist/pages/StockObservationsPage.js +168 -0
- package/dist/pages/TripUtilizationPage.js +227 -0
- package/dist/src/generated/consolidation-operations.js +505 -0
- package/dist/src/generated/container-condition-operations.js +208 -0
- package/dist/src/generated/container-operations.js +101 -0
- package/dist/src/generated/empty-reuse-operations.js +749 -0
- package/dist/src/generated/free-time-operations.js +235 -0
- package/dist/src/generated/freight-cost-operations.js +325 -0
- package/dist/src/generated/logistics-procedure-operations.js +362 -0
- package/dist/src/generated/pending-pick-operations.js +1128 -0
- package/dist/src/generated/stock-binding-operations.js +175 -0
- package/dist/src/generated/stock-observation-operations.js +93 -0
- package/dist/src/generated/trip-utilization-operations.js +140 -0
- package/dist/src/generated/wspace-operations.js +708 -0
- package/dist/utils/consolidationHistoryTarget.js +27 -0
- package/dist/utils/consolidationInput.js +21 -0
- package/dist/utils/consolidationLot.js +29 -0
- package/dist/utils/consolidationPins.js +13 -0
- package/dist/utils/consolidationRecovery.js +40 -0
- package/dist/utils/consolidationReportHead.js +18 -0
- package/dist/utils/freeTimeDate.js +26 -0
- package/dist/utils/freightAcknowledgement.js +8 -0
- package/dist/utils/freightDraft.js +125 -0
- package/dist/utils/freightRecovery.js +36 -0
- package/dist/utils/graphqlClient.js +28 -28
- package/dist/utils/pendingPickDraft.js +46 -0
- package/dist/utils/procedureInput.js +43 -0
- package/dist/utils/procedureRecovery.js +42 -0
- package/dist/utils/reuseAttempt.js +20 -0
- package/dist/utils/reuseForm.js +25 -0
- package/dist/utils/reuseRecovery.js +71 -0
- package/dist/utils/stockBindingForm.js +142 -0
- package/dist/utils/stockBindingLabels.js +23 -0
- package/dist/utils/stockObservationForm.js +55 -0
- package/dist/utils/tripDraftContext.js +19 -0
- package/dist/utils/tripUtilizationForm.js +60 -0
- package/package.json +20 -5
- package/src/generated/consolidation-operations.ts +1138 -0
- package/src/generated/container-condition-operations.ts +771 -0
- package/src/generated/container-operations.ts +376 -0
- package/src/generated/empty-reuse-operations.ts +1648 -0
- package/src/generated/free-time-operations.ts +814 -0
- package/src/generated/freight-cost-operations.ts +753 -0
- package/src/generated/logistics-procedure-operations.ts +1047 -0
- package/src/generated/pending-pick-operations.ts +1508 -0
- package/src/generated/stock-binding-operations.ts +631 -0
- package/src/generated/stock-observation-operations.ts +373 -0
- package/src/generated/trip-utilization-operations.ts +500 -0
- package/src/generated/wspace-operations.ts +116 -0
- package/src/movethewheels/MoveTheWheelsRoot.tsx +79 -0
- package/src/movethewheels/MoveTheWheelsRoutes.tsx +22 -0
- package/src/movethewheels/components/ContainerEvidencePicker.tsx +146 -0
- package/src/movethewheels/components/FreeTimeAgreementForm.tsx +483 -0
- package/src/movethewheels/components/ReturnInstructionForm.tsx +102 -0
- package/src/movethewheels/components/ReuseControls.tsx +138 -0
- package/src/movethewheels/components/ReusePermissionForm.tsx +123 -0
- package/src/movethewheels/components/ReuseProposalForm.tsx +484 -0
- package/src/movethewheels/components/ReuseSourceFields.tsx +80 -0
- package/src/movethewheels/components/consolidation/ConsolidationHistory.tsx +159 -0
- package/src/movethewheels/components/consolidation/ConsolidationLotEditor.tsx +144 -0
- package/src/movethewheels/components/consolidation/ConsolidationManifestWorkbench.tsx +168 -0
- package/src/movethewheels/components/consolidation/ConsolidationPlanForm.tsx +185 -0
- package/src/movethewheels/components/consolidation/ConsolidationPlanWorkbench.tsx +395 -0
- package/src/movethewheels/components/consolidation/ConsolidationReportForm.tsx +124 -0
- package/src/movethewheels/components/consolidation/ConsolidationReportsWorkbench.tsx +233 -0
- package/src/movethewheels/components/consolidation/ConsolidationSummary.tsx +84 -0
- package/src/movethewheels/components/consolidation/OriginalConsolidationHistory.tsx +133 -0
- package/src/movethewheels/components/freight-cost/FreightDraftForm.tsx +224 -0
- package/src/movethewheels/components/freight-cost/FreightFields.tsx +91 -0
- package/src/movethewheels/components/freight-cost/FreightFxEditor.tsx +98 -0
- package/src/movethewheels/components/freight-cost/FreightHistory.tsx +91 -0
- package/src/movethewheels/components/freight-cost/FreightLineEditor.tsx +192 -0
- package/src/movethewheels/components/freight-cost/FreightScopeEditor.tsx +64 -0
- package/src/movethewheels/components/freight-cost/FreightTotals.tsx +68 -0
- package/src/movethewheels/components/logistics-procedure/ProcedureDecisionForm.tsx +204 -0
- package/src/movethewheels/components/logistics-procedure/ProcedureFields.tsx +43 -0
- package/src/movethewheels/components/logistics-procedure/ProcedureHistory.tsx +102 -0
- package/src/movethewheels/components/logistics-procedure/ProcedurePolicyForm.tsx +226 -0
- package/src/movethewheels/components/logistics-procedure/ProcedurePolicyWorkbench.tsx +174 -0
- package/src/movethewheels/components/logistics-procedure/ProcedureReviewWorkbench.tsx +278 -0
- package/src/movethewheels/components/logistics-procedure/ProcedureRunWorkbench.tsx +292 -0
- package/src/movethewheels/components/logistics-procedure/ProcedureSubjectPicker.tsx +111 -0
- package/src/movethewheels/components/pending-pick/PendingPickDraft.tsx +82 -0
- package/src/movethewheels/components/pending-pick/PendingPickHistory.tsx +93 -0
- package/src/movethewheels/components/pending-pick/PickCapture.tsx +70 -0
- package/src/movethewheels/components/pending-pick/PickLineSelection.tsx +130 -0
- package/src/movethewheels/components/stock-binding/StockAssessmentDraft.tsx +52 -0
- package/src/movethewheels/components/stock-binding/StockAssessmentHistory.tsx +56 -0
- package/src/movethewheels/components/stock-binding/StockAssessmentSummary.tsx +108 -0
- package/src/movethewheels/components/stock-binding/StockFactForm.tsx +186 -0
- package/src/movethewheels/components/stock-observation/StockIssueForm.tsx +103 -0
- package/src/movethewheels/components/stock-observation/StockIssueHistory.tsx +96 -0
- package/src/movethewheels/components/stock-observation/StockIssueReadPanel.tsx +72 -0
- package/src/movethewheels/components/trip-utilization/TripReportForm.tsx +116 -0
- package/src/movethewheels/components/trip-utilization/TripReportHistory.tsx +51 -0
- package/src/movethewheels/components/trip-utilization/TripReportSummary.tsx +127 -0
- package/src/movethewheels/components/trip-utilization/TripSegmentFields.tsx +118 -0
- package/src/movethewheels/hooks/useConsolidationAction.ts +196 -0
- package/src/movethewheels/hooks/useContainerCondition.ts +129 -0
- package/src/movethewheels/hooks/useContainerLifecycle.ts +291 -0
- package/src/movethewheels/hooks/useEmptyReuseAction.ts +72 -0
- package/src/movethewheels/hooks/useFreightRecoveryAction.ts +201 -0
- package/src/movethewheels/hooks/useMultiModalShipments.ts +2 -1
- package/src/movethewheels/hooks/useProcedureAction.ts +196 -0
- package/src/movethewheels/hooks/useProcedureSelection.ts +75 -0
- package/src/movethewheels/hooks/useReuseRecoveryAction.ts +192 -0
- package/src/movethewheels/pages/ConsolidationPage.tsx +70 -0
- package/src/movethewheels/pages/ContainerConditionPage.tsx +959 -0
- package/src/movethewheels/pages/ContainersPage.tsx +490 -0
- package/src/movethewheels/pages/EmptyReusePage.tsx +823 -0
- package/src/movethewheels/pages/FreeTimePage.tsx +720 -0
- package/src/movethewheels/pages/FreightEstimatePage.tsx +353 -0
- package/src/movethewheels/pages/LogisticsProceduresPage.tsx +86 -0
- package/src/movethewheels/pages/PendingPickPage.tsx +226 -0
- package/src/movethewheels/pages/StockBindingPage.tsx +299 -0
- package/src/movethewheels/pages/StockObservationsPage.tsx +181 -0
- package/src/movethewheels/pages/TripUtilizationPage.tsx +315 -0
- package/src/movethewheels/utils/consolidationHistoryTarget.ts +39 -0
- package/src/movethewheels/utils/consolidationInput.ts +70 -0
- package/src/movethewheels/utils/consolidationLot.ts +24 -0
- package/src/movethewheels/utils/consolidationPins.ts +52 -0
- package/src/movethewheels/utils/consolidationRecovery.ts +88 -0
- package/src/movethewheels/utils/consolidationReportHead.ts +29 -0
- package/src/movethewheels/utils/freeTimeDate.ts +31 -0
- package/src/movethewheels/utils/freightAcknowledgement.ts +31 -0
- package/src/movethewheels/utils/freightDraft.ts +170 -0
- package/src/movethewheels/utils/freightRecovery.ts +79 -0
- package/src/movethewheels/utils/graphqlClient.ts +14 -5
- package/src/movethewheels/utils/pendingPickDraft.ts +61 -0
- package/src/movethewheels/utils/procedureInput.ts +98 -0
- package/src/movethewheels/utils/procedureRecovery.ts +92 -0
- package/src/movethewheels/utils/reuseAttempt.ts +29 -0
- package/src/movethewheels/utils/reuseForm.ts +30 -0
- package/src/movethewheels/utils/reuseRecovery.ts +151 -0
- package/src/movethewheels/utils/stockBindingForm.ts +209 -0
- package/src/movethewheels/utils/stockBindingLabels.ts +41 -0
- package/src/movethewheels/utils/stockObservationForm.ts +73 -0
- package/src/movethewheels/utils/tripDraftContext.ts +61 -0
- package/src/movethewheels/utils/tripUtilizationForm.ts +105 -0
- package/src/operations/condition/container-condition.graphql +41 -0
- package/src/operations/consolidation/consolidation.graphql +490 -0
- package/src/operations/container/container-lifecycle.graphql +80 -0
- package/src/operations/empty-reuse/empty-reuse.graphql +737 -0
- package/src/operations/free-time/free-time.graphql +47 -0
- package/src/operations/freight-cost/freight.graphql +6 -0
- package/src/operations/logistics-procedure/procedure.graphql +15 -0
- package/src/operations/pending-pick/pending-pick.graphql +1122 -0
- package/src/operations/stock-binding/stock-binding.graphql +160 -0
- package/src/operations/stock-observation/stock-observation.graphql +20 -0
- package/src/operations/trip-utilization/trip-utilization.graphql +126 -0
- package/src/operations/wspace/container-evidence.graphql +6 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { useRef, useState } from 'react';
|
|
2
|
+
import { print, type DocumentNode } from 'graphql';
|
|
3
|
+
import { useConditionApi } from './useContainerCondition';
|
|
4
|
+
import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
|
|
5
|
+
import { matchesFreightAcknowledgement } from '../utils/freightAcknowledgement';
|
|
6
|
+
import {
|
|
7
|
+
SaveFreightCostsDocument,
|
|
8
|
+
type SaveFreightCostsMutation,
|
|
9
|
+
} from '../../generated/freight-cost-operations';
|
|
10
|
+
import {
|
|
11
|
+
reuseRecoveryScope,
|
|
12
|
+
reuseRecoveryContextKey,
|
|
13
|
+
sameReuseRecoveryScope,
|
|
14
|
+
type ReuseRecovery,
|
|
15
|
+
} from '../utils/reuseRecovery';
|
|
16
|
+
import {
|
|
17
|
+
decodeFreightRecovery,
|
|
18
|
+
encodeFreightRecovery,
|
|
19
|
+
FREIGHT_RECOVERY_STORAGE,
|
|
20
|
+
} from '../utils/freightRecovery';
|
|
21
|
+
const documents = [SaveFreightCostsDocument];
|
|
22
|
+
function loadRecovery(): { attempt: ReuseRecovery | null; blocked: boolean } {
|
|
23
|
+
try {
|
|
24
|
+
const raw = sessionStorage.getItem(FREIGHT_RECOVERY_STORAGE);
|
|
25
|
+
const attempt = decodeFreightRecovery(raw);
|
|
26
|
+
return { attempt, blocked: raw !== null && attempt === null };
|
|
27
|
+
} catch {
|
|
28
|
+
return { attempt: null, blocked: true };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** F06 retains one unresolved request across entity/context remounts; it never sends automatically. */
|
|
32
|
+
export function useFreightRecoveryAction() {
|
|
33
|
+
const request = useConditionApi('SINGLE_ATTEMPT');
|
|
34
|
+
const context = useMoveTheWheels();
|
|
35
|
+
const scope = reuseRecoveryScope(
|
|
36
|
+
context.currentUser?.id,
|
|
37
|
+
context.workspaceId,
|
|
38
|
+
context.tenantId,
|
|
39
|
+
context.apiGatewayUrl,
|
|
40
|
+
context.workspaceToken
|
|
41
|
+
);
|
|
42
|
+
const [initial] = useState(loadRecovery);
|
|
43
|
+
const [pending, setPending] = useState<ReuseRecovery | null>(initial.attempt);
|
|
44
|
+
const [blocked, setBlocked] = useState(initial.blocked);
|
|
45
|
+
const pendingRef = useRef(pending);
|
|
46
|
+
const running = useRef(false);
|
|
47
|
+
const [busy, setBusy] = useState(false);
|
|
48
|
+
const contextKey = reuseRecoveryContextKey(scope);
|
|
49
|
+
const [feedback, setFeedback] = useState<{
|
|
50
|
+
scopeKey: string;
|
|
51
|
+
error: string | null;
|
|
52
|
+
notice: string | null;
|
|
53
|
+
}>({ scopeKey: contextKey, error: null, notice: null });
|
|
54
|
+
// Async callbacks retain their submitting context; a new context masks their feedback.
|
|
55
|
+
const setError = (error: string | null) =>
|
|
56
|
+
setFeedback({ scopeKey: contextKey, error, notice: null });
|
|
57
|
+
const setNotice = (notice: string | null) =>
|
|
58
|
+
setFeedback({ scopeKey: contextKey, error: null, notice });
|
|
59
|
+
const [revision, setRevision] = useState(0);
|
|
60
|
+
const retain = (attempt: ReuseRecovery | null, completed?: ReuseRecovery) => {
|
|
61
|
+
if (attempt) sessionStorage.setItem(FREIGHT_RECOVERY_STORAGE, encodeFreightRecovery(attempt));
|
|
62
|
+
else {
|
|
63
|
+
const saved = decodeFreightRecovery(sessionStorage.getItem(FREIGHT_RECOVERY_STORAGE));
|
|
64
|
+
// An older in-flight reply must not erase a subsequently retained attempt after a remount.
|
|
65
|
+
if (
|
|
66
|
+
!completed ||
|
|
67
|
+
(saved?.key === completed.key && sameReuseRecoveryScope(saved.scope, completed.scope))
|
|
68
|
+
)
|
|
69
|
+
sessionStorage.removeItem(FREIGHT_RECOVERY_STORAGE);
|
|
70
|
+
}
|
|
71
|
+
pendingRef.current = attempt;
|
|
72
|
+
setPending(attempt);
|
|
73
|
+
setBlocked(false);
|
|
74
|
+
};
|
|
75
|
+
const send = async (attempt: ReuseRecovery) => {
|
|
76
|
+
if (running.current) return null;
|
|
77
|
+
if (!sameReuseRecoveryScope(attempt.scope, scope)) {
|
|
78
|
+
setError(
|
|
79
|
+
'Return to the original account, organization, workspace and project before retrying.'
|
|
80
|
+
);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const document = documents.find((item) => print(item) === attempt.operation);
|
|
84
|
+
if (!document) {
|
|
85
|
+
setError('The saved operation changed. Check history before abandoning this attempt.');
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
running.current = true;
|
|
89
|
+
setBusy(true);
|
|
90
|
+
setError(null);
|
|
91
|
+
setNotice(null);
|
|
92
|
+
try {
|
|
93
|
+
const result = await request<SaveFreightCostsMutation>(document, {
|
|
94
|
+
input: { ...attempt.input, idempotencyKey: attempt.key },
|
|
95
|
+
});
|
|
96
|
+
if (!matchesFreightAcknowledgement(result, attempt.input))
|
|
97
|
+
throw new Error(
|
|
98
|
+
'The save reply could not be confirmed. Keep the original request and check history.'
|
|
99
|
+
);
|
|
100
|
+
// Clearing storage may fail after a known reply. Retain the same key rather than making a new intent.
|
|
101
|
+
retain(null, attempt);
|
|
102
|
+
setRevision((value) => value + 1);
|
|
103
|
+
setNotice(attempt.success);
|
|
104
|
+
return result;
|
|
105
|
+
} catch (failure) {
|
|
106
|
+
setError(
|
|
107
|
+
failure instanceof Error
|
|
108
|
+
? failure.message
|
|
109
|
+
: 'Unable to save. Check history before retrying.'
|
|
110
|
+
);
|
|
111
|
+
return null;
|
|
112
|
+
} finally {
|
|
113
|
+
running.current = false;
|
|
114
|
+
setBusy(false);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const run = async (document: DocumentNode, input: Record<string, unknown>, success: string) => {
|
|
118
|
+
if (running.current || pendingRef.current || blocked) {
|
|
119
|
+
setError('Resolve the original request before starting another.');
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
if (!scope) {
|
|
123
|
+
setError('Wait for the current account and workspace session.');
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
const operation = print(document);
|
|
127
|
+
if (!documents.some((item) => print(item) === operation)) {
|
|
128
|
+
setError('Unsupported freight operation.');
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
if (sessionStorage.getItem(FREIGHT_RECOVERY_STORAGE) !== null) {
|
|
133
|
+
setError(
|
|
134
|
+
'A saved request is unresolved. Reload this page and check history before starting another.'
|
|
135
|
+
);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
} catch {
|
|
139
|
+
setError('This browser cannot retain the request safely. Nothing was sent.');
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const attempt: ReuseRecovery = {
|
|
143
|
+
version: 1,
|
|
144
|
+
scope,
|
|
145
|
+
operation,
|
|
146
|
+
input: structuredClone(input),
|
|
147
|
+
key: crypto.randomUUID(),
|
|
148
|
+
success,
|
|
149
|
+
};
|
|
150
|
+
try {
|
|
151
|
+
retain(attempt);
|
|
152
|
+
} catch {
|
|
153
|
+
setError('This browser cannot retain the request safely. Nothing was sent.');
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
return send(attempt);
|
|
157
|
+
};
|
|
158
|
+
const retryOriginal = async () => {
|
|
159
|
+
if (pendingRef.current) await send(pendingRef.current);
|
|
160
|
+
};
|
|
161
|
+
const discardAttempt = () => {
|
|
162
|
+
if (running.current) return;
|
|
163
|
+
try {
|
|
164
|
+
retain(null);
|
|
165
|
+
setError(null);
|
|
166
|
+
setNotice(null);
|
|
167
|
+
} catch {
|
|
168
|
+
setError('Unable to clear the saved attempt. Nothing was sent.');
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
return {
|
|
172
|
+
run,
|
|
173
|
+
retryOriginal,
|
|
174
|
+
discardAttempt,
|
|
175
|
+
refresh: () => setRevision((value) => value + 1),
|
|
176
|
+
busy,
|
|
177
|
+
error: feedback.scopeKey === contextKey ? feedback.error : null,
|
|
178
|
+
notice: feedback.scopeKey === contextKey ? feedback.notice : null,
|
|
179
|
+
revision,
|
|
180
|
+
uncertain: pending !== null || blocked,
|
|
181
|
+
recoveryInvalid: blocked,
|
|
182
|
+
canRetry: pending !== null && sameReuseRecoveryScope(pending.scope, scope),
|
|
183
|
+
originalContext: pending?.scope ?? null,
|
|
184
|
+
// A read target never changes the retained intent or grants access across contexts.
|
|
185
|
+
originalHistoryTarget:
|
|
186
|
+
pending &&
|
|
187
|
+
sameReuseRecoveryScope(pending.scope, scope) &&
|
|
188
|
+
typeof pending.input.shipmentId === 'string' &&
|
|
189
|
+
pending.input.shipmentId.trim().length > 0 &&
|
|
190
|
+
pending.input.shipmentId.length <= 200 &&
|
|
191
|
+
typeof pending.input.estimateReference === 'string' &&
|
|
192
|
+
pending.input.estimateReference.trim().length > 0 &&
|
|
193
|
+
pending.input.estimateReference.length <= 200
|
|
194
|
+
? {
|
|
195
|
+
shipmentId: pending.input.shipmentId,
|
|
196
|
+
estimateReference: pending.input.estimateReference,
|
|
197
|
+
}
|
|
198
|
+
: null,
|
|
199
|
+
contextKey,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
@@ -332,7 +332,8 @@ export function useMultiModalShipments(
|
|
|
332
332
|
destination: input.destination,
|
|
333
333
|
legs: input.legs.map(toApiLeg),
|
|
334
334
|
},
|
|
335
|
-
}
|
|
335
|
+
},
|
|
336
|
+
'SINGLE_ATTEMPT'
|
|
336
337
|
);
|
|
337
338
|
const created = mapShipment(data.planMultiModalShipment);
|
|
338
339
|
setShipments((previous) => [created, ...previous]);
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { useRef, useState } from 'react';
|
|
2
|
+
import { print, type DocumentNode } from 'graphql';
|
|
3
|
+
import { useConditionApi } from './useContainerCondition';
|
|
4
|
+
import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
|
|
5
|
+
import {
|
|
6
|
+
PublishProcedureDocument,
|
|
7
|
+
StartProcedureDocument,
|
|
8
|
+
RecordProcedureStepDocument,
|
|
9
|
+
RecordProcedureDeviationDocument,
|
|
10
|
+
RevokeProcedureDeviationDocument,
|
|
11
|
+
} from '../../generated/logistics-procedure-operations';
|
|
12
|
+
import { procedureAcknowledgement } from '../utils/procedureInput';
|
|
13
|
+
import {
|
|
14
|
+
reuseRecoveryScope,
|
|
15
|
+
reuseRecoveryContextKey,
|
|
16
|
+
sameReuseRecoveryScope,
|
|
17
|
+
type ReuseRecovery,
|
|
18
|
+
} from '../utils/reuseRecovery';
|
|
19
|
+
import {
|
|
20
|
+
decodeProcedureRecovery,
|
|
21
|
+
encodeProcedureRecovery,
|
|
22
|
+
PROCEDURE_RECOVERY_STORAGE,
|
|
23
|
+
} from '../utils/procedureRecovery';
|
|
24
|
+
const documents = [
|
|
25
|
+
PublishProcedureDocument,
|
|
26
|
+
StartProcedureDocument,
|
|
27
|
+
RecordProcedureStepDocument,
|
|
28
|
+
RecordProcedureDeviationDocument,
|
|
29
|
+
RevokeProcedureDeviationDocument,
|
|
30
|
+
];
|
|
31
|
+
function loadRecovery(): { attempt: ReuseRecovery | null; blocked: boolean } {
|
|
32
|
+
try {
|
|
33
|
+
const raw = sessionStorage.getItem(PROCEDURE_RECOVERY_STORAGE);
|
|
34
|
+
const attempt = decodeProcedureRecovery(raw);
|
|
35
|
+
return { attempt, blocked: raw !== null && attempt === null };
|
|
36
|
+
} catch {
|
|
37
|
+
return { attempt: null, blocked: true };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** F05 retains one unresolved request across entity/context remounts; it never sends automatically. */
|
|
41
|
+
export function useProcedureAction() {
|
|
42
|
+
const request = useConditionApi('SINGLE_ATTEMPT');
|
|
43
|
+
const context = useMoveTheWheels();
|
|
44
|
+
const scope = reuseRecoveryScope(
|
|
45
|
+
context.currentUser?.id,
|
|
46
|
+
context.workspaceId,
|
|
47
|
+
context.tenantId,
|
|
48
|
+
context.apiGatewayUrl,
|
|
49
|
+
context.workspaceToken
|
|
50
|
+
);
|
|
51
|
+
const [initial] = useState(loadRecovery);
|
|
52
|
+
const [pending, setPending] = useState<ReuseRecovery | null>(initial.attempt);
|
|
53
|
+
const [blocked, setBlocked] = useState(initial.blocked);
|
|
54
|
+
const pendingRef = useRef(pending);
|
|
55
|
+
const running = useRef(false);
|
|
56
|
+
const [busy, setBusy] = useState(false);
|
|
57
|
+
const contextKey = reuseRecoveryContextKey(scope);
|
|
58
|
+
const [feedback, setFeedback] = useState<{
|
|
59
|
+
scopeKey: string;
|
|
60
|
+
error: string | null;
|
|
61
|
+
notice: string | null;
|
|
62
|
+
}>({ scopeKey: contextKey, error: null, notice: null });
|
|
63
|
+
// Async callbacks retain their submitting context; a new context masks their feedback.
|
|
64
|
+
const setError = (error: string | null) =>
|
|
65
|
+
setFeedback({ scopeKey: contextKey, error, notice: null });
|
|
66
|
+
const setNotice = (notice: string | null) =>
|
|
67
|
+
setFeedback({ scopeKey: contextKey, error: null, notice });
|
|
68
|
+
const [revision, setRevision] = useState(0);
|
|
69
|
+
const retain = (attempt: ReuseRecovery | null, completed?: ReuseRecovery) => {
|
|
70
|
+
if (attempt)
|
|
71
|
+
sessionStorage.setItem(PROCEDURE_RECOVERY_STORAGE, encodeProcedureRecovery(attempt));
|
|
72
|
+
else {
|
|
73
|
+
const saved = decodeProcedureRecovery(sessionStorage.getItem(PROCEDURE_RECOVERY_STORAGE));
|
|
74
|
+
// An older in-flight reply must not erase a subsequently retained attempt after a remount.
|
|
75
|
+
if (
|
|
76
|
+
!completed ||
|
|
77
|
+
(saved?.key === completed.key && sameReuseRecoveryScope(saved.scope, completed.scope))
|
|
78
|
+
)
|
|
79
|
+
sessionStorage.removeItem(PROCEDURE_RECOVERY_STORAGE);
|
|
80
|
+
}
|
|
81
|
+
pendingRef.current = attempt;
|
|
82
|
+
setPending(attempt);
|
|
83
|
+
setBlocked(false);
|
|
84
|
+
};
|
|
85
|
+
const send = async (attempt: ReuseRecovery) => {
|
|
86
|
+
if (running.current) return null;
|
|
87
|
+
if (!sameReuseRecoveryScope(attempt.scope, scope)) {
|
|
88
|
+
setError(
|
|
89
|
+
'Return to the original account, organization, workspace and project before retrying.'
|
|
90
|
+
);
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
const document = documents.find((item) => print(item) === attempt.operation);
|
|
94
|
+
if (!document) {
|
|
95
|
+
setError('The saved operation changed. Check history before abandoning this attempt.');
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
running.current = true;
|
|
99
|
+
setBusy(true);
|
|
100
|
+
setError(null);
|
|
101
|
+
setNotice(null);
|
|
102
|
+
try {
|
|
103
|
+
const result = await request<Record<string, unknown>>(document, {
|
|
104
|
+
input: { ...attempt.input, idempotencyKey: attempt.key },
|
|
105
|
+
});
|
|
106
|
+
if (!procedureAcknowledgement(result, attempt.input, attempt.scope.actorId))
|
|
107
|
+
throw new Error(
|
|
108
|
+
'The save reply could not be confirmed. Keep the original request and check history.'
|
|
109
|
+
);
|
|
110
|
+
// Clearing storage may fail after a known reply. Retain the same key rather than making a new intent.
|
|
111
|
+
retain(null, attempt);
|
|
112
|
+
setRevision((value) => value + 1);
|
|
113
|
+
setNotice(attempt.success);
|
|
114
|
+
return result;
|
|
115
|
+
} catch (failure) {
|
|
116
|
+
setError(
|
|
117
|
+
failure instanceof Error
|
|
118
|
+
? failure.message
|
|
119
|
+
: 'Unable to save. Check history before retrying.'
|
|
120
|
+
);
|
|
121
|
+
return null;
|
|
122
|
+
} finally {
|
|
123
|
+
running.current = false;
|
|
124
|
+
setBusy(false);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const run = async (document: DocumentNode, input: Record<string, unknown>, success: string) => {
|
|
128
|
+
if (running.current || pendingRef.current || blocked) {
|
|
129
|
+
setError('Resolve the original request before starting another.');
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
if (!scope) {
|
|
133
|
+
setError('Wait for the current account and workspace session.');
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
const operation = print(document);
|
|
137
|
+
if (!documents.some((item) => print(item) === operation)) {
|
|
138
|
+
setError('Unsupported procedure operation.');
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
if (sessionStorage.getItem(PROCEDURE_RECOVERY_STORAGE) !== null) {
|
|
143
|
+
setError(
|
|
144
|
+
'A saved request is unresolved. Reload this page and check history before starting another.'
|
|
145
|
+
);
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
} catch {
|
|
149
|
+
setError('This browser cannot retain the request safely. Nothing was sent.');
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
const attempt: ReuseRecovery = {
|
|
153
|
+
version: 1,
|
|
154
|
+
scope,
|
|
155
|
+
operation,
|
|
156
|
+
input: structuredClone(input),
|
|
157
|
+
key: crypto.randomUUID(),
|
|
158
|
+
success,
|
|
159
|
+
};
|
|
160
|
+
try {
|
|
161
|
+
retain(attempt);
|
|
162
|
+
} catch {
|
|
163
|
+
setError('This browser cannot retain the request safely. Nothing was sent.');
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
return send(attempt);
|
|
167
|
+
};
|
|
168
|
+
const retryOriginal = async () => {
|
|
169
|
+
if (pendingRef.current) await send(pendingRef.current);
|
|
170
|
+
};
|
|
171
|
+
const discardAttempt = () => {
|
|
172
|
+
if (running.current) return;
|
|
173
|
+
try {
|
|
174
|
+
retain(null);
|
|
175
|
+
setError(null);
|
|
176
|
+
setNotice(null);
|
|
177
|
+
} catch {
|
|
178
|
+
setError('Unable to clear the saved attempt. Nothing was sent.');
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
return {
|
|
182
|
+
run,
|
|
183
|
+
retryOriginal,
|
|
184
|
+
discardAttempt,
|
|
185
|
+
refresh: () => setRevision((value) => value + 1),
|
|
186
|
+
busy,
|
|
187
|
+
error: feedback.scopeKey === contextKey ? feedback.error : null,
|
|
188
|
+
notice: feedback.scopeKey === contextKey ? feedback.notice : null,
|
|
189
|
+
revision,
|
|
190
|
+
uncertain: pending !== null || blocked,
|
|
191
|
+
recoveryInvalid: blocked,
|
|
192
|
+
canRetry: pending !== null && sameReuseRecoveryScope(pending.scope, scope),
|
|
193
|
+
originalContext: pending?.scope ?? null,
|
|
194
|
+
contextKey,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ProcedureContainersDocument,
|
|
4
|
+
ProcedureCyclesDocument,
|
|
5
|
+
ProcedureProposalsDocument,
|
|
6
|
+
type ProcedureContainersQuery,
|
|
7
|
+
type ProcedureCyclesQuery,
|
|
8
|
+
type ProcedureProposalsQuery,
|
|
9
|
+
} from '../../generated/logistics-procedure-operations';
|
|
10
|
+
import { useConditionQuery } from './useContainerCondition';
|
|
11
|
+
export function useProcedureSelection(revision: number) {
|
|
12
|
+
const [containerId, setContainer] = useState(''),
|
|
13
|
+
[cycleId, setCycle] = useState(''),
|
|
14
|
+
[proposalId, setProposal] = useState('');
|
|
15
|
+
const [containerOffset, setContainerOffset] = useState(0),
|
|
16
|
+
[cycleOffset, setCycleOffset] = useState(0),
|
|
17
|
+
[proposalOffset, setProposalOffset] = useState(0);
|
|
18
|
+
const containers = useConditionQuery<ProcedureContainersQuery>(
|
|
19
|
+
ProcedureContainersDocument,
|
|
20
|
+
{ pagination: { limit: 25, offset: containerOffset } },
|
|
21
|
+
revision
|
|
22
|
+
);
|
|
23
|
+
const cycles = useConditionQuery<ProcedureCyclesQuery>(
|
|
24
|
+
ProcedureCyclesDocument,
|
|
25
|
+
containerId ? { containerId, pagination: { limit: 25, offset: cycleOffset } } : null,
|
|
26
|
+
revision
|
|
27
|
+
);
|
|
28
|
+
const proposals = useConditionQuery<ProcedureProposalsQuery>(
|
|
29
|
+
ProcedureProposalsDocument,
|
|
30
|
+
cycleId ? { cycleId, pagination: { limit: 25, offset: proposalOffset } } : null,
|
|
31
|
+
revision
|
|
32
|
+
);
|
|
33
|
+
return {
|
|
34
|
+
containerId,
|
|
35
|
+
cycleId,
|
|
36
|
+
proposalId,
|
|
37
|
+
containerOffset,
|
|
38
|
+
cycleOffset,
|
|
39
|
+
proposalOffset,
|
|
40
|
+
containers,
|
|
41
|
+
cycles,
|
|
42
|
+
proposals,
|
|
43
|
+
cycle: cycles.data?.mtwContainerCyclePage.items.find((row) => row.id === cycleId) ?? null,
|
|
44
|
+
proposal:
|
|
45
|
+
proposals.data?.mtwReuseProposalPage.items.find((row) => row.id === proposalId) ?? null,
|
|
46
|
+
selectContainer: (value: string) => {
|
|
47
|
+
setContainer(value);
|
|
48
|
+
setCycle('');
|
|
49
|
+
setProposal('');
|
|
50
|
+
setCycleOffset(0);
|
|
51
|
+
setProposalOffset(0);
|
|
52
|
+
},
|
|
53
|
+
selectCycle: (value: string) => {
|
|
54
|
+
setCycle(value);
|
|
55
|
+
setProposal('');
|
|
56
|
+
setProposalOffset(0);
|
|
57
|
+
},
|
|
58
|
+
selectProposal: setProposal,
|
|
59
|
+
pageContainers: (offset: number) => {
|
|
60
|
+
setContainerOffset(offset);
|
|
61
|
+
setContainer('');
|
|
62
|
+
setCycle('');
|
|
63
|
+
setProposal('');
|
|
64
|
+
},
|
|
65
|
+
pageCycles: (offset: number) => {
|
|
66
|
+
setCycleOffset(offset);
|
|
67
|
+
setCycle('');
|
|
68
|
+
setProposal('');
|
|
69
|
+
},
|
|
70
|
+
pageProposals: (offset: number) => {
|
|
71
|
+
setProposalOffset(offset);
|
|
72
|
+
setProposal('');
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { useRef, useState } from 'react';
|
|
2
|
+
import { print, type DocumentNode } from 'graphql';
|
|
3
|
+
import { useConditionApi } from './useContainerCondition';
|
|
4
|
+
import { useMoveTheWheels } from '../providers/MoveTheWheelsProvider';
|
|
5
|
+
import {
|
|
6
|
+
RecordReturnInstructionDocument,
|
|
7
|
+
RecordReuseProposalDocument,
|
|
8
|
+
RecordReuseApprovalDocument,
|
|
9
|
+
AcceptReuseReservationDocument,
|
|
10
|
+
TerminateReuseReservationDocument,
|
|
11
|
+
} from '../../generated/empty-reuse-operations';
|
|
12
|
+
import {
|
|
13
|
+
decodeReuseRecovery,
|
|
14
|
+
encodeReuseRecovery,
|
|
15
|
+
REUSE_RECOVERY_STORAGE,
|
|
16
|
+
reuseRecoveryScope,
|
|
17
|
+
reuseRecoveryContextKey,
|
|
18
|
+
sameReuseRecoveryScope,
|
|
19
|
+
type ReuseRecovery,
|
|
20
|
+
} from '../utils/reuseRecovery';
|
|
21
|
+
const documents = [
|
|
22
|
+
RecordReturnInstructionDocument,
|
|
23
|
+
RecordReuseProposalDocument,
|
|
24
|
+
RecordReuseApprovalDocument,
|
|
25
|
+
AcceptReuseReservationDocument,
|
|
26
|
+
TerminateReuseReservationDocument,
|
|
27
|
+
];
|
|
28
|
+
function loadRecovery(): { attempt: ReuseRecovery | null; blocked: boolean } {
|
|
29
|
+
try {
|
|
30
|
+
const raw = sessionStorage.getItem(REUSE_RECOVERY_STORAGE);
|
|
31
|
+
const attempt = decodeReuseRecovery(raw, documents);
|
|
32
|
+
return { attempt, blocked: raw !== null && attempt === null };
|
|
33
|
+
} catch {
|
|
34
|
+
return { attempt: null, blocked: true };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** F02 retains one unresolved request across entity/context remounts; it never sends automatically. */
|
|
38
|
+
export function useReuseRecoveryAction() {
|
|
39
|
+
const request = useConditionApi();
|
|
40
|
+
const context = useMoveTheWheels();
|
|
41
|
+
const scope = reuseRecoveryScope(
|
|
42
|
+
context.currentUser?.id,
|
|
43
|
+
context.workspaceId,
|
|
44
|
+
context.tenantId,
|
|
45
|
+
context.apiGatewayUrl,
|
|
46
|
+
context.workspaceToken
|
|
47
|
+
);
|
|
48
|
+
const [initial] = useState(loadRecovery);
|
|
49
|
+
const [pending, setPending] = useState<ReuseRecovery | null>(initial.attempt);
|
|
50
|
+
const [blocked, setBlocked] = useState(initial.blocked);
|
|
51
|
+
const pendingRef = useRef(pending);
|
|
52
|
+
const running = useRef(false);
|
|
53
|
+
const [busy, setBusy] = useState(false);
|
|
54
|
+
const contextKey = reuseRecoveryContextKey(scope);
|
|
55
|
+
const [feedback, setFeedback] = useState<{
|
|
56
|
+
scopeKey: string;
|
|
57
|
+
error: string | null;
|
|
58
|
+
notice: string | null;
|
|
59
|
+
}>({ scopeKey: contextKey, error: null, notice: null });
|
|
60
|
+
// Async callbacks retain their submitting context; a new context masks their feedback.
|
|
61
|
+
const setError = (error: string | null) =>
|
|
62
|
+
setFeedback({ scopeKey: contextKey, error, notice: null });
|
|
63
|
+
const setNotice = (notice: string | null) =>
|
|
64
|
+
setFeedback({ scopeKey: contextKey, error: null, notice });
|
|
65
|
+
const [revision, setRevision] = useState(0);
|
|
66
|
+
const retain = (attempt: ReuseRecovery | null, completed?: ReuseRecovery) => {
|
|
67
|
+
if (attempt) sessionStorage.setItem(REUSE_RECOVERY_STORAGE, encodeReuseRecovery(attempt));
|
|
68
|
+
else {
|
|
69
|
+
const saved = decodeReuseRecovery(sessionStorage.getItem(REUSE_RECOVERY_STORAGE), documents);
|
|
70
|
+
// An older in-flight reply must not erase a subsequently retained attempt after a remount.
|
|
71
|
+
if (
|
|
72
|
+
!completed ||
|
|
73
|
+
(saved?.key === completed.key && sameReuseRecoveryScope(saved.scope, completed.scope))
|
|
74
|
+
)
|
|
75
|
+
sessionStorage.removeItem(REUSE_RECOVERY_STORAGE);
|
|
76
|
+
}
|
|
77
|
+
pendingRef.current = attempt;
|
|
78
|
+
setPending(attempt);
|
|
79
|
+
setBlocked(false);
|
|
80
|
+
};
|
|
81
|
+
const send = async <T>(attempt: ReuseRecovery) => {
|
|
82
|
+
if (running.current) return null;
|
|
83
|
+
if (!sameReuseRecoveryScope(attempt.scope, scope)) {
|
|
84
|
+
setError(
|
|
85
|
+
'Return to the original account, organization, workspace and project before retrying.'
|
|
86
|
+
);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
const document = documents.find((item) => print(item) === attempt.operation);
|
|
90
|
+
if (!document) {
|
|
91
|
+
setError('The saved operation changed. Check history before abandoning this attempt.');
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
running.current = true;
|
|
95
|
+
setBusy(true);
|
|
96
|
+
setError(null);
|
|
97
|
+
setNotice(null);
|
|
98
|
+
try {
|
|
99
|
+
const result = await request<T>(document, {
|
|
100
|
+
input: { ...attempt.input, idempotencyKey: attempt.key },
|
|
101
|
+
});
|
|
102
|
+
// Clearing storage may fail after a known reply. Retain the same key rather than making a new intent.
|
|
103
|
+
retain(null, attempt);
|
|
104
|
+
setRevision((value) => value + 1);
|
|
105
|
+
setNotice(attempt.success);
|
|
106
|
+
return result;
|
|
107
|
+
} catch (failure) {
|
|
108
|
+
setError(
|
|
109
|
+
failure instanceof Error
|
|
110
|
+
? failure.message
|
|
111
|
+
: 'Unable to save. Check history before retrying.'
|
|
112
|
+
);
|
|
113
|
+
return null;
|
|
114
|
+
} finally {
|
|
115
|
+
running.current = false;
|
|
116
|
+
setBusy(false);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const run = async <T>(
|
|
120
|
+
document: DocumentNode,
|
|
121
|
+
input: Record<string, unknown>,
|
|
122
|
+
success: string
|
|
123
|
+
) => {
|
|
124
|
+
if (running.current || pendingRef.current || blocked) {
|
|
125
|
+
setError('Resolve the original request before starting another.');
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
if (!scope) {
|
|
129
|
+
setError('Wait for the current account and workspace session.');
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const operation = print(document);
|
|
133
|
+
if (!documents.some((item) => print(item) === operation)) {
|
|
134
|
+
setError('Unsupported reuse operation.');
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
if (sessionStorage.getItem(REUSE_RECOVERY_STORAGE) !== null) {
|
|
139
|
+
setError(
|
|
140
|
+
'A saved request is unresolved. Reload this page and check history before starting another.'
|
|
141
|
+
);
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
} catch {
|
|
145
|
+
setError('This browser cannot retain the request safely. Nothing was sent.');
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
const attempt: ReuseRecovery = {
|
|
149
|
+
version: 1,
|
|
150
|
+
scope,
|
|
151
|
+
operation,
|
|
152
|
+
input: structuredClone(input),
|
|
153
|
+
key: crypto.randomUUID(),
|
|
154
|
+
success,
|
|
155
|
+
};
|
|
156
|
+
try {
|
|
157
|
+
retain(attempt);
|
|
158
|
+
} catch {
|
|
159
|
+
setError('This browser cannot retain the request safely. Nothing was sent.');
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
return send<T>(attempt);
|
|
163
|
+
};
|
|
164
|
+
const retryOriginal = async () => {
|
|
165
|
+
if (pendingRef.current) await send(pendingRef.current);
|
|
166
|
+
};
|
|
167
|
+
const discardAttempt = () => {
|
|
168
|
+
if (running.current) return;
|
|
169
|
+
try {
|
|
170
|
+
retain(null);
|
|
171
|
+
setError(null);
|
|
172
|
+
setNotice(null);
|
|
173
|
+
} catch {
|
|
174
|
+
setError('Unable to clear the saved attempt. Nothing was sent.');
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
return {
|
|
178
|
+
run,
|
|
179
|
+
retryOriginal,
|
|
180
|
+
discardAttempt,
|
|
181
|
+
refresh: () => setRevision((value) => value + 1),
|
|
182
|
+
busy,
|
|
183
|
+
error: feedback.scopeKey === contextKey ? feedback.error : null,
|
|
184
|
+
notice: feedback.scopeKey === contextKey ? feedback.notice : null,
|
|
185
|
+
revision,
|
|
186
|
+
uncertain: pending !== null || blocked,
|
|
187
|
+
recoveryInvalid: blocked,
|
|
188
|
+
canRetry: pending !== null && sameReuseRecoveryScope(pending.scope, scope),
|
|
189
|
+
originalContext: pending?.scope ?? null,
|
|
190
|
+
contextKey,
|
|
191
|
+
};
|
|
192
|
+
}
|