@seedtactics/insight-client 16.5.2 → 16.7.0

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 (110) hide show
  1. package/dist/assets/ProgramHighlight-DPTeZ8Si.js +3 -0
  2. package/dist/assets/index-bPAFn3jp.js +364 -0
  3. package/dist/cell-status/basket-cycles.d.ts +21 -0
  4. package/dist/cell-status/basket-cycles.js +80 -0
  5. package/dist/cell-status/current-status.js +11 -3
  6. package/dist/cell-status/estimated-cycle-times.js +8 -4
  7. package/dist/cell-status/inspections.js +2 -2
  8. package/dist/cell-status/loading.js +4 -0
  9. package/dist/cell-status/material-details.d.ts +12 -4
  10. package/dist/cell-status/material-details.js +24 -13
  11. package/dist/cell-status/rebookings.js +15 -17
  12. package/dist/cell-status/scheduled-jobs.d.ts +1 -1
  13. package/dist/cell-status/scheduled-jobs.js +10 -3
  14. package/dist/cell-status/sim-production.js +3 -3
  15. package/dist/cell-status/sim-station-use.d.ts +1 -0
  16. package/dist/cell-status/sim-station-use.js +14 -8
  17. package/dist/cell-status/station-cycles.d.ts +29 -2
  18. package/dist/cell-status/station-cycles.js +81 -11
  19. package/dist/cell-status/tool-replacements.js +1 -1
  20. package/dist/cell-status/tool-usage.js +1 -1
  21. package/dist/components/App.js +101 -66
  22. package/dist/components/BarcodeScanning.js +12 -2
  23. package/dist/components/ErrorsAndLoading.js +10 -1
  24. package/dist/components/LogEntry.d.ts +0 -1
  25. package/dist/components/LogEntry.js +50 -26
  26. package/dist/components/Navigation.js +30 -4
  27. package/dist/components/analysis/AnalysisSelectToolbar.js +5 -1
  28. package/dist/components/analysis/BasketCycleCards.d.ts +1 -0
  29. package/dist/components/analysis/BasketCycleCards.js +145 -0
  30. package/dist/components/analysis/BufferChart.js +10 -4
  31. package/dist/components/analysis/CostPerPiece.js +28 -8
  32. package/dist/components/analysis/CycleChart.js +1 -1
  33. package/dist/components/analysis/DataTable.js +6 -4
  34. package/dist/components/analysis/HeatChart.js +27 -14
  35. package/dist/components/analysis/InspectionSankey.js +17 -6
  36. package/dist/components/analysis/PalletCycleCards.js +15 -4
  37. package/dist/components/analysis/PartCycleCards.js +62 -18
  38. package/dist/components/analysis/StationDataTable.js +14 -11
  39. package/dist/components/analysis/ToolReplacements.js +16 -10
  40. package/dist/components/log-entry-queue-filter.d.ts +2 -0
  41. package/dist/components/log-entry-queue-filter.js +21 -0
  42. package/dist/components/operations/AllMaterial.js +26 -10
  43. package/dist/components/operations/ChartRangeEdit.js +82 -4
  44. package/dist/components/operations/CloseoutReport.js +13 -4
  45. package/dist/components/operations/CompletedParts.js +23 -11
  46. package/dist/components/operations/CurrentWorkorders.js +31 -9
  47. package/dist/components/operations/OEEChart.js +8 -2
  48. package/dist/components/operations/Outliers.js +18 -7
  49. package/dist/components/operations/ProgramHighlight.js +4 -6
  50. package/dist/components/operations/Programs.js +9 -3
  51. package/dist/components/operations/Rebookings.js +8 -4
  52. package/dist/components/operations/RecentCycleChart.js +5 -3
  53. package/dist/components/operations/RecentProduction.js +30 -13
  54. package/dist/components/operations/RecentSchedules.js +6 -2
  55. package/dist/components/operations/RecentStationCycles.js +38 -11
  56. package/dist/components/operations/ShiftSettings.js +3 -3
  57. package/dist/components/operations/SimDayUsage.js +27 -4
  58. package/dist/components/operations/ToolReport.js +5 -1
  59. package/dist/components/operations/WorkorderGantt.js +22 -2
  60. package/dist/components/quality/QualityMaterial.js +11 -8
  61. package/dist/components/quality/RecentFailedInspections.js +3 -1
  62. package/dist/components/routes.d.ts +3 -0
  63. package/dist/components/routes.js +2 -0
  64. package/dist/components/station-monitor/BulkRawMaterial.js +11 -7
  65. package/dist/components/station-monitor/Closeout.js +14 -2
  66. package/dist/components/station-monitor/CustomStationMonitorDialog.js +1 -1
  67. package/dist/components/station-monitor/Inspection.js +23 -11
  68. package/dist/components/station-monitor/InvalidateCycle.js +3 -3
  69. package/dist/components/station-monitor/JobDetails.js +15 -2
  70. package/dist/components/station-monitor/LoadStation.js +274 -31
  71. package/dist/components/station-monitor/Material.js +71 -11
  72. package/dist/components/station-monitor/MoveMaterialArrows.js +4 -4
  73. package/dist/components/station-monitor/QuarantineButton.js +11 -0
  74. package/dist/components/station-monitor/Queues.js +28 -9
  75. package/dist/components/station-monitor/QueuesAddMaterial.js +8 -6
  76. package/dist/components/station-monitor/SelectInspType.js +1 -1
  77. package/dist/components/station-monitor/SelectWorkorder.js +1 -1
  78. package/dist/components/station-monitor/StationToolbar.js +17 -5
  79. package/dist/components/station-monitor/SystemOverview.d.ts +19 -1
  80. package/dist/components/station-monitor/SystemOverview.js +439 -20
  81. package/dist/components/station-monitor/Whiteboard.js +15 -7
  82. package/dist/data/all-material-bins.d.ts +7 -0
  83. package/dist/data/all-material-bins.js +47 -1
  84. package/dist/data/cost-per-piece.js +11 -8
  85. package/dist/data/current-cycles.d.ts +1 -1
  86. package/dist/data/current-cycles.js +62 -17
  87. package/dist/data/move-arrows.d.ts +5 -1
  88. package/dist/data/move-arrows.js +54 -4
  89. package/dist/data/part-summary.js +13 -13
  90. package/dist/data/path-lookup.js +6 -23
  91. package/dist/data/queue-material.d.ts +1 -1
  92. package/dist/data/queue-material.js +18 -17
  93. package/dist/data/results.completed-parts.js +4 -3
  94. package/dist/data/results.cycles.d.ts +15 -6
  95. package/dist/data/results.cycles.js +51 -30
  96. package/dist/data/results.inspection.js +11 -6
  97. package/dist/data/results.oee.js +8 -8
  98. package/dist/data/results.schedules.js +2 -11
  99. package/dist/data/tools-programs.js +5 -6
  100. package/dist/index.html +1 -1
  101. package/dist/network/api.d.ts +22 -4
  102. package/dist/network/api.js +40 -5
  103. package/dist/network/backend-mock.js +15 -8
  104. package/dist/network/backend.js +3 -3
  105. package/dist/network/websocket.js +15 -15
  106. package/dist/util/chart-helpers.d.ts +1 -1
  107. package/dist/util/chart-helpers.js +14 -8
  108. package/package.json +29 -31
  109. package/dist/assets/ProgramHighlight-LvRM40Qr.js +0 -3
  110. package/dist/assets/index-gAFi3Oss.js +0 -364
@@ -41,20 +41,25 @@ import { MenuItem } from "@mui/material";
41
41
  import { ImportExport } from "@mui/icons-material";
42
42
  import StationDataTable from "../analysis/StationDataTable.js";
43
43
  import { PartIdenticon } from "../station-monitor/Material.js";
44
- import { filterStationCycles, FilterAnyMachineKey, copyCyclesToClipboard, plannedOperationMinutes, loadOccupancyCycles, FilterAnyLoadKey, } from "../../data/results.cycles.js";
44
+ import { filterStationCycles, FilterAnyMachineKey, copyCyclesToClipboard, plannedOperationMinutes, loadOccupancyCycles, FilterAnyLoadKey, normalizeCarrierKindFilter, } from "../../data/results.cycles.js";
45
45
  import * as matDetails from "../../cell-status/material-details.js";
46
46
  import { CycleChart } from "../analysis/CycleChart.js";
47
47
  import { last30MaterialSummary } from "../../cell-status/material-summary.js";
48
48
  import { last30EstimatedCycleTimes, } from "../../cell-status/estimated-cycle-times.js";
49
- import { last30StationCycles } from "../../cell-status/station-cycles.js";
49
+ import { basketDisplayName, last30HasBasketCycles, last30StationCycles, } from "../../cell-status/station-cycles.js";
50
50
  import { LazySeq } from "@seedtactics/immutable-collections";
51
51
  import { useSetTitle } from "../routes.js";
52
52
  import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
53
+ import { fmsInformation } from "../../network/server-settings.js";
54
+ function hasLoadCycleOperations(point) {
55
+ return "operations" in point && (point.operations === undefined || Array.isArray(point.operations));
56
+ }
53
57
  const lulShowGraphAtom = atom(true);
54
58
  const machineShowGraphAtom = atom(true);
55
59
  const lulSelectedPartAtom = atom(undefined);
56
60
  const machineSelectedPartAtom = atom(undefined);
57
61
  const machineSelectedOperation = atom(undefined);
62
+ const lulSelectedCarrierAtom = atom("Any");
58
63
  const lulSelectedPalletAtom = atom(undefined);
59
64
  const machineSelectedPalletAtom = atom(undefined);
60
65
  const lulChartZoomAtom = atom({});
@@ -65,10 +70,12 @@ export function RecentStationCycleChart({ ty }) {
65
70
  useSetTitle(ty === "labor" ? "L/U Cycles" : "Machine Cycles");
66
71
  const setMatToShow = useSetAtom(matDetails.materialDialogOpen);
67
72
  const extraStationCycleTooltip = useCallback(function extraStationCycleTooltip(point) {
68
- const partC = point;
73
+ if (!hasLoadCycleOperations(point)) {
74
+ return [];
75
+ }
69
76
  const ret = [];
70
- if (partC.operations) {
71
- for (const mat of partC.operations) {
77
+ if (point.operations) {
78
+ for (const mat of point.operations) {
72
79
  ret.push({
73
80
  title: (mat.mat.serial ? mat.mat.serial : "Material") + " " + mat.operation,
74
81
  value: "Open Card",
@@ -76,8 +83,8 @@ export function RecentStationCycleChart({ ty }) {
76
83
  });
77
84
  }
78
85
  }
79
- else {
80
- for (const mat of partC.material) {
86
+ else if ("material" in point && Array.isArray(point.material)) {
87
+ for (const mat of point.material) {
81
88
  ret.push({
82
89
  title: mat.serial ? mat.serial : "Material",
83
90
  value: "Open Card",
@@ -91,8 +98,13 @@ export function RecentStationCycleChart({ ty }) {
91
98
  const [chartZoom, setChartZoom] = useAtom(ty === "labor" ? lulChartZoomAtom : machineChartZoomAtom);
92
99
  const [selectedPart, setSelectedPart] = useAtom(ty === "labor" ? lulSelectedPartAtom : machineSelectedPartAtom);
93
100
  const [selectedOperation, setSelectedOperation] = useAtom(machineSelectedOperation);
101
+ const [selectedCarrier, setSelectedCarrier] = useAtom(lulSelectedCarrierAtom);
94
102
  const [selectedPallet, setSelectedPallet] = useAtom(ty === "labor" ? lulSelectedPalletAtom : machineSelectedPalletAtom);
95
103
  const [yZoom, setYZoom] = useAtom(ty === "labor" ? lulYZoomAtom : machineYZoomAtom);
104
+ const fmsInfo = useAtomValue(fmsInformation);
105
+ const basketName = basketDisplayName(fmsInfo.basketName);
106
+ const hasBasketCycles = useAtomValue(last30HasBasketCycles);
107
+ const carrierFilter = normalizeCarrierKindFilter(selectedCarrier, ty === "labor" ? hasBasketCycles : true);
96
108
  const estimatedCycleTimes = useAtomValue(last30EstimatedCycleTimes);
97
109
  const default_date_range = [addDays(startOfToday(), -4), addDays(startOfToday(), 1)];
98
110
  const cycles = useAtomValue(last30StationCycles);
@@ -105,6 +117,7 @@ export function RecentStationCycleChart({ ty }) {
105
117
  partAndProc: selectedPart,
106
118
  pallet: selectedPallet,
107
119
  operation: selectedOperation,
120
+ carrierKind: carrierFilter,
108
121
  });
109
122
  }
110
123
  else if (ty === "labor" && showGraph) {
@@ -112,6 +125,7 @@ export function RecentStationCycleChart({ ty }) {
112
125
  zoom: { start: addDays(today, -4), end: addDays(today, 1) },
113
126
  partAndProc: selectedPart,
114
127
  pallet: selectedPallet,
128
+ carrierKind: carrierFilter,
115
129
  });
116
130
  }
117
131
  else {
@@ -120,9 +134,10 @@ export function RecentStationCycleChart({ ty }) {
120
134
  partAndProc: selectedPart,
121
135
  pallet: selectedPallet,
122
136
  station: ty === "labor" ? FilterAnyLoadKey : FilterAnyMachineKey,
137
+ carrierKind: carrierFilter,
123
138
  });
124
139
  }
125
- }, [cycles, ty, selectedPart, selectedPallet, selectedOperation, showGraph]);
140
+ }, [cycles, ty, selectedPart, selectedPallet, selectedOperation, showGraph, carrierFilter]);
126
141
  // If we have selected a part and there is only one operation, default to it.
127
142
  const curOperation = selectedPart
128
143
  ? (selectedOperation ??
@@ -136,12 +151,18 @@ export function RecentStationCycleChart({ ty }) {
136
151
  return undefined;
137
152
  }
138
153
  }, [points, ty, curOperation]);
139
- return (_jsxs(Box, { paddingLeft: "24px", paddingRight: "24px", paddingTop: "10px", children: [_jsxs(Box, { component: "nav", sx: {
154
+ return (_jsxs(Box, { sx: {
155
+ paddingLeft: "24px",
156
+ paddingRight: "24px",
157
+ paddingTop: "10px",
158
+ }, children: [_jsxs(Box, { component: "nav", sx: {
140
159
  display: "flex",
141
160
  minHeight: "2.5em",
142
161
  alignItems: "center",
143
162
  maxWidth: "calc(100vw - 24px - 24px)",
144
- }, children: [_jsxs(Typography, { variant: "subtitle1", children: ["Recent ", ty === "labor" ? "Load/Unload Occupancy" : "Machine Cycles"] }), _jsx(Box, { flexGrow: 1 }), _jsx(FormControl, { size: "small", children: _jsxs(Select, { name: "Station-Cycles-chart-or-table-select", autoWidth: true, value: showGraph ? "graph" : "table", onChange: (e) => setShowGraph(e.target.value === "graph"), children: [_jsx(MenuItem, { value: "graph", children: "Graph" }, "graph"), _jsx(MenuItem, { value: "table", children: "Table" }, "table")] }) }), _jsx(FormControl, { size: "small", children: _jsxs(Select, { autoWidth: true, displayEmpty: true, value: selectedPart
163
+ }, children: [_jsxs(Typography, { variant: "subtitle1", children: ["Recent ", ty === "labor" ? "Load/Unload Occupancy" : "Machine Cycles"] }), _jsx(Box, { sx: {
164
+ flexGrow: 1,
165
+ } }), _jsx(FormControl, { size: "small", children: _jsxs(Select, { name: "Station-Cycles-chart-or-table-select", autoWidth: true, value: showGraph ? "graph" : "table", onChange: (e) => setShowGraph(e.target.value === "graph"), children: [_jsx(MenuItem, { value: "graph", children: "Graph" }, "graph"), _jsx(MenuItem, { value: "table", children: "Table" }, "table")] }) }), _jsx(FormControl, { size: "small", children: _jsxs(Select, { autoWidth: true, displayEmpty: true, value: selectedPart
145
166
  ? points.allPartAndProcNames.findIndex((o) => selectedPart.part === o.part && selectedPart.proc === o.proc)
146
167
  : -1, style: { marginLeft: "1em" }, onChange: (e) => {
147
168
  setSelectedPart(e.target.value === -1 ? undefined : points.allPartAndProcNames[e.target.value]);
@@ -155,5 +176,11 @@ export function RecentStationCycleChart({ ty }) {
155
176
  ]
156
177
  : []),
157
178
  ...points.allMachineOperations.map((oper, idx) => (_jsxs(MenuItem, { value: idx, children: [oper.statGroup, " ", oper.operation] }, idx))),
158
- ] }) })) : undefined, _jsx(FormControl, { size: "small", children: _jsxs(Select, { name: "Station-Cycles-cycle-chart-station-pallet", autoWidth: true, displayEmpty: true, value: selectedPallet || "", style: { marginLeft: "1em" }, onChange: (e) => setSelectedPallet(e.target.value === "" ? undefined : e.target.value), children: [_jsx(MenuItem, { value: "", children: _jsx("em", { children: "Any Pallet" }) }, 0), points.allPalletNames.map((n) => (_jsx(MenuItem, { value: n, children: _jsx("div", { style: { display: "flex", alignItems: "center" }, children: _jsx("span", { style: { marginRight: "1em" }, children: n }) }) }, n)))] }) }), _jsx(Tooltip, { title: "Copy to Clipboard", children: _jsx(IconButton, { onClick: () => copyCyclesToClipboard(points, matSummary.matsById, undefined, ty === "labor"), style: { height: "25px", paddingTop: 0, paddingBottom: 0 }, size: "large", children: _jsx(ImportExport, {}) }) })] }), _jsx("main", { children: showGraph ? (_jsx(CycleChart, { points: points.data, series_label: points.seriesLabel, default_date_range: default_date_range, extra_tooltip: extraStationCycleTooltip, current_date_zoom: chartZoom.zoom, set_date_zoom_range: setChartZoom, yZoom: yZoom, setYZoom: setYZoom, stats: curOperation && ty === "machine" ? estimatedCycleTimes.get(curOperation) : undefined, partCntPerPoint: curOperation ? LazySeq.of(points.data).head()?.[1]?.[0]?.material?.length : undefined, plannedTimeMinutes: plannedMinutes })) : (_jsx(StationDataTable, { points: points.data, matsById: matSummary.matsById, period: { type: "Last30" }, current_date_zoom: undefined, set_date_zoom_range: undefined, showWorkorderAndInspect: true, hideMedian: ty === "labor" })) })] }));
179
+ ] }) })) : undefined, ty === "labor" && hasBasketCycles ? (_jsx(FormControl, { size: "small", children: _jsxs(Select, { autoWidth: true, displayEmpty: true, value: carrierFilter, style: { marginLeft: "1em" }, onChange: (e) => {
180
+ const carrier = e.target.value;
181
+ setSelectedCarrier(carrier);
182
+ if (carrier === "Basket") {
183
+ setSelectedPallet(undefined);
184
+ }
185
+ }, children: [_jsx(MenuItem, { value: "Any", children: _jsx("em", { children: "Any Carrier" }) }), _jsx(MenuItem, { value: "Pallet", children: "Pallet" }), _jsx(MenuItem, { value: "Basket", children: basketName })] }) })) : undefined, ty !== "labor" || carrierFilter !== "Basket" ? (_jsx(FormControl, { size: "small", children: _jsxs(Select, { name: "Station-Cycles-cycle-chart-station-pallet", autoWidth: true, displayEmpty: true, value: selectedPallet || "", style: { marginLeft: "1em" }, onChange: (e) => setSelectedPallet(e.target.value === "" ? undefined : e.target.value), children: [_jsx(MenuItem, { value: "", children: _jsx("em", { children: "Any Pallet" }) }, 0), points.allPalletNames.map((n) => (_jsx(MenuItem, { value: n, children: _jsx("div", { style: { display: "flex", alignItems: "center" }, children: _jsx("span", { style: { marginRight: "1em" }, children: n }) }) }, n)))] }) })) : undefined, _jsx(Tooltip, { title: "Copy to Clipboard", children: _jsx(IconButton, { onClick: () => copyCyclesToClipboard(points, matSummary.matsById, undefined, ty === "labor", fmsInfo.loadStationNames, basketName), style: { height: "25px", paddingTop: 0, paddingBottom: 0 }, size: "large", children: _jsx(ImportExport, {}) }) })] }), _jsx("main", { children: showGraph ? (_jsx(CycleChart, { points: points.data, series_label: points.seriesLabel, default_date_range: default_date_range, extra_tooltip: extraStationCycleTooltip, current_date_zoom: chartZoom.zoom, set_date_zoom_range: setChartZoom, yZoom: yZoom, setYZoom: setYZoom, stats: curOperation && ty === "machine" ? estimatedCycleTimes.get(curOperation) : undefined, partCntPerPoint: curOperation ? LazySeq.of(points.data).head()?.[1]?.[0]?.material?.length : undefined, plannedTimeMinutes: plannedMinutes })) : (_jsx(StationDataTable, { points: points.data, matsById: matSummary.matsById, period: { type: "Last30" }, current_date_zoom: undefined, set_date_zoom_range: undefined, showWorkorderAndInspect: true, hideMedian: ty === "labor" })) })] }));
159
186
  }
@@ -113,12 +113,12 @@ function ShiftStartInput({ shiftNum }) {
113
113
  const [shifts, setShifts] = useAtom(shiftStartAtom);
114
114
  const val = shifts.get(shiftNum);
115
115
  return (_jsx(TextField, { type: "time", label: `Shift ${shiftNum} Start`, error: shiftError(shiftNum, shifts), value: val === undefined ? "" : minutesToTimespan(val), onChange: (e) => {
116
- const val = e.target.value;
117
- if (val === "") {
116
+ const inputValue = e.target.value;
117
+ if (inputValue === "") {
118
118
  setShifts((draft) => draft.delete(shiftNum));
119
119
  }
120
120
  else {
121
- setShifts((draft) => draft.set(shiftNum, timespanToMinutes(val)));
121
+ setShifts((draft) => draft.set(shiftNum, timespanToMinutes(inputValue)));
122
122
  }
123
123
  }, variant: "standard", size: "small", slotProps: {
124
124
  inputLabel: { shrink: true },
@@ -87,15 +87,32 @@ const minAndMaxUsageDay = atom((get) => {
87
87
  function ShowMonth({ date, dayColor, tooltip, }) {
88
88
  const dayStart = new Date(date.getFullYear(), date.getMonth(), 1).getDay();
89
89
  const numDaysInMonth = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
90
- return (_jsxs(Box, { width: monthWidth, children: [_jsx(Typography, { variant: "h6", textAlign: "center", children: date.toLocaleString("default", { month: "long", year: "numeric" }) }), _jsxs(Box, { display: "flex", flexWrap: "wrap", children: [LazySeq.ofRange(0, dayStart).map((_, i) => (_jsx(Box, { height: monthBoxSize, width: monthBoxSize }, i))), LazySeq.ofRange(1, numDaysInMonth + 1).map((d, i) => (_jsx("div", { style: {
90
+ return (_jsxs(Box, { sx: {
91
+ width: monthWidth,
92
+ }, children: [_jsx(Typography, { variant: "h6", sx: {
93
+ textAlign: "center",
94
+ }, children: date.toLocaleString("default", { month: "long", year: "numeric" }) }), _jsxs(Box, { sx: {
95
+ display: "flex",
96
+ flexWrap: "wrap",
97
+ }, children: [LazySeq.ofRange(0, dayStart).map((_, i) => (_jsx(Box, { sx: {
98
+ height: monthBoxSize,
99
+ width: monthBoxSize,
100
+ } }, i))), LazySeq.ofRange(1, numDaysInMonth + 1).map((d, i) => (_jsx("div", { style: {
91
101
  width: monthBoxSize,
92
102
  height: monthBoxSize,
93
103
  cursor: "default",
94
104
  backgroundColor: dayColor(new Date(date.getFullYear(), date.getMonth(), d)),
95
- }, children: _jsx(Tooltip, { title: tooltip(new Date(date.getFullYear(), date.getMonth(), d)), children: _jsx(Box, { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", children: d }) }) }, i)))] })] }));
105
+ }, children: _jsx(Tooltip, { title: tooltip(new Date(date.getFullYear(), date.getMonth(), d)), children: _jsx(Box, { sx: {
106
+ display: "flex",
107
+ justifyContent: "center",
108
+ alignItems: "center",
109
+ height: "100%",
110
+ }, children: d }) }) }, i)))] })] }));
96
111
  }
97
112
  function Warning() {
98
- return (_jsxs(Stack, { direction: "row", spacing: 2, alignItems: "center", children: [_jsx(WarningIcon, { fontSize: "small" }), _jsx(Typography, { variant: "caption", children: "Projected dates are estimates" })] }));
113
+ return (_jsxs(Stack, { direction: "row", spacing: 2, sx: {
114
+ alignItems: "center",
115
+ }, children: [_jsx(WarningIcon, { fontSize: "small" }), _jsx(Typography, { variant: "caption", children: "Projected dates are estimates" })] }));
99
116
  }
100
117
  function MonthHeatmap({ group, month }) {
101
118
  const usage = useAtomValue(groupedSimDayUsage);
@@ -129,5 +146,11 @@ export function SimDayUsagePage() {
129
146
  useSetTitle("Projected Machine Usage");
130
147
  const groups = useAtomValue(machineGroups);
131
148
  const months = useAtomValue(usageMonths);
132
- return (_jsx(Box, { component: "main", padding: "24px", children: _jsxs(Stack, { direction: "column", spacing: 5, children: [_jsx(Warning, {}), groups.toAscLazySeq().map((g) => (_jsxs("div", { children: [_jsx(Typography, { variant: "h4", children: g }), _jsx(Box, { display: "flex", flexWrap: "wrap", columnGap: "50px", children: months.toAscLazySeq().map((m) => (_jsx(MonthHeatmap, { group: g, month: m }, m.getTime()))) })] }, g)))] }) }));
149
+ return (_jsx(Box, { component: "main", sx: {
150
+ padding: "24px",
151
+ }, children: _jsxs(Stack, { direction: "column", spacing: 5, children: [_jsx(Warning, {}), groups.toAscLazySeq().map((g) => (_jsxs("div", { children: [_jsx(Typography, { variant: "h4", children: g }), _jsx(Box, { sx: {
152
+ display: "flex",
153
+ flexWrap: "wrap",
154
+ columnGap: "50px",
155
+ }, children: months.toAscLazySeq().map((m) => (_jsx(MonthHeatmap, { group: g, month: m }, m.getTime()))) })] }, g)))] }) }));
133
156
  }
@@ -229,5 +229,9 @@ function ToolNavHeader() {
229
229
  }
230
230
  export function ToolReportPage() {
231
231
  useSetTitle("Tool Report");
232
- return (_jsxs(Box, { paddingLeft: "24px", paddingRight: "24px", paddingTop: "10px", children: [_jsx(ToolNavHeader, {}), _jsx("main", { children: _jsx(DisplayLoadingAndError, { children: _jsx(ToolSummaryTable, {}) }) })] }));
232
+ return (_jsxs(Box, { sx: {
233
+ paddingLeft: "24px",
234
+ paddingRight: "24px",
235
+ paddingTop: "10px",
236
+ }, children: [_jsx(ToolNavHeader, {}), _jsx("main", { children: _jsx(DisplayLoadingAndError, { children: _jsx(ToolSummaryTable, {}) }) })] }));
233
237
  }
@@ -81,7 +81,17 @@ function WorkorderTooltip({ tooltip }) {
81
81
  return (_jsxs(Stack, { children: [_jsxs("div", { children: ["Workorder: ", tooltip.data.workorderId] }), _jsxs("div", { children: ["Part: ", tooltip.data.part] }), _jsxs("div", { children: ["Due Date: ", tooltip.data.dueDate.toLocaleDateString()] }), _jsxs("div", { children: ["Priority: ", tooltip.data.priority] }), _jsxs("div", { children: ["Planned Quantity: ", tooltip.data.plannedQuantity] }), _jsxs("div", { children: ["Completed Quantity: ", tooltip.data.completedQuantity] }), _jsxs("div", { children: ["Projected Start: ", utcDateOnlyToLocal(tooltip.data.simulatedStart)?.toLocaleDateString()] }), _jsxs("div", { children: ["Projected Filled: ", utcDateOnlyToLocal(tooltip.data.simulatedFilled)?.toLocaleDateString()] })] }));
82
82
  }
83
83
  function YAxis({ workorders }) {
84
- return (_jsx("div", { children: workorders.map((work) => (_jsxs(Stack, { height: rowSize, direction: "column", alignItems: "flex-end", paddingRight: "10px", justifyContent: "center", children: [_jsx(Box, { children: work.workorderId }), _jsxs(Box, { display: "flex", alignItems: "center", children: [_jsx(PartIdenticon, { part: work.part, size: 18 }), _jsx(Box, { ml: "3px", children: work.part })] })] }, workorderKey(work)))) }));
84
+ return (_jsx("div", { children: workorders.map((work) => (_jsxs(Stack, { direction: "column", sx: {
85
+ height: rowSize,
86
+ alignItems: "flex-end",
87
+ paddingRight: "10px",
88
+ justifyContent: "center",
89
+ }, children: [_jsx(Box, { children: work.workorderId }), _jsxs(Box, { sx: {
90
+ display: "flex",
91
+ alignItems: "center",
92
+ }, children: [_jsx(PartIdenticon, { part: work.part, size: 18 }), _jsx(Box, { sx: {
93
+ ml: "3px",
94
+ }, children: work.part })] })] }, workorderKey(work)))) }));
85
95
  }
86
96
  function XAxis({ xScale, yScale }) {
87
97
  return (_jsxs(_Fragment, { children: [_jsx(AxisTop, { scale: xScale, top: 0 }), _jsx(GridCols, { scale: xScale, height: yScale.range()[1] - yScale.range()[0] })] }));
@@ -120,5 +130,15 @@ export function WorkorderGantt() {
120
130
  const currentSt = useAtomValue(currentStatus);
121
131
  const sortedWorkorders = useMemo(() => LazySeq.of(currentSt.workorders ?? []).toSortedArray((w) => w.simulatedFilled?.getTime() ?? null, (w) => w.simulatedStart?.getTime() ?? null, (w) => w.workorderId, (w) => w.part), [currentSt.workorders]);
122
132
  const { xScale, yScale } = useScales(sortedWorkorders);
123
- return (_jsxs(Box, { display: "flex", children: [_jsx(Box, { height: yScale.range()[1] + marginTop + marginBottom, width: namesWidth, paddingTop: `${marginTop}px`, children: _jsx(YAxis, { workorders: sortedWorkorders }) }), _jsxs(Box, { flexGrow: 1, width: 0, position: "relative", children: [_jsx("div", { style: { overflowX: "visible" }, children: _jsx("svg", { height: yScale.range()[1] + marginTop + marginBottom, width: xScale.range()[1] + marginRight + marginLeft, children: _jsxs("g", { transform: `translate(${marginLeft}, ${marginTop})`, children: [_jsx(XAxis, { yScale: yScale, xScale: xScale }), _jsx(Series, { workorders: sortedWorkorders, xScale: xScale, yScale: yScale })] }) }) }), _jsx(Tooltip, { atom: tooltipData, TooltipContent: WorkorderTooltip, chartHeight: yScale.range()[1] + marginTop + marginBottom, chartWidth: xScale.range()[1] + marginRight + marginLeft })] })] }));
133
+ return (_jsxs(Box, { sx: {
134
+ display: "flex",
135
+ }, children: [_jsx(Box, { sx: {
136
+ height: yScale.range()[1] + marginTop + marginBottom,
137
+ width: namesWidth,
138
+ paddingTop: `${marginTop}px`,
139
+ }, children: _jsx(YAxis, { workorders: sortedWorkorders }) }), _jsxs(Box, { sx: {
140
+ flexGrow: 1,
141
+ width: 0,
142
+ position: "relative",
143
+ }, children: [_jsx("div", { style: { overflowX: "visible" }, children: _jsx("svg", { height: yScale.range()[1] + marginTop + marginBottom, width: xScale.range()[1] + marginRight + marginLeft, children: _jsxs("g", { transform: `translate(${marginLeft}, ${marginTop})`, children: [_jsx(XAxis, { yScale: yScale, xScale: xScale }), _jsx(Series, { workorders: sortedWorkorders, xScale: xScale, yScale: yScale })] }) }) }), _jsx(Tooltip, { atom: tooltipData, TooltipContent: WorkorderTooltip, chartHeight: yScale.range()[1] + marginTop + marginBottom, chartWidth: xScale.range()[1] + marginRight + marginLeft })] })] }));
124
144
  }
@@ -46,7 +46,6 @@ import { LogBackend } from "../../network/backend.js";
46
46
  import { LazySeq } from "@seedtactics/immutable-collections";
47
47
  import { RecentFailedInspectionsTable } from "./RecentFailedInspections.js";
48
48
  import { useAtom, useAtomValue, useSetAtom } from "jotai";
49
- import { loadable } from "jotai/utils";
50
49
  function SerialLookup() {
51
50
  const demo = useIsDemo();
52
51
  const setMatToShow = useSetAtom(matDetails.materialDialogOpen);
@@ -77,13 +76,17 @@ function SerialLookup() {
77
76
  setError(e.message);
78
77
  }
79
78
  else {
80
- setError(e.toString());
79
+ setError(e);
81
80
  }
82
81
  })
83
82
  .finally(() => setLoading(false));
84
83
  }
85
84
  }
86
- return (_jsxs(_Fragment, { children: [_jsxs(Stack, { direction: "row", spacing: 2, alignItems: "center", marginLeft: "auto", marginRight: "auto", children: [_jsx("div", { children: _jsx(TextField, { label: serial === "" ? "Serial" : "Serial (press enter)", value: serial, onChange: (e) => setSerial(e.target.value), onKeyPress: (e) => {
85
+ return (_jsxs(_Fragment, { children: [_jsxs(Stack, { direction: "row", spacing: 2, sx: {
86
+ alignItems: "center",
87
+ marginLeft: "auto",
88
+ marginRight: "auto",
89
+ }, children: [_jsx("div", { children: _jsx(TextField, { label: serial === "" ? "Serial" : "Serial (press enter)", value: serial, onChange: (e) => setSerial(e.target.value), onKeyPress: (e) => {
87
90
  if (e.key === "Enter" && serial !== "") {
88
91
  e.preventDefault();
89
92
  lookup();
@@ -104,9 +107,8 @@ function lastMachineTime(evts) {
104
107
  return lastEnd;
105
108
  }
106
109
  function DetailsStepTitle() {
107
- const matL = useAtomValue(loadable(matDetails.materialInDialogInfo));
110
+ const mat = useAtomValue(matDetails.materialInDialogInfoUnwrapped);
108
111
  const matEvents = useAtomValue(matDetails.materialInDialogEvents);
109
- const mat = matL.state === "hasData" ? matL.data : null;
110
112
  if (mat) {
111
113
  return (_jsx(MaterialDetailTitle, { partName: mat.partName, serial: mat.serial, subtitle: "Path " +
112
114
  buildPathString(extractPath(matEvents)) +
@@ -118,12 +120,13 @@ function DetailsStepTitle() {
118
120
  }
119
121
  }
120
122
  function DetailsStepButtons({ setStep }) {
121
- const matL = useAtomValue(loadable(matDetails.materialInDialogInfo));
122
- const mat = matL.state === "hasData" ? matL.data : null;
123
+ const mat = useAtomValue(matDetails.materialInDialogInfoUnwrapped);
123
124
  const matEvents = useAtomValue(matDetails.materialInDialogEvents);
124
125
  const setSearchRange = useSetAtom(pathLookupRange);
125
126
  const setMatToShow = useSetAtom(matDetails.materialDialogOpen);
126
- return (_jsxs(Stack, { direction: "row", spacing: 2, mt: "2em", children: [mat ? (_jsx(Button, { variant: "contained", color: "secondary", onClick: () => {
127
+ return (_jsxs(Stack, { direction: "row", spacing: 2, sx: {
128
+ mt: "2em",
129
+ }, children: [mat ? (_jsx(Button, { variant: "contained", color: "secondary", onClick: () => {
127
130
  const d = lastMachineTime(matEvents);
128
131
  setSearchRange({
129
132
  part: mat?.partName ?? "",
@@ -119,5 +119,7 @@ export function RecentFailedInspectionsTable() {
119
119
  minHeight: "2.5em",
120
120
  alignItems: "center",
121
121
  maxWidth: "calc(100vw - 24px - 24px)",
122
- }, children: [_jsx(Typography, { variant: "subtitle1", children: "Inspections marked as failed in the last 5 days" }), _jsx(Box, { flexGrow: 1 }), _jsx(Tooltip, { title: "Copy to Clipboard", children: _jsx(IconButton, { style: { height: "25px", paddingTop: 0, paddingBottom: 0 }, onClick: () => copyFailedInspectionsToClipboard(failed), size: "large", children: _jsx(ImportExport, {}) }) })] }), _jsx(RecentFailedTable, { failed: failed })] }));
122
+ }, children: [_jsx(Typography, { variant: "subtitle1", children: "Inspections marked as failed in the last 5 days" }), _jsx(Box, { sx: {
123
+ flexGrow: 1,
124
+ } }), _jsx(Tooltip, { title: "Copy to Clipboard", children: _jsx(IconButton, { style: { height: "25px", paddingTop: 0, paddingBottom: 0 }, onClick: () => copyFailedInspectionsToClipboard(failed), size: "large", children: _jsx(ImportExport, {}) }) })] }), _jsx(RecentFailedTable, { failed: failed })] }));
123
125
  }
@@ -40,6 +40,7 @@ export declare enum RouteLocation {
40
40
  Analysis_MachineCycles = "/analysis/machine-cycles",
41
41
  Analysis_LoadCycles = "/analysis/load-cycles",
42
42
  Analysis_PalletCycles = "/analysis/pallet-cycles",
43
+ Analysis_BasketCycles = "/analysis/basket-cycles",
43
44
  Analysis_Schedules = "/analysis/schedules",
44
45
  Analysis_Quality = "/analysis/quality",
45
46
  Analysis_ToolReplacements = "/analysis/tool-replacements",
@@ -140,6 +141,8 @@ export type RouteState = {
140
141
  route: RouteLocation.Analysis_LoadCycles;
141
142
  } | {
142
143
  route: RouteLocation.Analysis_PalletCycles;
144
+ } | {
145
+ route: RouteLocation.Analysis_BasketCycles;
143
146
  } | {
144
147
  route: RouteLocation.Analysis_CostPerPiece;
145
148
  } | {
@@ -78,6 +78,7 @@ export var RouteLocation;
78
78
  RouteLocation["Analysis_MachineCycles"] = "/analysis/machine-cycles";
79
79
  RouteLocation["Analysis_LoadCycles"] = "/analysis/load-cycles";
80
80
  RouteLocation["Analysis_PalletCycles"] = "/analysis/pallet-cycles";
81
+ RouteLocation["Analysis_BasketCycles"] = "/analysis/basket-cycles";
81
82
  RouteLocation["Analysis_Schedules"] = "/analysis/schedules";
82
83
  RouteLocation["Analysis_Quality"] = "/analysis/quality";
83
84
  RouteLocation["Analysis_ToolReplacements"] = "/analysis/tool-replacements";
@@ -184,6 +185,7 @@ function urlToRoute(url) {
184
185
  custom: groups?.["custom"]?.split("/")?.map((s) => decodeURIComponent(s)) ?? [],
185
186
  };
186
187
  default:
188
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- the switch handles all routes with additional payload.
187
189
  return { route };
188
190
  }
189
191
  }
@@ -75,8 +75,10 @@ function WaitingForMaterialDialog() {
75
75
  print();
76
76
  printStarted.current = true;
77
77
  }, [waiting, materialToPrint, printStarted, print]);
78
- console.log(waiting, materialToPrint);
79
- return (_jsxs(_Fragment, { children: [_jsxs(Dialog, { open: waiting !== null, children: [_jsx(DialogTitle, { children: "Waiting for Material Assignment" }), _jsx(DialogContent, { children: materialToPrint === null ? (waiting === null ? (_jsx("div", {})) : (_jsxs(Stack, { direction: "column", spacing: 2, mt: "0.5em", mb: "0.5em", children: [_jsx(CircularProgress, { color: "secondary" }), _jsx("div", { children: "Waiting for material assignment. This could take a while if a download is currently in progress." })] }))) : (_jsx("div", { children: "Printing..." })) }), _jsx(DialogActions, { children: _jsx(Button, { color: "primary", onClick: () => setWaiting(null), children: "Cancel" }) })] }), _jsx("div", { style: { display: "none" }, children: _jsx("div", { ref: printRef, children: _jsx(PrintedLabel, { materialName: waiting?.selectedCasting, material: materialToPrint, operator: waiting?.operator, oneJobPerPage: true }) }) })] }));
78
+ return (_jsxs(_Fragment, { children: [_jsxs(Dialog, { open: waiting !== null, children: [_jsx(DialogTitle, { children: "Waiting for Material Assignment" }), _jsx(DialogContent, { children: materialToPrint === null ? (waiting === null ? (_jsx("div", {})) : (_jsxs(Stack, { direction: "column", spacing: 2, sx: {
79
+ mt: "0.5em",
80
+ mb: "0.5em",
81
+ }, children: [_jsx(CircularProgress, { color: "secondary" }), _jsx("div", { children: "Waiting for material assignment. This could take a while if a download is currently in progress." })] }))) : (_jsx("div", { children: "Printing..." })) }), _jsx(DialogActions, { children: _jsx(Button, { color: "primary", onClick: () => setWaiting(null), children: "Cancel" }) })] }), _jsx("div", { style: { display: "none" }, children: _jsx("div", { ref: printRef, children: _jsx(PrintedLabel, { materialName: waiting?.selectedCasting, material: materialToPrint, operator: waiting?.operator, oneJobPerPage: true }) }) })] }));
80
82
  }
81
83
  function JobsForCasting({ casting, queue }) {
82
84
  const currentSt = useAtomValue(currentStatus);
@@ -101,7 +103,7 @@ export const BulkAddCastingWithoutSerialDialog = memo(function BulkAddCastingWit
101
103
  const castings = useMemo(() => LazySeq.ofObject(currentSt.jobs)
102
104
  .flatMap(([, j]) => j.procsAndPaths[0].paths)
103
105
  .filter((p) => p.casting !== undefined && p.casting !== "")
104
- .map((p) => ({ casting: p.casting, cnt: 1 }))
106
+ .map((p) => ({ casting: p.casting ?? "", cnt: 1 }))
105
107
  .concat(LazySeq.of(historicCastNames).map((c) => ({ casting: c, cnt: 0 })))
106
108
  .buildOrderedMap((c) => c.casting, (old, c) => (old === undefined ? c.cnt : old + c.cnt))
107
109
  .toAscLazySeq(), [currentSt.jobs, historicCastNames]);
@@ -151,7 +153,9 @@ export const BulkAddCastingWithoutSerialDialog = memo(function BulkAddCastingWit
151
153
  });
152
154
  }
153
155
  }
154
- return (_jsxs(_Fragment, { children: [_jsxs(Dialog, { open: queue !== null, onClose: () => close(), maxWidth: "md", children: [_jsx(DialogTitle, { children: "Add Raw Material" }), _jsx(DialogContent, { children: _jsxs(Stack, { direction: "column", spacing: 2, mt: "0.5em", children: [_jsx(TextField, { style: { minWidth: "15em" }, value: selectedCasting || "", onChange: (e) => setSelectedCasting(e.target.value), select: true, fullWidth: true, label: "Raw Material", slotProps: {
156
+ return (_jsxs(_Fragment, { children: [_jsxs(Dialog, { open: queue !== null, onClose: () => close(), maxWidth: "md", children: [_jsx(DialogTitle, { children: "Add Raw Material" }), _jsx(DialogContent, { children: _jsxs(Stack, { direction: "column", spacing: 2, sx: {
157
+ mt: "0.5em",
158
+ }, children: [_jsx(TextField, { style: { minWidth: "15em" }, value: selectedCasting || "", onChange: (e) => setSelectedCasting(e.target.value), select: true, fullWidth: true, label: "Raw Material", slotProps: {
155
159
  select: {
156
160
  renderValue: selectedCasting === null
157
161
  ? undefined
@@ -185,11 +189,11 @@ export const MultiMaterialDialog = memo(function MultiMaterialDialog(props) {
185
189
  let isSubscribed = true;
186
190
  setLoading(true);
187
191
  loadRawMaterialEvents(props.material)
188
- .then((events) => {
192
+ .then((loadedEvents) => {
189
193
  if (isSubscribed) {
190
- setEvents(events);
194
+ setEvents(loadedEvents);
191
195
  let operator;
192
- for (const e of events) {
196
+ for (const e of loadedEvents) {
193
197
  if (e.type === api.LogType.AddToQueue && e.details?.["operator"] !== undefined) {
194
198
  operator = e.details["operator"];
195
199
  }
@@ -146,12 +146,24 @@ export function Closeout({ forceSingleColumn }) {
146
146
  : 0);
147
147
  return { uncompleted, closed };
148
148
  }, [matSummary, nearestMinute]);
149
- return (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: { display: forceSingleColumn ? undefined : { md: "flex" } }, children: [_jsxs(Box, { padding: "8px", sx: {
149
+ return (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: { display: forceSingleColumn ? undefined : { md: "flex" } }, children: [_jsxs(Box, { sx: {
150
+ padding: "8px",
150
151
  minHeight: forceSingleColumn ? undefined : { md: "calc(100vh - 64px)" },
151
152
  width: forceSingleColumn ? "100%" : { md: "50vw" },
152
153
  borderRight: forceSingleColumn ? undefined : { md: "1px solid black" },
153
154
  borderBottom: forceSingleColumn ? "1px solid black" : { sm: "1px solid black", md: "none" },
154
- }, children: [_jsx(Typography, { variant: "h4", children: "Recently Completed" }), _jsx(Box, { display: "flex", justifyContent: "flex-start", flexWrap: "wrap", children: material.uncompleted.map((m, idx) => (_jsx(MatSummary, { mat: m }, idx))) })] }), _jsxs(Box, { padding: "8px", sx: { width: forceSingleColumn ? "100%" : { md: "50vw" } }, children: [_jsx(Typography, { variant: "h4", children: "Recently Closed Out" }), _jsx(Box, { display: "flex", justifyContent: "flex-start", flexWrap: "wrap", children: material.closed.map((m, idx) => (_jsx(MatSummary, { mat: m }, idx))) })] })] }), _jsx(SelectWorkorderDialog, {}), _jsx(CloseoutMaterialDialog, {})] }));
155
+ }, children: [_jsx(Typography, { variant: "h4", children: "Recently Completed" }), _jsx(Box, { sx: {
156
+ display: "flex",
157
+ justifyContent: "flex-start",
158
+ flexWrap: "wrap",
159
+ }, children: material.uncompleted.map((m, idx) => (_jsx(MatSummary, { mat: m }, idx))) })] }), _jsxs(Box, { sx: {
160
+ padding: "8px",
161
+ width: forceSingleColumn ? "100%" : { md: "50vw" },
162
+ }, children: [_jsx(Typography, { variant: "h4", children: "Recently Closed Out" }), _jsx(Box, { sx: {
163
+ display: "flex",
164
+ justifyContent: "flex-start",
165
+ flexWrap: "wrap",
166
+ }, children: material.closed.map((m, idx) => (_jsx(MatSummary, { mat: m }, idx))) })] })] }), _jsx(SelectWorkorderDialog, {}), _jsx(CloseoutMaterialDialog, {})] }));
155
167
  }
156
168
  export function CloseoutPage() {
157
169
  useSetTitle("Close Out");
@@ -51,5 +51,5 @@ export const CustomStationMonitorDialog = memo(function CustomStationMonitorDial
51
51
  const parts = url.split("/");
52
52
  let title = parts[parts.length - 1];
53
53
  title = title[0].toUpperCase() + title.substr(1);
54
- return (_jsxs(_Fragment, { children: [_jsx(Tooltip, { title: title, children: _jsx(IconButton, { onClick: () => setOpen(true), size: "large", children: _jsx(SettingsIcon, {}) }) }), _jsxs(Dialog, { open: open, onClose: () => setOpen(false), fullWidth: true, maxWidth: "md", children: [_jsx(DialogTitle, { children: title }), _jsx(DialogContent, { children: _jsx("iframe", { width: "100%", src: url, style: { border: 0, height: "calc(100vh - 250px)" } }) }), _jsx(DialogActions, { children: _jsx(Button, { color: "primary", onClick: () => setOpen(false), children: "Close" }) })] })] }));
54
+ return (_jsxs(_Fragment, { children: [_jsx(Tooltip, { title: title, children: _jsx(IconButton, { onClick: () => setOpen(true), size: "large", children: _jsx(SettingsIcon, {}) }) }), _jsxs(Dialog, { open: open, onClose: () => setOpen(false), fullWidth: true, maxWidth: "md", children: [_jsx(DialogTitle, { children: title }), _jsx(DialogContent, { children: _jsx("iframe", { width: "100%", src: url, sandbox: "allow-scripts", style: { border: 0, height: "calc(100vh - 250px)" } }) }), _jsx(DialogActions, { children: _jsx(Button, { color: "primary", onClick: () => setOpen(false), children: "Close" }) })] })] }));
55
55
  });
@@ -95,25 +95,37 @@ const InspMaterialDialog = memo(function InspMaterialDialog(props) {
95
95
  export function Inspection({ focusInspectionType, forceSingleColumn }) {
96
96
  const matSummary = useAtomValue(last30MaterialSummary);
97
97
  const recent_inspections = useMemo(() => extractRecentInspections(matSummary.matsById, focusInspectionType), [matSummary, focusInspectionType]);
98
- return (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: { display: forceSingleColumn ? undefined : { md: "flex" } }, children: [_jsxs(Box, { padding: "8px", sx: {
98
+ return (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: { display: forceSingleColumn ? undefined : { md: "flex" } }, children: [_jsxs(Box, { sx: {
99
+ padding: "8px",
99
100
  minHeight: forceSingleColumn ? undefined : { md: "calc(100vh - 64px)" },
100
101
  width: forceSingleColumn ? "100%" : { md: "50vw" },
101
102
  borderRight: forceSingleColumn ? undefined : { md: "1px solid black" },
102
103
  borderBottom: forceSingleColumn ? "1px solid black" : { sm: "1px solid black", md: "none" },
103
- }, children: [_jsx(Typography, { variant: "h4", children: "Parts to Inspect" }), _jsx(Box, { display: "flex", justifyContent: "flex-start", flexWrap: "wrap", children: recent_inspections.waiting_to_inspect.map((m, idx) => (_jsx(MatSummary, { mat: m, focusInspectionType: focusInspectionType, hideWarningIcon: true }, idx))) })] }), _jsxs(Box, { padding: "8px", sx: { width: forceSingleColumn ? "100%" : { md: "50vw" } }, children: [_jsx(Typography, { variant: "h4", children: "Recently Inspected" }), _jsx(Box, { display: "flex", justifyContent: "flex-start", flexWrap: "wrap", children: recent_inspections.inspect_completed.map((m, idx) => (_jsx(MatSummary, { mat: m, focusInspectionType: focusInspectionType, hideWarningIcon: true }, idx))) })] })] }), _jsx(InspMaterialDialog, { focusInspectionType: focusInspectionType })] }));
104
+ }, children: [_jsx(Typography, { variant: "h4", children: "Parts to Inspect" }), _jsx(Box, { sx: {
105
+ display: "flex",
106
+ justifyContent: "flex-start",
107
+ flexWrap: "wrap",
108
+ }, children: recent_inspections.waiting_to_inspect.map((m, idx) => (_jsx(MatSummary, { mat: m, focusInspectionType: focusInspectionType, hideWarningIcon: true }, idx))) })] }), _jsxs(Box, { sx: {
109
+ padding: "8px",
110
+ width: forceSingleColumn ? "100%" : { md: "50vw" },
111
+ }, children: [_jsx(Typography, { variant: "h4", children: "Recently Inspected" }), _jsx(Box, { sx: {
112
+ display: "flex",
113
+ justifyContent: "flex-start",
114
+ flexWrap: "wrap",
115
+ }, children: recent_inspections.inspect_completed.map((m, idx) => (_jsx(MatSummary, { mat: m, focusInspectionType: focusInspectionType, hideWarningIcon: true }, idx))) })] })] }), _jsx(InspMaterialDialog, { focusInspectionType: focusInspectionType })] }));
116
+ }
117
+ function checkAllCompleted(m) {
118
+ const comp = m.completedInspections;
119
+ if (comp === undefined) {
120
+ return m.signaledInspections.length === 0;
121
+ }
122
+ else {
123
+ return LazySeq.of(m.signaledInspections).every((s) => s in comp);
124
+ }
104
125
  }
105
126
  function extractRecentInspections(mats, inspType) {
106
127
  const uninspectedCutoff = addDays(new Date(), -7);
107
128
  const inspectedCutoff = addDays(new Date(), -1);
108
- function checkAllCompleted(m) {
109
- const comp = m.completedInspections;
110
- if (comp === undefined) {
111
- return m.signaledInspections.length === 0;
112
- }
113
- else {
114
- return LazySeq.of(m.signaledInspections).every((s) => s in comp);
115
- }
116
- }
117
129
  const uninspected = Array.from(inspType === null
118
130
  ? mats
119
131
  .valuesToLazySeq()
@@ -87,9 +87,9 @@ function InvalidateSelect(props) {
87
87
  ? [_jsx(ListSubheader, { children: "Invalidate Selected Process" }, "procheader")]
88
88
  : [],
89
89
  lastMat
90
- ? [
91
- ...LazySeq.ofRange(1, lastMat.process + 1).map((p) => (_jsxs(MenuItem, { value: "proc" + p.toString(), children: ["Invalidate Process ", p] }, p))),
92
- ]
90
+ ? LazySeq.ofRange(1, lastMat.process + 1)
91
+ .map((p) => (_jsxs(MenuItem, { value: "proc" + p.toString(), children: ["Invalidate Process ", p] }, p)))
92
+ .toRArray()
93
93
  : [],
94
94
  hasProc && hasChangeMat ? [_jsx(ListSubheader, { children: "Change Material Type" }, "matheader")] : [],
95
95
  hasChangeMat
@@ -45,8 +45,10 @@ import { currentStatus } from "../../cell-status/current-status.js";
45
45
  import { selectedAnalysisPeriod } from "../../network/load-specific-month.js";
46
46
  import { last30MaterialSummary, specificMonthMaterialSummary } from "../../cell-status/material-summary.js";
47
47
  import { LazySeq, HashSet } from "@seedtactics/immutable-collections";
48
+ import { basketDisplayName, loadStationDisplayName } from "../../cell-status/station-cycles.js";
48
49
  import { MoreHoriz } from "@mui/icons-material";
49
50
  import { useAtomValue, useSetAtom } from "jotai";
51
+ import { fmsInformation } from "../../network/server-settings.js";
50
52
  function displayDate(d) {
51
53
  return d.toLocaleString(undefined, {
52
54
  month: "short",
@@ -64,19 +66,30 @@ function JobCompleted(props) {
64
66
  return null;
65
67
  }
66
68
  function JobDisplay(props) {
67
- return (_jsx("div", { children: _jsxs("dl", { children: [_jsx("dt", { children: "Job ID" }), _jsx("dd", { children: props.job.unique }), _jsx("dt", { children: "Time" }), _jsxs("dd", { children: [displayDate(props.job.routeStartUTC), " to ", displayDate(props.job.routeEndUTC)] }), props.job.cycles ? (_jsxs(_Fragment, { children: [_jsx("dt", { children: "Quantity" }), _jsx("dd", { children: props.job.cycles })] })) : undefined, props.job.comment !== undefined && props.job.comment !== "" ? (_jsxs(_Fragment, { children: [_jsx("dt", { children: "Comment" }), _jsx("dd", { children: props.job.comment })] })) : undefined, props.job.assignedWorkorders && props.job.assignedWorkorders.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("dt", { children: "Workorders" }), _jsx("dd", { children: props.job.assignedWorkorders.join(", ") })] })) : undefined, props.job.procsAndPaths.map((proc, procIdx) => (_jsx(Fragment, { children: proc.paths.map((path, pathIdx) => (_jsxs(Fragment, { children: [_jsxs("dt", { children: ["Process ", procIdx + 1, proc.paths.length > 1 ? ", Path " + (pathIdx + 1).toString() : undefined] }), _jsxs("dd", { children: [_jsx(JobCompleted, { job: props.job, procIdx: procIdx, pathIdx: pathIdx }), _jsxs("div", { children: ["Estimated Start: ", displayDate(path.simulatedStartingUTC)] }), _jsxs("div", { children: ["Pallets: ", (path.palletNums ?? []).map((p) => p.toString()).join(",")] }), path.fixture ? (_jsxs("div", { children: ["Fixture: ", path.fixture, " ", path.face !== undefined ? ", Face: " + path.face.toString() : undefined] })) : undefined, path.inputQueue ? _jsxs("div", { children: ["Input Queue: ", path.inputQueue] }) : undefined, path.casting ? _jsxs("div", { children: ["Raw Material: ", path.casting] }) : undefined, _jsxs("div", { children: ["Load Stations: ", path.load.join(","), " |", " ", durationToMinutes(path.expectedLoadTime).toFixed(1), " mins", path.partsPerPallet > 1 ? " per piece" : ""] }), path.stops.map((stop, stopIdx) => (_jsx(Fragment, { children: _jsxs("div", { children: [stop.stationGroup, ": ", (stop.stationNums ?? []).join(","), " | Program: ", stop.program, stop.programRevision ? " rev" + stop.programRevision.toString() : undefined, " |", " ", (durationToMinutes(stop.expectedCycleTime) / path.partsPerPallet).toFixed(1), " mins", path.partsPerPallet > 1 ? " per piece" : ""] }) }, stopIdx))), _jsxs("div", { children: ["Unload Stations: ", path.unload.join(","), " |", " ", durationToMinutes(path.expectedUnloadTime).toFixed(1), " mins", path.partsPerPallet > 1 ? " per piece" : ""] }), path.outputQueue ? _jsxs("div", { children: ["Output Queue: ", path.outputQueue] }) : undefined, path.inspections && path.inspections.length > 0 ? (_jsxs("div", { children: ["Inspections: ", path.inspections.map((i) => i.inspectionType).join(",")] })) : undefined] })] }, pathIdx))) }, procIdx)))] }) }));
69
+ const fmsInfo = useAtomValue(fmsInformation);
70
+ const displayLoadStations = (stations) => stations.map((station) => loadStationDisplayName(station, fmsInfo.loadStationNames)).join(", ");
71
+ return (_jsx("div", { children: _jsxs("dl", { children: [_jsx("dt", { children: "Job ID" }), _jsx("dd", { children: props.job.unique }), _jsx("dt", { children: "Time" }), _jsxs("dd", { children: [displayDate(props.job.routeStartUTC), " to ", displayDate(props.job.routeEndUTC)] }), props.job.cycles ? (_jsxs(_Fragment, { children: [_jsx("dt", { children: "Quantity" }), _jsx("dd", { children: props.job.cycles })] })) : undefined, props.job.comment !== undefined && props.job.comment !== "" ? (_jsxs(_Fragment, { children: [_jsx("dt", { children: "Comment" }), _jsx("dd", { children: props.job.comment })] })) : undefined, props.job.assignedWorkorders && props.job.assignedWorkorders.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("dt", { children: "Workorders" }), _jsx("dd", { children: props.job.assignedWorkorders.join(", ") })] })) : undefined, props.job.procsAndPaths.map((proc, procIdx) => (_jsx(Fragment, { children: proc.paths.map((path, pathIdx) => (_jsxs(Fragment, { children: [_jsxs("dt", { children: ["Process ", procIdx + 1, proc.paths.length > 1 ? ", Path " + (pathIdx + 1).toString() : undefined] }), _jsxs("dd", { children: [_jsx(JobCompleted, { job: props.job, procIdx: procIdx, pathIdx: pathIdx }), _jsxs("div", { children: ["Estimated Start: ", displayDate(path.simulatedStartingUTC)] }), _jsxs("div", { children: ["Pallets: ", (path.palletNums ?? []).map((p) => p.toString()).join(",")] }), path.fixture ? (_jsxs("div", { children: ["Fixture: ", path.fixture, " ", path.face !== undefined ? ", Face: " + path.face.toString() : undefined] })) : undefined, path.inputQueue ? _jsxs("div", { children: ["Input Queue: ", path.inputQueue] }) : undefined, path.casting ? _jsxs("div", { children: ["Raw Material: ", path.casting] }) : undefined, proc.basketLoadStations &&
72
+ proc.basketLoadStations.length > 0 &&
73
+ proc.expectedBasketLoadTime ? (_jsxs("div", { children: ["Basket Load Stations: ", displayLoadStations(proc.basketLoadStations), " |", " ", durationToMinutes(proc.expectedBasketLoadTime).toFixed(1), " mins", path.partsPerPallet > 1 ? " per piece" : ""] })) : undefined, _jsxs("div", { children: ["Load Stations: ", displayLoadStations(path.load), " |", " ", durationToMinutes(path.expectedLoadTime).toFixed(1), " mins", path.partsPerPallet > 1 ? " per piece" : ""] }), path.stops.map((stop, stopIdx) => (_jsx(Fragment, { children: _jsxs("div", { children: [stop.stationGroup, ": ", (stop.stationNums ?? []).join(","), " | Program: ", stop.program, stop.programRevision ? " rev" + stop.programRevision.toString() : undefined, " |", " ", (durationToMinutes(stop.expectedCycleTime) / path.partsPerPallet).toFixed(1), " mins", path.partsPerPallet > 1 ? " per piece" : ""] }) }, stopIdx))), _jsxs("div", { children: ["Unload Stations: ", displayLoadStations(path.unload), " |", " ", durationToMinutes(path.expectedUnloadTime).toFixed(1), " mins", path.partsPerPallet > 1 ? " per piece" : ""] }), proc.basketUnloadStations &&
74
+ proc.basketUnloadStations.length > 0 &&
75
+ proc.expectedBasketUnloadTime ? (_jsxs("div", { children: ["Basket Unload Stations: ", displayLoadStations(proc.basketUnloadStations), " |", " ", durationToMinutes(proc.expectedBasketUnloadTime).toFixed(1), " mins", path.partsPerPallet > 1 ? " per piece" : ""] })) : undefined, path.outputQueue ? _jsxs("div", { children: ["Output Queue: ", path.outputQueue] }) : undefined, path.inspections && path.inspections.length > 0 ? (_jsxs("div", { children: ["Inspections: ", path.inspections.map((i) => i.inspectionType).join(",")] })) : undefined] })] }, pathIdx))) }, procIdx)))] }) }));
68
76
  }
69
77
  function MaterialStatus(props) {
78
+ const fmsInfo = useAtomValue(fmsInformation);
79
+ const basketName = basketDisplayName(fmsInfo.basketName);
70
80
  if (props.inProcMat !== null && props.inProcMat.location.type === api.LocType.OnPallet) {
71
81
  return _jsxs("span", { children: ["On pallet ", props.inProcMat.location.palletNum ?? ""] });
72
82
  }
73
83
  else if (props.inProcMat !== null && props.inProcMat.location.type === api.LocType.InQueue) {
74
84
  return _jsxs("span", { children: ["In queue ", props.inProcMat.location.currentQueue ?? ""] });
75
85
  }
86
+ else if (props.inProcMat !== null && props.inProcMat.location.type === api.LocType.InBasket) {
87
+ return (_jsxs("span", { children: ["In ", basketName, " ", props.inProcMat.location.basketId ?? ""] }));
88
+ }
76
89
  else if (props.matSummary?.completed_last_proc_machining) {
77
90
  return _jsx("span", { children: "Completed" });
78
91
  }
79
- else if (props.matSummary !== null && props.matSummary.startedProcess1 === false) {
92
+ else if (props.matSummary !== null && !props.matSummary.startedProcess1) {
80
93
  return _jsx("span", { children: "Not yet started" });
81
94
  }
82
95
  else {