@optifye/dashboard-core 6.11.18 → 6.11.20

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 React141 from 'react';
2
- import React141__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 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';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { useRouter } from 'next/router';
5
5
  import { toast } from 'sonner';
@@ -10,13 +10,13 @@ import { EventEmitter } from 'events';
10
10
  import { createClient, REALTIME_SUBSCRIBE_STATES } from '@supabase/supabase-js';
11
11
  import Hls, { Events, ErrorTypes } from 'hls.js';
12
12
  import useSWR from 'swr';
13
- import { Camera, AlertTriangle, ChevronDown, ChevronUp, Check, Map as Map$1, Video, ShieldCheck, Star, Award, Filter, X, Coffee, Plus, ArrowUp, ArrowDown, ArrowRight, ArrowLeft, Clock, Calendar, Save, AlertCircle, Loader2, Minus, ChevronLeft, ChevronRight, TrendingUp, Sparkles, Pause, Play, XCircle, HelpCircle, Activity, Wrench, UserX, Package, RefreshCw, Palette, CheckCircle2, TrendingDown, FolderOpen, Folder, Tag, Sliders, Layers, Search, Edit2, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Copy, Settings, LifeBuoy, EyeOff, Zap, Flame, Crown, Medal } from 'lucide-react';
13
+ import { Camera, AlertTriangle, ChevronDown, ChevronUp, Check, Map as Map$1, Video, ShieldCheck, Star, Award, Filter, X, Coffee, Plus, ArrowUp, ArrowDown, ArrowRight, ArrowLeft, Clock, Calendar, Save, AlertCircle, Loader2, Minus, ChevronLeft, ChevronRight, TrendingUp, Sparkles, Pause, Play, XCircle, HelpCircle, Activity, Wrench, UserX, Package, RefreshCw, Palette, CheckCircle2, TrendingDown, FolderOpen, Folder, Tag, Sliders, Layers, Search, Edit2, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Copy, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Settings, LifeBuoy, EyeOff, Zap, Flame, Crown, Medal } from 'lucide-react';
14
14
  import { memo, noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds } from 'motion-utils';
15
15
  import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, ReferenceLine, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, PieChart, Pie, Cell, LineChart as LineChart$1, Line, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
16
16
  import { Slot } from '@radix-ui/react-slot';
17
17
  import * as SelectPrimitive from '@radix-ui/react-select';
18
18
  import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
19
- import { AdjustmentsHorizontalIcon, ClockIcon, UsersIcon, UserCircleIcon, TicketIcon, CurrencyDollarIcon, QuestionMarkCircleIcon, XMarkIcon, ArrowRightIcon, Bars3Icon, HomeIcon, VideoCameraIcon, TrophyIcon, ChartBarIcon, LightBulbIcon, CubeIcon, HeartIcon, BellIcon, Cog6ToothIcon, ChevronRightIcon, ArrowRightStartOnRectangleIcon, ExclamationCircleIcon, ExclamationTriangleIcon, CalendarIcon, ChevronDownIcon, ChevronLeftIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ArrowDownTrayIcon, CheckCircleIcon, ChatBubbleLeftRightIcon, XCircleIcon, FunnelIcon, EyeIcon, InformationCircleIcon, ArrowLeftIcon, PlayCircleIcon } from '@heroicons/react/24/outline';
19
+ import { AdjustmentsHorizontalIcon, ClockIcon, UsersIcon, UserCircleIcon, TicketIcon, CurrencyDollarIcon, QuestionMarkCircleIcon, XMarkIcon, InformationCircleIcon, ArrowRightIcon, Bars3Icon, HomeIcon, VideoCameraIcon, TrophyIcon, ChartBarIcon, LightBulbIcon, CubeIcon, HeartIcon, Cog6ToothIcon, ChevronRightIcon, ArrowRightStartOnRectangleIcon, ExclamationCircleIcon, ExclamationTriangleIcon, CalendarIcon, ChevronDownIcon, ChevronLeftIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ArrowDownTrayIcon, CheckCircleIcon, ChatBubbleLeftRightIcon, XCircleIcon, FunnelIcon, EyeIcon, ArrowLeftIcon, PlayCircleIcon } from '@heroicons/react/24/outline';
20
20
  import { CheckIcon } from '@heroicons/react/24/solid';
21
21
  import html2canvas from 'html2canvas';
22
22
  import jsPDF, { jsPDF as jsPDF$1 } from 'jspdf';
@@ -1938,14 +1938,14 @@ var useIdleTimeVlmConfig = () => {
1938
1938
  }
1939
1939
  return context;
1940
1940
  };
1941
- var DashboardConfigContext = React141.createContext(void 0);
1941
+ var DashboardConfigContext = React142.createContext(void 0);
1942
1942
  var DashboardProvider = ({ config: userProvidedConfig, children }) => {
1943
- const fullConfig = React141.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
1943
+ const fullConfig = React142.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
1944
1944
  _setDashboardConfigInstance(fullConfig);
1945
- React141.useEffect(() => {
1945
+ React142.useEffect(() => {
1946
1946
  _setDashboardConfigInstance(fullConfig);
1947
1947
  }, [fullConfig]);
1948
- React141.useEffect(() => {
1948
+ React142.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 = React141.useContext(DashboardConfigContext);
1974
+ const ctx = React142.useContext(DashboardConfigContext);
1975
1975
  if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
1976
1976
  return ctx;
1977
1977
  };
@@ -4639,6 +4639,11 @@ var workspaceService = {
4639
4639
  _workspaceVideoStreamsInFlight: /* @__PURE__ */ new Map(),
4640
4640
  _workspaceVideoStreamsCacheExpiryMs: 5 * 60 * 1e3,
4641
4641
  // 5 minutes cache
4642
+ // Cache for workspace camera IPs derived from CV configs
4643
+ _workspaceCameraIpsCache: /* @__PURE__ */ new Map(),
4644
+ _workspaceCameraIpsInFlight: /* @__PURE__ */ new Map(),
4645
+ _workspaceCameraIpsCacheExpiryMs: 5 * 60 * 1e3,
4646
+ // 5 minutes cache
4642
4647
  async getWorkspaces(lineId, options) {
4643
4648
  const enabledOnly = options?.enabledOnly ?? false;
4644
4649
  const force = options?.force ?? false;
@@ -4740,6 +4745,61 @@ var workspaceService = {
4740
4745
  this._workspaceVideoStreamsInFlight.set(cacheKey, fetchPromise);
4741
4746
  return fetchPromise;
4742
4747
  },
4748
+ async getWorkspaceCameraIps(params) {
4749
+ const workspaceIds = (params.workspaceIds || []).filter(Boolean);
4750
+ const lineIds = (params.lineIds || []).filter(Boolean);
4751
+ const force = params.force ?? false;
4752
+ if (!workspaceIds.length && !lineIds.length) {
4753
+ return {};
4754
+ }
4755
+ const workspaceKey = workspaceIds.slice().sort().join(",");
4756
+ const lineKey = lineIds.slice().sort().join(",");
4757
+ const cacheKey = workspaceKey ? `workspaces:${workspaceKey}` : `lines:${lineKey}`;
4758
+ const now4 = Date.now();
4759
+ const cached = this._workspaceCameraIpsCache.get(cacheKey);
4760
+ if (!force && cached && now4 - cached.timestamp < this._workspaceCameraIpsCacheExpiryMs) {
4761
+ return cached.cameraIps;
4762
+ }
4763
+ const inFlight = this._workspaceCameraIpsInFlight.get(cacheKey);
4764
+ if (!force && inFlight) {
4765
+ return inFlight;
4766
+ }
4767
+ const fetchPromise = (async () => {
4768
+ try {
4769
+ const token = await getAuthToken2();
4770
+ const apiUrl = getBackendUrl2();
4771
+ const response = await fetch(`${apiUrl}/api/workspaces/camera-ips`, {
4772
+ method: "POST",
4773
+ headers: {
4774
+ "Authorization": `Bearer ${token}`,
4775
+ "Content-Type": "application/json"
4776
+ },
4777
+ body: JSON.stringify({
4778
+ workspace_ids: workspaceIds.length ? workspaceIds : void 0,
4779
+ line_ids: lineIds.length ? lineIds : void 0
4780
+ })
4781
+ });
4782
+ if (!response.ok) {
4783
+ const errorText = await response.text();
4784
+ throw new Error(`Backend API error (${response.status}): ${errorText}`);
4785
+ }
4786
+ const data = await response.json();
4787
+ const cameraIps = data.camera_ips || {};
4788
+ this._workspaceCameraIpsCache.set(cacheKey, {
4789
+ cameraIps,
4790
+ timestamp: Date.now()
4791
+ });
4792
+ return cameraIps;
4793
+ } catch (error) {
4794
+ console.error("Error fetching workspace camera IPs:", error);
4795
+ throw error;
4796
+ } finally {
4797
+ this._workspaceCameraIpsInFlight.delete(cacheKey);
4798
+ }
4799
+ })();
4800
+ this._workspaceCameraIpsInFlight.set(cacheKey, fetchPromise);
4801
+ return fetchPromise;
4802
+ },
4743
4803
  /**
4744
4804
  * Fetches workspace display names from the database
4745
4805
  * Returns a map of workspace_id -> display_name
@@ -11130,7 +11190,7 @@ var useMobileMenu = () => {
11130
11190
  };
11131
11191
  var useHideMobileHeader = (shouldHide = true) => {
11132
11192
  const context = useMobileMenu();
11133
- React141__default.useEffect(() => {
11193
+ React142__default.useEffect(() => {
11134
11194
  if (context && shouldHide) {
11135
11195
  context.setHideMobileHeader(true);
11136
11196
  return () => {
@@ -19891,6 +19951,53 @@ function useCompanyClipsCost() {
19891
19951
  refetch: fetchData
19892
19952
  };
19893
19953
  }
19954
+ function useCompanyHasVlmEnabledLine(options = {}) {
19955
+ const { enabled = true } = options;
19956
+ const { user } = useAuth();
19957
+ const supabase = useSupabase();
19958
+ const entityConfig = useEntityConfig();
19959
+ const [hasVlmEnabledLine, setHasVlmEnabledLine] = useState(false);
19960
+ const [isLoading, setIsLoading] = useState(enabled);
19961
+ const companyId = user?.properties?.company_id || user?.company_id || entityConfig.companyId;
19962
+ useEffect(() => {
19963
+ let isCancelled = false;
19964
+ const load = async () => {
19965
+ if (!enabled || !companyId || !supabase) {
19966
+ setHasVlmEnabledLine(false);
19967
+ setIsLoading(false);
19968
+ return;
19969
+ }
19970
+ setIsLoading(true);
19971
+ try {
19972
+ const { data, error } = await supabase.from("lines").select("id").eq("company_id", companyId).eq("idle_time_vlm_enabled", true).limit(1);
19973
+ if (error) {
19974
+ throw error;
19975
+ }
19976
+ if (isCancelled) {
19977
+ return;
19978
+ }
19979
+ setHasVlmEnabledLine((data?.length || 0) > 0);
19980
+ } catch (error) {
19981
+ console.error("[useCompanyHasVlmEnabledLine] Error:", error);
19982
+ if (!isCancelled) {
19983
+ setHasVlmEnabledLine(false);
19984
+ }
19985
+ } finally {
19986
+ if (!isCancelled) {
19987
+ setIsLoading(false);
19988
+ }
19989
+ }
19990
+ };
19991
+ void load();
19992
+ return () => {
19993
+ isCancelled = true;
19994
+ };
19995
+ }, [companyId, enabled, supabase]);
19996
+ return {
19997
+ hasVlmEnabledLine,
19998
+ isLoading
19999
+ };
20000
+ }
19894
20001
 
19895
20002
  // src/lib/utils/api.ts
19896
20003
  var apiUtils = {
@@ -23123,7 +23230,7 @@ var MotionConfigContext = createContext({
23123
23230
  });
23124
23231
 
23125
23232
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
23126
- var PopChildMeasure = class extends React141.Component {
23233
+ var PopChildMeasure = class extends React142.Component {
23127
23234
  getSnapshotBeforeUpdate(prevProps) {
23128
23235
  const element = this.props.childRef.current;
23129
23236
  if (element && prevProps.isPresent && !this.props.isPresent) {
@@ -23178,7 +23285,7 @@ function PopChild({ children, isPresent }) {
23178
23285
  document.head.removeChild(style);
23179
23286
  };
23180
23287
  }, [isPresent]);
23181
- return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React141.cloneElement(children, { ref }) });
23288
+ return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React142.cloneElement(children, { ref }) });
23182
23289
  }
23183
23290
 
23184
23291
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
@@ -23215,7 +23322,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
23215
23322
  useMemo(() => {
23216
23323
  presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
23217
23324
  }, [isPresent]);
23218
- React141.useEffect(() => {
23325
+ React142.useEffect(() => {
23219
23326
  !isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
23220
23327
  }, [isPresent]);
23221
23328
  if (mode === "popLayout") {
@@ -31000,7 +31107,7 @@ var withAuth = (WrappedComponent2, options) => {
31000
31107
  requireAuth: true,
31001
31108
  ...options
31002
31109
  };
31003
- const WithAuthComponent = React141.memo(function WithAuthComponent2(props) {
31110
+ const WithAuthComponent = React142.memo(function WithAuthComponent2(props) {
31004
31111
  const {
31005
31112
  session,
31006
31113
  user,
@@ -31011,9 +31118,9 @@ var withAuth = (WrappedComponent2, options) => {
31011
31118
  retrySessionHydration
31012
31119
  } = useAuth();
31013
31120
  const router = useRouter();
31014
- const [localLoading, setLocalLoading] = React141.useState(loading);
31015
- const [loadingTimeoutReached, setLoadingTimeoutReached] = React141.useState(false);
31016
- React141.useEffect(() => {
31121
+ const [localLoading, setLocalLoading] = React142.useState(loading);
31122
+ const [loadingTimeoutReached, setLoadingTimeoutReached] = React142.useState(false);
31123
+ React142.useEffect(() => {
31017
31124
  if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
31018
31125
  console.log("withAuth state:", {
31019
31126
  loading,
@@ -31025,7 +31132,7 @@ var withAuth = (WrappedComponent2, options) => {
31025
31132
  });
31026
31133
  }
31027
31134
  }, [authStatus, error, loading, session, user]);
31028
- const handleLoadingTimeout = React141.useCallback(() => {
31135
+ const handleLoadingTimeout = React142.useCallback(() => {
31029
31136
  console.warn("[withAuth] Loading timeout reached");
31030
31137
  setLoadingTimeoutReached(true);
31031
31138
  if (hasStoredSupabaseSession()) {
@@ -31037,13 +31144,13 @@ var withAuth = (WrappedComponent2, options) => {
31037
31144
  router.replace(defaultOptions.redirectTo);
31038
31145
  }
31039
31146
  }, [retrySessionHydration, router]);
31040
- React141.useEffect(() => {
31147
+ React142.useEffect(() => {
31041
31148
  if (!loading && authStatus !== "recovering" && defaultOptions.requireAuth && !session && !error) {
31042
31149
  console.log("[withAuth] No session found, redirecting to login");
31043
31150
  router.replace(defaultOptions.redirectTo);
31044
31151
  }
31045
31152
  }, [authStatus, defaultOptions.requireAuth, error, loading, router, session]);
31046
- React141.useEffect(() => {
31153
+ React142.useEffect(() => {
31047
31154
  setLocalLoading(loading);
31048
31155
  }, [loading]);
31049
31156
  if (loading || localLoading) {
@@ -32042,11 +32149,11 @@ var BarChartComponent = ({
32042
32149
  aspect = 2,
32043
32150
  ...restOfChartProps
32044
32151
  }) => {
32045
- const containerRef = React141__default.useRef(null);
32046
- const [containerReady, setContainerReady] = React141__default.useState(false);
32152
+ const containerRef = React142__default.useRef(null);
32153
+ const [containerReady, setContainerReady] = React142__default.useState(false);
32047
32154
  const themeConfig = useThemeConfig();
32048
32155
  const { formatNumber } = useFormatNumber();
32049
- React141__default.useEffect(() => {
32156
+ React142__default.useEffect(() => {
32050
32157
  const checkContainerDimensions = () => {
32051
32158
  if (containerRef.current) {
32052
32159
  const rect = containerRef.current.getBoundingClientRect();
@@ -32160,7 +32267,7 @@ var BarChartComponent = ({
32160
32267
  }
32161
32268
  return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
32162
32269
  };
32163
- var BarChart = React141__default.memo(BarChartComponent, (prevProps, nextProps) => {
32270
+ var BarChart = React142__default.memo(BarChartComponent, (prevProps, nextProps) => {
32164
32271
  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) {
32165
32272
  return false;
32166
32273
  }
@@ -32211,10 +32318,10 @@ var LineChartComponent = ({
32211
32318
  fillContainer = false,
32212
32319
  ...restOfChartProps
32213
32320
  }) => {
32214
- const containerRef = React141__default.useRef(null);
32215
- const [dimensions, setDimensions] = React141__default.useState({ width: 0, height: 0 });
32216
- const [hasValidData, setHasValidData] = React141__default.useState(false);
32217
- React141__default.useEffect(() => {
32321
+ const containerRef = React142__default.useRef(null);
32322
+ const [dimensions, setDimensions] = React142__default.useState({ width: 0, height: 0 });
32323
+ const [hasValidData, setHasValidData] = React142__default.useState(false);
32324
+ React142__default.useEffect(() => {
32218
32325
  const currentHasValidData = data && lines && lines.length > 0 && data.some(
32219
32326
  (item) => lines.some((line) => {
32220
32327
  const val = item[line.dataKey];
@@ -32225,7 +32332,7 @@ var LineChartComponent = ({
32225
32332
  setHasValidData(true);
32226
32333
  }
32227
32334
  }, [data, lines, hasValidData]);
32228
- React141__default.useEffect(() => {
32335
+ React142__default.useEffect(() => {
32229
32336
  if (!containerRef.current) return;
32230
32337
  const observer = new ResizeObserver((entries) => {
32231
32338
  const entry = entries[0];
@@ -32350,7 +32457,7 @@ var LineChartComponent = ({
32350
32457
  }
32351
32458
  return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
32352
32459
  };
32353
- var LineChart = React141__default.memo(LineChartComponent, (prevProps, nextProps) => {
32460
+ var LineChart = React142__default.memo(LineChartComponent, (prevProps, nextProps) => {
32354
32461
  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)) {
32355
32462
  return false;
32356
32463
  }
@@ -32444,7 +32551,7 @@ var OutputProgressChartComponent = ({
32444
32551
  ] }) })
32445
32552
  ] }) });
32446
32553
  };
32447
- var OutputProgressChart = React141__default.memo(OutputProgressChartComponent);
32554
+ var OutputProgressChart = React142__default.memo(OutputProgressChartComponent);
32448
32555
  OutputProgressChart.displayName = "OutputProgressChart";
32449
32556
  var LargeOutputProgressChart = ({
32450
32557
  currentOutput,
@@ -32584,7 +32691,7 @@ var CycleTimeChartComponent = ({
32584
32691
  }
32585
32692
  ) }) });
32586
32693
  };
32587
- var CycleTimeChart = React141__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
32694
+ var CycleTimeChart = React142__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
32588
32695
  if (prevProps.className !== nextProps.className) {
32589
32696
  return false;
32590
32697
  }
@@ -32822,16 +32929,16 @@ var CycleTimeOverTimeChart = ({
32822
32929
  idleTimeSlots = []
32823
32930
  }) => {
32824
32931
  const MAX_DATA_POINTS = 40;
32825
- const containerRef = React141__default.useRef(null);
32826
- const [dimensions, setDimensions] = React141__default.useState({ width: 0, height: 0 });
32827
- const [hasValidData, setHasValidData] = React141__default.useState(false);
32828
- React141__default.useEffect(() => {
32932
+ const containerRef = React142__default.useRef(null);
32933
+ const [dimensions, setDimensions] = React142__default.useState({ width: 0, height: 0 });
32934
+ const [hasValidData, setHasValidData] = React142__default.useState(false);
32935
+ React142__default.useEffect(() => {
32829
32936
  const currentHasValidData = data && data.some((val) => val !== null && val > 0);
32830
32937
  if (currentHasValidData && !hasValidData) {
32831
32938
  setHasValidData(true);
32832
32939
  }
32833
32940
  }, [data, hasValidData]);
32834
- React141__default.useEffect(() => {
32941
+ React142__default.useEffect(() => {
32835
32942
  if (!containerRef.current) return;
32836
32943
  const observer = new ResizeObserver((entries) => {
32837
32944
  const entry = entries[0];
@@ -32863,7 +32970,7 @@ var CycleTimeOverTimeChart = ({
32863
32970
  const endLabel = shiftEnd && slotIndex === DURATION - 1 ? formatHourLabel(slotIndex + 1) : formatHourLabel(slotIndex + 1);
32864
32971
  return `${startLabel} - ${endLabel}`;
32865
32972
  };
32866
- const getDisplayData = React141__default.useCallback((rawData) => {
32973
+ const getDisplayData = React142__default.useCallback((rawData) => {
32867
32974
  if (xAxisMode === "hourly") return rawData;
32868
32975
  return rawData.slice(Math.max(0, rawData.length - MAX_DATA_POINTS));
32869
32976
  }, [xAxisMode]);
@@ -32871,7 +32978,7 @@ var CycleTimeOverTimeChart = ({
32871
32978
  const DURATION = displayData.length;
32872
32979
  const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
32873
32980
  const finalData = displayData;
32874
- const labelInterval = React141__default.useMemo(() => {
32981
+ const labelInterval = React142__default.useMemo(() => {
32875
32982
  if (xAxisMode === "hourly") {
32876
32983
  return Math.max(1, Math.ceil(DURATION / 8));
32877
32984
  }
@@ -32912,8 +33019,8 @@ var CycleTimeOverTimeChart = ({
32912
33019
  return `${minutes} minutes ${seconds} seconds ago`;
32913
33020
  }
32914
33021
  };
32915
- const getNumericValue = React141__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
32916
- const renderChartTooltip = React141__default.useCallback((tooltipProps) => {
33022
+ const getNumericValue = React142__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
33023
+ const renderChartTooltip = React142__default.useCallback((tooltipProps) => {
32917
33024
  const { active, payload } = tooltipProps;
32918
33025
  if (!active || !Array.isArray(payload) || payload.length === 0) {
32919
33026
  return null;
@@ -32976,7 +33083,7 @@ var CycleTimeOverTimeChart = ({
32976
33083
  ] })
32977
33084
  ] });
32978
33085
  }, [getNumericValue, shiftStart, showIdleTime]);
32979
- const renderCycleDot = React141__default.useCallback((props) => {
33086
+ const renderCycleDot = React142__default.useCallback((props) => {
32980
33087
  const { cx: cx2, cy, payload } = props;
32981
33088
  const cycleTime = getNumericValue(payload?.cycleTime);
32982
33089
  if (cycleTime === null) {
@@ -33009,7 +33116,7 @@ var CycleTimeOverTimeChart = ({
33009
33116
  }
33010
33117
  );
33011
33118
  }, [getNumericValue, idealCycleTime]);
33012
- const renderCycleActiveDot = React141__default.useCallback((props) => {
33119
+ const renderCycleActiveDot = React142__default.useCallback((props) => {
33013
33120
  const { cx: cx2, cy, payload } = props;
33014
33121
  const cycleTime = getNumericValue(payload?.cycleTime);
33015
33122
  if (cycleTime === null) {
@@ -33030,7 +33137,7 @@ var CycleTimeOverTimeChart = ({
33030
33137
  }
33031
33138
  );
33032
33139
  }, [getNumericValue, idealCycleTime]);
33033
- const renderIdleDot = React141__default.useCallback((props) => {
33140
+ const renderIdleDot = React142__default.useCallback((props) => {
33034
33141
  const { cx: cx2, cy, payload } = props;
33035
33142
  const idleMinutes = getNumericValue(payload?.idleMinutes);
33036
33143
  if (idleMinutes === null) {
@@ -33052,7 +33159,7 @@ var CycleTimeOverTimeChart = ({
33052
33159
  }
33053
33160
  );
33054
33161
  }, [getNumericValue, showIdleTime]);
33055
- const renderIdleActiveDot = React141__default.useCallback((props) => {
33162
+ const renderIdleActiveDot = React142__default.useCallback((props) => {
33056
33163
  const { cx: cx2, cy, payload } = props;
33057
33164
  const idleMinutes = getNumericValue(payload?.idleMinutes);
33058
33165
  if (idleMinutes === null || !showIdleTime) {
@@ -33070,7 +33177,7 @@ var CycleTimeOverTimeChart = ({
33070
33177
  }
33071
33178
  );
33072
33179
  }, [getNumericValue, showIdleTime]);
33073
- const chartData = React141__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
33180
+ const chartData = React142__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
33074
33181
  const cycleTime = getNumericValue(finalData[i]);
33075
33182
  const useIdleSlots = idleTimeSlots.length > 0;
33076
33183
  const idleSlot = useIdleSlots ? idleTimeSlots[i] ?? null : null;
@@ -33267,7 +33374,7 @@ var CycleTimeOverTimeChart = ({
33267
33374
  }
33268
33375
  );
33269
33376
  };
33270
- var Card = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33377
+ var Card = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33271
33378
  "div",
33272
33379
  {
33273
33380
  ref,
@@ -33279,7 +33386,7 @@ var Card = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
33279
33386
  }
33280
33387
  ));
33281
33388
  Card.displayName = "Card";
33282
- var CardHeader = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33389
+ var CardHeader = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33283
33390
  "div",
33284
33391
  {
33285
33392
  ref,
@@ -33288,7 +33395,7 @@ var CardHeader = React141.forwardRef(({ className, ...props }, ref) => /* @__PUR
33288
33395
  }
33289
33396
  ));
33290
33397
  CardHeader.displayName = "CardHeader";
33291
- var CardTitle = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33398
+ var CardTitle = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33292
33399
  "h3",
33293
33400
  {
33294
33401
  ref,
@@ -33300,7 +33407,7 @@ var CardTitle = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE
33300
33407
  }
33301
33408
  ));
33302
33409
  CardTitle.displayName = "CardTitle";
33303
- var CardDescription = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33410
+ var CardDescription = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33304
33411
  "p",
33305
33412
  {
33306
33413
  ref,
@@ -33309,9 +33416,9 @@ var CardDescription = React141.forwardRef(({ className, ...props }, ref) => /* @
33309
33416
  }
33310
33417
  ));
33311
33418
  CardDescription.displayName = "CardDescription";
33312
- var CardContent = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
33419
+ var CardContent = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
33313
33420
  CardContent.displayName = "CardContent";
33314
- var CardFooter = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33421
+ var CardFooter = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33315
33422
  "div",
33316
33423
  {
33317
33424
  ref,
@@ -33387,7 +33494,7 @@ var buttonVariants = cva(
33387
33494
  }
33388
33495
  }
33389
33496
  );
33390
- var Button = React141.forwardRef(
33497
+ var Button = React142.forwardRef(
33391
33498
  ({ className, variant, size, asChild = false, ...props }, ref) => {
33392
33499
  const Comp = asChild ? Slot : "button";
33393
33500
  return /* @__PURE__ */ jsx(
@@ -33410,10 +33517,10 @@ var HourlyOutputChartComponent = ({
33410
33517
  idleTimeHourly,
33411
33518
  className = ""
33412
33519
  }) => {
33413
- const containerRef = React141__default.useRef(null);
33414
- const [containerReady, setContainerReady] = React141__default.useState(false);
33415
- const [containerWidth, setContainerWidth] = React141__default.useState(0);
33416
- const idleSlots = React141__default.useMemo(
33520
+ const containerRef = React142__default.useRef(null);
33521
+ const [containerReady, setContainerReady] = React142__default.useState(false);
33522
+ const [containerWidth, setContainerWidth] = React142__default.useState(0);
33523
+ const idleSlots = React142__default.useMemo(
33417
33524
  () => buildHourlyIdleSlots({
33418
33525
  idleTimeHourly,
33419
33526
  shiftStart,
@@ -33422,12 +33529,12 @@ var HourlyOutputChartComponent = ({
33422
33529
  [idleTimeHourly, shiftStart, shiftEnd]
33423
33530
  );
33424
33531
  const SHIFT_DURATION = idleSlots.length;
33425
- const [animatedData, setAnimatedData] = React141__default.useState(
33532
+ const [animatedData, setAnimatedData] = React142__default.useState(
33426
33533
  () => Array(SHIFT_DURATION).fill(0)
33427
33534
  );
33428
- const prevDataRef = React141__default.useRef(Array(SHIFT_DURATION).fill(0));
33429
- const animationFrameRef = React141__default.useRef(null);
33430
- React141__default.useEffect(() => {
33535
+ const prevDataRef = React142__default.useRef(Array(SHIFT_DURATION).fill(0));
33536
+ const animationFrameRef = React142__default.useRef(null);
33537
+ React142__default.useEffect(() => {
33431
33538
  setAnimatedData((prev) => {
33432
33539
  if (prev.length !== SHIFT_DURATION) {
33433
33540
  return Array(SHIFT_DURATION).fill(0);
@@ -33436,14 +33543,14 @@ var HourlyOutputChartComponent = ({
33436
33543
  });
33437
33544
  prevDataRef.current = Array(SHIFT_DURATION).fill(0);
33438
33545
  }, [SHIFT_DURATION]);
33439
- const [idleBarState, setIdleBarState] = React141__default.useState({
33546
+ const [idleBarState, setIdleBarState] = React142__default.useState({
33440
33547
  visible: showIdleTime,
33441
33548
  key: 0,
33442
33549
  shouldAnimate: false
33443
33550
  });
33444
- const prevShowIdleTimeRef = React141__default.useRef(showIdleTime);
33445
- const stateUpdateTimeoutRef = React141__default.useRef(null);
33446
- React141__default.useEffect(() => {
33551
+ const prevShowIdleTimeRef = React142__default.useRef(showIdleTime);
33552
+ const stateUpdateTimeoutRef = React142__default.useRef(null);
33553
+ React142__default.useEffect(() => {
33447
33554
  if (stateUpdateTimeoutRef.current) {
33448
33555
  clearTimeout(stateUpdateTimeoutRef.current);
33449
33556
  }
@@ -33468,7 +33575,7 @@ var HourlyOutputChartComponent = ({
33468
33575
  }
33469
33576
  };
33470
33577
  }, [showIdleTime]);
33471
- const animateToNewData = React141__default.useCallback((targetData) => {
33578
+ const animateToNewData = React142__default.useCallback((targetData) => {
33472
33579
  const startData = [...prevDataRef.current];
33473
33580
  const startTime = performance.now();
33474
33581
  const duration = 1200;
@@ -33498,7 +33605,7 @@ var HourlyOutputChartComponent = ({
33498
33605
  }
33499
33606
  animationFrameRef.current = requestAnimationFrame(animate);
33500
33607
  }, []);
33501
- React141__default.useEffect(() => {
33608
+ React142__default.useEffect(() => {
33502
33609
  if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
33503
33610
  const shiftData = data.slice(0, SHIFT_DURATION);
33504
33611
  animateToNewData(shiftData);
@@ -33509,7 +33616,7 @@ var HourlyOutputChartComponent = ({
33509
33616
  }
33510
33617
  };
33511
33618
  }, [data, animateToNewData]);
33512
- React141__default.useEffect(() => {
33619
+ React142__default.useEffect(() => {
33513
33620
  const checkContainerDimensions = () => {
33514
33621
  if (containerRef.current) {
33515
33622
  const rect = containerRef.current.getBoundingClientRect();
@@ -33535,7 +33642,7 @@ var HourlyOutputChartComponent = ({
33535
33642
  clearTimeout(fallbackTimeout);
33536
33643
  };
33537
33644
  }, []);
33538
- const xAxisConfig = React141__default.useMemo(() => {
33645
+ const xAxisConfig = React142__default.useMemo(() => {
33539
33646
  if (containerWidth >= 960) {
33540
33647
  return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12 };
33541
33648
  }
@@ -33544,7 +33651,7 @@ var HourlyOutputChartComponent = ({
33544
33651
  }
33545
33652
  return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6 };
33546
33653
  }, [containerWidth]);
33547
- const chartData = React141__default.useMemo(() => {
33654
+ const chartData = React142__default.useMemo(() => {
33548
33655
  return Array.from({ length: SHIFT_DURATION }, (_, i) => {
33549
33656
  const idleSlot = idleSlots[i];
33550
33657
  return {
@@ -33560,7 +33667,7 @@ var HourlyOutputChartComponent = ({
33560
33667
  };
33561
33668
  });
33562
33669
  }, [animatedData, data, pphThreshold, idleSlots, SHIFT_DURATION]);
33563
- const IdleBar = React141__default.useMemo(() => {
33670
+ const IdleBar = React142__default.useMemo(() => {
33564
33671
  if (!idleBarState.visible) return null;
33565
33672
  return /* @__PURE__ */ jsx(
33566
33673
  Bar,
@@ -33858,7 +33965,7 @@ var HourlyOutputChartComponent = ({
33858
33965
  }
33859
33966
  );
33860
33967
  };
33861
- var HourlyOutputChart = React141__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
33968
+ var HourlyOutputChart = React142__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
33862
33969
  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) {
33863
33970
  return false;
33864
33971
  }
@@ -33946,6 +34053,9 @@ var getVideoGridBaseColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND)
33946
34053
  return getEfficiencyColor(metricValue, legend);
33947
34054
  };
33948
34055
  var isLowWipGreenOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
34056
+ if (workspace.scheduled_break_active === true) {
34057
+ return false;
34058
+ }
33949
34059
  if (!hasVideoGridRecentFlow(workspace) || !isVideoGridWipGated(workspace)) {
33950
34060
  return false;
33951
34061
  }
@@ -34035,7 +34145,7 @@ function getTrendArrowAndColor(trend) {
34035
34145
  return { arrow: "\u2192", color: "text-gray-400" };
34036
34146
  }
34037
34147
  }
34038
- var VideoCard = React141__default.memo(({
34148
+ var VideoCard = React142__default.memo(({
34039
34149
  workspace,
34040
34150
  hlsUrl,
34041
34151
  shouldPlay,
@@ -34197,7 +34307,7 @@ var VideoCard = React141__default.memo(({
34197
34307
  }
34198
34308
  );
34199
34309
  }, (prevProps, nextProps) => {
34200
- if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
34310
+ if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
34201
34311
  return false;
34202
34312
  }
34203
34313
  if (prevProps.workspace.workspace_uuid !== nextProps.workspace.workspace_uuid || prevProps.workspace.workspace_name !== nextProps.workspace.workspace_name || prevProps.workspace.line_id !== nextProps.workspace.line_id) {
@@ -34233,7 +34343,7 @@ var logDebug2 = (...args) => {
34233
34343
  if (!DEBUG_DASHBOARD_LOGS2) return;
34234
34344
  console.log(...args);
34235
34345
  };
34236
- var VideoGridView = React141__default.memo(({
34346
+ var VideoGridView = React142__default.memo(({
34237
34347
  workspaces,
34238
34348
  selectedLine,
34239
34349
  className = "",
@@ -34605,7 +34715,7 @@ var VideoGridView = React141__default.memo(({
34605
34715
  ) }) });
34606
34716
  });
34607
34717
  VideoGridView.displayName = "VideoGridView";
34608
- var MapGridView = React141__default.memo(({
34718
+ var MapGridView = React142__default.memo(({
34609
34719
  workspaces,
34610
34720
  className = "",
34611
34721
  displayNames = {},
@@ -35444,7 +35554,7 @@ var UptimeLineChartComponent = ({ points, className = "" }) => {
35444
35554
  )
35445
35555
  ] }) }) });
35446
35556
  };
35447
- var UptimeLineChart = React141__default.memo(UptimeLineChartComponent);
35557
+ var UptimeLineChart = React142__default.memo(UptimeLineChartComponent);
35448
35558
  var padTime = (value) => value.toString().padStart(2, "0");
35449
35559
  var parseTime = (timeValue) => {
35450
35560
  if (!timeValue) return null;
@@ -35684,10 +35794,10 @@ var HourlyUptimeChartComponent = ({
35684
35794
  elapsedMinutes,
35685
35795
  className = ""
35686
35796
  }) => {
35687
- const containerRef = React141__default.useRef(null);
35688
- const [containerReady, setContainerReady] = React141__default.useState(false);
35689
- const [containerWidth, setContainerWidth] = React141__default.useState(0);
35690
- const uptimeSeries = React141__default.useMemo(() => buildUptimeSeries({
35797
+ const containerRef = React142__default.useRef(null);
35798
+ const [containerReady, setContainerReady] = React142__default.useState(false);
35799
+ const [containerWidth, setContainerWidth] = React142__default.useState(0);
35800
+ const uptimeSeries = React142__default.useMemo(() => buildUptimeSeries({
35691
35801
  idleTimeHourly,
35692
35802
  shiftStart,
35693
35803
  shiftEnd,
@@ -35696,11 +35806,11 @@ var HourlyUptimeChartComponent = ({
35696
35806
  elapsedMinutes
35697
35807
  }), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes]);
35698
35808
  const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
35699
- const shiftStartTime = React141__default.useMemo(
35809
+ const shiftStartTime = React142__default.useMemo(
35700
35810
  () => getTimeFromTimeString(shiftStart),
35701
35811
  [shiftStart]
35702
35812
  );
35703
- const { shiftDuration, shiftEndTime } = React141__default.useMemo(() => {
35813
+ const { shiftDuration, shiftEndTime } = React142__default.useMemo(() => {
35704
35814
  if (!shiftEnd) {
35705
35815
  const fallbackHours = uptimeSeries.shiftMinutes > 0 ? Math.ceil(uptimeSeries.shiftMinutes / 60) : 0;
35706
35816
  return { shiftDuration: fallbackHours, shiftEndTime: null };
@@ -35714,7 +35824,7 @@ var HourlyUptimeChartComponent = ({
35714
35824
  const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
35715
35825
  return { shiftDuration: hourCount, shiftEndTime: endTime };
35716
35826
  }, [shiftEnd, shiftStartTime.decimalHour, uptimeSeries.shiftMinutes]);
35717
- const formatHour = React141__default.useCallback((hourIndex) => {
35827
+ const formatHour = React142__default.useCallback((hourIndex) => {
35718
35828
  const isLastHour = hourIndex === shiftDuration - 1;
35719
35829
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
35720
35830
  const startHour = Math.floor(startDecimalHour) % 24;
@@ -35739,7 +35849,7 @@ var HourlyUptimeChartComponent = ({
35739
35849
  };
35740
35850
  return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
35741
35851
  }, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
35742
- const formatTimeRange2 = React141__default.useCallback((hourIndex) => {
35852
+ const formatTimeRange2 = React142__default.useCallback((hourIndex) => {
35743
35853
  const isLastHour = hourIndex === shiftDuration - 1;
35744
35854
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
35745
35855
  const startHour = Math.floor(startDecimalHour) % 24;
@@ -35761,7 +35871,7 @@ var HourlyUptimeChartComponent = ({
35761
35871
  };
35762
35872
  return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
35763
35873
  }, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
35764
- const chartData = React141__default.useMemo(() => {
35874
+ const chartData = React142__default.useMemo(() => {
35765
35875
  if (shiftDuration <= 0) return [];
35766
35876
  if (hasAggregateData) {
35767
35877
  return hourlyAggregates.map((entry, hourIndex) => ({
@@ -35803,7 +35913,7 @@ var HourlyUptimeChartComponent = ({
35803
35913
  }, [hasAggregateData, hourlyAggregates, uptimeSeries.points, uptimeSeries.elapsedMinutes, uptimeSeries.shiftMinutes, shiftDuration, formatHour, formatTimeRange2]);
35804
35914
  const maxYValue = 100;
35805
35915
  const yAxisTicks = [0, 25, 50, 75, 100];
35806
- React141__default.useEffect(() => {
35916
+ React142__default.useEffect(() => {
35807
35917
  const checkContainerDimensions = () => {
35808
35918
  if (containerRef.current) {
35809
35919
  const rect = containerRef.current.getBoundingClientRect();
@@ -35829,7 +35939,7 @@ var HourlyUptimeChartComponent = ({
35829
35939
  clearTimeout(fallbackTimeout);
35830
35940
  };
35831
35941
  }, []);
35832
- const xAxisConfig = React141__default.useMemo(() => {
35942
+ const xAxisConfig = React142__default.useMemo(() => {
35833
35943
  if (containerWidth >= 960) {
35834
35944
  return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12, labelMode: "full" };
35835
35945
  }
@@ -35838,7 +35948,7 @@ var HourlyUptimeChartComponent = ({
35838
35948
  }
35839
35949
  return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6, labelMode: "start" };
35840
35950
  }, [containerWidth]);
35841
- const formatXAxisTick = React141__default.useCallback((raw) => {
35951
+ const formatXAxisTick = React142__default.useCallback((raw) => {
35842
35952
  const label = typeof raw === "string" ? raw : String(raw);
35843
35953
  if (xAxisConfig.labelMode === "full") return label;
35844
35954
  const parts = label.split("-");
@@ -36044,7 +36154,7 @@ var HourlyUptimeChartComponent = ({
36044
36154
  }
36045
36155
  );
36046
36156
  };
36047
- var HourlyUptimeChart = React141__default.memo(HourlyUptimeChartComponent);
36157
+ var HourlyUptimeChart = React142__default.memo(HourlyUptimeChartComponent);
36048
36158
  var DEFAULT_COLORS2 = ["#00AB45", "#ef4444"];
36049
36159
  var UptimeDonutChartComponent = ({
36050
36160
  data,
@@ -36114,7 +36224,7 @@ var UptimeDonutChartComponent = ({
36114
36224
  ] }) })
36115
36225
  ] }) });
36116
36226
  };
36117
- var UptimeDonutChart = React141__default.memo(UptimeDonutChartComponent);
36227
+ var UptimeDonutChart = React142__default.memo(UptimeDonutChartComponent);
36118
36228
  UptimeDonutChart.displayName = "UptimeDonutChart";
36119
36229
  var TrendIcon = ({ trend }) => {
36120
36230
  if (trend === "up") {
@@ -36233,7 +36343,7 @@ var EmptyStateMessage = ({
36233
36343
  iconClassName
36234
36344
  }) => {
36235
36345
  let IconContent = null;
36236
- if (React141__default.isValidElement(iconType)) {
36346
+ if (React142__default.isValidElement(iconType)) {
36237
36347
  IconContent = iconType;
36238
36348
  } else if (typeof iconType === "string") {
36239
36349
  const MappedIcon = IconMap[iconType];
@@ -36886,6 +36996,7 @@ var VideoControls = ({
36886
36996
  return /* @__PURE__ */ jsxs(
36887
36997
  "div",
36888
36998
  {
36999
+ onClick: (e) => e.stopPropagation(),
36889
37000
  className: `absolute bottom-0 left-0 right-0 px-3 pb-3 pt-12 bg-gradient-to-t from-black/80 via-black/40 to-transparent transition-opacity duration-300 ${controlsVisible ? "opacity-100" : "opacity-0 pointer-events-none"} ${className}`,
36890
37001
  style: { touchAction: "none" },
36891
37002
  children: [
@@ -37929,13 +38040,11 @@ var HlsVideoPlayer = forwardRef(({
37929
38040
  player: playerLikeObject()
37930
38041
  }), [play, pause, currentTimeProp, durationProp, paused, mute, volumeProp, playbackRateProp, dispose, isReady, playerLikeObject]);
37931
38042
  const handleContainerClick = useCallback(() => {
37932
- if (!onClick && !controls) {
37933
- handleTogglePlay();
37934
- }
38043
+ handleTogglePlay();
37935
38044
  if (onClick) {
37936
38045
  onClick();
37937
38046
  }
37938
- }, [onClick, controls, handleTogglePlay]);
38047
+ }, [onClick, handleTogglePlay]);
37939
38048
  return /* @__PURE__ */ jsxs(
37940
38049
  "div",
37941
38050
  {
@@ -38360,9 +38469,7 @@ var CroppedHlsVideoPlayer = forwardRef(({
38360
38469
  return /* @__PURE__ */ jsx(HlsVideoPlayer, { ref, ...videoProps, onClick, controls });
38361
38470
  }
38362
38471
  const handleClick = () => {
38363
- if (!onClick && !controls) {
38364
- handleTogglePlay();
38365
- }
38472
+ handleTogglePlay();
38366
38473
  if (onClick) onClick();
38367
38474
  };
38368
38475
  return /* @__PURE__ */ jsxs(
@@ -38518,7 +38625,7 @@ function Skeleton({ className, ...props }) {
38518
38625
  var Select = SelectPrimitive.Root;
38519
38626
  var SelectGroup = SelectPrimitive.Group;
38520
38627
  var SelectValue = SelectPrimitive.Value;
38521
- var SelectTrigger = React141.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
38628
+ var SelectTrigger = React142.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
38522
38629
  SelectPrimitive.Trigger,
38523
38630
  {
38524
38631
  ref,
@@ -38534,7 +38641,7 @@ var SelectTrigger = React141.forwardRef(({ className, children, ...props }, ref)
38534
38641
  }
38535
38642
  ));
38536
38643
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
38537
- var SelectScrollUpButton = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38644
+ var SelectScrollUpButton = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38538
38645
  SelectPrimitive.ScrollUpButton,
38539
38646
  {
38540
38647
  ref,
@@ -38544,7 +38651,7 @@ var SelectScrollUpButton = React141.forwardRef(({ className, ...props }, ref) =>
38544
38651
  }
38545
38652
  ));
38546
38653
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
38547
- var SelectScrollDownButton = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38654
+ var SelectScrollDownButton = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38548
38655
  SelectPrimitive.ScrollDownButton,
38549
38656
  {
38550
38657
  ref,
@@ -38554,7 +38661,7 @@ var SelectScrollDownButton = React141.forwardRef(({ className, ...props }, ref)
38554
38661
  }
38555
38662
  ));
38556
38663
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
38557
- var SelectContent = React141.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
38664
+ var SelectContent = React142.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
38558
38665
  SelectPrimitive.Content,
38559
38666
  {
38560
38667
  ref,
@@ -38582,7 +38689,7 @@ var SelectContent = React141.forwardRef(({ className, children, position = "popp
38582
38689
  }
38583
38690
  ) }));
38584
38691
  SelectContent.displayName = SelectPrimitive.Content.displayName;
38585
- var SelectLabel = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38692
+ var SelectLabel = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38586
38693
  SelectPrimitive.Label,
38587
38694
  {
38588
38695
  ref,
@@ -38591,7 +38698,7 @@ var SelectLabel = React141.forwardRef(({ className, ...props }, ref) => /* @__PU
38591
38698
  }
38592
38699
  ));
38593
38700
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
38594
- var SelectItem = React141.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
38701
+ var SelectItem = React142.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
38595
38702
  SelectPrimitive.Item,
38596
38703
  {
38597
38704
  ref,
@@ -38607,7 +38714,7 @@ var SelectItem = React141.forwardRef(({ className, children, ...props }, ref) =>
38607
38714
  }
38608
38715
  ));
38609
38716
  SelectItem.displayName = SelectPrimitive.Item.displayName;
38610
- var SelectSeparator = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38717
+ var SelectSeparator = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38611
38718
  SelectPrimitive.Separator,
38612
38719
  {
38613
38720
  ref,
@@ -38906,7 +39013,7 @@ var TimePickerDropdown = ({
38906
39013
  ] })
38907
39014
  ] });
38908
39015
  };
38909
- var SilentErrorBoundary = class extends React141__default.Component {
39016
+ var SilentErrorBoundary = class extends React142__default.Component {
38910
39017
  constructor(props) {
38911
39018
  super(props);
38912
39019
  this.handleClearAndReload = () => {
@@ -42865,17 +42972,6 @@ var BottlenecksContent = ({
42865
42972
  window.addEventListener("keydown", handleKeyDown);
42866
42973
  return () => window.removeEventListener("keydown", handleKeyDown);
42867
42974
  }, [handlePrevious, handleNext]);
42868
- const togglePlayback = () => {
42869
- const player = videoRef.current?.player;
42870
- if (!player) return;
42871
- if (player.paused()) {
42872
- player.play()?.catch((err) => {
42873
- console.error("Error playing video:", err);
42874
- });
42875
- } else {
42876
- player.pause();
42877
- }
42878
- };
42879
42975
  const handlePlaybackSpeedChange = useCallback((speed) => {
42880
42976
  setPlaybackSpeed(speed);
42881
42977
  if (videoRef.current?.playbackRate) {
@@ -43045,7 +43141,6 @@ var BottlenecksContent = ({
43045
43141
  poster: "",
43046
43142
  className: "w-full h-full",
43047
43143
  crop: workspaceCrop?.crop,
43048
- onClick: togglePlayback,
43049
43144
  autoplay: true,
43050
43145
  playsInline: true,
43051
43146
  loop: false,
@@ -43470,7 +43565,6 @@ var BottlenecksContent = ({
43470
43565
  poster: "",
43471
43566
  className: "w-full h-full",
43472
43567
  crop: workspaceCrop?.crop,
43473
- onClick: togglePlayback,
43474
43568
  autoplay: true,
43475
43569
  playsInline: true,
43476
43570
  loop: false,
@@ -43989,7 +44083,7 @@ function DiagnosisVideoModal({
43989
44083
  src: playlistUrl,
43990
44084
  className: "w-full h-full",
43991
44085
  crop: null,
43992
- onClick: togglePlayback,
44086
+ controls: false,
43993
44087
  autoplay: false,
43994
44088
  playsInline: true,
43995
44089
  loop: false,
@@ -45508,8 +45602,8 @@ var IdleTimeReasonChartComponent = ({
45508
45602
  updateAnimation = "replay",
45509
45603
  variant = "pie"
45510
45604
  }) => {
45511
- const [activeData, setActiveData] = React141__default.useState([]);
45512
- React141__default.useEffect(() => {
45605
+ const [activeData, setActiveData] = React142__default.useState([]);
45606
+ React142__default.useEffect(() => {
45513
45607
  if (updateAnimation === "smooth") {
45514
45608
  setActiveData(data && data.length > 0 ? data : []);
45515
45609
  return;
@@ -45528,7 +45622,7 @@ var IdleTimeReasonChartComponent = ({
45528
45622
  setActiveData([]);
45529
45623
  }
45530
45624
  }, [data, updateAnimation]);
45531
- React141__default.useEffect(() => {
45625
+ React142__default.useEffect(() => {
45532
45626
  if (!data || data.length === 0) return;
45533
45627
  data.forEach((entry, index) => {
45534
45628
  if (entry.name.toLowerCase().includes("other")) {
@@ -45536,7 +45630,7 @@ var IdleTimeReasonChartComponent = ({
45536
45630
  }
45537
45631
  });
45538
45632
  }, [data]);
45539
- const pieKey = React141__default.useMemo(() => {
45633
+ const pieKey = React142__default.useMemo(() => {
45540
45634
  if (updateAnimation === "smooth") {
45541
45635
  return "smooth";
45542
45636
  }
@@ -45706,7 +45800,7 @@ var IdleTimeReasonChartComponent = ({
45706
45800
  )
45707
45801
  ] });
45708
45802
  };
45709
- var IdleTimeReasonChart = React141__default.memo(IdleTimeReasonChartComponent);
45803
+ var IdleTimeReasonChart = React142__default.memo(IdleTimeReasonChartComponent);
45710
45804
  IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
45711
45805
  var IdleTimeReasonChart_default = IdleTimeReasonChart;
45712
45806
  var DEFAULT_PERFORMANCE_DATA = {
@@ -46981,10 +47075,17 @@ Underperforming Workspaces: ${lineInfo.metrics.underperforming_workspaces} / ${l
46981
47075
  var LinePdfGenerator = ({
46982
47076
  lineInfo,
46983
47077
  workspaceData,
47078
+ issueResolutionSummary,
46984
47079
  shiftName,
46985
47080
  className
46986
47081
  }) => {
46987
47082
  const [isGenerating, setIsGenerating] = useState(false);
47083
+ const formatResolutionDuration2 = (seconds) => {
47084
+ if (seconds === null || seconds === void 0 || seconds <= 0) {
47085
+ return "-";
47086
+ }
47087
+ return formatIdleTime(Math.max(0, Math.floor(seconds)));
47088
+ };
46988
47089
  const generatePDF = async () => {
46989
47090
  setIsGenerating(true);
46990
47091
  try {
@@ -47324,9 +47425,11 @@ var LinePdfGenerator = ({
47324
47425
  doc.text(`${lineInfo.metrics.current_output} / ${lineInfo.metrics.line_threshold}`, 120, kpiStartY);
47325
47426
  createKPIBox(kpiStartY + kpiSpacing);
47326
47427
  doc.setFont("helvetica", "normal");
47327
- doc.text("Underperforming Workspaces:", 25, kpiStartY + kpiSpacing);
47428
+ doc.text("Average Issue Resolution Time:", 25, kpiStartY + kpiSpacing);
47328
47429
  doc.setFont("helvetica", "bold");
47329
- doc.text(`${lineInfo.metrics.underperforming_workspaces} / ${lineInfo.metrics.total_workspaces}`, 120, kpiStartY + kpiSpacing);
47430
+ const resolutionSeconds = issueResolutionSummary ? issueResolutionSummary.mean_resolution_seconds ?? issueResolutionSummary.median_resolution_seconds : null;
47431
+ const displayValue = resolutionSeconds !== null ? formatResolutionDuration2(resolutionSeconds) : "-";
47432
+ doc.text(displayValue, 120, kpiStartY + kpiSpacing);
47330
47433
  createKPIBox(kpiStartY + kpiSpacing * 2);
47331
47434
  doc.setFont("helvetica", "normal");
47332
47435
  doc.text("Average Efficiency:", 25, kpiStartY + kpiSpacing * 2);
@@ -50064,7 +50167,7 @@ var arePropsEqual = (prevProps, nextProps) => {
50064
50167
  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
50065
50168
  prevProps.position.id === nextProps.position.id;
50066
50169
  };
50067
- var WorkspaceGridItem = React141__default.memo(({
50170
+ var WorkspaceGridItem = React142__default.memo(({
50068
50171
  data,
50069
50172
  position,
50070
50173
  isBottleneck = false,
@@ -50159,7 +50262,7 @@ var WorkspaceGridItem = React141__default.memo(({
50159
50262
  );
50160
50263
  }, arePropsEqual);
50161
50264
  WorkspaceGridItem.displayName = "WorkspaceGridItem";
50162
- var WorkspaceGrid = React141__default.memo(({
50265
+ var WorkspaceGrid = React142__default.memo(({
50163
50266
  workspaces,
50164
50267
  isPdfMode = false,
50165
50268
  customWorkspacePositions,
@@ -50418,7 +50521,7 @@ var KPICard = ({
50418
50521
  }) => {
50419
50522
  useThemeConfig();
50420
50523
  const { formatNumber } = useFormatNumber();
50421
- const trendInfo = React141__default.useMemo(() => {
50524
+ const trendInfo = React142__default.useMemo(() => {
50422
50525
  let trendValue = trend || "neutral";
50423
50526
  if (change !== void 0 && trend === void 0) {
50424
50527
  trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
@@ -50445,7 +50548,7 @@ var KPICard = ({
50445
50548
  const shouldShowTrend = !(change === 0 && trend === void 0);
50446
50549
  return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
50447
50550
  }, [trend, change]);
50448
- const formattedValue = React141__default.useMemo(() => {
50551
+ const formattedValue = React142__default.useMemo(() => {
50449
50552
  if (title === "Quality Compliance" && typeof value === "number") {
50450
50553
  return value.toFixed(1);
50451
50554
  }
@@ -50459,7 +50562,7 @@ var KPICard = ({
50459
50562
  }
50460
50563
  return value;
50461
50564
  }, [value, title]);
50462
- const formattedChange = React141__default.useMemo(() => {
50565
+ const formattedChange = React142__default.useMemo(() => {
50463
50566
  if (change === void 0 || change === 0 && !showZeroChange) return null;
50464
50567
  const absChange = Math.abs(change);
50465
50568
  return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
@@ -50833,6 +50936,7 @@ var WorkspaceHealthCard = ({
50833
50936
  className = "",
50834
50937
  onViewDetails
50835
50938
  }) => {
50939
+ const [copiedIp, setCopiedIp] = useState(false);
50836
50940
  const getStatusConfig = () => {
50837
50941
  switch (workspace.status) {
50838
50942
  case "healthy":
@@ -51007,6 +51111,34 @@ var WorkspaceHealthCard = ({
51007
51111
  /* @__PURE__ */ jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
51008
51112
  ] })
51009
51113
  ] }),
51114
+ workspace.cameraIp ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-2 mt-1.5 -mx-2 rounded-md bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800/60 group/ip transition-colors hover:bg-slate-100/50 dark:hover:bg-slate-800/50", children: [
51115
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
51116
+ /* @__PURE__ */ jsx(Video, { className: "h-3.5 w-3.5 text-slate-400" }),
51117
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium uppercase tracking-wide text-slate-500", children: "Camera IP" })
51118
+ ] }),
51119
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
51120
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-slate-700 dark:text-slate-300 select-all", children: workspace.cameraIp }),
51121
+ /* @__PURE__ */ jsx(
51122
+ "button",
51123
+ {
51124
+ onClick: (e) => {
51125
+ e.stopPropagation();
51126
+ e.preventDefault();
51127
+ navigator.clipboard.writeText(workspace.cameraIp);
51128
+ setCopiedIp(true);
51129
+ setTimeout(() => setCopiedIp(false), 2e3);
51130
+ },
51131
+ className: "p-1 rounded-md text-slate-400 hover:text-slate-600 hover:bg-slate-200 dark:hover:bg-slate-700 dark:hover:text-slate-300 transition-all opacity-0 group-hover/ip:opacity-100 focus:opacity-100",
51132
+ title: "Copy IP address",
51133
+ "aria-label": "Copy IP address",
51134
+ children: copiedIp ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-emerald-500" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" })
51135
+ }
51136
+ )
51137
+ ] })
51138
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 min-h-[1rem]", children: [
51139
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium uppercase tracking-wide text-slate-500", children: "Camera IP:" }),
51140
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: "N/A" })
51141
+ ] }),
51010
51142
  /* @__PURE__ */ jsx("div", { className: "mt-3 pt-3 border-t border-slate-100 dark:border-slate-800", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
51011
51143
  /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-slate-500 uppercase tracking-wide", children: downtimeConfig.label }),
51012
51144
  /* @__PURE__ */ jsx("span", { className: clsx("text-sm font-semibold", downtimeConfig.className), children: downtimeConfig.text })
@@ -51937,7 +52069,7 @@ var Breadcrumbs = ({ items }) => {
51937
52069
  }
51938
52070
  }
51939
52071
  };
51940
- 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(React141__default.Fragment, { children: [
52072
+ 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: [
51941
52073
  index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
51942
52074
  /* @__PURE__ */ jsxs(
51943
52075
  "span",
@@ -52498,7 +52630,11 @@ var SideNavBar = memo$1(({
52498
52630
  dashboardConfig?.supervisorConfig?.enabled || false;
52499
52631
  const showSupervisorManagement = false;
52500
52632
  const ticketsEnabled = dashboardConfig?.ticketsConfig?.enabled ?? true;
52501
- const showBillingLink = canRoleViewClipsCost(role);
52633
+ const canViewBillingByRole = canRoleViewClipsCost(role);
52634
+ const { hasVlmEnabledLine } = useCompanyHasVlmEnabledLine({
52635
+ enabled: canViewBillingByRole
52636
+ });
52637
+ const showBillingLink = canViewBillingByRole && hasVlmEnabledLine;
52502
52638
  console.log("\u{1F50D} [SideNavBar] dashboardConfig:", dashboardConfig);
52503
52639
  console.log("\u{1F50D} [SideNavBar] ticketsConfig:", dashboardConfig?.ticketsConfig);
52504
52640
  console.log("\u{1F50D} [SideNavBar] ticketsEnabled:", ticketsEnabled);
@@ -52697,7 +52833,6 @@ var SideNavBar = memo$1(({
52697
52833
  return prev;
52698
52834
  });
52699
52835
  }, [alertsCount, isAlertsOpen]);
52700
- const unreadCount = alertsCount !== null ? Math.max(0, alertsCount - lastViewedCount) : 0;
52701
52836
  const alertsTriggerRef = useRef(null);
52702
52837
  const alertsCompanyId = entityConfig.companyId || user?.company_id;
52703
52838
  const showAlertsButton = (role === "supervisor" || role === "optifye") && !!alertsCompanyId && !!supabase;
@@ -52837,7 +52972,7 @@ var SideNavBar = memo$1(({
52837
52972
  ${isActive ? "bg-blue-50/80 text-blue-600 font-medium" : "hover:bg-gray-50 text-gray-500 hover:text-gray-700 font-medium active:bg-gray-100"}
52838
52973
  transition-all duration-200 ease-out focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2`;
52839
52974
  }, [isSettingsOpen, settingsItems]);
52840
- const alertsButtonClasses = useMemo(() => {
52975
+ useMemo(() => {
52841
52976
  const isActive = isAlertsOpen;
52842
52977
  return `w-full flex flex-col items-center justify-center py-4 sm:py-3 px-2 sm:px-1 rounded-lg relative group min-h-[44px] sm:min-h-0
52843
52978
  ${isActive ? "bg-blue-50/80 text-blue-600 font-medium" : "hover:bg-gray-50 text-gray-500 hover:text-gray-700 font-medium active:bg-gray-100"}
@@ -52965,54 +53100,25 @@ var SideNavBar = memo$1(({
52965
53100
  )
52966
53101
  ] })
52967
53102
  ] }),
52968
- /* @__PURE__ */ jsxs("div", { className: "w-full py-4 px-4 border-t border-gray-100 flex-shrink-0 flex flex-col gap-2", children: [
52969
- showAlertsButton && /* @__PURE__ */ jsxs(
52970
- "button",
52971
- {
52972
- ref: alertsTriggerRef,
52973
- onClick: () => {
52974
- const willOpen = !isAlertsOpen;
52975
- setIsAlertsOpen(willOpen);
52976
- setIsSettingsOpen(false);
52977
- if (willOpen) {
52978
- trackCoreEvent("Alerts page clicked", { source: "side_nav" });
52979
- void refreshAlertsSummary();
52980
- }
52981
- },
52982
- className: alertsButtonClasses,
52983
- "aria-label": "Alerts",
52984
- tabIndex: 0,
52985
- role: "tab",
52986
- "aria-selected": isAlertsOpen,
52987
- children: [
52988
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
52989
- /* @__PURE__ */ jsx(BellIcon, { className: "w-5 h-5 mb-1" }),
52990
- unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1.5 -right-1.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-red-500 px-1 text-[9px] font-bold text-white shadow-sm ring-2 ring-white", children: unreadCount > 99 ? "99+" : unreadCount })
52991
- ] }),
52992
- /* @__PURE__ */ jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight mt-1", children: "Alerts" })
52993
- ]
52994
- }
52995
- ),
52996
- settingsItems.length > 0 && /* @__PURE__ */ jsxs(
52997
- "button",
52998
- {
52999
- ref: settingsTriggerRef,
53000
- onClick: () => {
53001
- setIsSettingsOpen(!isSettingsOpen);
53002
- setIsAlertsOpen(false);
53003
- },
53004
- className: settingsButtonClasses,
53005
- "aria-label": "Settings",
53006
- tabIndex: 0,
53007
- role: "tab",
53008
- "aria-selected": isSettingsOpen || settingsItems.some((item) => item.isActive),
53009
- children: [
53010
- /* @__PURE__ */ jsx(Cog6ToothIcon, { className: "w-5 h-5 mb-1" }),
53011
- /* @__PURE__ */ jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Settings" })
53012
- ]
53013
- }
53014
- )
53015
- ] })
53103
+ /* @__PURE__ */ jsx("div", { className: "w-full py-4 px-4 border-t border-gray-100 flex-shrink-0 flex flex-col gap-2", children: settingsItems.length > 0 && /* @__PURE__ */ jsxs(
53104
+ "button",
53105
+ {
53106
+ ref: settingsTriggerRef,
53107
+ onClick: () => {
53108
+ setIsSettingsOpen(!isSettingsOpen);
53109
+ setIsAlertsOpen(false);
53110
+ },
53111
+ className: settingsButtonClasses,
53112
+ "aria-label": "Settings",
53113
+ tabIndex: 0,
53114
+ role: "tab",
53115
+ "aria-selected": isSettingsOpen || settingsItems.some((item) => item.isActive),
53116
+ children: [
53117
+ /* @__PURE__ */ jsx(Cog6ToothIcon, { className: "w-5 h-5 mb-1" }),
53118
+ /* @__PURE__ */ jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Settings" })
53119
+ ]
53120
+ }
53121
+ ) })
53016
53122
  ] });
53017
53123
  const MobileNavigationContent = () => {
53018
53124
  const isActive = (path) => {
@@ -53125,26 +53231,6 @@ var SideNavBar = memo$1(({
53125
53231
  /* @__PURE__ */ jsxs("div", { className: "mt-8 pt-6 border-t border-gray-100", children: [
53126
53232
  /* @__PURE__ */ jsx("h3", { className: "px-5 mb-3 text-[10px] font-bold text-gray-400 uppercase tracking-widest", children: "Settings & Support" }),
53127
53233
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
53128
- showAlertsButton && /* @__PURE__ */ jsxs(
53129
- "button",
53130
- {
53131
- onClick: () => {
53132
- setIsAlertsOpen(true);
53133
- trackCoreEvent("Alerts page clicked", { source: "side_nav_mobile" });
53134
- void refreshAlertsSummary();
53135
- onMobileMenuClose?.();
53136
- },
53137
- className: getMobileButtonClass("/alerts"),
53138
- "aria-label": "Alerts",
53139
- children: [
53140
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
53141
- /* @__PURE__ */ jsx(BellIcon, { className: getIconClass("/alerts") }),
53142
- unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1.5 -right-1.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-red-500 px-1 text-[9px] font-bold text-white shadow-sm ring-2 ring-white", children: unreadCount > 99 ? "99+" : unreadCount })
53143
- ] }),
53144
- /* @__PURE__ */ jsx("span", { className: "text-base font-medium ml-3", children: "Alerts" })
53145
- ]
53146
- }
53147
- ),
53148
53234
  canAccessPath("/targets") && /* @__PURE__ */ jsxs(
53149
53235
  "button",
53150
53236
  {
@@ -53459,7 +53545,7 @@ var AwardBadge = ({
53459
53545
  }) => {
53460
53546
  const styles2 = getBadgeStyles(type);
53461
53547
  const Icon2 = CustomIcon || getDefaultIcon(type);
53462
- const randomDelay = React141__default.useMemo(() => Math.random() * 2, []);
53548
+ const randomDelay = React142__default.useMemo(() => Math.random() * 2, []);
53463
53549
  const floatingAnimation = {
53464
53550
  animate: {
53465
53551
  y: [0, -10, 0],
@@ -59374,6 +59460,17 @@ function HomeView({
59374
59460
  }
59375
59461
  return allActiveBreaks.filter((breakItem) => breakItem.lineId === selectedLineId);
59376
59462
  }, [allActiveBreaks, selectedLineId, factoryViewId]);
59463
+ const activeBreakLineIds = useMemo(
59464
+ () => new Set(activeBreaks.map((breakItem) => breakItem.lineId)),
59465
+ [activeBreaks]
59466
+ );
59467
+ const workspaceMetricsWithBreakState = useMemo(
59468
+ () => workspaceMetrics.map((workspace) => ({
59469
+ ...workspace,
59470
+ scheduled_break_active: activeBreakLineIds.has(workspace.line_id)
59471
+ })),
59472
+ [workspaceMetrics, activeBreakLineIds]
59473
+ );
59377
59474
  const [breakNotificationsDismissed, setBreakNotificationsDismissed] = useState(false);
59378
59475
  useEffect(() => {
59379
59476
  if (activeBreaks.length > 0) {
@@ -59848,15 +59945,15 @@ function HomeView({
59848
59945
  ) }) }),
59849
59946
  /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative", children: [
59850
59947
  /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-1 sm:right-6 sm:top-3 z-30 flex items-center space-x-2", children: lineSelectorComponent && lineSelectorComponent }),
59851
- /* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-100px)] sm:min-h-0", children: workspaceMetrics.length > 0 ? /* @__PURE__ */ jsx(
59948
+ /* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-100px)] sm:min-h-0", children: workspaceMetricsWithBreakState.length > 0 ? /* @__PURE__ */ jsx(
59852
59949
  motion.div,
59853
59950
  {
59854
59951
  initial: { opacity: 0, scale: 0.98 },
59855
59952
  animate: { opacity: 1, scale: 1 },
59856
59953
  transition: { duration: 0.3 },
59857
59954
  className: "h-full",
59858
- children: React141__default.createElement(WorkspaceGrid, {
59859
- workspaces: workspaceMetrics,
59955
+ children: React142__default.createElement(WorkspaceGrid, {
59956
+ workspaces: workspaceMetricsWithBreakState,
59860
59957
  lineNames,
59861
59958
  factoryView: factoryViewId,
59862
59959
  legend: efficiencyLegend,
@@ -59886,7 +59983,7 @@ function HomeView({
59886
59983
  animate: { opacity: 1, scale: 1 },
59887
59984
  transition: { duration: 0.3 },
59888
59985
  className: "h-full",
59889
- children: React141__default.createElement(WorkspaceGrid, {
59986
+ children: React142__default.createElement(WorkspaceGrid, {
59890
59987
  workspaces: [],
59891
59988
  // Show empty grid while loading
59892
59989
  lineNames,
@@ -59953,7 +60050,7 @@ function HomeView({
59953
60050
  }
59954
60051
  );
59955
60052
  }
59956
- var AuthenticatedHomeView = withAuth(React141__default.memo(HomeView));
60053
+ var AuthenticatedHomeView = withAuth(React142__default.memo(HomeView));
59957
60054
  var HomeView_default = HomeView;
59958
60055
  function withWorkspaceDisplayNames(Component3, options = {}) {
59959
60056
  const {
@@ -60136,6 +60233,295 @@ var lineDetailStore = {
60136
60233
  }
60137
60234
  };
60138
60235
 
60236
+ // src/lib/hooks/useLineDetailPageData.ts
60237
+ var buildLineInfoSnapshot = (lineDetails, metrics2) => {
60238
+ if (!lineDetails || !metrics2) {
60239
+ return null;
60240
+ }
60241
+ return {
60242
+ line_id: lineDetails.id,
60243
+ line_name: lineDetails.line_name,
60244
+ company_id: "",
60245
+ company_name: "",
60246
+ factory_id: lineDetails.factory_id,
60247
+ factory_name: lineDetails.factory.factory_name,
60248
+ shift_id: metrics2.shift_id ?? 0,
60249
+ date: metrics2.date || "",
60250
+ monitoring_mode: lineDetails.monitoring_mode ?? void 0,
60251
+ metrics: {
60252
+ avg_efficiency: metrics2.avg_efficiency ?? 0,
60253
+ avg_cycle_time: metrics2.avg_cycle_time ?? 0,
60254
+ current_output: metrics2.current_output ?? 0,
60255
+ ideal_output: metrics2.ideal_output ?? 0,
60256
+ total_workspaces: metrics2.total_workspaces ?? 0,
60257
+ underperforming_workspaces: metrics2.underperforming_workspaces ?? 0,
60258
+ underperforming_workspace_names: metrics2.underperforming_workspace_names || [],
60259
+ underperforming_workspace_uuids: metrics2.underperforming_workspace_uuids || [],
60260
+ output_array: metrics2.output_array || [],
60261
+ output_hourly: metrics2.output_hourly,
60262
+ line_threshold: metrics2.line_threshold ?? 0,
60263
+ threshold_pph: metrics2.threshold_pph ?? 0,
60264
+ shift_start: metrics2.shift_start || "06:00",
60265
+ shift_end: metrics2.shift_end || "14:00",
60266
+ last_updated: metrics2.last_updated || (/* @__PURE__ */ new Date()).toISOString(),
60267
+ poorest_performing_workspaces: metrics2.poorest_performing_workspaces || [],
60268
+ idle_time_hourly: metrics2.idle_time_hourly || null
60269
+ }
60270
+ };
60271
+ };
60272
+ var transformWorkspaceMetrics = (workspaceData, lineId, companyId, queryDate, queryShiftId) => (workspaceData || []).map((item) => ({
60273
+ company_id: item.company_id || companyId,
60274
+ line_id: item.line_id || lineId,
60275
+ shift_id: item.shift_id ?? queryShiftId,
60276
+ date: item.date || queryDate,
60277
+ workspace_uuid: item.workspace_id,
60278
+ workspace_name: item.workspace_name,
60279
+ action_count: item.total_output || 0,
60280
+ pph: item.avg_pph || 0,
60281
+ performance_score: item.performance_score || 0,
60282
+ avg_cycle_time: item.avg_cycle_time || 0,
60283
+ trend: item.trend_score === 1 ? 2 : 0,
60284
+ predicted_output: item.ideal_output || 0,
60285
+ efficiency: item.efficiency || 0,
60286
+ action_threshold: item.total_day_output || 0,
60287
+ idle_time: item.idle_time ?? void 0,
60288
+ idle_time_hourly: item.idle_time_hourly || null,
60289
+ shift_start: item.shift_start || void 0,
60290
+ shift_end: item.shift_end || void 0,
60291
+ monitoring_mode: item.monitoring_mode ?? void 0,
60292
+ assembly_enabled: item.assembly_enabled ?? false,
60293
+ video_grid_metric_mode: item.video_grid_metric_mode ?? void 0,
60294
+ action_type: item.action_type ?? void 0,
60295
+ action_family: item.action_family ?? void 0,
60296
+ action_display_name: item.action_display_name ?? void 0,
60297
+ recent_flow_percent: item.recent_flow_percent ?? null,
60298
+ recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
60299
+ recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
60300
+ recent_flow_computed_at: item.recent_flow_computed_at ?? null,
60301
+ incoming_wip_current: item.incoming_wip_current ?? null,
60302
+ incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
60303
+ incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null,
60304
+ show_exclamation: item.show_exclamation ?? void 0
60305
+ })).sort((a, b) => a.workspace_name.localeCompare(b.workspace_name));
60306
+ var transformLineDetails = (lineId, detailResponse) => {
60307
+ if (!detailResponse.line_details) {
60308
+ return null;
60309
+ }
60310
+ return {
60311
+ id: lineId,
60312
+ line_name: detailResponse.line_details.line_name || "Line",
60313
+ factory_id: detailResponse.line_details.factory_id || "",
60314
+ factory: {
60315
+ id: detailResponse.line_details.factory_id || "",
60316
+ factory_name: detailResponse.line_details.factory_name || ""
60317
+ },
60318
+ monitoring_mode: detailResponse.line_details.monitoring_mode ?? void 0
60319
+ };
60320
+ };
60321
+ var transformLineMetrics = (lineId, detailResponse, queryDate, queryShiftId) => {
60322
+ const poorestPerformingWorkspaces = detailResponse.poorest_performing_workspaces || [];
60323
+ const baseMetrics = detailResponse.line_metrics;
60324
+ if (!baseMetrics) {
60325
+ return {
60326
+ line_id: lineId,
60327
+ shift_id: queryShiftId,
60328
+ date: queryDate,
60329
+ factory_id: detailResponse.line_details?.factory_id || "",
60330
+ avg_efficiency: 0,
60331
+ avg_cycle_time: 0,
60332
+ current_output: 0,
60333
+ ideal_output: 0,
60334
+ total_workspaces: 0,
60335
+ underperforming_workspaces: 0,
60336
+ underperforming_workspace_names: [],
60337
+ underperforming_workspace_uuids: [],
60338
+ output_array: [],
60339
+ line_threshold: 0,
60340
+ threshold_pph: 0,
60341
+ shift_start: "06:00",
60342
+ shift_end: "14:00",
60343
+ last_updated: (/* @__PURE__ */ new Date()).toISOString(),
60344
+ poorest_performing_workspaces: poorestPerformingWorkspaces,
60345
+ idle_time_hourly: {}
60346
+ };
60347
+ }
60348
+ return {
60349
+ ...baseMetrics,
60350
+ line_id: lineId,
60351
+ shift_id: baseMetrics.shift_id ?? queryShiftId,
60352
+ date: baseMetrics.date ?? queryDate,
60353
+ factory_id: baseMetrics.factory_id ?? detailResponse.line_details?.factory_id ?? "",
60354
+ poorest_performing_workspaces: poorestPerformingWorkspaces
60355
+ };
60356
+ };
60357
+ var useLineDetailPageData = ({
60358
+ lineId,
60359
+ companyId,
60360
+ timezone,
60361
+ shiftConfig,
60362
+ date: urlDate,
60363
+ shiftId: urlShiftId,
60364
+ enabled = true
60365
+ }) => {
60366
+ const supabase = useSupabase();
60367
+ const { hydrateFromBackend } = useIdleTimeVlmConfig();
60368
+ const realtimeEnabled = enabled && urlDate === void 0 && urlShiftId === void 0;
60369
+ const { shiftKey: operationalShiftKey } = useOperationalShiftKey({
60370
+ enabled: realtimeEnabled,
60371
+ timezone,
60372
+ shiftConfig: shiftConfig || void 0
60373
+ });
60374
+ const currentShift = useMemo(
60375
+ () => shiftConfig ? getCurrentShift(timezone, shiftConfig) : null,
60376
+ [timezone, shiftConfig, operationalShiftKey]
60377
+ );
60378
+ const queryShiftId = useMemo(
60379
+ () => urlShiftId !== void 0 ? urlShiftId : currentShift?.shiftId ?? 0,
60380
+ [urlShiftId, currentShift]
60381
+ );
60382
+ const queryDate = useMemo(
60383
+ () => urlDate || getOperationalDate(timezone),
60384
+ [urlDate, timezone]
60385
+ );
60386
+ const [detailResponse, setDetailResponse] = useState(null);
60387
+ const [loading, setLoading] = useState(true);
60388
+ const [error, setError] = useState(null);
60389
+ const channelsRef = useRef([]);
60390
+ const requestIdRef = useRef(0);
60391
+ const fetchTimeoutRef = useRef(null);
60392
+ const fetchDetail = useCallback(async () => {
60393
+ if (!enabled || !supabase || !lineId || !companyId) {
60394
+ setLoading(false);
60395
+ if (!companyId) {
60396
+ setError({ message: "Company ID is not configured", code: "CONFIG_ERROR" });
60397
+ }
60398
+ return;
60399
+ }
60400
+ const requestId = requestIdRef.current + 1;
60401
+ requestIdRef.current = requestId;
60402
+ setLoading(true);
60403
+ setError(null);
60404
+ try {
60405
+ const nextDetail = await fetchLineDetail(supabase, {
60406
+ lineId,
60407
+ date: queryDate,
60408
+ shiftId: queryShiftId,
60409
+ companyId
60410
+ });
60411
+ if (requestId !== requestIdRef.current) {
60412
+ return;
60413
+ }
60414
+ hydrateFromBackend(nextDetail?.idle_time_vlm_by_line);
60415
+ setDetailResponse(nextDetail);
60416
+ const metrics3 = transformLineMetrics(lineId, nextDetail, queryDate, queryShiftId);
60417
+ const lineDetails2 = transformLineDetails(lineId, nextDetail);
60418
+ const workspaces2 = transformWorkspaceMetrics(
60419
+ nextDetail.workspace_metrics || [],
60420
+ lineId,
60421
+ companyId,
60422
+ queryDate,
60423
+ queryShiftId
60424
+ );
60425
+ const lineInfo2 = buildLineInfoSnapshot(lineDetails2, metrics3);
60426
+ if (lineInfo2) {
60427
+ lineDetailStore.setSnapshot(lineId, lineInfo2.date, lineInfo2.shift_id, {
60428
+ lineInfo: lineInfo2,
60429
+ workspaces: workspaces2
60430
+ });
60431
+ }
60432
+ } catch (err) {
60433
+ if (requestId !== requestIdRef.current) {
60434
+ return;
60435
+ }
60436
+ setError({ message: err.message, code: err.code || "FETCH_ERROR" });
60437
+ } finally {
60438
+ if (requestId === requestIdRef.current) {
60439
+ setLoading(false);
60440
+ }
60441
+ }
60442
+ }, [enabled, supabase, lineId, companyId, queryDate, queryShiftId, hydrateFromBackend]);
60443
+ const queueUpdate = useCallback(() => {
60444
+ if (fetchTimeoutRef.current) {
60445
+ clearTimeout(fetchTimeoutRef.current);
60446
+ }
60447
+ fetchTimeoutRef.current = setTimeout(() => {
60448
+ fetchDetail();
60449
+ fetchTimeoutRef.current = null;
60450
+ }, 300);
60451
+ }, [fetchDetail]);
60452
+ useEffect(() => {
60453
+ if (!enabled) {
60454
+ setLoading(false);
60455
+ return;
60456
+ }
60457
+ fetchDetail();
60458
+ }, [enabled, fetchDetail]);
60459
+ useEffect(() => {
60460
+ channelsRef.current.forEach((channel) => {
60461
+ supabase.removeChannel(channel);
60462
+ });
60463
+ channelsRef.current = [];
60464
+ if (!supabase || !companyId || !lineId || !realtimeEnabled) {
60465
+ return;
60466
+ }
60467
+ const metricsTable = `${getMetricsTablePrefix()}_${companyId.replace(/-/g, "_")}`;
60468
+ const timestamp = Date.now();
60469
+ const currentDate = queryDate;
60470
+ const currentShiftId = queryShiftId;
60471
+ const lineFilter = `line_id=eq.${lineId}`;
60472
+ const createChannel = (name, table, filter2) => supabase.channel(`${name}-${timestamp}`).on(
60473
+ "postgres_changes",
60474
+ { event: "*", schema: "public", table, filter: filter2 },
60475
+ (payload) => {
60476
+ const payloadData = payload.new || payload.old;
60477
+ if (payloadData?.date !== currentDate || payloadData?.shift_id !== currentShiftId) {
60478
+ return;
60479
+ }
60480
+ queueUpdate();
60481
+ }
60482
+ ).subscribe();
60483
+ channelsRef.current = [
60484
+ createChannel("line-detail-line-metrics", "line_metrics", lineFilter),
60485
+ createChannel("line-detail-performance-metrics", metricsTable, lineFilter),
60486
+ createChannel("line-detail-wip-buffer-metrics", "wip_buffer_metrics", lineFilter)
60487
+ ];
60488
+ return () => {
60489
+ if (fetchTimeoutRef.current) {
60490
+ clearTimeout(fetchTimeoutRef.current);
60491
+ fetchTimeoutRef.current = null;
60492
+ }
60493
+ channelsRef.current.forEach((channel) => {
60494
+ supabase.removeChannel(channel);
60495
+ });
60496
+ channelsRef.current = [];
60497
+ };
60498
+ }, [supabase, companyId, lineId, realtimeEnabled, queryDate, queryShiftId, queueUpdate]);
60499
+ const metrics2 = useMemo(
60500
+ () => detailResponse ? transformLineMetrics(lineId, detailResponse, queryDate, queryShiftId) : null,
60501
+ [detailResponse, lineId, queryDate, queryShiftId]
60502
+ );
60503
+ const lineDetails = useMemo(
60504
+ () => detailResponse ? transformLineDetails(lineId, detailResponse) : null,
60505
+ [detailResponse, lineId]
60506
+ );
60507
+ const workspaces = useMemo(
60508
+ () => detailResponse && companyId ? transformWorkspaceMetrics(detailResponse.workspace_metrics || [], lineId, companyId, queryDate, queryShiftId) : [],
60509
+ [detailResponse, companyId, lineId, queryDate, queryShiftId]
60510
+ );
60511
+ const lineInfo = useMemo(() => buildLineInfoSnapshot(lineDetails, metrics2), [lineDetails, metrics2]);
60512
+ return {
60513
+ detailResponse,
60514
+ lineDetails,
60515
+ metrics: metrics2,
60516
+ workspaces,
60517
+ lineInfo,
60518
+ issueResolutionSummary: detailResponse?.issue_resolution_summary ?? null,
60519
+ loading,
60520
+ error,
60521
+ refresh: () => fetchDetail()
60522
+ };
60523
+ };
60524
+
60139
60525
  // src/lib/services/efficiencyLegendService.ts
60140
60526
  var EfficiencyLegendService = class {
60141
60527
  // 5 minutes
@@ -60730,21 +61116,45 @@ var formatLocalDate = (date) => {
60730
61116
  };
60731
61117
  return date.toLocaleDateString("en-US", options);
60732
61118
  };
61119
+ var formatResolutionDuration = (seconds) => {
61120
+ if (seconds === null || seconds === void 0 || seconds <= 0) {
61121
+ return "-";
61122
+ }
61123
+ return formatIdleTime(Math.max(0, Math.floor(seconds)));
61124
+ };
61125
+ var getIssueResolutionSecondaryText = (summary) => {
61126
+ if (!summary) {
61127
+ return "No issue data";
61128
+ }
61129
+ const parts = [`${summary.resolved_issue_count} resolved`];
61130
+ if ((summary.open_issue_count || 0) > 0) {
61131
+ parts.push(`oldest open ${formatResolutionDuration(summary.oldest_open_issue_age_seconds)}`);
61132
+ }
61133
+ return parts.join(" \u2022 ");
61134
+ };
60733
61135
  var MetricCards = memo$1(({
60734
61136
  lineInfo,
61137
+ issueResolutionSummary,
60735
61138
  idleTimeData,
60736
61139
  showIdleTime,
60737
61140
  efficiencyLegend
60738
61141
  }) => {
60739
61142
  const efficiency = lineInfo?.metrics.avg_efficiency || 0;
60740
61143
  const efficiencyColorClass = getEfficiencyTextColorClasses(efficiency, efficiencyLegend);
61144
+ const showIssueResolutionCard = Boolean(issueResolutionSummary);
61145
+ const largeGridColumns = showIdleTime ? showIssueResolutionCard ? "lg:grid-cols-5" : "lg:grid-cols-4" : showIssueResolutionCard ? "lg:grid-cols-4" : "lg:grid-cols-3";
61146
+ const shouldMaskIssueResolution = efficiency < 5;
61147
+ const issueResolutionValue = shouldMaskIssueResolution ? "-" : formatResolutionDuration(
61148
+ issueResolutionSummary?.mean_resolution_seconds ?? issueResolutionSummary?.median_resolution_seconds
61149
+ );
61150
+ getIssueResolutionSecondaryText(issueResolutionSummary);
60741
61151
  return /* @__PURE__ */ jsxs(
60742
61152
  motion.div,
60743
61153
  {
60744
61154
  variants: containerVariants,
60745
61155
  initial: "initial",
60746
61156
  animate: "animate",
60747
- className: `grid grid-cols-1 sm:grid-cols-2 ${showIdleTime ? "lg:grid-cols-4" : "lg:grid-cols-3"} gap-3 sm:gap-4 mb-2 h-auto lg:flex-[2] lg:min-h-[250px]`,
61157
+ className: `grid grid-cols-1 sm:grid-cols-2 ${largeGridColumns} gap-3 sm:gap-4 mb-2 h-auto lg:flex-[2] lg:min-h-[250px]`,
60748
61158
  children: [
60749
61159
  /* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
60750
61160
  /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 mb-2 text-center", children: "Line Output" }),
@@ -60768,11 +61178,33 @@ var MetricCards = memo$1(({
60768
61178
  ] }),
60769
61179
  /* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
60770
61180
  /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center mb-2", children: "Average Efficiency" }),
60771
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100%-2.5rem)]", children: /* @__PURE__ */ jsxs("span", { className: `text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold ${efficiencyColorClass}`, children: [
61181
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100%-2.5rem)]", children: /* @__PURE__ */ jsxs("span", { className: `whitespace-nowrap tracking-tight text-3xl sm:text-4xl md:text-5xl lg:text-5xl xl:text-5xl 2xl:text-6xl font-bold ${efficiencyColorClass}`, children: [
60772
61182
  efficiency.toFixed(1),
60773
61183
  "%"
60774
61184
  ] }) })
60775
61185
  ] }),
61186
+ showIssueResolutionCard && /* @__PURE__ */ jsxs(
61187
+ motion.div,
61188
+ {
61189
+ variants: itemVariants,
61190
+ className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 h-[240px] sm:h-[260px] md:h-auto",
61191
+ children: [
61192
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-1.5 mb-2 relative group z-10", children: [
61193
+ /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700", children: "Average Issue Resolution Time" }),
61194
+ /* @__PURE__ */ jsx(InformationCircleIcon, { className: "w-4 h-4 text-gray-400 cursor-help" }),
61195
+ /* @__PURE__ */ jsxs("div", { className: "absolute top-full left-1/2 transform -translate-x-1/2 mt-2.5 w-[260px] p-3 bg-white rounded-lg shadow-xl border border-gray-200 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 pointer-events-none z-50", children: [
61196
+ /* @__PURE__ */ jsx("p", { className: "text-center text-xs text-gray-600 leading-relaxed mb-2.5 px-1", children: "The average time a supervisor takes to resolve a workstation in red." }),
61197
+ /* @__PURE__ */ jsx("div", { className: "bg-gray-50 rounded-md py-1.5 border border-gray-100/80", children: /* @__PURE__ */ jsxs("p", { className: "text-center font-medium text-[11px] text-gray-500", children: [
61198
+ ((issueResolutionSummary?.resolved_issue_count || 0) + (issueResolutionSummary?.open_issue_count || 0)).toLocaleString(),
61199
+ " recorded issues"
61200
+ ] }) }),
61201
+ /* @__PURE__ */ jsx("div", { className: "absolute -top-1.5 left-1/2 transform -translate-x-1/2 w-3 h-3 bg-white border-l border-t border-gray-200 rotate-45" })
61202
+ ] })
61203
+ ] }),
61204
+ /* @__PURE__ */ jsx("div", { className: "h-[calc(100%-2.5rem)] flex flex-col items-center justify-center gap-3", children: /* @__PURE__ */ jsx("span", { className: `whitespace-nowrap tracking-tight text-3xl sm:text-4xl md:text-5xl lg:text-5xl xl:text-5xl 2xl:text-6xl font-bold ${shouldMaskIssueResolution ? "text-gray-400" : "text-gray-900"}`, children: issueResolutionValue }) })
61205
+ ]
61206
+ }
61207
+ ),
60776
61208
  showIdleTime && /* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
60777
61209
  /* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center mb-2", children: "Idle Time Breakdown" }),
60778
61210
  /* @__PURE__ */ jsx("div", { className: "h-[calc(100%-2.5rem)]", children: /* @__PURE__ */ jsx(
@@ -60793,6 +61225,8 @@ var MetricCards = memo$1(({
60793
61225
  if (prevProps.efficiencyLegend !== nextProps.efficiencyLegend) return false;
60794
61226
  const prevMetrics = prevProps.lineInfo.metrics;
60795
61227
  const nextMetrics = nextProps.lineInfo.metrics;
61228
+ const prevIssueSummary = prevProps.issueResolutionSummary;
61229
+ const nextIssueSummary = nextProps.issueResolutionSummary;
60796
61230
  const prevIdleChartSignature = JSON.stringify(
60797
61231
  (prevProps.idleTimeData?.chartData || []).map((entry) => ({
60798
61232
  name: entry.name,
@@ -60811,6 +61245,9 @@ var MetricCards = memo$1(({
60811
61245
  );
60812
61246
  const idleTimeChanged = prevProps.idleTimeData?.isLoading !== nextProps.idleTimeData?.isLoading || prevProps.idleTimeData?.error !== nextProps.idleTimeData?.error || prevIdleChartSignature !== nextIdleChartSignature || prevProps.idleTimeData?.data?.total_idle_time_seconds !== nextProps.idleTimeData?.data?.total_idle_time_seconds || prevProps.idleTimeData?.data?.scope_work_seconds !== nextProps.idleTimeData?.data?.scope_work_seconds;
60813
61247
  if (idleTimeChanged) return false;
61248
+ if (prevIssueSummary?.mean_resolution_seconds !== nextIssueSummary?.mean_resolution_seconds || prevIssueSummary?.median_resolution_seconds !== nextIssueSummary?.median_resolution_seconds || prevIssueSummary?.resolved_issue_count !== nextIssueSummary?.resolved_issue_count || prevIssueSummary?.open_issue_count !== nextIssueSummary?.open_issue_count || prevIssueSummary?.oldest_open_issue_age_seconds !== nextIssueSummary?.oldest_open_issue_age_seconds || prevIssueSummary?.total_issue_seconds !== nextIssueSummary?.total_issue_seconds) {
61249
+ return false;
61250
+ }
60814
61251
  return prevMetrics.current_output === nextMetrics.current_output && prevMetrics.line_threshold === nextMetrics.line_threshold && prevMetrics.underperforming_workspaces === nextMetrics.underperforming_workspaces && prevMetrics.total_workspaces === nextMetrics.total_workspaces && prevMetrics.avg_efficiency === nextMetrics.avg_efficiency;
60815
61252
  });
60816
61253
  MetricCards.displayName = "MetricCards";
@@ -61317,11 +61754,16 @@ var KPIDetailView = ({
61317
61754
  const {
61318
61755
  metrics: metrics2,
61319
61756
  lineDetails,
61320
- loading: lineMetricsLoading,
61321
- error: lineMetricsError,
61322
- refreshMetrics
61323
- } = useRealtimeLineMetrics({
61757
+ workspaces,
61758
+ issueResolutionSummary,
61759
+ loading: lineDetailLoading,
61760
+ error: lineDetailError,
61761
+ refresh: refreshLineDetail
61762
+ } = useLineDetailPageData({
61324
61763
  lineId,
61764
+ companyId: resolvedCompanyId,
61765
+ timezone: configuredTimezone,
61766
+ shiftConfig,
61325
61767
  date: typeof urlDate === "string" ? urlDate : void 0,
61326
61768
  shiftId: parsedShiftId,
61327
61769
  enabled: !isShiftConfigLoading && (!historicalRouteRequested || historicalParamsReady)
@@ -61329,16 +61771,11 @@ var KPIDetailView = ({
61329
61771
  const resolvedMonitoringMode = lineDetails?.monitoring_mode ?? "output";
61330
61772
  const isUptimeMode = resolvedMonitoringMode === "uptime";
61331
61773
  const overviewTabLabel = isUptimeMode ? "Utilization" : "Efficiency";
61332
- const {
61333
- workspaces,
61334
- loading: workspacesLoading,
61335
- error: workspacesError,
61336
- refreshWorkspaces
61337
- } = useLineWorkspaceMetrics(lineId, {
61338
- initialDate: typeof urlDate === "string" ? urlDate : void 0,
61339
- initialShiftId: parsedShiftId,
61340
- enabled: !isShiftConfigLoading && (!historicalRouteRequested || historicalParamsReady)
61341
- });
61774
+ const lineMetricsLoading = lineDetailLoading;
61775
+ const workspacesLoading = lineDetailLoading;
61776
+ const lineMetricsError = lineDetailError;
61777
+ const workspacesError = lineDetailError;
61778
+ const refreshMetrics = refreshLineDetail;
61342
61779
  const idleTimeDate = historicalRouteRequested ? historicalParamsReady ? urlDate : void 0 : typeof urlDate === "string" ? urlDate : metrics2?.date || cachedLineInfo?.date;
61343
61780
  const idleTimeShiftId = historicalRouteRequested ? historicalParamsReady ? parsedShiftId : void 0 : parsedShiftId ?? metrics2?.shift_id ?? cachedLineInfo?.shift_id;
61344
61781
  const idleTimeEnabled = activeTab === "overview" && !!lineId && idleTimeVlmEnabled && !!idleTimeDate && idleTimeShiftId !== void 0 && (!historicalRouteRequested || historicalParamsReady);
@@ -62054,7 +62491,6 @@ var KPIDetailView = ({
62054
62491
  {
62055
62492
  onClick: () => {
62056
62493
  refreshMetrics();
62057
- refreshWorkspaces();
62058
62494
  },
62059
62495
  className: "mt-4 px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
62060
62496
  children: "Try Again"
@@ -62081,7 +62517,7 @@ var KPIDetailView = ({
62081
62517
  return /* @__PURE__ */ jsx(LoadingPage, { message: "Processing line data..." });
62082
62518
  }
62083
62519
  return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
62084
- /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
62520
+ /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
62085
62521
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
62086
62522
  /* @__PURE__ */ jsx(
62087
62523
  "button",
@@ -62257,7 +62693,7 @@ var KPIDetailView = ({
62257
62693
  )
62258
62694
  ] }),
62259
62695
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 ml-auto", children: [
62260
- resolvedLineInfo && activeTab === "overview" && /* @__PURE__ */ jsx(LinePdfGenerator, { lineInfo: resolvedLineInfo, workspaceData: resolvedWorkspaces || [], shiftName: getShiftName(resolvedLineInfo.shift_id) }),
62696
+ resolvedLineInfo && activeTab === "overview" && /* @__PURE__ */ jsx(LinePdfGenerator, { lineInfo: resolvedLineInfo, workspaceData: resolvedWorkspaces || [], issueResolutionSummary, shiftName: getShiftName(resolvedLineInfo.shift_id) }),
62261
62697
  activeTab === "monthly_history" && !urlDate && !urlShift && /* @__PURE__ */ jsxs(Fragment, { children: [
62262
62698
  /* @__PURE__ */ jsx(
62263
62699
  MonthlyRangeFilter_default,
@@ -62316,6 +62752,7 @@ var KPIDetailView = ({
62316
62752
  MetricCards,
62317
62753
  {
62318
62754
  lineInfo: resolvedLineInfo,
62755
+ issueResolutionSummary,
62319
62756
  idleTimeData,
62320
62757
  showIdleTime: idleTimeVlmEnabled,
62321
62758
  efficiencyLegend
@@ -62413,6 +62850,7 @@ var KPIDetailView = ({
62413
62850
  MetricCards,
62414
62851
  {
62415
62852
  lineInfo: resolvedLineInfo,
62853
+ issueResolutionSummary,
62416
62854
  idleTimeData,
62417
62855
  showIdleTime: idleTimeVlmEnabled,
62418
62856
  efficiencyLegend
@@ -62582,18 +63020,18 @@ var LinesLeaderboard = ({
62582
63020
  isHistoricalDaily
62583
63021
  }) => {
62584
63022
  const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
62585
- const assignedLineIdSet = React141__default.useMemo(
63023
+ const assignedLineIdSet = React142__default.useMemo(
62586
63024
  () => new Set(assignedLineIds || []),
62587
63025
  [assignedLineIds]
62588
63026
  );
62589
- const canClickLine = React141__default.useCallback(
63027
+ const canClickLine = React142__default.useCallback(
62590
63028
  (lineId) => {
62591
63029
  if (!assignedLineIds) return true;
62592
63030
  return assignedLineIdSet.has(lineId);
62593
63031
  },
62594
63032
  [assignedLineIds, assignedLineIdSet]
62595
63033
  );
62596
- const handleTimeRangeChange = React141__default.useCallback((newRange) => {
63034
+ const handleTimeRangeChange = React142__default.useCallback((newRange) => {
62597
63035
  if (newRange === timeRange) return;
62598
63036
  trackCoreEvent("Leaderboard Time Range Changed", {
62599
63037
  from_range: timeRange,
@@ -62604,7 +63042,7 @@ var LinesLeaderboard = ({
62604
63042
  });
62605
63043
  setTimeRange(newRange);
62606
63044
  }, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
62607
- const handleLeaderboardLineClick = React141__default.useCallback((item, clickSource) => {
63045
+ const handleLeaderboardLineClick = React142__default.useCallback((item, clickSource) => {
62608
63046
  if (!canClickLine(item.line.id)) return;
62609
63047
  trackCoreEvent("Leaderboard Line Clicked", {
62610
63048
  line_id: item.line.id,
@@ -62618,8 +63056,8 @@ var LinesLeaderboard = ({
62618
63056
  });
62619
63057
  onLineClick(item.line);
62620
63058
  }, [canClickLine, onLineClick, timeRange]);
62621
- const viewLoadedTrackedRef = React141__default.useRef(null);
62622
- const leaderboardData = React141__default.useMemo(() => {
63059
+ const viewLoadedTrackedRef = React142__default.useRef(null);
63060
+ const leaderboardData = React142__default.useMemo(() => {
62623
63061
  const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
62624
63062
  const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
62625
63063
  return lines.map((line) => {
@@ -62650,7 +63088,7 @@ var LinesLeaderboard = ({
62650
63088
  isLoadingToday,
62651
63089
  isLoadingMonthly
62652
63090
  ]);
62653
- React141__default.useEffect(() => {
63091
+ React142__default.useEffect(() => {
62654
63092
  const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
62655
63093
  const trackingKey = `${timeRange}-${leaderboardData.length}`;
62656
63094
  if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
@@ -62676,7 +63114,7 @@ var LinesLeaderboard = ({
62676
63114
  const countdownFormat = timeRange === "monthly" ? "days" : "clock";
62677
63115
  const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift Ended";
62678
63116
  const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
62679
- const handleCountdownFinished = React141__default.useCallback(() => {
63117
+ const handleCountdownFinished = React142__default.useCallback(() => {
62680
63118
  trackCoreEvent("Leaderboard Countdown Finished", {
62681
63119
  countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
62682
63120
  time_range: timeRange,
@@ -62703,7 +63141,7 @@ var LinesLeaderboard = ({
62703
63141
  return "bg-white border-gray-100";
62704
63142
  }
62705
63143
  };
62706
- React141__default.useEffect(() => {
63144
+ React142__default.useEffect(() => {
62707
63145
  const style = document.createElement("style");
62708
63146
  style.innerHTML = `
62709
63147
  @keyframes float {
@@ -62890,7 +63328,7 @@ var LineCard = ({
62890
63328
  supervisors
62891
63329
  }) => {
62892
63330
  const isUptimeLine = (line.monitoring_mode ?? "output") === "uptime";
62893
- const isOnTrack = React141__default.useMemo(() => {
63331
+ const isOnTrack = React142__default.useMemo(() => {
62894
63332
  if (!kpis) return null;
62895
63333
  return isEfficiencyOnTrack(kpis.efficiency.value);
62896
63334
  }, [kpis]);
@@ -63048,6 +63486,9 @@ var KPIsOverviewView = ({
63048
63486
  const [selectedLeaderboardShiftId, setSelectedLeaderboardShiftId] = useState(0);
63049
63487
  const [hasHydratedLeaderboardRouteState, setHasHydratedLeaderboardRouteState] = useState(false);
63050
63488
  const [loading, setLoading] = useState(true);
63489
+ const [isFilterOpen, setIsFilterOpen] = useState(false);
63490
+ const filterRef = useRef(null);
63491
+ const filterButtonRef = useRef(null);
63051
63492
  const [error, setError] = useState(null);
63052
63493
  const [topPerformer, setTopPerformer] = useState({
63053
63494
  name: "Top Performer",
@@ -63085,46 +63526,46 @@ var KPIsOverviewView = ({
63085
63526
  const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
63086
63527
  const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
63087
63528
  const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
63088
- const scopedLineIds = React141__default.useMemo(
63529
+ const scopedLineIds = React142__default.useMemo(
63089
63530
  () => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
63090
63531
  [user?.access_scope?.line_ids]
63091
63532
  );
63092
63533
  const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
63093
63534
  const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
63094
63535
  const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
63095
- const resolvedAssignedLineIds = React141__default.useMemo(() => {
63536
+ const resolvedAssignedLineIds = React142__default.useMemo(() => {
63096
63537
  if (isSuperAdmin) return [];
63097
63538
  if (scopedLineIds.length > 0) return scopedLineIds;
63098
63539
  if (lineIds && lineIds.length > 0) return lineIds;
63099
63540
  if (isStrictLineScopedRole && hasCanonicalScope) return [];
63100
63541
  return [];
63101
63542
  }, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
63102
- const assignedLineIdSet = React141__default.useMemo(
63543
+ const assignedLineIdSet = React142__default.useMemo(
63103
63544
  () => new Set(resolvedAssignedLineIds),
63104
63545
  [resolvedAssignedLineIds]
63105
63546
  );
63106
- const metricsLineIds = React141__default.useMemo(() => {
63547
+ const metricsLineIds = React142__default.useMemo(() => {
63107
63548
  if (isSuperAdmin) {
63108
63549
  return lineIds ?? [];
63109
63550
  }
63110
63551
  return resolvedAssignedLineIds;
63111
63552
  }, [isSuperAdmin, lineIds, resolvedAssignedLineIds]);
63112
63553
  const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
63113
- const leaderboardLinesForView = React141__default.useMemo(() => {
63554
+ const leaderboardLinesForView = React142__default.useMemo(() => {
63114
63555
  const targetMode = viewType === "machine" ? "uptime" : "output";
63115
63556
  return leaderboardLines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
63116
63557
  }, [leaderboardLines, viewType]);
63117
- const linesForView = React141__default.useMemo(() => {
63558
+ const linesForView = React142__default.useMemo(() => {
63118
63559
  const targetMode = viewType === "machine" ? "uptime" : "output";
63119
63560
  return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
63120
63561
  }, [lines, viewType]);
63121
- const relevantLinesForMode = React141__default.useMemo(() => {
63562
+ const relevantLinesForMode = React142__default.useMemo(() => {
63122
63563
  if (activeTab === "leaderboard") {
63123
63564
  return leaderboardLines.length > 0 ? leaderboardLines : lines;
63124
63565
  }
63125
63566
  return lines;
63126
63567
  }, [activeTab, leaderboardLines, lines]);
63127
- const { hasUptime, hasOutput } = React141__default.useMemo(() => {
63568
+ const { hasUptime, hasOutput } = React142__default.useMemo(() => {
63128
63569
  let uptime = false;
63129
63570
  let output = false;
63130
63571
  for (const line of relevantLinesForMode) {
@@ -63149,11 +63590,32 @@ var KPIsOverviewView = ({
63149
63590
  const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
63150
63591
  const currentShiftDate = currentShiftDetails.date;
63151
63592
  const currentShiftId = currentShiftDetails.shiftId;
63152
- const shiftEndDate = React141__default.useMemo(
63593
+ const activeFiltersCount = React142__default.useMemo(() => {
63594
+ let count = 0;
63595
+ if (selectedLeaderboardShiftId !== currentShiftId) {
63596
+ count++;
63597
+ }
63598
+ return count;
63599
+ }, [selectedLeaderboardShiftId, currentShiftId]);
63600
+ const clearFilters = React142__default.useCallback(() => {
63601
+ setSelectedLeaderboardShiftId(currentShiftId);
63602
+ }, [currentShiftId]);
63603
+ useEffect(() => {
63604
+ const handleClickOutside = (event) => {
63605
+ const target = event.target;
63606
+ if (filterButtonRef.current?.contains(target)) return;
63607
+ if (filterRef.current && !filterRef.current.contains(target)) {
63608
+ setIsFilterOpen(false);
63609
+ }
63610
+ };
63611
+ document.addEventListener("mousedown", handleClickOutside);
63612
+ return () => document.removeEventListener("mousedown", handleClickOutside);
63613
+ }, []);
63614
+ const shiftEndDate = React142__default.useMemo(
63153
63615
  () => getShiftEndDate(currentShiftDetails, configuredTimezone),
63154
63616
  [currentShiftDetails, configuredTimezone]
63155
63617
  );
63156
- const leaderboardShiftOptions = React141__default.useMemo(() => {
63618
+ const leaderboardShiftOptions = React142__default.useMemo(() => {
63157
63619
  if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
63158
63620
  return shiftConfig.shifts.map((shift) => ({
63159
63621
  id: shift.shiftId,
@@ -63233,15 +63695,15 @@ var KPIsOverviewView = ({
63233
63695
  lineId: factoryViewId,
63234
63696
  userAccessibleLineIds: metricsLineIds
63235
63697
  });
63236
- const defaultKPIs = React141__default.useMemo(() => createDefaultKPIs(), []);
63237
- const kpisByLineId = React141__default.useMemo(() => {
63698
+ const defaultKPIs = React142__default.useMemo(() => createDefaultKPIs(), []);
63699
+ const kpisByLineId = React142__default.useMemo(() => {
63238
63700
  const map = /* @__PURE__ */ new Map();
63239
63701
  lineMetrics.forEach((row) => {
63240
63702
  if (row?.line_id) map.set(row.line_id, buildKPIsFromLineMetricsRow(row));
63241
63703
  });
63242
63704
  return map;
63243
63705
  }, [lineMetrics]);
63244
- const supervisorLineIds = React141__default.useMemo(
63706
+ const supervisorLineIds = React142__default.useMemo(
63245
63707
  () => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
63246
63708
  [leaderboardLines, lines]
63247
63709
  );
@@ -63604,7 +64066,7 @@ var KPIsOverviewView = ({
63604
64066
  }
63605
64067
  if (error) {
63606
64068
  return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
63607
- /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
64069
+ /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
63608
64070
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
63609
64071
  mobileMenuContext && /* @__PURE__ */ jsx(
63610
64072
  HamburgerButton,
@@ -63640,7 +64102,7 @@ var KPIsOverviewView = ({
63640
64102
  }
63641
64103
  if (lines.length === 0) {
63642
64104
  return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
63643
- /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
64105
+ /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
63644
64106
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
63645
64107
  mobileMenuContext && /* @__PURE__ */ jsx(
63646
64108
  HamburgerButton,
@@ -63678,7 +64140,7 @@ var KPIsOverviewView = ({
63678
64140
  ] });
63679
64141
  }
63680
64142
  return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
63681
- /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
64143
+ /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
63682
64144
  /* @__PURE__ */ jsxs("div", { className: "sm:hidden", children: [
63683
64145
  /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
63684
64146
  mobileMenuContext && /* @__PURE__ */ jsx(
@@ -63690,12 +64152,7 @@ var KPIsOverviewView = ({
63690
64152
  ),
63691
64153
  /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
63692
64154
  /* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900", children: activeTab === "leaderboard" ? "Leaderboard" : "Overview" }),
63693
- /* @__PURE__ */ jsx(
63694
- "div",
63695
- {
63696
- className: `h-2 w-2 rounded-full ring-2 ${showHistoricalLeaderboardHeader ? "bg-amber-500 ring-amber-500/20" : "bg-emerald-500 animate-pulse ring-emerald-500/20"}`
63697
- }
63698
- )
64155
+ !showHistoricalLeaderboardHeader && /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-emerald-500 animate-pulse ring-2 ring-emerald-500/20" })
63699
64156
  ] }) }),
63700
64157
  /* @__PURE__ */ jsx("div", { className: "w-12" })
63701
64158
  ] }),
@@ -63706,9 +64163,23 @@ var KPIsOverviewView = ({
63706
64163
  /* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(headerShiftId) }),
63707
64164
  /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: headerShiftName })
63708
64165
  ] }),
63709
- showHistoricalLeaderboardHeader ? /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-amber-50 text-amber-700 rounded-full", children: [
63710
- /* @__PURE__ */ jsx(Clock, { className: "w-3 h-3" }),
63711
- /* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: "Historical" })
64166
+ showHistoricalLeaderboardHeader ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
64167
+ /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-amber-50 text-amber-700 rounded-full", children: [
64168
+ /* @__PURE__ */ jsx(Clock, { className: "w-3 h-3" }),
64169
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: "Historical" })
64170
+ ] }),
64171
+ activeTab === "leaderboard" && isHistoricalLeaderboardDaily && /* @__PURE__ */ jsx(
64172
+ "button",
64173
+ {
64174
+ type: "button",
64175
+ onClick: () => {
64176
+ setSelectedLeaderboardDate(currentShiftDate);
64177
+ setSelectedLeaderboardShiftId(currentShiftId);
64178
+ },
64179
+ className: "text-[10px] font-medium text-blue-600 hover:text-blue-700 hover:underline bg-blue-50 px-2 py-1 rounded-md",
64180
+ children: "Return to Live"
64181
+ }
64182
+ )
63712
64183
  ] }) : /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-green-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-green-700", children: /* @__PURE__ */ jsx(ISTTimer_default, {}) }) })
63713
64184
  ] })
63714
64185
  ] }),
@@ -63810,79 +64281,88 @@ var KPIsOverviewView = ({
63810
64281
  ) }),
63811
64282
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
63812
64283
  /* @__PURE__ */ jsx("h1", { className: "text-2xl md:text-3xl lg:text-4xl font-semibold text-gray-900 tracking-tight", children: activeTab === "leaderboard" ? "Leaderboard" : "Overview" }),
63813
- /* @__PURE__ */ jsx(
63814
- "div",
63815
- {
63816
- className: `h-2.5 w-2.5 rounded-full ring-4 flex-shrink-0 ${showHistoricalLeaderboardHeader ? "bg-amber-500 ring-amber-500/10" : "bg-emerald-500 animate-pulse ring-emerald-500/10"}`
63817
- }
63818
- )
64284
+ !showHistoricalLeaderboardHeader && /* @__PURE__ */ jsx("div", { className: "h-2.5 w-2.5 rounded-full ring-4 flex-shrink-0 bg-emerald-500 animate-pulse ring-emerald-500/10" })
63819
64285
  ] }),
63820
- !topPerformerLoading && activeTab !== "leaderboard" && /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-1/2 -translate-y-1/2 z-10", children: /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-2xl border border-amber-200 shadow-md pl-1.5 pr-4 py-1.5 flex items-center gap-4 transition-all hover:shadow-lg hover:border-amber-300 group", children: [
63821
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
63822
- (!topPerformer.supervisors || topPerformer.supervisors.length <= 1) && /* @__PURE__ */ jsx("div", { className: "w-10 h-10 rounded-full ring-2 ring-amber-100 overflow-hidden bg-amber-50 shadow-inner flex-shrink-0 transition-transform group-hover:scale-105", children: showTopPerformerImage ? /* @__PURE__ */ jsx(
63823
- "img",
63824
- {
63825
- src: topPerformer.imageUrl || "",
63826
- alt: topPerformer.name,
63827
- className: "w-full h-full object-cover",
63828
- onError: () => setTopPerformerImageError(true)
63829
- }
63830
- ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-sm font-bold text-amber-600 uppercase", children: topPerformer.initials }) }),
63831
- topPerformer.supervisors && topPerformer.supervisors.length > 1 && /* @__PURE__ */ jsxs("div", { className: "flex -space-x-2", children: [
63832
- topPerformer.supervisors.slice(0, 3).map((supervisor, idx) => /* @__PURE__ */ jsxs(
63833
- "div",
64286
+ /* @__PURE__ */ jsxs("div", { className: "absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center", children: [
64287
+ !topPerformerLoading && activeTab !== "leaderboard" && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-2xl border border-amber-200 shadow-md pl-1.5 pr-4 py-1.5 flex items-center gap-4 transition-all hover:shadow-lg hover:border-amber-300 group", children: [
64288
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
64289
+ (!topPerformer.supervisors || topPerformer.supervisors.length <= 1) && /* @__PURE__ */ jsx("div", { className: "w-10 h-10 rounded-full ring-2 ring-amber-100 overflow-hidden bg-amber-50 shadow-inner flex-shrink-0 transition-transform group-hover:scale-105", children: showTopPerformerImage ? /* @__PURE__ */ jsx(
64290
+ "img",
63834
64291
  {
63835
- className: "relative inline-block w-10 h-10 rounded-full ring-2 ring-white bg-amber-50 shadow-sm z-0 hover:z-10 transition-all hover:scale-110 group/avatar",
63836
- style: { zIndex: 3 - idx },
63837
- children: [
63838
- supervisor.imageUrl ? /* @__PURE__ */ jsx(
63839
- "img",
63840
- {
63841
- src: supervisor.imageUrl,
63842
- alt: supervisor.name,
63843
- className: "w-full h-full object-cover rounded-full"
63844
- }
63845
- ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-sm font-bold text-amber-600 uppercase rounded-full", children: supervisor.initials }),
63846
- /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 bg-gray-900 text-white text-[10px] font-medium rounded shadow-lg opacity-0 group-hover/avatar:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-20", children: [
63847
- supervisor.name,
63848
- /* @__PURE__ */ jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 -mt-[1px] border-4 border-transparent border-t-gray-900" })
63849
- ] })
63850
- ]
63851
- },
63852
- supervisor.userId
63853
- )),
63854
- topPerformer.supervisors.length > 3 && /* @__PURE__ */ jsxs("div", { className: "inline-flex w-10 h-10 rounded-full ring-2 ring-white bg-amber-100 items-center justify-center text-sm font-medium text-amber-700 z-0", children: [
63855
- "+",
63856
- topPerformer.supervisors.length - 3
64292
+ src: topPerformer.imageUrl || "",
64293
+ alt: topPerformer.name,
64294
+ className: "w-full h-full object-cover",
64295
+ onError: () => setTopPerformerImageError(true)
64296
+ }
64297
+ ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-sm font-bold text-amber-600 uppercase", children: topPerformer.initials }) }),
64298
+ topPerformer.supervisors && topPerformer.supervisors.length > 1 && /* @__PURE__ */ jsxs("div", { className: "flex -space-x-2", children: [
64299
+ topPerformer.supervisors.slice(0, 3).map((supervisor, idx) => /* @__PURE__ */ jsxs(
64300
+ "div",
64301
+ {
64302
+ className: "relative inline-block w-10 h-10 rounded-full ring-2 ring-white bg-amber-50 shadow-sm z-0 hover:z-10 transition-all hover:scale-110 group/avatar",
64303
+ style: { zIndex: 3 - idx },
64304
+ children: [
64305
+ supervisor.imageUrl ? /* @__PURE__ */ jsx(
64306
+ "img",
64307
+ {
64308
+ src: supervisor.imageUrl,
64309
+ alt: supervisor.name,
64310
+ className: "w-full h-full object-cover rounded-full"
64311
+ }
64312
+ ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-sm font-bold text-amber-600 uppercase rounded-full", children: supervisor.initials }),
64313
+ /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 bg-gray-900 text-white text-[10px] font-medium rounded shadow-lg opacity-0 group-hover/avatar:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-20", children: [
64314
+ supervisor.name,
64315
+ /* @__PURE__ */ jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 -mt-[1px] border-4 border-transparent border-t-gray-900" })
64316
+ ] })
64317
+ ]
64318
+ },
64319
+ supervisor.userId
64320
+ )),
64321
+ topPerformer.supervisors.length > 3 && /* @__PURE__ */ jsxs("div", { className: "inline-flex w-10 h-10 rounded-full ring-2 ring-white bg-amber-100 items-center justify-center text-sm font-medium text-amber-700 z-0", children: [
64322
+ "+",
64323
+ topPerformer.supervisors.length - 3
64324
+ ] })
63857
64325
  ] })
63858
- ] })
63859
- ] }),
63860
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
63861
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[10px] leading-tight mb-1", children: [
63862
- /* @__PURE__ */ jsx("span", { className: "font-bold text-amber-600 uppercase tracking-widest", children: "Performer of the month" }),
63863
- /* @__PURE__ */ jsx("span", { className: "text-amber-200 opacity-50", children: "\u2022" }),
63864
- /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-400", children: topPerformer.periodLabel })
63865
64326
  ] }),
63866
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 leading-tight", children: [
63867
- /* @__PURE__ */ jsx("div", { className: "max-w-[140px]", children: /* @__PURE__ */ jsx(
63868
- FittingTitle,
63869
- {
63870
- title: topPerformer.name,
63871
- as: "span",
63872
- className: "text-sm text-gray-900 font-bold"
63873
- }
63874
- ) }),
63875
- /* @__PURE__ */ jsx("span", { className: "w-px h-3.5 bg-gray-200 flex-shrink-0" }),
63876
- /* @__PURE__ */ jsx("div", { className: "max-w-[150px]", children: /* @__PURE__ */ jsx(
63877
- FittingTitle,
63878
- {
63879
- title: topPerformer.unit,
63880
- className: "text-xs font-medium text-gray-500"
63881
- }
63882
- ) })
64327
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
64328
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[10px] leading-tight mb-1", children: [
64329
+ /* @__PURE__ */ jsx("span", { className: "font-bold text-amber-600 uppercase tracking-widest", children: "Performer of the month" }),
64330
+ /* @__PURE__ */ jsx("span", { className: "text-amber-200 opacity-50", children: "\u2022" }),
64331
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-400", children: topPerformer.periodLabel })
64332
+ ] }),
64333
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 leading-tight", children: [
64334
+ /* @__PURE__ */ jsx("div", { className: "max-w-[140px]", children: /* @__PURE__ */ jsx(
64335
+ FittingTitle,
64336
+ {
64337
+ title: topPerformer.name,
64338
+ as: "span",
64339
+ className: "text-sm text-gray-900 font-bold"
64340
+ }
64341
+ ) }),
64342
+ /* @__PURE__ */ jsx("span", { className: "w-px h-3.5 bg-gray-200 flex-shrink-0" }),
64343
+ /* @__PURE__ */ jsx("div", { className: "max-w-[150px]", children: /* @__PURE__ */ jsx(
64344
+ FittingTitle,
64345
+ {
64346
+ title: topPerformer.unit,
64347
+ className: "text-xs font-medium text-gray-500"
64348
+ }
64349
+ ) })
64350
+ ] })
63883
64351
  ] })
63884
- ] })
63885
- ] }) })
64352
+ ] }),
64353
+ activeTab === "leaderboard" && isHistoricalLeaderboardDaily && /* @__PURE__ */ jsx(
64354
+ "button",
64355
+ {
64356
+ type: "button",
64357
+ onClick: () => {
64358
+ setSelectedLeaderboardDate(currentShiftDate);
64359
+ setSelectedLeaderboardShiftId(currentShiftId);
64360
+ },
64361
+ className: "text-xs sm:text-sm font-medium text-blue-600 bg-blue-50 border border-blue-100 hover:bg-blue-100 hover:text-blue-700 px-3 py-1.5 rounded-lg transition-colors shadow-sm ml-4 whitespace-nowrap",
64362
+ children: "Return to Live"
64363
+ }
64364
+ )
64365
+ ] })
63886
64366
  ] }),
63887
64367
  /* @__PURE__ */ jsx("div", { className: "bg-blue-50/50 px-4 py-2 rounded-xl border border-blue-100/50 backdrop-blur-sm", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-6", children: [
63888
64368
  !isMonthlyMode && !showHistoricalLeaderboardHeader && /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -63952,29 +64432,49 @@ var KPIsOverviewView = ({
63952
64432
  singleDateOnly: true
63953
64433
  }
63954
64434
  ),
63955
- /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
63956
- "select",
63957
- {
63958
- "aria-label": "Leaderboard shift",
63959
- value: effectiveLeaderboardShiftId,
63960
- onChange: (e) => setSelectedLeaderboardShiftId(Number(e.target.value)),
63961
- className: "appearance-none pl-3 pr-8 py-1.5 text-sm font-medium bg-white border border-gray-200 hover:border-gray-300 rounded-lg text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all cursor-pointer shadow-sm min-w-[170px]",
63962
- style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.5rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
63963
- children: leaderboardShiftOptions.map((shiftOption) => /* @__PURE__ */ jsx("option", { value: shiftOption.id, children: shiftOption.label }, shiftOption.id))
63964
- }
63965
- ) }),
63966
- isHistoricalLeaderboardDaily && /* @__PURE__ */ jsx(
63967
- "button",
63968
- {
63969
- type: "button",
63970
- onClick: () => {
63971
- setSelectedLeaderboardDate(currentShiftDate);
63972
- setSelectedLeaderboardShiftId(currentShiftId);
63973
- },
63974
- className: "text-xs font-medium text-blue-600 hover:text-blue-700 whitespace-nowrap",
63975
- children: "Return to Live"
63976
- }
63977
- )
64435
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
64436
+ /* @__PURE__ */ jsxs(
64437
+ "button",
64438
+ {
64439
+ ref: filterButtonRef,
64440
+ onClick: () => setIsFilterOpen(!isFilterOpen),
64441
+ className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || activeFiltersCount > 0 ? "bg-blue-50 border-blue-200 text-blue-700" : "bg-white border-gray-200 text-gray-700 hover:bg-gray-50"}`,
64442
+ children: [
64443
+ /* @__PURE__ */ jsx(Filter, { className: "w-4 h-4" }),
64444
+ /* @__PURE__ */ jsx("span", { children: "Filters" }),
64445
+ activeFiltersCount > 0 && /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center w-5 h-5 bg-blue-100 text-blue-700 text-xs rounded-full font-bold ml-1", children: activeFiltersCount }),
64446
+ /* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 ml-1 transition-transform ${isFilterOpen ? "rotate-180" : ""}` })
64447
+ ]
64448
+ }
64449
+ ),
64450
+ isFilterOpen && /* @__PURE__ */ jsxs("div", { ref: filterRef, className: "absolute right-0 top-full mt-2 w-72 bg-white rounded-xl shadow-xl border border-gray-100 p-4 z-50", children: [
64451
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
64452
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Filter View" }),
64453
+ activeFiltersCount > 0 && /* @__PURE__ */ jsx(
64454
+ "button",
64455
+ {
64456
+ onClick: clearFilters,
64457
+ className: "text-xs text-red-600 hover:text-red-700 font-medium",
64458
+ children: "Clear all"
64459
+ }
64460
+ )
64461
+ ] }),
64462
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
64463
+ /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Shift" }),
64464
+ /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
64465
+ "select",
64466
+ {
64467
+ "aria-label": "Leaderboard shift",
64468
+ value: effectiveLeaderboardShiftId,
64469
+ onChange: (e) => setSelectedLeaderboardShiftId(Number(e.target.value)),
64470
+ className: "w-full appearance-none pl-3 pr-8 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer",
64471
+ style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.75rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
64472
+ children: leaderboardShiftOptions.map((shiftOption) => /* @__PURE__ */ jsx("option", { value: shiftOption.id, children: shiftOption.label }, shiftOption.id))
64473
+ }
64474
+ ) })
64475
+ ] }) })
64476
+ ] })
64477
+ ] })
63978
64478
  ] }),
63979
64479
  (activeTab === "leaderboard" || activeTab === "today") && showViewTypeDropdown && /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
63980
64480
  "select",
@@ -64065,29 +64565,16 @@ var formatCycleTimeValue = (value) => {
64065
64565
  return `${numericValue.toFixed(1)}s`;
64066
64566
  };
64067
64567
  var CycleTimeComparison = memo$1(({
64068
- workspace,
64069
- variant = "table"
64568
+ workspace
64070
64569
  }) => {
64071
64570
  const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
64072
64571
  const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
64073
- if (variant === "mobile") {
64074
- return /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center justify-between py-2 border-t border-gray-100", children: [
64075
- /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Standard Cycle Time" }),
64076
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums text-gray-500", children: standardValue })
64077
- ] });
64078
- }
64079
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
64080
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
64081
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Average" }),
64082
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums text-gray-900", children: averageValue })
64083
- ] }),
64084
- /* @__PURE__ */ jsx("div", { className: "h-6 w-px bg-gray-200" }),
64085
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
64086
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Standard" }),
64087
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums text-gray-500", children: standardValue })
64088
- ] })
64572
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
64573
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
64574
+ /* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
64575
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
64089
64576
  ] });
64090
- }, (prevProps, nextProps) => prevProps.variant === nextProps.variant && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
64577
+ }, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
64091
64578
  CycleTimeComparison.displayName = "CycleTimeComparison";
64092
64579
  var IsolatedTimer = memo$1(() => {
64093
64580
  return /* @__PURE__ */ jsx(ISTTimer_default, {});
@@ -64154,7 +64641,7 @@ var MobileWorkspaceCard = memo$1(({
64154
64641
  getMedalIcon,
64155
64642
  metricLabel,
64156
64643
  isAssemblyMode
64157
- }) => /* @__PURE__ */ jsxs(
64644
+ }) => /* @__PURE__ */ jsx(
64158
64645
  motion.div,
64159
64646
  {
64160
64647
  layout: true,
@@ -64165,28 +64652,25 @@ var MobileWorkspaceCard = memo$1(({
64165
64652
  },
64166
64653
  onClick: isClickable ? () => onWorkspaceClick(workspace, rank) : void 0,
64167
64654
  className: `${cardClass} p-3 rounded-lg border shadow-sm active:scale-[0.98] ${isClickable ? "cursor-pointer" : "cursor-not-allowed opacity-75"}`,
64168
- children: [
64169
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2 gap-3", children: [
64170
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
64171
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
64172
- /* @__PURE__ */ jsxs("div", { className: "text-2xl font-bold text-gray-700", children: [
64173
- "#",
64174
- rank
64175
- ] }),
64176
- getMedalIcon(rank)
64655
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2 gap-3", children: [
64656
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
64657
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
64658
+ /* @__PURE__ */ jsxs("div", { className: "text-2xl font-bold text-gray-700", children: [
64659
+ "#",
64660
+ rank
64177
64661
  ] }),
64178
- /* @__PURE__ */ jsxs("div", { children: [
64179
- /* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-900", children: workspace.displayName }),
64180
- /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: workspace.lineName })
64181
- ] })
64662
+ getMedalIcon(rank)
64182
64663
  ] }),
64183
- /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
64184
- /* @__PURE__ */ jsx("div", { className: "font-bold text-gray-900 text-lg", children: isAssemblyMode ? /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formatCycleTimeValue(workspace.avg_cycle_time) }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) }),
64185
- /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: metricLabel })
64664
+ /* @__PURE__ */ jsxs("div", { children: [
64665
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-900", children: workspace.displayName }),
64666
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: workspace.lineName })
64186
64667
  ] })
64187
64668
  ] }),
64188
- isAssemblyMode && /* @__PURE__ */ jsx(CycleTimeComparison, { workspace, variant: "mobile" })
64189
- ]
64669
+ /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
64670
+ /* @__PURE__ */ jsx("div", { className: "font-bold text-gray-900 text-lg flex justify-end", children: isAssemblyMode ? /* @__PURE__ */ jsx(CycleTimeComparison, { workspace }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) }),
64671
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: metricLabel })
64672
+ ] })
64673
+ ] })
64190
64674
  }
64191
64675
  ), (prevProps, nextProps) => {
64192
64676
  return prevProps.metricLabel === nextProps.metricLabel && prevProps.isAssemblyMode === nextProps.isAssemblyMode && prevProps.rank === nextProps.rank && prevProps.cardClass === nextProps.cardClass && prevProps.isClickable === nextProps.isClickable && prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.efficiency === nextProps.workspace.efficiency && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time && prevProps.workspace.action_count === nextProps.workspace.action_count && prevProps.workspace.action_threshold === nextProps.workspace.action_threshold && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.displayName === nextProps.workspace.displayName && prevProps.workspace.lineName === nextProps.workspace.lineName;
@@ -64216,7 +64700,7 @@ var DesktopWorkspaceRow = memo$1(({
64216
64700
  ] }) }),
64217
64701
  /* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: workspace.displayName }) }),
64218
64702
  /* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: workspace.lineName }) }),
64219
- /* @__PURE__ */ jsx("td", { className: `px-3 py-2.5 sm:p-4 text-sm sm:text-base font-medium ${isAssemblyMode ? "" : "whitespace-nowrap"}`, children: isAssemblyMode ? /* @__PURE__ */ jsx(CycleTimeComparison, { workspace, variant: "table" }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) })
64703
+ /* @__PURE__ */ jsx("td", { className: `px-3 py-2.5 sm:p-4 text-sm sm:text-base font-medium ${isAssemblyMode ? "" : "whitespace-nowrap"}`, children: isAssemblyMode ? /* @__PURE__ */ jsx(CycleTimeComparison, { workspace }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) })
64220
64704
  ]
64221
64705
  }
64222
64706
  ), (prevProps, nextProps) => {
@@ -64343,7 +64827,7 @@ var LeaderboardDetailView = memo$1(({
64343
64827
  return () => document.removeEventListener("mousedown", handleClickOutside);
64344
64828
  }, []);
64345
64829
  const [isMobile, setIsMobile] = useState(false);
64346
- React141__default.useEffect(() => {
64830
+ React142__default.useEffect(() => {
64347
64831
  const checkMobile = () => setIsMobile(window.innerWidth < 640);
64348
64832
  checkMobile();
64349
64833
  window.addEventListener("resize", checkMobile);
@@ -64989,7 +65473,7 @@ var LeaderboardDetailView = memo$1(({
64989
65473
  const descendingSortLabel = "Highest to Lowest";
64990
65474
  const ascendingSortLabel = "Lowest to Highest";
64991
65475
  return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 flex flex-col ${className}`, style: { willChange: "contents" }, children: [
64992
- /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-20 bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 md:px-8 py-2 sm:py-2.5", children: [
65476
+ /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 md:px-8 py-2 sm:py-2.5", children: [
64993
65477
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
64994
65478
  mobileMenuContext && /* @__PURE__ */ jsx(
64995
65479
  HamburgerButton,
@@ -65000,7 +65484,7 @@ var LeaderboardDetailView = memo$1(({
65000
65484
  ),
65001
65485
  /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
65002
65486
  /* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900", children: "Leaderboard" }),
65003
- /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-emerald-500 animate-pulse ring-2 ring-emerald-500/20" })
65487
+ realtimeEnabled && /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-emerald-500 animate-pulse ring-2 ring-emerald-500/20" })
65004
65488
  ] }) }),
65005
65489
  /* @__PURE__ */ jsx("div", { className: "w-9" })
65006
65490
  ] }) }),
@@ -65016,7 +65500,7 @@ var LeaderboardDetailView = memo$1(({
65016
65500
  ) }),
65017
65501
  /* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2 max-w-[calc(100%-200px)]", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
65018
65502
  /* @__PURE__ */ jsx("h1", { className: "text-lg md:text-xl lg:text-2xl xl:text-3xl font-semibold text-gray-900 truncate", children: "Leaderboard" }),
65019
- /* @__PURE__ */ jsxs("div", { className: "relative flex h-2.5 w-2.5", children: [
65503
+ realtimeEnabled && /* @__PURE__ */ jsxs("div", { className: "relative flex h-2.5 w-2.5", children: [
65020
65504
  /* @__PURE__ */ jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
65021
65505
  /* @__PURE__ */ jsx("span", { className: "relative inline-flex rounded-full h-2.5 w-2.5 bg-green-500" })
65022
65506
  ] })
@@ -65514,7 +65998,7 @@ var ProfileView = () => {
65514
65998
  ] }) });
65515
65999
  }
65516
66000
  return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
65517
- /* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0", children: [
66001
+ /* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0", children: [
65518
66002
  /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
65519
66003
  /* @__PURE__ */ jsxs("div", { className: "sm:hidden flex items-center justify-between", children: [
65520
66004
  /* @__PURE__ */ jsx("div", { className: "flex items-center", children: mobileMenuContext && /* @__PURE__ */ jsx(
@@ -65738,7 +66222,7 @@ var ClipsCostView = () => {
65738
66222
  return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-screen bg-gray-50", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "lg", message: "Loading usage data..." }) });
65739
66223
  }
65740
66224
  return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
65741
- /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b border-gray-200 shadow-sm flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4 w-full", children: [
66225
+ /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b border-gray-200 shadow-sm flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4 w-full", children: [
65742
66226
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
65743
66227
  /* @__PURE__ */ jsx("div", { className: "flex items-center", children: mobileMenuContext && /* @__PURE__ */ jsx(
65744
66228
  HamburgerButton,
@@ -66625,7 +67109,7 @@ var ShiftsView = ({
66625
67109
  }
66626
67110
  }, [lineConfigs, recalculateTargetsForShiftHourChanges, supabase, showToast]);
66627
67111
  return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 ${className}`, children: [
66628
- /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 lg:px-8 py-3 sm:py-4", children: [
67112
+ /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 lg:px-8 py-3 sm:py-4", children: [
66629
67113
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
66630
67114
  mobileMenuContext && /* @__PURE__ */ jsx(
66631
67115
  HamburgerButton,
@@ -66739,7 +67223,7 @@ var ShiftsView = ({
66739
67223
  ] })
66740
67224
  ] });
66741
67225
  };
66742
- var AuthenticatedShiftsView = withAuth(React141__default.memo(ShiftsView));
67226
+ var AuthenticatedShiftsView = withAuth(React142__default.memo(ShiftsView));
66743
67227
  var ShiftsView_default = ShiftsView;
66744
67228
 
66745
67229
  // src/views/TargetsView.utils.ts
@@ -68441,7 +68925,7 @@ var TargetsView = ({
68441
68925
  };
68442
68926
  var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
68443
68927
  var TargetsView_default = TargetsViewWithDisplayNames;
68444
- var AuthenticatedTargetsView = withAuth(React141__default.memo(TargetsViewWithDisplayNames));
68928
+ var AuthenticatedTargetsView = withAuth(React142__default.memo(TargetsViewWithDisplayNames));
68445
68929
  function useTimezone(options = {}) {
68446
68930
  const dashboardConfig = useDashboardConfig();
68447
68931
  const workspaceConfig = useWorkspaceConfig();
@@ -69450,7 +69934,7 @@ var WorkspaceDetailView = ({
69450
69934
  animate: { opacity: 1 },
69451
69935
  transition: { duration: 0.3 },
69452
69936
  children: /* @__PURE__ */ jsxs("div", { className: "min-h-screen w-full flex flex-col bg-slate-50", children: [
69453
- /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 px-3 sm:px-4 md:px-5 lg:px-6 py-2 sm:py-2.5 lg:py-3 flex flex-col shadow-sm bg-white", children: /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
69937
+ /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 px-3 sm:px-4 md:px-5 lg:px-6 py-2 sm:py-2.5 lg:py-3 flex flex-col shadow-sm bg-white", children: /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
69454
69938
  /* @__PURE__ */ jsx("div", { className: "absolute left-0 animate-pulse", children: /* @__PURE__ */ jsx("div", { className: "h-6 sm:h-7 md:h-8 w-16 sm:w-20 bg-gray-200 rounded" }) }),
69455
69939
  /* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2 animate-pulse max-w-[calc(100%-160px)] sm:max-w-[calc(100%-200px)]", children: /* @__PURE__ */ jsx("div", { className: "h-5 sm:h-6 md:h-7 w-28 sm:w-36 md:w-40 bg-gray-200 rounded" }) }),
69456
69940
  /* @__PURE__ */ jsx("div", { className: "w-full h-8" })
@@ -69512,7 +69996,7 @@ var WorkspaceDetailView = ({
69512
69996
  initial: { opacity: 1 },
69513
69997
  animate: { opacity: 1 },
69514
69998
  children: /* @__PURE__ */ jsxs("div", { className: "min-h-screen w-full flex flex-col bg-slate-50", children: [
69515
- /* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-10 px-3 sm:px-4 md:px-5 lg:px-6 py-3 sm:py-3 lg:py-3.5 flex flex-col shadow-sm bg-white", children: [
69999
+ /* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-40 px-3 sm:px-4 md:px-5 lg:px-6 py-3 sm:py-3 lg:py-3.5 flex flex-col shadow-sm bg-white", children: [
69516
70000
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
69517
70001
  /* @__PURE__ */ jsx(
69518
70002
  "button",
@@ -70190,7 +70674,7 @@ var SKUManagementView = () => {
70190
70674
  ] }) });
70191
70675
  }
70192
70676
  return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-slate-50", children: [
70193
- /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-4 md:px-6 lg:px-8 py-3 sm:py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 sm:gap-4 relative", children: [
70677
+ /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-4 md:px-6 lg:px-8 py-3 sm:py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 sm:gap-4 relative", children: [
70194
70678
  /* @__PURE__ */ jsx("div", { className: "sm:absolute sm:left-0", children: /* @__PURE__ */ jsx(
70195
70679
  BackButtonMinimal,
70196
70680
  {
@@ -70328,8 +70812,29 @@ var useWorkspaceHealth = (options) => {
70328
70812
  date: options.date,
70329
70813
  shiftId: options.shiftId
70330
70814
  });
70331
- setWorkspaces(workspacesWithStatus);
70332
- setSummary(computeSummary(workspacesWithStatus));
70815
+ let cameraIpMap = {};
70816
+ const workspaceIds = workspacesWithStatus.map((workspace) => workspace.workspace_id).filter(Boolean);
70817
+ if (workspaceIds.length > 0) {
70818
+ try {
70819
+ cameraIpMap = await workspaceService.getWorkspaceCameraIps({ workspaceIds });
70820
+ } catch (cameraError) {
70821
+ console.error("[useWorkspaceHealth] Error fetching camera IPs:", cameraError);
70822
+ }
70823
+ }
70824
+ const workspacesWithCameraIps = workspacesWithStatus.map((workspace) => {
70825
+ const cameraInfo = cameraIpMap[workspace.workspace_id];
70826
+ if (!cameraInfo) {
70827
+ return workspace;
70828
+ }
70829
+ return {
70830
+ ...workspace,
70831
+ cameraIp: cameraInfo.camera_ip ?? null,
70832
+ cameraResolutionMode: cameraInfo.resolution_mode ?? null,
70833
+ effectiveCameraUuid: cameraInfo.effective_camera_uuid ?? null
70834
+ };
70835
+ });
70836
+ setWorkspaces(workspacesWithCameraIps);
70837
+ setSummary(computeSummary(workspacesWithCameraIps));
70333
70838
  } catch (err) {
70334
70839
  console.error("[useWorkspaceHealth] Error fetching workspace health:", err);
70335
70840
  setError({ message: err.message, code: err.code || "FETCH_ERROR" });
@@ -70695,7 +71200,7 @@ var WorkspaceUptimeDetailModal = ({
70695
71200
  role: "document",
70696
71201
  "aria-labelledby": "uptime-detail-title",
70697
71202
  children: [
70698
- /* @__PURE__ */ jsxs("header", { className: "flex items-start justify-between border-b border-gray-100 px-8 py-6 sticky top-0 z-10 bg-white rounded-t-2xl", children: [
71203
+ /* @__PURE__ */ jsxs("header", { className: "flex items-start justify-between border-b border-gray-100 px-8 py-6 sticky top-0 z-40 bg-white rounded-t-2xl", children: [
70699
71204
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 mr-4", children: [
70700
71205
  /* @__PURE__ */ jsx("h2", { id: "uptime-detail-title", className: "text-2xl font-semibold text-gray-900 truncate mb-3", children: workspace.workspace_display_name || `Workspace ${workspace.workspace_id.slice(0, 6)}` }),
70701
71206
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 text-sm text-gray-600", children: [
@@ -70705,7 +71210,7 @@ var WorkspaceUptimeDetailModal = ({
70705
71210
  /* @__PURE__ */ jsx("span", { className: "text-gray-600", children: formatTimeRange(shiftStart, shiftEnd, timezone) })
70706
71211
  ] })
70707
71212
  ] }),
70708
- /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-2", children: [
71213
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2", children: [
70709
71214
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
70710
71215
  /* @__PURE__ */ jsx("div", { className: `w-2 h-2 rounded-full ${workspace.status === "healthy" ? "bg-emerald-500 animate-pulse" : workspace.status === "warning" ? "bg-amber-500" : "bg-rose-500"}` }),
70711
71216
  /* @__PURE__ */ jsx("span", { className: `text-xs font-medium ${workspace.status === "healthy" ? "text-emerald-700" : workspace.status === "warning" ? "text-amber-700" : "text-rose-700"}`, children: workspace.status === "healthy" ? "Operational" : workspace.status === "warning" ? "Intermittent" : "Down" })
@@ -70714,6 +71219,13 @@ var WorkspaceUptimeDetailModal = ({
70714
71219
  /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500", children: [
70715
71220
  "Last heartbeat ",
70716
71221
  workspace.timeSinceLastUpdate
71222
+ ] }),
71223
+ workspace.cameraIp && /* @__PURE__ */ jsxs(Fragment, { children: [
71224
+ /* @__PURE__ */ jsx("span", { className: "text-gray-300 hidden sm:inline", children: "\u2022" }),
71225
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 bg-slate-50 dark:bg-slate-800/50 px-2 py-0.5 rounded border border-slate-100 dark:border-slate-700/50 group", title: "Camera IP", children: [
71226
+ /* @__PURE__ */ jsx(Video, { className: "h-3 w-3 text-slate-400" }),
71227
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-slate-600 dark:text-slate-300 select-all", children: workspace.cameraIp })
71228
+ ] })
70717
71229
  ] })
70718
71230
  ] })
70719
71231
  ] }),
@@ -70915,7 +71427,7 @@ var WorkspaceHealthView = ({
70915
71427
  }
70916
71428
  return /* @__PURE__ */ jsxs(Fragment, { children: [
70917
71429
  /* @__PURE__ */ jsxs("div", { className: clsx("min-h-screen bg-slate-50", className), children: [
70918
- /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b border-gray-200 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4", children: [
71430
+ /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b border-gray-200 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4", children: [
70919
71431
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
70920
71432
  mobileMenuContext && /* @__PURE__ */ jsx(
70921
71433
  HamburgerButton,
@@ -71249,7 +71761,7 @@ var SupervisorManagementView = ({
71249
71761
  ) }) });
71250
71762
  }
71251
71763
  return /* @__PURE__ */ jsxs("div", { className: clsx("min-h-screen bg-slate-50", className), children: [
71252
- /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-4 md:px-6 lg:px-8 py-3 sm:py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center relative", children: [
71764
+ /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-4 md:px-6 lg:px-8 py-3 sm:py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center relative", children: [
71253
71765
  /* @__PURE__ */ jsx("div", { className: "sm:absolute sm:left-0", children: /* @__PURE__ */ jsx(
71254
71766
  BackButtonMinimal,
71255
71767
  {
@@ -71671,7 +72183,7 @@ var TeamManagementView = ({
71671
72183
  ) }) });
71672
72184
  }
71673
72185
  return /* @__PURE__ */ jsxs("div", { className: cn("min-h-screen bg-slate-50", className), children: [
71674
- /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 bg-white border-b border-gray-200 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4", children: [
72186
+ /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 bg-white border-b border-gray-200 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4", children: [
71675
72187
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
71676
72188
  mobileMenuContext && /* @__PURE__ */ jsx(
71677
72189
  HamburgerButton,
@@ -71815,7 +72327,7 @@ function BottleneckClipsView({
71815
72327
  ) })
71816
72328
  ] }) });
71817
72329
  }
71818
- var AuthenticatedBottleneckClipsView = withAuth(React141__default.memo(BottleneckClipsView));
72330
+ var AuthenticatedBottleneckClipsView = withAuth(React142__default.memo(BottleneckClipsView));
71819
72331
  var BottleneckClipsView_default = BottleneckClipsView;
71820
72332
 
71821
72333
  // src/lib/services/ticketService.ts
@@ -72646,7 +73158,7 @@ Please ensure:
72646
73158
  )
72647
73159
  ] });
72648
73160
  }
72649
- var AuthenticatedTicketsView = withAuth(React141__default.memo(TicketsView));
73161
+ var AuthenticatedTicketsView = withAuth(React142__default.memo(TicketsView));
72650
73162
  var TicketsView_default = TicketsView;
72651
73163
 
72652
73164
  // src/lib/utils/improvementDisplay.ts
@@ -72976,6 +73488,18 @@ var buildInitials = (name) => {
72976
73488
  const second = parts.length > 1 ? parts[1]?.[0] || "" : "";
72977
73489
  return `${first}${second}`.toUpperCase();
72978
73490
  };
73491
+ var getRecommendationAssignedUserIds = (recommendation) => {
73492
+ if (Array.isArray(recommendation.assigned_user_ids) && recommendation.assigned_user_ids.length > 0) {
73493
+ return recommendation.assigned_user_ids.filter(
73494
+ (userId) => typeof userId === "string" && userId.trim().length > 0
73495
+ );
73496
+ }
73497
+ return recommendation.assigned_to_user_id ? [recommendation.assigned_to_user_id] : [];
73498
+ };
73499
+ var recommendationMatchesMember = (recommendation, memberId) => {
73500
+ if (memberId === "all") return true;
73501
+ return getRecommendationAssignedUserIds(recommendation).includes(memberId);
73502
+ };
72979
73503
  var getQueryParam = (value) => {
72980
73504
  if (typeof value === "string") {
72981
73505
  const trimmed = value.trim();
@@ -73070,7 +73594,6 @@ var ClipVideoCarousel = ({ clips, clipsService }) => {
73070
73594
  currentVideo.cycle_time_seconds.toFixed(1),
73071
73595
  "s"
73072
73596
  ] }),
73073
- !loading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none group-hover:opacity-0 transition-opacity", children: /* @__PURE__ */ jsx(PlayCircleIcon, { className: "w-16 h-16 text-white opacity-80" }) }),
73074
73597
  videos.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
73075
73598
  /* @__PURE__ */ jsx(
73076
73599
  "button",
@@ -73467,10 +73990,7 @@ var ImprovementCenterView = () => {
73467
73990
  if (!supabase || !companyId) return;
73468
73991
  try {
73469
73992
  const userService2 = createUserManagementService(supabase);
73470
- const users = await userService2.getCompanyUsers(
73471
- companyId,
73472
- "supervisor,owner,industrial_engineer"
73473
- );
73993
+ const users = await userService2.getCompanyUsers(companyId);
73474
73994
  if (cancelled) return;
73475
73995
  const membersById = /* @__PURE__ */ new Map();
73476
73996
  users.forEach((user2) => {
@@ -73574,18 +74094,8 @@ var ImprovementCenterView = () => {
73574
74094
  const teamMembersById = useMemo(() => {
73575
74095
  return new Map(teamMembers.map((member) => [member.id, member]));
73576
74096
  }, [teamMembers]);
73577
- const getRecommendationDisplayMetadata = React141__default.useCallback((rec) => {
73578
- const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
73579
- return getImprovementDisplayMetadata({
73580
- location: rec.location,
73581
- line: rec.line,
73582
- workspaceId: rec.workspace_id,
73583
- supervisors
73584
- });
73585
- }, [supervisorsByLineId]);
73586
- const filteredRecommendations = useMemo(() => {
73587
- const hasActiveFilters = selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedSortBy !== "all";
73588
- const sortedRecommendations = recommendations.filter((rec) => {
74097
+ const recommendationsMatchingViewFilters = useMemo(() => {
74098
+ return recommendations.filter((rec) => {
73589
74099
  if (selectedLineId !== "all" && rec.line_id !== selectedLineId) return false;
73590
74100
  if (selectedStatus === "resolved" && rec.ticket_status !== "solved") return false;
73591
74101
  if (selectedStatus === "unresolved" && rec.ticket_status === "solved") return false;
@@ -73596,9 +74106,41 @@ var ImprovementCenterView = () => {
73596
74106
  if (selectedWeeksRange === "2" && weeks !== 2) return false;
73597
74107
  if (selectedWeeksRange === "3+" && weeks < 3) return false;
73598
74108
  }
73599
- if (selectedMemberId !== "all" && !(rec.assigned_user_ids?.includes(selectedMemberId) || rec.assigned_to_user_id === selectedMemberId)) return false;
73600
74109
  return true;
73601
- }).sort((a, b) => {
74110
+ });
74111
+ }, [recommendations, selectedLineId, selectedShift, selectedStatus, selectedWeeksRange]);
74112
+ const memberOptions = useMemo(() => {
74113
+ const uniqueAssigneeIds = /* @__PURE__ */ new Set();
74114
+ recommendationsMatchingViewFilters.forEach((recommendation) => {
74115
+ getRecommendationAssignedUserIds(recommendation).forEach((userId) => {
74116
+ uniqueAssigneeIds.add(userId);
74117
+ });
74118
+ });
74119
+ const options = Array.from(uniqueAssigneeIds).map((userId) => ({
74120
+ id: userId,
74121
+ label: teamMembersById.get(userId)?.name || userId
74122
+ })).sort((left, right) => left.label.localeCompare(right.label));
74123
+ return [{ id: "all", label: "All Members" }, ...options];
74124
+ }, [recommendationsMatchingViewFilters, teamMembersById]);
74125
+ useEffect(() => {
74126
+ if (selectedMemberId === "all") return;
74127
+ const memberStillAvailable = memberOptions.some((option) => option.id === selectedMemberId);
74128
+ if (!memberStillAvailable) {
74129
+ setSelectedMemberId("all");
74130
+ }
74131
+ }, [memberOptions, selectedMemberId]);
74132
+ const getRecommendationDisplayMetadata = React142__default.useCallback((rec) => {
74133
+ const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
74134
+ return getImprovementDisplayMetadata({
74135
+ location: rec.location,
74136
+ line: rec.line,
74137
+ workspaceId: rec.workspace_id,
74138
+ supervisors
74139
+ });
74140
+ }, [supervisorsByLineId]);
74141
+ const filteredRecommendations = useMemo(() => {
74142
+ const hasActiveFilters = selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedSortBy !== "all";
74143
+ const sortedRecommendations = recommendationsMatchingViewFilters.filter((rec) => recommendationMatchesMember(rec, selectedMemberId)).sort((a, b) => {
73602
74144
  if (selectedSortBy === "highest_to_lowest" || selectedSortBy === "lowest_to_highest") {
73603
74145
  const gainA = getImprovementPcsGainSortValue(a);
73604
74146
  const gainB = getImprovementPcsGainSortValue(b);
@@ -73629,12 +74171,8 @@ var ImprovementCenterView = () => {
73629
74171
  ];
73630
74172
  }, [
73631
74173
  focusIssueId,
73632
- recommendations,
73633
- selectedLineId,
74174
+ recommendationsMatchingViewFilters,
73634
74175
  selectedMemberId,
73635
- selectedShift,
73636
- selectedStatus,
73637
- selectedWeeksRange,
73638
74176
  selectedSortBy
73639
74177
  ]);
73640
74178
  const stats = useMemo(() => {
@@ -73647,7 +74185,7 @@ var ImprovementCenterView = () => {
73647
74185
  if (selectedWeeksRange === "2" && weeks !== 2) return false;
73648
74186
  if (selectedWeeksRange === "3+" && weeks < 3) return false;
73649
74187
  }
73650
- if (selectedMemberId !== "all" && !(rec.assigned_user_ids?.includes(selectedMemberId) || rec.assigned_to_user_id === selectedMemberId)) return false;
74188
+ if (!recommendationMatchesMember(rec, selectedMemberId)) return false;
73651
74189
  return true;
73652
74190
  });
73653
74191
  const total = baseFiltered.length;
@@ -73826,7 +74364,7 @@ var ImprovementCenterView = () => {
73826
74364
  { value: selectedSortBy, onChange: handleSortByChange, options: [{ id: "all", label: "All" }, { id: "highest_to_lowest", label: "Highest to Lowest" }, { id: "lowest_to_highest", label: "Lowest to Highest" }], label: "Priority" },
73827
74365
  { value: selectedShift, onChange: handleShiftFilterChange, options: shiftOptions, label: "Shift" },
73828
74366
  { value: selectedWeeksRange, onChange: handleWeeksFilterChange, options: weekOptions.map((o) => o.id), labels: weekOptions, label: "Duration" },
73829
- { value: selectedMemberId, onChange: handleMemberFilterChange, options: ["all", ...teamMembers.map((m) => m.id)], labels: teamMembers, label: "Member" },
74367
+ { value: selectedMemberId, onChange: handleMemberFilterChange, options: memberOptions, label: "Member" },
73830
74368
  { value: selectedLineId, onChange: handleLineFilterChange, options: lineOptions.map((o) => o.id), labels: lineOptions, label: "Line" }
73831
74369
  ].map((filter2, idx) => /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
73832
74370
  /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: filter2.label }),
@@ -73835,6 +74373,7 @@ var ImprovementCenterView = () => {
73835
74373
  {
73836
74374
  value: filter2.value,
73837
74375
  onChange: (e) => filter2.onChange(e.target.value),
74376
+ "aria-label": `${filter2.label} filter`,
73838
74377
  className: "w-full appearance-none pl-3 pr-8 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer",
73839
74378
  style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.75rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
73840
74379
  children: filter2.options.map((opt) => {
@@ -74064,7 +74603,7 @@ var ThreadSidebar = ({
74064
74603
  ] }) })
74065
74604
  ] });
74066
74605
  };
74067
- var ProfilePicture = React141__default.memo(({
74606
+ var ProfilePicture = React142__default.memo(({
74068
74607
  alt = "Axel",
74069
74608
  className = "",
74070
74609
  size = "md",
@@ -75677,7 +76216,7 @@ var AIAgentView = () => {
75677
76216
  `
75678
76217
  } }),
75679
76218
  /* @__PURE__ */ jsxs("div", { className: `flex-1 flex flex-col h-screen transition-all duration-300 ${isSidebarOpen ? "lg:mr-80 mr-0" : "mr-0"}`, children: [
75680
- /* @__PURE__ */ jsxs("header", { className: "flex-shrink-0 bg-white px-3 sm:px-6 md:px-8 py-2 sm:py-5 md:py-6 shadow-sm border-b border-gray-200/80 sticky top-0 z-10", children: [
76219
+ /* @__PURE__ */ jsxs("header", { className: "flex-shrink-0 bg-white px-3 sm:px-6 md:px-8 py-2 sm:py-5 md:py-6 shadow-sm border-b border-gray-200/80 sticky top-0 z-40", children: [
75681
76220
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
75682
76221
  mobileMenuContext && /* @__PURE__ */ jsx(
75683
76222
  HamburgerButton,
@@ -76589,7 +77128,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
76589
77128
  ] }),
76590
77129
  /* @__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" }) })
76591
77130
  ] }, index)) });
76592
- var OperationsOverviewHeader = React141__default.memo(({
77131
+ var OperationsOverviewHeader = React142__default.memo(({
76593
77132
  dateRange,
76594
77133
  displayDateRange,
76595
77134
  trendMode,
@@ -76609,65 +77148,65 @@ var OperationsOverviewHeader = React141__default.memo(({
76609
77148
  bumpRenderCounter();
76610
77149
  const subtitleRange = displayDateRange || dateRange;
76611
77150
  const showLiveShiftMeta = isLiveScope && trendMode !== "all";
76612
- const liveShiftLabel = React141__default.useMemo(
77151
+ const liveShiftLabel = React142__default.useMemo(
76613
77152
  () => normalizeShiftLabel(liveShiftName, trendMode),
76614
77153
  [liveShiftName, trendMode]
76615
77154
  );
76616
- const liveShiftIcon = React141__default.useMemo(
77155
+ const liveShiftIcon = React142__default.useMemo(
76617
77156
  () => getShiftIcon(liveShiftName, trendMode),
76618
77157
  [liveShiftName, trendMode]
76619
77158
  );
76620
- const [isFilterOpen, setIsFilterOpen] = React141__default.useState(false);
76621
- const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React141__default.useState(false);
76622
- const filterRef = React141__default.useRef(null);
76623
- const filterButtonRef = React141__default.useRef(null);
76624
- const mobileFilterButtonRef = React141__default.useRef(null);
76625
- const linesDropdownRef = React141__default.useRef(null);
76626
- const mobileSubtitle = React141__default.useMemo(() => {
77159
+ const [isFilterOpen, setIsFilterOpen] = React142__default.useState(false);
77160
+ const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React142__default.useState(false);
77161
+ const filterRef = React142__default.useRef(null);
77162
+ const filterButtonRef = React142__default.useRef(null);
77163
+ const mobileFilterButtonRef = React142__default.useRef(null);
77164
+ const linesDropdownRef = React142__default.useRef(null);
77165
+ const mobileSubtitle = React142__default.useMemo(() => {
76627
77166
  if (subtitleRange.startKey === subtitleRange.endKey) {
76628
77167
  return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
76629
77168
  }
76630
77169
  return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
76631
77170
  }, [subtitleRange.endKey, subtitleRange.startKey]);
76632
- const desktopSubtitle = React141__default.useMemo(() => {
77171
+ const desktopSubtitle = React142__default.useMemo(() => {
76633
77172
  if (subtitleRange.startKey === subtitleRange.endKey) {
76634
77173
  return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
76635
77174
  }
76636
77175
  return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
76637
77176
  }, [subtitleRange.endKey, subtitleRange.startKey]);
76638
- const availableLineIds = React141__default.useMemo(
77177
+ const availableLineIds = React142__default.useMemo(
76639
77178
  () => lineOptions.map((line) => line.id),
76640
77179
  [lineOptions]
76641
77180
  );
76642
- const selectedLineIdSet = React141__default.useMemo(
77181
+ const selectedLineIdSet = React142__default.useMemo(
76643
77182
  () => new Set(selectedLineIds),
76644
77183
  [selectedLineIds]
76645
77184
  );
76646
- const isAllLinesSelected = React141__default.useMemo(() => {
77185
+ const isAllLinesSelected = React142__default.useMemo(() => {
76647
77186
  if (availableLineIds.length === 0) return true;
76648
77187
  return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
76649
77188
  }, [availableLineIds, selectedLineIdSet]);
76650
- const activeFilterCount = React141__default.useMemo(() => {
77189
+ const activeFilterCount = React142__default.useMemo(() => {
76651
77190
  let count = 0;
76652
77191
  if (trendMode !== "all") count += 1;
76653
77192
  if (selectedSupervisorId !== "all") count += 1;
76654
77193
  if (!isAllLinesSelected) count += 1;
76655
77194
  return count;
76656
77195
  }, [isAllLinesSelected, selectedSupervisorId, trendMode]);
76657
- const handleFilterToggle = React141__default.useCallback(() => {
77196
+ const handleFilterToggle = React142__default.useCallback(() => {
76658
77197
  trackCoreEvent("Operations Overview Filter Toggled", {
76659
77198
  action: !isFilterOpen ? "open" : "close"
76660
77199
  });
76661
77200
  setIsFilterOpen((previous) => !previous);
76662
77201
  }, [isFilterOpen]);
76663
- const handleTrendModeChange = React141__default.useCallback((event) => {
77202
+ const handleTrendModeChange = React142__default.useCallback((event) => {
76664
77203
  const nextMode = event.target.value;
76665
77204
  trackCoreEvent("Operations Overview Shift Filter Changed", {
76666
77205
  shift_mode: nextMode
76667
77206
  });
76668
77207
  onTrendModeChange(nextMode);
76669
77208
  }, [onTrendModeChange]);
76670
- const handleAllLinesToggle = React141__default.useCallback(() => {
77209
+ const handleAllLinesToggle = React142__default.useCallback(() => {
76671
77210
  trackCoreEvent("Operations Overview Line Filter Changed", {
76672
77211
  selected_line_ids: availableLineIds,
76673
77212
  selected_line_count: availableLineIds.length,
@@ -76675,7 +77214,7 @@ var OperationsOverviewHeader = React141__default.memo(({
76675
77214
  });
76676
77215
  onSelectedLineIdsChange(availableLineIds);
76677
77216
  }, [availableLineIds, onSelectedLineIdsChange]);
76678
- const handleSupervisorChange = React141__default.useCallback((event) => {
77217
+ const handleSupervisorChange = React142__default.useCallback((event) => {
76679
77218
  const supervisorId = event.target.value;
76680
77219
  const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
76681
77220
  trackCoreEvent("Operations Overview Supervisor Filter Changed", {
@@ -76686,7 +77225,7 @@ var OperationsOverviewHeader = React141__default.memo(({
76686
77225
  });
76687
77226
  onSelectedSupervisorIdChange(supervisorId);
76688
77227
  }, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
76689
- const handleLineToggle = React141__default.useCallback((lineId) => {
77228
+ const handleLineToggle = React142__default.useCallback((lineId) => {
76690
77229
  const current = new Set(selectedLineIds);
76691
77230
  if (current.has(lineId)) {
76692
77231
  if (current.size <= 1) return;
@@ -76702,13 +77241,13 @@ var OperationsOverviewHeader = React141__default.memo(({
76702
77241
  });
76703
77242
  onSelectedLineIdsChange(next);
76704
77243
  }, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
76705
- const handleClearAllFilters = React141__default.useCallback(() => {
77244
+ const handleClearAllFilters = React142__default.useCallback(() => {
76706
77245
  onTrendModeChange("all");
76707
77246
  onSelectedSupervisorIdChange("all");
76708
77247
  onSelectedLineIdsChange(availableLineIds);
76709
77248
  setIsFilterOpen(false);
76710
77249
  }, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
76711
- React141__default.useEffect(() => {
77250
+ React142__default.useEffect(() => {
76712
77251
  const handleClickOutside = (event) => {
76713
77252
  const target = event.target;
76714
77253
  if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
@@ -76723,7 +77262,7 @@ var OperationsOverviewHeader = React141__default.memo(({
76723
77262
  document.removeEventListener("mousedown", handleClickOutside);
76724
77263
  };
76725
77264
  }, []);
76726
- return /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3 relative", children: [
77265
+ return /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3 relative", children: [
76727
77266
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
76728
77267
  mobileMenuContext ? /* @__PURE__ */ jsx(
76729
77268
  HamburgerButton,
@@ -76947,12 +77486,12 @@ var OperationsOverviewHeader = React141__default.memo(({
76947
77486
  ] }) });
76948
77487
  });
76949
77488
  OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
76950
- var OverviewSummaryCards = React141__default.memo(({ store }) => {
77489
+ var OverviewSummaryCards = React142__default.memo(({ store }) => {
76951
77490
  bumpRenderCounter();
76952
77491
  const scope = useOperationsOverviewScope(store);
76953
77492
  const snapshot = useOperationsOverviewSnapshot(store);
76954
77493
  const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
76955
- const comparisonLabel = React141__default.useMemo(() => {
77494
+ const comparisonLabel = React142__default.useMemo(() => {
76956
77495
  return formatComparisonWindow({
76957
77496
  currentDayCount: scope.current_range?.day_count ?? null,
76958
77497
  previousDayCount: scope.previous_range?.day_count ?? null,
@@ -76965,27 +77504,27 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
76965
77504
  scope.previous_range?.day_count,
76966
77505
  scope.shift_mode
76967
77506
  ]);
76968
- const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React141__default.useState(false);
76969
- const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React141__default.useState(false);
76970
- const idleContributorsRef = React141__default.useRef(null);
76971
- const plantEfficiencyBadge = React141__default.useMemo(() => {
77507
+ const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React142__default.useState(false);
77508
+ const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React142__default.useState(false);
77509
+ const idleContributorsRef = React142__default.useRef(null);
77510
+ const plantEfficiencyBadge = React142__default.useMemo(() => {
76972
77511
  return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
76973
77512
  positiveIsGood: true,
76974
77513
  formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
76975
77514
  comparisonLabel
76976
77515
  });
76977
77516
  }, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
76978
- const idleBadge = React141__default.useMemo(() => {
77517
+ const idleBadge = React142__default.useMemo(() => {
76979
77518
  return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
76980
77519
  positiveIsGood: false,
76981
77520
  formatter: (value) => formatSignedIdleDuration(value),
76982
77521
  comparisonLabel
76983
77522
  });
76984
77523
  }, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
76985
- const canInspectIdleContributors = React141__default.useMemo(() => {
77524
+ const canInspectIdleContributors = React142__default.useMemo(() => {
76986
77525
  return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
76987
77526
  }, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
76988
- const idleTopContributors = React141__default.useMemo(() => {
77527
+ const idleTopContributors = React142__default.useMemo(() => {
76989
77528
  return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
76990
77529
  workspaceId: item.workspace_id || "",
76991
77530
  workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
@@ -76993,14 +77532,14 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
76993
77532
  avgIdleSeconds: toNumber3(item.avg_idle_seconds)
76994
77533
  })).slice(0, 5);
76995
77534
  }, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
76996
- const showIdleContributorLineNames = React141__default.useMemo(() => {
77535
+ const showIdleContributorLineNames = React142__default.useMemo(() => {
76997
77536
  return (scope.line_count ?? 0) > 1;
76998
77537
  }, [scope.line_count]);
76999
- const closeIdleContributors = React141__default.useCallback(() => {
77538
+ const closeIdleContributors = React142__default.useCallback(() => {
77000
77539
  setIsIdleContributorsOpen(false);
77001
77540
  setIsIdleContributorsPinned(false);
77002
77541
  }, []);
77003
- const handleIdleContributorsToggle = React141__default.useCallback(() => {
77542
+ const handleIdleContributorsToggle = React142__default.useCallback(() => {
77004
77543
  if (!canInspectIdleContributors) return;
77005
77544
  setIsIdleContributorsPinned((previous) => {
77006
77545
  const next = !previous;
@@ -77008,7 +77547,7 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
77008
77547
  return next;
77009
77548
  });
77010
77549
  }, [canInspectIdleContributors]);
77011
- const handleIdleContributorsKeyDown = React141__default.useCallback((event) => {
77550
+ const handleIdleContributorsKeyDown = React142__default.useCallback((event) => {
77012
77551
  if (!canInspectIdleContributors) return;
77013
77552
  if (event.key === "Enter" || event.key === " ") {
77014
77553
  event.preventDefault();
@@ -77020,11 +77559,11 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
77020
77559
  closeIdleContributors();
77021
77560
  }
77022
77561
  }, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
77023
- React141__default.useEffect(() => {
77562
+ React142__default.useEffect(() => {
77024
77563
  setIsIdleContributorsOpen(false);
77025
77564
  setIsIdleContributorsPinned(false);
77026
77565
  }, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
77027
- React141__default.useEffect(() => {
77566
+ React142__default.useEffect(() => {
77028
77567
  if (!isIdleContributorsOpen) return void 0;
77029
77568
  const handleClickOutside = (event) => {
77030
77569
  if (!isIdleContributorsPinned) return;
@@ -77162,7 +77701,7 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
77162
77701
  ] });
77163
77702
  });
77164
77703
  OverviewSummaryCards.displayName = "OverviewSummaryCards";
77165
- var PoorestPerformersCard = React141__default.memo(({
77704
+ var PoorestPerformersCard = React142__default.memo(({
77166
77705
  store,
77167
77706
  supervisorsByLineId,
77168
77707
  onViewAll,
@@ -77171,9 +77710,9 @@ var PoorestPerformersCard = React141__default.memo(({
77171
77710
  bumpRenderCounter();
77172
77711
  const scope = useOperationsOverviewScope(store);
77173
77712
  const snapshot = useOperationsOverviewSnapshot(store);
77174
- const [poorestLineMode, setPoorestLineMode] = React141__default.useState("output");
77713
+ const [poorestLineMode, setPoorestLineMode] = React142__default.useState("output");
77175
77714
  const availableLineModes = scope.available_line_modes;
77176
- React141__default.useEffect(() => {
77715
+ React142__default.useEffect(() => {
77177
77716
  const hasOutput = !!availableLineModes?.has_output;
77178
77717
  const hasUptime = !!availableLineModes?.has_uptime;
77179
77718
  if (hasOutput && !hasUptime && poorestLineMode !== "output") {
@@ -77182,7 +77721,7 @@ var PoorestPerformersCard = React141__default.memo(({
77182
77721
  setPoorestLineMode("uptime");
77183
77722
  }
77184
77723
  }, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
77185
- const comparisonLabel = React141__default.useMemo(() => {
77724
+ const comparisonLabel = React142__default.useMemo(() => {
77186
77725
  return formatComparisonWindow({
77187
77726
  currentDayCount: scope.current_range?.day_count ?? null,
77188
77727
  previousDayCount: scope.previous_range?.day_count ?? null,
@@ -77196,7 +77735,7 @@ var PoorestPerformersCard = React141__default.memo(({
77196
77735
  scope.shift_mode
77197
77736
  ]);
77198
77737
  const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
77199
- const mergedPoorestLines = React141__default.useMemo(() => {
77738
+ const mergedPoorestLines = React142__default.useMemo(() => {
77200
77739
  const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
77201
77740
  return rows.slice(0, 3).map((line) => {
77202
77741
  const lineId = line.line_id || "";
@@ -77215,7 +77754,7 @@ var PoorestPerformersCard = React141__default.memo(({
77215
77754
  }, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
77216
77755
  const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
77217
77756
  const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
77218
- const handlePoorestLineModeChange = React141__default.useCallback((mode) => {
77757
+ const handlePoorestLineModeChange = React142__default.useCallback((mode) => {
77219
77758
  trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
77220
77759
  setPoorestLineMode(mode);
77221
77760
  }, []);
@@ -77301,14 +77840,14 @@ var PoorestPerformersCard = React141__default.memo(({
77301
77840
  ] });
77302
77841
  });
77303
77842
  PoorestPerformersCard.displayName = "PoorestPerformersCard";
77304
- var IdleBreakdownCard = React141__default.memo(({
77843
+ var IdleBreakdownCard = React142__default.memo(({
77305
77844
  store,
77306
77845
  scopedLineCount
77307
77846
  }) => {
77308
77847
  bumpRenderCounter();
77309
77848
  const idle = useOperationsOverviewIdle(store);
77310
77849
  const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
77311
- const idleBreakdown = React141__default.useMemo(() => {
77850
+ const idleBreakdown = React142__default.useMemo(() => {
77312
77851
  return idle.data.map((item) => ({
77313
77852
  name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
77314
77853
  reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
@@ -77327,7 +77866,7 @@ var IdleBreakdownCard = React141__default.memo(({
77327
77866
  }))
77328
77867
  })).filter((item) => item.value > 0);
77329
77868
  }, [idle.data]);
77330
- const showIdleModuleNotEnabledState = React141__default.useMemo(() => {
77869
+ const showIdleModuleNotEnabledState = React142__default.useMemo(() => {
77331
77870
  const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
77332
77871
  return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
77333
77872
  }, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
@@ -77348,7 +77887,7 @@ var IdleBreakdownCard = React141__default.memo(({
77348
77887
  ] });
77349
77888
  });
77350
77889
  IdleBreakdownCard.displayName = "IdleBreakdownCard";
77351
- var EfficiencyTrendCard = React141__default.memo(({
77890
+ var EfficiencyTrendCard = React142__default.memo(({
77352
77891
  store,
77353
77892
  dateRange,
77354
77893
  appTimezone,
@@ -77356,14 +77895,14 @@ var EfficiencyTrendCard = React141__default.memo(({
77356
77895
  }) => {
77357
77896
  bumpRenderCounter();
77358
77897
  const trend = useOperationsOverviewTrend(store);
77359
- const currentWeekRange = React141__default.useMemo(
77898
+ const currentWeekRange = React142__default.useMemo(
77360
77899
  () => getCurrentWeekToDateRange(appTimezone),
77361
77900
  [appTimezone]
77362
77901
  );
77363
77902
  const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
77364
77903
  const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
77365
77904
  const isHourlyTrend = trend.data.granularity === "hour";
77366
- const trendData = React141__default.useMemo(() => {
77905
+ const trendData = React142__default.useMemo(() => {
77367
77906
  if (isHourlyTrend) {
77368
77907
  return (trend.data.points || []).map((point, index) => ({
77369
77908
  name: (() => {
@@ -77435,13 +77974,13 @@ var EfficiencyTrendCard = React141__default.memo(({
77435
77974
  };
77436
77975
  });
77437
77976
  }, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
77438
- const trendTooltipLabelFormatter = React141__default.useCallback((label, payload) => {
77977
+ const trendTooltipLabelFormatter = React142__default.useCallback((label, payload) => {
77439
77978
  if (isHourlyTrend) return label;
77440
77979
  const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
77441
77980
  if (!dayOfWeek || typeof label !== "string") return label;
77442
77981
  return `${label} (${dayOfWeek})`;
77443
77982
  }, [isHourlyTrend]);
77444
- const trendXAxisTickFormatter = React141__default.useCallback((value, index) => {
77983
+ const trendXAxisTickFormatter = React142__default.useCallback((value, index) => {
77445
77984
  if (!isHourlyTrend) {
77446
77985
  return typeof value === "string" ? value : String(value ?? "");
77447
77986
  }
@@ -77468,7 +78007,7 @@ var EfficiencyTrendCard = React141__default.memo(({
77468
78007
  ] });
77469
78008
  });
77470
78009
  EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
77471
- var TopImprovementsCard = React141__default.memo(({
78010
+ var TopImprovementsCard = React142__default.memo(({
77472
78011
  store,
77473
78012
  supervisorsByLineId,
77474
78013
  onViewAll,
@@ -77477,7 +78016,7 @@ var TopImprovementsCard = React141__default.memo(({
77477
78016
  bumpRenderCounter();
77478
78017
  const improvements = useOperationsOverviewImprovements(store);
77479
78018
  const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
77480
- const displayImprovements = React141__default.useMemo(() => {
78019
+ const displayImprovements = React142__default.useMemo(() => {
77481
78020
  return improvements.data.map((item) => {
77482
78021
  const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
77483
78022
  return {
@@ -77514,7 +78053,7 @@ var TopImprovementsCard = React141__default.memo(({
77514
78053
  className: "flex items-center justify-between py-3 border-b border-slate-50 last:border-0 group cursor-pointer",
77515
78054
  children: [
77516
78055
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0 pr-4", children: [
77517
- item.ticketLabel ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full border border-indigo-100 bg-indigo-50 px-2 py-0.5 text-[10px] font-semibold text-indigo-600", children: item.ticketLabel }) }) : null,
78056
+ item.ticketLabel ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-start flex-shrink-0 w-16", children: /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center min-w-[48px] max-w-[64px] truncate rounded-full border border-indigo-100 bg-indigo-50 px-2 py-0.5 text-[10px] font-semibold text-indigo-600", children: item.ticketLabel }) }) : null,
77518
78057
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
77519
78058
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 min-w-0 mb-0.5", children: /* @__PURE__ */ jsx("h4", { className: "text-[13px] font-semibold text-slate-800 truncate transition-colors group-hover:text-indigo-600", children: item.title }) }),
77520
78059
  /* @__PURE__ */ jsx(
@@ -77605,33 +78144,33 @@ var useOperationsOverviewRefresh = ({
77605
78144
  isLiveScope,
77606
78145
  enabled = true
77607
78146
  }) => {
77608
- const lineIdsKey = React141__default.useMemo(() => lineIds.join(","), [lineIds]);
77609
- const scopeSignature = React141__default.useMemo(
78147
+ const lineIdsKey = React142__default.useMemo(() => lineIds.join(","), [lineIds]);
78148
+ const scopeSignature = React142__default.useMemo(
77610
78149
  () => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
77611
78150
  [companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
77612
78151
  );
77613
- const controllersRef = React141__default.useRef({});
77614
- const requestIdsRef = React141__default.useRef({
78152
+ const controllersRef = React142__default.useRef({});
78153
+ const requestIdsRef = React142__default.useRef({
77615
78154
  snapshot: 0,
77616
78155
  trend: 0,
77617
78156
  idle: 0,
77618
78157
  improvements: 0
77619
78158
  });
77620
- const intervalRef = React141__default.useRef(null);
77621
- const isPageActiveRef = React141__default.useRef(true);
77622
- const lastResumeRefreshAtRef = React141__default.useRef(0);
77623
- const abortAll = React141__default.useCallback(() => {
78159
+ const intervalRef = React142__default.useRef(null);
78160
+ const isPageActiveRef = React142__default.useRef(true);
78161
+ const lastResumeRefreshAtRef = React142__default.useRef(0);
78162
+ const abortAll = React142__default.useCallback(() => {
77624
78163
  Object.values(controllersRef.current).forEach((controller) => {
77625
78164
  controller?.abort();
77626
78165
  });
77627
78166
  controllersRef.current = {};
77628
78167
  }, []);
77629
- React141__default.useEffect(() => {
78168
+ React142__default.useEffect(() => {
77630
78169
  return () => {
77631
78170
  abortAll();
77632
78171
  };
77633
78172
  }, [abortAll]);
77634
- const getIsPageActive = React141__default.useCallback(() => {
78173
+ const getIsPageActive = React142__default.useCallback(() => {
77635
78174
  if (typeof document === "undefined") {
77636
78175
  return true;
77637
78176
  }
@@ -77639,7 +78178,7 @@ var useOperationsOverviewRefresh = ({
77639
78178
  const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
77640
78179
  return isVisible && hasFocus;
77641
78180
  }, []);
77642
- const stopPolling = React141__default.useCallback((reason) => {
78181
+ const stopPolling = React142__default.useCallback((reason) => {
77643
78182
  if (intervalRef.current === null) {
77644
78183
  return;
77645
78184
  }
@@ -77647,7 +78186,7 @@ var useOperationsOverviewRefresh = ({
77647
78186
  intervalRef.current = null;
77648
78187
  debugRefreshLog("poll stopped", { reason });
77649
78188
  }, []);
77650
- const runRefresh = React141__default.useCallback(
78189
+ const runRefresh = React142__default.useCallback(
77651
78190
  async (section, begin, onSuccess, onError, request, reason) => {
77652
78191
  if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
77653
78192
  const requestId = requestIdsRef.current[section] + 1;
@@ -77671,7 +78210,7 @@ var useOperationsOverviewRefresh = ({
77671
78210
  },
77672
78211
  [companyId, enabled, lineIds.length, supabase]
77673
78212
  );
77674
- const refreshSnapshot = React141__default.useCallback(
78213
+ const refreshSnapshot = React142__default.useCallback(
77675
78214
  async (reason) => {
77676
78215
  await runRefresh(
77677
78216
  "snapshot",
@@ -77703,7 +78242,7 @@ var useOperationsOverviewRefresh = ({
77703
78242
  },
77704
78243
  [companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
77705
78244
  );
77706
- const refreshTrend = React141__default.useCallback(
78245
+ const refreshTrend = React142__default.useCallback(
77707
78246
  async (reason) => {
77708
78247
  await runRefresh(
77709
78248
  "trend",
@@ -77732,7 +78271,7 @@ var useOperationsOverviewRefresh = ({
77732
78271
  },
77733
78272
  [companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
77734
78273
  );
77735
- const refreshIdle = React141__default.useCallback(
78274
+ const refreshIdle = React142__default.useCallback(
77736
78275
  async (reason) => {
77737
78276
  await runRefresh(
77738
78277
  "idle",
@@ -77761,7 +78300,7 @@ var useOperationsOverviewRefresh = ({
77761
78300
  },
77762
78301
  [companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
77763
78302
  );
77764
- const refreshImprovements = React141__default.useCallback(
78303
+ const refreshImprovements = React142__default.useCallback(
77765
78304
  async (reason) => {
77766
78305
  await runRefresh(
77767
78306
  "improvements",
@@ -77791,7 +78330,7 @@ var useOperationsOverviewRefresh = ({
77791
78330
  },
77792
78331
  [companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
77793
78332
  );
77794
- const refreshAll = React141__default.useCallback(
78333
+ const refreshAll = React142__default.useCallback(
77795
78334
  async (reason) => {
77796
78335
  await Promise.allSettled([
77797
78336
  refreshSnapshot(reason),
@@ -77802,7 +78341,7 @@ var useOperationsOverviewRefresh = ({
77802
78341
  },
77803
78342
  [refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
77804
78343
  );
77805
- const startPolling = React141__default.useCallback((reason) => {
78344
+ const startPolling = React142__default.useCallback((reason) => {
77806
78345
  if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
77807
78346
  return;
77808
78347
  }
@@ -77823,7 +78362,7 @@ var useOperationsOverviewRefresh = ({
77823
78362
  }, LIVE_REFRESH_INTERVAL_MS);
77824
78363
  debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
77825
78364
  }, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
77826
- const refreshFromResume = React141__default.useCallback((reason) => {
78365
+ const refreshFromResume = React142__default.useCallback((reason) => {
77827
78366
  const now4 = Date.now();
77828
78367
  if (now4 - lastResumeRefreshAtRef.current < 1e3) {
77829
78368
  debugRefreshLog("resume refresh suppressed", { reason });
@@ -77838,7 +78377,7 @@ var useOperationsOverviewRefresh = ({
77838
78377
  }
77839
78378
  });
77840
78379
  }, [refreshAll, startPolling, stopPolling]);
77841
- React141__default.useEffect(() => {
78380
+ React142__default.useEffect(() => {
77842
78381
  if (!enabled) {
77843
78382
  stopPolling("disabled");
77844
78383
  abortAll();
@@ -77853,7 +78392,7 @@ var useOperationsOverviewRefresh = ({
77853
78392
  }
77854
78393
  void refreshAll("scope_change");
77855
78394
  }, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
77856
- React141__default.useEffect(() => {
78395
+ React142__default.useEffect(() => {
77857
78396
  if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
77858
78397
  isPageActiveRef.current = false;
77859
78398
  stopPolling("live_scope_disabled");
@@ -78028,55 +78567,55 @@ var PlantHeadView = () => {
78028
78567
  const { accessibleLineIds } = useUserLineAccess();
78029
78568
  const mobileMenuContext = useMobileMenu();
78030
78569
  useHideMobileHeader(!!mobileMenuContext);
78031
- const storeRef = React141__default.useRef(createOperationsOverviewStore());
78570
+ const storeRef = React142__default.useRef(createOperationsOverviewStore());
78032
78571
  const store = storeRef.current;
78033
- const fallbackOperationalDate = React141__default.useMemo(
78572
+ const fallbackOperationalDate = React142__default.useMemo(
78034
78573
  () => getOperationalDate(appTimezone),
78035
78574
  [appTimezone]
78036
78575
  );
78037
- const [dateRange, setDateRange] = React141__default.useState(() => ({
78576
+ const [dateRange, setDateRange] = React142__default.useState(() => ({
78038
78577
  startKey: fallbackOperationalDate,
78039
78578
  endKey: fallbackOperationalDate
78040
78579
  }));
78041
- const [usesThisWeekComparison, setUsesThisWeekComparison] = React141__default.useState(false);
78042
- const [trendMode, setTrendMode] = React141__default.useState("all");
78043
- const [selectedSupervisorId, setSelectedSupervisorId] = React141__default.useState("all");
78044
- const [selectedLineIds, setSelectedLineIds] = React141__default.useState([]);
78045
- const [isInitialScopeReady, setIsInitialScopeReady] = React141__default.useState(false);
78046
- const [shiftResolutionTick, setShiftResolutionTick] = React141__default.useState(0);
78047
- const hasAutoInitializedScopeRef = React141__default.useRef(false);
78048
- const hasUserAdjustedScopeRef = React141__default.useRef(false);
78049
- React141__default.useEffect(() => {
78580
+ const [usesThisWeekComparison, setUsesThisWeekComparison] = React142__default.useState(false);
78581
+ const [trendMode, setTrendMode] = React142__default.useState("all");
78582
+ const [selectedSupervisorId, setSelectedSupervisorId] = React142__default.useState("all");
78583
+ const [selectedLineIds, setSelectedLineIds] = React142__default.useState([]);
78584
+ const [isInitialScopeReady, setIsInitialScopeReady] = React142__default.useState(false);
78585
+ const [shiftResolutionTick, setShiftResolutionTick] = React142__default.useState(0);
78586
+ const hasAutoInitializedScopeRef = React142__default.useRef(false);
78587
+ const hasUserAdjustedScopeRef = React142__default.useRef(false);
78588
+ React142__default.useEffect(() => {
78050
78589
  trackCorePageView("Operations Overview", {
78051
78590
  dashboard_surface: "operations_overview"
78052
78591
  });
78053
78592
  }, []);
78054
- const currentWeekRange = React141__default.useMemo(
78593
+ const currentWeekRange = React142__default.useMemo(
78055
78594
  () => getCurrentWeekToDateRange(appTimezone),
78056
78595
  [appTimezone]
78057
78596
  );
78058
- const currentWeekDisplayRange = React141__default.useMemo(
78597
+ const currentWeekDisplayRange = React142__default.useMemo(
78059
78598
  () => getCurrentWeekFullRange(appTimezone),
78060
78599
  [appTimezone]
78061
78600
  );
78062
78601
  const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
78063
- const headerDateRange = React141__default.useMemo(() => {
78602
+ const headerDateRange = React142__default.useMemo(() => {
78064
78603
  if (usesThisWeekComparison && isCurrentWeekToDateRange) {
78065
78604
  return currentWeekDisplayRange;
78066
78605
  }
78067
78606
  return dateRange;
78068
78607
  }, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
78069
- const normalizedLineIds = React141__default.useMemo(
78608
+ const normalizedLineIds = React142__default.useMemo(
78070
78609
  () => Array.from(new Set(
78071
78610
  (accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
78072
78611
  )).sort(),
78073
78612
  [accessibleLineIds, factoryViewId]
78074
78613
  );
78075
- const lineIdsKey = React141__default.useMemo(
78614
+ const lineIdsKey = React142__default.useMemo(
78076
78615
  () => normalizedLineIds.join(","),
78077
78616
  [normalizedLineIds]
78078
78617
  );
78079
- const lineOptions = React141__default.useMemo(
78618
+ const lineOptions = React142__default.useMemo(
78080
78619
  () => normalizedLineIds.map((lineId) => ({
78081
78620
  id: lineId,
78082
78621
  name: getLineDisplayName(entityConfig, lineId)
@@ -78088,7 +78627,7 @@ var PlantHeadView = () => {
78088
78627
  companyId: entityConfig.companyId,
78089
78628
  useBackend: true
78090
78629
  });
78091
- const supervisorOptions = React141__default.useMemo(
78630
+ const supervisorOptions = React142__default.useMemo(
78092
78631
  () => {
78093
78632
  const optionsById = /* @__PURE__ */ new Map();
78094
78633
  normalizedLineIds.forEach((lineId) => {
@@ -78114,7 +78653,7 @@ var PlantHeadView = () => {
78114
78653
  },
78115
78654
  [normalizedLineIds, supervisorsByLineId]
78116
78655
  );
78117
- React141__default.useEffect(() => {
78656
+ React142__default.useEffect(() => {
78118
78657
  if (selectedSupervisorId === "all") {
78119
78658
  setSelectedLineIds((previous) => {
78120
78659
  if (normalizedLineIds.length === 0) {
@@ -78140,7 +78679,7 @@ var PlantHeadView = () => {
78140
78679
  const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
78141
78680
  setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
78142
78681
  }, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
78143
- const scopedLineIds = React141__default.useMemo(
78682
+ const scopedLineIds = React142__default.useMemo(
78144
78683
  () => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
78145
78684
  [normalizedLineIds, selectedLineIds]
78146
78685
  );
@@ -78148,7 +78687,7 @@ var PlantHeadView = () => {
78148
78687
  shiftConfigMap,
78149
78688
  isLoading: isShiftConfigLoading
78150
78689
  } = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
78151
- React141__default.useEffect(() => {
78690
+ React142__default.useEffect(() => {
78152
78691
  if (scopedLineIds.length === 0 || isShiftConfigLoading) {
78153
78692
  return;
78154
78693
  }
@@ -78159,11 +78698,11 @@ var PlantHeadView = () => {
78159
78698
  clearInterval(intervalId);
78160
78699
  };
78161
78700
  }, [isShiftConfigLoading, scopedLineIds.length]);
78162
- const shiftResolutionNow = React141__default.useMemo(
78701
+ const shiftResolutionNow = React142__default.useMemo(
78163
78702
  () => /* @__PURE__ */ new Date(),
78164
78703
  [shiftResolutionTick]
78165
78704
  );
78166
- const earliestDayShiftStartTime = React141__default.useMemo(() => {
78705
+ const earliestDayShiftStartTime = React142__default.useMemo(() => {
78167
78706
  const candidateStarts = [];
78168
78707
  scopedLineIds.forEach((lineId) => {
78169
78708
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
@@ -78199,11 +78738,11 @@ var PlantHeadView = () => {
78199
78738
  const minutes = earliestMinutes % 60;
78200
78739
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
78201
78740
  }, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
78202
- const resolvedOperationalToday = React141__default.useMemo(
78741
+ const resolvedOperationalToday = React142__default.useMemo(
78203
78742
  () => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
78204
78743
  [appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
78205
78744
  );
78206
- const activeLineShiftStates = React141__default.useMemo(() => {
78745
+ const activeLineShiftStates = React142__default.useMemo(() => {
78207
78746
  return scopedLineIds.flatMap((lineId) => {
78208
78747
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
78209
78748
  const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
@@ -78230,16 +78769,16 @@ var PlantHeadView = () => {
78230
78769
  }];
78231
78770
  });
78232
78771
  }, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
78233
- const hasActiveDayShiftLine = React141__default.useMemo(
78772
+ const hasActiveDayShiftLine = React142__default.useMemo(
78234
78773
  () => activeLineShiftStates.some((shift) => shift.trendMode === "day" && shift.date === resolvedOperationalToday),
78235
78774
  [activeLineShiftStates, resolvedOperationalToday]
78236
78775
  );
78237
- const hasActiveNightShiftLine = React141__default.useMemo(
78776
+ const hasActiveNightShiftLine = React142__default.useMemo(
78238
78777
  () => activeLineShiftStates.some((shift) => shift.trendMode === "night" && shift.date === resolvedOperationalToday),
78239
78778
  [activeLineShiftStates, resolvedOperationalToday]
78240
78779
  );
78241
78780
  const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
78242
- const hourlyWindowStartTime = React141__default.useMemo(() => {
78781
+ const hourlyWindowStartTime = React142__default.useMemo(() => {
78243
78782
  if (scopedLineIds.length === 0) {
78244
78783
  return null;
78245
78784
  }
@@ -78290,12 +78829,12 @@ var PlantHeadView = () => {
78290
78829
  const minutes = earliestMinutes % 60;
78291
78830
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
78292
78831
  }, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
78293
- const isShiftScopeResolved = React141__default.useMemo(
78832
+ const isShiftScopeResolved = React142__default.useMemo(
78294
78833
  () => !isShiftConfigLoading,
78295
78834
  [isShiftConfigLoading]
78296
78835
  );
78297
- const initializedTimezoneRef = React141__default.useRef(appTimezone);
78298
- React141__default.useEffect(() => {
78836
+ const initializedTimezoneRef = React142__default.useRef(appTimezone);
78837
+ React142__default.useEffect(() => {
78299
78838
  if (initializedTimezoneRef.current === appTimezone) return;
78300
78839
  hasAutoInitializedScopeRef.current = false;
78301
78840
  hasUserAdjustedScopeRef.current = false;
@@ -78308,7 +78847,7 @@ var PlantHeadView = () => {
78308
78847
  setIsInitialScopeReady(false);
78309
78848
  initializedTimezoneRef.current = appTimezone;
78310
78849
  }, [appTimezone, fallbackOperationalDate]);
78311
- React141__default.useEffect(() => {
78850
+ React142__default.useEffect(() => {
78312
78851
  if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
78313
78852
  return;
78314
78853
  }
@@ -78333,7 +78872,7 @@ var PlantHeadView = () => {
78333
78872
  hasAutoInitializedScopeRef.current = true;
78334
78873
  setIsInitialScopeReady(true);
78335
78874
  }, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
78336
- const handleDateRangeChange = React141__default.useCallback((range, meta) => {
78875
+ const handleDateRangeChange = React142__default.useCallback((range, meta) => {
78337
78876
  hasUserAdjustedScopeRef.current = true;
78338
78877
  setIsInitialScopeReady(true);
78339
78878
  trackCoreEvent("Operations Overview Date Range Changed", {
@@ -78351,12 +78890,12 @@ var PlantHeadView = () => {
78351
78890
  return previous;
78352
78891
  });
78353
78892
  }, []);
78354
- const handleTrendModeChange = React141__default.useCallback((mode) => {
78893
+ const handleTrendModeChange = React142__default.useCallback((mode) => {
78355
78894
  hasUserAdjustedScopeRef.current = true;
78356
78895
  setIsInitialScopeReady(true);
78357
78896
  setTrendMode(mode);
78358
78897
  }, []);
78359
- const handleSelectedLineIdsChange = React141__default.useCallback((lineIds) => {
78898
+ const handleSelectedLineIdsChange = React142__default.useCallback((lineIds) => {
78360
78899
  setSelectedSupervisorId("all");
78361
78900
  if (normalizedLineIds.length === 0) {
78362
78901
  setSelectedLineIds([]);
@@ -78367,10 +78906,10 @@ var PlantHeadView = () => {
78367
78906
  const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
78368
78907
  setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
78369
78908
  }, [normalizedLineIds]);
78370
- const handleSelectedSupervisorIdChange = React141__default.useCallback((supervisorId) => {
78909
+ const handleSelectedSupervisorIdChange = React142__default.useCallback((supervisorId) => {
78371
78910
  setSelectedSupervisorId(supervisorId);
78372
78911
  }, []);
78373
- const buildLineMonthlyHistoryUrl = React141__default.useCallback((lineId) => {
78912
+ const buildLineMonthlyHistoryUrl = React142__default.useCallback((lineId) => {
78374
78913
  const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
78375
78914
  const params = new URLSearchParams();
78376
78915
  params.set("tab", "monthly_history");
@@ -78380,15 +78919,15 @@ var PlantHeadView = () => {
78380
78919
  params.set("rangeEnd", dateRange.endKey);
78381
78920
  return `/kpis/${lineId}?${params.toString()}`;
78382
78921
  }, [dateRange.endKey, dateRange.startKey]);
78383
- const handleViewAllPoorestPerformers = React141__default.useCallback(() => {
78922
+ const handleViewAllPoorestPerformers = React142__default.useCallback(() => {
78384
78923
  trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
78385
78924
  navigate("/kpis?tab=leaderboard");
78386
78925
  }, [navigate]);
78387
- const handleViewAllImprovements = React141__default.useCallback(() => {
78926
+ const handleViewAllImprovements = React142__default.useCallback(() => {
78388
78927
  trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
78389
78928
  navigate("/improvement-center");
78390
78929
  }, [navigate]);
78391
- const handleOpenImprovement = React141__default.useCallback((item) => {
78930
+ const handleOpenImprovement = React142__default.useCallback((item) => {
78392
78931
  trackCoreEvent("Operations Overview Improvement Clicked", {
78393
78932
  issue_id: item.issueId,
78394
78933
  issue_number: item.issueNumber,
@@ -78399,13 +78938,13 @@ var PlantHeadView = () => {
78399
78938
  });
78400
78939
  navigate(`/improvement-center?${params.toString()}`);
78401
78940
  }, [navigate]);
78402
- const comparisonStrategy = React141__default.useMemo(() => {
78941
+ const comparisonStrategy = React142__default.useMemo(() => {
78403
78942
  if (usesThisWeekComparison && isCurrentWeekToDateRange) {
78404
78943
  return "previous_full_week";
78405
78944
  }
78406
78945
  return void 0;
78407
78946
  }, [isCurrentWeekToDateRange, usesThisWeekComparison]);
78408
- const effectiveDateRange = React141__default.useMemo(() => {
78947
+ const effectiveDateRange = React142__default.useMemo(() => {
78409
78948
  if (isInitialScopeReady) {
78410
78949
  return dateRange;
78411
78950
  }
@@ -78415,21 +78954,21 @@ var PlantHeadView = () => {
78415
78954
  endKey: nextStartKey
78416
78955
  };
78417
78956
  }, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
78418
- const effectiveTrendMode = React141__default.useMemo(
78957
+ const effectiveTrendMode = React142__default.useMemo(
78419
78958
  () => resolvedTrendMode,
78420
78959
  [resolvedTrendMode]
78421
78960
  );
78422
- const hourlyLabelStartTime = React141__default.useMemo(() => {
78961
+ const hourlyLabelStartTime = React142__default.useMemo(() => {
78423
78962
  if (scopedLineIds.length === 0) {
78424
78963
  return null;
78425
78964
  }
78426
78965
  return hourlyWindowStartTime;
78427
78966
  }, [hourlyWindowStartTime, scopedLineIds.length]);
78428
- const isSingleDayScope = React141__default.useMemo(
78967
+ const isSingleDayScope = React142__default.useMemo(
78429
78968
  () => effectiveDateRange.startKey === effectiveDateRange.endKey,
78430
78969
  [effectiveDateRange.endKey, effectiveDateRange.startKey]
78431
78970
  );
78432
- const isLiveScope = React141__default.useMemo(
78971
+ const isLiveScope = React142__default.useMemo(
78433
78972
  () => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && (effectiveTrendMode === "all" || effectiveTrendMode === "day" && hasActiveDayShiftLine || effectiveTrendMode === "night" && hasActiveNightShiftLine),
78434
78973
  [
78435
78974
  effectiveDateRange.startKey,
@@ -78440,7 +78979,7 @@ var PlantHeadView = () => {
78440
78979
  resolvedOperationalToday
78441
78980
  ]
78442
78981
  );
78443
- const handleOpenLineDetails = React141__default.useCallback((lineId, lineName) => {
78982
+ const handleOpenLineDetails = React142__default.useCallback((lineId, lineName) => {
78444
78983
  trackCoreEvent("Operations Overview Line Clicked", {
78445
78984
  line_id: lineId,
78446
78985
  line_name: lineName,
@@ -79008,4 +79547,4 @@ var streamProxyConfig = {
79008
79547
  }
79009
79548
  };
79010
79549
 
79011
- 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, 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, 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 };
79550
+ 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, 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, 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 };