@seedtactics/insight-client 16.6.0 → 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.
- package/dist/assets/ProgramHighlight-DPTeZ8Si.js +3 -0
- package/dist/assets/index-bPAFn3jp.js +364 -0
- package/dist/cell-status/basket-cycles.d.ts +21 -0
- package/dist/cell-status/basket-cycles.js +80 -0
- package/dist/cell-status/current-status.js +11 -3
- package/dist/cell-status/estimated-cycle-times.js +8 -4
- package/dist/cell-status/inspections.js +2 -2
- package/dist/cell-status/loading.js +4 -0
- package/dist/cell-status/material-details.d.ts +12 -4
- package/dist/cell-status/material-details.js +24 -13
- package/dist/cell-status/rebookings.js +15 -17
- package/dist/cell-status/scheduled-jobs.d.ts +1 -1
- package/dist/cell-status/scheduled-jobs.js +10 -3
- package/dist/cell-status/sim-production.js +3 -3
- package/dist/cell-status/sim-station-use.d.ts +1 -0
- package/dist/cell-status/sim-station-use.js +14 -8
- package/dist/cell-status/station-cycles.d.ts +29 -2
- package/dist/cell-status/station-cycles.js +81 -11
- package/dist/cell-status/tool-replacements.js +1 -1
- package/dist/cell-status/tool-usage.js +1 -1
- package/dist/components/App.js +101 -66
- package/dist/components/BarcodeScanning.js +12 -2
- package/dist/components/ErrorsAndLoading.js +10 -1
- package/dist/components/LogEntry.d.ts +0 -1
- package/dist/components/LogEntry.js +50 -26
- package/dist/components/Navigation.js +30 -4
- package/dist/components/analysis/AnalysisSelectToolbar.js +5 -1
- package/dist/components/analysis/BasketCycleCards.d.ts +1 -0
- package/dist/components/analysis/BasketCycleCards.js +145 -0
- package/dist/components/analysis/BufferChart.js +10 -4
- package/dist/components/analysis/CostPerPiece.js +28 -8
- package/dist/components/analysis/CycleChart.js +1 -1
- package/dist/components/analysis/DataTable.js +6 -4
- package/dist/components/analysis/HeatChart.js +27 -14
- package/dist/components/analysis/InspectionSankey.js +17 -6
- package/dist/components/analysis/PalletCycleCards.js +15 -4
- package/dist/components/analysis/PartCycleCards.js +62 -18
- package/dist/components/analysis/StationDataTable.js +14 -11
- package/dist/components/analysis/ToolReplacements.js +16 -10
- package/dist/components/log-entry-queue-filter.d.ts +2 -0
- package/dist/components/log-entry-queue-filter.js +21 -0
- package/dist/components/operations/AllMaterial.js +26 -10
- package/dist/components/operations/ChartRangeEdit.js +82 -4
- package/dist/components/operations/CloseoutReport.js +13 -4
- package/dist/components/operations/CompletedParts.js +23 -11
- package/dist/components/operations/CurrentWorkorders.js +31 -9
- package/dist/components/operations/OEEChart.js +8 -2
- package/dist/components/operations/Outliers.js +18 -7
- package/dist/components/operations/ProgramHighlight.js +4 -6
- package/dist/components/operations/Programs.js +9 -3
- package/dist/components/operations/Rebookings.js +8 -4
- package/dist/components/operations/RecentCycleChart.js +5 -3
- package/dist/components/operations/RecentProduction.js +30 -13
- package/dist/components/operations/RecentSchedules.js +6 -2
- package/dist/components/operations/RecentStationCycles.js +38 -11
- package/dist/components/operations/ShiftSettings.js +3 -3
- package/dist/components/operations/SimDayUsage.js +27 -4
- package/dist/components/operations/ToolReport.js +5 -1
- package/dist/components/operations/WorkorderGantt.js +22 -2
- package/dist/components/quality/QualityMaterial.js +11 -8
- package/dist/components/quality/RecentFailedInspections.js +3 -1
- package/dist/components/routes.d.ts +3 -0
- package/dist/components/routes.js +2 -0
- package/dist/components/station-monitor/BulkRawMaterial.js +11 -7
- package/dist/components/station-monitor/Closeout.js +14 -2
- package/dist/components/station-monitor/CustomStationMonitorDialog.js +1 -1
- package/dist/components/station-monitor/Inspection.js +23 -11
- package/dist/components/station-monitor/InvalidateCycle.js +3 -3
- package/dist/components/station-monitor/JobDetails.js +15 -2
- package/dist/components/station-monitor/LoadStation.js +274 -31
- package/dist/components/station-monitor/Material.js +71 -11
- package/dist/components/station-monitor/MoveMaterialArrows.js +4 -4
- package/dist/components/station-monitor/QuarantineButton.js +11 -0
- package/dist/components/station-monitor/Queues.js +28 -9
- package/dist/components/station-monitor/QueuesAddMaterial.js +8 -6
- package/dist/components/station-monitor/SelectInspType.js +1 -1
- package/dist/components/station-monitor/SelectWorkorder.js +1 -1
- package/dist/components/station-monitor/StationToolbar.js +17 -5
- package/dist/components/station-monitor/SystemOverview.d.ts +19 -1
- package/dist/components/station-monitor/SystemOverview.js +439 -20
- package/dist/components/station-monitor/Whiteboard.js +15 -7
- package/dist/data/all-material-bins.d.ts +7 -0
- package/dist/data/all-material-bins.js +47 -1
- package/dist/data/cost-per-piece.js +11 -8
- package/dist/data/current-cycles.d.ts +1 -1
- package/dist/data/current-cycles.js +62 -17
- package/dist/data/move-arrows.d.ts +5 -1
- package/dist/data/move-arrows.js +54 -4
- package/dist/data/part-summary.js +13 -13
- package/dist/data/path-lookup.js +6 -23
- package/dist/data/queue-material.d.ts +1 -1
- package/dist/data/queue-material.js +18 -17
- package/dist/data/results.completed-parts.js +4 -3
- package/dist/data/results.cycles.d.ts +15 -6
- package/dist/data/results.cycles.js +51 -30
- package/dist/data/results.inspection.js +11 -6
- package/dist/data/results.oee.js +8 -8
- package/dist/data/results.schedules.js +2 -11
- package/dist/data/tools-programs.js +5 -6
- package/dist/index.html +1 -1
- package/dist/network/api.d.ts +22 -4
- package/dist/network/api.js +40 -5
- package/dist/network/backend-mock.js +15 -8
- package/dist/network/backend.js +3 -3
- package/dist/network/websocket.js +15 -15
- package/dist/util/chart-helpers.d.ts +1 -1
- package/dist/util/chart-helpers.js +14 -8
- package/package.json +29 -31
- package/dist/assets/ProgramHighlight-LvRM40Qr.js +0 -3
- 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
|
-
|
|
73
|
+
if (!hasLoadCycleOperations(point)) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
69
76
|
const ret = [];
|
|
70
|
-
if (
|
|
71
|
-
for (const mat of
|
|
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
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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
|
|
117
|
-
if (
|
|
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(
|
|
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, {
|
|
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, {
|
|
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,
|
|
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",
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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,
|
|
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, {
|
|
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
|
-
|
|
79
|
-
|
|
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,
|
|
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((
|
|
192
|
+
.then((loadedEvents) => {
|
|
189
193
|
if (isSubscribed) {
|
|
190
|
-
setEvents(
|
|
194
|
+
setEvents(loadedEvents);
|
|
191
195
|
let operator;
|
|
192
|
-
for (const e of
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
92
|
+
else if (props.matSummary !== null && !props.matSummary.startedProcess1) {
|
|
80
93
|
return _jsx("span", { children: "Not yet started" });
|
|
81
94
|
}
|
|
82
95
|
else {
|