@optifye/dashboard-core 6.11.16 → 6.11.17
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.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +290 -91
- package/dist/index.mjs +290 -92
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3295,11 +3295,9 @@ var normalizeShiftDefinitions = (timezone, shiftConfig) => {
|
|
|
3295
3295
|
}
|
|
3296
3296
|
return { shifts: legacyShifts, timezone: fallbackTimezone };
|
|
3297
3297
|
};
|
|
3298
|
-
var
|
|
3298
|
+
var determineActiveShiftFromDefinitions = (timezone, shifts, now4 = /* @__PURE__ */ new Date()) => {
|
|
3299
3299
|
const zonedNow = dateFnsTz.toZonedTime(now4, timezone);
|
|
3300
3300
|
const currentMinutes = zonedNow.getHours() * 60 + zonedNow.getMinutes();
|
|
3301
|
-
let chosen;
|
|
3302
|
-
let operationalDate = getOperationalDate(timezone, now4, shifts[0].startTime);
|
|
3303
3301
|
for (const shift of shifts) {
|
|
3304
3302
|
const start = parseTimeToMinutes(shift.startTime);
|
|
3305
3303
|
const endRaw = parseTimeToMinutes(shift.endTime);
|
|
@@ -3307,32 +3305,47 @@ var determineShiftFromDefinitions = (timezone, shifts, now4 = /* @__PURE__ */ ne
|
|
|
3307
3305
|
const wraps = end <= start;
|
|
3308
3306
|
if (wraps) end += 1440;
|
|
3309
3307
|
if (start <= currentMinutes && currentMinutes < end) {
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3308
|
+
return {
|
|
3309
|
+
shiftId: shift.shiftId,
|
|
3310
|
+
shiftName: shift.shiftName,
|
|
3311
|
+
startTime: shift.startTime,
|
|
3312
|
+
endTime: shift.endTime,
|
|
3313
|
+
timezone,
|
|
3314
|
+
date: getOperationalDate(timezone, now4, shift.startTime)
|
|
3315
|
+
};
|
|
3313
3316
|
}
|
|
3314
3317
|
if (start <= currentMinutes + 1440 && currentMinutes + 1440 < end) {
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
+
return {
|
|
3319
|
+
shiftId: shift.shiftId,
|
|
3320
|
+
shiftName: shift.shiftName,
|
|
3321
|
+
startTime: shift.startTime,
|
|
3322
|
+
endTime: shift.endTime,
|
|
3323
|
+
timezone,
|
|
3324
|
+
date: getOperationalDate(timezone, now4, shift.startTime)
|
|
3325
|
+
};
|
|
3318
3326
|
}
|
|
3319
3327
|
}
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3328
|
+
return null;
|
|
3329
|
+
};
|
|
3330
|
+
var getCurrentShift = (timezone, shiftConfig, now4 = /* @__PURE__ */ new Date()) => {
|
|
3331
|
+
const { shifts, timezone: effectiveTz } = normalizeShiftDefinitions(timezone, shiftConfig);
|
|
3332
|
+
const activeShift = determineActiveShiftFromDefinitions(effectiveTz, shifts, now4);
|
|
3333
|
+
if (activeShift) {
|
|
3334
|
+
return activeShift;
|
|
3323
3335
|
}
|
|
3336
|
+
const fallbackShift = shifts[0];
|
|
3324
3337
|
return {
|
|
3325
|
-
shiftId:
|
|
3326
|
-
shiftName:
|
|
3327
|
-
startTime:
|
|
3328
|
-
endTime:
|
|
3329
|
-
timezone,
|
|
3330
|
-
date:
|
|
3338
|
+
shiftId: fallbackShift.shiftId,
|
|
3339
|
+
shiftName: fallbackShift.shiftName,
|
|
3340
|
+
startTime: fallbackShift.startTime,
|
|
3341
|
+
endTime: fallbackShift.endTime,
|
|
3342
|
+
timezone: effectiveTz,
|
|
3343
|
+
date: getOperationalDate(effectiveTz, now4, fallbackShift.startTime)
|
|
3331
3344
|
};
|
|
3332
3345
|
};
|
|
3333
|
-
var
|
|
3346
|
+
var getActiveShift = (timezone, shiftConfig, now4 = /* @__PURE__ */ new Date()) => {
|
|
3334
3347
|
const { shifts, timezone: effectiveTz } = normalizeShiftDefinitions(timezone, shiftConfig);
|
|
3335
|
-
return
|
|
3348
|
+
return determineActiveShiftFromDefinitions(effectiveTz, shifts, now4);
|
|
3336
3349
|
};
|
|
3337
3350
|
var isTransitionPeriod = (timezone, shiftConfig, now4 = /* @__PURE__ */ new Date()) => {
|
|
3338
3351
|
const transitionMinutes = shiftConfig?.transitionPeriodMinutes ?? DEFAULT_TRANSITION_MINUTES;
|
|
@@ -32203,6 +32216,7 @@ var LineChartComponent = ({
|
|
|
32203
32216
|
xAxisLabel,
|
|
32204
32217
|
xAxisTickFormatter,
|
|
32205
32218
|
// Pass through for X-axis tick formatting
|
|
32219
|
+
xAxisInterval,
|
|
32206
32220
|
yAxisLabel,
|
|
32207
32221
|
yAxisUnit,
|
|
32208
32222
|
yAxisDomain,
|
|
@@ -32285,6 +32299,7 @@ var LineChartComponent = ({
|
|
|
32285
32299
|
dataKey: xAxisDataKey,
|
|
32286
32300
|
label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -10 } : void 0,
|
|
32287
32301
|
tickFormatter: xAxisTickFormatter,
|
|
32302
|
+
interval: xAxisInterval,
|
|
32288
32303
|
tick: { fontSize: 12, fill: axisTickFillColor },
|
|
32289
32304
|
stroke: axisStrokeColor
|
|
32290
32305
|
}
|
|
@@ -34028,8 +34043,9 @@ var VideoCard = React141__namespace.default.memo(({
|
|
|
34028
34043
|
const isRecentFlowCard = isVideoGridRecentFlowEnabled(workspace);
|
|
34029
34044
|
const hasDisplayMetric = typeof videoGridDisplayValue === "number" && Number.isFinite(videoGridDisplayValue);
|
|
34030
34045
|
const hasBarMetric = typeof videoGridMetricValue === "number" && Number.isFinite(videoGridMetricValue);
|
|
34046
|
+
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
34031
34047
|
const badgeTitle = hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
34032
|
-
const badgeLabel =
|
|
34048
|
+
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
34033
34049
|
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
34034
34050
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
34035
34051
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
@@ -34105,7 +34121,7 @@ var VideoCard = React141__namespace.default.memo(({
|
|
|
34105
34121
|
lastSeenText
|
|
34106
34122
|
] })
|
|
34107
34123
|
] }) }),
|
|
34108
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute ${compact ? "top-1 right-1" : "top-2 right-2"} z-30`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
34124
|
+
shouldRenderMetricBadge && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute ${compact ? "top-1 right-1" : "top-2 right-2"} z-30`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
34109
34125
|
"div",
|
|
34110
34126
|
{
|
|
34111
34127
|
"data-testid": "video-card-metric-badge",
|
|
@@ -49832,8 +49848,7 @@ var WorkspaceCycleTimeMetricCards = ({
|
|
|
49832
49848
|
{
|
|
49833
49849
|
data: idleTimeData.chartData,
|
|
49834
49850
|
isLoading: idleTimeData.isLoading,
|
|
49835
|
-
error: idleTimeData.error
|
|
49836
|
-
variant: "bar"
|
|
49851
|
+
error: idleTimeData.error
|
|
49837
49852
|
}
|
|
49838
49853
|
) })
|
|
49839
49854
|
] })
|
|
@@ -76453,7 +76468,7 @@ var formatComparisonWindow = ({
|
|
|
76453
76468
|
shiftMode
|
|
76454
76469
|
}) => {
|
|
76455
76470
|
if (comparisonStrategy === "previous_full_week") return "last week";
|
|
76456
|
-
if (comparisonStrategy === "matched_range" &&
|
|
76471
|
+
if (comparisonStrategy === "matched_range" && currentDayCount === 1 && previousDayCount === 1) {
|
|
76457
76472
|
return "previous day";
|
|
76458
76473
|
}
|
|
76459
76474
|
if (!previousDayCount || !Number.isFinite(previousDayCount)) return "previous range";
|
|
@@ -76476,8 +76491,14 @@ var buildDeltaBadge = (delta, options) => {
|
|
|
76476
76491
|
};
|
|
76477
76492
|
};
|
|
76478
76493
|
var normalizeShiftLabel = (shiftName, shiftMode) => {
|
|
76494
|
+
if (shiftMode === "all") {
|
|
76495
|
+
return "All Shifts";
|
|
76496
|
+
}
|
|
76479
76497
|
const trimmedName = shiftName?.trim();
|
|
76480
76498
|
if (trimmedName) {
|
|
76499
|
+
const normalizedName = trimmedName.toLowerCase();
|
|
76500
|
+
if (normalizedName === "day") return "Day Shift";
|
|
76501
|
+
if (normalizedName === "night") return "Night Shift";
|
|
76481
76502
|
return /shift/i.test(trimmedName) ? trimmedName : `${trimmedName} Shift`;
|
|
76482
76503
|
}
|
|
76483
76504
|
if (shiftMode === "night") return "Night Shift";
|
|
@@ -76486,6 +76507,9 @@ var normalizeShiftLabel = (shiftName, shiftMode) => {
|
|
|
76486
76507
|
var getShiftIcon = (shiftName, shiftMode) => {
|
|
76487
76508
|
const normalizedName = (shiftName || "").toLowerCase();
|
|
76488
76509
|
const normalizedMode = shiftMode || "day";
|
|
76510
|
+
if (normalizedMode === "all") {
|
|
76511
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" }) });
|
|
76512
|
+
}
|
|
76489
76513
|
if (normalizedName.includes("day") || normalizedName.includes("morning") || normalizedMode === "day") {
|
|
76490
76514
|
return /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
76491
76515
|
}
|
|
@@ -76564,6 +76588,7 @@ var OperationsOverviewHeader = React141__namespace.default.memo(({
|
|
|
76564
76588
|
}) => {
|
|
76565
76589
|
bumpRenderCounter();
|
|
76566
76590
|
const subtitleRange = displayDateRange || dateRange;
|
|
76591
|
+
const showLiveShiftMeta = isLiveScope && trendMode !== "all";
|
|
76567
76592
|
const liveShiftLabel = React141__namespace.default.useMemo(
|
|
76568
76593
|
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
76569
76594
|
[liveShiftName, trendMode]
|
|
@@ -76701,8 +76726,8 @@ var OperationsOverviewHeader = React141__namespace.default.memo(({
|
|
|
76701
76726
|
] }),
|
|
76702
76727
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 flex flex-wrap items-center justify-center gap-x-2 gap-y-1 text-[11px] font-medium text-slate-500 min-w-0", children: [
|
|
76703
76728
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-center", children: mobileSubtitle }),
|
|
76704
|
-
|
|
76705
|
-
|
|
76729
|
+
showLiveShiftMeta ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-300", children: "|" }) : null,
|
|
76730
|
+
showLiveShiftMeta ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": "operations-overview-live-meta", className: "inline-flex items-center gap-1.5 text-gray-600 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 justify-center truncate", children: [
|
|
76706
76731
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-75 shrink-0", children: liveShiftIcon }),
|
|
76707
76732
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: liveShiftLabel })
|
|
76708
76733
|
] }) }) : null
|
|
@@ -76749,7 +76774,7 @@ var OperationsOverviewHeader = React141__namespace.default.memo(({
|
|
|
76749
76774
|
] }),
|
|
76750
76775
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex flex-wrap items-center justify-center gap-x-3 gap-y-1 text-xs sm:text-sm font-medium text-slate-500 text-center", children: [
|
|
76751
76776
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: desktopSubtitle }),
|
|
76752
|
-
|
|
76777
|
+
showLiveShiftMeta ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
76753
76778
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-300", children: "|" }),
|
|
76754
76779
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": "operations-overview-live-meta", className: "inline-flex items-center gap-1.5 text-gray-600", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 justify-center", children: [
|
|
76755
76780
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-75", children: liveShiftIcon }),
|
|
@@ -77323,18 +77348,18 @@ var EfficiencyTrendCard = React141__namespace.default.memo(({
|
|
|
77323
77348
|
return (trend.data.points || []).map((point, index) => ({
|
|
77324
77349
|
name: (() => {
|
|
77325
77350
|
const rawLabel = point.label?.trim() || "";
|
|
77326
|
-
if (
|
|
77327
|
-
return rawLabel || `Hour ${index + 1}`;
|
|
77328
|
-
}
|
|
77329
|
-
if (rawLabel && !/^Hour\s+\d+$/i.test(rawLabel)) {
|
|
77351
|
+
if (rawLabel) {
|
|
77330
77352
|
return rawLabel;
|
|
77331
77353
|
}
|
|
77354
|
+
if (!hourlyLabelStartTime) {
|
|
77355
|
+
return "";
|
|
77356
|
+
}
|
|
77332
77357
|
const hourIndex = typeof point.hour_index === "number" ? point.hour_index : index;
|
|
77333
77358
|
const [hoursPart, minutesPart] = hourlyLabelStartTime.split(":");
|
|
77334
77359
|
const startHours = Number(hoursPart);
|
|
77335
77360
|
const startMinutes = Number(minutesPart);
|
|
77336
77361
|
if (!Number.isFinite(startHours) || !Number.isFinite(startMinutes)) {
|
|
77337
|
-
return
|
|
77362
|
+
return "";
|
|
77338
77363
|
}
|
|
77339
77364
|
const totalMinutes = startHours * 60 + startMinutes + hourIndex * 60;
|
|
77340
77365
|
const hour24 = Math.floor(totalMinutes / 60) % 24;
|
|
@@ -77396,6 +77421,12 @@ var EfficiencyTrendCard = React141__namespace.default.memo(({
|
|
|
77396
77421
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
77397
77422
|
return `${label} (${dayOfWeek})`;
|
|
77398
77423
|
}, [isHourlyTrend]);
|
|
77424
|
+
const trendXAxisTickFormatter = React141__namespace.default.useCallback((value, index) => {
|
|
77425
|
+
if (!isHourlyTrend) {
|
|
77426
|
+
return typeof value === "string" ? value : String(value ?? "");
|
|
77427
|
+
}
|
|
77428
|
+
return index % 2 === 0 ? typeof value === "string" ? value : String(value ?? "") : "";
|
|
77429
|
+
}, [isHourlyTrend]);
|
|
77399
77430
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-xl shadow-[0_2px_10px_-3px_rgba(6,81,237,0.1)] border border-slate-100 flex flex-col overflow-hidden text-left", children: [
|
|
77400
77431
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-5 flex-none flex justify-between items-center border-b border-slate-50/50", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-gray-700", children: "Efficiency Trend" }) }),
|
|
77401
77432
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-[250px] w-full p-4 pt-4 relative", children: showInitialSkeleton ? /* @__PURE__ */ jsxRuntime.jsx(OverviewChartSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 pb-2 pr-4 pl-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -77404,6 +77435,8 @@ var EfficiencyTrendCard = React141__namespace.default.memo(({
|
|
|
77404
77435
|
data: trendData,
|
|
77405
77436
|
lines: efficiencyLineConfig,
|
|
77406
77437
|
xAxisDataKey: "name",
|
|
77438
|
+
xAxisInterval: isHourlyTrend ? 0 : void 0,
|
|
77439
|
+
xAxisTickFormatter: trendXAxisTickFormatter,
|
|
77407
77440
|
yAxisUnit: "%",
|
|
77408
77441
|
yAxisDomain: [0, 100],
|
|
77409
77442
|
showLegend: false,
|
|
@@ -77909,6 +77942,62 @@ var classifyShiftBucket = ({
|
|
|
77909
77942
|
if (normalizedShiftId === 1) return "night";
|
|
77910
77943
|
return null;
|
|
77911
77944
|
};
|
|
77945
|
+
var getShiftWindowsForConfig = (shiftConfig, timezone) => {
|
|
77946
|
+
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
77947
|
+
return shiftConfig.shifts.map((shift) => ({
|
|
77948
|
+
shiftId: shift.shiftId,
|
|
77949
|
+
shiftName: shift.shiftName,
|
|
77950
|
+
startTime: shift.startTime,
|
|
77951
|
+
endTime: shift.endTime
|
|
77952
|
+
}));
|
|
77953
|
+
}
|
|
77954
|
+
const windows = [];
|
|
77955
|
+
if (shiftConfig?.dayShift) {
|
|
77956
|
+
windows.push({
|
|
77957
|
+
shiftId: shiftConfig.dayShift.id ?? 0,
|
|
77958
|
+
shiftName: shiftConfig.dayShift.name || "Day Shift",
|
|
77959
|
+
startTime: shiftConfig.dayShift.startTime || "06:00",
|
|
77960
|
+
endTime: shiftConfig.dayShift.endTime || "18:00"
|
|
77961
|
+
});
|
|
77962
|
+
}
|
|
77963
|
+
if (shiftConfig?.nightShift) {
|
|
77964
|
+
windows.push({
|
|
77965
|
+
shiftId: shiftConfig.nightShift.id ?? 1,
|
|
77966
|
+
shiftName: shiftConfig.nightShift.name || "Night Shift",
|
|
77967
|
+
startTime: shiftConfig.nightShift.startTime || "18:00",
|
|
77968
|
+
endTime: shiftConfig.nightShift.endTime || "06:00"
|
|
77969
|
+
});
|
|
77970
|
+
}
|
|
77971
|
+
if (windows.length > 0) {
|
|
77972
|
+
return windows;
|
|
77973
|
+
}
|
|
77974
|
+
return [
|
|
77975
|
+
{
|
|
77976
|
+
shiftId: 0,
|
|
77977
|
+
shiftName: "Day Shift",
|
|
77978
|
+
startTime: "06:00",
|
|
77979
|
+
endTime: "18:00"
|
|
77980
|
+
},
|
|
77981
|
+
{
|
|
77982
|
+
shiftId: 1,
|
|
77983
|
+
shiftName: "Night Shift",
|
|
77984
|
+
startTime: "18:00",
|
|
77985
|
+
endTime: "06:00"
|
|
77986
|
+
}
|
|
77987
|
+
];
|
|
77988
|
+
};
|
|
77989
|
+
var normalizeShiftWindowMinutes = (startTime, endTime) => {
|
|
77990
|
+
const startMinutes = parseTimeToMinutes3(startTime);
|
|
77991
|
+
const endMinutesRaw = parseTimeToMinutes3(endTime);
|
|
77992
|
+
if (startMinutes === null || endMinutesRaw === null) {
|
|
77993
|
+
return null;
|
|
77994
|
+
}
|
|
77995
|
+
let endMinutes = endMinutesRaw;
|
|
77996
|
+
if (endMinutes <= startMinutes) {
|
|
77997
|
+
endMinutes += 24 * 60;
|
|
77998
|
+
}
|
|
77999
|
+
return { startMinutes, endMinutes };
|
|
78000
|
+
};
|
|
77912
78001
|
var PlantHeadView = () => {
|
|
77913
78002
|
const supabase = useSupabase();
|
|
77914
78003
|
const entityConfig = useEntityConfig();
|
|
@@ -77934,6 +78023,7 @@ var PlantHeadView = () => {
|
|
|
77934
78023
|
const [selectedSupervisorId, setSelectedSupervisorId] = React141__namespace.default.useState("all");
|
|
77935
78024
|
const [selectedLineIds, setSelectedLineIds] = React141__namespace.default.useState([]);
|
|
77936
78025
|
const [isInitialScopeReady, setIsInitialScopeReady] = React141__namespace.default.useState(false);
|
|
78026
|
+
const [shiftResolutionTick, setShiftResolutionTick] = React141__namespace.default.useState(0);
|
|
77937
78027
|
const hasAutoInitializedScopeRef = React141__namespace.default.useRef(false);
|
|
77938
78028
|
const hasUserAdjustedScopeRef = React141__namespace.default.useRef(false);
|
|
77939
78029
|
React141__namespace.default.useEffect(() => {
|
|
@@ -78038,34 +78128,151 @@ var PlantHeadView = () => {
|
|
|
78038
78128
|
shiftConfigMap,
|
|
78039
78129
|
isLoading: isShiftConfigLoading
|
|
78040
78130
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
78041
|
-
|
|
78042
|
-
|
|
78043
|
-
|
|
78044
|
-
|
|
78045
|
-
|
|
78046
|
-
|
|
78047
|
-
|
|
78048
|
-
|
|
78049
|
-
|
|
78050
|
-
const referenceShiftConfig = referenceLineId ? shiftConfigMap.get(referenceLineId) : null;
|
|
78051
|
-
const normalizedGroupShiftId = normalizeShiftId(group.shiftId);
|
|
78052
|
-
const shiftDefinition = referenceShiftConfig?.shifts?.find((shift) => normalizeShiftId(shift.shiftId) === normalizedGroupShiftId);
|
|
78053
|
-
const resolvedMode = classifyShiftBucket({
|
|
78054
|
-
shiftName: group.shiftName,
|
|
78055
|
-
shiftId: normalizedGroupShiftId,
|
|
78056
|
-
startTime: shiftDefinition?.startTime,
|
|
78057
|
-
endTime: shiftDefinition?.endTime
|
|
78058
|
-
});
|
|
78059
|
-
if (!resolvedMode || resolvedMode === "all") return null;
|
|
78060
|
-
return {
|
|
78061
|
-
date: group.date,
|
|
78062
|
-
trendMode: resolvedMode,
|
|
78063
|
-
shiftName: shiftDefinition?.shiftName || group.shiftName || null
|
|
78131
|
+
React141__namespace.default.useEffect(() => {
|
|
78132
|
+
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
78133
|
+
return;
|
|
78134
|
+
}
|
|
78135
|
+
const intervalId = window.setInterval(() => {
|
|
78136
|
+
setShiftResolutionTick((previous) => previous + 1);
|
|
78137
|
+
}, 6e4);
|
|
78138
|
+
return () => {
|
|
78139
|
+
clearInterval(intervalId);
|
|
78064
78140
|
};
|
|
78065
|
-
}, [
|
|
78141
|
+
}, [isShiftConfigLoading, scopedLineIds.length]);
|
|
78142
|
+
const shiftResolutionNow = React141__namespace.default.useMemo(
|
|
78143
|
+
() => /* @__PURE__ */ new Date(),
|
|
78144
|
+
[shiftResolutionTick]
|
|
78145
|
+
);
|
|
78146
|
+
const earliestDayShiftStartTime = React141__namespace.default.useMemo(() => {
|
|
78147
|
+
const candidateStarts = [];
|
|
78148
|
+
scopedLineIds.forEach((lineId) => {
|
|
78149
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78150
|
+
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
78151
|
+
const bucket = classifyShiftBucket({
|
|
78152
|
+
shiftName: shift.shiftName,
|
|
78153
|
+
shiftId: shift.shiftId,
|
|
78154
|
+
startTime: shift.startTime,
|
|
78155
|
+
endTime: shift.endTime
|
|
78156
|
+
});
|
|
78157
|
+
const startMinutes = parseTimeToMinutes3(shift.startTime);
|
|
78158
|
+
if (bucket === "day" && startMinutes !== null) {
|
|
78159
|
+
candidateStarts.push(startMinutes);
|
|
78160
|
+
}
|
|
78161
|
+
});
|
|
78162
|
+
});
|
|
78163
|
+
if (candidateStarts.length === 0) {
|
|
78164
|
+
scopedLineIds.forEach((lineId) => {
|
|
78165
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78166
|
+
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
78167
|
+
const startMinutes = parseTimeToMinutes3(shift.startTime);
|
|
78168
|
+
if (startMinutes !== null) {
|
|
78169
|
+
candidateStarts.push(startMinutes);
|
|
78170
|
+
}
|
|
78171
|
+
});
|
|
78172
|
+
});
|
|
78173
|
+
}
|
|
78174
|
+
if (candidateStarts.length === 0) {
|
|
78175
|
+
return "06:00";
|
|
78176
|
+
}
|
|
78177
|
+
const earliestMinutes = Math.min(...candidateStarts);
|
|
78178
|
+
const hours = Math.floor(earliestMinutes / 60);
|
|
78179
|
+
const minutes = earliestMinutes % 60;
|
|
78180
|
+
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
78181
|
+
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
78182
|
+
const resolvedOperationalToday = React141__namespace.default.useMemo(
|
|
78183
|
+
() => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
|
|
78184
|
+
[appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
|
|
78185
|
+
);
|
|
78186
|
+
const activeLineShiftStates = React141__namespace.default.useMemo(() => {
|
|
78187
|
+
return scopedLineIds.flatMap((lineId) => {
|
|
78188
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78189
|
+
const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
|
|
78190
|
+
if (!activeShift) {
|
|
78191
|
+
return [];
|
|
78192
|
+
}
|
|
78193
|
+
const trendBucket = classifyShiftBucket({
|
|
78194
|
+
shiftName: activeShift.shiftName,
|
|
78195
|
+
shiftId: activeShift.shiftId,
|
|
78196
|
+
startTime: activeShift.startTime,
|
|
78197
|
+
endTime: activeShift.endTime
|
|
78198
|
+
});
|
|
78199
|
+
if (!trendBucket || trendBucket === "all") {
|
|
78200
|
+
return [];
|
|
78201
|
+
}
|
|
78202
|
+
return [{
|
|
78203
|
+
lineId,
|
|
78204
|
+
trendMode: trendBucket,
|
|
78205
|
+
shiftId: activeShift.shiftId,
|
|
78206
|
+
shiftName: activeShift.shiftName || null,
|
|
78207
|
+
startTime: activeShift.startTime || null,
|
|
78208
|
+
endTime: activeShift.endTime || null,
|
|
78209
|
+
date: activeShift.date
|
|
78210
|
+
}];
|
|
78211
|
+
});
|
|
78212
|
+
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
78213
|
+
const hasActiveDayShiftLine = React141__namespace.default.useMemo(
|
|
78214
|
+
() => activeLineShiftStates.some((shift) => shift.trendMode === "day" && shift.date === resolvedOperationalToday),
|
|
78215
|
+
[activeLineShiftStates, resolvedOperationalToday]
|
|
78216
|
+
);
|
|
78217
|
+
const hasActiveNightShiftLine = React141__namespace.default.useMemo(
|
|
78218
|
+
() => activeLineShiftStates.some((shift) => shift.trendMode === "night" && shift.date === resolvedOperationalToday),
|
|
78219
|
+
[activeLineShiftStates, resolvedOperationalToday]
|
|
78220
|
+
);
|
|
78221
|
+
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
78222
|
+
const hourlyWindowStartTime = React141__namespace.default.useMemo(() => {
|
|
78223
|
+
if (scopedLineIds.length === 0) {
|
|
78224
|
+
return null;
|
|
78225
|
+
}
|
|
78226
|
+
const startCandidates = [];
|
|
78227
|
+
const endCandidates = [];
|
|
78228
|
+
scopedLineIds.forEach((lineId) => {
|
|
78229
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78230
|
+
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
78231
|
+
const bucket = classifyShiftBucket({
|
|
78232
|
+
shiftName: shift.shiftName,
|
|
78233
|
+
shiftId: shift.shiftId,
|
|
78234
|
+
startTime: shift.startTime,
|
|
78235
|
+
endTime: shift.endTime
|
|
78236
|
+
});
|
|
78237
|
+
if (resolvedTrendMode !== "all" && bucket !== resolvedTrendMode) {
|
|
78238
|
+
return;
|
|
78239
|
+
}
|
|
78240
|
+
const normalizedWindow = normalizeShiftWindowMinutes(shift.startTime, shift.endTime);
|
|
78241
|
+
if (!normalizedWindow) {
|
|
78242
|
+
return;
|
|
78243
|
+
}
|
|
78244
|
+
startCandidates.push(normalizedWindow.startMinutes);
|
|
78245
|
+
endCandidates.push(normalizedWindow.endMinutes);
|
|
78246
|
+
});
|
|
78247
|
+
});
|
|
78248
|
+
if (resolvedTrendMode === "all") {
|
|
78249
|
+
const dayStartCandidates = startCandidates.length > 0 ? scopedLineIds.flatMap((lineId) => {
|
|
78250
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78251
|
+
return getShiftWindowsForConfig(shiftConfig).map((shift) => {
|
|
78252
|
+
const bucket = classifyShiftBucket({
|
|
78253
|
+
shiftName: shift.shiftName,
|
|
78254
|
+
shiftId: shift.shiftId,
|
|
78255
|
+
startTime: shift.startTime,
|
|
78256
|
+
endTime: shift.endTime
|
|
78257
|
+
});
|
|
78258
|
+
return bucket === "day" ? parseTimeToMinutes3(shift.startTime) : null;
|
|
78259
|
+
}).filter((value) => value !== null);
|
|
78260
|
+
}) : [];
|
|
78261
|
+
if (dayStartCandidates.length > 0) {
|
|
78262
|
+
startCandidates.splice(0, startCandidates.length, ...dayStartCandidates);
|
|
78263
|
+
}
|
|
78264
|
+
}
|
|
78265
|
+
if (startCandidates.length === 0 || endCandidates.length === 0) {
|
|
78266
|
+
return null;
|
|
78267
|
+
}
|
|
78268
|
+
const earliestMinutes = Math.min(...startCandidates);
|
|
78269
|
+
const hours = Math.floor(earliestMinutes / 60);
|
|
78270
|
+
const minutes = earliestMinutes % 60;
|
|
78271
|
+
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
78272
|
+
}, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
78066
78273
|
const isShiftScopeResolved = React141__namespace.default.useMemo(
|
|
78067
|
-
() => !isShiftConfigLoading
|
|
78068
|
-
[
|
|
78274
|
+
() => !isShiftConfigLoading,
|
|
78275
|
+
[isShiftConfigLoading]
|
|
78069
78276
|
);
|
|
78070
78277
|
const initializedTimezoneRef = React141__namespace.default.useRef(appTimezone);
|
|
78071
78278
|
React141__namespace.default.useEffect(() => {
|
|
@@ -78092,7 +78299,7 @@ var PlantHeadView = () => {
|
|
|
78092
78299
|
return;
|
|
78093
78300
|
}
|
|
78094
78301
|
setDateRange((previous) => {
|
|
78095
|
-
const nextStartKey =
|
|
78302
|
+
const nextStartKey = resolvedOperationalToday || fallbackOperationalDate;
|
|
78096
78303
|
if (previous.startKey === nextStartKey && previous.endKey === nextStartKey) {
|
|
78097
78304
|
return previous;
|
|
78098
78305
|
}
|
|
@@ -78101,11 +78308,11 @@ var PlantHeadView = () => {
|
|
|
78101
78308
|
endKey: nextStartKey
|
|
78102
78309
|
};
|
|
78103
78310
|
});
|
|
78104
|
-
setTrendMode(
|
|
78311
|
+
setTrendMode("all");
|
|
78105
78312
|
setUsesThisWeekComparison(false);
|
|
78106
78313
|
hasAutoInitializedScopeRef.current = true;
|
|
78107
78314
|
setIsInitialScopeReady(true);
|
|
78108
|
-
}, [
|
|
78315
|
+
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
78109
78316
|
const handleDateRangeChange = React141__namespace.default.useCallback((range, meta) => {
|
|
78110
78317
|
hasUserAdjustedScopeRef.current = true;
|
|
78111
78318
|
setIsInitialScopeReady(true);
|
|
@@ -78182,45 +78389,36 @@ var PlantHeadView = () => {
|
|
|
78182
78389
|
if (isInitialScopeReady) {
|
|
78183
78390
|
return dateRange;
|
|
78184
78391
|
}
|
|
78185
|
-
const nextStartKey =
|
|
78392
|
+
const nextStartKey = resolvedOperationalToday || fallbackOperationalDate;
|
|
78186
78393
|
return {
|
|
78187
78394
|
startKey: nextStartKey,
|
|
78188
78395
|
endKey: nextStartKey
|
|
78189
78396
|
};
|
|
78190
|
-
}, [
|
|
78397
|
+
}, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
|
|
78191
78398
|
const effectiveTrendMode = React141__namespace.default.useMemo(
|
|
78192
|
-
() =>
|
|
78193
|
-
[
|
|
78399
|
+
() => resolvedTrendMode,
|
|
78400
|
+
[resolvedTrendMode]
|
|
78194
78401
|
);
|
|
78195
78402
|
const hourlyLabelStartTime = React141__namespace.default.useMemo(() => {
|
|
78196
|
-
if (
|
|
78197
|
-
return null;
|
|
78198
|
-
}
|
|
78199
|
-
const shiftStartTimes = /* @__PURE__ */ new Set();
|
|
78200
|
-
scopedLineIds.forEach((lineId) => {
|
|
78201
|
-
const shiftConfig = shiftConfigMap.get(lineId);
|
|
78202
|
-
const matchingShift = shiftConfig?.shifts?.find((shift) => classifyShiftBucket({
|
|
78203
|
-
shiftName: shift.shiftName,
|
|
78204
|
-
shiftId: shift.shiftId,
|
|
78205
|
-
startTime: shift.startTime,
|
|
78206
|
-
endTime: shift.endTime
|
|
78207
|
-
}) === effectiveTrendMode);
|
|
78208
|
-
if (matchingShift?.startTime) {
|
|
78209
|
-
shiftStartTimes.add(matchingShift.startTime);
|
|
78210
|
-
}
|
|
78211
|
-
});
|
|
78212
|
-
if (shiftStartTimes.size !== 1) {
|
|
78403
|
+
if (scopedLineIds.length === 0) {
|
|
78213
78404
|
return null;
|
|
78214
78405
|
}
|
|
78215
|
-
return
|
|
78216
|
-
}, [
|
|
78217
|
-
const
|
|
78218
|
-
() => effectiveDateRange.startKey === effectiveDateRange.endKey
|
|
78219
|
-
[effectiveDateRange.endKey, effectiveDateRange.startKey
|
|
78406
|
+
return hourlyWindowStartTime;
|
|
78407
|
+
}, [hourlyWindowStartTime, scopedLineIds.length]);
|
|
78408
|
+
const isSingleDayScope = React141__namespace.default.useMemo(
|
|
78409
|
+
() => effectiveDateRange.startKey === effectiveDateRange.endKey,
|
|
78410
|
+
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
78220
78411
|
);
|
|
78221
78412
|
const isLiveScope = React141__namespace.default.useMemo(
|
|
78222
|
-
() =>
|
|
78223
|
-
[
|
|
78413
|
+
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && (effectiveTrendMode === "all" || effectiveTrendMode === "day" && hasActiveDayShiftLine || effectiveTrendMode === "night" && hasActiveNightShiftLine),
|
|
78414
|
+
[
|
|
78415
|
+
effectiveDateRange.startKey,
|
|
78416
|
+
effectiveTrendMode,
|
|
78417
|
+
hasActiveDayShiftLine,
|
|
78418
|
+
hasActiveNightShiftLine,
|
|
78419
|
+
isSingleDayScope,
|
|
78420
|
+
resolvedOperationalToday
|
|
78421
|
+
]
|
|
78224
78422
|
);
|
|
78225
78423
|
const handleOpenLineDetails = React141__namespace.default.useCallback((lineId, lineName) => {
|
|
78226
78424
|
trackCoreEvent("Operations Overview Line Clicked", {
|
|
@@ -78255,7 +78453,7 @@ var PlantHeadView = () => {
|
|
|
78255
78453
|
displayDateRange: headerDateRange,
|
|
78256
78454
|
trendMode,
|
|
78257
78455
|
isLiveScope,
|
|
78258
|
-
liveShiftName:
|
|
78456
|
+
liveShiftName: isLiveScope && trendMode !== "all" ? trendMode : null,
|
|
78259
78457
|
lineOptions,
|
|
78260
78458
|
supervisorOptions,
|
|
78261
78459
|
selectedSupervisorId,
|
|
@@ -79086,6 +79284,7 @@ exports.formatRelativeTime = formatRelativeTime;
|
|
|
79086
79284
|
exports.formatTimeInZone = formatTimeInZone;
|
|
79087
79285
|
exports.fromUrlFriendlyName = fromUrlFriendlyName;
|
|
79088
79286
|
exports.getActionDisplayName = getActionDisplayName;
|
|
79287
|
+
exports.getActiveShift = getActiveShift;
|
|
79089
79288
|
exports.getAllLineDisplayNames = getAllLineDisplayNames;
|
|
79090
79289
|
exports.getAllThreadMessages = getAllThreadMessages;
|
|
79091
79290
|
exports.getAllWorkspaceDisplayNamesAsync = getAllWorkspaceDisplayNamesAsync;
|