@optifye/dashboard-core 6.12.47 → 6.12.49

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,7 +1,7 @@
1
1
  import { format, addDays, subMonths, endOfMonth, startOfMonth, endOfDay, eachDayOfInterval, getDay, isSameDay, isWithinInterval, startOfDay, parseISO, subDays, differenceInMinutes, addMinutes, addMonths, isValid, formatDistanceToNow, isToday, isFuture, isBefore } from 'date-fns';
2
2
  import { formatInTimeZone, fromZonedTime, toZonedTime } from 'date-fns-tz';
3
- import * as React148 from 'react';
4
- import React148__default, { createContext, useRef, useId, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore, Children, isValidElement, useInsertionEffect, startTransition, Fragment as Fragment$1, createElement, Component } from 'react';
3
+ import * as React125 from 'react';
4
+ import React125__default, { createContext, useRef, useId, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore, Children, isValidElement, useInsertionEffect, startTransition, Fragment as Fragment$1, createElement, Component } from 'react';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
  import { useRouter } from 'next/router';
7
7
  import { toast } from 'sonner';
@@ -10,11 +10,11 @@ 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, ShieldCheck, Star, Award, RefreshCw, Filter, X, Coffee, Plus, ArrowUp, ArrowDown, ArrowRight, HelpCircle, ClipboardX, Activity, Wrench, UserX, Clock, Package, Monitor, CheckCircle2, ArrowLeft, Calendar, Save, AlertCircle, Loader2, Minus, ChevronLeft, ChevronRight, TrendingUp, Sparkles, Pause, Play, XCircle, Palette, LockKeyhole, TrendingDown, FolderOpen, Folder, ArrowDownWideNarrow, Tag, Sliders, Layers, Search, Edit2, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Video, Copy, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Settings, LifeBuoy, EyeOff, Zap, ExternalLink, Flame, Crown, Medal } from 'lucide-react';
13
+ import { Camera, AlertTriangle, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, RefreshCw, ArrowUpDown, X, Coffee, Plus, Filter, ArrowUp, ArrowDown, ArrowRight, HelpCircle, ClipboardX, Activity, Wrench, UserX, Clock, Package, Monitor, CheckCircle2, ArrowLeft, Calendar, Save, AlertCircle, Loader2, Minus, ChevronLeft, ChevronRight, TrendingUp, Sparkles, Pause, Play, XCircle, Palette, LockKeyhole, TrendingDown, FolderOpen, Folder, ArrowDownWideNarrow, Tag, Sliders, Layers, Search, Edit2, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Video, Copy, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Settings, LifeBuoy, EyeOff, Zap, ExternalLink, 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, LineChart as LineChart$1, Line, Customized, Cell, PieChart, Pie, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
16
16
  import { Slot } from '@radix-ui/react-slot';
17
- import { AdjustmentsHorizontalIcon, ClipboardDocumentCheckIcon, ClockIcon, UsersIcon, UserCircleIcon, TicketIcon, CurrencyDollarIcon, QuestionMarkCircleIcon, XMarkIcon, ArrowRightIcon, SparklesIcon, PlayCircleIcon, 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, InformationCircleIcon, ArrowLeftIcon } from '@heroicons/react/24/outline';
17
+ import { LightBulbIcon, AdjustmentsHorizontalIcon, ClipboardDocumentCheckIcon, ClockIcon, UsersIcon, UserCircleIcon, TicketIcon, CurrencyDollarIcon, QuestionMarkCircleIcon, XMarkIcon, ArrowRightIcon, SparklesIcon, PlayCircleIcon, Bars3Icon, HomeIcon, VideoCameraIcon, TrophyIcon, ChartBarIcon, CubeIcon, HeartIcon, Cog6ToothIcon, ChevronRightIcon, ArrowRightStartOnRectangleIcon, ExclamationCircleIcon, ExclamationTriangleIcon, CalendarIcon, ChevronDownIcon, ChevronLeftIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ArrowDownTrayIcon, CheckCircleIcon, ChatBubbleLeftRightIcon, XCircleIcon, FunnelIcon, EyeIcon, InformationCircleIcon, ArrowLeftIcon } from '@heroicons/react/24/outline';
18
18
  import * as SelectPrimitive from '@radix-ui/react-select';
19
19
  import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
20
20
  import { CheckIcon } from '@heroicons/react/24/solid';
@@ -2091,14 +2091,14 @@ var useIdleTimeVlmConfig = () => {
2091
2091
  }
2092
2092
  return context;
2093
2093
  };
2094
- var DashboardConfigContext = React148.createContext(void 0);
2094
+ var DashboardConfigContext = React125.createContext(void 0);
2095
2095
  var DashboardProvider = ({ config: userProvidedConfig, children }) => {
2096
- const fullConfig = React148.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
2096
+ const fullConfig = React125.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
2097
2097
  _setDashboardConfigInstance(fullConfig);
2098
- React148.useEffect(() => {
2098
+ React125.useEffect(() => {
2099
2099
  _setDashboardConfigInstance(fullConfig);
2100
2100
  }, [fullConfig]);
2101
- React148.useEffect(() => {
2101
+ React125.useEffect(() => {
2102
2102
  if (!fullConfig.theme) return;
2103
2103
  const styleId = "dashboard-core-theme-vars";
2104
2104
  let styleEl = document.getElementById(styleId);
@@ -2124,7 +2124,7 @@ var DashboardProvider = ({ config: userProvidedConfig, children }) => {
2124
2124
  return /* @__PURE__ */ jsx(DashboardConfigContext.Provider, { value: fullConfig, children: /* @__PURE__ */ jsx(IdleTimeVlmConfigProvider, { children }) });
2125
2125
  };
2126
2126
  var useDashboardConfig = () => {
2127
- const ctx = React148.useContext(DashboardConfigContext);
2127
+ const ctx = React125.useContext(DashboardConfigContext);
2128
2128
  if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
2129
2129
  return ctx;
2130
2130
  };
@@ -12830,7 +12830,7 @@ var useMobileMenu = () => {
12830
12830
  };
12831
12831
  var useHideMobileHeader = (shouldHide = true) => {
12832
12832
  const context = useMobileMenu();
12833
- React148__default.useEffect(() => {
12833
+ React125__default.useEffect(() => {
12834
12834
  if (context && shouldHide) {
12835
12835
  context.setHideMobileHeader(true);
12836
12836
  return () => {
@@ -25914,7 +25914,7 @@ var MotionConfigContext = createContext({
25914
25914
  });
25915
25915
 
25916
25916
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
25917
- var PopChildMeasure = class extends React148.Component {
25917
+ var PopChildMeasure = class extends React125.Component {
25918
25918
  getSnapshotBeforeUpdate(prevProps) {
25919
25919
  const element = this.props.childRef.current;
25920
25920
  if (element && prevProps.isPresent && !this.props.isPresent) {
@@ -25969,7 +25969,7 @@ function PopChild({ children, isPresent }) {
25969
25969
  document.head.removeChild(style);
25970
25970
  };
25971
25971
  }, [isPresent]);
25972
- return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React148.cloneElement(children, { ref }) });
25972
+ return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React125.cloneElement(children, { ref }) });
25973
25973
  }
25974
25974
 
25975
25975
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
@@ -26006,7 +26006,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
26006
26006
  useMemo(() => {
26007
26007
  presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
26008
26008
  }, [isPresent]);
26009
- React148.useEffect(() => {
26009
+ React125.useEffect(() => {
26010
26010
  !isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
26011
26011
  }, [isPresent]);
26012
26012
  if (mode === "popLayout") {
@@ -33791,7 +33791,7 @@ var withAuth = (WrappedComponent2, options) => {
33791
33791
  requireAuth: true,
33792
33792
  ...options
33793
33793
  };
33794
- const WithAuthComponent = React148.memo(function WithAuthComponent2(props) {
33794
+ const WithAuthComponent = React125.memo(function WithAuthComponent2(props) {
33795
33795
  const {
33796
33796
  session,
33797
33797
  user,
@@ -33802,9 +33802,9 @@ var withAuth = (WrappedComponent2, options) => {
33802
33802
  retrySessionHydration
33803
33803
  } = useAuth();
33804
33804
  const router = useRouter();
33805
- const [localLoading, setLocalLoading] = React148.useState(loading);
33806
- const [loadingTimeoutReached, setLoadingTimeoutReached] = React148.useState(false);
33807
- React148.useEffect(() => {
33805
+ const [localLoading, setLocalLoading] = React125.useState(loading);
33806
+ const [loadingTimeoutReached, setLoadingTimeoutReached] = React125.useState(false);
33807
+ React125.useEffect(() => {
33808
33808
  if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
33809
33809
  console.log("withAuth state:", {
33810
33810
  loading,
@@ -33816,7 +33816,7 @@ var withAuth = (WrappedComponent2, options) => {
33816
33816
  });
33817
33817
  }
33818
33818
  }, [authStatus, error, loading, session, user]);
33819
- const handleLoadingTimeout = React148.useCallback(() => {
33819
+ const handleLoadingTimeout = React125.useCallback(() => {
33820
33820
  console.warn("[withAuth] Loading timeout reached");
33821
33821
  setLoadingTimeoutReached(true);
33822
33822
  if (hasStoredSupabaseSession()) {
@@ -33828,13 +33828,13 @@ var withAuth = (WrappedComponent2, options) => {
33828
33828
  router.replace(defaultOptions.redirectTo);
33829
33829
  }
33830
33830
  }, [retrySessionHydration, router]);
33831
- React148.useEffect(() => {
33831
+ React125.useEffect(() => {
33832
33832
  if (!loading && authStatus !== "recovering" && defaultOptions.requireAuth && !session && !error) {
33833
33833
  console.log("[withAuth] No session found, redirecting to login");
33834
33834
  router.replace(defaultOptions.redirectTo);
33835
33835
  }
33836
33836
  }, [authStatus, defaultOptions.requireAuth, error, loading, router, session]);
33837
- React148.useEffect(() => {
33837
+ React125.useEffect(() => {
33838
33838
  setLocalLoading(loading);
33839
33839
  }, [loading]);
33840
33840
  if (loading || localLoading) {
@@ -34833,11 +34833,11 @@ var BarChartComponent = ({
34833
34833
  aspect = 2,
34834
34834
  ...restOfChartProps
34835
34835
  }) => {
34836
- const containerRef = React148__default.useRef(null);
34837
- const [containerReady, setContainerReady] = React148__default.useState(false);
34836
+ const containerRef = React125__default.useRef(null);
34837
+ const [containerReady, setContainerReady] = React125__default.useState(false);
34838
34838
  const themeConfig = useThemeConfig();
34839
34839
  const { formatNumber } = useFormatNumber();
34840
- React148__default.useEffect(() => {
34840
+ React125__default.useEffect(() => {
34841
34841
  const checkContainerDimensions = () => {
34842
34842
  if (containerRef.current) {
34843
34843
  const rect = containerRef.current.getBoundingClientRect();
@@ -34951,7 +34951,7 @@ var BarChartComponent = ({
34951
34951
  }
34952
34952
  return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
34953
34953
  };
34954
- var BarChart = React148__default.memo(BarChartComponent, (prevProps, nextProps) => {
34954
+ var BarChart = React125__default.memo(BarChartComponent, (prevProps, nextProps) => {
34955
34955
  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) {
34956
34956
  return false;
34957
34957
  }
@@ -35002,10 +35002,10 @@ var LineChartComponent = ({
35002
35002
  fillContainer = false,
35003
35003
  ...restOfChartProps
35004
35004
  }) => {
35005
- const containerRef = React148__default.useRef(null);
35006
- const [dimensions, setDimensions] = React148__default.useState({ width: 0, height: 0 });
35007
- const [hasValidData, setHasValidData] = React148__default.useState(false);
35008
- React148__default.useEffect(() => {
35005
+ const containerRef = React125__default.useRef(null);
35006
+ const [dimensions, setDimensions] = React125__default.useState({ width: 0, height: 0 });
35007
+ const [hasValidData, setHasValidData] = React125__default.useState(false);
35008
+ React125__default.useEffect(() => {
35009
35009
  const currentHasValidData = data && lines && lines.length > 0 && data.some(
35010
35010
  (item) => lines.some((line) => {
35011
35011
  const val = item[line.dataKey];
@@ -35016,7 +35016,7 @@ var LineChartComponent = ({
35016
35016
  setHasValidData(true);
35017
35017
  }
35018
35018
  }, [data, lines, hasValidData]);
35019
- React148__default.useEffect(() => {
35019
+ React125__default.useEffect(() => {
35020
35020
  if (!containerRef.current) return;
35021
35021
  const observer = new ResizeObserver((entries) => {
35022
35022
  const entry = entries[0];
@@ -35141,7 +35141,7 @@ var LineChartComponent = ({
35141
35141
  }
35142
35142
  return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
35143
35143
  };
35144
- var LineChart = React148__default.memo(LineChartComponent, (prevProps, nextProps) => {
35144
+ var LineChart = React125__default.memo(LineChartComponent, (prevProps, nextProps) => {
35145
35145
  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)) {
35146
35146
  return false;
35147
35147
  }
@@ -35308,7 +35308,7 @@ var SkuRow = ({ sku, isSelected, isLive, onSelect }) => {
35308
35308
  );
35309
35309
  };
35310
35310
  var PerSkuView = ({ rows, className = "", selectedSkuId, liveSkuId, onSelectSku }) => {
35311
- const ordered = React148__default.useMemo(
35311
+ const ordered = React125__default.useMemo(
35312
35312
  () => [...rows].sort((a, b) => {
35313
35313
  const am = (b.active_minutes ?? 0) - (a.active_minutes ?? 0);
35314
35314
  if (am !== 0) return am;
@@ -35316,9 +35316,9 @@ var PerSkuView = ({ rows, className = "", selectedSkuId, liveSkuId, onSelectSku
35316
35316
  }),
35317
35317
  [rows]
35318
35318
  );
35319
- const scrollContainerRef = React148__default.useRef(null);
35320
- const [showScrollIndicatorBottom, setShowScrollIndicatorBottom] = React148__default.useState(ordered.length > 4);
35321
- const [showScrollIndicatorTop, setShowScrollIndicatorTop] = React148__default.useState(false);
35319
+ const scrollContainerRef = React125__default.useRef(null);
35320
+ const [showScrollIndicatorBottom, setShowScrollIndicatorBottom] = React125__default.useState(ordered.length > 4);
35321
+ const [showScrollIndicatorTop, setShowScrollIndicatorTop] = React125__default.useState(false);
35322
35322
  const handleScroll = (e) => {
35323
35323
  const target = e.currentTarget;
35324
35324
  if (target.scrollHeight - target.scrollTop <= target.clientHeight + 10) {
@@ -35342,7 +35342,7 @@ var PerSkuView = ({ rows, className = "", selectedSkuId, liveSkuId, onSelectSku
35342
35342
  scrollContainerRef.current.scrollBy({ top: -80, behavior: "smooth" });
35343
35343
  }
35344
35344
  };
35345
- React148__default.useEffect(() => {
35345
+ React125__default.useEffect(() => {
35346
35346
  if (scrollContainerRef.current) {
35347
35347
  const target = scrollContainerRef.current;
35348
35348
  setShowScrollIndicatorBottom(target.scrollHeight > target.clientHeight && target.scrollHeight - target.scrollTop > target.clientHeight + 10);
@@ -35415,7 +35415,7 @@ var OutputProgressChartComponent = ({
35415
35415
  liveSkuId,
35416
35416
  onSelectSku
35417
35417
  }) => {
35418
- const realSkuRows = React148__default.useMemo(
35418
+ const realSkuRows = React125__default.useMemo(
35419
35419
  () => filterRealSkuBreakdown(skuBreakdown),
35420
35420
  [skuBreakdown]
35421
35421
  );
@@ -35440,7 +35440,7 @@ var OutputProgressChartComponent = ({
35440
35440
  }
35441
35441
  );
35442
35442
  };
35443
- var OutputProgressChart = React148__default.memo(OutputProgressChartComponent);
35443
+ var OutputProgressChart = React125__default.memo(OutputProgressChartComponent);
35444
35444
  OutputProgressChart.displayName = "OutputProgressChart";
35445
35445
  var LargeOutputProgressChart = ({
35446
35446
  currentOutput,
@@ -35580,7 +35580,7 @@ var CycleTimeChartComponent = ({
35580
35580
  }
35581
35581
  ) }) });
35582
35582
  };
35583
- var CycleTimeChart = React148__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
35583
+ var CycleTimeChart = React125__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
35584
35584
  if (prevProps.className !== nextProps.className) {
35585
35585
  return false;
35586
35586
  }
@@ -35820,16 +35820,16 @@ var CycleTimeOverTimeChart = ({
35820
35820
  onHourClick
35821
35821
  }) => {
35822
35822
  const MAX_DATA_POINTS = 40;
35823
- const containerRef = React148__default.useRef(null);
35824
- const [dimensions, setDimensions] = React148__default.useState({ width: 0, height: 0 });
35825
- const [hasValidData, setHasValidData] = React148__default.useState(false);
35826
- React148__default.useEffect(() => {
35823
+ const containerRef = React125__default.useRef(null);
35824
+ const [dimensions, setDimensions] = React125__default.useState({ width: 0, height: 0 });
35825
+ const [hasValidData, setHasValidData] = React125__default.useState(false);
35826
+ React125__default.useEffect(() => {
35827
35827
  const currentHasValidData = data && data.some((val) => val !== null && val > 0);
35828
35828
  if (currentHasValidData && !hasValidData) {
35829
35829
  setHasValidData(true);
35830
35830
  }
35831
35831
  }, [data, hasValidData]);
35832
- React148__default.useEffect(() => {
35832
+ React125__default.useEffect(() => {
35833
35833
  if (!containerRef.current) return;
35834
35834
  const observer = new ResizeObserver((entries) => {
35835
35835
  const entry = entries[0];
@@ -35867,7 +35867,7 @@ var CycleTimeOverTimeChart = ({
35867
35867
  const endLabel = shiftEnd && slotIndex === DURATION - 1 ? formatHourLabel(slotIndex + 1) : formatHourLabel(slotIndex + 1);
35868
35868
  return `${startLabel} - ${endLabel}`;
35869
35869
  };
35870
- const getDisplayData = React148__default.useCallback((rawData) => {
35870
+ const getDisplayData = React125__default.useCallback((rawData) => {
35871
35871
  if (xAxisMode === "hourly") return rawData;
35872
35872
  return rawData.slice(Math.max(0, rawData.length - MAX_DATA_POINTS));
35873
35873
  }, [xAxisMode]);
@@ -35875,7 +35875,7 @@ var CycleTimeOverTimeChart = ({
35875
35875
  const DURATION = displayData.length;
35876
35876
  const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
35877
35877
  const finalData = displayData;
35878
- const labelInterval = React148__default.useMemo(() => {
35878
+ const labelInterval = React125__default.useMemo(() => {
35879
35879
  if (xAxisMode === "hourly") {
35880
35880
  return Math.max(1, Math.ceil(DURATION / 8));
35881
35881
  }
@@ -35916,8 +35916,8 @@ var CycleTimeOverTimeChart = ({
35916
35916
  return `${minutes} minutes ${seconds} seconds ago`;
35917
35917
  }
35918
35918
  };
35919
- const getNumericValue = React148__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
35920
- const buildHourClickPayload = React148__default.useCallback((dataPoint) => {
35919
+ const getNumericValue = React125__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
35920
+ const buildHourClickPayload = React125__default.useCallback((dataPoint) => {
35921
35921
  if (!onHourClick || xAxisMode !== "hourly") {
35922
35922
  return null;
35923
35923
  }
@@ -35936,7 +35936,7 @@ var CycleTimeOverTimeChart = ({
35936
35936
  status: cycleTime !== null && cycleTime <= idealCycleTime ? "within_standard" : "above_standard"
35937
35937
  };
35938
35938
  }, [DURATION, getNumericValue, idealCycleTime, onHourClick, shiftEnd, shiftStart, xAxisMode]);
35939
- const renderChartTooltip = React148__default.useCallback((tooltipProps) => {
35939
+ const renderChartTooltip = React125__default.useCallback((tooltipProps) => {
35940
35940
  const { active, payload } = tooltipProps;
35941
35941
  if (!active || !Array.isArray(payload) || payload.length === 0) {
35942
35942
  return null;
@@ -36000,7 +36000,7 @@ var CycleTimeOverTimeChart = ({
36000
36000
  ] })
36001
36001
  ] });
36002
36002
  }, [getNumericValue, onHourClick, shiftStart, showIdleTime, xAxisMode]);
36003
- const renderCycleDot = React148__default.useCallback((props) => {
36003
+ const renderCycleDot = React125__default.useCallback((props) => {
36004
36004
  const { cx: cx2, cy, payload } = props;
36005
36005
  const cycleTime = getNumericValue(payload?.cycleTime);
36006
36006
  if (cycleTime === null) {
@@ -36040,7 +36040,7 @@ var CycleTimeOverTimeChart = ({
36040
36040
  }
36041
36041
  );
36042
36042
  }, [buildHourClickPayload, getNumericValue, idealCycleTime, onHourClick, selectedHourIndex]);
36043
- const renderCycleActiveDot = React148__default.useCallback((props) => {
36043
+ const renderCycleActiveDot = React125__default.useCallback((props) => {
36044
36044
  const { cx: cx2, cy, payload } = props;
36045
36045
  const cycleTime = getNumericValue(payload?.cycleTime);
36046
36046
  if (cycleTime === null) {
@@ -36069,7 +36069,7 @@ var CycleTimeOverTimeChart = ({
36069
36069
  }
36070
36070
  );
36071
36071
  }, [buildHourClickPayload, getNumericValue, idealCycleTime, onHourClick, selectedHourIndex]);
36072
- const renderIdleDot = React148__default.useCallback((props) => {
36072
+ const renderIdleDot = React125__default.useCallback((props) => {
36073
36073
  const { cx: cx2, cy, payload } = props;
36074
36074
  const idleMinutes = getNumericValue(payload?.idleMinutes);
36075
36075
  if (idleMinutes === null) {
@@ -36091,7 +36091,7 @@ var CycleTimeOverTimeChart = ({
36091
36091
  }
36092
36092
  );
36093
36093
  }, [getNumericValue, showIdleTime]);
36094
- const renderIdleActiveDot = React148__default.useCallback((props) => {
36094
+ const renderIdleActiveDot = React125__default.useCallback((props) => {
36095
36095
  const { cx: cx2, cy, payload } = props;
36096
36096
  const idleMinutes = getNumericValue(payload?.idleMinutes);
36097
36097
  if (idleMinutes === null || !showIdleTime) {
@@ -36109,7 +36109,7 @@ var CycleTimeOverTimeChart = ({
36109
36109
  }
36110
36110
  );
36111
36111
  }, [getNumericValue, showIdleTime]);
36112
- const chartData = React148__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
36112
+ const chartData = React125__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
36113
36113
  const cycleTime = getNumericValue(finalData[i]);
36114
36114
  const useIdleSlots = idleTimeSlots.length > 0;
36115
36115
  const idleSlot = useIdleSlots ? idleTimeSlots[i] ?? null : null;
@@ -36306,7 +36306,7 @@ var CycleTimeOverTimeChart = ({
36306
36306
  }
36307
36307
  );
36308
36308
  };
36309
- var Card = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36309
+ var Card = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36310
36310
  "div",
36311
36311
  {
36312
36312
  ref,
@@ -36318,7 +36318,7 @@ var Card = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
36318
36318
  }
36319
36319
  ));
36320
36320
  Card.displayName = "Card";
36321
- var CardHeader = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36321
+ var CardHeader = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36322
36322
  "div",
36323
36323
  {
36324
36324
  ref,
@@ -36327,7 +36327,7 @@ var CardHeader = React148.forwardRef(({ className, ...props }, ref) => /* @__PUR
36327
36327
  }
36328
36328
  ));
36329
36329
  CardHeader.displayName = "CardHeader";
36330
- var CardTitle = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36330
+ var CardTitle = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36331
36331
  "h3",
36332
36332
  {
36333
36333
  ref,
@@ -36339,7 +36339,7 @@ var CardTitle = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE
36339
36339
  }
36340
36340
  ));
36341
36341
  CardTitle.displayName = "CardTitle";
36342
- var CardDescription = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36342
+ var CardDescription = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36343
36343
  "p",
36344
36344
  {
36345
36345
  ref,
@@ -36348,9 +36348,9 @@ var CardDescription = React148.forwardRef(({ className, ...props }, ref) => /* @
36348
36348
  }
36349
36349
  ));
36350
36350
  CardDescription.displayName = "CardDescription";
36351
- var CardContent = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
36351
+ var CardContent = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
36352
36352
  CardContent.displayName = "CardContent";
36353
- var CardFooter = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36353
+ var CardFooter = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36354
36354
  "div",
36355
36355
  {
36356
36356
  ref,
@@ -36426,7 +36426,7 @@ var buttonVariants = cva(
36426
36426
  }
36427
36427
  }
36428
36428
  );
36429
- var Button = React148.forwardRef(
36429
+ var Button = React125.forwardRef(
36430
36430
  ({ className, variant, size, asChild = false, ...props }, ref) => {
36431
36431
  const Comp = asChild ? Slot : "button";
36432
36432
  return /* @__PURE__ */ jsx(
@@ -37182,16 +37182,38 @@ var HourlyOutputChartComponent = ({
37182
37182
  onHourClick,
37183
37183
  onWatchClipsClick,
37184
37184
  onAiSummaryClick,
37185
+ onSelectSku,
37185
37186
  className = ""
37186
37187
  }) => {
37187
- const containerRef = React148__default.useRef(null);
37188
- const [containerReady, setContainerReady] = React148__default.useState(false);
37189
- const [containerWidth, setContainerWidth] = React148__default.useState(0);
37190
- const [hoveredSkuRailLabel, setHoveredSkuRailLabel] = React148__default.useState(null);
37191
- const [isTooltipHovered, setIsTooltipHovered] = React148__default.useState(false);
37192
- const lastTooltipDataRef = React148__default.useRef(null);
37193
- const tooltipHoverTimeoutRef = React148__default.useRef(null);
37194
- const idleSlots = React148__default.useMemo(
37188
+ const containerRef = React125__default.useRef(null);
37189
+ const [containerReady, setContainerReady] = React125__default.useState(false);
37190
+ const [containerWidth, setContainerWidth] = React125__default.useState(0);
37191
+ const [hoveredSkuRailLabel, setHoveredSkuRailLabel] = React125__default.useState(null);
37192
+ const [isTooltipHovered, setIsTooltipHovered] = React125__default.useState(false);
37193
+ const [forceHideTooltip, setForceHideTooltip] = React125__default.useState(false);
37194
+ const lastTooltipDataRef = React125__default.useRef(null);
37195
+ const tooltipHoverTimeoutRef = React125__default.useRef(null);
37196
+ const clearTooltipHoverTimeout = React125__default.useCallback(() => {
37197
+ if (tooltipHoverTimeoutRef.current) {
37198
+ clearTimeout(tooltipHoverTimeoutRef.current);
37199
+ tooltipHoverTimeoutRef.current = null;
37200
+ }
37201
+ }, []);
37202
+ const hideInteractiveTooltip = React125__default.useCallback(() => {
37203
+ clearTooltipHoverTimeout();
37204
+ setIsTooltipHovered(false);
37205
+ setForceHideTooltip(true);
37206
+ lastTooltipDataRef.current = null;
37207
+ }, [clearTooltipHoverTimeout]);
37208
+ const scheduleInteractiveTooltipHide = React125__default.useCallback((delayMs = 120) => {
37209
+ clearTooltipHoverTimeout();
37210
+ tooltipHoverTimeoutRef.current = setTimeout(() => {
37211
+ setIsTooltipHovered(false);
37212
+ lastTooltipDataRef.current = null;
37213
+ tooltipHoverTimeoutRef.current = null;
37214
+ }, delayMs);
37215
+ }, [clearTooltipHoverTimeout]);
37216
+ const idleSlots = React125__default.useMemo(
37195
37217
  () => buildHourlyIdleSlots({
37196
37218
  idleTimeHourly,
37197
37219
  shiftStart,
@@ -37200,12 +37222,12 @@ var HourlyOutputChartComponent = ({
37200
37222
  [idleTimeHourly, shiftStart, shiftEnd]
37201
37223
  );
37202
37224
  const SHIFT_DURATION = idleSlots.length;
37203
- const [animatedData, setAnimatedData] = React148__default.useState(
37225
+ const [animatedData, setAnimatedData] = React125__default.useState(
37204
37226
  () => Array(SHIFT_DURATION).fill(0)
37205
37227
  );
37206
- const prevDataRef = React148__default.useRef(Array(SHIFT_DURATION).fill(0));
37207
- const animationFrameRef = React148__default.useRef(null);
37208
- React148__default.useEffect(() => {
37228
+ const prevDataRef = React125__default.useRef(Array(SHIFT_DURATION).fill(0));
37229
+ const animationFrameRef = React125__default.useRef(null);
37230
+ React125__default.useEffect(() => {
37209
37231
  setAnimatedData((prev) => {
37210
37232
  if (prev.length !== SHIFT_DURATION) {
37211
37233
  return Array(SHIFT_DURATION).fill(0);
@@ -37214,14 +37236,14 @@ var HourlyOutputChartComponent = ({
37214
37236
  });
37215
37237
  prevDataRef.current = Array(SHIFT_DURATION).fill(0);
37216
37238
  }, [SHIFT_DURATION]);
37217
- const [idleBarState, setIdleBarState] = React148__default.useState({
37239
+ const [idleBarState, setIdleBarState] = React125__default.useState({
37218
37240
  visible: showIdleTime,
37219
37241
  key: 0,
37220
37242
  shouldAnimate: false
37221
37243
  });
37222
- const prevShowIdleTimeRef = React148__default.useRef(showIdleTime);
37223
- const stateUpdateTimeoutRef = React148__default.useRef(null);
37224
- React148__default.useEffect(() => {
37244
+ const prevShowIdleTimeRef = React125__default.useRef(showIdleTime);
37245
+ const stateUpdateTimeoutRef = React125__default.useRef(null);
37246
+ React125__default.useEffect(() => {
37225
37247
  if (stateUpdateTimeoutRef.current) {
37226
37248
  clearTimeout(stateUpdateTimeoutRef.current);
37227
37249
  }
@@ -37246,7 +37268,7 @@ var HourlyOutputChartComponent = ({
37246
37268
  }
37247
37269
  };
37248
37270
  }, [showIdleTime]);
37249
- const animateToNewData = React148__default.useCallback((targetData) => {
37271
+ const animateToNewData = React125__default.useCallback((targetData) => {
37250
37272
  const startData = [...prevDataRef.current];
37251
37273
  const startTime = performance.now();
37252
37274
  const duration = 1200;
@@ -37276,7 +37298,7 @@ var HourlyOutputChartComponent = ({
37276
37298
  }
37277
37299
  animationFrameRef.current = requestAnimationFrame(animate);
37278
37300
  }, []);
37279
- React148__default.useEffect(() => {
37301
+ React125__default.useEffect(() => {
37280
37302
  if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
37281
37303
  const shiftData = data.slice(0, SHIFT_DURATION);
37282
37304
  animateToNewData(shiftData);
@@ -37287,14 +37309,15 @@ var HourlyOutputChartComponent = ({
37287
37309
  }
37288
37310
  };
37289
37311
  }, [data, animateToNewData]);
37290
- React148__default.useEffect(() => {
37312
+ React125__default.useEffect(() => {
37313
+ const handleWindowBlur = () => hideInteractiveTooltip();
37314
+ window.addEventListener("blur", handleWindowBlur);
37291
37315
  return () => {
37292
- if (tooltipHoverTimeoutRef.current) {
37293
- clearTimeout(tooltipHoverTimeoutRef.current);
37294
- }
37316
+ window.removeEventListener("blur", handleWindowBlur);
37317
+ clearTooltipHoverTimeout();
37295
37318
  };
37296
- }, []);
37297
- React148__default.useEffect(() => {
37319
+ }, [clearTooltipHoverTimeout, hideInteractiveTooltip]);
37320
+ React125__default.useEffect(() => {
37298
37321
  const checkContainerDimensions = () => {
37299
37322
  if (containerRef.current) {
37300
37323
  const rect = containerRef.current.getBoundingClientRect();
@@ -37320,7 +37343,7 @@ var HourlyOutputChartComponent = ({
37320
37343
  clearTimeout(fallbackTimeout);
37321
37344
  };
37322
37345
  }, []);
37323
- const xAxisConfig = React148__default.useMemo(() => {
37346
+ const xAxisConfig = React125__default.useMemo(() => {
37324
37347
  if (containerWidth >= 960) {
37325
37348
  return {
37326
37349
  interval: 0,
@@ -37341,13 +37364,13 @@ var HourlyOutputChartComponent = ({
37341
37364
  }
37342
37365
  return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6 };
37343
37366
  }, [containerWidth]);
37344
- const shiftWindow = React148__default.useMemo(() => resolveShiftWindow2({
37367
+ const shiftWindow = React125__default.useMemo(() => resolveShiftWindow2({
37345
37368
  shiftStart,
37346
37369
  slotCount: SHIFT_DURATION,
37347
37370
  shiftDate,
37348
37371
  timezone
37349
37372
  }), [shiftStart, shiftEnd, SHIFT_DURATION, shiftDate, timezone]);
37350
- const fallbackTimelineEndOffset = React148__default.useMemo(
37373
+ const fallbackTimelineEndOffset = React125__default.useMemo(
37351
37374
  () => resolveTimelineEndOffset({
37352
37375
  shiftStart,
37353
37376
  shiftEnd,
@@ -37357,7 +37380,7 @@ var HourlyOutputChartComponent = ({
37357
37380
  }),
37358
37381
  [shiftStart, shiftEnd, SHIFT_DURATION, shiftDate, timezone]
37359
37382
  );
37360
- const observedTimelineEndOffset = React148__default.useMemo(() => {
37383
+ const observedTimelineEndOffset = React125__default.useMemo(() => {
37361
37384
  let lastObservedMinute = -1;
37362
37385
  idleSlots.forEach((slot) => {
37363
37386
  slot.idleArray.forEach((value, minuteIndex) => {
@@ -37373,7 +37396,7 @@ var HourlyOutputChartComponent = ({
37373
37396
  return Math.min((lastObservedMinute + 1) / 60, SHIFT_DURATION);
37374
37397
  }, [idleSlots, SHIFT_DURATION]);
37375
37398
  const timelineEndOffset = observedTimelineEndOffset ?? fallbackTimelineEndOffset;
37376
- const targetLineEndOffset = React148__default.useMemo(() => {
37399
+ const targetLineEndOffset = React125__default.useMemo(() => {
37377
37400
  if (timelineEndOffset >= SHIFT_DURATION) {
37378
37401
  return SHIFT_DURATION;
37379
37402
  }
@@ -37382,7 +37405,7 @@ var HourlyOutputChartComponent = ({
37382
37405
  }
37383
37406
  return Math.min(Math.floor(timelineEndOffset) + 1, SHIFT_DURATION);
37384
37407
  }, [timelineEndOffset, SHIFT_DURATION]);
37385
- const skuTimelineSegments = React148__default.useMemo(() => {
37408
+ const skuTimelineSegments = React125__default.useMemo(() => {
37386
37409
  if (!skuSegments || skuSegments.length === 0 || !shiftWindow || timelineEndOffset <= 0) {
37387
37410
  return [];
37388
37411
  }
@@ -37416,18 +37439,18 @@ var HourlyOutputChartComponent = ({
37416
37439
  };
37417
37440
  }).filter((segment) => segment.end > segment.start);
37418
37441
  }, [skuSegments, shiftWindow, timelineEndOffset, pphThreshold]);
37419
- const targetTimelineSegments = React148__default.useMemo(() => {
37442
+ const targetTimelineSegments = React125__default.useMemo(() => {
37420
37443
  if (skuTimelineSegments.length === 0) return [];
37421
37444
  return skuTimelineSegments.map((segment, index) => ({
37422
37445
  ...segment,
37423
37446
  end: index === skuTimelineSegments.length - 1 ? Math.max(segment.start, targetLineEndOffset) : segment.end
37424
37447
  })).filter((segment) => segment.end > segment.start);
37425
37448
  }, [skuTimelineSegments, targetLineEndOffset]);
37426
- const hasExplicitHourlyTargetOutputProp = React148__default.useMemo(
37449
+ const hasExplicitHourlyTargetOutputProp = React125__default.useMemo(
37427
37450
  () => hourlyTargetOutput !== void 0,
37428
37451
  [hourlyTargetOutput]
37429
37452
  );
37430
- const fallbackHourlyTargetOutput = React148__default.useMemo(() => {
37453
+ const fallbackHourlyTargetOutput = React125__default.useMemo(() => {
37431
37454
  if (hasExplicitHourlyTargetOutputProp) return void 0;
37432
37455
  if (skuTimelineSegments.length > 0) return void 0;
37433
37456
  const plan = buildHourlyTargetPlan({
@@ -37447,19 +37470,19 @@ var HourlyOutputChartComponent = ({
37447
37470
  shiftBreaks,
37448
37471
  pphThreshold
37449
37472
  ]);
37450
- const effectiveHourlyTargetOutput = React148__default.useMemo(
37473
+ const effectiveHourlyTargetOutput = React125__default.useMemo(
37451
37474
  () => hasExplicitHourlyTargetOutputProp ? hourlyTargetOutput : fallbackHourlyTargetOutput,
37452
37475
  [hasExplicitHourlyTargetOutputProp, hourlyTargetOutput, fallbackHourlyTargetOutput]
37453
37476
  );
37454
- const hasHourlyTargetOutputProp = React148__default.useMemo(
37477
+ const hasHourlyTargetOutputProp = React125__default.useMemo(
37455
37478
  () => effectiveHourlyTargetOutput !== void 0,
37456
37479
  [effectiveHourlyTargetOutput]
37457
37480
  );
37458
- const hasExplicitHourlyTargets = React148__default.useMemo(
37481
+ const hasExplicitHourlyTargets = React125__default.useMemo(
37459
37482
  () => Array.isArray(effectiveHourlyTargetOutput) && effectiveHourlyTargetOutput.some((value) => value !== null && value !== void 0),
37460
37483
  [effectiveHourlyTargetOutput]
37461
37484
  );
37462
- const hourlyTargetSegments = React148__default.useMemo(() => {
37485
+ const hourlyTargetSegments = React125__default.useMemo(() => {
37463
37486
  if (!hasExplicitHourlyTargets) return [];
37464
37487
  const segments = [];
37465
37488
  let runStart = null;
@@ -37491,7 +37514,7 @@ var HourlyOutputChartComponent = ({
37491
37514
  flush(SHIFT_DURATION);
37492
37515
  return segments.filter((segment) => segment.end > segment.start);
37493
37516
  }, [SHIFT_DURATION, hasExplicitHourlyTargets, effectiveHourlyTargetOutput]);
37494
- const activeSkuHourIndices = React148__default.useMemo(() => {
37517
+ const activeSkuHourIndices = React125__default.useMemo(() => {
37495
37518
  const indices = /* @__PURE__ */ new Set();
37496
37519
  const targets = Array(SHIFT_DURATION).fill(pphThreshold);
37497
37520
  if (!skuSegments || !shiftWindow) return { indices, targets, hasTimeline: false };
@@ -37524,7 +37547,7 @@ var HourlyOutputChartComponent = ({
37524
37547
  }
37525
37548
  return { indices, targets, hasTimeline: true };
37526
37549
  }, [skuSegments, activeSkuId, shiftWindow, SHIFT_DURATION, pphThreshold]);
37527
- const chartData = React148__default.useMemo(() => {
37550
+ const chartData = React125__default.useMemo(() => {
37528
37551
  const { indices, targets, hasTimeline } = activeSkuHourIndices;
37529
37552
  return Array.from({ length: SHIFT_DURATION }, (_, i) => {
37530
37553
  const idleSlot = idleSlots[i];
@@ -37553,7 +37576,7 @@ var HourlyOutputChartComponent = ({
37553
37576
  };
37554
37577
  });
37555
37578
  }, [animatedData, data, pphThreshold, idleSlots, SHIFT_DURATION, activeSkuHourIndices, activeSkuId, effectiveHourlyTargetOutput, hasHourlyTargetOutputProp, selectedHourIndex]);
37556
- const renderSkuTimelineRail = React148__default.useCallback((props) => {
37579
+ const renderSkuTimelineRail = React125__default.useCallback((props) => {
37557
37580
  if (!skuTimelineSegments.length || SHIFT_DURATION <= 0) return null;
37558
37581
  const offset = props?.offset;
37559
37582
  if (!offset) return null;
@@ -37617,6 +37640,8 @@ var HourlyOutputChartComponent = ({
37617
37640
  width: hoverHitWidth,
37618
37641
  height: hoverHitHeight,
37619
37642
  fill: "transparent",
37643
+ style: { cursor: onSelectSku ? "pointer" : "default" },
37644
+ onClick: () => onSelectSku?.(isActive ? null : segment.skuId),
37620
37645
  onMouseEnter: () => showHoverLabel(segment.label, xStart + segmentWidth / 2, railY),
37621
37646
  onMouseLeave: () => setHoveredSkuRailLabel((current) => current?.label === segment.label ? null : current)
37622
37647
  }
@@ -37701,8 +37726,8 @@ var HourlyOutputChartComponent = ({
37701
37726
  ] }, `sku-rail-${segment.skuId}-${segment.start}-${index}`);
37702
37727
  })
37703
37728
  ] });
37704
- }, [skuTimelineSegments, SHIFT_DURATION, activeSkuId]);
37705
- const IdleBar = React148__default.useMemo(() => {
37729
+ }, [skuTimelineSegments, SHIFT_DURATION, activeSkuId, onSelectSku]);
37730
+ const IdleBar = React125__default.useMemo(() => {
37706
37731
  if (!idleBarState.visible) return null;
37707
37732
  return /* @__PURE__ */ jsx(
37708
37733
  Bar,
@@ -37796,7 +37821,7 @@ var HourlyOutputChartComponent = ({
37796
37821
  }
37797
37822
  return filteredTicks;
37798
37823
  };
37799
- const renderTargetLine = React148__default.useCallback((props) => {
37824
+ const renderTargetLine = React125__default.useCallback((props) => {
37800
37825
  const { offset, yAxisMap } = props;
37801
37826
  if (!offset || !yAxisMap || SHIFT_DURATION <= 0 || targetLineEndOffset <= 0) return null;
37802
37827
  const { left, width } = offset;
@@ -37926,378 +37951,386 @@ var HourlyOutputChartComponent = ({
37926
37951
  className: `w-full h-full min-w-0 flex flex-col ${className}`,
37927
37952
  style: { minHeight: "200px", minWidth: 0 },
37928
37953
  children: [
37929
- containerReady ? /* @__PURE__ */ jsxs("div", { className: "flex-1 min-h-0 relative", children: [
37930
- /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
37931
- BarChart$1,
37932
- {
37933
- data: chartData,
37934
- margin: {
37935
- // Reserve headroom for the SKU timeline rail + staggered
37936
- // labels only when SKU segments are rendered. Non-SKU charts
37937
- // keep the original 10px top so recharts has enough vertical
37938
- // space to show the target (pph) tick label on the Y-axis.
37939
- top: skuTimelineSegments.length > 0 ? 40 : 10,
37940
- right: 10,
37941
- bottom: 10,
37942
- left: 6
37943
- },
37944
- barCategoryGap: "25%",
37945
- children: [
37946
- /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", vertical: false }),
37947
- /* @__PURE__ */ jsx(
37948
- XAxis,
37949
- {
37950
- xAxisId: "default",
37951
- dataKey: "hour",
37952
- tick: { fontSize: xAxisConfig.tickFont },
37953
- interval: xAxisConfig.interval,
37954
- angle: xAxisConfig.angle,
37955
- textAnchor: "end",
37956
- tickMargin: xAxisConfig.tickMargin,
37957
- height: xAxisConfig.height
37958
- }
37959
- ),
37960
- /* @__PURE__ */ jsx(
37961
- XAxis,
37962
- {
37963
- xAxisId: "sku",
37964
- type: "number",
37965
- dataKey: "skuIndex",
37966
- domain: [0, Math.max(SHIFT_DURATION, 0)],
37967
- hide: true,
37968
- allowDataOverflow: true
37969
- }
37970
- ),
37971
- /* @__PURE__ */ jsx(
37972
- YAxis,
37973
- {
37974
- yAxisId: "default",
37975
- tickMargin: 8,
37976
- width: 48,
37977
- domain: [0, maxYValue],
37978
- ticks: generateYAxisTicks(),
37979
- tickFormatter: (value) => value,
37980
- tick: (props) => {
37981
- const { x, y, payload } = props;
37982
- return /* @__PURE__ */ jsx("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ jsx(
37983
- "text",
37984
- {
37985
- x: -2,
37986
- y: 0,
37987
- dy: 4,
37988
- textAnchor: "end",
37989
- fill: "#666",
37990
- fontSize: 12,
37991
- children: payload.value
37992
- },
37993
- `tick-${payload.value}-${x}-${y}`
37994
- ) });
37995
- }
37996
- }
37997
- ),
37998
- /* @__PURE__ */ jsx(YAxis, { yAxisId: "idle", domain: [0, 60], hide: true }),
37999
- /* @__PURE__ */ jsx(
38000
- Tooltip,
38001
- {
38002
- cursor: { fill: "#f1f5f9" },
38003
- shared: false,
38004
- offset: -5,
38005
- wrapperStyle: { pointerEvents: "auto", zIndex: 100 },
38006
- active: isTooltipHovered ? true : void 0,
38007
- isAnimationActive: false,
38008
- contentStyle: { backgroundColor: "transparent", border: "none", padding: 0 },
38009
- content: (props) => {
38010
- const activeData = props.active && props.payload && props.payload.length > 0 ? props.payload[0].payload : null;
38011
- const data2 = activeData || (isTooltipHovered ? lastTooltipDataRef.current : null);
38012
- if (!data2)
38013
- return null;
38014
- if (activeData) {
38015
- lastTooltipDataRef.current = activeData;
37954
+ containerReady ? /* @__PURE__ */ jsxs(
37955
+ "div",
37956
+ {
37957
+ "data-testid": "hourly-output-chart-viewport",
37958
+ className: "flex-1 min-h-0 relative",
37959
+ onMouseEnter: () => {
37960
+ setForceHideTooltip(false);
37961
+ clearTooltipHoverTimeout();
37962
+ },
37963
+ onMouseLeave: () => {
37964
+ setForceHideTooltip(true);
37965
+ scheduleInteractiveTooltipHide(80);
37966
+ },
37967
+ children: [
37968
+ /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
37969
+ BarChart$1,
37970
+ {
37971
+ data: chartData,
37972
+ margin: {
37973
+ // Reserve headroom for the SKU timeline rail + staggered
37974
+ // labels only when SKU segments are rendered. Non-SKU charts
37975
+ // keep the original 10px top so recharts has enough vertical
37976
+ // space to show the target (pph) tick label on the Y-axis.
37977
+ top: skuTimelineSegments.length > 0 ? 40 : 10,
37978
+ right: 10,
37979
+ bottom: 10,
37980
+ left: 6
37981
+ },
37982
+ barCategoryGap: "25%",
37983
+ children: [
37984
+ /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", vertical: false }),
37985
+ /* @__PURE__ */ jsx(
37986
+ XAxis,
37987
+ {
37988
+ xAxisId: "default",
37989
+ dataKey: "hour",
37990
+ tick: { fontSize: xAxisConfig.tickFont },
37991
+ interval: xAxisConfig.interval,
37992
+ angle: xAxisConfig.angle,
37993
+ textAnchor: "end",
37994
+ tickMargin: xAxisConfig.tickMargin,
37995
+ height: xAxisConfig.height
38016
37996
  }
38017
- const idlePeriods = showIdleTime ? getHourlyIdlePeriods({
38018
- idleArray: data2.idleArray,
38019
- shiftStart,
38020
- hourIndex: Number.isFinite(data2.hourIndex) ? data2.hourIndex : 0
38021
- }) : [];
38022
- const tooltipHourIndex = Number.isFinite(data2.hourIndex) ? data2.hourIndex : 0;
38023
- const { startTime, endTime } = buildHourClipFilterWindow({
38024
- shiftStart,
38025
- shiftEnd,
38026
- hourIndex: tooltipHourIndex,
38027
- slotCount: SHIFT_DURATION
38028
- });
38029
- const clickPayload = {
38030
- hourIndex: tooltipHourIndex,
38031
- timeRange: data2.timeRange,
38032
- startTime,
38033
- endTime,
38034
- output: Math.round(data2.originalOutput || 0),
38035
- target: data2.target,
38036
- status: data2.status
38037
- };
38038
- return /* @__PURE__ */ jsx(
38039
- "div",
38040
- {
38041
- className: "p-3 -m-3 pointer-events-auto",
38042
- style: { cursor: "default" },
38043
- onMouseEnter: () => {
38044
- if (tooltipHoverTimeoutRef.current) {
38045
- clearTimeout(tooltipHoverTimeoutRef.current);
38046
- tooltipHoverTimeoutRef.current = null;
38047
- }
38048
- setIsTooltipHovered(true);
38049
- },
38050
- onMouseLeave: () => {
38051
- if (tooltipHoverTimeoutRef.current) {
38052
- clearTimeout(tooltipHoverTimeoutRef.current);
38053
- }
38054
- tooltipHoverTimeoutRef.current = setTimeout(() => {
38055
- setIsTooltipHovered(false);
38056
- tooltipHoverTimeoutRef.current = null;
38057
- }, 120);
38058
- },
38059
- children: /* @__PURE__ */ jsxs("div", { className: "bg-white/95 backdrop-blur-md border border-slate-200/60 shadow-xl shadow-slate-200/40 rounded-xl p-4 min-w-[240px] text-slate-700 pointer-events-auto", children: [
38060
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4 pb-3 border-b border-slate-100", children: [
38061
- /* @__PURE__ */ jsx("p", { className: "font-semibold text-slate-900 text-sm tracking-tight", children: data2.timeRange }),
38062
- onAiSummaryClick && /* @__PURE__ */ jsxs(
38063
- "button",
38064
- {
38065
- onClick: (e) => {
38066
- e.stopPropagation();
38067
- onAiSummaryClick(clickPayload);
38068
- },
38069
- className: "flex items-center gap-1 px-2 py-1 -mr-1 rounded-md border border-slate-200 bg-white hover:bg-slate-50 text-[11px] font-medium text-slate-600 shadow-sm transition-colors",
38070
- children: [
38071
- /* @__PURE__ */ jsx(SparklesIcon, { className: "w-3.5 h-3.5" }),
38072
- "Ask AI"
38073
- ]
38074
- }
38075
- )
38076
- ] }),
38077
- /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
38078
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
38079
- /* @__PURE__ */ jsx("span", { className: "text-sm text-slate-500 font-medium tracking-wide", children: "Output" }),
38080
- /* @__PURE__ */ jsxs("span", { className: "font-bold text-slate-900 text-sm", children: [
38081
- Math.round(data2.output),
38082
- " ",
38083
- /* @__PURE__ */ jsx("span", { className: "text-slate-400 font-normal text-xs ml-0.5", children: "units" })
38084
- ] })
38085
- ] }),
38086
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
38087
- /* @__PURE__ */ jsx("span", { className: "text-sm text-slate-500 font-medium tracking-wide", children: "Target" }),
38088
- /* @__PURE__ */ jsxs("span", { className: "font-bold text-slate-700 text-sm", children: [
38089
- Math.round(data2.target),
38090
- " ",
38091
- /* @__PURE__ */ jsx("span", { className: "text-slate-400 font-normal text-xs ml-0.5", children: "units" })
38092
- ] })
38093
- ] }),
38094
- showIdleTime && data2.idleMinutes > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
38095
- /* @__PURE__ */ jsx("div", { className: "pt-3 mt-3 border-t border-slate-100", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
38096
- /* @__PURE__ */ jsx("span", { className: "text-sm text-slate-500 font-medium tracking-wide", children: "Idle Time" }),
38097
- /* @__PURE__ */ jsxs("span", { className: "font-bold text-orange-600 text-sm flex items-center gap-1.5", children: [
38098
- /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-orange-500 shadow-[0_0_6px_rgba(249,115,22,0.6)] animate-pulse" }),
38099
- data2.idleMinutes,
38100
- " ",
38101
- /* @__PURE__ */ jsx("span", { className: "text-orange-500/70 font-normal text-xs ml-0.5", children: "min" })
38102
- ] })
38103
- ] }) }),
38104
- idlePeriods.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-3 bg-slate-50/80 rounded-lg p-3 border border-slate-100/50", children: [
38105
- /* @__PURE__ */ jsx("p", { className: "font-semibold text-slate-400 text-[10px] mb-2.5 uppercase tracking-wider", children: "Idle Periods" }),
38106
- /* @__PURE__ */ jsx("div", { className: "space-y-2.5 max-h-32 overflow-y-auto pr-1 custom-scrollbar", children: idlePeriods.map((period, index) => {
38107
- return /* @__PURE__ */ jsxs(
38108
- "div",
38109
- {
38110
- className: "flex items-start gap-2.5 text-xs",
38111
- children: [
38112
- /* @__PURE__ */ jsx("div", { className: "mt-[5px] w-1.5 h-1.5 bg-orange-400 rounded-full flex-shrink-0 shadow-[0_0_4px_rgba(251,146,60,0.5)]" }),
38113
- /* @__PURE__ */ jsx("span", { className: "text-slate-700 font-medium tracking-tight", children: period.duration === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
38114
- period.startTime,
38115
- " ",
38116
- /* @__PURE__ */ jsxs("span", { className: "text-slate-400 font-normal ml-1", children: [
38117
- "(",
38118
- period.duration,
38119
- "m)"
38120
- ] })
38121
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
38122
- period.startTime,
38123
- " ",
38124
- /* @__PURE__ */ jsx("span", { className: "text-slate-400 mx-0.5", children: "\u2192" }),
38125
- " ",
38126
- period.endTime,
38127
- " ",
38128
- /* @__PURE__ */ jsxs("span", { className: "text-slate-400 font-normal ml-1", children: [
38129
- "(",
38130
- period.duration,
38131
- "m)"
38132
- ] })
38133
- ] }) })
38134
- ]
38135
- },
38136
- index
38137
- );
38138
- }) })
38139
- ] })
38140
- ] }),
38141
- onWatchClipsClick && /* @__PURE__ */ jsx("div", { className: "pt-3 mt-3 border-t border-slate-100 flex items-center", children: /* @__PURE__ */ jsxs(
38142
- "button",
38143
- {
38144
- onClick: (e) => {
38145
- e.stopPropagation();
38146
- onWatchClipsClick(clickPayload);
38147
- },
38148
- className: "w-full rounded-md border border-slate-200 bg-white hover:bg-slate-50 px-2 py-1.5 text-xs font-semibold text-slate-700 transition-colors flex items-center justify-center gap-1.5 shadow-sm",
38149
- children: [
38150
- /* @__PURE__ */ jsx(PlayCircleIcon, { className: "w-4 h-4 text-blue-500" }),
38151
- "Watch Clips"
38152
- ]
38153
- }
38154
- ) }),
38155
- onHourClick && !onWatchClipsClick && !onAiSummaryClick && /* @__PURE__ */ jsx("div", { className: "pt-3 mt-3 border-t border-slate-100", children: /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-blue-100 bg-blue-50/70 px-3 py-2 text-xs font-semibold text-blue-700 text-center", children: "Click to inspect hour" }) })
38156
- ] })
38157
- ] })
37997
+ ),
37998
+ /* @__PURE__ */ jsx(
37999
+ XAxis,
38000
+ {
38001
+ xAxisId: "sku",
38002
+ type: "number",
38003
+ dataKey: "skuIndex",
38004
+ domain: [0, Math.max(SHIFT_DURATION, 0)],
38005
+ hide: true,
38006
+ allowDataOverflow: true
38007
+ }
38008
+ ),
38009
+ /* @__PURE__ */ jsx(
38010
+ YAxis,
38011
+ {
38012
+ yAxisId: "default",
38013
+ tickMargin: 8,
38014
+ width: 48,
38015
+ domain: [0, maxYValue],
38016
+ ticks: generateYAxisTicks(),
38017
+ tickFormatter: (value) => value,
38018
+ tick: (props) => {
38019
+ const { x, y, payload } = props;
38020
+ return /* @__PURE__ */ jsx("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ jsx(
38021
+ "text",
38022
+ {
38023
+ x: -2,
38024
+ y: 0,
38025
+ dy: 4,
38026
+ textAnchor: "end",
38027
+ fill: "#666",
38028
+ fontSize: 12,
38029
+ children: payload.value
38030
+ },
38031
+ `tick-${payload.value}-${x}-${y}`
38032
+ ) });
38158
38033
  }
38159
- );
38160
- },
38161
- animationDuration: 200
38162
- }
38163
- ),
38164
- /* @__PURE__ */ jsx(Customized, { component: renderTargetLine }),
38165
- /* @__PURE__ */ jsx(Customized, { component: renderSkuTimelineRail }),
38166
- /* @__PURE__ */ jsxs(
38167
- Bar,
38168
- {
38169
- xAxisId: "default",
38170
- dataKey: "output",
38171
- yAxisId: "default",
38172
- maxBarSize: 35,
38173
- radius: [10, 10, 0, 0],
38174
- isAnimationActive: false,
38175
- children: [
38176
- chartData.map((entry, index) => /* @__PURE__ */ jsx(
38177
- Cell,
38178
- {
38179
- fill: entry.color,
38180
- stroke: entry.isSelected ? "#0f172a" : "transparent",
38181
- strokeWidth: entry.isSelected ? 2 : 0,
38182
- style: {
38183
- filter: entry.isHighlighted || entry.isSelected ? "drop-shadow(0 4px 6px rgba(0, 0, 0, 0.12)) brightness(1.05)" : "brightness(1)",
38184
- transform: entry.isHighlighted || entry.isSelected ? "translateY(-4px)" : "translateY(0)",
38185
- opacity: entry.isDimmed ? 0.4 : 1,
38186
- transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
38187
- cursor: onHourClick || onWatchClipsClick || onAiSummaryClick ? "pointer" : "default"
38188
- },
38189
- onMouseEnter: (e) => {
38190
- const target = e.target;
38191
- target.style.filter = "drop-shadow(0 4px 6px rgba(0, 0, 0, 0.12)) brightness(1.05)";
38192
- target.style.transform = "translateY(-4px)";
38193
- target.style.opacity = "1";
38194
- },
38195
- onMouseLeave: (e) => {
38196
- const target = e.target;
38197
- target.style.filter = entry.isHighlighted || entry.isSelected ? "drop-shadow(0 4px 6px rgba(0, 0, 0, 0.12)) brightness(1.05)" : "brightness(1)";
38198
- target.style.transform = entry.isHighlighted || entry.isSelected ? "translateY(-4px)" : "translateY(0)";
38199
- target.style.opacity = entry.isDimmed ? "0.4" : "1";
38200
- },
38201
- onClick: () => {
38202
- if (!onHourClick && !onWatchClipsClick && !onAiSummaryClick) return;
38203
- const { startTime, endTime } = buildHourClipFilterWindow({
38204
- shiftStart,
38205
- shiftEnd,
38206
- hourIndex: entry.hourIndex,
38207
- slotCount: SHIFT_DURATION
38208
- });
38209
- const payload = {
38210
- hourIndex: entry.hourIndex,
38211
- timeRange: entry.timeRange,
38212
- startTime,
38213
- endTime,
38214
- output: Math.round(entry.originalOutput || 0),
38215
- target: entry.target,
38216
- status: entry.status
38217
- };
38218
- if (onHourClick) onHourClick(payload);
38034
+ }
38035
+ ),
38036
+ /* @__PURE__ */ jsx(YAxis, { yAxisId: "idle", domain: [0, 60], hide: true }),
38037
+ /* @__PURE__ */ jsx(
38038
+ Tooltip,
38039
+ {
38040
+ cursor: { fill: "#f1f5f9" },
38041
+ shared: false,
38042
+ offset: -5,
38043
+ wrapperStyle: { pointerEvents: "auto", zIndex: 100, transition: "opacity 0.2s ease-out, transform 0.15s ease-out" },
38044
+ active: forceHideTooltip ? false : isTooltipHovered ? true : void 0,
38045
+ isAnimationActive: false,
38046
+ contentStyle: { backgroundColor: "transparent", border: "none", padding: 0 },
38047
+ content: (props) => {
38048
+ const activeData = props.active && props.payload && props.payload.length > 0 ? props.payload[0].payload : null;
38049
+ const data2 = activeData || (isTooltipHovered ? lastTooltipDataRef.current : null);
38050
+ if (!data2)
38051
+ return null;
38052
+ if (activeData) {
38053
+ lastTooltipDataRef.current = activeData;
38219
38054
  }
38055
+ const idlePeriods = showIdleTime ? getHourlyIdlePeriods({
38056
+ idleArray: data2.idleArray,
38057
+ shiftStart,
38058
+ hourIndex: Number.isFinite(data2.hourIndex) ? data2.hourIndex : 0
38059
+ }) : [];
38060
+ const tooltipHourIndex = Number.isFinite(data2.hourIndex) ? data2.hourIndex : 0;
38061
+ const { startTime, endTime } = buildHourClipFilterWindow({
38062
+ shiftStart,
38063
+ shiftEnd,
38064
+ hourIndex: tooltipHourIndex,
38065
+ slotCount: SHIFT_DURATION
38066
+ });
38067
+ const clickPayload = {
38068
+ hourIndex: tooltipHourIndex,
38069
+ timeRange: data2.timeRange,
38070
+ startTime,
38071
+ endTime,
38072
+ output: Math.round(data2.originalOutput || 0),
38073
+ target: data2.target,
38074
+ status: data2.status
38075
+ };
38076
+ return /* @__PURE__ */ jsx(
38077
+ "div",
38078
+ {
38079
+ "data-testid": "hourly-output-tooltip",
38080
+ className: "p-3 -m-3 pointer-events-auto transition-opacity duration-200",
38081
+ style: { cursor: "default", opacity: data2 ? 1 : 0 },
38082
+ onMouseEnter: () => {
38083
+ clearTooltipHoverTimeout();
38084
+ setIsTooltipHovered(true);
38085
+ setForceHideTooltip(false);
38086
+ },
38087
+ onMouseLeave: () => {
38088
+ scheduleInteractiveTooltipHide();
38089
+ },
38090
+ children: /* @__PURE__ */ jsxs("div", { className: "bg-white/95 backdrop-blur-md border border-slate-200/60 shadow-xl shadow-slate-200/40 rounded-xl p-4 min-w-[240px] text-slate-700 pointer-events-auto", children: [
38091
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4 pb-3 border-b border-slate-100", children: [
38092
+ /* @__PURE__ */ jsx("p", { className: "font-semibold text-slate-900 text-sm tracking-tight", children: data2.timeRange }),
38093
+ onAiSummaryClick && /* @__PURE__ */ jsxs(
38094
+ "button",
38095
+ {
38096
+ onClick: (e) => {
38097
+ e.stopPropagation();
38098
+ onAiSummaryClick(clickPayload);
38099
+ },
38100
+ className: "flex items-center gap-1 px-2 py-1 -mr-1 rounded-md border border-slate-200 bg-white hover:bg-slate-50 text-[11px] font-medium text-slate-600 shadow-sm transition-colors",
38101
+ children: [
38102
+ /* @__PURE__ */ jsx(SparklesIcon, { className: "w-3.5 h-3.5" }),
38103
+ "Ask AI"
38104
+ ]
38105
+ }
38106
+ )
38107
+ ] }),
38108
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
38109
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
38110
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-slate-500 font-medium tracking-wide", children: "Output" }),
38111
+ /* @__PURE__ */ jsxs("span", { className: "font-bold text-slate-900 text-sm", children: [
38112
+ Math.round(data2.output),
38113
+ " ",
38114
+ /* @__PURE__ */ jsx("span", { className: "text-slate-400 font-normal text-xs ml-0.5", children: "units" })
38115
+ ] })
38116
+ ] }),
38117
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
38118
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-slate-500 font-medium tracking-wide", children: "Target" }),
38119
+ /* @__PURE__ */ jsxs("span", { className: "font-bold text-slate-700 text-sm", children: [
38120
+ Math.round(data2.target),
38121
+ " ",
38122
+ /* @__PURE__ */ jsx("span", { className: "text-slate-400 font-normal text-xs ml-0.5", children: "units" })
38123
+ ] })
38124
+ ] }),
38125
+ showIdleTime && data2.idleMinutes > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
38126
+ /* @__PURE__ */ jsx("div", { className: "pt-3 mt-3 border-t border-slate-100", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
38127
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-slate-500 font-medium tracking-wide", children: "Idle Time" }),
38128
+ /* @__PURE__ */ jsxs("span", { className: "font-bold text-orange-600 text-sm flex items-center gap-1.5", children: [
38129
+ /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-orange-500 shadow-[0_0_6px_rgba(249,115,22,0.6)] animate-pulse" }),
38130
+ data2.idleMinutes,
38131
+ " ",
38132
+ /* @__PURE__ */ jsx("span", { className: "text-orange-500/70 font-normal text-xs ml-0.5", children: "min" })
38133
+ ] })
38134
+ ] }) }),
38135
+ idlePeriods.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-3 bg-slate-50/80 rounded-lg p-3 border border-slate-100/50", children: [
38136
+ /* @__PURE__ */ jsx("p", { className: "font-semibold text-slate-400 text-[10px] mb-2.5 uppercase tracking-wider", children: "Idle Periods" }),
38137
+ /* @__PURE__ */ jsx("div", { className: "space-y-2.5 max-h-32 overflow-y-auto pr-1 custom-scrollbar", children: idlePeriods.map((period, index) => {
38138
+ return /* @__PURE__ */ jsxs(
38139
+ "div",
38140
+ {
38141
+ className: "flex items-start gap-2.5 text-xs",
38142
+ children: [
38143
+ /* @__PURE__ */ jsx("div", { className: "mt-[5px] w-1.5 h-1.5 bg-orange-400 rounded-full flex-shrink-0 shadow-[0_0_4px_rgba(251,146,60,0.5)]" }),
38144
+ /* @__PURE__ */ jsx("span", { className: "text-slate-700 font-medium tracking-tight", children: period.duration === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
38145
+ period.startTime,
38146
+ " ",
38147
+ /* @__PURE__ */ jsxs("span", { className: "text-slate-400 font-normal ml-1", children: [
38148
+ "(",
38149
+ period.duration,
38150
+ "m)"
38151
+ ] })
38152
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
38153
+ period.startTime,
38154
+ " ",
38155
+ /* @__PURE__ */ jsx("span", { className: "text-slate-400 mx-0.5", children: "\u2192" }),
38156
+ " ",
38157
+ period.endTime,
38158
+ " ",
38159
+ /* @__PURE__ */ jsxs("span", { className: "text-slate-400 font-normal ml-1", children: [
38160
+ "(",
38161
+ period.duration,
38162
+ "m)"
38163
+ ] })
38164
+ ] }) })
38165
+ ]
38166
+ },
38167
+ index
38168
+ );
38169
+ }) })
38170
+ ] })
38171
+ ] }),
38172
+ onWatchClipsClick && /* @__PURE__ */ jsx("div", { className: "pt-3 mt-3 border-t border-slate-100 flex items-center", children: /* @__PURE__ */ jsxs(
38173
+ "button",
38174
+ {
38175
+ onClick: (e) => {
38176
+ e.stopPropagation();
38177
+ onWatchClipsClick(clickPayload);
38178
+ },
38179
+ className: "w-full rounded-md border border-slate-200 bg-white hover:bg-slate-50 px-2 py-1.5 text-xs font-semibold text-slate-700 transition-colors flex items-center justify-center gap-1.5 shadow-sm",
38180
+ children: [
38181
+ /* @__PURE__ */ jsx(PlayCircleIcon, { className: "w-4 h-4 text-blue-500" }),
38182
+ "Watch Clips"
38183
+ ]
38184
+ }
38185
+ ) }),
38186
+ onHourClick && !onWatchClipsClick && !onAiSummaryClick && /* @__PURE__ */ jsx("div", { className: "pt-3 mt-3 border-t border-slate-100", children: /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-blue-100 bg-blue-50/70 px-3 py-2 text-xs font-semibold text-blue-700 text-center", children: "Click to inspect hour" }) })
38187
+ ] })
38188
+ ] })
38189
+ }
38190
+ );
38220
38191
  },
38221
- `cell-${index}`
38222
- )),
38223
- /* @__PURE__ */ jsx(
38224
- LabelList,
38225
- {
38226
- dataKey: "originalOutput",
38227
- position: "top",
38228
- content: (props) => {
38229
- const { x, y, width, value, payload } = props;
38230
- const actualValue = payload?.originalOutput || value;
38231
- if (!actualValue || actualValue === 0) return null;
38232
- return /* @__PURE__ */ jsx(
38233
- "text",
38234
- {
38235
- x: x + width / 2,
38236
- y: y - 8,
38237
- textAnchor: "middle",
38238
- fontSize: "12",
38239
- fontWeight: "600",
38240
- fill: "#374151",
38241
- style: {
38242
- opacity: 1,
38243
- pointerEvents: "none",
38244
- transition: "none"
38245
- },
38246
- children: Math.round(actualValue)
38192
+ animationDuration: 200
38193
+ }
38194
+ ),
38195
+ /* @__PURE__ */ jsx(Customized, { component: renderTargetLine }),
38196
+ /* @__PURE__ */ jsx(Customized, { component: renderSkuTimelineRail }),
38197
+ /* @__PURE__ */ jsxs(
38198
+ Bar,
38199
+ {
38200
+ xAxisId: "default",
38201
+ dataKey: "output",
38202
+ yAxisId: "default",
38203
+ maxBarSize: 35,
38204
+ radius: [10, 10, 0, 0],
38205
+ isAnimationActive: false,
38206
+ children: [
38207
+ chartData.map((entry, index) => /* @__PURE__ */ jsx(
38208
+ Cell,
38209
+ {
38210
+ fill: entry.color,
38211
+ stroke: entry.isSelected ? "#0f172a" : "transparent",
38212
+ strokeWidth: entry.isSelected ? 2 : 0,
38213
+ style: {
38214
+ filter: entry.isHighlighted || entry.isSelected ? "drop-shadow(0 4px 6px rgba(0, 0, 0, 0.12)) brightness(1.05)" : "brightness(1)",
38215
+ transform: entry.isHighlighted || entry.isSelected ? "translateY(-4px)" : "translateY(0)",
38216
+ opacity: entry.isDimmed ? 0.4 : 1,
38217
+ transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
38218
+ cursor: onHourClick || onWatchClipsClick || onAiSummaryClick ? "pointer" : "default"
38219
+ },
38220
+ onMouseEnter: (e) => {
38221
+ const target = e.target;
38222
+ target.style.filter = "drop-shadow(0 4px 6px rgba(0, 0, 0, 0.12)) brightness(1.05)";
38223
+ target.style.transform = "translateY(-4px)";
38224
+ target.style.opacity = "1";
38225
+ },
38226
+ onMouseLeave: (e) => {
38227
+ const target = e.target;
38228
+ target.style.filter = entry.isHighlighted || entry.isSelected ? "drop-shadow(0 4px 6px rgba(0, 0, 0, 0.12)) brightness(1.05)" : "brightness(1)";
38229
+ target.style.transform = entry.isHighlighted || entry.isSelected ? "translateY(-4px)" : "translateY(0)";
38230
+ target.style.opacity = entry.isDimmed ? "0.4" : "1";
38231
+ },
38232
+ onClick: () => {
38233
+ if (!onHourClick && !onWatchClipsClick && !onAiSummaryClick) return;
38234
+ const { startTime, endTime } = buildHourClipFilterWindow({
38235
+ shiftStart,
38236
+ shiftEnd,
38237
+ hourIndex: entry.hourIndex,
38238
+ slotCount: SHIFT_DURATION
38239
+ });
38240
+ const payload = {
38241
+ hourIndex: entry.hourIndex,
38242
+ timeRange: entry.timeRange,
38243
+ startTime,
38244
+ endTime,
38245
+ output: Math.round(entry.originalOutput || 0),
38246
+ target: entry.target,
38247
+ status: entry.status
38248
+ };
38249
+ if (onHourClick) onHourClick(payload);
38247
38250
  }
38248
- );
38249
- }
38250
- }
38251
- )
38252
- ]
38253
- }
38254
- ),
38255
- IdleBar,
38256
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
38257
- "pattern",
38258
- {
38259
- id: "idlePattern",
38260
- patternUnits: "userSpaceOnUse",
38261
- width: "4",
38262
- height: "4",
38263
- children: [
38264
- /* @__PURE__ */ jsx("rect", { width: "4", height: "4", fill: "#4b5563", opacity: "0.6" }),
38265
- /* @__PURE__ */ jsx(
38266
- "path",
38267
- {
38268
- d: "M 0,4 l 4,-4 M -1,1 l 2,-2 M 3,5 l 2,-2",
38269
- stroke: "#374151",
38270
- strokeWidth: "0.8",
38271
- opacity: "0.8"
38272
- }
38273
- )
38274
- ]
38275
- }
38276
- ) })
38277
- ]
38278
- }
38279
- ) }),
38280
- hoveredSkuRailLabel && /* @__PURE__ */ jsx(
38281
- "div",
38282
- {
38283
- className: "absolute z-50 pointer-events-none transform -translate-x-1/2 -translate-y-full transition-opacity duration-200",
38284
- style: {
38285
- left: hoveredSkuRailLabel.centerX,
38286
- top: hoveredSkuRailLabel.railY - 12
38287
- },
38288
- children: /* @__PURE__ */ jsxs("div", { className: "bg-white/95 backdrop-blur-md border border-slate-200/80 shadow-xl shadow-slate-200/50 rounded-lg px-3 py-2 flex flex-col min-w-[100px] max-w-[280px]", children: [
38289
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold tracking-wider text-blue-500 uppercase leading-none mb-1", children: "SKU" }),
38290
- /* @__PURE__ */ jsx("span", { className: "text-[13px] font-semibold text-slate-800 whitespace-normal break-words leading-snug", children: hoveredSkuRailLabel.label })
38291
- ] })
38292
- }
38293
- )
38294
- ] }) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center bg-gray-50 rounded-lg", children: /* @__PURE__ */ jsx("div", { className: "text-gray-500 text-sm", children: "Loading chart..." }) }),
38251
+ },
38252
+ `cell-${index}`
38253
+ )),
38254
+ /* @__PURE__ */ jsx(
38255
+ LabelList,
38256
+ {
38257
+ dataKey: "originalOutput",
38258
+ position: "top",
38259
+ content: (props) => {
38260
+ const { x, y, width, value, payload } = props;
38261
+ const actualValue = payload?.originalOutput || value;
38262
+ if (!actualValue || actualValue === 0) return null;
38263
+ return /* @__PURE__ */ jsx(
38264
+ "text",
38265
+ {
38266
+ x: x + width / 2,
38267
+ y: y - 8,
38268
+ textAnchor: "middle",
38269
+ fontSize: "12",
38270
+ fontWeight: "600",
38271
+ fill: "#374151",
38272
+ style: {
38273
+ opacity: 1,
38274
+ pointerEvents: "none",
38275
+ transition: "none"
38276
+ },
38277
+ children: Math.round(actualValue)
38278
+ }
38279
+ );
38280
+ }
38281
+ }
38282
+ )
38283
+ ]
38284
+ }
38285
+ ),
38286
+ IdleBar,
38287
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
38288
+ "pattern",
38289
+ {
38290
+ id: "idlePattern",
38291
+ patternUnits: "userSpaceOnUse",
38292
+ width: "4",
38293
+ height: "4",
38294
+ children: [
38295
+ /* @__PURE__ */ jsx("rect", { width: "4", height: "4", fill: "#4b5563", opacity: "0.6" }),
38296
+ /* @__PURE__ */ jsx(
38297
+ "path",
38298
+ {
38299
+ d: "M 0,4 l 4,-4 M -1,1 l 2,-2 M 3,5 l 2,-2",
38300
+ stroke: "#374151",
38301
+ strokeWidth: "0.8",
38302
+ opacity: "0.8"
38303
+ }
38304
+ )
38305
+ ]
38306
+ }
38307
+ ) })
38308
+ ]
38309
+ }
38310
+ ) }),
38311
+ hoveredSkuRailLabel && /* @__PURE__ */ jsx(
38312
+ "div",
38313
+ {
38314
+ className: "absolute z-50 pointer-events-none transform -translate-x-1/2 -translate-y-full transition-opacity duration-200",
38315
+ style: {
38316
+ left: hoveredSkuRailLabel.centerX,
38317
+ top: hoveredSkuRailLabel.railY - 12
38318
+ },
38319
+ children: /* @__PURE__ */ jsxs("div", { className: "bg-white/95 backdrop-blur-md border border-slate-200/80 shadow-xl shadow-slate-200/50 rounded-lg px-3 py-2 flex flex-col min-w-[100px] max-w-[280px]", children: [
38320
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold tracking-wider text-blue-500 uppercase leading-none mb-1", children: "SKU" }),
38321
+ /* @__PURE__ */ jsx("span", { className: "text-[13px] font-semibold text-slate-800 whitespace-normal break-words leading-snug", children: hoveredSkuRailLabel.label })
38322
+ ] })
38323
+ }
38324
+ )
38325
+ ]
38326
+ }
38327
+ ) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center bg-gray-50 rounded-lg", children: /* @__PURE__ */ jsx("div", { className: "text-gray-500 text-sm", children: "Loading chart..." }) }),
38295
38328
  /* @__PURE__ */ jsx("div", { className: "flex-none pt-2", children: renderLegend() })
38296
38329
  ]
38297
38330
  }
38298
38331
  );
38299
38332
  };
38300
- var HourlyOutputChart = React148__default.memo(
38333
+ var HourlyOutputChart = React125__default.memo(
38301
38334
  HourlyOutputChartComponent,
38302
38335
  (prevProps, nextProps) => {
38303
38336
  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.activeSkuId !== nextProps.activeSkuId || prevProps.selectedHourIndex !== nextProps.selectedHourIndex || prevProps.onHourClick !== nextProps.onHourClick || prevProps.className !== nextProps.className) {
@@ -38859,7 +38892,7 @@ function getTrendArrowAndColor(trend) {
38859
38892
  return { arrow: "\u2192", color: "text-gray-400" };
38860
38893
  }
38861
38894
  }
38862
- var VideoCard = React148__default.memo(({
38895
+ var VideoCard = React125__default.memo(({
38863
38896
  workspace,
38864
38897
  hlsUrl,
38865
38898
  shouldPlay,
@@ -38913,8 +38946,8 @@ var VideoCard = React148__default.memo(({
38913
38946
  const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "blue" ? "bg-[#0EA5E9]/30" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
38914
38947
  const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "blue" ? "bg-[#0EA5E9]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
38915
38948
  const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "blue" ? "Best" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
38916
- const worstMarkerClassName = compact ? "left-1.5 top-1.5 gap-1.5 px-2 py-1 text-[11px]" : "left-2 top-2 gap-2 px-3 py-1.5 text-xs";
38917
- const statusBadgesPositionClass = isWorstPerformance ? compact ? "top-8 left-1.5 gap-1" : "top-10 left-2 gap-1.5" : compact ? "top-1.5 left-1.5 gap-1" : "top-2 left-2 gap-1.5";
38949
+ const worstMarkerClassName = compact ? "left-1 top-1 sm:left-1.5 sm:top-1.5 gap-1 sm:gap-1.5 p-1 sm:px-2 sm:py-1 text-[10px] sm:text-[11px]" : "left-1.5 top-1.5 sm:left-2 sm:top-2 gap-1 sm:gap-2 px-1.5 sm:px-3 py-0.5 sm:py-1.5 text-[10px] sm:text-xs";
38950
+ const statusBadgesPositionClass = isWorstPerformance ? compact ? "top-6 sm:top-8 left-1 sm:left-1.5 gap-1" : "top-7 sm:top-10 left-1.5 sm:left-2 gap-1 sm:gap-1.5" : compact ? "top-1 sm:top-1.5 left-1 sm:left-1.5 gap-1" : "top-1.5 sm:top-2 left-1.5 sm:left-2 gap-1 sm:gap-1.5";
38918
38951
  const trendInfo = workspace.trend !== void 0 ? getTrendArrowAndColor(workspace.trend) : null;
38919
38952
  const handleClick = useCallback(() => {
38920
38953
  trackCoreEvent("Workspace Card Clicked", {
@@ -38950,8 +38983,8 @@ var VideoCard = React148__default.memo(({
38950
38983
  children: [
38951
38984
  /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full overflow-hidden bg-black", children: [
38952
38985
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black z-0", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse flex flex-col items-center", children: [
38953
- /* @__PURE__ */ jsx(Camera, { className: `w-5 h-5 sm:${compact ? "w-4 h-4" : "w-6 h-6"} text-gray-500` }),
38954
- /* @__PURE__ */ jsx("span", { className: `text-[11px] sm:${compact ? "text-[10px]" : "text-xs"} text-gray-500 mt-1`, children: "Loading..." })
38986
+ /* @__PURE__ */ jsx(Camera, { className: `w-5 h-5 ${compact ? "sm:w-4 sm:h-4" : "sm:w-6 sm:h-6"} text-gray-500` }),
38987
+ /* @__PURE__ */ jsx("span", { className: `text-[11px] ${compact ? "sm:text-[10px]" : "sm:text-xs"} text-gray-500 mt-1`, children: "Loading..." })
38955
38988
  ] }) }),
38956
38989
  /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 z-10", children: [
38957
38990
  /* @__PURE__ */ jsx(
@@ -39013,7 +39046,7 @@ var VideoCard = React148__default.memo(({
39013
39046
  "data-testid": `video-card-status-badge-${badge.kind}`,
39014
39047
  "aria-label": tooltipText,
39015
39048
  "aria-describedby": tooltipId,
39016
- className: `group relative inline-flex shrink-0 items-center justify-center rounded-full bg-slate-950/70 border-2 shadow-[0_3px_10px_rgba(0,0,0,0.34),inset_0_0_0_1px_rgba(255,255,255,0.18)] ${compact ? "h-10 w-10" : "h-11 w-11"}`,
39049
+ className: `group relative inline-flex shrink-0 items-center justify-center rounded-full bg-slate-950/70 border-2 shadow-[0_3px_10px_rgba(0,0,0,0.34),inset_0_0_0_1px_rgba(255,255,255,0.18)] ${compact ? "h-7 w-7 sm:h-10 sm:w-10" : "h-8 w-8 sm:h-11 sm:w-11"}`,
39017
39050
  style: {
39018
39051
  borderColor: presentation.hex
39019
39052
  },
@@ -39022,7 +39055,7 @@ var VideoCard = React148__default.memo(({
39022
39055
  Icon2,
39023
39056
  {
39024
39057
  "aria-hidden": "true",
39025
- className: `${compact ? "h-5 w-5" : "h-6 w-6"} text-white`,
39058
+ className: `${compact ? "h-4 w-4 sm:h-5 sm:w-5" : "h-4 w-4 sm:h-6 sm:w-6"} text-white`,
39026
39059
  strokeWidth: 2.4
39027
39060
  }
39028
39061
  ),
@@ -39050,10 +39083,10 @@ var VideoCard = React148__default.memo(({
39050
39083
  "div",
39051
39084
  {
39052
39085
  "data-testid": "video-card-worst-performance-marker",
39053
- className: `pointer-events-none absolute z-[65] inline-flex items-center rounded-md bg-[#1A0B09]/95 border border-[#E34329]/60 font-semibold tracking-wide text-white shadow-xl ${worstMarkerClassName}`,
39086
+ className: `pointer-events-none absolute z-[65] inline-flex items-center rounded-sm sm:rounded-md bg-[#1A0B09]/95 border border-[#E34329]/60 font-semibold tracking-wide text-white shadow-xl max-w-[calc(100%-8px)] sm:max-w-[calc(100%-16px)] ${worstMarkerClassName}`,
39054
39087
  children: [
39055
- /* @__PURE__ */ jsx(AlertTriangle, { className: `${compact ? "h-3.5 w-3.5" : "h-4 w-4"} text-[#E34329]`, "aria-hidden": "true" }),
39056
- /* @__PURE__ */ jsx("span", { children: "Overall Underperformer" })
39088
+ /* @__PURE__ */ jsx(AlertTriangle, { className: `${compact ? "h-3 w-3 sm:h-3.5 sm:w-3.5" : "h-3.5 w-3.5 sm:h-4 sm:w-4"} shrink-0 text-[#E34329]`, "aria-hidden": "true" }),
39089
+ /* @__PURE__ */ jsx("span", { className: `truncate leading-tight min-w-0 ${compact ? "hidden sm:block" : ""}`, children: "Overall Underperformer" })
39057
39090
  ]
39058
39091
  }
39059
39092
  ),
@@ -39066,10 +39099,10 @@ var VideoCard = React148__default.memo(({
39066
39099
  }
39067
39100
  ) })
39068
39101
  ] }),
39069
- /* @__PURE__ */ jsxs("div", { className: `absolute bottom-0 left-0 right-0 bg-black bg-opacity-60 p-1.5 sm:${compact ? "p-1" : "p-1.5"} flex min-w-0 justify-between items-center gap-1 z-10`, children: [
39102
+ /* @__PURE__ */ jsxs("div", { className: `absolute bottom-0 left-0 right-0 bg-black bg-opacity-60 p-1.5 ${compact ? "sm:p-1" : "sm:p-1.5"} flex min-w-0 justify-between items-center gap-1 z-10`, children: [
39070
39103
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
39071
39104
  /* @__PURE__ */ jsx(Camera, { size: compact ? 10 : 12, className: "shrink-0 text-white" }),
39072
- /* @__PURE__ */ jsx("p", { className: `min-w-0 truncate text-white text-[11px] sm:${compact ? "text-[10px]" : "text-xs"} font-medium tracking-wide`, children: workspaceDisplayName })
39105
+ /* @__PURE__ */ jsx("p", { className: `min-w-0 truncate text-white text-[11px] ${compact ? "sm:text-[10px]" : "sm:text-xs"} font-medium tracking-wide`, children: workspaceDisplayName })
39073
39106
  ] }),
39074
39107
  /* @__PURE__ */ jsxs("div", { className: `flex shrink-0 items-center ${compact ? "gap-1" : "gap-1.5"}`, children: [
39075
39108
  trendInfo && /* @__PURE__ */ jsx(
@@ -39086,7 +39119,7 @@ var VideoCard = React148__default.memo(({
39086
39119
  className: `${compact ? "w-1 h-1" : "w-1.5 h-1.5"} rounded-full ${showOffline ? "bg-red-500" : "bg-green-500"}`
39087
39120
  }
39088
39121
  ),
39089
- /* @__PURE__ */ jsx("span", { className: `text-white text-[11px] sm:${compact ? "text-[10px]" : "text-xs"}`, children: showOffline ? "Offline" : "Live" })
39122
+ /* @__PURE__ */ jsx("span", { className: `text-white text-[11px] ${compact ? "sm:text-[10px]" : "sm:text-xs"}`, children: showOffline ? "Offline" : "Live" })
39090
39123
  ] })
39091
39124
  ] })
39092
39125
  ]
@@ -39147,7 +39180,7 @@ var hasRecentHealthSignal = (lastHeartbeat) => {
39147
39180
  if (!Number.isFinite(heartbeatMs)) return false;
39148
39181
  return Date.now() - heartbeatMs <= RECENT_HEALTH_SIGNAL_MS;
39149
39182
  };
39150
- var VideoGridView = React148__default.memo(({
39183
+ var VideoGridView = React125__default.memo(({
39151
39184
  workspaces,
39152
39185
  blueComparisonWorkspaces,
39153
39186
  worstPerformanceWorkspaceIds = [],
@@ -39655,7 +39688,7 @@ var VideoGridView = React148__default.memo(({
39655
39688
  ) });
39656
39689
  });
39657
39690
  VideoGridView.displayName = "VideoGridView";
39658
- var MapGridView = React148__default.memo(({
39691
+ var MapGridView = React125__default.memo(({
39659
39692
  workspaces,
39660
39693
  className = "",
39661
39694
  displayNames = {},
@@ -39876,13 +39909,13 @@ var WorkspaceMetricCardsImpl = ({
39876
39909
  liveSkuId
39877
39910
  }) => {
39878
39911
  const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
39879
- const activeSku = React148__default.useMemo(() => {
39912
+ const activeSku = React125__default.useMemo(() => {
39880
39913
  if (skuAware && activeSkuId && skuBreakdown) {
39881
39914
  return skuBreakdown.find((s) => s.sku_id === activeSkuId);
39882
39915
  }
39883
39916
  return null;
39884
39917
  }, [skuAware, activeSkuId, skuBreakdown]);
39885
- const displaySku = React148__default.useMemo(() => {
39918
+ const displaySku = React125__default.useMemo(() => {
39886
39919
  if (activeSku) return activeSku;
39887
39920
  if (skuAware && !activeSkuId && liveSkuId && skuBreakdown) {
39888
39921
  return skuBreakdown.find((s) => s.sku_id === liveSkuId) ?? null;
@@ -40536,7 +40569,7 @@ var UptimeLineChartComponent = ({ points, className = "" }) => {
40536
40569
  )
40537
40570
  ] }) }) });
40538
40571
  };
40539
- var UptimeLineChart = React148__default.memo(UptimeLineChartComponent);
40572
+ var UptimeLineChart = React125__default.memo(UptimeLineChartComponent);
40540
40573
  var getTimeFromTimeString = (timeStr) => {
40541
40574
  if (!timeStr) {
40542
40575
  return { hour: 0, minute: 0, decimalHour: 0 };
@@ -40560,10 +40593,10 @@ var HourlyUptimeChartComponent = ({
40560
40593
  shiftBreaks,
40561
40594
  className = ""
40562
40595
  }) => {
40563
- const containerRef = React148__default.useRef(null);
40564
- const [containerReady, setContainerReady] = React148__default.useState(false);
40565
- const [containerWidth, setContainerWidth] = React148__default.useState(0);
40566
- const uptimeSeries = React148__default.useMemo(() => buildUptimeSeries({
40596
+ const containerRef = React125__default.useRef(null);
40597
+ const [containerReady, setContainerReady] = React125__default.useState(false);
40598
+ const [containerWidth, setContainerWidth] = React125__default.useState(0);
40599
+ const uptimeSeries = React125__default.useMemo(() => buildUptimeSeries({
40567
40600
  idleTimeHourly,
40568
40601
  shiftStart,
40569
40602
  shiftEnd,
@@ -40573,11 +40606,11 @@ var HourlyUptimeChartComponent = ({
40573
40606
  shiftBreaks
40574
40607
  }), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes, shiftBreaks]);
40575
40608
  const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
40576
- const shiftStartTime = React148__default.useMemo(
40609
+ const shiftStartTime = React125__default.useMemo(
40577
40610
  () => getTimeFromTimeString(shiftStart),
40578
40611
  [shiftStart]
40579
40612
  );
40580
- const { shiftDuration, shiftEndTime } = React148__default.useMemo(() => {
40613
+ const { shiftDuration, shiftEndTime } = React125__default.useMemo(() => {
40581
40614
  if (!shiftEnd) {
40582
40615
  const fallbackHours = uptimeSeries.shiftMinutes > 0 ? Math.ceil(uptimeSeries.shiftMinutes / 60) : 0;
40583
40616
  return { shiftDuration: fallbackHours, shiftEndTime: null };
@@ -40591,7 +40624,7 @@ var HourlyUptimeChartComponent = ({
40591
40624
  const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
40592
40625
  return { shiftDuration: hourCount, shiftEndTime: endTime };
40593
40626
  }, [shiftEnd, shiftStartTime.decimalHour, uptimeSeries.shiftMinutes]);
40594
- const formatHour = React148__default.useCallback((hourIndex) => {
40627
+ const formatHour = React125__default.useCallback((hourIndex) => {
40595
40628
  const isLastHour = hourIndex === shiftDuration - 1;
40596
40629
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
40597
40630
  const startHour = Math.floor(startDecimalHour) % 24;
@@ -40616,7 +40649,7 @@ var HourlyUptimeChartComponent = ({
40616
40649
  };
40617
40650
  return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
40618
40651
  }, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
40619
- const formatTimeRange2 = React148__default.useCallback((hourIndex) => {
40652
+ const formatTimeRange2 = React125__default.useCallback((hourIndex) => {
40620
40653
  const isLastHour = hourIndex === shiftDuration - 1;
40621
40654
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
40622
40655
  const startHour = Math.floor(startDecimalHour) % 24;
@@ -40638,7 +40671,7 @@ var HourlyUptimeChartComponent = ({
40638
40671
  };
40639
40672
  return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
40640
40673
  }, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
40641
- const chartData = React148__default.useMemo(() => {
40674
+ const chartData = React125__default.useMemo(() => {
40642
40675
  if (shiftDuration <= 0) return [];
40643
40676
  if (hasAggregateData) {
40644
40677
  return hourlyAggregates.map((entry, hourIndex) => ({
@@ -40680,7 +40713,7 @@ var HourlyUptimeChartComponent = ({
40680
40713
  }, [hasAggregateData, hourlyAggregates, uptimeSeries.points, uptimeSeries.elapsedMinutes, uptimeSeries.shiftMinutes, shiftDuration, formatHour, formatTimeRange2]);
40681
40714
  const maxYValue = 100;
40682
40715
  const yAxisTicks = [0, 25, 50, 75, 100];
40683
- React148__default.useEffect(() => {
40716
+ React125__default.useEffect(() => {
40684
40717
  const checkContainerDimensions = () => {
40685
40718
  if (containerRef.current) {
40686
40719
  const rect = containerRef.current.getBoundingClientRect();
@@ -40706,7 +40739,7 @@ var HourlyUptimeChartComponent = ({
40706
40739
  clearTimeout(fallbackTimeout);
40707
40740
  };
40708
40741
  }, []);
40709
- const xAxisConfig = React148__default.useMemo(() => {
40742
+ const xAxisConfig = React125__default.useMemo(() => {
40710
40743
  if (containerWidth >= 960) {
40711
40744
  return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12, labelMode: "full" };
40712
40745
  }
@@ -40715,7 +40748,7 @@ var HourlyUptimeChartComponent = ({
40715
40748
  }
40716
40749
  return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6, labelMode: "start" };
40717
40750
  }, [containerWidth]);
40718
- const formatXAxisTick = React148__default.useCallback((raw) => {
40751
+ const formatXAxisTick = React125__default.useCallback((raw) => {
40719
40752
  const label = typeof raw === "string" ? raw : String(raw);
40720
40753
  if (xAxisConfig.labelMode === "full") return label;
40721
40754
  const parts = label.split("-");
@@ -40921,7 +40954,7 @@ var HourlyUptimeChartComponent = ({
40921
40954
  }
40922
40955
  );
40923
40956
  };
40924
- var HourlyUptimeChart = React148__default.memo(HourlyUptimeChartComponent);
40957
+ var HourlyUptimeChart = React125__default.memo(HourlyUptimeChartComponent);
40925
40958
  var DEFAULT_COLORS2 = ["#00AB45", "#ef4444"];
40926
40959
  var UptimeDonutChartComponent = ({
40927
40960
  data,
@@ -40991,7 +41024,7 @@ var UptimeDonutChartComponent = ({
40991
41024
  ] }) })
40992
41025
  ] }) });
40993
41026
  };
40994
- var UptimeDonutChart = React148__default.memo(UptimeDonutChartComponent);
41027
+ var UptimeDonutChart = React125__default.memo(UptimeDonutChartComponent);
40995
41028
  UptimeDonutChart.displayName = "UptimeDonutChart";
40996
41029
  var TrendIcon = ({ trend }) => {
40997
41030
  if (trend === "up") {
@@ -41112,7 +41145,7 @@ var EmptyStateMessage = ({
41112
41145
  iconClassName
41113
41146
  }) => {
41114
41147
  let IconContent = null;
41115
- if (React148__default.isValidElement(iconType)) {
41148
+ if (React125__default.isValidElement(iconType)) {
41116
41149
  IconContent = iconType;
41117
41150
  } else if (typeof iconType === "string") {
41118
41151
  const MappedIcon = IconMap[iconType];
@@ -41883,7 +41916,31 @@ var formatOutputLabel = (bin) => {
41883
41916
  if (actualOutput === null) {
41884
41917
  return "";
41885
41918
  }
41886
- return `Output ${formatCompactNumber(actualOutput)}`;
41919
+ const expectedOutput = getExpectedOutputUnits(bin);
41920
+ return expectedOutput !== null ? `Output ${formatCompactNumber(actualOutput)}/${formatCompactNumber(expectedOutput)}` : `Output ${formatCompactNumber(actualOutput)}`;
41921
+ };
41922
+ var getTooltipOutputParts = (outputLabel, fallbackLabel) => {
41923
+ if (outputLabel.startsWith("Output ")) {
41924
+ const [actual, expected] = outputLabel.slice("Output ".length).split("/");
41925
+ return {
41926
+ label: "Output",
41927
+ actual: actual?.trim() || "",
41928
+ expected: expected?.trim()
41929
+ };
41930
+ }
41931
+ return {
41932
+ label: "Efficiency",
41933
+ actual: fallbackLabel,
41934
+ fallbackValue: fallbackLabel
41935
+ };
41936
+ };
41937
+ var getExpectedOutputUnits = (bin) => {
41938
+ const targetPpm = bin.target_ppm;
41939
+ const durationSeconds = bin.duration_seconds;
41940
+ if (typeof targetPpm !== "number" || !Number.isFinite(targetPpm) || typeof durationSeconds !== "number" || !Number.isFinite(durationSeconds) || durationSeconds <= 0) {
41941
+ return null;
41942
+ }
41943
+ return targetPpm * durationSeconds / 60;
41887
41944
  };
41888
41945
  var VideoControls = ({
41889
41946
  isPlaying,
@@ -41912,11 +41969,12 @@ var VideoControls = ({
41912
41969
  const [dragTime, setDragTime] = useState(0);
41913
41970
  const [isHoveringProgressBar, setIsHoveringProgressBar] = useState(false);
41914
41971
  const [hoveredTimelineBin, setHoveredTimelineBin] = useState(null);
41972
+ const [tooltipAnchorPercent, setTooltipAnchorPercent] = useState(50);
41973
+ const [tooltipPointerPercent, setTooltipPointerPercent] = useState(50);
41915
41974
  const [showSpeedMenu, setShowSpeedMenu] = useState(false);
41916
41975
  const speedMenuRef = useRef(null);
41917
41976
  const progressTrackRef = useRef(null);
41918
41977
  const activePointerIdRef = useRef(null);
41919
- const markerPointerJumpHandledRef = useRef(false);
41920
41978
  const progressColor = "#4b5563";
41921
41979
  const controlsVisible = showControls || controlsPinned;
41922
41980
  const isDraggingRef = useRef(false);
@@ -41940,43 +41998,6 @@ var VideoControls = ({
41940
41998
  isDraggingRef.current = false;
41941
41999
  onSeekEnd?.();
41942
42000
  };
41943
- const handleTimelineJump = useCallback((time2) => {
41944
- const nextTime = Math.min(Math.max(time2, 0), duration || time2);
41945
- const wasDragging = isDraggingRef.current;
41946
- activePointerIdRef.current = null;
41947
- setIsDragging(false);
41948
- isDraggingRef.current = false;
41949
- setDragTime(nextTime);
41950
- if (!wasDragging) {
41951
- onSeekStart?.();
41952
- }
41953
- onSeek(nextTime);
41954
- onSeekEnd?.();
41955
- }, [duration, onSeek, onSeekEnd, onSeekStart]);
41956
- const handleTimelineMarkerPointerDown = useCallback((e, time2) => {
41957
- e.preventDefault();
41958
- e.stopPropagation();
41959
- markerPointerJumpHandledRef.current = true;
41960
- handleTimelineJump(time2);
41961
- }, [handleTimelineJump]);
41962
- const handleTimelineMarkerMouseDown = useCallback((e, time2) => {
41963
- e.preventDefault();
41964
- e.stopPropagation();
41965
- if (markerPointerJumpHandledRef.current) {
41966
- return;
41967
- }
41968
- markerPointerJumpHandledRef.current = true;
41969
- handleTimelineJump(time2);
41970
- }, [handleTimelineJump]);
41971
- const handleTimelineMarkerClick = useCallback((e, time2) => {
41972
- e.preventDefault();
41973
- e.stopPropagation();
41974
- if (markerPointerJumpHandledRef.current) {
41975
- markerPointerJumpHandledRef.current = false;
41976
- return;
41977
- }
41978
- handleTimelineJump(time2);
41979
- }, [handleTimelineJump]);
41980
42001
  const updateTimeFromClientX = useCallback((clientX) => {
41981
42002
  if (!progressTrackRef.current) return;
41982
42003
  const rect = progressTrackRef.current.getBoundingClientRect();
@@ -42054,6 +42075,13 @@ var VideoControls = ({
42054
42075
  const clockLabel = formatTimelineClockTime(bin.start_time, timelineTimezone);
42055
42076
  const minuteExplanation = timelineExplanation?.minute_explanations?.find((explanation) => explanation.offset_seconds === offset || Boolean(explanation.start_time) && explanation.start_time === bin.start_time);
42056
42077
  const explanationLabel = minuteExplanation && minuteExplanation.confidence !== "low" ? minuteExplanation.primary_driver === "idle" ? "High Idle Detected" : minuteExplanation.primary_driver === "micro_stoppage" ? `Gap: ${Math.round(minuteExplanation.micro_stoppage_lost_seconds)}s lost` : minuteExplanation.primary_driver === "slow_cycle" ? typeof minuteExplanation.actual_cycle_time_seconds === "number" && Number.isFinite(minuteExplanation.actual_cycle_time_seconds) && typeof minuteExplanation.median_cycle_time_seconds === "number" && Number.isFinite(minuteExplanation.median_cycle_time_seconds) ? `Avg Cycle Time: ${formatTooltipSeconds(minuteExplanation.actual_cycle_time_seconds)} vs Shift Avg: ${formatTooltipSeconds(minuteExplanation.median_cycle_time_seconds)}` : `Slow cycle: ${Math.round(minuteExplanation.slow_cycle_lost_seconds)}s lost` : minuteExplanation.primary_driver === "low_output" ? "Low Output" : void 0 : void 0;
42078
+ const binOutputUnits = getBinOutputUnits(bin);
42079
+ const binEfficiency = typeof bin.efficiency_percent === "number" && Number.isFinite(bin.efficiency_percent) ? bin.efficiency_percent : null;
42080
+ const expectedOutputUnits = getExpectedOutputUnits({ ...bin, duration_seconds: clampedDuration });
42081
+ const isBelowExpectedOutput = binOutputUnits !== null && expectedOutputUnits !== null && expectedOutputUnits > 0 && binOutputUnits / expectedOutputUnits < 0.8;
42082
+ const fallbackTooltipReasonLabel = bin.is_idle === true && (binOutputUnits === null || binOutputUnits < 1) ? "Idle" : binOutputUnits === 0 || isBelowExpectedOutput || binOutputUnits !== null && binEfficiency !== null && binEfficiency < 80 ? "Low output" : void 0;
42083
+ const explanationTooltipReasonLabel = minuteExplanation && minuteExplanation.confidence !== "low" ? minuteExplanation.primary_driver === "idle" ? "Idle" : minuteExplanation.primary_driver === "micro_stoppage" ? "Gaps" : minuteExplanation.primary_driver === "slow_cycle" ? "Slow cycles" : minuteExplanation.primary_driver === "low_output" ? "Low output" : void 0 : void 0;
42084
+ const tooltipReasonLabel = explanationTooltipReasonLabel || fallbackTooltipReasonLabel;
42057
42085
  return {
42058
42086
  ...bin,
42059
42087
  offset_seconds: offset,
@@ -42063,97 +42091,155 @@ var VideoControls = ({
42063
42091
  clockLabel,
42064
42092
  efficiencyLabel: formatEfficiencyPercent(bin.efficiency_percent),
42065
42093
  outputLabel: formatOutputLabel({ ...bin, duration_seconds: clampedDuration }),
42066
- explanationLabel
42094
+ explanationLabel,
42095
+ tooltipReasonLabel
42067
42096
  };
42068
42097
  }).filter((bin) => Boolean(bin));
42069
42098
  }, [duration, timelineAnnotations, timelineExplanation, timelineTimezone]);
42070
42099
  const hasTimelineAnnotations = timelineBins.length > 0;
42071
- const worstMinuteMarkers = useMemo(() => {
42072
- const efficiencySource = timelineBins.filter((bin) => typeof bin.efficiency_percent === "number" && Number.isFinite(bin.efficiency_percent)).slice().sort((a, b) => a.efficiency_percent - b.efficiency_percent || a.offset_seconds - b.offset_seconds).slice(0, 3).map((bin, index) => ({
42073
- start_time: bin.start_time,
42074
- offset_seconds: bin.offset_seconds,
42075
- duration_seconds: bin.duration_seconds,
42076
- avg_flow_percent: bin.avg_flow_percent,
42077
- rank: index + 1
42078
- }));
42079
- const source = efficiencySource.length ? efficiencySource : timelineAnnotations?.worst_minutes?.length ? timelineAnnotations.worst_minutes : timelineBins.filter((bin) => typeof bin.avg_flow_percent === "number" && Number.isFinite(bin.avg_flow_percent)).sort((a, b) => a.avg_flow_percent - b.avg_flow_percent).slice(0, 3);
42080
- return source.filter((marker) => typeof marker.offset_seconds === "number" && Number.isFinite(marker.offset_seconds)).slice(0, 3).map((marker, index) => {
42081
- const offset = Math.max(0, Math.min(duration, marker.offset_seconds));
42082
- const matchingBin = timelineBins.find((bin) => bin.offset_seconds === marker.offset_seconds || Boolean(marker.start_time) && bin.start_time === marker.start_time);
42083
- const markerDuration = "duration_seconds" in marker ? Number(marker.duration_seconds || 0) : 0;
42084
- const width = markerDuration > 0 ? markerDuration : Number(matchingBin?.duration_seconds || 0);
42085
- const centerOffset = Math.min(duration, offset + Math.max(0, width) / 2);
42100
+ const outputBars = useMemo(() => {
42101
+ if (!timelineBins.length || duration <= 0) {
42102
+ return [];
42103
+ }
42104
+ const binsWithOutput = timelineBins.map((bin) => {
42105
+ const outputUnits = getBinOutputUnits(bin);
42106
+ if (outputUnits === null) {
42107
+ return null;
42108
+ }
42086
42109
  return {
42087
- ...marker,
42088
- rank: "rank" in marker ? marker.rank : index + 1,
42089
- leftPercent: getPercentage(centerOffset, duration)
42110
+ bin,
42111
+ outputUnits,
42112
+ expectedOutputUnits: getExpectedOutputUnits(bin)
42113
+ };
42114
+ }).filter((item) => Boolean(item));
42115
+ if (!binsWithOutput.length) {
42116
+ return [];
42117
+ }
42118
+ const maxActualOutput = binsWithOutput.reduce((max, item) => Math.max(max, item.outputUnits), 0);
42119
+ return binsWithOutput.map(({ bin, outputUnits, expectedOutputUnits }) => {
42120
+ const hasExpected = expectedOutputUnits !== null && expectedOutputUnits > 0;
42121
+ const scale2 = hasExpected ? outputUnits / expectedOutputUnits : maxActualOutput > 0 ? outputUnits / maxActualOutput : 0;
42122
+ const isZeroOutput = outputUnits === 0;
42123
+ const isIdle = bin.is_idle === true && outputUnits < 1;
42124
+ const hasProductionDespiteIdle = bin.is_idle === true && outputUnits >= 1;
42125
+ const isLowOutput = hasProductionDespiteIdle || (typeof bin.efficiency_percent !== "number" || !Number.isFinite(bin.efficiency_percent)) && hasExpected && outputUnits < expectedOutputUnits || !isZeroOutput && typeof bin.efficiency_percent === "number" && Number.isFinite(bin.efficiency_percent) && bin.efficiency_percent < 80;
42126
+ return {
42127
+ id: `${bin.offset_seconds}-${bin.duration_seconds}`,
42128
+ leftPercent: bin.leftPercent,
42129
+ widthPercent: bin.widthPercent,
42130
+ heightPercent: isZeroOutput ? 18 : Math.max(8, Math.min(scale2, 1) * 100),
42131
+ tone: isIdle ? "idle" : isZeroOutput ? "zero" : isLowOutput ? "low" : "normal",
42132
+ outputUnits
42090
42133
  };
42091
42134
  });
42092
- }, [duration, timelineAnnotations, timelineBins]);
42093
- const transitionMarkers = useMemo(() => {
42094
- if (timelineBins.length < 2 || duration <= 0) {
42135
+ }, [duration, timelineBins]);
42136
+ const lowOutputRanges = useMemo(() => {
42137
+ if (!timelineBins.length || duration <= 0) {
42095
42138
  return [];
42096
42139
  }
42140
+ const ranges = [];
42097
42141
  const orderedBins = timelineBins.slice().sort((left, right) => left.offset_seconds - right.offset_seconds);
42098
- return orderedBins.slice(1).map((bin, index) => {
42099
- const previousBin = orderedBins[index];
42100
- const fromOutputUnits = getBinOutputUnits(previousBin);
42101
- const toOutputUnits = getBinOutputUnits(bin);
42102
- const hasOutputValues = fromOutputUnits !== null && toOutputUnits !== null && fromOutputUnits > 0;
42103
- const fromEfficiency = previousBin.efficiency_percent;
42104
- const toEfficiency = bin.efficiency_percent;
42105
- const hasEfficiencyValues = typeof fromEfficiency === "number" && typeof toEfficiency === "number" && Number.isFinite(fromEfficiency) && Number.isFinite(toEfficiency) && fromEfficiency > 0;
42106
- if (!hasOutputValues && !hasEfficiencyValues) {
42107
- return null;
42142
+ orderedBins.forEach((bin) => {
42143
+ const actualOutputUnits = getBinOutputUnits(bin);
42144
+ const isIdle = bin.is_idle === true && (actualOutputUnits === null || actualOutputUnits < 1);
42145
+ const hasProductionDespiteIdle = bin.is_idle === true && actualOutputUnits !== null && actualOutputUnits >= 1;
42146
+ const isZeroOutput = actualOutputUnits === 0;
42147
+ const expectedOutputUnits = getExpectedOutputUnits(bin);
42148
+ const isBelowExpectedOutput = (typeof bin.efficiency_percent !== "number" || !Number.isFinite(bin.efficiency_percent)) && expectedOutputUnits !== null && expectedOutputUnits > 0 && actualOutputUnits !== null && actualOutputUnits < expectedOutputUnits;
42149
+ const isLowEfficiency = hasProductionDespiteIdle || isBelowExpectedOutput || !isZeroOutput && typeof bin.efficiency_percent === "number" && Number.isFinite(bin.efficiency_percent) && bin.efficiency_percent < 80;
42150
+ if (!isIdle && !isZeroOutput && !isLowEfficiency) {
42151
+ return;
42108
42152
  }
42109
- const fromValue = hasOutputValues ? fromOutputUnits : fromEfficiency;
42110
- const toValue2 = hasOutputValues ? toOutputUnits : toEfficiency;
42111
- const relativeDrop = (fromValue - toValue2) / fromValue;
42112
- if (relativeDrop <= 0.5) {
42113
- return null;
42153
+ const rangeKind = isIdle ? "idle" : isZeroOutput ? "zero" : "low";
42154
+ const binStart = Math.max(0, bin.offset_seconds);
42155
+ const binEnd = Math.min(duration, binStart + Math.max(0, bin.duration_seconds));
42156
+ if (binEnd <= binStart) {
42157
+ return;
42114
42158
  }
42115
- const transitionOffset = Math.min(Math.max(bin.offset_seconds, 0), duration);
42159
+ const outputShortfallUnits = expectedOutputUnits !== null && actualOutputUnits !== null ? Math.max(0, expectedOutputUnits - actualOutputUnits) : 0;
42160
+ const currentRange = ranges[ranges.length - 1];
42161
+ if (currentRange && currentRange.kind === rangeKind && binStart <= currentRange.endSeconds + 1) {
42162
+ currentRange.endSeconds = Math.max(currentRange.endSeconds, binEnd);
42163
+ currentRange.binCount += 1;
42164
+ currentRange.idleBinCount += isIdle ? 1 : 0;
42165
+ currentRange.zeroBinCount += isZeroOutput ? 1 : 0;
42166
+ currentRange.durationSeconds += binEnd - binStart;
42167
+ currentRange.outputShortfallUnits += outputShortfallUnits;
42168
+ return;
42169
+ }
42170
+ ranges.push({
42171
+ startSeconds: binStart,
42172
+ endSeconds: binEnd,
42173
+ kind: rangeKind,
42174
+ binCount: 1,
42175
+ idleBinCount: isIdle ? 1 : 0,
42176
+ zeroBinCount: isZeroOutput ? 1 : 0,
42177
+ durationSeconds: binEnd - binStart,
42178
+ outputShortfallUnits
42179
+ });
42180
+ });
42181
+ const labelRangeIndexes = ranges.map((range, index) => ({ range, index })).sort((left, right) => {
42182
+ const issuePriority = (range) => range.idleBinCount === range.binCount ? 2 : range.zeroBinCount === range.binCount ? 1 : 0;
42183
+ const priorityDiff = issuePriority(right.range) - issuePriority(left.range);
42184
+ if (priorityDiff !== 0) {
42185
+ return priorityDiff;
42186
+ }
42187
+ const durationDiff = right.range.durationSeconds - left.range.durationSeconds;
42188
+ if (durationDiff !== 0) {
42189
+ return durationDiff;
42190
+ }
42191
+ const shortfallDiff = right.range.outputShortfallUnits - left.range.outputShortfallUnits;
42192
+ if (shortfallDiff !== 0) {
42193
+ return shortfallDiff;
42194
+ }
42195
+ return left.range.startSeconds - right.range.startSeconds;
42196
+ }).slice(0, 3).reduce((set, item) => {
42197
+ set.add(item.index);
42198
+ return set;
42199
+ }, /* @__PURE__ */ new Set());
42200
+ return ranges.map((range, index) => {
42201
+ const isZeroOutputRange = range.zeroBinCount === range.binCount;
42202
+ const isIdleRange = range.idleBinCount === range.binCount;
42203
+ const leftPercent = getPercentage(range.startSeconds, duration);
42204
+ const widthPercent = Math.max(getPercentage(range.endSeconds - range.startSeconds, duration), 0.5);
42116
42205
  return {
42117
- offsetSeconds: transitionOffset,
42118
- leftPercent: getPercentage(transitionOffset, duration),
42119
- fromValue,
42120
- toValue: toValue2,
42121
- relativeDrop,
42122
- fromOutputUnits,
42123
- toOutputUnits,
42124
- source: hasOutputValues ? "output" : "efficiency",
42125
- absoluteDrop: fromValue - toValue2
42206
+ id: `${range.startSeconds}-${range.endSeconds}`,
42207
+ startSeconds: range.startSeconds,
42208
+ endSeconds: range.endSeconds,
42209
+ leftPercent,
42210
+ widthPercent,
42211
+ label: isIdleRange ? "Idle" : isZeroOutputRange ? "0 units" : "Low output",
42212
+ kind: range.kind,
42213
+ isIdleRange,
42214
+ isZeroOutputRange,
42215
+ durationSeconds: range.durationSeconds,
42216
+ outputShortfallUnits: range.outputShortfallUnits,
42217
+ showLabel: labelRangeIndexes.has(index) && widthPercent >= 4 && range.durationSeconds >= 60
42126
42218
  };
42127
- }).filter((marker) => Boolean(marker)).sort((left, right) => {
42128
- const relativeDiff = right.relativeDrop - left.relativeDrop;
42129
- if (relativeDiff !== 0) {
42130
- return relativeDiff;
42131
- }
42132
- const outputDiff = right.absoluteDrop - left.absoluteDrop;
42133
- if (outputDiff !== 0) {
42134
- return outputDiff;
42135
- }
42136
- return left.offsetSeconds - right.offsetSeconds;
42137
- }).slice(0, 3).map((marker, index) => ({
42138
- ...marker,
42139
- rank: index + 1
42140
- }));
42219
+ });
42141
42220
  }, [duration, timelineBins]);
42142
- worstMinuteMarkers[0] || null;
42143
42221
  const updateHoveredTimelineBin = useCallback((clientX) => {
42144
42222
  if (!hasTimelineAnnotations || !progressTrackRef.current || duration <= 0) {
42145
42223
  setHoveredTimelineBin(null);
42224
+ setTooltipAnchorPercent(50);
42225
+ setTooltipPointerPercent(50);
42146
42226
  return;
42147
42227
  }
42148
42228
  const rect = progressTrackRef.current.getBoundingClientRect();
42149
42229
  if (!rect.width) {
42150
42230
  setHoveredTimelineBin(null);
42231
+ setTooltipAnchorPercent(50);
42232
+ setTooltipPointerPercent(50);
42151
42233
  return;
42152
42234
  }
42153
42235
  const pct = Math.min(Math.max((clientX - rect.left) / rect.width, 0), 1);
42154
42236
  const hoverTime = pct * duration;
42155
42237
  const nextBin = timelineBins.find((bin) => hoverTime >= bin.offset_seconds && hoverTime <= bin.offset_seconds + bin.duration_seconds) || null;
42156
42238
  setHoveredTimelineBin(nextBin);
42239
+ const rawAnchorPercent = nextBin ? nextBin.leftPercent + nextBin.widthPercent / 2 : pct * 100;
42240
+ const clampedAnchorPercent = Math.min(90, Math.max(10, rawAnchorPercent));
42241
+ setTooltipAnchorPercent(clampedAnchorPercent);
42242
+ setTooltipPointerPercent(Math.min(92, Math.max(8, 50 + (rawAnchorPercent - clampedAnchorPercent) * 7.5)));
42157
42243
  }, [duration, hasTimelineAnnotations, timelineBins]);
42158
42244
  const handleProgressMouseMove = useCallback((e) => {
42159
42245
  updateHoveredTimelineBin(e.clientX);
@@ -42169,7 +42255,7 @@ var VideoControls = ({
42169
42255
  "div",
42170
42256
  {
42171
42257
  ref: progressTrackRef,
42172
- className: "relative z-10 h-1 mb-4 group cursor-pointer",
42258
+ className: "relative z-10 h-7 mb-4 group cursor-pointer",
42173
42259
  onMouseEnter: () => setIsHoveringProgressBar(true),
42174
42260
  onMouseMove: handleProgressMouseMove,
42175
42261
  onMouseLeave: () => {
@@ -42178,8 +42264,60 @@ var VideoControls = ({
42178
42264
  },
42179
42265
  onPointerDown: handlePointerDown,
42180
42266
  children: [
42181
- /* @__PURE__ */ jsx("div", { className: "absolute -top-4 bottom-0 left-0 right-0 z-20" }),
42182
- /* @__PURE__ */ jsx("div", { className: "absolute top-0 left-0 right-0 bottom-0 bg-white/20 rounded-full overflow-hidden z-0", children: /* @__PURE__ */ jsx(
42267
+ /* @__PURE__ */ jsx("div", { className: "absolute -top-5 -bottom-1 left-0 right-0 z-20" }),
42268
+ outputBars.length > 0 && /* @__PURE__ */ jsx(
42269
+ "div",
42270
+ {
42271
+ "data-testid": "output-bar-layer",
42272
+ "aria-hidden": "true",
42273
+ className: "pointer-events-none absolute left-0 right-0 top-0 z-[2] h-3.5",
42274
+ children: outputBars.map((bar) => /* @__PURE__ */ jsx(
42275
+ "div",
42276
+ {
42277
+ "data-testid": "output-minute-bar",
42278
+ "data-tone": bar.tone,
42279
+ className: "absolute bottom-0 rounded-sm",
42280
+ style: {
42281
+ left: `${bar.leftPercent}%`,
42282
+ width: `${Math.max(bar.widthPercent, 0.45)}%`,
42283
+ height: `${bar.heightPercent}%`,
42284
+ backgroundColor: bar.tone === "zero" ? "rgba(239, 68, 68, 0.78)" : bar.tone === "idle" ? "rgba(168, 85, 247, 0.70)" : bar.tone === "low" ? "rgba(248, 113, 113, 0.56)" : "rgba(255, 255, 255, 0.46)"
42285
+ }
42286
+ },
42287
+ bar.id
42288
+ ))
42289
+ }
42290
+ ),
42291
+ lowOutputRanges.map((range) => /* @__PURE__ */ jsx(
42292
+ "div",
42293
+ {
42294
+ "data-testid": "low-output-range",
42295
+ "data-kind": range.kind,
42296
+ "aria-hidden": "true",
42297
+ className: "pointer-events-none absolute top-[19px] z-[1] h-3 -translate-y-1/2 rounded-full border",
42298
+ style: {
42299
+ left: `${range.leftPercent}%`,
42300
+ width: `${range.widthPercent}%`,
42301
+ backgroundColor: range.isIdleRange ? "rgba(168, 85, 247, 0.24)" : range.isZeroOutputRange ? "rgba(239, 68, 68, 0.38)" : "rgba(248, 113, 113, 0.24)",
42302
+ borderColor: range.isIdleRange ? "rgba(216, 180, 254, 0.32)" : range.isZeroOutputRange ? "rgba(252, 165, 165, 0.35)" : "rgba(254, 202, 202, 0.28)"
42303
+ }
42304
+ },
42305
+ range.id
42306
+ )),
42307
+ !hoveredTimelineBin && lowOutputRanges.filter((range) => range.showLabel).map((range) => /* @__PURE__ */ jsx(
42308
+ "div",
42309
+ {
42310
+ "data-testid": "low-output-range-label",
42311
+ "data-kind": range.kind,
42312
+ className: `pointer-events-none absolute bottom-full z-[35] mb-1 -translate-x-1/2 rounded-md border px-1.5 py-0.5 text-[10px] font-semibold leading-none shadow-sm ${range.isIdleRange ? "border-violet-200/35 bg-violet-950/75 text-violet-50" : "border-red-200/30 bg-red-950/75 text-red-50"}`,
42313
+ style: {
42314
+ left: `${Math.min(98, Math.max(2, range.leftPercent + range.widthPercent / 2))}%`
42315
+ },
42316
+ children: range.label
42317
+ },
42318
+ `${range.id}-label`
42319
+ )),
42320
+ /* @__PURE__ */ jsx("div", { className: "absolute left-0 right-0 top-[19px] h-1 -translate-y-1/2 bg-white/20 rounded-full overflow-hidden z-10", children: /* @__PURE__ */ jsx(
42183
42321
  "div",
42184
42322
  {
42185
42323
  className: "absolute top-0 left-0 bottom-0 bg-white/40 transition-all duration-200",
@@ -42189,7 +42327,7 @@ var VideoControls = ({
42189
42327
  /* @__PURE__ */ jsx(
42190
42328
  "div",
42191
42329
  {
42192
- className: "absolute top-0 left-0 bottom-0 bg-[#007bff] transition-all duration-75 z-10",
42330
+ className: "absolute left-0 top-[19px] h-1 -translate-y-1/2 bg-[#007bff] transition-all duration-75 z-20",
42193
42331
  style: { width: `${progressPercent}%`, backgroundColor: progressColor },
42194
42332
  children: /* @__PURE__ */ jsx(
42195
42333
  "div",
@@ -42216,36 +42354,48 @@ var VideoControls = ({
42216
42354
  onTouchStart: handleSeekStart,
42217
42355
  onTouchEnd: handleSeekEnd,
42218
42356
  onPointerDown: handlePointerDown,
42219
- className: "absolute left-0 right-0 top-[-12px] bottom-0 w-full h-auto opacity-0 cursor-pointer z-30 margin-0 padding-0"
42357
+ className: "absolute left-0 right-0 top-[-12px] bottom-[-4px] w-full h-auto opacity-0 cursor-pointer z-40 margin-0 padding-0"
42220
42358
  }
42221
42359
  ),
42222
- hasTimelineAnnotations && transitionMarkers.map((marker) => /* @__PURE__ */ jsx(
42223
- "button",
42224
- {
42225
- type: "button",
42226
- "aria-label": marker.source === "output" ? `Output drop marker ${marker.rank}: output ${formatCompactNumber(marker.fromValue)} to ${formatCompactNumber(marker.toValue)} (${Math.round(marker.relativeDrop * 100)}% drop)` : `Output drop marker ${marker.rank}: efficiency ${Math.round(marker.fromValue)}% to ${Math.round(marker.toValue)}% (${Math.round(marker.relativeDrop * 100)}% drop)`,
42227
- title: marker.source === "output" ? `Output drop: ${formatCompactNumber(marker.fromValue)} to ${formatCompactNumber(marker.toValue)}` : `Output drop: ${Math.round(marker.fromValue)}% to ${Math.round(marker.toValue)}%`,
42228
- onPointerDownCapture: (e) => handleTimelineMarkerPointerDown(e, marker.offsetSeconds),
42229
- onMouseDownCapture: (e) => handleTimelineMarkerMouseDown(e, marker.offsetSeconds),
42230
- onClickCapture: (e) => handleTimelineMarkerClick(e, marker.offsetSeconds),
42231
- className: "absolute top-1/2 -translate-y-1/2 z-[70] flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-white bg-sky-500 p-0 text-center text-[9px] font-bold leading-none text-white shadow hover:bg-sky-400 focus:outline-none focus:ring-2 focus:ring-sky-200",
42232
- style: { left: `calc(${marker.leftPercent}% - 10px)`, zIndex: 70, pointerEvents: "auto" },
42233
- children: marker.rank
42234
- },
42235
- `${marker.rank}-${marker.offsetSeconds}`
42236
- )),
42237
- hasTimelineAnnotations && hoveredTimelineBin && /* @__PURE__ */ jsxs(
42360
+ hasTimelineAnnotations && hoveredTimelineBin && /* @__PURE__ */ jsx(
42238
42361
  "div",
42239
42362
  {
42240
- className: "absolute bottom-full z-50 mb-2 -translate-x-1/2 rounded bg-slate-900 px-2 py-1 text-[11px] font-semibold text-white shadow-lg",
42241
- style: { left: `${hoveredTimelineBin.leftPercent + hoveredTimelineBin.widthPercent / 2}%` },
42242
- children: [
42243
- hoveredTimelineBin.clockLabel || formatTime2(hoveredTimelineBin.offset_seconds),
42244
- " | ",
42245
- hoveredTimelineBin.efficiencyLabel,
42246
- hoveredTimelineBin.outputLabel ? ` | ${hoveredTimelineBin.outputLabel}` : "",
42247
- hoveredTimelineBin.explanationLabel ? ` | ${hoveredTimelineBin.explanationLabel}` : ""
42248
- ]
42363
+ "data-testid": "tooltip-card",
42364
+ className: "absolute bottom-full z-50 mb-5 min-w-[146px] -translate-x-1/2 whitespace-nowrap rounded-lg border border-slate-500/70 bg-[#0b101b]/95 px-3 py-2.5 text-left text-white shadow-[0_16px_36px_rgba(0,0,0,0.48)] backdrop-blur",
42365
+ style: { left: `${tooltipAnchorPercent}%` },
42366
+ children: (() => {
42367
+ const outputParts = getTooltipOutputParts(hoveredTimelineBin.outputLabel, hoveredTimelineBin.efficiencyLabel);
42368
+ const isIdleReason = hoveredTimelineBin.tooltipReasonLabel === "Idle";
42369
+ const isOutputTooltip = outputParts.label === "Output";
42370
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
42371
+ /* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium leading-none text-slate-300", children: hoveredTimelineBin.clockLabel || formatTime2(hoveredTimelineBin.offset_seconds) }),
42372
+ /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex items-baseline gap-1 text-[15px] font-bold leading-none tracking-[-0.01em]", children: [
42373
+ /* @__PURE__ */ jsx("span", { className: "text-white", children: outputParts.label }),
42374
+ isOutputTooltip ? /* @__PURE__ */ jsxs(Fragment, { children: [
42375
+ /* @__PURE__ */ jsx("span", { "data-testid": "tooltip-actual-output", className: "tabular-nums text-red-400", children: outputParts.actual }),
42376
+ outputParts.expected ? /* @__PURE__ */ jsxs(Fragment, { children: [
42377
+ /* @__PURE__ */ jsx("span", { className: "text-slate-100", children: "/" }),
42378
+ /* @__PURE__ */ jsx("span", { className: "tabular-nums text-slate-100", children: outputParts.expected })
42379
+ ] }) : null
42380
+ ] }) : /* @__PURE__ */ jsx("span", { className: "tabular-nums text-slate-100", children: outputParts.fallbackValue || outputParts.actual })
42381
+ ] }),
42382
+ hoveredTimelineBin.tooltipReasonLabel ? /* @__PURE__ */ jsx("div", { className: "mt-2 flex items-center", children: /* @__PURE__ */ jsx(
42383
+ "span",
42384
+ {
42385
+ className: `rounded-md border px-2 py-1 text-[10px] font-semibold leading-none shadow-sm ${isIdleReason ? "border-violet-300/30 bg-violet-500/20 text-violet-100" : "border-red-300/35 bg-red-500/25 text-red-50"}`,
42386
+ children: hoveredTimelineBin.tooltipReasonLabel
42387
+ }
42388
+ ) }) : null,
42389
+ /* @__PURE__ */ jsx(
42390
+ "div",
42391
+ {
42392
+ "data-testid": "tooltip-pointer",
42393
+ className: "absolute top-full h-3 w-3 -translate-x-1/2 -translate-y-1/2 rotate-45 border-b border-r border-slate-500/70 bg-[#0b101b]/95",
42394
+ style: { left: `${tooltipPointerPercent}%` }
42395
+ }
42396
+ )
42397
+ ] });
42398
+ })()
42249
42399
  }
42250
42400
  )
42251
42401
  ]
@@ -43812,6 +43962,19 @@ var buildLostChip = (explanation) => {
43812
43962
  }
43813
43963
  return null;
43814
43964
  };
43965
+ var getDriverBadgeClassName = (driverKeys) => {
43966
+ if (driverKeys.length === 1) {
43967
+ switch (driverKeys[0]) {
43968
+ case "idle":
43969
+ return "border border-violet-300/30 bg-violet-500/20 text-violet-100 ring-violet-500/20";
43970
+ case "slow_cycle":
43971
+ return "border border-amber-300/30 bg-amber-500/20 text-amber-100 ring-amber-500/20";
43972
+ case "micro_stoppage":
43973
+ return "border border-red-300/25 bg-red-500/15 text-red-100 ring-red-500/20";
43974
+ }
43975
+ }
43976
+ return "border border-red-300/25 bg-red-500/15 text-red-100 ring-red-500/20";
43977
+ };
43815
43978
  var RedFlowDiagnosticOverlay = ({
43816
43979
  timeline,
43817
43980
  explanation,
@@ -43836,6 +43999,7 @@ var RedFlowDiagnosticOverlay = ({
43836
43999
  const shouldShowLostChip = driverKeys.some((driver) => driver !== "low_output");
43837
44000
  const chips = explanation && shouldShowLostChip ? [buildLostChip(explanation)].filter((chip) => Boolean(chip)) : [];
43838
44001
  const shouldShowHeadline = Boolean(summary && driverKeys.length > 0 && summary.primary_driver !== "unknown");
44002
+ const driverBadgeClassName = getDriverBadgeClassName(driverKeys);
43839
44003
  const aiSummaryBullets = Array.isArray(aiSummary?.bullets) ? aiSummary.bullets.map((bullet) => String(bullet || "").trim()).filter(Boolean).slice(0, 3) : [];
43840
44004
  const shouldShowAiSummary = !aiSummaryError && aiSummaryBullets.length === 3;
43841
44005
  return /* @__PURE__ */ jsxs(
@@ -43854,9 +44018,9 @@ var RedFlowDiagnosticOverlay = ({
43854
44018
  ] }),
43855
44019
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
43856
44020
  /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-white/50", children: "Reason:" }),
43857
- /* @__PURE__ */ jsx("span", { className: "rounded bg-red-500/10 px-2 py-1 text-[10px] font-semibold tracking-wide text-red-400 ring-1 ring-inset ring-red-500/20", children: "Low output" })
44021
+ /* @__PURE__ */ jsx("span", { className: `rounded px-2 py-1 text-[10px] font-semibold tracking-wide ring-1 ring-inset ${driverBadgeClassName}`, children: driverLabel })
43858
44022
  ] })
43859
- ] }) : /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center gap-2", children: /* @__PURE__ */ jsx("span", { className: "rounded bg-red-500/10 px-2 py-1 text-[10px] font-semibold tracking-wide text-red-400 ring-1 ring-inset ring-red-500/20", children: driverLabel }) }),
44023
+ ] }) : /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center gap-2", children: /* @__PURE__ */ jsx("span", { className: `rounded px-2 py-1 text-[10px] font-semibold tracking-wide ring-1 ring-inset ${driverBadgeClassName}`, children: driverLabel }) }),
43860
44024
  (shouldShowAiSummary || aiSummaryLoading || chips.length > 0 || shouldShowHeadline) && /* @__PURE__ */ jsx("div", { className: "mb-4 h-px w-full bg-white/10" }),
43861
44025
  !shouldShowAiSummary && !aiSummaryLoading && shouldShowHeadline && summary?.headline ? /* @__PURE__ */ jsx("div", { className: "mb-3 text-[13px] font-medium leading-relaxed text-white/90", children: summary.headline }) : null,
43862
44026
  !shouldShowAiSummary && !aiSummaryLoading && chips.length > 0 ? /* @__PURE__ */ jsx("div", { className: "mb-3 flex flex-wrap gap-2", children: chips.slice(0, 3).map((chip) => /* @__PURE__ */ jsx(
@@ -43930,7 +44094,7 @@ function Skeleton({ className, ...props }) {
43930
44094
  var Select = SelectPrimitive.Root;
43931
44095
  var SelectGroup = SelectPrimitive.Group;
43932
44096
  var SelectValue = SelectPrimitive.Value;
43933
- var SelectTrigger = React148.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
44097
+ var SelectTrigger = React125.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
43934
44098
  SelectPrimitive.Trigger,
43935
44099
  {
43936
44100
  ref,
@@ -43946,7 +44110,7 @@ var SelectTrigger = React148.forwardRef(({ className, children, ...props }, ref)
43946
44110
  }
43947
44111
  ));
43948
44112
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
43949
- var SelectScrollUpButton = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
44113
+ var SelectScrollUpButton = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43950
44114
  SelectPrimitive.ScrollUpButton,
43951
44115
  {
43952
44116
  ref,
@@ -43956,7 +44120,7 @@ var SelectScrollUpButton = React148.forwardRef(({ className, ...props }, ref) =>
43956
44120
  }
43957
44121
  ));
43958
44122
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
43959
- var SelectScrollDownButton = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
44123
+ var SelectScrollDownButton = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43960
44124
  SelectPrimitive.ScrollDownButton,
43961
44125
  {
43962
44126
  ref,
@@ -43966,7 +44130,7 @@ var SelectScrollDownButton = React148.forwardRef(({ className, ...props }, ref)
43966
44130
  }
43967
44131
  ));
43968
44132
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
43969
- var SelectContent = React148.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
44133
+ var SelectContent = React125.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
43970
44134
  SelectPrimitive.Content,
43971
44135
  {
43972
44136
  ref,
@@ -43994,7 +44158,7 @@ var SelectContent = React148.forwardRef(({ className, children, position = "popp
43994
44158
  }
43995
44159
  ) }));
43996
44160
  SelectContent.displayName = SelectPrimitive.Content.displayName;
43997
- var SelectLabel = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
44161
+ var SelectLabel = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43998
44162
  SelectPrimitive.Label,
43999
44163
  {
44000
44164
  ref,
@@ -44003,7 +44167,7 @@ var SelectLabel = React148.forwardRef(({ className, ...props }, ref) => /* @__PU
44003
44167
  }
44004
44168
  ));
44005
44169
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
44006
- var SelectItem = React148.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
44170
+ var SelectItem = React125.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
44007
44171
  SelectPrimitive.Item,
44008
44172
  {
44009
44173
  ref,
@@ -44019,7 +44183,7 @@ var SelectItem = React148.forwardRef(({ className, children, ...props }, ref) =>
44019
44183
  }
44020
44184
  ));
44021
44185
  SelectItem.displayName = SelectPrimitive.Item.displayName;
44022
- var SelectSeparator = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
44186
+ var SelectSeparator = React125.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
44023
44187
  SelectPrimitive.Separator,
44024
44188
  {
44025
44189
  ref,
@@ -44645,7 +44809,7 @@ var TimePickerDropdown = ({
44645
44809
  )
44646
44810
  ] });
44647
44811
  };
44648
- var SilentErrorBoundary = class extends React148__default.Component {
44812
+ var SilentErrorBoundary = class extends React125__default.Component {
44649
44813
  constructor(props) {
44650
44814
  super(props);
44651
44815
  this.handleClearAndReload = () => {
@@ -47365,6 +47529,7 @@ function useClipsRealtimeUpdates({
47365
47529
  };
47366
47530
  }
47367
47531
  var LOW_EFFICIENCY_CATEGORY_ID = "recent_flow_red_streak";
47532
+ var LOW_EFFICIENCY_AI_SUMMARY_ENABLED = process.env.NEXT_PUBLIC_LOW_EFFICIENCY_AI_SUMMARY_ENABLED === "true";
47368
47533
  var parseFiniteNumber2 = (value) => {
47369
47534
  if (typeof value === "number" && Number.isFinite(value)) {
47370
47535
  return value;
@@ -48903,12 +49068,15 @@ var BottlenecksContent = ({
48903
49068
  const isCurrentLowEfficiencyClip = Boolean(
48904
49069
  currentVideo?.type === "recent_flow_red_streak" || currentVideo?.red_flow_timeline
48905
49070
  );
48906
- const currentLowEfficiencyAiSummary = currentLowEfficiencyClipId ? lowEfficiencyAiSummaryByClipId[currentLowEfficiencyClipId] || currentVideo?.low_efficiency_ai_summary || null : null;
49071
+ const currentLowEfficiencyAiSummary = currentLowEfficiencyClipId ? LOW_EFFICIENCY_AI_SUMMARY_ENABLED ? lowEfficiencyAiSummaryByClipId[currentLowEfficiencyClipId] || currentVideo?.low_efficiency_ai_summary || null : null : null;
48907
49072
  const isCurrentLowEfficiencyAiSummaryLoading = Boolean(
48908
- currentLowEfficiencyClipId && lowEfficiencyAiSummaryLoadingByClipId[currentLowEfficiencyClipId]
49073
+ LOW_EFFICIENCY_AI_SUMMARY_ENABLED && currentLowEfficiencyClipId && lowEfficiencyAiSummaryLoadingByClipId[currentLowEfficiencyClipId]
48909
49074
  );
48910
- const currentLowEfficiencyAiSummaryError = currentLowEfficiencyClipId ? lowEfficiencyAiSummaryErrorByClipId[currentLowEfficiencyClipId] || null : null;
49075
+ const currentLowEfficiencyAiSummaryError = currentLowEfficiencyClipId ? LOW_EFFICIENCY_AI_SUMMARY_ENABLED ? lowEfficiencyAiSummaryErrorByClipId[currentLowEfficiencyClipId] || null : null : null;
48911
49076
  useEffect(() => {
49077
+ if (!LOW_EFFICIENCY_AI_SUMMARY_ENABLED) {
49078
+ return;
49079
+ }
48912
49080
  const clipId = currentLowEfficiencyClipId;
48913
49081
  if (!clipId || !isCurrentLowEfficiencyClip || !workspaceId) {
48914
49082
  return;
@@ -52038,8 +52206,8 @@ var IdleTimeReasonChartComponent = ({
52038
52206
  updateAnimation = "replay",
52039
52207
  variant = "pie"
52040
52208
  }) => {
52041
- const [activeData, setActiveData] = React148__default.useState([]);
52042
- React148__default.useEffect(() => {
52209
+ const [activeData, setActiveData] = React125__default.useState([]);
52210
+ React125__default.useEffect(() => {
52043
52211
  if (updateAnimation === "smooth") {
52044
52212
  setActiveData(data && data.length > 0 ? data : []);
52045
52213
  return;
@@ -52058,7 +52226,7 @@ var IdleTimeReasonChartComponent = ({
52058
52226
  setActiveData([]);
52059
52227
  }
52060
52228
  }, [data, updateAnimation]);
52061
- React148__default.useEffect(() => {
52229
+ React125__default.useEffect(() => {
52062
52230
  if (!data || data.length === 0) return;
52063
52231
  data.forEach((entry, index) => {
52064
52232
  if (entry.name.toLowerCase().includes("other")) {
@@ -52066,7 +52234,7 @@ var IdleTimeReasonChartComponent = ({
52066
52234
  }
52067
52235
  });
52068
52236
  }, [data]);
52069
- const pieKey = React148__default.useMemo(() => {
52237
+ const pieKey = React125__default.useMemo(() => {
52070
52238
  if (updateAnimation === "smooth") {
52071
52239
  return "smooth";
52072
52240
  }
@@ -52236,7 +52404,7 @@ var IdleTimeReasonChartComponent = ({
52236
52404
  )
52237
52405
  ] });
52238
52406
  };
52239
- var IdleTimeReasonChart = React148__default.memo(IdleTimeReasonChartComponent);
52407
+ var IdleTimeReasonChart = React125__default.memo(IdleTimeReasonChartComponent);
52240
52408
  IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
52241
52409
  var IdleTimeReasonChart_default = IdleTimeReasonChart;
52242
52410
 
@@ -56763,13 +56931,13 @@ var WorkspaceCycleTimeMetricCards = ({
56763
56931
  liveSkuId
56764
56932
  }) => {
56765
56933
  const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
56766
- const activeSku = React148__default.useMemo(() => {
56934
+ const activeSku = React125__default.useMemo(() => {
56767
56935
  if (skuAware && activeSkuId && skuBreakdown) {
56768
56936
  return skuBreakdown.find((s) => s.sku_id === activeSkuId);
56769
56937
  }
56770
56938
  return null;
56771
56939
  }, [skuAware, activeSkuId, skuBreakdown]);
56772
- const displaySku = React148__default.useMemo(() => {
56940
+ const displaySku = React125__default.useMemo(() => {
56773
56941
  if (activeSku) return activeSku;
56774
56942
  if (skuAware && !activeSkuId && liveSkuId && skuBreakdown) {
56775
56943
  return skuBreakdown.find((s) => s.sku_id === liveSkuId) ?? null;
@@ -57014,7 +57182,7 @@ var arePropsEqual = (prevProps, nextProps) => {
57014
57182
  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
57015
57183
  prevProps.position.id === nextProps.position.id;
57016
57184
  };
57017
- var WorkspaceGridItem = React148__default.memo(({
57185
+ var WorkspaceGridItem = React125__default.memo(({
57018
57186
  data,
57019
57187
  position,
57020
57188
  isBottleneck = false,
@@ -57109,7 +57277,7 @@ var WorkspaceGridItem = React148__default.memo(({
57109
57277
  );
57110
57278
  }, arePropsEqual);
57111
57279
  WorkspaceGridItem.displayName = "WorkspaceGridItem";
57112
- var WorkspaceGrid = React148__default.memo(({
57280
+ var WorkspaceGrid = React125__default.memo(({
57113
57281
  workspaces,
57114
57282
  blueComparisonWorkspaces,
57115
57283
  worstPerformanceWorkspaceIds = [],
@@ -57368,7 +57536,7 @@ var KPICard = ({
57368
57536
  }) => {
57369
57537
  useThemeConfig();
57370
57538
  const { formatNumber } = useFormatNumber();
57371
- const trendInfo = React148__default.useMemo(() => {
57539
+ const trendInfo = React125__default.useMemo(() => {
57372
57540
  let trendValue = trend || "neutral";
57373
57541
  if (change !== void 0 && trend === void 0) {
57374
57542
  trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
@@ -57395,7 +57563,7 @@ var KPICard = ({
57395
57563
  const shouldShowTrend = !(change === 0 && trend === void 0);
57396
57564
  return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
57397
57565
  }, [trend, change]);
57398
- const formattedValue = React148__default.useMemo(() => {
57566
+ const formattedValue = React125__default.useMemo(() => {
57399
57567
  if (title === "Quality Compliance" && typeof value === "number") {
57400
57568
  return value.toFixed(1);
57401
57569
  }
@@ -57409,7 +57577,7 @@ var KPICard = ({
57409
57577
  }
57410
57578
  return value;
57411
57579
  }, [value, title]);
57412
- const formattedChange = React148__default.useMemo(() => {
57580
+ const formattedChange = React125__default.useMemo(() => {
57413
57581
  if (change === void 0 || change === 0 && !showZeroChange) return null;
57414
57582
  const absChange = Math.abs(change);
57415
57583
  return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
@@ -57661,11 +57829,6 @@ var KPISection = memo$1(({
57661
57829
  }) => {
57662
57830
  const showSkeleton = isLoading || !kpis;
57663
57831
  const isUptimeMode = mode === "uptime";
57664
- const efficiencyOnTrack = !isUptimeMode && isEfficiencyOnTrack(kpis?.efficiency.value);
57665
- const outputStatus = !showSkeleton && !isUptimeMode ? {
57666
- tooltipText: efficiencyOnTrack ? "On Track" : "Behind",
57667
- positive: efficiencyOnTrack
57668
- } : void 0;
57669
57832
  if (useSrcLayout) {
57670
57833
  const effChange = showSkeleton ? 0 : kpis.efficiency.change ?? 0;
57671
57834
  const effTrend = effChange > 0 ? "up" : effChange < 0 ? "down" : "neutral";
@@ -57701,7 +57864,6 @@ var KPISection = memo$1(({
57701
57864
  {
57702
57865
  title: secondaryTitle,
57703
57866
  value: secondaryValue,
57704
- status: outputStatus,
57705
57867
  isLoading: showSkeleton
57706
57868
  }
57707
57869
  ) })
@@ -57732,7 +57894,7 @@ var KPISection = memo$1(({
57732
57894
  value: showSkeleton ? "" : `${kpis.outputProgress.current}/${kpis.outputProgress.target}`,
57733
57895
  change: showSkeleton ? 0 : kpis.outputProgress.change,
57734
57896
  suffix: void 0,
57735
- status: outputStatus
57897
+ status: void 0
57736
57898
  }
57737
57899
  ];
57738
57900
  return /* @__PURE__ */ jsx(
@@ -57765,7 +57927,6 @@ var KPISection = memo$1(({
57765
57927
  if (!prevKpis && !nextKpis) return true;
57766
57928
  if (!prevKpis || !nextKpis) return false;
57767
57929
  if (prevKpis === nextKpis) return true;
57768
- if (isEfficiencyOnTrack(prevKpis.efficiency.value) !== isEfficiencyOnTrack(nextKpis.efficiency.value)) return false;
57769
57930
  if (Math.abs(prevKpis.efficiency.value - nextKpis.efficiency.value) >= 0.5) return false;
57770
57931
  if (prevKpis.efficiency.change !== nextKpis.efficiency.change) return false;
57771
57932
  if (prevKpis.underperformingWorkers.current !== nextKpis.underperformingWorkers.current || prevKpis.underperformingWorkers.total !== nextKpis.underperformingWorkers.total) return false;
@@ -58916,7 +59077,7 @@ var Breadcrumbs = ({ items }) => {
58916
59077
  }
58917
59078
  }
58918
59079
  };
58919
- 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(React148__default.Fragment, { children: [
59080
+ 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(React125__default.Fragment, { children: [
58920
59081
  index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
58921
59082
  /* @__PURE__ */ jsxs(
58922
59083
  "span",
@@ -59746,6 +59907,16 @@ var SideNavBar = memo$1(({
59746
59907
  }, [refreshAlertsSummary, showAlertsButton]);
59747
59908
  const settingsItems = useMemo(() => {
59748
59909
  const items = [
59910
+ ...canAccessPath("/improvement-center") ? [{
59911
+ key: "improvement-center",
59912
+ label: "Improve",
59913
+ icon: LightBulbIcon,
59914
+ onClick: () => {
59915
+ handleImprovementClick();
59916
+ setIsSettingsOpen(false);
59917
+ },
59918
+ isActive: pathname === "/improvement-center" || pathname.startsWith("/improvement-center/")
59919
+ }] : [],
59749
59920
  ...canAccessPath("/targets") ? [{
59750
59921
  key: "targets",
59751
59922
  label: "Targets",
@@ -59834,7 +60005,7 @@ var SideNavBar = memo$1(({
59834
60005
  });
59835
60006
  }
59836
60007
  return items;
59837
- }, [handleTargetsClick, handleProductionPlanClick, handleShiftsClick, handleTeamManagementClick, handleProfileClick, handleTicketsClick, handleClipsCostClick, handleHelpClick, pathname, ticketsEnabled, showBillingLink, canAccessPath]);
60008
+ }, [handleImprovementClick, handleTargetsClick, handleProductionPlanClick, handleShiftsClick, handleTeamManagementClick, handleProfileClick, handleTicketsClick, handleClipsCostClick, handleHelpClick, pathname, ticketsEnabled, showBillingLink, canAccessPath]);
59838
60009
  const handleLogout = useCallback(async () => {
59839
60010
  setIsSettingsOpen(false);
59840
60011
  try {
@@ -59853,7 +60024,6 @@ var SideNavBar = memo$1(({
59853
60024
  const liveButtonClasses = useMemo(() => getButtonClasses("/live-monitor"), [getButtonClasses]);
59854
60025
  const leaderboardButtonClasses = useMemo(() => getButtonClasses("/leaderboard"), [getButtonClasses]);
59855
60026
  const kpisButtonClasses = useMemo(() => getButtonClasses("/kpis"), [getButtonClasses]);
59856
- const improvementButtonClasses = useMemo(() => getButtonClasses("/improvement-center"), [getButtonClasses]);
59857
60027
  useMemo(() => getButtonClasses("/supervisor-management"), [getButtonClasses]);
59858
60028
  const skusButtonClasses = useMemo(() => getButtonClasses("/skus"), [getButtonClasses]);
59859
60029
  const healthButtonClasses = useMemo(() => getButtonClasses("/health"), [getButtonClasses]);
@@ -59941,21 +60111,6 @@ var SideNavBar = memo$1(({
59941
60111
  ]
59942
60112
  }
59943
60113
  ),
59944
- canAccessPath("/improvement-center") && /* @__PURE__ */ jsxs(
59945
- "button",
59946
- {
59947
- onClick: handleImprovementClick,
59948
- className: improvementButtonClasses,
59949
- "aria-label": "Improvement Center",
59950
- tabIndex: 0,
59951
- role: "tab",
59952
- "aria-selected": isPathActive("/improvement-center"),
59953
- children: [
59954
- /* @__PURE__ */ jsx(LightBulbIcon, { className: "w-5 h-5 mb-1" }),
59955
- /* @__PURE__ */ jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight text-center", children: "Improve" })
59956
- ]
59957
- }
59958
- ),
59959
60114
  showSupervisorManagement,
59960
60115
  skuEnabled && canAccessPath("/skus") && /* @__PURE__ */ jsxs(
59961
60116
  "button",
@@ -60073,18 +60228,6 @@ var SideNavBar = memo$1(({
60073
60228
  ]
60074
60229
  }
60075
60230
  ),
60076
- canAccessPath("/improvement-center") && /* @__PURE__ */ jsxs(
60077
- "button",
60078
- {
60079
- onClick: handleMobileNavClick(handleImprovementClick),
60080
- className: getMobileButtonClass("/improvement-center"),
60081
- "aria-label": "Improvement Center",
60082
- children: [
60083
- /* @__PURE__ */ jsx(LightBulbIcon, { className: getIconClass("/improvement-center") }),
60084
- /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Improve" })
60085
- ]
60086
- }
60087
- ),
60088
60231
  showSupervisorManagement,
60089
60232
  skuEnabled && canAccessPath("/skus") && /* @__PURE__ */ jsxs(
60090
60233
  "button",
@@ -60114,6 +60257,18 @@ var SideNavBar = memo$1(({
60114
60257
  /* @__PURE__ */ jsxs("div", { className: "mt-8 pt-6 border-t border-gray-100", children: [
60115
60258
  /* @__PURE__ */ jsx("h3", { className: "px-5 mb-3 text-[10px] font-bold text-gray-400 uppercase tracking-widest", children: "Settings & Support" }),
60116
60259
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
60260
+ canAccessPath("/improvement-center") && /* @__PURE__ */ jsxs(
60261
+ "button",
60262
+ {
60263
+ onClick: handleMobileNavClick(handleImprovementClick),
60264
+ className: getMobileButtonClass("/improvement-center"),
60265
+ "aria-label": "Improvement Center",
60266
+ children: [
60267
+ /* @__PURE__ */ jsx(LightBulbIcon, { className: getIconClass("/improvement-center") }),
60268
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Improve" })
60269
+ ]
60270
+ }
60271
+ ),
60117
60272
  canAccessPath("/targets") && /* @__PURE__ */ jsxs(
60118
60273
  "button",
60119
60274
  {
@@ -60232,12 +60387,12 @@ var SideNavBar = memo$1(({
60232
60387
  /* @__PURE__ */ jsx(
60233
60388
  "div",
60234
60389
  {
60235
- className: `md:hidden fixed inset-0 bg-black/60 backdrop-blur-sm z-40 transition-opacity duration-300 ease-in-out ${isMobileMenuOpen ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"}`,
60390
+ className: `md:hidden fixed inset-0 bg-black/60 backdrop-blur-sm z-[190] transition-opacity duration-300 ease-in-out ${isMobileMenuOpen ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"}`,
60236
60391
  onClick: onMobileMenuClose,
60237
60392
  "aria-hidden": "true"
60238
60393
  }
60239
60394
  ),
60240
- /* @__PURE__ */ jsxs("aside", { className: `md:hidden fixed inset-y-0 left-0 w-72 xs:w-80 bg-white shadow-2xl flex flex-col z-50 transform transition-transform duration-300 ease-in-out ${isMobileMenuOpen ? "translate-x-0" : "-translate-x-full"}`, children: [
60395
+ /* @__PURE__ */ jsxs("aside", { className: `md:hidden fixed inset-y-0 left-0 w-72 xs:w-80 bg-white shadow-2xl flex flex-col z-[200] transform transition-transform duration-300 ease-in-out ${isMobileMenuOpen ? "translate-x-0" : "-translate-x-full"}`, children: [
60241
60396
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b border-gray-200 bg-gradient-to-r from-blue-50 to-white", children: [
60242
60397
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx(Logo, { className: "w-11 h-11 object-contain" }) }),
60243
60398
  /* @__PURE__ */ jsx(
@@ -60440,7 +60595,7 @@ var AwardBadge = ({
60440
60595
  }) => {
60441
60596
  const styles2 = getBadgeStyles(type);
60442
60597
  const Icon2 = CustomIcon || getDefaultIcon(type);
60443
- const randomDelay = React148__default.useMemo(() => Math.random() * 2, []);
60598
+ const randomDelay = React125__default.useMemo(() => Math.random() * 2, []);
60444
60599
  const floatingAnimation = {
60445
60600
  animate: {
60446
60601
  y: [0, -10, 0],
@@ -67356,7 +67511,7 @@ var HOME_DISPLAY_MODE_OPTIONS = [
67356
67511
  {
67357
67512
  id: "worst_workstations",
67358
67513
  label: "Overall Underperformers",
67359
- description: "Lowest performers based on full day efficiency"
67514
+ description: "Highlights the poorest performers of the day"
67360
67515
  }
67361
67516
  ];
67362
67517
  var getHomeDisplayModeLabel = (displayMode) => HOME_DISPLAY_MODE_OPTIONS.find((option) => option.id === displayMode)?.label || "Default";
@@ -68624,10 +68779,6 @@ function HomeView({
68624
68779
  selection_mode: isAllLinesSelection(normalizedLineIds) ? "all" : normalizedLineIds.length === 1 ? "single" : "custom",
68625
68780
  line_name: getLineSelectionLabel(normalizedLineIds)
68626
68781
  });
68627
- trackCoreEvent("Dashboard Filter Selected", {
68628
- filter_type: "Line Filter",
68629
- filter_value: getLineSelectionLabel(normalizedLineIds)
68630
- });
68631
68782
  }, [factoryViewId, getLineSelectionLabel, getTrackedLineScope, selectedLineIds, selectedLineIdsKey, visibleLineIds]);
68632
68783
  useCallback(() => {
68633
68784
  updateSelectedLineIds(visibleLineIds);
@@ -68676,7 +68827,20 @@ function HomeView({
68676
68827
  "button",
68677
68828
  {
68678
68829
  type: "button",
68679
- onClick: () => setIsLineSelectorOpen((previous) => !previous),
68830
+ onClick: () => {
68831
+ const willOpen = !isLineSelectorOpen;
68832
+ setIsLineSelectorOpen(willOpen);
68833
+ if (willOpen) {
68834
+ trackCoreEvent("Monitor Line Selector Menu Opened", {
68835
+ selection_source: "home_line_selector",
68836
+ current_display_mode: displayMode,
68837
+ current_display_mode_label: getHomeDisplayModeLabel(displayMode),
68838
+ selected_line_ids: selectedLineIds,
68839
+ selected_line_count: selectedLineIds.length,
68840
+ is_all_lines: isAllLinesSelection(selectedLineIds)
68841
+ });
68842
+ }
68843
+ },
68680
68844
  className: "flex min-w-[180px] items-center justify-between gap-2 rounded-md border border-slate-200 bg-white px-3 py-1.5 text-left text-sm font-medium shadow-sm transition-colors hover:bg-slate-50 text-slate-700",
68681
68845
  "aria-haspopup": "menu",
68682
68846
  "aria-expanded": isLineSelectorOpen,
@@ -68791,7 +68955,17 @@ function HomeView({
68791
68955
  type: "button",
68792
68956
  onClick: () => {
68793
68957
  setIsLineSelectorOpen(false);
68794
- setIsDisplayModeMenuOpen((previous) => !previous);
68958
+ const willOpen = !isDisplayModeMenuOpen;
68959
+ setIsDisplayModeMenuOpen(willOpen);
68960
+ if (willOpen) {
68961
+ trackCoreEvent("Monitor Display Filter Menu Opened", {
68962
+ selection_source: "home_display_filter",
68963
+ current_display_mode: displayMode,
68964
+ current_display_mode_label: getHomeDisplayModeLabel(displayMode),
68965
+ selected_line_ids: selectedLineIds,
68966
+ selected_line_count: selectedLineIds.length
68967
+ });
68968
+ }
68795
68969
  },
68796
68970
  className: `inline-flex h-9 w-9 items-center justify-center rounded-md border shadow-sm transition-colors ${displayMode === "all" ? "border-slate-200 bg-white text-slate-500 hover:bg-slate-50 hover:text-slate-700" : "border-blue-200 bg-blue-50 text-blue-600 hover:bg-blue-100"}`,
68797
68971
  "aria-haspopup": "menu",
@@ -68817,6 +68991,12 @@ function HomeView({
68817
68991
  "aria-checked": isSelected,
68818
68992
  onClick: () => {
68819
68993
  const nextSelectedLineIds = option.id === "slideshow" ? visibleLineIds : selectedLineIds;
68994
+ const selectedViewProperties = {
68995
+ view_type: option.id,
68996
+ view_label: option.label,
68997
+ is_slideshow: option.id === "slideshow",
68998
+ selection_source: "home_display_filter"
68999
+ };
68820
69000
  setDisplayMode(option.id);
68821
69001
  if (option.id === "slideshow") {
68822
69002
  updateSelectedLineIds(visibleLineIds);
@@ -68825,14 +69005,22 @@ function HomeView({
68825
69005
  trackCoreEvent("Monitor Display Filter Selected", {
68826
69006
  filter_name: option.label,
68827
69007
  filter_id: option.id,
69008
+ ...selectedViewProperties,
68828
69009
  previous_display_mode: displayMode,
69010
+ previous_display_mode_label: getHomeDisplayModeLabel(displayMode),
68829
69011
  selected_line_ids: nextSelectedLineIds,
68830
69012
  selected_line_count: nextSelectedLineIds.length,
68831
69013
  highlighted_workspace_count: option.id === "worst_workstations" ? worstPerformanceWorkspaceIds.length : 0
68832
69014
  });
68833
- trackCoreEvent("Dashboard Filter Selected", {
68834
- filter_type: "Display Mode",
68835
- filter_value: option.label
69015
+ trackCoreEvent(`Display View Selected: ${option.label}`, {
69016
+ mode_id: option.id,
69017
+ mode_label: option.label,
69018
+ previous_display_mode: displayMode,
69019
+ previous_display_mode_label: getHomeDisplayModeLabel(displayMode),
69020
+ ...selectedViewProperties,
69021
+ selected_line_ids: nextSelectedLineIds,
69022
+ selected_line_count: nextSelectedLineIds.length,
69023
+ highlighted_workspace_count: option.id === "worst_workstations" ? worstPerformanceWorkspaceIds.length : 0
68836
69024
  });
68837
69025
  },
68838
69026
  className: "flex w-full items-start px-4 py-2.5 text-left transition-colors hover:bg-slate-50",
@@ -69044,7 +69232,7 @@ function HomeView({
69044
69232
  animate: { opacity: 1, scale: 1 },
69045
69233
  transition: { duration: 0.3 },
69046
69234
  className: "h-full",
69047
- children: React148__default.createElement(WorkspaceGrid, {
69235
+ children: React125__default.createElement(WorkspaceGrid, {
69048
69236
  workspaces: workspaceMetricsWithBreakState,
69049
69237
  blueComparisonWorkspaces: currentBlueComparisonWorkspaceMetrics || workspaceMetricsWithBreakState,
69050
69238
  worstPerformanceWorkspaceIds: activeWorstPerformanceWorkspaceIds,
@@ -69080,7 +69268,7 @@ function HomeView({
69080
69268
  animate: { opacity: 1, scale: 1 },
69081
69269
  transition: { duration: 0.3 },
69082
69270
  className: "h-full",
69083
- children: React148__default.createElement(WorkspaceGrid, {
69271
+ children: React125__default.createElement(WorkspaceGrid, {
69084
69272
  workspaces: [],
69085
69273
  // Show empty grid while loading
69086
69274
  blueComparisonWorkspaces: [],
@@ -69130,7 +69318,7 @@ function HomeView({
69130
69318
  contentVariant: "plain"
69131
69319
  }
69132
69320
  ),
69133
- /* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(React148__default.Fragment, { children: [
69321
+ /* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(React125__default.Fragment, { children: [
69134
69322
  /* @__PURE__ */ jsx(
69135
69323
  motion.div,
69136
69324
  {
@@ -69209,7 +69397,7 @@ function HomeView({
69209
69397
  "all-green-center-toast"
69210
69398
  )
69211
69399
  ] }, "all-green-celebration") : null }),
69212
- /* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(React148__default.Fragment, { children: [
69400
+ /* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(React125__default.Fragment, { children: [
69213
69401
  /* @__PURE__ */ jsx(
69214
69402
  motion.div,
69215
69403
  {
@@ -69303,7 +69491,7 @@ function HomeView({
69303
69491
  }
69304
69492
  );
69305
69493
  }
69306
- var AuthenticatedHomeView = withAuth(React148__default.memo(HomeView));
69494
+ var AuthenticatedHomeView = withAuth(React125__default.memo(HomeView));
69307
69495
  var HomeView_default = HomeView;
69308
69496
  function withWorkspaceDisplayNames(Component3, options = {}) {
69309
69497
  const {
@@ -72567,6 +72755,12 @@ var KPIDetailView_default = KPIDetailViewWithDisplayNames;
72567
72755
  var isNonEmptyString2 = (value) => typeof value === "string" && value.trim().length > 0;
72568
72756
  var KPI_FACTORY_QUERY_PARAM = "factory_id";
72569
72757
  var KPI_FACTORY_AREA_QUERY_PARAM = "factory_area_id";
72758
+ var LINE_STATUS_FILTER_OPTIONS = [
72759
+ { id: "attention", label: "Attention" },
72760
+ { id: "warning", label: "Warning" },
72761
+ { id: "stable", label: "Stable" }
72762
+ ];
72763
+ var DEFAULT_LINE_STATUS_FILTERS = LINE_STATUS_FILTER_OPTIONS.map((option) => option.id);
72570
72764
  var getSingleQueryValue = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
72571
72765
  var resolveCompanyId2 = (...candidates) => candidates.find(isNonEmptyString2);
72572
72766
  var parseTimeToMinutes4 = (value) => {
@@ -72724,19 +72918,36 @@ var LinesLeaderboard = ({
72724
72918
  timezone: _timezone,
72725
72919
  isHistoricalDaily
72726
72920
  }) => {
72921
+ const { user } = useAuth();
72922
+ const isSupervisor = user?.role_level === "supervisor";
72923
+ const isCurrentUserHighlightReady = timeRange === "today" ? !isLoadingToday : !isLoadingMonthly;
72924
+ const isCurrentUserRow = React125__default.useCallback((item) => {
72925
+ if (!isCurrentUserHighlightReady) return false;
72926
+ if (!isSupervisor || !user?.id) return false;
72927
+ if (!item.supervisors) return false;
72928
+ return item.supervisors.some((s) => s.userId === user.id);
72929
+ }, [isCurrentUserHighlightReady, isSupervisor, user?.id]);
72930
+ const renderCurrentUserBadge = () => /* @__PURE__ */ jsx(
72931
+ "span",
72932
+ {
72933
+ className: "inline-flex items-center rounded-full border border-blue-200 bg-blue-50 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.16em] text-blue-700 shadow-sm",
72934
+ "aria-label": "Your leaderboard position",
72935
+ children: "You"
72936
+ }
72937
+ );
72727
72938
  const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
72728
- const assignedLineIdSet = React148__default.useMemo(
72939
+ const assignedLineIdSet = React125__default.useMemo(
72729
72940
  () => new Set(assignedLineIds || []),
72730
72941
  [assignedLineIds]
72731
72942
  );
72732
- const canClickLine = React148__default.useCallback(
72943
+ const canClickLine = React125__default.useCallback(
72733
72944
  (lineId) => {
72734
72945
  if (!assignedLineIds) return true;
72735
72946
  return assignedLineIdSet.has(lineId);
72736
72947
  },
72737
72948
  [assignedLineIds, assignedLineIdSet]
72738
72949
  );
72739
- const handleTimeRangeChange = React148__default.useCallback((newRange) => {
72950
+ const handleTimeRangeChange = React125__default.useCallback((newRange) => {
72740
72951
  if (newRange === timeRange) return;
72741
72952
  trackCoreEvent("Leaderboard Time Range Changed", {
72742
72953
  from_range: timeRange,
@@ -72747,11 +72958,11 @@ var LinesLeaderboard = ({
72747
72958
  });
72748
72959
  setTimeRange(newRange);
72749
72960
  }, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
72750
- const canClickLeaderboardRow = React148__default.useCallback(
72961
+ const canClickLeaderboardRow = React125__default.useCallback(
72751
72962
  (item) => item.rowType === "line" && !!item.line && canClickLine(item.line.id),
72752
72963
  [canClickLine]
72753
72964
  );
72754
- const handleLeaderboardLineClick = React148__default.useCallback((item, clickSource) => {
72965
+ const handleLeaderboardLineClick = React125__default.useCallback((item, clickSource) => {
72755
72966
  if (!canClickLeaderboardRow(item) || !item.line) return;
72756
72967
  trackCoreEvent("Leaderboard Line Clicked", {
72757
72968
  line_id: item.line.id,
@@ -72765,8 +72976,8 @@ var LinesLeaderboard = ({
72765
72976
  });
72766
72977
  onLineClick(item.line);
72767
72978
  }, [canClickLeaderboardRow, onLineClick, timeRange]);
72768
- const viewLoadedTrackedRef = React148__default.useRef(null);
72769
- const leaderboardData = React148__default.useMemo(() => {
72979
+ const viewLoadedTrackedRef = React125__default.useRef(null);
72980
+ const leaderboardData = React125__default.useMemo(() => {
72770
72981
  const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
72771
72982
  const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
72772
72983
  const fallbackEfficiencyMap = timeRange === "today" ? dailyFallbackEfficiencyByLineId : void 0;
@@ -72810,7 +73021,7 @@ var LinesLeaderboard = ({
72810
73021
  isLoadingToday,
72811
73022
  isLoadingMonthly
72812
73023
  ]);
72813
- React148__default.useEffect(() => {
73024
+ React125__default.useEffect(() => {
72814
73025
  const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
72815
73026
  const trackingKey = `${timeRange}-${leaderboardData.length}`;
72816
73027
  if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
@@ -72836,7 +73047,7 @@ var LinesLeaderboard = ({
72836
73047
  const countdownFormat = timeRange === "monthly" ? "days" : "clock";
72837
73048
  const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift ended";
72838
73049
  const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
72839
- const handleCountdownFinished = React148__default.useCallback(() => {
73050
+ const handleCountdownFinished = React125__default.useCallback(() => {
72840
73051
  trackCoreEvent("Leaderboard Countdown Finished", {
72841
73052
  countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
72842
73053
  time_range: timeRange,
@@ -72863,7 +73074,7 @@ var LinesLeaderboard = ({
72863
73074
  return "bg-white border-gray-100";
72864
73075
  }
72865
73076
  };
72866
- React148__default.useEffect(() => {
73077
+ React125__default.useEffect(() => {
72867
73078
  const style = document.createElement("style");
72868
73079
  style.innerHTML = `
72869
73080
  @keyframes float {
@@ -72929,6 +73140,7 @@ var LinesLeaderboard = ({
72929
73140
  const isSecond = item.rank === 2;
72930
73141
  item.rank === 3;
72931
73142
  const isClickable = canClickLeaderboardRow(item);
73143
+ const isOwnSupervisorRow = isCurrentUserRow(item);
72932
73144
  return /* @__PURE__ */ jsxs(
72933
73145
  "div",
72934
73146
  {
@@ -72965,22 +73177,25 @@ var LinesLeaderboard = ({
72965
73177
  /* @__PURE__ */ jsx("div", { className: `absolute -bottom-2 md:-bottom-3 left-1/2 -translate-x-1/2 w-6 h-6 md:w-8 md:h-8 xl:w-10 xl:h-10 rounded-full flex items-center justify-center text-[10px] md:text-xs lg:text-sm xl:text-base font-extrabold text-white shadow-lg ${isFirst ? "bg-gradient-to-br from-yellow-400 to-yellow-600 ring-2 md:ring-4 ring-yellow-50" : isSecond ? "bg-gradient-to-br from-gray-400 to-gray-600 ring-2 md:ring-4 ring-gray-50" : "bg-gradient-to-br from-orange-400 to-orange-600 ring-2 md:ring-4 ring-orange-50"}`, children: item.rank })
72966
73178
  ] })
72967
73179
  ] }),
72968
- /* @__PURE__ */ jsx(
73180
+ /* @__PURE__ */ jsxs(
72969
73181
  "div",
72970
73182
  {
72971
- className: `flex flex-col items-center w-32 md:w-40 lg:w-48 xl:w-60 px-2 md:px-3 xl:px-4 pb-3 md:pb-4 pt-8 md:pt-10 rounded-2xl border bg-gradient-to-b shadow-2xl backdrop-blur-sm ${getRankColor(item.rank)} ${isFirst ? "h-44 md:h-52 lg:h-60 xl:h-64" : isSecond ? "h-36 md:h-44 lg:h-52 xl:h-56" : "h-28 md:h-36 lg:h-44 xl:h-48"}`,
72972
- children: /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center w-full", children: [
72973
- /* @__PURE__ */ jsx("h3", { className: `font-bold text-gray-900 text-center line-clamp-1 mb-1 ${isFirst ? "text-xs md:text-sm lg:text-base xl:text-lg" : "text-[10px] md:text-xs lg:text-sm xl:text-base"}`, children: item.supervisorName }),
72974
- /* @__PURE__ */ jsx("p", { className: `text-gray-600 text-center line-clamp-1 font-medium opacity-80 bg-white/50 px-2 md:px-3 py-0.5 rounded-full ${isFirst ? "text-[9px] md:text-[10px] lg:text-xs xl:text-sm mb-2 md:mb-3" : "text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs mb-1 md:mb-2"}`, children: item.displayName }),
72975
- item.rowType === "area" && /* @__PURE__ */ jsxs("span", { className: "mb-1 text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs font-semibold uppercase text-gray-500", children: [
72976
- item.lines.length,
72977
- " lines"
72978
- ] }),
72979
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center mt-auto", children: [
72980
- /* @__PURE__ */ jsx("span", { className: `font-bold uppercase tracking-widest mb-0.5 ${isFirst ? "text-yellow-700/70 text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs" : isSecond ? "text-gray-600/70 text-[7px] md:text-[8px] lg:text-[9px] xl:text-[10px]" : "text-orange-700/70 text-[7px] md:text-[8px] lg:text-[9px] xl:text-[10px]"}`, children: viewType === "machine" ? "Utilization" : "Efficiency" }),
72981
- /* @__PURE__ */ jsx("span", { className: `font-black tracking-tight leading-none ${isFirst ? "text-lg md:text-xl lg:text-2xl xl:text-3xl text-transparent bg-clip-text bg-gradient-to-br from-yellow-600 to-yellow-800 drop-shadow-sm" : isSecond ? "text-base md:text-lg lg:text-xl xl:text-2xl text-transparent bg-clip-text bg-gradient-to-br from-gray-600 to-gray-800 drop-shadow-sm" : "text-sm md:text-base lg:text-lg xl:text-xl text-transparent bg-clip-text bg-gradient-to-br from-orange-600 to-orange-800 drop-shadow-sm"}`, children: formatEfficiency(item.efficiency) })
73183
+ className: `relative flex flex-col items-center w-32 md:w-40 lg:w-48 xl:w-60 px-2 md:px-3 xl:px-4 pb-3 md:pb-4 pt-8 md:pt-10 rounded-2xl border bg-gradient-to-b shadow-2xl backdrop-blur-sm ${getRankColor(item.rank)} ${isOwnSupervisorRow ? "!border-blue-300 ring-2 ring-blue-500/20 shadow-[0_16px_45px_rgba(37,99,235,0.16)]" : ""} ${isFirst ? "h-44 md:h-52 lg:h-60 xl:h-64" : isSecond ? "h-36 md:h-44 lg:h-52 xl:h-56" : "h-28 md:h-36 lg:h-44 xl:h-48"}`,
73184
+ children: [
73185
+ isOwnSupervisorRow && /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-3", children: renderCurrentUserBadge() }),
73186
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center w-full", children: [
73187
+ /* @__PURE__ */ jsx("h3", { className: `font-bold text-gray-900 text-center line-clamp-1 mb-1 ${isFirst ? "text-xs md:text-sm lg:text-base xl:text-lg" : "text-[10px] md:text-xs lg:text-sm xl:text-base"}`, children: item.supervisorName }),
73188
+ /* @__PURE__ */ jsx("p", { className: `text-gray-600 text-center line-clamp-1 font-medium opacity-80 bg-white/50 px-2 md:px-3 py-0.5 rounded-full ${isFirst ? "text-[9px] md:text-[10px] lg:text-xs xl:text-sm mb-2 md:mb-3" : "text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs mb-1 md:mb-2"}`, children: item.displayName }),
73189
+ item.rowType === "area" && /* @__PURE__ */ jsxs("span", { className: "mb-1 text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs font-semibold uppercase text-gray-500", children: [
73190
+ item.lines.length,
73191
+ " lines"
73192
+ ] }),
73193
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center mt-auto", children: [
73194
+ /* @__PURE__ */ jsx("span", { className: `font-bold uppercase tracking-widest mb-0.5 ${isFirst ? "text-yellow-700/70 text-[8px] md:text-[9px] lg:text-[10px] xl:text-xs" : isSecond ? "text-gray-600/70 text-[7px] md:text-[8px] lg:text-[9px] xl:text-[10px]" : "text-orange-700/70 text-[7px] md:text-[8px] lg:text-[9px] xl:text-[10px]"}`, children: viewType === "machine" ? "Utilization" : "Efficiency" }),
73195
+ /* @__PURE__ */ jsx("span", { className: `font-black tracking-tight leading-none ${isFirst ? "text-lg md:text-xl lg:text-2xl xl:text-3xl text-transparent bg-clip-text bg-gradient-to-br from-yellow-600 to-yellow-800 drop-shadow-sm" : isSecond ? "text-base md:text-lg lg:text-xl xl:text-2xl text-transparent bg-clip-text bg-gradient-to-br from-gray-600 to-gray-800 drop-shadow-sm" : "text-sm md:text-base lg:text-lg xl:text-xl text-transparent bg-clip-text bg-gradient-to-br from-orange-600 to-orange-800 drop-shadow-sm"}`, children: formatEfficiency(item.efficiency) })
73196
+ ] })
72982
73197
  ] })
72983
- ] })
73198
+ ]
72984
73199
  }
72985
73200
  )
72986
73201
  ]
@@ -72999,11 +73214,12 @@ var LinesLeaderboard = ({
72999
73214
  /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-100", children: leaderboardData.map((item) => {
73000
73215
  const isTopThree = item.rank <= 3;
73001
73216
  const isClickable = canClickLeaderboardRow(item);
73217
+ const isOwnSupervisorRow = isCurrentUserRow(item);
73002
73218
  return /* @__PURE__ */ jsxs(
73003
73219
  "tr",
73004
73220
  {
73005
73221
  onClick: () => handleLeaderboardLineClick(item, isTopThree ? "podium" : "table"),
73006
- className: `transition-colors ${isTopThree ? "sm:hidden" : ""} ${isClickable ? "hover:bg-gray-50 cursor-pointer group" : "cursor-not-allowed"}`,
73222
+ className: `transition-colors ${isTopThree ? "sm:hidden" : ""} ${isOwnSupervisorRow ? "bg-blue-50/80 ring-inset ring-1 ring-blue-500/20 shadow-[inset_3px_0_0_rgba(37,99,235,0.75)]" : ""} ${isClickable ? isOwnSupervisorRow ? "hover:bg-blue-100/80 cursor-pointer group" : "hover:bg-gray-50 cursor-pointer group" : "cursor-not-allowed"}`,
73007
73223
  children: [
73008
73224
  /* @__PURE__ */ jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-8 h-8 rounded-full bg-gray-100 text-gray-600 font-bold text-sm", children: item.rank }) }),
73009
73225
  /* @__PURE__ */ jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
@@ -73028,7 +73244,8 @@ var LinesLeaderboard = ({
73028
73244
  item.supervisors.length - 3
73029
73245
  ] })
73030
73246
  ] }) : /* @__PURE__ */ jsx("div", { className: "w-8 h-8 rounded-full bg-gray-100 flex items-center justify-center text-gray-500 overflow-hidden border border-gray-200 flex-shrink-0", children: item.supervisorImage ? /* @__PURE__ */ jsx("img", { src: item.supervisorImage, alt: item.supervisorName, className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsx("span", { className: "text-xs font-bold", children: getInitials(item.supervisorName) }) }),
73031
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-900", children: item.supervisorName })
73247
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-900", children: item.supervisorName }),
73248
+ isOwnSupervisorRow && renderCurrentUserBadge()
73032
73249
  ] }) }),
73033
73250
  /* @__PURE__ */ jsx("td", { className: "px-4 py-3 whitespace-nowrap text-sm text-gray-500", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
73034
73251
  /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-700", children: item.displayName }),
@@ -73325,14 +73542,26 @@ var KPIsOverviewView = ({
73325
73542
  const [activeTab, setActiveTab] = useState("today");
73326
73543
  const [timeRange, setTimeRange] = useState("today");
73327
73544
  const [viewType, setViewType] = useState("operator");
73545
+ const [selectedLineStatusFilters, setSelectedLineStatusFilters] = useState(DEFAULT_LINE_STATUS_FILTERS);
73546
+ const [selectedFactoryFilters, setSelectedFactoryFilters] = useState([]);
73547
+ const [hasUserEditedFactoryFilters, setHasUserEditedFactoryFilters] = useState(false);
73548
+ const [todayViewLevel, setTodayViewLevel] = useState("factory");
73549
+ const [efficiencySortDirection, setEfficiencySortDirection] = useState("desc");
73328
73550
  const [selectedLeaderboardDate, setSelectedLeaderboardDate] = useState("");
73329
73551
  const [selectedLeaderboardShiftId, setSelectedLeaderboardShiftId] = useState(0);
73330
73552
  const [leaderboardDailyScopeMode, setLeaderboardDailyScopeMode] = useState("live");
73331
73553
  const [hasHydratedLeaderboardRouteState, setHasHydratedLeaderboardRouteState] = useState(false);
73332
73554
  const [loading, setLoading] = useState(true);
73333
73555
  const [isFilterOpen, setIsFilterOpen] = useState(false);
73556
+ const [isViewsOpen, setIsViewsOpen] = useState(false);
73557
+ const [isSortOpen, setIsSortOpen] = useState(false);
73334
73558
  const filterRef = useRef(null);
73335
73559
  const filterButtonRef = useRef(null);
73560
+ const viewsRef = useRef(null);
73561
+ const viewsButtonRef = useRef(null);
73562
+ const sortRef = useRef(null);
73563
+ const sortButtonRef = useRef(null);
73564
+ const previousFactoryFilterOptionIdsRef = useRef([]);
73336
73565
  const [error, setError] = useState(null);
73337
73566
  const [todayEfficiencyByLineId, setTodayEfficiencyByLineId] = useState(/* @__PURE__ */ new Map());
73338
73567
  const [dailyLoading, setDailyLoading] = useState(false);
@@ -73362,36 +73591,36 @@ var KPIsOverviewView = ({
73362
73591
  const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
73363
73592
  const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
73364
73593
  const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
73365
- const scopedLineIds = React148__default.useMemo(
73594
+ const scopedLineIds = React125__default.useMemo(
73366
73595
  () => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
73367
73596
  [user?.access_scope?.line_ids]
73368
73597
  );
73369
73598
  const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
73370
73599
  const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
73371
73600
  const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
73372
- const resolvedAssignedLineIds = React148__default.useMemo(() => {
73601
+ const resolvedAssignedLineIds = React125__default.useMemo(() => {
73373
73602
  if (isSuperAdmin) return [];
73374
73603
  if (scopedLineIds.length > 0) return scopedLineIds;
73375
73604
  if (lineIds && lineIds.length > 0) return lineIds;
73376
73605
  if (isStrictLineScopedRole && hasCanonicalScope) return [];
73377
73606
  return [];
73378
73607
  }, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
73379
- const assignedLineIdSet = React148__default.useMemo(
73608
+ const assignedLineIdSet = React125__default.useMemo(
73380
73609
  () => new Set(resolvedAssignedLineIds),
73381
73610
  [resolvedAssignedLineIds]
73382
73611
  );
73383
- const loadedLineIds = React148__default.useMemo(
73612
+ const loadedLineIds = React125__default.useMemo(
73384
73613
  () => lines.map((line) => line.id).filter(Boolean),
73385
73614
  [lines]
73386
73615
  );
73387
- const metricsLineIds = React148__default.useMemo(() => {
73616
+ const metricsLineIds = React125__default.useMemo(() => {
73388
73617
  if (isSuperAdmin) {
73389
73618
  return loadedLineIds.length > 0 ? loadedLineIds : lineIds ?? [];
73390
73619
  }
73391
73620
  return resolvedAssignedLineIds;
73392
73621
  }, [isSuperAdmin, loadedLineIds, lineIds, resolvedAssignedLineIds]);
73393
73622
  const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
73394
- const leaderboardLinesForView = React148__default.useMemo(() => {
73623
+ const leaderboardLinesForView = React125__default.useMemo(() => {
73395
73624
  const targetMode = viewType === "machine" ? "uptime" : "output";
73396
73625
  const metadataByLineId = new Map(lines.map((line) => [line.id, line]));
73397
73626
  return leaderboardLines.map((line) => {
@@ -73410,17 +73639,57 @@ var KPIsOverviewView = ({
73410
73639
  } : line;
73411
73640
  }).filter((line) => (line.monitoring_mode ?? "output") === targetMode);
73412
73641
  }, [leaderboardLines, lines, viewType]);
73413
- const linesForView = React148__default.useMemo(() => {
73642
+ const linesForView = React125__default.useMemo(() => {
73414
73643
  const targetMode = viewType === "machine" ? "uptime" : "output";
73415
73644
  return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
73416
73645
  }, [lines, viewType]);
73417
- const relevantLinesForMode = React148__default.useMemo(() => {
73646
+ const factoryFilterOptions = React125__default.useMemo(() => {
73647
+ const factories = /* @__PURE__ */ new Map();
73648
+ linesForView.forEach((line) => {
73649
+ const factoryId = line.factory_id || "unknown-factory";
73650
+ if (!factories.has(factoryId)) {
73651
+ factories.set(factoryId, line.factory_name || "Factory");
73652
+ }
73653
+ });
73654
+ return Array.from(factories.entries()).map(([id3, label]) => ({ id: id3, label })).sort((left, right) => left.label.localeCompare(right.label, void 0, { sensitivity: "base", numeric: true }));
73655
+ }, [linesForView]);
73656
+ const factoryFilterOptionIds = React125__default.useMemo(
73657
+ () => factoryFilterOptions.map((option) => option.id),
73658
+ [factoryFilterOptions]
73659
+ );
73660
+ const effectiveSelectedFactoryFilters = React125__default.useMemo(
73661
+ () => hasUserEditedFactoryFilters ? selectedFactoryFilters : factoryFilterOptionIds,
73662
+ [factoryFilterOptionIds, hasUserEditedFactoryFilters, selectedFactoryFilters]
73663
+ );
73664
+ useEffect(() => {
73665
+ const previousFactoryFilterOptionIds = previousFactoryFilterOptionIdsRef.current;
73666
+ if (factoryFilterOptionIds.length === 0) {
73667
+ setHasUserEditedFactoryFilters(false);
73668
+ }
73669
+ setSelectedFactoryFilters((previousFilters) => {
73670
+ if (factoryFilterOptionIds.length === 0) {
73671
+ return previousFilters.length === 0 ? previousFilters : [];
73672
+ }
73673
+ if (!hasUserEditedFactoryFilters) {
73674
+ return factoryFilterOptionIds;
73675
+ }
73676
+ const validFactoryIds = new Set(factoryFilterOptionIds);
73677
+ const previousFactoryIds = new Set(previousFactoryFilterOptionIds);
73678
+ const nextFilters = [
73679
+ ...previousFilters.filter((factoryId) => validFactoryIds.has(factoryId)),
73680
+ ...factoryFilterOptionIds.filter((factoryId) => !previousFactoryIds.has(factoryId))
73681
+ ];
73682
+ return nextFilters.length === previousFilters.length ? previousFilters : nextFilters;
73683
+ });
73684
+ previousFactoryFilterOptionIdsRef.current = factoryFilterOptionIds;
73685
+ }, [factoryFilterOptionIds, hasUserEditedFactoryFilters]);
73686
+ const relevantLinesForMode = React125__default.useMemo(() => {
73418
73687
  if (activeTab === "leaderboard") {
73419
73688
  return leaderboardLines.length > 0 ? leaderboardLines : lines;
73420
73689
  }
73421
73690
  return lines;
73422
73691
  }, [activeTab, leaderboardLines, lines]);
73423
- const { hasUptime, hasOutput } = React148__default.useMemo(() => {
73692
+ const { hasUptime, hasOutput } = React125__default.useMemo(() => {
73424
73693
  let uptime = false;
73425
73694
  let output = false;
73426
73695
  for (const line of relevantLinesForMode) {
@@ -73445,18 +73714,42 @@ var KPIsOverviewView = ({
73445
73714
  const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
73446
73715
  const currentShiftDate = currentShiftDetails.date;
73447
73716
  const currentShiftId = currentShiftDetails.shiftId;
73448
- const activeFiltersCount = React148__default.useMemo(() => {
73717
+ const activeFiltersCount = React125__default.useMemo(() => {
73449
73718
  let count = 0;
73450
- if (leaderboardDailyScopeMode === "historical" && selectedLeaderboardShiftId !== currentShiftId) {
73719
+ if (activeTab === "today" && selectedLineStatusFilters.length !== LINE_STATUS_FILTER_OPTIONS.length) {
73720
+ count++;
73721
+ }
73722
+ if (activeTab === "today" && factoryFilterOptions.length > 0 && effectiveSelectedFactoryFilters.length !== factoryFilterOptions.length) {
73723
+ count++;
73724
+ }
73725
+ if (activeTab === "leaderboard" && leaderboardDailyScopeMode === "historical" && selectedLeaderboardShiftId !== currentShiftId) {
73451
73726
  count++;
73452
73727
  }
73453
73728
  return count;
73454
- }, [leaderboardDailyScopeMode, selectedLeaderboardShiftId, currentShiftId]);
73455
- const clearFilters = React148__default.useCallback(() => {
73729
+ }, [activeTab, selectedLineStatusFilters.length, factoryFilterOptions.length, effectiveSelectedFactoryFilters.length, leaderboardDailyScopeMode, selectedLeaderboardShiftId, currentShiftId]);
73730
+ const activeSortCount = React125__default.useMemo(() => activeTab === "today" && efficiencySortDirection !== "desc" ? 1 : 0, [activeTab, efficiencySortDirection]);
73731
+ const clearFilters = React125__default.useCallback(() => {
73732
+ trackCoreEvent("Lines Overview Filters Cleared", {
73733
+ surface: "lines_overview",
73734
+ action: "clear_filters",
73735
+ control_clicked: "filters",
73736
+ option_clicked: "clear_all",
73737
+ option_label: "Clear all",
73738
+ source: "filters_dropdown",
73739
+ active_tab: activeTab,
73740
+ previous_status_filters: selectedLineStatusFilters,
73741
+ previous_factory_filters: effectiveSelectedFactoryFilters,
73742
+ selected_shift_id: selectedLeaderboardShiftId,
73743
+ selected_view_level: todayViewLevel,
73744
+ selected_sort_direction: efficiencySortDirection
73745
+ });
73746
+ setSelectedLineStatusFilters(DEFAULT_LINE_STATUS_FILTERS);
73747
+ setHasUserEditedFactoryFilters(false);
73748
+ setSelectedFactoryFilters(factoryFilterOptionIds);
73456
73749
  setSelectedLeaderboardShiftId(currentShiftId);
73457
73750
  setSelectedLeaderboardDate(currentShiftDate);
73458
73751
  setLeaderboardDailyScopeMode("live");
73459
- }, [currentShiftDate, currentShiftId]);
73752
+ }, [activeTab, currentShiftDate, currentShiftId, effectiveSelectedFactoryFilters, efficiencySortDirection, factoryFilterOptionIds, selectedLineStatusFilters, selectedLeaderboardShiftId, todayViewLevel]);
73460
73753
  useEffect(() => {
73461
73754
  const handleClickOutside = (event) => {
73462
73755
  const target = event.target;
@@ -73464,15 +73757,23 @@ var KPIsOverviewView = ({
73464
73757
  if (filterRef.current && !filterRef.current.contains(target)) {
73465
73758
  setIsFilterOpen(false);
73466
73759
  }
73760
+ if (viewsButtonRef.current?.contains(target)) return;
73761
+ if (viewsRef.current && !viewsRef.current.contains(target)) {
73762
+ setIsViewsOpen(false);
73763
+ }
73764
+ if (sortButtonRef.current?.contains(target)) return;
73765
+ if (sortRef.current && !sortRef.current.contains(target)) {
73766
+ setIsSortOpen(false);
73767
+ }
73467
73768
  };
73468
73769
  document.addEventListener("mousedown", handleClickOutside);
73469
73770
  return () => document.removeEventListener("mousedown", handleClickOutside);
73470
73771
  }, []);
73471
- const shiftEndDate = React148__default.useMemo(
73772
+ const shiftEndDate = React125__default.useMemo(
73472
73773
  () => getShiftEndDate(currentShiftDetails, configuredTimezone),
73473
73774
  [currentShiftDetails, configuredTimezone]
73474
73775
  );
73475
- const leaderboardShiftOptions = React148__default.useMemo(() => {
73776
+ const leaderboardShiftOptions = React125__default.useMemo(() => {
73476
73777
  if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
73477
73778
  return shiftConfig.shifts.map((shift) => ({
73478
73779
  id: shift.shiftId,
@@ -73489,37 +73790,42 @@ var KPIsOverviewView = ({
73489
73790
  const effectiveLeaderboardDate = selectedLeaderboardDate || currentShiftDate;
73490
73791
  const effectiveLeaderboardShiftId = Number.isFinite(selectedLeaderboardShiftId) ? selectedLeaderboardShiftId : currentShiftId;
73491
73792
  const isHistoricalLeaderboardDaily = activeTab === "leaderboard" && timeRange === "today" && leaderboardDailyScopeMode === "historical" && (effectiveLeaderboardDate !== currentShiftDate || effectiveLeaderboardShiftId !== currentShiftId);
73492
- const updateLeaderboardDate = React148__default.useCallback((dateKey) => {
73793
+ const updateLeaderboardDate = React125__default.useCallback((dateKey) => {
73493
73794
  setSelectedLeaderboardDate(dateKey);
73494
73795
  setLeaderboardDailyScopeMode(
73495
73796
  dateKey === currentShiftDate && effectiveLeaderboardShiftId === currentShiftId ? "live" : "historical"
73496
73797
  );
73497
73798
  }, [currentShiftDate, currentShiftId, effectiveLeaderboardShiftId]);
73498
- const updateLeaderboardShiftId = React148__default.useCallback((shiftId) => {
73799
+ const updateLeaderboardShiftId = React125__default.useCallback((shiftId) => {
73499
73800
  setSelectedLeaderboardShiftId(shiftId);
73500
73801
  setLeaderboardDailyScopeMode(
73501
73802
  effectiveLeaderboardDate === currentShiftDate && shiftId === currentShiftId ? "live" : "historical"
73502
73803
  );
73503
73804
  }, [currentShiftDate, currentShiftId, effectiveLeaderboardDate]);
73504
- const returnLeaderboardToLive = React148__default.useCallback(() => {
73805
+ const returnLeaderboardToLive = React125__default.useCallback(() => {
73505
73806
  setSelectedLeaderboardDate(currentShiftDate);
73506
73807
  setSelectedLeaderboardShiftId(currentShiftId);
73507
73808
  setLeaderboardDailyScopeMode("live");
73508
73809
  }, [currentShiftDate, currentShiftId]);
73509
73810
  const selectedFactoryIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_QUERY_PARAM]);
73510
73811
  const selectedFactoryAreaIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_AREA_QUERY_PARAM]);
73511
- const kpiLineHierarchy = React148__default.useMemo(
73812
+ const kpiLineHierarchy = React125__default.useMemo(
73512
73813
  () => buildKpiLineHierarchy(linesForView),
73513
73814
  [linesForView]
73514
73815
  );
73515
- const selectedFactoryNode = React148__default.useMemo(
73816
+ const selectedFactoryNode = React125__default.useMemo(
73516
73817
  () => kpiLineHierarchy.showFactoryLevel && selectedFactoryIdFromUrl ? kpiLineHierarchy.factories.find((factory) => factory.id === selectedFactoryIdFromUrl) : void 0,
73517
73818
  [kpiLineHierarchy, selectedFactoryIdFromUrl]
73518
73819
  );
73519
- const selectedFactoryAreaNode = React148__default.useMemo(
73820
+ const selectedFactoryAreaNode = React125__default.useMemo(
73520
73821
  () => selectedFactoryNode && selectedFactoryAreaIdFromUrl ? selectedFactoryNode.areas.find((area) => area.id === selectedFactoryAreaIdFromUrl) : void 0,
73521
73822
  [selectedFactoryNode, selectedFactoryAreaIdFromUrl]
73522
73823
  );
73824
+ useEffect(() => {
73825
+ if (!kpiLineHierarchy.showFactoryLevel && todayViewLevel !== "factory") {
73826
+ setTodayViewLevel("factory");
73827
+ }
73828
+ }, [kpiLineHierarchy.showFactoryLevel, todayViewLevel]);
73523
73829
  useEffect(() => {
73524
73830
  if (!router.isReady) return;
73525
73831
  const tabQuery = router.query.tab;
@@ -73605,15 +73911,15 @@ var KPIsOverviewView = ({
73605
73911
  lineId: factoryViewId,
73606
73912
  userAccessibleLineIds: metricsLineIds
73607
73913
  });
73608
- const defaultKPIs = React148__default.useMemo(() => createDefaultKPIs(), []);
73609
- const lineModeById = React148__default.useMemo(() => {
73914
+ const defaultKPIs = React125__default.useMemo(() => createDefaultKPIs(), []);
73915
+ const lineModeById = React125__default.useMemo(() => {
73610
73916
  const map = /* @__PURE__ */ new Map();
73611
73917
  linesForView.forEach((line) => {
73612
73918
  map.set(line.id, line.monitoring_mode ?? "output");
73613
73919
  });
73614
73920
  return map;
73615
73921
  }, [linesForView]);
73616
- const lineMetricRowsByLineId = React148__default.useMemo(() => {
73922
+ const lineMetricRowsByLineId = React125__default.useMemo(() => {
73617
73923
  const map = /* @__PURE__ */ new Map();
73618
73924
  lineMetrics.forEach((row) => {
73619
73925
  if (!row?.line_id) return;
@@ -73625,7 +73931,7 @@ var KPIsOverviewView = ({
73625
73931
  });
73626
73932
  return map;
73627
73933
  }, [lineMetrics, lineModeById]);
73628
- const liveDailyFallbackEfficiencyByLineId = React148__default.useMemo(() => {
73934
+ const liveDailyFallbackEfficiencyByLineId = React125__default.useMemo(() => {
73629
73935
  const map = /* @__PURE__ */ new Map();
73630
73936
  lineMetricRowsByLineId.forEach((row, lineId) => {
73631
73937
  const value = Number(row?.avg_efficiency);
@@ -73647,31 +73953,31 @@ var KPIsOverviewView = ({
73647
73953
  isHistoricalLeaderboardDaily,
73648
73954
  lineMetricRowsByLineId
73649
73955
  ]);
73650
- const dailyFallbackEfficiencyByLineId = React148__default.useMemo(() => {
73956
+ const dailyFallbackEfficiencyByLineId = React125__default.useMemo(() => {
73651
73957
  const map = new Map(liveDailyFallbackEfficiencyByLineId);
73652
73958
  scopedDailyFallbackEfficiencyByLineId.forEach((value, lineId) => {
73653
73959
  map.set(lineId, value);
73654
73960
  });
73655
73961
  return map;
73656
73962
  }, [liveDailyFallbackEfficiencyByLineId, scopedDailyFallbackEfficiencyByLineId]);
73657
- const kpisByLineId = React148__default.useMemo(() => {
73963
+ const kpisByLineId = React125__default.useMemo(() => {
73658
73964
  const map = /* @__PURE__ */ new Map();
73659
73965
  lineMetricRowsByLineId.forEach((row, lineId) => {
73660
73966
  map.set(lineId, buildKPIsFromLineMetricsRow(row));
73661
73967
  });
73662
73968
  return map;
73663
73969
  }, [lineMetricRowsByLineId]);
73664
- const getLineCardKpis = React148__default.useCallback((line) => {
73970
+ const getLineCardKpis = React125__default.useCallback((line) => {
73665
73971
  if (metricsError) return null;
73666
73972
  return kpisByLineId.get(line.id) ?? (metricsLoading ? null : defaultKPIs);
73667
73973
  }, [defaultKPIs, kpisByLineId, metricsError, metricsLoading]);
73668
- const getAggregateCardKpis = React148__default.useCallback((cardLines) => {
73974
+ const getAggregateCardKpis = React125__default.useCallback((cardLines) => {
73669
73975
  if (metricsError) return null;
73670
73976
  const rows = cardLines.map((line) => lineMetricRowsByLineId.get(line.id)).filter(Boolean);
73671
73977
  if (metricsLoading && rows.length === 0) return null;
73672
73978
  return aggregateKPIsFromLineMetricsRows(rows);
73673
73979
  }, [lineMetricRowsByLineId, metricsError, metricsLoading]);
73674
- const supervisorLineIds = React148__default.useMemo(
73980
+ const supervisorLineIds = React125__default.useMemo(
73675
73981
  () => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
73676
73982
  [leaderboardLines, lines]
73677
73983
  );
@@ -73923,7 +74229,135 @@ var KPIsOverviewView = ({
73923
74229
  { shallow: true }
73924
74230
  );
73925
74231
  }, [router]);
73926
- const lineDetailReturnTo = React148__default.useMemo(() => {
74232
+ const handleLineStatusFilterToggle = useCallback((status) => {
74233
+ setSelectedLineStatusFilters((previousStatuses) => {
74234
+ const optionLabel = LINE_STATUS_FILTER_OPTIONS.find((option) => option.id === status)?.label ?? status;
74235
+ const wasSelected = previousStatuses.includes(status);
74236
+ const nextStatuses = previousStatuses.includes(status) ? previousStatuses.filter((item) => item !== status) : [...previousStatuses, status];
74237
+ trackCoreEvent("Lines Overview Filter Changed", {
74238
+ surface: "lines_overview",
74239
+ action: "toggle_status_filter",
74240
+ control_clicked: "filters",
74241
+ source: "filters_dropdown",
74242
+ filter_group: "status",
74243
+ option_clicked: status,
74244
+ option_label: optionLabel,
74245
+ option_selected: !wasSelected,
74246
+ toggled_status: status,
74247
+ previous_status_filters: previousStatuses,
74248
+ selected_status_filters: nextStatuses,
74249
+ selected_factory_filters: effectiveSelectedFactoryFilters,
74250
+ selected_view_level: todayViewLevel,
74251
+ selected_sort_direction: efficiencySortDirection
74252
+ });
74253
+ return nextStatuses;
74254
+ });
74255
+ }, [effectiveSelectedFactoryFilters, efficiencySortDirection, todayViewLevel]);
74256
+ const handleFactoryFilterToggle = useCallback((factoryId) => {
74257
+ setHasUserEditedFactoryFilters(true);
74258
+ setSelectedFactoryFilters((previousFactoryFilters) => {
74259
+ const baseFactoryFilters = hasUserEditedFactoryFilters ? previousFactoryFilters : factoryFilterOptionIds;
74260
+ const optionLabel = factoryFilterOptions.find((option) => option.id === factoryId)?.label ?? factoryId;
74261
+ const wasSelected = baseFactoryFilters.includes(factoryId);
74262
+ const nextFactoryFilters = baseFactoryFilters.includes(factoryId) ? baseFactoryFilters.filter((item) => item !== factoryId) : [...baseFactoryFilters, factoryId];
74263
+ trackCoreEvent("Lines Overview Filter Changed", {
74264
+ surface: "lines_overview",
74265
+ action: "toggle_factory",
74266
+ control_clicked: "filters",
74267
+ source: "filters_dropdown",
74268
+ filter_group: "factory",
74269
+ option_clicked: factoryId,
74270
+ option_label: optionLabel,
74271
+ option_selected: !wasSelected,
74272
+ toggled_factory_id: factoryId,
74273
+ toggled_factory_name: optionLabel,
74274
+ previous_factory_filters: baseFactoryFilters,
74275
+ selected_factory_filters: nextFactoryFilters,
74276
+ selected_status_filters: selectedLineStatusFilters,
74277
+ selected_view_level: todayViewLevel,
74278
+ selected_sort_direction: efficiencySortDirection
74279
+ });
74280
+ return nextFactoryFilters;
74281
+ });
74282
+ }, [efficiencySortDirection, factoryFilterOptionIds, factoryFilterOptions, hasUserEditedFactoryFilters, selectedLineStatusFilters, todayViewLevel]);
74283
+ const handleTodayViewLevelChange = useCallback((nextViewLevel) => {
74284
+ const viewLevelLabels = {
74285
+ factory: "Factory level",
74286
+ units: "Area level"
74287
+ };
74288
+ trackCoreEvent("Lines Overview View Option Clicked", {
74289
+ surface: "lines_overview",
74290
+ action: "click_view_option",
74291
+ control_clicked: "views",
74292
+ source: "views_dropdown",
74293
+ option_clicked: nextViewLevel,
74294
+ option_label: viewLevelLabels[nextViewLevel],
74295
+ previous_view_level: todayViewLevel,
74296
+ selected_view_level: nextViewLevel,
74297
+ option_selected: nextViewLevel !== todayViewLevel,
74298
+ selected_factory_filters: effectiveSelectedFactoryFilters,
74299
+ selected_status_filters: selectedLineStatusFilters,
74300
+ selected_sort_direction: efficiencySortDirection
74301
+ });
74302
+ if (nextViewLevel === todayViewLevel) {
74303
+ return;
74304
+ }
74305
+ trackCoreEvent("Lines Overview View Changed", {
74306
+ surface: "lines_overview",
74307
+ action: "select_view_level",
74308
+ control_clicked: "views",
74309
+ source: "views_dropdown",
74310
+ option_clicked: nextViewLevel,
74311
+ option_label: viewLevelLabels[nextViewLevel],
74312
+ previous_view_level: todayViewLevel,
74313
+ selected_view_level: nextViewLevel,
74314
+ selected_factory_filters: effectiveSelectedFactoryFilters,
74315
+ selected_status_filters: selectedLineStatusFilters,
74316
+ selected_sort_direction: efficiencySortDirection
74317
+ });
74318
+ setTodayViewLevel(nextViewLevel);
74319
+ navigateTodayHierarchy();
74320
+ }, [effectiveSelectedFactoryFilters, efficiencySortDirection, navigateTodayHierarchy, selectedLineStatusFilters, todayViewLevel]);
74321
+ const handleEfficiencySortChange = useCallback((nextSortDirection) => {
74322
+ const sortLabels = {
74323
+ desc: "Highest to lowest",
74324
+ asc: "Lowest to highest"
74325
+ };
74326
+ trackCoreEvent("Lines Overview Sort Option Clicked", {
74327
+ surface: "lines_overview",
74328
+ action: "click_sort_option",
74329
+ control_clicked: "sort",
74330
+ source: "sort_dropdown",
74331
+ sort_metric: "efficiency",
74332
+ option_clicked: nextSortDirection,
74333
+ option_label: sortLabels[nextSortDirection],
74334
+ previous_sort_direction: efficiencySortDirection,
74335
+ selected_sort_direction: nextSortDirection,
74336
+ option_selected: nextSortDirection !== efficiencySortDirection,
74337
+ selected_factory_filters: effectiveSelectedFactoryFilters,
74338
+ selected_status_filters: selectedLineStatusFilters,
74339
+ selected_view_level: todayViewLevel
74340
+ });
74341
+ if (nextSortDirection === efficiencySortDirection) {
74342
+ return;
74343
+ }
74344
+ trackCoreEvent("Lines Overview Sort Changed", {
74345
+ surface: "lines_overview",
74346
+ action: "select_efficiency_sort",
74347
+ control_clicked: "sort",
74348
+ source: "sort_dropdown",
74349
+ sort_metric: "efficiency",
74350
+ option_clicked: nextSortDirection,
74351
+ option_label: sortLabels[nextSortDirection],
74352
+ previous_sort_direction: efficiencySortDirection,
74353
+ selected_sort_direction: nextSortDirection,
74354
+ selected_factory_filters: effectiveSelectedFactoryFilters,
74355
+ selected_status_filters: selectedLineStatusFilters,
74356
+ selected_view_level: todayViewLevel
74357
+ });
74358
+ setEfficiencySortDirection(nextSortDirection);
74359
+ }, [effectiveSelectedFactoryFilters, efficiencySortDirection, selectedLineStatusFilters, todayViewLevel]);
74360
+ const lineDetailReturnTo = React125__default.useMemo(() => {
73927
74361
  if (activeTab !== "today" || !selectedFactoryNode) return void 0;
73928
74362
  return createKpisOverviewUrl({
73929
74363
  factoryId: selectedFactoryNode.id,
@@ -74013,6 +74447,19 @@ var KPIsOverviewView = ({
74013
74447
  const headerShiftId = showHistoricalLeaderboardHeader ? effectiveLeaderboardShiftId : currentShiftDetails.shiftId;
74014
74448
  const headerShiftName = getShiftNameById(headerShiftId, configuredTimezone, shiftConfig).replace(/ Shift$/i, "");
74015
74449
  const headerDateLabel = isMonthlyMode ? getMonthRange() : formatLocalDate2(headerDateKey);
74450
+ const isDefaultStatusFilter = selectedLineStatusFilters.length === LINE_STATUS_FILTER_OPTIONS.length;
74451
+ const selectedLineStatusSet = React125__default.useMemo(
74452
+ () => new Set(selectedLineStatusFilters),
74453
+ [selectedLineStatusFilters]
74454
+ );
74455
+ const selectedFactoryFilterSet = React125__default.useMemo(
74456
+ () => new Set(effectiveSelectedFactoryFilters),
74457
+ [effectiveSelectedFactoryFilters]
74458
+ );
74459
+ const isDefaultFactoryFilter = React125__default.useMemo(
74460
+ () => factoryFilterOptions.length === 0 || effectiveSelectedFactoryFilters.length === factoryFilterOptions.length && factoryFilterOptions.every((option) => selectedFactoryFilterSet.has(option.id)),
74461
+ [effectiveSelectedFactoryFilters.length, factoryFilterOptions, selectedFactoryFilterSet]
74462
+ );
74016
74463
  const getShiftIcon2 = (shiftId) => {
74017
74464
  const shiftNameLower = getShiftNameById(shiftId, configuredTimezone, shiftConfig).toLowerCase();
74018
74465
  if (shiftNameLower.includes("day") || shiftNameLower.includes("morning") || shiftId === 0) {
@@ -74061,16 +74508,77 @@ var KPIsOverviewView = ({
74061
74508
  },
74062
74509
  key
74063
74510
  );
74511
+ const statusMatchesFilters = React125__default.useCallback((status) => {
74512
+ if (isDefaultStatusFilter) return true;
74513
+ if (!status) return false;
74514
+ return selectedLineStatusSet.has(status);
74515
+ }, [isDefaultStatusFilter, selectedLineStatusSet]);
74516
+ const factoryMatchesFilters = React125__default.useCallback((line) => {
74517
+ if (isDefaultFactoryFilter) return true;
74518
+ return selectedFactoryFilterSet.has(line.factory_id || "unknown-factory");
74519
+ }, [isDefaultFactoryFilter, selectedFactoryFilterSet]);
74520
+ const getLineStatus = React125__default.useCallback((line) => {
74521
+ const kpis = getLineCardKpis(line);
74522
+ return getKpiSignalStatus(kpis?.lineSignal, efficiencyLegend);
74523
+ }, [efficiencyLegend, getLineCardKpis]);
74524
+ const getGroupStatus = React125__default.useCallback((cardLines) => {
74525
+ const kpis = getAggregateCardKpis(cardLines);
74526
+ return getKpiSignalStatus(kpis?.lineSignal, efficiencyLegend);
74527
+ }, [efficiencyLegend, getAggregateCardKpis]);
74528
+ const getLineSortEfficiency = React125__default.useCallback((line) => {
74529
+ const value = getLineCardKpis(line)?.efficiency?.value;
74530
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
74531
+ }, [getLineCardKpis]);
74532
+ const getGroupSortEfficiency = React125__default.useCallback((cardLines) => {
74533
+ const value = getAggregateCardKpis(cardLines)?.efficiency?.value;
74534
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
74535
+ }, [getAggregateCardKpis]);
74536
+ const compareEfficiencyValues = React125__default.useCallback((leftValue, rightValue) => {
74537
+ if (leftValue === null && rightValue === null) return 0;
74538
+ if (leftValue === null) return 1;
74539
+ if (rightValue === null) return -1;
74540
+ return efficiencySortDirection === "asc" ? leftValue - rightValue : rightValue - leftValue;
74541
+ }, [efficiencySortDirection]);
74542
+ const sortLineCollection = React125__default.useCallback(
74543
+ (cardLines) => [...cardLines].sort((left, right) => {
74544
+ const efficiencyComparison = compareEfficiencyValues(getLineSortEfficiency(left), getLineSortEfficiency(right));
74545
+ if (efficiencyComparison !== 0) return efficiencyComparison;
74546
+ return (left.line_name || "").localeCompare(right.line_name || "", void 0, { sensitivity: "base", numeric: true });
74547
+ }),
74548
+ [compareEfficiencyValues, getLineSortEfficiency]
74549
+ );
74550
+ const sortGroupCollection = React125__default.useCallback(
74551
+ (groups) => [...groups].sort((left, right) => {
74552
+ const leftLines = left.lines.filter(factoryMatchesFilters);
74553
+ const rightLines = right.lines.filter(factoryMatchesFilters);
74554
+ const efficiencyComparison = compareEfficiencyValues(getGroupSortEfficiency(leftLines), getGroupSortEfficiency(rightLines));
74555
+ if (efficiencyComparison !== 0) return efficiencyComparison;
74556
+ return (left.factoryName || left.areaName || "").localeCompare(right.factoryName || right.areaName || "", void 0, { sensitivity: "base", numeric: true });
74557
+ }),
74558
+ [compareEfficiencyValues, factoryMatchesFilters, getGroupSortEfficiency]
74559
+ );
74560
+ const filterLineCollection = React125__default.useCallback(
74561
+ (cardLines) => sortLineCollection(cardLines.filter((line) => factoryMatchesFilters(line) && statusMatchesFilters(getLineStatus(line)))),
74562
+ [factoryMatchesFilters, getLineStatus, sortLineCollection, statusMatchesFilters]
74563
+ );
74564
+ const filterGroupCollection = React125__default.useCallback(
74565
+ (groups) => sortGroupCollection(groups.filter((group) => {
74566
+ const factoryFilteredLines = group.lines.filter(factoryMatchesFilters);
74567
+ if (factoryFilteredLines.length === 0) return false;
74568
+ return statusMatchesFilters(getGroupStatus(factoryFilteredLines));
74569
+ })),
74570
+ [factoryMatchesFilters, getGroupStatus, sortGroupCollection, statusMatchesFilters]
74571
+ );
74064
74572
  const renderTodayCards = () => {
74065
74573
  if (!kpiLineHierarchy.showFactoryLevel) {
74066
- return linesForView.map(renderLineCard);
74574
+ return filterLineCollection(linesForView).map(renderLineCard);
74067
74575
  }
74068
74576
  if (selectedFactoryNode && selectedFactoryAreaNode) {
74069
- return selectedFactoryAreaNode.lines.map(renderLineCard);
74577
+ return filterLineCollection(selectedFactoryAreaNode.lines).map(renderLineCard);
74070
74578
  }
74071
74579
  if (selectedFactoryNode) {
74072
74580
  return [
74073
- ...selectedFactoryNode.areas.map(
74581
+ ...filterGroupCollection(selectedFactoryNode.areas).map(
74074
74582
  (area) => renderGroupCard({
74075
74583
  key: `area-${area.id}`,
74076
74584
  title: area.areaName,
@@ -74079,10 +74587,10 @@ var KPIsOverviewView = ({
74079
74587
  onClick: () => navigateTodayHierarchy(selectedFactoryNode.id, area.id)
74080
74588
  })
74081
74589
  ),
74082
- ...selectedFactoryNode.ungroupedLines.map(renderLineCard)
74590
+ ...filterLineCollection(selectedFactoryNode.ungroupedLines).map(renderLineCard)
74083
74591
  ];
74084
74592
  }
74085
- return kpiLineHierarchy.factories.map(
74593
+ return filterGroupCollection(kpiLineHierarchy.factories).map(
74086
74594
  (factory) => renderGroupCard({
74087
74595
  key: `factory-${factory.id}`,
74088
74596
  title: factory.factoryName,
@@ -74092,6 +74600,18 @@ var KPIsOverviewView = ({
74092
74600
  })
74093
74601
  );
74094
74602
  };
74603
+ const renderTodayUnitsByFactory = () => kpiLineHierarchy.factories.flatMap((factory) => [
74604
+ ...filterGroupCollection(factory.areas).map(
74605
+ (area) => renderGroupCard({
74606
+ key: `unit-area-${factory.id}-${area.id}`,
74607
+ title: area.areaName,
74608
+ subtitle: `${area.lines.length} ${area.lines.length === 1 ? "line" : "lines"}`,
74609
+ lines: area.lines,
74610
+ onClick: () => navigateTodayHierarchy(factory.id, area.id)
74611
+ })
74612
+ ),
74613
+ ...filterLineCollection(factory.ungroupedLines).map(renderLineCard)
74614
+ ]);
74095
74615
  if (loading || isShiftConfigLoading) {
74096
74616
  return /* @__PURE__ */ jsx(LoadingPage, { message: "Loading production lines..." });
74097
74617
  }
@@ -74305,65 +74825,237 @@ var KPIsOverviewView = ({
74305
74825
  )
74306
74826
  ] }),
74307
74827
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
74308
- activeTab === "leaderboard" && timeRange === "today" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
74309
- /* @__PURE__ */ jsx(
74310
- MonthlyRangeFilter_default,
74828
+ activeTab === "leaderboard" && timeRange === "today" && /* @__PURE__ */ jsx(
74829
+ MonthlyRangeFilter_default,
74830
+ {
74831
+ month: parseDateKeyToDate(effectiveLeaderboardDate).getMonth(),
74832
+ year: parseDateKeyToDate(effectiveLeaderboardDate).getFullYear(),
74833
+ timezone: configuredTimezone,
74834
+ value: {
74835
+ startKey: effectiveLeaderboardDate,
74836
+ endKey: effectiveLeaderboardDate
74837
+ },
74838
+ onChange: (range) => {
74839
+ updateLeaderboardDate(range.startKey);
74840
+ },
74841
+ showLabel: false,
74842
+ singleDateOnly: true
74843
+ }
74844
+ ),
74845
+ (activeTab === "today" || activeTab === "leaderboard" && timeRange === "today") && /* @__PURE__ */ jsxs("div", { className: "relative", children: [
74846
+ /* @__PURE__ */ jsxs(
74847
+ "button",
74311
74848
  {
74312
- month: parseDateKeyToDate(effectiveLeaderboardDate).getMonth(),
74313
- year: parseDateKeyToDate(effectiveLeaderboardDate).getFullYear(),
74314
- timezone: configuredTimezone,
74315
- value: {
74316
- startKey: effectiveLeaderboardDate,
74317
- endKey: effectiveLeaderboardDate
74849
+ ref: filterButtonRef,
74850
+ type: "button",
74851
+ onClick: () => {
74852
+ const nextOpen = !isFilterOpen;
74853
+ if (nextOpen) {
74854
+ trackCoreEvent("Lines Overview Filter Menu Opened", {
74855
+ surface: "lines_overview",
74856
+ action: "open_filter_menu",
74857
+ control_clicked: "filters",
74858
+ source: "top_right_controls",
74859
+ active_tab: activeTab,
74860
+ selected_status_filters: selectedLineStatusFilters,
74861
+ selected_factory_filters: effectiveSelectedFactoryFilters,
74862
+ selected_view_level: todayViewLevel,
74863
+ selected_sort_direction: efficiencySortDirection
74864
+ });
74865
+ }
74866
+ setIsFilterOpen(nextOpen);
74867
+ setIsViewsOpen(false);
74868
+ setIsSortOpen(false);
74869
+ },
74870
+ 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"}`,
74871
+ children: [
74872
+ /* @__PURE__ */ jsx(Filter, { className: "w-4 h-4" }),
74873
+ /* @__PURE__ */ jsx("span", { children: "Filters" }),
74874
+ 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 }),
74875
+ /* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 ml-1 transition-transform ${isFilterOpen ? "rotate-180" : ""}` })
74876
+ ]
74877
+ }
74878
+ ),
74879
+ isFilterOpen && /* @__PURE__ */ jsxs("div", { ref: filterRef, className: "absolute right-0 top-full mt-2 w-72 max-h-[calc(100vh-12rem)] overflow-y-auto bg-white rounded-xl shadow-xl border border-gray-100 p-4 z-50", children: [
74880
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
74881
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Filters" }),
74882
+ activeFiltersCount > 0 && /* @__PURE__ */ jsx(
74883
+ "button",
74884
+ {
74885
+ type: "button",
74886
+ onClick: clearFilters,
74887
+ className: "text-xs text-red-600 hover:text-red-700 font-medium",
74888
+ children: "Clear all"
74889
+ }
74890
+ )
74891
+ ] }),
74892
+ activeTab === "today" ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
74893
+ factoryFilterOptions.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
74894
+ /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Filter by factory" }),
74895
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: factoryFilterOptions.map((option) => {
74896
+ const isSelected = selectedFactoryFilterSet.has(option.id);
74897
+ return /* @__PURE__ */ jsxs(
74898
+ "button",
74899
+ {
74900
+ type: "button",
74901
+ onClick: () => handleFactoryFilterToggle(option.id),
74902
+ className: `flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors ${isSelected ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
74903
+ children: [
74904
+ /* @__PURE__ */ jsx("span", { className: `flex h-4 w-4 flex-shrink-0 items-center justify-center rounded border ${isSelected ? "border-blue-500 bg-blue-500 text-white" : "border-gray-300 bg-white"}`, children: isSelected && /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) }),
74905
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: option.label })
74906
+ ]
74907
+ },
74908
+ option.id
74909
+ );
74910
+ }) })
74911
+ ] }),
74912
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
74913
+ /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Filter by status" }),
74914
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: LINE_STATUS_FILTER_OPTIONS.map((option) => {
74915
+ const isSelected = selectedLineStatusSet.has(option.id);
74916
+ return /* @__PURE__ */ jsxs(
74917
+ "button",
74918
+ {
74919
+ type: "button",
74920
+ onClick: () => handleLineStatusFilterToggle(option.id),
74921
+ className: `flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors ${isSelected ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
74922
+ children: [
74923
+ /* @__PURE__ */ jsx("span", { className: `flex h-4 w-4 items-center justify-center rounded border ${isSelected ? "border-blue-500 bg-blue-500 text-white" : "border-gray-300 bg-white"}`, children: isSelected && /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) }),
74924
+ option.label
74925
+ ]
74926
+ },
74927
+ option.id
74928
+ );
74929
+ }) })
74930
+ ] })
74931
+ ] }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
74932
+ /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Shift" }),
74933
+ /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
74934
+ "select",
74935
+ {
74936
+ "aria-label": "Leaderboard shift",
74937
+ value: effectiveLeaderboardShiftId,
74938
+ onChange: (e) => updateLeaderboardShiftId(Number(e.target.value)),
74939
+ 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",
74940
+ 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` },
74941
+ children: leaderboardShiftOptions.map((shiftOption) => /* @__PURE__ */ jsx("option", { value: shiftOption.id, children: shiftOption.label }, shiftOption.id))
74942
+ }
74943
+ ) })
74944
+ ] }) })
74945
+ ] })
74946
+ ] }),
74947
+ activeTab === "today" && kpiLineHierarchy.showFactoryLevel && /* @__PURE__ */ jsxs("div", { className: "relative", children: [
74948
+ /* @__PURE__ */ jsxs(
74949
+ "button",
74950
+ {
74951
+ ref: viewsButtonRef,
74952
+ type: "button",
74953
+ onClick: () => {
74954
+ const nextOpen = !isViewsOpen;
74955
+ if (nextOpen) {
74956
+ trackCoreEvent("Lines Overview Views Menu Opened", {
74957
+ surface: "lines_overview",
74958
+ action: "open_views_menu",
74959
+ control_clicked: "views",
74960
+ source: "top_right_controls",
74961
+ selected_view_level: todayViewLevel,
74962
+ selected_factory_filters: effectiveSelectedFactoryFilters,
74963
+ selected_status_filters: selectedLineStatusFilters,
74964
+ selected_sort_direction: efficiencySortDirection
74965
+ });
74966
+ }
74967
+ setIsViewsOpen(nextOpen);
74968
+ setIsFilterOpen(false);
74969
+ setIsSortOpen(false);
74318
74970
  },
74319
- onChange: (range) => {
74320
- updateLeaderboardDate(range.startKey);
74971
+ className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isViewsOpen ? "bg-blue-50 border-blue-200 text-blue-700" : "bg-white border-gray-200 text-gray-700 hover:bg-gray-50"}`,
74972
+ children: [
74973
+ /* @__PURE__ */ jsx(Layers, { className: "w-4 h-4" }),
74974
+ /* @__PURE__ */ jsx("span", { children: "Views" }),
74975
+ /* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 ml-1 transition-transform ${isViewsOpen ? "rotate-180" : ""}` })
74976
+ ]
74977
+ }
74978
+ ),
74979
+ isViewsOpen && /* @__PURE__ */ jsxs("div", { ref: viewsRef, 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: [
74980
+ /* @__PURE__ */ jsx("div", { className: "mb-3", children: /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Views" }) }),
74981
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: [
74982
+ { id: "factory", label: "Factory level" },
74983
+ { id: "units", label: "Area level" }
74984
+ ].map((option) => {
74985
+ const isSelected = todayViewLevel === option.id;
74986
+ return /* @__PURE__ */ jsxs(
74987
+ "button",
74988
+ {
74989
+ type: "button",
74990
+ onClick: () => handleTodayViewLevelChange(option.id),
74991
+ className: `flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors ${isSelected ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
74992
+ children: [
74993
+ /* @__PURE__ */ jsx("span", { className: `flex h-4 w-4 items-center justify-center rounded border ${isSelected ? "border-blue-500 bg-blue-500 text-white" : "border-gray-300 bg-white"}`, children: isSelected && /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) }),
74994
+ option.label
74995
+ ]
74996
+ },
74997
+ option.id
74998
+ );
74999
+ }) })
75000
+ ] })
75001
+ ] }),
75002
+ activeTab === "today" && /* @__PURE__ */ jsxs("div", { className: "relative", children: [
75003
+ /* @__PURE__ */ jsxs(
75004
+ "button",
75005
+ {
75006
+ ref: sortButtonRef,
75007
+ type: "button",
75008
+ onClick: () => {
75009
+ const nextOpen = !isSortOpen;
75010
+ if (nextOpen) {
75011
+ trackCoreEvent("Lines Overview Sort Menu Opened", {
75012
+ surface: "lines_overview",
75013
+ action: "open_sort_menu",
75014
+ control_clicked: "sort",
75015
+ source: "top_right_controls",
75016
+ sort_metric: "efficiency",
75017
+ selected_sort_direction: efficiencySortDirection,
75018
+ selected_factory_filters: effectiveSelectedFactoryFilters,
75019
+ selected_status_filters: selectedLineStatusFilters,
75020
+ selected_view_level: todayViewLevel
75021
+ });
75022
+ }
75023
+ setIsSortOpen(nextOpen);
75024
+ setIsFilterOpen(false);
75025
+ setIsViewsOpen(false);
74321
75026
  },
74322
- showLabel: false,
74323
- singleDateOnly: true
75027
+ className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isSortOpen || activeSortCount > 0 ? "bg-blue-50 border-blue-200 text-blue-700" : "bg-white border-gray-200 text-gray-700 hover:bg-gray-50"}`,
75028
+ children: [
75029
+ /* @__PURE__ */ jsx(ArrowUpDown, { className: "w-4 h-4" }),
75030
+ /* @__PURE__ */ jsx("span", { children: "Sort" }),
75031
+ activeSortCount > 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: activeSortCount }),
75032
+ /* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 ml-1 transition-transform ${isSortOpen ? "rotate-180" : ""}` })
75033
+ ]
74324
75034
  }
74325
75035
  ),
74326
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
74327
- /* @__PURE__ */ jsxs(
74328
- "button",
74329
- {
74330
- ref: filterButtonRef,
74331
- onClick: () => setIsFilterOpen(!isFilterOpen),
74332
- 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"}`,
74333
- children: [
74334
- /* @__PURE__ */ jsx(Filter, { className: "w-4 h-4" }),
74335
- /* @__PURE__ */ jsx("span", { children: "Filters" }),
74336
- 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 }),
74337
- /* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 ml-1 transition-transform ${isFilterOpen ? "rotate-180" : ""}` })
74338
- ]
74339
- }
74340
- ),
74341
- 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: [
74342
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
74343
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Filter View" }),
74344
- activeFiltersCount > 0 && /* @__PURE__ */ jsx(
75036
+ isSortOpen && /* @__PURE__ */ jsxs("div", { ref: sortRef, 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: [
75037
+ /* @__PURE__ */ jsx("div", { className: "mb-3", children: /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Sort" }) }),
75038
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
75039
+ /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Efficiency" }),
75040
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: [
75041
+ { id: "desc", label: "Highest to lowest" },
75042
+ { id: "asc", label: "Lowest to highest" }
75043
+ ].map((option) => {
75044
+ const isSelected = efficiencySortDirection === option.id;
75045
+ return /* @__PURE__ */ jsxs(
74345
75046
  "button",
74346
75047
  {
74347
- onClick: clearFilters,
74348
- className: "text-xs text-red-600 hover:text-red-700 font-medium",
74349
- children: "Clear all"
74350
- }
74351
- )
74352
- ] }),
74353
- /* @__PURE__ */ jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
74354
- /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Shift" }),
74355
- /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
74356
- "select",
74357
- {
74358
- "aria-label": "Leaderboard shift",
74359
- value: effectiveLeaderboardShiftId,
74360
- onChange: (e) => updateLeaderboardShiftId(Number(e.target.value)),
74361
- 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",
74362
- 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` },
74363
- children: leaderboardShiftOptions.map((shiftOption) => /* @__PURE__ */ jsx("option", { value: shiftOption.id, children: shiftOption.label }, shiftOption.id))
74364
- }
74365
- ) })
74366
- ] }) })
75048
+ type: "button",
75049
+ onClick: () => handleEfficiencySortChange(option.id),
75050
+ className: `flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors ${isSelected ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
75051
+ children: [
75052
+ /* @__PURE__ */ jsx("span", { className: `flex h-4 w-4 items-center justify-center rounded border ${isSelected ? "border-blue-500 bg-blue-500 text-white" : "border-gray-300 bg-white"}`, children: isSelected && /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) }),
75053
+ option.label
75054
+ ]
75055
+ },
75056
+ option.id
75057
+ );
75058
+ }) })
74367
75059
  ] })
74368
75060
  ] })
74369
75061
  ] }),
@@ -74384,7 +75076,7 @@ var KPIsOverviewView = ({
74384
75076
  ] })
74385
75077
  ] })
74386
75078
  ] }) }),
74387
- /* @__PURE__ */ jsx("main", { className: `flex-1 p-3 sm:p-4 md:p-6 bg-slate-50 ${activeTab === "leaderboard" ? "overflow-hidden flex flex-col" : "overflow-y-auto"}`, children: activeTab === "today" ? /* @__PURE__ */ jsxs("div", { className: "space-y-3 sm:space-y-4", children: [
75079
+ /* @__PURE__ */ jsx("main", { className: `flex-1 p-3 sm:p-4 md:p-6 bg-slate-50 ${activeTab === "leaderboard" ? "overflow-hidden flex flex-col" : "overflow-y-auto"}`, children: activeTab === "today" ? /* @__PURE__ */ jsx("div", { className: "space-y-3 sm:space-y-4", children: todayViewLevel === "units" && kpiLineHierarchy.showFactoryLevel ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3 sm:gap-4 md:gap-6", children: renderTodayUnitsByFactory() }) : /* @__PURE__ */ jsxs(Fragment, { children: [
74388
75080
  kpiLineHierarchy.showFactoryLevel && selectedFactoryNode && /* @__PURE__ */ jsxs("nav", { className: "flex flex-wrap items-center gap-2 text-sm", "aria-label": "KPI hierarchy", children: [
74389
75081
  /* @__PURE__ */ jsx(
74390
75082
  "button",
@@ -74411,7 +75103,7 @@ var KPIsOverviewView = ({
74411
75103
  ] })
74412
75104
  ] }),
74413
75105
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3 sm:gap-4 md:gap-6", children: renderTodayCards() })
74414
- ] }) : showLeaderboardLoader ? /* @__PURE__ */ jsx("div", { className: "flex-1 flex flex-col items-center justify-center bg-white rounded-2xl border border-gray-100 shadow-sm m-2 sm:m-4", children: /* @__PURE__ */ jsx(
75106
+ ] }) }) : showLeaderboardLoader ? /* @__PURE__ */ jsx("div", { className: "flex-1 flex flex-col items-center justify-center bg-white rounded-2xl border border-gray-100 shadow-sm m-2 sm:m-4", children: /* @__PURE__ */ jsx(
74415
75107
  OptifyeLogoLoader_default,
74416
75108
  {
74417
75109
  size: "lg",
@@ -74723,7 +75415,7 @@ var LeaderboardDetailView = memo$1(({
74723
75415
  return () => document.removeEventListener("mousedown", handleClickOutside);
74724
75416
  }, []);
74725
75417
  const [isMobile, setIsMobile] = useState(false);
74726
- React148__default.useEffect(() => {
75418
+ React125__default.useEffect(() => {
74727
75419
  const checkMobile = () => setIsMobile(window.innerWidth < 640);
74728
75420
  checkMobile();
74729
75421
  window.addEventListener("resize", checkMobile);
@@ -75548,7 +76240,7 @@ var LeaderboardDetailView = memo$1(({
75548
76240
  ] }) }),
75549
76241
  isFilterOpen && /* @__PURE__ */ jsxs("div", { ref: filterRef, className: "absolute right-3 sm:right-4 md:right-5 lg:right-6 top-full mt-2 w-72 bg-white rounded-xl shadow-xl border border-gray-100 p-4 z-50", children: [
75550
76242
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
75551
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Filter View" }),
76243
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Sort" }),
75552
76244
  activeFiltersCount > 0 && /* @__PURE__ */ jsx(
75553
76245
  "button",
75554
76246
  {
@@ -75673,9 +76365,9 @@ var LeaderboardDetailView = memo$1(({
75673
76365
  ref: mobileFilterButtonRef,
75674
76366
  onClick: () => setIsFilterOpen(!isFilterOpen),
75675
76367
  className: `p-2 rounded-full transition-colors relative ${isFilterOpen || activeFiltersCount > 0 ? "bg-blue-50" : "active:bg-gray-100"}`,
75676
- "aria-label": "Open filters",
76368
+ "aria-label": "Open sort",
75677
76369
  children: [
75678
- /* @__PURE__ */ jsx(Filter, { className: `w-5 h-5 ${activeFiltersCount > 0 ? "text-blue-600" : "text-gray-700"}` }),
76370
+ /* @__PURE__ */ jsx(ArrowUpDown, { className: `w-5 h-5 ${activeFiltersCount > 0 ? "text-blue-600" : "text-gray-700"}` }),
75679
76371
  activeFiltersCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 flex items-center justify-center w-4 h-4 bg-blue-600 text-white text-[10px] rounded-full font-bold", children: activeFiltersCount })
75680
76372
  ]
75681
76373
  }
@@ -75748,8 +76440,8 @@ var LeaderboardDetailView = memo$1(({
75748
76440
  onClick: () => setIsFilterOpen(!isFilterOpen),
75749
76441
  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"}`,
75750
76442
  children: [
75751
- /* @__PURE__ */ jsx(Filter, { className: "w-4 h-4" }),
75752
- /* @__PURE__ */ jsx("span", { children: "Filters" }),
76443
+ /* @__PURE__ */ jsx(ArrowUpDown, { className: "w-4 h-4" }),
76444
+ /* @__PURE__ */ jsx("span", { children: "Sort" }),
75753
76445
  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 }),
75754
76446
  /* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 ml-1 transition-transform ${isFilterOpen ? "rotate-180" : ""}` })
75755
76447
  ]
@@ -78773,7 +79465,7 @@ var ShiftsView = ({
78773
79465
  ] })
78774
79466
  ] });
78775
79467
  };
78776
- var AuthenticatedShiftsView = withAuth(React148__default.memo(ShiftsView));
79468
+ var AuthenticatedShiftsView = withAuth(React125__default.memo(ShiftsView));
78777
79469
  var ShiftsView_default = ShiftsView;
78778
79470
 
78779
79471
  // src/views/TargetsView.utils.ts
@@ -80640,7 +81332,7 @@ var TargetsView = ({
80640
81332
  };
80641
81333
  var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
80642
81334
  var TargetsView_default = TargetsViewWithDisplayNames;
80643
- var AuthenticatedTargetsView = withAuth(React148__default.memo(TargetsViewWithDisplayNames));
81335
+ var AuthenticatedTargetsView = withAuth(React125__default.memo(TargetsViewWithDisplayNames));
80644
81336
  function useTimezone(options = {}) {
80645
81337
  const dashboardConfig = useDashboardConfig();
80646
81338
  const workspaceConfig = useWorkspaceConfig();
@@ -80805,13 +81497,13 @@ var WorkspaceHourSummaryPanel = ({
80805
81497
  }) => {
80806
81498
  const { data, isLoading, error, summarize, reset } = useWorkspaceHourSummary();
80807
81499
  const selectedKey = selectedHour ? `${selectedHour.source}:${selectedHour.hourIndex}:${date}:${shiftId}` : "none";
80808
- const autoSummaryKeyRef = React148__default.useRef(null);
80809
- React148__default.useEffect(() => {
81500
+ const autoSummaryKeyRef = React125__default.useRef(null);
81501
+ React125__default.useEffect(() => {
80810
81502
  reset();
80811
81503
  autoSummaryKeyRef.current = null;
80812
81504
  }, [reset, selectedKey]);
80813
81505
  const canSummarize = Boolean(workspaceId && companyId && date && shiftId !== null && shiftId !== void 0);
80814
- React148__default.useEffect(() => {
81506
+ React125__default.useEffect(() => {
80815
81507
  if (!selectedHour || !canSummarize || !companyId || !date || shiftId === null || shiftId === void 0) {
80816
81508
  return;
80817
81509
  }
@@ -82542,7 +83234,8 @@ var WorkspaceDetailView = ({
82542
83234
  selectedHourIndex: isWorkspaceHourAiSummaryEnabled ? selectedHour?.source === "output" ? selectedHour.hourIndex : aiSummaryHour?.hourIndex ?? null : null,
82543
83235
  onHourClick: isWorkspaceHourAiSummaryEnabled ? handleOutputHourSelect : void 0,
82544
83236
  onWatchClipsClick: handleWatchClipsFromChart,
82545
- onAiSummaryClick: isWorkspaceHourAiSummaryEnabled ? handleAiSummaryClick : void 0
83237
+ onAiSummaryClick: isWorkspaceHourAiSummaryEnabled ? handleAiSummaryClick : void 0,
83238
+ onSelectSku: setSelectedSkuId
82546
83239
  }
82547
83240
  )
82548
83241
  }
@@ -82715,7 +83408,8 @@ var WorkspaceDetailView = ({
82715
83408
  selectedHourIndex: isWorkspaceHourAiSummaryEnabled ? selectedHour?.source === "output" ? selectedHour.hourIndex : aiSummaryHour?.hourIndex ?? null : null,
82716
83409
  onHourClick: isWorkspaceHourAiSummaryEnabled ? handleOutputHourSelect : void 0,
82717
83410
  onWatchClipsClick: handleWatchClipsFromChart,
82718
- onAiSummaryClick: isWorkspaceHourAiSummaryEnabled ? handleAiSummaryClick : void 0
83411
+ onAiSummaryClick: isWorkspaceHourAiSummaryEnabled ? handleAiSummaryClick : void 0,
83412
+ onSelectSku: setSelectedSkuId
82719
83413
  }
82720
83414
  ) })
82721
83415
  ]
@@ -84502,7 +85196,7 @@ function BottleneckClipsView({
84502
85196
  ) })
84503
85197
  ] }) });
84504
85198
  }
84505
- var AuthenticatedBottleneckClipsView = withAuth(React148__default.memo(BottleneckClipsView));
85199
+ var AuthenticatedBottleneckClipsView = withAuth(React125__default.memo(BottleneckClipsView));
84506
85200
  var BottleneckClipsView_default = BottleneckClipsView;
84507
85201
 
84508
85202
  // src/lib/services/ticketService.ts
@@ -85345,7 +86039,7 @@ Please ensure:
85345
86039
  )
85346
86040
  ] });
85347
86041
  }
85348
- var AuthenticatedTicketsView = withAuth(React148__default.memo(TicketsView));
86042
+ var AuthenticatedTicketsView = withAuth(React125__default.memo(TicketsView));
85349
86043
  var TicketsView_default = TicketsView;
85350
86044
 
85351
86045
  // src/lib/utils/improvementDisplay.ts
@@ -86316,7 +87010,7 @@ var ImprovementCenterView = () => {
86316
87010
  setSelectedMemberId("all");
86317
87011
  }
86318
87012
  }, [memberOptions, selectedMemberId]);
86319
- const getRecommendationDisplayMetadata = React148__default.useCallback((rec) => {
87013
+ const getRecommendationDisplayMetadata = React125__default.useCallback((rec) => {
86320
87014
  const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
86321
87015
  return getImprovementDisplayMetadata({
86322
87016
  location: rec.location,
@@ -86790,7 +87484,7 @@ var ThreadSidebar = ({
86790
87484
  ] }) })
86791
87485
  ] });
86792
87486
  };
86793
- var ProfilePicture = React148__default.memo(({
87487
+ var ProfilePicture = React125__default.memo(({
86794
87488
  alt = "Axel",
86795
87489
  className = "",
86796
87490
  size = "md",
@@ -89350,7 +90044,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
89350
90044
  ] }),
89351
90045
  /* @__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" }) })
89352
90046
  ] }, index)) });
89353
- var OperationsOverviewHeader = React148__default.memo(({
90047
+ var OperationsOverviewHeader = React125__default.memo(({
89354
90048
  dateRange,
89355
90049
  displayDateRange,
89356
90050
  trendMode,
@@ -89371,65 +90065,65 @@ var OperationsOverviewHeader = React148__default.memo(({
89371
90065
  bumpRenderCounter();
89372
90066
  const subtitleRange = displayDateRange || dateRange;
89373
90067
  const showLiveShiftMeta = isLiveScope && trendMode !== "all";
89374
- const liveShiftLabel = React148__default.useMemo(
90068
+ const liveShiftLabel = React125__default.useMemo(
89375
90069
  () => normalizeShiftLabel(liveShiftName, trendMode),
89376
90070
  [liveShiftName, trendMode]
89377
90071
  );
89378
- const liveShiftIcon = React148__default.useMemo(
90072
+ const liveShiftIcon = React125__default.useMemo(
89379
90073
  () => getShiftIcon(liveShiftName, trendMode),
89380
90074
  [liveShiftName, trendMode]
89381
90075
  );
89382
- const [isFilterOpen, setIsFilterOpen] = React148__default.useState(false);
89383
- const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React148__default.useState(false);
89384
- const filterRef = React148__default.useRef(null);
89385
- const filterButtonRef = React148__default.useRef(null);
89386
- const mobileFilterButtonRef = React148__default.useRef(null);
89387
- const linesDropdownRef = React148__default.useRef(null);
89388
- const mobileSubtitle = React148__default.useMemo(() => {
90076
+ const [isFilterOpen, setIsFilterOpen] = React125__default.useState(false);
90077
+ const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React125__default.useState(false);
90078
+ const filterRef = React125__default.useRef(null);
90079
+ const filterButtonRef = React125__default.useRef(null);
90080
+ const mobileFilterButtonRef = React125__default.useRef(null);
90081
+ const linesDropdownRef = React125__default.useRef(null);
90082
+ const mobileSubtitle = React125__default.useMemo(() => {
89389
90083
  if (subtitleRange.startKey === subtitleRange.endKey) {
89390
90084
  return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
89391
90085
  }
89392
90086
  return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
89393
90087
  }, [subtitleRange.endKey, subtitleRange.startKey]);
89394
- const desktopSubtitle = React148__default.useMemo(() => {
90088
+ const desktopSubtitle = React125__default.useMemo(() => {
89395
90089
  if (subtitleRange.startKey === subtitleRange.endKey) {
89396
90090
  return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
89397
90091
  }
89398
90092
  return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
89399
90093
  }, [subtitleRange.endKey, subtitleRange.startKey]);
89400
- const availableLineIds = React148__default.useMemo(
90094
+ const availableLineIds = React125__default.useMemo(
89401
90095
  () => lineOptions.map((line) => line.id),
89402
90096
  [lineOptions]
89403
90097
  );
89404
- const selectedLineIdSet = React148__default.useMemo(
90098
+ const selectedLineIdSet = React125__default.useMemo(
89405
90099
  () => new Set(selectedLineIds),
89406
90100
  [selectedLineIds]
89407
90101
  );
89408
- const isAllLinesSelected = React148__default.useMemo(() => {
90102
+ const isAllLinesSelected = React125__default.useMemo(() => {
89409
90103
  if (availableLineIds.length === 0) return true;
89410
90104
  return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
89411
90105
  }, [availableLineIds, selectedLineIdSet]);
89412
- const activeFilterCount = React148__default.useMemo(() => {
90106
+ const activeFilterCount = React125__default.useMemo(() => {
89413
90107
  let count = 0;
89414
90108
  if (trendMode !== "all") count += 1;
89415
90109
  if (selectedSupervisorId !== "all") count += 1;
89416
90110
  if (!isAllLinesSelected) count += 1;
89417
90111
  return count;
89418
90112
  }, [isAllLinesSelected, selectedSupervisorId, trendMode]);
89419
- const handleFilterToggle = React148__default.useCallback(() => {
90113
+ const handleFilterToggle = React125__default.useCallback(() => {
89420
90114
  trackCoreEvent("Operations Overview Filter Toggled", {
89421
90115
  action: !isFilterOpen ? "open" : "close"
89422
90116
  });
89423
90117
  setIsFilterOpen((previous) => !previous);
89424
90118
  }, [isFilterOpen]);
89425
- const handleTrendModeChange = React148__default.useCallback((event) => {
90119
+ const handleTrendModeChange = React125__default.useCallback((event) => {
89426
90120
  const nextMode = event.target.value;
89427
90121
  trackCoreEvent("Operations Overview Shift Filter Changed", {
89428
90122
  shift_mode: nextMode
89429
90123
  });
89430
90124
  onTrendModeChange(nextMode);
89431
90125
  }, [onTrendModeChange]);
89432
- const handleAllLinesToggle = React148__default.useCallback(() => {
90126
+ const handleAllLinesToggle = React125__default.useCallback(() => {
89433
90127
  trackCoreEvent("Operations Overview Line Filter Changed", {
89434
90128
  selected_line_ids: availableLineIds,
89435
90129
  selected_line_count: availableLineIds.length,
@@ -89437,7 +90131,7 @@ var OperationsOverviewHeader = React148__default.memo(({
89437
90131
  });
89438
90132
  onSelectedLineIdsChange(availableLineIds);
89439
90133
  }, [availableLineIds, onSelectedLineIdsChange]);
89440
- const handleSupervisorChange = React148__default.useCallback((event) => {
90134
+ const handleSupervisorChange = React125__default.useCallback((event) => {
89441
90135
  const supervisorId = event.target.value;
89442
90136
  const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
89443
90137
  trackCoreEvent("Operations Overview Supervisor Filter Changed", {
@@ -89448,7 +90142,7 @@ var OperationsOverviewHeader = React148__default.memo(({
89448
90142
  });
89449
90143
  onSelectedSupervisorIdChange(supervisorId);
89450
90144
  }, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
89451
- const handleLineToggle = React148__default.useCallback((lineId) => {
90145
+ const handleLineToggle = React125__default.useCallback((lineId) => {
89452
90146
  const current = new Set(selectedLineIds);
89453
90147
  if (current.has(lineId)) {
89454
90148
  if (current.size <= 1) return;
@@ -89464,13 +90158,13 @@ var OperationsOverviewHeader = React148__default.memo(({
89464
90158
  });
89465
90159
  onSelectedLineIdsChange(next);
89466
90160
  }, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
89467
- const handleClearAllFilters = React148__default.useCallback(() => {
90161
+ const handleClearAllFilters = React125__default.useCallback(() => {
89468
90162
  onTrendModeChange("all");
89469
90163
  onSelectedSupervisorIdChange("all");
89470
90164
  onSelectedLineIdsChange(availableLineIds);
89471
90165
  setIsFilterOpen(false);
89472
90166
  }, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
89473
- React148__default.useEffect(() => {
90167
+ React125__default.useEffect(() => {
89474
90168
  const handleClickOutside = (event) => {
89475
90169
  const target = event.target;
89476
90170
  if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
@@ -89705,12 +90399,12 @@ var OperationsOverviewHeader = React148__default.memo(({
89705
90399
  ] }) });
89706
90400
  });
89707
90401
  OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
89708
- var OverviewSummaryCards = React148__default.memo(({ store }) => {
90402
+ var OverviewSummaryCards = React125__default.memo(({ store }) => {
89709
90403
  bumpRenderCounter();
89710
90404
  const scope = useOperationsOverviewScope(store);
89711
90405
  const snapshot = useOperationsOverviewSnapshot(store);
89712
90406
  const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
89713
- const comparisonLabel = React148__default.useMemo(() => {
90407
+ const comparisonLabel = React125__default.useMemo(() => {
89714
90408
  return formatComparisonWindow({
89715
90409
  currentDayCount: scope.current_range?.day_count ?? null,
89716
90410
  previousDayCount: scope.previous_range?.day_count ?? null,
@@ -89723,27 +90417,27 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
89723
90417
  scope.previous_range?.day_count,
89724
90418
  scope.shift_mode
89725
90419
  ]);
89726
- const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React148__default.useState(false);
89727
- const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React148__default.useState(false);
89728
- const idleContributorsRef = React148__default.useRef(null);
89729
- const plantEfficiencyBadge = React148__default.useMemo(() => {
90420
+ const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React125__default.useState(false);
90421
+ const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React125__default.useState(false);
90422
+ const idleContributorsRef = React125__default.useRef(null);
90423
+ const plantEfficiencyBadge = React125__default.useMemo(() => {
89730
90424
  return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
89731
90425
  positiveIsGood: true,
89732
90426
  formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
89733
90427
  comparisonLabel
89734
90428
  });
89735
90429
  }, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
89736
- const idleBadge = React148__default.useMemo(() => {
90430
+ const idleBadge = React125__default.useMemo(() => {
89737
90431
  return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
89738
90432
  positiveIsGood: false,
89739
90433
  formatter: (value) => formatSignedIdleDuration(value),
89740
90434
  comparisonLabel
89741
90435
  });
89742
90436
  }, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
89743
- const canInspectIdleContributors = React148__default.useMemo(() => {
90437
+ const canInspectIdleContributors = React125__default.useMemo(() => {
89744
90438
  return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
89745
90439
  }, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
89746
- const idleTopContributors = React148__default.useMemo(() => {
90440
+ const idleTopContributors = React125__default.useMemo(() => {
89747
90441
  return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
89748
90442
  workspaceId: item.workspace_id || "",
89749
90443
  workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
@@ -89751,14 +90445,14 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
89751
90445
  avgIdleSeconds: toNumber4(item.avg_idle_seconds)
89752
90446
  })).slice(0, 5);
89753
90447
  }, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
89754
- const showIdleContributorLineNames = React148__default.useMemo(() => {
90448
+ const showIdleContributorLineNames = React125__default.useMemo(() => {
89755
90449
  return (scope.line_count ?? 0) > 1;
89756
90450
  }, [scope.line_count]);
89757
- const closeIdleContributors = React148__default.useCallback(() => {
90451
+ const closeIdleContributors = React125__default.useCallback(() => {
89758
90452
  setIsIdleContributorsOpen(false);
89759
90453
  setIsIdleContributorsPinned(false);
89760
90454
  }, []);
89761
- const handleIdleContributorsToggle = React148__default.useCallback(() => {
90455
+ const handleIdleContributorsToggle = React125__default.useCallback(() => {
89762
90456
  if (!canInspectIdleContributors) return;
89763
90457
  setIsIdleContributorsPinned((previous) => {
89764
90458
  const next = !previous;
@@ -89766,7 +90460,7 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
89766
90460
  return next;
89767
90461
  });
89768
90462
  }, [canInspectIdleContributors]);
89769
- const handleIdleContributorsKeyDown = React148__default.useCallback((event) => {
90463
+ const handleIdleContributorsKeyDown = React125__default.useCallback((event) => {
89770
90464
  if (!canInspectIdleContributors) return;
89771
90465
  if (event.key === "Enter" || event.key === " ") {
89772
90466
  event.preventDefault();
@@ -89778,11 +90472,11 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
89778
90472
  closeIdleContributors();
89779
90473
  }
89780
90474
  }, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
89781
- React148__default.useEffect(() => {
90475
+ React125__default.useEffect(() => {
89782
90476
  setIsIdleContributorsOpen(false);
89783
90477
  setIsIdleContributorsPinned(false);
89784
90478
  }, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
89785
- React148__default.useEffect(() => {
90479
+ React125__default.useEffect(() => {
89786
90480
  if (!isIdleContributorsOpen) return void 0;
89787
90481
  const handleClickOutside = (event) => {
89788
90482
  if (!isIdleContributorsPinned) return;
@@ -89920,7 +90614,7 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
89920
90614
  ] });
89921
90615
  });
89922
90616
  OverviewSummaryCards.displayName = "OverviewSummaryCards";
89923
- var PoorestPerformersCard = React148__default.memo(({
90617
+ var PoorestPerformersCard = React125__default.memo(({
89924
90618
  store,
89925
90619
  supervisorsByLineId,
89926
90620
  onViewAll,
@@ -89929,9 +90623,9 @@ var PoorestPerformersCard = React148__default.memo(({
89929
90623
  bumpRenderCounter();
89930
90624
  const scope = useOperationsOverviewScope(store);
89931
90625
  const snapshot = useOperationsOverviewSnapshot(store);
89932
- const [poorestLineMode, setPoorestLineMode] = React148__default.useState("output");
90626
+ const [poorestLineMode, setPoorestLineMode] = React125__default.useState("output");
89933
90627
  const availableLineModes = scope.available_line_modes;
89934
- React148__default.useEffect(() => {
90628
+ React125__default.useEffect(() => {
89935
90629
  const hasOutput = !!availableLineModes?.has_output;
89936
90630
  const hasUptime = !!availableLineModes?.has_uptime;
89937
90631
  if (hasOutput && !hasUptime && poorestLineMode !== "output") {
@@ -89940,7 +90634,7 @@ var PoorestPerformersCard = React148__default.memo(({
89940
90634
  setPoorestLineMode("uptime");
89941
90635
  }
89942
90636
  }, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
89943
- const comparisonLabel = React148__default.useMemo(() => {
90637
+ const comparisonLabel = React125__default.useMemo(() => {
89944
90638
  return formatComparisonWindow({
89945
90639
  currentDayCount: scope.current_range?.day_count ?? null,
89946
90640
  previousDayCount: scope.previous_range?.day_count ?? null,
@@ -89954,7 +90648,7 @@ var PoorestPerformersCard = React148__default.memo(({
89954
90648
  scope.shift_mode
89955
90649
  ]);
89956
90650
  const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
89957
- const mergedPoorestLines = React148__default.useMemo(() => {
90651
+ const mergedPoorestLines = React125__default.useMemo(() => {
89958
90652
  const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
89959
90653
  const lineRows = [];
89960
90654
  const areaGroups = /* @__PURE__ */ new Map();
@@ -90034,7 +90728,7 @@ var PoorestPerformersCard = React148__default.memo(({
90034
90728
  }, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
90035
90729
  const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
90036
90730
  const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
90037
- const handlePoorestLineModeChange = React148__default.useCallback((mode) => {
90731
+ const handlePoorestLineModeChange = React125__default.useCallback((mode) => {
90038
90732
  trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
90039
90733
  setPoorestLineMode(mode);
90040
90734
  }, []);
@@ -90120,14 +90814,14 @@ var PoorestPerformersCard = React148__default.memo(({
90120
90814
  ] });
90121
90815
  });
90122
90816
  PoorestPerformersCard.displayName = "PoorestPerformersCard";
90123
- var IdleBreakdownCard = React148__default.memo(({
90817
+ var IdleBreakdownCard = React125__default.memo(({
90124
90818
  store,
90125
90819
  scopedLineCount
90126
90820
  }) => {
90127
90821
  bumpRenderCounter();
90128
90822
  const idle = useOperationsOverviewIdle(store);
90129
90823
  const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
90130
- const idleBreakdown = React148__default.useMemo(() => {
90824
+ const idleBreakdown = React125__default.useMemo(() => {
90131
90825
  return idle.data.map((item) => ({
90132
90826
  name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
90133
90827
  reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
@@ -90146,7 +90840,7 @@ var IdleBreakdownCard = React148__default.memo(({
90146
90840
  }))
90147
90841
  })).filter((item) => item.value > 0);
90148
90842
  }, [idle.data]);
90149
- const showIdleModuleNotEnabledState = React148__default.useMemo(() => {
90843
+ const showIdleModuleNotEnabledState = React125__default.useMemo(() => {
90150
90844
  const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
90151
90845
  return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
90152
90846
  }, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
@@ -90167,7 +90861,7 @@ var IdleBreakdownCard = React148__default.memo(({
90167
90861
  ] });
90168
90862
  });
90169
90863
  IdleBreakdownCard.displayName = "IdleBreakdownCard";
90170
- var EfficiencyTrendCard = React148__default.memo(({
90864
+ var EfficiencyTrendCard = React125__default.memo(({
90171
90865
  store,
90172
90866
  dateRange,
90173
90867
  appTimezone,
@@ -90175,14 +90869,14 @@ var EfficiencyTrendCard = React148__default.memo(({
90175
90869
  }) => {
90176
90870
  bumpRenderCounter();
90177
90871
  const trend = useOperationsOverviewTrend(store);
90178
- const currentWeekRange = React148__default.useMemo(
90872
+ const currentWeekRange = React125__default.useMemo(
90179
90873
  () => getCurrentWeekToDateRange(appTimezone),
90180
90874
  [appTimezone]
90181
90875
  );
90182
90876
  const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
90183
90877
  const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
90184
90878
  const isHourlyTrend = trend.data.granularity === "hour";
90185
- const trendData = React148__default.useMemo(() => {
90879
+ const trendData = React125__default.useMemo(() => {
90186
90880
  if (isHourlyTrend) {
90187
90881
  return (trend.data.points || []).map((point, index) => ({
90188
90882
  name: (() => {
@@ -90254,13 +90948,13 @@ var EfficiencyTrendCard = React148__default.memo(({
90254
90948
  };
90255
90949
  });
90256
90950
  }, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
90257
- const trendTooltipLabelFormatter = React148__default.useCallback((label, payload) => {
90951
+ const trendTooltipLabelFormatter = React125__default.useCallback((label, payload) => {
90258
90952
  if (isHourlyTrend) return label;
90259
90953
  const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
90260
90954
  if (!dayOfWeek || typeof label !== "string") return label;
90261
90955
  return `${label} (${dayOfWeek})`;
90262
90956
  }, [isHourlyTrend]);
90263
- const trendXAxisTickFormatter = React148__default.useCallback((value, index) => {
90957
+ const trendXAxisTickFormatter = React125__default.useCallback((value, index) => {
90264
90958
  if (!isHourlyTrend) {
90265
90959
  return typeof value === "string" ? value : String(value ?? "");
90266
90960
  }
@@ -90287,7 +90981,7 @@ var EfficiencyTrendCard = React148__default.memo(({
90287
90981
  ] });
90288
90982
  });
90289
90983
  EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
90290
- var TopImprovementsCard = React148__default.memo(({
90984
+ var TopImprovementsCard = React125__default.memo(({
90291
90985
  store,
90292
90986
  supervisorsByLineId,
90293
90987
  onViewAll,
@@ -90296,7 +90990,7 @@ var TopImprovementsCard = React148__default.memo(({
90296
90990
  bumpRenderCounter();
90297
90991
  const improvements = useOperationsOverviewImprovements(store);
90298
90992
  const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
90299
- const displayImprovements = React148__default.useMemo(() => {
90993
+ const displayImprovements = React125__default.useMemo(() => {
90300
90994
  return improvements.data.map((item) => {
90301
90995
  const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
90302
90996
  return {
@@ -90424,33 +91118,33 @@ var useOperationsOverviewRefresh = ({
90424
91118
  isLiveScope,
90425
91119
  enabled = true
90426
91120
  }) => {
90427
- const lineIdsKey = React148__default.useMemo(() => lineIds.join(","), [lineIds]);
90428
- const scopeSignature = React148__default.useMemo(
91121
+ const lineIdsKey = React125__default.useMemo(() => lineIds.join(","), [lineIds]);
91122
+ const scopeSignature = React125__default.useMemo(
90429
91123
  () => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
90430
91124
  [companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
90431
91125
  );
90432
- const controllersRef = React148__default.useRef({});
90433
- const requestIdsRef = React148__default.useRef({
91126
+ const controllersRef = React125__default.useRef({});
91127
+ const requestIdsRef = React125__default.useRef({
90434
91128
  snapshot: 0,
90435
91129
  trend: 0,
90436
91130
  idle: 0,
90437
91131
  improvements: 0
90438
91132
  });
90439
- const intervalRef = React148__default.useRef(null);
90440
- const isPageActiveRef = React148__default.useRef(true);
90441
- const lastResumeRefreshAtRef = React148__default.useRef(0);
90442
- const abortAll = React148__default.useCallback(() => {
91133
+ const intervalRef = React125__default.useRef(null);
91134
+ const isPageActiveRef = React125__default.useRef(true);
91135
+ const lastResumeRefreshAtRef = React125__default.useRef(0);
91136
+ const abortAll = React125__default.useCallback(() => {
90443
91137
  Object.values(controllersRef.current).forEach((controller) => {
90444
91138
  controller?.abort();
90445
91139
  });
90446
91140
  controllersRef.current = {};
90447
91141
  }, []);
90448
- React148__default.useEffect(() => {
91142
+ React125__default.useEffect(() => {
90449
91143
  return () => {
90450
91144
  abortAll();
90451
91145
  };
90452
91146
  }, [abortAll]);
90453
- const getIsPageActive = React148__default.useCallback(() => {
91147
+ const getIsPageActive = React125__default.useCallback(() => {
90454
91148
  if (typeof document === "undefined") {
90455
91149
  return true;
90456
91150
  }
@@ -90458,7 +91152,7 @@ var useOperationsOverviewRefresh = ({
90458
91152
  const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
90459
91153
  return isVisible && hasFocus;
90460
91154
  }, []);
90461
- const stopPolling = React148__default.useCallback((reason) => {
91155
+ const stopPolling = React125__default.useCallback((reason) => {
90462
91156
  if (intervalRef.current === null) {
90463
91157
  return;
90464
91158
  }
@@ -90466,7 +91160,7 @@ var useOperationsOverviewRefresh = ({
90466
91160
  intervalRef.current = null;
90467
91161
  debugRefreshLog("poll stopped", { reason });
90468
91162
  }, []);
90469
- const runRefresh = React148__default.useCallback(
91163
+ const runRefresh = React125__default.useCallback(
90470
91164
  async (section, begin, onSuccess, onError, request, reason) => {
90471
91165
  if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
90472
91166
  const requestId = requestIdsRef.current[section] + 1;
@@ -90513,7 +91207,7 @@ var useOperationsOverviewRefresh = ({
90513
91207
  },
90514
91208
  [companyId, comparisonStrategy, enabled, endKey, lineIds, startKey, supabase, trendMode]
90515
91209
  );
90516
- const refreshSnapshot = React148__default.useCallback(
91210
+ const refreshSnapshot = React125__default.useCallback(
90517
91211
  async (reason) => {
90518
91212
  await runRefresh(
90519
91213
  "snapshot",
@@ -90545,7 +91239,7 @@ var useOperationsOverviewRefresh = ({
90545
91239
  },
90546
91240
  [companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
90547
91241
  );
90548
- const refreshTrend = React148__default.useCallback(
91242
+ const refreshTrend = React125__default.useCallback(
90549
91243
  async (reason) => {
90550
91244
  await runRefresh(
90551
91245
  "trend",
@@ -90574,7 +91268,7 @@ var useOperationsOverviewRefresh = ({
90574
91268
  },
90575
91269
  [companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
90576
91270
  );
90577
- const refreshIdle = React148__default.useCallback(
91271
+ const refreshIdle = React125__default.useCallback(
90578
91272
  async (reason) => {
90579
91273
  await runRefresh(
90580
91274
  "idle",
@@ -90603,7 +91297,7 @@ var useOperationsOverviewRefresh = ({
90603
91297
  },
90604
91298
  [companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
90605
91299
  );
90606
- const refreshImprovements = React148__default.useCallback(
91300
+ const refreshImprovements = React125__default.useCallback(
90607
91301
  async (reason) => {
90608
91302
  await runRefresh(
90609
91303
  "improvements",
@@ -90633,7 +91327,7 @@ var useOperationsOverviewRefresh = ({
90633
91327
  },
90634
91328
  [companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
90635
91329
  );
90636
- const refreshAll = React148__default.useCallback(
91330
+ const refreshAll = React125__default.useCallback(
90637
91331
  async (reason) => {
90638
91332
  await Promise.allSettled([
90639
91333
  refreshSnapshot(reason),
@@ -90644,7 +91338,7 @@ var useOperationsOverviewRefresh = ({
90644
91338
  },
90645
91339
  [refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
90646
91340
  );
90647
- const startPolling = React148__default.useCallback((reason) => {
91341
+ const startPolling = React125__default.useCallback((reason) => {
90648
91342
  if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
90649
91343
  return;
90650
91344
  }
@@ -90665,7 +91359,7 @@ var useOperationsOverviewRefresh = ({
90665
91359
  }, LIVE_REFRESH_INTERVAL_MS);
90666
91360
  debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
90667
91361
  }, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
90668
- const refreshFromResume = React148__default.useCallback((reason) => {
91362
+ const refreshFromResume = React125__default.useCallback((reason) => {
90669
91363
  const now4 = Date.now();
90670
91364
  if (now4 - lastResumeRefreshAtRef.current < 1e3) {
90671
91365
  debugRefreshLog("resume refresh suppressed", { reason });
@@ -90680,7 +91374,7 @@ var useOperationsOverviewRefresh = ({
90680
91374
  }
90681
91375
  });
90682
91376
  }, [refreshAll, startPolling, stopPolling]);
90683
- React148__default.useEffect(() => {
91377
+ React125__default.useEffect(() => {
90684
91378
  if (!enabled) {
90685
91379
  stopPolling("disabled");
90686
91380
  abortAll();
@@ -90695,7 +91389,7 @@ var useOperationsOverviewRefresh = ({
90695
91389
  }
90696
91390
  void refreshAll("scope_change");
90697
91391
  }, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
90698
- React148__default.useEffect(() => {
91392
+ React125__default.useEffect(() => {
90699
91393
  if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
90700
91394
  isPageActiveRef.current = false;
90701
91395
  stopPolling("live_scope_disabled");
@@ -90908,55 +91602,55 @@ var PlantHeadView = () => {
90908
91602
  const { accessibleLineIds } = useUserLineAccess();
90909
91603
  const mobileMenuContext = useMobileMenu();
90910
91604
  useHideMobileHeader(!!mobileMenuContext);
90911
- const storeRef = React148__default.useRef(createOperationsOverviewStore());
91605
+ const storeRef = React125__default.useRef(createOperationsOverviewStore());
90912
91606
  const store = storeRef.current;
90913
- const fallbackOperationalDate = React148__default.useMemo(
91607
+ const fallbackOperationalDate = React125__default.useMemo(
90914
91608
  () => getOperationalDate(appTimezone),
90915
91609
  [appTimezone]
90916
91610
  );
90917
- const [dateRange, setDateRange] = React148__default.useState(() => ({
91611
+ const [dateRange, setDateRange] = React125__default.useState(() => ({
90918
91612
  startKey: fallbackOperationalDate,
90919
91613
  endKey: fallbackOperationalDate
90920
91614
  }));
90921
- const [usesThisWeekComparison, setUsesThisWeekComparison] = React148__default.useState(false);
90922
- const [trendMode, setTrendMode] = React148__default.useState("all");
90923
- const [selectedSupervisorId, setSelectedSupervisorId] = React148__default.useState("all");
90924
- const [selectedLineIds, setSelectedLineIds] = React148__default.useState([]);
90925
- const [isInitialScopeReady, setIsInitialScopeReady] = React148__default.useState(false);
90926
- const [shiftResolutionTick, setShiftResolutionTick] = React148__default.useState(0);
90927
- const hasAutoInitializedScopeRef = React148__default.useRef(false);
90928
- const hasUserAdjustedScopeRef = React148__default.useRef(false);
90929
- React148__default.useEffect(() => {
91615
+ const [usesThisWeekComparison, setUsesThisWeekComparison] = React125__default.useState(false);
91616
+ const [trendMode, setTrendMode] = React125__default.useState("all");
91617
+ const [selectedSupervisorId, setSelectedSupervisorId] = React125__default.useState("all");
91618
+ const [selectedLineIds, setSelectedLineIds] = React125__default.useState([]);
91619
+ const [isInitialScopeReady, setIsInitialScopeReady] = React125__default.useState(false);
91620
+ const [shiftResolutionTick, setShiftResolutionTick] = React125__default.useState(0);
91621
+ const hasAutoInitializedScopeRef = React125__default.useRef(false);
91622
+ const hasUserAdjustedScopeRef = React125__default.useRef(false);
91623
+ React125__default.useEffect(() => {
90930
91624
  trackCorePageView("Operations Overview", {
90931
91625
  dashboard_surface: "operations_overview"
90932
91626
  });
90933
91627
  }, []);
90934
- const currentWeekRange = React148__default.useMemo(
91628
+ const currentWeekRange = React125__default.useMemo(
90935
91629
  () => getCurrentWeekToDateRange(appTimezone),
90936
91630
  [appTimezone]
90937
91631
  );
90938
- const currentWeekDisplayRange = React148__default.useMemo(
91632
+ const currentWeekDisplayRange = React125__default.useMemo(
90939
91633
  () => getCurrentWeekFullRange(appTimezone),
90940
91634
  [appTimezone]
90941
91635
  );
90942
91636
  const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
90943
- const headerDateRange = React148__default.useMemo(() => {
91637
+ const headerDateRange = React125__default.useMemo(() => {
90944
91638
  if (usesThisWeekComparison && isCurrentWeekToDateRange) {
90945
91639
  return currentWeekDisplayRange;
90946
91640
  }
90947
91641
  return dateRange;
90948
91642
  }, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
90949
- const normalizedLineIds = React148__default.useMemo(
91643
+ const normalizedLineIds = React125__default.useMemo(
90950
91644
  () => Array.from(new Set(
90951
91645
  (accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
90952
91646
  )).sort(),
90953
91647
  [accessibleLineIds, factoryViewId]
90954
91648
  );
90955
- const lineIdsKey = React148__default.useMemo(
91649
+ const lineIdsKey = React125__default.useMemo(
90956
91650
  () => normalizedLineIds.join(","),
90957
91651
  [normalizedLineIds]
90958
91652
  );
90959
- const lineOptions = React148__default.useMemo(
91653
+ const lineOptions = React125__default.useMemo(
90960
91654
  () => normalizedLineIds.map((lineId) => ({
90961
91655
  id: lineId,
90962
91656
  name: getLineDisplayName(entityConfig, lineId)
@@ -90968,7 +91662,7 @@ var PlantHeadView = () => {
90968
91662
  companyId: entityConfig.companyId,
90969
91663
  useBackend: true
90970
91664
  });
90971
- const supervisorOptions = React148__default.useMemo(
91665
+ const supervisorOptions = React125__default.useMemo(
90972
91666
  () => {
90973
91667
  const optionsById = /* @__PURE__ */ new Map();
90974
91668
  normalizedLineIds.forEach((lineId) => {
@@ -90994,7 +91688,7 @@ var PlantHeadView = () => {
90994
91688
  },
90995
91689
  [normalizedLineIds, supervisorsByLineId]
90996
91690
  );
90997
- React148__default.useEffect(() => {
91691
+ React125__default.useEffect(() => {
90998
91692
  if (selectedSupervisorId === "all") {
90999
91693
  setSelectedLineIds((previous) => {
91000
91694
  if (normalizedLineIds.length === 0) {
@@ -91020,7 +91714,7 @@ var PlantHeadView = () => {
91020
91714
  const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
91021
91715
  setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
91022
91716
  }, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
91023
- const scopedLineIds = React148__default.useMemo(
91717
+ const scopedLineIds = React125__default.useMemo(
91024
91718
  () => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
91025
91719
  [normalizedLineIds, selectedLineIds]
91026
91720
  );
@@ -91028,7 +91722,7 @@ var PlantHeadView = () => {
91028
91722
  shiftConfigMap,
91029
91723
  isLoading: isShiftConfigLoading
91030
91724
  } = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
91031
- const shiftFilterOptions = React148__default.useMemo(() => {
91725
+ const shiftFilterOptions = React125__default.useMemo(() => {
91032
91726
  const optionsById = /* @__PURE__ */ new Map();
91033
91727
  scopedLineIds.forEach((lineId) => {
91034
91728
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
@@ -91067,7 +91761,7 @@ var PlantHeadView = () => {
91067
91761
  ...dynamicOptions
91068
91762
  ];
91069
91763
  }, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
91070
- React148__default.useEffect(() => {
91764
+ React125__default.useEffect(() => {
91071
91765
  if (scopedLineIds.length === 0 || isShiftConfigLoading) {
91072
91766
  return;
91073
91767
  }
@@ -91078,11 +91772,11 @@ var PlantHeadView = () => {
91078
91772
  clearInterval(intervalId);
91079
91773
  };
91080
91774
  }, [isShiftConfigLoading, scopedLineIds.length]);
91081
- const shiftResolutionNow = React148__default.useMemo(
91775
+ const shiftResolutionNow = React125__default.useMemo(
91082
91776
  () => /* @__PURE__ */ new Date(),
91083
91777
  [shiftResolutionTick]
91084
91778
  );
91085
- const earliestDayShiftStartTime = React148__default.useMemo(() => {
91779
+ const earliestDayShiftStartTime = React125__default.useMemo(() => {
91086
91780
  const candidateStarts = [];
91087
91781
  scopedLineIds.forEach((lineId) => {
91088
91782
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
@@ -91118,11 +91812,11 @@ var PlantHeadView = () => {
91118
91812
  const minutes = earliestMinutes % 60;
91119
91813
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
91120
91814
  }, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
91121
- const resolvedOperationalToday = React148__default.useMemo(
91815
+ const resolvedOperationalToday = React125__default.useMemo(
91122
91816
  () => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
91123
91817
  [appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
91124
91818
  );
91125
- const activeLineShiftStates = React148__default.useMemo(() => {
91819
+ const activeLineShiftStates = React125__default.useMemo(() => {
91126
91820
  return scopedLineIds.flatMap((lineId) => {
91127
91821
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
91128
91822
  const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
@@ -91152,7 +91846,7 @@ var PlantHeadView = () => {
91152
91846
  });
91153
91847
  }, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
91154
91848
  const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
91155
- const hourlyWindowStartTime = React148__default.useMemo(() => {
91849
+ const hourlyWindowStartTime = React125__default.useMemo(() => {
91156
91850
  if (scopedLineIds.length === 0) {
91157
91851
  return null;
91158
91852
  }
@@ -91209,12 +91903,12 @@ var PlantHeadView = () => {
91209
91903
  const minutes = earliestMinutes % 60;
91210
91904
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
91211
91905
  }, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
91212
- const isShiftScopeResolved = React148__default.useMemo(
91906
+ const isShiftScopeResolved = React125__default.useMemo(
91213
91907
  () => !isShiftConfigLoading,
91214
91908
  [isShiftConfigLoading]
91215
91909
  );
91216
- const initializedTimezoneRef = React148__default.useRef(appTimezone);
91217
- React148__default.useEffect(() => {
91910
+ const initializedTimezoneRef = React125__default.useRef(appTimezone);
91911
+ React125__default.useEffect(() => {
91218
91912
  if (initializedTimezoneRef.current === appTimezone) return;
91219
91913
  hasAutoInitializedScopeRef.current = false;
91220
91914
  hasUserAdjustedScopeRef.current = false;
@@ -91227,7 +91921,7 @@ var PlantHeadView = () => {
91227
91921
  setIsInitialScopeReady(false);
91228
91922
  initializedTimezoneRef.current = appTimezone;
91229
91923
  }, [appTimezone, fallbackOperationalDate]);
91230
- React148__default.useEffect(() => {
91924
+ React125__default.useEffect(() => {
91231
91925
  if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
91232
91926
  return;
91233
91927
  }
@@ -91252,7 +91946,7 @@ var PlantHeadView = () => {
91252
91946
  hasAutoInitializedScopeRef.current = true;
91253
91947
  setIsInitialScopeReady(true);
91254
91948
  }, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
91255
- const handleDateRangeChange = React148__default.useCallback((range, meta) => {
91949
+ const handleDateRangeChange = React125__default.useCallback((range, meta) => {
91256
91950
  hasUserAdjustedScopeRef.current = true;
91257
91951
  setIsInitialScopeReady(true);
91258
91952
  trackCoreEvent("Operations Overview Date Range Changed", {
@@ -91270,12 +91964,12 @@ var PlantHeadView = () => {
91270
91964
  return previous;
91271
91965
  });
91272
91966
  }, []);
91273
- const handleTrendModeChange = React148__default.useCallback((mode) => {
91967
+ const handleTrendModeChange = React125__default.useCallback((mode) => {
91274
91968
  hasUserAdjustedScopeRef.current = true;
91275
91969
  setIsInitialScopeReady(true);
91276
91970
  setTrendMode(mode);
91277
91971
  }, []);
91278
- const handleSelectedLineIdsChange = React148__default.useCallback((lineIds) => {
91972
+ const handleSelectedLineIdsChange = React125__default.useCallback((lineIds) => {
91279
91973
  setSelectedSupervisorId("all");
91280
91974
  if (normalizedLineIds.length === 0) {
91281
91975
  setSelectedLineIds([]);
@@ -91286,10 +91980,10 @@ var PlantHeadView = () => {
91286
91980
  const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
91287
91981
  setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
91288
91982
  }, [normalizedLineIds]);
91289
- const handleSelectedSupervisorIdChange = React148__default.useCallback((supervisorId) => {
91983
+ const handleSelectedSupervisorIdChange = React125__default.useCallback((supervisorId) => {
91290
91984
  setSelectedSupervisorId(supervisorId);
91291
91985
  }, []);
91292
- const buildLineMonthlyHistoryUrl = React148__default.useCallback((lineId) => {
91986
+ const buildLineMonthlyHistoryUrl = React125__default.useCallback((lineId) => {
91293
91987
  const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
91294
91988
  const params = new URLSearchParams();
91295
91989
  params.set("tab", "monthly_history");
@@ -91299,15 +91993,15 @@ var PlantHeadView = () => {
91299
91993
  params.set("rangeEnd", dateRange.endKey);
91300
91994
  return `/kpis/${lineId}?${params.toString()}`;
91301
91995
  }, [dateRange.endKey, dateRange.startKey]);
91302
- const handleViewAllPoorestPerformers = React148__default.useCallback(() => {
91996
+ const handleViewAllPoorestPerformers = React125__default.useCallback(() => {
91303
91997
  trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
91304
91998
  navigate("/kpis?tab=leaderboard");
91305
91999
  }, [navigate]);
91306
- const handleViewAllImprovements = React148__default.useCallback(() => {
92000
+ const handleViewAllImprovements = React125__default.useCallback(() => {
91307
92001
  trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
91308
92002
  navigate("/improvement-center");
91309
92003
  }, [navigate]);
91310
- const handleOpenImprovement = React148__default.useCallback((item) => {
92004
+ const handleOpenImprovement = React125__default.useCallback((item) => {
91311
92005
  trackCoreEvent("Operations Overview Improvement Clicked", {
91312
92006
  issue_id: item.issueId,
91313
92007
  issue_number: item.issueNumber,
@@ -91318,13 +92012,13 @@ var PlantHeadView = () => {
91318
92012
  });
91319
92013
  navigate(`/improvement-center?${params.toString()}`);
91320
92014
  }, [navigate]);
91321
- const comparisonStrategy = React148__default.useMemo(() => {
92015
+ const comparisonStrategy = React125__default.useMemo(() => {
91322
92016
  if (usesThisWeekComparison && isCurrentWeekToDateRange) {
91323
92017
  return "previous_full_week";
91324
92018
  }
91325
92019
  return void 0;
91326
92020
  }, [isCurrentWeekToDateRange, usesThisWeekComparison]);
91327
- const effectiveDateRange = React148__default.useMemo(() => {
92021
+ const effectiveDateRange = React125__default.useMemo(() => {
91328
92022
  if (isInitialScopeReady) {
91329
92023
  return dateRange;
91330
92024
  }
@@ -91334,11 +92028,11 @@ var PlantHeadView = () => {
91334
92028
  endKey: nextStartKey
91335
92029
  };
91336
92030
  }, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
91337
- const effectiveTrendMode = React148__default.useMemo(
92031
+ const effectiveTrendMode = React125__default.useMemo(
91338
92032
  () => resolvedTrendMode,
91339
92033
  [resolvedTrendMode]
91340
92034
  );
91341
- const hasActiveSelectedShiftLine = React148__default.useMemo(
92035
+ const hasActiveSelectedShiftLine = React125__default.useMemo(
91342
92036
  () => activeLineShiftStates.some((shift) => {
91343
92037
  if (shift.date !== resolvedOperationalToday) return false;
91344
92038
  if (effectiveTrendMode === "all") return true;
@@ -91350,7 +92044,7 @@ var PlantHeadView = () => {
91350
92044
  }),
91351
92045
  [activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
91352
92046
  );
91353
- const activeLiveShiftName = React148__default.useMemo(
92047
+ const activeLiveShiftName = React125__default.useMemo(
91354
92048
  () => {
91355
92049
  if (effectiveTrendMode === "all") return null;
91356
92050
  const matchingShift = activeLineShiftStates.find((shift) => {
@@ -91365,17 +92059,17 @@ var PlantHeadView = () => {
91365
92059
  },
91366
92060
  [activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
91367
92061
  );
91368
- const hourlyLabelStartTime = React148__default.useMemo(() => {
92062
+ const hourlyLabelStartTime = React125__default.useMemo(() => {
91369
92063
  if (scopedLineIds.length === 0) {
91370
92064
  return null;
91371
92065
  }
91372
92066
  return hourlyWindowStartTime;
91373
92067
  }, [hourlyWindowStartTime, scopedLineIds.length]);
91374
- const isSingleDayScope = React148__default.useMemo(
92068
+ const isSingleDayScope = React125__default.useMemo(
91375
92069
  () => effectiveDateRange.startKey === effectiveDateRange.endKey,
91376
92070
  [effectiveDateRange.endKey, effectiveDateRange.startKey]
91377
92071
  );
91378
- const isLiveScope = React148__default.useMemo(
92072
+ const isLiveScope = React125__default.useMemo(
91379
92073
  () => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && hasActiveSelectedShiftLine,
91380
92074
  [
91381
92075
  effectiveDateRange.startKey,
@@ -91385,7 +92079,7 @@ var PlantHeadView = () => {
91385
92079
  resolvedOperationalToday
91386
92080
  ]
91387
92081
  );
91388
- const handleOpenLineDetails = React148__default.useCallback((line) => {
92082
+ const handleOpenLineDetails = React125__default.useCallback((line) => {
91389
92083
  trackCoreEvent("Operations Overview Line Clicked", {
91390
92084
  line_id: line.rowType === "line" ? line.id : null,
91391
92085
  line_name: line.name,