@seedtactics/insight-client 16.6.0 → 16.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/ProgramHighlight-DPTeZ8Si.js +3 -0
- package/dist/assets/index-DL7cXxkt.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 +30 -32
- package/dist/assets/ProgramHighlight-LvRM40Qr.js +0 -3
- package/dist/assets/index-gAFi3Oss.js +0 -364
|
@@ -36,6 +36,25 @@ import { durationToMinutes } from "../util/parseISODuration.js";
|
|
|
36
36
|
import { addDays } from "date-fns";
|
|
37
37
|
import { HashMap } from "@seedtactics/immutable-collections";
|
|
38
38
|
import { atom } from "jotai";
|
|
39
|
+
import { fmsInformation } from "../network/server-settings.js";
|
|
40
|
+
export function isLaborCycle(cycle) {
|
|
41
|
+
return cycle.carrier.kind !== "machining";
|
|
42
|
+
}
|
|
43
|
+
export function isMachineCycle(cycle) {
|
|
44
|
+
return cycle.carrier.kind === "machining";
|
|
45
|
+
}
|
|
46
|
+
export function isPalletLoadCycle(cycle) {
|
|
47
|
+
return cycle.carrier.kind === "pallet-lul";
|
|
48
|
+
}
|
|
49
|
+
export function isBasketLoadCycle(cycle) {
|
|
50
|
+
return cycle.carrier.kind === "basket-lul";
|
|
51
|
+
}
|
|
52
|
+
export function palletForCycle(cycle) {
|
|
53
|
+
return cycle.carrier.kind === "basket-lul" ? undefined : cycle.carrier.pallet;
|
|
54
|
+
}
|
|
55
|
+
export function basketForCycle(cycle) {
|
|
56
|
+
return cycle.carrier.kind === "basket-lul" ? cycle.carrier.basket : undefined;
|
|
57
|
+
}
|
|
39
58
|
export function stat_name_and_num(stationGroup, stationNumber) {
|
|
40
59
|
if (stationGroup.startsWith("Inspect")) {
|
|
41
60
|
return stationGroup;
|
|
@@ -44,21 +63,68 @@ export function stat_name_and_num(stationGroup, stationNumber) {
|
|
|
44
63
|
return stationGroup + " #" + stationNumber.toString();
|
|
45
64
|
}
|
|
46
65
|
}
|
|
66
|
+
export function loadStationDisplayName(stationNumber, loadStationNames) {
|
|
67
|
+
const name = loadStationNames?.[stationNumber.toString()];
|
|
68
|
+
return name && name.trim().length > 0 ? name : `L/U #${stationNumber}`;
|
|
69
|
+
}
|
|
70
|
+
export function displayStationName(stationGroup, stationNumber, loadStationNames) {
|
|
71
|
+
return stationGroup === "L/U"
|
|
72
|
+
? loadStationDisplayName(stationNumber, loadStationNames)
|
|
73
|
+
: stat_name_and_num(stationGroup, stationNumber);
|
|
74
|
+
}
|
|
75
|
+
export function basketDisplayName(basketName) {
|
|
76
|
+
return basketName && basketName.trim().length > 0 ? basketName : "Basket";
|
|
77
|
+
}
|
|
78
|
+
export function carrierLabel(cycle, basketName = "Basket") {
|
|
79
|
+
switch (cycle.carrier.kind) {
|
|
80
|
+
case "machining":
|
|
81
|
+
case "pallet-lul":
|
|
82
|
+
return `Pallet ${cycle.carrier.pallet}`;
|
|
83
|
+
case "basket-lul":
|
|
84
|
+
return `${basketName} ${cycle.carrier.basket}`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export function carrierSortKey(cycle) {
|
|
88
|
+
switch (cycle.carrier.kind) {
|
|
89
|
+
case "machining":
|
|
90
|
+
case "pallet-lul":
|
|
91
|
+
return cycle.carrier.pallet;
|
|
92
|
+
case "basket-lul":
|
|
93
|
+
return cycle.carrier.basket + 1000000;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function hasBasketCycles(cycles) {
|
|
97
|
+
return cycles.valuesToLazySeq().some((cycle) => cycle.carrier.kind === "basket-lul");
|
|
98
|
+
}
|
|
47
99
|
const last30StationCyclesRW = atom(HashMap.empty());
|
|
48
100
|
export const last30StationCycles = last30StationCyclesRW;
|
|
101
|
+
export const last30HasBasketCycles = atom((get) => hasBasketCycles(get(last30StationCyclesRW)));
|
|
49
102
|
const specificMonthStationCyclesRW = atom(HashMap.empty());
|
|
50
103
|
export const specificMonthStationCycles = specificMonthStationCyclesRW;
|
|
51
|
-
|
|
104
|
+
export const specificMonthHasBasketCycles = atom((get) => hasBasketCycles(get(specificMonthStationCyclesRW)));
|
|
105
|
+
function convertLogToCycle(estimatedCycleTimes, cycle, elapsedPerMat, loadStationNames) {
|
|
52
106
|
if (cycle.startofcycle ||
|
|
53
|
-
(cycle.type !== LogType.LoadUnloadCycle &&
|
|
107
|
+
(cycle.type !== LogType.LoadUnloadCycle &&
|
|
108
|
+
cycle.type !== LogType.BasketLoadUnload &&
|
|
109
|
+
cycle.type !== LogType.MachineCycle) ||
|
|
54
110
|
cycle.loc === "") {
|
|
55
111
|
return null;
|
|
56
112
|
}
|
|
113
|
+
const carrier = cycle.type === LogType.MachineCycle
|
|
114
|
+
? { kind: "machining", pallet: cycle.pal }
|
|
115
|
+
: cycle.type === LogType.LoadUnloadCycle
|
|
116
|
+
? { kind: "pallet-lul", pallet: cycle.pal }
|
|
117
|
+
: { kind: "basket-lul", basket: cycle.pal };
|
|
118
|
+
const activeMinsFromLog = durationToMinutes(cycle.active);
|
|
119
|
+
if (carrier.kind === "basket-lul" && elapsedPerMat <= 0 && activeMinsFromLog <= 0) {
|
|
120
|
+
// For pallet <-> basket transfers, the basket-side companion event carries zero time.
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
57
123
|
const part = cycle.material.length > 0 ? cycle.material[0].part : "";
|
|
58
124
|
const stats = cycle.material.length > 0
|
|
59
125
|
? estimatedCycleTimes.get(PartAndStationOperation.ofLogCycle(cycle))
|
|
60
126
|
: undefined;
|
|
61
|
-
let activeMins =
|
|
127
|
+
let activeMins = activeMinsFromLog;
|
|
62
128
|
if (cycle.active === "" || activeMins <= 0 || cycle.material.length == 0) {
|
|
63
129
|
activeMins = (stats?.expectedCycleMinutesForSingleMat ?? 0) * cycle.material.length;
|
|
64
130
|
}
|
|
@@ -70,19 +136,19 @@ function convertLogToCycle(estimatedCycleTimes, cycle, elapsedPerMat) {
|
|
|
70
136
|
medianCycleMinutes: (stats?.medianMinutesForSingleMat ?? 0) * cycle.material.length,
|
|
71
137
|
MAD_aboveMinutes: stats?.MAD_aboveMinutes ?? 0,
|
|
72
138
|
part: part,
|
|
73
|
-
|
|
139
|
+
carrier: carrier,
|
|
74
140
|
material: cycle.material,
|
|
75
|
-
isLabor: cycle.type === LogType.LoadUnloadCycle,
|
|
76
141
|
isOutlier: stats ? isOutlier(stats, elapsedPerMat) : false,
|
|
77
142
|
stationGroup: cycle.loc,
|
|
78
143
|
stationNumber: cycle.locnum,
|
|
79
|
-
|
|
144
|
+
stationLabel: displayStationName(cycle.loc, cycle.locnum, loadStationNames),
|
|
145
|
+
operation: carrier.kind === "machining" ? cycle.program : cycle.result,
|
|
80
146
|
operator: cycle.details ? cycle.details.operator || "" : "",
|
|
81
147
|
};
|
|
82
148
|
}
|
|
83
|
-
function convertOldLogsToCycles(estimateCycleTimes, log) {
|
|
149
|
+
function convertOldLogsToCycles(estimateCycleTimes, log, loadStationNames) {
|
|
84
150
|
return calcElapsedForCycles(log)
|
|
85
|
-
.collect((c) => convertLogToCycle(estimateCycleTimes, c.cycle, c.elapsedForSingleMaterialMinutes))
|
|
151
|
+
.collect((c) => convertLogToCycle(estimateCycleTimes, c.cycle, c.elapsedForSingleMaterialMinutes, loadStationNames))
|
|
86
152
|
.buildHashMap((c) => c.cntr);
|
|
87
153
|
}
|
|
88
154
|
function process_swap(swap, partCycles) {
|
|
@@ -97,7 +163,8 @@ function process_swap(swap, partCycles) {
|
|
|
97
163
|
}
|
|
98
164
|
export const setLast30StationCycles = atom(null, (get, set, log) => {
|
|
99
165
|
const estimatedCycleTimes = get(last30EstimatedCycleTimes);
|
|
100
|
-
|
|
166
|
+
const loadStationNames = get(fmsInformation)?.loadStationNames;
|
|
167
|
+
set(last30StationCyclesRW, (oldCycles) => oldCycles.union(convertOldLogsToCycles(estimatedCycleTimes, log, loadStationNames)));
|
|
101
168
|
});
|
|
102
169
|
export const updateLast30StationCycles = atom(null, (get, set, { evt, now, expire }) => {
|
|
103
170
|
if (evt.logEntry && evt.logEntry.type === LogType.InvalidateCycle) {
|
|
@@ -122,7 +189,8 @@ export const updateLast30StationCycles = atom(null, (get, set, { evt, now, expir
|
|
|
122
189
|
const elapsedPerMat = evt.logEntry.material.length > 0
|
|
123
190
|
? durationToMinutes(evt.logEntry.elapsed) / evt.logEntry.material.length
|
|
124
191
|
: 0;
|
|
125
|
-
const
|
|
192
|
+
const loadStationNames = get(fmsInformation)?.loadStationNames;
|
|
193
|
+
const converted = convertLogToCycle(estimatedCycleTimes, evt.logEntry, elapsedPerMat, loadStationNames);
|
|
126
194
|
if (!converted)
|
|
127
195
|
return;
|
|
128
196
|
set(last30StationCyclesRW, (cycles) => {
|
|
@@ -141,5 +209,7 @@ export const updateLast30StationCycles = atom(null, (get, set, { evt, now, expir
|
|
|
141
209
|
});
|
|
142
210
|
export const setSpecificMonthStationCycles = atom(null, (get, set, log) => {
|
|
143
211
|
const estimatedCycleTimes = get(specificMonthEstimatedCycleTimes);
|
|
144
|
-
|
|
212
|
+
const loadStationNames = get(fmsInformation)?.loadStationNames;
|
|
213
|
+
const cycles = convertOldLogsToCycles(estimatedCycleTimes, log, loadStationNames);
|
|
214
|
+
set(specificMonthStationCyclesRW, cycles);
|
|
145
215
|
});
|
|
@@ -77,7 +77,7 @@ function addReplacementsFromLog(old, e) {
|
|
|
77
77
|
const totalCntAtEnd = use.totalToolUseCountAtEndOfCycle ?? null;
|
|
78
78
|
if ((useDuring || cntDuring) && useDuring === totalUseAtEnd && cntDuring === totalCntAtEnd) {
|
|
79
79
|
// replace before cycle start
|
|
80
|
-
const last = old.recentUse.get(key)?.find((
|
|
80
|
+
const last = old.recentUse.get(key)?.find((entry) => entry.tool === use.tool && entry.pocket === use.pocket);
|
|
81
81
|
if (last) {
|
|
82
82
|
const lastTotalUse = last.totalToolUseAtEndOfCycle
|
|
83
83
|
? durationToMinutes(last.totalToolUseAtEndOfCycle)
|
|
@@ -84,7 +84,7 @@ function process_tools(cycle, estimatedCycleTimes, toolUsage) {
|
|
|
84
84
|
}
|
|
85
85
|
export const setLast30ToolUse = atom(null, (get, set, log) => {
|
|
86
86
|
const estimated = get(last30EstimatedCycleTimes);
|
|
87
|
-
set(last30ToolUseRW, (oldUsage) => log.reduce((usage,
|
|
87
|
+
set(last30ToolUseRW, (oldUsage) => log.reduce((usage, entry) => process_tools(entry, estimated, usage), oldUsage));
|
|
88
88
|
});
|
|
89
89
|
export const updateLast30ToolUse = atom(null, (get, set, { evt }) => {
|
|
90
90
|
if (evt.logEntry) {
|
package/dist/components/App.js
CHANGED
|
@@ -70,6 +70,7 @@ import { BufferOccupancyChart } from "./analysis/BufferChart.js";
|
|
|
70
70
|
import { CompletedCountHeatmap, StationOeeHeatmap } from "./analysis/EfficiencyPage.js";
|
|
71
71
|
import { PartLoadStationCycleChart, PartMachineCycleChart } from "./analysis/PartCycleCards.js";
|
|
72
72
|
import { PalletCycleChart } from "./analysis/PalletCycleCards.js";
|
|
73
|
+
import { BasketCycleChart } from "./analysis/BasketCycleCards.js";
|
|
73
74
|
import { ToolReplacementPage } from "./analysis/ToolReplacements.js";
|
|
74
75
|
import { CurrentWorkordersPage } from "./operations/CurrentWorkorders.js";
|
|
75
76
|
import { useAtom, useAtomValue } from "jotai";
|
|
@@ -78,6 +79,8 @@ import { latestSimDayUsage } from "../cell-status/sim-day-usage.js";
|
|
|
78
79
|
import { CloseoutReport } from "./operations/CloseoutReport.js";
|
|
79
80
|
import { RebookingsPage } from "./operations/Rebookings.js";
|
|
80
81
|
import { RecentCompletedPartsPage } from "./operations/CompletedParts.js";
|
|
82
|
+
import { basketDisplayName } from "../cell-status/station-cycles.js";
|
|
83
|
+
import { last30HasBasketCycleData, specificMonthHasBasketCycleData } from "../cell-status/basket-cycles.js";
|
|
81
84
|
const OperationsReportsTab = "bms-operations-reports-tab";
|
|
82
85
|
const operationsReports = [
|
|
83
86
|
{ separator: "Load/Unload" },
|
|
@@ -166,59 +169,82 @@ const operationsReports = [
|
|
|
166
169
|
hidden: (info) => info.supportsRebookings === null || info.supportsRebookings === "",
|
|
167
170
|
},
|
|
168
171
|
];
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
name: "
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
172
|
+
function analysisReports(hasBasketCycles) {
|
|
173
|
+
return [
|
|
174
|
+
{ separator: "Efficiency" },
|
|
175
|
+
{ name: "Buffers", route: { route: routes.RouteLocation.Analysis_Buffers }, icon: _jsx(BufferIcon, {}) },
|
|
176
|
+
{
|
|
177
|
+
name: "Station OEE",
|
|
178
|
+
route: { route: routes.RouteLocation.Analysis_StationOEE },
|
|
179
|
+
icon: _jsx(HourglassIcon, {}),
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "Completed Parts",
|
|
183
|
+
route: { route: routes.RouteLocation.Analysis_PartsCompleted },
|
|
184
|
+
icon: _jsx(ExtensionIcon, {}),
|
|
185
|
+
},
|
|
186
|
+
{ separator: "Cycles" },
|
|
187
|
+
{
|
|
188
|
+
name: "Machine Cycles",
|
|
189
|
+
route: { route: routes.RouteLocation.Analysis_MachineCycles },
|
|
190
|
+
icon: _jsx(WorkIcon, {}),
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: "L/U Cycles",
|
|
194
|
+
route: { route: routes.RouteLocation.Analysis_LoadCycles },
|
|
195
|
+
icon: _jsx(LoadUnloadIcon, {}),
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: "Pallet Cycles",
|
|
199
|
+
route: { route: routes.RouteLocation.Analysis_PalletCycles },
|
|
200
|
+
icon: _jsx(PalletIcon, {}),
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: (info) => basketDisplayName(info.basketName) + " Cycles",
|
|
204
|
+
route: { route: routes.RouteLocation.Analysis_BasketCycles },
|
|
205
|
+
icon: _jsx(PalletIcon, {}),
|
|
206
|
+
hidden: () => !hasBasketCycles,
|
|
207
|
+
},
|
|
208
|
+
{ separator: "Cell" },
|
|
209
|
+
{ name: "Quality", route: { route: routes.RouteLocation.Analysis_Quality }, icon: _jsx(BuildIcon, {}) },
|
|
210
|
+
{
|
|
211
|
+
name: "Tool Replacements",
|
|
212
|
+
route: { route: routes.RouteLocation.Analysis_ToolReplacements },
|
|
213
|
+
icon: _jsx(ToolIcon, {}),
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: "Schedules",
|
|
217
|
+
route: { route: routes.RouteLocation.Analysis_Schedules },
|
|
218
|
+
icon: _jsx(ScheduleIcon, {}),
|
|
219
|
+
},
|
|
220
|
+
{ separator: "Costs" },
|
|
221
|
+
{
|
|
222
|
+
name: "Percentages",
|
|
223
|
+
route: { route: routes.RouteLocation.Analysis_CostPercents },
|
|
224
|
+
icon: _jsx(CallSplit, {}),
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "Cost/Piece",
|
|
228
|
+
route: { route: routes.RouteLocation.Analysis_CostPerPiece },
|
|
229
|
+
icon: _jsx(CostIcon, {}),
|
|
230
|
+
},
|
|
231
|
+
];
|
|
232
|
+
}
|
|
233
|
+
function isRouteLocation(value) {
|
|
234
|
+
return typeof value === "string" && Object.values(routes.RouteLocation).includes(value);
|
|
235
|
+
}
|
|
236
|
+
function isSimpleRouteLocation(value) {
|
|
237
|
+
return (isRouteLocation(value) &&
|
|
238
|
+
value !== routes.RouteLocation.Client_Custom &&
|
|
239
|
+
value !== routes.RouteLocation.Operations_CurrentWorkorders &&
|
|
240
|
+
value !== routes.RouteLocation.Station_InspectionMonitorWithType &&
|
|
241
|
+
value !== routes.RouteLocation.Station_LoadMonitor &&
|
|
242
|
+
value !== routes.RouteLocation.Station_Queues);
|
|
243
|
+
}
|
|
244
|
+
function toRouteState(simpleRoute) {
|
|
245
|
+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- these routes do not carry extra payload.
|
|
246
|
+
return { route: simpleRoute };
|
|
247
|
+
}
|
|
222
248
|
export function NavTabs({ children }) {
|
|
223
249
|
const [route, setRoute] = useAtom(routes.currentRoute);
|
|
224
250
|
const theme = useTheme();
|
|
@@ -229,8 +255,8 @@ export function NavTabs({ children }) {
|
|
|
229
255
|
if (v === OperationsReportsTab) {
|
|
230
256
|
setRoute({ route: routes.RouteLocation.Operations_MachineCycles });
|
|
231
257
|
}
|
|
232
|
-
else {
|
|
233
|
-
setRoute(
|
|
258
|
+
else if (isSimpleRouteLocation(v)) {
|
|
259
|
+
setRoute(toRouteState(v));
|
|
234
260
|
}
|
|
235
261
|
}), textColor: "inherit", scrollButtons: true, allowScrollButtonsMobile: true, indicatorColor: "secondary", children: children }));
|
|
236
262
|
}
|
|
@@ -255,7 +281,10 @@ function SalesTabs() {
|
|
|
255
281
|
const App = memo(function App(props) {
|
|
256
282
|
routes.useWatchHistory();
|
|
257
283
|
const fmsInfo = useAtomValue(serverSettings.fmsInformation);
|
|
284
|
+
const hasLast30BasketCycles = useAtomValue(last30HasBasketCycleData);
|
|
285
|
+
const hasSpecificMonthBasketCycles = useAtomValue(specificMonthHasBasketCycleData);
|
|
258
286
|
const [route, setRoute] = useAtom(routes.currentRoute);
|
|
287
|
+
const analysisMenuNavItems = analysisReports(hasLast30BasketCycles || hasSpecificMonthBasketCycles);
|
|
259
288
|
const showLogout = fmsInfo.user !== null && fmsInfo.user !== undefined;
|
|
260
289
|
let page;
|
|
261
290
|
let nav1 = undefined;
|
|
@@ -314,67 +343,73 @@ const App = memo(function App(props) {
|
|
|
314
343
|
case routes.RouteLocation.Analysis_Quality:
|
|
315
344
|
page = _jsx(AnalysisQualityPage, {});
|
|
316
345
|
nav1 = AnalysisSelectToolbar;
|
|
317
|
-
menuNavItems =
|
|
346
|
+
menuNavItems = analysisMenuNavItems;
|
|
318
347
|
showAlarms = false;
|
|
319
348
|
break;
|
|
320
349
|
case routes.RouteLocation.Analysis_ToolReplacements:
|
|
321
350
|
page = _jsx(ToolReplacementPage, {});
|
|
322
351
|
nav1 = AnalysisSelectToolbar;
|
|
323
|
-
menuNavItems =
|
|
352
|
+
menuNavItems = analysisMenuNavItems;
|
|
324
353
|
showAlarms = false;
|
|
325
354
|
break;
|
|
326
355
|
case routes.RouteLocation.Analysis_Schedules:
|
|
327
356
|
page = _jsx(ScheduleHistory, {});
|
|
328
357
|
nav1 = AnalysisSelectToolbar;
|
|
329
|
-
menuNavItems =
|
|
358
|
+
menuNavItems = analysisMenuNavItems;
|
|
330
359
|
showAlarms = false;
|
|
331
360
|
break;
|
|
332
361
|
case routes.RouteLocation.Analysis_Buffers:
|
|
333
362
|
page = _jsx(BufferOccupancyChart, {});
|
|
334
363
|
nav1 = AnalysisSelectToolbar;
|
|
335
|
-
menuNavItems =
|
|
364
|
+
menuNavItems = analysisMenuNavItems;
|
|
336
365
|
showAlarms = false;
|
|
337
366
|
break;
|
|
338
367
|
case routes.RouteLocation.Analysis_StationOEE:
|
|
339
368
|
page = _jsx(StationOeeHeatmap, {});
|
|
340
369
|
nav1 = AnalysisSelectToolbar;
|
|
341
|
-
menuNavItems =
|
|
370
|
+
menuNavItems = analysisMenuNavItems;
|
|
342
371
|
showAlarms = false;
|
|
343
372
|
break;
|
|
344
373
|
case routes.RouteLocation.Analysis_PartsCompleted:
|
|
345
374
|
page = _jsx(CompletedCountHeatmap, {});
|
|
346
375
|
nav1 = AnalysisSelectToolbar;
|
|
347
|
-
menuNavItems =
|
|
376
|
+
menuNavItems = analysisMenuNavItems;
|
|
348
377
|
showAlarms = false;
|
|
349
378
|
break;
|
|
350
379
|
case routes.RouteLocation.Analysis_MachineCycles:
|
|
351
380
|
page = _jsx(PartMachineCycleChart, {});
|
|
352
381
|
nav1 = AnalysisSelectToolbar;
|
|
353
|
-
menuNavItems =
|
|
382
|
+
menuNavItems = analysisMenuNavItems;
|
|
354
383
|
showAlarms = false;
|
|
355
384
|
break;
|
|
356
385
|
case routes.RouteLocation.Analysis_LoadCycles:
|
|
357
386
|
page = _jsx(PartLoadStationCycleChart, {});
|
|
358
387
|
nav1 = AnalysisSelectToolbar;
|
|
359
|
-
menuNavItems =
|
|
388
|
+
menuNavItems = analysisMenuNavItems;
|
|
360
389
|
showAlarms = false;
|
|
361
390
|
break;
|
|
362
391
|
case routes.RouteLocation.Analysis_PalletCycles:
|
|
363
392
|
page = _jsx(PalletCycleChart, {});
|
|
364
393
|
nav1 = AnalysisSelectToolbar;
|
|
365
|
-
menuNavItems =
|
|
394
|
+
menuNavItems = analysisMenuNavItems;
|
|
395
|
+
showAlarms = false;
|
|
396
|
+
break;
|
|
397
|
+
case routes.RouteLocation.Analysis_BasketCycles:
|
|
398
|
+
page = _jsx(BasketCycleChart, {});
|
|
399
|
+
nav1 = AnalysisSelectToolbar;
|
|
400
|
+
menuNavItems = analysisMenuNavItems;
|
|
366
401
|
showAlarms = false;
|
|
367
402
|
break;
|
|
368
403
|
case routes.RouteLocation.Analysis_CostPercents:
|
|
369
404
|
page = _jsx(CostBreakdownPage, {});
|
|
370
405
|
nav1 = AnalysisSelectToolbar;
|
|
371
|
-
menuNavItems =
|
|
406
|
+
menuNavItems = analysisMenuNavItems;
|
|
372
407
|
showAlarms = false;
|
|
373
408
|
break;
|
|
374
409
|
case routes.RouteLocation.Analysis_CostPerPiece:
|
|
375
410
|
page = _jsx(CostPerPiecePage, {});
|
|
376
411
|
nav1 = AnalysisSelectToolbar;
|
|
377
|
-
menuNavItems =
|
|
412
|
+
menuNavItems = analysisMenuNavItems;
|
|
378
413
|
showAlarms = false;
|
|
379
414
|
break;
|
|
380
415
|
case routes.RouteLocation.Operations_Dashboard:
|
|
@@ -114,7 +114,12 @@ export const QRScanButton = memo(function QRScanButton() {
|
|
|
114
114
|
setDialogOpen(false);
|
|
115
115
|
setManual("");
|
|
116
116
|
}
|
|
117
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Dialog, { open: dialogOpen, onClose: () => setDialogOpen(false), children: [_jsx(DialogTitle, { children: "Scan a QR Code" }), _jsxs(DialogContent, { children: [_jsx(Box, {
|
|
117
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Dialog, { open: dialogOpen, onClose: () => setDialogOpen(false), children: [_jsx(DialogTitle, { children: "Scan a QR Code" }), _jsxs(DialogContent, { children: [_jsx(Box, { sx: {
|
|
118
|
+
width: "15em",
|
|
119
|
+
height: "15em",
|
|
120
|
+
}, children: dialogOpen ? _jsx(Scanner, { onScan: onScan }) : undefined }), _jsx(Box, { sx: {
|
|
121
|
+
marginTop: "1em",
|
|
122
|
+
}, children: _jsx(TextField, { label: "Manual Entry", value: manual, variant: "outlined", fullWidth: true, onKeyDown: (e) => {
|
|
118
123
|
if (e.key === "Enter") {
|
|
119
124
|
onManual();
|
|
120
125
|
}
|
|
@@ -142,7 +147,12 @@ export const AddByBarcodeDialog = memo(function AddByBarcodeDialog() {
|
|
|
142
147
|
setManual("");
|
|
143
148
|
}
|
|
144
149
|
return (_jsxs(Dialog, { open: queue !== null, onClose: () => setQueue(null), maxWidth: "md", children: [_jsxs(DialogTitle, { children: ["Scan a Barcode To Add To ", queue] }), _jsxs(DialogContent, { children: [window.location.protocol === "https:" ||
|
|
145
|
-
(import.meta.env.DEV && window.location.hostname === "localhost") ? (_jsx(Box, {
|
|
150
|
+
(import.meta.env.DEV && window.location.hostname === "localhost") ? (_jsx(Box, { sx: {
|
|
151
|
+
width: "15em",
|
|
152
|
+
height: "15em",
|
|
153
|
+
}, children: queue !== null ? _jsx(Scanner, { onScan: onScan }) : undefined })) : undefined, _jsx(Box, { sx: {
|
|
154
|
+
marginTop: "1em",
|
|
155
|
+
}, children: _jsx(TextField, { label: "Manual Entry", value: manual, variant: "outlined", fullWidth: true, onKeyDown: (e) => {
|
|
146
156
|
if (e.key === "Enter") {
|
|
147
157
|
onManual();
|
|
148
158
|
}
|
|
@@ -37,6 +37,15 @@ import { Card } from "@mui/material";
|
|
|
37
37
|
import { CardContent } from "@mui/material";
|
|
38
38
|
import { ErrorBoundary } from "react-error-boundary";
|
|
39
39
|
import { ApiException } from "../network/api.js";
|
|
40
|
+
function displayUnknownError(error) {
|
|
41
|
+
if (typeof error === "string") {
|
|
42
|
+
return error;
|
|
43
|
+
}
|
|
44
|
+
if (typeof error === "number" || typeof error === "boolean" || typeof error === "bigint") {
|
|
45
|
+
return error.toString();
|
|
46
|
+
}
|
|
47
|
+
return JSON.stringify(error) ?? "";
|
|
48
|
+
}
|
|
40
49
|
export function Loading() {
|
|
41
50
|
return (_jsxs("div", { style: { textAlign: "center", marginTop: "4em" }, children: [_jsx(CircularProgress, {}), _jsx("p", { children: "Loading" })] }));
|
|
42
51
|
}
|
|
@@ -50,7 +59,7 @@ export function DisplayError({ error }) {
|
|
|
50
59
|
return (_jsx(Card, { children: _jsx(CardContent, { children: error.message }) }));
|
|
51
60
|
}
|
|
52
61
|
else {
|
|
53
|
-
return (_jsx(Card, { children: _jsxs(CardContent, { children: [_jsx("h3", { children: "Unknown Error" }), _jsx("p", { children:
|
|
62
|
+
return (_jsx(Card, { children: _jsxs(CardContent, { children: [_jsx("h3", { children: "Unknown Error" }), _jsx("p", { children: displayUnknownError(error) })] }) }));
|
|
54
63
|
}
|
|
55
64
|
}
|
|
56
65
|
export function DisplayLoadingAndError(props) {
|
|
@@ -7,7 +7,6 @@ export interface LogEntryProps {
|
|
|
7
7
|
}
|
|
8
8
|
export declare function isLogEntryInvalidated(e: api.ILogEntry): boolean;
|
|
9
9
|
export declare const LogEntry: import("react").MemoExoticComponent<(props: LogEntryProps) => import("react/jsx-runtime").JSX.Element>;
|
|
10
|
-
export declare function filterRemoveAddQueue(entries: Iterable<Readonly<api.ILogEntry>>): Iterable<Readonly<api.ILogEntry>>;
|
|
11
10
|
export interface LogEntriesProps {
|
|
12
11
|
entries: Iterable<Readonly<api.ILogEntry>>;
|
|
13
12
|
copyToClipboard?: boolean;
|
|
@@ -44,6 +44,10 @@ import { ChevronRight as ChevronRightIcon, ImportExport } from "@mui/icons-mater
|
|
|
44
44
|
import { copyLogEntriesToClipboard } from "../data/results.cycles.js";
|
|
45
45
|
import { durationToMinutes, durationToSeconds } from "../util/parseISODuration.js";
|
|
46
46
|
import { LazySeq } from "@seedtactics/immutable-collections";
|
|
47
|
+
import { useAtomValue } from "jotai";
|
|
48
|
+
import { fmsInformation } from "../network/server-settings.js";
|
|
49
|
+
import { basketDisplayName, loadStationDisplayName } from "../cell-status/station-cycles.js";
|
|
50
|
+
import { filterRemoveAddQueue } from "./log-entry-queue-filter.js";
|
|
47
51
|
const ColoredSpan = styled("span", { shouldForwardProp: (prop) => prop.toString()[0] !== "$" })(({ $type }) => {
|
|
48
52
|
switch ($type) {
|
|
49
53
|
case "machine":
|
|
@@ -62,7 +66,8 @@ const ColoredSpan = styled("span", { shouldForwardProp: (prop) => prop.toString(
|
|
|
62
66
|
return { color: "red" };
|
|
63
67
|
}
|
|
64
68
|
});
|
|
65
|
-
function logType(entry) {
|
|
69
|
+
function logType(entry, fmsInfo) {
|
|
70
|
+
const basketName = basketDisplayName(fmsInfo.basketName);
|
|
66
71
|
switch (entry.type) {
|
|
67
72
|
case api.LogType.LoadUnloadCycle:
|
|
68
73
|
if (entry.startofcycle) {
|
|
@@ -71,6 +76,22 @@ function logType(entry) {
|
|
|
71
76
|
else {
|
|
72
77
|
return "End " + entry.result.charAt(0).toUpperCase() + entry.result.substring(1).toLowerCase();
|
|
73
78
|
}
|
|
79
|
+
case api.LogType.BasketLoadUnload:
|
|
80
|
+
if (entry.program === "LOAD") {
|
|
81
|
+
return `${basketName} Load`;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return `${basketName} Unload`;
|
|
85
|
+
}
|
|
86
|
+
case api.LogType.BasketCycle:
|
|
87
|
+
return `${basketName} Cycle`;
|
|
88
|
+
case api.LogType.BasketInLocation:
|
|
89
|
+
if (entry.startofcycle) {
|
|
90
|
+
return "Depart";
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
return "Arrive";
|
|
94
|
+
}
|
|
74
95
|
case api.LogType.MachineCycle:
|
|
75
96
|
if (entry.startofcycle) {
|
|
76
97
|
return "Start Cycle";
|
|
@@ -133,7 +154,7 @@ function displayMat(mats) {
|
|
|
133
154
|
}
|
|
134
155
|
else if (mats.length == 1) {
|
|
135
156
|
if (mats[0].numproc == 1) {
|
|
136
|
-
return
|
|
157
|
+
return mats[0].part;
|
|
137
158
|
}
|
|
138
159
|
else {
|
|
139
160
|
return `${mats[0].part}-${mats[0].proc}`;
|
|
@@ -154,11 +175,33 @@ function displayQueueMat(mats) {
|
|
|
154
175
|
return "";
|
|
155
176
|
}
|
|
156
177
|
}
|
|
157
|
-
function display(props) {
|
|
178
|
+
function display(props, fmsInfo) {
|
|
158
179
|
const entry = props.entry;
|
|
159
180
|
switch (entry.type) {
|
|
160
181
|
case api.LogType.LoadUnloadCycle:
|
|
161
|
-
return (_jsxs("span", { children: [displayMat(entry.material), " on ", _jsxs(ColoredSpan, { "$type": "pallet", children: ["pallet ", entry.pal] }), " at", " ",
|
|
182
|
+
return (_jsxs("span", { children: [displayMat(entry.material), " on ", _jsxs(ColoredSpan, { "$type": "pallet", children: ["pallet ", entry.pal] }), " at", " ", _jsx(ColoredSpan, { "$type": "loadStation", children: loadStationDisplayName(entry.locnum, fmsInfo.loadStationNames) })] }));
|
|
183
|
+
case api.LogType.BasketLoadUnload: {
|
|
184
|
+
const basketName = basketDisplayName(fmsInfo.basketName);
|
|
185
|
+
return (_jsxs("span", { children: [displayMat(entry.material), " ", entry.program === "LOAD" ? "loaded onto" : "unloaded from", " ", _jsxs(ColoredSpan, { "$type": "pallet", children: [basketName, " ", entry.pal] }), " ", "at", " ", _jsx(ColoredSpan, { "$type": "loadStation", children: loadStationDisplayName(entry.locnum, fmsInfo.loadStationNames) })] }));
|
|
186
|
+
}
|
|
187
|
+
case api.LogType.BasketCycle: {
|
|
188
|
+
const basketName = basketDisplayName(fmsInfo.basketName);
|
|
189
|
+
if (entry.startofcycle) {
|
|
190
|
+
return (_jsxs("span", { children: [basketName, " ", entry.pal, " started cycle"] }));
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
return (_jsxs("span", { children: [basketName, " ", entry.pal, " completed cycle"] }));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
case api.LogType.BasketInLocation: {
|
|
197
|
+
const basketName = basketDisplayName(fmsInfo.basketName);
|
|
198
|
+
if (entry.startofcycle) {
|
|
199
|
+
return (_jsxs("span", { children: [basketName, " ", entry.pal, " departed from ", entry.loc, entry.locnum > 0 ? ` position ${entry.locnum}` : ""] }));
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
return (_jsxs("span", { children: [basketName, " ", entry.pal, " arrived at ", entry.loc, entry.locnum > 0 ? ` position ${entry.locnum}` : ""] }));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
162
205
|
case api.LogType.MachineCycle:
|
|
163
206
|
return (_jsxs("span", { children: [displayMat(entry.material), " on ", _jsxs(ColoredSpan, { "$type": "pallet", children: ["pallet ", entry.pal] }), " at", " ", _jsxs(ColoredSpan, { "$type": "machine", children: [entry.loc, " ", entry.locnum.toString()] }), entry.program && entry.program !== "" ? _jsxs("span", { children: [" with program ", entry.program] }) : undefined] }));
|
|
164
207
|
case api.LogType.PartMark:
|
|
@@ -312,6 +355,7 @@ const logTypesToHighlight = [
|
|
|
312
355
|
api.LogType.AddToQueue,
|
|
313
356
|
api.LogType.RemoveFromQueue,
|
|
314
357
|
api.LogType.LoadUnloadCycle,
|
|
358
|
+
api.LogType.BasketLoadUnload,
|
|
315
359
|
api.LogType.MachineCycle,
|
|
316
360
|
];
|
|
317
361
|
const LogEntryTableRow = styled(TableRow, { shouldForwardProp: (prop) => prop.toString()[0] !== "$" })(({ $highlightProc, $invalidCycle }) => ({
|
|
@@ -321,6 +365,7 @@ const LogEntryTableRow = styled(TableRow, { shouldForwardProp: (prop) => prop.to
|
|
|
321
365
|
export const LogEntry = memo(function LogEntry(props) {
|
|
322
366
|
const details = detailsForEntry(props.entry);
|
|
323
367
|
const highlight = props.highlightProcsGreaterOrEqualTo;
|
|
368
|
+
const fmsInfo = useAtomValue(fmsInformation);
|
|
324
369
|
return (_jsxs(_Fragment, { children: [_jsxs(LogEntryTableRow, { "$highlightProc": highlight !== undefined &&
|
|
325
370
|
props.entry.material.findIndex((m) => m.proc >= highlight) >= 0 &&
|
|
326
371
|
logTypesToHighlight.indexOf(props.entry.type) >= 0, "$invalidCycle": isLogEntryInvalidated(props.entry), children: [_jsx(TableCell, { size: "small", children: props.entry.endUTC.toLocaleDateString(undefined, {
|
|
@@ -330,7 +375,7 @@ export const LogEntry = memo(function LogEntry(props) {
|
|
|
330
375
|
}) }), _jsx(TableCell, { size: "small", children: props.entry.endUTC.toLocaleTimeString(undefined, {
|
|
331
376
|
hour: "numeric",
|
|
332
377
|
minute: "2-digit",
|
|
333
|
-
}) }), _jsx(TableCell, { size: "small", children: logType(props.entry) }), _jsx(TableCell, { size: "small", children: display(props) }), _jsx(TableCell, { padding: "checkbox", children: details.length > 0 ? (_jsx(IconButton, { style: {
|
|
378
|
+
}) }), _jsx(TableCell, { size: "small", children: logType(props.entry, fmsInfo) }), _jsx(TableCell, { size: "small", children: display(props, fmsInfo) }), _jsx(TableCell, { padding: "checkbox", children: details.length > 0 ? (_jsx(IconButton, { style: {
|
|
334
379
|
transition: "all ease 200ms",
|
|
335
380
|
transform: props.entry.counter === props.detailLogCounter ? "rotate(90deg)" : "none",
|
|
336
381
|
}, onClick: (event) => {
|
|
@@ -338,27 +383,6 @@ export const LogEntry = memo(function LogEntry(props) {
|
|
|
338
383
|
event.stopPropagation();
|
|
339
384
|
}, size: "small", children: _jsx(ChevronRightIcon, { fontSize: "inherit" }) })) : undefined })] }), details.length > 0 && props.entry.counter === props.detailLogCounter ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 5, children: _jsx("ul", { children: details.map((d, idx) => (_jsxs("li", { children: [d.name, ": ", d.value] }, idx))) }) }) })) : undefined] }));
|
|
340
385
|
});
|
|
341
|
-
export function* filterRemoveAddQueue(entries) {
|
|
342
|
-
let prev = null;
|
|
343
|
-
for (const e of entries) {
|
|
344
|
-
if (prev != null &&
|
|
345
|
-
prev.type === api.LogType.RemoveFromQueue &&
|
|
346
|
-
e.type === api.LogType.AddToQueue &&
|
|
347
|
-
prev.loc === e.loc) {
|
|
348
|
-
// skip both prev and e
|
|
349
|
-
prev = null;
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
if (prev !== null) {
|
|
353
|
-
yield prev;
|
|
354
|
-
}
|
|
355
|
-
prev = e;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
if (prev !== null) {
|
|
359
|
-
yield prev;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
386
|
export const LogEntries = memo(function LogEntriesF(props) {
|
|
363
387
|
const [curDetail, setDetail] = useState(null);
|
|
364
388
|
return (_jsxs(Table, { children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableCell, { children: "Date" }), _jsx(TableCell, { children: "Time" }), _jsx(TableCell, { children: "Type" }), _jsx(TableCell, { children: "Details" }), _jsx(TableCell, { padding: "checkbox", children: props.copyToClipboard ? (_jsx(Tooltip, { title: "Copy to Clipboard", children: _jsx(IconButton, { onClick: () => copyLogEntriesToClipboard(props.entries), style: { height: "25px", paddingTop: 0, paddingBottom: 0 }, size: "large", children: _jsx(ImportExport, {}) }) })) : undefined })] }) }), _jsx(TableBody, { children: Array.from(filterRemoveAddQueue(props.entries)).map((e, idx) => (_jsx(LogEntry, { entry: e, detailLogCounter: curDetail, setDetail: setDetail, highlightProcsGreaterOrEqualTo: props.highlightProcsGreaterOrEqualTo }, idx))) })] }));
|