@optifye/dashboard-core 6.12.44 → 6.12.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +64 -6
- package/dist/index.d.mts +150 -2
- package/dist/index.d.ts +150 -2
- package/dist/index.js +3653 -2804
- package/dist/index.mjs +1331 -482
- package/package.json +2 -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 React148 from 'react';
|
|
4
|
+
import React148__default, { createContext, useRef, useId, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore, Children, isValidElement, useInsertionEffect, startTransition, Fragment as Fragment$1, createElement, Component } from 'react';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import { useRouter } from 'next/router';
|
|
7
7
|
import { toast } from 'sonner';
|
|
@@ -2091,14 +2091,14 @@ var useIdleTimeVlmConfig = () => {
|
|
|
2091
2091
|
}
|
|
2092
2092
|
return context;
|
|
2093
2093
|
};
|
|
2094
|
-
var DashboardConfigContext =
|
|
2094
|
+
var DashboardConfigContext = React148.createContext(void 0);
|
|
2095
2095
|
var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
2096
|
-
const fullConfig =
|
|
2096
|
+
const fullConfig = React148.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
|
|
2097
2097
|
_setDashboardConfigInstance(fullConfig);
|
|
2098
|
-
|
|
2098
|
+
React148.useEffect(() => {
|
|
2099
2099
|
_setDashboardConfigInstance(fullConfig);
|
|
2100
2100
|
}, [fullConfig]);
|
|
2101
|
-
|
|
2101
|
+
React148.useEffect(() => {
|
|
2102
2102
|
if (!fullConfig.theme) return;
|
|
2103
2103
|
const styleId = "dashboard-core-theme-vars";
|
|
2104
2104
|
let styleEl = document.getElementById(styleId);
|
|
@@ -2124,7 +2124,7 @@ var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
|
2124
2124
|
return /* @__PURE__ */ jsx(DashboardConfigContext.Provider, { value: fullConfig, children: /* @__PURE__ */ jsx(IdleTimeVlmConfigProvider, { children }) });
|
|
2125
2125
|
};
|
|
2126
2126
|
var useDashboardConfig = () => {
|
|
2127
|
-
const ctx =
|
|
2127
|
+
const ctx = React148.useContext(DashboardConfigContext);
|
|
2128
2128
|
if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
|
|
2129
2129
|
return ctx;
|
|
2130
2130
|
};
|
|
@@ -9290,6 +9290,7 @@ var CLIP_COUNTS_CACHE_TTL = 30 * 1e3;
|
|
|
9290
9290
|
var CLIP_BY_ID_CACHE_TTL = 2 * 60 * 1e3;
|
|
9291
9291
|
var CLIP_BY_ID_CACHE_MAX = 200;
|
|
9292
9292
|
var CLIPS_INIT_CACHE_TTL = 30 * 1e3;
|
|
9293
|
+
var RECENT_FLOW_RED_STREAK_CLIP_TYPE = "recent_flow_red_streak";
|
|
9293
9294
|
var parseFiniteNumber = (value) => {
|
|
9294
9295
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
9295
9296
|
return value;
|
|
@@ -9885,6 +9886,7 @@ var S3ClipsSupabaseService = class {
|
|
|
9885
9886
|
case "long_cycle_time":
|
|
9886
9887
|
case "worst_cycle_time":
|
|
9887
9888
|
case "sop_deviations":
|
|
9889
|
+
case RECENT_FLOW_RED_STREAK_CLIP_TYPE:
|
|
9888
9890
|
return "high";
|
|
9889
9891
|
case "idle_time":
|
|
9890
9892
|
return "medium";
|
|
@@ -9905,7 +9907,8 @@ var S3ClipsSupabaseService = class {
|
|
|
9905
9907
|
"best_cycle_time": "Best Cycle Time Performance",
|
|
9906
9908
|
"worst_cycle_time": "Worst Cycle Time Performance",
|
|
9907
9909
|
"sop_deviations": "SOP Deviations",
|
|
9908
|
-
"cycle_completion": "Cycle Completion"
|
|
9910
|
+
"cycle_completion": "Cycle Completion",
|
|
9911
|
+
[RECENT_FLOW_RED_STREAK_CLIP_TYPE]: "Moments with low efficiency"
|
|
9909
9912
|
};
|
|
9910
9913
|
return clipType ? descriptions[clipType] || "Analysis Clip" : "Analysis Clip";
|
|
9911
9914
|
}
|
|
@@ -12827,7 +12830,7 @@ var useMobileMenu = () => {
|
|
|
12827
12830
|
};
|
|
12828
12831
|
var useHideMobileHeader = (shouldHide = true) => {
|
|
12829
12832
|
const context = useMobileMenu();
|
|
12830
|
-
|
|
12833
|
+
React148__default.useEffect(() => {
|
|
12831
12834
|
if (context && shouldHide) {
|
|
12832
12835
|
context.setHideMobileHeader(true);
|
|
12833
12836
|
return () => {
|
|
@@ -25910,7 +25913,7 @@ var MotionConfigContext = createContext({
|
|
|
25910
25913
|
});
|
|
25911
25914
|
|
|
25912
25915
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
|
|
25913
|
-
var PopChildMeasure = class extends
|
|
25916
|
+
var PopChildMeasure = class extends React148.Component {
|
|
25914
25917
|
getSnapshotBeforeUpdate(prevProps) {
|
|
25915
25918
|
const element = this.props.childRef.current;
|
|
25916
25919
|
if (element && prevProps.isPresent && !this.props.isPresent) {
|
|
@@ -25965,7 +25968,7 @@ function PopChild({ children, isPresent }) {
|
|
|
25965
25968
|
document.head.removeChild(style);
|
|
25966
25969
|
};
|
|
25967
25970
|
}, [isPresent]);
|
|
25968
|
-
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children:
|
|
25971
|
+
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React148.cloneElement(children, { ref }) });
|
|
25969
25972
|
}
|
|
25970
25973
|
|
|
25971
25974
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
|
|
@@ -26002,7 +26005,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
|
|
|
26002
26005
|
useMemo(() => {
|
|
26003
26006
|
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
|
26004
26007
|
}, [isPresent]);
|
|
26005
|
-
|
|
26008
|
+
React148.useEffect(() => {
|
|
26006
26009
|
!isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
|
|
26007
26010
|
}, [isPresent]);
|
|
26008
26011
|
if (mode === "popLayout") {
|
|
@@ -33787,7 +33790,7 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
33787
33790
|
requireAuth: true,
|
|
33788
33791
|
...options
|
|
33789
33792
|
};
|
|
33790
|
-
const WithAuthComponent =
|
|
33793
|
+
const WithAuthComponent = React148.memo(function WithAuthComponent2(props) {
|
|
33791
33794
|
const {
|
|
33792
33795
|
session,
|
|
33793
33796
|
user,
|
|
@@ -33798,9 +33801,9 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
33798
33801
|
retrySessionHydration
|
|
33799
33802
|
} = useAuth();
|
|
33800
33803
|
const router = useRouter();
|
|
33801
|
-
const [localLoading, setLocalLoading] =
|
|
33802
|
-
const [loadingTimeoutReached, setLoadingTimeoutReached] =
|
|
33803
|
-
|
|
33804
|
+
const [localLoading, setLocalLoading] = React148.useState(loading);
|
|
33805
|
+
const [loadingTimeoutReached, setLoadingTimeoutReached] = React148.useState(false);
|
|
33806
|
+
React148.useEffect(() => {
|
|
33804
33807
|
if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
|
|
33805
33808
|
console.log("withAuth state:", {
|
|
33806
33809
|
loading,
|
|
@@ -33812,7 +33815,7 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
33812
33815
|
});
|
|
33813
33816
|
}
|
|
33814
33817
|
}, [authStatus, error, loading, session, user]);
|
|
33815
|
-
const handleLoadingTimeout =
|
|
33818
|
+
const handleLoadingTimeout = React148.useCallback(() => {
|
|
33816
33819
|
console.warn("[withAuth] Loading timeout reached");
|
|
33817
33820
|
setLoadingTimeoutReached(true);
|
|
33818
33821
|
if (hasStoredSupabaseSession()) {
|
|
@@ -33824,13 +33827,13 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
33824
33827
|
router.replace(defaultOptions.redirectTo);
|
|
33825
33828
|
}
|
|
33826
33829
|
}, [retrySessionHydration, router]);
|
|
33827
|
-
|
|
33830
|
+
React148.useEffect(() => {
|
|
33828
33831
|
if (!loading && authStatus !== "recovering" && defaultOptions.requireAuth && !session && !error) {
|
|
33829
33832
|
console.log("[withAuth] No session found, redirecting to login");
|
|
33830
33833
|
router.replace(defaultOptions.redirectTo);
|
|
33831
33834
|
}
|
|
33832
33835
|
}, [authStatus, defaultOptions.requireAuth, error, loading, router, session]);
|
|
33833
|
-
|
|
33836
|
+
React148.useEffect(() => {
|
|
33834
33837
|
setLocalLoading(loading);
|
|
33835
33838
|
}, [loading]);
|
|
33836
33839
|
if (loading || localLoading) {
|
|
@@ -34829,11 +34832,11 @@ var BarChartComponent = ({
|
|
|
34829
34832
|
aspect = 2,
|
|
34830
34833
|
...restOfChartProps
|
|
34831
34834
|
}) => {
|
|
34832
|
-
const containerRef =
|
|
34833
|
-
const [containerReady, setContainerReady] =
|
|
34835
|
+
const containerRef = React148__default.useRef(null);
|
|
34836
|
+
const [containerReady, setContainerReady] = React148__default.useState(false);
|
|
34834
34837
|
const themeConfig = useThemeConfig();
|
|
34835
34838
|
const { formatNumber } = useFormatNumber();
|
|
34836
|
-
|
|
34839
|
+
React148__default.useEffect(() => {
|
|
34837
34840
|
const checkContainerDimensions = () => {
|
|
34838
34841
|
if (containerRef.current) {
|
|
34839
34842
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -34947,7 +34950,7 @@ var BarChartComponent = ({
|
|
|
34947
34950
|
}
|
|
34948
34951
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
34949
34952
|
};
|
|
34950
|
-
var BarChart =
|
|
34953
|
+
var BarChart = React148__default.memo(BarChartComponent, (prevProps, nextProps) => {
|
|
34951
34954
|
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || JSON.stringify(prevProps.referenceLines || []) !== JSON.stringify(nextProps.referenceLines || []) || prevProps.layout !== nextProps.layout || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect) {
|
|
34952
34955
|
return false;
|
|
34953
34956
|
}
|
|
@@ -34998,10 +35001,10 @@ var LineChartComponent = ({
|
|
|
34998
35001
|
fillContainer = false,
|
|
34999
35002
|
...restOfChartProps
|
|
35000
35003
|
}) => {
|
|
35001
|
-
const containerRef =
|
|
35002
|
-
const [dimensions, setDimensions] =
|
|
35003
|
-
const [hasValidData, setHasValidData] =
|
|
35004
|
-
|
|
35004
|
+
const containerRef = React148__default.useRef(null);
|
|
35005
|
+
const [dimensions, setDimensions] = React148__default.useState({ width: 0, height: 0 });
|
|
35006
|
+
const [hasValidData, setHasValidData] = React148__default.useState(false);
|
|
35007
|
+
React148__default.useEffect(() => {
|
|
35005
35008
|
const currentHasValidData = data && lines && lines.length > 0 && data.some(
|
|
35006
35009
|
(item) => lines.some((line) => {
|
|
35007
35010
|
const val = item[line.dataKey];
|
|
@@ -35012,7 +35015,7 @@ var LineChartComponent = ({
|
|
|
35012
35015
|
setHasValidData(true);
|
|
35013
35016
|
}
|
|
35014
35017
|
}, [data, lines, hasValidData]);
|
|
35015
|
-
|
|
35018
|
+
React148__default.useEffect(() => {
|
|
35016
35019
|
if (!containerRef.current) return;
|
|
35017
35020
|
const observer = new ResizeObserver((entries) => {
|
|
35018
35021
|
const entry = entries[0];
|
|
@@ -35137,7 +35140,7 @@ var LineChartComponent = ({
|
|
|
35137
35140
|
}
|
|
35138
35141
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
|
|
35139
35142
|
};
|
|
35140
|
-
var LineChart =
|
|
35143
|
+
var LineChart = React148__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
35141
35144
|
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect || JSON.stringify(prevProps.yAxisDomain) !== JSON.stringify(nextProps.yAxisDomain)) {
|
|
35142
35145
|
return false;
|
|
35143
35146
|
}
|
|
@@ -35304,7 +35307,7 @@ var SkuRow = ({ sku, isSelected, isLive, onSelect }) => {
|
|
|
35304
35307
|
);
|
|
35305
35308
|
};
|
|
35306
35309
|
var PerSkuView = ({ rows, className = "", selectedSkuId, liveSkuId, onSelectSku }) => {
|
|
35307
|
-
const ordered =
|
|
35310
|
+
const ordered = React148__default.useMemo(
|
|
35308
35311
|
() => [...rows].sort((a, b) => {
|
|
35309
35312
|
const am = (b.active_minutes ?? 0) - (a.active_minutes ?? 0);
|
|
35310
35313
|
if (am !== 0) return am;
|
|
@@ -35312,9 +35315,9 @@ var PerSkuView = ({ rows, className = "", selectedSkuId, liveSkuId, onSelectSku
|
|
|
35312
35315
|
}),
|
|
35313
35316
|
[rows]
|
|
35314
35317
|
);
|
|
35315
|
-
const scrollContainerRef =
|
|
35316
|
-
const [showScrollIndicatorBottom, setShowScrollIndicatorBottom] =
|
|
35317
|
-
const [showScrollIndicatorTop, setShowScrollIndicatorTop] =
|
|
35318
|
+
const scrollContainerRef = React148__default.useRef(null);
|
|
35319
|
+
const [showScrollIndicatorBottom, setShowScrollIndicatorBottom] = React148__default.useState(ordered.length > 4);
|
|
35320
|
+
const [showScrollIndicatorTop, setShowScrollIndicatorTop] = React148__default.useState(false);
|
|
35318
35321
|
const handleScroll = (e) => {
|
|
35319
35322
|
const target = e.currentTarget;
|
|
35320
35323
|
if (target.scrollHeight - target.scrollTop <= target.clientHeight + 10) {
|
|
@@ -35338,7 +35341,7 @@ var PerSkuView = ({ rows, className = "", selectedSkuId, liveSkuId, onSelectSku
|
|
|
35338
35341
|
scrollContainerRef.current.scrollBy({ top: -80, behavior: "smooth" });
|
|
35339
35342
|
}
|
|
35340
35343
|
};
|
|
35341
|
-
|
|
35344
|
+
React148__default.useEffect(() => {
|
|
35342
35345
|
if (scrollContainerRef.current) {
|
|
35343
35346
|
const target = scrollContainerRef.current;
|
|
35344
35347
|
setShowScrollIndicatorBottom(target.scrollHeight > target.clientHeight && target.scrollHeight - target.scrollTop > target.clientHeight + 10);
|
|
@@ -35411,7 +35414,7 @@ var OutputProgressChartComponent = ({
|
|
|
35411
35414
|
liveSkuId,
|
|
35412
35415
|
onSelectSku
|
|
35413
35416
|
}) => {
|
|
35414
|
-
const realSkuRows =
|
|
35417
|
+
const realSkuRows = React148__default.useMemo(
|
|
35415
35418
|
() => filterRealSkuBreakdown(skuBreakdown),
|
|
35416
35419
|
[skuBreakdown]
|
|
35417
35420
|
);
|
|
@@ -35436,7 +35439,7 @@ var OutputProgressChartComponent = ({
|
|
|
35436
35439
|
}
|
|
35437
35440
|
);
|
|
35438
35441
|
};
|
|
35439
|
-
var OutputProgressChart =
|
|
35442
|
+
var OutputProgressChart = React148__default.memo(OutputProgressChartComponent);
|
|
35440
35443
|
OutputProgressChart.displayName = "OutputProgressChart";
|
|
35441
35444
|
var LargeOutputProgressChart = ({
|
|
35442
35445
|
currentOutput,
|
|
@@ -35576,7 +35579,7 @@ var CycleTimeChartComponent = ({
|
|
|
35576
35579
|
}
|
|
35577
35580
|
) }) });
|
|
35578
35581
|
};
|
|
35579
|
-
var CycleTimeChart =
|
|
35582
|
+
var CycleTimeChart = React148__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
|
|
35580
35583
|
if (prevProps.className !== nextProps.className) {
|
|
35581
35584
|
return false;
|
|
35582
35585
|
}
|
|
@@ -35816,16 +35819,16 @@ var CycleTimeOverTimeChart = ({
|
|
|
35816
35819
|
onHourClick
|
|
35817
35820
|
}) => {
|
|
35818
35821
|
const MAX_DATA_POINTS = 40;
|
|
35819
|
-
const containerRef =
|
|
35820
|
-
const [dimensions, setDimensions] =
|
|
35821
|
-
const [hasValidData, setHasValidData] =
|
|
35822
|
-
|
|
35822
|
+
const containerRef = React148__default.useRef(null);
|
|
35823
|
+
const [dimensions, setDimensions] = React148__default.useState({ width: 0, height: 0 });
|
|
35824
|
+
const [hasValidData, setHasValidData] = React148__default.useState(false);
|
|
35825
|
+
React148__default.useEffect(() => {
|
|
35823
35826
|
const currentHasValidData = data && data.some((val) => val !== null && val > 0);
|
|
35824
35827
|
if (currentHasValidData && !hasValidData) {
|
|
35825
35828
|
setHasValidData(true);
|
|
35826
35829
|
}
|
|
35827
35830
|
}, [data, hasValidData]);
|
|
35828
|
-
|
|
35831
|
+
React148__default.useEffect(() => {
|
|
35829
35832
|
if (!containerRef.current) return;
|
|
35830
35833
|
const observer = new ResizeObserver((entries) => {
|
|
35831
35834
|
const entry = entries[0];
|
|
@@ -35863,7 +35866,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
35863
35866
|
const endLabel = shiftEnd && slotIndex === DURATION - 1 ? formatHourLabel(slotIndex + 1) : formatHourLabel(slotIndex + 1);
|
|
35864
35867
|
return `${startLabel} - ${endLabel}`;
|
|
35865
35868
|
};
|
|
35866
|
-
const getDisplayData =
|
|
35869
|
+
const getDisplayData = React148__default.useCallback((rawData) => {
|
|
35867
35870
|
if (xAxisMode === "hourly") return rawData;
|
|
35868
35871
|
return rawData.slice(Math.max(0, rawData.length - MAX_DATA_POINTS));
|
|
35869
35872
|
}, [xAxisMode]);
|
|
@@ -35871,7 +35874,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
35871
35874
|
const DURATION = displayData.length;
|
|
35872
35875
|
const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
|
|
35873
35876
|
const finalData = displayData;
|
|
35874
|
-
const labelInterval =
|
|
35877
|
+
const labelInterval = React148__default.useMemo(() => {
|
|
35875
35878
|
if (xAxisMode === "hourly") {
|
|
35876
35879
|
return Math.max(1, Math.ceil(DURATION / 8));
|
|
35877
35880
|
}
|
|
@@ -35912,8 +35915,8 @@ var CycleTimeOverTimeChart = ({
|
|
|
35912
35915
|
return `${minutes} minutes ${seconds} seconds ago`;
|
|
35913
35916
|
}
|
|
35914
35917
|
};
|
|
35915
|
-
const getNumericValue =
|
|
35916
|
-
const buildHourClickPayload =
|
|
35918
|
+
const getNumericValue = React148__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
|
|
35919
|
+
const buildHourClickPayload = React148__default.useCallback((dataPoint) => {
|
|
35917
35920
|
if (!onHourClick || xAxisMode !== "hourly") {
|
|
35918
35921
|
return null;
|
|
35919
35922
|
}
|
|
@@ -35932,7 +35935,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
35932
35935
|
status: cycleTime !== null && cycleTime <= idealCycleTime ? "within_standard" : "above_standard"
|
|
35933
35936
|
};
|
|
35934
35937
|
}, [DURATION, getNumericValue, idealCycleTime, onHourClick, shiftEnd, shiftStart, xAxisMode]);
|
|
35935
|
-
const renderChartTooltip =
|
|
35938
|
+
const renderChartTooltip = React148__default.useCallback((tooltipProps) => {
|
|
35936
35939
|
const { active, payload } = tooltipProps;
|
|
35937
35940
|
if (!active || !Array.isArray(payload) || payload.length === 0) {
|
|
35938
35941
|
return null;
|
|
@@ -35996,7 +35999,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
35996
35999
|
] })
|
|
35997
36000
|
] });
|
|
35998
36001
|
}, [getNumericValue, onHourClick, shiftStart, showIdleTime, xAxisMode]);
|
|
35999
|
-
const renderCycleDot =
|
|
36002
|
+
const renderCycleDot = React148__default.useCallback((props) => {
|
|
36000
36003
|
const { cx: cx2, cy, payload } = props;
|
|
36001
36004
|
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
36002
36005
|
if (cycleTime === null) {
|
|
@@ -36036,7 +36039,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
36036
36039
|
}
|
|
36037
36040
|
);
|
|
36038
36041
|
}, [buildHourClickPayload, getNumericValue, idealCycleTime, onHourClick, selectedHourIndex]);
|
|
36039
|
-
const renderCycleActiveDot =
|
|
36042
|
+
const renderCycleActiveDot = React148__default.useCallback((props) => {
|
|
36040
36043
|
const { cx: cx2, cy, payload } = props;
|
|
36041
36044
|
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
36042
36045
|
if (cycleTime === null) {
|
|
@@ -36065,7 +36068,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
36065
36068
|
}
|
|
36066
36069
|
);
|
|
36067
36070
|
}, [buildHourClickPayload, getNumericValue, idealCycleTime, onHourClick, selectedHourIndex]);
|
|
36068
|
-
const renderIdleDot =
|
|
36071
|
+
const renderIdleDot = React148__default.useCallback((props) => {
|
|
36069
36072
|
const { cx: cx2, cy, payload } = props;
|
|
36070
36073
|
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
36071
36074
|
if (idleMinutes === null) {
|
|
@@ -36087,7 +36090,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
36087
36090
|
}
|
|
36088
36091
|
);
|
|
36089
36092
|
}, [getNumericValue, showIdleTime]);
|
|
36090
|
-
const renderIdleActiveDot =
|
|
36093
|
+
const renderIdleActiveDot = React148__default.useCallback((props) => {
|
|
36091
36094
|
const { cx: cx2, cy, payload } = props;
|
|
36092
36095
|
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
36093
36096
|
if (idleMinutes === null || !showIdleTime) {
|
|
@@ -36105,7 +36108,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
36105
36108
|
}
|
|
36106
36109
|
);
|
|
36107
36110
|
}, [getNumericValue, showIdleTime]);
|
|
36108
|
-
const chartData =
|
|
36111
|
+
const chartData = React148__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
|
|
36109
36112
|
const cycleTime = getNumericValue(finalData[i]);
|
|
36110
36113
|
const useIdleSlots = idleTimeSlots.length > 0;
|
|
36111
36114
|
const idleSlot = useIdleSlots ? idleTimeSlots[i] ?? null : null;
|
|
@@ -36302,7 +36305,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
36302
36305
|
}
|
|
36303
36306
|
);
|
|
36304
36307
|
};
|
|
36305
|
-
var Card =
|
|
36308
|
+
var Card = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
36306
36309
|
"div",
|
|
36307
36310
|
{
|
|
36308
36311
|
ref,
|
|
@@ -36314,7 +36317,7 @@ var Card = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
36314
36317
|
}
|
|
36315
36318
|
));
|
|
36316
36319
|
Card.displayName = "Card";
|
|
36317
|
-
var CardHeader =
|
|
36320
|
+
var CardHeader = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
36318
36321
|
"div",
|
|
36319
36322
|
{
|
|
36320
36323
|
ref,
|
|
@@ -36323,7 +36326,7 @@ var CardHeader = React147.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
36323
36326
|
}
|
|
36324
36327
|
));
|
|
36325
36328
|
CardHeader.displayName = "CardHeader";
|
|
36326
|
-
var CardTitle =
|
|
36329
|
+
var CardTitle = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
36327
36330
|
"h3",
|
|
36328
36331
|
{
|
|
36329
36332
|
ref,
|
|
@@ -36335,7 +36338,7 @@ var CardTitle = React147.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
36335
36338
|
}
|
|
36336
36339
|
));
|
|
36337
36340
|
CardTitle.displayName = "CardTitle";
|
|
36338
|
-
var CardDescription =
|
|
36341
|
+
var CardDescription = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
36339
36342
|
"p",
|
|
36340
36343
|
{
|
|
36341
36344
|
ref,
|
|
@@ -36344,9 +36347,9 @@ var CardDescription = React147.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
36344
36347
|
}
|
|
36345
36348
|
));
|
|
36346
36349
|
CardDescription.displayName = "CardDescription";
|
|
36347
|
-
var CardContent =
|
|
36350
|
+
var CardContent = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
|
|
36348
36351
|
CardContent.displayName = "CardContent";
|
|
36349
|
-
var CardFooter =
|
|
36352
|
+
var CardFooter = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
36350
36353
|
"div",
|
|
36351
36354
|
{
|
|
36352
36355
|
ref,
|
|
@@ -36422,7 +36425,7 @@ var buttonVariants = cva(
|
|
|
36422
36425
|
}
|
|
36423
36426
|
}
|
|
36424
36427
|
);
|
|
36425
|
-
var Button =
|
|
36428
|
+
var Button = React148.forwardRef(
|
|
36426
36429
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
36427
36430
|
const Comp = asChild ? Slot : "button";
|
|
36428
36431
|
return /* @__PURE__ */ jsx(
|
|
@@ -37180,14 +37183,14 @@ var HourlyOutputChartComponent = ({
|
|
|
37180
37183
|
onAiSummaryClick,
|
|
37181
37184
|
className = ""
|
|
37182
37185
|
}) => {
|
|
37183
|
-
const containerRef =
|
|
37184
|
-
const [containerReady, setContainerReady] =
|
|
37185
|
-
const [containerWidth, setContainerWidth] =
|
|
37186
|
-
const [hoveredSkuRailLabel, setHoveredSkuRailLabel] =
|
|
37187
|
-
const [isTooltipHovered, setIsTooltipHovered] =
|
|
37188
|
-
const lastTooltipDataRef =
|
|
37189
|
-
const tooltipHoverTimeoutRef =
|
|
37190
|
-
const idleSlots =
|
|
37186
|
+
const containerRef = React148__default.useRef(null);
|
|
37187
|
+
const [containerReady, setContainerReady] = React148__default.useState(false);
|
|
37188
|
+
const [containerWidth, setContainerWidth] = React148__default.useState(0);
|
|
37189
|
+
const [hoveredSkuRailLabel, setHoveredSkuRailLabel] = React148__default.useState(null);
|
|
37190
|
+
const [isTooltipHovered, setIsTooltipHovered] = React148__default.useState(false);
|
|
37191
|
+
const lastTooltipDataRef = React148__default.useRef(null);
|
|
37192
|
+
const tooltipHoverTimeoutRef = React148__default.useRef(null);
|
|
37193
|
+
const idleSlots = React148__default.useMemo(
|
|
37191
37194
|
() => buildHourlyIdleSlots({
|
|
37192
37195
|
idleTimeHourly,
|
|
37193
37196
|
shiftStart,
|
|
@@ -37196,12 +37199,12 @@ var HourlyOutputChartComponent = ({
|
|
|
37196
37199
|
[idleTimeHourly, shiftStart, shiftEnd]
|
|
37197
37200
|
);
|
|
37198
37201
|
const SHIFT_DURATION = idleSlots.length;
|
|
37199
|
-
const [animatedData, setAnimatedData] =
|
|
37202
|
+
const [animatedData, setAnimatedData] = React148__default.useState(
|
|
37200
37203
|
() => Array(SHIFT_DURATION).fill(0)
|
|
37201
37204
|
);
|
|
37202
|
-
const prevDataRef =
|
|
37203
|
-
const animationFrameRef =
|
|
37204
|
-
|
|
37205
|
+
const prevDataRef = React148__default.useRef(Array(SHIFT_DURATION).fill(0));
|
|
37206
|
+
const animationFrameRef = React148__default.useRef(null);
|
|
37207
|
+
React148__default.useEffect(() => {
|
|
37205
37208
|
setAnimatedData((prev) => {
|
|
37206
37209
|
if (prev.length !== SHIFT_DURATION) {
|
|
37207
37210
|
return Array(SHIFT_DURATION).fill(0);
|
|
@@ -37210,14 +37213,14 @@ var HourlyOutputChartComponent = ({
|
|
|
37210
37213
|
});
|
|
37211
37214
|
prevDataRef.current = Array(SHIFT_DURATION).fill(0);
|
|
37212
37215
|
}, [SHIFT_DURATION]);
|
|
37213
|
-
const [idleBarState, setIdleBarState] =
|
|
37216
|
+
const [idleBarState, setIdleBarState] = React148__default.useState({
|
|
37214
37217
|
visible: showIdleTime,
|
|
37215
37218
|
key: 0,
|
|
37216
37219
|
shouldAnimate: false
|
|
37217
37220
|
});
|
|
37218
|
-
const prevShowIdleTimeRef =
|
|
37219
|
-
const stateUpdateTimeoutRef =
|
|
37220
|
-
|
|
37221
|
+
const prevShowIdleTimeRef = React148__default.useRef(showIdleTime);
|
|
37222
|
+
const stateUpdateTimeoutRef = React148__default.useRef(null);
|
|
37223
|
+
React148__default.useEffect(() => {
|
|
37221
37224
|
if (stateUpdateTimeoutRef.current) {
|
|
37222
37225
|
clearTimeout(stateUpdateTimeoutRef.current);
|
|
37223
37226
|
}
|
|
@@ -37242,7 +37245,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37242
37245
|
}
|
|
37243
37246
|
};
|
|
37244
37247
|
}, [showIdleTime]);
|
|
37245
|
-
const animateToNewData =
|
|
37248
|
+
const animateToNewData = React148__default.useCallback((targetData) => {
|
|
37246
37249
|
const startData = [...prevDataRef.current];
|
|
37247
37250
|
const startTime = performance.now();
|
|
37248
37251
|
const duration = 1200;
|
|
@@ -37272,7 +37275,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37272
37275
|
}
|
|
37273
37276
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
37274
37277
|
}, []);
|
|
37275
|
-
|
|
37278
|
+
React148__default.useEffect(() => {
|
|
37276
37279
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
37277
37280
|
const shiftData = data.slice(0, SHIFT_DURATION);
|
|
37278
37281
|
animateToNewData(shiftData);
|
|
@@ -37283,14 +37286,14 @@ var HourlyOutputChartComponent = ({
|
|
|
37283
37286
|
}
|
|
37284
37287
|
};
|
|
37285
37288
|
}, [data, animateToNewData]);
|
|
37286
|
-
|
|
37289
|
+
React148__default.useEffect(() => {
|
|
37287
37290
|
return () => {
|
|
37288
37291
|
if (tooltipHoverTimeoutRef.current) {
|
|
37289
37292
|
clearTimeout(tooltipHoverTimeoutRef.current);
|
|
37290
37293
|
}
|
|
37291
37294
|
};
|
|
37292
37295
|
}, []);
|
|
37293
|
-
|
|
37296
|
+
React148__default.useEffect(() => {
|
|
37294
37297
|
const checkContainerDimensions = () => {
|
|
37295
37298
|
if (containerRef.current) {
|
|
37296
37299
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -37316,7 +37319,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37316
37319
|
clearTimeout(fallbackTimeout);
|
|
37317
37320
|
};
|
|
37318
37321
|
}, []);
|
|
37319
|
-
const xAxisConfig =
|
|
37322
|
+
const xAxisConfig = React148__default.useMemo(() => {
|
|
37320
37323
|
if (containerWidth >= 960) {
|
|
37321
37324
|
return {
|
|
37322
37325
|
interval: 0,
|
|
@@ -37337,13 +37340,13 @@ var HourlyOutputChartComponent = ({
|
|
|
37337
37340
|
}
|
|
37338
37341
|
return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6 };
|
|
37339
37342
|
}, [containerWidth]);
|
|
37340
|
-
const shiftWindow =
|
|
37343
|
+
const shiftWindow = React148__default.useMemo(() => resolveShiftWindow2({
|
|
37341
37344
|
shiftStart,
|
|
37342
37345
|
slotCount: SHIFT_DURATION,
|
|
37343
37346
|
shiftDate,
|
|
37344
37347
|
timezone
|
|
37345
37348
|
}), [shiftStart, shiftEnd, SHIFT_DURATION, shiftDate, timezone]);
|
|
37346
|
-
const fallbackTimelineEndOffset =
|
|
37349
|
+
const fallbackTimelineEndOffset = React148__default.useMemo(
|
|
37347
37350
|
() => resolveTimelineEndOffset({
|
|
37348
37351
|
shiftStart,
|
|
37349
37352
|
shiftEnd,
|
|
@@ -37353,7 +37356,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37353
37356
|
}),
|
|
37354
37357
|
[shiftStart, shiftEnd, SHIFT_DURATION, shiftDate, timezone]
|
|
37355
37358
|
);
|
|
37356
|
-
const observedTimelineEndOffset =
|
|
37359
|
+
const observedTimelineEndOffset = React148__default.useMemo(() => {
|
|
37357
37360
|
let lastObservedMinute = -1;
|
|
37358
37361
|
idleSlots.forEach((slot) => {
|
|
37359
37362
|
slot.idleArray.forEach((value, minuteIndex) => {
|
|
@@ -37369,7 +37372,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37369
37372
|
return Math.min((lastObservedMinute + 1) / 60, SHIFT_DURATION);
|
|
37370
37373
|
}, [idleSlots, SHIFT_DURATION]);
|
|
37371
37374
|
const timelineEndOffset = observedTimelineEndOffset ?? fallbackTimelineEndOffset;
|
|
37372
|
-
const targetLineEndOffset =
|
|
37375
|
+
const targetLineEndOffset = React148__default.useMemo(() => {
|
|
37373
37376
|
if (timelineEndOffset >= SHIFT_DURATION) {
|
|
37374
37377
|
return SHIFT_DURATION;
|
|
37375
37378
|
}
|
|
@@ -37378,7 +37381,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37378
37381
|
}
|
|
37379
37382
|
return Math.min(Math.floor(timelineEndOffset) + 1, SHIFT_DURATION);
|
|
37380
37383
|
}, [timelineEndOffset, SHIFT_DURATION]);
|
|
37381
|
-
const skuTimelineSegments =
|
|
37384
|
+
const skuTimelineSegments = React148__default.useMemo(() => {
|
|
37382
37385
|
if (!skuSegments || skuSegments.length === 0 || !shiftWindow || timelineEndOffset <= 0) {
|
|
37383
37386
|
return [];
|
|
37384
37387
|
}
|
|
@@ -37412,18 +37415,18 @@ var HourlyOutputChartComponent = ({
|
|
|
37412
37415
|
};
|
|
37413
37416
|
}).filter((segment) => segment.end > segment.start);
|
|
37414
37417
|
}, [skuSegments, shiftWindow, timelineEndOffset, pphThreshold]);
|
|
37415
|
-
const targetTimelineSegments =
|
|
37418
|
+
const targetTimelineSegments = React148__default.useMemo(() => {
|
|
37416
37419
|
if (skuTimelineSegments.length === 0) return [];
|
|
37417
37420
|
return skuTimelineSegments.map((segment, index) => ({
|
|
37418
37421
|
...segment,
|
|
37419
37422
|
end: index === skuTimelineSegments.length - 1 ? Math.max(segment.start, targetLineEndOffset) : segment.end
|
|
37420
37423
|
})).filter((segment) => segment.end > segment.start);
|
|
37421
37424
|
}, [skuTimelineSegments, targetLineEndOffset]);
|
|
37422
|
-
const hasExplicitHourlyTargetOutputProp =
|
|
37425
|
+
const hasExplicitHourlyTargetOutputProp = React148__default.useMemo(
|
|
37423
37426
|
() => hourlyTargetOutput !== void 0,
|
|
37424
37427
|
[hourlyTargetOutput]
|
|
37425
37428
|
);
|
|
37426
|
-
const fallbackHourlyTargetOutput =
|
|
37429
|
+
const fallbackHourlyTargetOutput = React148__default.useMemo(() => {
|
|
37427
37430
|
if (hasExplicitHourlyTargetOutputProp) return void 0;
|
|
37428
37431
|
if (skuTimelineSegments.length > 0) return void 0;
|
|
37429
37432
|
const plan = buildHourlyTargetPlan({
|
|
@@ -37443,19 +37446,19 @@ var HourlyOutputChartComponent = ({
|
|
|
37443
37446
|
shiftBreaks,
|
|
37444
37447
|
pphThreshold
|
|
37445
37448
|
]);
|
|
37446
|
-
const effectiveHourlyTargetOutput =
|
|
37449
|
+
const effectiveHourlyTargetOutput = React148__default.useMemo(
|
|
37447
37450
|
() => hasExplicitHourlyTargetOutputProp ? hourlyTargetOutput : fallbackHourlyTargetOutput,
|
|
37448
37451
|
[hasExplicitHourlyTargetOutputProp, hourlyTargetOutput, fallbackHourlyTargetOutput]
|
|
37449
37452
|
);
|
|
37450
|
-
const hasHourlyTargetOutputProp =
|
|
37453
|
+
const hasHourlyTargetOutputProp = React148__default.useMemo(
|
|
37451
37454
|
() => effectiveHourlyTargetOutput !== void 0,
|
|
37452
37455
|
[effectiveHourlyTargetOutput]
|
|
37453
37456
|
);
|
|
37454
|
-
const hasExplicitHourlyTargets =
|
|
37457
|
+
const hasExplicitHourlyTargets = React148__default.useMemo(
|
|
37455
37458
|
() => Array.isArray(effectiveHourlyTargetOutput) && effectiveHourlyTargetOutput.some((value) => value !== null && value !== void 0),
|
|
37456
37459
|
[effectiveHourlyTargetOutput]
|
|
37457
37460
|
);
|
|
37458
|
-
const hourlyTargetSegments =
|
|
37461
|
+
const hourlyTargetSegments = React148__default.useMemo(() => {
|
|
37459
37462
|
if (!hasExplicitHourlyTargets) return [];
|
|
37460
37463
|
const segments = [];
|
|
37461
37464
|
let runStart = null;
|
|
@@ -37487,7 +37490,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37487
37490
|
flush(SHIFT_DURATION);
|
|
37488
37491
|
return segments.filter((segment) => segment.end > segment.start);
|
|
37489
37492
|
}, [SHIFT_DURATION, hasExplicitHourlyTargets, effectiveHourlyTargetOutput]);
|
|
37490
|
-
const activeSkuHourIndices =
|
|
37493
|
+
const activeSkuHourIndices = React148__default.useMemo(() => {
|
|
37491
37494
|
const indices = /* @__PURE__ */ new Set();
|
|
37492
37495
|
const targets = Array(SHIFT_DURATION).fill(pphThreshold);
|
|
37493
37496
|
if (!skuSegments || !shiftWindow) return { indices, targets, hasTimeline: false };
|
|
@@ -37520,7 +37523,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37520
37523
|
}
|
|
37521
37524
|
return { indices, targets, hasTimeline: true };
|
|
37522
37525
|
}, [skuSegments, activeSkuId, shiftWindow, SHIFT_DURATION, pphThreshold]);
|
|
37523
|
-
const chartData =
|
|
37526
|
+
const chartData = React148__default.useMemo(() => {
|
|
37524
37527
|
const { indices, targets, hasTimeline } = activeSkuHourIndices;
|
|
37525
37528
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
37526
37529
|
const idleSlot = idleSlots[i];
|
|
@@ -37549,7 +37552,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37549
37552
|
};
|
|
37550
37553
|
});
|
|
37551
37554
|
}, [animatedData, data, pphThreshold, idleSlots, SHIFT_DURATION, activeSkuHourIndices, activeSkuId, effectiveHourlyTargetOutput, hasHourlyTargetOutputProp, selectedHourIndex]);
|
|
37552
|
-
const renderSkuTimelineRail =
|
|
37555
|
+
const renderSkuTimelineRail = React148__default.useCallback((props) => {
|
|
37553
37556
|
if (!skuTimelineSegments.length || SHIFT_DURATION <= 0) return null;
|
|
37554
37557
|
const offset = props?.offset;
|
|
37555
37558
|
if (!offset) return null;
|
|
@@ -37698,7 +37701,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37698
37701
|
})
|
|
37699
37702
|
] });
|
|
37700
37703
|
}, [skuTimelineSegments, SHIFT_DURATION, activeSkuId]);
|
|
37701
|
-
const IdleBar =
|
|
37704
|
+
const IdleBar = React148__default.useMemo(() => {
|
|
37702
37705
|
if (!idleBarState.visible) return null;
|
|
37703
37706
|
return /* @__PURE__ */ jsx(
|
|
37704
37707
|
Bar,
|
|
@@ -37792,7 +37795,7 @@ var HourlyOutputChartComponent = ({
|
|
|
37792
37795
|
}
|
|
37793
37796
|
return filteredTicks;
|
|
37794
37797
|
};
|
|
37795
|
-
const renderTargetLine =
|
|
37798
|
+
const renderTargetLine = React148__default.useCallback((props) => {
|
|
37796
37799
|
const { offset, yAxisMap } = props;
|
|
37797
37800
|
if (!offset || !yAxisMap || SHIFT_DURATION <= 0 || targetLineEndOffset <= 0) return null;
|
|
37798
37801
|
const { left, width } = offset;
|
|
@@ -38293,7 +38296,7 @@ var HourlyOutputChartComponent = ({
|
|
|
38293
38296
|
}
|
|
38294
38297
|
);
|
|
38295
38298
|
};
|
|
38296
|
-
var HourlyOutputChart =
|
|
38299
|
+
var HourlyOutputChart = React148__default.memo(
|
|
38297
38300
|
HourlyOutputChartComponent,
|
|
38298
38301
|
(prevProps, nextProps) => {
|
|
38299
38302
|
if (prevProps.pphThreshold !== nextProps.pphThreshold || prevProps.shiftStart !== nextProps.shiftStart || prevProps.shiftEnd !== nextProps.shiftEnd || prevProps.shiftDate !== nextProps.shiftDate || prevProps.timezone !== nextProps.timezone || prevProps.showIdleTime !== nextProps.showIdleTime || prevProps.activeSkuId !== nextProps.activeSkuId || prevProps.selectedHourIndex !== nextProps.selectedHourIndex || prevProps.onHourClick !== nextProps.onHourClick || prevProps.className !== nextProps.className) {
|
|
@@ -38747,7 +38750,7 @@ function getTrendArrowAndColor(trend) {
|
|
|
38747
38750
|
return { arrow: "\u2192", color: "text-gray-400" };
|
|
38748
38751
|
}
|
|
38749
38752
|
}
|
|
38750
|
-
var VideoCard =
|
|
38753
|
+
var VideoCard = React148__default.memo(({
|
|
38751
38754
|
workspace,
|
|
38752
38755
|
hlsUrl,
|
|
38753
38756
|
shouldPlay,
|
|
@@ -39017,7 +39020,7 @@ var hasRecentHealthSignal = (lastHeartbeat) => {
|
|
|
39017
39020
|
if (!Number.isFinite(heartbeatMs)) return false;
|
|
39018
39021
|
return Date.now() - heartbeatMs <= RECENT_HEALTH_SIGNAL_MS;
|
|
39019
39022
|
};
|
|
39020
|
-
var VideoGridView =
|
|
39023
|
+
var VideoGridView = React148__default.memo(({
|
|
39021
39024
|
workspaces,
|
|
39022
39025
|
blueComparisonWorkspaces,
|
|
39023
39026
|
selectedLine,
|
|
@@ -39456,7 +39459,7 @@ var VideoGridView = React147__default.memo(({
|
|
|
39456
39459
|
) });
|
|
39457
39460
|
});
|
|
39458
39461
|
VideoGridView.displayName = "VideoGridView";
|
|
39459
|
-
var MapGridView =
|
|
39462
|
+
var MapGridView = React148__default.memo(({
|
|
39460
39463
|
workspaces,
|
|
39461
39464
|
className = "",
|
|
39462
39465
|
displayNames = {},
|
|
@@ -39677,13 +39680,13 @@ var WorkspaceMetricCardsImpl = ({
|
|
|
39677
39680
|
liveSkuId
|
|
39678
39681
|
}) => {
|
|
39679
39682
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
39680
|
-
const activeSku =
|
|
39683
|
+
const activeSku = React148__default.useMemo(() => {
|
|
39681
39684
|
if (skuAware && activeSkuId && skuBreakdown) {
|
|
39682
39685
|
return skuBreakdown.find((s) => s.sku_id === activeSkuId);
|
|
39683
39686
|
}
|
|
39684
39687
|
return null;
|
|
39685
39688
|
}, [skuAware, activeSkuId, skuBreakdown]);
|
|
39686
|
-
const displaySku =
|
|
39689
|
+
const displaySku = React148__default.useMemo(() => {
|
|
39687
39690
|
if (activeSku) return activeSku;
|
|
39688
39691
|
if (skuAware && !activeSkuId && liveSkuId && skuBreakdown) {
|
|
39689
39692
|
return skuBreakdown.find((s) => s.sku_id === liveSkuId) ?? null;
|
|
@@ -40337,7 +40340,7 @@ var UptimeLineChartComponent = ({ points, className = "" }) => {
|
|
|
40337
40340
|
)
|
|
40338
40341
|
] }) }) });
|
|
40339
40342
|
};
|
|
40340
|
-
var UptimeLineChart =
|
|
40343
|
+
var UptimeLineChart = React148__default.memo(UptimeLineChartComponent);
|
|
40341
40344
|
var getTimeFromTimeString = (timeStr) => {
|
|
40342
40345
|
if (!timeStr) {
|
|
40343
40346
|
return { hour: 0, minute: 0, decimalHour: 0 };
|
|
@@ -40361,10 +40364,10 @@ var HourlyUptimeChartComponent = ({
|
|
|
40361
40364
|
shiftBreaks,
|
|
40362
40365
|
className = ""
|
|
40363
40366
|
}) => {
|
|
40364
|
-
const containerRef =
|
|
40365
|
-
const [containerReady, setContainerReady] =
|
|
40366
|
-
const [containerWidth, setContainerWidth] =
|
|
40367
|
-
const uptimeSeries =
|
|
40367
|
+
const containerRef = React148__default.useRef(null);
|
|
40368
|
+
const [containerReady, setContainerReady] = React148__default.useState(false);
|
|
40369
|
+
const [containerWidth, setContainerWidth] = React148__default.useState(0);
|
|
40370
|
+
const uptimeSeries = React148__default.useMemo(() => buildUptimeSeries({
|
|
40368
40371
|
idleTimeHourly,
|
|
40369
40372
|
shiftStart,
|
|
40370
40373
|
shiftEnd,
|
|
@@ -40374,11 +40377,11 @@ var HourlyUptimeChartComponent = ({
|
|
|
40374
40377
|
shiftBreaks
|
|
40375
40378
|
}), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes, shiftBreaks]);
|
|
40376
40379
|
const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
|
|
40377
|
-
const shiftStartTime =
|
|
40380
|
+
const shiftStartTime = React148__default.useMemo(
|
|
40378
40381
|
() => getTimeFromTimeString(shiftStart),
|
|
40379
40382
|
[shiftStart]
|
|
40380
40383
|
);
|
|
40381
|
-
const { shiftDuration, shiftEndTime } =
|
|
40384
|
+
const { shiftDuration, shiftEndTime } = React148__default.useMemo(() => {
|
|
40382
40385
|
if (!shiftEnd) {
|
|
40383
40386
|
const fallbackHours = uptimeSeries.shiftMinutes > 0 ? Math.ceil(uptimeSeries.shiftMinutes / 60) : 0;
|
|
40384
40387
|
return { shiftDuration: fallbackHours, shiftEndTime: null };
|
|
@@ -40392,7 +40395,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40392
40395
|
const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
|
|
40393
40396
|
return { shiftDuration: hourCount, shiftEndTime: endTime };
|
|
40394
40397
|
}, [shiftEnd, shiftStartTime.decimalHour, uptimeSeries.shiftMinutes]);
|
|
40395
|
-
const formatHour =
|
|
40398
|
+
const formatHour = React148__default.useCallback((hourIndex) => {
|
|
40396
40399
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
40397
40400
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
40398
40401
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -40417,7 +40420,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40417
40420
|
};
|
|
40418
40421
|
return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
|
|
40419
40422
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
40420
|
-
const formatTimeRange2 =
|
|
40423
|
+
const formatTimeRange2 = React148__default.useCallback((hourIndex) => {
|
|
40421
40424
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
40422
40425
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
40423
40426
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -40439,7 +40442,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40439
40442
|
};
|
|
40440
40443
|
return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
|
|
40441
40444
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
40442
|
-
const chartData =
|
|
40445
|
+
const chartData = React148__default.useMemo(() => {
|
|
40443
40446
|
if (shiftDuration <= 0) return [];
|
|
40444
40447
|
if (hasAggregateData) {
|
|
40445
40448
|
return hourlyAggregates.map((entry, hourIndex) => ({
|
|
@@ -40481,7 +40484,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40481
40484
|
}, [hasAggregateData, hourlyAggregates, uptimeSeries.points, uptimeSeries.elapsedMinutes, uptimeSeries.shiftMinutes, shiftDuration, formatHour, formatTimeRange2]);
|
|
40482
40485
|
const maxYValue = 100;
|
|
40483
40486
|
const yAxisTicks = [0, 25, 50, 75, 100];
|
|
40484
|
-
|
|
40487
|
+
React148__default.useEffect(() => {
|
|
40485
40488
|
const checkContainerDimensions = () => {
|
|
40486
40489
|
if (containerRef.current) {
|
|
40487
40490
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -40507,7 +40510,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40507
40510
|
clearTimeout(fallbackTimeout);
|
|
40508
40511
|
};
|
|
40509
40512
|
}, []);
|
|
40510
|
-
const xAxisConfig =
|
|
40513
|
+
const xAxisConfig = React148__default.useMemo(() => {
|
|
40511
40514
|
if (containerWidth >= 960) {
|
|
40512
40515
|
return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12, labelMode: "full" };
|
|
40513
40516
|
}
|
|
@@ -40516,7 +40519,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40516
40519
|
}
|
|
40517
40520
|
return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6, labelMode: "start" };
|
|
40518
40521
|
}, [containerWidth]);
|
|
40519
|
-
const formatXAxisTick =
|
|
40522
|
+
const formatXAxisTick = React148__default.useCallback((raw) => {
|
|
40520
40523
|
const label = typeof raw === "string" ? raw : String(raw);
|
|
40521
40524
|
if (xAxisConfig.labelMode === "full") return label;
|
|
40522
40525
|
const parts = label.split("-");
|
|
@@ -40722,7 +40725,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40722
40725
|
}
|
|
40723
40726
|
);
|
|
40724
40727
|
};
|
|
40725
|
-
var HourlyUptimeChart =
|
|
40728
|
+
var HourlyUptimeChart = React148__default.memo(HourlyUptimeChartComponent);
|
|
40726
40729
|
var DEFAULT_COLORS2 = ["#00AB45", "#ef4444"];
|
|
40727
40730
|
var UptimeDonutChartComponent = ({
|
|
40728
40731
|
data,
|
|
@@ -40792,7 +40795,7 @@ var UptimeDonutChartComponent = ({
|
|
|
40792
40795
|
] }) })
|
|
40793
40796
|
] }) });
|
|
40794
40797
|
};
|
|
40795
|
-
var UptimeDonutChart =
|
|
40798
|
+
var UptimeDonutChart = React148__default.memo(UptimeDonutChartComponent);
|
|
40796
40799
|
UptimeDonutChart.displayName = "UptimeDonutChart";
|
|
40797
40800
|
var TrendIcon = ({ trend }) => {
|
|
40798
40801
|
if (trend === "up") {
|
|
@@ -40913,7 +40916,7 @@ var EmptyStateMessage = ({
|
|
|
40913
40916
|
iconClassName
|
|
40914
40917
|
}) => {
|
|
40915
40918
|
let IconContent = null;
|
|
40916
|
-
if (
|
|
40919
|
+
if (React148__default.isValidElement(iconType)) {
|
|
40917
40920
|
IconContent = iconType;
|
|
40918
40921
|
} else if (typeof iconType === "string") {
|
|
40919
40922
|
const MappedIcon = IconMap[iconType];
|
|
@@ -41421,6 +41424,7 @@ var CYCLE_RANGE_CATEGORY_IDS = /* @__PURE__ */ new Set([
|
|
|
41421
41424
|
"fast-cycles",
|
|
41422
41425
|
"slow-cycles"
|
|
41423
41426
|
]);
|
|
41427
|
+
var EXPLICIT_INTERVAL_CATEGORY_IDS = /* @__PURE__ */ new Set(["recent_flow_red_streak"]);
|
|
41424
41428
|
var roundToNearestMinute = (date) => {
|
|
41425
41429
|
const rounded = new Date(date.getTime());
|
|
41426
41430
|
const seconds = rounded.getSeconds();
|
|
@@ -41476,6 +41480,22 @@ var buildPrefetchedExplorerMetadata = (activeFilter, metadataCategoryId, categor
|
|
|
41476
41480
|
};
|
|
41477
41481
|
};
|
|
41478
41482
|
var shouldDeferClipPlayerRender = (cropLoading, workspaceCrop) => cropLoading && workspaceCrop === null;
|
|
41483
|
+
var getCategoryMetadataLoadPlanForFilterChange = ({
|
|
41484
|
+
activeFilter,
|
|
41485
|
+
currentClipId,
|
|
41486
|
+
categoryTotal
|
|
41487
|
+
}) => {
|
|
41488
|
+
if (!activeFilter || activeFilter === "all") {
|
|
41489
|
+
return { shouldLoad: false, autoLoadFirstVideo: false };
|
|
41490
|
+
}
|
|
41491
|
+
if (activeFilter === "recent_flow_red_streak" && categoryTotal > 0) {
|
|
41492
|
+
return { shouldLoad: true, autoLoadFirstVideo: true };
|
|
41493
|
+
}
|
|
41494
|
+
return {
|
|
41495
|
+
shouldLoad: Boolean(currentClipId),
|
|
41496
|
+
autoLoadFirstVideo: false
|
|
41497
|
+
};
|
|
41498
|
+
};
|
|
41479
41499
|
var getSecondsBetweenTimestamps = (startTime, endTime) => {
|
|
41480
41500
|
const startDate = parseTimestamp(startTime);
|
|
41481
41501
|
const endDate = parseTimestamp(endTime);
|
|
@@ -41488,8 +41508,24 @@ var formatClipExplorerTimeLabel = ({
|
|
|
41488
41508
|
timezone,
|
|
41489
41509
|
durationSeconds,
|
|
41490
41510
|
idleStartTime,
|
|
41491
|
-
idleEndTime
|
|
41511
|
+
idleEndTime,
|
|
41512
|
+
clipStartTime,
|
|
41513
|
+
clipEndTime
|
|
41492
41514
|
}) => {
|
|
41515
|
+
if (EXPLICIT_INTERVAL_CATEGORY_IDS.has(categoryId)) {
|
|
41516
|
+
const endTimestamp = clipEndTime || clipTimestamp;
|
|
41517
|
+
if (clipStartTime && endTimestamp) {
|
|
41518
|
+
return formatTimestampRange(clipStartTime, endTimestamp, timezone);
|
|
41519
|
+
}
|
|
41520
|
+
if (typeof durationSeconds === "number" && Number.isFinite(durationSeconds) && durationSeconds > 0) {
|
|
41521
|
+
const endDate = parseTimestamp(endTimestamp);
|
|
41522
|
+
if (endDate) {
|
|
41523
|
+
const startDate = new Date(endDate.getTime() - durationSeconds * 1e3);
|
|
41524
|
+
return formatTimestampRange(startDate.toISOString(), endTimestamp, timezone);
|
|
41525
|
+
}
|
|
41526
|
+
}
|
|
41527
|
+
return formatClipExplorerSingleTime(endTimestamp, timezone);
|
|
41528
|
+
}
|
|
41493
41529
|
if (IDLE_RANGE_CATEGORY_IDS.has(categoryId)) {
|
|
41494
41530
|
const idleDurationSeconds = getSecondsBetweenTimestamps(idleStartTime, idleEndTime);
|
|
41495
41531
|
const idleEndTimestamp = idleEndTime || clipTimestamp;
|
|
@@ -41516,6 +41552,106 @@ var formatClipExplorerTimeLabel = ({
|
|
|
41516
41552
|
return singleTime;
|
|
41517
41553
|
};
|
|
41518
41554
|
var formatIdleTimeRange = (startTime, endTime, timezone) => formatTimestampRange(startTime, endTime, timezone);
|
|
41555
|
+
|
|
41556
|
+
// src/lib/utils/redFlowDisplay.ts
|
|
41557
|
+
var getRedFlowDriverLabel = (driver) => {
|
|
41558
|
+
switch (driver) {
|
|
41559
|
+
case "idle":
|
|
41560
|
+
return "Idle";
|
|
41561
|
+
case "micro_stoppage":
|
|
41562
|
+
return "Gaps";
|
|
41563
|
+
case "slow_cycle":
|
|
41564
|
+
return "Slow Cycles";
|
|
41565
|
+
case "low_output":
|
|
41566
|
+
return "Low Output";
|
|
41567
|
+
default:
|
|
41568
|
+
return "";
|
|
41569
|
+
}
|
|
41570
|
+
};
|
|
41571
|
+
var getRedFlowDriversFromEvidence = (evidence) => {
|
|
41572
|
+
const drivers = /* @__PURE__ */ new Set();
|
|
41573
|
+
(evidence || []).forEach((item) => {
|
|
41574
|
+
const normalized = item.toLowerCase();
|
|
41575
|
+
if (normalized.includes("idle")) {
|
|
41576
|
+
drivers.add("idle");
|
|
41577
|
+
}
|
|
41578
|
+
if (normalized.includes("micro") || normalized.includes("gap")) {
|
|
41579
|
+
drivers.add("micro_stoppage");
|
|
41580
|
+
}
|
|
41581
|
+
if (normalized.includes("slow") || normalized.includes("cycle time") || normalized.includes("shift avg")) {
|
|
41582
|
+
drivers.add("slow_cycle");
|
|
41583
|
+
}
|
|
41584
|
+
if (normalized.includes("output")) {
|
|
41585
|
+
drivers.add("low_output");
|
|
41586
|
+
}
|
|
41587
|
+
});
|
|
41588
|
+
return Array.from(drivers);
|
|
41589
|
+
};
|
|
41590
|
+
var getRedFlowDisplayDriverKeys = (summary) => {
|
|
41591
|
+
if (!summary || summary.confidence !== "medium" && summary.confidence !== "high") {
|
|
41592
|
+
return [];
|
|
41593
|
+
}
|
|
41594
|
+
if (summary.primary_driver === "unknown") {
|
|
41595
|
+
return [];
|
|
41596
|
+
}
|
|
41597
|
+
if (summary.primary_driver === "mixed") {
|
|
41598
|
+
const evidenceDrivers = getRedFlowDriversFromEvidence(summary.evidence).filter((driver) => Boolean(getRedFlowDriverLabel(driver)));
|
|
41599
|
+
return evidenceDrivers.length >= 2 ? evidenceDrivers.slice(0, 3) : [];
|
|
41600
|
+
}
|
|
41601
|
+
return getRedFlowDriverLabel(summary.primary_driver) ? [summary.primary_driver] : [];
|
|
41602
|
+
};
|
|
41603
|
+
var formatRedFlowCompactNumber = (value) => Number.isInteger(value) ? String(value) : value.toFixed(1).replace(/\.0$/, "");
|
|
41604
|
+
var formatRedFlowOutputCount = (value) => Number.isFinite(value) ? String(Math.round(value)) : "";
|
|
41605
|
+
var getRedFlowBinOutputUnits = (bin) => {
|
|
41606
|
+
if (typeof bin.actual_output_units === "number" && Number.isFinite(bin.actual_output_units)) {
|
|
41607
|
+
return bin.actual_output_units;
|
|
41608
|
+
}
|
|
41609
|
+
if (typeof bin.actual_ppm === "number" && Number.isFinite(bin.actual_ppm)) {
|
|
41610
|
+
const durationSeconds = typeof bin.duration_seconds === "number" && Number.isFinite(bin.duration_seconds) && bin.duration_seconds > 0 ? bin.duration_seconds : 60;
|
|
41611
|
+
return bin.actual_ppm * durationSeconds / 60;
|
|
41612
|
+
}
|
|
41613
|
+
return null;
|
|
41614
|
+
};
|
|
41615
|
+
var summarizeRedFlowOutput = (timeline, summary) => {
|
|
41616
|
+
const actualFromSummary = summary?.totals.actual_output_units;
|
|
41617
|
+
const expectedFromSummary = summary?.totals.baseline_output_units;
|
|
41618
|
+
if (typeof actualFromSummary === "number" && Number.isFinite(actualFromSummary) && typeof expectedFromSummary === "number" && Number.isFinite(expectedFromSummary)) {
|
|
41619
|
+
return { actual: actualFromSummary, expected: expectedFromSummary };
|
|
41620
|
+
}
|
|
41621
|
+
let actual = 0;
|
|
41622
|
+
let expected = 0;
|
|
41623
|
+
let hasActual = false;
|
|
41624
|
+
let hasExpected = false;
|
|
41625
|
+
(timeline?.minute_bins || []).forEach((bin) => {
|
|
41626
|
+
const output = getRedFlowBinOutputUnits(bin);
|
|
41627
|
+
if (output !== null) {
|
|
41628
|
+
actual += output;
|
|
41629
|
+
hasActual = true;
|
|
41630
|
+
}
|
|
41631
|
+
if (typeof bin.target_ppm === "number" && Number.isFinite(bin.target_ppm)) {
|
|
41632
|
+
const durationSeconds = typeof bin.duration_seconds === "number" && Number.isFinite(bin.duration_seconds) && bin.duration_seconds > 0 ? bin.duration_seconds : 60;
|
|
41633
|
+
expected += bin.target_ppm * durationSeconds / 60;
|
|
41634
|
+
hasExpected = true;
|
|
41635
|
+
}
|
|
41636
|
+
});
|
|
41637
|
+
return hasActual && hasExpected ? { actual, expected } : null;
|
|
41638
|
+
};
|
|
41639
|
+
var getRedFlowOutputShortfallUnits = (timeline) => {
|
|
41640
|
+
let actual = 0;
|
|
41641
|
+
let expected = 0;
|
|
41642
|
+
let hasComparableBin = false;
|
|
41643
|
+
(timeline?.minute_bins || []).forEach((bin) => {
|
|
41644
|
+
const output = getRedFlowBinOutputUnits(bin);
|
|
41645
|
+
const durationSeconds = typeof bin.duration_seconds === "number" && Number.isFinite(bin.duration_seconds) && bin.duration_seconds > 0 ? bin.duration_seconds : null;
|
|
41646
|
+
if (output === null || durationSeconds === null || typeof bin.target_ppm !== "number" || !Number.isFinite(bin.target_ppm)) {
|
|
41647
|
+
return;
|
|
41648
|
+
}
|
|
41649
|
+
actual += output;
|
|
41650
|
+
expected += bin.target_ppm * durationSeconds / 60;
|
|
41651
|
+
hasComparableBin = true;
|
|
41652
|
+
});
|
|
41653
|
+
return hasComparableBin ? expected - actual : null;
|
|
41654
|
+
};
|
|
41519
41655
|
var formatTime2 = (seconds) => {
|
|
41520
41656
|
if (!seconds || isNaN(seconds)) return "0:00";
|
|
41521
41657
|
const h = Math.floor(seconds / 3600);
|
|
@@ -41526,6 +41662,33 @@ var formatTime2 = (seconds) => {
|
|
|
41526
41662
|
}
|
|
41527
41663
|
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
41528
41664
|
};
|
|
41665
|
+
var formatTimelineClockTime = (isoTime, timezone) => {
|
|
41666
|
+
if (!isoTime) return "";
|
|
41667
|
+
const date = new Date(isoTime);
|
|
41668
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
41669
|
+
return date.toLocaleTimeString("en-US", {
|
|
41670
|
+
hour: "numeric",
|
|
41671
|
+
minute: "2-digit",
|
|
41672
|
+
hour12: true,
|
|
41673
|
+
timeZone: timezone
|
|
41674
|
+
});
|
|
41675
|
+
};
|
|
41676
|
+
var formatCompactNumber = formatRedFlowCompactNumber;
|
|
41677
|
+
var formatTooltipSeconds = (value) => `${Math.round(value)}s`;
|
|
41678
|
+
var formatEfficiencyPercent = (value) => {
|
|
41679
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
41680
|
+
return "No output data";
|
|
41681
|
+
}
|
|
41682
|
+
return `${Math.round(value)}% efficient`;
|
|
41683
|
+
};
|
|
41684
|
+
var getBinOutputUnits = getRedFlowBinOutputUnits;
|
|
41685
|
+
var formatOutputLabel = (bin) => {
|
|
41686
|
+
const actualOutput = getBinOutputUnits(bin);
|
|
41687
|
+
if (actualOutput === null) {
|
|
41688
|
+
return "";
|
|
41689
|
+
}
|
|
41690
|
+
return `Output ${formatCompactNumber(actualOutput)}`;
|
|
41691
|
+
};
|
|
41529
41692
|
var VideoControls = ({
|
|
41530
41693
|
isPlaying,
|
|
41531
41694
|
currentTime,
|
|
@@ -41544,15 +41707,20 @@ var VideoControls = ({
|
|
|
41544
41707
|
onShare,
|
|
41545
41708
|
isShareLoading = false,
|
|
41546
41709
|
isShareCopied = false,
|
|
41710
|
+
timelineAnnotations,
|
|
41711
|
+
timelineExplanation,
|
|
41712
|
+
timelineTimezone,
|
|
41547
41713
|
className = ""
|
|
41548
41714
|
}) => {
|
|
41549
41715
|
const [isDragging2, setIsDragging] = useState(false);
|
|
41550
41716
|
const [dragTime, setDragTime] = useState(0);
|
|
41551
41717
|
const [isHoveringProgressBar, setIsHoveringProgressBar] = useState(false);
|
|
41718
|
+
const [hoveredTimelineBin, setHoveredTimelineBin] = useState(null);
|
|
41552
41719
|
const [showSpeedMenu, setShowSpeedMenu] = useState(false);
|
|
41553
41720
|
const speedMenuRef = useRef(null);
|
|
41554
41721
|
const progressTrackRef = useRef(null);
|
|
41555
41722
|
const activePointerIdRef = useRef(null);
|
|
41723
|
+
const markerPointerJumpHandledRef = useRef(false);
|
|
41556
41724
|
const progressColor = "#4b5563";
|
|
41557
41725
|
const controlsVisible = showControls || controlsPinned;
|
|
41558
41726
|
const isDraggingRef = useRef(false);
|
|
@@ -41576,6 +41744,43 @@ var VideoControls = ({
|
|
|
41576
41744
|
isDraggingRef.current = false;
|
|
41577
41745
|
onSeekEnd?.();
|
|
41578
41746
|
};
|
|
41747
|
+
const handleTimelineJump = useCallback((time2) => {
|
|
41748
|
+
const nextTime = Math.min(Math.max(time2, 0), duration || time2);
|
|
41749
|
+
const wasDragging = isDraggingRef.current;
|
|
41750
|
+
activePointerIdRef.current = null;
|
|
41751
|
+
setIsDragging(false);
|
|
41752
|
+
isDraggingRef.current = false;
|
|
41753
|
+
setDragTime(nextTime);
|
|
41754
|
+
if (!wasDragging) {
|
|
41755
|
+
onSeekStart?.();
|
|
41756
|
+
}
|
|
41757
|
+
onSeek(nextTime);
|
|
41758
|
+
onSeekEnd?.();
|
|
41759
|
+
}, [duration, onSeek, onSeekEnd, onSeekStart]);
|
|
41760
|
+
const handleTimelineMarkerPointerDown = useCallback((e, time2) => {
|
|
41761
|
+
e.preventDefault();
|
|
41762
|
+
e.stopPropagation();
|
|
41763
|
+
markerPointerJumpHandledRef.current = true;
|
|
41764
|
+
handleTimelineJump(time2);
|
|
41765
|
+
}, [handleTimelineJump]);
|
|
41766
|
+
const handleTimelineMarkerMouseDown = useCallback((e, time2) => {
|
|
41767
|
+
e.preventDefault();
|
|
41768
|
+
e.stopPropagation();
|
|
41769
|
+
if (markerPointerJumpHandledRef.current) {
|
|
41770
|
+
return;
|
|
41771
|
+
}
|
|
41772
|
+
markerPointerJumpHandledRef.current = true;
|
|
41773
|
+
handleTimelineJump(time2);
|
|
41774
|
+
}, [handleTimelineJump]);
|
|
41775
|
+
const handleTimelineMarkerClick = useCallback((e, time2) => {
|
|
41776
|
+
e.preventDefault();
|
|
41777
|
+
e.stopPropagation();
|
|
41778
|
+
if (markerPointerJumpHandledRef.current) {
|
|
41779
|
+
markerPointerJumpHandledRef.current = false;
|
|
41780
|
+
return;
|
|
41781
|
+
}
|
|
41782
|
+
handleTimelineJump(time2);
|
|
41783
|
+
}, [handleTimelineJump]);
|
|
41579
41784
|
const updateTimeFromClientX = useCallback((clientX) => {
|
|
41580
41785
|
if (!progressTrackRef.current) return;
|
|
41581
41786
|
const rect = progressTrackRef.current.getBoundingClientRect();
|
|
@@ -41636,6 +41841,127 @@ var VideoControls = ({
|
|
|
41636
41841
|
const displayTime = isDragging2 ? dragTime : currentTime;
|
|
41637
41842
|
const progressPercent = getPercentage(displayTime, duration);
|
|
41638
41843
|
const bufferedPercent = getPercentage(buffered, duration);
|
|
41844
|
+
const timelineBins = useMemo(() => {
|
|
41845
|
+
if (!timelineAnnotations?.minute_bins?.length || duration <= 0) {
|
|
41846
|
+
return [];
|
|
41847
|
+
}
|
|
41848
|
+
return timelineAnnotations.minute_bins.map((bin) => {
|
|
41849
|
+
const offset = typeof bin.offset_seconds === "number" && Number.isFinite(bin.offset_seconds) ? Math.max(0, bin.offset_seconds) : 0;
|
|
41850
|
+
const binDuration = typeof bin.duration_seconds === "number" && Number.isFinite(bin.duration_seconds) && bin.duration_seconds > 0 ? bin.duration_seconds : 60;
|
|
41851
|
+
if (offset >= duration) {
|
|
41852
|
+
return null;
|
|
41853
|
+
}
|
|
41854
|
+
const clampedDuration = Math.min(binDuration, Math.max(0, duration - offset));
|
|
41855
|
+
if (clampedDuration <= 0) {
|
|
41856
|
+
return null;
|
|
41857
|
+
}
|
|
41858
|
+
const clockLabel = formatTimelineClockTime(bin.start_time, timelineTimezone);
|
|
41859
|
+
const minuteExplanation = timelineExplanation?.minute_explanations?.find((explanation) => explanation.offset_seconds === offset || Boolean(explanation.start_time) && explanation.start_time === bin.start_time);
|
|
41860
|
+
const explanationLabel = minuteExplanation && minuteExplanation.confidence !== "low" ? minuteExplanation.primary_driver === "idle" ? "High Idle Detected" : minuteExplanation.primary_driver === "micro_stoppage" ? `Gap: ${Math.round(minuteExplanation.micro_stoppage_lost_seconds)}s lost` : minuteExplanation.primary_driver === "slow_cycle" ? typeof minuteExplanation.actual_cycle_time_seconds === "number" && Number.isFinite(minuteExplanation.actual_cycle_time_seconds) && typeof minuteExplanation.median_cycle_time_seconds === "number" && Number.isFinite(minuteExplanation.median_cycle_time_seconds) ? `Avg Cycle Time: ${formatTooltipSeconds(minuteExplanation.actual_cycle_time_seconds)} vs Shift Avg: ${formatTooltipSeconds(minuteExplanation.median_cycle_time_seconds)}` : `Slow cycle: ${Math.round(minuteExplanation.slow_cycle_lost_seconds)}s lost` : minuteExplanation.primary_driver === "low_output" ? "Low Output" : void 0 : void 0;
|
|
41861
|
+
return {
|
|
41862
|
+
...bin,
|
|
41863
|
+
offset_seconds: offset,
|
|
41864
|
+
duration_seconds: clampedDuration,
|
|
41865
|
+
leftPercent: getPercentage(offset, duration),
|
|
41866
|
+
widthPercent: Math.max(getPercentage(clampedDuration, duration), 0.4),
|
|
41867
|
+
clockLabel,
|
|
41868
|
+
efficiencyLabel: formatEfficiencyPercent(bin.efficiency_percent),
|
|
41869
|
+
outputLabel: formatOutputLabel({ ...bin, duration_seconds: clampedDuration }),
|
|
41870
|
+
explanationLabel
|
|
41871
|
+
};
|
|
41872
|
+
}).filter((bin) => Boolean(bin));
|
|
41873
|
+
}, [duration, timelineAnnotations, timelineExplanation, timelineTimezone]);
|
|
41874
|
+
const hasTimelineAnnotations = timelineBins.length > 0;
|
|
41875
|
+
const worstMinuteMarkers = useMemo(() => {
|
|
41876
|
+
const efficiencySource = timelineBins.filter((bin) => typeof bin.efficiency_percent === "number" && Number.isFinite(bin.efficiency_percent)).slice().sort((a, b) => a.efficiency_percent - b.efficiency_percent || a.offset_seconds - b.offset_seconds).slice(0, 3).map((bin, index) => ({
|
|
41877
|
+
start_time: bin.start_time,
|
|
41878
|
+
offset_seconds: bin.offset_seconds,
|
|
41879
|
+
duration_seconds: bin.duration_seconds,
|
|
41880
|
+
avg_flow_percent: bin.avg_flow_percent,
|
|
41881
|
+
rank: index + 1
|
|
41882
|
+
}));
|
|
41883
|
+
const source = efficiencySource.length ? efficiencySource : timelineAnnotations?.worst_minutes?.length ? timelineAnnotations.worst_minutes : timelineBins.filter((bin) => typeof bin.avg_flow_percent === "number" && Number.isFinite(bin.avg_flow_percent)).sort((a, b) => a.avg_flow_percent - b.avg_flow_percent).slice(0, 3);
|
|
41884
|
+
return source.filter((marker) => typeof marker.offset_seconds === "number" && Number.isFinite(marker.offset_seconds)).slice(0, 3).map((marker, index) => {
|
|
41885
|
+
const offset = Math.max(0, Math.min(duration, marker.offset_seconds));
|
|
41886
|
+
const matchingBin = timelineBins.find((bin) => bin.offset_seconds === marker.offset_seconds || Boolean(marker.start_time) && bin.start_time === marker.start_time);
|
|
41887
|
+
const markerDuration = "duration_seconds" in marker ? Number(marker.duration_seconds || 0) : 0;
|
|
41888
|
+
const width = markerDuration > 0 ? markerDuration : Number(matchingBin?.duration_seconds || 0);
|
|
41889
|
+
const centerOffset = Math.min(duration, offset + Math.max(0, width) / 2);
|
|
41890
|
+
return {
|
|
41891
|
+
...marker,
|
|
41892
|
+
rank: "rank" in marker ? marker.rank : index + 1,
|
|
41893
|
+
leftPercent: getPercentage(centerOffset, duration)
|
|
41894
|
+
};
|
|
41895
|
+
});
|
|
41896
|
+
}, [duration, timelineAnnotations, timelineBins]);
|
|
41897
|
+
const transitionMarkers = useMemo(() => {
|
|
41898
|
+
if (timelineBins.length < 2 || duration <= 0) {
|
|
41899
|
+
return [];
|
|
41900
|
+
}
|
|
41901
|
+
const orderedBins = timelineBins.slice().sort((left, right) => left.offset_seconds - right.offset_seconds);
|
|
41902
|
+
return orderedBins.slice(1).map((bin, index) => {
|
|
41903
|
+
const previousBin = orderedBins[index];
|
|
41904
|
+
const fromOutputUnits = getBinOutputUnits(previousBin);
|
|
41905
|
+
const toOutputUnits = getBinOutputUnits(bin);
|
|
41906
|
+
const hasOutputValues = fromOutputUnits !== null && toOutputUnits !== null && fromOutputUnits > 0;
|
|
41907
|
+
const fromEfficiency = previousBin.efficiency_percent;
|
|
41908
|
+
const toEfficiency = bin.efficiency_percent;
|
|
41909
|
+
const hasEfficiencyValues = typeof fromEfficiency === "number" && typeof toEfficiency === "number" && Number.isFinite(fromEfficiency) && Number.isFinite(toEfficiency) && fromEfficiency > 0;
|
|
41910
|
+
if (!hasOutputValues && !hasEfficiencyValues) {
|
|
41911
|
+
return null;
|
|
41912
|
+
}
|
|
41913
|
+
const fromValue = hasOutputValues ? fromOutputUnits : fromEfficiency;
|
|
41914
|
+
const toValue2 = hasOutputValues ? toOutputUnits : toEfficiency;
|
|
41915
|
+
const relativeDrop = (fromValue - toValue2) / fromValue;
|
|
41916
|
+
if (relativeDrop <= 0.5) {
|
|
41917
|
+
return null;
|
|
41918
|
+
}
|
|
41919
|
+
const transitionOffset = Math.min(Math.max(bin.offset_seconds, 0), duration);
|
|
41920
|
+
return {
|
|
41921
|
+
offsetSeconds: transitionOffset,
|
|
41922
|
+
leftPercent: getPercentage(transitionOffset, duration),
|
|
41923
|
+
fromValue,
|
|
41924
|
+
toValue: toValue2,
|
|
41925
|
+
relativeDrop,
|
|
41926
|
+
fromOutputUnits,
|
|
41927
|
+
toOutputUnits,
|
|
41928
|
+
source: hasOutputValues ? "output" : "efficiency",
|
|
41929
|
+
absoluteDrop: fromValue - toValue2
|
|
41930
|
+
};
|
|
41931
|
+
}).filter((marker) => Boolean(marker)).sort((left, right) => {
|
|
41932
|
+
const relativeDiff = right.relativeDrop - left.relativeDrop;
|
|
41933
|
+
if (relativeDiff !== 0) {
|
|
41934
|
+
return relativeDiff;
|
|
41935
|
+
}
|
|
41936
|
+
const outputDiff = right.absoluteDrop - left.absoluteDrop;
|
|
41937
|
+
if (outputDiff !== 0) {
|
|
41938
|
+
return outputDiff;
|
|
41939
|
+
}
|
|
41940
|
+
return left.offsetSeconds - right.offsetSeconds;
|
|
41941
|
+
}).slice(0, 3).map((marker, index) => ({
|
|
41942
|
+
...marker,
|
|
41943
|
+
rank: index + 1
|
|
41944
|
+
}));
|
|
41945
|
+
}, [duration, timelineBins]);
|
|
41946
|
+
worstMinuteMarkers[0] || null;
|
|
41947
|
+
const updateHoveredTimelineBin = useCallback((clientX) => {
|
|
41948
|
+
if (!hasTimelineAnnotations || !progressTrackRef.current || duration <= 0) {
|
|
41949
|
+
setHoveredTimelineBin(null);
|
|
41950
|
+
return;
|
|
41951
|
+
}
|
|
41952
|
+
const rect = progressTrackRef.current.getBoundingClientRect();
|
|
41953
|
+
if (!rect.width) {
|
|
41954
|
+
setHoveredTimelineBin(null);
|
|
41955
|
+
return;
|
|
41956
|
+
}
|
|
41957
|
+
const pct = Math.min(Math.max((clientX - rect.left) / rect.width, 0), 1);
|
|
41958
|
+
const hoverTime = pct * duration;
|
|
41959
|
+
const nextBin = timelineBins.find((bin) => hoverTime >= bin.offset_seconds && hoverTime <= bin.offset_seconds + bin.duration_seconds) || null;
|
|
41960
|
+
setHoveredTimelineBin(nextBin);
|
|
41961
|
+
}, [duration, hasTimelineAnnotations, timelineBins]);
|
|
41962
|
+
const handleProgressMouseMove = useCallback((e) => {
|
|
41963
|
+
updateHoveredTimelineBin(e.clientX);
|
|
41964
|
+
}, [updateHoveredTimelineBin]);
|
|
41639
41965
|
return /* @__PURE__ */ jsxs(
|
|
41640
41966
|
"div",
|
|
41641
41967
|
{
|
|
@@ -41647,12 +41973,16 @@ var VideoControls = ({
|
|
|
41647
41973
|
"div",
|
|
41648
41974
|
{
|
|
41649
41975
|
ref: progressTrackRef,
|
|
41650
|
-
className: "relative h-1 mb-4 group cursor-pointer",
|
|
41976
|
+
className: "relative z-10 h-1 mb-4 group cursor-pointer",
|
|
41651
41977
|
onMouseEnter: () => setIsHoveringProgressBar(true),
|
|
41652
|
-
|
|
41978
|
+
onMouseMove: handleProgressMouseMove,
|
|
41979
|
+
onMouseLeave: () => {
|
|
41980
|
+
setIsHoveringProgressBar(false);
|
|
41981
|
+
setHoveredTimelineBin(null);
|
|
41982
|
+
},
|
|
41653
41983
|
onPointerDown: handlePointerDown,
|
|
41654
41984
|
children: [
|
|
41655
|
-
/* @__PURE__ */ jsx("div", { className: "absolute -top-4
|
|
41985
|
+
/* @__PURE__ */ jsx("div", { className: "absolute -top-4 bottom-0 left-0 right-0 z-20" }),
|
|
41656
41986
|
/* @__PURE__ */ jsx("div", { className: "absolute top-0 left-0 right-0 bottom-0 bg-white/20 rounded-full overflow-hidden z-0", children: /* @__PURE__ */ jsx(
|
|
41657
41987
|
"div",
|
|
41658
41988
|
{
|
|
@@ -41686,17 +42016,47 @@ var VideoControls = ({
|
|
|
41686
42016
|
onInput: handleSeekChange,
|
|
41687
42017
|
onMouseDown: handleSeekStart,
|
|
41688
42018
|
onMouseUp: handleSeekEnd,
|
|
42019
|
+
onMouseMove: handleProgressMouseMove,
|
|
41689
42020
|
onTouchStart: handleSeekStart,
|
|
41690
42021
|
onTouchEnd: handleSeekEnd,
|
|
41691
42022
|
onPointerDown: handlePointerDown,
|
|
41692
|
-
className: "absolute left-0 right-0 top-[-12px] bottom-
|
|
42023
|
+
className: "absolute left-0 right-0 top-[-12px] bottom-0 w-full h-auto opacity-0 cursor-pointer z-30 margin-0 padding-0"
|
|
42024
|
+
}
|
|
42025
|
+
),
|
|
42026
|
+
hasTimelineAnnotations && transitionMarkers.map((marker) => /* @__PURE__ */ jsx(
|
|
42027
|
+
"button",
|
|
42028
|
+
{
|
|
42029
|
+
type: "button",
|
|
42030
|
+
"aria-label": marker.source === "output" ? `Output drop marker ${marker.rank}: output ${formatCompactNumber(marker.fromValue)} to ${formatCompactNumber(marker.toValue)} (${Math.round(marker.relativeDrop * 100)}% drop)` : `Output drop marker ${marker.rank}: efficiency ${Math.round(marker.fromValue)}% to ${Math.round(marker.toValue)}% (${Math.round(marker.relativeDrop * 100)}% drop)`,
|
|
42031
|
+
title: marker.source === "output" ? `Output drop: ${formatCompactNumber(marker.fromValue)} to ${formatCompactNumber(marker.toValue)}` : `Output drop: ${Math.round(marker.fromValue)}% to ${Math.round(marker.toValue)}%`,
|
|
42032
|
+
onPointerDownCapture: (e) => handleTimelineMarkerPointerDown(e, marker.offsetSeconds),
|
|
42033
|
+
onMouseDownCapture: (e) => handleTimelineMarkerMouseDown(e, marker.offsetSeconds),
|
|
42034
|
+
onClickCapture: (e) => handleTimelineMarkerClick(e, marker.offsetSeconds),
|
|
42035
|
+
className: "absolute top-1/2 -translate-y-1/2 z-[70] flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-white bg-sky-500 p-0 text-center text-[9px] font-bold leading-none text-white shadow hover:bg-sky-400 focus:outline-none focus:ring-2 focus:ring-sky-200",
|
|
42036
|
+
style: { left: `calc(${marker.leftPercent}% - 10px)`, zIndex: 70, pointerEvents: "auto" },
|
|
42037
|
+
children: marker.rank
|
|
42038
|
+
},
|
|
42039
|
+
`${marker.rank}-${marker.offsetSeconds}`
|
|
42040
|
+
)),
|
|
42041
|
+
hasTimelineAnnotations && hoveredTimelineBin && /* @__PURE__ */ jsxs(
|
|
42042
|
+
"div",
|
|
42043
|
+
{
|
|
42044
|
+
className: "absolute bottom-full z-50 mb-2 -translate-x-1/2 rounded bg-slate-900 px-2 py-1 text-[11px] font-semibold text-white shadow-lg",
|
|
42045
|
+
style: { left: `${hoveredTimelineBin.leftPercent + hoveredTimelineBin.widthPercent / 2}%` },
|
|
42046
|
+
children: [
|
|
42047
|
+
hoveredTimelineBin.clockLabel || formatTime2(hoveredTimelineBin.offset_seconds),
|
|
42048
|
+
" | ",
|
|
42049
|
+
hoveredTimelineBin.efficiencyLabel,
|
|
42050
|
+
hoveredTimelineBin.outputLabel ? ` | ${hoveredTimelineBin.outputLabel}` : "",
|
|
42051
|
+
hoveredTimelineBin.explanationLabel ? ` | ${hoveredTimelineBin.explanationLabel}` : ""
|
|
42052
|
+
]
|
|
41693
42053
|
}
|
|
41694
42054
|
)
|
|
41695
42055
|
]
|
|
41696
42056
|
}
|
|
41697
42057
|
),
|
|
41698
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-white", children: [
|
|
41699
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
42058
|
+
/* @__PURE__ */ jsxs("div", { className: "relative z-40 flex items-center justify-between text-white", children: [
|
|
42059
|
+
/* @__PURE__ */ jsxs("div", { className: "relative z-50 flex items-center gap-4", children: [
|
|
41700
42060
|
/* @__PURE__ */ jsx(
|
|
41701
42061
|
"button",
|
|
41702
42062
|
{
|
|
@@ -41977,7 +42337,10 @@ var HlsVideoPlayer = forwardRef(({
|
|
|
41977
42337
|
onClick,
|
|
41978
42338
|
onShare,
|
|
41979
42339
|
isShareLoading,
|
|
41980
|
-
isShareCopied
|
|
42340
|
+
isShareCopied,
|
|
42341
|
+
timelineAnnotations,
|
|
42342
|
+
timelineExplanation,
|
|
42343
|
+
timelineTimezone
|
|
41981
42344
|
}, ref) => {
|
|
41982
42345
|
const supabase = useSupabase();
|
|
41983
42346
|
const videoContainerRef = useRef(null);
|
|
@@ -42639,6 +43002,7 @@ var HlsVideoPlayer = forwardRef(({
|
|
|
42639
43002
|
const handleSeek = useCallback((time2) => {
|
|
42640
43003
|
if (videoRef.current) {
|
|
42641
43004
|
videoRef.current.currentTime = time2;
|
|
43005
|
+
setCurrentTime(time2);
|
|
42642
43006
|
}
|
|
42643
43007
|
}, []);
|
|
42644
43008
|
const handleSeekStart = useCallback(() => {
|
|
@@ -42745,7 +43109,10 @@ var HlsVideoPlayer = forwardRef(({
|
|
|
42745
43109
|
onToggleFullscreen: handleToggleFullscreen,
|
|
42746
43110
|
onShare,
|
|
42747
43111
|
isShareLoading,
|
|
42748
|
-
isShareCopied
|
|
43112
|
+
isShareCopied,
|
|
43113
|
+
timelineAnnotations,
|
|
43114
|
+
timelineExplanation,
|
|
43115
|
+
timelineTimezone
|
|
42749
43116
|
}
|
|
42750
43117
|
)
|
|
42751
43118
|
]
|
|
@@ -43066,6 +43433,7 @@ var CroppedHlsVideoPlayer = forwardRef(({
|
|
|
43066
43433
|
const handleSeek = useCallback((time2) => {
|
|
43067
43434
|
if (hiddenVideoRef.current) {
|
|
43068
43435
|
hiddenVideoRef.current.currentTime(time2);
|
|
43436
|
+
setCurrentTime(time2);
|
|
43069
43437
|
setTimeout(() => renderFrameToCanvas(), 50);
|
|
43070
43438
|
userSeekingRef.current = true;
|
|
43071
43439
|
}
|
|
@@ -43211,7 +43579,10 @@ var CroppedHlsVideoPlayer = forwardRef(({
|
|
|
43211
43579
|
onToggleFullscreen: handleToggleFullscreen,
|
|
43212
43580
|
onShare: videoProps.onShare,
|
|
43213
43581
|
isShareLoading: videoProps.isShareLoading,
|
|
43214
|
-
isShareCopied: videoProps.isShareCopied
|
|
43582
|
+
isShareCopied: videoProps.isShareCopied,
|
|
43583
|
+
timelineAnnotations: videoProps.timelineAnnotations,
|
|
43584
|
+
timelineExplanation: videoProps.timelineExplanation,
|
|
43585
|
+
timelineTimezone: videoProps.timelineTimezone
|
|
43215
43586
|
}
|
|
43216
43587
|
)
|
|
43217
43588
|
]
|
|
@@ -43220,6 +43591,100 @@ var CroppedHlsVideoPlayer = forwardRef(({
|
|
|
43220
43591
|
});
|
|
43221
43592
|
CroppedHlsVideoPlayer.displayName = "CroppedHlsVideoPlayer";
|
|
43222
43593
|
var CroppedVideoPlayer = CroppedHlsVideoPlayer;
|
|
43594
|
+
var formatSeconds = (value) => {
|
|
43595
|
+
const seconds = Math.max(0, Math.round(value));
|
|
43596
|
+
if (seconds < 60) {
|
|
43597
|
+
return `${seconds}s`;
|
|
43598
|
+
}
|
|
43599
|
+
const minutes = Math.floor(seconds / 60);
|
|
43600
|
+
const remainingSeconds = seconds % 60;
|
|
43601
|
+
return remainingSeconds > 0 ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
|
|
43602
|
+
};
|
|
43603
|
+
var buildLostChip = (explanation) => {
|
|
43604
|
+
const totals = explanation.summary.totals;
|
|
43605
|
+
const explicitTotalLostSeconds = Number(totals.total_lost_seconds);
|
|
43606
|
+
const lostSeconds = Number.isFinite(explicitTotalLostSeconds) ? explicitTotalLostSeconds : Math.max(
|
|
43607
|
+
Number(totals.idle_overlap_seconds) || 0,
|
|
43608
|
+
Number(totals.micro_stoppage_lost_seconds) || 0,
|
|
43609
|
+
Number(totals.slow_cycle_lost_seconds) || 0
|
|
43610
|
+
);
|
|
43611
|
+
if (lostSeconds > 0) {
|
|
43612
|
+
return `${formatSeconds(lostSeconds)} lost`;
|
|
43613
|
+
}
|
|
43614
|
+
if (Number(totals.idle_overlap_percent) > 0) {
|
|
43615
|
+
return `${Math.round(totals.idle_overlap_percent)}% idle`;
|
|
43616
|
+
}
|
|
43617
|
+
return null;
|
|
43618
|
+
};
|
|
43619
|
+
var RedFlowDiagnosticOverlay = ({
|
|
43620
|
+
timeline,
|
|
43621
|
+
explanation,
|
|
43622
|
+
aiSummary,
|
|
43623
|
+
aiSummaryLoading = false,
|
|
43624
|
+
aiSummaryError = null,
|
|
43625
|
+
className = ""
|
|
43626
|
+
}) => {
|
|
43627
|
+
const summary = explanation?.summary || null;
|
|
43628
|
+
const driverKeys = useMemo(() => getRedFlowDisplayDriverKeys(summary), [summary]);
|
|
43629
|
+
const outputSummary = useMemo(() => summarizeRedFlowOutput(timeline, summary), [summary, timeline]);
|
|
43630
|
+
const hasOutputIssue = Boolean(
|
|
43631
|
+
outputSummary && Number.isFinite(outputSummary.expected) && Number.isFinite(outputSummary.actual) && outputSummary.expected > outputSummary.actual
|
|
43632
|
+
);
|
|
43633
|
+
if (driverKeys.length === 0 && !hasOutputIssue) {
|
|
43634
|
+
return null;
|
|
43635
|
+
}
|
|
43636
|
+
const driverLabel = driverKeys.length > 0 ? driverKeys.map(getRedFlowDriverLabel).filter(Boolean).join(" + ") : "Low Output";
|
|
43637
|
+
if (!driverLabel) {
|
|
43638
|
+
return null;
|
|
43639
|
+
}
|
|
43640
|
+
const shouldShowLostChip = driverKeys.some((driver) => driver !== "low_output");
|
|
43641
|
+
const chips = explanation && shouldShowLostChip ? [buildLostChip(explanation)].filter((chip) => Boolean(chip)) : [];
|
|
43642
|
+
const shouldShowHeadline = Boolean(summary && driverKeys.length > 0 && summary.primary_driver !== "unknown");
|
|
43643
|
+
const aiSummaryBullets = Array.isArray(aiSummary?.bullets) ? aiSummary.bullets.map((bullet) => String(bullet || "").trim()).filter(Boolean).slice(0, 3) : [];
|
|
43644
|
+
const shouldShowAiSummary = !aiSummaryError && aiSummaryBullets.length === 3;
|
|
43645
|
+
return /* @__PURE__ */ jsxs(
|
|
43646
|
+
"div",
|
|
43647
|
+
{
|
|
43648
|
+
className: `pointer-events-none absolute z-20 w-[240px] max-w-[calc(100%-2rem)] rounded-xl border border-white/10 bg-black/60 p-5 text-white shadow-xl backdrop-blur-md ${className}`,
|
|
43649
|
+
children: [
|
|
43650
|
+
outputSummary ? /* @__PURE__ */ jsxs("div", { className: "mb-5 space-y-4", children: [
|
|
43651
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
43652
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-white/50", children: "Output:" }),
|
|
43653
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm font-bold text-white", children: [
|
|
43654
|
+
/* @__PURE__ */ jsx("span", { className: "text-red-400", children: formatRedFlowOutputCount(outputSummary.actual) }),
|
|
43655
|
+
/* @__PURE__ */ jsx("span", { className: "px-1 text-white/30", children: "/" }),
|
|
43656
|
+
formatRedFlowOutputCount(outputSummary.expected)
|
|
43657
|
+
] })
|
|
43658
|
+
] }),
|
|
43659
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
43660
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-white/50", children: "Reason:" }),
|
|
43661
|
+
/* @__PURE__ */ jsx("span", { className: "rounded bg-red-500/10 px-2 py-1 text-[10px] font-semibold tracking-wide text-red-400 ring-1 ring-inset ring-red-500/20", children: "Low output" })
|
|
43662
|
+
] })
|
|
43663
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center gap-2", children: /* @__PURE__ */ jsx("span", { className: "rounded bg-red-500/10 px-2 py-1 text-[10px] font-semibold tracking-wide text-red-400 ring-1 ring-inset ring-red-500/20", children: driverLabel }) }),
|
|
43664
|
+
(shouldShowAiSummary || aiSummaryLoading || chips.length > 0 || shouldShowHeadline) && /* @__PURE__ */ jsx("div", { className: "mb-4 h-px w-full bg-white/10" }),
|
|
43665
|
+
!shouldShowAiSummary && !aiSummaryLoading && shouldShowHeadline && summary?.headline ? /* @__PURE__ */ jsx("div", { className: "mb-3 text-[13px] font-medium leading-relaxed text-white/90", children: summary.headline }) : null,
|
|
43666
|
+
!shouldShowAiSummary && !aiSummaryLoading && chips.length > 0 ? /* @__PURE__ */ jsx("div", { className: "mb-3 flex flex-wrap gap-2", children: chips.slice(0, 3).map((chip) => /* @__PURE__ */ jsx(
|
|
43667
|
+
"span",
|
|
43668
|
+
{
|
|
43669
|
+
className: "rounded border border-white/10 bg-white/5 px-2 py-0.5 text-[11px] font-medium text-white/70",
|
|
43670
|
+
children: chip
|
|
43671
|
+
},
|
|
43672
|
+
chip
|
|
43673
|
+
)) }) : null,
|
|
43674
|
+
shouldShowAiSummary ? /* @__PURE__ */ jsxs("div", { className: "mt-1", children: [
|
|
43675
|
+
/* @__PURE__ */ jsx("div", { className: "mb-3 text-[10px] font-bold uppercase tracking-[0.15em] text-white/40", children: "AI summary" }),
|
|
43676
|
+
/* @__PURE__ */ jsx("ol", { className: "space-y-3 text-[12px] leading-relaxed text-white/80", children: aiSummaryBullets.map((bullet, index) => /* @__PURE__ */ jsxs("li", { className: "flex gap-2", children: [
|
|
43677
|
+
/* @__PURE__ */ jsxs("span", { className: "font-semibold text-white/40", children: [
|
|
43678
|
+
index + 1,
|
|
43679
|
+
"."
|
|
43680
|
+
] }),
|
|
43681
|
+
/* @__PURE__ */ jsx("span", { children: bullet })
|
|
43682
|
+
] }, `${index}-${bullet}`)) })
|
|
43683
|
+
] }) : aiSummaryLoading ? /* @__PURE__ */ jsx("div", { className: "mt-1 text-[13px] font-medium text-white/60", children: "Generating summary..." }) : null
|
|
43684
|
+
]
|
|
43685
|
+
}
|
|
43686
|
+
);
|
|
43687
|
+
};
|
|
43223
43688
|
function useWorkspaceCrop(workspaceId) {
|
|
43224
43689
|
const supabase = useSupabase();
|
|
43225
43690
|
const [crop, setCrop] = useState(null);
|
|
@@ -43269,7 +43734,7 @@ function Skeleton({ className, ...props }) {
|
|
|
43269
43734
|
var Select = SelectPrimitive.Root;
|
|
43270
43735
|
var SelectGroup = SelectPrimitive.Group;
|
|
43271
43736
|
var SelectValue = SelectPrimitive.Value;
|
|
43272
|
-
var SelectTrigger =
|
|
43737
|
+
var SelectTrigger = React148.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
43273
43738
|
SelectPrimitive.Trigger,
|
|
43274
43739
|
{
|
|
43275
43740
|
ref,
|
|
@@ -43285,7 +43750,7 @@ var SelectTrigger = React147.forwardRef(({ className, children, ...props }, ref)
|
|
|
43285
43750
|
}
|
|
43286
43751
|
));
|
|
43287
43752
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
43288
|
-
var SelectScrollUpButton =
|
|
43753
|
+
var SelectScrollUpButton = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
43289
43754
|
SelectPrimitive.ScrollUpButton,
|
|
43290
43755
|
{
|
|
43291
43756
|
ref,
|
|
@@ -43295,7 +43760,7 @@ var SelectScrollUpButton = React147.forwardRef(({ className, ...props }, ref) =>
|
|
|
43295
43760
|
}
|
|
43296
43761
|
));
|
|
43297
43762
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
43298
|
-
var SelectScrollDownButton =
|
|
43763
|
+
var SelectScrollDownButton = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
43299
43764
|
SelectPrimitive.ScrollDownButton,
|
|
43300
43765
|
{
|
|
43301
43766
|
ref,
|
|
@@ -43305,7 +43770,7 @@ var SelectScrollDownButton = React147.forwardRef(({ className, ...props }, ref)
|
|
|
43305
43770
|
}
|
|
43306
43771
|
));
|
|
43307
43772
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
43308
|
-
var SelectContent =
|
|
43773
|
+
var SelectContent = React148.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
43309
43774
|
SelectPrimitive.Content,
|
|
43310
43775
|
{
|
|
43311
43776
|
ref,
|
|
@@ -43333,7 +43798,7 @@ var SelectContent = React147.forwardRef(({ className, children, position = "popp
|
|
|
43333
43798
|
}
|
|
43334
43799
|
) }));
|
|
43335
43800
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
43336
|
-
var SelectLabel =
|
|
43801
|
+
var SelectLabel = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
43337
43802
|
SelectPrimitive.Label,
|
|
43338
43803
|
{
|
|
43339
43804
|
ref,
|
|
@@ -43342,7 +43807,7 @@ var SelectLabel = React147.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
43342
43807
|
}
|
|
43343
43808
|
));
|
|
43344
43809
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
43345
|
-
var SelectItem =
|
|
43810
|
+
var SelectItem = React148.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
43346
43811
|
SelectPrimitive.Item,
|
|
43347
43812
|
{
|
|
43348
43813
|
ref,
|
|
@@ -43358,7 +43823,7 @@ var SelectItem = React147.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
43358
43823
|
}
|
|
43359
43824
|
));
|
|
43360
43825
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
43361
|
-
var SelectSeparator =
|
|
43826
|
+
var SelectSeparator = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
43362
43827
|
SelectPrimitive.Separator,
|
|
43363
43828
|
{
|
|
43364
43829
|
ref,
|
|
@@ -43984,7 +44449,7 @@ var TimePickerDropdown = ({
|
|
|
43984
44449
|
)
|
|
43985
44450
|
] });
|
|
43986
44451
|
};
|
|
43987
|
-
var SilentErrorBoundary = class extends
|
|
44452
|
+
var SilentErrorBoundary = class extends React148__default.Component {
|
|
43988
44453
|
constructor(props) {
|
|
43989
44454
|
super(props);
|
|
43990
44455
|
this.handleClearAndReload = () => {
|
|
@@ -44729,6 +45194,9 @@ var AvatarUpload = ({
|
|
|
44729
45194
|
] });
|
|
44730
45195
|
};
|
|
44731
45196
|
var CLIP_METADATA_PAGE_SIZE = 50;
|
|
45197
|
+
var RECENT_FLOW_RED_STREAK_CLIP_TYPE2 = "recent_flow_red_streak";
|
|
45198
|
+
var RECENT_FLOW_RED_STREAK_DISPLAY_LABEL = "Low moments";
|
|
45199
|
+
var RECENT_FLOW_RED_STREAK_DISPLAY_SUBTITLE = "Moments of low efficiency";
|
|
44732
45200
|
var parseCycleTime = (value) => {
|
|
44733
45201
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
44734
45202
|
return value;
|
|
@@ -44757,10 +45225,37 @@ var formatDurationLabel = (seconds) => {
|
|
|
44757
45225
|
}
|
|
44758
45226
|
return `${Math.round(roundedSeconds / 60)} min`;
|
|
44759
45227
|
};
|
|
45228
|
+
var sortRedFlowMetadata = (clips) => {
|
|
45229
|
+
return clips.slice().sort((left, right) => {
|
|
45230
|
+
const getOutputShortfall = (clip) => {
|
|
45231
|
+
const directShortfall = parseCycleTime(clip.red_flow_output_shortfall_units);
|
|
45232
|
+
if (directShortfall !== null) {
|
|
45233
|
+
return directShortfall;
|
|
45234
|
+
}
|
|
45235
|
+
return getRedFlowOutputShortfallUnits(clip.red_flow_timeline);
|
|
45236
|
+
};
|
|
45237
|
+
const leftScore = getOutputShortfall(left);
|
|
45238
|
+
const rightScore = getOutputShortfall(right);
|
|
45239
|
+
const leftNull = leftScore === null;
|
|
45240
|
+
const rightNull = rightScore === null;
|
|
45241
|
+
if (leftNull !== rightNull) {
|
|
45242
|
+
return leftNull ? 1 : -1;
|
|
45243
|
+
}
|
|
45244
|
+
if (leftScore !== null && rightScore !== null && leftScore !== rightScore) {
|
|
45245
|
+
return rightScore - leftScore;
|
|
45246
|
+
}
|
|
45247
|
+
const leftTime = new Date(left.clip_timestamp).getTime();
|
|
45248
|
+
const rightTime = new Date(right.clip_timestamp).getTime();
|
|
45249
|
+
return (Number.isFinite(rightTime) ? rightTime : 0) - (Number.isFinite(leftTime) ? leftTime : 0);
|
|
45250
|
+
});
|
|
45251
|
+
};
|
|
44760
45252
|
var getSeverityIcon = (severity, categoryId, cycleTimeSeconds, targetCycleTime, clipId) => {
|
|
44761
45253
|
if (categoryId === "idle_time" || categoryId === "low_value" || categoryId === "longest-idles") {
|
|
44762
45254
|
return null;
|
|
44763
45255
|
}
|
|
45256
|
+
if (categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
|
|
45257
|
+
return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3 w-3 text-red-500" });
|
|
45258
|
+
}
|
|
44764
45259
|
if (categoryId === "cycle_completion" && targetCycleTime && targetCycleTime > 0 && cycleTimeSeconds !== null && cycleTimeSeconds !== void 0) {
|
|
44765
45260
|
if (cycleTimeSeconds <= targetCycleTime) {
|
|
44766
45261
|
return /* @__PURE__ */ jsx(CheckCircle, { className: "h-3 w-3 text-green-500" });
|
|
@@ -44832,6 +45327,7 @@ var FileManagerFilters = ({
|
|
|
44832
45327
|
idleTimeVlmEnabled = false,
|
|
44833
45328
|
showPercentileCycleFilters = true,
|
|
44834
45329
|
prefetchedClipMetadata,
|
|
45330
|
+
externallyManagedLoadingCategories,
|
|
44835
45331
|
activeCategoryLoading,
|
|
44836
45332
|
idleClipSort = "latest",
|
|
44837
45333
|
onIdleClipSortChange,
|
|
@@ -44916,11 +45412,11 @@ var FileManagerFilters = ({
|
|
|
44916
45412
|
if (prefetchedClipMetadata && Array.isArray(prefetchedClipMetadata[categoryId]) && prefetchedClipMetadata[categoryId].length > 0) {
|
|
44917
45413
|
return true;
|
|
44918
45414
|
}
|
|
44919
|
-
if (
|
|
45415
|
+
if (externallyManagedLoadingCategories?.[categoryId]) {
|
|
44920
45416
|
return true;
|
|
44921
45417
|
}
|
|
44922
45418
|
return false;
|
|
44923
|
-
}, [prefetchedClipMetadata,
|
|
45419
|
+
}, [prefetchedClipMetadata, externallyManagedLoadingCategories]);
|
|
44924
45420
|
useEffect(() => {
|
|
44925
45421
|
if (!prefetchedClipMetadata) {
|
|
44926
45422
|
return;
|
|
@@ -45041,6 +45537,9 @@ var FileManagerFilters = ({
|
|
|
45041
45537
|
[idleReasonOptions, idleLabelFilter]
|
|
45042
45538
|
);
|
|
45043
45539
|
const getClipBadge = useCallback((node) => {
|
|
45540
|
+
if (node.categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
|
|
45541
|
+
return null;
|
|
45542
|
+
}
|
|
45044
45543
|
if (node.categoryId === "idle_time" || node.categoryId === "low_value") {
|
|
45045
45544
|
return { text: "Idle", className: "bg-red-100 text-red-700" };
|
|
45046
45545
|
}
|
|
@@ -45059,6 +45558,23 @@ var FileManagerFilters = ({
|
|
|
45059
45558
|
}
|
|
45060
45559
|
return { text: "Fast", className: "bg-green-100 text-green-700" };
|
|
45061
45560
|
}, [resolvedTargetCycleTime]);
|
|
45561
|
+
const getRedFlowDriverBadges = useCallback((node) => {
|
|
45562
|
+
if (node.categoryId !== RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
|
|
45563
|
+
return [];
|
|
45564
|
+
}
|
|
45565
|
+
const summary = node.redFlowExplanationSummary || null;
|
|
45566
|
+
const drivers = getRedFlowDisplayDriverKeys(summary);
|
|
45567
|
+
if (drivers.length === 0) {
|
|
45568
|
+
return [{
|
|
45569
|
+
text: "Low Output",
|
|
45570
|
+
className: "bg-slate-50 text-slate-600 border border-slate-200"
|
|
45571
|
+
}];
|
|
45572
|
+
}
|
|
45573
|
+
return drivers.slice(0, 3).map((driver) => ({
|
|
45574
|
+
text: getRedFlowDriverLabel(driver),
|
|
45575
|
+
className: "bg-rose-50 text-rose-700 border border-rose-200"
|
|
45576
|
+
}));
|
|
45577
|
+
}, []);
|
|
45062
45578
|
const getAuthToken4 = useCallback(async () => {
|
|
45063
45579
|
try {
|
|
45064
45580
|
return await getAccessTokenOrRedirect(supabase, { redirectReason: "session_expired" });
|
|
@@ -45067,7 +45583,7 @@ var FileManagerFilters = ({
|
|
|
45067
45583
|
return null;
|
|
45068
45584
|
}
|
|
45069
45585
|
}, [supabase]);
|
|
45070
|
-
const getMetadataLoadingKey = useCallback((categoryId, page) => `${categoryId}-${page}-${categoryId === "idle_time" ? idleClipSort : "latest"}`, [idleClipSort]);
|
|
45586
|
+
const getMetadataLoadingKey = useCallback((categoryId, page) => `${categoryId}-${page}-${categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest"}`, [idleClipSort]);
|
|
45071
45587
|
const fetchClipMetadataPage = useCallback(async (categoryId, page = 1) => {
|
|
45072
45588
|
if (!workspaceId || !date || shift === void 0) {
|
|
45073
45589
|
throw new Error("Missing required params for clip metadata fetch");
|
|
@@ -45088,7 +45604,7 @@ var FileManagerFilters = ({
|
|
|
45088
45604
|
knownTotal: typeof counts?.[categoryId] === "number" ? counts[categoryId] : null,
|
|
45089
45605
|
snapshotDateTime,
|
|
45090
45606
|
snapshotClipId,
|
|
45091
|
-
sort: categoryId === "idle_time" ? idleClipSort : "latest"
|
|
45607
|
+
sort: categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest"
|
|
45092
45608
|
}),
|
|
45093
45609
|
redirectReason: "session_expired"
|
|
45094
45610
|
});
|
|
@@ -45459,7 +45975,7 @@ var FileManagerFilters = ({
|
|
|
45459
45975
|
fetchClipMetadata(activeFilter, 1);
|
|
45460
45976
|
}
|
|
45461
45977
|
}
|
|
45462
|
-
}, [activeFilter
|
|
45978
|
+
}, [activeFilter]);
|
|
45463
45979
|
useEffect(() => {
|
|
45464
45980
|
const handleEscape = (e) => {
|
|
45465
45981
|
if (e.key === "Escape") {
|
|
@@ -45542,6 +46058,9 @@ var FileManagerFilters = ({
|
|
|
45542
46058
|
const categoryCount = counts?.[category.id] || 0;
|
|
45543
46059
|
const categoryClips = clipMetadata[category.id] || [];
|
|
45544
46060
|
let filteredClips = categoryClips.filter((clip) => isClipInTimeRange(clip.clip_timestamp));
|
|
46061
|
+
if (category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
|
|
46062
|
+
filteredClips = sortRedFlowMetadata(filteredClips);
|
|
46063
|
+
}
|
|
45545
46064
|
if (category.id === "idle_time" && idleLabelFilter) {
|
|
45546
46065
|
filteredClips = filteredClips.filter((clip) => {
|
|
45547
46066
|
const classification = getIdleTimeClassification(clip.clipId || clip.id);
|
|
@@ -45556,15 +46075,18 @@ var FileManagerFilters = ({
|
|
|
45556
46075
|
const cycleTime = extractCycleTimeSeconds(clip);
|
|
45557
46076
|
const idleDuration = category.id === "idle_time" ? clip.idle_duration_seconds ?? clip.duration : null;
|
|
45558
46077
|
const idleDurationLabel = formatDurationLabel(idleDuration);
|
|
46078
|
+
const redFlowDurationLabel = category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? formatDurationLabel(clip.duration) : null;
|
|
45559
46079
|
const baseTimeLabel = formatClipExplorerTimeLabel({
|
|
45560
46080
|
categoryId: category.id,
|
|
45561
46081
|
clipTimestamp: clip.clip_timestamp,
|
|
45562
46082
|
timezone,
|
|
45563
46083
|
durationSeconds: idleDuration ?? clip.duration,
|
|
45564
46084
|
idleStartTime: clip.idle_start_time,
|
|
45565
|
-
idleEndTime: clip.idle_end_time
|
|
46085
|
+
idleEndTime: clip.idle_end_time,
|
|
46086
|
+
clipStartTime: clip.clip_start_time,
|
|
46087
|
+
clipEndTime: clip.clip_end_time
|
|
45566
46088
|
});
|
|
45567
|
-
const displayLabel = `${baseTimeLabel}${idleDurationLabel && category.id === "idle_time" ? ` - (${idleDurationLabel})` : ""}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
|
|
46089
|
+
const displayLabel = `${baseTimeLabel}${idleDurationLabel && category.id === "idle_time" ? ` - (${idleDurationLabel})` : ""}${redFlowDurationLabel ? ` - (${redFlowDurationLabel})` : ""}${clip.duration && category.id !== "idle_time" && category.id !== "low_value" && category.id !== RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? ` - (${clip.duration.toFixed(1)}s)` : ""}`;
|
|
45568
46090
|
return {
|
|
45569
46091
|
id: clip.id,
|
|
45570
46092
|
label: displayLabel,
|
|
@@ -45580,14 +46102,18 @@ var FileManagerFilters = ({
|
|
|
45580
46102
|
cycleTimeSeconds: cycleTime,
|
|
45581
46103
|
duration: idleDuration ?? clip.duration,
|
|
45582
46104
|
// Store duration for custom badge rendering
|
|
45583
|
-
cycleItemCount: clip.cycle_item_count ?? null
|
|
46105
|
+
cycleItemCount: clip.cycle_item_count ?? null,
|
|
46106
|
+
redFlowSeverityScore: clip.red_flow_severity_score ?? null,
|
|
46107
|
+
redFlowExplanationSummary: clip.red_flow_explanation_summary ?? clip.red_flow_explanation?.summary ?? null
|
|
45584
46108
|
};
|
|
45585
46109
|
});
|
|
46110
|
+
const categoryLabel = category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? RECENT_FLOW_RED_STREAK_DISPLAY_LABEL : category.label;
|
|
46111
|
+
const categorySubtitle = category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? RECENT_FLOW_RED_STREAK_DISPLAY_SUBTITLE : category.subtitle || category.description;
|
|
45586
46112
|
regularCategoryNodes.push({
|
|
45587
46113
|
id: category.id,
|
|
45588
|
-
label:
|
|
45589
|
-
subtitle:
|
|
45590
|
-
description: category.description,
|
|
46114
|
+
label: categoryLabel,
|
|
46115
|
+
subtitle: categorySubtitle,
|
|
46116
|
+
description: category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? RECENT_FLOW_RED_STREAK_DISPLAY_SUBTITLE : category.description,
|
|
45591
46117
|
type: "category",
|
|
45592
46118
|
count: displayCount,
|
|
45593
46119
|
// Use filtered count when time filter is active
|
|
@@ -45699,7 +46225,7 @@ var FileManagerFilters = ({
|
|
|
45699
46225
|
})
|
|
45700
46226
|
} */
|
|
45701
46227
|
] : [];
|
|
45702
|
-
const orderedIds = ["cycle_completion", "fast-cycles", "slow-cycles", "idle_time"];
|
|
46228
|
+
const orderedIds = [RECENT_FLOW_RED_STREAK_CLIP_TYPE2, "cycle_completion", "fast-cycles", "slow-cycles", "idle_time"];
|
|
45703
46229
|
orderedIds.forEach((orderedId) => {
|
|
45704
46230
|
const percentileCategory = percentileCategories.find((cat) => cat.id === orderedId);
|
|
45705
46231
|
const shouldIncludePercentile = percentileCategory ? typeof percentileCategory.count === "number" && percentileCategory.count > 0 : false;
|
|
@@ -45812,8 +46338,15 @@ var FileManagerFilters = ({
|
|
|
45812
46338
|
const isCurrentVideo = currentVideoId === node.id;
|
|
45813
46339
|
const isCountUnknown = node.type === "percentile-category" && node.count === null;
|
|
45814
46340
|
const hasChildren = isCountUnknown || (node.count || 0) > 0;
|
|
45815
|
-
const
|
|
45816
|
-
|
|
46341
|
+
const hasLoadedChildren = (clipMetadata[node.id]?.length || percentileClips[node.id]?.length || 0) > 0;
|
|
46342
|
+
const loadedPage = categoryPages[node.id] || 0;
|
|
46343
|
+
const pageOneLoadingKey = getMetadataLoadingKey(node.id, 1);
|
|
46344
|
+
const nextMetadataPage = loadedPage + 1;
|
|
46345
|
+
const nextLoadMorePage = (categoryPages[node.id] || 1) + 1;
|
|
46346
|
+
const isPageOneLoading = loadingCategories.has(pageOneLoadingKey);
|
|
46347
|
+
const isLoadMoreLoading = loadedPage > 0 && loadingCategories.has(getMetadataLoadingKey(node.id, nextMetadataPage));
|
|
46348
|
+
const showInitialLoadingState = Boolean(
|
|
46349
|
+
isExpanded && !hasLoadedChildren && (node.type === "category" || node.type === "percentile-category") && (isPageOneLoading || activeCategoryLoading && node.id === activeFilter)
|
|
45817
46350
|
);
|
|
45818
46351
|
const colorClasses = node.color ? getColorClasses(node.color) : null;
|
|
45819
46352
|
return /* @__PURE__ */ jsxs("div", { className: "select-none animate-in", children: [
|
|
@@ -45855,9 +46388,9 @@ var FileManagerFilters = ({
|
|
|
45855
46388
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 flex items-center justify-between", children: [
|
|
45856
46389
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
45857
46390
|
/* @__PURE__ */ jsx("div", { className: `font-semibold tracking-tight ${node.type === "category" || node.type === "percentile-category" ? "text-slate-800 text-sm" : "text-slate-700 text-xs"} ${isCurrentVideo ? "text-blue-700 font-bold" : ""} group-hover:text-slate-900 transition-colors duration-200`, children: node.label }),
|
|
45858
|
-
node.type === "category" && categories.find((c) => c.id === node.id)?.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: categories.find((c) => c.id === node.id)?.description }),
|
|
46391
|
+
node.type === "category" && (node.subtitle || categories.find((c) => c.id === node.id)?.description) && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: node.subtitle || categories.find((c) => c.id === node.id)?.description }),
|
|
45859
46392
|
node.type === "percentile-category" && node.subtitle && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: node.subtitle }),
|
|
45860
|
-
node.type === "video" && (node.severity || node.categoryId === "cycle_completion" || node.categoryId === "idle_time" || node.categoryId === "low_value") && /* @__PURE__ */ jsx("div", { className: "text-xs mt-0.5 font-medium", children: node.categoryId === "idle_time" ? (
|
|
46393
|
+
node.type === "video" && (node.severity || node.categoryId === "cycle_completion" || node.categoryId === "idle_time" || node.categoryId === "low_value" || node.categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) && /* @__PURE__ */ jsx("div", { className: "text-xs mt-0.5 font-medium", children: node.categoryId === "idle_time" ? (
|
|
45861
46394
|
// Show root cause label for idle time clips (text only, icon is on the left)
|
|
45862
46395
|
(() => {
|
|
45863
46396
|
if (!idleTimeVlmEnabled) {
|
|
@@ -45879,8 +46412,10 @@ var FileManagerFilters = ({
|
|
|
45879
46412
|
// Show badge for other clips
|
|
45880
46413
|
(() => {
|
|
45881
46414
|
const badge = getClipBadge(node);
|
|
46415
|
+
const redFlowDriverBadges = getRedFlowDriverBadges(node);
|
|
45882
46416
|
return /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1.5", children: [
|
|
45883
|
-
/* @__PURE__ */ jsx("span", { className: `inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-medium ${badge.className}`, children: badge.text }),
|
|
46417
|
+
badge ? /* @__PURE__ */ jsx("span", { className: `inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-medium ${badge.className}`, children: badge.text }) : null,
|
|
46418
|
+
redFlowDriverBadges.map((redFlowDriverBadge) => /* @__PURE__ */ jsx("span", { className: `inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-medium ${redFlowDriverBadge.className}`, children: redFlowDriverBadge.text }, redFlowDriverBadge.text)),
|
|
45884
46419
|
node.categoryId === "cycle_completion" && node.cycleItemCount && node.cycleItemCount > 1 ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-semibold bg-blue-100 text-blue-700 border border-blue-200", children: [
|
|
45885
46420
|
"x",
|
|
45886
46421
|
node.cycleItemCount
|
|
@@ -45896,21 +46431,20 @@ var FileManagerFilters = ({
|
|
|
45896
46431
|
),
|
|
45897
46432
|
hasChildren && isExpanded && (node.type === "category" || node.type === "percentile-category") && /* @__PURE__ */ jsx("div", { className: "mt-2 ml-3 animate-in border-l-2 border-slate-100 pl-3", children: /* @__PURE__ */ jsxs("div", { className: "max-h-64 overflow-y-auto space-y-1 scrollbar-thin scrollbar-track-slate-100 scrollbar-thumb-slate-300", children: [
|
|
45898
46433
|
node.children.map((child) => renderNode(child, depth + 1)),
|
|
45899
|
-
|
|
46434
|
+
showInitialLoadingState && /* @__PURE__ */ jsx("div", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center text-sm text-slate-500", children: [
|
|
45900
46435
|
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
45901
46436
|
"Loading clips..."
|
|
45902
46437
|
] }) }),
|
|
45903
|
-
|
|
46438
|
+
isLoadMoreLoading && /* @__PURE__ */ jsx("div", { className: "py-2 px-3 text-center", children: /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center text-sm text-slate-500", children: [
|
|
45904
46439
|
/* @__PURE__ */ jsx("div", { className: "animate-spin mr-2 h-4 w-4 border-2 border-slate-300 border-t-blue-500 rounded-full" }),
|
|
45905
46440
|
"Loading more clips..."
|
|
45906
46441
|
] }) }),
|
|
45907
|
-
categoryHasMore[node.id] && !
|
|
46442
|
+
categoryHasMore[node.id] && !isLoadMoreLoading && /* @__PURE__ */ jsxs(
|
|
45908
46443
|
"button",
|
|
45909
46444
|
{
|
|
45910
46445
|
onClick: (e) => {
|
|
45911
46446
|
e.stopPropagation();
|
|
45912
|
-
|
|
45913
|
-
fetchClipMetadata(node.id, nextPage);
|
|
46447
|
+
fetchClipMetadata(node.id, nextLoadMorePage);
|
|
45914
46448
|
},
|
|
45915
46449
|
className: "w-full py-2 px-3 text-sm text-blue-600 hover:bg-blue-50 rounded-lg transition-colors duration-200 text-center",
|
|
45916
46450
|
children: [
|
|
@@ -46673,6 +47207,7 @@ var BottlenecksContent = ({
|
|
|
46673
47207
|
triageMode = false,
|
|
46674
47208
|
ticketId,
|
|
46675
47209
|
prefetchedPercentileCounts,
|
|
47210
|
+
lowMomentsPrefetch,
|
|
46676
47211
|
initialTimeFilter
|
|
46677
47212
|
}) => {
|
|
46678
47213
|
console.log("\u{1F3AB} [BottlenecksContent] Rendered with ticketId:", ticketId || "NONE", "workspaceId:", workspaceId, "date:", date, "shift:", shift);
|
|
@@ -46765,6 +47300,10 @@ var BottlenecksContent = ({
|
|
|
46765
47300
|
const [isShareLoading, setIsShareLoading] = useState(false);
|
|
46766
47301
|
const [isShareCopied, setIsShareCopied] = useState(false);
|
|
46767
47302
|
const shareCopiedTimeoutRef = useRef(null);
|
|
47303
|
+
const [lowEfficiencyAiSummaryByClipId, setLowEfficiencyAiSummaryByClipId] = useState({});
|
|
47304
|
+
const [lowEfficiencyAiSummaryLoadingByClipId, setLowEfficiencyAiSummaryLoadingByClipId] = useState({});
|
|
47305
|
+
const [lowEfficiencyAiSummaryErrorByClipId, setLowEfficiencyAiSummaryErrorByClipId] = useState({});
|
|
47306
|
+
const lowEfficiencyAiSummaryRequestStatusRef = useRef({});
|
|
46768
47307
|
useEffect(() => {
|
|
46769
47308
|
return () => {
|
|
46770
47309
|
if (shareCopiedTimeoutRef.current) {
|
|
@@ -46773,6 +47312,7 @@ var BottlenecksContent = ({
|
|
|
46773
47312
|
};
|
|
46774
47313
|
}, []);
|
|
46775
47314
|
const loadingTimeoutRef = useRef(null);
|
|
47315
|
+
const metadataLoadingKeyRef = useRef(null);
|
|
46776
47316
|
const [activeFilter, setActiveFilter] = useState(initialFilter);
|
|
46777
47317
|
const previousFilterRef = useRef("");
|
|
46778
47318
|
const [allVideos, setAllVideos] = useState([]);
|
|
@@ -46929,60 +47469,33 @@ var BottlenecksContent = ({
|
|
|
46929
47469
|
if (initialFilter) {
|
|
46930
47470
|
return;
|
|
46931
47471
|
}
|
|
47472
|
+
const redStreakType = "recent_flow_red_streak";
|
|
47473
|
+
if (dynamicCounts[redStreakType] > 0) {
|
|
47474
|
+
setInitialFilter(redStreakType);
|
|
47475
|
+
setActiveFilter(redStreakType);
|
|
47476
|
+
activeFilterRef.current = redStreakType;
|
|
47477
|
+
return;
|
|
47478
|
+
}
|
|
46932
47479
|
if (defaultCategory) {
|
|
46933
47480
|
setInitialFilter(defaultCategory);
|
|
46934
47481
|
setActiveFilter(defaultCategory);
|
|
46935
47482
|
activeFilterRef.current = defaultCategory;
|
|
46936
47483
|
return;
|
|
46937
47484
|
}
|
|
46938
|
-
if (clipTypes.length > 0) {
|
|
46939
|
-
let selectedType = null;
|
|
46940
|
-
if (clipTypes.length === 1) {
|
|
46941
|
-
selectedType = clipTypes[0];
|
|
46942
|
-
} else {
|
|
46943
|
-
const priorityOrder = ["cycle_completion", "fast-cycles", "slow-cycles", "idle_time"];
|
|
46944
|
-
for (const priorityType of priorityOrder) {
|
|
46945
|
-
const type = clipTypes.find((t) => t.type === priorityType && (dynamicCounts[t.type] || 0) > 0);
|
|
46946
|
-
if (type) {
|
|
46947
|
-
selectedType = type;
|
|
46948
|
-
break;
|
|
46949
|
-
}
|
|
46950
|
-
}
|
|
46951
|
-
if (!selectedType) {
|
|
46952
|
-
selectedType = clipTypes.find((type) => (dynamicCounts[type.type] || 0) > 0);
|
|
46953
|
-
}
|
|
46954
|
-
if (!selectedType) {
|
|
46955
|
-
selectedType = clipTypes[0];
|
|
46956
|
-
}
|
|
46957
|
-
}
|
|
46958
|
-
if (selectedType) {
|
|
46959
|
-
console.log(`[BottlenecksContent] Auto-selecting filter: ${selectedType.type} (count: ${dynamicCounts[selectedType.type] || 0})`);
|
|
46960
|
-
setInitialFilter(selectedType.type);
|
|
46961
|
-
setActiveFilter(selectedType.type);
|
|
46962
|
-
activeFilterRef.current = selectedType.type;
|
|
46963
|
-
}
|
|
46964
|
-
}
|
|
46965
47485
|
}, [clipTypes, dynamicCounts, defaultCategory, initialFilter]);
|
|
46966
47486
|
const mergedCounts = useMemo(() => {
|
|
46967
47487
|
return { ...dynamicCounts };
|
|
46968
47488
|
}, [dynamicCounts]);
|
|
46969
47489
|
useEffect(() => {
|
|
46970
|
-
if (
|
|
47490
|
+
if (allVideos.length > 0 || !isMountedRef.current) {
|
|
46971
47491
|
return;
|
|
46972
47492
|
}
|
|
46973
|
-
if (activeFilterRef.current
|
|
47493
|
+
if (!activeFilterRef.current) {
|
|
47494
|
+
setHasInitialLoad(true);
|
|
47495
|
+
setIsCategoryLoading(false);
|
|
46974
47496
|
return;
|
|
46975
47497
|
}
|
|
46976
|
-
|
|
46977
|
-
setAllVideos([firstClip]);
|
|
46978
|
-
setCurrentPosition(1);
|
|
46979
|
-
currentPositionRef.current = 1;
|
|
46980
|
-
const total = mergedCounts[firstClip.type] || 0;
|
|
46981
|
-
currentTotalRef.current = total;
|
|
46982
|
-
setCurrentTotal(total);
|
|
46983
|
-
setHasInitialLoad(true);
|
|
46984
|
-
setIsCategoryLoading(false);
|
|
46985
|
-
}, [firstClip, allVideos.length, mergedCounts]);
|
|
47498
|
+
}, [firstClips, allVideos.length, mergedCounts]);
|
|
46986
47499
|
useEffect(() => {
|
|
46987
47500
|
if (!firstClips || typeof document === "undefined") {
|
|
46988
47501
|
return;
|
|
@@ -47018,25 +47531,6 @@ var BottlenecksContent = ({
|
|
|
47018
47531
|
const loadFirstVideoForCategory = useCallback(async (category) => {
|
|
47019
47532
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current || !isEffectiveShiftReady) return;
|
|
47020
47533
|
const targetCategory = category || activeFilterRef.current;
|
|
47021
|
-
const initClip = targetCategory ? firstClips?.[targetCategory] : null;
|
|
47022
|
-
if (initClip) {
|
|
47023
|
-
setCurrentClipId(initClip.id || null);
|
|
47024
|
-
setAllVideos((prev) => {
|
|
47025
|
-
const exists = prev.some((v) => v.id === initClip.id);
|
|
47026
|
-
if (!exists) {
|
|
47027
|
-
return [...prev, initClip];
|
|
47028
|
-
}
|
|
47029
|
-
return prev;
|
|
47030
|
-
});
|
|
47031
|
-
setCurrentPosition(1);
|
|
47032
|
-
currentPositionRef.current = 1;
|
|
47033
|
-
const total = mergedCounts[targetCategory] || 0;
|
|
47034
|
-
currentTotalRef.current = total;
|
|
47035
|
-
setCurrentTotal(total);
|
|
47036
|
-
setHasInitialLoad(true);
|
|
47037
|
-
setIsCategoryLoading(false);
|
|
47038
|
-
return;
|
|
47039
|
-
}
|
|
47040
47534
|
const operationKey = `loadFirstVideo:${targetCategory}:${effectiveDateString}:${effectiveShiftId}`;
|
|
47041
47535
|
if (loadingCategoryRef.current === targetCategory || fetchInProgressRef.current.has(operationKey)) {
|
|
47042
47536
|
console.log(`[BottlenecksContent] Load first video already in progress for ${targetCategory}`);
|
|
@@ -47052,12 +47546,25 @@ var BottlenecksContent = ({
|
|
|
47052
47546
|
const shiftStr = effectiveShiftId;
|
|
47053
47547
|
console.log(`[BottlenecksContent] Loading first video for category: ${targetCategory}`);
|
|
47054
47548
|
try {
|
|
47055
|
-
|
|
47056
|
-
|
|
47057
|
-
|
|
47058
|
-
|
|
47059
|
-
|
|
47060
|
-
|
|
47549
|
+
let firstVideo = null;
|
|
47550
|
+
const totalCategoryClips = mergedCounts[targetCategory] || 0;
|
|
47551
|
+
if (totalCategoryClips > 0) {
|
|
47552
|
+
firstVideo = await s3ClipsService.getClipByIndex(
|
|
47553
|
+
workspaceId,
|
|
47554
|
+
operationalDate,
|
|
47555
|
+
shiftStr,
|
|
47556
|
+
targetCategory,
|
|
47557
|
+
0
|
|
47558
|
+
);
|
|
47559
|
+
}
|
|
47560
|
+
if (!firstVideo) {
|
|
47561
|
+
firstVideo = await s3ClipsService.getFirstClipForCategory(
|
|
47562
|
+
workspaceId,
|
|
47563
|
+
operationalDate,
|
|
47564
|
+
shiftStr,
|
|
47565
|
+
targetCategory
|
|
47566
|
+
);
|
|
47567
|
+
}
|
|
47061
47568
|
if (firstVideo) {
|
|
47062
47569
|
console.log(`[BottlenecksContent] Successfully loaded first video, ID: ${firstVideo.id}`);
|
|
47063
47570
|
setCurrentClipId(firstVideo.id || null);
|
|
@@ -47068,8 +47575,8 @@ var BottlenecksContent = ({
|
|
|
47068
47575
|
}
|
|
47069
47576
|
return prev;
|
|
47070
47577
|
});
|
|
47071
|
-
setCurrentPosition(1);
|
|
47072
|
-
currentPositionRef.current = 1;
|
|
47578
|
+
setCurrentPosition(totalCategoryClips > 0 ? 1 : 0);
|
|
47579
|
+
currentPositionRef.current = totalCategoryClips > 0 ? 1 : 0;
|
|
47073
47580
|
const total = mergedCounts[targetCategory] || 0;
|
|
47074
47581
|
currentTotalRef.current = total;
|
|
47075
47582
|
setCurrentTotal(total);
|
|
@@ -47083,13 +47590,13 @@ var BottlenecksContent = ({
|
|
|
47083
47590
|
}
|
|
47084
47591
|
if (mergedCounts[targetCategory] > 0) {
|
|
47085
47592
|
try {
|
|
47593
|
+
const fallbackIndex = 0;
|
|
47086
47594
|
const firstVideo = await s3ClipsService.getClipByIndex(
|
|
47087
47595
|
workspaceId,
|
|
47088
47596
|
operationalDate,
|
|
47089
47597
|
shiftStr,
|
|
47090
47598
|
targetCategory,
|
|
47091
|
-
|
|
47092
|
-
// First video (index 0)
|
|
47599
|
+
fallbackIndex
|
|
47093
47600
|
);
|
|
47094
47601
|
if (firstVideo && isMountedRef.current) {
|
|
47095
47602
|
console.log(`[BottlenecksContent] Successfully loaded first video via index`);
|
|
@@ -47192,11 +47699,12 @@ var BottlenecksContent = ({
|
|
|
47192
47699
|
categoryId
|
|
47193
47700
|
}));
|
|
47194
47701
|
};
|
|
47195
|
-
const [cycleClips, idleClips] = await Promise.all([
|
|
47702
|
+
const [cycleClips, redFlowClips, idleClips] = await Promise.all([
|
|
47196
47703
|
fetchCategoryMetadata("cycle_completion"),
|
|
47704
|
+
fetchCategoryMetadata("recent_flow_red_streak"),
|
|
47197
47705
|
fetchCategoryMetadata("idle_time")
|
|
47198
47706
|
]);
|
|
47199
|
-
const allClips = [...cycleClips, ...idleClips].sort(
|
|
47707
|
+
const allClips = [...cycleClips, ...redFlowClips, ...idleClips].sort(
|
|
47200
47708
|
(a, b) => new Date(b.clip_timestamp).getTime() - new Date(a.clip_timestamp).getTime()
|
|
47201
47709
|
);
|
|
47202
47710
|
setTriageClips(allClips);
|
|
@@ -47245,6 +47753,9 @@ var BottlenecksContent = ({
|
|
|
47245
47753
|
}, [idleTimeVlmEnabled, triageClips, triageMode, getAuthToken4]);
|
|
47246
47754
|
useEffect(() => {
|
|
47247
47755
|
if (s3ClipsService && (mergedCounts[activeFilter] || 0) > 0) {
|
|
47756
|
+
if (activeFilter === "recent_flow_red_streak") {
|
|
47757
|
+
return;
|
|
47758
|
+
}
|
|
47248
47759
|
if (firstClip && firstClip.type === activeFilter) {
|
|
47249
47760
|
return;
|
|
47250
47761
|
}
|
|
@@ -47265,10 +47776,10 @@ var BottlenecksContent = ({
|
|
|
47265
47776
|
return ["fast-cycles", "slow-cycles", "longest-idles"].includes(categoryId);
|
|
47266
47777
|
}, [isFastSlowClipFiltersEnabled]);
|
|
47267
47778
|
const shouldUseMetadataNavigation = useCallback((categoryId) => {
|
|
47268
|
-
return isPercentileCategory(categoryId) || categoryId === "idle_time" && idleClipSort === "idle_duration_desc";
|
|
47779
|
+
return isPercentileCategory(categoryId) || categoryId === "recent_flow_red_streak" || categoryId === "idle_time" && idleClipSort === "idle_duration_desc";
|
|
47269
47780
|
}, [idleClipSort, isPercentileCategory]);
|
|
47270
47781
|
const getMetadataCacheKey = useCallback((categoryId) => {
|
|
47271
|
-
const sortKey = categoryId === "idle_time" ? idleClipSort : "latest";
|
|
47782
|
+
const sortKey = categoryId === "recent_flow_red_streak" ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest";
|
|
47272
47783
|
return `${categoryId}-${effectiveDateString}-${effectiveShiftId}-${snapshotDateTime ?? "nosnap"}-${snapshotClipId ?? "nosnap"}-${sortKey}`;
|
|
47273
47784
|
}, [effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, idleClipSort]);
|
|
47274
47785
|
const setVisibleCategoryMetadata = useCallback((categoryId, clips) => {
|
|
@@ -47278,7 +47789,7 @@ var BottlenecksContent = ({
|
|
|
47278
47789
|
categoryMetadataRef.current = clips;
|
|
47279
47790
|
setCategoryMetadata(clips);
|
|
47280
47791
|
setCategoryMetadataCategoryId(clips.length > 0 ? categoryId : null);
|
|
47281
|
-
setCategoryMetadataSort(clips.length > 0 ? categoryId === "idle_time" ? idleClipSort : "latest" : null);
|
|
47792
|
+
setCategoryMetadataSort(clips.length > 0 ? categoryId === "recent_flow_red_streak" ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest" : null);
|
|
47282
47793
|
return true;
|
|
47283
47794
|
}, [idleClipSort]);
|
|
47284
47795
|
const applyMetadataSnapshot = useCallback((categoryId, clips, total) => {
|
|
@@ -47296,6 +47807,22 @@ var BottlenecksContent = ({
|
|
|
47296
47807
|
setCurrentTotal(total);
|
|
47297
47808
|
}
|
|
47298
47809
|
}, [getMetadataCacheKey, shouldUseMetadataNavigation, setVisibleCategoryMetadata]);
|
|
47810
|
+
const applyPrefetchedFirstVideo = useCallback((video) => {
|
|
47811
|
+
if (!video || !isMountedRef.current) {
|
|
47812
|
+
return false;
|
|
47813
|
+
}
|
|
47814
|
+
if (currentClipIdRef.current === video.id) {
|
|
47815
|
+
return true;
|
|
47816
|
+
}
|
|
47817
|
+
setCurrentClipId(video.id);
|
|
47818
|
+
setAllVideos([video]);
|
|
47819
|
+
setCurrentIndex(0);
|
|
47820
|
+
setCurrentMetadataIndex(0);
|
|
47821
|
+
currentMetadataIndexRef.current = 0;
|
|
47822
|
+
setCurrentPosition(1);
|
|
47823
|
+
currentPositionRef.current = 1;
|
|
47824
|
+
return true;
|
|
47825
|
+
}, []);
|
|
47299
47826
|
const getClipTypesForPercentileCategory = useCallback((categoryId) => {
|
|
47300
47827
|
switch (categoryId) {
|
|
47301
47828
|
case "fast-cycles":
|
|
@@ -47315,7 +47842,7 @@ var BottlenecksContent = ({
|
|
|
47315
47842
|
if (activeFilter !== "fast-cycles" && activeFilter !== "slow-cycles") {
|
|
47316
47843
|
return;
|
|
47317
47844
|
}
|
|
47318
|
-
const fallbackFilter = ["cycle_completion", "idle_time"].find((type) => (dynamicCounts[type] || 0) > 0) || clipTypes.find((type) => (dynamicCounts[type.type] || 0) > 0)?.type || clipTypes[0]?.type;
|
|
47845
|
+
const fallbackFilter = ["cycle_completion", "recent_flow_red_streak", "idle_time"].find((type) => (dynamicCounts[type] || 0) > 0) || clipTypes.find((type) => (dynamicCounts[type.type] || 0) > 0)?.type || clipTypes[0]?.type;
|
|
47319
47846
|
if (!fallbackFilter || fallbackFilter === activeFilter) {
|
|
47320
47847
|
return;
|
|
47321
47848
|
}
|
|
@@ -47371,30 +47898,70 @@ var BottlenecksContent = ({
|
|
|
47371
47898
|
setCategoryMetadataCategoryId(null);
|
|
47372
47899
|
setCategoryMetadataSort(null);
|
|
47373
47900
|
categoryMetadataRef.current = [];
|
|
47901
|
+
if (activeFilterRef.current === categoryId) {
|
|
47902
|
+
setIsCategoryLoading(false);
|
|
47903
|
+
}
|
|
47374
47904
|
return;
|
|
47375
47905
|
}
|
|
47376
47906
|
if (!isEffectiveShiftReady) {
|
|
47377
47907
|
console.log("[BottlenecksContent] Skipping metadata load - shift/date not ready");
|
|
47908
|
+
if (activeFilterRef.current === categoryId) {
|
|
47909
|
+
setIsCategoryLoading(false);
|
|
47910
|
+
}
|
|
47378
47911
|
return;
|
|
47379
47912
|
}
|
|
47380
47913
|
const resolvedDate = effectiveDateString;
|
|
47381
47914
|
const cacheKey = getMetadataCacheKey(categoryId);
|
|
47382
|
-
const
|
|
47915
|
+
const candidateLowMomentsPrefetch = lowMomentsPrefetch ?? null;
|
|
47916
|
+
const lowMomentsPrefetchMatchesScope = Boolean(
|
|
47917
|
+
candidateLowMomentsPrefetch?.key?.startsWith(`recent_flow_red_streak-${effectiveDateString}-${effectiveShiftId}-`)
|
|
47918
|
+
);
|
|
47919
|
+
const matchingLowMomentsPrefetch = !forceRefresh && categoryId === "recent_flow_red_streak" && candidateLowMomentsPrefetch && (candidateLowMomentsPrefetch.key === cacheKey || lowMomentsPrefetchMatchesScope) && !candidateLowMomentsPrefetch.loading && Array.isArray(candidateLowMomentsPrefetch.metadata) && candidateLowMomentsPrefetch.metadata.length > 0 ? candidateLowMomentsPrefetch : null;
|
|
47920
|
+
const lowMomentsPrefetchInFlight = !forceRefresh && categoryId === "recent_flow_red_streak" && candidateLowMomentsPrefetch && (candidateLowMomentsPrefetch.key === cacheKey || lowMomentsPrefetchMatchesScope) && candidateLowMomentsPrefetch.loading;
|
|
47921
|
+
if (lowMomentsPrefetchInFlight) {
|
|
47922
|
+
if (autoLoadFirstVideo && candidateLowMomentsPrefetch?.firstVideo) {
|
|
47923
|
+
applyPrefetchedFirstVideo(candidateLowMomentsPrefetch.firstVideo);
|
|
47924
|
+
}
|
|
47925
|
+
if (Array.isArray(candidateLowMomentsPrefetch?.metadata) && candidateLowMomentsPrefetch.metadata.length > 0) {
|
|
47926
|
+
applyMetadataSnapshot(categoryId, candidateLowMomentsPrefetch.metadata, candidateLowMomentsPrefetch.total);
|
|
47927
|
+
}
|
|
47928
|
+
if (activeFilterRef.current === categoryId) {
|
|
47929
|
+
setIsCategoryLoading(true);
|
|
47930
|
+
}
|
|
47931
|
+
return;
|
|
47932
|
+
}
|
|
47933
|
+
const cachedMetadata = matchingLowMomentsPrefetch?.metadata ?? (!forceRefresh ? metadataCache[cacheKey] : void 0);
|
|
47934
|
+
const requestKey = cacheKey;
|
|
47935
|
+
if (metadataLoadingKeyRef.current === requestKey) {
|
|
47936
|
+
console.log(`[BottlenecksContent] Metadata load already in progress for ${categoryId}`);
|
|
47937
|
+
return;
|
|
47938
|
+
}
|
|
47939
|
+
metadataLoadingKeyRef.current = requestKey;
|
|
47383
47940
|
try {
|
|
47384
47941
|
if (cachedMetadata) {
|
|
47385
47942
|
console.log(`[BottlenecksContent] Using cached metadata for ${categoryId}`);
|
|
47943
|
+
if (matchingLowMomentsPrefetch) {
|
|
47944
|
+
setMetadataCache((prev) => prev[cacheKey] ? prev : {
|
|
47945
|
+
...prev,
|
|
47946
|
+
[cacheKey]: matchingLowMomentsPrefetch.metadata
|
|
47947
|
+
});
|
|
47948
|
+
}
|
|
47386
47949
|
setVisibleCategoryMetadata(categoryId, cachedMetadata);
|
|
47387
47950
|
if (autoLoadFirstVideo && cachedMetadata.length > 0 && s3ClipsService) {
|
|
47388
47951
|
const firstClipMeta = cachedMetadata[0];
|
|
47952
|
+
const firstClipId = firstClipMeta.clipId || firstClipMeta.id;
|
|
47953
|
+
const prefetchedFirstVideo = matchingLowMomentsPrefetch?.firstVideo ?? null;
|
|
47389
47954
|
try {
|
|
47390
|
-
|
|
47391
|
-
if (
|
|
47392
|
-
|
|
47393
|
-
|
|
47394
|
-
|
|
47395
|
-
|
|
47396
|
-
|
|
47397
|
-
|
|
47955
|
+
let loadedVideo = null;
|
|
47956
|
+
if (prefetchedFirstVideo?.id === firstClipId) {
|
|
47957
|
+
loadedVideo = prefetchedFirstVideo;
|
|
47958
|
+
applyPrefetchedFirstVideo(prefetchedFirstVideo);
|
|
47959
|
+
} else {
|
|
47960
|
+
loadedVideo = await s3ClipsService.getClipById(firstClipId);
|
|
47961
|
+
applyPrefetchedFirstVideo(loadedVideo);
|
|
47962
|
+
}
|
|
47963
|
+
if (loadedVideo && isMountedRef.current) {
|
|
47964
|
+
console.log(`[BottlenecksContent] Auto-loaded first video from cache: ${loadedVideo.id} (1/${cachedMetadata.length})`);
|
|
47398
47965
|
}
|
|
47399
47966
|
} catch (error2) {
|
|
47400
47967
|
console.error(`[BottlenecksContent] Error loading first video from cache:`, error2);
|
|
@@ -47441,7 +48008,7 @@ var BottlenecksContent = ({
|
|
|
47441
48008
|
knownTotal: mergedCounts[categoryId] ?? null,
|
|
47442
48009
|
snapshotDateTime,
|
|
47443
48010
|
snapshotClipId,
|
|
47444
|
-
sort: categoryId === "idle_time" ? idleClipSort : "latest"
|
|
48011
|
+
sort: categoryId === "recent_flow_red_streak" ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest"
|
|
47445
48012
|
}),
|
|
47446
48013
|
redirectReason: "session_expired"
|
|
47447
48014
|
});
|
|
@@ -47502,10 +48069,11 @@ var BottlenecksContent = ({
|
|
|
47502
48069
|
console.log(`[BottlenecksContent] Loaded metadata for ${categoryId}: ${metadataClips.length} clips`);
|
|
47503
48070
|
if (autoLoadFirstVideo && metadataClips.length > 0 && s3ClipsService) {
|
|
47504
48071
|
const firstClipMeta = metadataClips[0];
|
|
48072
|
+
const firstClipId = firstClipMeta.clipId || firstClipMeta.id;
|
|
47505
48073
|
try {
|
|
47506
|
-
const video = await s3ClipsService.getClipById(
|
|
48074
|
+
const video = await s3ClipsService.getClipById(firstClipId);
|
|
47507
48075
|
if (video && isMountedRef.current) {
|
|
47508
|
-
setCurrentClipId(
|
|
48076
|
+
setCurrentClipId(firstClipId);
|
|
47509
48077
|
setAllVideos([video]);
|
|
47510
48078
|
setCurrentIndex(0);
|
|
47511
48079
|
setCurrentMetadataIndex(0);
|
|
@@ -47527,9 +48095,43 @@ var BottlenecksContent = ({
|
|
|
47527
48095
|
} catch (error2) {
|
|
47528
48096
|
console.error(`[BottlenecksContent] Error loading category metadata:`, error2);
|
|
47529
48097
|
} finally {
|
|
47530
|
-
|
|
48098
|
+
if (metadataLoadingKeyRef.current === requestKey) {
|
|
48099
|
+
metadataLoadingKeyRef.current = null;
|
|
48100
|
+
}
|
|
48101
|
+
if (activeFilterRef.current === categoryId) {
|
|
48102
|
+
setIsCategoryLoading(false);
|
|
48103
|
+
}
|
|
48104
|
+
}
|
|
48105
|
+
}, [workspaceId, effectiveDateString, effectiveShiftId, getMetadataCacheKey, isPercentileCategory, isFastSlowClipFiltersEnabled, metadataCache, s3ClipsService, clearLoadingState, isEffectiveShiftReady, snapshotDateTime, snapshotClipId, idleClipSort, supabase, setVisibleCategoryMetadata, lowMomentsPrefetch, applyPrefetchedFirstVideo, applyMetadataSnapshot]);
|
|
48106
|
+
useEffect(() => {
|
|
48107
|
+
if (activeFilter !== "recent_flow_red_streak") {
|
|
48108
|
+
return;
|
|
48109
|
+
}
|
|
48110
|
+
if (!lowMomentsPrefetch?.key?.startsWith(`recent_flow_red_streak-${effectiveDateString}-${effectiveShiftId}-`)) {
|
|
48111
|
+
return;
|
|
48112
|
+
}
|
|
48113
|
+
if (lowMomentsPrefetch.firstVideo && !allVideos.some((video) => video.type === "recent_flow_red_streak")) {
|
|
48114
|
+
applyPrefetchedFirstVideo(lowMomentsPrefetch.firstVideo);
|
|
48115
|
+
}
|
|
48116
|
+
if (lowMomentsPrefetch.metadata.length > 0) {
|
|
48117
|
+
applyMetadataSnapshot("recent_flow_red_streak", lowMomentsPrefetch.metadata, lowMomentsPrefetch.total);
|
|
48118
|
+
if (isMountedRef.current) {
|
|
48119
|
+
setIsCategoryLoading(false);
|
|
48120
|
+
}
|
|
48121
|
+
return;
|
|
48122
|
+
}
|
|
48123
|
+
if (isMountedRef.current) {
|
|
48124
|
+
setIsCategoryLoading(lowMomentsPrefetch.loading);
|
|
47531
48125
|
}
|
|
47532
|
-
}, [
|
|
48126
|
+
}, [
|
|
48127
|
+
activeFilter,
|
|
48128
|
+
lowMomentsPrefetch,
|
|
48129
|
+
effectiveDateString,
|
|
48130
|
+
effectiveShiftId,
|
|
48131
|
+
allVideos,
|
|
48132
|
+
applyPrefetchedFirstVideo,
|
|
48133
|
+
applyMetadataSnapshot
|
|
48134
|
+
]);
|
|
47533
48135
|
useEffect(() => {
|
|
47534
48136
|
if (previousIdleClipSortRef.current === idleClipSort) {
|
|
47535
48137
|
return;
|
|
@@ -47569,8 +48171,13 @@ var BottlenecksContent = ({
|
|
|
47569
48171
|
currentTotalRef.current = total;
|
|
47570
48172
|
setCurrentTotal(total);
|
|
47571
48173
|
previousFilterRef.current = activeFilter;
|
|
47572
|
-
|
|
47573
|
-
|
|
48174
|
+
const metadataLoadPlan = getCategoryMetadataLoadPlanForFilterChange({
|
|
48175
|
+
activeFilter,
|
|
48176
|
+
currentClipId,
|
|
48177
|
+
categoryTotal: total
|
|
48178
|
+
});
|
|
48179
|
+
if (metadataLoadPlan.shouldLoad) {
|
|
48180
|
+
loadCategoryMetadata(activeFilter, metadataLoadPlan.autoLoadFirstVideo);
|
|
47574
48181
|
}
|
|
47575
48182
|
const filtered = allVideos.filter((video) => {
|
|
47576
48183
|
if (activeFilter === "all") return true;
|
|
@@ -47593,11 +48200,11 @@ var BottlenecksContent = ({
|
|
|
47593
48200
|
if (!currentClipId || activeFilter === "all") {
|
|
47594
48201
|
return;
|
|
47595
48202
|
}
|
|
47596
|
-
if (categoryMetadataRef.current.length > 0
|
|
48203
|
+
if (categoryMetadataRef.current.length > 0) {
|
|
47597
48204
|
return;
|
|
47598
48205
|
}
|
|
47599
48206
|
loadCategoryMetadata(activeFilter, false);
|
|
47600
|
-
}, [currentClipId, activeFilter,
|
|
48207
|
+
}, [currentClipId, activeFilter, loadCategoryMetadata]);
|
|
47601
48208
|
const loadAndPlayClipById = useCallback(async (clipId, categoryId, position, metadataContext) => {
|
|
47602
48209
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
|
|
47603
48210
|
console.log(`[BottlenecksContent] Loading clip by ID: ${clipId}, category=${categoryId}, position=${position}`);
|
|
@@ -48056,6 +48663,98 @@ var BottlenecksContent = ({
|
|
|
48056
48663
|
}
|
|
48057
48664
|
return filteredVideos[currentIndex];
|
|
48058
48665
|
}, [filteredVideos, currentIndex]);
|
|
48666
|
+
const currentLowEfficiencyClipId = currentVideo?.id || currentClipId || null;
|
|
48667
|
+
const isCurrentLowEfficiencyClip = Boolean(
|
|
48668
|
+
currentVideo?.type === "recent_flow_red_streak" || currentVideo?.red_flow_timeline
|
|
48669
|
+
);
|
|
48670
|
+
const currentLowEfficiencyAiSummary = currentLowEfficiencyClipId ? lowEfficiencyAiSummaryByClipId[currentLowEfficiencyClipId] || currentVideo?.low_efficiency_ai_summary || null : null;
|
|
48671
|
+
const isCurrentLowEfficiencyAiSummaryLoading = Boolean(
|
|
48672
|
+
currentLowEfficiencyClipId && lowEfficiencyAiSummaryLoadingByClipId[currentLowEfficiencyClipId]
|
|
48673
|
+
);
|
|
48674
|
+
const currentLowEfficiencyAiSummaryError = currentLowEfficiencyClipId ? lowEfficiencyAiSummaryErrorByClipId[currentLowEfficiencyClipId] || null : null;
|
|
48675
|
+
useEffect(() => {
|
|
48676
|
+
const clipId = currentLowEfficiencyClipId;
|
|
48677
|
+
if (!clipId || !isCurrentLowEfficiencyClip || !workspaceId) {
|
|
48678
|
+
return;
|
|
48679
|
+
}
|
|
48680
|
+
if (currentVideo?.low_efficiency_ai_summary || lowEfficiencyAiSummaryRequestStatusRef.current[clipId]) {
|
|
48681
|
+
return;
|
|
48682
|
+
}
|
|
48683
|
+
let cancelled = false;
|
|
48684
|
+
let timedOut = false;
|
|
48685
|
+
const controller = new AbortController();
|
|
48686
|
+
lowEfficiencyAiSummaryRequestStatusRef.current[clipId] = "loading";
|
|
48687
|
+
const timeout = setTimeout(() => {
|
|
48688
|
+
timedOut = true;
|
|
48689
|
+
controller.abort();
|
|
48690
|
+
}, 3e4);
|
|
48691
|
+
setLowEfficiencyAiSummaryLoadingByClipId((prev) => ({ ...prev, [clipId]: true }));
|
|
48692
|
+
setLowEfficiencyAiSummaryErrorByClipId((prev) => ({ ...prev, [clipId]: null }));
|
|
48693
|
+
void (async () => {
|
|
48694
|
+
try {
|
|
48695
|
+
const response = await fetchWithSupabaseAuth(supabase, "/api/clips/supabase", {
|
|
48696
|
+
method: "POST",
|
|
48697
|
+
headers: {
|
|
48698
|
+
"Content-Type": "application/json"
|
|
48699
|
+
},
|
|
48700
|
+
signal: controller.signal,
|
|
48701
|
+
body: JSON.stringify({
|
|
48702
|
+
action: "ai-summary",
|
|
48703
|
+
workspaceId,
|
|
48704
|
+
clipId,
|
|
48705
|
+
workspaceName
|
|
48706
|
+
}),
|
|
48707
|
+
redirectReason: "session_expired"
|
|
48708
|
+
});
|
|
48709
|
+
if (!response.ok) {
|
|
48710
|
+
throw new Error(`AI summary API error: ${response.status}`);
|
|
48711
|
+
}
|
|
48712
|
+
const payload = await response.json();
|
|
48713
|
+
const summary = payload?.summary;
|
|
48714
|
+
if (!summary || !Array.isArray(summary.bullets) || summary.bullets.filter((bullet) => String(bullet || "").trim()).length < 3) {
|
|
48715
|
+
throw new Error("AI summary response was empty");
|
|
48716
|
+
}
|
|
48717
|
+
if (!cancelled) {
|
|
48718
|
+
lowEfficiencyAiSummaryRequestStatusRef.current[clipId] = "success";
|
|
48719
|
+
setLowEfficiencyAiSummaryByClipId((prev) => ({ ...prev, [clipId]: summary }));
|
|
48720
|
+
}
|
|
48721
|
+
} catch (error2) {
|
|
48722
|
+
if (cancelled) {
|
|
48723
|
+
return;
|
|
48724
|
+
}
|
|
48725
|
+
lowEfficiencyAiSummaryRequestStatusRef.current[clipId] = "error";
|
|
48726
|
+
const message = timedOut ? "AI summary timed out" : error2 instanceof Error ? error2.message : "AI summary unavailable";
|
|
48727
|
+
console.warn("[BottlenecksContent] Failed to generate Low Efficiency AI summary:", error2);
|
|
48728
|
+
setLowEfficiencyAiSummaryErrorByClipId((prev) => ({
|
|
48729
|
+
...prev,
|
|
48730
|
+
[clipId]: message
|
|
48731
|
+
}));
|
|
48732
|
+
} finally {
|
|
48733
|
+
clearTimeout(timeout);
|
|
48734
|
+
if (isMountedRef.current) {
|
|
48735
|
+
setLowEfficiencyAiSummaryLoadingByClipId((prev) => ({ ...prev, [clipId]: false }));
|
|
48736
|
+
}
|
|
48737
|
+
}
|
|
48738
|
+
})();
|
|
48739
|
+
return () => {
|
|
48740
|
+
cancelled = true;
|
|
48741
|
+
clearTimeout(timeout);
|
|
48742
|
+
if (lowEfficiencyAiSummaryRequestStatusRef.current[clipId] === "loading") {
|
|
48743
|
+
delete lowEfficiencyAiSummaryRequestStatusRef.current[clipId];
|
|
48744
|
+
}
|
|
48745
|
+
if (isMountedRef.current) {
|
|
48746
|
+
setLowEfficiencyAiSummaryLoadingByClipId((prev) => ({ ...prev, [clipId]: false }));
|
|
48747
|
+
}
|
|
48748
|
+
controller.abort();
|
|
48749
|
+
};
|
|
48750
|
+
}, [
|
|
48751
|
+
currentLowEfficiencyClipId,
|
|
48752
|
+
currentVideo?.low_efficiency_ai_summary,
|
|
48753
|
+
isCurrentLowEfficiencyClip,
|
|
48754
|
+
supabase,
|
|
48755
|
+
workspaceId,
|
|
48756
|
+
workspaceName
|
|
48757
|
+
]);
|
|
48059
48758
|
const handleShareClip = useCallback(async () => {
|
|
48060
48759
|
if (!currentVideo?.id || isShareLoading) {
|
|
48061
48760
|
if (!currentVideo?.id) {
|
|
@@ -48127,11 +48826,11 @@ var BottlenecksContent = ({
|
|
|
48127
48826
|
}
|
|
48128
48827
|
return currentPosition;
|
|
48129
48828
|
}, [activeFilter, categoryMetadata.length, currentMetadataIndex, currentPosition, shouldUseMetadataNavigation]);
|
|
48130
|
-
const prefetchedExplorerMetadata = useMemo(() => activeFilter === "idle_time" && categoryMetadataSort !== idleClipSort ? void 0 : buildPrefetchedExplorerMetadata(
|
|
48829
|
+
const prefetchedExplorerMetadata = useMemo(() => activeFilter === "recent_flow_red_streak" && lowMomentsPrefetch?.key?.startsWith(`recent_flow_red_streak-${effectiveDateString}-${effectiveShiftId}-`) && !lowMomentsPrefetch.loading && lowMomentsPrefetch.metadata.length > 0 ? { recent_flow_red_streak: lowMomentsPrefetch.metadata } : activeFilter === "idle_time" && categoryMetadataSort !== idleClipSort ? void 0 : buildPrefetchedExplorerMetadata(
|
|
48131
48830
|
activeFilter,
|
|
48132
48831
|
categoryMetadataCategoryId,
|
|
48133
48832
|
categoryMetadata
|
|
48134
|
-
), [activeFilter, categoryMetadata, categoryMetadataCategoryId, categoryMetadataSort, idleClipSort]);
|
|
48833
|
+
), [activeFilter, categoryMetadata, categoryMetadataCategoryId, categoryMetadataSort, idleClipSort, lowMomentsPrefetch, effectiveDateString, effectiveShiftId]);
|
|
48135
48834
|
const classificationClipIds = useMemo(() => {
|
|
48136
48835
|
if (!idleTimeVlmEnabled) {
|
|
48137
48836
|
return [];
|
|
@@ -48523,6 +49222,8 @@ var BottlenecksContent = ({
|
|
|
48523
49222
|
return "Cycle Completion";
|
|
48524
49223
|
case "idle_time":
|
|
48525
49224
|
return "Idle Time";
|
|
49225
|
+
case "recent_flow_red_streak":
|
|
49226
|
+
return "Low efficiency videos";
|
|
48526
49227
|
case "running_cycle":
|
|
48527
49228
|
return "Running Cycle";
|
|
48528
49229
|
case "setup_state":
|
|
@@ -48602,12 +49303,26 @@ var BottlenecksContent = ({
|
|
|
48602
49303
|
onShare: handleShareClip,
|
|
48603
49304
|
isShareLoading,
|
|
48604
49305
|
isShareCopied,
|
|
49306
|
+
timelineAnnotations: currentVideo.red_flow_timeline,
|
|
49307
|
+
timelineExplanation: currentVideo.red_flow_explanation,
|
|
49308
|
+
timelineTimezone: timezone,
|
|
48605
49309
|
options: videoPlayerOptions
|
|
48606
49310
|
},
|
|
48607
49311
|
`${currentVideo.id}-${playerInstanceNonce}-inline`
|
|
48608
49312
|
)
|
|
48609
49313
|
}
|
|
48610
49314
|
),
|
|
49315
|
+
currentVideo.type === "recent_flow_red_streak" && !shouldDeferPlayerRenderForCrop ? /* @__PURE__ */ jsx(
|
|
49316
|
+
RedFlowDiagnosticOverlay,
|
|
49317
|
+
{
|
|
49318
|
+
timeline: currentVideo.red_flow_timeline,
|
|
49319
|
+
explanation: currentVideo.red_flow_explanation,
|
|
49320
|
+
aiSummary: currentLowEfficiencyAiSummary,
|
|
49321
|
+
aiSummaryLoading: isCurrentLowEfficiencyAiSummaryLoading,
|
|
49322
|
+
aiSummaryError: currentLowEfficiencyAiSummaryError,
|
|
49323
|
+
className: "right-4 top-4"
|
|
49324
|
+
}
|
|
49325
|
+
) : null,
|
|
48611
49326
|
showBlockingVideoLoader && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
|
|
48612
49327
|
!shouldDeferPlayerRenderForCrop && !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
|
|
48613
49328
|
error && error.type === "retrying" && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-40 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
@@ -48707,10 +49422,10 @@ var BottlenecksContent = ({
|
|
|
48707
49422
|
] }) })
|
|
48708
49423
|
] });
|
|
48709
49424
|
})()
|
|
48710
|
-
) : /* @__PURE__ */ jsx("div", { className:
|
|
49425
|
+
) : /* @__PURE__ */ jsx("div", { className: `absolute top-3 z-10 bg-black/60 backdrop-blur-sm px-3 py-1.5 rounded-lg text-white shadow-lg text-xs ${currentVideo.type === "recent_flow_red_streak" ? "left-3" : "right-3"}`, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
48711
49426
|
/* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 rounded-full ${getSeverityColor(currentVideo.severity)} mr-2 animate-pulse` }),
|
|
48712
49427
|
/* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
|
|
48713
|
-
/* @__PURE__ */ jsx("span", { className: "opacity-80 hidden sm:inline", children: currentVideo.description })
|
|
49428
|
+
currentVideo.type !== "recent_flow_red_streak" && /* @__PURE__ */ jsx("span", { className: "opacity-80 hidden sm:inline", children: currentVideo.description })
|
|
48714
49429
|
] }) })
|
|
48715
49430
|
)
|
|
48716
49431
|
] }) }) }) : (
|
|
@@ -48720,14 +49435,21 @@ var BottlenecksContent = ({
|
|
|
48720
49435
|
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Clips Found" }),
|
|
48721
49436
|
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There were no video clips found for this workspace today." })
|
|
48722
49437
|
] }) }) : (
|
|
48723
|
-
/* Priority
|
|
48724
|
-
hasInitialLoad &&
|
|
49438
|
+
/* Priority 5.5: Show "no folder selected" if activeFilter is empty */
|
|
49439
|
+
hasInitialLoad && !activeFilter ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-[220px] sm:min-h-[320px] lg:h-full", children: /* @__PURE__ */ jsxs("div", { className: "text-center p-8", children: [
|
|
48725
49440
|
/* @__PURE__ */ jsx("svg", { className: "w-16 h-16 text-gray-300 mx-auto mb-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" }) }),
|
|
48726
|
-
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No
|
|
48727
|
-
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "
|
|
49441
|
+
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Folder Selected" }),
|
|
49442
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "Please select a folder to view clips." })
|
|
48728
49443
|
] }) }) : (
|
|
48729
|
-
/* Priority
|
|
48730
|
-
|
|
49444
|
+
/* Priority 6: Show "no matching clips" only if we have data loaded and specifically no clips for this filter */
|
|
49445
|
+
hasInitialLoad && (mergedCounts[activeFilter] || 0) === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-[220px] sm:min-h-[320px] lg:h-full", children: /* @__PURE__ */ jsxs("div", { className: "text-center p-8", children: [
|
|
49446
|
+
/* @__PURE__ */ jsx("svg", { className: "w-16 h-16 text-gray-300 mx-auto mb-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" }) }),
|
|
49447
|
+
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Matching Clips" }),
|
|
49448
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There are no clips matching the selected filter." })
|
|
49449
|
+
] }) }) : (
|
|
49450
|
+
/* Priority 7: Default loading state for any other case */
|
|
49451
|
+
/* @__PURE__ */ jsx("div", { className: "p-4 lg:h-full", children: /* @__PURE__ */ jsx("div", { className: "relative lg:h-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full min-h-[220px] sm:min-h-[320px] lg:min-h-0 lg:h-full overflow-hidden rounded-md shadow-inner bg-gray-900 flex items-center justify-center", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading..." }) }) }) })
|
|
49452
|
+
)
|
|
48731
49453
|
)
|
|
48732
49454
|
)
|
|
48733
49455
|
) }) }),
|
|
@@ -48879,6 +49601,11 @@ var BottlenecksContent = ({
|
|
|
48879
49601
|
idleTimeVlmEnabled,
|
|
48880
49602
|
showPercentileCycleFilters: isFastSlowClipFiltersEnabled,
|
|
48881
49603
|
prefetchedClipMetadata: prefetchedExplorerMetadata,
|
|
49604
|
+
externallyManagedLoadingCategories: {
|
|
49605
|
+
recent_flow_red_streak: Boolean(
|
|
49606
|
+
activeFilter === "recent_flow_red_streak" && lowMomentsPrefetch?.key?.startsWith(`recent_flow_red_streak-${effectiveDateString}-${effectiveShiftId}-`) && lowMomentsPrefetch.loading
|
|
49607
|
+
)
|
|
49608
|
+
},
|
|
48882
49609
|
activeCategoryLoading: isCategoryLoading,
|
|
48883
49610
|
idleClipSort,
|
|
48884
49611
|
onIdleClipSortChange: setIdleClipSort,
|
|
@@ -48994,10 +49721,10 @@ var BottlenecksContent = ({
|
|
|
48994
49721
|
] }) })
|
|
48995
49722
|
] });
|
|
48996
49723
|
})()
|
|
48997
|
-
) : /* @__PURE__ */ jsx("div", { className:
|
|
49724
|
+
) : /* @__PURE__ */ jsx("div", { className: `absolute top-4 z-50 bg-black/60 backdrop-blur-sm px-4 py-2 rounded-lg text-white shadow-lg ${currentVideo.type === "recent_flow_red_streak" ? "left-4" : "right-20"}`, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
48998
49725
|
/* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-3 w-3 rounded-full ${getSeverityColor(currentVideo.severity)} mr-2 animate-pulse` }),
|
|
48999
49726
|
/* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
|
|
49000
|
-
/* @__PURE__ */ jsx("span", { className: "opacity-80", children: currentVideo.description })
|
|
49727
|
+
currentVideo.type !== "recent_flow_red_streak" && /* @__PURE__ */ jsx("span", { className: "opacity-80", children: currentVideo.description })
|
|
49001
49728
|
] }) }),
|
|
49002
49729
|
/* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center p-8", children: /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full max-w-7xl group", children: [
|
|
49003
49730
|
/* @__PURE__ */ jsx(
|
|
@@ -49033,12 +49760,26 @@ var BottlenecksContent = ({
|
|
|
49033
49760
|
onShare: handleShareClip,
|
|
49034
49761
|
isShareLoading,
|
|
49035
49762
|
isShareCopied,
|
|
49763
|
+
timelineAnnotations: currentVideo.red_flow_timeline,
|
|
49764
|
+
timelineExplanation: currentVideo.red_flow_explanation,
|
|
49765
|
+
timelineTimezone: timezone,
|
|
49036
49766
|
options: videoPlayerOptions
|
|
49037
49767
|
},
|
|
49038
49768
|
`${currentVideo.id}-${playerInstanceNonce}-fullscreen`
|
|
49039
49769
|
)
|
|
49040
49770
|
}
|
|
49041
49771
|
),
|
|
49772
|
+
currentVideo.type === "recent_flow_red_streak" && !shouldDeferPlayerRenderForCrop ? /* @__PURE__ */ jsx(
|
|
49773
|
+
RedFlowDiagnosticOverlay,
|
|
49774
|
+
{
|
|
49775
|
+
timeline: currentVideo.red_flow_timeline,
|
|
49776
|
+
explanation: currentVideo.red_flow_explanation,
|
|
49777
|
+
aiSummary: currentLowEfficiencyAiSummary,
|
|
49778
|
+
aiSummaryLoading: isCurrentLowEfficiencyAiSummaryLoading,
|
|
49779
|
+
aiSummaryError: currentLowEfficiencyAiSummaryError,
|
|
49780
|
+
className: "right-8 top-8"
|
|
49781
|
+
}
|
|
49782
|
+
) : null,
|
|
49042
49783
|
showBlockingVideoLoader && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
|
|
49043
49784
|
!shouldDeferPlayerRenderForCrop && !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
|
|
49044
49785
|
/* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-white", children: [
|
|
@@ -51061,8 +51802,8 @@ var IdleTimeReasonChartComponent = ({
|
|
|
51061
51802
|
updateAnimation = "replay",
|
|
51062
51803
|
variant = "pie"
|
|
51063
51804
|
}) => {
|
|
51064
|
-
const [activeData, setActiveData] =
|
|
51065
|
-
|
|
51805
|
+
const [activeData, setActiveData] = React148__default.useState([]);
|
|
51806
|
+
React148__default.useEffect(() => {
|
|
51066
51807
|
if (updateAnimation === "smooth") {
|
|
51067
51808
|
setActiveData(data && data.length > 0 ? data : []);
|
|
51068
51809
|
return;
|
|
@@ -51081,7 +51822,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
51081
51822
|
setActiveData([]);
|
|
51082
51823
|
}
|
|
51083
51824
|
}, [data, updateAnimation]);
|
|
51084
|
-
|
|
51825
|
+
React148__default.useEffect(() => {
|
|
51085
51826
|
if (!data || data.length === 0) return;
|
|
51086
51827
|
data.forEach((entry, index) => {
|
|
51087
51828
|
if (entry.name.toLowerCase().includes("other")) {
|
|
@@ -51089,7 +51830,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
51089
51830
|
}
|
|
51090
51831
|
});
|
|
51091
51832
|
}, [data]);
|
|
51092
|
-
const pieKey =
|
|
51833
|
+
const pieKey = React148__default.useMemo(() => {
|
|
51093
51834
|
if (updateAnimation === "smooth") {
|
|
51094
51835
|
return "smooth";
|
|
51095
51836
|
}
|
|
@@ -51259,7 +52000,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
51259
52000
|
)
|
|
51260
52001
|
] });
|
|
51261
52002
|
};
|
|
51262
|
-
var IdleTimeReasonChart =
|
|
52003
|
+
var IdleTimeReasonChart = React148__default.memo(IdleTimeReasonChartComponent);
|
|
51263
52004
|
IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
|
|
51264
52005
|
var IdleTimeReasonChart_default = IdleTimeReasonChart;
|
|
51265
52006
|
|
|
@@ -53483,7 +54224,7 @@ var StatusIndicator = ({ status }) => {
|
|
|
53483
54224
|
case "bottleneck":
|
|
53484
54225
|
return /* @__PURE__ */ jsx(Zap, { className: "h-5 w-5 text-orange-400", "aria-label": "Bottleneck" });
|
|
53485
54226
|
case "lowEfficiency":
|
|
53486
|
-
return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-5 w-5 text-red-400", "aria-label": "Low
|
|
54227
|
+
return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-5 w-5 text-red-400", "aria-label": "Low moments" });
|
|
53487
54228
|
case "inactive":
|
|
53488
54229
|
return /* @__PURE__ */ jsx("div", { className: "h-3 w-3 bg-gray-400 rounded-full", title: "Inactive", "aria-label": "Inactive Workspace" });
|
|
53489
54230
|
default:
|
|
@@ -55786,13 +56527,13 @@ var WorkspaceCycleTimeMetricCards = ({
|
|
|
55786
56527
|
liveSkuId
|
|
55787
56528
|
}) => {
|
|
55788
56529
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
55789
|
-
const activeSku =
|
|
56530
|
+
const activeSku = React148__default.useMemo(() => {
|
|
55790
56531
|
if (skuAware && activeSkuId && skuBreakdown) {
|
|
55791
56532
|
return skuBreakdown.find((s) => s.sku_id === activeSkuId);
|
|
55792
56533
|
}
|
|
55793
56534
|
return null;
|
|
55794
56535
|
}, [skuAware, activeSkuId, skuBreakdown]);
|
|
55795
|
-
const displaySku =
|
|
56536
|
+
const displaySku = React148__default.useMemo(() => {
|
|
55796
56537
|
if (activeSku) return activeSku;
|
|
55797
56538
|
if (skuAware && !activeSkuId && liveSkuId && skuBreakdown) {
|
|
55798
56539
|
return skuBreakdown.find((s) => s.sku_id === liveSkuId) ?? null;
|
|
@@ -56037,7 +56778,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
56037
56778
|
return prevProps.data.efficiency === nextProps.data.efficiency && prevProps.data.trend_score === nextProps.data.trend_score && prevProps.data.workspace_id === nextProps.data.workspace_id && prevProps.data.workspace_name === nextProps.data.workspace_name && prevProps.isBottleneck === nextProps.isBottleneck && prevProps.isLowEfficiency === nextProps.isLowEfficiency && prevProps.isVeryLowEfficiency === nextProps.isVeryLowEfficiency && prevLegend.green_min === nextLegend.green_min && prevLegend.green_max === nextLegend.green_max && prevLegend.yellow_min === nextLegend.yellow_min && prevLegend.yellow_max === nextLegend.yellow_max && prevLegend.red_min === nextLegend.red_min && prevLegend.red_max === nextLegend.red_max && prevLegend.critical_threshold === nextLegend.critical_threshold && // Position doesn't need deep equality check as it's generally static
|
|
56038
56779
|
prevProps.position.id === nextProps.position.id;
|
|
56039
56780
|
};
|
|
56040
|
-
var WorkspaceGridItem =
|
|
56781
|
+
var WorkspaceGridItem = React148__default.memo(({
|
|
56041
56782
|
data,
|
|
56042
56783
|
position,
|
|
56043
56784
|
isBottleneck = false,
|
|
@@ -56132,7 +56873,7 @@ var WorkspaceGridItem = React147__default.memo(({
|
|
|
56132
56873
|
);
|
|
56133
56874
|
}, arePropsEqual);
|
|
56134
56875
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
56135
|
-
var WorkspaceGrid =
|
|
56876
|
+
var WorkspaceGrid = React148__default.memo(({
|
|
56136
56877
|
workspaces,
|
|
56137
56878
|
blueComparisonWorkspaces,
|
|
56138
56879
|
isPdfMode = false,
|
|
@@ -56385,7 +57126,7 @@ var KPICard = ({
|
|
|
56385
57126
|
}) => {
|
|
56386
57127
|
useThemeConfig();
|
|
56387
57128
|
const { formatNumber } = useFormatNumber();
|
|
56388
|
-
const trendInfo =
|
|
57129
|
+
const trendInfo = React148__default.useMemo(() => {
|
|
56389
57130
|
let trendValue = trend || "neutral";
|
|
56390
57131
|
if (change !== void 0 && trend === void 0) {
|
|
56391
57132
|
trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
|
|
@@ -56412,7 +57153,7 @@ var KPICard = ({
|
|
|
56412
57153
|
const shouldShowTrend = !(change === 0 && trend === void 0);
|
|
56413
57154
|
return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
|
|
56414
57155
|
}, [trend, change]);
|
|
56415
|
-
const formattedValue =
|
|
57156
|
+
const formattedValue = React148__default.useMemo(() => {
|
|
56416
57157
|
if (title === "Quality Compliance" && typeof value === "number") {
|
|
56417
57158
|
return value.toFixed(1);
|
|
56418
57159
|
}
|
|
@@ -56426,7 +57167,7 @@ var KPICard = ({
|
|
|
56426
57167
|
}
|
|
56427
57168
|
return value;
|
|
56428
57169
|
}, [value, title]);
|
|
56429
|
-
const formattedChange =
|
|
57170
|
+
const formattedChange = React148__default.useMemo(() => {
|
|
56430
57171
|
if (change === void 0 || change === 0 && !showZeroChange) return null;
|
|
56431
57172
|
const absChange = Math.abs(change);
|
|
56432
57173
|
return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
|
|
@@ -57933,7 +58674,7 @@ var Breadcrumbs = ({ items }) => {
|
|
|
57933
58674
|
}
|
|
57934
58675
|
}
|
|
57935
58676
|
};
|
|
57936
|
-
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
58677
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(React148__default.Fragment, { children: [
|
|
57937
58678
|
index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
|
|
57938
58679
|
/* @__PURE__ */ jsxs(
|
|
57939
58680
|
"span",
|
|
@@ -59457,7 +60198,7 @@ var AwardBadge = ({
|
|
|
59457
60198
|
}) => {
|
|
59458
60199
|
const styles2 = getBadgeStyles(type);
|
|
59459
60200
|
const Icon2 = CustomIcon || getDefaultIcon(type);
|
|
59460
|
-
const randomDelay =
|
|
60201
|
+
const randomDelay = React148__default.useMemo(() => Math.random() * 2, []);
|
|
59461
60202
|
const floatingAnimation = {
|
|
59462
60203
|
animate: {
|
|
59463
60204
|
y: [0, -10, 0],
|
|
@@ -67826,7 +68567,7 @@ function HomeView({
|
|
|
67826
68567
|
animate: { opacity: 1, scale: 1 },
|
|
67827
68568
|
transition: { duration: 0.3 },
|
|
67828
68569
|
className: "h-full",
|
|
67829
|
-
children:
|
|
68570
|
+
children: React148__default.createElement(WorkspaceGrid, {
|
|
67830
68571
|
workspaces: workspaceMetricsWithBreakState,
|
|
67831
68572
|
blueComparisonWorkspaces: currentBlueComparisonWorkspaceMetrics || workspaceMetricsWithBreakState,
|
|
67832
68573
|
lineNames: mergedLineNames,
|
|
@@ -67859,7 +68600,7 @@ function HomeView({
|
|
|
67859
68600
|
animate: { opacity: 1, scale: 1 },
|
|
67860
68601
|
transition: { duration: 0.3 },
|
|
67861
68602
|
className: "h-full",
|
|
67862
|
-
children:
|
|
68603
|
+
children: React148__default.createElement(WorkspaceGrid, {
|
|
67863
68604
|
workspaces: [],
|
|
67864
68605
|
// Show empty grid while loading
|
|
67865
68606
|
blueComparisonWorkspaces: [],
|
|
@@ -67906,7 +68647,7 @@ function HomeView({
|
|
|
67906
68647
|
contentVariant: "plain"
|
|
67907
68648
|
}
|
|
67908
68649
|
),
|
|
67909
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(
|
|
68650
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(React148__default.Fragment, { children: [
|
|
67910
68651
|
/* @__PURE__ */ jsx(
|
|
67911
68652
|
motion.div,
|
|
67912
68653
|
{
|
|
@@ -67985,7 +68726,7 @@ function HomeView({
|
|
|
67985
68726
|
"all-green-center-toast"
|
|
67986
68727
|
)
|
|
67987
68728
|
] }, "all-green-celebration") : null }),
|
|
67988
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(
|
|
68729
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(React148__default.Fragment, { children: [
|
|
67989
68730
|
/* @__PURE__ */ jsx(
|
|
67990
68731
|
motion.div,
|
|
67991
68732
|
{
|
|
@@ -68079,7 +68820,7 @@ function HomeView({
|
|
|
68079
68820
|
}
|
|
68080
68821
|
);
|
|
68081
68822
|
}
|
|
68082
|
-
var AuthenticatedHomeView = withAuth(
|
|
68823
|
+
var AuthenticatedHomeView = withAuth(React148__default.memo(HomeView));
|
|
68083
68824
|
var HomeView_default = HomeView;
|
|
68084
68825
|
function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
68085
68826
|
const {
|
|
@@ -71428,7 +72169,14 @@ var formatSupervisorFirstNames = (supervisors, fallbackSupervisorNames) => {
|
|
|
71428
72169
|
return fallbackFirstNames.length > 0 ? Array.from(new Set(fallbackFirstNames)).join(", ") : "Unassigned";
|
|
71429
72170
|
};
|
|
71430
72171
|
var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Finished", placeholder = "--", onFinished }) => {
|
|
71431
|
-
const [time2, setTime] = useState(
|
|
72172
|
+
const [time2, setTime] = useState(() => {
|
|
72173
|
+
if (!targetDate) return "";
|
|
72174
|
+
return targetDate.getTime() <= Date.now() ? finishedLabel : "";
|
|
72175
|
+
});
|
|
72176
|
+
const [showEndsInPrefix, setShowEndsInPrefix] = useState(() => {
|
|
72177
|
+
if (!targetDate) return true;
|
|
72178
|
+
return targetDate.getTime() > Date.now();
|
|
72179
|
+
});
|
|
71432
72180
|
const hasFinishedRef = useRef(false);
|
|
71433
72181
|
useEffect(() => {
|
|
71434
72182
|
hasFinishedRef.current = false;
|
|
@@ -71436,12 +72184,14 @@ var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Fin
|
|
|
71436
72184
|
useEffect(() => {
|
|
71437
72185
|
if (!targetDate) {
|
|
71438
72186
|
setTime(placeholder);
|
|
72187
|
+
setShowEndsInPrefix(true);
|
|
71439
72188
|
return;
|
|
71440
72189
|
}
|
|
71441
72190
|
const tick = () => {
|
|
71442
72191
|
const now4 = /* @__PURE__ */ new Date();
|
|
71443
72192
|
const diff = targetDate.getTime() - now4.getTime();
|
|
71444
72193
|
if (diff <= 0) {
|
|
72194
|
+
setShowEndsInPrefix(false);
|
|
71445
72195
|
setTime(finishedLabel);
|
|
71446
72196
|
if (!hasFinishedRef.current && onFinished) {
|
|
71447
72197
|
hasFinishedRef.current = true;
|
|
@@ -71449,6 +72199,7 @@ var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Fin
|
|
|
71449
72199
|
}
|
|
71450
72200
|
return;
|
|
71451
72201
|
}
|
|
72202
|
+
setShowEndsInPrefix(true);
|
|
71452
72203
|
if (format10 === "days") {
|
|
71453
72204
|
const days = Math.floor(diff / (1e3 * 60 * 60 * 24));
|
|
71454
72205
|
const hours = Math.floor(diff % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60));
|
|
@@ -71465,7 +72216,10 @@ var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Fin
|
|
|
71465
72216
|
const interval = setInterval(tick, 1e3);
|
|
71466
72217
|
return () => clearInterval(interval);
|
|
71467
72218
|
}, [targetDate, format10, finishedLabel, placeholder, onFinished]);
|
|
71468
|
-
return /* @__PURE__ */
|
|
72219
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
72220
|
+
showEndsInPrefix && /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider", children: "Ends in" }),
|
|
72221
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-gray-900 tabular-nums tracking-tight font-mono", children: time2 })
|
|
72222
|
+
] });
|
|
71469
72223
|
};
|
|
71470
72224
|
var LinesLeaderboard = ({
|
|
71471
72225
|
lines,
|
|
@@ -71488,18 +72242,18 @@ var LinesLeaderboard = ({
|
|
|
71488
72242
|
isHistoricalDaily
|
|
71489
72243
|
}) => {
|
|
71490
72244
|
const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
|
|
71491
|
-
const assignedLineIdSet =
|
|
72245
|
+
const assignedLineIdSet = React148__default.useMemo(
|
|
71492
72246
|
() => new Set(assignedLineIds || []),
|
|
71493
72247
|
[assignedLineIds]
|
|
71494
72248
|
);
|
|
71495
|
-
const canClickLine =
|
|
72249
|
+
const canClickLine = React148__default.useCallback(
|
|
71496
72250
|
(lineId) => {
|
|
71497
72251
|
if (!assignedLineIds) return true;
|
|
71498
72252
|
return assignedLineIdSet.has(lineId);
|
|
71499
72253
|
},
|
|
71500
72254
|
[assignedLineIds, assignedLineIdSet]
|
|
71501
72255
|
);
|
|
71502
|
-
const handleTimeRangeChange =
|
|
72256
|
+
const handleTimeRangeChange = React148__default.useCallback((newRange) => {
|
|
71503
72257
|
if (newRange === timeRange) return;
|
|
71504
72258
|
trackCoreEvent("Leaderboard Time Range Changed", {
|
|
71505
72259
|
from_range: timeRange,
|
|
@@ -71510,11 +72264,11 @@ var LinesLeaderboard = ({
|
|
|
71510
72264
|
});
|
|
71511
72265
|
setTimeRange(newRange);
|
|
71512
72266
|
}, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
|
|
71513
|
-
const canClickLeaderboardRow =
|
|
72267
|
+
const canClickLeaderboardRow = React148__default.useCallback(
|
|
71514
72268
|
(item) => item.rowType === "line" && !!item.line && canClickLine(item.line.id),
|
|
71515
72269
|
[canClickLine]
|
|
71516
72270
|
);
|
|
71517
|
-
const handleLeaderboardLineClick =
|
|
72271
|
+
const handleLeaderboardLineClick = React148__default.useCallback((item, clickSource) => {
|
|
71518
72272
|
if (!canClickLeaderboardRow(item) || !item.line) return;
|
|
71519
72273
|
trackCoreEvent("Leaderboard Line Clicked", {
|
|
71520
72274
|
line_id: item.line.id,
|
|
@@ -71528,8 +72282,8 @@ var LinesLeaderboard = ({
|
|
|
71528
72282
|
});
|
|
71529
72283
|
onLineClick(item.line);
|
|
71530
72284
|
}, [canClickLeaderboardRow, onLineClick, timeRange]);
|
|
71531
|
-
const viewLoadedTrackedRef =
|
|
71532
|
-
const leaderboardData =
|
|
72285
|
+
const viewLoadedTrackedRef = React148__default.useRef(null);
|
|
72286
|
+
const leaderboardData = React148__default.useMemo(() => {
|
|
71533
72287
|
const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
71534
72288
|
const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
|
|
71535
72289
|
const fallbackEfficiencyMap = timeRange === "today" ? dailyFallbackEfficiencyByLineId : void 0;
|
|
@@ -71573,7 +72327,7 @@ var LinesLeaderboard = ({
|
|
|
71573
72327
|
isLoadingToday,
|
|
71574
72328
|
isLoadingMonthly
|
|
71575
72329
|
]);
|
|
71576
|
-
|
|
72330
|
+
React148__default.useEffect(() => {
|
|
71577
72331
|
const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
71578
72332
|
const trackingKey = `${timeRange}-${leaderboardData.length}`;
|
|
71579
72333
|
if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
|
|
@@ -71597,9 +72351,9 @@ var LinesLeaderboard = ({
|
|
|
71597
72351
|
const topThree = leaderboardData.slice(0, 3);
|
|
71598
72352
|
const countdownTarget = timeRange === "monthly" ? monthEndDate : shiftEndDate;
|
|
71599
72353
|
const countdownFormat = timeRange === "monthly" ? "days" : "clock";
|
|
71600
|
-
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift
|
|
72354
|
+
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift ended";
|
|
71601
72355
|
const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
|
|
71602
|
-
const handleCountdownFinished =
|
|
72356
|
+
const handleCountdownFinished = React148__default.useCallback(() => {
|
|
71603
72357
|
trackCoreEvent("Leaderboard Countdown Finished", {
|
|
71604
72358
|
countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
|
|
71605
72359
|
time_range: timeRange,
|
|
@@ -71626,7 +72380,7 @@ var LinesLeaderboard = ({
|
|
|
71626
72380
|
return "bg-white border-gray-100";
|
|
71627
72381
|
}
|
|
71628
72382
|
};
|
|
71629
|
-
|
|
72383
|
+
React148__default.useEffect(() => {
|
|
71630
72384
|
const style = document.createElement("style");
|
|
71631
72385
|
style.innerHTML = `
|
|
71632
72386
|
@keyframes float {
|
|
@@ -71674,19 +72428,16 @@ var LinesLeaderboard = ({
|
|
|
71674
72428
|
] }),
|
|
71675
72429
|
/* @__PURE__ */ jsx("div", { className: "md:absolute md:right-0 md:top-1/2 md:-translate-y-1/2 flex flex-wrap items-center justify-center md:justify-end gap-2", children: showCountdown && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 px-4 py-2 bg-white rounded-full shadow-sm border border-gray-100", children: [
|
|
71676
72430
|
/* @__PURE__ */ jsx(Clock, { className: "w-4 h-4 text-orange-500" }),
|
|
71677
|
-
/* @__PURE__ */
|
|
71678
|
-
|
|
71679
|
-
|
|
71680
|
-
|
|
71681
|
-
|
|
71682
|
-
|
|
71683
|
-
|
|
71684
|
-
|
|
71685
|
-
|
|
71686
|
-
|
|
71687
|
-
}
|
|
71688
|
-
) })
|
|
71689
|
-
] })
|
|
72431
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-baseline gap-2", children: /* @__PURE__ */ jsx(
|
|
72432
|
+
LeaderboardCountdown,
|
|
72433
|
+
{
|
|
72434
|
+
targetDate: countdownTarget,
|
|
72435
|
+
format: countdownFormat,
|
|
72436
|
+
finishedLabel: countdownFinishedLabel,
|
|
72437
|
+
placeholder: timeRange === "monthly" ? "--" : "--:--:--",
|
|
72438
|
+
onFinished: handleCountdownFinished
|
|
72439
|
+
}
|
|
72440
|
+
) })
|
|
71690
72441
|
] }) })
|
|
71691
72442
|
] }),
|
|
71692
72443
|
/* @__PURE__ */ jsx("div", { className: "flex-1 hidden sm:flex justify-center items-end gap-2 md:gap-4 lg:gap-6 xl:gap-10 pb-4 pt-4 min-h-0", children: podiumOrder.map((item, index) => {
|
|
@@ -72128,36 +72879,36 @@ var KPIsOverviewView = ({
|
|
|
72128
72879
|
const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
|
|
72129
72880
|
const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
|
|
72130
72881
|
const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
|
|
72131
|
-
const scopedLineIds =
|
|
72882
|
+
const scopedLineIds = React148__default.useMemo(
|
|
72132
72883
|
() => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
|
|
72133
72884
|
[user?.access_scope?.line_ids]
|
|
72134
72885
|
);
|
|
72135
72886
|
const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
|
|
72136
72887
|
const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
|
|
72137
72888
|
const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
|
|
72138
|
-
const resolvedAssignedLineIds =
|
|
72889
|
+
const resolvedAssignedLineIds = React148__default.useMemo(() => {
|
|
72139
72890
|
if (isSuperAdmin) return [];
|
|
72140
72891
|
if (scopedLineIds.length > 0) return scopedLineIds;
|
|
72141
72892
|
if (lineIds && lineIds.length > 0) return lineIds;
|
|
72142
72893
|
if (isStrictLineScopedRole && hasCanonicalScope) return [];
|
|
72143
72894
|
return [];
|
|
72144
72895
|
}, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
|
|
72145
|
-
const assignedLineIdSet =
|
|
72896
|
+
const assignedLineIdSet = React148__default.useMemo(
|
|
72146
72897
|
() => new Set(resolvedAssignedLineIds),
|
|
72147
72898
|
[resolvedAssignedLineIds]
|
|
72148
72899
|
);
|
|
72149
|
-
const loadedLineIds =
|
|
72900
|
+
const loadedLineIds = React148__default.useMemo(
|
|
72150
72901
|
() => lines.map((line) => line.id).filter(Boolean),
|
|
72151
72902
|
[lines]
|
|
72152
72903
|
);
|
|
72153
|
-
const metricsLineIds =
|
|
72904
|
+
const metricsLineIds = React148__default.useMemo(() => {
|
|
72154
72905
|
if (isSuperAdmin) {
|
|
72155
72906
|
return loadedLineIds.length > 0 ? loadedLineIds : lineIds ?? [];
|
|
72156
72907
|
}
|
|
72157
72908
|
return resolvedAssignedLineIds;
|
|
72158
72909
|
}, [isSuperAdmin, loadedLineIds, lineIds, resolvedAssignedLineIds]);
|
|
72159
72910
|
const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
|
|
72160
|
-
const leaderboardLinesForView =
|
|
72911
|
+
const leaderboardLinesForView = React148__default.useMemo(() => {
|
|
72161
72912
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
72162
72913
|
const metadataByLineId = new Map(lines.map((line) => [line.id, line]));
|
|
72163
72914
|
return leaderboardLines.map((line) => {
|
|
@@ -72176,17 +72927,17 @@ var KPIsOverviewView = ({
|
|
|
72176
72927
|
} : line;
|
|
72177
72928
|
}).filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
72178
72929
|
}, [leaderboardLines, lines, viewType]);
|
|
72179
|
-
const linesForView =
|
|
72930
|
+
const linesForView = React148__default.useMemo(() => {
|
|
72180
72931
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
72181
72932
|
return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
72182
72933
|
}, [lines, viewType]);
|
|
72183
|
-
const relevantLinesForMode =
|
|
72934
|
+
const relevantLinesForMode = React148__default.useMemo(() => {
|
|
72184
72935
|
if (activeTab === "leaderboard") {
|
|
72185
72936
|
return leaderboardLines.length > 0 ? leaderboardLines : lines;
|
|
72186
72937
|
}
|
|
72187
72938
|
return lines;
|
|
72188
72939
|
}, [activeTab, leaderboardLines, lines]);
|
|
72189
|
-
const { hasUptime, hasOutput } =
|
|
72940
|
+
const { hasUptime, hasOutput } = React148__default.useMemo(() => {
|
|
72190
72941
|
let uptime = false;
|
|
72191
72942
|
let output = false;
|
|
72192
72943
|
for (const line of relevantLinesForMode) {
|
|
@@ -72211,14 +72962,14 @@ var KPIsOverviewView = ({
|
|
|
72211
72962
|
const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
|
|
72212
72963
|
const currentShiftDate = currentShiftDetails.date;
|
|
72213
72964
|
const currentShiftId = currentShiftDetails.shiftId;
|
|
72214
|
-
const activeFiltersCount =
|
|
72965
|
+
const activeFiltersCount = React148__default.useMemo(() => {
|
|
72215
72966
|
let count = 0;
|
|
72216
72967
|
if (leaderboardDailyScopeMode === "historical" && selectedLeaderboardShiftId !== currentShiftId) {
|
|
72217
72968
|
count++;
|
|
72218
72969
|
}
|
|
72219
72970
|
return count;
|
|
72220
72971
|
}, [leaderboardDailyScopeMode, selectedLeaderboardShiftId, currentShiftId]);
|
|
72221
|
-
const clearFilters =
|
|
72972
|
+
const clearFilters = React148__default.useCallback(() => {
|
|
72222
72973
|
setSelectedLeaderboardShiftId(currentShiftId);
|
|
72223
72974
|
setSelectedLeaderboardDate(currentShiftDate);
|
|
72224
72975
|
setLeaderboardDailyScopeMode("live");
|
|
@@ -72234,11 +72985,11 @@ var KPIsOverviewView = ({
|
|
|
72234
72985
|
document.addEventListener("mousedown", handleClickOutside);
|
|
72235
72986
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
72236
72987
|
}, []);
|
|
72237
|
-
const shiftEndDate =
|
|
72988
|
+
const shiftEndDate = React148__default.useMemo(
|
|
72238
72989
|
() => getShiftEndDate(currentShiftDetails, configuredTimezone),
|
|
72239
72990
|
[currentShiftDetails, configuredTimezone]
|
|
72240
72991
|
);
|
|
72241
|
-
const leaderboardShiftOptions =
|
|
72992
|
+
const leaderboardShiftOptions = React148__default.useMemo(() => {
|
|
72242
72993
|
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
72243
72994
|
return shiftConfig.shifts.map((shift) => ({
|
|
72244
72995
|
id: shift.shiftId,
|
|
@@ -72255,34 +73006,34 @@ var KPIsOverviewView = ({
|
|
|
72255
73006
|
const effectiveLeaderboardDate = selectedLeaderboardDate || currentShiftDate;
|
|
72256
73007
|
const effectiveLeaderboardShiftId = Number.isFinite(selectedLeaderboardShiftId) ? selectedLeaderboardShiftId : currentShiftId;
|
|
72257
73008
|
const isHistoricalLeaderboardDaily = activeTab === "leaderboard" && timeRange === "today" && leaderboardDailyScopeMode === "historical" && (effectiveLeaderboardDate !== currentShiftDate || effectiveLeaderboardShiftId !== currentShiftId);
|
|
72258
|
-
const updateLeaderboardDate =
|
|
73009
|
+
const updateLeaderboardDate = React148__default.useCallback((dateKey) => {
|
|
72259
73010
|
setSelectedLeaderboardDate(dateKey);
|
|
72260
73011
|
setLeaderboardDailyScopeMode(
|
|
72261
73012
|
dateKey === currentShiftDate && effectiveLeaderboardShiftId === currentShiftId ? "live" : "historical"
|
|
72262
73013
|
);
|
|
72263
73014
|
}, [currentShiftDate, currentShiftId, effectiveLeaderboardShiftId]);
|
|
72264
|
-
const updateLeaderboardShiftId =
|
|
73015
|
+
const updateLeaderboardShiftId = React148__default.useCallback((shiftId) => {
|
|
72265
73016
|
setSelectedLeaderboardShiftId(shiftId);
|
|
72266
73017
|
setLeaderboardDailyScopeMode(
|
|
72267
73018
|
effectiveLeaderboardDate === currentShiftDate && shiftId === currentShiftId ? "live" : "historical"
|
|
72268
73019
|
);
|
|
72269
73020
|
}, [currentShiftDate, currentShiftId, effectiveLeaderboardDate]);
|
|
72270
|
-
const returnLeaderboardToLive =
|
|
73021
|
+
const returnLeaderboardToLive = React148__default.useCallback(() => {
|
|
72271
73022
|
setSelectedLeaderboardDate(currentShiftDate);
|
|
72272
73023
|
setSelectedLeaderboardShiftId(currentShiftId);
|
|
72273
73024
|
setLeaderboardDailyScopeMode("live");
|
|
72274
73025
|
}, [currentShiftDate, currentShiftId]);
|
|
72275
73026
|
const selectedFactoryIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_QUERY_PARAM]);
|
|
72276
73027
|
const selectedFactoryAreaIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_AREA_QUERY_PARAM]);
|
|
72277
|
-
const kpiLineHierarchy =
|
|
73028
|
+
const kpiLineHierarchy = React148__default.useMemo(
|
|
72278
73029
|
() => buildKpiLineHierarchy(linesForView),
|
|
72279
73030
|
[linesForView]
|
|
72280
73031
|
);
|
|
72281
|
-
const selectedFactoryNode =
|
|
73032
|
+
const selectedFactoryNode = React148__default.useMemo(
|
|
72282
73033
|
() => kpiLineHierarchy.showFactoryLevel && selectedFactoryIdFromUrl ? kpiLineHierarchy.factories.find((factory) => factory.id === selectedFactoryIdFromUrl) : void 0,
|
|
72283
73034
|
[kpiLineHierarchy, selectedFactoryIdFromUrl]
|
|
72284
73035
|
);
|
|
72285
|
-
const selectedFactoryAreaNode =
|
|
73036
|
+
const selectedFactoryAreaNode = React148__default.useMemo(
|
|
72286
73037
|
() => selectedFactoryNode && selectedFactoryAreaIdFromUrl ? selectedFactoryNode.areas.find((area) => area.id === selectedFactoryAreaIdFromUrl) : void 0,
|
|
72287
73038
|
[selectedFactoryNode, selectedFactoryAreaIdFromUrl]
|
|
72288
73039
|
);
|
|
@@ -72371,15 +73122,15 @@ var KPIsOverviewView = ({
|
|
|
72371
73122
|
lineId: factoryViewId,
|
|
72372
73123
|
userAccessibleLineIds: metricsLineIds
|
|
72373
73124
|
});
|
|
72374
|
-
const defaultKPIs =
|
|
72375
|
-
const lineModeById =
|
|
73125
|
+
const defaultKPIs = React148__default.useMemo(() => createDefaultKPIs(), []);
|
|
73126
|
+
const lineModeById = React148__default.useMemo(() => {
|
|
72376
73127
|
const map = /* @__PURE__ */ new Map();
|
|
72377
73128
|
linesForView.forEach((line) => {
|
|
72378
73129
|
map.set(line.id, line.monitoring_mode ?? "output");
|
|
72379
73130
|
});
|
|
72380
73131
|
return map;
|
|
72381
73132
|
}, [linesForView]);
|
|
72382
|
-
const lineMetricRowsByLineId =
|
|
73133
|
+
const lineMetricRowsByLineId = React148__default.useMemo(() => {
|
|
72383
73134
|
const map = /* @__PURE__ */ new Map();
|
|
72384
73135
|
lineMetrics.forEach((row) => {
|
|
72385
73136
|
if (!row?.line_id) return;
|
|
@@ -72391,7 +73142,7 @@ var KPIsOverviewView = ({
|
|
|
72391
73142
|
});
|
|
72392
73143
|
return map;
|
|
72393
73144
|
}, [lineMetrics, lineModeById]);
|
|
72394
|
-
const liveDailyFallbackEfficiencyByLineId =
|
|
73145
|
+
const liveDailyFallbackEfficiencyByLineId = React148__default.useMemo(() => {
|
|
72395
73146
|
const map = /* @__PURE__ */ new Map();
|
|
72396
73147
|
lineMetricRowsByLineId.forEach((row, lineId) => {
|
|
72397
73148
|
const value = Number(row?.avg_efficiency);
|
|
@@ -72413,31 +73164,31 @@ var KPIsOverviewView = ({
|
|
|
72413
73164
|
isHistoricalLeaderboardDaily,
|
|
72414
73165
|
lineMetricRowsByLineId
|
|
72415
73166
|
]);
|
|
72416
|
-
const dailyFallbackEfficiencyByLineId =
|
|
73167
|
+
const dailyFallbackEfficiencyByLineId = React148__default.useMemo(() => {
|
|
72417
73168
|
const map = new Map(liveDailyFallbackEfficiencyByLineId);
|
|
72418
73169
|
scopedDailyFallbackEfficiencyByLineId.forEach((value, lineId) => {
|
|
72419
73170
|
map.set(lineId, value);
|
|
72420
73171
|
});
|
|
72421
73172
|
return map;
|
|
72422
73173
|
}, [liveDailyFallbackEfficiencyByLineId, scopedDailyFallbackEfficiencyByLineId]);
|
|
72423
|
-
const kpisByLineId =
|
|
73174
|
+
const kpisByLineId = React148__default.useMemo(() => {
|
|
72424
73175
|
const map = /* @__PURE__ */ new Map();
|
|
72425
73176
|
lineMetricRowsByLineId.forEach((row, lineId) => {
|
|
72426
73177
|
map.set(lineId, buildKPIsFromLineMetricsRow(row));
|
|
72427
73178
|
});
|
|
72428
73179
|
return map;
|
|
72429
73180
|
}, [lineMetricRowsByLineId]);
|
|
72430
|
-
const getLineCardKpis =
|
|
73181
|
+
const getLineCardKpis = React148__default.useCallback((line) => {
|
|
72431
73182
|
if (metricsError) return null;
|
|
72432
73183
|
return kpisByLineId.get(line.id) ?? (metricsLoading ? null : defaultKPIs);
|
|
72433
73184
|
}, [defaultKPIs, kpisByLineId, metricsError, metricsLoading]);
|
|
72434
|
-
const getAggregateCardKpis =
|
|
73185
|
+
const getAggregateCardKpis = React148__default.useCallback((cardLines) => {
|
|
72435
73186
|
if (metricsError) return null;
|
|
72436
73187
|
const rows = cardLines.map((line) => lineMetricRowsByLineId.get(line.id)).filter(Boolean);
|
|
72437
73188
|
if (metricsLoading && rows.length === 0) return null;
|
|
72438
73189
|
return aggregateKPIsFromLineMetricsRows(rows);
|
|
72439
73190
|
}, [lineMetricRowsByLineId, metricsError, metricsLoading]);
|
|
72440
|
-
const supervisorLineIds =
|
|
73191
|
+
const supervisorLineIds = React148__default.useMemo(
|
|
72441
73192
|
() => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
|
|
72442
73193
|
[leaderboardLines, lines]
|
|
72443
73194
|
);
|
|
@@ -72689,7 +73440,7 @@ var KPIsOverviewView = ({
|
|
|
72689
73440
|
{ shallow: true }
|
|
72690
73441
|
);
|
|
72691
73442
|
}, [router]);
|
|
72692
|
-
const lineDetailReturnTo =
|
|
73443
|
+
const lineDetailReturnTo = React148__default.useMemo(() => {
|
|
72693
73444
|
if (activeTab !== "today" || !selectedFactoryNode) return void 0;
|
|
72694
73445
|
return createKpisOverviewUrl({
|
|
72695
73446
|
factoryId: selectedFactoryNode.id,
|
|
@@ -73489,7 +74240,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
73489
74240
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
73490
74241
|
}, []);
|
|
73491
74242
|
const [isMobile, setIsMobile] = useState(false);
|
|
73492
|
-
|
|
74243
|
+
React148__default.useEffect(() => {
|
|
73493
74244
|
const checkMobile = () => setIsMobile(window.innerWidth < 640);
|
|
73494
74245
|
checkMobile();
|
|
73495
74246
|
window.addEventListener("resize", checkMobile);
|
|
@@ -77539,7 +78290,7 @@ var ShiftsView = ({
|
|
|
77539
78290
|
] })
|
|
77540
78291
|
] });
|
|
77541
78292
|
};
|
|
77542
|
-
var AuthenticatedShiftsView = withAuth(
|
|
78293
|
+
var AuthenticatedShiftsView = withAuth(React148__default.memo(ShiftsView));
|
|
77543
78294
|
var ShiftsView_default = ShiftsView;
|
|
77544
78295
|
|
|
77545
78296
|
// src/views/TargetsView.utils.ts
|
|
@@ -79406,7 +80157,7 @@ var TargetsView = ({
|
|
|
79406
80157
|
};
|
|
79407
80158
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
79408
80159
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
79409
|
-
var AuthenticatedTargetsView = withAuth(
|
|
80160
|
+
var AuthenticatedTargetsView = withAuth(React148__default.memo(TargetsViewWithDisplayNames));
|
|
79410
80161
|
function useTimezone(options = {}) {
|
|
79411
80162
|
const dashboardConfig = useDashboardConfig();
|
|
79412
80163
|
const workspaceConfig = useWorkspaceConfig();
|
|
@@ -79554,7 +80305,7 @@ var formatWholeNumber = (value) => {
|
|
|
79554
80305
|
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
79555
80306
|
return Math.round(value).toLocaleString();
|
|
79556
80307
|
};
|
|
79557
|
-
var
|
|
80308
|
+
var formatSeconds2 = (value) => {
|
|
79558
80309
|
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
79559
80310
|
return `${value.toFixed(1)}s`;
|
|
79560
80311
|
};
|
|
@@ -79571,13 +80322,13 @@ var WorkspaceHourSummaryPanel = ({
|
|
|
79571
80322
|
}) => {
|
|
79572
80323
|
const { data, isLoading, error, summarize, reset } = useWorkspaceHourSummary();
|
|
79573
80324
|
const selectedKey = selectedHour ? `${selectedHour.source}:${selectedHour.hourIndex}:${date}:${shiftId}` : "none";
|
|
79574
|
-
const autoSummaryKeyRef =
|
|
79575
|
-
|
|
80325
|
+
const autoSummaryKeyRef = React148__default.useRef(null);
|
|
80326
|
+
React148__default.useEffect(() => {
|
|
79576
80327
|
reset();
|
|
79577
80328
|
autoSummaryKeyRef.current = null;
|
|
79578
80329
|
}, [reset, selectedKey]);
|
|
79579
80330
|
const canSummarize = Boolean(workspaceId && companyId && date && shiftId !== null && shiftId !== void 0);
|
|
79580
|
-
|
|
80331
|
+
React148__default.useEffect(() => {
|
|
79581
80332
|
if (!selectedHour || !canSummarize || !companyId || !date || shiftId === null || shiftId === void 0) {
|
|
79582
80333
|
return;
|
|
79583
80334
|
}
|
|
@@ -79606,8 +80357,8 @@ var WorkspaceHourSummaryPanel = ({
|
|
|
79606
80357
|
const formattedTimeRange = formatTimeRangeTo12Hour(verifiedTimeRange);
|
|
79607
80358
|
const selectedMetric = selectedHour.source === "cycle" ? {
|
|
79608
80359
|
label: "Cycle time",
|
|
79609
|
-
actual:
|
|
79610
|
-
standard:
|
|
80360
|
+
actual: formatSeconds2(selectedHour.cycleTime),
|
|
80361
|
+
standard: formatSeconds2(selectedHour.idealCycleTime)
|
|
79611
80362
|
} : {
|
|
79612
80363
|
label: "Hourly output",
|
|
79613
80364
|
actual: formatWholeNumber(selectedHour.output),
|
|
@@ -79783,6 +80534,7 @@ var WorkspaceDetailView = ({
|
|
|
79783
80534
|
const { legend: efficiencyLegend } = useEfficiencyLegend();
|
|
79784
80535
|
const prewarmedClipsRef = useRef(/* @__PURE__ */ new Set());
|
|
79785
80536
|
const prewarmInFlightRef = useRef(/* @__PURE__ */ new Set());
|
|
80537
|
+
const [lowMomentsPrefetch, setLowMomentsPrefetch] = useState(null);
|
|
79786
80538
|
const [aiSummaryHour, setAiSummaryHour] = useState(null);
|
|
79787
80539
|
const buildHourlyOutputActionTrackingProps = useCallback((payload) => ({
|
|
79788
80540
|
workspace_id: workspaceId,
|
|
@@ -80295,13 +81047,108 @@ var WorkspaceDetailView = ({
|
|
|
80295
81047
|
}
|
|
80296
81048
|
prewarmInFlightRef.current.add(cacheKey);
|
|
80297
81049
|
const s3Service = videoPrefetchManager.getS3Service(dashboardConfig);
|
|
80298
|
-
|
|
80299
|
-
|
|
80300
|
-
|
|
80301
|
-
|
|
80302
|
-
|
|
80303
|
-
|
|
80304
|
-
|
|
81050
|
+
const controller = new AbortController();
|
|
81051
|
+
let cancelled = false;
|
|
81052
|
+
const prefetchLowMoments = async () => {
|
|
81053
|
+
try {
|
|
81054
|
+
const initData = await s3Service.getClipsInit(workspaceId, resolvedDate, resolvedShiftId, totalOutput);
|
|
81055
|
+
const lowMomentsCount = Number(initData?.counts?.recent_flow_red_streak || 0);
|
|
81056
|
+
const lowMomentsKey = [
|
|
81057
|
+
"recent_flow_red_streak",
|
|
81058
|
+
resolvedDate,
|
|
81059
|
+
resolvedShiftId,
|
|
81060
|
+
initData?.snapshotDateTime ?? "nosnap",
|
|
81061
|
+
initData?.snapshotClipId ?? "nosnap",
|
|
81062
|
+
"red_flow_output_shortfall_desc"
|
|
81063
|
+
].join("-");
|
|
81064
|
+
if (cancelled) {
|
|
81065
|
+
return;
|
|
81066
|
+
}
|
|
81067
|
+
const initFirstVideo = initData?.firstClips?.recent_flow_red_streak ?? null;
|
|
81068
|
+
if (lowMomentsCount <= 0) {
|
|
81069
|
+
setLowMomentsPrefetch((prev) => prev?.key === lowMomentsKey ? {
|
|
81070
|
+
key: lowMomentsKey,
|
|
81071
|
+
metadata: [],
|
|
81072
|
+
firstVideo: null,
|
|
81073
|
+
total: 0,
|
|
81074
|
+
loading: false,
|
|
81075
|
+
error: null
|
|
81076
|
+
} : prev);
|
|
81077
|
+
prewarmedClipsRef.current.add(cacheKey);
|
|
81078
|
+
return;
|
|
81079
|
+
}
|
|
81080
|
+
setLowMomentsPrefetch((prev) => {
|
|
81081
|
+
if (prev?.key === lowMomentsKey && !prev.loading && prev.metadata.length > 0) {
|
|
81082
|
+
return prev;
|
|
81083
|
+
}
|
|
81084
|
+
return {
|
|
81085
|
+
key: lowMomentsKey,
|
|
81086
|
+
metadata: prev?.key === lowMomentsKey ? prev.metadata : [],
|
|
81087
|
+
firstVideo: prev?.key === lowMomentsKey ? prev.firstVideo || initFirstVideo : initFirstVideo,
|
|
81088
|
+
total: lowMomentsCount,
|
|
81089
|
+
loading: true,
|
|
81090
|
+
error: null
|
|
81091
|
+
};
|
|
81092
|
+
});
|
|
81093
|
+
const metadataResponse = await fetchWithSupabaseAuth(supabase, "/api/clips/supabase", {
|
|
81094
|
+
method: "POST",
|
|
81095
|
+
headers: {
|
|
81096
|
+
"Content-Type": "application/json"
|
|
81097
|
+
},
|
|
81098
|
+
body: JSON.stringify({
|
|
81099
|
+
action: "clip-metadata",
|
|
81100
|
+
workspaceId,
|
|
81101
|
+
date: resolvedDate,
|
|
81102
|
+
shift: resolvedShiftId,
|
|
81103
|
+
category: "recent_flow_red_streak",
|
|
81104
|
+
page: 1,
|
|
81105
|
+
limit: 100,
|
|
81106
|
+
knownTotal: lowMomentsCount,
|
|
81107
|
+
snapshotDateTime: initData?.snapshotDateTime ?? null,
|
|
81108
|
+
snapshotClipId: initData?.snapshotClipId ?? null,
|
|
81109
|
+
sort: "red_flow_output_shortfall_desc"
|
|
81110
|
+
}),
|
|
81111
|
+
signal: controller.signal,
|
|
81112
|
+
redirectReason: "session_expired"
|
|
81113
|
+
});
|
|
81114
|
+
if (!metadataResponse.ok) {
|
|
81115
|
+
throw new Error(`Low moments metadata prefetch failed: ${metadataResponse.status}`);
|
|
81116
|
+
}
|
|
81117
|
+
const metadataData = await metadataResponse.json();
|
|
81118
|
+
const metadata = Array.isArray(metadataData?.clips) ? metadataData.clips : [];
|
|
81119
|
+
const firstClipId = metadata[0]?.clipId || metadata[0]?.id || null;
|
|
81120
|
+
const firstVideo = initFirstVideo && (!firstClipId || initFirstVideo.id === firstClipId) ? initFirstVideo : firstClipId ? await s3Service.getClipById(firstClipId) : null;
|
|
81121
|
+
if (cancelled) {
|
|
81122
|
+
return;
|
|
81123
|
+
}
|
|
81124
|
+
setLowMomentsPrefetch({
|
|
81125
|
+
key: lowMomentsKey,
|
|
81126
|
+
metadata,
|
|
81127
|
+
firstVideo,
|
|
81128
|
+
total: typeof metadataData?.total === "number" ? metadataData.total : lowMomentsCount,
|
|
81129
|
+
loading: false,
|
|
81130
|
+
error: null
|
|
81131
|
+
});
|
|
81132
|
+
prewarmedClipsRef.current.add(cacheKey);
|
|
81133
|
+
} catch (error2) {
|
|
81134
|
+
if (error2.name === "AbortError") {
|
|
81135
|
+
return;
|
|
81136
|
+
}
|
|
81137
|
+
console.warn("[WorkspaceDetailView] Clips init prewarm failed:", error2);
|
|
81138
|
+
setLowMomentsPrefetch((prev) => prev ? {
|
|
81139
|
+
...prev,
|
|
81140
|
+
loading: false,
|
|
81141
|
+
error: error2 instanceof Error ? error2.message : "Low moments prefetch failed"
|
|
81142
|
+
} : prev);
|
|
81143
|
+
} finally {
|
|
81144
|
+
prewarmInFlightRef.current.delete(cacheKey);
|
|
81145
|
+
}
|
|
81146
|
+
};
|
|
81147
|
+
void prefetchLowMoments();
|
|
81148
|
+
return () => {
|
|
81149
|
+
cancelled = true;
|
|
81150
|
+
controller.abort();
|
|
81151
|
+
};
|
|
80305
81152
|
}, [
|
|
80306
81153
|
isClipsEnabled,
|
|
80307
81154
|
dashboardConfig,
|
|
@@ -80311,7 +81158,8 @@ var WorkspaceDetailView = ({
|
|
|
80311
81158
|
isShiftConfigLoading,
|
|
80312
81159
|
shiftConfig,
|
|
80313
81160
|
timezone,
|
|
80314
|
-
workspace
|
|
81161
|
+
workspace,
|
|
81162
|
+
supabase
|
|
80315
81163
|
]);
|
|
80316
81164
|
const { supervisorName, supervisors } = useLineSupervisor(workspace?.line_id || lineId);
|
|
80317
81165
|
useEffect(() => {
|
|
@@ -81530,6 +82378,7 @@ var WorkspaceDetailView = ({
|
|
|
81530
82378
|
totalOutput: workspace?.total_actions,
|
|
81531
82379
|
workspaceMetrics: detailedWorkspaceMetrics || void 0,
|
|
81532
82380
|
prefetchedPercentileCounts: isFastSlowClipFiltersEnabled ? prefetchedPercentileCounts : null,
|
|
82381
|
+
lowMomentsPrefetch,
|
|
81533
82382
|
initialTimeFilter: pendingClipHourFilter,
|
|
81534
82383
|
className: "h-[calc(100vh-10rem)]"
|
|
81535
82384
|
}
|
|
@@ -83168,7 +84017,7 @@ function BottleneckClipsView({
|
|
|
83168
84017
|
) })
|
|
83169
84018
|
] }) });
|
|
83170
84019
|
}
|
|
83171
|
-
var AuthenticatedBottleneckClipsView = withAuth(
|
|
84020
|
+
var AuthenticatedBottleneckClipsView = withAuth(React148__default.memo(BottleneckClipsView));
|
|
83172
84021
|
var BottleneckClipsView_default = BottleneckClipsView;
|
|
83173
84022
|
|
|
83174
84023
|
// src/lib/services/ticketService.ts
|
|
@@ -84011,7 +84860,7 @@ Please ensure:
|
|
|
84011
84860
|
)
|
|
84012
84861
|
] });
|
|
84013
84862
|
}
|
|
84014
|
-
var AuthenticatedTicketsView = withAuth(
|
|
84863
|
+
var AuthenticatedTicketsView = withAuth(React148__default.memo(TicketsView));
|
|
84015
84864
|
var TicketsView_default = TicketsView;
|
|
84016
84865
|
|
|
84017
84866
|
// src/lib/utils/improvementDisplay.ts
|
|
@@ -84982,7 +85831,7 @@ var ImprovementCenterView = () => {
|
|
|
84982
85831
|
setSelectedMemberId("all");
|
|
84983
85832
|
}
|
|
84984
85833
|
}, [memberOptions, selectedMemberId]);
|
|
84985
|
-
const getRecommendationDisplayMetadata =
|
|
85834
|
+
const getRecommendationDisplayMetadata = React148__default.useCallback((rec) => {
|
|
84986
85835
|
const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
|
|
84987
85836
|
return getImprovementDisplayMetadata({
|
|
84988
85837
|
location: rec.location,
|
|
@@ -85456,7 +86305,7 @@ var ThreadSidebar = ({
|
|
|
85456
86305
|
] }) })
|
|
85457
86306
|
] });
|
|
85458
86307
|
};
|
|
85459
|
-
var ProfilePicture =
|
|
86308
|
+
var ProfilePicture = React148__default.memo(({
|
|
85460
86309
|
alt = "Axel",
|
|
85461
86310
|
className = "",
|
|
85462
86311
|
size = "md",
|
|
@@ -88016,7 +88865,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
|
|
|
88016
88865
|
] }),
|
|
88017
88866
|
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end flex-shrink-0 ml-4", children: /* @__PURE__ */ jsx(SectionPulse, { className: "h-6 w-20 rounded-full" }) })
|
|
88018
88867
|
] }, index)) });
|
|
88019
|
-
var OperationsOverviewHeader =
|
|
88868
|
+
var OperationsOverviewHeader = React148__default.memo(({
|
|
88020
88869
|
dateRange,
|
|
88021
88870
|
displayDateRange,
|
|
88022
88871
|
trendMode,
|
|
@@ -88037,65 +88886,65 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88037
88886
|
bumpRenderCounter();
|
|
88038
88887
|
const subtitleRange = displayDateRange || dateRange;
|
|
88039
88888
|
const showLiveShiftMeta = isLiveScope && trendMode !== "all";
|
|
88040
|
-
const liveShiftLabel =
|
|
88889
|
+
const liveShiftLabel = React148__default.useMemo(
|
|
88041
88890
|
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
88042
88891
|
[liveShiftName, trendMode]
|
|
88043
88892
|
);
|
|
88044
|
-
const liveShiftIcon =
|
|
88893
|
+
const liveShiftIcon = React148__default.useMemo(
|
|
88045
88894
|
() => getShiftIcon(liveShiftName, trendMode),
|
|
88046
88895
|
[liveShiftName, trendMode]
|
|
88047
88896
|
);
|
|
88048
|
-
const [isFilterOpen, setIsFilterOpen] =
|
|
88049
|
-
const [isLinesDropdownOpen, setIsLinesDropdownOpen] =
|
|
88050
|
-
const filterRef =
|
|
88051
|
-
const filterButtonRef =
|
|
88052
|
-
const mobileFilterButtonRef =
|
|
88053
|
-
const linesDropdownRef =
|
|
88054
|
-
const mobileSubtitle =
|
|
88897
|
+
const [isFilterOpen, setIsFilterOpen] = React148__default.useState(false);
|
|
88898
|
+
const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React148__default.useState(false);
|
|
88899
|
+
const filterRef = React148__default.useRef(null);
|
|
88900
|
+
const filterButtonRef = React148__default.useRef(null);
|
|
88901
|
+
const mobileFilterButtonRef = React148__default.useRef(null);
|
|
88902
|
+
const linesDropdownRef = React148__default.useRef(null);
|
|
88903
|
+
const mobileSubtitle = React148__default.useMemo(() => {
|
|
88055
88904
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
88056
88905
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
|
|
88057
88906
|
}
|
|
88058
88907
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
|
|
88059
88908
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
88060
|
-
const desktopSubtitle =
|
|
88909
|
+
const desktopSubtitle = React148__default.useMemo(() => {
|
|
88061
88910
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
88062
88911
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
|
|
88063
88912
|
}
|
|
88064
88913
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
|
|
88065
88914
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
88066
|
-
const availableLineIds =
|
|
88915
|
+
const availableLineIds = React148__default.useMemo(
|
|
88067
88916
|
() => lineOptions.map((line) => line.id),
|
|
88068
88917
|
[lineOptions]
|
|
88069
88918
|
);
|
|
88070
|
-
const selectedLineIdSet =
|
|
88919
|
+
const selectedLineIdSet = React148__default.useMemo(
|
|
88071
88920
|
() => new Set(selectedLineIds),
|
|
88072
88921
|
[selectedLineIds]
|
|
88073
88922
|
);
|
|
88074
|
-
const isAllLinesSelected =
|
|
88923
|
+
const isAllLinesSelected = React148__default.useMemo(() => {
|
|
88075
88924
|
if (availableLineIds.length === 0) return true;
|
|
88076
88925
|
return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
|
|
88077
88926
|
}, [availableLineIds, selectedLineIdSet]);
|
|
88078
|
-
const activeFilterCount =
|
|
88927
|
+
const activeFilterCount = React148__default.useMemo(() => {
|
|
88079
88928
|
let count = 0;
|
|
88080
88929
|
if (trendMode !== "all") count += 1;
|
|
88081
88930
|
if (selectedSupervisorId !== "all") count += 1;
|
|
88082
88931
|
if (!isAllLinesSelected) count += 1;
|
|
88083
88932
|
return count;
|
|
88084
88933
|
}, [isAllLinesSelected, selectedSupervisorId, trendMode]);
|
|
88085
|
-
const handleFilterToggle =
|
|
88934
|
+
const handleFilterToggle = React148__default.useCallback(() => {
|
|
88086
88935
|
trackCoreEvent("Operations Overview Filter Toggled", {
|
|
88087
88936
|
action: !isFilterOpen ? "open" : "close"
|
|
88088
88937
|
});
|
|
88089
88938
|
setIsFilterOpen((previous) => !previous);
|
|
88090
88939
|
}, [isFilterOpen]);
|
|
88091
|
-
const handleTrendModeChange =
|
|
88940
|
+
const handleTrendModeChange = React148__default.useCallback((event) => {
|
|
88092
88941
|
const nextMode = event.target.value;
|
|
88093
88942
|
trackCoreEvent("Operations Overview Shift Filter Changed", {
|
|
88094
88943
|
shift_mode: nextMode
|
|
88095
88944
|
});
|
|
88096
88945
|
onTrendModeChange(nextMode);
|
|
88097
88946
|
}, [onTrendModeChange]);
|
|
88098
|
-
const handleAllLinesToggle =
|
|
88947
|
+
const handleAllLinesToggle = React148__default.useCallback(() => {
|
|
88099
88948
|
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
88100
88949
|
selected_line_ids: availableLineIds,
|
|
88101
88950
|
selected_line_count: availableLineIds.length,
|
|
@@ -88103,7 +88952,7 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88103
88952
|
});
|
|
88104
88953
|
onSelectedLineIdsChange(availableLineIds);
|
|
88105
88954
|
}, [availableLineIds, onSelectedLineIdsChange]);
|
|
88106
|
-
const handleSupervisorChange =
|
|
88955
|
+
const handleSupervisorChange = React148__default.useCallback((event) => {
|
|
88107
88956
|
const supervisorId = event.target.value;
|
|
88108
88957
|
const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
|
|
88109
88958
|
trackCoreEvent("Operations Overview Supervisor Filter Changed", {
|
|
@@ -88114,7 +88963,7 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88114
88963
|
});
|
|
88115
88964
|
onSelectedSupervisorIdChange(supervisorId);
|
|
88116
88965
|
}, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
|
|
88117
|
-
const handleLineToggle =
|
|
88966
|
+
const handleLineToggle = React148__default.useCallback((lineId) => {
|
|
88118
88967
|
const current = new Set(selectedLineIds);
|
|
88119
88968
|
if (current.has(lineId)) {
|
|
88120
88969
|
if (current.size <= 1) return;
|
|
@@ -88130,13 +88979,13 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88130
88979
|
});
|
|
88131
88980
|
onSelectedLineIdsChange(next);
|
|
88132
88981
|
}, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
|
|
88133
|
-
const handleClearAllFilters =
|
|
88982
|
+
const handleClearAllFilters = React148__default.useCallback(() => {
|
|
88134
88983
|
onTrendModeChange("all");
|
|
88135
88984
|
onSelectedSupervisorIdChange("all");
|
|
88136
88985
|
onSelectedLineIdsChange(availableLineIds);
|
|
88137
88986
|
setIsFilterOpen(false);
|
|
88138
88987
|
}, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
|
|
88139
|
-
|
|
88988
|
+
React148__default.useEffect(() => {
|
|
88140
88989
|
const handleClickOutside = (event) => {
|
|
88141
88990
|
const target = event.target;
|
|
88142
88991
|
if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
|
|
@@ -88371,12 +89220,12 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88371
89220
|
] }) });
|
|
88372
89221
|
});
|
|
88373
89222
|
OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
|
|
88374
|
-
var OverviewSummaryCards =
|
|
89223
|
+
var OverviewSummaryCards = React148__default.memo(({ store }) => {
|
|
88375
89224
|
bumpRenderCounter();
|
|
88376
89225
|
const scope = useOperationsOverviewScope(store);
|
|
88377
89226
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
88378
89227
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
88379
|
-
const comparisonLabel =
|
|
89228
|
+
const comparisonLabel = React148__default.useMemo(() => {
|
|
88380
89229
|
return formatComparisonWindow({
|
|
88381
89230
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
88382
89231
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -88389,27 +89238,27 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88389
89238
|
scope.previous_range?.day_count,
|
|
88390
89239
|
scope.shift_mode
|
|
88391
89240
|
]);
|
|
88392
|
-
const [isIdleContributorsOpen, setIsIdleContributorsOpen] =
|
|
88393
|
-
const [isIdleContributorsPinned, setIsIdleContributorsPinned] =
|
|
88394
|
-
const idleContributorsRef =
|
|
88395
|
-
const plantEfficiencyBadge =
|
|
89241
|
+
const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React148__default.useState(false);
|
|
89242
|
+
const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React148__default.useState(false);
|
|
89243
|
+
const idleContributorsRef = React148__default.useRef(null);
|
|
89244
|
+
const plantEfficiencyBadge = React148__default.useMemo(() => {
|
|
88396
89245
|
return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
|
|
88397
89246
|
positiveIsGood: true,
|
|
88398
89247
|
formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
|
|
88399
89248
|
comparisonLabel
|
|
88400
89249
|
});
|
|
88401
89250
|
}, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
|
|
88402
|
-
const idleBadge =
|
|
89251
|
+
const idleBadge = React148__default.useMemo(() => {
|
|
88403
89252
|
return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
|
|
88404
89253
|
positiveIsGood: false,
|
|
88405
89254
|
formatter: (value) => formatSignedIdleDuration(value),
|
|
88406
89255
|
comparisonLabel
|
|
88407
89256
|
});
|
|
88408
89257
|
}, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
|
|
88409
|
-
const canInspectIdleContributors =
|
|
89258
|
+
const canInspectIdleContributors = React148__default.useMemo(() => {
|
|
88410
89259
|
return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
|
|
88411
89260
|
}, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
|
|
88412
|
-
const idleTopContributors =
|
|
89261
|
+
const idleTopContributors = React148__default.useMemo(() => {
|
|
88413
89262
|
return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
|
|
88414
89263
|
workspaceId: item.workspace_id || "",
|
|
88415
89264
|
workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
|
|
@@ -88417,14 +89266,14 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88417
89266
|
avgIdleSeconds: toNumber4(item.avg_idle_seconds)
|
|
88418
89267
|
})).slice(0, 5);
|
|
88419
89268
|
}, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
|
|
88420
|
-
const showIdleContributorLineNames =
|
|
89269
|
+
const showIdleContributorLineNames = React148__default.useMemo(() => {
|
|
88421
89270
|
return (scope.line_count ?? 0) > 1;
|
|
88422
89271
|
}, [scope.line_count]);
|
|
88423
|
-
const closeIdleContributors =
|
|
89272
|
+
const closeIdleContributors = React148__default.useCallback(() => {
|
|
88424
89273
|
setIsIdleContributorsOpen(false);
|
|
88425
89274
|
setIsIdleContributorsPinned(false);
|
|
88426
89275
|
}, []);
|
|
88427
|
-
const handleIdleContributorsToggle =
|
|
89276
|
+
const handleIdleContributorsToggle = React148__default.useCallback(() => {
|
|
88428
89277
|
if (!canInspectIdleContributors) return;
|
|
88429
89278
|
setIsIdleContributorsPinned((previous) => {
|
|
88430
89279
|
const next = !previous;
|
|
@@ -88432,7 +89281,7 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88432
89281
|
return next;
|
|
88433
89282
|
});
|
|
88434
89283
|
}, [canInspectIdleContributors]);
|
|
88435
|
-
const handleIdleContributorsKeyDown =
|
|
89284
|
+
const handleIdleContributorsKeyDown = React148__default.useCallback((event) => {
|
|
88436
89285
|
if (!canInspectIdleContributors) return;
|
|
88437
89286
|
if (event.key === "Enter" || event.key === " ") {
|
|
88438
89287
|
event.preventDefault();
|
|
@@ -88444,11 +89293,11 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88444
89293
|
closeIdleContributors();
|
|
88445
89294
|
}
|
|
88446
89295
|
}, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
|
|
88447
|
-
|
|
89296
|
+
React148__default.useEffect(() => {
|
|
88448
89297
|
setIsIdleContributorsOpen(false);
|
|
88449
89298
|
setIsIdleContributorsPinned(false);
|
|
88450
89299
|
}, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
|
|
88451
|
-
|
|
89300
|
+
React148__default.useEffect(() => {
|
|
88452
89301
|
if (!isIdleContributorsOpen) return void 0;
|
|
88453
89302
|
const handleClickOutside = (event) => {
|
|
88454
89303
|
if (!isIdleContributorsPinned) return;
|
|
@@ -88586,7 +89435,7 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88586
89435
|
] });
|
|
88587
89436
|
});
|
|
88588
89437
|
OverviewSummaryCards.displayName = "OverviewSummaryCards";
|
|
88589
|
-
var PoorestPerformersCard =
|
|
89438
|
+
var PoorestPerformersCard = React148__default.memo(({
|
|
88590
89439
|
store,
|
|
88591
89440
|
supervisorsByLineId,
|
|
88592
89441
|
onViewAll,
|
|
@@ -88595,9 +89444,9 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88595
89444
|
bumpRenderCounter();
|
|
88596
89445
|
const scope = useOperationsOverviewScope(store);
|
|
88597
89446
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
88598
|
-
const [poorestLineMode, setPoorestLineMode] =
|
|
89447
|
+
const [poorestLineMode, setPoorestLineMode] = React148__default.useState("output");
|
|
88599
89448
|
const availableLineModes = scope.available_line_modes;
|
|
88600
|
-
|
|
89449
|
+
React148__default.useEffect(() => {
|
|
88601
89450
|
const hasOutput = !!availableLineModes?.has_output;
|
|
88602
89451
|
const hasUptime = !!availableLineModes?.has_uptime;
|
|
88603
89452
|
if (hasOutput && !hasUptime && poorestLineMode !== "output") {
|
|
@@ -88606,7 +89455,7 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88606
89455
|
setPoorestLineMode("uptime");
|
|
88607
89456
|
}
|
|
88608
89457
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
88609
|
-
const comparisonLabel =
|
|
89458
|
+
const comparisonLabel = React148__default.useMemo(() => {
|
|
88610
89459
|
return formatComparisonWindow({
|
|
88611
89460
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
88612
89461
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -88620,7 +89469,7 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88620
89469
|
scope.shift_mode
|
|
88621
89470
|
]);
|
|
88622
89471
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
88623
|
-
const mergedPoorestLines =
|
|
89472
|
+
const mergedPoorestLines = React148__default.useMemo(() => {
|
|
88624
89473
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
88625
89474
|
const lineRows = [];
|
|
88626
89475
|
const areaGroups = /* @__PURE__ */ new Map();
|
|
@@ -88700,7 +89549,7 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88700
89549
|
}, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
|
|
88701
89550
|
const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
|
|
88702
89551
|
const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
|
|
88703
|
-
const handlePoorestLineModeChange =
|
|
89552
|
+
const handlePoorestLineModeChange = React148__default.useCallback((mode) => {
|
|
88704
89553
|
trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
|
|
88705
89554
|
setPoorestLineMode(mode);
|
|
88706
89555
|
}, []);
|
|
@@ -88786,14 +89635,14 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88786
89635
|
] });
|
|
88787
89636
|
});
|
|
88788
89637
|
PoorestPerformersCard.displayName = "PoorestPerformersCard";
|
|
88789
|
-
var IdleBreakdownCard =
|
|
89638
|
+
var IdleBreakdownCard = React148__default.memo(({
|
|
88790
89639
|
store,
|
|
88791
89640
|
scopedLineCount
|
|
88792
89641
|
}) => {
|
|
88793
89642
|
bumpRenderCounter();
|
|
88794
89643
|
const idle = useOperationsOverviewIdle(store);
|
|
88795
89644
|
const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
|
|
88796
|
-
const idleBreakdown =
|
|
89645
|
+
const idleBreakdown = React148__default.useMemo(() => {
|
|
88797
89646
|
return idle.data.map((item) => ({
|
|
88798
89647
|
name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
|
|
88799
89648
|
reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
|
|
@@ -88812,7 +89661,7 @@ var IdleBreakdownCard = React147__default.memo(({
|
|
|
88812
89661
|
}))
|
|
88813
89662
|
})).filter((item) => item.value > 0);
|
|
88814
89663
|
}, [idle.data]);
|
|
88815
|
-
const showIdleModuleNotEnabledState =
|
|
89664
|
+
const showIdleModuleNotEnabledState = React148__default.useMemo(() => {
|
|
88816
89665
|
const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
|
|
88817
89666
|
return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
|
|
88818
89667
|
}, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
|
|
@@ -88833,7 +89682,7 @@ var IdleBreakdownCard = React147__default.memo(({
|
|
|
88833
89682
|
] });
|
|
88834
89683
|
});
|
|
88835
89684
|
IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
88836
|
-
var EfficiencyTrendCard =
|
|
89685
|
+
var EfficiencyTrendCard = React148__default.memo(({
|
|
88837
89686
|
store,
|
|
88838
89687
|
dateRange,
|
|
88839
89688
|
appTimezone,
|
|
@@ -88841,14 +89690,14 @@ var EfficiencyTrendCard = React147__default.memo(({
|
|
|
88841
89690
|
}) => {
|
|
88842
89691
|
bumpRenderCounter();
|
|
88843
89692
|
const trend = useOperationsOverviewTrend(store);
|
|
88844
|
-
const currentWeekRange =
|
|
89693
|
+
const currentWeekRange = React148__default.useMemo(
|
|
88845
89694
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
88846
89695
|
[appTimezone]
|
|
88847
89696
|
);
|
|
88848
89697
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
88849
89698
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
88850
89699
|
const isHourlyTrend = trend.data.granularity === "hour";
|
|
88851
|
-
const trendData =
|
|
89700
|
+
const trendData = React148__default.useMemo(() => {
|
|
88852
89701
|
if (isHourlyTrend) {
|
|
88853
89702
|
return (trend.data.points || []).map((point, index) => ({
|
|
88854
89703
|
name: (() => {
|
|
@@ -88920,13 +89769,13 @@ var EfficiencyTrendCard = React147__default.memo(({
|
|
|
88920
89769
|
};
|
|
88921
89770
|
});
|
|
88922
89771
|
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
88923
|
-
const trendTooltipLabelFormatter =
|
|
89772
|
+
const trendTooltipLabelFormatter = React148__default.useCallback((label, payload) => {
|
|
88924
89773
|
if (isHourlyTrend) return label;
|
|
88925
89774
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
88926
89775
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
88927
89776
|
return `${label} (${dayOfWeek})`;
|
|
88928
89777
|
}, [isHourlyTrend]);
|
|
88929
|
-
const trendXAxisTickFormatter =
|
|
89778
|
+
const trendXAxisTickFormatter = React148__default.useCallback((value, index) => {
|
|
88930
89779
|
if (!isHourlyTrend) {
|
|
88931
89780
|
return typeof value === "string" ? value : String(value ?? "");
|
|
88932
89781
|
}
|
|
@@ -88953,7 +89802,7 @@ var EfficiencyTrendCard = React147__default.memo(({
|
|
|
88953
89802
|
] });
|
|
88954
89803
|
});
|
|
88955
89804
|
EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
|
|
88956
|
-
var TopImprovementsCard =
|
|
89805
|
+
var TopImprovementsCard = React148__default.memo(({
|
|
88957
89806
|
store,
|
|
88958
89807
|
supervisorsByLineId,
|
|
88959
89808
|
onViewAll,
|
|
@@ -88962,7 +89811,7 @@ var TopImprovementsCard = React147__default.memo(({
|
|
|
88962
89811
|
bumpRenderCounter();
|
|
88963
89812
|
const improvements = useOperationsOverviewImprovements(store);
|
|
88964
89813
|
const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
|
|
88965
|
-
const displayImprovements =
|
|
89814
|
+
const displayImprovements = React148__default.useMemo(() => {
|
|
88966
89815
|
return improvements.data.map((item) => {
|
|
88967
89816
|
const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
|
|
88968
89817
|
return {
|
|
@@ -89090,33 +89939,33 @@ var useOperationsOverviewRefresh = ({
|
|
|
89090
89939
|
isLiveScope,
|
|
89091
89940
|
enabled = true
|
|
89092
89941
|
}) => {
|
|
89093
|
-
const lineIdsKey =
|
|
89094
|
-
const scopeSignature =
|
|
89942
|
+
const lineIdsKey = React148__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
89943
|
+
const scopeSignature = React148__default.useMemo(
|
|
89095
89944
|
() => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
|
|
89096
89945
|
[companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
|
|
89097
89946
|
);
|
|
89098
|
-
const controllersRef =
|
|
89099
|
-
const requestIdsRef =
|
|
89947
|
+
const controllersRef = React148__default.useRef({});
|
|
89948
|
+
const requestIdsRef = React148__default.useRef({
|
|
89100
89949
|
snapshot: 0,
|
|
89101
89950
|
trend: 0,
|
|
89102
89951
|
idle: 0,
|
|
89103
89952
|
improvements: 0
|
|
89104
89953
|
});
|
|
89105
|
-
const intervalRef =
|
|
89106
|
-
const isPageActiveRef =
|
|
89107
|
-
const lastResumeRefreshAtRef =
|
|
89108
|
-
const abortAll =
|
|
89954
|
+
const intervalRef = React148__default.useRef(null);
|
|
89955
|
+
const isPageActiveRef = React148__default.useRef(true);
|
|
89956
|
+
const lastResumeRefreshAtRef = React148__default.useRef(0);
|
|
89957
|
+
const abortAll = React148__default.useCallback(() => {
|
|
89109
89958
|
Object.values(controllersRef.current).forEach((controller) => {
|
|
89110
89959
|
controller?.abort();
|
|
89111
89960
|
});
|
|
89112
89961
|
controllersRef.current = {};
|
|
89113
89962
|
}, []);
|
|
89114
|
-
|
|
89963
|
+
React148__default.useEffect(() => {
|
|
89115
89964
|
return () => {
|
|
89116
89965
|
abortAll();
|
|
89117
89966
|
};
|
|
89118
89967
|
}, [abortAll]);
|
|
89119
|
-
const getIsPageActive =
|
|
89968
|
+
const getIsPageActive = React148__default.useCallback(() => {
|
|
89120
89969
|
if (typeof document === "undefined") {
|
|
89121
89970
|
return true;
|
|
89122
89971
|
}
|
|
@@ -89124,7 +89973,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89124
89973
|
const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
|
|
89125
89974
|
return isVisible && hasFocus;
|
|
89126
89975
|
}, []);
|
|
89127
|
-
const stopPolling =
|
|
89976
|
+
const stopPolling = React148__default.useCallback((reason) => {
|
|
89128
89977
|
if (intervalRef.current === null) {
|
|
89129
89978
|
return;
|
|
89130
89979
|
}
|
|
@@ -89132,7 +89981,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89132
89981
|
intervalRef.current = null;
|
|
89133
89982
|
debugRefreshLog("poll stopped", { reason });
|
|
89134
89983
|
}, []);
|
|
89135
|
-
const runRefresh =
|
|
89984
|
+
const runRefresh = React148__default.useCallback(
|
|
89136
89985
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
89137
89986
|
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
89138
89987
|
const requestId = requestIdsRef.current[section] + 1;
|
|
@@ -89179,7 +90028,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89179
90028
|
},
|
|
89180
90029
|
[companyId, comparisonStrategy, enabled, endKey, lineIds, startKey, supabase, trendMode]
|
|
89181
90030
|
);
|
|
89182
|
-
const refreshSnapshot =
|
|
90031
|
+
const refreshSnapshot = React148__default.useCallback(
|
|
89183
90032
|
async (reason) => {
|
|
89184
90033
|
await runRefresh(
|
|
89185
90034
|
"snapshot",
|
|
@@ -89211,7 +90060,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89211
90060
|
},
|
|
89212
90061
|
[companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
89213
90062
|
);
|
|
89214
|
-
const refreshTrend =
|
|
90063
|
+
const refreshTrend = React148__default.useCallback(
|
|
89215
90064
|
async (reason) => {
|
|
89216
90065
|
await runRefresh(
|
|
89217
90066
|
"trend",
|
|
@@ -89240,7 +90089,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89240
90089
|
},
|
|
89241
90090
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
89242
90091
|
);
|
|
89243
|
-
const refreshIdle =
|
|
90092
|
+
const refreshIdle = React148__default.useCallback(
|
|
89244
90093
|
async (reason) => {
|
|
89245
90094
|
await runRefresh(
|
|
89246
90095
|
"idle",
|
|
@@ -89269,7 +90118,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89269
90118
|
},
|
|
89270
90119
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
89271
90120
|
);
|
|
89272
|
-
const refreshImprovements =
|
|
90121
|
+
const refreshImprovements = React148__default.useCallback(
|
|
89273
90122
|
async (reason) => {
|
|
89274
90123
|
await runRefresh(
|
|
89275
90124
|
"improvements",
|
|
@@ -89299,7 +90148,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89299
90148
|
},
|
|
89300
90149
|
[companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
|
|
89301
90150
|
);
|
|
89302
|
-
const refreshAll =
|
|
90151
|
+
const refreshAll = React148__default.useCallback(
|
|
89303
90152
|
async (reason) => {
|
|
89304
90153
|
await Promise.allSettled([
|
|
89305
90154
|
refreshSnapshot(reason),
|
|
@@ -89310,7 +90159,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89310
90159
|
},
|
|
89311
90160
|
[refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
|
|
89312
90161
|
);
|
|
89313
|
-
const startPolling =
|
|
90162
|
+
const startPolling = React148__default.useCallback((reason) => {
|
|
89314
90163
|
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
89315
90164
|
return;
|
|
89316
90165
|
}
|
|
@@ -89331,7 +90180,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89331
90180
|
}, LIVE_REFRESH_INTERVAL_MS);
|
|
89332
90181
|
debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
|
|
89333
90182
|
}, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
|
|
89334
|
-
const refreshFromResume =
|
|
90183
|
+
const refreshFromResume = React148__default.useCallback((reason) => {
|
|
89335
90184
|
const now4 = Date.now();
|
|
89336
90185
|
if (now4 - lastResumeRefreshAtRef.current < 1e3) {
|
|
89337
90186
|
debugRefreshLog("resume refresh suppressed", { reason });
|
|
@@ -89346,7 +90195,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89346
90195
|
}
|
|
89347
90196
|
});
|
|
89348
90197
|
}, [refreshAll, startPolling, stopPolling]);
|
|
89349
|
-
|
|
90198
|
+
React148__default.useEffect(() => {
|
|
89350
90199
|
if (!enabled) {
|
|
89351
90200
|
stopPolling("disabled");
|
|
89352
90201
|
abortAll();
|
|
@@ -89361,7 +90210,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89361
90210
|
}
|
|
89362
90211
|
void refreshAll("scope_change");
|
|
89363
90212
|
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
89364
|
-
|
|
90213
|
+
React148__default.useEffect(() => {
|
|
89365
90214
|
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
89366
90215
|
isPageActiveRef.current = false;
|
|
89367
90216
|
stopPolling("live_scope_disabled");
|
|
@@ -89574,55 +90423,55 @@ var PlantHeadView = () => {
|
|
|
89574
90423
|
const { accessibleLineIds } = useUserLineAccess();
|
|
89575
90424
|
const mobileMenuContext = useMobileMenu();
|
|
89576
90425
|
useHideMobileHeader(!!mobileMenuContext);
|
|
89577
|
-
const storeRef =
|
|
90426
|
+
const storeRef = React148__default.useRef(createOperationsOverviewStore());
|
|
89578
90427
|
const store = storeRef.current;
|
|
89579
|
-
const fallbackOperationalDate =
|
|
90428
|
+
const fallbackOperationalDate = React148__default.useMemo(
|
|
89580
90429
|
() => getOperationalDate(appTimezone),
|
|
89581
90430
|
[appTimezone]
|
|
89582
90431
|
);
|
|
89583
|
-
const [dateRange, setDateRange] =
|
|
90432
|
+
const [dateRange, setDateRange] = React148__default.useState(() => ({
|
|
89584
90433
|
startKey: fallbackOperationalDate,
|
|
89585
90434
|
endKey: fallbackOperationalDate
|
|
89586
90435
|
}));
|
|
89587
|
-
const [usesThisWeekComparison, setUsesThisWeekComparison] =
|
|
89588
|
-
const [trendMode, setTrendMode] =
|
|
89589
|
-
const [selectedSupervisorId, setSelectedSupervisorId] =
|
|
89590
|
-
const [selectedLineIds, setSelectedLineIds] =
|
|
89591
|
-
const [isInitialScopeReady, setIsInitialScopeReady] =
|
|
89592
|
-
const [shiftResolutionTick, setShiftResolutionTick] =
|
|
89593
|
-
const hasAutoInitializedScopeRef =
|
|
89594
|
-
const hasUserAdjustedScopeRef =
|
|
89595
|
-
|
|
90436
|
+
const [usesThisWeekComparison, setUsesThisWeekComparison] = React148__default.useState(false);
|
|
90437
|
+
const [trendMode, setTrendMode] = React148__default.useState("all");
|
|
90438
|
+
const [selectedSupervisorId, setSelectedSupervisorId] = React148__default.useState("all");
|
|
90439
|
+
const [selectedLineIds, setSelectedLineIds] = React148__default.useState([]);
|
|
90440
|
+
const [isInitialScopeReady, setIsInitialScopeReady] = React148__default.useState(false);
|
|
90441
|
+
const [shiftResolutionTick, setShiftResolutionTick] = React148__default.useState(0);
|
|
90442
|
+
const hasAutoInitializedScopeRef = React148__default.useRef(false);
|
|
90443
|
+
const hasUserAdjustedScopeRef = React148__default.useRef(false);
|
|
90444
|
+
React148__default.useEffect(() => {
|
|
89596
90445
|
trackCorePageView("Operations Overview", {
|
|
89597
90446
|
dashboard_surface: "operations_overview"
|
|
89598
90447
|
});
|
|
89599
90448
|
}, []);
|
|
89600
|
-
const currentWeekRange =
|
|
90449
|
+
const currentWeekRange = React148__default.useMemo(
|
|
89601
90450
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
89602
90451
|
[appTimezone]
|
|
89603
90452
|
);
|
|
89604
|
-
const currentWeekDisplayRange =
|
|
90453
|
+
const currentWeekDisplayRange = React148__default.useMemo(
|
|
89605
90454
|
() => getCurrentWeekFullRange(appTimezone),
|
|
89606
90455
|
[appTimezone]
|
|
89607
90456
|
);
|
|
89608
90457
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
89609
|
-
const headerDateRange =
|
|
90458
|
+
const headerDateRange = React148__default.useMemo(() => {
|
|
89610
90459
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
89611
90460
|
return currentWeekDisplayRange;
|
|
89612
90461
|
}
|
|
89613
90462
|
return dateRange;
|
|
89614
90463
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
89615
|
-
const normalizedLineIds =
|
|
90464
|
+
const normalizedLineIds = React148__default.useMemo(
|
|
89616
90465
|
() => Array.from(new Set(
|
|
89617
90466
|
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
89618
90467
|
)).sort(),
|
|
89619
90468
|
[accessibleLineIds, factoryViewId]
|
|
89620
90469
|
);
|
|
89621
|
-
const lineIdsKey =
|
|
90470
|
+
const lineIdsKey = React148__default.useMemo(
|
|
89622
90471
|
() => normalizedLineIds.join(","),
|
|
89623
90472
|
[normalizedLineIds]
|
|
89624
90473
|
);
|
|
89625
|
-
const lineOptions =
|
|
90474
|
+
const lineOptions = React148__default.useMemo(
|
|
89626
90475
|
() => normalizedLineIds.map((lineId) => ({
|
|
89627
90476
|
id: lineId,
|
|
89628
90477
|
name: getLineDisplayName(entityConfig, lineId)
|
|
@@ -89634,7 +90483,7 @@ var PlantHeadView = () => {
|
|
|
89634
90483
|
companyId: entityConfig.companyId,
|
|
89635
90484
|
useBackend: true
|
|
89636
90485
|
});
|
|
89637
|
-
const supervisorOptions =
|
|
90486
|
+
const supervisorOptions = React148__default.useMemo(
|
|
89638
90487
|
() => {
|
|
89639
90488
|
const optionsById = /* @__PURE__ */ new Map();
|
|
89640
90489
|
normalizedLineIds.forEach((lineId) => {
|
|
@@ -89660,7 +90509,7 @@ var PlantHeadView = () => {
|
|
|
89660
90509
|
},
|
|
89661
90510
|
[normalizedLineIds, supervisorsByLineId]
|
|
89662
90511
|
);
|
|
89663
|
-
|
|
90512
|
+
React148__default.useEffect(() => {
|
|
89664
90513
|
if (selectedSupervisorId === "all") {
|
|
89665
90514
|
setSelectedLineIds((previous) => {
|
|
89666
90515
|
if (normalizedLineIds.length === 0) {
|
|
@@ -89686,7 +90535,7 @@ var PlantHeadView = () => {
|
|
|
89686
90535
|
const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
|
|
89687
90536
|
setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
|
|
89688
90537
|
}, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
|
|
89689
|
-
const scopedLineIds =
|
|
90538
|
+
const scopedLineIds = React148__default.useMemo(
|
|
89690
90539
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
89691
90540
|
[normalizedLineIds, selectedLineIds]
|
|
89692
90541
|
);
|
|
@@ -89694,7 +90543,7 @@ var PlantHeadView = () => {
|
|
|
89694
90543
|
shiftConfigMap,
|
|
89695
90544
|
isLoading: isShiftConfigLoading
|
|
89696
90545
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
89697
|
-
const shiftFilterOptions =
|
|
90546
|
+
const shiftFilterOptions = React148__default.useMemo(() => {
|
|
89698
90547
|
const optionsById = /* @__PURE__ */ new Map();
|
|
89699
90548
|
scopedLineIds.forEach((lineId) => {
|
|
89700
90549
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -89733,7 +90582,7 @@ var PlantHeadView = () => {
|
|
|
89733
90582
|
...dynamicOptions
|
|
89734
90583
|
];
|
|
89735
90584
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
89736
|
-
|
|
90585
|
+
React148__default.useEffect(() => {
|
|
89737
90586
|
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
89738
90587
|
return;
|
|
89739
90588
|
}
|
|
@@ -89744,11 +90593,11 @@ var PlantHeadView = () => {
|
|
|
89744
90593
|
clearInterval(intervalId);
|
|
89745
90594
|
};
|
|
89746
90595
|
}, [isShiftConfigLoading, scopedLineIds.length]);
|
|
89747
|
-
const shiftResolutionNow =
|
|
90596
|
+
const shiftResolutionNow = React148__default.useMemo(
|
|
89748
90597
|
() => /* @__PURE__ */ new Date(),
|
|
89749
90598
|
[shiftResolutionTick]
|
|
89750
90599
|
);
|
|
89751
|
-
const earliestDayShiftStartTime =
|
|
90600
|
+
const earliestDayShiftStartTime = React148__default.useMemo(() => {
|
|
89752
90601
|
const candidateStarts = [];
|
|
89753
90602
|
scopedLineIds.forEach((lineId) => {
|
|
89754
90603
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -89784,11 +90633,11 @@ var PlantHeadView = () => {
|
|
|
89784
90633
|
const minutes = earliestMinutes % 60;
|
|
89785
90634
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
89786
90635
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
89787
|
-
const resolvedOperationalToday =
|
|
90636
|
+
const resolvedOperationalToday = React148__default.useMemo(
|
|
89788
90637
|
() => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
|
|
89789
90638
|
[appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
|
|
89790
90639
|
);
|
|
89791
|
-
const activeLineShiftStates =
|
|
90640
|
+
const activeLineShiftStates = React148__default.useMemo(() => {
|
|
89792
90641
|
return scopedLineIds.flatMap((lineId) => {
|
|
89793
90642
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
89794
90643
|
const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
|
|
@@ -89818,7 +90667,7 @@ var PlantHeadView = () => {
|
|
|
89818
90667
|
});
|
|
89819
90668
|
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
89820
90669
|
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
89821
|
-
const hourlyWindowStartTime =
|
|
90670
|
+
const hourlyWindowStartTime = React148__default.useMemo(() => {
|
|
89822
90671
|
if (scopedLineIds.length === 0) {
|
|
89823
90672
|
return null;
|
|
89824
90673
|
}
|
|
@@ -89875,12 +90724,12 @@ var PlantHeadView = () => {
|
|
|
89875
90724
|
const minutes = earliestMinutes % 60;
|
|
89876
90725
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
89877
90726
|
}, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
89878
|
-
const isShiftScopeResolved =
|
|
90727
|
+
const isShiftScopeResolved = React148__default.useMemo(
|
|
89879
90728
|
() => !isShiftConfigLoading,
|
|
89880
90729
|
[isShiftConfigLoading]
|
|
89881
90730
|
);
|
|
89882
|
-
const initializedTimezoneRef =
|
|
89883
|
-
|
|
90731
|
+
const initializedTimezoneRef = React148__default.useRef(appTimezone);
|
|
90732
|
+
React148__default.useEffect(() => {
|
|
89884
90733
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
89885
90734
|
hasAutoInitializedScopeRef.current = false;
|
|
89886
90735
|
hasUserAdjustedScopeRef.current = false;
|
|
@@ -89893,7 +90742,7 @@ var PlantHeadView = () => {
|
|
|
89893
90742
|
setIsInitialScopeReady(false);
|
|
89894
90743
|
initializedTimezoneRef.current = appTimezone;
|
|
89895
90744
|
}, [appTimezone, fallbackOperationalDate]);
|
|
89896
|
-
|
|
90745
|
+
React148__default.useEffect(() => {
|
|
89897
90746
|
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
89898
90747
|
return;
|
|
89899
90748
|
}
|
|
@@ -89918,7 +90767,7 @@ var PlantHeadView = () => {
|
|
|
89918
90767
|
hasAutoInitializedScopeRef.current = true;
|
|
89919
90768
|
setIsInitialScopeReady(true);
|
|
89920
90769
|
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
89921
|
-
const handleDateRangeChange =
|
|
90770
|
+
const handleDateRangeChange = React148__default.useCallback((range, meta) => {
|
|
89922
90771
|
hasUserAdjustedScopeRef.current = true;
|
|
89923
90772
|
setIsInitialScopeReady(true);
|
|
89924
90773
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
@@ -89936,12 +90785,12 @@ var PlantHeadView = () => {
|
|
|
89936
90785
|
return previous;
|
|
89937
90786
|
});
|
|
89938
90787
|
}, []);
|
|
89939
|
-
const handleTrendModeChange =
|
|
90788
|
+
const handleTrendModeChange = React148__default.useCallback((mode) => {
|
|
89940
90789
|
hasUserAdjustedScopeRef.current = true;
|
|
89941
90790
|
setIsInitialScopeReady(true);
|
|
89942
90791
|
setTrendMode(mode);
|
|
89943
90792
|
}, []);
|
|
89944
|
-
const handleSelectedLineIdsChange =
|
|
90793
|
+
const handleSelectedLineIdsChange = React148__default.useCallback((lineIds) => {
|
|
89945
90794
|
setSelectedSupervisorId("all");
|
|
89946
90795
|
if (normalizedLineIds.length === 0) {
|
|
89947
90796
|
setSelectedLineIds([]);
|
|
@@ -89952,10 +90801,10 @@ var PlantHeadView = () => {
|
|
|
89952
90801
|
const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
|
|
89953
90802
|
setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
|
|
89954
90803
|
}, [normalizedLineIds]);
|
|
89955
|
-
const handleSelectedSupervisorIdChange =
|
|
90804
|
+
const handleSelectedSupervisorIdChange = React148__default.useCallback((supervisorId) => {
|
|
89956
90805
|
setSelectedSupervisorId(supervisorId);
|
|
89957
90806
|
}, []);
|
|
89958
|
-
const buildLineMonthlyHistoryUrl =
|
|
90807
|
+
const buildLineMonthlyHistoryUrl = React148__default.useCallback((lineId) => {
|
|
89959
90808
|
const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
|
|
89960
90809
|
const params = new URLSearchParams();
|
|
89961
90810
|
params.set("tab", "monthly_history");
|
|
@@ -89965,15 +90814,15 @@ var PlantHeadView = () => {
|
|
|
89965
90814
|
params.set("rangeEnd", dateRange.endKey);
|
|
89966
90815
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
89967
90816
|
}, [dateRange.endKey, dateRange.startKey]);
|
|
89968
|
-
const handleViewAllPoorestPerformers =
|
|
90817
|
+
const handleViewAllPoorestPerformers = React148__default.useCallback(() => {
|
|
89969
90818
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
89970
90819
|
navigate("/kpis?tab=leaderboard");
|
|
89971
90820
|
}, [navigate]);
|
|
89972
|
-
const handleViewAllImprovements =
|
|
90821
|
+
const handleViewAllImprovements = React148__default.useCallback(() => {
|
|
89973
90822
|
trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
|
|
89974
90823
|
navigate("/improvement-center");
|
|
89975
90824
|
}, [navigate]);
|
|
89976
|
-
const handleOpenImprovement =
|
|
90825
|
+
const handleOpenImprovement = React148__default.useCallback((item) => {
|
|
89977
90826
|
trackCoreEvent("Operations Overview Improvement Clicked", {
|
|
89978
90827
|
issue_id: item.issueId,
|
|
89979
90828
|
issue_number: item.issueNumber,
|
|
@@ -89984,13 +90833,13 @@ var PlantHeadView = () => {
|
|
|
89984
90833
|
});
|
|
89985
90834
|
navigate(`/improvement-center?${params.toString()}`);
|
|
89986
90835
|
}, [navigate]);
|
|
89987
|
-
const comparisonStrategy =
|
|
90836
|
+
const comparisonStrategy = React148__default.useMemo(() => {
|
|
89988
90837
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
89989
90838
|
return "previous_full_week";
|
|
89990
90839
|
}
|
|
89991
90840
|
return void 0;
|
|
89992
90841
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
89993
|
-
const effectiveDateRange =
|
|
90842
|
+
const effectiveDateRange = React148__default.useMemo(() => {
|
|
89994
90843
|
if (isInitialScopeReady) {
|
|
89995
90844
|
return dateRange;
|
|
89996
90845
|
}
|
|
@@ -90000,11 +90849,11 @@ var PlantHeadView = () => {
|
|
|
90000
90849
|
endKey: nextStartKey
|
|
90001
90850
|
};
|
|
90002
90851
|
}, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
|
|
90003
|
-
const effectiveTrendMode =
|
|
90852
|
+
const effectiveTrendMode = React148__default.useMemo(
|
|
90004
90853
|
() => resolvedTrendMode,
|
|
90005
90854
|
[resolvedTrendMode]
|
|
90006
90855
|
);
|
|
90007
|
-
const hasActiveSelectedShiftLine =
|
|
90856
|
+
const hasActiveSelectedShiftLine = React148__default.useMemo(
|
|
90008
90857
|
() => activeLineShiftStates.some((shift) => {
|
|
90009
90858
|
if (shift.date !== resolvedOperationalToday) return false;
|
|
90010
90859
|
if (effectiveTrendMode === "all") return true;
|
|
@@ -90016,7 +90865,7 @@ var PlantHeadView = () => {
|
|
|
90016
90865
|
}),
|
|
90017
90866
|
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
90018
90867
|
);
|
|
90019
|
-
const activeLiveShiftName =
|
|
90868
|
+
const activeLiveShiftName = React148__default.useMemo(
|
|
90020
90869
|
() => {
|
|
90021
90870
|
if (effectiveTrendMode === "all") return null;
|
|
90022
90871
|
const matchingShift = activeLineShiftStates.find((shift) => {
|
|
@@ -90031,17 +90880,17 @@ var PlantHeadView = () => {
|
|
|
90031
90880
|
},
|
|
90032
90881
|
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
90033
90882
|
);
|
|
90034
|
-
const hourlyLabelStartTime =
|
|
90883
|
+
const hourlyLabelStartTime = React148__default.useMemo(() => {
|
|
90035
90884
|
if (scopedLineIds.length === 0) {
|
|
90036
90885
|
return null;
|
|
90037
90886
|
}
|
|
90038
90887
|
return hourlyWindowStartTime;
|
|
90039
90888
|
}, [hourlyWindowStartTime, scopedLineIds.length]);
|
|
90040
|
-
const isSingleDayScope =
|
|
90889
|
+
const isSingleDayScope = React148__default.useMemo(
|
|
90041
90890
|
() => effectiveDateRange.startKey === effectiveDateRange.endKey,
|
|
90042
90891
|
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
90043
90892
|
);
|
|
90044
|
-
const isLiveScope =
|
|
90893
|
+
const isLiveScope = React148__default.useMemo(
|
|
90045
90894
|
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && hasActiveSelectedShiftLine,
|
|
90046
90895
|
[
|
|
90047
90896
|
effectiveDateRange.startKey,
|
|
@@ -90051,7 +90900,7 @@ var PlantHeadView = () => {
|
|
|
90051
90900
|
resolvedOperationalToday
|
|
90052
90901
|
]
|
|
90053
90902
|
);
|
|
90054
|
-
const handleOpenLineDetails =
|
|
90903
|
+
const handleOpenLineDetails = React148__default.useCallback((line) => {
|
|
90055
90904
|
trackCoreEvent("Operations Overview Line Clicked", {
|
|
90056
90905
|
line_id: line.rowType === "line" ? line.id : null,
|
|
90057
90906
|
line_name: line.name,
|