@optifye/dashboard-core 6.12.42 → 6.12.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -2771,6 +2771,11 @@ interface UseDashboardMetricsProps {
2771
2771
  * Visible workspace and KPI payloads remain scoped to `lineIds`.
2772
2772
  */
2773
2773
  blueComparisonLineIds?: string[];
2774
+ /**
2775
+ * Optional complete line set used only to hydrate line-selector signal dots.
2776
+ * Visible workspace and KPI payloads remain scoped to `lineIds`.
2777
+ */
2778
+ selectorLineIds?: string[];
2774
2779
  /**
2775
2780
  * Optional callback invoked when underlying line metrics data might have changed,
2776
2781
  * suggesting that related components (like a Line KPI display) might need to refresh.
@@ -2832,10 +2837,11 @@ interface DashboardMetricsMetadata {
2832
2837
  * }
2833
2838
  * ```
2834
2839
  */
2835
- declare const useDashboardMetrics: ({ onLineMetricsUpdate, lineId, lineIds, blueComparisonLineIds, userAccessibleLineIds, enabled, }: UseDashboardMetricsProps) => {
2840
+ declare const useDashboardMetrics: ({ onLineMetricsUpdate, lineId, lineIds, blueComparisonLineIds, selectorLineIds, userAccessibleLineIds, enabled, }: UseDashboardMetricsProps) => {
2836
2841
  workspaceMetrics: WorkspaceMetrics[];
2837
2842
  blueComparisonWorkspaceMetrics: WorkspaceMetrics[];
2838
2843
  lineMetrics: OverviewLineMetric[];
2844
+ selectorLineMetrics: OverviewLineMetric[];
2839
2845
  efficiencyLegend: EfficiencyLegendUpdate;
2840
2846
  metadata: DashboardMetricsMetadata | undefined;
2841
2847
  isLoading: boolean;
package/dist/index.d.ts CHANGED
@@ -2771,6 +2771,11 @@ interface UseDashboardMetricsProps {
2771
2771
  * Visible workspace and KPI payloads remain scoped to `lineIds`.
2772
2772
  */
2773
2773
  blueComparisonLineIds?: string[];
2774
+ /**
2775
+ * Optional complete line set used only to hydrate line-selector signal dots.
2776
+ * Visible workspace and KPI payloads remain scoped to `lineIds`.
2777
+ */
2778
+ selectorLineIds?: string[];
2774
2779
  /**
2775
2780
  * Optional callback invoked when underlying line metrics data might have changed,
2776
2781
  * suggesting that related components (like a Line KPI display) might need to refresh.
@@ -2832,10 +2837,11 @@ interface DashboardMetricsMetadata {
2832
2837
  * }
2833
2838
  * ```
2834
2839
  */
2835
- declare const useDashboardMetrics: ({ onLineMetricsUpdate, lineId, lineIds, blueComparisonLineIds, userAccessibleLineIds, enabled, }: UseDashboardMetricsProps) => {
2840
+ declare const useDashboardMetrics: ({ onLineMetricsUpdate, lineId, lineIds, blueComparisonLineIds, selectorLineIds, userAccessibleLineIds, enabled, }: UseDashboardMetricsProps) => {
2836
2841
  workspaceMetrics: WorkspaceMetrics[];
2837
2842
  blueComparisonWorkspaceMetrics: WorkspaceMetrics[];
2838
2843
  lineMetrics: OverviewLineMetric[];
2844
+ selectorLineMetrics: OverviewLineMetric[];
2839
2845
  efficiencyLegend: EfficiencyLegendUpdate;
2840
2846
  metadata: DashboardMetricsMetadata | undefined;
2841
2847
  isLoading: boolean;
package/dist/index.js CHANGED
@@ -14926,12 +14926,14 @@ var logDebug = (...args) => {
14926
14926
  if (!DEBUG_DASHBOARD_LOGS) return;
14927
14927
  console.log(...args);
14928
14928
  };
14929
- var buildMetricsScopeKey = (lineId, lineIds, blueComparisonLineIds) => {
14929
+ var buildMetricsScopeKey = (lineId, lineIds, blueComparisonLineIds, selectorLineIds) => {
14930
14930
  const normalizedLineIds = Array.from(new Set((lineIds || []).filter(Boolean))).sort();
14931
14931
  const normalizedBlueComparisonLineIds = Array.from(new Set((blueComparisonLineIds || []).filter(Boolean))).sort();
14932
+ const normalizedSelectorLineIds = Array.from(new Set((selectorLineIds || []).filter(Boolean))).sort();
14932
14933
  const lineKey = normalizedLineIds.length > 0 ? normalizedLineIds.join(",") : lineId;
14933
14934
  const comparisonKey = normalizedBlueComparisonLineIds.length > 0 ? normalizedBlueComparisonLineIds.join(",") : lineKey;
14934
- return `${lineId}|${lineKey}|blue:${comparisonKey}`;
14935
+ const selectorKey = normalizedSelectorLineIds.length > 0 ? normalizedSelectorLineIds.join(",") : "";
14936
+ return `${lineId}|${lineKey}|blue:${comparisonKey}|selector:${selectorKey}`;
14935
14937
  };
14936
14938
  var parseEfficiencyLegend = (legend) => {
14937
14939
  if (!legend) return null;
@@ -14954,6 +14956,7 @@ var useDashboardMetrics = ({
14954
14956
  lineId,
14955
14957
  lineIds,
14956
14958
  blueComparisonLineIds,
14959
+ selectorLineIds,
14957
14960
  userAccessibleLineIds,
14958
14961
  enabled = true
14959
14962
  }) => {
@@ -14980,6 +14983,10 @@ var useDashboardMetrics = ({
14980
14983
  () => Array.from(new Set((blueComparisonLineIds || []).filter(Boolean))),
14981
14984
  [blueComparisonLineIds]
14982
14985
  );
14986
+ const normalizedSelectorLineIds = React147.useMemo(
14987
+ () => Array.from(new Set((selectorLineIds || []).filter(Boolean))),
14988
+ [selectorLineIds]
14989
+ );
14983
14990
  const { shiftConfig: staticShiftConfig } = useDashboardConfig();
14984
14991
  const {
14985
14992
  shiftConfigMap: multiLineShiftConfigMap,
@@ -15015,9 +15022,9 @@ var useDashboardMetrics = ({
15015
15022
  const configuredLineMetricsTable = databaseConfig?.tables?.lineMetrics ?? "line_metrics";
15016
15023
  const schema = databaseConfig?.schema ?? "public";
15017
15024
  const supabase = useSupabase();
15018
- const [metrics2, setMetrics] = React147.useState({ workspaceMetrics: [], lineMetrics: [] });
15025
+ const [metrics2, setMetrics] = React147.useState({ workspaceMetrics: [], lineMetrics: [], selectorLineMetrics: [] });
15019
15026
  const [metricsLineId, setMetricsLineId] = React147.useState(lineId ?? null);
15020
- const [metricsScopeKey, setMetricsScopeKey] = React147.useState(() => buildMetricsScopeKey(lineId, lineIds, blueComparisonLineIds));
15027
+ const [metricsScopeKey, setMetricsScopeKey] = React147.useState(() => buildMetricsScopeKey(lineId, lineIds, blueComparisonLineIds, selectorLineIds));
15021
15028
  const [isLoading, setIsLoading] = React147.useState(true);
15022
15029
  const [error, setError] = React147.useState(null);
15023
15030
  const lineIdRef = React147.useRef(lineId);
@@ -15036,6 +15043,7 @@ var useDashboardMetrics = ({
15036
15043
  const configuredLineIdsRef = React147.useRef(configuredLineIds);
15037
15044
  const userAccessibleLineIdsRef = React147.useRef(userAccessibleLineIds);
15038
15045
  const explicitLineIdsRef = React147.useRef(lineIds);
15046
+ const selectorLineIdsRef = React147.useRef(selectorLineIds);
15039
15047
  React147.useEffect(() => {
15040
15048
  onLineMetricsUpdateRef.current = onLineMetricsUpdate;
15041
15049
  }, [onLineMetricsUpdate]);
@@ -15054,6 +15062,9 @@ var useDashboardMetrics = ({
15054
15062
  React147.useEffect(() => {
15055
15063
  explicitLineIdsRef.current = lineIds;
15056
15064
  }, [lineIds]);
15065
+ React147.useEffect(() => {
15066
+ selectorLineIdsRef.current = selectorLineIds;
15067
+ }, [selectorLineIds]);
15057
15068
  const companySpecificMetricsTable = React147.useMemo(
15058
15069
  () => getCompanyMetricsTableName(entityConfig.companyId, "performance_metrics"),
15059
15070
  [entityConfig.companyId]
@@ -15062,9 +15073,10 @@ var useDashboardMetrics = ({
15062
15073
  () => buildMetricsScopeKey(
15063
15074
  lineId,
15064
15075
  isFactoryView ? targetFactoryLineIds : void 0,
15065
- normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0
15076
+ normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0,
15077
+ normalizedSelectorLineIds.length ? normalizedSelectorLineIds : void 0
15066
15078
  ),
15067
- [isFactoryView, lineId, targetFactoryLineIds, normalizedBlueComparisonLineIds]
15079
+ [isFactoryView, lineId, targetFactoryLineIds, normalizedBlueComparisonLineIds, normalizedSelectorLineIds]
15068
15080
  );
15069
15081
  React147.useEffect(() => {
15070
15082
  lineIdRef.current = lineId;
@@ -15096,13 +15108,15 @@ var useDashboardMetrics = ({
15096
15108
  const targetLineIdsKey = targetLineIds.slice().sort().join(",");
15097
15109
  const effectiveBlueComparisonLineIds = normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : targetLineIds;
15098
15110
  const blueComparisonLineIdsKey = effectiveBlueComparisonLineIds.slice().sort().join(",");
15111
+ const selectorLineIdsKey = normalizedSelectorLineIds.slice().sort().join(",");
15099
15112
  const usesShiftGroups = isFactory && shiftGroups.length > 0;
15100
15113
  const singleShiftDetails = usesShiftGroups ? null : shiftConfig ? getCurrentShift(defaultTimezone, shiftConfig) : shiftGroups.length === 1 ? { date: shiftGroups[0].date, shiftId: shiftGroups[0].shiftId } : getCurrentShift(defaultTimezone, staticShiftConfig);
15101
- 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}`;
15114
+ const fetchKey = usesShiftGroups ? `factory|${companyId || "unknown"}|${shiftGroupsKey}|blue:${blueComparisonLineIdsKey}|selector:${selectorLineIdsKey}` : isFactory ? `factory|${companyId || "unknown"}|${singleShiftDetails?.date}|${singleShiftDetails?.shiftId}|${targetLineIdsKey}|blue:${blueComparisonLineIdsKey}|selector:${selectorLineIdsKey}` : `${currentLineIdToUse}|${companyId || "unknown"}|${singleShiftDetails?.date}|${singleShiftDetails?.shiftId}|blue:${blueComparisonLineIdsKey}|selector:${selectorLineIdsKey}`;
15102
15115
  const responseScopeKey = buildMetricsScopeKey(
15103
15116
  currentLineIdToUse,
15104
15117
  isFactory ? targetLineIds : void 0,
15105
- normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0
15118
+ normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0,
15119
+ normalizedSelectorLineIds.length ? normalizedSelectorLineIds : void 0
15106
15120
  );
15107
15121
  logDebug("[useDashboardMetrics] Fetch key details:", {
15108
15122
  isFactory,
@@ -15134,6 +15148,7 @@ var useDashboardMetrics = ({
15134
15148
  workspaceMetrics: [],
15135
15149
  blueComparisonWorkspaceMetrics: [],
15136
15150
  lineMetrics: [],
15151
+ selectorLineMetrics: [],
15137
15152
  metadata: void 0,
15138
15153
  efficiencyLegend: DEFAULT_EFFICIENCY_LEGEND
15139
15154
  });
@@ -15145,6 +15160,7 @@ var useDashboardMetrics = ({
15145
15160
  let allWorkspaceMetrics = [];
15146
15161
  let allBlueComparisonWorkspaceMetrics = [];
15147
15162
  let allLineMetrics = [];
15163
+ let allSelectorLineMetrics = [];
15148
15164
  let hasFlowBuffers = false;
15149
15165
  let idleTimeVlmByLine = {};
15150
15166
  let efficiencyLegend;
@@ -15154,7 +15170,8 @@ var useDashboardMetrics = ({
15154
15170
  const buildMetricsEndpoint = (params) => {
15155
15171
  const lineIdsParam = isFactory ? `line_ids=${params.groupLineIds.join(",")}` : `line_id=${params.groupLineIds[0]}`;
15156
15172
  const blueComparisonParam = effectiveBlueComparisonLineIds.length ? `&blue_comparison_line_ids=${effectiveBlueComparisonLineIds.join(",")}` : "";
15157
- return `/api/dashboard/metrics?${lineIdsParam}${blueComparisonParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}${qaGreenStreakParams}`;
15173
+ const selectorParam = normalizedSelectorLineIds.length ? `&selector_line_ids=${encodeURIComponent(normalizedSelectorLineIds.join(","))}` : "";
15174
+ return `/api/dashboard/metrics?${lineIdsParam}${blueComparisonParam}${selectorParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}${qaGreenStreakParams}`;
15158
15175
  };
15159
15176
  if (usesShiftGroups) {
15160
15177
  logDebug("[useDashboardMetrics] Factory view shift groups fetch:", {
@@ -15210,6 +15227,9 @@ var useDashboardMetrics = ({
15210
15227
  if (result.line_metrics) {
15211
15228
  allLineMetrics.push(...result.line_metrics);
15212
15229
  }
15230
+ if (result.selector_line_metrics) {
15231
+ allSelectorLineMetrics.push(...result.selector_line_metrics);
15232
+ }
15213
15233
  });
15214
15234
  if (allBlueComparisonWorkspaceMetrics.length === 0) {
15215
15235
  allBlueComparisonWorkspaceMetrics = allWorkspaceMetrics;
@@ -15253,6 +15273,7 @@ var useDashboardMetrics = ({
15253
15273
  allWorkspaceMetrics = backendData.workspace_metrics || [];
15254
15274
  allBlueComparisonWorkspaceMetrics = backendData.blue_comparison_workspace_metrics || allWorkspaceMetrics;
15255
15275
  allLineMetrics = backendData.line_metrics || [];
15276
+ allSelectorLineMetrics = backendData.selector_line_metrics || [];
15256
15277
  hasFlowBuffers = Boolean(backendData?.metadata?.has_flow_buffers);
15257
15278
  if (backendData?.metadata?.idle_time_vlm_by_line && typeof backendData.metadata.idle_time_vlm_by_line === "object") {
15258
15279
  idleTimeVlmByLine = backendData.metadata.idle_time_vlm_by_line;
@@ -15284,6 +15305,7 @@ var useDashboardMetrics = ({
15284
15305
  workspaceMetrics: transformedWorkspaceData,
15285
15306
  blueComparisonWorkspaceMetrics: transformedBlueComparisonWorkspaceData.length ? transformedBlueComparisonWorkspaceData : transformedWorkspaceData,
15286
15307
  lineMetrics: allLineMetrics || [],
15308
+ selectorLineMetrics: allSelectorLineMetrics || [],
15287
15309
  metadata: { hasFlowBuffers, idleTimeVlmByLine },
15288
15310
  efficiencyLegend: efficiencyLegend ?? DEFAULT_EFFICIENCY_LEGEND
15289
15311
  };
@@ -15354,6 +15376,7 @@ var useDashboardMetrics = ({
15354
15376
  configuredLineIds,
15355
15377
  targetFactoryLineIds,
15356
15378
  normalizedBlueComparisonLineIds,
15379
+ normalizedSelectorLineIds,
15357
15380
  isFactoryView,
15358
15381
  multiLineShiftConfigMap,
15359
15382
  staticShiftConfig,
@@ -15470,7 +15493,8 @@ var useDashboardMetrics = ({
15470
15493
  const isFactory = lineId === (entityConfig.factoryViewId || "factory");
15471
15494
  if (isFactory && shiftGroups.length === 0) return null;
15472
15495
  const shiftGroupsKeyPart = isFactory ? shiftGroups.map((g) => `${g.date}-${g.shiftId}-${g.lineIds.join("_")}`).join("|") : operationalShiftKey;
15473
- return `${lineId}|${entityConfig.companyId}|${shiftGroupsKeyPart}`;
15496
+ const selectorLineIdsKeyPart = (selectorLineIds || []).filter(Boolean).slice().sort().join(",");
15497
+ return `${lineId}|${entityConfig.companyId}|${shiftGroupsKeyPart}|selector:${selectorLineIdsKeyPart}`;
15474
15498
  }, [
15475
15499
  enabled,
15476
15500
  supabase,
@@ -15480,7 +15504,8 @@ var useDashboardMetrics = ({
15480
15504
  shiftLoading,
15481
15505
  isTimezoneLoading,
15482
15506
  shiftGroups,
15483
- operationalShiftKey
15507
+ operationalShiftKey,
15508
+ selectorLineIds
15484
15509
  ]);
15485
15510
  React147.useEffect(() => {
15486
15511
  const currentLineIdToUse = lineIdRef.current;
@@ -15517,7 +15542,7 @@ var useDashboardMetrics = ({
15517
15542
  });
15518
15543
  const targetFactoryLineIdsForSubscriptions = explicitLineIdsRef.current !== void 0 ? explicitLineIdsRef.current : currentUserAccessibleLineIds !== void 0 ? currentUserAccessibleLineIds : currentConfiguredLineIds;
15519
15544
  const targetFactoryLineIdSet = new Set(
15520
- (targetFactoryLineIdsForSubscriptions || []).filter(Boolean)
15545
+ [...targetFactoryLineIdsForSubscriptions || [], ...selectorLineIdsRef.current || []].filter(Boolean)
15521
15546
  );
15522
15547
  currentShiftGroups.forEach((group, index) => {
15523
15548
  const groupLineIds = group.lineIds.filter(
@@ -15687,7 +15712,10 @@ var useDashboardMetrics = ({
15687
15712
  const currentShiftDetails = shiftConfig ? getCurrentShift(defaultTimezone, shiftConfig) : getCurrentShift(defaultTimezone, staticShiftConfig);
15688
15713
  const operationalDateForSubscription = currentShiftDetails.date;
15689
15714
  const targetLineIds = isFactory ? explicitLineIdsRef.current || currentUserAccessibleLineIds || currentConfiguredLineIds : [currentLineIdToUse];
15690
- const filteredLineIds = targetLineIds.filter((id3) => id3 && id3 !== factoryViewIdentifier);
15715
+ const filteredLineIds = Array.from(/* @__PURE__ */ new Set([
15716
+ ...targetLineIds,
15717
+ ...selectorLineIdsRef.current || []
15718
+ ])).filter((id3) => id3 && id3 !== factoryViewIdentifier);
15691
15719
  if (filteredLineIds.length === 0) {
15692
15720
  logDebug("[useDashboardMetrics] Realtime setup skipped: no line IDs after filtering", {
15693
15721
  targetLineIds,
@@ -15794,11 +15822,12 @@ var useDashboardMetrics = ({
15794
15822
  const isCurrentScopeResolved = metricsScopeKey === requestedScopeKey;
15795
15823
  const hasLastGoodMetrics = metrics2.workspaceMetrics.length > 0 || metrics2.lineMetrics.length > 0;
15796
15824
  const canReuseLastGoodMetrics = hasLastGoodMetrics && !isCurrentScopeResolved && (isLoading || !!error);
15797
- const safeMetrics = isCurrentScopeResolved || canReuseLastGoodMetrics ? metrics2 : { workspaceMetrics: [], blueComparisonWorkspaceMetrics: [], lineMetrics: [], metadata: void 0, efficiencyLegend: DEFAULT_EFFICIENCY_LEGEND };
15825
+ const safeMetrics = isCurrentScopeResolved || canReuseLastGoodMetrics ? metrics2 : { workspaceMetrics: [], blueComparisonWorkspaceMetrics: [], lineMetrics: [], selectorLineMetrics: [], metadata: void 0, efficiencyLegend: DEFAULT_EFFICIENCY_LEGEND };
15798
15826
  return {
15799
15827
  workspaceMetrics: safeMetrics?.workspaceMetrics || [],
15800
15828
  blueComparisonWorkspaceMetrics: safeMetrics?.blueComparisonWorkspaceMetrics || safeMetrics?.workspaceMetrics || [],
15801
15829
  lineMetrics: safeMetrics?.lineMetrics || [],
15830
+ selectorLineMetrics: safeMetrics?.selectorLineMetrics || [],
15802
15831
  efficiencyLegend: safeMetrics?.efficiencyLegend || DEFAULT_EFFICIENCY_LEGEND,
15803
15832
  metadata: safeMetrics?.metadata,
15804
15833
  isLoading: enabled ? isLoading || !isCurrentScopeResolved && !canReuseLastGoodMetrics : false,
@@ -65681,6 +65710,7 @@ var createEmptyState = () => ({
65681
65710
  workspaceMetrics: [],
65682
65711
  blueComparisonWorkspaceMetrics: [],
65683
65712
  lineMetrics: [],
65713
+ selectorLineMetrics: [],
65684
65714
  kpiTrend: null,
65685
65715
  activeBreaks: [],
65686
65716
  videoStreamsByWorkspaceId: {},
@@ -65694,7 +65724,7 @@ var normalizeMetadata = (metadata) => ({
65694
65724
  cacheStatus: metadata?.cache_status,
65695
65725
  warnings: metadata?.warnings ?? []
65696
65726
  });
65697
- var createResolvedScopeLookup = (resolvedScope, workspaces, blueComparisonWorkspaces) => {
65727
+ var createResolvedScopeLookup = (resolvedScope, workspaces, blueComparisonWorkspaces, selectorLineMetrics) => {
65698
65728
  const lookup = /* @__PURE__ */ new Set();
65699
65729
  const addEntry = (lineId, date, shiftId) => {
65700
65730
  if (!lineId || !date || shiftId === void 0 || shiftId === null) return;
@@ -65703,11 +65733,13 @@ var createResolvedScopeLookup = (resolvedScope, workspaces, blueComparisonWorksp
65703
65733
  resolvedScope.forEach((entry) => addEntry(entry.line_id, entry.date, entry.shift_id));
65704
65734
  workspaces.forEach((workspace) => addEntry(workspace.line_id, workspace.date, workspace.shift_id));
65705
65735
  blueComparisonWorkspaces.forEach((workspace) => addEntry(workspace.line_id, workspace.date, workspace.shift_id));
65736
+ selectorLineMetrics.forEach((lineMetric) => addEntry(lineMetric.line_id, lineMetric.date, lineMetric.shift_id));
65706
65737
  return lookup;
65707
65738
  };
65708
65739
  var useLiveMonitorBootstrap = ({
65709
65740
  lineIds,
65710
65741
  blueComparisonLineIds,
65742
+ selectorLineIds,
65711
65743
  companyId,
65712
65744
  enabled = true,
65713
65745
  appTimezone,
@@ -65723,6 +65755,7 @@ var useLiveMonitorBootstrap = ({
65723
65755
  const effectiveTimezone = appTimezone || "Asia/Kolkata";
65724
65756
  const rawLineIdsKey = (lineIds || []).filter(Boolean).join(",");
65725
65757
  const rawBlueComparisonLineIdsKey = (blueComparisonLineIds || lineIds || []).filter(Boolean).join(",");
65758
+ const rawSelectorLineIdsKey = (selectorLineIds || []).filter(Boolean).join(",");
65726
65759
  const normalizedLineIds = React147.useMemo(
65727
65760
  () => Array.from(new Set(rawLineIdsKey ? rawLineIdsKey.split(",") : [])),
65728
65761
  [rawLineIdsKey]
@@ -65731,13 +65764,17 @@ var useLiveMonitorBootstrap = ({
65731
65764
  () => Array.from(new Set(rawBlueComparisonLineIdsKey ? rawBlueComparisonLineIdsKey.split(",") : [])),
65732
65765
  [rawBlueComparisonLineIdsKey]
65733
65766
  );
65767
+ const normalizedSelectorLineIds = React147.useMemo(
65768
+ () => Array.from(new Set(rawSelectorLineIdsKey ? rawSelectorLineIdsKey.split(",") : [])),
65769
+ [rawSelectorLineIdsKey]
65770
+ );
65734
65771
  const realtimeLineIds = React147.useMemo(
65735
- () => Array.from(new Set([...normalizedLineIds, ...normalizedBlueComparisonLineIds].filter(Boolean))).sort(),
65736
- [normalizedLineIds, normalizedBlueComparisonLineIds]
65772
+ () => Array.from(new Set([...normalizedLineIds, ...normalizedBlueComparisonLineIds, ...normalizedSelectorLineIds].filter(Boolean))).sort(),
65773
+ [normalizedLineIds, normalizedBlueComparisonLineIds, normalizedSelectorLineIds]
65737
65774
  );
65738
65775
  const requestKey = React147.useMemo(
65739
- () => `${normalizedLineIds.slice().sort().join(",")}|blue:${normalizedBlueComparisonLineIds.slice().sort().join(",")}`,
65740
- [normalizedLineIds, normalizedBlueComparisonLineIds]
65776
+ () => `${normalizedLineIds.slice().sort().join(",")}|blue:${normalizedBlueComparisonLineIds.slice().sort().join(",")}|selector:${normalizedSelectorLineIds.slice().sort().join(",")}`,
65777
+ [normalizedLineIds, normalizedBlueComparisonLineIds, normalizedSelectorLineIds]
65741
65778
  );
65742
65779
  const realtimeLineIdsKey = React147.useMemo(() => realtimeLineIds.join(","), [realtimeLineIds]);
65743
65780
  const companySpecificMetricsTable = React147.useMemo(
@@ -65769,6 +65806,9 @@ var useLiveMonitorBootstrap = ({
65769
65806
  if (normalizedBlueComparisonLineIds.length) {
65770
65807
  searchParams.set("blue_comparison_line_ids", normalizedBlueComparisonLineIds.join(","));
65771
65808
  }
65809
+ if (normalizedSelectorLineIds.length) {
65810
+ searchParams.set("selector_line_ids", normalizedSelectorLineIds.join(","));
65811
+ }
65772
65812
  if (force) {
65773
65813
  searchParams.set("force_refresh", "true");
65774
65814
  }
@@ -65802,6 +65842,7 @@ var useLiveMonitorBootstrap = ({
65802
65842
  company_id: resolvedCompanyId,
65803
65843
  line_ids: normalizedLineIds,
65804
65844
  blue_comparison_line_ids: normalizedBlueComparisonLineIds,
65845
+ selector_line_ids: normalizedSelectorLineIds,
65805
65846
  force_refresh: force,
65806
65847
  pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
65807
65848
  }
@@ -65819,6 +65860,7 @@ var useLiveMonitorBootstrap = ({
65819
65860
  resolvedCompanyId,
65820
65861
  normalizedLineIds,
65821
65862
  normalizedBlueComparisonLineIds,
65863
+ normalizedSelectorLineIds,
65822
65864
  requestKey
65823
65865
  ]);
65824
65866
  const fetchBootstrapRef = React147.useRef(fetchBootstrap);
@@ -65930,6 +65972,7 @@ var useLiveMonitorBootstrap = ({
65930
65972
  workspaceMetrics,
65931
65973
  blueComparisonWorkspaceMetrics: blueComparisonWorkspaceMetrics.length ? blueComparisonWorkspaceMetrics : workspaceMetrics,
65932
65974
  lineMetrics: rawState.response.line_metrics || [],
65975
+ selectorLineMetrics: rawState.response.selector_line_metrics || [],
65933
65976
  kpiTrend: rawState.response.kpi_trend || null,
65934
65977
  activeBreaks,
65935
65978
  videoStreamsByWorkspaceId,
@@ -65966,8 +66009,9 @@ var useLiveMonitorBootstrap = ({
65966
66009
  const realtimeScopeKey = React147.useMemo(() => Array.from(createResolvedScopeLookup(
65967
66010
  state.resolvedScope,
65968
66011
  state.workspaceMetrics,
65969
- state.blueComparisonWorkspaceMetrics
65970
- )).sort().join("||"), [state.resolvedScope, state.workspaceMetrics, state.blueComparisonWorkspaceMetrics]);
66012
+ state.blueComparisonWorkspaceMetrics,
66013
+ state.selectorLineMetrics
66014
+ )).sort().join("||"), [state.resolvedScope, state.workspaceMetrics, state.blueComparisonWorkspaceMetrics, state.selectorLineMetrics]);
65971
66015
  React147.useEffect(() => {
65972
66016
  if (!enabled || !resolvedCompanyId || !realtimeLineIdsKey || !supabase) {
65973
66017
  return void 0;
@@ -66073,6 +66117,7 @@ var useLiveMonitorBootstrap = ({
66073
66117
  workspaceMetrics: state.workspaceMetrics,
66074
66118
  blueComparisonWorkspaceMetrics: state.blueComparisonWorkspaceMetrics,
66075
66119
  lineMetrics: state.lineMetrics,
66120
+ selectorLineMetrics: state.selectorLineMetrics,
66076
66121
  kpiTrend: state.kpiTrend,
66077
66122
  activeBreaks: state.activeBreaks,
66078
66123
  videoStreamsByWorkspaceId: state.videoStreamsByWorkspaceId,
@@ -66587,6 +66632,7 @@ function HomeView({
66587
66632
  workspaceMetrics: legacyWorkspaceMetrics,
66588
66633
  blueComparisonWorkspaceMetrics: legacyMetricsBlueComparisonWorkspaceMetrics,
66589
66634
  lineMetrics: legacyLineMetrics,
66635
+ selectorLineMetrics: legacySelectorLineMetrics = [],
66590
66636
  efficiencyLegend: legacyEfficiencyLegend,
66591
66637
  metadata: legacyMetricsMetadata,
66592
66638
  isLoading: legacyMetricsLoading,
@@ -66597,6 +66643,7 @@ function HomeView({
66597
66643
  lineId: metricsScopeLineId,
66598
66644
  lineIds: selectedLineIds,
66599
66645
  blueComparisonLineIds,
66646
+ selectorLineIds: visibleLineIds,
66600
66647
  onLineMetricsUpdate: handleLineMetricsUpdate,
66601
66648
  userAccessibleLineIds: visibleLineIds,
66602
66649
  enabled: shouldEnableMetricsFetch && !isBootstrapMonitorMode
@@ -66652,6 +66699,7 @@ function HomeView({
66652
66699
  const bootstrapMonitor = useLiveMonitorBootstrap({
66653
66700
  lineIds: selectedLineIds,
66654
66701
  blueComparisonLineIds,
66702
+ selectorLineIds: visibleLineIds,
66655
66703
  companyId: userCompanyId,
66656
66704
  enabled: shouldEnableMetricsFetch && !isLegacyMonitorMode,
66657
66705
  appTimezone: timezone,
@@ -66662,12 +66710,32 @@ function HomeView({
66662
66710
  const currentWorkspaceMetrics = isBootstrapMonitorMode ? bootstrapMonitor.workspaceMetrics : legacyWorkspaceMetrics;
66663
66711
  const currentBlueComparisonWorkspaceMetrics = isBootstrapMonitorMode ? bootstrapMonitor.blueComparisonWorkspaceMetrics : legacyMetricsBlueComparisonWorkspaceMetrics;
66664
66712
  const currentLineMetrics = isBootstrapMonitorMode ? bootstrapMonitor.lineMetrics : legacyLineMetrics;
66713
+ const currentSelectorLineMetrics = isBootstrapMonitorMode ? bootstrapMonitor.selectorLineMetrics : legacySelectorLineMetrics;
66665
66714
  const currentEfficiencyLegend = isBootstrapMonitorMode ? bootstrapMonitor.efficiencyLegend : legacyEfficiencyLegend;
66666
66715
  const currentMetricsMetadata = isBootstrapMonitorMode ? bootstrapMonitor.metadata : legacyMetricsMetadata;
66667
66716
  const currentMetricsLoading = isBootstrapMonitorMode ? bootstrapMonitor.isLoading : legacyMetricsLoading;
66668
66717
  const currentIsCurrentScopeResolved = isBootstrapMonitorMode ? bootstrapMonitor.isCurrentScopeResolved : legacyIsCurrentScopeResolved;
66669
66718
  const currentMetricsError = isBootstrapMonitorMode ? bootstrapMonitor.error : legacyMetricsError;
66670
66719
  const currentRefetchMetrics = isBootstrapMonitorMode ? bootstrapMonitor.refetch : refetchLegacyMetrics;
66720
+ const lineSelectorSignalStatusByLine = React147.useMemo(() => {
66721
+ const statusByLine = /* @__PURE__ */ new Map();
66722
+ const legend = currentEfficiencyLegend || DEFAULT_EFFICIENCY_LEGEND;
66723
+ const addRows = (rows) => {
66724
+ (rows || []).forEach((row) => {
66725
+ const lineId = typeof row?.line_id === "string" ? row.line_id : "";
66726
+ if (!lineId || statusByLine.has(lineId)) {
66727
+ return;
66728
+ }
66729
+ const status = getKpiSignalStatus(row?.line_signal, legend);
66730
+ if (status) {
66731
+ statusByLine.set(lineId, status);
66732
+ }
66733
+ });
66734
+ };
66735
+ addRows(currentSelectorLineMetrics);
66736
+ addRows(currentLineMetrics);
66737
+ return statusByLine;
66738
+ }, [currentEfficiencyLegend, currentLineMetrics, currentSelectorLineMetrics]);
66671
66739
  const metricsDisplayNames = React147.useMemo(() => {
66672
66740
  const nextDisplayNames = {};
66673
66741
  currentWorkspaceMetrics.forEach((workspace) => {
@@ -67525,6 +67593,8 @@ function HomeView({
67525
67593
  ] }),
67526
67594
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-56 space-y-0.5 overflow-y-auto pr-1", children: visibleLineIds.map((lineId) => {
67527
67595
  const isChecked = pendingSelectedLineIds.includes(lineId);
67596
+ const signalStatus = lineSelectorSignalStatusByLine.get(lineId);
67597
+ const signalDotClass = signalStatus === "stable" ? "bg-green-500" : signalStatus === "warning" ? "bg-yellow-400" : signalStatus === "attention" ? "bg-red-500" : "";
67528
67598
  return /* @__PURE__ */ jsxRuntime.jsxs(
67529
67599
  "label",
67530
67600
  {
@@ -67549,7 +67619,15 @@ function HomeView({
67549
67619
  }
67550
67620
  }
67551
67621
  ),
67552
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: mergedLineNames[lineId] || `Line ${lineId.substring(0, 4)}` })
67622
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: mergedLineNames[lineId] || `Line ${lineId.substring(0, 4)}` }),
67623
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-2.5 w-2.5 flex-shrink-0 items-center justify-center", children: signalStatus ? /* @__PURE__ */ jsxRuntime.jsx(
67624
+ "span",
67625
+ {
67626
+ "data-testid": `line-selector-signal-dot-${lineId}`,
67627
+ className: `h-2 w-2 rounded-full ${signalDotClass}`,
67628
+ "aria-hidden": "true"
67629
+ }
67630
+ ) : null })
67553
67631
  ]
67554
67632
  },
67555
67633
  lineId
@@ -67578,6 +67656,7 @@ function HomeView({
67578
67656
  mergedLineNames,
67579
67657
  selectedLineIds,
67580
67658
  pendingSelectedLineIds,
67659
+ lineSelectorSignalStatusByLine,
67581
67660
  visibleLineIds,
67582
67661
  updateSelectedLineIds,
67583
67662
  isAllLinesSelection
package/dist/index.mjs CHANGED
@@ -14897,12 +14897,14 @@ var logDebug = (...args) => {
14897
14897
  if (!DEBUG_DASHBOARD_LOGS) return;
14898
14898
  console.log(...args);
14899
14899
  };
14900
- var buildMetricsScopeKey = (lineId, lineIds, blueComparisonLineIds) => {
14900
+ var buildMetricsScopeKey = (lineId, lineIds, blueComparisonLineIds, selectorLineIds) => {
14901
14901
  const normalizedLineIds = Array.from(new Set((lineIds || []).filter(Boolean))).sort();
14902
14902
  const normalizedBlueComparisonLineIds = Array.from(new Set((blueComparisonLineIds || []).filter(Boolean))).sort();
14903
+ const normalizedSelectorLineIds = Array.from(new Set((selectorLineIds || []).filter(Boolean))).sort();
14903
14904
  const lineKey = normalizedLineIds.length > 0 ? normalizedLineIds.join(",") : lineId;
14904
14905
  const comparisonKey = normalizedBlueComparisonLineIds.length > 0 ? normalizedBlueComparisonLineIds.join(",") : lineKey;
14905
- return `${lineId}|${lineKey}|blue:${comparisonKey}`;
14906
+ const selectorKey = normalizedSelectorLineIds.length > 0 ? normalizedSelectorLineIds.join(",") : "";
14907
+ return `${lineId}|${lineKey}|blue:${comparisonKey}|selector:${selectorKey}`;
14906
14908
  };
14907
14909
  var parseEfficiencyLegend = (legend) => {
14908
14910
  if (!legend) return null;
@@ -14925,6 +14927,7 @@ var useDashboardMetrics = ({
14925
14927
  lineId,
14926
14928
  lineIds,
14927
14929
  blueComparisonLineIds,
14930
+ selectorLineIds,
14928
14931
  userAccessibleLineIds,
14929
14932
  enabled = true
14930
14933
  }) => {
@@ -14951,6 +14954,10 @@ var useDashboardMetrics = ({
14951
14954
  () => Array.from(new Set((blueComparisonLineIds || []).filter(Boolean))),
14952
14955
  [blueComparisonLineIds]
14953
14956
  );
14957
+ const normalizedSelectorLineIds = useMemo(
14958
+ () => Array.from(new Set((selectorLineIds || []).filter(Boolean))),
14959
+ [selectorLineIds]
14960
+ );
14954
14961
  const { shiftConfig: staticShiftConfig } = useDashboardConfig();
14955
14962
  const {
14956
14963
  shiftConfigMap: multiLineShiftConfigMap,
@@ -14986,9 +14993,9 @@ var useDashboardMetrics = ({
14986
14993
  const configuredLineMetricsTable = databaseConfig?.tables?.lineMetrics ?? "line_metrics";
14987
14994
  const schema = databaseConfig?.schema ?? "public";
14988
14995
  const supabase = useSupabase();
14989
- const [metrics2, setMetrics] = useState({ workspaceMetrics: [], lineMetrics: [] });
14996
+ const [metrics2, setMetrics] = useState({ workspaceMetrics: [], lineMetrics: [], selectorLineMetrics: [] });
14990
14997
  const [metricsLineId, setMetricsLineId] = useState(lineId ?? null);
14991
- const [metricsScopeKey, setMetricsScopeKey] = useState(() => buildMetricsScopeKey(lineId, lineIds, blueComparisonLineIds));
14998
+ const [metricsScopeKey, setMetricsScopeKey] = useState(() => buildMetricsScopeKey(lineId, lineIds, blueComparisonLineIds, selectorLineIds));
14992
14999
  const [isLoading, setIsLoading] = useState(true);
14993
15000
  const [error, setError] = useState(null);
14994
15001
  const lineIdRef = useRef(lineId);
@@ -15007,6 +15014,7 @@ var useDashboardMetrics = ({
15007
15014
  const configuredLineIdsRef = useRef(configuredLineIds);
15008
15015
  const userAccessibleLineIdsRef = useRef(userAccessibleLineIds);
15009
15016
  const explicitLineIdsRef = useRef(lineIds);
15017
+ const selectorLineIdsRef = useRef(selectorLineIds);
15010
15018
  useEffect(() => {
15011
15019
  onLineMetricsUpdateRef.current = onLineMetricsUpdate;
15012
15020
  }, [onLineMetricsUpdate]);
@@ -15025,6 +15033,9 @@ var useDashboardMetrics = ({
15025
15033
  useEffect(() => {
15026
15034
  explicitLineIdsRef.current = lineIds;
15027
15035
  }, [lineIds]);
15036
+ useEffect(() => {
15037
+ selectorLineIdsRef.current = selectorLineIds;
15038
+ }, [selectorLineIds]);
15028
15039
  const companySpecificMetricsTable = useMemo(
15029
15040
  () => getCompanyMetricsTableName(entityConfig.companyId, "performance_metrics"),
15030
15041
  [entityConfig.companyId]
@@ -15033,9 +15044,10 @@ var useDashboardMetrics = ({
15033
15044
  () => buildMetricsScopeKey(
15034
15045
  lineId,
15035
15046
  isFactoryView ? targetFactoryLineIds : void 0,
15036
- normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0
15047
+ normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0,
15048
+ normalizedSelectorLineIds.length ? normalizedSelectorLineIds : void 0
15037
15049
  ),
15038
- [isFactoryView, lineId, targetFactoryLineIds, normalizedBlueComparisonLineIds]
15050
+ [isFactoryView, lineId, targetFactoryLineIds, normalizedBlueComparisonLineIds, normalizedSelectorLineIds]
15039
15051
  );
15040
15052
  useEffect(() => {
15041
15053
  lineIdRef.current = lineId;
@@ -15067,13 +15079,15 @@ var useDashboardMetrics = ({
15067
15079
  const targetLineIdsKey = targetLineIds.slice().sort().join(",");
15068
15080
  const effectiveBlueComparisonLineIds = normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : targetLineIds;
15069
15081
  const blueComparisonLineIdsKey = effectiveBlueComparisonLineIds.slice().sort().join(",");
15082
+ const selectorLineIdsKey = normalizedSelectorLineIds.slice().sort().join(",");
15070
15083
  const usesShiftGroups = isFactory && shiftGroups.length > 0;
15071
15084
  const singleShiftDetails = usesShiftGroups ? null : shiftConfig ? getCurrentShift(defaultTimezone, shiftConfig) : shiftGroups.length === 1 ? { date: shiftGroups[0].date, shiftId: shiftGroups[0].shiftId } : getCurrentShift(defaultTimezone, staticShiftConfig);
15072
- 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}`;
15085
+ const fetchKey = usesShiftGroups ? `factory|${companyId || "unknown"}|${shiftGroupsKey}|blue:${blueComparisonLineIdsKey}|selector:${selectorLineIdsKey}` : isFactory ? `factory|${companyId || "unknown"}|${singleShiftDetails?.date}|${singleShiftDetails?.shiftId}|${targetLineIdsKey}|blue:${blueComparisonLineIdsKey}|selector:${selectorLineIdsKey}` : `${currentLineIdToUse}|${companyId || "unknown"}|${singleShiftDetails?.date}|${singleShiftDetails?.shiftId}|blue:${blueComparisonLineIdsKey}|selector:${selectorLineIdsKey}`;
15073
15086
  const responseScopeKey = buildMetricsScopeKey(
15074
15087
  currentLineIdToUse,
15075
15088
  isFactory ? targetLineIds : void 0,
15076
- normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0
15089
+ normalizedBlueComparisonLineIds.length ? normalizedBlueComparisonLineIds : void 0,
15090
+ normalizedSelectorLineIds.length ? normalizedSelectorLineIds : void 0
15077
15091
  );
15078
15092
  logDebug("[useDashboardMetrics] Fetch key details:", {
15079
15093
  isFactory,
@@ -15105,6 +15119,7 @@ var useDashboardMetrics = ({
15105
15119
  workspaceMetrics: [],
15106
15120
  blueComparisonWorkspaceMetrics: [],
15107
15121
  lineMetrics: [],
15122
+ selectorLineMetrics: [],
15108
15123
  metadata: void 0,
15109
15124
  efficiencyLegend: DEFAULT_EFFICIENCY_LEGEND
15110
15125
  });
@@ -15116,6 +15131,7 @@ var useDashboardMetrics = ({
15116
15131
  let allWorkspaceMetrics = [];
15117
15132
  let allBlueComparisonWorkspaceMetrics = [];
15118
15133
  let allLineMetrics = [];
15134
+ let allSelectorLineMetrics = [];
15119
15135
  let hasFlowBuffers = false;
15120
15136
  let idleTimeVlmByLine = {};
15121
15137
  let efficiencyLegend;
@@ -15125,7 +15141,8 @@ var useDashboardMetrics = ({
15125
15141
  const buildMetricsEndpoint = (params) => {
15126
15142
  const lineIdsParam = isFactory ? `line_ids=${params.groupLineIds.join(",")}` : `line_id=${params.groupLineIds[0]}`;
15127
15143
  const blueComparisonParam = effectiveBlueComparisonLineIds.length ? `&blue_comparison_line_ids=${effectiveBlueComparisonLineIds.join(",")}` : "";
15128
- return `/api/dashboard/metrics?${lineIdsParam}${blueComparisonParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}${qaGreenStreakParams}`;
15144
+ const selectorParam = normalizedSelectorLineIds.length ? `&selector_line_ids=${encodeURIComponent(normalizedSelectorLineIds.join(","))}` : "";
15145
+ return `/api/dashboard/metrics?${lineIdsParam}${blueComparisonParam}${selectorParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}${qaGreenStreakParams}`;
15129
15146
  };
15130
15147
  if (usesShiftGroups) {
15131
15148
  logDebug("[useDashboardMetrics] Factory view shift groups fetch:", {
@@ -15181,6 +15198,9 @@ var useDashboardMetrics = ({
15181
15198
  if (result.line_metrics) {
15182
15199
  allLineMetrics.push(...result.line_metrics);
15183
15200
  }
15201
+ if (result.selector_line_metrics) {
15202
+ allSelectorLineMetrics.push(...result.selector_line_metrics);
15203
+ }
15184
15204
  });
15185
15205
  if (allBlueComparisonWorkspaceMetrics.length === 0) {
15186
15206
  allBlueComparisonWorkspaceMetrics = allWorkspaceMetrics;
@@ -15224,6 +15244,7 @@ var useDashboardMetrics = ({
15224
15244
  allWorkspaceMetrics = backendData.workspace_metrics || [];
15225
15245
  allBlueComparisonWorkspaceMetrics = backendData.blue_comparison_workspace_metrics || allWorkspaceMetrics;
15226
15246
  allLineMetrics = backendData.line_metrics || [];
15247
+ allSelectorLineMetrics = backendData.selector_line_metrics || [];
15227
15248
  hasFlowBuffers = Boolean(backendData?.metadata?.has_flow_buffers);
15228
15249
  if (backendData?.metadata?.idle_time_vlm_by_line && typeof backendData.metadata.idle_time_vlm_by_line === "object") {
15229
15250
  idleTimeVlmByLine = backendData.metadata.idle_time_vlm_by_line;
@@ -15255,6 +15276,7 @@ var useDashboardMetrics = ({
15255
15276
  workspaceMetrics: transformedWorkspaceData,
15256
15277
  blueComparisonWorkspaceMetrics: transformedBlueComparisonWorkspaceData.length ? transformedBlueComparisonWorkspaceData : transformedWorkspaceData,
15257
15278
  lineMetrics: allLineMetrics || [],
15279
+ selectorLineMetrics: allSelectorLineMetrics || [],
15258
15280
  metadata: { hasFlowBuffers, idleTimeVlmByLine },
15259
15281
  efficiencyLegend: efficiencyLegend ?? DEFAULT_EFFICIENCY_LEGEND
15260
15282
  };
@@ -15325,6 +15347,7 @@ var useDashboardMetrics = ({
15325
15347
  configuredLineIds,
15326
15348
  targetFactoryLineIds,
15327
15349
  normalizedBlueComparisonLineIds,
15350
+ normalizedSelectorLineIds,
15328
15351
  isFactoryView,
15329
15352
  multiLineShiftConfigMap,
15330
15353
  staticShiftConfig,
@@ -15441,7 +15464,8 @@ var useDashboardMetrics = ({
15441
15464
  const isFactory = lineId === (entityConfig.factoryViewId || "factory");
15442
15465
  if (isFactory && shiftGroups.length === 0) return null;
15443
15466
  const shiftGroupsKeyPart = isFactory ? shiftGroups.map((g) => `${g.date}-${g.shiftId}-${g.lineIds.join("_")}`).join("|") : operationalShiftKey;
15444
- return `${lineId}|${entityConfig.companyId}|${shiftGroupsKeyPart}`;
15467
+ const selectorLineIdsKeyPart = (selectorLineIds || []).filter(Boolean).slice().sort().join(",");
15468
+ return `${lineId}|${entityConfig.companyId}|${shiftGroupsKeyPart}|selector:${selectorLineIdsKeyPart}`;
15445
15469
  }, [
15446
15470
  enabled,
15447
15471
  supabase,
@@ -15451,7 +15475,8 @@ var useDashboardMetrics = ({
15451
15475
  shiftLoading,
15452
15476
  isTimezoneLoading,
15453
15477
  shiftGroups,
15454
- operationalShiftKey
15478
+ operationalShiftKey,
15479
+ selectorLineIds
15455
15480
  ]);
15456
15481
  useEffect(() => {
15457
15482
  const currentLineIdToUse = lineIdRef.current;
@@ -15488,7 +15513,7 @@ var useDashboardMetrics = ({
15488
15513
  });
15489
15514
  const targetFactoryLineIdsForSubscriptions = explicitLineIdsRef.current !== void 0 ? explicitLineIdsRef.current : currentUserAccessibleLineIds !== void 0 ? currentUserAccessibleLineIds : currentConfiguredLineIds;
15490
15515
  const targetFactoryLineIdSet = new Set(
15491
- (targetFactoryLineIdsForSubscriptions || []).filter(Boolean)
15516
+ [...targetFactoryLineIdsForSubscriptions || [], ...selectorLineIdsRef.current || []].filter(Boolean)
15492
15517
  );
15493
15518
  currentShiftGroups.forEach((group, index) => {
15494
15519
  const groupLineIds = group.lineIds.filter(
@@ -15658,7 +15683,10 @@ var useDashboardMetrics = ({
15658
15683
  const currentShiftDetails = shiftConfig ? getCurrentShift(defaultTimezone, shiftConfig) : getCurrentShift(defaultTimezone, staticShiftConfig);
15659
15684
  const operationalDateForSubscription = currentShiftDetails.date;
15660
15685
  const targetLineIds = isFactory ? explicitLineIdsRef.current || currentUserAccessibleLineIds || currentConfiguredLineIds : [currentLineIdToUse];
15661
- const filteredLineIds = targetLineIds.filter((id3) => id3 && id3 !== factoryViewIdentifier);
15686
+ const filteredLineIds = Array.from(/* @__PURE__ */ new Set([
15687
+ ...targetLineIds,
15688
+ ...selectorLineIdsRef.current || []
15689
+ ])).filter((id3) => id3 && id3 !== factoryViewIdentifier);
15662
15690
  if (filteredLineIds.length === 0) {
15663
15691
  logDebug("[useDashboardMetrics] Realtime setup skipped: no line IDs after filtering", {
15664
15692
  targetLineIds,
@@ -15765,11 +15793,12 @@ var useDashboardMetrics = ({
15765
15793
  const isCurrentScopeResolved = metricsScopeKey === requestedScopeKey;
15766
15794
  const hasLastGoodMetrics = metrics2.workspaceMetrics.length > 0 || metrics2.lineMetrics.length > 0;
15767
15795
  const canReuseLastGoodMetrics = hasLastGoodMetrics && !isCurrentScopeResolved && (isLoading || !!error);
15768
- const safeMetrics = isCurrentScopeResolved || canReuseLastGoodMetrics ? metrics2 : { workspaceMetrics: [], blueComparisonWorkspaceMetrics: [], lineMetrics: [], metadata: void 0, efficiencyLegend: DEFAULT_EFFICIENCY_LEGEND };
15796
+ const safeMetrics = isCurrentScopeResolved || canReuseLastGoodMetrics ? metrics2 : { workspaceMetrics: [], blueComparisonWorkspaceMetrics: [], lineMetrics: [], selectorLineMetrics: [], metadata: void 0, efficiencyLegend: DEFAULT_EFFICIENCY_LEGEND };
15769
15797
  return {
15770
15798
  workspaceMetrics: safeMetrics?.workspaceMetrics || [],
15771
15799
  blueComparisonWorkspaceMetrics: safeMetrics?.blueComparisonWorkspaceMetrics || safeMetrics?.workspaceMetrics || [],
15772
15800
  lineMetrics: safeMetrics?.lineMetrics || [],
15801
+ selectorLineMetrics: safeMetrics?.selectorLineMetrics || [],
15773
15802
  efficiencyLegend: safeMetrics?.efficiencyLegend || DEFAULT_EFFICIENCY_LEGEND,
15774
15803
  metadata: safeMetrics?.metadata,
15775
15804
  isLoading: enabled ? isLoading || !isCurrentScopeResolved && !canReuseLastGoodMetrics : false,
@@ -65652,6 +65681,7 @@ var createEmptyState = () => ({
65652
65681
  workspaceMetrics: [],
65653
65682
  blueComparisonWorkspaceMetrics: [],
65654
65683
  lineMetrics: [],
65684
+ selectorLineMetrics: [],
65655
65685
  kpiTrend: null,
65656
65686
  activeBreaks: [],
65657
65687
  videoStreamsByWorkspaceId: {},
@@ -65665,7 +65695,7 @@ var normalizeMetadata = (metadata) => ({
65665
65695
  cacheStatus: metadata?.cache_status,
65666
65696
  warnings: metadata?.warnings ?? []
65667
65697
  });
65668
- var createResolvedScopeLookup = (resolvedScope, workspaces, blueComparisonWorkspaces) => {
65698
+ var createResolvedScopeLookup = (resolvedScope, workspaces, blueComparisonWorkspaces, selectorLineMetrics) => {
65669
65699
  const lookup = /* @__PURE__ */ new Set();
65670
65700
  const addEntry = (lineId, date, shiftId) => {
65671
65701
  if (!lineId || !date || shiftId === void 0 || shiftId === null) return;
@@ -65674,11 +65704,13 @@ var createResolvedScopeLookup = (resolvedScope, workspaces, blueComparisonWorksp
65674
65704
  resolvedScope.forEach((entry) => addEntry(entry.line_id, entry.date, entry.shift_id));
65675
65705
  workspaces.forEach((workspace) => addEntry(workspace.line_id, workspace.date, workspace.shift_id));
65676
65706
  blueComparisonWorkspaces.forEach((workspace) => addEntry(workspace.line_id, workspace.date, workspace.shift_id));
65707
+ selectorLineMetrics.forEach((lineMetric) => addEntry(lineMetric.line_id, lineMetric.date, lineMetric.shift_id));
65677
65708
  return lookup;
65678
65709
  };
65679
65710
  var useLiveMonitorBootstrap = ({
65680
65711
  lineIds,
65681
65712
  blueComparisonLineIds,
65713
+ selectorLineIds,
65682
65714
  companyId,
65683
65715
  enabled = true,
65684
65716
  appTimezone,
@@ -65694,6 +65726,7 @@ var useLiveMonitorBootstrap = ({
65694
65726
  const effectiveTimezone = appTimezone || "Asia/Kolkata";
65695
65727
  const rawLineIdsKey = (lineIds || []).filter(Boolean).join(",");
65696
65728
  const rawBlueComparisonLineIdsKey = (blueComparisonLineIds || lineIds || []).filter(Boolean).join(",");
65729
+ const rawSelectorLineIdsKey = (selectorLineIds || []).filter(Boolean).join(",");
65697
65730
  const normalizedLineIds = useMemo(
65698
65731
  () => Array.from(new Set(rawLineIdsKey ? rawLineIdsKey.split(",") : [])),
65699
65732
  [rawLineIdsKey]
@@ -65702,13 +65735,17 @@ var useLiveMonitorBootstrap = ({
65702
65735
  () => Array.from(new Set(rawBlueComparisonLineIdsKey ? rawBlueComparisonLineIdsKey.split(",") : [])),
65703
65736
  [rawBlueComparisonLineIdsKey]
65704
65737
  );
65738
+ const normalizedSelectorLineIds = useMemo(
65739
+ () => Array.from(new Set(rawSelectorLineIdsKey ? rawSelectorLineIdsKey.split(",") : [])),
65740
+ [rawSelectorLineIdsKey]
65741
+ );
65705
65742
  const realtimeLineIds = useMemo(
65706
- () => Array.from(new Set([...normalizedLineIds, ...normalizedBlueComparisonLineIds].filter(Boolean))).sort(),
65707
- [normalizedLineIds, normalizedBlueComparisonLineIds]
65743
+ () => Array.from(new Set([...normalizedLineIds, ...normalizedBlueComparisonLineIds, ...normalizedSelectorLineIds].filter(Boolean))).sort(),
65744
+ [normalizedLineIds, normalizedBlueComparisonLineIds, normalizedSelectorLineIds]
65708
65745
  );
65709
65746
  const requestKey = useMemo(
65710
- () => `${normalizedLineIds.slice().sort().join(",")}|blue:${normalizedBlueComparisonLineIds.slice().sort().join(",")}`,
65711
- [normalizedLineIds, normalizedBlueComparisonLineIds]
65747
+ () => `${normalizedLineIds.slice().sort().join(",")}|blue:${normalizedBlueComparisonLineIds.slice().sort().join(",")}|selector:${normalizedSelectorLineIds.slice().sort().join(",")}`,
65748
+ [normalizedLineIds, normalizedBlueComparisonLineIds, normalizedSelectorLineIds]
65712
65749
  );
65713
65750
  const realtimeLineIdsKey = useMemo(() => realtimeLineIds.join(","), [realtimeLineIds]);
65714
65751
  const companySpecificMetricsTable = useMemo(
@@ -65740,6 +65777,9 @@ var useLiveMonitorBootstrap = ({
65740
65777
  if (normalizedBlueComparisonLineIds.length) {
65741
65778
  searchParams.set("blue_comparison_line_ids", normalizedBlueComparisonLineIds.join(","));
65742
65779
  }
65780
+ if (normalizedSelectorLineIds.length) {
65781
+ searchParams.set("selector_line_ids", normalizedSelectorLineIds.join(","));
65782
+ }
65743
65783
  if (force) {
65744
65784
  searchParams.set("force_refresh", "true");
65745
65785
  }
@@ -65773,6 +65813,7 @@ var useLiveMonitorBootstrap = ({
65773
65813
  company_id: resolvedCompanyId,
65774
65814
  line_ids: normalizedLineIds,
65775
65815
  blue_comparison_line_ids: normalizedBlueComparisonLineIds,
65816
+ selector_line_ids: normalizedSelectorLineIds,
65776
65817
  force_refresh: force,
65777
65818
  pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
65778
65819
  }
@@ -65790,6 +65831,7 @@ var useLiveMonitorBootstrap = ({
65790
65831
  resolvedCompanyId,
65791
65832
  normalizedLineIds,
65792
65833
  normalizedBlueComparisonLineIds,
65834
+ normalizedSelectorLineIds,
65793
65835
  requestKey
65794
65836
  ]);
65795
65837
  const fetchBootstrapRef = useRef(fetchBootstrap);
@@ -65901,6 +65943,7 @@ var useLiveMonitorBootstrap = ({
65901
65943
  workspaceMetrics,
65902
65944
  blueComparisonWorkspaceMetrics: blueComparisonWorkspaceMetrics.length ? blueComparisonWorkspaceMetrics : workspaceMetrics,
65903
65945
  lineMetrics: rawState.response.line_metrics || [],
65946
+ selectorLineMetrics: rawState.response.selector_line_metrics || [],
65904
65947
  kpiTrend: rawState.response.kpi_trend || null,
65905
65948
  activeBreaks,
65906
65949
  videoStreamsByWorkspaceId,
@@ -65937,8 +65980,9 @@ var useLiveMonitorBootstrap = ({
65937
65980
  const realtimeScopeKey = useMemo(() => Array.from(createResolvedScopeLookup(
65938
65981
  state.resolvedScope,
65939
65982
  state.workspaceMetrics,
65940
- state.blueComparisonWorkspaceMetrics
65941
- )).sort().join("||"), [state.resolvedScope, state.workspaceMetrics, state.blueComparisonWorkspaceMetrics]);
65983
+ state.blueComparisonWorkspaceMetrics,
65984
+ state.selectorLineMetrics
65985
+ )).sort().join("||"), [state.resolvedScope, state.workspaceMetrics, state.blueComparisonWorkspaceMetrics, state.selectorLineMetrics]);
65942
65986
  useEffect(() => {
65943
65987
  if (!enabled || !resolvedCompanyId || !realtimeLineIdsKey || !supabase) {
65944
65988
  return void 0;
@@ -66044,6 +66088,7 @@ var useLiveMonitorBootstrap = ({
66044
66088
  workspaceMetrics: state.workspaceMetrics,
66045
66089
  blueComparisonWorkspaceMetrics: state.blueComparisonWorkspaceMetrics,
66046
66090
  lineMetrics: state.lineMetrics,
66091
+ selectorLineMetrics: state.selectorLineMetrics,
66047
66092
  kpiTrend: state.kpiTrend,
66048
66093
  activeBreaks: state.activeBreaks,
66049
66094
  videoStreamsByWorkspaceId: state.videoStreamsByWorkspaceId,
@@ -66558,6 +66603,7 @@ function HomeView({
66558
66603
  workspaceMetrics: legacyWorkspaceMetrics,
66559
66604
  blueComparisonWorkspaceMetrics: legacyMetricsBlueComparisonWorkspaceMetrics,
66560
66605
  lineMetrics: legacyLineMetrics,
66606
+ selectorLineMetrics: legacySelectorLineMetrics = [],
66561
66607
  efficiencyLegend: legacyEfficiencyLegend,
66562
66608
  metadata: legacyMetricsMetadata,
66563
66609
  isLoading: legacyMetricsLoading,
@@ -66568,6 +66614,7 @@ function HomeView({
66568
66614
  lineId: metricsScopeLineId,
66569
66615
  lineIds: selectedLineIds,
66570
66616
  blueComparisonLineIds,
66617
+ selectorLineIds: visibleLineIds,
66571
66618
  onLineMetricsUpdate: handleLineMetricsUpdate,
66572
66619
  userAccessibleLineIds: visibleLineIds,
66573
66620
  enabled: shouldEnableMetricsFetch && !isBootstrapMonitorMode
@@ -66623,6 +66670,7 @@ function HomeView({
66623
66670
  const bootstrapMonitor = useLiveMonitorBootstrap({
66624
66671
  lineIds: selectedLineIds,
66625
66672
  blueComparisonLineIds,
66673
+ selectorLineIds: visibleLineIds,
66626
66674
  companyId: userCompanyId,
66627
66675
  enabled: shouldEnableMetricsFetch && !isLegacyMonitorMode,
66628
66676
  appTimezone: timezone,
@@ -66633,12 +66681,32 @@ function HomeView({
66633
66681
  const currentWorkspaceMetrics = isBootstrapMonitorMode ? bootstrapMonitor.workspaceMetrics : legacyWorkspaceMetrics;
66634
66682
  const currentBlueComparisonWorkspaceMetrics = isBootstrapMonitorMode ? bootstrapMonitor.blueComparisonWorkspaceMetrics : legacyMetricsBlueComparisonWorkspaceMetrics;
66635
66683
  const currentLineMetrics = isBootstrapMonitorMode ? bootstrapMonitor.lineMetrics : legacyLineMetrics;
66684
+ const currentSelectorLineMetrics = isBootstrapMonitorMode ? bootstrapMonitor.selectorLineMetrics : legacySelectorLineMetrics;
66636
66685
  const currentEfficiencyLegend = isBootstrapMonitorMode ? bootstrapMonitor.efficiencyLegend : legacyEfficiencyLegend;
66637
66686
  const currentMetricsMetadata = isBootstrapMonitorMode ? bootstrapMonitor.metadata : legacyMetricsMetadata;
66638
66687
  const currentMetricsLoading = isBootstrapMonitorMode ? bootstrapMonitor.isLoading : legacyMetricsLoading;
66639
66688
  const currentIsCurrentScopeResolved = isBootstrapMonitorMode ? bootstrapMonitor.isCurrentScopeResolved : legacyIsCurrentScopeResolved;
66640
66689
  const currentMetricsError = isBootstrapMonitorMode ? bootstrapMonitor.error : legacyMetricsError;
66641
66690
  const currentRefetchMetrics = isBootstrapMonitorMode ? bootstrapMonitor.refetch : refetchLegacyMetrics;
66691
+ const lineSelectorSignalStatusByLine = useMemo(() => {
66692
+ const statusByLine = /* @__PURE__ */ new Map();
66693
+ const legend = currentEfficiencyLegend || DEFAULT_EFFICIENCY_LEGEND;
66694
+ const addRows = (rows) => {
66695
+ (rows || []).forEach((row) => {
66696
+ const lineId = typeof row?.line_id === "string" ? row.line_id : "";
66697
+ if (!lineId || statusByLine.has(lineId)) {
66698
+ return;
66699
+ }
66700
+ const status = getKpiSignalStatus(row?.line_signal, legend);
66701
+ if (status) {
66702
+ statusByLine.set(lineId, status);
66703
+ }
66704
+ });
66705
+ };
66706
+ addRows(currentSelectorLineMetrics);
66707
+ addRows(currentLineMetrics);
66708
+ return statusByLine;
66709
+ }, [currentEfficiencyLegend, currentLineMetrics, currentSelectorLineMetrics]);
66642
66710
  const metricsDisplayNames = useMemo(() => {
66643
66711
  const nextDisplayNames = {};
66644
66712
  currentWorkspaceMetrics.forEach((workspace) => {
@@ -67496,6 +67564,8 @@ function HomeView({
67496
67564
  ] }),
67497
67565
  /* @__PURE__ */ jsx("div", { className: "max-h-56 space-y-0.5 overflow-y-auto pr-1", children: visibleLineIds.map((lineId) => {
67498
67566
  const isChecked = pendingSelectedLineIds.includes(lineId);
67567
+ const signalStatus = lineSelectorSignalStatusByLine.get(lineId);
67568
+ const signalDotClass = signalStatus === "stable" ? "bg-green-500" : signalStatus === "warning" ? "bg-yellow-400" : signalStatus === "attention" ? "bg-red-500" : "";
67499
67569
  return /* @__PURE__ */ jsxs(
67500
67570
  "label",
67501
67571
  {
@@ -67520,7 +67590,15 @@ function HomeView({
67520
67590
  }
67521
67591
  }
67522
67592
  ),
67523
- /* @__PURE__ */ jsx("span", { className: "truncate", children: mergedLineNames[lineId] || `Line ${lineId.substring(0, 4)}` })
67593
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: mergedLineNames[lineId] || `Line ${lineId.substring(0, 4)}` }),
67594
+ /* @__PURE__ */ jsx("span", { className: "flex h-2.5 w-2.5 flex-shrink-0 items-center justify-center", children: signalStatus ? /* @__PURE__ */ jsx(
67595
+ "span",
67596
+ {
67597
+ "data-testid": `line-selector-signal-dot-${lineId}`,
67598
+ className: `h-2 w-2 rounded-full ${signalDotClass}`,
67599
+ "aria-hidden": "true"
67600
+ }
67601
+ ) : null })
67524
67602
  ]
67525
67603
  },
67526
67604
  lineId
@@ -67549,6 +67627,7 @@ function HomeView({
67549
67627
  mergedLineNames,
67550
67628
  selectedLineIds,
67551
67629
  pendingSelectedLineIds,
67630
+ lineSelectorSignalStatusByLine,
67552
67631
  visibleLineIds,
67553
67632
  updateSelectedLineIds,
67554
67633
  isAllLinesSelection
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optifye/dashboard-core",
3
- "version": "6.12.42",
3
+ "version": "6.12.43",
4
4
  "description": "Reusable UI & logic for Optifye dashboard",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",