@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
|
@@ -42,16 +42,17 @@ import { ImportExport } from "@mui/icons-material";
|
|
|
42
42
|
import { selectedAnalysisPeriod } from "../../network/load-specific-month.js";
|
|
43
43
|
import { CycleChart } from "./CycleChart.js";
|
|
44
44
|
import * as matDetails from "../../cell-status/material-details.js";
|
|
45
|
-
import { filterStationCycles, FilterAnyMachineKey, copyCyclesToClipboard, plannedOperationMinutes, loadOccupancyCycles, FilterAnyLoadKey, emptyStationCycles, } from "../../data/results.cycles.js";
|
|
45
|
+
import { filterStationCycles, FilterAnyMachineKey, copyCyclesToClipboard, plannedOperationMinutes, loadOccupancyCycles, FilterAnyLoadKey, emptyStationCycles, normalizeCarrierKindFilter, } from "../../data/results.cycles.js";
|
|
46
46
|
import { PartIdenticon } from "../station-monitor/Material.js";
|
|
47
47
|
import StationDataTable from "./StationDataTable.js";
|
|
48
48
|
import { useSetTitle, isDemoAtom } from "../routes.js";
|
|
49
49
|
import { last30MaterialSummary, specificMonthMaterialSummary } from "../../cell-status/material-summary.js";
|
|
50
50
|
import { last30EstimatedCycleTimes, PartAndStationOperation, specificMonthEstimatedCycleTimes, } from "../../cell-status/estimated-cycle-times.js";
|
|
51
|
-
import { last30StationCycles, specificMonthStationCycles } from "../../cell-status/station-cycles.js";
|
|
51
|
+
import { basketDisplayName, last30HasBasketCycles, last30StationCycles, specificMonthHasBasketCycles, specificMonthStationCycles, } from "../../cell-status/station-cycles.js";
|
|
52
52
|
import { LazySeq, OrderedMap } from "@seedtactics/immutable-collections";
|
|
53
53
|
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
54
54
|
import { atomWithDefault } from "jotai/utils";
|
|
55
|
+
import { fmsInformation } from "../../network/server-settings.js";
|
|
55
56
|
const dateTimeFormat = new Intl.DateTimeFormat(undefined, {
|
|
56
57
|
weekday: "short",
|
|
57
58
|
month: "short",
|
|
@@ -59,6 +60,12 @@ const dateTimeFormat = new Intl.DateTimeFormat(undefined, {
|
|
|
59
60
|
hour: "numeric",
|
|
60
61
|
minute: "2-digit",
|
|
61
62
|
});
|
|
63
|
+
function isPartCycleChartData(point) {
|
|
64
|
+
return "material" in point && Array.isArray(point.material);
|
|
65
|
+
}
|
|
66
|
+
function hasLoadCycleOperations(point) {
|
|
67
|
+
return "operations" in point && (point.operations === undefined || Array.isArray(point.operations));
|
|
68
|
+
}
|
|
62
69
|
function DisplayDateRange({ range }) {
|
|
63
70
|
const period = useAtomValue(selectedAnalysisPeriod);
|
|
64
71
|
if (!range)
|
|
@@ -104,9 +111,11 @@ export function PartMachineCycleChart() {
|
|
|
104
111
|
useSetTitle("Machine Cycles");
|
|
105
112
|
const setMatToShow = useSetAtom(matDetails.materialDialogOpen);
|
|
106
113
|
const extraStationCycleTooltip = useCallback(function extraStationCycleTooltip(point) {
|
|
107
|
-
|
|
114
|
+
if (!isPartCycleChartData(point)) {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
108
117
|
const ret = [];
|
|
109
|
-
for (const mat of
|
|
118
|
+
for (const mat of point.material) {
|
|
110
119
|
ret.push({
|
|
111
120
|
title: mat.serial ? mat.serial : "Material",
|
|
112
121
|
value: "Open Card",
|
|
@@ -174,12 +183,18 @@ export function PartMachineCycleChart() {
|
|
|
174
183
|
return undefined;
|
|
175
184
|
}
|
|
176
185
|
}, [points, curOperation]);
|
|
177
|
-
return (_jsxs(Box, {
|
|
186
|
+
return (_jsxs(Box, { sx: {
|
|
187
|
+
paddingLeft: "24px",
|
|
188
|
+
paddingRight: "24px",
|
|
189
|
+
paddingTop: "10px",
|
|
190
|
+
}, children: [_jsxs(Box, { component: "nav", sx: {
|
|
178
191
|
display: "flex",
|
|
179
192
|
minHeight: "2.5em",
|
|
180
193
|
alignItems: "center",
|
|
181
194
|
maxWidth: "calc(100vw - 24px - 24px)",
|
|
182
|
-
}, children: [_jsxs(Typography, { variant: "subtitle1", children: ["Machine Cycles for ", _jsx(DisplayDateRange, { range: zoomDateRange ?? defaultDateRange })] }), _jsx(Box, {
|
|
195
|
+
}, children: [_jsxs(Typography, { variant: "subtitle1", children: ["Machine Cycles for ", _jsx(DisplayDateRange, { range: zoomDateRange ?? defaultDateRange })] }), _jsx(Box, { sx: {
|
|
196
|
+
flexGrow: 1,
|
|
197
|
+
} }), _jsx(FormControl, { size: "small", children: _jsxs(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
|
|
183
198
|
? points.allPartAndProcNames.findIndex((o) => selectedPart.part === o.part && selectedPart.proc === o.proc)
|
|
184
199
|
: -1, style: { marginLeft: "1em" }, onChange: (e) => {
|
|
185
200
|
setSelectedPart(e.target.value === -1 ? undefined : points.allPartAndProcNames[e.target.value]);
|
|
@@ -190,9 +205,12 @@ export function PartMachineCycleChart() {
|
|
|
190
205
|
: -1
|
|
191
206
|
: selectedMachine, style: { marginLeft: "1em" }, onChange: (e) => {
|
|
192
207
|
if (selectedPart) {
|
|
193
|
-
|
|
208
|
+
const selectedIdx = typeof e.target.value === "number" ? e.target.value : Number.parseInt(e.target.value, 10);
|
|
209
|
+
if (!Number.isNaN(selectedIdx)) {
|
|
210
|
+
setSelectedOperation(selectedIdx === -1 ? undefined : points.allMachineOperations[selectedIdx]);
|
|
211
|
+
}
|
|
194
212
|
}
|
|
195
|
-
else {
|
|
213
|
+
else if (typeof e.target.value === "string") {
|
|
196
214
|
setSelectedMachine(e.target.value);
|
|
197
215
|
}
|
|
198
216
|
}, children: selectedPart
|
|
@@ -215,6 +233,7 @@ const loadShowGraph = atom(true);
|
|
|
215
233
|
const loadSelectedPart = atomWithDefault((get) => get(isDemoAtom) ? { part: "aaa", proc: 2 } : undefined);
|
|
216
234
|
const loadSelectedOperation = atomWithDefault((get) => get(isDemoAtom) ? "LoadOp" : "LULOccupancy");
|
|
217
235
|
const loadSelectedLoad = atom(FilterAnyLoadKey);
|
|
236
|
+
const loadSelectedCarrier = atom("Any");
|
|
218
237
|
const loadSelectedPallet = atom(undefined);
|
|
219
238
|
const loadZoomDateRangeRecent = atom(undefined);
|
|
220
239
|
const loadZoomDateRangeByMonth = atom(OrderedMap.empty());
|
|
@@ -240,10 +259,12 @@ export function PartLoadStationCycleChart() {
|
|
|
240
259
|
useSetTitle("L/U Cycles");
|
|
241
260
|
const setMatToShow = useSetAtom(matDetails.materialDialogOpen);
|
|
242
261
|
const extraLoadCycleTooltip = useCallback(function extraLoadCycleTooltip(point) {
|
|
243
|
-
|
|
262
|
+
if (!hasLoadCycleOperations(point)) {
|
|
263
|
+
return [];
|
|
264
|
+
}
|
|
244
265
|
const ret = [];
|
|
245
|
-
if (
|
|
246
|
-
for (const mat of
|
|
266
|
+
if (point.operations) {
|
|
267
|
+
for (const mat of point.operations) {
|
|
247
268
|
ret.push({
|
|
248
269
|
title: (mat.mat.serial ? mat.mat.serial : "Material") + " " + mat.operation,
|
|
249
270
|
value: "Open Card",
|
|
@@ -258,13 +279,18 @@ export function PartLoadStationCycleChart() {
|
|
|
258
279
|
const [selectedPart, setSelectedPart] = useAtom(loadSelectedPart);
|
|
259
280
|
const [selectedOperation, setSelectedOperation] = useAtom(loadSelectedOperation);
|
|
260
281
|
const [selectedLoadStation, setSelectedLoadStation] = useAtom(loadSelectedLoad);
|
|
282
|
+
const [selectedCarrier, setSelectedCarrier] = useAtom(loadSelectedCarrier);
|
|
261
283
|
const [selectedPallet, setSelectedPallet] = useAtom(loadSelectedPallet);
|
|
262
284
|
const [zoomDateRange, setZoomRange] = useAtom(loadZoomDateRange);
|
|
263
285
|
const [yZoom, setYZoom] = useAtom(loadYZoom);
|
|
286
|
+
const fmsInfo = useAtomValue(fmsInformation);
|
|
287
|
+
const basketName = basketDisplayName(fmsInfo.basketName);
|
|
288
|
+
const hasBasketCycles = useAtomValue(period.type === "Last30" ? last30HasBasketCycles : specificMonthHasBasketCycles);
|
|
289
|
+
const carrierFilter = normalizeCarrierKindFilter(selectedCarrier, hasBasketCycles);
|
|
264
290
|
const curOperation = useMemo(() => selectedPart && selectedOperation === "LoadOp"
|
|
265
|
-
? new PartAndStationOperation(selectedPart.part, "L/U",
|
|
291
|
+
? new PartAndStationOperation(selectedPart.part, "L/U", `LOAD-${selectedPart.proc}`)
|
|
266
292
|
: selectedPart && selectedOperation === "UnloadOp"
|
|
267
|
-
? new PartAndStationOperation(selectedPart.part, "L/U",
|
|
293
|
+
? new PartAndStationOperation(selectedPart.part, "L/U", `UNLOAD-${selectedPart.proc}`)
|
|
268
294
|
: null, [selectedPart, selectedOperation]);
|
|
269
295
|
const defaultDateRange = period.type === "Last30"
|
|
270
296
|
? [addDays(startOfToday(), -29), addDays(startOfToday(), 1)]
|
|
@@ -273,12 +299,16 @@ export function PartLoadStationCycleChart() {
|
|
|
273
299
|
const matSummary = useAtomValue(period.type === "Last30" ? last30MaterialSummary : specificMonthMaterialSummary);
|
|
274
300
|
const estimatedCycleTimes = useAtomValue(period.type === "Last30" ? last30EstimatedCycleTimes : specificMonthEstimatedCycleTimes);
|
|
275
301
|
const points = useMemo(() => {
|
|
276
|
-
if (selectedPart ||
|
|
302
|
+
if (selectedPart ||
|
|
303
|
+
selectedPallet ||
|
|
304
|
+
selectedLoadStation !== FilterAnyLoadKey ||
|
|
305
|
+
carrierFilter !== "Any") {
|
|
277
306
|
if (curOperation) {
|
|
278
307
|
return filterStationCycles(cycles.valuesToLazySeq(), {
|
|
279
308
|
operation: curOperation,
|
|
280
309
|
pallet: selectedPallet,
|
|
281
310
|
station: selectedLoadStation,
|
|
311
|
+
carrierKind: carrierFilter,
|
|
282
312
|
});
|
|
283
313
|
}
|
|
284
314
|
else if (showGraph) {
|
|
@@ -286,6 +316,7 @@ export function PartLoadStationCycleChart() {
|
|
|
286
316
|
partAndProc: selectedPart,
|
|
287
317
|
pallet: selectedPallet,
|
|
288
318
|
station: selectedLoadStation,
|
|
319
|
+
carrierKind: carrierFilter,
|
|
289
320
|
});
|
|
290
321
|
}
|
|
291
322
|
else {
|
|
@@ -293,13 +324,14 @@ export function PartLoadStationCycleChart() {
|
|
|
293
324
|
partAndProc: selectedPart,
|
|
294
325
|
pallet: selectedPallet,
|
|
295
326
|
station: selectedLoadStation,
|
|
327
|
+
carrierKind: carrierFilter,
|
|
296
328
|
});
|
|
297
329
|
}
|
|
298
330
|
}
|
|
299
331
|
else {
|
|
300
332
|
return emptyStationCycles(cycles.valuesToLazySeq());
|
|
301
333
|
}
|
|
302
|
-
}, [selectedPart, selectedPallet, curOperation, selectedLoadStation, cycles, showGraph]);
|
|
334
|
+
}, [selectedPart, selectedPallet, curOperation, selectedLoadStation, cycles, showGraph, carrierFilter]);
|
|
303
335
|
const plannedMinutes = useMemo(() => {
|
|
304
336
|
if (selectedOperation === "LoadOp" || selectedOperation === "UnloadOp") {
|
|
305
337
|
return plannedOperationMinutes(points, true);
|
|
@@ -308,12 +340,18 @@ export function PartLoadStationCycleChart() {
|
|
|
308
340
|
return undefined;
|
|
309
341
|
}
|
|
310
342
|
}, [points, selectedOperation]);
|
|
311
|
-
return (_jsxs(Box, {
|
|
343
|
+
return (_jsxs(Box, { sx: {
|
|
344
|
+
paddingLeft: "24px",
|
|
345
|
+
paddingRight: "24px",
|
|
346
|
+
paddingTop: "10px",
|
|
347
|
+
}, children: [_jsxs(Box, { component: "nav", sx: {
|
|
312
348
|
display: "flex",
|
|
313
349
|
minHeight: "2.5em",
|
|
314
350
|
alignItems: "center",
|
|
315
351
|
maxWidth: "calc(100vw - 24px - 24px)",
|
|
316
|
-
}, children: [_jsxs(Typography, { variant: "subtitle1", children: ["Load/Unload Cycles for ", _jsx(DisplayDateRange, { range: zoomDateRange ?? defaultDateRange })] }), _jsx(Box, {
|
|
352
|
+
}, children: [_jsxs(Typography, { variant: "subtitle1", children: ["Load/Unload Cycles for ", _jsx(DisplayDateRange, { range: zoomDateRange ?? defaultDateRange })] }), _jsx(Box, { sx: {
|
|
353
|
+
flexGrow: 1,
|
|
354
|
+
} }), _jsx(FormControl, { size: "small", children: _jsxs(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
|
|
317
355
|
? points.allPartAndProcNames.findIndex((o) => selectedPart.part === o.part && selectedPart.proc === o.proc)
|
|
318
356
|
: -1, style: { marginLeft: "1em" }, onChange: (e) => {
|
|
319
357
|
if (e.target.value === -1) {
|
|
@@ -325,7 +363,13 @@ export function PartLoadStationCycleChart() {
|
|
|
325
363
|
}
|
|
326
364
|
}, children: [_jsx(MenuItem, { value: -1, children: _jsx("em", { children: "Any Part" }) }, 0), points.allPartAndProcNames.map((n, idx) => (_jsx(MenuItem, { value: idx, children: _jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [_jsx(PartIdenticon, { part: n.part, size: 20 }), _jsxs("span", { style: { marginRight: "1em" }, children: [n.part, "-", n.proc] })] }) }, idx)))] }) }), _jsx(FormControl, { size: "small", children: _jsxs(Select, { autoWidth: true, displayEmpty: true, value: selectedOperation, style: { marginLeft: "1em" }, onChange: (e) => setSelectedOperation(e.target.value), children: [_jsx(MenuItem, { value: "LULOccupancy", children: "L/U Occupancy" }), selectedPart ? _jsx(MenuItem, { value: "LoadOp", children: "Load Operation (estimated)" }) : undefined, selectedPart ? _jsx(MenuItem, { value: "UnloadOp", children: "Unload Operation (estimated)" }) : undefined] }) }), _jsx(FormControl, { size: "small", children: _jsxs(Select, { autoWidth: true, displayEmpty: true, value: selectedLoadStation, style: { marginLeft: "1em" }, onChange: (e) => {
|
|
327
365
|
setSelectedLoadStation(e.target.value);
|
|
328
|
-
}, children: [_jsx(MenuItem, { value: FilterAnyLoadKey, children: _jsx("em", { children: "Any Station" }) }, -1), points.allLoadStationNames.map((n) => (_jsx(MenuItem, { value: n, children: _jsx("div", { style: { display: "flex", alignItems: "center" }, children: _jsx("span", { style: { marginRight: "1em" }, children: n }) }) }, n)))] }) }), _jsx(FormControl, { size: "small", children: _jsxs(Select, { autoWidth: true, displayEmpty: true, value:
|
|
366
|
+
}, children: [_jsx(MenuItem, { value: FilterAnyLoadKey, children: _jsx("em", { children: "Any Station" }) }, -1), points.allLoadStationNames.map((n) => (_jsx(MenuItem, { value: n, children: _jsx("div", { style: { display: "flex", alignItems: "center" }, children: _jsx("span", { style: { marginRight: "1em" }, children: n }) }) }, n)))] }) }), hasBasketCycles ? (_jsx(FormControl, { size: "small", children: _jsxs(Select, { autoWidth: true, displayEmpty: true, value: carrierFilter, style: { marginLeft: "1em" }, onChange: (e) => {
|
|
367
|
+
const carrier = e.target.value;
|
|
368
|
+
setSelectedCarrier(carrier);
|
|
369
|
+
if (carrier === "Basket") {
|
|
370
|
+
setSelectedPallet(undefined);
|
|
371
|
+
}
|
|
372
|
+
}, children: [_jsx(MenuItem, { value: "Any", children: _jsx("em", { children: "Any Carrier" }) }), _jsx(MenuItem, { value: "Pallet", children: "Pallet" }), _jsx(MenuItem, { value: "Basket", children: basketName })] }) })) : undefined, carrierFilter !== "Basket" ? (_jsx(FormControl, { size: "small", children: _jsxs(Select, { 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, points.data.size > 0 ? (_jsx(Tooltip, { title: "Copy to Clipboard", children: _jsx(IconButton, { onClick: () => copyCyclesToClipboard(points, matSummary.matsById, zoomDateRange, selectedOperation === "LULOccupancy", fmsInfo.loadStationNames, basketName), style: { height: "25px", paddingTop: 0, paddingBottom: 0 }, size: "large", children: _jsx(ImportExport, {}) }) })) : undefined] }), _jsx("main", { children: showGraph ? (_jsx(CycleChart, { points: points.data, series_label: points.seriesLabel, default_date_range: defaultDateRange, extra_tooltip: extraLoadCycleTooltip, current_date_zoom: zoomDateRange, set_date_zoom_range: (z) => setZoomRange(z.zoom), yZoom: yZoom, setYZoom: setYZoom, stats: curOperation ? estimatedCycleTimes.get(curOperation) : undefined, plannedTimeMinutes: plannedMinutes })) : (_jsx(StationDataTable, { points: points.data, matsById: matSummary.matsById, period: period, current_date_zoom: zoomDateRange, set_date_zoom_range: (z) => setZoomRange(z.zoom), showWorkorderAndInspect: true, hideMedian: selectedOperation === "LULOccupancy", emptyMessage: selectedPart || selectedPallet
|
|
329
373
|
? "No Cycles"
|
|
330
374
|
: "Select part, operation, or pallet to see cycles." })) })] }));
|
|
331
375
|
}
|
|
@@ -39,8 +39,10 @@ import { addDays, addHours, addMonths } from "date-fns";
|
|
|
39
39
|
import { Menu } from "@mui/material";
|
|
40
40
|
import { MenuItem } from "@mui/material";
|
|
41
41
|
import { materialDialogOpen } from "../../cell-status/material-details.js";
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
42
|
+
import { basketDisplayName, carrierLabel, carrierSortKey, displayStationName, } from "../../cell-status/station-cycles.js";
|
|
43
|
+
import { LazySeq } from "@seedtactics/immutable-collections";
|
|
44
|
+
import { useAtomValue, useSetAtom } from "jotai";
|
|
45
|
+
import { fmsInformation } from "../../network/server-settings.js";
|
|
44
46
|
var ColumnId;
|
|
45
47
|
(function (ColumnId) {
|
|
46
48
|
ColumnId[ColumnId["Date"] = 0] = "Date";
|
|
@@ -56,7 +58,7 @@ var ColumnId;
|
|
|
56
58
|
ColumnId[ColumnId["MedianElapsed"] = 10] = "MedianElapsed";
|
|
57
59
|
ColumnId[ColumnId["MedianDeviation"] = 11] = "MedianDeviation";
|
|
58
60
|
})(ColumnId || (ColumnId = {}));
|
|
59
|
-
function buildColumns(matIds) {
|
|
61
|
+
function buildColumns(matIds, loadStationNames, basketName) {
|
|
60
62
|
return [
|
|
61
63
|
{
|
|
62
64
|
id: ColumnId.Date,
|
|
@@ -81,7 +83,7 @@ function buildColumns(matIds) {
|
|
|
81
83
|
id: ColumnId.Station,
|
|
82
84
|
numeric: false,
|
|
83
85
|
label: "Station",
|
|
84
|
-
getDisplay: (c) => c.stationGroup
|
|
86
|
+
getDisplay: (c) => displayStationName(c.stationGroup, c.stationNumber, loadStationNames),
|
|
85
87
|
},
|
|
86
88
|
{
|
|
87
89
|
id: ColumnId.Operation,
|
|
@@ -92,9 +94,9 @@ function buildColumns(matIds) {
|
|
|
92
94
|
{
|
|
93
95
|
id: ColumnId.Pallet,
|
|
94
96
|
numeric: false,
|
|
95
|
-
label: "
|
|
96
|
-
getDisplay: (c) => c
|
|
97
|
-
getForSort: (c) => c
|
|
97
|
+
label: "Carrier",
|
|
98
|
+
getDisplay: (c) => carrierLabel(c, basketName),
|
|
99
|
+
getForSort: (c) => carrierSortKey(c),
|
|
98
100
|
},
|
|
99
101
|
{
|
|
100
102
|
id: ColumnId.Serial,
|
|
@@ -167,9 +169,9 @@ function extractData(points, columns, currentZoom, orderBy, order) {
|
|
|
167
169
|
const getDataC = getData;
|
|
168
170
|
const data = LazySeq.of(points.values()).flatMap((x) => x);
|
|
169
171
|
const arr = currentZoom
|
|
170
|
-
? data.filter((p) => p.endTime >= currentZoom.start && p.endTime <= currentZoom.end)
|
|
171
|
-
: data
|
|
172
|
-
return arr.
|
|
172
|
+
? data.filter((p) => p.endTime >= currentZoom.start && p.endTime <= currentZoom.end)
|
|
173
|
+
: data;
|
|
174
|
+
return arr.toSortedArray(order === "desc" ? { desc: getDataC } : { asc: getDataC }, order === "desc" ? { desc: (a) => a.endTime.getTime() } : { asc: (a) => a.endTime.getTime() });
|
|
173
175
|
}
|
|
174
176
|
function useZoom(props) {
|
|
175
177
|
let zoom;
|
|
@@ -204,7 +206,8 @@ function useZoom(props) {
|
|
|
204
206
|
};
|
|
205
207
|
}
|
|
206
208
|
export default memo(function StationDataTable(props) {
|
|
207
|
-
const
|
|
209
|
+
const fmsInfo = useAtomValue(fmsInformation);
|
|
210
|
+
const columns = buildColumns(props.matsById, fmsInfo.loadStationNames, basketDisplayName(fmsInfo.basketName));
|
|
208
211
|
const sort = useColSort(ColumnId.Date, columns);
|
|
209
212
|
const tpage = useTablePage();
|
|
210
213
|
const zoom = useZoom(props);
|
|
@@ -45,14 +45,14 @@ import { localPoint } from "../../util/chart-helpers.js";
|
|
|
45
45
|
import { useSetTitle } from "../routes.js";
|
|
46
46
|
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
47
47
|
import { useResizeDetector } from "react-resize-detector";
|
|
48
|
-
function tool_replacements_with_station_and_date(zoom, allReplacements,
|
|
48
|
+
function tool_replacements_with_station_and_date(zoom, allReplacements, selectedStation) {
|
|
49
49
|
const zoomRange = zoom?.zoomRange;
|
|
50
|
-
if (
|
|
51
|
-
const rsForStat = allReplacements.get(
|
|
50
|
+
if (selectedStation) {
|
|
51
|
+
const rsForStat = allReplacements.get(selectedStation) ?? OrderedMap.empty();
|
|
52
52
|
return rsForStat
|
|
53
53
|
.valuesToAscLazySeq()
|
|
54
54
|
.transform((x) => zoomRange ? x.filter((rs) => rs.time >= zoomRange.start && rs.time <= zoomRange.end) : x)
|
|
55
|
-
.flatMap((rs) => rs.replacements.map((
|
|
55
|
+
.flatMap((rs) => rs.replacements.map((replacement) => ({ ...replacement, station: selectedStation, time: rs.time })));
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
58
|
return allReplacements.toAscLazySeq().flatMap(([station, rsByStat]) => rsByStat
|
|
@@ -332,12 +332,12 @@ const AllReplacementTable = memo(function ReplacementTable(props) {
|
|
|
332
332
|
});
|
|
333
333
|
function copyToClipboard(replacements, displayType) {
|
|
334
334
|
if (displayType === "summary") {
|
|
335
|
-
const
|
|
336
|
-
copyTableToClipboard(summaryColumns,
|
|
335
|
+
const summaryRows = tool_summary(undefined, replacements, undefined, (replacement) => replacement.tool);
|
|
336
|
+
copyTableToClipboard(summaryColumns, summaryRows);
|
|
337
337
|
}
|
|
338
338
|
else {
|
|
339
|
-
const
|
|
340
|
-
copyTableToClipboard(allReplacementsColumns,
|
|
339
|
+
const detailRows = tool_replacements_with_station_and_date(undefined, replacements, undefined).toSortedArray((replacement) => replacement.tool, (replacement) => replacement.time);
|
|
340
|
+
copyTableToClipboard(allReplacementsColumns, detailRows);
|
|
341
341
|
}
|
|
342
342
|
}
|
|
343
343
|
const ChooseMachine = memo(function ChooseMachineSelect(props) {
|
|
@@ -361,10 +361,16 @@ export const ToolReplacementPage = memo(function ToolReplacementCard() {
|
|
|
361
361
|
useSetTitle("Tool Replacements");
|
|
362
362
|
const [selectedMachine, setSelectedMachine] = useAtom(selectedMachineAtom);
|
|
363
363
|
const [type, setType] = useAtom(selectedType);
|
|
364
|
-
return (_jsxs(Box, {
|
|
364
|
+
return (_jsxs(Box, { sx: {
|
|
365
|
+
paddingLeft: "24px",
|
|
366
|
+
paddingRight: "24px",
|
|
367
|
+
paddingTop: "10px",
|
|
368
|
+
}, children: [_jsxs(Box, { component: "nav", sx: {
|
|
365
369
|
display: "flex",
|
|
366
370
|
minHeight: "2.5em",
|
|
367
371
|
alignItems: "center",
|
|
368
372
|
maxWidth: "calc(100vw - 24px - 24px)",
|
|
369
|
-
}, children: [_jsx(Typography, { variant: "subtitle1", children: "Tool Replacements" }), _jsx(Box, {
|
|
373
|
+
}, children: [_jsx(Typography, { variant: "subtitle1", children: "Tool Replacements" }), _jsx(Box, { sx: {
|
|
374
|
+
flexGrow: 1,
|
|
375
|
+
} }), _jsx(FormControl, { size: "small", children: _jsxs(Select, { autoWidth: true, value: type, style: { marginLeft: "1em" }, onChange: (e) => setType(e.target.value), children: [_jsx(MenuItem, { value: "summary", children: "Summary" }), _jsx(MenuItem, { value: "details", children: "Details" })] }) }), _jsx(ChooseMachine, { station: selectedMachine, setSelectedStation: setSelectedMachine, displayType: type })] }), _jsx("main", { children: type === "summary" ? (_jsx(SummaryTable, { station: selectedMachine })) : (_jsx(AllReplacementTable, { station: selectedMachine })) })] }));
|
|
370
376
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as api from "../network/api.js";
|
|
2
|
+
export function* filterRemoveAddQueue(entries) {
|
|
3
|
+
let prev = null;
|
|
4
|
+
for (const e of entries) {
|
|
5
|
+
if (prev != null &&
|
|
6
|
+
prev.type === api.LogType.RemoveFromQueue &&
|
|
7
|
+
e.type === api.LogType.AddToQueue &&
|
|
8
|
+
prev.loc === e.loc) {
|
|
9
|
+
prev = null;
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
if (prev !== null) {
|
|
13
|
+
yield prev;
|
|
14
|
+
}
|
|
15
|
+
prev = e;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (prev !== null) {
|
|
19
|
+
yield prev;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -45,6 +45,8 @@ import { closestCenter, DndContext, DragOverlay, getFirstCollision, MeasuringStr
|
|
|
45
45
|
import { QuarantineMatButton } from "../station-monitor/QuarantineButton.js";
|
|
46
46
|
import { useSetTitle } from "../routes.js";
|
|
47
47
|
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
48
|
+
import { fmsInformation } from "../../network/server-settings.js";
|
|
49
|
+
import { basketDisplayName, loadStationDisplayName } from "../../cell-status/station-cycles.js";
|
|
48
50
|
const ColumnWithTitle = forwardRef(function MaterialBin(props, ref) {
|
|
49
51
|
return (_jsxs(Box, { sx: {
|
|
50
52
|
margin: props.isDragOverlay ? undefined : "0.75em",
|
|
@@ -89,9 +91,6 @@ const QuarantineQueue = memo(function QuarantineQueue(props) {
|
|
|
89
91
|
return (_jsx(SortableColumnWithTitle, { binId: props.binId, label: props.queue, bin: props.bin, children: _jsx(SortableContext, { items: props.material.map((m) => m.materialID), strategy: verticalListSortingStrategy, children: props.material.map((mat) => (_jsx(SortableInProcMaterial, { mat: mat, hideAvatar: true }, mat.materialID))) }) }));
|
|
90
92
|
}
|
|
91
93
|
});
|
|
92
|
-
function renderLul(lul) {
|
|
93
|
-
return "L/U " + lul.toString();
|
|
94
|
-
}
|
|
95
94
|
function compareLul(l1, l2) {
|
|
96
95
|
return l1 - l2;
|
|
97
96
|
}
|
|
@@ -114,22 +113,34 @@ function renderQueue(queue) {
|
|
|
114
113
|
function compareQueue(q1, q2) {
|
|
115
114
|
return q1.localeCompare(q2);
|
|
116
115
|
}
|
|
116
|
+
function compareBasket(b1, b2) {
|
|
117
|
+
return b1 - b2;
|
|
118
|
+
}
|
|
117
119
|
class SystemMaterial extends PureComponent {
|
|
118
120
|
render() {
|
|
119
121
|
const Col = this.props.isDragOverlay ? ColumnWithTitle : SortableColumnWithTitle;
|
|
120
122
|
return (_jsx(Col, { label: this.props.name, binId: this.props.binId, bin: this.props.bin, isDragOverlay: this.props.isDragOverlay, children: LazySeq.of(this.props.material)
|
|
121
123
|
.sortWith(([l1, _m1], [l2, _m2]) => this.props.compareLabel(l1, l2))
|
|
122
|
-
.map(([label, material],
|
|
124
|
+
.map(([label, material], matGroupIdx) => (_jsxs("div", { children: [_jsx(Typography, { variant: "caption", children: this.props.renderLabel(label) }), material.map((mat, idx) => (_jsx(InProcMaterial, { mat: mat, hideAvatar: true }, idx)))] }, matGroupIdx))) }));
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
function MaterialBinColumn({ matBin, isDragOverlay, }) {
|
|
128
|
+
const fmsInfo = useAtomValue(fmsInformation);
|
|
129
|
+
const basketName = basketDisplayName(fmsInfo.basketName);
|
|
126
130
|
switch (matBin.type) {
|
|
127
131
|
case MaterialBinType.LoadStations:
|
|
128
|
-
return (_jsx(SystemMaterial, { name: "Load Stations", binId: matBin.binId, renderLabel:
|
|
132
|
+
return (_jsx(SystemMaterial, { name: "Load Stations", binId: matBin.binId, renderLabel: (lul) => loadStationDisplayName(lul, fmsInfo.loadStationNames), compareLabel: compareLul, material: matBin.byLul, bin: matBin, isDragOverlay: isDragOverlay }));
|
|
129
133
|
case MaterialBinType.Pallets:
|
|
130
134
|
return (_jsx(SystemMaterial, { name: "Pallets", binId: matBin.binId, renderLabel: renderPal, compareLabel: comparePal, material: matBin.byPallet, bin: matBin, isDragOverlay: isDragOverlay }));
|
|
131
135
|
case MaterialBinType.ActiveQueues:
|
|
132
136
|
return (_jsx(SystemMaterial, { name: "Queues", binId: matBin.binId, renderLabel: renderQueue, compareLabel: compareQueue, material: matBin.byQueue, bin: matBin, isDragOverlay: isDragOverlay }));
|
|
137
|
+
case MaterialBinType.Baskets:
|
|
138
|
+
return (_jsx(SystemMaterial, { name: basketName + "s", binId: matBin.binId, renderLabel: (id) => basketName +
|
|
139
|
+
" " +
|
|
140
|
+
id.toString() +
|
|
141
|
+
(typeof id === "number" && matBin.basketLocations.get(id)
|
|
142
|
+
? ` (${matBin.basketLocations.get(id)})`
|
|
143
|
+
: ""), compareLabel: compareBasket, material: matBin.byBasket, bin: matBin, isDragOverlay: isDragOverlay }));
|
|
133
144
|
case MaterialBinType.QuarantineQueues:
|
|
134
145
|
return (_jsx(QuarantineQueue, { binId: matBin.binId, queue: matBin.queueName, material: matBin.material, bin: matBin, isDragOverlay: isDragOverlay }));
|
|
135
146
|
}
|
|
@@ -181,12 +192,12 @@ export function AllMaterial(props) {
|
|
|
181
192
|
const reorderQueuedMat = useSetAtom(currentSt.reorderQueuedMatInCurrentStatus);
|
|
182
193
|
const [activeDrag, setActiveDrag] = useState(null);
|
|
183
194
|
const allBins = useMemo(() => {
|
|
184
|
-
const
|
|
195
|
+
const bins = selectAllMaterialIntoBins(st, matBinOrder);
|
|
185
196
|
if (activeDrag && activeDrag.type === "material" && activeDrag.curOverBinId !== null) {
|
|
186
|
-
return moveMaterialInBin(
|
|
197
|
+
return moveMaterialInBin(bins, activeDrag.mat, activeDrag.curOverBinId, activeDrag.initialIdx);
|
|
187
198
|
}
|
|
188
199
|
else {
|
|
189
|
-
return
|
|
200
|
+
return bins;
|
|
190
201
|
}
|
|
191
202
|
}, [st, matBinOrder, activeDrag]);
|
|
192
203
|
const curBins = props.displaySystemBins
|
|
@@ -196,10 +207,15 @@ export function AllMaterial(props) {
|
|
|
196
207
|
return (_jsxs(DndContext, { collisionDetection: collisionDetectionStrategy, measuring: {
|
|
197
208
|
droppable: { strategy: MeasuringStrategy.Always },
|
|
198
209
|
}, onDragStart: ({ active }) => {
|
|
199
|
-
if (typeof active.id === "string"
|
|
210
|
+
if (typeof active.id === "string" &&
|
|
211
|
+
typeof active.data.current === "object" &&
|
|
212
|
+
active.data.current !== null &&
|
|
213
|
+
"bin" in active.data.current) {
|
|
200
214
|
setActiveDrag({ type: "column", bin: active.data.current.bin });
|
|
201
215
|
}
|
|
202
|
-
else
|
|
216
|
+
else if (typeof active.data.current === "object" &&
|
|
217
|
+
active.data.current !== null &&
|
|
218
|
+
"mat" in active.data.current) {
|
|
203
219
|
setActiveDrag({
|
|
204
220
|
type: "material",
|
|
205
221
|
mat: active.data.current.mat,
|
|
@@ -35,6 +35,37 @@ import { memo, useState } from "react";
|
|
|
35
35
|
import { last30ChartEndTimes, last30ChartStartTimes, last30WeekdayStartIdx, last30WeekdayStartMinuteOffset, } from "../../data/chart-times";
|
|
36
36
|
import { useAtom, useAtomValue } from "jotai";
|
|
37
37
|
import { Box, Button, Dialog, DialogActions, DialogContent, Divider, IconButton, MenuItem, Radio, RadioGroup, Stack, TextField, Tooltip, Typography, } from "@mui/material";
|
|
38
|
+
function isStartType(value) {
|
|
39
|
+
return (value === "CustomDate" ||
|
|
40
|
+
value === "StartOfToday" ||
|
|
41
|
+
value === "StartOfYesterday" ||
|
|
42
|
+
value === "StartOfWeek" ||
|
|
43
|
+
value === "StartOfLastWeek" ||
|
|
44
|
+
value === "Last30");
|
|
45
|
+
}
|
|
46
|
+
function isEndType(value) {
|
|
47
|
+
return value === "CustomDate" || value === "Now" || value === "EndOfYesterday" || value === "EndOfLastWeek";
|
|
48
|
+
}
|
|
49
|
+
function parseWeekdayStart(value) {
|
|
50
|
+
switch (value) {
|
|
51
|
+
case "0":
|
|
52
|
+
return 0;
|
|
53
|
+
case "1":
|
|
54
|
+
return 1;
|
|
55
|
+
case "2":
|
|
56
|
+
return 2;
|
|
57
|
+
case "3":
|
|
58
|
+
return 3;
|
|
59
|
+
case "4":
|
|
60
|
+
return 4;
|
|
61
|
+
case "5":
|
|
62
|
+
return 5;
|
|
63
|
+
case "6":
|
|
64
|
+
return 6;
|
|
65
|
+
default:
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
38
69
|
import { Edit } from "@mui/icons-material";
|
|
39
70
|
import { addMinutes, startOfToday } from "date-fns";
|
|
40
71
|
function RadioLabel({ label, date }) {
|
|
@@ -70,7 +101,29 @@ function RangeStart({ chartAtom }) {
|
|
|
70
101
|
const startOfWeek = useAtomValue(last30ChartStartTimes("StartOfWeek"));
|
|
71
102
|
const startOfLastWeek = useAtomValue(last30ChartStartTimes("StartOfLastWeek"));
|
|
72
103
|
const last30 = useAtomValue(last30ChartStartTimes("Last30"));
|
|
73
|
-
return (_jsxs(Box, { children: [_jsx(Typography, { variant: "h6", children: "Range Start" }), _jsx(RadioGroup, { value: chartRange.startType instanceof Date ? "CustomDate" : chartRange.startType, onChange: (event) =>
|
|
104
|
+
return (_jsxs(Box, { children: [_jsx(Typography, { variant: "h6", children: "Range Start" }), _jsx(RadioGroup, { value: chartRange.startType instanceof Date ? "CustomDate" : chartRange.startType, onChange: (event) => {
|
|
105
|
+
if (isStartType(event.target.value)) {
|
|
106
|
+
setTy(event.target.value);
|
|
107
|
+
}
|
|
108
|
+
}, children: _jsxs(Stack, { direction: "column", spacing: 2, children: [_jsxs(Stack, { direction: "row", sx: {
|
|
109
|
+
alignItems: "center",
|
|
110
|
+
minHeight: "3em",
|
|
111
|
+
}, children: [_jsx(Radio, { value: "StartOfToday" }), _jsx(RadioLabel, { label: "Start of Today", date: stOfToday })] }), _jsxs(Stack, { direction: "row", sx: {
|
|
112
|
+
alignItems: "center",
|
|
113
|
+
minHeight: "3em",
|
|
114
|
+
}, children: [_jsx(Radio, { value: "StartOfYesterday" }), _jsx(RadioLabel, { label: "Start of Yesterday", date: startOfYesterday })] }), _jsxs(Stack, { direction: "row", sx: {
|
|
115
|
+
alignItems: "center",
|
|
116
|
+
minHeight: "3em",
|
|
117
|
+
}, children: [_jsx(Radio, { value: "StartOfWeek" }), _jsx(RadioLabel, { label: "Start of This Week", date: startOfWeek })] }), _jsxs(Stack, { direction: "row", sx: {
|
|
118
|
+
alignItems: "center",
|
|
119
|
+
minHeight: "3em",
|
|
120
|
+
}, children: [_jsx(Radio, { value: "StartOfLastWeek" }), _jsx(RadioLabel, { label: "Start of Last Week", date: startOfLastWeek })] }), _jsxs(Stack, { direction: "row", sx: {
|
|
121
|
+
alignItems: "center",
|
|
122
|
+
minHeight: "3em",
|
|
123
|
+
}, children: [_jsx(Radio, { value: "Last30" }), _jsx(RadioLabel, { label: "Last 30 Days", date: last30 })] }), _jsxs(Stack, { direction: "row", sx: {
|
|
124
|
+
alignItems: "center",
|
|
125
|
+
minHeight: "3em",
|
|
126
|
+
}, children: [_jsx(Radio, { value: "CustomDate" }), _jsx(CustomDateLabel, { enabled: chartRange.startType instanceof Date, date: customDate, setDate: setDate })] })] }) })] }));
|
|
74
127
|
}
|
|
75
128
|
function RangeEnd({ chartAtom }) {
|
|
76
129
|
const [chartRange, setChartRange] = useAtom(chartAtom);
|
|
@@ -90,7 +143,23 @@ function RangeEnd({ chartAtom }) {
|
|
|
90
143
|
}
|
|
91
144
|
const endOfYesterday = useAtomValue(last30ChartEndTimes("EndOfYesterday"));
|
|
92
145
|
const endOfLastWeek = useAtomValue(last30ChartEndTimes("EndOfLastWeek"));
|
|
93
|
-
return (_jsxs(Box, { children: [_jsx(Typography, { variant: "h6", children: "Range End" }), _jsx(RadioGroup, { value: chartRange.endType instanceof Date ? "CustomDate" : chartRange.endType, onChange: (event) =>
|
|
146
|
+
return (_jsxs(Box, { children: [_jsx(Typography, { variant: "h6", children: "Range End" }), _jsx(RadioGroup, { value: chartRange.endType instanceof Date ? "CustomDate" : chartRange.endType, onChange: (event) => {
|
|
147
|
+
if (isEndType(event.target.value)) {
|
|
148
|
+
setTy(event.target.value);
|
|
149
|
+
}
|
|
150
|
+
}, children: _jsxs(Stack, { direction: "column", spacing: 2, children: [_jsxs(Stack, { direction: "row", sx: {
|
|
151
|
+
alignItems: "center",
|
|
152
|
+
minHeight: "3em",
|
|
153
|
+
}, children: [_jsx(Radio, { value: "Now" }), _jsx(Typography, { children: "Now" })] }), _jsxs(Stack, { direction: "row", sx: {
|
|
154
|
+
alignItems: "center",
|
|
155
|
+
minHeight: "3em",
|
|
156
|
+
}, children: [_jsx(Radio, { value: "EndOfYesterday" }), _jsx(RadioLabel, { label: "End of Yesterday", date: endOfYesterday })] }), _jsx(Box, { sx: { height: "3em" } }), _jsxs(Stack, { direction: "row", sx: {
|
|
157
|
+
alignItems: "center",
|
|
158
|
+
minHeight: "3em",
|
|
159
|
+
}, children: [_jsx(Radio, { value: "EndOfLastWeek" }), _jsx(RadioLabel, { label: "End of Last Week", date: endOfLastWeek })] }), _jsx(Box, { sx: { height: "3em" } }), _jsxs(Stack, { direction: "row", sx: {
|
|
160
|
+
alignItems: "center",
|
|
161
|
+
minHeight: "3em",
|
|
162
|
+
}, children: [_jsx(Radio, { value: "CustomDate" }), _jsx(CustomDateLabel, { enabled: chartRange.endType instanceof Date, date: customDate, setDate: setDate })] })] }) })] }));
|
|
94
163
|
}
|
|
95
164
|
function minutesToTimespan(m) {
|
|
96
165
|
const h = Math.floor(m / 60);
|
|
@@ -100,7 +169,14 @@ function minutesToTimespan(m) {
|
|
|
100
169
|
function RangeDialog({ chartAtom, open, setOpen, }) {
|
|
101
170
|
const [weekdayStart, setWeekdayStart] = useAtom(last30WeekdayStartIdx);
|
|
102
171
|
const [weekdayStartMinuteOffset, setWeekdayStartMinuteOffset] = useAtom(last30WeekdayStartMinuteOffset);
|
|
103
|
-
return (_jsxs(Dialog, { open: open, onClose: () => setOpen(false), maxWidth: "md", children: [_jsx(DialogContent, { children: _jsxs(Stack, { direction: "column", spacing: 2, divider: _jsx(Divider, { orientation: "horizontal", flexItem: true }), children: [_jsxs(Stack, { direction: "row", spacing: 2, divider: _jsx(Divider, { orientation: "vertical", flexItem: true }), children: [_jsx(RangeStart, { chartAtom: chartAtom }), _jsx(RangeEnd, { chartAtom: chartAtom })] }), _jsxs(Stack, { direction: "row",
|
|
172
|
+
return (_jsxs(Dialog, { open: open, onClose: () => setOpen(false), maxWidth: "md", children: [_jsx(DialogContent, { children: _jsxs(Stack, { direction: "column", spacing: 2, divider: _jsx(Divider, { orientation: "horizontal", flexItem: true }), children: [_jsxs(Stack, { direction: "row", spacing: 2, divider: _jsx(Divider, { orientation: "vertical", flexItem: true }), children: [_jsx(RangeStart, { chartAtom: chartAtom }), _jsx(RangeEnd, { chartAtom: chartAtom })] }), _jsxs(Stack, { direction: "row", sx: {
|
|
173
|
+
justifyContent: "space-around",
|
|
174
|
+
}, children: [_jsxs(TextField, { select: true, label: "First Day Of Week", sx: { minWidth: "10em" }, value: weekdayStart, onChange: (e) => {
|
|
175
|
+
const parsed = parseWeekdayStart(e.target.value);
|
|
176
|
+
if (parsed !== null) {
|
|
177
|
+
setWeekdayStart(parsed);
|
|
178
|
+
}
|
|
179
|
+
}, children: [_jsx(MenuItem, { value: 0, children: "Sunday" }), _jsx(MenuItem, { value: 1, children: "Monday" }), _jsx(MenuItem, { value: 2, children: "Tuesday" }), _jsx(MenuItem, { value: 3, children: "Wednesday" }), _jsx(MenuItem, { value: 4, children: "Thursday" }), _jsx(MenuItem, { value: 5, children: "Friday" }), _jsx(MenuItem, { value: 6, children: "Saturday" })] }), _jsx(TextField, { type: "time", label: "Day Start Time", sx: { minWidth: "10em" }, value: minutesToTimespan(weekdayStartMinuteOffset), onChange: (e) => {
|
|
104
180
|
const val = e.target.value;
|
|
105
181
|
if (val === "") {
|
|
106
182
|
setWeekdayStartMinuteOffset(0);
|
|
@@ -144,5 +220,7 @@ function formatEnd(ty, d) {
|
|
|
144
220
|
export const Last30ChartRangeToolbar = memo(function Last30ChartRangeToolbar({ chartAtom, }) {
|
|
145
221
|
const chartRange = useAtomValue(chartAtom);
|
|
146
222
|
const [dialogOpen, setDialogOpen] = useState(false);
|
|
147
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Stack, { direction: "row", spacing: 2,
|
|
223
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Stack, { direction: "row", spacing: 2, sx: {
|
|
224
|
+
alignItems: "center",
|
|
225
|
+
}, children: [_jsxs(Typography, { variant: "body2", color: "textSecondary", children: ["Range: ", formatStart(chartRange.startType, chartRange.startDate), " -", " ", formatEnd(chartRange.endType, chartRange.endDate)] }), _jsx(Tooltip, { title: "Edit Range", children: _jsx(IconButton, { onClick: () => setDialogOpen(true), children: _jsx(Edit, {}) }) })] }), _jsx(RangeDialog, { open: dialogOpen, setOpen: setDialogOpen, chartAtom: chartAtom })] }));
|
|
148
226
|
});
|