@optifye/dashboard-core 6.12.28 → 6.12.30
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/{automation-CQqrAD4z.d.mts → automation-Jf6Isg6G.d.mts} +24 -1
- package/dist/{automation-CQqrAD4z.d.ts → automation-Jf6Isg6G.d.ts} +24 -1
- package/dist/automation.d.mts +1 -1
- package/dist/automation.d.ts +1 -1
- package/dist/automation.js +165 -1
- package/dist/automation.mjs +167 -3
- package/dist/index.css +35 -0
- package/dist/index.d.mts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +101 -26
- package/dist/index.mjs +103 -28
- package/package.json +1 -1
|
@@ -5,6 +5,9 @@ declare const normalizeVideoGridMetricMode: (value: unknown, assemblyEnabled?: b
|
|
|
5
5
|
declare const isRecentFlowVideoGridMetricMode: (value: unknown, assemblyEnabled?: boolean) => boolean;
|
|
6
6
|
declare const isWipGatedVideoGridMetricMode: (value: unknown, assemblyEnabled?: boolean) => boolean;
|
|
7
7
|
|
|
8
|
+
type IdleReasonPaletteToken = 'red' | 'amber' | 'blue' | 'violet' | 'emerald' | 'cyan' | 'slate';
|
|
9
|
+
type IdleReasonIconToken = 'alert-triangle' | 'refresh-cw' | 'package' | 'clock' | 'user-x' | 'wrench' | 'activity' | 'clipboard-x' | 'help-circle';
|
|
10
|
+
|
|
8
11
|
/** One row of per-SKU workspace metrics. Backend computes; frontend renders. */
|
|
9
12
|
interface SkuBreakdownItem {
|
|
10
13
|
/** UUID — `skus.id`. Stable identifier for selectors and threshold writes. */
|
|
@@ -149,6 +152,18 @@ interface PoorPerformingWorkspace {
|
|
|
149
152
|
action_count: number;
|
|
150
153
|
action_threshold: number;
|
|
151
154
|
}
|
|
155
|
+
interface VideoGridStatusBadge {
|
|
156
|
+
kind: 'idle_reason' | 'no_plan';
|
|
157
|
+
label: string | null;
|
|
158
|
+
display_name: string;
|
|
159
|
+
palette_token: IdleReasonPaletteToken;
|
|
160
|
+
icon_token: IdleReasonIconToken;
|
|
161
|
+
is_known?: boolean;
|
|
162
|
+
title?: string;
|
|
163
|
+
anchor_minute?: number;
|
|
164
|
+
reason_minute?: number;
|
|
165
|
+
shift_elapsed_fraction?: number;
|
|
166
|
+
}
|
|
152
167
|
interface WorkspaceMetrics {
|
|
153
168
|
company_id: string;
|
|
154
169
|
line_id: string;
|
|
@@ -170,6 +185,7 @@ interface WorkspaceMetrics {
|
|
|
170
185
|
monitoring_mode?: 'output' | 'uptime';
|
|
171
186
|
idle_time?: number;
|
|
172
187
|
idle_time_hourly?: Record<string, any> | null;
|
|
188
|
+
idle_reason_hourly?: Record<string, any> | null;
|
|
173
189
|
shift_start?: string;
|
|
174
190
|
shift_end?: string;
|
|
175
191
|
assembly_enabled?: boolean;
|
|
@@ -200,6 +216,7 @@ interface WorkspaceMetrics {
|
|
|
200
216
|
incoming_wip_current?: number | null;
|
|
201
217
|
incoming_wip_effective_at?: string | null;
|
|
202
218
|
incoming_wip_buffer_name?: string | null;
|
|
219
|
+
video_grid_badges?: VideoGridStatusBadge[];
|
|
203
220
|
/**
|
|
204
221
|
* When present, controls whether the UI should show the exclamation indicator for this workstation.
|
|
205
222
|
* - Flow-configured lines: true only when a WIP alert is active for a buffer that outputs to this workstation.
|
|
@@ -270,6 +287,9 @@ interface LineSignal {
|
|
|
270
287
|
weight?: number | null;
|
|
271
288
|
mode?: KpiSignalMode;
|
|
272
289
|
reason?: string | null;
|
|
290
|
+
aggregate_eligible?: boolean | null;
|
|
291
|
+
aggregate_reason?: string | null;
|
|
292
|
+
aggregate_threshold_percent?: number | null;
|
|
273
293
|
effective_end_at?: string | null;
|
|
274
294
|
computed_at?: string | null;
|
|
275
295
|
}
|
|
@@ -279,6 +299,9 @@ interface KpiSignal {
|
|
|
279
299
|
weight?: number | null;
|
|
280
300
|
mode?: KpiSignalMode;
|
|
281
301
|
reason?: string | null;
|
|
302
|
+
aggregateEligible?: boolean | null;
|
|
303
|
+
aggregateReason?: string | null;
|
|
304
|
+
aggregateThresholdPercent?: number | null;
|
|
282
305
|
effectiveEndAt?: string | null;
|
|
283
306
|
computedAt?: string | null;
|
|
284
307
|
}
|
|
@@ -471,4 +494,4 @@ interface RecentFlowSnapshotGridProps {
|
|
|
471
494
|
}
|
|
472
495
|
declare const RecentFlowSnapshotGrid: React__default.FC<RecentFlowSnapshotGridProps>;
|
|
473
496
|
|
|
474
|
-
export { type ActionThreshold as A, type CurrentWorkspaceSKU as C, type DashboardKPIs as D, type EfficiencyLegendUpdate as E, type KpiTrend as K, type LineSignal as L, type MonthlyTrendSummary as M, type PoorPerformingWorkspace as P, type RecentFlowSnapshotGridProps as R, type SkuBreakdownItem as S, type VideoGridMetricMode as V, type WorkspaceMetrics as W, type LineInfo as a, type WorkspaceDetailedMetrics as b, type SkuSegmentItem as c, type LineSkuBreakdownItem as d, type WorkspaceVideoStream as e, type Workspace as f, type WorkspaceCameraIpInfo as g, type WorkspaceActionUpdate as h, type ShiftConfiguration as i, type KpiSignal as j, type LineIssueResolutionSummary as k, type LineDetailedMetrics as l, type
|
|
497
|
+
export { type ActionThreshold as A, RecentFlowSnapshotGrid as B, type CurrentWorkspaceSKU as C, type DashboardKPIs as D, type EfficiencyLegendUpdate as E, type KpiTrend as K, type LineSignal as L, type MonthlyTrendSummary as M, type PoorPerformingWorkspace as P, type RecentFlowSnapshotGridProps as R, type SkuBreakdownItem as S, type VideoGridMetricMode as V, type WorkspaceMetrics as W, type LineInfo as a, type WorkspaceDetailedMetrics as b, type SkuSegmentItem as c, type LineSkuBreakdownItem as d, type WorkspaceVideoStream as e, type Workspace as f, type WorkspaceCameraIpInfo as g, type WorkspaceActionUpdate as h, type ShiftConfiguration as i, type KpiSignal as j, type LineIssueResolutionSummary as k, type LineDetailedMetrics as l, type VideoGridStatusBadge as m, type LineSignalSource as n, type KpiSignalSource as o, type KpiSignalMode as p, type ValueDelta as q, type PercentageDelta as r, type CountDelta as s, type DurationDelta as t, type WorkspaceCropRect as u, type LineThreshold as v, type ShiftConfigurationRecord as w, normalizeVideoGridMetricMode as x, isRecentFlowVideoGridMetricMode as y, isWipGatedVideoGridMetricMode as z };
|
|
@@ -5,6 +5,9 @@ declare const normalizeVideoGridMetricMode: (value: unknown, assemblyEnabled?: b
|
|
|
5
5
|
declare const isRecentFlowVideoGridMetricMode: (value: unknown, assemblyEnabled?: boolean) => boolean;
|
|
6
6
|
declare const isWipGatedVideoGridMetricMode: (value: unknown, assemblyEnabled?: boolean) => boolean;
|
|
7
7
|
|
|
8
|
+
type IdleReasonPaletteToken = 'red' | 'amber' | 'blue' | 'violet' | 'emerald' | 'cyan' | 'slate';
|
|
9
|
+
type IdleReasonIconToken = 'alert-triangle' | 'refresh-cw' | 'package' | 'clock' | 'user-x' | 'wrench' | 'activity' | 'clipboard-x' | 'help-circle';
|
|
10
|
+
|
|
8
11
|
/** One row of per-SKU workspace metrics. Backend computes; frontend renders. */
|
|
9
12
|
interface SkuBreakdownItem {
|
|
10
13
|
/** UUID — `skus.id`. Stable identifier for selectors and threshold writes. */
|
|
@@ -149,6 +152,18 @@ interface PoorPerformingWorkspace {
|
|
|
149
152
|
action_count: number;
|
|
150
153
|
action_threshold: number;
|
|
151
154
|
}
|
|
155
|
+
interface VideoGridStatusBadge {
|
|
156
|
+
kind: 'idle_reason' | 'no_plan';
|
|
157
|
+
label: string | null;
|
|
158
|
+
display_name: string;
|
|
159
|
+
palette_token: IdleReasonPaletteToken;
|
|
160
|
+
icon_token: IdleReasonIconToken;
|
|
161
|
+
is_known?: boolean;
|
|
162
|
+
title?: string;
|
|
163
|
+
anchor_minute?: number;
|
|
164
|
+
reason_minute?: number;
|
|
165
|
+
shift_elapsed_fraction?: number;
|
|
166
|
+
}
|
|
152
167
|
interface WorkspaceMetrics {
|
|
153
168
|
company_id: string;
|
|
154
169
|
line_id: string;
|
|
@@ -170,6 +185,7 @@ interface WorkspaceMetrics {
|
|
|
170
185
|
monitoring_mode?: 'output' | 'uptime';
|
|
171
186
|
idle_time?: number;
|
|
172
187
|
idle_time_hourly?: Record<string, any> | null;
|
|
188
|
+
idle_reason_hourly?: Record<string, any> | null;
|
|
173
189
|
shift_start?: string;
|
|
174
190
|
shift_end?: string;
|
|
175
191
|
assembly_enabled?: boolean;
|
|
@@ -200,6 +216,7 @@ interface WorkspaceMetrics {
|
|
|
200
216
|
incoming_wip_current?: number | null;
|
|
201
217
|
incoming_wip_effective_at?: string | null;
|
|
202
218
|
incoming_wip_buffer_name?: string | null;
|
|
219
|
+
video_grid_badges?: VideoGridStatusBadge[];
|
|
203
220
|
/**
|
|
204
221
|
* When present, controls whether the UI should show the exclamation indicator for this workstation.
|
|
205
222
|
* - Flow-configured lines: true only when a WIP alert is active for a buffer that outputs to this workstation.
|
|
@@ -270,6 +287,9 @@ interface LineSignal {
|
|
|
270
287
|
weight?: number | null;
|
|
271
288
|
mode?: KpiSignalMode;
|
|
272
289
|
reason?: string | null;
|
|
290
|
+
aggregate_eligible?: boolean | null;
|
|
291
|
+
aggregate_reason?: string | null;
|
|
292
|
+
aggregate_threshold_percent?: number | null;
|
|
273
293
|
effective_end_at?: string | null;
|
|
274
294
|
computed_at?: string | null;
|
|
275
295
|
}
|
|
@@ -279,6 +299,9 @@ interface KpiSignal {
|
|
|
279
299
|
weight?: number | null;
|
|
280
300
|
mode?: KpiSignalMode;
|
|
281
301
|
reason?: string | null;
|
|
302
|
+
aggregateEligible?: boolean | null;
|
|
303
|
+
aggregateReason?: string | null;
|
|
304
|
+
aggregateThresholdPercent?: number | null;
|
|
282
305
|
effectiveEndAt?: string | null;
|
|
283
306
|
computedAt?: string | null;
|
|
284
307
|
}
|
|
@@ -471,4 +494,4 @@ interface RecentFlowSnapshotGridProps {
|
|
|
471
494
|
}
|
|
472
495
|
declare const RecentFlowSnapshotGrid: React__default.FC<RecentFlowSnapshotGridProps>;
|
|
473
496
|
|
|
474
|
-
export { type ActionThreshold as A, type CurrentWorkspaceSKU as C, type DashboardKPIs as D, type EfficiencyLegendUpdate as E, type KpiTrend as K, type LineSignal as L, type MonthlyTrendSummary as M, type PoorPerformingWorkspace as P, type RecentFlowSnapshotGridProps as R, type SkuBreakdownItem as S, type VideoGridMetricMode as V, type WorkspaceMetrics as W, type LineInfo as a, type WorkspaceDetailedMetrics as b, type SkuSegmentItem as c, type LineSkuBreakdownItem as d, type WorkspaceVideoStream as e, type Workspace as f, type WorkspaceCameraIpInfo as g, type WorkspaceActionUpdate as h, type ShiftConfiguration as i, type KpiSignal as j, type LineIssueResolutionSummary as k, type LineDetailedMetrics as l, type
|
|
497
|
+
export { type ActionThreshold as A, RecentFlowSnapshotGrid as B, type CurrentWorkspaceSKU as C, type DashboardKPIs as D, type EfficiencyLegendUpdate as E, type KpiTrend as K, type LineSignal as L, type MonthlyTrendSummary as M, type PoorPerformingWorkspace as P, type RecentFlowSnapshotGridProps as R, type SkuBreakdownItem as S, type VideoGridMetricMode as V, type WorkspaceMetrics as W, type LineInfo as a, type WorkspaceDetailedMetrics as b, type SkuSegmentItem as c, type LineSkuBreakdownItem as d, type WorkspaceVideoStream as e, type Workspace as f, type WorkspaceCameraIpInfo as g, type WorkspaceActionUpdate as h, type ShiftConfiguration as i, type KpiSignal as j, type LineIssueResolutionSummary as k, type LineDetailedMetrics as l, type VideoGridStatusBadge as m, type LineSignalSource as n, type KpiSignalSource as o, type KpiSignalMode as p, type ValueDelta as q, type PercentageDelta as r, type CountDelta as s, type DurationDelta as t, type WorkspaceCropRect as u, type LineThreshold as v, type ShiftConfigurationRecord as w, normalizeVideoGridMetricMode as x, isRecentFlowVideoGridMetricMode as y, isWipGatedVideoGridMetricMode as z };
|
package/dist/automation.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { B as RecentFlowSnapshotGrid, R as RecentFlowSnapshotGridProps, W as WorkspaceMetrics, e as WorkspaceVideoStream } from './automation-Jf6Isg6G.mjs';
|
|
2
2
|
import 'react';
|
package/dist/automation.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { B as RecentFlowSnapshotGrid, R as RecentFlowSnapshotGridProps, W as WorkspaceMetrics, e as WorkspaceVideoStream } from './automation-Jf6Isg6G.js';
|
|
2
2
|
import 'react';
|
package/dist/automation.js
CHANGED
|
@@ -1734,6 +1734,99 @@ var trackCoreEvent = (eventName, properties) => {
|
|
|
1734
1734
|
return;
|
|
1735
1735
|
}
|
|
1736
1736
|
};
|
|
1737
|
+
var DEFAULT_PALETTE_TOKEN = "slate";
|
|
1738
|
+
var DEFAULT_ICON_TOKEN = "help-circle";
|
|
1739
|
+
var PALETTE_CONFIG = {
|
|
1740
|
+
red: {
|
|
1741
|
+
hex: "#dc2626",
|
|
1742
|
+
textClass: "text-red-600",
|
|
1743
|
+
bgClass: "bg-red-50",
|
|
1744
|
+
borderClass: "border-red-200"
|
|
1745
|
+
},
|
|
1746
|
+
amber: {
|
|
1747
|
+
hex: "#f59e0b",
|
|
1748
|
+
textClass: "text-amber-600",
|
|
1749
|
+
bgClass: "bg-amber-50",
|
|
1750
|
+
borderClass: "border-amber-200"
|
|
1751
|
+
},
|
|
1752
|
+
blue: {
|
|
1753
|
+
hex: "#3b82f6",
|
|
1754
|
+
textClass: "text-blue-600",
|
|
1755
|
+
bgClass: "bg-blue-50",
|
|
1756
|
+
borderClass: "border-blue-200"
|
|
1757
|
+
},
|
|
1758
|
+
violet: {
|
|
1759
|
+
hex: "#8b5cf6",
|
|
1760
|
+
textClass: "text-violet-600",
|
|
1761
|
+
bgClass: "bg-violet-50",
|
|
1762
|
+
borderClass: "border-violet-200"
|
|
1763
|
+
},
|
|
1764
|
+
emerald: {
|
|
1765
|
+
hex: "#10b981",
|
|
1766
|
+
textClass: "text-emerald-600",
|
|
1767
|
+
bgClass: "bg-emerald-50",
|
|
1768
|
+
borderClass: "border-emerald-200"
|
|
1769
|
+
},
|
|
1770
|
+
cyan: {
|
|
1771
|
+
hex: "#0891b2",
|
|
1772
|
+
textClass: "text-cyan-600",
|
|
1773
|
+
bgClass: "bg-cyan-50",
|
|
1774
|
+
borderClass: "border-cyan-200"
|
|
1775
|
+
},
|
|
1776
|
+
slate: {
|
|
1777
|
+
hex: "#64748b",
|
|
1778
|
+
textClass: "text-slate-600",
|
|
1779
|
+
bgClass: "bg-slate-50",
|
|
1780
|
+
borderClass: "border-slate-200"
|
|
1781
|
+
}
|
|
1782
|
+
};
|
|
1783
|
+
var ICON_CONFIG = {
|
|
1784
|
+
"alert-triangle": lucideReact.AlertTriangle,
|
|
1785
|
+
"refresh-cw": lucideReact.RefreshCw,
|
|
1786
|
+
package: lucideReact.Package,
|
|
1787
|
+
clock: lucideReact.Clock,
|
|
1788
|
+
"user-x": lucideReact.UserX,
|
|
1789
|
+
wrench: lucideReact.Wrench,
|
|
1790
|
+
activity: lucideReact.Activity,
|
|
1791
|
+
"clipboard-x": lucideReact.ClipboardX,
|
|
1792
|
+
"help-circle": lucideReact.HelpCircle
|
|
1793
|
+
};
|
|
1794
|
+
var humanizeIdleReasonLabel = (value) => {
|
|
1795
|
+
const text = String(value || "").trim();
|
|
1796
|
+
if (!text) {
|
|
1797
|
+
return "Unknown";
|
|
1798
|
+
}
|
|
1799
|
+
return text.replace(/_/g, " ").split(/\s+/).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
1800
|
+
};
|
|
1801
|
+
var normalizePaletteToken = (value) => {
|
|
1802
|
+
const token = String(value || "").trim().toLowerCase();
|
|
1803
|
+
if (token in PALETTE_CONFIG) {
|
|
1804
|
+
return token;
|
|
1805
|
+
}
|
|
1806
|
+
return DEFAULT_PALETTE_TOKEN;
|
|
1807
|
+
};
|
|
1808
|
+
var normalizeIconToken = (value) => {
|
|
1809
|
+
const token = String(value || "").trim().toLowerCase();
|
|
1810
|
+
if (token in ICON_CONFIG) {
|
|
1811
|
+
return token;
|
|
1812
|
+
}
|
|
1813
|
+
return DEFAULT_ICON_TOKEN;
|
|
1814
|
+
};
|
|
1815
|
+
var getIdleReasonPresentation = (metadata) => {
|
|
1816
|
+
const label = typeof metadata?.label === "string" && metadata.label.trim() ? metadata.label.trim() : null;
|
|
1817
|
+
const displayName = typeof metadata?.displayName === "string" && metadata.displayName.trim() ? metadata.displayName.trim() : humanizeIdleReasonLabel(label);
|
|
1818
|
+
const paletteToken = normalizePaletteToken(metadata?.paletteToken);
|
|
1819
|
+
const iconToken = normalizeIconToken(metadata?.iconToken);
|
|
1820
|
+
return {
|
|
1821
|
+
label,
|
|
1822
|
+
displayName,
|
|
1823
|
+
paletteToken,
|
|
1824
|
+
iconToken,
|
|
1825
|
+
isKnown: Boolean(metadata?.isKnown),
|
|
1826
|
+
Icon: ICON_CONFIG[iconToken],
|
|
1827
|
+
...PALETTE_CONFIG[paletteToken]
|
|
1828
|
+
};
|
|
1829
|
+
};
|
|
1737
1830
|
|
|
1738
1831
|
// src/lib/constants/videoGridMetricMode.ts
|
|
1739
1832
|
var VALID_VIDEO_GRID_METRIC_MODES = /* @__PURE__ */ new Set([
|
|
@@ -1875,6 +1968,20 @@ var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND, blu
|
|
|
1875
1968
|
}
|
|
1876
1969
|
return baseColor;
|
|
1877
1970
|
};
|
|
1971
|
+
var getStatusBadgeSignature = (workspace) => {
|
|
1972
|
+
const badges = workspace.video_grid_badges || [];
|
|
1973
|
+
return badges.map((badge) => [
|
|
1974
|
+
badge.kind,
|
|
1975
|
+
badge.label,
|
|
1976
|
+
badge.display_name,
|
|
1977
|
+
badge.palette_token,
|
|
1978
|
+
badge.icon_token,
|
|
1979
|
+
badge.anchor_minute,
|
|
1980
|
+
badge.reason_minute,
|
|
1981
|
+
badge.shift_elapsed_fraction,
|
|
1982
|
+
badge.title
|
|
1983
|
+
].join(":")).join("|");
|
|
1984
|
+
};
|
|
1878
1985
|
function getTrendArrowAndColor(trend) {
|
|
1879
1986
|
if (trend > 0) {
|
|
1880
1987
|
return { arrow: "\u2191", color: "text-green-400" };
|
|
@@ -1906,6 +2013,7 @@ var VideoCard = React__default.default.memo(({
|
|
|
1906
2013
|
}) => {
|
|
1907
2014
|
const videoRef = React.useRef(null);
|
|
1908
2015
|
const canvasRef = React.useRef(null);
|
|
2016
|
+
const statusBadgeIdPrefix = React.useId();
|
|
1909
2017
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
1910
2018
|
const { isStale: isStreamStale } = useHlsStreamWithCropping(videoRef, canvasRef, {
|
|
1911
2019
|
src: hlsUrl,
|
|
@@ -1932,6 +2040,7 @@ var VideoCard = React__default.default.memo(({
|
|
|
1932
2040
|
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
1933
2041
|
const badgeTitle = isHighEfficiencyOverride ? `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%` : hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
1934
2042
|
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
2043
|
+
const statusBadges = workspace.video_grid_badges || [];
|
|
1935
2044
|
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "blue" ? "bg-[#0EA5E9]/30" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
1936
2045
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "blue" ? "bg-[#0EA5E9]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
1937
2046
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "blue" ? "Best" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
@@ -2010,6 +2119,61 @@ var VideoCard = React__default.default.memo(({
|
|
|
2010
2119
|
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${compact ? "text-[10px]" : "text-xs"} font-semibold`, children: badgeLabel })
|
|
2011
2120
|
}
|
|
2012
2121
|
) }),
|
|
2122
|
+
statusBadges.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2123
|
+
"div",
|
|
2124
|
+
{
|
|
2125
|
+
"data-testid": "video-card-status-badges",
|
|
2126
|
+
className: `absolute ${compact ? "top-1.5 left-1.5 gap-1" : "top-2 left-2 gap-1.5"} z-30 flex items-center`,
|
|
2127
|
+
children: statusBadges.map((badge, index) => {
|
|
2128
|
+
const presentation = getIdleReasonPresentation({
|
|
2129
|
+
label: badge.label,
|
|
2130
|
+
displayName: badge.display_name,
|
|
2131
|
+
paletteToken: badge.palette_token,
|
|
2132
|
+
iconToken: badge.icon_token,
|
|
2133
|
+
isKnown: badge.is_known
|
|
2134
|
+
});
|
|
2135
|
+
const Icon = presentation.Icon;
|
|
2136
|
+
const tooltipText = presentation.displayName;
|
|
2137
|
+
const tooltipId = `video-card-status-tooltip-${statusBadgeIdPrefix}-${badge.kind}-${index}`;
|
|
2138
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2139
|
+
"div",
|
|
2140
|
+
{
|
|
2141
|
+
"data-testid": `video-card-status-badge-${badge.kind}`,
|
|
2142
|
+
"aria-label": tooltipText,
|
|
2143
|
+
"aria-describedby": tooltipId,
|
|
2144
|
+
className: `group relative inline-flex shrink-0 items-center justify-center rounded-full bg-slate-950/70 border-2 shadow-[0_3px_10px_rgba(0,0,0,0.34),inset_0_0_0_1px_rgba(255,255,255,0.18)] ${compact ? "h-10 w-10" : "h-11 w-11"}`,
|
|
2145
|
+
style: {
|
|
2146
|
+
borderColor: presentation.hex
|
|
2147
|
+
},
|
|
2148
|
+
children: [
|
|
2149
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2150
|
+
Icon,
|
|
2151
|
+
{
|
|
2152
|
+
"aria-hidden": "true",
|
|
2153
|
+
className: `${compact ? "h-5 w-5" : "h-6 w-6"} text-white`,
|
|
2154
|
+
strokeWidth: 2.4
|
|
2155
|
+
}
|
|
2156
|
+
),
|
|
2157
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2158
|
+
"span",
|
|
2159
|
+
{
|
|
2160
|
+
id: tooltipId,
|
|
2161
|
+
role: "tooltip",
|
|
2162
|
+
"data-testid": `video-card-status-tooltip-${badge.kind}`,
|
|
2163
|
+
className: "pointer-events-none absolute left-0 top-full mt-2 whitespace-nowrap rounded-md border border-white/10 bg-slate-950/95 px-2 py-1 text-[11px] font-semibold leading-none text-white opacity-0 shadow-[0_6px_18px_rgba(0,0,0,0.34)] transition-opacity duration-150 group-hover:opacity-100",
|
|
2164
|
+
children: [
|
|
2165
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-1 left-3 h-2 w-2 rotate-45 border-l border-t border-white/10 bg-slate-950/95" }),
|
|
2166
|
+
tooltipText
|
|
2167
|
+
]
|
|
2168
|
+
}
|
|
2169
|
+
)
|
|
2170
|
+
]
|
|
2171
|
+
},
|
|
2172
|
+
`${badge.kind}-${badge.label || index}-${badge.reason_minute ?? index}`
|
|
2173
|
+
);
|
|
2174
|
+
})
|
|
2175
|
+
}
|
|
2176
|
+
),
|
|
2013
2177
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute bottom-0 left-0 right-0 ${compact ? "h-0.5" : "h-1"} bg-black/50 z-30`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2014
2178
|
"div",
|
|
2015
2179
|
{
|
|
@@ -2046,7 +2210,7 @@ var VideoCard = React__default.default.memo(({
|
|
|
2046
2210
|
}
|
|
2047
2211
|
);
|
|
2048
2212
|
}, (prevProps, nextProps) => {
|
|
2049
|
-
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.recent_flow_forced_zero_after_shift !== nextProps.workspace.recent_flow_forced_zero_after_shift || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
2213
|
+
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.recent_flow_forced_zero_after_shift !== nextProps.workspace.recent_flow_forced_zero_after_shift || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || getStatusBadgeSignature(prevProps.workspace) !== getStatusBadgeSignature(nextProps.workspace) || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
2050
2214
|
return false;
|
|
2051
2215
|
}
|
|
2052
2216
|
if (prevProps.workspace.workspace_uuid !== nextProps.workspace.workspace_uuid || prevProps.workspace.workspace_name !== nextProps.workspace.workspace_name || prevProps.workspace.line_id !== nextProps.workspace.line_id) {
|
package/dist/automation.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React, { useRef, useCallback, useEffect, useState, useMemo } from 'react';
|
|
2
|
-
import { Camera, AlertTriangle } from 'lucide-react';
|
|
1
|
+
import React, { useRef, useId, useCallback, useEffect, useState, useMemo } from 'react';
|
|
2
|
+
import { Camera, AlertTriangle, HelpCircle, ClipboardX, Activity, Wrench, UserX, Clock, Package, RefreshCw } from 'lucide-react';
|
|
3
3
|
import Hls from 'hls.js';
|
|
4
4
|
import 'mixpanel-browser';
|
|
5
5
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -1727,6 +1727,99 @@ var trackCoreEvent = (eventName, properties) => {
|
|
|
1727
1727
|
return;
|
|
1728
1728
|
}
|
|
1729
1729
|
};
|
|
1730
|
+
var DEFAULT_PALETTE_TOKEN = "slate";
|
|
1731
|
+
var DEFAULT_ICON_TOKEN = "help-circle";
|
|
1732
|
+
var PALETTE_CONFIG = {
|
|
1733
|
+
red: {
|
|
1734
|
+
hex: "#dc2626",
|
|
1735
|
+
textClass: "text-red-600",
|
|
1736
|
+
bgClass: "bg-red-50",
|
|
1737
|
+
borderClass: "border-red-200"
|
|
1738
|
+
},
|
|
1739
|
+
amber: {
|
|
1740
|
+
hex: "#f59e0b",
|
|
1741
|
+
textClass: "text-amber-600",
|
|
1742
|
+
bgClass: "bg-amber-50",
|
|
1743
|
+
borderClass: "border-amber-200"
|
|
1744
|
+
},
|
|
1745
|
+
blue: {
|
|
1746
|
+
hex: "#3b82f6",
|
|
1747
|
+
textClass: "text-blue-600",
|
|
1748
|
+
bgClass: "bg-blue-50",
|
|
1749
|
+
borderClass: "border-blue-200"
|
|
1750
|
+
},
|
|
1751
|
+
violet: {
|
|
1752
|
+
hex: "#8b5cf6",
|
|
1753
|
+
textClass: "text-violet-600",
|
|
1754
|
+
bgClass: "bg-violet-50",
|
|
1755
|
+
borderClass: "border-violet-200"
|
|
1756
|
+
},
|
|
1757
|
+
emerald: {
|
|
1758
|
+
hex: "#10b981",
|
|
1759
|
+
textClass: "text-emerald-600",
|
|
1760
|
+
bgClass: "bg-emerald-50",
|
|
1761
|
+
borderClass: "border-emerald-200"
|
|
1762
|
+
},
|
|
1763
|
+
cyan: {
|
|
1764
|
+
hex: "#0891b2",
|
|
1765
|
+
textClass: "text-cyan-600",
|
|
1766
|
+
bgClass: "bg-cyan-50",
|
|
1767
|
+
borderClass: "border-cyan-200"
|
|
1768
|
+
},
|
|
1769
|
+
slate: {
|
|
1770
|
+
hex: "#64748b",
|
|
1771
|
+
textClass: "text-slate-600",
|
|
1772
|
+
bgClass: "bg-slate-50",
|
|
1773
|
+
borderClass: "border-slate-200"
|
|
1774
|
+
}
|
|
1775
|
+
};
|
|
1776
|
+
var ICON_CONFIG = {
|
|
1777
|
+
"alert-triangle": AlertTriangle,
|
|
1778
|
+
"refresh-cw": RefreshCw,
|
|
1779
|
+
package: Package,
|
|
1780
|
+
clock: Clock,
|
|
1781
|
+
"user-x": UserX,
|
|
1782
|
+
wrench: Wrench,
|
|
1783
|
+
activity: Activity,
|
|
1784
|
+
"clipboard-x": ClipboardX,
|
|
1785
|
+
"help-circle": HelpCircle
|
|
1786
|
+
};
|
|
1787
|
+
var humanizeIdleReasonLabel = (value) => {
|
|
1788
|
+
const text = String(value || "").trim();
|
|
1789
|
+
if (!text) {
|
|
1790
|
+
return "Unknown";
|
|
1791
|
+
}
|
|
1792
|
+
return text.replace(/_/g, " ").split(/\s+/).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
1793
|
+
};
|
|
1794
|
+
var normalizePaletteToken = (value) => {
|
|
1795
|
+
const token = String(value || "").trim().toLowerCase();
|
|
1796
|
+
if (token in PALETTE_CONFIG) {
|
|
1797
|
+
return token;
|
|
1798
|
+
}
|
|
1799
|
+
return DEFAULT_PALETTE_TOKEN;
|
|
1800
|
+
};
|
|
1801
|
+
var normalizeIconToken = (value) => {
|
|
1802
|
+
const token = String(value || "").trim().toLowerCase();
|
|
1803
|
+
if (token in ICON_CONFIG) {
|
|
1804
|
+
return token;
|
|
1805
|
+
}
|
|
1806
|
+
return DEFAULT_ICON_TOKEN;
|
|
1807
|
+
};
|
|
1808
|
+
var getIdleReasonPresentation = (metadata) => {
|
|
1809
|
+
const label = typeof metadata?.label === "string" && metadata.label.trim() ? metadata.label.trim() : null;
|
|
1810
|
+
const displayName = typeof metadata?.displayName === "string" && metadata.displayName.trim() ? metadata.displayName.trim() : humanizeIdleReasonLabel(label);
|
|
1811
|
+
const paletteToken = normalizePaletteToken(metadata?.paletteToken);
|
|
1812
|
+
const iconToken = normalizeIconToken(metadata?.iconToken);
|
|
1813
|
+
return {
|
|
1814
|
+
label,
|
|
1815
|
+
displayName,
|
|
1816
|
+
paletteToken,
|
|
1817
|
+
iconToken,
|
|
1818
|
+
isKnown: Boolean(metadata?.isKnown),
|
|
1819
|
+
Icon: ICON_CONFIG[iconToken],
|
|
1820
|
+
...PALETTE_CONFIG[paletteToken]
|
|
1821
|
+
};
|
|
1822
|
+
};
|
|
1730
1823
|
|
|
1731
1824
|
// src/lib/constants/videoGridMetricMode.ts
|
|
1732
1825
|
var VALID_VIDEO_GRID_METRIC_MODES = /* @__PURE__ */ new Set([
|
|
@@ -1868,6 +1961,20 @@ var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND, blu
|
|
|
1868
1961
|
}
|
|
1869
1962
|
return baseColor;
|
|
1870
1963
|
};
|
|
1964
|
+
var getStatusBadgeSignature = (workspace) => {
|
|
1965
|
+
const badges = workspace.video_grid_badges || [];
|
|
1966
|
+
return badges.map((badge) => [
|
|
1967
|
+
badge.kind,
|
|
1968
|
+
badge.label,
|
|
1969
|
+
badge.display_name,
|
|
1970
|
+
badge.palette_token,
|
|
1971
|
+
badge.icon_token,
|
|
1972
|
+
badge.anchor_minute,
|
|
1973
|
+
badge.reason_minute,
|
|
1974
|
+
badge.shift_elapsed_fraction,
|
|
1975
|
+
badge.title
|
|
1976
|
+
].join(":")).join("|");
|
|
1977
|
+
};
|
|
1871
1978
|
function getTrendArrowAndColor(trend) {
|
|
1872
1979
|
if (trend > 0) {
|
|
1873
1980
|
return { arrow: "\u2191", color: "text-green-400" };
|
|
@@ -1899,6 +2006,7 @@ var VideoCard = React.memo(({
|
|
|
1899
2006
|
}) => {
|
|
1900
2007
|
const videoRef = useRef(null);
|
|
1901
2008
|
const canvasRef = useRef(null);
|
|
2009
|
+
const statusBadgeIdPrefix = useId();
|
|
1902
2010
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
1903
2011
|
const { isStale: isStreamStale } = useHlsStreamWithCropping(videoRef, canvasRef, {
|
|
1904
2012
|
src: hlsUrl,
|
|
@@ -1925,6 +2033,7 @@ var VideoCard = React.memo(({
|
|
|
1925
2033
|
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
1926
2034
|
const badgeTitle = isHighEfficiencyOverride ? `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%` : hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
1927
2035
|
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
2036
|
+
const statusBadges = workspace.video_grid_badges || [];
|
|
1928
2037
|
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "blue" ? "bg-[#0EA5E9]/30" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
1929
2038
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "blue" ? "bg-[#0EA5E9]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
1930
2039
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "blue" ? "Best" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
@@ -2003,6 +2112,61 @@ var VideoCard = React.memo(({
|
|
|
2003
2112
|
children: /* @__PURE__ */ jsx("span", { className: `${compact ? "text-[10px]" : "text-xs"} font-semibold`, children: badgeLabel })
|
|
2004
2113
|
}
|
|
2005
2114
|
) }),
|
|
2115
|
+
statusBadges.length > 0 && /* @__PURE__ */ jsx(
|
|
2116
|
+
"div",
|
|
2117
|
+
{
|
|
2118
|
+
"data-testid": "video-card-status-badges",
|
|
2119
|
+
className: `absolute ${compact ? "top-1.5 left-1.5 gap-1" : "top-2 left-2 gap-1.5"} z-30 flex items-center`,
|
|
2120
|
+
children: statusBadges.map((badge, index) => {
|
|
2121
|
+
const presentation = getIdleReasonPresentation({
|
|
2122
|
+
label: badge.label,
|
|
2123
|
+
displayName: badge.display_name,
|
|
2124
|
+
paletteToken: badge.palette_token,
|
|
2125
|
+
iconToken: badge.icon_token,
|
|
2126
|
+
isKnown: badge.is_known
|
|
2127
|
+
});
|
|
2128
|
+
const Icon = presentation.Icon;
|
|
2129
|
+
const tooltipText = presentation.displayName;
|
|
2130
|
+
const tooltipId = `video-card-status-tooltip-${statusBadgeIdPrefix}-${badge.kind}-${index}`;
|
|
2131
|
+
return /* @__PURE__ */ jsxs(
|
|
2132
|
+
"div",
|
|
2133
|
+
{
|
|
2134
|
+
"data-testid": `video-card-status-badge-${badge.kind}`,
|
|
2135
|
+
"aria-label": tooltipText,
|
|
2136
|
+
"aria-describedby": tooltipId,
|
|
2137
|
+
className: `group relative inline-flex shrink-0 items-center justify-center rounded-full bg-slate-950/70 border-2 shadow-[0_3px_10px_rgba(0,0,0,0.34),inset_0_0_0_1px_rgba(255,255,255,0.18)] ${compact ? "h-10 w-10" : "h-11 w-11"}`,
|
|
2138
|
+
style: {
|
|
2139
|
+
borderColor: presentation.hex
|
|
2140
|
+
},
|
|
2141
|
+
children: [
|
|
2142
|
+
/* @__PURE__ */ jsx(
|
|
2143
|
+
Icon,
|
|
2144
|
+
{
|
|
2145
|
+
"aria-hidden": "true",
|
|
2146
|
+
className: `${compact ? "h-5 w-5" : "h-6 w-6"} text-white`,
|
|
2147
|
+
strokeWidth: 2.4
|
|
2148
|
+
}
|
|
2149
|
+
),
|
|
2150
|
+
/* @__PURE__ */ jsxs(
|
|
2151
|
+
"span",
|
|
2152
|
+
{
|
|
2153
|
+
id: tooltipId,
|
|
2154
|
+
role: "tooltip",
|
|
2155
|
+
"data-testid": `video-card-status-tooltip-${badge.kind}`,
|
|
2156
|
+
className: "pointer-events-none absolute left-0 top-full mt-2 whitespace-nowrap rounded-md border border-white/10 bg-slate-950/95 px-2 py-1 text-[11px] font-semibold leading-none text-white opacity-0 shadow-[0_6px_18px_rgba(0,0,0,0.34)] transition-opacity duration-150 group-hover:opacity-100",
|
|
2157
|
+
children: [
|
|
2158
|
+
/* @__PURE__ */ jsx("span", { className: "absolute -top-1 left-3 h-2 w-2 rotate-45 border-l border-t border-white/10 bg-slate-950/95" }),
|
|
2159
|
+
tooltipText
|
|
2160
|
+
]
|
|
2161
|
+
}
|
|
2162
|
+
)
|
|
2163
|
+
]
|
|
2164
|
+
},
|
|
2165
|
+
`${badge.kind}-${badge.label || index}-${badge.reason_minute ?? index}`
|
|
2166
|
+
);
|
|
2167
|
+
})
|
|
2168
|
+
}
|
|
2169
|
+
),
|
|
2006
2170
|
/* @__PURE__ */ jsx("div", { className: `absolute bottom-0 left-0 right-0 ${compact ? "h-0.5" : "h-1"} bg-black/50 z-30`, children: /* @__PURE__ */ jsx(
|
|
2007
2171
|
"div",
|
|
2008
2172
|
{
|
|
@@ -2039,7 +2203,7 @@ var VideoCard = React.memo(({
|
|
|
2039
2203
|
}
|
|
2040
2204
|
);
|
|
2041
2205
|
}, (prevProps, nextProps) => {
|
|
2042
|
-
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.recent_flow_forced_zero_after_shift !== nextProps.workspace.recent_flow_forced_zero_after_shift || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
2206
|
+
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.recent_flow_forced_zero_after_shift !== nextProps.workspace.recent_flow_forced_zero_after_shift || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || getStatusBadgeSignature(prevProps.workspace) !== getStatusBadgeSignature(nextProps.workspace) || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
2043
2207
|
return false;
|
|
2044
2208
|
}
|
|
2045
2209
|
if (prevProps.workspace.workspace_uuid !== nextProps.workspace.workspace_uuid || prevProps.workspace.workspace_name !== nextProps.workspace.workspace_name || prevProps.workspace.line_id !== nextProps.workspace.line_id) {
|
package/dist/index.css
CHANGED
|
@@ -538,6 +538,9 @@ body {
|
|
|
538
538
|
.left-1 {
|
|
539
539
|
left: 0.25rem;
|
|
540
540
|
}
|
|
541
|
+
.left-1\.5 {
|
|
542
|
+
left: 0.375rem;
|
|
543
|
+
}
|
|
541
544
|
.left-1\/2 {
|
|
542
545
|
left: 50%;
|
|
543
546
|
}
|
|
@@ -595,6 +598,9 @@ body {
|
|
|
595
598
|
.top-1 {
|
|
596
599
|
top: 0.25rem;
|
|
597
600
|
}
|
|
601
|
+
.top-1\.5 {
|
|
602
|
+
top: 0.375rem;
|
|
603
|
+
}
|
|
598
604
|
.top-1\/2 {
|
|
599
605
|
top: 50%;
|
|
600
606
|
}
|
|
@@ -1740,6 +1746,10 @@ body {
|
|
|
1740
1746
|
--tw-rotate: 180deg;
|
|
1741
1747
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
1742
1748
|
}
|
|
1749
|
+
.rotate-45 {
|
|
1750
|
+
--tw-rotate: 45deg;
|
|
1751
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
1752
|
+
}
|
|
1743
1753
|
.scale-0 {
|
|
1744
1754
|
--tw-scale-x: 0;
|
|
1745
1755
|
--tw-scale-y: 0;
|
|
@@ -2261,6 +2271,9 @@ body {
|
|
|
2261
2271
|
.border-b-\[6px\] {
|
|
2262
2272
|
border-bottom-width: 6px;
|
|
2263
2273
|
}
|
|
2274
|
+
.border-l {
|
|
2275
|
+
border-left-width: 1px;
|
|
2276
|
+
}
|
|
2264
2277
|
.border-l-2 {
|
|
2265
2278
|
border-left-width: 2px;
|
|
2266
2279
|
}
|
|
@@ -3091,6 +3104,12 @@ body {
|
|
|
3091
3104
|
.bg-slate-900\/60 {
|
|
3092
3105
|
background-color: rgb(15 23 42 / 0.6);
|
|
3093
3106
|
}
|
|
3107
|
+
.bg-slate-950\/70 {
|
|
3108
|
+
background-color: rgb(2 6 23 / 0.7);
|
|
3109
|
+
}
|
|
3110
|
+
.bg-slate-950\/95 {
|
|
3111
|
+
background-color: rgb(2 6 23 / 0.95);
|
|
3112
|
+
}
|
|
3094
3113
|
.bg-teal-100 {
|
|
3095
3114
|
--tw-bg-opacity: 1;
|
|
3096
3115
|
background-color: rgb(204 251 241 / var(--tw-bg-opacity, 1));
|
|
@@ -4974,6 +4993,22 @@ body {
|
|
|
4974
4993
|
var(--tw-ring-shadow, 0 0 #0000),
|
|
4975
4994
|
var(--tw-shadow);
|
|
4976
4995
|
}
|
|
4996
|
+
.shadow-\[0_3px_10px_rgba\(0\,0\,0\,0\.34\)\,inset_0_0_0_1px_rgba\(255\,255\,255\,0\.18\)\] {
|
|
4997
|
+
--tw-shadow: 0 3px 10px rgba(0,0,0,0.34),inset 0 0 0 1px rgba(255,255,255,0.18);
|
|
4998
|
+
--tw-shadow-colored: 0 3px 10px var(--tw-shadow-color), inset 0 0 0 1px var(--tw-shadow-color);
|
|
4999
|
+
box-shadow:
|
|
5000
|
+
var(--tw-ring-offset-shadow, 0 0 #0000),
|
|
5001
|
+
var(--tw-ring-shadow, 0 0 #0000),
|
|
5002
|
+
var(--tw-shadow);
|
|
5003
|
+
}
|
|
5004
|
+
.shadow-\[0_6px_18px_rgba\(0\,0\,0\,0\.34\)\] {
|
|
5005
|
+
--tw-shadow: 0 6px 18px rgba(0,0,0,0.34);
|
|
5006
|
+
--tw-shadow-colored: 0 6px 18px var(--tw-shadow-color);
|
|
5007
|
+
box-shadow:
|
|
5008
|
+
var(--tw-ring-offset-shadow, 0 0 #0000),
|
|
5009
|
+
var(--tw-ring-shadow, 0 0 #0000),
|
|
5010
|
+
var(--tw-shadow);
|
|
5011
|
+
}
|
|
4977
5012
|
.shadow-inner {
|
|
4978
5013
|
--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
|
4979
5014
|
--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as LineSignal, V as VideoGridMetricMode, W as WorkspaceMetrics, a as LineInfo, b as WorkspaceDetailedMetrics, S as SkuBreakdownItem, c as SkuSegmentItem, d as LineSkuBreakdownItem, E as EfficiencyLegendUpdate, D as DashboardKPIs, P as PoorPerformingWorkspace, e as WorkspaceVideoStream, K as KpiTrend, M as MonthlyTrendSummary, f as Workspace, g as WorkspaceCameraIpInfo, h as WorkspaceActionUpdate, A as ActionThreshold, i as ShiftConfiguration, j as KpiSignal, k as LineIssueResolutionSummary } from './automation-
|
|
2
|
-
export {
|
|
1
|
+
import { L as LineSignal, V as VideoGridMetricMode, W as WorkspaceMetrics, a as LineInfo, b as WorkspaceDetailedMetrics, S as SkuBreakdownItem, c as SkuSegmentItem, d as LineSkuBreakdownItem, E as EfficiencyLegendUpdate, D as DashboardKPIs, P as PoorPerformingWorkspace, e as WorkspaceVideoStream, K as KpiTrend, M as MonthlyTrendSummary, f as Workspace, g as WorkspaceCameraIpInfo, h as WorkspaceActionUpdate, A as ActionThreshold, i as ShiftConfiguration, j as KpiSignal, k as LineIssueResolutionSummary } from './automation-Jf6Isg6G.mjs';
|
|
2
|
+
export { s as CountDelta, C as CurrentWorkspaceSKU, t as DurationDelta, p as KpiSignalMode, o as KpiSignalSource, l as LineDetailedMetrics, n as LineSignalSource, v as LineThreshold, r as PercentageDelta, B as RecentFlowSnapshotGrid, R as RecentFlowSnapshotGridProps, w as ShiftConfigurationRecord, q as ValueDelta, m as VideoGridStatusBadge, u as WorkspaceCropRect, y as isRecentFlowVideoGridMetricMode, z as isWipGatedVideoGridMetricMode, x as normalizeVideoGridMetricMode } from './automation-Jf6Isg6G.mjs';
|
|
3
3
|
import * as _supabase_supabase_js from '@supabase/supabase-js';
|
|
4
4
|
import { SupabaseClient as SupabaseClient$1, Session, User, AuthError } from '@supabase/supabase-js';
|
|
5
5
|
import { LucideProps, Share2, Download } from 'lucide-react';
|
|
@@ -5262,9 +5262,11 @@ declare const pickPreferredLineMetricsRow: (supabase: {
|
|
|
5262
5262
|
* - Aggregates `current_output` and `ideal_output` sum across
|
|
5263
5263
|
* **real-SKU rows only**. Dummy rows contribute 0 — they are skipped
|
|
5264
5264
|
* from that summation set.
|
|
5265
|
-
* - Weighted-average fields (avg_efficiency, avg_cycle_time
|
|
5266
|
-
*
|
|
5267
|
-
*
|
|
5265
|
+
* - Weighted-average fields (avg_efficiency, avg_cycle_time) use per-row
|
|
5266
|
+
* active-minutes as weight; falls back to plain mean when no row has
|
|
5267
|
+
* positive weight.
|
|
5268
|
+
* - `threshold_pph` sums across real rows so it matches the Targets
|
|
5269
|
+
* page/API additive output-family PPH rule.
|
|
5268
5270
|
* - `underperforming_workspaces` is averaged across ACTIVE real rows only
|
|
5269
5271
|
* (real row with `current_output > 0 || ideal_output > 0`), rounded
|
|
5270
5272
|
* half-up to the nearest whole number. Names / UUIDs are deduped unions
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as LineSignal, V as VideoGridMetricMode, W as WorkspaceMetrics, a as LineInfo, b as WorkspaceDetailedMetrics, S as SkuBreakdownItem, c as SkuSegmentItem, d as LineSkuBreakdownItem, E as EfficiencyLegendUpdate, D as DashboardKPIs, P as PoorPerformingWorkspace, e as WorkspaceVideoStream, K as KpiTrend, M as MonthlyTrendSummary, f as Workspace, g as WorkspaceCameraIpInfo, h as WorkspaceActionUpdate, A as ActionThreshold, i as ShiftConfiguration, j as KpiSignal, k as LineIssueResolutionSummary } from './automation-
|
|
2
|
-
export {
|
|
1
|
+
import { L as LineSignal, V as VideoGridMetricMode, W as WorkspaceMetrics, a as LineInfo, b as WorkspaceDetailedMetrics, S as SkuBreakdownItem, c as SkuSegmentItem, d as LineSkuBreakdownItem, E as EfficiencyLegendUpdate, D as DashboardKPIs, P as PoorPerformingWorkspace, e as WorkspaceVideoStream, K as KpiTrend, M as MonthlyTrendSummary, f as Workspace, g as WorkspaceCameraIpInfo, h as WorkspaceActionUpdate, A as ActionThreshold, i as ShiftConfiguration, j as KpiSignal, k as LineIssueResolutionSummary } from './automation-Jf6Isg6G.js';
|
|
2
|
+
export { s as CountDelta, C as CurrentWorkspaceSKU, t as DurationDelta, p as KpiSignalMode, o as KpiSignalSource, l as LineDetailedMetrics, n as LineSignalSource, v as LineThreshold, r as PercentageDelta, B as RecentFlowSnapshotGrid, R as RecentFlowSnapshotGridProps, w as ShiftConfigurationRecord, q as ValueDelta, m as VideoGridStatusBadge, u as WorkspaceCropRect, y as isRecentFlowVideoGridMetricMode, z as isWipGatedVideoGridMetricMode, x as normalizeVideoGridMetricMode } from './automation-Jf6Isg6G.js';
|
|
3
3
|
import * as _supabase_supabase_js from '@supabase/supabase-js';
|
|
4
4
|
import { SupabaseClient as SupabaseClient$1, Session, User, AuthError } from '@supabase/supabase-js';
|
|
5
5
|
import { LucideProps, Share2, Download } from 'lucide-react';
|
|
@@ -5262,9 +5262,11 @@ declare const pickPreferredLineMetricsRow: (supabase: {
|
|
|
5262
5262
|
* - Aggregates `current_output` and `ideal_output` sum across
|
|
5263
5263
|
* **real-SKU rows only**. Dummy rows contribute 0 — they are skipped
|
|
5264
5264
|
* from that summation set.
|
|
5265
|
-
* - Weighted-average fields (avg_efficiency, avg_cycle_time
|
|
5266
|
-
*
|
|
5267
|
-
*
|
|
5265
|
+
* - Weighted-average fields (avg_efficiency, avg_cycle_time) use per-row
|
|
5266
|
+
* active-minutes as weight; falls back to plain mean when no row has
|
|
5267
|
+
* positive weight.
|
|
5268
|
+
* - `threshold_pph` sums across real rows so it matches the Targets
|
|
5269
|
+
* page/API additive output-family PPH rule.
|
|
5268
5270
|
* - `underperforming_workspaces` is averaged across ACTIVE real rows only
|
|
5269
5271
|
* (real row with `current_output > 0 || ideal_output > 0`), rounded
|
|
5270
5272
|
* half-up to the nearest whole number. Names / UUIDs are deduped unions
|
package/dist/index.js
CHANGED
|
@@ -4665,7 +4665,10 @@ var combineLineMetricsRows = (rows, dummySkuId) => {
|
|
|
4665
4665
|
};
|
|
4666
4666
|
const avgEfficiency = weighted("avg_efficiency");
|
|
4667
4667
|
const avgCycleTime = weighted("avg_cycle_time");
|
|
4668
|
-
const thresholdPph =
|
|
4668
|
+
const thresholdPph = rowsForAggregation.reduce(
|
|
4669
|
+
(acc, row) => acc + (coerceOptionalNumber(row.threshold_pph) ?? 0),
|
|
4670
|
+
0
|
|
4671
|
+
);
|
|
4669
4672
|
const underperformingWorkspaces = activeRealRows.length > 0 ? roundHalfUpInt(
|
|
4670
4673
|
activeRealRows.reduce(
|
|
4671
4674
|
(acc, row) => acc + safeInt(row.underperforming_workspaces),
|
|
@@ -14716,6 +14719,7 @@ var transformMonitorWorkspaceMetrics = ({
|
|
|
14716
14719
|
monitoring_mode: item.monitoring_mode ?? void 0,
|
|
14717
14720
|
idle_time: idleTimeSeconds,
|
|
14718
14721
|
idle_time_hourly: item.idle_time_hourly ?? null,
|
|
14722
|
+
idle_reason_hourly: item.idle_reason_hourly ?? null,
|
|
14719
14723
|
shift_start: item.shift_start ?? void 0,
|
|
14720
14724
|
shift_end: item.shift_end ?? void 0,
|
|
14721
14725
|
assembly_enabled: item.assembly_enabled ?? false,
|
|
@@ -14751,6 +14755,7 @@ var transformMonitorWorkspaceMetrics = ({
|
|
|
14751
14755
|
incoming_wip_current: item.incoming_wip_current ?? null,
|
|
14752
14756
|
incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
|
|
14753
14757
|
incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null,
|
|
14758
|
+
video_grid_badges: Array.isArray(item.video_grid_badges) ? item.video_grid_badges : [],
|
|
14754
14759
|
show_exclamation: item.show_exclamation ?? void 0
|
|
14755
14760
|
};
|
|
14756
14761
|
workspaceMetricsStore.setOverview(metric);
|
|
@@ -21269,6 +21274,7 @@ var ICON_CONFIG = {
|
|
|
21269
21274
|
"user-x": lucideReact.UserX,
|
|
21270
21275
|
wrench: lucideReact.Wrench,
|
|
21271
21276
|
activity: lucideReact.Activity,
|
|
21277
|
+
"clipboard-x": lucideReact.ClipboardX,
|
|
21272
21278
|
"help-circle": lucideReact.HelpCircle
|
|
21273
21279
|
};
|
|
21274
21280
|
var humanizeIdleReasonLabel = (value) => {
|
|
@@ -22096,7 +22102,7 @@ var normalizeLineSignalSource = (source) => source === "recent_flow" ? "recent_f
|
|
|
22096
22102
|
var normalizeLineSignal = (lineSignal, fallbackEfficiency, fallbackWeight) => {
|
|
22097
22103
|
if (lineSignal && typeof lineSignal === "object") {
|
|
22098
22104
|
const raw = lineSignal;
|
|
22099
|
-
|
|
22105
|
+
const normalized = {
|
|
22100
22106
|
source: normalizeLineSignalSource(raw.source),
|
|
22101
22107
|
percent: toOptionalNumber(raw.percent),
|
|
22102
22108
|
weight: toOptionalNumber(raw.weight),
|
|
@@ -22105,6 +22111,21 @@ var normalizeLineSignal = (lineSignal, fallbackEfficiency, fallbackWeight) => {
|
|
|
22105
22111
|
effectiveEndAt: raw.effective_end_at ?? raw.effectiveEndAt ?? null,
|
|
22106
22112
|
computedAt: raw.computed_at ?? raw.computedAt ?? null
|
|
22107
22113
|
};
|
|
22114
|
+
const aggregateEligible = typeof raw.aggregate_eligible === "boolean" ? raw.aggregate_eligible : typeof raw.aggregateEligible === "boolean" ? raw.aggregateEligible : null;
|
|
22115
|
+
if (aggregateEligible !== null) {
|
|
22116
|
+
normalized.aggregateEligible = aggregateEligible;
|
|
22117
|
+
}
|
|
22118
|
+
const aggregateReason = typeof raw.aggregate_reason === "string" ? raw.aggregate_reason : typeof raw.aggregateReason === "string" ? raw.aggregateReason : null;
|
|
22119
|
+
if (aggregateReason !== null) {
|
|
22120
|
+
normalized.aggregateReason = aggregateReason;
|
|
22121
|
+
}
|
|
22122
|
+
const aggregateThresholdPercent = toOptionalNumber(
|
|
22123
|
+
raw.aggregate_threshold_percent ?? raw.aggregateThresholdPercent
|
|
22124
|
+
);
|
|
22125
|
+
if (aggregateThresholdPercent !== null) {
|
|
22126
|
+
normalized.aggregateThresholdPercent = aggregateThresholdPercent;
|
|
22127
|
+
}
|
|
22128
|
+
return normalized;
|
|
22108
22129
|
}
|
|
22109
22130
|
const percent2 = toOptionalNumber(fallbackEfficiency);
|
|
22110
22131
|
if (percent2 === null) return null;
|
|
@@ -22132,7 +22153,7 @@ var getKpiSignalLabel = (signal, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
|
22132
22153
|
};
|
|
22133
22154
|
var aggregateLineSignals = (signals) => {
|
|
22134
22155
|
const numericSignals = signals.filter(
|
|
22135
|
-
(signal) => signal !== null && signal !== void 0 && toOptionalNumber(signal.percent) !== null
|
|
22156
|
+
(signal) => signal !== null && signal !== void 0 && signal.aggregateEligible !== false && toOptionalNumber(signal.percent) !== null
|
|
22136
22157
|
);
|
|
22137
22158
|
if (numericSignals.length === 0) return null;
|
|
22138
22159
|
const percent2 = numericSignals.reduce(
|
|
@@ -38040,6 +38061,20 @@ var getVideoGridLegendLabel = (workspaces) => {
|
|
|
38040
38061
|
}
|
|
38041
38062
|
return visibleWorkspaces.some(isVideoGridRecentFlowEnabled) ? VIDEO_GRID_LEGEND_LABEL : MAP_GRID_LEGEND_LABEL;
|
|
38042
38063
|
};
|
|
38064
|
+
var getStatusBadgeSignature = (workspace) => {
|
|
38065
|
+
const badges = workspace.video_grid_badges || [];
|
|
38066
|
+
return badges.map((badge) => [
|
|
38067
|
+
badge.kind,
|
|
38068
|
+
badge.label,
|
|
38069
|
+
badge.display_name,
|
|
38070
|
+
badge.palette_token,
|
|
38071
|
+
badge.icon_token,
|
|
38072
|
+
badge.anchor_minute,
|
|
38073
|
+
badge.reason_minute,
|
|
38074
|
+
badge.shift_elapsed_fraction,
|
|
38075
|
+
badge.title
|
|
38076
|
+
].join(":")).join("|");
|
|
38077
|
+
};
|
|
38043
38078
|
function getTrendArrowAndColor(trend) {
|
|
38044
38079
|
if (trend > 0) {
|
|
38045
38080
|
return { arrow: "\u2191", color: "text-green-400" };
|
|
@@ -38071,6 +38106,7 @@ var VideoCard = React144__namespace.default.memo(({
|
|
|
38071
38106
|
}) => {
|
|
38072
38107
|
const videoRef = React144.useRef(null);
|
|
38073
38108
|
const canvasRef = React144.useRef(null);
|
|
38109
|
+
const statusBadgeIdPrefix = React144.useId();
|
|
38074
38110
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
38075
38111
|
const { isStale: isStreamStale } = useHlsStreamWithCropping(videoRef, canvasRef, {
|
|
38076
38112
|
src: hlsUrl,
|
|
@@ -38097,6 +38133,7 @@ var VideoCard = React144__namespace.default.memo(({
|
|
|
38097
38133
|
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
38098
38134
|
const badgeTitle = isHighEfficiencyOverride ? `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%` : hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
38099
38135
|
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
38136
|
+
const statusBadges = workspace.video_grid_badges || [];
|
|
38100
38137
|
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "blue" ? "bg-[#0EA5E9]/30" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
38101
38138
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "blue" ? "bg-[#0EA5E9]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
38102
38139
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "blue" ? "Best" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
@@ -38175,6 +38212,61 @@ var VideoCard = React144__namespace.default.memo(({
|
|
|
38175
38212
|
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${compact ? "text-[10px]" : "text-xs"} font-semibold`, children: badgeLabel })
|
|
38176
38213
|
}
|
|
38177
38214
|
) }),
|
|
38215
|
+
statusBadges.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
38216
|
+
"div",
|
|
38217
|
+
{
|
|
38218
|
+
"data-testid": "video-card-status-badges",
|
|
38219
|
+
className: `absolute ${compact ? "top-1.5 left-1.5 gap-1" : "top-2 left-2 gap-1.5"} z-30 flex items-center`,
|
|
38220
|
+
children: statusBadges.map((badge, index) => {
|
|
38221
|
+
const presentation = getIdleReasonPresentation({
|
|
38222
|
+
label: badge.label,
|
|
38223
|
+
displayName: badge.display_name,
|
|
38224
|
+
paletteToken: badge.palette_token,
|
|
38225
|
+
iconToken: badge.icon_token,
|
|
38226
|
+
isKnown: badge.is_known
|
|
38227
|
+
});
|
|
38228
|
+
const Icon2 = presentation.Icon;
|
|
38229
|
+
const tooltipText = presentation.displayName;
|
|
38230
|
+
const tooltipId = `video-card-status-tooltip-${statusBadgeIdPrefix}-${badge.kind}-${index}`;
|
|
38231
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
38232
|
+
"div",
|
|
38233
|
+
{
|
|
38234
|
+
"data-testid": `video-card-status-badge-${badge.kind}`,
|
|
38235
|
+
"aria-label": tooltipText,
|
|
38236
|
+
"aria-describedby": tooltipId,
|
|
38237
|
+
className: `group relative inline-flex shrink-0 items-center justify-center rounded-full bg-slate-950/70 border-2 shadow-[0_3px_10px_rgba(0,0,0,0.34),inset_0_0_0_1px_rgba(255,255,255,0.18)] ${compact ? "h-10 w-10" : "h-11 w-11"}`,
|
|
38238
|
+
style: {
|
|
38239
|
+
borderColor: presentation.hex
|
|
38240
|
+
},
|
|
38241
|
+
children: [
|
|
38242
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
38243
|
+
Icon2,
|
|
38244
|
+
{
|
|
38245
|
+
"aria-hidden": "true",
|
|
38246
|
+
className: `${compact ? "h-5 w-5" : "h-6 w-6"} text-white`,
|
|
38247
|
+
strokeWidth: 2.4
|
|
38248
|
+
}
|
|
38249
|
+
),
|
|
38250
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
38251
|
+
"span",
|
|
38252
|
+
{
|
|
38253
|
+
id: tooltipId,
|
|
38254
|
+
role: "tooltip",
|
|
38255
|
+
"data-testid": `video-card-status-tooltip-${badge.kind}`,
|
|
38256
|
+
className: "pointer-events-none absolute left-0 top-full mt-2 whitespace-nowrap rounded-md border border-white/10 bg-slate-950/95 px-2 py-1 text-[11px] font-semibold leading-none text-white opacity-0 shadow-[0_6px_18px_rgba(0,0,0,0.34)] transition-opacity duration-150 group-hover:opacity-100",
|
|
38257
|
+
children: [
|
|
38258
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-1 left-3 h-2 w-2 rotate-45 border-l border-t border-white/10 bg-slate-950/95" }),
|
|
38259
|
+
tooltipText
|
|
38260
|
+
]
|
|
38261
|
+
}
|
|
38262
|
+
)
|
|
38263
|
+
]
|
|
38264
|
+
},
|
|
38265
|
+
`${badge.kind}-${badge.label || index}-${badge.reason_minute ?? index}`
|
|
38266
|
+
);
|
|
38267
|
+
})
|
|
38268
|
+
}
|
|
38269
|
+
),
|
|
38178
38270
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `absolute bottom-0 left-0 right-0 ${compact ? "h-0.5" : "h-1"} bg-black/50 z-30`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
38179
38271
|
"div",
|
|
38180
38272
|
{
|
|
@@ -38211,7 +38303,7 @@ var VideoCard = React144__namespace.default.memo(({
|
|
|
38211
38303
|
}
|
|
38212
38304
|
);
|
|
38213
38305
|
}, (prevProps, nextProps) => {
|
|
38214
|
-
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.recent_flow_forced_zero_after_shift !== nextProps.workspace.recent_flow_forced_zero_after_shift || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
38306
|
+
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.recent_flow_forced_zero_after_shift !== nextProps.workspace.recent_flow_forced_zero_after_shift || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || getStatusBadgeSignature(prevProps.workspace) !== getStatusBadgeSignature(nextProps.workspace) || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
38215
38307
|
return false;
|
|
38216
38308
|
}
|
|
38217
38309
|
if (prevProps.workspace.workspace_uuid !== nextProps.workspace.workspace_uuid || prevProps.workspace.workspace_name !== nextProps.workspace.workspace_name || prevProps.workspace.line_id !== nextProps.workspace.line_id) {
|
|
@@ -64837,7 +64929,6 @@ var EMPTY_LINE_IDS = [];
|
|
|
64837
64929
|
var EMPTY_WORKSPACES = [];
|
|
64838
64930
|
var ALL_GREEN_CELEBRATION_DURATION_MS = 6e3;
|
|
64839
64931
|
var ALL_GREEN_MILESTONE_DURATION_MS = 6e3;
|
|
64840
|
-
var ALL_GREEN_STREAK_LOCAL_SECOND_CAP = 59;
|
|
64841
64932
|
var formatAllGreenCelebrationTimer = (elapsedSeconds) => {
|
|
64842
64933
|
const safeElapsedSeconds = Math.max(1, Math.floor(elapsedSeconds));
|
|
64843
64934
|
const minutes = Math.floor(safeElapsedSeconds / 60);
|
|
@@ -64845,10 +64936,7 @@ var formatAllGreenCelebrationTimer = (elapsedSeconds) => {
|
|
|
64845
64936
|
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}s`;
|
|
64846
64937
|
};
|
|
64847
64938
|
var getAllGreenBackendVisibleSeconds = (confirmedSeconds, tickOriginAtMs, nowMs2) => {
|
|
64848
|
-
const localSecondOffset = Math.
|
|
64849
|
-
ALL_GREEN_STREAK_LOCAL_SECOND_CAP,
|
|
64850
|
-
Math.max(0, Math.floor((nowMs2 - tickOriginAtMs) / 1e3))
|
|
64851
|
-
);
|
|
64939
|
+
const localSecondOffset = Math.max(0, Math.floor((nowMs2 - tickOriginAtMs) / 1e3));
|
|
64852
64940
|
return confirmedSeconds + localSecondOffset;
|
|
64853
64941
|
};
|
|
64854
64942
|
var LoadingPageCmp = LoadingPage_default;
|
|
@@ -65308,38 +65396,25 @@ function HomeView({
|
|
|
65308
65396
|
allGreenStreakDisplay.tickOriginAtMs,
|
|
65309
65397
|
currentAllGreenStreakNowMs
|
|
65310
65398
|
);
|
|
65311
|
-
const backendMaxVisibleSeconds = confirmedSeconds + ALL_GREEN_STREAK_LOCAL_SECOND_CAP;
|
|
65312
65399
|
const currentBaseline = allGreenStreakTimerBaselineRef.current;
|
|
65313
65400
|
if (!currentBaseline || currentBaseline.identity !== allGreenMilestoneIdentity) {
|
|
65314
65401
|
allGreenStreakTimerBaselineRef.current = {
|
|
65315
65402
|
identity: allGreenMilestoneIdentity,
|
|
65316
65403
|
baseSeconds: backendVisibleSeconds,
|
|
65317
|
-
baseReceivedAtMs: currentAllGreenStreakNowMs
|
|
65318
|
-
maxVisibleSeconds: backendMaxVisibleSeconds
|
|
65404
|
+
baseReceivedAtMs: currentAllGreenStreakNowMs
|
|
65319
65405
|
};
|
|
65320
65406
|
} else {
|
|
65321
|
-
currentBaseline.
|
|
65322
|
-
currentBaseline.maxVisibleSeconds,
|
|
65323
|
-
backendMaxVisibleSeconds
|
|
65324
|
-
);
|
|
65325
|
-
const visibleSeconds = Math.min(
|
|
65326
|
-
currentBaseline.maxVisibleSeconds,
|
|
65327
|
-
currentBaseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - currentBaseline.baseReceivedAtMs) / 1e3))
|
|
65328
|
-
);
|
|
65407
|
+
const visibleSeconds = currentBaseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - currentBaseline.baseReceivedAtMs) / 1e3));
|
|
65329
65408
|
if (backendVisibleSeconds > visibleSeconds) {
|
|
65330
65409
|
allGreenStreakTimerBaselineRef.current = {
|
|
65331
65410
|
identity: allGreenMilestoneIdentity,
|
|
65332
65411
|
baseSeconds: backendVisibleSeconds,
|
|
65333
|
-
baseReceivedAtMs: currentAllGreenStreakNowMs
|
|
65334
|
-
maxVisibleSeconds: currentBaseline.maxVisibleSeconds
|
|
65412
|
+
baseReceivedAtMs: currentAllGreenStreakNowMs
|
|
65335
65413
|
};
|
|
65336
65414
|
}
|
|
65337
65415
|
}
|
|
65338
65416
|
const baseline = allGreenStreakTimerBaselineRef.current;
|
|
65339
|
-
const elapsedSeconds = baseline ? Math.
|
|
65340
|
-
baseline.maxVisibleSeconds,
|
|
65341
|
-
baseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - baseline.baseReceivedAtMs) / 1e3))
|
|
65342
|
-
) : backendVisibleSeconds;
|
|
65417
|
+
const elapsedSeconds = baseline ? baseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - baseline.baseReceivedAtMs) / 1e3)) : backendVisibleSeconds;
|
|
65343
65418
|
return {
|
|
65344
65419
|
...allGreenStreakDisplay,
|
|
65345
65420
|
elapsedSeconds,
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { format, addDays, subMonths, endOfMonth, startOfMonth, endOfDay, eachDayOfInterval, getDay, isSameDay, isWithinInterval, startOfDay, parseISO, subDays, differenceInMinutes, addMinutes, addMonths, isValid, formatDistanceToNow, isToday, isFuture, isBefore } from 'date-fns';
|
|
2
2
|
import { formatInTimeZone, fromZonedTime, toZonedTime } from 'date-fns-tz';
|
|
3
3
|
import * as React144 from 'react';
|
|
4
|
-
import React144__default, { createContext, useRef, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore,
|
|
4
|
+
import React144__default, { createContext, useRef, useId, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore, Children, isValidElement, useInsertionEffect, startTransition, Fragment as Fragment$1, createElement, Component } from 'react';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import { useRouter } from 'next/router';
|
|
7
7
|
import { toast } from 'sonner';
|
|
@@ -10,7 +10,7 @@ import { EventEmitter } from 'events';
|
|
|
10
10
|
import { createClient, REALTIME_SUBSCRIBE_STATES } from '@supabase/supabase-js';
|
|
11
11
|
import Hls, { Events, ErrorTypes } from 'hls.js';
|
|
12
12
|
import useSWR from 'swr';
|
|
13
|
-
import { Camera, AlertTriangle, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, Filter, X, Coffee, Plus, ArrowUp, ArrowDown, ArrowRight,
|
|
13
|
+
import { Camera, AlertTriangle, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, Filter, X, Coffee, Plus, ArrowUp, ArrowDown, ArrowRight, HelpCircle, ClipboardX, Activity, Wrench, UserX, Clock, Package, RefreshCw, CheckCircle2, ArrowLeft, Calendar, Save, AlertCircle, Loader2, Minus, ChevronLeft, ChevronRight, TrendingUp, Sparkles, Pause, Play, XCircle, Palette, TrendingDown, FolderOpen, Folder, ArrowDownWideNarrow, Tag, Sliders, Layers, Search, Edit2, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Video, Copy, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Settings, LifeBuoy, EyeOff, Zap, Flame, Crown, Medal } from 'lucide-react';
|
|
14
14
|
import { memo, noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds } from 'motion-utils';
|
|
15
15
|
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, ReferenceLine, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, Customized, Cell, PieChart, Pie, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
|
|
16
16
|
import { Slot } from '@radix-ui/react-slot';
|
|
@@ -4636,7 +4636,10 @@ var combineLineMetricsRows = (rows, dummySkuId) => {
|
|
|
4636
4636
|
};
|
|
4637
4637
|
const avgEfficiency = weighted("avg_efficiency");
|
|
4638
4638
|
const avgCycleTime = weighted("avg_cycle_time");
|
|
4639
|
-
const thresholdPph =
|
|
4639
|
+
const thresholdPph = rowsForAggregation.reduce(
|
|
4640
|
+
(acc, row) => acc + (coerceOptionalNumber(row.threshold_pph) ?? 0),
|
|
4641
|
+
0
|
|
4642
|
+
);
|
|
4640
4643
|
const underperformingWorkspaces = activeRealRows.length > 0 ? roundHalfUpInt(
|
|
4641
4644
|
activeRealRows.reduce(
|
|
4642
4645
|
(acc, row) => acc + safeInt(row.underperforming_workspaces),
|
|
@@ -14687,6 +14690,7 @@ var transformMonitorWorkspaceMetrics = ({
|
|
|
14687
14690
|
monitoring_mode: item.monitoring_mode ?? void 0,
|
|
14688
14691
|
idle_time: idleTimeSeconds,
|
|
14689
14692
|
idle_time_hourly: item.idle_time_hourly ?? null,
|
|
14693
|
+
idle_reason_hourly: item.idle_reason_hourly ?? null,
|
|
14690
14694
|
shift_start: item.shift_start ?? void 0,
|
|
14691
14695
|
shift_end: item.shift_end ?? void 0,
|
|
14692
14696
|
assembly_enabled: item.assembly_enabled ?? false,
|
|
@@ -14722,6 +14726,7 @@ var transformMonitorWorkspaceMetrics = ({
|
|
|
14722
14726
|
incoming_wip_current: item.incoming_wip_current ?? null,
|
|
14723
14727
|
incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
|
|
14724
14728
|
incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null,
|
|
14729
|
+
video_grid_badges: Array.isArray(item.video_grid_badges) ? item.video_grid_badges : [],
|
|
14725
14730
|
show_exclamation: item.show_exclamation ?? void 0
|
|
14726
14731
|
};
|
|
14727
14732
|
workspaceMetricsStore.setOverview(metric);
|
|
@@ -21240,6 +21245,7 @@ var ICON_CONFIG = {
|
|
|
21240
21245
|
"user-x": UserX,
|
|
21241
21246
|
wrench: Wrench,
|
|
21242
21247
|
activity: Activity,
|
|
21248
|
+
"clipboard-x": ClipboardX,
|
|
21243
21249
|
"help-circle": HelpCircle
|
|
21244
21250
|
};
|
|
21245
21251
|
var humanizeIdleReasonLabel = (value) => {
|
|
@@ -22067,7 +22073,7 @@ var normalizeLineSignalSource = (source) => source === "recent_flow" ? "recent_f
|
|
|
22067
22073
|
var normalizeLineSignal = (lineSignal, fallbackEfficiency, fallbackWeight) => {
|
|
22068
22074
|
if (lineSignal && typeof lineSignal === "object") {
|
|
22069
22075
|
const raw = lineSignal;
|
|
22070
|
-
|
|
22076
|
+
const normalized = {
|
|
22071
22077
|
source: normalizeLineSignalSource(raw.source),
|
|
22072
22078
|
percent: toOptionalNumber(raw.percent),
|
|
22073
22079
|
weight: toOptionalNumber(raw.weight),
|
|
@@ -22076,6 +22082,21 @@ var normalizeLineSignal = (lineSignal, fallbackEfficiency, fallbackWeight) => {
|
|
|
22076
22082
|
effectiveEndAt: raw.effective_end_at ?? raw.effectiveEndAt ?? null,
|
|
22077
22083
|
computedAt: raw.computed_at ?? raw.computedAt ?? null
|
|
22078
22084
|
};
|
|
22085
|
+
const aggregateEligible = typeof raw.aggregate_eligible === "boolean" ? raw.aggregate_eligible : typeof raw.aggregateEligible === "boolean" ? raw.aggregateEligible : null;
|
|
22086
|
+
if (aggregateEligible !== null) {
|
|
22087
|
+
normalized.aggregateEligible = aggregateEligible;
|
|
22088
|
+
}
|
|
22089
|
+
const aggregateReason = typeof raw.aggregate_reason === "string" ? raw.aggregate_reason : typeof raw.aggregateReason === "string" ? raw.aggregateReason : null;
|
|
22090
|
+
if (aggregateReason !== null) {
|
|
22091
|
+
normalized.aggregateReason = aggregateReason;
|
|
22092
|
+
}
|
|
22093
|
+
const aggregateThresholdPercent = toOptionalNumber(
|
|
22094
|
+
raw.aggregate_threshold_percent ?? raw.aggregateThresholdPercent
|
|
22095
|
+
);
|
|
22096
|
+
if (aggregateThresholdPercent !== null) {
|
|
22097
|
+
normalized.aggregateThresholdPercent = aggregateThresholdPercent;
|
|
22098
|
+
}
|
|
22099
|
+
return normalized;
|
|
22079
22100
|
}
|
|
22080
22101
|
const percent2 = toOptionalNumber(fallbackEfficiency);
|
|
22081
22102
|
if (percent2 === null) return null;
|
|
@@ -22103,7 +22124,7 @@ var getKpiSignalLabel = (signal, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
|
22103
22124
|
};
|
|
22104
22125
|
var aggregateLineSignals = (signals) => {
|
|
22105
22126
|
const numericSignals = signals.filter(
|
|
22106
|
-
(signal) => signal !== null && signal !== void 0 && toOptionalNumber(signal.percent) !== null
|
|
22127
|
+
(signal) => signal !== null && signal !== void 0 && signal.aggregateEligible !== false && toOptionalNumber(signal.percent) !== null
|
|
22107
22128
|
);
|
|
22108
22129
|
if (numericSignals.length === 0) return null;
|
|
22109
22130
|
const percent2 = numericSignals.reduce(
|
|
@@ -38011,6 +38032,20 @@ var getVideoGridLegendLabel = (workspaces) => {
|
|
|
38011
38032
|
}
|
|
38012
38033
|
return visibleWorkspaces.some(isVideoGridRecentFlowEnabled) ? VIDEO_GRID_LEGEND_LABEL : MAP_GRID_LEGEND_LABEL;
|
|
38013
38034
|
};
|
|
38035
|
+
var getStatusBadgeSignature = (workspace) => {
|
|
38036
|
+
const badges = workspace.video_grid_badges || [];
|
|
38037
|
+
return badges.map((badge) => [
|
|
38038
|
+
badge.kind,
|
|
38039
|
+
badge.label,
|
|
38040
|
+
badge.display_name,
|
|
38041
|
+
badge.palette_token,
|
|
38042
|
+
badge.icon_token,
|
|
38043
|
+
badge.anchor_minute,
|
|
38044
|
+
badge.reason_minute,
|
|
38045
|
+
badge.shift_elapsed_fraction,
|
|
38046
|
+
badge.title
|
|
38047
|
+
].join(":")).join("|");
|
|
38048
|
+
};
|
|
38014
38049
|
function getTrendArrowAndColor(trend) {
|
|
38015
38050
|
if (trend > 0) {
|
|
38016
38051
|
return { arrow: "\u2191", color: "text-green-400" };
|
|
@@ -38042,6 +38077,7 @@ var VideoCard = React144__default.memo(({
|
|
|
38042
38077
|
}) => {
|
|
38043
38078
|
const videoRef = useRef(null);
|
|
38044
38079
|
const canvasRef = useRef(null);
|
|
38080
|
+
const statusBadgeIdPrefix = useId();
|
|
38045
38081
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
38046
38082
|
const { isStale: isStreamStale } = useHlsStreamWithCropping(videoRef, canvasRef, {
|
|
38047
38083
|
src: hlsUrl,
|
|
@@ -38068,6 +38104,7 @@ var VideoCard = React144__default.memo(({
|
|
|
38068
38104
|
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
38069
38105
|
const badgeTitle = isHighEfficiencyOverride ? `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%` : hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
38070
38106
|
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
38107
|
+
const statusBadges = workspace.video_grid_badges || [];
|
|
38071
38108
|
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "blue" ? "bg-[#0EA5E9]/30" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
38072
38109
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "blue" ? "bg-[#0EA5E9]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
38073
38110
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "blue" ? "Best" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
@@ -38146,6 +38183,61 @@ var VideoCard = React144__default.memo(({
|
|
|
38146
38183
|
children: /* @__PURE__ */ jsx("span", { className: `${compact ? "text-[10px]" : "text-xs"} font-semibold`, children: badgeLabel })
|
|
38147
38184
|
}
|
|
38148
38185
|
) }),
|
|
38186
|
+
statusBadges.length > 0 && /* @__PURE__ */ jsx(
|
|
38187
|
+
"div",
|
|
38188
|
+
{
|
|
38189
|
+
"data-testid": "video-card-status-badges",
|
|
38190
|
+
className: `absolute ${compact ? "top-1.5 left-1.5 gap-1" : "top-2 left-2 gap-1.5"} z-30 flex items-center`,
|
|
38191
|
+
children: statusBadges.map((badge, index) => {
|
|
38192
|
+
const presentation = getIdleReasonPresentation({
|
|
38193
|
+
label: badge.label,
|
|
38194
|
+
displayName: badge.display_name,
|
|
38195
|
+
paletteToken: badge.palette_token,
|
|
38196
|
+
iconToken: badge.icon_token,
|
|
38197
|
+
isKnown: badge.is_known
|
|
38198
|
+
});
|
|
38199
|
+
const Icon2 = presentation.Icon;
|
|
38200
|
+
const tooltipText = presentation.displayName;
|
|
38201
|
+
const tooltipId = `video-card-status-tooltip-${statusBadgeIdPrefix}-${badge.kind}-${index}`;
|
|
38202
|
+
return /* @__PURE__ */ jsxs(
|
|
38203
|
+
"div",
|
|
38204
|
+
{
|
|
38205
|
+
"data-testid": `video-card-status-badge-${badge.kind}`,
|
|
38206
|
+
"aria-label": tooltipText,
|
|
38207
|
+
"aria-describedby": tooltipId,
|
|
38208
|
+
className: `group relative inline-flex shrink-0 items-center justify-center rounded-full bg-slate-950/70 border-2 shadow-[0_3px_10px_rgba(0,0,0,0.34),inset_0_0_0_1px_rgba(255,255,255,0.18)] ${compact ? "h-10 w-10" : "h-11 w-11"}`,
|
|
38209
|
+
style: {
|
|
38210
|
+
borderColor: presentation.hex
|
|
38211
|
+
},
|
|
38212
|
+
children: [
|
|
38213
|
+
/* @__PURE__ */ jsx(
|
|
38214
|
+
Icon2,
|
|
38215
|
+
{
|
|
38216
|
+
"aria-hidden": "true",
|
|
38217
|
+
className: `${compact ? "h-5 w-5" : "h-6 w-6"} text-white`,
|
|
38218
|
+
strokeWidth: 2.4
|
|
38219
|
+
}
|
|
38220
|
+
),
|
|
38221
|
+
/* @__PURE__ */ jsxs(
|
|
38222
|
+
"span",
|
|
38223
|
+
{
|
|
38224
|
+
id: tooltipId,
|
|
38225
|
+
role: "tooltip",
|
|
38226
|
+
"data-testid": `video-card-status-tooltip-${badge.kind}`,
|
|
38227
|
+
className: "pointer-events-none absolute left-0 top-full mt-2 whitespace-nowrap rounded-md border border-white/10 bg-slate-950/95 px-2 py-1 text-[11px] font-semibold leading-none text-white opacity-0 shadow-[0_6px_18px_rgba(0,0,0,0.34)] transition-opacity duration-150 group-hover:opacity-100",
|
|
38228
|
+
children: [
|
|
38229
|
+
/* @__PURE__ */ jsx("span", { className: "absolute -top-1 left-3 h-2 w-2 rotate-45 border-l border-t border-white/10 bg-slate-950/95" }),
|
|
38230
|
+
tooltipText
|
|
38231
|
+
]
|
|
38232
|
+
}
|
|
38233
|
+
)
|
|
38234
|
+
]
|
|
38235
|
+
},
|
|
38236
|
+
`${badge.kind}-${badge.label || index}-${badge.reason_minute ?? index}`
|
|
38237
|
+
);
|
|
38238
|
+
})
|
|
38239
|
+
}
|
|
38240
|
+
),
|
|
38149
38241
|
/* @__PURE__ */ jsx("div", { className: `absolute bottom-0 left-0 right-0 ${compact ? "h-0.5" : "h-1"} bg-black/50 z-30`, children: /* @__PURE__ */ jsx(
|
|
38150
38242
|
"div",
|
|
38151
38243
|
{
|
|
@@ -38182,7 +38274,7 @@ var VideoCard = React144__default.memo(({
|
|
|
38182
38274
|
}
|
|
38183
38275
|
);
|
|
38184
38276
|
}, (prevProps, nextProps) => {
|
|
38185
|
-
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.recent_flow_forced_zero_after_shift !== nextProps.workspace.recent_flow_forced_zero_after_shift || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
38277
|
+
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.recent_flow_forced_zero_after_shift !== nextProps.workspace.recent_flow_forced_zero_after_shift || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || getStatusBadgeSignature(prevProps.workspace) !== getStatusBadgeSignature(nextProps.workspace) || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
38186
38278
|
return false;
|
|
38187
38279
|
}
|
|
38188
38280
|
if (prevProps.workspace.workspace_uuid !== nextProps.workspace.workspace_uuid || prevProps.workspace.workspace_name !== nextProps.workspace.workspace_name || prevProps.workspace.line_id !== nextProps.workspace.line_id) {
|
|
@@ -64808,7 +64900,6 @@ var EMPTY_LINE_IDS = [];
|
|
|
64808
64900
|
var EMPTY_WORKSPACES = [];
|
|
64809
64901
|
var ALL_GREEN_CELEBRATION_DURATION_MS = 6e3;
|
|
64810
64902
|
var ALL_GREEN_MILESTONE_DURATION_MS = 6e3;
|
|
64811
|
-
var ALL_GREEN_STREAK_LOCAL_SECOND_CAP = 59;
|
|
64812
64903
|
var formatAllGreenCelebrationTimer = (elapsedSeconds) => {
|
|
64813
64904
|
const safeElapsedSeconds = Math.max(1, Math.floor(elapsedSeconds));
|
|
64814
64905
|
const minutes = Math.floor(safeElapsedSeconds / 60);
|
|
@@ -64816,10 +64907,7 @@ var formatAllGreenCelebrationTimer = (elapsedSeconds) => {
|
|
|
64816
64907
|
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}s`;
|
|
64817
64908
|
};
|
|
64818
64909
|
var getAllGreenBackendVisibleSeconds = (confirmedSeconds, tickOriginAtMs, nowMs2) => {
|
|
64819
|
-
const localSecondOffset = Math.
|
|
64820
|
-
ALL_GREEN_STREAK_LOCAL_SECOND_CAP,
|
|
64821
|
-
Math.max(0, Math.floor((nowMs2 - tickOriginAtMs) / 1e3))
|
|
64822
|
-
);
|
|
64910
|
+
const localSecondOffset = Math.max(0, Math.floor((nowMs2 - tickOriginAtMs) / 1e3));
|
|
64823
64911
|
return confirmedSeconds + localSecondOffset;
|
|
64824
64912
|
};
|
|
64825
64913
|
var LoadingPageCmp = LoadingPage_default;
|
|
@@ -65279,38 +65367,25 @@ function HomeView({
|
|
|
65279
65367
|
allGreenStreakDisplay.tickOriginAtMs,
|
|
65280
65368
|
currentAllGreenStreakNowMs
|
|
65281
65369
|
);
|
|
65282
|
-
const backendMaxVisibleSeconds = confirmedSeconds + ALL_GREEN_STREAK_LOCAL_SECOND_CAP;
|
|
65283
65370
|
const currentBaseline = allGreenStreakTimerBaselineRef.current;
|
|
65284
65371
|
if (!currentBaseline || currentBaseline.identity !== allGreenMilestoneIdentity) {
|
|
65285
65372
|
allGreenStreakTimerBaselineRef.current = {
|
|
65286
65373
|
identity: allGreenMilestoneIdentity,
|
|
65287
65374
|
baseSeconds: backendVisibleSeconds,
|
|
65288
|
-
baseReceivedAtMs: currentAllGreenStreakNowMs
|
|
65289
|
-
maxVisibleSeconds: backendMaxVisibleSeconds
|
|
65375
|
+
baseReceivedAtMs: currentAllGreenStreakNowMs
|
|
65290
65376
|
};
|
|
65291
65377
|
} else {
|
|
65292
|
-
currentBaseline.
|
|
65293
|
-
currentBaseline.maxVisibleSeconds,
|
|
65294
|
-
backendMaxVisibleSeconds
|
|
65295
|
-
);
|
|
65296
|
-
const visibleSeconds = Math.min(
|
|
65297
|
-
currentBaseline.maxVisibleSeconds,
|
|
65298
|
-
currentBaseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - currentBaseline.baseReceivedAtMs) / 1e3))
|
|
65299
|
-
);
|
|
65378
|
+
const visibleSeconds = currentBaseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - currentBaseline.baseReceivedAtMs) / 1e3));
|
|
65300
65379
|
if (backendVisibleSeconds > visibleSeconds) {
|
|
65301
65380
|
allGreenStreakTimerBaselineRef.current = {
|
|
65302
65381
|
identity: allGreenMilestoneIdentity,
|
|
65303
65382
|
baseSeconds: backendVisibleSeconds,
|
|
65304
|
-
baseReceivedAtMs: currentAllGreenStreakNowMs
|
|
65305
|
-
maxVisibleSeconds: currentBaseline.maxVisibleSeconds
|
|
65383
|
+
baseReceivedAtMs: currentAllGreenStreakNowMs
|
|
65306
65384
|
};
|
|
65307
65385
|
}
|
|
65308
65386
|
}
|
|
65309
65387
|
const baseline = allGreenStreakTimerBaselineRef.current;
|
|
65310
|
-
const elapsedSeconds = baseline ? Math.
|
|
65311
|
-
baseline.maxVisibleSeconds,
|
|
65312
|
-
baseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - baseline.baseReceivedAtMs) / 1e3))
|
|
65313
|
-
) : backendVisibleSeconds;
|
|
65388
|
+
const elapsedSeconds = baseline ? baseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - baseline.baseReceivedAtMs) / 1e3)) : backendVisibleSeconds;
|
|
65314
65389
|
return {
|
|
65315
65390
|
...allGreenStreakDisplay,
|
|
65316
65391
|
elapsedSeconds,
|