@optifye/dashboard-core 6.12.14 → 6.12.16
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/automation.d.ts +1 -0
- package/automation.js +1 -0
- package/dist/automation-Hl2PFMb3.d.mts +444 -0
- package/dist/automation-Hl2PFMb3.d.ts +444 -0
- package/dist/automation.d.mts +2 -0
- package/dist/automation.d.ts +2 -0
- package/dist/automation.js +2312 -0
- package/dist/automation.mjs +2305 -0
- package/dist/index.d.mts +5 -421
- package/dist/index.d.ts +5 -421
- package/dist/index.js +324 -19
- package/dist/index.mjs +324 -20
- package/package.json +11 -2
package/dist/index.js
CHANGED
|
@@ -5596,8 +5596,9 @@ var dashboardService = {
|
|
|
5596
5596
|
total_output: item.total_output || 0,
|
|
5597
5597
|
avg_cycle_time: item.avg_cycle_time || 0,
|
|
5598
5598
|
ideal_cycle_time: item.ideal_cycle_time ?? 0,
|
|
5599
|
-
ideal_output: item.ideal_output
|
|
5600
|
-
total_day_output: item.total_day_output ?? item.ideal_output ?? 0,
|
|
5599
|
+
ideal_output: item.target_output ?? item.ideal_output ?? 0,
|
|
5600
|
+
total_day_output: item.target_output ?? item.total_day_output ?? item.ideal_output ?? 0,
|
|
5601
|
+
target_output: item.target_output ?? item.total_day_output ?? item.ideal_output ?? 0,
|
|
5601
5602
|
avg_pph: item.avg_pph || 0,
|
|
5602
5603
|
pph_threshold: item.pph_threshold || 0,
|
|
5603
5604
|
workspace_rank: item.workspace_rank || 0,
|
|
@@ -13996,7 +13997,7 @@ var useLineWorkspaceMetrics = (lineId, options) => {
|
|
|
13996
13997
|
trend: item.trend_score === 1 ? 2 : 0,
|
|
13997
13998
|
predicted_output: item.ideal_output || 0,
|
|
13998
13999
|
efficiency: item.efficiency || 0,
|
|
13999
|
-
action_threshold: item.total_day_output
|
|
14000
|
+
action_threshold: item.target_output ?? item.total_day_output_recalculated ?? item.total_day_output ?? 0,
|
|
14000
14001
|
idle_time: item.idle_time ?? void 0,
|
|
14001
14002
|
idle_time_hourly: item.idle_time_hourly || null,
|
|
14002
14003
|
shift_start: item.shift_start || void 0,
|
|
@@ -14677,7 +14678,7 @@ var transformMonitorWorkspaceMetrics = ({
|
|
|
14677
14678
|
trend: item.trend_score === 1 ? 2 : 0,
|
|
14678
14679
|
predicted_output: item.ideal_output || 0,
|
|
14679
14680
|
efficiency: item.efficiency || 0,
|
|
14680
|
-
action_threshold: item.total_day_output
|
|
14681
|
+
action_threshold: item.target_output ?? item.total_day_output_recalculated ?? item.total_day_output ?? 0,
|
|
14681
14682
|
monitoring_mode: item.monitoring_mode ?? void 0,
|
|
14682
14683
|
idle_time: idleTimeSeconds,
|
|
14683
14684
|
idle_time_hourly: item.idle_time_hourly ?? null,
|
|
@@ -16847,6 +16848,7 @@ function useHlsStream(videoRef, { src, shouldPlay, onFatalError, hlsConfig }) {
|
|
|
16847
16848
|
return url.includes(proxyBaseUrl);
|
|
16848
16849
|
}
|
|
16849
16850
|
};
|
|
16851
|
+
const isSnapshotStreamUrl = (url) => url.includes("/api/automation/snapshot/stream/");
|
|
16850
16852
|
const getR2CameraUuid = (url) => {
|
|
16851
16853
|
try {
|
|
16852
16854
|
const parsed = new URL(url);
|
|
@@ -17435,11 +17437,16 @@ function useHlsStream(videoRef, { src, shouldPlay, onFatalError, hlsConfig }) {
|
|
|
17435
17437
|
return;
|
|
17436
17438
|
}
|
|
17437
17439
|
if (Hls__default.default.isSupported() && !isNativeHlsRef.current) {
|
|
17440
|
+
const usesSnapshotStream = isSnapshotStreamUrl(resolvedHlsSrc);
|
|
17438
17441
|
const mergedConfig = {
|
|
17439
17442
|
...HLS_CONFIG,
|
|
17440
17443
|
...hlsConfig,
|
|
17444
|
+
enableWorker: usesSnapshotStream ? false : hlsConfig?.enableWorker ?? HLS_CONFIG.enableWorker,
|
|
17441
17445
|
xhrSetup: (xhr, url) => {
|
|
17442
17446
|
const usesProxy = isProxyUrl(url);
|
|
17447
|
+
if (isSnapshotStreamUrl(url)) {
|
|
17448
|
+
xhr.withCredentials = true;
|
|
17449
|
+
}
|
|
17443
17450
|
if (isR2WorkerUrl(url, r2WorkerDomain) || usesProxy) {
|
|
17444
17451
|
if (isManifestUrl(url)) {
|
|
17445
17452
|
xhr.open("GET", buildCacheBustedUrl(url), true);
|
|
@@ -17453,7 +17460,11 @@ function useHlsStream(videoRef, { src, shouldPlay, onFatalError, hlsConfig }) {
|
|
|
17453
17460
|
const isR2Url = isR2WorkerUrl(context.url, r2WorkerDomain);
|
|
17454
17461
|
const isManifestRequest = isManifestUrl(context.url);
|
|
17455
17462
|
const usesProxy = isProxyUrl(context.url);
|
|
17463
|
+
const isSnapshotStream = isSnapshotStreamUrl(context.url);
|
|
17456
17464
|
let requestUrl = context.url;
|
|
17465
|
+
if (isSnapshotStream) {
|
|
17466
|
+
initParams.credentials = "include";
|
|
17467
|
+
}
|
|
17457
17468
|
if (isR2Url || usesProxy) {
|
|
17458
17469
|
if (authToken) {
|
|
17459
17470
|
initParams.headers = {
|
|
@@ -18858,6 +18869,7 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
18858
18869
|
trend_score,
|
|
18859
18870
|
line_id,
|
|
18860
18871
|
total_day_output,
|
|
18872
|
+
total_day_output_recalculated,
|
|
18861
18873
|
workspace_display_name
|
|
18862
18874
|
`).eq("date", fallbackQueryDate).eq("shift_id", fallbackQueryShiftId).in("workspace_id", allEnabledWorkspaceIds).order("efficiency", { ascending: false });
|
|
18863
18875
|
if (fetchError) throw fetchError;
|
|
@@ -18876,7 +18888,7 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
18876
18888
|
trend: item.trend_score === 1 ? 2 : 0,
|
|
18877
18889
|
predicted_output: 0,
|
|
18878
18890
|
efficiency: item.efficiency || 0,
|
|
18879
|
-
action_threshold: item.total_day_output
|
|
18891
|
+
action_threshold: item.target_output ?? item.total_day_output_recalculated ?? item.total_day_output ?? 0
|
|
18880
18892
|
}));
|
|
18881
18893
|
} else if (shiftGroups.length > 0) {
|
|
18882
18894
|
console.log(`[useAllWorkspaceMetrics] \u{1F3ED} Fetching per-shift: ${shiftGroups.length} group(s)`);
|
|
@@ -18903,6 +18915,7 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
18903
18915
|
trend_score,
|
|
18904
18916
|
line_id,
|
|
18905
18917
|
total_day_output,
|
|
18918
|
+
total_day_output_recalculated,
|
|
18906
18919
|
workspace_display_name
|
|
18907
18920
|
`).eq("date", group.date).eq("shift_id", group.shiftId).in("workspace_id", groupWorkspaceIds);
|
|
18908
18921
|
if (fetchError) throw fetchError;
|
|
@@ -18921,7 +18934,7 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
18921
18934
|
trend: item.trend_score === 1 ? 2 : 0,
|
|
18922
18935
|
predicted_output: 0,
|
|
18923
18936
|
efficiency: item.efficiency || 0,
|
|
18924
|
-
action_threshold: item.total_day_output
|
|
18937
|
+
action_threshold: item.target_output ?? item.total_day_output_recalculated ?? item.total_day_output ?? 0
|
|
18925
18938
|
}));
|
|
18926
18939
|
});
|
|
18927
18940
|
const results = await Promise.all(queryPromises);
|
|
@@ -51735,12 +51748,15 @@ var LinePdfGenerator = ({
|
|
|
51735
51748
|
doc.setTextColor(0, 0, 0);
|
|
51736
51749
|
const kpiStartY = 80;
|
|
51737
51750
|
const kpiSpacing = 10;
|
|
51751
|
+
const dayTargetOutput = Math.round(Number(
|
|
51752
|
+
lineInfo.metrics.output_target_recalculated ?? lineInfo.metrics.line_threshold ?? 0
|
|
51753
|
+
));
|
|
51738
51754
|
createKPIBox(kpiStartY);
|
|
51739
51755
|
doc.setFontSize(11);
|
|
51740
51756
|
doc.setFont("helvetica", "normal");
|
|
51741
51757
|
doc.text("Output:", 25, kpiStartY);
|
|
51742
51758
|
doc.setFont("helvetica", "bold");
|
|
51743
|
-
doc.text(`${lineInfo.metrics.current_output} / ${
|
|
51759
|
+
doc.text(`${lineInfo.metrics.current_output} / ${dayTargetOutput}`, 120, kpiStartY);
|
|
51744
51760
|
createKPIBox(kpiStartY + kpiSpacing);
|
|
51745
51761
|
doc.setFont("helvetica", "normal");
|
|
51746
51762
|
doc.text("Average Efficiency:", 25, kpiStartY + kpiSpacing);
|
|
@@ -51775,6 +51791,18 @@ var LinePdfGenerator = ({
|
|
|
51775
51791
|
fallbackHours: Math.max(hourlyTimeRanges.length, 1),
|
|
51776
51792
|
rounding: "floor"
|
|
51777
51793
|
});
|
|
51794
|
+
const backendHourlyTargetOutput = lineInfo.metrics.hourly_target_output;
|
|
51795
|
+
const shouldUseBackendHourlyTargets = backendHourlyTargetOutput !== void 0;
|
|
51796
|
+
const resolveTargetForRange = (index) => {
|
|
51797
|
+
if (shouldUseBackendHourlyTargets) {
|
|
51798
|
+
if (!Array.isArray(backendHourlyTargetOutput)) return null;
|
|
51799
|
+
const targetValue = backendHourlyTargetOutput[index];
|
|
51800
|
+
if (targetValue === null || targetValue === void 0) return null;
|
|
51801
|
+
const numericTarget = Number(targetValue);
|
|
51802
|
+
return Number.isFinite(numericTarget) ? numericTarget : null;
|
|
51803
|
+
}
|
|
51804
|
+
return targetPlan.targets[index] ?? 0;
|
|
51805
|
+
};
|
|
51778
51806
|
const skuRemarksByIndex = {};
|
|
51779
51807
|
if (lineInfo.metrics.sku_segments && lineInfo.metrics.sku_segments.length > 0) {
|
|
51780
51808
|
lineInfo.metrics.sku_segments.forEach((segment, segmentIndex) => {
|
|
@@ -52004,8 +52032,9 @@ var LinePdfGenerator = ({
|
|
|
52004
52032
|
doc.setDrawColor(200, 200, 200);
|
|
52005
52033
|
doc.line(20, rowBottomY, 190, rowBottomY);
|
|
52006
52034
|
}
|
|
52007
|
-
const targetForRange =
|
|
52008
|
-
const
|
|
52035
|
+
const targetForRange = resolveTargetForRange(index);
|
|
52036
|
+
const roundedTargetForRange = targetForRange === null ? null : Math.round(targetForRange);
|
|
52037
|
+
const targetStr = roundedTargetForRange === null ? "-" : roundedTargetForRange.toString();
|
|
52009
52038
|
let remarkText = targetPlan.breakRemarks[index] || "";
|
|
52010
52039
|
if (skuRemarksByIndex[index] && skuRemarksByIndex[index].length > 0) {
|
|
52011
52040
|
const skuRemarks = skuRemarksByIndex[index];
|
|
@@ -52027,7 +52056,10 @@ var LinePdfGenerator = ({
|
|
|
52027
52056
|
if (!dataCollected) {
|
|
52028
52057
|
doc.setTextColor(100, 100, 100);
|
|
52029
52058
|
doc.text("-", 135, yPos);
|
|
52030
|
-
} else if (
|
|
52059
|
+
} else if (roundedTargetForRange === null) {
|
|
52060
|
+
doc.setTextColor(100, 100, 100);
|
|
52061
|
+
doc.text("-", 135, yPos);
|
|
52062
|
+
} else if (actualOutput >= roundedTargetForRange) {
|
|
52031
52063
|
doc.setTextColor(0, 171, 69);
|
|
52032
52064
|
doc.setFont("ZapfDingbats", "normal");
|
|
52033
52065
|
doc.text("4", 135, yPos);
|
|
@@ -53789,6 +53821,19 @@ var WorkspacePdfGenerator = ({
|
|
|
53789
53821
|
fallbackHours: Math.max(hourlyData.length, 1),
|
|
53790
53822
|
rounding: "floor"
|
|
53791
53823
|
}) : null;
|
|
53824
|
+
const backendHourlyTargetOutput = workspace.hourly_target_output;
|
|
53825
|
+
const shouldUseBackendHourlyTargets = backendHourlyTargetOutput !== void 0;
|
|
53826
|
+
const resolveTargetForRange = (index) => {
|
|
53827
|
+
if (!outputTargetPlan) return null;
|
|
53828
|
+
if (shouldUseBackendHourlyTargets) {
|
|
53829
|
+
if (!Array.isArray(backendHourlyTargetOutput)) return null;
|
|
53830
|
+
const targetValue = backendHourlyTargetOutput[index];
|
|
53831
|
+
if (targetValue === null || targetValue === void 0) return null;
|
|
53832
|
+
const numericTarget = Number(targetValue);
|
|
53833
|
+
return Number.isFinite(numericTarget) ? numericTarget : null;
|
|
53834
|
+
}
|
|
53835
|
+
return outputTargetPlan.targets[index] ?? hourlyTarget;
|
|
53836
|
+
};
|
|
53792
53837
|
const skuRemarksByIndex = {};
|
|
53793
53838
|
if (workspace.sku_segments && workspace.sku_segments.length > 0) {
|
|
53794
53839
|
workspace.sku_segments.forEach((segment, segmentIndex) => {
|
|
@@ -53915,7 +53960,7 @@ var WorkspacePdfGenerator = ({
|
|
|
53915
53960
|
const idleValue = isUptimeMode ? entry.idleMinutes ?? 0 : 0;
|
|
53916
53961
|
const uptimePercent = isUptimeMode ? entry.uptimePercent ?? 0 : 0;
|
|
53917
53962
|
const outputStr = dataCollected ? outputValue.toString() : "TBD";
|
|
53918
|
-
const effectiveTarget =
|
|
53963
|
+
const effectiveTarget = resolveTargetForRange(index);
|
|
53919
53964
|
let remarkText = outputTargetPlan?.breakRemarks[index] || "";
|
|
53920
53965
|
if (skuRemarksByIndex[index] && skuRemarksByIndex[index].length > 0) {
|
|
53921
53966
|
const skuRemarks = skuRemarksByIndex[index];
|
|
@@ -53923,7 +53968,8 @@ var WorkspacePdfGenerator = ({
|
|
|
53923
53968
|
const compactSkuRemark = skuRemarks.length === 1 ? `${latestSku} started` : `${latestSku} started, +${skuRemarks.length - 1}`;
|
|
53924
53969
|
remarkText = remarkText ? `${remarkText}, ${compactSkuRemark}` : compactSkuRemark;
|
|
53925
53970
|
}
|
|
53926
|
-
const
|
|
53971
|
+
const roundedEffectiveTarget = effectiveTarget === null ? null : Math.round(effectiveTarget);
|
|
53972
|
+
const targetStr = isUptimeMode ? dataCollected ? idleValue.toString() : "TBD" : roundedEffectiveTarget === null ? "-" : roundedEffectiveTarget.toString();
|
|
53927
53973
|
if (index < totalRows - 1) {
|
|
53928
53974
|
const rowBottomY = headerBottomY + (index + 1) * rowHeight;
|
|
53929
53975
|
doc.setDrawColor(200, 200, 200);
|
|
@@ -53966,7 +54012,10 @@ var WorkspacePdfGenerator = ({
|
|
|
53966
54012
|
if (!dataCollected) {
|
|
53967
54013
|
doc.setTextColor(100, 100, 100);
|
|
53968
54014
|
doc.text("-", 135, yPos);
|
|
53969
|
-
} else if (
|
|
54015
|
+
} else if (roundedEffectiveTarget === null) {
|
|
54016
|
+
doc.setTextColor(100, 100, 100);
|
|
54017
|
+
doc.text("-", 135, yPos);
|
|
54018
|
+
} else if (outputValue >= roundedEffectiveTarget) {
|
|
53970
54019
|
doc.setTextColor(0, 171, 69);
|
|
53971
54020
|
doc.setFont("ZapfDingbats", "normal");
|
|
53972
54021
|
doc.text("4", 135, yPos);
|
|
@@ -65535,6 +65584,7 @@ var buildLineInfoSnapshot = (lineDetails, metrics2) => {
|
|
|
65535
65584
|
output_array: metrics2.output_array || [],
|
|
65536
65585
|
output_hourly: metrics2.output_hourly,
|
|
65537
65586
|
hourly_target_output: metrics2.hourly_target_output,
|
|
65587
|
+
hourly_target_output_by_sku: metrics2.hourly_target_output_by_sku,
|
|
65538
65588
|
line_threshold: metrics2.line_threshold ?? 0,
|
|
65539
65589
|
output_target_recalculated: metrics2.output_target_recalculated ?? null,
|
|
65540
65590
|
threshold_pph: metrics2.threshold_pph ?? 0,
|
|
@@ -65568,7 +65618,7 @@ var transformWorkspaceMetrics = (workspaceData, lineId, companyId, queryDate, qu
|
|
|
65568
65618
|
trend: item.trend_score === 1 ? 2 : 0,
|
|
65569
65619
|
predicted_output: item.ideal_output || 0,
|
|
65570
65620
|
efficiency: item.efficiency || 0,
|
|
65571
|
-
action_threshold: item.total_day_output
|
|
65621
|
+
action_threshold: item.target_output ?? item.total_day_output_recalculated ?? item.total_day_output ?? 0,
|
|
65572
65622
|
idle_time: item.idle_time ?? void 0,
|
|
65573
65623
|
idle_time_hourly: item.idle_time_hourly || null,
|
|
65574
65624
|
shift_start: item.shift_start || void 0,
|
|
@@ -67363,9 +67413,9 @@ var KPIDetailView = ({
|
|
|
67363
67413
|
output: metric.current_output || 0,
|
|
67364
67414
|
// LineMonthlyHistory expects `idealOutput` for the red dotted target ReferenceLine.
|
|
67365
67415
|
// `line_threshold` comes from `line_metrics` (numeric -> string via PostgREST), so coerce.
|
|
67366
|
-
idealOutput: Number(metric.line_threshold ?? metric.ideal_output ?? 0),
|
|
67416
|
+
idealOutput: Number(metric.target_output ?? metric.line_threshold ?? metric.ideal_output ?? 0),
|
|
67367
67417
|
// Keep legacy field in case any downstream code still reads it.
|
|
67368
|
-
targetOutput: Number(metric.line_threshold ?? metric.ideal_output ?? 0),
|
|
67418
|
+
targetOutput: Number(metric.target_output ?? metric.line_threshold ?? metric.ideal_output ?? 0),
|
|
67369
67419
|
compliance_percentage: 95 + Math.random() * 5,
|
|
67370
67420
|
// Mock data: random value between 95-100%
|
|
67371
67421
|
hasData: isUptimeMode ? hasUptimeMetricData : true,
|
|
@@ -67452,6 +67502,7 @@ var KPIDetailView = ({
|
|
|
67452
67502
|
output_array: metrics2.output_array || [],
|
|
67453
67503
|
output_hourly: metrics2.output_hourly,
|
|
67454
67504
|
hourly_target_output: metrics2.hourly_target_output,
|
|
67505
|
+
hourly_target_output_by_sku: metrics2.hourly_target_output_by_sku,
|
|
67455
67506
|
line_threshold: metrics2.line_threshold ?? 0,
|
|
67456
67507
|
output_target_recalculated: metrics2.output_target_recalculated ?? null,
|
|
67457
67508
|
threshold_pph: metrics2.threshold_pph ?? 0,
|
|
@@ -67579,6 +67630,19 @@ var KPIDetailView = ({
|
|
|
67579
67630
|
if (selectedSkuId === "all") return null;
|
|
67580
67631
|
return realSkuOptions.find((item) => item.sku_id === selectedSkuId) ?? null;
|
|
67581
67632
|
}, [realSkuOptions, selectedSkuId]);
|
|
67633
|
+
const selectedHourlyTargetOutput = React144.useMemo(() => {
|
|
67634
|
+
const aggregateTarget = chartMetrics?.hourly_target_output;
|
|
67635
|
+
if (!normalizedSelectedSkuId) return aggregateTarget;
|
|
67636
|
+
const targetBySku = chartMetrics?.hourly_target_output_by_sku;
|
|
67637
|
+
if (targetBySku && Object.prototype.hasOwnProperty.call(targetBySku, normalizedSelectedSkuId)) {
|
|
67638
|
+
return targetBySku[normalizedSelectedSkuId];
|
|
67639
|
+
}
|
|
67640
|
+
return aggregateTarget;
|
|
67641
|
+
}, [
|
|
67642
|
+
chartMetrics?.hourly_target_output,
|
|
67643
|
+
chartMetrics?.hourly_target_output_by_sku,
|
|
67644
|
+
normalizedSelectedSkuId
|
|
67645
|
+
]);
|
|
67582
67646
|
const displayLineInfo = React144.useMemo(() => {
|
|
67583
67647
|
if (!resolvedLineInfo) return null;
|
|
67584
67648
|
if (!selectedSkuRow) return resolvedLineInfo;
|
|
@@ -68420,7 +68484,7 @@ var KPIDetailView = ({
|
|
|
68420
68484
|
workspaceDisplayNames,
|
|
68421
68485
|
hourlyOutputData,
|
|
68422
68486
|
hourlyThreshold,
|
|
68423
|
-
hourlyTargetOutput:
|
|
68487
|
+
hourlyTargetOutput: selectedHourlyTargetOutput,
|
|
68424
68488
|
shiftBreaks: shiftConfig?.shifts?.find((shift) => shift.shiftId === resolvedLineInfo.shift_id)?.breaks || [],
|
|
68425
68489
|
idleTimeHourly: chartMetrics?.idle_time_hourly,
|
|
68426
68490
|
timezone: lineTimezone,
|
|
@@ -75822,8 +75886,8 @@ var WorkspaceDetailView = ({
|
|
|
75822
75886
|
idealCycleTime: Number(metric.ideal_cycle_time || 0),
|
|
75823
75887
|
pph: metric.avg_pph || 0,
|
|
75824
75888
|
pphThreshold: metric.pph_threshold || 0,
|
|
75825
|
-
idealOutput: Number(metric.ideal_output
|
|
75826
|
-
targetOutput: Number(metric.total_day_output
|
|
75889
|
+
idealOutput: Number(metric.target_output ?? metric.ideal_output ?? 0),
|
|
75890
|
+
targetOutput: Number(metric.target_output ?? metric.total_day_output ?? 0),
|
|
75827
75891
|
rank: metric.workspace_rank || 0,
|
|
75828
75892
|
idleTime: idleTimeSeconds || 0,
|
|
75829
75893
|
activeTimeSeconds,
|
|
@@ -85793,6 +85857,246 @@ var streamProxyConfig = {
|
|
|
85793
85857
|
responseLimit: false
|
|
85794
85858
|
}
|
|
85795
85859
|
};
|
|
85860
|
+
var MOBILE_SCROLL_THRESHOLD2 = 15;
|
|
85861
|
+
var MOBILE_BREAKPOINT_PX2 = 640;
|
|
85862
|
+
var sortWorkspaces = (left, right) => {
|
|
85863
|
+
if (left.line_id !== right.line_id) {
|
|
85864
|
+
return left.line_id.localeCompare(right.line_id);
|
|
85865
|
+
}
|
|
85866
|
+
const leftMatch = left.workspace_name.match(/WS(\d+)/);
|
|
85867
|
+
const rightMatch = right.workspace_name.match(/WS(\d+)/);
|
|
85868
|
+
if (leftMatch && rightMatch) {
|
|
85869
|
+
return parseInt(leftMatch[1], 10) - parseInt(rightMatch[1], 10);
|
|
85870
|
+
}
|
|
85871
|
+
return left.workspace_name.localeCompare(right.workspace_name, void 0, { numeric: true });
|
|
85872
|
+
};
|
|
85873
|
+
var RecentFlowSnapshotGrid = ({
|
|
85874
|
+
workspaces,
|
|
85875
|
+
videoStreamsByWorkspaceId,
|
|
85876
|
+
legend,
|
|
85877
|
+
className = ""
|
|
85878
|
+
}) => {
|
|
85879
|
+
const containerRef = React144.useRef(null);
|
|
85880
|
+
const readinessRef = React144.useRef(null);
|
|
85881
|
+
const [gridCols, setGridCols] = React144.useState(4);
|
|
85882
|
+
const [gridRows, setGridRows] = React144.useState(1);
|
|
85883
|
+
const [isMobileScrollableGrid, setIsMobileScrollableGrid] = React144.useState(false);
|
|
85884
|
+
const sortedWorkspaces = React144.useMemo(
|
|
85885
|
+
() => [...workspaces || []].sort(sortWorkspaces),
|
|
85886
|
+
[workspaces]
|
|
85887
|
+
);
|
|
85888
|
+
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
85889
|
+
const displayMinuteBucket = Math.floor(Date.now() / 6e4);
|
|
85890
|
+
const expectedVideoCount = React144.useMemo(
|
|
85891
|
+
() => sortedWorkspaces.filter((workspace) => {
|
|
85892
|
+
const workspaceId = workspace.workspace_uuid || workspace.workspace_name;
|
|
85893
|
+
return Boolean(workspaceId && videoStreamsByWorkspaceId[workspaceId]?.hls_url);
|
|
85894
|
+
}).length,
|
|
85895
|
+
[sortedWorkspaces, videoStreamsByWorkspaceId]
|
|
85896
|
+
);
|
|
85897
|
+
const publishSnapshotReadiness = React144.useCallback((readyVideoCount) => {
|
|
85898
|
+
const status = {
|
|
85899
|
+
expectedVideoCount,
|
|
85900
|
+
readyVideoCount,
|
|
85901
|
+
status: expectedVideoCount === 0 ? "no_videos" : readyVideoCount >= expectedVideoCount ? "ready" : "loading",
|
|
85902
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
85903
|
+
};
|
|
85904
|
+
const isReady = expectedVideoCount > 0 && status.status === "ready";
|
|
85905
|
+
if (typeof window !== "undefined") {
|
|
85906
|
+
window.__OPTIFYE_SNAPSHOT_READY__ = isReady;
|
|
85907
|
+
window.__OPTIFYE_SNAPSHOT_VIDEO_STATUS__ = status;
|
|
85908
|
+
}
|
|
85909
|
+
const marker = readinessRef.current;
|
|
85910
|
+
if (marker) {
|
|
85911
|
+
marker.dataset.ready = isReady ? "true" : "false";
|
|
85912
|
+
marker.dataset.status = status.status;
|
|
85913
|
+
marker.dataset.expectedVideoCount = String(status.expectedVideoCount);
|
|
85914
|
+
marker.dataset.readyVideoCount = String(status.readyVideoCount);
|
|
85915
|
+
marker.dataset.updatedAt = status.updatedAt;
|
|
85916
|
+
}
|
|
85917
|
+
}, [expectedVideoCount]);
|
|
85918
|
+
const calculateOptimalGrid = React144.useCallback(() => {
|
|
85919
|
+
if (!containerRef.current) return;
|
|
85920
|
+
const containerPadding = 16;
|
|
85921
|
+
const rawContainerWidth = containerRef.current.clientWidth;
|
|
85922
|
+
const containerWidth = rawContainerWidth - containerPadding;
|
|
85923
|
+
const containerHeight = containerRef.current.clientHeight - containerPadding;
|
|
85924
|
+
const count = sortedWorkspaces.length;
|
|
85925
|
+
if (count === 0) {
|
|
85926
|
+
setGridCols(1);
|
|
85927
|
+
setGridRows(1);
|
|
85928
|
+
setIsMobileScrollableGrid(false);
|
|
85929
|
+
return;
|
|
85930
|
+
}
|
|
85931
|
+
const shouldUseMobileScroll = rawContainerWidth < MOBILE_BREAKPOINT_PX2 && count >= MOBILE_SCROLL_THRESHOLD2;
|
|
85932
|
+
const optimalLayouts = {
|
|
85933
|
+
1: 1,
|
|
85934
|
+
2: 2,
|
|
85935
|
+
3: 3,
|
|
85936
|
+
4: 2,
|
|
85937
|
+
5: 3,
|
|
85938
|
+
6: 3,
|
|
85939
|
+
7: 4,
|
|
85940
|
+
8: 4,
|
|
85941
|
+
9: 3,
|
|
85942
|
+
10: 5,
|
|
85943
|
+
11: 4,
|
|
85944
|
+
12: 4,
|
|
85945
|
+
13: 5,
|
|
85946
|
+
14: 5,
|
|
85947
|
+
15: 5,
|
|
85948
|
+
16: 4,
|
|
85949
|
+
17: 6,
|
|
85950
|
+
18: 6,
|
|
85951
|
+
19: 5,
|
|
85952
|
+
20: 5,
|
|
85953
|
+
21: 7,
|
|
85954
|
+
22: 6,
|
|
85955
|
+
23: 6,
|
|
85956
|
+
24: 6
|
|
85957
|
+
};
|
|
85958
|
+
let bestCols = optimalLayouts[count] || Math.ceil(Math.sqrt(count));
|
|
85959
|
+
const containerAspectRatio = containerWidth / containerHeight;
|
|
85960
|
+
const targetAspectRatio = 16 / 9;
|
|
85961
|
+
const gap = 8;
|
|
85962
|
+
if (containerAspectRatio > targetAspectRatio * 1.5 && count > 6) {
|
|
85963
|
+
bestCols = Math.min(bestCols + 1, Math.ceil(count / 2));
|
|
85964
|
+
}
|
|
85965
|
+
const minCellWidth = 100;
|
|
85966
|
+
const availableWidth = containerWidth - gap * (bestCols - 1);
|
|
85967
|
+
const cellWidth = availableWidth / bestCols;
|
|
85968
|
+
if (cellWidth < minCellWidth && bestCols > 1) {
|
|
85969
|
+
bestCols = Math.max(1, Math.floor((containerWidth + gap) / (minCellWidth + gap)));
|
|
85970
|
+
}
|
|
85971
|
+
setGridCols(bestCols);
|
|
85972
|
+
setGridRows(Math.ceil(count / bestCols));
|
|
85973
|
+
setIsMobileScrollableGrid(shouldUseMobileScroll);
|
|
85974
|
+
}, [sortedWorkspaces.length]);
|
|
85975
|
+
React144.useEffect(() => {
|
|
85976
|
+
calculateOptimalGrid();
|
|
85977
|
+
window.addEventListener("resize", calculateOptimalGrid);
|
|
85978
|
+
return () => window.removeEventListener("resize", calculateOptimalGrid);
|
|
85979
|
+
}, [calculateOptimalGrid]);
|
|
85980
|
+
React144.useEffect(() => {
|
|
85981
|
+
const attachedVideos = /* @__PURE__ */ new Set();
|
|
85982
|
+
const videoEvents = ["loadeddata", "canplay", "playing", "timeupdate", "error", "stalled"];
|
|
85983
|
+
const hasDecodedFrame = (video) => video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && video.videoWidth > 0 && video.videoHeight > 0;
|
|
85984
|
+
const updateReadiness = () => {
|
|
85985
|
+
const videos = Array.from(containerRef.current?.querySelectorAll("video") ?? []);
|
|
85986
|
+
const readyVideoCount = videos.filter(hasDecodedFrame).length;
|
|
85987
|
+
publishSnapshotReadiness(Math.min(readyVideoCount, expectedVideoCount));
|
|
85988
|
+
for (const video of videos) {
|
|
85989
|
+
if (attachedVideos.has(video)) continue;
|
|
85990
|
+
attachedVideos.add(video);
|
|
85991
|
+
for (const eventName of videoEvents) {
|
|
85992
|
+
video.addEventListener(eventName, updateReadiness);
|
|
85993
|
+
}
|
|
85994
|
+
}
|
|
85995
|
+
};
|
|
85996
|
+
publishSnapshotReadiness(0);
|
|
85997
|
+
updateReadiness();
|
|
85998
|
+
const intervalId = window.setInterval(updateReadiness, 250);
|
|
85999
|
+
return () => {
|
|
86000
|
+
window.clearInterval(intervalId);
|
|
86001
|
+
for (const video of attachedVideos) {
|
|
86002
|
+
for (const eventName of videoEvents) {
|
|
86003
|
+
video.removeEventListener(eventName, updateReadiness);
|
|
86004
|
+
}
|
|
86005
|
+
}
|
|
86006
|
+
if (typeof window !== "undefined") {
|
|
86007
|
+
window.__OPTIFYE_SNAPSHOT_READY__ = false;
|
|
86008
|
+
window.__OPTIFYE_SNAPSHOT_VIDEO_STATUS__ = void 0;
|
|
86009
|
+
}
|
|
86010
|
+
};
|
|
86011
|
+
}, [expectedVideoCount, publishSnapshotReadiness]);
|
|
86012
|
+
if (!sortedWorkspaces.length) {
|
|
86013
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
86014
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
86015
|
+
"div",
|
|
86016
|
+
{
|
|
86017
|
+
ref: readinessRef,
|
|
86018
|
+
"data-testid": "snapshot-video-readiness",
|
|
86019
|
+
"data-ready": "false",
|
|
86020
|
+
"data-status": "no_videos",
|
|
86021
|
+
"data-expected-video-count": "0",
|
|
86022
|
+
"data-ready-video-count": "0",
|
|
86023
|
+
hidden: true
|
|
86024
|
+
}
|
|
86025
|
+
),
|
|
86026
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-[320px] items-center justify-center rounded-md border border-dashed border-slate-300 bg-slate-50 text-sm font-medium text-slate-500", children: "No workstation snapshot available" })
|
|
86027
|
+
] });
|
|
86028
|
+
}
|
|
86029
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
86030
|
+
"div",
|
|
86031
|
+
{
|
|
86032
|
+
"aria-label": "Recent-flow workstation snapshot",
|
|
86033
|
+
className: `relative h-full min-h-0 w-full overflow-hidden bg-slate-50/30 ${className}`,
|
|
86034
|
+
children: [
|
|
86035
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
86036
|
+
"div",
|
|
86037
|
+
{
|
|
86038
|
+
ref: readinessRef,
|
|
86039
|
+
"data-testid": "snapshot-video-readiness",
|
|
86040
|
+
"data-ready": "false",
|
|
86041
|
+
"data-status": expectedVideoCount === 0 ? "no_videos" : "loading",
|
|
86042
|
+
"data-expected-video-count": expectedVideoCount,
|
|
86043
|
+
"data-ready-video-count": "0",
|
|
86044
|
+
hidden: true
|
|
86045
|
+
}
|
|
86046
|
+
),
|
|
86047
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
86048
|
+
"div",
|
|
86049
|
+
{
|
|
86050
|
+
ref: containerRef,
|
|
86051
|
+
"data-testid": "video-grid-scroll-container",
|
|
86052
|
+
"data-mobile-scrollable": isMobileScrollableGrid ? "true" : "false",
|
|
86053
|
+
className: `absolute inset-0 w-full overflow-x-hidden px-1 py-1 sm:px-2 sm:py-2 ${isMobileScrollableGrid ? "overflow-y-auto" : "overflow-hidden"}`,
|
|
86054
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
86055
|
+
"div",
|
|
86056
|
+
{
|
|
86057
|
+
"data-testid": "video-grid-layout",
|
|
86058
|
+
className: `grid min-w-0 w-full gap-1.5 sm:gap-2 ${isMobileScrollableGrid ? "content-start" : "h-full"}`,
|
|
86059
|
+
style: {
|
|
86060
|
+
gridTemplateColumns: `repeat(${gridCols}, minmax(0, 1fr))`,
|
|
86061
|
+
gridTemplateRows: isMobileScrollableGrid ? void 0 : `repeat(${gridRows}, 1fr)`,
|
|
86062
|
+
gridAutoFlow: "row"
|
|
86063
|
+
},
|
|
86064
|
+
children: sortedWorkspaces.map((workspace) => {
|
|
86065
|
+
const workspaceId = workspace.workspace_uuid || workspace.workspace_name;
|
|
86066
|
+
const stream = workspaceId ? videoStreamsByWorkspaceId[workspaceId] : null;
|
|
86067
|
+
const hlsUrl = stream?.hls_url || "";
|
|
86068
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
86069
|
+
"div",
|
|
86070
|
+
{
|
|
86071
|
+
"data-workspace-id": workspaceId,
|
|
86072
|
+
className: isMobileScrollableGrid ? "workspace-card relative min-w-0 w-full aspect-video min-h-[92px]" : "workspace-card relative min-w-0 w-full h-full",
|
|
86073
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
86074
|
+
VideoCard,
|
|
86075
|
+
{
|
|
86076
|
+
workspace,
|
|
86077
|
+
hlsUrl,
|
|
86078
|
+
shouldPlay: Boolean(hlsUrl),
|
|
86079
|
+
legend: effectiveLegend,
|
|
86080
|
+
cropping: stream?.crop || void 0,
|
|
86081
|
+
canvasFps: 10,
|
|
86082
|
+
useRAF: false,
|
|
86083
|
+
displayMinuteBucket,
|
|
86084
|
+
displayName: workspace.displayName || workspace.workspace_name,
|
|
86085
|
+
compact: true
|
|
86086
|
+
}
|
|
86087
|
+
) })
|
|
86088
|
+
},
|
|
86089
|
+
`${workspace.line_id}-${workspaceId}`
|
|
86090
|
+
);
|
|
86091
|
+
})
|
|
86092
|
+
}
|
|
86093
|
+
)
|
|
86094
|
+
}
|
|
86095
|
+
)
|
|
86096
|
+
]
|
|
86097
|
+
}
|
|
86098
|
+
);
|
|
86099
|
+
};
|
|
85796
86100
|
|
|
85797
86101
|
exports.ACTION_FAMILIES = ACTION_FAMILIES;
|
|
85798
86102
|
exports.ACTION_NAMES = ACTION_NAMES;
|
|
@@ -85949,6 +86253,7 @@ exports.PrefetchStatus = PrefetchStatus;
|
|
|
85949
86253
|
exports.PrefetchTimeoutError = PrefetchTimeoutError;
|
|
85950
86254
|
exports.ProfileView = ProfileView_default;
|
|
85951
86255
|
exports.ROOT_DASHBOARD_EVENT_NAMES = ROOT_DASHBOARD_EVENT_NAMES;
|
|
86256
|
+
exports.RecentFlowSnapshotGrid = RecentFlowSnapshotGrid;
|
|
85952
86257
|
exports.RegistryProvider = RegistryProvider;
|
|
85953
86258
|
exports.RoleBadge = RoleBadge;
|
|
85954
86259
|
exports.S3ClipsService = S3ClipsSupabaseService;
|