@optifye/dashboard-core 6.12.29 → 6.12.31
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-DYa3jNEf.d.mts → automation-ZIumB5W9.d.mts} +19 -1
- package/dist/{automation-DYa3jNEf.d.ts → automation-ZIumB5W9.d.ts} +19 -1
- package/dist/automation.d.mts +1 -1
- package/dist/automation.d.ts +1 -1
- package/dist/automation.js +197 -1
- package/dist/automation.mjs +199 -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 +282 -16
- package/dist/index.mjs +284 -18
- 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;
|
|
@@ -196,10 +212,12 @@ interface WorkspaceMetrics {
|
|
|
196
212
|
video_grid_green_streak_minutes?: number | null;
|
|
197
213
|
video_grid_green_streak_anchor_at?: string | null;
|
|
198
214
|
video_grid_green_streak_started_at?: string | null;
|
|
215
|
+
video_grid_green_streak_observed_at?: string | null;
|
|
199
216
|
scheduled_break_active?: boolean;
|
|
200
217
|
incoming_wip_current?: number | null;
|
|
201
218
|
incoming_wip_effective_at?: string | null;
|
|
202
219
|
incoming_wip_buffer_name?: string | null;
|
|
220
|
+
video_grid_badges?: VideoGridStatusBadge[];
|
|
203
221
|
/**
|
|
204
222
|
* When present, controls whether the UI should show the exclamation indicator for this workstation.
|
|
205
223
|
* - Flow-configured lines: true only when a WIP alert is active for a buffer that outputs to this workstation.
|
|
@@ -477,4 +495,4 @@ interface RecentFlowSnapshotGridProps {
|
|
|
477
495
|
}
|
|
478
496
|
declare const RecentFlowSnapshotGrid: React__default.FC<RecentFlowSnapshotGridProps>;
|
|
479
497
|
|
|
480
|
-
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
|
|
498
|
+
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;
|
|
@@ -196,10 +212,12 @@ interface WorkspaceMetrics {
|
|
|
196
212
|
video_grid_green_streak_minutes?: number | null;
|
|
197
213
|
video_grid_green_streak_anchor_at?: string | null;
|
|
198
214
|
video_grid_green_streak_started_at?: string | null;
|
|
215
|
+
video_grid_green_streak_observed_at?: string | null;
|
|
199
216
|
scheduled_break_active?: boolean;
|
|
200
217
|
incoming_wip_current?: number | null;
|
|
201
218
|
incoming_wip_effective_at?: string | null;
|
|
202
219
|
incoming_wip_buffer_name?: string | null;
|
|
220
|
+
video_grid_badges?: VideoGridStatusBadge[];
|
|
203
221
|
/**
|
|
204
222
|
* When present, controls whether the UI should show the exclamation indicator for this workstation.
|
|
205
223
|
* - Flow-configured lines: true only when a WIP alert is active for a buffer that outputs to this workstation.
|
|
@@ -477,4 +495,4 @@ interface RecentFlowSnapshotGridProps {
|
|
|
477
495
|
}
|
|
478
496
|
declare const RecentFlowSnapshotGrid: React__default.FC<RecentFlowSnapshotGridProps>;
|
|
479
497
|
|
|
480
|
-
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
|
|
498
|
+
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-ZIumB5W9.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-ZIumB5W9.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,52 @@ 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
|
+
};
|
|
1985
|
+
var VALID_STATUS_BADGE_ICON_TOKENS = /* @__PURE__ */ new Set([
|
|
1986
|
+
"alert-triangle",
|
|
1987
|
+
"refresh-cw",
|
|
1988
|
+
"package",
|
|
1989
|
+
"clock",
|
|
1990
|
+
"user-x",
|
|
1991
|
+
"wrench",
|
|
1992
|
+
"activity",
|
|
1993
|
+
"clipboard-x"
|
|
1994
|
+
]);
|
|
1995
|
+
var normalizeStatusBadgeToken = (value) => String(value || "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
1996
|
+
var resolveVideoGridStatusBadgeIconToken = (badge) => {
|
|
1997
|
+
if (badge.kind === "no_plan") {
|
|
1998
|
+
return "clipboard-x";
|
|
1999
|
+
}
|
|
2000
|
+
const reasonTokens = /* @__PURE__ */ new Set([
|
|
2001
|
+
normalizeStatusBadgeToken(badge.label),
|
|
2002
|
+
normalizeStatusBadgeToken(badge.display_name),
|
|
2003
|
+
normalizeStatusBadgeToken(badge.title)
|
|
2004
|
+
]);
|
|
2005
|
+
if (reasonTokens.has("no_material")) {
|
|
2006
|
+
return "package";
|
|
2007
|
+
}
|
|
2008
|
+
if (reasonTokens.has("machine_maintenance") || reasonTokens.has("machine_downtime")) {
|
|
2009
|
+
return "wrench";
|
|
2010
|
+
}
|
|
2011
|
+
const iconToken = normalizeStatusBadgeToken(badge.icon_token);
|
|
2012
|
+
if (VALID_STATUS_BADGE_ICON_TOKENS.has(iconToken)) {
|
|
2013
|
+
return iconToken;
|
|
2014
|
+
}
|
|
2015
|
+
return "activity";
|
|
2016
|
+
};
|
|
1878
2017
|
function getTrendArrowAndColor(trend) {
|
|
1879
2018
|
if (trend > 0) {
|
|
1880
2019
|
return { arrow: "\u2191", color: "text-green-400" };
|
|
@@ -1906,6 +2045,7 @@ var VideoCard = React__default.default.memo(({
|
|
|
1906
2045
|
}) => {
|
|
1907
2046
|
const videoRef = React.useRef(null);
|
|
1908
2047
|
const canvasRef = React.useRef(null);
|
|
2048
|
+
const statusBadgeIdPrefix = React.useId();
|
|
1909
2049
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
1910
2050
|
const { isStale: isStreamStale } = useHlsStreamWithCropping(videoRef, canvasRef, {
|
|
1911
2051
|
src: hlsUrl,
|
|
@@ -1932,6 +2072,7 @@ var VideoCard = React__default.default.memo(({
|
|
|
1932
2072
|
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
1933
2073
|
const badgeTitle = isHighEfficiencyOverride ? `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%` : hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
1934
2074
|
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
2075
|
+
const statusBadges = workspace.video_grid_badges || [];
|
|
1935
2076
|
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
2077
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "blue" ? "bg-[#0EA5E9]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
1937
2078
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "blue" ? "Best" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
@@ -2010,6 +2151,61 @@ var VideoCard = React__default.default.memo(({
|
|
|
2010
2151
|
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${compact ? "text-[10px]" : "text-xs"} font-semibold`, children: badgeLabel })
|
|
2011
2152
|
}
|
|
2012
2153
|
) }),
|
|
2154
|
+
statusBadges.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2155
|
+
"div",
|
|
2156
|
+
{
|
|
2157
|
+
"data-testid": "video-card-status-badges",
|
|
2158
|
+
className: `absolute ${compact ? "top-1.5 left-1.5 gap-1" : "top-2 left-2 gap-1.5"} z-30 flex items-center`,
|
|
2159
|
+
children: statusBadges.map((badge, index) => {
|
|
2160
|
+
const presentation = getIdleReasonPresentation({
|
|
2161
|
+
label: badge.label,
|
|
2162
|
+
displayName: badge.display_name,
|
|
2163
|
+
paletteToken: badge.palette_token,
|
|
2164
|
+
iconToken: resolveVideoGridStatusBadgeIconToken(badge),
|
|
2165
|
+
isKnown: badge.is_known
|
|
2166
|
+
});
|
|
2167
|
+
const Icon = presentation.Icon;
|
|
2168
|
+
const tooltipText = presentation.displayName;
|
|
2169
|
+
const tooltipId = `video-card-status-tooltip-${statusBadgeIdPrefix}-${badge.kind}-${index}`;
|
|
2170
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2171
|
+
"div",
|
|
2172
|
+
{
|
|
2173
|
+
"data-testid": `video-card-status-badge-${badge.kind}`,
|
|
2174
|
+
"aria-label": tooltipText,
|
|
2175
|
+
"aria-describedby": tooltipId,
|
|
2176
|
+
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"}`,
|
|
2177
|
+
style: {
|
|
2178
|
+
borderColor: presentation.hex
|
|
2179
|
+
},
|
|
2180
|
+
children: [
|
|
2181
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2182
|
+
Icon,
|
|
2183
|
+
{
|
|
2184
|
+
"aria-hidden": "true",
|
|
2185
|
+
className: `${compact ? "h-5 w-5" : "h-6 w-6"} text-white`,
|
|
2186
|
+
strokeWidth: 2.4
|
|
2187
|
+
}
|
|
2188
|
+
),
|
|
2189
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2190
|
+
"span",
|
|
2191
|
+
{
|
|
2192
|
+
id: tooltipId,
|
|
2193
|
+
role: "tooltip",
|
|
2194
|
+
"data-testid": `video-card-status-tooltip-${badge.kind}`,
|
|
2195
|
+
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",
|
|
2196
|
+
children: [
|
|
2197
|
+
/* @__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" }),
|
|
2198
|
+
tooltipText
|
|
2199
|
+
]
|
|
2200
|
+
}
|
|
2201
|
+
)
|
|
2202
|
+
]
|
|
2203
|
+
},
|
|
2204
|
+
`${badge.kind}-${badge.label || index}-${badge.reason_minute ?? index}`
|
|
2205
|
+
);
|
|
2206
|
+
})
|
|
2207
|
+
}
|
|
2208
|
+
),
|
|
2013
2209
|
/* @__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
2210
|
"div",
|
|
2015
2211
|
{
|
|
@@ -2046,7 +2242,7 @@ var VideoCard = React__default.default.memo(({
|
|
|
2046
2242
|
}
|
|
2047
2243
|
);
|
|
2048
2244
|
}, (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) {
|
|
2245
|
+
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
2246
|
return false;
|
|
2051
2247
|
}
|
|
2052
2248
|
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,52 @@ 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
|
+
};
|
|
1978
|
+
var VALID_STATUS_BADGE_ICON_TOKENS = /* @__PURE__ */ new Set([
|
|
1979
|
+
"alert-triangle",
|
|
1980
|
+
"refresh-cw",
|
|
1981
|
+
"package",
|
|
1982
|
+
"clock",
|
|
1983
|
+
"user-x",
|
|
1984
|
+
"wrench",
|
|
1985
|
+
"activity",
|
|
1986
|
+
"clipboard-x"
|
|
1987
|
+
]);
|
|
1988
|
+
var normalizeStatusBadgeToken = (value) => String(value || "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
1989
|
+
var resolveVideoGridStatusBadgeIconToken = (badge) => {
|
|
1990
|
+
if (badge.kind === "no_plan") {
|
|
1991
|
+
return "clipboard-x";
|
|
1992
|
+
}
|
|
1993
|
+
const reasonTokens = /* @__PURE__ */ new Set([
|
|
1994
|
+
normalizeStatusBadgeToken(badge.label),
|
|
1995
|
+
normalizeStatusBadgeToken(badge.display_name),
|
|
1996
|
+
normalizeStatusBadgeToken(badge.title)
|
|
1997
|
+
]);
|
|
1998
|
+
if (reasonTokens.has("no_material")) {
|
|
1999
|
+
return "package";
|
|
2000
|
+
}
|
|
2001
|
+
if (reasonTokens.has("machine_maintenance") || reasonTokens.has("machine_downtime")) {
|
|
2002
|
+
return "wrench";
|
|
2003
|
+
}
|
|
2004
|
+
const iconToken = normalizeStatusBadgeToken(badge.icon_token);
|
|
2005
|
+
if (VALID_STATUS_BADGE_ICON_TOKENS.has(iconToken)) {
|
|
2006
|
+
return iconToken;
|
|
2007
|
+
}
|
|
2008
|
+
return "activity";
|
|
2009
|
+
};
|
|
1871
2010
|
function getTrendArrowAndColor(trend) {
|
|
1872
2011
|
if (trend > 0) {
|
|
1873
2012
|
return { arrow: "\u2191", color: "text-green-400" };
|
|
@@ -1899,6 +2038,7 @@ var VideoCard = React.memo(({
|
|
|
1899
2038
|
}) => {
|
|
1900
2039
|
const videoRef = useRef(null);
|
|
1901
2040
|
const canvasRef = useRef(null);
|
|
2041
|
+
const statusBadgeIdPrefix = useId();
|
|
1902
2042
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
1903
2043
|
const { isStale: isStreamStale } = useHlsStreamWithCropping(videoRef, canvasRef, {
|
|
1904
2044
|
src: hlsUrl,
|
|
@@ -1925,6 +2065,7 @@ var VideoCard = React.memo(({
|
|
|
1925
2065
|
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
1926
2066
|
const badgeTitle = isHighEfficiencyOverride ? `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%` : hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
1927
2067
|
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
2068
|
+
const statusBadges = workspace.video_grid_badges || [];
|
|
1928
2069
|
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
2070
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "blue" ? "bg-[#0EA5E9]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
1930
2071
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "blue" ? "Best" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
@@ -2003,6 +2144,61 @@ var VideoCard = React.memo(({
|
|
|
2003
2144
|
children: /* @__PURE__ */ jsx("span", { className: `${compact ? "text-[10px]" : "text-xs"} font-semibold`, children: badgeLabel })
|
|
2004
2145
|
}
|
|
2005
2146
|
) }),
|
|
2147
|
+
statusBadges.length > 0 && /* @__PURE__ */ jsx(
|
|
2148
|
+
"div",
|
|
2149
|
+
{
|
|
2150
|
+
"data-testid": "video-card-status-badges",
|
|
2151
|
+
className: `absolute ${compact ? "top-1.5 left-1.5 gap-1" : "top-2 left-2 gap-1.5"} z-30 flex items-center`,
|
|
2152
|
+
children: statusBadges.map((badge, index) => {
|
|
2153
|
+
const presentation = getIdleReasonPresentation({
|
|
2154
|
+
label: badge.label,
|
|
2155
|
+
displayName: badge.display_name,
|
|
2156
|
+
paletteToken: badge.palette_token,
|
|
2157
|
+
iconToken: resolveVideoGridStatusBadgeIconToken(badge),
|
|
2158
|
+
isKnown: badge.is_known
|
|
2159
|
+
});
|
|
2160
|
+
const Icon = presentation.Icon;
|
|
2161
|
+
const tooltipText = presentation.displayName;
|
|
2162
|
+
const tooltipId = `video-card-status-tooltip-${statusBadgeIdPrefix}-${badge.kind}-${index}`;
|
|
2163
|
+
return /* @__PURE__ */ jsxs(
|
|
2164
|
+
"div",
|
|
2165
|
+
{
|
|
2166
|
+
"data-testid": `video-card-status-badge-${badge.kind}`,
|
|
2167
|
+
"aria-label": tooltipText,
|
|
2168
|
+
"aria-describedby": tooltipId,
|
|
2169
|
+
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"}`,
|
|
2170
|
+
style: {
|
|
2171
|
+
borderColor: presentation.hex
|
|
2172
|
+
},
|
|
2173
|
+
children: [
|
|
2174
|
+
/* @__PURE__ */ jsx(
|
|
2175
|
+
Icon,
|
|
2176
|
+
{
|
|
2177
|
+
"aria-hidden": "true",
|
|
2178
|
+
className: `${compact ? "h-5 w-5" : "h-6 w-6"} text-white`,
|
|
2179
|
+
strokeWidth: 2.4
|
|
2180
|
+
}
|
|
2181
|
+
),
|
|
2182
|
+
/* @__PURE__ */ jsxs(
|
|
2183
|
+
"span",
|
|
2184
|
+
{
|
|
2185
|
+
id: tooltipId,
|
|
2186
|
+
role: "tooltip",
|
|
2187
|
+
"data-testid": `video-card-status-tooltip-${badge.kind}`,
|
|
2188
|
+
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",
|
|
2189
|
+
children: [
|
|
2190
|
+
/* @__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" }),
|
|
2191
|
+
tooltipText
|
|
2192
|
+
]
|
|
2193
|
+
}
|
|
2194
|
+
)
|
|
2195
|
+
]
|
|
2196
|
+
},
|
|
2197
|
+
`${badge.kind}-${badge.label || index}-${badge.reason_minute ?? index}`
|
|
2198
|
+
);
|
|
2199
|
+
})
|
|
2200
|
+
}
|
|
2201
|
+
),
|
|
2006
2202
|
/* @__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
2203
|
"div",
|
|
2008
2204
|
{
|
|
@@ -2039,7 +2235,7 @@ var VideoCard = React.memo(({
|
|
|
2039
2235
|
}
|
|
2040
2236
|
);
|
|
2041
2237
|
}, (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) {
|
|
2238
|
+
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
2239
|
return false;
|
|
2044
2240
|
}
|
|
2045
2241
|
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) {
|