@optifye/dashboard-core 6.11.23 → 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 +18 -32
- package/dist/index.d.mts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +564 -318
- package/dist/index.mjs +564 -318
- 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(({
|
|
@@ -47648,7 +47717,7 @@ var LinePdfGenerator = ({
|
|
|
47648
47717
|
doc.text(`${lineInfo.metrics.current_output} / ${lineInfo.metrics.line_threshold}`, 120, kpiStartY);
|
|
47649
47718
|
createKPIBox(kpiStartY + kpiSpacing);
|
|
47650
47719
|
doc.setFont("helvetica", "normal");
|
|
47651
|
-
doc.text("
|
|
47720
|
+
doc.text("Issue Resolution Time:", 25, kpiStartY + kpiSpacing);
|
|
47652
47721
|
doc.setFont("helvetica", "bold");
|
|
47653
47722
|
const resolutionSeconds = issueResolutionSummary ? issueResolutionSummary.mean_resolution_seconds ?? issueResolutionSummary.median_resolution_seconds : null;
|
|
47654
47723
|
const displayValue = resolutionSeconds !== null ? formatResolutionDuration2(resolutionSeconds) : "-";
|
|
@@ -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)));
|
|
59545
|
+
}
|
|
59546
|
+
}
|
|
59547
|
+
const legacyLineId = sessionStorage.getItem("optifye_home_line_filter");
|
|
59548
|
+
if (legacyLineId) {
|
|
59549
|
+
if (legacyLineId === factoryViewId) {
|
|
59550
|
+
return normalizeSelectedLineIds(visibleLineIds);
|
|
59458
59551
|
}
|
|
59552
|
+
return normalizeSelectedLineIds([legacyLineId]);
|
|
59459
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
|
}
|
|
@@ -61379,9 +61625,9 @@ var MetricCards = memo$1(({
|
|
|
61379
61625
|
animate: "animate",
|
|
61380
61626
|
className: `grid grid-cols-1 sm:grid-cols-2 ${largeGridColumns} gap-3 sm:gap-4 mb-2 h-auto lg:flex-[2] lg:min-h-[250px]`,
|
|
61381
61627
|
children: [
|
|
61382
|
-
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61383
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700
|
|
61384
|
-
/* @__PURE__ */ jsx("div", { className: "h-
|
|
61628
|
+
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 flex flex-col overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61629
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 sm:h-12 flex items-start justify-center mb-2 mt-1", children: /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center", children: "Line Output" }) }),
|
|
61630
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
61385
61631
|
OutputProgressChart,
|
|
61386
61632
|
{
|
|
61387
61633
|
currentOutput: lineInfo?.metrics.current_output || 0,
|
|
@@ -61389,19 +61635,19 @@ var MetricCards = memo$1(({
|
|
|
61389
61635
|
}
|
|
61390
61636
|
) }) })
|
|
61391
61637
|
] }),
|
|
61392
|
-
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61393
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center
|
|
61394
|
-
/* @__PURE__ */
|
|
61395
|
-
/* @__PURE__ */ jsx("span", { className: "text-4xl sm:text-5xl md:text-
|
|
61396
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xl sm:text-2xl md:text-2xl lg:text-3xl text-gray-500 ml-1 sm:ml-2", children: [
|
|
61638
|
+
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 flex flex-col overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61639
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 sm:h-12 flex items-start justify-center mb-2 mt-1", children: /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center", children: "Underperforming Workspaces" }) }),
|
|
61640
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-1 min-h-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-baseline", children: [
|
|
61641
|
+
/* @__PURE__ */ jsx("span", { className: "whitespace-nowrap tracking-tight text-4xl sm:text-5xl md:text-5xl lg:text-4xl xl:text-5xl 2xl:text-6xl font-bold text-red-600", children: lineInfo?.metrics.underperforming_workspaces }),
|
|
61642
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xl sm:text-2xl md:text-2xl lg:text-xl xl:text-2xl 2xl:text-3xl text-gray-500 ml-1 sm:ml-2", children: [
|
|
61397
61643
|
"/ ",
|
|
61398
61644
|
lineInfo?.metrics.total_workspaces
|
|
61399
61645
|
] })
|
|
61400
|
-
] })
|
|
61646
|
+
] }) })
|
|
61401
61647
|
] }),
|
|
61402
|
-
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61403
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center
|
|
61404
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-
|
|
61648
|
+
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 flex flex-col overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61649
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 sm:h-12 flex items-start justify-center mb-2 mt-1", children: /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center", children: "Average Efficiency" }) }),
|
|
61650
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-1 min-h-0", children: /* @__PURE__ */ jsxs("span", { className: `whitespace-nowrap tracking-tight text-4xl sm:text-5xl md:text-5xl lg:text-4xl xl:text-5xl 2xl:text-6xl font-bold ${efficiencyColorClass}`, children: [
|
|
61405
61651
|
efficiency.toFixed(1),
|
|
61406
61652
|
"%"
|
|
61407
61653
|
] }) })
|
|
@@ -61410,11 +61656,11 @@ var MetricCards = memo$1(({
|
|
|
61410
61656
|
motion.div,
|
|
61411
61657
|
{
|
|
61412
61658
|
variants: itemVariants,
|
|
61413
|
-
className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 h-[240px] sm:h-[260px] md:h-auto",
|
|
61659
|
+
className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 flex flex-col overflow-hidden h-[240px] sm:h-[260px] md:h-auto",
|
|
61414
61660
|
children: [
|
|
61415
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-
|
|
61416
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700", children: "
|
|
61417
|
-
/* @__PURE__ */ jsx(InformationCircleIcon, { className: "w-4 h-4 text-gray-400 cursor-help" }),
|
|
61661
|
+
/* @__PURE__ */ jsxs("div", { className: "h-10 sm:h-12 flex items-start justify-center gap-1.5 mb-2 mt-1 relative group z-10", children: [
|
|
61662
|
+
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center", children: "Issue Resolution Time" }),
|
|
61663
|
+
/* @__PURE__ */ jsx(InformationCircleIcon, { className: "w-4 h-4 text-gray-400 cursor-help flex-shrink-0" }),
|
|
61418
61664
|
/* @__PURE__ */ jsxs("div", { className: "absolute top-full left-1/2 transform -translate-x-1/2 mt-2.5 w-[260px] p-3 bg-white rounded-lg shadow-xl border border-gray-200 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 pointer-events-none z-50", children: [
|
|
61419
61665
|
/* @__PURE__ */ jsx("p", { className: "text-center text-xs text-gray-600 leading-relaxed mb-2.5 px-1", children: "The average time a supervisor takes to resolve a workstation in red." }),
|
|
61420
61666
|
/* @__PURE__ */ jsx("div", { className: "bg-gray-50 rounded-md py-1.5 border border-gray-100/80", children: /* @__PURE__ */ jsxs("p", { className: "text-center font-medium text-[11px] text-gray-500", children: [
|
|
@@ -61424,13 +61670,13 @@ var MetricCards = memo$1(({
|
|
|
61424
61670
|
/* @__PURE__ */ jsx("div", { className: "absolute -top-1.5 left-1/2 transform -translate-x-1/2 w-3 h-3 bg-white border-l border-t border-gray-200 rotate-45" })
|
|
61425
61671
|
] })
|
|
61426
61672
|
] }),
|
|
61427
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
61673
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-1 min-h-0", children: /* @__PURE__ */ jsx("span", { className: `whitespace-nowrap tracking-tight text-3xl sm:text-4xl md:text-4xl lg:text-3xl xl:text-4xl 2xl:text-5xl font-bold ${shouldMaskIssueResolution ? "text-gray-400" : "text-gray-900"}`, children: issueResolutionValue }) })
|
|
61428
61674
|
]
|
|
61429
61675
|
}
|
|
61430
61676
|
),
|
|
61431
|
-
showIdleTime && /* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61432
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center
|
|
61433
|
-
/* @__PURE__ */ jsx("div", { className: "h-
|
|
61677
|
+
showIdleTime && /* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 flex flex-col overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61678
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 sm:h-12 flex items-start justify-center mb-2 mt-1", children: /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center", children: "Idle Time Breakdown" }) }),
|
|
61679
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsx(
|
|
61434
61680
|
IdleTimeReasonChart,
|
|
61435
61681
|
{
|
|
61436
61682
|
data: idleTimeData?.chartData,
|
|
@@ -61490,9 +61736,9 @@ var LineUptimeMetricCards = memo$1(({
|
|
|
61490
61736
|
animate: "animate",
|
|
61491
61737
|
className: `grid grid-cols-1 sm:grid-cols-2 ${showIdleTime ? "lg:grid-cols-4" : "lg:grid-cols-3"} gap-3 sm:gap-4 mb-2 h-auto lg:flex-[2] lg:min-h-[250px]`,
|
|
61492
61738
|
children: [
|
|
61493
|
-
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61494
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700
|
|
61495
|
-
/* @__PURE__ */ jsx("div", { className: "h-
|
|
61739
|
+
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 flex flex-col overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61740
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 sm:h-12 flex items-start justify-center mb-2 mt-1", children: /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center", children: "Utilization" }) }),
|
|
61741
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
61496
61742
|
OutputProgressChart,
|
|
61497
61743
|
{
|
|
61498
61744
|
currentOutput: Number(utilizationText),
|
|
@@ -61500,17 +61746,17 @@ var LineUptimeMetricCards = memo$1(({
|
|
|
61500
61746
|
}
|
|
61501
61747
|
) }) })
|
|
61502
61748
|
] }),
|
|
61503
|
-
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61504
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center
|
|
61505
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-
|
|
61749
|
+
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 flex flex-col overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61750
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 sm:h-12 flex items-start justify-center mb-2 mt-1", children: /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center", children: "Stoppages" }) }),
|
|
61751
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-1 min-h-0", children: /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap tracking-tight text-4xl sm:text-5xl md:text-5xl lg:text-4xl xl:text-5xl 2xl:text-6xl font-bold text-red-600", children: stoppages }) })
|
|
61506
61752
|
] }),
|
|
61507
|
-
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61508
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center
|
|
61509
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-
|
|
61753
|
+
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 flex flex-col overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61754
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 sm:h-12 flex items-start justify-center mb-2 mt-1", children: /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center", children: "Average Idle Time" }) }),
|
|
61755
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-1 min-h-0", children: /* @__PURE__ */ jsx("span", { className: `whitespace-nowrap tracking-tight text-3xl sm:text-4xl md:text-5xl lg:text-4xl xl:text-5xl 2xl:text-6xl font-bold ${idleTimeSeconds <= 0 ? "text-green-500" : idleTimeSeconds <= 300 ? "text-yellow-500" : "text-red-500"}`, children: formatIdleTime(idleTimeSeconds) }) })
|
|
61510
61756
|
] }),
|
|
61511
|
-
showIdleTime && /* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61512
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center
|
|
61513
|
-
/* @__PURE__ */ jsx("div", { className: "h-
|
|
61757
|
+
showIdleTime && /* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 flex flex-col overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
61758
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 sm:h-12 flex items-start justify-center mb-2 mt-1", children: /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center", children: "Idle Time Breakdown" }) }),
|
|
61759
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsx(
|
|
61514
61760
|
IdleTimeReasonChart,
|
|
61515
61761
|
{
|
|
61516
61762
|
data: idleTimeData?.chartData,
|