@optifye/dashboard-core 6.11.24 → 6.11.25
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.css +6 -21
- package/dist/index.d.mts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +531 -285
- package/dist/index.mjs +531 -285
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -13255,7 +13255,7 @@ var parseEfficiencyLegend = (legend) => {
|
|
|
13255
13255
|
critical_threshold: coerce(legend.critical_threshold, DEFAULT_EFFICIENCY_LEGEND.critical_threshold)
|
|
13256
13256
|
};
|
|
13257
13257
|
};
|
|
13258
|
-
var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds }) => {
|
|
13258
|
+
var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibleLineIds }) => {
|
|
13259
13259
|
const { supabaseUrl, supabaseKey } = useDashboardConfig();
|
|
13260
13260
|
const entityConfig = useEntityConfig();
|
|
13261
13261
|
const databaseConfig = useDatabaseConfig();
|
|
@@ -13272,9 +13272,9 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13272
13272
|
return getConfiguredLineIds(entityConfig);
|
|
13273
13273
|
}, [entityConfig]);
|
|
13274
13274
|
const targetFactoryLineIds = useMemo(() => {
|
|
13275
|
-
const sourceLineIds = userAccessibleLineIds !== void 0 ? userAccessibleLineIds : configuredLineIds;
|
|
13275
|
+
const sourceLineIds = lineIds !== void 0 ? lineIds : userAccessibleLineIds !== void 0 ? userAccessibleLineIds : configuredLineIds;
|
|
13276
13276
|
return Array.from(new Set((sourceLineIds || []).filter(Boolean)));
|
|
13277
|
-
}, [userAccessibleLineIds, configuredLineIds]);
|
|
13277
|
+
}, [lineIds, userAccessibleLineIds, configuredLineIds]);
|
|
13278
13278
|
const { shiftConfig: staticShiftConfig } = useDashboardConfig();
|
|
13279
13279
|
const {
|
|
13280
13280
|
shiftConfigMap: multiLineShiftConfigMap,
|
|
@@ -13327,6 +13327,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13327
13327
|
const operationalShiftKeyRef = useRef(operationalShiftKey);
|
|
13328
13328
|
const configuredLineIdsRef = useRef(configuredLineIds);
|
|
13329
13329
|
const userAccessibleLineIdsRef = useRef(userAccessibleLineIds);
|
|
13330
|
+
const explicitLineIdsRef = useRef(lineIds);
|
|
13330
13331
|
useEffect(() => {
|
|
13331
13332
|
onLineMetricsUpdateRef.current = onLineMetricsUpdate;
|
|
13332
13333
|
}, [onLineMetricsUpdate]);
|
|
@@ -13342,6 +13343,9 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13342
13343
|
useEffect(() => {
|
|
13343
13344
|
userAccessibleLineIdsRef.current = userAccessibleLineIds;
|
|
13344
13345
|
}, [userAccessibleLineIds]);
|
|
13346
|
+
useEffect(() => {
|
|
13347
|
+
explicitLineIdsRef.current = lineIds;
|
|
13348
|
+
}, [lineIds]);
|
|
13345
13349
|
const companySpecificMetricsTable = useMemo(
|
|
13346
13350
|
() => getCompanyMetricsTableName(entityConfig.companyId, "performance_metrics"),
|
|
13347
13351
|
[entityConfig.companyId]
|
|
@@ -13692,6 +13696,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13692
13696
|
isFactoryView,
|
|
13693
13697
|
multiLineShiftConfigMap,
|
|
13694
13698
|
staticShiftConfig,
|
|
13699
|
+
lineIds,
|
|
13695
13700
|
userAccessibleLineIds,
|
|
13696
13701
|
effectiveWorkspaceConfig,
|
|
13697
13702
|
shiftLoading,
|
|
@@ -13809,7 +13814,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13809
13814
|
logDebug("[useDashboardMetrics] Setting up group subscriptions:", {
|
|
13810
13815
|
groupCount: currentShiftGroups.length
|
|
13811
13816
|
});
|
|
13812
|
-
const targetFactoryLineIdsForSubscriptions = currentUserAccessibleLineIds !== void 0 ? currentUserAccessibleLineIds : currentConfiguredLineIds;
|
|
13817
|
+
const targetFactoryLineIdsForSubscriptions = explicitLineIdsRef.current !== void 0 ? explicitLineIdsRef.current : currentUserAccessibleLineIds !== void 0 ? currentUserAccessibleLineIds : currentConfiguredLineIds;
|
|
13813
13818
|
const targetFactoryLineIdSet = new Set(
|
|
13814
13819
|
(targetFactoryLineIdsForSubscriptions || []).filter(Boolean)
|
|
13815
13820
|
);
|
|
@@ -13980,7 +13985,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13980
13985
|
});
|
|
13981
13986
|
const currentShiftDetails = shiftConfig ? getCurrentShift(defaultTimezone, shiftConfig) : getCurrentShift(defaultTimezone, staticShiftConfig);
|
|
13982
13987
|
const operationalDateForSubscription = currentShiftDetails.date;
|
|
13983
|
-
const targetLineIds = isFactory ? currentUserAccessibleLineIds || currentConfiguredLineIds : [currentLineIdToUse];
|
|
13988
|
+
const targetLineIds = isFactory ? explicitLineIdsRef.current || currentUserAccessibleLineIds || currentConfiguredLineIds : [currentLineIdToUse];
|
|
13984
13989
|
const filteredLineIds = targetLineIds.filter((id3) => id3 && id3 !== factoryViewIdentifier);
|
|
13985
13990
|
if (filteredLineIds.length === 0) {
|
|
13986
13991
|
logDebug("[useDashboardMetrics] Realtime setup skipped: no line IDs after filtering", {
|
|
@@ -20394,13 +20399,15 @@ var buildKPIsFromLineMetricsRow = (row) => {
|
|
|
20394
20399
|
};
|
|
20395
20400
|
var aggregateKPIsFromLineMetricsRows = (rows) => {
|
|
20396
20401
|
if (!rows || rows.length === 0) return createDefaultKPIs();
|
|
20397
|
-
const
|
|
20398
|
-
|
|
20399
|
-
const
|
|
20402
|
+
const eligibleRows = rows.filter((row) => toNumber(row?.avg_efficiency) >= 5);
|
|
20403
|
+
if (eligibleRows.length === 0) return createDefaultKPIs();
|
|
20404
|
+
const currentOutputSum = eligibleRows.reduce((sum, row) => sum + toNumber(row.current_output), 0);
|
|
20405
|
+
const lineThresholdSum = eligibleRows.reduce((sum, row) => sum + toNumber(row.line_threshold), 0);
|
|
20406
|
+
const idealOutputSum = eligibleRows.reduce(
|
|
20400
20407
|
(sum, row) => sum + (toNumber(row.ideal_output) || toNumber(row.line_threshold)),
|
|
20401
20408
|
0
|
|
20402
20409
|
);
|
|
20403
|
-
const efficiencyValues =
|
|
20410
|
+
const efficiencyValues = eligibleRows.map((row) => {
|
|
20404
20411
|
const value = row?.avg_efficiency;
|
|
20405
20412
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
20406
20413
|
if (typeof value === "string" && value.trim() !== "") {
|
|
@@ -20410,10 +20417,10 @@ var aggregateKPIsFromLineMetricsRows = (rows) => {
|
|
|
20410
20417
|
return null;
|
|
20411
20418
|
}).filter((value) => value !== null);
|
|
20412
20419
|
const avgEfficiency = efficiencyValues.length > 0 ? efficiencyValues.reduce((sum, value) => sum + value, 0) / efficiencyValues.length : 0;
|
|
20413
|
-
const numLines =
|
|
20414
|
-
const avgCycleTime = numLines > 0 ?
|
|
20415
|
-
const totalUnderperforming =
|
|
20416
|
-
const totalWorkspaces =
|
|
20420
|
+
const numLines = eligibleRows.length;
|
|
20421
|
+
const avgCycleTime = numLines > 0 ? eligibleRows.reduce((sum, row) => sum + toNumber(row.avg_cycle_time), 0) / numLines : 0;
|
|
20422
|
+
const totalUnderperforming = eligibleRows.reduce((sum, row) => sum + toNumber(row.underperforming_workspaces), 0);
|
|
20423
|
+
const totalWorkspaces = eligibleRows.reduce((sum, row) => sum + toNumber(row.total_workspaces), 0);
|
|
20417
20424
|
return {
|
|
20418
20425
|
underperformingWorkers: {
|
|
20419
20426
|
current: totalUnderperforming,
|
|
@@ -34569,6 +34576,8 @@ var logDebug2 = (...args) => {
|
|
|
34569
34576
|
var VideoGridView = React142__default.memo(({
|
|
34570
34577
|
workspaces,
|
|
34571
34578
|
selectedLine,
|
|
34579
|
+
lineNames = {},
|
|
34580
|
+
lineOrder = [],
|
|
34572
34581
|
className = "",
|
|
34573
34582
|
legend,
|
|
34574
34583
|
videoSources = {},
|
|
@@ -34671,6 +34680,44 @@ var VideoGridView = React142__default.memo(({
|
|
|
34671
34680
|
}
|
|
34672
34681
|
}) : workspaces;
|
|
34673
34682
|
}, [workspaces, selectedLine]);
|
|
34683
|
+
const sortedWorkspaces = useMemo(() => {
|
|
34684
|
+
return [...filteredWorkspaces].sort((a, b) => {
|
|
34685
|
+
if (a.line_id !== b.line_id) {
|
|
34686
|
+
return (a.line_id || "").localeCompare(b.line_id || "");
|
|
34687
|
+
}
|
|
34688
|
+
const aMatch = a.workspace_name.match(/WS(\d+)/);
|
|
34689
|
+
const bMatch = b.workspace_name.match(/WS(\d+)/);
|
|
34690
|
+
if (aMatch && bMatch) {
|
|
34691
|
+
const aNum = parseInt(aMatch[1], 10);
|
|
34692
|
+
const bNum = parseInt(bMatch[1], 10);
|
|
34693
|
+
return aNum - bNum;
|
|
34694
|
+
}
|
|
34695
|
+
return a.workspace_name.localeCompare(b.workspace_name);
|
|
34696
|
+
});
|
|
34697
|
+
}, [filteredWorkspaces]);
|
|
34698
|
+
const lineGroups = useMemo(() => {
|
|
34699
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
34700
|
+
sortedWorkspaces.forEach((workspace) => {
|
|
34701
|
+
const lineId = workspace.line_id || "unknown";
|
|
34702
|
+
const existing = grouped.get(lineId);
|
|
34703
|
+
if (existing) {
|
|
34704
|
+
existing.push(workspace);
|
|
34705
|
+
return;
|
|
34706
|
+
}
|
|
34707
|
+
grouped.set(lineId, [workspace]);
|
|
34708
|
+
});
|
|
34709
|
+
const sortedRemainingLineIds = Array.from(grouped.keys()).sort((a, b) => a.localeCompare(b));
|
|
34710
|
+
const orderedLineIds = [
|
|
34711
|
+
...lineOrder.filter((lineId) => grouped.has(lineId)),
|
|
34712
|
+
...sortedRemainingLineIds.filter((lineId) => !lineOrder.includes(lineId))
|
|
34713
|
+
];
|
|
34714
|
+
return orderedLineIds.map((lineId) => ({
|
|
34715
|
+
lineId,
|
|
34716
|
+
lineName: lineNames[lineId] || `Line ${lineId.substring(0, 4)}`,
|
|
34717
|
+
workspaces: grouped.get(lineId) || []
|
|
34718
|
+
}));
|
|
34719
|
+
}, [sortedWorkspaces, lineOrder, lineNames]);
|
|
34720
|
+
lineGroups.length > 1;
|
|
34674
34721
|
const streamsReady = !videoStreamsLoading;
|
|
34675
34722
|
const calculateOptimalGrid = useCallback(() => {
|
|
34676
34723
|
if (!containerRef.current) return;
|
|
@@ -34834,108 +34881,130 @@ var VideoGridView = React142__default.memo(({
|
|
|
34834
34881
|
stream_source: isR2Stream ? "r2" : "media_config"
|
|
34835
34882
|
});
|
|
34836
34883
|
}, []);
|
|
34884
|
+
const workspaceCards = useMemo(() => {
|
|
34885
|
+
return sortedWorkspaces.map((workspace) => {
|
|
34886
|
+
const workspaceId = workspace.workspace_uuid || workspace.workspace_name;
|
|
34887
|
+
const workspaceKey = `${workspace.line_id || "unknown"}-${workspaceId}`;
|
|
34888
|
+
const isVisible = visibleWorkspaces.has(workspaceId);
|
|
34889
|
+
const isVeryLowEfficiency = workspace.show_exclamation ?? (workspace.efficiency < 50 && workspace.efficiency >= 10);
|
|
34890
|
+
const workspaceCropping = getWorkspaceCropping(workspaceId, workspace.workspace_name);
|
|
34891
|
+
const workspaceStream = videoStreamsByWorkspaceId?.[workspaceId];
|
|
34892
|
+
const lastSeenLabel = workspace.workspace_uuid ? lastSeenByWorkspaceId[workspace.workspace_uuid]?.timeSinceLastUpdate : void 0;
|
|
34893
|
+
const r2Url = workspaceStream?.hls_url;
|
|
34894
|
+
const fallbackUrl = getWorkspaceHlsUrl(workspace.workspace_name, workspace.line_id);
|
|
34895
|
+
const hasR2Stream = Boolean(r2Url);
|
|
34896
|
+
const useFallback = r2FallbackWorkspaces.has(workspaceId) || streamsReady && !hasR2Stream;
|
|
34897
|
+
const hlsUrl = useFallback ? fallbackUrl : r2Url ?? "";
|
|
34898
|
+
const isR2Stream = !useFallback && hasR2Stream;
|
|
34899
|
+
const canAttemptR2 = hasR2Stream && !r2FallbackWorkspaces.has(workspaceId);
|
|
34900
|
+
const shouldPlay = isVisible && Boolean(hlsUrl) && (!failedStreams.has(workspaceId) || canAttemptR2);
|
|
34901
|
+
return {
|
|
34902
|
+
workspace,
|
|
34903
|
+
workspaceId,
|
|
34904
|
+
workspaceKey,
|
|
34905
|
+
isVisible,
|
|
34906
|
+
isVeryLowEfficiency,
|
|
34907
|
+
workspaceCropping,
|
|
34908
|
+
fallbackUrl,
|
|
34909
|
+
hlsUrl,
|
|
34910
|
+
isR2Stream,
|
|
34911
|
+
shouldPlay,
|
|
34912
|
+
lastSeenLabel
|
|
34913
|
+
};
|
|
34914
|
+
});
|
|
34915
|
+
}, [
|
|
34916
|
+
sortedWorkspaces,
|
|
34917
|
+
visibleWorkspaces,
|
|
34918
|
+
getWorkspaceCropping,
|
|
34919
|
+
videoStreamsByWorkspaceId,
|
|
34920
|
+
lastSeenByWorkspaceId,
|
|
34921
|
+
getWorkspaceHlsUrl,
|
|
34922
|
+
r2FallbackWorkspaces,
|
|
34923
|
+
streamsReady,
|
|
34924
|
+
failedStreams
|
|
34925
|
+
]);
|
|
34926
|
+
useMemo(() => {
|
|
34927
|
+
const map = /* @__PURE__ */ new Map();
|
|
34928
|
+
workspaceCards.forEach((card) => {
|
|
34929
|
+
map.set(card.workspaceKey, card);
|
|
34930
|
+
});
|
|
34931
|
+
return map;
|
|
34932
|
+
}, [workspaceCards]);
|
|
34933
|
+
const croppedActiveCount = useMemo(() => {
|
|
34934
|
+
return workspaceCards.reduce((count, card) => {
|
|
34935
|
+
if (card.shouldPlay && card.workspaceCropping) {
|
|
34936
|
+
return count + 1;
|
|
34937
|
+
}
|
|
34938
|
+
return count;
|
|
34939
|
+
}, 0);
|
|
34940
|
+
}, [workspaceCards]);
|
|
34941
|
+
const throttleCropping = croppedActiveCount > 10;
|
|
34942
|
+
const effectiveCanvasFps = throttleCropping ? 10 : canvasConfig?.fps;
|
|
34943
|
+
const effectiveUseRAF = throttleCropping ? false : canvasConfig?.useRAF;
|
|
34837
34944
|
const displayMinuteBucket = Math.floor(Date.now() / 6e4);
|
|
34838
|
-
|
|
34945
|
+
const renderWorkspaceCard = useCallback((card, className2) => /* @__PURE__ */ jsx(
|
|
34839
34946
|
"div",
|
|
34840
34947
|
{
|
|
34841
|
-
|
|
34842
|
-
|
|
34843
|
-
|
|
34844
|
-
|
|
34845
|
-
|
|
34846
|
-
|
|
34847
|
-
|
|
34848
|
-
|
|
34849
|
-
|
|
34850
|
-
|
|
34851
|
-
|
|
34852
|
-
|
|
34853
|
-
|
|
34854
|
-
|
|
34855
|
-
|
|
34856
|
-
|
|
34857
|
-
|
|
34858
|
-
}
|
|
34859
|
-
|
|
34860
|
-
|
|
34861
|
-
|
|
34862
|
-
|
|
34863
|
-
|
|
34864
|
-
|
|
34865
|
-
|
|
34866
|
-
|
|
34867
|
-
|
|
34868
|
-
|
|
34869
|
-
|
|
34870
|
-
|
|
34871
|
-
|
|
34872
|
-
|
|
34873
|
-
|
|
34874
|
-
|
|
34875
|
-
|
|
34876
|
-
|
|
34877
|
-
|
|
34878
|
-
|
|
34879
|
-
|
|
34880
|
-
|
|
34881
|
-
|
|
34882
|
-
|
|
34883
|
-
|
|
34884
|
-
|
|
34885
|
-
|
|
34886
|
-
|
|
34887
|
-
|
|
34888
|
-
|
|
34889
|
-
|
|
34890
|
-
|
|
34891
|
-
|
|
34892
|
-
|
|
34893
|
-
|
|
34894
|
-
|
|
34895
|
-
}, 0);
|
|
34896
|
-
const throttleCropping = croppedActiveCount > 10;
|
|
34897
|
-
const effectiveCanvasFps = throttleCropping ? 10 : canvasConfig?.fps;
|
|
34898
|
-
const effectiveUseRAF = throttleCropping ? false : canvasConfig?.useRAF;
|
|
34899
|
-
return workspaceCards.map((card) => /* @__PURE__ */ jsx(
|
|
34900
|
-
"div",
|
|
34901
|
-
{
|
|
34902
|
-
"data-workspace-id": card.workspaceId,
|
|
34903
|
-
className: "workspace-card relative w-full h-full",
|
|
34904
|
-
children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx(
|
|
34905
|
-
VideoCard,
|
|
34906
|
-
{
|
|
34907
|
-
workspace: card.workspace,
|
|
34908
|
-
hlsUrl: card.hlsUrl,
|
|
34909
|
-
shouldPlay: card.shouldPlay,
|
|
34910
|
-
onClick: () => handleWorkspaceClick(card.workspace),
|
|
34911
|
-
onFatalError: () => handleStreamError(card.workspaceId, {
|
|
34912
|
-
isR2Stream: card.isR2Stream,
|
|
34913
|
-
fallbackUrl: card.fallbackUrl
|
|
34914
|
-
}),
|
|
34915
|
-
isVeryLowEfficiency: card.isVeryLowEfficiency,
|
|
34916
|
-
legend: effectiveLegend,
|
|
34917
|
-
cropping: card.workspaceCropping,
|
|
34918
|
-
canvasFps: effectiveCanvasFps,
|
|
34919
|
-
displayName: (
|
|
34920
|
-
// Create line-aware lookup key: lineId_workspaceName
|
|
34921
|
-
// This ensures correct mapping when multiple lines have same workspace names
|
|
34922
|
-
displayNames[`${card.workspace.line_id}_${card.workspace.workspace_name}`] || // Always pass line_id to fallback to ensure correct mapping per line
|
|
34923
|
-
getWorkspaceDisplayName(card.workspace.workspace_name, card.workspace.line_id)
|
|
34924
|
-
),
|
|
34925
|
-
lastSeenLabel: card.lastSeenLabel,
|
|
34926
|
-
useRAF: effectiveUseRAF,
|
|
34927
|
-
displayMinuteBucket,
|
|
34928
|
-
compact: !selectedLine,
|
|
34929
|
-
onMouseEnter: onWorkspaceHover ? () => onWorkspaceHover(card.workspaceId) : void 0,
|
|
34930
|
-
onMouseLeave: onWorkspaceHoverEnd ? () => onWorkspaceHoverEnd(card.workspaceId) : void 0
|
|
34931
|
-
}
|
|
34932
|
-
) })
|
|
34948
|
+
"data-workspace-id": card.workspaceId,
|
|
34949
|
+
className: className2,
|
|
34950
|
+
children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx(
|
|
34951
|
+
VideoCard,
|
|
34952
|
+
{
|
|
34953
|
+
workspace: card.workspace,
|
|
34954
|
+
hlsUrl: card.hlsUrl,
|
|
34955
|
+
shouldPlay: card.shouldPlay,
|
|
34956
|
+
onClick: () => handleWorkspaceClick(card.workspace),
|
|
34957
|
+
onFatalError: () => handleStreamError(card.workspaceId, {
|
|
34958
|
+
isR2Stream: card.isR2Stream,
|
|
34959
|
+
fallbackUrl: card.fallbackUrl
|
|
34960
|
+
}),
|
|
34961
|
+
isVeryLowEfficiency: card.isVeryLowEfficiency,
|
|
34962
|
+
legend: effectiveLegend,
|
|
34963
|
+
cropping: card.workspaceCropping,
|
|
34964
|
+
canvasFps: effectiveCanvasFps,
|
|
34965
|
+
displayName: displayNames[`${card.workspace.line_id}_${card.workspace.workspace_name}`] || getWorkspaceDisplayName(card.workspace.workspace_name, card.workspace.line_id),
|
|
34966
|
+
lastSeenLabel: card.lastSeenLabel,
|
|
34967
|
+
useRAF: effectiveUseRAF,
|
|
34968
|
+
displayMinuteBucket,
|
|
34969
|
+
compact: !selectedLine,
|
|
34970
|
+
onMouseEnter: onWorkspaceHover ? () => onWorkspaceHover(card.workspaceId) : void 0,
|
|
34971
|
+
onMouseLeave: onWorkspaceHoverEnd ? () => onWorkspaceHoverEnd(card.workspaceId) : void 0
|
|
34972
|
+
}
|
|
34973
|
+
) })
|
|
34974
|
+
},
|
|
34975
|
+
card.workspaceKey
|
|
34976
|
+
), [
|
|
34977
|
+
displayNames,
|
|
34978
|
+
displayMinuteBucket,
|
|
34979
|
+
effectiveCanvasFps,
|
|
34980
|
+
effectiveLegend,
|
|
34981
|
+
effectiveUseRAF,
|
|
34982
|
+
getWorkspaceDisplayName,
|
|
34983
|
+
handleStreamError,
|
|
34984
|
+
handleWorkspaceClick,
|
|
34985
|
+
onWorkspaceHover,
|
|
34986
|
+
onWorkspaceHoverEnd,
|
|
34987
|
+
selectedLine
|
|
34988
|
+
]);
|
|
34989
|
+
return /* @__PURE__ */ jsx("div", { className: `relative overflow-hidden h-full w-full bg-slate-50/30 ${className}`, children: /* @__PURE__ */ jsx(
|
|
34990
|
+
"div",
|
|
34991
|
+
{
|
|
34992
|
+
ref: containerRef,
|
|
34993
|
+
className: "h-full w-full px-1 sm:px-2 py-1 sm:py-2",
|
|
34994
|
+
children: /* @__PURE__ */ jsx(
|
|
34995
|
+
"div",
|
|
34996
|
+
{
|
|
34997
|
+
className: "grid h-full w-full gap-1.5 sm:gap-2",
|
|
34998
|
+
style: {
|
|
34999
|
+
gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
|
|
35000
|
+
gridTemplateRows: `repeat(${gridRows}, 1fr)`,
|
|
35001
|
+
gridAutoFlow: "row"
|
|
34933
35002
|
},
|
|
34934
|
-
card
|
|
34935
|
-
|
|
34936
|
-
|
|
35003
|
+
children: workspaceCards.map((card) => renderWorkspaceCard(card, "workspace-card relative w-full h-full"))
|
|
35004
|
+
}
|
|
35005
|
+
)
|
|
34937
35006
|
}
|
|
34938
|
-
) })
|
|
35007
|
+
) });
|
|
34939
35008
|
});
|
|
34940
35009
|
VideoGridView.displayName = "VideoGridView";
|
|
34941
35010
|
var MapGridView = React142__default.memo(({
|
|
@@ -50358,29 +50427,29 @@ var Legend5 = ({
|
|
|
50358
50427
|
}) => {
|
|
50359
50428
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
50360
50429
|
const exclamationLabel = useBottleneckLabel ? "Bottleneck" : "<50% efficiency";
|
|
50361
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-
|
|
50430
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:gap-4 text-xs font-medium text-slate-600", children: [
|
|
50362
50431
|
/* @__PURE__ */ jsxs("div", { className: "font-medium text-gray-700 hidden sm:block", children: [
|
|
50363
50432
|
metricLabel,
|
|
50364
50433
|
":"
|
|
50365
50434
|
] }),
|
|
50366
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
50367
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
50368
|
-
/* @__PURE__ */ jsx("div", { className: "w-
|
|
50369
|
-
/* @__PURE__ */ jsx("span", {
|
|
50435
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 sm:gap-4", children: [
|
|
50436
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
50437
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full bg-[#00AB45]" }),
|
|
50438
|
+
/* @__PURE__ */ jsx("span", { children: formatPercentRange(effectiveLegend.green_min, effectiveLegend.green_max) })
|
|
50370
50439
|
] }),
|
|
50371
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
50372
|
-
/* @__PURE__ */ jsx("div", { className: "w-
|
|
50373
|
-
/* @__PURE__ */ jsx("span", {
|
|
50440
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
50441
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full bg-[#FFB020]" }),
|
|
50442
|
+
/* @__PURE__ */ jsx("span", { children: formatPercentRange(effectiveLegend.yellow_min, effectiveLegend.yellow_max) })
|
|
50374
50443
|
] }),
|
|
50375
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
50376
|
-
/* @__PURE__ */ jsx("div", { className: "w-
|
|
50377
|
-
/* @__PURE__ */ jsx("span", {
|
|
50444
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
50445
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full bg-[#E34329]" }),
|
|
50446
|
+
/* @__PURE__ */ jsx("span", { children: formatPercentRange(effectiveLegend.red_min, effectiveLegend.red_max) })
|
|
50378
50447
|
] })
|
|
50379
50448
|
] }),
|
|
50380
|
-
/* @__PURE__ */ jsx("div", { className: "hidden sm:block w-px h-
|
|
50381
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
50382
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-3 h-3 sm:w-
|
|
50383
|
-
/* @__PURE__ */ jsx("span", {
|
|
50449
|
+
/* @__PURE__ */ jsx("div", { className: "hidden sm:block w-px h-4 bg-slate-200 mx-1" }),
|
|
50450
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
50451
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-3 h-3 sm:w-4 sm:h-4 bg-[#E34329] rounded-full text-white font-bold text-[8px] sm:text-[10px]", children: "!" }),
|
|
50452
|
+
/* @__PURE__ */ jsx("span", { children: exclamationLabel })
|
|
50384
50453
|
] })
|
|
50385
50454
|
] });
|
|
50386
50455
|
};
|
|
@@ -50490,6 +50559,7 @@ var WorkspaceGrid = React142__default.memo(({
|
|
|
50490
50559
|
isPdfMode = false,
|
|
50491
50560
|
customWorkspacePositions,
|
|
50492
50561
|
lineNames = {},
|
|
50562
|
+
lineOrder = [],
|
|
50493
50563
|
factoryView = "factory",
|
|
50494
50564
|
line2Uuid = "line-2",
|
|
50495
50565
|
className = "",
|
|
@@ -50500,7 +50570,8 @@ var WorkspaceGrid = React142__default.memo(({
|
|
|
50500
50570
|
videoStreamsLoading = false,
|
|
50501
50571
|
displayNames = {},
|
|
50502
50572
|
onWorkspaceHover,
|
|
50503
|
-
onWorkspaceHoverEnd
|
|
50573
|
+
onWorkspaceHoverEnd,
|
|
50574
|
+
toolbarRightContent
|
|
50504
50575
|
}) => {
|
|
50505
50576
|
const dashboardConfig = useDashboardConfig();
|
|
50506
50577
|
const mapViewEnabled = dashboardConfig?.mapViewConfig?.enabled ?? false;
|
|
@@ -50534,29 +50605,30 @@ var WorkspaceGrid = React142__default.memo(({
|
|
|
50534
50605
|
() => viewMode === "video" ? getVideoGridLegendLabel(workspaces) : MAP_GRID_LEGEND_LABEL,
|
|
50535
50606
|
[viewMode, workspaces]
|
|
50536
50607
|
);
|
|
50537
|
-
return /* @__PURE__ */ jsxs("div", { className: `
|
|
50538
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
50539
|
-
/* @__PURE__ */
|
|
50540
|
-
|
|
50608
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex flex-col w-full h-full overflow-hidden bg-slate-50/50 ${className}`, children: [
|
|
50609
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-none px-4 py-3 z-20 flex flex-row items-center justify-between gap-4", children: [
|
|
50610
|
+
/* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsx("div", { className: "inline-flex bg-white/95 rounded-lg shadow-sm px-4 py-2 border border-slate-200/60 backdrop-blur-sm", children: /* @__PURE__ */ jsx(Legend5, { legend, useBottleneckLabel: hasFlowBuffers, metricLabel: legendMetricLabel }) }) }),
|
|
50611
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-3 shrink-0", children: [
|
|
50612
|
+
toolbarRightContent,
|
|
50541
50613
|
mapViewEnabled && /* @__PURE__ */ jsx(
|
|
50542
50614
|
"button",
|
|
50543
50615
|
{
|
|
50544
50616
|
onClick: handleViewModeToggle,
|
|
50545
|
-
className: "flex items-center gap-2 px-3 py-1.5 bg-white border border-
|
|
50617
|
+
className: "flex items-center gap-2 px-3 py-1.5 bg-white border border-slate-200 rounded-md shadow-sm hover:bg-slate-50 transition-colors duration-200 text-slate-700",
|
|
50546
50618
|
title: viewMode === "video" ? "Switch to Map View" : "Switch to Video View",
|
|
50547
50619
|
children: viewMode === "video" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
50548
|
-
/* @__PURE__ */ jsx(Map$1, { className: "w-4 h-4 text-
|
|
50549
|
-
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline text-sm
|
|
50620
|
+
/* @__PURE__ */ jsx(Map$1, { className: "w-4 h-4 text-slate-500" }),
|
|
50621
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline text-sm font-medium", children: "Map View" })
|
|
50550
50622
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
50551
|
-
/* @__PURE__ */ jsx(Video, { className: "w-4 h-4 text-
|
|
50552
|
-
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline text-sm
|
|
50623
|
+
/* @__PURE__ */ jsx(Video, { className: "w-4 h-4 text-slate-500" }),
|
|
50624
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline text-sm font-medium", children: "Video View" })
|
|
50553
50625
|
] })
|
|
50554
50626
|
}
|
|
50555
50627
|
)
|
|
50556
|
-
] })
|
|
50557
|
-
/* @__PURE__ */ jsx("div", { className: "sm:hidden mt-1 mr-32", children: /* @__PURE__ */ jsx(Legend5, { legend, useBottleneckLabel: hasFlowBuffers, metricLabel: legendMetricLabel }) })
|
|
50628
|
+
] })
|
|
50558
50629
|
] }),
|
|
50559
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
50630
|
+
/* @__PURE__ */ jsx("div", { className: "sm:hidden px-3 py-2 bg-white border-b border-slate-200/60 z-10", children: /* @__PURE__ */ jsx(Legend5, { legend, useBottleneckLabel: hasFlowBuffers, metricLabel: legendMetricLabel }) }),
|
|
50631
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: viewMode === "video" ? /* @__PURE__ */ jsx(
|
|
50560
50632
|
motion.div,
|
|
50561
50633
|
{
|
|
50562
50634
|
initial: { opacity: 0 },
|
|
@@ -50568,6 +50640,8 @@ var WorkspaceGrid = React142__default.memo(({
|
|
|
50568
50640
|
VideoGridViewComponent,
|
|
50569
50641
|
{
|
|
50570
50642
|
workspaces,
|
|
50643
|
+
lineNames,
|
|
50644
|
+
lineOrder,
|
|
50571
50645
|
videoSources,
|
|
50572
50646
|
videoStreamsByWorkspaceId,
|
|
50573
50647
|
videoStreamsLoading,
|
|
@@ -59430,6 +59504,7 @@ function HomeView({
|
|
|
59430
59504
|
[dbLines]
|
|
59431
59505
|
);
|
|
59432
59506
|
const isSupervisor = user?.role_level === "supervisor";
|
|
59507
|
+
const hasUser = Boolean(user);
|
|
59433
59508
|
const visibleLineIds = useMemo(() => {
|
|
59434
59509
|
const scoped = Array.from(new Set(allLineIds.filter(Boolean)));
|
|
59435
59510
|
if (enabledLineIdSet.size === 0) {
|
|
@@ -59439,57 +59514,100 @@ function HomeView({
|
|
|
59439
59514
|
}, [allLineIds, enabledLineIdSet]);
|
|
59440
59515
|
const fallbackLineId = visibleLineIds[0] || defaultLineId;
|
|
59441
59516
|
const defaultHomeLineId = fallbackLineId;
|
|
59442
|
-
const
|
|
59443
|
-
|
|
59444
|
-
|
|
59445
|
-
|
|
59446
|
-
|
|
59447
|
-
|
|
59448
|
-
|
|
59449
|
-
|
|
59517
|
+
const visibleLineIdsKey = visibleLineIds.join(",");
|
|
59518
|
+
const normalizeSelectedLineIds = (lineIdsToNormalize) => {
|
|
59519
|
+
const allowedLineIds = new Set(visibleLineIds);
|
|
59520
|
+
const requestedLineIds = new Set((lineIdsToNormalize || []).filter(Boolean));
|
|
59521
|
+
const normalized = visibleLineIds.filter((lineId) => requestedLineIds.has(lineId) && allowedLineIds.has(lineId));
|
|
59522
|
+
if (normalized.length > 0) {
|
|
59523
|
+
return normalized;
|
|
59524
|
+
}
|
|
59525
|
+
if (defaultHomeLineId && allowedLineIds.has(defaultHomeLineId)) {
|
|
59526
|
+
return [defaultHomeLineId];
|
|
59527
|
+
}
|
|
59528
|
+
return visibleLineIds.length > 0 ? [visibleLineIds[0]] : [];
|
|
59529
|
+
};
|
|
59530
|
+
const selectedLineIdsEqual = (left, right) => {
|
|
59531
|
+
if (left.length !== right.length) return false;
|
|
59532
|
+
return left.every((value, index) => value === right[index]);
|
|
59533
|
+
};
|
|
59534
|
+
const isAllLinesSelection = (lineIdsToCheck) => visibleLineIds.length > 0 && lineIdsToCheck.length === visibleLineIds.length;
|
|
59535
|
+
const readPersistedSelectedLineIds = () => {
|
|
59450
59536
|
if (typeof window === "undefined") {
|
|
59451
|
-
return
|
|
59537
|
+
return null;
|
|
59452
59538
|
}
|
|
59453
59539
|
try {
|
|
59454
|
-
const
|
|
59455
|
-
if (
|
|
59456
|
-
|
|
59457
|
-
|
|
59540
|
+
const savedLineIds = sessionStorage.getItem("optifye_home_line_filters_v2");
|
|
59541
|
+
if (savedLineIds) {
|
|
59542
|
+
const parsedLineIds = JSON.parse(savedLineIds);
|
|
59543
|
+
if (Array.isArray(parsedLineIds)) {
|
|
59544
|
+
return normalizeSelectedLineIds(parsedLineIds.map((lineId) => String(lineId)));
|
|
59458
59545
|
}
|
|
59459
59546
|
}
|
|
59547
|
+
const legacyLineId = sessionStorage.getItem("optifye_home_line_filter");
|
|
59548
|
+
if (legacyLineId) {
|
|
59549
|
+
if (legacyLineId === factoryViewId) {
|
|
59550
|
+
return normalizeSelectedLineIds(visibleLineIds);
|
|
59551
|
+
}
|
|
59552
|
+
return normalizeSelectedLineIds([legacyLineId]);
|
|
59553
|
+
}
|
|
59460
59554
|
} catch (error) {
|
|
59461
59555
|
console.warn("Failed to read line filter from sessionStorage:", error);
|
|
59462
59556
|
}
|
|
59463
|
-
return
|
|
59464
|
-
}
|
|
59557
|
+
return null;
|
|
59558
|
+
};
|
|
59559
|
+
const [selectedLineIds, setSelectedLineIds] = useState(() => readPersistedSelectedLineIds() || normalizeSelectedLineIds([defaultHomeLineId]));
|
|
59560
|
+
const [isLineSelectorOpen, setIsLineSelectorOpen] = useState(false);
|
|
59561
|
+
const [pendingSelectedLineIds, setPendingSelectedLineIds] = useState([]);
|
|
59562
|
+
const lineSelectorRef = useRef(null);
|
|
59465
59563
|
useEffect(() => {
|
|
59466
|
-
if (
|
|
59564
|
+
if (isLineSelectorOpen) {
|
|
59565
|
+
setPendingSelectedLineIds(selectedLineIds);
|
|
59566
|
+
}
|
|
59567
|
+
}, [isLineSelectorOpen, selectedLineIds]);
|
|
59568
|
+
useEffect(() => {
|
|
59569
|
+
if (!hasUser || visibleLineIds.length === 0) {
|
|
59467
59570
|
return;
|
|
59468
59571
|
}
|
|
59469
|
-
|
|
59470
|
-
|
|
59471
|
-
if (
|
|
59472
|
-
|
|
59473
|
-
setSelectedLineId(savedLineId);
|
|
59474
|
-
}
|
|
59475
|
-
return;
|
|
59572
|
+
const restoredLineIds = readPersistedSelectedLineIds();
|
|
59573
|
+
setSelectedLineIds((previousSelectedLineIds) => {
|
|
59574
|
+
if (restoredLineIds) {
|
|
59575
|
+
return selectedLineIdsEqual(restoredLineIds, previousSelectedLineIds) ? previousSelectedLineIds : restoredLineIds;
|
|
59476
59576
|
}
|
|
59577
|
+
const normalizedCurrentLineIds = normalizeSelectedLineIds(previousSelectedLineIds);
|
|
59578
|
+
return selectedLineIdsEqual(normalizedCurrentLineIds, previousSelectedLineIds) ? previousSelectedLineIds : normalizedCurrentLineIds;
|
|
59579
|
+
});
|
|
59580
|
+
}, [hasUser, visibleLineIdsKey, defaultHomeLineId, factoryViewId]);
|
|
59581
|
+
useEffect(() => {
|
|
59582
|
+
try {
|
|
59583
|
+
sessionStorage.setItem("optifye_home_line_filters_v2", JSON.stringify(selectedLineIds));
|
|
59584
|
+
sessionStorage.removeItem("optifye_home_line_filter");
|
|
59477
59585
|
} catch (error) {
|
|
59478
|
-
console.warn("Failed to
|
|
59586
|
+
console.warn("Failed to save line filter to sessionStorage:", error);
|
|
59479
59587
|
}
|
|
59480
|
-
|
|
59588
|
+
}, [selectedLineIds]);
|
|
59589
|
+
useEffect(() => {
|
|
59590
|
+
if (!isLineSelectorOpen) {
|
|
59481
59591
|
return;
|
|
59482
59592
|
}
|
|
59483
|
-
|
|
59484
|
-
|
|
59485
|
-
|
|
59486
|
-
|
|
59487
|
-
|
|
59488
|
-
|
|
59489
|
-
|
|
59490
|
-
|
|
59491
|
-
|
|
59492
|
-
]);
|
|
59593
|
+
const handleClickOutside = (event) => {
|
|
59594
|
+
if (lineSelectorRef.current && !lineSelectorRef.current.contains(event.target)) {
|
|
59595
|
+
setIsLineSelectorOpen(false);
|
|
59596
|
+
}
|
|
59597
|
+
};
|
|
59598
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
59599
|
+
return () => {
|
|
59600
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
59601
|
+
};
|
|
59602
|
+
}, [isLineSelectorOpen]);
|
|
59603
|
+
const primarySelectedLineId = selectedLineIds[0] || defaultHomeLineId;
|
|
59604
|
+
const isMultiLineSelection = selectedLineIds.length > 1;
|
|
59605
|
+
const selectedLineIdsKey = selectedLineIds.join(",");
|
|
59606
|
+
const selectedLineIdSet = useMemo(
|
|
59607
|
+
() => new Set(selectedLineIds),
|
|
59608
|
+
[selectedLineIds]
|
|
59609
|
+
);
|
|
59610
|
+
const metricsScopeLineId = isMultiLineSelection ? factoryViewId : primarySelectedLineId;
|
|
59493
59611
|
const userCompanyId = useMemo(() => {
|
|
59494
59612
|
return user?.properties?.company_id || user?.company_id || entityConfig.companyId;
|
|
59495
59613
|
}, [user, entityConfig.companyId]);
|
|
@@ -59509,12 +59627,8 @@ function HomeView({
|
|
|
59509
59627
|
useEffect(() => {
|
|
59510
59628
|
const initDisplayNames = async () => {
|
|
59511
59629
|
try {
|
|
59512
|
-
|
|
59513
|
-
|
|
59514
|
-
await preInitializeWorkspaceDisplayNames(lineId);
|
|
59515
|
-
}
|
|
59516
|
-
} else {
|
|
59517
|
-
await preInitializeWorkspaceDisplayNames(selectedLineId);
|
|
59630
|
+
for (const lineId of selectedLineIds) {
|
|
59631
|
+
await preInitializeWorkspaceDisplayNames(lineId);
|
|
59518
59632
|
}
|
|
59519
59633
|
setDisplayNamesInitialized(true);
|
|
59520
59634
|
} catch (error) {
|
|
@@ -59523,8 +59637,8 @@ function HomeView({
|
|
|
59523
59637
|
}
|
|
59524
59638
|
};
|
|
59525
59639
|
initDisplayNames();
|
|
59526
|
-
}, [
|
|
59527
|
-
const displayNameLineId =
|
|
59640
|
+
}, [selectedLineIdsKey]);
|
|
59641
|
+
const displayNameLineId = isMultiLineSelection ? void 0 : primarySelectedLineId;
|
|
59528
59642
|
const {
|
|
59529
59643
|
displayNames: workspaceDisplayNames,
|
|
59530
59644
|
loading: displayNamesLoading,
|
|
@@ -59553,7 +59667,8 @@ function HomeView({
|
|
|
59553
59667
|
error: metricsError,
|
|
59554
59668
|
refetch: refetchMetrics
|
|
59555
59669
|
} = useDashboardMetrics({
|
|
59556
|
-
lineId:
|
|
59670
|
+
lineId: metricsScopeLineId,
|
|
59671
|
+
lineIds: selectedLineIds,
|
|
59557
59672
|
onLineMetricsUpdate: handleLineMetricsUpdate,
|
|
59558
59673
|
userAccessibleLineIds: visibleLineIds
|
|
59559
59674
|
// Pass user's accessible lines for supervisor filtering
|
|
@@ -59561,10 +59676,8 @@ function HomeView({
|
|
|
59561
59676
|
const trendGroups = useMemo(() => {
|
|
59562
59677
|
const lineMetricsRows = lineMetrics || [];
|
|
59563
59678
|
if (!lineMetricsRows.length) return null;
|
|
59564
|
-
if (
|
|
59565
|
-
const
|
|
59566
|
-
if (!candidateLineIds.length) return null;
|
|
59567
|
-
const rowsForLines = lineMetricsRows.filter((row2) => candidateLineIds.includes(row2?.line_id));
|
|
59679
|
+
if (selectedLineIds.length > 1) {
|
|
59680
|
+
const rowsForLines = lineMetricsRows.filter((row2) => selectedLineIdSet.has(row2?.line_id));
|
|
59568
59681
|
if (!rowsForLines.length) return null;
|
|
59569
59682
|
const groupsMap = /* @__PURE__ */ new Map();
|
|
59570
59683
|
rowsForLines.forEach((row2) => {
|
|
@@ -59587,16 +59700,16 @@ function HomeView({
|
|
|
59587
59700
|
shiftId: group.shiftId
|
|
59588
59701
|
}));
|
|
59589
59702
|
}
|
|
59590
|
-
const row = lineMetricsRows.find((r2) => r2?.line_id ===
|
|
59703
|
+
const row = lineMetricsRows.find((r2) => r2?.line_id === primarySelectedLineId);
|
|
59591
59704
|
if (!row?.date || row?.shift_id === void 0 || row?.shift_id === null) {
|
|
59592
59705
|
return null;
|
|
59593
59706
|
}
|
|
59594
59707
|
return [{
|
|
59595
|
-
lineIds: [
|
|
59708
|
+
lineIds: [primarySelectedLineId],
|
|
59596
59709
|
date: row.date,
|
|
59597
59710
|
shiftId: row.shift_id
|
|
59598
59711
|
}];
|
|
59599
|
-
}, [
|
|
59712
|
+
}, [lineMetrics, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
|
|
59600
59713
|
const trendOptions = useMemo(() => {
|
|
59601
59714
|
if (!trendGroups || !userCompanyId) return null;
|
|
59602
59715
|
return {
|
|
@@ -59624,17 +59737,18 @@ function HomeView({
|
|
|
59624
59737
|
}, [workspaceMetrics, metricsLoading, metricsError]);
|
|
59625
59738
|
const kpis = useMemo(() => {
|
|
59626
59739
|
const lineMetricsRows = lineMetrics || [];
|
|
59627
|
-
if (
|
|
59628
|
-
|
|
59629
|
-
|
|
59740
|
+
if (selectedLineIds.length > 1) {
|
|
59741
|
+
const rowsForSelectedLines = lineMetricsRows.filter((row2) => selectedLineIdSet.has(row2?.line_id));
|
|
59742
|
+
if (metricsLoading && rowsForSelectedLines.length === 0) return null;
|
|
59743
|
+
return aggregateKPIsFromLineMetricsRows(rowsForSelectedLines);
|
|
59630
59744
|
}
|
|
59631
|
-
const row = lineMetricsRows.find((r2) => r2?.line_id ===
|
|
59745
|
+
const row = lineMetricsRows.find((r2) => r2?.line_id === primarySelectedLineId);
|
|
59632
59746
|
if (!row) {
|
|
59633
59747
|
if (metricsLoading) return null;
|
|
59634
59748
|
return buildKPIsFromLineMetricsRow(null);
|
|
59635
59749
|
}
|
|
59636
59750
|
return buildKPIsFromLineMetricsRow(row);
|
|
59637
|
-
}, [
|
|
59751
|
+
}, [lineMetrics, metricsLoading, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
|
|
59638
59752
|
const kpisWithTrend = useMemo(() => {
|
|
59639
59753
|
if (!kpis) return null;
|
|
59640
59754
|
if (!kpiTrend) return kpis;
|
|
@@ -59659,30 +59773,30 @@ function HomeView({
|
|
|
59659
59773
|
};
|
|
59660
59774
|
}, [kpis, kpiTrend]);
|
|
59661
59775
|
const selectedLineMeta = useMemo(
|
|
59662
|
-
() => dbLines.find((line) => line.id ===
|
|
59663
|
-
[dbLines,
|
|
59776
|
+
() => selectedLineIds.length === 1 ? dbLines.find((line) => line.id === primarySelectedLineId) : void 0,
|
|
59777
|
+
[dbLines, primarySelectedLineId, selectedLineIds.length]
|
|
59664
59778
|
);
|
|
59665
|
-
const selectedMonitoringMode =
|
|
59779
|
+
const selectedMonitoringMode = selectedLineIds.length === 1 ? selectedLineMeta?.monitoring_mode ?? "output" : "output";
|
|
59666
59780
|
const isUptimeMode = selectedMonitoringMode === "uptime";
|
|
59667
59781
|
const averageIdleTimeSeconds = useMemo(() => {
|
|
59668
59782
|
if (!isUptimeMode) return null;
|
|
59669
|
-
const targetWorkspaces =
|
|
59783
|
+
const targetWorkspaces = workspaceMetrics.filter((ws) => ws.line_id === primarySelectedLineId);
|
|
59670
59784
|
const idleValues = targetWorkspaces.map((ws) => ws.idle_time).filter((value) => Number.isFinite(value));
|
|
59671
59785
|
if (idleValues.length === 0) return 0;
|
|
59672
59786
|
const totalIdle = idleValues.reduce((sum, value) => sum + value, 0);
|
|
59673
59787
|
return totalIdle / idleValues.length;
|
|
59674
|
-
}, [isUptimeMode,
|
|
59788
|
+
}, [isUptimeMode, primarySelectedLineId, workspaceMetrics]);
|
|
59675
59789
|
const {
|
|
59676
59790
|
activeBreaks: allActiveBreaks,
|
|
59677
59791
|
isLoading: breaksLoading,
|
|
59678
59792
|
error: breaksError
|
|
59679
|
-
} = useActiveBreaks(
|
|
59793
|
+
} = useActiveBreaks(visibleLineIds);
|
|
59680
59794
|
const activeBreaks = useMemo(() => {
|
|
59681
|
-
if (
|
|
59795
|
+
if (isAllLinesSelection(selectedLineIds)) {
|
|
59682
59796
|
return allActiveBreaks;
|
|
59683
59797
|
}
|
|
59684
|
-
return allActiveBreaks.filter((breakItem) => breakItem.lineId
|
|
59685
|
-
}, [allActiveBreaks,
|
|
59798
|
+
return allActiveBreaks.filter((breakItem) => selectedLineIdSet.has(breakItem.lineId));
|
|
59799
|
+
}, [allActiveBreaks, selectedLineIdSet, selectedLineIds]);
|
|
59686
59800
|
const activeBreakLineIds = useMemo(
|
|
59687
59801
|
() => new Set(activeBreaks.map((breakItem) => breakItem.lineId)),
|
|
59688
59802
|
[activeBreaks]
|
|
@@ -59989,7 +60103,7 @@ function HomeView({
|
|
|
59989
60103
|
// Round to 1 decimal
|
|
59990
60104
|
kpisWithTrend?.avgCycleTime?.change,
|
|
59991
60105
|
kpisWithTrend?.qualityCompliance?.value ? Math.round(kpisWithTrend.qualityCompliance.value) : null,
|
|
59992
|
-
|
|
60106
|
+
selectedLineIdsKey
|
|
59993
60107
|
]);
|
|
59994
60108
|
useEffect(() => {
|
|
59995
60109
|
setIsHydrated(true);
|
|
@@ -60006,27 +60120,62 @@ function HomeView({
|
|
|
60006
60120
|
setErrorMessage(null);
|
|
60007
60121
|
}
|
|
60008
60122
|
}, [metricsError]);
|
|
60009
|
-
const
|
|
60123
|
+
const getTrackedLineScope = useCallback((lineIdsForScope) => {
|
|
60124
|
+
if (isAllLinesSelection(lineIdsForScope)) {
|
|
60125
|
+
return factoryViewId;
|
|
60126
|
+
}
|
|
60127
|
+
if (lineIdsForScope.length === 1) {
|
|
60128
|
+
return lineIdsForScope[0];
|
|
60129
|
+
}
|
|
60130
|
+
return "custom_multi";
|
|
60131
|
+
}, [factoryViewId, visibleLineIds.length]);
|
|
60132
|
+
const getLineSelectionLabel = useCallback((lineIdsForScope) => {
|
|
60133
|
+
if (isAllLinesSelection(lineIdsForScope)) {
|
|
60134
|
+
return "All Lines";
|
|
60135
|
+
}
|
|
60136
|
+
if (lineIdsForScope.length === 1) {
|
|
60137
|
+
const lineId = lineIdsForScope[0];
|
|
60138
|
+
return mergedLineNames[lineId] || `Line ${lineId.substring(0, 4)}`;
|
|
60139
|
+
}
|
|
60140
|
+
return `${lineIdsForScope.length} Lines Selected`;
|
|
60141
|
+
}, [mergedLineNames, visibleLineIds.length]);
|
|
60142
|
+
const updateSelectedLineIds = useCallback((nextLineIds) => {
|
|
60143
|
+
const normalizedLineIds = normalizeSelectedLineIds(nextLineIds);
|
|
60144
|
+
if (selectedLineIdsEqual(normalizedLineIds, selectedLineIds)) {
|
|
60145
|
+
return;
|
|
60146
|
+
}
|
|
60010
60147
|
setIsChangingFilter(true);
|
|
60011
|
-
|
|
60148
|
+
setSelectedLineIds(normalizedLineIds);
|
|
60012
60149
|
trackCoreEvent("monitor line filter changed", {
|
|
60013
|
-
previous_line_id:
|
|
60014
|
-
new_line_id:
|
|
60015
|
-
|
|
60150
|
+
previous_line_id: getTrackedLineScope(selectedLineIds),
|
|
60151
|
+
new_line_id: getTrackedLineScope(normalizedLineIds),
|
|
60152
|
+
previous_line_ids: selectedLineIds,
|
|
60153
|
+
new_line_ids: normalizedLineIds,
|
|
60154
|
+
selected_line_count: normalizedLineIds.length,
|
|
60155
|
+
selection_mode: isAllLinesSelection(normalizedLineIds) ? "all" : normalizedLineIds.length === 1 ? "single" : "custom",
|
|
60156
|
+
line_name: getLineSelectionLabel(normalizedLineIds)
|
|
60016
60157
|
});
|
|
60017
|
-
|
|
60018
|
-
|
|
60019
|
-
|
|
60020
|
-
|
|
60158
|
+
}, [factoryViewId, getLineSelectionLabel, getTrackedLineScope, selectedLineIds, selectedLineIdsKey, visibleLineIds]);
|
|
60159
|
+
useCallback(() => {
|
|
60160
|
+
updateSelectedLineIds(visibleLineIds);
|
|
60161
|
+
}, [updateSelectedLineIds, visibleLineIds]);
|
|
60162
|
+
useCallback((lineId) => {
|
|
60163
|
+
const currentSelection = new Set(selectedLineIds);
|
|
60164
|
+
if (currentSelection.has(lineId)) {
|
|
60165
|
+
if (currentSelection.size <= 1) {
|
|
60166
|
+
return;
|
|
60167
|
+
}
|
|
60168
|
+
currentSelection.delete(lineId);
|
|
60169
|
+
} else {
|
|
60170
|
+
currentSelection.add(lineId);
|
|
60021
60171
|
}
|
|
60022
|
-
|
|
60172
|
+
updateSelectedLineIds(Array.from(currentSelection));
|
|
60173
|
+
}, [selectedLineIds, updateSelectedLineIds]);
|
|
60023
60174
|
useEffect(() => {
|
|
60024
60175
|
if (!metricsLoading && isChangingFilter) {
|
|
60025
|
-
|
|
60026
|
-
setIsChangingFilter(false);
|
|
60027
|
-
}
|
|
60176
|
+
setIsChangingFilter(false);
|
|
60028
60177
|
}
|
|
60029
|
-
}, [metricsLoading,
|
|
60178
|
+
}, [metricsLoading, isChangingFilter]);
|
|
60030
60179
|
useEffect(() => {
|
|
60031
60180
|
if (!metricsLoading && !hasInitialDataLoaded) {
|
|
60032
60181
|
setHasInitialDataLoaded(true);
|
|
@@ -60045,11 +60194,107 @@ function HomeView({
|
|
|
60045
60194
|
if (visibleLineIds.length <= 1) {
|
|
60046
60195
|
return null;
|
|
60047
60196
|
}
|
|
60048
|
-
|
|
60049
|
-
|
|
60050
|
-
/* @__PURE__ */
|
|
60197
|
+
const allLinesSelected = isAllLinesSelection(pendingSelectedLineIds);
|
|
60198
|
+
return /* @__PURE__ */ jsxs("div", { ref: lineSelectorRef, className: "relative", children: [
|
|
60199
|
+
/* @__PURE__ */ jsxs(
|
|
60200
|
+
"button",
|
|
60201
|
+
{
|
|
60202
|
+
type: "button",
|
|
60203
|
+
onClick: () => setIsLineSelectorOpen((previous) => !previous),
|
|
60204
|
+
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",
|
|
60205
|
+
"aria-haspopup": "menu",
|
|
60206
|
+
"aria-expanded": isLineSelectorOpen,
|
|
60207
|
+
"aria-label": "Select lines",
|
|
60208
|
+
children: [
|
|
60209
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: getLineSelectionLabel(selectedLineIds) }),
|
|
60210
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `h-4 w-4 text-slate-400 transition-transform ${isLineSelectorOpen ? "rotate-180" : ""}` })
|
|
60211
|
+
]
|
|
60212
|
+
}
|
|
60213
|
+
),
|
|
60214
|
+
isLineSelectorOpen ? /* @__PURE__ */ jsxs("div", { className: "absolute right-0 top-full z-50 mt-2 w-[280px] rounded-lg border border-slate-200 bg-white p-3 shadow-xl flex flex-col gap-2", children: [
|
|
60215
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pb-2 border-b border-slate-100", children: [
|
|
60216
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-slate-800", children: "Select Lines" }),
|
|
60217
|
+
/* @__PURE__ */ jsx(
|
|
60218
|
+
"button",
|
|
60219
|
+
{
|
|
60220
|
+
type: "button",
|
|
60221
|
+
onClick: () => setPendingSelectedLineIds([]),
|
|
60222
|
+
className: "text-xs font-medium text-blue-600 hover:text-blue-700 transition-colors",
|
|
60223
|
+
children: "Clear All"
|
|
60224
|
+
}
|
|
60225
|
+
)
|
|
60226
|
+
] }),
|
|
60227
|
+
/* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2.5 rounded-md px-2 py-1.5 text-sm font-medium text-slate-900 hover:bg-slate-50 transition-colors", children: [
|
|
60228
|
+
/* @__PURE__ */ jsx(
|
|
60229
|
+
"input",
|
|
60230
|
+
{
|
|
60231
|
+
type: "checkbox",
|
|
60232
|
+
className: "h-4 w-4 rounded border-slate-300 text-blue-600 focus:ring-blue-500",
|
|
60233
|
+
checked: allLinesSelected,
|
|
60234
|
+
onChange: () => setPendingSelectedLineIds(allLinesSelected ? [] : visibleLineIds)
|
|
60235
|
+
}
|
|
60236
|
+
),
|
|
60237
|
+
/* @__PURE__ */ jsx("span", { children: "All Lines" })
|
|
60238
|
+
] }),
|
|
60239
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-56 space-y-0.5 overflow-y-auto pr-1", children: visibleLineIds.map((lineId) => {
|
|
60240
|
+
const isChecked = pendingSelectedLineIds.includes(lineId);
|
|
60241
|
+
return /* @__PURE__ */ jsxs(
|
|
60242
|
+
"label",
|
|
60243
|
+
{
|
|
60244
|
+
className: "flex cursor-pointer items-center gap-2.5 rounded-md px-2 py-1.5 text-sm transition-colors text-slate-700 hover:bg-slate-50",
|
|
60245
|
+
children: [
|
|
60246
|
+
/* @__PURE__ */ jsx(
|
|
60247
|
+
"input",
|
|
60248
|
+
{
|
|
60249
|
+
type: "checkbox",
|
|
60250
|
+
className: "h-4 w-4 rounded border-slate-300 text-blue-600 focus:ring-blue-500",
|
|
60251
|
+
checked: isChecked,
|
|
60252
|
+
onChange: () => {
|
|
60253
|
+
setPendingSelectedLineIds((prev) => {
|
|
60254
|
+
const current = new Set(prev);
|
|
60255
|
+
if (current.has(lineId)) {
|
|
60256
|
+
current.delete(lineId);
|
|
60257
|
+
} else {
|
|
60258
|
+
current.add(lineId);
|
|
60259
|
+
}
|
|
60260
|
+
return Array.from(current);
|
|
60261
|
+
});
|
|
60262
|
+
}
|
|
60263
|
+
}
|
|
60264
|
+
),
|
|
60265
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: mergedLineNames[lineId] || `Line ${lineId.substring(0, 4)}` })
|
|
60266
|
+
]
|
|
60267
|
+
},
|
|
60268
|
+
lineId
|
|
60269
|
+
);
|
|
60270
|
+
}) }),
|
|
60271
|
+
/* @__PURE__ */ jsx("div", { className: "pt-3 pb-1 mt-1 border-t border-slate-100 flex justify-end", children: /* @__PURE__ */ jsx(
|
|
60272
|
+
"button",
|
|
60273
|
+
{
|
|
60274
|
+
type: "button",
|
|
60275
|
+
onClick: () => {
|
|
60276
|
+
if (pendingSelectedLineIds.length > 0) {
|
|
60277
|
+
updateSelectedLineIds(pendingSelectedLineIds);
|
|
60278
|
+
}
|
|
60279
|
+
setIsLineSelectorOpen(false);
|
|
60280
|
+
},
|
|
60281
|
+
disabled: pendingSelectedLineIds.length === 0,
|
|
60282
|
+
className: "bg-blue-600 text-white px-4 py-1.5 rounded-md text-sm font-medium hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors w-full",
|
|
60283
|
+
children: "Apply"
|
|
60284
|
+
}
|
|
60285
|
+
) })
|
|
60286
|
+
] }) : null
|
|
60051
60287
|
] });
|
|
60052
|
-
}, [
|
|
60288
|
+
}, [
|
|
60289
|
+
getLineSelectionLabel,
|
|
60290
|
+
isLineSelectorOpen,
|
|
60291
|
+
mergedLineNames,
|
|
60292
|
+
selectedLineIds,
|
|
60293
|
+
pendingSelectedLineIds,
|
|
60294
|
+
visibleLineIds,
|
|
60295
|
+
updateSelectedLineIds,
|
|
60296
|
+
isAllLinesSelection
|
|
60297
|
+
]);
|
|
60053
60298
|
const useSmoothLoading = (isLoading, minDuration = 400) => {
|
|
60054
60299
|
const [showLoading, setShowLoading] = useState(isLoading);
|
|
60055
60300
|
const loadingStartRef2 = useRef(null);
|
|
@@ -60095,11 +60340,11 @@ function HomeView({
|
|
|
60095
60340
|
const isDataLoading = metricsLoading || displayNamesLoading && workspaceMetrics.length === 0;
|
|
60096
60341
|
const hasKpiDataReady = useMemo(() => {
|
|
60097
60342
|
const lineMetricsRows = lineMetrics || [];
|
|
60098
|
-
if (
|
|
60099
|
-
return lineMetricsRows.
|
|
60343
|
+
if (selectedLineIds.length > 1) {
|
|
60344
|
+
return lineMetricsRows.some((row) => selectedLineIdSet.has(row?.line_id));
|
|
60100
60345
|
}
|
|
60101
|
-
return lineMetricsRows.some((row) => row?.line_id ===
|
|
60102
|
-
}, [lineMetrics,
|
|
60346
|
+
return lineMetricsRows.some((row) => row?.line_id === primarySelectedLineId);
|
|
60347
|
+
}, [lineMetrics, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
|
|
60103
60348
|
const isKpiLoading = !hasKpiDataReady;
|
|
60104
60349
|
useEffect(() => {
|
|
60105
60350
|
const minLoadingDurationMs = 250;
|
|
@@ -60161,76 +60406,77 @@ function HomeView({
|
|
|
60161
60406
|
DashboardHeader,
|
|
60162
60407
|
{
|
|
60163
60408
|
lineTitle,
|
|
60164
|
-
lineId:
|
|
60409
|
+
lineId: primarySelectedLineId,
|
|
60165
60410
|
className: "w-full",
|
|
60166
60411
|
headerControls: kpiSectionControl
|
|
60167
60412
|
}
|
|
60168
60413
|
) }) }),
|
|
60169
|
-
/* @__PURE__ */
|
|
60170
|
-
|
|
60171
|
-
|
|
60172
|
-
|
|
60173
|
-
{
|
|
60174
|
-
|
|
60175
|
-
|
|
60176
|
-
|
|
60414
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative flex flex-col", children: /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-[calc(100vh-100px)] sm:min-h-0", children: workspaceMetricsWithBreakState.length > 0 ? /* @__PURE__ */ jsx(
|
|
60415
|
+
motion.div,
|
|
60416
|
+
{
|
|
60417
|
+
initial: { opacity: 0, scale: 0.98 },
|
|
60418
|
+
animate: { opacity: 1, scale: 1 },
|
|
60419
|
+
transition: { duration: 0.3 },
|
|
60420
|
+
className: "h-full",
|
|
60421
|
+
children: React142__default.createElement(WorkspaceGrid, {
|
|
60422
|
+
workspaces: workspaceMetricsWithBreakState,
|
|
60423
|
+
lineNames: mergedLineNames,
|
|
60424
|
+
lineOrder: selectedLineIds,
|
|
60425
|
+
factoryView: factoryViewId,
|
|
60426
|
+
legend: efficiencyLegend,
|
|
60427
|
+
videoSources,
|
|
60428
|
+
videoStreamsByWorkspaceId,
|
|
60429
|
+
videoStreamsLoading,
|
|
60430
|
+
displayNames: workspaceDisplayNames,
|
|
60431
|
+
hasFlowBuffers,
|
|
60177
60432
|
className: "h-full",
|
|
60178
|
-
|
|
60179
|
-
|
|
60180
|
-
|
|
60181
|
-
|
|
60182
|
-
|
|
60183
|
-
|
|
60184
|
-
|
|
60185
|
-
|
|
60186
|
-
|
|
60187
|
-
|
|
60188
|
-
|
|
60189
|
-
|
|
60190
|
-
|
|
60191
|
-
|
|
60192
|
-
|
|
60193
|
-
|
|
60194
|
-
|
|
60195
|
-
|
|
60196
|
-
{
|
|
60197
|
-
|
|
60198
|
-
|
|
60199
|
-
|
|
60200
|
-
|
|
60201
|
-
|
|
60202
|
-
|
|
60203
|
-
|
|
60204
|
-
|
|
60205
|
-
|
|
60206
|
-
|
|
60207
|
-
|
|
60433
|
+
toolbarRightContent: lineSelectorComponent,
|
|
60434
|
+
onWorkspaceHover: handleWorkspaceHover,
|
|
60435
|
+
onWorkspaceHoverEnd: handleWorkspaceHoverEnd
|
|
60436
|
+
})
|
|
60437
|
+
},
|
|
60438
|
+
selectedLineIdsKey
|
|
60439
|
+
) : !shouldShowDataLoading && hasInitialDataLoaded ? /* @__PURE__ */ jsx(
|
|
60440
|
+
motion.div,
|
|
60441
|
+
{
|
|
60442
|
+
initial: { opacity: 0 },
|
|
60443
|
+
animate: { opacity: 1 },
|
|
60444
|
+
transition: { duration: 0.3 },
|
|
60445
|
+
children: /* @__PURE__ */ jsx(NoWorkspaceData, { message: "No workspace data available. Adjust the selected lines or check configurations." })
|
|
60446
|
+
}
|
|
60447
|
+
) : /* @__PURE__ */ jsx(
|
|
60448
|
+
motion.div,
|
|
60449
|
+
{
|
|
60450
|
+
initial: { opacity: 0, scale: 0.98 },
|
|
60451
|
+
animate: { opacity: 1, scale: 1 },
|
|
60452
|
+
transition: { duration: 0.3 },
|
|
60453
|
+
className: "h-full",
|
|
60454
|
+
children: React142__default.createElement(WorkspaceGrid, {
|
|
60455
|
+
workspaces: [],
|
|
60456
|
+
// Show empty grid while loading
|
|
60457
|
+
lineNames: mergedLineNames,
|
|
60458
|
+
lineOrder: selectedLineIds,
|
|
60459
|
+
factoryView: factoryViewId,
|
|
60460
|
+
legend: efficiencyLegend,
|
|
60461
|
+
videoSources,
|
|
60462
|
+
videoStreamsByWorkspaceId,
|
|
60463
|
+
videoStreamsLoading,
|
|
60464
|
+
displayNames: workspaceDisplayNames,
|
|
60465
|
+
hasFlowBuffers,
|
|
60208
60466
|
className: "h-full",
|
|
60209
|
-
|
|
60210
|
-
|
|
60211
|
-
|
|
60212
|
-
|
|
60213
|
-
|
|
60214
|
-
|
|
60215
|
-
|
|
60216
|
-
videoStreamsByWorkspaceId,
|
|
60217
|
-
videoStreamsLoading,
|
|
60218
|
-
displayNames: workspaceDisplayNames,
|
|
60219
|
-
hasFlowBuffers,
|
|
60220
|
-
className: "h-full",
|
|
60221
|
-
onWorkspaceHover: handleWorkspaceHover,
|
|
60222
|
-
onWorkspaceHoverEnd: handleWorkspaceHoverEnd
|
|
60223
|
-
})
|
|
60224
|
-
},
|
|
60225
|
-
selectedLineId
|
|
60226
|
-
) })
|
|
60227
|
-
] })
|
|
60467
|
+
toolbarRightContent: lineSelectorComponent,
|
|
60468
|
+
onWorkspaceHover: handleWorkspaceHover,
|
|
60469
|
+
onWorkspaceHoverEnd: handleWorkspaceHoverEnd
|
|
60470
|
+
})
|
|
60471
|
+
},
|
|
60472
|
+
selectedLineIdsKey
|
|
60473
|
+
) }) })
|
|
60228
60474
|
] }),
|
|
60229
60475
|
/* @__PURE__ */ jsx(
|
|
60230
60476
|
BreakNotificationPopup,
|
|
60231
60477
|
{
|
|
60232
60478
|
activeBreaks,
|
|
60233
|
-
lineNames,
|
|
60479
|
+
lineNames: mergedLineNames,
|
|
60234
60480
|
isVisible: !breaksLoading && !breaksError && !breakNotificationsDismissed,
|
|
60235
60481
|
onDismiss: () => setBreakNotificationsDismissed(true)
|
|
60236
60482
|
}
|