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