@optifye/dashboard-core 6.12.46 → 6.12.48
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/{automation-ZIumB5W9.d.mts → automation-B472r1h3.d.mts} +1 -0
- package/dist/{automation-ZIumB5W9.d.ts → automation-B472r1h3.d.ts} +1 -0
- package/dist/automation.d.mts +1 -1
- package/dist/automation.d.ts +1 -1
- package/dist/automation.js +19 -1
- package/dist/automation.mjs +19 -1
- package/dist/index.css +18 -0
- package/dist/index.d.mts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +572 -48
- package/dist/index.mjs +573 -49
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14900,6 +14900,7 @@ var transformMonitorWorkspaceMetrics = ({
|
|
|
14900
14900
|
leaderboard_value: item.leaderboard_value ?? null,
|
|
14901
14901
|
avg_recent_flow: item.avg_recent_flow ?? null,
|
|
14902
14902
|
recent_flow_percent: item.recent_flow_percent ?? null,
|
|
14903
|
+
recent_flow_hourly: item.recent_flow_hourly ?? null,
|
|
14903
14904
|
recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
|
|
14904
14905
|
recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
|
|
14905
14906
|
recent_flow_computed_at: item.recent_flow_computed_at ?? null,
|
|
@@ -38502,6 +38503,114 @@ var getRawVideoGridMetricValue = (workspace) => {
|
|
|
38502
38503
|
};
|
|
38503
38504
|
var hasIncomingWipMapping = (workspace) => Boolean(workspace.incoming_wip_buffer_name);
|
|
38504
38505
|
var getVideoGridWorkspaceKey = (workspace) => workspace.workspace_uuid || `${workspace.line_id || "unknown"}:${workspace.workspace_name || "unknown"}`;
|
|
38506
|
+
var getWorstPerformanceWorkstationLimit = (totalWorkstations) => {
|
|
38507
|
+
if (!Number.isFinite(totalWorkstations) || totalWorkstations <= 0) return 0;
|
|
38508
|
+
if (totalWorkstations === 2) return 1;
|
|
38509
|
+
if (totalWorkstations === 4) return 2;
|
|
38510
|
+
return Math.min(3, Math.max(1, Math.floor(totalWorkstations)));
|
|
38511
|
+
};
|
|
38512
|
+
var coerceRecentFlowHourlyValue = (value) => {
|
|
38513
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
38514
|
+
return value;
|
|
38515
|
+
}
|
|
38516
|
+
if (typeof value === "string") {
|
|
38517
|
+
const trimmed = value.trim();
|
|
38518
|
+
if (!trimmed || trimmed.toLowerCase() === "x") return null;
|
|
38519
|
+
const parsed = Number(trimmed);
|
|
38520
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
38521
|
+
}
|
|
38522
|
+
return null;
|
|
38523
|
+
};
|
|
38524
|
+
var collectRecentFlowHourlyValues = (hourly) => {
|
|
38525
|
+
if (!hourly || typeof hourly !== "object" || Array.isArray(hourly)) {
|
|
38526
|
+
return [];
|
|
38527
|
+
}
|
|
38528
|
+
const values = [];
|
|
38529
|
+
Object.values(hourly).forEach((rawSlotValues) => {
|
|
38530
|
+
if (Array.isArray(rawSlotValues)) {
|
|
38531
|
+
rawSlotValues.forEach((rawValue) => {
|
|
38532
|
+
const value = coerceRecentFlowHourlyValue(rawValue);
|
|
38533
|
+
if (value !== null) values.push(value);
|
|
38534
|
+
});
|
|
38535
|
+
return;
|
|
38536
|
+
}
|
|
38537
|
+
if (rawSlotValues && typeof rawSlotValues === "object") {
|
|
38538
|
+
Object.values(rawSlotValues).forEach((rawValue) => {
|
|
38539
|
+
const value = coerceRecentFlowHourlyValue(rawValue);
|
|
38540
|
+
if (value !== null) values.push(value);
|
|
38541
|
+
});
|
|
38542
|
+
}
|
|
38543
|
+
});
|
|
38544
|
+
return values;
|
|
38545
|
+
};
|
|
38546
|
+
var getAverageRecentFlowHourlyPercent = (workspace) => {
|
|
38547
|
+
const values = collectRecentFlowHourlyValues(workspace.recent_flow_hourly);
|
|
38548
|
+
if (values.length > 0) {
|
|
38549
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
38550
|
+
}
|
|
38551
|
+
if (isFiniteNumber4(workspace.avg_recent_flow)) {
|
|
38552
|
+
return workspace.avg_recent_flow;
|
|
38553
|
+
}
|
|
38554
|
+
return isFiniteNumber4(workspace.recent_flow_percent) ? workspace.recent_flow_percent : null;
|
|
38555
|
+
};
|
|
38556
|
+
var getAssemblyCycleOverStandardRatio = (workspace) => {
|
|
38557
|
+
const medianCycleTime = toFiniteNumberOrNull(workspace.avg_cycle_time);
|
|
38558
|
+
const standardCycleTime = toFiniteNumberOrNull(workspace.ideal_cycle_time);
|
|
38559
|
+
if (medianCycleTime === null || standardCycleTime === null || medianCycleTime <= 0 || standardCycleTime <= 0) {
|
|
38560
|
+
return null;
|
|
38561
|
+
}
|
|
38562
|
+
return medianCycleTime / standardCycleTime;
|
|
38563
|
+
};
|
|
38564
|
+
var getUptimeWorstPerformanceValue = (workspace) => toFiniteNumberOrNull(workspace.efficiency);
|
|
38565
|
+
var isWorstPerformanceEligible = (workspace) => isValidAggregateEfficiency(workspace.monitoring_mode, workspace.efficiency);
|
|
38566
|
+
var isAssemblyLineGroup = (lineWorkspaces) => (
|
|
38567
|
+
// `assembly_enabled` is denormalized from `lines.assembly` onto every
|
|
38568
|
+
// live-monitor workspace row; it is not a workstation-level flag.
|
|
38569
|
+
lineWorkspaces.some((workspace) => workspace.assembly_enabled === true)
|
|
38570
|
+
);
|
|
38571
|
+
var getWorstPerformanceLineMode = (lineWorkspaces) => {
|
|
38572
|
+
if (lineWorkspaces.some((workspace) => normalizeMonitoringMode(workspace.monitoring_mode) === "uptime")) {
|
|
38573
|
+
return "uptime";
|
|
38574
|
+
}
|
|
38575
|
+
return isAssemblyLineGroup(lineWorkspaces) ? "assembly" : "flow";
|
|
38576
|
+
};
|
|
38577
|
+
var getEligibleWorstPerformanceCandidates = (lineWorkspaces) => lineWorkspaces.map((workspace, index) => ({ workspace, index })).filter(({ workspace }) => isWorstPerformanceEligible(workspace));
|
|
38578
|
+
var selectWorstPerformanceWorkspaceIds = (workspaces) => {
|
|
38579
|
+
const workspacesByLine = /* @__PURE__ */ new Map();
|
|
38580
|
+
workspaces.forEach((workspace) => {
|
|
38581
|
+
const lineKey = workspace.line_id || "unknown";
|
|
38582
|
+
const lineWorkspaces = workspacesByLine.get(lineKey) || [];
|
|
38583
|
+
lineWorkspaces.push(workspace);
|
|
38584
|
+
workspacesByLine.set(lineKey, lineWorkspaces);
|
|
38585
|
+
});
|
|
38586
|
+
const selected = /* @__PURE__ */ new Set();
|
|
38587
|
+
workspacesByLine.forEach((lineWorkspaces) => {
|
|
38588
|
+
const limit = getWorstPerformanceWorkstationLimit(lineWorkspaces.length);
|
|
38589
|
+
if (limit <= 0) return;
|
|
38590
|
+
const eligibleCandidates = getEligibleWorstPerformanceCandidates(lineWorkspaces);
|
|
38591
|
+
if (eligibleCandidates.length === 0) return;
|
|
38592
|
+
const lineMode = getWorstPerformanceLineMode(lineWorkspaces);
|
|
38593
|
+
if (lineMode === "uptime") {
|
|
38594
|
+
eligibleCandidates.map((candidate) => ({
|
|
38595
|
+
...candidate,
|
|
38596
|
+
efficiency: getUptimeWorstPerformanceValue(candidate.workspace)
|
|
38597
|
+
})).filter((entry) => entry.efficiency !== null).sort((left, right) => left.efficiency - right.efficiency || left.workspace.workspace_name.localeCompare(right.workspace.workspace_name, void 0, { numeric: true }) || left.index - right.index).slice(0, limit).forEach((entry) => selected.add(getVideoGridWorkspaceKey(entry.workspace)));
|
|
38598
|
+
return;
|
|
38599
|
+
}
|
|
38600
|
+
if (lineMode === "assembly") {
|
|
38601
|
+
eligibleCandidates.map((candidate) => ({
|
|
38602
|
+
...candidate,
|
|
38603
|
+
ratio: getAssemblyCycleOverStandardRatio(candidate.workspace)
|
|
38604
|
+
})).filter((entry) => entry.ratio !== null).sort((left, right) => right.ratio - left.ratio || left.workspace.workspace_name.localeCompare(right.workspace.workspace_name, void 0, { numeric: true }) || left.index - right.index).slice(0, limit).forEach((entry) => selected.add(getVideoGridWorkspaceKey(entry.workspace)));
|
|
38605
|
+
return;
|
|
38606
|
+
}
|
|
38607
|
+
eligibleCandidates.map((candidate) => ({
|
|
38608
|
+
...candidate,
|
|
38609
|
+
averageFlow: getAverageRecentFlowHourlyPercent(candidate.workspace)
|
|
38610
|
+
})).filter((entry) => entry.averageFlow !== null).sort((left, right) => left.averageFlow - right.averageFlow || left.workspace.workspace_name.localeCompare(right.workspace.workspace_name, void 0, { numeric: true }) || left.index - right.index).slice(0, limit).forEach((entry) => selected.add(getVideoGridWorkspaceKey(entry.workspace)));
|
|
38611
|
+
});
|
|
38612
|
+
return selected;
|
|
38613
|
+
};
|
|
38505
38614
|
var getVideoGridBlueComparisonGroupKey = (workspace) => {
|
|
38506
38615
|
const factoryAreaId = typeof workspace.factory_area_id === "string" ? workspace.factory_area_id.trim() : "";
|
|
38507
38616
|
if (factoryAreaId && workspace.factory_area_enabled === true) {
|
|
@@ -38794,6 +38903,7 @@ var VideoCard = React148__namespace.default.memo(({
|
|
|
38794
38903
|
displayMinuteBucket,
|
|
38795
38904
|
displayName,
|
|
38796
38905
|
isBlueBest = false,
|
|
38906
|
+
isWorstPerformance = false,
|
|
38797
38907
|
lastSeenLabel,
|
|
38798
38908
|
hasRecentHealthSignal: hasRecentHealthSignal2 = false,
|
|
38799
38909
|
onMouseEnter,
|
|
@@ -38832,6 +38942,8 @@ var VideoCard = React148__namespace.default.memo(({
|
|
|
38832
38942
|
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "blue" ? "bg-[#0EA5E9]/30" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
38833
38943
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "blue" ? "bg-[#0EA5E9]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
38834
38944
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "blue" ? "Best" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
38945
|
+
const worstMarkerClassName = compact ? "left-1.5 top-1.5 gap-1.5 px-2 py-1 text-[11px]" : "left-2 top-2 gap-2 px-3 py-1.5 text-xs";
|
|
38946
|
+
const statusBadgesPositionClass = isWorstPerformance ? compact ? "top-8 left-1.5 gap-1" : "top-10 left-2 gap-1.5" : compact ? "top-1.5 left-1.5 gap-1" : "top-2 left-2 gap-1.5";
|
|
38835
38947
|
const trendInfo = workspace.trend !== void 0 ? getTrendArrowAndColor(workspace.trend) : null;
|
|
38836
38948
|
const handleClick = React148.useCallback(() => {
|
|
38837
38949
|
trackCoreEvent("Workspace Card Clicked", {
|
|
@@ -38850,6 +38962,7 @@ var VideoCard = React148__namespace.default.memo(({
|
|
|
38850
38962
|
{
|
|
38851
38963
|
className: `workspace-card relative bg-gray-950 rounded-md overflow-hidden cursor-pointer shadow-[0_1px_3px_rgba(15,23,42,0.16),0_0_0_1px_rgba(255,255,255,0.06)] transition-[box-shadow] duration-200 hover:shadow-[0_10px_24px_rgba(15,23,42,0.28),0_0_0_1px_rgba(255,255,255,0.10)] active:shadow-[0_1px_3px_rgba(15,23,42,0.16),0_0_0_1px_rgba(255,255,255,0.06)] touch-manipulation ${className}`,
|
|
38852
38964
|
style: { width: "100%", height: "100%" },
|
|
38965
|
+
"data-worst-performance-highlight": isWorstPerformance ? "true" : void 0,
|
|
38853
38966
|
onClick: handleClick,
|
|
38854
38967
|
onMouseEnter,
|
|
38855
38968
|
onMouseLeave,
|
|
@@ -38911,7 +39024,7 @@ var VideoCard = React148__namespace.default.memo(({
|
|
|
38911
39024
|
"div",
|
|
38912
39025
|
{
|
|
38913
39026
|
"data-testid": "video-card-status-badges",
|
|
38914
|
-
className: `absolute ${
|
|
39027
|
+
className: `absolute ${statusBadgesPositionClass} z-30 flex items-center`,
|
|
38915
39028
|
children: statusBadges.map((badge, index) => {
|
|
38916
39029
|
const presentation = getIdleReasonPresentation({
|
|
38917
39030
|
label: badge.label,
|
|
@@ -38962,6 +39075,17 @@ var VideoCard = React148__namespace.default.memo(({
|
|
|
38962
39075
|
})
|
|
38963
39076
|
}
|
|
38964
39077
|
),
|
|
39078
|
+
isWorstPerformance && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
39079
|
+
"div",
|
|
39080
|
+
{
|
|
39081
|
+
"data-testid": "video-card-worst-performance-marker",
|
|
39082
|
+
className: `pointer-events-none absolute z-[65] inline-flex items-center rounded-md bg-[#1A0B09]/95 border border-[#E34329]/60 font-semibold tracking-wide text-white shadow-xl ${worstMarkerClassName}`,
|
|
39083
|
+
children: [
|
|
39084
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: `${compact ? "h-3.5 w-3.5" : "h-4 w-4"} text-[#E34329]`, "aria-hidden": "true" }),
|
|
39085
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Overall Underperformer" })
|
|
39086
|
+
]
|
|
39087
|
+
}
|
|
39088
|
+
),
|
|
38965
39089
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute bottom-0 left-0 right-0 ${compact ? "h-0.5" : "h-1"} bg-black/50 z-30`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
38966
39090
|
"div",
|
|
38967
39091
|
{
|
|
@@ -39010,6 +39134,9 @@ var VideoCard = React148__namespace.default.memo(({
|
|
|
39010
39134
|
if (prevProps.isBlueBest !== nextProps.isBlueBest) {
|
|
39011
39135
|
return false;
|
|
39012
39136
|
}
|
|
39137
|
+
if (prevProps.isWorstPerformance !== nextProps.isWorstPerformance) {
|
|
39138
|
+
return false;
|
|
39139
|
+
}
|
|
39013
39140
|
if (prevProps.lastSeenLabel !== nextProps.lastSeenLabel) {
|
|
39014
39141
|
return false;
|
|
39015
39142
|
}
|
|
@@ -39052,6 +39179,7 @@ var hasRecentHealthSignal = (lastHeartbeat) => {
|
|
|
39052
39179
|
var VideoGridView = React148__namespace.default.memo(({
|
|
39053
39180
|
workspaces,
|
|
39054
39181
|
blueComparisonWorkspaces,
|
|
39182
|
+
worstPerformanceWorkspaceIds = [],
|
|
39055
39183
|
selectedLine,
|
|
39056
39184
|
className = "",
|
|
39057
39185
|
legend,
|
|
@@ -39059,6 +39187,9 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39059
39187
|
videoStreamsByWorkspaceId,
|
|
39060
39188
|
videoStreamsLoading = false,
|
|
39061
39189
|
displayNames = {},
|
|
39190
|
+
lineOrder = [],
|
|
39191
|
+
activeSlideshowLineId = null,
|
|
39192
|
+
displayMode = "all",
|
|
39062
39193
|
onWorkspaceHover,
|
|
39063
39194
|
onWorkspaceHoverEnd
|
|
39064
39195
|
}) => {
|
|
@@ -39181,6 +39312,48 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39181
39312
|
});
|
|
39182
39313
|
}, [filteredWorkspaces]);
|
|
39183
39314
|
const blueWinnerIds = React148.useMemo(() => selectVideoGridBlueWinnerIds(blueComparisonWorkspaces || sortedWorkspaces, effectiveLegend), [blueComparisonWorkspaces, sortedWorkspaces, effectiveLegend]);
|
|
39315
|
+
const worstPerformanceIdSet = React148.useMemo(
|
|
39316
|
+
() => new Set(worstPerformanceWorkspaceIds),
|
|
39317
|
+
[worstPerformanceWorkspaceIds]
|
|
39318
|
+
);
|
|
39319
|
+
const modeBaseWorkspaces = React148.useMemo(() => {
|
|
39320
|
+
if (displayMode !== "red_only") {
|
|
39321
|
+
return sortedWorkspaces;
|
|
39322
|
+
}
|
|
39323
|
+
return sortedWorkspaces.filter((workspace) => getVideoGridColorState(workspace, effectiveLegend, blueWinnerIds) === "red");
|
|
39324
|
+
}, [blueWinnerIds, displayMode, effectiveLegend, sortedWorkspaces]);
|
|
39325
|
+
const slideshowLines = React148.useMemo(() => {
|
|
39326
|
+
const linesWithWorkspaces = new Set(
|
|
39327
|
+
sortedWorkspaces.map((workspace) => workspace.line_id).filter((lineId) => Boolean(lineId))
|
|
39328
|
+
);
|
|
39329
|
+
if (lineOrder.length > 0) {
|
|
39330
|
+
return lineOrder.filter((lineId) => linesWithWorkspaces.has(lineId));
|
|
39331
|
+
}
|
|
39332
|
+
const orderedLineIds = [];
|
|
39333
|
+
const seenLineIds = /* @__PURE__ */ new Set();
|
|
39334
|
+
for (const workspace of sortedWorkspaces) {
|
|
39335
|
+
if (!workspace.line_id || seenLineIds.has(workspace.line_id)) {
|
|
39336
|
+
continue;
|
|
39337
|
+
}
|
|
39338
|
+
seenLineIds.add(workspace.line_id);
|
|
39339
|
+
orderedLineIds.push(workspace.line_id);
|
|
39340
|
+
}
|
|
39341
|
+
return orderedLineIds;
|
|
39342
|
+
}, [lineOrder, sortedWorkspaces]);
|
|
39343
|
+
const currentSlideshowLineId = displayMode === "slideshow" && slideshowLines.length > 0 ? activeSlideshowLineId && slideshowLines.includes(activeSlideshowLineId) ? activeSlideshowLineId : slideshowLines[0] : null;
|
|
39344
|
+
const displayWorkspaces = React148.useMemo(() => {
|
|
39345
|
+
if (displayMode === "red_only") {
|
|
39346
|
+
return modeBaseWorkspaces;
|
|
39347
|
+
}
|
|
39348
|
+
if (displayMode !== "slideshow") {
|
|
39349
|
+
return sortedWorkspaces;
|
|
39350
|
+
}
|
|
39351
|
+
if (slideshowLines.length === 0) {
|
|
39352
|
+
return [];
|
|
39353
|
+
}
|
|
39354
|
+
const currentLineId = currentSlideshowLineId || slideshowLines[0];
|
|
39355
|
+
return sortedWorkspaces.filter((workspace) => workspace.line_id === currentLineId);
|
|
39356
|
+
}, [currentSlideshowLineId, displayMode, modeBaseWorkspaces, slideshowLines, sortedWorkspaces]);
|
|
39184
39357
|
const streamsResolvedForWorkspaceSet = resolvedStreamWorkspaceKey === workspaceIdsKey;
|
|
39185
39358
|
const resolveWorkspaceDisplayName = React148.useCallback((workspace) => {
|
|
39186
39359
|
return workspace.displayName || displayNames[`${workspace.line_id}_${workspace.workspace_name}`] || workspace.workspace_name;
|
|
@@ -39191,7 +39364,7 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39191
39364
|
const rawContainerWidth = containerRef.current.clientWidth;
|
|
39192
39365
|
const containerWidth = rawContainerWidth - containerPadding;
|
|
39193
39366
|
const containerHeight = containerRef.current.clientHeight - containerPadding;
|
|
39194
|
-
const count =
|
|
39367
|
+
const count = displayWorkspaces.length;
|
|
39195
39368
|
if (count === 0) {
|
|
39196
39369
|
setGridCols(1);
|
|
39197
39370
|
setGridRows(1);
|
|
@@ -39242,7 +39415,7 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39242
39415
|
setGridCols(bestCols);
|
|
39243
39416
|
setGridRows(rows);
|
|
39244
39417
|
setIsMobileScrollableGrid(shouldUseMobileScroll);
|
|
39245
|
-
}, [
|
|
39418
|
+
}, [displayWorkspaces.length, selectedLine]);
|
|
39246
39419
|
React148.useEffect(() => {
|
|
39247
39420
|
calculateOptimalGrid();
|
|
39248
39421
|
const handleResize = () => calculateOptimalGrid();
|
|
@@ -39276,7 +39449,7 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39276
39449
|
return () => {
|
|
39277
39450
|
observerRef.current?.disconnect();
|
|
39278
39451
|
};
|
|
39279
|
-
}, [
|
|
39452
|
+
}, [displayWorkspaces]);
|
|
39280
39453
|
const prewarmClipsInit = React148.useCallback((workspace) => {
|
|
39281
39454
|
if (!dashboardConfig?.s3Config) return;
|
|
39282
39455
|
const workspaceId = workspace.workspace_uuid || workspace.workspace_name;
|
|
@@ -39362,7 +39535,7 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39362
39535
|
});
|
|
39363
39536
|
}, []);
|
|
39364
39537
|
const workspaceCards = React148.useMemo(() => {
|
|
39365
|
-
return
|
|
39538
|
+
return displayWorkspaces.map((workspace) => {
|
|
39366
39539
|
const workspaceId = workspace.workspace_uuid || workspace.workspace_name;
|
|
39367
39540
|
const workspaceKey = `${workspace.line_id || "unknown"}-${workspaceId}`;
|
|
39368
39541
|
const isVisible = visibleWorkspaces.has(workspaceId);
|
|
@@ -39390,12 +39563,14 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39390
39563
|
shouldPlay,
|
|
39391
39564
|
lastSeenLabel,
|
|
39392
39565
|
hasRecentHealthSignal: hasRecentHealthSignal(workspaceHealth?.lastHeartbeat),
|
|
39393
|
-
isBlueBest: blueWinnerIds.has(getVideoGridWorkspaceKey(workspace))
|
|
39566
|
+
isBlueBest: blueWinnerIds.has(getVideoGridWorkspaceKey(workspace)),
|
|
39567
|
+
isWorstPerformance: worstPerformanceIdSet.has(getVideoGridWorkspaceKey(workspace))
|
|
39394
39568
|
};
|
|
39395
39569
|
});
|
|
39396
39570
|
}, [
|
|
39397
|
-
|
|
39571
|
+
displayWorkspaces,
|
|
39398
39572
|
blueWinnerIds,
|
|
39573
|
+
worstPerformanceIdSet,
|
|
39399
39574
|
visibleWorkspaces,
|
|
39400
39575
|
getWorkspaceCropping,
|
|
39401
39576
|
videoStreamsByWorkspaceId,
|
|
@@ -39443,6 +39618,7 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39443
39618
|
displayMinuteBucket,
|
|
39444
39619
|
compact: !selectedLine,
|
|
39445
39620
|
isBlueBest: card.isBlueBest,
|
|
39621
|
+
isWorstPerformance: card.isWorstPerformance,
|
|
39446
39622
|
onMouseEnter: onWorkspaceHover ? () => onWorkspaceHover(card.workspaceId) : void 0,
|
|
39447
39623
|
onMouseLeave: onWorkspaceHoverEnd ? () => onWorkspaceHoverEnd(card.workspaceId) : void 0
|
|
39448
39624
|
}
|
|
@@ -39468,9 +39644,28 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39468
39644
|
"data-testid": "video-grid-scroll-container",
|
|
39469
39645
|
"data-mobile-scrollable": isMobileScrollableGrid ? "true" : "false",
|
|
39470
39646
|
className: `absolute inset-0 w-full overflow-x-hidden px-1 py-1 sm:px-2 sm:py-2 ${isMobileScrollableGrid ? "overflow-y-auto" : "overflow-hidden"}`,
|
|
39471
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
39472
|
-
|
|
39647
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(AnimatePresence, { mode: "popLayout", children: displayMode === "red_only" && workspaceCards.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
39648
|
+
motion.div,
|
|
39649
|
+
{
|
|
39650
|
+
initial: { opacity: 0, scale: 0.95 },
|
|
39651
|
+
animate: { opacity: 1, scale: 1 },
|
|
39652
|
+
exit: { opacity: 0, scale: 0.95 },
|
|
39653
|
+
transition: { duration: 0.3 },
|
|
39654
|
+
"data-testid": "video-grid-empty-red-cameras",
|
|
39655
|
+
className: "flex h-full min-h-[240px] flex-col items-center justify-center rounded-xl border border-emerald-200 bg-emerald-50/70 px-6 text-center",
|
|
39656
|
+
children: [
|
|
39657
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-semibold text-emerald-900", children: "No red cameras right now" }),
|
|
39658
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 max-w-md text-sm text-emerald-700", children: "The selected line filter has no cameras in the red state. Switch back to all cameras to keep monitoring the full floor." })
|
|
39659
|
+
]
|
|
39660
|
+
},
|
|
39661
|
+
"empty-red"
|
|
39662
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
39663
|
+
motion.div,
|
|
39473
39664
|
{
|
|
39665
|
+
initial: displayMode === "slideshow" ? { opacity: 0, x: 100 } : { opacity: 0 },
|
|
39666
|
+
animate: displayMode === "slideshow" ? { opacity: 1, x: 0 } : { opacity: 1 },
|
|
39667
|
+
exit: displayMode === "slideshow" ? { opacity: 0, x: -100 } : { opacity: 0 },
|
|
39668
|
+
transition: { duration: 0.5, ease: [0.32, 0.72, 0, 1] },
|
|
39474
39669
|
"data-testid": "video-grid-layout",
|
|
39475
39670
|
className: `grid min-w-0 w-full gap-1.5 sm:gap-2 ${isMobileScrollableGrid ? "content-start" : "h-full"}`,
|
|
39476
39671
|
style: {
|
|
@@ -39482,8 +39677,9 @@ var VideoGridView = React148__namespace.default.memo(({
|
|
|
39482
39677
|
card,
|
|
39483
39678
|
isMobileScrollableGrid ? "workspace-card relative min-w-0 w-full aspect-video min-h-[92px]" : "workspace-card relative min-w-0 w-full h-full"
|
|
39484
39679
|
))
|
|
39485
|
-
}
|
|
39486
|
-
|
|
39680
|
+
},
|
|
39681
|
+
`grid-${displayMode === "slideshow" ? currentSlideshowLineId : "standard"}`
|
|
39682
|
+
) })
|
|
39487
39683
|
}
|
|
39488
39684
|
) });
|
|
39489
39685
|
});
|
|
@@ -47197,6 +47393,7 @@ function useClipsRealtimeUpdates({
|
|
|
47197
47393
|
hasNewClips: newClipsNotification !== null && newClipsNotification.count > 0
|
|
47198
47394
|
};
|
|
47199
47395
|
}
|
|
47396
|
+
var LOW_EFFICIENCY_CATEGORY_ID = "recent_flow_red_streak";
|
|
47200
47397
|
var parseFiniteNumber2 = (value) => {
|
|
47201
47398
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
47202
47399
|
return value;
|
|
@@ -47455,6 +47652,7 @@ var BottlenecksContent = ({
|
|
|
47455
47652
|
totalOutput,
|
|
47456
47653
|
enabled: isEffectiveShiftReady
|
|
47457
47654
|
});
|
|
47655
|
+
const isLowMomentsCategoryAvailable = React148.useMemo(() => Array.isArray(clipTypes) && clipTypes.some((type) => type?.type === LOW_EFFICIENCY_CATEGORY_ID || type?.id === LOW_EFFICIENCY_CATEGORY_ID), [clipTypes]);
|
|
47458
47656
|
console.log("[BottlenecksContent] Clip types data:", {
|
|
47459
47657
|
clipTypes,
|
|
47460
47658
|
clipTypesLength: clipTypes?.length,
|
|
@@ -47505,20 +47703,20 @@ var BottlenecksContent = ({
|
|
|
47505
47703
|
if (initialFilter) {
|
|
47506
47704
|
return;
|
|
47507
47705
|
}
|
|
47508
|
-
const redStreakType =
|
|
47509
|
-
if (dynamicCounts[redStreakType] > 0) {
|
|
47706
|
+
const redStreakType = LOW_EFFICIENCY_CATEGORY_ID;
|
|
47707
|
+
if (isLowMomentsCategoryAvailable && dynamicCounts[redStreakType] > 0) {
|
|
47510
47708
|
setInitialFilter(redStreakType);
|
|
47511
47709
|
setActiveFilter(redStreakType);
|
|
47512
47710
|
activeFilterRef.current = redStreakType;
|
|
47513
47711
|
return;
|
|
47514
47712
|
}
|
|
47515
|
-
if (defaultCategory) {
|
|
47713
|
+
if (defaultCategory && (defaultCategory !== LOW_EFFICIENCY_CATEGORY_ID || isLowMomentsCategoryAvailable)) {
|
|
47516
47714
|
setInitialFilter(defaultCategory);
|
|
47517
47715
|
setActiveFilter(defaultCategory);
|
|
47518
47716
|
activeFilterRef.current = defaultCategory;
|
|
47519
47717
|
return;
|
|
47520
47718
|
}
|
|
47521
|
-
}, [clipTypes, dynamicCounts, defaultCategory, initialFilter]);
|
|
47719
|
+
}, [clipTypes, dynamicCounts, defaultCategory, initialFilter, isLowMomentsCategoryAvailable]);
|
|
47522
47720
|
const mergedCounts = React148.useMemo(() => {
|
|
47523
47721
|
return { ...dynamicCounts };
|
|
47524
47722
|
}, [dynamicCounts]);
|
|
@@ -47737,7 +47935,7 @@ var BottlenecksContent = ({
|
|
|
47737
47935
|
};
|
|
47738
47936
|
const [cycleClips, redFlowClips, idleClips] = await Promise.all([
|
|
47739
47937
|
fetchCategoryMetadata("cycle_completion"),
|
|
47740
|
-
fetchCategoryMetadata(
|
|
47938
|
+
isLowMomentsCategoryAvailable ? fetchCategoryMetadata(LOW_EFFICIENCY_CATEGORY_ID) : Promise.resolve([]),
|
|
47741
47939
|
fetchCategoryMetadata("idle_time")
|
|
47742
47940
|
]);
|
|
47743
47941
|
const allClips = [...cycleClips, ...redFlowClips, ...idleClips].sort(
|
|
@@ -47751,7 +47949,7 @@ var BottlenecksContent = ({
|
|
|
47751
47949
|
}
|
|
47752
47950
|
};
|
|
47753
47951
|
fetchTriageClips();
|
|
47754
|
-
}, [triageMode, workspaceId, effectiveDateString, effectiveShiftId, supabase, isEffectiveShiftReady]);
|
|
47952
|
+
}, [triageMode, workspaceId, effectiveDateString, effectiveShiftId, supabase, isEffectiveShiftReady, isLowMomentsCategoryAvailable]);
|
|
47755
47953
|
React148.useEffect(() => {
|
|
47756
47954
|
if (!idleTimeVlmEnabled || !triageMode || triageClips.length === 0) {
|
|
47757
47955
|
return;
|
|
@@ -47789,7 +47987,7 @@ var BottlenecksContent = ({
|
|
|
47789
47987
|
}, [idleTimeVlmEnabled, triageClips, triageMode, getAuthToken4]);
|
|
47790
47988
|
React148.useEffect(() => {
|
|
47791
47989
|
if (s3ClipsService && (mergedCounts[activeFilter] || 0) > 0) {
|
|
47792
|
-
if (activeFilter ===
|
|
47990
|
+
if (activeFilter === LOW_EFFICIENCY_CATEGORY_ID) {
|
|
47793
47991
|
return;
|
|
47794
47992
|
}
|
|
47795
47993
|
if (firstClip && firstClip.type === activeFilter) {
|
|
@@ -47812,12 +48010,12 @@ var BottlenecksContent = ({
|
|
|
47812
48010
|
return ["fast-cycles", "slow-cycles", "longest-idles"].includes(categoryId);
|
|
47813
48011
|
}, [isFastSlowClipFiltersEnabled]);
|
|
47814
48012
|
const shouldUseMetadataNavigation = React148.useCallback((categoryId) => {
|
|
47815
|
-
return isPercentileCategory(categoryId) || categoryId ===
|
|
48013
|
+
return isPercentileCategory(categoryId) || categoryId === LOW_EFFICIENCY_CATEGORY_ID || categoryId === "idle_time" && idleClipSort === "idle_duration_desc";
|
|
47816
48014
|
}, [idleClipSort, isPercentileCategory]);
|
|
47817
48015
|
const getMetadataCacheKey = React148.useCallback((categoryId) => {
|
|
47818
|
-
const sortKey = categoryId ===
|
|
47819
|
-
return `${categoryId}-${effectiveDateString}-${effectiveShiftId}-${snapshotDateTime ?? "nosnap"}-${snapshotClipId ?? "nosnap"}-${sortKey}`;
|
|
47820
|
-
}, [effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, idleClipSort]);
|
|
48016
|
+
const sortKey = categoryId === LOW_EFFICIENCY_CATEGORY_ID ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest";
|
|
48017
|
+
return `${categoryId}-${workspaceId}-${effectiveDateString}-${effectiveShiftId}-${snapshotDateTime ?? "nosnap"}-${snapshotClipId ?? "nosnap"}-${sortKey}`;
|
|
48018
|
+
}, [workspaceId, effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, idleClipSort]);
|
|
47821
48019
|
const setVisibleCategoryMetadata = React148.useCallback((categoryId, clips) => {
|
|
47822
48020
|
if (activeFilterRef.current !== categoryId) {
|
|
47823
48021
|
return false;
|
|
@@ -47825,7 +48023,7 @@ var BottlenecksContent = ({
|
|
|
47825
48023
|
categoryMetadataRef.current = clips;
|
|
47826
48024
|
setCategoryMetadata(clips);
|
|
47827
48025
|
setCategoryMetadataCategoryId(clips.length > 0 ? categoryId : null);
|
|
47828
|
-
setCategoryMetadataSort(clips.length > 0 ? categoryId ===
|
|
48026
|
+
setCategoryMetadataSort(clips.length > 0 ? categoryId === LOW_EFFICIENCY_CATEGORY_ID ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest" : null);
|
|
47829
48027
|
return true;
|
|
47830
48028
|
}, [idleClipSort]);
|
|
47831
48029
|
const applyMetadataSnapshot = React148.useCallback((categoryId, clips, total) => {
|
|
@@ -47878,7 +48076,8 @@ var BottlenecksContent = ({
|
|
|
47878
48076
|
if (activeFilter !== "fast-cycles" && activeFilter !== "slow-cycles") {
|
|
47879
48077
|
return;
|
|
47880
48078
|
}
|
|
47881
|
-
const
|
|
48079
|
+
const lowMomentsFallback = isLowMomentsCategoryAvailable ? LOW_EFFICIENCY_CATEGORY_ID : null;
|
|
48080
|
+
const fallbackFilter = ["cycle_completion", lowMomentsFallback, "idle_time"].filter((type) => Boolean(type)).find((type) => (dynamicCounts[type] || 0) > 0) || clipTypes.find((type) => (dynamicCounts[type.type] || 0) > 0)?.type || clipTypes[0]?.type;
|
|
47882
48081
|
if (!fallbackFilter || fallbackFilter === activeFilter) {
|
|
47883
48082
|
return;
|
|
47884
48083
|
}
|
|
@@ -47887,7 +48086,25 @@ var BottlenecksContent = ({
|
|
|
47887
48086
|
setCategoryMetadataSort(null);
|
|
47888
48087
|
categoryMetadataRef.current = [];
|
|
47889
48088
|
updateActiveFilter(fallbackFilter);
|
|
47890
|
-
}, [isFastSlowClipFiltersEnabled, activeFilter, dynamicCounts, clipTypes, updateActiveFilter]);
|
|
48089
|
+
}, [isFastSlowClipFiltersEnabled, activeFilter, dynamicCounts, clipTypes, updateActiveFilter, isLowMomentsCategoryAvailable]);
|
|
48090
|
+
React148.useEffect(() => {
|
|
48091
|
+
if (activeFilter !== LOW_EFFICIENCY_CATEGORY_ID || isLowMomentsCategoryAvailable) {
|
|
48092
|
+
return;
|
|
48093
|
+
}
|
|
48094
|
+
const fallbackFilter = clipTypes.find((type) => type.type !== LOW_EFFICIENCY_CATEGORY_ID && (dynamicCounts[type.type] || 0) > 0)?.type || clipTypes.find((type) => type.type !== LOW_EFFICIENCY_CATEGORY_ID)?.type || "";
|
|
48095
|
+
setCategoryMetadata([]);
|
|
48096
|
+
setCategoryMetadataCategoryId(null);
|
|
48097
|
+
setCategoryMetadataSort(null);
|
|
48098
|
+
categoryMetadataRef.current = [];
|
|
48099
|
+
if (fallbackFilter) {
|
|
48100
|
+
setInitialFilter(fallbackFilter);
|
|
48101
|
+
updateActiveFilter(fallbackFilter);
|
|
48102
|
+
} else {
|
|
48103
|
+
setInitialFilter("");
|
|
48104
|
+
updateActiveFilter("");
|
|
48105
|
+
setIsCategoryLoading(false);
|
|
48106
|
+
}
|
|
48107
|
+
}, [activeFilter, isLowMomentsCategoryAvailable, clipTypes, dynamicCounts, updateActiveFilter]);
|
|
47891
48108
|
React148.useCallback((categoryId) => {
|
|
47892
48109
|
if (isPercentileCategory(categoryId)) {
|
|
47893
48110
|
return categoryMetadata.length;
|
|
@@ -47939,6 +48156,16 @@ var BottlenecksContent = ({
|
|
|
47939
48156
|
}
|
|
47940
48157
|
return;
|
|
47941
48158
|
}
|
|
48159
|
+
if (categoryId === LOW_EFFICIENCY_CATEGORY_ID && !isLowMomentsCategoryAvailable) {
|
|
48160
|
+
setCategoryMetadata([]);
|
|
48161
|
+
setCategoryMetadataCategoryId(null);
|
|
48162
|
+
setCategoryMetadataSort(null);
|
|
48163
|
+
categoryMetadataRef.current = [];
|
|
48164
|
+
if (activeFilterRef.current === categoryId) {
|
|
48165
|
+
setIsCategoryLoading(false);
|
|
48166
|
+
}
|
|
48167
|
+
return;
|
|
48168
|
+
}
|
|
47942
48169
|
if (!isEffectiveShiftReady) {
|
|
47943
48170
|
console.log("[BottlenecksContent] Skipping metadata load - shift/date not ready");
|
|
47944
48171
|
if (activeFilterRef.current === categoryId) {
|
|
@@ -47950,10 +48177,10 @@ var BottlenecksContent = ({
|
|
|
47950
48177
|
const cacheKey = getMetadataCacheKey(categoryId);
|
|
47951
48178
|
const candidateLowMomentsPrefetch = lowMomentsPrefetch ?? null;
|
|
47952
48179
|
const lowMomentsPrefetchMatchesScope = Boolean(
|
|
47953
|
-
candidateLowMomentsPrefetch?.key?.startsWith(
|
|
48180
|
+
candidateLowMomentsPrefetch?.key?.startsWith(`${LOW_EFFICIENCY_CATEGORY_ID}-${workspaceId}-${effectiveDateString}-${effectiveShiftId}-`)
|
|
47954
48181
|
);
|
|
47955
|
-
const matchingLowMomentsPrefetch = !forceRefresh && categoryId ===
|
|
47956
|
-
const lowMomentsPrefetchInFlight = !forceRefresh && categoryId ===
|
|
48182
|
+
const matchingLowMomentsPrefetch = !forceRefresh && categoryId === LOW_EFFICIENCY_CATEGORY_ID && isLowMomentsCategoryAvailable && candidateLowMomentsPrefetch && (candidateLowMomentsPrefetch.key === cacheKey || lowMomentsPrefetchMatchesScope) && !candidateLowMomentsPrefetch.loading && Array.isArray(candidateLowMomentsPrefetch.metadata) && candidateLowMomentsPrefetch.metadata.length > 0 ? candidateLowMomentsPrefetch : null;
|
|
48183
|
+
const lowMomentsPrefetchInFlight = !forceRefresh && categoryId === LOW_EFFICIENCY_CATEGORY_ID && isLowMomentsCategoryAvailable && candidateLowMomentsPrefetch && (candidateLowMomentsPrefetch.key === cacheKey || lowMomentsPrefetchMatchesScope) && candidateLowMomentsPrefetch.loading;
|
|
47957
48184
|
if (lowMomentsPrefetchInFlight) {
|
|
47958
48185
|
if (autoLoadFirstVideo && candidateLowMomentsPrefetch?.firstVideo) {
|
|
47959
48186
|
applyPrefetchedFirstVideo(candidateLowMomentsPrefetch.firstVideo);
|
|
@@ -48044,7 +48271,7 @@ var BottlenecksContent = ({
|
|
|
48044
48271
|
knownTotal: mergedCounts[categoryId] ?? null,
|
|
48045
48272
|
snapshotDateTime,
|
|
48046
48273
|
snapshotClipId,
|
|
48047
|
-
sort: categoryId ===
|
|
48274
|
+
sort: categoryId === LOW_EFFICIENCY_CATEGORY_ID ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest"
|
|
48048
48275
|
}),
|
|
48049
48276
|
redirectReason: "session_expired"
|
|
48050
48277
|
});
|
|
@@ -48138,19 +48365,19 @@ var BottlenecksContent = ({
|
|
|
48138
48365
|
setIsCategoryLoading(false);
|
|
48139
48366
|
}
|
|
48140
48367
|
}
|
|
48141
|
-
}, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, idleClipSort, supabase, setVisibleCategoryMetadata, lowMomentsPrefetch, applyPrefetchedFirstVideo, applyMetadataSnapshot]);
|
|
48368
|
+
}, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, idleClipSort, supabase, setVisibleCategoryMetadata, lowMomentsPrefetch, applyPrefetchedFirstVideo, applyMetadataSnapshot, isLowMomentsCategoryAvailable]);
|
|
48142
48369
|
React148.useEffect(() => {
|
|
48143
|
-
if (activeFilter !==
|
|
48370
|
+
if (activeFilter !== LOW_EFFICIENCY_CATEGORY_ID || !isLowMomentsCategoryAvailable) {
|
|
48144
48371
|
return;
|
|
48145
48372
|
}
|
|
48146
|
-
if (!lowMomentsPrefetch?.key?.startsWith(
|
|
48373
|
+
if (!lowMomentsPrefetch?.key?.startsWith(`${LOW_EFFICIENCY_CATEGORY_ID}-${workspaceId}-${effectiveDateString}-${effectiveShiftId}-`)) {
|
|
48147
48374
|
return;
|
|
48148
48375
|
}
|
|
48149
|
-
if (lowMomentsPrefetch.firstVideo && !allVideos.some((video) => video.type ===
|
|
48376
|
+
if (lowMomentsPrefetch.firstVideo && !allVideos.some((video) => video.type === LOW_EFFICIENCY_CATEGORY_ID)) {
|
|
48150
48377
|
applyPrefetchedFirstVideo(lowMomentsPrefetch.firstVideo);
|
|
48151
48378
|
}
|
|
48152
48379
|
if (lowMomentsPrefetch.metadata.length > 0) {
|
|
48153
|
-
applyMetadataSnapshot(
|
|
48380
|
+
applyMetadataSnapshot(LOW_EFFICIENCY_CATEGORY_ID, lowMomentsPrefetch.metadata, lowMomentsPrefetch.total);
|
|
48154
48381
|
if (isMountedRef.current) {
|
|
48155
48382
|
setIsCategoryLoading(false);
|
|
48156
48383
|
}
|
|
@@ -48162,11 +48389,13 @@ var BottlenecksContent = ({
|
|
|
48162
48389
|
}, [
|
|
48163
48390
|
activeFilter,
|
|
48164
48391
|
lowMomentsPrefetch,
|
|
48392
|
+
workspaceId,
|
|
48165
48393
|
effectiveDateString,
|
|
48166
48394
|
effectiveShiftId,
|
|
48167
48395
|
allVideos,
|
|
48168
48396
|
applyPrefetchedFirstVideo,
|
|
48169
|
-
applyMetadataSnapshot
|
|
48397
|
+
applyMetadataSnapshot,
|
|
48398
|
+
isLowMomentsCategoryAvailable
|
|
48170
48399
|
]);
|
|
48171
48400
|
React148.useEffect(() => {
|
|
48172
48401
|
if (previousIdleClipSortRef.current === idleClipSort) {
|
|
@@ -48862,11 +49091,11 @@ var BottlenecksContent = ({
|
|
|
48862
49091
|
}
|
|
48863
49092
|
return currentPosition;
|
|
48864
49093
|
}, [activeFilter, categoryMetadata.length, currentMetadataIndex, currentPosition, shouldUseMetadataNavigation]);
|
|
48865
|
-
const prefetchedExplorerMetadata = React148.useMemo(() => activeFilter ===
|
|
49094
|
+
const prefetchedExplorerMetadata = React148.useMemo(() => activeFilter === LOW_EFFICIENCY_CATEGORY_ID && isLowMomentsCategoryAvailable && lowMomentsPrefetch?.key?.startsWith(`${LOW_EFFICIENCY_CATEGORY_ID}-${workspaceId}-${effectiveDateString}-${effectiveShiftId}-`) && !lowMomentsPrefetch.loading && lowMomentsPrefetch.metadata.length > 0 ? { [LOW_EFFICIENCY_CATEGORY_ID]: lowMomentsPrefetch.metadata } : activeFilter === "idle_time" && categoryMetadataSort !== idleClipSort ? void 0 : buildPrefetchedExplorerMetadata(
|
|
48866
49095
|
activeFilter,
|
|
48867
49096
|
categoryMetadataCategoryId,
|
|
48868
49097
|
categoryMetadata
|
|
48869
|
-
), [activeFilter, categoryMetadata, categoryMetadataCategoryId, categoryMetadataSort, idleClipSort, lowMomentsPrefetch, effectiveDateString, effectiveShiftId]);
|
|
49098
|
+
), [activeFilter, categoryMetadata, categoryMetadataCategoryId, categoryMetadataSort, idleClipSort, lowMomentsPrefetch, workspaceId, effectiveDateString, effectiveShiftId, isLowMomentsCategoryAvailable]);
|
|
48870
49099
|
const classificationClipIds = React148.useMemo(() => {
|
|
48871
49100
|
if (!idleTimeVlmEnabled) {
|
|
48872
49101
|
return [];
|
|
@@ -49639,7 +49868,7 @@ var BottlenecksContent = ({
|
|
|
49639
49868
|
prefetchedClipMetadata: prefetchedExplorerMetadata,
|
|
49640
49869
|
externallyManagedLoadingCategories: {
|
|
49641
49870
|
recent_flow_red_streak: Boolean(
|
|
49642
|
-
activeFilter ===
|
|
49871
|
+
activeFilter === LOW_EFFICIENCY_CATEGORY_ID && isLowMomentsCategoryAvailable && lowMomentsPrefetch?.key?.startsWith(`${LOW_EFFICIENCY_CATEGORY_ID}-${workspaceId}-${effectiveDateString}-${effectiveShiftId}-`) && lowMomentsPrefetch.loading
|
|
49643
49872
|
)
|
|
49644
49873
|
},
|
|
49645
49874
|
activeCategoryLoading: isCategoryLoading,
|
|
@@ -56912,10 +57141,12 @@ WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
|
56912
57141
|
var WorkspaceGrid = React148__namespace.default.memo(({
|
|
56913
57142
|
workspaces,
|
|
56914
57143
|
blueComparisonWorkspaces,
|
|
57144
|
+
worstPerformanceWorkspaceIds = [],
|
|
56915
57145
|
isPdfMode = false,
|
|
56916
57146
|
customWorkspacePositions,
|
|
56917
57147
|
lineNames = {},
|
|
56918
57148
|
lineOrder = [],
|
|
57149
|
+
activeSlideshowLineId = null,
|
|
56919
57150
|
factoryView = "factory",
|
|
56920
57151
|
line2Uuid = "line-2",
|
|
56921
57152
|
className = "",
|
|
@@ -56926,7 +57157,8 @@ var WorkspaceGrid = React148__namespace.default.memo(({
|
|
|
56926
57157
|
displayNames = {},
|
|
56927
57158
|
onWorkspaceHover,
|
|
56928
57159
|
onWorkspaceHoverEnd,
|
|
56929
|
-
toolbarRightContent
|
|
57160
|
+
toolbarRightContent,
|
|
57161
|
+
displayMode = "all"
|
|
56930
57162
|
}) => {
|
|
56931
57163
|
const mapViewEnabled = false;
|
|
56932
57164
|
const [viewMode, setViewMode] = React148.useState(() => {
|
|
@@ -56984,13 +57216,16 @@ var WorkspaceGrid = React148__namespace.default.memo(({
|
|
|
56984
57216
|
{
|
|
56985
57217
|
workspaces,
|
|
56986
57218
|
blueComparisonWorkspaces,
|
|
57219
|
+
worstPerformanceWorkspaceIds,
|
|
56987
57220
|
lineNames,
|
|
56988
57221
|
lineOrder,
|
|
57222
|
+
activeSlideshowLineId,
|
|
56989
57223
|
videoSources,
|
|
56990
57224
|
videoStreamsByWorkspaceId,
|
|
56991
57225
|
videoStreamsLoading,
|
|
56992
57226
|
displayNames,
|
|
56993
57227
|
legend,
|
|
57228
|
+
displayMode,
|
|
56994
57229
|
onWorkspaceHover,
|
|
56995
57230
|
onWorkspaceHoverEnd
|
|
56996
57231
|
}
|
|
@@ -67129,6 +67364,31 @@ var NotificationService = class {
|
|
|
67129
67364
|
function createNotificationService(supabaseClient) {
|
|
67130
67365
|
return new NotificationService(supabaseClient);
|
|
67131
67366
|
}
|
|
67367
|
+
|
|
67368
|
+
// src/components/dashboard/grid/displayModes.ts
|
|
67369
|
+
var HOME_DISPLAY_MODE_OPTIONS = [
|
|
67370
|
+
{
|
|
67371
|
+
id: "all",
|
|
67372
|
+
label: "Default",
|
|
67373
|
+
description: "Show every camera in the selected line filter."
|
|
67374
|
+
},
|
|
67375
|
+
{
|
|
67376
|
+
id: "red_only",
|
|
67377
|
+
label: "Only red",
|
|
67378
|
+
description: "Only show workstations in red."
|
|
67379
|
+
},
|
|
67380
|
+
{
|
|
67381
|
+
id: "slideshow",
|
|
67382
|
+
label: "Slideshow",
|
|
67383
|
+
description: "Automatically switches between all lines every 15 seconds."
|
|
67384
|
+
},
|
|
67385
|
+
{
|
|
67386
|
+
id: "worst_workstations",
|
|
67387
|
+
label: "Overall Underperformers",
|
|
67388
|
+
description: "Lowest performers based on full day efficiency"
|
|
67389
|
+
}
|
|
67390
|
+
];
|
|
67391
|
+
var getHomeDisplayModeLabel = (displayMode) => HOME_DISPLAY_MODE_OPTIONS.find((option) => option.id === displayMode)?.label || "Default";
|
|
67132
67392
|
var KPISection2 = KPISection;
|
|
67133
67393
|
var DEBUG_DASHBOARD_LOGS3 = process.env.NEXT_PUBLIC_DEBUG_DASHBOARD === "true";
|
|
67134
67394
|
var logDebug3 = (...args) => {
|
|
@@ -67139,6 +67399,9 @@ var EMPTY_LINE_IDS = [];
|
|
|
67139
67399
|
var EMPTY_WORKSPACES = [];
|
|
67140
67400
|
var ALL_GREEN_CELEBRATION_DURATION_MS = 6e3;
|
|
67141
67401
|
var ALL_GREEN_MILESTONE_DURATION_MS = 6e3;
|
|
67402
|
+
var SLIDESHOW_ROTATION_INTERVAL_MS = 15e3;
|
|
67403
|
+
var SLIDESHOW_IDLE_REQUIRED_MS = 15e3;
|
|
67404
|
+
var SLIDESHOW_ACTIVE_LINE_STORAGE_KEY = "optifye_home_slideshow_active_line_id";
|
|
67142
67405
|
var ALL_GREEN_CELEBRATION_SEEN_PREFIX = "optifye:all-green-celebration:v1:";
|
|
67143
67406
|
var ALL_GREEN_MILESTONE_SEEN_PREFIX = "optifye:all-green-milestone:v1:";
|
|
67144
67407
|
var formatAllGreenCelebrationTimer = (elapsedSeconds) => {
|
|
@@ -67268,6 +67531,31 @@ function HomeView({
|
|
|
67268
67531
|
const [isLineSelectorOpen, setIsLineSelectorOpen] = React148.useState(false);
|
|
67269
67532
|
const [pendingSelectedLineIds, setPendingSelectedLineIds] = React148.useState([]);
|
|
67270
67533
|
const lineSelectorRef = React148.useRef(null);
|
|
67534
|
+
const [displayMode, setDisplayMode] = React148.useState(() => {
|
|
67535
|
+
if (typeof window === "undefined") {
|
|
67536
|
+
return "all";
|
|
67537
|
+
}
|
|
67538
|
+
try {
|
|
67539
|
+
const savedDisplayMode = sessionStorage.getItem("optifye_home_display_mode");
|
|
67540
|
+
return HOME_DISPLAY_MODE_OPTIONS.some((option) => option.id === savedDisplayMode) ? savedDisplayMode : "all";
|
|
67541
|
+
} catch {
|
|
67542
|
+
return "all";
|
|
67543
|
+
}
|
|
67544
|
+
});
|
|
67545
|
+
const [isDisplayModeMenuOpen, setIsDisplayModeMenuOpen] = React148.useState(false);
|
|
67546
|
+
const displayModeSelectorRef = React148.useRef(null);
|
|
67547
|
+
const readPersistedSlideshowActiveLineId = () => {
|
|
67548
|
+
if (typeof window === "undefined") {
|
|
67549
|
+
return null;
|
|
67550
|
+
}
|
|
67551
|
+
try {
|
|
67552
|
+
return sessionStorage.getItem(SLIDESHOW_ACTIVE_LINE_STORAGE_KEY);
|
|
67553
|
+
} catch {
|
|
67554
|
+
return null;
|
|
67555
|
+
}
|
|
67556
|
+
};
|
|
67557
|
+
const [slideshowActiveLineId, setSlideshowActiveLineId] = React148.useState(() => readPersistedSlideshowActiveLineId());
|
|
67558
|
+
const slideshowLastUserActivityAtRef = React148.useRef(Date.now());
|
|
67271
67559
|
React148.useEffect(() => {
|
|
67272
67560
|
if (isLineSelectorOpen) {
|
|
67273
67561
|
setPendingSelectedLineIds(selectedLineIds);
|
|
@@ -67294,6 +67582,13 @@ function HomeView({
|
|
|
67294
67582
|
console.warn("Failed to save line filter to sessionStorage:", error);
|
|
67295
67583
|
}
|
|
67296
67584
|
}, [selectedLineIds]);
|
|
67585
|
+
React148.useEffect(() => {
|
|
67586
|
+
try {
|
|
67587
|
+
sessionStorage.setItem("optifye_home_display_mode", displayMode);
|
|
67588
|
+
} catch (error) {
|
|
67589
|
+
console.warn("Failed to save display mode to sessionStorage:", error);
|
|
67590
|
+
}
|
|
67591
|
+
}, [displayMode]);
|
|
67297
67592
|
React148.useEffect(() => {
|
|
67298
67593
|
if (!isLineSelectorOpen) {
|
|
67299
67594
|
return;
|
|
@@ -67308,6 +67603,20 @@ function HomeView({
|
|
|
67308
67603
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
67309
67604
|
};
|
|
67310
67605
|
}, [isLineSelectorOpen]);
|
|
67606
|
+
React148.useEffect(() => {
|
|
67607
|
+
if (!isDisplayModeMenuOpen) {
|
|
67608
|
+
return;
|
|
67609
|
+
}
|
|
67610
|
+
const handleClickOutside = (event) => {
|
|
67611
|
+
if (displayModeSelectorRef.current && !displayModeSelectorRef.current.contains(event.target)) {
|
|
67612
|
+
setIsDisplayModeMenuOpen(false);
|
|
67613
|
+
}
|
|
67614
|
+
};
|
|
67615
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
67616
|
+
return () => {
|
|
67617
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
67618
|
+
};
|
|
67619
|
+
}, [isDisplayModeMenuOpen]);
|
|
67311
67620
|
const primarySelectedLineId = selectedLineIds[0] || defaultHomeLineId;
|
|
67312
67621
|
const isMultiLineSelection = selectedLineIds.length > 1;
|
|
67313
67622
|
const selectedLineIdsKey = selectedLineIds.join(",");
|
|
@@ -67610,6 +67919,88 @@ function HomeView({
|
|
|
67610
67919
|
})),
|
|
67611
67920
|
[currentWorkspaceMetrics, activeBreakLineIds]
|
|
67612
67921
|
);
|
|
67922
|
+
const slideshowLineIds = React148.useMemo(() => {
|
|
67923
|
+
const selectedLineIdSetForSlideshow = new Set(selectedLineIds);
|
|
67924
|
+
const linesWithVisibleWorkspaces = new Set(
|
|
67925
|
+
workspaceMetricsWithBreakState.map((workspace) => workspace.line_id).filter((lineId) => Boolean(lineId))
|
|
67926
|
+
);
|
|
67927
|
+
const selectedVisibleLines = visibleLineIds.filter((lineId) => selectedLineIdSetForSlideshow.has(lineId));
|
|
67928
|
+
const selectedLinesWithWorkspaces = selectedVisibleLines.filter((lineId) => linesWithVisibleWorkspaces.has(lineId));
|
|
67929
|
+
if (selectedLinesWithWorkspaces.length > 0) {
|
|
67930
|
+
return selectedLinesWithWorkspaces;
|
|
67931
|
+
}
|
|
67932
|
+
return selectedVisibleLines;
|
|
67933
|
+
}, [selectedLineIds, visibleLineIds, workspaceMetricsWithBreakState]);
|
|
67934
|
+
const slideshowLineIdsKey = slideshowLineIds.join(",");
|
|
67935
|
+
React148.useEffect(() => {
|
|
67936
|
+
if (displayMode !== "slideshow") {
|
|
67937
|
+
return;
|
|
67938
|
+
}
|
|
67939
|
+
slideshowLastUserActivityAtRef.current = Date.now();
|
|
67940
|
+
setSlideshowActiveLineId((previousLineId) => {
|
|
67941
|
+
if (previousLineId && slideshowLineIds.includes(previousLineId)) {
|
|
67942
|
+
return previousLineId;
|
|
67943
|
+
}
|
|
67944
|
+
const persistedLineId = readPersistedSlideshowActiveLineId();
|
|
67945
|
+
if (persistedLineId && slideshowLineIds.includes(persistedLineId)) {
|
|
67946
|
+
return persistedLineId;
|
|
67947
|
+
}
|
|
67948
|
+
if (primarySelectedLineId && slideshowLineIds.includes(primarySelectedLineId)) {
|
|
67949
|
+
return primarySelectedLineId;
|
|
67950
|
+
}
|
|
67951
|
+
return slideshowLineIds[0] || null;
|
|
67952
|
+
});
|
|
67953
|
+
}, [displayMode, primarySelectedLineId, slideshowLineIdsKey]);
|
|
67954
|
+
React148.useEffect(() => {
|
|
67955
|
+
if (typeof window === "undefined") {
|
|
67956
|
+
return;
|
|
67957
|
+
}
|
|
67958
|
+
try {
|
|
67959
|
+
if (slideshowActiveLineId) {
|
|
67960
|
+
sessionStorage.setItem(SLIDESHOW_ACTIVE_LINE_STORAGE_KEY, slideshowActiveLineId);
|
|
67961
|
+
} else {
|
|
67962
|
+
sessionStorage.removeItem(SLIDESHOW_ACTIVE_LINE_STORAGE_KEY);
|
|
67963
|
+
}
|
|
67964
|
+
} catch {
|
|
67965
|
+
}
|
|
67966
|
+
}, [slideshowActiveLineId]);
|
|
67967
|
+
React148.useEffect(() => {
|
|
67968
|
+
if (displayMode !== "slideshow") {
|
|
67969
|
+
return void 0;
|
|
67970
|
+
}
|
|
67971
|
+
const markActivity = () => {
|
|
67972
|
+
slideshowLastUserActivityAtRef.current = Date.now();
|
|
67973
|
+
};
|
|
67974
|
+
const eventOptions = { passive: true };
|
|
67975
|
+
const activityEvents = ["mousemove", "mousedown", "keydown", "touchstart", "wheel"];
|
|
67976
|
+
activityEvents.forEach((eventName) => {
|
|
67977
|
+
window.addEventListener(eventName, markActivity, eventOptions);
|
|
67978
|
+
});
|
|
67979
|
+
return () => {
|
|
67980
|
+
activityEvents.forEach((eventName) => {
|
|
67981
|
+
window.removeEventListener(eventName, markActivity, eventOptions);
|
|
67982
|
+
});
|
|
67983
|
+
};
|
|
67984
|
+
}, [displayMode]);
|
|
67985
|
+
React148.useEffect(() => {
|
|
67986
|
+
if (displayMode !== "slideshow" || slideshowLineIds.length <= 1) {
|
|
67987
|
+
return void 0;
|
|
67988
|
+
}
|
|
67989
|
+
const intervalId = window.setInterval(() => {
|
|
67990
|
+
const nowMs2 = Date.now();
|
|
67991
|
+
if (nowMs2 - slideshowLastUserActivityAtRef.current < SLIDESHOW_IDLE_REQUIRED_MS) {
|
|
67992
|
+
return;
|
|
67993
|
+
}
|
|
67994
|
+
setSlideshowActiveLineId((previousLineId) => {
|
|
67995
|
+
const previousIndex = previousLineId ? slideshowLineIds.indexOf(previousLineId) : -1;
|
|
67996
|
+
const nextIndex = previousIndex >= 0 ? (previousIndex + 1) % slideshowLineIds.length : 0;
|
|
67997
|
+
return slideshowLineIds[nextIndex] || null;
|
|
67998
|
+
});
|
|
67999
|
+
}, SLIDESHOW_ROTATION_INTERVAL_MS);
|
|
68000
|
+
return () => {
|
|
68001
|
+
window.clearInterval(intervalId);
|
|
68002
|
+
};
|
|
68003
|
+
}, [displayMode, slideshowLineIdsKey, slideshowLineIds]);
|
|
67613
68004
|
const [breakNotificationsDismissed, setBreakNotificationsDismissed] = React148.useState(false);
|
|
67614
68005
|
React148.useEffect(() => {
|
|
67615
68006
|
if (currentActiveBreaks.length > 0) {
|
|
@@ -67621,6 +68012,11 @@ function HomeView({
|
|
|
67621
68012
|
() => workspaceMetricsWithBreakState.filter((workspace) => Boolean(workspace.workspace_uuid || workspace.workspace_name)).length,
|
|
67622
68013
|
[workspaceMetricsWithBreakState]
|
|
67623
68014
|
);
|
|
68015
|
+
const worstPerformanceWorkspaceIds = React148.useMemo(
|
|
68016
|
+
() => Array.from(selectWorstPerformanceWorkspaceIds(workspaceMetricsWithBreakState)),
|
|
68017
|
+
[workspaceMetricsWithBreakState]
|
|
68018
|
+
);
|
|
68019
|
+
const activeWorstPerformanceWorkspaceIds = displayMode === "worst_workstations" ? worstPerformanceWorkspaceIds : EMPTY_LINE_IDS;
|
|
67624
68020
|
const allGreenCelebrationSignature = React148.useMemo(() => {
|
|
67625
68021
|
const workspaceSignature = workspaceMetricsWithBreakState.map((workspace) => workspace.workspace_uuid || `${workspace.line_id}:${workspace.workspace_name}`).filter(Boolean).sort().join(",");
|
|
67626
68022
|
return `${selectedLineIds.join(",")}::${workspaceSignature}`;
|
|
@@ -68257,6 +68653,10 @@ function HomeView({
|
|
|
68257
68653
|
selection_mode: isAllLinesSelection(normalizedLineIds) ? "all" : normalizedLineIds.length === 1 ? "single" : "custom",
|
|
68258
68654
|
line_name: getLineSelectionLabel(normalizedLineIds)
|
|
68259
68655
|
});
|
|
68656
|
+
trackCoreEvent("Dashboard Filter Selected", {
|
|
68657
|
+
filter_type: "Line Filter",
|
|
68658
|
+
filter_value: getLineSelectionLabel(normalizedLineIds)
|
|
68659
|
+
});
|
|
68260
68660
|
}, [factoryViewId, getLineSelectionLabel, getTrackedLineScope, selectedLineIds, selectedLineIdsKey, visibleLineIds]);
|
|
68261
68661
|
React148.useCallback(() => {
|
|
68262
68662
|
updateSelectedLineIds(visibleLineIds);
|
|
@@ -68305,13 +68705,26 @@ function HomeView({
|
|
|
68305
68705
|
"button",
|
|
68306
68706
|
{
|
|
68307
68707
|
type: "button",
|
|
68308
|
-
onClick: () =>
|
|
68708
|
+
onClick: () => {
|
|
68709
|
+
const willOpen = !isLineSelectorOpen;
|
|
68710
|
+
setIsLineSelectorOpen(willOpen);
|
|
68711
|
+
if (willOpen) {
|
|
68712
|
+
trackCoreEvent("Monitor Line Selector Menu Opened", {
|
|
68713
|
+
selection_source: "home_line_selector",
|
|
68714
|
+
current_display_mode: displayMode,
|
|
68715
|
+
current_display_mode_label: getHomeDisplayModeLabel(displayMode),
|
|
68716
|
+
selected_line_ids: selectedLineIds,
|
|
68717
|
+
selected_line_count: selectedLineIds.length,
|
|
68718
|
+
is_all_lines: isAllLinesSelection(selectedLineIds)
|
|
68719
|
+
});
|
|
68720
|
+
}
|
|
68721
|
+
},
|
|
68309
68722
|
className: "flex min-w-[180px] items-center justify-between gap-2 rounded-md border border-slate-200 bg-white px-3 py-1.5 text-left text-sm font-medium shadow-sm transition-colors hover:bg-slate-50 text-slate-700",
|
|
68310
68723
|
"aria-haspopup": "menu",
|
|
68311
68724
|
"aria-expanded": isLineSelectorOpen,
|
|
68312
68725
|
"aria-label": "Select lines",
|
|
68313
68726
|
children: [
|
|
68314
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: getLineSelectionLabel(selectedLineIds) }),
|
|
68727
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: displayMode === "slideshow" && slideshowActiveLineId ? getLineSelectionLabel([slideshowActiveLineId]) : getLineSelectionLabel(selectedLineIds) }),
|
|
68315
68728
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: `h-4 w-4 text-slate-400 transition-transform ${isLineSelectorOpen ? "rotate-180" : ""}` })
|
|
68316
68729
|
]
|
|
68317
68730
|
}
|
|
@@ -68407,10 +68820,111 @@ function HomeView({
|
|
|
68407
68820
|
selectedLineIds,
|
|
68408
68821
|
pendingSelectedLineIds,
|
|
68409
68822
|
lineSelectorSignalStatusByLine,
|
|
68823
|
+
displayMode,
|
|
68824
|
+
slideshowActiveLineId,
|
|
68410
68825
|
visibleLineIds,
|
|
68411
68826
|
updateSelectedLineIds,
|
|
68412
68827
|
isAllLinesSelection
|
|
68413
68828
|
]);
|
|
68829
|
+
const displayModeSelectorComponent = React148.useMemo(() => /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: displayModeSelectorRef, className: "relative", children: [
|
|
68830
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
68831
|
+
"button",
|
|
68832
|
+
{
|
|
68833
|
+
type: "button",
|
|
68834
|
+
onClick: () => {
|
|
68835
|
+
setIsLineSelectorOpen(false);
|
|
68836
|
+
const willOpen = !isDisplayModeMenuOpen;
|
|
68837
|
+
setIsDisplayModeMenuOpen(willOpen);
|
|
68838
|
+
if (willOpen) {
|
|
68839
|
+
trackCoreEvent("Monitor Display Filter Menu Opened", {
|
|
68840
|
+
selection_source: "home_display_filter",
|
|
68841
|
+
current_display_mode: displayMode,
|
|
68842
|
+
current_display_mode_label: getHomeDisplayModeLabel(displayMode),
|
|
68843
|
+
selected_line_ids: selectedLineIds,
|
|
68844
|
+
selected_line_count: selectedLineIds.length
|
|
68845
|
+
});
|
|
68846
|
+
}
|
|
68847
|
+
},
|
|
68848
|
+
className: `inline-flex h-9 w-9 items-center justify-center rounded-md border shadow-sm transition-colors ${displayMode === "all" ? "border-slate-200 bg-white text-slate-500 hover:bg-slate-50 hover:text-slate-700" : "border-blue-200 bg-blue-50 text-blue-600 hover:bg-blue-100"}`,
|
|
68849
|
+
"aria-haspopup": "menu",
|
|
68850
|
+
"aria-expanded": isDisplayModeMenuOpen,
|
|
68851
|
+
"aria-label": `Display mode: ${getHomeDisplayModeLabel(displayMode)}`,
|
|
68852
|
+
title: `Display mode: ${getHomeDisplayModeLabel(displayMode)}`,
|
|
68853
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Monitor, { className: "h-4 w-4" })
|
|
68854
|
+
}
|
|
68855
|
+
),
|
|
68856
|
+
isDisplayModeMenuOpen ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
68857
|
+
"div",
|
|
68858
|
+
{
|
|
68859
|
+
role: "menu",
|
|
68860
|
+
"aria-label": "Display modes",
|
|
68861
|
+
className: "absolute right-0 top-full z-50 mt-1.5 w-64 rounded-md border border-slate-200 bg-white py-1 shadow-lg ring-1 ring-black/5 focus:outline-none",
|
|
68862
|
+
children: HOME_DISPLAY_MODE_OPTIONS.map((option) => {
|
|
68863
|
+
const isSelected = option.id === displayMode;
|
|
68864
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
68865
|
+
"button",
|
|
68866
|
+
{
|
|
68867
|
+
type: "button",
|
|
68868
|
+
role: "menuitemradio",
|
|
68869
|
+
"aria-checked": isSelected,
|
|
68870
|
+
onClick: () => {
|
|
68871
|
+
const nextSelectedLineIds = option.id === "slideshow" ? visibleLineIds : selectedLineIds;
|
|
68872
|
+
const selectedViewProperties = {
|
|
68873
|
+
view_type: option.id,
|
|
68874
|
+
view_label: option.label,
|
|
68875
|
+
is_slideshow: option.id === "slideshow",
|
|
68876
|
+
selection_source: "home_display_filter"
|
|
68877
|
+
};
|
|
68878
|
+
setDisplayMode(option.id);
|
|
68879
|
+
if (option.id === "slideshow") {
|
|
68880
|
+
updateSelectedLineIds(visibleLineIds);
|
|
68881
|
+
}
|
|
68882
|
+
setIsDisplayModeMenuOpen(false);
|
|
68883
|
+
trackCoreEvent("Monitor Display Filter Selected", {
|
|
68884
|
+
filter_name: option.label,
|
|
68885
|
+
filter_id: option.id,
|
|
68886
|
+
...selectedViewProperties,
|
|
68887
|
+
previous_display_mode: displayMode,
|
|
68888
|
+
previous_display_mode_label: getHomeDisplayModeLabel(displayMode),
|
|
68889
|
+
selected_line_ids: nextSelectedLineIds,
|
|
68890
|
+
selected_line_count: nextSelectedLineIds.length,
|
|
68891
|
+
highlighted_workspace_count: option.id === "worst_workstations" ? worstPerformanceWorkspaceIds.length : 0
|
|
68892
|
+
});
|
|
68893
|
+
trackCoreEvent("Dashboard Filter Selected", {
|
|
68894
|
+
filter_type: "Display Mode",
|
|
68895
|
+
filter_value: option.label,
|
|
68896
|
+
filter_id: option.id,
|
|
68897
|
+
previous_filter_value: getHomeDisplayModeLabel(displayMode),
|
|
68898
|
+
...selectedViewProperties,
|
|
68899
|
+
selected_line_ids: nextSelectedLineIds,
|
|
68900
|
+
selected_line_count: nextSelectedLineIds.length
|
|
68901
|
+
});
|
|
68902
|
+
trackCoreEvent(`Display View Selected: ${option.label}`, {
|
|
68903
|
+
mode_id: option.id,
|
|
68904
|
+
mode_label: option.label,
|
|
68905
|
+
previous_display_mode: displayMode,
|
|
68906
|
+
previous_display_mode_label: getHomeDisplayModeLabel(displayMode),
|
|
68907
|
+
...selectedViewProperties,
|
|
68908
|
+
selected_line_ids: nextSelectedLineIds,
|
|
68909
|
+
selected_line_count: nextSelectedLineIds.length,
|
|
68910
|
+
highlighted_workspace_count: option.id === "worst_workstations" ? worstPerformanceWorkspaceIds.length : 0
|
|
68911
|
+
});
|
|
68912
|
+
},
|
|
68913
|
+
className: "flex w-full items-start px-4 py-2.5 text-left transition-colors hover:bg-slate-50",
|
|
68914
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-col", children: [
|
|
68915
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
68916
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-sm ${isSelected ? "font-semibold text-blue-600" : "font-medium text-slate-700"}`, children: option.label }),
|
|
68917
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-3 inline-flex items-center gap-2", children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-blue-600" }) })
|
|
68918
|
+
] }),
|
|
68919
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-1 text-xs text-slate-500", children: option.description })
|
|
68920
|
+
] })
|
|
68921
|
+
},
|
|
68922
|
+
option.id
|
|
68923
|
+
);
|
|
68924
|
+
})
|
|
68925
|
+
}
|
|
68926
|
+
) : null
|
|
68927
|
+
] }), [displayMode, isDisplayModeMenuOpen, selectedLineIds, updateSelectedLineIds, visibleLineIds, worstPerformanceWorkspaceIds]);
|
|
68414
68928
|
const gridToolbarControls = React148.useMemo(() => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2", children: [
|
|
68415
68929
|
/* @__PURE__ */ jsxRuntime.jsx(AnimatePresence, { children: visibleAllGreenStreakDisplay ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
68416
68930
|
motion.div,
|
|
@@ -68428,8 +68942,10 @@ function HomeView({
|
|
|
68428
68942
|
},
|
|
68429
68943
|
visibleAllGreenStreakDisplay.startedAt
|
|
68430
68944
|
) : null }),
|
|
68431
|
-
lineSelectorComponent
|
|
68945
|
+
lineSelectorComponent,
|
|
68946
|
+
displayModeSelectorComponent
|
|
68432
68947
|
] }), [
|
|
68948
|
+
displayModeSelectorComponent,
|
|
68433
68949
|
lineSelectorComponent,
|
|
68434
68950
|
visibleAllGreenStreakDisplay
|
|
68435
68951
|
]);
|
|
@@ -68606,14 +69122,17 @@ function HomeView({
|
|
|
68606
69122
|
children: React148__namespace.default.createElement(WorkspaceGrid, {
|
|
68607
69123
|
workspaces: workspaceMetricsWithBreakState,
|
|
68608
69124
|
blueComparisonWorkspaces: currentBlueComparisonWorkspaceMetrics || workspaceMetricsWithBreakState,
|
|
69125
|
+
worstPerformanceWorkspaceIds: activeWorstPerformanceWorkspaceIds,
|
|
68609
69126
|
lineNames: mergedLineNames,
|
|
68610
|
-
lineOrder: selectedLineIds,
|
|
69127
|
+
lineOrder: displayMode === "slideshow" ? slideshowLineIds : selectedLineIds,
|
|
69128
|
+
activeSlideshowLineId: displayMode === "slideshow" ? slideshowActiveLineId : null,
|
|
68611
69129
|
factoryView: factoryViewId,
|
|
68612
69130
|
legend: effectiveEfficiencyLegend,
|
|
68613
69131
|
videoSources,
|
|
68614
69132
|
videoStreamsByWorkspaceId: currentVideoStreamsByWorkspaceId,
|
|
68615
69133
|
videoStreamsLoading: currentVideoStreamsLoading,
|
|
68616
69134
|
displayNames: metricsDisplayNames,
|
|
69135
|
+
displayMode,
|
|
68617
69136
|
hasFlowBuffers,
|
|
68618
69137
|
className: "h-full",
|
|
68619
69138
|
toolbarRightContent: gridToolbarControls,
|
|
@@ -68640,14 +69159,17 @@ function HomeView({
|
|
|
68640
69159
|
workspaces: [],
|
|
68641
69160
|
// Show empty grid while loading
|
|
68642
69161
|
blueComparisonWorkspaces: [],
|
|
69162
|
+
worstPerformanceWorkspaceIds: [],
|
|
68643
69163
|
lineNames: mergedLineNames,
|
|
68644
|
-
lineOrder: selectedLineIds,
|
|
69164
|
+
lineOrder: displayMode === "slideshow" ? slideshowLineIds : selectedLineIds,
|
|
69165
|
+
activeSlideshowLineId: displayMode === "slideshow" ? slideshowActiveLineId : null,
|
|
68645
69166
|
factoryView: factoryViewId,
|
|
68646
69167
|
legend: effectiveEfficiencyLegend,
|
|
68647
69168
|
videoSources,
|
|
68648
69169
|
videoStreamsByWorkspaceId: currentVideoStreamsByWorkspaceId,
|
|
68649
69170
|
videoStreamsLoading: currentVideoStreamsLoading,
|
|
68650
69171
|
displayNames: metricsDisplayNames,
|
|
69172
|
+
displayMode,
|
|
68651
69173
|
hasFlowBuffers,
|
|
68652
69174
|
className: "h-full",
|
|
68653
69175
|
toolbarRightContent: gridToolbarControls,
|
|
@@ -81088,9 +81610,11 @@ var WorkspaceDetailView = ({
|
|
|
81088
81610
|
const prefetchLowMoments = async () => {
|
|
81089
81611
|
try {
|
|
81090
81612
|
const initData = await s3Service.getClipsInit(workspaceId, resolvedDate, resolvedShiftId, totalOutput);
|
|
81091
|
-
const
|
|
81613
|
+
const hasLowMomentsCategory = Array.isArray(initData?.clipTypes) ? initData.clipTypes.some((type) => type?.type === "recent_flow_red_streak" || type?.id === "recent_flow_red_streak") : false;
|
|
81614
|
+
const lowMomentsCount = hasLowMomentsCategory ? Number(initData?.counts?.recent_flow_red_streak || 0) : 0;
|
|
81092
81615
|
const lowMomentsKey = [
|
|
81093
81616
|
"recent_flow_red_streak",
|
|
81617
|
+
workspaceId,
|
|
81094
81618
|
resolvedDate,
|
|
81095
81619
|
resolvedShiftId,
|
|
81096
81620
|
initData?.snapshotDateTime ?? "nosnap",
|
|
@@ -81101,15 +81625,15 @@ var WorkspaceDetailView = ({
|
|
|
81101
81625
|
return;
|
|
81102
81626
|
}
|
|
81103
81627
|
const initFirstVideo = initData?.firstClips?.recent_flow_red_streak ?? null;
|
|
81104
|
-
if (lowMomentsCount <= 0) {
|
|
81105
|
-
setLowMomentsPrefetch(
|
|
81628
|
+
if (!hasLowMomentsCategory || lowMomentsCount <= 0) {
|
|
81629
|
+
setLowMomentsPrefetch({
|
|
81106
81630
|
key: lowMomentsKey,
|
|
81107
81631
|
metadata: [],
|
|
81108
81632
|
firstVideo: null,
|
|
81109
81633
|
total: 0,
|
|
81110
81634
|
loading: false,
|
|
81111
81635
|
error: null
|
|
81112
|
-
}
|
|
81636
|
+
});
|
|
81113
81637
|
prewarmedClipsRef.current.add(cacheKey);
|
|
81114
81638
|
return;
|
|
81115
81639
|
}
|