@seedtactics/insight-client 16.5.2 → 16.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
@@ -31,27 +31,35 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
31
31
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
32
32
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
33
33
|
*/
|
|
34
|
-
import { memo, useState } from "react";
|
|
34
|
+
import { memo, useMemo, useState } from "react";
|
|
35
35
|
import { closestCenter, DndContext, DragOverlay, KeyboardSensor, PointerSensor, useSensor, useSensors, } from "@dnd-kit/core";
|
|
36
36
|
import { rectSortingStrategy, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, } from "@dnd-kit/sortable";
|
|
37
37
|
import { useAddExistingMaterialToQueue } from "../../cell-status/material-details.js";
|
|
38
38
|
import { reorderQueuedMatInCurrentStatus } from "../../cell-status/current-status.js";
|
|
39
39
|
import { currentOperator } from "../../data/operators.js";
|
|
40
40
|
import { useAtomValue, useSetAtom } from "jotai";
|
|
41
|
+
function isSortableMatData(value) {
|
|
42
|
+
return typeof value === "object" && value !== null && "mat" in value;
|
|
43
|
+
}
|
|
44
|
+
function numericId(id) {
|
|
45
|
+
return typeof id === "number" ? id : null;
|
|
46
|
+
}
|
|
41
47
|
export const SortableRegion = memo(function SortableRegion(props) {
|
|
42
48
|
const [activeMat, setActiveMat] = useState(undefined);
|
|
43
49
|
const [addExistingMatToQueue] = useAddExistingMaterialToQueue();
|
|
44
50
|
const reorderQueuedMat = useSetAtom(reorderQueuedMatInCurrentStatus);
|
|
45
51
|
const operator = useAtomValue(currentOperator);
|
|
52
|
+
const sortableItemIds = useMemo(() => props.matIds.slice(), [props.matIds]);
|
|
46
53
|
const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, {
|
|
47
54
|
coordinateGetter: sortableKeyboardCoordinates,
|
|
48
55
|
}));
|
|
49
|
-
return (_jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragStart: ({ active }) => setActiveMat(active.data.current.mat), onDragCancel: () => setActiveMat(undefined), onDragEnd: ({ active, over }) => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
return (_jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragStart: ({ active }) => setActiveMat(isSortableMatData(active.data.current) ? active.data.current.mat : undefined), onDragCancel: () => setActiveMat(undefined), onDragEnd: ({ active, over }) => {
|
|
57
|
+
const activeMatId = numericId(active.id);
|
|
58
|
+
const overMatId = over ? numericId(over.id) : null;
|
|
59
|
+
if (over && active.id !== over.id && activeMatId !== null && overMatId !== null) {
|
|
60
|
+
const overIdx = props.matIds.indexOf(overMatId);
|
|
53
61
|
addExistingMatToQueue({
|
|
54
|
-
materialId:
|
|
62
|
+
materialId: activeMatId,
|
|
55
63
|
queue: props.queueName,
|
|
56
64
|
queuePosition: overIdx,
|
|
57
65
|
operator: operator,
|
|
@@ -63,5 +71,5 @@ export const SortableRegion = memo(function SortableRegion(props) {
|
|
|
63
71
|
});
|
|
64
72
|
}
|
|
65
73
|
setActiveMat(undefined);
|
|
66
|
-
}, children: _jsxs(SortableContext, { items:
|
|
74
|
+
}, children: _jsxs(SortableContext, { items: sortableItemIds, strategy: props.direction === "vertical" ? verticalListSortingStrategy : rectSortingStrategy, children: [props.children, _jsx(DragOverlay, { children: activeMat !== undefined ? props.renderDragOverlay(activeMat) : undefined })] }) }));
|
|
67
75
|
});
|
|
@@ -4,6 +4,7 @@ export type MaterialBinId = string;
|
|
|
4
4
|
export declare const LoadStationBinId: MaterialBinId;
|
|
5
5
|
export declare const PalletsBinId: MaterialBinId;
|
|
6
6
|
export declare const ActiveQueuesBinId: MaterialBinId;
|
|
7
|
+
export declare const BasketsBinId: MaterialBinId;
|
|
7
8
|
export interface MaterialBinState {
|
|
8
9
|
readonly curBinOrder: ReadonlyArray<MaterialBinId>;
|
|
9
10
|
}
|
|
@@ -13,6 +14,7 @@ export declare enum MaterialBinType {
|
|
|
13
14
|
LoadStations = "Bin_LoadStations",
|
|
14
15
|
Pallets = "Bin_Pallets",
|
|
15
16
|
ActiveQueues = "Bin_ActiveQueues",
|
|
17
|
+
Baskets = "Bin_Baskets",
|
|
16
18
|
QuarantineQueues = "Bin_Quarantine"
|
|
17
19
|
}
|
|
18
20
|
export type MaterialBin = {
|
|
@@ -27,6 +29,11 @@ export type MaterialBin = {
|
|
|
27
29
|
readonly type: MaterialBinType.ActiveQueues;
|
|
28
30
|
readonly binId: MaterialBinId;
|
|
29
31
|
readonly byQueue: ReadonlyMap<string, MaterialList>;
|
|
32
|
+
} | {
|
|
33
|
+
readonly type: MaterialBinType.Baskets;
|
|
34
|
+
readonly binId: MaterialBinId;
|
|
35
|
+
readonly byBasket: ReadonlyMap<number, MaterialList>;
|
|
36
|
+
readonly basketLocations: ReadonlyMap<number, string>;
|
|
30
37
|
} | {
|
|
31
38
|
readonly type: MaterialBinType.QuarantineQueues;
|
|
32
39
|
readonly binId: MaterialBinId;
|
|
@@ -36,6 +36,7 @@ import { atomWithStorage } from "jotai/utils";
|
|
|
36
36
|
export const LoadStationBinId = "__FMS_INSIGHT_LOAD_STATION_BIN__";
|
|
37
37
|
export const PalletsBinId = "__FMS_INSIGHT_PALLETS_BIN__";
|
|
38
38
|
export const ActiveQueuesBinId = "__FMS_INSIGHT_ACTIVE_QUEUE_BIN__";
|
|
39
|
+
export const BasketsBinId = "__FMS_INSIGHT_BASKETS_BIN__";
|
|
39
40
|
export const currentMaterialBinOrder = atomWithStorage("material-bins", []);
|
|
40
41
|
export function moveMaterialBin(curBinOrder, oldIdx, newIdx) {
|
|
41
42
|
const newBinOrder = Array.from(curBinOrder);
|
|
@@ -57,12 +58,27 @@ export var MaterialBinType;
|
|
|
57
58
|
MaterialBinType["LoadStations"] = "Bin_LoadStations";
|
|
58
59
|
MaterialBinType["Pallets"] = "Bin_Pallets";
|
|
59
60
|
MaterialBinType["ActiveQueues"] = "Bin_ActiveQueues";
|
|
61
|
+
MaterialBinType["Baskets"] = "Bin_Baskets";
|
|
60
62
|
MaterialBinType["QuarantineQueues"] = "Bin_Quarantine";
|
|
61
63
|
})(MaterialBinType || (MaterialBinType = {}));
|
|
64
|
+
function basketLocation(st) {
|
|
65
|
+
let loc;
|
|
66
|
+
if (st.locationTitle && st.locationTitle.length > 0) {
|
|
67
|
+
loc = st.locationTitle;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
loc = st.location + " " + st.locationNum.toString();
|
|
71
|
+
}
|
|
72
|
+
if (st.slot) {
|
|
73
|
+
loc += `-${st.slot}`;
|
|
74
|
+
}
|
|
75
|
+
return loc;
|
|
76
|
+
}
|
|
62
77
|
export function selectAllMaterialIntoBins(curSt, curBinOrder) {
|
|
63
78
|
const loadStations = new Map();
|
|
64
79
|
const pallets = new Map();
|
|
65
80
|
const queues = new Map();
|
|
81
|
+
const baskets = new Map();
|
|
66
82
|
const palLoc = LazySeq.ofObject(curSt.pallets).toRMap(([, st]) => [
|
|
67
83
|
st.palletNum,
|
|
68
84
|
st.palletNum.toString() +
|
|
@@ -115,6 +131,11 @@ export function selectAllMaterialIntoBins(curSt, curBinOrder) {
|
|
|
115
131
|
break;
|
|
116
132
|
}
|
|
117
133
|
break;
|
|
134
|
+
case api.LocType.InBasket:
|
|
135
|
+
if (mat.location.basketId !== undefined) {
|
|
136
|
+
addToMap(baskets, mat.location.basketId, mat);
|
|
137
|
+
}
|
|
138
|
+
break;
|
|
118
139
|
}
|
|
119
140
|
}
|
|
120
141
|
const activeQueues = LazySeq.ofObject(curSt.jobs)
|
|
@@ -135,10 +156,17 @@ export function selectAllMaterialIntoBins(curSt, curBinOrder) {
|
|
|
135
156
|
const quarantineQueues = LazySeq.ofObject(curSt.queues)
|
|
136
157
|
.filter(([qname, _]) => !activeQueues.has(qname))
|
|
137
158
|
.toRSet(([qname, _]) => qname);
|
|
138
|
-
const bins = curBinOrder.filter((b) => b === LoadStationBinId ||
|
|
159
|
+
const bins = curBinOrder.filter((b) => b === LoadStationBinId ||
|
|
160
|
+
b === PalletsBinId ||
|
|
161
|
+
b === ActiveQueuesBinId ||
|
|
162
|
+
b === BasketsBinId ||
|
|
163
|
+
quarantineQueues.has(b));
|
|
139
164
|
if (bins.indexOf(ActiveQueuesBinId) < 0) {
|
|
140
165
|
bins.unshift(ActiveQueuesBinId);
|
|
141
166
|
}
|
|
167
|
+
if (baskets.size > 0 && bins.indexOf(BasketsBinId) < 0) {
|
|
168
|
+
bins.unshift(BasketsBinId);
|
|
169
|
+
}
|
|
142
170
|
if (bins.indexOf(PalletsBinId) < 0) {
|
|
143
171
|
bins.unshift(PalletsBinId);
|
|
144
172
|
}
|
|
@@ -168,6 +196,24 @@ export function selectAllMaterialIntoBins(curSt, curBinOrder) {
|
|
|
168
196
|
}, (ms1, ms2) => ms1.concat(ms2)),
|
|
169
197
|
};
|
|
170
198
|
}
|
|
199
|
+
else if (binId === BasketsBinId) {
|
|
200
|
+
return {
|
|
201
|
+
type: MaterialBinType.Baskets,
|
|
202
|
+
binId: BasketsBinId,
|
|
203
|
+
byBasket: new Map(baskets),
|
|
204
|
+
basketLocations: LazySeq.ofObject(curSt.baskets ?? {})
|
|
205
|
+
.collect(([id, st]) => {
|
|
206
|
+
const basketId = parseInt(id);
|
|
207
|
+
if (basketId > 0) {
|
|
208
|
+
return [parseInt(id), basketLocation(st)];
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
.toRMap((x) => x),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
171
217
|
else {
|
|
172
218
|
const queueName = binId;
|
|
173
219
|
const mat = queues.get(queueName) ?? [];
|
|
@@ -32,9 +32,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
32
32
|
*/
|
|
33
33
|
import { addMonths, getDaysInMonth, addDays } from "date-fns";
|
|
34
34
|
import copy from "copy-to-clipboard";
|
|
35
|
+
import { isLaborCycle, isMachineCycle, isPalletLoadCycle, } from "../cell-status/station-cycles.js";
|
|
35
36
|
import { LazySeq } from "@seedtactics/immutable-collections";
|
|
36
37
|
function isUnloadCycle(c) {
|
|
37
|
-
return c
|
|
38
|
+
return isPalletLoadCycle(c) && c.operation === "UNLOAD";
|
|
38
39
|
}
|
|
39
40
|
function isMonthType(type) {
|
|
40
41
|
return Object.prototype.hasOwnProperty.call(type, "month");
|
|
@@ -51,10 +52,10 @@ export function compute_monthly_cost_percentages(cycles, partsToIgnore, matsById
|
|
|
51
52
|
if (isUnloadCycle(c)) {
|
|
52
53
|
totalPalletCycles += 1;
|
|
53
54
|
}
|
|
54
|
-
if (c
|
|
55
|
+
if (isLaborCycle(c)) {
|
|
55
56
|
totalLaborUseMinutes += c.activeMinutes;
|
|
56
57
|
}
|
|
57
|
-
else {
|
|
58
|
+
else if (isMachineCycle(c)) {
|
|
58
59
|
totalStatUseMinutes.set(c.stationGroup, c.activeMinutes + (totalStatUseMinutes.get(c.stationGroup) ?? 0));
|
|
59
60
|
const s = stationCount.get(c.stationGroup);
|
|
60
61
|
if (s) {
|
|
@@ -81,16 +82,18 @@ export function compute_monthly_cost_percentages(cycles, partsToIgnore, matsById
|
|
|
81
82
|
part: partName,
|
|
82
83
|
parts_completed: completed.get(partName) ?? 0,
|
|
83
84
|
machine: LazySeq.of(forPart)
|
|
84
|
-
.filter((c) =>
|
|
85
|
+
.filter((c) => isMachineCycle(c))
|
|
85
86
|
.buildOrderedMap((c) => c.stationGroup, (old, c) => (old ?? 0) + c.activeMinutes)
|
|
86
87
|
.mapValues((minutes, statGroup) => {
|
|
87
88
|
const totalUse = totalStatUseMinutes.get(statGroup) ?? 1;
|
|
88
89
|
return minutes / totalUse;
|
|
89
90
|
}),
|
|
90
91
|
labor: LazySeq.of(forPart)
|
|
91
|
-
.filter((c) => c
|
|
92
|
+
.filter((c) => isLaborCycle(c))
|
|
92
93
|
.sumBy((c) => c.activeMinutes / totalLaborUseMinutes),
|
|
93
|
-
automation:
|
|
94
|
+
automation: totalPalletCycles > 0
|
|
95
|
+
? forPart.reduce((acc, v) => (isUnloadCycle(v) ? acc + 1 : acc), 0) / totalPalletCycles
|
|
96
|
+
: 0,
|
|
94
97
|
}))
|
|
95
98
|
.toRArray();
|
|
96
99
|
const machineQuantities = LazySeq.of(stationCount).toOrderedMap(([statGroup, nums]) => [
|
|
@@ -147,7 +150,7 @@ export function buildCostPerPieceTable(costs) {
|
|
|
147
150
|
return table;
|
|
148
151
|
}
|
|
149
152
|
export function copyCostPerPieceToClipboard(costs) {
|
|
150
|
-
copy(buildCostPerPieceTable(costs));
|
|
153
|
+
void copy(buildCostPerPieceTable(costs));
|
|
151
154
|
}
|
|
152
155
|
export function buildCostBreakdownTable(costs) {
|
|
153
156
|
let table = "<table>\n<thead><tr>";
|
|
@@ -179,5 +182,5 @@ export function buildCostBreakdownTable(costs) {
|
|
|
179
182
|
return table;
|
|
180
183
|
}
|
|
181
184
|
export function copyCostBreakdownToClipboard(costs) {
|
|
182
|
-
copy(buildCostBreakdownTable(costs));
|
|
185
|
+
void copy(buildCostBreakdownTable(costs));
|
|
183
186
|
}
|
|
@@ -10,4 +10,4 @@ export type CurrentCycle = {
|
|
|
10
10
|
readonly oper: string;
|
|
11
11
|
}>;
|
|
12
12
|
};
|
|
13
|
-
export declare function currentCycles(currentSt: ICurrentStatus, estimated: EstimatedCycleTimes): ReadonlyArray<CurrentCycle>;
|
|
13
|
+
export declare function currentCycles(currentSt: ICurrentStatus, estimated: EstimatedCycleTimes, loadStationNames?: Readonly<Record<string, string>>): ReadonlyArray<CurrentCycle>;
|
|
@@ -33,10 +33,51 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
33
33
|
import { LazySeq } from "@seedtactics/immutable-collections";
|
|
34
34
|
import { addSeconds } from "date-fns";
|
|
35
35
|
import { isOutlierAbove, PartAndStationOperation, splitElapsedTimeAmongChunk, } from "../cell-status/estimated-cycle-times.js";
|
|
36
|
-
import {
|
|
37
|
-
import { ActionType } from "../network/api.js";
|
|
36
|
+
import { displayStationName } from "../cell-status/station-cycles.js";
|
|
37
|
+
import { ActionType, BasketLocationEnum } from "../network/api.js";
|
|
38
38
|
import { durationToMinutes, durationToSeconds } from "../util/parseISODuration.js";
|
|
39
|
-
function
|
|
39
|
+
function basketsAtLoad(currentSt) {
|
|
40
|
+
return LazySeq.ofObject(currentSt.baskets ?? {})
|
|
41
|
+
.collect(([, basket]) => {
|
|
42
|
+
if (basket.location === BasketLocationEnum.LoadUnload ||
|
|
43
|
+
basket.location === BasketLocationEnum.LoadStationStaging) {
|
|
44
|
+
return [basket.basketId, { group: "L/U", num: basket.locationNum }];
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
})
|
|
48
|
+
.toRMap(([basketId, loc]) => [basketId, loc]);
|
|
49
|
+
}
|
|
50
|
+
function locationForLoadActivity(material, jobs, palToLoc, basketToLoad) {
|
|
51
|
+
if (material.action.type === ActionType.Loading) {
|
|
52
|
+
if (material.action.loadOntoPalletNum) {
|
|
53
|
+
return palToLoc.get(material.action.loadOntoPalletNum) ?? null;
|
|
54
|
+
}
|
|
55
|
+
if (material.action.loadFromBasketId) {
|
|
56
|
+
return basketToLoad.get(material.action.loadFromBasketId) ?? null;
|
|
57
|
+
}
|
|
58
|
+
// queue → basket: neither pallet nor source basket set. Find a basket at a load station
|
|
59
|
+
// that is a basket-load station for this job/process.
|
|
60
|
+
const proc = material.action.processAfterLoad ?? material.process;
|
|
61
|
+
const procInfo = jobs[material.jobUnique]?.procsAndPaths?.[proc - 1];
|
|
62
|
+
const basketLoadStations = procInfo?.basketLoadStations ?? [];
|
|
63
|
+
for (const [, loc] of basketToLoad) {
|
|
64
|
+
if (basketLoadStations.length === 0 || basketLoadStations.includes(loc.num)) {
|
|
65
|
+
return loc;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
if (material.location.palletNum) {
|
|
72
|
+
return palToLoc.get(material.location.palletNum) ?? null;
|
|
73
|
+
}
|
|
74
|
+
if (material.location.basketId) {
|
|
75
|
+
return basketToLoad.get(material.location.basketId) ?? null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
function machiningCurrentCycles(currentSt, estimated, palToLoc, loadStationNames) {
|
|
40
81
|
return LazySeq.of(currentSt.material)
|
|
41
82
|
.collect((m) => {
|
|
42
83
|
if (m.action.type !== ActionType.Machining)
|
|
@@ -55,7 +96,7 @@ function machiningCurrentCycles(currentSt, estimated, palToLoc) {
|
|
|
55
96
|
const elapsedSec = durationToSeconds(mats[0].mat.action.elapsedMachiningTime ?? "PT0S");
|
|
56
97
|
const remainingSec = durationToSeconds(mats[0].mat.action.expectedRemainingMachiningTime ?? "PT0S");
|
|
57
98
|
return {
|
|
58
|
-
station:
|
|
99
|
+
station: displayStationName(statGroup, statNum, loadStationNames),
|
|
59
100
|
start: addSeconds(currentSt.timeOfCurrentStatusUTC, -elapsedSec),
|
|
60
101
|
expectedEnd: addSeconds(currentSt.timeOfCurrentStatusUTC, remainingSec),
|
|
61
102
|
isOutlier: stats ? isOutlierAbove(stats, elapsedSec / 60 / mats.length) : false,
|
|
@@ -63,22 +104,19 @@ function machiningCurrentCycles(currentSt, estimated, palToLoc) {
|
|
|
63
104
|
};
|
|
64
105
|
});
|
|
65
106
|
}
|
|
66
|
-
function loadCurrentCycles(currentSt, estimated, palToLoc) {
|
|
107
|
+
function loadCurrentCycles(currentSt, estimated, palToLoc, loadStationNames) {
|
|
108
|
+
const basketToLoad = basketsAtLoad(currentSt);
|
|
67
109
|
return LazySeq.of(currentSt.material)
|
|
68
110
|
.collect((m) => {
|
|
69
111
|
if (m.action.type === ActionType.UnloadToCompletedMaterial ||
|
|
70
112
|
m.action.type === ActionType.UnloadToInProcess) {
|
|
71
|
-
|
|
72
|
-
return null;
|
|
73
|
-
const loc = palToLoc.get(m.location.palletNum);
|
|
113
|
+
const loc = locationForLoadActivity(m, currentSt.jobs, palToLoc, basketToLoad);
|
|
74
114
|
if (!loc)
|
|
75
115
|
return null;
|
|
76
116
|
return { mat: m, material: [m], proc: m.process, path: m.path, loc };
|
|
77
117
|
}
|
|
78
118
|
else if (m.action.type === ActionType.Loading) {
|
|
79
|
-
|
|
80
|
-
return null;
|
|
81
|
-
const loc = palToLoc.get(m.action.loadOntoPalletNum);
|
|
119
|
+
const loc = locationForLoadActivity(m, currentSt.jobs, palToLoc, basketToLoad);
|
|
82
120
|
if (!loc)
|
|
83
121
|
return null;
|
|
84
122
|
return {
|
|
@@ -93,12 +131,19 @@ function loadCurrentCycles(currentSt, estimated, palToLoc) {
|
|
|
93
131
|
})
|
|
94
132
|
.map((m) => {
|
|
95
133
|
const job = currentSt.jobs[m.mat.jobUnique];
|
|
134
|
+
const procInfo = job?.procsAndPaths?.[m.proc - 1];
|
|
96
135
|
const pathData = job?.procsAndPaths?.[m.proc - 1]?.paths?.[m.path - 1];
|
|
97
136
|
if (m.mat.action.type === ActionType.Loading) {
|
|
98
|
-
|
|
137
|
+
const expected = m.mat.action.loadOntoPalletNum !== null && m.mat.action.loadOntoPalletNum !== undefined
|
|
138
|
+
? pathData?.expectedLoadTime
|
|
139
|
+
: (procInfo?.expectedBasketLoadTime ?? pathData?.expectedLoadTime);
|
|
140
|
+
return { ...m, expectedLoadSecs: durationToSeconds(expected ?? "PT0S") };
|
|
99
141
|
}
|
|
100
142
|
else {
|
|
101
|
-
|
|
143
|
+
const expected = m.mat.location.palletNum !== null && m.mat.location.palletNum !== undefined
|
|
144
|
+
? pathData?.expectedUnloadTime
|
|
145
|
+
: (procInfo?.expectedBasketUnloadTime ?? pathData?.expectedUnloadTime);
|
|
146
|
+
return { ...m, expectedLoadSecs: durationToSeconds(expected ?? "PT0S") };
|
|
102
147
|
}
|
|
103
148
|
})
|
|
104
149
|
.groupBy(({ loc }) => loc.group, ({ loc }) => loc.num)
|
|
@@ -122,7 +167,7 @@ function loadCurrentCycles(currentSt, estimated, palToLoc) {
|
|
|
122
167
|
}
|
|
123
168
|
const elapsedSec = durationToSeconds(mats[0].mat.action.elapsedLoadUnloadTime ?? "PT0S");
|
|
124
169
|
return {
|
|
125
|
-
station:
|
|
170
|
+
station: displayStationName(statGroup, statNum, loadStationNames),
|
|
126
171
|
start: addSeconds(currentSt.timeOfCurrentStatusUTC, -elapsedSec),
|
|
127
172
|
expectedEnd: addSeconds(currentSt.timeOfCurrentStatusUTC, -elapsedSec + expectedSecs),
|
|
128
173
|
isOutlier: outlier,
|
|
@@ -136,9 +181,9 @@ function loadCurrentCycles(currentSt, estimated, palToLoc) {
|
|
|
136
181
|
};
|
|
137
182
|
});
|
|
138
183
|
}
|
|
139
|
-
export function currentCycles(currentSt, estimated) {
|
|
184
|
+
export function currentCycles(currentSt, estimated, loadStationNames) {
|
|
140
185
|
const palToLoc = LazySeq.ofObject(currentSt.pallets).buildHashMap(([, p]) => p.palletNum, (_old, [, pal]) => pal.currentPalletLocation);
|
|
141
|
-
return machiningCurrentCycles(currentSt, estimated, palToLoc)
|
|
142
|
-
.concat(loadCurrentCycles(currentSt, estimated, palToLoc))
|
|
186
|
+
return machiningCurrentCycles(currentSt, estimated, palToLoc, loadStationNames)
|
|
187
|
+
.concat(loadCurrentCycles(currentSt, estimated, palToLoc, loadStationNames))
|
|
143
188
|
.toRArray();
|
|
144
189
|
}
|
|
@@ -6,7 +6,8 @@ export declare enum MoveMaterialNodeKindType {
|
|
|
6
6
|
CompletedCollapsedMaterialZone = 2,
|
|
7
7
|
CompletedExpandedMaterialZone = 3,
|
|
8
8
|
PalletFaceZone = 4,
|
|
9
|
-
QueueZone = 5
|
|
9
|
+
QueueZone = 5,
|
|
10
|
+
BasketZone = 6
|
|
10
11
|
}
|
|
11
12
|
export type MoveMaterialNodeKind = {
|
|
12
13
|
readonly type: MoveMaterialNodeKindType.Material;
|
|
@@ -23,6 +24,9 @@ export type MoveMaterialNodeKind = {
|
|
|
23
24
|
} | {
|
|
24
25
|
readonly type: MoveMaterialNodeKindType.QueueZone;
|
|
25
26
|
readonly queue: string;
|
|
27
|
+
} | {
|
|
28
|
+
readonly type: MoveMaterialNodeKindType.BasketZone;
|
|
29
|
+
readonly basketId: number;
|
|
26
30
|
};
|
|
27
31
|
export type MoveMaterialIdentifier = string;
|
|
28
32
|
export declare function uniqueIdForNodeKind(kind: MoveMaterialNodeKind): MoveMaterialIdentifier;
|
package/dist/data/move-arrows.js
CHANGED
|
@@ -40,6 +40,7 @@ export var MoveMaterialNodeKindType;
|
|
|
40
40
|
MoveMaterialNodeKindType[MoveMaterialNodeKindType["CompletedExpandedMaterialZone"] = 3] = "CompletedExpandedMaterialZone";
|
|
41
41
|
MoveMaterialNodeKindType[MoveMaterialNodeKindType["PalletFaceZone"] = 4] = "PalletFaceZone";
|
|
42
42
|
MoveMaterialNodeKindType[MoveMaterialNodeKindType["QueueZone"] = 5] = "QueueZone";
|
|
43
|
+
MoveMaterialNodeKindType[MoveMaterialNodeKindType["BasketZone"] = 6] = "BasketZone";
|
|
43
44
|
})(MoveMaterialNodeKindType || (MoveMaterialNodeKindType = {}));
|
|
44
45
|
export function uniqueIdForNodeKind(kind) {
|
|
45
46
|
switch (kind.type) {
|
|
@@ -55,6 +56,8 @@ export function uniqueIdForNodeKind(kind) {
|
|
|
55
56
|
return "PalletFaceZone-" + kind.face.toString();
|
|
56
57
|
case MoveMaterialNodeKindType.QueueZone:
|
|
57
58
|
return "QueueZone-" + kind.queue;
|
|
59
|
+
case MoveMaterialNodeKindType.BasketZone:
|
|
60
|
+
return "BasketZone-" + kind.basketId.toString();
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
export function memoPropsForNodeKind(kind) {
|
|
@@ -69,6 +72,8 @@ export function memoPropsForNodeKind(kind) {
|
|
|
69
72
|
return [kind.type, kind.face];
|
|
70
73
|
case MoveMaterialNodeKindType.QueueZone:
|
|
71
74
|
return [kind.type, kind.queue];
|
|
75
|
+
case MoveMaterialNodeKindType.BasketZone:
|
|
76
|
+
return [kind.type, kind.basketId];
|
|
72
77
|
}
|
|
73
78
|
}
|
|
74
79
|
function groupMatByKind(allNodes) {
|
|
@@ -76,6 +81,7 @@ function groupMatByKind(allNodes) {
|
|
|
76
81
|
let completedMaterial;
|
|
77
82
|
const faces = new Map();
|
|
78
83
|
const queues = new Map();
|
|
84
|
+
const baskets = new Map();
|
|
79
85
|
const material = new Array();
|
|
80
86
|
for (const node of allNodes.values()) {
|
|
81
87
|
switch (node.type) {
|
|
@@ -92,6 +98,9 @@ function groupMatByKind(allNodes) {
|
|
|
92
98
|
case MoveMaterialNodeKindType.QueueZone:
|
|
93
99
|
queues.set(node.queue, node.elem);
|
|
94
100
|
break;
|
|
101
|
+
case MoveMaterialNodeKindType.BasketZone:
|
|
102
|
+
baskets.set(node.basketId, node.elem);
|
|
103
|
+
break;
|
|
95
104
|
case MoveMaterialNodeKindType.Material:
|
|
96
105
|
if (node.material) {
|
|
97
106
|
material.push([node.elem, node.material]);
|
|
@@ -99,7 +108,7 @@ function groupMatByKind(allNodes) {
|
|
|
99
108
|
break;
|
|
100
109
|
}
|
|
101
110
|
}
|
|
102
|
-
return { freeMaterial, completedMaterial, faces, queues, material };
|
|
111
|
+
return { freeMaterial, completedMaterial, faces, queues, baskets, material };
|
|
103
112
|
}
|
|
104
113
|
export function computeArrows(container, allNodes) {
|
|
105
114
|
if (!container) {
|
|
@@ -112,12 +121,25 @@ export function computeArrows(container, allNodes) {
|
|
|
112
121
|
const arrows = [];
|
|
113
122
|
const faceDestUsed = new Map();
|
|
114
123
|
const queueDestUsed = new Map();
|
|
124
|
+
const basketDestUsed = new Map();
|
|
115
125
|
let lastFreeUsed = 0;
|
|
116
|
-
for (const [rect, mat] of LazySeq.of(byKind.material).sortBy(([
|
|
126
|
+
for (const [rect, mat] of LazySeq.of(byKind.material).sortBy(([box]) => box.left, ([box]) => box.top)) {
|
|
117
127
|
switch (mat.action.type) {
|
|
118
128
|
case api.ActionType.UnloadToCompletedMaterial:
|
|
119
129
|
case api.ActionType.UnloadToInProcess:
|
|
120
|
-
if (mat.action.
|
|
130
|
+
if (mat.action.unloadToBasketId) {
|
|
131
|
+
const dest = byKind.baskets.get(mat.action.unloadToBasketId);
|
|
132
|
+
const lastSlotUsed = basketDestUsed.get(mat.action.unloadToBasketId) ?? 0;
|
|
133
|
+
basketDestUsed.set(mat.action.unloadToBasketId, lastSlotUsed + 1);
|
|
134
|
+
arrows.push({
|
|
135
|
+
fromX: rect.left,
|
|
136
|
+
fromY: rect.top + rect.height / 2,
|
|
137
|
+
toX: dest !== undefined ? dest.right - 5 : container.left + 2,
|
|
138
|
+
toY: dest !== undefined ? dest.top + 20 * (lastSlotUsed + 1) : rect.top + rect.height / 2,
|
|
139
|
+
curveDirection: 1,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
else if (mat.action.type === api.ActionType.UnloadToCompletedMaterial &&
|
|
121
143
|
(!mat.action.unloadIntoQueue || mat.action.unloadIntoQueue === "")) {
|
|
122
144
|
arrows.push({
|
|
123
145
|
fromX: rect.right,
|
|
@@ -150,7 +172,35 @@ export function computeArrows(container, allNodes) {
|
|
|
150
172
|
}
|
|
151
173
|
break;
|
|
152
174
|
case api.ActionType.Loading:
|
|
153
|
-
if (mat.action.loadOntoFace) {
|
|
175
|
+
if (mat.action.loadFromBasketId && mat.action.loadOntoFace) {
|
|
176
|
+
// loading from basket onto pallet face
|
|
177
|
+
const face = byKind.faces.get(mat.action.loadOntoFace);
|
|
178
|
+
if (face !== undefined) {
|
|
179
|
+
const faceSpotsUsed = faceDestUsed.get(mat.action.loadOntoFace) ?? 0;
|
|
180
|
+
faceDestUsed.set(mat.action.loadOntoFace, faceSpotsUsed + 1);
|
|
181
|
+
arrows.push({
|
|
182
|
+
fromX: rect.right,
|
|
183
|
+
fromY: rect.top + rect.height / 2,
|
|
184
|
+
toX: face.left + 20,
|
|
185
|
+
toY: face.top + 50 + 20 * faceSpotsUsed,
|
|
186
|
+
curveDirection: -1,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (mat.action.loadFromBasketId) {
|
|
191
|
+
// basket-only load from a queue into the active basket
|
|
192
|
+
const dest = byKind.baskets.get(mat.action.loadFromBasketId);
|
|
193
|
+
const lastSlotUsed = basketDestUsed.get(mat.action.loadFromBasketId) ?? 0;
|
|
194
|
+
basketDestUsed.set(mat.action.loadFromBasketId, lastSlotUsed + 1);
|
|
195
|
+
arrows.push({
|
|
196
|
+
fromX: rect.right,
|
|
197
|
+
fromY: rect.top + rect.height / 2,
|
|
198
|
+
toX: dest !== undefined ? dest.left + 20 : container.right - 10,
|
|
199
|
+
toY: dest !== undefined ? dest.top + 50 + 20 * lastSlotUsed : rect.top + rect.height / 2,
|
|
200
|
+
curveDirection: -1,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
else if (mat.action.loadOntoFace) {
|
|
154
204
|
if (mat.location.type === api.LocType.OnPallet) {
|
|
155
205
|
if (mat.location.palletNum === mat.action.loadOntoPalletNum &&
|
|
156
206
|
mat.location.face === mat.action.loadOntoFace) {
|
|
@@ -33,12 +33,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
33
33
|
import { LazySeq, OrderedMap, OrderedSet } from "@seedtactics/immutable-collections";
|
|
34
34
|
import { last30MaterialSummary } from "../cell-status/material-summary";
|
|
35
35
|
import { atom } from "jotai";
|
|
36
|
-
import { last30StationCycles } from "../cell-status/station-cycles";
|
|
36
|
+
import { isLaborCycle, last30StationCycles } from "../cell-status/station-cycles";
|
|
37
37
|
import { chartRangeAtom } from "./chart-times";
|
|
38
38
|
function isAbnormal(m) {
|
|
39
39
|
if (m.closeout_completed === undefined) {
|
|
40
40
|
// no closeout has been done, so fall back to checking inspections and quarantined
|
|
41
|
-
if (LazySeq.ofObject(m.completedInspections ?? {}).some(([, insp]) => insp.success
|
|
41
|
+
if (LazySeq.ofObject(m.completedInspections ?? {}).some(([, insp]) => !insp.success)) {
|
|
42
42
|
return true;
|
|
43
43
|
}
|
|
44
44
|
if (m.currently_quarantined) {
|
|
@@ -52,7 +52,7 @@ function isAbnormal(m) {
|
|
|
52
52
|
}
|
|
53
53
|
export const last30PartSummaryRange = chartRangeAtom("part-summary");
|
|
54
54
|
export const last30PartSummary = atom((get) => {
|
|
55
|
-
const
|
|
55
|
+
const materialSummary = get(last30MaterialSummary);
|
|
56
56
|
const cycles = get(last30StationCycles);
|
|
57
57
|
const range = get(last30PartSummaryRange);
|
|
58
58
|
const stationTimes = cycles
|
|
@@ -60,7 +60,7 @@ export const last30PartSummary = atom((get) => {
|
|
|
60
60
|
.filter((c) => (range.startDate === null || c.endTime >= range.startDate) &&
|
|
61
61
|
(range.endDate === null || c.endTime <= range.endDate))
|
|
62
62
|
.toLookupOrderedMap((c) => c.part, (c) => c.stationGroup, (c) => ({
|
|
63
|
-
isLoadUnload: c
|
|
63
|
+
isLoadUnload: isLaborCycle(c),
|
|
64
64
|
elapsed: c.elapsedMinsPerMaterial * c.material.length,
|
|
65
65
|
active: c.activeMinutes,
|
|
66
66
|
medianElapsed: c.medianCycleMinutes,
|
|
@@ -70,26 +70,26 @@ export const last30PartSummary = atom((get) => {
|
|
|
70
70
|
active: a.active + b.active,
|
|
71
71
|
medianElapsed: a.medianElapsed + b.medianElapsed,
|
|
72
72
|
}));
|
|
73
|
-
return
|
|
73
|
+
return materialSummary.matsById
|
|
74
74
|
.valuesToLazySeq()
|
|
75
75
|
.filter((m) => Boolean(m.numProcesses &&
|
|
76
76
|
m.unloaded_processes?.[m.numProcesses] &&
|
|
77
77
|
(range.startDate === null || m.unloaded_processes[m.numProcesses] >= range.startDate) &&
|
|
78
78
|
(range.endDate === null || m.unloaded_processes[m.numProcesses] <= range.endDate)))
|
|
79
79
|
.toOrderedLookup((m) => m.partName)
|
|
80
|
-
.mapValues((
|
|
80
|
+
.mapValues((partMats, partName) => ({
|
|
81
81
|
part: partName,
|
|
82
|
-
completedQty:
|
|
83
|
-
abnormalQty: LazySeq.of(
|
|
84
|
-
mats:
|
|
82
|
+
completedQty: partMats.length,
|
|
83
|
+
abnormalQty: LazySeq.of(partMats).sumBy((m) => (isAbnormal(m) ? 1 : 0)),
|
|
84
|
+
mats: partMats,
|
|
85
85
|
stationMins: OrderedMap.empty(),
|
|
86
|
-
workorders: LazySeq.of(
|
|
86
|
+
workorders: LazySeq.of(partMats)
|
|
87
87
|
.toOrderedSet((m) => m.workorderId ?? "")
|
|
88
88
|
.delete(""),
|
|
89
89
|
}))
|
|
90
|
-
.adjust(stationTimes, (summary,
|
|
90
|
+
.adjust(stationTimes, (summary, partStationTimes, partName) => {
|
|
91
91
|
if (summary) {
|
|
92
|
-
return { ...summary, stationMins:
|
|
92
|
+
return { ...summary, stationMins: partStationTimes };
|
|
93
93
|
}
|
|
94
94
|
else {
|
|
95
95
|
return {
|
|
@@ -97,7 +97,7 @@ export const last30PartSummary = atom((get) => {
|
|
|
97
97
|
completedQty: 0,
|
|
98
98
|
abnormalQty: 0,
|
|
99
99
|
mats: [],
|
|
100
|
-
stationMins:
|
|
100
|
+
stationMins: partStationTimes,
|
|
101
101
|
workorders: OrderedSet.empty(),
|
|
102
102
|
};
|
|
103
103
|
}
|
package/dist/data/path-lookup.js
CHANGED
|
@@ -35,19 +35,21 @@ import { addDays } from "date-fns";
|
|
|
35
35
|
import { convertLogToInspections, } from "../cell-status/inspections.js";
|
|
36
36
|
import { HashMap, LazySeq } from "@seedtactics/immutable-collections";
|
|
37
37
|
import { atom } from "jotai";
|
|
38
|
-
import {
|
|
38
|
+
import { unwrap } from "jotai/utils";
|
|
39
39
|
export const pathLookupRange = atom(null);
|
|
40
40
|
const localLogEntries = atom(async (get, { signal }) => {
|
|
41
41
|
const range = get(pathLookupRange);
|
|
42
42
|
if (range == null)
|
|
43
43
|
return HashMap.empty();
|
|
44
|
+
if (typeof LogBackend === "undefined")
|
|
45
|
+
return HashMap.empty();
|
|
44
46
|
const events = await LogBackend.get(range.curStart, range.curEnd, signal);
|
|
45
47
|
return LazySeq.of(events)
|
|
46
48
|
.flatMap(convertLogToInspections)
|
|
47
49
|
.filter((e) => e.key.part === range.part)
|
|
48
50
|
.toLookupMap((e) => e.key, (e) => e.entry.cntr, (e) => e.entry);
|
|
49
51
|
});
|
|
50
|
-
const
|
|
52
|
+
const localLogEntriesUnwrapped = unwrap(localLogEntries, (prev) => prev ?? HashMap.empty());
|
|
51
53
|
const otherLogEntries = atom(async (get) => {
|
|
52
54
|
const range = get(pathLookupRange);
|
|
53
55
|
if (range == null)
|
|
@@ -62,28 +64,9 @@ const otherLogEntries = atom(async (get) => {
|
|
|
62
64
|
.filter((e) => e.key.part === range.part)
|
|
63
65
|
.toLookupMap((e) => e.key, (e) => e.entry.cntr, (e) => e.entry);
|
|
64
66
|
});
|
|
65
|
-
const
|
|
67
|
+
const otherLogEntriesUnwrapped = unwrap(otherLogEntries, (prev) => prev ?? HashMap.empty());
|
|
66
68
|
export const inspectionLogEntries = atom((get) => {
|
|
67
|
-
|
|
68
|
-
const otherEvts = get(otherLogLoadable);
|
|
69
|
-
const localData = localEvts.state === "hasData" ? localEvts.data : null;
|
|
70
|
-
const otherData = otherEvts.state === "hasData" ? otherEvts.data : null;
|
|
71
|
-
if (localData) {
|
|
72
|
-
if (!otherData) {
|
|
73
|
-
return localData;
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
return HashMap.union((inspsByCntr1, inspsByCntr2) => inspsByCntr1.union(inspsByCntr2), localData, otherData);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
if (otherData) {
|
|
81
|
-
return otherData;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
return HashMap.empty();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
69
|
+
return HashMap.union((inspsByCntr1, inspsByCntr2) => inspsByCntr1.union(inspsByCntr2), get(localLogEntriesUnwrapped), get(otherLogEntriesUnwrapped));
|
|
87
70
|
});
|
|
88
71
|
export function extendRange(numDays) {
|
|
89
72
|
return (range) => {
|
|
@@ -44,4 +44,4 @@ export interface QueueData {
|
|
|
44
44
|
readonly groupedRawMat?: ReadonlyArray<QueueRawMaterialGroup>;
|
|
45
45
|
}
|
|
46
46
|
export declare function selectQueueData(queuesToCheck: ReadonlyArray<string>, curSt: Readonly<api.ICurrentStatus>, rawMatQueues: ReadonlySet<string>, inProcQueues: ReadonlySet<string>): ReadonlyArray<QueueData>;
|
|
47
|
-
export declare function loadRawMaterialEvents(
|
|
47
|
+
export declare function loadRawMaterialEvents(materials: ReadonlyArray<Readonly<api.IInProcessMaterial>>): Promise<ReadonlyArray<Readonly<api.ILogEntry>>>;
|