@optifye/dashboard-core 6.0.7 → 6.0.9

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.js CHANGED
@@ -4613,20 +4613,13 @@ var useRealtimeLineMetrics = ({
4613
4613
  workspaceData: workspaceData?.length
4614
4614
  });
4615
4615
  }
4616
- let avgEfficiency = 0;
4617
- if (workspaceData && workspaceData.length > 0) {
4618
- const activeWorkspaces = workspaceData.filter((w) => w.efficiency >= 10);
4619
- if (activeWorkspaces.length > 0) {
4620
- const totalEfficiency = activeWorkspaces.reduce((sum, workspace) => sum + (workspace.efficiency || 0), 0);
4621
- avgEfficiency = totalEfficiency / activeWorkspaces.length;
4622
- }
4623
- }
4616
+ const avgEfficiency = metricsData.reduce((sum, m) => sum + (m.avg_efficiency || 0), 0) / metricsData.length;
4624
4617
  const combinedMetrics = {
4625
4618
  line_id: factoryViewId,
4626
4619
  shift_id: shiftId,
4627
4620
  date,
4628
4621
  factory_id: firstLine.factory_id,
4629
- avg_efficiency: avgEfficiency > 0 ? avgEfficiency : metricsData.reduce((sum, m) => sum + (m.avg_efficiency || 0), 0) / metricsData.length,
4622
+ avg_efficiency: avgEfficiency,
4630
4623
  avg_cycle_time: metricsData.reduce((sum, m) => sum + (m.avg_cycle_time || 0), 0) / metricsData.length,
4631
4624
  current_output: metricsData.reduce((sum, m) => sum + (m.current_output || 0), 0),
4632
4625
  ideal_output: metricsData.reduce((sum, m) => sum + (m.ideal_output || 0), 0),
@@ -4678,22 +4671,14 @@ var useRealtimeLineMetrics = ({
4678
4671
  workspaceData: workspaceData?.length
4679
4672
  });
4680
4673
  }
4681
- let avgEfficiency = 0;
4682
- if (workspaceData && workspaceData.length > 0) {
4683
- const activeWorkspaces = workspaceData.filter((w) => w.efficiency >= 10);
4684
- if (activeWorkspaces.length > 0) {
4685
- const totalEfficiency = activeWorkspaces.reduce((sum, workspace) => sum + (workspace.efficiency || 0), 0);
4686
- avgEfficiency = totalEfficiency / activeWorkspaces.length;
4687
- }
4688
- }
4689
4674
  if (!metricsData) {
4690
4675
  setMetrics({
4691
4676
  line_id: lineIdRef.current,
4692
4677
  shift_id: shiftId,
4693
4678
  date,
4694
4679
  factory_id: "",
4695
- avg_efficiency: avgEfficiency,
4696
- // Use calculated workspace average
4680
+ avg_efficiency: 0,
4681
+ // Default to 0 when no data
4697
4682
  avg_cycle_time: 0,
4698
4683
  current_output: 0,
4699
4684
  ideal_output: 0,
@@ -4712,7 +4697,6 @@ var useRealtimeLineMetrics = ({
4712
4697
  } else {
4713
4698
  setMetrics({
4714
4699
  ...metricsData,
4715
- avg_efficiency: avgEfficiency > 0 ? avgEfficiency : metricsData.avg_efficiency,
4716
4700
  poorest_performing_workspaces: poorestPerformingWorkspaces
4717
4701
  });
4718
4702
  }
@@ -5561,6 +5545,7 @@ console.log("\u{1F504} workspaceDisplayNames.ts module loaded");
5561
5545
  var runtimeWorkspaceDisplayNames = {};
5562
5546
  var isInitialized = false;
5563
5547
  var isInitializing = false;
5548
+ var initializedWithLineIds = [];
5564
5549
  function getCurrentLineIds() {
5565
5550
  try {
5566
5551
  const config = _getDashboardConfigInstance();
@@ -5592,28 +5577,29 @@ async function initializeWorkspaceDisplayNames(explicitLineId) {
5592
5577
  targetLineIds = getCurrentLineIds();
5593
5578
  }
5594
5579
  console.log("\u{1F504} Target line IDs for workspace filtering:", targetLineIds);
5595
- const allDisplayNamesMap = /* @__PURE__ */ new Map();
5580
+ runtimeWorkspaceDisplayNames = {};
5596
5581
  if (targetLineIds.length > 0) {
5597
5582
  for (const lineId of targetLineIds) {
5598
5583
  console.log(`\u{1F504} Fetching workspaces for line: ${lineId}`);
5599
5584
  const lineDisplayNamesMap = await workspaceService.getWorkspaceDisplayNames(void 0, lineId);
5585
+ runtimeWorkspaceDisplayNames[lineId] = {};
5600
5586
  lineDisplayNamesMap.forEach((displayName, workspaceId) => {
5601
- allDisplayNamesMap.set(workspaceId, displayName);
5587
+ runtimeWorkspaceDisplayNames[lineId][workspaceId] = displayName;
5602
5588
  });
5589
+ console.log(`\u2705 Stored ${lineDisplayNamesMap.size} workspaces for line ${lineId}`);
5603
5590
  }
5604
5591
  } else {
5605
5592
  console.warn("\u26A0\uFE0F No line IDs found, fetching all workspaces (less efficient)");
5606
5593
  const allWorkspacesMap = await workspaceService.getWorkspaceDisplayNames();
5594
+ runtimeWorkspaceDisplayNames["global"] = {};
5607
5595
  allWorkspacesMap.forEach((displayName, workspaceId) => {
5608
- allDisplayNamesMap.set(workspaceId, displayName);
5596
+ runtimeWorkspaceDisplayNames["global"][workspaceId] = displayName;
5609
5597
  });
5610
5598
  }
5611
- runtimeWorkspaceDisplayNames = {};
5612
- allDisplayNamesMap.forEach((displayName, workspaceId) => {
5613
- runtimeWorkspaceDisplayNames[workspaceId] = displayName;
5614
- });
5615
5599
  isInitialized = true;
5600
+ initializedWithLineIds = targetLineIds;
5616
5601
  console.log("\u2705 Workspace display names initialized from Supabase:", runtimeWorkspaceDisplayNames);
5602
+ console.log("\u2705 Initialized with line IDs:", initializedWithLineIds);
5617
5603
  } catch (error) {
5618
5604
  console.error("\u274C Failed to initialize workspace display names from Supabase:", error);
5619
5605
  } finally {
@@ -5623,7 +5609,20 @@ async function initializeWorkspaceDisplayNames(explicitLineId) {
5623
5609
  var preInitializeWorkspaceDisplayNames = async (lineId) => {
5624
5610
  console.log("\u{1F504} preInitializeWorkspaceDisplayNames called for lineId:", lineId);
5625
5611
  if (isInitialized || isInitializing) {
5626
- console.log("\u{1F504} Already initialized or initializing, skipping pre-init");
5612
+ console.log("\u{1F504} Already initialized or initializing");
5613
+ if (lineId && !runtimeWorkspaceDisplayNames[lineId]) {
5614
+ console.log(`\u{1F504} Line ${lineId} not in cache, fetching...`);
5615
+ try {
5616
+ const lineDisplayNamesMap = await workspaceService.getWorkspaceDisplayNames(void 0, lineId);
5617
+ runtimeWorkspaceDisplayNames[lineId] = {};
5618
+ lineDisplayNamesMap.forEach((displayName, workspaceId) => {
5619
+ runtimeWorkspaceDisplayNames[lineId][workspaceId] = displayName;
5620
+ });
5621
+ console.log(`\u2705 Added ${lineDisplayNamesMap.size} workspaces for line ${lineId}`);
5622
+ } catch (error) {
5623
+ console.error(`\u274C Failed to fetch workspaces for line ${lineId}:`, error);
5624
+ }
5625
+ }
5627
5626
  return;
5628
5627
  }
5629
5628
  await initializeWorkspaceDisplayNames(lineId);
@@ -5636,45 +5635,91 @@ var forceRefreshWorkspaceDisplayNames = async (lineId) => {
5636
5635
  console.log("\u{1F504} Module loaded, will initialize lazily when first function is called");
5637
5636
  var getWorkspaceDisplayName = (workspaceId, lineId) => {
5638
5637
  if (!isInitialized && !isInitializing) {
5639
- console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}) - Not initialized, triggering lazy init...`);
5638
+ console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) - Not initialized, triggering lazy init...`);
5640
5639
  } else if (isInitializing) {
5641
- console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}) - Currently initializing...`);
5640
+ console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) - Currently initializing...`);
5642
5641
  }
5643
5642
  if (!isInitialized && !isInitializing) {
5644
- console.log("\u{1F504} Lazy initialization triggered by getWorkspaceDisplayName");
5643
+ console.log("\u{1F504} Lazy initialization triggered by getWorkspaceDisplayName with lineId:", lineId);
5645
5644
  initializeWorkspaceDisplayNames(lineId).catch((error) => {
5646
5645
  console.error("\u274C Lazy initialization failed:", error);
5647
5646
  });
5648
5647
  }
5649
- const displayName = runtimeWorkspaceDisplayNames[workspaceId];
5648
+ if (isInitialized && lineId && !runtimeWorkspaceDisplayNames[lineId]) {
5649
+ console.log(`\u{1F504} Line ${lineId} not in cache, fetching its workspaces...`);
5650
+ workspaceService.getWorkspaceDisplayNames(void 0, lineId).then((lineDisplayNamesMap) => {
5651
+ runtimeWorkspaceDisplayNames[lineId] = {};
5652
+ lineDisplayNamesMap.forEach((displayName2, workspaceId2) => {
5653
+ runtimeWorkspaceDisplayNames[lineId][workspaceId2] = displayName2;
5654
+ });
5655
+ console.log(`\u2705 Added ${lineDisplayNamesMap.size} workspaces for line ${lineId} to cache`);
5656
+ }).catch((error) => {
5657
+ console.error(`\u274C Failed to fetch workspaces for line ${lineId}:`, error);
5658
+ });
5659
+ }
5660
+ let displayName;
5661
+ if (lineId && runtimeWorkspaceDisplayNames[lineId]) {
5662
+ displayName = runtimeWorkspaceDisplayNames[lineId][workspaceId];
5663
+ } else if (!lineId) {
5664
+ for (const cachedLineId of Object.keys(runtimeWorkspaceDisplayNames)) {
5665
+ if (runtimeWorkspaceDisplayNames[cachedLineId][workspaceId]) {
5666
+ displayName = runtimeWorkspaceDisplayNames[cachedLineId][workspaceId];
5667
+ console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
5668
+ break;
5669
+ }
5670
+ }
5671
+ }
5650
5672
  if (displayName) {
5651
- console.log(`getWorkspaceDisplayName(${workspaceId}) -> ${displayName} (from Supabase)`);
5673
+ console.log(`getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${displayName} (from Supabase)`);
5652
5674
  return displayName;
5653
5675
  } else {
5654
5676
  if (isInitialized) {
5655
- console.log(`getWorkspaceDisplayName(${workspaceId}) -> ${workspaceId} (not found in Supabase data)`);
5677
+ console.log(`getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (not found in Supabase data)`);
5656
5678
  } else {
5657
- console.log(`getWorkspaceDisplayName(${workspaceId}) -> ${workspaceId} (Supabase not initialized yet)`);
5679
+ console.log(`getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (Supabase not initialized yet)`);
5658
5680
  }
5659
5681
  return workspaceId;
5660
5682
  }
5661
5683
  };
5662
5684
  var getShortWorkspaceDisplayName = (workspaceId, lineId) => {
5663
5685
  if (!isInitialized && !isInitializing) {
5664
- console.log("\u{1F504} Lazy initialization triggered by getShortWorkspaceDisplayName");
5686
+ console.log("\u{1F504} Lazy initialization triggered by getShortWorkspaceDisplayName with lineId:", lineId);
5665
5687
  initializeWorkspaceDisplayNames(lineId).catch((error) => {
5666
5688
  console.error("\u274C Lazy initialization failed:", error);
5667
5689
  });
5668
5690
  }
5669
- const displayName = runtimeWorkspaceDisplayNames[workspaceId];
5691
+ if (isInitialized && lineId && !runtimeWorkspaceDisplayNames[lineId]) {
5692
+ console.log(`\u{1F504} Line ${lineId} not in cache, fetching its workspaces...`);
5693
+ workspaceService.getWorkspaceDisplayNames(void 0, lineId).then((lineDisplayNamesMap) => {
5694
+ runtimeWorkspaceDisplayNames[lineId] = {};
5695
+ lineDisplayNamesMap.forEach((displayName2, workspaceId2) => {
5696
+ runtimeWorkspaceDisplayNames[lineId][workspaceId2] = displayName2;
5697
+ });
5698
+ console.log(`\u2705 Added ${lineDisplayNamesMap.size} workspaces for line ${lineId} to cache`);
5699
+ }).catch((error) => {
5700
+ console.error(`\u274C Failed to fetch workspaces for line ${lineId}:`, error);
5701
+ });
5702
+ }
5703
+ let displayName;
5704
+ if (lineId && runtimeWorkspaceDisplayNames[lineId]) {
5705
+ displayName = runtimeWorkspaceDisplayNames[lineId][workspaceId];
5706
+ } else if (!lineId) {
5707
+ for (const cachedLineId of Object.keys(runtimeWorkspaceDisplayNames)) {
5708
+ if (runtimeWorkspaceDisplayNames[cachedLineId][workspaceId]) {
5709
+ displayName = runtimeWorkspaceDisplayNames[cachedLineId][workspaceId];
5710
+ console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
5711
+ break;
5712
+ }
5713
+ }
5714
+ }
5670
5715
  if (displayName) {
5671
- console.log(`getShortWorkspaceDisplayName(${workspaceId}) -> ${displayName} (from Supabase)`);
5716
+ console.log(`getShortWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${displayName} (from Supabase)`);
5672
5717
  return displayName;
5673
5718
  } else {
5674
5719
  if (isInitialized) {
5675
- console.log(`getShortWorkspaceDisplayName(${workspaceId}) -> ${workspaceId} (not found in Supabase data)`);
5720
+ console.log(`getShortWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (not found in Supabase data)`);
5676
5721
  } else {
5677
- console.log(`getShortWorkspaceDisplayName(${workspaceId}) -> ${workspaceId} (Supabase not initialized yet)`);
5722
+ console.log(`getShortWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (Supabase not initialized yet)`);
5678
5723
  }
5679
5724
  return workspaceId;
5680
5725
  }
@@ -5695,7 +5740,14 @@ var getAllWorkspaceDisplayNamesAsync = async (companyId, lineId) => {
5695
5740
  while (isInitializing) {
5696
5741
  await new Promise((resolve) => setTimeout(resolve, 100));
5697
5742
  }
5698
- return { ...runtimeWorkspaceDisplayNames };
5743
+ if (lineId && runtimeWorkspaceDisplayNames[lineId]) {
5744
+ return { ...runtimeWorkspaceDisplayNames[lineId] };
5745
+ }
5746
+ const allNames = {};
5747
+ Object.values(runtimeWorkspaceDisplayNames).forEach((lineNames) => {
5748
+ Object.assign(allNames, lineNames);
5749
+ });
5750
+ return allNames;
5699
5751
  };
5700
5752
  var getWorkspaceDisplayNamesMap = async (workspaceIds, companyId, lineId) => {
5701
5753
  const allNames = await getAllWorkspaceDisplayNamesAsync(companyId, lineId);
@@ -5724,10 +5776,11 @@ var clearWorkspaceDisplayNamesCache = () => {
5724
5776
  runtimeWorkspaceDisplayNames = {};
5725
5777
  isInitialized = false;
5726
5778
  isInitializing = false;
5779
+ initializedWithLineIds = [];
5727
5780
  };
5728
5781
 
5729
5782
  // src/lib/hooks/useWorkspaceDisplayNames.ts
5730
- var useWorkspaceDisplayNames = (companyId, lineId) => {
5783
+ var useWorkspaceDisplayNames = (lineId, companyId) => {
5731
5784
  const [displayNames, setDisplayNames] = React19.useState({});
5732
5785
  const [loading, setLoading] = React19.useState(true);
5733
5786
  const [error, setError] = React19.useState(null);
@@ -5753,7 +5806,7 @@ var useWorkspaceDisplayNames = (companyId, lineId) => {
5753
5806
  refetch: fetchDisplayNames
5754
5807
  };
5755
5808
  };
5756
- var useWorkspaceDisplayName = (workspaceId, companyId, lineId) => {
5809
+ var useWorkspaceDisplayName = (workspaceId, lineId, companyId) => {
5757
5810
  const [displayName, setDisplayName] = React19.useState(workspaceId);
5758
5811
  const [loading, setLoading] = React19.useState(true);
5759
5812
  const [error, setError] = React19.useState(null);
@@ -5780,7 +5833,7 @@ var useWorkspaceDisplayName = (workspaceId, companyId, lineId) => {
5780
5833
  refetch: fetchDisplayName
5781
5834
  };
5782
5835
  };
5783
- var useWorkspaceDisplayNamesMap = (workspaceIds, companyId, lineId) => {
5836
+ var useWorkspaceDisplayNamesMap = (workspaceIds, lineId, companyId) => {
5784
5837
  const [displayNames, setDisplayNames] = React19.useState({});
5785
5838
  const [loading, setLoading] = React19.useState(true);
5786
5839
  const [error, setError] = React19.useState(null);
@@ -18491,7 +18544,7 @@ var VideoCard = React19__namespace.default.memo(({
18491
18544
  onFatalError: onFatalError ?? (() => throttledReloadDashboard())
18492
18545
  });
18493
18546
  }
18494
- const displayName = getWorkspaceDisplayName(workspace.workspace_name);
18547
+ const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
18495
18548
  const getEfficiencyOverlayColor = (efficiency) => {
18496
18549
  if (efficiency >= 80) {
18497
18550
  return "bg-[#00D654]/25";
@@ -18613,7 +18666,9 @@ var VideoGridView = React19__namespace.default.memo(({
18613
18666
  const containerRef = React19.useRef(null);
18614
18667
  const observerRef = React19.useRef(null);
18615
18668
  const [gridCols, setGridCols] = React19.useState(4);
18669
+ const [gridRows, setGridRows] = React19.useState(1);
18616
18670
  const [visibleWorkspaces, setVisibleWorkspaces] = React19.useState(/* @__PURE__ */ new Set());
18671
+ const [cardDimensions, setCardDimensions] = React19.useState({ width: 0, height: 0 });
18617
18672
  const videoConfig = useVideoConfig();
18618
18673
  const { cropping, canvasConfig, hlsUrls } = videoConfig;
18619
18674
  const mergedVideoSources = {
@@ -18674,35 +18729,51 @@ var VideoGridView = React19__namespace.default.memo(({
18674
18729
  setGridCols(1);
18675
18730
  return;
18676
18731
  }
18677
- let bestCols = 1;
18678
- let bestScore = 0;
18732
+ const optimalLayouts = {
18733
+ 1: 1,
18734
+ 2: 2,
18735
+ 3: 3,
18736
+ 4: 2,
18737
+ 5: 3,
18738
+ 6: 3,
18739
+ 7: 4,
18740
+ 8: 4,
18741
+ 9: 3,
18742
+ 10: 5,
18743
+ 11: 4,
18744
+ 12: 4,
18745
+ 13: 5,
18746
+ 14: 5,
18747
+ 15: 5,
18748
+ 16: 4,
18749
+ 17: 6,
18750
+ 18: 6,
18751
+ 19: 5,
18752
+ 20: 5,
18753
+ 21: 7,
18754
+ 22: 6,
18755
+ 23: 6,
18756
+ 24: 6
18757
+ };
18758
+ let bestCols = optimalLayouts[count] || Math.ceil(Math.sqrt(count));
18759
+ const containerAspectRatio = containerWidth / containerHeight;
18679
18760
  const targetAspectRatio = 16 / 9;
18680
18761
  const gap = 8;
18681
- const maxCols = Math.min(count, selectedLine ? 6 : 12);
18682
- for (let cols = 1; cols <= maxCols; cols++) {
18683
- const rows = Math.ceil(count / cols);
18684
- const availableWidth = containerWidth - gap * (cols - 1);
18685
- const availableHeight = containerHeight - gap * (rows - 1);
18686
- const cellWidth = availableWidth / cols;
18687
- const cellHeight = availableHeight / rows;
18688
- const minCellWidth = selectedLine ? containerWidth < 800 ? 120 : 150 : containerWidth < 800 ? 80 : 100;
18689
- const minCellHeight = selectedLine ? containerHeight < 600 ? 80 : 100 : containerHeight < 600 ? 60 : 80;
18690
- if (cellWidth < minCellWidth || cellHeight < minCellHeight) continue;
18691
- const totalUsedArea = cellWidth * cellHeight * count;
18692
- const totalAvailableArea = containerWidth * containerHeight;
18693
- const spaceUtilization = totalUsedArea / totalAvailableArea;
18694
- const actualAspectRatio = cellWidth / cellHeight;
18695
- const aspectRatioScore = 1 / (1 + Math.abs(actualAspectRatio - targetAspectRatio) * 0.3);
18696
- const score = spaceUtilization * 0.9 + aspectRatioScore * 0.1;
18697
- if (score > bestScore) {
18698
- bestScore = score;
18699
- bestCols = cols;
18700
- }
18701
- }
18702
- if (bestScore === 0) {
18703
- bestCols = Math.ceil(Math.sqrt(count));
18762
+ if (containerAspectRatio > targetAspectRatio * 1.5 && count > 6) {
18763
+ bestCols = Math.min(bestCols + 1, Math.ceil(count / 2));
18764
+ }
18765
+ const minCellWidth = selectedLine ? 150 : 100;
18766
+ const availableWidth = containerWidth - gap * (bestCols - 1);
18767
+ const cellWidth = availableWidth / bestCols;
18768
+ if (cellWidth < minCellWidth && bestCols > 1) {
18769
+ bestCols = Math.floor((containerWidth + gap) / (minCellWidth + gap));
18704
18770
  }
18771
+ const rows = Math.ceil(count / bestCols);
18705
18772
  setGridCols(bestCols);
18773
+ setGridRows(rows);
18774
+ const cardWidth = (containerWidth - gap * (bestCols - 1)) / bestCols;
18775
+ const cardHeight = (containerHeight - gap * (rows - 1)) / rows;
18776
+ setCardDimensions({ width: Math.floor(cardWidth), height: Math.floor(cardHeight) });
18706
18777
  }, [filteredWorkspaces.length, selectedLine]);
18707
18778
  React19.useEffect(() => {
18708
18779
  calculateOptimalGrid();
@@ -18748,7 +18819,7 @@ var VideoGridView = React19__namespace.default.memo(({
18748
18819
  efficiency: workspace.efficiency,
18749
18820
  action_count: workspace.action_count
18750
18821
  });
18751
- const displayName = getWorkspaceDisplayName(workspace.workspace_name);
18822
+ const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
18752
18823
  const navParams = getWorkspaceNavigationParams(workspaceId, displayName);
18753
18824
  router$1.push(`/workspace/${workspaceId}${navParams}`);
18754
18825
  }, [router$1]);
@@ -18758,8 +18829,8 @@ var VideoGridView = React19__namespace.default.memo(({
18758
18829
  className: "grid h-full w-full gap-2",
18759
18830
  style: {
18760
18831
  gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
18761
- gridTemplateRows: `repeat(${Math.ceil(filteredWorkspaces.length / gridCols)}, 1fr)`,
18762
- minHeight: "100%"
18832
+ gridTemplateRows: `repeat(${gridRows}, 1fr)`,
18833
+ gridAutoFlow: "row"
18763
18834
  },
18764
18835
  children: filteredWorkspaces.sort((a, b) => {
18765
18836
  if (a.line_id !== b.line_id) {
@@ -18782,9 +18853,8 @@ var VideoGridView = React19__namespace.default.memo(({
18782
18853
  "div",
18783
18854
  {
18784
18855
  "data-workspace-id": workspaceId,
18785
- className: "workspace-card relative min-h-0 min-w-0",
18786
- style: { width: "100%", height: "100%" },
18787
- children: /* @__PURE__ */ jsxRuntime.jsx(
18856
+ className: "workspace-card relative w-full h-full",
18857
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsxRuntime.jsx(
18788
18858
  VideoCard,
18789
18859
  {
18790
18860
  workspace,
@@ -18798,7 +18868,7 @@ var VideoGridView = React19__namespace.default.memo(({
18798
18868
  useRAF: canvasConfig?.useRAF,
18799
18869
  compact: !selectedLine
18800
18870
  }
18801
- )
18871
+ ) })
18802
18872
  },
18803
18873
  workspaceId
18804
18874
  );
@@ -20223,7 +20293,7 @@ var LineMonthlyHistory = ({
20223
20293
  className: "block hover:bg-gray-50 transition-colors rounded-lg w-full text-left",
20224
20294
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-3 px-2 border-b border-gray-100 last:border-b-0", children: [
20225
20295
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-medium text-gray-900", children: [
20226
- getWorkspaceDisplayName(workspace.workspace_name),
20296
+ getWorkspaceDisplayName(workspace.workspace_name, lineId),
20227
20297
  workspace.avg_efficiency !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 text-sm text-gray-500", children: [
20228
20298
  "(",
20229
20299
  workspace.avg_efficiency.toFixed(1),
@@ -20807,7 +20877,7 @@ var LinePdfGenerator = ({
20807
20877
  doc.setFillColor(252, 252, 252);
20808
20878
  doc.roundedRect(20, yPos - 5, 170, 8, 1, 1, "F");
20809
20879
  }
20810
- const workspaceName = getWorkspaceDisplayName(ws.workspace_name);
20880
+ const workspaceName = getWorkspaceDisplayName(ws.workspace_name, lineInfo.line_id);
20811
20881
  const maxWidth = 55;
20812
20882
  const truncatedName = workspaceName.length > 25 ? workspaceName.substring(0, 22) + "..." : workspaceName;
20813
20883
  doc.text(truncatedName, 25, yPos);
@@ -21488,7 +21558,7 @@ var WorkspacePdfGenerator = ({ workspace, className }) => {
21488
21558
  doc.setFontSize(22);
21489
21559
  doc.setFont("helvetica", "normal");
21490
21560
  doc.setTextColor(40, 40, 40);
21491
- doc.text(getWorkspaceDisplayName(workspace.workspace_name), 20, 52);
21561
+ doc.text(getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id), 20, 52);
21492
21562
  doc.setFontSize(13);
21493
21563
  doc.setFont("helvetica", "normal");
21494
21564
  doc.setTextColor(60, 60, 60);
@@ -23957,7 +24027,7 @@ var WorkspaceGridItem = React19__namespace.default.memo(({
23957
24027
  const handleClick = React19.useCallback((e) => {
23958
24028
  e.preventDefault();
23959
24029
  if (isInactive) return;
23960
- const displayName = getWorkspaceDisplayName(data.workspace_name);
24030
+ const displayName = getWorkspaceDisplayName(data.workspace_name, data.line_id);
23961
24031
  const navParams = getWorkspaceNavigationParams(data.workspace_id, displayName);
23962
24032
  navigate(`/workspace/${data.workspace_id}${navParams}`, {
23963
24033
  trackingEvent: {
@@ -24005,7 +24075,7 @@ var WorkspaceGridItem = React19__namespace.default.memo(({
24005
24075
  onClick: handleClick,
24006
24076
  className: `${styles2} ${colorClass} ${isBottleneck ? "ring-2 ring-red-500/70" : ""} ${isVeryLowEfficiency ? "ring-2 ring-red-500/50" : ""} ${isInactive ? "bg-gray-200" : ""} shadow-lg`,
24007
24077
  "aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
24008
- title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name)}` : getWorkspaceDisplayName(data.workspace_name),
24078
+ title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : getWorkspaceDisplayName(data.workspace_name, data.line_id),
24009
24079
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `font-semibold tracking-wide text-[min(4vw,2rem)] uppercase ${isInactive ? "text-gray-400" : "text-white"} drop-shadow-sm`, children: workspaceNumber })
24010
24080
  }
24011
24081
  ),
@@ -28820,6 +28890,7 @@ var MetricCards = React19.memo(({ lineInfo }) => {
28820
28890
  MetricCards.displayName = "MetricCards";
28821
28891
  var BottomSection = React19.memo(({
28822
28892
  lineInfo,
28893
+ lineId,
28823
28894
  workspaceData,
28824
28895
  sortedByEfficiency,
28825
28896
  hourlyOutputData,
@@ -28877,7 +28948,7 @@ var BottomSection = React19.memo(({
28877
28948
  return null;
28878
28949
  }
28879
28950
  const clickHandler = () => handleWorkspaceClick(ws, index);
28880
- const displayName = getWorkspaceDisplayName(ws.workspace_name);
28951
+ const displayName = getWorkspaceDisplayName(ws.workspace_name, lineId);
28881
28952
  const navParams = wsUuid ? getWorkspaceNavigationParams2(wsUuid, displayName) : "";
28882
28953
  const dateShiftParams = urlDate ? `&date=${urlDate}&shift=${urlShift || "0"}` : "";
28883
28954
  const returnToParam = `&returnTo=${encodeURIComponent(`/kpis/${lineInfo?.line_id}`)}`;
@@ -28911,7 +28982,7 @@ var BottomSection = React19.memo(({
28911
28982
  // Fallback to sorted workspaces if no poorest performing workspaces provided
28912
28983
  sortedByEfficiency.map((ws, index) => {
28913
28984
  const clickHandler = () => handleWorkspaceClick(ws, index);
28914
- const displayName = getWorkspaceDisplayName(ws.workspace_name);
28985
+ const displayName = getWorkspaceDisplayName(ws.workspace_name, lineId);
28915
28986
  const navParams = ws.workspace_uuid ? getWorkspaceNavigationParams2(ws.workspace_uuid, displayName) : "";
28916
28987
  const dateShiftParams = urlDate ? `&date=${urlDate}&shift=${urlShift || "0"}` : "";
28917
28988
  const returnToParam = `&returnTo=${encodeURIComponent(`/kpis/${lineInfo?.line_id}`)}`;
@@ -29408,6 +29479,7 @@ var KPIDetailView = ({
29408
29479
  BottomSection,
29409
29480
  {
29410
29481
  lineInfo,
29482
+ lineId,
29411
29483
  workspaceData: workspaces || [],
29412
29484
  sortedByEfficiency,
29413
29485
  hourlyOutputData,
@@ -29510,6 +29582,7 @@ var KPIDetailView = ({
29510
29582
  BottomSection,
29511
29583
  {
29512
29584
  lineInfo,
29585
+ lineId,
29513
29586
  workspaceData: workspaces || [],
29514
29587
  sortedByEfficiency,
29515
29588
  hourlyOutputData,
@@ -29528,34 +29601,10 @@ var KPIDetailView = ({
29528
29601
  var KPIDetailView_default = KPIDetailView;
29529
29602
  var LineCard = ({ line, onClick }) => {
29530
29603
  const { kpis, isLoading, error } = useLineKPIs({ lineId: line.id });
29531
- const shiftConfig = useShiftConfig();
29532
- const dateTimeConfig = useDateTimeConfig();
29533
29604
  const isOnTrack = React19__namespace.default.useMemo(() => {
29534
29605
  if (!kpis) return null;
29535
- const currentTime = /* @__PURE__ */ new Date();
29536
- const timezone = dateTimeConfig.defaultTimezone || "Asia/Kolkata";
29537
- const currentShiftDetails = getCurrentShift(timezone, shiftConfig);
29538
- const shiftStartTime = currentShiftDetails.shiftId === 0 ? shiftConfig.dayShift?.startTime || "06:00" : shiftConfig.nightShift?.startTime || "18:00";
29539
- const shiftEndTime = currentShiftDetails.shiftId === 0 ? shiftConfig.dayShift?.endTime || "14:00" : shiftConfig.nightShift?.endTime || "02:00";
29540
- const [startHour, startMin] = shiftStartTime.split(":").map(Number);
29541
- const [endHour, endMin] = shiftEndTime.split(":").map(Number);
29542
- const shiftStart = /* @__PURE__ */ new Date();
29543
- shiftStart.setHours(startHour, startMin, 0, 0);
29544
- const shiftEnd = /* @__PURE__ */ new Date();
29545
- shiftEnd.setHours(endHour, endMin, 0, 0);
29546
- if (endHour < startHour) {
29547
- if (currentTime.getHours() < endHour) {
29548
- shiftStart.setDate(shiftStart.getDate() - 1);
29549
- } else {
29550
- shiftEnd.setDate(shiftEnd.getDate() + 1);
29551
- }
29552
- }
29553
- const totalShiftMinutes = (shiftEnd.getTime() - shiftStart.getTime()) / (1e3 * 60);
29554
- const elapsedMinutes = (currentTime.getTime() - shiftStart.getTime()) / (1e3 * 60);
29555
- const shiftProgress = Math.max(0, Math.min(1, elapsedMinutes / totalShiftMinutes));
29556
- const outputProgress = kpis.outputProgress.current / kpis.outputProgress.target;
29557
- return outputProgress >= shiftProgress - 0.05;
29558
- }, [kpis, shiftConfig, dateTimeConfig]);
29606
+ return kpis.efficiency.value > 90;
29607
+ }, [kpis]);
29559
29608
  return /* @__PURE__ */ jsxRuntime.jsxs(
29560
29609
  motion.div,
29561
29610
  {
@@ -29871,7 +29920,7 @@ var MobileWorkspaceCard = React19.memo(({
29871
29920
  getMedalIcon(rank)
29872
29921
  ] }),
29873
29922
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
29874
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-semibold text-gray-900", children: getWorkspaceDisplayName(workspace.workspace_name) }),
29923
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-semibold text-gray-900", children: getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id) }),
29875
29924
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-gray-500", children: getLineName(workspace.line_id) })
29876
29925
  ] })
29877
29926
  ] }),
@@ -29921,7 +29970,7 @@ var DesktopWorkspaceRow = React19.memo(({
29921
29970
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: index + 1 }),
29922
29971
  getMedalIcon(index + 1)
29923
29972
  ] }) }),
29924
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: getWorkspaceDisplayName(workspace.workspace_name) }) }),
29973
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id) }) }),
29925
29974
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: getLineName(workspace.line_id) }) }),
29926
29975
  /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base font-medium whitespace-nowrap", children: [
29927
29976
  (workspace.efficiency || 0).toFixed(1),
@@ -30038,7 +30087,7 @@ var LeaderboardDetailView = React19.memo(({
30038
30087
  action_count: workspace.action_count,
30039
30088
  action_threshold: workspace.action_threshold
30040
30089
  });
30041
- const displayName = getWorkspaceDisplayName(workspace.workspace_name);
30090
+ const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
30042
30091
  const navParams = workspace.workspace_uuid ? getWorkspaceNavigationParams(workspace.workspace_uuid, displayName) : "";
30043
30092
  const returnToParam = `&returnTo=${encodeURIComponent(`/leaderboard`)}`;
30044
30093
  if (onWorkspaceClick) {
@@ -31266,8 +31315,8 @@ var calculateDayOutput = (pph, shiftHours, breaks = []) => {
31266
31315
  const realWorkHours = shiftHours - totalBreakHours;
31267
31316
  return Math.round(pph * realWorkHours);
31268
31317
  };
31269
- var formatWorkspaceName = (name) => {
31270
- return getWorkspaceDisplayName(name);
31318
+ var formatWorkspaceName = (name, lineId) => {
31319
+ return getWorkspaceDisplayName(name, lineId);
31271
31320
  };
31272
31321
  var getStoredLineState2 = (lineId) => {
31273
31322
  try {
@@ -31295,6 +31344,7 @@ var BulkConfigureModal = ({
31295
31344
  isOpen,
31296
31345
  onClose,
31297
31346
  lineWorkspaces,
31347
+ lineNames,
31298
31348
  onSave,
31299
31349
  selectedShift
31300
31350
  }) => {
@@ -31445,10 +31495,7 @@ var BulkConfigureModal = ({
31445
31495
  className: "block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm\n shadow-sm focus:border-blue-500 focus:ring-blue-500 \n transition-all duration-200 hover:border-blue-400\n appearance-none bg-no-repeat bg-right pr-10\n hover:bg-blue-50/50",
31446
31496
  children: [
31447
31497
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select a line" }),
31448
- Object.entries(lineWorkspaces).map(([lineId, line]) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: lineId, className: "py-2", children: [
31449
- lineId,
31450
- " "
31451
- ] }, lineId))
31498
+ Object.entries(lineWorkspaces).map(([lineId, line]) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: lineId, className: "py-2", children: lineNames[lineId] || lineId }, lineId))
31452
31499
  ]
31453
31500
  }
31454
31501
  )
@@ -31506,7 +31553,7 @@ var BulkConfigureModal = ({
31506
31553
  className: "rounded border-gray-300 text-blue-600 focus:ring-blue-500"
31507
31554
  }
31508
31555
  ),
31509
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-sm ${selectedWorkspaces.includes(workspace.id) ? "text-blue-900 font-medium" : "text-gray-900"}`, children: formatWorkspaceName(workspace.name) })
31556
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-sm ${selectedWorkspaces.includes(workspace.id) ? "text-blue-900 font-medium" : "text-gray-900"}`, children: formatWorkspaceName(workspace.name, selectedLine) })
31510
31557
  ]
31511
31558
  },
31512
31559
  workspace.id
@@ -32193,7 +32240,7 @@ var TargetsViewUI = ({
32193
32240
  {
32194
32241
  className: "px-6 py-4 hover:bg-gray-50 transition-all duration-200",
32195
32242
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 gap-6 items-center", children: [
32196
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-2", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-900", children: formatWorkspaceName(workspace.name) }) }),
32243
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-2", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-900", children: formatWorkspaceName(workspace.name, lineId) }) }),
32197
32244
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
32198
32245
  "select",
32199
32246
  {
@@ -32203,7 +32250,7 @@ var TargetsViewUI = ({
32203
32250
  onActionTypeChange(lineId, workspace.id, newActionType);
32204
32251
  },
32205
32252
  className: "w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm",
32206
- "aria-label": `Action type for ${formatWorkspaceName(workspace.name)}`,
32253
+ "aria-label": `Action type for ${formatWorkspaceName(workspace.name, lineId)}`,
32207
32254
  children: [
32208
32255
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "assembly", className: "py-2", children: "Assembly" }),
32209
32256
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "packaging", className: "py-2", children: "Packaging" })
@@ -32262,6 +32309,7 @@ var TargetsViewUI = ({
32262
32309
  isOpen: isBulkConfigureOpen,
32263
32310
  onClose: onToggleBulkConfigure,
32264
32311
  lineWorkspaces,
32312
+ lineNames,
32265
32313
  onSave: onBulkConfigure,
32266
32314
  selectedShift
32267
32315
  }