@optifye/dashboard-core 6.11.32 → 6.11.34

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 React142 from 'react';
2
- import React142__default, { createContext, useRef, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore, useId, Children, isValidElement, useInsertionEffect, startTransition, Fragment as Fragment$1, createElement, Component } from 'react';
1
+ import * as React143 from 'react';
2
+ import React143__default, { createContext, useRef, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore, useId, Children, isValidElement, useInsertionEffect, startTransition, 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 { toast } from 'sonner';
@@ -1938,14 +1938,14 @@ var useIdleTimeVlmConfig = () => {
1938
1938
  }
1939
1939
  return context;
1940
1940
  };
1941
- var DashboardConfigContext = React142.createContext(void 0);
1941
+ var DashboardConfigContext = React143.createContext(void 0);
1942
1942
  var DashboardProvider = ({ config: userProvidedConfig, children }) => {
1943
- const fullConfig = React142.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
1943
+ const fullConfig = React143.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
1944
1944
  _setDashboardConfigInstance(fullConfig);
1945
- React142.useEffect(() => {
1945
+ React143.useEffect(() => {
1946
1946
  _setDashboardConfigInstance(fullConfig);
1947
1947
  }, [fullConfig]);
1948
- React142.useEffect(() => {
1948
+ React143.useEffect(() => {
1949
1949
  if (!fullConfig.theme) return;
1950
1950
  const styleId = "dashboard-core-theme-vars";
1951
1951
  let styleEl = document.getElementById(styleId);
@@ -1971,7 +1971,7 @@ var DashboardProvider = ({ config: userProvidedConfig, children }) => {
1971
1971
  return /* @__PURE__ */ jsx(DashboardConfigContext.Provider, { value: fullConfig, children: /* @__PURE__ */ jsx(IdleTimeVlmConfigProvider, { children }) });
1972
1972
  };
1973
1973
  var useDashboardConfig = () => {
1974
- const ctx = React142.useContext(DashboardConfigContext);
1974
+ const ctx = React143.useContext(DashboardConfigContext);
1975
1975
  if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
1976
1976
  return ctx;
1977
1977
  };
@@ -2444,6 +2444,107 @@ var _getSupabaseInstanceOptional = () => {
2444
2444
  return supabaseInstance;
2445
2445
  };
2446
2446
 
2447
+ // src/lib/utils/sentryContext.ts
2448
+ function getSentry() {
2449
+ try {
2450
+ return __require("@sentry/nextjs");
2451
+ } catch {
2452
+ return null;
2453
+ }
2454
+ }
2455
+ function isIgnorableFrontendError(error) {
2456
+ const name = error && typeof error === "object" ? error.name || "" : "";
2457
+ const message = error instanceof Error ? error.message : String(error ?? "");
2458
+ const lowerMessage = message.toLowerCase();
2459
+ return name === "AbortError" || lowerMessage.includes("the operation was aborted") || lowerMessage.includes("signal is aborted") || lowerMessage.includes("resizeobserver loop");
2460
+ }
2461
+ function setSentryUserContext(user) {
2462
+ const sentry = getSentry();
2463
+ if (!sentry) return;
2464
+ if (user) {
2465
+ sentry.setUser({
2466
+ id: user.id,
2467
+ email: user.email
2468
+ });
2469
+ sentry.setTags({
2470
+ company_id: user.company_id || "unknown",
2471
+ role: user.role || "unknown",
2472
+ role_level: user.role_level || "unknown"
2473
+ });
2474
+ } else {
2475
+ sentry.setUser(null);
2476
+ sentry.setTags({
2477
+ company_id: void 0,
2478
+ role: void 0,
2479
+ role_level: void 0
2480
+ });
2481
+ }
2482
+ }
2483
+ function setSentryWorkspaceContext(config) {
2484
+ const sentry = getSentry();
2485
+ if (!sentry) return;
2486
+ sentry.setTags({
2487
+ workspace_company: config.companyId || "unknown",
2488
+ workspace_factory: config.factoryId || "unknown",
2489
+ factory_name: config.factoryName || "unknown"
2490
+ });
2491
+ }
2492
+ function clearSentryContext() {
2493
+ const sentry = getSentry();
2494
+ if (!sentry) return;
2495
+ sentry.setUser(null);
2496
+ sentry.setTags({
2497
+ company_id: void 0,
2498
+ role: void 0,
2499
+ role_level: void 0,
2500
+ workspace_company: void 0,
2501
+ workspace_factory: void 0,
2502
+ factory_name: void 0
2503
+ });
2504
+ }
2505
+ function applyScopeExtras(scope, extras) {
2506
+ if (!extras) return;
2507
+ if (scope.setExtras) {
2508
+ scope.setExtras(extras);
2509
+ return;
2510
+ }
2511
+ if (scope.setExtra) {
2512
+ Object.entries(extras).forEach(([key, value]) => scope.setExtra?.(key, value));
2513
+ }
2514
+ }
2515
+ function captureSentryMessage(message, level = "warning", extras) {
2516
+ const sentry = getSentry();
2517
+ if (!sentry || !sentry.captureMessage) return;
2518
+ if (sentry.withScope) {
2519
+ sentry.withScope((scope) => {
2520
+ scope.setLevel?.(level);
2521
+ applyScopeExtras(scope, extras);
2522
+ sentry.captureMessage?.(message);
2523
+ });
2524
+ return;
2525
+ }
2526
+ sentry.captureMessage(message, level);
2527
+ }
2528
+ function captureSentryException(error, extras) {
2529
+ const sentry = getSentry();
2530
+ if (!sentry || !sentry.captureException) return;
2531
+ if (sentry.withScope) {
2532
+ sentry.withScope((scope) => {
2533
+ scope.setLevel?.("error");
2534
+ applyScopeExtras(scope, extras);
2535
+ sentry.captureException?.(error);
2536
+ });
2537
+ return;
2538
+ }
2539
+ sentry.captureException(error);
2540
+ }
2541
+ function captureHandledFrontendException(error, extras) {
2542
+ if (isIgnorableFrontendError(error)) {
2543
+ return;
2544
+ }
2545
+ captureSentryException(error, extras);
2546
+ }
2547
+
2447
2548
  // src/lib/services/backendClient.ts
2448
2549
  var ACCESS_TOKEN_REFRESH_BUFFER_MS = 6e4;
2449
2550
  var cachedAccessToken = null;
@@ -2499,6 +2600,40 @@ var defaultDedupeKey = (method, url, body) => {
2499
2600
  const bodyKey = body === void 0 ? "" : typeof body === "string" ? body : JSON.stringify(body);
2500
2601
  return `${cachedUserId || "anon"}::${method.toUpperCase()}::${url}::${bodyKey}`;
2501
2602
  };
2603
+ var DEFAULT_TIMEOUT_MS = 1e4;
2604
+ var DEFAULT_RETRY_DELAY_MS = 750;
2605
+ var createAbortError = () => {
2606
+ try {
2607
+ return new DOMException("The operation was aborted.", "AbortError");
2608
+ } catch {
2609
+ const error = new Error("The operation was aborted.");
2610
+ error.name = "AbortError";
2611
+ return error;
2612
+ }
2613
+ };
2614
+ var getStatusFromError = (error) => {
2615
+ const message = error instanceof Error ? error.message : String(error ?? "");
2616
+ const statusMatch = message.match(/\((\d{3})\)/) || message.match(/http\s+(\d{3})/i);
2617
+ if (!statusMatch) {
2618
+ return null;
2619
+ }
2620
+ const status = Number.parseInt(statusMatch[1], 10);
2621
+ return Number.isFinite(status) ? status : null;
2622
+ };
2623
+ var isAbortError = (error) => {
2624
+ return error instanceof Error && error.name === "AbortError";
2625
+ };
2626
+ var isRetryableError = (error) => {
2627
+ if (isAbortError(error)) {
2628
+ return false;
2629
+ }
2630
+ const status = getStatusFromError(error);
2631
+ if (status !== null) {
2632
+ return status >= 500 || status === 408 || status === 425 || status === 429;
2633
+ }
2634
+ const message = error instanceof Error ? error.message.toLowerCase() : String(error ?? "").toLowerCase();
2635
+ return message.includes("failed to fetch") || message.includes("networkerror") || message.includes("network request failed") || message.includes("load failed") || message.includes("timed out") || message.includes("fetch failed");
2636
+ };
2502
2637
  var fetchBackendJson = async (supabase, endpoint, options = {}) => {
2503
2638
  const baseUrl = getBackendUrl();
2504
2639
  const url = endpoint.startsWith("http") ? endpoint : `${baseUrl}${endpoint.startsWith("/") ? "" : "/"}${endpoint}`;
@@ -2510,25 +2645,66 @@ var fetchBackendJson = async (supabase, endpoint, options = {}) => {
2510
2645
  return existing;
2511
2646
  }
2512
2647
  const requestPromise = (async () => {
2513
- const headers = new Headers(options.headers || {});
2514
- if (!options.skipAuth) {
2515
- const token = await getAuthToken(supabase);
2516
- headers.set("Authorization", `Bearer ${token}`);
2517
- }
2518
- if (!headers.has("Content-Type") && options.body !== void 0) {
2519
- headers.set("Content-Type", "application/json");
2520
- }
2521
- const response = await fetch(url, {
2522
- ...options,
2523
- headers
2524
- });
2525
- if (!response.ok) {
2526
- const errorText = await response.text();
2527
- throw new Error(`Backend API error (${response.status}): ${errorText}`);
2648
+ const {
2649
+ dedupeKey: _dedupeKey,
2650
+ skipAuth,
2651
+ timeoutMs = DEFAULT_TIMEOUT_MS,
2652
+ retries = 0,
2653
+ retryDelayMs = DEFAULT_RETRY_DELAY_MS,
2654
+ signal: externalSignal,
2655
+ ...fetchOptions
2656
+ } = options;
2657
+ for (let attempt = 0; attempt <= retries; attempt += 1) {
2658
+ if (externalSignal?.aborted) {
2659
+ throw createAbortError();
2660
+ }
2661
+ const headers = new Headers(fetchOptions.headers || {});
2662
+ if (!skipAuth) {
2663
+ const token = await getAuthToken(supabase);
2664
+ headers.set("Authorization", `Bearer ${token}`);
2665
+ }
2666
+ if (!headers.has("Content-Type") && fetchOptions.body !== void 0) {
2667
+ headers.set("Content-Type", "application/json");
2668
+ }
2669
+ const controller = new AbortController();
2670
+ const timeoutId = globalThis.setTimeout(() => controller.abort(), timeoutMs);
2671
+ const abortListener = () => controller.abort();
2672
+ externalSignal?.addEventListener("abort", abortListener, { once: true });
2673
+ try {
2674
+ const response = await fetch(url, {
2675
+ ...fetchOptions,
2676
+ headers,
2677
+ signal: controller.signal
2678
+ });
2679
+ if (!response.ok) {
2680
+ const errorText = await response.text();
2681
+ throw new Error(`Backend API error (${response.status}): ${errorText}`);
2682
+ }
2683
+ if (response.status === 204) {
2684
+ return void 0;
2685
+ }
2686
+ const text = await response.text();
2687
+ return text ? JSON.parse(text) : void 0;
2688
+ } catch (error) {
2689
+ const wrappedError = externalSignal?.aborted || controller.signal.aborted && !isAbortError(error) ? createAbortError() : error;
2690
+ if (attempt >= retries || !isRetryableError(wrappedError)) {
2691
+ captureHandledFrontendException(wrappedError, {
2692
+ surface: "backend_client",
2693
+ url,
2694
+ method,
2695
+ retry_attempt: attempt,
2696
+ retries,
2697
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
2698
+ });
2699
+ throw wrappedError;
2700
+ }
2701
+ await new Promise((resolve) => globalThis.setTimeout(resolve, retryDelayMs));
2702
+ } finally {
2703
+ globalThis.clearTimeout(timeoutId);
2704
+ externalSignal?.removeEventListener("abort", abortListener);
2705
+ }
2528
2706
  }
2529
- if (response.status === 204) return void 0;
2530
- const text = await response.text();
2531
- return text ? JSON.parse(text) : void 0;
2707
+ return void 0;
2532
2708
  })();
2533
2709
  inFlightRequests.set(dedupeKey, requestPromise);
2534
2710
  try {
@@ -2639,9 +2815,23 @@ var ApiClient = class {
2639
2815
  continue;
2640
2816
  }
2641
2817
  if (silentErrors) {
2818
+ captureHandledFrontendException(lastError, {
2819
+ surface: "api_client",
2820
+ url,
2821
+ retries,
2822
+ silent_errors: true,
2823
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
2824
+ });
2642
2825
  console.warn("[ApiClient] All retries exhausted, returning fallback data");
2643
2826
  return fallbackData;
2644
2827
  } else {
2828
+ captureHandledFrontendException(lastError, {
2829
+ surface: "api_client",
2830
+ url,
2831
+ retries,
2832
+ silent_errors: false,
2833
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
2834
+ });
2645
2835
  throw lastError;
2646
2836
  }
2647
2837
  }
@@ -4355,6 +4545,49 @@ var dashboardService = {
4355
4545
  throw err;
4356
4546
  }
4357
4547
  },
4548
+ async getAssemblyMonthlyPoorestPerformers(lineIdInput, month, year, options) {
4549
+ const supabase = _getSupabaseInstance();
4550
+ const config = _getDashboardConfigInstance();
4551
+ const entityConfig = config.entityConfig ?? DEFAULT_ENTITY_CONFIG;
4552
+ const configuredLineIds = getConfiguredLineIds(entityConfig);
4553
+ const factoryViewId = entityConfig.factoryViewId ?? "factory";
4554
+ const startDate = options?.startDate ? new Date(options.startDate) : new Date(year, month, 1);
4555
+ const endDate = options?.endDate ? new Date(options.endDate) : new Date(year, month + 1, 0);
4556
+ const formatDate2 = (date) => {
4557
+ const year2 = date.getFullYear();
4558
+ const month2 = String(date.getMonth() + 1).padStart(2, "0");
4559
+ const day = String(date.getDate()).padStart(2, "0");
4560
+ return `${year2}-${month2}-${day}`;
4561
+ };
4562
+ const formattedStartDate = formatDate2(startDate);
4563
+ const formattedEndDate = formatDate2(endDate);
4564
+ const params = new URLSearchParams({
4565
+ start_date: formattedStartDate,
4566
+ end_date: formattedEndDate,
4567
+ company_id: entityConfig.companyId || ""
4568
+ });
4569
+ if (lineIdInput === factoryViewId) {
4570
+ if (!isValidFactoryViewConfiguration(entityConfig)) {
4571
+ throw new Error("Factory View requires at least one configured line for monthly data.");
4572
+ }
4573
+ params.set("line_ids", configuredLineIds.join(","));
4574
+ } else {
4575
+ params.set("line_id", lineIdInput);
4576
+ }
4577
+ if (options?.shiftIds && options.shiftIds.length > 0) {
4578
+ params.set("shift_ids", options.shiftIds.join(","));
4579
+ }
4580
+ try {
4581
+ const response = await fetchBackendJson(
4582
+ supabase,
4583
+ `/api/dashboard/line-monthly-assembly-poorest-performers?${params.toString()}`
4584
+ );
4585
+ return response || {};
4586
+ } catch (err) {
4587
+ console.error("Exception in getAssemblyMonthlyPoorestPerformers:", err);
4588
+ throw err;
4589
+ }
4590
+ },
4358
4591
  async getUnderperformingWorkspaces(lineIdInput, monthInput, yearInput, shiftIds, startDate, endDate) {
4359
4592
  _getSupabaseInstance();
4360
4593
  const config = _getDashboardConfigInstance();
@@ -4919,6 +5152,13 @@ var workspaceService = {
4919
5152
  return displayNamesMap;
4920
5153
  } catch (error) {
4921
5154
  console.error("Error fetching workspace display names:", error);
5155
+ captureSentryException(error, {
5156
+ surface: "workspace_display_names",
5157
+ route: "/api/workspaces/display-names",
5158
+ company_id: companyId || null,
5159
+ line_id: lineId || null,
5160
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
5161
+ });
4922
5162
  throw error;
4923
5163
  }
4924
5164
  },
@@ -6573,95 +6813,6 @@ function clearAllRateLimits2() {
6573
6813
  rateLimitMap2.clear();
6574
6814
  }
6575
6815
 
6576
- // src/lib/utils/sentryContext.ts
6577
- function getSentry() {
6578
- try {
6579
- return __require("@sentry/nextjs");
6580
- } catch {
6581
- return null;
6582
- }
6583
- }
6584
- function setSentryUserContext(user) {
6585
- const sentry = getSentry();
6586
- if (!sentry) return;
6587
- if (user) {
6588
- sentry.setUser({
6589
- id: user.id,
6590
- email: user.email
6591
- });
6592
- sentry.setTags({
6593
- company_id: user.company_id || "unknown",
6594
- role: user.role || "unknown",
6595
- role_level: user.role_level || "unknown"
6596
- });
6597
- } else {
6598
- sentry.setUser(null);
6599
- sentry.setTags({
6600
- company_id: void 0,
6601
- role: void 0,
6602
- role_level: void 0
6603
- });
6604
- }
6605
- }
6606
- function setSentryWorkspaceContext(config) {
6607
- const sentry = getSentry();
6608
- if (!sentry) return;
6609
- sentry.setTags({
6610
- workspace_company: config.companyId || "unknown",
6611
- workspace_factory: config.factoryId || "unknown",
6612
- factory_name: config.factoryName || "unknown"
6613
- });
6614
- }
6615
- function clearSentryContext() {
6616
- const sentry = getSentry();
6617
- if (!sentry) return;
6618
- sentry.setUser(null);
6619
- sentry.setTags({
6620
- company_id: void 0,
6621
- role: void 0,
6622
- role_level: void 0,
6623
- workspace_company: void 0,
6624
- workspace_factory: void 0,
6625
- factory_name: void 0
6626
- });
6627
- }
6628
- function applyScopeExtras(scope, extras) {
6629
- if (!extras) return;
6630
- if (scope.setExtras) {
6631
- scope.setExtras(extras);
6632
- return;
6633
- }
6634
- if (scope.setExtra) {
6635
- Object.entries(extras).forEach(([key, value]) => scope.setExtra?.(key, value));
6636
- }
6637
- }
6638
- function captureSentryMessage(message, level = "warning", extras) {
6639
- const sentry = getSentry();
6640
- if (!sentry || !sentry.captureMessage) return;
6641
- if (sentry.withScope) {
6642
- sentry.withScope((scope) => {
6643
- scope.setLevel?.(level);
6644
- applyScopeExtras(scope, extras);
6645
- sentry.captureMessage?.(message);
6646
- });
6647
- return;
6648
- }
6649
- sentry.captureMessage(message, level);
6650
- }
6651
- function captureSentryException(error, extras) {
6652
- const sentry = getSentry();
6653
- if (!sentry || !sentry.captureException) return;
6654
- if (sentry.withScope) {
6655
- sentry.withScope((scope) => {
6656
- scope.setLevel?.("error");
6657
- applyScopeExtras(scope, extras);
6658
- sentry.captureException?.(error);
6659
- });
6660
- return;
6661
- }
6662
- sentry.captureException(error);
6663
- }
6664
-
6665
6816
  // src/lib/services/mixpanelService.ts
6666
6817
  var ROOT_DASHBOARD_EVENT_NAMES = {
6667
6818
  operations_overview: "Operations Overview Page Clicked",
@@ -8716,6 +8867,12 @@ var LinesService = class {
8716
8867
  }));
8717
8868
  } catch (error) {
8718
8869
  console.error("Error fetching lines:", error);
8870
+ captureHandledFrontendException(error, {
8871
+ surface: "lines_service",
8872
+ operation: "getLinesByCompanyId",
8873
+ company_id: companyId,
8874
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
8875
+ });
8719
8876
  throw new Error(`Failed to fetch lines: ${error.message}`);
8720
8877
  }
8721
8878
  }
@@ -8765,6 +8922,11 @@ var LinesService = class {
8765
8922
  }));
8766
8923
  } catch (error) {
8767
8924
  console.error("Error fetching all lines:", error);
8925
+ captureHandledFrontendException(error, {
8926
+ surface: "lines_service",
8927
+ operation: "getAllLines",
8928
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
8929
+ });
8768
8930
  throw new Error(`Failed to fetch lines: ${error.message}`);
8769
8931
  }
8770
8932
  }
@@ -8823,6 +8985,12 @@ var LinesService = class {
8823
8985
  };
8824
8986
  } catch (error) {
8825
8987
  console.error("Error fetching line:", error);
8988
+ captureHandledFrontendException(error, {
8989
+ surface: "lines_service",
8990
+ operation: "getLineById",
8991
+ line_id: lineId,
8992
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
8993
+ });
8826
8994
  throw new Error(`Failed to fetch line: ${error.message}`);
8827
8995
  }
8828
8996
  }
@@ -10541,6 +10709,17 @@ var AuthProvider = ({ children }) => {
10541
10709
  const isRecoveringSession = authStatus === "recovering";
10542
10710
  useEffect(() => {
10543
10711
  currentUserRef.current = user;
10712
+ if (user) {
10713
+ setSentryUserContext({
10714
+ id: user.id,
10715
+ email: user.email,
10716
+ role: user.role,
10717
+ role_level: user.role_level,
10718
+ company_id: user.company_id
10719
+ });
10720
+ return;
10721
+ }
10722
+ clearSentryContext();
10544
10723
  }, [user]);
10545
10724
  const setTrackedSession = useCallback((nextSession) => {
10546
10725
  latestSessionRef.current = nextSession;
@@ -10701,6 +10880,17 @@ var AuthProvider = ({ children }) => {
10701
10880
  }
10702
10881
  if (isRetryableSessionError(err)) {
10703
10882
  console.warn("[AuthContext] Retryable session hydration error, entering recovery mode");
10883
+ if (recoveryAttemptRef.current === 0) {
10884
+ captureSentryException(err, {
10885
+ surface: "auth_session_hydration",
10886
+ phase: isReauth ? "reauth" : "initial",
10887
+ retryable: true,
10888
+ auth_status: authStatus,
10889
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown",
10890
+ visibility_state: typeof document !== "undefined" ? document.visibilityState : "unknown",
10891
+ online_state: typeof navigator !== "undefined" ? navigator.onLine : "unknown"
10892
+ });
10893
+ }
10704
10894
  enterRecoveryMode(supabaseSession);
10705
10895
  return;
10706
10896
  }
@@ -10720,6 +10910,13 @@ var AuthProvider = ({ children }) => {
10720
10910
  }
10721
10911
  resetRecoveryState();
10722
10912
  clearAuthSnapshot();
10913
+ captureSentryException(fatalError, {
10914
+ surface: "auth_session_hydration",
10915
+ phase: isReauth ? "reauth" : "initial",
10916
+ retryable: false,
10917
+ auth_status: authStatus,
10918
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
10919
+ });
10723
10920
  setError(fatalError);
10724
10921
  setAuthStatus("failed");
10725
10922
  setUser(null);
@@ -11414,7 +11611,7 @@ var useMobileMenu = () => {
11414
11611
  };
11415
11612
  var useHideMobileHeader = (shouldHide = true) => {
11416
11613
  const context = useMobileMenu();
11417
- React142__default.useEffect(() => {
11614
+ React143__default.useEffect(() => {
11418
11615
  if (context && shouldHide) {
11419
11616
  context.setHideMobileHeader(true);
11420
11617
  return () => {
@@ -13256,7 +13453,13 @@ var parseEfficiencyLegend = (legend) => {
13256
13453
  critical_threshold: coerce(legend.critical_threshold, DEFAULT_EFFICIENCY_LEGEND.critical_threshold)
13257
13454
  };
13258
13455
  };
13259
- var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibleLineIds }) => {
13456
+ var useDashboardMetrics = ({
13457
+ onLineMetricsUpdate,
13458
+ lineId,
13459
+ lineIds,
13460
+ userAccessibleLineIds,
13461
+ enabled = true
13462
+ }) => {
13260
13463
  const { supabaseUrl, supabaseKey } = useDashboardConfig();
13261
13464
  const entityConfig = useEntityConfig();
13262
13465
  const databaseConfig = useDatabaseConfig();
@@ -13371,7 +13574,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13371
13574
  isTimezoneLoading,
13372
13575
  companySpecificMetricsTable
13373
13576
  });
13374
- if (!currentLineIdToUse || !supabase || shiftLoading || isTimezoneLoading || companySpecificMetricsTable.includes("unknown_company")) {
13577
+ if (!currentLineIdToUse || !supabase || !enabled || shiftLoading || isTimezoneLoading || companySpecificMetricsTable.includes("unknown_company")) {
13375
13578
  updateQueueRef.current = false;
13376
13579
  if (!metrics2?.workspaceMetrics?.length && !metrics2?.lineMetrics?.length && !shiftLoading) setIsLoading(false);
13377
13580
  if (companySpecificMetricsTable.includes("unknown_company") && !error) {
@@ -13415,19 +13618,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13415
13618
  abortControllerRef.current = abortController;
13416
13619
  inFlightFetchKeyRef.current = fetchKey;
13417
13620
  try {
13418
- const { data: { session } } = await supabase.auth.getSession();
13419
- logDebug("[useDashboardMetrics] Session check:", {
13420
- hasSession: !!session,
13421
- hasToken: !!session?.access_token,
13422
- tokenPreview: session?.access_token?.substring(0, 20) + "..."
13423
- });
13424
- if (!session?.access_token) {
13425
- throw new Error("No authentication token available. Please log in.");
13426
- }
13427
- const apiUrl = process.env.NEXT_PUBLIC_BACKEND_URL;
13428
- if (!apiUrl) {
13429
- throw new Error("Backend URL is not configured. Please set NEXT_PUBLIC_BACKEND_URL in your environment.");
13430
- }
13431
13621
  if (targetLineIds.length === 0) {
13432
13622
  logDebug("[useDashboardMetrics] Skipping fetch: no target line IDs after scope filtering");
13433
13623
  setMetrics({
@@ -13446,6 +13636,10 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13446
13636
  let idleTimeVlmByLine = {};
13447
13637
  let efficiencyLegend;
13448
13638
  const forceParam = force ? "&force_refresh=true" : "";
13639
+ const buildMetricsEndpoint = (params) => {
13640
+ const lineIdsParam = isFactory ? `line_ids=${params.groupLineIds.join(",")}` : `line_id=${params.groupLineIds[0]}`;
13641
+ return `/api/dashboard/metrics?${lineIdsParam}&date=${params.date}&shift_id=${params.shiftId}&company_id=${companyId}${forceParam}`;
13642
+ };
13449
13643
  if (usesShiftGroups) {
13450
13644
  logDebug("[useDashboardMetrics] Factory view shift groups fetch:", {
13451
13645
  groupCount: shiftGroups.length,
@@ -13462,32 +13656,23 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13462
13656
  if (groupLineIds.length === 0) {
13463
13657
  return null;
13464
13658
  }
13465
- const lineIdsParam = `line_ids=${groupLineIds.join(",")}`;
13466
- const url = `${apiUrl}/api/dashboard/metrics?${lineIdsParam}&date=${group.date}&shift_id=${group.shiftId}&company_id=${companyId}${forceParam}`;
13659
+ const endpoint = buildMetricsEndpoint({
13660
+ groupLineIds,
13661
+ date: group.date,
13662
+ shiftId: group.shiftId
13663
+ });
13467
13664
  logDebug(`[useDashboardMetrics] \u{1F4CA} Fetching for shift ${group.shiftId} (${group.shiftName}):`, {
13468
13665
  lineIds: groupLineIds,
13469
- date: group.date
13666
+ date: group.date,
13667
+ endpoint
13470
13668
  });
13471
- const response = await fetch(url, {
13669
+ return await fetchBackendJson(supabase, endpoint, {
13472
13670
  method: "GET",
13473
- headers: {
13474
- "Authorization": `Bearer ${session.access_token}`,
13475
- "Content-Type": "application/json"
13476
- },
13477
- signal: abortController.signal
13671
+ signal: abortController.signal,
13672
+ timeoutMs: 1e4,
13673
+ retries: 1,
13674
+ dedupeKey: `dashboard-metrics::${requestLineId}::${group.date}::${group.shiftId}::${groupLineIds.join(",")}::${force ? "force" : "cached"}`
13478
13675
  });
13479
- if (!response.ok) {
13480
- const errorText = await response.text();
13481
- console.error(`[useDashboardMetrics] Backend API error for shift ${group.shiftId}:`, errorText);
13482
- throw new Error(`Backend API error (${response.status}): ${errorText}`);
13483
- }
13484
- const responseText = await response.text();
13485
- try {
13486
- return JSON.parse(responseText);
13487
- } catch (parseError) {
13488
- console.error("[useDashboardMetrics] Failed to parse response:", responseText.substring(0, 500));
13489
- throw new Error(`Invalid JSON response from backend`);
13490
- }
13491
13676
  });
13492
13677
  const results = (await Promise.all(metricsPromises)).filter((result) => !!result);
13493
13678
  hasFlowBuffers = results.some((result) => result?.metadata?.has_flow_buffers);
@@ -13522,39 +13707,23 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13522
13707
  if (!currentShiftDetails) {
13523
13708
  throw new Error("Shift details not available for metrics fetch.");
13524
13709
  }
13525
- const operationalDate = currentShiftDetails.date;
13526
- const lineIdsParam = isFactory ? `line_ids=${targetLineIds.join(",")}` : `line_id=${targetLineIds[0]}`;
13527
- const url = `${apiUrl}/api/dashboard/metrics?${lineIdsParam}&date=${operationalDate}&shift_id=${currentShiftDetails.shiftId}&company_id=${companyId}${forceParam}`;
13710
+ const endpoint = buildMetricsEndpoint({
13711
+ groupLineIds: targetLineIds,
13712
+ date: currentShiftDetails.date,
13713
+ shiftId: currentShiftDetails.shiftId
13714
+ });
13528
13715
  logDebug("[useDashboardMetrics] Calling backend API:", {
13529
- url,
13530
- apiUrl,
13531
- lineIdsParam,
13532
- operationalDate,
13716
+ endpoint,
13533
13717
  shiftId: currentShiftDetails.shiftId,
13534
13718
  companyId
13535
13719
  });
13536
- const response = await fetch(url, {
13720
+ const backendData = await fetchBackendJson(supabase, endpoint, {
13537
13721
  method: "GET",
13538
- headers: {
13539
- "Authorization": `Bearer ${session.access_token}`,
13540
- "Content-Type": "application/json"
13541
- },
13542
- signal: abortController.signal
13722
+ signal: abortController.signal,
13723
+ timeoutMs: 1e4,
13724
+ retries: 1,
13725
+ dedupeKey: `dashboard-metrics::${requestLineId}::${currentShiftDetails.date}::${currentShiftDetails.shiftId}::${targetLineIds.join(",")}::${force ? "force" : "cached"}`
13543
13726
  });
13544
- logDebug("[useDashboardMetrics] Response status:", response.status, response.statusText);
13545
- if (!response.ok) {
13546
- const errorText = await response.text();
13547
- console.error("[useDashboardMetrics] Backend API error response:", errorText);
13548
- throw new Error(`Backend API error (${response.status}): ${errorText}`);
13549
- }
13550
- const responseText = await response.text();
13551
- let backendData;
13552
- try {
13553
- backendData = JSON.parse(responseText);
13554
- } catch (parseError) {
13555
- console.error("[useDashboardMetrics] Failed to parse response as JSON. Response text:", responseText.substring(0, 500));
13556
- throw new Error(`Invalid JSON response from backend. Received: ${responseText.substring(0, 100)}...`);
13557
- }
13558
13727
  logDebug("[useDashboardMetrics] Backend response:", {
13559
13728
  workspaceCount: backendData.workspace_metrics?.length || 0,
13560
13729
  lineCount: backendData.line_metrics?.length || 0
@@ -13609,6 +13778,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13609
13778
  date: item.date,
13610
13779
  workspace_uuid: item.workspace_id,
13611
13780
  workspace_name: item.workspace_name,
13781
+ displayName: item.workspace_display_name || item.display_name || void 0,
13612
13782
  action_count: item.total_output || 0,
13613
13783
  pph: item.avg_pph || 0,
13614
13784
  performance_score: item.performance_score || 0,
@@ -13672,6 +13842,17 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13672
13842
  return;
13673
13843
  }
13674
13844
  console.error("[useDashboardMetrics] Error fetching dashboard metrics:", err);
13845
+ captureSentryException(err, {
13846
+ surface: "home_live_monitor_metrics",
13847
+ route: "/api/dashboard/metrics",
13848
+ line_id: requestLineId,
13849
+ selected_line_ids: targetLineIds,
13850
+ is_factory_view: isFactory,
13851
+ reason: options.reason || "unknown",
13852
+ auth_deferred: !enabled,
13853
+ visibility_state: typeof document !== "undefined" ? document.visibilityState : "unknown",
13854
+ online_state: typeof navigator !== "undefined" ? navigator.onLine : "unknown"
13855
+ });
13675
13856
  setError({ message: err.message, code: err.code || "FETCH_ERROR" });
13676
13857
  } finally {
13677
13858
  if (requestId === activeRequestIdRef.current) {
@@ -13685,6 +13866,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13685
13866
  }, [
13686
13867
  supabase,
13687
13868
  companySpecificMetricsTable,
13869
+ enabled,
13688
13870
  companyId,
13689
13871
  factoryViewId,
13690
13872
  defaultTimezone,
@@ -13721,24 +13903,24 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13721
13903
  logDebug("[useDashboardMetrics] queueUpdate triggered from realtime");
13722
13904
  updateQueueRef.current = true;
13723
13905
  fetchAllMetricsRef.current({ force: true, reason: "subscription" });
13724
- }, [supabase]);
13906
+ }, [supabase, enabled]);
13725
13907
  useEffect(() => {
13726
- if (lineId && supabase && !shiftLoading && !isTimezoneLoading) {
13908
+ if (enabled && lineId && supabase && !shiftLoading && !isTimezoneLoading) {
13727
13909
  fetchAllMetrics({ reason: "line-change" });
13728
13910
  }
13729
- }, [lineId, supabase, fetchAllMetrics, shiftLoading, isTimezoneLoading]);
13911
+ }, [enabled, lineId, supabase, fetchAllMetrics, shiftLoading, isTimezoneLoading]);
13730
13912
  useEffect(() => {
13731
- if (isFactoryView || !operationalShiftKey) return;
13913
+ if (!enabled || isFactoryView || !operationalShiftKey) return;
13732
13914
  if (!supabase || shiftLoading || isTimezoneLoading) return;
13733
13915
  fetchAllMetrics({ force: true, reason: "shift-change" });
13734
- }, [isFactoryView, operationalShiftKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
13916
+ }, [enabled, isFactoryView, operationalShiftKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
13735
13917
  useEffect(() => {
13736
- if (!isFactoryView || !shiftGroupsKey) return;
13918
+ if (!enabled || !isFactoryView || !shiftGroupsKey) return;
13737
13919
  if (!supabase || shiftLoading || isTimezoneLoading) return;
13738
13920
  fetchAllMetrics({ force: true, reason: "shift-change" });
13739
- }, [isFactoryView, shiftGroupsKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
13921
+ }, [enabled, isFactoryView, shiftGroupsKey, supabase, shiftLoading, isTimezoneLoading, fetchAllMetrics]);
13740
13922
  useEffect(() => {
13741
- if (!lineId || !supabase || shiftLoading || isTimezoneLoading) {
13923
+ if (!enabled || !lineId || !supabase || shiftLoading || isTimezoneLoading) {
13742
13924
  return;
13743
13925
  }
13744
13926
  let intervalId = null;
@@ -13764,15 +13946,16 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
13764
13946
  window.clearInterval(intervalId);
13765
13947
  }
13766
13948
  };
13767
- }, [lineId, supabase, shiftLoading, isTimezoneLoading]);
13949
+ }, [enabled, lineId, supabase, shiftLoading, isTimezoneLoading]);
13768
13950
  const subscriptionKey = useMemo(() => {
13769
- if (!supabase || !entityConfig?.companyId) return null;
13951
+ if (!enabled || !supabase || !entityConfig?.companyId) return null;
13770
13952
  if (shiftLoading || isTimezoneLoading) return null;
13771
13953
  const isFactory = lineId === (entityConfig.factoryViewId || "factory");
13772
13954
  if (isFactory && shiftGroups.length === 0) return null;
13773
13955
  const shiftGroupsKeyPart = isFactory ? shiftGroups.map((g) => `${g.date}-${g.shiftId}-${g.lineIds.join("_")}`).join("|") : operationalShiftKey;
13774
13956
  return `${lineId}|${entityConfig.companyId}|${shiftGroupsKeyPart}`;
13775
13957
  }, [
13958
+ enabled,
13776
13959
  supabase,
13777
13960
  entityConfig?.companyId,
13778
13961
  entityConfig?.factoryViewId,
@@ -14098,9 +14281,14 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, lineIds, userAccessibl
14098
14281
  lineMetrics: safeMetrics?.lineMetrics || [],
14099
14282
  efficiencyLegend: safeMetrics?.efficiencyLegend || DEFAULT_EFFICIENCY_LEGEND,
14100
14283
  metadata: safeMetrics?.metadata,
14101
- isLoading: isLoading || !isMetricsForActiveLine,
14284
+ isLoading: enabled ? isLoading || !isMetricsForActiveLine : false,
14102
14285
  error,
14103
- refetch: () => fetchAllMetrics({ force: true, reason: "manual" })
14286
+ refetch: () => {
14287
+ if (!enabled) {
14288
+ return;
14289
+ }
14290
+ fetchAllMetrics({ force: true, reason: "manual" });
14291
+ }
14104
14292
  };
14105
14293
  };
14106
14294
  var useLineKPIs = ({ lineId, enabled }) => {
@@ -16540,6 +16728,7 @@ var runtimeWorkspaceDisplayNames = {};
16540
16728
  var isInitialized = false;
16541
16729
  var isInitializing = false;
16542
16730
  var initializedWithLineIds = [];
16731
+ var missingLineContextWarnings = /* @__PURE__ */ new Set();
16543
16732
  var initializationPromise = null;
16544
16733
  var workspaceDisplayNamesListeners = /* @__PURE__ */ new Set();
16545
16734
  var notifyWorkspaceDisplayNamesListeners = (changedLineId) => {
@@ -16709,6 +16898,9 @@ var forceRefreshWorkspaceDisplayNames = async (lineId) => {
16709
16898
  };
16710
16899
  console.log("\u{1F504} Module loaded, will initialize lazily when first function is called");
16711
16900
  var getWorkspaceDisplayName = (workspaceId, lineId) => {
16901
+ if (!workspaceId) {
16902
+ return workspaceId;
16903
+ }
16712
16904
  if (!isInitialized && !isInitializing) {
16713
16905
  console.log(`\u{1F504} [DEBUG] getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) - Not initialized, triggering lazy init...`);
16714
16906
  } else if (isInitializing) {
@@ -16740,7 +16932,11 @@ var getWorkspaceDisplayName = (workspaceId, lineId) => {
16740
16932
  for (const cachedLineId of Object.keys(runtimeWorkspaceDisplayNames)) {
16741
16933
  if (runtimeWorkspaceDisplayNames[cachedLineId][workspaceId]) {
16742
16934
  displayName = runtimeWorkspaceDisplayNames[cachedLineId][workspaceId];
16743
- console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
16935
+ const warningKey = `${workspaceId}:${cachedLineId}:full`;
16936
+ if (!missingLineContextWarnings.has(warningKey)) {
16937
+ missingLineContextWarnings.add(warningKey);
16938
+ console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
16939
+ }
16744
16940
  break;
16745
16941
  }
16746
16942
  }
@@ -16755,6 +16951,9 @@ var getWorkspaceDisplayName = (workspaceId, lineId) => {
16755
16951
  }
16756
16952
  };
16757
16953
  var getShortWorkspaceDisplayName = (workspaceId, lineId) => {
16954
+ if (!workspaceId) {
16955
+ return workspaceId;
16956
+ }
16758
16957
  if (!isInitialized && !isInitializing) {
16759
16958
  console.log("\u{1F504} Lazy initialization triggered by getShortWorkspaceDisplayName with lineId:", lineId);
16760
16959
  initializeWorkspaceDisplayNames(lineId).catch((error) => {
@@ -16781,7 +16980,11 @@ var getShortWorkspaceDisplayName = (workspaceId, lineId) => {
16781
16980
  for (const cachedLineId of Object.keys(runtimeWorkspaceDisplayNames)) {
16782
16981
  if (runtimeWorkspaceDisplayNames[cachedLineId][workspaceId]) {
16783
16982
  displayName = runtimeWorkspaceDisplayNames[cachedLineId][workspaceId];
16784
- console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
16983
+ const warningKey = `${workspaceId}:${cachedLineId}:short`;
16984
+ if (!missingLineContextWarnings.has(warningKey)) {
16985
+ missingLineContextWarnings.add(warningKey);
16986
+ console.warn(`\u26A0\uFE0F No lineId provided for ${workspaceId}, found in line ${cachedLineId}`);
16987
+ }
16785
16988
  break;
16786
16989
  }
16787
16990
  }
@@ -17653,7 +17856,6 @@ var usePrefetchClipCounts = ({
17653
17856
  subscriberId
17654
17857
  }) => {
17655
17858
  const [status] = useState("idle" /* IDLE */);
17656
- console.log("[usePrefetchClipCounts] DISABLED - Returning empty state");
17657
17859
  return {
17658
17860
  status,
17659
17861
  data: null,
@@ -17662,7 +17864,6 @@ var usePrefetchClipCounts = ({
17662
17864
  isFullyIndexed: false,
17663
17865
  isLoading: false,
17664
17866
  prefetchClipCounts: async () => {
17665
- console.log("[usePrefetchClipCounts] DISABLED - Not prefetching");
17666
17867
  return null;
17667
17868
  },
17668
17869
  cacheKey: `disabled:${workspaceId}:${date}:${shift}`
@@ -20256,11 +20457,21 @@ var apiUtils = {
20256
20457
  const token = sessionResponse.data.session?.access_token;
20257
20458
  if (!token) {
20258
20459
  console.error("API Util: No authentication token available.");
20460
+ captureHandledFrontendException(new Error("Authentication required."), {
20461
+ surface: "api_utils",
20462
+ endpoint: relativeEndpoint,
20463
+ reason: "missing_auth_token"
20464
+ });
20259
20465
  throw new Error("Authentication required.");
20260
20466
  }
20261
20467
  const baseUrl = config.apiBaseUrl;
20262
20468
  if (!baseUrl) {
20263
20469
  console.error("API Util: apiBaseUrl is not configured.");
20470
+ captureHandledFrontendException(new Error("API base URL is not configured."), {
20471
+ surface: "api_utils",
20472
+ endpoint: relativeEndpoint,
20473
+ reason: "missing_api_base_url"
20474
+ });
20264
20475
  throw new Error("API base URL is not configured.");
20265
20476
  }
20266
20477
  const endpoint = `${baseUrl.replace(/\/$/, "")}/${relativeEndpoint.replace(/^\//, "")}`;
@@ -20289,6 +20500,12 @@ var apiUtils = {
20289
20500
  return await response.json();
20290
20501
  } catch (error) {
20291
20502
  console.error(`Network or fetch error calling ${endpoint}:`, error);
20503
+ captureHandledFrontendException(error, {
20504
+ surface: "api_utils",
20505
+ endpoint,
20506
+ method: options.method || "GET",
20507
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
20508
+ });
20292
20509
  if (error instanceof Error) {
20293
20510
  throw error;
20294
20511
  } else {
@@ -23472,7 +23689,7 @@ var MotionConfigContext = createContext({
23472
23689
  });
23473
23690
 
23474
23691
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
23475
- var PopChildMeasure = class extends React142.Component {
23692
+ var PopChildMeasure = class extends React143.Component {
23476
23693
  getSnapshotBeforeUpdate(prevProps) {
23477
23694
  const element = this.props.childRef.current;
23478
23695
  if (element && prevProps.isPresent && !this.props.isPresent) {
@@ -23527,7 +23744,7 @@ function PopChild({ children, isPresent }) {
23527
23744
  document.head.removeChild(style);
23528
23745
  };
23529
23746
  }, [isPresent]);
23530
- return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React142.cloneElement(children, { ref }) });
23747
+ return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React143.cloneElement(children, { ref }) });
23531
23748
  }
23532
23749
 
23533
23750
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
@@ -23564,7 +23781,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
23564
23781
  useMemo(() => {
23565
23782
  presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
23566
23783
  }, [isPresent]);
23567
- React142.useEffect(() => {
23784
+ React143.useEffect(() => {
23568
23785
  !isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
23569
23786
  }, [isPresent]);
23570
23787
  if (mode === "popLayout") {
@@ -31349,7 +31566,7 @@ var withAuth = (WrappedComponent2, options) => {
31349
31566
  requireAuth: true,
31350
31567
  ...options
31351
31568
  };
31352
- const WithAuthComponent = React142.memo(function WithAuthComponent2(props) {
31569
+ const WithAuthComponent = React143.memo(function WithAuthComponent2(props) {
31353
31570
  const {
31354
31571
  session,
31355
31572
  user,
@@ -31360,9 +31577,9 @@ var withAuth = (WrappedComponent2, options) => {
31360
31577
  retrySessionHydration
31361
31578
  } = useAuth();
31362
31579
  const router = useRouter();
31363
- const [localLoading, setLocalLoading] = React142.useState(loading);
31364
- const [loadingTimeoutReached, setLoadingTimeoutReached] = React142.useState(false);
31365
- React142.useEffect(() => {
31580
+ const [localLoading, setLocalLoading] = React143.useState(loading);
31581
+ const [loadingTimeoutReached, setLoadingTimeoutReached] = React143.useState(false);
31582
+ React143.useEffect(() => {
31366
31583
  if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
31367
31584
  console.log("withAuth state:", {
31368
31585
  loading,
@@ -31374,7 +31591,7 @@ var withAuth = (WrappedComponent2, options) => {
31374
31591
  });
31375
31592
  }
31376
31593
  }, [authStatus, error, loading, session, user]);
31377
- const handleLoadingTimeout = React142.useCallback(() => {
31594
+ const handleLoadingTimeout = React143.useCallback(() => {
31378
31595
  console.warn("[withAuth] Loading timeout reached");
31379
31596
  setLoadingTimeoutReached(true);
31380
31597
  if (hasStoredSupabaseSession()) {
@@ -31386,13 +31603,13 @@ var withAuth = (WrappedComponent2, options) => {
31386
31603
  router.replace(defaultOptions.redirectTo);
31387
31604
  }
31388
31605
  }, [retrySessionHydration, router]);
31389
- React142.useEffect(() => {
31606
+ React143.useEffect(() => {
31390
31607
  if (!loading && authStatus !== "recovering" && defaultOptions.requireAuth && !session && !error) {
31391
31608
  console.log("[withAuth] No session found, redirecting to login");
31392
31609
  router.replace(defaultOptions.redirectTo);
31393
31610
  }
31394
31611
  }, [authStatus, defaultOptions.requireAuth, error, loading, router, session]);
31395
- React142.useEffect(() => {
31612
+ React143.useEffect(() => {
31396
31613
  setLocalLoading(loading);
31397
31614
  }, [loading]);
31398
31615
  if (loading || localLoading) {
@@ -32391,11 +32608,11 @@ var BarChartComponent = ({
32391
32608
  aspect = 2,
32392
32609
  ...restOfChartProps
32393
32610
  }) => {
32394
- const containerRef = React142__default.useRef(null);
32395
- const [containerReady, setContainerReady] = React142__default.useState(false);
32611
+ const containerRef = React143__default.useRef(null);
32612
+ const [containerReady, setContainerReady] = React143__default.useState(false);
32396
32613
  const themeConfig = useThemeConfig();
32397
32614
  const { formatNumber } = useFormatNumber();
32398
- React142__default.useEffect(() => {
32615
+ React143__default.useEffect(() => {
32399
32616
  const checkContainerDimensions = () => {
32400
32617
  if (containerRef.current) {
32401
32618
  const rect = containerRef.current.getBoundingClientRect();
@@ -32509,7 +32726,7 @@ var BarChartComponent = ({
32509
32726
  }
32510
32727
  return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
32511
32728
  };
32512
- var BarChart = React142__default.memo(BarChartComponent, (prevProps, nextProps) => {
32729
+ var BarChart = React143__default.memo(BarChartComponent, (prevProps, nextProps) => {
32513
32730
  if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || JSON.stringify(prevProps.referenceLines || []) !== JSON.stringify(nextProps.referenceLines || []) || prevProps.layout !== nextProps.layout || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect) {
32514
32731
  return false;
32515
32732
  }
@@ -32560,10 +32777,10 @@ var LineChartComponent = ({
32560
32777
  fillContainer = false,
32561
32778
  ...restOfChartProps
32562
32779
  }) => {
32563
- const containerRef = React142__default.useRef(null);
32564
- const [dimensions, setDimensions] = React142__default.useState({ width: 0, height: 0 });
32565
- const [hasValidData, setHasValidData] = React142__default.useState(false);
32566
- React142__default.useEffect(() => {
32780
+ const containerRef = React143__default.useRef(null);
32781
+ const [dimensions, setDimensions] = React143__default.useState({ width: 0, height: 0 });
32782
+ const [hasValidData, setHasValidData] = React143__default.useState(false);
32783
+ React143__default.useEffect(() => {
32567
32784
  const currentHasValidData = data && lines && lines.length > 0 && data.some(
32568
32785
  (item) => lines.some((line) => {
32569
32786
  const val = item[line.dataKey];
@@ -32574,7 +32791,7 @@ var LineChartComponent = ({
32574
32791
  setHasValidData(true);
32575
32792
  }
32576
32793
  }, [data, lines, hasValidData]);
32577
- React142__default.useEffect(() => {
32794
+ React143__default.useEffect(() => {
32578
32795
  if (!containerRef.current) return;
32579
32796
  const observer = new ResizeObserver((entries) => {
32580
32797
  const entry = entries[0];
@@ -32699,7 +32916,7 @@ var LineChartComponent = ({
32699
32916
  }
32700
32917
  return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
32701
32918
  };
32702
- var LineChart = React142__default.memo(LineChartComponent, (prevProps, nextProps) => {
32919
+ var LineChart = React143__default.memo(LineChartComponent, (prevProps, nextProps) => {
32703
32920
  if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect || JSON.stringify(prevProps.yAxisDomain) !== JSON.stringify(nextProps.yAxisDomain)) {
32704
32921
  return false;
32705
32922
  }
@@ -32793,7 +33010,7 @@ var OutputProgressChartComponent = ({
32793
33010
  ] }) })
32794
33011
  ] }) });
32795
33012
  };
32796
- var OutputProgressChart = React142__default.memo(OutputProgressChartComponent);
33013
+ var OutputProgressChart = React143__default.memo(OutputProgressChartComponent);
32797
33014
  OutputProgressChart.displayName = "OutputProgressChart";
32798
33015
  var LargeOutputProgressChart = ({
32799
33016
  currentOutput,
@@ -32933,7 +33150,7 @@ var CycleTimeChartComponent = ({
32933
33150
  }
32934
33151
  ) }) });
32935
33152
  };
32936
- var CycleTimeChart = React142__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
33153
+ var CycleTimeChart = React143__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
32937
33154
  if (prevProps.className !== nextProps.className) {
32938
33155
  return false;
32939
33156
  }
@@ -33171,16 +33388,16 @@ var CycleTimeOverTimeChart = ({
33171
33388
  idleTimeSlots = []
33172
33389
  }) => {
33173
33390
  const MAX_DATA_POINTS = 40;
33174
- const containerRef = React142__default.useRef(null);
33175
- const [dimensions, setDimensions] = React142__default.useState({ width: 0, height: 0 });
33176
- const [hasValidData, setHasValidData] = React142__default.useState(false);
33177
- React142__default.useEffect(() => {
33391
+ const containerRef = React143__default.useRef(null);
33392
+ const [dimensions, setDimensions] = React143__default.useState({ width: 0, height: 0 });
33393
+ const [hasValidData, setHasValidData] = React143__default.useState(false);
33394
+ React143__default.useEffect(() => {
33178
33395
  const currentHasValidData = data && data.some((val) => val !== null && val > 0);
33179
33396
  if (currentHasValidData && !hasValidData) {
33180
33397
  setHasValidData(true);
33181
33398
  }
33182
33399
  }, [data, hasValidData]);
33183
- React142__default.useEffect(() => {
33400
+ React143__default.useEffect(() => {
33184
33401
  if (!containerRef.current) return;
33185
33402
  const observer = new ResizeObserver((entries) => {
33186
33403
  const entry = entries[0];
@@ -33212,7 +33429,7 @@ var CycleTimeOverTimeChart = ({
33212
33429
  const endLabel = shiftEnd && slotIndex === DURATION - 1 ? formatHourLabel(slotIndex + 1) : formatHourLabel(slotIndex + 1);
33213
33430
  return `${startLabel} - ${endLabel}`;
33214
33431
  };
33215
- const getDisplayData = React142__default.useCallback((rawData) => {
33432
+ const getDisplayData = React143__default.useCallback((rawData) => {
33216
33433
  if (xAxisMode === "hourly") return rawData;
33217
33434
  return rawData.slice(Math.max(0, rawData.length - MAX_DATA_POINTS));
33218
33435
  }, [xAxisMode]);
@@ -33220,7 +33437,7 @@ var CycleTimeOverTimeChart = ({
33220
33437
  const DURATION = displayData.length;
33221
33438
  const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
33222
33439
  const finalData = displayData;
33223
- const labelInterval = React142__default.useMemo(() => {
33440
+ const labelInterval = React143__default.useMemo(() => {
33224
33441
  if (xAxisMode === "hourly") {
33225
33442
  return Math.max(1, Math.ceil(DURATION / 8));
33226
33443
  }
@@ -33261,8 +33478,8 @@ var CycleTimeOverTimeChart = ({
33261
33478
  return `${minutes} minutes ${seconds} seconds ago`;
33262
33479
  }
33263
33480
  };
33264
- const getNumericValue = React142__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
33265
- const renderChartTooltip = React142__default.useCallback((tooltipProps) => {
33481
+ const getNumericValue = React143__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
33482
+ const renderChartTooltip = React143__default.useCallback((tooltipProps) => {
33266
33483
  const { active, payload } = tooltipProps;
33267
33484
  if (!active || !Array.isArray(payload) || payload.length === 0) {
33268
33485
  return null;
@@ -33325,7 +33542,7 @@ var CycleTimeOverTimeChart = ({
33325
33542
  ] })
33326
33543
  ] });
33327
33544
  }, [getNumericValue, shiftStart, showIdleTime]);
33328
- const renderCycleDot = React142__default.useCallback((props) => {
33545
+ const renderCycleDot = React143__default.useCallback((props) => {
33329
33546
  const { cx: cx2, cy, payload } = props;
33330
33547
  const cycleTime = getNumericValue(payload?.cycleTime);
33331
33548
  if (cycleTime === null) {
@@ -33358,7 +33575,7 @@ var CycleTimeOverTimeChart = ({
33358
33575
  }
33359
33576
  );
33360
33577
  }, [getNumericValue, idealCycleTime]);
33361
- const renderCycleActiveDot = React142__default.useCallback((props) => {
33578
+ const renderCycleActiveDot = React143__default.useCallback((props) => {
33362
33579
  const { cx: cx2, cy, payload } = props;
33363
33580
  const cycleTime = getNumericValue(payload?.cycleTime);
33364
33581
  if (cycleTime === null) {
@@ -33379,7 +33596,7 @@ var CycleTimeOverTimeChart = ({
33379
33596
  }
33380
33597
  );
33381
33598
  }, [getNumericValue, idealCycleTime]);
33382
- const renderIdleDot = React142__default.useCallback((props) => {
33599
+ const renderIdleDot = React143__default.useCallback((props) => {
33383
33600
  const { cx: cx2, cy, payload } = props;
33384
33601
  const idleMinutes = getNumericValue(payload?.idleMinutes);
33385
33602
  if (idleMinutes === null) {
@@ -33401,7 +33618,7 @@ var CycleTimeOverTimeChart = ({
33401
33618
  }
33402
33619
  );
33403
33620
  }, [getNumericValue, showIdleTime]);
33404
- const renderIdleActiveDot = React142__default.useCallback((props) => {
33621
+ const renderIdleActiveDot = React143__default.useCallback((props) => {
33405
33622
  const { cx: cx2, cy, payload } = props;
33406
33623
  const idleMinutes = getNumericValue(payload?.idleMinutes);
33407
33624
  if (idleMinutes === null || !showIdleTime) {
@@ -33419,7 +33636,7 @@ var CycleTimeOverTimeChart = ({
33419
33636
  }
33420
33637
  );
33421
33638
  }, [getNumericValue, showIdleTime]);
33422
- const chartData = React142__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
33639
+ const chartData = React143__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
33423
33640
  const cycleTime = getNumericValue(finalData[i]);
33424
33641
  const useIdleSlots = idleTimeSlots.length > 0;
33425
33642
  const idleSlot = useIdleSlots ? idleTimeSlots[i] ?? null : null;
@@ -33616,7 +33833,7 @@ var CycleTimeOverTimeChart = ({
33616
33833
  }
33617
33834
  );
33618
33835
  };
33619
- var Card = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33836
+ var Card = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33620
33837
  "div",
33621
33838
  {
33622
33839
  ref,
@@ -33628,7 +33845,7 @@ var Card = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
33628
33845
  }
33629
33846
  ));
33630
33847
  Card.displayName = "Card";
33631
- var CardHeader = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33848
+ var CardHeader = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33632
33849
  "div",
33633
33850
  {
33634
33851
  ref,
@@ -33637,7 +33854,7 @@ var CardHeader = React142.forwardRef(({ className, ...props }, ref) => /* @__PUR
33637
33854
  }
33638
33855
  ));
33639
33856
  CardHeader.displayName = "CardHeader";
33640
- var CardTitle = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33857
+ var CardTitle = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33641
33858
  "h3",
33642
33859
  {
33643
33860
  ref,
@@ -33649,7 +33866,7 @@ var CardTitle = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE
33649
33866
  }
33650
33867
  ));
33651
33868
  CardTitle.displayName = "CardTitle";
33652
- var CardDescription = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33869
+ var CardDescription = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33653
33870
  "p",
33654
33871
  {
33655
33872
  ref,
@@ -33658,9 +33875,9 @@ var CardDescription = React142.forwardRef(({ className, ...props }, ref) => /* @
33658
33875
  }
33659
33876
  ));
33660
33877
  CardDescription.displayName = "CardDescription";
33661
- var CardContent = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
33878
+ var CardContent = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
33662
33879
  CardContent.displayName = "CardContent";
33663
- var CardFooter = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33880
+ var CardFooter = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33664
33881
  "div",
33665
33882
  {
33666
33883
  ref,
@@ -33736,7 +33953,7 @@ var buttonVariants = cva(
33736
33953
  }
33737
33954
  }
33738
33955
  );
33739
- var Button = React142.forwardRef(
33956
+ var Button = React143.forwardRef(
33740
33957
  ({ className, variant, size, asChild = false, ...props }, ref) => {
33741
33958
  const Comp = asChild ? Slot : "button";
33742
33959
  return /* @__PURE__ */ jsx(
@@ -33759,10 +33976,10 @@ var HourlyOutputChartComponent = ({
33759
33976
  idleTimeHourly,
33760
33977
  className = ""
33761
33978
  }) => {
33762
- const containerRef = React142__default.useRef(null);
33763
- const [containerReady, setContainerReady] = React142__default.useState(false);
33764
- const [containerWidth, setContainerWidth] = React142__default.useState(0);
33765
- const idleSlots = React142__default.useMemo(
33979
+ const containerRef = React143__default.useRef(null);
33980
+ const [containerReady, setContainerReady] = React143__default.useState(false);
33981
+ const [containerWidth, setContainerWidth] = React143__default.useState(0);
33982
+ const idleSlots = React143__default.useMemo(
33766
33983
  () => buildHourlyIdleSlots({
33767
33984
  idleTimeHourly,
33768
33985
  shiftStart,
@@ -33771,12 +33988,12 @@ var HourlyOutputChartComponent = ({
33771
33988
  [idleTimeHourly, shiftStart, shiftEnd]
33772
33989
  );
33773
33990
  const SHIFT_DURATION = idleSlots.length;
33774
- const [animatedData, setAnimatedData] = React142__default.useState(
33991
+ const [animatedData, setAnimatedData] = React143__default.useState(
33775
33992
  () => Array(SHIFT_DURATION).fill(0)
33776
33993
  );
33777
- const prevDataRef = React142__default.useRef(Array(SHIFT_DURATION).fill(0));
33778
- const animationFrameRef = React142__default.useRef(null);
33779
- React142__default.useEffect(() => {
33994
+ const prevDataRef = React143__default.useRef(Array(SHIFT_DURATION).fill(0));
33995
+ const animationFrameRef = React143__default.useRef(null);
33996
+ React143__default.useEffect(() => {
33780
33997
  setAnimatedData((prev) => {
33781
33998
  if (prev.length !== SHIFT_DURATION) {
33782
33999
  return Array(SHIFT_DURATION).fill(0);
@@ -33785,14 +34002,14 @@ var HourlyOutputChartComponent = ({
33785
34002
  });
33786
34003
  prevDataRef.current = Array(SHIFT_DURATION).fill(0);
33787
34004
  }, [SHIFT_DURATION]);
33788
- const [idleBarState, setIdleBarState] = React142__default.useState({
34005
+ const [idleBarState, setIdleBarState] = React143__default.useState({
33789
34006
  visible: showIdleTime,
33790
34007
  key: 0,
33791
34008
  shouldAnimate: false
33792
34009
  });
33793
- const prevShowIdleTimeRef = React142__default.useRef(showIdleTime);
33794
- const stateUpdateTimeoutRef = React142__default.useRef(null);
33795
- React142__default.useEffect(() => {
34010
+ const prevShowIdleTimeRef = React143__default.useRef(showIdleTime);
34011
+ const stateUpdateTimeoutRef = React143__default.useRef(null);
34012
+ React143__default.useEffect(() => {
33796
34013
  if (stateUpdateTimeoutRef.current) {
33797
34014
  clearTimeout(stateUpdateTimeoutRef.current);
33798
34015
  }
@@ -33817,7 +34034,7 @@ var HourlyOutputChartComponent = ({
33817
34034
  }
33818
34035
  };
33819
34036
  }, [showIdleTime]);
33820
- const animateToNewData = React142__default.useCallback((targetData) => {
34037
+ const animateToNewData = React143__default.useCallback((targetData) => {
33821
34038
  const startData = [...prevDataRef.current];
33822
34039
  const startTime = performance.now();
33823
34040
  const duration = 1200;
@@ -33847,7 +34064,7 @@ var HourlyOutputChartComponent = ({
33847
34064
  }
33848
34065
  animationFrameRef.current = requestAnimationFrame(animate);
33849
34066
  }, []);
33850
- React142__default.useEffect(() => {
34067
+ React143__default.useEffect(() => {
33851
34068
  if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
33852
34069
  const shiftData = data.slice(0, SHIFT_DURATION);
33853
34070
  animateToNewData(shiftData);
@@ -33858,7 +34075,7 @@ var HourlyOutputChartComponent = ({
33858
34075
  }
33859
34076
  };
33860
34077
  }, [data, animateToNewData]);
33861
- React142__default.useEffect(() => {
34078
+ React143__default.useEffect(() => {
33862
34079
  const checkContainerDimensions = () => {
33863
34080
  if (containerRef.current) {
33864
34081
  const rect = containerRef.current.getBoundingClientRect();
@@ -33884,7 +34101,7 @@ var HourlyOutputChartComponent = ({
33884
34101
  clearTimeout(fallbackTimeout);
33885
34102
  };
33886
34103
  }, []);
33887
- const xAxisConfig = React142__default.useMemo(() => {
34104
+ const xAxisConfig = React143__default.useMemo(() => {
33888
34105
  if (containerWidth >= 960) {
33889
34106
  return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12 };
33890
34107
  }
@@ -33893,7 +34110,7 @@ var HourlyOutputChartComponent = ({
33893
34110
  }
33894
34111
  return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6 };
33895
34112
  }, [containerWidth]);
33896
- const chartData = React142__default.useMemo(() => {
34113
+ const chartData = React143__default.useMemo(() => {
33897
34114
  return Array.from({ length: SHIFT_DURATION }, (_, i) => {
33898
34115
  const idleSlot = idleSlots[i];
33899
34116
  return {
@@ -33909,7 +34126,7 @@ var HourlyOutputChartComponent = ({
33909
34126
  };
33910
34127
  });
33911
34128
  }, [animatedData, data, pphThreshold, idleSlots, SHIFT_DURATION]);
33912
- const IdleBar = React142__default.useMemo(() => {
34129
+ const IdleBar = React143__default.useMemo(() => {
33913
34130
  if (!idleBarState.visible) return null;
33914
34131
  return /* @__PURE__ */ jsx(
33915
34132
  Bar,
@@ -34207,7 +34424,7 @@ var HourlyOutputChartComponent = ({
34207
34424
  }
34208
34425
  );
34209
34426
  };
34210
- var HourlyOutputChart = React142__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
34427
+ var HourlyOutputChart = React143__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
34211
34428
  if (prevProps.pphThreshold !== nextProps.pphThreshold || prevProps.shiftStart !== nextProps.shiftStart || prevProps.shiftEnd !== nextProps.shiftEnd || prevProps.shiftDate !== nextProps.shiftDate || prevProps.timezone !== nextProps.timezone || prevProps.showIdleTime !== nextProps.showIdleTime || prevProps.className !== nextProps.className) {
34212
34429
  return false;
34213
34430
  }
@@ -34387,7 +34604,7 @@ function getTrendArrowAndColor(trend) {
34387
34604
  return { arrow: "\u2192", color: "text-gray-400" };
34388
34605
  }
34389
34606
  }
34390
- var VideoCard = React142__default.memo(({
34607
+ var VideoCard = React143__default.memo(({
34391
34608
  workspace,
34392
34609
  hlsUrl,
34393
34610
  shouldPlay,
@@ -34585,7 +34802,7 @@ var logDebug2 = (...args) => {
34585
34802
  if (!DEBUG_DASHBOARD_LOGS2) return;
34586
34803
  console.log(...args);
34587
34804
  };
34588
- var VideoGridView = React142__default.memo(({
34805
+ var VideoGridView = React143__default.memo(({
34589
34806
  workspaces,
34590
34807
  selectedLine,
34591
34808
  lineNames = {},
@@ -34861,7 +35078,7 @@ var VideoGridView = React142__default.memo(({
34861
35078
  efficiency: workspace.efficiency,
34862
35079
  action_count: workspace.action_count
34863
35080
  });
34864
- const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
35081
+ const displayName = workspace.displayName || displayNames[`${workspace.line_id}_${workspace.workspace_name}`] || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
34865
35082
  const currentPath = (router.asPath || "/").split("#")[0];
34866
35083
  const navParams = getWorkspaceNavigationParams(workspaceId, displayName, workspace.line_id, currentPath);
34867
35084
  router.push(`/workspace/${workspaceId}${navParams}`);
@@ -35019,7 +35236,7 @@ var VideoGridView = React142__default.memo(({
35019
35236
  ) });
35020
35237
  });
35021
35238
  VideoGridView.displayName = "VideoGridView";
35022
- var MapGridView = React142__default.memo(({
35239
+ var MapGridView = React143__default.memo(({
35023
35240
  workspaces,
35024
35241
  className = "",
35025
35242
  displayNames = {},
@@ -35858,7 +36075,7 @@ var UptimeLineChartComponent = ({ points, className = "" }) => {
35858
36075
  )
35859
36076
  ] }) }) });
35860
36077
  };
35861
- var UptimeLineChart = React142__default.memo(UptimeLineChartComponent);
36078
+ var UptimeLineChart = React143__default.memo(UptimeLineChartComponent);
35862
36079
  var padTime = (value) => value.toString().padStart(2, "0");
35863
36080
  var parseTime = (timeValue) => {
35864
36081
  if (!timeValue) return null;
@@ -36098,10 +36315,10 @@ var HourlyUptimeChartComponent = ({
36098
36315
  elapsedMinutes,
36099
36316
  className = ""
36100
36317
  }) => {
36101
- const containerRef = React142__default.useRef(null);
36102
- const [containerReady, setContainerReady] = React142__default.useState(false);
36103
- const [containerWidth, setContainerWidth] = React142__default.useState(0);
36104
- const uptimeSeries = React142__default.useMemo(() => buildUptimeSeries({
36318
+ const containerRef = React143__default.useRef(null);
36319
+ const [containerReady, setContainerReady] = React143__default.useState(false);
36320
+ const [containerWidth, setContainerWidth] = React143__default.useState(0);
36321
+ const uptimeSeries = React143__default.useMemo(() => buildUptimeSeries({
36105
36322
  idleTimeHourly,
36106
36323
  shiftStart,
36107
36324
  shiftEnd,
@@ -36110,11 +36327,11 @@ var HourlyUptimeChartComponent = ({
36110
36327
  elapsedMinutes
36111
36328
  }), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes]);
36112
36329
  const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
36113
- const shiftStartTime = React142__default.useMemo(
36330
+ const shiftStartTime = React143__default.useMemo(
36114
36331
  () => getTimeFromTimeString(shiftStart),
36115
36332
  [shiftStart]
36116
36333
  );
36117
- const { shiftDuration, shiftEndTime } = React142__default.useMemo(() => {
36334
+ const { shiftDuration, shiftEndTime } = React143__default.useMemo(() => {
36118
36335
  if (!shiftEnd) {
36119
36336
  const fallbackHours = uptimeSeries.shiftMinutes > 0 ? Math.ceil(uptimeSeries.shiftMinutes / 60) : 0;
36120
36337
  return { shiftDuration: fallbackHours, shiftEndTime: null };
@@ -36128,7 +36345,7 @@ var HourlyUptimeChartComponent = ({
36128
36345
  const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
36129
36346
  return { shiftDuration: hourCount, shiftEndTime: endTime };
36130
36347
  }, [shiftEnd, shiftStartTime.decimalHour, uptimeSeries.shiftMinutes]);
36131
- const formatHour = React142__default.useCallback((hourIndex) => {
36348
+ const formatHour = React143__default.useCallback((hourIndex) => {
36132
36349
  const isLastHour = hourIndex === shiftDuration - 1;
36133
36350
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
36134
36351
  const startHour = Math.floor(startDecimalHour) % 24;
@@ -36153,7 +36370,7 @@ var HourlyUptimeChartComponent = ({
36153
36370
  };
36154
36371
  return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
36155
36372
  }, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
36156
- const formatTimeRange2 = React142__default.useCallback((hourIndex) => {
36373
+ const formatTimeRange2 = React143__default.useCallback((hourIndex) => {
36157
36374
  const isLastHour = hourIndex === shiftDuration - 1;
36158
36375
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
36159
36376
  const startHour = Math.floor(startDecimalHour) % 24;
@@ -36175,7 +36392,7 @@ var HourlyUptimeChartComponent = ({
36175
36392
  };
36176
36393
  return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
36177
36394
  }, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
36178
- const chartData = React142__default.useMemo(() => {
36395
+ const chartData = React143__default.useMemo(() => {
36179
36396
  if (shiftDuration <= 0) return [];
36180
36397
  if (hasAggregateData) {
36181
36398
  return hourlyAggregates.map((entry, hourIndex) => ({
@@ -36217,7 +36434,7 @@ var HourlyUptimeChartComponent = ({
36217
36434
  }, [hasAggregateData, hourlyAggregates, uptimeSeries.points, uptimeSeries.elapsedMinutes, uptimeSeries.shiftMinutes, shiftDuration, formatHour, formatTimeRange2]);
36218
36435
  const maxYValue = 100;
36219
36436
  const yAxisTicks = [0, 25, 50, 75, 100];
36220
- React142__default.useEffect(() => {
36437
+ React143__default.useEffect(() => {
36221
36438
  const checkContainerDimensions = () => {
36222
36439
  if (containerRef.current) {
36223
36440
  const rect = containerRef.current.getBoundingClientRect();
@@ -36243,7 +36460,7 @@ var HourlyUptimeChartComponent = ({
36243
36460
  clearTimeout(fallbackTimeout);
36244
36461
  };
36245
36462
  }, []);
36246
- const xAxisConfig = React142__default.useMemo(() => {
36463
+ const xAxisConfig = React143__default.useMemo(() => {
36247
36464
  if (containerWidth >= 960) {
36248
36465
  return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12, labelMode: "full" };
36249
36466
  }
@@ -36252,7 +36469,7 @@ var HourlyUptimeChartComponent = ({
36252
36469
  }
36253
36470
  return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6, labelMode: "start" };
36254
36471
  }, [containerWidth]);
36255
- const formatXAxisTick = React142__default.useCallback((raw) => {
36472
+ const formatXAxisTick = React143__default.useCallback((raw) => {
36256
36473
  const label = typeof raw === "string" ? raw : String(raw);
36257
36474
  if (xAxisConfig.labelMode === "full") return label;
36258
36475
  const parts = label.split("-");
@@ -36458,7 +36675,7 @@ var HourlyUptimeChartComponent = ({
36458
36675
  }
36459
36676
  );
36460
36677
  };
36461
- var HourlyUptimeChart = React142__default.memo(HourlyUptimeChartComponent);
36678
+ var HourlyUptimeChart = React143__default.memo(HourlyUptimeChartComponent);
36462
36679
  var DEFAULT_COLORS2 = ["#00AB45", "#ef4444"];
36463
36680
  var UptimeDonutChartComponent = ({
36464
36681
  data,
@@ -36528,7 +36745,7 @@ var UptimeDonutChartComponent = ({
36528
36745
  ] }) })
36529
36746
  ] }) });
36530
36747
  };
36531
- var UptimeDonutChart = React142__default.memo(UptimeDonutChartComponent);
36748
+ var UptimeDonutChart = React143__default.memo(UptimeDonutChartComponent);
36532
36749
  UptimeDonutChart.displayName = "UptimeDonutChart";
36533
36750
  var TrendIcon = ({ trend }) => {
36534
36751
  if (trend === "up") {
@@ -36647,7 +36864,7 @@ var EmptyStateMessage = ({
36647
36864
  iconClassName
36648
36865
  }) => {
36649
36866
  let IconContent = null;
36650
- if (React142__default.isValidElement(iconType)) {
36867
+ if (React143__default.isValidElement(iconType)) {
36651
36868
  IconContent = iconType;
36652
36869
  } else if (typeof iconType === "string") {
36653
36870
  const MappedIcon = IconMap[iconType];
@@ -37146,37 +37363,101 @@ var getSeverityColor = (severity) => {
37146
37363
  return "bg-gray-500";
37147
37364
  }
37148
37365
  };
37149
- var formatIdleTimeRange = (startTime, endTime, timezone) => {
37150
- const roundToNearestMinute = (date) => {
37151
- const rounded = new Date(date.getTime());
37152
- const seconds = rounded.getSeconds();
37153
- if (seconds > 30) {
37154
- rounded.setMinutes(rounded.getMinutes() + 1);
37155
- }
37156
- rounded.setSeconds(0);
37157
- rounded.setMilliseconds(0);
37158
- return rounded;
37159
- };
37160
- const startDate = roundToNearestMinute(new Date(startTime));
37161
- const endDate = roundToNearestMinute(new Date(endTime));
37162
- const formatTimeWithoutPeriod = (date, tz) => {
37163
- return date.toLocaleTimeString("en-US", {
37164
- hour: "numeric",
37165
- minute: "2-digit",
37166
- timeZone: tz
37167
- }).replace(/\s?(AM|PM)$/i, "");
37168
- };
37169
- const formatTimeWithPeriod = (date, tz) => {
37170
- return date.toLocaleTimeString("en-US", {
37171
- hour: "numeric",
37172
- minute: "2-digit",
37173
- timeZone: tz
37174
- });
37175
- };
37176
- const startFormatted = formatTimeWithoutPeriod(startDate, timezone);
37177
- const endFormatted = formatTimeWithPeriod(endDate, timezone);
37366
+ var IDLE_RANGE_CATEGORY_IDS = /* @__PURE__ */ new Set(["idle_time", "low_value", "longest-idles"]);
37367
+ var CYCLE_RANGE_CATEGORY_IDS = /* @__PURE__ */ new Set([
37368
+ "cycle_completion",
37369
+ "best_cycle_time",
37370
+ "worst_cycle_time",
37371
+ "long_cycle_time",
37372
+ "fast-cycles",
37373
+ "slow-cycles"
37374
+ ]);
37375
+ var roundToNearestMinute = (date) => {
37376
+ const rounded = new Date(date.getTime());
37377
+ const seconds = rounded.getSeconds();
37378
+ if (seconds > 30) {
37379
+ rounded.setMinutes(rounded.getMinutes() + 1);
37380
+ }
37381
+ rounded.setSeconds(0);
37382
+ rounded.setMilliseconds(0);
37383
+ return rounded;
37384
+ };
37385
+ var parseTimestamp = (value) => {
37386
+ if (!value) return null;
37387
+ const parsed = new Date(value);
37388
+ return Number.isNaN(parsed.getTime()) ? null : parsed;
37389
+ };
37390
+ var formatTimeWithoutPeriod = (date, timezone) => date.toLocaleTimeString("en-US", {
37391
+ hour: "numeric",
37392
+ minute: "2-digit",
37393
+ timeZone: timezone
37394
+ }).replace(/\s?(AM|PM)$/i, "");
37395
+ var formatClipExplorerSingleTime = (timestamp, timezone) => {
37396
+ const parsed = parseTimestamp(timestamp);
37397
+ if (!parsed) return "";
37398
+ return parsed.toLocaleTimeString("en-US", {
37399
+ hour12: true,
37400
+ hour: "numeric",
37401
+ minute: "2-digit",
37402
+ timeZone: timezone
37403
+ });
37404
+ };
37405
+ var formatTimestampRange = (startTime, endTime, timezone) => {
37406
+ const startDate = parseTimestamp(startTime);
37407
+ const endDate = parseTimestamp(endTime);
37408
+ if (!startDate || !endDate) {
37409
+ return formatClipExplorerSingleTime(endTime, timezone);
37410
+ }
37411
+ const roundedStart = roundToNearestMinute(startDate);
37412
+ const roundedEnd = roundToNearestMinute(endDate);
37413
+ const startFormatted = formatTimeWithoutPeriod(roundedStart, timezone);
37414
+ const endFormatted = roundedEnd.toLocaleTimeString("en-US", {
37415
+ hour: "numeric",
37416
+ minute: "2-digit",
37417
+ timeZone: timezone
37418
+ });
37178
37419
  return `${startFormatted} - ${endFormatted}`;
37179
37420
  };
37421
+ var getSecondsBetweenTimestamps = (startTime, endTime) => {
37422
+ const startDate = parseTimestamp(startTime);
37423
+ const endDate = parseTimestamp(endTime);
37424
+ if (!startDate || !endDate) return null;
37425
+ return Math.max(0, (endDate.getTime() - startDate.getTime()) / 1e3);
37426
+ };
37427
+ var formatClipExplorerTimeLabel = ({
37428
+ categoryId,
37429
+ clipTimestamp,
37430
+ timezone,
37431
+ durationSeconds,
37432
+ idleStartTime,
37433
+ idleEndTime
37434
+ }) => {
37435
+ if (IDLE_RANGE_CATEGORY_IDS.has(categoryId)) {
37436
+ const idleDurationSeconds = getSecondsBetweenTimestamps(idleStartTime, idleEndTime);
37437
+ const idleEndTimestamp = idleEndTime || clipTimestamp;
37438
+ if (idleDurationSeconds !== null && idleDurationSeconds >= 60 && idleStartTime && idleEndTime) {
37439
+ return formatTimestampRange(idleStartTime, idleEndTime, timezone);
37440
+ }
37441
+ if (idleDurationSeconds === null && typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds >= 60) {
37442
+ const endDate = parseTimestamp(idleEndTimestamp);
37443
+ if (endDate) {
37444
+ const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
37445
+ return formatTimestampRange(startDate.toISOString(), idleEndTimestamp, timezone);
37446
+ }
37447
+ }
37448
+ return formatClipExplorerSingleTime(idleEndTimestamp, timezone);
37449
+ }
37450
+ const singleTime = formatClipExplorerSingleTime(clipTimestamp, timezone);
37451
+ if (CYCLE_RANGE_CATEGORY_IDS.has(categoryId) && typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds > 60) {
37452
+ const endDate = parseTimestamp(clipTimestamp);
37453
+ if (endDate) {
37454
+ const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
37455
+ return formatTimestampRange(startDate.toISOString(), clipTimestamp, timezone);
37456
+ }
37457
+ }
37458
+ return singleTime;
37459
+ };
37460
+ var formatIdleTimeRange = (startTime, endTime, timezone) => formatTimestampRange(startTime, endTime, timezone);
37180
37461
  var formatTime2 = (seconds) => {
37181
37462
  if (!seconds || isNaN(seconds)) return "0:00";
37182
37463
  const h = Math.floor(seconds / 3600);
@@ -38930,7 +39211,7 @@ function Skeleton({ className, ...props }) {
38930
39211
  var Select = SelectPrimitive.Root;
38931
39212
  var SelectGroup = SelectPrimitive.Group;
38932
39213
  var SelectValue = SelectPrimitive.Value;
38933
- var SelectTrigger = React142.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
39214
+ var SelectTrigger = React143.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
38934
39215
  SelectPrimitive.Trigger,
38935
39216
  {
38936
39217
  ref,
@@ -38946,7 +39227,7 @@ var SelectTrigger = React142.forwardRef(({ className, children, ...props }, ref)
38946
39227
  }
38947
39228
  ));
38948
39229
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
38949
- var SelectScrollUpButton = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
39230
+ var SelectScrollUpButton = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38950
39231
  SelectPrimitive.ScrollUpButton,
38951
39232
  {
38952
39233
  ref,
@@ -38956,7 +39237,7 @@ var SelectScrollUpButton = React142.forwardRef(({ className, ...props }, ref) =>
38956
39237
  }
38957
39238
  ));
38958
39239
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
38959
- var SelectScrollDownButton = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
39240
+ var SelectScrollDownButton = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38960
39241
  SelectPrimitive.ScrollDownButton,
38961
39242
  {
38962
39243
  ref,
@@ -38966,7 +39247,7 @@ var SelectScrollDownButton = React142.forwardRef(({ className, ...props }, ref)
38966
39247
  }
38967
39248
  ));
38968
39249
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
38969
- var SelectContent = React142.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
39250
+ var SelectContent = React143.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
38970
39251
  SelectPrimitive.Content,
38971
39252
  {
38972
39253
  ref,
@@ -38994,7 +39275,7 @@ var SelectContent = React142.forwardRef(({ className, children, position = "popp
38994
39275
  }
38995
39276
  ) }));
38996
39277
  SelectContent.displayName = SelectPrimitive.Content.displayName;
38997
- var SelectLabel = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
39278
+ var SelectLabel = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38998
39279
  SelectPrimitive.Label,
38999
39280
  {
39000
39281
  ref,
@@ -39003,7 +39284,7 @@ var SelectLabel = React142.forwardRef(({ className, ...props }, ref) => /* @__PU
39003
39284
  }
39004
39285
  ));
39005
39286
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
39006
- var SelectItem = React142.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
39287
+ var SelectItem = React143.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
39007
39288
  SelectPrimitive.Item,
39008
39289
  {
39009
39290
  ref,
@@ -39019,7 +39300,7 @@ var SelectItem = React142.forwardRef(({ className, children, ...props }, ref) =>
39019
39300
  }
39020
39301
  ));
39021
39302
  SelectItem.displayName = SelectPrimitive.Item.displayName;
39022
- var SelectSeparator = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
39303
+ var SelectSeparator = React143.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
39023
39304
  SelectPrimitive.Separator,
39024
39305
  {
39025
39306
  ref,
@@ -39641,7 +39922,7 @@ var TimePickerDropdown = ({
39641
39922
  )
39642
39923
  ] });
39643
39924
  };
39644
- var SilentErrorBoundary = class extends React142__default.Component {
39925
+ var SilentErrorBoundary = class extends React143__default.Component {
39645
39926
  constructor(props) {
39646
39927
  super(props);
39647
39928
  this.handleClearAndReload = () => {
@@ -39674,6 +39955,12 @@ var SilentErrorBoundary = class extends React142__default.Component {
39674
39955
  componentStack: errorInfo.componentStack,
39675
39956
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
39676
39957
  });
39958
+ captureSentryException(error, {
39959
+ surface: "react_error_boundary",
39960
+ component_stack: errorInfo.componentStack,
39961
+ error_count: this.state.errorCount + 1,
39962
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
39963
+ });
39677
39964
  this.setState((prev) => ({
39678
39965
  errorCount: prev.errorCount + 1,
39679
39966
  lastError: error,
@@ -41137,15 +41424,16 @@ var FileManagerFilters = ({
41137
41424
  if ((displayCount > 0 || shouldShowEmptyIdleTime) && shouldShowCategory(category.id)) {
41138
41425
  const colorClasses = getColorClasses(category.color);
41139
41426
  const clipNodes = filteredClips.map((clip, index) => {
41140
- const timeString = new Date(clip.clip_timestamp).toLocaleTimeString("en-US", {
41141
- hour12: true,
41142
- hour: "numeric",
41143
- minute: "2-digit",
41144
- timeZone: timezone
41145
- // Use database timezone for display
41146
- });
41147
41427
  const cycleTime = extractCycleTimeSeconds(clip);
41148
- const displayLabel = category.id === "idle_time" && clip.idle_start_time && clip.idle_end_time ? formatIdleTimeRange(clip.idle_start_time, clip.idle_end_time, timezone) : `${timeString}${clip.duration && category.id !== "idle_time" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
41428
+ const baseTimeLabel = formatClipExplorerTimeLabel({
41429
+ categoryId: category.id,
41430
+ clipTimestamp: clip.clip_timestamp,
41431
+ timezone,
41432
+ durationSeconds: clip.duration,
41433
+ idleStartTime: clip.idle_start_time,
41434
+ idleEndTime: clip.idle_end_time
41435
+ });
41436
+ const displayLabel = `${baseTimeLabel}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
41149
41437
  return {
41150
41438
  id: clip.id,
41151
41439
  label: displayLabel,
@@ -41196,16 +41484,15 @@ var FileManagerFilters = ({
41196
41484
  percentileType: "fast-cycles",
41197
41485
  isPercentile: true,
41198
41486
  children: filteredFastCycles.map((clip, index) => {
41199
- const timeString = new Date(clip.creation_timestamp || clip.timestamp || "").toLocaleTimeString("en-US", {
41200
- hour12: true,
41201
- hour: "numeric",
41202
- minute: "2-digit",
41203
- timeZone: timezone
41204
- });
41205
41487
  const cycleTime = extractCycleTimeSeconds(clip);
41206
41488
  return {
41207
41489
  id: clip.id,
41208
- label: `${timeString}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41490
+ label: `${formatClipExplorerTimeLabel({
41491
+ categoryId: "fast-cycles",
41492
+ clipTimestamp: clip.creation_timestamp || clip.timestamp || "",
41493
+ timezone,
41494
+ durationSeconds: cycleTime
41495
+ })}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41209
41496
  type: "video",
41210
41497
  icon: getSeverityIcon(clip.severity, "fast-cycles", cycleTime, resolvedTargetCycleTime),
41211
41498
  timestamp: clip.creation_timestamp,
@@ -41228,16 +41515,15 @@ var FileManagerFilters = ({
41228
41515
  percentileType: "slow-cycles",
41229
41516
  isPercentile: true,
41230
41517
  children: filteredSlowCycles.map((clip, index) => {
41231
- const timeString = new Date(clip.creation_timestamp || clip.timestamp || "").toLocaleTimeString("en-US", {
41232
- hour12: true,
41233
- hour: "numeric",
41234
- minute: "2-digit",
41235
- timeZone: timezone
41236
- });
41237
41518
  const cycleTime = extractCycleTimeSeconds(clip);
41238
41519
  return {
41239
41520
  id: clip.id,
41240
- label: `${timeString}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41521
+ label: `${formatClipExplorerTimeLabel({
41522
+ categoryId: "slow-cycles",
41523
+ clipTimestamp: clip.creation_timestamp || clip.timestamp || "",
41524
+ timezone,
41525
+ durationSeconds: cycleTime
41526
+ })}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
41241
41527
  type: "video",
41242
41528
  icon: getSeverityIcon(clip.severity, "slow-cycles", cycleTime, resolvedTargetCycleTime),
41243
41529
  timestamp: clip.creation_timestamp,
@@ -46510,8 +46796,8 @@ var IdleTimeReasonChartComponent = ({
46510
46796
  updateAnimation = "replay",
46511
46797
  variant = "pie"
46512
46798
  }) => {
46513
- const [activeData, setActiveData] = React142__default.useState([]);
46514
- React142__default.useEffect(() => {
46799
+ const [activeData, setActiveData] = React143__default.useState([]);
46800
+ React143__default.useEffect(() => {
46515
46801
  if (updateAnimation === "smooth") {
46516
46802
  setActiveData(data && data.length > 0 ? data : []);
46517
46803
  return;
@@ -46530,7 +46816,7 @@ var IdleTimeReasonChartComponent = ({
46530
46816
  setActiveData([]);
46531
46817
  }
46532
46818
  }, [data, updateAnimation]);
46533
- React142__default.useEffect(() => {
46819
+ React143__default.useEffect(() => {
46534
46820
  if (!data || data.length === 0) return;
46535
46821
  data.forEach((entry, index) => {
46536
46822
  if (entry.name.toLowerCase().includes("other")) {
@@ -46538,7 +46824,7 @@ var IdleTimeReasonChartComponent = ({
46538
46824
  }
46539
46825
  });
46540
46826
  }, [data]);
46541
- const pieKey = React142__default.useMemo(() => {
46827
+ const pieKey = React143__default.useMemo(() => {
46542
46828
  if (updateAnimation === "smooth") {
46543
46829
  return "smooth";
46544
46830
  }
@@ -46708,9 +46994,44 @@ var IdleTimeReasonChartComponent = ({
46708
46994
  )
46709
46995
  ] });
46710
46996
  };
46711
- var IdleTimeReasonChart = React142__default.memo(IdleTimeReasonChartComponent);
46997
+ var IdleTimeReasonChart = React143__default.memo(IdleTimeReasonChartComponent);
46712
46998
  IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
46713
46999
  var IdleTimeReasonChart_default = IdleTimeReasonChart;
47000
+
47001
+ // src/lib/utils/cycleTime.ts
47002
+ var toFiniteNumber = (value) => {
47003
+ if (typeof value === "number" && Number.isFinite(value)) return value;
47004
+ if (typeof value === "string" && value.trim() !== "") {
47005
+ const parsed = Number(value);
47006
+ return Number.isFinite(parsed) ? parsed : null;
47007
+ }
47008
+ return null;
47009
+ };
47010
+ var getCycleRatio = (workspace) => {
47011
+ const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
47012
+ const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
47013
+ if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
47014
+ return null;
47015
+ }
47016
+ return idealCycleTime / avgCycleTime;
47017
+ };
47018
+ var formatCycleTimeValue = (value) => {
47019
+ const numericValue = toFiniteNumber(value);
47020
+ if (numericValue === null || numericValue <= 0) return "--";
47021
+ return `${numericValue.toFixed(1)}s`;
47022
+ };
47023
+ var CycleTimeComparison = memo$1(({
47024
+ workspace
47025
+ }) => {
47026
+ const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
47027
+ const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
47028
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
47029
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
47030
+ /* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
47031
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
47032
+ ] });
47033
+ }, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
47034
+ CycleTimeComparison.displayName = "CycleTimeComparison";
46714
47035
  var DEFAULT_PERFORMANCE_DATA = {
46715
47036
  avg_efficiency: 0,
46716
47037
  underperforming_workspaces: 0,
@@ -46809,6 +47130,7 @@ var LineMonthlyHistory = ({
46809
47130
  timezone,
46810
47131
  legend,
46811
47132
  monitoringMode,
47133
+ lineAssembly = false,
46812
47134
  underperformingWorkspaces = {},
46813
47135
  lineId,
46814
47136
  selectedShiftId = 0,
@@ -47098,7 +47420,7 @@ var LineMonthlyHistory = ({
47098
47420
  "div",
47099
47421
  {
47100
47422
  className: `w-3 h-3 sm:w-4 sm:h-4 rounded ${getColorClass(performance2.performance_score)}`,
47101
- title: `${getPerformanceText(performance2.performance_score)} performance on ${new Date(performance2.date).toLocaleDateString()}${performance2.efficiency !== void 0 ? ` (${performance2.efficiency.toFixed(1)}% efficiency)` : ""}`
47423
+ title: `${getPerformanceText(performance2.performance_score)} performance on ${new Date(performance2.date).toLocaleDateString()}${performance2.efficiency !== void 0 ? ` (${performance2.efficiency.toFixed(1)}% efficiency)` : performance2.avg_cycle_time !== void 0 && performance2.avg_cycle_time !== null && performance2.ideal_cycle_time !== void 0 && performance2.ideal_cycle_time !== null ? ` (${performance2.avg_cycle_time.toFixed(1)}s / ${performance2.ideal_cycle_time.toFixed(1)}s cycle time)` : ""}`
47102
47424
  },
47103
47425
  `${performance2.date}-${index}`
47104
47426
  )) });
@@ -47344,13 +47666,20 @@ var LineMonthlyHistory = ({
47344
47666
  onClick: () => handleWorkspaceClick(workspace),
47345
47667
  className: "block hover:bg-gray-50 transition-colors rounded-lg w-full text-left group",
47346
47668
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-1 sm:py-1.5 lg:py-2 px-1 sm:px-2 border-b border-gray-50 group-last:border-b-0", children: [
47347
- /* @__PURE__ */ jsxs("div", { className: "font-medium text-gray-900 text-[10px] sm:text-xs", children: [
47348
- getWorkspaceDisplayName(workspace.workspace_name, lineId),
47349
- workspace.avg_efficiency !== void 0 && /* @__PURE__ */ jsxs("span", { className: "ml-0.5 sm:ml-1 text-[8px] sm:text-[10px] text-gray-500", children: [
47350
- "(",
47669
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
47670
+ /* @__PURE__ */ jsx("div", { className: "font-medium text-gray-900 text-[10px] sm:text-xs truncate", children: getWorkspaceDisplayName(workspace.workspace_name, lineId) }),
47671
+ lineAssembly && workspace.metric_mode === "cycle_time" ? /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-[9px] sm:text-[11px]", children: /* @__PURE__ */ jsx(
47672
+ CycleTimeComparison,
47673
+ {
47674
+ workspace: {
47675
+ avg_cycle_time: workspace.avg_cycle_time ?? 0,
47676
+ ideal_cycle_time: workspace.ideal_cycle_time ?? void 0
47677
+ }
47678
+ }
47679
+ ) }) : workspace.avg_efficiency !== void 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-0.5 text-[8px] sm:text-[10px] text-gray-500", children: [
47351
47680
  (workspace.avg_efficiency || 0).toFixed(1),
47352
- "%)"
47353
- ] })
47681
+ "%"
47682
+ ] }) : null
47354
47683
  ] }),
47355
47684
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 sm:gap-1 lg:gap-1.5", children: renderPerformanceSquares(workspace.last_5_days) })
47356
47685
  ] })
@@ -49720,7 +50049,7 @@ var WorkspaceMonthlyHistory = ({
49720
50049
  Math.round(shiftData.efficiency || 0),
49721
50050
  "%"
49722
50051
  ] }),
49723
- /* @__PURE__ */ jsxs("div", { children: [
50052
+ !isAssemblyWorkspace && /* @__PURE__ */ jsxs("div", { children: [
49724
50053
  "Output: ",
49725
50054
  shiftData.output || 0,
49726
50055
  " units"
@@ -51075,7 +51404,7 @@ var arePropsEqual = (prevProps, nextProps) => {
51075
51404
  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 && prevLegend.green_min === nextLegend.green_min && prevLegend.green_max === nextLegend.green_max && prevLegend.yellow_min === nextLegend.yellow_min && prevLegend.yellow_max === nextLegend.yellow_max && prevLegend.red_min === nextLegend.red_min && prevLegend.red_max === nextLegend.red_max && prevLegend.critical_threshold === nextLegend.critical_threshold && // Position doesn't need deep equality check as it's generally static
51076
51405
  prevProps.position.id === nextProps.position.id;
51077
51406
  };
51078
- var WorkspaceGridItem = React142__default.memo(({
51407
+ var WorkspaceGridItem = React143__default.memo(({
51079
51408
  data,
51080
51409
  position,
51081
51410
  isBottleneck = false,
@@ -51103,7 +51432,7 @@ var WorkspaceGridItem = React142__default.memo(({
51103
51432
  const handleClick = useCallback((e) => {
51104
51433
  e.preventDefault();
51105
51434
  if (isInactive) return;
51106
- const displayName = getWorkspaceDisplayName(data.workspace_name, data.line_id);
51435
+ const displayName = data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id);
51107
51436
  const currentPath = typeof window !== "undefined" ? `${window.location.pathname}${window.location.search}` : "/";
51108
51437
  const navParams = getWorkspaceNavigationParams(data.workspace_id, displayName, data.line_id, currentPath);
51109
51438
  navigate(`/workspace/${data.workspace_id}${navParams}`, {
@@ -51152,7 +51481,7 @@ var WorkspaceGridItem = React142__default.memo(({
51152
51481
  onClick: handleClick,
51153
51482
  className: `${styles2} ${colorClass} ${isBottleneck ? "ring-2 ring-red-500/70" : ""} ${isVeryLowEfficiency ? "ring-2 ring-red-500/50" : ""} ${isInactive ? "bg-gray-200" : ""} shadow-lg touch-manipulation active:scale-[0.98] transition-transform`,
51154
51483
  "aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
51155
- title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : getWorkspaceDisplayName(data.workspace_name, data.line_id),
51484
+ title: isInactive ? `Inactive: ${data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : data.displayName || getWorkspaceDisplayName(data.workspace_name, data.line_id),
51156
51485
  children: /* @__PURE__ */ jsx("div", { className: `font-semibold tracking-wide text-lg sm:text-xl md:text-[min(4vw,2rem)] uppercase ${isInactive ? "text-gray-400" : "text-white"} drop-shadow-sm`, children: workspaceNumber })
51157
51486
  }
51158
51487
  ),
@@ -51170,7 +51499,7 @@ var WorkspaceGridItem = React142__default.memo(({
51170
51499
  );
51171
51500
  }, arePropsEqual);
51172
51501
  WorkspaceGridItem.displayName = "WorkspaceGridItem";
51173
- var WorkspaceGrid = React142__default.memo(({
51502
+ var WorkspaceGrid = React143__default.memo(({
51174
51503
  workspaces,
51175
51504
  isPdfMode = false,
51176
51505
  customWorkspacePositions,
@@ -51434,7 +51763,7 @@ var KPICard = ({
51434
51763
  }) => {
51435
51764
  useThemeConfig();
51436
51765
  const { formatNumber } = useFormatNumber();
51437
- const trendInfo = React142__default.useMemo(() => {
51766
+ const trendInfo = React143__default.useMemo(() => {
51438
51767
  let trendValue = trend || "neutral";
51439
51768
  if (change !== void 0 && trend === void 0) {
51440
51769
  trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
@@ -51461,7 +51790,7 @@ var KPICard = ({
51461
51790
  const shouldShowTrend = !(change === 0 && trend === void 0);
51462
51791
  return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
51463
51792
  }, [trend, change]);
51464
- const formattedValue = React142__default.useMemo(() => {
51793
+ const formattedValue = React143__default.useMemo(() => {
51465
51794
  if (title === "Quality Compliance" && typeof value === "number") {
51466
51795
  return value.toFixed(1);
51467
51796
  }
@@ -51475,7 +51804,7 @@ var KPICard = ({
51475
51804
  }
51476
51805
  return value;
51477
51806
  }, [value, title]);
51478
- const formattedChange = React142__default.useMemo(() => {
51807
+ const formattedChange = React143__default.useMemo(() => {
51479
51808
  if (change === void 0 || change === 0 && !showZeroChange) return null;
51480
51809
  const absChange = Math.abs(change);
51481
51810
  return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
@@ -52982,7 +53311,7 @@ var Breadcrumbs = ({ items }) => {
52982
53311
  }
52983
53312
  }
52984
53313
  };
52985
- 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(React142__default.Fragment, { children: [
53314
+ 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(React143__default.Fragment, { children: [
52986
53315
  index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
52987
53316
  /* @__PURE__ */ jsxs(
52988
53317
  "span",
@@ -54458,7 +54787,7 @@ var AwardBadge = ({
54458
54787
  }) => {
54459
54788
  const styles2 = getBadgeStyles(type);
54460
54789
  const Icon2 = CustomIcon || getDefaultIcon(type);
54461
- const randomDelay = React142__default.useMemo(() => Math.random() * 2, []);
54790
+ const randomDelay = React143__default.useMemo(() => Math.random() * 2, []);
54462
54791
  const floatingAnimation = {
54463
54792
  animate: {
54464
54793
  y: [0, -10, 0],
@@ -59962,67 +60291,77 @@ var NotificationService = class {
59962
60291
  this.supabaseClient = supabaseClient || null;
59963
60292
  }
59964
60293
  async fetchWithAuth(url, options = {}) {
59965
- if (!this.supabaseClient) {
59966
- throw new Error("Supabase client not initialized. Please provide a Supabase client to NotificationService.");
59967
- }
59968
- const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
59969
- if (sessionError) {
59970
- console.error("Session error:", sessionError);
59971
- throw new Error("Failed to get authentication session. Please log in.");
59972
- }
59973
- if (!session) {
59974
- console.error("No session found. User must be logged in.");
59975
- throw new Error("User not authenticated. Please log in.");
59976
- }
59977
- if (!session.access_token) {
59978
- console.error("Session exists but no access_token found");
59979
- throw new Error("Invalid session. Please log in again.");
59980
- }
59981
- const token = session.access_token;
59982
- if (process.env.NODE_ENV === "development") {
59983
- console.log("[NotificationService] Using JWT token for notifications API");
59984
- }
59985
- const headers = {
59986
- "Content-Type": "application/json",
59987
- ...options.headers,
59988
- "Authorization": `Bearer ${token}`
59989
- };
59990
- const response = await fetch(url, {
59991
- ...options,
59992
- headers
59993
- });
59994
- if (response.status === 401) {
59995
- console.error("401 Unauthorized - Token expired or invalid");
59996
- throw new Error("Authentication failed. Please log in again.");
59997
- }
59998
- if (response.status === 403) {
59999
- console.error("403 Forbidden - User does not have permission");
60000
- throw new Error("Access denied. You do not have permission to access this resource.");
60001
- }
60002
- if (response.status === 500) {
60003
- console.error("500 Internal Server Error - Backend error");
60004
- let errorDetail = "Internal server error occurred.";
60005
- try {
60006
- const errorData = await response.text();
60007
- console.error("Backend error details:", errorData);
60008
- errorDetail = errorData || errorDetail;
60009
- } catch (e) {
60294
+ try {
60295
+ if (!this.supabaseClient) {
60296
+ throw new Error("Supabase client not initialized. Please provide a Supabase client to NotificationService.");
60010
60297
  }
60011
- throw new Error(`Backend error: ${errorDetail}`);
60012
- }
60013
- if (!response.ok) {
60014
- console.error(`HTTP ${response.status} - ${response.statusText}`);
60015
- let errorDetail = response.statusText;
60016
- try {
60017
- const errorData = await response.json();
60018
- if (errorData.detail) {
60019
- errorDetail = errorData.detail;
60298
+ const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
60299
+ if (sessionError) {
60300
+ console.error("Session error:", sessionError);
60301
+ throw new Error("Failed to get authentication session. Please log in.");
60302
+ }
60303
+ if (!session) {
60304
+ console.error("No session found. User must be logged in.");
60305
+ throw new Error("User not authenticated. Please log in.");
60306
+ }
60307
+ if (!session.access_token) {
60308
+ console.error("Session exists but no access_token found");
60309
+ throw new Error("Invalid session. Please log in again.");
60310
+ }
60311
+ const token = session.access_token;
60312
+ if (process.env.NODE_ENV === "development") {
60313
+ console.log("[NotificationService] Using JWT token for notifications API");
60314
+ }
60315
+ const headers = {
60316
+ "Content-Type": "application/json",
60317
+ ...options.headers,
60318
+ "Authorization": `Bearer ${token}`
60319
+ };
60320
+ const response = await fetch(url, {
60321
+ ...options,
60322
+ headers
60323
+ });
60324
+ if (response.status === 401) {
60325
+ console.error("401 Unauthorized - Token expired or invalid");
60326
+ throw new Error("Authentication failed. Please log in again.");
60327
+ }
60328
+ if (response.status === 403) {
60329
+ console.error("403 Forbidden - User does not have permission");
60330
+ throw new Error("Access denied. You do not have permission to access this resource.");
60331
+ }
60332
+ if (response.status === 500) {
60333
+ console.error("500 Internal Server Error - Backend error");
60334
+ let errorDetail = "Internal server error occurred.";
60335
+ try {
60336
+ const errorData = await response.text();
60337
+ console.error("Backend error details:", errorData);
60338
+ errorDetail = errorData || errorDetail;
60339
+ } catch (e) {
60020
60340
  }
60021
- } catch (e) {
60341
+ throw new Error(`Backend error: ${errorDetail}`);
60022
60342
  }
60023
- throw new Error(`Request failed (${response.status}): ${errorDetail}`);
60343
+ if (!response.ok) {
60344
+ console.error(`HTTP ${response.status} - ${response.statusText}`);
60345
+ let errorDetail = response.statusText;
60346
+ try {
60347
+ const errorData = await response.json();
60348
+ if (errorData.detail) {
60349
+ errorDetail = errorData.detail;
60350
+ }
60351
+ } catch (e) {
60352
+ }
60353
+ throw new Error(`Request failed (${response.status}): ${errorDetail}`);
60354
+ }
60355
+ return response;
60356
+ } catch (error) {
60357
+ captureHandledFrontendException(error, {
60358
+ surface: "notification_service",
60359
+ url,
60360
+ method: options.method || "GET",
60361
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
60362
+ });
60363
+ throw error;
60024
60364
  }
60025
- return response;
60026
60365
  }
60027
60366
  /**
60028
60367
  * Get bottleneck notifications
@@ -60096,8 +60435,6 @@ function HomeView({
60096
60435
  }) {
60097
60436
  const [isHydrated, setIsHydrated] = useState(false);
60098
60437
  const [isChangingFilter, setIsChangingFilter] = useState(false);
60099
- const [errorMessage, setErrorMessage] = useState(null);
60100
- const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
60101
60438
  const [hasInitialDataLoaded, setHasInitialDataLoaded] = useState(false);
60102
60439
  const [showDataLoading, setShowDataLoading] = useState(false);
60103
60440
  const loadingStartRef = useRef(null);
@@ -60106,7 +60443,7 @@ function HomeView({
60106
60443
  const dashboardConfig = useDashboardConfig();
60107
60444
  const entityConfig = useEntityConfig();
60108
60445
  const supabaseClient = useSupabaseClient();
60109
- const { user } = useAuth();
60446
+ const { user, authStatus, isRecoveringSession, retrySessionHydration } = useAuth();
60110
60447
  const { lines: dbLines } = useLines();
60111
60448
  const mergedLineNames = useMemo(() => {
60112
60449
  const merged = { ...lineNames };
@@ -60240,26 +60577,7 @@ function HomeView({
60240
60577
  visibleLineIds,
60241
60578
  dashboardConfig?.shiftConfig
60242
60579
  );
60243
- useEffect(() => {
60244
- const initDisplayNames = async () => {
60245
- try {
60246
- for (const lineId of selectedLineIds) {
60247
- await preInitializeWorkspaceDisplayNames(lineId);
60248
- }
60249
- setDisplayNamesInitialized(true);
60250
- } catch (error) {
60251
- console.error("Failed to pre-initialize workspace display names:", error);
60252
- setDisplayNamesInitialized(true);
60253
- }
60254
- };
60255
- initDisplayNames();
60256
- }, [selectedLineIdsKey]);
60257
- const displayNameLineId = isMultiLineSelection ? void 0 : primarySelectedLineId;
60258
- const {
60259
- displayNames: workspaceDisplayNames,
60260
- loading: displayNamesLoading,
60261
- error: displayNamesError
60262
- } = useWorkspaceDisplayNames(displayNameLineId, void 0);
60580
+ const shouldEnableMetricsFetch = authStatus === "ready";
60263
60581
  const handleLineMetricsUpdate = useCallback(() => {
60264
60582
  if (trendRefreshTimerRef.current) {
60265
60583
  window.clearTimeout(trendRefreshTimerRef.current);
@@ -60286,9 +60604,32 @@ function HomeView({
60286
60604
  lineId: metricsScopeLineId,
60287
60605
  lineIds: selectedLineIds,
60288
60606
  onLineMetricsUpdate: handleLineMetricsUpdate,
60289
- userAccessibleLineIds: visibleLineIds
60607
+ userAccessibleLineIds: visibleLineIds,
60290
60608
  // Pass user's accessible lines for supervisor filtering
60609
+ enabled: shouldEnableMetricsFetch
60291
60610
  });
60611
+ const metricsDisplayNames = useMemo(() => {
60612
+ const nextDisplayNames = {};
60613
+ workspaceMetrics.forEach((workspace) => {
60614
+ if (!workspace.displayName) {
60615
+ return;
60616
+ }
60617
+ nextDisplayNames[`${workspace.line_id}_${workspace.workspace_name}`] = workspace.displayName;
60618
+ });
60619
+ return nextDisplayNames;
60620
+ }, [workspaceMetrics]);
60621
+ useEffect(() => {
60622
+ workspaceMetrics.forEach((workspace) => {
60623
+ if (!workspace.displayName) {
60624
+ return;
60625
+ }
60626
+ upsertWorkspaceDisplayNameInCache({
60627
+ lineId: workspace.line_id,
60628
+ workspaceId: workspace.workspace_name,
60629
+ displayName: workspace.displayName
60630
+ });
60631
+ });
60632
+ }, [workspaceMetrics]);
60292
60633
  const trendGroups = useMemo(() => {
60293
60634
  const lineMetricsRows = lineMetrics || [];
60294
60635
  if (!lineMetricsRows.length) return null;
@@ -60729,13 +61070,13 @@ function HomeView({
60729
61070
  dashboard_surface: "monitor"
60730
61071
  });
60731
61072
  }, []);
60732
- useEffect(() => {
60733
- if (metricsError) {
60734
- setErrorMessage(metricsError.message);
60735
- } else {
60736
- setErrorMessage(null);
61073
+ const metricsErrorMessage = metricsError?.message || null;
61074
+ const handleRetryDashboardData = useCallback(async () => {
61075
+ if (isRecoveringSession) {
61076
+ await retrySessionHydration();
60737
61077
  }
60738
- }, [metricsError]);
61078
+ refetchMetrics();
61079
+ }, [isRecoveringSession, refetchMetrics, retrySessionHydration]);
60739
61080
  const getTrackedLineScope = useCallback((lineIdsForScope) => {
60740
61081
  if (isAllLinesSelection(lineIdsForScope)) {
60741
61082
  return factoryViewId;
@@ -60793,7 +61134,7 @@ function HomeView({
60793
61134
  }
60794
61135
  }, [metricsLoading, isChangingFilter]);
60795
61136
  useEffect(() => {
60796
- if (!metricsLoading && !hasInitialDataLoaded) {
61137
+ if (shouldEnableMetricsFetch && !metricsLoading && !metricsError && !hasInitialDataLoaded) {
60797
61138
  setHasInitialDataLoaded(true);
60798
61139
  trackCoreEvent("monitor page loaded", {
60799
61140
  default_line_id: defaultLineId,
@@ -60802,7 +61143,7 @@ function HomeView({
60802
61143
  dashboard_surface: "monitor"
60803
61144
  });
60804
61145
  }
60805
- }, [metricsLoading, hasInitialDataLoaded, defaultLineId, factoryViewId, isSupervisor]);
61146
+ }, [shouldEnableMetricsFetch, metricsLoading, metricsError, hasInitialDataLoaded, defaultLineId, factoryViewId, isSupervisor]);
60806
61147
  const lineTitle = useMemo(() => {
60807
61148
  return factoryName;
60808
61149
  }, [factoryName]);
@@ -60952,8 +61293,9 @@ function HomeView({
60952
61293
  }, [isLoading, minDuration]);
60953
61294
  return showLoading;
60954
61295
  };
60955
- const isInitialLoading = !isHydrated || !hasInitialDataLoaded && (displayNamesLoading || !displayNamesInitialized);
60956
- const isDataLoading = metricsLoading || displayNamesLoading && workspaceMetrics.length === 0;
61296
+ const isAuthBootstrapping = authStatus === "loading";
61297
+ const isInitialLoading = !isHydrated || !hasInitialDataLoaded && (isAuthBootstrapping || shouldEnableMetricsFetch && metricsLoading);
61298
+ const isDataLoading = metricsLoading;
60957
61299
  const hasKpiDataReady = useMemo(() => {
60958
61300
  const lineMetricsRows = lineMetrics || [];
60959
61301
  if (selectedLineIds.length > 1) {
@@ -60962,6 +61304,10 @@ function HomeView({
60962
61304
  return lineMetricsRows.some((row) => row?.line_id === primarySelectedLineId);
60963
61305
  }, [lineMetrics, primarySelectedLineId, selectedLineIdSet, selectedLineIds.length]);
60964
61306
  const isKpiLoading = !hasKpiDataReady;
61307
+ const shouldShowReconnectScreen = !hasInitialDataLoaded && (isRecoveringSession || !shouldEnableMetricsFetch && authStatus !== "failed" || !!metricsErrorMessage && authStatus !== "failed");
61308
+ const shouldShowFatalLoadFailure = !hasInitialDataLoaded && !!metricsErrorMessage && authStatus === "failed";
61309
+ const shouldShowRecoveryBanner = hasInitialDataLoaded && (isRecoveringSession || !!metricsErrorMessage);
61310
+ const recoveryBannerMessage = isRecoveringSession ? "Reconnecting to the dashboard. Showing the last good data while auth recovers." : metricsErrorMessage ? "Live data refresh failed. Showing the last good dashboard snapshot." : null;
60965
61311
  useEffect(() => {
60966
61312
  const minLoadingDurationMs = 250;
60967
61313
  if (isDataLoading) {
@@ -61001,14 +61347,41 @@ function HomeView({
61001
61347
  if (isInitialLoading) {
61002
61348
  return /* @__PURE__ */ jsx(LoadingPageCmp, { message: "Loading Dashboard..." });
61003
61349
  }
61004
- if (errorMessage || displayNamesError) {
61005
- 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: [
61006
- /* @__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" }) }),
61007
- /* @__PURE__ */ jsxs("span", { className: "text-base sm:text-lg font-medium", children: [
61008
- "Error: ",
61009
- errorMessage || displayNamesError?.message
61010
- ] })
61011
- ] }) }) });
61350
+ if (shouldShowReconnectScreen) {
61351
+ return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center bg-slate-50 px-6", children: /* @__PURE__ */ jsxs("div", { className: "max-w-md rounded-2xl border border-slate-200 bg-white p-8 text-center shadow-sm", children: [
61352
+ /* @__PURE__ */ jsx("div", { className: "mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-amber-50 text-amber-600", children: /* @__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: "M4 4v5h.582m14.836 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-14.837-2m14.837 2H15" }) }) }),
61353
+ /* @__PURE__ */ jsx("h2", { className: "mt-4 text-lg font-semibold text-slate-900", children: "Reconnecting to Optifye" }),
61354
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-slate-600", children: metricsErrorMessage || "Your session is recovering after the tab resumed. We will retry automatically." }),
61355
+ /* @__PURE__ */ jsx(
61356
+ "button",
61357
+ {
61358
+ type: "button",
61359
+ onClick: () => {
61360
+ void handleRetryDashboardData();
61361
+ },
61362
+ className: "mt-5 inline-flex items-center justify-center rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-slate-800",
61363
+ children: "Retry Now"
61364
+ }
61365
+ )
61366
+ ] }) });
61367
+ }
61368
+ if (shouldShowFatalLoadFailure) {
61369
+ return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center bg-slate-50 px-6", children: /* @__PURE__ */ jsxs("div", { className: "max-w-md rounded-2xl border border-red-200 bg-white p-8 text-center shadow-sm", children: [
61370
+ /* @__PURE__ */ jsx("div", { className: "mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-red-50 text-red-600", children: /* @__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" }) }) }),
61371
+ /* @__PURE__ */ jsx("h2", { className: "mt-4 text-lg font-semibold text-slate-900", children: "Unable to load the dashboard" }),
61372
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-slate-600", children: metricsErrorMessage }),
61373
+ /* @__PURE__ */ jsx(
61374
+ "button",
61375
+ {
61376
+ type: "button",
61377
+ onClick: () => {
61378
+ void handleRetryDashboardData();
61379
+ },
61380
+ className: "mt-5 inline-flex items-center justify-center rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-slate-800",
61381
+ children: "Retry Now"
61382
+ }
61383
+ )
61384
+ ] }) });
61012
61385
  }
61013
61386
  return /* @__PURE__ */ jsx(
61014
61387
  motion.div,
@@ -61027,6 +61400,20 @@ function HomeView({
61027
61400
  headerControls: kpiSectionControl
61028
61401
  }
61029
61402
  ) }) }),
61403
+ shouldShowRecoveryBanner && recoveryBannerMessage ? /* @__PURE__ */ jsx("div", { className: "border-b border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [
61404
+ /* @__PURE__ */ jsx("span", { children: recoveryBannerMessage }),
61405
+ /* @__PURE__ */ jsx(
61406
+ "button",
61407
+ {
61408
+ type: "button",
61409
+ onClick: () => {
61410
+ void handleRetryDashboardData();
61411
+ },
61412
+ className: "inline-flex items-center justify-center rounded-md border border-amber-300 bg-white px-3 py-1.5 text-xs font-medium text-amber-900 transition-colors hover:bg-amber-100",
61413
+ children: "Retry"
61414
+ }
61415
+ )
61416
+ ] }) }) : null,
61030
61417
  /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative flex flex-col", children: /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-[calc(100vh-100px)] sm:min-h-0", children: workspaceMetricsWithBreakState.length > 0 ? /* @__PURE__ */ jsx(
61031
61418
  motion.div,
61032
61419
  {
@@ -61034,7 +61421,7 @@ function HomeView({
61034
61421
  animate: { opacity: 1, scale: 1 },
61035
61422
  transition: { duration: 0.3 },
61036
61423
  className: "h-full",
61037
- children: React142__default.createElement(WorkspaceGrid, {
61424
+ children: React143__default.createElement(WorkspaceGrid, {
61038
61425
  workspaces: workspaceMetricsWithBreakState,
61039
61426
  lineNames: mergedLineNames,
61040
61427
  lineOrder: selectedLineIds,
@@ -61043,7 +61430,7 @@ function HomeView({
61043
61430
  videoSources,
61044
61431
  videoStreamsByWorkspaceId,
61045
61432
  videoStreamsLoading,
61046
- displayNames: workspaceDisplayNames,
61433
+ displayNames: metricsDisplayNames,
61047
61434
  hasFlowBuffers,
61048
61435
  className: "h-full",
61049
61436
  toolbarRightContent: lineSelectorComponent,
@@ -61067,7 +61454,7 @@ function HomeView({
61067
61454
  animate: { opacity: 1, scale: 1 },
61068
61455
  transition: { duration: 0.3 },
61069
61456
  className: "h-full",
61070
- children: React142__default.createElement(WorkspaceGrid, {
61457
+ children: React143__default.createElement(WorkspaceGrid, {
61071
61458
  workspaces: [],
61072
61459
  // Show empty grid while loading
61073
61460
  lineNames: mergedLineNames,
@@ -61077,7 +61464,7 @@ function HomeView({
61077
61464
  videoSources,
61078
61465
  videoStreamsByWorkspaceId,
61079
61466
  videoStreamsLoading,
61080
- displayNames: workspaceDisplayNames,
61467
+ displayNames: metricsDisplayNames,
61081
61468
  hasFlowBuffers,
61082
61469
  className: "h-full",
61083
61470
  toolbarRightContent: lineSelectorComponent,
@@ -61135,7 +61522,7 @@ function HomeView({
61135
61522
  }
61136
61523
  );
61137
61524
  }
61138
- var AuthenticatedHomeView = withAuth(React142__default.memo(HomeView));
61525
+ var AuthenticatedHomeView = withAuth(React143__default.memo(HomeView));
61139
61526
  var HomeView_default = HomeView;
61140
61527
  function withWorkspaceDisplayNames(Component3, options = {}) {
61141
61528
  const {
@@ -61333,6 +61720,7 @@ var buildLineInfoSnapshot = (lineDetails, metrics2) => {
61333
61720
  shift_id: metrics2.shift_id ?? 0,
61334
61721
  date: metrics2.date || "",
61335
61722
  monitoring_mode: lineDetails.monitoring_mode ?? void 0,
61723
+ assembly: lineDetails.assembly ?? null,
61336
61724
  metrics: {
61337
61725
  avg_efficiency: metrics2.avg_efficiency ?? 0,
61338
61726
  avg_cycle_time: metrics2.avg_cycle_time ?? 0,
@@ -61365,6 +61753,7 @@ var transformWorkspaceMetrics = (workspaceData, lineId, companyId, queryDate, qu
61365
61753
  pph: item.avg_pph || 0,
61366
61754
  performance_score: item.performance_score || 0,
61367
61755
  avg_cycle_time: item.avg_cycle_time || 0,
61756
+ ideal_cycle_time: item.ideal_cycle_time ?? void 0,
61368
61757
  trend: item.trend_score === 1 ? 2 : 0,
61369
61758
  predicted_output: item.ideal_output || 0,
61370
61759
  efficiency: item.efficiency || 0,
@@ -61400,7 +61789,8 @@ var transformLineDetails = (lineId, detailResponse) => {
61400
61789
  id: detailResponse.line_details.factory_id || "",
61401
61790
  factory_name: detailResponse.line_details.factory_name || ""
61402
61791
  },
61403
- monitoring_mode: detailResponse.line_details.monitoring_mode ?? void 0
61792
+ monitoring_mode: detailResponse.line_details.monitoring_mode ?? void 0,
61793
+ assembly: detailResponse.line_details.assembly ?? null
61404
61794
  };
61405
61795
  };
61406
61796
  var transformLineMetrics = (lineId, detailResponse, queryDate, queryShiftId) => {
@@ -61801,6 +62191,21 @@ function useEfficiencyLegend(companyId) {
61801
62191
  refetch: fetchLegend
61802
62192
  };
61803
62193
  }
62194
+
62195
+ // src/lib/utils/kpiPoorestPerformers.ts
62196
+ var getWorstAssemblyCycleTimeWorkspaces = (workspaces, limit = 5) => {
62197
+ return workspaces.map((workspace, index) => ({
62198
+ workspace,
62199
+ index,
62200
+ cycleRatio: getCycleRatio(workspace)
62201
+ })).sort((a, b) => {
62202
+ if (a.cycleRatio === null && b.cycleRatio === null) return a.index - b.index;
62203
+ if (a.cycleRatio === null) return 1;
62204
+ if (b.cycleRatio === null) return -1;
62205
+ if (a.cycleRatio !== b.cycleRatio) return a.cycleRatio - b.cycleRatio;
62206
+ return a.index - b.index;
62207
+ }).slice(0, limit).map(({ workspace }) => workspace);
62208
+ };
61804
62209
  var WEEKDAYS4 = ["S", "M", "T", "W", "T", "F", "S"];
61805
62210
  var MonthlyRangeFilter = ({
61806
62211
  month,
@@ -62400,7 +62805,13 @@ var BottomSection = memo$1(({
62400
62805
  }) => {
62401
62806
  const navigation = useNavigation();
62402
62807
  const handleNavigate = navigate || navigation.navigate;
62808
+ const isAssemblyLine = (lineInfo.assembly === true || workspaceData.some((workspace) => workspace.assembly_enabled)) && lineInfo.monitoring_mode !== "uptime";
62809
+ const assemblyRows = useMemo(
62810
+ () => isAssemblyLine ? getWorstAssemblyCycleTimeWorkspaces(workspaceData) : [],
62811
+ [isAssemblyLine, workspaceData]
62812
+ );
62403
62813
  const handleWorkspaceClick = useCallback((ws, index) => {
62814
+ const cycleRatio = getCycleRatio(ws);
62404
62815
  trackCoreEvent("Workspace from KPI Clicked", {
62405
62816
  workspace_name: ws.workspace_name,
62406
62817
  workspace_id: ws.workspace_uuid,
@@ -62409,9 +62820,13 @@ var BottomSection = memo$1(({
62409
62820
  efficiency: ws.efficiency,
62410
62821
  action_count: ws.action_count,
62411
62822
  action_threshold: ws.action_threshold,
62823
+ avg_cycle_time: ws.avg_cycle_time ?? null,
62824
+ ideal_cycle_time: ws.ideal_cycle_time ?? null,
62825
+ cycle_ratio: cycleRatio,
62826
+ ranking_metric: isAssemblyLine ? "cycle_time" : "efficiency",
62412
62827
  section: "Poorest Performing Workspaces"
62413
62828
  });
62414
- }, [workspaceData.length]);
62829
+ }, [isAssemblyLine, workspaceData.length]);
62415
62830
  return /* @__PURE__ */ jsxs(
62416
62831
  motion.div,
62417
62832
  {
@@ -62433,14 +62848,42 @@ var BottomSection = memo$1(({
62433
62848
  )
62434
62849
  ] }),
62435
62850
  /* @__PURE__ */ jsxs("div", { className: "divide-y overflow-auto flex-1 pr-1 sm:pr-2", children: [
62436
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pb-2", children: [
62851
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between pb-2", children: isAssemblyLine ? /* @__PURE__ */ jsxs(Fragment, { children: [
62852
+ /* @__PURE__ */ jsx("div", { className: "font-medium text-gray-500 min-w-[80px] sm:min-w-[100px] md:min-w-[120px] text-xs sm:text-sm md:text-base", children: "Workspace" }),
62853
+ /* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500 pr-1 sm:pr-2", children: "Cycle Time" })
62854
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
62437
62855
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 sm:gap-3 md:gap-6", children: [
62438
62856
  /* @__PURE__ */ jsx("div", { className: "font-medium text-gray-500 min-w-[80px] sm:min-w-[100px] md:min-w-[120px] text-xs sm:text-sm md:text-base", children: "Workspace" }),
62439
62857
  /* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500", children: "Current/Ideal" })
62440
62858
  ] }),
62441
62859
  /* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-500 pr-1 sm:pr-2", children: "Efficiency" })
62442
- ] }),
62443
- lineInfo.metrics.poorest_performing_workspaces && lineInfo.metrics.poorest_performing_workspaces.length > 0 ? lineInfo.metrics.poorest_performing_workspaces.map((ws, index) => {
62860
+ ] }) }),
62861
+ isAssemblyLine ? assemblyRows.map((ws, index) => {
62862
+ if (!ws.workspace_uuid) {
62863
+ return null;
62864
+ }
62865
+ const clickHandler = () => handleWorkspaceClick(ws, index);
62866
+ const displayName = workspaceDisplayNames && workspaceDisplayNames[ws.workspace_name] || getWorkspaceDisplayName(ws.workspace_name, lineId);
62867
+ const navParams = getWorkspaceNavigationParams(ws.workspace_uuid, displayName, lineId);
62868
+ const dateShiftParams = urlDate ? `&date=${urlDate}&shift=${urlShift || "0"}` : "";
62869
+ const returnToParam = `&returnTo=${encodeURIComponent(`/kpis/${lineInfo?.line_id}`)}`;
62870
+ const fullUrl = `/workspace/${ws.workspace_uuid}${navParams}${dateShiftParams}${returnToParam}`;
62871
+ return /* @__PURE__ */ jsx(
62872
+ "div",
62873
+ {
62874
+ onClick: () => {
62875
+ clickHandler();
62876
+ handleNavigate && handleNavigate(fullUrl);
62877
+ },
62878
+ className: "block py-2 sm:py-3 hover:bg-gray-50 transition-colors rounded-lg cursor-pointer",
62879
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
62880
+ /* @__PURE__ */ jsx("div", { className: "min-w-[80px] sm:min-w-[100px] md:min-w-[120px]", children: /* @__PURE__ */ jsx("div", { className: "font-medium text-gray-900 text-xs sm:text-sm md:text-base truncate", children: displayName }) }),
62881
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 text-xs md:text-sm", children: /* @__PURE__ */ jsx(CycleTimeComparison, { workspace: ws }) })
62882
+ ] })
62883
+ },
62884
+ ws.workspace_uuid
62885
+ );
62886
+ }) : lineInfo.metrics.poorest_performing_workspaces && lineInfo.metrics.poorest_performing_workspaces.length > 0 ? lineInfo.metrics.poorest_performing_workspaces.map((ws, index) => {
62444
62887
  const wsMetrics = workspaceData.find((w) => w.workspace_name === ws.workspace_name);
62445
62888
  const wsUuid = wsMetrics?.workspace_uuid;
62446
62889
  if (!wsUuid) {
@@ -62536,10 +62979,63 @@ var BottomSection = memo$1(({
62536
62979
  const prevPoorest = prevProps.lineInfo.metrics.poorest_performing_workspaces || [];
62537
62980
  const nextPoorest = nextProps.lineInfo.metrics.poorest_performing_workspaces || [];
62538
62981
  if (prevPoorest.length !== nextPoorest.length) return false;
62982
+ const prevPoorestSignature = JSON.stringify(prevPoorest);
62983
+ const nextPoorestSignature = JSON.stringify(nextPoorest);
62984
+ if (prevPoorestSignature !== nextPoorestSignature) return false;
62985
+ if (prevProps.lineInfo.assembly !== nextProps.lineInfo.assembly) return false;
62986
+ if (prevProps.lineInfo.monitoring_mode !== nextProps.lineInfo.monitoring_mode) return false;
62539
62987
  if (prevProps.hourlyOutputData.length !== nextProps.hourlyOutputData.length) return false;
62540
62988
  const hourlyDataChanged = prevProps.hourlyOutputData.some((value, index) => value !== nextProps.hourlyOutputData[index]);
62541
62989
  if (hourlyDataChanged) return false;
62542
62990
  if (prevProps.sortedByEfficiency.length !== nextProps.sortedByEfficiency.length) return false;
62991
+ const prevSortedSignature = JSON.stringify(
62992
+ prevProps.sortedByEfficiency.map((workspace) => ({
62993
+ workspace_uuid: workspace.workspace_uuid,
62994
+ workspace_name: workspace.workspace_name,
62995
+ efficiency: workspace.efficiency,
62996
+ action_count: workspace.action_count,
62997
+ predicted_output: workspace.predicted_output,
62998
+ avg_cycle_time: workspace.avg_cycle_time,
62999
+ ideal_cycle_time: workspace.ideal_cycle_time ?? null
63000
+ }))
63001
+ );
63002
+ const nextSortedSignature = JSON.stringify(
63003
+ nextProps.sortedByEfficiency.map((workspace) => ({
63004
+ workspace_uuid: workspace.workspace_uuid,
63005
+ workspace_name: workspace.workspace_name,
63006
+ efficiency: workspace.efficiency,
63007
+ action_count: workspace.action_count,
63008
+ predicted_output: workspace.predicted_output,
63009
+ avg_cycle_time: workspace.avg_cycle_time,
63010
+ ideal_cycle_time: workspace.ideal_cycle_time ?? null
63011
+ }))
63012
+ );
63013
+ if (prevSortedSignature !== nextSortedSignature) return false;
63014
+ const prevWorkspaceSignature = JSON.stringify(
63015
+ prevProps.workspaceData.map((workspace) => ({
63016
+ workspace_uuid: workspace.workspace_uuid,
63017
+ workspace_name: workspace.workspace_name,
63018
+ efficiency: workspace.efficiency,
63019
+ action_count: workspace.action_count,
63020
+ action_threshold: workspace.action_threshold,
63021
+ predicted_output: workspace.predicted_output,
63022
+ avg_cycle_time: workspace.avg_cycle_time,
63023
+ ideal_cycle_time: workspace.ideal_cycle_time ?? null
63024
+ }))
63025
+ );
63026
+ const nextWorkspaceSignature = JSON.stringify(
63027
+ nextProps.workspaceData.map((workspace) => ({
63028
+ workspace_uuid: workspace.workspace_uuid,
63029
+ workspace_name: workspace.workspace_name,
63030
+ efficiency: workspace.efficiency,
63031
+ action_count: workspace.action_count,
63032
+ action_threshold: workspace.action_threshold,
63033
+ predicted_output: workspace.predicted_output,
63034
+ avg_cycle_time: workspace.avg_cycle_time,
63035
+ ideal_cycle_time: workspace.ideal_cycle_time ?? null
63036
+ }))
63037
+ );
63038
+ if (prevWorkspaceSignature !== nextWorkspaceSignature) return false;
62543
63039
  if (prevProps.lineInfo.metrics.shift_start !== nextProps.lineInfo.metrics.shift_start) return false;
62544
63040
  if (prevProps.hourlyThreshold !== nextProps.hourlyThreshold) return false;
62545
63041
  if (prevProps.urlDate !== nextProps.urlDate || prevProps.urlShift !== nextProps.urlShift) return false;
@@ -62883,27 +63379,33 @@ var KPIDetailView = ({
62883
63379
  error: idleTimeError
62884
63380
  }), [idleTimeRawData, idleTimeChartData, idleTimeLoading, idleTimeError]);
62885
63381
  useEffect(() => {
62886
- if (activeTab === "monthly_history" && lineId) {
63382
+ if (activeTab === "monthly_history" && lineId && lineDetails) {
62887
63383
  if (!supabase || !dashboardConfig || !dashboardConfig.supabaseUrl || !dashboardConfig.supabaseKey) {
62888
63384
  console.error("Supabase client or required config not available in KPIsPage for monthly data");
62889
63385
  return;
62890
63386
  }
62891
63387
  setMonthlyDataLoading(true);
63388
+ const monthlyShiftIds = shiftConfig?.shifts?.map((s) => s.shiftId);
63389
+ const monthlyHistoryAssemblyMode = lineDetails.assembly === true && !isUptimeMode;
63390
+ const underperformingPromise = monthlyHistoryAssemblyMode ? dashboardService.getAssemblyMonthlyPoorestPerformers(lineId, currentMonth, currentYear, {
63391
+ startDate: isFullRange ? void 0 : range.startKey,
63392
+ endDate: isFullRange ? void 0 : range.endKey,
63393
+ shiftIds: monthlyShiftIds
63394
+ }) : dashboardService.getUnderperformingWorkspaces(
63395
+ lineId,
63396
+ currentMonth,
63397
+ currentYear,
63398
+ monthlyShiftIds,
63399
+ isFullRange ? void 0 : range.startKey,
63400
+ isFullRange ? void 0 : range.endKey
63401
+ );
62892
63402
  Promise.all([
62893
63403
  dashboardService.getLineMonthlyData(lineId, currentMonth, currentYear, {
62894
63404
  startDate: isFullRange ? void 0 : range.startKey,
62895
63405
  endDate: isFullRange ? void 0 : range.endKey,
62896
- shiftIds: shiftConfig?.shifts?.map((s) => s.shiftId)
63406
+ shiftIds: monthlyShiftIds
62897
63407
  }),
62898
- dashboardService.getUnderperformingWorkspaces(
62899
- lineId,
62900
- currentMonth,
62901
- currentYear,
62902
- shiftConfig?.shifts?.map((s) => s.shiftId),
62903
- // Pass dynamic shift IDs
62904
- isFullRange ? void 0 : range.startKey,
62905
- isFullRange ? void 0 : range.endKey
62906
- )
63408
+ underperformingPromise
62907
63409
  ]).then(([monthlyMetrics, underperformingData]) => {
62908
63410
  console.log("Fetched monthly metrics data:", monthlyMetrics);
62909
63411
  const dayDataMap = /* @__PURE__ */ new Map();
@@ -62967,11 +63469,17 @@ var KPIDetailView = ({
62967
63469
  const mapWorkspaces = (workspaces2) => (workspaces2 || []).map((ws) => ({
62968
63470
  workspace_name: ws.workspace_name || "Unknown Workspace",
62969
63471
  workspace_uuid: ws.workspace_uuid || ws.workspace_name || `unknown-${Math.random()}`,
62970
- avg_efficiency: ws.avg_efficiency || 0,
63472
+ avg_efficiency: ws.avg_efficiency ?? 0,
63473
+ avg_cycle_time: ws.avg_cycle_time ?? null,
63474
+ ideal_cycle_time: ws.ideal_cycle_time ?? null,
63475
+ cycle_ratio: ws.cycle_ratio ?? null,
63476
+ metric_mode: ws.metric_mode ?? "efficiency",
62971
63477
  last_5_days: (ws.last_5_days || []).map((day) => ({
62972
63478
  date: day.date,
62973
63479
  efficiency: day.efficiency ?? 0,
62974
- performance_score: day.performance_score
63480
+ performance_score: day.performance_score,
63481
+ avg_cycle_time: day.avg_cycle_time ?? null,
63482
+ ideal_cycle_time: day.ideal_cycle_time ?? null
62975
63483
  }))
62976
63484
  }));
62977
63485
  const mappedData = {};
@@ -62996,7 +63504,7 @@ var KPIDetailView = ({
62996
63504
  setMonthlyDataLoading(false);
62997
63505
  });
62998
63506
  }
62999
- }, [activeTab, lineId, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig, range.startKey, range.endKey, isFullRange, configuredTimezone, isUptimeMode, resolveShiftTimes]);
63507
+ }, [activeTab, lineId, lineDetails, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig, range.startKey, range.endKey, isFullRange, configuredTimezone, isUptimeMode, resolveShiftTimes]);
63000
63508
  const analysisMonthlyData = useMemo(() => {
63001
63509
  return filterDataByDateKeyRange(monthlyData, range);
63002
63510
  }, [monthlyData, range]);
@@ -63014,6 +63522,7 @@ var KPIDetailView = ({
63014
63522
  shift_id: metrics2.shift_id ?? 0,
63015
63523
  date: metrics2.date || getOperationalDate(timezone || "UTC"),
63016
63524
  monitoring_mode: lineDetails.monitoring_mode ?? void 0,
63525
+ assembly: lineDetails.assembly ?? null,
63017
63526
  metrics: {
63018
63527
  avg_efficiency: metrics2.avg_efficiency ?? 0,
63019
63528
  avg_cycle_time: metrics2.avg_cycle_time ?? 0,
@@ -63901,6 +64410,7 @@ var KPIDetailView = ({
63901
64410
  timezone: configuredTimezone,
63902
64411
  legend: efficiencyLegend,
63903
64412
  monitoringMode: resolvedMonitoringMode,
64413
+ lineAssembly: resolvedLineInfo?.assembly === true,
63904
64414
  shiftConfig,
63905
64415
  selectedShiftId,
63906
64416
  onShiftChange: setSelectedShiftId,
@@ -64105,18 +64615,18 @@ var LinesLeaderboard = ({
64105
64615
  isHistoricalDaily
64106
64616
  }) => {
64107
64617
  const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
64108
- const assignedLineIdSet = React142__default.useMemo(
64618
+ const assignedLineIdSet = React143__default.useMemo(
64109
64619
  () => new Set(assignedLineIds || []),
64110
64620
  [assignedLineIds]
64111
64621
  );
64112
- const canClickLine = React142__default.useCallback(
64622
+ const canClickLine = React143__default.useCallback(
64113
64623
  (lineId) => {
64114
64624
  if (!assignedLineIds) return true;
64115
64625
  return assignedLineIdSet.has(lineId);
64116
64626
  },
64117
64627
  [assignedLineIds, assignedLineIdSet]
64118
64628
  );
64119
- const handleTimeRangeChange = React142__default.useCallback((newRange) => {
64629
+ const handleTimeRangeChange = React143__default.useCallback((newRange) => {
64120
64630
  if (newRange === timeRange) return;
64121
64631
  trackCoreEvent("Leaderboard Time Range Changed", {
64122
64632
  from_range: timeRange,
@@ -64127,7 +64637,7 @@ var LinesLeaderboard = ({
64127
64637
  });
64128
64638
  setTimeRange(newRange);
64129
64639
  }, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
64130
- const handleLeaderboardLineClick = React142__default.useCallback((item, clickSource) => {
64640
+ const handleLeaderboardLineClick = React143__default.useCallback((item, clickSource) => {
64131
64641
  if (!canClickLine(item.line.id)) return;
64132
64642
  trackCoreEvent("Leaderboard Line Clicked", {
64133
64643
  line_id: item.line.id,
@@ -64141,8 +64651,8 @@ var LinesLeaderboard = ({
64141
64651
  });
64142
64652
  onLineClick(item.line);
64143
64653
  }, [canClickLine, onLineClick, timeRange]);
64144
- const viewLoadedTrackedRef = React142__default.useRef(null);
64145
- const leaderboardData = React142__default.useMemo(() => {
64654
+ const viewLoadedTrackedRef = React143__default.useRef(null);
64655
+ const leaderboardData = React143__default.useMemo(() => {
64146
64656
  const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
64147
64657
  const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
64148
64658
  return lines.map((line) => {
@@ -64173,7 +64683,7 @@ var LinesLeaderboard = ({
64173
64683
  isLoadingToday,
64174
64684
  isLoadingMonthly
64175
64685
  ]);
64176
- React142__default.useEffect(() => {
64686
+ React143__default.useEffect(() => {
64177
64687
  const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
64178
64688
  const trackingKey = `${timeRange}-${leaderboardData.length}`;
64179
64689
  if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
@@ -64199,7 +64709,7 @@ var LinesLeaderboard = ({
64199
64709
  const countdownFormat = timeRange === "monthly" ? "days" : "clock";
64200
64710
  const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift Ended";
64201
64711
  const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
64202
- const handleCountdownFinished = React142__default.useCallback(() => {
64712
+ const handleCountdownFinished = React143__default.useCallback(() => {
64203
64713
  trackCoreEvent("Leaderboard Countdown Finished", {
64204
64714
  countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
64205
64715
  time_range: timeRange,
@@ -64226,7 +64736,7 @@ var LinesLeaderboard = ({
64226
64736
  return "bg-white border-gray-100";
64227
64737
  }
64228
64738
  };
64229
- React142__default.useEffect(() => {
64739
+ React143__default.useEffect(() => {
64230
64740
  const style = document.createElement("style");
64231
64741
  style.innerHTML = `
64232
64742
  @keyframes float {
@@ -64413,7 +64923,7 @@ var LineCard = ({
64413
64923
  supervisors
64414
64924
  }) => {
64415
64925
  const isUptimeLine = (line.monitoring_mode ?? "output") === "uptime";
64416
- const isOnTrack = React142__default.useMemo(() => {
64926
+ const isOnTrack = React143__default.useMemo(() => {
64417
64927
  if (!kpis) return null;
64418
64928
  return isEfficiencyOnTrack(kpis.efficiency.value);
64419
64929
  }, [kpis]);
@@ -64611,46 +65121,46 @@ var KPIsOverviewView = ({
64611
65121
  const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
64612
65122
  const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
64613
65123
  const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
64614
- const scopedLineIds = React142__default.useMemo(
65124
+ const scopedLineIds = React143__default.useMemo(
64615
65125
  () => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
64616
65126
  [user?.access_scope?.line_ids]
64617
65127
  );
64618
65128
  const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
64619
65129
  const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
64620
65130
  const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
64621
- const resolvedAssignedLineIds = React142__default.useMemo(() => {
65131
+ const resolvedAssignedLineIds = React143__default.useMemo(() => {
64622
65132
  if (isSuperAdmin) return [];
64623
65133
  if (scopedLineIds.length > 0) return scopedLineIds;
64624
65134
  if (lineIds && lineIds.length > 0) return lineIds;
64625
65135
  if (isStrictLineScopedRole && hasCanonicalScope) return [];
64626
65136
  return [];
64627
65137
  }, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
64628
- const assignedLineIdSet = React142__default.useMemo(
65138
+ const assignedLineIdSet = React143__default.useMemo(
64629
65139
  () => new Set(resolvedAssignedLineIds),
64630
65140
  [resolvedAssignedLineIds]
64631
65141
  );
64632
- const metricsLineIds = React142__default.useMemo(() => {
65142
+ const metricsLineIds = React143__default.useMemo(() => {
64633
65143
  if (isSuperAdmin) {
64634
65144
  return lineIds ?? [];
64635
65145
  }
64636
65146
  return resolvedAssignedLineIds;
64637
65147
  }, [isSuperAdmin, lineIds, resolvedAssignedLineIds]);
64638
65148
  const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
64639
- const leaderboardLinesForView = React142__default.useMemo(() => {
65149
+ const leaderboardLinesForView = React143__default.useMemo(() => {
64640
65150
  const targetMode = viewType === "machine" ? "uptime" : "output";
64641
65151
  return leaderboardLines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
64642
65152
  }, [leaderboardLines, viewType]);
64643
- const linesForView = React142__default.useMemo(() => {
65153
+ const linesForView = React143__default.useMemo(() => {
64644
65154
  const targetMode = viewType === "machine" ? "uptime" : "output";
64645
65155
  return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
64646
65156
  }, [lines, viewType]);
64647
- const relevantLinesForMode = React142__default.useMemo(() => {
65157
+ const relevantLinesForMode = React143__default.useMemo(() => {
64648
65158
  if (activeTab === "leaderboard") {
64649
65159
  return leaderboardLines.length > 0 ? leaderboardLines : lines;
64650
65160
  }
64651
65161
  return lines;
64652
65162
  }, [activeTab, leaderboardLines, lines]);
64653
- const { hasUptime, hasOutput } = React142__default.useMemo(() => {
65163
+ const { hasUptime, hasOutput } = React143__default.useMemo(() => {
64654
65164
  let uptime = false;
64655
65165
  let output = false;
64656
65166
  for (const line of relevantLinesForMode) {
@@ -64675,14 +65185,14 @@ var KPIsOverviewView = ({
64675
65185
  const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
64676
65186
  const currentShiftDate = currentShiftDetails.date;
64677
65187
  const currentShiftId = currentShiftDetails.shiftId;
64678
- const activeFiltersCount = React142__default.useMemo(() => {
65188
+ const activeFiltersCount = React143__default.useMemo(() => {
64679
65189
  let count = 0;
64680
65190
  if (selectedLeaderboardShiftId !== currentShiftId) {
64681
65191
  count++;
64682
65192
  }
64683
65193
  return count;
64684
65194
  }, [selectedLeaderboardShiftId, currentShiftId]);
64685
- const clearFilters = React142__default.useCallback(() => {
65195
+ const clearFilters = React143__default.useCallback(() => {
64686
65196
  setSelectedLeaderboardShiftId(currentShiftId);
64687
65197
  }, [currentShiftId]);
64688
65198
  useEffect(() => {
@@ -64696,11 +65206,11 @@ var KPIsOverviewView = ({
64696
65206
  document.addEventListener("mousedown", handleClickOutside);
64697
65207
  return () => document.removeEventListener("mousedown", handleClickOutside);
64698
65208
  }, []);
64699
- const shiftEndDate = React142__default.useMemo(
65209
+ const shiftEndDate = React143__default.useMemo(
64700
65210
  () => getShiftEndDate(currentShiftDetails, configuredTimezone),
64701
65211
  [currentShiftDetails, configuredTimezone]
64702
65212
  );
64703
- const leaderboardShiftOptions = React142__default.useMemo(() => {
65213
+ const leaderboardShiftOptions = React143__default.useMemo(() => {
64704
65214
  if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
64705
65215
  return shiftConfig.shifts.map((shift) => ({
64706
65216
  id: shift.shiftId,
@@ -64780,15 +65290,15 @@ var KPIsOverviewView = ({
64780
65290
  lineId: factoryViewId,
64781
65291
  userAccessibleLineIds: metricsLineIds
64782
65292
  });
64783
- const defaultKPIs = React142__default.useMemo(() => createDefaultKPIs(), []);
64784
- const kpisByLineId = React142__default.useMemo(() => {
65293
+ const defaultKPIs = React143__default.useMemo(() => createDefaultKPIs(), []);
65294
+ const kpisByLineId = React143__default.useMemo(() => {
64785
65295
  const map = /* @__PURE__ */ new Map();
64786
65296
  lineMetrics.forEach((row) => {
64787
65297
  if (row?.line_id) map.set(row.line_id, buildKPIsFromLineMetricsRow(row));
64788
65298
  });
64789
65299
  return map;
64790
65300
  }, [lineMetrics]);
64791
- const supervisorLineIds = React142__default.useMemo(
65301
+ const supervisorLineIds = React143__default.useMemo(
64792
65302
  () => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
64793
65303
  [leaderboardLines, lines]
64794
65304
  );
@@ -65628,39 +66138,6 @@ var KPIsOverviewView = ({
65628
66138
  ] });
65629
66139
  };
65630
66140
  var KPIsOverviewView_default = KPIsOverviewView;
65631
- var toFiniteNumber = (value) => {
65632
- if (typeof value === "number" && Number.isFinite(value)) return value;
65633
- if (typeof value === "string" && value.trim() !== "") {
65634
- const parsed = Number(value);
65635
- return Number.isFinite(parsed) ? parsed : null;
65636
- }
65637
- return null;
65638
- };
65639
- var getCycleRatio = (workspace) => {
65640
- const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
65641
- const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
65642
- if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
65643
- return null;
65644
- }
65645
- return idealCycleTime / avgCycleTime;
65646
- };
65647
- var formatCycleTimeValue = (value) => {
65648
- const numericValue = toFiniteNumber(value);
65649
- if (numericValue === null || numericValue <= 0) return "--";
65650
- return `${numericValue.toFixed(1)}s`;
65651
- };
65652
- var CycleTimeComparison = memo$1(({
65653
- workspace
65654
- }) => {
65655
- const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
65656
- const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
65657
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
65658
- /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
65659
- /* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
65660
- /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
65661
- ] });
65662
- }, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
65663
- CycleTimeComparison.displayName = "CycleTimeComparison";
65664
66141
  var IsolatedTimer = memo$1(() => {
65665
66142
  return /* @__PURE__ */ jsx(ISTTimer_default, {});
65666
66143
  });
@@ -65912,7 +66389,7 @@ var LeaderboardDetailView = memo$1(({
65912
66389
  return () => document.removeEventListener("mousedown", handleClickOutside);
65913
66390
  }, []);
65914
66391
  const [isMobile, setIsMobile] = useState(false);
65915
- React142__default.useEffect(() => {
66392
+ React143__default.useEffect(() => {
65916
66393
  const checkMobile = () => setIsMobile(window.innerWidth < 640);
65917
66394
  checkMobile();
65918
66395
  window.addEventListener("resize", checkMobile);
@@ -66202,10 +66679,25 @@ var LeaderboardDetailView = memo$1(({
66202
66679
  setTodayLoading(true);
66203
66680
  setTodayError(null);
66204
66681
  try {
66205
- const entries = await fetchLeaderboardEntries({
66682
+ if (!supabase) {
66683
+ throw new Error("Supabase client not initialized");
66684
+ }
66685
+ if (!entityConfig.companyId) {
66686
+ throw new Error("Company ID is not configured");
66687
+ }
66688
+ const searchParams = new URLSearchParams({
66689
+ company_id: entityConfig.companyId,
66206
66690
  date: todayDate,
66207
- shiftId: todayShiftId
66691
+ shift_id: todayShiftId.toString()
66208
66692
  });
66693
+ if (configuredLineIds.length > 0) {
66694
+ searchParams.set("line_ids", configuredLineIds.join(","));
66695
+ }
66696
+ const metricsData = await fetchBackendJson(
66697
+ supabase,
66698
+ `/api/dashboard/metrics?${searchParams.toString()}`
66699
+ );
66700
+ const entries = metricsData.workspace_metrics || [];
66209
66701
  if (todayRequestKeyRef.current !== requestKey) {
66210
66702
  return;
66211
66703
  }
@@ -66222,7 +66714,15 @@ var LeaderboardDetailView = memo$1(({
66222
66714
  setTodayLoading(false);
66223
66715
  }
66224
66716
  }
66225
- }, [fetchLeaderboardEntries, mapEntriesToWorkspaces, todayDate, todayShiftId, lineKey]);
66717
+ }, [
66718
+ configuredLineIds,
66719
+ entityConfig.companyId,
66720
+ mapEntriesToWorkspaces,
66721
+ supabase,
66722
+ todayDate,
66723
+ todayShiftId,
66724
+ lineKey
66725
+ ]);
66226
66726
  const queueTodayLeaderboardRefresh = useCallback(() => {
66227
66727
  if (leaderboardUpdateQueuedRef.current) return;
66228
66728
  leaderboardUpdateQueuedRef.current = true;
@@ -68308,7 +68808,7 @@ var ShiftsView = ({
68308
68808
  ] })
68309
68809
  ] });
68310
68810
  };
68311
- var AuthenticatedShiftsView = withAuth(React142__default.memo(ShiftsView));
68811
+ var AuthenticatedShiftsView = withAuth(React143__default.memo(ShiftsView));
68312
68812
  var ShiftsView_default = ShiftsView;
68313
68813
 
68314
68814
  // src/views/TargetsView.utils.ts
@@ -70010,7 +70510,7 @@ var TargetsView = ({
70010
70510
  };
70011
70511
  var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
70012
70512
  var TargetsView_default = TargetsViewWithDisplayNames;
70013
- var AuthenticatedTargetsView = withAuth(React142__default.memo(TargetsViewWithDisplayNames));
70513
+ var AuthenticatedTargetsView = withAuth(React143__default.memo(TargetsViewWithDisplayNames));
70014
70514
  function useTimezone(options = {}) {
70015
70515
  const dashboardConfig = useDashboardConfig();
70016
70516
  const workspaceConfig = useWorkspaceConfig();
@@ -70237,7 +70737,20 @@ var WorkspaceDetailView = ({
70237
70737
  } = useCompanyFastSlowClipFiltersEnabled();
70238
70738
  const isClipsEnabled = dashboardConfig?.clipsConfig?.enabled ?? true;
70239
70739
  dashboardConfig?.supervisorConfig?.enabled || false;
70240
- const effectiveLineId = lineId || selectedLineId;
70740
+ const routedLineId = lineId || selectedLineId;
70741
+ const latestCachedDetailedMetrics = useMemo(() => {
70742
+ if (!workspaceId) {
70743
+ return null;
70744
+ }
70745
+ return workspaceMetricsStore.getLatestDetailed(workspaceId);
70746
+ }, [workspaceId]);
70747
+ const latestCachedOverviewMetrics = useMemo(() => {
70748
+ if (!workspaceId) {
70749
+ return null;
70750
+ }
70751
+ return workspaceMetricsStore.getLatestOverview(workspaceId);
70752
+ }, [workspaceId]);
70753
+ const effectiveLineId = routedLineId || latestCachedDetailedMetrics?.line_id || latestCachedOverviewMetrics?.line_id;
70241
70754
  const { shiftConfig, isLoading: isShiftConfigLoading, isFromDatabase: isShiftConfigFromDatabase } = useDynamicShiftConfig(effectiveLineId);
70242
70755
  const currentShiftDetails = useMemo(() => {
70243
70756
  if (isShiftConfigLoading || !shiftConfig) return null;
@@ -70514,8 +71027,9 @@ var WorkspaceDetailView = ({
70514
71027
  }, [cachedOverviewMetrics, shiftConfig?.shifts]);
70515
71028
  const authoritativeCycleMetrics = isHistoricView ? historicMetrics : liveMetrics;
70516
71029
  const workspace = authoritativeCycleMetrics || cachedDetailedMetrics || overviewFallback;
71030
+ const resolvedLineId = effectiveLineId || workspace?.line_id || cachedDetailedMetrics?.line_id || cachedOverviewMetrics?.line_id || overviewFallback?.line_id;
70517
71031
  const { timezone: cycleTimeTimezone } = useTimezone({
70518
- lineId: effectiveLineId || workspace?.line_id || void 0,
71032
+ lineId: resolvedLineId || void 0,
70519
71033
  workspaceId: workspaceId || void 0
70520
71034
  });
70521
71035
  const effectiveCycleTimeTimezone = cycleTimeTimezone || timezone;
@@ -70560,7 +71074,7 @@ var WorkspaceDetailView = ({
70560
71074
  const error = isHistoricView ? historicError : liveError;
70561
71075
  const monitoringMode = workspace?.monitoring_mode ?? "output";
70562
71076
  const isUptimeMode = monitoringMode === "uptime";
70563
- const idleTimeVlmEnabled = isIdleTimeVlmEnabled(effectiveLineId || workspace?.line_id);
71077
+ const idleTimeVlmEnabled = isIdleTimeVlmEnabled(resolvedLineId);
70564
71078
  useEffect(() => {
70565
71079
  if (!isClipsEnabled || !dashboardConfig?.s3Config || !workspaceId) {
70566
71080
  return;
@@ -70795,7 +71309,7 @@ var WorkspaceDetailView = ({
70795
71309
  const analysisMonthlyData = useMemo(() => {
70796
71310
  return filterDataByDateKeyRange(monthlyData, range);
70797
71311
  }, [monthlyData, range]);
70798
- const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
71312
+ const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", resolvedLineId);
70799
71313
  const workspaceCycleTimeEligibility = workspace ? {
70800
71314
  line_assembly_enabled: workspace.line_assembly_enabled,
70801
71315
  action_family: workspace.action_family,
@@ -70972,8 +71486,8 @@ var WorkspaceDetailView = ({
70972
71486
  params.set("rangeStart", range.startKey);
70973
71487
  params.set("rangeEnd", range.endKey);
70974
71488
  }
70975
- if (effectiveLineId) {
70976
- params.set("lineId", effectiveLineId);
71489
+ if (resolvedLineId) {
71490
+ params.set("lineId", resolvedLineId);
70977
71491
  }
70978
71492
  appendReturnUrl(params);
70979
71493
  onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
@@ -71002,8 +71516,8 @@ var WorkspaceDetailView = ({
71002
71516
  params.set("rangeStart", range.startKey);
71003
71517
  params.set("rangeEnd", range.endKey);
71004
71518
  }
71005
- if (effectiveLineId) {
71006
- params.set("lineId", effectiveLineId);
71519
+ if (resolvedLineId) {
71520
+ params.set("lineId", resolvedLineId);
71007
71521
  }
71008
71522
  appendReturnUrl(params);
71009
71523
  onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
@@ -71627,7 +72141,7 @@ var WorkspaceDetailView = ({
71627
72141
  month: selectedMonth,
71628
72142
  year: selectedYear,
71629
72143
  workspaceId,
71630
- lineId: effectiveLineId || workspace?.line_id,
72144
+ lineId: resolvedLineId,
71631
72145
  monitoringMode: workspace?.monitoring_mode,
71632
72146
  selectedShiftId: selectedShift,
71633
72147
  rangeStart,
@@ -71652,8 +72166,8 @@ var WorkspaceDetailView = ({
71652
72166
  params.set("rangeStart", range.startKey);
71653
72167
  params.set("rangeEnd", range.endKey);
71654
72168
  }
71655
- if (effectiveLineId) {
71656
- params.set("lineId", effectiveLineId);
72169
+ if (resolvedLineId) {
72170
+ params.set("lineId", resolvedLineId);
71657
72171
  }
71658
72172
  appendReturnUrl(params);
71659
72173
  onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
@@ -71681,7 +72195,7 @@ var WorkspaceDetailView = ({
71681
72195
  workspaceId,
71682
72196
  workspaceName: formattedWorkspaceName,
71683
72197
  date,
71684
- lineId: effectiveLineId,
72198
+ lineId: resolvedLineId,
71685
72199
  shift,
71686
72200
  totalOutput: workspace?.total_actions,
71687
72201
  workspaceMetrics: detailedWorkspaceMetrics || void 0,
@@ -73429,7 +73943,7 @@ function BottleneckClipsView({
73429
73943
  ) })
73430
73944
  ] }) });
73431
73945
  }
73432
- var AuthenticatedBottleneckClipsView = withAuth(React142__default.memo(BottleneckClipsView));
73946
+ var AuthenticatedBottleneckClipsView = withAuth(React143__default.memo(BottleneckClipsView));
73433
73947
  var BottleneckClipsView_default = BottleneckClipsView;
73434
73948
 
73435
73949
  // src/lib/services/ticketService.ts
@@ -73459,8 +73973,8 @@ var TicketService = class {
73459
73973
  return response;
73460
73974
  } catch (error) {
73461
73975
  lastError = error instanceof Error ? error : new Error(String(error));
73462
- const isRetryableError = lastError.message.includes("network") || lastError.message.includes("Failed to fetch") || lastError.message.includes("fetch failed") || lastError.message.includes("aborted") || lastError.message.includes("ENOTFOUND") || lastError.message.includes("ECONNREFUSED") || lastError.message.includes("503");
73463
- if (!isRetryableError || attempt === retries) {
73976
+ const isRetryableError2 = lastError.message.includes("network") || lastError.message.includes("Failed to fetch") || lastError.message.includes("fetch failed") || lastError.message.includes("aborted") || lastError.message.includes("ENOTFOUND") || lastError.message.includes("ECONNREFUSED") || lastError.message.includes("503");
73977
+ if (!isRetryableError2 || attempt === retries) {
73464
73978
  throw lastError;
73465
73979
  }
73466
73980
  const delay2 = 1e3 * Math.pow(2, attempt);
@@ -73475,69 +73989,78 @@ var TicketService = class {
73475
73989
  * Uses the user's JWT access token from Supabase session (NOT the anon key)
73476
73990
  */
73477
73991
  async fetchWithAuth(url, options = {}) {
73478
- if (!this.supabaseClient) {
73479
- throw new Error("Supabase client not initialized. Please provide a Supabase client to TicketService.");
73480
- }
73481
- const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
73482
- if (sessionError) {
73483
- console.error("Session error:", sessionError);
73484
- throw new Error("Failed to get authentication session. Please log in.");
73485
- }
73486
- if (!session) {
73487
- console.error("No session found. User must be logged in.");
73488
- throw new Error("User not authenticated. Please log in.");
73489
- }
73490
- if (!session.access_token) {
73491
- console.error("Session exists but no access_token found");
73492
- throw new Error("Invalid session. Please log in again.");
73493
- }
73494
- const token = session.access_token;
73495
- if (process.env.NODE_ENV === "development") {
73496
- console.log("[TicketService] Using JWT token (first 20 chars):", token.substring(0, 20) + "...");
73497
- console.log("[TicketService] Token is NOT the anon key - it is the user JWT from session.access_token");
73498
- }
73499
- const headers = {
73500
- "Content-Type": "application/json",
73501
- ...options.headers,
73502
- "Authorization": `Bearer ${token}`
73503
- // This is the USER's JWT, not the anon key
73504
- };
73505
- const response = await this.fetchWithRetry(url, {
73506
- ...options,
73507
- headers
73508
- });
73509
- if (response.status === 401) {
73510
- console.error("401 Unauthorized - Token expired or invalid");
73511
- throw new Error("Authentication failed. Token expired or invalid. Please log in again.");
73512
- }
73513
- if (response.status === 403) {
73514
- console.error("403 Forbidden - User does not have permission");
73515
- throw new Error("Access denied. You do not have permission to access this resource.");
73516
- }
73517
- if (response.status === 500) {
73518
- console.error("500 Internal Server Error - Backend error");
73519
- let errorDetail = "Internal server error occurred.";
73520
- try {
73521
- const errorData = await response.text();
73522
- console.error("Backend error details:", errorData);
73523
- errorDetail = errorData || errorDetail;
73524
- } catch (e) {
73992
+ try {
73993
+ if (!this.supabaseClient) {
73994
+ throw new Error("Supabase client not initialized. Please provide a Supabase client to TicketService.");
73525
73995
  }
73526
- throw new Error(`Backend error: ${errorDetail}`);
73527
- }
73528
- if (!response.ok) {
73529
- console.error(`HTTP ${response.status} - ${response.statusText}`);
73530
- let errorDetail = response.statusText;
73531
- try {
73532
- const errorData = await response.json();
73533
- if (errorData.detail) {
73534
- errorDetail = errorData.detail;
73996
+ const { data: { session }, error: sessionError } = await this.supabaseClient.auth.getSession();
73997
+ if (sessionError) {
73998
+ console.error("Session error:", sessionError);
73999
+ throw new Error("Failed to get authentication session. Please log in.");
74000
+ }
74001
+ if (!session) {
74002
+ console.error("No session found. User must be logged in.");
74003
+ throw new Error("User not authenticated. Please log in.");
74004
+ }
74005
+ if (!session.access_token) {
74006
+ console.error("Session exists but no access_token found");
74007
+ throw new Error("Invalid session. Please log in again.");
74008
+ }
74009
+ const token = session.access_token;
74010
+ if (process.env.NODE_ENV === "development") {
74011
+ console.log("[TicketService] Using JWT token (first 20 chars):", token.substring(0, 20) + "...");
74012
+ console.log("[TicketService] Token is NOT the anon key - it is the user JWT from session.access_token");
74013
+ }
74014
+ const headers = {
74015
+ "Content-Type": "application/json",
74016
+ ...options.headers,
74017
+ "Authorization": `Bearer ${token}`
74018
+ };
74019
+ const response = await this.fetchWithRetry(url, {
74020
+ ...options,
74021
+ headers
74022
+ });
74023
+ if (response.status === 401) {
74024
+ console.error("401 Unauthorized - Token expired or invalid");
74025
+ throw new Error("Authentication failed. Token expired or invalid. Please log in again.");
74026
+ }
74027
+ if (response.status === 403) {
74028
+ console.error("403 Forbidden - User does not have permission");
74029
+ throw new Error("Access denied. You do not have permission to access this resource.");
74030
+ }
74031
+ if (response.status === 500) {
74032
+ console.error("500 Internal Server Error - Backend error");
74033
+ let errorDetail = "Internal server error occurred.";
74034
+ try {
74035
+ const errorData = await response.text();
74036
+ console.error("Backend error details:", errorData);
74037
+ errorDetail = errorData || errorDetail;
74038
+ } catch (e) {
73535
74039
  }
73536
- } catch (e) {
74040
+ throw new Error(`Backend error: ${errorDetail}`);
74041
+ }
74042
+ if (!response.ok) {
74043
+ console.error(`HTTP ${response.status} - ${response.statusText}`);
74044
+ let errorDetail = response.statusText;
74045
+ try {
74046
+ const errorData = await response.json();
74047
+ if (errorData.detail) {
74048
+ errorDetail = errorData.detail;
74049
+ }
74050
+ } catch (e) {
74051
+ }
74052
+ throw new Error(`Request failed (${response.status}): ${errorDetail}`);
73537
74053
  }
73538
- throw new Error(`Request failed (${response.status}): ${errorDetail}`);
74054
+ return response;
74055
+ } catch (error) {
74056
+ captureHandledFrontendException(error, {
74057
+ surface: "ticket_service",
74058
+ url,
74059
+ method: options.method || "GET",
74060
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
74061
+ });
74062
+ throw error;
73539
74063
  }
73540
- return response;
73541
74064
  }
73542
74065
  /**
73543
74066
  * Get tickets with filters and pagination
@@ -74260,7 +74783,7 @@ Please ensure:
74260
74783
  )
74261
74784
  ] });
74262
74785
  }
74263
- var AuthenticatedTicketsView = withAuth(React142__default.memo(TicketsView));
74786
+ var AuthenticatedTicketsView = withAuth(React143__default.memo(TicketsView));
74264
74787
  var TicketsView_default = TicketsView;
74265
74788
 
74266
74789
  // src/lib/utils/improvementDisplay.ts
@@ -75231,7 +75754,7 @@ var ImprovementCenterView = () => {
75231
75754
  setSelectedMemberId("all");
75232
75755
  }
75233
75756
  }, [memberOptions, selectedMemberId]);
75234
- const getRecommendationDisplayMetadata = React142__default.useCallback((rec) => {
75757
+ const getRecommendationDisplayMetadata = React143__default.useCallback((rec) => {
75235
75758
  const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
75236
75759
  return getImprovementDisplayMetadata({
75237
75760
  location: rec.location,
@@ -75705,7 +76228,7 @@ var ThreadSidebar = ({
75705
76228
  ] }) })
75706
76229
  ] });
75707
76230
  };
75708
- var ProfilePicture = React142__default.memo(({
76231
+ var ProfilePicture = React143__default.memo(({
75709
76232
  alt = "Axel",
75710
76233
  className = "",
75711
76234
  size = "md",
@@ -78230,7 +78753,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
78230
78753
  ] }),
78231
78754
  /* @__PURE__ */ jsx("div", { className: "flex items-center justify-end flex-shrink-0 ml-4", children: /* @__PURE__ */ jsx(SectionPulse, { className: "h-6 w-20 rounded-full" }) })
78232
78755
  ] }, index)) });
78233
- var OperationsOverviewHeader = React142__default.memo(({
78756
+ var OperationsOverviewHeader = React143__default.memo(({
78234
78757
  dateRange,
78235
78758
  displayDateRange,
78236
78759
  trendMode,
@@ -78250,65 +78773,65 @@ var OperationsOverviewHeader = React142__default.memo(({
78250
78773
  bumpRenderCounter();
78251
78774
  const subtitleRange = displayDateRange || dateRange;
78252
78775
  const showLiveShiftMeta = isLiveScope && trendMode !== "all";
78253
- const liveShiftLabel = React142__default.useMemo(
78776
+ const liveShiftLabel = React143__default.useMemo(
78254
78777
  () => normalizeShiftLabel(liveShiftName, trendMode),
78255
78778
  [liveShiftName, trendMode]
78256
78779
  );
78257
- const liveShiftIcon = React142__default.useMemo(
78780
+ const liveShiftIcon = React143__default.useMemo(
78258
78781
  () => getShiftIcon(liveShiftName, trendMode),
78259
78782
  [liveShiftName, trendMode]
78260
78783
  );
78261
- const [isFilterOpen, setIsFilterOpen] = React142__default.useState(false);
78262
- const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React142__default.useState(false);
78263
- const filterRef = React142__default.useRef(null);
78264
- const filterButtonRef = React142__default.useRef(null);
78265
- const mobileFilterButtonRef = React142__default.useRef(null);
78266
- const linesDropdownRef = React142__default.useRef(null);
78267
- const mobileSubtitle = React142__default.useMemo(() => {
78784
+ const [isFilterOpen, setIsFilterOpen] = React143__default.useState(false);
78785
+ const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React143__default.useState(false);
78786
+ const filterRef = React143__default.useRef(null);
78787
+ const filterButtonRef = React143__default.useRef(null);
78788
+ const mobileFilterButtonRef = React143__default.useRef(null);
78789
+ const linesDropdownRef = React143__default.useRef(null);
78790
+ const mobileSubtitle = React143__default.useMemo(() => {
78268
78791
  if (subtitleRange.startKey === subtitleRange.endKey) {
78269
78792
  return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
78270
78793
  }
78271
78794
  return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
78272
78795
  }, [subtitleRange.endKey, subtitleRange.startKey]);
78273
- const desktopSubtitle = React142__default.useMemo(() => {
78796
+ const desktopSubtitle = React143__default.useMemo(() => {
78274
78797
  if (subtitleRange.startKey === subtitleRange.endKey) {
78275
78798
  return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
78276
78799
  }
78277
78800
  return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
78278
78801
  }, [subtitleRange.endKey, subtitleRange.startKey]);
78279
- const availableLineIds = React142__default.useMemo(
78802
+ const availableLineIds = React143__default.useMemo(
78280
78803
  () => lineOptions.map((line) => line.id),
78281
78804
  [lineOptions]
78282
78805
  );
78283
- const selectedLineIdSet = React142__default.useMemo(
78806
+ const selectedLineIdSet = React143__default.useMemo(
78284
78807
  () => new Set(selectedLineIds),
78285
78808
  [selectedLineIds]
78286
78809
  );
78287
- const isAllLinesSelected = React142__default.useMemo(() => {
78810
+ const isAllLinesSelected = React143__default.useMemo(() => {
78288
78811
  if (availableLineIds.length === 0) return true;
78289
78812
  return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
78290
78813
  }, [availableLineIds, selectedLineIdSet]);
78291
- const activeFilterCount = React142__default.useMemo(() => {
78814
+ const activeFilterCount = React143__default.useMemo(() => {
78292
78815
  let count = 0;
78293
78816
  if (trendMode !== "all") count += 1;
78294
78817
  if (selectedSupervisorId !== "all") count += 1;
78295
78818
  if (!isAllLinesSelected) count += 1;
78296
78819
  return count;
78297
78820
  }, [isAllLinesSelected, selectedSupervisorId, trendMode]);
78298
- const handleFilterToggle = React142__default.useCallback(() => {
78821
+ const handleFilterToggle = React143__default.useCallback(() => {
78299
78822
  trackCoreEvent("Operations Overview Filter Toggled", {
78300
78823
  action: !isFilterOpen ? "open" : "close"
78301
78824
  });
78302
78825
  setIsFilterOpen((previous) => !previous);
78303
78826
  }, [isFilterOpen]);
78304
- const handleTrendModeChange = React142__default.useCallback((event) => {
78827
+ const handleTrendModeChange = React143__default.useCallback((event) => {
78305
78828
  const nextMode = event.target.value;
78306
78829
  trackCoreEvent("Operations Overview Shift Filter Changed", {
78307
78830
  shift_mode: nextMode
78308
78831
  });
78309
78832
  onTrendModeChange(nextMode);
78310
78833
  }, [onTrendModeChange]);
78311
- const handleAllLinesToggle = React142__default.useCallback(() => {
78834
+ const handleAllLinesToggle = React143__default.useCallback(() => {
78312
78835
  trackCoreEvent("Operations Overview Line Filter Changed", {
78313
78836
  selected_line_ids: availableLineIds,
78314
78837
  selected_line_count: availableLineIds.length,
@@ -78316,7 +78839,7 @@ var OperationsOverviewHeader = React142__default.memo(({
78316
78839
  });
78317
78840
  onSelectedLineIdsChange(availableLineIds);
78318
78841
  }, [availableLineIds, onSelectedLineIdsChange]);
78319
- const handleSupervisorChange = React142__default.useCallback((event) => {
78842
+ const handleSupervisorChange = React143__default.useCallback((event) => {
78320
78843
  const supervisorId = event.target.value;
78321
78844
  const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
78322
78845
  trackCoreEvent("Operations Overview Supervisor Filter Changed", {
@@ -78327,7 +78850,7 @@ var OperationsOverviewHeader = React142__default.memo(({
78327
78850
  });
78328
78851
  onSelectedSupervisorIdChange(supervisorId);
78329
78852
  }, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
78330
- const handleLineToggle = React142__default.useCallback((lineId) => {
78853
+ const handleLineToggle = React143__default.useCallback((lineId) => {
78331
78854
  const current = new Set(selectedLineIds);
78332
78855
  if (current.has(lineId)) {
78333
78856
  if (current.size <= 1) return;
@@ -78343,13 +78866,13 @@ var OperationsOverviewHeader = React142__default.memo(({
78343
78866
  });
78344
78867
  onSelectedLineIdsChange(next);
78345
78868
  }, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
78346
- const handleClearAllFilters = React142__default.useCallback(() => {
78869
+ const handleClearAllFilters = React143__default.useCallback(() => {
78347
78870
  onTrendModeChange("all");
78348
78871
  onSelectedSupervisorIdChange("all");
78349
78872
  onSelectedLineIdsChange(availableLineIds);
78350
78873
  setIsFilterOpen(false);
78351
78874
  }, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
78352
- React142__default.useEffect(() => {
78875
+ React143__default.useEffect(() => {
78353
78876
  const handleClickOutside = (event) => {
78354
78877
  const target = event.target;
78355
78878
  if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
@@ -78588,12 +79111,12 @@ var OperationsOverviewHeader = React142__default.memo(({
78588
79111
  ] }) });
78589
79112
  });
78590
79113
  OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
78591
- var OverviewSummaryCards = React142__default.memo(({ store }) => {
79114
+ var OverviewSummaryCards = React143__default.memo(({ store }) => {
78592
79115
  bumpRenderCounter();
78593
79116
  const scope = useOperationsOverviewScope(store);
78594
79117
  const snapshot = useOperationsOverviewSnapshot(store);
78595
79118
  const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
78596
- const comparisonLabel = React142__default.useMemo(() => {
79119
+ const comparisonLabel = React143__default.useMemo(() => {
78597
79120
  return formatComparisonWindow({
78598
79121
  currentDayCount: scope.current_range?.day_count ?? null,
78599
79122
  previousDayCount: scope.previous_range?.day_count ?? null,
@@ -78606,27 +79129,27 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
78606
79129
  scope.previous_range?.day_count,
78607
79130
  scope.shift_mode
78608
79131
  ]);
78609
- const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React142__default.useState(false);
78610
- const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React142__default.useState(false);
78611
- const idleContributorsRef = React142__default.useRef(null);
78612
- const plantEfficiencyBadge = React142__default.useMemo(() => {
79132
+ const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React143__default.useState(false);
79133
+ const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React143__default.useState(false);
79134
+ const idleContributorsRef = React143__default.useRef(null);
79135
+ const plantEfficiencyBadge = React143__default.useMemo(() => {
78613
79136
  return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
78614
79137
  positiveIsGood: true,
78615
79138
  formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
78616
79139
  comparisonLabel
78617
79140
  });
78618
79141
  }, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
78619
- const idleBadge = React142__default.useMemo(() => {
79142
+ const idleBadge = React143__default.useMemo(() => {
78620
79143
  return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
78621
79144
  positiveIsGood: false,
78622
79145
  formatter: (value) => formatSignedIdleDuration(value),
78623
79146
  comparisonLabel
78624
79147
  });
78625
79148
  }, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
78626
- const canInspectIdleContributors = React142__default.useMemo(() => {
79149
+ const canInspectIdleContributors = React143__default.useMemo(() => {
78627
79150
  return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
78628
79151
  }, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
78629
- const idleTopContributors = React142__default.useMemo(() => {
79152
+ const idleTopContributors = React143__default.useMemo(() => {
78630
79153
  return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
78631
79154
  workspaceId: item.workspace_id || "",
78632
79155
  workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
@@ -78634,14 +79157,14 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
78634
79157
  avgIdleSeconds: toNumber3(item.avg_idle_seconds)
78635
79158
  })).slice(0, 5);
78636
79159
  }, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
78637
- const showIdleContributorLineNames = React142__default.useMemo(() => {
79160
+ const showIdleContributorLineNames = React143__default.useMemo(() => {
78638
79161
  return (scope.line_count ?? 0) > 1;
78639
79162
  }, [scope.line_count]);
78640
- const closeIdleContributors = React142__default.useCallback(() => {
79163
+ const closeIdleContributors = React143__default.useCallback(() => {
78641
79164
  setIsIdleContributorsOpen(false);
78642
79165
  setIsIdleContributorsPinned(false);
78643
79166
  }, []);
78644
- const handleIdleContributorsToggle = React142__default.useCallback(() => {
79167
+ const handleIdleContributorsToggle = React143__default.useCallback(() => {
78645
79168
  if (!canInspectIdleContributors) return;
78646
79169
  setIsIdleContributorsPinned((previous) => {
78647
79170
  const next = !previous;
@@ -78649,7 +79172,7 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
78649
79172
  return next;
78650
79173
  });
78651
79174
  }, [canInspectIdleContributors]);
78652
- const handleIdleContributorsKeyDown = React142__default.useCallback((event) => {
79175
+ const handleIdleContributorsKeyDown = React143__default.useCallback((event) => {
78653
79176
  if (!canInspectIdleContributors) return;
78654
79177
  if (event.key === "Enter" || event.key === " ") {
78655
79178
  event.preventDefault();
@@ -78661,11 +79184,11 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
78661
79184
  closeIdleContributors();
78662
79185
  }
78663
79186
  }, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
78664
- React142__default.useEffect(() => {
79187
+ React143__default.useEffect(() => {
78665
79188
  setIsIdleContributorsOpen(false);
78666
79189
  setIsIdleContributorsPinned(false);
78667
79190
  }, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
78668
- React142__default.useEffect(() => {
79191
+ React143__default.useEffect(() => {
78669
79192
  if (!isIdleContributorsOpen) return void 0;
78670
79193
  const handleClickOutside = (event) => {
78671
79194
  if (!isIdleContributorsPinned) return;
@@ -78803,7 +79326,7 @@ var OverviewSummaryCards = React142__default.memo(({ store }) => {
78803
79326
  ] });
78804
79327
  });
78805
79328
  OverviewSummaryCards.displayName = "OverviewSummaryCards";
78806
- var PoorestPerformersCard = React142__default.memo(({
79329
+ var PoorestPerformersCard = React143__default.memo(({
78807
79330
  store,
78808
79331
  supervisorsByLineId,
78809
79332
  onViewAll,
@@ -78812,9 +79335,9 @@ var PoorestPerformersCard = React142__default.memo(({
78812
79335
  bumpRenderCounter();
78813
79336
  const scope = useOperationsOverviewScope(store);
78814
79337
  const snapshot = useOperationsOverviewSnapshot(store);
78815
- const [poorestLineMode, setPoorestLineMode] = React142__default.useState("output");
79338
+ const [poorestLineMode, setPoorestLineMode] = React143__default.useState("output");
78816
79339
  const availableLineModes = scope.available_line_modes;
78817
- React142__default.useEffect(() => {
79340
+ React143__default.useEffect(() => {
78818
79341
  const hasOutput = !!availableLineModes?.has_output;
78819
79342
  const hasUptime = !!availableLineModes?.has_uptime;
78820
79343
  if (hasOutput && !hasUptime && poorestLineMode !== "output") {
@@ -78823,7 +79346,7 @@ var PoorestPerformersCard = React142__default.memo(({
78823
79346
  setPoorestLineMode("uptime");
78824
79347
  }
78825
79348
  }, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
78826
- const comparisonLabel = React142__default.useMemo(() => {
79349
+ const comparisonLabel = React143__default.useMemo(() => {
78827
79350
  return formatComparisonWindow({
78828
79351
  currentDayCount: scope.current_range?.day_count ?? null,
78829
79352
  previousDayCount: scope.previous_range?.day_count ?? null,
@@ -78837,7 +79360,7 @@ var PoorestPerformersCard = React142__default.memo(({
78837
79360
  scope.shift_mode
78838
79361
  ]);
78839
79362
  const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
78840
- const mergedPoorestLines = React142__default.useMemo(() => {
79363
+ const mergedPoorestLines = React143__default.useMemo(() => {
78841
79364
  const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
78842
79365
  return rows.slice(0, 3).map((line) => {
78843
79366
  const lineId = line.line_id || "";
@@ -78856,7 +79379,7 @@ var PoorestPerformersCard = React142__default.memo(({
78856
79379
  }, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
78857
79380
  const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
78858
79381
  const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
78859
- const handlePoorestLineModeChange = React142__default.useCallback((mode) => {
79382
+ const handlePoorestLineModeChange = React143__default.useCallback((mode) => {
78860
79383
  trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
78861
79384
  setPoorestLineMode(mode);
78862
79385
  }, []);
@@ -78942,14 +79465,14 @@ var PoorestPerformersCard = React142__default.memo(({
78942
79465
  ] });
78943
79466
  });
78944
79467
  PoorestPerformersCard.displayName = "PoorestPerformersCard";
78945
- var IdleBreakdownCard = React142__default.memo(({
79468
+ var IdleBreakdownCard = React143__default.memo(({
78946
79469
  store,
78947
79470
  scopedLineCount
78948
79471
  }) => {
78949
79472
  bumpRenderCounter();
78950
79473
  const idle = useOperationsOverviewIdle(store);
78951
79474
  const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
78952
- const idleBreakdown = React142__default.useMemo(() => {
79475
+ const idleBreakdown = React143__default.useMemo(() => {
78953
79476
  return idle.data.map((item) => ({
78954
79477
  name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
78955
79478
  reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
@@ -78968,7 +79491,7 @@ var IdleBreakdownCard = React142__default.memo(({
78968
79491
  }))
78969
79492
  })).filter((item) => item.value > 0);
78970
79493
  }, [idle.data]);
78971
- const showIdleModuleNotEnabledState = React142__default.useMemo(() => {
79494
+ const showIdleModuleNotEnabledState = React143__default.useMemo(() => {
78972
79495
  const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
78973
79496
  return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
78974
79497
  }, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
@@ -78989,7 +79512,7 @@ var IdleBreakdownCard = React142__default.memo(({
78989
79512
  ] });
78990
79513
  });
78991
79514
  IdleBreakdownCard.displayName = "IdleBreakdownCard";
78992
- var EfficiencyTrendCard = React142__default.memo(({
79515
+ var EfficiencyTrendCard = React143__default.memo(({
78993
79516
  store,
78994
79517
  dateRange,
78995
79518
  appTimezone,
@@ -78997,14 +79520,14 @@ var EfficiencyTrendCard = React142__default.memo(({
78997
79520
  }) => {
78998
79521
  bumpRenderCounter();
78999
79522
  const trend = useOperationsOverviewTrend(store);
79000
- const currentWeekRange = React142__default.useMemo(
79523
+ const currentWeekRange = React143__default.useMemo(
79001
79524
  () => getCurrentWeekToDateRange(appTimezone),
79002
79525
  [appTimezone]
79003
79526
  );
79004
79527
  const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
79005
79528
  const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
79006
79529
  const isHourlyTrend = trend.data.granularity === "hour";
79007
- const trendData = React142__default.useMemo(() => {
79530
+ const trendData = React143__default.useMemo(() => {
79008
79531
  if (isHourlyTrend) {
79009
79532
  return (trend.data.points || []).map((point, index) => ({
79010
79533
  name: (() => {
@@ -79076,13 +79599,13 @@ var EfficiencyTrendCard = React142__default.memo(({
79076
79599
  };
79077
79600
  });
79078
79601
  }, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
79079
- const trendTooltipLabelFormatter = React142__default.useCallback((label, payload) => {
79602
+ const trendTooltipLabelFormatter = React143__default.useCallback((label, payload) => {
79080
79603
  if (isHourlyTrend) return label;
79081
79604
  const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
79082
79605
  if (!dayOfWeek || typeof label !== "string") return label;
79083
79606
  return `${label} (${dayOfWeek})`;
79084
79607
  }, [isHourlyTrend]);
79085
- const trendXAxisTickFormatter = React142__default.useCallback((value, index) => {
79608
+ const trendXAxisTickFormatter = React143__default.useCallback((value, index) => {
79086
79609
  if (!isHourlyTrend) {
79087
79610
  return typeof value === "string" ? value : String(value ?? "");
79088
79611
  }
@@ -79109,7 +79632,7 @@ var EfficiencyTrendCard = React142__default.memo(({
79109
79632
  ] });
79110
79633
  });
79111
79634
  EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
79112
- var TopImprovementsCard = React142__default.memo(({
79635
+ var TopImprovementsCard = React143__default.memo(({
79113
79636
  store,
79114
79637
  supervisorsByLineId,
79115
79638
  onViewAll,
@@ -79118,7 +79641,7 @@ var TopImprovementsCard = React142__default.memo(({
79118
79641
  bumpRenderCounter();
79119
79642
  const improvements = useOperationsOverviewImprovements(store);
79120
79643
  const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
79121
- const displayImprovements = React142__default.useMemo(() => {
79644
+ const displayImprovements = React143__default.useMemo(() => {
79122
79645
  return improvements.data.map((item) => {
79123
79646
  const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
79124
79647
  return {
@@ -79191,7 +79714,7 @@ var debugRefreshLog = (message, payload) => {
79191
79714
  }
79192
79715
  console.log(`[OperationsOverviewRefresh] ${message}`);
79193
79716
  };
79194
- var isAbortError = (error) => {
79717
+ var isAbortError2 = (error) => {
79195
79718
  return error instanceof DOMException && error.name === "AbortError";
79196
79719
  };
79197
79720
  var toNumber4 = (value) => {
@@ -79246,33 +79769,33 @@ var useOperationsOverviewRefresh = ({
79246
79769
  isLiveScope,
79247
79770
  enabled = true
79248
79771
  }) => {
79249
- const lineIdsKey = React142__default.useMemo(() => lineIds.join(","), [lineIds]);
79250
- const scopeSignature = React142__default.useMemo(
79772
+ const lineIdsKey = React143__default.useMemo(() => lineIds.join(","), [lineIds]);
79773
+ const scopeSignature = React143__default.useMemo(
79251
79774
  () => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
79252
79775
  [companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
79253
79776
  );
79254
- const controllersRef = React142__default.useRef({});
79255
- const requestIdsRef = React142__default.useRef({
79777
+ const controllersRef = React143__default.useRef({});
79778
+ const requestIdsRef = React143__default.useRef({
79256
79779
  snapshot: 0,
79257
79780
  trend: 0,
79258
79781
  idle: 0,
79259
79782
  improvements: 0
79260
79783
  });
79261
- const intervalRef = React142__default.useRef(null);
79262
- const isPageActiveRef = React142__default.useRef(true);
79263
- const lastResumeRefreshAtRef = React142__default.useRef(0);
79264
- const abortAll = React142__default.useCallback(() => {
79784
+ const intervalRef = React143__default.useRef(null);
79785
+ const isPageActiveRef = React143__default.useRef(true);
79786
+ const lastResumeRefreshAtRef = React143__default.useRef(0);
79787
+ const abortAll = React143__default.useCallback(() => {
79265
79788
  Object.values(controllersRef.current).forEach((controller) => {
79266
79789
  controller?.abort();
79267
79790
  });
79268
79791
  controllersRef.current = {};
79269
79792
  }, []);
79270
- React142__default.useEffect(() => {
79793
+ React143__default.useEffect(() => {
79271
79794
  return () => {
79272
79795
  abortAll();
79273
79796
  };
79274
79797
  }, [abortAll]);
79275
- const getIsPageActive = React142__default.useCallback(() => {
79798
+ const getIsPageActive = React143__default.useCallback(() => {
79276
79799
  if (typeof document === "undefined") {
79277
79800
  return true;
79278
79801
  }
@@ -79280,7 +79803,7 @@ var useOperationsOverviewRefresh = ({
79280
79803
  const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
79281
79804
  return isVisible && hasFocus;
79282
79805
  }, []);
79283
- const stopPolling = React142__default.useCallback((reason) => {
79806
+ const stopPolling = React143__default.useCallback((reason) => {
79284
79807
  if (intervalRef.current === null) {
79285
79808
  return;
79286
79809
  }
@@ -79288,7 +79811,7 @@ var useOperationsOverviewRefresh = ({
79288
79811
  intervalRef.current = null;
79289
79812
  debugRefreshLog("poll stopped", { reason });
79290
79813
  }, []);
79291
- const runRefresh = React142__default.useCallback(
79814
+ const runRefresh = React143__default.useCallback(
79292
79815
  async (section, begin, onSuccess, onError, request, reason) => {
79293
79816
  if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
79294
79817
  const requestId = requestIdsRef.current[section] + 1;
@@ -79304,7 +79827,7 @@ var useOperationsOverviewRefresh = ({
79304
79827
  }
79305
79828
  onSuccess(response, Date.now(), reason === "live_refresh" ? "transition" : "default");
79306
79829
  } catch (error) {
79307
- if (controller.signal.aborted || requestIdsRef.current[section] !== requestId || isAbortError(error)) {
79830
+ if (controller.signal.aborted || requestIdsRef.current[section] !== requestId || isAbortError2(error)) {
79308
79831
  return;
79309
79832
  }
79310
79833
  onError(error instanceof Error ? error.message : `Failed to refresh ${section}`);
@@ -79312,7 +79835,7 @@ var useOperationsOverviewRefresh = ({
79312
79835
  },
79313
79836
  [companyId, enabled, lineIds.length, supabase]
79314
79837
  );
79315
- const refreshSnapshot = React142__default.useCallback(
79838
+ const refreshSnapshot = React143__default.useCallback(
79316
79839
  async (reason) => {
79317
79840
  await runRefresh(
79318
79841
  "snapshot",
@@ -79344,7 +79867,7 @@ var useOperationsOverviewRefresh = ({
79344
79867
  },
79345
79868
  [companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
79346
79869
  );
79347
- const refreshTrend = React142__default.useCallback(
79870
+ const refreshTrend = React143__default.useCallback(
79348
79871
  async (reason) => {
79349
79872
  await runRefresh(
79350
79873
  "trend",
@@ -79373,7 +79896,7 @@ var useOperationsOverviewRefresh = ({
79373
79896
  },
79374
79897
  [companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
79375
79898
  );
79376
- const refreshIdle = React142__default.useCallback(
79899
+ const refreshIdle = React143__default.useCallback(
79377
79900
  async (reason) => {
79378
79901
  await runRefresh(
79379
79902
  "idle",
@@ -79402,7 +79925,7 @@ var useOperationsOverviewRefresh = ({
79402
79925
  },
79403
79926
  [companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
79404
79927
  );
79405
- const refreshImprovements = React142__default.useCallback(
79928
+ const refreshImprovements = React143__default.useCallback(
79406
79929
  async (reason) => {
79407
79930
  await runRefresh(
79408
79931
  "improvements",
@@ -79432,7 +79955,7 @@ var useOperationsOverviewRefresh = ({
79432
79955
  },
79433
79956
  [companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
79434
79957
  );
79435
- const refreshAll = React142__default.useCallback(
79958
+ const refreshAll = React143__default.useCallback(
79436
79959
  async (reason) => {
79437
79960
  await Promise.allSettled([
79438
79961
  refreshSnapshot(reason),
@@ -79443,7 +79966,7 @@ var useOperationsOverviewRefresh = ({
79443
79966
  },
79444
79967
  [refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
79445
79968
  );
79446
- const startPolling = React142__default.useCallback((reason) => {
79969
+ const startPolling = React143__default.useCallback((reason) => {
79447
79970
  if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
79448
79971
  return;
79449
79972
  }
@@ -79464,7 +79987,7 @@ var useOperationsOverviewRefresh = ({
79464
79987
  }, LIVE_REFRESH_INTERVAL_MS);
79465
79988
  debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
79466
79989
  }, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
79467
- const refreshFromResume = React142__default.useCallback((reason) => {
79990
+ const refreshFromResume = React143__default.useCallback((reason) => {
79468
79991
  const now4 = Date.now();
79469
79992
  if (now4 - lastResumeRefreshAtRef.current < 1e3) {
79470
79993
  debugRefreshLog("resume refresh suppressed", { reason });
@@ -79479,7 +80002,7 @@ var useOperationsOverviewRefresh = ({
79479
80002
  }
79480
80003
  });
79481
80004
  }, [refreshAll, startPolling, stopPolling]);
79482
- React142__default.useEffect(() => {
80005
+ React143__default.useEffect(() => {
79483
80006
  if (!enabled) {
79484
80007
  stopPolling("disabled");
79485
80008
  abortAll();
@@ -79494,7 +80017,7 @@ var useOperationsOverviewRefresh = ({
79494
80017
  }
79495
80018
  void refreshAll("scope_change");
79496
80019
  }, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
79497
- React142__default.useEffect(() => {
80020
+ React143__default.useEffect(() => {
79498
80021
  if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
79499
80022
  isPageActiveRef.current = false;
79500
80023
  stopPolling("live_scope_disabled");
@@ -79669,55 +80192,55 @@ var PlantHeadView = () => {
79669
80192
  const { accessibleLineIds } = useUserLineAccess();
79670
80193
  const mobileMenuContext = useMobileMenu();
79671
80194
  useHideMobileHeader(!!mobileMenuContext);
79672
- const storeRef = React142__default.useRef(createOperationsOverviewStore());
80195
+ const storeRef = React143__default.useRef(createOperationsOverviewStore());
79673
80196
  const store = storeRef.current;
79674
- const fallbackOperationalDate = React142__default.useMemo(
80197
+ const fallbackOperationalDate = React143__default.useMemo(
79675
80198
  () => getOperationalDate(appTimezone),
79676
80199
  [appTimezone]
79677
80200
  );
79678
- const [dateRange, setDateRange] = React142__default.useState(() => ({
80201
+ const [dateRange, setDateRange] = React143__default.useState(() => ({
79679
80202
  startKey: fallbackOperationalDate,
79680
80203
  endKey: fallbackOperationalDate
79681
80204
  }));
79682
- const [usesThisWeekComparison, setUsesThisWeekComparison] = React142__default.useState(false);
79683
- const [trendMode, setTrendMode] = React142__default.useState("all");
79684
- const [selectedSupervisorId, setSelectedSupervisorId] = React142__default.useState("all");
79685
- const [selectedLineIds, setSelectedLineIds] = React142__default.useState([]);
79686
- const [isInitialScopeReady, setIsInitialScopeReady] = React142__default.useState(false);
79687
- const [shiftResolutionTick, setShiftResolutionTick] = React142__default.useState(0);
79688
- const hasAutoInitializedScopeRef = React142__default.useRef(false);
79689
- const hasUserAdjustedScopeRef = React142__default.useRef(false);
79690
- React142__default.useEffect(() => {
80205
+ const [usesThisWeekComparison, setUsesThisWeekComparison] = React143__default.useState(false);
80206
+ const [trendMode, setTrendMode] = React143__default.useState("all");
80207
+ const [selectedSupervisorId, setSelectedSupervisorId] = React143__default.useState("all");
80208
+ const [selectedLineIds, setSelectedLineIds] = React143__default.useState([]);
80209
+ const [isInitialScopeReady, setIsInitialScopeReady] = React143__default.useState(false);
80210
+ const [shiftResolutionTick, setShiftResolutionTick] = React143__default.useState(0);
80211
+ const hasAutoInitializedScopeRef = React143__default.useRef(false);
80212
+ const hasUserAdjustedScopeRef = React143__default.useRef(false);
80213
+ React143__default.useEffect(() => {
79691
80214
  trackCorePageView("Operations Overview", {
79692
80215
  dashboard_surface: "operations_overview"
79693
80216
  });
79694
80217
  }, []);
79695
- const currentWeekRange = React142__default.useMemo(
80218
+ const currentWeekRange = React143__default.useMemo(
79696
80219
  () => getCurrentWeekToDateRange(appTimezone),
79697
80220
  [appTimezone]
79698
80221
  );
79699
- const currentWeekDisplayRange = React142__default.useMemo(
80222
+ const currentWeekDisplayRange = React143__default.useMemo(
79700
80223
  () => getCurrentWeekFullRange(appTimezone),
79701
80224
  [appTimezone]
79702
80225
  );
79703
80226
  const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
79704
- const headerDateRange = React142__default.useMemo(() => {
80227
+ const headerDateRange = React143__default.useMemo(() => {
79705
80228
  if (usesThisWeekComparison && isCurrentWeekToDateRange) {
79706
80229
  return currentWeekDisplayRange;
79707
80230
  }
79708
80231
  return dateRange;
79709
80232
  }, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
79710
- const normalizedLineIds = React142__default.useMemo(
80233
+ const normalizedLineIds = React143__default.useMemo(
79711
80234
  () => Array.from(new Set(
79712
80235
  (accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
79713
80236
  )).sort(),
79714
80237
  [accessibleLineIds, factoryViewId]
79715
80238
  );
79716
- const lineIdsKey = React142__default.useMemo(
80239
+ const lineIdsKey = React143__default.useMemo(
79717
80240
  () => normalizedLineIds.join(","),
79718
80241
  [normalizedLineIds]
79719
80242
  );
79720
- const lineOptions = React142__default.useMemo(
80243
+ const lineOptions = React143__default.useMemo(
79721
80244
  () => normalizedLineIds.map((lineId) => ({
79722
80245
  id: lineId,
79723
80246
  name: getLineDisplayName(entityConfig, lineId)
@@ -79729,7 +80252,7 @@ var PlantHeadView = () => {
79729
80252
  companyId: entityConfig.companyId,
79730
80253
  useBackend: true
79731
80254
  });
79732
- const supervisorOptions = React142__default.useMemo(
80255
+ const supervisorOptions = React143__default.useMemo(
79733
80256
  () => {
79734
80257
  const optionsById = /* @__PURE__ */ new Map();
79735
80258
  normalizedLineIds.forEach((lineId) => {
@@ -79755,7 +80278,7 @@ var PlantHeadView = () => {
79755
80278
  },
79756
80279
  [normalizedLineIds, supervisorsByLineId]
79757
80280
  );
79758
- React142__default.useEffect(() => {
80281
+ React143__default.useEffect(() => {
79759
80282
  if (selectedSupervisorId === "all") {
79760
80283
  setSelectedLineIds((previous) => {
79761
80284
  if (normalizedLineIds.length === 0) {
@@ -79781,7 +80304,7 @@ var PlantHeadView = () => {
79781
80304
  const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
79782
80305
  setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
79783
80306
  }, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
79784
- const scopedLineIds = React142__default.useMemo(
80307
+ const scopedLineIds = React143__default.useMemo(
79785
80308
  () => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
79786
80309
  [normalizedLineIds, selectedLineIds]
79787
80310
  );
@@ -79789,7 +80312,7 @@ var PlantHeadView = () => {
79789
80312
  shiftConfigMap,
79790
80313
  isLoading: isShiftConfigLoading
79791
80314
  } = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
79792
- React142__default.useEffect(() => {
80315
+ React143__default.useEffect(() => {
79793
80316
  if (scopedLineIds.length === 0 || isShiftConfigLoading) {
79794
80317
  return;
79795
80318
  }
@@ -79800,11 +80323,11 @@ var PlantHeadView = () => {
79800
80323
  clearInterval(intervalId);
79801
80324
  };
79802
80325
  }, [isShiftConfigLoading, scopedLineIds.length]);
79803
- const shiftResolutionNow = React142__default.useMemo(
80326
+ const shiftResolutionNow = React143__default.useMemo(
79804
80327
  () => /* @__PURE__ */ new Date(),
79805
80328
  [shiftResolutionTick]
79806
80329
  );
79807
- const earliestDayShiftStartTime = React142__default.useMemo(() => {
80330
+ const earliestDayShiftStartTime = React143__default.useMemo(() => {
79808
80331
  const candidateStarts = [];
79809
80332
  scopedLineIds.forEach((lineId) => {
79810
80333
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
@@ -79840,11 +80363,11 @@ var PlantHeadView = () => {
79840
80363
  const minutes = earliestMinutes % 60;
79841
80364
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
79842
80365
  }, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
79843
- const resolvedOperationalToday = React142__default.useMemo(
80366
+ const resolvedOperationalToday = React143__default.useMemo(
79844
80367
  () => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
79845
80368
  [appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
79846
80369
  );
79847
- const activeLineShiftStates = React142__default.useMemo(() => {
80370
+ const activeLineShiftStates = React143__default.useMemo(() => {
79848
80371
  return scopedLineIds.flatMap((lineId) => {
79849
80372
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
79850
80373
  const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
@@ -79871,16 +80394,16 @@ var PlantHeadView = () => {
79871
80394
  }];
79872
80395
  });
79873
80396
  }, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
79874
- const hasActiveDayShiftLine = React142__default.useMemo(
80397
+ const hasActiveDayShiftLine = React143__default.useMemo(
79875
80398
  () => activeLineShiftStates.some((shift) => shift.trendMode === "day" && shift.date === resolvedOperationalToday),
79876
80399
  [activeLineShiftStates, resolvedOperationalToday]
79877
80400
  );
79878
- const hasActiveNightShiftLine = React142__default.useMemo(
80401
+ const hasActiveNightShiftLine = React143__default.useMemo(
79879
80402
  () => activeLineShiftStates.some((shift) => shift.trendMode === "night" && shift.date === resolvedOperationalToday),
79880
80403
  [activeLineShiftStates, resolvedOperationalToday]
79881
80404
  );
79882
80405
  const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
79883
- const hourlyWindowStartTime = React142__default.useMemo(() => {
80406
+ const hourlyWindowStartTime = React143__default.useMemo(() => {
79884
80407
  if (scopedLineIds.length === 0) {
79885
80408
  return null;
79886
80409
  }
@@ -79931,12 +80454,12 @@ var PlantHeadView = () => {
79931
80454
  const minutes = earliestMinutes % 60;
79932
80455
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
79933
80456
  }, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
79934
- const isShiftScopeResolved = React142__default.useMemo(
80457
+ const isShiftScopeResolved = React143__default.useMemo(
79935
80458
  () => !isShiftConfigLoading,
79936
80459
  [isShiftConfigLoading]
79937
80460
  );
79938
- const initializedTimezoneRef = React142__default.useRef(appTimezone);
79939
- React142__default.useEffect(() => {
80461
+ const initializedTimezoneRef = React143__default.useRef(appTimezone);
80462
+ React143__default.useEffect(() => {
79940
80463
  if (initializedTimezoneRef.current === appTimezone) return;
79941
80464
  hasAutoInitializedScopeRef.current = false;
79942
80465
  hasUserAdjustedScopeRef.current = false;
@@ -79949,7 +80472,7 @@ var PlantHeadView = () => {
79949
80472
  setIsInitialScopeReady(false);
79950
80473
  initializedTimezoneRef.current = appTimezone;
79951
80474
  }, [appTimezone, fallbackOperationalDate]);
79952
- React142__default.useEffect(() => {
80475
+ React143__default.useEffect(() => {
79953
80476
  if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
79954
80477
  return;
79955
80478
  }
@@ -79974,7 +80497,7 @@ var PlantHeadView = () => {
79974
80497
  hasAutoInitializedScopeRef.current = true;
79975
80498
  setIsInitialScopeReady(true);
79976
80499
  }, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
79977
- const handleDateRangeChange = React142__default.useCallback((range, meta) => {
80500
+ const handleDateRangeChange = React143__default.useCallback((range, meta) => {
79978
80501
  hasUserAdjustedScopeRef.current = true;
79979
80502
  setIsInitialScopeReady(true);
79980
80503
  trackCoreEvent("Operations Overview Date Range Changed", {
@@ -79992,12 +80515,12 @@ var PlantHeadView = () => {
79992
80515
  return previous;
79993
80516
  });
79994
80517
  }, []);
79995
- const handleTrendModeChange = React142__default.useCallback((mode) => {
80518
+ const handleTrendModeChange = React143__default.useCallback((mode) => {
79996
80519
  hasUserAdjustedScopeRef.current = true;
79997
80520
  setIsInitialScopeReady(true);
79998
80521
  setTrendMode(mode);
79999
80522
  }, []);
80000
- const handleSelectedLineIdsChange = React142__default.useCallback((lineIds) => {
80523
+ const handleSelectedLineIdsChange = React143__default.useCallback((lineIds) => {
80001
80524
  setSelectedSupervisorId("all");
80002
80525
  if (normalizedLineIds.length === 0) {
80003
80526
  setSelectedLineIds([]);
@@ -80008,10 +80531,10 @@ var PlantHeadView = () => {
80008
80531
  const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
80009
80532
  setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
80010
80533
  }, [normalizedLineIds]);
80011
- const handleSelectedSupervisorIdChange = React142__default.useCallback((supervisorId) => {
80534
+ const handleSelectedSupervisorIdChange = React143__default.useCallback((supervisorId) => {
80012
80535
  setSelectedSupervisorId(supervisorId);
80013
80536
  }, []);
80014
- const buildLineMonthlyHistoryUrl = React142__default.useCallback((lineId) => {
80537
+ const buildLineMonthlyHistoryUrl = React143__default.useCallback((lineId) => {
80015
80538
  const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
80016
80539
  const params = new URLSearchParams();
80017
80540
  params.set("tab", "monthly_history");
@@ -80021,15 +80544,15 @@ var PlantHeadView = () => {
80021
80544
  params.set("rangeEnd", dateRange.endKey);
80022
80545
  return `/kpis/${lineId}?${params.toString()}`;
80023
80546
  }, [dateRange.endKey, dateRange.startKey]);
80024
- const handleViewAllPoorestPerformers = React142__default.useCallback(() => {
80547
+ const handleViewAllPoorestPerformers = React143__default.useCallback(() => {
80025
80548
  trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
80026
80549
  navigate("/kpis?tab=leaderboard");
80027
80550
  }, [navigate]);
80028
- const handleViewAllImprovements = React142__default.useCallback(() => {
80551
+ const handleViewAllImprovements = React143__default.useCallback(() => {
80029
80552
  trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
80030
80553
  navigate("/improvement-center");
80031
80554
  }, [navigate]);
80032
- const handleOpenImprovement = React142__default.useCallback((item) => {
80555
+ const handleOpenImprovement = React143__default.useCallback((item) => {
80033
80556
  trackCoreEvent("Operations Overview Improvement Clicked", {
80034
80557
  issue_id: item.issueId,
80035
80558
  issue_number: item.issueNumber,
@@ -80040,13 +80563,13 @@ var PlantHeadView = () => {
80040
80563
  });
80041
80564
  navigate(`/improvement-center?${params.toString()}`);
80042
80565
  }, [navigate]);
80043
- const comparisonStrategy = React142__default.useMemo(() => {
80566
+ const comparisonStrategy = React143__default.useMemo(() => {
80044
80567
  if (usesThisWeekComparison && isCurrentWeekToDateRange) {
80045
80568
  return "previous_full_week";
80046
80569
  }
80047
80570
  return void 0;
80048
80571
  }, [isCurrentWeekToDateRange, usesThisWeekComparison]);
80049
- const effectiveDateRange = React142__default.useMemo(() => {
80572
+ const effectiveDateRange = React143__default.useMemo(() => {
80050
80573
  if (isInitialScopeReady) {
80051
80574
  return dateRange;
80052
80575
  }
@@ -80056,21 +80579,21 @@ var PlantHeadView = () => {
80056
80579
  endKey: nextStartKey
80057
80580
  };
80058
80581
  }, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
80059
- const effectiveTrendMode = React142__default.useMemo(
80582
+ const effectiveTrendMode = React143__default.useMemo(
80060
80583
  () => resolvedTrendMode,
80061
80584
  [resolvedTrendMode]
80062
80585
  );
80063
- const hourlyLabelStartTime = React142__default.useMemo(() => {
80586
+ const hourlyLabelStartTime = React143__default.useMemo(() => {
80064
80587
  if (scopedLineIds.length === 0) {
80065
80588
  return null;
80066
80589
  }
80067
80590
  return hourlyWindowStartTime;
80068
80591
  }, [hourlyWindowStartTime, scopedLineIds.length]);
80069
- const isSingleDayScope = React142__default.useMemo(
80592
+ const isSingleDayScope = React143__default.useMemo(
80070
80593
  () => effectiveDateRange.startKey === effectiveDateRange.endKey,
80071
80594
  [effectiveDateRange.endKey, effectiveDateRange.startKey]
80072
80595
  );
80073
- const isLiveScope = React142__default.useMemo(
80596
+ const isLiveScope = React143__default.useMemo(
80074
80597
  () => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && (effectiveTrendMode === "all" || effectiveTrendMode === "day" && hasActiveDayShiftLine || effectiveTrendMode === "night" && hasActiveNightShiftLine),
80075
80598
  [
80076
80599
  effectiveDateRange.startKey,
@@ -80081,7 +80604,7 @@ var PlantHeadView = () => {
80081
80604
  resolvedOperationalToday
80082
80605
  ]
80083
80606
  );
80084
- const handleOpenLineDetails = React142__default.useCallback((lineId, lineName) => {
80607
+ const handleOpenLineDetails = React143__default.useCallback((lineId, lineName) => {
80085
80608
  trackCoreEvent("Operations Overview Line Clicked", {
80086
80609
  line_id: lineId,
80087
80610
  line_name: lineName,
@@ -80649,4 +81172,4 @@ var streamProxyConfig = {
80649
81172
  }
80650
81173
  };
80651
81174
 
80652
- export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, ROOT_DASHBOARD_EVENT_NAMES, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyFastSlowClipFiltersEnabled, useCompanyHasVlmEnabledLine, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
81175
+ export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, ROOT_DASHBOARD_EVENT_NAMES, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureHandledFrontendException, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isIgnorableFrontendError, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyFastSlowClipFiltersEnabled, useCompanyHasVlmEnabledLine, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };