@optifye/dashboard-core 4.3.5 → 4.3.8

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
@@ -463,6 +463,25 @@ var getTable2 = (dbConfig, tableName) => {
463
463
  return userValue ?? defaults2[tableName];
464
464
  };
465
465
  var dashboardService = {
466
+ /**
467
+ * Helper method to filter workspaces by line_id for disambiguation
468
+ * @param workspaces - Array of workspace metrics
469
+ * @param lineId - Line ID to filter by
470
+ * @returns Filtered workspace metrics
471
+ */
472
+ filterWorkspacesByLineId(workspaces, lineId) {
473
+ return workspaces.filter((workspace) => workspace.line_id === lineId);
474
+ },
475
+ /**
476
+ * Helper method to get workspace by composite key (line_id + workspace_name)
477
+ * @param workspaces - Array of workspace metrics
478
+ * @param workspaceName - Workspace name to search for
479
+ * @param lineId - Line ID to filter by
480
+ * @returns Matching workspace or undefined
481
+ */
482
+ getWorkspaceByLineIdAndName(workspaces, workspaceName, lineId) {
483
+ return workspaces.find((workspace) => workspace.workspace_name === workspaceName && workspace.line_id === lineId);
484
+ },
466
485
  // Example for getLineInfo:
467
486
  async getLineInfo(lineIdInput) {
468
487
  const supabase = _getSupabaseInstance();
@@ -623,6 +642,13 @@ var dashboardService = {
623
642
  metrics: metricsForReturn
624
643
  };
625
644
  },
645
+ /**
646
+ * Get workspace data with line_id-aware filtering
647
+ * @param lineIdInput - Specific line ID to filter by, or factory view ID
648
+ * @param dateProp - Date to query (optional)
649
+ * @param shiftProp - Shift ID to query (optional)
650
+ * @returns Array of workspace metrics with line_id context
651
+ */
626
652
  async getWorkspacesData(lineIdInput, dateProp, shiftProp) {
627
653
  const supabase = _getSupabaseInstance();
628
654
  const config = _getDashboardConfigInstance();
@@ -649,17 +675,20 @@ var dashboardService = {
649
675
  throw new Error("Factory View requires defaultLineId and secondaryLineId to be configured for workspace data.");
650
676
  }
651
677
  query = query.in("line_id", [defaultLineId, secondaryLineId]);
678
+ console.log(`[getWorkspacesData] Querying factory view with lines: ${defaultLineId}, ${secondaryLineId}`);
652
679
  } else {
653
680
  query = query.eq("line_id", lineId);
681
+ console.log(`[getWorkspacesData] Querying single line: ${lineId}`);
654
682
  }
655
683
  const { data, error } = await query;
656
684
  if (error) {
657
685
  console.error("Error in getWorkspacesData:", error);
658
686
  throw error;
659
687
  }
660
- return (data || []).map((item) => ({
688
+ const workspaces = (data || []).map((item) => ({
661
689
  company_id: item.company_id,
662
690
  line_id: item.line_id,
691
+ // Ensure line_id is always included
663
692
  shift_id: item.shift_id,
664
693
  date: item.date,
665
694
  workspace_uuid: item.workspace_id,
@@ -673,6 +702,20 @@ var dashboardService = {
673
702
  efficiency: item.efficiency || 0,
674
703
  action_threshold: item.total_day_output || 0
675
704
  }));
705
+ console.log(`[getWorkspacesData] Retrieved ${workspaces.length} workspaces for line(s): ${lineId || "factory"}`);
706
+ console.log(
707
+ `[getWorkspacesData] Workspace line_id distribution:`,
708
+ workspaces.reduce((acc, ws) => {
709
+ acc[ws.line_id] = (acc[ws.line_id] || 0) + 1;
710
+ return acc;
711
+ }, {})
712
+ );
713
+ console.log(`[getWorkspacesData] Sample workspaces:`, workspaces.slice(0, 5).map((ws) => ({
714
+ workspace_name: ws.workspace_name,
715
+ line_id: ws.line_id,
716
+ efficiency: ws.efficiency
717
+ })));
718
+ return workspaces;
676
719
  },
677
720
  async getWorkspaceDetailedMetrics(workspaceUuid, dateProp, shiftIdProp) {
678
721
  const supabase = _getSupabaseInstance();
@@ -1905,8 +1948,8 @@ var SSEChatClient = class {
1905
1948
  user_id: userId,
1906
1949
  context
1907
1950
  });
1908
- const agnoApiUrl = this.baseUrl || "https://optifye-agent-production.up.railway.app";
1909
- const endpoint = `${agnoApiUrl}/api/chat`;
1951
+ const agnoApiUrl = this.baseUrl || "https://fastapi-production-111f9.up.railway.app";
1952
+ const endpoint = `${agnoApiUrl}/api/v2/chat`;
1910
1953
  console.log("[SSEClient] Posting directly to AGNO:", endpoint);
1911
1954
  const response = await fetch(endpoint, {
1912
1955
  method: "POST",
@@ -1964,7 +2007,7 @@ var SSEChatClient = class {
1964
2007
  const decoder = new TextDecoder();
1965
2008
  let buffer = "";
1966
2009
  try {
1967
- console.log("[SSEClient] Starting to read stream...");
2010
+ console.log("[SSEClient] Starting to read enhanced stream...");
1968
2011
  while (true) {
1969
2012
  const { done, value } = await reader.read();
1970
2013
  if (done) {
@@ -1994,11 +2037,14 @@ var SSEChatClient = class {
1994
2037
  case "message":
1995
2038
  callbacks.onMessage?.(data.text);
1996
2039
  break;
1997
- case "reasoning":
1998
- callbacks.onReasoning?.(data.text);
2040
+ case "tool_call":
2041
+ callbacks.onToolCall?.(data.tools);
2042
+ break;
2043
+ case "tool_result":
2044
+ callbacks.onToolResult?.(data.results);
1999
2045
  break;
2000
2046
  case "complete":
2001
- callbacks.onComplete?.(data.message_id);
2047
+ callbacks.onComplete?.(data.message_id, data.metrics);
2002
2048
  break;
2003
2049
  case "error":
2004
2050
  callbacks.onError?.(data.error);
@@ -2538,7 +2584,7 @@ var useMetrics = (tableName, options) => {
2538
2584
  };
2539
2585
  return { data, isLoading, error, refetch };
2540
2586
  };
2541
- var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
2587
+ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId, lineId) => {
2542
2588
  const entityConfig = useEntityConfig();
2543
2589
  const databaseConfig = useDatabaseConfig();
2544
2590
  const dateTimeConfig = useDateTimeConfig();
@@ -2566,14 +2612,32 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
2566
2612
  const currentShift = getCurrentShift(defaultTimezone, shiftConfig);
2567
2613
  const queryDate = date || currentShift.date;
2568
2614
  const queryShiftId = shiftId !== void 0 ? shiftId : currentShift.shiftId;
2615
+ console.log("[useWorkspaceDetailedMetrics] Hook called with parameters:", {
2616
+ workspaceId,
2617
+ date,
2618
+ shiftId,
2619
+ lineId,
2620
+ queryDate,
2621
+ queryShiftId
2622
+ });
2569
2623
  console.log("[useWorkspaceDetailedMetrics] Using shift ID:", queryShiftId, "from input shift:", shiftId);
2570
2624
  console.log("[useWorkspaceDetailedMetrics] Using date:", queryDate, "from input date:", date);
2571
- console.log(`[useWorkspaceDetailedMetrics] Querying ${metricsTable} for workspace: ${workspaceId}, date: ${queryDate}, shift: ${queryShiftId}`);
2572
- const { data, error: fetchError } = await supabase.from(metricsTable).select("*").eq("workspace_id", workspaceId).eq("date", queryDate).eq("shift_id", queryShiftId).maybeSingle();
2625
+ console.log(`[useWorkspaceDetailedMetrics] Querying ${metricsTable} for workspace: ${workspaceId}, date: ${queryDate}, shift: ${queryShiftId}, line: ${lineId || "any"}`);
2626
+ let query = supabase.from(metricsTable).select("*").eq("workspace_id", workspaceId).eq("date", queryDate).eq("shift_id", queryShiftId);
2627
+ if (lineId) {
2628
+ query = query.eq("line_id", lineId);
2629
+ console.log(`[useWorkspaceDetailedMetrics] Filtering by line_id: ${lineId}`);
2630
+ }
2631
+ const { data, error: fetchError } = await query.maybeSingle();
2573
2632
  if (fetchError) throw fetchError;
2574
2633
  if (!data && !date && shiftId === void 0) {
2575
2634
  console.log("[useWorkspaceDetailedMetrics] No data found for current date/shift, attempting to find most recent data...");
2576
- const { data: recentData, error: recentError } = await supabase.from(metricsTable).select("*").eq("workspace_id", workspaceId).order("date", { ascending: false }).order("shift_id", { ascending: false }).limit(1).maybeSingle();
2635
+ let recentQuery = supabase.from(metricsTable).select("*").eq("workspace_id", workspaceId);
2636
+ if (lineId) {
2637
+ recentQuery = recentQuery.eq("line_id", lineId);
2638
+ console.log(`[useWorkspaceDetailedMetrics] Fallback query filtering by line_id: ${lineId}`);
2639
+ }
2640
+ const { data: recentData, error: recentError } = await recentQuery.order("date", { ascending: false }).order("shift_id", { ascending: false }).limit(1).maybeSingle();
2577
2641
  if (recentError) throw recentError;
2578
2642
  if (recentData) {
2579
2643
  console.log(`[useWorkspaceDetailedMetrics] Found fallback data from date: ${recentData.date}, shift: ${recentData.shift_id}`);
@@ -2791,7 +2855,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
2791
2855
  updateQueueRef.current = false;
2792
2856
  setIsLoading(false);
2793
2857
  }
2794
- }, [supabase, workspaceId, date, shiftId, metricsTable, defaultTimezone, shiftConfig, workspaceConfig, companyId]);
2858
+ }, [supabase, workspaceId, date, shiftId, lineId, metricsTable, defaultTimezone, shiftConfig, workspaceConfig, companyId]);
2795
2859
  const queueUpdate = React14.useCallback(() => {
2796
2860
  if (!workspaceId || updateQueueRef.current) return;
2797
2861
  updateQueueRef.current = true;
@@ -2922,7 +2986,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
2922
2986
  supabase.removeChannel(channelRef.current);
2923
2987
  }
2924
2988
  };
2925
- }, [supabase, workspaceId, date, shiftId, fetchMetrics, queueUpdate, setupSubscription, metricsTable, workspaceMetricsBaseTable, workspaceActionsTable, defaultTimezone, shiftConfig, schema, metricsTablePrefix]);
2989
+ }, [supabase, workspaceId, date, shiftId, lineId, fetchMetrics, queueUpdate, setupSubscription, metricsTable, workspaceMetricsBaseTable, workspaceActionsTable, defaultTimezone, shiftConfig, schema, metricsTablePrefix]);
2926
2990
  return {
2927
2991
  metrics: metrics2,
2928
2992
  isLoading,
@@ -3384,6 +3448,7 @@ var setCache = (lineId, metrics2) => {
3384
3448
  }
3385
3449
  };
3386
3450
  var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
3451
+ console.log("[useDashboardMetrics] Hook called with lineId:", lineId);
3387
3452
  const { supabaseUrl, supabaseKey } = useDashboardConfig();
3388
3453
  const entityConfig = useEntityConfig();
3389
3454
  const databaseConfig = useDatabaseConfig();
@@ -3427,14 +3492,33 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
3427
3492
  try {
3428
3493
  const currentShiftDetails = getCurrentShift(defaultTimezone, shiftConfig);
3429
3494
  const operationalDate = getOperationalDate(defaultTimezone);
3430
- const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ? [entityConfig.defaultLineId, entityConfig.secondaryLineId].filter((id3) => !!id3) : [currentLineIdToUse];
3495
+ const isFactoryView = currentLineIdToUse === (entityConfig.factoryViewId || "factory");
3496
+ const targetLineIds = isFactoryView ? [entityConfig.defaultLineId, entityConfig.secondaryLineId].filter((id3) => !!id3) : [currentLineIdToUse];
3497
+ console.log("[useDashboardMetrics] Target line IDs determined:", {
3498
+ currentLineIdToUse,
3499
+ isFactoryView,
3500
+ factoryViewId: entityConfig.factoryViewId,
3501
+ defaultLineId: entityConfig.defaultLineId,
3502
+ secondaryLineId: entityConfig.secondaryLineId,
3503
+ targetLineIds
3504
+ });
3431
3505
  if (targetLineIds.length === 0 && currentLineIdToUse === (entityConfig.factoryViewId || "factory")) {
3432
3506
  throw new Error("Factory view selected, but defaultLineId and/or secondaryLineId are not configured in entityConfig.");
3433
3507
  }
3434
3508
  if (targetLineIds.length === 0) {
3435
3509
  throw new Error("No target line IDs available for fetching metrics.");
3436
3510
  }
3511
+ console.log("[useDashboardMetrics] Executing workspace query with line IDs:", targetLineIds, "Date:", operationalDate, "ShiftID:", currentShiftDetails.shiftId, "Table:", companySpecificMetricsTable);
3437
3512
  const { data: workspaceData, error: workspaceError } = await supabase.from(companySpecificMetricsTable).select("company_id,line_id,shift_id,date,workspace_id,workspace_name,total_output,avg_pph,performance_score,avg_cycle_time,trend_score,ideal_output,efficiency,total_day_output").eq("date", operationalDate).eq("shift_id", currentShiftDetails.shiftId).in("line_id", targetLineIds);
3513
+ console.log("[useDashboardMetrics] Workspace query result:", {
3514
+ dataCount: workspaceData?.length || 0,
3515
+ error: workspaceError,
3516
+ sampleData: workspaceData?.slice(0, 3).map((w) => ({
3517
+ workspace_name: w.workspace_name,
3518
+ line_id: w.line_id,
3519
+ efficiency: w.efficiency
3520
+ }))
3521
+ });
3438
3522
  if (workspaceError) {
3439
3523
  throw workspaceError;
3440
3524
  }
@@ -4806,12 +4890,16 @@ function getCurrentLineIds() {
4806
4890
  try {
4807
4891
  const config = _getDashboardConfigInstance();
4808
4892
  const entityConfig = config?.entityConfig;
4893
+ console.log("\u{1F504} Dashboard config:", config);
4894
+ console.log("\u{1F504} Entity config:", entityConfig);
4809
4895
  const lineIds = [];
4810
4896
  if (entityConfig?.defaultLineId) {
4811
4897
  lineIds.push(entityConfig.defaultLineId);
4898
+ console.log("\u{1F504} Added defaultLineId:", entityConfig.defaultLineId);
4812
4899
  }
4813
4900
  if (entityConfig?.secondaryLineId) {
4814
4901
  lineIds.push(entityConfig.secondaryLineId);
4902
+ console.log("\u{1F504} Added secondaryLineId:", entityConfig.secondaryLineId);
4815
4903
  }
4816
4904
  console.log("\u{1F504} Current line IDs from config:", lineIds);
4817
4905
  return lineIds;
@@ -4829,15 +4917,22 @@ async function initializeWorkspaceDisplayNames(explicitLineId) {
4829
4917
  let targetLineIds = [];
4830
4918
  if (explicitLineId) {
4831
4919
  targetLineIds = [explicitLineId];
4920
+ console.log("\u{1F504} Using explicit lineId:", explicitLineId);
4832
4921
  } else {
4833
4922
  targetLineIds = getCurrentLineIds();
4923
+ console.log("\u{1F504} Using line IDs from config:", targetLineIds);
4834
4924
  }
4835
4925
  console.log("\u{1F504} Target line IDs for workspace filtering:", targetLineIds);
4836
4926
  const allDisplayNamesMap = /* @__PURE__ */ new Map();
4927
+ console.log("\u{1F504} About to fetch workspaces for lines:", targetLineIds);
4837
4928
  if (targetLineIds.length > 0) {
4838
4929
  for (const lineId of targetLineIds) {
4839
4930
  console.log(`\u{1F504} Fetching workspaces for line: ${lineId}`);
4840
4931
  const lineDisplayNamesMap = await workspaceService.getWorkspaceDisplayNames(void 0, lineId);
4932
+ console.log(
4933
+ `\u{1F504} Retrieved ${lineDisplayNamesMap.size} workspaces for line ${lineId}:`,
4934
+ Array.from(lineDisplayNamesMap.entries()).slice(0, 5)
4935
+ );
4841
4936
  lineDisplayNamesMap.forEach((displayName, workspaceId) => {
4842
4937
  allDisplayNamesMap.set(workspaceId, displayName);
4843
4938
  });
@@ -4849,6 +4944,7 @@ async function initializeWorkspaceDisplayNames(explicitLineId) {
4849
4944
  allDisplayNamesMap.set(workspaceId, displayName);
4850
4945
  });
4851
4946
  }
4947
+ console.log("\u{1F504} Final combined display names map size:", allDisplayNamesMap.size);
4852
4948
  runtimeWorkspaceDisplayNames = {};
4853
4949
  allDisplayNamesMap.forEach((displayName, workspaceId) => {
4854
4950
  runtimeWorkspaceDisplayNames[workspaceId] = displayName;
@@ -4876,6 +4972,7 @@ var forceRefreshWorkspaceDisplayNames = async (lineId) => {
4876
4972
  };
4877
4973
  console.log("\u{1F504} Module loaded, will initialize lazily when first function is called");
4878
4974
  var getWorkspaceDisplayName = (workspaceId, lineId) => {
4975
+ console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName called with:`, { workspaceId, lineId, isInitialized, isInitializing });
4879
4976
  if (!isInitialized && !isInitializing) {
4880
4977
  console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}) - Not initialized, triggering lazy init...`);
4881
4978
  } else if (isInitializing) {
@@ -4887,6 +4984,14 @@ var getWorkspaceDisplayName = (workspaceId, lineId) => {
4887
4984
  console.error("\u274C Lazy initialization failed:", error);
4888
4985
  });
4889
4986
  }
4987
+ if (lineId) {
4988
+ const lineSpecificKey = `${lineId}_${workspaceId}`;
4989
+ const lineSpecificDisplayName = runtimeWorkspaceDisplayNames[lineSpecificKey];
4990
+ if (lineSpecificDisplayName) {
4991
+ console.log(`getWorkspaceDisplayName(${workspaceId}, ${lineId}) -> ${lineSpecificDisplayName} (line-specific from Supabase)`);
4992
+ return lineSpecificDisplayName;
4993
+ }
4994
+ }
4890
4995
  const displayName = runtimeWorkspaceDisplayNames[workspaceId];
4891
4996
  if (displayName) {
4892
4997
  console.log(`getWorkspaceDisplayName(${workspaceId}) -> ${displayName} (from Supabase)`);
@@ -4907,6 +5012,14 @@ var getShortWorkspaceDisplayName = (workspaceId, lineId) => {
4907
5012
  console.error("\u274C Lazy initialization failed:", error);
4908
5013
  });
4909
5014
  }
5015
+ if (lineId) {
5016
+ const lineSpecificKey = `${lineId}_${workspaceId}`;
5017
+ const lineSpecificDisplayName = runtimeWorkspaceDisplayNames[lineSpecificKey];
5018
+ if (lineSpecificDisplayName) {
5019
+ console.log(`getShortWorkspaceDisplayName(${workspaceId}, ${lineId}) -> ${lineSpecificDisplayName} (line-specific from Supabase)`);
5020
+ return lineSpecificDisplayName;
5021
+ }
5022
+ }
4910
5023
  const displayName = runtimeWorkspaceDisplayNames[workspaceId];
4911
5024
  if (displayName) {
4912
5025
  console.log(`getShortWorkspaceDisplayName(${workspaceId}) -> ${displayName} (from Supabase)`);
@@ -7981,18 +8094,36 @@ function cn(...inputs) {
7981
8094
  }
7982
8095
 
7983
8096
  // src/lib/utils/urlMapping.ts
7984
- var toUrlFriendlyName = (workspaceName) => {
8097
+ var toUrlFriendlyName = (workspaceName, lineId) => {
7985
8098
  if (!workspaceName) throw new Error("Workspace name is required");
7986
- return workspaceName.toLowerCase().replace(/\s+/g, "-");
8099
+ const baseName = workspaceName.toLowerCase().replace(/\s+/g, "-");
8100
+ return lineId ? `${lineId}-${baseName}` : baseName;
8101
+ };
8102
+ var fromUrlFriendlyName = (urlName) => {
8103
+ const parts = urlName.split("-");
8104
+ if (parts.length >= 2 && (parts[0].startsWith("line") || parts[0].length === 36)) {
8105
+ return {
8106
+ lineId: parts[0],
8107
+ workspaceName: parts.slice(1).join("-").toUpperCase()
8108
+ };
8109
+ }
8110
+ return { workspaceName: urlName.toUpperCase() };
7987
8111
  };
7988
- var fromUrlFriendlyName = (urlName) => urlName.toUpperCase();
7989
8112
  var storeWorkspaceMapping = (mapping) => {
7990
8113
  const mappings = getStoredWorkspaceMappings();
7991
- mappings[mapping.urlName] = mapping;
8114
+ const key = mapping.lineId ? `${mapping.lineId}_${mapping.urlName}` : mapping.urlName;
8115
+ mappings[key] = mapping;
7992
8116
  sessionStorage.setItem("workspaceMappings", JSON.stringify(mappings));
7993
8117
  };
7994
- var getWorkspaceFromUrl = (urlName) => {
8118
+ var getWorkspaceFromUrl = (urlName, lineId) => {
7995
8119
  const mappings = getStoredWorkspaceMappings();
8120
+ if (lineId) {
8121
+ const lineSpecificKey = `${lineId}_${urlName}`;
8122
+ const lineSpecificMapping = mappings[lineSpecificKey];
8123
+ if (lineSpecificMapping) {
8124
+ return lineSpecificMapping;
8125
+ }
8126
+ }
7996
8127
  return mappings[urlName] || null;
7997
8128
  };
7998
8129
  var getStoredWorkspaceMappings = () => {
@@ -8003,6 +8134,26 @@ var getStoredWorkspaceMappings = () => {
8003
8134
  return {};
8004
8135
  }
8005
8136
  };
8137
+ var getWorkspaceMappingsForLine = (lineId) => {
8138
+ const allMappings = getStoredWorkspaceMappings();
8139
+ const lineMappings = {};
8140
+ Object.entries(allMappings).forEach(([key, mapping]) => {
8141
+ if (mapping.lineId === lineId) {
8142
+ lineMappings[key] = mapping;
8143
+ }
8144
+ });
8145
+ return lineMappings;
8146
+ };
8147
+ var clearWorkspaceMappingsForLine = (lineId) => {
8148
+ const allMappings = getStoredWorkspaceMappings();
8149
+ const filteredMappings = {};
8150
+ Object.entries(allMappings).forEach(([key, mapping]) => {
8151
+ if (mapping.lineId !== lineId) {
8152
+ filteredMappings[key] = mapping;
8153
+ }
8154
+ });
8155
+ sessionStorage.setItem("workspaceMappings", JSON.stringify(filteredMappings));
8156
+ };
8006
8157
 
8007
8158
  // src/lib/utils/workspacePreferences.ts
8008
8159
  var getDefaultTabForWorkspace = (workspaceId, displayName) => {
@@ -17497,6 +17648,7 @@ var VideoCard = React14__namespace.default.memo(({
17497
17648
  });
17498
17649
  VideoCard.displayName = "VideoCard";
17499
17650
  var DEFAULT_WORKSPACE_HLS_URLS = {
17651
+ // Line-agnostic fallbacks
17500
17652
  "WS1": "https://dnh-hls.optifye.ai/cam1/index.m3u8",
17501
17653
  "WS2": "https://dnh-hls.optifye.ai/cam2/index.m3u8",
17502
17654
  "WS3": "https://dnh-hls.optifye.ai/cam3/index.m3u8",
@@ -17507,6 +17659,9 @@ var DEFAULT_WORKSPACE_HLS_URLS = {
17507
17659
  "WS04": "https://59.144.218.58:8443/camera4.m3u8",
17508
17660
  "WS05": "https://59.144.218.58:8443/camera1.m3u8",
17509
17661
  "WS06": "https://59.144.218.58:8443/camera5.m3u8"
17662
+ // Line-specific mappings (line_id_workspaceName format)
17663
+ // Example: '98a2287e-8d55-4020-b00d-b9940437e3e1_WS1': 'https://line1-hls.optifye.ai/cam1/index.m3u8',
17664
+ // Example: 'd93997bb-ecac-4478-a4a6-008d536b724c_WS1': 'https://line2-hls.optifye.ai/cam1/index.m3u8',
17510
17665
  };
17511
17666
  var DEFAULT_HLS_URL = "https://192.168.5.9:8443/cam1.m3u8";
17512
17667
  var VideoGridView = React14__namespace.default.memo(({
@@ -17514,7 +17669,8 @@ var VideoGridView = React14__namespace.default.memo(({
17514
17669
  selectedLine,
17515
17670
  className = "",
17516
17671
  lineIdMapping = {},
17517
- videoSources = {}
17672
+ videoSources = {},
17673
+ targetLineId
17518
17674
  }) => {
17519
17675
  const router$1 = router.useRouter();
17520
17676
  const containerRef = React14.useRef(null);
@@ -17522,14 +17678,38 @@ var VideoGridView = React14__namespace.default.memo(({
17522
17678
  const [gridCols, setGridCols] = React14.useState(4);
17523
17679
  const [visibleWorkspaces, setVisibleWorkspaces] = React14.useState(/* @__PURE__ */ new Set());
17524
17680
  const videoConfig = useVideoConfig();
17681
+ const entityConfig = useEntityConfig();
17525
17682
  const { cropping, canvasConfig } = videoConfig;
17683
+ const defaultLineId = entityConfig.defaultLineId;
17684
+ const secondaryLineId = entityConfig.secondaryLineId;
17685
+ console.log("[VideoGridView] Line configuration:", {
17686
+ defaultLineId,
17687
+ secondaryLineId,
17688
+ selectedLine,
17689
+ targetLineId,
17690
+ totalWorkspaces: workspaces.length
17691
+ });
17526
17692
  const mergedVideoSources = {
17527
17693
  defaultHlsUrl: videoSources.defaultHlsUrl || DEFAULT_HLS_URL,
17528
17694
  workspaceHlsUrls: { ...DEFAULT_WORKSPACE_HLS_URLS, ...videoSources.workspaceHlsUrls }
17529
17695
  };
17530
- const getWorkspaceHlsUrl = React14.useCallback((workspaceName) => {
17696
+ const getWorkspaceHlsUrl = React14.useCallback((workspaceName, lineId) => {
17531
17697
  const wsName = workspaceName.toUpperCase();
17532
- return mergedVideoSources.workspaceHlsUrls[wsName] || mergedVideoSources.defaultHlsUrl;
17698
+ if (lineId) {
17699
+ const lineSpecificKey = `${lineId}_${wsName}`;
17700
+ const lineSpecificUrl = mergedVideoSources.workspaceHlsUrls[lineSpecificKey];
17701
+ console.log(`[VideoGridView] HLS URL lookup for ${wsName} (line: ${lineId}):`, {
17702
+ lineSpecificKey,
17703
+ lineSpecificUrl,
17704
+ fallbackUrl: mergedVideoSources.workspaceHlsUrls[wsName] || mergedVideoSources.defaultHlsUrl
17705
+ });
17706
+ if (lineSpecificUrl) {
17707
+ return lineSpecificUrl;
17708
+ }
17709
+ }
17710
+ const fallbackUrl = mergedVideoSources.workspaceHlsUrls[wsName] || mergedVideoSources.defaultHlsUrl;
17711
+ console.log(`[VideoGridView] HLS URL fallback for ${wsName}:`, fallbackUrl);
17712
+ return fallbackUrl;
17533
17713
  }, [mergedVideoSources]);
17534
17714
  const getWorkspaceCropping = React14.useCallback((workspaceName) => {
17535
17715
  if (!cropping) return void 0;
@@ -17544,26 +17724,70 @@ var VideoGridView = React14__namespace.default.memo(({
17544
17724
  );
17545
17725
  }, [workspaces]);
17546
17726
  const filteredWorkspaces = React14.useMemo(() => {
17547
- return selectedLine === 1 ? workspaces.filter((w) => {
17548
- if (w.workspace_name === "WS5-5") return true;
17549
- if (w.workspace_name === "WS32-5") return false;
17550
- try {
17551
- const wsNumber = parseInt(w.workspace_name.replace("WS", ""));
17552
- return wsNumber >= 1 && wsNumber <= 22;
17553
- } catch {
17554
- return true;
17555
- }
17556
- }) : selectedLine === 2 ? workspaces.filter((w) => {
17557
- if (w.workspace_name === "WS5-5") return false;
17558
- if (w.workspace_name === "WS32-5") return true;
17559
- try {
17560
- const wsNumber = parseInt(w.workspace_name.replace("WS", ""));
17561
- return wsNumber >= 23 && wsNumber <= 44;
17562
- } catch {
17563
- return false;
17564
- }
17565
- }) : workspaces;
17566
- }, [workspaces, selectedLine]);
17727
+ const uniqueLineIds = [...new Set(workspaces.map((w) => w.line_id))];
17728
+ console.log("[VideoGridView] Filtering workspaces:", {
17729
+ totalWorkspaces: workspaces.length,
17730
+ targetLineId,
17731
+ selectedLine,
17732
+ defaultLineId,
17733
+ secondaryLineId,
17734
+ uniqueLineIds,
17735
+ workspacesByLine: workspaces.reduce((acc, w) => {
17736
+ acc[w.line_id] = (acc[w.line_id] || 0) + 1;
17737
+ return acc;
17738
+ }, {})
17739
+ });
17740
+ console.log("[VideoGridView] Sample workspaces with line_id:", workspaces.slice(0, 5).map((w) => ({
17741
+ workspace_name: w.workspace_name,
17742
+ line_id: w.line_id,
17743
+ workspace_uuid: w.workspace_uuid
17744
+ })));
17745
+ if (targetLineId) {
17746
+ const filtered = workspaces.filter((w) => w.line_id === targetLineId);
17747
+ console.log(`[VideoGridView] Filtered by targetLineId (${targetLineId}):`, filtered.length, "workspaces");
17748
+ return filtered;
17749
+ }
17750
+ if (selectedLine === 1 && defaultLineId) {
17751
+ const filtered = workspaces.filter((w) => w.line_id === defaultLineId);
17752
+ console.log(`[VideoGridView] Filtered by selectedLine=1 (${defaultLineId}):`, filtered.length, "workspaces");
17753
+ return filtered;
17754
+ }
17755
+ if (selectedLine === 2 && secondaryLineId) {
17756
+ const filtered = workspaces.filter((w) => w.line_id === secondaryLineId);
17757
+ console.log(`[VideoGridView] Filtered by selectedLine=2 (${secondaryLineId}):`, filtered.length, "workspaces");
17758
+ return filtered;
17759
+ }
17760
+ if (selectedLine === 1) {
17761
+ const filtered = workspaces.filter((w) => {
17762
+ if (w.workspace_name === "WS5-5") return true;
17763
+ if (w.workspace_name === "WS32-5") return false;
17764
+ try {
17765
+ const wsNumber = parseInt(w.workspace_name.replace("WS", ""));
17766
+ return wsNumber >= 1 && wsNumber <= 22;
17767
+ } catch {
17768
+ return true;
17769
+ }
17770
+ });
17771
+ console.log(`[VideoGridView] Legacy filtered by selectedLine=1 (WS1-WS22):`, filtered.length, "workspaces");
17772
+ return filtered;
17773
+ }
17774
+ if (selectedLine === 2) {
17775
+ const filtered = workspaces.filter((w) => {
17776
+ if (w.workspace_name === "WS5-5") return false;
17777
+ if (w.workspace_name === "WS32-5") return true;
17778
+ try {
17779
+ const wsNumber = parseInt(w.workspace_name.replace("WS", ""));
17780
+ return wsNumber >= 23 && wsNumber <= 44;
17781
+ } catch {
17782
+ return false;
17783
+ }
17784
+ });
17785
+ console.log(`[VideoGridView] Legacy filtered by selectedLine=2 (WS23-WS44):`, filtered.length, "workspaces");
17786
+ return filtered;
17787
+ }
17788
+ console.log(`[VideoGridView] No filtering applied, returning all workspaces:`, workspaces.length);
17789
+ return workspaces;
17790
+ }, [workspaces, selectedLine, targetLineId, defaultLineId, secondaryLineId]);
17567
17791
  const calculateOptimalGrid = React14.useCallback(() => {
17568
17792
  if (!containerRef.current) return;
17569
17793
  const containerPadding = 16;
@@ -17640,6 +17864,12 @@ var VideoGridView = React14__namespace.default.memo(({
17640
17864
  }, [filteredWorkspaces]);
17641
17865
  const handleWorkspaceClick = React14.useCallback((workspace) => {
17642
17866
  const workspaceId = workspace.workspace_uuid || workspace.workspace_name;
17867
+ console.log("[VideoGridView] Workspace clicked:", {
17868
+ workspace_name: workspace.workspace_name,
17869
+ workspace_id: workspaceId,
17870
+ line_id: workspace.line_id,
17871
+ efficiency: workspace.efficiency
17872
+ });
17643
17873
  trackCoreEvent("Workspace Detail Clicked", {
17644
17874
  workspace_name: workspace.workspace_name,
17645
17875
  workspace_id: workspaceId,
@@ -17648,8 +17878,15 @@ var VideoGridView = React14__namespace.default.memo(({
17648
17878
  efficiency: workspace.efficiency,
17649
17879
  action_count: workspace.action_count
17650
17880
  });
17651
- const displayName = getWorkspaceDisplayName(workspace.workspace_name);
17881
+ const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
17652
17882
  const navParams = getWorkspaceNavigationParams(workspaceId, displayName);
17883
+ console.log("[VideoGridView] Navigation params:", {
17884
+ workspaceId,
17885
+ displayName,
17886
+ line_id: workspace.line_id,
17887
+ navParams,
17888
+ finalUrl: `/workspace/${workspaceId}${navParams}`
17889
+ });
17653
17890
  router$1.push(`/workspace/${workspaceId}${navParams}`);
17654
17891
  }, [router$1]);
17655
17892
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `relative overflow-hidden h-full w-full ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "h-full w-full p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -17662,15 +17899,22 @@ var VideoGridView = React14__namespace.default.memo(({
17662
17899
  minHeight: "100%"
17663
17900
  },
17664
17901
  children: filteredWorkspaces.sort((a, b) => {
17665
- const aNum = parseInt(a.workspace_name.slice(2));
17666
- const bNum = parseInt(b.workspace_name.slice(2));
17667
- if (!selectedLine) {
17668
- const aIsLine2 = a.line_id === lineIdMapping.line2;
17669
- const bIsLine2 = b.line_id === lineIdMapping.line2;
17670
- if (aIsLine2 !== bIsLine2) {
17671
- return aIsLine2 ? 1 : -1;
17902
+ if (!targetLineId && !selectedLine) {
17903
+ const aIsSecondaryLine = secondaryLineId && a.line_id === secondaryLineId;
17904
+ const bIsSecondaryLine = secondaryLineId && b.line_id === secondaryLineId;
17905
+ if (aIsSecondaryLine !== bIsSecondaryLine) {
17906
+ return aIsSecondaryLine ? 1 : -1;
17907
+ }
17908
+ if (!secondaryLineId && lineIdMapping.line2) {
17909
+ const aIsLine2 = a.line_id === lineIdMapping.line2;
17910
+ const bIsLine2 = b.line_id === lineIdMapping.line2;
17911
+ if (aIsLine2 !== bIsLine2) {
17912
+ return aIsLine2 ? 1 : -1;
17913
+ }
17672
17914
  }
17673
17915
  }
17916
+ const aNum = parseInt(a.workspace_name.slice(2));
17917
+ const bNum = parseInt(b.workspace_name.slice(2));
17674
17918
  return aNum - bNum;
17675
17919
  }).map((workspace) => {
17676
17920
  const workspaceId = workspace.workspace_uuid || workspace.workspace_name;
@@ -17687,7 +17931,7 @@ var VideoGridView = React14__namespace.default.memo(({
17687
17931
  VideoCard,
17688
17932
  {
17689
17933
  workspace,
17690
- hlsUrl: getWorkspaceHlsUrl(workspace.workspace_name),
17934
+ hlsUrl: getWorkspaceHlsUrl(workspace.workspace_name, workspace.line_id),
17691
17935
  shouldPlay: isVisible,
17692
17936
  onClick: () => handleWorkspaceClick(workspace),
17693
17937
  onFatalError: throttledReloadDashboard,
@@ -21331,6 +21575,14 @@ function parseS3Uri(s3Uri) {
21331
21575
  severity = "high";
21332
21576
  description = "Worst Cycle Time Performance";
21333
21577
  break;
21578
+ case "cycle_completions":
21579
+ case "cycle_completion":
21580
+ case "completed_cycles":
21581
+ case "completed_cycle":
21582
+ type = "cycle_completions";
21583
+ severity = "low";
21584
+ description = "Cycle Completion";
21585
+ break;
21334
21586
  case "medium_bottleneck":
21335
21587
  severity = "medium";
21336
21588
  description = "Medium Bottleneck Identified";
@@ -21357,6 +21609,10 @@ function parseS3Uri(s3Uri) {
21357
21609
  type = "bottleneck";
21358
21610
  severity = "high";
21359
21611
  description = "Long Cycle Time Detected";
21612
+ } else if (normalizedViolationType.includes("cycle") && (normalizedViolationType.includes("completion") || normalizedViolationType.includes("complete"))) {
21613
+ type = "cycle_completions";
21614
+ severity = "low";
21615
+ description = "Cycle Completion";
21360
21616
  } else {
21361
21617
  description = `Clip type: ${violationType.replace(/_/g, " ")}`;
21362
21618
  console.log(`Detected unknown violation type: ${violationType} in URI: ${s3Uri}`);
@@ -21536,7 +21792,7 @@ var S3ClipsService = class {
21536
21792
  }
21537
21793
  let cycleTimeSeconds = null;
21538
21794
  let creationTimestamp = void 0;
21539
- if (includeMetadata || includeCycleTime && (parsedInfo.type === "bottleneck" && parsedInfo.description.toLowerCase().includes("cycle time") || parsedInfo.type === "best_cycle_time" || parsedInfo.type === "worst_cycle_time")) {
21795
+ if (includeMetadata || includeCycleTime && (parsedInfo.type === "bottleneck" && parsedInfo.description.toLowerCase().includes("cycle time") || parsedInfo.type === "best_cycle_time" || parsedInfo.type === "worst_cycle_time" || parsedInfo.type === "cycle_completions")) {
21540
21796
  const metadata = await this.getFullMetadata(uri);
21541
21797
  if (metadata) {
21542
21798
  if (metadata.original_task_metadata?.cycle_time) {
@@ -21569,6 +21825,7 @@ var S3ClipsService = class {
21569
21825
  low_value: 0,
21570
21826
  long_cycle_time: 0,
21571
21827
  missing_quality_check: 0,
21828
+ cycle_completions: 0,
21572
21829
  total: 0
21573
21830
  };
21574
21831
  const samples = {
@@ -21577,7 +21834,8 @@ var S3ClipsService = class {
21577
21834
  bottleneck: null,
21578
21835
  low_value: null,
21579
21836
  long_cycle_time: null,
21580
- missing_quality_check: null
21837
+ missing_quality_check: null,
21838
+ cycle_completions: null
21581
21839
  };
21582
21840
  for (const uri of s3Uris) {
21583
21841
  const parsedInfo = parseS3Uri(uri);
@@ -21865,6 +22123,7 @@ var BottlenecksContent = ({
21865
22123
  const firstBestCycle = videos.find((v) => v.type === "best_cycle_time");
21866
22124
  const firstWorstCycle = videos.find((v) => v.type === "worst_cycle_time");
21867
22125
  const firstSOPDeviation = videos.find((v) => v.type === "missing_quality_check");
22126
+ const firstCycleCompletion = videos.find((v) => v.type === "cycle_completions");
21868
22127
  preloadVideosUrl2([
21869
22128
  firstHigh?.src,
21870
22129
  firstMed?.src,
@@ -21872,7 +22131,8 @@ var BottlenecksContent = ({
21872
22131
  firstLowValue?.src,
21873
22132
  firstBestCycle?.src,
21874
22133
  firstWorstCycle?.src,
21875
- firstSOPDeviation?.src
22134
+ firstSOPDeviation?.src,
22135
+ firstCycleCompletion?.src
21876
22136
  ].filter(Boolean));
21877
22137
  }
21878
22138
  setAllVideos(videos);
@@ -21896,6 +22156,7 @@ var BottlenecksContent = ({
21896
22156
  if (activeFilter === "sop_deviations") return video.type === "missing_quality_check";
21897
22157
  if (activeFilter === "best_cycle_time") return video.type === "best_cycle_time";
21898
22158
  if (activeFilter === "worst_cycle_time") return video.type === "worst_cycle_time";
22159
+ if (activeFilter === "cycle_completions") return video.type === "cycle_completions";
21899
22160
  if (activeFilter === "long_cycle_time") {
21900
22161
  return video.type === "bottleneck" && video.description.toLowerCase().includes("cycle time");
21901
22162
  }
@@ -21918,6 +22179,8 @@ var BottlenecksContent = ({
21918
22179
  filtered = allVideos.filter((video) => video.type === "best_cycle_time");
21919
22180
  } else if (activeFilter === "worst_cycle_time") {
21920
22181
  filtered = allVideos.filter((video) => video.type === "worst_cycle_time");
22182
+ } else if (activeFilter === "cycle_completions") {
22183
+ filtered = allVideos.filter((video) => video.type === "cycle_completions");
21921
22184
  } else if (activeFilter === "long_cycle_time") {
21922
22185
  filtered = allVideos.filter(
21923
22186
  (video) => video.type === "bottleneck" && video.description.toLowerCase().includes("cycle time")
@@ -22212,6 +22475,7 @@ var BottlenecksContent = ({
22212
22475
  bestCycleTimes: 0,
22213
22476
  worstCycleTimes: 0,
22214
22477
  longCycleTimes: 0,
22478
+ cycleCompletions: 0,
22215
22479
  total: 0
22216
22480
  };
22217
22481
  return {
@@ -22226,6 +22490,7 @@ var BottlenecksContent = ({
22226
22490
  longCycleTimes: allVideos.filter(
22227
22491
  (video) => video.type === "bottleneck" && video.description.toLowerCase().includes("cycle time")
22228
22492
  ).length,
22493
+ cycleCompletions: allVideos.filter((video) => video.type === "cycle_completions").length,
22229
22494
  total: allVideos.length
22230
22495
  };
22231
22496
  }, [allVideos]);
@@ -22246,6 +22511,8 @@ var BottlenecksContent = ({
22246
22511
  return "Best Cycle Time";
22247
22512
  case "worst_cycle_time":
22248
22513
  return "Worst Cycle Time";
22514
+ case "cycle_completions":
22515
+ return "Cycle Completion";
22249
22516
  case "bottleneck":
22250
22517
  default:
22251
22518
  return "Bottleneck";
@@ -22281,7 +22548,7 @@ var BottlenecksContent = ({
22281
22548
  ] });
22282
22549
  }
22283
22550
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-grow p-1.5 sm:p-2 lg:p-4 h-[calc(100vh-12rem)]", children: [
22284
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 mb-4", children: [
22551
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-3 mb-4", children: [
22285
22552
  /* @__PURE__ */ jsxRuntime.jsxs(
22286
22553
  Card2,
22287
22554
  {
@@ -22401,11 +22668,41 @@ var BottlenecksContent = ({
22401
22668
  ] }) })
22402
22669
  ]
22403
22670
  }
22671
+ ),
22672
+ /* @__PURE__ */ jsxRuntime.jsxs(
22673
+ Card2,
22674
+ {
22675
+ onClick: () => {
22676
+ setActiveFilter("cycle_completions");
22677
+ trackCoreEvent("Cycle Completions Filter Clicked", {
22678
+ workspaceId,
22679
+ workspaceName,
22680
+ date,
22681
+ filterType: "cycle_completions",
22682
+ clipCount: clipCounts.cycleCompletions
22683
+ });
22684
+ },
22685
+ className: `bg-white shadow-sm cursor-pointer transition-all duration-200 hover:bg-gray-50 ${activeFilter === "cycle_completions" ? "bg-blue-50 shadow-md ring-1 ring-blue-200" : ""}`,
22686
+ "aria-label": `Filter by Cycle Completions (${clipCounts.cycleCompletions} clips)`,
22687
+ role: "button",
22688
+ tabIndex: 0,
22689
+ onKeyDown: (e) => e.key === "Enter" && setActiveFilter("cycle_completions"),
22690
+ children: [
22691
+ /* @__PURE__ */ jsxRuntime.jsx(CardHeader2, { className: "pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(CardTitle2, { className: `text-lg ${activeFilter === "cycle_completions" ? "text-blue-600" : ""}`, children: "Cycle Completions" }) }),
22692
+ /* @__PURE__ */ jsxRuntime.jsx(CardContent2, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-center", children: [
22693
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-3xl font-bold text-blue-600", children: clipCounts.cycleCompletions }),
22694
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center text-sm text-gray-500 mt-1", children: [
22695
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-blue-600 mr-1.5" }),
22696
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Completed production cycles" })
22697
+ ] })
22698
+ ] }) })
22699
+ ]
22700
+ }
22404
22701
  )
22405
22702
  ] }),
22406
22703
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-lg shadow-sm overflow-hidden", style: { height: "calc(100% - 8.5rem)" }, children: [
22407
22704
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3 border-b border-gray-100", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
22408
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-800", children: activeFilter === "low_value" ? `Idle Moments (${clipCounts.lowValue})` : activeFilter === "best_cycle_time" ? `Best Cycle Time (${clipCounts.bestCycleTimes})` : activeFilter === "worst_cycle_time" ? `Worst Cycle Time (${clipCounts.worstCycleTimes})` : activeFilter === "long_cycle_time" ? `Long Cycle Time (${clipCounts.longCycleTimes})` : `All Clips (${clipCounts.total})` }),
22705
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-800", children: activeFilter === "low_value" ? `Idle Moments (${clipCounts.lowValue})` : activeFilter === "best_cycle_time" ? `Best Cycle Time (${clipCounts.bestCycleTimes})` : activeFilter === "worst_cycle_time" ? `Worst Cycle Time (${clipCounts.worstCycleTimes})` : activeFilter === "long_cycle_time" ? `Long Cycle Time (${clipCounts.longCycleTimes})` : activeFilter === "cycle_completions" ? `Cycle Completions (${clipCounts.cycleCompletions})` : `All Clips (${clipCounts.total})` }),
22409
22706
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
22410
22707
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", ref: timestampFilterRef, children: [
22411
22708
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -22560,9 +22857,9 @@ var BottlenecksContent = ({
22560
22857
  }
22561
22858
  )
22562
22859
  ] }) }),
22563
- (currentVideo.type === "best_cycle_time" || currentVideo.type === "worst_cycle_time" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds || currentVideo.type === "low_value" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-3 left-3 z-10 bg-black/60 backdrop-blur-sm px-3 py-1.5 rounded-lg text-white shadow-lg text-xs", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
22564
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 rounded-full ${currentVideo.type === "low_value" ? "bg-purple-400" : currentVideo.type === "best_cycle_time" ? "bg-green-600" : currentVideo.type === "worst_cycle_time" ? "bg-red-700" : "bg-red-500"} mr-2 animate-pulse` }),
22565
- (currentVideo.type === "best_cycle_time" || currentVideo.type === "worst_cycle_time" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "opacity-90 font-mono bg-black/30 px-2 py-0.5 rounded", children: [
22860
+ (currentVideo.type === "best_cycle_time" || currentVideo.type === "worst_cycle_time" || currentVideo.type === "cycle_completions" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds || currentVideo.type === "low_value" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-3 left-3 z-10 bg-black/60 backdrop-blur-sm px-3 py-1.5 rounded-lg text-white shadow-lg text-xs", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
22861
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 rounded-full ${currentVideo.type === "low_value" ? "bg-purple-400" : currentVideo.type === "best_cycle_time" ? "bg-green-600" : currentVideo.type === "worst_cycle_time" ? "bg-red-700" : currentVideo.type === "cycle_completions" ? "bg-blue-600" : "bg-red-500"} mr-2 animate-pulse` }),
22862
+ (currentVideo.type === "best_cycle_time" || currentVideo.type === "worst_cycle_time" || currentVideo.type === "cycle_completions" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "opacity-90 font-mono bg-black/30 px-2 py-0.5 rounded", children: [
22566
22863
  "Cycle time: ",
22567
22864
  (currentVideo.cycle_time_seconds / 20).toFixed(1),
22568
22865
  "s"
@@ -22644,9 +22941,9 @@ var BottlenecksContent = ({
22644
22941
  children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
22645
22942
  }
22646
22943
  ),
22647
- (currentVideo.type === "best_cycle_time" || currentVideo.type === "worst_cycle_time" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds || currentVideo.type === "low_value" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-4 left-4 z-[101] bg-black/60 backdrop-blur-sm px-4 py-2 rounded-lg text-white shadow-lg text-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
22648
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 rounded-full ${currentVideo.type === "low_value" ? "bg-purple-400" : currentVideo.type === "best_cycle_time" ? "bg-green-600" : currentVideo.type === "worst_cycle_time" ? "bg-red-700" : "bg-red-500"} mr-2` }),
22649
- (currentVideo.type === "best_cycle_time" || currentVideo.type === "worst_cycle_time" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "opacity-90 font-mono bg-black/30 px-2 py-1 rounded", children: [
22944
+ (currentVideo.type === "best_cycle_time" || currentVideo.type === "worst_cycle_time" || currentVideo.type === "cycle_completions" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds || currentVideo.type === "low_value" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-4 left-4 z-[101] bg-black/60 backdrop-blur-sm px-4 py-2 rounded-lg text-white shadow-lg text-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
22945
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 rounded-full ${currentVideo.type === "low_value" ? "bg-purple-400" : currentVideo.type === "best_cycle_time" ? "bg-green-600" : currentVideo.type === "worst_cycle_time" ? "bg-red-700" : currentVideo.type === "cycle_completions" ? "bg-blue-600" : "bg-red-500"} mr-2` }),
22946
+ (currentVideo.type === "best_cycle_time" || currentVideo.type === "worst_cycle_time" || currentVideo.type === "cycle_completions" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "opacity-90 font-mono bg-black/30 px-2 py-1 rounded", children: [
22650
22947
  "Cycle time: ",
22651
22948
  (currentVideo.cycle_time_seconds / 20).toFixed(1),
22652
22949
  "s"
@@ -24456,6 +24753,7 @@ var AIAgentView = () => {
24456
24753
  const entityConfig = useEntityConfig();
24457
24754
  const dateTimeConfig = useDateTimeConfig();
24458
24755
  const shiftConfig = useShiftConfig();
24756
+ const { formatNumber } = useFormatNumber();
24459
24757
  const [inputValue, setInputValue] = React14.useState("");
24460
24758
  const [loadingThreads, setLoadingThreads] = React14.useState(/* @__PURE__ */ new Set());
24461
24759
  const [lastError, setLastError] = React14.useState(null);
@@ -25282,71 +25580,184 @@ var AIAgentView = () => {
25282
25580
  };
25283
25581
  const renderChart = (chartType, args, key) => {
25284
25582
  console.log(`[DEBUG] Attempting to render chart type: ${chartType}`, args);
25583
+ const CHART_COLORS = {
25584
+ primary: "#3b82f6",
25585
+ // blue-500
25586
+ secondary: "#10b981",
25587
+ // green-500
25588
+ accent: "#f59e0b",
25589
+ // amber-500
25590
+ danger: "#ef4444",
25591
+ // red-500
25592
+ violet: "#8b5cf6",
25593
+ // violet-500
25594
+ cyan: "#06b6d4",
25595
+ // cyan-500
25596
+ orange: "#f97316",
25597
+ // orange-500
25598
+ indigo: "#6366f1"
25599
+ // indigo-500
25600
+ };
25601
+ const CHART_COLOR_PALETTE = Object.values(CHART_COLORS);
25602
+ const CHART_STYLES = {
25603
+ grid: {
25604
+ strokeDasharray: "3 3",
25605
+ stroke: "#e5e7eb"
25606
+ // gray-300
25607
+ },
25608
+ axis: {
25609
+ tick: { fontSize: 12, fill: "#4b5563" },
25610
+ // gray-600
25611
+ stroke: "#9ca3af"
25612
+ // gray-400
25613
+ },
25614
+ margin: { top: 10, right: 30, left: 20, bottom: 40 },
25615
+ barRadius: [4, 4, 0, 0]
25616
+ // Top corners rounded
25617
+ };
25618
+ const CustomTooltip = ({ active, payload, label }) => {
25619
+ if (active && payload && payload.length) {
25620
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white px-4 py-3 shadow-lg rounded-lg border border-gray-200", children: [
25621
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 mb-1", children: label }),
25622
+ payload.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-600", style: { color: entry.color }, children: [
25623
+ entry.name,
25624
+ ": ",
25625
+ typeof entry.value === "number" ? formatNumber(entry.value) : entry.value,
25626
+ args.unit || ""
25627
+ ] }, index))
25628
+ ] });
25629
+ }
25630
+ return null;
25631
+ };
25632
+ const DualAxisTooltip = ({ active, payload, label }) => {
25633
+ if (active && payload && payload.length) {
25634
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white px-4 py-3 shadow-lg rounded-lg border border-gray-200", children: [
25635
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 mb-2", children: label }),
25636
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: payload.map((entry, index) => {
25637
+ const value = typeof entry.value === "number" ? formatNumber(entry.value) : entry.value;
25638
+ const unit = entry.dataKey === args.left_y_field ? args.left_unit || "" : entry.dataKey === args.right_y_field ? args.right_unit || "" : "";
25639
+ return /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm", style: { color: entry.color }, children: [
25640
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
25641
+ entry.name,
25642
+ ":"
25643
+ ] }),
25644
+ " ",
25645
+ value,
25646
+ unit
25647
+ ] }, index);
25648
+ }) })
25649
+ ] });
25650
+ }
25651
+ return null;
25652
+ };
25653
+ const formatXAxisTick = (value) => {
25654
+ if (typeof value === "string") {
25655
+ if (value.match(/^\d{2}\/\d{2}\s/)) {
25656
+ return value;
25657
+ }
25658
+ if (value.length > 15) {
25659
+ return value.substring(0, 12) + "...";
25660
+ }
25661
+ }
25662
+ return value;
25663
+ };
25664
+ const ChartWrapper = ({ children, title }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 bg-white rounded-xl shadow-sm border border-gray-200 p-6", children: [
25665
+ title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold text-gray-900 mb-4", children: title }),
25666
+ children
25667
+ ] });
25285
25668
  switch (chartType) {
25286
25669
  case "create_gauge_chart":
25287
25670
  console.log("[DEBUG] Rendering gauge chart");
25288
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-6 h-64 w-full flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
25671
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-64 w-full flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
25289
25672
  GaugeChart,
25290
25673
  {
25291
25674
  value: args.value || 0,
25292
25675
  min: args.min_value || 0,
25293
25676
  max: args.max_value || 100,
25294
25677
  target: args.target,
25295
- label: args.title || "",
25678
+ label: args.label || "",
25296
25679
  unit: args.unit || "",
25297
25680
  thresholds: args.thresholds,
25298
25681
  className: "w-full max-w-sm"
25299
25682
  }
25300
- ) }, `gauge-${key}`);
25683
+ ) }) }, `gauge-${key}`);
25301
25684
  case "create_bar_chart":
25302
25685
  console.log("[DEBUG] Rendering bar chart");
25303
25686
  if (!args.data || !args.x_field || !args.y_field) {
25304
25687
  console.error("Bar chart missing required parameters:", { data: !!args.data, x_field: !!args.x_field, y_field: !!args.y_field });
25305
25688
  return null;
25306
25689
  }
25307
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", style: { maxWidth: args.max_width || "100%" }, children: [
25690
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-64", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data: args.data, margin: CHART_STYLES.margin, children: [
25691
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
25308
25692
  /* @__PURE__ */ jsxRuntime.jsx(
25309
- BarChart,
25693
+ recharts.XAxis,
25694
+ {
25695
+ dataKey: args.x_field,
25696
+ ...CHART_STYLES.axis,
25697
+ angle: -45,
25698
+ textAnchor: "end",
25699
+ height: 60,
25700
+ interval: 0,
25701
+ tickFormatter: formatXAxisTick
25702
+ }
25703
+ ),
25704
+ /* @__PURE__ */ jsxRuntime.jsx(
25705
+ recharts.YAxis,
25310
25706
  {
25311
- data: args.data,
25312
- bars: [{
25313
- dataKey: args.y_field,
25314
- fill: args.color || "#3b82f6",
25315
- labelList: args.show_values
25316
- }],
25317
- xAxisDataKey: args.x_field,
25318
- className: "h-64",
25319
- showLegend: false
25707
+ ...CHART_STYLES.axis,
25708
+ tickFormatter: (value) => formatNumber(value)
25320
25709
  }
25321
25710
  ),
25322
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
25323
- ] }, `bar-${key}`);
25711
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
25712
+ /* @__PURE__ */ jsxRuntime.jsx(
25713
+ recharts.Bar,
25714
+ {
25715
+ dataKey: args.y_field,
25716
+ fill: args.color || CHART_COLORS.primary,
25717
+ radius: CHART_STYLES.barRadius
25718
+ }
25719
+ )
25720
+ ] }) }) }) }, `bar-${key}`);
25324
25721
  case "create_line_chart":
25325
25722
  console.log("[DEBUG] Rendering line chart");
25326
25723
  if (!args.data || !args.x_field || !args.y_field) {
25327
25724
  console.error("Line chart missing required parameters:", { data: !!args.data, x_field: !!args.x_field, y_field: !!args.y_field });
25328
25725
  return null;
25329
25726
  }
25330
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", style: {
25331
- height: args.height || 256,
25332
- width: args.width || "100%"
25333
- }, children: [
25727
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-64", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data: args.data, margin: CHART_STYLES.margin, children: [
25728
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
25334
25729
  /* @__PURE__ */ jsxRuntime.jsx(
25335
- LineChart,
25730
+ recharts.XAxis,
25336
25731
  {
25337
- data: args.data,
25338
- lines: [{
25339
- dataKey: args.y_field,
25340
- stroke: "#3b82f6",
25341
- strokeWidth: 2
25342
- }],
25343
- xAxisDataKey: args.x_field,
25344
- className: "h-full",
25345
- showLegend: false
25732
+ dataKey: args.x_field,
25733
+ ...CHART_STYLES.axis,
25734
+ angle: -45,
25735
+ textAnchor: "end",
25736
+ height: 60,
25737
+ interval: 0,
25738
+ tickFormatter: formatXAxisTick
25346
25739
  }
25347
25740
  ),
25348
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
25349
- ] }, `line-${key}`);
25741
+ /* @__PURE__ */ jsxRuntime.jsx(
25742
+ recharts.YAxis,
25743
+ {
25744
+ ...CHART_STYLES.axis,
25745
+ tickFormatter: (value) => formatNumber(value)
25746
+ }
25747
+ ),
25748
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip, {}), cursor: { strokeDasharray: "3 3" } }),
25749
+ /* @__PURE__ */ jsxRuntime.jsx(
25750
+ recharts.Line,
25751
+ {
25752
+ type: "monotone",
25753
+ dataKey: args.y_field,
25754
+ stroke: CHART_COLORS.primary,
25755
+ strokeWidth: 2,
25756
+ dot: { r: 4, fill: CHART_COLORS.primary },
25757
+ activeDot: { r: 6 }
25758
+ }
25759
+ )
25760
+ ] }) }) }) }, `line-${key}`);
25350
25761
  case "create_pie_chart":
25351
25762
  console.log("[DEBUG] Rendering pie chart");
25352
25763
  if (!args.data || !args.label_field || !args.value_field) {
@@ -25359,16 +25770,14 @@ var AIAgentView = () => {
25359
25770
  value: item[args.value_field]
25360
25771
  }));
25361
25772
  console.log("[DEBUG] Pie chart data transformed:", pieData);
25362
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full flex flex-col items-center", children: [
25363
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-700 mb-2", children: args.title }),
25364
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-64 w-full max-w-md", children: /* @__PURE__ */ jsxRuntime.jsx(
25365
- PieChart4,
25366
- {
25367
- data: pieData,
25368
- showPercentages: args.show_percentages || false
25369
- }
25370
- ) })
25371
- ] }, `pie-${key}`);
25773
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-64 w-full max-w-md mx-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
25774
+ PieChart4,
25775
+ {
25776
+ data: pieData,
25777
+ showPercentages: args.show_percentages || false,
25778
+ colors: CHART_COLOR_PALETTE
25779
+ }
25780
+ ) }) }, `pie-${key}`);
25372
25781
  case "create_comparison_table":
25373
25782
  console.log("[DEBUG] Rendering comparison table");
25374
25783
  if (!args.data) {
@@ -25385,27 +25794,24 @@ var AIAgentView = () => {
25385
25794
  return args.sort_descending === false ? comparison : -comparison;
25386
25795
  });
25387
25796
  }
25388
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full overflow-x-auto", children: [
25389
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-700 mb-2", children: args.title }),
25390
- /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
25391
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
25392
- "th",
25393
- {
25394
- className: `px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider ${col === args.highlight_column ? "bg-blue-50" : ""}`,
25395
- children: col
25396
- },
25397
- col
25398
- )) }) }),
25399
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-white divide-y divide-gray-200", children: sortedData.map((row, rowIdx) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: rowIdx % 2 === 0 ? "bg-white" : "bg-gray-50", children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
25400
- "td",
25401
- {
25402
- className: `px-4 py-2 whitespace-nowrap text-sm ${col === args.highlight_column ? "font-medium text-blue-600 bg-blue-50" : "text-gray-900"}`,
25403
- children: row[col]
25404
- },
25405
- col
25406
- )) }, rowIdx)) })
25407
- ] })
25408
- ] }, `table-${key}`);
25797
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto rounded-lg border border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
25798
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
25799
+ "th",
25800
+ {
25801
+ className: `px-6 py-3 text-left text-xs font-medium text-gray-600 uppercase tracking-wider ${col === args.highlight_column ? "bg-blue-50" : ""}`,
25802
+ children: col
25803
+ },
25804
+ col
25805
+ )) }) }),
25806
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-white divide-y divide-gray-200", children: sortedData.map((row, rowIdx) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: rowIdx % 2 === 0 ? "bg-white" : "bg-gray-50", children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
25807
+ "td",
25808
+ {
25809
+ className: `px-6 py-4 whitespace-nowrap text-sm ${col === args.highlight_column ? "font-medium text-blue-600 bg-blue-50" : "text-gray-900"}`,
25810
+ children: typeof row[col] === "number" ? formatNumber(row[col]) : row[col]
25811
+ },
25812
+ col
25813
+ )) }, rowIdx)) })
25814
+ ] }) }) }, `table-${key}`);
25409
25815
  case "create_multi_line_chart":
25410
25816
  console.log("[DEBUG] Rendering multi-line chart");
25411
25817
  if (!args.data || !args.x_field || !args.y_fields || !args.legend) {
@@ -25417,30 +25823,49 @@ var AIAgentView = () => {
25417
25823
  });
25418
25824
  return null;
25419
25825
  }
25420
- const colors = ["#3b82f6", "#ef4444", "#10b981", "#f59e0b", "#8b5cf6", "#06b6d4", "#84cc16", "#f97316"];
25421
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", children: [
25422
- /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: 400, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data: args.data, children: [
25423
- /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3" }),
25424
- /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: args.x_field }),
25425
- /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, {}),
25426
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, {}),
25427
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, {}),
25428
- args.y_fields.map((field, index) => /* @__PURE__ */ jsxRuntime.jsx(
25429
- recharts.Line,
25430
- {
25431
- type: "monotone",
25432
- dataKey: field,
25433
- stroke: colors[index % colors.length],
25434
- strokeWidth: 2,
25435
- name: args.legend[index] || field,
25436
- dot: { r: 4 },
25437
- activeDot: { r: 6 }
25438
- },
25439
- field
25440
- ))
25441
- ] }) }),
25442
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
25443
- ] }, `multi-line-${key}`);
25826
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data: args.data, margin: CHART_STYLES.margin, children: [
25827
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
25828
+ /* @__PURE__ */ jsxRuntime.jsx(
25829
+ recharts.XAxis,
25830
+ {
25831
+ dataKey: args.x_field,
25832
+ ...CHART_STYLES.axis,
25833
+ angle: -45,
25834
+ textAnchor: "end",
25835
+ height: 60,
25836
+ interval: 0,
25837
+ tickFormatter: formatXAxisTick
25838
+ }
25839
+ ),
25840
+ /* @__PURE__ */ jsxRuntime.jsx(
25841
+ recharts.YAxis,
25842
+ {
25843
+ ...CHART_STYLES.axis,
25844
+ tickFormatter: (value) => formatNumber(value)
25845
+ }
25846
+ ),
25847
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip, {}), cursor: { strokeDasharray: "3 3" } }),
25848
+ /* @__PURE__ */ jsxRuntime.jsx(
25849
+ recharts.Legend,
25850
+ {
25851
+ wrapperStyle: { paddingTop: "20px" },
25852
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
25853
+ }
25854
+ ),
25855
+ args.y_fields.map((field, index) => /* @__PURE__ */ jsxRuntime.jsx(
25856
+ recharts.Line,
25857
+ {
25858
+ type: "monotone",
25859
+ dataKey: field,
25860
+ stroke: CHART_COLOR_PALETTE[index % CHART_COLOR_PALETTE.length],
25861
+ strokeWidth: 2,
25862
+ name: args.legend[index] || field,
25863
+ dot: { r: 4 },
25864
+ activeDot: { r: 6 }
25865
+ },
25866
+ field
25867
+ ))
25868
+ ] }) }) }) }, `multi-line-${key}`);
25444
25869
  case "create_stacked_bar_chart":
25445
25870
  console.log("[DEBUG] Rendering stacked bar chart");
25446
25871
  if (!args.data || !args.x_field || !args.stack_fields) {
@@ -25451,27 +25876,47 @@ var AIAgentView = () => {
25451
25876
  });
25452
25877
  return null;
25453
25878
  }
25454
- const stackColors = ["#3b82f6", "#ef4444", "#10b981", "#f59e0b", "#8b5cf6", "#06b6d4", "#84cc16", "#f97316"];
25455
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", children: [
25456
- /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: 400, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data: args.data, children: [
25457
- /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3" }),
25458
- /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: args.x_field }),
25459
- /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, {}),
25460
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, {}),
25461
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, {}),
25462
- args.stack_fields.map((field, index) => /* @__PURE__ */ jsxRuntime.jsx(
25463
- recharts.Bar,
25464
- {
25465
- dataKey: field,
25466
- stackId: "stack",
25467
- fill: stackColors[index % stackColors.length],
25468
- name: field
25469
- },
25470
- field
25471
- ))
25472
- ] }) }),
25473
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
25474
- ] }, `stacked-bar-${key}`);
25879
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data: args.data, margin: CHART_STYLES.margin, children: [
25880
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
25881
+ /* @__PURE__ */ jsxRuntime.jsx(
25882
+ recharts.XAxis,
25883
+ {
25884
+ dataKey: args.x_field,
25885
+ ...CHART_STYLES.axis,
25886
+ angle: -45,
25887
+ textAnchor: "end",
25888
+ height: 60,
25889
+ interval: 0,
25890
+ tickFormatter: formatXAxisTick
25891
+ }
25892
+ ),
25893
+ /* @__PURE__ */ jsxRuntime.jsx(
25894
+ recharts.YAxis,
25895
+ {
25896
+ ...CHART_STYLES.axis,
25897
+ tickFormatter: (value) => formatNumber(value)
25898
+ }
25899
+ ),
25900
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
25901
+ /* @__PURE__ */ jsxRuntime.jsx(
25902
+ recharts.Legend,
25903
+ {
25904
+ wrapperStyle: { paddingTop: "20px" },
25905
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
25906
+ }
25907
+ ),
25908
+ args.stack_fields.map((field, index) => /* @__PURE__ */ jsxRuntime.jsx(
25909
+ recharts.Bar,
25910
+ {
25911
+ dataKey: field,
25912
+ stackId: "stack",
25913
+ fill: CHART_COLOR_PALETTE[index % CHART_COLOR_PALETTE.length],
25914
+ name: field,
25915
+ radius: index === args.stack_fields.length - 1 ? CHART_STYLES.barRadius : void 0
25916
+ },
25917
+ field
25918
+ ))
25919
+ ] }) }) }) }, `stacked-bar-${key}`);
25475
25920
  case "create_dual_axis_chart":
25476
25921
  console.log("[DEBUG] Rendering dual-axis chart");
25477
25922
  if (!args.data || !args.x_field || !args.left_y_field || !args.right_y_field) {
@@ -25483,19 +25928,82 @@ var AIAgentView = () => {
25483
25928
  });
25484
25929
  return null;
25485
25930
  }
25486
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", children: [
25487
- /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: 400, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, children: [
25488
- /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3" }),
25489
- /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: args.x_field }),
25490
- /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { yAxisId: "left", orientation: "left", label: { value: args.left_label || "", angle: -90, position: "insideLeft" } }),
25491
- /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { yAxisId: "right", orientation: "right", label: { value: args.right_label || "", angle: 90, position: "insideRight" } }),
25492
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, {}),
25493
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, {}),
25494
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Bar, { yAxisId: "left", dataKey: args.left_y_field, fill: "#3b82f6", name: args.left_label || args.left_y_field }),
25495
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Line, { yAxisId: "right", type: "monotone", dataKey: args.right_y_field, stroke: "#ef4444", strokeWidth: 2, name: args.right_label || args.right_y_field })
25496
- ] }) }),
25497
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
25498
- ] }, `dual-axis-${key}`);
25931
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
25932
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
25933
+ /* @__PURE__ */ jsxRuntime.jsx(
25934
+ recharts.XAxis,
25935
+ {
25936
+ dataKey: args.x_field,
25937
+ ...CHART_STYLES.axis,
25938
+ angle: -45,
25939
+ textAnchor: "end",
25940
+ height: 100,
25941
+ interval: 0,
25942
+ tickFormatter: formatXAxisTick
25943
+ }
25944
+ ),
25945
+ /* @__PURE__ */ jsxRuntime.jsx(
25946
+ recharts.YAxis,
25947
+ {
25948
+ yAxisId: "left",
25949
+ orientation: "left",
25950
+ label: {
25951
+ value: args.left_label || args.left_y_field,
25952
+ angle: -90,
25953
+ position: "insideLeft",
25954
+ style: { textAnchor: "middle", fill: "#4b5563" }
25955
+ },
25956
+ ...CHART_STYLES.axis,
25957
+ tickFormatter: (value) => `${formatNumber(value)}${args.left_unit || ""}`
25958
+ }
25959
+ ),
25960
+ /* @__PURE__ */ jsxRuntime.jsx(
25961
+ recharts.YAxis,
25962
+ {
25963
+ yAxisId: "right",
25964
+ orientation: "right",
25965
+ label: {
25966
+ value: args.right_label || args.right_y_field,
25967
+ angle: 90,
25968
+ position: "insideRight",
25969
+ style: { textAnchor: "middle", fill: "#4b5563" }
25970
+ },
25971
+ ...CHART_STYLES.axis,
25972
+ tickFormatter: (value) => `${formatNumber(value)}${args.right_unit || ""}`
25973
+ }
25974
+ ),
25975
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(DualAxisTooltip, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
25976
+ /* @__PURE__ */ jsxRuntime.jsx(
25977
+ recharts.Legend,
25978
+ {
25979
+ wrapperStyle: { paddingTop: "20px" },
25980
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
25981
+ }
25982
+ ),
25983
+ /* @__PURE__ */ jsxRuntime.jsx(
25984
+ recharts.Bar,
25985
+ {
25986
+ yAxisId: "left",
25987
+ dataKey: args.left_y_field,
25988
+ fill: CHART_COLORS.primary,
25989
+ name: args.left_label || args.left_y_field,
25990
+ radius: CHART_STYLES.barRadius
25991
+ }
25992
+ ),
25993
+ /* @__PURE__ */ jsxRuntime.jsx(
25994
+ recharts.Line,
25995
+ {
25996
+ yAxisId: "right",
25997
+ type: "monotone",
25998
+ dataKey: args.right_y_field,
25999
+ stroke: CHART_COLORS.danger,
26000
+ strokeWidth: 3,
26001
+ name: args.right_label || args.right_y_field,
26002
+ dot: { r: 5, fill: CHART_COLORS.danger },
26003
+ activeDot: { r: 7 }
26004
+ }
26005
+ )
26006
+ ] }) }) }) }, `dual-axis-${key}`);
25499
26007
  case "create_scatter_plot":
25500
26008
  console.log("[DEBUG] Rendering scatter plot");
25501
26009
  if (!args.data || !args.x_field || !args.y_field || !args.group_field) {
@@ -25515,26 +26023,50 @@ var AIAgentView = () => {
25515
26023
  acc[group].push(item);
25516
26024
  return acc;
25517
26025
  }, {});
25518
- const scatterColors = ["#3b82f6", "#ef4444", "#10b981", "#f59e0b", "#8b5cf6", "#06b6d4", "#84cc16", "#f97316"];
25519
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", children: [
25520
- /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: 400, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ScatterChart, { children: [
25521
- /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3" }),
25522
- /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: args.x_field, type: "number", name: args.x_field }),
25523
- /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { dataKey: args.y_field, type: "number", name: args.y_field }),
25524
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { cursor: { strokeDasharray: "3 3" } }),
25525
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, {}),
25526
- Object.entries(groupedData).map(([group, data], index) => /* @__PURE__ */ jsxRuntime.jsx(
25527
- recharts.Scatter,
25528
- {
25529
- name: group,
25530
- data,
25531
- fill: scatterColors[index % scatterColors.length]
25532
- },
25533
- group
25534
- ))
25535
- ] }) }),
25536
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
25537
- ] }, `scatter-${key}`);
26026
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ScatterChart, { margin: CHART_STYLES.margin, children: [
26027
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
26028
+ /* @__PURE__ */ jsxRuntime.jsx(
26029
+ recharts.XAxis,
26030
+ {
26031
+ dataKey: args.x_field,
26032
+ type: "number",
26033
+ name: args.x_field,
26034
+ ...CHART_STYLES.axis
26035
+ }
26036
+ ),
26037
+ /* @__PURE__ */ jsxRuntime.jsx(
26038
+ recharts.YAxis,
26039
+ {
26040
+ dataKey: args.y_field,
26041
+ type: "number",
26042
+ name: args.y_field,
26043
+ ...CHART_STYLES.axis
26044
+ }
26045
+ ),
26046
+ /* @__PURE__ */ jsxRuntime.jsx(
26047
+ recharts.Tooltip,
26048
+ {
26049
+ cursor: { strokeDasharray: "3 3" },
26050
+ content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip, {})
26051
+ }
26052
+ ),
26053
+ /* @__PURE__ */ jsxRuntime.jsx(
26054
+ recharts.Legend,
26055
+ {
26056
+ wrapperStyle: { paddingTop: "20px" },
26057
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
26058
+ }
26059
+ ),
26060
+ Object.entries(groupedData).map(([group, data], index) => /* @__PURE__ */ jsxRuntime.jsx(
26061
+ recharts.Scatter,
26062
+ {
26063
+ name: group,
26064
+ data,
26065
+ fill: CHART_COLOR_PALETTE[index % CHART_COLOR_PALETTE.length]
26066
+ },
26067
+ group
26068
+ ))
26069
+ ] }) }) }) }, `scatter-${key}`);
25538
26070
  case "create_combo_chart":
25539
26071
  console.log("[DEBUG] Rendering combo chart");
25540
26072
  if (!args.data || !args.x_field || !args.bar_field || !args.line_field) {
@@ -25546,19 +26078,70 @@ var AIAgentView = () => {
25546
26078
  });
25547
26079
  return null;
25548
26080
  }
25549
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", children: [
25550
- /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: 400, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, children: [
25551
- /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3" }),
25552
- /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: args.x_field }),
25553
- /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { yAxisId: "left", orientation: "left" }),
25554
- /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { yAxisId: "right", orientation: "right" }),
25555
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, {}),
25556
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, {}),
25557
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Bar, { yAxisId: "left", dataKey: args.bar_field, fill: "#3b82f6", name: args.bar_field }),
25558
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Line, { yAxisId: "right", type: "monotone", dataKey: args.line_field, stroke: "#ef4444", strokeWidth: 2, name: args.line_field })
25559
- ] }) }),
25560
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
25561
- ] }, `combo-${key}`);
26081
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
26082
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
26083
+ /* @__PURE__ */ jsxRuntime.jsx(
26084
+ recharts.XAxis,
26085
+ {
26086
+ dataKey: args.x_field,
26087
+ ...CHART_STYLES.axis,
26088
+ angle: -45,
26089
+ textAnchor: "end",
26090
+ height: 100,
26091
+ interval: 0,
26092
+ tickFormatter: formatXAxisTick
26093
+ }
26094
+ ),
26095
+ /* @__PURE__ */ jsxRuntime.jsx(
26096
+ recharts.YAxis,
26097
+ {
26098
+ yAxisId: "left",
26099
+ orientation: "left",
26100
+ ...CHART_STYLES.axis,
26101
+ tickFormatter: (value) => formatNumber(value)
26102
+ }
26103
+ ),
26104
+ /* @__PURE__ */ jsxRuntime.jsx(
26105
+ recharts.YAxis,
26106
+ {
26107
+ yAxisId: "right",
26108
+ orientation: "right",
26109
+ ...CHART_STYLES.axis,
26110
+ tickFormatter: (value) => formatNumber(value)
26111
+ }
26112
+ ),
26113
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
26114
+ /* @__PURE__ */ jsxRuntime.jsx(
26115
+ recharts.Legend,
26116
+ {
26117
+ wrapperStyle: { paddingTop: "20px" },
26118
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
26119
+ }
26120
+ ),
26121
+ /* @__PURE__ */ jsxRuntime.jsx(
26122
+ recharts.Bar,
26123
+ {
26124
+ yAxisId: "left",
26125
+ dataKey: args.bar_field,
26126
+ fill: CHART_COLORS.primary,
26127
+ name: args.bar_field,
26128
+ radius: CHART_STYLES.barRadius
26129
+ }
26130
+ ),
26131
+ /* @__PURE__ */ jsxRuntime.jsx(
26132
+ recharts.Line,
26133
+ {
26134
+ yAxisId: "right",
26135
+ type: "monotone",
26136
+ dataKey: args.line_field,
26137
+ stroke: CHART_COLORS.danger,
26138
+ strokeWidth: 3,
26139
+ name: args.line_field,
26140
+ dot: { r: 5 },
26141
+ activeDot: { r: 7 }
26142
+ }
26143
+ )
26144
+ ] }) }) }) }, `combo-${key}`);
25562
26145
  case "create_area_chart":
25563
26146
  console.log("[DEBUG] Rendering area chart");
25564
26147
  if (!args.data || !args.x_field || !args.y_field) {
@@ -25569,27 +26152,53 @@ var AIAgentView = () => {
25569
26152
  });
25570
26153
  return null;
25571
26154
  }
25572
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", children: [
25573
- /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: 400, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, children: [
25574
- /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3" }),
25575
- /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: args.x_field }),
25576
- /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, {}),
25577
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, {}),
25578
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, {}),
25579
- /* @__PURE__ */ jsxRuntime.jsx(
25580
- recharts.Area,
25581
- {
25582
- type: "monotone",
25583
- dataKey: args.y_field,
25584
- stroke: "#3b82f6",
25585
- fill: args.fill ? "#3b82f6" : "none",
25586
- fillOpacity: args.fill ? 0.6 : 0,
25587
- name: args.y_field
25588
- }
25589
- )
26155
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-80", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
26156
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: "colorGradient", x1: "0", y1: "0", x2: "0", y2: "1", children: [
26157
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: CHART_COLORS.primary, stopOpacity: 0.8 }),
26158
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "95%", stopColor: CHART_COLORS.primary, stopOpacity: 0.1 })
25590
26159
  ] }) }),
25591
- args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
25592
- ] }, `area-${key}`);
26160
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...CHART_STYLES.grid }),
26161
+ /* @__PURE__ */ jsxRuntime.jsx(
26162
+ recharts.XAxis,
26163
+ {
26164
+ dataKey: args.x_field,
26165
+ ...CHART_STYLES.axis,
26166
+ angle: -45,
26167
+ textAnchor: "end",
26168
+ height: 100,
26169
+ interval: 0,
26170
+ tickFormatter: formatXAxisTick
26171
+ }
26172
+ ),
26173
+ /* @__PURE__ */ jsxRuntime.jsx(
26174
+ recharts.YAxis,
26175
+ {
26176
+ ...CHART_STYLES.axis,
26177
+ tickFormatter: (value) => formatNumber(value)
26178
+ }
26179
+ ),
26180
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip, {}), cursor: { strokeDasharray: "3 3" } }),
26181
+ /* @__PURE__ */ jsxRuntime.jsx(
26182
+ recharts.Legend,
26183
+ {
26184
+ wrapperStyle: { paddingTop: "20px" },
26185
+ formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
26186
+ }
26187
+ ),
26188
+ /* @__PURE__ */ jsxRuntime.jsx(
26189
+ recharts.Area,
26190
+ {
26191
+ type: "monotone",
26192
+ dataKey: args.y_field,
26193
+ stroke: CHART_COLORS.primary,
26194
+ strokeWidth: 2,
26195
+ fill: args.fill !== false ? "url(#colorGradient)" : "none",
26196
+ name: args.y_field,
26197
+ dot: { r: 4, fill: CHART_COLORS.primary },
26198
+ activeDot: { r: 6 }
26199
+ }
26200
+ )
26201
+ ] }) }) }) }, `area-${key}`);
25593
26202
  default:
25594
26203
  console.warn(`Unknown chart type: ${chartType}`);
25595
26204
  return null;
@@ -25620,6 +26229,31 @@ var AIAgentView = () => {
25620
26229
  opacity: 1;
25621
26230
  }
25622
26231
  }
26232
+
26233
+ @keyframes waveLoad {
26234
+ 0% {
26235
+ background-position: -200% 0;
26236
+ }
26237
+ 100% {
26238
+ background-position: 200% 0;
26239
+ }
26240
+ }
26241
+
26242
+ .thinking-wave {
26243
+ background: linear-gradient(
26244
+ 90deg,
26245
+ #6b7280 0%,
26246
+ #6b7280 40%,
26247
+ #3b82f6 50%,
26248
+ #6b7280 60%,
26249
+ #6b7280 100%
26250
+ );
26251
+ background-size: 200% 100%;
26252
+ -webkit-background-clip: text;
26253
+ background-clip: text;
26254
+ -webkit-text-fill-color: transparent;
26255
+ animation: waveLoad 3s ease-in-out infinite;
26256
+ }
25623
26257
  `
25624
26258
  } }),
25625
26259
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex-1 flex flex-col h-screen transition-all duration-300 ${isSidebarOpen ? "mr-80" : "mr-0"}`, children: [
@@ -25769,14 +26403,7 @@ var AIAgentView = () => {
25769
26403
  )),
25770
26404
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 justify-start", children: [
25771
26405
  /* @__PURE__ */ jsxRuntime.jsx(ProfilePicture, {}),
25772
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
25773
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-1", children: [
25774
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce" }),
25775
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.1s" } }),
25776
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.2s" } })
25777
- ] }),
25778
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-600 text-sm", children: "Axel is thinking..." })
25779
- ] }) })
26406
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium thinking-wave", children: "Thinking" }) }) })
25780
26407
  ] })
25781
26408
  ] }) })
25782
26409
  ) : (
@@ -25842,14 +26469,7 @@ var AIAgentView = () => {
25842
26469
  ] }),
25843
26470
  isCurrentThreadLoading && !currentStreaming.message && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 justify-start", children: [
25844
26471
  /* @__PURE__ */ jsxRuntime.jsx(ProfilePicture, {}),
25845
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
25846
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-1", children: [
25847
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce" }),
25848
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.1s" } }),
25849
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.2s" } })
25850
- ] }),
25851
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-600 text-sm", children: "Axel is thinking..." })
25852
- ] }) })
26472
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium thinking-wave", children: "Thinking" }) }) })
25853
26473
  ] }),
25854
26474
  /* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
25855
26475
  ] }) })
@@ -26851,14 +27471,30 @@ function HomeView({
26851
27471
  factoryName = "Simba Beer - Line 1"
26852
27472
  }) {
26853
27473
  const [isHydrated, setIsHydrated] = React14.useState(false);
26854
- const [selectedLineId, setSelectedLineId] = React14.useState(defaultLineId);
27474
+ const [selectedLineId, setSelectedLineId] = React14.useState(factoryViewId);
27475
+ console.log("[HomeView] Component initialized with:", {
27476
+ defaultLineId,
27477
+ factoryViewId,
27478
+ line1Uuid,
27479
+ line2Uuid,
27480
+ selectedLineId: factoryViewId
27481
+ });
26855
27482
  const [isChangingFilter, setIsChangingFilter] = React14.useState(false);
26856
27483
  const [errorMessage, setErrorMessage] = React14.useState(null);
26857
27484
  const [displayNamesInitialized, setDisplayNamesInitialized] = React14.useState(false);
27485
+ const metricsLineId = selectedLineId;
27486
+ console.log("[HomeView] Using metrics line ID:", metricsLineId, "for selectedLineId:", selectedLineId);
26858
27487
  React14.useEffect(() => {
26859
27488
  const initDisplayNames = async () => {
26860
27489
  try {
26861
- await preInitializeWorkspaceDisplayNames(selectedLineId);
27490
+ if (metricsLineId === factoryViewId) {
27491
+ console.log("[HomeView] Initializing display names for factory view (both lines)");
27492
+ await preInitializeWorkspaceDisplayNames(line1Uuid);
27493
+ await preInitializeWorkspaceDisplayNames(line2Uuid);
27494
+ } else {
27495
+ console.log("[HomeView] Initializing display names for single line:", selectedLineId);
27496
+ await preInitializeWorkspaceDisplayNames(selectedLineId);
27497
+ }
26862
27498
  setDisplayNamesInitialized(true);
26863
27499
  } catch (error) {
26864
27500
  console.error("Failed to pre-initialize workspace display names:", error);
@@ -26866,12 +27502,13 @@ function HomeView({
26866
27502
  }
26867
27503
  };
26868
27504
  initDisplayNames();
26869
- }, [selectedLineId]);
27505
+ }, [selectedLineId, metricsLineId, factoryViewId, line1Uuid, line2Uuid]);
27506
+ const displayNamesLineId = metricsLineId === factoryViewId ? void 0 : selectedLineId;
26870
27507
  const {
26871
27508
  displayNames: workspaceDisplayNames,
26872
27509
  loading: displayNamesLoading,
26873
27510
  error: displayNamesError
26874
- } = useWorkspaceDisplayNames(void 0, selectedLineId);
27511
+ } = useWorkspaceDisplayNames(void 0, displayNamesLineId);
26875
27512
  React14.useCallback(() => {
26876
27513
  console.log("Refetching KPIs after line metrics update");
26877
27514
  }, []);
@@ -26896,14 +27533,16 @@ function HomeView({
26896
27533
  error: metricsError,
26897
27534
  refetch: refetchMetrics
26898
27535
  } = useDashboardMetrics({
26899
- lineId: selectedLineId,
27536
+ lineId: metricsLineId,
26900
27537
  onLineMetricsUpdate
26901
27538
  });
27539
+ const breaksLineIds = metricsLineId === factoryViewId ? [line1Uuid, line2Uuid] : [selectedLineId];
27540
+ console.log("[HomeView] Using breaks line IDs:", breaksLineIds);
26902
27541
  const {
26903
27542
  activeBreaks,
26904
27543
  isLoading: breaksLoading,
26905
27544
  error: breaksError
26906
- } = useActiveBreaks([selectedLineId]);
27545
+ } = useActiveBreaks(breaksLineIds);
26907
27546
  const memoizedWorkspaceMetrics = React14.useMemo(() => workspaceMetrics, [
26908
27547
  // Only update reference if meaningful properties change
26909
27548
  workspaceMetrics.length,
@@ -27058,8 +27697,12 @@ var itemVariants = {
27058
27697
  };
27059
27698
 
27060
27699
  // src/lib/utils/navigation.ts
27061
- function getWorkspaceNavigationParams2(workspaceUuid, displayName) {
27062
- return `?name=${encodeURIComponent(displayName || "")}`;
27700
+ function getWorkspaceNavigationParams2(workspaceUuid, displayName, lineId) {
27701
+ const params = new URLSearchParams();
27702
+ if (displayName) {
27703
+ params.set("name", displayName);
27704
+ }
27705
+ return params.toString() ? `?${params.toString()}` : "";
27063
27706
  }
27064
27707
  var formatLocalDate = (date) => {
27065
27708
  const options = {
@@ -28251,6 +28894,13 @@ var LeaderboardDetailView = React14.memo(({
28251
28894
  line2Id = "",
28252
28895
  className = ""
28253
28896
  }) => {
28897
+ console.log("[LeaderboardDetailView] Component initialized with:", {
28898
+ lineId,
28899
+ line1Id,
28900
+ line2Id,
28901
+ date,
28902
+ shift
28903
+ });
28254
28904
  const navigation = useNavigation();
28255
28905
  const [sortAscending, setSortAscending] = React14.useState(true);
28256
28906
  const handleSortToggle = React14.useCallback(() => {
@@ -28268,13 +28918,39 @@ var LeaderboardDetailView = React14.memo(({
28268
28918
  error: metricsError,
28269
28919
  refreshMetrics
28270
28920
  } = useRealtimeLineMetrics(realtimeMetricsParams);
28921
+ const isFactoryView = React14.useMemo(() => {
28922
+ const hasEssentialLineIds = Boolean(line1Id && line2Id);
28923
+ const isFactoryLineId = lineId === "factory" || !lineId;
28924
+ return hasEssentialLineIds && isFactoryLineId;
28925
+ }, [lineId, line1Id, line2Id]);
28271
28926
  const memoizedLineId = React14.useMemo(() => lineId || "", [lineId]);
28927
+ console.log("[LeaderboardDetailView] Factory view check:", {
28928
+ isFactoryView,
28929
+ lineId,
28930
+ line1Id,
28931
+ line2Id
28932
+ });
28933
+ const singleLineResult = useLineWorkspaceMetrics(isFactoryView ? "" : memoizedLineId);
28934
+ const factoryResult = useDashboardMetrics({
28935
+ lineId: isFactoryView ? "factory" : "",
28936
+ onLineMetricsUpdate: void 0
28937
+ });
28272
28938
  const {
28273
28939
  workspaces,
28274
28940
  loading: workspacesLoading,
28275
28941
  error: workspacesError,
28276
28942
  refreshWorkspaces
28277
- } = useLineWorkspaceMetrics(memoizedLineId);
28943
+ } = isFactoryView ? {
28944
+ workspaces: factoryResult.workspaceMetrics,
28945
+ loading: factoryResult.isLoading,
28946
+ error: factoryResult.error,
28947
+ refreshWorkspaces: factoryResult.refetch
28948
+ } : singleLineResult;
28949
+ console.log("[LeaderboardDetailView] Workspace data:", {
28950
+ workspaces: workspaces?.length || 0,
28951
+ loading: workspacesLoading,
28952
+ error: workspacesError
28953
+ });
28278
28954
  const getShiftName = React14.useCallback((shiftId) => {
28279
28955
  if (shiftId === void 0) return "Day";
28280
28956
  return shiftId === 0 ? "Day" : "Night";
@@ -30205,6 +30881,12 @@ var TargetsView = ({
30205
30881
  userId,
30206
30882
  onSaveChanges
30207
30883
  }) => {
30884
+ console.log("[TargetsView] Component initialized with:", {
30885
+ lineIds,
30886
+ lineNames,
30887
+ companyId,
30888
+ totalLines: lineIds.length
30889
+ });
30208
30890
  const initialLineWorkspaces = React14.useMemo(() => {
30209
30891
  return lineIds.reduce((acc, lineId) => ({
30210
30892
  ...acc,
@@ -30516,7 +31198,9 @@ var TargetsView = ({
30516
31198
  continue;
30517
31199
  }
30518
31200
  try {
31201
+ console.log(`[TargetsView] Fetching workspaces for line: ${lineId}`);
30519
31202
  const fetchedLineWorkspacesData = await workspaceService.getWorkspaces(lineId);
31203
+ console.log(`[TargetsView] Retrieved ${fetchedLineWorkspacesData.length} workspaces for line ${lineId}`);
30520
31204
  const mappedWorkspaces = fetchedLineWorkspacesData.map((ws) => ({
30521
31205
  id: ws.id,
30522
31206
  name: ws.workspace_id,
@@ -31946,6 +32630,7 @@ exports.clearRateLimit = clearRateLimit2;
31946
32630
  exports.clearS3VideoCache = clearS3VideoCache;
31947
32631
  exports.clearS3VideoFromCache = clearS3VideoFromCache;
31948
32632
  exports.clearWorkspaceDisplayNamesCache = clearWorkspaceDisplayNamesCache;
32633
+ exports.clearWorkspaceMappingsForLine = clearWorkspaceMappingsForLine;
31949
32634
  exports.cn = cn;
31950
32635
  exports.createStreamProxyHandler = createStreamProxyHandler;
31951
32636
  exports.createSupabaseClient = createSupabaseClient;
@@ -31987,6 +32672,7 @@ exports.getWorkspaceDisplayName = getWorkspaceDisplayName;
31987
32672
  exports.getWorkspaceDisplayNameAsync = getWorkspaceDisplayNameAsync;
31988
32673
  exports.getWorkspaceDisplayNamesMap = getWorkspaceDisplayNamesMap;
31989
32674
  exports.getWorkspaceFromUrl = getWorkspaceFromUrl;
32675
+ exports.getWorkspaceMappingsForLine = getWorkspaceMappingsForLine;
31990
32676
  exports.getWorkspaceNavigationParams = getWorkspaceNavigationParams;
31991
32677
  exports.identifyCoreUser = identifyCoreUser;
31992
32678
  exports.initializeCoreMixpanel = initializeCoreMixpanel;