@optifye/dashboard-core 4.2.2 → 4.2.4

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.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import * as React33 from 'react';
2
- import React33__default, { createContext, memo, useState, useEffect, useRef, useCallback, useMemo, useContext, useLayoutEffect, useId, Children, isValidElement, useInsertionEffect, forwardRef, Fragment as Fragment$1, createElement, Component } from 'react';
1
+ import * as React14 from 'react';
2
+ import React14__default, { createContext, memo, useState, useEffect, useRef, useCallback, useMemo, useContext, useLayoutEffect, useId, Children, isValidElement, useInsertionEffect, forwardRef, Fragment as Fragment$1, createElement, Component } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { useRouter } from 'next/router';
5
5
  import { subDays, format, parseISO, isValid, isFuture, isToday } from 'date-fns';
@@ -110,8 +110,9 @@ var DEFAULT_ENDPOINTS_CONFIG = {
110
110
  whatsapp: "/api/send-whatsapp-direct",
111
111
  agnoApiUrl: process.env.NEXT_PUBLIC_AGNO_URL || "https://optifye-agent-production.up.railway.app",
112
112
  // Default AGNO API URL
113
- // Hard-coded Slack webhook so the Help page works out-of-the-box without any config
114
- slackWebhookUrl: "https://hooks.slack.com/services/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",
113
+ // Use environment variable for Slack webhook URL for privacy/security
114
+ // Note: SLACK_WEBHOOK_URL is server-side only, NEXT_PUBLIC_SLACK_WEBHOOK_URL works client-side but is less secure
115
+ slackWebhookUrl: process.env.SLACK_WEBHOOK_URL || process.env.NEXT_PUBLIC_SLACK_WEBHOOK_URL || void 0,
115
116
  slackProxyEndpoint: void 0
116
117
  };
117
118
  var DEFAULT_THEME_CONFIG = {
@@ -187,14 +188,14 @@ var _getDashboardConfigInstance = () => {
187
188
  }
188
189
  return dashboardConfigInstance;
189
190
  };
190
- var DashboardConfigContext = React33.createContext(void 0);
191
+ var DashboardConfigContext = React14.createContext(void 0);
191
192
  var DashboardProvider = ({ config: userProvidedConfig, children }) => {
192
- const fullConfig = React33.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
193
+ const fullConfig = React14.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
193
194
  _setDashboardConfigInstance(fullConfig);
194
- React33.useEffect(() => {
195
+ React14.useEffect(() => {
195
196
  _setDashboardConfigInstance(fullConfig);
196
197
  }, [fullConfig]);
197
- React33.useEffect(() => {
198
+ React14.useEffect(() => {
198
199
  if (!fullConfig.theme) return;
199
200
  const styleId = "dashboard-core-theme-vars";
200
201
  let styleEl = document.getElementById(styleId);
@@ -220,7 +221,7 @@ var DashboardProvider = ({ config: userProvidedConfig, children }) => {
220
221
  return /* @__PURE__ */ jsx(DashboardConfigContext.Provider, { value: fullConfig, children });
221
222
  };
222
223
  var useDashboardConfig = () => {
223
- const ctx = React33.useContext(DashboardConfigContext);
224
+ const ctx = React14.useContext(DashboardConfigContext);
224
225
  if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
225
226
  return ctx;
226
227
  };
@@ -848,6 +849,63 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
848
849
  if (recentData) {
849
850
  console.log(`[useWorkspaceDetailedMetrics] Found fallback data from date: ${recentData.date}, shift: ${recentData.shift_id}`);
850
851
  const outputDifference2 = (recentData.total_output || 0) - (recentData.ideal_output || 0);
852
+ const workspaceMatch2 = recentData.workspace_name?.match(/WS(\d+)/);
853
+ const workspaceNumber2 = workspaceMatch2 ? parseInt(workspaceMatch2[1]) : 0;
854
+ const specialWsStart2 = workspaceConfig.specialWorkspaces?.startId ?? 19;
855
+ const specialWsEnd2 = workspaceConfig.specialWorkspaces?.endId ?? 34;
856
+ const isSpecialWorkspace2 = workspaceNumber2 >= specialWsStart2 && workspaceNumber2 <= specialWsEnd2;
857
+ const outputHourly2 = recentData.output_hourly || {};
858
+ const hasOutputHourlyData2 = outputHourly2 && typeof outputHourly2 === "object" && Object.keys(outputHourly2).length > 0;
859
+ let hourlyActionCounts2 = [];
860
+ if (hasOutputHourlyData2) {
861
+ console.log("Using new output_hourly column for workspace (fallback):", recentData.workspace_name);
862
+ console.log("Raw output_hourly data (fallback):", outputHourly2);
863
+ const isNightShift = recentData.shift_id === 1;
864
+ const shiftStart = recentData.shift_start || (isNightShift ? "22:00" : "06:00");
865
+ const shiftEnd = recentData.shift_end || (isNightShift ? "06:00" : "14:00");
866
+ const startHour = parseInt(shiftStart.split(":")[0]);
867
+ let expectedHours = [];
868
+ if (isNightShift) {
869
+ for (let i = 0; i < 9; i++) {
870
+ expectedHours.push((startHour + i) % 24);
871
+ }
872
+ } else {
873
+ for (let i = 0; i < 9; i++) {
874
+ expectedHours.push((startHour + i) % 24);
875
+ }
876
+ }
877
+ console.log("Expected shift hours (fallback):", expectedHours);
878
+ console.log("Available data hours (fallback):", Object.keys(outputHourly2));
879
+ hourlyActionCounts2 = expectedHours.map((expectedHour) => {
880
+ let hourData = outputHourly2[expectedHour.toString()];
881
+ if (!hourData && isNightShift) {
882
+ for (const [storedHour, data2] of Object.entries(outputHourly2)) {
883
+ if (Array.isArray(data2) && data2.length > 0 && data2.some((val) => val > 0)) {
884
+ if (storedHour === "18" && expectedHour === 1) {
885
+ hourData = data2;
886
+ console.log(`Mapping stored hour ${storedHour} to expected hour ${expectedHour} (fallback)`);
887
+ break;
888
+ }
889
+ }
890
+ }
891
+ }
892
+ return Array.isArray(hourData) ? hourData.reduce((sum, count) => sum + (count || 0), 0) : 0;
893
+ });
894
+ console.log("Final hourly action counts (fallback):", hourlyActionCounts2);
895
+ } else {
896
+ console.log("Using output_array fallback for workspace (fallback):", recentData.workspace_name);
897
+ const minuteByMinuteArray = recentData.output_array || [];
898
+ if (isSpecialWorkspace2) {
899
+ const last40Readings = minuteByMinuteArray.slice(Math.max(0, minuteByMinuteArray.length - 40));
900
+ hourlyActionCounts2 = last40Readings;
901
+ } else {
902
+ for (let i = 0; i < minuteByMinuteArray.length; i += 60) {
903
+ const hourSlice = minuteByMinuteArray.slice(i, Math.min(i + 60, minuteByMinuteArray.length));
904
+ const hourlySum = hourSlice.reduce((sum, count) => sum + count, 0);
905
+ hourlyActionCounts2.push(hourlySum);
906
+ }
907
+ }
908
+ }
851
909
  const transformedData2 = {
852
910
  workspace_id: recentData.workspace_id,
853
911
  workspace_name: recentData.workspace_name,
@@ -868,12 +926,14 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
868
926
  ideal_cycle_time: recentData.ideal_cycle_time || 0,
869
927
  avg_efficiency: recentData.efficiency || 0,
870
928
  total_actions: recentData.total_output || 0,
871
- hourly_action_counts: recentData.output_array || [],
929
+ hourly_action_counts: hourlyActionCounts2,
930
+ // Now uses the NEW logic with fallback
872
931
  workspace_rank: recentData.workspace_rank || 0,
873
932
  total_workspaces: recentData.total_workspaces || workspaceConfig.totalWorkspaces || 42,
874
933
  ideal_output_until_now: recentData.ideal_output || 0,
875
934
  output_difference: outputDifference2,
876
935
  idle_time: recentData.idle_time || 0,
936
+ idle_time_hourly: recentData.idle_time_hourly || void 0,
877
937
  ...recentData.compliance_efficiency !== void 0 && { compliance_efficiency: recentData.compliance_efficiency },
878
938
  ...recentData.sop_check !== void 0 && { sop_check: recentData.sop_check }
879
939
  };
@@ -900,17 +960,66 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
900
960
  const specialWsStart = workspaceConfig.specialWorkspaces?.startId ?? 19;
901
961
  const specialWsEnd = workspaceConfig.specialWorkspaces?.endId ?? 34;
902
962
  const isSpecialWorkspace = workspaceNumber >= specialWsStart && workspaceNumber <= specialWsEnd;
903
- const minuteByMinuteArray = data.output_array || [];
963
+ const outputHourly = data.output_hourly || {};
964
+ console.log("[DEBUG] Raw data.output_hourly:", data.output_hourly);
965
+ console.log("[DEBUG] outputHourly after || {}:", outputHourly);
966
+ console.log("[DEBUG] typeof outputHourly:", typeof outputHourly);
967
+ console.log("[DEBUG] Object.keys(outputHourly):", Object.keys(outputHourly));
968
+ console.log("[DEBUG] Object.keys(outputHourly).length:", Object.keys(outputHourly).length);
969
+ const hasOutputHourlyData = outputHourly && typeof outputHourly === "object" && Object.keys(outputHourly).length > 0;
970
+ console.log("[DEBUG] hasOutputHourlyData:", hasOutputHourlyData);
904
971
  let hourlyActionCounts = [];
905
- if (isSpecialWorkspace) {
906
- const last40Readings = minuteByMinuteArray.slice(Math.max(0, minuteByMinuteArray.length - 40));
907
- hourlyActionCounts = last40Readings;
972
+ if (hasOutputHourlyData) {
973
+ console.log("\u2705 Using new output_hourly column for workspace:", data.workspace_name);
974
+ console.log("Raw output_hourly data:", JSON.stringify(outputHourly));
975
+ const isNightShift = data.shift_id === 1;
976
+ const shiftStart = data.shift_start || (isNightShift ? "22:00" : "06:00");
977
+ const shiftEnd = data.shift_end || (isNightShift ? "06:00" : "14:00");
978
+ const startHour = parseInt(shiftStart.split(":")[0]);
979
+ let expectedHours = [];
980
+ if (isNightShift) {
981
+ for (let i = 0; i < 9; i++) {
982
+ expectedHours.push((startHour + i) % 24);
983
+ }
984
+ } else {
985
+ for (let i = 0; i < 9; i++) {
986
+ expectedHours.push((startHour + i) % 24);
987
+ }
988
+ }
989
+ console.log("Expected shift hours:", expectedHours);
990
+ console.log("Available data hours:", Object.keys(outputHourly));
991
+ hourlyActionCounts = expectedHours.map((expectedHour) => {
992
+ let hourData = outputHourly[expectedHour.toString()];
993
+ if (!hourData && isNightShift) {
994
+ for (const [storedHour, data2] of Object.entries(outputHourly)) {
995
+ if (Array.isArray(data2) && data2.length > 0 && data2.some((val) => val > 0)) {
996
+ if (storedHour === "18" && expectedHour === 1) {
997
+ hourData = data2;
998
+ console.log(`Mapping stored hour ${storedHour} to expected hour ${expectedHour}`);
999
+ break;
1000
+ }
1001
+ }
1002
+ }
1003
+ }
1004
+ return Array.isArray(hourData) ? hourData.reduce((sum, count) => sum + (count || 0), 0) : 0;
1005
+ });
1006
+ console.log("Final hourly action counts:", hourlyActionCounts);
908
1007
  } else {
909
- for (let i = 0; i < minuteByMinuteArray.length; i += 60) {
910
- const hourSlice = minuteByMinuteArray.slice(i, Math.min(i + 60, minuteByMinuteArray.length));
911
- const hourlySum = hourSlice.reduce((sum, count) => sum + count, 0);
912
- hourlyActionCounts.push(hourlySum);
1008
+ console.log("\u274C Using output_array fallback for workspace:", data.workspace_name);
1009
+ console.log("[DEBUG] Fallback reason - hasOutputHourlyData is false");
1010
+ console.log("[DEBUG] data.output_hourly was:", data.output_hourly);
1011
+ const minuteByMinuteArray = data.output_array || [];
1012
+ if (isSpecialWorkspace) {
1013
+ const last40Readings = minuteByMinuteArray.slice(Math.max(0, minuteByMinuteArray.length - 40));
1014
+ hourlyActionCounts = last40Readings;
1015
+ } else {
1016
+ for (let i = 0; i < minuteByMinuteArray.length; i += 60) {
1017
+ const hourSlice = minuteByMinuteArray.slice(i, Math.min(i + 60, minuteByMinuteArray.length));
1018
+ const hourlySum = hourSlice.reduce((sum, count) => sum + count, 0);
1019
+ hourlyActionCounts.push(hourlySum);
1020
+ }
913
1021
  }
1022
+ console.log("Final hourly action counts:", hourlyActionCounts);
914
1023
  }
915
1024
  const transformedData = {
916
1025
  workspace_id: data.workspace_id,
@@ -939,6 +1048,8 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
939
1048
  output_difference: outputDifference,
940
1049
  idle_time: data.idle_time || 0,
941
1050
  // Add idle_time from performance_metrics table
1051
+ idle_time_hourly: data.idle_time_hourly || void 0,
1052
+ // Add idle_time_hourly from performance_metrics table
942
1053
  ...data.compliance_efficiency !== void 0 && { compliance_efficiency: data.compliance_efficiency },
943
1054
  ...data.sop_check !== void 0 && { sop_check: data.sop_check }
944
1055
  };
@@ -1459,16 +1570,56 @@ var dashboardService = {
1459
1570
  const specialStart = workspaceConfig.specialWorkspaces?.startId ?? 19;
1460
1571
  const specialEnd = workspaceConfig.specialWorkspaces?.endId ?? 34;
1461
1572
  const isSpecialWorkspace = workspaceNumber >= specialStart && workspaceNumber <= specialEnd;
1462
- const minuteByMinuteArray = data.output_array || [];
1573
+ const outputHourly = data.output_hourly || {};
1574
+ const hasOutputHourlyData = outputHourly && typeof outputHourly === "object" && Object.keys(outputHourly).length > 0;
1463
1575
  let hourlyActionCounts = [];
1464
- if (isSpecialWorkspace) {
1465
- const numReadings = workspaceConfig.specialWorkspaces?.hourlyReadingsCount ?? 40;
1466
- hourlyActionCounts = minuteByMinuteArray.slice(-numReadings);
1576
+ if (hasOutputHourlyData) {
1577
+ console.log("Using new output_hourly column for workspace:", data.workspace_name);
1578
+ console.log("Raw output_hourly data:", outputHourly);
1579
+ const isNightShift = data.shift_id === 1;
1580
+ const shiftStart = data.shift_start || (isNightShift ? "22:00" : "06:00");
1581
+ const shiftEnd = data.shift_end || (isNightShift ? "06:00" : "14:00");
1582
+ const startHour = parseInt(shiftStart.split(":")[0]);
1583
+ let expectedHours = [];
1584
+ if (isNightShift) {
1585
+ for (let i = 0; i < 9; i++) {
1586
+ expectedHours.push((startHour + i) % 24);
1587
+ }
1588
+ } else {
1589
+ for (let i = 0; i < 9; i++) {
1590
+ expectedHours.push((startHour + i) % 24);
1591
+ }
1592
+ }
1593
+ console.log("Expected shift hours:", expectedHours);
1594
+ console.log("Available data hours:", Object.keys(outputHourly));
1595
+ hourlyActionCounts = expectedHours.map((expectedHour) => {
1596
+ let hourData = outputHourly[expectedHour.toString()];
1597
+ if (!hourData && isNightShift) {
1598
+ for (const [storedHour, data2] of Object.entries(outputHourly)) {
1599
+ if (Array.isArray(data2) && data2.length > 0 && data2.some((val) => val > 0)) {
1600
+ if (storedHour === "18" && expectedHour === 1) {
1601
+ hourData = data2;
1602
+ console.log(`Mapping stored hour ${storedHour} to expected hour ${expectedHour}`);
1603
+ break;
1604
+ }
1605
+ }
1606
+ }
1607
+ }
1608
+ return Array.isArray(hourData) ? hourData.reduce((sum, count) => sum + (count || 0), 0) : 0;
1609
+ });
1610
+ console.log("Final hourly action counts:", hourlyActionCounts);
1467
1611
  } else {
1468
- for (let i = 0; i < minuteByMinuteArray.length; i += 60) {
1469
- const hourSlice = minuteByMinuteArray.slice(i, Math.min(i + 60, minuteByMinuteArray.length));
1470
- const hourlySum = hourSlice.reduce((sum, count) => sum + (count ?? 0), 0);
1471
- hourlyActionCounts.push(hourlySum);
1612
+ console.log("Using output_array fallback for workspace:", data.workspace_name);
1613
+ const minuteByMinuteArray = data.output_array || [];
1614
+ if (isSpecialWorkspace) {
1615
+ const numReadings = workspaceConfig.specialWorkspaces?.hourlyReadingsCount ?? 40;
1616
+ hourlyActionCounts = minuteByMinuteArray.slice(-numReadings);
1617
+ } else {
1618
+ for (let i = 0; i < minuteByMinuteArray.length; i += 60) {
1619
+ const hourSlice = minuteByMinuteArray.slice(i, Math.min(i + 60, minuteByMinuteArray.length));
1620
+ const hourlySum = hourSlice.reduce((sum, count) => sum + (count ?? 0), 0);
1621
+ hourlyActionCounts.push(hourlySum);
1622
+ }
1472
1623
  }
1473
1624
  }
1474
1625
  const transformedData = {
@@ -1497,6 +1648,7 @@ var dashboardService = {
1497
1648
  ideal_output_until_now: data.ideal_output || 0,
1498
1649
  output_difference: outputDifference,
1499
1650
  idle_time: data.idle_time || 0,
1651
+ idle_time_hourly: data.idle_time_hourly || void 0,
1500
1652
  ...data.compliance_efficiency !== void 0 && { compliance_efficiency: data.compliance_efficiency },
1501
1653
  ...data.sop_check !== void 0 && { sop_check: data.sop_check }
1502
1654
  };
@@ -4283,8 +4435,26 @@ async function initializeWorkspaceDisplayNames(explicitLineId) {
4283
4435
  isInitializing = false;
4284
4436
  }
4285
4437
  }
4438
+ var preInitializeWorkspaceDisplayNames = async (lineId) => {
4439
+ console.log("\u{1F504} preInitializeWorkspaceDisplayNames called for lineId:", lineId);
4440
+ if (isInitialized || isInitializing) {
4441
+ console.log("\u{1F504} Already initialized or initializing, skipping pre-init");
4442
+ return;
4443
+ }
4444
+ await initializeWorkspaceDisplayNames(lineId);
4445
+ };
4446
+ var forceRefreshWorkspaceDisplayNames = async (lineId) => {
4447
+ console.log("\u{1F504} forceRefreshWorkspaceDisplayNames called for lineId:", lineId);
4448
+ clearWorkspaceDisplayNamesCache();
4449
+ await initializeWorkspaceDisplayNames(lineId);
4450
+ };
4286
4451
  console.log("\u{1F504} Module loaded, will initialize lazily when first function is called");
4287
4452
  var getWorkspaceDisplayName = (workspaceId, lineId) => {
4453
+ if (!isInitialized && !isInitializing) {
4454
+ console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}) - Not initialized, triggering lazy init...`);
4455
+ } else if (isInitializing) {
4456
+ console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}) - Currently initializing...`);
4457
+ }
4288
4458
  if (!isInitialized && !isInitializing) {
4289
4459
  console.log("\u{1F504} Lazy initialization triggered by getWorkspaceDisplayName");
4290
4460
  initializeWorkspaceDisplayNames(lineId).catch((error) => {
@@ -4368,6 +4538,7 @@ var clearWorkspaceDisplayNamesCache = () => {
4368
4538
  workspaceService.clearWorkspaceDisplayNamesCache();
4369
4539
  runtimeWorkspaceDisplayNames = {};
4370
4540
  isInitialized = false;
4541
+ isInitializing = false;
4371
4542
  };
4372
4543
 
4373
4544
  // src/lib/hooks/useWorkspaceDisplayNames.ts
@@ -8036,7 +8207,7 @@ var MotionConfigContext = createContext({
8036
8207
  });
8037
8208
 
8038
8209
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
8039
- var PopChildMeasure = class extends React33.Component {
8210
+ var PopChildMeasure = class extends React14.Component {
8040
8211
  getSnapshotBeforeUpdate(prevProps) {
8041
8212
  const element = this.props.childRef.current;
8042
8213
  if (element && prevProps.isPresent && !this.props.isPresent) {
@@ -8091,7 +8262,7 @@ function PopChild({ children, isPresent }) {
8091
8262
  document.head.removeChild(style);
8092
8263
  };
8093
8264
  }, [isPresent]);
8094
- return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React33.cloneElement(children, { ref }) });
8265
+ return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React14.cloneElement(children, { ref }) });
8095
8266
  }
8096
8267
 
8097
8268
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
@@ -8128,7 +8299,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
8128
8299
  useMemo(() => {
8129
8300
  presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
8130
8301
  }, [isPresent]);
8131
- React33.useEffect(() => {
8302
+ React14.useEffect(() => {
8132
8303
  !isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
8133
8304
  }, [isPresent]);
8134
8305
  if (mode === "popLayout") {
@@ -15397,7 +15568,7 @@ var LoadingPage = ({
15397
15568
  subMessage = "Please wait while we prepare your data",
15398
15569
  className
15399
15570
  }) => {
15400
- React33__default.useEffect(() => {
15571
+ React14__default.useEffect(() => {
15401
15572
  console.log("LoadingPage rendered with message:", message);
15402
15573
  const timeout = setTimeout(() => {
15403
15574
  console.warn("LoadingPage has been visible for more than 8 seconds. This might indicate an issue.");
@@ -15440,10 +15611,10 @@ var withAuth = (WrappedComponent2, options) => {
15440
15611
  return function WithAuthComponent(props) {
15441
15612
  const { session, loading } = useAuth();
15442
15613
  const router = useRouter();
15443
- React33.useEffect(() => {
15614
+ React14.useEffect(() => {
15444
15615
  console.log("withAuth state:", { loading, hasSession: !!session, requireAuth: defaultOptions.requireAuth });
15445
15616
  }, [session, loading]);
15446
- React33.useEffect(() => {
15617
+ React14.useEffect(() => {
15447
15618
  if (!loading && defaultOptions.requireAuth && !session) {
15448
15619
  console.log("Redirecting to login from withAuth");
15449
15620
  router.replace(defaultOptions.redirectTo);
@@ -16130,10 +16301,10 @@ var CycleTimeOverTimeChart = ({
16130
16301
  };
16131
16302
  const displayData = getDisplayData(data);
16132
16303
  const DURATION = displayData.length;
16133
- const [animatedData, setAnimatedData] = React33__default.useState(Array(DURATION).fill(0));
16134
- const prevDataRef = React33__default.useRef(Array(DURATION).fill(0));
16135
- const animationFrameRef = React33__default.useRef(null);
16136
- const animateToNewData = React33__default.useCallback((targetData) => {
16304
+ const [animatedData, setAnimatedData] = React14__default.useState(Array(DURATION).fill(0));
16305
+ const prevDataRef = React14__default.useRef(Array(DURATION).fill(0));
16306
+ const animationFrameRef = React14__default.useRef(null);
16307
+ const animateToNewData = React14__default.useCallback((targetData) => {
16137
16308
  const startData = [...prevDataRef.current];
16138
16309
  const startTime = performance.now();
16139
16310
  const duration = 1200;
@@ -16163,7 +16334,7 @@ var CycleTimeOverTimeChart = ({
16163
16334
  }
16164
16335
  animationFrameRef.current = requestAnimationFrame(animate);
16165
16336
  }, []);
16166
- React33__default.useEffect(() => {
16337
+ React14__default.useEffect(() => {
16167
16338
  if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
16168
16339
  const processedData = getDisplayData(data);
16169
16340
  animateToNewData(processedData);
@@ -16387,7 +16558,7 @@ var CycleTimeOverTimeChart = ({
16387
16558
  renderLegend()
16388
16559
  ] });
16389
16560
  };
16390
- var Card = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16561
+ var Card = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16391
16562
  "div",
16392
16563
  {
16393
16564
  ref,
@@ -16399,7 +16570,7 @@ var Card = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
16399
16570
  }
16400
16571
  ));
16401
16572
  Card.displayName = "Card";
16402
- var CardHeader = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16573
+ var CardHeader = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16403
16574
  "div",
16404
16575
  {
16405
16576
  ref,
@@ -16408,7 +16579,7 @@ var CardHeader = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE
16408
16579
  }
16409
16580
  ));
16410
16581
  CardHeader.displayName = "CardHeader";
16411
- var CardTitle = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16582
+ var CardTitle = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16412
16583
  "h3",
16413
16584
  {
16414
16585
  ref,
@@ -16420,7 +16591,7 @@ var CardTitle = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE_
16420
16591
  }
16421
16592
  ));
16422
16593
  CardTitle.displayName = "CardTitle";
16423
- var CardDescription = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16594
+ var CardDescription = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16424
16595
  "p",
16425
16596
  {
16426
16597
  ref,
@@ -16429,9 +16600,9 @@ var CardDescription = React33.forwardRef(({ className, ...props }, ref) => /* @_
16429
16600
  }
16430
16601
  ));
16431
16602
  CardDescription.displayName = "CardDescription";
16432
- var CardContent = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
16603
+ var CardContent = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
16433
16604
  CardContent.displayName = "CardContent";
16434
- var CardFooter = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16605
+ var CardFooter = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16435
16606
  "div",
16436
16607
  {
16437
16608
  ref,
@@ -16507,7 +16678,7 @@ var buttonVariants = cva(
16507
16678
  }
16508
16679
  }
16509
16680
  );
16510
- var Button = React33.forwardRef(
16681
+ var Button = React14.forwardRef(
16511
16682
  ({ className, variant, size, asChild = false, ...props }, ref) => {
16512
16683
  const Comp = asChild ? Slot : "button";
16513
16684
  return /* @__PURE__ */ jsx(
@@ -16538,10 +16709,30 @@ var HourlyOutputChart = ({
16538
16709
  };
16539
16710
  const shiftStartTime = getTimeFromTimeString(shiftStart);
16540
16711
  const SHIFT_DURATION = 11;
16541
- const [animatedData, setAnimatedData] = React33__default.useState(Array(SHIFT_DURATION).fill(0));
16542
- const prevDataRef = React33__default.useRef(Array(SHIFT_DURATION).fill(0));
16543
- const animationFrameRef = React33__default.useRef(null);
16544
- const animateToNewData = React33__default.useCallback((targetData) => {
16712
+ const [animatedData, setAnimatedData] = React14__default.useState(Array(SHIFT_DURATION).fill(0));
16713
+ const prevDataRef = React14__default.useRef(Array(SHIFT_DURATION).fill(0));
16714
+ const animationFrameRef = React14__default.useRef(null);
16715
+ const [shouldAnimateIdle, setShouldAnimateIdle] = React14__default.useState(false);
16716
+ const prevShowIdleTimeRef = React14__default.useRef(showIdleTime);
16717
+ const animationTimeoutRef = React14__default.useRef(null);
16718
+ React14__default.useEffect(() => {
16719
+ if (showIdleTime && !prevShowIdleTimeRef.current) {
16720
+ setShouldAnimateIdle(true);
16721
+ if (animationTimeoutRef.current) {
16722
+ clearTimeout(animationTimeoutRef.current);
16723
+ }
16724
+ animationTimeoutRef.current = setTimeout(() => {
16725
+ setShouldAnimateIdle(false);
16726
+ }, 1e3);
16727
+ }
16728
+ prevShowIdleTimeRef.current = showIdleTime;
16729
+ return () => {
16730
+ if (animationTimeoutRef.current) {
16731
+ clearTimeout(animationTimeoutRef.current);
16732
+ }
16733
+ };
16734
+ }, [showIdleTime]);
16735
+ const animateToNewData = React14__default.useCallback((targetData) => {
16545
16736
  const startData = [...prevDataRef.current];
16546
16737
  const startTime = performance.now();
16547
16738
  const duration = 1200;
@@ -16571,7 +16762,7 @@ var HourlyOutputChart = ({
16571
16762
  }
16572
16763
  animationFrameRef.current = requestAnimationFrame(animate);
16573
16764
  }, []);
16574
- React33__default.useEffect(() => {
16765
+ React14__default.useEffect(() => {
16575
16766
  if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
16576
16767
  const shiftData = data.slice(0, SHIFT_DURATION);
16577
16768
  animateToNewData(shiftData);
@@ -16582,7 +16773,7 @@ var HourlyOutputChart = ({
16582
16773
  }
16583
16774
  };
16584
16775
  }, [data, animateToNewData]);
16585
- const formatHour = (hourIndex) => {
16776
+ const formatHour = React14__default.useCallback((hourIndex) => {
16586
16777
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
16587
16778
  const startHour = Math.floor(startDecimalHour) % 24;
16588
16779
  const startMinute = Math.round(startDecimalHour % 1 * 60);
@@ -16598,8 +16789,8 @@ var HourlyOutputChart = ({
16598
16789
  return `${hour12}:${m.toString().padStart(2, "0")}${period}`;
16599
16790
  };
16600
16791
  return `${formatTime2(startHour, startMinute)}-${formatTime2(endHour, endMinute)}`;
16601
- };
16602
- const formatTimeRange = (hourIndex) => {
16792
+ }, [shiftStartTime.decimalHour]);
16793
+ const formatTimeRange = React14__default.useCallback((hourIndex) => {
16603
16794
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
16604
16795
  const startHour = Math.floor(startDecimalHour) % 24;
16605
16796
  const startMinute = Math.round(startDecimalHour % 1 * 60);
@@ -16612,22 +16803,24 @@ var HourlyOutputChart = ({
16612
16803
  return `${hour12}:${m.toString().padStart(2, "0")} ${period}`;
16613
16804
  };
16614
16805
  return `${formatTime2(startHour, startMinute)} - ${formatTime2(endHour, endMinute)}`;
16615
- };
16616
- const chartData = Array.from({ length: SHIFT_DURATION }, (_, i) => {
16617
- const actualHour = (shiftStartTime.hour + i) % 24;
16618
- const idleArray = idleTimeHourly?.[actualHour.toString()] || [];
16619
- const idleMinutes = idleArray.filter((val) => val === "1").length;
16620
- return {
16621
- hour: formatHour(i),
16622
- timeRange: formatTimeRange(i),
16623
- output: animatedData[i] || 0,
16624
- originalOutput: data[i] || 0,
16625
- // Keep original data for labels
16626
- color: (animatedData[i] || 0) >= Math.round(pphThreshold) ? "#00AB45" : "#E34329",
16627
- idleMinutes,
16628
- idleArray
16629
- };
16630
- });
16806
+ }, [shiftStartTime.decimalHour]);
16807
+ const chartData = React14__default.useMemo(() => {
16808
+ return Array.from({ length: SHIFT_DURATION }, (_, i) => {
16809
+ const actualHour = (shiftStartTime.hour + i) % 24;
16810
+ const idleArray = idleTimeHourly?.[actualHour.toString()] || [];
16811
+ const idleMinutes = idleArray.filter((val) => val === "1").length;
16812
+ return {
16813
+ hour: formatHour(i),
16814
+ timeRange: formatTimeRange(i),
16815
+ output: animatedData[i] || 0,
16816
+ originalOutput: data[i] || 0,
16817
+ // Keep original data for labels
16818
+ color: (animatedData[i] || 0) >= Math.round(pphThreshold) ? "#00AB45" : "#E34329",
16819
+ idleMinutes,
16820
+ idleArray
16821
+ };
16822
+ });
16823
+ }, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, formatHour, formatTimeRange]);
16631
16824
  const maxYValue = Math.ceil(pphThreshold * 1.5);
16632
16825
  const generateYAxisTicks = () => {
16633
16826
  const targetValue = Math.round(pphThreshold);
@@ -16720,10 +16913,10 @@ var HourlyOutputChart = ({
16720
16913
  contentStyle: {
16721
16914
  backgroundColor: "white",
16722
16915
  border: "none",
16723
- borderRadius: "8px",
16724
- boxShadow: "0 4px 12px rgba(0,0,0,0.1)",
16725
- padding: "8px 12px",
16726
- fontSize: "13px"
16916
+ borderRadius: "12px",
16917
+ boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
16918
+ padding: "0",
16919
+ fontSize: "14px"
16727
16920
  },
16728
16921
  content: (props) => {
16729
16922
  if (!props.active || !props.payload || props.payload.length === 0) return null;
@@ -16757,48 +16950,54 @@ var HourlyOutputChart = ({
16757
16950
  const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
16758
16951
  return `${hour12}:${minute.toString().padStart(2, "0")} ${period}`;
16759
16952
  };
16760
- return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-lg p-3 min-w-[180px]", children: [
16761
- /* @__PURE__ */ jsx("p", { className: "font-semibold text-gray-700 mb-2", children: data2.timeRange }),
16762
- /* @__PURE__ */ jsxs("p", { className: "text-gray-600", children: [
16763
- "Output: ",
16764
- /* @__PURE__ */ jsxs("span", { className: "font-medium text-gray-800", children: [
16765
- Math.round(data2.output),
16766
- " units"
16767
- ] })
16768
- ] }),
16769
- showIdleTime && data2.idleMinutes > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
16770
- /* @__PURE__ */ jsxs("p", { className: "text-gray-600 mb-1 border-t pt-1 mt-1", children: [
16771
- "Idle Time: ",
16772
- /* @__PURE__ */ jsxs("span", { className: "font-medium text-gray-700", children: [
16773
- data2.idleMinutes,
16774
- " minutes"
16953
+ return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-xl border border-gray-100 p-4 min-w-[220px]", children: [
16954
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsx("p", { className: "font-semibold text-gray-900 text-sm", children: data2.timeRange }) }),
16955
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
16956
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
16957
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: "Output" }),
16958
+ /* @__PURE__ */ jsxs("span", { className: "font-semibold text-gray-900 text-sm", children: [
16959
+ Math.round(data2.output),
16960
+ " units"
16775
16961
  ] })
16776
16962
  ] }),
16777
- idleRanges.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-2 text-xs", children: [
16778
- /* @__PURE__ */ jsx("p", { className: "font-medium text-gray-600 mb-1", children: "Idle periods:" }),
16779
- /* @__PURE__ */ jsx("div", { className: "space-y-0.5 max-h-32 overflow-y-auto", children: idleRanges.map((range, index) => {
16780
- const duration = range.end - range.start + 1;
16781
- const startTime = formatIdleTimestamp(range.start);
16782
- const endTime = formatIdleTimestamp(range.end + 1);
16783
- return /* @__PURE__ */ jsxs("div", { className: "text-gray-500 flex items-center gap-1", children: [
16784
- /* @__PURE__ */ jsx("span", { className: "inline-block w-1 h-1 bg-gray-400 rounded-full" }),
16785
- duration === 1 ? /* @__PURE__ */ jsxs("span", { children: [
16786
- startTime,
16787
- " ",
16788
- /* @__PURE__ */ jsx("span", { className: "text-gray-400", children: "(1 min)" })
16789
- ] }) : /* @__PURE__ */ jsxs("span", { children: [
16790
- startTime,
16791
- " - ",
16792
- endTime,
16793
- " ",
16794
- /* @__PURE__ */ jsxs("span", { className: "text-gray-400", children: [
16795
- "(",
16796
- duration,
16797
- " min)"
16798
- ] })
16799
- ] })
16800
- ] }, index);
16801
- }) })
16963
+ showIdleTime && data2.idleMinutes > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
16964
+ /* @__PURE__ */ jsx("div", { className: "border-t border-gray-100 pt-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
16965
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: "Idle Time" }),
16966
+ /* @__PURE__ */ jsxs("span", { className: "font-semibold text-orange-600 text-sm", children: [
16967
+ data2.idleMinutes,
16968
+ " minutes"
16969
+ ] })
16970
+ ] }) }),
16971
+ idleRanges.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-3 bg-gray-50 rounded-lg p-2.5", children: [
16972
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-gray-700 text-xs mb-2", children: "Idle periods:" }),
16973
+ /* @__PURE__ */ jsx("div", { className: "space-y-1 max-h-32 overflow-y-auto pr-1", children: idleRanges.map((range, index) => {
16974
+ const duration = range.end - range.start + 1;
16975
+ const startTime = formatIdleTimestamp(range.start);
16976
+ const endTime = formatIdleTimestamp(range.end + 1);
16977
+ return /* @__PURE__ */ jsxs("div", { className: "text-gray-600 flex items-center gap-2 text-xs", children: [
16978
+ /* @__PURE__ */ jsx("span", { className: "inline-block w-1.5 h-1.5 bg-orange-400 rounded-full flex-shrink-0" }),
16979
+ /* @__PURE__ */ jsx("span", { children: duration === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
16980
+ startTime,
16981
+ " ",
16982
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-400", children: [
16983
+ "(",
16984
+ duration,
16985
+ " min)"
16986
+ ] })
16987
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
16988
+ startTime,
16989
+ " - ",
16990
+ endTime,
16991
+ " ",
16992
+ /* @__PURE__ */ jsxs("span", { className: "text-gray-400", children: [
16993
+ "(",
16994
+ duration,
16995
+ " min)"
16996
+ ] })
16997
+ ] }) })
16998
+ ] }, index);
16999
+ }) })
17000
+ ] })
16802
17001
  ] })
16803
17002
  ] })
16804
17003
  ] });
@@ -16888,10 +17087,40 @@ var HourlyOutputChart = ({
16888
17087
  radius: [10, 10, 0, 0],
16889
17088
  fill: "url(#idlePattern)",
16890
17089
  opacity: 0.7,
16891
- isAnimationActive: true,
16892
- animationBegin: 200,
16893
- animationDuration: 800,
16894
- animationEasing: "ease-out"
17090
+ isAnimationActive: shouldAnimateIdle,
17091
+ animationBegin: shouldAnimateIdle ? 200 : 0,
17092
+ animationDuration: shouldAnimateIdle ? 800 : 0,
17093
+ animationEasing: "ease-out",
17094
+ children: /* @__PURE__ */ jsx(
17095
+ LabelList,
17096
+ {
17097
+ dataKey: "idleMinutes",
17098
+ position: "top",
17099
+ content: (props) => {
17100
+ const { x, y, width, value } = props;
17101
+ if (!value || value === 0) return null;
17102
+ return /* @__PURE__ */ jsxs(
17103
+ "text",
17104
+ {
17105
+ x: x + width / 2,
17106
+ y: y - 2,
17107
+ textAnchor: "middle",
17108
+ fontSize: "9",
17109
+ fontWeight: "600",
17110
+ fill: "#6b7280",
17111
+ style: {
17112
+ opacity: 1,
17113
+ pointerEvents: "none"
17114
+ },
17115
+ children: [
17116
+ value,
17117
+ "m"
17118
+ ]
17119
+ }
17120
+ );
17121
+ }
17122
+ }
17123
+ )
16895
17124
  }
16896
17125
  ),
16897
17126
  /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("pattern", { id: "idlePattern", patternUnits: "userSpaceOnUse", width: "4", height: "4", children: [
@@ -17320,7 +17549,7 @@ var EmptyStateMessage = ({
17320
17549
  iconClassName
17321
17550
  }) => {
17322
17551
  let IconContent = null;
17323
- if (React33__default.isValidElement(iconType)) {
17552
+ if (React14__default.isValidElement(iconType)) {
17324
17553
  IconContent = iconType;
17325
17554
  } else if (typeof iconType === "string") {
17326
17555
  const MappedIcon = IconMap[iconType];
@@ -19886,7 +20115,7 @@ function Skeleton({ className, ...props }) {
19886
20115
  var Select = SelectPrimitive.Root;
19887
20116
  var SelectGroup = SelectPrimitive.Group;
19888
20117
  var SelectValue = SelectPrimitive.Value;
19889
- var SelectTrigger = React33.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
20118
+ var SelectTrigger = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
19890
20119
  SelectPrimitive.Trigger,
19891
20120
  {
19892
20121
  ref,
@@ -19902,7 +20131,7 @@ var SelectTrigger = React33.forwardRef(({ className, children, ...props }, ref)
19902
20131
  }
19903
20132
  ));
19904
20133
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
19905
- var SelectScrollUpButton = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
20134
+ var SelectScrollUpButton = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
19906
20135
  SelectPrimitive.ScrollUpButton,
19907
20136
  {
19908
20137
  ref,
@@ -19912,7 +20141,7 @@ var SelectScrollUpButton = React33.forwardRef(({ className, ...props }, ref) =>
19912
20141
  }
19913
20142
  ));
19914
20143
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
19915
- var SelectScrollDownButton = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
20144
+ var SelectScrollDownButton = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
19916
20145
  SelectPrimitive.ScrollDownButton,
19917
20146
  {
19918
20147
  ref,
@@ -19922,7 +20151,7 @@ var SelectScrollDownButton = React33.forwardRef(({ className, ...props }, ref) =
19922
20151
  }
19923
20152
  ));
19924
20153
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
19925
- var SelectContent = React33.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
20154
+ var SelectContent = React14.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
19926
20155
  SelectPrimitive.Content,
19927
20156
  {
19928
20157
  ref,
@@ -19950,7 +20179,7 @@ var SelectContent = React33.forwardRef(({ className, children, position = "poppe
19950
20179
  }
19951
20180
  ) }));
19952
20181
  SelectContent.displayName = SelectPrimitive.Content.displayName;
19953
- var SelectLabel = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
20182
+ var SelectLabel = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
19954
20183
  SelectPrimitive.Label,
19955
20184
  {
19956
20185
  ref,
@@ -19959,7 +20188,7 @@ var SelectLabel = React33.forwardRef(({ className, ...props }, ref) => /* @__PUR
19959
20188
  }
19960
20189
  ));
19961
20190
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
19962
- var SelectItem = React33.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
20191
+ var SelectItem = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
19963
20192
  SelectPrimitive.Item,
19964
20193
  {
19965
20194
  ref,
@@ -19975,7 +20204,7 @@ var SelectItem = React33.forwardRef(({ className, children, ...props }, ref) =>
19975
20204
  }
19976
20205
  ));
19977
20206
  SelectItem.displayName = SelectPrimitive.Item.displayName;
19978
- var SelectSeparator = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
20207
+ var SelectSeparator = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
19979
20208
  SelectPrimitive.Separator,
19980
20209
  {
19981
20210
  ref,
@@ -21717,7 +21946,7 @@ var TREND_STYLES = {
21717
21946
  // Up
21718
21947
  };
21719
21948
  var getTrendArrowAndColor = (trend) => TREND_STYLES[trend] || { arrow: "", color: "" };
21720
- var VideoCard = React33__default.memo(({
21949
+ var VideoCard = React14__default.memo(({
21721
21950
  workspace,
21722
21951
  hlsUrl,
21723
21952
  shouldPlay,
@@ -21848,7 +22077,7 @@ var DEFAULT_WORKSPACE_HLS_URLS = {
21848
22077
  "WS06": "https://59.144.218.58:8443/camera5.m3u8"
21849
22078
  };
21850
22079
  var DEFAULT_HLS_URL = "https://192.168.5.9:8443/cam1.m3u8";
21851
- var VideoGridView = React33__default.memo(({
22080
+ var VideoGridView = React14__default.memo(({
21852
22081
  workspaces,
21853
22082
  selectedLine,
21854
22083
  className = "",
@@ -22131,7 +22360,7 @@ var arePropsEqual = (prevProps, nextProps) => {
22131
22360
  return prevProps.data.efficiency === nextProps.data.efficiency && prevProps.data.trend_score === nextProps.data.trend_score && prevProps.data.workspace_id === nextProps.data.workspace_id && prevProps.data.workspace_name === nextProps.data.workspace_name && prevProps.isBottleneck === nextProps.isBottleneck && prevProps.isLowEfficiency === nextProps.isLowEfficiency && prevProps.isVeryLowEfficiency === nextProps.isVeryLowEfficiency && // Position doesn't need deep equality check as it's generally static
22132
22361
  prevProps.position.id === nextProps.position.id;
22133
22362
  };
22134
- var WorkspaceGridItem = React33__default.memo(({
22363
+ var WorkspaceGridItem = React14__default.memo(({
22135
22364
  data,
22136
22365
  position,
22137
22366
  isBottleneck = false,
@@ -22224,7 +22453,7 @@ var WorkspaceGridItem = React33__default.memo(({
22224
22453
  );
22225
22454
  }, arePropsEqual);
22226
22455
  WorkspaceGridItem.displayName = "WorkspaceGridItem";
22227
- var WorkspaceGrid = React33__default.memo(({
22456
+ var WorkspaceGrid = React14__default.memo(({
22228
22457
  workspaces,
22229
22458
  isPdfMode = false,
22230
22459
  customWorkspacePositions,
@@ -22413,7 +22642,7 @@ var KPICard = ({
22413
22642
  }) => {
22414
22643
  useThemeConfig();
22415
22644
  const { formatNumber } = useFormatNumber();
22416
- const trendInfo = React33__default.useMemo(() => {
22645
+ const trendInfo = React14__default.useMemo(() => {
22417
22646
  let trendValue = trend || "neutral";
22418
22647
  if (change !== void 0 && trend === void 0) {
22419
22648
  trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
@@ -22436,7 +22665,7 @@ var KPICard = ({
22436
22665
  const shouldShowTrend = !(change === 0 && trend === void 0);
22437
22666
  return { trendValue, Icon: Icon2, colorClass, shouldShowTrend };
22438
22667
  }, [trend, change]);
22439
- const formattedValue = React33__default.useMemo(() => {
22668
+ const formattedValue = React14__default.useMemo(() => {
22440
22669
  if (title === "Quality Compliance" && typeof value === "number") {
22441
22670
  return value.toFixed(1);
22442
22671
  }
@@ -22450,7 +22679,7 @@ var KPICard = ({
22450
22679
  }
22451
22680
  return value;
22452
22681
  }, [value, title]);
22453
- const formattedChange = React33__default.useMemo(() => {
22682
+ const formattedChange = React14__default.useMemo(() => {
22454
22683
  if (change === void 0 || change === 0) return null;
22455
22684
  const absChange = Math.abs(change);
22456
22685
  return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
@@ -22862,7 +23091,7 @@ var Breadcrumbs = ({ items }) => {
22862
23091
  }
22863
23092
  }
22864
23093
  };
22865
- return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(React33__default.Fragment, { children: [
23094
+ return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(React14__default.Fragment, { children: [
22866
23095
  index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
22867
23096
  /* @__PURE__ */ jsxs(
22868
23097
  "span",
@@ -23681,7 +23910,7 @@ var ThreadSidebar = ({
23681
23910
  ] });
23682
23911
  };
23683
23912
  var axelProfilePng = "/axel-profile.png";
23684
- var ProfilePicture = React33__default.memo(({ alt = "Axel", className = "w-12 h-12" }) => {
23913
+ var ProfilePicture = React14__default.memo(({ alt = "Axel", className = "w-12 h-12" }) => {
23685
23914
  return /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx("div", { className: `${className} rounded-xl overflow-hidden shadow-sm`, children: /* @__PURE__ */ jsx(
23686
23915
  "img",
23687
23916
  {
@@ -25127,6 +25356,17 @@ var SlackAPI = class {
25127
25356
  const config = _getDashboardConfigInstance();
25128
25357
  const endpointsConfig = config.endpoints ?? DEFAULT_ENDPOINTS_CONFIG;
25129
25358
  const { slackWebhookUrl, slackProxyEndpoint } = endpointsConfig;
25359
+ console.log("SlackAPI Debug - Configuration check:", {
25360
+ hasConfig: !!config,
25361
+ hasEndpoints: !!config.endpoints,
25362
+ slackWebhookUrl: slackWebhookUrl ? "configured" : "not configured",
25363
+ slackProxyEndpoint: slackProxyEndpoint ? "configured" : "not configured",
25364
+ envVariable: process.env.SLACK_WEBHOOK_URL ? "set" : "not set",
25365
+ publicEnvVariable: process.env.NEXT_PUBLIC_SLACK_WEBHOOK_URL ? "set" : "not set"
25366
+ });
25367
+ if (process.env.NEXT_PUBLIC_SLACK_WEBHOOK_URL && !process.env.SLACK_WEBHOOK_URL) {
25368
+ console.warn("\u26A0\uFE0F SECURITY WARNING: Using NEXT_PUBLIC_SLACK_WEBHOOK_URL exposes your webhook URL to the client. Consider using a server-side proxy instead.");
25369
+ }
25130
25370
  if (slackWebhookUrl) {
25131
25371
  const slackMessage = this.formatSlackMessage(ticket);
25132
25372
  const response = await fetch(slackWebhookUrl, {
@@ -25161,6 +25401,10 @@ var SlackAPI = class {
25161
25401
  return;
25162
25402
  }
25163
25403
  console.warn("Slack notification skipped: No webhook or proxy endpoint configured");
25404
+ console.info("To fix this, either:");
25405
+ console.info("1. Set up a server-side proxy endpoint and configure slackProxyEndpoint in your dashboard config");
25406
+ console.info("2. For development only: use NEXT_PUBLIC_SLACK_WEBHOOK_URL (not recommended for production)");
25407
+ console.info("3. Configure the webhook URL directly in your dashboard config at runtime");
25164
25408
  } catch (error) {
25165
25409
  console.error("Failed to send Slack notification:", error);
25166
25410
  throw error;
@@ -25531,6 +25775,24 @@ function HomeView({
25531
25775
  const [selectedLineId, setSelectedLineId] = useState(defaultLineId);
25532
25776
  const [isChangingFilter, setIsChangingFilter] = useState(false);
25533
25777
  const [errorMessage, setErrorMessage] = useState(null);
25778
+ const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
25779
+ useEffect(() => {
25780
+ const initDisplayNames = async () => {
25781
+ try {
25782
+ await preInitializeWorkspaceDisplayNames(selectedLineId);
25783
+ setDisplayNamesInitialized(true);
25784
+ } catch (error) {
25785
+ console.error("Failed to pre-initialize workspace display names:", error);
25786
+ setDisplayNamesInitialized(true);
25787
+ }
25788
+ };
25789
+ initDisplayNames();
25790
+ }, [selectedLineId]);
25791
+ const {
25792
+ displayNames: workspaceDisplayNames,
25793
+ loading: displayNamesLoading,
25794
+ error: displayNamesError
25795
+ } = useWorkspaceDisplayNames(void 0, selectedLineId);
25534
25796
  useCallback(() => {
25535
25797
  console.log("Refetching KPIs after line metrics update");
25536
25798
  }, []);
@@ -25603,16 +25865,16 @@ function HomeView({
25603
25865
  const lineTitle = useMemo(() => {
25604
25866
  return factoryName;
25605
25867
  }, [factoryName]);
25606
- const isLoading = !isHydrated || metricsLoading || kpisLoading || isChangingFilter;
25868
+ const isLoading = !isHydrated || metricsLoading || kpisLoading || isChangingFilter || displayNamesLoading || !displayNamesInitialized;
25607
25869
  if (isLoading) {
25608
25870
  return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-slate-50", children: /* @__PURE__ */ jsx(LoadingPageCmp, { message: "Loading dashboard..." }) });
25609
25871
  }
25610
- if (errorMessage) {
25872
+ if (errorMessage || displayNamesError) {
25611
25873
  return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "rounded-lg bg-white p-6 shadow-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3 text-red-500", children: [
25612
25874
  /* @__PURE__ */ 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__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
25613
25875
  /* @__PURE__ */ jsxs("span", { className: "text-lg font-medium", children: [
25614
25876
  "Error: ",
25615
- errorMessage
25877
+ errorMessage || displayNamesError?.message
25616
25878
  ] })
25617
25879
  ] }) }) });
25618
25880
  }
@@ -25632,7 +25894,7 @@ function HomeView({
25632
25894
  /* @__PURE__ */ jsx(DashboardHeader, { lineTitle, className: "mb-1 sm:mb-0" }),
25633
25895
  memoizedKPIs && /* @__PURE__ */ jsx(KPISection2, { kpis: memoizedKPIs, className: "w-full sm:w-auto" })
25634
25896
  ] }) }),
25635
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden", children: memoizedWorkspaceMetrics.length > 0 ? /* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-80px)] sm:min-h-0", children: React33__default.createElement(WorkspaceGrid, {
25897
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden", children: memoizedWorkspaceMetrics.length > 0 ? /* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-80px)] sm:min-h-0", children: React14__default.createElement(WorkspaceGrid, {
25636
25898
  workspaces: memoizedWorkspaceMetrics,
25637
25899
  lineNames,
25638
25900
  factoryView: factoryViewId,
@@ -25653,7 +25915,7 @@ function HomeView({
25653
25915
  }
25654
25916
  );
25655
25917
  }
25656
- var AuthenticatedHomeView = withAuth(React33__default.memo(HomeView));
25918
+ var AuthenticatedHomeView = withAuth(React14__default.memo(HomeView));
25657
25919
  var HomeView_default = HomeView;
25658
25920
 
25659
25921
  // src/views/kpi-detail-view.types.ts
@@ -26486,7 +26748,7 @@ var LineCard = ({ line, onClick }) => {
26486
26748
  const { kpis, isLoading, error } = useLineKPIs({ lineId: line.id });
26487
26749
  const shiftConfig = useShiftConfig();
26488
26750
  const dateTimeConfig = useDateTimeConfig();
26489
- const isOnTrack = React33__default.useMemo(() => {
26751
+ const isOnTrack = React14__default.useMemo(() => {
26490
26752
  if (!kpis) return null;
26491
26753
  const currentTime = /* @__PURE__ */ new Date();
26492
26754
  const timezone = dateTimeConfig.defaultTimezone || "Asia/Kolkata";
@@ -30450,4 +30712,4 @@ var S3Service = class {
30450
30712
  }
30451
30713
  };
30452
30714
 
30453
- export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, FactoryView_default as FactoryView, GridComponentsPlaceholder, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LiveTimer, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSpinner_default as LoadingSpinner, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, NoWorkspaceData, OptifyeAgentClient, OutputProgressChart, PageHeader, ProfileView_default as ProfileView, RegistryProvider, S3Service, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SingleVideoStream_default as SingleVideoStream, Skeleton, SlackAPI, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultTabForWorkspace, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isTransitionPeriod, isValidLineInfoPayload, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, optifyeAgentClient, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, s3VideoPreloader, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAnalyticsConfig, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHookOverride, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, useRealtimeLineMetrics, useRegistry, useShiftConfig, useShifts, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };
30715
+ export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, FactoryView_default as FactoryView, GridComponentsPlaceholder, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LiveTimer, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSpinner_default as LoadingSpinner, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, NoWorkspaceData, OptifyeAgentClient, OutputProgressChart, PageHeader, ProfileView_default as ProfileView, RegistryProvider, S3Service, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SingleVideoStream_default as SingleVideoStream, Skeleton, SlackAPI, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultTabForWorkspace, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isTransitionPeriod, isValidLineInfoPayload, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, optifyeAgentClient, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, s3VideoPreloader, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAnalyticsConfig, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHookOverride, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, useRealtimeLineMetrics, useRegistry, useShiftConfig, useShifts, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };