@optifye/dashboard-core 6.12.23 → 6.12.26
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 +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +335 -41
- package/dist/index.mjs +335 -41
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14615,6 +14615,32 @@ function getEfficiencyTextColorClasses(efficiency, legend = DEFAULT_EFFICIENCY_L
|
|
|
14615
14615
|
}
|
|
14616
14616
|
}
|
|
14617
14617
|
|
|
14618
|
+
// src/lib/utils/qaGreenStreakParams.ts
|
|
14619
|
+
var QA_GREEN_STREAK_QUERY_PARAM_NAMES = [
|
|
14620
|
+
"qa_green_streak_started_at",
|
|
14621
|
+
"qa_green_streak_elapsed_seconds",
|
|
14622
|
+
"qa_green_streak_status"
|
|
14623
|
+
];
|
|
14624
|
+
var isTruthyEnv = (value) => ["1", "true", "yes", "on"].includes(String(value || "").trim().toLowerCase());
|
|
14625
|
+
var isQaGreenStreakForwardingEnabled = () => isTruthyEnv(process.env.NEXT_PUBLIC_DASHBOARD_QA_GREEN_STREAK_OVERRIDE_ENABLED);
|
|
14626
|
+
var appendQaGreenStreakSearchParams = (targetParams) => {
|
|
14627
|
+
if (!isQaGreenStreakForwardingEnabled() || typeof window === "undefined") {
|
|
14628
|
+
return;
|
|
14629
|
+
}
|
|
14630
|
+
const sourceParams = new URLSearchParams(window.location.search);
|
|
14631
|
+
QA_GREEN_STREAK_QUERY_PARAM_NAMES.forEach((paramName) => {
|
|
14632
|
+
const value = sourceParams.get(paramName);
|
|
14633
|
+
if (value !== null) {
|
|
14634
|
+
targetParams.set(paramName, value);
|
|
14635
|
+
}
|
|
14636
|
+
});
|
|
14637
|
+
};
|
|
14638
|
+
var getQaGreenStreakQueryString = () => {
|
|
14639
|
+
const params = new URLSearchParams();
|
|
14640
|
+
appendQaGreenStreakSearchParams(params);
|
|
14641
|
+
return params.toString();
|
|
14642
|
+
};
|
|
14643
|
+
|
|
14618
14644
|
// src/lib/utils/monitorWorkspaceMetrics.ts
|
|
14619
14645
|
var sortWorkspaceMetrics = (left, right) => {
|
|
14620
14646
|
if (left.line_id !== right.line_id) {
|
|
@@ -14961,10 +14987,12 @@ var useDashboardMetrics = ({
|
|
|
14961
14987
|
let idleTimeVlmByLine = {};
|
|
14962
14988
|
let efficiencyLegend;
|
|
14963
14989
|
const forceParam = force ? "&force_refresh=true" : "";
|
|
14990
|
+
const qaGreenStreakParamString = getQaGreenStreakQueryString();
|
|
14991
|
+
const qaGreenStreakParams = qaGreenStreakParamString ? `&${qaGreenStreakParamString}` : "";
|
|
14964
14992
|
const buildMetricsEndpoint = (params) => {
|
|
14965
14993
|
const lineIdsParam = isFactory ? `line_ids=${params.groupLineIds.join(",")}` : `line_id=${params.groupLineIds[0]}`;
|
|
14966
14994
|
const blueComparisonParam = effectiveBlueComparisonLineIds.length ? `&blue_comparison_line_ids=${effectiveBlueComparisonLineIds.join(",")}` : "";
|
|
14967
|
-
return `/api/dashboard/metrics?${lineIdsParam}${blueComparisonParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}`;
|
|
14995
|
+
return `/api/dashboard/metrics?${lineIdsParam}${blueComparisonParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}${qaGreenStreakParams}`;
|
|
14968
14996
|
};
|
|
14969
14997
|
if (usesShiftGroups) {
|
|
14970
14998
|
logDebug("[useDashboardMetrics] Factory view shift groups fetch:", {
|
|
@@ -36118,6 +36146,37 @@ var interpretIdleValue = (value) => {
|
|
|
36118
36146
|
if (value === "x" || value === null || value === void 0) return "unknown";
|
|
36119
36147
|
return "unknown";
|
|
36120
36148
|
};
|
|
36149
|
+
var timeToMinutes = (value) => {
|
|
36150
|
+
const parsed = parseTime(value);
|
|
36151
|
+
if (!parsed) return null;
|
|
36152
|
+
return parsed.hour * 60 + parsed.minute;
|
|
36153
|
+
};
|
|
36154
|
+
var normalizeBreaksOnShiftTimeline2 = (shiftStart, shiftBreaks) => {
|
|
36155
|
+
const shiftStartMinutes = timeToMinutes(shiftStart);
|
|
36156
|
+
if (shiftStartMinutes === null || !Array.isArray(shiftBreaks)) {
|
|
36157
|
+
return [];
|
|
36158
|
+
}
|
|
36159
|
+
return shiftBreaks.flatMap((entry) => {
|
|
36160
|
+
const startRaw = timeToMinutes(entry?.startTime ?? entry?.start);
|
|
36161
|
+
const endRaw = timeToMinutes(entry?.endTime ?? entry?.end);
|
|
36162
|
+
if (startRaw === null || endRaw === null) return [];
|
|
36163
|
+
let start = startRaw;
|
|
36164
|
+
let end = endRaw;
|
|
36165
|
+
if (end <= start) {
|
|
36166
|
+
end += 24 * 60;
|
|
36167
|
+
}
|
|
36168
|
+
if (start < shiftStartMinutes) {
|
|
36169
|
+
start += 24 * 60;
|
|
36170
|
+
end += 24 * 60;
|
|
36171
|
+
}
|
|
36172
|
+
return [{ start, end }];
|
|
36173
|
+
});
|
|
36174
|
+
};
|
|
36175
|
+
var isBreakMinute = (minuteIndex, shiftStartMinutes, normalizedBreaks) => {
|
|
36176
|
+
if (!normalizedBreaks.length) return false;
|
|
36177
|
+
const absoluteMinute = shiftStartMinutes + minuteIndex;
|
|
36178
|
+
return normalizedBreaks.some((entry) => entry.start <= absoluteMinute && absoluteMinute < entry.end);
|
|
36179
|
+
};
|
|
36121
36180
|
var getShiftDurationMinutes = (shiftStart, shiftEnd) => {
|
|
36122
36181
|
const start = parseTime(shiftStart);
|
|
36123
36182
|
const end = parseTime(shiftEnd);
|
|
@@ -36128,6 +36187,29 @@ var getShiftDurationMinutes = (shiftStart, shiftEnd) => {
|
|
|
36128
36187
|
}
|
|
36129
36188
|
return duration > 0 ? duration : null;
|
|
36130
36189
|
};
|
|
36190
|
+
var getBreakExcludedShiftMinutes = ({
|
|
36191
|
+
shiftStart,
|
|
36192
|
+
shiftEnd,
|
|
36193
|
+
elapsedMinutes,
|
|
36194
|
+
shiftBreaks
|
|
36195
|
+
}) => {
|
|
36196
|
+
const shiftMinutes = getShiftDurationMinutes(shiftStart, shiftEnd);
|
|
36197
|
+
if (shiftMinutes === null) return null;
|
|
36198
|
+
const elapsedLimit = Number.isFinite(elapsedMinutes) ? Math.min(Math.max(Math.floor(elapsedMinutes ?? 0), 0), shiftMinutes) : shiftMinutes;
|
|
36199
|
+
if (elapsedLimit <= 0) return 0;
|
|
36200
|
+
const startTime = parseTime(shiftStart);
|
|
36201
|
+
if (!startTime) return elapsedLimit;
|
|
36202
|
+
const shiftStartMinutes = startTime.hour * 60 + startTime.minute;
|
|
36203
|
+
const normalizedBreaks = normalizeBreaksOnShiftTimeline2(shiftStart, shiftBreaks);
|
|
36204
|
+
if (!normalizedBreaks.length) return elapsedLimit;
|
|
36205
|
+
let workingMinutes = 0;
|
|
36206
|
+
for (let minuteIndex = 0; minuteIndex < elapsedLimit; minuteIndex += 1) {
|
|
36207
|
+
if (!isBreakMinute(minuteIndex, shiftStartMinutes, normalizedBreaks)) {
|
|
36208
|
+
workingMinutes += 1;
|
|
36209
|
+
}
|
|
36210
|
+
}
|
|
36211
|
+
return workingMinutes;
|
|
36212
|
+
};
|
|
36131
36213
|
var getShiftElapsedMinutes = ({
|
|
36132
36214
|
shiftStart,
|
|
36133
36215
|
shiftEnd,
|
|
@@ -36192,7 +36274,8 @@ var buildUptimeSeries = ({
|
|
|
36192
36274
|
shiftEnd,
|
|
36193
36275
|
shiftDate,
|
|
36194
36276
|
timezone,
|
|
36195
|
-
elapsedMinutes
|
|
36277
|
+
elapsedMinutes,
|
|
36278
|
+
shiftBreaks
|
|
36196
36279
|
}) => {
|
|
36197
36280
|
const normalizedIdle = normalizeIdleTimeHourly(idleTimeHourly || {});
|
|
36198
36281
|
const hasIdleData = Object.keys(normalizedIdle).length > 0;
|
|
@@ -36247,6 +36330,8 @@ var buildUptimeSeries = ({
|
|
|
36247
36330
|
const points = [];
|
|
36248
36331
|
let activeMinutes = 0;
|
|
36249
36332
|
let idleMinutes = 0;
|
|
36333
|
+
const shiftStartMinutes = startTime.hour * 60 + startTime.minute;
|
|
36334
|
+
const normalizedBreaks = normalizeBreaksOnShiftTimeline2(shiftStart, shiftBreaks);
|
|
36250
36335
|
for (let minuteIndex = 0; minuteIndex < shiftMinutes; minuteIndex += 1) {
|
|
36251
36336
|
const minuteDate = dateFns.addMinutes(shiftStartDate, minuteIndex);
|
|
36252
36337
|
const timeLabel = dateFnsTz.formatInTimeZone(minuteDate, timezone, "h:mm a");
|
|
@@ -36259,6 +36344,15 @@ var buildUptimeSeries = ({
|
|
|
36259
36344
|
});
|
|
36260
36345
|
continue;
|
|
36261
36346
|
}
|
|
36347
|
+
if (isBreakMinute(minuteIndex, shiftStartMinutes, normalizedBreaks)) {
|
|
36348
|
+
points.push({
|
|
36349
|
+
minuteIndex,
|
|
36350
|
+
timeLabel,
|
|
36351
|
+
uptime: null,
|
|
36352
|
+
status: "break"
|
|
36353
|
+
});
|
|
36354
|
+
continue;
|
|
36355
|
+
}
|
|
36262
36356
|
const hourKey = dateFnsTz.formatInTimeZone(minuteDate, timezone, "H");
|
|
36263
36357
|
const minuteKey = Number.parseInt(dateFnsTz.formatInTimeZone(minuteDate, timezone, "m"), 10);
|
|
36264
36358
|
const hourBucket = normalizedIdle[hourKey] || [];
|
|
@@ -37820,12 +37914,10 @@ var getAllVideoGridGreenStreakDisplay = (workspaces, legend = DEFAULT_EFFICIENCY
|
|
|
37820
37914
|
const startedAt = workspace.video_grid_green_streak_started_at;
|
|
37821
37915
|
const anchorAt = workspace.video_grid_green_streak_anchor_at;
|
|
37822
37916
|
const streakMinutes = workspace.video_grid_green_streak_minutes;
|
|
37823
|
-
const computedAt = workspace.recent_flow_computed_at;
|
|
37824
37917
|
const startedAtMs = parseTimestampMs(startedAt);
|
|
37825
37918
|
const anchorAtMs = parseTimestampMs(anchorAt);
|
|
37826
|
-
const computedAtMs = typeof computedAt === "string" && computedAt.trim() ? parseTimestampMs(computedAt) : Number.NaN;
|
|
37827
37919
|
const isFresh = isAllGreenStreakFresh(workspace, anchorAtMs, nowMs2);
|
|
37828
|
-
const tickOriginAtMs =
|
|
37920
|
+
const tickOriginAtMs = anchorAtMs + CONFIRMED_MINUTE_DURATION_MS;
|
|
37829
37921
|
if (workspace.video_grid_green_streak_active === true && isFiniteNumber3(streakMinutes) && streakMinutes > 0 && startedAt && anchorAt && Number.isFinite(startedAtMs) && isFresh) {
|
|
37830
37922
|
return {
|
|
37831
37923
|
startedAt,
|
|
@@ -39421,6 +39513,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
39421
39513
|
shiftDate,
|
|
39422
39514
|
timezone,
|
|
39423
39515
|
elapsedMinutes,
|
|
39516
|
+
shiftBreaks,
|
|
39424
39517
|
className = ""
|
|
39425
39518
|
}) => {
|
|
39426
39519
|
const containerRef = React144__namespace.default.useRef(null);
|
|
@@ -39432,8 +39525,9 @@ var HourlyUptimeChartComponent = ({
|
|
|
39432
39525
|
shiftEnd,
|
|
39433
39526
|
shiftDate,
|
|
39434
39527
|
timezone,
|
|
39435
|
-
elapsedMinutes
|
|
39436
|
-
|
|
39528
|
+
elapsedMinutes,
|
|
39529
|
+
shiftBreaks
|
|
39530
|
+
}), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes, shiftBreaks]);
|
|
39437
39531
|
const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
|
|
39438
39532
|
const shiftStartTime = React144__namespace.default.useMemo(
|
|
39439
39533
|
() => getTimeFromTimeString(shiftStart),
|
|
@@ -51625,7 +51719,8 @@ var LineMonthlyPdfGenerator = ({
|
|
|
51625
51719
|
};
|
|
51626
51720
|
var LineWhatsAppShareButton = ({
|
|
51627
51721
|
lineInfo,
|
|
51628
|
-
className
|
|
51722
|
+
className,
|
|
51723
|
+
shiftBreaks = []
|
|
51629
51724
|
}) => {
|
|
51630
51725
|
const handleShare = () => {
|
|
51631
51726
|
trackCoreEvent("Line WhatsApp Share Clicked", {
|
|
@@ -51639,7 +51734,8 @@ var LineWhatsAppShareButton = ({
|
|
|
51639
51734
|
shiftStart: lineInfo.metrics.shift_start,
|
|
51640
51735
|
shiftEnd: lineInfo.metrics.shift_end,
|
|
51641
51736
|
shiftDate: lineInfo.date,
|
|
51642
|
-
timezone: "Asia/Kolkata"
|
|
51737
|
+
timezone: "Asia/Kolkata",
|
|
51738
|
+
shiftBreaks
|
|
51643
51739
|
}) : null;
|
|
51644
51740
|
const efficiencyValue = Number.isFinite(lineInfo.metrics.avg_efficiency) ? Number(lineInfo.metrics.avg_efficiency) : null;
|
|
51645
51741
|
const utilization = efficiencyValue !== null ? efficiencyValue : uptimeSeries && uptimeSeries.availableMinutes > 0 ? uptimeSeries.activeMinutes / uptimeSeries.availableMinutes * 100 : 0;
|
|
@@ -51808,16 +51904,24 @@ var LinePdfGenerator = ({
|
|
|
51808
51904
|
shiftStart,
|
|
51809
51905
|
shiftEnd,
|
|
51810
51906
|
shiftDate,
|
|
51811
|
-
timezone: effectiveUptimeTimezone
|
|
51907
|
+
timezone: effectiveUptimeTimezone,
|
|
51908
|
+
shiftBreaks
|
|
51812
51909
|
});
|
|
51813
51910
|
let activeMinutes = uptimeSeries.activeMinutes;
|
|
51814
51911
|
let idleMinutes = uptimeSeries.idleMinutes;
|
|
51815
51912
|
let availableMinutes = uptimeSeries.availableMinutes;
|
|
51816
51913
|
let hasData = uptimeSeries.hasData;
|
|
51817
|
-
|
|
51914
|
+
const hasIdleHourlyPayload = Boolean(
|
|
51915
|
+
workspace.idle_time_hourly && typeof workspace.idle_time_hourly === "object" && Object.keys(workspace.idle_time_hourly).length > 0
|
|
51916
|
+
);
|
|
51917
|
+
if (!hasData && !hasIdleHourlyPayload) {
|
|
51818
51918
|
const idleTimeValue = workspace.idle_time;
|
|
51819
51919
|
const hasIdleTimeValue = Number.isFinite(idleTimeValue);
|
|
51820
|
-
const fallbackDuration =
|
|
51920
|
+
const fallbackDuration = getBreakExcludedShiftMinutes({
|
|
51921
|
+
shiftStart,
|
|
51922
|
+
shiftEnd,
|
|
51923
|
+
shiftBreaks
|
|
51924
|
+
}) ?? shiftDurationMinutes;
|
|
51821
51925
|
if (hasIdleTimeValue && idleTimeValue > 0 && fallbackDuration > 0) {
|
|
51822
51926
|
const idleFromAggregate = Math.min(Math.max(Number(idleTimeValue) / 60, 0), fallbackDuration);
|
|
51823
51927
|
idleMinutes = idleFromAggregate;
|
|
@@ -51889,7 +51993,8 @@ var LinePdfGenerator = ({
|
|
|
51889
51993
|
shiftStart: lineShiftStart,
|
|
51890
51994
|
shiftEnd: lineShiftEnd,
|
|
51891
51995
|
shiftDate: lineInfo.date,
|
|
51892
|
-
timezone: effectiveUptimeTimezone
|
|
51996
|
+
timezone: effectiveUptimeTimezone,
|
|
51997
|
+
shiftBreaks
|
|
51893
51998
|
});
|
|
51894
51999
|
hourlyData = buildHourlyFromSeries(lineUptimeSeries);
|
|
51895
52000
|
}
|
|
@@ -53828,7 +53933,8 @@ var WorkspaceMonthlyHistory = ({
|
|
|
53828
53933
|
};
|
|
53829
53934
|
var WorkspaceWhatsAppShareButton = ({
|
|
53830
53935
|
workspace,
|
|
53831
|
-
className
|
|
53936
|
+
className,
|
|
53937
|
+
shiftBreaks = []
|
|
53832
53938
|
}) => {
|
|
53833
53939
|
const handleShare = () => {
|
|
53834
53940
|
trackCoreEvent("Workspace WhatsApp Share Clicked", {
|
|
@@ -53844,7 +53950,11 @@ var WorkspaceWhatsAppShareButton = ({
|
|
|
53844
53950
|
timeZone: "Asia/Kolkata"
|
|
53845
53951
|
});
|
|
53846
53952
|
const isUptimeMode = workspace.monitoring_mode === "uptime";
|
|
53847
|
-
const shiftMinutes =
|
|
53953
|
+
const shiftMinutes = getBreakExcludedShiftMinutes({
|
|
53954
|
+
shiftStart: workspace.shift_start,
|
|
53955
|
+
shiftEnd: workspace.shift_end,
|
|
53956
|
+
shiftBreaks
|
|
53957
|
+
}) ?? getShiftDurationMinutes(workspace.shift_start, workspace.shift_end);
|
|
53848
53958
|
const shiftSeconds = shiftMinutes ? shiftMinutes * 60 : 0;
|
|
53849
53959
|
const idleSeconds = Math.max(workspace.idle_time || 0, 0);
|
|
53850
53960
|
const clampedIdleSeconds = shiftSeconds > 0 ? Math.min(idleSeconds, shiftSeconds) : idleSeconds;
|
|
@@ -53934,7 +54044,11 @@ var WorkspacePdfGenerator = ({
|
|
|
53934
54044
|
try {
|
|
53935
54045
|
const isUptimeMode = workspace.monitoring_mode === "uptime";
|
|
53936
54046
|
const isAssemblyCycleMode = !isUptimeMode && shouldUseAssemblyCycleTimeLayout(workspace);
|
|
53937
|
-
const shiftMinutes =
|
|
54047
|
+
const shiftMinutes = getBreakExcludedShiftMinutes({
|
|
54048
|
+
shiftStart: workspace.shift_start,
|
|
54049
|
+
shiftEnd: workspace.shift_end,
|
|
54050
|
+
shiftBreaks
|
|
54051
|
+
}) ?? getShiftDurationMinutes(workspace.shift_start, workspace.shift_end);
|
|
53938
54052
|
const shiftSeconds = shiftMinutes ? shiftMinutes * 60 : 0;
|
|
53939
54053
|
const idleSeconds = Math.max(workspace.idle_time || 0, 0);
|
|
53940
54054
|
const clampedIdleSeconds = shiftSeconds > 0 ? Math.min(idleSeconds, shiftSeconds) : idleSeconds;
|
|
@@ -54104,7 +54218,8 @@ var WorkspacePdfGenerator = ({
|
|
|
54104
54218
|
shiftStart: workspace.shift_start,
|
|
54105
54219
|
shiftEnd: workspace.shift_end,
|
|
54106
54220
|
shiftDate: workspace.date,
|
|
54107
|
-
timezone: reportTimezone
|
|
54221
|
+
timezone: reportTimezone,
|
|
54222
|
+
shiftBreaks
|
|
54108
54223
|
}) : null;
|
|
54109
54224
|
const hourlyUptime = uptimeSeries?.points?.length ? Array.from({ length: Math.ceil(uptimeSeries.shiftMinutes / 60) }, (_, index) => {
|
|
54110
54225
|
const start = index * 60;
|
|
@@ -63964,6 +64079,8 @@ var HelpView = ({
|
|
|
63964
64079
|
};
|
|
63965
64080
|
var AuthenticatedHelpView = withAuth(HelpView);
|
|
63966
64081
|
var HelpView_default = HelpView;
|
|
64082
|
+
var REALTIME_REFRESH_DEBOUNCE_MS2 = 1500;
|
|
64083
|
+
var REALTIME_REFRESH_MIN_INTERVAL_MS2 = 5e3;
|
|
63967
64084
|
var transformActiveBreaks = (activeBreaksByLine) => {
|
|
63968
64085
|
if (!activeBreaksByLine) return [];
|
|
63969
64086
|
return Object.values(activeBreaksByLine).flat().map((item) => ({
|
|
@@ -64002,6 +64119,17 @@ var normalizeMetadata = (metadata) => ({
|
|
|
64002
64119
|
cacheStatus: metadata?.cache_status,
|
|
64003
64120
|
warnings: metadata?.warnings ?? []
|
|
64004
64121
|
});
|
|
64122
|
+
var createResolvedScopeLookup = (resolvedScope, workspaces, blueComparisonWorkspaces) => {
|
|
64123
|
+
const lookup = /* @__PURE__ */ new Set();
|
|
64124
|
+
const addEntry = (lineId, date, shiftId) => {
|
|
64125
|
+
if (!lineId || !date || shiftId === void 0 || shiftId === null) return;
|
|
64126
|
+
lookup.add(`${lineId}|${date}|${shiftId}`);
|
|
64127
|
+
};
|
|
64128
|
+
resolvedScope.forEach((entry) => addEntry(entry.line_id, entry.date, entry.shift_id));
|
|
64129
|
+
workspaces.forEach((workspace) => addEntry(workspace.line_id, workspace.date, workspace.shift_id));
|
|
64130
|
+
blueComparisonWorkspaces.forEach((workspace) => addEntry(workspace.line_id, workspace.date, workspace.shift_id));
|
|
64131
|
+
return lookup;
|
|
64132
|
+
};
|
|
64005
64133
|
var useLiveMonitorBootstrap = ({
|
|
64006
64134
|
lineIds,
|
|
64007
64135
|
blueComparisonLineIds,
|
|
@@ -64028,20 +64156,34 @@ var useLiveMonitorBootstrap = ({
|
|
|
64028
64156
|
() => Array.from(new Set(rawBlueComparisonLineIdsKey ? rawBlueComparisonLineIdsKey.split(",") : [])),
|
|
64029
64157
|
[rawBlueComparisonLineIdsKey]
|
|
64030
64158
|
);
|
|
64159
|
+
const realtimeLineIds = React144.useMemo(
|
|
64160
|
+
() => Array.from(new Set([...normalizedLineIds, ...normalizedBlueComparisonLineIds].filter(Boolean))).sort(),
|
|
64161
|
+
[normalizedLineIds, normalizedBlueComparisonLineIds]
|
|
64162
|
+
);
|
|
64031
64163
|
const requestKey = React144.useMemo(
|
|
64032
64164
|
() => `${normalizedLineIds.slice().sort().join(",")}|blue:${normalizedBlueComparisonLineIds.slice().sort().join(",")}`,
|
|
64033
64165
|
[normalizedLineIds, normalizedBlueComparisonLineIds]
|
|
64034
64166
|
);
|
|
64167
|
+
const realtimeLineIdsKey = React144.useMemo(() => realtimeLineIds.join(","), [realtimeLineIds]);
|
|
64168
|
+
const companySpecificMetricsTable = React144.useMemo(
|
|
64169
|
+
() => getCompanyMetricsTableName(resolvedCompanyId, "performance_metrics"),
|
|
64170
|
+
[resolvedCompanyId]
|
|
64171
|
+
);
|
|
64035
64172
|
const [state, setState] = React144.useState(() => createEmptyState());
|
|
64036
64173
|
const [rawState, setRawState] = React144.useState(null);
|
|
64037
64174
|
const [isLoading, setIsLoading] = React144.useState(false);
|
|
64038
64175
|
const [error, setError] = React144.useState(null);
|
|
64039
64176
|
const activeRequestIdRef = React144.useRef(0);
|
|
64177
|
+
const isFetchingRef = React144.useRef(false);
|
|
64178
|
+
const pendingRealtimeRefreshRef = React144.useRef(false);
|
|
64179
|
+
const realtimeRefreshTimerRef = React144.useRef(null);
|
|
64180
|
+
const lastRealtimeRefreshStartedAtRef = React144.useRef(0);
|
|
64040
64181
|
const fetchBootstrap = React144.useCallback(async (force = false) => {
|
|
64041
64182
|
if (!enabled || !supabase || !resolvedCompanyId || normalizedLineIds.length === 0) {
|
|
64042
64183
|
return;
|
|
64043
64184
|
}
|
|
64044
64185
|
const requestId = ++activeRequestIdRef.current;
|
|
64186
|
+
isFetchingRef.current = true;
|
|
64045
64187
|
setIsLoading(true);
|
|
64046
64188
|
setError(null);
|
|
64047
64189
|
try {
|
|
@@ -64054,6 +64196,7 @@ var useLiveMonitorBootstrap = ({
|
|
|
64054
64196
|
if (force) {
|
|
64055
64197
|
searchParams.set("force_refresh", "true");
|
|
64056
64198
|
}
|
|
64199
|
+
appendQaGreenStreakSearchParams(searchParams);
|
|
64057
64200
|
const response = await fetchBackendJson(
|
|
64058
64201
|
supabase,
|
|
64059
64202
|
`/api/dashboard/monitor-bootstrap?${searchParams.toString()}`,
|
|
@@ -64091,6 +64234,7 @@ var useLiveMonitorBootstrap = ({
|
|
|
64091
64234
|
} finally {
|
|
64092
64235
|
if (requestId === activeRequestIdRef.current) {
|
|
64093
64236
|
setIsLoading(false);
|
|
64237
|
+
isFetchingRef.current = false;
|
|
64094
64238
|
}
|
|
64095
64239
|
}
|
|
64096
64240
|
}, [
|
|
@@ -64101,6 +64245,52 @@ var useLiveMonitorBootstrap = ({
|
|
|
64101
64245
|
normalizedBlueComparisonLineIds,
|
|
64102
64246
|
requestKey
|
|
64103
64247
|
]);
|
|
64248
|
+
const fetchBootstrapRef = React144.useRef(fetchBootstrap);
|
|
64249
|
+
React144.useEffect(() => {
|
|
64250
|
+
fetchBootstrapRef.current = fetchBootstrap;
|
|
64251
|
+
}, [fetchBootstrap]);
|
|
64252
|
+
const clearRealtimeRefreshTimer = React144.useCallback(() => {
|
|
64253
|
+
if (realtimeRefreshTimerRef.current !== null) {
|
|
64254
|
+
window.clearTimeout(realtimeRefreshTimerRef.current);
|
|
64255
|
+
realtimeRefreshTimerRef.current = null;
|
|
64256
|
+
}
|
|
64257
|
+
}, []);
|
|
64258
|
+
const scheduleRealtimeRefresh = React144.useCallback(() => {
|
|
64259
|
+
if (!enabled || !supabase || realtimeRefreshTimerRef.current !== null) {
|
|
64260
|
+
return;
|
|
64261
|
+
}
|
|
64262
|
+
const elapsedSinceLastRealtimeRefresh = Date.now() - lastRealtimeRefreshStartedAtRef.current;
|
|
64263
|
+
const minIntervalRemaining = Math.max(0, REALTIME_REFRESH_MIN_INTERVAL_MS2 - elapsedSinceLastRealtimeRefresh);
|
|
64264
|
+
const nextDelay = Math.max(REALTIME_REFRESH_DEBOUNCE_MS2, minIntervalRemaining);
|
|
64265
|
+
realtimeRefreshTimerRef.current = window.setTimeout(() => {
|
|
64266
|
+
realtimeRefreshTimerRef.current = null;
|
|
64267
|
+
if (!pendingRealtimeRefreshRef.current) {
|
|
64268
|
+
return;
|
|
64269
|
+
}
|
|
64270
|
+
if (isFetchingRef.current) {
|
|
64271
|
+
scheduleRealtimeRefresh();
|
|
64272
|
+
return;
|
|
64273
|
+
}
|
|
64274
|
+
pendingRealtimeRefreshRef.current = false;
|
|
64275
|
+
lastRealtimeRefreshStartedAtRef.current = Date.now();
|
|
64276
|
+
void fetchBootstrapRef.current(true);
|
|
64277
|
+
}, nextDelay);
|
|
64278
|
+
}, [enabled, supabase]);
|
|
64279
|
+
const queueRealtimeRefresh = React144.useCallback(() => {
|
|
64280
|
+
if (!enabled || !supabase) {
|
|
64281
|
+
pendingRealtimeRefreshRef.current = false;
|
|
64282
|
+
clearRealtimeRefreshTimer();
|
|
64283
|
+
return;
|
|
64284
|
+
}
|
|
64285
|
+
pendingRealtimeRefreshRef.current = true;
|
|
64286
|
+
scheduleRealtimeRefresh();
|
|
64287
|
+
}, [clearRealtimeRefreshTimer, enabled, scheduleRealtimeRefresh, supabase]);
|
|
64288
|
+
React144.useEffect(() => {
|
|
64289
|
+
return () => {
|
|
64290
|
+
pendingRealtimeRefreshRef.current = false;
|
|
64291
|
+
clearRealtimeRefreshTimer();
|
|
64292
|
+
};
|
|
64293
|
+
}, [clearRealtimeRefreshTimer]);
|
|
64104
64294
|
React144.useEffect(() => {
|
|
64105
64295
|
if (!enabled || !rawState || !resolvedCompanyId) {
|
|
64106
64296
|
return;
|
|
@@ -64179,6 +64369,83 @@ var useLiveMonitorBootstrap = ({
|
|
|
64179
64369
|
}
|
|
64180
64370
|
void fetchBootstrap(false);
|
|
64181
64371
|
}, [enabled, resolvedCompanyId, normalizedLineIds, supabase, fetchBootstrap]);
|
|
64372
|
+
const realtimeScopeKey = React144.useMemo(() => Array.from(createResolvedScopeLookup(
|
|
64373
|
+
state.resolvedScope,
|
|
64374
|
+
state.workspaceMetrics,
|
|
64375
|
+
state.blueComparisonWorkspaceMetrics
|
|
64376
|
+
)).sort().join("||"), [state.resolvedScope, state.workspaceMetrics, state.blueComparisonWorkspaceMetrics]);
|
|
64377
|
+
React144.useEffect(() => {
|
|
64378
|
+
if (!enabled || !resolvedCompanyId || !realtimeLineIdsKey || !supabase) {
|
|
64379
|
+
return void 0;
|
|
64380
|
+
}
|
|
64381
|
+
const scopeLookup = new Set(realtimeScopeKey ? realtimeScopeKey.split("||") : []);
|
|
64382
|
+
if (scopeLookup.size === 0) {
|
|
64383
|
+
return void 0;
|
|
64384
|
+
}
|
|
64385
|
+
const realtimeLineIdsForFilter = realtimeLineIdsKey.split(",").filter(Boolean);
|
|
64386
|
+
if (realtimeLineIdsForFilter.length === 0) {
|
|
64387
|
+
return void 0;
|
|
64388
|
+
}
|
|
64389
|
+
const lineIdFilter = `line_id=in.(${realtimeLineIdsForFilter.join(",")})`;
|
|
64390
|
+
const channels = [];
|
|
64391
|
+
const shouldRefreshForPayload = (payload) => {
|
|
64392
|
+
const payloadData = payload.new || payload.old;
|
|
64393
|
+
return scopeLookup.has(`${payloadData?.line_id}|${payloadData?.date}|${payloadData?.shift_id}`);
|
|
64394
|
+
};
|
|
64395
|
+
const createSubscription = (table, channelNameBase) => {
|
|
64396
|
+
const channelName = `${channelNameBase}-${state.scopeKey || requestKey}`.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
64397
|
+
const channel = supabase.channel(channelName).on(
|
|
64398
|
+
"postgres_changes",
|
|
64399
|
+
{ event: "*", schema: "public", table, filter: lineIdFilter },
|
|
64400
|
+
(payload) => {
|
|
64401
|
+
if (shouldRefreshForPayload(payload)) {
|
|
64402
|
+
queueRealtimeRefresh();
|
|
64403
|
+
}
|
|
64404
|
+
}
|
|
64405
|
+
).subscribe();
|
|
64406
|
+
channels.push(channel);
|
|
64407
|
+
};
|
|
64408
|
+
createSubscription(companySpecificMetricsTable, "monitor-bootstrap-ws");
|
|
64409
|
+
createSubscription("line_metrics", "monitor-bootstrap-lm");
|
|
64410
|
+
createSubscription("wip_buffer_metrics", "monitor-bootstrap-wip-metrics");
|
|
64411
|
+
createSubscription("wip_buffer_alerts", "monitor-bootstrap-wip-alerts");
|
|
64412
|
+
return () => {
|
|
64413
|
+
channels.forEach((channel) => {
|
|
64414
|
+
supabase.removeChannel(channel);
|
|
64415
|
+
});
|
|
64416
|
+
};
|
|
64417
|
+
}, [
|
|
64418
|
+
enabled,
|
|
64419
|
+
resolvedCompanyId,
|
|
64420
|
+
realtimeLineIdsKey,
|
|
64421
|
+
supabase,
|
|
64422
|
+
realtimeScopeKey,
|
|
64423
|
+
state.scopeKey,
|
|
64424
|
+
requestKey,
|
|
64425
|
+
companySpecificMetricsTable,
|
|
64426
|
+
queueRealtimeRefresh
|
|
64427
|
+
]);
|
|
64428
|
+
React144.useEffect(() => {
|
|
64429
|
+
if (!enabled || !resolvedCompanyId || normalizedLineIds.length === 0 || !supabase) {
|
|
64430
|
+
return void 0;
|
|
64431
|
+
}
|
|
64432
|
+
const forceRefreshOnResume = () => {
|
|
64433
|
+
void fetchBootstrapRef.current(true);
|
|
64434
|
+
};
|
|
64435
|
+
const handleVisibilityChange = () => {
|
|
64436
|
+
if (document.visibilityState === "visible") {
|
|
64437
|
+
forceRefreshOnResume();
|
|
64438
|
+
}
|
|
64439
|
+
};
|
|
64440
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
64441
|
+
window.addEventListener("focus", forceRefreshOnResume);
|
|
64442
|
+
window.addEventListener("online", forceRefreshOnResume);
|
|
64443
|
+
return () => {
|
|
64444
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
64445
|
+
window.removeEventListener("focus", forceRefreshOnResume);
|
|
64446
|
+
window.removeEventListener("online", forceRefreshOnResume);
|
|
64447
|
+
};
|
|
64448
|
+
}, [enabled, normalizedLineIds.length, resolvedCompanyId, supabase]);
|
|
64182
64449
|
React144.useEffect(() => {
|
|
64183
64450
|
if (!enabled || !resolvedCompanyId || normalizedLineIds.length === 0 || !supabase) {
|
|
64184
64451
|
return void 0;
|
|
@@ -64933,7 +65200,6 @@ function HomeView({
|
|
|
64933
65200
|
const allGreenMilestoneTrackingRef = React144.useRef({ identity: null, lastMilestoneSeconds: null });
|
|
64934
65201
|
const allGreenStreakTimerBaselineRef = React144.useRef(null);
|
|
64935
65202
|
const [showAllGreenCelebration, setShowAllGreenCelebration] = React144.useState(false);
|
|
64936
|
-
const [allGreenCelebrationStartedAtMs, setAllGreenCelebrationStartedAtMs] = React144.useState(null);
|
|
64937
65203
|
const [greenStreakMilestoneBanner, setGreenStreakMilestoneBanner] = React144.useState(null);
|
|
64938
65204
|
const [allGreenStreakNowMs, setAllGreenStreakNowMs] = React144.useState(() => Date.now());
|
|
64939
65205
|
const currentAllGreenStreakNowMs = Math.max(allGreenStreakNowMs, Date.now());
|
|
@@ -64996,13 +65262,11 @@ function HomeView({
|
|
|
64996
65262
|
};
|
|
64997
65263
|
}, [allGreenMilestoneIdentity, allGreenStreakDisplay, currentAllGreenStreakNowMs]);
|
|
64998
65264
|
const allGreenCelebrationTimerText = React144.useMemo(() => {
|
|
64999
|
-
if (!showAllGreenCelebration ||
|
|
65265
|
+
if (!showAllGreenCelebration || !visibleAllGreenStreakDisplay) {
|
|
65000
65266
|
return null;
|
|
65001
65267
|
}
|
|
65002
|
-
return formatAllGreenCelebrationTimer(
|
|
65003
|
-
|
|
65004
|
-
);
|
|
65005
|
-
}, [allGreenCelebrationStartedAtMs, currentAllGreenStreakNowMs, showAllGreenCelebration]);
|
|
65268
|
+
return formatAllGreenCelebrationTimer(visibleAllGreenStreakDisplay.elapsedSeconds);
|
|
65269
|
+
}, [showAllGreenCelebration, visibleAllGreenStreakDisplay]);
|
|
65006
65270
|
React144.useEffect(() => {
|
|
65007
65271
|
const hasPossibleStreakTimer = showAllGreenCelebration || Boolean(allGreenStreakDisplay) || workspaceMetricsWithBreakState.some((workspace) => workspace.video_grid_green_streak_active === true);
|
|
65008
65272
|
if (!hasPossibleStreakTimer) {
|
|
@@ -65021,17 +65285,14 @@ function HomeView({
|
|
|
65021
65285
|
allGreenCelebrationTimerRef.current = null;
|
|
65022
65286
|
}
|
|
65023
65287
|
setShowAllGreenCelebration(false);
|
|
65024
|
-
setAllGreenCelebrationStartedAtMs(null);
|
|
65025
65288
|
}, []);
|
|
65026
65289
|
const triggerAllGreenCelebration = React144.useCallback(() => {
|
|
65027
|
-
setAllGreenCelebrationStartedAtMs(Date.now());
|
|
65028
65290
|
setShowAllGreenCelebration(true);
|
|
65029
65291
|
if (allGreenCelebrationTimerRef.current) {
|
|
65030
65292
|
clearTimeout(allGreenCelebrationTimerRef.current);
|
|
65031
65293
|
}
|
|
65032
65294
|
allGreenCelebrationTimerRef.current = setTimeout(() => {
|
|
65033
65295
|
setShowAllGreenCelebration(false);
|
|
65034
|
-
setAllGreenCelebrationStartedAtMs(null);
|
|
65035
65296
|
allGreenCelebrationTimerRef.current = null;
|
|
65036
65297
|
}, ALL_GREEN_CELEBRATION_DURATION_MS);
|
|
65037
65298
|
}, []);
|
|
@@ -67753,6 +68014,7 @@ var UptimeBottomSection = React144.memo(({
|
|
|
67753
68014
|
shiftDate,
|
|
67754
68015
|
timezone,
|
|
67755
68016
|
elapsedMinutes,
|
|
68017
|
+
shiftBreaks,
|
|
67756
68018
|
urlDate,
|
|
67757
68019
|
urlShift,
|
|
67758
68020
|
navigate
|
|
@@ -67840,7 +68102,8 @@ var UptimeBottomSection = React144.memo(({
|
|
|
67840
68102
|
shiftEnd,
|
|
67841
68103
|
shiftDate,
|
|
67842
68104
|
timezone,
|
|
67843
|
-
elapsedMinutes
|
|
68105
|
+
elapsedMinutes,
|
|
68106
|
+
shiftBreaks
|
|
67844
68107
|
}
|
|
67845
68108
|
) })
|
|
67846
68109
|
] })
|
|
@@ -68158,7 +68421,8 @@ var KPIDetailView = ({
|
|
|
68158
68421
|
shiftStart: resolvedShiftStart || void 0,
|
|
68159
68422
|
shiftEnd: resolvedShiftEnd || void 0,
|
|
68160
68423
|
shiftDate: metric.date,
|
|
68161
|
-
timezone: configuredTimezone
|
|
68424
|
+
timezone: configuredTimezone,
|
|
68425
|
+
shiftBreaks: shiftConfig?.shifts?.find((shift) => shift.shiftId === metric.shift_id)?.breaks || []
|
|
68162
68426
|
}) : null;
|
|
68163
68427
|
const idleTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ? metricIdleTimeSeconds ?? 0 : (uptimeSeries2?.idleMinutes || 0) * 60 : 0;
|
|
68164
68428
|
const activeTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ? metricActiveTimeSeconds ?? 0 : (uptimeSeries2?.activeMinutes || 0) * 60 : 0;
|
|
@@ -68338,6 +68602,10 @@ var KPIDetailView = ({
|
|
|
68338
68602
|
end: chartMetrics.shift_end || fallback.end
|
|
68339
68603
|
};
|
|
68340
68604
|
}, [chartMetrics?.shift_start, chartMetrics?.shift_end, chartMetrics?.shift_id, resolveShiftTimes]);
|
|
68605
|
+
const resolvedShiftBreaks = React144.useMemo(
|
|
68606
|
+
() => shiftConfig?.shifts?.find((shift) => shift.shiftId === chartMetrics?.shift_id)?.breaks || [],
|
|
68607
|
+
[shiftConfig?.shifts, chartMetrics?.shift_id]
|
|
68608
|
+
);
|
|
68341
68609
|
const lineSkuBreakdown = React144.useMemo(
|
|
68342
68610
|
() => resolvedLineInfo?.metrics.sku_breakdown ?? [],
|
|
68343
68611
|
[resolvedLineInfo]
|
|
@@ -68471,7 +68739,8 @@ var KPIDetailView = ({
|
|
|
68471
68739
|
shiftEnd: null,
|
|
68472
68740
|
shiftDate: null,
|
|
68473
68741
|
timezone: configuredTimezone,
|
|
68474
|
-
elapsedMinutes: null
|
|
68742
|
+
elapsedMinutes: null,
|
|
68743
|
+
shiftBreaks: resolvedShiftBreaks
|
|
68475
68744
|
});
|
|
68476
68745
|
}
|
|
68477
68746
|
return buildUptimeSeries({
|
|
@@ -68480,9 +68749,10 @@ var KPIDetailView = ({
|
|
|
68480
68749
|
shiftEnd: resolvedShiftTimes.end,
|
|
68481
68750
|
shiftDate: chartMetrics.date,
|
|
68482
68751
|
timezone: configuredTimezone,
|
|
68483
|
-
elapsedMinutes: elapsedShiftMinutes
|
|
68752
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
68753
|
+
shiftBreaks: resolvedShiftBreaks
|
|
68484
68754
|
});
|
|
68485
|
-
}, [chartMetrics, resolvedShiftTimes.start, resolvedShiftTimes.end, configuredTimezone, elapsedShiftMinutes]);
|
|
68755
|
+
}, [chartMetrics, resolvedShiftTimes.start, resolvedShiftTimes.end, configuredTimezone, elapsedShiftMinutes, resolvedShiftBreaks]);
|
|
68486
68756
|
const lineUtilizationFromLine = React144.useMemo(() => {
|
|
68487
68757
|
const efficiencyValue = Number.isFinite(chartMetrics?.avg_efficiency) ? Number(chartMetrics?.avg_efficiency) : null;
|
|
68488
68758
|
if (efficiencyValue !== null) return efficiencyValue;
|
|
@@ -68509,7 +68779,8 @@ var KPIDetailView = ({
|
|
|
68509
68779
|
shiftEnd,
|
|
68510
68780
|
shiftDate,
|
|
68511
68781
|
timezone: configuredTimezone,
|
|
68512
|
-
elapsedMinutes: workspaceElapsedMinutes
|
|
68782
|
+
elapsedMinutes: workspaceElapsedMinutes,
|
|
68783
|
+
shiftBreaks: resolvedShiftBreaks
|
|
68513
68784
|
});
|
|
68514
68785
|
let activeMinutes = uptimeSeries2.activeMinutes;
|
|
68515
68786
|
let idleMinutes = uptimeSeries2.idleMinutes;
|
|
@@ -68521,7 +68792,12 @@ var KPIDetailView = ({
|
|
|
68521
68792
|
);
|
|
68522
68793
|
const idleTimeValue = workspace.idle_time;
|
|
68523
68794
|
const hasIdleTimeValue = Number.isFinite(idleTimeValue);
|
|
68524
|
-
const fallbackDuration =
|
|
68795
|
+
const fallbackDuration = getBreakExcludedShiftMinutes({
|
|
68796
|
+
shiftStart,
|
|
68797
|
+
shiftEnd,
|
|
68798
|
+
elapsedMinutes: workspaceElapsedMinutes,
|
|
68799
|
+
shiftBreaks: resolvedShiftBreaks
|
|
68800
|
+
}) ?? workspaceElapsedMinutes ?? shiftMinutes;
|
|
68525
68801
|
if (!hasIdleHourlyPayload && hasIdleTimeValue && idleTimeValue > 0 && fallbackDuration > 0) {
|
|
68526
68802
|
const idleSeconds = Number(idleTimeValue);
|
|
68527
68803
|
const idleFromAggregate = Math.min(Math.max(idleSeconds / 60, 0), fallbackDuration);
|
|
@@ -68551,7 +68827,8 @@ var KPIDetailView = ({
|
|
|
68551
68827
|
resolvedShiftTimes.end,
|
|
68552
68828
|
chartMetrics?.date,
|
|
68553
68829
|
configuredTimezone,
|
|
68554
|
-
isCurrentShiftView
|
|
68830
|
+
isCurrentShiftView,
|
|
68831
|
+
resolvedShiftBreaks
|
|
68555
68832
|
]);
|
|
68556
68833
|
const lineUptimeStats = React144.useMemo(() => {
|
|
68557
68834
|
if (!isUptimeMode) {
|
|
@@ -69238,6 +69515,7 @@ var KPIDetailView = ({
|
|
|
69238
69515
|
shiftDate: chartMetrics?.date,
|
|
69239
69516
|
timezone: configuredTimezone,
|
|
69240
69517
|
elapsedMinutes: elapsedShiftMinutes,
|
|
69518
|
+
shiftBreaks: resolvedShiftBreaks,
|
|
69241
69519
|
urlDate,
|
|
69242
69520
|
urlShift,
|
|
69243
69521
|
navigate
|
|
@@ -69352,6 +69630,7 @@ var KPIDetailView = ({
|
|
|
69352
69630
|
shiftDate: chartMetrics?.date,
|
|
69353
69631
|
timezone: configuredTimezone,
|
|
69354
69632
|
elapsedMinutes: elapsedShiftMinutes,
|
|
69633
|
+
shiftBreaks: resolvedShiftBreaks,
|
|
69355
69634
|
urlDate,
|
|
69356
69635
|
urlShift,
|
|
69357
69636
|
navigate
|
|
@@ -76837,6 +77116,10 @@ var WorkspaceDetailView = ({
|
|
|
76837
77116
|
timezone
|
|
76838
77117
|
});
|
|
76839
77118
|
}, [isCurrentShiftView, workspace?.shift_start, workspace?.shift_end, idleClipDate, timezone]);
|
|
77119
|
+
const workspaceShiftBreaks = React144.useMemo(
|
|
77120
|
+
() => shiftConfig?.shifts?.find((shift2) => shift2.shiftId === workspace?.shift_id)?.breaks || [],
|
|
77121
|
+
[shiftConfig?.shifts, workspace?.shift_id]
|
|
77122
|
+
);
|
|
76840
77123
|
const uptimeSeries = React144.useMemo(
|
|
76841
77124
|
() => buildUptimeSeries({
|
|
76842
77125
|
idleTimeHourly: workspace?.idle_time_hourly,
|
|
@@ -76844,17 +77127,26 @@ var WorkspaceDetailView = ({
|
|
|
76844
77127
|
shiftEnd: workspace?.shift_end,
|
|
76845
77128
|
shiftDate: idleClipDate,
|
|
76846
77129
|
timezone,
|
|
76847
|
-
elapsedMinutes: elapsedShiftMinutes
|
|
77130
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
77131
|
+
shiftBreaks: workspaceShiftBreaks
|
|
76848
77132
|
}),
|
|
76849
|
-
[workspace?.idle_time_hourly, workspace?.shift_start, workspace?.shift_end, idleClipDate, timezone, elapsedShiftMinutes]
|
|
77133
|
+
[workspace?.idle_time_hourly, workspace?.shift_start, workspace?.shift_end, idleClipDate, timezone, elapsedShiftMinutes, workspaceShiftBreaks]
|
|
76850
77134
|
);
|
|
76851
77135
|
const uptimePieData = React144.useMemo(() => {
|
|
76852
77136
|
if (!isUptimeMode) return [];
|
|
76853
77137
|
let activeMinutes = uptimeSeries.activeMinutes;
|
|
76854
77138
|
let idleMinutes = uptimeSeries.idleMinutes;
|
|
76855
77139
|
let totalMinutes = uptimeSeries.availableMinutes;
|
|
76856
|
-
const fallbackDuration =
|
|
76857
|
-
|
|
77140
|
+
const fallbackDuration = getBreakExcludedShiftMinutes({
|
|
77141
|
+
shiftStart: workspace?.shift_start,
|
|
77142
|
+
shiftEnd: workspace?.shift_end,
|
|
77143
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
77144
|
+
shiftBreaks: workspaceShiftBreaks
|
|
77145
|
+
}) ?? elapsedShiftMinutes ?? shiftDurationMinutes;
|
|
77146
|
+
const hasIdleHourlyPayload = Boolean(
|
|
77147
|
+
workspace?.idle_time_hourly && typeof workspace.idle_time_hourly === "object" && Object.keys(workspace.idle_time_hourly).length > 0
|
|
77148
|
+
);
|
|
77149
|
+
if (!uptimeSeries.hasData && !hasIdleHourlyPayload && fallbackDuration !== null && fallbackDuration !== void 0) {
|
|
76858
77150
|
const idleSeconds = Number(workspace?.idle_time || 0);
|
|
76859
77151
|
const idleFromAggregate = Math.min(Math.max(Math.round(idleSeconds / 60), 0), fallbackDuration);
|
|
76860
77152
|
const activeFromAggregate = Math.max(fallbackDuration - idleFromAggregate, 0);
|
|
@@ -76867,7 +77159,7 @@ var WorkspaceDetailView = ({
|
|
|
76867
77159
|
{ name: "Productive", value: activeMinutes },
|
|
76868
77160
|
{ name: "Idle", value: idleMinutes }
|
|
76869
77161
|
];
|
|
76870
|
-
}, [isUptimeMode, uptimeSeries, shiftDurationMinutes, elapsedShiftMinutes, workspace?.idle_time]);
|
|
77162
|
+
}, [isUptimeMode, uptimeSeries, shiftDurationMinutes, elapsedShiftMinutes, workspace?.idle_time, workspace?.shift_start, workspace?.shift_end, workspaceShiftBreaks]);
|
|
76871
77163
|
const overviewTabLabel = isUptimeMode ? "Utilization" : "Efficiency";
|
|
76872
77164
|
const idleClipFetchEnabled = Boolean(
|
|
76873
77165
|
workspaceId && idleClipDate && idleClipShiftId !== void 0 && activeTab === "overview" && idleTimeVlmEnabled && isOutputLayout
|
|
@@ -77346,7 +77638,8 @@ var WorkspaceDetailView = ({
|
|
|
77346
77638
|
shiftEnd: workspace.shift_end,
|
|
77347
77639
|
shiftDate: idleClipDate,
|
|
77348
77640
|
timezone,
|
|
77349
|
-
elapsedMinutes: elapsedShiftMinutes
|
|
77641
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
77642
|
+
shiftBreaks: workspaceShiftBreaks
|
|
77350
77643
|
}
|
|
77351
77644
|
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
77352
77645
|
CycleTimeOverTimeChart,
|
|
@@ -77499,7 +77792,8 @@ var WorkspaceDetailView = ({
|
|
|
77499
77792
|
shiftEnd: workspace.shift_end,
|
|
77500
77793
|
shiftDate: idleClipDate,
|
|
77501
77794
|
timezone,
|
|
77502
|
-
elapsedMinutes: elapsedShiftMinutes
|
|
77795
|
+
elapsedMinutes: elapsedShiftMinutes,
|
|
77796
|
+
shiftBreaks: workspaceShiftBreaks
|
|
77503
77797
|
}
|
|
77504
77798
|
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
77505
77799
|
CycleTimeOverTimeChart,
|