@optifye/dashboard-core 6.11.37 → 6.11.38
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/index.js +142 -25
- package/dist/index.mjs +142 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -78909,6 +78909,12 @@ var buildDeltaBadge = (delta, options) => {
|
|
|
78909
78909
|
text: `${options.formatter(delta)} vs ${options.comparisonLabel}`
|
|
78910
78910
|
};
|
|
78911
78911
|
};
|
|
78912
|
+
var parseSpecificShiftId = (shiftMode) => {
|
|
78913
|
+
const rawMode = String(shiftMode || "").trim().toLowerCase();
|
|
78914
|
+
if (!rawMode.startsWith("shift:")) return null;
|
|
78915
|
+
const parsed = Number(rawMode.split(":", 2)[1]);
|
|
78916
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
78917
|
+
};
|
|
78912
78918
|
var normalizeShiftLabel = (shiftName, shiftMode) => {
|
|
78913
78919
|
if (shiftMode === "all") {
|
|
78914
78920
|
return "All Shifts";
|
|
@@ -78920,6 +78926,10 @@ var normalizeShiftLabel = (shiftName, shiftMode) => {
|
|
|
78920
78926
|
if (normalizedName === "night") return "Night Shift";
|
|
78921
78927
|
return /shift/i.test(trimmedName) ? trimmedName : `${trimmedName} Shift`;
|
|
78922
78928
|
}
|
|
78929
|
+
const specificShiftId = parseSpecificShiftId(shiftMode);
|
|
78930
|
+
if (specificShiftId !== null) {
|
|
78931
|
+
return `Shift ${specificShiftId}`;
|
|
78932
|
+
}
|
|
78923
78933
|
if (shiftMode === "night") return "Night Shift";
|
|
78924
78934
|
return "Day Shift";
|
|
78925
78935
|
};
|
|
@@ -78992,6 +79002,7 @@ var OperationsOverviewHeader = React143__namespace.default.memo(({
|
|
|
78992
79002
|
dateRange,
|
|
78993
79003
|
displayDateRange,
|
|
78994
79004
|
trendMode,
|
|
79005
|
+
shiftFilterOptions,
|
|
78995
79006
|
isLiveScope,
|
|
78996
79007
|
liveShiftName,
|
|
78997
79008
|
lineOptions,
|
|
@@ -79245,7 +79256,7 @@ var OperationsOverviewHeader = React143__namespace.default.memo(({
|
|
|
79245
79256
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
79246
79257
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
79247
79258
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Shift" }),
|
|
79248
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children: /* @__PURE__ */ jsxRuntime.
|
|
79259
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
79249
79260
|
"select",
|
|
79250
79261
|
{
|
|
79251
79262
|
value: trendMode,
|
|
@@ -79257,11 +79268,7 @@ var OperationsOverviewHeader = React143__namespace.default.memo(({
|
|
|
79257
79268
|
backgroundRepeat: "no-repeat",
|
|
79258
79269
|
backgroundSize: "1.2em 1.2em"
|
|
79259
79270
|
},
|
|
79260
|
-
children:
|
|
79261
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Shifts" }),
|
|
79262
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "day", children: "Day Shift" }),
|
|
79263
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "night", children: "Night Shift" })
|
|
79264
|
-
]
|
|
79271
|
+
children: shiftFilterOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, children: option.label }, option.value))
|
|
79265
79272
|
}
|
|
79266
79273
|
) })
|
|
79267
79274
|
] }),
|
|
@@ -80331,6 +80338,24 @@ var normalizeShiftId = (value) => {
|
|
|
80331
80338
|
}
|
|
80332
80339
|
return null;
|
|
80333
80340
|
};
|
|
80341
|
+
var buildSpecificShiftMode = (value) => {
|
|
80342
|
+
const normalizedShiftId = normalizeShiftId(value);
|
|
80343
|
+
return normalizedShiftId === null ? null : `shift:${normalizedShiftId}`;
|
|
80344
|
+
};
|
|
80345
|
+
var parseSpecificShiftMode = (value) => {
|
|
80346
|
+
const rawValue = String(value || "").trim().toLowerCase();
|
|
80347
|
+
if (!rawValue.startsWith("shift:")) return null;
|
|
80348
|
+
const parsed = Number(rawValue.split(":", 2)[1]);
|
|
80349
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
80350
|
+
};
|
|
80351
|
+
var formatShiftOptionLabel = (shiftName, shiftId) => {
|
|
80352
|
+
const trimmedName = shiftName?.trim();
|
|
80353
|
+
if (trimmedName) {
|
|
80354
|
+
return /shift/i.test(trimmedName) ? trimmedName : `${trimmedName} Shift`;
|
|
80355
|
+
}
|
|
80356
|
+
const normalizedShiftId = normalizeShiftId(shiftId);
|
|
80357
|
+
return normalizedShiftId === null ? "Unknown Shift" : `Shift ${normalizedShiftId}`;
|
|
80358
|
+
};
|
|
80334
80359
|
var classifyShiftBucket = ({
|
|
80335
80360
|
shiftName,
|
|
80336
80361
|
shiftId,
|
|
@@ -80417,6 +80442,26 @@ var normalizeShiftWindowMinutes = (startTime, endTime) => {
|
|
|
80417
80442
|
}
|
|
80418
80443
|
return { startMinutes, endMinutes };
|
|
80419
80444
|
};
|
|
80445
|
+
var getOperationalSortStartMinutes = (startTime, endTime) => {
|
|
80446
|
+
const normalizedWindow = normalizeShiftWindowMinutes(startTime, endTime);
|
|
80447
|
+
if (!normalizedWindow) return null;
|
|
80448
|
+
return normalizedWindow.startMinutes < 6 * 60 ? normalizedWindow.startMinutes + 24 * 60 : normalizedWindow.startMinutes;
|
|
80449
|
+
};
|
|
80450
|
+
var doesShiftMatchTrendMode = ({
|
|
80451
|
+
trendMode,
|
|
80452
|
+
shiftName,
|
|
80453
|
+
shiftId,
|
|
80454
|
+
startTime,
|
|
80455
|
+
endTime
|
|
80456
|
+
}) => {
|
|
80457
|
+
if (trendMode === "all") return true;
|
|
80458
|
+
const specificShiftId = parseSpecificShiftMode(trendMode);
|
|
80459
|
+
if (specificShiftId !== null) {
|
|
80460
|
+
return normalizeShiftId(shiftId) === specificShiftId;
|
|
80461
|
+
}
|
|
80462
|
+
const bucket = classifyShiftBucket({ shiftName, shiftId, startTime, endTime });
|
|
80463
|
+
return bucket === trendMode;
|
|
80464
|
+
};
|
|
80420
80465
|
var PlantHeadView = () => {
|
|
80421
80466
|
const supabase = useSupabase();
|
|
80422
80467
|
const entityConfig = useEntityConfig();
|
|
@@ -80547,6 +80592,45 @@ var PlantHeadView = () => {
|
|
|
80547
80592
|
shiftConfigMap,
|
|
80548
80593
|
isLoading: isShiftConfigLoading
|
|
80549
80594
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
80595
|
+
const shiftFilterOptions = React143__namespace.default.useMemo(() => {
|
|
80596
|
+
const optionsById = /* @__PURE__ */ new Map();
|
|
80597
|
+
scopedLineIds.forEach((lineId) => {
|
|
80598
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
80599
|
+
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
80600
|
+
const shiftId = normalizeShiftId(shift.shiftId);
|
|
80601
|
+
if (shiftId === null) return;
|
|
80602
|
+
const sortKey = getOperationalSortStartMinutes(shift.startTime, shift.endTime) ?? 24 * 60 + shiftId;
|
|
80603
|
+
const existing = optionsById.get(shiftId);
|
|
80604
|
+
const label = formatShiftOptionLabel(shift.shiftName, shiftId);
|
|
80605
|
+
if (!existing) {
|
|
80606
|
+
optionsById.set(shiftId, {
|
|
80607
|
+
value: buildSpecificShiftMode(shiftId),
|
|
80608
|
+
label,
|
|
80609
|
+
shiftId,
|
|
80610
|
+
shiftName: shift.shiftName || null,
|
|
80611
|
+
startTime: shift.startTime || null,
|
|
80612
|
+
endTime: shift.endTime || null,
|
|
80613
|
+
sortKey
|
|
80614
|
+
});
|
|
80615
|
+
return;
|
|
80616
|
+
}
|
|
80617
|
+
if ((!existing.shiftName || existing.shiftName === `Shift ${shiftId}`) && shift.shiftName) {
|
|
80618
|
+
existing.shiftName = shift.shiftName;
|
|
80619
|
+
existing.label = label;
|
|
80620
|
+
}
|
|
80621
|
+
if (sortKey < existing.sortKey) {
|
|
80622
|
+
existing.sortKey = sortKey;
|
|
80623
|
+
existing.startTime = shift.startTime || null;
|
|
80624
|
+
existing.endTime = shift.endTime || null;
|
|
80625
|
+
}
|
|
80626
|
+
});
|
|
80627
|
+
});
|
|
80628
|
+
const dynamicOptions = Array.from(optionsById.values()).sort((a, b) => a.sortKey - b.sortKey || (a.shiftId || 0) - (b.shiftId || 0)).map(({ sortKey, ...option }) => option);
|
|
80629
|
+
return [
|
|
80630
|
+
{ value: "all", label: "All Shifts" },
|
|
80631
|
+
...dynamicOptions
|
|
80632
|
+
];
|
|
80633
|
+
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
80550
80634
|
React143__namespace.default.useEffect(() => {
|
|
80551
80635
|
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
80552
80636
|
return;
|
|
@@ -80609,18 +80693,20 @@ var PlantHeadView = () => {
|
|
|
80609
80693
|
if (!activeShift) {
|
|
80610
80694
|
return [];
|
|
80611
80695
|
}
|
|
80612
|
-
const
|
|
80696
|
+
const bucketTrendMode = classifyShiftBucket({
|
|
80613
80697
|
shiftName: activeShift.shiftName,
|
|
80614
80698
|
shiftId: activeShift.shiftId,
|
|
80615
80699
|
startTime: activeShift.startTime,
|
|
80616
80700
|
endTime: activeShift.endTime
|
|
80617
80701
|
});
|
|
80618
|
-
|
|
80702
|
+
const exactTrendMode = buildSpecificShiftMode(activeShift.shiftId);
|
|
80703
|
+
if (!bucketTrendMode && !exactTrendMode) {
|
|
80619
80704
|
return [];
|
|
80620
80705
|
}
|
|
80621
80706
|
return [{
|
|
80622
80707
|
lineId,
|
|
80623
|
-
|
|
80708
|
+
exactTrendMode,
|
|
80709
|
+
bucketTrendMode,
|
|
80624
80710
|
shiftId: activeShift.shiftId,
|
|
80625
80711
|
shiftName: activeShift.shiftName || null,
|
|
80626
80712
|
startTime: activeShift.startTime || null,
|
|
@@ -80629,14 +80715,12 @@ var PlantHeadView = () => {
|
|
|
80629
80715
|
}];
|
|
80630
80716
|
});
|
|
80631
80717
|
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
80632
|
-
const
|
|
80633
|
-
|
|
80634
|
-
|
|
80635
|
-
|
|
80636
|
-
|
|
80637
|
-
|
|
80638
|
-
[activeLineShiftStates, resolvedOperationalToday]
|
|
80639
|
-
);
|
|
80718
|
+
const uniformActiveTrendMode = React143__namespace.default.useMemo(() => {
|
|
80719
|
+
const activeModes = Array.from(new Set(
|
|
80720
|
+
activeLineShiftStates.filter((shift) => shift.date === resolvedOperationalToday).map((shift) => shift.exactTrendMode).filter((mode) => !!mode)
|
|
80721
|
+
));
|
|
80722
|
+
return activeModes.length === 1 ? activeModes[0] : null;
|
|
80723
|
+
}, [activeLineShiftStates, resolvedOperationalToday]);
|
|
80640
80724
|
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
80641
80725
|
const hourlyWindowStartTime = React143__namespace.default.useMemo(() => {
|
|
80642
80726
|
if (scopedLineIds.length === 0) {
|
|
@@ -80647,13 +80731,19 @@ var PlantHeadView = () => {
|
|
|
80647
80731
|
scopedLineIds.forEach((lineId) => {
|
|
80648
80732
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
80649
80733
|
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
80650
|
-
|
|
80734
|
+
classifyShiftBucket({
|
|
80651
80735
|
shiftName: shift.shiftName,
|
|
80652
80736
|
shiftId: shift.shiftId,
|
|
80653
80737
|
startTime: shift.startTime,
|
|
80654
80738
|
endTime: shift.endTime
|
|
80655
80739
|
});
|
|
80656
|
-
if (
|
|
80740
|
+
if (!doesShiftMatchTrendMode({
|
|
80741
|
+
trendMode: resolvedTrendMode,
|
|
80742
|
+
shiftName: shift.shiftName,
|
|
80743
|
+
shiftId: shift.shiftId,
|
|
80744
|
+
startTime: shift.startTime,
|
|
80745
|
+
endTime: shift.endTime
|
|
80746
|
+
})) {
|
|
80657
80747
|
return;
|
|
80658
80748
|
}
|
|
80659
80749
|
const normalizedWindow = normalizeShiftWindowMinutes(shift.startTime, shift.endTime);
|
|
@@ -80727,11 +80817,11 @@ var PlantHeadView = () => {
|
|
|
80727
80817
|
endKey: nextStartKey
|
|
80728
80818
|
};
|
|
80729
80819
|
});
|
|
80730
|
-
setTrendMode("all");
|
|
80820
|
+
setTrendMode(uniformActiveTrendMode || "all");
|
|
80731
80821
|
setUsesThisWeekComparison(false);
|
|
80732
80822
|
hasAutoInitializedScopeRef.current = true;
|
|
80733
80823
|
setIsInitialScopeReady(true);
|
|
80734
|
-
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
80824
|
+
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length, uniformActiveTrendMode]);
|
|
80735
80825
|
const handleDateRangeChange = React143__namespace.default.useCallback((range, meta) => {
|
|
80736
80826
|
hasUserAdjustedScopeRef.current = true;
|
|
80737
80827
|
setIsInitialScopeReady(true);
|
|
@@ -80818,6 +80908,33 @@ var PlantHeadView = () => {
|
|
|
80818
80908
|
() => resolvedTrendMode,
|
|
80819
80909
|
[resolvedTrendMode]
|
|
80820
80910
|
);
|
|
80911
|
+
const hasActiveSelectedShiftLine = React143__namespace.default.useMemo(
|
|
80912
|
+
() => activeLineShiftStates.some((shift) => {
|
|
80913
|
+
if (shift.date !== resolvedOperationalToday) return false;
|
|
80914
|
+
if (effectiveTrendMode === "all") return true;
|
|
80915
|
+
const specificShiftId = parseSpecificShiftMode(effectiveTrendMode);
|
|
80916
|
+
if (specificShiftId !== null) {
|
|
80917
|
+
return shift.exactTrendMode === effectiveTrendMode;
|
|
80918
|
+
}
|
|
80919
|
+
return shift.bucketTrendMode === effectiveTrendMode;
|
|
80920
|
+
}),
|
|
80921
|
+
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
80922
|
+
);
|
|
80923
|
+
const activeLiveShiftName = React143__namespace.default.useMemo(
|
|
80924
|
+
() => {
|
|
80925
|
+
if (effectiveTrendMode === "all") return null;
|
|
80926
|
+
const matchingShift = activeLineShiftStates.find((shift) => {
|
|
80927
|
+
if (shift.date !== resolvedOperationalToday) return false;
|
|
80928
|
+
const specificShiftId = parseSpecificShiftMode(effectiveTrendMode);
|
|
80929
|
+
if (specificShiftId !== null) {
|
|
80930
|
+
return shift.exactTrendMode === effectiveTrendMode;
|
|
80931
|
+
}
|
|
80932
|
+
return shift.bucketTrendMode === effectiveTrendMode;
|
|
80933
|
+
});
|
|
80934
|
+
return matchingShift?.shiftName || null;
|
|
80935
|
+
},
|
|
80936
|
+
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
80937
|
+
);
|
|
80821
80938
|
const hourlyLabelStartTime = React143__namespace.default.useMemo(() => {
|
|
80822
80939
|
if (scopedLineIds.length === 0) {
|
|
80823
80940
|
return null;
|
|
@@ -80829,12 +80946,11 @@ var PlantHeadView = () => {
|
|
|
80829
80946
|
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
80830
80947
|
);
|
|
80831
80948
|
const isLiveScope = React143__namespace.default.useMemo(
|
|
80832
|
-
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday &&
|
|
80949
|
+
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && hasActiveSelectedShiftLine,
|
|
80833
80950
|
[
|
|
80834
80951
|
effectiveDateRange.startKey,
|
|
80835
80952
|
effectiveTrendMode,
|
|
80836
|
-
|
|
80837
|
-
hasActiveNightShiftLine,
|
|
80953
|
+
hasActiveSelectedShiftLine,
|
|
80838
80954
|
isSingleDayScope,
|
|
80839
80955
|
resolvedOperationalToday
|
|
80840
80956
|
]
|
|
@@ -80871,8 +80987,9 @@ var PlantHeadView = () => {
|
|
|
80871
80987
|
dateRange,
|
|
80872
80988
|
displayDateRange: headerDateRange,
|
|
80873
80989
|
trendMode,
|
|
80990
|
+
shiftFilterOptions,
|
|
80874
80991
|
isLiveScope,
|
|
80875
|
-
liveShiftName: isLiveScope && trendMode !== "all" ?
|
|
80992
|
+
liveShiftName: isLiveScope && trendMode !== "all" ? activeLiveShiftName : null,
|
|
80876
80993
|
lineOptions,
|
|
80877
80994
|
supervisorOptions,
|
|
80878
80995
|
selectedSupervisorId,
|
package/dist/index.mjs
CHANGED
|
@@ -78880,6 +78880,12 @@ var buildDeltaBadge = (delta, options) => {
|
|
|
78880
78880
|
text: `${options.formatter(delta)} vs ${options.comparisonLabel}`
|
|
78881
78881
|
};
|
|
78882
78882
|
};
|
|
78883
|
+
var parseSpecificShiftId = (shiftMode) => {
|
|
78884
|
+
const rawMode = String(shiftMode || "").trim().toLowerCase();
|
|
78885
|
+
if (!rawMode.startsWith("shift:")) return null;
|
|
78886
|
+
const parsed = Number(rawMode.split(":", 2)[1]);
|
|
78887
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
78888
|
+
};
|
|
78883
78889
|
var normalizeShiftLabel = (shiftName, shiftMode) => {
|
|
78884
78890
|
if (shiftMode === "all") {
|
|
78885
78891
|
return "All Shifts";
|
|
@@ -78891,6 +78897,10 @@ var normalizeShiftLabel = (shiftName, shiftMode) => {
|
|
|
78891
78897
|
if (normalizedName === "night") return "Night Shift";
|
|
78892
78898
|
return /shift/i.test(trimmedName) ? trimmedName : `${trimmedName} Shift`;
|
|
78893
78899
|
}
|
|
78900
|
+
const specificShiftId = parseSpecificShiftId(shiftMode);
|
|
78901
|
+
if (specificShiftId !== null) {
|
|
78902
|
+
return `Shift ${specificShiftId}`;
|
|
78903
|
+
}
|
|
78894
78904
|
if (shiftMode === "night") return "Night Shift";
|
|
78895
78905
|
return "Day Shift";
|
|
78896
78906
|
};
|
|
@@ -78963,6 +78973,7 @@ var OperationsOverviewHeader = React143__default.memo(({
|
|
|
78963
78973
|
dateRange,
|
|
78964
78974
|
displayDateRange,
|
|
78965
78975
|
trendMode,
|
|
78976
|
+
shiftFilterOptions,
|
|
78966
78977
|
isLiveScope,
|
|
78967
78978
|
liveShiftName,
|
|
78968
78979
|
lineOptions,
|
|
@@ -79216,7 +79227,7 @@ var OperationsOverviewHeader = React143__default.memo(({
|
|
|
79216
79227
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
79217
79228
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
79218
79229
|
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Shift" }),
|
|
79219
|
-
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */
|
|
79230
|
+
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
|
|
79220
79231
|
"select",
|
|
79221
79232
|
{
|
|
79222
79233
|
value: trendMode,
|
|
@@ -79228,11 +79239,7 @@ var OperationsOverviewHeader = React143__default.memo(({
|
|
|
79228
79239
|
backgroundRepeat: "no-repeat",
|
|
79229
79240
|
backgroundSize: "1.2em 1.2em"
|
|
79230
79241
|
},
|
|
79231
|
-
children:
|
|
79232
|
-
/* @__PURE__ */ jsx("option", { value: "all", children: "All Shifts" }),
|
|
79233
|
-
/* @__PURE__ */ jsx("option", { value: "day", children: "Day Shift" }),
|
|
79234
|
-
/* @__PURE__ */ jsx("option", { value: "night", children: "Night Shift" })
|
|
79235
|
-
]
|
|
79242
|
+
children: shiftFilterOptions.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
|
|
79236
79243
|
}
|
|
79237
79244
|
) })
|
|
79238
79245
|
] }),
|
|
@@ -80302,6 +80309,24 @@ var normalizeShiftId = (value) => {
|
|
|
80302
80309
|
}
|
|
80303
80310
|
return null;
|
|
80304
80311
|
};
|
|
80312
|
+
var buildSpecificShiftMode = (value) => {
|
|
80313
|
+
const normalizedShiftId = normalizeShiftId(value);
|
|
80314
|
+
return normalizedShiftId === null ? null : `shift:${normalizedShiftId}`;
|
|
80315
|
+
};
|
|
80316
|
+
var parseSpecificShiftMode = (value) => {
|
|
80317
|
+
const rawValue = String(value || "").trim().toLowerCase();
|
|
80318
|
+
if (!rawValue.startsWith("shift:")) return null;
|
|
80319
|
+
const parsed = Number(rawValue.split(":", 2)[1]);
|
|
80320
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
80321
|
+
};
|
|
80322
|
+
var formatShiftOptionLabel = (shiftName, shiftId) => {
|
|
80323
|
+
const trimmedName = shiftName?.trim();
|
|
80324
|
+
if (trimmedName) {
|
|
80325
|
+
return /shift/i.test(trimmedName) ? trimmedName : `${trimmedName} Shift`;
|
|
80326
|
+
}
|
|
80327
|
+
const normalizedShiftId = normalizeShiftId(shiftId);
|
|
80328
|
+
return normalizedShiftId === null ? "Unknown Shift" : `Shift ${normalizedShiftId}`;
|
|
80329
|
+
};
|
|
80305
80330
|
var classifyShiftBucket = ({
|
|
80306
80331
|
shiftName,
|
|
80307
80332
|
shiftId,
|
|
@@ -80388,6 +80413,26 @@ var normalizeShiftWindowMinutes = (startTime, endTime) => {
|
|
|
80388
80413
|
}
|
|
80389
80414
|
return { startMinutes, endMinutes };
|
|
80390
80415
|
};
|
|
80416
|
+
var getOperationalSortStartMinutes = (startTime, endTime) => {
|
|
80417
|
+
const normalizedWindow = normalizeShiftWindowMinutes(startTime, endTime);
|
|
80418
|
+
if (!normalizedWindow) return null;
|
|
80419
|
+
return normalizedWindow.startMinutes < 6 * 60 ? normalizedWindow.startMinutes + 24 * 60 : normalizedWindow.startMinutes;
|
|
80420
|
+
};
|
|
80421
|
+
var doesShiftMatchTrendMode = ({
|
|
80422
|
+
trendMode,
|
|
80423
|
+
shiftName,
|
|
80424
|
+
shiftId,
|
|
80425
|
+
startTime,
|
|
80426
|
+
endTime
|
|
80427
|
+
}) => {
|
|
80428
|
+
if (trendMode === "all") return true;
|
|
80429
|
+
const specificShiftId = parseSpecificShiftMode(trendMode);
|
|
80430
|
+
if (specificShiftId !== null) {
|
|
80431
|
+
return normalizeShiftId(shiftId) === specificShiftId;
|
|
80432
|
+
}
|
|
80433
|
+
const bucket = classifyShiftBucket({ shiftName, shiftId, startTime, endTime });
|
|
80434
|
+
return bucket === trendMode;
|
|
80435
|
+
};
|
|
80391
80436
|
var PlantHeadView = () => {
|
|
80392
80437
|
const supabase = useSupabase();
|
|
80393
80438
|
const entityConfig = useEntityConfig();
|
|
@@ -80518,6 +80563,45 @@ var PlantHeadView = () => {
|
|
|
80518
80563
|
shiftConfigMap,
|
|
80519
80564
|
isLoading: isShiftConfigLoading
|
|
80520
80565
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
80566
|
+
const shiftFilterOptions = React143__default.useMemo(() => {
|
|
80567
|
+
const optionsById = /* @__PURE__ */ new Map();
|
|
80568
|
+
scopedLineIds.forEach((lineId) => {
|
|
80569
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
80570
|
+
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
80571
|
+
const shiftId = normalizeShiftId(shift.shiftId);
|
|
80572
|
+
if (shiftId === null) return;
|
|
80573
|
+
const sortKey = getOperationalSortStartMinutes(shift.startTime, shift.endTime) ?? 24 * 60 + shiftId;
|
|
80574
|
+
const existing = optionsById.get(shiftId);
|
|
80575
|
+
const label = formatShiftOptionLabel(shift.shiftName, shiftId);
|
|
80576
|
+
if (!existing) {
|
|
80577
|
+
optionsById.set(shiftId, {
|
|
80578
|
+
value: buildSpecificShiftMode(shiftId),
|
|
80579
|
+
label,
|
|
80580
|
+
shiftId,
|
|
80581
|
+
shiftName: shift.shiftName || null,
|
|
80582
|
+
startTime: shift.startTime || null,
|
|
80583
|
+
endTime: shift.endTime || null,
|
|
80584
|
+
sortKey
|
|
80585
|
+
});
|
|
80586
|
+
return;
|
|
80587
|
+
}
|
|
80588
|
+
if ((!existing.shiftName || existing.shiftName === `Shift ${shiftId}`) && shift.shiftName) {
|
|
80589
|
+
existing.shiftName = shift.shiftName;
|
|
80590
|
+
existing.label = label;
|
|
80591
|
+
}
|
|
80592
|
+
if (sortKey < existing.sortKey) {
|
|
80593
|
+
existing.sortKey = sortKey;
|
|
80594
|
+
existing.startTime = shift.startTime || null;
|
|
80595
|
+
existing.endTime = shift.endTime || null;
|
|
80596
|
+
}
|
|
80597
|
+
});
|
|
80598
|
+
});
|
|
80599
|
+
const dynamicOptions = Array.from(optionsById.values()).sort((a, b) => a.sortKey - b.sortKey || (a.shiftId || 0) - (b.shiftId || 0)).map(({ sortKey, ...option }) => option);
|
|
80600
|
+
return [
|
|
80601
|
+
{ value: "all", label: "All Shifts" },
|
|
80602
|
+
...dynamicOptions
|
|
80603
|
+
];
|
|
80604
|
+
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
80521
80605
|
React143__default.useEffect(() => {
|
|
80522
80606
|
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
80523
80607
|
return;
|
|
@@ -80580,18 +80664,20 @@ var PlantHeadView = () => {
|
|
|
80580
80664
|
if (!activeShift) {
|
|
80581
80665
|
return [];
|
|
80582
80666
|
}
|
|
80583
|
-
const
|
|
80667
|
+
const bucketTrendMode = classifyShiftBucket({
|
|
80584
80668
|
shiftName: activeShift.shiftName,
|
|
80585
80669
|
shiftId: activeShift.shiftId,
|
|
80586
80670
|
startTime: activeShift.startTime,
|
|
80587
80671
|
endTime: activeShift.endTime
|
|
80588
80672
|
});
|
|
80589
|
-
|
|
80673
|
+
const exactTrendMode = buildSpecificShiftMode(activeShift.shiftId);
|
|
80674
|
+
if (!bucketTrendMode && !exactTrendMode) {
|
|
80590
80675
|
return [];
|
|
80591
80676
|
}
|
|
80592
80677
|
return [{
|
|
80593
80678
|
lineId,
|
|
80594
|
-
|
|
80679
|
+
exactTrendMode,
|
|
80680
|
+
bucketTrendMode,
|
|
80595
80681
|
shiftId: activeShift.shiftId,
|
|
80596
80682
|
shiftName: activeShift.shiftName || null,
|
|
80597
80683
|
startTime: activeShift.startTime || null,
|
|
@@ -80600,14 +80686,12 @@ var PlantHeadView = () => {
|
|
|
80600
80686
|
}];
|
|
80601
80687
|
});
|
|
80602
80688
|
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
80603
|
-
const
|
|
80604
|
-
|
|
80605
|
-
|
|
80606
|
-
|
|
80607
|
-
|
|
80608
|
-
|
|
80609
|
-
[activeLineShiftStates, resolvedOperationalToday]
|
|
80610
|
-
);
|
|
80689
|
+
const uniformActiveTrendMode = React143__default.useMemo(() => {
|
|
80690
|
+
const activeModes = Array.from(new Set(
|
|
80691
|
+
activeLineShiftStates.filter((shift) => shift.date === resolvedOperationalToday).map((shift) => shift.exactTrendMode).filter((mode) => !!mode)
|
|
80692
|
+
));
|
|
80693
|
+
return activeModes.length === 1 ? activeModes[0] : null;
|
|
80694
|
+
}, [activeLineShiftStates, resolvedOperationalToday]);
|
|
80611
80695
|
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
80612
80696
|
const hourlyWindowStartTime = React143__default.useMemo(() => {
|
|
80613
80697
|
if (scopedLineIds.length === 0) {
|
|
@@ -80618,13 +80702,19 @@ var PlantHeadView = () => {
|
|
|
80618
80702
|
scopedLineIds.forEach((lineId) => {
|
|
80619
80703
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
80620
80704
|
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
80621
|
-
|
|
80705
|
+
classifyShiftBucket({
|
|
80622
80706
|
shiftName: shift.shiftName,
|
|
80623
80707
|
shiftId: shift.shiftId,
|
|
80624
80708
|
startTime: shift.startTime,
|
|
80625
80709
|
endTime: shift.endTime
|
|
80626
80710
|
});
|
|
80627
|
-
if (
|
|
80711
|
+
if (!doesShiftMatchTrendMode({
|
|
80712
|
+
trendMode: resolvedTrendMode,
|
|
80713
|
+
shiftName: shift.shiftName,
|
|
80714
|
+
shiftId: shift.shiftId,
|
|
80715
|
+
startTime: shift.startTime,
|
|
80716
|
+
endTime: shift.endTime
|
|
80717
|
+
})) {
|
|
80628
80718
|
return;
|
|
80629
80719
|
}
|
|
80630
80720
|
const normalizedWindow = normalizeShiftWindowMinutes(shift.startTime, shift.endTime);
|
|
@@ -80698,11 +80788,11 @@ var PlantHeadView = () => {
|
|
|
80698
80788
|
endKey: nextStartKey
|
|
80699
80789
|
};
|
|
80700
80790
|
});
|
|
80701
|
-
setTrendMode("all");
|
|
80791
|
+
setTrendMode(uniformActiveTrendMode || "all");
|
|
80702
80792
|
setUsesThisWeekComparison(false);
|
|
80703
80793
|
hasAutoInitializedScopeRef.current = true;
|
|
80704
80794
|
setIsInitialScopeReady(true);
|
|
80705
|
-
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
80795
|
+
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length, uniformActiveTrendMode]);
|
|
80706
80796
|
const handleDateRangeChange = React143__default.useCallback((range, meta) => {
|
|
80707
80797
|
hasUserAdjustedScopeRef.current = true;
|
|
80708
80798
|
setIsInitialScopeReady(true);
|
|
@@ -80789,6 +80879,33 @@ var PlantHeadView = () => {
|
|
|
80789
80879
|
() => resolvedTrendMode,
|
|
80790
80880
|
[resolvedTrendMode]
|
|
80791
80881
|
);
|
|
80882
|
+
const hasActiveSelectedShiftLine = React143__default.useMemo(
|
|
80883
|
+
() => activeLineShiftStates.some((shift) => {
|
|
80884
|
+
if (shift.date !== resolvedOperationalToday) return false;
|
|
80885
|
+
if (effectiveTrendMode === "all") return true;
|
|
80886
|
+
const specificShiftId = parseSpecificShiftMode(effectiveTrendMode);
|
|
80887
|
+
if (specificShiftId !== null) {
|
|
80888
|
+
return shift.exactTrendMode === effectiveTrendMode;
|
|
80889
|
+
}
|
|
80890
|
+
return shift.bucketTrendMode === effectiveTrendMode;
|
|
80891
|
+
}),
|
|
80892
|
+
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
80893
|
+
);
|
|
80894
|
+
const activeLiveShiftName = React143__default.useMemo(
|
|
80895
|
+
() => {
|
|
80896
|
+
if (effectiveTrendMode === "all") return null;
|
|
80897
|
+
const matchingShift = activeLineShiftStates.find((shift) => {
|
|
80898
|
+
if (shift.date !== resolvedOperationalToday) return false;
|
|
80899
|
+
const specificShiftId = parseSpecificShiftMode(effectiveTrendMode);
|
|
80900
|
+
if (specificShiftId !== null) {
|
|
80901
|
+
return shift.exactTrendMode === effectiveTrendMode;
|
|
80902
|
+
}
|
|
80903
|
+
return shift.bucketTrendMode === effectiveTrendMode;
|
|
80904
|
+
});
|
|
80905
|
+
return matchingShift?.shiftName || null;
|
|
80906
|
+
},
|
|
80907
|
+
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
80908
|
+
);
|
|
80792
80909
|
const hourlyLabelStartTime = React143__default.useMemo(() => {
|
|
80793
80910
|
if (scopedLineIds.length === 0) {
|
|
80794
80911
|
return null;
|
|
@@ -80800,12 +80917,11 @@ var PlantHeadView = () => {
|
|
|
80800
80917
|
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
80801
80918
|
);
|
|
80802
80919
|
const isLiveScope = React143__default.useMemo(
|
|
80803
|
-
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday &&
|
|
80920
|
+
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && hasActiveSelectedShiftLine,
|
|
80804
80921
|
[
|
|
80805
80922
|
effectiveDateRange.startKey,
|
|
80806
80923
|
effectiveTrendMode,
|
|
80807
|
-
|
|
80808
|
-
hasActiveNightShiftLine,
|
|
80924
|
+
hasActiveSelectedShiftLine,
|
|
80809
80925
|
isSingleDayScope,
|
|
80810
80926
|
resolvedOperationalToday
|
|
80811
80927
|
]
|
|
@@ -80842,8 +80958,9 @@ var PlantHeadView = () => {
|
|
|
80842
80958
|
dateRange,
|
|
80843
80959
|
displayDateRange: headerDateRange,
|
|
80844
80960
|
trendMode,
|
|
80961
|
+
shiftFilterOptions,
|
|
80845
80962
|
isLiveScope,
|
|
80846
|
-
liveShiftName: isLiveScope && trendMode !== "all" ?
|
|
80963
|
+
liveShiftName: isLiveScope && trendMode !== "all" ? activeLiveShiftName : null,
|
|
80847
80964
|
lineOptions,
|
|
80848
80965
|
supervisorOptions,
|
|
80849
80966
|
selectedSupervisorId,
|