@optifye/dashboard-core 6.12.48 → 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 +3977 -3329
- package/dist/index.mjs +1618 -970
- 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
|
-
|
|
42081
|
-
|
|
42082
|
-
|
|
42083
|
-
|
|
42084
|
-
|
|
42085
|
-
|
|
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
|
+
}
|
|
42109
|
+
return {
|
|
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;
|
|
42086
42126
|
return {
|
|
42087
|
-
|
|
42088
|
-
|
|
42089
|
-
|
|
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);
|
|
@@ -68861,15 +69012,6 @@ function HomeView({
|
|
|
68861
69012
|
selected_line_count: nextSelectedLineIds.length,
|
|
68862
69013
|
highlighted_workspace_count: option.id === "worst_workstations" ? worstPerformanceWorkspaceIds.length : 0
|
|
68863
69014
|
});
|
|
68864
|
-
trackCoreEvent("Dashboard Filter Selected", {
|
|
68865
|
-
filter_type: "Display Mode",
|
|
68866
|
-
filter_value: option.label,
|
|
68867
|
-
filter_id: option.id,
|
|
68868
|
-
previous_filter_value: getHomeDisplayModeLabel(displayMode),
|
|
68869
|
-
...selectedViewProperties,
|
|
68870
|
-
selected_line_ids: nextSelectedLineIds,
|
|
68871
|
-
selected_line_count: nextSelectedLineIds.length
|
|
68872
|
-
});
|
|
68873
69015
|
trackCoreEvent(`Display View Selected: ${option.label}`, {
|
|
68874
69016
|
mode_id: option.id,
|
|
68875
69017
|
mode_label: option.label,
|
|
@@ -69090,7 +69232,7 @@ function HomeView({
|
|
|
69090
69232
|
animate: { opacity: 1, scale: 1 },
|
|
69091
69233
|
transition: { duration: 0.3 },
|
|
69092
69234
|
className: "h-full",
|
|
69093
|
-
children:
|
|
69235
|
+
children: React125__default.createElement(WorkspaceGrid, {
|
|
69094
69236
|
workspaces: workspaceMetricsWithBreakState,
|
|
69095
69237
|
blueComparisonWorkspaces: currentBlueComparisonWorkspaceMetrics || workspaceMetricsWithBreakState,
|
|
69096
69238
|
worstPerformanceWorkspaceIds: activeWorstPerformanceWorkspaceIds,
|
|
@@ -69126,7 +69268,7 @@ function HomeView({
|
|
|
69126
69268
|
animate: { opacity: 1, scale: 1 },
|
|
69127
69269
|
transition: { duration: 0.3 },
|
|
69128
69270
|
className: "h-full",
|
|
69129
|
-
children:
|
|
69271
|
+
children: React125__default.createElement(WorkspaceGrid, {
|
|
69130
69272
|
workspaces: [],
|
|
69131
69273
|
// Show empty grid while loading
|
|
69132
69274
|
blueComparisonWorkspaces: [],
|
|
@@ -69176,7 +69318,7 @@ function HomeView({
|
|
|
69176
69318
|
contentVariant: "plain"
|
|
69177
69319
|
}
|
|
69178
69320
|
),
|
|
69179
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(
|
|
69321
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(React125__default.Fragment, { children: [
|
|
69180
69322
|
/* @__PURE__ */ jsx(
|
|
69181
69323
|
motion.div,
|
|
69182
69324
|
{
|
|
@@ -69255,7 +69397,7 @@ function HomeView({
|
|
|
69255
69397
|
"all-green-center-toast"
|
|
69256
69398
|
)
|
|
69257
69399
|
] }, "all-green-celebration") : null }),
|
|
69258
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(
|
|
69400
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(React125__default.Fragment, { children: [
|
|
69259
69401
|
/* @__PURE__ */ jsx(
|
|
69260
69402
|
motion.div,
|
|
69261
69403
|
{
|
|
@@ -69349,7 +69491,7 @@ function HomeView({
|
|
|
69349
69491
|
}
|
|
69350
69492
|
);
|
|
69351
69493
|
}
|
|
69352
|
-
var AuthenticatedHomeView = withAuth(
|
|
69494
|
+
var AuthenticatedHomeView = withAuth(React125__default.memo(HomeView));
|
|
69353
69495
|
var HomeView_default = HomeView;
|
|
69354
69496
|
function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
69355
69497
|
const {
|
|
@@ -72613,6 +72755,12 @@ var KPIDetailView_default = KPIDetailViewWithDisplayNames;
|
|
|
72613
72755
|
var isNonEmptyString2 = (value) => typeof value === "string" && value.trim().length > 0;
|
|
72614
72756
|
var KPI_FACTORY_QUERY_PARAM = "factory_id";
|
|
72615
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);
|
|
72616
72764
|
var getSingleQueryValue = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
72617
72765
|
var resolveCompanyId2 = (...candidates) => candidates.find(isNonEmptyString2);
|
|
72618
72766
|
var parseTimeToMinutes4 = (value) => {
|
|
@@ -72770,19 +72918,36 @@ var LinesLeaderboard = ({
|
|
|
72770
72918
|
timezone: _timezone,
|
|
72771
72919
|
isHistoricalDaily
|
|
72772
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
|
+
);
|
|
72773
72938
|
const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
|
|
72774
|
-
const assignedLineIdSet =
|
|
72939
|
+
const assignedLineIdSet = React125__default.useMemo(
|
|
72775
72940
|
() => new Set(assignedLineIds || []),
|
|
72776
72941
|
[assignedLineIds]
|
|
72777
72942
|
);
|
|
72778
|
-
const canClickLine =
|
|
72943
|
+
const canClickLine = React125__default.useCallback(
|
|
72779
72944
|
(lineId) => {
|
|
72780
72945
|
if (!assignedLineIds) return true;
|
|
72781
72946
|
return assignedLineIdSet.has(lineId);
|
|
72782
72947
|
},
|
|
72783
72948
|
[assignedLineIds, assignedLineIdSet]
|
|
72784
72949
|
);
|
|
72785
|
-
const handleTimeRangeChange =
|
|
72950
|
+
const handleTimeRangeChange = React125__default.useCallback((newRange) => {
|
|
72786
72951
|
if (newRange === timeRange) return;
|
|
72787
72952
|
trackCoreEvent("Leaderboard Time Range Changed", {
|
|
72788
72953
|
from_range: timeRange,
|
|
@@ -72793,11 +72958,11 @@ var LinesLeaderboard = ({
|
|
|
72793
72958
|
});
|
|
72794
72959
|
setTimeRange(newRange);
|
|
72795
72960
|
}, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
|
|
72796
|
-
const canClickLeaderboardRow =
|
|
72961
|
+
const canClickLeaderboardRow = React125__default.useCallback(
|
|
72797
72962
|
(item) => item.rowType === "line" && !!item.line && canClickLine(item.line.id),
|
|
72798
72963
|
[canClickLine]
|
|
72799
72964
|
);
|
|
72800
|
-
const handleLeaderboardLineClick =
|
|
72965
|
+
const handleLeaderboardLineClick = React125__default.useCallback((item, clickSource) => {
|
|
72801
72966
|
if (!canClickLeaderboardRow(item) || !item.line) return;
|
|
72802
72967
|
trackCoreEvent("Leaderboard Line Clicked", {
|
|
72803
72968
|
line_id: item.line.id,
|
|
@@ -72811,8 +72976,8 @@ var LinesLeaderboard = ({
|
|
|
72811
72976
|
});
|
|
72812
72977
|
onLineClick(item.line);
|
|
72813
72978
|
}, [canClickLeaderboardRow, onLineClick, timeRange]);
|
|
72814
|
-
const viewLoadedTrackedRef =
|
|
72815
|
-
const leaderboardData =
|
|
72979
|
+
const viewLoadedTrackedRef = React125__default.useRef(null);
|
|
72980
|
+
const leaderboardData = React125__default.useMemo(() => {
|
|
72816
72981
|
const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
72817
72982
|
const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
|
|
72818
72983
|
const fallbackEfficiencyMap = timeRange === "today" ? dailyFallbackEfficiencyByLineId : void 0;
|
|
@@ -72856,7 +73021,7 @@ var LinesLeaderboard = ({
|
|
|
72856
73021
|
isLoadingToday,
|
|
72857
73022
|
isLoadingMonthly
|
|
72858
73023
|
]);
|
|
72859
|
-
|
|
73024
|
+
React125__default.useEffect(() => {
|
|
72860
73025
|
const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
72861
73026
|
const trackingKey = `${timeRange}-${leaderboardData.length}`;
|
|
72862
73027
|
if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
|
|
@@ -72882,7 +73047,7 @@ var LinesLeaderboard = ({
|
|
|
72882
73047
|
const countdownFormat = timeRange === "monthly" ? "days" : "clock";
|
|
72883
73048
|
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift ended";
|
|
72884
73049
|
const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
|
|
72885
|
-
const handleCountdownFinished =
|
|
73050
|
+
const handleCountdownFinished = React125__default.useCallback(() => {
|
|
72886
73051
|
trackCoreEvent("Leaderboard Countdown Finished", {
|
|
72887
73052
|
countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
|
|
72888
73053
|
time_range: timeRange,
|
|
@@ -72909,7 +73074,7 @@ var LinesLeaderboard = ({
|
|
|
72909
73074
|
return "bg-white border-gray-100";
|
|
72910
73075
|
}
|
|
72911
73076
|
};
|
|
72912
|
-
|
|
73077
|
+
React125__default.useEffect(() => {
|
|
72913
73078
|
const style = document.createElement("style");
|
|
72914
73079
|
style.innerHTML = `
|
|
72915
73080
|
@keyframes float {
|
|
@@ -72975,6 +73140,7 @@ var LinesLeaderboard = ({
|
|
|
72975
73140
|
const isSecond = item.rank === 2;
|
|
72976
73141
|
item.rank === 3;
|
|
72977
73142
|
const isClickable = canClickLeaderboardRow(item);
|
|
73143
|
+
const isOwnSupervisorRow = isCurrentUserRow(item);
|
|
72978
73144
|
return /* @__PURE__ */ jsxs(
|
|
72979
73145
|
"div",
|
|
72980
73146
|
{
|
|
@@ -73011,22 +73177,25 @@ var LinesLeaderboard = ({
|
|
|
73011
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 })
|
|
73012
73178
|
] })
|
|
73013
73179
|
] }),
|
|
73014
|
-
/* @__PURE__ */
|
|
73180
|
+
/* @__PURE__ */ jsxs(
|
|
73015
73181
|
"div",
|
|
73016
73182
|
{
|
|
73017
|
-
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"}`,
|
|
73018
|
-
children:
|
|
73019
|
-
/* @__PURE__ */ jsx("
|
|
73020
|
-
/* @__PURE__ */
|
|
73021
|
-
|
|
73022
|
-
item.
|
|
73023
|
-
"
|
|
73024
|
-
|
|
73025
|
-
|
|
73026
|
-
|
|
73027
|
-
/* @__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
|
+
] })
|
|
73028
73197
|
] })
|
|
73029
|
-
]
|
|
73198
|
+
]
|
|
73030
73199
|
}
|
|
73031
73200
|
)
|
|
73032
73201
|
]
|
|
@@ -73045,11 +73214,12 @@ var LinesLeaderboard = ({
|
|
|
73045
73214
|
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-100", children: leaderboardData.map((item) => {
|
|
73046
73215
|
const isTopThree = item.rank <= 3;
|
|
73047
73216
|
const isClickable = canClickLeaderboardRow(item);
|
|
73217
|
+
const isOwnSupervisorRow = isCurrentUserRow(item);
|
|
73048
73218
|
return /* @__PURE__ */ jsxs(
|
|
73049
73219
|
"tr",
|
|
73050
73220
|
{
|
|
73051
73221
|
onClick: () => handleLeaderboardLineClick(item, isTopThree ? "podium" : "table"),
|
|
73052
|
-
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"}`,
|
|
73053
73223
|
children: [
|
|
73054
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 }) }),
|
|
73055
73225
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
@@ -73074,7 +73244,8 @@ var LinesLeaderboard = ({
|
|
|
73074
73244
|
item.supervisors.length - 3
|
|
73075
73245
|
] })
|
|
73076
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) }) }),
|
|
73077
|
-
/* @__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()
|
|
73078
73249
|
] }) }),
|
|
73079
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: [
|
|
73080
73251
|
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-700", children: item.displayName }),
|
|
@@ -73371,14 +73542,26 @@ var KPIsOverviewView = ({
|
|
|
73371
73542
|
const [activeTab, setActiveTab] = useState("today");
|
|
73372
73543
|
const [timeRange, setTimeRange] = useState("today");
|
|
73373
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");
|
|
73374
73550
|
const [selectedLeaderboardDate, setSelectedLeaderboardDate] = useState("");
|
|
73375
73551
|
const [selectedLeaderboardShiftId, setSelectedLeaderboardShiftId] = useState(0);
|
|
73376
73552
|
const [leaderboardDailyScopeMode, setLeaderboardDailyScopeMode] = useState("live");
|
|
73377
73553
|
const [hasHydratedLeaderboardRouteState, setHasHydratedLeaderboardRouteState] = useState(false);
|
|
73378
73554
|
const [loading, setLoading] = useState(true);
|
|
73379
73555
|
const [isFilterOpen, setIsFilterOpen] = useState(false);
|
|
73556
|
+
const [isViewsOpen, setIsViewsOpen] = useState(false);
|
|
73557
|
+
const [isSortOpen, setIsSortOpen] = useState(false);
|
|
73380
73558
|
const filterRef = useRef(null);
|
|
73381
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([]);
|
|
73382
73565
|
const [error, setError] = useState(null);
|
|
73383
73566
|
const [todayEfficiencyByLineId, setTodayEfficiencyByLineId] = useState(/* @__PURE__ */ new Map());
|
|
73384
73567
|
const [dailyLoading, setDailyLoading] = useState(false);
|
|
@@ -73408,36 +73591,36 @@ var KPIsOverviewView = ({
|
|
|
73408
73591
|
const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
|
|
73409
73592
|
const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
|
|
73410
73593
|
const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
|
|
73411
|
-
const scopedLineIds =
|
|
73594
|
+
const scopedLineIds = React125__default.useMemo(
|
|
73412
73595
|
() => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
|
|
73413
73596
|
[user?.access_scope?.line_ids]
|
|
73414
73597
|
);
|
|
73415
73598
|
const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
|
|
73416
73599
|
const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
|
|
73417
73600
|
const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
|
|
73418
|
-
const resolvedAssignedLineIds =
|
|
73601
|
+
const resolvedAssignedLineIds = React125__default.useMemo(() => {
|
|
73419
73602
|
if (isSuperAdmin) return [];
|
|
73420
73603
|
if (scopedLineIds.length > 0) return scopedLineIds;
|
|
73421
73604
|
if (lineIds && lineIds.length > 0) return lineIds;
|
|
73422
73605
|
if (isStrictLineScopedRole && hasCanonicalScope) return [];
|
|
73423
73606
|
return [];
|
|
73424
73607
|
}, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
|
|
73425
|
-
const assignedLineIdSet =
|
|
73608
|
+
const assignedLineIdSet = React125__default.useMemo(
|
|
73426
73609
|
() => new Set(resolvedAssignedLineIds),
|
|
73427
73610
|
[resolvedAssignedLineIds]
|
|
73428
73611
|
);
|
|
73429
|
-
const loadedLineIds =
|
|
73612
|
+
const loadedLineIds = React125__default.useMemo(
|
|
73430
73613
|
() => lines.map((line) => line.id).filter(Boolean),
|
|
73431
73614
|
[lines]
|
|
73432
73615
|
);
|
|
73433
|
-
const metricsLineIds =
|
|
73616
|
+
const metricsLineIds = React125__default.useMemo(() => {
|
|
73434
73617
|
if (isSuperAdmin) {
|
|
73435
73618
|
return loadedLineIds.length > 0 ? loadedLineIds : lineIds ?? [];
|
|
73436
73619
|
}
|
|
73437
73620
|
return resolvedAssignedLineIds;
|
|
73438
73621
|
}, [isSuperAdmin, loadedLineIds, lineIds, resolvedAssignedLineIds]);
|
|
73439
73622
|
const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
|
|
73440
|
-
const leaderboardLinesForView =
|
|
73623
|
+
const leaderboardLinesForView = React125__default.useMemo(() => {
|
|
73441
73624
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
73442
73625
|
const metadataByLineId = new Map(lines.map((line) => [line.id, line]));
|
|
73443
73626
|
return leaderboardLines.map((line) => {
|
|
@@ -73456,17 +73639,57 @@ var KPIsOverviewView = ({
|
|
|
73456
73639
|
} : line;
|
|
73457
73640
|
}).filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
73458
73641
|
}, [leaderboardLines, lines, viewType]);
|
|
73459
|
-
const linesForView =
|
|
73642
|
+
const linesForView = React125__default.useMemo(() => {
|
|
73460
73643
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
73461
73644
|
return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
73462
73645
|
}, [lines, viewType]);
|
|
73463
|
-
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(() => {
|
|
73464
73687
|
if (activeTab === "leaderboard") {
|
|
73465
73688
|
return leaderboardLines.length > 0 ? leaderboardLines : lines;
|
|
73466
73689
|
}
|
|
73467
73690
|
return lines;
|
|
73468
73691
|
}, [activeTab, leaderboardLines, lines]);
|
|
73469
|
-
const { hasUptime, hasOutput } =
|
|
73692
|
+
const { hasUptime, hasOutput } = React125__default.useMemo(() => {
|
|
73470
73693
|
let uptime = false;
|
|
73471
73694
|
let output = false;
|
|
73472
73695
|
for (const line of relevantLinesForMode) {
|
|
@@ -73491,18 +73714,42 @@ var KPIsOverviewView = ({
|
|
|
73491
73714
|
const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
|
|
73492
73715
|
const currentShiftDate = currentShiftDetails.date;
|
|
73493
73716
|
const currentShiftId = currentShiftDetails.shiftId;
|
|
73494
|
-
const activeFiltersCount =
|
|
73717
|
+
const activeFiltersCount = React125__default.useMemo(() => {
|
|
73495
73718
|
let count = 0;
|
|
73496
|
-
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) {
|
|
73497
73726
|
count++;
|
|
73498
73727
|
}
|
|
73499
73728
|
return count;
|
|
73500
|
-
}, [leaderboardDailyScopeMode, selectedLeaderboardShiftId, currentShiftId]);
|
|
73501
|
-
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);
|
|
73502
73749
|
setSelectedLeaderboardShiftId(currentShiftId);
|
|
73503
73750
|
setSelectedLeaderboardDate(currentShiftDate);
|
|
73504
73751
|
setLeaderboardDailyScopeMode("live");
|
|
73505
|
-
}, [currentShiftDate, currentShiftId]);
|
|
73752
|
+
}, [activeTab, currentShiftDate, currentShiftId, effectiveSelectedFactoryFilters, efficiencySortDirection, factoryFilterOptionIds, selectedLineStatusFilters, selectedLeaderboardShiftId, todayViewLevel]);
|
|
73506
73753
|
useEffect(() => {
|
|
73507
73754
|
const handleClickOutside = (event) => {
|
|
73508
73755
|
const target = event.target;
|
|
@@ -73510,15 +73757,23 @@ var KPIsOverviewView = ({
|
|
|
73510
73757
|
if (filterRef.current && !filterRef.current.contains(target)) {
|
|
73511
73758
|
setIsFilterOpen(false);
|
|
73512
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
|
+
}
|
|
73513
73768
|
};
|
|
73514
73769
|
document.addEventListener("mousedown", handleClickOutside);
|
|
73515
73770
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
73516
73771
|
}, []);
|
|
73517
|
-
const shiftEndDate =
|
|
73772
|
+
const shiftEndDate = React125__default.useMemo(
|
|
73518
73773
|
() => getShiftEndDate(currentShiftDetails, configuredTimezone),
|
|
73519
73774
|
[currentShiftDetails, configuredTimezone]
|
|
73520
73775
|
);
|
|
73521
|
-
const leaderboardShiftOptions =
|
|
73776
|
+
const leaderboardShiftOptions = React125__default.useMemo(() => {
|
|
73522
73777
|
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
73523
73778
|
return shiftConfig.shifts.map((shift) => ({
|
|
73524
73779
|
id: shift.shiftId,
|
|
@@ -73535,37 +73790,42 @@ var KPIsOverviewView = ({
|
|
|
73535
73790
|
const effectiveLeaderboardDate = selectedLeaderboardDate || currentShiftDate;
|
|
73536
73791
|
const effectiveLeaderboardShiftId = Number.isFinite(selectedLeaderboardShiftId) ? selectedLeaderboardShiftId : currentShiftId;
|
|
73537
73792
|
const isHistoricalLeaderboardDaily = activeTab === "leaderboard" && timeRange === "today" && leaderboardDailyScopeMode === "historical" && (effectiveLeaderboardDate !== currentShiftDate || effectiveLeaderboardShiftId !== currentShiftId);
|
|
73538
|
-
const updateLeaderboardDate =
|
|
73793
|
+
const updateLeaderboardDate = React125__default.useCallback((dateKey) => {
|
|
73539
73794
|
setSelectedLeaderboardDate(dateKey);
|
|
73540
73795
|
setLeaderboardDailyScopeMode(
|
|
73541
73796
|
dateKey === currentShiftDate && effectiveLeaderboardShiftId === currentShiftId ? "live" : "historical"
|
|
73542
73797
|
);
|
|
73543
73798
|
}, [currentShiftDate, currentShiftId, effectiveLeaderboardShiftId]);
|
|
73544
|
-
const updateLeaderboardShiftId =
|
|
73799
|
+
const updateLeaderboardShiftId = React125__default.useCallback((shiftId) => {
|
|
73545
73800
|
setSelectedLeaderboardShiftId(shiftId);
|
|
73546
73801
|
setLeaderboardDailyScopeMode(
|
|
73547
73802
|
effectiveLeaderboardDate === currentShiftDate && shiftId === currentShiftId ? "live" : "historical"
|
|
73548
73803
|
);
|
|
73549
73804
|
}, [currentShiftDate, currentShiftId, effectiveLeaderboardDate]);
|
|
73550
|
-
const returnLeaderboardToLive =
|
|
73805
|
+
const returnLeaderboardToLive = React125__default.useCallback(() => {
|
|
73551
73806
|
setSelectedLeaderboardDate(currentShiftDate);
|
|
73552
73807
|
setSelectedLeaderboardShiftId(currentShiftId);
|
|
73553
73808
|
setLeaderboardDailyScopeMode("live");
|
|
73554
73809
|
}, [currentShiftDate, currentShiftId]);
|
|
73555
73810
|
const selectedFactoryIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_QUERY_PARAM]);
|
|
73556
73811
|
const selectedFactoryAreaIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_AREA_QUERY_PARAM]);
|
|
73557
|
-
const kpiLineHierarchy =
|
|
73812
|
+
const kpiLineHierarchy = React125__default.useMemo(
|
|
73558
73813
|
() => buildKpiLineHierarchy(linesForView),
|
|
73559
73814
|
[linesForView]
|
|
73560
73815
|
);
|
|
73561
|
-
const selectedFactoryNode =
|
|
73816
|
+
const selectedFactoryNode = React125__default.useMemo(
|
|
73562
73817
|
() => kpiLineHierarchy.showFactoryLevel && selectedFactoryIdFromUrl ? kpiLineHierarchy.factories.find((factory) => factory.id === selectedFactoryIdFromUrl) : void 0,
|
|
73563
73818
|
[kpiLineHierarchy, selectedFactoryIdFromUrl]
|
|
73564
73819
|
);
|
|
73565
|
-
const selectedFactoryAreaNode =
|
|
73820
|
+
const selectedFactoryAreaNode = React125__default.useMemo(
|
|
73566
73821
|
() => selectedFactoryNode && selectedFactoryAreaIdFromUrl ? selectedFactoryNode.areas.find((area) => area.id === selectedFactoryAreaIdFromUrl) : void 0,
|
|
73567
73822
|
[selectedFactoryNode, selectedFactoryAreaIdFromUrl]
|
|
73568
73823
|
);
|
|
73824
|
+
useEffect(() => {
|
|
73825
|
+
if (!kpiLineHierarchy.showFactoryLevel && todayViewLevel !== "factory") {
|
|
73826
|
+
setTodayViewLevel("factory");
|
|
73827
|
+
}
|
|
73828
|
+
}, [kpiLineHierarchy.showFactoryLevel, todayViewLevel]);
|
|
73569
73829
|
useEffect(() => {
|
|
73570
73830
|
if (!router.isReady) return;
|
|
73571
73831
|
const tabQuery = router.query.tab;
|
|
@@ -73651,15 +73911,15 @@ var KPIsOverviewView = ({
|
|
|
73651
73911
|
lineId: factoryViewId,
|
|
73652
73912
|
userAccessibleLineIds: metricsLineIds
|
|
73653
73913
|
});
|
|
73654
|
-
const defaultKPIs =
|
|
73655
|
-
const lineModeById =
|
|
73914
|
+
const defaultKPIs = React125__default.useMemo(() => createDefaultKPIs(), []);
|
|
73915
|
+
const lineModeById = React125__default.useMemo(() => {
|
|
73656
73916
|
const map = /* @__PURE__ */ new Map();
|
|
73657
73917
|
linesForView.forEach((line) => {
|
|
73658
73918
|
map.set(line.id, line.monitoring_mode ?? "output");
|
|
73659
73919
|
});
|
|
73660
73920
|
return map;
|
|
73661
73921
|
}, [linesForView]);
|
|
73662
|
-
const lineMetricRowsByLineId =
|
|
73922
|
+
const lineMetricRowsByLineId = React125__default.useMemo(() => {
|
|
73663
73923
|
const map = /* @__PURE__ */ new Map();
|
|
73664
73924
|
lineMetrics.forEach((row) => {
|
|
73665
73925
|
if (!row?.line_id) return;
|
|
@@ -73671,7 +73931,7 @@ var KPIsOverviewView = ({
|
|
|
73671
73931
|
});
|
|
73672
73932
|
return map;
|
|
73673
73933
|
}, [lineMetrics, lineModeById]);
|
|
73674
|
-
const liveDailyFallbackEfficiencyByLineId =
|
|
73934
|
+
const liveDailyFallbackEfficiencyByLineId = React125__default.useMemo(() => {
|
|
73675
73935
|
const map = /* @__PURE__ */ new Map();
|
|
73676
73936
|
lineMetricRowsByLineId.forEach((row, lineId) => {
|
|
73677
73937
|
const value = Number(row?.avg_efficiency);
|
|
@@ -73693,31 +73953,31 @@ var KPIsOverviewView = ({
|
|
|
73693
73953
|
isHistoricalLeaderboardDaily,
|
|
73694
73954
|
lineMetricRowsByLineId
|
|
73695
73955
|
]);
|
|
73696
|
-
const dailyFallbackEfficiencyByLineId =
|
|
73956
|
+
const dailyFallbackEfficiencyByLineId = React125__default.useMemo(() => {
|
|
73697
73957
|
const map = new Map(liveDailyFallbackEfficiencyByLineId);
|
|
73698
73958
|
scopedDailyFallbackEfficiencyByLineId.forEach((value, lineId) => {
|
|
73699
73959
|
map.set(lineId, value);
|
|
73700
73960
|
});
|
|
73701
73961
|
return map;
|
|
73702
73962
|
}, [liveDailyFallbackEfficiencyByLineId, scopedDailyFallbackEfficiencyByLineId]);
|
|
73703
|
-
const kpisByLineId =
|
|
73963
|
+
const kpisByLineId = React125__default.useMemo(() => {
|
|
73704
73964
|
const map = /* @__PURE__ */ new Map();
|
|
73705
73965
|
lineMetricRowsByLineId.forEach((row, lineId) => {
|
|
73706
73966
|
map.set(lineId, buildKPIsFromLineMetricsRow(row));
|
|
73707
73967
|
});
|
|
73708
73968
|
return map;
|
|
73709
73969
|
}, [lineMetricRowsByLineId]);
|
|
73710
|
-
const getLineCardKpis =
|
|
73970
|
+
const getLineCardKpis = React125__default.useCallback((line) => {
|
|
73711
73971
|
if (metricsError) return null;
|
|
73712
73972
|
return kpisByLineId.get(line.id) ?? (metricsLoading ? null : defaultKPIs);
|
|
73713
73973
|
}, [defaultKPIs, kpisByLineId, metricsError, metricsLoading]);
|
|
73714
|
-
const getAggregateCardKpis =
|
|
73974
|
+
const getAggregateCardKpis = React125__default.useCallback((cardLines) => {
|
|
73715
73975
|
if (metricsError) return null;
|
|
73716
73976
|
const rows = cardLines.map((line) => lineMetricRowsByLineId.get(line.id)).filter(Boolean);
|
|
73717
73977
|
if (metricsLoading && rows.length === 0) return null;
|
|
73718
73978
|
return aggregateKPIsFromLineMetricsRows(rows);
|
|
73719
73979
|
}, [lineMetricRowsByLineId, metricsError, metricsLoading]);
|
|
73720
|
-
const supervisorLineIds =
|
|
73980
|
+
const supervisorLineIds = React125__default.useMemo(
|
|
73721
73981
|
() => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
|
|
73722
73982
|
[leaderboardLines, lines]
|
|
73723
73983
|
);
|
|
@@ -73969,7 +74229,135 @@ var KPIsOverviewView = ({
|
|
|
73969
74229
|
{ shallow: true }
|
|
73970
74230
|
);
|
|
73971
74231
|
}, [router]);
|
|
73972
|
-
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(() => {
|
|
73973
74361
|
if (activeTab !== "today" || !selectedFactoryNode) return void 0;
|
|
73974
74362
|
return createKpisOverviewUrl({
|
|
73975
74363
|
factoryId: selectedFactoryNode.id,
|
|
@@ -74059,6 +74447,19 @@ var KPIsOverviewView = ({
|
|
|
74059
74447
|
const headerShiftId = showHistoricalLeaderboardHeader ? effectiveLeaderboardShiftId : currentShiftDetails.shiftId;
|
|
74060
74448
|
const headerShiftName = getShiftNameById(headerShiftId, configuredTimezone, shiftConfig).replace(/ Shift$/i, "");
|
|
74061
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
|
+
);
|
|
74062
74463
|
const getShiftIcon2 = (shiftId) => {
|
|
74063
74464
|
const shiftNameLower = getShiftNameById(shiftId, configuredTimezone, shiftConfig).toLowerCase();
|
|
74064
74465
|
if (shiftNameLower.includes("day") || shiftNameLower.includes("morning") || shiftId === 0) {
|
|
@@ -74107,16 +74508,77 @@ var KPIsOverviewView = ({
|
|
|
74107
74508
|
},
|
|
74108
74509
|
key
|
|
74109
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
|
+
);
|
|
74110
74572
|
const renderTodayCards = () => {
|
|
74111
74573
|
if (!kpiLineHierarchy.showFactoryLevel) {
|
|
74112
|
-
return linesForView.map(renderLineCard);
|
|
74574
|
+
return filterLineCollection(linesForView).map(renderLineCard);
|
|
74113
74575
|
}
|
|
74114
74576
|
if (selectedFactoryNode && selectedFactoryAreaNode) {
|
|
74115
|
-
return selectedFactoryAreaNode.lines.map(renderLineCard);
|
|
74577
|
+
return filterLineCollection(selectedFactoryAreaNode.lines).map(renderLineCard);
|
|
74116
74578
|
}
|
|
74117
74579
|
if (selectedFactoryNode) {
|
|
74118
74580
|
return [
|
|
74119
|
-
...selectedFactoryNode.areas.map(
|
|
74581
|
+
...filterGroupCollection(selectedFactoryNode.areas).map(
|
|
74120
74582
|
(area) => renderGroupCard({
|
|
74121
74583
|
key: `area-${area.id}`,
|
|
74122
74584
|
title: area.areaName,
|
|
@@ -74125,10 +74587,10 @@ var KPIsOverviewView = ({
|
|
|
74125
74587
|
onClick: () => navigateTodayHierarchy(selectedFactoryNode.id, area.id)
|
|
74126
74588
|
})
|
|
74127
74589
|
),
|
|
74128
|
-
...selectedFactoryNode.ungroupedLines.map(renderLineCard)
|
|
74590
|
+
...filterLineCollection(selectedFactoryNode.ungroupedLines).map(renderLineCard)
|
|
74129
74591
|
];
|
|
74130
74592
|
}
|
|
74131
|
-
return kpiLineHierarchy.factories.map(
|
|
74593
|
+
return filterGroupCollection(kpiLineHierarchy.factories).map(
|
|
74132
74594
|
(factory) => renderGroupCard({
|
|
74133
74595
|
key: `factory-${factory.id}`,
|
|
74134
74596
|
title: factory.factoryName,
|
|
@@ -74138,6 +74600,18 @@ var KPIsOverviewView = ({
|
|
|
74138
74600
|
})
|
|
74139
74601
|
);
|
|
74140
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
|
+
]);
|
|
74141
74615
|
if (loading || isShiftConfigLoading) {
|
|
74142
74616
|
return /* @__PURE__ */ jsx(LoadingPage, { message: "Loading production lines..." });
|
|
74143
74617
|
}
|
|
@@ -74351,65 +74825,237 @@ var KPIsOverviewView = ({
|
|
|
74351
74825
|
)
|
|
74352
74826
|
] }),
|
|
74353
74827
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
74354
|
-
activeTab === "leaderboard" && timeRange === "today" && /* @__PURE__ */
|
|
74355
|
-
|
|
74356
|
-
|
|
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",
|
|
74357
74848
|
{
|
|
74358
|
-
|
|
74359
|
-
|
|
74360
|
-
|
|
74361
|
-
|
|
74362
|
-
|
|
74363
|
-
|
|
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);
|
|
74364
74970
|
},
|
|
74365
|
-
|
|
74366
|
-
|
|
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);
|
|
74367
75026
|
},
|
|
74368
|
-
|
|
74369
|
-
|
|
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
|
+
]
|
|
74370
75034
|
}
|
|
74371
75035
|
),
|
|
74372
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
74373
|
-
/* @__PURE__ */
|
|
74374
|
-
|
|
74375
|
-
{
|
|
74376
|
-
|
|
74377
|
-
|
|
74378
|
-
|
|
74379
|
-
|
|
74380
|
-
|
|
74381
|
-
|
|
74382
|
-
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 }),
|
|
74383
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 ml-1 transition-transform ${isFilterOpen ? "rotate-180" : ""}` })
|
|
74384
|
-
]
|
|
74385
|
-
}
|
|
74386
|
-
),
|
|
74387
|
-
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: [
|
|
74388
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
74389
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Filter View" }),
|
|
74390
|
-
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(
|
|
74391
75046
|
"button",
|
|
74392
75047
|
{
|
|
74393
|
-
|
|
74394
|
-
|
|
74395
|
-
|
|
74396
|
-
|
|
74397
|
-
|
|
74398
|
-
|
|
74399
|
-
|
|
74400
|
-
|
|
74401
|
-
|
|
74402
|
-
|
|
74403
|
-
|
|
74404
|
-
"aria-label": "Leaderboard shift",
|
|
74405
|
-
value: effectiveLeaderboardShiftId,
|
|
74406
|
-
onChange: (e) => updateLeaderboardShiftId(Number(e.target.value)),
|
|
74407
|
-
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",
|
|
74408
|
-
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` },
|
|
74409
|
-
children: leaderboardShiftOptions.map((shiftOption) => /* @__PURE__ */ jsx("option", { value: shiftOption.id, children: shiftOption.label }, shiftOption.id))
|
|
74410
|
-
}
|
|
74411
|
-
) })
|
|
74412
|
-
] }) })
|
|
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
|
+
}) })
|
|
74413
75059
|
] })
|
|
74414
75060
|
] })
|
|
74415
75061
|
] }),
|
|
@@ -74430,7 +75076,7 @@ var KPIsOverviewView = ({
|
|
|
74430
75076
|
] })
|
|
74431
75077
|
] })
|
|
74432
75078
|
] }) }),
|
|
74433
|
-
/* @__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: [
|
|
74434
75080
|
kpiLineHierarchy.showFactoryLevel && selectedFactoryNode && /* @__PURE__ */ jsxs("nav", { className: "flex flex-wrap items-center gap-2 text-sm", "aria-label": "KPI hierarchy", children: [
|
|
74435
75081
|
/* @__PURE__ */ jsx(
|
|
74436
75082
|
"button",
|
|
@@ -74457,7 +75103,7 @@ var KPIsOverviewView = ({
|
|
|
74457
75103
|
] })
|
|
74458
75104
|
] }),
|
|
74459
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() })
|
|
74460
|
-
] }) : 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(
|
|
74461
75107
|
OptifyeLogoLoader_default,
|
|
74462
75108
|
{
|
|
74463
75109
|
size: "lg",
|
|
@@ -74769,7 +75415,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
74769
75415
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
74770
75416
|
}, []);
|
|
74771
75417
|
const [isMobile, setIsMobile] = useState(false);
|
|
74772
|
-
|
|
75418
|
+
React125__default.useEffect(() => {
|
|
74773
75419
|
const checkMobile = () => setIsMobile(window.innerWidth < 640);
|
|
74774
75420
|
checkMobile();
|
|
74775
75421
|
window.addEventListener("resize", checkMobile);
|
|
@@ -75594,7 +76240,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
75594
76240
|
] }) }),
|
|
75595
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: [
|
|
75596
76242
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
75597
|
-
/* @__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" }),
|
|
75598
76244
|
activeFiltersCount > 0 && /* @__PURE__ */ jsx(
|
|
75599
76245
|
"button",
|
|
75600
76246
|
{
|
|
@@ -75719,9 +76365,9 @@ var LeaderboardDetailView = memo$1(({
|
|
|
75719
76365
|
ref: mobileFilterButtonRef,
|
|
75720
76366
|
onClick: () => setIsFilterOpen(!isFilterOpen),
|
|
75721
76367
|
className: `p-2 rounded-full transition-colors relative ${isFilterOpen || activeFiltersCount > 0 ? "bg-blue-50" : "active:bg-gray-100"}`,
|
|
75722
|
-
"aria-label": "Open
|
|
76368
|
+
"aria-label": "Open sort",
|
|
75723
76369
|
children: [
|
|
75724
|
-
/* @__PURE__ */ jsx(
|
|
76370
|
+
/* @__PURE__ */ jsx(ArrowUpDown, { className: `w-5 h-5 ${activeFiltersCount > 0 ? "text-blue-600" : "text-gray-700"}` }),
|
|
75725
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 })
|
|
75726
76372
|
]
|
|
75727
76373
|
}
|
|
@@ -75794,8 +76440,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
75794
76440
|
onClick: () => setIsFilterOpen(!isFilterOpen),
|
|
75795
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"}`,
|
|
75796
76442
|
children: [
|
|
75797
|
-
/* @__PURE__ */ jsx(
|
|
75798
|
-
/* @__PURE__ */ jsx("span", { children: "
|
|
76443
|
+
/* @__PURE__ */ jsx(ArrowUpDown, { className: "w-4 h-4" }),
|
|
76444
|
+
/* @__PURE__ */ jsx("span", { children: "Sort" }),
|
|
75799
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 }),
|
|
75800
76446
|
/* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 ml-1 transition-transform ${isFilterOpen ? "rotate-180" : ""}` })
|
|
75801
76447
|
]
|
|
@@ -78819,7 +79465,7 @@ var ShiftsView = ({
|
|
|
78819
79465
|
] })
|
|
78820
79466
|
] });
|
|
78821
79467
|
};
|
|
78822
|
-
var AuthenticatedShiftsView = withAuth(
|
|
79468
|
+
var AuthenticatedShiftsView = withAuth(React125__default.memo(ShiftsView));
|
|
78823
79469
|
var ShiftsView_default = ShiftsView;
|
|
78824
79470
|
|
|
78825
79471
|
// src/views/TargetsView.utils.ts
|
|
@@ -80686,7 +81332,7 @@ var TargetsView = ({
|
|
|
80686
81332
|
};
|
|
80687
81333
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
80688
81334
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
80689
|
-
var AuthenticatedTargetsView = withAuth(
|
|
81335
|
+
var AuthenticatedTargetsView = withAuth(React125__default.memo(TargetsViewWithDisplayNames));
|
|
80690
81336
|
function useTimezone(options = {}) {
|
|
80691
81337
|
const dashboardConfig = useDashboardConfig();
|
|
80692
81338
|
const workspaceConfig = useWorkspaceConfig();
|
|
@@ -80851,13 +81497,13 @@ var WorkspaceHourSummaryPanel = ({
|
|
|
80851
81497
|
}) => {
|
|
80852
81498
|
const { data, isLoading, error, summarize, reset } = useWorkspaceHourSummary();
|
|
80853
81499
|
const selectedKey = selectedHour ? `${selectedHour.source}:${selectedHour.hourIndex}:${date}:${shiftId}` : "none";
|
|
80854
|
-
const autoSummaryKeyRef =
|
|
80855
|
-
|
|
81500
|
+
const autoSummaryKeyRef = React125__default.useRef(null);
|
|
81501
|
+
React125__default.useEffect(() => {
|
|
80856
81502
|
reset();
|
|
80857
81503
|
autoSummaryKeyRef.current = null;
|
|
80858
81504
|
}, [reset, selectedKey]);
|
|
80859
81505
|
const canSummarize = Boolean(workspaceId && companyId && date && shiftId !== null && shiftId !== void 0);
|
|
80860
|
-
|
|
81506
|
+
React125__default.useEffect(() => {
|
|
80861
81507
|
if (!selectedHour || !canSummarize || !companyId || !date || shiftId === null || shiftId === void 0) {
|
|
80862
81508
|
return;
|
|
80863
81509
|
}
|
|
@@ -82588,7 +83234,8 @@ var WorkspaceDetailView = ({
|
|
|
82588
83234
|
selectedHourIndex: isWorkspaceHourAiSummaryEnabled ? selectedHour?.source === "output" ? selectedHour.hourIndex : aiSummaryHour?.hourIndex ?? null : null,
|
|
82589
83235
|
onHourClick: isWorkspaceHourAiSummaryEnabled ? handleOutputHourSelect : void 0,
|
|
82590
83236
|
onWatchClipsClick: handleWatchClipsFromChart,
|
|
82591
|
-
onAiSummaryClick: isWorkspaceHourAiSummaryEnabled ? handleAiSummaryClick : void 0
|
|
83237
|
+
onAiSummaryClick: isWorkspaceHourAiSummaryEnabled ? handleAiSummaryClick : void 0,
|
|
83238
|
+
onSelectSku: setSelectedSkuId
|
|
82592
83239
|
}
|
|
82593
83240
|
)
|
|
82594
83241
|
}
|
|
@@ -82761,7 +83408,8 @@ var WorkspaceDetailView = ({
|
|
|
82761
83408
|
selectedHourIndex: isWorkspaceHourAiSummaryEnabled ? selectedHour?.source === "output" ? selectedHour.hourIndex : aiSummaryHour?.hourIndex ?? null : null,
|
|
82762
83409
|
onHourClick: isWorkspaceHourAiSummaryEnabled ? handleOutputHourSelect : void 0,
|
|
82763
83410
|
onWatchClipsClick: handleWatchClipsFromChart,
|
|
82764
|
-
onAiSummaryClick: isWorkspaceHourAiSummaryEnabled ? handleAiSummaryClick : void 0
|
|
83411
|
+
onAiSummaryClick: isWorkspaceHourAiSummaryEnabled ? handleAiSummaryClick : void 0,
|
|
83412
|
+
onSelectSku: setSelectedSkuId
|
|
82765
83413
|
}
|
|
82766
83414
|
) })
|
|
82767
83415
|
]
|
|
@@ -84548,7 +85196,7 @@ function BottleneckClipsView({
|
|
|
84548
85196
|
) })
|
|
84549
85197
|
] }) });
|
|
84550
85198
|
}
|
|
84551
|
-
var AuthenticatedBottleneckClipsView = withAuth(
|
|
85199
|
+
var AuthenticatedBottleneckClipsView = withAuth(React125__default.memo(BottleneckClipsView));
|
|
84552
85200
|
var BottleneckClipsView_default = BottleneckClipsView;
|
|
84553
85201
|
|
|
84554
85202
|
// src/lib/services/ticketService.ts
|
|
@@ -85391,7 +86039,7 @@ Please ensure:
|
|
|
85391
86039
|
)
|
|
85392
86040
|
] });
|
|
85393
86041
|
}
|
|
85394
|
-
var AuthenticatedTicketsView = withAuth(
|
|
86042
|
+
var AuthenticatedTicketsView = withAuth(React125__default.memo(TicketsView));
|
|
85395
86043
|
var TicketsView_default = TicketsView;
|
|
85396
86044
|
|
|
85397
86045
|
// src/lib/utils/improvementDisplay.ts
|
|
@@ -86362,7 +87010,7 @@ var ImprovementCenterView = () => {
|
|
|
86362
87010
|
setSelectedMemberId("all");
|
|
86363
87011
|
}
|
|
86364
87012
|
}, [memberOptions, selectedMemberId]);
|
|
86365
|
-
const getRecommendationDisplayMetadata =
|
|
87013
|
+
const getRecommendationDisplayMetadata = React125__default.useCallback((rec) => {
|
|
86366
87014
|
const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
|
|
86367
87015
|
return getImprovementDisplayMetadata({
|
|
86368
87016
|
location: rec.location,
|
|
@@ -86836,7 +87484,7 @@ var ThreadSidebar = ({
|
|
|
86836
87484
|
] }) })
|
|
86837
87485
|
] });
|
|
86838
87486
|
};
|
|
86839
|
-
var ProfilePicture =
|
|
87487
|
+
var ProfilePicture = React125__default.memo(({
|
|
86840
87488
|
alt = "Axel",
|
|
86841
87489
|
className = "",
|
|
86842
87490
|
size = "md",
|
|
@@ -89396,7 +90044,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
|
|
|
89396
90044
|
] }),
|
|
89397
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" }) })
|
|
89398
90046
|
] }, index)) });
|
|
89399
|
-
var OperationsOverviewHeader =
|
|
90047
|
+
var OperationsOverviewHeader = React125__default.memo(({
|
|
89400
90048
|
dateRange,
|
|
89401
90049
|
displayDateRange,
|
|
89402
90050
|
trendMode,
|
|
@@ -89417,65 +90065,65 @@ var OperationsOverviewHeader = React148__default.memo(({
|
|
|
89417
90065
|
bumpRenderCounter();
|
|
89418
90066
|
const subtitleRange = displayDateRange || dateRange;
|
|
89419
90067
|
const showLiveShiftMeta = isLiveScope && trendMode !== "all";
|
|
89420
|
-
const liveShiftLabel =
|
|
90068
|
+
const liveShiftLabel = React125__default.useMemo(
|
|
89421
90069
|
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
89422
90070
|
[liveShiftName, trendMode]
|
|
89423
90071
|
);
|
|
89424
|
-
const liveShiftIcon =
|
|
90072
|
+
const liveShiftIcon = React125__default.useMemo(
|
|
89425
90073
|
() => getShiftIcon(liveShiftName, trendMode),
|
|
89426
90074
|
[liveShiftName, trendMode]
|
|
89427
90075
|
);
|
|
89428
|
-
const [isFilterOpen, setIsFilterOpen] =
|
|
89429
|
-
const [isLinesDropdownOpen, setIsLinesDropdownOpen] =
|
|
89430
|
-
const filterRef =
|
|
89431
|
-
const filterButtonRef =
|
|
89432
|
-
const mobileFilterButtonRef =
|
|
89433
|
-
const linesDropdownRef =
|
|
89434
|
-
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(() => {
|
|
89435
90083
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
89436
90084
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
|
|
89437
90085
|
}
|
|
89438
90086
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
|
|
89439
90087
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
89440
|
-
const desktopSubtitle =
|
|
90088
|
+
const desktopSubtitle = React125__default.useMemo(() => {
|
|
89441
90089
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
89442
90090
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
|
|
89443
90091
|
}
|
|
89444
90092
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
|
|
89445
90093
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
89446
|
-
const availableLineIds =
|
|
90094
|
+
const availableLineIds = React125__default.useMemo(
|
|
89447
90095
|
() => lineOptions.map((line) => line.id),
|
|
89448
90096
|
[lineOptions]
|
|
89449
90097
|
);
|
|
89450
|
-
const selectedLineIdSet =
|
|
90098
|
+
const selectedLineIdSet = React125__default.useMemo(
|
|
89451
90099
|
() => new Set(selectedLineIds),
|
|
89452
90100
|
[selectedLineIds]
|
|
89453
90101
|
);
|
|
89454
|
-
const isAllLinesSelected =
|
|
90102
|
+
const isAllLinesSelected = React125__default.useMemo(() => {
|
|
89455
90103
|
if (availableLineIds.length === 0) return true;
|
|
89456
90104
|
return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
|
|
89457
90105
|
}, [availableLineIds, selectedLineIdSet]);
|
|
89458
|
-
const activeFilterCount =
|
|
90106
|
+
const activeFilterCount = React125__default.useMemo(() => {
|
|
89459
90107
|
let count = 0;
|
|
89460
90108
|
if (trendMode !== "all") count += 1;
|
|
89461
90109
|
if (selectedSupervisorId !== "all") count += 1;
|
|
89462
90110
|
if (!isAllLinesSelected) count += 1;
|
|
89463
90111
|
return count;
|
|
89464
90112
|
}, [isAllLinesSelected, selectedSupervisorId, trendMode]);
|
|
89465
|
-
const handleFilterToggle =
|
|
90113
|
+
const handleFilterToggle = React125__default.useCallback(() => {
|
|
89466
90114
|
trackCoreEvent("Operations Overview Filter Toggled", {
|
|
89467
90115
|
action: !isFilterOpen ? "open" : "close"
|
|
89468
90116
|
});
|
|
89469
90117
|
setIsFilterOpen((previous) => !previous);
|
|
89470
90118
|
}, [isFilterOpen]);
|
|
89471
|
-
const handleTrendModeChange =
|
|
90119
|
+
const handleTrendModeChange = React125__default.useCallback((event) => {
|
|
89472
90120
|
const nextMode = event.target.value;
|
|
89473
90121
|
trackCoreEvent("Operations Overview Shift Filter Changed", {
|
|
89474
90122
|
shift_mode: nextMode
|
|
89475
90123
|
});
|
|
89476
90124
|
onTrendModeChange(nextMode);
|
|
89477
90125
|
}, [onTrendModeChange]);
|
|
89478
|
-
const handleAllLinesToggle =
|
|
90126
|
+
const handleAllLinesToggle = React125__default.useCallback(() => {
|
|
89479
90127
|
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
89480
90128
|
selected_line_ids: availableLineIds,
|
|
89481
90129
|
selected_line_count: availableLineIds.length,
|
|
@@ -89483,7 +90131,7 @@ var OperationsOverviewHeader = React148__default.memo(({
|
|
|
89483
90131
|
});
|
|
89484
90132
|
onSelectedLineIdsChange(availableLineIds);
|
|
89485
90133
|
}, [availableLineIds, onSelectedLineIdsChange]);
|
|
89486
|
-
const handleSupervisorChange =
|
|
90134
|
+
const handleSupervisorChange = React125__default.useCallback((event) => {
|
|
89487
90135
|
const supervisorId = event.target.value;
|
|
89488
90136
|
const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
|
|
89489
90137
|
trackCoreEvent("Operations Overview Supervisor Filter Changed", {
|
|
@@ -89494,7 +90142,7 @@ var OperationsOverviewHeader = React148__default.memo(({
|
|
|
89494
90142
|
});
|
|
89495
90143
|
onSelectedSupervisorIdChange(supervisorId);
|
|
89496
90144
|
}, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
|
|
89497
|
-
const handleLineToggle =
|
|
90145
|
+
const handleLineToggle = React125__default.useCallback((lineId) => {
|
|
89498
90146
|
const current = new Set(selectedLineIds);
|
|
89499
90147
|
if (current.has(lineId)) {
|
|
89500
90148
|
if (current.size <= 1) return;
|
|
@@ -89510,13 +90158,13 @@ var OperationsOverviewHeader = React148__default.memo(({
|
|
|
89510
90158
|
});
|
|
89511
90159
|
onSelectedLineIdsChange(next);
|
|
89512
90160
|
}, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
|
|
89513
|
-
const handleClearAllFilters =
|
|
90161
|
+
const handleClearAllFilters = React125__default.useCallback(() => {
|
|
89514
90162
|
onTrendModeChange("all");
|
|
89515
90163
|
onSelectedSupervisorIdChange("all");
|
|
89516
90164
|
onSelectedLineIdsChange(availableLineIds);
|
|
89517
90165
|
setIsFilterOpen(false);
|
|
89518
90166
|
}, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
|
|
89519
|
-
|
|
90167
|
+
React125__default.useEffect(() => {
|
|
89520
90168
|
const handleClickOutside = (event) => {
|
|
89521
90169
|
const target = event.target;
|
|
89522
90170
|
if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
|
|
@@ -89751,12 +90399,12 @@ var OperationsOverviewHeader = React148__default.memo(({
|
|
|
89751
90399
|
] }) });
|
|
89752
90400
|
});
|
|
89753
90401
|
OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
|
|
89754
|
-
var OverviewSummaryCards =
|
|
90402
|
+
var OverviewSummaryCards = React125__default.memo(({ store }) => {
|
|
89755
90403
|
bumpRenderCounter();
|
|
89756
90404
|
const scope = useOperationsOverviewScope(store);
|
|
89757
90405
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
89758
90406
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
89759
|
-
const comparisonLabel =
|
|
90407
|
+
const comparisonLabel = React125__default.useMemo(() => {
|
|
89760
90408
|
return formatComparisonWindow({
|
|
89761
90409
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
89762
90410
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -89769,27 +90417,27 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
|
|
|
89769
90417
|
scope.previous_range?.day_count,
|
|
89770
90418
|
scope.shift_mode
|
|
89771
90419
|
]);
|
|
89772
|
-
const [isIdleContributorsOpen, setIsIdleContributorsOpen] =
|
|
89773
|
-
const [isIdleContributorsPinned, setIsIdleContributorsPinned] =
|
|
89774
|
-
const idleContributorsRef =
|
|
89775
|
-
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(() => {
|
|
89776
90424
|
return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
|
|
89777
90425
|
positiveIsGood: true,
|
|
89778
90426
|
formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
|
|
89779
90427
|
comparisonLabel
|
|
89780
90428
|
});
|
|
89781
90429
|
}, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
|
|
89782
|
-
const idleBadge =
|
|
90430
|
+
const idleBadge = React125__default.useMemo(() => {
|
|
89783
90431
|
return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
|
|
89784
90432
|
positiveIsGood: false,
|
|
89785
90433
|
formatter: (value) => formatSignedIdleDuration(value),
|
|
89786
90434
|
comparisonLabel
|
|
89787
90435
|
});
|
|
89788
90436
|
}, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
|
|
89789
|
-
const canInspectIdleContributors =
|
|
90437
|
+
const canInspectIdleContributors = React125__default.useMemo(() => {
|
|
89790
90438
|
return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
|
|
89791
90439
|
}, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
|
|
89792
|
-
const idleTopContributors =
|
|
90440
|
+
const idleTopContributors = React125__default.useMemo(() => {
|
|
89793
90441
|
return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
|
|
89794
90442
|
workspaceId: item.workspace_id || "",
|
|
89795
90443
|
workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
|
|
@@ -89797,14 +90445,14 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
|
|
|
89797
90445
|
avgIdleSeconds: toNumber4(item.avg_idle_seconds)
|
|
89798
90446
|
})).slice(0, 5);
|
|
89799
90447
|
}, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
|
|
89800
|
-
const showIdleContributorLineNames =
|
|
90448
|
+
const showIdleContributorLineNames = React125__default.useMemo(() => {
|
|
89801
90449
|
return (scope.line_count ?? 0) > 1;
|
|
89802
90450
|
}, [scope.line_count]);
|
|
89803
|
-
const closeIdleContributors =
|
|
90451
|
+
const closeIdleContributors = React125__default.useCallback(() => {
|
|
89804
90452
|
setIsIdleContributorsOpen(false);
|
|
89805
90453
|
setIsIdleContributorsPinned(false);
|
|
89806
90454
|
}, []);
|
|
89807
|
-
const handleIdleContributorsToggle =
|
|
90455
|
+
const handleIdleContributorsToggle = React125__default.useCallback(() => {
|
|
89808
90456
|
if (!canInspectIdleContributors) return;
|
|
89809
90457
|
setIsIdleContributorsPinned((previous) => {
|
|
89810
90458
|
const next = !previous;
|
|
@@ -89812,7 +90460,7 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
|
|
|
89812
90460
|
return next;
|
|
89813
90461
|
});
|
|
89814
90462
|
}, [canInspectIdleContributors]);
|
|
89815
|
-
const handleIdleContributorsKeyDown =
|
|
90463
|
+
const handleIdleContributorsKeyDown = React125__default.useCallback((event) => {
|
|
89816
90464
|
if (!canInspectIdleContributors) return;
|
|
89817
90465
|
if (event.key === "Enter" || event.key === " ") {
|
|
89818
90466
|
event.preventDefault();
|
|
@@ -89824,11 +90472,11 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
|
|
|
89824
90472
|
closeIdleContributors();
|
|
89825
90473
|
}
|
|
89826
90474
|
}, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
|
|
89827
|
-
|
|
90475
|
+
React125__default.useEffect(() => {
|
|
89828
90476
|
setIsIdleContributorsOpen(false);
|
|
89829
90477
|
setIsIdleContributorsPinned(false);
|
|
89830
90478
|
}, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
|
|
89831
|
-
|
|
90479
|
+
React125__default.useEffect(() => {
|
|
89832
90480
|
if (!isIdleContributorsOpen) return void 0;
|
|
89833
90481
|
const handleClickOutside = (event) => {
|
|
89834
90482
|
if (!isIdleContributorsPinned) return;
|
|
@@ -89966,7 +90614,7 @@ var OverviewSummaryCards = React148__default.memo(({ store }) => {
|
|
|
89966
90614
|
] });
|
|
89967
90615
|
});
|
|
89968
90616
|
OverviewSummaryCards.displayName = "OverviewSummaryCards";
|
|
89969
|
-
var PoorestPerformersCard =
|
|
90617
|
+
var PoorestPerformersCard = React125__default.memo(({
|
|
89970
90618
|
store,
|
|
89971
90619
|
supervisorsByLineId,
|
|
89972
90620
|
onViewAll,
|
|
@@ -89975,9 +90623,9 @@ var PoorestPerformersCard = React148__default.memo(({
|
|
|
89975
90623
|
bumpRenderCounter();
|
|
89976
90624
|
const scope = useOperationsOverviewScope(store);
|
|
89977
90625
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
89978
|
-
const [poorestLineMode, setPoorestLineMode] =
|
|
90626
|
+
const [poorestLineMode, setPoorestLineMode] = React125__default.useState("output");
|
|
89979
90627
|
const availableLineModes = scope.available_line_modes;
|
|
89980
|
-
|
|
90628
|
+
React125__default.useEffect(() => {
|
|
89981
90629
|
const hasOutput = !!availableLineModes?.has_output;
|
|
89982
90630
|
const hasUptime = !!availableLineModes?.has_uptime;
|
|
89983
90631
|
if (hasOutput && !hasUptime && poorestLineMode !== "output") {
|
|
@@ -89986,7 +90634,7 @@ var PoorestPerformersCard = React148__default.memo(({
|
|
|
89986
90634
|
setPoorestLineMode("uptime");
|
|
89987
90635
|
}
|
|
89988
90636
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
89989
|
-
const comparisonLabel =
|
|
90637
|
+
const comparisonLabel = React125__default.useMemo(() => {
|
|
89990
90638
|
return formatComparisonWindow({
|
|
89991
90639
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
89992
90640
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -90000,7 +90648,7 @@ var PoorestPerformersCard = React148__default.memo(({
|
|
|
90000
90648
|
scope.shift_mode
|
|
90001
90649
|
]);
|
|
90002
90650
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
90003
|
-
const mergedPoorestLines =
|
|
90651
|
+
const mergedPoorestLines = React125__default.useMemo(() => {
|
|
90004
90652
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
90005
90653
|
const lineRows = [];
|
|
90006
90654
|
const areaGroups = /* @__PURE__ */ new Map();
|
|
@@ -90080,7 +90728,7 @@ var PoorestPerformersCard = React148__default.memo(({
|
|
|
90080
90728
|
}, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
|
|
90081
90729
|
const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
|
|
90082
90730
|
const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
|
|
90083
|
-
const handlePoorestLineModeChange =
|
|
90731
|
+
const handlePoorestLineModeChange = React125__default.useCallback((mode) => {
|
|
90084
90732
|
trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
|
|
90085
90733
|
setPoorestLineMode(mode);
|
|
90086
90734
|
}, []);
|
|
@@ -90166,14 +90814,14 @@ var PoorestPerformersCard = React148__default.memo(({
|
|
|
90166
90814
|
] });
|
|
90167
90815
|
});
|
|
90168
90816
|
PoorestPerformersCard.displayName = "PoorestPerformersCard";
|
|
90169
|
-
var IdleBreakdownCard =
|
|
90817
|
+
var IdleBreakdownCard = React125__default.memo(({
|
|
90170
90818
|
store,
|
|
90171
90819
|
scopedLineCount
|
|
90172
90820
|
}) => {
|
|
90173
90821
|
bumpRenderCounter();
|
|
90174
90822
|
const idle = useOperationsOverviewIdle(store);
|
|
90175
90823
|
const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
|
|
90176
|
-
const idleBreakdown =
|
|
90824
|
+
const idleBreakdown = React125__default.useMemo(() => {
|
|
90177
90825
|
return idle.data.map((item) => ({
|
|
90178
90826
|
name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
|
|
90179
90827
|
reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
|
|
@@ -90192,7 +90840,7 @@ var IdleBreakdownCard = React148__default.memo(({
|
|
|
90192
90840
|
}))
|
|
90193
90841
|
})).filter((item) => item.value > 0);
|
|
90194
90842
|
}, [idle.data]);
|
|
90195
|
-
const showIdleModuleNotEnabledState =
|
|
90843
|
+
const showIdleModuleNotEnabledState = React125__default.useMemo(() => {
|
|
90196
90844
|
const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
|
|
90197
90845
|
return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
|
|
90198
90846
|
}, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
|
|
@@ -90213,7 +90861,7 @@ var IdleBreakdownCard = React148__default.memo(({
|
|
|
90213
90861
|
] });
|
|
90214
90862
|
});
|
|
90215
90863
|
IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
90216
|
-
var EfficiencyTrendCard =
|
|
90864
|
+
var EfficiencyTrendCard = React125__default.memo(({
|
|
90217
90865
|
store,
|
|
90218
90866
|
dateRange,
|
|
90219
90867
|
appTimezone,
|
|
@@ -90221,14 +90869,14 @@ var EfficiencyTrendCard = React148__default.memo(({
|
|
|
90221
90869
|
}) => {
|
|
90222
90870
|
bumpRenderCounter();
|
|
90223
90871
|
const trend = useOperationsOverviewTrend(store);
|
|
90224
|
-
const currentWeekRange =
|
|
90872
|
+
const currentWeekRange = React125__default.useMemo(
|
|
90225
90873
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
90226
90874
|
[appTimezone]
|
|
90227
90875
|
);
|
|
90228
90876
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
90229
90877
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
90230
90878
|
const isHourlyTrend = trend.data.granularity === "hour";
|
|
90231
|
-
const trendData =
|
|
90879
|
+
const trendData = React125__default.useMemo(() => {
|
|
90232
90880
|
if (isHourlyTrend) {
|
|
90233
90881
|
return (trend.data.points || []).map((point, index) => ({
|
|
90234
90882
|
name: (() => {
|
|
@@ -90300,13 +90948,13 @@ var EfficiencyTrendCard = React148__default.memo(({
|
|
|
90300
90948
|
};
|
|
90301
90949
|
});
|
|
90302
90950
|
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
90303
|
-
const trendTooltipLabelFormatter =
|
|
90951
|
+
const trendTooltipLabelFormatter = React125__default.useCallback((label, payload) => {
|
|
90304
90952
|
if (isHourlyTrend) return label;
|
|
90305
90953
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
90306
90954
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
90307
90955
|
return `${label} (${dayOfWeek})`;
|
|
90308
90956
|
}, [isHourlyTrend]);
|
|
90309
|
-
const trendXAxisTickFormatter =
|
|
90957
|
+
const trendXAxisTickFormatter = React125__default.useCallback((value, index) => {
|
|
90310
90958
|
if (!isHourlyTrend) {
|
|
90311
90959
|
return typeof value === "string" ? value : String(value ?? "");
|
|
90312
90960
|
}
|
|
@@ -90333,7 +90981,7 @@ var EfficiencyTrendCard = React148__default.memo(({
|
|
|
90333
90981
|
] });
|
|
90334
90982
|
});
|
|
90335
90983
|
EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
|
|
90336
|
-
var TopImprovementsCard =
|
|
90984
|
+
var TopImprovementsCard = React125__default.memo(({
|
|
90337
90985
|
store,
|
|
90338
90986
|
supervisorsByLineId,
|
|
90339
90987
|
onViewAll,
|
|
@@ -90342,7 +90990,7 @@ var TopImprovementsCard = React148__default.memo(({
|
|
|
90342
90990
|
bumpRenderCounter();
|
|
90343
90991
|
const improvements = useOperationsOverviewImprovements(store);
|
|
90344
90992
|
const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
|
|
90345
|
-
const displayImprovements =
|
|
90993
|
+
const displayImprovements = React125__default.useMemo(() => {
|
|
90346
90994
|
return improvements.data.map((item) => {
|
|
90347
90995
|
const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
|
|
90348
90996
|
return {
|
|
@@ -90470,33 +91118,33 @@ var useOperationsOverviewRefresh = ({
|
|
|
90470
91118
|
isLiveScope,
|
|
90471
91119
|
enabled = true
|
|
90472
91120
|
}) => {
|
|
90473
|
-
const lineIdsKey =
|
|
90474
|
-
const scopeSignature =
|
|
91121
|
+
const lineIdsKey = React125__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
91122
|
+
const scopeSignature = React125__default.useMemo(
|
|
90475
91123
|
() => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
|
|
90476
91124
|
[companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
|
|
90477
91125
|
);
|
|
90478
|
-
const controllersRef =
|
|
90479
|
-
const requestIdsRef =
|
|
91126
|
+
const controllersRef = React125__default.useRef({});
|
|
91127
|
+
const requestIdsRef = React125__default.useRef({
|
|
90480
91128
|
snapshot: 0,
|
|
90481
91129
|
trend: 0,
|
|
90482
91130
|
idle: 0,
|
|
90483
91131
|
improvements: 0
|
|
90484
91132
|
});
|
|
90485
|
-
const intervalRef =
|
|
90486
|
-
const isPageActiveRef =
|
|
90487
|
-
const lastResumeRefreshAtRef =
|
|
90488
|
-
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(() => {
|
|
90489
91137
|
Object.values(controllersRef.current).forEach((controller) => {
|
|
90490
91138
|
controller?.abort();
|
|
90491
91139
|
});
|
|
90492
91140
|
controllersRef.current = {};
|
|
90493
91141
|
}, []);
|
|
90494
|
-
|
|
91142
|
+
React125__default.useEffect(() => {
|
|
90495
91143
|
return () => {
|
|
90496
91144
|
abortAll();
|
|
90497
91145
|
};
|
|
90498
91146
|
}, [abortAll]);
|
|
90499
|
-
const getIsPageActive =
|
|
91147
|
+
const getIsPageActive = React125__default.useCallback(() => {
|
|
90500
91148
|
if (typeof document === "undefined") {
|
|
90501
91149
|
return true;
|
|
90502
91150
|
}
|
|
@@ -90504,7 +91152,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90504
91152
|
const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
|
|
90505
91153
|
return isVisible && hasFocus;
|
|
90506
91154
|
}, []);
|
|
90507
|
-
const stopPolling =
|
|
91155
|
+
const stopPolling = React125__default.useCallback((reason) => {
|
|
90508
91156
|
if (intervalRef.current === null) {
|
|
90509
91157
|
return;
|
|
90510
91158
|
}
|
|
@@ -90512,7 +91160,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90512
91160
|
intervalRef.current = null;
|
|
90513
91161
|
debugRefreshLog("poll stopped", { reason });
|
|
90514
91162
|
}, []);
|
|
90515
|
-
const runRefresh =
|
|
91163
|
+
const runRefresh = React125__default.useCallback(
|
|
90516
91164
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
90517
91165
|
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
90518
91166
|
const requestId = requestIdsRef.current[section] + 1;
|
|
@@ -90559,7 +91207,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90559
91207
|
},
|
|
90560
91208
|
[companyId, comparisonStrategy, enabled, endKey, lineIds, startKey, supabase, trendMode]
|
|
90561
91209
|
);
|
|
90562
|
-
const refreshSnapshot =
|
|
91210
|
+
const refreshSnapshot = React125__default.useCallback(
|
|
90563
91211
|
async (reason) => {
|
|
90564
91212
|
await runRefresh(
|
|
90565
91213
|
"snapshot",
|
|
@@ -90591,7 +91239,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90591
91239
|
},
|
|
90592
91240
|
[companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
90593
91241
|
);
|
|
90594
|
-
const refreshTrend =
|
|
91242
|
+
const refreshTrend = React125__default.useCallback(
|
|
90595
91243
|
async (reason) => {
|
|
90596
91244
|
await runRefresh(
|
|
90597
91245
|
"trend",
|
|
@@ -90620,7 +91268,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90620
91268
|
},
|
|
90621
91269
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
90622
91270
|
);
|
|
90623
|
-
const refreshIdle =
|
|
91271
|
+
const refreshIdle = React125__default.useCallback(
|
|
90624
91272
|
async (reason) => {
|
|
90625
91273
|
await runRefresh(
|
|
90626
91274
|
"idle",
|
|
@@ -90649,7 +91297,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90649
91297
|
},
|
|
90650
91298
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
90651
91299
|
);
|
|
90652
|
-
const refreshImprovements =
|
|
91300
|
+
const refreshImprovements = React125__default.useCallback(
|
|
90653
91301
|
async (reason) => {
|
|
90654
91302
|
await runRefresh(
|
|
90655
91303
|
"improvements",
|
|
@@ -90679,7 +91327,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90679
91327
|
},
|
|
90680
91328
|
[companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
|
|
90681
91329
|
);
|
|
90682
|
-
const refreshAll =
|
|
91330
|
+
const refreshAll = React125__default.useCallback(
|
|
90683
91331
|
async (reason) => {
|
|
90684
91332
|
await Promise.allSettled([
|
|
90685
91333
|
refreshSnapshot(reason),
|
|
@@ -90690,7 +91338,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90690
91338
|
},
|
|
90691
91339
|
[refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
|
|
90692
91340
|
);
|
|
90693
|
-
const startPolling =
|
|
91341
|
+
const startPolling = React125__default.useCallback((reason) => {
|
|
90694
91342
|
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
90695
91343
|
return;
|
|
90696
91344
|
}
|
|
@@ -90711,7 +91359,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90711
91359
|
}, LIVE_REFRESH_INTERVAL_MS);
|
|
90712
91360
|
debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
|
|
90713
91361
|
}, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
|
|
90714
|
-
const refreshFromResume =
|
|
91362
|
+
const refreshFromResume = React125__default.useCallback((reason) => {
|
|
90715
91363
|
const now4 = Date.now();
|
|
90716
91364
|
if (now4 - lastResumeRefreshAtRef.current < 1e3) {
|
|
90717
91365
|
debugRefreshLog("resume refresh suppressed", { reason });
|
|
@@ -90726,7 +91374,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90726
91374
|
}
|
|
90727
91375
|
});
|
|
90728
91376
|
}, [refreshAll, startPolling, stopPolling]);
|
|
90729
|
-
|
|
91377
|
+
React125__default.useEffect(() => {
|
|
90730
91378
|
if (!enabled) {
|
|
90731
91379
|
stopPolling("disabled");
|
|
90732
91380
|
abortAll();
|
|
@@ -90741,7 +91389,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
90741
91389
|
}
|
|
90742
91390
|
void refreshAll("scope_change");
|
|
90743
91391
|
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
90744
|
-
|
|
91392
|
+
React125__default.useEffect(() => {
|
|
90745
91393
|
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
90746
91394
|
isPageActiveRef.current = false;
|
|
90747
91395
|
stopPolling("live_scope_disabled");
|
|
@@ -90954,55 +91602,55 @@ var PlantHeadView = () => {
|
|
|
90954
91602
|
const { accessibleLineIds } = useUserLineAccess();
|
|
90955
91603
|
const mobileMenuContext = useMobileMenu();
|
|
90956
91604
|
useHideMobileHeader(!!mobileMenuContext);
|
|
90957
|
-
const storeRef =
|
|
91605
|
+
const storeRef = React125__default.useRef(createOperationsOverviewStore());
|
|
90958
91606
|
const store = storeRef.current;
|
|
90959
|
-
const fallbackOperationalDate =
|
|
91607
|
+
const fallbackOperationalDate = React125__default.useMemo(
|
|
90960
91608
|
() => getOperationalDate(appTimezone),
|
|
90961
91609
|
[appTimezone]
|
|
90962
91610
|
);
|
|
90963
|
-
const [dateRange, setDateRange] =
|
|
91611
|
+
const [dateRange, setDateRange] = React125__default.useState(() => ({
|
|
90964
91612
|
startKey: fallbackOperationalDate,
|
|
90965
91613
|
endKey: fallbackOperationalDate
|
|
90966
91614
|
}));
|
|
90967
|
-
const [usesThisWeekComparison, setUsesThisWeekComparison] =
|
|
90968
|
-
const [trendMode, setTrendMode] =
|
|
90969
|
-
const [selectedSupervisorId, setSelectedSupervisorId] =
|
|
90970
|
-
const [selectedLineIds, setSelectedLineIds] =
|
|
90971
|
-
const [isInitialScopeReady, setIsInitialScopeReady] =
|
|
90972
|
-
const [shiftResolutionTick, setShiftResolutionTick] =
|
|
90973
|
-
const hasAutoInitializedScopeRef =
|
|
90974
|
-
const hasUserAdjustedScopeRef =
|
|
90975
|
-
|
|
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(() => {
|
|
90976
91624
|
trackCorePageView("Operations Overview", {
|
|
90977
91625
|
dashboard_surface: "operations_overview"
|
|
90978
91626
|
});
|
|
90979
91627
|
}, []);
|
|
90980
|
-
const currentWeekRange =
|
|
91628
|
+
const currentWeekRange = React125__default.useMemo(
|
|
90981
91629
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
90982
91630
|
[appTimezone]
|
|
90983
91631
|
);
|
|
90984
|
-
const currentWeekDisplayRange =
|
|
91632
|
+
const currentWeekDisplayRange = React125__default.useMemo(
|
|
90985
91633
|
() => getCurrentWeekFullRange(appTimezone),
|
|
90986
91634
|
[appTimezone]
|
|
90987
91635
|
);
|
|
90988
91636
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
90989
|
-
const headerDateRange =
|
|
91637
|
+
const headerDateRange = React125__default.useMemo(() => {
|
|
90990
91638
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
90991
91639
|
return currentWeekDisplayRange;
|
|
90992
91640
|
}
|
|
90993
91641
|
return dateRange;
|
|
90994
91642
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
90995
|
-
const normalizedLineIds =
|
|
91643
|
+
const normalizedLineIds = React125__default.useMemo(
|
|
90996
91644
|
() => Array.from(new Set(
|
|
90997
91645
|
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
90998
91646
|
)).sort(),
|
|
90999
91647
|
[accessibleLineIds, factoryViewId]
|
|
91000
91648
|
);
|
|
91001
|
-
const lineIdsKey =
|
|
91649
|
+
const lineIdsKey = React125__default.useMemo(
|
|
91002
91650
|
() => normalizedLineIds.join(","),
|
|
91003
91651
|
[normalizedLineIds]
|
|
91004
91652
|
);
|
|
91005
|
-
const lineOptions =
|
|
91653
|
+
const lineOptions = React125__default.useMemo(
|
|
91006
91654
|
() => normalizedLineIds.map((lineId) => ({
|
|
91007
91655
|
id: lineId,
|
|
91008
91656
|
name: getLineDisplayName(entityConfig, lineId)
|
|
@@ -91014,7 +91662,7 @@ var PlantHeadView = () => {
|
|
|
91014
91662
|
companyId: entityConfig.companyId,
|
|
91015
91663
|
useBackend: true
|
|
91016
91664
|
});
|
|
91017
|
-
const supervisorOptions =
|
|
91665
|
+
const supervisorOptions = React125__default.useMemo(
|
|
91018
91666
|
() => {
|
|
91019
91667
|
const optionsById = /* @__PURE__ */ new Map();
|
|
91020
91668
|
normalizedLineIds.forEach((lineId) => {
|
|
@@ -91040,7 +91688,7 @@ var PlantHeadView = () => {
|
|
|
91040
91688
|
},
|
|
91041
91689
|
[normalizedLineIds, supervisorsByLineId]
|
|
91042
91690
|
);
|
|
91043
|
-
|
|
91691
|
+
React125__default.useEffect(() => {
|
|
91044
91692
|
if (selectedSupervisorId === "all") {
|
|
91045
91693
|
setSelectedLineIds((previous) => {
|
|
91046
91694
|
if (normalizedLineIds.length === 0) {
|
|
@@ -91066,7 +91714,7 @@ var PlantHeadView = () => {
|
|
|
91066
91714
|
const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
|
|
91067
91715
|
setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
|
|
91068
91716
|
}, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
|
|
91069
|
-
const scopedLineIds =
|
|
91717
|
+
const scopedLineIds = React125__default.useMemo(
|
|
91070
91718
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
91071
91719
|
[normalizedLineIds, selectedLineIds]
|
|
91072
91720
|
);
|
|
@@ -91074,7 +91722,7 @@ var PlantHeadView = () => {
|
|
|
91074
91722
|
shiftConfigMap,
|
|
91075
91723
|
isLoading: isShiftConfigLoading
|
|
91076
91724
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
91077
|
-
const shiftFilterOptions =
|
|
91725
|
+
const shiftFilterOptions = React125__default.useMemo(() => {
|
|
91078
91726
|
const optionsById = /* @__PURE__ */ new Map();
|
|
91079
91727
|
scopedLineIds.forEach((lineId) => {
|
|
91080
91728
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -91113,7 +91761,7 @@ var PlantHeadView = () => {
|
|
|
91113
91761
|
...dynamicOptions
|
|
91114
91762
|
];
|
|
91115
91763
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
91116
|
-
|
|
91764
|
+
React125__default.useEffect(() => {
|
|
91117
91765
|
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
91118
91766
|
return;
|
|
91119
91767
|
}
|
|
@@ -91124,11 +91772,11 @@ var PlantHeadView = () => {
|
|
|
91124
91772
|
clearInterval(intervalId);
|
|
91125
91773
|
};
|
|
91126
91774
|
}, [isShiftConfigLoading, scopedLineIds.length]);
|
|
91127
|
-
const shiftResolutionNow =
|
|
91775
|
+
const shiftResolutionNow = React125__default.useMemo(
|
|
91128
91776
|
() => /* @__PURE__ */ new Date(),
|
|
91129
91777
|
[shiftResolutionTick]
|
|
91130
91778
|
);
|
|
91131
|
-
const earliestDayShiftStartTime =
|
|
91779
|
+
const earliestDayShiftStartTime = React125__default.useMemo(() => {
|
|
91132
91780
|
const candidateStarts = [];
|
|
91133
91781
|
scopedLineIds.forEach((lineId) => {
|
|
91134
91782
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -91164,11 +91812,11 @@ var PlantHeadView = () => {
|
|
|
91164
91812
|
const minutes = earliestMinutes % 60;
|
|
91165
91813
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
91166
91814
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
91167
|
-
const resolvedOperationalToday =
|
|
91815
|
+
const resolvedOperationalToday = React125__default.useMemo(
|
|
91168
91816
|
() => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
|
|
91169
91817
|
[appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
|
|
91170
91818
|
);
|
|
91171
|
-
const activeLineShiftStates =
|
|
91819
|
+
const activeLineShiftStates = React125__default.useMemo(() => {
|
|
91172
91820
|
return scopedLineIds.flatMap((lineId) => {
|
|
91173
91821
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
91174
91822
|
const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
|
|
@@ -91198,7 +91846,7 @@ var PlantHeadView = () => {
|
|
|
91198
91846
|
});
|
|
91199
91847
|
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
91200
91848
|
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
91201
|
-
const hourlyWindowStartTime =
|
|
91849
|
+
const hourlyWindowStartTime = React125__default.useMemo(() => {
|
|
91202
91850
|
if (scopedLineIds.length === 0) {
|
|
91203
91851
|
return null;
|
|
91204
91852
|
}
|
|
@@ -91255,12 +91903,12 @@ var PlantHeadView = () => {
|
|
|
91255
91903
|
const minutes = earliestMinutes % 60;
|
|
91256
91904
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
91257
91905
|
}, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
91258
|
-
const isShiftScopeResolved =
|
|
91906
|
+
const isShiftScopeResolved = React125__default.useMemo(
|
|
91259
91907
|
() => !isShiftConfigLoading,
|
|
91260
91908
|
[isShiftConfigLoading]
|
|
91261
91909
|
);
|
|
91262
|
-
const initializedTimezoneRef =
|
|
91263
|
-
|
|
91910
|
+
const initializedTimezoneRef = React125__default.useRef(appTimezone);
|
|
91911
|
+
React125__default.useEffect(() => {
|
|
91264
91912
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
91265
91913
|
hasAutoInitializedScopeRef.current = false;
|
|
91266
91914
|
hasUserAdjustedScopeRef.current = false;
|
|
@@ -91273,7 +91921,7 @@ var PlantHeadView = () => {
|
|
|
91273
91921
|
setIsInitialScopeReady(false);
|
|
91274
91922
|
initializedTimezoneRef.current = appTimezone;
|
|
91275
91923
|
}, [appTimezone, fallbackOperationalDate]);
|
|
91276
|
-
|
|
91924
|
+
React125__default.useEffect(() => {
|
|
91277
91925
|
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
91278
91926
|
return;
|
|
91279
91927
|
}
|
|
@@ -91298,7 +91946,7 @@ var PlantHeadView = () => {
|
|
|
91298
91946
|
hasAutoInitializedScopeRef.current = true;
|
|
91299
91947
|
setIsInitialScopeReady(true);
|
|
91300
91948
|
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
91301
|
-
const handleDateRangeChange =
|
|
91949
|
+
const handleDateRangeChange = React125__default.useCallback((range, meta) => {
|
|
91302
91950
|
hasUserAdjustedScopeRef.current = true;
|
|
91303
91951
|
setIsInitialScopeReady(true);
|
|
91304
91952
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
@@ -91316,12 +91964,12 @@ var PlantHeadView = () => {
|
|
|
91316
91964
|
return previous;
|
|
91317
91965
|
});
|
|
91318
91966
|
}, []);
|
|
91319
|
-
const handleTrendModeChange =
|
|
91967
|
+
const handleTrendModeChange = React125__default.useCallback((mode) => {
|
|
91320
91968
|
hasUserAdjustedScopeRef.current = true;
|
|
91321
91969
|
setIsInitialScopeReady(true);
|
|
91322
91970
|
setTrendMode(mode);
|
|
91323
91971
|
}, []);
|
|
91324
|
-
const handleSelectedLineIdsChange =
|
|
91972
|
+
const handleSelectedLineIdsChange = React125__default.useCallback((lineIds) => {
|
|
91325
91973
|
setSelectedSupervisorId("all");
|
|
91326
91974
|
if (normalizedLineIds.length === 0) {
|
|
91327
91975
|
setSelectedLineIds([]);
|
|
@@ -91332,10 +91980,10 @@ var PlantHeadView = () => {
|
|
|
91332
91980
|
const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
|
|
91333
91981
|
setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
|
|
91334
91982
|
}, [normalizedLineIds]);
|
|
91335
|
-
const handleSelectedSupervisorIdChange =
|
|
91983
|
+
const handleSelectedSupervisorIdChange = React125__default.useCallback((supervisorId) => {
|
|
91336
91984
|
setSelectedSupervisorId(supervisorId);
|
|
91337
91985
|
}, []);
|
|
91338
|
-
const buildLineMonthlyHistoryUrl =
|
|
91986
|
+
const buildLineMonthlyHistoryUrl = React125__default.useCallback((lineId) => {
|
|
91339
91987
|
const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
|
|
91340
91988
|
const params = new URLSearchParams();
|
|
91341
91989
|
params.set("tab", "monthly_history");
|
|
@@ -91345,15 +91993,15 @@ var PlantHeadView = () => {
|
|
|
91345
91993
|
params.set("rangeEnd", dateRange.endKey);
|
|
91346
91994
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
91347
91995
|
}, [dateRange.endKey, dateRange.startKey]);
|
|
91348
|
-
const handleViewAllPoorestPerformers =
|
|
91996
|
+
const handleViewAllPoorestPerformers = React125__default.useCallback(() => {
|
|
91349
91997
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
91350
91998
|
navigate("/kpis?tab=leaderboard");
|
|
91351
91999
|
}, [navigate]);
|
|
91352
|
-
const handleViewAllImprovements =
|
|
92000
|
+
const handleViewAllImprovements = React125__default.useCallback(() => {
|
|
91353
92001
|
trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
|
|
91354
92002
|
navigate("/improvement-center");
|
|
91355
92003
|
}, [navigate]);
|
|
91356
|
-
const handleOpenImprovement =
|
|
92004
|
+
const handleOpenImprovement = React125__default.useCallback((item) => {
|
|
91357
92005
|
trackCoreEvent("Operations Overview Improvement Clicked", {
|
|
91358
92006
|
issue_id: item.issueId,
|
|
91359
92007
|
issue_number: item.issueNumber,
|
|
@@ -91364,13 +92012,13 @@ var PlantHeadView = () => {
|
|
|
91364
92012
|
});
|
|
91365
92013
|
navigate(`/improvement-center?${params.toString()}`);
|
|
91366
92014
|
}, [navigate]);
|
|
91367
|
-
const comparisonStrategy =
|
|
92015
|
+
const comparisonStrategy = React125__default.useMemo(() => {
|
|
91368
92016
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
91369
92017
|
return "previous_full_week";
|
|
91370
92018
|
}
|
|
91371
92019
|
return void 0;
|
|
91372
92020
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
91373
|
-
const effectiveDateRange =
|
|
92021
|
+
const effectiveDateRange = React125__default.useMemo(() => {
|
|
91374
92022
|
if (isInitialScopeReady) {
|
|
91375
92023
|
return dateRange;
|
|
91376
92024
|
}
|
|
@@ -91380,11 +92028,11 @@ var PlantHeadView = () => {
|
|
|
91380
92028
|
endKey: nextStartKey
|
|
91381
92029
|
};
|
|
91382
92030
|
}, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
|
|
91383
|
-
const effectiveTrendMode =
|
|
92031
|
+
const effectiveTrendMode = React125__default.useMemo(
|
|
91384
92032
|
() => resolvedTrendMode,
|
|
91385
92033
|
[resolvedTrendMode]
|
|
91386
92034
|
);
|
|
91387
|
-
const hasActiveSelectedShiftLine =
|
|
92035
|
+
const hasActiveSelectedShiftLine = React125__default.useMemo(
|
|
91388
92036
|
() => activeLineShiftStates.some((shift) => {
|
|
91389
92037
|
if (shift.date !== resolvedOperationalToday) return false;
|
|
91390
92038
|
if (effectiveTrendMode === "all") return true;
|
|
@@ -91396,7 +92044,7 @@ var PlantHeadView = () => {
|
|
|
91396
92044
|
}),
|
|
91397
92045
|
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
91398
92046
|
);
|
|
91399
|
-
const activeLiveShiftName =
|
|
92047
|
+
const activeLiveShiftName = React125__default.useMemo(
|
|
91400
92048
|
() => {
|
|
91401
92049
|
if (effectiveTrendMode === "all") return null;
|
|
91402
92050
|
const matchingShift = activeLineShiftStates.find((shift) => {
|
|
@@ -91411,17 +92059,17 @@ var PlantHeadView = () => {
|
|
|
91411
92059
|
},
|
|
91412
92060
|
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
91413
92061
|
);
|
|
91414
|
-
const hourlyLabelStartTime =
|
|
92062
|
+
const hourlyLabelStartTime = React125__default.useMemo(() => {
|
|
91415
92063
|
if (scopedLineIds.length === 0) {
|
|
91416
92064
|
return null;
|
|
91417
92065
|
}
|
|
91418
92066
|
return hourlyWindowStartTime;
|
|
91419
92067
|
}, [hourlyWindowStartTime, scopedLineIds.length]);
|
|
91420
|
-
const isSingleDayScope =
|
|
92068
|
+
const isSingleDayScope = React125__default.useMemo(
|
|
91421
92069
|
() => effectiveDateRange.startKey === effectiveDateRange.endKey,
|
|
91422
92070
|
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
91423
92071
|
);
|
|
91424
|
-
const isLiveScope =
|
|
92072
|
+
const isLiveScope = React125__default.useMemo(
|
|
91425
92073
|
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && hasActiveSelectedShiftLine,
|
|
91426
92074
|
[
|
|
91427
92075
|
effectiveDateRange.startKey,
|
|
@@ -91431,7 +92079,7 @@ var PlantHeadView = () => {
|
|
|
91431
92079
|
resolvedOperationalToday
|
|
91432
92080
|
]
|
|
91433
92081
|
);
|
|
91434
|
-
const handleOpenLineDetails =
|
|
92082
|
+
const handleOpenLineDetails = React125__default.useCallback((line) => {
|
|
91435
92083
|
trackCoreEvent("Operations Overview Line Clicked", {
|
|
91436
92084
|
line_id: line.rowType === "line" ? line.id : null,
|
|
91437
92085
|
line_name: line.name,
|