@optifye/dashboard-core 6.12.44 → 6.12.46

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 React147 from 'react';
4
- import React147__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 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';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
  import { useRouter } from 'next/router';
7
7
  import { toast } from 'sonner';
@@ -2091,14 +2091,14 @@ var useIdleTimeVlmConfig = () => {
2091
2091
  }
2092
2092
  return context;
2093
2093
  };
2094
- var DashboardConfigContext = React147.createContext(void 0);
2094
+ var DashboardConfigContext = React148.createContext(void 0);
2095
2095
  var DashboardProvider = ({ config: userProvidedConfig, children }) => {
2096
- const fullConfig = React147.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
2096
+ const fullConfig = React148.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
2097
2097
  _setDashboardConfigInstance(fullConfig);
2098
- React147.useEffect(() => {
2098
+ React148.useEffect(() => {
2099
2099
  _setDashboardConfigInstance(fullConfig);
2100
2100
  }, [fullConfig]);
2101
- React147.useEffect(() => {
2101
+ React148.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 = React147.useContext(DashboardConfigContext);
2127
+ const ctx = React148.useContext(DashboardConfigContext);
2128
2128
  if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
2129
2129
  return ctx;
2130
2130
  };
@@ -9290,6 +9290,7 @@ var CLIP_COUNTS_CACHE_TTL = 30 * 1e3;
9290
9290
  var CLIP_BY_ID_CACHE_TTL = 2 * 60 * 1e3;
9291
9291
  var CLIP_BY_ID_CACHE_MAX = 200;
9292
9292
  var CLIPS_INIT_CACHE_TTL = 30 * 1e3;
9293
+ var RECENT_FLOW_RED_STREAK_CLIP_TYPE = "recent_flow_red_streak";
9293
9294
  var parseFiniteNumber = (value) => {
9294
9295
  if (typeof value === "number" && Number.isFinite(value)) {
9295
9296
  return value;
@@ -9885,6 +9886,7 @@ var S3ClipsSupabaseService = class {
9885
9886
  case "long_cycle_time":
9886
9887
  case "worst_cycle_time":
9887
9888
  case "sop_deviations":
9889
+ case RECENT_FLOW_RED_STREAK_CLIP_TYPE:
9888
9890
  return "high";
9889
9891
  case "idle_time":
9890
9892
  return "medium";
@@ -9905,7 +9907,8 @@ var S3ClipsSupabaseService = class {
9905
9907
  "best_cycle_time": "Best Cycle Time Performance",
9906
9908
  "worst_cycle_time": "Worst Cycle Time Performance",
9907
9909
  "sop_deviations": "SOP Deviations",
9908
- "cycle_completion": "Cycle Completion"
9910
+ "cycle_completion": "Cycle Completion",
9911
+ [RECENT_FLOW_RED_STREAK_CLIP_TYPE]: "Moments with low efficiency"
9909
9912
  };
9910
9913
  return clipType ? descriptions[clipType] || "Analysis Clip" : "Analysis Clip";
9911
9914
  }
@@ -12827,7 +12830,7 @@ var useMobileMenu = () => {
12827
12830
  };
12828
12831
  var useHideMobileHeader = (shouldHide = true) => {
12829
12832
  const context = useMobileMenu();
12830
- React147__default.useEffect(() => {
12833
+ React148__default.useEffect(() => {
12831
12834
  if (context && shouldHide) {
12832
12835
  context.setHideMobileHeader(true);
12833
12836
  return () => {
@@ -25910,7 +25913,7 @@ var MotionConfigContext = createContext({
25910
25913
  });
25911
25914
 
25912
25915
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
25913
- var PopChildMeasure = class extends React147.Component {
25916
+ var PopChildMeasure = class extends React148.Component {
25914
25917
  getSnapshotBeforeUpdate(prevProps) {
25915
25918
  const element = this.props.childRef.current;
25916
25919
  if (element && prevProps.isPresent && !this.props.isPresent) {
@@ -25965,7 +25968,7 @@ function PopChild({ children, isPresent }) {
25965
25968
  document.head.removeChild(style);
25966
25969
  };
25967
25970
  }, [isPresent]);
25968
- return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React147.cloneElement(children, { ref }) });
25971
+ return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React148.cloneElement(children, { ref }) });
25969
25972
  }
25970
25973
 
25971
25974
  // ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
@@ -26002,7 +26005,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
26002
26005
  useMemo(() => {
26003
26006
  presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
26004
26007
  }, [isPresent]);
26005
- React147.useEffect(() => {
26008
+ React148.useEffect(() => {
26006
26009
  !isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
26007
26010
  }, [isPresent]);
26008
26011
  if (mode === "popLayout") {
@@ -33787,7 +33790,7 @@ var withAuth = (WrappedComponent2, options) => {
33787
33790
  requireAuth: true,
33788
33791
  ...options
33789
33792
  };
33790
- const WithAuthComponent = React147.memo(function WithAuthComponent2(props) {
33793
+ const WithAuthComponent = React148.memo(function WithAuthComponent2(props) {
33791
33794
  const {
33792
33795
  session,
33793
33796
  user,
@@ -33798,9 +33801,9 @@ var withAuth = (WrappedComponent2, options) => {
33798
33801
  retrySessionHydration
33799
33802
  } = useAuth();
33800
33803
  const router = useRouter();
33801
- const [localLoading, setLocalLoading] = React147.useState(loading);
33802
- const [loadingTimeoutReached, setLoadingTimeoutReached] = React147.useState(false);
33803
- React147.useEffect(() => {
33804
+ const [localLoading, setLocalLoading] = React148.useState(loading);
33805
+ const [loadingTimeoutReached, setLoadingTimeoutReached] = React148.useState(false);
33806
+ React148.useEffect(() => {
33804
33807
  if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
33805
33808
  console.log("withAuth state:", {
33806
33809
  loading,
@@ -33812,7 +33815,7 @@ var withAuth = (WrappedComponent2, options) => {
33812
33815
  });
33813
33816
  }
33814
33817
  }, [authStatus, error, loading, session, user]);
33815
- const handleLoadingTimeout = React147.useCallback(() => {
33818
+ const handleLoadingTimeout = React148.useCallback(() => {
33816
33819
  console.warn("[withAuth] Loading timeout reached");
33817
33820
  setLoadingTimeoutReached(true);
33818
33821
  if (hasStoredSupabaseSession()) {
@@ -33824,13 +33827,13 @@ var withAuth = (WrappedComponent2, options) => {
33824
33827
  router.replace(defaultOptions.redirectTo);
33825
33828
  }
33826
33829
  }, [retrySessionHydration, router]);
33827
- React147.useEffect(() => {
33830
+ React148.useEffect(() => {
33828
33831
  if (!loading && authStatus !== "recovering" && defaultOptions.requireAuth && !session && !error) {
33829
33832
  console.log("[withAuth] No session found, redirecting to login");
33830
33833
  router.replace(defaultOptions.redirectTo);
33831
33834
  }
33832
33835
  }, [authStatus, defaultOptions.requireAuth, error, loading, router, session]);
33833
- React147.useEffect(() => {
33836
+ React148.useEffect(() => {
33834
33837
  setLocalLoading(loading);
33835
33838
  }, [loading]);
33836
33839
  if (loading || localLoading) {
@@ -34829,11 +34832,11 @@ var BarChartComponent = ({
34829
34832
  aspect = 2,
34830
34833
  ...restOfChartProps
34831
34834
  }) => {
34832
- const containerRef = React147__default.useRef(null);
34833
- const [containerReady, setContainerReady] = React147__default.useState(false);
34835
+ const containerRef = React148__default.useRef(null);
34836
+ const [containerReady, setContainerReady] = React148__default.useState(false);
34834
34837
  const themeConfig = useThemeConfig();
34835
34838
  const { formatNumber } = useFormatNumber();
34836
- React147__default.useEffect(() => {
34839
+ React148__default.useEffect(() => {
34837
34840
  const checkContainerDimensions = () => {
34838
34841
  if (containerRef.current) {
34839
34842
  const rect = containerRef.current.getBoundingClientRect();
@@ -34947,7 +34950,7 @@ var BarChartComponent = ({
34947
34950
  }
34948
34951
  return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
34949
34952
  };
34950
- var BarChart = React147__default.memo(BarChartComponent, (prevProps, nextProps) => {
34953
+ var BarChart = React148__default.memo(BarChartComponent, (prevProps, nextProps) => {
34951
34954
  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) {
34952
34955
  return false;
34953
34956
  }
@@ -34998,10 +35001,10 @@ var LineChartComponent = ({
34998
35001
  fillContainer = false,
34999
35002
  ...restOfChartProps
35000
35003
  }) => {
35001
- const containerRef = React147__default.useRef(null);
35002
- const [dimensions, setDimensions] = React147__default.useState({ width: 0, height: 0 });
35003
- const [hasValidData, setHasValidData] = React147__default.useState(false);
35004
- React147__default.useEffect(() => {
35004
+ const containerRef = React148__default.useRef(null);
35005
+ const [dimensions, setDimensions] = React148__default.useState({ width: 0, height: 0 });
35006
+ const [hasValidData, setHasValidData] = React148__default.useState(false);
35007
+ React148__default.useEffect(() => {
35005
35008
  const currentHasValidData = data && lines && lines.length > 0 && data.some(
35006
35009
  (item) => lines.some((line) => {
35007
35010
  const val = item[line.dataKey];
@@ -35012,7 +35015,7 @@ var LineChartComponent = ({
35012
35015
  setHasValidData(true);
35013
35016
  }
35014
35017
  }, [data, lines, hasValidData]);
35015
- React147__default.useEffect(() => {
35018
+ React148__default.useEffect(() => {
35016
35019
  if (!containerRef.current) return;
35017
35020
  const observer = new ResizeObserver((entries) => {
35018
35021
  const entry = entries[0];
@@ -35137,7 +35140,7 @@ var LineChartComponent = ({
35137
35140
  }
35138
35141
  return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
35139
35142
  };
35140
- var LineChart = React147__default.memo(LineChartComponent, (prevProps, nextProps) => {
35143
+ var LineChart = React148__default.memo(LineChartComponent, (prevProps, nextProps) => {
35141
35144
  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)) {
35142
35145
  return false;
35143
35146
  }
@@ -35304,7 +35307,7 @@ var SkuRow = ({ sku, isSelected, isLive, onSelect }) => {
35304
35307
  );
35305
35308
  };
35306
35309
  var PerSkuView = ({ rows, className = "", selectedSkuId, liveSkuId, onSelectSku }) => {
35307
- const ordered = React147__default.useMemo(
35310
+ const ordered = React148__default.useMemo(
35308
35311
  () => [...rows].sort((a, b) => {
35309
35312
  const am = (b.active_minutes ?? 0) - (a.active_minutes ?? 0);
35310
35313
  if (am !== 0) return am;
@@ -35312,9 +35315,9 @@ var PerSkuView = ({ rows, className = "", selectedSkuId, liveSkuId, onSelectSku
35312
35315
  }),
35313
35316
  [rows]
35314
35317
  );
35315
- const scrollContainerRef = React147__default.useRef(null);
35316
- const [showScrollIndicatorBottom, setShowScrollIndicatorBottom] = React147__default.useState(ordered.length > 4);
35317
- const [showScrollIndicatorTop, setShowScrollIndicatorTop] = React147__default.useState(false);
35318
+ const scrollContainerRef = React148__default.useRef(null);
35319
+ const [showScrollIndicatorBottom, setShowScrollIndicatorBottom] = React148__default.useState(ordered.length > 4);
35320
+ const [showScrollIndicatorTop, setShowScrollIndicatorTop] = React148__default.useState(false);
35318
35321
  const handleScroll = (e) => {
35319
35322
  const target = e.currentTarget;
35320
35323
  if (target.scrollHeight - target.scrollTop <= target.clientHeight + 10) {
@@ -35338,7 +35341,7 @@ var PerSkuView = ({ rows, className = "", selectedSkuId, liveSkuId, onSelectSku
35338
35341
  scrollContainerRef.current.scrollBy({ top: -80, behavior: "smooth" });
35339
35342
  }
35340
35343
  };
35341
- React147__default.useEffect(() => {
35344
+ React148__default.useEffect(() => {
35342
35345
  if (scrollContainerRef.current) {
35343
35346
  const target = scrollContainerRef.current;
35344
35347
  setShowScrollIndicatorBottom(target.scrollHeight > target.clientHeight && target.scrollHeight - target.scrollTop > target.clientHeight + 10);
@@ -35411,7 +35414,7 @@ var OutputProgressChartComponent = ({
35411
35414
  liveSkuId,
35412
35415
  onSelectSku
35413
35416
  }) => {
35414
- const realSkuRows = React147__default.useMemo(
35417
+ const realSkuRows = React148__default.useMemo(
35415
35418
  () => filterRealSkuBreakdown(skuBreakdown),
35416
35419
  [skuBreakdown]
35417
35420
  );
@@ -35436,7 +35439,7 @@ var OutputProgressChartComponent = ({
35436
35439
  }
35437
35440
  );
35438
35441
  };
35439
- var OutputProgressChart = React147__default.memo(OutputProgressChartComponent);
35442
+ var OutputProgressChart = React148__default.memo(OutputProgressChartComponent);
35440
35443
  OutputProgressChart.displayName = "OutputProgressChart";
35441
35444
  var LargeOutputProgressChart = ({
35442
35445
  currentOutput,
@@ -35576,7 +35579,7 @@ var CycleTimeChartComponent = ({
35576
35579
  }
35577
35580
  ) }) });
35578
35581
  };
35579
- var CycleTimeChart = React147__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
35582
+ var CycleTimeChart = React148__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
35580
35583
  if (prevProps.className !== nextProps.className) {
35581
35584
  return false;
35582
35585
  }
@@ -35816,16 +35819,16 @@ var CycleTimeOverTimeChart = ({
35816
35819
  onHourClick
35817
35820
  }) => {
35818
35821
  const MAX_DATA_POINTS = 40;
35819
- const containerRef = React147__default.useRef(null);
35820
- const [dimensions, setDimensions] = React147__default.useState({ width: 0, height: 0 });
35821
- const [hasValidData, setHasValidData] = React147__default.useState(false);
35822
- React147__default.useEffect(() => {
35822
+ const containerRef = React148__default.useRef(null);
35823
+ const [dimensions, setDimensions] = React148__default.useState({ width: 0, height: 0 });
35824
+ const [hasValidData, setHasValidData] = React148__default.useState(false);
35825
+ React148__default.useEffect(() => {
35823
35826
  const currentHasValidData = data && data.some((val) => val !== null && val > 0);
35824
35827
  if (currentHasValidData && !hasValidData) {
35825
35828
  setHasValidData(true);
35826
35829
  }
35827
35830
  }, [data, hasValidData]);
35828
- React147__default.useEffect(() => {
35831
+ React148__default.useEffect(() => {
35829
35832
  if (!containerRef.current) return;
35830
35833
  const observer = new ResizeObserver((entries) => {
35831
35834
  const entry = entries[0];
@@ -35863,7 +35866,7 @@ var CycleTimeOverTimeChart = ({
35863
35866
  const endLabel = shiftEnd && slotIndex === DURATION - 1 ? formatHourLabel(slotIndex + 1) : formatHourLabel(slotIndex + 1);
35864
35867
  return `${startLabel} - ${endLabel}`;
35865
35868
  };
35866
- const getDisplayData = React147__default.useCallback((rawData) => {
35869
+ const getDisplayData = React148__default.useCallback((rawData) => {
35867
35870
  if (xAxisMode === "hourly") return rawData;
35868
35871
  return rawData.slice(Math.max(0, rawData.length - MAX_DATA_POINTS));
35869
35872
  }, [xAxisMode]);
@@ -35871,7 +35874,7 @@ var CycleTimeOverTimeChart = ({
35871
35874
  const DURATION = displayData.length;
35872
35875
  const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
35873
35876
  const finalData = displayData;
35874
- const labelInterval = React147__default.useMemo(() => {
35877
+ const labelInterval = React148__default.useMemo(() => {
35875
35878
  if (xAxisMode === "hourly") {
35876
35879
  return Math.max(1, Math.ceil(DURATION / 8));
35877
35880
  }
@@ -35912,8 +35915,8 @@ var CycleTimeOverTimeChart = ({
35912
35915
  return `${minutes} minutes ${seconds} seconds ago`;
35913
35916
  }
35914
35917
  };
35915
- const getNumericValue = React147__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
35916
- const buildHourClickPayload = React147__default.useCallback((dataPoint) => {
35918
+ const getNumericValue = React148__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
35919
+ const buildHourClickPayload = React148__default.useCallback((dataPoint) => {
35917
35920
  if (!onHourClick || xAxisMode !== "hourly") {
35918
35921
  return null;
35919
35922
  }
@@ -35932,7 +35935,7 @@ var CycleTimeOverTimeChart = ({
35932
35935
  status: cycleTime !== null && cycleTime <= idealCycleTime ? "within_standard" : "above_standard"
35933
35936
  };
35934
35937
  }, [DURATION, getNumericValue, idealCycleTime, onHourClick, shiftEnd, shiftStart, xAxisMode]);
35935
- const renderChartTooltip = React147__default.useCallback((tooltipProps) => {
35938
+ const renderChartTooltip = React148__default.useCallback((tooltipProps) => {
35936
35939
  const { active, payload } = tooltipProps;
35937
35940
  if (!active || !Array.isArray(payload) || payload.length === 0) {
35938
35941
  return null;
@@ -35996,7 +35999,7 @@ var CycleTimeOverTimeChart = ({
35996
35999
  ] })
35997
36000
  ] });
35998
36001
  }, [getNumericValue, onHourClick, shiftStart, showIdleTime, xAxisMode]);
35999
- const renderCycleDot = React147__default.useCallback((props) => {
36002
+ const renderCycleDot = React148__default.useCallback((props) => {
36000
36003
  const { cx: cx2, cy, payload } = props;
36001
36004
  const cycleTime = getNumericValue(payload?.cycleTime);
36002
36005
  if (cycleTime === null) {
@@ -36036,7 +36039,7 @@ var CycleTimeOverTimeChart = ({
36036
36039
  }
36037
36040
  );
36038
36041
  }, [buildHourClickPayload, getNumericValue, idealCycleTime, onHourClick, selectedHourIndex]);
36039
- const renderCycleActiveDot = React147__default.useCallback((props) => {
36042
+ const renderCycleActiveDot = React148__default.useCallback((props) => {
36040
36043
  const { cx: cx2, cy, payload } = props;
36041
36044
  const cycleTime = getNumericValue(payload?.cycleTime);
36042
36045
  if (cycleTime === null) {
@@ -36065,7 +36068,7 @@ var CycleTimeOverTimeChart = ({
36065
36068
  }
36066
36069
  );
36067
36070
  }, [buildHourClickPayload, getNumericValue, idealCycleTime, onHourClick, selectedHourIndex]);
36068
- const renderIdleDot = React147__default.useCallback((props) => {
36071
+ const renderIdleDot = React148__default.useCallback((props) => {
36069
36072
  const { cx: cx2, cy, payload } = props;
36070
36073
  const idleMinutes = getNumericValue(payload?.idleMinutes);
36071
36074
  if (idleMinutes === null) {
@@ -36087,7 +36090,7 @@ var CycleTimeOverTimeChart = ({
36087
36090
  }
36088
36091
  );
36089
36092
  }, [getNumericValue, showIdleTime]);
36090
- const renderIdleActiveDot = React147__default.useCallback((props) => {
36093
+ const renderIdleActiveDot = React148__default.useCallback((props) => {
36091
36094
  const { cx: cx2, cy, payload } = props;
36092
36095
  const idleMinutes = getNumericValue(payload?.idleMinutes);
36093
36096
  if (idleMinutes === null || !showIdleTime) {
@@ -36105,7 +36108,7 @@ var CycleTimeOverTimeChart = ({
36105
36108
  }
36106
36109
  );
36107
36110
  }, [getNumericValue, showIdleTime]);
36108
- const chartData = React147__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
36111
+ const chartData = React148__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
36109
36112
  const cycleTime = getNumericValue(finalData[i]);
36110
36113
  const useIdleSlots = idleTimeSlots.length > 0;
36111
36114
  const idleSlot = useIdleSlots ? idleTimeSlots[i] ?? null : null;
@@ -36302,7 +36305,7 @@ var CycleTimeOverTimeChart = ({
36302
36305
  }
36303
36306
  );
36304
36307
  };
36305
- var Card = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36308
+ var Card = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36306
36309
  "div",
36307
36310
  {
36308
36311
  ref,
@@ -36314,7 +36317,7 @@ var Card = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
36314
36317
  }
36315
36318
  ));
36316
36319
  Card.displayName = "Card";
36317
- var CardHeader = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36320
+ var CardHeader = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36318
36321
  "div",
36319
36322
  {
36320
36323
  ref,
@@ -36323,7 +36326,7 @@ var CardHeader = React147.forwardRef(({ className, ...props }, ref) => /* @__PUR
36323
36326
  }
36324
36327
  ));
36325
36328
  CardHeader.displayName = "CardHeader";
36326
- var CardTitle = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36329
+ var CardTitle = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36327
36330
  "h3",
36328
36331
  {
36329
36332
  ref,
@@ -36335,7 +36338,7 @@ var CardTitle = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE
36335
36338
  }
36336
36339
  ));
36337
36340
  CardTitle.displayName = "CardTitle";
36338
- var CardDescription = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36341
+ var CardDescription = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36339
36342
  "p",
36340
36343
  {
36341
36344
  ref,
@@ -36344,9 +36347,9 @@ var CardDescription = React147.forwardRef(({ className, ...props }, ref) => /* @
36344
36347
  }
36345
36348
  ));
36346
36349
  CardDescription.displayName = "CardDescription";
36347
- var CardContent = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
36350
+ var CardContent = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
36348
36351
  CardContent.displayName = "CardContent";
36349
- var CardFooter = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36352
+ var CardFooter = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36350
36353
  "div",
36351
36354
  {
36352
36355
  ref,
@@ -36422,7 +36425,7 @@ var buttonVariants = cva(
36422
36425
  }
36423
36426
  }
36424
36427
  );
36425
- var Button = React147.forwardRef(
36428
+ var Button = React148.forwardRef(
36426
36429
  ({ className, variant, size, asChild = false, ...props }, ref) => {
36427
36430
  const Comp = asChild ? Slot : "button";
36428
36431
  return /* @__PURE__ */ jsx(
@@ -37180,14 +37183,14 @@ var HourlyOutputChartComponent = ({
37180
37183
  onAiSummaryClick,
37181
37184
  className = ""
37182
37185
  }) => {
37183
- const containerRef = React147__default.useRef(null);
37184
- const [containerReady, setContainerReady] = React147__default.useState(false);
37185
- const [containerWidth, setContainerWidth] = React147__default.useState(0);
37186
- const [hoveredSkuRailLabel, setHoveredSkuRailLabel] = React147__default.useState(null);
37187
- const [isTooltipHovered, setIsTooltipHovered] = React147__default.useState(false);
37188
- const lastTooltipDataRef = React147__default.useRef(null);
37189
- const tooltipHoverTimeoutRef = React147__default.useRef(null);
37190
- const idleSlots = React147__default.useMemo(
37186
+ const containerRef = React148__default.useRef(null);
37187
+ const [containerReady, setContainerReady] = React148__default.useState(false);
37188
+ const [containerWidth, setContainerWidth] = React148__default.useState(0);
37189
+ const [hoveredSkuRailLabel, setHoveredSkuRailLabel] = React148__default.useState(null);
37190
+ const [isTooltipHovered, setIsTooltipHovered] = React148__default.useState(false);
37191
+ const lastTooltipDataRef = React148__default.useRef(null);
37192
+ const tooltipHoverTimeoutRef = React148__default.useRef(null);
37193
+ const idleSlots = React148__default.useMemo(
37191
37194
  () => buildHourlyIdleSlots({
37192
37195
  idleTimeHourly,
37193
37196
  shiftStart,
@@ -37196,12 +37199,12 @@ var HourlyOutputChartComponent = ({
37196
37199
  [idleTimeHourly, shiftStart, shiftEnd]
37197
37200
  );
37198
37201
  const SHIFT_DURATION = idleSlots.length;
37199
- const [animatedData, setAnimatedData] = React147__default.useState(
37202
+ const [animatedData, setAnimatedData] = React148__default.useState(
37200
37203
  () => Array(SHIFT_DURATION).fill(0)
37201
37204
  );
37202
- const prevDataRef = React147__default.useRef(Array(SHIFT_DURATION).fill(0));
37203
- const animationFrameRef = React147__default.useRef(null);
37204
- React147__default.useEffect(() => {
37205
+ const prevDataRef = React148__default.useRef(Array(SHIFT_DURATION).fill(0));
37206
+ const animationFrameRef = React148__default.useRef(null);
37207
+ React148__default.useEffect(() => {
37205
37208
  setAnimatedData((prev) => {
37206
37209
  if (prev.length !== SHIFT_DURATION) {
37207
37210
  return Array(SHIFT_DURATION).fill(0);
@@ -37210,14 +37213,14 @@ var HourlyOutputChartComponent = ({
37210
37213
  });
37211
37214
  prevDataRef.current = Array(SHIFT_DURATION).fill(0);
37212
37215
  }, [SHIFT_DURATION]);
37213
- const [idleBarState, setIdleBarState] = React147__default.useState({
37216
+ const [idleBarState, setIdleBarState] = React148__default.useState({
37214
37217
  visible: showIdleTime,
37215
37218
  key: 0,
37216
37219
  shouldAnimate: false
37217
37220
  });
37218
- const prevShowIdleTimeRef = React147__default.useRef(showIdleTime);
37219
- const stateUpdateTimeoutRef = React147__default.useRef(null);
37220
- React147__default.useEffect(() => {
37221
+ const prevShowIdleTimeRef = React148__default.useRef(showIdleTime);
37222
+ const stateUpdateTimeoutRef = React148__default.useRef(null);
37223
+ React148__default.useEffect(() => {
37221
37224
  if (stateUpdateTimeoutRef.current) {
37222
37225
  clearTimeout(stateUpdateTimeoutRef.current);
37223
37226
  }
@@ -37242,7 +37245,7 @@ var HourlyOutputChartComponent = ({
37242
37245
  }
37243
37246
  };
37244
37247
  }, [showIdleTime]);
37245
- const animateToNewData = React147__default.useCallback((targetData) => {
37248
+ const animateToNewData = React148__default.useCallback((targetData) => {
37246
37249
  const startData = [...prevDataRef.current];
37247
37250
  const startTime = performance.now();
37248
37251
  const duration = 1200;
@@ -37272,7 +37275,7 @@ var HourlyOutputChartComponent = ({
37272
37275
  }
37273
37276
  animationFrameRef.current = requestAnimationFrame(animate);
37274
37277
  }, []);
37275
- React147__default.useEffect(() => {
37278
+ React148__default.useEffect(() => {
37276
37279
  if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
37277
37280
  const shiftData = data.slice(0, SHIFT_DURATION);
37278
37281
  animateToNewData(shiftData);
@@ -37283,14 +37286,14 @@ var HourlyOutputChartComponent = ({
37283
37286
  }
37284
37287
  };
37285
37288
  }, [data, animateToNewData]);
37286
- React147__default.useEffect(() => {
37289
+ React148__default.useEffect(() => {
37287
37290
  return () => {
37288
37291
  if (tooltipHoverTimeoutRef.current) {
37289
37292
  clearTimeout(tooltipHoverTimeoutRef.current);
37290
37293
  }
37291
37294
  };
37292
37295
  }, []);
37293
- React147__default.useEffect(() => {
37296
+ React148__default.useEffect(() => {
37294
37297
  const checkContainerDimensions = () => {
37295
37298
  if (containerRef.current) {
37296
37299
  const rect = containerRef.current.getBoundingClientRect();
@@ -37316,7 +37319,7 @@ var HourlyOutputChartComponent = ({
37316
37319
  clearTimeout(fallbackTimeout);
37317
37320
  };
37318
37321
  }, []);
37319
- const xAxisConfig = React147__default.useMemo(() => {
37322
+ const xAxisConfig = React148__default.useMemo(() => {
37320
37323
  if (containerWidth >= 960) {
37321
37324
  return {
37322
37325
  interval: 0,
@@ -37337,13 +37340,13 @@ var HourlyOutputChartComponent = ({
37337
37340
  }
37338
37341
  return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6 };
37339
37342
  }, [containerWidth]);
37340
- const shiftWindow = React147__default.useMemo(() => resolveShiftWindow2({
37343
+ const shiftWindow = React148__default.useMemo(() => resolveShiftWindow2({
37341
37344
  shiftStart,
37342
37345
  slotCount: SHIFT_DURATION,
37343
37346
  shiftDate,
37344
37347
  timezone
37345
37348
  }), [shiftStart, shiftEnd, SHIFT_DURATION, shiftDate, timezone]);
37346
- const fallbackTimelineEndOffset = React147__default.useMemo(
37349
+ const fallbackTimelineEndOffset = React148__default.useMemo(
37347
37350
  () => resolveTimelineEndOffset({
37348
37351
  shiftStart,
37349
37352
  shiftEnd,
@@ -37353,7 +37356,7 @@ var HourlyOutputChartComponent = ({
37353
37356
  }),
37354
37357
  [shiftStart, shiftEnd, SHIFT_DURATION, shiftDate, timezone]
37355
37358
  );
37356
- const observedTimelineEndOffset = React147__default.useMemo(() => {
37359
+ const observedTimelineEndOffset = React148__default.useMemo(() => {
37357
37360
  let lastObservedMinute = -1;
37358
37361
  idleSlots.forEach((slot) => {
37359
37362
  slot.idleArray.forEach((value, minuteIndex) => {
@@ -37369,7 +37372,7 @@ var HourlyOutputChartComponent = ({
37369
37372
  return Math.min((lastObservedMinute + 1) / 60, SHIFT_DURATION);
37370
37373
  }, [idleSlots, SHIFT_DURATION]);
37371
37374
  const timelineEndOffset = observedTimelineEndOffset ?? fallbackTimelineEndOffset;
37372
- const targetLineEndOffset = React147__default.useMemo(() => {
37375
+ const targetLineEndOffset = React148__default.useMemo(() => {
37373
37376
  if (timelineEndOffset >= SHIFT_DURATION) {
37374
37377
  return SHIFT_DURATION;
37375
37378
  }
@@ -37378,7 +37381,7 @@ var HourlyOutputChartComponent = ({
37378
37381
  }
37379
37382
  return Math.min(Math.floor(timelineEndOffset) + 1, SHIFT_DURATION);
37380
37383
  }, [timelineEndOffset, SHIFT_DURATION]);
37381
- const skuTimelineSegments = React147__default.useMemo(() => {
37384
+ const skuTimelineSegments = React148__default.useMemo(() => {
37382
37385
  if (!skuSegments || skuSegments.length === 0 || !shiftWindow || timelineEndOffset <= 0) {
37383
37386
  return [];
37384
37387
  }
@@ -37412,18 +37415,18 @@ var HourlyOutputChartComponent = ({
37412
37415
  };
37413
37416
  }).filter((segment) => segment.end > segment.start);
37414
37417
  }, [skuSegments, shiftWindow, timelineEndOffset, pphThreshold]);
37415
- const targetTimelineSegments = React147__default.useMemo(() => {
37418
+ const targetTimelineSegments = React148__default.useMemo(() => {
37416
37419
  if (skuTimelineSegments.length === 0) return [];
37417
37420
  return skuTimelineSegments.map((segment, index) => ({
37418
37421
  ...segment,
37419
37422
  end: index === skuTimelineSegments.length - 1 ? Math.max(segment.start, targetLineEndOffset) : segment.end
37420
37423
  })).filter((segment) => segment.end > segment.start);
37421
37424
  }, [skuTimelineSegments, targetLineEndOffset]);
37422
- const hasExplicitHourlyTargetOutputProp = React147__default.useMemo(
37425
+ const hasExplicitHourlyTargetOutputProp = React148__default.useMemo(
37423
37426
  () => hourlyTargetOutput !== void 0,
37424
37427
  [hourlyTargetOutput]
37425
37428
  );
37426
- const fallbackHourlyTargetOutput = React147__default.useMemo(() => {
37429
+ const fallbackHourlyTargetOutput = React148__default.useMemo(() => {
37427
37430
  if (hasExplicitHourlyTargetOutputProp) return void 0;
37428
37431
  if (skuTimelineSegments.length > 0) return void 0;
37429
37432
  const plan = buildHourlyTargetPlan({
@@ -37443,19 +37446,19 @@ var HourlyOutputChartComponent = ({
37443
37446
  shiftBreaks,
37444
37447
  pphThreshold
37445
37448
  ]);
37446
- const effectiveHourlyTargetOutput = React147__default.useMemo(
37449
+ const effectiveHourlyTargetOutput = React148__default.useMemo(
37447
37450
  () => hasExplicitHourlyTargetOutputProp ? hourlyTargetOutput : fallbackHourlyTargetOutput,
37448
37451
  [hasExplicitHourlyTargetOutputProp, hourlyTargetOutput, fallbackHourlyTargetOutput]
37449
37452
  );
37450
- const hasHourlyTargetOutputProp = React147__default.useMemo(
37453
+ const hasHourlyTargetOutputProp = React148__default.useMemo(
37451
37454
  () => effectiveHourlyTargetOutput !== void 0,
37452
37455
  [effectiveHourlyTargetOutput]
37453
37456
  );
37454
- const hasExplicitHourlyTargets = React147__default.useMemo(
37457
+ const hasExplicitHourlyTargets = React148__default.useMemo(
37455
37458
  () => Array.isArray(effectiveHourlyTargetOutput) && effectiveHourlyTargetOutput.some((value) => value !== null && value !== void 0),
37456
37459
  [effectiveHourlyTargetOutput]
37457
37460
  );
37458
- const hourlyTargetSegments = React147__default.useMemo(() => {
37461
+ const hourlyTargetSegments = React148__default.useMemo(() => {
37459
37462
  if (!hasExplicitHourlyTargets) return [];
37460
37463
  const segments = [];
37461
37464
  let runStart = null;
@@ -37487,7 +37490,7 @@ var HourlyOutputChartComponent = ({
37487
37490
  flush(SHIFT_DURATION);
37488
37491
  return segments.filter((segment) => segment.end > segment.start);
37489
37492
  }, [SHIFT_DURATION, hasExplicitHourlyTargets, effectiveHourlyTargetOutput]);
37490
- const activeSkuHourIndices = React147__default.useMemo(() => {
37493
+ const activeSkuHourIndices = React148__default.useMemo(() => {
37491
37494
  const indices = /* @__PURE__ */ new Set();
37492
37495
  const targets = Array(SHIFT_DURATION).fill(pphThreshold);
37493
37496
  if (!skuSegments || !shiftWindow) return { indices, targets, hasTimeline: false };
@@ -37520,7 +37523,7 @@ var HourlyOutputChartComponent = ({
37520
37523
  }
37521
37524
  return { indices, targets, hasTimeline: true };
37522
37525
  }, [skuSegments, activeSkuId, shiftWindow, SHIFT_DURATION, pphThreshold]);
37523
- const chartData = React147__default.useMemo(() => {
37526
+ const chartData = React148__default.useMemo(() => {
37524
37527
  const { indices, targets, hasTimeline } = activeSkuHourIndices;
37525
37528
  return Array.from({ length: SHIFT_DURATION }, (_, i) => {
37526
37529
  const idleSlot = idleSlots[i];
@@ -37549,7 +37552,7 @@ var HourlyOutputChartComponent = ({
37549
37552
  };
37550
37553
  });
37551
37554
  }, [animatedData, data, pphThreshold, idleSlots, SHIFT_DURATION, activeSkuHourIndices, activeSkuId, effectiveHourlyTargetOutput, hasHourlyTargetOutputProp, selectedHourIndex]);
37552
- const renderSkuTimelineRail = React147__default.useCallback((props) => {
37555
+ const renderSkuTimelineRail = React148__default.useCallback((props) => {
37553
37556
  if (!skuTimelineSegments.length || SHIFT_DURATION <= 0) return null;
37554
37557
  const offset = props?.offset;
37555
37558
  if (!offset) return null;
@@ -37698,7 +37701,7 @@ var HourlyOutputChartComponent = ({
37698
37701
  })
37699
37702
  ] });
37700
37703
  }, [skuTimelineSegments, SHIFT_DURATION, activeSkuId]);
37701
- const IdleBar = React147__default.useMemo(() => {
37704
+ const IdleBar = React148__default.useMemo(() => {
37702
37705
  if (!idleBarState.visible) return null;
37703
37706
  return /* @__PURE__ */ jsx(
37704
37707
  Bar,
@@ -37792,7 +37795,7 @@ var HourlyOutputChartComponent = ({
37792
37795
  }
37793
37796
  return filteredTicks;
37794
37797
  };
37795
- const renderTargetLine = React147__default.useCallback((props) => {
37798
+ const renderTargetLine = React148__default.useCallback((props) => {
37796
37799
  const { offset, yAxisMap } = props;
37797
37800
  if (!offset || !yAxisMap || SHIFT_DURATION <= 0 || targetLineEndOffset <= 0) return null;
37798
37801
  const { left, width } = offset;
@@ -38293,7 +38296,7 @@ var HourlyOutputChartComponent = ({
38293
38296
  }
38294
38297
  );
38295
38298
  };
38296
- var HourlyOutputChart = React147__default.memo(
38299
+ var HourlyOutputChart = React148__default.memo(
38297
38300
  HourlyOutputChartComponent,
38298
38301
  (prevProps, nextProps) => {
38299
38302
  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) {
@@ -38747,7 +38750,7 @@ function getTrendArrowAndColor(trend) {
38747
38750
  return { arrow: "\u2192", color: "text-gray-400" };
38748
38751
  }
38749
38752
  }
38750
- var VideoCard = React147__default.memo(({
38753
+ var VideoCard = React148__default.memo(({
38751
38754
  workspace,
38752
38755
  hlsUrl,
38753
38756
  shouldPlay,
@@ -39017,7 +39020,7 @@ var hasRecentHealthSignal = (lastHeartbeat) => {
39017
39020
  if (!Number.isFinite(heartbeatMs)) return false;
39018
39021
  return Date.now() - heartbeatMs <= RECENT_HEALTH_SIGNAL_MS;
39019
39022
  };
39020
- var VideoGridView = React147__default.memo(({
39023
+ var VideoGridView = React148__default.memo(({
39021
39024
  workspaces,
39022
39025
  blueComparisonWorkspaces,
39023
39026
  selectedLine,
@@ -39456,7 +39459,7 @@ var VideoGridView = React147__default.memo(({
39456
39459
  ) });
39457
39460
  });
39458
39461
  VideoGridView.displayName = "VideoGridView";
39459
- var MapGridView = React147__default.memo(({
39462
+ var MapGridView = React148__default.memo(({
39460
39463
  workspaces,
39461
39464
  className = "",
39462
39465
  displayNames = {},
@@ -39677,13 +39680,13 @@ var WorkspaceMetricCardsImpl = ({
39677
39680
  liveSkuId
39678
39681
  }) => {
39679
39682
  const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
39680
- const activeSku = React147__default.useMemo(() => {
39683
+ const activeSku = React148__default.useMemo(() => {
39681
39684
  if (skuAware && activeSkuId && skuBreakdown) {
39682
39685
  return skuBreakdown.find((s) => s.sku_id === activeSkuId);
39683
39686
  }
39684
39687
  return null;
39685
39688
  }, [skuAware, activeSkuId, skuBreakdown]);
39686
- const displaySku = React147__default.useMemo(() => {
39689
+ const displaySku = React148__default.useMemo(() => {
39687
39690
  if (activeSku) return activeSku;
39688
39691
  if (skuAware && !activeSkuId && liveSkuId && skuBreakdown) {
39689
39692
  return skuBreakdown.find((s) => s.sku_id === liveSkuId) ?? null;
@@ -40337,7 +40340,7 @@ var UptimeLineChartComponent = ({ points, className = "" }) => {
40337
40340
  )
40338
40341
  ] }) }) });
40339
40342
  };
40340
- var UptimeLineChart = React147__default.memo(UptimeLineChartComponent);
40343
+ var UptimeLineChart = React148__default.memo(UptimeLineChartComponent);
40341
40344
  var getTimeFromTimeString = (timeStr) => {
40342
40345
  if (!timeStr) {
40343
40346
  return { hour: 0, minute: 0, decimalHour: 0 };
@@ -40361,10 +40364,10 @@ var HourlyUptimeChartComponent = ({
40361
40364
  shiftBreaks,
40362
40365
  className = ""
40363
40366
  }) => {
40364
- const containerRef = React147__default.useRef(null);
40365
- const [containerReady, setContainerReady] = React147__default.useState(false);
40366
- const [containerWidth, setContainerWidth] = React147__default.useState(0);
40367
- const uptimeSeries = React147__default.useMemo(() => buildUptimeSeries({
40367
+ const containerRef = React148__default.useRef(null);
40368
+ const [containerReady, setContainerReady] = React148__default.useState(false);
40369
+ const [containerWidth, setContainerWidth] = React148__default.useState(0);
40370
+ const uptimeSeries = React148__default.useMemo(() => buildUptimeSeries({
40368
40371
  idleTimeHourly,
40369
40372
  shiftStart,
40370
40373
  shiftEnd,
@@ -40374,11 +40377,11 @@ var HourlyUptimeChartComponent = ({
40374
40377
  shiftBreaks
40375
40378
  }), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes, shiftBreaks]);
40376
40379
  const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
40377
- const shiftStartTime = React147__default.useMemo(
40380
+ const shiftStartTime = React148__default.useMemo(
40378
40381
  () => getTimeFromTimeString(shiftStart),
40379
40382
  [shiftStart]
40380
40383
  );
40381
- const { shiftDuration, shiftEndTime } = React147__default.useMemo(() => {
40384
+ const { shiftDuration, shiftEndTime } = React148__default.useMemo(() => {
40382
40385
  if (!shiftEnd) {
40383
40386
  const fallbackHours = uptimeSeries.shiftMinutes > 0 ? Math.ceil(uptimeSeries.shiftMinutes / 60) : 0;
40384
40387
  return { shiftDuration: fallbackHours, shiftEndTime: null };
@@ -40392,7 +40395,7 @@ var HourlyUptimeChartComponent = ({
40392
40395
  const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
40393
40396
  return { shiftDuration: hourCount, shiftEndTime: endTime };
40394
40397
  }, [shiftEnd, shiftStartTime.decimalHour, uptimeSeries.shiftMinutes]);
40395
- const formatHour = React147__default.useCallback((hourIndex) => {
40398
+ const formatHour = React148__default.useCallback((hourIndex) => {
40396
40399
  const isLastHour = hourIndex === shiftDuration - 1;
40397
40400
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
40398
40401
  const startHour = Math.floor(startDecimalHour) % 24;
@@ -40417,7 +40420,7 @@ var HourlyUptimeChartComponent = ({
40417
40420
  };
40418
40421
  return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
40419
40422
  }, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
40420
- const formatTimeRange2 = React147__default.useCallback((hourIndex) => {
40423
+ const formatTimeRange2 = React148__default.useCallback((hourIndex) => {
40421
40424
  const isLastHour = hourIndex === shiftDuration - 1;
40422
40425
  const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
40423
40426
  const startHour = Math.floor(startDecimalHour) % 24;
@@ -40439,7 +40442,7 @@ var HourlyUptimeChartComponent = ({
40439
40442
  };
40440
40443
  return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
40441
40444
  }, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
40442
- const chartData = React147__default.useMemo(() => {
40445
+ const chartData = React148__default.useMemo(() => {
40443
40446
  if (shiftDuration <= 0) return [];
40444
40447
  if (hasAggregateData) {
40445
40448
  return hourlyAggregates.map((entry, hourIndex) => ({
@@ -40481,7 +40484,7 @@ var HourlyUptimeChartComponent = ({
40481
40484
  }, [hasAggregateData, hourlyAggregates, uptimeSeries.points, uptimeSeries.elapsedMinutes, uptimeSeries.shiftMinutes, shiftDuration, formatHour, formatTimeRange2]);
40482
40485
  const maxYValue = 100;
40483
40486
  const yAxisTicks = [0, 25, 50, 75, 100];
40484
- React147__default.useEffect(() => {
40487
+ React148__default.useEffect(() => {
40485
40488
  const checkContainerDimensions = () => {
40486
40489
  if (containerRef.current) {
40487
40490
  const rect = containerRef.current.getBoundingClientRect();
@@ -40507,7 +40510,7 @@ var HourlyUptimeChartComponent = ({
40507
40510
  clearTimeout(fallbackTimeout);
40508
40511
  };
40509
40512
  }, []);
40510
- const xAxisConfig = React147__default.useMemo(() => {
40513
+ const xAxisConfig = React148__default.useMemo(() => {
40511
40514
  if (containerWidth >= 960) {
40512
40515
  return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12, labelMode: "full" };
40513
40516
  }
@@ -40516,7 +40519,7 @@ var HourlyUptimeChartComponent = ({
40516
40519
  }
40517
40520
  return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6, labelMode: "start" };
40518
40521
  }, [containerWidth]);
40519
- const formatXAxisTick = React147__default.useCallback((raw) => {
40522
+ const formatXAxisTick = React148__default.useCallback((raw) => {
40520
40523
  const label = typeof raw === "string" ? raw : String(raw);
40521
40524
  if (xAxisConfig.labelMode === "full") return label;
40522
40525
  const parts = label.split("-");
@@ -40722,7 +40725,7 @@ var HourlyUptimeChartComponent = ({
40722
40725
  }
40723
40726
  );
40724
40727
  };
40725
- var HourlyUptimeChart = React147__default.memo(HourlyUptimeChartComponent);
40728
+ var HourlyUptimeChart = React148__default.memo(HourlyUptimeChartComponent);
40726
40729
  var DEFAULT_COLORS2 = ["#00AB45", "#ef4444"];
40727
40730
  var UptimeDonutChartComponent = ({
40728
40731
  data,
@@ -40792,7 +40795,7 @@ var UptimeDonutChartComponent = ({
40792
40795
  ] }) })
40793
40796
  ] }) });
40794
40797
  };
40795
- var UptimeDonutChart = React147__default.memo(UptimeDonutChartComponent);
40798
+ var UptimeDonutChart = React148__default.memo(UptimeDonutChartComponent);
40796
40799
  UptimeDonutChart.displayName = "UptimeDonutChart";
40797
40800
  var TrendIcon = ({ trend }) => {
40798
40801
  if (trend === "up") {
@@ -40913,7 +40916,7 @@ var EmptyStateMessage = ({
40913
40916
  iconClassName
40914
40917
  }) => {
40915
40918
  let IconContent = null;
40916
- if (React147__default.isValidElement(iconType)) {
40919
+ if (React148__default.isValidElement(iconType)) {
40917
40920
  IconContent = iconType;
40918
40921
  } else if (typeof iconType === "string") {
40919
40922
  const MappedIcon = IconMap[iconType];
@@ -41421,6 +41424,7 @@ var CYCLE_RANGE_CATEGORY_IDS = /* @__PURE__ */ new Set([
41421
41424
  "fast-cycles",
41422
41425
  "slow-cycles"
41423
41426
  ]);
41427
+ var EXPLICIT_INTERVAL_CATEGORY_IDS = /* @__PURE__ */ new Set(["recent_flow_red_streak"]);
41424
41428
  var roundToNearestMinute = (date) => {
41425
41429
  const rounded = new Date(date.getTime());
41426
41430
  const seconds = rounded.getSeconds();
@@ -41476,6 +41480,22 @@ var buildPrefetchedExplorerMetadata = (activeFilter, metadataCategoryId, categor
41476
41480
  };
41477
41481
  };
41478
41482
  var shouldDeferClipPlayerRender = (cropLoading, workspaceCrop) => cropLoading && workspaceCrop === null;
41483
+ var getCategoryMetadataLoadPlanForFilterChange = ({
41484
+ activeFilter,
41485
+ currentClipId,
41486
+ categoryTotal
41487
+ }) => {
41488
+ if (!activeFilter || activeFilter === "all") {
41489
+ return { shouldLoad: false, autoLoadFirstVideo: false };
41490
+ }
41491
+ if (activeFilter === "recent_flow_red_streak" && categoryTotal > 0) {
41492
+ return { shouldLoad: true, autoLoadFirstVideo: true };
41493
+ }
41494
+ return {
41495
+ shouldLoad: Boolean(currentClipId),
41496
+ autoLoadFirstVideo: false
41497
+ };
41498
+ };
41479
41499
  var getSecondsBetweenTimestamps = (startTime, endTime) => {
41480
41500
  const startDate = parseTimestamp(startTime);
41481
41501
  const endDate = parseTimestamp(endTime);
@@ -41488,8 +41508,24 @@ var formatClipExplorerTimeLabel = ({
41488
41508
  timezone,
41489
41509
  durationSeconds,
41490
41510
  idleStartTime,
41491
- idleEndTime
41511
+ idleEndTime,
41512
+ clipStartTime,
41513
+ clipEndTime
41492
41514
  }) => {
41515
+ if (EXPLICIT_INTERVAL_CATEGORY_IDS.has(categoryId)) {
41516
+ const endTimestamp = clipEndTime || clipTimestamp;
41517
+ if (clipStartTime && endTimestamp) {
41518
+ return formatTimestampRange(clipStartTime, endTimestamp, timezone);
41519
+ }
41520
+ if (typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds > 0) {
41521
+ const endDate = parseTimestamp(endTimestamp);
41522
+ if (endDate) {
41523
+ const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
41524
+ return formatTimestampRange(startDate.toISOString(), endTimestamp, timezone);
41525
+ }
41526
+ }
41527
+ return formatClipExplorerSingleTime(endTimestamp, timezone);
41528
+ }
41493
41529
  if (IDLE_RANGE_CATEGORY_IDS.has(categoryId)) {
41494
41530
  const idleDurationSeconds = getSecondsBetweenTimestamps(idleStartTime, idleEndTime);
41495
41531
  const idleEndTimestamp = idleEndTime || clipTimestamp;
@@ -41516,6 +41552,106 @@ var formatClipExplorerTimeLabel = ({
41516
41552
  return singleTime;
41517
41553
  };
41518
41554
  var formatIdleTimeRange = (startTime, endTime, timezone) => formatTimestampRange(startTime, endTime, timezone);
41555
+
41556
+ // src/lib/utils/redFlowDisplay.ts
41557
+ var getRedFlowDriverLabel = (driver) => {
41558
+ switch (driver) {
41559
+ case "idle":
41560
+ return "Idle";
41561
+ case "micro_stoppage":
41562
+ return "Gaps";
41563
+ case "slow_cycle":
41564
+ return "Slow Cycles";
41565
+ case "low_output":
41566
+ return "Low Output";
41567
+ default:
41568
+ return "";
41569
+ }
41570
+ };
41571
+ var getRedFlowDriversFromEvidence = (evidence) => {
41572
+ const drivers = /* @__PURE__ */ new Set();
41573
+ (evidence || []).forEach((item) => {
41574
+ const normalized = item.toLowerCase();
41575
+ if (normalized.includes("idle")) {
41576
+ drivers.add("idle");
41577
+ }
41578
+ if (normalized.includes("micro") || normalized.includes("gap")) {
41579
+ drivers.add("micro_stoppage");
41580
+ }
41581
+ if (normalized.includes("slow") || normalized.includes("cycle time") || normalized.includes("shift avg")) {
41582
+ drivers.add("slow_cycle");
41583
+ }
41584
+ if (normalized.includes("output")) {
41585
+ drivers.add("low_output");
41586
+ }
41587
+ });
41588
+ return Array.from(drivers);
41589
+ };
41590
+ var getRedFlowDisplayDriverKeys = (summary) => {
41591
+ if (!summary || summary.confidence !== "medium" && summary.confidence !== "high") {
41592
+ return [];
41593
+ }
41594
+ if (summary.primary_driver === "unknown") {
41595
+ return [];
41596
+ }
41597
+ if (summary.primary_driver === "mixed") {
41598
+ const evidenceDrivers = getRedFlowDriversFromEvidence(summary.evidence).filter((driver) => Boolean(getRedFlowDriverLabel(driver)));
41599
+ return evidenceDrivers.length >= 2 ? evidenceDrivers.slice(0, 3) : [];
41600
+ }
41601
+ return getRedFlowDriverLabel(summary.primary_driver) ? [summary.primary_driver] : [];
41602
+ };
41603
+ var formatRedFlowCompactNumber = (value) => Number.isInteger(value) ? String(value) : value.toFixed(1).replace(/\.0$/, "");
41604
+ var formatRedFlowOutputCount = (value) => Number.isFinite(value) ? String(Math.round(value)) : "";
41605
+ var getRedFlowBinOutputUnits = (bin) => {
41606
+ if (typeof bin.actual_output_units === "number" && Number.isFinite(bin.actual_output_units)) {
41607
+ return bin.actual_output_units;
41608
+ }
41609
+ if (typeof bin.actual_ppm === "number" && Number.isFinite(bin.actual_ppm)) {
41610
+ const durationSeconds = typeof bin.duration_seconds === "number" && Number.isFinite(bin.duration_seconds) && bin.duration_seconds > 0 ? bin.duration_seconds : 60;
41611
+ return bin.actual_ppm * durationSeconds / 60;
41612
+ }
41613
+ return null;
41614
+ };
41615
+ var summarizeRedFlowOutput = (timeline, summary) => {
41616
+ const actualFromSummary = summary?.totals.actual_output_units;
41617
+ const expectedFromSummary = summary?.totals.baseline_output_units;
41618
+ if (typeof actualFromSummary === "number" && Number.isFinite(actualFromSummary) && typeof expectedFromSummary === "number" && Number.isFinite(expectedFromSummary)) {
41619
+ return { actual: actualFromSummary, expected: expectedFromSummary };
41620
+ }
41621
+ let actual = 0;
41622
+ let expected = 0;
41623
+ let hasActual = false;
41624
+ let hasExpected = false;
41625
+ (timeline?.minute_bins || []).forEach((bin) => {
41626
+ const output = getRedFlowBinOutputUnits(bin);
41627
+ if (output !== null) {
41628
+ actual += output;
41629
+ hasActual = true;
41630
+ }
41631
+ if (typeof bin.target_ppm === "number" && Number.isFinite(bin.target_ppm)) {
41632
+ const durationSeconds = typeof bin.duration_seconds === "number" && Number.isFinite(bin.duration_seconds) && bin.duration_seconds > 0 ? bin.duration_seconds : 60;
41633
+ expected += bin.target_ppm * durationSeconds / 60;
41634
+ hasExpected = true;
41635
+ }
41636
+ });
41637
+ return hasActual && hasExpected ? { actual, expected } : null;
41638
+ };
41639
+ var getRedFlowOutputShortfallUnits = (timeline) => {
41640
+ let actual = 0;
41641
+ let expected = 0;
41642
+ let hasComparableBin = false;
41643
+ (timeline?.minute_bins || []).forEach((bin) => {
41644
+ const output = getRedFlowBinOutputUnits(bin);
41645
+ const durationSeconds = typeof bin.duration_seconds === "number" && Number.isFinite(bin.duration_seconds) && bin.duration_seconds > 0 ? bin.duration_seconds : null;
41646
+ if (output === null || durationSeconds === null || typeof bin.target_ppm !== "number" || !Number.isFinite(bin.target_ppm)) {
41647
+ return;
41648
+ }
41649
+ actual += output;
41650
+ expected += bin.target_ppm * durationSeconds / 60;
41651
+ hasComparableBin = true;
41652
+ });
41653
+ return hasComparableBin ? expected - actual : null;
41654
+ };
41519
41655
  var formatTime2 = (seconds) => {
41520
41656
  if (!seconds || isNaN(seconds)) return "0:00";
41521
41657
  const h = Math.floor(seconds / 3600);
@@ -41526,6 +41662,33 @@ var formatTime2 = (seconds) => {
41526
41662
  }
41527
41663
  return `${m}:${s.toString().padStart(2, "0")}`;
41528
41664
  };
41665
+ var formatTimelineClockTime = (isoTime, timezone) => {
41666
+ if (!isoTime) return "";
41667
+ const date = new Date(isoTime);
41668
+ if (Number.isNaN(date.getTime())) return "";
41669
+ return date.toLocaleTimeString("en-US", {
41670
+ hour: "numeric",
41671
+ minute: "2-digit",
41672
+ hour12: true,
41673
+ timeZone: timezone
41674
+ });
41675
+ };
41676
+ var formatCompactNumber = formatRedFlowCompactNumber;
41677
+ var formatTooltipSeconds = (value) => `${Math.round(value)}s`;
41678
+ var formatEfficiencyPercent = (value) => {
41679
+ if (typeof value !== "number" || !Number.isFinite(value)) {
41680
+ return "No output data";
41681
+ }
41682
+ return `${Math.round(value)}% efficient`;
41683
+ };
41684
+ var getBinOutputUnits = getRedFlowBinOutputUnits;
41685
+ var formatOutputLabel = (bin) => {
41686
+ const actualOutput = getBinOutputUnits(bin);
41687
+ if (actualOutput === null) {
41688
+ return "";
41689
+ }
41690
+ return `Output ${formatCompactNumber(actualOutput)}`;
41691
+ };
41529
41692
  var VideoControls = ({
41530
41693
  isPlaying,
41531
41694
  currentTime,
@@ -41544,15 +41707,20 @@ var VideoControls = ({
41544
41707
  onShare,
41545
41708
  isShareLoading = false,
41546
41709
  isShareCopied = false,
41710
+ timelineAnnotations,
41711
+ timelineExplanation,
41712
+ timelineTimezone,
41547
41713
  className = ""
41548
41714
  }) => {
41549
41715
  const [isDragging2, setIsDragging] = useState(false);
41550
41716
  const [dragTime, setDragTime] = useState(0);
41551
41717
  const [isHoveringProgressBar, setIsHoveringProgressBar] = useState(false);
41718
+ const [hoveredTimelineBin, setHoveredTimelineBin] = useState(null);
41552
41719
  const [showSpeedMenu, setShowSpeedMenu] = useState(false);
41553
41720
  const speedMenuRef = useRef(null);
41554
41721
  const progressTrackRef = useRef(null);
41555
41722
  const activePointerIdRef = useRef(null);
41723
+ const markerPointerJumpHandledRef = useRef(false);
41556
41724
  const progressColor = "#4b5563";
41557
41725
  const controlsVisible = showControls || controlsPinned;
41558
41726
  const isDraggingRef = useRef(false);
@@ -41576,6 +41744,43 @@ var VideoControls = ({
41576
41744
  isDraggingRef.current = false;
41577
41745
  onSeekEnd?.();
41578
41746
  };
41747
+ const handleTimelineJump = useCallback((time2) => {
41748
+ const nextTime = Math.min(Math.max(time2, 0), duration || time2);
41749
+ const wasDragging = isDraggingRef.current;
41750
+ activePointerIdRef.current = null;
41751
+ setIsDragging(false);
41752
+ isDraggingRef.current = false;
41753
+ setDragTime(nextTime);
41754
+ if (!wasDragging) {
41755
+ onSeekStart?.();
41756
+ }
41757
+ onSeek(nextTime);
41758
+ onSeekEnd?.();
41759
+ }, [duration, onSeek, onSeekEnd, onSeekStart]);
41760
+ const handleTimelineMarkerPointerDown = useCallback((e, time2) => {
41761
+ e.preventDefault();
41762
+ e.stopPropagation();
41763
+ markerPointerJumpHandledRef.current = true;
41764
+ handleTimelineJump(time2);
41765
+ }, [handleTimelineJump]);
41766
+ const handleTimelineMarkerMouseDown = useCallback((e, time2) => {
41767
+ e.preventDefault();
41768
+ e.stopPropagation();
41769
+ if (markerPointerJumpHandledRef.current) {
41770
+ return;
41771
+ }
41772
+ markerPointerJumpHandledRef.current = true;
41773
+ handleTimelineJump(time2);
41774
+ }, [handleTimelineJump]);
41775
+ const handleTimelineMarkerClick = useCallback((e, time2) => {
41776
+ e.preventDefault();
41777
+ e.stopPropagation();
41778
+ if (markerPointerJumpHandledRef.current) {
41779
+ markerPointerJumpHandledRef.current = false;
41780
+ return;
41781
+ }
41782
+ handleTimelineJump(time2);
41783
+ }, [handleTimelineJump]);
41579
41784
  const updateTimeFromClientX = useCallback((clientX) => {
41580
41785
  if (!progressTrackRef.current) return;
41581
41786
  const rect = progressTrackRef.current.getBoundingClientRect();
@@ -41636,6 +41841,127 @@ var VideoControls = ({
41636
41841
  const displayTime = isDragging2 ? dragTime : currentTime;
41637
41842
  const progressPercent = getPercentage(displayTime, duration);
41638
41843
  const bufferedPercent = getPercentage(buffered, duration);
41844
+ const timelineBins = useMemo(() => {
41845
+ if (!timelineAnnotations?.minute_bins?.length || duration <= 0) {
41846
+ return [];
41847
+ }
41848
+ return timelineAnnotations.minute_bins.map((bin) => {
41849
+ const offset = typeof bin.offset_seconds === "number" && Number.isFinite(bin.offset_seconds) ? Math.max(0, bin.offset_seconds) : 0;
41850
+ const binDuration = typeof bin.duration_seconds === "number" && Number.isFinite(bin.duration_seconds) && bin.duration_seconds > 0 ? bin.duration_seconds : 60;
41851
+ if (offset >= duration) {
41852
+ return null;
41853
+ }
41854
+ const clampedDuration = Math.min(binDuration, Math.max(0, duration - offset));
41855
+ if (clampedDuration <= 0) {
41856
+ return null;
41857
+ }
41858
+ const clockLabel = formatTimelineClockTime(bin.start_time, timelineTimezone);
41859
+ const minuteExplanation = timelineExplanation?.minute_explanations?.find((explanation) => explanation.offset_seconds === offset || Boolean(explanation.start_time) && explanation.start_time === bin.start_time);
41860
+ 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;
41861
+ return {
41862
+ ...bin,
41863
+ offset_seconds: offset,
41864
+ duration_seconds: clampedDuration,
41865
+ leftPercent: getPercentage(offset, duration),
41866
+ widthPercent: Math.max(getPercentage(clampedDuration, duration), 0.4),
41867
+ clockLabel,
41868
+ efficiencyLabel: formatEfficiencyPercent(bin.efficiency_percent),
41869
+ outputLabel: formatOutputLabel({ ...bin, duration_seconds: clampedDuration }),
41870
+ explanationLabel
41871
+ };
41872
+ }).filter((bin) => Boolean(bin));
41873
+ }, [duration, timelineAnnotations, timelineExplanation, timelineTimezone]);
41874
+ const hasTimelineAnnotations = timelineBins.length > 0;
41875
+ const worstMinuteMarkers = useMemo(() => {
41876
+ 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) => ({
41877
+ start_time: bin.start_time,
41878
+ offset_seconds: bin.offset_seconds,
41879
+ duration_seconds: bin.duration_seconds,
41880
+ avg_flow_percent: bin.avg_flow_percent,
41881
+ rank: index + 1
41882
+ }));
41883
+ 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);
41884
+ return source.filter((marker) => typeof marker.offset_seconds === "number" && Number.isFinite(marker.offset_seconds)).slice(0, 3).map((marker, index) => {
41885
+ const offset = Math.max(0, Math.min(duration, marker.offset_seconds));
41886
+ const matchingBin = timelineBins.find((bin) => bin.offset_seconds === marker.offset_seconds || Boolean(marker.start_time) && bin.start_time === marker.start_time);
41887
+ const markerDuration = "duration_seconds" in marker ? Number(marker.duration_seconds || 0) : 0;
41888
+ const width = markerDuration > 0 ? markerDuration : Number(matchingBin?.duration_seconds || 0);
41889
+ const centerOffset = Math.min(duration, offset + Math.max(0, width) / 2);
41890
+ return {
41891
+ ...marker,
41892
+ rank: "rank" in marker ? marker.rank : index + 1,
41893
+ leftPercent: getPercentage(centerOffset, duration)
41894
+ };
41895
+ });
41896
+ }, [duration, timelineAnnotations, timelineBins]);
41897
+ const transitionMarkers = useMemo(() => {
41898
+ if (timelineBins.length < 2 || duration <= 0) {
41899
+ return [];
41900
+ }
41901
+ const orderedBins = timelineBins.slice().sort((left, right) => left.offset_seconds - right.offset_seconds);
41902
+ return orderedBins.slice(1).map((bin, index) => {
41903
+ const previousBin = orderedBins[index];
41904
+ const fromOutputUnits = getBinOutputUnits(previousBin);
41905
+ const toOutputUnits = getBinOutputUnits(bin);
41906
+ const hasOutputValues = fromOutputUnits !== null && toOutputUnits !== null && fromOutputUnits > 0;
41907
+ const fromEfficiency = previousBin.efficiency_percent;
41908
+ const toEfficiency = bin.efficiency_percent;
41909
+ const hasEfficiencyValues = typeof fromEfficiency === "number" && typeof toEfficiency === "number" && Number.isFinite(fromEfficiency) && Number.isFinite(toEfficiency) && fromEfficiency > 0;
41910
+ if (!hasOutputValues && !hasEfficiencyValues) {
41911
+ return null;
41912
+ }
41913
+ const fromValue = hasOutputValues ? fromOutputUnits : fromEfficiency;
41914
+ const toValue2 = hasOutputValues ? toOutputUnits : toEfficiency;
41915
+ const relativeDrop = (fromValue - toValue2) / fromValue;
41916
+ if (relativeDrop <= 0.5) {
41917
+ return null;
41918
+ }
41919
+ const transitionOffset = Math.min(Math.max(bin.offset_seconds, 0), duration);
41920
+ return {
41921
+ offsetSeconds: transitionOffset,
41922
+ leftPercent: getPercentage(transitionOffset, duration),
41923
+ fromValue,
41924
+ toValue: toValue2,
41925
+ relativeDrop,
41926
+ fromOutputUnits,
41927
+ toOutputUnits,
41928
+ source: hasOutputValues ? "output" : "efficiency",
41929
+ absoluteDrop: fromValue - toValue2
41930
+ };
41931
+ }).filter((marker) => Boolean(marker)).sort((left, right) => {
41932
+ const relativeDiff = right.relativeDrop - left.relativeDrop;
41933
+ if (relativeDiff !== 0) {
41934
+ return relativeDiff;
41935
+ }
41936
+ const outputDiff = right.absoluteDrop - left.absoluteDrop;
41937
+ if (outputDiff !== 0) {
41938
+ return outputDiff;
41939
+ }
41940
+ return left.offsetSeconds - right.offsetSeconds;
41941
+ }).slice(0, 3).map((marker, index) => ({
41942
+ ...marker,
41943
+ rank: index + 1
41944
+ }));
41945
+ }, [duration, timelineBins]);
41946
+ worstMinuteMarkers[0] || null;
41947
+ const updateHoveredTimelineBin = useCallback((clientX) => {
41948
+ if (!hasTimelineAnnotations || !progressTrackRef.current || duration <= 0) {
41949
+ setHoveredTimelineBin(null);
41950
+ return;
41951
+ }
41952
+ const rect = progressTrackRef.current.getBoundingClientRect();
41953
+ if (!rect.width) {
41954
+ setHoveredTimelineBin(null);
41955
+ return;
41956
+ }
41957
+ const pct = Math.min(Math.max((clientX - rect.left) / rect.width, 0), 1);
41958
+ const hoverTime = pct * duration;
41959
+ const nextBin = timelineBins.find((bin) => hoverTime >= bin.offset_seconds && hoverTime <= bin.offset_seconds + bin.duration_seconds) || null;
41960
+ setHoveredTimelineBin(nextBin);
41961
+ }, [duration, hasTimelineAnnotations, timelineBins]);
41962
+ const handleProgressMouseMove = useCallback((e) => {
41963
+ updateHoveredTimelineBin(e.clientX);
41964
+ }, [updateHoveredTimelineBin]);
41639
41965
  return /* @__PURE__ */ jsxs(
41640
41966
  "div",
41641
41967
  {
@@ -41647,12 +41973,16 @@ var VideoControls = ({
41647
41973
  "div",
41648
41974
  {
41649
41975
  ref: progressTrackRef,
41650
- className: "relative h-1 mb-4 group cursor-pointer",
41976
+ className: "relative z-10 h-1 mb-4 group cursor-pointer",
41651
41977
  onMouseEnter: () => setIsHoveringProgressBar(true),
41652
- onMouseLeave: () => setIsHoveringProgressBar(false),
41978
+ onMouseMove: handleProgressMouseMove,
41979
+ onMouseLeave: () => {
41980
+ setIsHoveringProgressBar(false);
41981
+ setHoveredTimelineBin(null);
41982
+ },
41653
41983
  onPointerDown: handlePointerDown,
41654
41984
  children: [
41655
- /* @__PURE__ */ jsx("div", { className: "absolute -top-4 -bottom-4 left-0 right-0 z-20" }),
41985
+ /* @__PURE__ */ jsx("div", { className: "absolute -top-4 bottom-0 left-0 right-0 z-20" }),
41656
41986
  /* @__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(
41657
41987
  "div",
41658
41988
  {
@@ -41686,17 +42016,47 @@ var VideoControls = ({
41686
42016
  onInput: handleSeekChange,
41687
42017
  onMouseDown: handleSeekStart,
41688
42018
  onMouseUp: handleSeekEnd,
42019
+ onMouseMove: handleProgressMouseMove,
41689
42020
  onTouchStart: handleSeekStart,
41690
42021
  onTouchEnd: handleSeekEnd,
41691
42022
  onPointerDown: handlePointerDown,
41692
- className: "absolute left-0 right-0 top-[-12px] bottom-[-12px] w-full h-auto opacity-0 cursor-pointer z-30 margin-0 padding-0"
42023
+ className: "absolute left-0 right-0 top-[-12px] bottom-0 w-full h-auto opacity-0 cursor-pointer z-30 margin-0 padding-0"
42024
+ }
42025
+ ),
42026
+ hasTimelineAnnotations && transitionMarkers.map((marker) => /* @__PURE__ */ jsx(
42027
+ "button",
42028
+ {
42029
+ type: "button",
42030
+ "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)`,
42031
+ title: marker.source === "output" ? `Output drop: ${formatCompactNumber(marker.fromValue)} to ${formatCompactNumber(marker.toValue)}` : `Output drop: ${Math.round(marker.fromValue)}% to ${Math.round(marker.toValue)}%`,
42032
+ onPointerDownCapture: (e) => handleTimelineMarkerPointerDown(e, marker.offsetSeconds),
42033
+ onMouseDownCapture: (e) => handleTimelineMarkerMouseDown(e, marker.offsetSeconds),
42034
+ onClickCapture: (e) => handleTimelineMarkerClick(e, marker.offsetSeconds),
42035
+ 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",
42036
+ style: { left: `calc(${marker.leftPercent}% - 10px)`, zIndex: 70, pointerEvents: "auto" },
42037
+ children: marker.rank
42038
+ },
42039
+ `${marker.rank}-${marker.offsetSeconds}`
42040
+ )),
42041
+ hasTimelineAnnotations && hoveredTimelineBin && /* @__PURE__ */ jsxs(
42042
+ "div",
42043
+ {
42044
+ 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",
42045
+ style: { left: `${hoveredTimelineBin.leftPercent + hoveredTimelineBin.widthPercent / 2}%` },
42046
+ children: [
42047
+ hoveredTimelineBin.clockLabel || formatTime2(hoveredTimelineBin.offset_seconds),
42048
+ " | ",
42049
+ hoveredTimelineBin.efficiencyLabel,
42050
+ hoveredTimelineBin.outputLabel ? ` | ${hoveredTimelineBin.outputLabel}` : "",
42051
+ hoveredTimelineBin.explanationLabel ? ` | ${hoveredTimelineBin.explanationLabel}` : ""
42052
+ ]
41693
42053
  }
41694
42054
  )
41695
42055
  ]
41696
42056
  }
41697
42057
  ),
41698
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-white", children: [
41699
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
42058
+ /* @__PURE__ */ jsxs("div", { className: "relative z-40 flex items-center justify-between text-white", children: [
42059
+ /* @__PURE__ */ jsxs("div", { className: "relative z-50 flex items-center gap-4", children: [
41700
42060
  /* @__PURE__ */ jsx(
41701
42061
  "button",
41702
42062
  {
@@ -41977,7 +42337,10 @@ var HlsVideoPlayer = forwardRef(({
41977
42337
  onClick,
41978
42338
  onShare,
41979
42339
  isShareLoading,
41980
- isShareCopied
42340
+ isShareCopied,
42341
+ timelineAnnotations,
42342
+ timelineExplanation,
42343
+ timelineTimezone
41981
42344
  }, ref) => {
41982
42345
  const supabase = useSupabase();
41983
42346
  const videoContainerRef = useRef(null);
@@ -42639,6 +43002,7 @@ var HlsVideoPlayer = forwardRef(({
42639
43002
  const handleSeek = useCallback((time2) => {
42640
43003
  if (videoRef.current) {
42641
43004
  videoRef.current.currentTime = time2;
43005
+ setCurrentTime(time2);
42642
43006
  }
42643
43007
  }, []);
42644
43008
  const handleSeekStart = useCallback(() => {
@@ -42745,7 +43109,10 @@ var HlsVideoPlayer = forwardRef(({
42745
43109
  onToggleFullscreen: handleToggleFullscreen,
42746
43110
  onShare,
42747
43111
  isShareLoading,
42748
- isShareCopied
43112
+ isShareCopied,
43113
+ timelineAnnotations,
43114
+ timelineExplanation,
43115
+ timelineTimezone
42749
43116
  }
42750
43117
  )
42751
43118
  ]
@@ -43066,6 +43433,7 @@ var CroppedHlsVideoPlayer = forwardRef(({
43066
43433
  const handleSeek = useCallback((time2) => {
43067
43434
  if (hiddenVideoRef.current) {
43068
43435
  hiddenVideoRef.current.currentTime(time2);
43436
+ setCurrentTime(time2);
43069
43437
  setTimeout(() => renderFrameToCanvas(), 50);
43070
43438
  userSeekingRef.current = true;
43071
43439
  }
@@ -43211,7 +43579,10 @@ var CroppedHlsVideoPlayer = forwardRef(({
43211
43579
  onToggleFullscreen: handleToggleFullscreen,
43212
43580
  onShare: videoProps.onShare,
43213
43581
  isShareLoading: videoProps.isShareLoading,
43214
- isShareCopied: videoProps.isShareCopied
43582
+ isShareCopied: videoProps.isShareCopied,
43583
+ timelineAnnotations: videoProps.timelineAnnotations,
43584
+ timelineExplanation: videoProps.timelineExplanation,
43585
+ timelineTimezone: videoProps.timelineTimezone
43215
43586
  }
43216
43587
  )
43217
43588
  ]
@@ -43220,6 +43591,100 @@ var CroppedHlsVideoPlayer = forwardRef(({
43220
43591
  });
43221
43592
  CroppedHlsVideoPlayer.displayName = "CroppedHlsVideoPlayer";
43222
43593
  var CroppedVideoPlayer = CroppedHlsVideoPlayer;
43594
+ var formatSeconds = (value) => {
43595
+ const seconds = Math.max(0, Math.round(value));
43596
+ if (seconds < 60) {
43597
+ return `${seconds}s`;
43598
+ }
43599
+ const minutes = Math.floor(seconds / 60);
43600
+ const remainingSeconds = seconds % 60;
43601
+ return remainingSeconds > 0 ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
43602
+ };
43603
+ var buildLostChip = (explanation) => {
43604
+ const totals = explanation.summary.totals;
43605
+ const explicitTotalLostSeconds = Number(totals.total_lost_seconds);
43606
+ const lostSeconds = Number.isFinite(explicitTotalLostSeconds) ? explicitTotalLostSeconds : Math.max(
43607
+ Number(totals.idle_overlap_seconds) || 0,
43608
+ Number(totals.micro_stoppage_lost_seconds) || 0,
43609
+ Number(totals.slow_cycle_lost_seconds) || 0
43610
+ );
43611
+ if (lostSeconds > 0) {
43612
+ return `${formatSeconds(lostSeconds)} lost`;
43613
+ }
43614
+ if (Number(totals.idle_overlap_percent) > 0) {
43615
+ return `${Math.round(totals.idle_overlap_percent)}% idle`;
43616
+ }
43617
+ return null;
43618
+ };
43619
+ var RedFlowDiagnosticOverlay = ({
43620
+ timeline,
43621
+ explanation,
43622
+ aiSummary,
43623
+ aiSummaryLoading = false,
43624
+ aiSummaryError = null,
43625
+ className = ""
43626
+ }) => {
43627
+ const summary = explanation?.summary || null;
43628
+ const driverKeys = useMemo(() => getRedFlowDisplayDriverKeys(summary), [summary]);
43629
+ const outputSummary = useMemo(() => summarizeRedFlowOutput(timeline, summary), [summary, timeline]);
43630
+ const hasOutputIssue = Boolean(
43631
+ outputSummary && Number.isFinite(outputSummary.expected) && Number.isFinite(outputSummary.actual) && outputSummary.expected > outputSummary.actual
43632
+ );
43633
+ if (driverKeys.length === 0 && !hasOutputIssue) {
43634
+ return null;
43635
+ }
43636
+ const driverLabel = driverKeys.length > 0 ? driverKeys.map(getRedFlowDriverLabel).filter(Boolean).join(" + ") : "Low Output";
43637
+ if (!driverLabel) {
43638
+ return null;
43639
+ }
43640
+ const shouldShowLostChip = driverKeys.some((driver) => driver !== "low_output");
43641
+ const chips = explanation && shouldShowLostChip ? [buildLostChip(explanation)].filter((chip) => Boolean(chip)) : [];
43642
+ const shouldShowHeadline = Boolean(summary && driverKeys.length > 0 && summary.primary_driver !== "unknown");
43643
+ const aiSummaryBullets = Array.isArray(aiSummary?.bullets) ? aiSummary.bullets.map((bullet) => String(bullet || "").trim()).filter(Boolean).slice(0, 3) : [];
43644
+ const shouldShowAiSummary = !aiSummaryError && aiSummaryBullets.length === 3;
43645
+ return /* @__PURE__ */ jsxs(
43646
+ "div",
43647
+ {
43648
+ className: `pointer-events-none absolute z-20 w-[240px] max-w-[calc(100%-2rem)] rounded-xl border border-white/10 bg-black/60 p-5 text-white shadow-xl backdrop-blur-md ${className}`,
43649
+ children: [
43650
+ outputSummary ? /* @__PURE__ */ jsxs("div", { className: "mb-5 space-y-4", children: [
43651
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
43652
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-white/50", children: "Output:" }),
43653
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-bold text-white", children: [
43654
+ /* @__PURE__ */ jsx("span", { className: "text-red-400", children: formatRedFlowOutputCount(outputSummary.actual) }),
43655
+ /* @__PURE__ */ jsx("span", { className: "px-1 text-white/30", children: "/" }),
43656
+ formatRedFlowOutputCount(outputSummary.expected)
43657
+ ] })
43658
+ ] }),
43659
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
43660
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-white/50", children: "Reason:" }),
43661
+ /* @__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" })
43662
+ ] })
43663
+ ] }) : /* @__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 }) }),
43664
+ (shouldShowAiSummary || aiSummaryLoading || chips.length > 0 || shouldShowHeadline) && /* @__PURE__ */ jsx("div", { className: "mb-4 h-px w-full bg-white/10" }),
43665
+ !shouldShowAiSummary && !aiSummaryLoading && shouldShowHeadline && summary?.headline ? /* @__PURE__ */ jsx("div", { className: "mb-3 text-[13px] font-medium leading-relaxed text-white/90", children: summary.headline }) : null,
43666
+ !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(
43667
+ "span",
43668
+ {
43669
+ className: "rounded border border-white/10 bg-white/5 px-2 py-0.5 text-[11px] font-medium text-white/70",
43670
+ children: chip
43671
+ },
43672
+ chip
43673
+ )) }) : null,
43674
+ shouldShowAiSummary ? /* @__PURE__ */ jsxs("div", { className: "mt-1", children: [
43675
+ /* @__PURE__ */ jsx("div", { className: "mb-3 text-[10px] font-bold uppercase tracking-[0.15em] text-white/40", children: "AI summary" }),
43676
+ /* @__PURE__ */ jsx("ol", { className: "space-y-3 text-[12px] leading-relaxed text-white/80", children: aiSummaryBullets.map((bullet, index) => /* @__PURE__ */ jsxs("li", { className: "flex gap-2", children: [
43677
+ /* @__PURE__ */ jsxs("span", { className: "font-semibold text-white/40", children: [
43678
+ index + 1,
43679
+ "."
43680
+ ] }),
43681
+ /* @__PURE__ */ jsx("span", { children: bullet })
43682
+ ] }, `${index}-${bullet}`)) })
43683
+ ] }) : aiSummaryLoading ? /* @__PURE__ */ jsx("div", { className: "mt-1 text-[13px] font-medium text-white/60", children: "Generating summary..." }) : null
43684
+ ]
43685
+ }
43686
+ );
43687
+ };
43223
43688
  function useWorkspaceCrop(workspaceId) {
43224
43689
  const supabase = useSupabase();
43225
43690
  const [crop, setCrop] = useState(null);
@@ -43269,7 +43734,7 @@ function Skeleton({ className, ...props }) {
43269
43734
  var Select = SelectPrimitive.Root;
43270
43735
  var SelectGroup = SelectPrimitive.Group;
43271
43736
  var SelectValue = SelectPrimitive.Value;
43272
- var SelectTrigger = React147.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
43737
+ var SelectTrigger = React148.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
43273
43738
  SelectPrimitive.Trigger,
43274
43739
  {
43275
43740
  ref,
@@ -43285,7 +43750,7 @@ var SelectTrigger = React147.forwardRef(({ className, children, ...props }, ref)
43285
43750
  }
43286
43751
  ));
43287
43752
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
43288
- var SelectScrollUpButton = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43753
+ var SelectScrollUpButton = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43289
43754
  SelectPrimitive.ScrollUpButton,
43290
43755
  {
43291
43756
  ref,
@@ -43295,7 +43760,7 @@ var SelectScrollUpButton = React147.forwardRef(({ className, ...props }, ref) =>
43295
43760
  }
43296
43761
  ));
43297
43762
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
43298
- var SelectScrollDownButton = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43763
+ var SelectScrollDownButton = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43299
43764
  SelectPrimitive.ScrollDownButton,
43300
43765
  {
43301
43766
  ref,
@@ -43305,7 +43770,7 @@ var SelectScrollDownButton = React147.forwardRef(({ className, ...props }, ref)
43305
43770
  }
43306
43771
  ));
43307
43772
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
43308
- var SelectContent = React147.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
43773
+ var SelectContent = React148.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
43309
43774
  SelectPrimitive.Content,
43310
43775
  {
43311
43776
  ref,
@@ -43333,7 +43798,7 @@ var SelectContent = React147.forwardRef(({ className, children, position = "popp
43333
43798
  }
43334
43799
  ) }));
43335
43800
  SelectContent.displayName = SelectPrimitive.Content.displayName;
43336
- var SelectLabel = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43801
+ var SelectLabel = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43337
43802
  SelectPrimitive.Label,
43338
43803
  {
43339
43804
  ref,
@@ -43342,7 +43807,7 @@ var SelectLabel = React147.forwardRef(({ className, ...props }, ref) => /* @__PU
43342
43807
  }
43343
43808
  ));
43344
43809
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
43345
- var SelectItem = React147.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
43810
+ var SelectItem = React148.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
43346
43811
  SelectPrimitive.Item,
43347
43812
  {
43348
43813
  ref,
@@ -43358,7 +43823,7 @@ var SelectItem = React147.forwardRef(({ className, children, ...props }, ref) =>
43358
43823
  }
43359
43824
  ));
43360
43825
  SelectItem.displayName = SelectPrimitive.Item.displayName;
43361
- var SelectSeparator = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43826
+ var SelectSeparator = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43362
43827
  SelectPrimitive.Separator,
43363
43828
  {
43364
43829
  ref,
@@ -43984,7 +44449,7 @@ var TimePickerDropdown = ({
43984
44449
  )
43985
44450
  ] });
43986
44451
  };
43987
- var SilentErrorBoundary = class extends React147__default.Component {
44452
+ var SilentErrorBoundary = class extends React148__default.Component {
43988
44453
  constructor(props) {
43989
44454
  super(props);
43990
44455
  this.handleClearAndReload = () => {
@@ -44729,6 +45194,9 @@ var AvatarUpload = ({
44729
45194
  ] });
44730
45195
  };
44731
45196
  var CLIP_METADATA_PAGE_SIZE = 50;
45197
+ var RECENT_FLOW_RED_STREAK_CLIP_TYPE2 = "recent_flow_red_streak";
45198
+ var RECENT_FLOW_RED_STREAK_DISPLAY_LABEL = "Low moments";
45199
+ var RECENT_FLOW_RED_STREAK_DISPLAY_SUBTITLE = "Moments of low efficiency";
44732
45200
  var parseCycleTime = (value) => {
44733
45201
  if (typeof value === "number" && Number.isFinite(value)) {
44734
45202
  return value;
@@ -44757,10 +45225,37 @@ var formatDurationLabel = (seconds) => {
44757
45225
  }
44758
45226
  return `${Math.round(roundedSeconds / 60)} min`;
44759
45227
  };
45228
+ var sortRedFlowMetadata = (clips) => {
45229
+ return clips.slice().sort((left, right) => {
45230
+ const getOutputShortfall = (clip) => {
45231
+ const directShortfall = parseCycleTime(clip.red_flow_output_shortfall_units);
45232
+ if (directShortfall !== null) {
45233
+ return directShortfall;
45234
+ }
45235
+ return getRedFlowOutputShortfallUnits(clip.red_flow_timeline);
45236
+ };
45237
+ const leftScore = getOutputShortfall(left);
45238
+ const rightScore = getOutputShortfall(right);
45239
+ const leftNull = leftScore === null;
45240
+ const rightNull = rightScore === null;
45241
+ if (leftNull !== rightNull) {
45242
+ return leftNull ? 1 : -1;
45243
+ }
45244
+ if (leftScore !== null && rightScore !== null && leftScore !== rightScore) {
45245
+ return rightScore - leftScore;
45246
+ }
45247
+ const leftTime = new Date(left.clip_timestamp).getTime();
45248
+ const rightTime = new Date(right.clip_timestamp).getTime();
45249
+ return (Number.isFinite(rightTime) ? rightTime : 0) - (Number.isFinite(leftTime) ? leftTime : 0);
45250
+ });
45251
+ };
44760
45252
  var getSeverityIcon = (severity, categoryId, cycleTimeSeconds, targetCycleTime, clipId) => {
44761
45253
  if (categoryId === "idle_time" || categoryId === "low_value" || categoryId === "longest-idles") {
44762
45254
  return null;
44763
45255
  }
45256
+ if (categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
45257
+ return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3 w-3 text-red-500" });
45258
+ }
44764
45259
  if (categoryId === "cycle_completion" && targetCycleTime && targetCycleTime > 0 && cycleTimeSeconds !== null && cycleTimeSeconds !== void 0) {
44765
45260
  if (cycleTimeSeconds <= targetCycleTime) {
44766
45261
  return /* @__PURE__ */ jsx(CheckCircle, { className: "h-3 w-3 text-green-500" });
@@ -44832,6 +45327,7 @@ var FileManagerFilters = ({
44832
45327
  idleTimeVlmEnabled = false,
44833
45328
  showPercentileCycleFilters = true,
44834
45329
  prefetchedClipMetadata,
45330
+ externallyManagedLoadingCategories,
44835
45331
  activeCategoryLoading,
44836
45332
  idleClipSort = "latest",
44837
45333
  onIdleClipSortChange,
@@ -44916,11 +45412,11 @@ var FileManagerFilters = ({
44916
45412
  if (prefetchedClipMetadata && Array.isArray(prefetchedClipMetadata[categoryId]) && prefetchedClipMetadata[categoryId].length > 0) {
44917
45413
  return true;
44918
45414
  }
44919
- if (activeCategoryLoading !== void 0 && categoryId === activeFilter) {
45415
+ if (externallyManagedLoadingCategories?.[categoryId]) {
44920
45416
  return true;
44921
45417
  }
44922
45418
  return false;
44923
- }, [prefetchedClipMetadata, activeCategoryLoading, activeFilter]);
45419
+ }, [prefetchedClipMetadata, externallyManagedLoadingCategories]);
44924
45420
  useEffect(() => {
44925
45421
  if (!prefetchedClipMetadata) {
44926
45422
  return;
@@ -45041,6 +45537,9 @@ var FileManagerFilters = ({
45041
45537
  [idleReasonOptions, idleLabelFilter]
45042
45538
  );
45043
45539
  const getClipBadge = useCallback((node) => {
45540
+ if (node.categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
45541
+ return null;
45542
+ }
45044
45543
  if (node.categoryId === "idle_time" || node.categoryId === "low_value") {
45045
45544
  return { text: "Idle", className: "bg-red-100 text-red-700" };
45046
45545
  }
@@ -45059,6 +45558,23 @@ var FileManagerFilters = ({
45059
45558
  }
45060
45559
  return { text: "Fast", className: "bg-green-100 text-green-700" };
45061
45560
  }, [resolvedTargetCycleTime]);
45561
+ const getRedFlowDriverBadges = useCallback((node) => {
45562
+ if (node.categoryId !== RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
45563
+ return [];
45564
+ }
45565
+ const summary = node.redFlowExplanationSummary || null;
45566
+ const drivers = getRedFlowDisplayDriverKeys(summary);
45567
+ if (drivers.length === 0) {
45568
+ return [{
45569
+ text: "Low Output",
45570
+ className: "bg-slate-50 text-slate-600 border border-slate-200"
45571
+ }];
45572
+ }
45573
+ return drivers.slice(0, 3).map((driver) => ({
45574
+ text: getRedFlowDriverLabel(driver),
45575
+ className: "bg-rose-50 text-rose-700 border border-rose-200"
45576
+ }));
45577
+ }, []);
45062
45578
  const getAuthToken4 = useCallback(async () => {
45063
45579
  try {
45064
45580
  return await getAccessTokenOrRedirect(supabase, { redirectReason: "session_expired" });
@@ -45067,7 +45583,7 @@ var FileManagerFilters = ({
45067
45583
  return null;
45068
45584
  }
45069
45585
  }, [supabase]);
45070
- const getMetadataLoadingKey = useCallback((categoryId, page) => `${categoryId}-${page}-${categoryId === "idle_time" ? idleClipSort : "latest"}`, [idleClipSort]);
45586
+ const getMetadataLoadingKey = useCallback((categoryId, page) => `${categoryId}-${page}-${categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest"}`, [idleClipSort]);
45071
45587
  const fetchClipMetadataPage = useCallback(async (categoryId, page = 1) => {
45072
45588
  if (!workspaceId || !date || shift === void 0) {
45073
45589
  throw new Error("Missing required params for clip metadata fetch");
@@ -45088,7 +45604,7 @@ var FileManagerFilters = ({
45088
45604
  knownTotal: typeof counts?.[categoryId] === "number" ? counts[categoryId] : null,
45089
45605
  snapshotDateTime,
45090
45606
  snapshotClipId,
45091
- sort: categoryId === "idle_time" ? idleClipSort : "latest"
45607
+ sort: categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest"
45092
45608
  }),
45093
45609
  redirectReason: "session_expired"
45094
45610
  });
@@ -45459,7 +45975,7 @@ var FileManagerFilters = ({
45459
45975
  fetchClipMetadata(activeFilter, 1);
45460
45976
  }
45461
45977
  }
45462
- }, [activeFilter, isCategoryExternallyManaged]);
45978
+ }, [activeFilter]);
45463
45979
  useEffect(() => {
45464
45980
  const handleEscape = (e) => {
45465
45981
  if (e.key === "Escape") {
@@ -45542,6 +46058,9 @@ var FileManagerFilters = ({
45542
46058
  const categoryCount = counts?.[category.id] || 0;
45543
46059
  const categoryClips = clipMetadata[category.id] || [];
45544
46060
  let filteredClips = categoryClips.filter((clip) => isClipInTimeRange(clip.clip_timestamp));
46061
+ if (category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
46062
+ filteredClips = sortRedFlowMetadata(filteredClips);
46063
+ }
45545
46064
  if (category.id === "idle_time" && idleLabelFilter) {
45546
46065
  filteredClips = filteredClips.filter((clip) => {
45547
46066
  const classification = getIdleTimeClassification(clip.clipId || clip.id);
@@ -45556,15 +46075,18 @@ var FileManagerFilters = ({
45556
46075
  const cycleTime = extractCycleTimeSeconds(clip);
45557
46076
  const idleDuration = category.id === "idle_time" ? clip.idle_duration_seconds ?? clip.duration : null;
45558
46077
  const idleDurationLabel = formatDurationLabel(idleDuration);
46078
+ const redFlowDurationLabel = category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? formatDurationLabel(clip.duration) : null;
45559
46079
  const baseTimeLabel = formatClipExplorerTimeLabel({
45560
46080
  categoryId: category.id,
45561
46081
  clipTimestamp: clip.clip_timestamp,
45562
46082
  timezone,
45563
46083
  durationSeconds: idleDuration ?? clip.duration,
45564
46084
  idleStartTime: clip.idle_start_time,
45565
- idleEndTime: clip.idle_end_time
46085
+ idleEndTime: clip.idle_end_time,
46086
+ clipStartTime: clip.clip_start_time,
46087
+ clipEndTime: clip.clip_end_time
45566
46088
  });
45567
- const displayLabel = `${baseTimeLabel}${idleDurationLabel && category.id === "idle_time" ? ` - (${idleDurationLabel})` : ""}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
46089
+ const displayLabel = `${baseTimeLabel}${idleDurationLabel && category.id === "idle_time" ? ` - (${idleDurationLabel})` : ""}${redFlowDurationLabel ? ` - (${redFlowDurationLabel})` : ""}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" && category.id !== RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
45568
46090
  return {
45569
46091
  id: clip.id,
45570
46092
  label: displayLabel,
@@ -45580,14 +46102,18 @@ var FileManagerFilters = ({
45580
46102
  cycleTimeSeconds: cycleTime,
45581
46103
  duration: idleDuration ?? clip.duration,
45582
46104
  // Store duration for custom badge rendering
45583
- cycleItemCount: clip.cycle_item_count ?? null
46105
+ cycleItemCount: clip.cycle_item_count ?? null,
46106
+ redFlowSeverityScore: clip.red_flow_severity_score ?? null,
46107
+ redFlowExplanationSummary: clip.red_flow_explanation_summary ?? clip.red_flow_explanation?.summary ?? null
45584
46108
  };
45585
46109
  });
46110
+ const categoryLabel = category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? RECENT_FLOW_RED_STREAK_DISPLAY_LABEL : category.label;
46111
+ const categorySubtitle = category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? RECENT_FLOW_RED_STREAK_DISPLAY_SUBTITLE : category.subtitle || category.description;
45586
46112
  regularCategoryNodes.push({
45587
46113
  id: category.id,
45588
- label: category.label,
45589
- subtitle: category.subtitle || category.description,
45590
- description: category.description,
46114
+ label: categoryLabel,
46115
+ subtitle: categorySubtitle,
46116
+ description: category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? RECENT_FLOW_RED_STREAK_DISPLAY_SUBTITLE : category.description,
45591
46117
  type: "category",
45592
46118
  count: displayCount,
45593
46119
  // Use filtered count when time filter is active
@@ -45699,7 +46225,7 @@ var FileManagerFilters = ({
45699
46225
  })
45700
46226
  } */
45701
46227
  ] : [];
45702
- const orderedIds = ["cycle_completion", "fast-cycles", "slow-cycles", "idle_time"];
46228
+ const orderedIds = [RECENT_FLOW_RED_STREAK_CLIP_TYPE2, "cycle_completion", "fast-cycles", "slow-cycles", "idle_time"];
45703
46229
  orderedIds.forEach((orderedId) => {
45704
46230
  const percentileCategory = percentileCategories.find((cat) => cat.id === orderedId);
45705
46231
  const shouldIncludePercentile = percentileCategory ? typeof percentileCategory.count === "number" && percentileCategory.count > 0 : false;
@@ -45788,6 +46314,13 @@ var FileManagerFilters = ({
45788
46314
  shift,
45789
46315
  count: node.count || 0
45790
46316
  });
46317
+ } else if (node.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
46318
+ trackCoreEvent("Low Moments Clicked", {
46319
+ workspaceId,
46320
+ date,
46321
+ shift,
46322
+ count: node.count || 0
46323
+ });
45791
46324
  }
45792
46325
  if (node.id !== "idle_time" && idleLabelFilter) {
45793
46326
  setIdleLabelFilter(null);
@@ -45812,8 +46345,15 @@ var FileManagerFilters = ({
45812
46345
  const isCurrentVideo = currentVideoId === node.id;
45813
46346
  const isCountUnknown = node.type === "percentile-category" && node.count === null;
45814
46347
  const hasChildren = isCountUnknown || (node.count || 0) > 0;
45815
- const showExternalLoadingState = Boolean(
45816
- activeCategoryLoading && isExpanded && node.id === activeFilter && (node.type === "category" || node.type === "percentile-category")
46348
+ const hasLoadedChildren = (clipMetadata[node.id]?.length || percentileClips[node.id]?.length || 0) > 0;
46349
+ const loadedPage = categoryPages[node.id] || 0;
46350
+ const pageOneLoadingKey = getMetadataLoadingKey(node.id, 1);
46351
+ const nextMetadataPage = loadedPage + 1;
46352
+ const nextLoadMorePage = (categoryPages[node.id] || 1) + 1;
46353
+ const isPageOneLoading = loadingCategories.has(pageOneLoadingKey);
46354
+ const isLoadMoreLoading = loadedPage > 0 && loadingCategories.has(getMetadataLoadingKey(node.id, nextMetadataPage));
46355
+ const showInitialLoadingState = Boolean(
46356
+ isExpanded && !hasLoadedChildren && (node.type === "category" || node.type === "percentile-category") && (isPageOneLoading || activeCategoryLoading && node.id === activeFilter)
45817
46357
  );
45818
46358
  const colorClasses = node.color ? getColorClasses(node.color) : null;
45819
46359
  return /* @__PURE__ */ jsxs("div", { className: "select-none animate-in", children: [
@@ -45855,9 +46395,9 @@ var FileManagerFilters = ({
45855
46395
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 flex items-center justify-between", children: [
45856
46396
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
45857
46397
  /* @__PURE__ */ jsx("div", { className: `font-semibold tracking-tight ${node.type === "category" || node.type === "percentile-category" ? "text-slate-800 text-sm" : "text-slate-700 text-xs"} ${isCurrentVideo ? "text-blue-700 font-bold" : ""} group-hover:text-slate-900 transition-colors duration-200`, children: node.label }),
45858
- node.type === "category" && categories.find((c) => c.id === node.id)?.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: categories.find((c) => c.id === node.id)?.description }),
46398
+ node.type === "category" && (node.subtitle || categories.find((c) => c.id === node.id)?.description) && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: node.subtitle || categories.find((c) => c.id === node.id)?.description }),
45859
46399
  node.type === "percentile-category" && node.subtitle && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: node.subtitle }),
45860
- node.type === "video" && (node.severity || node.categoryId === "cycle_completion" || node.categoryId === "idle_time" || node.categoryId === "low_value") && /* @__PURE__ */ jsx("div", { className: "text-xs mt-0.5 font-medium", children: node.categoryId === "idle_time" ? (
46400
+ node.type === "video" && (node.severity || node.categoryId === "cycle_completion" || node.categoryId === "idle_time" || node.categoryId === "low_value" || node.categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) && /* @__PURE__ */ jsx("div", { className: "text-xs mt-0.5 font-medium", children: node.categoryId === "idle_time" ? (
45861
46401
  // Show root cause label for idle time clips (text only, icon is on the left)
45862
46402
  (() => {
45863
46403
  if (!idleTimeVlmEnabled) {
@@ -45879,8 +46419,10 @@ var FileManagerFilters = ({
45879
46419
  // Show badge for other clips
45880
46420
  (() => {
45881
46421
  const badge = getClipBadge(node);
46422
+ const redFlowDriverBadges = getRedFlowDriverBadges(node);
45882
46423
  return /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1.5", children: [
45883
- /* @__PURE__ */ jsx("span", { className: `inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-medium ${badge.className}`, children: badge.text }),
46424
+ badge ? /* @__PURE__ */ jsx("span", { className: `inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-medium ${badge.className}`, children: badge.text }) : null,
46425
+ redFlowDriverBadges.map((redFlowDriverBadge) => /* @__PURE__ */ jsx("span", { className: `inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-medium ${redFlowDriverBadge.className}`, children: redFlowDriverBadge.text }, redFlowDriverBadge.text)),
45884
46426
  node.categoryId === "cycle_completion" && node.cycleItemCount && node.cycleItemCount > 1 ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-semibold bg-blue-100 text-blue-700 border border-blue-200", children: [
45885
46427
  "x",
45886
46428
  node.cycleItemCount
@@ -45896,21 +46438,20 @@ var FileManagerFilters = ({
45896
46438
  ),
45897
46439
  hasChildren && isExpanded && (node.type === "category" || node.type === "percentile-category") && /* @__PURE__ */ jsx("div", { className: "mt-2 ml-3 animate-in border-l-2 border-slate-100 pl-3", children: /* @__PURE__ */ jsxs("div", { className: "max-h-64 overflow-y-auto space-y-1 scrollbar-thin scrollbar-track-slate-100 scrollbar-thumb-slate-300", children: [
45898
46440
  node.children.map((child) => renderNode(child, depth + 1)),
45899
- showExternalLoadingState && /* @__PURE__ */ jsx("div", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center text-sm text-slate-500", children: [
46441
+ showInitialLoadingState && /* @__PURE__ */ jsx("div", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center text-sm text-slate-500", children: [
45900
46442
  /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
45901
46443
  "Loading clips..."
45902
46444
  ] }) }),
45903
- loadingCategories.has(getMetadataLoadingKey(node.id, (categoryPages[node.id] || 0) + 1)) && /* @__PURE__ */ jsx("div", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center text-sm text-slate-500", children: [
46445
+ isLoadMoreLoading && /* @__PURE__ */ jsx("div", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center text-sm text-slate-500", children: [
45904
46446
  /* @__PURE__ */ jsx("div", { className: "animate-spin mr-2 h-4 w-4 border-2 border-slate-300 border-t-blue-500 rounded-full" }),
45905
46447
  "Loading more clips..."
45906
46448
  ] }) }),
45907
- categoryHasMore[node.id] && !loadingCategories.has(getMetadataLoadingKey(node.id, (categoryPages[node.id] || 0) + 1)) && /* @__PURE__ */ jsxs(
46449
+ categoryHasMore[node.id] && !isLoadMoreLoading && /* @__PURE__ */ jsxs(
45908
46450
  "button",
45909
46451
  {
45910
46452
  onClick: (e) => {
45911
46453
  e.stopPropagation();
45912
- const nextPage = (categoryPages[node.id] || 1) + 1;
45913
- fetchClipMetadata(node.id, nextPage);
46454
+ fetchClipMetadata(node.id, nextLoadMorePage);
45914
46455
  },
45915
46456
  className: "w-full py-2 px-3 text-sm text-blue-600 hover:bg-blue-50 rounded-lg transition-colors duration-200 text-center",
45916
46457
  children: [
@@ -46673,6 +47214,7 @@ var BottlenecksContent = ({
46673
47214
  triageMode = false,
46674
47215
  ticketId,
46675
47216
  prefetchedPercentileCounts,
47217
+ lowMomentsPrefetch,
46676
47218
  initialTimeFilter
46677
47219
  }) => {
46678
47220
  console.log("\u{1F3AB} [BottlenecksContent] Rendered with ticketId:", ticketId || "NONE", "workspaceId:", workspaceId, "date:", date, "shift:", shift);
@@ -46765,6 +47307,10 @@ var BottlenecksContent = ({
46765
47307
  const [isShareLoading, setIsShareLoading] = useState(false);
46766
47308
  const [isShareCopied, setIsShareCopied] = useState(false);
46767
47309
  const shareCopiedTimeoutRef = useRef(null);
47310
+ const [lowEfficiencyAiSummaryByClipId, setLowEfficiencyAiSummaryByClipId] = useState({});
47311
+ const [lowEfficiencyAiSummaryLoadingByClipId, setLowEfficiencyAiSummaryLoadingByClipId] = useState({});
47312
+ const [lowEfficiencyAiSummaryErrorByClipId, setLowEfficiencyAiSummaryErrorByClipId] = useState({});
47313
+ const lowEfficiencyAiSummaryRequestStatusRef = useRef({});
46768
47314
  useEffect(() => {
46769
47315
  return () => {
46770
47316
  if (shareCopiedTimeoutRef.current) {
@@ -46773,6 +47319,7 @@ var BottlenecksContent = ({
46773
47319
  };
46774
47320
  }, []);
46775
47321
  const loadingTimeoutRef = useRef(null);
47322
+ const metadataLoadingKeyRef = useRef(null);
46776
47323
  const [activeFilter, setActiveFilter] = useState(initialFilter);
46777
47324
  const previousFilterRef = useRef("");
46778
47325
  const [allVideos, setAllVideos] = useState([]);
@@ -46929,60 +47476,33 @@ var BottlenecksContent = ({
46929
47476
  if (initialFilter) {
46930
47477
  return;
46931
47478
  }
47479
+ const redStreakType = "recent_flow_red_streak";
47480
+ if (dynamicCounts[redStreakType] > 0) {
47481
+ setInitialFilter(redStreakType);
47482
+ setActiveFilter(redStreakType);
47483
+ activeFilterRef.current = redStreakType;
47484
+ return;
47485
+ }
46932
47486
  if (defaultCategory) {
46933
47487
  setInitialFilter(defaultCategory);
46934
47488
  setActiveFilter(defaultCategory);
46935
47489
  activeFilterRef.current = defaultCategory;
46936
47490
  return;
46937
47491
  }
46938
- if (clipTypes.length > 0) {
46939
- let selectedType = null;
46940
- if (clipTypes.length === 1) {
46941
- selectedType = clipTypes[0];
46942
- } else {
46943
- const priorityOrder = ["cycle_completion", "fast-cycles", "slow-cycles", "idle_time"];
46944
- for (const priorityType of priorityOrder) {
46945
- const type = clipTypes.find((t) => t.type === priorityType && (dynamicCounts[t.type] || 0) > 0);
46946
- if (type) {
46947
- selectedType = type;
46948
- break;
46949
- }
46950
- }
46951
- if (!selectedType) {
46952
- selectedType = clipTypes.find((type) => (dynamicCounts[type.type] || 0) > 0);
46953
- }
46954
- if (!selectedType) {
46955
- selectedType = clipTypes[0];
46956
- }
46957
- }
46958
- if (selectedType) {
46959
- console.log(`[BottlenecksContent] Auto-selecting filter: ${selectedType.type} (count: ${dynamicCounts[selectedType.type] || 0})`);
46960
- setInitialFilter(selectedType.type);
46961
- setActiveFilter(selectedType.type);
46962
- activeFilterRef.current = selectedType.type;
46963
- }
46964
- }
46965
47492
  }, [clipTypes, dynamicCounts, defaultCategory, initialFilter]);
46966
47493
  const mergedCounts = useMemo(() => {
46967
47494
  return { ...dynamicCounts };
46968
47495
  }, [dynamicCounts]);
46969
47496
  useEffect(() => {
46970
- if (!firstClip || allVideos.length > 0 || !isMountedRef.current) {
47497
+ if (allVideos.length > 0 || !isMountedRef.current) {
46971
47498
  return;
46972
47499
  }
46973
- if (activeFilterRef.current && firstClip.type !== activeFilterRef.current) {
47500
+ if (!activeFilterRef.current) {
47501
+ setHasInitialLoad(true);
47502
+ setIsCategoryLoading(false);
46974
47503
  return;
46975
47504
  }
46976
- setCurrentClipId(firstClip.id || null);
46977
- setAllVideos([firstClip]);
46978
- setCurrentPosition(1);
46979
- currentPositionRef.current = 1;
46980
- const total = mergedCounts[firstClip.type] || 0;
46981
- currentTotalRef.current = total;
46982
- setCurrentTotal(total);
46983
- setHasInitialLoad(true);
46984
- setIsCategoryLoading(false);
46985
- }, [firstClip, allVideos.length, mergedCounts]);
47505
+ }, [firstClips, allVideos.length, mergedCounts]);
46986
47506
  useEffect(() => {
46987
47507
  if (!firstClips || typeof document === "undefined") {
46988
47508
  return;
@@ -47018,25 +47538,6 @@ var BottlenecksContent = ({
47018
47538
  const loadFirstVideoForCategory = useCallback(async (category) => {
47019
47539
  if (!workspaceId || !s3ClipsService || !isMountedRef.current || !isEffectiveShiftReady) return;
47020
47540
  const targetCategory = category || activeFilterRef.current;
47021
- const initClip = targetCategory ? firstClips?.[targetCategory] : null;
47022
- if (initClip) {
47023
- setCurrentClipId(initClip.id || null);
47024
- setAllVideos((prev) => {
47025
- const exists = prev.some((v) => v.id === initClip.id);
47026
- if (!exists) {
47027
- return [...prev, initClip];
47028
- }
47029
- return prev;
47030
- });
47031
- setCurrentPosition(1);
47032
- currentPositionRef.current = 1;
47033
- const total = mergedCounts[targetCategory] || 0;
47034
- currentTotalRef.current = total;
47035
- setCurrentTotal(total);
47036
- setHasInitialLoad(true);
47037
- setIsCategoryLoading(false);
47038
- return;
47039
- }
47040
47541
  const operationKey = `loadFirstVideo:${targetCategory}:${effectiveDateString}:${effectiveShiftId}`;
47041
47542
  if (loadingCategoryRef.current === targetCategory || fetchInProgressRef.current.has(operationKey)) {
47042
47543
  console.log(`[BottlenecksContent] Load first video already in progress for ${targetCategory}`);
@@ -47052,12 +47553,25 @@ var BottlenecksContent = ({
47052
47553
  const shiftStr = effectiveShiftId;
47053
47554
  console.log(`[BottlenecksContent] Loading first video for category: ${targetCategory}`);
47054
47555
  try {
47055
- const firstVideo = await s3ClipsService.getFirstClipForCategory(
47056
- workspaceId,
47057
- operationalDate,
47058
- shiftStr,
47059
- targetCategory
47060
- );
47556
+ let firstVideo = null;
47557
+ const totalCategoryClips = mergedCounts[targetCategory] || 0;
47558
+ if (totalCategoryClips > 0) {
47559
+ firstVideo = await s3ClipsService.getClipByIndex(
47560
+ workspaceId,
47561
+ operationalDate,
47562
+ shiftStr,
47563
+ targetCategory,
47564
+ 0
47565
+ );
47566
+ }
47567
+ if (!firstVideo) {
47568
+ firstVideo = await s3ClipsService.getFirstClipForCategory(
47569
+ workspaceId,
47570
+ operationalDate,
47571
+ shiftStr,
47572
+ targetCategory
47573
+ );
47574
+ }
47061
47575
  if (firstVideo) {
47062
47576
  console.log(`[BottlenecksContent] Successfully loaded first video, ID: ${firstVideo.id}`);
47063
47577
  setCurrentClipId(firstVideo.id || null);
@@ -47068,8 +47582,8 @@ var BottlenecksContent = ({
47068
47582
  }
47069
47583
  return prev;
47070
47584
  });
47071
- setCurrentPosition(1);
47072
- currentPositionRef.current = 1;
47585
+ setCurrentPosition(totalCategoryClips > 0 ? 1 : 0);
47586
+ currentPositionRef.current = totalCategoryClips > 0 ? 1 : 0;
47073
47587
  const total = mergedCounts[targetCategory] || 0;
47074
47588
  currentTotalRef.current = total;
47075
47589
  setCurrentTotal(total);
@@ -47083,13 +47597,13 @@ var BottlenecksContent = ({
47083
47597
  }
47084
47598
  if (mergedCounts[targetCategory] > 0) {
47085
47599
  try {
47600
+ const fallbackIndex = 0;
47086
47601
  const firstVideo = await s3ClipsService.getClipByIndex(
47087
47602
  workspaceId,
47088
47603
  operationalDate,
47089
47604
  shiftStr,
47090
47605
  targetCategory,
47091
- 0
47092
- // First video (index 0)
47606
+ fallbackIndex
47093
47607
  );
47094
47608
  if (firstVideo && isMountedRef.current) {
47095
47609
  console.log(`[BottlenecksContent] Successfully loaded first video via index`);
@@ -47192,11 +47706,12 @@ var BottlenecksContent = ({
47192
47706
  categoryId
47193
47707
  }));
47194
47708
  };
47195
- const [cycleClips, idleClips] = await Promise.all([
47709
+ const [cycleClips, redFlowClips, idleClips] = await Promise.all([
47196
47710
  fetchCategoryMetadata("cycle_completion"),
47711
+ fetchCategoryMetadata("recent_flow_red_streak"),
47197
47712
  fetchCategoryMetadata("idle_time")
47198
47713
  ]);
47199
- const allClips = [...cycleClips, ...idleClips].sort(
47714
+ const allClips = [...cycleClips, ...redFlowClips, ...idleClips].sort(
47200
47715
  (a, b) => new Date(b.clip_timestamp).getTime() - new Date(a.clip_timestamp).getTime()
47201
47716
  );
47202
47717
  setTriageClips(allClips);
@@ -47245,6 +47760,9 @@ var BottlenecksContent = ({
47245
47760
  }, [idleTimeVlmEnabled, triageClips, triageMode, getAuthToken4]);
47246
47761
  useEffect(() => {
47247
47762
  if (s3ClipsService && (mergedCounts[activeFilter] || 0) > 0) {
47763
+ if (activeFilter === "recent_flow_red_streak") {
47764
+ return;
47765
+ }
47248
47766
  if (firstClip && firstClip.type === activeFilter) {
47249
47767
  return;
47250
47768
  }
@@ -47265,10 +47783,10 @@ var BottlenecksContent = ({
47265
47783
  return ["fast-cycles", "slow-cycles", "longest-idles"].includes(categoryId);
47266
47784
  }, [isFastSlowClipFiltersEnabled]);
47267
47785
  const shouldUseMetadataNavigation = useCallback((categoryId) => {
47268
- return isPercentileCategory(categoryId) || categoryId === "idle_time" && idleClipSort === "idle_duration_desc";
47786
+ return isPercentileCategory(categoryId) || categoryId === "recent_flow_red_streak" || categoryId === "idle_time" && idleClipSort === "idle_duration_desc";
47269
47787
  }, [idleClipSort, isPercentileCategory]);
47270
47788
  const getMetadataCacheKey = useCallback((categoryId) => {
47271
- const sortKey = categoryId === "idle_time" ? idleClipSort : "latest";
47789
+ const sortKey = categoryId === "recent_flow_red_streak" ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest";
47272
47790
  return `${categoryId}-${effectiveDateString}-${effectiveShiftId}-${snapshotDateTime ?? "nosnap"}-${snapshotClipId ?? "nosnap"}-${sortKey}`;
47273
47791
  }, [effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, idleClipSort]);
47274
47792
  const setVisibleCategoryMetadata = useCallback((categoryId, clips) => {
@@ -47278,7 +47796,7 @@ var BottlenecksContent = ({
47278
47796
  categoryMetadataRef.current = clips;
47279
47797
  setCategoryMetadata(clips);
47280
47798
  setCategoryMetadataCategoryId(clips.length > 0 ? categoryId : null);
47281
- setCategoryMetadataSort(clips.length > 0 ? categoryId === "idle_time" ? idleClipSort : "latest" : null);
47799
+ setCategoryMetadataSort(clips.length > 0 ? categoryId === "recent_flow_red_streak" ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest" : null);
47282
47800
  return true;
47283
47801
  }, [idleClipSort]);
47284
47802
  const applyMetadataSnapshot = useCallback((categoryId, clips, total) => {
@@ -47296,6 +47814,22 @@ var BottlenecksContent = ({
47296
47814
  setCurrentTotal(total);
47297
47815
  }
47298
47816
  }, [getMetadataCacheKey, shouldUseMetadataNavigation, setVisibleCategoryMetadata]);
47817
+ const applyPrefetchedFirstVideo = useCallback((video) => {
47818
+ if (!video || !isMountedRef.current) {
47819
+ return false;
47820
+ }
47821
+ if (currentClipIdRef.current === video.id) {
47822
+ return true;
47823
+ }
47824
+ setCurrentClipId(video.id);
47825
+ setAllVideos([video]);
47826
+ setCurrentIndex(0);
47827
+ setCurrentMetadataIndex(0);
47828
+ currentMetadataIndexRef.current = 0;
47829
+ setCurrentPosition(1);
47830
+ currentPositionRef.current = 1;
47831
+ return true;
47832
+ }, []);
47299
47833
  const getClipTypesForPercentileCategory = useCallback((categoryId) => {
47300
47834
  switch (categoryId) {
47301
47835
  case "fast-cycles":
@@ -47315,7 +47849,7 @@ var BottlenecksContent = ({
47315
47849
  if (activeFilter !== "fast-cycles" && activeFilter !== "slow-cycles") {
47316
47850
  return;
47317
47851
  }
47318
- const fallbackFilter = ["cycle_completion", "idle_time"].find((type) => (dynamicCounts[type] || 0) > 0) || clipTypes.find((type) => (dynamicCounts[type.type] || 0) > 0)?.type || clipTypes[0]?.type;
47852
+ const fallbackFilter = ["cycle_completion", "recent_flow_red_streak", "idle_time"].find((type) => (dynamicCounts[type] || 0) > 0) || clipTypes.find((type) => (dynamicCounts[type.type] || 0) > 0)?.type || clipTypes[0]?.type;
47319
47853
  if (!fallbackFilter || fallbackFilter === activeFilter) {
47320
47854
  return;
47321
47855
  }
@@ -47371,30 +47905,70 @@ var BottlenecksContent = ({
47371
47905
  setCategoryMetadataCategoryId(null);
47372
47906
  setCategoryMetadataSort(null);
47373
47907
  categoryMetadataRef.current = [];
47908
+ if (activeFilterRef.current === categoryId) {
47909
+ setIsCategoryLoading(false);
47910
+ }
47374
47911
  return;
47375
47912
  }
47376
47913
  if (!isEffectiveShiftReady) {
47377
47914
  console.log("[BottlenecksContent] Skipping metadata load - shift/date not ready");
47915
+ if (activeFilterRef.current === categoryId) {
47916
+ setIsCategoryLoading(false);
47917
+ }
47378
47918
  return;
47379
47919
  }
47380
47920
  const resolvedDate = effectiveDateString;
47381
47921
  const cacheKey = getMetadataCacheKey(categoryId);
47382
- const cachedMetadata = !forceRefresh ? metadataCache[cacheKey] : void 0;
47922
+ const candidateLowMomentsPrefetch = lowMomentsPrefetch ?? null;
47923
+ const lowMomentsPrefetchMatchesScope = Boolean(
47924
+ candidateLowMomentsPrefetch?.key?.startsWith(`recent_flow_red_streak-${effectiveDateString}-${effectiveShiftId}-`)
47925
+ );
47926
+ const matchingLowMomentsPrefetch = !forceRefresh && categoryId === "recent_flow_red_streak" && candidateLowMomentsPrefetch && (candidateLowMomentsPrefetch.key === cacheKey || lowMomentsPrefetchMatchesScope) && !candidateLowMomentsPrefetch.loading && Array.isArray(candidateLowMomentsPrefetch.metadata) && candidateLowMomentsPrefetch.metadata.length > 0 ? candidateLowMomentsPrefetch : null;
47927
+ const lowMomentsPrefetchInFlight = !forceRefresh && categoryId === "recent_flow_red_streak" && candidateLowMomentsPrefetch && (candidateLowMomentsPrefetch.key === cacheKey || lowMomentsPrefetchMatchesScope) && candidateLowMomentsPrefetch.loading;
47928
+ if (lowMomentsPrefetchInFlight) {
47929
+ if (autoLoadFirstVideo && candidateLowMomentsPrefetch?.firstVideo) {
47930
+ applyPrefetchedFirstVideo(candidateLowMomentsPrefetch.firstVideo);
47931
+ }
47932
+ if (Array.isArray(candidateLowMomentsPrefetch?.metadata) && candidateLowMomentsPrefetch.metadata.length > 0) {
47933
+ applyMetadataSnapshot(categoryId, candidateLowMomentsPrefetch.metadata, candidateLowMomentsPrefetch.total);
47934
+ }
47935
+ if (activeFilterRef.current === categoryId) {
47936
+ setIsCategoryLoading(true);
47937
+ }
47938
+ return;
47939
+ }
47940
+ const cachedMetadata = matchingLowMomentsPrefetch?.metadata ?? (!forceRefresh ? metadataCache[cacheKey] : void 0);
47941
+ const requestKey = cacheKey;
47942
+ if (metadataLoadingKeyRef.current === requestKey) {
47943
+ console.log(`[BottlenecksContent] Metadata load already in progress for ${categoryId}`);
47944
+ return;
47945
+ }
47946
+ metadataLoadingKeyRef.current = requestKey;
47383
47947
  try {
47384
47948
  if (cachedMetadata) {
47385
47949
  console.log(`[BottlenecksContent] Using cached metadata for ${categoryId}`);
47950
+ if (matchingLowMomentsPrefetch) {
47951
+ setMetadataCache((prev) => prev[cacheKey] ? prev : {
47952
+ ...prev,
47953
+ [cacheKey]: matchingLowMomentsPrefetch.metadata
47954
+ });
47955
+ }
47386
47956
  setVisibleCategoryMetadata(categoryId, cachedMetadata);
47387
47957
  if (autoLoadFirstVideo && cachedMetadata.length > 0 && s3ClipsService) {
47388
47958
  const firstClipMeta = cachedMetadata[0];
47959
+ const firstClipId = firstClipMeta.clipId || firstClipMeta.id;
47960
+ const prefetchedFirstVideo = matchingLowMomentsPrefetch?.firstVideo ?? null;
47389
47961
  try {
47390
- const video = await s3ClipsService.getClipById(firstClipMeta.clipId);
47391
- if (video && isMountedRef.current) {
47392
- setCurrentClipId(firstClipMeta.clipId);
47393
- setAllVideos([video]);
47394
- setCurrentIndex(0);
47395
- setCurrentMetadataIndex(0);
47396
- currentMetadataIndexRef.current = 0;
47397
- console.log(`[BottlenecksContent] Auto-loaded first video from cache: ${video.id} (1/${cachedMetadata.length})`);
47962
+ let loadedVideo = null;
47963
+ if (prefetchedFirstVideo?.id === firstClipId) {
47964
+ loadedVideo = prefetchedFirstVideo;
47965
+ applyPrefetchedFirstVideo(prefetchedFirstVideo);
47966
+ } else {
47967
+ loadedVideo = await s3ClipsService.getClipById(firstClipId);
47968
+ applyPrefetchedFirstVideo(loadedVideo);
47969
+ }
47970
+ if (loadedVideo && isMountedRef.current) {
47971
+ console.log(`[BottlenecksContent] Auto-loaded first video from cache: ${loadedVideo.id} (1/${cachedMetadata.length})`);
47398
47972
  }
47399
47973
  } catch (error2) {
47400
47974
  console.error(`[BottlenecksContent] Error loading first video from cache:`, error2);
@@ -47441,7 +48015,7 @@ var BottlenecksContent = ({
47441
48015
  knownTotal: mergedCounts[categoryId] ?? null,
47442
48016
  snapshotDateTime,
47443
48017
  snapshotClipId,
47444
- sort: categoryId === "idle_time" ? idleClipSort : "latest"
48018
+ sort: categoryId === "recent_flow_red_streak" ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest"
47445
48019
  }),
47446
48020
  redirectReason: "session_expired"
47447
48021
  });
@@ -47502,10 +48076,11 @@ var BottlenecksContent = ({
47502
48076
  console.log(`[BottlenecksContent] Loaded metadata for ${categoryId}: ${metadataClips.length} clips`);
47503
48077
  if (autoLoadFirstVideo && metadataClips.length > 0 && s3ClipsService) {
47504
48078
  const firstClipMeta = metadataClips[0];
48079
+ const firstClipId = firstClipMeta.clipId || firstClipMeta.id;
47505
48080
  try {
47506
- const video = await s3ClipsService.getClipById(firstClipMeta.clipId);
48081
+ const video = await s3ClipsService.getClipById(firstClipId);
47507
48082
  if (video && isMountedRef.current) {
47508
- setCurrentClipId(firstClipMeta.clipId);
48083
+ setCurrentClipId(firstClipId);
47509
48084
  setAllVideos([video]);
47510
48085
  setCurrentIndex(0);
47511
48086
  setCurrentMetadataIndex(0);
@@ -47527,9 +48102,43 @@ var BottlenecksContent = ({
47527
48102
  } catch (error2) {
47528
48103
  console.error(`[BottlenecksContent] Error loading category metadata:`, error2);
47529
48104
  } finally {
47530
- setIsCategoryLoading(false);
48105
+ if (metadataLoadingKeyRef.current === requestKey) {
48106
+ metadataLoadingKeyRef.current = null;
48107
+ }
48108
+ if (activeFilterRef.current === categoryId) {
48109
+ setIsCategoryLoading(false);
48110
+ }
47531
48111
  }
47532
- }, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, idleClipSort, supabase, setVisibleCategoryMetadata]);
48112
+ }, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, idleClipSort, supabase, setVisibleCategoryMetadata, lowMomentsPrefetch, applyPrefetchedFirstVideo, applyMetadataSnapshot]);
48113
+ useEffect(() => {
48114
+ if (activeFilter !== "recent_flow_red_streak") {
48115
+ return;
48116
+ }
48117
+ if (!lowMomentsPrefetch?.key?.startsWith(`recent_flow_red_streak-${effectiveDateString}-${effectiveShiftId}-`)) {
48118
+ return;
48119
+ }
48120
+ if (lowMomentsPrefetch.firstVideo && !allVideos.some((video) => video.type === "recent_flow_red_streak")) {
48121
+ applyPrefetchedFirstVideo(lowMomentsPrefetch.firstVideo);
48122
+ }
48123
+ if (lowMomentsPrefetch.metadata.length > 0) {
48124
+ applyMetadataSnapshot("recent_flow_red_streak", lowMomentsPrefetch.metadata, lowMomentsPrefetch.total);
48125
+ if (isMountedRef.current) {
48126
+ setIsCategoryLoading(false);
48127
+ }
48128
+ return;
48129
+ }
48130
+ if (isMountedRef.current) {
48131
+ setIsCategoryLoading(lowMomentsPrefetch.loading);
48132
+ }
48133
+ }, [
48134
+ activeFilter,
48135
+ lowMomentsPrefetch,
48136
+ effectiveDateString,
48137
+ effectiveShiftId,
48138
+ allVideos,
48139
+ applyPrefetchedFirstVideo,
48140
+ applyMetadataSnapshot
48141
+ ]);
47533
48142
  useEffect(() => {
47534
48143
  if (previousIdleClipSortRef.current === idleClipSort) {
47535
48144
  return;
@@ -47569,8 +48178,13 @@ var BottlenecksContent = ({
47569
48178
  currentTotalRef.current = total;
47570
48179
  setCurrentTotal(total);
47571
48180
  previousFilterRef.current = activeFilter;
47572
- if (activeFilter !== "all" && currentClipId) {
47573
- loadCategoryMetadata(activeFilter, false);
48181
+ const metadataLoadPlan = getCategoryMetadataLoadPlanForFilterChange({
48182
+ activeFilter,
48183
+ currentClipId,
48184
+ categoryTotal: total
48185
+ });
48186
+ if (metadataLoadPlan.shouldLoad) {
48187
+ loadCategoryMetadata(activeFilter, metadataLoadPlan.autoLoadFirstVideo);
47574
48188
  }
47575
48189
  const filtered = allVideos.filter((video) => {
47576
48190
  if (activeFilter === "all") return true;
@@ -47593,11 +48207,11 @@ var BottlenecksContent = ({
47593
48207
  if (!currentClipId || activeFilter === "all") {
47594
48208
  return;
47595
48209
  }
47596
- if (categoryMetadataRef.current.length > 0 || isCategoryLoading) {
48210
+ if (categoryMetadataRef.current.length > 0) {
47597
48211
  return;
47598
48212
  }
47599
48213
  loadCategoryMetadata(activeFilter, false);
47600
- }, [currentClipId, activeFilter, isCategoryLoading, loadCategoryMetadata]);
48214
+ }, [currentClipId, activeFilter, loadCategoryMetadata]);
47601
48215
  const loadAndPlayClipById = useCallback(async (clipId, categoryId, position, metadataContext) => {
47602
48216
  if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
47603
48217
  console.log(`[BottlenecksContent] Loading clip by ID: ${clipId}, category=${categoryId}, position=${position}`);
@@ -48056,6 +48670,98 @@ var BottlenecksContent = ({
48056
48670
  }
48057
48671
  return filteredVideos[currentIndex];
48058
48672
  }, [filteredVideos, currentIndex]);
48673
+ const currentLowEfficiencyClipId = currentVideo?.id || currentClipId || null;
48674
+ const isCurrentLowEfficiencyClip = Boolean(
48675
+ currentVideo?.type === "recent_flow_red_streak" || currentVideo?.red_flow_timeline
48676
+ );
48677
+ const currentLowEfficiencyAiSummary = currentLowEfficiencyClipId ? lowEfficiencyAiSummaryByClipId[currentLowEfficiencyClipId] || currentVideo?.low_efficiency_ai_summary || null : null;
48678
+ const isCurrentLowEfficiencyAiSummaryLoading = Boolean(
48679
+ currentLowEfficiencyClipId && lowEfficiencyAiSummaryLoadingByClipId[currentLowEfficiencyClipId]
48680
+ );
48681
+ const currentLowEfficiencyAiSummaryError = currentLowEfficiencyClipId ? lowEfficiencyAiSummaryErrorByClipId[currentLowEfficiencyClipId] || null : null;
48682
+ useEffect(() => {
48683
+ const clipId = currentLowEfficiencyClipId;
48684
+ if (!clipId || !isCurrentLowEfficiencyClip || !workspaceId) {
48685
+ return;
48686
+ }
48687
+ if (currentVideo?.low_efficiency_ai_summary || lowEfficiencyAiSummaryRequestStatusRef.current[clipId]) {
48688
+ return;
48689
+ }
48690
+ let cancelled = false;
48691
+ let timedOut = false;
48692
+ const controller = new AbortController();
48693
+ lowEfficiencyAiSummaryRequestStatusRef.current[clipId] = "loading";
48694
+ const timeout = setTimeout(() => {
48695
+ timedOut = true;
48696
+ controller.abort();
48697
+ }, 3e4);
48698
+ setLowEfficiencyAiSummaryLoadingByClipId((prev) => ({ ...prev, [clipId]: true }));
48699
+ setLowEfficiencyAiSummaryErrorByClipId((prev) => ({ ...prev, [clipId]: null }));
48700
+ void (async () => {
48701
+ try {
48702
+ const response = await fetchWithSupabaseAuth(supabase, "/api/clips/supabase", {
48703
+ method: "POST",
48704
+ headers: {
48705
+ "Content-Type": "application/json"
48706
+ },
48707
+ signal: controller.signal,
48708
+ body: JSON.stringify({
48709
+ action: "ai-summary",
48710
+ workspaceId,
48711
+ clipId,
48712
+ workspaceName
48713
+ }),
48714
+ redirectReason: "session_expired"
48715
+ });
48716
+ if (!response.ok) {
48717
+ throw new Error(`AI summary API error: ${response.status}`);
48718
+ }
48719
+ const payload = await response.json();
48720
+ const summary = payload?.summary;
48721
+ if (!summary || !Array.isArray(summary.bullets) || summary.bullets.filter((bullet) => String(bullet || "").trim()).length < 3) {
48722
+ throw new Error("AI summary response was empty");
48723
+ }
48724
+ if (!cancelled) {
48725
+ lowEfficiencyAiSummaryRequestStatusRef.current[clipId] = "success";
48726
+ setLowEfficiencyAiSummaryByClipId((prev) => ({ ...prev, [clipId]: summary }));
48727
+ }
48728
+ } catch (error2) {
48729
+ if (cancelled) {
48730
+ return;
48731
+ }
48732
+ lowEfficiencyAiSummaryRequestStatusRef.current[clipId] = "error";
48733
+ const message = timedOut ? "AI summary timed out" : error2 instanceof Error ? error2.message : "AI summary unavailable";
48734
+ console.warn("[BottlenecksContent] Failed to generate Low Efficiency AI summary:", error2);
48735
+ setLowEfficiencyAiSummaryErrorByClipId((prev) => ({
48736
+ ...prev,
48737
+ [clipId]: message
48738
+ }));
48739
+ } finally {
48740
+ clearTimeout(timeout);
48741
+ if (isMountedRef.current) {
48742
+ setLowEfficiencyAiSummaryLoadingByClipId((prev) => ({ ...prev, [clipId]: false }));
48743
+ }
48744
+ }
48745
+ })();
48746
+ return () => {
48747
+ cancelled = true;
48748
+ clearTimeout(timeout);
48749
+ if (lowEfficiencyAiSummaryRequestStatusRef.current[clipId] === "loading") {
48750
+ delete lowEfficiencyAiSummaryRequestStatusRef.current[clipId];
48751
+ }
48752
+ if (isMountedRef.current) {
48753
+ setLowEfficiencyAiSummaryLoadingByClipId((prev) => ({ ...prev, [clipId]: false }));
48754
+ }
48755
+ controller.abort();
48756
+ };
48757
+ }, [
48758
+ currentLowEfficiencyClipId,
48759
+ currentVideo?.low_efficiency_ai_summary,
48760
+ isCurrentLowEfficiencyClip,
48761
+ supabase,
48762
+ workspaceId,
48763
+ workspaceName
48764
+ ]);
48059
48765
  const handleShareClip = useCallback(async () => {
48060
48766
  if (!currentVideo?.id || isShareLoading) {
48061
48767
  if (!currentVideo?.id) {
@@ -48127,11 +48833,11 @@ var BottlenecksContent = ({
48127
48833
  }
48128
48834
  return currentPosition;
48129
48835
  }, [activeFilter, categoryMetadata.length, currentMetadataIndex, currentPosition, shouldUseMetadataNavigation]);
48130
- const prefetchedExplorerMetadata = useMemo(() => activeFilter === "idle_time" && categoryMetadataSort !== idleClipSort ? void 0 : buildPrefetchedExplorerMetadata(
48836
+ const prefetchedExplorerMetadata = useMemo(() => activeFilter === "recent_flow_red_streak" && lowMomentsPrefetch?.key?.startsWith(`recent_flow_red_streak-${effectiveDateString}-${effectiveShiftId}-`) && !lowMomentsPrefetch.loading && lowMomentsPrefetch.metadata.length > 0 ? { recent_flow_red_streak: lowMomentsPrefetch.metadata } : activeFilter === "idle_time" && categoryMetadataSort !== idleClipSort ? void 0 : buildPrefetchedExplorerMetadata(
48131
48837
  activeFilter,
48132
48838
  categoryMetadataCategoryId,
48133
48839
  categoryMetadata
48134
- ), [activeFilter, categoryMetadata, categoryMetadataCategoryId, categoryMetadataSort, idleClipSort]);
48840
+ ), [activeFilter, categoryMetadata, categoryMetadataCategoryId, categoryMetadataSort, idleClipSort, lowMomentsPrefetch, effectiveDateString, effectiveShiftId]);
48135
48841
  const classificationClipIds = useMemo(() => {
48136
48842
  if (!idleTimeVlmEnabled) {
48137
48843
  return [];
@@ -48523,6 +49229,8 @@ var BottlenecksContent = ({
48523
49229
  return "Cycle Completion";
48524
49230
  case "idle_time":
48525
49231
  return "Idle Time";
49232
+ case "recent_flow_red_streak":
49233
+ return "Low efficiency videos";
48526
49234
  case "running_cycle":
48527
49235
  return "Running Cycle";
48528
49236
  case "setup_state":
@@ -48602,12 +49310,26 @@ var BottlenecksContent = ({
48602
49310
  onShare: handleShareClip,
48603
49311
  isShareLoading,
48604
49312
  isShareCopied,
49313
+ timelineAnnotations: currentVideo.red_flow_timeline,
49314
+ timelineExplanation: currentVideo.red_flow_explanation,
49315
+ timelineTimezone: timezone,
48605
49316
  options: videoPlayerOptions
48606
49317
  },
48607
49318
  `${currentVideo.id}-${playerInstanceNonce}-inline`
48608
49319
  )
48609
49320
  }
48610
49321
  ),
49322
+ currentVideo.type === "recent_flow_red_streak" && !shouldDeferPlayerRenderForCrop ? /* @__PURE__ */ jsx(
49323
+ RedFlowDiagnosticOverlay,
49324
+ {
49325
+ timeline: currentVideo.red_flow_timeline,
49326
+ explanation: currentVideo.red_flow_explanation,
49327
+ aiSummary: currentLowEfficiencyAiSummary,
49328
+ aiSummaryLoading: isCurrentLowEfficiencyAiSummaryLoading,
49329
+ aiSummaryError: currentLowEfficiencyAiSummaryError,
49330
+ className: "right-4 top-4"
49331
+ }
49332
+ ) : null,
48611
49333
  showBlockingVideoLoader && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
48612
49334
  !shouldDeferPlayerRenderForCrop && !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
48613
49335
  error && error.type === "retrying" && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-40 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
@@ -48707,10 +49429,10 @@ var BottlenecksContent = ({
48707
49429
  ] }) })
48708
49430
  ] });
48709
49431
  })()
48710
- ) : /* @__PURE__ */ jsx("div", { className: "absolute top-3 right-3 z-10 bg-black/60 backdrop-blur-sm px-3 py-1.5 rounded-lg text-white shadow-lg text-xs", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
49432
+ ) : /* @__PURE__ */ jsx("div", { className: `absolute top-3 z-10 bg-black/60 backdrop-blur-sm px-3 py-1.5 rounded-lg text-white shadow-lg text-xs ${currentVideo.type === "recent_flow_red_streak" ? "left-3" : "right-3"}`, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
48711
49433
  /* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 rounded-full ${getSeverityColor(currentVideo.severity)} mr-2 animate-pulse` }),
48712
49434
  /* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
48713
- /* @__PURE__ */ jsx("span", { className: "opacity-80 hidden sm:inline", children: currentVideo.description })
49435
+ currentVideo.type !== "recent_flow_red_streak" && /* @__PURE__ */ jsx("span", { className: "opacity-80 hidden sm:inline", children: currentVideo.description })
48714
49436
  ] }) })
48715
49437
  )
48716
49438
  ] }) }) }) : (
@@ -48720,14 +49442,21 @@ var BottlenecksContent = ({
48720
49442
  /* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Clips Found" }),
48721
49443
  /* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There were no video clips found for this workspace today." })
48722
49444
  ] }) }) : (
48723
- /* Priority 6: Show "no matching clips" only if we have data loaded and specifically no clips for this filter */
48724
- hasInitialLoad && (mergedCounts[activeFilter] || 0) === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-[220px] sm:min-h-[320px] lg:h-full", children: /* @__PURE__ */ jsxs("div", { className: "text-center p-8", children: [
49445
+ /* Priority 5.5: Show "no folder selected" if activeFilter is empty */
49446
+ hasInitialLoad && !activeFilter ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-[220px] sm:min-h-[320px] lg:h-full", children: /* @__PURE__ */ jsxs("div", { className: "text-center p-8", children: [
48725
49447
  /* @__PURE__ */ jsx("svg", { className: "w-16 h-16 text-gray-300 mx-auto mb-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" }) }),
48726
- /* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Matching Clips" }),
48727
- /* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There are no clips matching the selected filter." })
49448
+ /* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Folder Selected" }),
49449
+ /* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "Please select a folder to view clips." })
48728
49450
  ] }) }) : (
48729
- /* Priority 7: Default loading state for any other case */
48730
- /* @__PURE__ */ jsx("div", { className: "p-4 lg:h-full", children: /* @__PURE__ */ jsx("div", { className: "relative lg:h-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full min-h-[220px] sm:min-h-[320px] lg:min-h-0 lg:h-full overflow-hidden rounded-md shadow-inner bg-gray-900 flex items-center justify-center", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading..." }) }) }) })
49451
+ /* Priority 6: Show "no matching clips" only if we have data loaded and specifically no clips for this filter */
49452
+ hasInitialLoad && (mergedCounts[activeFilter] || 0) === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-[220px] sm:min-h-[320px] lg:h-full", children: /* @__PURE__ */ jsxs("div", { className: "text-center p-8", children: [
49453
+ /* @__PURE__ */ jsx("svg", { className: "w-16 h-16 text-gray-300 mx-auto mb-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" }) }),
49454
+ /* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Matching Clips" }),
49455
+ /* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There are no clips matching the selected filter." })
49456
+ ] }) }) : (
49457
+ /* Priority 7: Default loading state for any other case */
49458
+ /* @__PURE__ */ jsx("div", { className: "p-4 lg:h-full", children: /* @__PURE__ */ jsx("div", { className: "relative lg:h-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full min-h-[220px] sm:min-h-[320px] lg:min-h-0 lg:h-full overflow-hidden rounded-md shadow-inner bg-gray-900 flex items-center justify-center", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading..." }) }) }) })
49459
+ )
48731
49460
  )
48732
49461
  )
48733
49462
  ) }) }),
@@ -48879,6 +49608,11 @@ var BottlenecksContent = ({
48879
49608
  idleTimeVlmEnabled,
48880
49609
  showPercentileCycleFilters: isFastSlowClipFiltersEnabled,
48881
49610
  prefetchedClipMetadata: prefetchedExplorerMetadata,
49611
+ externallyManagedLoadingCategories: {
49612
+ recent_flow_red_streak: Boolean(
49613
+ activeFilter === "recent_flow_red_streak" && lowMomentsPrefetch?.key?.startsWith(`recent_flow_red_streak-${effectiveDateString}-${effectiveShiftId}-`) && lowMomentsPrefetch.loading
49614
+ )
49615
+ },
48882
49616
  activeCategoryLoading: isCategoryLoading,
48883
49617
  idleClipSort,
48884
49618
  onIdleClipSortChange: setIdleClipSort,
@@ -48994,10 +49728,10 @@ var BottlenecksContent = ({
48994
49728
  ] }) })
48995
49729
  ] });
48996
49730
  })()
48997
- ) : /* @__PURE__ */ jsx("div", { className: "absolute top-4 right-20 z-50 bg-black/60 backdrop-blur-sm px-4 py-2 rounded-lg text-white shadow-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
49731
+ ) : /* @__PURE__ */ jsx("div", { className: `absolute top-4 z-50 bg-black/60 backdrop-blur-sm px-4 py-2 rounded-lg text-white shadow-lg ${currentVideo.type === "recent_flow_red_streak" ? "left-4" : "right-20"}`, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
48998
49732
  /* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-3 w-3 rounded-full ${getSeverityColor(currentVideo.severity)} mr-2 animate-pulse` }),
48999
49733
  /* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
49000
- /* @__PURE__ */ jsx("span", { className: "opacity-80", children: currentVideo.description })
49734
+ currentVideo.type !== "recent_flow_red_streak" && /* @__PURE__ */ jsx("span", { className: "opacity-80", children: currentVideo.description })
49001
49735
  ] }) }),
49002
49736
  /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center p-8", children: /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full max-w-7xl group", children: [
49003
49737
  /* @__PURE__ */ jsx(
@@ -49033,12 +49767,26 @@ var BottlenecksContent = ({
49033
49767
  onShare: handleShareClip,
49034
49768
  isShareLoading,
49035
49769
  isShareCopied,
49770
+ timelineAnnotations: currentVideo.red_flow_timeline,
49771
+ timelineExplanation: currentVideo.red_flow_explanation,
49772
+ timelineTimezone: timezone,
49036
49773
  options: videoPlayerOptions
49037
49774
  },
49038
49775
  `${currentVideo.id}-${playerInstanceNonce}-fullscreen`
49039
49776
  )
49040
49777
  }
49041
49778
  ),
49779
+ currentVideo.type === "recent_flow_red_streak" && !shouldDeferPlayerRenderForCrop ? /* @__PURE__ */ jsx(
49780
+ RedFlowDiagnosticOverlay,
49781
+ {
49782
+ timeline: currentVideo.red_flow_timeline,
49783
+ explanation: currentVideo.red_flow_explanation,
49784
+ aiSummary: currentLowEfficiencyAiSummary,
49785
+ aiSummaryLoading: isCurrentLowEfficiencyAiSummaryLoading,
49786
+ aiSummaryError: currentLowEfficiencyAiSummaryError,
49787
+ className: "right-8 top-8"
49788
+ }
49789
+ ) : null,
49042
49790
  showBlockingVideoLoader && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
49043
49791
  !shouldDeferPlayerRenderForCrop && !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
49044
49792
  /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-white", children: [
@@ -51061,8 +51809,8 @@ var IdleTimeReasonChartComponent = ({
51061
51809
  updateAnimation = "replay",
51062
51810
  variant = "pie"
51063
51811
  }) => {
51064
- const [activeData, setActiveData] = React147__default.useState([]);
51065
- React147__default.useEffect(() => {
51812
+ const [activeData, setActiveData] = React148__default.useState([]);
51813
+ React148__default.useEffect(() => {
51066
51814
  if (updateAnimation === "smooth") {
51067
51815
  setActiveData(data && data.length > 0 ? data : []);
51068
51816
  return;
@@ -51081,7 +51829,7 @@ var IdleTimeReasonChartComponent = ({
51081
51829
  setActiveData([]);
51082
51830
  }
51083
51831
  }, [data, updateAnimation]);
51084
- React147__default.useEffect(() => {
51832
+ React148__default.useEffect(() => {
51085
51833
  if (!data || data.length === 0) return;
51086
51834
  data.forEach((entry, index) => {
51087
51835
  if (entry.name.toLowerCase().includes("other")) {
@@ -51089,7 +51837,7 @@ var IdleTimeReasonChartComponent = ({
51089
51837
  }
51090
51838
  });
51091
51839
  }, [data]);
51092
- const pieKey = React147__default.useMemo(() => {
51840
+ const pieKey = React148__default.useMemo(() => {
51093
51841
  if (updateAnimation === "smooth") {
51094
51842
  return "smooth";
51095
51843
  }
@@ -51259,7 +52007,7 @@ var IdleTimeReasonChartComponent = ({
51259
52007
  )
51260
52008
  ] });
51261
52009
  };
51262
- var IdleTimeReasonChart = React147__default.memo(IdleTimeReasonChartComponent);
52010
+ var IdleTimeReasonChart = React148__default.memo(IdleTimeReasonChartComponent);
51263
52011
  IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
51264
52012
  var IdleTimeReasonChart_default = IdleTimeReasonChart;
51265
52013
 
@@ -53483,7 +54231,7 @@ var StatusIndicator = ({ status }) => {
53483
54231
  case "bottleneck":
53484
54232
  return /* @__PURE__ */ jsx(Zap, { className: "h-5 w-5 text-orange-400", "aria-label": "Bottleneck" });
53485
54233
  case "lowEfficiency":
53486
- return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-5 w-5 text-red-400", "aria-label": "Low Efficiency" });
54234
+ return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-5 w-5 text-red-400", "aria-label": "Low moments" });
53487
54235
  case "inactive":
53488
54236
  return /* @__PURE__ */ jsx("div", { className: "h-3 w-3 bg-gray-400 rounded-full", title: "Inactive", "aria-label": "Inactive Workspace" });
53489
54237
  default:
@@ -55786,13 +56534,13 @@ var WorkspaceCycleTimeMetricCards = ({
55786
56534
  liveSkuId
55787
56535
  }) => {
55788
56536
  const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
55789
- const activeSku = React147__default.useMemo(() => {
56537
+ const activeSku = React148__default.useMemo(() => {
55790
56538
  if (skuAware && activeSkuId && skuBreakdown) {
55791
56539
  return skuBreakdown.find((s) => s.sku_id === activeSkuId);
55792
56540
  }
55793
56541
  return null;
55794
56542
  }, [skuAware, activeSkuId, skuBreakdown]);
55795
- const displaySku = React147__default.useMemo(() => {
56543
+ const displaySku = React148__default.useMemo(() => {
55796
56544
  if (activeSku) return activeSku;
55797
56545
  if (skuAware && !activeSkuId && liveSkuId && skuBreakdown) {
55798
56546
  return skuBreakdown.find((s) => s.sku_id === liveSkuId) ?? null;
@@ -56037,7 +56785,7 @@ var arePropsEqual = (prevProps, nextProps) => {
56037
56785
  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
56038
56786
  prevProps.position.id === nextProps.position.id;
56039
56787
  };
56040
- var WorkspaceGridItem = React147__default.memo(({
56788
+ var WorkspaceGridItem = React148__default.memo(({
56041
56789
  data,
56042
56790
  position,
56043
56791
  isBottleneck = false,
@@ -56132,7 +56880,7 @@ var WorkspaceGridItem = React147__default.memo(({
56132
56880
  );
56133
56881
  }, arePropsEqual);
56134
56882
  WorkspaceGridItem.displayName = "WorkspaceGridItem";
56135
- var WorkspaceGrid = React147__default.memo(({
56883
+ var WorkspaceGrid = React148__default.memo(({
56136
56884
  workspaces,
56137
56885
  blueComparisonWorkspaces,
56138
56886
  isPdfMode = false,
@@ -56385,7 +57133,7 @@ var KPICard = ({
56385
57133
  }) => {
56386
57134
  useThemeConfig();
56387
57135
  const { formatNumber } = useFormatNumber();
56388
- const trendInfo = React147__default.useMemo(() => {
57136
+ const trendInfo = React148__default.useMemo(() => {
56389
57137
  let trendValue = trend || "neutral";
56390
57138
  if (change !== void 0 && trend === void 0) {
56391
57139
  trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
@@ -56412,7 +57160,7 @@ var KPICard = ({
56412
57160
  const shouldShowTrend = !(change === 0 && trend === void 0);
56413
57161
  return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
56414
57162
  }, [trend, change]);
56415
- const formattedValue = React147__default.useMemo(() => {
57163
+ const formattedValue = React148__default.useMemo(() => {
56416
57164
  if (title === "Quality Compliance" && typeof value === "number") {
56417
57165
  return value.toFixed(1);
56418
57166
  }
@@ -56426,7 +57174,7 @@ var KPICard = ({
56426
57174
  }
56427
57175
  return value;
56428
57176
  }, [value, title]);
56429
- const formattedChange = React147__default.useMemo(() => {
57177
+ const formattedChange = React148__default.useMemo(() => {
56430
57178
  if (change === void 0 || change === 0 && !showZeroChange) return null;
56431
57179
  const absChange = Math.abs(change);
56432
57180
  return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
@@ -57933,7 +58681,7 @@ var Breadcrumbs = ({ items }) => {
57933
58681
  }
57934
58682
  }
57935
58683
  };
57936
- 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(React147__default.Fragment, { children: [
58684
+ 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: [
57937
58685
  index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
57938
58686
  /* @__PURE__ */ jsxs(
57939
58687
  "span",
@@ -59457,7 +60205,7 @@ var AwardBadge = ({
59457
60205
  }) => {
59458
60206
  const styles2 = getBadgeStyles(type);
59459
60207
  const Icon2 = CustomIcon || getDefaultIcon(type);
59460
- const randomDelay = React147__default.useMemo(() => Math.random() * 2, []);
60208
+ const randomDelay = React148__default.useMemo(() => Math.random() * 2, []);
59461
60209
  const floatingAnimation = {
59462
60210
  animate: {
59463
60211
  y: [0, -10, 0],
@@ -67826,7 +68574,7 @@ function HomeView({
67826
68574
  animate: { opacity: 1, scale: 1 },
67827
68575
  transition: { duration: 0.3 },
67828
68576
  className: "h-full",
67829
- children: React147__default.createElement(WorkspaceGrid, {
68577
+ children: React148__default.createElement(WorkspaceGrid, {
67830
68578
  workspaces: workspaceMetricsWithBreakState,
67831
68579
  blueComparisonWorkspaces: currentBlueComparisonWorkspaceMetrics || workspaceMetricsWithBreakState,
67832
68580
  lineNames: mergedLineNames,
@@ -67859,7 +68607,7 @@ function HomeView({
67859
68607
  animate: { opacity: 1, scale: 1 },
67860
68608
  transition: { duration: 0.3 },
67861
68609
  className: "h-full",
67862
- children: React147__default.createElement(WorkspaceGrid, {
68610
+ children: React148__default.createElement(WorkspaceGrid, {
67863
68611
  workspaces: [],
67864
68612
  // Show empty grid while loading
67865
68613
  blueComparisonWorkspaces: [],
@@ -67906,7 +68654,7 @@ function HomeView({
67906
68654
  contentVariant: "plain"
67907
68655
  }
67908
68656
  ),
67909
- /* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(React147__default.Fragment, { children: [
68657
+ /* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(React148__default.Fragment, { children: [
67910
68658
  /* @__PURE__ */ jsx(
67911
68659
  motion.div,
67912
68660
  {
@@ -67985,7 +68733,7 @@ function HomeView({
67985
68733
  "all-green-center-toast"
67986
68734
  )
67987
68735
  ] }, "all-green-celebration") : null }),
67988
- /* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(React147__default.Fragment, { children: [
68736
+ /* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(React148__default.Fragment, { children: [
67989
68737
  /* @__PURE__ */ jsx(
67990
68738
  motion.div,
67991
68739
  {
@@ -68079,7 +68827,7 @@ function HomeView({
68079
68827
  }
68080
68828
  );
68081
68829
  }
68082
- var AuthenticatedHomeView = withAuth(React147__default.memo(HomeView));
68830
+ var AuthenticatedHomeView = withAuth(React148__default.memo(HomeView));
68083
68831
  var HomeView_default = HomeView;
68084
68832
  function withWorkspaceDisplayNames(Component3, options = {}) {
68085
68833
  const {
@@ -71428,7 +72176,14 @@ var formatSupervisorFirstNames = (supervisors, fallbackSupervisorNames) => {
71428
72176
  return fallbackFirstNames.length > 0 ? Array.from(new Set(fallbackFirstNames)).join(", ") : "Unassigned";
71429
72177
  };
71430
72178
  var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Finished", placeholder = "--", onFinished }) => {
71431
- const [time2, setTime] = useState("");
72179
+ const [time2, setTime] = useState(() => {
72180
+ if (!targetDate) return "";
72181
+ return targetDate.getTime() <= Date.now() ? finishedLabel : "";
72182
+ });
72183
+ const [showEndsInPrefix, setShowEndsInPrefix] = useState(() => {
72184
+ if (!targetDate) return true;
72185
+ return targetDate.getTime() > Date.now();
72186
+ });
71432
72187
  const hasFinishedRef = useRef(false);
71433
72188
  useEffect(() => {
71434
72189
  hasFinishedRef.current = false;
@@ -71436,12 +72191,14 @@ var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Fin
71436
72191
  useEffect(() => {
71437
72192
  if (!targetDate) {
71438
72193
  setTime(placeholder);
72194
+ setShowEndsInPrefix(true);
71439
72195
  return;
71440
72196
  }
71441
72197
  const tick = () => {
71442
72198
  const now4 = /* @__PURE__ */ new Date();
71443
72199
  const diff = targetDate.getTime() - now4.getTime();
71444
72200
  if (diff <= 0) {
72201
+ setShowEndsInPrefix(false);
71445
72202
  setTime(finishedLabel);
71446
72203
  if (!hasFinishedRef.current && onFinished) {
71447
72204
  hasFinishedRef.current = true;
@@ -71449,6 +72206,7 @@ var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Fin
71449
72206
  }
71450
72207
  return;
71451
72208
  }
72209
+ setShowEndsInPrefix(true);
71452
72210
  if (format10 === "days") {
71453
72211
  const days = Math.floor(diff / (1e3 * 60 * 60 * 24));
71454
72212
  const hours = Math.floor(diff % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60));
@@ -71465,7 +72223,10 @@ var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Fin
71465
72223
  const interval = setInterval(tick, 1e3);
71466
72224
  return () => clearInterval(interval);
71467
72225
  }, [targetDate, format10, finishedLabel, placeholder, onFinished]);
71468
- return /* @__PURE__ */ jsx(Fragment, { children: time2 });
72226
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
72227
+ showEndsInPrefix && /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider", children: "Ends in" }),
72228
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-gray-900 tabular-nums tracking-tight font-mono", children: time2 })
72229
+ ] });
71469
72230
  };
71470
72231
  var LinesLeaderboard = ({
71471
72232
  lines,
@@ -71488,18 +72249,18 @@ var LinesLeaderboard = ({
71488
72249
  isHistoricalDaily
71489
72250
  }) => {
71490
72251
  const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
71491
- const assignedLineIdSet = React147__default.useMemo(
72252
+ const assignedLineIdSet = React148__default.useMemo(
71492
72253
  () => new Set(assignedLineIds || []),
71493
72254
  [assignedLineIds]
71494
72255
  );
71495
- const canClickLine = React147__default.useCallback(
72256
+ const canClickLine = React148__default.useCallback(
71496
72257
  (lineId) => {
71497
72258
  if (!assignedLineIds) return true;
71498
72259
  return assignedLineIdSet.has(lineId);
71499
72260
  },
71500
72261
  [assignedLineIds, assignedLineIdSet]
71501
72262
  );
71502
- const handleTimeRangeChange = React147__default.useCallback((newRange) => {
72263
+ const handleTimeRangeChange = React148__default.useCallback((newRange) => {
71503
72264
  if (newRange === timeRange) return;
71504
72265
  trackCoreEvent("Leaderboard Time Range Changed", {
71505
72266
  from_range: timeRange,
@@ -71510,11 +72271,11 @@ var LinesLeaderboard = ({
71510
72271
  });
71511
72272
  setTimeRange(newRange);
71512
72273
  }, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
71513
- const canClickLeaderboardRow = React147__default.useCallback(
72274
+ const canClickLeaderboardRow = React148__default.useCallback(
71514
72275
  (item) => item.rowType === "line" && !!item.line && canClickLine(item.line.id),
71515
72276
  [canClickLine]
71516
72277
  );
71517
- const handleLeaderboardLineClick = React147__default.useCallback((item, clickSource) => {
72278
+ const handleLeaderboardLineClick = React148__default.useCallback((item, clickSource) => {
71518
72279
  if (!canClickLeaderboardRow(item) || !item.line) return;
71519
72280
  trackCoreEvent("Leaderboard Line Clicked", {
71520
72281
  line_id: item.line.id,
@@ -71528,8 +72289,8 @@ var LinesLeaderboard = ({
71528
72289
  });
71529
72290
  onLineClick(item.line);
71530
72291
  }, [canClickLeaderboardRow, onLineClick, timeRange]);
71531
- const viewLoadedTrackedRef = React147__default.useRef(null);
71532
- const leaderboardData = React147__default.useMemo(() => {
72292
+ const viewLoadedTrackedRef = React148__default.useRef(null);
72293
+ const leaderboardData = React148__default.useMemo(() => {
71533
72294
  const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
71534
72295
  const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
71535
72296
  const fallbackEfficiencyMap = timeRange === "today" ? dailyFallbackEfficiencyByLineId : void 0;
@@ -71573,7 +72334,7 @@ var LinesLeaderboard = ({
71573
72334
  isLoadingToday,
71574
72335
  isLoadingMonthly
71575
72336
  ]);
71576
- React147__default.useEffect(() => {
72337
+ React148__default.useEffect(() => {
71577
72338
  const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
71578
72339
  const trackingKey = `${timeRange}-${leaderboardData.length}`;
71579
72340
  if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
@@ -71597,9 +72358,9 @@ var LinesLeaderboard = ({
71597
72358
  const topThree = leaderboardData.slice(0, 3);
71598
72359
  const countdownTarget = timeRange === "monthly" ? monthEndDate : shiftEndDate;
71599
72360
  const countdownFormat = timeRange === "monthly" ? "days" : "clock";
71600
- const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift Ended";
72361
+ const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift ended";
71601
72362
  const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
71602
- const handleCountdownFinished = React147__default.useCallback(() => {
72363
+ const handleCountdownFinished = React148__default.useCallback(() => {
71603
72364
  trackCoreEvent("Leaderboard Countdown Finished", {
71604
72365
  countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
71605
72366
  time_range: timeRange,
@@ -71626,7 +72387,7 @@ var LinesLeaderboard = ({
71626
72387
  return "bg-white border-gray-100";
71627
72388
  }
71628
72389
  };
71629
- React147__default.useEffect(() => {
72390
+ React148__default.useEffect(() => {
71630
72391
  const style = document.createElement("style");
71631
72392
  style.innerHTML = `
71632
72393
  @keyframes float {
@@ -71674,19 +72435,16 @@ var LinesLeaderboard = ({
71674
72435
  ] }),
71675
72436
  /* @__PURE__ */ jsx("div", { className: "md:absolute md:right-0 md:top-1/2 md:-translate-y-1/2 flex flex-wrap items-center justify-center md:justify-end gap-2", children: showCountdown && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 px-4 py-2 bg-white rounded-full shadow-sm border border-gray-100", children: [
71676
72437
  /* @__PURE__ */ jsx(Clock, { className: "w-4 h-4 text-orange-500" }),
71677
- /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
71678
- /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider", children: "Ends in" }),
71679
- /* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-gray-900 tabular-nums tracking-tight font-mono", children: /* @__PURE__ */ jsx(
71680
- LeaderboardCountdown,
71681
- {
71682
- targetDate: countdownTarget,
71683
- format: countdownFormat,
71684
- finishedLabel: countdownFinishedLabel,
71685
- placeholder: timeRange === "monthly" ? "--" : "--:--:--",
71686
- onFinished: handleCountdownFinished
71687
- }
71688
- ) })
71689
- ] })
72438
+ /* @__PURE__ */ jsx("div", { className: "flex items-baseline gap-2", children: /* @__PURE__ */ jsx(
72439
+ LeaderboardCountdown,
72440
+ {
72441
+ targetDate: countdownTarget,
72442
+ format: countdownFormat,
72443
+ finishedLabel: countdownFinishedLabel,
72444
+ placeholder: timeRange === "monthly" ? "--" : "--:--:--",
72445
+ onFinished: handleCountdownFinished
72446
+ }
72447
+ ) })
71690
72448
  ] }) })
71691
72449
  ] }),
71692
72450
  /* @__PURE__ */ jsx("div", { className: "flex-1 hidden sm:flex justify-center items-end gap-2 md:gap-4 lg:gap-6 xl:gap-10 pb-4 pt-4 min-h-0", children: podiumOrder.map((item, index) => {
@@ -72128,36 +72886,36 @@ var KPIsOverviewView = ({
72128
72886
  const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
72129
72887
  const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
72130
72888
  const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
72131
- const scopedLineIds = React147__default.useMemo(
72889
+ const scopedLineIds = React148__default.useMemo(
72132
72890
  () => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
72133
72891
  [user?.access_scope?.line_ids]
72134
72892
  );
72135
72893
  const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
72136
72894
  const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
72137
72895
  const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
72138
- const resolvedAssignedLineIds = React147__default.useMemo(() => {
72896
+ const resolvedAssignedLineIds = React148__default.useMemo(() => {
72139
72897
  if (isSuperAdmin) return [];
72140
72898
  if (scopedLineIds.length > 0) return scopedLineIds;
72141
72899
  if (lineIds && lineIds.length > 0) return lineIds;
72142
72900
  if (isStrictLineScopedRole && hasCanonicalScope) return [];
72143
72901
  return [];
72144
72902
  }, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
72145
- const assignedLineIdSet = React147__default.useMemo(
72903
+ const assignedLineIdSet = React148__default.useMemo(
72146
72904
  () => new Set(resolvedAssignedLineIds),
72147
72905
  [resolvedAssignedLineIds]
72148
72906
  );
72149
- const loadedLineIds = React147__default.useMemo(
72907
+ const loadedLineIds = React148__default.useMemo(
72150
72908
  () => lines.map((line) => line.id).filter(Boolean),
72151
72909
  [lines]
72152
72910
  );
72153
- const metricsLineIds = React147__default.useMemo(() => {
72911
+ const metricsLineIds = React148__default.useMemo(() => {
72154
72912
  if (isSuperAdmin) {
72155
72913
  return loadedLineIds.length > 0 ? loadedLineIds : lineIds ?? [];
72156
72914
  }
72157
72915
  return resolvedAssignedLineIds;
72158
72916
  }, [isSuperAdmin, loadedLineIds, lineIds, resolvedAssignedLineIds]);
72159
72917
  const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
72160
- const leaderboardLinesForView = React147__default.useMemo(() => {
72918
+ const leaderboardLinesForView = React148__default.useMemo(() => {
72161
72919
  const targetMode = viewType === "machine" ? "uptime" : "output";
72162
72920
  const metadataByLineId = new Map(lines.map((line) => [line.id, line]));
72163
72921
  return leaderboardLines.map((line) => {
@@ -72176,17 +72934,17 @@ var KPIsOverviewView = ({
72176
72934
  } : line;
72177
72935
  }).filter((line) => (line.monitoring_mode ?? "output") === targetMode);
72178
72936
  }, [leaderboardLines, lines, viewType]);
72179
- const linesForView = React147__default.useMemo(() => {
72937
+ const linesForView = React148__default.useMemo(() => {
72180
72938
  const targetMode = viewType === "machine" ? "uptime" : "output";
72181
72939
  return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
72182
72940
  }, [lines, viewType]);
72183
- const relevantLinesForMode = React147__default.useMemo(() => {
72941
+ const relevantLinesForMode = React148__default.useMemo(() => {
72184
72942
  if (activeTab === "leaderboard") {
72185
72943
  return leaderboardLines.length > 0 ? leaderboardLines : lines;
72186
72944
  }
72187
72945
  return lines;
72188
72946
  }, [activeTab, leaderboardLines, lines]);
72189
- const { hasUptime, hasOutput } = React147__default.useMemo(() => {
72947
+ const { hasUptime, hasOutput } = React148__default.useMemo(() => {
72190
72948
  let uptime = false;
72191
72949
  let output = false;
72192
72950
  for (const line of relevantLinesForMode) {
@@ -72211,14 +72969,14 @@ var KPIsOverviewView = ({
72211
72969
  const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
72212
72970
  const currentShiftDate = currentShiftDetails.date;
72213
72971
  const currentShiftId = currentShiftDetails.shiftId;
72214
- const activeFiltersCount = React147__default.useMemo(() => {
72972
+ const activeFiltersCount = React148__default.useMemo(() => {
72215
72973
  let count = 0;
72216
72974
  if (leaderboardDailyScopeMode === "historical" && selectedLeaderboardShiftId !== currentShiftId) {
72217
72975
  count++;
72218
72976
  }
72219
72977
  return count;
72220
72978
  }, [leaderboardDailyScopeMode, selectedLeaderboardShiftId, currentShiftId]);
72221
- const clearFilters = React147__default.useCallback(() => {
72979
+ const clearFilters = React148__default.useCallback(() => {
72222
72980
  setSelectedLeaderboardShiftId(currentShiftId);
72223
72981
  setSelectedLeaderboardDate(currentShiftDate);
72224
72982
  setLeaderboardDailyScopeMode("live");
@@ -72234,11 +72992,11 @@ var KPIsOverviewView = ({
72234
72992
  document.addEventListener("mousedown", handleClickOutside);
72235
72993
  return () => document.removeEventListener("mousedown", handleClickOutside);
72236
72994
  }, []);
72237
- const shiftEndDate = React147__default.useMemo(
72995
+ const shiftEndDate = React148__default.useMemo(
72238
72996
  () => getShiftEndDate(currentShiftDetails, configuredTimezone),
72239
72997
  [currentShiftDetails, configuredTimezone]
72240
72998
  );
72241
- const leaderboardShiftOptions = React147__default.useMemo(() => {
72999
+ const leaderboardShiftOptions = React148__default.useMemo(() => {
72242
73000
  if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
72243
73001
  return shiftConfig.shifts.map((shift) => ({
72244
73002
  id: shift.shiftId,
@@ -72255,34 +73013,34 @@ var KPIsOverviewView = ({
72255
73013
  const effectiveLeaderboardDate = selectedLeaderboardDate || currentShiftDate;
72256
73014
  const effectiveLeaderboardShiftId = Number.isFinite(selectedLeaderboardShiftId) ? selectedLeaderboardShiftId : currentShiftId;
72257
73015
  const isHistoricalLeaderboardDaily = activeTab === "leaderboard" && timeRange === "today" && leaderboardDailyScopeMode === "historical" && (effectiveLeaderboardDate !== currentShiftDate || effectiveLeaderboardShiftId !== currentShiftId);
72258
- const updateLeaderboardDate = React147__default.useCallback((dateKey) => {
73016
+ const updateLeaderboardDate = React148__default.useCallback((dateKey) => {
72259
73017
  setSelectedLeaderboardDate(dateKey);
72260
73018
  setLeaderboardDailyScopeMode(
72261
73019
  dateKey === currentShiftDate && effectiveLeaderboardShiftId === currentShiftId ? "live" : "historical"
72262
73020
  );
72263
73021
  }, [currentShiftDate, currentShiftId, effectiveLeaderboardShiftId]);
72264
- const updateLeaderboardShiftId = React147__default.useCallback((shiftId) => {
73022
+ const updateLeaderboardShiftId = React148__default.useCallback((shiftId) => {
72265
73023
  setSelectedLeaderboardShiftId(shiftId);
72266
73024
  setLeaderboardDailyScopeMode(
72267
73025
  effectiveLeaderboardDate === currentShiftDate && shiftId === currentShiftId ? "live" : "historical"
72268
73026
  );
72269
73027
  }, [currentShiftDate, currentShiftId, effectiveLeaderboardDate]);
72270
- const returnLeaderboardToLive = React147__default.useCallback(() => {
73028
+ const returnLeaderboardToLive = React148__default.useCallback(() => {
72271
73029
  setSelectedLeaderboardDate(currentShiftDate);
72272
73030
  setSelectedLeaderboardShiftId(currentShiftId);
72273
73031
  setLeaderboardDailyScopeMode("live");
72274
73032
  }, [currentShiftDate, currentShiftId]);
72275
73033
  const selectedFactoryIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_QUERY_PARAM]);
72276
73034
  const selectedFactoryAreaIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_AREA_QUERY_PARAM]);
72277
- const kpiLineHierarchy = React147__default.useMemo(
73035
+ const kpiLineHierarchy = React148__default.useMemo(
72278
73036
  () => buildKpiLineHierarchy(linesForView),
72279
73037
  [linesForView]
72280
73038
  );
72281
- const selectedFactoryNode = React147__default.useMemo(
73039
+ const selectedFactoryNode = React148__default.useMemo(
72282
73040
  () => kpiLineHierarchy.showFactoryLevel && selectedFactoryIdFromUrl ? kpiLineHierarchy.factories.find((factory) => factory.id === selectedFactoryIdFromUrl) : void 0,
72283
73041
  [kpiLineHierarchy, selectedFactoryIdFromUrl]
72284
73042
  );
72285
- const selectedFactoryAreaNode = React147__default.useMemo(
73043
+ const selectedFactoryAreaNode = React148__default.useMemo(
72286
73044
  () => selectedFactoryNode && selectedFactoryAreaIdFromUrl ? selectedFactoryNode.areas.find((area) => area.id === selectedFactoryAreaIdFromUrl) : void 0,
72287
73045
  [selectedFactoryNode, selectedFactoryAreaIdFromUrl]
72288
73046
  );
@@ -72371,15 +73129,15 @@ var KPIsOverviewView = ({
72371
73129
  lineId: factoryViewId,
72372
73130
  userAccessibleLineIds: metricsLineIds
72373
73131
  });
72374
- const defaultKPIs = React147__default.useMemo(() => createDefaultKPIs(), []);
72375
- const lineModeById = React147__default.useMemo(() => {
73132
+ const defaultKPIs = React148__default.useMemo(() => createDefaultKPIs(), []);
73133
+ const lineModeById = React148__default.useMemo(() => {
72376
73134
  const map = /* @__PURE__ */ new Map();
72377
73135
  linesForView.forEach((line) => {
72378
73136
  map.set(line.id, line.monitoring_mode ?? "output");
72379
73137
  });
72380
73138
  return map;
72381
73139
  }, [linesForView]);
72382
- const lineMetricRowsByLineId = React147__default.useMemo(() => {
73140
+ const lineMetricRowsByLineId = React148__default.useMemo(() => {
72383
73141
  const map = /* @__PURE__ */ new Map();
72384
73142
  lineMetrics.forEach((row) => {
72385
73143
  if (!row?.line_id) return;
@@ -72391,7 +73149,7 @@ var KPIsOverviewView = ({
72391
73149
  });
72392
73150
  return map;
72393
73151
  }, [lineMetrics, lineModeById]);
72394
- const liveDailyFallbackEfficiencyByLineId = React147__default.useMemo(() => {
73152
+ const liveDailyFallbackEfficiencyByLineId = React148__default.useMemo(() => {
72395
73153
  const map = /* @__PURE__ */ new Map();
72396
73154
  lineMetricRowsByLineId.forEach((row, lineId) => {
72397
73155
  const value = Number(row?.avg_efficiency);
@@ -72413,31 +73171,31 @@ var KPIsOverviewView = ({
72413
73171
  isHistoricalLeaderboardDaily,
72414
73172
  lineMetricRowsByLineId
72415
73173
  ]);
72416
- const dailyFallbackEfficiencyByLineId = React147__default.useMemo(() => {
73174
+ const dailyFallbackEfficiencyByLineId = React148__default.useMemo(() => {
72417
73175
  const map = new Map(liveDailyFallbackEfficiencyByLineId);
72418
73176
  scopedDailyFallbackEfficiencyByLineId.forEach((value, lineId) => {
72419
73177
  map.set(lineId, value);
72420
73178
  });
72421
73179
  return map;
72422
73180
  }, [liveDailyFallbackEfficiencyByLineId, scopedDailyFallbackEfficiencyByLineId]);
72423
- const kpisByLineId = React147__default.useMemo(() => {
73181
+ const kpisByLineId = React148__default.useMemo(() => {
72424
73182
  const map = /* @__PURE__ */ new Map();
72425
73183
  lineMetricRowsByLineId.forEach((row, lineId) => {
72426
73184
  map.set(lineId, buildKPIsFromLineMetricsRow(row));
72427
73185
  });
72428
73186
  return map;
72429
73187
  }, [lineMetricRowsByLineId]);
72430
- const getLineCardKpis = React147__default.useCallback((line) => {
73188
+ const getLineCardKpis = React148__default.useCallback((line) => {
72431
73189
  if (metricsError) return null;
72432
73190
  return kpisByLineId.get(line.id) ?? (metricsLoading ? null : defaultKPIs);
72433
73191
  }, [defaultKPIs, kpisByLineId, metricsError, metricsLoading]);
72434
- const getAggregateCardKpis = React147__default.useCallback((cardLines) => {
73192
+ const getAggregateCardKpis = React148__default.useCallback((cardLines) => {
72435
73193
  if (metricsError) return null;
72436
73194
  const rows = cardLines.map((line) => lineMetricRowsByLineId.get(line.id)).filter(Boolean);
72437
73195
  if (metricsLoading && rows.length === 0) return null;
72438
73196
  return aggregateKPIsFromLineMetricsRows(rows);
72439
73197
  }, [lineMetricRowsByLineId, metricsError, metricsLoading]);
72440
- const supervisorLineIds = React147__default.useMemo(
73198
+ const supervisorLineIds = React148__default.useMemo(
72441
73199
  () => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
72442
73200
  [leaderboardLines, lines]
72443
73201
  );
@@ -72689,7 +73447,7 @@ var KPIsOverviewView = ({
72689
73447
  { shallow: true }
72690
73448
  );
72691
73449
  }, [router]);
72692
- const lineDetailReturnTo = React147__default.useMemo(() => {
73450
+ const lineDetailReturnTo = React148__default.useMemo(() => {
72693
73451
  if (activeTab !== "today" || !selectedFactoryNode) return void 0;
72694
73452
  return createKpisOverviewUrl({
72695
73453
  factoryId: selectedFactoryNode.id,
@@ -73489,7 +74247,7 @@ var LeaderboardDetailView = memo$1(({
73489
74247
  return () => document.removeEventListener("mousedown", handleClickOutside);
73490
74248
  }, []);
73491
74249
  const [isMobile, setIsMobile] = useState(false);
73492
- React147__default.useEffect(() => {
74250
+ React148__default.useEffect(() => {
73493
74251
  const checkMobile = () => setIsMobile(window.innerWidth < 640);
73494
74252
  checkMobile();
73495
74253
  window.addEventListener("resize", checkMobile);
@@ -77539,7 +78297,7 @@ var ShiftsView = ({
77539
78297
  ] })
77540
78298
  ] });
77541
78299
  };
77542
- var AuthenticatedShiftsView = withAuth(React147__default.memo(ShiftsView));
78300
+ var AuthenticatedShiftsView = withAuth(React148__default.memo(ShiftsView));
77543
78301
  var ShiftsView_default = ShiftsView;
77544
78302
 
77545
78303
  // src/views/TargetsView.utils.ts
@@ -79406,7 +80164,7 @@ var TargetsView = ({
79406
80164
  };
79407
80165
  var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
79408
80166
  var TargetsView_default = TargetsViewWithDisplayNames;
79409
- var AuthenticatedTargetsView = withAuth(React147__default.memo(TargetsViewWithDisplayNames));
80167
+ var AuthenticatedTargetsView = withAuth(React148__default.memo(TargetsViewWithDisplayNames));
79410
80168
  function useTimezone(options = {}) {
79411
80169
  const dashboardConfig = useDashboardConfig();
79412
80170
  const workspaceConfig = useWorkspaceConfig();
@@ -79554,7 +80312,7 @@ var formatWholeNumber = (value) => {
79554
80312
  if (typeof value !== "number" || !Number.isFinite(value)) return null;
79555
80313
  return Math.round(value).toLocaleString();
79556
80314
  };
79557
- var formatSeconds = (value) => {
80315
+ var formatSeconds2 = (value) => {
79558
80316
  if (typeof value !== "number" || !Number.isFinite(value)) return null;
79559
80317
  return `${value.toFixed(1)}s`;
79560
80318
  };
@@ -79571,13 +80329,13 @@ var WorkspaceHourSummaryPanel = ({
79571
80329
  }) => {
79572
80330
  const { data, isLoading, error, summarize, reset } = useWorkspaceHourSummary();
79573
80331
  const selectedKey = selectedHour ? `${selectedHour.source}:${selectedHour.hourIndex}:${date}:${shiftId}` : "none";
79574
- const autoSummaryKeyRef = React147__default.useRef(null);
79575
- React147__default.useEffect(() => {
80332
+ const autoSummaryKeyRef = React148__default.useRef(null);
80333
+ React148__default.useEffect(() => {
79576
80334
  reset();
79577
80335
  autoSummaryKeyRef.current = null;
79578
80336
  }, [reset, selectedKey]);
79579
80337
  const canSummarize = Boolean(workspaceId && companyId && date && shiftId !== null && shiftId !== void 0);
79580
- React147__default.useEffect(() => {
80338
+ React148__default.useEffect(() => {
79581
80339
  if (!selectedHour || !canSummarize || !companyId || !date || shiftId === null || shiftId === void 0) {
79582
80340
  return;
79583
80341
  }
@@ -79606,8 +80364,8 @@ var WorkspaceHourSummaryPanel = ({
79606
80364
  const formattedTimeRange = formatTimeRangeTo12Hour(verifiedTimeRange);
79607
80365
  const selectedMetric = selectedHour.source === "cycle" ? {
79608
80366
  label: "Cycle time",
79609
- actual: formatSeconds(selectedHour.cycleTime),
79610
- standard: formatSeconds(selectedHour.idealCycleTime)
80367
+ actual: formatSeconds2(selectedHour.cycleTime),
80368
+ standard: formatSeconds2(selectedHour.idealCycleTime)
79611
80369
  } : {
79612
80370
  label: "Hourly output",
79613
80371
  actual: formatWholeNumber(selectedHour.output),
@@ -79783,6 +80541,7 @@ var WorkspaceDetailView = ({
79783
80541
  const { legend: efficiencyLegend } = useEfficiencyLegend();
79784
80542
  const prewarmedClipsRef = useRef(/* @__PURE__ */ new Set());
79785
80543
  const prewarmInFlightRef = useRef(/* @__PURE__ */ new Set());
80544
+ const [lowMomentsPrefetch, setLowMomentsPrefetch] = useState(null);
79786
80545
  const [aiSummaryHour, setAiSummaryHour] = useState(null);
79787
80546
  const buildHourlyOutputActionTrackingProps = useCallback((payload) => ({
79788
80547
  workspace_id: workspaceId,
@@ -80295,13 +81054,108 @@ var WorkspaceDetailView = ({
80295
81054
  }
80296
81055
  prewarmInFlightRef.current.add(cacheKey);
80297
81056
  const s3Service = videoPrefetchManager.getS3Service(dashboardConfig);
80298
- s3Service.getClipsInit(workspaceId, resolvedDate, resolvedShiftId, totalOutput).then(() => {
80299
- prewarmedClipsRef.current.add(cacheKey);
80300
- }).catch((error2) => {
80301
- console.warn("[WorkspaceDetailView] Clips init prewarm failed:", error2);
80302
- }).finally(() => {
80303
- prewarmInFlightRef.current.delete(cacheKey);
80304
- });
81057
+ const controller = new AbortController();
81058
+ let cancelled = false;
81059
+ const prefetchLowMoments = async () => {
81060
+ try {
81061
+ const initData = await s3Service.getClipsInit(workspaceId, resolvedDate, resolvedShiftId, totalOutput);
81062
+ const lowMomentsCount = Number(initData?.counts?.recent_flow_red_streak || 0);
81063
+ const lowMomentsKey = [
81064
+ "recent_flow_red_streak",
81065
+ resolvedDate,
81066
+ resolvedShiftId,
81067
+ initData?.snapshotDateTime ?? "nosnap",
81068
+ initData?.snapshotClipId ?? "nosnap",
81069
+ "red_flow_output_shortfall_desc"
81070
+ ].join("-");
81071
+ if (cancelled) {
81072
+ return;
81073
+ }
81074
+ const initFirstVideo = initData?.firstClips?.recent_flow_red_streak ?? null;
81075
+ if (lowMomentsCount <= 0) {
81076
+ setLowMomentsPrefetch((prev) => prev?.key === lowMomentsKey ? {
81077
+ key: lowMomentsKey,
81078
+ metadata: [],
81079
+ firstVideo: null,
81080
+ total: 0,
81081
+ loading: false,
81082
+ error: null
81083
+ } : prev);
81084
+ prewarmedClipsRef.current.add(cacheKey);
81085
+ return;
81086
+ }
81087
+ setLowMomentsPrefetch((prev) => {
81088
+ if (prev?.key === lowMomentsKey && !prev.loading && prev.metadata.length > 0) {
81089
+ return prev;
81090
+ }
81091
+ return {
81092
+ key: lowMomentsKey,
81093
+ metadata: prev?.key === lowMomentsKey ? prev.metadata : [],
81094
+ firstVideo: prev?.key === lowMomentsKey ? prev.firstVideo || initFirstVideo : initFirstVideo,
81095
+ total: lowMomentsCount,
81096
+ loading: true,
81097
+ error: null
81098
+ };
81099
+ });
81100
+ const metadataResponse = await fetchWithSupabaseAuth(supabase, "/api/clips/supabase", {
81101
+ method: "POST",
81102
+ headers: {
81103
+ "Content-Type": "application/json"
81104
+ },
81105
+ body: JSON.stringify({
81106
+ action: "clip-metadata",
81107
+ workspaceId,
81108
+ date: resolvedDate,
81109
+ shift: resolvedShiftId,
81110
+ category: "recent_flow_red_streak",
81111
+ page: 1,
81112
+ limit: 100,
81113
+ knownTotal: lowMomentsCount,
81114
+ snapshotDateTime: initData?.snapshotDateTime ?? null,
81115
+ snapshotClipId: initData?.snapshotClipId ?? null,
81116
+ sort: "red_flow_output_shortfall_desc"
81117
+ }),
81118
+ signal: controller.signal,
81119
+ redirectReason: "session_expired"
81120
+ });
81121
+ if (!metadataResponse.ok) {
81122
+ throw new Error(`Low moments metadata prefetch failed: ${metadataResponse.status}`);
81123
+ }
81124
+ const metadataData = await metadataResponse.json();
81125
+ const metadata = Array.isArray(metadataData?.clips) ? metadataData.clips : [];
81126
+ const firstClipId = metadata[0]?.clipId || metadata[0]?.id || null;
81127
+ const firstVideo = initFirstVideo && (!firstClipId || initFirstVideo.id === firstClipId) ? initFirstVideo : firstClipId ? await s3Service.getClipById(firstClipId) : null;
81128
+ if (cancelled) {
81129
+ return;
81130
+ }
81131
+ setLowMomentsPrefetch({
81132
+ key: lowMomentsKey,
81133
+ metadata,
81134
+ firstVideo,
81135
+ total: typeof metadataData?.total === "number" ? metadataData.total : lowMomentsCount,
81136
+ loading: false,
81137
+ error: null
81138
+ });
81139
+ prewarmedClipsRef.current.add(cacheKey);
81140
+ } catch (error2) {
81141
+ if (error2.name === "AbortError") {
81142
+ return;
81143
+ }
81144
+ console.warn("[WorkspaceDetailView] Clips init prewarm failed:", error2);
81145
+ setLowMomentsPrefetch((prev) => prev ? {
81146
+ ...prev,
81147
+ loading: false,
81148
+ error: error2 instanceof Error ? error2.message : "Low moments prefetch failed"
81149
+ } : prev);
81150
+ } finally {
81151
+ prewarmInFlightRef.current.delete(cacheKey);
81152
+ }
81153
+ };
81154
+ void prefetchLowMoments();
81155
+ return () => {
81156
+ cancelled = true;
81157
+ controller.abort();
81158
+ };
80305
81159
  }, [
80306
81160
  isClipsEnabled,
80307
81161
  dashboardConfig,
@@ -80311,7 +81165,8 @@ var WorkspaceDetailView = ({
80311
81165
  isShiftConfigLoading,
80312
81166
  shiftConfig,
80313
81167
  timezone,
80314
- workspace
81168
+ workspace,
81169
+ supabase
80315
81170
  ]);
80316
81171
  const { supervisorName, supervisors } = useLineSupervisor(workspace?.line_id || lineId);
80317
81172
  useEffect(() => {
@@ -81530,6 +82385,7 @@ var WorkspaceDetailView = ({
81530
82385
  totalOutput: workspace?.total_actions,
81531
82386
  workspaceMetrics: detailedWorkspaceMetrics || void 0,
81532
82387
  prefetchedPercentileCounts: isFastSlowClipFiltersEnabled ? prefetchedPercentileCounts : null,
82388
+ lowMomentsPrefetch,
81533
82389
  initialTimeFilter: pendingClipHourFilter,
81534
82390
  className: "h-[calc(100vh-10rem)]"
81535
82391
  }
@@ -83168,7 +84024,7 @@ function BottleneckClipsView({
83168
84024
  ) })
83169
84025
  ] }) });
83170
84026
  }
83171
- var AuthenticatedBottleneckClipsView = withAuth(React147__default.memo(BottleneckClipsView));
84027
+ var AuthenticatedBottleneckClipsView = withAuth(React148__default.memo(BottleneckClipsView));
83172
84028
  var BottleneckClipsView_default = BottleneckClipsView;
83173
84029
 
83174
84030
  // src/lib/services/ticketService.ts
@@ -84011,7 +84867,7 @@ Please ensure:
84011
84867
  )
84012
84868
  ] });
84013
84869
  }
84014
- var AuthenticatedTicketsView = withAuth(React147__default.memo(TicketsView));
84870
+ var AuthenticatedTicketsView = withAuth(React148__default.memo(TicketsView));
84015
84871
  var TicketsView_default = TicketsView;
84016
84872
 
84017
84873
  // src/lib/utils/improvementDisplay.ts
@@ -84982,7 +85838,7 @@ var ImprovementCenterView = () => {
84982
85838
  setSelectedMemberId("all");
84983
85839
  }
84984
85840
  }, [memberOptions, selectedMemberId]);
84985
- const getRecommendationDisplayMetadata = React147__default.useCallback((rec) => {
85841
+ const getRecommendationDisplayMetadata = React148__default.useCallback((rec) => {
84986
85842
  const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
84987
85843
  return getImprovementDisplayMetadata({
84988
85844
  location: rec.location,
@@ -85456,7 +86312,7 @@ var ThreadSidebar = ({
85456
86312
  ] }) })
85457
86313
  ] });
85458
86314
  };
85459
- var ProfilePicture = React147__default.memo(({
86315
+ var ProfilePicture = React148__default.memo(({
85460
86316
  alt = "Axel",
85461
86317
  className = "",
85462
86318
  size = "md",
@@ -88016,7 +88872,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
88016
88872
  ] }),
88017
88873
  /* @__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" }) })
88018
88874
  ] }, index)) });
88019
- var OperationsOverviewHeader = React147__default.memo(({
88875
+ var OperationsOverviewHeader = React148__default.memo(({
88020
88876
  dateRange,
88021
88877
  displayDateRange,
88022
88878
  trendMode,
@@ -88037,65 +88893,65 @@ var OperationsOverviewHeader = React147__default.memo(({
88037
88893
  bumpRenderCounter();
88038
88894
  const subtitleRange = displayDateRange || dateRange;
88039
88895
  const showLiveShiftMeta = isLiveScope && trendMode !== "all";
88040
- const liveShiftLabel = React147__default.useMemo(
88896
+ const liveShiftLabel = React148__default.useMemo(
88041
88897
  () => normalizeShiftLabel(liveShiftName, trendMode),
88042
88898
  [liveShiftName, trendMode]
88043
88899
  );
88044
- const liveShiftIcon = React147__default.useMemo(
88900
+ const liveShiftIcon = React148__default.useMemo(
88045
88901
  () => getShiftIcon(liveShiftName, trendMode),
88046
88902
  [liveShiftName, trendMode]
88047
88903
  );
88048
- const [isFilterOpen, setIsFilterOpen] = React147__default.useState(false);
88049
- const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React147__default.useState(false);
88050
- const filterRef = React147__default.useRef(null);
88051
- const filterButtonRef = React147__default.useRef(null);
88052
- const mobileFilterButtonRef = React147__default.useRef(null);
88053
- const linesDropdownRef = React147__default.useRef(null);
88054
- const mobileSubtitle = React147__default.useMemo(() => {
88904
+ const [isFilterOpen, setIsFilterOpen] = React148__default.useState(false);
88905
+ const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React148__default.useState(false);
88906
+ const filterRef = React148__default.useRef(null);
88907
+ const filterButtonRef = React148__default.useRef(null);
88908
+ const mobileFilterButtonRef = React148__default.useRef(null);
88909
+ const linesDropdownRef = React148__default.useRef(null);
88910
+ const mobileSubtitle = React148__default.useMemo(() => {
88055
88911
  if (subtitleRange.startKey === subtitleRange.endKey) {
88056
88912
  return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
88057
88913
  }
88058
88914
  return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
88059
88915
  }, [subtitleRange.endKey, subtitleRange.startKey]);
88060
- const desktopSubtitle = React147__default.useMemo(() => {
88916
+ const desktopSubtitle = React148__default.useMemo(() => {
88061
88917
  if (subtitleRange.startKey === subtitleRange.endKey) {
88062
88918
  return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
88063
88919
  }
88064
88920
  return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
88065
88921
  }, [subtitleRange.endKey, subtitleRange.startKey]);
88066
- const availableLineIds = React147__default.useMemo(
88922
+ const availableLineIds = React148__default.useMemo(
88067
88923
  () => lineOptions.map((line) => line.id),
88068
88924
  [lineOptions]
88069
88925
  );
88070
- const selectedLineIdSet = React147__default.useMemo(
88926
+ const selectedLineIdSet = React148__default.useMemo(
88071
88927
  () => new Set(selectedLineIds),
88072
88928
  [selectedLineIds]
88073
88929
  );
88074
- const isAllLinesSelected = React147__default.useMemo(() => {
88930
+ const isAllLinesSelected = React148__default.useMemo(() => {
88075
88931
  if (availableLineIds.length === 0) return true;
88076
88932
  return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
88077
88933
  }, [availableLineIds, selectedLineIdSet]);
88078
- const activeFilterCount = React147__default.useMemo(() => {
88934
+ const activeFilterCount = React148__default.useMemo(() => {
88079
88935
  let count = 0;
88080
88936
  if (trendMode !== "all") count += 1;
88081
88937
  if (selectedSupervisorId !== "all") count += 1;
88082
88938
  if (!isAllLinesSelected) count += 1;
88083
88939
  return count;
88084
88940
  }, [isAllLinesSelected, selectedSupervisorId, trendMode]);
88085
- const handleFilterToggle = React147__default.useCallback(() => {
88941
+ const handleFilterToggle = React148__default.useCallback(() => {
88086
88942
  trackCoreEvent("Operations Overview Filter Toggled", {
88087
88943
  action: !isFilterOpen ? "open" : "close"
88088
88944
  });
88089
88945
  setIsFilterOpen((previous) => !previous);
88090
88946
  }, [isFilterOpen]);
88091
- const handleTrendModeChange = React147__default.useCallback((event) => {
88947
+ const handleTrendModeChange = React148__default.useCallback((event) => {
88092
88948
  const nextMode = event.target.value;
88093
88949
  trackCoreEvent("Operations Overview Shift Filter Changed", {
88094
88950
  shift_mode: nextMode
88095
88951
  });
88096
88952
  onTrendModeChange(nextMode);
88097
88953
  }, [onTrendModeChange]);
88098
- const handleAllLinesToggle = React147__default.useCallback(() => {
88954
+ const handleAllLinesToggle = React148__default.useCallback(() => {
88099
88955
  trackCoreEvent("Operations Overview Line Filter Changed", {
88100
88956
  selected_line_ids: availableLineIds,
88101
88957
  selected_line_count: availableLineIds.length,
@@ -88103,7 +88959,7 @@ var OperationsOverviewHeader = React147__default.memo(({
88103
88959
  });
88104
88960
  onSelectedLineIdsChange(availableLineIds);
88105
88961
  }, [availableLineIds, onSelectedLineIdsChange]);
88106
- const handleSupervisorChange = React147__default.useCallback((event) => {
88962
+ const handleSupervisorChange = React148__default.useCallback((event) => {
88107
88963
  const supervisorId = event.target.value;
88108
88964
  const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
88109
88965
  trackCoreEvent("Operations Overview Supervisor Filter Changed", {
@@ -88114,7 +88970,7 @@ var OperationsOverviewHeader = React147__default.memo(({
88114
88970
  });
88115
88971
  onSelectedSupervisorIdChange(supervisorId);
88116
88972
  }, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
88117
- const handleLineToggle = React147__default.useCallback((lineId) => {
88973
+ const handleLineToggle = React148__default.useCallback((lineId) => {
88118
88974
  const current = new Set(selectedLineIds);
88119
88975
  if (current.has(lineId)) {
88120
88976
  if (current.size <= 1) return;
@@ -88130,13 +88986,13 @@ var OperationsOverviewHeader = React147__default.memo(({
88130
88986
  });
88131
88987
  onSelectedLineIdsChange(next);
88132
88988
  }, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
88133
- const handleClearAllFilters = React147__default.useCallback(() => {
88989
+ const handleClearAllFilters = React148__default.useCallback(() => {
88134
88990
  onTrendModeChange("all");
88135
88991
  onSelectedSupervisorIdChange("all");
88136
88992
  onSelectedLineIdsChange(availableLineIds);
88137
88993
  setIsFilterOpen(false);
88138
88994
  }, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
88139
- React147__default.useEffect(() => {
88995
+ React148__default.useEffect(() => {
88140
88996
  const handleClickOutside = (event) => {
88141
88997
  const target = event.target;
88142
88998
  if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
@@ -88371,12 +89227,12 @@ var OperationsOverviewHeader = React147__default.memo(({
88371
89227
  ] }) });
88372
89228
  });
88373
89229
  OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
88374
- var OverviewSummaryCards = React147__default.memo(({ store }) => {
89230
+ var OverviewSummaryCards = React148__default.memo(({ store }) => {
88375
89231
  bumpRenderCounter();
88376
89232
  const scope = useOperationsOverviewScope(store);
88377
89233
  const snapshot = useOperationsOverviewSnapshot(store);
88378
89234
  const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
88379
- const comparisonLabel = React147__default.useMemo(() => {
89235
+ const comparisonLabel = React148__default.useMemo(() => {
88380
89236
  return formatComparisonWindow({
88381
89237
  currentDayCount: scope.current_range?.day_count ?? null,
88382
89238
  previousDayCount: scope.previous_range?.day_count ?? null,
@@ -88389,27 +89245,27 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
88389
89245
  scope.previous_range?.day_count,
88390
89246
  scope.shift_mode
88391
89247
  ]);
88392
- const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React147__default.useState(false);
88393
- const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React147__default.useState(false);
88394
- const idleContributorsRef = React147__default.useRef(null);
88395
- const plantEfficiencyBadge = React147__default.useMemo(() => {
89248
+ const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React148__default.useState(false);
89249
+ const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React148__default.useState(false);
89250
+ const idleContributorsRef = React148__default.useRef(null);
89251
+ const plantEfficiencyBadge = React148__default.useMemo(() => {
88396
89252
  return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
88397
89253
  positiveIsGood: true,
88398
89254
  formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
88399
89255
  comparisonLabel
88400
89256
  });
88401
89257
  }, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
88402
- const idleBadge = React147__default.useMemo(() => {
89258
+ const idleBadge = React148__default.useMemo(() => {
88403
89259
  return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
88404
89260
  positiveIsGood: false,
88405
89261
  formatter: (value) => formatSignedIdleDuration(value),
88406
89262
  comparisonLabel
88407
89263
  });
88408
89264
  }, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
88409
- const canInspectIdleContributors = React147__default.useMemo(() => {
89265
+ const canInspectIdleContributors = React148__default.useMemo(() => {
88410
89266
  return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
88411
89267
  }, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
88412
- const idleTopContributors = React147__default.useMemo(() => {
89268
+ const idleTopContributors = React148__default.useMemo(() => {
88413
89269
  return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
88414
89270
  workspaceId: item.workspace_id || "",
88415
89271
  workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
@@ -88417,14 +89273,14 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
88417
89273
  avgIdleSeconds: toNumber4(item.avg_idle_seconds)
88418
89274
  })).slice(0, 5);
88419
89275
  }, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
88420
- const showIdleContributorLineNames = React147__default.useMemo(() => {
89276
+ const showIdleContributorLineNames = React148__default.useMemo(() => {
88421
89277
  return (scope.line_count ?? 0) > 1;
88422
89278
  }, [scope.line_count]);
88423
- const closeIdleContributors = React147__default.useCallback(() => {
89279
+ const closeIdleContributors = React148__default.useCallback(() => {
88424
89280
  setIsIdleContributorsOpen(false);
88425
89281
  setIsIdleContributorsPinned(false);
88426
89282
  }, []);
88427
- const handleIdleContributorsToggle = React147__default.useCallback(() => {
89283
+ const handleIdleContributorsToggle = React148__default.useCallback(() => {
88428
89284
  if (!canInspectIdleContributors) return;
88429
89285
  setIsIdleContributorsPinned((previous) => {
88430
89286
  const next = !previous;
@@ -88432,7 +89288,7 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
88432
89288
  return next;
88433
89289
  });
88434
89290
  }, [canInspectIdleContributors]);
88435
- const handleIdleContributorsKeyDown = React147__default.useCallback((event) => {
89291
+ const handleIdleContributorsKeyDown = React148__default.useCallback((event) => {
88436
89292
  if (!canInspectIdleContributors) return;
88437
89293
  if (event.key === "Enter" || event.key === " ") {
88438
89294
  event.preventDefault();
@@ -88444,11 +89300,11 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
88444
89300
  closeIdleContributors();
88445
89301
  }
88446
89302
  }, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
88447
- React147__default.useEffect(() => {
89303
+ React148__default.useEffect(() => {
88448
89304
  setIsIdleContributorsOpen(false);
88449
89305
  setIsIdleContributorsPinned(false);
88450
89306
  }, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
88451
- React147__default.useEffect(() => {
89307
+ React148__default.useEffect(() => {
88452
89308
  if (!isIdleContributorsOpen) return void 0;
88453
89309
  const handleClickOutside = (event) => {
88454
89310
  if (!isIdleContributorsPinned) return;
@@ -88586,7 +89442,7 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
88586
89442
  ] });
88587
89443
  });
88588
89444
  OverviewSummaryCards.displayName = "OverviewSummaryCards";
88589
- var PoorestPerformersCard = React147__default.memo(({
89445
+ var PoorestPerformersCard = React148__default.memo(({
88590
89446
  store,
88591
89447
  supervisorsByLineId,
88592
89448
  onViewAll,
@@ -88595,9 +89451,9 @@ var PoorestPerformersCard = React147__default.memo(({
88595
89451
  bumpRenderCounter();
88596
89452
  const scope = useOperationsOverviewScope(store);
88597
89453
  const snapshot = useOperationsOverviewSnapshot(store);
88598
- const [poorestLineMode, setPoorestLineMode] = React147__default.useState("output");
89454
+ const [poorestLineMode, setPoorestLineMode] = React148__default.useState("output");
88599
89455
  const availableLineModes = scope.available_line_modes;
88600
- React147__default.useEffect(() => {
89456
+ React148__default.useEffect(() => {
88601
89457
  const hasOutput = !!availableLineModes?.has_output;
88602
89458
  const hasUptime = !!availableLineModes?.has_uptime;
88603
89459
  if (hasOutput && !hasUptime && poorestLineMode !== "output") {
@@ -88606,7 +89462,7 @@ var PoorestPerformersCard = React147__default.memo(({
88606
89462
  setPoorestLineMode("uptime");
88607
89463
  }
88608
89464
  }, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
88609
- const comparisonLabel = React147__default.useMemo(() => {
89465
+ const comparisonLabel = React148__default.useMemo(() => {
88610
89466
  return formatComparisonWindow({
88611
89467
  currentDayCount: scope.current_range?.day_count ?? null,
88612
89468
  previousDayCount: scope.previous_range?.day_count ?? null,
@@ -88620,7 +89476,7 @@ var PoorestPerformersCard = React147__default.memo(({
88620
89476
  scope.shift_mode
88621
89477
  ]);
88622
89478
  const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
88623
- const mergedPoorestLines = React147__default.useMemo(() => {
89479
+ const mergedPoorestLines = React148__default.useMemo(() => {
88624
89480
  const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
88625
89481
  const lineRows = [];
88626
89482
  const areaGroups = /* @__PURE__ */ new Map();
@@ -88700,7 +89556,7 @@ var PoorestPerformersCard = React147__default.memo(({
88700
89556
  }, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
88701
89557
  const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
88702
89558
  const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
88703
- const handlePoorestLineModeChange = React147__default.useCallback((mode) => {
89559
+ const handlePoorestLineModeChange = React148__default.useCallback((mode) => {
88704
89560
  trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
88705
89561
  setPoorestLineMode(mode);
88706
89562
  }, []);
@@ -88786,14 +89642,14 @@ var PoorestPerformersCard = React147__default.memo(({
88786
89642
  ] });
88787
89643
  });
88788
89644
  PoorestPerformersCard.displayName = "PoorestPerformersCard";
88789
- var IdleBreakdownCard = React147__default.memo(({
89645
+ var IdleBreakdownCard = React148__default.memo(({
88790
89646
  store,
88791
89647
  scopedLineCount
88792
89648
  }) => {
88793
89649
  bumpRenderCounter();
88794
89650
  const idle = useOperationsOverviewIdle(store);
88795
89651
  const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
88796
- const idleBreakdown = React147__default.useMemo(() => {
89652
+ const idleBreakdown = React148__default.useMemo(() => {
88797
89653
  return idle.data.map((item) => ({
88798
89654
  name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
88799
89655
  reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
@@ -88812,7 +89668,7 @@ var IdleBreakdownCard = React147__default.memo(({
88812
89668
  }))
88813
89669
  })).filter((item) => item.value > 0);
88814
89670
  }, [idle.data]);
88815
- const showIdleModuleNotEnabledState = React147__default.useMemo(() => {
89671
+ const showIdleModuleNotEnabledState = React148__default.useMemo(() => {
88816
89672
  const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
88817
89673
  return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
88818
89674
  }, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
@@ -88833,7 +89689,7 @@ var IdleBreakdownCard = React147__default.memo(({
88833
89689
  ] });
88834
89690
  });
88835
89691
  IdleBreakdownCard.displayName = "IdleBreakdownCard";
88836
- var EfficiencyTrendCard = React147__default.memo(({
89692
+ var EfficiencyTrendCard = React148__default.memo(({
88837
89693
  store,
88838
89694
  dateRange,
88839
89695
  appTimezone,
@@ -88841,14 +89697,14 @@ var EfficiencyTrendCard = React147__default.memo(({
88841
89697
  }) => {
88842
89698
  bumpRenderCounter();
88843
89699
  const trend = useOperationsOverviewTrend(store);
88844
- const currentWeekRange = React147__default.useMemo(
89700
+ const currentWeekRange = React148__default.useMemo(
88845
89701
  () => getCurrentWeekToDateRange(appTimezone),
88846
89702
  [appTimezone]
88847
89703
  );
88848
89704
  const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
88849
89705
  const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
88850
89706
  const isHourlyTrend = trend.data.granularity === "hour";
88851
- const trendData = React147__default.useMemo(() => {
89707
+ const trendData = React148__default.useMemo(() => {
88852
89708
  if (isHourlyTrend) {
88853
89709
  return (trend.data.points || []).map((point, index) => ({
88854
89710
  name: (() => {
@@ -88920,13 +89776,13 @@ var EfficiencyTrendCard = React147__default.memo(({
88920
89776
  };
88921
89777
  });
88922
89778
  }, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
88923
- const trendTooltipLabelFormatter = React147__default.useCallback((label, payload) => {
89779
+ const trendTooltipLabelFormatter = React148__default.useCallback((label, payload) => {
88924
89780
  if (isHourlyTrend) return label;
88925
89781
  const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
88926
89782
  if (!dayOfWeek || typeof label !== "string") return label;
88927
89783
  return `${label} (${dayOfWeek})`;
88928
89784
  }, [isHourlyTrend]);
88929
- const trendXAxisTickFormatter = React147__default.useCallback((value, index) => {
89785
+ const trendXAxisTickFormatter = React148__default.useCallback((value, index) => {
88930
89786
  if (!isHourlyTrend) {
88931
89787
  return typeof value === "string" ? value : String(value ?? "");
88932
89788
  }
@@ -88953,7 +89809,7 @@ var EfficiencyTrendCard = React147__default.memo(({
88953
89809
  ] });
88954
89810
  });
88955
89811
  EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
88956
- var TopImprovementsCard = React147__default.memo(({
89812
+ var TopImprovementsCard = React148__default.memo(({
88957
89813
  store,
88958
89814
  supervisorsByLineId,
88959
89815
  onViewAll,
@@ -88962,7 +89818,7 @@ var TopImprovementsCard = React147__default.memo(({
88962
89818
  bumpRenderCounter();
88963
89819
  const improvements = useOperationsOverviewImprovements(store);
88964
89820
  const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
88965
- const displayImprovements = React147__default.useMemo(() => {
89821
+ const displayImprovements = React148__default.useMemo(() => {
88966
89822
  return improvements.data.map((item) => {
88967
89823
  const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
88968
89824
  return {
@@ -89090,33 +89946,33 @@ var useOperationsOverviewRefresh = ({
89090
89946
  isLiveScope,
89091
89947
  enabled = true
89092
89948
  }) => {
89093
- const lineIdsKey = React147__default.useMemo(() => lineIds.join(","), [lineIds]);
89094
- const scopeSignature = React147__default.useMemo(
89949
+ const lineIdsKey = React148__default.useMemo(() => lineIds.join(","), [lineIds]);
89950
+ const scopeSignature = React148__default.useMemo(
89095
89951
  () => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
89096
89952
  [companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
89097
89953
  );
89098
- const controllersRef = React147__default.useRef({});
89099
- const requestIdsRef = React147__default.useRef({
89954
+ const controllersRef = React148__default.useRef({});
89955
+ const requestIdsRef = React148__default.useRef({
89100
89956
  snapshot: 0,
89101
89957
  trend: 0,
89102
89958
  idle: 0,
89103
89959
  improvements: 0
89104
89960
  });
89105
- const intervalRef = React147__default.useRef(null);
89106
- const isPageActiveRef = React147__default.useRef(true);
89107
- const lastResumeRefreshAtRef = React147__default.useRef(0);
89108
- const abortAll = React147__default.useCallback(() => {
89961
+ const intervalRef = React148__default.useRef(null);
89962
+ const isPageActiveRef = React148__default.useRef(true);
89963
+ const lastResumeRefreshAtRef = React148__default.useRef(0);
89964
+ const abortAll = React148__default.useCallback(() => {
89109
89965
  Object.values(controllersRef.current).forEach((controller) => {
89110
89966
  controller?.abort();
89111
89967
  });
89112
89968
  controllersRef.current = {};
89113
89969
  }, []);
89114
- React147__default.useEffect(() => {
89970
+ React148__default.useEffect(() => {
89115
89971
  return () => {
89116
89972
  abortAll();
89117
89973
  };
89118
89974
  }, [abortAll]);
89119
- const getIsPageActive = React147__default.useCallback(() => {
89975
+ const getIsPageActive = React148__default.useCallback(() => {
89120
89976
  if (typeof document === "undefined") {
89121
89977
  return true;
89122
89978
  }
@@ -89124,7 +89980,7 @@ var useOperationsOverviewRefresh = ({
89124
89980
  const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
89125
89981
  return isVisible && hasFocus;
89126
89982
  }, []);
89127
- const stopPolling = React147__default.useCallback((reason) => {
89983
+ const stopPolling = React148__default.useCallback((reason) => {
89128
89984
  if (intervalRef.current === null) {
89129
89985
  return;
89130
89986
  }
@@ -89132,7 +89988,7 @@ var useOperationsOverviewRefresh = ({
89132
89988
  intervalRef.current = null;
89133
89989
  debugRefreshLog("poll stopped", { reason });
89134
89990
  }, []);
89135
- const runRefresh = React147__default.useCallback(
89991
+ const runRefresh = React148__default.useCallback(
89136
89992
  async (section, begin, onSuccess, onError, request, reason) => {
89137
89993
  if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
89138
89994
  const requestId = requestIdsRef.current[section] + 1;
@@ -89179,7 +90035,7 @@ var useOperationsOverviewRefresh = ({
89179
90035
  },
89180
90036
  [companyId, comparisonStrategy, enabled, endKey, lineIds, startKey, supabase, trendMode]
89181
90037
  );
89182
- const refreshSnapshot = React147__default.useCallback(
90038
+ const refreshSnapshot = React148__default.useCallback(
89183
90039
  async (reason) => {
89184
90040
  await runRefresh(
89185
90041
  "snapshot",
@@ -89211,7 +90067,7 @@ var useOperationsOverviewRefresh = ({
89211
90067
  },
89212
90068
  [companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
89213
90069
  );
89214
- const refreshTrend = React147__default.useCallback(
90070
+ const refreshTrend = React148__default.useCallback(
89215
90071
  async (reason) => {
89216
90072
  await runRefresh(
89217
90073
  "trend",
@@ -89240,7 +90096,7 @@ var useOperationsOverviewRefresh = ({
89240
90096
  },
89241
90097
  [companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
89242
90098
  );
89243
- const refreshIdle = React147__default.useCallback(
90099
+ const refreshIdle = React148__default.useCallback(
89244
90100
  async (reason) => {
89245
90101
  await runRefresh(
89246
90102
  "idle",
@@ -89269,7 +90125,7 @@ var useOperationsOverviewRefresh = ({
89269
90125
  },
89270
90126
  [companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
89271
90127
  );
89272
- const refreshImprovements = React147__default.useCallback(
90128
+ const refreshImprovements = React148__default.useCallback(
89273
90129
  async (reason) => {
89274
90130
  await runRefresh(
89275
90131
  "improvements",
@@ -89299,7 +90155,7 @@ var useOperationsOverviewRefresh = ({
89299
90155
  },
89300
90156
  [companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
89301
90157
  );
89302
- const refreshAll = React147__default.useCallback(
90158
+ const refreshAll = React148__default.useCallback(
89303
90159
  async (reason) => {
89304
90160
  await Promise.allSettled([
89305
90161
  refreshSnapshot(reason),
@@ -89310,7 +90166,7 @@ var useOperationsOverviewRefresh = ({
89310
90166
  },
89311
90167
  [refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
89312
90168
  );
89313
- const startPolling = React147__default.useCallback((reason) => {
90169
+ const startPolling = React148__default.useCallback((reason) => {
89314
90170
  if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
89315
90171
  return;
89316
90172
  }
@@ -89331,7 +90187,7 @@ var useOperationsOverviewRefresh = ({
89331
90187
  }, LIVE_REFRESH_INTERVAL_MS);
89332
90188
  debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
89333
90189
  }, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
89334
- const refreshFromResume = React147__default.useCallback((reason) => {
90190
+ const refreshFromResume = React148__default.useCallback((reason) => {
89335
90191
  const now4 = Date.now();
89336
90192
  if (now4 - lastResumeRefreshAtRef.current < 1e3) {
89337
90193
  debugRefreshLog("resume refresh suppressed", { reason });
@@ -89346,7 +90202,7 @@ var useOperationsOverviewRefresh = ({
89346
90202
  }
89347
90203
  });
89348
90204
  }, [refreshAll, startPolling, stopPolling]);
89349
- React147__default.useEffect(() => {
90205
+ React148__default.useEffect(() => {
89350
90206
  if (!enabled) {
89351
90207
  stopPolling("disabled");
89352
90208
  abortAll();
@@ -89361,7 +90217,7 @@ var useOperationsOverviewRefresh = ({
89361
90217
  }
89362
90218
  void refreshAll("scope_change");
89363
90219
  }, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
89364
- React147__default.useEffect(() => {
90220
+ React148__default.useEffect(() => {
89365
90221
  if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
89366
90222
  isPageActiveRef.current = false;
89367
90223
  stopPolling("live_scope_disabled");
@@ -89574,55 +90430,55 @@ var PlantHeadView = () => {
89574
90430
  const { accessibleLineIds } = useUserLineAccess();
89575
90431
  const mobileMenuContext = useMobileMenu();
89576
90432
  useHideMobileHeader(!!mobileMenuContext);
89577
- const storeRef = React147__default.useRef(createOperationsOverviewStore());
90433
+ const storeRef = React148__default.useRef(createOperationsOverviewStore());
89578
90434
  const store = storeRef.current;
89579
- const fallbackOperationalDate = React147__default.useMemo(
90435
+ const fallbackOperationalDate = React148__default.useMemo(
89580
90436
  () => getOperationalDate(appTimezone),
89581
90437
  [appTimezone]
89582
90438
  );
89583
- const [dateRange, setDateRange] = React147__default.useState(() => ({
90439
+ const [dateRange, setDateRange] = React148__default.useState(() => ({
89584
90440
  startKey: fallbackOperationalDate,
89585
90441
  endKey: fallbackOperationalDate
89586
90442
  }));
89587
- const [usesThisWeekComparison, setUsesThisWeekComparison] = React147__default.useState(false);
89588
- const [trendMode, setTrendMode] = React147__default.useState("all");
89589
- const [selectedSupervisorId, setSelectedSupervisorId] = React147__default.useState("all");
89590
- const [selectedLineIds, setSelectedLineIds] = React147__default.useState([]);
89591
- const [isInitialScopeReady, setIsInitialScopeReady] = React147__default.useState(false);
89592
- const [shiftResolutionTick, setShiftResolutionTick] = React147__default.useState(0);
89593
- const hasAutoInitializedScopeRef = React147__default.useRef(false);
89594
- const hasUserAdjustedScopeRef = React147__default.useRef(false);
89595
- React147__default.useEffect(() => {
90443
+ const [usesThisWeekComparison, setUsesThisWeekComparison] = React148__default.useState(false);
90444
+ const [trendMode, setTrendMode] = React148__default.useState("all");
90445
+ const [selectedSupervisorId, setSelectedSupervisorId] = React148__default.useState("all");
90446
+ const [selectedLineIds, setSelectedLineIds] = React148__default.useState([]);
90447
+ const [isInitialScopeReady, setIsInitialScopeReady] = React148__default.useState(false);
90448
+ const [shiftResolutionTick, setShiftResolutionTick] = React148__default.useState(0);
90449
+ const hasAutoInitializedScopeRef = React148__default.useRef(false);
90450
+ const hasUserAdjustedScopeRef = React148__default.useRef(false);
90451
+ React148__default.useEffect(() => {
89596
90452
  trackCorePageView("Operations Overview", {
89597
90453
  dashboard_surface: "operations_overview"
89598
90454
  });
89599
90455
  }, []);
89600
- const currentWeekRange = React147__default.useMemo(
90456
+ const currentWeekRange = React148__default.useMemo(
89601
90457
  () => getCurrentWeekToDateRange(appTimezone),
89602
90458
  [appTimezone]
89603
90459
  );
89604
- const currentWeekDisplayRange = React147__default.useMemo(
90460
+ const currentWeekDisplayRange = React148__default.useMemo(
89605
90461
  () => getCurrentWeekFullRange(appTimezone),
89606
90462
  [appTimezone]
89607
90463
  );
89608
90464
  const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
89609
- const headerDateRange = React147__default.useMemo(() => {
90465
+ const headerDateRange = React148__default.useMemo(() => {
89610
90466
  if (usesThisWeekComparison && isCurrentWeekToDateRange) {
89611
90467
  return currentWeekDisplayRange;
89612
90468
  }
89613
90469
  return dateRange;
89614
90470
  }, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
89615
- const normalizedLineIds = React147__default.useMemo(
90471
+ const normalizedLineIds = React148__default.useMemo(
89616
90472
  () => Array.from(new Set(
89617
90473
  (accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
89618
90474
  )).sort(),
89619
90475
  [accessibleLineIds, factoryViewId]
89620
90476
  );
89621
- const lineIdsKey = React147__default.useMemo(
90477
+ const lineIdsKey = React148__default.useMemo(
89622
90478
  () => normalizedLineIds.join(","),
89623
90479
  [normalizedLineIds]
89624
90480
  );
89625
- const lineOptions = React147__default.useMemo(
90481
+ const lineOptions = React148__default.useMemo(
89626
90482
  () => normalizedLineIds.map((lineId) => ({
89627
90483
  id: lineId,
89628
90484
  name: getLineDisplayName(entityConfig, lineId)
@@ -89634,7 +90490,7 @@ var PlantHeadView = () => {
89634
90490
  companyId: entityConfig.companyId,
89635
90491
  useBackend: true
89636
90492
  });
89637
- const supervisorOptions = React147__default.useMemo(
90493
+ const supervisorOptions = React148__default.useMemo(
89638
90494
  () => {
89639
90495
  const optionsById = /* @__PURE__ */ new Map();
89640
90496
  normalizedLineIds.forEach((lineId) => {
@@ -89660,7 +90516,7 @@ var PlantHeadView = () => {
89660
90516
  },
89661
90517
  [normalizedLineIds, supervisorsByLineId]
89662
90518
  );
89663
- React147__default.useEffect(() => {
90519
+ React148__default.useEffect(() => {
89664
90520
  if (selectedSupervisorId === "all") {
89665
90521
  setSelectedLineIds((previous) => {
89666
90522
  if (normalizedLineIds.length === 0) {
@@ -89686,7 +90542,7 @@ var PlantHeadView = () => {
89686
90542
  const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
89687
90543
  setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
89688
90544
  }, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
89689
- const scopedLineIds = React147__default.useMemo(
90545
+ const scopedLineIds = React148__default.useMemo(
89690
90546
  () => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
89691
90547
  [normalizedLineIds, selectedLineIds]
89692
90548
  );
@@ -89694,7 +90550,7 @@ var PlantHeadView = () => {
89694
90550
  shiftConfigMap,
89695
90551
  isLoading: isShiftConfigLoading
89696
90552
  } = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
89697
- const shiftFilterOptions = React147__default.useMemo(() => {
90553
+ const shiftFilterOptions = React148__default.useMemo(() => {
89698
90554
  const optionsById = /* @__PURE__ */ new Map();
89699
90555
  scopedLineIds.forEach((lineId) => {
89700
90556
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
@@ -89733,7 +90589,7 @@ var PlantHeadView = () => {
89733
90589
  ...dynamicOptions
89734
90590
  ];
89735
90591
  }, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
89736
- React147__default.useEffect(() => {
90592
+ React148__default.useEffect(() => {
89737
90593
  if (scopedLineIds.length === 0 || isShiftConfigLoading) {
89738
90594
  return;
89739
90595
  }
@@ -89744,11 +90600,11 @@ var PlantHeadView = () => {
89744
90600
  clearInterval(intervalId);
89745
90601
  };
89746
90602
  }, [isShiftConfigLoading, scopedLineIds.length]);
89747
- const shiftResolutionNow = React147__default.useMemo(
90603
+ const shiftResolutionNow = React148__default.useMemo(
89748
90604
  () => /* @__PURE__ */ new Date(),
89749
90605
  [shiftResolutionTick]
89750
90606
  );
89751
- const earliestDayShiftStartTime = React147__default.useMemo(() => {
90607
+ const earliestDayShiftStartTime = React148__default.useMemo(() => {
89752
90608
  const candidateStarts = [];
89753
90609
  scopedLineIds.forEach((lineId) => {
89754
90610
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
@@ -89784,11 +90640,11 @@ var PlantHeadView = () => {
89784
90640
  const minutes = earliestMinutes % 60;
89785
90641
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
89786
90642
  }, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
89787
- const resolvedOperationalToday = React147__default.useMemo(
90643
+ const resolvedOperationalToday = React148__default.useMemo(
89788
90644
  () => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
89789
90645
  [appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
89790
90646
  );
89791
- const activeLineShiftStates = React147__default.useMemo(() => {
90647
+ const activeLineShiftStates = React148__default.useMemo(() => {
89792
90648
  return scopedLineIds.flatMap((lineId) => {
89793
90649
  const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
89794
90650
  const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
@@ -89818,7 +90674,7 @@ var PlantHeadView = () => {
89818
90674
  });
89819
90675
  }, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
89820
90676
  const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
89821
- const hourlyWindowStartTime = React147__default.useMemo(() => {
90677
+ const hourlyWindowStartTime = React148__default.useMemo(() => {
89822
90678
  if (scopedLineIds.length === 0) {
89823
90679
  return null;
89824
90680
  }
@@ -89875,12 +90731,12 @@ var PlantHeadView = () => {
89875
90731
  const minutes = earliestMinutes % 60;
89876
90732
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
89877
90733
  }, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
89878
- const isShiftScopeResolved = React147__default.useMemo(
90734
+ const isShiftScopeResolved = React148__default.useMemo(
89879
90735
  () => !isShiftConfigLoading,
89880
90736
  [isShiftConfigLoading]
89881
90737
  );
89882
- const initializedTimezoneRef = React147__default.useRef(appTimezone);
89883
- React147__default.useEffect(() => {
90738
+ const initializedTimezoneRef = React148__default.useRef(appTimezone);
90739
+ React148__default.useEffect(() => {
89884
90740
  if (initializedTimezoneRef.current === appTimezone) return;
89885
90741
  hasAutoInitializedScopeRef.current = false;
89886
90742
  hasUserAdjustedScopeRef.current = false;
@@ -89893,7 +90749,7 @@ var PlantHeadView = () => {
89893
90749
  setIsInitialScopeReady(false);
89894
90750
  initializedTimezoneRef.current = appTimezone;
89895
90751
  }, [appTimezone, fallbackOperationalDate]);
89896
- React147__default.useEffect(() => {
90752
+ React148__default.useEffect(() => {
89897
90753
  if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
89898
90754
  return;
89899
90755
  }
@@ -89918,7 +90774,7 @@ var PlantHeadView = () => {
89918
90774
  hasAutoInitializedScopeRef.current = true;
89919
90775
  setIsInitialScopeReady(true);
89920
90776
  }, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
89921
- const handleDateRangeChange = React147__default.useCallback((range, meta) => {
90777
+ const handleDateRangeChange = React148__default.useCallback((range, meta) => {
89922
90778
  hasUserAdjustedScopeRef.current = true;
89923
90779
  setIsInitialScopeReady(true);
89924
90780
  trackCoreEvent("Operations Overview Date Range Changed", {
@@ -89936,12 +90792,12 @@ var PlantHeadView = () => {
89936
90792
  return previous;
89937
90793
  });
89938
90794
  }, []);
89939
- const handleTrendModeChange = React147__default.useCallback((mode) => {
90795
+ const handleTrendModeChange = React148__default.useCallback((mode) => {
89940
90796
  hasUserAdjustedScopeRef.current = true;
89941
90797
  setIsInitialScopeReady(true);
89942
90798
  setTrendMode(mode);
89943
90799
  }, []);
89944
- const handleSelectedLineIdsChange = React147__default.useCallback((lineIds) => {
90800
+ const handleSelectedLineIdsChange = React148__default.useCallback((lineIds) => {
89945
90801
  setSelectedSupervisorId("all");
89946
90802
  if (normalizedLineIds.length === 0) {
89947
90803
  setSelectedLineIds([]);
@@ -89952,10 +90808,10 @@ var PlantHeadView = () => {
89952
90808
  const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
89953
90809
  setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
89954
90810
  }, [normalizedLineIds]);
89955
- const handleSelectedSupervisorIdChange = React147__default.useCallback((supervisorId) => {
90811
+ const handleSelectedSupervisorIdChange = React148__default.useCallback((supervisorId) => {
89956
90812
  setSelectedSupervisorId(supervisorId);
89957
90813
  }, []);
89958
- const buildLineMonthlyHistoryUrl = React147__default.useCallback((lineId) => {
90814
+ const buildLineMonthlyHistoryUrl = React148__default.useCallback((lineId) => {
89959
90815
  const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
89960
90816
  const params = new URLSearchParams();
89961
90817
  params.set("tab", "monthly_history");
@@ -89965,15 +90821,15 @@ var PlantHeadView = () => {
89965
90821
  params.set("rangeEnd", dateRange.endKey);
89966
90822
  return `/kpis/${lineId}?${params.toString()}`;
89967
90823
  }, [dateRange.endKey, dateRange.startKey]);
89968
- const handleViewAllPoorestPerformers = React147__default.useCallback(() => {
90824
+ const handleViewAllPoorestPerformers = React148__default.useCallback(() => {
89969
90825
  trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
89970
90826
  navigate("/kpis?tab=leaderboard");
89971
90827
  }, [navigate]);
89972
- const handleViewAllImprovements = React147__default.useCallback(() => {
90828
+ const handleViewAllImprovements = React148__default.useCallback(() => {
89973
90829
  trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
89974
90830
  navigate("/improvement-center");
89975
90831
  }, [navigate]);
89976
- const handleOpenImprovement = React147__default.useCallback((item) => {
90832
+ const handleOpenImprovement = React148__default.useCallback((item) => {
89977
90833
  trackCoreEvent("Operations Overview Improvement Clicked", {
89978
90834
  issue_id: item.issueId,
89979
90835
  issue_number: item.issueNumber,
@@ -89984,13 +90840,13 @@ var PlantHeadView = () => {
89984
90840
  });
89985
90841
  navigate(`/improvement-center?${params.toString()}`);
89986
90842
  }, [navigate]);
89987
- const comparisonStrategy = React147__default.useMemo(() => {
90843
+ const comparisonStrategy = React148__default.useMemo(() => {
89988
90844
  if (usesThisWeekComparison && isCurrentWeekToDateRange) {
89989
90845
  return "previous_full_week";
89990
90846
  }
89991
90847
  return void 0;
89992
90848
  }, [isCurrentWeekToDateRange, usesThisWeekComparison]);
89993
- const effectiveDateRange = React147__default.useMemo(() => {
90849
+ const effectiveDateRange = React148__default.useMemo(() => {
89994
90850
  if (isInitialScopeReady) {
89995
90851
  return dateRange;
89996
90852
  }
@@ -90000,11 +90856,11 @@ var PlantHeadView = () => {
90000
90856
  endKey: nextStartKey
90001
90857
  };
90002
90858
  }, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
90003
- const effectiveTrendMode = React147__default.useMemo(
90859
+ const effectiveTrendMode = React148__default.useMemo(
90004
90860
  () => resolvedTrendMode,
90005
90861
  [resolvedTrendMode]
90006
90862
  );
90007
- const hasActiveSelectedShiftLine = React147__default.useMemo(
90863
+ const hasActiveSelectedShiftLine = React148__default.useMemo(
90008
90864
  () => activeLineShiftStates.some((shift) => {
90009
90865
  if (shift.date !== resolvedOperationalToday) return false;
90010
90866
  if (effectiveTrendMode === "all") return true;
@@ -90016,7 +90872,7 @@ var PlantHeadView = () => {
90016
90872
  }),
90017
90873
  [activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
90018
90874
  );
90019
- const activeLiveShiftName = React147__default.useMemo(
90875
+ const activeLiveShiftName = React148__default.useMemo(
90020
90876
  () => {
90021
90877
  if (effectiveTrendMode === "all") return null;
90022
90878
  const matchingShift = activeLineShiftStates.find((shift) => {
@@ -90031,17 +90887,17 @@ var PlantHeadView = () => {
90031
90887
  },
90032
90888
  [activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
90033
90889
  );
90034
- const hourlyLabelStartTime = React147__default.useMemo(() => {
90890
+ const hourlyLabelStartTime = React148__default.useMemo(() => {
90035
90891
  if (scopedLineIds.length === 0) {
90036
90892
  return null;
90037
90893
  }
90038
90894
  return hourlyWindowStartTime;
90039
90895
  }, [hourlyWindowStartTime, scopedLineIds.length]);
90040
- const isSingleDayScope = React147__default.useMemo(
90896
+ const isSingleDayScope = React148__default.useMemo(
90041
90897
  () => effectiveDateRange.startKey === effectiveDateRange.endKey,
90042
90898
  [effectiveDateRange.endKey, effectiveDateRange.startKey]
90043
90899
  );
90044
- const isLiveScope = React147__default.useMemo(
90900
+ const isLiveScope = React148__default.useMemo(
90045
90901
  () => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && hasActiveSelectedShiftLine,
90046
90902
  [
90047
90903
  effectiveDateRange.startKey,
@@ -90051,7 +90907,7 @@ var PlantHeadView = () => {
90051
90907
  resolvedOperationalToday
90052
90908
  ]
90053
90909
  );
90054
- const handleOpenLineDetails = React147__default.useCallback((line) => {
90910
+ const handleOpenLineDetails = React148__default.useCallback((line) => {
90055
90911
  trackCoreEvent("Operations Overview Line Clicked", {
90056
90912
  line_id: line.rowType === "line" ? line.id : null,
90057
90913
  line_name: line.name,