@optifye/dashboard-core 6.12.22 → 6.12.25
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-Hl2PFMb3.d.mts → automation-C3vudVDH.d.mts} +8 -0
- package/dist/{automation-Hl2PFMb3.d.ts → automation-C3vudVDH.d.ts} +8 -0
- package/dist/automation.d.mts +1 -1
- package/dist/automation.d.ts +1 -1
- package/dist/automation.js +18 -7
- package/dist/automation.mjs +18 -7
- package/dist/index.css +80 -22
- package/dist/index.d.mts +36 -5
- package/dist/index.d.ts +36 -5
- package/dist/index.js +1218 -384
- package/dist/index.mjs +1219 -386
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9933,7 +9933,8 @@ var LinesService = class {
|
|
|
9933
9933
|
line.video_grid_metric_mode,
|
|
9934
9934
|
line.assembly ?? false
|
|
9935
9935
|
),
|
|
9936
|
-
recentFlowWindowMinutes: line.recent_flow_window_minutes ?? 7
|
|
9936
|
+
recentFlowWindowMinutes: line.recent_flow_window_minutes ?? 7,
|
|
9937
|
+
factoryAreaId: line.factory_area_id ?? null
|
|
9937
9938
|
}));
|
|
9938
9939
|
} catch (error) {
|
|
9939
9940
|
console.error("Error fetching lines:", error);
|
|
@@ -9992,7 +9993,8 @@ var LinesService = class {
|
|
|
9992
9993
|
line.video_grid_metric_mode,
|
|
9993
9994
|
line.assembly ?? false
|
|
9994
9995
|
),
|
|
9995
|
-
recentFlowWindowMinutes: line.recent_flow_window_minutes ?? 7
|
|
9996
|
+
recentFlowWindowMinutes: line.recent_flow_window_minutes ?? 7,
|
|
9997
|
+
factoryAreaId: line.factory_area_id ?? null
|
|
9996
9998
|
}));
|
|
9997
9999
|
} catch (error) {
|
|
9998
10000
|
console.error("Error fetching all lines:", error);
|
|
@@ -10059,7 +10061,8 @@ var LinesService = class {
|
|
|
10059
10061
|
data.video_grid_metric_mode,
|
|
10060
10062
|
data.assembly ?? false
|
|
10061
10063
|
),
|
|
10062
|
-
recentFlowWindowMinutes: data.recent_flow_window_minutes ?? 7
|
|
10064
|
+
recentFlowWindowMinutes: data.recent_flow_window_minutes ?? 7,
|
|
10065
|
+
factoryAreaId: data.factory_area_id ?? null
|
|
10063
10066
|
};
|
|
10064
10067
|
} catch (error) {
|
|
10065
10068
|
console.error("Error fetching line:", error);
|
|
@@ -11673,6 +11676,9 @@ var lineLeaderboardService = {
|
|
|
11673
11676
|
if (typeof params.limit === "number") {
|
|
11674
11677
|
searchParams.set("limit", params.limit.toString());
|
|
11675
11678
|
}
|
|
11679
|
+
if (params.includeBelowThreshold) {
|
|
11680
|
+
searchParams.set("include_below_threshold", "true");
|
|
11681
|
+
}
|
|
11676
11682
|
const data = await fetchBackendJson(
|
|
11677
11683
|
supabase,
|
|
11678
11684
|
`/api/dashboard/line-leaderboard-daily?${searchParams.toString()}`
|
|
@@ -14609,6 +14615,32 @@ function getEfficiencyTextColorClasses(efficiency, legend = DEFAULT_EFFICIENCY_L
|
|
|
14609
14615
|
}
|
|
14610
14616
|
}
|
|
14611
14617
|
|
|
14618
|
+
// src/lib/utils/qaGreenStreakParams.ts
|
|
14619
|
+
var QA_GREEN_STREAK_QUERY_PARAM_NAMES = [
|
|
14620
|
+
"qa_green_streak_started_at",
|
|
14621
|
+
"qa_green_streak_elapsed_seconds",
|
|
14622
|
+
"qa_green_streak_status"
|
|
14623
|
+
];
|
|
14624
|
+
var isTruthyEnv = (value) => ["1", "true", "yes", "on"].includes(String(value || "").trim().toLowerCase());
|
|
14625
|
+
var isQaGreenStreakForwardingEnabled = () => isTruthyEnv(process.env.NEXT_PUBLIC_DASHBOARD_QA_GREEN_STREAK_OVERRIDE_ENABLED);
|
|
14626
|
+
var appendQaGreenStreakSearchParams = (targetParams) => {
|
|
14627
|
+
if (!isQaGreenStreakForwardingEnabled() || typeof window === "undefined") {
|
|
14628
|
+
return;
|
|
14629
|
+
}
|
|
14630
|
+
const sourceParams = new URLSearchParams(window.location.search);
|
|
14631
|
+
QA_GREEN_STREAK_QUERY_PARAM_NAMES.forEach((paramName) => {
|
|
14632
|
+
const value = sourceParams.get(paramName);
|
|
14633
|
+
if (value !== null) {
|
|
14634
|
+
targetParams.set(paramName, value);
|
|
14635
|
+
}
|
|
14636
|
+
});
|
|
14637
|
+
};
|
|
14638
|
+
var getQaGreenStreakQueryString = () => {
|
|
14639
|
+
const params = new URLSearchParams();
|
|
14640
|
+
appendQaGreenStreakSearchParams(params);
|
|
14641
|
+
return params.toString();
|
|
14642
|
+
};
|
|
14643
|
+
|
|
14612
14644
|
// src/lib/utils/monitorWorkspaceMetrics.ts
|
|
14613
14645
|
var sortWorkspaceMetrics = (left, right) => {
|
|
14614
14646
|
if (left.line_id !== right.line_id) {
|
|
@@ -14697,11 +14729,22 @@ var transformMonitorWorkspaceMetrics = ({
|
|
|
14697
14729
|
actionType: item.action_type,
|
|
14698
14730
|
actionName: item.action_name
|
|
14699
14731
|
}),
|
|
14732
|
+
factory_area_id: item.factory_area_id ?? null,
|
|
14733
|
+
factory_area_key: item.factory_area_key ?? null,
|
|
14734
|
+
factory_area_name: item.factory_area_name ?? null,
|
|
14735
|
+
factory_area_enabled: item.factory_area_enabled ?? null,
|
|
14736
|
+
leaderboard_metric_kind: item.leaderboard_metric_kind ?? void 0,
|
|
14737
|
+
leaderboard_value: item.leaderboard_value ?? null,
|
|
14738
|
+
avg_recent_flow: item.avg_recent_flow ?? null,
|
|
14700
14739
|
recent_flow_percent: item.recent_flow_percent ?? null,
|
|
14701
14740
|
recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
|
|
14702
14741
|
recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
|
|
14703
14742
|
recent_flow_computed_at: item.recent_flow_computed_at ?? null,
|
|
14704
14743
|
recent_flow_forced_zero_after_shift: item.recent_flow_forced_zero_after_shift ?? null,
|
|
14744
|
+
video_grid_green_streak_active: item.video_grid_green_streak_active ?? null,
|
|
14745
|
+
video_grid_green_streak_minutes: item.video_grid_green_streak_minutes ?? null,
|
|
14746
|
+
video_grid_green_streak_anchor_at: item.video_grid_green_streak_anchor_at ?? null,
|
|
14747
|
+
video_grid_green_streak_started_at: item.video_grid_green_streak_started_at ?? null,
|
|
14705
14748
|
scheduled_break_active: item.scheduled_break_active ?? false,
|
|
14706
14749
|
incoming_wip_current: item.incoming_wip_current ?? null,
|
|
14707
14750
|
incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
|
|
@@ -14721,12 +14764,12 @@ var logDebug = (...args) => {
|
|
|
14721
14764
|
if (!DEBUG_DASHBOARD_LOGS) return;
|
|
14722
14765
|
console.log(...args);
|
|
14723
14766
|
};
|
|
14724
|
-
var buildMetricsScopeKey = (lineId, lineIds) => {
|
|
14767
|
+
var buildMetricsScopeKey = (lineId, lineIds, blueComparisonLineIds) => {
|
|
14725
14768
|
const normalizedLineIds = Array.from(new Set((lineIds || []).filter(Boolean))).sort();
|
|
14726
|
-
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
return lineId
|
|
14769
|
+
const normalizedBlueComparisonLineIds = Array.from(new Set((blueComparisonLineIds || []).filter(Boolean))).sort();
|
|
14770
|
+
const lineKey = normalizedLineIds.length > 0 ? normalizedLineIds.join(",") : lineId;
|
|
14771
|
+
const comparisonKey = normalizedBlueComparisonLineIds.length > 0 ? normalizedBlueComparisonLineIds.join(",") : lineKey;
|
|
14772
|
+
return `${lineId}|${lineKey}|blue:${comparisonKey}`;
|
|
14730
14773
|
};
|
|
14731
14774
|
var parseEfficiencyLegend = (legend) => {
|
|
14732
14775
|
if (!legend) return null;
|
|
@@ -14748,6 +14791,7 @@ var useDashboardMetrics = ({
|
|
|
14748
14791
|
onLineMetricsUpdate,
|
|
14749
14792
|
lineId,
|
|
14750
14793
|
lineIds,
|
|
14794
|
+
blueComparisonLineIds,
|
|
14751
14795
|
userAccessibleLineIds,
|
|
14752
14796
|
enabled = true
|
|
14753
14797
|
}) => {
|
|
@@ -14770,6 +14814,10 @@ var useDashboardMetrics = ({
|
|
|
14770
14814
|
const sourceLineIds = lineIds !== void 0 ? lineIds : userAccessibleLineIds !== void 0 ? userAccessibleLineIds : configuredLineIds;
|
|
14771
14815
|
return Array.from(new Set((sourceLineIds || []).filter(Boolean)));
|
|
14772
14816
|
}, [lineIds, userAccessibleLineIds, configuredLineIds]);
|
|
14817
|
+
const normalizedBlueComparisonLineIds = React144.useMemo(
|
|
14818
|
+
() => Array.from(new Set((blueComparisonLineIds || []).filter(Boolean))),
|
|
14819
|
+
[blueComparisonLineIds]
|
|
14820
|
+
);
|
|
14773
14821
|
const { shiftConfig: staticShiftConfig } = useDashboardConfig();
|
|
14774
14822
|
const {
|
|
14775
14823
|
shiftConfigMap: multiLineShiftConfigMap,
|
|
@@ -14807,7 +14855,7 @@ var useDashboardMetrics = ({
|
|
|
14807
14855
|
const supabase = useSupabase();
|
|
14808
14856
|
const [metrics2, setMetrics] = React144.useState({ workspaceMetrics: [], lineMetrics: [] });
|
|
14809
14857
|
const [metricsLineId, setMetricsLineId] = React144.useState(lineId ?? null);
|
|
14810
|
-
const [metricsScopeKey, setMetricsScopeKey] = React144.useState(() => buildMetricsScopeKey(lineId, lineIds));
|
|
14858
|
+
const [metricsScopeKey, setMetricsScopeKey] = React144.useState(() => buildMetricsScopeKey(lineId, lineIds, blueComparisonLineIds));
|
|
14811
14859
|
const [isLoading, setIsLoading] = React144.useState(true);
|
|
14812
14860
|
const [error, setError] = React144.useState(null);
|
|
14813
14861
|
const lineIdRef = React144.useRef(lineId);
|
|
@@ -14849,8 +14897,12 @@ var useDashboardMetrics = ({
|
|
|
14849
14897
|
[entityConfig.companyId]
|
|
14850
14898
|
);
|
|
14851
14899
|
const requestedScopeKey = React144.useMemo(
|
|
14852
|
-
() => buildMetricsScopeKey(
|
|
14853
|
-
|
|
14900
|
+
() => buildMetricsScopeKey(
|
|
14901
|
+
lineId,
|
|
14902
|
+
isFactoryView ? targetFactoryLineIds : void 0,
|
|
14903
|
+
normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0
|
|
14904
|
+
),
|
|
14905
|
+
[isFactoryView, lineId, targetFactoryLineIds, normalizedBlueComparisonLineIds]
|
|
14854
14906
|
);
|
|
14855
14907
|
React144.useEffect(() => {
|
|
14856
14908
|
lineIdRef.current = lineId;
|
|
@@ -14880,12 +14932,15 @@ var useDashboardMetrics = ({
|
|
|
14880
14932
|
const isFactory = currentLineIdToUse === factoryViewId;
|
|
14881
14933
|
const targetLineIds = isFactory ? targetFactoryLineIds : [currentLineIdToUse];
|
|
14882
14934
|
const targetLineIdsKey = targetLineIds.slice().sort().join(",");
|
|
14935
|
+
const effectiveBlueComparisonLineIds = normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : targetLineIds;
|
|
14936
|
+
const blueComparisonLineIdsKey = effectiveBlueComparisonLineIds.slice().sort().join(",");
|
|
14883
14937
|
const usesShiftGroups = isFactory && shiftGroups.length > 0;
|
|
14884
14938
|
const singleShiftDetails = usesShiftGroups ? null : shiftConfig ? getCurrentShift(defaultTimezone, shiftConfig) : shiftGroups.length === 1 ? { date: shiftGroups[0].date, shiftId: shiftGroups[0].shiftId } : getCurrentShift(defaultTimezone, staticShiftConfig);
|
|
14885
|
-
const fetchKey = usesShiftGroups ? `factory|${companyId || "unknown"}|${shiftGroupsKey}` : isFactory ? `factory|${companyId || "unknown"}|${singleShiftDetails?.date}|${singleShiftDetails?.shiftId}|${targetLineIdsKey}` : `${currentLineIdToUse}|${companyId || "unknown"}|${singleShiftDetails?.date}|${singleShiftDetails?.shiftId}`;
|
|
14939
|
+
const fetchKey = usesShiftGroups ? `factory|${companyId || "unknown"}|${shiftGroupsKey}|blue:${blueComparisonLineIdsKey}` : isFactory ? `factory|${companyId || "unknown"}|${singleShiftDetails?.date}|${singleShiftDetails?.shiftId}|${targetLineIdsKey}|blue:${blueComparisonLineIdsKey}` : `${currentLineIdToUse}|${companyId || "unknown"}|${singleShiftDetails?.date}|${singleShiftDetails?.shiftId}|blue:${blueComparisonLineIdsKey}`;
|
|
14886
14940
|
const responseScopeKey = buildMetricsScopeKey(
|
|
14887
14941
|
currentLineIdToUse,
|
|
14888
|
-
isFactory ? targetLineIds : void 0
|
|
14942
|
+
isFactory ? targetLineIds : void 0,
|
|
14943
|
+
normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0
|
|
14889
14944
|
);
|
|
14890
14945
|
logDebug("[useDashboardMetrics] Fetch key details:", {
|
|
14891
14946
|
isFactory,
|
|
@@ -14915,6 +14970,7 @@ var useDashboardMetrics = ({
|
|
|
14915
14970
|
logDebug("[useDashboardMetrics] Skipping fetch: no target line IDs after scope filtering");
|
|
14916
14971
|
setMetrics({
|
|
14917
14972
|
workspaceMetrics: [],
|
|
14973
|
+
blueComparisonWorkspaceMetrics: [],
|
|
14918
14974
|
lineMetrics: [],
|
|
14919
14975
|
metadata: void 0,
|
|
14920
14976
|
efficiencyLegend: DEFAULT_EFFICIENCY_LEGEND
|
|
@@ -14925,14 +14981,18 @@ var useDashboardMetrics = ({
|
|
|
14925
14981
|
return;
|
|
14926
14982
|
}
|
|
14927
14983
|
let allWorkspaceMetrics = [];
|
|
14984
|
+
let allBlueComparisonWorkspaceMetrics = [];
|
|
14928
14985
|
let allLineMetrics = [];
|
|
14929
14986
|
let hasFlowBuffers = false;
|
|
14930
14987
|
let idleTimeVlmByLine = {};
|
|
14931
14988
|
let efficiencyLegend;
|
|
14932
14989
|
const forceParam = force ? "&force_refresh=true" : "";
|
|
14990
|
+
const qaGreenStreakParamString = getQaGreenStreakQueryString();
|
|
14991
|
+
const qaGreenStreakParams = qaGreenStreakParamString ? `&${qaGreenStreakParamString}` : "";
|
|
14933
14992
|
const buildMetricsEndpoint = (params) => {
|
|
14934
14993
|
const lineIdsParam = isFactory ? `line_ids=${params.groupLineIds.join(",")}` : `line_id=${params.groupLineIds[0]}`;
|
|
14935
|
-
|
|
14994
|
+
const blueComparisonParam = effectiveBlueComparisonLineIds.length ? `&blue_comparison_line_ids=${effectiveBlueComparisonLineIds.join(",")}` : "";
|
|
14995
|
+
return `/api/dashboard/metrics?${lineIdsParam}${blueComparisonParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}${qaGreenStreakParams}`;
|
|
14936
14996
|
};
|
|
14937
14997
|
if (usesShiftGroups) {
|
|
14938
14998
|
logDebug("[useDashboardMetrics] Factory view shift groups fetch:", {
|
|
@@ -14982,10 +15042,16 @@ var useDashboardMetrics = ({
|
|
|
14982
15042
|
if (result.workspace_metrics) {
|
|
14983
15043
|
allWorkspaceMetrics.push(...result.workspace_metrics);
|
|
14984
15044
|
}
|
|
15045
|
+
if (result.blue_comparison_workspace_metrics) {
|
|
15046
|
+
allBlueComparisonWorkspaceMetrics.push(...result.blue_comparison_workspace_metrics);
|
|
15047
|
+
}
|
|
14985
15048
|
if (result.line_metrics) {
|
|
14986
15049
|
allLineMetrics.push(...result.line_metrics);
|
|
14987
15050
|
}
|
|
14988
15051
|
});
|
|
15052
|
+
if (allBlueComparisonWorkspaceMetrics.length === 0) {
|
|
15053
|
+
allBlueComparisonWorkspaceMetrics = allWorkspaceMetrics;
|
|
15054
|
+
}
|
|
14989
15055
|
logDebug(`[useDashboardMetrics] \u{1F4CA} Merged metrics from ${results.length} shift groups:`, {
|
|
14990
15056
|
workspaceCount: allWorkspaceMetrics.length,
|
|
14991
15057
|
lineMetricsCount: allLineMetrics.length
|
|
@@ -15023,6 +15089,7 @@ var useDashboardMetrics = ({
|
|
|
15023
15089
|
lineCount: backendData.line_metrics?.length || 0
|
|
15024
15090
|
});
|
|
15025
15091
|
allWorkspaceMetrics = backendData.workspace_metrics || [];
|
|
15092
|
+
allBlueComparisonWorkspaceMetrics = backendData.blue_comparison_workspace_metrics || allWorkspaceMetrics;
|
|
15026
15093
|
allLineMetrics = backendData.line_metrics || [];
|
|
15027
15094
|
hasFlowBuffers = Boolean(backendData?.metadata?.has_flow_buffers);
|
|
15028
15095
|
if (backendData?.metadata?.idle_time_vlm_by_line && typeof backendData.metadata.idle_time_vlm_by_line === "object") {
|
|
@@ -15041,8 +15108,19 @@ var useDashboardMetrics = ({
|
|
|
15041
15108
|
shouldOverrideShiftType: (metricLineId) => isFactoryView ? Boolean(multiLineShiftConfigMap.get(metricLineId)) : Boolean(shiftConfig),
|
|
15042
15109
|
fallbackShiftConfig: staticShiftConfig
|
|
15043
15110
|
});
|
|
15111
|
+
const transformedBlueComparisonWorkspaceData = allBlueComparisonWorkspaceMetrics === allWorkspaceMetrics ? transformedWorkspaceData : transformMonitorWorkspaceMetrics({
|
|
15112
|
+
rows: allBlueComparisonWorkspaceMetrics,
|
|
15113
|
+
companyId: companyId || "",
|
|
15114
|
+
workspaceConfig: effectiveWorkspaceConfig,
|
|
15115
|
+
appTimezone: detailTimezone,
|
|
15116
|
+
lineMetrics: allLineMetrics,
|
|
15117
|
+
resolveShiftConfig: (metricLineId) => isFactoryView ? multiLineShiftConfigMap.get(metricLineId) || staticShiftConfig : shiftConfig || staticShiftConfig,
|
|
15118
|
+
shouldOverrideShiftType: (metricLineId) => isFactoryView ? Boolean(multiLineShiftConfigMap.get(metricLineId)) : Boolean(shiftConfig),
|
|
15119
|
+
fallbackShiftConfig: staticShiftConfig
|
|
15120
|
+
});
|
|
15044
15121
|
const newMetricsState = {
|
|
15045
15122
|
workspaceMetrics: transformedWorkspaceData,
|
|
15123
|
+
blueComparisonWorkspaceMetrics: transformedBlueComparisonWorkspaceData.length ? transformedBlueComparisonWorkspaceData : transformedWorkspaceData,
|
|
15046
15124
|
lineMetrics: allLineMetrics || [],
|
|
15047
15125
|
metadata: { hasFlowBuffers, idleTimeVlmByLine },
|
|
15048
15126
|
efficiencyLegend: efficiencyLegend ?? DEFAULT_EFFICIENCY_LEGEND
|
|
@@ -15113,6 +15191,7 @@ var useDashboardMetrics = ({
|
|
|
15113
15191
|
shiftGroupsKey,
|
|
15114
15192
|
configuredLineIds,
|
|
15115
15193
|
targetFactoryLineIds,
|
|
15194
|
+
normalizedBlueComparisonLineIds,
|
|
15116
15195
|
isFactoryView,
|
|
15117
15196
|
multiLineShiftConfigMap,
|
|
15118
15197
|
staticShiftConfig,
|
|
@@ -15553,9 +15632,10 @@ var useDashboardMetrics = ({
|
|
|
15553
15632
|
const isCurrentScopeResolved = metricsScopeKey === requestedScopeKey;
|
|
15554
15633
|
const hasLastGoodMetrics = metrics2.workspaceMetrics.length > 0 || metrics2.lineMetrics.length > 0;
|
|
15555
15634
|
const canReuseLastGoodMetrics = hasLastGoodMetrics && !isCurrentScopeResolved && (isLoading || !!error);
|
|
15556
|
-
const safeMetrics = isCurrentScopeResolved || canReuseLastGoodMetrics ? metrics2 : { workspaceMetrics: [], lineMetrics: [], metadata: void 0, efficiencyLegend: DEFAULT_EFFICIENCY_LEGEND };
|
|
15635
|
+
const safeMetrics = isCurrentScopeResolved || canReuseLastGoodMetrics ? metrics2 : { workspaceMetrics: [], blueComparisonWorkspaceMetrics: [], lineMetrics: [], metadata: void 0, efficiencyLegend: DEFAULT_EFFICIENCY_LEGEND };
|
|
15557
15636
|
return {
|
|
15558
15637
|
workspaceMetrics: safeMetrics?.workspaceMetrics || [],
|
|
15638
|
+
blueComparisonWorkspaceMetrics: safeMetrics?.blueComparisonWorkspaceMetrics || safeMetrics?.workspaceMetrics || [],
|
|
15559
15639
|
lineMetrics: safeMetrics?.lineMetrics || [],
|
|
15560
15640
|
efficiencyLegend: safeMetrics?.efficiencyLegend || DEFAULT_EFFICIENCY_LEGEND,
|
|
15561
15641
|
metadata: safeMetrics?.metadata,
|
|
@@ -22173,6 +22253,77 @@ var buildKpiLineHierarchy = (lines) => {
|
|
|
22173
22253
|
};
|
|
22174
22254
|
};
|
|
22175
22255
|
|
|
22256
|
+
// src/lib/utils/leaderboardGrouping.ts
|
|
22257
|
+
var isFiniteNumber2 = (value) => typeof value === "number" && Number.isFinite(value);
|
|
22258
|
+
var getEnabledFactoryArea = (line) => {
|
|
22259
|
+
if (!line.factory_area_id) return null;
|
|
22260
|
+
if (line.factory_area_enabled !== true) return null;
|
|
22261
|
+
const areaName = line.factory_area_name?.trim();
|
|
22262
|
+
if (!areaName) return null;
|
|
22263
|
+
return { id: line.factory_area_id, name: areaName };
|
|
22264
|
+
};
|
|
22265
|
+
var getLineEfficiency = (lineId, efficiencyByLineId, isLoading) => {
|
|
22266
|
+
if (efficiencyByLineId.has(lineId)) {
|
|
22267
|
+
const value = efficiencyByLineId.get(lineId);
|
|
22268
|
+
return isFiniteNumber2(value) ? value : null;
|
|
22269
|
+
}
|
|
22270
|
+
if (isLoading) return null;
|
|
22271
|
+
return 0;
|
|
22272
|
+
};
|
|
22273
|
+
var buildLineLeaderboardRows = ({
|
|
22274
|
+
lines,
|
|
22275
|
+
efficiencyByLineId,
|
|
22276
|
+
fallbackEfficiencyByLineId,
|
|
22277
|
+
isLoading
|
|
22278
|
+
}) => {
|
|
22279
|
+
const rows = [];
|
|
22280
|
+
const areaGroups = /* @__PURE__ */ new Map();
|
|
22281
|
+
lines.forEach((line) => {
|
|
22282
|
+
const area = getEnabledFactoryArea(line);
|
|
22283
|
+
if (!area) {
|
|
22284
|
+
const efficiency = getLineEfficiency(line.id, efficiencyByLineId, isLoading);
|
|
22285
|
+
rows.push({
|
|
22286
|
+
rowType: "line",
|
|
22287
|
+
id: line.id,
|
|
22288
|
+
displayName: line.line_name,
|
|
22289
|
+
line,
|
|
22290
|
+
lines: [line],
|
|
22291
|
+
efficiency,
|
|
22292
|
+
sortValue: isFiniteNumber2(efficiency) ? efficiency : -1
|
|
22293
|
+
});
|
|
22294
|
+
return;
|
|
22295
|
+
}
|
|
22296
|
+
const group = areaGroups.get(area.id);
|
|
22297
|
+
if (group) {
|
|
22298
|
+
group.lines.push(line);
|
|
22299
|
+
return;
|
|
22300
|
+
}
|
|
22301
|
+
areaGroups.set(area.id, {
|
|
22302
|
+
areaId: area.id,
|
|
22303
|
+
areaName: area.name,
|
|
22304
|
+
lines: [line]
|
|
22305
|
+
});
|
|
22306
|
+
});
|
|
22307
|
+
areaGroups.forEach((group) => {
|
|
22308
|
+
const validEfficiencies = group.lines.map((line) => efficiencyByLineId.get(line.id)).filter(isFiniteNumber2);
|
|
22309
|
+
const fallbackEfficiencies = validEfficiencies.length === 0 ? group.lines.map((line) => fallbackEfficiencyByLineId?.get(line.id)).filter(isFiniteNumber2) : [];
|
|
22310
|
+
const efficiencyValues = validEfficiencies.length > 0 ? validEfficiencies : fallbackEfficiencies;
|
|
22311
|
+
const shouldRenderZeroFallback = efficiencyValues.length === 0 && !!fallbackEfficiencyByLineId && !isLoading;
|
|
22312
|
+
if (efficiencyValues.length === 0 && !shouldRenderZeroFallback) return;
|
|
22313
|
+
const efficiency = shouldRenderZeroFallback ? 0 : efficiencyValues.reduce((sum, value) => sum + value, 0) / efficiencyValues.length;
|
|
22314
|
+
rows.push({
|
|
22315
|
+
rowType: "area",
|
|
22316
|
+
id: `area:${group.areaId}`,
|
|
22317
|
+
displayName: group.areaName,
|
|
22318
|
+
areaId: group.areaId,
|
|
22319
|
+
lines: group.lines,
|
|
22320
|
+
efficiency,
|
|
22321
|
+
sortValue: efficiency
|
|
22322
|
+
});
|
|
22323
|
+
});
|
|
22324
|
+
return rows.sort((left, right) => right.sortValue - left.sortValue).map((row, index) => ({ ...row, rank: index + 1 }));
|
|
22325
|
+
};
|
|
22326
|
+
|
|
22176
22327
|
// src/lib/utils/awards.ts
|
|
22177
22328
|
var toNumber2 = (value) => {
|
|
22178
22329
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
@@ -37459,7 +37610,58 @@ HourlyOutputChart.displayName = "HourlyOutputChart";
|
|
|
37459
37610
|
// src/components/dashboard/grid/videoGridMetricUtils.ts
|
|
37460
37611
|
var VIDEO_GRID_LEGEND_LABEL = "Real-Time efficiency";
|
|
37461
37612
|
var MAP_GRID_LEGEND_LABEL = "Efficiency";
|
|
37462
|
-
var
|
|
37613
|
+
var GREEN_STREAK_FRESHNESS_GRACE_MS = 2 * 60 * 1e3;
|
|
37614
|
+
var CONFIRMED_MINUTE_DURATION_MS = 60 * 1e3;
|
|
37615
|
+
var RECENT_FLOW_COMPUTED_FRESHNESS_MS = 120 * 1e3;
|
|
37616
|
+
var isFiniteNumber3 = (value) => typeof value === "number" && Number.isFinite(value);
|
|
37617
|
+
var padTwoDigits = (value) => String(value).padStart(2, "0");
|
|
37618
|
+
var parseTimestampMs = (value) => {
|
|
37619
|
+
if (!value) {
|
|
37620
|
+
return Number.NaN;
|
|
37621
|
+
}
|
|
37622
|
+
const timestampMs = Date.parse(value);
|
|
37623
|
+
return Number.isFinite(timestampMs) ? timestampMs : Number.NaN;
|
|
37624
|
+
};
|
|
37625
|
+
var isAllGreenStreakFresh = (workspace, anchorAtMs, nowMs2) => {
|
|
37626
|
+
const computedAt = workspace.recent_flow_computed_at;
|
|
37627
|
+
if (typeof computedAt === "string" && computedAt.trim()) {
|
|
37628
|
+
const computedAtMs = parseTimestampMs(computedAt);
|
|
37629
|
+
return Number.isFinite(computedAtMs) && nowMs2 - computedAtMs <= RECENT_FLOW_COMPUTED_FRESHNESS_MS;
|
|
37630
|
+
}
|
|
37631
|
+
return Number.isFinite(anchorAtMs) && nowMs2 <= anchorAtMs + CONFIRMED_MINUTE_DURATION_MS + GREEN_STREAK_FRESHNESS_GRACE_MS;
|
|
37632
|
+
};
|
|
37633
|
+
var formatAllGreenStreakDuration = (elapsedSeconds) => {
|
|
37634
|
+
const safeElapsedSeconds = Math.max(0, Math.floor(elapsedSeconds));
|
|
37635
|
+
const hours = Math.floor(safeElapsedSeconds / 3600);
|
|
37636
|
+
const minutes = Math.floor(safeElapsedSeconds % 3600 / 60);
|
|
37637
|
+
const seconds = safeElapsedSeconds % 60;
|
|
37638
|
+
if (hours > 0) {
|
|
37639
|
+
return `${hours}h ${padTwoDigits(minutes)}m ${padTwoDigits(seconds)}s`;
|
|
37640
|
+
}
|
|
37641
|
+
if (minutes > 0) {
|
|
37642
|
+
return `${minutes}m ${padTwoDigits(seconds)}s`;
|
|
37643
|
+
}
|
|
37644
|
+
return `${seconds}s`;
|
|
37645
|
+
};
|
|
37646
|
+
var getAllGreenStreakMilestone = (elapsedSeconds) => {
|
|
37647
|
+
const safeElapsedSeconds = Math.max(0, Math.floor(elapsedSeconds));
|
|
37648
|
+
const thirtyMinutesSeconds = 30 * 60;
|
|
37649
|
+
const oneHourSeconds = 60 * 60;
|
|
37650
|
+
if (safeElapsedSeconds < thirtyMinutesSeconds) {
|
|
37651
|
+
return null;
|
|
37652
|
+
}
|
|
37653
|
+
if (safeElapsedSeconds < oneHourSeconds) {
|
|
37654
|
+
return {
|
|
37655
|
+
milestoneSeconds: thirtyMinutesSeconds,
|
|
37656
|
+
headline: "30 min"
|
|
37657
|
+
};
|
|
37658
|
+
}
|
|
37659
|
+
const hours = Math.floor(safeElapsedSeconds / oneHourSeconds);
|
|
37660
|
+
return {
|
|
37661
|
+
milestoneSeconds: hours * oneHourSeconds,
|
|
37662
|
+
headline: `${hours * 60} min`
|
|
37663
|
+
};
|
|
37664
|
+
};
|
|
37463
37665
|
var isVideoGridRecentFlowEnabled = (workspace) => isRecentFlowVideoGridMetricMode(
|
|
37464
37666
|
workspace.video_grid_metric_mode,
|
|
37465
37667
|
workspace.assembly_enabled === true
|
|
@@ -37468,11 +37670,11 @@ var isVideoGridWipGated = (workspace) => isWipGatedVideoGridMetricMode(
|
|
|
37468
37670
|
workspace.video_grid_metric_mode,
|
|
37469
37671
|
workspace.assembly_enabled === true
|
|
37470
37672
|
);
|
|
37471
|
-
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) &&
|
|
37673
|
+
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) && isFiniteNumber3(workspace.recent_flow_percent);
|
|
37472
37674
|
var isVideoGridRecentFlowUnavailable = (workspace) => isVideoGridRecentFlowEnabled(workspace) && !hasVideoGridRecentFlow(workspace);
|
|
37473
37675
|
var getRawVideoGridMetricValue = (workspace) => {
|
|
37474
37676
|
const recentFlowPercent = workspace.recent_flow_percent;
|
|
37475
|
-
if (hasVideoGridRecentFlow(workspace) &&
|
|
37677
|
+
if (hasVideoGridRecentFlow(workspace) && isFiniteNumber3(recentFlowPercent)) {
|
|
37476
37678
|
return recentFlowPercent;
|
|
37477
37679
|
}
|
|
37478
37680
|
if (isVideoGridRecentFlowUnavailable(workspace)) {
|
|
@@ -37481,9 +37683,63 @@ var getRawVideoGridMetricValue = (workspace) => {
|
|
|
37481
37683
|
return workspace.efficiency;
|
|
37482
37684
|
};
|
|
37483
37685
|
var hasIncomingWipMapping = (workspace) => Boolean(workspace.incoming_wip_buffer_name);
|
|
37686
|
+
var getVideoGridWorkspaceKey = (workspace) => workspace.workspace_uuid || `${workspace.line_id || "unknown"}:${workspace.workspace_name || "unknown"}`;
|
|
37687
|
+
var getVideoGridBlueComparisonGroupKey = (workspace) => {
|
|
37688
|
+
const factoryAreaId = typeof workspace.factory_area_id === "string" ? workspace.factory_area_id.trim() : "";
|
|
37689
|
+
if (factoryAreaId && workspace.factory_area_enabled === true) {
|
|
37690
|
+
return `area:${factoryAreaId}`;
|
|
37691
|
+
}
|
|
37692
|
+
const lineId = typeof workspace.line_id === "string" ? workspace.line_id.trim() : "";
|
|
37693
|
+
return lineId ? `line:${lineId}` : null;
|
|
37694
|
+
};
|
|
37695
|
+
var isVideoGridBlueCandidate = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => hasVideoGridRecentFlow(workspace) && isFiniteNumber3(workspace.recent_flow_percent) && workspace.recent_flow_percent >= legend.green_min;
|
|
37696
|
+
var selectVideoGridBlueWinnerIds = (workspaces, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
37697
|
+
const candidatesByGroup = /* @__PURE__ */ new Map();
|
|
37698
|
+
for (const workspace of workspaces) {
|
|
37699
|
+
if (!isVideoGridBlueCandidate(workspace, legend)) {
|
|
37700
|
+
continue;
|
|
37701
|
+
}
|
|
37702
|
+
const groupKey = getVideoGridBlueComparisonGroupKey(workspace);
|
|
37703
|
+
if (!groupKey) {
|
|
37704
|
+
continue;
|
|
37705
|
+
}
|
|
37706
|
+
const candidates = candidatesByGroup.get(groupKey) || [];
|
|
37707
|
+
candidates.push(workspace);
|
|
37708
|
+
candidatesByGroup.set(groupKey, candidates);
|
|
37709
|
+
}
|
|
37710
|
+
const winners = /* @__PURE__ */ new Set();
|
|
37711
|
+
for (const candidates of candidatesByGroup.values()) {
|
|
37712
|
+
candidates.sort((left, right) => {
|
|
37713
|
+
const leftCurrent = left.recent_flow_percent;
|
|
37714
|
+
const rightCurrent = right.recent_flow_percent;
|
|
37715
|
+
if (rightCurrent !== leftCurrent) {
|
|
37716
|
+
return rightCurrent - leftCurrent;
|
|
37717
|
+
}
|
|
37718
|
+
const leftAverage = isFiniteNumber3(left.avg_recent_flow) ? left.avg_recent_flow : Number.NEGATIVE_INFINITY;
|
|
37719
|
+
const rightAverage = isFiniteNumber3(right.avg_recent_flow) ? right.avg_recent_flow : Number.NEGATIVE_INFINITY;
|
|
37720
|
+
if (rightAverage !== leftAverage) {
|
|
37721
|
+
return rightAverage - leftAverage;
|
|
37722
|
+
}
|
|
37723
|
+
const lineCompare = (left.line_id || "").localeCompare(right.line_id || "");
|
|
37724
|
+
if (lineCompare !== 0) {
|
|
37725
|
+
return lineCompare;
|
|
37726
|
+
}
|
|
37727
|
+
const nameCompare = (left.workspace_name || "").localeCompare(right.workspace_name || "");
|
|
37728
|
+
if (nameCompare !== 0) {
|
|
37729
|
+
return nameCompare;
|
|
37730
|
+
}
|
|
37731
|
+
return getVideoGridWorkspaceKey(left).localeCompare(getVideoGridWorkspaceKey(right));
|
|
37732
|
+
});
|
|
37733
|
+
const winner = candidates[0];
|
|
37734
|
+
if (winner) {
|
|
37735
|
+
winners.add(getVideoGridWorkspaceKey(winner));
|
|
37736
|
+
}
|
|
37737
|
+
}
|
|
37738
|
+
return winners;
|
|
37739
|
+
};
|
|
37484
37740
|
var getVideoGridBaseColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
37485
37741
|
const metricValue = getRawVideoGridMetricValue(workspace);
|
|
37486
|
-
if (!
|
|
37742
|
+
if (!isFiniteNumber3(metricValue)) {
|
|
37487
37743
|
return "neutral";
|
|
37488
37744
|
}
|
|
37489
37745
|
return getEfficiencyColor(metricValue, legend);
|
|
@@ -37504,7 +37760,7 @@ var isLowWipGreenOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
|
37504
37760
|
if (!hasIncomingWipMapping(workspace)) {
|
|
37505
37761
|
return false;
|
|
37506
37762
|
}
|
|
37507
|
-
return
|
|
37763
|
+
return isFiniteNumber3(workspace.incoming_wip_current) && workspace.incoming_wip_current <= 1;
|
|
37508
37764
|
};
|
|
37509
37765
|
var isHighEfficiencyRedFlowOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
37510
37766
|
if (workspace.scheduled_break_active === true) {
|
|
@@ -37522,7 +37778,7 @@ var isHighEfficiencyRedFlowOverride = (workspace, legend = DEFAULT_EFFICIENCY_LE
|
|
|
37522
37778
|
if (getVideoGridBaseColorState(workspace, legend) !== "red") {
|
|
37523
37779
|
return false;
|
|
37524
37780
|
}
|
|
37525
|
-
return
|
|
37781
|
+
return isFiniteNumber3(workspace.efficiency) && workspace.efficiency > 100;
|
|
37526
37782
|
};
|
|
37527
37783
|
var getVideoGridMetricValue = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => isHighEfficiencyRedFlowOverride(workspace, legend) ? workspace.efficiency : getRawVideoGridMetricValue(workspace);
|
|
37528
37784
|
var toMinuteBucket = (minuteBucket) => Number.isFinite(minuteBucket) ? Math.floor(minuteBucket) : Math.floor(Date.now() / 6e4);
|
|
@@ -37551,7 +37807,10 @@ var getSyntheticLowWipDisplayValue = (workspace, minuteBucket) => {
|
|
|
37551
37807
|
return 100 + offset;
|
|
37552
37808
|
};
|
|
37553
37809
|
var getVideoGridDisplayValue = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND, minuteBucket) => isLowWipGreenOverride(workspace, legend) ? getSyntheticLowWipDisplayValue(workspace, minuteBucket) : getVideoGridMetricValue(workspace, legend);
|
|
37554
|
-
var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
37810
|
+
var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND, blueWinnerIds) => {
|
|
37811
|
+
if (blueWinnerIds?.has(getVideoGridWorkspaceKey(workspace)) && isVideoGridBlueCandidate(workspace, legend)) {
|
|
37812
|
+
return "blue";
|
|
37813
|
+
}
|
|
37555
37814
|
const baseColor = getVideoGridBaseColorState(workspace, legend);
|
|
37556
37815
|
if (!hasVideoGridRecentFlow(workspace)) {
|
|
37557
37816
|
return baseColor;
|
|
@@ -37571,11 +37830,54 @@ var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) =>
|
|
|
37571
37830
|
if (!hasIncomingWipMapping(workspace)) {
|
|
37572
37831
|
return baseColor;
|
|
37573
37832
|
}
|
|
37574
|
-
if (!
|
|
37833
|
+
if (!isFiniteNumber3(workspace.incoming_wip_current)) {
|
|
37575
37834
|
return "neutral";
|
|
37576
37835
|
}
|
|
37577
37836
|
return baseColor;
|
|
37578
37837
|
};
|
|
37838
|
+
var hasAllVideoGridWorkspacesGreen = (workspaces, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
37839
|
+
const visibleWorkspaces = workspaces.filter((workspace) => Boolean(workspace.workspace_uuid || workspace.workspace_name));
|
|
37840
|
+
return visibleWorkspaces.length > 0 && visibleWorkspaces.every((workspace) => getVideoGridColorState(workspace, legend) === "green");
|
|
37841
|
+
};
|
|
37842
|
+
var getAllVideoGridGreenStreakDisplay = (workspaces, legend = DEFAULT_EFFICIENCY_LEGEND, nowMs2 = Date.now()) => {
|
|
37843
|
+
const visibleWorkspaces = workspaces.filter((workspace) => Boolean(workspace.workspace_uuid || workspace.workspace_name));
|
|
37844
|
+
if (visibleWorkspaces.length === 0 || !hasAllVideoGridWorkspacesGreen(visibleWorkspaces, legend)) {
|
|
37845
|
+
return null;
|
|
37846
|
+
}
|
|
37847
|
+
const activeStreaks = visibleWorkspaces.map((workspace) => {
|
|
37848
|
+
const startedAt = workspace.video_grid_green_streak_started_at;
|
|
37849
|
+
const anchorAt = workspace.video_grid_green_streak_anchor_at;
|
|
37850
|
+
const streakMinutes = workspace.video_grid_green_streak_minutes;
|
|
37851
|
+
const startedAtMs = parseTimestampMs(startedAt);
|
|
37852
|
+
const anchorAtMs = parseTimestampMs(anchorAt);
|
|
37853
|
+
const isFresh = isAllGreenStreakFresh(workspace, anchorAtMs, nowMs2);
|
|
37854
|
+
const tickOriginAtMs = anchorAtMs + CONFIRMED_MINUTE_DURATION_MS;
|
|
37855
|
+
if (workspace.video_grid_green_streak_active === true && isFiniteNumber3(streakMinutes) && streakMinutes > 0 && startedAt && anchorAt && Number.isFinite(startedAtMs) && isFresh) {
|
|
37856
|
+
return {
|
|
37857
|
+
startedAt,
|
|
37858
|
+
startedAtMs,
|
|
37859
|
+
anchorAt,
|
|
37860
|
+
streakMinutes,
|
|
37861
|
+
tickOriginAtMs
|
|
37862
|
+
};
|
|
37863
|
+
}
|
|
37864
|
+
return null;
|
|
37865
|
+
});
|
|
37866
|
+
if (activeStreaks.some((streak) => streak === null)) {
|
|
37867
|
+
return null;
|
|
37868
|
+
}
|
|
37869
|
+
const strictestStartedAt = activeStreaks.reduce((latest, current) => current.streakMinutes < latest.streakMinutes || current.streakMinutes === latest.streakMinutes && current.startedAtMs > latest.startedAtMs ? current : latest);
|
|
37870
|
+
const confirmedSeconds = Math.max(0, Math.floor(strictestStartedAt.streakMinutes * 60));
|
|
37871
|
+
return {
|
|
37872
|
+
label: "All green",
|
|
37873
|
+
elapsedSeconds: confirmedSeconds,
|
|
37874
|
+
confirmedSeconds,
|
|
37875
|
+
durationText: formatAllGreenStreakDuration(confirmedSeconds),
|
|
37876
|
+
startedAt: strictestStartedAt.startedAt,
|
|
37877
|
+
anchorAt: strictestStartedAt.anchorAt,
|
|
37878
|
+
tickOriginAtMs: strictestStartedAt.tickOriginAtMs
|
|
37879
|
+
};
|
|
37880
|
+
};
|
|
37579
37881
|
var getVideoGridLegendLabel = (workspaces) => {
|
|
37580
37882
|
const visibleWorkspaces = workspaces;
|
|
37581
37883
|
if (visibleWorkspaces.length === 0) {
|
|
@@ -37606,6 +37908,7 @@ var VideoCard = React144__namespace.default.memo(({
|
|
|
37606
37908
|
compact = false,
|
|
37607
37909
|
displayMinuteBucket,
|
|
37608
37910
|
displayName,
|
|
37911
|
+
isBlueBest = false,
|
|
37609
37912
|
lastSeenLabel,
|
|
37610
37913
|
hasRecentHealthSignal: hasRecentHealthSignal2 = false,
|
|
37611
37914
|
onMouseEnter,
|
|
@@ -37627,7 +37930,11 @@ var VideoCard = React144__namespace.default.memo(({
|
|
|
37627
37930
|
const workspaceDisplayName = displayName || workspace.displayName || workspace.workspace_name;
|
|
37628
37931
|
const videoGridMetricValue = getVideoGridMetricValue(workspace, effectiveLegend);
|
|
37629
37932
|
const videoGridDisplayValue = getVideoGridDisplayValue(workspace, effectiveLegend, displayMinuteBucket);
|
|
37630
|
-
const videoGridColorState = getVideoGridColorState(
|
|
37933
|
+
const videoGridColorState = getVideoGridColorState(
|
|
37934
|
+
workspace,
|
|
37935
|
+
effectiveLegend,
|
|
37936
|
+
isBlueBest ? /* @__PURE__ */ new Set([getVideoGridWorkspaceKey(workspace)]) : void 0
|
|
37937
|
+
);
|
|
37631
37938
|
const isRecentFlowCard = isVideoGridRecentFlowEnabled(workspace);
|
|
37632
37939
|
const isHighEfficiencyOverride = isHighEfficiencyRedFlowOverride(workspace, effectiveLegend);
|
|
37633
37940
|
const hasDisplayMetric = typeof videoGridDisplayValue === "number" && Number.isFinite(videoGridDisplayValue);
|
|
@@ -37635,9 +37942,9 @@ var VideoCard = React144__namespace.default.memo(({
|
|
|
37635
37942
|
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
37636
37943
|
const badgeTitle = isHighEfficiencyOverride ? `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%` : hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
37637
37944
|
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
37638
|
-
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
37639
|
-
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
37640
|
-
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
37945
|
+
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "blue" ? "bg-[#0EA5E9]/30" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
37946
|
+
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "blue" ? "bg-[#0EA5E9]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
37947
|
+
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "blue" ? "Best" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
37641
37948
|
const trendInfo = workspace.trend !== void 0 ? getTrendArrowAndColor(workspace.trend) : null;
|
|
37642
37949
|
const handleClick = React144.useCallback(() => {
|
|
37643
37950
|
trackCoreEvent("Workspace Card Clicked", {
|
|
@@ -37758,6 +38065,9 @@ var VideoCard = React144__namespace.default.memo(({
|
|
|
37758
38065
|
if (prevProps.displayName !== nextProps.displayName) {
|
|
37759
38066
|
return false;
|
|
37760
38067
|
}
|
|
38068
|
+
if (prevProps.isBlueBest !== nextProps.isBlueBest) {
|
|
38069
|
+
return false;
|
|
38070
|
+
}
|
|
37761
38071
|
if (prevProps.lastSeenLabel !== nextProps.lastSeenLabel) {
|
|
37762
38072
|
return false;
|
|
37763
38073
|
}
|
|
@@ -37799,6 +38109,7 @@ var hasRecentHealthSignal = (lastHeartbeat) => {
|
|
|
37799
38109
|
};
|
|
37800
38110
|
var VideoGridView = React144__namespace.default.memo(({
|
|
37801
38111
|
workspaces,
|
|
38112
|
+
blueComparisonWorkspaces,
|
|
37802
38113
|
selectedLine,
|
|
37803
38114
|
className = "",
|
|
37804
38115
|
legend,
|
|
@@ -37927,6 +38238,7 @@ var VideoGridView = React144__namespace.default.memo(({
|
|
|
37927
38238
|
return a.workspace_name.localeCompare(b.workspace_name);
|
|
37928
38239
|
});
|
|
37929
38240
|
}, [filteredWorkspaces]);
|
|
38241
|
+
const blueWinnerIds = React144.useMemo(() => selectVideoGridBlueWinnerIds(blueComparisonWorkspaces || sortedWorkspaces, effectiveLegend), [blueComparisonWorkspaces, sortedWorkspaces, effectiveLegend]);
|
|
37930
38242
|
const streamsResolvedForWorkspaceSet = resolvedStreamWorkspaceKey === workspaceIdsKey;
|
|
37931
38243
|
const resolveWorkspaceDisplayName = React144.useCallback((workspace) => {
|
|
37932
38244
|
return workspace.displayName || displayNames[`${workspace.line_id}_${workspace.workspace_name}`] || workspace.workspace_name;
|
|
@@ -38135,11 +38447,13 @@ var VideoGridView = React144__namespace.default.memo(({
|
|
|
38135
38447
|
isR2Stream,
|
|
38136
38448
|
shouldPlay,
|
|
38137
38449
|
lastSeenLabel,
|
|
38138
|
-
hasRecentHealthSignal: hasRecentHealthSignal(workspaceHealth?.lastHeartbeat)
|
|
38450
|
+
hasRecentHealthSignal: hasRecentHealthSignal(workspaceHealth?.lastHeartbeat),
|
|
38451
|
+
isBlueBest: blueWinnerIds.has(getVideoGridWorkspaceKey(workspace))
|
|
38139
38452
|
};
|
|
38140
38453
|
});
|
|
38141
38454
|
}, [
|
|
38142
38455
|
sortedWorkspaces,
|
|
38456
|
+
blueWinnerIds,
|
|
38143
38457
|
visibleWorkspaces,
|
|
38144
38458
|
getWorkspaceCropping,
|
|
38145
38459
|
videoStreamsByWorkspaceId,
|
|
@@ -38186,6 +38500,7 @@ var VideoGridView = React144__namespace.default.memo(({
|
|
|
38186
38500
|
useRAF: effectiveUseRAF,
|
|
38187
38501
|
displayMinuteBucket,
|
|
38188
38502
|
compact: !selectedLine,
|
|
38503
|
+
isBlueBest: card.isBlueBest,
|
|
38189
38504
|
onMouseEnter: onWorkspaceHover ? () => onWorkspaceHover(card.workspaceId) : void 0,
|
|
38190
38505
|
onMouseLeave: onWorkspaceHoverEnd ? () => onWorkspaceHoverEnd(card.workspaceId) : void 0
|
|
38191
38506
|
}
|
|
@@ -54743,6 +55058,10 @@ var Legend5 = ({
|
|
|
54743
55058
|
":"
|
|
54744
55059
|
] }),
|
|
54745
55060
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:gap-4", children: [
|
|
55061
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
55062
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full bg-[#0EA5E9]" }),
|
|
55063
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Best" })
|
|
55064
|
+
] }),
|
|
54746
55065
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
54747
55066
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full bg-[#00AB45]" }),
|
|
54748
55067
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatPercentRange(effectiveLegend.green_min, effectiveLegend.green_max) })
|
|
@@ -54861,6 +55180,7 @@ var WorkspaceGridItem = React144__namespace.default.memo(({
|
|
|
54861
55180
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
54862
55181
|
var WorkspaceGrid = React144__namespace.default.memo(({
|
|
54863
55182
|
workspaces,
|
|
55183
|
+
blueComparisonWorkspaces,
|
|
54864
55184
|
isPdfMode = false,
|
|
54865
55185
|
customWorkspacePositions,
|
|
54866
55186
|
lineNames = {},
|
|
@@ -54877,13 +55197,8 @@ var WorkspaceGrid = React144__namespace.default.memo(({
|
|
|
54877
55197
|
onWorkspaceHoverEnd,
|
|
54878
55198
|
toolbarRightContent
|
|
54879
55199
|
}) => {
|
|
54880
|
-
const
|
|
54881
|
-
const mapViewEnabled = dashboardConfig?.mapViewConfig?.enabled ?? false;
|
|
55200
|
+
const mapViewEnabled = false;
|
|
54882
55201
|
const [viewMode, setViewMode] = React144.useState(() => {
|
|
54883
|
-
if (typeof window !== "undefined" && mapViewEnabled) {
|
|
54884
|
-
const saved = localStorage.getItem("home-view-mode");
|
|
54885
|
-
return saved === "map" || saved === "video" ? saved : "video";
|
|
54886
|
-
}
|
|
54887
55202
|
return "video";
|
|
54888
55203
|
});
|
|
54889
55204
|
React144.useEffect(() => {
|
|
@@ -54892,7 +55207,7 @@ var WorkspaceGrid = React144__namespace.default.memo(({
|
|
|
54892
55207
|
total_workspaces: workspaces.length
|
|
54893
55208
|
});
|
|
54894
55209
|
}, [workspaces.length]);
|
|
54895
|
-
|
|
55210
|
+
React144.useCallback(() => {
|
|
54896
55211
|
const newMode = viewMode === "video" ? "map" : "video";
|
|
54897
55212
|
setViewMode(newMode);
|
|
54898
55213
|
if (typeof window !== "undefined") {
|
|
@@ -54906,8 +55221,8 @@ var WorkspaceGrid = React144__namespace.default.memo(({
|
|
|
54906
55221
|
}, [viewMode]);
|
|
54907
55222
|
const { VideoGridView: VideoGridViewComponent, MapGridView: MapGridViewComponent } = useRegistry();
|
|
54908
55223
|
const legendMetricLabel = React144.useMemo(
|
|
54909
|
-
() =>
|
|
54910
|
-
[
|
|
55224
|
+
() => getVideoGridLegendLabel(workspaces),
|
|
55225
|
+
[workspaces]
|
|
54911
55226
|
);
|
|
54912
55227
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col w-full h-full overflow-hidden bg-slate-50/50 ${className}`, children: [
|
|
54913
55228
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -54919,21 +55234,7 @@ var WorkspaceGrid = React144__namespace.default.memo(({
|
|
|
54919
55234
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex bg-white/95 rounded-lg shadow-sm px-4 py-2 border border-slate-200/60 backdrop-blur-sm", children: /* @__PURE__ */ jsxRuntime.jsx(Legend5, { legend, metricLabel: legendMetricLabel }) }) }),
|
|
54920
55235
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-3 shrink-0", children: [
|
|
54921
55236
|
toolbarRightContent,
|
|
54922
|
-
mapViewEnabled
|
|
54923
|
-
"button",
|
|
54924
|
-
{
|
|
54925
|
-
onClick: handleViewModeToggle,
|
|
54926
|
-
className: "flex items-center gap-2 px-3 py-1.5 bg-white border border-slate-200 rounded-md shadow-sm hover:bg-slate-50 transition-colors duration-200 text-slate-700",
|
|
54927
|
-
title: viewMode === "video" ? "Switch to Map View" : "Switch to Video View",
|
|
54928
|
-
children: viewMode === "video" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
54929
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Map, { className: "w-4 h-4 text-slate-500" }),
|
|
54930
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline text-sm font-medium", children: "Map View" })
|
|
54931
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
54932
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Video, { className: "w-4 h-4 text-slate-500" }),
|
|
54933
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline text-sm font-medium", children: "Video View" })
|
|
54934
|
-
] })
|
|
54935
|
-
}
|
|
54936
|
-
)
|
|
55237
|
+
mapViewEnabled
|
|
54937
55238
|
] })
|
|
54938
55239
|
]
|
|
54939
55240
|
}
|
|
@@ -54951,6 +55252,7 @@ var WorkspaceGrid = React144__namespace.default.memo(({
|
|
|
54951
55252
|
VideoGridViewComponent,
|
|
54952
55253
|
{
|
|
54953
55254
|
workspaces,
|
|
55255
|
+
blueComparisonWorkspaces,
|
|
54954
55256
|
lineNames,
|
|
54955
55257
|
lineOrder,
|
|
54956
55258
|
videoSources,
|
|
@@ -57247,12 +57549,25 @@ var SideNavBar = React144.memo(({
|
|
|
57247
57549
|
console.log("\u{1F50D} [SideNavBar] ticketsConfig:", dashboardConfig?.ticketsConfig);
|
|
57248
57550
|
console.log("\u{1F50D} [SideNavBar] ticketsEnabled:", ticketsEnabled);
|
|
57249
57551
|
const pathname = propPathname || router$1.pathname;
|
|
57552
|
+
const rawCurrentTabQuery = currentQuery?.tab ?? router$1.query?.tab;
|
|
57553
|
+
const currentTabQuery = Array.isArray(rawCurrentTabQuery) ? rawCurrentTabQuery[0] : rawCurrentTabQuery;
|
|
57554
|
+
const isKpisLeaderboardRoute = pathname === "/kpis" && currentTabQuery === "leaderboard";
|
|
57555
|
+
const isPathActive = React144.useCallback((path) => {
|
|
57556
|
+
if (path === "/") return pathname === "/";
|
|
57557
|
+
if (path === "/leaderboard") {
|
|
57558
|
+
return pathname === "/leaderboard" || pathname.startsWith("/leaderboard/");
|
|
57559
|
+
}
|
|
57560
|
+
if (path === "/kpis") {
|
|
57561
|
+
return pathname === "/kpis" || pathname.startsWith("/kpis/");
|
|
57562
|
+
}
|
|
57563
|
+
return pathname === path || pathname.startsWith(path + "/");
|
|
57564
|
+
}, [pathname]);
|
|
57250
57565
|
const getButtonClasses = React144.useCallback((path) => {
|
|
57251
|
-
const isActive =
|
|
57566
|
+
const isActive = isPathActive(path);
|
|
57252
57567
|
return `w-full flex flex-col items-center justify-center py-4 sm:py-3 px-2 sm:px-1 rounded-lg relative group min-h-[44px] sm:min-h-0
|
|
57253
57568
|
${isActive ? "bg-blue-50/80 text-blue-600 font-medium" : "hover:bg-gray-50 text-gray-500 hover:text-gray-700 font-medium active:bg-gray-100"}
|
|
57254
57569
|
transition-all duration-200 ease-out focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2`;
|
|
57255
|
-
}, [
|
|
57570
|
+
}, [isPathActive]);
|
|
57256
57571
|
const buildDashboardSurfaceTrackingEvent = React144.useCallback((source, destinationPath, dashboardSurface) => ({
|
|
57257
57572
|
name: ROOT_DASHBOARD_EVENT_NAMES[dashboardSurface],
|
|
57258
57573
|
properties: {
|
|
@@ -57285,17 +57600,24 @@ var SideNavBar = React144.memo(({
|
|
|
57285
57600
|
onMobileMenuClose?.();
|
|
57286
57601
|
}, [navigate, onMobileMenuClose, buildDashboardSurfaceTrackingEvent]);
|
|
57287
57602
|
const handleKPIsClick = React144.useCallback(() => {
|
|
57288
|
-
|
|
57289
|
-
|
|
57290
|
-
|
|
57291
|
-
|
|
57292
|
-
|
|
57293
|
-
page_type: "overview"
|
|
57294
|
-
}
|
|
57603
|
+
const trackingEvent = {
|
|
57604
|
+
name: "KPI Page Clicked",
|
|
57605
|
+
properties: {
|
|
57606
|
+
source: "side_nav",
|
|
57607
|
+
page_type: "overview"
|
|
57295
57608
|
}
|
|
57609
|
+
};
|
|
57610
|
+
if (isKpisLeaderboardRoute) {
|
|
57611
|
+
trackCoreEvent(trackingEvent.name, trackingEvent.properties);
|
|
57612
|
+
void router$1.replace("/kpis", void 0, { shallow: false });
|
|
57613
|
+
onMobileMenuClose?.();
|
|
57614
|
+
return;
|
|
57615
|
+
}
|
|
57616
|
+
navigate(`/kpis`, {
|
|
57617
|
+
trackingEvent
|
|
57296
57618
|
});
|
|
57297
57619
|
onMobileMenuClose?.();
|
|
57298
|
-
}, [navigate, onMobileMenuClose]);
|
|
57620
|
+
}, [isKpisLeaderboardRoute, navigate, onMobileMenuClose, router$1]);
|
|
57299
57621
|
const handleImprovementClick = React144.useCallback(() => {
|
|
57300
57622
|
navigate("/improvement-center", {
|
|
57301
57623
|
trackingEvent: {
|
|
@@ -57565,14 +57887,14 @@ var SideNavBar = React144.memo(({
|
|
|
57565
57887
|
});
|
|
57566
57888
|
onMobileMenuClose?.();
|
|
57567
57889
|
}, [navigate, onMobileMenuClose, buildDashboardSurfaceTrackingEvent, rootDashboardSurface]);
|
|
57568
|
-
const homeButtonClasses = React144.useMemo(() => getButtonClasses("/"), [getButtonClasses
|
|
57569
|
-
const liveButtonClasses = React144.useMemo(() => getButtonClasses("/live-monitor"), [getButtonClasses
|
|
57570
|
-
const leaderboardButtonClasses = React144.useMemo(() => getButtonClasses("/leaderboard"), [getButtonClasses
|
|
57571
|
-
const kpisButtonClasses = React144.useMemo(() => getButtonClasses("/kpis"), [getButtonClasses
|
|
57572
|
-
const improvementButtonClasses = React144.useMemo(() => getButtonClasses("/improvement-center"), [getButtonClasses
|
|
57573
|
-
React144.useMemo(() => getButtonClasses("/supervisor-management"), [getButtonClasses
|
|
57574
|
-
const skusButtonClasses = React144.useMemo(() => getButtonClasses("/skus"), [getButtonClasses
|
|
57575
|
-
const healthButtonClasses = React144.useMemo(() => getButtonClasses("/health"), [getButtonClasses
|
|
57890
|
+
const homeButtonClasses = React144.useMemo(() => getButtonClasses("/"), [getButtonClasses]);
|
|
57891
|
+
const liveButtonClasses = React144.useMemo(() => getButtonClasses("/live-monitor"), [getButtonClasses]);
|
|
57892
|
+
const leaderboardButtonClasses = React144.useMemo(() => getButtonClasses("/leaderboard"), [getButtonClasses]);
|
|
57893
|
+
const kpisButtonClasses = React144.useMemo(() => getButtonClasses("/kpis"), [getButtonClasses]);
|
|
57894
|
+
const improvementButtonClasses = React144.useMemo(() => getButtonClasses("/improvement-center"), [getButtonClasses]);
|
|
57895
|
+
React144.useMemo(() => getButtonClasses("/supervisor-management"), [getButtonClasses]);
|
|
57896
|
+
const skusButtonClasses = React144.useMemo(() => getButtonClasses("/skus"), [getButtonClasses]);
|
|
57897
|
+
const healthButtonClasses = React144.useMemo(() => getButtonClasses("/health"), [getButtonClasses]);
|
|
57576
57898
|
const settingsButtonClasses = React144.useMemo(() => {
|
|
57577
57899
|
const isAnyItemActive = settingsItems.some((item) => item.isActive);
|
|
57578
57900
|
const isActive = isSettingsOpen || isAnyItemActive;
|
|
@@ -57606,7 +57928,7 @@ var SideNavBar = React144.memo(({
|
|
|
57606
57928
|
"aria-label": "Home",
|
|
57607
57929
|
tabIndex: 0,
|
|
57608
57930
|
role: "tab",
|
|
57609
|
-
"aria-selected":
|
|
57931
|
+
"aria-selected": isPathActive("/"),
|
|
57610
57932
|
children: [
|
|
57611
57933
|
/* @__PURE__ */ jsxRuntime.jsx(outline.HomeIcon, { className: "w-5 h-5 mb-1" }),
|
|
57612
57934
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Home" })
|
|
@@ -57621,7 +57943,7 @@ var SideNavBar = React144.memo(({
|
|
|
57621
57943
|
"aria-label": "Monitor",
|
|
57622
57944
|
tabIndex: 0,
|
|
57623
57945
|
role: "tab",
|
|
57624
|
-
"aria-selected":
|
|
57946
|
+
"aria-selected": isPathActive("/live-monitor"),
|
|
57625
57947
|
children: [
|
|
57626
57948
|
/* @__PURE__ */ jsxRuntime.jsx(outline.VideoCameraIcon, { className: "w-5 h-5 mb-1" }),
|
|
57627
57949
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Monitor" })
|
|
@@ -57638,7 +57960,7 @@ var SideNavBar = React144.memo(({
|
|
|
57638
57960
|
"aria-label": "Leaderboard",
|
|
57639
57961
|
tabIndex: 0,
|
|
57640
57962
|
role: "tab",
|
|
57641
|
-
"aria-selected":
|
|
57963
|
+
"aria-selected": isPathActive("/leaderboard"),
|
|
57642
57964
|
children: [
|
|
57643
57965
|
/* @__PURE__ */ jsxRuntime.jsx(outline.TrophyIcon, { className: "w-5 h-5 mb-1" }),
|
|
57644
57966
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Leaders" })
|
|
@@ -57653,7 +57975,7 @@ var SideNavBar = React144.memo(({
|
|
|
57653
57975
|
"aria-label": "Lines",
|
|
57654
57976
|
tabIndex: 0,
|
|
57655
57977
|
role: "tab",
|
|
57656
|
-
"aria-selected":
|
|
57978
|
+
"aria-selected": isPathActive("/kpis"),
|
|
57657
57979
|
children: [
|
|
57658
57980
|
/* @__PURE__ */ jsxRuntime.jsx(outline.ChartBarIcon, { className: "w-5 h-5 mb-1" }),
|
|
57659
57981
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Lines" })
|
|
@@ -57668,7 +57990,7 @@ var SideNavBar = React144.memo(({
|
|
|
57668
57990
|
"aria-label": "Improvement Center",
|
|
57669
57991
|
tabIndex: 0,
|
|
57670
57992
|
role: "tab",
|
|
57671
|
-
"aria-selected":
|
|
57993
|
+
"aria-selected": isPathActive("/improvement-center"),
|
|
57672
57994
|
children: [
|
|
57673
57995
|
/* @__PURE__ */ jsxRuntime.jsx(outline.LightBulbIcon, { className: "w-5 h-5 mb-1" }),
|
|
57674
57996
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight text-center", children: "Improve" })
|
|
@@ -57684,7 +58006,7 @@ var SideNavBar = React144.memo(({
|
|
|
57684
58006
|
"aria-label": "SKU Management",
|
|
57685
58007
|
tabIndex: 0,
|
|
57686
58008
|
role: "tab",
|
|
57687
|
-
"aria-selected":
|
|
58009
|
+
"aria-selected": isPathActive("/skus"),
|
|
57688
58010
|
children: [
|
|
57689
58011
|
/* @__PURE__ */ jsxRuntime.jsx(outline.CubeIcon, { className: "w-5 h-5 mb-1" }),
|
|
57690
58012
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "SKUs" })
|
|
@@ -57699,7 +58021,7 @@ var SideNavBar = React144.memo(({
|
|
|
57699
58021
|
"aria-label": "System Health",
|
|
57700
58022
|
tabIndex: 0,
|
|
57701
58023
|
role: "tab",
|
|
57702
|
-
"aria-selected":
|
|
58024
|
+
"aria-selected": isPathActive("/health"),
|
|
57703
58025
|
children: [
|
|
57704
58026
|
/* @__PURE__ */ jsxRuntime.jsx(outline.HeartIcon, { className: "w-5 h-5 mb-1" }),
|
|
57705
58027
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Health" })
|
|
@@ -57729,17 +58051,12 @@ var SideNavBar = React144.memo(({
|
|
|
57729
58051
|
) })
|
|
57730
58052
|
] });
|
|
57731
58053
|
const MobileNavigationContent = () => {
|
|
57732
|
-
const isActive = (path) => {
|
|
57733
|
-
if (path === "/" && pathname === "/") return true;
|
|
57734
|
-
if (path !== "/" && pathname.startsWith(path)) return true;
|
|
57735
|
-
return false;
|
|
57736
|
-
};
|
|
57737
58054
|
const getMobileButtonClass = (path) => {
|
|
57738
|
-
const active =
|
|
58055
|
+
const active = isPathActive(path);
|
|
57739
58056
|
return `w-full flex items-center gap-3 px-5 py-3.5 rounded-lg transition-colors active:scale-[0.98] ${active ? "bg-blue-50 text-blue-700" : "text-gray-700 hover:bg-gray-100 active:bg-gray-200"}`;
|
|
57740
58057
|
};
|
|
57741
58058
|
const getIconClass = (path) => {
|
|
57742
|
-
const active =
|
|
58059
|
+
const active = isPathActive(path);
|
|
57743
58060
|
return `w-7 h-7 ${active ? "text-blue-600" : "text-gray-600"}`;
|
|
57744
58061
|
};
|
|
57745
58062
|
const handleMobileNavClick = (handler) => {
|
|
@@ -63673,6 +63990,8 @@ var HelpView = ({
|
|
|
63673
63990
|
};
|
|
63674
63991
|
var AuthenticatedHelpView = withAuth(HelpView);
|
|
63675
63992
|
var HelpView_default = HelpView;
|
|
63993
|
+
var REALTIME_REFRESH_DEBOUNCE_MS2 = 1500;
|
|
63994
|
+
var REALTIME_REFRESH_MIN_INTERVAL_MS2 = 5e3;
|
|
63676
63995
|
var transformActiveBreaks = (activeBreaksByLine) => {
|
|
63677
63996
|
if (!activeBreaksByLine) return [];
|
|
63678
63997
|
return Object.values(activeBreaksByLine).flat().map((item) => ({
|
|
@@ -63696,6 +64015,7 @@ var createEmptyState = () => ({
|
|
|
63696
64015
|
scopeKey: null,
|
|
63697
64016
|
lines: [],
|
|
63698
64017
|
workspaceMetrics: [],
|
|
64018
|
+
blueComparisonWorkspaceMetrics: [],
|
|
63699
64019
|
lineMetrics: [],
|
|
63700
64020
|
kpiTrend: null,
|
|
63701
64021
|
activeBreaks: [],
|
|
@@ -63710,8 +64030,20 @@ var normalizeMetadata = (metadata) => ({
|
|
|
63710
64030
|
cacheStatus: metadata?.cache_status,
|
|
63711
64031
|
warnings: metadata?.warnings ?? []
|
|
63712
64032
|
});
|
|
64033
|
+
var createResolvedScopeLookup = (resolvedScope, workspaces, blueComparisonWorkspaces) => {
|
|
64034
|
+
const lookup = /* @__PURE__ */ new Set();
|
|
64035
|
+
const addEntry = (lineId, date, shiftId) => {
|
|
64036
|
+
if (!lineId || !date || shiftId === void 0 || shiftId === null) return;
|
|
64037
|
+
lookup.add(`${lineId}|${date}|${shiftId}`);
|
|
64038
|
+
};
|
|
64039
|
+
resolvedScope.forEach((entry) => addEntry(entry.line_id, entry.date, entry.shift_id));
|
|
64040
|
+
workspaces.forEach((workspace) => addEntry(workspace.line_id, workspace.date, workspace.shift_id));
|
|
64041
|
+
blueComparisonWorkspaces.forEach((workspace) => addEntry(workspace.line_id, workspace.date, workspace.shift_id));
|
|
64042
|
+
return lookup;
|
|
64043
|
+
};
|
|
63713
64044
|
var useLiveMonitorBootstrap = ({
|
|
63714
64045
|
lineIds,
|
|
64046
|
+
blueComparisonLineIds,
|
|
63715
64047
|
companyId,
|
|
63716
64048
|
enabled = true,
|
|
63717
64049
|
appTimezone,
|
|
@@ -63726,33 +64058,56 @@ var useLiveMonitorBootstrap = ({
|
|
|
63726
64058
|
const effectiveWorkspaceConfig = workspaceConfig || DEFAULT_WORKSPACE_CONFIG;
|
|
63727
64059
|
const effectiveTimezone = appTimezone || "Asia/Kolkata";
|
|
63728
64060
|
const rawLineIdsKey = (lineIds || []).filter(Boolean).join(",");
|
|
64061
|
+
const rawBlueComparisonLineIdsKey = (blueComparisonLineIds || lineIds || []).filter(Boolean).join(",");
|
|
63729
64062
|
const normalizedLineIds = React144.useMemo(
|
|
63730
64063
|
() => Array.from(new Set(rawLineIdsKey ? rawLineIdsKey.split(",") : [])),
|
|
63731
64064
|
[rawLineIdsKey]
|
|
63732
64065
|
);
|
|
64066
|
+
const normalizedBlueComparisonLineIds = React144.useMemo(
|
|
64067
|
+
() => Array.from(new Set(rawBlueComparisonLineIdsKey ? rawBlueComparisonLineIdsKey.split(",") : [])),
|
|
64068
|
+
[rawBlueComparisonLineIdsKey]
|
|
64069
|
+
);
|
|
64070
|
+
const realtimeLineIds = React144.useMemo(
|
|
64071
|
+
() => Array.from(new Set([...normalizedLineIds, ...normalizedBlueComparisonLineIds].filter(Boolean))).sort(),
|
|
64072
|
+
[normalizedLineIds, normalizedBlueComparisonLineIds]
|
|
64073
|
+
);
|
|
63733
64074
|
const requestKey = React144.useMemo(
|
|
63734
|
-
() => normalizedLineIds.slice().sort().join(","),
|
|
63735
|
-
[normalizedLineIds]
|
|
64075
|
+
() => `${normalizedLineIds.slice().sort().join(",")}|blue:${normalizedBlueComparisonLineIds.slice().sort().join(",")}`,
|
|
64076
|
+
[normalizedLineIds, normalizedBlueComparisonLineIds]
|
|
64077
|
+
);
|
|
64078
|
+
const realtimeLineIdsKey = React144.useMemo(() => realtimeLineIds.join(","), [realtimeLineIds]);
|
|
64079
|
+
const companySpecificMetricsTable = React144.useMemo(
|
|
64080
|
+
() => getCompanyMetricsTableName(resolvedCompanyId, "performance_metrics"),
|
|
64081
|
+
[resolvedCompanyId]
|
|
63736
64082
|
);
|
|
63737
64083
|
const [state, setState] = React144.useState(() => createEmptyState());
|
|
63738
64084
|
const [rawState, setRawState] = React144.useState(null);
|
|
63739
64085
|
const [isLoading, setIsLoading] = React144.useState(false);
|
|
63740
64086
|
const [error, setError] = React144.useState(null);
|
|
63741
64087
|
const activeRequestIdRef = React144.useRef(0);
|
|
64088
|
+
const isFetchingRef = React144.useRef(false);
|
|
64089
|
+
const pendingRealtimeRefreshRef = React144.useRef(false);
|
|
64090
|
+
const realtimeRefreshTimerRef = React144.useRef(null);
|
|
64091
|
+
const lastRealtimeRefreshStartedAtRef = React144.useRef(0);
|
|
63742
64092
|
const fetchBootstrap = React144.useCallback(async (force = false) => {
|
|
63743
64093
|
if (!enabled || !supabase || !resolvedCompanyId || normalizedLineIds.length === 0) {
|
|
63744
64094
|
return;
|
|
63745
64095
|
}
|
|
63746
64096
|
const requestId = ++activeRequestIdRef.current;
|
|
64097
|
+
isFetchingRef.current = true;
|
|
63747
64098
|
setIsLoading(true);
|
|
63748
64099
|
setError(null);
|
|
63749
64100
|
try {
|
|
63750
64101
|
const searchParams = new URLSearchParams();
|
|
63751
64102
|
searchParams.set("company_id", resolvedCompanyId);
|
|
63752
64103
|
searchParams.set("line_ids", normalizedLineIds.join(","));
|
|
64104
|
+
if (normalizedBlueComparisonLineIds.length) {
|
|
64105
|
+
searchParams.set("blue_comparison_line_ids", normalizedBlueComparisonLineIds.join(","));
|
|
64106
|
+
}
|
|
63753
64107
|
if (force) {
|
|
63754
64108
|
searchParams.set("force_refresh", "true");
|
|
63755
64109
|
}
|
|
64110
|
+
appendQaGreenStreakSearchParams(searchParams);
|
|
63756
64111
|
const response = await fetchBackendJson(
|
|
63757
64112
|
supabase,
|
|
63758
64113
|
`/api/dashboard/monitor-bootstrap?${searchParams.toString()}`,
|
|
@@ -63781,6 +64136,7 @@ var useLiveMonitorBootstrap = ({
|
|
|
63781
64136
|
extras: {
|
|
63782
64137
|
company_id: resolvedCompanyId,
|
|
63783
64138
|
line_ids: normalizedLineIds,
|
|
64139
|
+
blue_comparison_line_ids: normalizedBlueComparisonLineIds,
|
|
63784
64140
|
force_refresh: force,
|
|
63785
64141
|
pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
|
|
63786
64142
|
}
|
|
@@ -63789,6 +64145,7 @@ var useLiveMonitorBootstrap = ({
|
|
|
63789
64145
|
} finally {
|
|
63790
64146
|
if (requestId === activeRequestIdRef.current) {
|
|
63791
64147
|
setIsLoading(false);
|
|
64148
|
+
isFetchingRef.current = false;
|
|
63792
64149
|
}
|
|
63793
64150
|
}
|
|
63794
64151
|
}, [
|
|
@@ -63796,8 +64153,55 @@ var useLiveMonitorBootstrap = ({
|
|
|
63796
64153
|
supabase,
|
|
63797
64154
|
resolvedCompanyId,
|
|
63798
64155
|
normalizedLineIds,
|
|
64156
|
+
normalizedBlueComparisonLineIds,
|
|
63799
64157
|
requestKey
|
|
63800
64158
|
]);
|
|
64159
|
+
const fetchBootstrapRef = React144.useRef(fetchBootstrap);
|
|
64160
|
+
React144.useEffect(() => {
|
|
64161
|
+
fetchBootstrapRef.current = fetchBootstrap;
|
|
64162
|
+
}, [fetchBootstrap]);
|
|
64163
|
+
const clearRealtimeRefreshTimer = React144.useCallback(() => {
|
|
64164
|
+
if (realtimeRefreshTimerRef.current !== null) {
|
|
64165
|
+
window.clearTimeout(realtimeRefreshTimerRef.current);
|
|
64166
|
+
realtimeRefreshTimerRef.current = null;
|
|
64167
|
+
}
|
|
64168
|
+
}, []);
|
|
64169
|
+
const scheduleRealtimeRefresh = React144.useCallback(() => {
|
|
64170
|
+
if (!enabled || !supabase || realtimeRefreshTimerRef.current !== null) {
|
|
64171
|
+
return;
|
|
64172
|
+
}
|
|
64173
|
+
const elapsedSinceLastRealtimeRefresh = Date.now() - lastRealtimeRefreshStartedAtRef.current;
|
|
64174
|
+
const minIntervalRemaining = Math.max(0, REALTIME_REFRESH_MIN_INTERVAL_MS2 - elapsedSinceLastRealtimeRefresh);
|
|
64175
|
+
const nextDelay = Math.max(REALTIME_REFRESH_DEBOUNCE_MS2, minIntervalRemaining);
|
|
64176
|
+
realtimeRefreshTimerRef.current = window.setTimeout(() => {
|
|
64177
|
+
realtimeRefreshTimerRef.current = null;
|
|
64178
|
+
if (!pendingRealtimeRefreshRef.current) {
|
|
64179
|
+
return;
|
|
64180
|
+
}
|
|
64181
|
+
if (isFetchingRef.current) {
|
|
64182
|
+
scheduleRealtimeRefresh();
|
|
64183
|
+
return;
|
|
64184
|
+
}
|
|
64185
|
+
pendingRealtimeRefreshRef.current = false;
|
|
64186
|
+
lastRealtimeRefreshStartedAtRef.current = Date.now();
|
|
64187
|
+
void fetchBootstrapRef.current(true);
|
|
64188
|
+
}, nextDelay);
|
|
64189
|
+
}, [enabled, supabase]);
|
|
64190
|
+
const queueRealtimeRefresh = React144.useCallback(() => {
|
|
64191
|
+
if (!enabled || !supabase) {
|
|
64192
|
+
pendingRealtimeRefreshRef.current = false;
|
|
64193
|
+
clearRealtimeRefreshTimer();
|
|
64194
|
+
return;
|
|
64195
|
+
}
|
|
64196
|
+
pendingRealtimeRefreshRef.current = true;
|
|
64197
|
+
scheduleRealtimeRefresh();
|
|
64198
|
+
}, [clearRealtimeRefreshTimer, enabled, scheduleRealtimeRefresh, supabase]);
|
|
64199
|
+
React144.useEffect(() => {
|
|
64200
|
+
return () => {
|
|
64201
|
+
pendingRealtimeRefreshRef.current = false;
|
|
64202
|
+
clearRealtimeRefreshTimer();
|
|
64203
|
+
};
|
|
64204
|
+
}, [clearRealtimeRefreshTimer]);
|
|
63801
64205
|
React144.useEffect(() => {
|
|
63802
64206
|
if (!enabled || !rawState || !resolvedCompanyId) {
|
|
63803
64207
|
return;
|
|
@@ -63814,6 +64218,16 @@ var useLiveMonitorBootstrap = ({
|
|
|
63814
64218
|
fallbackShiftConfig
|
|
63815
64219
|
});
|
|
63816
64220
|
const activeBreaks = transformActiveBreaks(rawState.response.active_breaks_by_line);
|
|
64221
|
+
const blueComparisonWorkspaceMetrics = rawState.response.blue_comparison_workspace_metrics ? transformMonitorWorkspaceMetrics({
|
|
64222
|
+
rows: rawState.response.blue_comparison_workspace_metrics,
|
|
64223
|
+
companyId: resolvedCompanyId,
|
|
64224
|
+
workspaceConfig: effectiveWorkspaceConfig,
|
|
64225
|
+
appTimezone: effectiveTimezone,
|
|
64226
|
+
lineMetrics: rawState.response.line_metrics || [],
|
|
64227
|
+
resolveShiftConfig: (lineId) => lineShiftConfigs?.get(lineId) || fallbackShiftConfig,
|
|
64228
|
+
shouldOverrideShiftType: (lineId) => Boolean(lineShiftConfigs?.get(lineId)),
|
|
64229
|
+
fallbackShiftConfig
|
|
64230
|
+
}) : workspaceMetrics;
|
|
63817
64231
|
const metadata = normalizeMetadata(rawState.response.metadata);
|
|
63818
64232
|
const workspaceIds = workspaceMetrics.map((metric) => metric.workspace_uuid).filter((workspaceId) => Boolean(workspaceId));
|
|
63819
64233
|
const videoStreamsByWorkspaceId = rawState.response.video_streams_by_workspace_id || {};
|
|
@@ -63831,6 +64245,7 @@ var useLiveMonitorBootstrap = ({
|
|
|
63831
64245
|
scopeKey: rawState.response.scope_key || null,
|
|
63832
64246
|
lines: rawState.response.lines || [],
|
|
63833
64247
|
workspaceMetrics,
|
|
64248
|
+
blueComparisonWorkspaceMetrics: blueComparisonWorkspaceMetrics.length ? blueComparisonWorkspaceMetrics : workspaceMetrics,
|
|
63834
64249
|
lineMetrics: rawState.response.line_metrics || [],
|
|
63835
64250
|
kpiTrend: rawState.response.kpi_trend || null,
|
|
63836
64251
|
activeBreaks,
|
|
@@ -63865,6 +64280,83 @@ var useLiveMonitorBootstrap = ({
|
|
|
63865
64280
|
}
|
|
63866
64281
|
void fetchBootstrap(false);
|
|
63867
64282
|
}, [enabled, resolvedCompanyId, normalizedLineIds, supabase, fetchBootstrap]);
|
|
64283
|
+
const realtimeScopeKey = React144.useMemo(() => Array.from(createResolvedScopeLookup(
|
|
64284
|
+
state.resolvedScope,
|
|
64285
|
+
state.workspaceMetrics,
|
|
64286
|
+
state.blueComparisonWorkspaceMetrics
|
|
64287
|
+
)).sort().join("||"), [state.resolvedScope, state.workspaceMetrics, state.blueComparisonWorkspaceMetrics]);
|
|
64288
|
+
React144.useEffect(() => {
|
|
64289
|
+
if (!enabled || !resolvedCompanyId || !realtimeLineIdsKey || !supabase) {
|
|
64290
|
+
return void 0;
|
|
64291
|
+
}
|
|
64292
|
+
const scopeLookup = new Set(realtimeScopeKey ? realtimeScopeKey.split("||") : []);
|
|
64293
|
+
if (scopeLookup.size === 0) {
|
|
64294
|
+
return void 0;
|
|
64295
|
+
}
|
|
64296
|
+
const realtimeLineIdsForFilter = realtimeLineIdsKey.split(",").filter(Boolean);
|
|
64297
|
+
if (realtimeLineIdsForFilter.length === 0) {
|
|
64298
|
+
return void 0;
|
|
64299
|
+
}
|
|
64300
|
+
const lineIdFilter = `line_id=in.(${realtimeLineIdsForFilter.join(",")})`;
|
|
64301
|
+
const channels = [];
|
|
64302
|
+
const shouldRefreshForPayload = (payload) => {
|
|
64303
|
+
const payloadData = payload.new || payload.old;
|
|
64304
|
+
return scopeLookup.has(`${payloadData?.line_id}|${payloadData?.date}|${payloadData?.shift_id}`);
|
|
64305
|
+
};
|
|
64306
|
+
const createSubscription = (table, channelNameBase) => {
|
|
64307
|
+
const channelName = `${channelNameBase}-${state.scopeKey || requestKey}`.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
64308
|
+
const channel = supabase.channel(channelName).on(
|
|
64309
|
+
"postgres_changes",
|
|
64310
|
+
{ event: "*", schema: "public", table, filter: lineIdFilter },
|
|
64311
|
+
(payload) => {
|
|
64312
|
+
if (shouldRefreshForPayload(payload)) {
|
|
64313
|
+
queueRealtimeRefresh();
|
|
64314
|
+
}
|
|
64315
|
+
}
|
|
64316
|
+
).subscribe();
|
|
64317
|
+
channels.push(channel);
|
|
64318
|
+
};
|
|
64319
|
+
createSubscription(companySpecificMetricsTable, "monitor-bootstrap-ws");
|
|
64320
|
+
createSubscription("line_metrics", "monitor-bootstrap-lm");
|
|
64321
|
+
createSubscription("wip_buffer_metrics", "monitor-bootstrap-wip-metrics");
|
|
64322
|
+
createSubscription("wip_buffer_alerts", "monitor-bootstrap-wip-alerts");
|
|
64323
|
+
return () => {
|
|
64324
|
+
channels.forEach((channel) => {
|
|
64325
|
+
supabase.removeChannel(channel);
|
|
64326
|
+
});
|
|
64327
|
+
};
|
|
64328
|
+
}, [
|
|
64329
|
+
enabled,
|
|
64330
|
+
resolvedCompanyId,
|
|
64331
|
+
realtimeLineIdsKey,
|
|
64332
|
+
supabase,
|
|
64333
|
+
realtimeScopeKey,
|
|
64334
|
+
state.scopeKey,
|
|
64335
|
+
requestKey,
|
|
64336
|
+
companySpecificMetricsTable,
|
|
64337
|
+
queueRealtimeRefresh
|
|
64338
|
+
]);
|
|
64339
|
+
React144.useEffect(() => {
|
|
64340
|
+
if (!enabled || !resolvedCompanyId || normalizedLineIds.length === 0 || !supabase) {
|
|
64341
|
+
return void 0;
|
|
64342
|
+
}
|
|
64343
|
+
const forceRefreshOnResume = () => {
|
|
64344
|
+
void fetchBootstrapRef.current(true);
|
|
64345
|
+
};
|
|
64346
|
+
const handleVisibilityChange = () => {
|
|
64347
|
+
if (document.visibilityState === "visible") {
|
|
64348
|
+
forceRefreshOnResume();
|
|
64349
|
+
}
|
|
64350
|
+
};
|
|
64351
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
64352
|
+
window.addEventListener("focus", forceRefreshOnResume);
|
|
64353
|
+
window.addEventListener("online", forceRefreshOnResume);
|
|
64354
|
+
return () => {
|
|
64355
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
64356
|
+
window.removeEventListener("focus", forceRefreshOnResume);
|
|
64357
|
+
window.removeEventListener("online", forceRefreshOnResume);
|
|
64358
|
+
};
|
|
64359
|
+
}, [enabled, normalizedLineIds.length, resolvedCompanyId, supabase]);
|
|
63868
64360
|
React144.useEffect(() => {
|
|
63869
64361
|
if (!enabled || !resolvedCompanyId || normalizedLineIds.length === 0 || !supabase) {
|
|
63870
64362
|
return void 0;
|
|
@@ -63898,6 +64390,7 @@ var useLiveMonitorBootstrap = ({
|
|
|
63898
64390
|
scopeKey: state.scopeKey,
|
|
63899
64391
|
lines: state.lines,
|
|
63900
64392
|
workspaceMetrics: state.workspaceMetrics,
|
|
64393
|
+
blueComparisonWorkspaceMetrics: state.blueComparisonWorkspaceMetrics,
|
|
63901
64394
|
lineMetrics: state.lineMetrics,
|
|
63902
64395
|
kpiTrend: state.kpiTrend,
|
|
63903
64396
|
activeBreaks: state.activeBreaks,
|
|
@@ -64168,6 +64661,22 @@ var logDebug3 = (...args) => {
|
|
|
64168
64661
|
};
|
|
64169
64662
|
var EMPTY_LINE_IDS = [];
|
|
64170
64663
|
var EMPTY_WORKSPACES = [];
|
|
64664
|
+
var ALL_GREEN_CELEBRATION_DURATION_MS = 6e3;
|
|
64665
|
+
var ALL_GREEN_MILESTONE_DURATION_MS = 6e3;
|
|
64666
|
+
var ALL_GREEN_STREAK_LOCAL_SECOND_CAP = 59;
|
|
64667
|
+
var formatAllGreenCelebrationTimer = (elapsedSeconds) => {
|
|
64668
|
+
const safeElapsedSeconds = Math.max(1, Math.floor(elapsedSeconds));
|
|
64669
|
+
const minutes = Math.floor(safeElapsedSeconds / 60);
|
|
64670
|
+
const seconds = safeElapsedSeconds % 60;
|
|
64671
|
+
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}s`;
|
|
64672
|
+
};
|
|
64673
|
+
var getAllGreenBackendVisibleSeconds = (confirmedSeconds, tickOriginAtMs, nowMs2) => {
|
|
64674
|
+
const localSecondOffset = Math.min(
|
|
64675
|
+
ALL_GREEN_STREAK_LOCAL_SECOND_CAP,
|
|
64676
|
+
Math.max(0, Math.floor((nowMs2 - tickOriginAtMs) / 1e3))
|
|
64677
|
+
);
|
|
64678
|
+
return confirmedSeconds + localSecondOffset;
|
|
64679
|
+
};
|
|
64171
64680
|
var LoadingPageCmp = LoadingPage_default;
|
|
64172
64681
|
var LoadingOverlayCmp = LoadingOverlay_default;
|
|
64173
64682
|
function HomeView({
|
|
@@ -64309,6 +64818,31 @@ function HomeView({
|
|
|
64309
64818
|
() => new Set(selectedLineIds),
|
|
64310
64819
|
[selectedLineIds]
|
|
64311
64820
|
);
|
|
64821
|
+
const blueComparisonLineIds = React144.useMemo(() => {
|
|
64822
|
+
const selectedFactoryAreaIds = /* @__PURE__ */ new Set();
|
|
64823
|
+
for (const line of dbLines) {
|
|
64824
|
+
if (!selectedLineIdSet.has(line.id)) {
|
|
64825
|
+
continue;
|
|
64826
|
+
}
|
|
64827
|
+
const factoryAreaId = typeof line.factory_area_id === "string" ? line.factory_area_id.trim() : "";
|
|
64828
|
+
if (factoryAreaId) {
|
|
64829
|
+
selectedFactoryAreaIds.add(factoryAreaId);
|
|
64830
|
+
}
|
|
64831
|
+
}
|
|
64832
|
+
if (selectedFactoryAreaIds.size === 0) {
|
|
64833
|
+
return selectedLineIds;
|
|
64834
|
+
}
|
|
64835
|
+
const dbLinesById = new Map(dbLines.map((line) => [line.id, line]));
|
|
64836
|
+
const selectedIds = new Set(selectedLineIds);
|
|
64837
|
+
return visibleLineIds.filter((lineId) => {
|
|
64838
|
+
if (selectedIds.has(lineId)) {
|
|
64839
|
+
return true;
|
|
64840
|
+
}
|
|
64841
|
+
const line = dbLinesById.get(lineId);
|
|
64842
|
+
const factoryAreaId = typeof line?.factory_area_id === "string" ? line.factory_area_id.trim() : "";
|
|
64843
|
+
return factoryAreaId ? selectedFactoryAreaIds.has(factoryAreaId) : false;
|
|
64844
|
+
});
|
|
64845
|
+
}, [dbLines, selectedLineIdSet, selectedLineIds, visibleLineIds]);
|
|
64312
64846
|
const metricsScopeLineId = isMultiLineSelection ? factoryViewId : primarySelectedLineId;
|
|
64313
64847
|
const userCompanyId = React144.useMemo(() => {
|
|
64314
64848
|
return user?.properties?.company_id || user?.company_id || entityConfig.companyId;
|
|
@@ -64349,6 +64883,7 @@ function HomeView({
|
|
|
64349
64883
|
}, []);
|
|
64350
64884
|
const {
|
|
64351
64885
|
workspaceMetrics: legacyWorkspaceMetrics,
|
|
64886
|
+
blueComparisonWorkspaceMetrics: legacyMetricsBlueComparisonWorkspaceMetrics,
|
|
64352
64887
|
lineMetrics: legacyLineMetrics,
|
|
64353
64888
|
efficiencyLegend: legacyEfficiencyLegend,
|
|
64354
64889
|
metadata: legacyMetricsMetadata,
|
|
@@ -64359,6 +64894,7 @@ function HomeView({
|
|
|
64359
64894
|
} = useDashboardMetrics({
|
|
64360
64895
|
lineId: metricsScopeLineId,
|
|
64361
64896
|
lineIds: selectedLineIds,
|
|
64897
|
+
blueComparisonLineIds,
|
|
64362
64898
|
onLineMetricsUpdate: handleLineMetricsUpdate,
|
|
64363
64899
|
userAccessibleLineIds: visibleLineIds,
|
|
64364
64900
|
enabled: shouldEnableMetricsFetch && !isBootstrapMonitorMode
|
|
@@ -64413,6 +64949,7 @@ function HomeView({
|
|
|
64413
64949
|
const { trend: legacyKpiTrend } = useKpiTrends(legacyTrendOptions);
|
|
64414
64950
|
const bootstrapMonitor = useLiveMonitorBootstrap({
|
|
64415
64951
|
lineIds: selectedLineIds,
|
|
64952
|
+
blueComparisonLineIds,
|
|
64416
64953
|
companyId: userCompanyId,
|
|
64417
64954
|
enabled: shouldEnableMetricsFetch && !isLegacyMonitorMode,
|
|
64418
64955
|
appTimezone: timezone,
|
|
@@ -64421,6 +64958,7 @@ function HomeView({
|
|
|
64421
64958
|
lineShiftConfigs
|
|
64422
64959
|
});
|
|
64423
64960
|
const currentWorkspaceMetrics = isBootstrapMonitorMode ? bootstrapMonitor.workspaceMetrics : legacyWorkspaceMetrics;
|
|
64961
|
+
const currentBlueComparisonWorkspaceMetrics = isBootstrapMonitorMode ? bootstrapMonitor.blueComparisonWorkspaceMetrics : legacyMetricsBlueComparisonWorkspaceMetrics;
|
|
64424
64962
|
const currentLineMetrics = isBootstrapMonitorMode ? bootstrapMonitor.lineMetrics : legacyLineMetrics;
|
|
64425
64963
|
const currentEfficiencyLegend = isBootstrapMonitorMode ? bootstrapMonitor.efficiencyLegend : legacyEfficiencyLegend;
|
|
64426
64964
|
const currentMetricsMetadata = isBootstrapMonitorMode ? bootstrapMonitor.metadata : legacyMetricsMetadata;
|
|
@@ -64558,6 +65096,212 @@ function HomeView({
|
|
|
64558
65096
|
setBreakNotificationsDismissed(false);
|
|
64559
65097
|
}
|
|
64560
65098
|
}, [currentActiveBreaks.length]);
|
|
65099
|
+
const effectiveEfficiencyLegend = currentEfficiencyLegend || DEFAULT_EFFICIENCY_LEGEND;
|
|
65100
|
+
React144.useMemo(
|
|
65101
|
+
() => workspaceMetricsWithBreakState.filter((workspace) => Boolean(workspace.workspace_uuid || workspace.workspace_name)).length,
|
|
65102
|
+
[workspaceMetricsWithBreakState]
|
|
65103
|
+
);
|
|
65104
|
+
const allGreenCelebrationSignature = React144.useMemo(() => {
|
|
65105
|
+
const workspaceSignature = workspaceMetricsWithBreakState.map((workspace) => workspace.workspace_uuid || `${workspace.line_id}:${workspace.workspace_name}`).filter(Boolean).sort().join(",");
|
|
65106
|
+
return `${selectedLineIds.join(",")}::${workspaceSignature}`;
|
|
65107
|
+
}, [selectedLineIds, workspaceMetricsWithBreakState]);
|
|
65108
|
+
const allGreenTransitionRef = React144.useRef({ signature: null, previousValidStreakIdentity: null });
|
|
65109
|
+
const allGreenCelebrationTimerRef = React144.useRef(null);
|
|
65110
|
+
const allGreenMilestoneTimerRef = React144.useRef(null);
|
|
65111
|
+
const allGreenMilestoneTrackingRef = React144.useRef({ identity: null, lastMilestoneSeconds: null });
|
|
65112
|
+
const allGreenStreakTimerBaselineRef = React144.useRef(null);
|
|
65113
|
+
const [showAllGreenCelebration, setShowAllGreenCelebration] = React144.useState(false);
|
|
65114
|
+
const [greenStreakMilestoneBanner, setGreenStreakMilestoneBanner] = React144.useState(null);
|
|
65115
|
+
const [allGreenStreakNowMs, setAllGreenStreakNowMs] = React144.useState(() => Date.now());
|
|
65116
|
+
const currentAllGreenStreakNowMs = Math.max(allGreenStreakNowMs, Date.now());
|
|
65117
|
+
const allGreenStreakDisplay = React144.useMemo(
|
|
65118
|
+
() => getAllVideoGridGreenStreakDisplay(
|
|
65119
|
+
workspaceMetricsWithBreakState,
|
|
65120
|
+
effectiveEfficiencyLegend,
|
|
65121
|
+
currentAllGreenStreakNowMs
|
|
65122
|
+
),
|
|
65123
|
+
[currentAllGreenStreakNowMs, effectiveEfficiencyLegend, workspaceMetricsWithBreakState]
|
|
65124
|
+
);
|
|
65125
|
+
const allGreenMilestoneIdentity = React144.useMemo(() => allGreenStreakDisplay ? `${allGreenCelebrationSignature}::${allGreenStreakDisplay.startedAt}` : null, [allGreenCelebrationSignature, allGreenStreakDisplay]);
|
|
65126
|
+
const visibleAllGreenStreakDisplay = React144.useMemo(() => {
|
|
65127
|
+
if (!allGreenStreakDisplay || !allGreenMilestoneIdentity) {
|
|
65128
|
+
allGreenStreakTimerBaselineRef.current = null;
|
|
65129
|
+
return null;
|
|
65130
|
+
}
|
|
65131
|
+
const confirmedSeconds = allGreenStreakDisplay.confirmedSeconds;
|
|
65132
|
+
const backendVisibleSeconds = getAllGreenBackendVisibleSeconds(
|
|
65133
|
+
confirmedSeconds,
|
|
65134
|
+
allGreenStreakDisplay.tickOriginAtMs,
|
|
65135
|
+
currentAllGreenStreakNowMs
|
|
65136
|
+
);
|
|
65137
|
+
const backendMaxVisibleSeconds = confirmedSeconds + ALL_GREEN_STREAK_LOCAL_SECOND_CAP;
|
|
65138
|
+
const currentBaseline = allGreenStreakTimerBaselineRef.current;
|
|
65139
|
+
if (!currentBaseline || currentBaseline.identity !== allGreenMilestoneIdentity) {
|
|
65140
|
+
allGreenStreakTimerBaselineRef.current = {
|
|
65141
|
+
identity: allGreenMilestoneIdentity,
|
|
65142
|
+
baseSeconds: backendVisibleSeconds,
|
|
65143
|
+
baseReceivedAtMs: currentAllGreenStreakNowMs,
|
|
65144
|
+
maxVisibleSeconds: backendMaxVisibleSeconds
|
|
65145
|
+
};
|
|
65146
|
+
} else {
|
|
65147
|
+
currentBaseline.maxVisibleSeconds = Math.max(
|
|
65148
|
+
currentBaseline.maxVisibleSeconds,
|
|
65149
|
+
backendMaxVisibleSeconds
|
|
65150
|
+
);
|
|
65151
|
+
const visibleSeconds = Math.min(
|
|
65152
|
+
currentBaseline.maxVisibleSeconds,
|
|
65153
|
+
currentBaseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - currentBaseline.baseReceivedAtMs) / 1e3))
|
|
65154
|
+
);
|
|
65155
|
+
if (backendVisibleSeconds > visibleSeconds) {
|
|
65156
|
+
allGreenStreakTimerBaselineRef.current = {
|
|
65157
|
+
identity: allGreenMilestoneIdentity,
|
|
65158
|
+
baseSeconds: backendVisibleSeconds,
|
|
65159
|
+
baseReceivedAtMs: currentAllGreenStreakNowMs,
|
|
65160
|
+
maxVisibleSeconds: currentBaseline.maxVisibleSeconds
|
|
65161
|
+
};
|
|
65162
|
+
}
|
|
65163
|
+
}
|
|
65164
|
+
const baseline = allGreenStreakTimerBaselineRef.current;
|
|
65165
|
+
const elapsedSeconds = baseline ? Math.min(
|
|
65166
|
+
baseline.maxVisibleSeconds,
|
|
65167
|
+
baseline.baseSeconds + Math.max(0, Math.floor((currentAllGreenStreakNowMs - baseline.baseReceivedAtMs) / 1e3))
|
|
65168
|
+
) : backendVisibleSeconds;
|
|
65169
|
+
return {
|
|
65170
|
+
...allGreenStreakDisplay,
|
|
65171
|
+
elapsedSeconds,
|
|
65172
|
+
durationText: formatAllGreenStreakDuration(elapsedSeconds)
|
|
65173
|
+
};
|
|
65174
|
+
}, [allGreenMilestoneIdentity, allGreenStreakDisplay, currentAllGreenStreakNowMs]);
|
|
65175
|
+
const allGreenCelebrationTimerText = React144.useMemo(() => {
|
|
65176
|
+
if (!showAllGreenCelebration || !visibleAllGreenStreakDisplay) {
|
|
65177
|
+
return null;
|
|
65178
|
+
}
|
|
65179
|
+
return formatAllGreenCelebrationTimer(visibleAllGreenStreakDisplay.elapsedSeconds);
|
|
65180
|
+
}, [showAllGreenCelebration, visibleAllGreenStreakDisplay]);
|
|
65181
|
+
React144.useEffect(() => {
|
|
65182
|
+
const hasPossibleStreakTimer = showAllGreenCelebration || Boolean(allGreenStreakDisplay) || workspaceMetricsWithBreakState.some((workspace) => workspace.video_grid_green_streak_active === true);
|
|
65183
|
+
if (!hasPossibleStreakTimer) {
|
|
65184
|
+
return void 0;
|
|
65185
|
+
}
|
|
65186
|
+
const timerId = setInterval(() => {
|
|
65187
|
+
setAllGreenStreakNowMs(Date.now());
|
|
65188
|
+
}, 1e3);
|
|
65189
|
+
return () => {
|
|
65190
|
+
clearInterval(timerId);
|
|
65191
|
+
};
|
|
65192
|
+
}, [allGreenStreakDisplay, showAllGreenCelebration, workspaceMetricsWithBreakState]);
|
|
65193
|
+
const dismissAllGreenCelebration = React144.useCallback(() => {
|
|
65194
|
+
if (allGreenCelebrationTimerRef.current) {
|
|
65195
|
+
clearTimeout(allGreenCelebrationTimerRef.current);
|
|
65196
|
+
allGreenCelebrationTimerRef.current = null;
|
|
65197
|
+
}
|
|
65198
|
+
setShowAllGreenCelebration(false);
|
|
65199
|
+
}, []);
|
|
65200
|
+
const triggerAllGreenCelebration = React144.useCallback(() => {
|
|
65201
|
+
setShowAllGreenCelebration(true);
|
|
65202
|
+
if (allGreenCelebrationTimerRef.current) {
|
|
65203
|
+
clearTimeout(allGreenCelebrationTimerRef.current);
|
|
65204
|
+
}
|
|
65205
|
+
allGreenCelebrationTimerRef.current = setTimeout(() => {
|
|
65206
|
+
setShowAllGreenCelebration(false);
|
|
65207
|
+
allGreenCelebrationTimerRef.current = null;
|
|
65208
|
+
}, ALL_GREEN_CELEBRATION_DURATION_MS);
|
|
65209
|
+
}, []);
|
|
65210
|
+
const dismissGreenStreakMilestoneBanner = React144.useCallback(() => {
|
|
65211
|
+
if (allGreenMilestoneTimerRef.current) {
|
|
65212
|
+
clearTimeout(allGreenMilestoneTimerRef.current);
|
|
65213
|
+
allGreenMilestoneTimerRef.current = null;
|
|
65214
|
+
}
|
|
65215
|
+
setGreenStreakMilestoneBanner(null);
|
|
65216
|
+
}, []);
|
|
65217
|
+
const triggerGreenStreakMilestoneBanner = React144.useCallback((milestone) => {
|
|
65218
|
+
setGreenStreakMilestoneBanner(milestone);
|
|
65219
|
+
if (allGreenMilestoneTimerRef.current) {
|
|
65220
|
+
clearTimeout(allGreenMilestoneTimerRef.current);
|
|
65221
|
+
}
|
|
65222
|
+
allGreenMilestoneTimerRef.current = setTimeout(() => {
|
|
65223
|
+
setGreenStreakMilestoneBanner(null);
|
|
65224
|
+
allGreenMilestoneTimerRef.current = null;
|
|
65225
|
+
}, ALL_GREEN_MILESTONE_DURATION_MS);
|
|
65226
|
+
}, []);
|
|
65227
|
+
React144.useEffect(() => {
|
|
65228
|
+
return () => {
|
|
65229
|
+
if (allGreenCelebrationTimerRef.current) {
|
|
65230
|
+
clearTimeout(allGreenCelebrationTimerRef.current);
|
|
65231
|
+
}
|
|
65232
|
+
if (allGreenMilestoneTimerRef.current) {
|
|
65233
|
+
clearTimeout(allGreenMilestoneTimerRef.current);
|
|
65234
|
+
}
|
|
65235
|
+
};
|
|
65236
|
+
}, []);
|
|
65237
|
+
React144.useEffect(() => {
|
|
65238
|
+
const milestoneTracking = allGreenMilestoneTrackingRef.current;
|
|
65239
|
+
if (currentMetricsLoading) {
|
|
65240
|
+
return;
|
|
65241
|
+
}
|
|
65242
|
+
if (!visibleAllGreenStreakDisplay || !allGreenMilestoneIdentity) {
|
|
65243
|
+
milestoneTracking.identity = null;
|
|
65244
|
+
milestoneTracking.lastMilestoneSeconds = null;
|
|
65245
|
+
dismissGreenStreakMilestoneBanner();
|
|
65246
|
+
return;
|
|
65247
|
+
}
|
|
65248
|
+
const currentMilestone = getAllGreenStreakMilestone(visibleAllGreenStreakDisplay.elapsedSeconds);
|
|
65249
|
+
const currentMilestoneSeconds = currentMilestone?.milestoneSeconds ?? null;
|
|
65250
|
+
if (milestoneTracking.identity !== allGreenMilestoneIdentity) {
|
|
65251
|
+
milestoneTracking.identity = allGreenMilestoneIdentity;
|
|
65252
|
+
milestoneTracking.lastMilestoneSeconds = currentMilestoneSeconds;
|
|
65253
|
+
dismissGreenStreakMilestoneBanner();
|
|
65254
|
+
return;
|
|
65255
|
+
}
|
|
65256
|
+
if (!currentMilestone) {
|
|
65257
|
+
milestoneTracking.lastMilestoneSeconds = null;
|
|
65258
|
+
return;
|
|
65259
|
+
}
|
|
65260
|
+
if ((milestoneTracking.lastMilestoneSeconds ?? 0) < currentMilestone.milestoneSeconds) {
|
|
65261
|
+
milestoneTracking.lastMilestoneSeconds = currentMilestone.milestoneSeconds;
|
|
65262
|
+
triggerGreenStreakMilestoneBanner(currentMilestone);
|
|
65263
|
+
}
|
|
65264
|
+
}, [
|
|
65265
|
+
allGreenMilestoneIdentity,
|
|
65266
|
+
currentMetricsLoading,
|
|
65267
|
+
dismissGreenStreakMilestoneBanner,
|
|
65268
|
+
triggerGreenStreakMilestoneBanner,
|
|
65269
|
+
visibleAllGreenStreakDisplay
|
|
65270
|
+
]);
|
|
65271
|
+
React144.useEffect(() => {
|
|
65272
|
+
if (currentMetricsLoading) {
|
|
65273
|
+
return;
|
|
65274
|
+
}
|
|
65275
|
+
const currentValidStreakIdentity = visibleAllGreenStreakDisplay && allGreenMilestoneIdentity ? allGreenMilestoneIdentity : null;
|
|
65276
|
+
const transitionState = allGreenTransitionRef.current;
|
|
65277
|
+
if (transitionState.signature !== allGreenCelebrationSignature) {
|
|
65278
|
+
transitionState.signature = allGreenCelebrationSignature;
|
|
65279
|
+
transitionState.previousValidStreakIdentity = currentValidStreakIdentity;
|
|
65280
|
+
dismissAllGreenCelebration();
|
|
65281
|
+
return;
|
|
65282
|
+
}
|
|
65283
|
+
if (!currentValidStreakIdentity) {
|
|
65284
|
+
transitionState.previousValidStreakIdentity = null;
|
|
65285
|
+
dismissAllGreenCelebration();
|
|
65286
|
+
return;
|
|
65287
|
+
}
|
|
65288
|
+
if (transitionState.previousValidStreakIdentity === null) {
|
|
65289
|
+
transitionState.previousValidStreakIdentity = currentValidStreakIdentity;
|
|
65290
|
+
triggerAllGreenCelebration();
|
|
65291
|
+
return;
|
|
65292
|
+
}
|
|
65293
|
+
if (transitionState.previousValidStreakIdentity !== currentValidStreakIdentity) {
|
|
65294
|
+
transitionState.previousValidStreakIdentity = currentValidStreakIdentity;
|
|
65295
|
+
dismissAllGreenCelebration();
|
|
65296
|
+
}
|
|
65297
|
+
}, [
|
|
65298
|
+
allGreenCelebrationSignature,
|
|
65299
|
+
allGreenMilestoneIdentity,
|
|
65300
|
+
currentMetricsLoading,
|
|
65301
|
+
dismissAllGreenCelebration,
|
|
65302
|
+
triggerAllGreenCelebration,
|
|
65303
|
+
visibleAllGreenStreakDisplay
|
|
65304
|
+
]);
|
|
64561
65305
|
const {
|
|
64562
65306
|
streamsByWorkspaceId: legacyVideoStreamsByWorkspaceId,
|
|
64563
65307
|
isLoading: legacyVideoStreamsLoading
|
|
@@ -65124,6 +65868,28 @@ function HomeView({
|
|
|
65124
65868
|
updateSelectedLineIds,
|
|
65125
65869
|
isAllLinesSelection
|
|
65126
65870
|
]);
|
|
65871
|
+
const gridToolbarControls = React144.useMemo(() => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2", children: [
|
|
65872
|
+
/* @__PURE__ */ jsxRuntime.jsx(AnimatePresence, { children: visibleAllGreenStreakDisplay ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
65873
|
+
motion.div,
|
|
65874
|
+
{
|
|
65875
|
+
initial: { opacity: 0, y: -4 },
|
|
65876
|
+
animate: { opacity: 1, y: 0 },
|
|
65877
|
+
exit: { opacity: 0, y: -4 },
|
|
65878
|
+
transition: { duration: 0.18, ease: "easeOut" },
|
|
65879
|
+
className: "inline-flex items-center gap-1.5 rounded-md border border-[#00AB45]/20 bg-[#00AB45]/10 px-3 py-1.5 text-sm font-semibold text-[#00AB45] shadow-sm",
|
|
65880
|
+
"aria-label": "All green streak",
|
|
65881
|
+
children: [
|
|
65882
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "h-4 w-4" }),
|
|
65883
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${visibleAllGreenStreakDisplay.label} \xB7 ${visibleAllGreenStreakDisplay.durationText}` })
|
|
65884
|
+
]
|
|
65885
|
+
},
|
|
65886
|
+
visibleAllGreenStreakDisplay.startedAt
|
|
65887
|
+
) : null }),
|
|
65888
|
+
lineSelectorComponent
|
|
65889
|
+
] }), [
|
|
65890
|
+
lineSelectorComponent,
|
|
65891
|
+
visibleAllGreenStreakDisplay
|
|
65892
|
+
]);
|
|
65127
65893
|
const useSmoothLoading = (isLoading, minDuration = 400) => {
|
|
65128
65894
|
const [showLoading, setShowLoading] = React144.useState(isLoading);
|
|
65129
65895
|
const loadingStartRef2 = React144.useRef(null);
|
|
@@ -65296,17 +66062,18 @@ function HomeView({
|
|
|
65296
66062
|
className: "h-full",
|
|
65297
66063
|
children: React144__namespace.default.createElement(WorkspaceGrid, {
|
|
65298
66064
|
workspaces: workspaceMetricsWithBreakState,
|
|
66065
|
+
blueComparisonWorkspaces: currentBlueComparisonWorkspaceMetrics || workspaceMetricsWithBreakState,
|
|
65299
66066
|
lineNames: mergedLineNames,
|
|
65300
66067
|
lineOrder: selectedLineIds,
|
|
65301
66068
|
factoryView: factoryViewId,
|
|
65302
|
-
legend:
|
|
66069
|
+
legend: effectiveEfficiencyLegend,
|
|
65303
66070
|
videoSources,
|
|
65304
66071
|
videoStreamsByWorkspaceId: currentVideoStreamsByWorkspaceId,
|
|
65305
66072
|
videoStreamsLoading: currentVideoStreamsLoading,
|
|
65306
66073
|
displayNames: metricsDisplayNames,
|
|
65307
66074
|
hasFlowBuffers,
|
|
65308
66075
|
className: "h-full",
|
|
65309
|
-
toolbarRightContent:
|
|
66076
|
+
toolbarRightContent: gridToolbarControls,
|
|
65310
66077
|
onWorkspaceHover: handleWorkspaceHover,
|
|
65311
66078
|
onWorkspaceHoverEnd: handleWorkspaceHoverEnd
|
|
65312
66079
|
})
|
|
@@ -65329,17 +66096,18 @@ function HomeView({
|
|
|
65329
66096
|
children: React144__namespace.default.createElement(WorkspaceGrid, {
|
|
65330
66097
|
workspaces: [],
|
|
65331
66098
|
// Show empty grid while loading
|
|
66099
|
+
blueComparisonWorkspaces: [],
|
|
65332
66100
|
lineNames: mergedLineNames,
|
|
65333
66101
|
lineOrder: selectedLineIds,
|
|
65334
66102
|
factoryView: factoryViewId,
|
|
65335
|
-
legend:
|
|
66103
|
+
legend: effectiveEfficiencyLegend,
|
|
65336
66104
|
videoSources,
|
|
65337
66105
|
videoStreamsByWorkspaceId: currentVideoStreamsByWorkspaceId,
|
|
65338
66106
|
videoStreamsLoading: currentVideoStreamsLoading,
|
|
65339
66107
|
displayNames: metricsDisplayNames,
|
|
65340
66108
|
hasFlowBuffers,
|
|
65341
66109
|
className: "h-full",
|
|
65342
|
-
toolbarRightContent:
|
|
66110
|
+
toolbarRightContent: gridToolbarControls,
|
|
65343
66111
|
onWorkspaceHover: handleWorkspaceHover,
|
|
65344
66112
|
onWorkspaceHoverEnd: handleWorkspaceHoverEnd
|
|
65345
66113
|
})
|
|
@@ -65372,6 +66140,149 @@ function HomeView({
|
|
|
65372
66140
|
contentVariant: "plain"
|
|
65373
66141
|
}
|
|
65374
66142
|
),
|
|
66143
|
+
/* @__PURE__ */ jsxRuntime.jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxRuntime.jsxs(React144__namespace.default.Fragment, { children: [
|
|
66144
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
66145
|
+
motion.div,
|
|
66146
|
+
{
|
|
66147
|
+
initial: { opacity: 0 },
|
|
66148
|
+
animate: { opacity: 1 },
|
|
66149
|
+
exit: { opacity: 0 },
|
|
66150
|
+
transition: { duration: 0.4 },
|
|
66151
|
+
className: "pointer-events-none fixed inset-0 z-[9998] bg-slate-900/40 backdrop-blur-sm",
|
|
66152
|
+
"aria-hidden": "true"
|
|
66153
|
+
},
|
|
66154
|
+
"all-green-backdrop"
|
|
66155
|
+
),
|
|
66156
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
66157
|
+
motion.div,
|
|
66158
|
+
{
|
|
66159
|
+
initial: { opacity: 0 },
|
|
66160
|
+
animate: { opacity: 1 },
|
|
66161
|
+
exit: { opacity: 0, y: -50, scale: 0.9, filter: "blur(10px)" },
|
|
66162
|
+
transition: { duration: 0.4 },
|
|
66163
|
+
className: "pointer-events-none fixed inset-0 z-[10000] flex flex-col items-center justify-center px-4",
|
|
66164
|
+
role: "status",
|
|
66165
|
+
"aria-live": "polite",
|
|
66166
|
+
"aria-label": "All green celebration",
|
|
66167
|
+
children: [
|
|
66168
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
66169
|
+
motion.div,
|
|
66170
|
+
{
|
|
66171
|
+
initial: { opacity: 0, y: 8, filter: "blur(6px)" },
|
|
66172
|
+
animate: { opacity: 1, y: 0, filter: "blur(0px)" },
|
|
66173
|
+
transition: { duration: 0.28, ease: [0.16, 1, 0.3, 1] },
|
|
66174
|
+
className: "flex flex-wrap items-center justify-center gap-x-4 sm:gap-x-8",
|
|
66175
|
+
children: [
|
|
66176
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
66177
|
+
"span",
|
|
66178
|
+
{
|
|
66179
|
+
className: "text-[100px] font-black uppercase leading-none tracking-tight text-white drop-shadow-2xl sm:text-[140px]",
|
|
66180
|
+
style: { textShadow: "0 18px 36px rgba(0,0,0,0.34)" },
|
|
66181
|
+
children: "ALL"
|
|
66182
|
+
}
|
|
66183
|
+
),
|
|
66184
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
66185
|
+
"span",
|
|
66186
|
+
{
|
|
66187
|
+
className: "text-[100px] font-black uppercase leading-none tracking-tight text-[#00AB45] drop-shadow-2xl sm:text-[140px]",
|
|
66188
|
+
style: { filter: "drop-shadow(0 18px 36px rgba(0,171,69,0.28))" },
|
|
66189
|
+
children: "GREEN"
|
|
66190
|
+
}
|
|
66191
|
+
)
|
|
66192
|
+
]
|
|
66193
|
+
}
|
|
66194
|
+
),
|
|
66195
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
66196
|
+
motion.div,
|
|
66197
|
+
{
|
|
66198
|
+
initial: { opacity: 0, scaleX: 0 },
|
|
66199
|
+
animate: { opacity: 1, scaleX: 1 },
|
|
66200
|
+
transition: { delay: 0.18, duration: 0.45, ease: [0.16, 1, 0.3, 1] },
|
|
66201
|
+
className: "mt-4 h-1 w-44 origin-left rounded-full bg-[#00AB45] shadow-[0_0_16px_rgba(0,171,69,0.44)] sm:w-64"
|
|
66202
|
+
}
|
|
66203
|
+
),
|
|
66204
|
+
allGreenCelebrationTimerText && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
66205
|
+
motion.div,
|
|
66206
|
+
{
|
|
66207
|
+
initial: { opacity: 0, y: 4 },
|
|
66208
|
+
animate: { opacity: 1, y: 0 },
|
|
66209
|
+
transition: { delay: 0.28, duration: 0.18, ease: "easeOut" },
|
|
66210
|
+
className: "mt-3 flex items-center justify-center gap-2 text-2xl font-semibold tracking-tight text-white drop-shadow-[0_4px_18px_rgba(0,0,0,0.45)] sm:mt-4 sm:text-3xl",
|
|
66211
|
+
children: [
|
|
66212
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2.5 w-2.5 rounded-full bg-[#00AB45] shadow-[0_0_10px_rgba(0,171,69,0.72)]" }),
|
|
66213
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: allGreenCelebrationTimerText })
|
|
66214
|
+
]
|
|
66215
|
+
}
|
|
66216
|
+
)
|
|
66217
|
+
]
|
|
66218
|
+
},
|
|
66219
|
+
"all-green-center-toast"
|
|
66220
|
+
)
|
|
66221
|
+
] }, "all-green-celebration") : null }),
|
|
66222
|
+
/* @__PURE__ */ jsxRuntime.jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxRuntime.jsxs(React144__namespace.default.Fragment, { children: [
|
|
66223
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
66224
|
+
motion.div,
|
|
66225
|
+
{
|
|
66226
|
+
initial: { opacity: 0 },
|
|
66227
|
+
animate: { opacity: 1 },
|
|
66228
|
+
exit: { opacity: 0 },
|
|
66229
|
+
transition: { duration: 0.4 },
|
|
66230
|
+
className: "pointer-events-none fixed inset-0 z-[9998] bg-slate-900/40 backdrop-blur-sm",
|
|
66231
|
+
"aria-hidden": "true"
|
|
66232
|
+
},
|
|
66233
|
+
`green-streak-backdrop-${greenStreakMilestoneBanner.milestoneSeconds}`
|
|
66234
|
+
),
|
|
66235
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
66236
|
+
motion.div,
|
|
66237
|
+
{
|
|
66238
|
+
initial: { opacity: 0 },
|
|
66239
|
+
animate: { opacity: 1 },
|
|
66240
|
+
exit: { opacity: 0, y: -50, scale: 0.9, filter: "blur(10px)" },
|
|
66241
|
+
transition: { duration: 0.4 },
|
|
66242
|
+
className: "pointer-events-none fixed inset-0 z-[10000] flex flex-col items-center justify-center px-4",
|
|
66243
|
+
role: "status",
|
|
66244
|
+
"aria-live": "polite",
|
|
66245
|
+
"aria-label": `Green streak milestone: ${greenStreakMilestoneBanner.headline}`,
|
|
66246
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center gap-y-4", children: [
|
|
66247
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
66248
|
+
motion.div,
|
|
66249
|
+
{
|
|
66250
|
+
initial: { opacity: 0, y: 8, filter: "blur(6px)" },
|
|
66251
|
+
animate: { opacity: 1, y: 0, filter: "blur(0px)" },
|
|
66252
|
+
transition: { delay: 0.08, duration: 0.28, ease: [0.16, 1, 0.3, 1] },
|
|
66253
|
+
className: "text-[80px] font-black uppercase leading-none tracking-tight text-white drop-shadow-2xl sm:text-[120px]",
|
|
66254
|
+
style: { textShadow: "0 18px 36px rgba(0,0,0,0.34)" },
|
|
66255
|
+
children: greenStreakMilestoneBanner.headline
|
|
66256
|
+
}
|
|
66257
|
+
) }),
|
|
66258
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
66259
|
+
motion.div,
|
|
66260
|
+
{
|
|
66261
|
+
initial: { opacity: 0, scaleX: 0 },
|
|
66262
|
+
animate: { opacity: 1, scaleX: 1 },
|
|
66263
|
+
transition: { delay: 0.22, duration: 0.45, ease: [0.16, 1, 0.3, 1] },
|
|
66264
|
+
className: "h-1 w-40 origin-left rounded-full bg-[#00AB45] shadow-[0_0_16px_rgba(0,171,69,0.44)] sm:w-56"
|
|
66265
|
+
}
|
|
66266
|
+
),
|
|
66267
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
66268
|
+
motion.div,
|
|
66269
|
+
{
|
|
66270
|
+
initial: { opacity: 0, y: 8, filter: "blur(6px)" },
|
|
66271
|
+
animate: { opacity: 1, y: 0, filter: "blur(0px)" },
|
|
66272
|
+
transition: { delay: 0.28, duration: 0.28, ease: [0.16, 1, 0.3, 1] },
|
|
66273
|
+
className: "flex flex-wrap items-center justify-center gap-x-4 text-[60px] font-black uppercase leading-none tracking-tight text-[#00AB45] drop-shadow-2xl sm:gap-x-8 sm:text-[90px]",
|
|
66274
|
+
style: { filter: "drop-shadow(0 18px 36px rgba(0,171,69,0.28))" },
|
|
66275
|
+
children: [
|
|
66276
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "ALL" }),
|
|
66277
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "GREEN" })
|
|
66278
|
+
]
|
|
66279
|
+
}
|
|
66280
|
+
)
|
|
66281
|
+
] })
|
|
66282
|
+
},
|
|
66283
|
+
`green-streak-milestone-${greenStreakMilestoneBanner.milestoneSeconds}`
|
|
66284
|
+
)
|
|
66285
|
+
] }, `green-streak-milestone-wrapper-${greenStreakMilestoneBanner.milestoneSeconds}`) : null }),
|
|
65375
66286
|
diagnosisModalOpen && bottleneckModalData?.clipId && /* @__PURE__ */ jsxRuntime.jsx(
|
|
65376
66287
|
DiagnosisVideoModal,
|
|
65377
66288
|
{
|
|
@@ -68766,6 +69677,7 @@ var LinesLeaderboard = ({
|
|
|
68766
69677
|
timeRange,
|
|
68767
69678
|
setTimeRange,
|
|
68768
69679
|
todayEfficiencyByLineId,
|
|
69680
|
+
dailyFallbackEfficiencyByLineId,
|
|
68769
69681
|
monthlyEfficiencyByLineId,
|
|
68770
69682
|
supervisorsByLineId,
|
|
68771
69683
|
supervisorNamesByLineId,
|
|
@@ -68801,8 +69713,12 @@ var LinesLeaderboard = ({
|
|
|
68801
69713
|
});
|
|
68802
69714
|
setTimeRange(newRange);
|
|
68803
69715
|
}, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
|
|
69716
|
+
const canClickLeaderboardRow = React144__namespace.default.useCallback(
|
|
69717
|
+
(item) => item.rowType === "line" && !!item.line && canClickLine(item.line.id),
|
|
69718
|
+
[canClickLine]
|
|
69719
|
+
);
|
|
68804
69720
|
const handleLeaderboardLineClick = React144__namespace.default.useCallback((item, clickSource) => {
|
|
68805
|
-
if (!
|
|
69721
|
+
if (!canClickLeaderboardRow(item) || !item.line) return;
|
|
68806
69722
|
trackCoreEvent("Leaderboard Line Clicked", {
|
|
68807
69723
|
line_id: item.line.id,
|
|
68808
69724
|
line_name: item.line.line_name,
|
|
@@ -68814,33 +69730,46 @@ var LinesLeaderboard = ({
|
|
|
68814
69730
|
supervisor_name: item.supervisorName || "Unassigned"
|
|
68815
69731
|
});
|
|
68816
69732
|
onLineClick(item.line);
|
|
68817
|
-
}, [
|
|
69733
|
+
}, [canClickLeaderboardRow, onLineClick, timeRange]);
|
|
68818
69734
|
const viewLoadedTrackedRef = React144__namespace.default.useRef(null);
|
|
68819
69735
|
const leaderboardData = React144__namespace.default.useMemo(() => {
|
|
68820
69736
|
const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
68821
69737
|
const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
|
|
68822
|
-
|
|
68823
|
-
|
|
69738
|
+
const fallbackEfficiencyMap = timeRange === "today" ? dailyFallbackEfficiencyByLineId : void 0;
|
|
69739
|
+
return buildLineLeaderboardRows({
|
|
69740
|
+
lines,
|
|
69741
|
+
efficiencyByLineId: efficiencyMap,
|
|
69742
|
+
fallbackEfficiencyByLineId: fallbackEfficiencyMap,
|
|
69743
|
+
isLoading: loading
|
|
69744
|
+
}).map((row, index) => {
|
|
69745
|
+
const supervisorByUserId = /* @__PURE__ */ new Map();
|
|
69746
|
+
const fallbackSupervisorNames = [];
|
|
69747
|
+
row.lines.forEach((line) => {
|
|
69748
|
+
(supervisorsByLineId?.get(line.id) || []).forEach((supervisor) => {
|
|
69749
|
+
supervisorByUserId.set(supervisor.userId, supervisor);
|
|
69750
|
+
});
|
|
69751
|
+
const fallbackName = supervisorNamesByLineId.get(line.id);
|
|
69752
|
+
if (fallbackName && !fallbackSupervisorNames.includes(fallbackName)) {
|
|
69753
|
+
fallbackSupervisorNames.push(fallbackName);
|
|
69754
|
+
}
|
|
69755
|
+
});
|
|
69756
|
+
const supervisors = Array.from(supervisorByUserId.values());
|
|
68824
69757
|
const primarySupervisor = supervisors[0];
|
|
68825
|
-
const supervisorName =
|
|
69758
|
+
const supervisorName = supervisors.length > 1 ? `${supervisors.length} supervisors` : primarySupervisor?.displayName || fallbackSupervisorNames[0] || "Unassigned";
|
|
68826
69759
|
const supervisorImage = primarySupervisor?.profilePhotoUrl || null;
|
|
68827
|
-
const hasEfficiency = efficiencyMap.has(line.id);
|
|
68828
|
-
const efficiency = hasEfficiency ? efficiencyMap.get(line.id) ?? 0 : loading ? null : timeRange === "monthly" ? 0 : null;
|
|
68829
|
-
const sortValue = typeof efficiency === "number" ? efficiency : -1;
|
|
68830
69760
|
return {
|
|
68831
|
-
|
|
68832
|
-
|
|
69761
|
+
...row,
|
|
69762
|
+
rank: row.rank ?? index + 1,
|
|
68833
69763
|
supervisorName,
|
|
68834
69764
|
supervisorImage,
|
|
68835
|
-
supervisors
|
|
68836
|
-
efficiency,
|
|
68837
|
-
sortValue
|
|
69765
|
+
supervisors
|
|
68838
69766
|
};
|
|
68839
|
-
})
|
|
69767
|
+
});
|
|
68840
69768
|
}, [
|
|
68841
69769
|
lines,
|
|
68842
69770
|
timeRange,
|
|
68843
69771
|
todayEfficiencyByLineId,
|
|
69772
|
+
dailyFallbackEfficiencyByLineId,
|
|
68844
69773
|
monthlyEfficiencyByLineId,
|
|
68845
69774
|
supervisorsByLineId,
|
|
68846
69775
|
supervisorNamesByLineId,
|
|
@@ -68857,11 +69786,11 @@ var LinesLeaderboard = ({
|
|
|
68857
69786
|
trackCoreEvent("Leaderboard View Loaded", {
|
|
68858
69787
|
time_range: timeRange,
|
|
68859
69788
|
lines_count: leaderboardData.length,
|
|
68860
|
-
top_line_id: topLine?.line.id,
|
|
68861
|
-
top_line_name: topLine?.
|
|
69789
|
+
top_line_id: topLine?.rowType === "line" ? topLine.line?.id : topLine?.areaId,
|
|
69790
|
+
top_line_name: topLine?.displayName,
|
|
68862
69791
|
top_efficiency: topLine?.efficiency,
|
|
68863
|
-
bottom_line_id: bottomLine?.line.id,
|
|
68864
|
-
bottom_line_name: bottomLine?.
|
|
69792
|
+
bottom_line_id: bottomLine?.rowType === "line" ? bottomLine.line?.id : bottomLine?.areaId,
|
|
69793
|
+
bottom_line_name: bottomLine?.displayName,
|
|
68865
69794
|
bottom_efficiency: bottomLine?.efficiency,
|
|
68866
69795
|
efficiency_spread: topLine && bottomLine && topLine.efficiency !== null && bottomLine.efficiency !== null ? (topLine.efficiency - bottomLine.efficiency).toFixed(1) : null,
|
|
68867
69796
|
from_page: "kpis_overview"
|
|
@@ -68968,7 +69897,7 @@ var LinesLeaderboard = ({
|
|
|
68968
69897
|
const isFirst = item.rank === 1;
|
|
68969
69898
|
const isSecond = item.rank === 2;
|
|
68970
69899
|
item.rank === 3;
|
|
68971
|
-
const isClickable =
|
|
69900
|
+
const isClickable = canClickLeaderboardRow(item);
|
|
68972
69901
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
68973
69902
|
"div",
|
|
68974
69903
|
{
|
|
@@ -69011,7 +69940,11 @@ var LinesLeaderboard = ({
|
|
|
69011
69940
|
className: `flex flex-col items-center w-32 md:w-40 lg:w-48 xl:w-60 px-2 md:px-3 xl:px-4 pb-3 md:pb-4 pt-8 md:pt-10 rounded-2xl border bg-gradient-to-b shadow-2xl backdrop-blur-sm ${getRankColor(item.rank)} ${isFirst ? "h-44 md:h-52 lg:h-60 xl:h-64" : isSecond ? "h-36 md:h-44 lg:h-52 xl:h-56" : "h-28 md:h-36 lg:h-44 xl:h-48"}`,
|
|
69012
69941
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col items-center justify-center w-full", children: [
|
|
69013
69942
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: `font-bold text-gray-900 text-center line-clamp-1 mb-1 ${isFirst ? "text-xs md:text-sm lg:text-base xl:text-lg" : "text-[10px] md:text-xs lg:text-sm xl:text-base"}`, children: item.supervisorName }),
|
|
69014
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-gray-600 text-center line-clamp-1 font-medium opacity-80 bg-white/50 px-2 md:px-3 py-0.5 rounded-full ${isFirst ? "text-[9px] md:text-[10px] lg:text-xs xl:text-sm mb-2 md:mb-3" : "text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs mb-1 md:mb-2"}`, children: item.
|
|
69943
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-gray-600 text-center line-clamp-1 font-medium opacity-80 bg-white/50 px-2 md:px-3 py-0.5 rounded-full ${isFirst ? "text-[9px] md:text-[10px] lg:text-xs xl:text-sm mb-2 md:mb-3" : "text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs mb-1 md:mb-2"}`, children: item.displayName }),
|
|
69944
|
+
item.rowType === "area" && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mb-1 text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs font-semibold uppercase text-gray-500", children: [
|
|
69945
|
+
item.lines.length,
|
|
69946
|
+
" lines"
|
|
69947
|
+
] }),
|
|
69015
69948
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center mt-auto", children: [
|
|
69016
69949
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `font-bold uppercase tracking-widest mb-0.5 ${isFirst ? "text-yellow-700/70 text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs" : isSecond ? "text-gray-600/70 text-[7px] md:text-[8px] lg:text-[9px] xl:text-[10px]" : "text-orange-700/70 text-[7px] md:text-[8px] lg:text-[9px] xl:text-[10px]"}`, children: viewType === "machine" ? "Utilization" : "Efficiency" }),
|
|
69017
69950
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `font-black tracking-tight leading-none ${isFirst ? "text-lg md:text-xl lg:text-2xl xl:text-3xl text-transparent bg-clip-text bg-gradient-to-br from-yellow-600 to-yellow-800 drop-shadow-sm" : isSecond ? "text-base md:text-lg lg:text-xl xl:text-2xl text-transparent bg-clip-text bg-gradient-to-br from-gray-600 to-gray-800 drop-shadow-sm" : "text-sm md:text-base lg:text-lg xl:text-xl text-transparent bg-clip-text bg-gradient-to-br from-orange-600 to-orange-800 drop-shadow-sm"}`, children: formatEfficiency(item.efficiency) })
|
|
@@ -69034,7 +69967,7 @@ var LinesLeaderboard = ({
|
|
|
69034
69967
|
] }) }),
|
|
69035
69968
|
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-gray-100", children: leaderboardData.map((item) => {
|
|
69036
69969
|
const isTopThree = item.rank <= 3;
|
|
69037
|
-
const isClickable =
|
|
69970
|
+
const isClickable = canClickLeaderboardRow(item);
|
|
69038
69971
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
69039
69972
|
"tr",
|
|
69040
69973
|
{
|
|
@@ -69066,7 +69999,13 @@ var LinesLeaderboard = ({
|
|
|
69066
69999
|
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 rounded-full bg-gray-100 flex items-center justify-center text-gray-500 overflow-hidden border border-gray-200 flex-shrink-0", children: item.supervisorImage ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.supervisorImage, alt: item.supervisorName, className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-bold", children: getInitials(item.supervisorName) }) }),
|
|
69067
70000
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-gray-900", children: item.supervisorName })
|
|
69068
70001
|
] }) }),
|
|
69069
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 whitespace-nowrap text-sm text-gray-500", children:
|
|
70002
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 whitespace-nowrap text-sm text-gray-500", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
70003
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-700", children: item.displayName }),
|
|
70004
|
+
item.rowType === "area" && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-gray-400", children: [
|
|
70005
|
+
item.lines.length,
|
|
70006
|
+
" lines"
|
|
70007
|
+
] })
|
|
70008
|
+
] }) }),
|
|
69070
70009
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 whitespace-nowrap text-right", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-end", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-gray-900", children: formatEfficiency(item.efficiency) }) }) })
|
|
69071
70010
|
]
|
|
69072
70011
|
},
|
|
@@ -69344,17 +70283,6 @@ var KPIsOverviewView = ({
|
|
|
69344
70283
|
const filterRef = React144.useRef(null);
|
|
69345
70284
|
const filterButtonRef = React144.useRef(null);
|
|
69346
70285
|
const [error, setError] = React144.useState(null);
|
|
69347
|
-
const [topPerformer, setTopPerformer] = React144.useState({
|
|
69348
|
-
name: "Top Performer",
|
|
69349
|
-
role: "Sup.",
|
|
69350
|
-
unit: "Line",
|
|
69351
|
-
periodLabel: (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", { month: "long", year: "numeric" }),
|
|
69352
|
-
efficiency: null,
|
|
69353
|
-
imageUrl: null,
|
|
69354
|
-
initials: "TP"
|
|
69355
|
-
});
|
|
69356
|
-
const [topPerformerLoading, setTopPerformerLoading] = React144.useState(true);
|
|
69357
|
-
const [topPerformerImageError, setTopPerformerImageError] = React144.useState(false);
|
|
69358
70286
|
const [todayEfficiencyByLineId, setTodayEfficiencyByLineId] = React144.useState(/* @__PURE__ */ new Map());
|
|
69359
70287
|
const [dailyLoading, setDailyLoading] = React144.useState(false);
|
|
69360
70288
|
const [dailyError, setDailyError] = React144.useState(null);
|
|
@@ -69363,6 +70291,9 @@ var KPIsOverviewView = ({
|
|
|
69363
70291
|
const [monthlyError, setMonthlyError] = React144.useState(null);
|
|
69364
70292
|
const dailyRequestKeyRef = React144.useRef(null);
|
|
69365
70293
|
const monthlyRequestKeyRef = React144.useRef(null);
|
|
70294
|
+
const dailyFallbackRequestKeyRef = React144.useRef(null);
|
|
70295
|
+
const pendingTabRouteSyncRef = React144.useRef(null);
|
|
70296
|
+
const [scopedDailyFallbackEfficiencyByLineId, setScopedDailyFallbackEfficiencyByLineId] = React144.useState(/* @__PURE__ */ new Map());
|
|
69366
70297
|
const supabase = useSupabase();
|
|
69367
70298
|
const { user } = useAuth();
|
|
69368
70299
|
const dashboardConfig = useDashboardConfig();
|
|
@@ -69407,8 +70338,23 @@ var KPIsOverviewView = ({
|
|
|
69407
70338
|
const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
|
|
69408
70339
|
const leaderboardLinesForView = React144__namespace.default.useMemo(() => {
|
|
69409
70340
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
69410
|
-
|
|
69411
|
-
|
|
70341
|
+
const metadataByLineId = new Map(lines.map((line) => [line.id, line]));
|
|
70342
|
+
return leaderboardLines.map((line) => {
|
|
70343
|
+
const metadata = metadataByLineId.get(line.id);
|
|
70344
|
+
return metadata ? {
|
|
70345
|
+
...line,
|
|
70346
|
+
factory_id: line.factory_id || metadata.factory_id,
|
|
70347
|
+
factory_name: line.factory_name || metadata.factory_name,
|
|
70348
|
+
company_name: line.company_name || metadata.company_name,
|
|
70349
|
+
monitoring_mode: line.monitoring_mode ?? metadata.monitoring_mode,
|
|
70350
|
+
factory_area_id: line.factory_area_id ?? metadata.factory_area_id ?? null,
|
|
70351
|
+
factory_area_key: line.factory_area_key ?? metadata.factory_area_key ?? null,
|
|
70352
|
+
factory_area_name: line.factory_area_name ?? metadata.factory_area_name ?? null,
|
|
70353
|
+
factory_area_sort_order: line.factory_area_sort_order ?? metadata.factory_area_sort_order ?? null,
|
|
70354
|
+
factory_area_enabled: line.factory_area_enabled ?? metadata.factory_area_enabled ?? null
|
|
70355
|
+
} : line;
|
|
70356
|
+
}).filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
70357
|
+
}, [leaderboardLines, lines, viewType]);
|
|
69412
70358
|
const linesForView = React144__namespace.default.useMemo(() => {
|
|
69413
70359
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
69414
70360
|
return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
@@ -69528,12 +70474,19 @@ var KPIsOverviewView = ({
|
|
|
69528
70474
|
React144.useEffect(() => {
|
|
69529
70475
|
if (!router$1.isReady || !hasHydratedLeaderboardRouteState) return;
|
|
69530
70476
|
if (activeTab === "today" && loading) return;
|
|
70477
|
+
const currentTab = typeof router$1.query.tab === "string" ? router$1.query.tab : void 0;
|
|
70478
|
+
const currentRouteTab = currentTab === "leaderboard" ? "leaderboard" : "today";
|
|
70479
|
+
if (currentRouteTab !== activeTab) {
|
|
70480
|
+
if (pendingTabRouteSyncRef.current !== activeTab) {
|
|
70481
|
+
return;
|
|
70482
|
+
}
|
|
70483
|
+
pendingTabRouteSyncRef.current = null;
|
|
70484
|
+
}
|
|
69531
70485
|
const expectedTab = activeTab === "leaderboard" ? "leaderboard" : void 0;
|
|
69532
70486
|
const expectedDate = activeTab === "leaderboard" && timeRange === "today" && isHistoricalLeaderboardDaily ? effectiveLeaderboardDate : void 0;
|
|
69533
70487
|
const expectedShift = expectedDate !== void 0 ? effectiveLeaderboardShiftId.toString() : void 0;
|
|
69534
70488
|
const expectedFactory = activeTab === "today" && selectedFactoryNode ? selectedFactoryNode.id : void 0;
|
|
69535
70489
|
const expectedFactoryArea = activeTab === "today" && selectedFactoryNode && selectedFactoryAreaNode ? selectedFactoryAreaNode.id : void 0;
|
|
69536
|
-
const currentTab = typeof router$1.query.tab === "string" ? router$1.query.tab : void 0;
|
|
69537
70490
|
const currentDateQuery = typeof router$1.query.date === "string" ? router$1.query.date : void 0;
|
|
69538
70491
|
const currentShiftQuery = typeof router$1.query.shift === "string" ? router$1.query.shift : void 0;
|
|
69539
70492
|
const currentFactoryQuery = getSingleQueryValue(router$1.query[KPI_FACTORY_QUERY_PARAM]);
|
|
@@ -69593,6 +70546,35 @@ var KPIsOverviewView = ({
|
|
|
69593
70546
|
});
|
|
69594
70547
|
return map;
|
|
69595
70548
|
}, [lineMetrics, lineModeById]);
|
|
70549
|
+
const liveDailyFallbackEfficiencyByLineId = React144__namespace.default.useMemo(() => {
|
|
70550
|
+
const map = /* @__PURE__ */ new Map();
|
|
70551
|
+
lineMetricRowsByLineId.forEach((row, lineId) => {
|
|
70552
|
+
const value = Number(row?.avg_efficiency);
|
|
70553
|
+
if (!Number.isFinite(value)) return;
|
|
70554
|
+
const rowDate = typeof row?.date === "string" ? row.date : typeof row?.operational_date === "string" ? row.operational_date : void 0;
|
|
70555
|
+
const rawShiftId = row?.shift_id ?? row?.shiftId;
|
|
70556
|
+
const parsedShiftId = typeof rawShiftId === "number" ? rawShiftId : Number.parseInt(String(rawShiftId ?? ""), 10);
|
|
70557
|
+
const hasScopedRow = rowDate !== void 0 || rawShiftId !== void 0;
|
|
70558
|
+
const matchesSelectedScope = rowDate === effectiveLeaderboardDate && Number.isFinite(parsedShiftId) && parsedShiftId === effectiveLeaderboardShiftId;
|
|
70559
|
+
const canUseUnscopedLiveFallback = !isHistoricalLeaderboardDaily && !hasScopedRow;
|
|
70560
|
+
if (matchesSelectedScope || canUseUnscopedLiveFallback) {
|
|
70561
|
+
map.set(lineId, value);
|
|
70562
|
+
}
|
|
70563
|
+
});
|
|
70564
|
+
return map;
|
|
70565
|
+
}, [
|
|
70566
|
+
effectiveLeaderboardDate,
|
|
70567
|
+
effectiveLeaderboardShiftId,
|
|
70568
|
+
isHistoricalLeaderboardDaily,
|
|
70569
|
+
lineMetricRowsByLineId
|
|
70570
|
+
]);
|
|
70571
|
+
const dailyFallbackEfficiencyByLineId = React144__namespace.default.useMemo(() => {
|
|
70572
|
+
const map = new Map(liveDailyFallbackEfficiencyByLineId);
|
|
70573
|
+
scopedDailyFallbackEfficiencyByLineId.forEach((value, lineId) => {
|
|
70574
|
+
map.set(lineId, value);
|
|
70575
|
+
});
|
|
70576
|
+
return map;
|
|
70577
|
+
}, [liveDailyFallbackEfficiencyByLineId, scopedDailyFallbackEfficiencyByLineId]);
|
|
69596
70578
|
const kpisByLineId = React144__namespace.default.useMemo(() => {
|
|
69597
70579
|
const map = /* @__PURE__ */ new Map();
|
|
69598
70580
|
lineMetricRowsByLineId.forEach((row, lineId) => {
|
|
@@ -69614,32 +70596,11 @@ var KPIsOverviewView = ({
|
|
|
69614
70596
|
() => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
|
|
69615
70597
|
[leaderboardLines, lines]
|
|
69616
70598
|
);
|
|
69617
|
-
const { supervisorNamesByLineId, supervisorsByLineId
|
|
70599
|
+
const { supervisorNamesByLineId, supervisorsByLineId } = useSupervisorsByLineIds(supervisorLineIds, {
|
|
69618
70600
|
enabled: supervisorEnabled && supervisorLineIds.length > 0,
|
|
69619
70601
|
companyId: resolvedCompanyId,
|
|
69620
70602
|
useBackend: true
|
|
69621
70603
|
});
|
|
69622
|
-
React144.useEffect(() => {
|
|
69623
|
-
let isMounted = true;
|
|
69624
|
-
const loadTopPerformer = async () => {
|
|
69625
|
-
try {
|
|
69626
|
-
const record = await awardsService.getTopPerformer(supabase, resolvedCompanyId);
|
|
69627
|
-
if (!isMounted) return;
|
|
69628
|
-
if (record) {
|
|
69629
|
-
setTopPerformer(buildTopPerformerDisplay(record));
|
|
69630
|
-
setTopPerformerImageError(false);
|
|
69631
|
-
}
|
|
69632
|
-
} catch (err) {
|
|
69633
|
-
console.error("[KPIsOverviewView] Failed to load top performer:", err);
|
|
69634
|
-
} finally {
|
|
69635
|
-
if (isMounted) setTopPerformerLoading(false);
|
|
69636
|
-
}
|
|
69637
|
-
};
|
|
69638
|
-
loadTopPerformer();
|
|
69639
|
-
return () => {
|
|
69640
|
-
isMounted = false;
|
|
69641
|
-
};
|
|
69642
|
-
}, [supabase, resolvedCompanyId]);
|
|
69643
70604
|
React144.useEffect(() => {
|
|
69644
70605
|
trackCorePageView("KPIs Overview");
|
|
69645
70606
|
}, []);
|
|
@@ -69689,16 +70650,25 @@ var KPIsOverviewView = ({
|
|
|
69689
70650
|
`/api/dashboard/leaderboard-lines?company_id=${encodeURIComponent(resolvedCompanyId)}`
|
|
69690
70651
|
);
|
|
69691
70652
|
if (!isMounted) return;
|
|
69692
|
-
const
|
|
69693
|
-
|
|
69694
|
-
|
|
69695
|
-
|
|
69696
|
-
|
|
69697
|
-
|
|
69698
|
-
|
|
69699
|
-
|
|
69700
|
-
|
|
69701
|
-
|
|
70653
|
+
const metadataByLineId = new Map(lines.map((line) => [line.id, line]));
|
|
70654
|
+
const transformed = (data.lines || []).filter((line) => line.enable !== false).map((line) => {
|
|
70655
|
+
const metadata = metadataByLineId.get(line.id);
|
|
70656
|
+
return {
|
|
70657
|
+
id: line.id,
|
|
70658
|
+
line_name: line.line_name,
|
|
70659
|
+
factory_id: line.factory_id || metadata?.factory_id || "",
|
|
70660
|
+
factory_name: metadata?.factory_name || "N/A",
|
|
70661
|
+
company_id: line.company_id,
|
|
70662
|
+
company_name: metadata?.company_name || "",
|
|
70663
|
+
enable: line.enable ?? true,
|
|
70664
|
+
monitoring_mode: line.monitoring_mode ?? metadata?.monitoring_mode ?? "output",
|
|
70665
|
+
factory_area_id: line.factory_area_id ?? metadata?.factory_area_id ?? null,
|
|
70666
|
+
factory_area_key: line.factory_area_key ?? metadata?.factory_area_key ?? null,
|
|
70667
|
+
factory_area_name: line.factory_area_name ?? metadata?.factory_area_name ?? null,
|
|
70668
|
+
factory_area_sort_order: line.factory_area_sort_order ?? metadata?.factory_area_sort_order ?? null,
|
|
70669
|
+
factory_area_enabled: line.factory_area_enabled ?? metadata?.factory_area_enabled ?? null
|
|
70670
|
+
};
|
|
70671
|
+
});
|
|
69702
70672
|
setLeaderboardLines(transformed);
|
|
69703
70673
|
} catch (err) {
|
|
69704
70674
|
console.error("[KPIsOverviewView] Failed to load leaderboard lines:", err);
|
|
@@ -69713,6 +70683,58 @@ var KPIsOverviewView = ({
|
|
|
69713
70683
|
isMounted = false;
|
|
69714
70684
|
};
|
|
69715
70685
|
}, [supabase, resolvedCompanyId, lines]);
|
|
70686
|
+
React144.useEffect(() => {
|
|
70687
|
+
if (activeTab !== "leaderboard" || timeRange !== "today") return;
|
|
70688
|
+
if (!supabase || !resolvedCompanyId || !effectiveLeaderboardDate || leaderboardLinesForView.length === 0) {
|
|
70689
|
+
setScopedDailyFallbackEfficiencyByLineId(/* @__PURE__ */ new Map());
|
|
70690
|
+
return;
|
|
70691
|
+
}
|
|
70692
|
+
const targetLineIds = leaderboardLinesForView.map((line) => line.id);
|
|
70693
|
+
const lineIdsKey = targetLineIds.slice().sort().join(",");
|
|
70694
|
+
const requestKey = `${effectiveLeaderboardDate}|${effectiveLeaderboardShiftId}|${lineIdsKey}`;
|
|
70695
|
+
if (dailyFallbackRequestKeyRef.current === requestKey) return;
|
|
70696
|
+
dailyFallbackRequestKeyRef.current = requestKey;
|
|
70697
|
+
let isMounted = true;
|
|
70698
|
+
const fetchScopedFallbackEfficiencies = async () => {
|
|
70699
|
+
try {
|
|
70700
|
+
const entries = await lineLeaderboardService.getDailyLineLeaderboard(supabase, {
|
|
70701
|
+
companyId: resolvedCompanyId,
|
|
70702
|
+
date: effectiveLeaderboardDate,
|
|
70703
|
+
shiftId: effectiveLeaderboardShiftId,
|
|
70704
|
+
lineIds: targetLineIds,
|
|
70705
|
+
lineMode: viewType === "machine" ? "uptime" : "output",
|
|
70706
|
+
includeBelowThreshold: true
|
|
70707
|
+
});
|
|
70708
|
+
if (!isMounted) return;
|
|
70709
|
+
const nextMap = /* @__PURE__ */ new Map();
|
|
70710
|
+
entries.forEach((entry) => {
|
|
70711
|
+
const value = Number(entry.avg_efficiency);
|
|
70712
|
+
if (Number.isFinite(value)) {
|
|
70713
|
+
nextMap.set(entry.line_id, value);
|
|
70714
|
+
}
|
|
70715
|
+
});
|
|
70716
|
+
setScopedDailyFallbackEfficiencyByLineId(nextMap);
|
|
70717
|
+
} catch (err) {
|
|
70718
|
+
if (!isMounted) return;
|
|
70719
|
+
console.warn("[KPIsOverviewView] Failed to load daily fallback line efficiencies:", err);
|
|
70720
|
+
setScopedDailyFallbackEfficiencyByLineId(/* @__PURE__ */ new Map());
|
|
70721
|
+
dailyFallbackRequestKeyRef.current = null;
|
|
70722
|
+
}
|
|
70723
|
+
};
|
|
70724
|
+
void fetchScopedFallbackEfficiencies();
|
|
70725
|
+
return () => {
|
|
70726
|
+
isMounted = false;
|
|
70727
|
+
};
|
|
70728
|
+
}, [
|
|
70729
|
+
activeTab,
|
|
70730
|
+
effectiveLeaderboardDate,
|
|
70731
|
+
effectiveLeaderboardShiftId,
|
|
70732
|
+
leaderboardLinesForView,
|
|
70733
|
+
resolvedCompanyId,
|
|
70734
|
+
supabase,
|
|
70735
|
+
timeRange,
|
|
70736
|
+
viewType
|
|
70737
|
+
]);
|
|
69716
70738
|
const fetchMonthlyLeaderboard = React144.useCallback(async () => {
|
|
69717
70739
|
if (!supabase || !resolvedCompanyId || leaderboardLinesForView.length === 0) return;
|
|
69718
70740
|
const targetLineIds = leaderboardLinesForView.map((line) => line.id);
|
|
@@ -69734,10 +70756,11 @@ var KPIsOverviewView = ({
|
|
|
69734
70756
|
lineMode: viewType === "machine" ? "uptime" : "output"
|
|
69735
70757
|
});
|
|
69736
70758
|
const nextMap = /* @__PURE__ */ new Map();
|
|
69737
|
-
targetLineIds.forEach((lineId) => nextMap.set(lineId, 0));
|
|
69738
70759
|
entries.forEach((entry) => {
|
|
69739
70760
|
const value = Number(entry.avg_efficiency);
|
|
69740
|
-
|
|
70761
|
+
if (Number.isFinite(value)) {
|
|
70762
|
+
nextMap.set(entry.line_id, value);
|
|
70763
|
+
}
|
|
69741
70764
|
});
|
|
69742
70765
|
setMonthlyEfficiencyByLineId(nextMap);
|
|
69743
70766
|
trackCoreEvent("Leaderboard Monthly Data Fetched", {
|
|
@@ -69784,10 +70807,11 @@ var KPIsOverviewView = ({
|
|
|
69784
70807
|
lineMode: viewType === "machine" ? "uptime" : "output"
|
|
69785
70808
|
});
|
|
69786
70809
|
const nextMap = /* @__PURE__ */ new Map();
|
|
69787
|
-
targetLineIds.forEach((lineId) => nextMap.set(lineId, 0));
|
|
69788
70810
|
entries.forEach((entry) => {
|
|
69789
70811
|
const value = Number(entry.avg_efficiency);
|
|
69790
|
-
|
|
70812
|
+
if (Number.isFinite(value)) {
|
|
70813
|
+
nextMap.set(entry.line_id, value);
|
|
70814
|
+
}
|
|
69791
70815
|
});
|
|
69792
70816
|
setTodayEfficiencyByLineId(nextMap);
|
|
69793
70817
|
} catch (err) {
|
|
@@ -69827,69 +70851,6 @@ var KPIsOverviewView = ({
|
|
|
69827
70851
|
factoryAreaId: selectedFactoryAreaNode?.id
|
|
69828
70852
|
});
|
|
69829
70853
|
}, [activeTab, selectedFactoryNode, selectedFactoryAreaNode]);
|
|
69830
|
-
const formatTopPerformerWeek = (periodStart, periodEnd) => {
|
|
69831
|
-
const dateToUse = periodStart ? /* @__PURE__ */ new Date(`${periodStart}T00:00:00`) : /* @__PURE__ */ new Date();
|
|
69832
|
-
if (Number.isNaN(dateToUse.getTime())) {
|
|
69833
|
-
return (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", { month: "long", year: "numeric" });
|
|
69834
|
-
}
|
|
69835
|
-
return dateToUse.toLocaleDateString("en-US", { month: "long", year: "numeric" });
|
|
69836
|
-
};
|
|
69837
|
-
const buildTopPerformerDisplay = (record) => {
|
|
69838
|
-
const supervisorAvatars = [];
|
|
69839
|
-
if (record.supervisors && record.supervisors.length > 0) {
|
|
69840
|
-
for (const s of record.supervisors) {
|
|
69841
|
-
let supervisorName = "Supervisor";
|
|
69842
|
-
if (s.first_name) {
|
|
69843
|
-
supervisorName = s.last_name ? `${s.first_name} ${s.last_name}` : s.first_name;
|
|
69844
|
-
}
|
|
69845
|
-
supervisorAvatars.push({
|
|
69846
|
-
userId: s.user_id,
|
|
69847
|
-
name: supervisorName,
|
|
69848
|
-
imageUrl: s.profile_photo_url || null,
|
|
69849
|
-
initials: getInitials(supervisorName)
|
|
69850
|
-
});
|
|
69851
|
-
}
|
|
69852
|
-
}
|
|
69853
|
-
let displayName = record.recipient_name || "Supervisor";
|
|
69854
|
-
if (record.first_name) {
|
|
69855
|
-
displayName = record.last_name ? `${record.first_name} ${record.last_name}` : record.first_name;
|
|
69856
|
-
} else if (record.recipient_user_id && allSupervisorsMap?.has(record.recipient_user_id)) {
|
|
69857
|
-
const supervisor = allSupervisorsMap.get(record.recipient_user_id);
|
|
69858
|
-
if (supervisor) {
|
|
69859
|
-
displayName = supervisor.displayName;
|
|
69860
|
-
}
|
|
69861
|
-
} else if (displayName.includes(".") || displayName.includes("@")) {
|
|
69862
|
-
const parts = displayName.split(/[.@]/);
|
|
69863
|
-
if (parts.length >= 2) {
|
|
69864
|
-
const firstName = parts[0].charAt(0).toUpperCase() + parts[0].slice(1);
|
|
69865
|
-
const lastName = parts[1].charAt(0).toUpperCase() + parts[1].slice(1);
|
|
69866
|
-
displayName = `${firstName} ${lastName}`;
|
|
69867
|
-
} else if (parts.length === 1) {
|
|
69868
|
-
displayName = parts[0].charAt(0).toUpperCase() + parts[0].slice(1);
|
|
69869
|
-
}
|
|
69870
|
-
}
|
|
69871
|
-
if (supervisorAvatars.length === 0 && record.recipient_user_id) {
|
|
69872
|
-
supervisorAvatars.push({
|
|
69873
|
-
userId: record.recipient_user_id,
|
|
69874
|
-
name: displayName,
|
|
69875
|
-
imageUrl: record.profile_photo_url || null,
|
|
69876
|
-
initials: getInitials(displayName)
|
|
69877
|
-
});
|
|
69878
|
-
}
|
|
69879
|
-
const efficiencyValue = typeof record.avg_efficiency === "number" ? record.avg_efficiency : Number.parseFloat(String(record.avg_efficiency));
|
|
69880
|
-
const efficiency = Number.isFinite(efficiencyValue) ? efficiencyValue : null;
|
|
69881
|
-
const unitLabel = record.winning_line_name || record.unit || "Line";
|
|
69882
|
-
return {
|
|
69883
|
-
name: displayName,
|
|
69884
|
-
role: "Sup.",
|
|
69885
|
-
unit: unitLabel,
|
|
69886
|
-
periodLabel: formatTopPerformerWeek(record.period_start, record.period_end),
|
|
69887
|
-
efficiency,
|
|
69888
|
-
imageUrl: record.profile_photo_url || null,
|
|
69889
|
-
initials: getInitials(displayName),
|
|
69890
|
-
supervisors: supervisorAvatars.length > 0 ? supervisorAvatars : void 0
|
|
69891
|
-
};
|
|
69892
|
-
};
|
|
69893
70854
|
const handleLineClick = (line, kpis) => {
|
|
69894
70855
|
if (!isSuperAdmin && !assignedLineIdSet.has(line.id)) {
|
|
69895
70856
|
return;
|
|
@@ -69937,6 +70898,7 @@ var KPIsOverviewView = ({
|
|
|
69937
70898
|
from_page: "kpis_overview",
|
|
69938
70899
|
lines_count: trackedLineCount
|
|
69939
70900
|
});
|
|
70901
|
+
pendingTabRouteSyncRef.current = newTab;
|
|
69940
70902
|
setActiveTab(newTab);
|
|
69941
70903
|
}, [activeTab, leaderboardLines.length, lines.length]);
|
|
69942
70904
|
const formatLocalDate2 = React144.useCallback((dateKey) => {
|
|
@@ -69961,10 +70923,8 @@ var KPIsOverviewView = ({
|
|
|
69961
70923
|
const isMonthlyMode = activeTab === "leaderboard" && timeRange === "monthly";
|
|
69962
70924
|
const isLeaderboardLoading = timeRange === "today" ? dailyLoading : monthlyLoading;
|
|
69963
70925
|
const currentEfficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
|
|
69964
|
-
const
|
|
69965
|
-
const
|
|
69966
|
-
typeof topPerformer.efficiency === "number" && Number.isFinite(topPerformer.efficiency);
|
|
69967
|
-
topPerformerLoading ? "--" : typeof topPerformer.efficiency === "number" && Number.isFinite(topPerformer.efficiency) ? `${topPerformer.efficiency.toFixed(1)}%` : "--";
|
|
70926
|
+
const currentFallbackEfficiencyMap = timeRange === "today" ? dailyFallbackEfficiencyByLineId : void 0;
|
|
70927
|
+
const showLeaderboardLoader = activeTab === "leaderboard" && (leaderboardLinesLoading || isLeaderboardLoading && currentEfficiencyMap.size === 0 && (currentFallbackEfficiencyMap?.size ?? 0) === 0);
|
|
69968
70928
|
const showHistoricalLeaderboardHeader = activeTab === "leaderboard" && timeRange === "today" && isHistoricalLeaderboardDaily;
|
|
69969
70929
|
const headerDateKey = activeTab === "leaderboard" && timeRange === "today" ? effectiveLeaderboardDate : monthEndDateKey;
|
|
69970
70930
|
const headerShiftId = showHistoricalLeaderboardHeader ? effectiveLeaderboardShiftId : currentShiftDetails.shiftId;
|
|
@@ -70169,72 +71129,6 @@ var KPIsOverviewView = ({
|
|
|
70169
71129
|
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-green-100 rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-green-700", children: /* @__PURE__ */ jsxRuntime.jsx(ISTTimer_default, {}) }) })
|
|
70170
71130
|
] })
|
|
70171
71131
|
] }),
|
|
70172
|
-
activeTab !== "leaderboard" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 bg-white shadow-md hover:shadow-lg transition-all duration-300 ease-out hover:scale-[1.01] relative rounded-2xl border border-amber-100 pl-2 pr-4 py-1.5 flex items-center justify-between group", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 min-w-0", children: [
|
|
70173
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-shrink-0", children: [
|
|
70174
|
-
(!topPerformer.supervisors || topPerformer.supervisors.length <= 1) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-full border-2 border-amber-100 overflow-hidden bg-amber-50 shadow-sm transition-transform group-hover:scale-105", children: showTopPerformerImage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
70175
|
-
"img",
|
|
70176
|
-
{
|
|
70177
|
-
src: topPerformer.imageUrl || "",
|
|
70178
|
-
alt: "Top Performer",
|
|
70179
|
-
className: "w-full h-full object-cover",
|
|
70180
|
-
onError: () => setTopPerformerImageError(true)
|
|
70181
|
-
}
|
|
70182
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center bg-amber-50 text-sm font-bold text-amber-600", children: topPerformer.initials }) }),
|
|
70183
|
-
topPerformer.supervisors && topPerformer.supervisors.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex -space-x-2", children: [
|
|
70184
|
-
topPerformer.supervisors.slice(0, 3).map((supervisor, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
70185
|
-
"div",
|
|
70186
|
-
{
|
|
70187
|
-
className: "relative inline-block w-9 h-9 rounded-full ring-2 ring-white bg-amber-50 shadow-sm z-0 hover:z-10 transition-all hover:scale-110 group/avatar",
|
|
70188
|
-
style: { zIndex: 3 - idx },
|
|
70189
|
-
children: [
|
|
70190
|
-
supervisor.imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
70191
|
-
"img",
|
|
70192
|
-
{
|
|
70193
|
-
src: supervisor.imageUrl,
|
|
70194
|
-
alt: supervisor.name,
|
|
70195
|
-
className: "w-full h-full object-cover rounded-full"
|
|
70196
|
-
}
|
|
70197
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-xs font-bold text-amber-600 uppercase rounded-full", children: supervisor.initials }),
|
|
70198
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 bg-gray-900 text-white text-[10px] font-medium rounded shadow-lg opacity-0 group-hover/avatar:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-20", children: [
|
|
70199
|
-
supervisor.name,
|
|
70200
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 -mt-[1px] border-4 border-transparent border-t-gray-900" })
|
|
70201
|
-
] })
|
|
70202
|
-
]
|
|
70203
|
-
},
|
|
70204
|
-
supervisor.userId
|
|
70205
|
-
)),
|
|
70206
|
-
topPerformer.supervisors.length > 3 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex w-9 h-9 rounded-full ring-2 ring-white bg-amber-100 items-center justify-center text-xs font-medium text-amber-700 z-0", children: [
|
|
70207
|
-
"+",
|
|
70208
|
-
topPerformer.supervisors.length - 3
|
|
70209
|
-
] })
|
|
70210
|
-
] })
|
|
70211
|
-
] }),
|
|
70212
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
70213
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 leading-none mb-1", children: [
|
|
70214
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold text-amber-600 uppercase tracking-widest", children: "Performer of the month" }),
|
|
70215
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-1 h-1 bg-amber-200 rounded-full" }),
|
|
70216
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold text-gray-400", children: topPerformerLoading ? "Loading" : topPerformer.periodLabel })
|
|
70217
|
-
] }),
|
|
70218
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 leading-none", children: [
|
|
70219
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[140px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
70220
|
-
FittingTitle,
|
|
70221
|
-
{
|
|
70222
|
-
title: topPerformer.name,
|
|
70223
|
-
as: "span",
|
|
70224
|
-
className: "text-sm text-gray-900 font-bold"
|
|
70225
|
-
}
|
|
70226
|
-
) }),
|
|
70227
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-px h-3 bg-gray-200 flex-shrink-0" }),
|
|
70228
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[120px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
70229
|
-
FittingTitle,
|
|
70230
|
-
{
|
|
70231
|
-
title: topPerformer.unit,
|
|
70232
|
-
className: "text-xs font-medium text-gray-500"
|
|
70233
|
-
}
|
|
70234
|
-
) })
|
|
70235
|
-
] })
|
|
70236
|
-
] })
|
|
70237
|
-
] }) }),
|
|
70238
71132
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex bg-gray-100/80 p-1 rounded-xl w-full", children: [
|
|
70239
71133
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
70240
71134
|
"button",
|
|
@@ -70269,86 +71163,18 @@ var KPIsOverviewView = ({
|
|
|
70269
71163
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl md:text-3xl lg:text-4xl font-semibold text-gray-900 tracking-tight", children: activeTab === "leaderboard" ? "Leaderboard" : "Overview" }),
|
|
70270
71164
|
!showHistoricalLeaderboardHeader && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2.5 w-2.5 rounded-full ring-4 flex-shrink-0 bg-emerald-500 animate-pulse ring-emerald-500/10" })
|
|
70271
71165
|
] }),
|
|
70272
|
-
/* @__PURE__ */ jsxRuntime.
|
|
70273
|
-
|
|
70274
|
-
|
|
70275
|
-
|
|
70276
|
-
|
|
70277
|
-
|
|
70278
|
-
|
|
70279
|
-
|
|
70280
|
-
|
|
70281
|
-
|
|
70282
|
-
|
|
70283
|
-
|
|
70284
|
-
topPerformer.supervisors && topPerformer.supervisors.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex -space-x-2", children: [
|
|
70285
|
-
topPerformer.supervisors.slice(0, 3).map((supervisor, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
70286
|
-
"div",
|
|
70287
|
-
{
|
|
70288
|
-
className: "relative inline-block w-10 h-10 rounded-full ring-2 ring-white bg-amber-50 shadow-sm z-0 hover:z-10 transition-all hover:scale-110 group/avatar",
|
|
70289
|
-
style: { zIndex: 3 - idx },
|
|
70290
|
-
children: [
|
|
70291
|
-
supervisor.imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
70292
|
-
"img",
|
|
70293
|
-
{
|
|
70294
|
-
src: supervisor.imageUrl,
|
|
70295
|
-
alt: supervisor.name,
|
|
70296
|
-
className: "w-full h-full object-cover rounded-full"
|
|
70297
|
-
}
|
|
70298
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-sm font-bold text-amber-600 uppercase rounded-full", children: supervisor.initials }),
|
|
70299
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 bg-gray-900 text-white text-[10px] font-medium rounded shadow-lg opacity-0 group-hover/avatar:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-20", children: [
|
|
70300
|
-
supervisor.name,
|
|
70301
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 -mt-[1px] border-4 border-transparent border-t-gray-900" })
|
|
70302
|
-
] })
|
|
70303
|
-
]
|
|
70304
|
-
},
|
|
70305
|
-
supervisor.userId
|
|
70306
|
-
)),
|
|
70307
|
-
topPerformer.supervisors.length > 3 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex w-10 h-10 rounded-full ring-2 ring-white bg-amber-100 items-center justify-center text-sm font-medium text-amber-700 z-0", children: [
|
|
70308
|
-
"+",
|
|
70309
|
-
topPerformer.supervisors.length - 3
|
|
70310
|
-
] })
|
|
70311
|
-
] })
|
|
70312
|
-
] }),
|
|
70313
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
70314
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-[10px] leading-tight mb-1", children: [
|
|
70315
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold text-amber-600 uppercase tracking-widest", children: "Performer of the month" }),
|
|
70316
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-amber-200 opacity-50", children: "\u2022" }),
|
|
70317
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-gray-400", children: topPerformer.periodLabel })
|
|
70318
|
-
] }),
|
|
70319
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 leading-tight", children: [
|
|
70320
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[140px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
70321
|
-
FittingTitle,
|
|
70322
|
-
{
|
|
70323
|
-
title: topPerformer.name,
|
|
70324
|
-
as: "span",
|
|
70325
|
-
className: "text-sm text-gray-900 font-bold"
|
|
70326
|
-
}
|
|
70327
|
-
) }),
|
|
70328
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-px h-3.5 bg-gray-200 flex-shrink-0" }),
|
|
70329
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[150px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
70330
|
-
FittingTitle,
|
|
70331
|
-
{
|
|
70332
|
-
title: topPerformer.unit,
|
|
70333
|
-
className: "text-xs font-medium text-gray-500"
|
|
70334
|
-
}
|
|
70335
|
-
) })
|
|
70336
|
-
] })
|
|
70337
|
-
] })
|
|
70338
|
-
] }),
|
|
70339
|
-
activeTab === "leaderboard" && isHistoricalLeaderboardDaily && /* @__PURE__ */ jsxRuntime.jsx(
|
|
70340
|
-
"button",
|
|
70341
|
-
{
|
|
70342
|
-
type: "button",
|
|
70343
|
-
onClick: () => {
|
|
70344
|
-
setSelectedLeaderboardDate(currentShiftDate);
|
|
70345
|
-
setSelectedLeaderboardShiftId(currentShiftId);
|
|
70346
|
-
},
|
|
70347
|
-
className: "text-xs sm:text-sm font-medium text-blue-600 bg-blue-50 border border-blue-100 hover:bg-blue-100 hover:text-blue-700 px-3 py-1.5 rounded-lg transition-colors shadow-sm ml-4 whitespace-nowrap",
|
|
70348
|
-
children: "Return to Live"
|
|
70349
|
-
}
|
|
70350
|
-
)
|
|
70351
|
-
] })
|
|
71166
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center", children: activeTab === "leaderboard" && isHistoricalLeaderboardDaily && /* @__PURE__ */ jsxRuntime.jsx(
|
|
71167
|
+
"button",
|
|
71168
|
+
{
|
|
71169
|
+
type: "button",
|
|
71170
|
+
onClick: () => {
|
|
71171
|
+
setSelectedLeaderboardDate(currentShiftDate);
|
|
71172
|
+
setSelectedLeaderboardShiftId(currentShiftId);
|
|
71173
|
+
},
|
|
71174
|
+
className: "text-xs sm:text-sm font-medium text-blue-600 bg-blue-50 border border-blue-100 hover:bg-blue-100 hover:text-blue-700 px-3 py-1.5 rounded-lg transition-colors shadow-sm ml-4 whitespace-nowrap",
|
|
71175
|
+
children: "Return to Live"
|
|
71176
|
+
}
|
|
71177
|
+
) })
|
|
70352
71178
|
] }),
|
|
70353
71179
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-blue-50/50 px-4 py-2 rounded-xl border border-blue-100/50 backdrop-blur-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-6", children: [
|
|
70354
71180
|
!isMonthlyMode && !showHistoricalLeaderboardHeader && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -70523,6 +71349,7 @@ var KPIsOverviewView = ({
|
|
|
70523
71349
|
timeRange,
|
|
70524
71350
|
setTimeRange,
|
|
70525
71351
|
todayEfficiencyByLineId,
|
|
71352
|
+
dailyFallbackEfficiencyByLineId,
|
|
70526
71353
|
monthlyEfficiencyByLineId,
|
|
70527
71354
|
supervisorsByLineId,
|
|
70528
71355
|
supervisorNamesByLineId,
|
|
@@ -70555,13 +71382,23 @@ var AnimatedEfficiency = React144.memo(({ value }) => {
|
|
|
70555
71382
|
AnimatedEfficiency.displayName = "AnimatedEfficiency";
|
|
70556
71383
|
var getWorkspaceLeaderboardMetricValue = (workspace) => {
|
|
70557
71384
|
if (workspace.leaderboard_metric_kind === "recent_flow_shift_average") {
|
|
70558
|
-
|
|
71385
|
+
const cycleRatio = getCycleRatio(workspace);
|
|
71386
|
+
return cycleRatio === null ? null : cycleRatio * 100;
|
|
70559
71387
|
}
|
|
70560
71388
|
return toFiniteNumber(workspace.leaderboard_value) ?? toFiniteNumber(workspace.efficiency);
|
|
70561
71389
|
};
|
|
70562
71390
|
var getWorkspaceDisplayedMetricValue = (workspace) => getWorkspaceLeaderboardMetricValue(workspace);
|
|
70563
|
-
var getWorkspaceLeaderboardMetricLabel = (workspace, defaultLabel) => workspace.leaderboard_metric_kind === "recent_flow_shift_average" ? "
|
|
71391
|
+
var getWorkspaceLeaderboardMetricLabel = (workspace, defaultLabel) => workspace.leaderboard_metric_kind === "recent_flow_shift_average" ? "Actual CT / Standard CT" : defaultLabel;
|
|
70564
71392
|
var renderWorkspaceLeaderboardMetric = (workspace) => {
|
|
71393
|
+
if (workspace.leaderboard_metric_kind === "recent_flow_shift_average") {
|
|
71394
|
+
const actualCT = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
71395
|
+
const standardCT = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
71396
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums", children: [
|
|
71397
|
+
actualCT,
|
|
71398
|
+
" / ",
|
|
71399
|
+
standardCT
|
|
71400
|
+
] });
|
|
71401
|
+
}
|
|
70565
71402
|
const displayedMetricValue = getWorkspaceDisplayedMetricValue(workspace);
|
|
70566
71403
|
if (displayedMetricValue === null) {
|
|
70567
71404
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums", children: "--" });
|
|
@@ -70839,12 +71676,8 @@ var LeaderboardDetailView = React144.memo(({
|
|
|
70839
71676
|
return `Line ${lineId2.substring(0, 8)}`;
|
|
70840
71677
|
}, [dbLineNames, configuredLineNames, lineNames, line1Id, line2Id]);
|
|
70841
71678
|
const configuredLineIds = React144.useMemo(() => {
|
|
70842
|
-
|
|
70843
|
-
|
|
70844
|
-
return allLineIds.filter((id3) => userAccessibleLineIds.includes(id3));
|
|
70845
|
-
}
|
|
70846
|
-
return allLineIds;
|
|
70847
|
-
}, [entityConfig, userAccessibleLineIds]);
|
|
71679
|
+
return getConfiguredLineIds(entityConfig);
|
|
71680
|
+
}, [entityConfig]);
|
|
70848
71681
|
const accessibleLineIdSet = React144.useMemo(
|
|
70849
71682
|
() => new Set((userAccessibleLineIds || []).filter(Boolean)),
|
|
70850
71683
|
[userAccessibleLineIds]
|
|
@@ -71532,7 +72365,7 @@ var LeaderboardDetailView = React144.memo(({
|
|
|
71532
72365
|
const hasEfficiencyLeaderboardRows = sortedWorkspaces.some(
|
|
71533
72366
|
(workspace) => workspace.leaderboard_metric_kind !== "recent_flow_shift_average"
|
|
71534
72367
|
);
|
|
71535
|
-
const metricLabel = viewType === "machine" ? "Utilization" : hasRecentFlowLeaderboardRows && !hasEfficiencyLeaderboardRows ? "
|
|
72368
|
+
const metricLabel = viewType === "machine" ? "Utilization" : hasRecentFlowLeaderboardRows && !hasEfficiencyLeaderboardRows ? "Actual CT / Standard CT" : hasRecentFlowLeaderboardRows && hasEfficiencyLeaderboardRows ? "Performance" : "Efficiency";
|
|
71536
72369
|
const descendingSortLabel = "Highest to Lowest";
|
|
71537
72370
|
const ascendingSortLabel = "Lowest to Highest";
|
|
71538
72371
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `min-h-screen bg-slate-50 flex flex-col ${className}`, style: { willChange: "contents" }, children: [
|
|
@@ -86453,6 +87286,7 @@ exports.awardsService = awardsService;
|
|
|
86453
87286
|
exports.buildDateKey = buildDateKey;
|
|
86454
87287
|
exports.buildKPIsFromLineMetricsRow = buildKPIsFromLineMetricsRow;
|
|
86455
87288
|
exports.buildKpiLineHierarchy = buildKpiLineHierarchy;
|
|
87289
|
+
exports.buildLineLeaderboardRows = buildLineLeaderboardRows;
|
|
86456
87290
|
exports.buildLineSkuBreakdown = buildLineSkuBreakdown;
|
|
86457
87291
|
exports.buildShiftGroupsKey = buildShiftGroupsKey;
|
|
86458
87292
|
exports.canRoleAccessDashboardPath = canRoleAccessDashboardPath;
|