@optifye/dashboard-core 6.11.5 → 6.11.6

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
@@ -3,14 +3,14 @@ import React141__default, { createContext, useRef, useCallback, useState, useMem
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { useRouter } from 'next/router';
5
5
  import { fromZonedTime, formatInTimeZone, toZonedTime } from 'date-fns-tz';
6
- import { endOfDay, startOfDay, startOfMonth, isSameDay, endOfMonth, eachDayOfInterval, getDay, isWithinInterval, format, addDays, differenceInMinutes, addMinutes, subDays, subMonths, addMonths, parseISO, isValid, formatDistanceToNow, isToday, isFuture, isBefore } from 'date-fns';
6
+ import { format, subMonths, endOfMonth, startOfMonth, endOfDay, eachDayOfInterval, getDay, isSameDay, isWithinInterval, startOfDay, addDays, differenceInMinutes, addMinutes, parseISO, subDays, addMonths, isValid, formatDistanceToNow, isToday, isFuture, isBefore } from 'date-fns';
7
7
  import mixpanel from 'mixpanel-browser';
8
8
  import { EventEmitter } from 'events';
9
9
  import { createClient, REALTIME_SUBSCRIBE_STATES } from '@supabase/supabase-js';
10
10
  import Hls, { Events, ErrorTypes } from 'hls.js';
11
11
  import useSWR from 'swr';
12
12
  import { memo, noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds } from 'motion-utils';
13
- import { Camera, AlertTriangle, ChevronDown, ChevronUp, Check, Map as Map$1, Video, ShieldCheck, Star, Award, Filter, X, Coffee, Plus, ArrowLeft, Clock, Calendar, Save, AlertCircle, Loader2, Minus, ArrowDown, ArrowUp, ChevronLeft, ChevronRight, TrendingUp, Sparkles, Pause, Play, Wrench, XCircle, Package, UserX, Zap, HelpCircle, Tag, Palette, CheckCircle2, RefreshCw, TrendingDown, FolderOpen, Folder, Sliders, Activity, Layers, Search, Edit2, ArrowRight, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Copy, ArrowUpRight, Settings, LifeBuoy, EyeOff, Flame, Crown, Medal } from 'lucide-react';
13
+ import { Camera, AlertTriangle, ChevronDown, ChevronUp, Check, Map as Map$1, Video, ShieldCheck, Star, Award, Filter, X, Coffee, Plus, ArrowLeft, Clock, Calendar, Save, AlertCircle, Loader2, Minus, ArrowDown, ArrowUp, ChevronLeft, ChevronRight, TrendingUp, Sparkles, Pause, Play, Wrench, XCircle, Package, UserX, Zap, HelpCircle, Tag, Palette, CheckCircle2, RefreshCw, TrendingDown, FolderOpen, Folder, Sliders, Activity, Layers, Search, Edit2, ArrowRight, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Copy, Settings, LifeBuoy, EyeOff, Flame, Crown, Medal } from 'lucide-react';
14
14
  import { toast } from 'sonner';
15
15
  import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, ReferenceLine, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, PieChart, Pie, Cell, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
16
16
  import { Slot } from '@radix-ui/react-slot';
@@ -623,6 +623,17 @@ var getMonthKeyBounds = (year, monthIndex) => {
623
623
  const endKey = buildDateKey(year, monthIndex, lastDay);
624
624
  return { startKey, endKey };
625
625
  };
626
+ var getCurrentWeekToDateRange = (timezone, now4 = /* @__PURE__ */ new Date()) => {
627
+ const todayKey = formatInTimeZone(now4, timezone || "UTC", "yyyy-MM-dd");
628
+ const todayDate = parseISO(`${todayKey}T00:00:00`);
629
+ const dayOfWeek = getDay(todayDate);
630
+ const daysSinceMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
631
+ const weekStart = subDays(todayDate, daysSinceMonday);
632
+ return {
633
+ startKey: format(weekStart, "yyyy-MM-dd"),
634
+ endKey: format(todayDate, "yyyy-MM-dd")
635
+ };
636
+ };
626
637
  var normalizeDateKeyRange = (startKey, endKey, minKey, maxKey) => {
627
638
  const clampedStart = startKey < minKey ? minKey : startKey > maxKey ? maxKey : startKey;
628
639
  const clampedEnd = endKey < minKey ? minKey : endKey > maxKey ? maxKey : endKey;
@@ -2681,6 +2692,45 @@ var workspaceService = {
2681
2692
  }
2682
2693
  }
2683
2694
  };
2695
+
2696
+ // src/lib/utils/workspaceHealthSummary.ts
2697
+ var computeWorkspaceHealthSummary = (data, lastUpdated = (/* @__PURE__ */ new Date()).toISOString()) => {
2698
+ const totalWorkspaces = data.length;
2699
+ const healthyWorkspaces = data.filter((workspace) => workspace.status === "healthy").length;
2700
+ const unhealthyWorkspaces = data.filter((workspace) => workspace.status === "unhealthy").length;
2701
+ const warningWorkspaces = data.filter((workspace) => workspace.status === "warning").length;
2702
+ const workspacesWithUptime = data.filter(
2703
+ (workspace) => workspace.hasUptimeData && workspace.uptimePercentage !== void 0 && workspace.uptimeDetails !== void 0
2704
+ );
2705
+ const workspacesWithoutUptimeData = totalWorkspaces - workspacesWithUptime.length;
2706
+ let uptimePercentage = null;
2707
+ let totalDowntimeMinutes;
2708
+ if (workspacesWithUptime.length > 0) {
2709
+ const totalUptime = workspacesWithUptime.reduce(
2710
+ (sum, workspace) => sum + (workspace.uptimePercentage || 0),
2711
+ 0
2712
+ );
2713
+ uptimePercentage = totalUptime / workspacesWithUptime.length;
2714
+ totalDowntimeMinutes = workspacesWithUptime.reduce((sum, workspace) => {
2715
+ if (!workspace.uptimeDetails) {
2716
+ return sum;
2717
+ }
2718
+ return sum + Math.max(0, workspace.uptimeDetails.expectedMinutes - workspace.uptimeDetails.actualMinutes);
2719
+ }, 0);
2720
+ }
2721
+ return {
2722
+ totalWorkspaces,
2723
+ healthyWorkspaces,
2724
+ unhealthyWorkspaces,
2725
+ warningWorkspaces,
2726
+ uptimePercentage,
2727
+ workspacesWithoutUptimeData,
2728
+ totalDowntimeMinutes,
2729
+ lastUpdated
2730
+ };
2731
+ };
2732
+
2733
+ // src/lib/services/workspaceHealthService.ts
2684
2734
  var DATA_PROCESSING_DELAY_MINUTES = 5;
2685
2735
  var WorkspaceHealthService = class _WorkspaceHealthService {
2686
2736
  constructor() {
@@ -2820,6 +2870,24 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
2820
2870
  }
2821
2871
  return "down";
2822
2872
  }
2873
+ hasCompletedTimelineData(completedMinutes, shiftStartDate, outputHourly, outputArray, timezone) {
2874
+ if (completedMinutes <= 0) {
2875
+ return false;
2876
+ }
2877
+ for (let minuteIndex = 0; minuteIndex < completedMinutes; minuteIndex++) {
2878
+ const minuteDate = addMinutes(shiftStartDate, minuteIndex);
2879
+ const hourKey = formatInTimeZone(minuteDate, timezone, "H");
2880
+ const minuteKey = Number.parseInt(formatInTimeZone(minuteDate, timezone, "m"), 10);
2881
+ const hourBucket = outputHourly[hourKey];
2882
+ if (Array.isArray(hourBucket) && hourBucket[minuteKey] !== void 0) {
2883
+ return true;
2884
+ }
2885
+ if (minuteIndex < outputArray.length) {
2886
+ return true;
2887
+ }
2888
+ }
2889
+ return false;
2890
+ }
2823
2891
  async getWorkspaceHealthStatus(options = {}) {
2824
2892
  const supabase = _getSupabaseInstance();
2825
2893
  if (!supabase) throw new Error("Supabase client not initialized");
@@ -2874,11 +2942,15 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
2874
2942
  if (uptimeDetails) {
2875
2943
  return {
2876
2944
  ...workspace,
2945
+ hasUptimeData: true,
2877
2946
  uptimePercentage: uptimeDetails.percentage,
2878
2947
  uptimeDetails
2879
2948
  };
2880
2949
  }
2881
- return workspace;
2950
+ return {
2951
+ ...workspace,
2952
+ hasUptimeData: false
2953
+ };
2882
2954
  });
2883
2955
  let filteredData = dataWithUptime;
2884
2956
  try {
@@ -3010,6 +3082,33 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
3010
3082
  const record = Array.isArray(data) && data.length > 0 ? data[0] : null;
3011
3083
  const outputHourly = this.normalizeOutputHourly(record?.output_hourly || {});
3012
3084
  const outputArray = Array.isArray(record?.output_array) ? record.output_array : [];
3085
+ const hasData = Boolean(
3086
+ record && this.hasCompletedTimelineData(
3087
+ completedMinutes,
3088
+ shiftStartDate,
3089
+ outputHourly,
3090
+ outputArray,
3091
+ timezone
3092
+ )
3093
+ );
3094
+ if (!hasData) {
3095
+ return {
3096
+ shiftId: queryShiftId,
3097
+ shiftLabel,
3098
+ shiftStart: formatInTimeZone(shiftStartDate, timezone, "yyyy-MM-dd'T'HH:mm:ssXXX"),
3099
+ shiftEnd: formatInTimeZone(shiftEndDate, timezone, "yyyy-MM-dd'T'HH:mm:ssXXX"),
3100
+ totalMinutes,
3101
+ completedMinutes,
3102
+ uptimeMinutes: 0,
3103
+ downtimeMinutes: 0,
3104
+ pendingMinutes,
3105
+ uptimePercentage: 0,
3106
+ hasData: false,
3107
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
3108
+ points: [],
3109
+ downtimeSegments: []
3110
+ };
3111
+ }
3013
3112
  const points = [];
3014
3113
  let uptimeMinutes = 0;
3015
3114
  let downtimeMinutes = 0;
@@ -3095,6 +3194,7 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
3095
3194
  downtimeMinutes,
3096
3195
  pendingMinutes,
3097
3196
  uptimePercentage,
3197
+ hasData: true,
3098
3198
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
3099
3199
  points,
3100
3200
  downtimeSegments: filteredSegments
@@ -3123,37 +3223,7 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
3123
3223
  async getHealthSummary(lineId, companyId) {
3124
3224
  this.clearCache();
3125
3225
  const workspaces = await this.getWorkspaceHealthStatus({ lineId, companyId });
3126
- const totalWorkspaces = workspaces.length;
3127
- const healthyWorkspaces = workspaces.filter((w) => w.status === "healthy").length;
3128
- const unhealthyWorkspaces = workspaces.filter((w) => w.status === "unhealthy").length;
3129
- const warningWorkspaces = workspaces.filter((w) => w.status === "warning").length;
3130
- let uptimePercentage = 0;
3131
- let totalDowntimeMinutes = 0;
3132
- if (totalWorkspaces > 0) {
3133
- const workspacesWithUptime = workspaces.filter((w) => w.uptimePercentage !== void 0 && w.uptimeDetails !== void 0);
3134
- if (workspacesWithUptime.length > 0) {
3135
- const totalUptime = workspacesWithUptime.reduce((sum, w) => sum + (w.uptimePercentage || 0), 0);
3136
- uptimePercentage = totalUptime / workspacesWithUptime.length;
3137
- totalDowntimeMinutes = workspacesWithUptime.reduce((sum, w) => {
3138
- if (w.uptimeDetails) {
3139
- const downtime = Math.max(0, w.uptimeDetails.expectedMinutes - w.uptimeDetails.actualMinutes);
3140
- return sum + downtime;
3141
- }
3142
- return sum;
3143
- }, 0);
3144
- } else {
3145
- uptimePercentage = healthyWorkspaces / totalWorkspaces * 100;
3146
- }
3147
- }
3148
- return {
3149
- totalWorkspaces,
3150
- healthyWorkspaces,
3151
- unhealthyWorkspaces,
3152
- warningWorkspaces,
3153
- uptimePercentage,
3154
- totalDowntimeMinutes,
3155
- lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
3156
- };
3226
+ return computeWorkspaceHealthSummary(workspaces);
3157
3227
  }
3158
3228
  async getHealthMetrics(workspaceId, startDate, endDate) {
3159
3229
  const supabase = _getSupabaseInstance();
@@ -3192,7 +3262,8 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
3192
3262
  ...data,
3193
3263
  status,
3194
3264
  timeSinceLastUpdate,
3195
- isStale
3265
+ isStale,
3266
+ hasUptimeData: false
3196
3267
  };
3197
3268
  }
3198
3269
  getStatusPriority(status) {
@@ -15936,7 +16007,8 @@ var useWorkspaceHealthById = (workspaceId, options) => {
15936
16007
  ...healthData,
15937
16008
  status,
15938
16009
  timeSinceLastUpdate,
15939
- isStale: !lastUpdate || now4.getTime() - lastUpdate.getTime() > 15 * 6e4
16010
+ isStale: !lastUpdate || now4.getTime() - lastUpdate.getTime() > 15 * 6e4,
16011
+ hasUptimeData: false
15940
16012
  };
15941
16013
  setWorkspace(workspaceWithStatus);
15942
16014
  } else {
@@ -47988,14 +48060,11 @@ var WorkspaceHealthCard = ({
47988
48060
  };
47989
48061
  const getDowntimeConfig = (uptimeDetails) => {
47990
48062
  if (!uptimeDetails) {
47991
- if (workspace.status === "healthy") {
47992
- return {
47993
- text: "0m",
47994
- className: "text-emerald-600 dark:text-emerald-400",
47995
- label: "Total Downtime"
47996
- };
47997
- }
47998
- return { text: "--", className: "text-slate-400", label: "Total Downtime" };
48063
+ return {
48064
+ text: "--",
48065
+ className: "text-slate-400",
48066
+ label: "Uptime Data"
48067
+ };
47999
48068
  }
48000
48069
  const downtimeMinutes = Math.max(0, uptimeDetails.expectedMinutes - uptimeDetails.actualMinutes);
48001
48070
  if (downtimeMinutes === 0) {
@@ -48054,7 +48123,7 @@ var WorkspaceHealthCard = ({
48054
48123
  ] })
48055
48124
  ] }),
48056
48125
  /* @__PURE__ */ jsx("div", { className: "mt-3 pt-3 border-t border-slate-100 dark:border-slate-800", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
48057
- /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-slate-500 uppercase tracking-wide", children: "Total Downtime" }),
48126
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-slate-500 uppercase tracking-wide", children: downtimeConfig.label }),
48058
48127
  /* @__PURE__ */ jsx("span", { className: clsx("text-sm font-semibold", downtimeConfig.className), children: downtimeConfig.text })
48059
48128
  ] }) })
48060
48129
  ] }),
@@ -48077,8 +48146,8 @@ var CompactWorkspaceHealthCard = ({
48077
48146
  className = "",
48078
48147
  onViewDetails
48079
48148
  }) => {
48080
- const downtimeMinutes = workspace.uptimeDetails ? Math.max(0, workspace.uptimeDetails.expectedMinutes - workspace.uptimeDetails.actualMinutes) : null;
48081
- const downtimeLabel = downtimeMinutes === null ? "No downtime data" : downtimeMinutes === 0 ? "No downtime" : `${downtimeMinutes} min down`;
48149
+ const downtimeMinutes = workspace.hasUptimeData && workspace.uptimeDetails ? Math.max(0, workspace.uptimeDetails.expectedMinutes - workspace.uptimeDetails.actualMinutes) : null;
48150
+ const downtimeLabel = !workspace.hasUptimeData ? "Uptime data unavailable" : downtimeMinutes === null ? "No downtime data" : downtimeMinutes === 0 ? "No downtime" : `${downtimeMinutes} min down`;
48082
48151
  const getStatusConfig = () => {
48083
48152
  switch (workspace.status) {
48084
48153
  case "healthy":
@@ -48147,7 +48216,7 @@ var CompactWorkspaceHealthCard = ({
48147
48216
  ] })
48148
48217
  ] }),
48149
48218
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
48150
- workspace.uptimePercentage !== void 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
48219
+ workspace.hasUptimeData && workspace.uptimePercentage !== void 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
48151
48220
  /* @__PURE__ */ jsxs("p", { className: "text-xs font-medium text-gray-600 dark:text-gray-400", children: [
48152
48221
  workspace.uptimePercentage.toFixed(1),
48153
48222
  "%"
@@ -48155,6 +48224,7 @@ var CompactWorkspaceHealthCard = ({
48155
48224
  downtimeMinutes !== null && downtimeMinutes > 0 && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 dark:text-gray-400", children: "\u2022" }),
48156
48225
  downtimeLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: downtimeLabel })
48157
48226
  ] }),
48227
+ !workspace.hasUptimeData && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Uptime data unavailable" }),
48158
48228
  /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: workspace.timeSinceLastUpdate }),
48159
48229
  /* @__PURE__ */ jsx("div", { className: clsx("h-2 w-2 rounded-full", config.dot) }),
48160
48230
  onViewDetails && /* @__PURE__ */ jsx(
@@ -49727,7 +49797,28 @@ var SideNavBar = memo$1(({
49727
49797
  const [isSettingsOpen, setIsSettingsOpen] = useState(false);
49728
49798
  const settingsTriggerRef = useRef(null);
49729
49799
  const [isAlertsOpen, setIsAlertsOpen] = useState(false);
49730
- const [alertsCount, setAlertsCount] = useState(0);
49800
+ const [alertsCount, setAlertsCount] = useState(null);
49801
+ const [lastViewedCount, setLastViewedCount] = useState(() => {
49802
+ if (typeof window !== "undefined") {
49803
+ return parseInt(localStorage.getItem("lastViewedAlertsCount") || "0", 10);
49804
+ }
49805
+ return 0;
49806
+ });
49807
+ useEffect(() => {
49808
+ if (alertsCount === null) return;
49809
+ setLastViewedCount((prev) => {
49810
+ if (isAlertsOpen) {
49811
+ localStorage.setItem("lastViewedAlertsCount", alertsCount.toString());
49812
+ return alertsCount;
49813
+ }
49814
+ if (alertsCount < prev) {
49815
+ localStorage.setItem("lastViewedAlertsCount", alertsCount.toString());
49816
+ return alertsCount;
49817
+ }
49818
+ return prev;
49819
+ });
49820
+ }, [alertsCount, isAlertsOpen]);
49821
+ const unreadCount = alertsCount !== null ? Math.max(0, alertsCount - lastViewedCount) : 0;
49731
49822
  const alertsTriggerRef = useRef(null);
49732
49823
  const alertsCompanyId = entityConfig.companyId || user?.company_id;
49733
49824
  const showAlertsButton = (role === "supervisor" || role === "optifye") && !!alertsCompanyId && !!supabase;
@@ -50016,10 +50107,7 @@ var SideNavBar = memo$1(({
50016
50107
  children: [
50017
50108
  /* @__PURE__ */ jsxs("div", { className: "relative", children: [
50018
50109
  /* @__PURE__ */ jsx(BellIcon, { className: "w-5 h-5 mb-1" }),
50019
- alertsCount > 0 && /* @__PURE__ */ jsxs("span", { className: "absolute -top-1 -right-1 flex h-2.5 w-2.5", children: [
50020
- /* @__PURE__ */ jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75" }),
50021
- /* @__PURE__ */ jsx("span", { className: "relative inline-flex rounded-full h-2.5 w-2.5 bg-red-500" })
50022
- ] })
50110
+ unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1.5 -right-1.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-red-500 px-1 text-[9px] font-bold text-white shadow-sm ring-2 ring-white", children: unreadCount > 99 ? "99+" : unreadCount })
50023
50111
  ] }),
50024
50112
  /* @__PURE__ */ jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight mt-1", children: "Alerts" })
50025
50113
  ]
@@ -50171,10 +50259,7 @@ var SideNavBar = memo$1(({
50171
50259
  children: [
50172
50260
  /* @__PURE__ */ jsxs("div", { className: "relative", children: [
50173
50261
  /* @__PURE__ */ jsx(BellIcon, { className: getIconClass("/alerts") }),
50174
- alertsCount > 0 && /* @__PURE__ */ jsxs("span", { className: "absolute -top-1 -right-1 flex h-2.5 w-2.5", children: [
50175
- /* @__PURE__ */ jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75" }),
50176
- /* @__PURE__ */ jsx("span", { className: "relative inline-flex rounded-full h-2.5 w-2.5 bg-red-500" })
50177
- ] })
50262
+ unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1.5 -right-1.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-red-500 px-1 text-[9px] font-bold text-white shadow-sm ring-2 ring-white", children: unreadCount > 99 ? "99+" : unreadCount })
50178
50263
  ] }),
50179
50264
  /* @__PURE__ */ jsx("span", { className: "text-base font-medium ml-3", children: "Alerts" })
50180
50265
  ]
@@ -50302,7 +50387,7 @@ var SideNavBar = memo$1(({
50302
50387
  onClose: () => setIsAlertsOpen(false),
50303
50388
  triggerRef: alertsTriggerRef,
50304
50389
  companyId: alertsCompanyId,
50305
- alertsCount,
50390
+ alertsCount: alertsCount ?? 0,
50306
50391
  onAlertsLoaded: setAlertsCount
50307
50392
  }
50308
50393
  )
@@ -57351,6 +57436,7 @@ var WEEKDAYS4 = ["S", "M", "T", "W", "T", "F", "S"];
57351
57436
  var MonthlyRangeFilter = ({
57352
57437
  month,
57353
57438
  year,
57439
+ timezone,
57354
57440
  value,
57355
57441
  onChange,
57356
57442
  onMonthNavigate,
@@ -57358,32 +57444,34 @@ var MonthlyRangeFilter = ({
57358
57444
  variant = "default",
57359
57445
  showLabel = true
57360
57446
  }) => {
57361
- const presets = [
57447
+ const todayKey = useMemo(
57448
+ () => formatInTimeZone(/* @__PURE__ */ new Date(), timezone || "UTC", "yyyy-MM-dd"),
57449
+ [timezone]
57450
+ );
57451
+ const todayDate = useMemo(() => parseDateKeyToDate(todayKey), [todayKey]);
57452
+ const presets = useMemo(() => [
57362
57453
  {
57363
- label: "Last Week",
57364
- getValue: () => ({
57365
- start: startOfDay(subDays(/* @__PURE__ */ new Date(), 6)),
57366
- end: endOfDay(/* @__PURE__ */ new Date())
57367
- })
57454
+ label: "This Week",
57455
+ getValue: () => getCurrentWeekToDateRange(timezone)
57368
57456
  },
57369
57457
  {
57370
57458
  label: "Last Month",
57371
57459
  getValue: () => {
57372
- const lastMonth = subMonths(/* @__PURE__ */ new Date(), 1);
57460
+ const lastMonth = subMonths(todayDate, 1);
57373
57461
  return {
57374
- start: startOfMonth(lastMonth),
57375
- end: endOfMonth(lastMonth)
57462
+ startKey: format(startOfMonth(lastMonth), "yyyy-MM-dd"),
57463
+ endKey: format(endOfMonth(lastMonth), "yyyy-MM-dd")
57376
57464
  };
57377
57465
  }
57378
57466
  },
57379
57467
  {
57380
57468
  label: "This Month",
57381
57469
  getValue: () => ({
57382
- start: startOfMonth(/* @__PURE__ */ new Date()),
57383
- end: endOfDay(/* @__PURE__ */ new Date())
57470
+ startKey: format(startOfMonth(todayDate), "yyyy-MM-dd"),
57471
+ endKey: format(todayDate, "yyyy-MM-dd")
57384
57472
  })
57385
57473
  }
57386
- ];
57474
+ ], [timezone, todayDate]);
57387
57475
  const monthBounds = useMemo(() => getMonthKeyBounds(year, month), [year, month]);
57388
57476
  const normalizedRange = useMemo(() => {
57389
57477
  return normalizeDateKeyRange(value.startKey, value.endKey, monthBounds.startKey, monthBounds.endKey);
@@ -57404,15 +57492,15 @@ var MonthlyRangeFilter = ({
57404
57492
  const [rangeEnd, setRangeEnd] = useState(parseDateKeyToDate(normalizedRange.endKey));
57405
57493
  const [selecting, setSelecting] = useState(false);
57406
57494
  const [activePreset, setActivePreset] = useState(null);
57407
- const today = useMemo(() => endOfDay(/* @__PURE__ */ new Date()), []);
57495
+ const today = useMemo(() => endOfDay(todayDate), [todayDate]);
57408
57496
  useEffect(() => {
57409
57497
  setCalendarMonth(month);
57410
57498
  setCalendarYear(year);
57411
57499
  }, [month, year]);
57412
57500
  useEffect(() => {
57413
57501
  if (isOpen) {
57414
- const start = parseDateKeyToDate(normalizedRange.startKey);
57415
- const end = parseDateKeyToDate(normalizedRange.endKey);
57502
+ const start = parseDateKeyToDate(value.startKey);
57503
+ const end = parseDateKeyToDate(value.endKey);
57416
57504
  setRangeStart(start);
57417
57505
  setRangeEnd(end);
57418
57506
  setSelecting(false);
@@ -57420,11 +57508,11 @@ var MonthlyRangeFilter = ({
57420
57508
  setCalendarYear(year);
57421
57509
  const match = presets.find((p) => {
57422
57510
  const val = p.getValue();
57423
- return isSameDay(val.start, start) && isSameDay(val.end, end);
57511
+ return val.startKey === value.startKey && val.endKey === value.endKey;
57424
57512
  });
57425
57513
  setActivePreset(match ? match.label : "Custom");
57426
57514
  }
57427
- }, [isOpen, normalizedRange.startKey, normalizedRange.endKey, month, year]);
57515
+ }, [isOpen, month, presets, value.endKey, value.startKey, year]);
57428
57516
  useEffect(() => {
57429
57517
  const handleClickOutside = (event) => {
57430
57518
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
@@ -57454,7 +57542,9 @@ var MonthlyRangeFilter = ({
57454
57542
  }
57455
57543
  };
57456
57544
  const handlePresetClick = (preset) => {
57457
- const { start, end } = preset.getValue();
57545
+ const { startKey, endKey } = preset.getValue();
57546
+ const start = parseDateKeyToDate(startKey);
57547
+ const end = parseDateKeyToDate(endKey);
57458
57548
  setRangeStart(start);
57459
57549
  setRangeEnd(end);
57460
57550
  setSelecting(false);
@@ -57494,8 +57584,7 @@ var MonthlyRangeFilter = ({
57494
57584
  const nextMonthDate = addMonths(new Date(calendarYear, calendarMonth), 1);
57495
57585
  const newMonth = nextMonthDate.getMonth();
57496
57586
  const newYear = nextMonthDate.getFullYear();
57497
- const currentDate = /* @__PURE__ */ new Date();
57498
- if (newYear > currentDate.getFullYear() || newYear === currentDate.getFullYear() && newMonth > currentDate.getMonth()) {
57587
+ if (newYear > todayDate.getFullYear() || newYear === todayDate.getFullYear() && newMonth > todayDate.getMonth()) {
57499
57588
  return;
57500
57589
  }
57501
57590
  setCalendarMonth(newMonth);
@@ -57503,7 +57592,7 @@ var MonthlyRangeFilter = ({
57503
57592
  onMonthNavigate?.(newMonth, newYear);
57504
57593
  };
57505
57594
  const canGoPrevious = !(calendarYear === 2023 && calendarMonth === 0);
57506
- const canGoNext = !(calendarYear === (/* @__PURE__ */ new Date()).getFullYear() && calendarMonth === (/* @__PURE__ */ new Date()).getMonth());
57595
+ const canGoNext = !(calendarYear === todayDate.getFullYear() && calendarMonth === todayDate.getMonth());
57507
57596
  const monthDate = useMemo(() => new Date(calendarYear, calendarMonth), [calendarYear, calendarMonth]);
57508
57597
  const calendarDays = useMemo(() => {
57509
57598
  const start = startOfMonth(monthDate);
@@ -66684,7 +66773,8 @@ var useWorkspaceHealth = (options) => {
66684
66773
  healthyWorkspaces: 0,
66685
66774
  unhealthyWorkspaces: 0,
66686
66775
  warningWorkspaces: 0,
66687
- uptimePercentage: 100,
66776
+ uptimePercentage: null,
66777
+ workspacesWithoutUptimeData: 0,
66688
66778
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
66689
66779
  });
66690
66780
  const [loading, setLoading] = useState(true);
@@ -66692,36 +66782,10 @@ var useWorkspaceHealth = (options) => {
66692
66782
  const isFetchingRef = useRef(false);
66693
66783
  const refreshIntervalRef = useRef(null);
66694
66784
  const healthTable = databaseConfig?.tables?.workspace_health || "workspace_health_status";
66695
- const computeSummary = useCallback((data) => {
66696
- const total = data.length;
66697
- const healthy = data.filter((w) => w.status === "healthy").length;
66698
- const unhealthy = data.filter((w) => w.status === "unhealthy").length;
66699
- const warning6 = data.filter((w) => w.status === "warning").length;
66700
- let uptimePercentage = total > 0 ? healthy / total * 100 : 100;
66701
- let totalDowntimeMinutes;
66702
- const withUptime = data.filter(
66703
- (w) => w.uptimePercentage !== void 0 && w.uptimeDetails !== void 0
66704
- );
66705
- if (withUptime.length > 0) {
66706
- const totalUptime = withUptime.reduce((sum, w) => sum + (w.uptimePercentage || 0), 0);
66707
- uptimePercentage = totalUptime / withUptime.length;
66708
- totalDowntimeMinutes = withUptime.reduce((sum, w) => {
66709
- if (w.uptimeDetails) {
66710
- return sum + Math.max(0, w.uptimeDetails.expectedMinutes - w.uptimeDetails.actualMinutes);
66711
- }
66712
- return sum;
66713
- }, 0);
66714
- }
66715
- return {
66716
- totalWorkspaces: total,
66717
- healthyWorkspaces: healthy,
66718
- unhealthyWorkspaces: unhealthy,
66719
- warningWorkspaces: warning6,
66720
- uptimePercentage,
66721
- totalDowntimeMinutes,
66722
- lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
66723
- };
66724
- }, []);
66785
+ const computeSummary = useCallback(
66786
+ (data) => computeWorkspaceHealthSummary(data),
66787
+ []
66788
+ );
66725
66789
  const fetchWorkspacesHealth = useCallback(async () => {
66726
66790
  if (isFetchingRef.current) return;
66727
66791
  if (isShiftConfigLoading) {
@@ -66876,7 +66940,7 @@ var UptimeTimelineStrip = ({
66876
66940
  shiftEnd,
66877
66941
  timezone,
66878
66942
  className = "",
66879
- uptimePercentage = 0,
66943
+ uptimePercentage = null,
66880
66944
  downtimeMinutes = 0
66881
66945
  }) => {
66882
66946
  const segments = useMemo(() => {
@@ -66941,7 +67005,7 @@ var UptimeTimelineStrip = ({
66941
67005
  return /* @__PURE__ */ jsx("div", { className: "w-full rounded-xl border border-dashed border-gray-200 bg-gray-50/50 p-6 text-center text-sm text-gray-600", children: "No uptime data available for this shift yet." });
66942
67006
  }
66943
67007
  return /* @__PURE__ */ jsxs("div", { className: `relative w-full ${className}`, children: [
66944
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center mb-3 text-sm", children: /* @__PURE__ */ jsxs("span", { className: "text-gray-900 font-semibold", children: [
67008
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center mb-3 text-sm", children: typeof uptimePercentage === "number" ? /* @__PURE__ */ jsxs("span", { className: "text-gray-900 font-semibold", children: [
66945
67009
  uptimePercentage.toFixed(1),
66946
67010
  " % uptime ",
66947
67011
  downtimeMinutes > 0 && /* @__PURE__ */ jsxs("span", { className: "text-gray-600 font-normal", children: [
@@ -66949,7 +67013,7 @@ var UptimeTimelineStrip = ({
66949
67013
  formatDowntimeLabel(downtimeMinutes),
66950
67014
  ")"
66951
67015
  ] })
66952
- ] }) }),
67016
+ ] }) : /* @__PURE__ */ jsx("span", { className: "text-gray-600 font-medium", children: "Uptime data unavailable" }) }),
66953
67017
  /* @__PURE__ */ jsx("div", { className: "relative flex h-4 overflow-hidden rounded-lg border border-gray-200 shadow-sm bg-white", children: segments.map((segment, index) => {
66954
67018
  const startDate = new Date(segment.startTimestamp);
66955
67019
  const endDate = new Date(segment.endTimestamp);
@@ -67070,7 +67134,8 @@ var WorkspaceUptimeDetailModal = ({
67070
67134
  const downtimeSegments = timeline?.downtimeSegments || [];
67071
67135
  downtimeSegments.length;
67072
67136
  const downtimeMinutes = timeline?.downtimeMinutes ?? 0;
67073
- const uptimePercentage = timeline?.uptimePercentage ?? workspace?.uptimePercentage ?? 0;
67137
+ const hasTimelineData = Boolean(timeline?.hasData);
67138
+ const uptimePercentage = hasTimelineData ? timeline?.uptimePercentage ?? workspace?.uptimePercentage ?? null : null;
67074
67139
  const allInterruptionsSorted = useMemo(
67075
67140
  () => [...downtimeSegments].sort(
67076
67141
  (a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime()
@@ -67192,7 +67257,7 @@ var WorkspaceUptimeDetailModal = ({
67192
67257
  shiftEnd: timeline?.shiftEnd || (/* @__PURE__ */ new Date()).toISOString(),
67193
67258
  timezone,
67194
67259
  uptimePercentage,
67195
- downtimeMinutes
67260
+ downtimeMinutes: hasTimelineData ? downtimeMinutes : 0
67196
67261
  }
67197
67262
  ),
67198
67263
  loading && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-600 mt-4", children: [
@@ -67202,7 +67267,7 @@ var WorkspaceUptimeDetailModal = ({
67202
67267
  ] }),
67203
67268
  /* @__PURE__ */ jsxs("div", { className: "pt-4", children: [
67204
67269
  /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 uppercase tracking-wider mb-3", children: "Downtime Logs" }),
67205
- downtimeSegments.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-gray-100 bg-gray-50/50 px-5 py-4 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600", children: "No downtime events recorded for this shift." }) }) : /* @__PURE__ */ jsxs("div", { className: "relative", children: [
67270
+ !hasTimelineData ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-gray-100 bg-gray-50/50 px-5 py-4 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600", children: "No uptime data available for this shift." }) }) : downtimeSegments.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-gray-100 bg-gray-50/50 px-5 py-4 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600", children: "No downtime events recorded for this shift." }) }) : /* @__PURE__ */ jsxs("div", { className: "relative", children: [
67206
67271
  /* @__PURE__ */ jsx(
67207
67272
  "div",
67208
67273
  {
@@ -67327,6 +67392,7 @@ var WorkspaceHealthView = ({
67327
67392
  }
67328
67393
  };
67329
67394
  const getUptimeColor = (percentage) => {
67395
+ if (percentage === null) return "text-gray-500 dark:text-gray-400";
67330
67396
  if (percentage >= 97) return "text-green-600 dark:text-green-400";
67331
67397
  if (percentage >= 90) return "text-yellow-600 dark:text-yellow-400";
67332
67398
  return "text-red-600 dark:text-red-400";
@@ -67436,13 +67502,16 @@ var WorkspaceHealthView = ({
67436
67502
  /* @__PURE__ */ jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "System Availability" }) }),
67437
67503
  /* @__PURE__ */ jsxs(CardContent2, { children: [
67438
67504
  /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
67439
- /* @__PURE__ */ jsxs("span", { className: clsx("text-3xl font-bold", getUptimeColor(summary.uptimePercentage)), children: [
67440
- summary.uptimePercentage.toFixed(1),
67441
- "%"
67442
- ] }),
67443
- summary.uptimePercentage >= 97 ? /* @__PURE__ */ jsx(TrendingUp, { className: "h-5 w-5 text-green-500" }) : summary.uptimePercentage >= 90 ? /* @__PURE__ */ jsx(Activity, { className: "h-5 w-5 text-yellow-500" }) : /* @__PURE__ */ jsx(TrendingDown, { className: "h-5 w-5 text-red-500" })
67505
+ /* @__PURE__ */ jsx("span", { className: clsx("text-3xl font-bold", getUptimeColor(summary.uptimePercentage)), children: summary.uptimePercentage === null ? "No data" : `${summary.uptimePercentage.toFixed(1)}%` }),
67506
+ summary.uptimePercentage === null ? /* @__PURE__ */ jsx(Activity, { className: "h-5 w-5 text-gray-400" }) : summary.uptimePercentage >= 97 ? /* @__PURE__ */ jsx(TrendingUp, { className: "h-5 w-5 text-green-500" }) : summary.uptimePercentage >= 90 ? /* @__PURE__ */ jsx(Activity, { className: "h-5 w-5 text-yellow-500" }) : /* @__PURE__ */ jsx(TrendingDown, { className: "h-5 w-5 text-red-500" })
67444
67507
  ] }),
67445
- /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Overall system uptime today" })
67508
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: summary.uptimePercentage === null ? "Uptime metrics unavailable for visible workspaces" : "Overall system uptime today" }),
67509
+ summary.workspacesWithoutUptimeData > 0 && /* @__PURE__ */ jsxs("p", { className: "text-xs text-amber-600 mt-1", children: [
67510
+ summary.workspacesWithoutUptimeData,
67511
+ " workspace",
67512
+ summary.workspacesWithoutUptimeData === 1 ? "" : "s",
67513
+ " missing uptime data"
67514
+ ] })
67446
67515
  ] })
67447
67516
  ] }),
67448
67517
  /* @__PURE__ */ jsxs(Card2, { className: "bg-white", children: [
@@ -69088,6 +69157,155 @@ Please ensure:
69088
69157
  var AuthenticatedTicketsView = withAuth(React141__default.memo(TicketsView));
69089
69158
  var TicketsView_default = TicketsView;
69090
69159
 
69160
+ // src/lib/utils/improvementDisplay.ts
69161
+ var LINE_WIDE_ISSUE_LABEL = "Line-wide issue";
69162
+ var UNKNOWN_LINE_LABEL = "Unknown line";
69163
+ var UNKNOWN_WORKSTATION_LABEL = "Unknown workstation";
69164
+ var UNASSIGNED_SUPERVISOR_LABEL = "Unassigned";
69165
+ var normalizeLabel = (value) => {
69166
+ if (typeof value !== "string") return void 0;
69167
+ const trimmed = value.trim();
69168
+ return trimmed.length > 0 ? trimmed : void 0;
69169
+ };
69170
+ var toFiniteNumber = (value) => {
69171
+ if (typeof value === "number" && Number.isFinite(value)) return value;
69172
+ if (typeof value === "string" && value.trim().length > 0) {
69173
+ const parsed = Number(value);
69174
+ return Number.isFinite(parsed) ? parsed : null;
69175
+ }
69176
+ return null;
69177
+ };
69178
+ var normalizeSupervisorNames = (supervisors) => {
69179
+ if (!supervisors) return [];
69180
+ if (typeof supervisors === "string") {
69181
+ const label = normalizeLabel(supervisors);
69182
+ return label ? [label] : [];
69183
+ }
69184
+ return supervisors.map((supervisor) => {
69185
+ if (typeof supervisor === "string") {
69186
+ return normalizeLabel(supervisor);
69187
+ }
69188
+ return normalizeLabel(supervisor?.displayName);
69189
+ }).filter((name) => !!name);
69190
+ };
69191
+ var formatImprovementTicketNumber = (issueNumber) => {
69192
+ if (typeof issueNumber !== "number" || !Number.isFinite(issueNumber)) {
69193
+ return null;
69194
+ }
69195
+ return `#${issueNumber}`;
69196
+ };
69197
+ var formatImprovementPieceGain = (pcsGain) => {
69198
+ const rounded = Math.round(pcsGain);
69199
+ return `+${rounded.toLocaleString("en-US")} pcs / day`;
69200
+ };
69201
+ var getPositiveImprovementGain = ({
69202
+ estimated_gain_pieces
69203
+ }) => {
69204
+ const issueGain = toFiniteNumber(estimated_gain_pieces);
69205
+ return {
69206
+ pcsGain: issueGain !== null && issueGain > 0 ? issueGain : null
69207
+ };
69208
+ };
69209
+ var getImprovementDisplayMetadata = ({
69210
+ location,
69211
+ line,
69212
+ workspaceId,
69213
+ supervisors
69214
+ }) => {
69215
+ const supervisorNames = normalizeSupervisorNames(supervisors);
69216
+ const workstationLabel = workspaceId ? normalizeLabel(location) ?? UNKNOWN_WORKSTATION_LABEL : LINE_WIDE_ISSUE_LABEL;
69217
+ const lineLabel = normalizeLabel(line) ?? UNKNOWN_LINE_LABEL;
69218
+ const supervisorLabel = supervisorNames.length > 0 ? supervisorNames.join(", ") : UNASSIGNED_SUPERVISOR_LABEL;
69219
+ return {
69220
+ workstationLabel,
69221
+ lineLabel,
69222
+ supervisorLabel,
69223
+ metadataLabel: [workstationLabel, lineLabel, supervisorLabel].join(" \xB7 ")
69224
+ };
69225
+ };
69226
+ var toFiniteNumber2 = (value) => {
69227
+ if (typeof value === "number" && Number.isFinite(value)) return value;
69228
+ if (typeof value === "string" && value.trim().length > 0) {
69229
+ const parsed = Number(value);
69230
+ return Number.isFinite(parsed) ? parsed : null;
69231
+ }
69232
+ return null;
69233
+ };
69234
+ var getImprovementGainSummary = (recommendation) => {
69235
+ const { pcsGain } = getPositiveImprovementGain(recommendation);
69236
+ if (pcsGain !== null) {
69237
+ return {
69238
+ primary: formatImprovementPieceGain(pcsGain)
69239
+ };
69240
+ }
69241
+ return null;
69242
+ };
69243
+ var needsTargetReadjustment = (recommendation) => {
69244
+ if (recommendation.targets_need_reassignment === true) return true;
69245
+ const metrics2 = recommendation.metrics || {};
69246
+ return metrics2.targets_need_reassignment_current === true;
69247
+ };
69248
+ var compareImprovementRecommendationPriority = (left, right) => {
69249
+ const leftIndustrial = left.industrial_eng_bottleneck ? 1 : 0;
69250
+ const rightIndustrial = right.industrial_eng_bottleneck ? 1 : 0;
69251
+ if (leftIndustrial !== rightIndustrial) {
69252
+ return rightIndustrial - leftIndustrial;
69253
+ }
69254
+ const leftGain = toFiniteNumber2(left.estimated_gain_pieces);
69255
+ const rightGain = toFiniteNumber2(right.estimated_gain_pieces);
69256
+ if (leftGain !== rightGain) {
69257
+ if (leftGain === null) return 1;
69258
+ if (rightGain === null) return -1;
69259
+ return rightGain - leftGain;
69260
+ }
69261
+ const leftRatio = toFiniteNumber2(left.gain_to_target_ratio);
69262
+ const rightRatio = toFiniteNumber2(right.gain_to_target_ratio);
69263
+ if (leftRatio !== rightRatio) {
69264
+ if (leftRatio === null) return 1;
69265
+ if (rightRatio === null) return -1;
69266
+ return rightRatio - leftRatio;
69267
+ }
69268
+ return (left.issue_number || Number.MAX_SAFE_INTEGER) - (right.issue_number || Number.MAX_SAFE_INTEGER);
69269
+ };
69270
+ var ImprovementRecommendationSignals = ({
69271
+ recommendation,
69272
+ className
69273
+ }) => {
69274
+ const gainSummary = getImprovementGainSummary(recommendation);
69275
+ const showTargetReadjustment = needsTargetReadjustment(recommendation);
69276
+ if (!gainSummary && !showTargetReadjustment) {
69277
+ return null;
69278
+ }
69279
+ return /* @__PURE__ */ jsxs("div", { className: className || "flex flex-wrap items-center gap-x-4 gap-y-3", children: [
69280
+ gainSummary && /* @__PURE__ */ jsxs(
69281
+ "span",
69282
+ {
69283
+ "data-testid": "improvement-gain-chip",
69284
+ className: "inline-flex items-center gap-1.5 rounded-full border border-emerald-200 bg-emerald-50 px-3 py-1.5 text-sm font-medium text-emerald-700 shadow-sm",
69285
+ children: [
69286
+ /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-trending-up w-4 h-4", children: [
69287
+ /* @__PURE__ */ jsx("polyline", { points: "22 7 13.5 15.5 8.5 10.5 2 17" }),
69288
+ /* @__PURE__ */ jsx("polyline", { points: "16 7 22 7 22 13" })
69289
+ ] }),
69290
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: gainSummary.primary })
69291
+ ]
69292
+ }
69293
+ ),
69294
+ showTargetReadjustment && /* @__PURE__ */ jsxs(
69295
+ "span",
69296
+ {
69297
+ "data-testid": "targets-readjustment-chip",
69298
+ className: "inline-flex items-center gap-1.5 rounded-full border border-amber-200 bg-white px-3 py-1.5 text-sm font-medium text-amber-700 shadow-sm",
69299
+ children: [
69300
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4 text-amber-600" }),
69301
+ "Targets need readjustment"
69302
+ ]
69303
+ }
69304
+ )
69305
+ ] });
69306
+ };
69307
+ var ImprovementRecommendationSignals_default = ImprovementRecommendationSignals;
69308
+
69091
69309
  // src/lib/api/s3-clips-parser.ts
69092
69310
  function parseS3Uri(s3Uri, sopCategories) {
69093
69311
  const path = new URL(s3Uri).pathname;
@@ -69265,6 +69483,24 @@ var buildInitials = (name) => {
69265
69483
  const second = parts.length > 1 ? parts[1]?.[0] || "" : "";
69266
69484
  return `${first}${second}`.toUpperCase();
69267
69485
  };
69486
+ var getQueryParam = (value) => {
69487
+ if (typeof value === "string") {
69488
+ const trimmed = value.trim();
69489
+ return trimmed.length > 0 ? trimmed : null;
69490
+ }
69491
+ if (Array.isArray(value)) {
69492
+ const firstValue = value[0];
69493
+ return getQueryParam(firstValue);
69494
+ }
69495
+ return null;
69496
+ };
69497
+ var getQueryParamFromAsPath = (asPath, key) => {
69498
+ if (!asPath || !asPath.includes("?")) return null;
69499
+ const queryString = asPath.split("?")[1]?.split("#")[0];
69500
+ if (!queryString) return null;
69501
+ const value = new URLSearchParams(queryString).get(key);
69502
+ return getQueryParam(value ?? void 0);
69503
+ };
69268
69504
  var ClipVideoCarousel = ({ clips, clipsService }) => {
69269
69505
  const [currentIndex, setCurrentIndex] = useState(0);
69270
69506
  const [videos, setVideos] = useState([]);
@@ -69586,6 +69822,7 @@ var EvidenceCarousel = ({ evidence, clipsService }) => {
69586
69822
  };
69587
69823
  var ImprovementCenterView = () => {
69588
69824
  const { navigate } = useNavigation();
69825
+ const router = useRouter();
69589
69826
  const supabase = useSupabase();
69590
69827
  const { user } = useAuth();
69591
69828
  const dashboardConfig = useDashboardConfig();
@@ -69596,6 +69833,7 @@ var ImprovementCenterView = () => {
69596
69833
  const [selectedShift, setSelectedShift] = useState("all");
69597
69834
  const [selectedWeeksRange, setSelectedWeeksRange] = useState("all");
69598
69835
  const [selectedMemberId, setSelectedMemberId] = useState("all");
69836
+ const [selectedSortBy, setSelectedSortBy] = useState("all");
69599
69837
  const [recommendations, setRecommendations] = useState([]);
69600
69838
  const [isLoading, setIsLoading] = useState(false);
69601
69839
  const [loadError, setLoadError] = useState(null);
@@ -69634,14 +69872,6 @@ var ImprovementCenterView = () => {
69634
69872
  if (day % 10 === 3) return "rd";
69635
69873
  return "th";
69636
69874
  };
69637
- const formatOpenedDate = (firstSeenAt) => {
69638
- if (!firstSeenAt) return void 0;
69639
- const zoned = toZonedDate(firstSeenAt);
69640
- if (!zoned) return void 0;
69641
- const day = zoned.getDate();
69642
- const month = zoned.toLocaleString("en-US", { month: "short" });
69643
- return `${day}${getDaySuffix(day)} ${month}`;
69644
- };
69645
69875
  const formatMonthDay = (date) => {
69646
69876
  const month = date.toLocaleString("en-US", { month: "short" });
69647
69877
  return `${month} ${date.getDate()}`;
@@ -69723,6 +69953,9 @@ var ImprovementCenterView = () => {
69723
69953
  return map;
69724
69954
  }, [companyLines, configuredLines]);
69725
69955
  const companyId = user?.company_id || entityConfig.companyId;
69956
+ const focusIssueId = useMemo(() => {
69957
+ return getQueryParam(router.query.focusIssueId) || getQueryParamFromAsPath(router.asPath, "focusIssueId");
69958
+ }, [router.asPath, router.query.focusIssueId]);
69726
69959
  const clipsService = useMemo(() => {
69727
69960
  try {
69728
69961
  return new S3ClipsSupabaseService(dashboardConfig);
@@ -69730,6 +69963,11 @@ var ImprovementCenterView = () => {
69730
69963
  return null;
69731
69964
  }
69732
69965
  }, [dashboardConfig]);
69966
+ const { supervisorsByLineId } = useSupervisorsByLineIds(scopeLineIds, {
69967
+ enabled: !!companyId && scopeLineIds.length > 0,
69968
+ companyId,
69969
+ useBackend: true
69970
+ });
69733
69971
  useEffect(() => {
69734
69972
  let cancelled = false;
69735
69973
  const loadTeamMembers = async () => {
@@ -69841,8 +70079,17 @@ var ImprovementCenterView = () => {
69841
70079
  const teamMembersById = useMemo(() => {
69842
70080
  return new Map(teamMembers.map((member) => [member.id, member]));
69843
70081
  }, [teamMembers]);
70082
+ const getRecommendationDisplayMetadata = React141__default.useCallback((rec) => {
70083
+ const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
70084
+ return getImprovementDisplayMetadata({
70085
+ location: rec.location,
70086
+ line: rec.line,
70087
+ workspaceId: rec.workspace_id,
70088
+ supervisors
70089
+ });
70090
+ }, [supervisorsByLineId]);
69844
70091
  const filteredRecommendations = useMemo(() => {
69845
- return recommendations.filter((rec) => {
70092
+ const sortedRecommendations = recommendations.filter((rec) => {
69846
70093
  if (selectedLineId !== "all" && rec.line_id !== selectedLineId) return false;
69847
70094
  if (selectedStatus === "resolved" && rec.ticket_status !== "solved") return false;
69848
70095
  if (selectedStatus === "unresolved" && rec.ticket_status === "solved") return false;
@@ -69856,12 +70103,44 @@ var ImprovementCenterView = () => {
69856
70103
  if (selectedMemberId !== "all" && !(rec.assigned_user_ids?.includes(selectedMemberId) || rec.assigned_to_user_id === selectedMemberId)) return false;
69857
70104
  return true;
69858
70105
  }).sort((a, b) => {
69859
- const aIndustrial = a.industrial_eng_bottleneck ? 1 : 0;
69860
- const bIndustrial = b.industrial_eng_bottleneck ? 1 : 0;
69861
- if (aIndustrial !== bIndustrial) return bIndustrial - aIndustrial;
69862
- return (a.issue_number || 0) - (b.issue_number || 0);
70106
+ if (selectedSortBy === "highest_to_lowest") {
70107
+ const gainA = toFiniteNumber2(a.estimated_gain_pieces) || 0;
70108
+ const gainB = toFiniteNumber2(b.estimated_gain_pieces) || 0;
70109
+ if (gainA !== gainB) {
70110
+ return gainB - gainA;
70111
+ }
70112
+ } else if (selectedSortBy === "lowest_to_highest") {
70113
+ const gainA = toFiniteNumber2(a.estimated_gain_pieces) || 0;
70114
+ const gainB = toFiniteNumber2(b.estimated_gain_pieces) || 0;
70115
+ if (gainA !== gainB) {
70116
+ return gainA - gainB;
70117
+ }
70118
+ }
70119
+ return compareImprovementRecommendationPriority(a, b);
69863
70120
  });
69864
- }, [recommendations, selectedLineId, selectedStatus, selectedShift, selectedWeeksRange, selectedMemberId]);
70121
+ if (!focusIssueId) {
70122
+ return sortedRecommendations;
70123
+ }
70124
+ const focusedIndex = sortedRecommendations.findIndex((rec) => rec.issue_id === focusIssueId);
70125
+ if (focusedIndex <= 0) {
70126
+ return sortedRecommendations;
70127
+ }
70128
+ const focusedItem = sortedRecommendations[focusedIndex];
70129
+ return [
70130
+ focusedItem,
70131
+ ...sortedRecommendations.slice(0, focusedIndex),
70132
+ ...sortedRecommendations.slice(focusedIndex + 1)
70133
+ ];
70134
+ }, [
70135
+ focusIssueId,
70136
+ recommendations,
70137
+ selectedLineId,
70138
+ selectedMemberId,
70139
+ selectedShift,
70140
+ selectedStatus,
70141
+ selectedWeeksRange,
70142
+ selectedSortBy
70143
+ ]);
69865
70144
  const stats = useMemo(() => {
69866
70145
  const baseFiltered = recommendations.filter((rec) => {
69867
70146
  if (selectedLineId !== "all" && rec.line_id !== selectedLineId) return false;
@@ -69890,7 +70169,8 @@ var ImprovementCenterView = () => {
69890
70169
  status: selectedStatus,
69891
70170
  shift: selectedShift,
69892
70171
  weeks_range: selectedWeeksRange,
69893
- member_id: selectedMemberId
70172
+ member_id: selectedMemberId,
70173
+ sort_by: selectedSortBy
69894
70174
  }
69895
70175
  });
69896
70176
  setSelectedLineId("all");
@@ -69898,6 +70178,7 @@ var ImprovementCenterView = () => {
69898
70178
  setSelectedShift("all");
69899
70179
  setSelectedWeeksRange("all");
69900
70180
  setSelectedMemberId("all");
70181
+ setSelectedSortBy("all");
69901
70182
  };
69902
70183
  const shiftOptions = useMemo(() => {
69903
70184
  const shifts = /* @__PURE__ */ new Set();
@@ -69977,6 +70258,14 @@ var ImprovementCenterView = () => {
69977
70258
  });
69978
70259
  setSelectedLineId(lineId);
69979
70260
  };
70261
+ const handleSortByChange = (sortBy) => {
70262
+ trackCoreEvent("Improvement Center Filter Applied", {
70263
+ filter_type: "sort_by",
70264
+ filter_value: sortBy,
70265
+ previous_value: selectedSortBy
70266
+ });
70267
+ setSelectedSortBy(sortBy);
70268
+ };
69980
70269
  return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
69981
70270
  /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-30 bg-white border-b border-gray-200 flex-shrink-0", children: /* @__PURE__ */ jsx("div", { className: "px-4 sm:px-6 lg:px-8 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
69982
70271
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-4 min-w-[120px]", children: /* @__PURE__ */ jsx(
@@ -70016,11 +70305,11 @@ var ImprovementCenterView = () => {
70016
70305
  "button",
70017
70306
  {
70018
70307
  onClick: () => setIsFilterOpen(!isFilterOpen),
70019
- className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || (selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedLineId !== "all") ? "bg-blue-50 border-blue-200 text-blue-700" : "bg-white border-gray-200 text-gray-700 hover:bg-gray-50"}`,
70308
+ className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || (selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedLineId !== "all" || selectedSortBy !== "all") ? "bg-blue-50 border-blue-200 text-blue-700" : "bg-white border-gray-200 text-gray-700 hover:bg-gray-50"}`,
70020
70309
  children: [
70021
70310
  /* @__PURE__ */ jsx(FunnelIcon, { className: "w-4 h-4" }),
70022
70311
  /* @__PURE__ */ jsx("span", { children: "Filters" }),
70023
- (selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedLineId !== "all") && /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center w-5 h-5 bg-blue-100 text-blue-700 text-xs rounded-full font-bold ml-1", children: [selectedShift, selectedWeeksRange, selectedMemberId, selectedLineId].filter((v) => v !== "all").length }),
70312
+ (selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedLineId !== "all" || selectedSortBy !== "all") && /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center w-5 h-5 bg-blue-100 text-blue-700 text-xs rounded-full font-bold ml-1", children: [selectedShift, selectedWeeksRange, selectedMemberId, selectedLineId].filter((v) => v !== "all").length + (selectedSortBy !== "all" ? 1 : 0) }),
70024
70313
  /* @__PURE__ */ jsx(ChevronDownIcon, { className: `w-3 h-3 ml-1 transition-transform ${isFilterOpen ? "rotate-180" : ""}` })
70025
70314
  ]
70026
70315
  }
@@ -70028,7 +70317,7 @@ var ImprovementCenterView = () => {
70028
70317
  isFilterOpen && /* @__PURE__ */ jsxs("div", { className: "absolute right-0 top-full mt-2 w-72 bg-white rounded-xl shadow-xl border border-gray-100 p-4 z-50 animate-in fade-in zoom-in-95 duration-100", children: [
70029
70318
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
70030
70319
  /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Filter View" }),
70031
- (selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedLineId !== "all") && /* @__PURE__ */ jsx(
70320
+ (selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedLineId !== "all" || selectedSortBy !== "all") && /* @__PURE__ */ jsx(
70032
70321
  "button",
70033
70322
  {
70034
70323
  onClick: clearFilters,
@@ -70038,6 +70327,7 @@ var ImprovementCenterView = () => {
70038
70327
  )
70039
70328
  ] }),
70040
70329
  /* @__PURE__ */ jsx("div", { className: "space-y-3", children: [
70330
+ { value: selectedSortBy, onChange: handleSortByChange, options: [{ id: "all", label: "All" }, { id: "highest_to_lowest", label: "Highest to Lowest" }, { id: "lowest_to_highest", label: "Lowest to Highest" }], label: "Priority" },
70041
70331
  { value: selectedShift, onChange: handleShiftFilterChange, options: shiftOptions, label: "Shift" },
70042
70332
  { value: selectedWeeksRange, onChange: handleWeeksFilterChange, options: weekOptions.map((o) => o.id), labels: weekOptions, label: "Duration" },
70043
70333
  { value: selectedMemberId, onChange: handleMemberFilterChange, options: ["all", ...teamMembers.map((m) => m.id)], labels: teamMembers, label: "Member" },
@@ -70053,12 +70343,19 @@ var ImprovementCenterView = () => {
70053
70343
  style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.75rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
70054
70344
  children: filter2.options.map((opt) => {
70055
70345
  const val = typeof opt === "string" ? opt : opt.id;
70056
- let label = val;
70057
- if (filter2.labels) {
70058
- const found = filter2.labels.find((l) => (l.id || l.user_id || l) === val);
70346
+ let label;
70347
+ if (val === "all") {
70348
+ label = filter2.label === "Priority" ? "All Priorities" : `All ${filter2.label}s`;
70349
+ } else if (typeof opt === "object" && opt !== null && typeof opt.label === "string" && opt.label.length > 0) {
70350
+ label = opt.label;
70351
+ } else if (filter2.labels) {
70352
+ const found = filter2.labels.find(
70353
+ (l) => (l.id || l.user_id || l) === val
70354
+ );
70059
70355
  label = found ? found.label || found.name || found : val;
70356
+ } else {
70357
+ label = val;
70060
70358
  }
70061
- if (val === "all") label = `All ${filter2.label}s`;
70062
70359
  return /* @__PURE__ */ jsx("option", { value: val, children: label }, val);
70063
70360
  })
70064
70361
  }
@@ -70071,23 +70368,25 @@ var ImprovementCenterView = () => {
70071
70368
  filteredRecommendations.length > 0 ? filteredRecommendations.map((rec, index) => {
70072
70369
  const weeksOpen = rec.weeks_open || 1;
70073
70370
  const openLabel = weeksOpen <= 1 ? "Opened this week" : `Opened for ${weeksOpen} weeks`;
70074
- formatOpenedDate(rec.first_seen_at);
70075
70371
  const periodLabel = formatPeriodRange(rec.period_start, rec.period_end);
70076
70372
  const description = stripPeriodFromDescription(rec.description, rec.period_start, rec.period_end);
70373
+ const ticketLabel = formatImprovementTicketNumber(rec.issue_number) || `#${index + 1}`;
70374
+ const displayMetadata = getRecommendationDisplayMetadata(rec);
70375
+ const hasSignalContent = Boolean(
70376
+ rec.resolution_instructions || rec.targets_need_reassignment || rec.estimated_gain_pieces !== void 0 || rec.metrics && Object.keys(rec.metrics).length > 0
70377
+ );
70077
70378
  return /* @__PURE__ */ jsx(
70078
70379
  motion.div,
70079
70380
  {
70080
70381
  initial: { opacity: 0, y: 20 },
70081
70382
  animate: { opacity: 1, y: 0 },
70082
70383
  transition: { delay: index * 0.1 },
70384
+ "data-testid": `improvement-card-${rec.issue_id}`,
70083
70385
  className: `bg-white rounded-xl shadow-sm border overflow-hidden ${rec.ticket_status === "solved" ? "border-green-200" : "border-gray-200"}`,
70084
70386
  children: /* @__PURE__ */ jsx("div", { className: "p-5 relative", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col lg:flex-row gap-5", children: [
70085
70387
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
70086
70388
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-3", children: [
70087
- /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-sm font-semibold text-gray-600 bg-gray-100 border border-gray-200", children: [
70088
- "#",
70089
- rec.issue_number ?? index + 1
70090
- ] }),
70389
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-sm font-semibold text-gray-600 bg-gray-100 border border-gray-200", children: ticketLabel }),
70091
70390
  rec.ticket_status === "solved" ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-sm font-medium bg-emerald-50 text-emerald-700 border border-emerald-100", children: [
70092
70391
  /* @__PURE__ */ jsx(CheckCircleIcon, { className: "w-4 h-4" }),
70093
70392
  "Resolved"
@@ -70116,32 +70415,44 @@ var ImprovementCenterView = () => {
70116
70415
  ] })
70117
70416
  ] }),
70118
70417
  /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: rec.title }),
70119
- /* @__PURE__ */ jsxs("p", { className: "text-base text-gray-500 mb-3", children: [
70120
- rec.location,
70121
- " \xB7 ",
70122
- rec.line,
70123
- (rec.shift_label || rec.shift_id !== void 0) && /* @__PURE__ */ jsxs("span", { className: "uppercase tracking-wide text-sm ml-1", children: [
70124
- "\xB7 ",
70125
- rec.shift_label || `Shift ${rec.shift_id}`
70126
- ] }),
70127
- periodLabel && /* @__PURE__ */ jsxs("span", { children: [
70128
- " \xB7 ",
70129
- periodLabel
70130
- ] })
70131
- ] }),
70418
+ /* @__PURE__ */ jsxs(
70419
+ "p",
70420
+ {
70421
+ className: "text-base text-gray-500 mb-3",
70422
+ title: displayMetadata.metadataLabel,
70423
+ children: [
70424
+ displayMetadata.workstationLabel,
70425
+ " \xB7 ",
70426
+ displayMetadata.lineLabel,
70427
+ " \xB7 ",
70428
+ displayMetadata.supervisorLabel,
70429
+ (rec.shift_label || rec.shift_id !== void 0) && /* @__PURE__ */ jsxs("span", { className: "uppercase tracking-wide text-sm ml-1", children: [
70430
+ "\xB7 ",
70431
+ rec.shift_label || `Shift ${rec.shift_id}`
70432
+ ] }),
70433
+ periodLabel && /* @__PURE__ */ jsxs("span", { children: [
70434
+ " \xB7 ",
70435
+ periodLabel
70436
+ ] })
70437
+ ]
70438
+ }
70439
+ ),
70132
70440
  /* @__PURE__ */ jsx("p", { className: "text-base text-gray-600 leading-relaxed", children: description }),
70133
- rec.resolution_instructions && /* @__PURE__ */ jsxs("div", { className: "relative group inline-flex mt-4", children: [
70134
- /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-sm font-medium bg-blue-50 text-blue-600 border border-blue-200 cursor-help transition-colors group-hover:bg-blue-100", children: [
70135
- /* @__PURE__ */ jsx(EyeIcon, { className: "w-4 h-4" }),
70136
- "Resolution Goal"
70137
- ] }),
70138
- /* @__PURE__ */ jsxs("div", { className: "absolute left-0 bottom-full mb-2 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-150 z-50 pointer-events-none", children: [
70139
- /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-xl border border-gray-100 p-4 w-80", children: [
70140
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-500 uppercase tracking-wide mb-1.5", children: "How this ticket gets resolved" }),
70141
- /* @__PURE__ */ jsx("p", { className: "text-base text-gray-700 leading-relaxed", children: rec.resolution_instructions })
70441
+ hasSignalContent && /* @__PURE__ */ jsxs("div", { className: "mt-6 flex flex-wrap items-center gap-x-4 gap-y-3", children: [
70442
+ rec.resolution_instructions && /* @__PURE__ */ jsxs("div", { className: "relative group inline-flex", children: [
70443
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-sm font-medium bg-blue-50 text-blue-600 border border-blue-200 cursor-help transition-colors group-hover:bg-blue-100 shadow-sm", children: [
70444
+ /* @__PURE__ */ jsx(EyeIcon, { className: "w-4 h-4" }),
70445
+ "Resolve"
70142
70446
  ] }),
70143
- /* @__PURE__ */ jsx("div", { className: "absolute left-4 top-full w-0 h-0 border-l-[6px] border-r-[6px] border-t-[6px] border-transparent border-t-white", style: { filter: "drop-shadow(0 1px 1px rgba(0,0,0,0.05))" } })
70144
- ] })
70447
+ /* @__PURE__ */ jsxs("div", { className: "absolute left-0 bottom-full mb-2 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-150 z-50 pointer-events-none", children: [
70448
+ /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-xl border border-gray-100 p-4 w-80", children: [
70449
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-500 uppercase tracking-wide mb-1.5", children: "How this ticket gets resolved" }),
70450
+ /* @__PURE__ */ jsx("p", { className: "text-base text-gray-700 leading-relaxed", children: rec.resolution_instructions })
70451
+ ] }),
70452
+ /* @__PURE__ */ jsx("div", { className: "absolute left-6 top-full w-0 h-0 border-l-[6px] border-r-[6px] border-t-[6px] border-transparent border-t-white", style: { filter: "drop-shadow(0 1px 1px rgba(0,0,0,0.05))" } })
70453
+ ] })
70454
+ ] }),
70455
+ /* @__PURE__ */ jsx(ImprovementRecommendationSignals_default, { recommendation: rec })
70145
70456
  ] })
70146
70457
  ] }),
70147
70458
  /* @__PURE__ */ jsx("div", { className: "w-full lg:w-5/12 bg-gray-50 rounded-lg p-4 border border-gray-100 flex-shrink-0", children: Array.isArray(rec.evidence) && rec.evidence.length > 0 ? /* @__PURE__ */ jsx(
@@ -70161,8 +70472,8 @@ var ImprovementCenterView = () => {
70161
70472
  /* @__PURE__ */ jsxs("div", { className: "text-center py-16 bg-white rounded-xl border border-gray-200 shadow-sm", children: [
70162
70473
  /* @__PURE__ */ jsx("div", { className: "mx-auto flex items-center justify-center w-16 h-16 rounded-full bg-green-50 mb-4", children: /* @__PURE__ */ jsx(CheckCircleIcon, { className: "w-8 h-8 text-green-500" }) }),
70163
70474
  /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "No tickets found" }),
70164
- /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-gray-500 max-w-md mx-auto", children: selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" ? "Try adjusting your filters to see more results." : "All monitored long-term patterns were evaluated and remained within limits. This is a success state!" }),
70165
- (selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all") && /* @__PURE__ */ jsx(
70475
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-gray-500 max-w-md mx-auto", children: selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedSortBy !== "all" ? "Try adjusting your filters to see more results." : "All monitored long-term patterns were evaluated and remained within limits. This is a success state!" }),
70476
+ (selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedSortBy !== "all") && /* @__PURE__ */ jsx(
70166
70477
  "button",
70167
70478
  {
70168
70479
  onClick: clearFilters,
@@ -72236,7 +72547,7 @@ var EMPTY_OVERVIEW = {
72236
72547
  },
72237
72548
  summary: {
72238
72549
  plant_efficiency: { current: null, previous: null, delta_pp: null },
72239
- avg_idle_per_workstation: { current_seconds: null, previous_seconds: null, delta_seconds: null }
72550
+ avg_idle_per_workstation: { current_seconds: null, previous_seconds: null, delta_seconds: null, top_contributors: [] }
72240
72551
  },
72241
72552
  poorest_lines: { output: [], uptime: [] },
72242
72553
  trend: { shift_mode: "all", points: [] },
@@ -72262,15 +72573,6 @@ var toNumber3 = (value) => {
72262
72573
  return null;
72263
72574
  };
72264
72575
  var roundOne = (value) => Math.round(value * 10) / 10;
72265
- var getLastSevenDayRange = (timezone) => {
72266
- const todayKey = formatInTimeZone(/* @__PURE__ */ new Date(), timezone || "UTC", "yyyy-MM-dd");
72267
- const endDate = parseISO(`${todayKey}T00:00:00`);
72268
- const startDate = subDays(endDate, 6);
72269
- return {
72270
- startKey: format(startDate, "yyyy-MM-dd"),
72271
- endKey: format(endDate, "yyyy-MM-dd")
72272
- };
72273
- };
72274
72576
  var formatIdleDuration = (seconds) => {
72275
72577
  if (seconds === null || seconds === void 0 || !Number.isFinite(seconds)) {
72276
72578
  return "--";
@@ -72285,23 +72587,11 @@ var formatComparisonWindow = (dayCount) => {
72285
72587
  if (!dayCount || !Number.isFinite(dayCount)) return "previous range";
72286
72588
  return `previous ${dayCount} ${dayCount === 1 ? "day" : "days"}`;
72287
72589
  };
72288
- var shuffle = (items) => {
72289
- const next = [...items];
72290
- for (let i = next.length - 1; i > 0; i -= 1) {
72291
- const swapIndex = Math.floor(Math.random() * (i + 1));
72292
- [next[i], next[swapIndex]] = [next[swapIndex], next[i]];
72293
- }
72294
- return next;
72295
- };
72296
72590
  var buildImprovementMetric = (recommendation) => {
72591
+ const { pcsGain } = getPositiveImprovementGain(recommendation);
72297
72592
  const metrics2 = recommendation.metrics || {};
72298
- const efficiencyGain = toNumber3(metrics2.efficiency_gain_pct);
72299
- if (efficiencyGain !== null) {
72300
- return `+${roundOne(efficiencyGain)}% Efficiency`;
72301
- }
72302
- const outputGain = toNumber3(metrics2.output_gain);
72303
- if (outputGain !== null) {
72304
- return `+${Math.round(outputGain)} Units`;
72593
+ if (pcsGain !== null) {
72594
+ return formatImprovementPieceGain(pcsGain);
72305
72595
  }
72306
72596
  const idleMinutes = toNumber3(metrics2.idle_minutes);
72307
72597
  if (idleMinutes !== null) {
@@ -72313,14 +72603,6 @@ var buildImprovementMetric = (recommendation) => {
72313
72603
  }
72314
72604
  return "Review Issue";
72315
72605
  };
72316
- var buildImprovementImpact = (recommendation) => {
72317
- if (recommendation.issue_severity !== void 0 && recommendation.issue_severity !== null) {
72318
- if (recommendation.issue_severity >= 3) return "High";
72319
- if (recommendation.issue_severity >= 2) return "Medium";
72320
- return "Low";
72321
- }
72322
- return "Medium";
72323
- };
72324
72606
  var buildDeltaBadge = (delta, options) => {
72325
72607
  if (delta === null || delta === void 0 || !Number.isFinite(delta)) {
72326
72608
  return {
@@ -72378,12 +72660,15 @@ var OverviewIdleBreakdownSkeleton = () => /* @__PURE__ */ jsxs("div", { classNam
72378
72660
  /* @__PURE__ */ jsx("div", { className: "h-3 bg-slate-200 rounded w-20" })
72379
72661
  ] }, i)) })
72380
72662
  ] });
72381
- var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className: "space-y-4 py-3", children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
72382
- /* @__PURE__ */ jsx(SectionPulse, { className: "h-4 w-4 rounded-full" }),
72383
- /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
72384
- /* @__PURE__ */ jsx(SectionPulse, { className: "h-3 w-40" }),
72385
- /* @__PURE__ */ jsx(SectionPulse, { className: "h-2.5 w-24" })
72386
- ] })
72663
+ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className: "space-y-4 py-3", children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4", children: [
72664
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0 pr-4", children: [
72665
+ /* @__PURE__ */ jsx(SectionPulse, { className: "h-5 w-10 rounded-full flex-shrink-0" }),
72666
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2 min-w-0", children: [
72667
+ /* @__PURE__ */ jsx(SectionPulse, { className: "h-3 w-40" }),
72668
+ /* @__PURE__ */ jsx(SectionPulse, { className: "h-2.5 w-24" })
72669
+ ] })
72670
+ ] }),
72671
+ /* @__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" }) })
72387
72672
  ] }, index)) });
72388
72673
  var PlantHeadView = () => {
72389
72674
  const supabase = useSupabase();
@@ -72393,7 +72678,7 @@ var PlantHeadView = () => {
72393
72678
  const { accessibleLineIds } = useUserLineAccess();
72394
72679
  const mobileMenuContext = useMobileMenu();
72395
72680
  useHideMobileHeader(!!mobileMenuContext);
72396
- const [dateRange, setDateRange] = React141__default.useState(() => getLastSevenDayRange("UTC"));
72681
+ const [dateRange, setDateRange] = React141__default.useState(() => getCurrentWeekToDateRange(appTimezone));
72397
72682
  const [trendMode, setTrendMode] = React141__default.useState("all");
72398
72683
  const [poorestLineMode, setPoorestLineMode] = React141__default.useState("output");
72399
72684
  const [overview, setOverview] = React141__default.useState(EMPTY_OVERVIEW);
@@ -72407,9 +72692,12 @@ var PlantHeadView = () => {
72407
72692
  const [improvements, setImprovements] = React141__default.useState([]);
72408
72693
  const [isImprovementsLoading, setIsImprovementsLoading] = React141__default.useState(false);
72409
72694
  const [isFilterOpen, setIsFilterOpen] = React141__default.useState(false);
72695
+ const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React141__default.useState(false);
72696
+ const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React141__default.useState(false);
72410
72697
  const filterRef = React141__default.useRef(null);
72411
72698
  const filterButtonRef = React141__default.useRef(null);
72412
72699
  const mobileFilterButtonRef = React141__default.useRef(null);
72700
+ const idleContributorsRef = React141__default.useRef(null);
72413
72701
  React141__default.useEffect(() => {
72414
72702
  trackCorePageView("Operations Overview");
72415
72703
  }, []);
@@ -72450,11 +72738,11 @@ var PlantHeadView = () => {
72450
72738
  document.removeEventListener("mousedown", handleClickOutside);
72451
72739
  };
72452
72740
  }, []);
72453
- const hasInitializedRangeRef = React141__default.useRef(false);
72741
+ const initializedTimezoneRef = React141__default.useRef(appTimezone);
72454
72742
  React141__default.useEffect(() => {
72455
- if (hasInitializedRangeRef.current) return;
72456
- setDateRange(getLastSevenDayRange(appTimezone));
72457
- hasInitializedRangeRef.current = true;
72743
+ if (initializedTimezoneRef.current === appTimezone) return;
72744
+ setDateRange(getCurrentWeekToDateRange(appTimezone));
72745
+ initializedTimezoneRef.current = appTimezone;
72458
72746
  }, [appTimezone]);
72459
72747
  const companyId = entityConfig.companyId;
72460
72748
  const scopedLineIds = React141__default.useMemo(
@@ -72465,6 +72753,10 @@ var PlantHeadView = () => {
72465
72753
  () => scopedLineIds.slice().sort().join(","),
72466
72754
  [scopedLineIds]
72467
72755
  );
72756
+ React141__default.useEffect(() => {
72757
+ setIsIdleContributorsOpen(false);
72758
+ setIsIdleContributorsPinned(false);
72759
+ }, [companyId, dateRange.endKey, dateRange.startKey, lineIdsKey, trendMode]);
72468
72760
  const { supervisorsByLineId } = useSupervisorsByLineIds(scopedLineIds, {
72469
72761
  enabled: !!companyId && scopedLineIds.length > 0,
72470
72762
  companyId,
@@ -72662,11 +72954,16 @@ var PlantHeadView = () => {
72662
72954
  const scopedRecommendations = (response.recommendations || []).filter((recommendation) => {
72663
72955
  return !recommendation.line_id || allowedLineIds.has(recommendation.line_id);
72664
72956
  });
72665
- const nextImprovements = shuffle(scopedRecommendations).slice(0, 3).map((recommendation) => ({
72666
- id: recommendation.id,
72957
+ const nextImprovements = [...scopedRecommendations].sort(compareImprovementRecommendationPriority).slice(0, 3).map((recommendation) => ({
72958
+ id: recommendation.issue_id || recommendation.id,
72959
+ issueId: recommendation.issue_id || recommendation.id,
72960
+ issueNumber: recommendation.issue_number,
72667
72961
  title: recommendation.title?.trim() || "Untitled issue",
72668
- impact: buildImprovementImpact(recommendation),
72669
- metric: buildImprovementMetric(recommendation)
72962
+ metric: buildImprovementMetric(recommendation),
72963
+ location: recommendation.location,
72964
+ line: recommendation.line,
72965
+ lineId: recommendation.line_id,
72966
+ workspaceId: recommendation.workspace_id
72670
72967
  }));
72671
72968
  setImprovements(nextImprovements);
72672
72969
  };
@@ -72712,7 +73009,99 @@ var PlantHeadView = () => {
72712
73009
  comparisonLabel
72713
73010
  });
72714
73011
  }, [comparisonLabel, overview.summary?.avg_idle_per_workstation?.delta_seconds]);
73012
+ const canInspectIdleContributors = React141__default.useMemo(() => {
73013
+ return !isSnapshotLoading && overview.summary?.avg_idle_per_workstation?.current_seconds !== null && overview.summary?.avg_idle_per_workstation?.current_seconds !== void 0;
73014
+ }, [isSnapshotLoading, overview.summary?.avg_idle_per_workstation?.current_seconds]);
73015
+ const idleTopContributors = React141__default.useMemo(() => {
73016
+ return (overview.summary?.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
73017
+ workspaceId: item.workspace_id || "",
73018
+ workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
73019
+ lineId: item.line_id || "",
73020
+ lineName: item.line_name?.trim() || "Unknown Line",
73021
+ avgIdleSeconds: toNumber3(item.avg_idle_seconds)
73022
+ })).slice(0, 5);
73023
+ }, [overview.summary?.avg_idle_per_workstation?.top_contributors]);
73024
+ const showIdleContributorLineNames = React141__default.useMemo(() => {
73025
+ return (overview.scope?.line_count ?? 0) > 1;
73026
+ }, [overview.scope?.line_count]);
73027
+ const closeIdleContributors = React141__default.useCallback(() => {
73028
+ setIsIdleContributorsOpen(false);
73029
+ setIsIdleContributorsPinned(false);
73030
+ }, []);
73031
+ const handleIdleContributorsToggle = React141__default.useCallback(() => {
73032
+ if (!canInspectIdleContributors) return;
73033
+ setIsIdleContributorsPinned((prev) => {
73034
+ const next = !prev;
73035
+ setIsIdleContributorsOpen(next);
73036
+ return next;
73037
+ });
73038
+ }, [canInspectIdleContributors]);
73039
+ const handleIdleContributorsKeyDown = React141__default.useCallback((event) => {
73040
+ if (!canInspectIdleContributors) return;
73041
+ if (event.key === "Enter" || event.key === " ") {
73042
+ event.preventDefault();
73043
+ handleIdleContributorsToggle();
73044
+ return;
73045
+ }
73046
+ if (event.key === "Escape") {
73047
+ event.preventDefault();
73048
+ closeIdleContributors();
73049
+ }
73050
+ }, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
73051
+ React141__default.useEffect(() => {
73052
+ if (!isIdleContributorsOpen) return void 0;
73053
+ const handleClickOutside = (event) => {
73054
+ if (!isIdleContributorsPinned) return;
73055
+ if (idleContributorsRef.current && !idleContributorsRef.current.contains(event.target)) {
73056
+ closeIdleContributors();
73057
+ }
73058
+ };
73059
+ const handleEscape = (event) => {
73060
+ if (event.key === "Escape") {
73061
+ closeIdleContributors();
73062
+ }
73063
+ };
73064
+ document.addEventListener("mousedown", handleClickOutside);
73065
+ document.addEventListener("touchstart", handleClickOutside);
73066
+ document.addEventListener("keydown", handleEscape);
73067
+ return () => {
73068
+ document.removeEventListener("mousedown", handleClickOutside);
73069
+ document.removeEventListener("touchstart", handleClickOutside);
73070
+ document.removeEventListener("keydown", handleEscape);
73071
+ };
73072
+ }, [closeIdleContributors, isIdleContributorsOpen, isIdleContributorsPinned]);
73073
+ const currentWeekRange = React141__default.useMemo(
73074
+ () => getCurrentWeekToDateRange(appTimezone),
73075
+ [appTimezone]
73076
+ );
73077
+ const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
72715
73078
  const trendData = React141__default.useMemo(() => {
73079
+ const pointsByDate = new Map(
73080
+ (overview.trend?.points || []).flatMap((point) => {
73081
+ if (!point.date) return [];
73082
+ const pointDate = parseDateKeyToDate(point.date);
73083
+ return [[point.date, {
73084
+ name: format(pointDate, "MMM d"),
73085
+ dayOfWeek: format(pointDate, "EEEE"),
73086
+ efficiency: (() => {
73087
+ const value = toNumber3(point.avg_efficiency);
73088
+ return value === null ? void 0 : value;
73089
+ })()
73090
+ }]];
73091
+ })
73092
+ );
73093
+ if (isCurrentWeekToDateRange) {
73094
+ const weekStart = parseDateKeyToDate(currentWeekRange.startKey);
73095
+ return Array.from({ length: 7 }, (_, index) => {
73096
+ const date = addDays(weekStart, index);
73097
+ const dateKey = format(date, "yyyy-MM-dd");
73098
+ return pointsByDate.get(dateKey) || {
73099
+ name: format(date, "MMM d"),
73100
+ dayOfWeek: format(date, "EEEE"),
73101
+ efficiency: void 0
73102
+ };
73103
+ });
73104
+ }
72716
73105
  return (overview.trend?.points || []).map((point) => {
72717
73106
  const pointDate = point.date ? parseDateKeyToDate(point.date) : null;
72718
73107
  return {
@@ -72724,7 +73113,7 @@ var PlantHeadView = () => {
72724
73113
  })()
72725
73114
  };
72726
73115
  });
72727
- }, [overview.trend?.points]);
73116
+ }, [currentWeekRange.startKey, isCurrentWeekToDateRange, overview.trend?.points]);
72728
73117
  const trendPlayKey = React141__default.useMemo(() => {
72729
73118
  return `${trendViewOpenNonce}:${trendFetchNonce}`;
72730
73119
  }, [trendFetchNonce, trendViewOpenNonce]);
@@ -72771,6 +73160,33 @@ var PlantHeadView = () => {
72771
73160
  if (!dayOfWeek || typeof label !== "string") return label;
72772
73161
  return `${label} (${dayOfWeek})`;
72773
73162
  }, []);
73163
+ const displayImprovements = React141__default.useMemo(() => {
73164
+ return improvements.map((item) => {
73165
+ const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
73166
+ return {
73167
+ ...item,
73168
+ ticketLabel: formatImprovementTicketNumber(item.issueNumber),
73169
+ ...getImprovementDisplayMetadata({
73170
+ location: item.location,
73171
+ line: item.line,
73172
+ workspaceId: item.workspaceId,
73173
+ supervisors
73174
+ })
73175
+ };
73176
+ });
73177
+ }, [improvements, supervisorsByLineId]);
73178
+ const mobileSubtitle = React141__default.useMemo(() => {
73179
+ if (isCurrentWeekToDateRange) {
73180
+ return `Week of ${format(parseDateKeyToDate(dateRange.startKey), "do MMM")}`;
73181
+ }
73182
+ return `${format(parseDateKeyToDate(dateRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(dateRange.endKey), "do MMM, yyyy")}`;
73183
+ }, [dateRange.endKey, dateRange.startKey, isCurrentWeekToDateRange]);
73184
+ const desktopSubtitle = React141__default.useMemo(() => {
73185
+ if (isCurrentWeekToDateRange) {
73186
+ return `Week of ${format(parseDateKeyToDate(dateRange.startKey), "do MMMM, yyyy")}`;
73187
+ }
73188
+ return `${format(parseDateKeyToDate(dateRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(dateRange.endKey), "do MMMM, yyyy")}`;
73189
+ }, [dateRange.endKey, dateRange.startKey, isCurrentWeekToDateRange]);
72774
73190
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-h-screen bg-slate-50 w-full font-sans", children: [
72775
73191
  /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3 relative", children: [
72776
73192
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
@@ -72783,11 +73199,7 @@ var PlantHeadView = () => {
72783
73199
  ) : /* @__PURE__ */ jsx("div", { className: "w-8 flex-shrink-0" }),
72784
73200
  /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center", children: [
72785
73201
  /* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900 text-center px-1 truncate max-w-[200px]", children: "Operations Overview" }),
72786
- /* @__PURE__ */ jsxs("span", { className: "text-[10px] font-medium text-slate-500 text-center mt-0.5", children: [
72787
- format(parseDateKeyToDate(dateRange.startKey), "do MMM"),
72788
- " - ",
72789
- format(parseDateKeyToDate(dateRange.endKey), "do MMM, yyyy")
72790
- ] })
73202
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-slate-500 text-center mt-0.5", children: mobileSubtitle })
72791
73203
  ] }),
72792
73204
  /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 flex items-center gap-1.5", children: [
72793
73205
  /* @__PURE__ */ jsx(
@@ -72819,11 +73231,7 @@ var PlantHeadView = () => {
72819
73231
  /* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center relative min-h-[56px]", children: [
72820
73232
  /* @__PURE__ */ jsxs("div", { className: "absolute left-1/2 -translate-x-1/2 flex flex-col items-center pointer-events-none", children: [
72821
73233
  /* @__PURE__ */ jsx("h1", { className: "text-2xl md:text-3xl lg:text-4xl font-semibold text-gray-900 tracking-tight text-center pointer-events-auto leading-tight mb-0.5", children: "Operations Overview" }),
72822
- /* @__PURE__ */ jsxs("span", { className: "text-xs sm:text-sm font-medium text-slate-500 text-center pointer-events-auto", children: [
72823
- format(parseDateKeyToDate(dateRange.startKey), "do MMMM, yyyy"),
72824
- " - ",
72825
- format(parseDateKeyToDate(dateRange.endKey), "do MMMM, yyyy")
72826
- ] })
73234
+ /* @__PURE__ */ jsx("span", { className: "text-xs sm:text-sm font-medium text-slate-500 text-center pointer-events-auto", children: desktopSubtitle })
72827
73235
  ] }),
72828
73236
  /* @__PURE__ */ jsxs("div", { className: "absolute right-0 flex items-center gap-3", children: [
72829
73237
  /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx(
@@ -72911,16 +73319,92 @@ var PlantHeadView = () => {
72911
73319
  /* @__PURE__ */ jsxs(
72912
73320
  "div",
72913
73321
  {
72914
- className: "bg-white rounded-xl shadow-sm border border-slate-100 p-4 md:p-5 flex flex-col justify-center min-h-[100px] text-left",
73322
+ ref: idleContributorsRef,
73323
+ "data-testid": "idle-kpi-card-region",
73324
+ className: "relative",
73325
+ onMouseEnter: () => {
73326
+ if (canInspectIdleContributors) {
73327
+ setIsIdleContributorsOpen(true);
73328
+ }
73329
+ },
73330
+ onMouseLeave: () => {
73331
+ if (!isIdleContributorsPinned) {
73332
+ setIsIdleContributorsOpen(false);
73333
+ }
73334
+ },
73335
+ onFocus: () => {
73336
+ if (canInspectIdleContributors) {
73337
+ setIsIdleContributorsOpen(true);
73338
+ }
73339
+ },
73340
+ onBlur: (event) => {
73341
+ if (isIdleContributorsPinned) return;
73342
+ const nextTarget = event.relatedTarget;
73343
+ if (nextTarget && idleContributorsRef.current?.contains(nextTarget)) return;
73344
+ setIsIdleContributorsOpen(false);
73345
+ },
72915
73346
  children: [
72916
- /* @__PURE__ */ jsx("div", { className: "flex justify-between items-center mb-1", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-700", children: "Idle Time per Workstation" }) }),
72917
- isSnapshotLoading ? /* @__PURE__ */ jsx(OverviewMetricCardSkeleton, {}) : overview.summary?.avg_idle_per_workstation?.current_seconds !== null && overview.summary?.avg_idle_per_workstation?.current_seconds !== void 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:gap-3 mt-1", children: [
72918
- /* @__PURE__ */ jsx("span", { className: "text-2xl sm:text-3xl font-bold text-slate-800 tracking-tight", children: formatIdleDuration(overview.summary.avg_idle_per_workstation.current_seconds) }),
72919
- /* @__PURE__ */ jsxs("div", { className: `flex items-center gap-1 px-2.5 py-1 rounded-full ${idleBadge.className}`, children: [
72920
- idleBadge.icon === "up" ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : idleBadge.icon === "down" ? /* @__PURE__ */ jsx(ArrowDown, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : null,
72921
- /* @__PURE__ */ jsx("span", { className: "text-xs sm:text-sm font-medium", children: idleBadge.text })
72922
- ] })
72923
- ] }) : /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-slate-400", children: "No idle time data available" })
73347
+ /* @__PURE__ */ jsxs(
73348
+ "div",
73349
+ {
73350
+ "data-testid": "idle-kpi-card",
73351
+ role: canInspectIdleContributors ? "button" : void 0,
73352
+ tabIndex: canInspectIdleContributors ? 0 : -1,
73353
+ "aria-controls": canInspectIdleContributors ? "idle-kpi-popover" : void 0,
73354
+ "aria-expanded": canInspectIdleContributors ? isIdleContributorsOpen : void 0,
73355
+ className: `bg-white rounded-xl border p-4 md:p-5 flex flex-col justify-center min-h-[100px] text-left transition-all ${canInspectIdleContributors ? "cursor-pointer hover:shadow-md focus:outline-none focus:ring-2 focus:ring-indigo-200" : ""} ${isIdleContributorsOpen ? "shadow-md border-indigo-100" : "shadow-sm border-slate-100"}`,
73356
+ onClick: handleIdleContributorsToggle,
73357
+ onKeyDown: handleIdleContributorsKeyDown,
73358
+ children: [
73359
+ /* @__PURE__ */ jsx("div", { className: "mb-1", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-700", children: "Idle Time per Workstation" }) }),
73360
+ isSnapshotLoading ? /* @__PURE__ */ jsx(OverviewMetricCardSkeleton, {}) : overview.summary?.avg_idle_per_workstation?.current_seconds !== null && overview.summary?.avg_idle_per_workstation?.current_seconds !== void 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:gap-3 mt-1", children: [
73361
+ /* @__PURE__ */ jsx("span", { className: "text-2xl sm:text-3xl font-bold text-slate-800 tracking-tight", children: formatIdleDuration(overview.summary.avg_idle_per_workstation.current_seconds) }),
73362
+ /* @__PURE__ */ jsxs("div", { className: `flex items-center gap-1 px-2.5 py-1 rounded-full ${idleBadge.className}`, children: [
73363
+ idleBadge.icon === "up" ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : idleBadge.icon === "down" ? /* @__PURE__ */ jsx(ArrowDown, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : null,
73364
+ /* @__PURE__ */ jsx("span", { className: "text-xs sm:text-sm font-medium", children: idleBadge.text })
73365
+ ] })
73366
+ ] }) : /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-slate-400", children: "No idle time data available" })
73367
+ ]
73368
+ }
73369
+ ),
73370
+ canInspectIdleContributors && isIdleContributorsOpen ? /* @__PURE__ */ jsxs(
73371
+ "div",
73372
+ {
73373
+ id: "idle-kpi-popover",
73374
+ "data-testid": "idle-kpi-popover",
73375
+ className: "absolute left-0 right-0 top-full z-20 mt-2 bg-white p-4 border border-gray-100 shadow-xl rounded-xl sm:left-auto sm:right-0 sm:w-[320px] min-w-[280px]",
73376
+ children: [
73377
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pb-3 mb-3 border-b border-slate-100", children: [
73378
+ /* @__PURE__ */ jsx("div", { className: "w-2.5 h-2.5 rounded-full flex-shrink-0 bg-red-500" }),
73379
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-slate-800 text-[15px]", children: "Idle Time per Workstation" })
73380
+ ] }),
73381
+ /* @__PURE__ */ jsxs("div", { children: [
73382
+ /* @__PURE__ */ jsx("p", { className: "text-[10px] font-bold uppercase tracking-wider text-slate-400 mb-3", children: "TOP CONTRIBUTORS" }),
73383
+ idleTopContributors.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-2.5", children: idleTopContributors.map((contributor, index) => /* @__PURE__ */ jsxs(
73384
+ "div",
73385
+ {
73386
+ className: "flex items-start justify-between gap-3",
73387
+ children: [
73388
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
73389
+ /* @__PURE__ */ jsx(
73390
+ "div",
73391
+ {
73392
+ className: "text-slate-600 text-[13px] truncate",
73393
+ title: contributor.workspaceName,
73394
+ children: contributor.workspaceName
73395
+ }
73396
+ ),
73397
+ showIdleContributorLineNames && contributor.lineName ? /* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium text-slate-400 truncate", title: contributor.lineName, children: contributor.lineName }) : null
73398
+ ] }),
73399
+ /* @__PURE__ */ jsx("div", { className: "text-slate-500 text-[13px] text-right whitespace-nowrap", children: formatIdleDuration(contributor.avgIdleSeconds) })
73400
+ ]
73401
+ },
73402
+ `${contributor.workspaceId || contributor.workspaceName}-${index}`
73403
+ )) }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-dashed border-slate-200 bg-slate-50 px-3 py-2 text-xs text-slate-500", children: "No workstation idle averages available for this range." })
73404
+ ] })
73405
+ ]
73406
+ }
73407
+ ) : null
72924
73408
  ]
72925
73409
  }
72926
73410
  )
@@ -73074,24 +73558,48 @@ var PlantHeadView = () => {
73074
73558
  }
73075
73559
  )
73076
73560
  ] }),
73077
- /* @__PURE__ */ jsx("div", { className: "flex-1 p-0 flex flex-col px-5 py-2 justify-start overflow-auto", children: isImprovementsLoading ? /* @__PURE__ */ jsx(OverviewImprovementsSkeleton, {}) : improvements.length > 0 ? improvements.map((item) => /* @__PURE__ */ jsx(
73561
+ /* @__PURE__ */ jsx("div", { className: "flex-1 p-0 flex flex-col px-5 py-2 justify-start overflow-auto", children: isImprovementsLoading ? /* @__PURE__ */ jsx(OverviewImprovementsSkeleton, {}) : displayImprovements.length > 0 ? displayImprovements.map((item) => /* @__PURE__ */ jsxs(
73078
73562
  "div",
73079
73563
  {
73564
+ "data-testid": `plant-head-improvement-${item.issueId}`,
73080
73565
  onClick: () => {
73081
- trackCoreEvent("Operations Overview Improvement Clicked", { issue_id: item.id, title: item.title });
73082
- navigate("/improvement-center");
73566
+ trackCoreEvent("Operations Overview Improvement Clicked", {
73567
+ issue_id: item.issueId,
73568
+ issue_number: item.issueNumber,
73569
+ title: item.title
73570
+ });
73571
+ const params = new URLSearchParams({
73572
+ focusIssueId: item.issueId
73573
+ });
73574
+ navigate(`/improvement-center?${params.toString()}`);
73083
73575
  },
73084
73576
  className: "flex items-center justify-between py-3 border-b border-slate-50 last:border-0 group cursor-pointer",
73085
- children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0 pr-4", children: [
73086
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx(ArrowUpRight, { className: "w-4 h-4 text-slate-400 group-hover:text-indigo-500 transition-colors" }) }),
73087
- /* @__PURE__ */ jsxs("div", { children: [
73088
- /* @__PURE__ */ jsx("h4", { className: "text-[13px] font-semibold text-slate-800 truncate transition-colors group-hover:text-indigo-600 mb-0.5", children: item.title }),
73089
- /* @__PURE__ */ jsxs("p", { className: "text-[10px] font-medium text-slate-400", children: [
73090
- "Impact: ",
73091
- /* @__PURE__ */ jsx("span", { className: "text-slate-500 font-semibold", children: item.impact })
73577
+ children: [
73578
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0 pr-4", children: [
73579
+ item.ticketLabel && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full border border-indigo-100 bg-indigo-50 px-2 py-0.5 text-[10px] font-semibold text-indigo-600", children: item.ticketLabel }) }),
73580
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
73581
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 min-w-0 mb-0.5", children: /* @__PURE__ */ jsx("h4", { className: "text-[13px] font-semibold text-slate-800 truncate transition-colors group-hover:text-indigo-600", children: item.title }) }),
73582
+ /* @__PURE__ */ jsx(
73583
+ "p",
73584
+ {
73585
+ className: "text-[10px] font-medium text-slate-400 truncate",
73586
+ title: item.metadataLabel,
73587
+ children: item.metadataLabel
73588
+ }
73589
+ )
73092
73590
  ] })
73093
- ] })
73094
- ] })
73591
+ ] }),
73592
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-end flex-shrink-0 ml-4", children: /* @__PURE__ */ jsxs(
73593
+ "span",
73594
+ {
73595
+ className: `inline-flex items-center gap-1 rounded-full border px-2.5 py-0.5 text-[11px] ${item.metric.includes("pcs / day") || item.metric.includes("gain") ? "border-emerald-100 bg-emerald-50 text-emerald-700" : item.metric.includes("Idle") ? "border-amber-100 bg-amber-50 text-amber-700" : "border-slate-100 bg-slate-50 text-slate-600"}`,
73596
+ children: [
73597
+ (item.metric.includes("pcs / day") || item.metric.includes("gain")) && /* @__PURE__ */ jsx(TrendingUp, { className: "h-3 w-3" }),
73598
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: item.metric })
73599
+ ]
73600
+ }
73601
+ ) })
73602
+ ]
73095
73603
  },
73096
73604
  item.id
73097
73605
  )) : /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-slate-400", children: "No open improvement issues" }) })
@@ -73578,4 +74086,4 @@ var streamProxyConfig = {
73578
74086
  }
73579
74087
  };
73580
74088
 
73581
- export { ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getReasonColor, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFullMonthRange, isLegacyConfiguration, isPrefetchError, isSafari, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeDateKeyRange, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
74089
+ export { ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getReasonColor, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFullMonthRange, isLegacyConfiguration, isPrefetchError, isSafari, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeDateKeyRange, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };