@optifye/dashboard-core 6.12.5 → 6.12.6
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 +23 -4
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +254 -77
- package/dist/index.mjs +255 -78
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21902,6 +21902,24 @@ var getConfigurableShortWorkspaceDisplayName = (workspaceId, workspaceConfig, li
|
|
|
21902
21902
|
return fullName;
|
|
21903
21903
|
};
|
|
21904
21904
|
|
|
21905
|
+
// src/lib/utils/efficiencyValidity.ts
|
|
21906
|
+
var MIN_VALID_OUTPUT_EFFICIENCY = 5;
|
|
21907
|
+
var MIN_VALID_UPTIME_EFFICIENCY = 1;
|
|
21908
|
+
var normalizeMonitoringMode = (mode) => String(mode ?? "").trim().toLowerCase() === "uptime" ? "uptime" : "output";
|
|
21909
|
+
var toFiniteNumberOrNull = (value) => {
|
|
21910
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
21911
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
21912
|
+
const parsed = Number(value);
|
|
21913
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
21914
|
+
}
|
|
21915
|
+
return null;
|
|
21916
|
+
};
|
|
21917
|
+
var isValidAggregateEfficiency = (monitoringMode, efficiency) => {
|
|
21918
|
+
const value = toFiniteNumberOrNull(efficiency);
|
|
21919
|
+
if (value === null) return false;
|
|
21920
|
+
return normalizeMonitoringMode(monitoringMode) === "uptime" ? value >= MIN_VALID_UPTIME_EFFICIENCY : value >= MIN_VALID_OUTPUT_EFFICIENCY;
|
|
21921
|
+
};
|
|
21922
|
+
|
|
21905
21923
|
// src/lib/utils/kpis.ts
|
|
21906
21924
|
var toNumber = (value) => {
|
|
21907
21925
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
@@ -21957,7 +21975,9 @@ var buildKPIsFromLineMetricsRow = (row) => {
|
|
|
21957
21975
|
};
|
|
21958
21976
|
var aggregateKPIsFromLineMetricsRows = (rows) => {
|
|
21959
21977
|
if (!rows || rows.length === 0) return createDefaultKPIs();
|
|
21960
|
-
const eligibleRows = rows.filter(
|
|
21978
|
+
const eligibleRows = rows.filter(
|
|
21979
|
+
(row) => isValidAggregateEfficiency(row?.monitoring_mode ?? row?.monitoringMode, row?.avg_efficiency)
|
|
21980
|
+
);
|
|
21961
21981
|
if (eligibleRows.length === 0) return createDefaultKPIs();
|
|
21962
21982
|
const currentOutputSum = eligibleRows.reduce((sum, row) => sum + toNumber(row.current_output), 0);
|
|
21963
21983
|
const lineThresholdSum = eligibleRows.reduce(
|
|
@@ -37285,8 +37305,8 @@ var HourlyOutputChart = React144__namespace.default.memo(
|
|
|
37285
37305
|
HourlyOutputChart.displayName = "HourlyOutputChart";
|
|
37286
37306
|
|
|
37287
37307
|
// src/components/dashboard/grid/videoGridMetricUtils.ts
|
|
37308
|
+
var VIDEO_GRID_LEGEND_LABEL = "Real-Time efficiency";
|
|
37288
37309
|
var MAP_GRID_LEGEND_LABEL = "Efficiency";
|
|
37289
|
-
var MIXED_VIDEO_GRID_LEGEND_LABEL = "Live Efficiency";
|
|
37290
37310
|
var isFiniteNumber2 = (value) => typeof value === "number" && Number.isFinite(value);
|
|
37291
37311
|
var isVideoGridRecentFlowEnabled = (workspace) => isRecentFlowVideoGridMetricMode(
|
|
37292
37312
|
workspace.video_grid_metric_mode,
|
|
@@ -37298,7 +37318,7 @@ var isVideoGridWipGated = (workspace) => isWipGatedVideoGridMetricMode(
|
|
|
37298
37318
|
);
|
|
37299
37319
|
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) && isFiniteNumber2(workspace.recent_flow_percent);
|
|
37300
37320
|
var isVideoGridRecentFlowUnavailable = (workspace) => isVideoGridRecentFlowEnabled(workspace) && !hasVideoGridRecentFlow(workspace);
|
|
37301
|
-
var
|
|
37321
|
+
var getRawVideoGridMetricValue = (workspace) => {
|
|
37302
37322
|
const recentFlowPercent = workspace.recent_flow_percent;
|
|
37303
37323
|
if (hasVideoGridRecentFlow(workspace) && isFiniteNumber2(recentFlowPercent)) {
|
|
37304
37324
|
return recentFlowPercent;
|
|
@@ -37310,7 +37330,7 @@ var getVideoGridMetricValue = (workspace) => {
|
|
|
37310
37330
|
};
|
|
37311
37331
|
var hasIncomingWipMapping = (workspace) => Boolean(workspace.incoming_wip_buffer_name);
|
|
37312
37332
|
var getVideoGridBaseColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
37313
|
-
const metricValue =
|
|
37333
|
+
const metricValue = getRawVideoGridMetricValue(workspace);
|
|
37314
37334
|
if (!isFiniteNumber2(metricValue)) {
|
|
37315
37335
|
return "neutral";
|
|
37316
37336
|
}
|
|
@@ -37334,6 +37354,25 @@ var isLowWipGreenOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
|
37334
37354
|
}
|
|
37335
37355
|
return isFiniteNumber2(workspace.incoming_wip_current) && workspace.incoming_wip_current <= 1;
|
|
37336
37356
|
};
|
|
37357
|
+
var isHighEfficiencyRedFlowOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
37358
|
+
if (workspace.scheduled_break_active === true) {
|
|
37359
|
+
return false;
|
|
37360
|
+
}
|
|
37361
|
+
if (workspace.recent_flow_forced_zero_after_shift === true) {
|
|
37362
|
+
return false;
|
|
37363
|
+
}
|
|
37364
|
+
if (!hasVideoGridRecentFlow(workspace) || !isVideoGridWipGated(workspace)) {
|
|
37365
|
+
return false;
|
|
37366
|
+
}
|
|
37367
|
+
if (isLowWipGreenOverride(workspace, legend)) {
|
|
37368
|
+
return false;
|
|
37369
|
+
}
|
|
37370
|
+
if (getVideoGridBaseColorState(workspace, legend) !== "red") {
|
|
37371
|
+
return false;
|
|
37372
|
+
}
|
|
37373
|
+
return isFiniteNumber2(workspace.efficiency) && workspace.efficiency > 100;
|
|
37374
|
+
};
|
|
37375
|
+
var getVideoGridMetricValue = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => isHighEfficiencyRedFlowOverride(workspace, legend) ? workspace.efficiency : getRawVideoGridMetricValue(workspace);
|
|
37337
37376
|
var toMinuteBucket = (minuteBucket) => Number.isFinite(minuteBucket) ? Math.floor(minuteBucket) : Math.floor(Date.now() / 6e4);
|
|
37338
37377
|
var getEffectiveFlowMinuteBucket = (workspace) => {
|
|
37339
37378
|
const effectiveAt = workspace.recent_flow_effective_end_at;
|
|
@@ -37359,7 +37398,7 @@ var getSyntheticLowWipDisplayValue = (workspace, minuteBucket) => {
|
|
|
37359
37398
|
const offset = (hashWorkspaceKey(workspace) % 11 + bucket % 11 + 11) % 11;
|
|
37360
37399
|
return 100 + offset;
|
|
37361
37400
|
};
|
|
37362
|
-
var getVideoGridDisplayValue = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND, minuteBucket) => isLowWipGreenOverride(workspace, legend) ? getSyntheticLowWipDisplayValue(workspace, minuteBucket) : getVideoGridMetricValue(workspace);
|
|
37401
|
+
var getVideoGridDisplayValue = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND, minuteBucket) => isLowWipGreenOverride(workspace, legend) ? getSyntheticLowWipDisplayValue(workspace, minuteBucket) : getVideoGridMetricValue(workspace, legend);
|
|
37363
37402
|
var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
37364
37403
|
const baseColor = getVideoGridBaseColorState(workspace, legend);
|
|
37365
37404
|
if (!hasVideoGridRecentFlow(workspace)) {
|
|
@@ -37371,15 +37410,18 @@ var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) =>
|
|
|
37371
37410
|
if (baseColor !== "red") {
|
|
37372
37411
|
return baseColor;
|
|
37373
37412
|
}
|
|
37413
|
+
if (isLowWipGreenOverride(workspace, legend)) {
|
|
37414
|
+
return "green";
|
|
37415
|
+
}
|
|
37416
|
+
if (isHighEfficiencyRedFlowOverride(workspace, legend)) {
|
|
37417
|
+
return getEfficiencyColor(workspace.efficiency, legend);
|
|
37418
|
+
}
|
|
37374
37419
|
if (!hasIncomingWipMapping(workspace)) {
|
|
37375
37420
|
return baseColor;
|
|
37376
37421
|
}
|
|
37377
37422
|
if (!isFiniteNumber2(workspace.incoming_wip_current)) {
|
|
37378
37423
|
return "neutral";
|
|
37379
37424
|
}
|
|
37380
|
-
if (isLowWipGreenOverride(workspace, legend)) {
|
|
37381
|
-
return "green";
|
|
37382
|
-
}
|
|
37383
37425
|
return baseColor;
|
|
37384
37426
|
};
|
|
37385
37427
|
var getVideoGridLegendLabel = (workspaces) => {
|
|
@@ -37387,21 +37429,7 @@ var getVideoGridLegendLabel = (workspaces) => {
|
|
|
37387
37429
|
if (visibleWorkspaces.length === 0) {
|
|
37388
37430
|
return MAP_GRID_LEGEND_LABEL;
|
|
37389
37431
|
}
|
|
37390
|
-
|
|
37391
|
-
if (recentFlowEnabledCount === 0) {
|
|
37392
|
-
return MAP_GRID_LEGEND_LABEL;
|
|
37393
|
-
}
|
|
37394
|
-
const recentFlowWindows = new Set(
|
|
37395
|
-
visibleWorkspaces.filter(isVideoGridRecentFlowEnabled).map((workspace) => workspace.recent_flow_window_minutes ?? 7).filter((value) => typeof value === "number" && Number.isFinite(value))
|
|
37396
|
-
);
|
|
37397
|
-
if (recentFlowEnabledCount === visibleWorkspaces.length) {
|
|
37398
|
-
if (recentFlowWindows.size === 1) {
|
|
37399
|
-
const [windowMinutes] = Array.from(recentFlowWindows);
|
|
37400
|
-
return `${windowMinutes} Minute Efficiency`;
|
|
37401
|
-
}
|
|
37402
|
-
return MIXED_VIDEO_GRID_LEGEND_LABEL;
|
|
37403
|
-
}
|
|
37404
|
-
return MIXED_VIDEO_GRID_LEGEND_LABEL;
|
|
37432
|
+
return visibleWorkspaces.some(isVideoGridRecentFlowEnabled) ? VIDEO_GRID_LEGEND_LABEL : MAP_GRID_LEGEND_LABEL;
|
|
37405
37433
|
};
|
|
37406
37434
|
function getTrendArrowAndColor(trend) {
|
|
37407
37435
|
if (trend > 0) {
|
|
@@ -37444,14 +37472,15 @@ var VideoCard = React144__namespace.default.memo(({
|
|
|
37444
37472
|
const showOffline = Boolean(isStreamStale);
|
|
37445
37473
|
const lastSeenText = lastSeenLabel || "Unknown";
|
|
37446
37474
|
const workspaceDisplayName = displayName || workspace.displayName || workspace.workspace_name;
|
|
37447
|
-
const videoGridMetricValue = getVideoGridMetricValue(workspace);
|
|
37475
|
+
const videoGridMetricValue = getVideoGridMetricValue(workspace, effectiveLegend);
|
|
37448
37476
|
const videoGridDisplayValue = getVideoGridDisplayValue(workspace, effectiveLegend, displayMinuteBucket);
|
|
37449
37477
|
const videoGridColorState = getVideoGridColorState(workspace, effectiveLegend);
|
|
37450
37478
|
const isRecentFlowCard = isVideoGridRecentFlowEnabled(workspace);
|
|
37479
|
+
const isHighEfficiencyOverride = isHighEfficiencyRedFlowOverride(workspace, effectiveLegend);
|
|
37451
37480
|
const hasDisplayMetric = typeof videoGridDisplayValue === "number" && Number.isFinite(videoGridDisplayValue);
|
|
37452
37481
|
const hasBarMetric = typeof videoGridMetricValue === "number" && Number.isFinite(videoGridMetricValue);
|
|
37453
37482
|
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
37454
|
-
const badgeTitle = hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
37483
|
+
const badgeTitle = isHighEfficiencyOverride ? `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%` : hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
37455
37484
|
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
37456
37485
|
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
37457
37486
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
@@ -43288,6 +43317,21 @@ var parseCycleTime = (value) => {
|
|
|
43288
43317
|
var extractCycleTimeSeconds = (clip) => {
|
|
43289
43318
|
return parseCycleTime(clip?.cycleTimeSeconds) ?? parseCycleTime(clip?.cycle_time_seconds) ?? parseCycleTime(clip?.duration) ?? parseCycleTime(clip?.original_task_metadata?.cycle_time) ?? null;
|
|
43290
43319
|
};
|
|
43320
|
+
var formatDurationLabel = (seconds) => {
|
|
43321
|
+
if (typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) {
|
|
43322
|
+
return null;
|
|
43323
|
+
}
|
|
43324
|
+
const roundedSeconds = Math.round(seconds);
|
|
43325
|
+
if (roundedSeconds < 60) {
|
|
43326
|
+
return `${roundedSeconds}s`;
|
|
43327
|
+
}
|
|
43328
|
+
const minutes = Math.floor(roundedSeconds / 60);
|
|
43329
|
+
const remainingSeconds = roundedSeconds % 60;
|
|
43330
|
+
if (minutes < 10) {
|
|
43331
|
+
return remainingSeconds > 0 ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
|
|
43332
|
+
}
|
|
43333
|
+
return `${Math.round(roundedSeconds / 60)} min`;
|
|
43334
|
+
};
|
|
43291
43335
|
var getSeverityIcon = (severity, categoryId, cycleTimeSeconds, targetCycleTime, clipId) => {
|
|
43292
43336
|
if (categoryId === "idle_time" || categoryId === "low_value" || categoryId === "longest-idles") {
|
|
43293
43337
|
return null;
|
|
@@ -43363,7 +43407,9 @@ var FileManagerFilters = ({
|
|
|
43363
43407
|
idleTimeVlmEnabled = false,
|
|
43364
43408
|
showPercentileCycleFilters = true,
|
|
43365
43409
|
prefetchedClipMetadata,
|
|
43366
|
-
activeCategoryLoading
|
|
43410
|
+
activeCategoryLoading,
|
|
43411
|
+
idleClipSort = "latest",
|
|
43412
|
+
onIdleClipSortChange
|
|
43367
43413
|
}) => {
|
|
43368
43414
|
const [expandedNodes, setExpandedNodes] = React144.useState(/* @__PURE__ */ new Set());
|
|
43369
43415
|
const [startTime, setStartTime] = React144.useState("");
|
|
@@ -43386,6 +43432,7 @@ var FileManagerFilters = ({
|
|
|
43386
43432
|
const [localClipClassifications, setLocalClipClassifications] = React144.useState({});
|
|
43387
43433
|
const clipMetadataRef = React144.useRef({});
|
|
43388
43434
|
const inFlightMetadataRequestsRef = React144.useRef(/* @__PURE__ */ new Set());
|
|
43435
|
+
const previousIdleClipSortRef = React144.useRef(idleClipSort);
|
|
43389
43436
|
const mergedClipClassifications = React144.useMemo(() => ({
|
|
43390
43437
|
...clipClassifications || {},
|
|
43391
43438
|
...localClipClassifications
|
|
@@ -43393,6 +43440,36 @@ var FileManagerFilters = ({
|
|
|
43393
43440
|
React144.useEffect(() => {
|
|
43394
43441
|
clipMetadataRef.current = clipMetadata;
|
|
43395
43442
|
}, [clipMetadata]);
|
|
43443
|
+
React144.useEffect(() => {
|
|
43444
|
+
if (previousIdleClipSortRef.current === idleClipSort) {
|
|
43445
|
+
return;
|
|
43446
|
+
}
|
|
43447
|
+
previousIdleClipSortRef.current = idleClipSort;
|
|
43448
|
+
setClipMetadata((prev) => {
|
|
43449
|
+
if (!prev.idle_time) {
|
|
43450
|
+
return prev;
|
|
43451
|
+
}
|
|
43452
|
+
const next = { ...prev };
|
|
43453
|
+
delete next.idle_time;
|
|
43454
|
+
return next;
|
|
43455
|
+
});
|
|
43456
|
+
setCategoryPages((prev) => {
|
|
43457
|
+
if (prev.idle_time === void 0) {
|
|
43458
|
+
return prev;
|
|
43459
|
+
}
|
|
43460
|
+
const next = { ...prev };
|
|
43461
|
+
delete next.idle_time;
|
|
43462
|
+
return next;
|
|
43463
|
+
});
|
|
43464
|
+
setCategoryHasMore((prev) => {
|
|
43465
|
+
if (prev.idle_time === void 0) {
|
|
43466
|
+
return prev;
|
|
43467
|
+
}
|
|
43468
|
+
const next = { ...prev };
|
|
43469
|
+
delete next.idle_time;
|
|
43470
|
+
return next;
|
|
43471
|
+
});
|
|
43472
|
+
}, [idleClipSort]);
|
|
43396
43473
|
const isCategoryExternallyManaged = React144.useCallback((categoryId) => {
|
|
43397
43474
|
if (!categoryId) {
|
|
43398
43475
|
return false;
|
|
@@ -43551,6 +43628,7 @@ var FileManagerFilters = ({
|
|
|
43551
43628
|
return null;
|
|
43552
43629
|
}
|
|
43553
43630
|
}, [supabase]);
|
|
43631
|
+
const getMetadataLoadingKey = React144.useCallback((categoryId, page) => `${categoryId}-${page}-${categoryId === "idle_time" ? idleClipSort : "latest"}`, [idleClipSort]);
|
|
43554
43632
|
const fetchClipMetadataPage = React144.useCallback(async (categoryId, page = 1) => {
|
|
43555
43633
|
if (!workspaceId || !date || shift === void 0) {
|
|
43556
43634
|
throw new Error("Missing required params for clip metadata fetch");
|
|
@@ -43570,7 +43648,8 @@ var FileManagerFilters = ({
|
|
|
43570
43648
|
limit: CLIP_METADATA_PAGE_SIZE,
|
|
43571
43649
|
knownTotal: typeof counts?.[categoryId] === "number" ? counts[categoryId] : null,
|
|
43572
43650
|
snapshotDateTime,
|
|
43573
|
-
snapshotClipId
|
|
43651
|
+
snapshotClipId,
|
|
43652
|
+
sort: categoryId === "idle_time" ? idleClipSort : "latest"
|
|
43574
43653
|
}),
|
|
43575
43654
|
redirectReason: "session_expired"
|
|
43576
43655
|
});
|
|
@@ -43578,7 +43657,7 @@ var FileManagerFilters = ({
|
|
|
43578
43657
|
throw new Error(`API error: ${response.status}`);
|
|
43579
43658
|
}
|
|
43580
43659
|
return response.json();
|
|
43581
|
-
}, [workspaceId, date, shift, counts, snapshotDateTime, snapshotClipId, supabase]);
|
|
43660
|
+
}, [workspaceId, date, shift, counts, snapshotDateTime, snapshotClipId, idleClipSort, supabase]);
|
|
43582
43661
|
const seedIdleClassifications = React144.useCallback(async (clips) => {
|
|
43583
43662
|
if (!idleTimeVlmEnabled || clips.length === 0) {
|
|
43584
43663
|
return;
|
|
@@ -43634,7 +43713,7 @@ var FileManagerFilters = ({
|
|
|
43634
43713
|
console.warn("[FileManager] Missing required params for clip metadata fetch");
|
|
43635
43714
|
return;
|
|
43636
43715
|
}
|
|
43637
|
-
const loadingKey =
|
|
43716
|
+
const loadingKey = getMetadataLoadingKey(categoryId, page);
|
|
43638
43717
|
if (inFlightMetadataRequestsRef.current.has(loadingKey)) {
|
|
43639
43718
|
return;
|
|
43640
43719
|
}
|
|
@@ -43662,7 +43741,7 @@ var FileManagerFilters = ({
|
|
|
43662
43741
|
return newSet;
|
|
43663
43742
|
});
|
|
43664
43743
|
}
|
|
43665
|
-
}, [workspaceId, date, shift, fetchClipMetadataPage, idleTimeVlmEnabled, seedIdleClassifications]);
|
|
43744
|
+
}, [workspaceId, date, shift, fetchClipMetadataPage, idleTimeVlmEnabled, seedIdleClassifications, getMetadataLoadingKey]);
|
|
43666
43745
|
const ensureAllIdleTimeClipMetadataLoaded = React144.useCallback(async () => {
|
|
43667
43746
|
if (!workspaceId || !date || shift === void 0) {
|
|
43668
43747
|
return;
|
|
@@ -44036,15 +44115,17 @@ var FileManagerFilters = ({
|
|
|
44036
44115
|
const colorClasses = getColorClasses(category.color);
|
|
44037
44116
|
const clipNodes = filteredClips.map((clip, index) => {
|
|
44038
44117
|
const cycleTime = extractCycleTimeSeconds(clip);
|
|
44118
|
+
const idleDuration = category.id === "idle_time" ? clip.idle_duration_seconds ?? clip.duration : null;
|
|
44119
|
+
const idleDurationLabel = formatDurationLabel(idleDuration);
|
|
44039
44120
|
const baseTimeLabel = formatClipExplorerTimeLabel({
|
|
44040
44121
|
categoryId: category.id,
|
|
44041
44122
|
clipTimestamp: clip.clip_timestamp,
|
|
44042
44123
|
timezone,
|
|
44043
|
-
durationSeconds: clip.duration,
|
|
44124
|
+
durationSeconds: idleDuration ?? clip.duration,
|
|
44044
44125
|
idleStartTime: clip.idle_start_time,
|
|
44045
44126
|
idleEndTime: clip.idle_end_time
|
|
44046
44127
|
});
|
|
44047
|
-
const displayLabel = `${baseTimeLabel}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
|
|
44128
|
+
const displayLabel = `${baseTimeLabel}${idleDurationLabel && category.id === "idle_time" ? ` - (${idleDurationLabel})` : ""}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
|
|
44048
44129
|
return {
|
|
44049
44130
|
id: clip.id,
|
|
44050
44131
|
label: displayLabel,
|
|
@@ -44058,7 +44139,7 @@ var FileManagerFilters = ({
|
|
|
44058
44139
|
clipPosition: index + 1,
|
|
44059
44140
|
// Store 1-based position
|
|
44060
44141
|
cycleTimeSeconds: cycleTime,
|
|
44061
|
-
duration: clip.duration,
|
|
44142
|
+
duration: idleDuration ?? clip.duration,
|
|
44062
44143
|
// Store duration for custom badge rendering
|
|
44063
44144
|
cycleItemCount: clip.cycle_item_count ?? null
|
|
44064
44145
|
};
|
|
@@ -44380,11 +44461,11 @@ var FileManagerFilters = ({
|
|
|
44380
44461
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
44381
44462
|
"Loading clips..."
|
|
44382
44463
|
] }) }),
|
|
44383
|
-
loadingCategories.has(
|
|
44464
|
+
loadingCategories.has(getMetadataLoadingKey(node.id, (categoryPages[node.id] || 0) + 1)) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center text-sm text-slate-500", children: [
|
|
44384
44465
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin mr-2 h-4 w-4 border-2 border-slate-300 border-t-blue-500 rounded-full" }),
|
|
44385
44466
|
"Loading more clips..."
|
|
44386
44467
|
] }) }),
|
|
44387
|
-
categoryHasMore[node.id] && !loadingCategories.has(
|
|
44468
|
+
categoryHasMore[node.id] && !loadingCategories.has(getMetadataLoadingKey(node.id, (categoryPages[node.id] || 0) + 1)) && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
44388
44469
|
"button",
|
|
44389
44470
|
{
|
|
44390
44471
|
onClick: (e) => {
|
|
@@ -44411,6 +44492,18 @@ var FileManagerFilters = ({
|
|
|
44411
44492
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-bold text-slate-900 tracking-tight", children: "Clips Explorer" }) })
|
|
44412
44493
|
] }),
|
|
44413
44494
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
44495
|
+
activeFilter === "idle_time" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
44496
|
+
"button",
|
|
44497
|
+
{
|
|
44498
|
+
onClick: () => {
|
|
44499
|
+
onIdleClipSortChange?.(idleClipSort === "latest" ? "idle_duration_desc" : "latest");
|
|
44500
|
+
},
|
|
44501
|
+
className: `p-2 rounded-xl transition-all duration-200 ${idleClipSort === "idle_duration_desc" ? "bg-orange-100 text-orange-600 hover:bg-orange-200 shadow-sm" : "bg-slate-100 text-slate-600 hover:bg-slate-200"}`,
|
|
44502
|
+
title: idleClipSort === "idle_duration_desc" ? "Sort by newest first" : "Sort by longest idle first",
|
|
44503
|
+
"aria-label": idleClipSort === "idle_duration_desc" ? "Sort idle clips by newest first" : "Sort idle clips by longest idle first",
|
|
44504
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownWideNarrow, { className: "h-5 w-5" })
|
|
44505
|
+
}
|
|
44506
|
+
),
|
|
44414
44507
|
activeFilter === "idle_time" && idleTimeVlmEnabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
44415
44508
|
"button",
|
|
44416
44509
|
{
|
|
@@ -44431,8 +44524,8 @@ var FileManagerFilters = ({
|
|
|
44431
44524
|
)
|
|
44432
44525
|
] })
|
|
44433
44526
|
] }),
|
|
44434
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-
|
|
44435
|
-
isTimeFilterActive && startTime && endTime && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center
|
|
44527
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
|
|
44528
|
+
isTimeFilterActive && startTime && endTime && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex w-fit items-center gap-2 rounded-full border border-blue-100 bg-blue-50/70 px-2.5 py-1 text-xs text-blue-700 shadow-sm", children: [
|
|
44436
44529
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
44437
44530
|
"Time: ",
|
|
44438
44531
|
getDisplayValue(startTime),
|
|
@@ -44448,13 +44541,13 @@ var FileManagerFilters = ({
|
|
|
44448
44541
|
setEndTime("");
|
|
44449
44542
|
setIsTimeFilterActive(false);
|
|
44450
44543
|
},
|
|
44451
|
-
className: "
|
|
44544
|
+
className: "rounded-full p-0.5 transition-colors hover:bg-blue-100",
|
|
44452
44545
|
title: "Clear time filter",
|
|
44453
44546
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" })
|
|
44454
44547
|
}
|
|
44455
44548
|
)
|
|
44456
44549
|
] }),
|
|
44457
|
-
idleLabelFilter && activeFilter === "idle_time" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center
|
|
44550
|
+
idleLabelFilter && activeFilter === "idle_time" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex w-fit items-center gap-2 rounded-full border border-purple-100 bg-purple-50/70 px-2.5 py-1 text-xs text-purple-700 shadow-sm", children: [
|
|
44458
44551
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
44459
44552
|
"Reason: ",
|
|
44460
44553
|
selectedIdleReasonOption?.displayName || idleLabelFilter.replace(/_/g, " ")
|
|
@@ -44466,11 +44559,27 @@ var FileManagerFilters = ({
|
|
|
44466
44559
|
e.stopPropagation();
|
|
44467
44560
|
setIdleLabelFilter(null);
|
|
44468
44561
|
},
|
|
44469
|
-
className: "
|
|
44562
|
+
className: "rounded-full p-0.5 transition-colors hover:bg-purple-100",
|
|
44470
44563
|
title: "Clear label filter",
|
|
44471
44564
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" })
|
|
44472
44565
|
}
|
|
44473
44566
|
)
|
|
44567
|
+
] }),
|
|
44568
|
+
activeFilter === "idle_time" && idleClipSort === "idle_duration_desc" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex w-fit items-center gap-2 rounded-full border border-orange-100 bg-orange-50/70 px-2.5 py-1 text-xs text-orange-700 shadow-sm", children: [
|
|
44569
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownWideNarrow, { className: "h-3.5 w-3.5" }),
|
|
44570
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Longest idle first" }),
|
|
44571
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
44572
|
+
"button",
|
|
44573
|
+
{
|
|
44574
|
+
onClick: (e) => {
|
|
44575
|
+
e.stopPropagation();
|
|
44576
|
+
onIdleClipSortChange?.("latest");
|
|
44577
|
+
},
|
|
44578
|
+
className: "rounded-full p-0.5 transition-colors hover:bg-orange-100",
|
|
44579
|
+
title: "Clear idle sort",
|
|
44580
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" })
|
|
44581
|
+
}
|
|
44582
|
+
)
|
|
44474
44583
|
] })
|
|
44475
44584
|
] })
|
|
44476
44585
|
] }),
|
|
@@ -45234,8 +45343,10 @@ var BottlenecksContent = ({
|
|
|
45234
45343
|
const [clipClassifications, setClipClassifications] = React144.useState({});
|
|
45235
45344
|
const [categoryMetadata, setCategoryMetadata] = React144.useState([]);
|
|
45236
45345
|
const [categoryMetadataCategoryId, setCategoryMetadataCategoryId] = React144.useState(null);
|
|
45346
|
+
const [categoryMetadataSort, setCategoryMetadataSort] = React144.useState(null);
|
|
45237
45347
|
const [currentMetadataIndex, setCurrentMetadataIndex] = React144.useState(0);
|
|
45238
45348
|
const [metadataCache, setMetadataCache] = React144.useState({});
|
|
45349
|
+
const [idleClipSort, setIdleClipSort] = React144.useState("latest");
|
|
45239
45350
|
const invalidateMetadataCache = React144.useCallback((categories) => {
|
|
45240
45351
|
setMetadataCache((prevCache) => {
|
|
45241
45352
|
if (!prevCache || Object.keys(prevCache).length === 0) {
|
|
@@ -45266,6 +45377,7 @@ var BottlenecksContent = ({
|
|
|
45266
45377
|
const [isFullscreen, setIsFullscreen] = React144.useState(false);
|
|
45267
45378
|
const categoryMetadataRef = React144.useRef([]);
|
|
45268
45379
|
const currentMetadataIndexRef = React144.useRef(0);
|
|
45380
|
+
const previousIdleClipSortRef = React144.useRef(idleClipSort);
|
|
45269
45381
|
const clearRetryTimeout = React144.useCallback(() => {
|
|
45270
45382
|
if (retryTimeoutRef.current) {
|
|
45271
45383
|
clearTimeout(retryTimeoutRef.current);
|
|
@@ -45712,9 +45824,13 @@ var BottlenecksContent = ({
|
|
|
45712
45824
|
}
|
|
45713
45825
|
return ["fast-cycles", "slow-cycles", "longest-idles"].includes(categoryId);
|
|
45714
45826
|
}, [isFastSlowClipFiltersEnabled]);
|
|
45827
|
+
const shouldUseMetadataNavigation = React144.useCallback((categoryId) => {
|
|
45828
|
+
return isPercentileCategory(categoryId) || categoryId === "idle_time" && idleClipSort === "idle_duration_desc";
|
|
45829
|
+
}, [idleClipSort, isPercentileCategory]);
|
|
45715
45830
|
const getMetadataCacheKey = React144.useCallback((categoryId) => {
|
|
45716
|
-
|
|
45717
|
-
|
|
45831
|
+
const sortKey = categoryId === "idle_time" ? idleClipSort : "latest";
|
|
45832
|
+
return `${categoryId}-${effectiveDateString}-${effectiveShiftId}-${snapshotDateTime ?? "nosnap"}-${snapshotClipId ?? "nosnap"}-${sortKey}`;
|
|
45833
|
+
}, [effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, idleClipSort]);
|
|
45718
45834
|
const setVisibleCategoryMetadata = React144.useCallback((categoryId, clips) => {
|
|
45719
45835
|
if (activeFilterRef.current !== categoryId) {
|
|
45720
45836
|
return false;
|
|
@@ -45722,8 +45838,9 @@ var BottlenecksContent = ({
|
|
|
45722
45838
|
categoryMetadataRef.current = clips;
|
|
45723
45839
|
setCategoryMetadata(clips);
|
|
45724
45840
|
setCategoryMetadataCategoryId(clips.length > 0 ? categoryId : null);
|
|
45841
|
+
setCategoryMetadataSort(clips.length > 0 ? categoryId === "idle_time" ? idleClipSort : "latest" : null);
|
|
45725
45842
|
return true;
|
|
45726
|
-
}, []);
|
|
45843
|
+
}, [idleClipSort]);
|
|
45727
45844
|
const applyMetadataSnapshot = React144.useCallback((categoryId, clips, total) => {
|
|
45728
45845
|
if (!clips || clips.length === 0) {
|
|
45729
45846
|
return;
|
|
@@ -45734,11 +45851,11 @@ var BottlenecksContent = ({
|
|
|
45734
45851
|
[cacheKey]: clips
|
|
45735
45852
|
}));
|
|
45736
45853
|
setVisibleCategoryMetadata(categoryId, clips);
|
|
45737
|
-
if (!
|
|
45854
|
+
if (!shouldUseMetadataNavigation(categoryId) && typeof total === "number") {
|
|
45738
45855
|
currentTotalRef.current = total;
|
|
45739
45856
|
setCurrentTotal(total);
|
|
45740
45857
|
}
|
|
45741
|
-
}, [getMetadataCacheKey,
|
|
45858
|
+
}, [getMetadataCacheKey, shouldUseMetadataNavigation, setVisibleCategoryMetadata]);
|
|
45742
45859
|
const getClipTypesForPercentileCategory = React144.useCallback((categoryId) => {
|
|
45743
45860
|
switch (categoryId) {
|
|
45744
45861
|
case "fast-cycles":
|
|
@@ -45764,6 +45881,7 @@ var BottlenecksContent = ({
|
|
|
45764
45881
|
}
|
|
45765
45882
|
setCategoryMetadata([]);
|
|
45766
45883
|
setCategoryMetadataCategoryId(null);
|
|
45884
|
+
setCategoryMetadataSort(null);
|
|
45767
45885
|
categoryMetadataRef.current = [];
|
|
45768
45886
|
updateActiveFilter(fallbackFilter);
|
|
45769
45887
|
}, [isFastSlowClipFiltersEnabled, activeFilter, dynamicCounts, clipTypes, updateActiveFilter]);
|
|
@@ -45811,6 +45929,7 @@ var BottlenecksContent = ({
|
|
|
45811
45929
|
if (!isFastSlowClipFiltersEnabled && (categoryId === "fast-cycles" || categoryId === "slow-cycles")) {
|
|
45812
45930
|
setCategoryMetadata([]);
|
|
45813
45931
|
setCategoryMetadataCategoryId(null);
|
|
45932
|
+
setCategoryMetadataSort(null);
|
|
45814
45933
|
categoryMetadataRef.current = [];
|
|
45815
45934
|
return;
|
|
45816
45935
|
}
|
|
@@ -45881,7 +46000,8 @@ var BottlenecksContent = ({
|
|
|
45881
46000
|
limit: 100,
|
|
45882
46001
|
knownTotal: mergedCounts[categoryId] ?? null,
|
|
45883
46002
|
snapshotDateTime,
|
|
45884
|
-
snapshotClipId
|
|
46003
|
+
snapshotClipId,
|
|
46004
|
+
sort: categoryId === "idle_time" ? idleClipSort : "latest"
|
|
45885
46005
|
}),
|
|
45886
46006
|
redirectReason: "session_expired"
|
|
45887
46007
|
});
|
|
@@ -45960,6 +46080,7 @@ var BottlenecksContent = ({
|
|
|
45960
46080
|
if (activeFilterRef.current === categoryId) {
|
|
45961
46081
|
setCategoryMetadata([]);
|
|
45962
46082
|
setCategoryMetadataCategoryId(null);
|
|
46083
|
+
setCategoryMetadataSort(null);
|
|
45963
46084
|
categoryMetadataRef.current = [];
|
|
45964
46085
|
}
|
|
45965
46086
|
}
|
|
@@ -45968,7 +46089,26 @@ var BottlenecksContent = ({
|
|
|
45968
46089
|
} finally {
|
|
45969
46090
|
setIsCategoryLoading(false);
|
|
45970
46091
|
}
|
|
45971
|
-
}, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, supabase, setVisibleCategoryMetadata]);
|
|
46092
|
+
}, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, idleClipSort, supabase, setVisibleCategoryMetadata]);
|
|
46093
|
+
React144.useEffect(() => {
|
|
46094
|
+
if (previousIdleClipSortRef.current === idleClipSort) {
|
|
46095
|
+
return;
|
|
46096
|
+
}
|
|
46097
|
+
previousIdleClipSortRef.current = idleClipSort;
|
|
46098
|
+
if (activeFilterRef.current !== "idle_time") {
|
|
46099
|
+
return;
|
|
46100
|
+
}
|
|
46101
|
+
setCategoryMetadata([]);
|
|
46102
|
+
setCategoryMetadataCategoryId(null);
|
|
46103
|
+
setCategoryMetadataSort(null);
|
|
46104
|
+
categoryMetadataRef.current = [];
|
|
46105
|
+
setCurrentMetadataIndex(0);
|
|
46106
|
+
currentMetadataIndexRef.current = 0;
|
|
46107
|
+
setCurrentPosition(0);
|
|
46108
|
+
currentPositionRef.current = 0;
|
|
46109
|
+
setIsCategoryLoading(true);
|
|
46110
|
+
void loadCategoryMetadata("idle_time", true, true);
|
|
46111
|
+
}, [idleClipSort, loadCategoryMetadata]);
|
|
45972
46112
|
React144.useEffect(() => {
|
|
45973
46113
|
if (previousFilterRef.current !== activeFilter) {
|
|
45974
46114
|
console.log(`Filter changed from ${previousFilterRef.current} to ${activeFilter} - resetting to first video`);
|
|
@@ -45979,6 +46119,7 @@ var BottlenecksContent = ({
|
|
|
45979
46119
|
loadingCategoryRef.current = null;
|
|
45980
46120
|
setCategoryMetadata([]);
|
|
45981
46121
|
setCategoryMetadataCategoryId(null);
|
|
46122
|
+
setCategoryMetadataSort(null);
|
|
45982
46123
|
setCurrentMetadataIndex(0);
|
|
45983
46124
|
categoryMetadataRef.current = [];
|
|
45984
46125
|
currentMetadataIndexRef.current = 0;
|
|
@@ -46077,7 +46218,7 @@ var BottlenecksContent = ({
|
|
|
46077
46218
|
}
|
|
46078
46219
|
if (metadataArray.length === 0) {
|
|
46079
46220
|
console.warn(`[BottlenecksContent] No metadata available for category ${categoryId} after refresh`);
|
|
46080
|
-
if (!
|
|
46221
|
+
if (!shouldUseMetadataNavigation(categoryId)) {
|
|
46081
46222
|
const resolvedPosition = typeof position === "number" ? position : 1;
|
|
46082
46223
|
currentPositionRef.current = resolvedPosition;
|
|
46083
46224
|
setCurrentPosition(resolvedPosition);
|
|
@@ -46090,7 +46231,7 @@ var BottlenecksContent = ({
|
|
|
46090
46231
|
const clickedClipIndex = metadataArray.findIndex((clip) => clip.clipId === clipId);
|
|
46091
46232
|
if (clickedClipIndex === -1) {
|
|
46092
46233
|
console.warn(`[BottlenecksContent] Clip ${clipId} not found after metadata refresh`);
|
|
46093
|
-
if (!
|
|
46234
|
+
if (!shouldUseMetadataNavigation(categoryId)) {
|
|
46094
46235
|
const resolvedPosition = typeof position === "number" ? position : 1;
|
|
46095
46236
|
currentPositionRef.current = resolvedPosition;
|
|
46096
46237
|
setCurrentPosition(resolvedPosition);
|
|
@@ -46102,7 +46243,7 @@ var BottlenecksContent = ({
|
|
|
46102
46243
|
}
|
|
46103
46244
|
setCurrentMetadataIndex(clickedClipIndex);
|
|
46104
46245
|
currentMetadataIndexRef.current = clickedClipIndex;
|
|
46105
|
-
if (!
|
|
46246
|
+
if (!shouldUseMetadataNavigation(categoryId)) {
|
|
46106
46247
|
const position2 = clickedClipIndex + 1;
|
|
46107
46248
|
currentPositionRef.current = position2;
|
|
46108
46249
|
setCurrentPosition(position2);
|
|
@@ -46132,7 +46273,7 @@ var BottlenecksContent = ({
|
|
|
46132
46273
|
clearLoadingState();
|
|
46133
46274
|
}
|
|
46134
46275
|
}
|
|
46135
|
-
}, [workspaceId, s3ClipsService, updateActiveFilter, clearLoadingState, clearRetryTimeout, loadCategoryMetadata, applyMetadataSnapshot, mergedCounts,
|
|
46276
|
+
}, [workspaceId, s3ClipsService, updateActiveFilter, clearLoadingState, clearRetryTimeout, loadCategoryMetadata, applyMetadataSnapshot, mergedCounts, shouldUseMetadataNavigation]);
|
|
46136
46277
|
const restartCurrentClipPlayback = React144.useCallback(() => {
|
|
46137
46278
|
if (!currentClipId) {
|
|
46138
46279
|
return;
|
|
@@ -46153,7 +46294,7 @@ var BottlenecksContent = ({
|
|
|
46153
46294
|
return;
|
|
46154
46295
|
}
|
|
46155
46296
|
const activeCategory = activeFilterRef.current;
|
|
46156
|
-
if (!activeCategory || activeCategory === "all" ||
|
|
46297
|
+
if (!activeCategory || activeCategory === "all" || shouldUseMetadataNavigation(activeCategory)) {
|
|
46157
46298
|
return;
|
|
46158
46299
|
}
|
|
46159
46300
|
let cancelled = false;
|
|
@@ -46186,7 +46327,7 @@ var BottlenecksContent = ({
|
|
|
46186
46327
|
}, [
|
|
46187
46328
|
newClipsNotification,
|
|
46188
46329
|
s3ClipsService,
|
|
46189
|
-
|
|
46330
|
+
shouldUseMetadataNavigation,
|
|
46190
46331
|
currentClipId,
|
|
46191
46332
|
invalidateMetadataCache,
|
|
46192
46333
|
loadAndPlayClipById,
|
|
@@ -46238,7 +46379,7 @@ var BottlenecksContent = ({
|
|
|
46238
46379
|
}
|
|
46239
46380
|
}
|
|
46240
46381
|
try {
|
|
46241
|
-
if (!
|
|
46382
|
+
if (!shouldUseMetadataNavigation(currentFilter)) {
|
|
46242
46383
|
if (!s3ClipsService || !workspaceId || !currentClipId) {
|
|
46243
46384
|
throw new Error("S3 clips service not available");
|
|
46244
46385
|
}
|
|
@@ -46338,7 +46479,7 @@ var BottlenecksContent = ({
|
|
|
46338
46479
|
} else {
|
|
46339
46480
|
const firstClipMeta = metadataArray[0];
|
|
46340
46481
|
if (firstClipMeta?.clipId && firstClipMeta.clipId !== currentClipId) {
|
|
46341
|
-
console.log(`[handleNext] Reached end of ${currentFilter}, looping back to
|
|
46482
|
+
console.log(`[handleNext] Reached end of ${currentFilter}, looping back to first metadata clip ${firstClipMeta.clipId}`);
|
|
46342
46483
|
await loadAndPlayClipById(firstClipMeta.clipId, currentFilter, 1, {
|
|
46343
46484
|
clips: metadataArray,
|
|
46344
46485
|
total: metadataArray.length
|
|
@@ -46364,7 +46505,7 @@ var BottlenecksContent = ({
|
|
|
46364
46505
|
});
|
|
46365
46506
|
clearLoadingState();
|
|
46366
46507
|
}
|
|
46367
|
-
}, [clearLoadingState, clearRetryTimeout, s3ClipsService, loadCategoryMetadata, loadAndPlayClipById,
|
|
46508
|
+
}, [clearLoadingState, clearRetryTimeout, s3ClipsService, loadCategoryMetadata, loadAndPlayClipById, shouldUseMetadataNavigation, workspaceId, currentClipId, effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, mergedCounts]);
|
|
46368
46509
|
const handlePrevious = React144.useCallback(async () => {
|
|
46369
46510
|
if (!isMountedRef.current || navigationLockRef.current) return;
|
|
46370
46511
|
const currentFilter = activeFilterRef.current;
|
|
@@ -46383,7 +46524,7 @@ var BottlenecksContent = ({
|
|
|
46383
46524
|
}
|
|
46384
46525
|
}
|
|
46385
46526
|
try {
|
|
46386
|
-
if (!
|
|
46527
|
+
if (!shouldUseMetadataNavigation(currentFilter)) {
|
|
46387
46528
|
if (!s3ClipsService || !workspaceId || !currentClipId) {
|
|
46388
46529
|
throw new Error("S3 clips service not available");
|
|
46389
46530
|
}
|
|
@@ -46468,7 +46609,7 @@ var BottlenecksContent = ({
|
|
|
46468
46609
|
});
|
|
46469
46610
|
clearLoadingState();
|
|
46470
46611
|
}
|
|
46471
|
-
}, [clearLoadingState, clearRetryTimeout, s3ClipsService, loadCategoryMetadata,
|
|
46612
|
+
}, [clearLoadingState, clearRetryTimeout, s3ClipsService, loadCategoryMetadata, shouldUseMetadataNavigation, workspaceId, currentClipId, effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, mergedCounts]);
|
|
46472
46613
|
const currentVideo = React144.useMemo(() => {
|
|
46473
46614
|
if (!filteredVideos || filteredVideos.length === 0 || currentIndex >= filteredVideos.length) {
|
|
46474
46615
|
return null;
|
|
@@ -46535,22 +46676,22 @@ var BottlenecksContent = ({
|
|
|
46535
46676
|
}
|
|
46536
46677
|
}, [currentVideo?.id, isShareLoading, supabase, workspaceId, workspaceName]);
|
|
46537
46678
|
React144.useMemo(() => {
|
|
46538
|
-
if (
|
|
46679
|
+
if (shouldUseMetadataNavigation(activeFilter)) {
|
|
46539
46680
|
return categoryMetadata.length;
|
|
46540
46681
|
}
|
|
46541
46682
|
return currentTotal || mergedCounts[activeFilter] || 0;
|
|
46542
|
-
}, [activeFilter, categoryMetadata.length, currentTotal, mergedCounts,
|
|
46683
|
+
}, [activeFilter, categoryMetadata.length, currentTotal, mergedCounts, shouldUseMetadataNavigation]);
|
|
46543
46684
|
React144.useMemo(() => {
|
|
46544
|
-
if (
|
|
46685
|
+
if (shouldUseMetadataNavigation(activeFilter)) {
|
|
46545
46686
|
return categoryMetadata.length > 0 ? currentMetadataIndex + 1 : 0;
|
|
46546
46687
|
}
|
|
46547
46688
|
return currentPosition;
|
|
46548
|
-
}, [activeFilter, categoryMetadata.length, currentMetadataIndex, currentPosition,
|
|
46549
|
-
const prefetchedExplorerMetadata = React144.useMemo(() => buildPrefetchedExplorerMetadata(
|
|
46689
|
+
}, [activeFilter, categoryMetadata.length, currentMetadataIndex, currentPosition, shouldUseMetadataNavigation]);
|
|
46690
|
+
const prefetchedExplorerMetadata = React144.useMemo(() => activeFilter === "idle_time" && categoryMetadataSort !== idleClipSort ? void 0 : buildPrefetchedExplorerMetadata(
|
|
46550
46691
|
activeFilter,
|
|
46551
46692
|
categoryMetadataCategoryId,
|
|
46552
46693
|
categoryMetadata
|
|
46553
|
-
), [activeFilter, categoryMetadata, categoryMetadataCategoryId]);
|
|
46694
|
+
), [activeFilter, categoryMetadata, categoryMetadataCategoryId, categoryMetadataSort, idleClipSort]);
|
|
46554
46695
|
const classificationClipIds = React144.useMemo(() => {
|
|
46555
46696
|
if (!idleTimeVlmEnabled) {
|
|
46556
46697
|
return [];
|
|
@@ -47299,7 +47440,12 @@ var BottlenecksContent = ({
|
|
|
47299
47440
|
showPercentileCycleFilters: isFastSlowClipFiltersEnabled,
|
|
47300
47441
|
prefetchedClipMetadata: prefetchedExplorerMetadata,
|
|
47301
47442
|
activeCategoryLoading: isCategoryLoading,
|
|
47443
|
+
idleClipSort,
|
|
47444
|
+
onIdleClipSortChange: setIdleClipSort,
|
|
47302
47445
|
onFilterChange: (filterId) => {
|
|
47446
|
+
if (filterId !== "idle_time") {
|
|
47447
|
+
setIdleClipSort("latest");
|
|
47448
|
+
}
|
|
47303
47449
|
updateActiveFilter(filterId);
|
|
47304
47450
|
const category = categoriesToShow.find((cat) => cat.type === filterId);
|
|
47305
47451
|
if (category) {
|
|
@@ -49222,6 +49368,11 @@ var LineHistoryCalendar = ({
|
|
|
49222
49368
|
return calendar;
|
|
49223
49369
|
}, [data, month, year, configuredTimezone]);
|
|
49224
49370
|
const hasRealData = (shift) => {
|
|
49371
|
+
if (isUptimeMode) {
|
|
49372
|
+
if (shift.hasData === true) return true;
|
|
49373
|
+
const efficiency = Number(shift.avg_efficiency);
|
|
49374
|
+
return shift.total_workspaces > 0 || shift.underperforming_workspaces > 0 || (shift.output || 0) > 0 || (shift.available_time_seconds || 0) > 0 || (shift.active_time_seconds || 0) > 0 || (shift.idle_time_seconds || 0) > 0 || Number.isFinite(efficiency) && efficiency > 0;
|
|
49375
|
+
}
|
|
49225
49376
|
if (shift.hasData !== void 0) return shift.hasData;
|
|
49226
49377
|
return shift.total_workspaces > 0 || shift.avg_efficiency > 0 || shift.underperforming_workspaces > 0;
|
|
49227
49378
|
};
|
|
@@ -49854,13 +50005,18 @@ var LineMonthlyHistory = ({
|
|
|
49854
50005
|
enabled: !!lineId && idleTimeVlmEnabled
|
|
49855
50006
|
});
|
|
49856
50007
|
const hasRealData = (shift) => {
|
|
50008
|
+
if (isUptimeMode) {
|
|
50009
|
+
if (shift.hasData === true) return true;
|
|
50010
|
+
const efficiency = Number(shift.avg_efficiency);
|
|
50011
|
+
return shift.total_workspaces > 0 || shift.underperforming_workspaces > 0 || (shift.output || 0) > 0 || (shift.idealOutput || 0) > 0 || (shift.idle_time_seconds || 0) > 0 || (shift.active_time_seconds || 0) > 0 || (shift.available_time_seconds || 0) > 0 || Number.isFinite(efficiency) && efficiency > 0;
|
|
50012
|
+
}
|
|
49857
50013
|
if (shift.hasData !== void 0) return shift.hasData;
|
|
49858
50014
|
return shift.avg_efficiency > 0 || shift.underperforming_workspaces > 0 || shift.total_workspaces > 0 || (shift.output || 0) > 0 || (shift.idealOutput || 0) > 0 || (shift.idle_time_seconds || 0) > 0 || (shift.active_time_seconds || 0) > 0 || (shift.available_time_seconds || 0) > 0;
|
|
49859
50015
|
};
|
|
49860
50016
|
const averages = (analysisMonthlyData || []).reduce(
|
|
49861
50017
|
(acc, day) => {
|
|
49862
50018
|
const shiftData = getShiftData2(day, selectedShiftId);
|
|
49863
|
-
if (!shiftData || shiftData
|
|
50019
|
+
if (!shiftData || !isValidAggregateEfficiency(isUptimeMode ? "uptime" : "output", shiftData.avg_efficiency)) {
|
|
49864
50020
|
return acc;
|
|
49865
50021
|
}
|
|
49866
50022
|
return {
|
|
@@ -49889,7 +50045,9 @@ var LineMonthlyHistory = ({
|
|
|
49889
50045
|
const avgOutput = outputAverages.count > 0 ? outputAverages.output / outputAverages.count : 0;
|
|
49890
50046
|
const uptimeSummary = React144.useMemo(() => {
|
|
49891
50047
|
if (!isUptimeMode) return null;
|
|
49892
|
-
const validDays = (analysisMonthlyData || []).map((day) => getShiftData2(day, selectedShiftId)).filter(
|
|
50048
|
+
const validDays = (analysisMonthlyData || []).map((day) => getShiftData2(day, selectedShiftId)).filter(
|
|
50049
|
+
(shiftData) => shiftData && hasRealData(shiftData) && isValidAggregateEfficiency("uptime", shiftData.avg_efficiency)
|
|
50050
|
+
).map((shiftData) => ({ shiftData, totals: getUptimeTotals(shiftData) }));
|
|
49893
50051
|
if (!validDays.length) {
|
|
49894
50052
|
return { avgUtilization: 0, avgIdleTime: 0, avgDailyStoppages: 0 };
|
|
49895
50053
|
}
|
|
@@ -50037,7 +50195,9 @@ var LineMonthlyHistory = ({
|
|
|
50037
50195
|
}, [chartData.yAxisMax, chartData.lastSetTarget]);
|
|
50038
50196
|
const pieChartData = React144.useMemo(() => {
|
|
50039
50197
|
if (!isUptimeMode) return [];
|
|
50040
|
-
const validShifts = (analysisMonthlyData || []).map((day) => getShiftData2(day, selectedShiftId)).filter(
|
|
50198
|
+
const validShifts = (analysisMonthlyData || []).map((day) => getShiftData2(day, selectedShiftId)).filter(
|
|
50199
|
+
(shift) => shift && hasRealData(shift) && isValidAggregateEfficiency("uptime", shift.avg_efficiency)
|
|
50200
|
+
);
|
|
50041
50201
|
if (!validShifts.length) return [];
|
|
50042
50202
|
const efficiencyValues = validShifts.map((shift) => Number.isFinite(shift.avg_efficiency) ? Number(shift.avg_efficiency) : null).filter((value) => value !== null);
|
|
50043
50203
|
if (!efficiencyValues.length) return [];
|
|
@@ -50647,7 +50807,9 @@ var LineMonthlyPdfGenerator = ({
|
|
|
50647
50807
|
const productiveSeconds = activeSecondsRaw > 0 ? Math.min(activeSecondsRaw, availableSeconds) : Math.max(availableSeconds - idleSeconds, 0);
|
|
50648
50808
|
return { availableSeconds, productiveSeconds, idleSeconds };
|
|
50649
50809
|
};
|
|
50650
|
-
const validShifts = validDays.map((day) => getLineShiftData2(day, selectedShiftId)).filter(
|
|
50810
|
+
const validShifts = validDays.map((day) => getLineShiftData2(day, selectedShiftId)).filter(
|
|
50811
|
+
(shift) => hasShiftData(shift) && isValidAggregateEfficiency(isUptimeMode ? "uptime" : "output", shift.avg_efficiency)
|
|
50812
|
+
);
|
|
50651
50813
|
const monthlyMetrics = validShifts.length > 0 ? isUptimeMode ? (() => {
|
|
50652
50814
|
let utilizationSum = 0;
|
|
50653
50815
|
let idleTimeSum = 0;
|
|
@@ -52632,7 +52794,10 @@ var WorkspaceMonthlyHistory = ({
|
|
|
52632
52794
|
return ticks.filter((v) => v >= 0 && v <= max * 1.05).sort((a, b) => a - b);
|
|
52633
52795
|
}, [chartData.yAxisMax, chartData.lastSetTarget, isUptimeMode]);
|
|
52634
52796
|
const pieChartData = React144.useMemo(() => {
|
|
52635
|
-
const
|
|
52797
|
+
const aggregateMode = isUptimeMode ? "uptime" : "output";
|
|
52798
|
+
const validShifts = analysisMonthlyData.map((d) => getShiftData(d, selectedShiftId)).filter(
|
|
52799
|
+
(shift) => shift && hasRealData(shift) && isValidAggregateEfficiency(aggregateMode, shift.efficiency)
|
|
52800
|
+
);
|
|
52636
52801
|
if (validShifts.length === 0) return [];
|
|
52637
52802
|
const efficiencyValues = validShifts.map((shift) => Number.isFinite(shift.efficiency) ? Number(shift.efficiency) : null).filter((value) => value !== null);
|
|
52638
52803
|
if (!efficiencyValues.length) return [];
|
|
@@ -52643,10 +52808,10 @@ var WorkspaceMonthlyHistory = ({
|
|
|
52643
52808
|
{ name: "Productive", value: productivePercent },
|
|
52644
52809
|
{ name: "Idle", value: idlePercent }
|
|
52645
52810
|
];
|
|
52646
|
-
}, [analysisMonthlyData, selectedShiftId,
|
|
52811
|
+
}, [analysisMonthlyData, selectedShiftId, isUptimeMode]);
|
|
52647
52812
|
const metrics2 = React144.useMemo(() => {
|
|
52648
52813
|
const validShifts = analysisMonthlyData.map((d) => getShiftData(d, selectedShiftId)).filter(hasRealData);
|
|
52649
|
-
const filteredShifts = isUptimeMode ? validShifts
|
|
52814
|
+
const filteredShifts = isUptimeMode ? validShifts.filter((shift) => isValidAggregateEfficiency("uptime", shift.efficiency)) : validShifts.filter((shift) => isValidAggregateEfficiency("output", shift.efficiency));
|
|
52650
52815
|
if (filteredShifts.length === 0) return null;
|
|
52651
52816
|
const totalEfficiency = filteredShifts.reduce((sum, shift) => sum + (shift.efficiency || 0), 0);
|
|
52652
52817
|
const totalUtilization = filteredShifts.reduce(
|
|
@@ -53866,7 +54031,7 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
53866
54031
|
const shift = getShiftData(dayData, selectedShiftId);
|
|
53867
54032
|
return { dayData, shift };
|
|
53868
54033
|
}).filter(({ shift }) => hasShiftData(shift)).sort((left, right) => getDayDateKey(right.dayData).localeCompare(getDayDateKey(left.dayData)));
|
|
53869
|
-
const filteredShifts = isUptimeMode ? validShifts
|
|
54034
|
+
const filteredShifts = isUptimeMode ? validShifts.filter((shift) => isValidAggregateEfficiency("uptime", shift.efficiency)) : validShifts.filter((shift) => isValidAggregateEfficiency("output", shift.efficiency));
|
|
53870
54035
|
const monthlyMetrics = filteredShifts.length > 0 ? isUptimeMode ? (() => {
|
|
53871
54036
|
const totalIdleTime = filteredShifts.reduce((sum, shift) => sum + shift.idleTime, 0);
|
|
53872
54037
|
const totalCycleTime = filteredShifts.reduce((sum, shift) => sum + shift.cycleTime, 0);
|
|
@@ -67038,7 +67203,15 @@ var KPIDetailView = ({
|
|
|
67038
67203
|
const fallbackTimes = resolveMonthlyShiftTimes(metric.shift_id);
|
|
67039
67204
|
const resolvedShiftStart = metric.shift_start || fallbackTimes.start;
|
|
67040
67205
|
const resolvedShiftEnd = metric.shift_end || fallbackTimes.end;
|
|
67041
|
-
const
|
|
67206
|
+
const coerceOptionalNumber2 = (value) => {
|
|
67207
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
67208
|
+
const parsed = Number(value);
|
|
67209
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
67210
|
+
};
|
|
67211
|
+
const metricActiveTimeSeconds = coerceOptionalNumber2(metric.active_time_seconds);
|
|
67212
|
+
const metricIdleTimeSeconds = coerceOptionalNumber2(metric.idle_time_seconds);
|
|
67213
|
+
const metricAvailableTimeSeconds = coerceOptionalNumber2(metric.available_time_seconds);
|
|
67214
|
+
const hasBackendUptimeSeconds = isUptimeMode && (metricActiveTimeSeconds !== null || metricIdleTimeSeconds !== null || metricAvailableTimeSeconds !== null);
|
|
67042
67215
|
const uptimeSeries2 = isUptimeMode && !hasBackendUptimeSeconds ? buildUptimeSeries({
|
|
67043
67216
|
idleTimeHourly: metric.idle_time_hourly || {},
|
|
67044
67217
|
shiftStart: resolvedShiftStart || void 0,
|
|
@@ -67046,9 +67219,13 @@ var KPIDetailView = ({
|
|
|
67046
67219
|
shiftDate: metric.date,
|
|
67047
67220
|
timezone: configuredTimezone
|
|
67048
67221
|
}) : null;
|
|
67049
|
-
const idleTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ?
|
|
67050
|
-
const activeTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ?
|
|
67051
|
-
const availableTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ?
|
|
67222
|
+
const idleTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ? metricIdleTimeSeconds ?? 0 : (uptimeSeries2?.idleMinutes || 0) * 60 : 0;
|
|
67223
|
+
const activeTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ? metricActiveTimeSeconds ?? 0 : (uptimeSeries2?.activeMinutes || 0) * 60 : 0;
|
|
67224
|
+
const availableTimeSeconds = isUptimeMode ? hasBackendUptimeSeconds ? metricAvailableTimeSeconds ?? activeTimeSeconds + idleTimeSeconds : (uptimeSeries2?.availableMinutes || 0) * 60 : 0;
|
|
67225
|
+
const metricAvgEfficiency = Number(metric.avg_efficiency);
|
|
67226
|
+
const metricTotalWorkspaces = Number(metric.total_workspaces || 0);
|
|
67227
|
+
const metricCurrentOutput = Number(metric.current_output || 0);
|
|
67228
|
+
const hasUptimeMetricData = isUptimeMode && (availableTimeSeconds > 0 || metricTotalWorkspaces > 0 || metricCurrentOutput > 0 || Number.isFinite(metricAvgEfficiency) && metricAvgEfficiency > 0);
|
|
67052
67229
|
const computedUptimeEfficiency = (() => {
|
|
67053
67230
|
const availableMinutes = availableTimeSeconds / 60;
|
|
67054
67231
|
if (!availableMinutes || availableMinutes <= 0) return 0;
|
|
@@ -67068,7 +67245,7 @@ var KPIDetailView = ({
|
|
|
67068
67245
|
targetOutput: Number(metric.line_threshold ?? metric.ideal_output ?? 0),
|
|
67069
67246
|
compliance_percentage: 95 + Math.random() * 5,
|
|
67070
67247
|
// Mock data: random value between 95-100%
|
|
67071
|
-
hasData: isUptimeMode ?
|
|
67248
|
+
hasData: isUptimeMode ? hasUptimeMetricData : true,
|
|
67072
67249
|
idle_time_seconds: idleTimeSeconds,
|
|
67073
67250
|
active_time_seconds: activeTimeSeconds,
|
|
67074
67251
|
available_time_seconds: availableTimeSeconds,
|