@optifye/dashboard-core 6.11.24 → 6.11.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +6 -21
- package/dist/index.d.mts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +799 -345
- package/dist/index.mjs +799 -346
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3016,6 +3016,7 @@ var AuthService = class {
|
|
|
3016
3016
|
scope_ttl_seconds: enrichedUser.scope_ttl_seconds,
|
|
3017
3017
|
access_scope: enrichedUser.access_scope,
|
|
3018
3018
|
company_id: enrichedUser.company_id,
|
|
3019
|
+
company: enrichedUser.company,
|
|
3019
3020
|
first_login_completed: enrichedUser.profile.first_login_completed,
|
|
3020
3021
|
properties: {
|
|
3021
3022
|
company_id: enrichedUser.company_id,
|
|
@@ -13284,7 +13285,7 @@ var parseEfficiencyLegend = (legend) => {
|
|
|
13284
13285
|
critical_threshold: coerce(legend.critical_threshold, DEFAULT_EFFICIENCY_LEGEND.critical_threshold)
|
|
13285
13286
|
};
|
|
13286
13287
|
};
|
|
13287
|
-
var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds }) => {
|
|
13288
|
+
var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibleLineIds }) => {
|
|
13288
13289
|
const { supabaseUrl, supabaseKey } = useDashboardConfig();
|
|
13289
13290
|
const entityConfig = useEntityConfig();
|
|
13290
13291
|
const databaseConfig = useDatabaseConfig();
|
|
@@ -13301,9 +13302,9 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13301
13302
|
return getConfiguredLineIds(entityConfig);
|
|
13302
13303
|
}, [entityConfig]);
|
|
13303
13304
|
const targetFactoryLineIds = React142.useMemo(() => {
|
|
13304
|
-
const sourceLineIds = userAccessibleLineIds !== void 0 ? userAccessibleLineIds : configuredLineIds;
|
|
13305
|
+
const sourceLineIds = lineIds !== void 0 ? lineIds : userAccessibleLineIds !== void 0 ? userAccessibleLineIds : configuredLineIds;
|
|
13305
13306
|
return Array.from(new Set((sourceLineIds || []).filter(Boolean)));
|
|
13306
|
-
}, [userAccessibleLineIds, configuredLineIds]);
|
|
13307
|
+
}, [lineIds, userAccessibleLineIds, configuredLineIds]);
|
|
13307
13308
|
const { shiftConfig: staticShiftConfig } = useDashboardConfig();
|
|
13308
13309
|
const {
|
|
13309
13310
|
shiftConfigMap: multiLineShiftConfigMap,
|
|
@@ -13356,6 +13357,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13356
13357
|
const operationalShiftKeyRef = React142.useRef(operationalShiftKey);
|
|
13357
13358
|
const configuredLineIdsRef = React142.useRef(configuredLineIds);
|
|
13358
13359
|
const userAccessibleLineIdsRef = React142.useRef(userAccessibleLineIds);
|
|
13360
|
+
const explicitLineIdsRef = React142.useRef(lineIds);
|
|
13359
13361
|
React142.useEffect(() => {
|
|
13360
13362
|
onLineMetricsUpdateRef.current = onLineMetricsUpdate;
|
|
13361
13363
|
}, [onLineMetricsUpdate]);
|
|
@@ -13371,6 +13373,9 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13371
13373
|
React142.useEffect(() => {
|
|
13372
13374
|
userAccessibleLineIdsRef.current = userAccessibleLineIds;
|
|
13373
13375
|
}, [userAccessibleLineIds]);
|
|
13376
|
+
React142.useEffect(() => {
|
|
13377
|
+
explicitLineIdsRef.current = lineIds;
|
|
13378
|
+
}, [lineIds]);
|
|
13374
13379
|
const companySpecificMetricsTable = React142.useMemo(
|
|
13375
13380
|
() => getCompanyMetricsTableName(entityConfig.companyId, "performance_metrics"),
|
|
13376
13381
|
[entityConfig.companyId]
|
|
@@ -13721,6 +13726,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13721
13726
|
isFactoryView,
|
|
13722
13727
|
multiLineShiftConfigMap,
|
|
13723
13728
|
staticShiftConfig,
|
|
13729
|
+
lineIds,
|
|
13724
13730
|
userAccessibleLineIds,
|
|
13725
13731
|
effectiveWorkspaceConfig,
|
|
13726
13732
|
shiftLoading,
|
|
@@ -13838,7 +13844,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13838
13844
|
logDebug("[useDashboardMetrics] Setting up group subscriptions:", {
|
|
13839
13845
|
groupCount: currentShiftGroups.length
|
|
13840
13846
|
});
|
|
13841
|
-
const targetFactoryLineIdsForSubscriptions = currentUserAccessibleLineIds !== void 0 ? currentUserAccessibleLineIds : currentConfiguredLineIds;
|
|
13847
|
+
const targetFactoryLineIdsForSubscriptions = explicitLineIdsRef.current !== void 0 ? explicitLineIdsRef.current : currentUserAccessibleLineIds !== void 0 ? currentUserAccessibleLineIds : currentConfiguredLineIds;
|
|
13842
13848
|
const targetFactoryLineIdSet = new Set(
|
|
13843
13849
|
(targetFactoryLineIdsForSubscriptions || []).filter(Boolean)
|
|
13844
13850
|
);
|
|
@@ -14009,7 +14015,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
14009
14015
|
});
|
|
14010
14016
|
const currentShiftDetails = shiftConfig ? getCurrentShift(defaultTimezone, shiftConfig) : getCurrentShift(defaultTimezone, staticShiftConfig);
|
|
14011
14017
|
const operationalDateForSubscription = currentShiftDetails.date;
|
|
14012
|
-
const targetLineIds = isFactory ? currentUserAccessibleLineIds || currentConfiguredLineIds : [currentLineIdToUse];
|
|
14018
|
+
const targetLineIds = isFactory ? explicitLineIdsRef.current || currentUserAccessibleLineIds || currentConfiguredLineIds : [currentLineIdToUse];
|
|
14013
14019
|
const filteredLineIds = targetLineIds.filter((id3) => id3 && id3 !== factoryViewIdentifier);
|
|
14014
14020
|
if (filteredLineIds.length === 0) {
|
|
14015
14021
|
logDebug("[useDashboardMetrics] Realtime setup skipped: no line IDs after filtering", {
|
|
@@ -20251,6 +20257,17 @@ function useCompanyHasVlmEnabledLine(options = {}) {
|
|
|
20251
20257
|
};
|
|
20252
20258
|
}
|
|
20253
20259
|
|
|
20260
|
+
// src/lib/hooks/useCompanyFastSlowClipFiltersEnabled.ts
|
|
20261
|
+
function useCompanyFastSlowClipFiltersEnabled() {
|
|
20262
|
+
const { user, loading } = useAuth();
|
|
20263
|
+
const company = user?.company || user?.properties?.company;
|
|
20264
|
+
const explicitValue = company?.enable_fast_slow_clip_filters;
|
|
20265
|
+
return {
|
|
20266
|
+
isFastSlowClipFiltersEnabled: typeof explicitValue === "boolean" ? explicitValue : true,
|
|
20267
|
+
isResolved: !loading || typeof explicitValue === "boolean"
|
|
20268
|
+
};
|
|
20269
|
+
}
|
|
20270
|
+
|
|
20254
20271
|
// src/lib/utils/api.ts
|
|
20255
20272
|
var apiUtils = {
|
|
20256
20273
|
/**
|
|
@@ -20423,13 +20440,15 @@ var buildKPIsFromLineMetricsRow = (row) => {
|
|
|
20423
20440
|
};
|
|
20424
20441
|
var aggregateKPIsFromLineMetricsRows = (rows) => {
|
|
20425
20442
|
if (!rows || rows.length === 0) return createDefaultKPIs();
|
|
20426
|
-
const
|
|
20427
|
-
|
|
20428
|
-
const
|
|
20443
|
+
const eligibleRows = rows.filter((row) => toNumber(row?.avg_efficiency) >= 5);
|
|
20444
|
+
if (eligibleRows.length === 0) return createDefaultKPIs();
|
|
20445
|
+
const currentOutputSum = eligibleRows.reduce((sum, row) => sum + toNumber(row.current_output), 0);
|
|
20446
|
+
const lineThresholdSum = eligibleRows.reduce((sum, row) => sum + toNumber(row.line_threshold), 0);
|
|
20447
|
+
const idealOutputSum = eligibleRows.reduce(
|
|
20429
20448
|
(sum, row) => sum + (toNumber(row.ideal_output) || toNumber(row.line_threshold)),
|
|
20430
20449
|
0
|
|
20431
20450
|
);
|
|
20432
|
-
const efficiencyValues =
|
|
20451
|
+
const efficiencyValues = eligibleRows.map((row) => {
|
|
20433
20452
|
const value = row?.avg_efficiency;
|
|
20434
20453
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
20435
20454
|
if (typeof value === "string" && value.trim() !== "") {
|
|
@@ -20439,10 +20458,10 @@ var aggregateKPIsFromLineMetricsRows = (rows) => {
|
|
|
20439
20458
|
return null;
|
|
20440
20459
|
}).filter((value) => value !== null);
|
|
20441
20460
|
const avgEfficiency = efficiencyValues.length > 0 ? efficiencyValues.reduce((sum, value) => sum + value, 0) / efficiencyValues.length : 0;
|
|
20442
|
-
const numLines =
|
|
20443
|
-
const avgCycleTime = numLines > 0 ?
|
|
20444
|
-
const totalUnderperforming =
|
|
20445
|
-
const totalWorkspaces =
|
|
20461
|
+
const numLines = eligibleRows.length;
|
|
20462
|
+
const avgCycleTime = numLines > 0 ? eligibleRows.reduce((sum, row) => sum + toNumber(row.avg_cycle_time), 0) / numLines : 0;
|
|
20463
|
+
const totalUnderperforming = eligibleRows.reduce((sum, row) => sum + toNumber(row.underperforming_workspaces), 0);
|
|
20464
|
+
const totalWorkspaces = eligibleRows.reduce((sum, row) => sum + toNumber(row.total_workspaces), 0);
|
|
20446
20465
|
return {
|
|
20447
20466
|
underperformingWorkers: {
|
|
20448
20467
|
current: totalUnderperforming,
|
|
@@ -34598,6 +34617,8 @@ var logDebug2 = (...args) => {
|
|
|
34598
34617
|
var VideoGridView = React142__namespace.default.memo(({
|
|
34599
34618
|
workspaces,
|
|
34600
34619
|
selectedLine,
|
|
34620
|
+
lineNames = {},
|
|
34621
|
+
lineOrder = [],
|
|
34601
34622
|
className = "",
|
|
34602
34623
|
legend,
|
|
34603
34624
|
videoSources = {},
|
|
@@ -34700,6 +34721,44 @@ var VideoGridView = React142__namespace.default.memo(({
|
|
|
34700
34721
|
}
|
|
34701
34722
|
}) : workspaces;
|
|
34702
34723
|
}, [workspaces, selectedLine]);
|
|
34724
|
+
const sortedWorkspaces = React142.useMemo(() => {
|
|
34725
|
+
return [...filteredWorkspaces].sort((a, b) => {
|
|
34726
|
+
if (a.line_id !== b.line_id) {
|
|
34727
|
+
return (a.line_id || "").localeCompare(b.line_id || "");
|
|
34728
|
+
}
|
|
34729
|
+
const aMatch = a.workspace_name.match(/WS(\d+)/);
|
|
34730
|
+
const bMatch = b.workspace_name.match(/WS(\d+)/);
|
|
34731
|
+
if (aMatch && bMatch) {
|
|
34732
|
+
const aNum = parseInt(aMatch[1], 10);
|
|
34733
|
+
const bNum = parseInt(bMatch[1], 10);
|
|
34734
|
+
return aNum - bNum;
|
|
34735
|
+
}
|
|
34736
|
+
return a.workspace_name.localeCompare(b.workspace_name);
|
|
34737
|
+
});
|
|
34738
|
+
}, [filteredWorkspaces]);
|
|
34739
|
+
const lineGroups = React142.useMemo(() => {
|
|
34740
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
34741
|
+
sortedWorkspaces.forEach((workspace) => {
|
|
34742
|
+
const lineId = workspace.line_id || "unknown";
|
|
34743
|
+
const existing = grouped.get(lineId);
|
|
34744
|
+
if (existing) {
|
|
34745
|
+
existing.push(workspace);
|
|
34746
|
+
return;
|
|
34747
|
+
}
|
|
34748
|
+
grouped.set(lineId, [workspace]);
|
|
34749
|
+
});
|
|
34750
|
+
const sortedRemainingLineIds = Array.from(grouped.keys()).sort((a, b) => a.localeCompare(b));
|
|
34751
|
+
const orderedLineIds = [
|
|
34752
|
+
...lineOrder.filter((lineId) => grouped.has(lineId)),
|
|
34753
|
+
...sortedRemainingLineIds.filter((lineId) => !lineOrder.includes(lineId))
|
|
34754
|
+
];
|
|
34755
|
+
return orderedLineIds.map((lineId) => ({
|
|
34756
|
+
lineId,
|
|
34757
|
+
lineName: lineNames[lineId] || `Line ${lineId.substring(0, 4)}`,
|
|
34758
|
+
workspaces: grouped.get(lineId) || []
|
|
34759
|
+
}));
|
|
34760
|
+
}, [sortedWorkspaces, lineOrder, lineNames]);
|
|
34761
|
+
lineGroups.length > 1;
|
|
34703
34762
|
const streamsReady = !videoStreamsLoading;
|
|
34704
34763
|
const calculateOptimalGrid = React142.useCallback(() => {
|
|
34705
34764
|
if (!containerRef.current) return;
|
|
@@ -34863,108 +34922,130 @@ var VideoGridView = React142__namespace.default.memo(({
|
|
|
34863
34922
|
stream_source: isR2Stream ? "r2" : "media_config"
|
|
34864
34923
|
});
|
|
34865
34924
|
}, []);
|
|
34925
|
+
const workspaceCards = React142.useMemo(() => {
|
|
34926
|
+
return sortedWorkspaces.map((workspace) => {
|
|
34927
|
+
const workspaceId = workspace.workspace_uuid || workspace.workspace_name;
|
|
34928
|
+
const workspaceKey = `${workspace.line_id || "unknown"}-${workspaceId}`;
|
|
34929
|
+
const isVisible = visibleWorkspaces.has(workspaceId);
|
|
34930
|
+
const isVeryLowEfficiency = workspace.show_exclamation ?? (workspace.efficiency < 50 && workspace.efficiency >= 10);
|
|
34931
|
+
const workspaceCropping = getWorkspaceCropping(workspaceId, workspace.workspace_name);
|
|
34932
|
+
const workspaceStream = videoStreamsByWorkspaceId?.[workspaceId];
|
|
34933
|
+
const lastSeenLabel = workspace.workspace_uuid ? lastSeenByWorkspaceId[workspace.workspace_uuid]?.timeSinceLastUpdate : void 0;
|
|
34934
|
+
const r2Url = workspaceStream?.hls_url;
|
|
34935
|
+
const fallbackUrl = getWorkspaceHlsUrl(workspace.workspace_name, workspace.line_id);
|
|
34936
|
+
const hasR2Stream = Boolean(r2Url);
|
|
34937
|
+
const useFallback = r2FallbackWorkspaces.has(workspaceId) || streamsReady && !hasR2Stream;
|
|
34938
|
+
const hlsUrl = useFallback ? fallbackUrl : r2Url ?? "";
|
|
34939
|
+
const isR2Stream = !useFallback && hasR2Stream;
|
|
34940
|
+
const canAttemptR2 = hasR2Stream && !r2FallbackWorkspaces.has(workspaceId);
|
|
34941
|
+
const shouldPlay = isVisible && Boolean(hlsUrl) && (!failedStreams.has(workspaceId) || canAttemptR2);
|
|
34942
|
+
return {
|
|
34943
|
+
workspace,
|
|
34944
|
+
workspaceId,
|
|
34945
|
+
workspaceKey,
|
|
34946
|
+
isVisible,
|
|
34947
|
+
isVeryLowEfficiency,
|
|
34948
|
+
workspaceCropping,
|
|
34949
|
+
fallbackUrl,
|
|
34950
|
+
hlsUrl,
|
|
34951
|
+
isR2Stream,
|
|
34952
|
+
shouldPlay,
|
|
34953
|
+
lastSeenLabel
|
|
34954
|
+
};
|
|
34955
|
+
});
|
|
34956
|
+
}, [
|
|
34957
|
+
sortedWorkspaces,
|
|
34958
|
+
visibleWorkspaces,
|
|
34959
|
+
getWorkspaceCropping,
|
|
34960
|
+
videoStreamsByWorkspaceId,
|
|
34961
|
+
lastSeenByWorkspaceId,
|
|
34962
|
+
getWorkspaceHlsUrl,
|
|
34963
|
+
r2FallbackWorkspaces,
|
|
34964
|
+
streamsReady,
|
|
34965
|
+
failedStreams
|
|
34966
|
+
]);
|
|
34967
|
+
React142.useMemo(() => {
|
|
34968
|
+
const map = /* @__PURE__ */ new Map();
|
|
34969
|
+
workspaceCards.forEach((card) => {
|
|
34970
|
+
map.set(card.workspaceKey, card);
|
|
34971
|
+
});
|
|
34972
|
+
return map;
|
|
34973
|
+
}, [workspaceCards]);
|
|
34974
|
+
const croppedActiveCount = React142.useMemo(() => {
|
|
34975
|
+
return workspaceCards.reduce((count, card) => {
|
|
34976
|
+
if (card.shouldPlay && card.workspaceCropping) {
|
|
34977
|
+
return count + 1;
|
|
34978
|
+
}
|
|
34979
|
+
return count;
|
|
34980
|
+
}, 0);
|
|
34981
|
+
}, [workspaceCards]);
|
|
34982
|
+
const throttleCropping = croppedActiveCount > 10;
|
|
34983
|
+
const effectiveCanvasFps = throttleCropping ? 10 : canvasConfig?.fps;
|
|
34984
|
+
const effectiveUseRAF = throttleCropping ? false : canvasConfig?.useRAF;
|
|
34866
34985
|
const displayMinuteBucket = Math.floor(Date.now() / 6e4);
|
|
34867
|
-
|
|
34986
|
+
const renderWorkspaceCard = React142.useCallback((card, className2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
34868
34987
|
"div",
|
|
34869
34988
|
{
|
|
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
|
-
|
|
34896
|
-
|
|
34897
|
-
|
|
34898
|
-
|
|
34899
|
-
|
|
34900
|
-
|
|
34901
|
-
|
|
34902
|
-
|
|
34903
|
-
|
|
34904
|
-
|
|
34905
|
-
|
|
34906
|
-
|
|
34907
|
-
|
|
34908
|
-
|
|
34909
|
-
|
|
34910
|
-
|
|
34911
|
-
|
|
34912
|
-
|
|
34913
|
-
|
|
34914
|
-
|
|
34915
|
-
|
|
34916
|
-
|
|
34917
|
-
|
|
34918
|
-
|
|
34919
|
-
|
|
34920
|
-
|
|
34921
|
-
|
|
34922
|
-
|
|
34923
|
-
|
|
34924
|
-
}, 0);
|
|
34925
|
-
const throttleCropping = croppedActiveCount > 10;
|
|
34926
|
-
const effectiveCanvasFps = throttleCropping ? 10 : canvasConfig?.fps;
|
|
34927
|
-
const effectiveUseRAF = throttleCropping ? false : canvasConfig?.useRAF;
|
|
34928
|
-
return workspaceCards.map((card) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
34929
|
-
"div",
|
|
34930
|
-
{
|
|
34931
|
-
"data-workspace-id": card.workspaceId,
|
|
34932
|
-
className: "workspace-card relative w-full h-full",
|
|
34933
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
34934
|
-
VideoCard,
|
|
34935
|
-
{
|
|
34936
|
-
workspace: card.workspace,
|
|
34937
|
-
hlsUrl: card.hlsUrl,
|
|
34938
|
-
shouldPlay: card.shouldPlay,
|
|
34939
|
-
onClick: () => handleWorkspaceClick(card.workspace),
|
|
34940
|
-
onFatalError: () => handleStreamError(card.workspaceId, {
|
|
34941
|
-
isR2Stream: card.isR2Stream,
|
|
34942
|
-
fallbackUrl: card.fallbackUrl
|
|
34943
|
-
}),
|
|
34944
|
-
isVeryLowEfficiency: card.isVeryLowEfficiency,
|
|
34945
|
-
legend: effectiveLegend,
|
|
34946
|
-
cropping: card.workspaceCropping,
|
|
34947
|
-
canvasFps: effectiveCanvasFps,
|
|
34948
|
-
displayName: (
|
|
34949
|
-
// Create line-aware lookup key: lineId_workspaceName
|
|
34950
|
-
// This ensures correct mapping when multiple lines have same workspace names
|
|
34951
|
-
displayNames[`${card.workspace.line_id}_${card.workspace.workspace_name}`] || // Always pass line_id to fallback to ensure correct mapping per line
|
|
34952
|
-
getWorkspaceDisplayName(card.workspace.workspace_name, card.workspace.line_id)
|
|
34953
|
-
),
|
|
34954
|
-
lastSeenLabel: card.lastSeenLabel,
|
|
34955
|
-
useRAF: effectiveUseRAF,
|
|
34956
|
-
displayMinuteBucket,
|
|
34957
|
-
compact: !selectedLine,
|
|
34958
|
-
onMouseEnter: onWorkspaceHover ? () => onWorkspaceHover(card.workspaceId) : void 0,
|
|
34959
|
-
onMouseLeave: onWorkspaceHoverEnd ? () => onWorkspaceHoverEnd(card.workspaceId) : void 0
|
|
34960
|
-
}
|
|
34961
|
-
) })
|
|
34989
|
+
"data-workspace-id": card.workspaceId,
|
|
34990
|
+
className: className2,
|
|
34991
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
34992
|
+
VideoCard,
|
|
34993
|
+
{
|
|
34994
|
+
workspace: card.workspace,
|
|
34995
|
+
hlsUrl: card.hlsUrl,
|
|
34996
|
+
shouldPlay: card.shouldPlay,
|
|
34997
|
+
onClick: () => handleWorkspaceClick(card.workspace),
|
|
34998
|
+
onFatalError: () => handleStreamError(card.workspaceId, {
|
|
34999
|
+
isR2Stream: card.isR2Stream,
|
|
35000
|
+
fallbackUrl: card.fallbackUrl
|
|
35001
|
+
}),
|
|
35002
|
+
isVeryLowEfficiency: card.isVeryLowEfficiency,
|
|
35003
|
+
legend: effectiveLegend,
|
|
35004
|
+
cropping: card.workspaceCropping,
|
|
35005
|
+
canvasFps: effectiveCanvasFps,
|
|
35006
|
+
displayName: displayNames[`${card.workspace.line_id}_${card.workspace.workspace_name}`] || getWorkspaceDisplayName(card.workspace.workspace_name, card.workspace.line_id),
|
|
35007
|
+
lastSeenLabel: card.lastSeenLabel,
|
|
35008
|
+
useRAF: effectiveUseRAF,
|
|
35009
|
+
displayMinuteBucket,
|
|
35010
|
+
compact: !selectedLine,
|
|
35011
|
+
onMouseEnter: onWorkspaceHover ? () => onWorkspaceHover(card.workspaceId) : void 0,
|
|
35012
|
+
onMouseLeave: onWorkspaceHoverEnd ? () => onWorkspaceHoverEnd(card.workspaceId) : void 0
|
|
35013
|
+
}
|
|
35014
|
+
) })
|
|
35015
|
+
},
|
|
35016
|
+
card.workspaceKey
|
|
35017
|
+
), [
|
|
35018
|
+
displayNames,
|
|
35019
|
+
displayMinuteBucket,
|
|
35020
|
+
effectiveCanvasFps,
|
|
35021
|
+
effectiveLegend,
|
|
35022
|
+
effectiveUseRAF,
|
|
35023
|
+
getWorkspaceDisplayName,
|
|
35024
|
+
handleStreamError,
|
|
35025
|
+
handleWorkspaceClick,
|
|
35026
|
+
onWorkspaceHover,
|
|
35027
|
+
onWorkspaceHoverEnd,
|
|
35028
|
+
selectedLine
|
|
35029
|
+
]);
|
|
35030
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `relative overflow-hidden h-full w-full bg-slate-50/30 ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
35031
|
+
"div",
|
|
35032
|
+
{
|
|
35033
|
+
ref: containerRef,
|
|
35034
|
+
className: "h-full w-full px-1 sm:px-2 py-1 sm:py-2",
|
|
35035
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
35036
|
+
"div",
|
|
35037
|
+
{
|
|
35038
|
+
className: "grid h-full w-full gap-1.5 sm:gap-2",
|
|
35039
|
+
style: {
|
|
35040
|
+
gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
|
|
35041
|
+
gridTemplateRows: `repeat(${gridRows}, 1fr)`,
|
|
35042
|
+
gridAutoFlow: "row"
|
|
34962
35043
|
},
|
|
34963
|
-
card
|
|
34964
|
-
|
|
34965
|
-
|
|
35044
|
+
children: workspaceCards.map((card) => renderWorkspaceCard(card, "workspace-card relative w-full h-full"))
|
|
35045
|
+
}
|
|
35046
|
+
)
|
|
34966
35047
|
}
|
|
34967
|
-
) })
|
|
35048
|
+
) });
|
|
34968
35049
|
});
|
|
34969
35050
|
VideoGridView.displayName = "VideoGridView";
|
|
34970
35051
|
var MapGridView = React142__namespace.default.memo(({
|
|
@@ -38157,14 +38238,15 @@ var HlsVideoPlayer = React142.forwardRef(({
|
|
|
38157
38238
|
};
|
|
38158
38239
|
}, [effectiveSrc, initializePlayer, cleanupBlobUrl]);
|
|
38159
38240
|
React142.useEffect(() => {
|
|
38160
|
-
if (videoRef.current) {
|
|
38161
|
-
|
|
38162
|
-
videoRef.current.play().catch((err) => {
|
|
38163
|
-
console.warn("[HlsVideoPlayer] Autoplay failed:", err);
|
|
38164
|
-
});
|
|
38165
|
-
}
|
|
38241
|
+
if (!videoRef.current || !autoplay || !effectiveSrc) {
|
|
38242
|
+
return;
|
|
38166
38243
|
}
|
|
38167
|
-
|
|
38244
|
+
videoRef.current.play().catch((err) => {
|
|
38245
|
+
if (err?.name !== "AbortError") {
|
|
38246
|
+
console.warn("[HlsVideoPlayer] Autoplay failed:", err);
|
|
38247
|
+
}
|
|
38248
|
+
});
|
|
38249
|
+
}, [autoplay, effectiveSrc]);
|
|
38168
38250
|
const resetControlsTimeout = React142.useCallback(() => {
|
|
38169
38251
|
if (controlsPinned) {
|
|
38170
38252
|
setShowControls(true);
|
|
@@ -40085,7 +40167,8 @@ var FileManagerFilters = ({
|
|
|
40085
40167
|
snapshotClipId,
|
|
40086
40168
|
className = "",
|
|
40087
40169
|
targetCycleTime = null,
|
|
40088
|
-
idleTimeVlmEnabled = false
|
|
40170
|
+
idleTimeVlmEnabled = false,
|
|
40171
|
+
showPercentileCycleFilters = true
|
|
40089
40172
|
}) => {
|
|
40090
40173
|
const [expandedNodes, setExpandedNodes] = React142.useState(/* @__PURE__ */ new Set());
|
|
40091
40174
|
const [startTime, setStartTime] = React142.useState("");
|
|
@@ -40364,6 +40447,9 @@ var FileManagerFilters = ({
|
|
|
40364
40447
|
}
|
|
40365
40448
|
}, [ensureAllIdleTimeClipMetadataLoaded]);
|
|
40366
40449
|
const fetchPercentileClips = React142.useCallback(async (type) => {
|
|
40450
|
+
if (!showPercentileCycleFilters && type !== "idle-times") {
|
|
40451
|
+
return;
|
|
40452
|
+
}
|
|
40367
40453
|
if (!workspaceId || !date || shift === void 0) {
|
|
40368
40454
|
console.warn("[FileManager] Missing required params for percentile clips fetch");
|
|
40369
40455
|
return;
|
|
@@ -40410,7 +40496,7 @@ var FileManagerFilters = ({
|
|
|
40410
40496
|
} catch (error) {
|
|
40411
40497
|
console.error(`[FileManager] Error fetching ${type} clips:`, error);
|
|
40412
40498
|
}
|
|
40413
|
-
}, [workspaceId, date, shift, filterState.percentile, supabase]);
|
|
40499
|
+
}, [workspaceId, date, shift, filterState.percentile, showPercentileCycleFilters, supabase]);
|
|
40414
40500
|
const percentileCountsKey = React142.useMemo(() => {
|
|
40415
40501
|
if (!workspaceId || !date || shift === void 0) {
|
|
40416
40502
|
return null;
|
|
@@ -40418,7 +40504,7 @@ var FileManagerFilters = ({
|
|
|
40418
40504
|
return `${workspaceId}:${date}:${shift}:${filterState.percentile}`;
|
|
40419
40505
|
}, [workspaceId, date, shift, filterState.percentile]);
|
|
40420
40506
|
React142.useEffect(() => {
|
|
40421
|
-
if (!percentileCountsKey) {
|
|
40507
|
+
if (!showPercentileCycleFilters || !percentileCountsKey) {
|
|
40422
40508
|
percentileCountsKeyRef.current = null;
|
|
40423
40509
|
percentilePrefetchRef.current = { key: null, types: /* @__PURE__ */ new Set() };
|
|
40424
40510
|
setPercentileCounts({
|
|
@@ -40438,8 +40524,11 @@ var FileManagerFilters = ({
|
|
|
40438
40524
|
"slow-cycles": null
|
|
40439
40525
|
});
|
|
40440
40526
|
setPercentileClips({});
|
|
40441
|
-
}, [percentileCountsKey]);
|
|
40527
|
+
}, [showPercentileCycleFilters, percentileCountsKey]);
|
|
40442
40528
|
React142.useEffect(() => {
|
|
40529
|
+
if (!showPercentileCycleFilters) {
|
|
40530
|
+
return;
|
|
40531
|
+
}
|
|
40443
40532
|
if (!prefetchedPercentileCounts || !percentileCountsKey) {
|
|
40444
40533
|
return;
|
|
40445
40534
|
}
|
|
@@ -40454,8 +40543,11 @@ var FileManagerFilters = ({
|
|
|
40454
40543
|
"fast-cycles": typeof prefetchedPercentileCounts.counts["fast-cycles"] === "number" ? prefetchedPercentileCounts.counts["fast-cycles"] : prev["fast-cycles"],
|
|
40455
40544
|
"slow-cycles": typeof prefetchedPercentileCounts.counts["slow-cycles"] === "number" ? prefetchedPercentileCounts.counts["slow-cycles"] : prev["slow-cycles"]
|
|
40456
40545
|
}));
|
|
40457
|
-
}, [prefetchedPercentileCounts, percentileCountsKey, filterState.percentile]);
|
|
40546
|
+
}, [showPercentileCycleFilters, prefetchedPercentileCounts, percentileCountsKey, filterState.percentile]);
|
|
40458
40547
|
const fetchPercentileCounts = React142.useCallback(async (options) => {
|
|
40548
|
+
if (!showPercentileCycleFilters) {
|
|
40549
|
+
return;
|
|
40550
|
+
}
|
|
40459
40551
|
if (!workspaceId || !date || shift === void 0) {
|
|
40460
40552
|
console.warn("[FileManager] Missing required params for percentile counts fetch");
|
|
40461
40553
|
return;
|
|
@@ -40509,9 +40601,9 @@ var FileManagerFilters = ({
|
|
|
40509
40601
|
} catch (error) {
|
|
40510
40602
|
console.error("[FileManager] Error fetching percentile counts:", error);
|
|
40511
40603
|
}
|
|
40512
|
-
}, [workspaceId, date, shift, filterState.percentile, supabase, percentileCounts, percentileClips, fetchPercentileClips]);
|
|
40604
|
+
}, [workspaceId, date, shift, filterState.percentile, showPercentileCycleFilters, supabase, percentileCounts, percentileClips, fetchPercentileClips]);
|
|
40513
40605
|
React142.useEffect(() => {
|
|
40514
|
-
if (!isReady || !percentileCountsKey) {
|
|
40606
|
+
if (!showPercentileCycleFilters || !isReady || !percentileCountsKey) {
|
|
40515
40607
|
return;
|
|
40516
40608
|
}
|
|
40517
40609
|
const schedule = () => {
|
|
@@ -40522,13 +40614,13 @@ var FileManagerFilters = ({
|
|
|
40522
40614
|
} else {
|
|
40523
40615
|
setTimeout(schedule, 0);
|
|
40524
40616
|
}
|
|
40525
|
-
}, [isReady, percentileCountsKey, fetchPercentileCounts]);
|
|
40617
|
+
}, [showPercentileCycleFilters, isReady, percentileCountsKey, fetchPercentileCounts]);
|
|
40526
40618
|
const shouldShowCategory = React142.useCallback((categoryId) => {
|
|
40527
40619
|
switch (categoryId) {
|
|
40528
40620
|
case "fast-cycles":
|
|
40529
|
-
return filterState.showFastCycles;
|
|
40621
|
+
return showPercentileCycleFilters && filterState.showFastCycles;
|
|
40530
40622
|
case "slow-cycles":
|
|
40531
|
-
return filterState.showSlowCycles;
|
|
40623
|
+
return showPercentileCycleFilters && filterState.showSlowCycles;
|
|
40532
40624
|
case "longest-idles":
|
|
40533
40625
|
return false;
|
|
40534
40626
|
// filterState.showLongestIdles; // Temporarily disabled
|
|
@@ -40541,7 +40633,7 @@ var FileManagerFilters = ({
|
|
|
40541
40633
|
default:
|
|
40542
40634
|
return true;
|
|
40543
40635
|
}
|
|
40544
|
-
}, [filterState]);
|
|
40636
|
+
}, [filterState, showPercentileCycleFilters]);
|
|
40545
40637
|
const getPercentileIcon = React142.useCallback((type, isExpanded, colorClasses) => {
|
|
40546
40638
|
const iconMap = {
|
|
40547
40639
|
"fast-cycles": { icon: lucideReact.TrendingUp, color: "text-green-600" },
|
|
@@ -40712,7 +40804,7 @@ var FileManagerFilters = ({
|
|
|
40712
40804
|
const filteredSlowCycles = (percentileClips["slow-cycles"] || []).filter((clip) => isClipInTimeRange(clip.creation_timestamp || ""));
|
|
40713
40805
|
const fastCount = typeof percentileCounts["fast-cycles"] === "number" ? percentileCounts["fast-cycles"] : null;
|
|
40714
40806
|
const slowCount = typeof percentileCounts["slow-cycles"] === "number" ? percentileCounts["slow-cycles"] : null;
|
|
40715
|
-
const percentileCategories = [
|
|
40807
|
+
const percentileCategories = showPercentileCycleFilters ? [
|
|
40716
40808
|
{
|
|
40717
40809
|
id: "fast-cycles",
|
|
40718
40810
|
label: "Fast Cycles",
|
|
@@ -40810,7 +40902,7 @@ var FileManagerFilters = ({
|
|
|
40810
40902
|
};
|
|
40811
40903
|
})
|
|
40812
40904
|
} */
|
|
40813
|
-
];
|
|
40905
|
+
] : [];
|
|
40814
40906
|
const orderedIds = ["cycle_completion", "fast-cycles", "slow-cycles", "idle_time"];
|
|
40815
40907
|
orderedIds.forEach((orderedId) => {
|
|
40816
40908
|
const percentileCategory = percentileCategories.find((cat) => cat.id === orderedId);
|
|
@@ -40835,7 +40927,7 @@ var FileManagerFilters = ({
|
|
|
40835
40927
|
}
|
|
40836
40928
|
});
|
|
40837
40929
|
return tree;
|
|
40838
|
-
}, [categories, expandedNodes, counts, clipMetadata, percentileCounts, percentileClips, shouldShowCategory, getPercentileIcon, isClipInTimeRange, isTimeFilterActive]);
|
|
40930
|
+
}, [categories, expandedNodes, counts, clipMetadata, percentileCounts, percentileClips, shouldShowCategory, getPercentileIcon, isClipInTimeRange, isTimeFilterActive, showPercentileCycleFilters]);
|
|
40839
40931
|
const toggleExpanded = (nodeId) => {
|
|
40840
40932
|
const newExpanded = new Set(expandedNodes);
|
|
40841
40933
|
if (newExpanded.has(nodeId)) {
|
|
@@ -40847,10 +40939,10 @@ var FileManagerFilters = ({
|
|
|
40847
40939
|
console.log(`[FileManager] Fetching clips for expanded category: ${nodeId}`);
|
|
40848
40940
|
fetchClipMetadata(nodeId, 1);
|
|
40849
40941
|
}
|
|
40850
|
-
if (nodeId === "fast-cycles" && (percentileClips["fast-cycles"] || []).length === 0) {
|
|
40942
|
+
if (showPercentileCycleFilters && nodeId === "fast-cycles" && (percentileClips["fast-cycles"] || []).length === 0) {
|
|
40851
40943
|
fetchPercentileClips("fast-cycles");
|
|
40852
40944
|
}
|
|
40853
|
-
if (nodeId === "slow-cycles" && (percentileClips["slow-cycles"] || []).length === 0) {
|
|
40945
|
+
if (showPercentileCycleFilters && nodeId === "slow-cycles" && (percentileClips["slow-cycles"] || []).length === 0) {
|
|
40854
40946
|
fetchPercentileClips("slow-cycles");
|
|
40855
40947
|
}
|
|
40856
40948
|
}
|
|
@@ -40868,10 +40960,10 @@ var FileManagerFilters = ({
|
|
|
40868
40960
|
console.log(`[FileManager] Fetching clips for expanded category: ${node.id}`);
|
|
40869
40961
|
fetchClipMetadata(node.id, 1);
|
|
40870
40962
|
}
|
|
40871
|
-
if (node.id === "fast-cycles" && (percentileClips["fast-cycles"] || []).length === 0) {
|
|
40963
|
+
if (showPercentileCycleFilters && node.id === "fast-cycles" && (percentileClips["fast-cycles"] || []).length === 0) {
|
|
40872
40964
|
fetchPercentileClips("fast-cycles");
|
|
40873
40965
|
}
|
|
40874
|
-
if (node.id === "slow-cycles" && (percentileClips["slow-cycles"] || []).length === 0) {
|
|
40966
|
+
if (showPercentileCycleFilters && node.id === "slow-cycles" && (percentileClips["slow-cycles"] || []).length === 0) {
|
|
40875
40967
|
fetchPercentileClips("slow-cycles");
|
|
40876
40968
|
}
|
|
40877
40969
|
}
|
|
@@ -41309,7 +41401,8 @@ var FileManagerFilters = ({
|
|
|
41309
41401
|
};
|
|
41310
41402
|
var PERCENTILE_PRESETS = [5, 10, 15, 20, 25, 30];
|
|
41311
41403
|
var AdvancedFilterDialog = ({
|
|
41312
|
-
onApply
|
|
41404
|
+
onApply,
|
|
41405
|
+
showPercentileCycleFilters = true
|
|
41313
41406
|
}) => {
|
|
41314
41407
|
const {
|
|
41315
41408
|
state,
|
|
@@ -41376,7 +41469,7 @@ var AdvancedFilterDialog = ({
|
|
|
41376
41469
|
)
|
|
41377
41470
|
] }) }),
|
|
41378
41471
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 space-y-8 overflow-y-auto max-h-[60vh]", children: [
|
|
41379
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
41472
|
+
showPercentileCycleFilters && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
41380
41473
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-3", children: [
|
|
41381
41474
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 bg-gradient-to-r from-emerald-100 to-blue-100 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Activity, { className: "h-5 w-5 text-emerald-600" }) }),
|
|
41382
41475
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
@@ -41469,7 +41562,7 @@ var AdvancedFilterDialog = ({
|
|
|
41469
41562
|
] })
|
|
41470
41563
|
] }),
|
|
41471
41564
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
41472
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-gradient-to-br from-green-50 to-red-50 rounded-xl p-4 space-y-3", children: [
|
|
41565
|
+
showPercentileCycleFilters && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-gradient-to-br from-green-50 to-red-50 rounded-xl p-4 space-y-3", children: [
|
|
41473
41566
|
/* @__PURE__ */ jsxRuntime.jsxs("h4", { className: "text-sm font-bold text-gray-700 uppercase tracking-wide flex items-center space-x-2", children: [
|
|
41474
41567
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-4 w-4 text-emerald-600" }),
|
|
41475
41568
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Performance Extremes" })
|
|
@@ -41750,6 +41843,7 @@ var BottlenecksContent = ({
|
|
|
41750
41843
|
const supabase = useSupabase();
|
|
41751
41844
|
const timezone = useAppTimezone();
|
|
41752
41845
|
const { isIdleTimeVlmEnabled } = useIdleTimeVlmConfig();
|
|
41846
|
+
const { isFastSlowClipFiltersEnabled } = useCompanyFastSlowClipFiltersEnabled();
|
|
41753
41847
|
const { shiftConfig, isLoading: isShiftConfigLoading } = useDynamicShiftConfig(lineId);
|
|
41754
41848
|
const { effectiveShift, effectiveDate } = React142.useMemo(() => {
|
|
41755
41849
|
if (shift !== void 0 && shift !== null && date) {
|
|
@@ -41806,12 +41900,16 @@ var BottlenecksContent = ({
|
|
|
41806
41900
|
}), []);
|
|
41807
41901
|
const [initialFilter, setInitialFilter] = React142.useState("");
|
|
41808
41902
|
const currentIndexRef = React142.useRef(0);
|
|
41903
|
+
const currentClipIdRef = React142.useRef(null);
|
|
41809
41904
|
const currentPositionRef = React142.useRef(0);
|
|
41810
41905
|
const currentTotalRef = React142.useRef(0);
|
|
41811
41906
|
const activeFilterRef = React142.useRef(initialFilter);
|
|
41812
41907
|
const isMountedRef = React142.useRef(true);
|
|
41813
41908
|
const fetchInProgressRef = React142.useRef(/* @__PURE__ */ new Set());
|
|
41814
41909
|
const refreshCountsTimeoutRef = React142.useRef(null);
|
|
41910
|
+
const awaitingNextClipRef = React142.useRef(false);
|
|
41911
|
+
const retryTimeoutRef = React142.useRef(null);
|
|
41912
|
+
const navigationLockRef = React142.useRef(false);
|
|
41815
41913
|
const [isPlaying, setIsPlaying] = React142.useState(false);
|
|
41816
41914
|
const [currentTime, setCurrentTime] = React142.useState(0);
|
|
41817
41915
|
const [duration, setDuration] = React142.useState(0);
|
|
@@ -41820,6 +41918,7 @@ var BottlenecksContent = ({
|
|
|
41820
41918
|
const [playbackSpeed, setPlaybackSpeed] = React142.useState(1);
|
|
41821
41919
|
const [currentPosition, setCurrentPosition] = React142.useState(0);
|
|
41822
41920
|
const [currentTotal, setCurrentTotal] = React142.useState(0);
|
|
41921
|
+
const [playerInstanceNonce, setPlayerInstanceNonce] = React142.useState(0);
|
|
41823
41922
|
const [isTransitioning, setIsTransitioning] = React142.useState(false);
|
|
41824
41923
|
const [pendingVideo, setPendingVideo] = React142.useState(null);
|
|
41825
41924
|
const [isVideoBuffering, setIsVideoBuffering] = React142.useState(false);
|
|
@@ -41876,14 +41975,29 @@ var BottlenecksContent = ({
|
|
|
41876
41975
|
const [isFullscreen, setIsFullscreen] = React142.useState(false);
|
|
41877
41976
|
const categoryMetadataRef = React142.useRef([]);
|
|
41878
41977
|
const currentMetadataIndexRef = React142.useRef(0);
|
|
41978
|
+
const clearRetryTimeout = React142.useCallback(() => {
|
|
41979
|
+
if (retryTimeoutRef.current) {
|
|
41980
|
+
clearTimeout(retryTimeoutRef.current);
|
|
41981
|
+
retryTimeoutRef.current = null;
|
|
41982
|
+
}
|
|
41983
|
+
}, []);
|
|
41984
|
+
const bumpPlayerInstanceNonce = React142.useCallback(() => {
|
|
41985
|
+
setPlayerInstanceNonce((prev) => prev + 1);
|
|
41986
|
+
}, []);
|
|
41879
41987
|
const updateActiveFilter = React142.useCallback((newFilter) => {
|
|
41880
41988
|
console.log(`[BottlenecksContent] Updating active filter: ${activeFilterRef.current} -> ${newFilter}`);
|
|
41989
|
+
awaitingNextClipRef.current = false;
|
|
41990
|
+
navigationLockRef.current = false;
|
|
41991
|
+
clearRetryTimeout();
|
|
41881
41992
|
setActiveFilter(newFilter);
|
|
41882
41993
|
activeFilterRef.current = newFilter;
|
|
41883
|
-
}, []);
|
|
41994
|
+
}, [clearRetryTimeout]);
|
|
41884
41995
|
React142.useEffect(() => {
|
|
41885
41996
|
currentIndexRef.current = currentIndex;
|
|
41886
41997
|
}, [currentIndex]);
|
|
41998
|
+
React142.useEffect(() => {
|
|
41999
|
+
currentClipIdRef.current = currentClipId;
|
|
42000
|
+
}, [currentClipId]);
|
|
41887
42001
|
React142.useEffect(() => {
|
|
41888
42002
|
currentPositionRef.current = currentPosition;
|
|
41889
42003
|
}, [currentPosition]);
|
|
@@ -42292,8 +42406,11 @@ var BottlenecksContent = ({
|
|
|
42292
42406
|
}
|
|
42293
42407
|
}, [activeFilter, s3ClipsService, mergedCounts, loadFirstVideoForCategory, allVideos, firstClip]);
|
|
42294
42408
|
const isPercentileCategory = React142.useCallback((categoryId) => {
|
|
42409
|
+
if (!isFastSlowClipFiltersEnabled) {
|
|
42410
|
+
return false;
|
|
42411
|
+
}
|
|
42295
42412
|
return ["fast-cycles", "slow-cycles", "longest-idles"].includes(categoryId);
|
|
42296
|
-
}, []);
|
|
42413
|
+
}, [isFastSlowClipFiltersEnabled]);
|
|
42297
42414
|
const getMetadataCacheKey = React142.useCallback((categoryId) => {
|
|
42298
42415
|
return `${categoryId}-${effectiveDateString}-${effectiveShiftId}-${snapshotDateTime ?? "nosnap"}-${snapshotClipId ?? "nosnap"}`;
|
|
42299
42416
|
}, [effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId]);
|
|
@@ -42325,6 +42442,21 @@ var BottlenecksContent = ({
|
|
|
42325
42442
|
return [categoryId];
|
|
42326
42443
|
}
|
|
42327
42444
|
}, []);
|
|
42445
|
+
React142.useEffect(() => {
|
|
42446
|
+
if (isFastSlowClipFiltersEnabled) {
|
|
42447
|
+
return;
|
|
42448
|
+
}
|
|
42449
|
+
if (activeFilter !== "fast-cycles" && activeFilter !== "slow-cycles") {
|
|
42450
|
+
return;
|
|
42451
|
+
}
|
|
42452
|
+
const fallbackFilter = ["cycle_completion", "idle_time"].find((type) => (dynamicCounts[type] || 0) > 0) || clipTypes.find((type) => (dynamicCounts[type.type] || 0) > 0)?.type || clipTypes[0]?.type;
|
|
42453
|
+
if (!fallbackFilter || fallbackFilter === activeFilter) {
|
|
42454
|
+
return;
|
|
42455
|
+
}
|
|
42456
|
+
setCategoryMetadata([]);
|
|
42457
|
+
categoryMetadataRef.current = [];
|
|
42458
|
+
updateActiveFilter(fallbackFilter);
|
|
42459
|
+
}, [isFastSlowClipFiltersEnabled, activeFilter, dynamicCounts, clipTypes, updateActiveFilter]);
|
|
42328
42460
|
React142.useCallback((categoryId) => {
|
|
42329
42461
|
if (isPercentileCategory(categoryId)) {
|
|
42330
42462
|
return categoryMetadata.length;
|
|
@@ -42354,6 +42486,7 @@ var BottlenecksContent = ({
|
|
|
42354
42486
|
}
|
|
42355
42487
|
}, [isNavigating, currentIndex, filteredVideos.length]);
|
|
42356
42488
|
const clearLoadingState = React142.useCallback(() => {
|
|
42489
|
+
navigationLockRef.current = false;
|
|
42357
42490
|
setIsTransitioning(false);
|
|
42358
42491
|
setIsNavigating(false);
|
|
42359
42492
|
if (loadingTimeoutRef.current) {
|
|
@@ -42365,6 +42498,11 @@ var BottlenecksContent = ({
|
|
|
42365
42498
|
if (!workspaceId) {
|
|
42366
42499
|
return;
|
|
42367
42500
|
}
|
|
42501
|
+
if (!isFastSlowClipFiltersEnabled && (categoryId === "fast-cycles" || categoryId === "slow-cycles")) {
|
|
42502
|
+
setCategoryMetadata([]);
|
|
42503
|
+
categoryMetadataRef.current = [];
|
|
42504
|
+
return;
|
|
42505
|
+
}
|
|
42368
42506
|
if (!isEffectiveShiftReady) {
|
|
42369
42507
|
console.log("[BottlenecksContent] Skipping metadata load - shift/date not ready");
|
|
42370
42508
|
return;
|
|
@@ -42517,7 +42655,7 @@ var BottlenecksContent = ({
|
|
|
42517
42655
|
} finally {
|
|
42518
42656
|
setIsCategoryLoading(false);
|
|
42519
42657
|
}
|
|
42520
|
-
}, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, supabase]);
|
|
42658
|
+
}, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, supabase]);
|
|
42521
42659
|
React142.useEffect(() => {
|
|
42522
42660
|
if (previousFilterRef.current !== activeFilter) {
|
|
42523
42661
|
console.log(`Filter changed from ${previousFilterRef.current} to ${activeFilter} - resetting to first video`);
|
|
@@ -42568,8 +42706,12 @@ var BottlenecksContent = ({
|
|
|
42568
42706
|
const loadAndPlayClipById = React142.useCallback(async (clipId, categoryId, position, metadataContext) => {
|
|
42569
42707
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
|
|
42570
42708
|
console.log(`[BottlenecksContent] Loading clip by ID: ${clipId}, category=${categoryId}, position=${position}`);
|
|
42709
|
+
awaitingNextClipRef.current = false;
|
|
42710
|
+
navigationLockRef.current = true;
|
|
42711
|
+
clearRetryTimeout();
|
|
42571
42712
|
setIsTransitioning(true);
|
|
42572
42713
|
setIsInitialLoading(true);
|
|
42714
|
+
setIsNavigating(true);
|
|
42573
42715
|
setError(null);
|
|
42574
42716
|
if (videoRef.current?.player) {
|
|
42575
42717
|
try {
|
|
@@ -42667,7 +42809,67 @@ var BottlenecksContent = ({
|
|
|
42667
42809
|
clearLoadingState();
|
|
42668
42810
|
}
|
|
42669
42811
|
}
|
|
42670
|
-
}, [workspaceId, s3ClipsService, updateActiveFilter, clearLoadingState, loadCategoryMetadata, applyMetadataSnapshot, mergedCounts, isPercentileCategory]);
|
|
42812
|
+
}, [workspaceId, s3ClipsService, updateActiveFilter, clearLoadingState, clearRetryTimeout, loadCategoryMetadata, applyMetadataSnapshot, mergedCounts, isPercentileCategory]);
|
|
42813
|
+
const restartCurrentClipPlayback = React142.useCallback(() => {
|
|
42814
|
+
if (!currentClipId) {
|
|
42815
|
+
return;
|
|
42816
|
+
}
|
|
42817
|
+
console.log(`[BottlenecksContent] Restarting playback for clip ${currentClipId}`);
|
|
42818
|
+
awaitingNextClipRef.current = false;
|
|
42819
|
+
navigationLockRef.current = true;
|
|
42820
|
+
clearRetryTimeout();
|
|
42821
|
+
setError(null);
|
|
42822
|
+
setIsTransitioning(true);
|
|
42823
|
+
setIsInitialLoading(true);
|
|
42824
|
+
setIsNavigating(true);
|
|
42825
|
+
setIsVideoBuffering(false);
|
|
42826
|
+
bumpPlayerInstanceNonce();
|
|
42827
|
+
}, [currentClipId, clearRetryTimeout, bumpPlayerInstanceNonce]);
|
|
42828
|
+
React142.useEffect(() => {
|
|
42829
|
+
if (!newClipsNotification || !awaitingNextClipRef.current || !s3ClipsService) {
|
|
42830
|
+
return;
|
|
42831
|
+
}
|
|
42832
|
+
const activeCategory = activeFilterRef.current;
|
|
42833
|
+
if (!activeCategory || activeCategory === "all" || isPercentileCategory(activeCategory)) {
|
|
42834
|
+
return;
|
|
42835
|
+
}
|
|
42836
|
+
let cancelled = false;
|
|
42837
|
+
const timer = setTimeout(() => {
|
|
42838
|
+
void (async () => {
|
|
42839
|
+
const incomingClips = [...newClipsNotification.clips].reverse();
|
|
42840
|
+
for (const incomingClip of incomingClips) {
|
|
42841
|
+
if (cancelled || !incomingClip?.id || incomingClip.id === currentClipId) {
|
|
42842
|
+
continue;
|
|
42843
|
+
}
|
|
42844
|
+
const incomingVideo = await s3ClipsService.getClipById(incomingClip.id);
|
|
42845
|
+
if (cancelled || !incomingVideo || incomingVideo.type !== activeCategory) {
|
|
42846
|
+
continue;
|
|
42847
|
+
}
|
|
42848
|
+
console.log(`[BottlenecksContent] Autoplaying incoming ${activeCategory} clip ${incomingClip.id}`);
|
|
42849
|
+
invalidateMetadataCache(activeCategory);
|
|
42850
|
+
await loadAndPlayClipById(incomingClip.id, activeCategory, 1, {
|
|
42851
|
+
clips: [{ clipId: incomingClip.id }],
|
|
42852
|
+
total: Math.max(mergedCounts[activeCategory] || 0, 1)
|
|
42853
|
+
});
|
|
42854
|
+
void loadCategoryMetadata(activeCategory, false, true);
|
|
42855
|
+
return;
|
|
42856
|
+
}
|
|
42857
|
+
})();
|
|
42858
|
+
}, 300);
|
|
42859
|
+
return () => {
|
|
42860
|
+
cancelled = true;
|
|
42861
|
+
clearTimeout(timer);
|
|
42862
|
+
};
|
|
42863
|
+
}, [
|
|
42864
|
+
newClipsNotification,
|
|
42865
|
+
s3ClipsService,
|
|
42866
|
+
isPercentileCategory,
|
|
42867
|
+
currentClipId,
|
|
42868
|
+
invalidateMetadataCache,
|
|
42869
|
+
loadAndPlayClipById,
|
|
42870
|
+
loadCategoryMetadata,
|
|
42871
|
+
mergedCounts
|
|
42872
|
+
]);
|
|
42671
42873
|
React142.useCallback(async (categoryId, clipIndex) => {
|
|
42672
42874
|
console.warn("[BottlenecksContent] loadAndPlayClip is deprecated, use loadAndPlayClipById instead");
|
|
42673
42875
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current || !isEffectiveShiftReady) return;
|
|
@@ -42696,8 +42898,11 @@ var BottlenecksContent = ({
|
|
|
42696
42898
|
}
|
|
42697
42899
|
}, [workspaceId, s3ClipsService, effectiveDateString, effectiveShiftId, loadAndPlayClipById, isEffectiveShiftReady]);
|
|
42698
42900
|
const handleNext = React142.useCallback(async () => {
|
|
42699
|
-
if (!isMountedRef.current) return;
|
|
42901
|
+
if (!isMountedRef.current || navigationLockRef.current) return;
|
|
42700
42902
|
const currentFilter = activeFilterRef.current;
|
|
42903
|
+
navigationLockRef.current = true;
|
|
42904
|
+
clearRetryTimeout();
|
|
42905
|
+
setIsNavigating(true);
|
|
42701
42906
|
setIsTransitioning(true);
|
|
42702
42907
|
setIsInitialLoading(true);
|
|
42703
42908
|
setError(null);
|
|
@@ -42727,10 +42932,32 @@ var BottlenecksContent = ({
|
|
|
42727
42932
|
);
|
|
42728
42933
|
const olderClip = neighbors.previous;
|
|
42729
42934
|
if (!olderClip) {
|
|
42730
|
-
|
|
42731
|
-
|
|
42935
|
+
let metadataArray3 = categoryMetadataRef.current;
|
|
42936
|
+
if (metadataArray3.length === 0) {
|
|
42937
|
+
console.log(`[handleNext] Metadata empty for ${currentFilter}, loading before loop restart`);
|
|
42938
|
+
await loadCategoryMetadata(currentFilter, false, true);
|
|
42939
|
+
metadataArray3 = categoryMetadataRef.current;
|
|
42940
|
+
}
|
|
42941
|
+
const firstClipMeta = metadataArray3[0];
|
|
42942
|
+
if (firstClipMeta?.clipId && firstClipMeta.clipId !== currentClipId) {
|
|
42943
|
+
console.log(`[handleNext] Reached end of ${currentFilter}, looping back to newest clip ${firstClipMeta.clipId}`);
|
|
42944
|
+
await loadAndPlayClipById(firstClipMeta.clipId, currentFilter, 1, {
|
|
42945
|
+
clips: metadataArray3,
|
|
42946
|
+
total: mergedCounts[currentFilter] || metadataArray3.length
|
|
42947
|
+
});
|
|
42948
|
+
return;
|
|
42949
|
+
}
|
|
42950
|
+
console.log("[handleNext] Reached live edge, waiting for the next clip");
|
|
42951
|
+
awaitingNextClipRef.current = true;
|
|
42952
|
+
navigationLockRef.current = false;
|
|
42953
|
+
setIsInitialLoading(false);
|
|
42954
|
+
setIsVideoBuffering(false);
|
|
42955
|
+
setIsPlaying(false);
|
|
42956
|
+
setIsNavigating(false);
|
|
42957
|
+
setIsTransitioning(false);
|
|
42732
42958
|
return;
|
|
42733
42959
|
}
|
|
42960
|
+
awaitingNextClipRef.current = false;
|
|
42734
42961
|
setPendingVideo(olderClip);
|
|
42735
42962
|
setCurrentClipId(olderClip.id || null);
|
|
42736
42963
|
setAllVideos([olderClip]);
|
|
@@ -42786,8 +43013,23 @@ var BottlenecksContent = ({
|
|
|
42786
43013
|
clearLoadingState();
|
|
42787
43014
|
}
|
|
42788
43015
|
} else {
|
|
42789
|
-
|
|
42790
|
-
|
|
43016
|
+
const firstClipMeta = metadataArray[0];
|
|
43017
|
+
if (firstClipMeta?.clipId && firstClipMeta.clipId !== currentClipId) {
|
|
43018
|
+
console.log(`[handleNext] Reached end of ${currentFilter}, looping back to newest percentile clip ${firstClipMeta.clipId}`);
|
|
43019
|
+
await loadAndPlayClipById(firstClipMeta.clipId, currentFilter, 1, {
|
|
43020
|
+
clips: metadataArray,
|
|
43021
|
+
total: metadataArray.length
|
|
43022
|
+
});
|
|
43023
|
+
return;
|
|
43024
|
+
}
|
|
43025
|
+
console.log(`[handleNext] Reached live edge for ${currentFilter}, waiting for the next clip`);
|
|
43026
|
+
awaitingNextClipRef.current = true;
|
|
43027
|
+
navigationLockRef.current = false;
|
|
43028
|
+
setIsInitialLoading(false);
|
|
43029
|
+
setIsVideoBuffering(false);
|
|
43030
|
+
setIsPlaying(false);
|
|
43031
|
+
setIsNavigating(false);
|
|
43032
|
+
setIsTransitioning(false);
|
|
42791
43033
|
}
|
|
42792
43034
|
} catch (error2) {
|
|
42793
43035
|
console.error(`[handleNext] Error navigating:`, error2);
|
|
@@ -42799,10 +43041,13 @@ var BottlenecksContent = ({
|
|
|
42799
43041
|
});
|
|
42800
43042
|
clearLoadingState();
|
|
42801
43043
|
}
|
|
42802
|
-
}, [clearLoadingState, s3ClipsService, loadCategoryMetadata, isPercentileCategory, workspaceId, currentClipId, effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, mergedCounts]);
|
|
43044
|
+
}, [clearLoadingState, clearRetryTimeout, s3ClipsService, loadCategoryMetadata, loadAndPlayClipById, isPercentileCategory, workspaceId, currentClipId, effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, mergedCounts]);
|
|
42803
43045
|
const handlePrevious = React142.useCallback(async () => {
|
|
42804
|
-
if (!isMountedRef.current) return;
|
|
43046
|
+
if (!isMountedRef.current || navigationLockRef.current) return;
|
|
42805
43047
|
const currentFilter = activeFilterRef.current;
|
|
43048
|
+
navigationLockRef.current = true;
|
|
43049
|
+
clearRetryTimeout();
|
|
43050
|
+
setIsNavigating(true);
|
|
42806
43051
|
setIsTransitioning(true);
|
|
42807
43052
|
setIsInitialLoading(true);
|
|
42808
43053
|
setError(null);
|
|
@@ -42900,7 +43145,7 @@ var BottlenecksContent = ({
|
|
|
42900
43145
|
});
|
|
42901
43146
|
clearLoadingState();
|
|
42902
43147
|
}
|
|
42903
|
-
}, [clearLoadingState, s3ClipsService, loadCategoryMetadata, isPercentileCategory, workspaceId, currentClipId, effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, mergedCounts]);
|
|
43148
|
+
}, [clearLoadingState, clearRetryTimeout, s3ClipsService, loadCategoryMetadata, isPercentileCategory, workspaceId, currentClipId, effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, mergedCounts]);
|
|
42904
43149
|
const currentVideo = React142.useMemo(() => {
|
|
42905
43150
|
if (!filteredVideos || filteredVideos.length === 0 || currentIndex >= filteredVideos.length) {
|
|
42906
43151
|
return null;
|
|
@@ -43067,6 +43312,8 @@ var BottlenecksContent = ({
|
|
|
43067
43312
|
}
|
|
43068
43313
|
}, [error, playbackSpeed]);
|
|
43069
43314
|
const handleVideoPlay = React142.useCallback(async (player) => {
|
|
43315
|
+
awaitingNextClipRef.current = false;
|
|
43316
|
+
clearRetryTimeout();
|
|
43070
43317
|
setIsPlaying(true);
|
|
43071
43318
|
setIsInitialLoading(false);
|
|
43072
43319
|
if (currentVideo && !currentVideo.creation_timestamp && s3ClipsService) {
|
|
@@ -43088,7 +43335,7 @@ var BottlenecksContent = ({
|
|
|
43088
43335
|
console.warn("[BottlenecksContent] Failed to load metadata for current video:", error2);
|
|
43089
43336
|
}
|
|
43090
43337
|
}
|
|
43091
|
-
}, [currentVideo, s3ClipsService]);
|
|
43338
|
+
}, [currentVideo, s3ClipsService, clearRetryTimeout]);
|
|
43092
43339
|
const handleVideoPause = React142.useCallback((player) => {
|
|
43093
43340
|
setIsPlaying(false);
|
|
43094
43341
|
}, []);
|
|
@@ -43099,8 +43346,10 @@ var BottlenecksContent = ({
|
|
|
43099
43346
|
setDuration(duration2);
|
|
43100
43347
|
}, []);
|
|
43101
43348
|
const handleLoadedData = React142.useCallback((player) => {
|
|
43102
|
-
console.log("Video data loaded -
|
|
43103
|
-
|
|
43349
|
+
console.log("Video data loaded - clearing transition overlay");
|
|
43350
|
+
setIsInitialLoading(false);
|
|
43351
|
+
clearLoadingState();
|
|
43352
|
+
}, [clearLoadingState]);
|
|
43104
43353
|
const handleVideoPlaying = React142.useCallback((player) => {
|
|
43105
43354
|
console.log("Video playing - hiding transition overlay (most reliable)");
|
|
43106
43355
|
clearLoadingState();
|
|
@@ -43121,6 +43370,7 @@ var BottlenecksContent = ({
|
|
|
43121
43370
|
console.error("[BottlenecksContent] Video.js error:", errorInfo);
|
|
43122
43371
|
setIsPlaying(false);
|
|
43123
43372
|
setIsVideoBuffering(false);
|
|
43373
|
+
clearRetryTimeout();
|
|
43124
43374
|
const errorCode = errorInfo?.code || 0;
|
|
43125
43375
|
const canRetry = errorInfo?.canRetry ?? false;
|
|
43126
43376
|
const errorMessage = errorInfo?.message || "Unknown error";
|
|
@@ -43148,17 +43398,24 @@ var BottlenecksContent = ({
|
|
|
43148
43398
|
if (videoRetryCountRef.current < 3 && currentVideo) {
|
|
43149
43399
|
videoRetryCountRef.current++;
|
|
43150
43400
|
const retryDelay = 1e3 * videoRetryCountRef.current;
|
|
43401
|
+
const retryClipId = currentVideo.id;
|
|
43402
|
+
const retryCategory = activeFilterRef.current;
|
|
43151
43403
|
console.log(`[Video Error] Recoverable error - Retrying... Attempt ${videoRetryCountRef.current}/3 in ${retryDelay}ms`);
|
|
43152
43404
|
setError({
|
|
43153
43405
|
type: "retrying",
|
|
43154
43406
|
message: `Retrying... (${videoRetryCountRef.current}/3)`,
|
|
43155
43407
|
isRetrying: true
|
|
43156
43408
|
});
|
|
43157
|
-
setTimeout(() => {
|
|
43158
|
-
|
|
43159
|
-
|
|
43160
|
-
|
|
43409
|
+
retryTimeoutRef.current = setTimeout(() => {
|
|
43410
|
+
retryTimeoutRef.current = null;
|
|
43411
|
+
if (!isMountedRef.current) {
|
|
43412
|
+
return;
|
|
43161
43413
|
}
|
|
43414
|
+
if (currentClipIdRef.current !== retryClipId || activeFilterRef.current !== retryCategory) {
|
|
43415
|
+
console.log("[Video Error] Skipping stale retry for previous clip");
|
|
43416
|
+
return;
|
|
43417
|
+
}
|
|
43418
|
+
restartCurrentClipPlayback();
|
|
43162
43419
|
}, retryDelay);
|
|
43163
43420
|
} else {
|
|
43164
43421
|
console.log("[Video Error] Retries exhausted - showing final error overlay");
|
|
@@ -43180,7 +43437,7 @@ var BottlenecksContent = ({
|
|
|
43180
43437
|
attempts: 3
|
|
43181
43438
|
});
|
|
43182
43439
|
}
|
|
43183
|
-
}, [currentVideo, workspaceId, clearLoadingState]);
|
|
43440
|
+
}, [currentVideo, workspaceId, clearLoadingState, clearRetryTimeout, restartCurrentClipPlayback]);
|
|
43184
43441
|
React142.useEffect(() => {
|
|
43185
43442
|
isMountedRef.current = true;
|
|
43186
43443
|
return () => {
|
|
@@ -43192,10 +43449,11 @@ var BottlenecksContent = ({
|
|
|
43192
43449
|
clearTimeout(loadingTimeoutRef.current);
|
|
43193
43450
|
loadingTimeoutRef.current = null;
|
|
43194
43451
|
}
|
|
43452
|
+
clearRetryTimeout();
|
|
43195
43453
|
setIsCategoryLoading(false);
|
|
43196
43454
|
setIsNavigating(false);
|
|
43197
43455
|
};
|
|
43198
|
-
}, [s3ClipsService]);
|
|
43456
|
+
}, [s3ClipsService, clearRetryTimeout]);
|
|
43199
43457
|
React142.useEffect(() => {
|
|
43200
43458
|
if (filteredVideos.length > 0 && currentIndex < filteredVideos.length) {
|
|
43201
43459
|
if (error && error.type === "fatal") {
|
|
@@ -43411,7 +43669,8 @@ var BottlenecksContent = ({
|
|
|
43411
43669
|
isShareLoading,
|
|
43412
43670
|
isShareCopied,
|
|
43413
43671
|
options: videoPlayerOptions
|
|
43414
|
-
}
|
|
43672
|
+
},
|
|
43673
|
+
`${currentVideo.id}-${playerInstanceNonce}-inline`
|
|
43415
43674
|
)
|
|
43416
43675
|
}
|
|
43417
43676
|
),
|
|
@@ -43442,11 +43701,8 @@ var BottlenecksContent = ({
|
|
|
43442
43701
|
"button",
|
|
43443
43702
|
{
|
|
43444
43703
|
onClick: () => {
|
|
43445
|
-
setError(null);
|
|
43446
43704
|
videoRetryCountRef.current = 0;
|
|
43447
|
-
|
|
43448
|
-
videoRef.current.dispose();
|
|
43449
|
-
}
|
|
43705
|
+
restartCurrentClipPlayback();
|
|
43450
43706
|
},
|
|
43451
43707
|
className: "px-5 py-2.5 bg-gray-600 hover:bg-gray-700 rounded-md text-sm font-medium transition-colors",
|
|
43452
43708
|
children: "Retry"
|
|
@@ -43678,7 +43934,7 @@ var BottlenecksContent = ({
|
|
|
43678
43934
|
currentVideoId: currentVideo?.id,
|
|
43679
43935
|
counts: mergedCounts,
|
|
43680
43936
|
isReady: hasInitialLoad,
|
|
43681
|
-
prefetchedPercentileCounts: prefetchedPercentileCounts || void 0,
|
|
43937
|
+
prefetchedPercentileCounts: isFastSlowClipFiltersEnabled ? prefetchedPercentileCounts || void 0 : void 0,
|
|
43682
43938
|
workspaceId,
|
|
43683
43939
|
date: effectiveDateString,
|
|
43684
43940
|
shift: effectiveShiftId,
|
|
@@ -43687,6 +43943,7 @@ var BottlenecksContent = ({
|
|
|
43687
43943
|
targetCycleTime: workspaceTargetCycleTime,
|
|
43688
43944
|
clipClassifications,
|
|
43689
43945
|
idleTimeVlmEnabled,
|
|
43946
|
+
showPercentileCycleFilters: isFastSlowClipFiltersEnabled,
|
|
43690
43947
|
onFilterChange: (filterId) => {
|
|
43691
43948
|
updateActiveFilter(filterId);
|
|
43692
43949
|
const category = categoriesToShow.find((cat) => cat.type === filterId);
|
|
@@ -43835,7 +44092,8 @@ var BottlenecksContent = ({
|
|
|
43835
44092
|
isShareLoading,
|
|
43836
44093
|
isShareCopied,
|
|
43837
44094
|
options: videoPlayerOptions
|
|
43838
|
-
}
|
|
44095
|
+
},
|
|
44096
|
+
`${currentVideo.id}-${playerInstanceNonce}-fullscreen`
|
|
43839
44097
|
)
|
|
43840
44098
|
}
|
|
43841
44099
|
),
|
|
@@ -43899,6 +44157,7 @@ var BottlenecksContent = ({
|
|
|
43899
44157
|
!triageMode && /* @__PURE__ */ jsxRuntime.jsx(
|
|
43900
44158
|
AdvancedFilterDialog,
|
|
43901
44159
|
{
|
|
44160
|
+
showPercentileCycleFilters: isFastSlowClipFiltersEnabled,
|
|
43902
44161
|
onApply: () => {
|
|
43903
44162
|
console.log("[BottlenecksContent] Advanced filters applied, will refresh clips...");
|
|
43904
44163
|
}
|
|
@@ -50387,29 +50646,29 @@ var Legend5 = ({
|
|
|
50387
50646
|
}) => {
|
|
50388
50647
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
50389
50648
|
const exclamationLabel = useBottleneckLabel ? "Bottleneck" : "<50% efficiency";
|
|
50390
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-
|
|
50649
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:gap-4 text-xs font-medium text-slate-600", children: [
|
|
50391
50650
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-medium text-gray-700 hidden sm:block", children: [
|
|
50392
50651
|
metricLabel,
|
|
50393
50652
|
":"
|
|
50394
50653
|
] }),
|
|
50395
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
50396
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
50397
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-
|
|
50398
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
50654
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:gap-4", children: [
|
|
50655
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
50656
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full bg-[#00AB45]" }),
|
|
50657
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatPercentRange(effectiveLegend.green_min, effectiveLegend.green_max) })
|
|
50399
50658
|
] }),
|
|
50400
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
50401
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-
|
|
50402
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
50659
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
50660
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full bg-[#FFB020]" }),
|
|
50661
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatPercentRange(effectiveLegend.yellow_min, effectiveLegend.yellow_max) })
|
|
50403
50662
|
] }),
|
|
50404
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
50405
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-
|
|
50406
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
50663
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
50664
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full bg-[#E34329]" }),
|
|
50665
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatPercentRange(effectiveLegend.red_min, effectiveLegend.red_max) })
|
|
50407
50666
|
] })
|
|
50408
50667
|
] }),
|
|
50409
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block w-px h-
|
|
50410
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
50411
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center w-3 h-3 sm:w-
|
|
50412
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
50668
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block w-px h-4 bg-slate-200 mx-1" }),
|
|
50669
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
50670
|
+
/* @__PURE__ */ jsxRuntime.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: "!" }),
|
|
50671
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: exclamationLabel })
|
|
50413
50672
|
] })
|
|
50414
50673
|
] });
|
|
50415
50674
|
};
|
|
@@ -50519,6 +50778,7 @@ var WorkspaceGrid = React142__namespace.default.memo(({
|
|
|
50519
50778
|
isPdfMode = false,
|
|
50520
50779
|
customWorkspacePositions,
|
|
50521
50780
|
lineNames = {},
|
|
50781
|
+
lineOrder = [],
|
|
50522
50782
|
factoryView = "factory",
|
|
50523
50783
|
line2Uuid = "line-2",
|
|
50524
50784
|
className = "",
|
|
@@ -50529,7 +50789,8 @@ var WorkspaceGrid = React142__namespace.default.memo(({
|
|
|
50529
50789
|
videoStreamsLoading = false,
|
|
50530
50790
|
displayNames = {},
|
|
50531
50791
|
onWorkspaceHover,
|
|
50532
|
-
onWorkspaceHoverEnd
|
|
50792
|
+
onWorkspaceHoverEnd,
|
|
50793
|
+
toolbarRightContent
|
|
50533
50794
|
}) => {
|
|
50534
50795
|
const dashboardConfig = useDashboardConfig();
|
|
50535
50796
|
const mapViewEnabled = dashboardConfig?.mapViewConfig?.enabled ?? false;
|
|
@@ -50563,29 +50824,30 @@ var WorkspaceGrid = React142__namespace.default.memo(({
|
|
|
50563
50824
|
() => viewMode === "video" ? getVideoGridLegendLabel(workspaces) : MAP_GRID_LEGEND_LABEL,
|
|
50564
50825
|
[viewMode, workspaces]
|
|
50565
50826
|
);
|
|
50566
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `
|
|
50567
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
50568
|
-
/* @__PURE__ */ jsxRuntime.
|
|
50569
|
-
|
|
50827
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col w-full h-full overflow-hidden bg-slate-50/50 ${className}`, children: [
|
|
50828
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-none px-4 py-3 z-20 flex flex-row items-center justify-between gap-4", children: [
|
|
50829
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(Legend5, { legend, useBottleneckLabel: hasFlowBuffers, metricLabel: legendMetricLabel }) }) }),
|
|
50830
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-3 shrink-0", children: [
|
|
50831
|
+
toolbarRightContent,
|
|
50570
50832
|
mapViewEnabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
50571
50833
|
"button",
|
|
50572
50834
|
{
|
|
50573
50835
|
onClick: handleViewModeToggle,
|
|
50574
|
-
className: "flex items-center gap-2 px-3 py-1.5 bg-white border border-
|
|
50836
|
+
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",
|
|
50575
50837
|
title: viewMode === "video" ? "Switch to Map View" : "Switch to Video View",
|
|
50576
50838
|
children: viewMode === "video" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
50577
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Map, { className: "w-4 h-4 text-
|
|
50578
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline text-sm
|
|
50839
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Map, { className: "w-4 h-4 text-slate-500" }),
|
|
50840
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline text-sm font-medium", children: "Map View" })
|
|
50579
50841
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
50580
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Video, { className: "w-4 h-4 text-
|
|
50581
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline text-sm
|
|
50842
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Video, { className: "w-4 h-4 text-slate-500" }),
|
|
50843
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline text-sm font-medium", children: "Video View" })
|
|
50582
50844
|
] })
|
|
50583
50845
|
}
|
|
50584
50846
|
)
|
|
50585
|
-
] })
|
|
50586
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden mt-1 mr-32", children: /* @__PURE__ */ jsxRuntime.jsx(Legend5, { legend, useBottleneckLabel: hasFlowBuffers, metricLabel: legendMetricLabel }) })
|
|
50847
|
+
] })
|
|
50587
50848
|
] }),
|
|
50588
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
50849
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden px-3 py-2 bg-white border-b border-slate-200/60 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(Legend5, { legend, useBottleneckLabel: hasFlowBuffers, metricLabel: legendMetricLabel }) }),
|
|
50850
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AnimatePresence, { mode: "wait", children: viewMode === "video" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
50589
50851
|
motion.div,
|
|
50590
50852
|
{
|
|
50591
50853
|
initial: { opacity: 0 },
|
|
@@ -50597,6 +50859,8 @@ var WorkspaceGrid = React142__namespace.default.memo(({
|
|
|
50597
50859
|
VideoGridViewComponent,
|
|
50598
50860
|
{
|
|
50599
50861
|
workspaces,
|
|
50862
|
+
lineNames,
|
|
50863
|
+
lineOrder,
|
|
50600
50864
|
videoSources,
|
|
50601
50865
|
videoStreamsByWorkspaceId,
|
|
50602
50866
|
videoStreamsLoading,
|
|
@@ -59459,6 +59723,7 @@ function HomeView({
|
|
|
59459
59723
|
[dbLines]
|
|
59460
59724
|
);
|
|
59461
59725
|
const isSupervisor = user?.role_level === "supervisor";
|
|
59726
|
+
const hasUser = Boolean(user);
|
|
59462
59727
|
const visibleLineIds = React142.useMemo(() => {
|
|
59463
59728
|
const scoped = Array.from(new Set(allLineIds.filter(Boolean)));
|
|
59464
59729
|
if (enabledLineIdSet.size === 0) {
|
|
@@ -59468,57 +59733,100 @@ function HomeView({
|
|
|
59468
59733
|
}, [allLineIds, enabledLineIdSet]);
|
|
59469
59734
|
const fallbackLineId = visibleLineIds[0] || defaultLineId;
|
|
59470
59735
|
const defaultHomeLineId = fallbackLineId;
|
|
59471
|
-
const
|
|
59472
|
-
|
|
59473
|
-
|
|
59474
|
-
|
|
59475
|
-
|
|
59476
|
-
|
|
59477
|
-
|
|
59478
|
-
|
|
59736
|
+
const visibleLineIdsKey = visibleLineIds.join(",");
|
|
59737
|
+
const normalizeSelectedLineIds = (lineIdsToNormalize) => {
|
|
59738
|
+
const allowedLineIds = new Set(visibleLineIds);
|
|
59739
|
+
const requestedLineIds = new Set((lineIdsToNormalize || []).filter(Boolean));
|
|
59740
|
+
const normalized = visibleLineIds.filter((lineId) => requestedLineIds.has(lineId) && allowedLineIds.has(lineId));
|
|
59741
|
+
if (normalized.length > 0) {
|
|
59742
|
+
return normalized;
|
|
59743
|
+
}
|
|
59744
|
+
if (defaultHomeLineId && allowedLineIds.has(defaultHomeLineId)) {
|
|
59745
|
+
return [defaultHomeLineId];
|
|
59746
|
+
}
|
|
59747
|
+
return visibleLineIds.length > 0 ? [visibleLineIds[0]] : [];
|
|
59748
|
+
};
|
|
59749
|
+
const selectedLineIdsEqual = (left, right) => {
|
|
59750
|
+
if (left.length !== right.length) return false;
|
|
59751
|
+
return left.every((value, index) => value === right[index]);
|
|
59752
|
+
};
|
|
59753
|
+
const isAllLinesSelection = (lineIdsToCheck) => visibleLineIds.length > 0 && lineIdsToCheck.length === visibleLineIds.length;
|
|
59754
|
+
const readPersistedSelectedLineIds = () => {
|
|
59479
59755
|
if (typeof window === "undefined") {
|
|
59480
|
-
return
|
|
59756
|
+
return null;
|
|
59481
59757
|
}
|
|
59482
59758
|
try {
|
|
59483
|
-
const
|
|
59484
|
-
if (
|
|
59485
|
-
|
|
59486
|
-
|
|
59759
|
+
const savedLineIds = sessionStorage.getItem("optifye_home_line_filters_v2");
|
|
59760
|
+
if (savedLineIds) {
|
|
59761
|
+
const parsedLineIds = JSON.parse(savedLineIds);
|
|
59762
|
+
if (Array.isArray(parsedLineIds)) {
|
|
59763
|
+
return normalizeSelectedLineIds(parsedLineIds.map((lineId) => String(lineId)));
|
|
59764
|
+
}
|
|
59765
|
+
}
|
|
59766
|
+
const legacyLineId = sessionStorage.getItem("optifye_home_line_filter");
|
|
59767
|
+
if (legacyLineId) {
|
|
59768
|
+
if (legacyLineId === factoryViewId) {
|
|
59769
|
+
return normalizeSelectedLineIds(visibleLineIds);
|
|
59487
59770
|
}
|
|
59771
|
+
return normalizeSelectedLineIds([legacyLineId]);
|
|
59488
59772
|
}
|
|
59489
59773
|
} catch (error) {
|
|
59490
59774
|
console.warn("Failed to read line filter from sessionStorage:", error);
|
|
59491
59775
|
}
|
|
59492
|
-
return
|
|
59493
|
-
}
|
|
59776
|
+
return null;
|
|
59777
|
+
};
|
|
59778
|
+
const [selectedLineIds, setSelectedLineIds] = React142.useState(() => readPersistedSelectedLineIds() || normalizeSelectedLineIds([defaultHomeLineId]));
|
|
59779
|
+
const [isLineSelectorOpen, setIsLineSelectorOpen] = React142.useState(false);
|
|
59780
|
+
const [pendingSelectedLineIds, setPendingSelectedLineIds] = React142.useState([]);
|
|
59781
|
+
const lineSelectorRef = React142.useRef(null);
|
|
59782
|
+
React142.useEffect(() => {
|
|
59783
|
+
if (isLineSelectorOpen) {
|
|
59784
|
+
setPendingSelectedLineIds(selectedLineIds);
|
|
59785
|
+
}
|
|
59786
|
+
}, [isLineSelectorOpen, selectedLineIds]);
|
|
59494
59787
|
React142.useEffect(() => {
|
|
59495
|
-
if (!
|
|
59788
|
+
if (!hasUser || visibleLineIds.length === 0) {
|
|
59496
59789
|
return;
|
|
59497
59790
|
}
|
|
59498
|
-
|
|
59499
|
-
|
|
59500
|
-
if (
|
|
59501
|
-
|
|
59502
|
-
setSelectedLineId(savedLineId);
|
|
59503
|
-
}
|
|
59504
|
-
return;
|
|
59791
|
+
const restoredLineIds = readPersistedSelectedLineIds();
|
|
59792
|
+
setSelectedLineIds((previousSelectedLineIds) => {
|
|
59793
|
+
if (restoredLineIds) {
|
|
59794
|
+
return selectedLineIdsEqual(restoredLineIds, previousSelectedLineIds) ? previousSelectedLineIds : restoredLineIds;
|
|
59505
59795
|
}
|
|
59796
|
+
const normalizedCurrentLineIds = normalizeSelectedLineIds(previousSelectedLineIds);
|
|
59797
|
+
return selectedLineIdsEqual(normalizedCurrentLineIds, previousSelectedLineIds) ? previousSelectedLineIds : normalizedCurrentLineIds;
|
|
59798
|
+
});
|
|
59799
|
+
}, [hasUser, visibleLineIdsKey, defaultHomeLineId, factoryViewId]);
|
|
59800
|
+
React142.useEffect(() => {
|
|
59801
|
+
try {
|
|
59802
|
+
sessionStorage.setItem("optifye_home_line_filters_v2", JSON.stringify(selectedLineIds));
|
|
59803
|
+
sessionStorage.removeItem("optifye_home_line_filter");
|
|
59506
59804
|
} catch (error) {
|
|
59507
|
-
console.warn("Failed to
|
|
59805
|
+
console.warn("Failed to save line filter to sessionStorage:", error);
|
|
59508
59806
|
}
|
|
59509
|
-
|
|
59807
|
+
}, [selectedLineIds]);
|
|
59808
|
+
React142.useEffect(() => {
|
|
59809
|
+
if (!isLineSelectorOpen) {
|
|
59510
59810
|
return;
|
|
59511
59811
|
}
|
|
59512
|
-
|
|
59513
|
-
|
|
59514
|
-
|
|
59515
|
-
|
|
59516
|
-
|
|
59517
|
-
|
|
59518
|
-
|
|
59519
|
-
|
|
59520
|
-
|
|
59521
|
-
]);
|
|
59812
|
+
const handleClickOutside = (event) => {
|
|
59813
|
+
if (lineSelectorRef.current && !lineSelectorRef.current.contains(event.target)) {
|
|
59814
|
+
setIsLineSelectorOpen(false);
|
|
59815
|
+
}
|
|
59816
|
+
};
|
|
59817
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
59818
|
+
return () => {
|
|
59819
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
59820
|
+
};
|
|
59821
|
+
}, [isLineSelectorOpen]);
|
|
59822
|
+
const primarySelectedLineId = selectedLineIds[0] || defaultHomeLineId;
|
|
59823
|
+
const isMultiLineSelection = selectedLineIds.length > 1;
|
|
59824
|
+
const selectedLineIdsKey = selectedLineIds.join(",");
|
|
59825
|
+
const selectedLineIdSet = React142.useMemo(
|
|
59826
|
+
() => new Set(selectedLineIds),
|
|
59827
|
+
[selectedLineIds]
|
|
59828
|
+
);
|
|
59829
|
+
const metricsScopeLineId = isMultiLineSelection ? factoryViewId : primarySelectedLineId;
|
|
59522
59830
|
const userCompanyId = React142.useMemo(() => {
|
|
59523
59831
|
return user?.properties?.company_id || user?.company_id || entityConfig.companyId;
|
|
59524
59832
|
}, [user, entityConfig.companyId]);
|
|
@@ -59538,12 +59846,8 @@ function HomeView({
|
|
|
59538
59846
|
React142.useEffect(() => {
|
|
59539
59847
|
const initDisplayNames = async () => {
|
|
59540
59848
|
try {
|
|
59541
|
-
|
|
59542
|
-
|
|
59543
|
-
await preInitializeWorkspaceDisplayNames(lineId);
|
|
59544
|
-
}
|
|
59545
|
-
} else {
|
|
59546
|
-
await preInitializeWorkspaceDisplayNames(selectedLineId);
|
|
59849
|
+
for (const lineId of selectedLineIds) {
|
|
59850
|
+
await preInitializeWorkspaceDisplayNames(lineId);
|
|
59547
59851
|
}
|
|
59548
59852
|
setDisplayNamesInitialized(true);
|
|
59549
59853
|
} catch (error) {
|
|
@@ -59552,8 +59856,8 @@ function HomeView({
|
|
|
59552
59856
|
}
|
|
59553
59857
|
};
|
|
59554
59858
|
initDisplayNames();
|
|
59555
|
-
}, [
|
|
59556
|
-
const displayNameLineId =
|
|
59859
|
+
}, [selectedLineIdsKey]);
|
|
59860
|
+
const displayNameLineId = isMultiLineSelection ? void 0 : primarySelectedLineId;
|
|
59557
59861
|
const {
|
|
59558
59862
|
displayNames: workspaceDisplayNames,
|
|
59559
59863
|
loading: displayNamesLoading,
|
|
@@ -59582,7 +59886,8 @@ function HomeView({
|
|
|
59582
59886
|
error: metricsError,
|
|
59583
59887
|
refetch: refetchMetrics
|
|
59584
59888
|
} = useDashboardMetrics({
|
|
59585
|
-
lineId:
|
|
59889
|
+
lineId: metricsScopeLineId,
|
|
59890
|
+
lineIds: selectedLineIds,
|
|
59586
59891
|
onLineMetricsUpdate: handleLineMetricsUpdate,
|
|
59587
59892
|
userAccessibleLineIds: visibleLineIds
|
|
59588
59893
|
// Pass user's accessible lines for supervisor filtering
|
|
@@ -59590,10 +59895,8 @@ function HomeView({
|
|
|
59590
59895
|
const trendGroups = React142.useMemo(() => {
|
|
59591
59896
|
const lineMetricsRows = lineMetrics || [];
|
|
59592
59897
|
if (!lineMetricsRows.length) return null;
|
|
59593
|
-
if (
|
|
59594
|
-
const
|
|
59595
|
-
if (!candidateLineIds.length) return null;
|
|
59596
|
-
const rowsForLines = lineMetricsRows.filter((row2) => candidateLineIds.includes(row2?.line_id));
|
|
59898
|
+
if (selectedLineIds.length > 1) {
|
|
59899
|
+
const rowsForLines = lineMetricsRows.filter((row2) => selectedLineIdSet.has(row2?.line_id));
|
|
59597
59900
|
if (!rowsForLines.length) return null;
|
|
59598
59901
|
const groupsMap = /* @__PURE__ */ new Map();
|
|
59599
59902
|
rowsForLines.forEach((row2) => {
|
|
@@ -59616,16 +59919,16 @@ function HomeView({
|
|
|
59616
59919
|
shiftId: group.shiftId
|
|
59617
59920
|
}));
|
|
59618
59921
|
}
|
|
59619
|
-
const row = lineMetricsRows.find((r2) => r2?.line_id ===
|
|
59922
|
+
const row = lineMetricsRows.find((r2) => r2?.line_id === primarySelectedLineId);
|
|
59620
59923
|
if (!row?.date || row?.shift_id === void 0 || row?.shift_id === null) {
|
|
59621
59924
|
return null;
|
|
59622
59925
|
}
|
|
59623
59926
|
return [{
|
|
59624
|
-
lineIds: [
|
|
59927
|
+
lineIds: [primarySelectedLineId],
|
|
59625
59928
|
date: row.date,
|
|
59626
59929
|
shiftId: row.shift_id
|
|
59627
59930
|
}];
|
|
59628
|
-
}, [
|
|
59931
|
+
}, [lineMetrics, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
|
|
59629
59932
|
const trendOptions = React142.useMemo(() => {
|
|
59630
59933
|
if (!trendGroups || !userCompanyId) return null;
|
|
59631
59934
|
return {
|
|
@@ -59653,17 +59956,18 @@ function HomeView({
|
|
|
59653
59956
|
}, [workspaceMetrics, metricsLoading, metricsError]);
|
|
59654
59957
|
const kpis = React142.useMemo(() => {
|
|
59655
59958
|
const lineMetricsRows = lineMetrics || [];
|
|
59656
|
-
if (
|
|
59657
|
-
|
|
59658
|
-
|
|
59959
|
+
if (selectedLineIds.length > 1) {
|
|
59960
|
+
const rowsForSelectedLines = lineMetricsRows.filter((row2) => selectedLineIdSet.has(row2?.line_id));
|
|
59961
|
+
if (metricsLoading && rowsForSelectedLines.length === 0) return null;
|
|
59962
|
+
return aggregateKPIsFromLineMetricsRows(rowsForSelectedLines);
|
|
59659
59963
|
}
|
|
59660
|
-
const row = lineMetricsRows.find((r2) => r2?.line_id ===
|
|
59964
|
+
const row = lineMetricsRows.find((r2) => r2?.line_id === primarySelectedLineId);
|
|
59661
59965
|
if (!row) {
|
|
59662
59966
|
if (metricsLoading) return null;
|
|
59663
59967
|
return buildKPIsFromLineMetricsRow(null);
|
|
59664
59968
|
}
|
|
59665
59969
|
return buildKPIsFromLineMetricsRow(row);
|
|
59666
|
-
}, [
|
|
59970
|
+
}, [lineMetrics, metricsLoading, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
|
|
59667
59971
|
const kpisWithTrend = React142.useMemo(() => {
|
|
59668
59972
|
if (!kpis) return null;
|
|
59669
59973
|
if (!kpiTrend) return kpis;
|
|
@@ -59688,30 +59992,30 @@ function HomeView({
|
|
|
59688
59992
|
};
|
|
59689
59993
|
}, [kpis, kpiTrend]);
|
|
59690
59994
|
const selectedLineMeta = React142.useMemo(
|
|
59691
|
-
() => dbLines.find((line) => line.id ===
|
|
59692
|
-
[dbLines,
|
|
59995
|
+
() => selectedLineIds.length === 1 ? dbLines.find((line) => line.id === primarySelectedLineId) : void 0,
|
|
59996
|
+
[dbLines, primarySelectedLineId, selectedLineIds.length]
|
|
59693
59997
|
);
|
|
59694
|
-
const selectedMonitoringMode =
|
|
59998
|
+
const selectedMonitoringMode = selectedLineIds.length === 1 ? selectedLineMeta?.monitoring_mode ?? "output" : "output";
|
|
59695
59999
|
const isUptimeMode = selectedMonitoringMode === "uptime";
|
|
59696
60000
|
const averageIdleTimeSeconds = React142.useMemo(() => {
|
|
59697
60001
|
if (!isUptimeMode) return null;
|
|
59698
|
-
const targetWorkspaces =
|
|
60002
|
+
const targetWorkspaces = workspaceMetrics.filter((ws) => ws.line_id === primarySelectedLineId);
|
|
59699
60003
|
const idleValues = targetWorkspaces.map((ws) => ws.idle_time).filter((value) => Number.isFinite(value));
|
|
59700
60004
|
if (idleValues.length === 0) return 0;
|
|
59701
60005
|
const totalIdle = idleValues.reduce((sum, value) => sum + value, 0);
|
|
59702
60006
|
return totalIdle / idleValues.length;
|
|
59703
|
-
}, [isUptimeMode,
|
|
60007
|
+
}, [isUptimeMode, primarySelectedLineId, workspaceMetrics]);
|
|
59704
60008
|
const {
|
|
59705
60009
|
activeBreaks: allActiveBreaks,
|
|
59706
60010
|
isLoading: breaksLoading,
|
|
59707
60011
|
error: breaksError
|
|
59708
|
-
} = useActiveBreaks(
|
|
60012
|
+
} = useActiveBreaks(visibleLineIds);
|
|
59709
60013
|
const activeBreaks = React142.useMemo(() => {
|
|
59710
|
-
if (
|
|
60014
|
+
if (isAllLinesSelection(selectedLineIds)) {
|
|
59711
60015
|
return allActiveBreaks;
|
|
59712
60016
|
}
|
|
59713
|
-
return allActiveBreaks.filter((breakItem) => breakItem.lineId
|
|
59714
|
-
}, [allActiveBreaks,
|
|
60017
|
+
return allActiveBreaks.filter((breakItem) => selectedLineIdSet.has(breakItem.lineId));
|
|
60018
|
+
}, [allActiveBreaks, selectedLineIdSet, selectedLineIds]);
|
|
59715
60019
|
const activeBreakLineIds = React142.useMemo(
|
|
59716
60020
|
() => new Set(activeBreaks.map((breakItem) => breakItem.lineId)),
|
|
59717
60021
|
[activeBreaks]
|
|
@@ -60018,7 +60322,7 @@ function HomeView({
|
|
|
60018
60322
|
// Round to 1 decimal
|
|
60019
60323
|
kpisWithTrend?.avgCycleTime?.change,
|
|
60020
60324
|
kpisWithTrend?.qualityCompliance?.value ? Math.round(kpisWithTrend.qualityCompliance.value) : null,
|
|
60021
|
-
|
|
60325
|
+
selectedLineIdsKey
|
|
60022
60326
|
]);
|
|
60023
60327
|
React142.useEffect(() => {
|
|
60024
60328
|
setIsHydrated(true);
|
|
@@ -60035,27 +60339,62 @@ function HomeView({
|
|
|
60035
60339
|
setErrorMessage(null);
|
|
60036
60340
|
}
|
|
60037
60341
|
}, [metricsError]);
|
|
60038
|
-
const
|
|
60342
|
+
const getTrackedLineScope = React142.useCallback((lineIdsForScope) => {
|
|
60343
|
+
if (isAllLinesSelection(lineIdsForScope)) {
|
|
60344
|
+
return factoryViewId;
|
|
60345
|
+
}
|
|
60346
|
+
if (lineIdsForScope.length === 1) {
|
|
60347
|
+
return lineIdsForScope[0];
|
|
60348
|
+
}
|
|
60349
|
+
return "custom_multi";
|
|
60350
|
+
}, [factoryViewId, visibleLineIds.length]);
|
|
60351
|
+
const getLineSelectionLabel = React142.useCallback((lineIdsForScope) => {
|
|
60352
|
+
if (isAllLinesSelection(lineIdsForScope)) {
|
|
60353
|
+
return "All Lines";
|
|
60354
|
+
}
|
|
60355
|
+
if (lineIdsForScope.length === 1) {
|
|
60356
|
+
const lineId = lineIdsForScope[0];
|
|
60357
|
+
return mergedLineNames[lineId] || `Line ${lineId.substring(0, 4)}`;
|
|
60358
|
+
}
|
|
60359
|
+
return `${lineIdsForScope.length} Lines Selected`;
|
|
60360
|
+
}, [mergedLineNames, visibleLineIds.length]);
|
|
60361
|
+
const updateSelectedLineIds = React142.useCallback((nextLineIds) => {
|
|
60362
|
+
const normalizedLineIds = normalizeSelectedLineIds(nextLineIds);
|
|
60363
|
+
if (selectedLineIdsEqual(normalizedLineIds, selectedLineIds)) {
|
|
60364
|
+
return;
|
|
60365
|
+
}
|
|
60039
60366
|
setIsChangingFilter(true);
|
|
60040
|
-
|
|
60367
|
+
setSelectedLineIds(normalizedLineIds);
|
|
60041
60368
|
trackCoreEvent("monitor line filter changed", {
|
|
60042
|
-
previous_line_id:
|
|
60043
|
-
new_line_id:
|
|
60044
|
-
|
|
60369
|
+
previous_line_id: getTrackedLineScope(selectedLineIds),
|
|
60370
|
+
new_line_id: getTrackedLineScope(normalizedLineIds),
|
|
60371
|
+
previous_line_ids: selectedLineIds,
|
|
60372
|
+
new_line_ids: normalizedLineIds,
|
|
60373
|
+
selected_line_count: normalizedLineIds.length,
|
|
60374
|
+
selection_mode: isAllLinesSelection(normalizedLineIds) ? "all" : normalizedLineIds.length === 1 ? "single" : "custom",
|
|
60375
|
+
line_name: getLineSelectionLabel(normalizedLineIds)
|
|
60045
60376
|
});
|
|
60046
|
-
|
|
60047
|
-
|
|
60048
|
-
|
|
60049
|
-
|
|
60377
|
+
}, [factoryViewId, getLineSelectionLabel, getTrackedLineScope, selectedLineIds, selectedLineIdsKey, visibleLineIds]);
|
|
60378
|
+
React142.useCallback(() => {
|
|
60379
|
+
updateSelectedLineIds(visibleLineIds);
|
|
60380
|
+
}, [updateSelectedLineIds, visibleLineIds]);
|
|
60381
|
+
React142.useCallback((lineId) => {
|
|
60382
|
+
const currentSelection = new Set(selectedLineIds);
|
|
60383
|
+
if (currentSelection.has(lineId)) {
|
|
60384
|
+
if (currentSelection.size <= 1) {
|
|
60385
|
+
return;
|
|
60386
|
+
}
|
|
60387
|
+
currentSelection.delete(lineId);
|
|
60388
|
+
} else {
|
|
60389
|
+
currentSelection.add(lineId);
|
|
60050
60390
|
}
|
|
60051
|
-
|
|
60391
|
+
updateSelectedLineIds(Array.from(currentSelection));
|
|
60392
|
+
}, [selectedLineIds, updateSelectedLineIds]);
|
|
60052
60393
|
React142.useEffect(() => {
|
|
60053
60394
|
if (!metricsLoading && isChangingFilter) {
|
|
60054
|
-
|
|
60055
|
-
setIsChangingFilter(false);
|
|
60056
|
-
}
|
|
60395
|
+
setIsChangingFilter(false);
|
|
60057
60396
|
}
|
|
60058
|
-
}, [metricsLoading,
|
|
60397
|
+
}, [metricsLoading, isChangingFilter]);
|
|
60059
60398
|
React142.useEffect(() => {
|
|
60060
60399
|
if (!metricsLoading && !hasInitialDataLoaded) {
|
|
60061
60400
|
setHasInitialDataLoaded(true);
|
|
@@ -60074,11 +60413,107 @@ function HomeView({
|
|
|
60074
60413
|
if (visibleLineIds.length <= 1) {
|
|
60075
60414
|
return null;
|
|
60076
60415
|
}
|
|
60077
|
-
|
|
60078
|
-
|
|
60079
|
-
/* @__PURE__ */ jsxRuntime.
|
|
60416
|
+
const allLinesSelected = isAllLinesSelection(pendingSelectedLineIds);
|
|
60417
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: lineSelectorRef, className: "relative", children: [
|
|
60418
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
60419
|
+
"button",
|
|
60420
|
+
{
|
|
60421
|
+
type: "button",
|
|
60422
|
+
onClick: () => setIsLineSelectorOpen((previous) => !previous),
|
|
60423
|
+
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",
|
|
60424
|
+
"aria-haspopup": "menu",
|
|
60425
|
+
"aria-expanded": isLineSelectorOpen,
|
|
60426
|
+
"aria-label": "Select lines",
|
|
60427
|
+
children: [
|
|
60428
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: getLineSelectionLabel(selectedLineIds) }),
|
|
60429
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: `h-4 w-4 text-slate-400 transition-transform ${isLineSelectorOpen ? "rotate-180" : ""}` })
|
|
60430
|
+
]
|
|
60431
|
+
}
|
|
60432
|
+
),
|
|
60433
|
+
isLineSelectorOpen ? /* @__PURE__ */ jsxRuntime.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: [
|
|
60434
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between pb-2 border-b border-slate-100", children: [
|
|
60435
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-slate-800", children: "Select Lines" }),
|
|
60436
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
60437
|
+
"button",
|
|
60438
|
+
{
|
|
60439
|
+
type: "button",
|
|
60440
|
+
onClick: () => setPendingSelectedLineIds([]),
|
|
60441
|
+
className: "text-xs font-medium text-blue-600 hover:text-blue-700 transition-colors",
|
|
60442
|
+
children: "Clear All"
|
|
60443
|
+
}
|
|
60444
|
+
)
|
|
60445
|
+
] }),
|
|
60446
|
+
/* @__PURE__ */ jsxRuntime.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: [
|
|
60447
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
60448
|
+
"input",
|
|
60449
|
+
{
|
|
60450
|
+
type: "checkbox",
|
|
60451
|
+
className: "h-4 w-4 rounded border-slate-300 text-blue-600 focus:ring-blue-500",
|
|
60452
|
+
checked: allLinesSelected,
|
|
60453
|
+
onChange: () => setPendingSelectedLineIds(allLinesSelected ? [] : visibleLineIds)
|
|
60454
|
+
}
|
|
60455
|
+
),
|
|
60456
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "All Lines" })
|
|
60457
|
+
] }),
|
|
60458
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-56 space-y-0.5 overflow-y-auto pr-1", children: visibleLineIds.map((lineId) => {
|
|
60459
|
+
const isChecked = pendingSelectedLineIds.includes(lineId);
|
|
60460
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
60461
|
+
"label",
|
|
60462
|
+
{
|
|
60463
|
+
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",
|
|
60464
|
+
children: [
|
|
60465
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
60466
|
+
"input",
|
|
60467
|
+
{
|
|
60468
|
+
type: "checkbox",
|
|
60469
|
+
className: "h-4 w-4 rounded border-slate-300 text-blue-600 focus:ring-blue-500",
|
|
60470
|
+
checked: isChecked,
|
|
60471
|
+
onChange: () => {
|
|
60472
|
+
setPendingSelectedLineIds((prev) => {
|
|
60473
|
+
const current = new Set(prev);
|
|
60474
|
+
if (current.has(lineId)) {
|
|
60475
|
+
current.delete(lineId);
|
|
60476
|
+
} else {
|
|
60477
|
+
current.add(lineId);
|
|
60478
|
+
}
|
|
60479
|
+
return Array.from(current);
|
|
60480
|
+
});
|
|
60481
|
+
}
|
|
60482
|
+
}
|
|
60483
|
+
),
|
|
60484
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: mergedLineNames[lineId] || `Line ${lineId.substring(0, 4)}` })
|
|
60485
|
+
]
|
|
60486
|
+
},
|
|
60487
|
+
lineId
|
|
60488
|
+
);
|
|
60489
|
+
}) }),
|
|
60490
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-3 pb-1 mt-1 border-t border-slate-100 flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
60491
|
+
"button",
|
|
60492
|
+
{
|
|
60493
|
+
type: "button",
|
|
60494
|
+
onClick: () => {
|
|
60495
|
+
if (pendingSelectedLineIds.length > 0) {
|
|
60496
|
+
updateSelectedLineIds(pendingSelectedLineIds);
|
|
60497
|
+
}
|
|
60498
|
+
setIsLineSelectorOpen(false);
|
|
60499
|
+
},
|
|
60500
|
+
disabled: pendingSelectedLineIds.length === 0,
|
|
60501
|
+
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",
|
|
60502
|
+
children: "Apply"
|
|
60503
|
+
}
|
|
60504
|
+
) })
|
|
60505
|
+
] }) : null
|
|
60080
60506
|
] });
|
|
60081
|
-
}, [
|
|
60507
|
+
}, [
|
|
60508
|
+
getLineSelectionLabel,
|
|
60509
|
+
isLineSelectorOpen,
|
|
60510
|
+
mergedLineNames,
|
|
60511
|
+
selectedLineIds,
|
|
60512
|
+
pendingSelectedLineIds,
|
|
60513
|
+
visibleLineIds,
|
|
60514
|
+
updateSelectedLineIds,
|
|
60515
|
+
isAllLinesSelection
|
|
60516
|
+
]);
|
|
60082
60517
|
const useSmoothLoading = (isLoading, minDuration = 400) => {
|
|
60083
60518
|
const [showLoading, setShowLoading] = React142.useState(isLoading);
|
|
60084
60519
|
const loadingStartRef2 = React142.useRef(null);
|
|
@@ -60124,11 +60559,11 @@ function HomeView({
|
|
|
60124
60559
|
const isDataLoading = metricsLoading || displayNamesLoading && workspaceMetrics.length === 0;
|
|
60125
60560
|
const hasKpiDataReady = React142.useMemo(() => {
|
|
60126
60561
|
const lineMetricsRows = lineMetrics || [];
|
|
60127
|
-
if (
|
|
60128
|
-
return lineMetricsRows.
|
|
60562
|
+
if (selectedLineIds.length > 1) {
|
|
60563
|
+
return lineMetricsRows.some((row) => selectedLineIdSet.has(row?.line_id));
|
|
60129
60564
|
}
|
|
60130
|
-
return lineMetricsRows.some((row) => row?.line_id ===
|
|
60131
|
-
}, [lineMetrics,
|
|
60565
|
+
return lineMetricsRows.some((row) => row?.line_id === primarySelectedLineId);
|
|
60566
|
+
}, [lineMetrics, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
|
|
60132
60567
|
const isKpiLoading = !hasKpiDataReady;
|
|
60133
60568
|
React142.useEffect(() => {
|
|
60134
60569
|
const minLoadingDurationMs = 250;
|
|
@@ -60190,76 +60625,77 @@ function HomeView({
|
|
|
60190
60625
|
DashboardHeader,
|
|
60191
60626
|
{
|
|
60192
60627
|
lineTitle,
|
|
60193
|
-
lineId:
|
|
60628
|
+
lineId: primarySelectedLineId,
|
|
60194
60629
|
className: "w-full",
|
|
60195
60630
|
headerControls: kpiSectionControl
|
|
60196
60631
|
}
|
|
60197
60632
|
) }) }),
|
|
60198
|
-
/* @__PURE__ */ jsxRuntime.
|
|
60199
|
-
|
|
60200
|
-
|
|
60201
|
-
|
|
60202
|
-
{
|
|
60203
|
-
|
|
60204
|
-
|
|
60205
|
-
|
|
60633
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-[calc(100vh-100px)] sm:min-h-0", children: workspaceMetricsWithBreakState.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
60634
|
+
motion.div,
|
|
60635
|
+
{
|
|
60636
|
+
initial: { opacity: 0, scale: 0.98 },
|
|
60637
|
+
animate: { opacity: 1, scale: 1 },
|
|
60638
|
+
transition: { duration: 0.3 },
|
|
60639
|
+
className: "h-full",
|
|
60640
|
+
children: React142__namespace.default.createElement(WorkspaceGrid, {
|
|
60641
|
+
workspaces: workspaceMetricsWithBreakState,
|
|
60642
|
+
lineNames: mergedLineNames,
|
|
60643
|
+
lineOrder: selectedLineIds,
|
|
60644
|
+
factoryView: factoryViewId,
|
|
60645
|
+
legend: efficiencyLegend,
|
|
60646
|
+
videoSources,
|
|
60647
|
+
videoStreamsByWorkspaceId,
|
|
60648
|
+
videoStreamsLoading,
|
|
60649
|
+
displayNames: workspaceDisplayNames,
|
|
60650
|
+
hasFlowBuffers,
|
|
60206
60651
|
className: "h-full",
|
|
60207
|
-
|
|
60208
|
-
|
|
60209
|
-
|
|
60210
|
-
|
|
60211
|
-
|
|
60212
|
-
|
|
60213
|
-
|
|
60214
|
-
|
|
60215
|
-
|
|
60216
|
-
|
|
60217
|
-
|
|
60218
|
-
|
|
60219
|
-
|
|
60220
|
-
|
|
60221
|
-
|
|
60222
|
-
|
|
60223
|
-
|
|
60224
|
-
|
|
60225
|
-
{
|
|
60226
|
-
|
|
60227
|
-
|
|
60228
|
-
|
|
60229
|
-
|
|
60230
|
-
|
|
60231
|
-
|
|
60232
|
-
|
|
60233
|
-
|
|
60234
|
-
|
|
60235
|
-
|
|
60236
|
-
|
|
60652
|
+
toolbarRightContent: lineSelectorComponent,
|
|
60653
|
+
onWorkspaceHover: handleWorkspaceHover,
|
|
60654
|
+
onWorkspaceHoverEnd: handleWorkspaceHoverEnd
|
|
60655
|
+
})
|
|
60656
|
+
},
|
|
60657
|
+
selectedLineIdsKey
|
|
60658
|
+
) : !shouldShowDataLoading && hasInitialDataLoaded ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
60659
|
+
motion.div,
|
|
60660
|
+
{
|
|
60661
|
+
initial: { opacity: 0 },
|
|
60662
|
+
animate: { opacity: 1 },
|
|
60663
|
+
transition: { duration: 0.3 },
|
|
60664
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(NoWorkspaceData, { message: "No workspace data available. Adjust the selected lines or check configurations." })
|
|
60665
|
+
}
|
|
60666
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
60667
|
+
motion.div,
|
|
60668
|
+
{
|
|
60669
|
+
initial: { opacity: 0, scale: 0.98 },
|
|
60670
|
+
animate: { opacity: 1, scale: 1 },
|
|
60671
|
+
transition: { duration: 0.3 },
|
|
60672
|
+
className: "h-full",
|
|
60673
|
+
children: React142__namespace.default.createElement(WorkspaceGrid, {
|
|
60674
|
+
workspaces: [],
|
|
60675
|
+
// Show empty grid while loading
|
|
60676
|
+
lineNames: mergedLineNames,
|
|
60677
|
+
lineOrder: selectedLineIds,
|
|
60678
|
+
factoryView: factoryViewId,
|
|
60679
|
+
legend: efficiencyLegend,
|
|
60680
|
+
videoSources,
|
|
60681
|
+
videoStreamsByWorkspaceId,
|
|
60682
|
+
videoStreamsLoading,
|
|
60683
|
+
displayNames: workspaceDisplayNames,
|
|
60684
|
+
hasFlowBuffers,
|
|
60237
60685
|
className: "h-full",
|
|
60238
|
-
|
|
60239
|
-
|
|
60240
|
-
|
|
60241
|
-
|
|
60242
|
-
|
|
60243
|
-
|
|
60244
|
-
|
|
60245
|
-
videoStreamsByWorkspaceId,
|
|
60246
|
-
videoStreamsLoading,
|
|
60247
|
-
displayNames: workspaceDisplayNames,
|
|
60248
|
-
hasFlowBuffers,
|
|
60249
|
-
className: "h-full",
|
|
60250
|
-
onWorkspaceHover: handleWorkspaceHover,
|
|
60251
|
-
onWorkspaceHoverEnd: handleWorkspaceHoverEnd
|
|
60252
|
-
})
|
|
60253
|
-
},
|
|
60254
|
-
selectedLineId
|
|
60255
|
-
) })
|
|
60256
|
-
] })
|
|
60686
|
+
toolbarRightContent: lineSelectorComponent,
|
|
60687
|
+
onWorkspaceHover: handleWorkspaceHover,
|
|
60688
|
+
onWorkspaceHoverEnd: handleWorkspaceHoverEnd
|
|
60689
|
+
})
|
|
60690
|
+
},
|
|
60691
|
+
selectedLineIdsKey
|
|
60692
|
+
) }) })
|
|
60257
60693
|
] }),
|
|
60258
60694
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
60259
60695
|
BreakNotificationPopup,
|
|
60260
60696
|
{
|
|
60261
60697
|
activeBreaks,
|
|
60262
|
-
lineNames,
|
|
60698
|
+
lineNames: mergedLineNames,
|
|
60263
60699
|
isVisible: !breaksLoading && !breaksError && !breakNotificationsDismissed,
|
|
60264
60700
|
onDismiss: () => setBreakNotificationsDismissed(true)
|
|
60265
60701
|
}
|
|
@@ -69398,6 +69834,10 @@ var WorkspaceDetailView = ({
|
|
|
69398
69834
|
shiftId: selectedShift,
|
|
69399
69835
|
companyId: dashboardConfig?.entityConfig?.companyId
|
|
69400
69836
|
});
|
|
69837
|
+
const {
|
|
69838
|
+
isFastSlowClipFiltersEnabled,
|
|
69839
|
+
isResolved: isFastSlowClipFiltersResolved
|
|
69840
|
+
} = useCompanyFastSlowClipFiltersEnabled();
|
|
69401
69841
|
const isClipsEnabled = dashboardConfig?.clipsConfig?.enabled ?? true;
|
|
69402
69842
|
dashboardConfig?.supervisorConfig?.enabled || false;
|
|
69403
69843
|
const effectiveLineId = lineId || selectedLineId;
|
|
@@ -69484,15 +69924,19 @@ var WorkspaceDetailView = ({
|
|
|
69484
69924
|
return `${workspaceId}:${percentileDate}:${percentileShiftId.toString()}:10`;
|
|
69485
69925
|
}, [workspaceId, percentileDate, percentileShiftId]);
|
|
69486
69926
|
React142.useEffect(() => {
|
|
69487
|
-
if (!percentileCountsKey) {
|
|
69927
|
+
if (!isFastSlowClipFiltersEnabled || !percentileCountsKey) {
|
|
69488
69928
|
setPrefetchedPercentileCounts(null);
|
|
69489
69929
|
return;
|
|
69490
69930
|
}
|
|
69491
69931
|
if (prefetchedPercentileCounts && prefetchedPercentileCounts.key !== percentileCountsKey) {
|
|
69492
69932
|
setPrefetchedPercentileCounts(null);
|
|
69493
69933
|
}
|
|
69494
|
-
}, [percentileCountsKey, prefetchedPercentileCounts]);
|
|
69934
|
+
}, [isFastSlowClipFiltersEnabled, percentileCountsKey, prefetchedPercentileCounts]);
|
|
69495
69935
|
React142.useEffect(() => {
|
|
69936
|
+
if (!isFastSlowClipFiltersEnabled || !isFastSlowClipFiltersResolved) {
|
|
69937
|
+
setPrefetchedPercentileCounts(null);
|
|
69938
|
+
return;
|
|
69939
|
+
}
|
|
69496
69940
|
if (!percentileCountsKey || !percentileDate || percentileShiftId === null || percentileShiftId === void 0) {
|
|
69497
69941
|
return;
|
|
69498
69942
|
}
|
|
@@ -69559,7 +70003,16 @@ var WorkspaceDetailView = ({
|
|
|
69559
70003
|
return () => {
|
|
69560
70004
|
controller.abort();
|
|
69561
70005
|
};
|
|
69562
|
-
}, [
|
|
70006
|
+
}, [
|
|
70007
|
+
isFastSlowClipFiltersEnabled,
|
|
70008
|
+
isFastSlowClipFiltersResolved,
|
|
70009
|
+
percentileCountsKey,
|
|
70010
|
+
percentileDate,
|
|
70011
|
+
percentileShiftId,
|
|
70012
|
+
workspaceId,
|
|
70013
|
+
supabase,
|
|
70014
|
+
prefetchedPercentileCounts
|
|
70015
|
+
]);
|
|
69563
70016
|
const {
|
|
69564
70017
|
metrics: historicMetrics,
|
|
69565
70018
|
isLoading: historicLoading,
|
|
@@ -70835,7 +71288,7 @@ var WorkspaceDetailView = ({
|
|
|
70835
71288
|
shift,
|
|
70836
71289
|
totalOutput: workspace?.total_actions,
|
|
70837
71290
|
workspaceMetrics: detailedWorkspaceMetrics || void 0,
|
|
70838
|
-
prefetchedPercentileCounts,
|
|
71291
|
+
prefetchedPercentileCounts: isFastSlowClipFiltersEnabled ? prefetchedPercentileCounts : null,
|
|
70839
71292
|
className: "h-[calc(100vh-10rem)]"
|
|
70840
71293
|
}
|
|
70841
71294
|
) })
|
|
@@ -80242,6 +80695,7 @@ exports.useClipTypes = useClipTypes;
|
|
|
80242
80695
|
exports.useClipTypesWithCounts = useClipTypesWithCounts;
|
|
80243
80696
|
exports.useClipsInit = useClipsInit;
|
|
80244
80697
|
exports.useCompanyClipsCost = useCompanyClipsCost;
|
|
80698
|
+
exports.useCompanyFastSlowClipFiltersEnabled = useCompanyFastSlowClipFiltersEnabled;
|
|
80245
80699
|
exports.useCompanyHasVlmEnabledLine = useCompanyHasVlmEnabledLine;
|
|
80246
80700
|
exports.useCompanyUsersUsage = useCompanyUsersUsage;
|
|
80247
80701
|
exports.useComponentOverride = useComponentOverride;
|