@optifye/dashboard-core 6.12.43 → 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 +3667 -2814
- package/dist/index.mjs +1345 -492
- 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,23 +39680,24 @@ 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;
|
|
39690
39693
|
}
|
|
39691
39694
|
return null;
|
|
39692
39695
|
}, [activeSku, skuAware, activeSkuId, liveSkuId, skuBreakdown]);
|
|
39693
|
-
const
|
|
39694
|
-
const
|
|
39695
|
-
const
|
|
39696
|
-
const
|
|
39696
|
+
const metricSku = displaySku;
|
|
39697
|
+
const pphValue = metricSku ? metricSku.avg_pph : workspace.avg_pph;
|
|
39698
|
+
const pphThreshold = metricSku ? metricSku.pph_threshold : workspace.pph_threshold;
|
|
39699
|
+
const cycleValue = metricSku ? metricSku.avg_cycle_time : workspace.avg_cycle_time;
|
|
39700
|
+
const cycleStandard = metricSku ? metricSku.ideal_cycle_time : workspace.ideal_cycle_time;
|
|
39697
39701
|
const displaySkuLabel = displaySku ? getSkuDisplayName(displaySku) : "";
|
|
39698
39702
|
const efficiencyValue = workspace.avg_efficiency || 0;
|
|
39699
39703
|
const efficiencyTarget = effectiveLegend.green_min;
|
|
@@ -40336,7 +40340,7 @@ var UptimeLineChartComponent = ({ points, className = "" }) => {
|
|
|
40336
40340
|
)
|
|
40337
40341
|
] }) }) });
|
|
40338
40342
|
};
|
|
40339
|
-
var UptimeLineChart =
|
|
40343
|
+
var UptimeLineChart = React148__default.memo(UptimeLineChartComponent);
|
|
40340
40344
|
var getTimeFromTimeString = (timeStr) => {
|
|
40341
40345
|
if (!timeStr) {
|
|
40342
40346
|
return { hour: 0, minute: 0, decimalHour: 0 };
|
|
@@ -40360,10 +40364,10 @@ var HourlyUptimeChartComponent = ({
|
|
|
40360
40364
|
shiftBreaks,
|
|
40361
40365
|
className = ""
|
|
40362
40366
|
}) => {
|
|
40363
|
-
const containerRef =
|
|
40364
|
-
const [containerReady, setContainerReady] =
|
|
40365
|
-
const [containerWidth, setContainerWidth] =
|
|
40366
|
-
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({
|
|
40367
40371
|
idleTimeHourly,
|
|
40368
40372
|
shiftStart,
|
|
40369
40373
|
shiftEnd,
|
|
@@ -40373,11 +40377,11 @@ var HourlyUptimeChartComponent = ({
|
|
|
40373
40377
|
shiftBreaks
|
|
40374
40378
|
}), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes, shiftBreaks]);
|
|
40375
40379
|
const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
|
|
40376
|
-
const shiftStartTime =
|
|
40380
|
+
const shiftStartTime = React148__default.useMemo(
|
|
40377
40381
|
() => getTimeFromTimeString(shiftStart),
|
|
40378
40382
|
[shiftStart]
|
|
40379
40383
|
);
|
|
40380
|
-
const { shiftDuration, shiftEndTime } =
|
|
40384
|
+
const { shiftDuration, shiftEndTime } = React148__default.useMemo(() => {
|
|
40381
40385
|
if (!shiftEnd) {
|
|
40382
40386
|
const fallbackHours = uptimeSeries.shiftMinutes > 0 ? Math.ceil(uptimeSeries.shiftMinutes / 60) : 0;
|
|
40383
40387
|
return { shiftDuration: fallbackHours, shiftEndTime: null };
|
|
@@ -40391,7 +40395,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40391
40395
|
const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
|
|
40392
40396
|
return { shiftDuration: hourCount, shiftEndTime: endTime };
|
|
40393
40397
|
}, [shiftEnd, shiftStartTime.decimalHour, uptimeSeries.shiftMinutes]);
|
|
40394
|
-
const formatHour =
|
|
40398
|
+
const formatHour = React148__default.useCallback((hourIndex) => {
|
|
40395
40399
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
40396
40400
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
40397
40401
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -40416,7 +40420,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40416
40420
|
};
|
|
40417
40421
|
return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
|
|
40418
40422
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
40419
|
-
const formatTimeRange2 =
|
|
40423
|
+
const formatTimeRange2 = React148__default.useCallback((hourIndex) => {
|
|
40420
40424
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
40421
40425
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
40422
40426
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -40438,7 +40442,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40438
40442
|
};
|
|
40439
40443
|
return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
|
|
40440
40444
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
40441
|
-
const chartData =
|
|
40445
|
+
const chartData = React148__default.useMemo(() => {
|
|
40442
40446
|
if (shiftDuration <= 0) return [];
|
|
40443
40447
|
if (hasAggregateData) {
|
|
40444
40448
|
return hourlyAggregates.map((entry, hourIndex) => ({
|
|
@@ -40480,7 +40484,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40480
40484
|
}, [hasAggregateData, hourlyAggregates, uptimeSeries.points, uptimeSeries.elapsedMinutes, uptimeSeries.shiftMinutes, shiftDuration, formatHour, formatTimeRange2]);
|
|
40481
40485
|
const maxYValue = 100;
|
|
40482
40486
|
const yAxisTicks = [0, 25, 50, 75, 100];
|
|
40483
|
-
|
|
40487
|
+
React148__default.useEffect(() => {
|
|
40484
40488
|
const checkContainerDimensions = () => {
|
|
40485
40489
|
if (containerRef.current) {
|
|
40486
40490
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -40506,7 +40510,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40506
40510
|
clearTimeout(fallbackTimeout);
|
|
40507
40511
|
};
|
|
40508
40512
|
}, []);
|
|
40509
|
-
const xAxisConfig =
|
|
40513
|
+
const xAxisConfig = React148__default.useMemo(() => {
|
|
40510
40514
|
if (containerWidth >= 960) {
|
|
40511
40515
|
return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12, labelMode: "full" };
|
|
40512
40516
|
}
|
|
@@ -40515,7 +40519,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40515
40519
|
}
|
|
40516
40520
|
return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6, labelMode: "start" };
|
|
40517
40521
|
}, [containerWidth]);
|
|
40518
|
-
const formatXAxisTick =
|
|
40522
|
+
const formatXAxisTick = React148__default.useCallback((raw) => {
|
|
40519
40523
|
const label = typeof raw === "string" ? raw : String(raw);
|
|
40520
40524
|
if (xAxisConfig.labelMode === "full") return label;
|
|
40521
40525
|
const parts = label.split("-");
|
|
@@ -40721,7 +40725,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
40721
40725
|
}
|
|
40722
40726
|
);
|
|
40723
40727
|
};
|
|
40724
|
-
var HourlyUptimeChart =
|
|
40728
|
+
var HourlyUptimeChart = React148__default.memo(HourlyUptimeChartComponent);
|
|
40725
40729
|
var DEFAULT_COLORS2 = ["#00AB45", "#ef4444"];
|
|
40726
40730
|
var UptimeDonutChartComponent = ({
|
|
40727
40731
|
data,
|
|
@@ -40791,7 +40795,7 @@ var UptimeDonutChartComponent = ({
|
|
|
40791
40795
|
] }) })
|
|
40792
40796
|
] }) });
|
|
40793
40797
|
};
|
|
40794
|
-
var UptimeDonutChart =
|
|
40798
|
+
var UptimeDonutChart = React148__default.memo(UptimeDonutChartComponent);
|
|
40795
40799
|
UptimeDonutChart.displayName = "UptimeDonutChart";
|
|
40796
40800
|
var TrendIcon = ({ trend }) => {
|
|
40797
40801
|
if (trend === "up") {
|
|
@@ -40912,7 +40916,7 @@ var EmptyStateMessage = ({
|
|
|
40912
40916
|
iconClassName
|
|
40913
40917
|
}) => {
|
|
40914
40918
|
let IconContent = null;
|
|
40915
|
-
if (
|
|
40919
|
+
if (React148__default.isValidElement(iconType)) {
|
|
40916
40920
|
IconContent = iconType;
|
|
40917
40921
|
} else if (typeof iconType === "string") {
|
|
40918
40922
|
const MappedIcon = IconMap[iconType];
|
|
@@ -41420,6 +41424,7 @@ var CYCLE_RANGE_CATEGORY_IDS = /* @__PURE__ */ new Set([
|
|
|
41420
41424
|
"fast-cycles",
|
|
41421
41425
|
"slow-cycles"
|
|
41422
41426
|
]);
|
|
41427
|
+
var EXPLICIT_INTERVAL_CATEGORY_IDS = /* @__PURE__ */ new Set(["recent_flow_red_streak"]);
|
|
41423
41428
|
var roundToNearestMinute = (date) => {
|
|
41424
41429
|
const rounded = new Date(date.getTime());
|
|
41425
41430
|
const seconds = rounded.getSeconds();
|
|
@@ -41475,6 +41480,22 @@ var buildPrefetchedExplorerMetadata = (activeFilter, metadataCategoryId, categor
|
|
|
41475
41480
|
};
|
|
41476
41481
|
};
|
|
41477
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
|
+
};
|
|
41478
41499
|
var getSecondsBetweenTimestamps = (startTime, endTime) => {
|
|
41479
41500
|
const startDate = parseTimestamp(startTime);
|
|
41480
41501
|
const endDate = parseTimestamp(endTime);
|
|
@@ -41487,8 +41508,24 @@ var formatClipExplorerTimeLabel = ({
|
|
|
41487
41508
|
timezone,
|
|
41488
41509
|
durationSeconds,
|
|
41489
41510
|
idleStartTime,
|
|
41490
|
-
idleEndTime
|
|
41511
|
+
idleEndTime,
|
|
41512
|
+
clipStartTime,
|
|
41513
|
+
clipEndTime
|
|
41491
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
|
+
}
|
|
41492
41529
|
if (IDLE_RANGE_CATEGORY_IDS.has(categoryId)) {
|
|
41493
41530
|
const idleDurationSeconds = getSecondsBetweenTimestamps(idleStartTime, idleEndTime);
|
|
41494
41531
|
const idleEndTimestamp = idleEndTime || clipTimestamp;
|
|
@@ -41515,6 +41552,106 @@ var formatClipExplorerTimeLabel = ({
|
|
|
41515
41552
|
return singleTime;
|
|
41516
41553
|
};
|
|
41517
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
|
+
};
|
|
41518
41655
|
var formatTime2 = (seconds) => {
|
|
41519
41656
|
if (!seconds || isNaN(seconds)) return "0:00";
|
|
41520
41657
|
const h = Math.floor(seconds / 3600);
|
|
@@ -41525,6 +41662,33 @@ var formatTime2 = (seconds) => {
|
|
|
41525
41662
|
}
|
|
41526
41663
|
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
41527
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
|
+
};
|
|
41528
41692
|
var VideoControls = ({
|
|
41529
41693
|
isPlaying,
|
|
41530
41694
|
currentTime,
|
|
@@ -41543,15 +41707,20 @@ var VideoControls = ({
|
|
|
41543
41707
|
onShare,
|
|
41544
41708
|
isShareLoading = false,
|
|
41545
41709
|
isShareCopied = false,
|
|
41710
|
+
timelineAnnotations,
|
|
41711
|
+
timelineExplanation,
|
|
41712
|
+
timelineTimezone,
|
|
41546
41713
|
className = ""
|
|
41547
41714
|
}) => {
|
|
41548
41715
|
const [isDragging2, setIsDragging] = useState(false);
|
|
41549
41716
|
const [dragTime, setDragTime] = useState(0);
|
|
41550
41717
|
const [isHoveringProgressBar, setIsHoveringProgressBar] = useState(false);
|
|
41718
|
+
const [hoveredTimelineBin, setHoveredTimelineBin] = useState(null);
|
|
41551
41719
|
const [showSpeedMenu, setShowSpeedMenu] = useState(false);
|
|
41552
41720
|
const speedMenuRef = useRef(null);
|
|
41553
41721
|
const progressTrackRef = useRef(null);
|
|
41554
41722
|
const activePointerIdRef = useRef(null);
|
|
41723
|
+
const markerPointerJumpHandledRef = useRef(false);
|
|
41555
41724
|
const progressColor = "#4b5563";
|
|
41556
41725
|
const controlsVisible = showControls || controlsPinned;
|
|
41557
41726
|
const isDraggingRef = useRef(false);
|
|
@@ -41575,6 +41744,43 @@ var VideoControls = ({
|
|
|
41575
41744
|
isDraggingRef.current = false;
|
|
41576
41745
|
onSeekEnd?.();
|
|
41577
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]);
|
|
41578
41784
|
const updateTimeFromClientX = useCallback((clientX) => {
|
|
41579
41785
|
if (!progressTrackRef.current) return;
|
|
41580
41786
|
const rect = progressTrackRef.current.getBoundingClientRect();
|
|
@@ -41635,6 +41841,127 @@ var VideoControls = ({
|
|
|
41635
41841
|
const displayTime = isDragging2 ? dragTime : currentTime;
|
|
41636
41842
|
const progressPercent = getPercentage(displayTime, duration);
|
|
41637
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]);
|
|
41638
41965
|
return /* @__PURE__ */ jsxs(
|
|
41639
41966
|
"div",
|
|
41640
41967
|
{
|
|
@@ -41646,12 +41973,16 @@ var VideoControls = ({
|
|
|
41646
41973
|
"div",
|
|
41647
41974
|
{
|
|
41648
41975
|
ref: progressTrackRef,
|
|
41649
|
-
className: "relative h-1 mb-4 group cursor-pointer",
|
|
41976
|
+
className: "relative z-10 h-1 mb-4 group cursor-pointer",
|
|
41650
41977
|
onMouseEnter: () => setIsHoveringProgressBar(true),
|
|
41651
|
-
|
|
41978
|
+
onMouseMove: handleProgressMouseMove,
|
|
41979
|
+
onMouseLeave: () => {
|
|
41980
|
+
setIsHoveringProgressBar(false);
|
|
41981
|
+
setHoveredTimelineBin(null);
|
|
41982
|
+
},
|
|
41652
41983
|
onPointerDown: handlePointerDown,
|
|
41653
41984
|
children: [
|
|
41654
|
-
/* @__PURE__ */ jsx("div", { className: "absolute -top-4
|
|
41985
|
+
/* @__PURE__ */ jsx("div", { className: "absolute -top-4 bottom-0 left-0 right-0 z-20" }),
|
|
41655
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(
|
|
41656
41987
|
"div",
|
|
41657
41988
|
{
|
|
@@ -41685,17 +42016,47 @@ var VideoControls = ({
|
|
|
41685
42016
|
onInput: handleSeekChange,
|
|
41686
42017
|
onMouseDown: handleSeekStart,
|
|
41687
42018
|
onMouseUp: handleSeekEnd,
|
|
42019
|
+
onMouseMove: handleProgressMouseMove,
|
|
41688
42020
|
onTouchStart: handleSeekStart,
|
|
41689
42021
|
onTouchEnd: handleSeekEnd,
|
|
41690
42022
|
onPointerDown: handlePointerDown,
|
|
41691
|
-
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
|
+
]
|
|
41692
42053
|
}
|
|
41693
42054
|
)
|
|
41694
42055
|
]
|
|
41695
42056
|
}
|
|
41696
42057
|
),
|
|
41697
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-white", children: [
|
|
41698
|
-
/* @__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: [
|
|
41699
42060
|
/* @__PURE__ */ jsx(
|
|
41700
42061
|
"button",
|
|
41701
42062
|
{
|
|
@@ -41976,7 +42337,10 @@ var HlsVideoPlayer = forwardRef(({
|
|
|
41976
42337
|
onClick,
|
|
41977
42338
|
onShare,
|
|
41978
42339
|
isShareLoading,
|
|
41979
|
-
isShareCopied
|
|
42340
|
+
isShareCopied,
|
|
42341
|
+
timelineAnnotations,
|
|
42342
|
+
timelineExplanation,
|
|
42343
|
+
timelineTimezone
|
|
41980
42344
|
}, ref) => {
|
|
41981
42345
|
const supabase = useSupabase();
|
|
41982
42346
|
const videoContainerRef = useRef(null);
|
|
@@ -42638,6 +43002,7 @@ var HlsVideoPlayer = forwardRef(({
|
|
|
42638
43002
|
const handleSeek = useCallback((time2) => {
|
|
42639
43003
|
if (videoRef.current) {
|
|
42640
43004
|
videoRef.current.currentTime = time2;
|
|
43005
|
+
setCurrentTime(time2);
|
|
42641
43006
|
}
|
|
42642
43007
|
}, []);
|
|
42643
43008
|
const handleSeekStart = useCallback(() => {
|
|
@@ -42744,7 +43109,10 @@ var HlsVideoPlayer = forwardRef(({
|
|
|
42744
43109
|
onToggleFullscreen: handleToggleFullscreen,
|
|
42745
43110
|
onShare,
|
|
42746
43111
|
isShareLoading,
|
|
42747
|
-
isShareCopied
|
|
43112
|
+
isShareCopied,
|
|
43113
|
+
timelineAnnotations,
|
|
43114
|
+
timelineExplanation,
|
|
43115
|
+
timelineTimezone
|
|
42748
43116
|
}
|
|
42749
43117
|
)
|
|
42750
43118
|
]
|
|
@@ -43065,6 +43433,7 @@ var CroppedHlsVideoPlayer = forwardRef(({
|
|
|
43065
43433
|
const handleSeek = useCallback((time2) => {
|
|
43066
43434
|
if (hiddenVideoRef.current) {
|
|
43067
43435
|
hiddenVideoRef.current.currentTime(time2);
|
|
43436
|
+
setCurrentTime(time2);
|
|
43068
43437
|
setTimeout(() => renderFrameToCanvas(), 50);
|
|
43069
43438
|
userSeekingRef.current = true;
|
|
43070
43439
|
}
|
|
@@ -43210,7 +43579,10 @@ var CroppedHlsVideoPlayer = forwardRef(({
|
|
|
43210
43579
|
onToggleFullscreen: handleToggleFullscreen,
|
|
43211
43580
|
onShare: videoProps.onShare,
|
|
43212
43581
|
isShareLoading: videoProps.isShareLoading,
|
|
43213
|
-
isShareCopied: videoProps.isShareCopied
|
|
43582
|
+
isShareCopied: videoProps.isShareCopied,
|
|
43583
|
+
timelineAnnotations: videoProps.timelineAnnotations,
|
|
43584
|
+
timelineExplanation: videoProps.timelineExplanation,
|
|
43585
|
+
timelineTimezone: videoProps.timelineTimezone
|
|
43214
43586
|
}
|
|
43215
43587
|
)
|
|
43216
43588
|
]
|
|
@@ -43219,6 +43591,100 @@ var CroppedHlsVideoPlayer = forwardRef(({
|
|
|
43219
43591
|
});
|
|
43220
43592
|
CroppedHlsVideoPlayer.displayName = "CroppedHlsVideoPlayer";
|
|
43221
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
|
+
};
|
|
43222
43688
|
function useWorkspaceCrop(workspaceId) {
|
|
43223
43689
|
const supabase = useSupabase();
|
|
43224
43690
|
const [crop, setCrop] = useState(null);
|
|
@@ -43268,7 +43734,7 @@ function Skeleton({ className, ...props }) {
|
|
|
43268
43734
|
var Select = SelectPrimitive.Root;
|
|
43269
43735
|
var SelectGroup = SelectPrimitive.Group;
|
|
43270
43736
|
var SelectValue = SelectPrimitive.Value;
|
|
43271
|
-
var SelectTrigger =
|
|
43737
|
+
var SelectTrigger = React148.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
43272
43738
|
SelectPrimitive.Trigger,
|
|
43273
43739
|
{
|
|
43274
43740
|
ref,
|
|
@@ -43284,7 +43750,7 @@ var SelectTrigger = React147.forwardRef(({ className, children, ...props }, ref)
|
|
|
43284
43750
|
}
|
|
43285
43751
|
));
|
|
43286
43752
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
43287
|
-
var SelectScrollUpButton =
|
|
43753
|
+
var SelectScrollUpButton = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
43288
43754
|
SelectPrimitive.ScrollUpButton,
|
|
43289
43755
|
{
|
|
43290
43756
|
ref,
|
|
@@ -43294,7 +43760,7 @@ var SelectScrollUpButton = React147.forwardRef(({ className, ...props }, ref) =>
|
|
|
43294
43760
|
}
|
|
43295
43761
|
));
|
|
43296
43762
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
43297
|
-
var SelectScrollDownButton =
|
|
43763
|
+
var SelectScrollDownButton = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
43298
43764
|
SelectPrimitive.ScrollDownButton,
|
|
43299
43765
|
{
|
|
43300
43766
|
ref,
|
|
@@ -43304,7 +43770,7 @@ var SelectScrollDownButton = React147.forwardRef(({ className, ...props }, ref)
|
|
|
43304
43770
|
}
|
|
43305
43771
|
));
|
|
43306
43772
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
43307
|
-
var SelectContent =
|
|
43773
|
+
var SelectContent = React148.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
43308
43774
|
SelectPrimitive.Content,
|
|
43309
43775
|
{
|
|
43310
43776
|
ref,
|
|
@@ -43332,7 +43798,7 @@ var SelectContent = React147.forwardRef(({ className, children, position = "popp
|
|
|
43332
43798
|
}
|
|
43333
43799
|
) }));
|
|
43334
43800
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
43335
|
-
var SelectLabel =
|
|
43801
|
+
var SelectLabel = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
43336
43802
|
SelectPrimitive.Label,
|
|
43337
43803
|
{
|
|
43338
43804
|
ref,
|
|
@@ -43341,7 +43807,7 @@ var SelectLabel = React147.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
43341
43807
|
}
|
|
43342
43808
|
));
|
|
43343
43809
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
43344
|
-
var SelectItem =
|
|
43810
|
+
var SelectItem = React148.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
43345
43811
|
SelectPrimitive.Item,
|
|
43346
43812
|
{
|
|
43347
43813
|
ref,
|
|
@@ -43357,7 +43823,7 @@ var SelectItem = React147.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
43357
43823
|
}
|
|
43358
43824
|
));
|
|
43359
43825
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
43360
|
-
var SelectSeparator =
|
|
43826
|
+
var SelectSeparator = React148.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
43361
43827
|
SelectPrimitive.Separator,
|
|
43362
43828
|
{
|
|
43363
43829
|
ref,
|
|
@@ -43983,7 +44449,7 @@ var TimePickerDropdown = ({
|
|
|
43983
44449
|
)
|
|
43984
44450
|
] });
|
|
43985
44451
|
};
|
|
43986
|
-
var SilentErrorBoundary = class extends
|
|
44452
|
+
var SilentErrorBoundary = class extends React148__default.Component {
|
|
43987
44453
|
constructor(props) {
|
|
43988
44454
|
super(props);
|
|
43989
44455
|
this.handleClearAndReload = () => {
|
|
@@ -44728,6 +45194,9 @@ var AvatarUpload = ({
|
|
|
44728
45194
|
] });
|
|
44729
45195
|
};
|
|
44730
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";
|
|
44731
45200
|
var parseCycleTime = (value) => {
|
|
44732
45201
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
44733
45202
|
return value;
|
|
@@ -44756,10 +45225,37 @@ var formatDurationLabel = (seconds) => {
|
|
|
44756
45225
|
}
|
|
44757
45226
|
return `${Math.round(roundedSeconds / 60)} min`;
|
|
44758
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
|
+
};
|
|
44759
45252
|
var getSeverityIcon = (severity, categoryId, cycleTimeSeconds, targetCycleTime, clipId) => {
|
|
44760
45253
|
if (categoryId === "idle_time" || categoryId === "low_value" || categoryId === "longest-idles") {
|
|
44761
45254
|
return null;
|
|
44762
45255
|
}
|
|
45256
|
+
if (categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
|
|
45257
|
+
return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3 w-3 text-red-500" });
|
|
45258
|
+
}
|
|
44763
45259
|
if (categoryId === "cycle_completion" && targetCycleTime && targetCycleTime > 0 && cycleTimeSeconds !== null && cycleTimeSeconds !== void 0) {
|
|
44764
45260
|
if (cycleTimeSeconds <= targetCycleTime) {
|
|
44765
45261
|
return /* @__PURE__ */ jsx(CheckCircle, { className: "h-3 w-3 text-green-500" });
|
|
@@ -44831,6 +45327,7 @@ var FileManagerFilters = ({
|
|
|
44831
45327
|
idleTimeVlmEnabled = false,
|
|
44832
45328
|
showPercentileCycleFilters = true,
|
|
44833
45329
|
prefetchedClipMetadata,
|
|
45330
|
+
externallyManagedLoadingCategories,
|
|
44834
45331
|
activeCategoryLoading,
|
|
44835
45332
|
idleClipSort = "latest",
|
|
44836
45333
|
onIdleClipSortChange,
|
|
@@ -44915,11 +45412,11 @@ var FileManagerFilters = ({
|
|
|
44915
45412
|
if (prefetchedClipMetadata && Array.isArray(prefetchedClipMetadata[categoryId]) && prefetchedClipMetadata[categoryId].length > 0) {
|
|
44916
45413
|
return true;
|
|
44917
45414
|
}
|
|
44918
|
-
if (
|
|
45415
|
+
if (externallyManagedLoadingCategories?.[categoryId]) {
|
|
44919
45416
|
return true;
|
|
44920
45417
|
}
|
|
44921
45418
|
return false;
|
|
44922
|
-
}, [prefetchedClipMetadata,
|
|
45419
|
+
}, [prefetchedClipMetadata, externallyManagedLoadingCategories]);
|
|
44923
45420
|
useEffect(() => {
|
|
44924
45421
|
if (!prefetchedClipMetadata) {
|
|
44925
45422
|
return;
|
|
@@ -45040,6 +45537,9 @@ var FileManagerFilters = ({
|
|
|
45040
45537
|
[idleReasonOptions, idleLabelFilter]
|
|
45041
45538
|
);
|
|
45042
45539
|
const getClipBadge = useCallback((node) => {
|
|
45540
|
+
if (node.categoryId === RECENT_FLOW_RED_STREAK_CLIP_TYPE2) {
|
|
45541
|
+
return null;
|
|
45542
|
+
}
|
|
45043
45543
|
if (node.categoryId === "idle_time" || node.categoryId === "low_value") {
|
|
45044
45544
|
return { text: "Idle", className: "bg-red-100 text-red-700" };
|
|
45045
45545
|
}
|
|
@@ -45058,6 +45558,23 @@ var FileManagerFilters = ({
|
|
|
45058
45558
|
}
|
|
45059
45559
|
return { text: "Fast", className: "bg-green-100 text-green-700" };
|
|
45060
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
|
+
}, []);
|
|
45061
45578
|
const getAuthToken4 = useCallback(async () => {
|
|
45062
45579
|
try {
|
|
45063
45580
|
return await getAccessTokenOrRedirect(supabase, { redirectReason: "session_expired" });
|
|
@@ -45066,7 +45583,7 @@ var FileManagerFilters = ({
|
|
|
45066
45583
|
return null;
|
|
45067
45584
|
}
|
|
45068
45585
|
}, [supabase]);
|
|
45069
|
-
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]);
|
|
45070
45587
|
const fetchClipMetadataPage = useCallback(async (categoryId, page = 1) => {
|
|
45071
45588
|
if (!workspaceId || !date || shift === void 0) {
|
|
45072
45589
|
throw new Error("Missing required params for clip metadata fetch");
|
|
@@ -45087,7 +45604,7 @@ var FileManagerFilters = ({
|
|
|
45087
45604
|
knownTotal: typeof counts?.[categoryId] === "number" ? counts[categoryId] : null,
|
|
45088
45605
|
snapshotDateTime,
|
|
45089
45606
|
snapshotClipId,
|
|
45090
|
-
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"
|
|
45091
45608
|
}),
|
|
45092
45609
|
redirectReason: "session_expired"
|
|
45093
45610
|
});
|
|
@@ -45458,7 +45975,7 @@ var FileManagerFilters = ({
|
|
|
45458
45975
|
fetchClipMetadata(activeFilter, 1);
|
|
45459
45976
|
}
|
|
45460
45977
|
}
|
|
45461
|
-
}, [activeFilter
|
|
45978
|
+
}, [activeFilter]);
|
|
45462
45979
|
useEffect(() => {
|
|
45463
45980
|
const handleEscape = (e) => {
|
|
45464
45981
|
if (e.key === "Escape") {
|
|
@@ -45541,6 +46058,9 @@ var FileManagerFilters = ({
|
|
|
45541
46058
|
const categoryCount = counts?.[category.id] || 0;
|
|
45542
46059
|
const categoryClips = clipMetadata[category.id] || [];
|
|
45543
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
|
+
}
|
|
45544
46064
|
if (category.id === "idle_time" && idleLabelFilter) {
|
|
45545
46065
|
filteredClips = filteredClips.filter((clip) => {
|
|
45546
46066
|
const classification = getIdleTimeClassification(clip.clipId || clip.id);
|
|
@@ -45555,15 +46075,18 @@ var FileManagerFilters = ({
|
|
|
45555
46075
|
const cycleTime = extractCycleTimeSeconds(clip);
|
|
45556
46076
|
const idleDuration = category.id === "idle_time" ? clip.idle_duration_seconds ?? clip.duration : null;
|
|
45557
46077
|
const idleDurationLabel = formatDurationLabel(idleDuration);
|
|
46078
|
+
const redFlowDurationLabel = category.id === RECENT_FLOW_RED_STREAK_CLIP_TYPE2 ? formatDurationLabel(clip.duration) : null;
|
|
45558
46079
|
const baseTimeLabel = formatClipExplorerTimeLabel({
|
|
45559
46080
|
categoryId: category.id,
|
|
45560
46081
|
clipTimestamp: clip.clip_timestamp,
|
|
45561
46082
|
timezone,
|
|
45562
46083
|
durationSeconds: idleDuration ?? clip.duration,
|
|
45563
46084
|
idleStartTime: clip.idle_start_time,
|
|
45564
|
-
idleEndTime: clip.idle_end_time
|
|
46085
|
+
idleEndTime: clip.idle_end_time,
|
|
46086
|
+
clipStartTime: clip.clip_start_time,
|
|
46087
|
+
clipEndTime: clip.clip_end_time
|
|
45565
46088
|
});
|
|
45566
|
-
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)` : ""}`;
|
|
45567
46090
|
return {
|
|
45568
46091
|
id: clip.id,
|
|
45569
46092
|
label: displayLabel,
|
|
@@ -45579,14 +46102,18 @@ var FileManagerFilters = ({
|
|
|
45579
46102
|
cycleTimeSeconds: cycleTime,
|
|
45580
46103
|
duration: idleDuration ?? clip.duration,
|
|
45581
46104
|
// Store duration for custom badge rendering
|
|
45582
|
-
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
|
|
45583
46108
|
};
|
|
45584
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;
|
|
45585
46112
|
regularCategoryNodes.push({
|
|
45586
46113
|
id: category.id,
|
|
45587
|
-
label:
|
|
45588
|
-
subtitle:
|
|
45589
|
-
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,
|
|
45590
46117
|
type: "category",
|
|
45591
46118
|
count: displayCount,
|
|
45592
46119
|
// Use filtered count when time filter is active
|
|
@@ -45698,7 +46225,7 @@ var FileManagerFilters = ({
|
|
|
45698
46225
|
})
|
|
45699
46226
|
} */
|
|
45700
46227
|
] : [];
|
|
45701
|
-
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"];
|
|
45702
46229
|
orderedIds.forEach((orderedId) => {
|
|
45703
46230
|
const percentileCategory = percentileCategories.find((cat) => cat.id === orderedId);
|
|
45704
46231
|
const shouldIncludePercentile = percentileCategory ? typeof percentileCategory.count === "number" && percentileCategory.count > 0 : false;
|
|
@@ -45811,8 +46338,15 @@ var FileManagerFilters = ({
|
|
|
45811
46338
|
const isCurrentVideo = currentVideoId === node.id;
|
|
45812
46339
|
const isCountUnknown = node.type === "percentile-category" && node.count === null;
|
|
45813
46340
|
const hasChildren = isCountUnknown || (node.count || 0) > 0;
|
|
45814
|
-
const
|
|
45815
|
-
|
|
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)
|
|
45816
46350
|
);
|
|
45817
46351
|
const colorClasses = node.color ? getColorClasses(node.color) : null;
|
|
45818
46352
|
return /* @__PURE__ */ jsxs("div", { className: "select-none animate-in", children: [
|
|
@@ -45854,9 +46388,9 @@ var FileManagerFilters = ({
|
|
|
45854
46388
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 flex items-center justify-between", children: [
|
|
45855
46389
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
45856
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 }),
|
|
45857
|
-
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 }),
|
|
45858
46392
|
node.type === "percentile-category" && node.subtitle && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: node.subtitle }),
|
|
45859
|
-
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" ? (
|
|
45860
46394
|
// Show root cause label for idle time clips (text only, icon is on the left)
|
|
45861
46395
|
(() => {
|
|
45862
46396
|
if (!idleTimeVlmEnabled) {
|
|
@@ -45878,8 +46412,10 @@ var FileManagerFilters = ({
|
|
|
45878
46412
|
// Show badge for other clips
|
|
45879
46413
|
(() => {
|
|
45880
46414
|
const badge = getClipBadge(node);
|
|
46415
|
+
const redFlowDriverBadges = getRedFlowDriverBadges(node);
|
|
45881
46416
|
return /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1.5", children: [
|
|
45882
|
-
/* @__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)),
|
|
45883
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: [
|
|
45884
46420
|
"x",
|
|
45885
46421
|
node.cycleItemCount
|
|
@@ -45895,21 +46431,20 @@ var FileManagerFilters = ({
|
|
|
45895
46431
|
),
|
|
45896
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: [
|
|
45897
46433
|
node.children.map((child) => renderNode(child, depth + 1)),
|
|
45898
|
-
|
|
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: [
|
|
45899
46435
|
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
45900
46436
|
"Loading clips..."
|
|
45901
46437
|
] }) }),
|
|
45902
|
-
|
|
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: [
|
|
45903
46439
|
/* @__PURE__ */ jsx("div", { className: "animate-spin mr-2 h-4 w-4 border-2 border-slate-300 border-t-blue-500 rounded-full" }),
|
|
45904
46440
|
"Loading more clips..."
|
|
45905
46441
|
] }) }),
|
|
45906
|
-
categoryHasMore[node.id] && !
|
|
46442
|
+
categoryHasMore[node.id] && !isLoadMoreLoading && /* @__PURE__ */ jsxs(
|
|
45907
46443
|
"button",
|
|
45908
46444
|
{
|
|
45909
46445
|
onClick: (e) => {
|
|
45910
46446
|
e.stopPropagation();
|
|
45911
|
-
|
|
45912
|
-
fetchClipMetadata(node.id, nextPage);
|
|
46447
|
+
fetchClipMetadata(node.id, nextLoadMorePage);
|
|
45913
46448
|
},
|
|
45914
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",
|
|
45915
46450
|
children: [
|
|
@@ -46672,6 +47207,7 @@ var BottlenecksContent = ({
|
|
|
46672
47207
|
triageMode = false,
|
|
46673
47208
|
ticketId,
|
|
46674
47209
|
prefetchedPercentileCounts,
|
|
47210
|
+
lowMomentsPrefetch,
|
|
46675
47211
|
initialTimeFilter
|
|
46676
47212
|
}) => {
|
|
46677
47213
|
console.log("\u{1F3AB} [BottlenecksContent] Rendered with ticketId:", ticketId || "NONE", "workspaceId:", workspaceId, "date:", date, "shift:", shift);
|
|
@@ -46764,6 +47300,10 @@ var BottlenecksContent = ({
|
|
|
46764
47300
|
const [isShareLoading, setIsShareLoading] = useState(false);
|
|
46765
47301
|
const [isShareCopied, setIsShareCopied] = useState(false);
|
|
46766
47302
|
const shareCopiedTimeoutRef = useRef(null);
|
|
47303
|
+
const [lowEfficiencyAiSummaryByClipId, setLowEfficiencyAiSummaryByClipId] = useState({});
|
|
47304
|
+
const [lowEfficiencyAiSummaryLoadingByClipId, setLowEfficiencyAiSummaryLoadingByClipId] = useState({});
|
|
47305
|
+
const [lowEfficiencyAiSummaryErrorByClipId, setLowEfficiencyAiSummaryErrorByClipId] = useState({});
|
|
47306
|
+
const lowEfficiencyAiSummaryRequestStatusRef = useRef({});
|
|
46767
47307
|
useEffect(() => {
|
|
46768
47308
|
return () => {
|
|
46769
47309
|
if (shareCopiedTimeoutRef.current) {
|
|
@@ -46772,6 +47312,7 @@ var BottlenecksContent = ({
|
|
|
46772
47312
|
};
|
|
46773
47313
|
}, []);
|
|
46774
47314
|
const loadingTimeoutRef = useRef(null);
|
|
47315
|
+
const metadataLoadingKeyRef = useRef(null);
|
|
46775
47316
|
const [activeFilter, setActiveFilter] = useState(initialFilter);
|
|
46776
47317
|
const previousFilterRef = useRef("");
|
|
46777
47318
|
const [allVideos, setAllVideos] = useState([]);
|
|
@@ -46928,60 +47469,33 @@ var BottlenecksContent = ({
|
|
|
46928
47469
|
if (initialFilter) {
|
|
46929
47470
|
return;
|
|
46930
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
|
+
}
|
|
46931
47479
|
if (defaultCategory) {
|
|
46932
47480
|
setInitialFilter(defaultCategory);
|
|
46933
47481
|
setActiveFilter(defaultCategory);
|
|
46934
47482
|
activeFilterRef.current = defaultCategory;
|
|
46935
47483
|
return;
|
|
46936
47484
|
}
|
|
46937
|
-
if (clipTypes.length > 0) {
|
|
46938
|
-
let selectedType = null;
|
|
46939
|
-
if (clipTypes.length === 1) {
|
|
46940
|
-
selectedType = clipTypes[0];
|
|
46941
|
-
} else {
|
|
46942
|
-
const priorityOrder = ["cycle_completion", "fast-cycles", "slow-cycles", "idle_time"];
|
|
46943
|
-
for (const priorityType of priorityOrder) {
|
|
46944
|
-
const type = clipTypes.find((t) => t.type === priorityType && (dynamicCounts[t.type] || 0) > 0);
|
|
46945
|
-
if (type) {
|
|
46946
|
-
selectedType = type;
|
|
46947
|
-
break;
|
|
46948
|
-
}
|
|
46949
|
-
}
|
|
46950
|
-
if (!selectedType) {
|
|
46951
|
-
selectedType = clipTypes.find((type) => (dynamicCounts[type.type] || 0) > 0);
|
|
46952
|
-
}
|
|
46953
|
-
if (!selectedType) {
|
|
46954
|
-
selectedType = clipTypes[0];
|
|
46955
|
-
}
|
|
46956
|
-
}
|
|
46957
|
-
if (selectedType) {
|
|
46958
|
-
console.log(`[BottlenecksContent] Auto-selecting filter: ${selectedType.type} (count: ${dynamicCounts[selectedType.type] || 0})`);
|
|
46959
|
-
setInitialFilter(selectedType.type);
|
|
46960
|
-
setActiveFilter(selectedType.type);
|
|
46961
|
-
activeFilterRef.current = selectedType.type;
|
|
46962
|
-
}
|
|
46963
|
-
}
|
|
46964
47485
|
}, [clipTypes, dynamicCounts, defaultCategory, initialFilter]);
|
|
46965
47486
|
const mergedCounts = useMemo(() => {
|
|
46966
47487
|
return { ...dynamicCounts };
|
|
46967
47488
|
}, [dynamicCounts]);
|
|
46968
47489
|
useEffect(() => {
|
|
46969
|
-
if (
|
|
47490
|
+
if (allVideos.length > 0 || !isMountedRef.current) {
|
|
46970
47491
|
return;
|
|
46971
47492
|
}
|
|
46972
|
-
if (activeFilterRef.current
|
|
47493
|
+
if (!activeFilterRef.current) {
|
|
47494
|
+
setHasInitialLoad(true);
|
|
47495
|
+
setIsCategoryLoading(false);
|
|
46973
47496
|
return;
|
|
46974
47497
|
}
|
|
46975
|
-
|
|
46976
|
-
setAllVideos([firstClip]);
|
|
46977
|
-
setCurrentPosition(1);
|
|
46978
|
-
currentPositionRef.current = 1;
|
|
46979
|
-
const total = mergedCounts[firstClip.type] || 0;
|
|
46980
|
-
currentTotalRef.current = total;
|
|
46981
|
-
setCurrentTotal(total);
|
|
46982
|
-
setHasInitialLoad(true);
|
|
46983
|
-
setIsCategoryLoading(false);
|
|
46984
|
-
}, [firstClip, allVideos.length, mergedCounts]);
|
|
47498
|
+
}, [firstClips, allVideos.length, mergedCounts]);
|
|
46985
47499
|
useEffect(() => {
|
|
46986
47500
|
if (!firstClips || typeof document === "undefined") {
|
|
46987
47501
|
return;
|
|
@@ -47017,25 +47531,6 @@ var BottlenecksContent = ({
|
|
|
47017
47531
|
const loadFirstVideoForCategory = useCallback(async (category) => {
|
|
47018
47532
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current || !isEffectiveShiftReady) return;
|
|
47019
47533
|
const targetCategory = category || activeFilterRef.current;
|
|
47020
|
-
const initClip = targetCategory ? firstClips?.[targetCategory] : null;
|
|
47021
|
-
if (initClip) {
|
|
47022
|
-
setCurrentClipId(initClip.id || null);
|
|
47023
|
-
setAllVideos((prev) => {
|
|
47024
|
-
const exists = prev.some((v) => v.id === initClip.id);
|
|
47025
|
-
if (!exists) {
|
|
47026
|
-
return [...prev, initClip];
|
|
47027
|
-
}
|
|
47028
|
-
return prev;
|
|
47029
|
-
});
|
|
47030
|
-
setCurrentPosition(1);
|
|
47031
|
-
currentPositionRef.current = 1;
|
|
47032
|
-
const total = mergedCounts[targetCategory] || 0;
|
|
47033
|
-
currentTotalRef.current = total;
|
|
47034
|
-
setCurrentTotal(total);
|
|
47035
|
-
setHasInitialLoad(true);
|
|
47036
|
-
setIsCategoryLoading(false);
|
|
47037
|
-
return;
|
|
47038
|
-
}
|
|
47039
47534
|
const operationKey = `loadFirstVideo:${targetCategory}:${effectiveDateString}:${effectiveShiftId}`;
|
|
47040
47535
|
if (loadingCategoryRef.current === targetCategory || fetchInProgressRef.current.has(operationKey)) {
|
|
47041
47536
|
console.log(`[BottlenecksContent] Load first video already in progress for ${targetCategory}`);
|
|
@@ -47051,12 +47546,25 @@ var BottlenecksContent = ({
|
|
|
47051
47546
|
const shiftStr = effectiveShiftId;
|
|
47052
47547
|
console.log(`[BottlenecksContent] Loading first video for category: ${targetCategory}`);
|
|
47053
47548
|
try {
|
|
47054
|
-
|
|
47055
|
-
|
|
47056
|
-
|
|
47057
|
-
|
|
47058
|
-
|
|
47059
|
-
|
|
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
|
+
}
|
|
47060
47568
|
if (firstVideo) {
|
|
47061
47569
|
console.log(`[BottlenecksContent] Successfully loaded first video, ID: ${firstVideo.id}`);
|
|
47062
47570
|
setCurrentClipId(firstVideo.id || null);
|
|
@@ -47067,8 +47575,8 @@ var BottlenecksContent = ({
|
|
|
47067
47575
|
}
|
|
47068
47576
|
return prev;
|
|
47069
47577
|
});
|
|
47070
|
-
setCurrentPosition(1);
|
|
47071
|
-
currentPositionRef.current = 1;
|
|
47578
|
+
setCurrentPosition(totalCategoryClips > 0 ? 1 : 0);
|
|
47579
|
+
currentPositionRef.current = totalCategoryClips > 0 ? 1 : 0;
|
|
47072
47580
|
const total = mergedCounts[targetCategory] || 0;
|
|
47073
47581
|
currentTotalRef.current = total;
|
|
47074
47582
|
setCurrentTotal(total);
|
|
@@ -47082,13 +47590,13 @@ var BottlenecksContent = ({
|
|
|
47082
47590
|
}
|
|
47083
47591
|
if (mergedCounts[targetCategory] > 0) {
|
|
47084
47592
|
try {
|
|
47593
|
+
const fallbackIndex = 0;
|
|
47085
47594
|
const firstVideo = await s3ClipsService.getClipByIndex(
|
|
47086
47595
|
workspaceId,
|
|
47087
47596
|
operationalDate,
|
|
47088
47597
|
shiftStr,
|
|
47089
47598
|
targetCategory,
|
|
47090
|
-
|
|
47091
|
-
// First video (index 0)
|
|
47599
|
+
fallbackIndex
|
|
47092
47600
|
);
|
|
47093
47601
|
if (firstVideo && isMountedRef.current) {
|
|
47094
47602
|
console.log(`[BottlenecksContent] Successfully loaded first video via index`);
|
|
@@ -47191,11 +47699,12 @@ var BottlenecksContent = ({
|
|
|
47191
47699
|
categoryId
|
|
47192
47700
|
}));
|
|
47193
47701
|
};
|
|
47194
|
-
const [cycleClips, idleClips] = await Promise.all([
|
|
47702
|
+
const [cycleClips, redFlowClips, idleClips] = await Promise.all([
|
|
47195
47703
|
fetchCategoryMetadata("cycle_completion"),
|
|
47704
|
+
fetchCategoryMetadata("recent_flow_red_streak"),
|
|
47196
47705
|
fetchCategoryMetadata("idle_time")
|
|
47197
47706
|
]);
|
|
47198
|
-
const allClips = [...cycleClips, ...idleClips].sort(
|
|
47707
|
+
const allClips = [...cycleClips, ...redFlowClips, ...idleClips].sort(
|
|
47199
47708
|
(a, b) => new Date(b.clip_timestamp).getTime() - new Date(a.clip_timestamp).getTime()
|
|
47200
47709
|
);
|
|
47201
47710
|
setTriageClips(allClips);
|
|
@@ -47244,6 +47753,9 @@ var BottlenecksContent = ({
|
|
|
47244
47753
|
}, [idleTimeVlmEnabled, triageClips, triageMode, getAuthToken4]);
|
|
47245
47754
|
useEffect(() => {
|
|
47246
47755
|
if (s3ClipsService && (mergedCounts[activeFilter] || 0) > 0) {
|
|
47756
|
+
if (activeFilter === "recent_flow_red_streak") {
|
|
47757
|
+
return;
|
|
47758
|
+
}
|
|
47247
47759
|
if (firstClip && firstClip.type === activeFilter) {
|
|
47248
47760
|
return;
|
|
47249
47761
|
}
|
|
@@ -47264,10 +47776,10 @@ var BottlenecksContent = ({
|
|
|
47264
47776
|
return ["fast-cycles", "slow-cycles", "longest-idles"].includes(categoryId);
|
|
47265
47777
|
}, [isFastSlowClipFiltersEnabled]);
|
|
47266
47778
|
const shouldUseMetadataNavigation = useCallback((categoryId) => {
|
|
47267
|
-
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";
|
|
47268
47780
|
}, [idleClipSort, isPercentileCategory]);
|
|
47269
47781
|
const getMetadataCacheKey = useCallback((categoryId) => {
|
|
47270
|
-
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";
|
|
47271
47783
|
return `${categoryId}-${effectiveDateString}-${effectiveShiftId}-${snapshotDateTime ?? "nosnap"}-${snapshotClipId ?? "nosnap"}-${sortKey}`;
|
|
47272
47784
|
}, [effectiveDateString, effectiveShiftId, snapshotDateTime, snapshotClipId, idleClipSort]);
|
|
47273
47785
|
const setVisibleCategoryMetadata = useCallback((categoryId, clips) => {
|
|
@@ -47277,7 +47789,7 @@ var BottlenecksContent = ({
|
|
|
47277
47789
|
categoryMetadataRef.current = clips;
|
|
47278
47790
|
setCategoryMetadata(clips);
|
|
47279
47791
|
setCategoryMetadataCategoryId(clips.length > 0 ? categoryId : null);
|
|
47280
|
-
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);
|
|
47281
47793
|
return true;
|
|
47282
47794
|
}, [idleClipSort]);
|
|
47283
47795
|
const applyMetadataSnapshot = useCallback((categoryId, clips, total) => {
|
|
@@ -47295,6 +47807,22 @@ var BottlenecksContent = ({
|
|
|
47295
47807
|
setCurrentTotal(total);
|
|
47296
47808
|
}
|
|
47297
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
|
+
}, []);
|
|
47298
47826
|
const getClipTypesForPercentileCategory = useCallback((categoryId) => {
|
|
47299
47827
|
switch (categoryId) {
|
|
47300
47828
|
case "fast-cycles":
|
|
@@ -47314,7 +47842,7 @@ var BottlenecksContent = ({
|
|
|
47314
47842
|
if (activeFilter !== "fast-cycles" && activeFilter !== "slow-cycles") {
|
|
47315
47843
|
return;
|
|
47316
47844
|
}
|
|
47317
|
-
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;
|
|
47318
47846
|
if (!fallbackFilter || fallbackFilter === activeFilter) {
|
|
47319
47847
|
return;
|
|
47320
47848
|
}
|
|
@@ -47370,30 +47898,70 @@ var BottlenecksContent = ({
|
|
|
47370
47898
|
setCategoryMetadataCategoryId(null);
|
|
47371
47899
|
setCategoryMetadataSort(null);
|
|
47372
47900
|
categoryMetadataRef.current = [];
|
|
47901
|
+
if (activeFilterRef.current === categoryId) {
|
|
47902
|
+
setIsCategoryLoading(false);
|
|
47903
|
+
}
|
|
47373
47904
|
return;
|
|
47374
47905
|
}
|
|
47375
47906
|
if (!isEffectiveShiftReady) {
|
|
47376
47907
|
console.log("[BottlenecksContent] Skipping metadata load - shift/date not ready");
|
|
47908
|
+
if (activeFilterRef.current === categoryId) {
|
|
47909
|
+
setIsCategoryLoading(false);
|
|
47910
|
+
}
|
|
47377
47911
|
return;
|
|
47378
47912
|
}
|
|
47379
47913
|
const resolvedDate = effectiveDateString;
|
|
47380
47914
|
const cacheKey = getMetadataCacheKey(categoryId);
|
|
47381
|
-
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;
|
|
47382
47940
|
try {
|
|
47383
47941
|
if (cachedMetadata) {
|
|
47384
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
|
+
}
|
|
47385
47949
|
setVisibleCategoryMetadata(categoryId, cachedMetadata);
|
|
47386
47950
|
if (autoLoadFirstVideo && cachedMetadata.length > 0 && s3ClipsService) {
|
|
47387
47951
|
const firstClipMeta = cachedMetadata[0];
|
|
47952
|
+
const firstClipId = firstClipMeta.clipId || firstClipMeta.id;
|
|
47953
|
+
const prefetchedFirstVideo = matchingLowMomentsPrefetch?.firstVideo ?? null;
|
|
47388
47954
|
try {
|
|
47389
|
-
|
|
47390
|
-
if (
|
|
47391
|
-
|
|
47392
|
-
|
|
47393
|
-
|
|
47394
|
-
|
|
47395
|
-
|
|
47396
|
-
|
|
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})`);
|
|
47397
47965
|
}
|
|
47398
47966
|
} catch (error2) {
|
|
47399
47967
|
console.error(`[BottlenecksContent] Error loading first video from cache:`, error2);
|
|
@@ -47440,7 +48008,7 @@ var BottlenecksContent = ({
|
|
|
47440
48008
|
knownTotal: mergedCounts[categoryId] ?? null,
|
|
47441
48009
|
snapshotDateTime,
|
|
47442
48010
|
snapshotClipId,
|
|
47443
|
-
sort: categoryId === "idle_time" ? idleClipSort : "latest"
|
|
48011
|
+
sort: categoryId === "recent_flow_red_streak" ? "red_flow_output_shortfall_desc" : categoryId === "idle_time" ? idleClipSort : "latest"
|
|
47444
48012
|
}),
|
|
47445
48013
|
redirectReason: "session_expired"
|
|
47446
48014
|
});
|
|
@@ -47501,10 +48069,11 @@ var BottlenecksContent = ({
|
|
|
47501
48069
|
console.log(`[BottlenecksContent] Loaded metadata for ${categoryId}: ${metadataClips.length} clips`);
|
|
47502
48070
|
if (autoLoadFirstVideo && metadataClips.length > 0 && s3ClipsService) {
|
|
47503
48071
|
const firstClipMeta = metadataClips[0];
|
|
48072
|
+
const firstClipId = firstClipMeta.clipId || firstClipMeta.id;
|
|
47504
48073
|
try {
|
|
47505
|
-
const video = await s3ClipsService.getClipById(
|
|
48074
|
+
const video = await s3ClipsService.getClipById(firstClipId);
|
|
47506
48075
|
if (video && isMountedRef.current) {
|
|
47507
|
-
setCurrentClipId(
|
|
48076
|
+
setCurrentClipId(firstClipId);
|
|
47508
48077
|
setAllVideos([video]);
|
|
47509
48078
|
setCurrentIndex(0);
|
|
47510
48079
|
setCurrentMetadataIndex(0);
|
|
@@ -47526,9 +48095,43 @@ var BottlenecksContent = ({
|
|
|
47526
48095
|
} catch (error2) {
|
|
47527
48096
|
console.error(`[BottlenecksContent] Error loading category metadata:`, error2);
|
|
47528
48097
|
} finally {
|
|
47529
|
-
|
|
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);
|
|
47530
48125
|
}
|
|
47531
|
-
}, [
|
|
48126
|
+
}, [
|
|
48127
|
+
activeFilter,
|
|
48128
|
+
lowMomentsPrefetch,
|
|
48129
|
+
effectiveDateString,
|
|
48130
|
+
effectiveShiftId,
|
|
48131
|
+
allVideos,
|
|
48132
|
+
applyPrefetchedFirstVideo,
|
|
48133
|
+
applyMetadataSnapshot
|
|
48134
|
+
]);
|
|
47532
48135
|
useEffect(() => {
|
|
47533
48136
|
if (previousIdleClipSortRef.current === idleClipSort) {
|
|
47534
48137
|
return;
|
|
@@ -47568,8 +48171,13 @@ var BottlenecksContent = ({
|
|
|
47568
48171
|
currentTotalRef.current = total;
|
|
47569
48172
|
setCurrentTotal(total);
|
|
47570
48173
|
previousFilterRef.current = activeFilter;
|
|
47571
|
-
|
|
47572
|
-
|
|
48174
|
+
const metadataLoadPlan = getCategoryMetadataLoadPlanForFilterChange({
|
|
48175
|
+
activeFilter,
|
|
48176
|
+
currentClipId,
|
|
48177
|
+
categoryTotal: total
|
|
48178
|
+
});
|
|
48179
|
+
if (metadataLoadPlan.shouldLoad) {
|
|
48180
|
+
loadCategoryMetadata(activeFilter, metadataLoadPlan.autoLoadFirstVideo);
|
|
47573
48181
|
}
|
|
47574
48182
|
const filtered = allVideos.filter((video) => {
|
|
47575
48183
|
if (activeFilter === "all") return true;
|
|
@@ -47592,11 +48200,11 @@ var BottlenecksContent = ({
|
|
|
47592
48200
|
if (!currentClipId || activeFilter === "all") {
|
|
47593
48201
|
return;
|
|
47594
48202
|
}
|
|
47595
|
-
if (categoryMetadataRef.current.length > 0
|
|
48203
|
+
if (categoryMetadataRef.current.length > 0) {
|
|
47596
48204
|
return;
|
|
47597
48205
|
}
|
|
47598
48206
|
loadCategoryMetadata(activeFilter, false);
|
|
47599
|
-
}, [currentClipId, activeFilter,
|
|
48207
|
+
}, [currentClipId, activeFilter, loadCategoryMetadata]);
|
|
47600
48208
|
const loadAndPlayClipById = useCallback(async (clipId, categoryId, position, metadataContext) => {
|
|
47601
48209
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
|
|
47602
48210
|
console.log(`[BottlenecksContent] Loading clip by ID: ${clipId}, category=${categoryId}, position=${position}`);
|
|
@@ -48055,6 +48663,98 @@ var BottlenecksContent = ({
|
|
|
48055
48663
|
}
|
|
48056
48664
|
return filteredVideos[currentIndex];
|
|
48057
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
|
+
]);
|
|
48058
48758
|
const handleShareClip = useCallback(async () => {
|
|
48059
48759
|
if (!currentVideo?.id || isShareLoading) {
|
|
48060
48760
|
if (!currentVideo?.id) {
|
|
@@ -48126,11 +48826,11 @@ var BottlenecksContent = ({
|
|
|
48126
48826
|
}
|
|
48127
48827
|
return currentPosition;
|
|
48128
48828
|
}, [activeFilter, categoryMetadata.length, currentMetadataIndex, currentPosition, shouldUseMetadataNavigation]);
|
|
48129
|
-
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(
|
|
48130
48830
|
activeFilter,
|
|
48131
48831
|
categoryMetadataCategoryId,
|
|
48132
48832
|
categoryMetadata
|
|
48133
|
-
), [activeFilter, categoryMetadata, categoryMetadataCategoryId, categoryMetadataSort, idleClipSort]);
|
|
48833
|
+
), [activeFilter, categoryMetadata, categoryMetadataCategoryId, categoryMetadataSort, idleClipSort, lowMomentsPrefetch, effectiveDateString, effectiveShiftId]);
|
|
48134
48834
|
const classificationClipIds = useMemo(() => {
|
|
48135
48835
|
if (!idleTimeVlmEnabled) {
|
|
48136
48836
|
return [];
|
|
@@ -48522,6 +49222,8 @@ var BottlenecksContent = ({
|
|
|
48522
49222
|
return "Cycle Completion";
|
|
48523
49223
|
case "idle_time":
|
|
48524
49224
|
return "Idle Time";
|
|
49225
|
+
case "recent_flow_red_streak":
|
|
49226
|
+
return "Low efficiency videos";
|
|
48525
49227
|
case "running_cycle":
|
|
48526
49228
|
return "Running Cycle";
|
|
48527
49229
|
case "setup_state":
|
|
@@ -48601,12 +49303,26 @@ var BottlenecksContent = ({
|
|
|
48601
49303
|
onShare: handleShareClip,
|
|
48602
49304
|
isShareLoading,
|
|
48603
49305
|
isShareCopied,
|
|
49306
|
+
timelineAnnotations: currentVideo.red_flow_timeline,
|
|
49307
|
+
timelineExplanation: currentVideo.red_flow_explanation,
|
|
49308
|
+
timelineTimezone: timezone,
|
|
48604
49309
|
options: videoPlayerOptions
|
|
48605
49310
|
},
|
|
48606
49311
|
`${currentVideo.id}-${playerInstanceNonce}-inline`
|
|
48607
49312
|
)
|
|
48608
49313
|
}
|
|
48609
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,
|
|
48610
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..." }) }),
|
|
48611
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..." }) }),
|
|
48612
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: [
|
|
@@ -48706,10 +49422,10 @@ var BottlenecksContent = ({
|
|
|
48706
49422
|
] }) })
|
|
48707
49423
|
] });
|
|
48708
49424
|
})()
|
|
48709
|
-
) : /* @__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: [
|
|
48710
49426
|
/* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 rounded-full ${getSeverityColor(currentVideo.severity)} mr-2 animate-pulse` }),
|
|
48711
49427
|
/* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
|
|
48712
|
-
/* @__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 })
|
|
48713
49429
|
] }) })
|
|
48714
49430
|
)
|
|
48715
49431
|
] }) }) }) : (
|
|
@@ -48719,14 +49435,21 @@ var BottlenecksContent = ({
|
|
|
48719
49435
|
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No Clips Found" }),
|
|
48720
49436
|
/* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "There were no video clips found for this workspace today." })
|
|
48721
49437
|
] }) }) : (
|
|
48722
|
-
/* Priority
|
|
48723
|
-
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: [
|
|
48724
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" }) }),
|
|
48725
|
-
/* @__PURE__ */ jsx("h3", { className: "text-xl font-medium text-gray-700 mb-2", children: "No
|
|
48726
|
-
/* @__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." })
|
|
48727
49443
|
] }) }) : (
|
|
48728
|
-
/* Priority
|
|
48729
|
-
|
|
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
|
+
)
|
|
48730
49453
|
)
|
|
48731
49454
|
)
|
|
48732
49455
|
) }) }),
|
|
@@ -48878,6 +49601,11 @@ var BottlenecksContent = ({
|
|
|
48878
49601
|
idleTimeVlmEnabled,
|
|
48879
49602
|
showPercentileCycleFilters: isFastSlowClipFiltersEnabled,
|
|
48880
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
|
+
},
|
|
48881
49609
|
activeCategoryLoading: isCategoryLoading,
|
|
48882
49610
|
idleClipSort,
|
|
48883
49611
|
onIdleClipSortChange: setIdleClipSort,
|
|
@@ -48993,10 +49721,10 @@ var BottlenecksContent = ({
|
|
|
48993
49721
|
] }) })
|
|
48994
49722
|
] });
|
|
48995
49723
|
})()
|
|
48996
|
-
) : /* @__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: [
|
|
48997
49725
|
/* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-3 w-3 rounded-full ${getSeverityColor(currentVideo.severity)} mr-2 animate-pulse` }),
|
|
48998
49726
|
/* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
|
|
48999
|
-
/* @__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 })
|
|
49000
49728
|
] }) }),
|
|
49001
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: [
|
|
49002
49730
|
/* @__PURE__ */ jsx(
|
|
@@ -49032,12 +49760,26 @@ var BottlenecksContent = ({
|
|
|
49032
49760
|
onShare: handleShareClip,
|
|
49033
49761
|
isShareLoading,
|
|
49034
49762
|
isShareCopied,
|
|
49763
|
+
timelineAnnotations: currentVideo.red_flow_timeline,
|
|
49764
|
+
timelineExplanation: currentVideo.red_flow_explanation,
|
|
49765
|
+
timelineTimezone: timezone,
|
|
49035
49766
|
options: videoPlayerOptions
|
|
49036
49767
|
},
|
|
49037
49768
|
`${currentVideo.id}-${playerInstanceNonce}-fullscreen`
|
|
49038
49769
|
)
|
|
49039
49770
|
}
|
|
49040
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,
|
|
49041
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..." }) }),
|
|
49042
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..." }) }),
|
|
49043
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: [
|
|
@@ -51060,8 +51802,8 @@ var IdleTimeReasonChartComponent = ({
|
|
|
51060
51802
|
updateAnimation = "replay",
|
|
51061
51803
|
variant = "pie"
|
|
51062
51804
|
}) => {
|
|
51063
|
-
const [activeData, setActiveData] =
|
|
51064
|
-
|
|
51805
|
+
const [activeData, setActiveData] = React148__default.useState([]);
|
|
51806
|
+
React148__default.useEffect(() => {
|
|
51065
51807
|
if (updateAnimation === "smooth") {
|
|
51066
51808
|
setActiveData(data && data.length > 0 ? data : []);
|
|
51067
51809
|
return;
|
|
@@ -51080,7 +51822,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
51080
51822
|
setActiveData([]);
|
|
51081
51823
|
}
|
|
51082
51824
|
}, [data, updateAnimation]);
|
|
51083
|
-
|
|
51825
|
+
React148__default.useEffect(() => {
|
|
51084
51826
|
if (!data || data.length === 0) return;
|
|
51085
51827
|
data.forEach((entry, index) => {
|
|
51086
51828
|
if (entry.name.toLowerCase().includes("other")) {
|
|
@@ -51088,7 +51830,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
51088
51830
|
}
|
|
51089
51831
|
});
|
|
51090
51832
|
}, [data]);
|
|
51091
|
-
const pieKey =
|
|
51833
|
+
const pieKey = React148__default.useMemo(() => {
|
|
51092
51834
|
if (updateAnimation === "smooth") {
|
|
51093
51835
|
return "smooth";
|
|
51094
51836
|
}
|
|
@@ -51258,7 +52000,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
51258
52000
|
)
|
|
51259
52001
|
] });
|
|
51260
52002
|
};
|
|
51261
|
-
var IdleTimeReasonChart =
|
|
52003
|
+
var IdleTimeReasonChart = React148__default.memo(IdleTimeReasonChartComponent);
|
|
51262
52004
|
IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
|
|
51263
52005
|
var IdleTimeReasonChart_default = IdleTimeReasonChart;
|
|
51264
52006
|
|
|
@@ -53482,7 +54224,7 @@ var StatusIndicator = ({ status }) => {
|
|
|
53482
54224
|
case "bottleneck":
|
|
53483
54225
|
return /* @__PURE__ */ jsx(Zap, { className: "h-5 w-5 text-orange-400", "aria-label": "Bottleneck" });
|
|
53484
54226
|
case "lowEfficiency":
|
|
53485
|
-
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" });
|
|
53486
54228
|
case "inactive":
|
|
53487
54229
|
return /* @__PURE__ */ jsx("div", { className: "h-3 w-3 bg-gray-400 rounded-full", title: "Inactive", "aria-label": "Inactive Workspace" });
|
|
53488
54230
|
default:
|
|
@@ -55785,21 +56527,22 @@ var WorkspaceCycleTimeMetricCards = ({
|
|
|
55785
56527
|
liveSkuId
|
|
55786
56528
|
}) => {
|
|
55787
56529
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
55788
|
-
const activeSku =
|
|
56530
|
+
const activeSku = React148__default.useMemo(() => {
|
|
55789
56531
|
if (skuAware && activeSkuId && skuBreakdown) {
|
|
55790
56532
|
return skuBreakdown.find((s) => s.sku_id === activeSkuId);
|
|
55791
56533
|
}
|
|
55792
56534
|
return null;
|
|
55793
56535
|
}, [skuAware, activeSkuId, skuBreakdown]);
|
|
55794
|
-
const displaySku =
|
|
56536
|
+
const displaySku = React148__default.useMemo(() => {
|
|
55795
56537
|
if (activeSku) return activeSku;
|
|
55796
56538
|
if (skuAware && !activeSkuId && liveSkuId && skuBreakdown) {
|
|
55797
56539
|
return skuBreakdown.find((s) => s.sku_id === liveSkuId) ?? null;
|
|
55798
56540
|
}
|
|
55799
56541
|
return null;
|
|
55800
56542
|
}, [activeSku, skuAware, activeSkuId, liveSkuId, skuBreakdown]);
|
|
55801
|
-
const
|
|
55802
|
-
const
|
|
56543
|
+
const metricSku = displaySku;
|
|
56544
|
+
const cycleValue = metricSku ? metricSku.avg_cycle_time : workspace.avg_cycle_time;
|
|
56545
|
+
const cycleStandard = metricSku ? metricSku.ideal_cycle_time : workspace.ideal_cycle_time;
|
|
55803
56546
|
const displaySkuLabel = displaySku ? getSkuDisplayName(displaySku) : "";
|
|
55804
56547
|
const efficiencyValue = workspace.avg_efficiency || 0;
|
|
55805
56548
|
const efficiencyTarget = effectiveLegend.green_min;
|
|
@@ -56035,7 +56778,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
56035
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
|
|
56036
56779
|
prevProps.position.id === nextProps.position.id;
|
|
56037
56780
|
};
|
|
56038
|
-
var WorkspaceGridItem =
|
|
56781
|
+
var WorkspaceGridItem = React148__default.memo(({
|
|
56039
56782
|
data,
|
|
56040
56783
|
position,
|
|
56041
56784
|
isBottleneck = false,
|
|
@@ -56130,7 +56873,7 @@ var WorkspaceGridItem = React147__default.memo(({
|
|
|
56130
56873
|
);
|
|
56131
56874
|
}, arePropsEqual);
|
|
56132
56875
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
56133
|
-
var WorkspaceGrid =
|
|
56876
|
+
var WorkspaceGrid = React148__default.memo(({
|
|
56134
56877
|
workspaces,
|
|
56135
56878
|
blueComparisonWorkspaces,
|
|
56136
56879
|
isPdfMode = false,
|
|
@@ -56383,7 +57126,7 @@ var KPICard = ({
|
|
|
56383
57126
|
}) => {
|
|
56384
57127
|
useThemeConfig();
|
|
56385
57128
|
const { formatNumber } = useFormatNumber();
|
|
56386
|
-
const trendInfo =
|
|
57129
|
+
const trendInfo = React148__default.useMemo(() => {
|
|
56387
57130
|
let trendValue = trend || "neutral";
|
|
56388
57131
|
if (change !== void 0 && trend === void 0) {
|
|
56389
57132
|
trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
|
|
@@ -56410,7 +57153,7 @@ var KPICard = ({
|
|
|
56410
57153
|
const shouldShowTrend = !(change === 0 && trend === void 0);
|
|
56411
57154
|
return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
|
|
56412
57155
|
}, [trend, change]);
|
|
56413
|
-
const formattedValue =
|
|
57156
|
+
const formattedValue = React148__default.useMemo(() => {
|
|
56414
57157
|
if (title === "Quality Compliance" && typeof value === "number") {
|
|
56415
57158
|
return value.toFixed(1);
|
|
56416
57159
|
}
|
|
@@ -56424,7 +57167,7 @@ var KPICard = ({
|
|
|
56424
57167
|
}
|
|
56425
57168
|
return value;
|
|
56426
57169
|
}, [value, title]);
|
|
56427
|
-
const formattedChange =
|
|
57170
|
+
const formattedChange = React148__default.useMemo(() => {
|
|
56428
57171
|
if (change === void 0 || change === 0 && !showZeroChange) return null;
|
|
56429
57172
|
const absChange = Math.abs(change);
|
|
56430
57173
|
return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
|
|
@@ -57931,7 +58674,7 @@ var Breadcrumbs = ({ items }) => {
|
|
|
57931
58674
|
}
|
|
57932
58675
|
}
|
|
57933
58676
|
};
|
|
57934
|
-
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: [
|
|
57935
58678
|
index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
|
|
57936
58679
|
/* @__PURE__ */ jsxs(
|
|
57937
58680
|
"span",
|
|
@@ -59455,7 +60198,7 @@ var AwardBadge = ({
|
|
|
59455
60198
|
}) => {
|
|
59456
60199
|
const styles2 = getBadgeStyles(type);
|
|
59457
60200
|
const Icon2 = CustomIcon || getDefaultIcon(type);
|
|
59458
|
-
const randomDelay =
|
|
60201
|
+
const randomDelay = React148__default.useMemo(() => Math.random() * 2, []);
|
|
59459
60202
|
const floatingAnimation = {
|
|
59460
60203
|
animate: {
|
|
59461
60204
|
y: [0, -10, 0],
|
|
@@ -67824,7 +68567,7 @@ function HomeView({
|
|
|
67824
68567
|
animate: { opacity: 1, scale: 1 },
|
|
67825
68568
|
transition: { duration: 0.3 },
|
|
67826
68569
|
className: "h-full",
|
|
67827
|
-
children:
|
|
68570
|
+
children: React148__default.createElement(WorkspaceGrid, {
|
|
67828
68571
|
workspaces: workspaceMetricsWithBreakState,
|
|
67829
68572
|
blueComparisonWorkspaces: currentBlueComparisonWorkspaceMetrics || workspaceMetricsWithBreakState,
|
|
67830
68573
|
lineNames: mergedLineNames,
|
|
@@ -67857,7 +68600,7 @@ function HomeView({
|
|
|
67857
68600
|
animate: { opacity: 1, scale: 1 },
|
|
67858
68601
|
transition: { duration: 0.3 },
|
|
67859
68602
|
className: "h-full",
|
|
67860
|
-
children:
|
|
68603
|
+
children: React148__default.createElement(WorkspaceGrid, {
|
|
67861
68604
|
workspaces: [],
|
|
67862
68605
|
// Show empty grid while loading
|
|
67863
68606
|
blueComparisonWorkspaces: [],
|
|
@@ -67904,7 +68647,7 @@ function HomeView({
|
|
|
67904
68647
|
contentVariant: "plain"
|
|
67905
68648
|
}
|
|
67906
68649
|
),
|
|
67907
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(
|
|
68650
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: showAllGreenCelebration ? /* @__PURE__ */ jsxs(React148__default.Fragment, { children: [
|
|
67908
68651
|
/* @__PURE__ */ jsx(
|
|
67909
68652
|
motion.div,
|
|
67910
68653
|
{
|
|
@@ -67983,7 +68726,7 @@ function HomeView({
|
|
|
67983
68726
|
"all-green-center-toast"
|
|
67984
68727
|
)
|
|
67985
68728
|
] }, "all-green-celebration") : null }),
|
|
67986
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(
|
|
68729
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: greenStreakMilestoneBanner ? /* @__PURE__ */ jsxs(React148__default.Fragment, { children: [
|
|
67987
68730
|
/* @__PURE__ */ jsx(
|
|
67988
68731
|
motion.div,
|
|
67989
68732
|
{
|
|
@@ -68077,7 +68820,7 @@ function HomeView({
|
|
|
68077
68820
|
}
|
|
68078
68821
|
);
|
|
68079
68822
|
}
|
|
68080
|
-
var AuthenticatedHomeView = withAuth(
|
|
68823
|
+
var AuthenticatedHomeView = withAuth(React148__default.memo(HomeView));
|
|
68081
68824
|
var HomeView_default = HomeView;
|
|
68082
68825
|
function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
68083
68826
|
const {
|
|
@@ -71426,7 +72169,14 @@ var formatSupervisorFirstNames = (supervisors, fallbackSupervisorNames) => {
|
|
|
71426
72169
|
return fallbackFirstNames.length > 0 ? Array.from(new Set(fallbackFirstNames)).join(", ") : "Unassigned";
|
|
71427
72170
|
};
|
|
71428
72171
|
var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Finished", placeholder = "--", onFinished }) => {
|
|
71429
|
-
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
|
+
});
|
|
71430
72180
|
const hasFinishedRef = useRef(false);
|
|
71431
72181
|
useEffect(() => {
|
|
71432
72182
|
hasFinishedRef.current = false;
|
|
@@ -71434,12 +72184,14 @@ var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Fin
|
|
|
71434
72184
|
useEffect(() => {
|
|
71435
72185
|
if (!targetDate) {
|
|
71436
72186
|
setTime(placeholder);
|
|
72187
|
+
setShowEndsInPrefix(true);
|
|
71437
72188
|
return;
|
|
71438
72189
|
}
|
|
71439
72190
|
const tick = () => {
|
|
71440
72191
|
const now4 = /* @__PURE__ */ new Date();
|
|
71441
72192
|
const diff = targetDate.getTime() - now4.getTime();
|
|
71442
72193
|
if (diff <= 0) {
|
|
72194
|
+
setShowEndsInPrefix(false);
|
|
71443
72195
|
setTime(finishedLabel);
|
|
71444
72196
|
if (!hasFinishedRef.current && onFinished) {
|
|
71445
72197
|
hasFinishedRef.current = true;
|
|
@@ -71447,6 +72199,7 @@ var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Fin
|
|
|
71447
72199
|
}
|
|
71448
72200
|
return;
|
|
71449
72201
|
}
|
|
72202
|
+
setShowEndsInPrefix(true);
|
|
71450
72203
|
if (format10 === "days") {
|
|
71451
72204
|
const days = Math.floor(diff / (1e3 * 60 * 60 * 24));
|
|
71452
72205
|
const hours = Math.floor(diff % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60));
|
|
@@ -71463,7 +72216,10 @@ var LeaderboardCountdown = ({ targetDate, format: format10, finishedLabel = "Fin
|
|
|
71463
72216
|
const interval = setInterval(tick, 1e3);
|
|
71464
72217
|
return () => clearInterval(interval);
|
|
71465
72218
|
}, [targetDate, format10, finishedLabel, placeholder, onFinished]);
|
|
71466
|
-
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
|
+
] });
|
|
71467
72223
|
};
|
|
71468
72224
|
var LinesLeaderboard = ({
|
|
71469
72225
|
lines,
|
|
@@ -71486,18 +72242,18 @@ var LinesLeaderboard = ({
|
|
|
71486
72242
|
isHistoricalDaily
|
|
71487
72243
|
}) => {
|
|
71488
72244
|
const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
|
|
71489
|
-
const assignedLineIdSet =
|
|
72245
|
+
const assignedLineIdSet = React148__default.useMemo(
|
|
71490
72246
|
() => new Set(assignedLineIds || []),
|
|
71491
72247
|
[assignedLineIds]
|
|
71492
72248
|
);
|
|
71493
|
-
const canClickLine =
|
|
72249
|
+
const canClickLine = React148__default.useCallback(
|
|
71494
72250
|
(lineId) => {
|
|
71495
72251
|
if (!assignedLineIds) return true;
|
|
71496
72252
|
return assignedLineIdSet.has(lineId);
|
|
71497
72253
|
},
|
|
71498
72254
|
[assignedLineIds, assignedLineIdSet]
|
|
71499
72255
|
);
|
|
71500
|
-
const handleTimeRangeChange =
|
|
72256
|
+
const handleTimeRangeChange = React148__default.useCallback((newRange) => {
|
|
71501
72257
|
if (newRange === timeRange) return;
|
|
71502
72258
|
trackCoreEvent("Leaderboard Time Range Changed", {
|
|
71503
72259
|
from_range: timeRange,
|
|
@@ -71508,11 +72264,11 @@ var LinesLeaderboard = ({
|
|
|
71508
72264
|
});
|
|
71509
72265
|
setTimeRange(newRange);
|
|
71510
72266
|
}, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
|
|
71511
|
-
const canClickLeaderboardRow =
|
|
72267
|
+
const canClickLeaderboardRow = React148__default.useCallback(
|
|
71512
72268
|
(item) => item.rowType === "line" && !!item.line && canClickLine(item.line.id),
|
|
71513
72269
|
[canClickLine]
|
|
71514
72270
|
);
|
|
71515
|
-
const handleLeaderboardLineClick =
|
|
72271
|
+
const handleLeaderboardLineClick = React148__default.useCallback((item, clickSource) => {
|
|
71516
72272
|
if (!canClickLeaderboardRow(item) || !item.line) return;
|
|
71517
72273
|
trackCoreEvent("Leaderboard Line Clicked", {
|
|
71518
72274
|
line_id: item.line.id,
|
|
@@ -71526,8 +72282,8 @@ var LinesLeaderboard = ({
|
|
|
71526
72282
|
});
|
|
71527
72283
|
onLineClick(item.line);
|
|
71528
72284
|
}, [canClickLeaderboardRow, onLineClick, timeRange]);
|
|
71529
|
-
const viewLoadedTrackedRef =
|
|
71530
|
-
const leaderboardData =
|
|
72285
|
+
const viewLoadedTrackedRef = React148__default.useRef(null);
|
|
72286
|
+
const leaderboardData = React148__default.useMemo(() => {
|
|
71531
72287
|
const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
71532
72288
|
const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
|
|
71533
72289
|
const fallbackEfficiencyMap = timeRange === "today" ? dailyFallbackEfficiencyByLineId : void 0;
|
|
@@ -71571,7 +72327,7 @@ var LinesLeaderboard = ({
|
|
|
71571
72327
|
isLoadingToday,
|
|
71572
72328
|
isLoadingMonthly
|
|
71573
72329
|
]);
|
|
71574
|
-
|
|
72330
|
+
React148__default.useEffect(() => {
|
|
71575
72331
|
const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
71576
72332
|
const trackingKey = `${timeRange}-${leaderboardData.length}`;
|
|
71577
72333
|
if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
|
|
@@ -71595,9 +72351,9 @@ var LinesLeaderboard = ({
|
|
|
71595
72351
|
const topThree = leaderboardData.slice(0, 3);
|
|
71596
72352
|
const countdownTarget = timeRange === "monthly" ? monthEndDate : shiftEndDate;
|
|
71597
72353
|
const countdownFormat = timeRange === "monthly" ? "days" : "clock";
|
|
71598
|
-
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift
|
|
72354
|
+
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift ended";
|
|
71599
72355
|
const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
|
|
71600
|
-
const handleCountdownFinished =
|
|
72356
|
+
const handleCountdownFinished = React148__default.useCallback(() => {
|
|
71601
72357
|
trackCoreEvent("Leaderboard Countdown Finished", {
|
|
71602
72358
|
countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
|
|
71603
72359
|
time_range: timeRange,
|
|
@@ -71624,7 +72380,7 @@ var LinesLeaderboard = ({
|
|
|
71624
72380
|
return "bg-white border-gray-100";
|
|
71625
72381
|
}
|
|
71626
72382
|
};
|
|
71627
|
-
|
|
72383
|
+
React148__default.useEffect(() => {
|
|
71628
72384
|
const style = document.createElement("style");
|
|
71629
72385
|
style.innerHTML = `
|
|
71630
72386
|
@keyframes float {
|
|
@@ -71672,19 +72428,16 @@ var LinesLeaderboard = ({
|
|
|
71672
72428
|
] }),
|
|
71673
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: [
|
|
71674
72430
|
/* @__PURE__ */ jsx(Clock, { className: "w-4 h-4 text-orange-500" }),
|
|
71675
|
-
/* @__PURE__ */
|
|
71676
|
-
|
|
71677
|
-
|
|
71678
|
-
|
|
71679
|
-
|
|
71680
|
-
|
|
71681
|
-
|
|
71682
|
-
|
|
71683
|
-
|
|
71684
|
-
|
|
71685
|
-
}
|
|
71686
|
-
) })
|
|
71687
|
-
] })
|
|
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
|
+
) })
|
|
71688
72441
|
] }) })
|
|
71689
72442
|
] }),
|
|
71690
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) => {
|
|
@@ -72126,36 +72879,36 @@ var KPIsOverviewView = ({
|
|
|
72126
72879
|
const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
|
|
72127
72880
|
const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
|
|
72128
72881
|
const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
|
|
72129
|
-
const scopedLineIds =
|
|
72882
|
+
const scopedLineIds = React148__default.useMemo(
|
|
72130
72883
|
() => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
|
|
72131
72884
|
[user?.access_scope?.line_ids]
|
|
72132
72885
|
);
|
|
72133
72886
|
const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
|
|
72134
72887
|
const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
|
|
72135
72888
|
const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
|
|
72136
|
-
const resolvedAssignedLineIds =
|
|
72889
|
+
const resolvedAssignedLineIds = React148__default.useMemo(() => {
|
|
72137
72890
|
if (isSuperAdmin) return [];
|
|
72138
72891
|
if (scopedLineIds.length > 0) return scopedLineIds;
|
|
72139
72892
|
if (lineIds && lineIds.length > 0) return lineIds;
|
|
72140
72893
|
if (isStrictLineScopedRole && hasCanonicalScope) return [];
|
|
72141
72894
|
return [];
|
|
72142
72895
|
}, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
|
|
72143
|
-
const assignedLineIdSet =
|
|
72896
|
+
const assignedLineIdSet = React148__default.useMemo(
|
|
72144
72897
|
() => new Set(resolvedAssignedLineIds),
|
|
72145
72898
|
[resolvedAssignedLineIds]
|
|
72146
72899
|
);
|
|
72147
|
-
const loadedLineIds =
|
|
72900
|
+
const loadedLineIds = React148__default.useMemo(
|
|
72148
72901
|
() => lines.map((line) => line.id).filter(Boolean),
|
|
72149
72902
|
[lines]
|
|
72150
72903
|
);
|
|
72151
|
-
const metricsLineIds =
|
|
72904
|
+
const metricsLineIds = React148__default.useMemo(() => {
|
|
72152
72905
|
if (isSuperAdmin) {
|
|
72153
72906
|
return loadedLineIds.length > 0 ? loadedLineIds : lineIds ?? [];
|
|
72154
72907
|
}
|
|
72155
72908
|
return resolvedAssignedLineIds;
|
|
72156
72909
|
}, [isSuperAdmin, loadedLineIds, lineIds, resolvedAssignedLineIds]);
|
|
72157
72910
|
const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
|
|
72158
|
-
const leaderboardLinesForView =
|
|
72911
|
+
const leaderboardLinesForView = React148__default.useMemo(() => {
|
|
72159
72912
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
72160
72913
|
const metadataByLineId = new Map(lines.map((line) => [line.id, line]));
|
|
72161
72914
|
return leaderboardLines.map((line) => {
|
|
@@ -72174,17 +72927,17 @@ var KPIsOverviewView = ({
|
|
|
72174
72927
|
} : line;
|
|
72175
72928
|
}).filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
72176
72929
|
}, [leaderboardLines, lines, viewType]);
|
|
72177
|
-
const linesForView =
|
|
72930
|
+
const linesForView = React148__default.useMemo(() => {
|
|
72178
72931
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
72179
72932
|
return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
72180
72933
|
}, [lines, viewType]);
|
|
72181
|
-
const relevantLinesForMode =
|
|
72934
|
+
const relevantLinesForMode = React148__default.useMemo(() => {
|
|
72182
72935
|
if (activeTab === "leaderboard") {
|
|
72183
72936
|
return leaderboardLines.length > 0 ? leaderboardLines : lines;
|
|
72184
72937
|
}
|
|
72185
72938
|
return lines;
|
|
72186
72939
|
}, [activeTab, leaderboardLines, lines]);
|
|
72187
|
-
const { hasUptime, hasOutput } =
|
|
72940
|
+
const { hasUptime, hasOutput } = React148__default.useMemo(() => {
|
|
72188
72941
|
let uptime = false;
|
|
72189
72942
|
let output = false;
|
|
72190
72943
|
for (const line of relevantLinesForMode) {
|
|
@@ -72209,14 +72962,14 @@ var KPIsOverviewView = ({
|
|
|
72209
72962
|
const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
|
|
72210
72963
|
const currentShiftDate = currentShiftDetails.date;
|
|
72211
72964
|
const currentShiftId = currentShiftDetails.shiftId;
|
|
72212
|
-
const activeFiltersCount =
|
|
72965
|
+
const activeFiltersCount = React148__default.useMemo(() => {
|
|
72213
72966
|
let count = 0;
|
|
72214
72967
|
if (leaderboardDailyScopeMode === "historical" && selectedLeaderboardShiftId !== currentShiftId) {
|
|
72215
72968
|
count++;
|
|
72216
72969
|
}
|
|
72217
72970
|
return count;
|
|
72218
72971
|
}, [leaderboardDailyScopeMode, selectedLeaderboardShiftId, currentShiftId]);
|
|
72219
|
-
const clearFilters =
|
|
72972
|
+
const clearFilters = React148__default.useCallback(() => {
|
|
72220
72973
|
setSelectedLeaderboardShiftId(currentShiftId);
|
|
72221
72974
|
setSelectedLeaderboardDate(currentShiftDate);
|
|
72222
72975
|
setLeaderboardDailyScopeMode("live");
|
|
@@ -72232,11 +72985,11 @@ var KPIsOverviewView = ({
|
|
|
72232
72985
|
document.addEventListener("mousedown", handleClickOutside);
|
|
72233
72986
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
72234
72987
|
}, []);
|
|
72235
|
-
const shiftEndDate =
|
|
72988
|
+
const shiftEndDate = React148__default.useMemo(
|
|
72236
72989
|
() => getShiftEndDate(currentShiftDetails, configuredTimezone),
|
|
72237
72990
|
[currentShiftDetails, configuredTimezone]
|
|
72238
72991
|
);
|
|
72239
|
-
const leaderboardShiftOptions =
|
|
72992
|
+
const leaderboardShiftOptions = React148__default.useMemo(() => {
|
|
72240
72993
|
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
72241
72994
|
return shiftConfig.shifts.map((shift) => ({
|
|
72242
72995
|
id: shift.shiftId,
|
|
@@ -72253,34 +73006,34 @@ var KPIsOverviewView = ({
|
|
|
72253
73006
|
const effectiveLeaderboardDate = selectedLeaderboardDate || currentShiftDate;
|
|
72254
73007
|
const effectiveLeaderboardShiftId = Number.isFinite(selectedLeaderboardShiftId) ? selectedLeaderboardShiftId : currentShiftId;
|
|
72255
73008
|
const isHistoricalLeaderboardDaily = activeTab === "leaderboard" && timeRange === "today" && leaderboardDailyScopeMode === "historical" && (effectiveLeaderboardDate !== currentShiftDate || effectiveLeaderboardShiftId !== currentShiftId);
|
|
72256
|
-
const updateLeaderboardDate =
|
|
73009
|
+
const updateLeaderboardDate = React148__default.useCallback((dateKey) => {
|
|
72257
73010
|
setSelectedLeaderboardDate(dateKey);
|
|
72258
73011
|
setLeaderboardDailyScopeMode(
|
|
72259
73012
|
dateKey === currentShiftDate && effectiveLeaderboardShiftId === currentShiftId ? "live" : "historical"
|
|
72260
73013
|
);
|
|
72261
73014
|
}, [currentShiftDate, currentShiftId, effectiveLeaderboardShiftId]);
|
|
72262
|
-
const updateLeaderboardShiftId =
|
|
73015
|
+
const updateLeaderboardShiftId = React148__default.useCallback((shiftId) => {
|
|
72263
73016
|
setSelectedLeaderboardShiftId(shiftId);
|
|
72264
73017
|
setLeaderboardDailyScopeMode(
|
|
72265
73018
|
effectiveLeaderboardDate === currentShiftDate && shiftId === currentShiftId ? "live" : "historical"
|
|
72266
73019
|
);
|
|
72267
73020
|
}, [currentShiftDate, currentShiftId, effectiveLeaderboardDate]);
|
|
72268
|
-
const returnLeaderboardToLive =
|
|
73021
|
+
const returnLeaderboardToLive = React148__default.useCallback(() => {
|
|
72269
73022
|
setSelectedLeaderboardDate(currentShiftDate);
|
|
72270
73023
|
setSelectedLeaderboardShiftId(currentShiftId);
|
|
72271
73024
|
setLeaderboardDailyScopeMode("live");
|
|
72272
73025
|
}, [currentShiftDate, currentShiftId]);
|
|
72273
73026
|
const selectedFactoryIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_QUERY_PARAM]);
|
|
72274
73027
|
const selectedFactoryAreaIdFromUrl = getSingleQueryValue(router.query[KPI_FACTORY_AREA_QUERY_PARAM]);
|
|
72275
|
-
const kpiLineHierarchy =
|
|
73028
|
+
const kpiLineHierarchy = React148__default.useMemo(
|
|
72276
73029
|
() => buildKpiLineHierarchy(linesForView),
|
|
72277
73030
|
[linesForView]
|
|
72278
73031
|
);
|
|
72279
|
-
const selectedFactoryNode =
|
|
73032
|
+
const selectedFactoryNode = React148__default.useMemo(
|
|
72280
73033
|
() => kpiLineHierarchy.showFactoryLevel && selectedFactoryIdFromUrl ? kpiLineHierarchy.factories.find((factory) => factory.id === selectedFactoryIdFromUrl) : void 0,
|
|
72281
73034
|
[kpiLineHierarchy, selectedFactoryIdFromUrl]
|
|
72282
73035
|
);
|
|
72283
|
-
const selectedFactoryAreaNode =
|
|
73036
|
+
const selectedFactoryAreaNode = React148__default.useMemo(
|
|
72284
73037
|
() => selectedFactoryNode && selectedFactoryAreaIdFromUrl ? selectedFactoryNode.areas.find((area) => area.id === selectedFactoryAreaIdFromUrl) : void 0,
|
|
72285
73038
|
[selectedFactoryNode, selectedFactoryAreaIdFromUrl]
|
|
72286
73039
|
);
|
|
@@ -72369,15 +73122,15 @@ var KPIsOverviewView = ({
|
|
|
72369
73122
|
lineId: factoryViewId,
|
|
72370
73123
|
userAccessibleLineIds: metricsLineIds
|
|
72371
73124
|
});
|
|
72372
|
-
const defaultKPIs =
|
|
72373
|
-
const lineModeById =
|
|
73125
|
+
const defaultKPIs = React148__default.useMemo(() => createDefaultKPIs(), []);
|
|
73126
|
+
const lineModeById = React148__default.useMemo(() => {
|
|
72374
73127
|
const map = /* @__PURE__ */ new Map();
|
|
72375
73128
|
linesForView.forEach((line) => {
|
|
72376
73129
|
map.set(line.id, line.monitoring_mode ?? "output");
|
|
72377
73130
|
});
|
|
72378
73131
|
return map;
|
|
72379
73132
|
}, [linesForView]);
|
|
72380
|
-
const lineMetricRowsByLineId =
|
|
73133
|
+
const lineMetricRowsByLineId = React148__default.useMemo(() => {
|
|
72381
73134
|
const map = /* @__PURE__ */ new Map();
|
|
72382
73135
|
lineMetrics.forEach((row) => {
|
|
72383
73136
|
if (!row?.line_id) return;
|
|
@@ -72389,7 +73142,7 @@ var KPIsOverviewView = ({
|
|
|
72389
73142
|
});
|
|
72390
73143
|
return map;
|
|
72391
73144
|
}, [lineMetrics, lineModeById]);
|
|
72392
|
-
const liveDailyFallbackEfficiencyByLineId =
|
|
73145
|
+
const liveDailyFallbackEfficiencyByLineId = React148__default.useMemo(() => {
|
|
72393
73146
|
const map = /* @__PURE__ */ new Map();
|
|
72394
73147
|
lineMetricRowsByLineId.forEach((row, lineId) => {
|
|
72395
73148
|
const value = Number(row?.avg_efficiency);
|
|
@@ -72411,31 +73164,31 @@ var KPIsOverviewView = ({
|
|
|
72411
73164
|
isHistoricalLeaderboardDaily,
|
|
72412
73165
|
lineMetricRowsByLineId
|
|
72413
73166
|
]);
|
|
72414
|
-
const dailyFallbackEfficiencyByLineId =
|
|
73167
|
+
const dailyFallbackEfficiencyByLineId = React148__default.useMemo(() => {
|
|
72415
73168
|
const map = new Map(liveDailyFallbackEfficiencyByLineId);
|
|
72416
73169
|
scopedDailyFallbackEfficiencyByLineId.forEach((value, lineId) => {
|
|
72417
73170
|
map.set(lineId, value);
|
|
72418
73171
|
});
|
|
72419
73172
|
return map;
|
|
72420
73173
|
}, [liveDailyFallbackEfficiencyByLineId, scopedDailyFallbackEfficiencyByLineId]);
|
|
72421
|
-
const kpisByLineId =
|
|
73174
|
+
const kpisByLineId = React148__default.useMemo(() => {
|
|
72422
73175
|
const map = /* @__PURE__ */ new Map();
|
|
72423
73176
|
lineMetricRowsByLineId.forEach((row, lineId) => {
|
|
72424
73177
|
map.set(lineId, buildKPIsFromLineMetricsRow(row));
|
|
72425
73178
|
});
|
|
72426
73179
|
return map;
|
|
72427
73180
|
}, [lineMetricRowsByLineId]);
|
|
72428
|
-
const getLineCardKpis =
|
|
73181
|
+
const getLineCardKpis = React148__default.useCallback((line) => {
|
|
72429
73182
|
if (metricsError) return null;
|
|
72430
73183
|
return kpisByLineId.get(line.id) ?? (metricsLoading ? null : defaultKPIs);
|
|
72431
73184
|
}, [defaultKPIs, kpisByLineId, metricsError, metricsLoading]);
|
|
72432
|
-
const getAggregateCardKpis =
|
|
73185
|
+
const getAggregateCardKpis = React148__default.useCallback((cardLines) => {
|
|
72433
73186
|
if (metricsError) return null;
|
|
72434
73187
|
const rows = cardLines.map((line) => lineMetricRowsByLineId.get(line.id)).filter(Boolean);
|
|
72435
73188
|
if (metricsLoading && rows.length === 0) return null;
|
|
72436
73189
|
return aggregateKPIsFromLineMetricsRows(rows);
|
|
72437
73190
|
}, [lineMetricRowsByLineId, metricsError, metricsLoading]);
|
|
72438
|
-
const supervisorLineIds =
|
|
73191
|
+
const supervisorLineIds = React148__default.useMemo(
|
|
72439
73192
|
() => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
|
|
72440
73193
|
[leaderboardLines, lines]
|
|
72441
73194
|
);
|
|
@@ -72687,7 +73440,7 @@ var KPIsOverviewView = ({
|
|
|
72687
73440
|
{ shallow: true }
|
|
72688
73441
|
);
|
|
72689
73442
|
}, [router]);
|
|
72690
|
-
const lineDetailReturnTo =
|
|
73443
|
+
const lineDetailReturnTo = React148__default.useMemo(() => {
|
|
72691
73444
|
if (activeTab !== "today" || !selectedFactoryNode) return void 0;
|
|
72692
73445
|
return createKpisOverviewUrl({
|
|
72693
73446
|
factoryId: selectedFactoryNode.id,
|
|
@@ -73487,7 +74240,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
73487
74240
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
73488
74241
|
}, []);
|
|
73489
74242
|
const [isMobile, setIsMobile] = useState(false);
|
|
73490
|
-
|
|
74243
|
+
React148__default.useEffect(() => {
|
|
73491
74244
|
const checkMobile = () => setIsMobile(window.innerWidth < 640);
|
|
73492
74245
|
checkMobile();
|
|
73493
74246
|
window.addEventListener("resize", checkMobile);
|
|
@@ -77537,7 +78290,7 @@ var ShiftsView = ({
|
|
|
77537
78290
|
] })
|
|
77538
78291
|
] });
|
|
77539
78292
|
};
|
|
77540
|
-
var AuthenticatedShiftsView = withAuth(
|
|
78293
|
+
var AuthenticatedShiftsView = withAuth(React148__default.memo(ShiftsView));
|
|
77541
78294
|
var ShiftsView_default = ShiftsView;
|
|
77542
78295
|
|
|
77543
78296
|
// src/views/TargetsView.utils.ts
|
|
@@ -79404,7 +80157,7 @@ var TargetsView = ({
|
|
|
79404
80157
|
};
|
|
79405
80158
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
79406
80159
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
79407
|
-
var AuthenticatedTargetsView = withAuth(
|
|
80160
|
+
var AuthenticatedTargetsView = withAuth(React148__default.memo(TargetsViewWithDisplayNames));
|
|
79408
80161
|
function useTimezone(options = {}) {
|
|
79409
80162
|
const dashboardConfig = useDashboardConfig();
|
|
79410
80163
|
const workspaceConfig = useWorkspaceConfig();
|
|
@@ -79552,7 +80305,7 @@ var formatWholeNumber = (value) => {
|
|
|
79552
80305
|
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
79553
80306
|
return Math.round(value).toLocaleString();
|
|
79554
80307
|
};
|
|
79555
|
-
var
|
|
80308
|
+
var formatSeconds2 = (value) => {
|
|
79556
80309
|
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
79557
80310
|
return `${value.toFixed(1)}s`;
|
|
79558
80311
|
};
|
|
@@ -79569,13 +80322,13 @@ var WorkspaceHourSummaryPanel = ({
|
|
|
79569
80322
|
}) => {
|
|
79570
80323
|
const { data, isLoading, error, summarize, reset } = useWorkspaceHourSummary();
|
|
79571
80324
|
const selectedKey = selectedHour ? `${selectedHour.source}:${selectedHour.hourIndex}:${date}:${shiftId}` : "none";
|
|
79572
|
-
const autoSummaryKeyRef =
|
|
79573
|
-
|
|
80325
|
+
const autoSummaryKeyRef = React148__default.useRef(null);
|
|
80326
|
+
React148__default.useEffect(() => {
|
|
79574
80327
|
reset();
|
|
79575
80328
|
autoSummaryKeyRef.current = null;
|
|
79576
80329
|
}, [reset, selectedKey]);
|
|
79577
80330
|
const canSummarize = Boolean(workspaceId && companyId && date && shiftId !== null && shiftId !== void 0);
|
|
79578
|
-
|
|
80331
|
+
React148__default.useEffect(() => {
|
|
79579
80332
|
if (!selectedHour || !canSummarize || !companyId || !date || shiftId === null || shiftId === void 0) {
|
|
79580
80333
|
return;
|
|
79581
80334
|
}
|
|
@@ -79604,8 +80357,8 @@ var WorkspaceHourSummaryPanel = ({
|
|
|
79604
80357
|
const formattedTimeRange = formatTimeRangeTo12Hour(verifiedTimeRange);
|
|
79605
80358
|
const selectedMetric = selectedHour.source === "cycle" ? {
|
|
79606
80359
|
label: "Cycle time",
|
|
79607
|
-
actual:
|
|
79608
|
-
standard:
|
|
80360
|
+
actual: formatSeconds2(selectedHour.cycleTime),
|
|
80361
|
+
standard: formatSeconds2(selectedHour.idealCycleTime)
|
|
79609
80362
|
} : {
|
|
79610
80363
|
label: "Hourly output",
|
|
79611
80364
|
actual: formatWholeNumber(selectedHour.output),
|
|
@@ -79781,6 +80534,7 @@ var WorkspaceDetailView = ({
|
|
|
79781
80534
|
const { legend: efficiencyLegend } = useEfficiencyLegend();
|
|
79782
80535
|
const prewarmedClipsRef = useRef(/* @__PURE__ */ new Set());
|
|
79783
80536
|
const prewarmInFlightRef = useRef(/* @__PURE__ */ new Set());
|
|
80537
|
+
const [lowMomentsPrefetch, setLowMomentsPrefetch] = useState(null);
|
|
79784
80538
|
const [aiSummaryHour, setAiSummaryHour] = useState(null);
|
|
79785
80539
|
const buildHourlyOutputActionTrackingProps = useCallback((payload) => ({
|
|
79786
80540
|
workspace_id: workspaceId,
|
|
@@ -80184,6 +80938,8 @@ var WorkspaceDetailView = ({
|
|
|
80184
80938
|
[workspace?.sku_segments]
|
|
80185
80939
|
);
|
|
80186
80940
|
const activeSkuId = selectedSkuId;
|
|
80941
|
+
const shouldUseLiveSkuForMetricCards = !isHistoricView || Boolean(date) && date === calculatedOperationalDate && parsedShiftId !== void 0 && parsedShiftId === calculatedShiftId;
|
|
80942
|
+
const metricCardLiveSkuId = shouldUseLiveSkuForMetricCards ? liveSkuId : null;
|
|
80187
80943
|
const resolvedLineId = effectiveLineId || workspace?.line_id || cachedDetailedMetrics?.line_id || cachedOverviewMetrics?.line_id || overviewFallback?.line_id;
|
|
80188
80944
|
const { timezone: cycleTimeTimezone } = useTimezone({
|
|
80189
80945
|
lineId: resolvedLineId || void 0,
|
|
@@ -80291,13 +81047,108 @@ var WorkspaceDetailView = ({
|
|
|
80291
81047
|
}
|
|
80292
81048
|
prewarmInFlightRef.current.add(cacheKey);
|
|
80293
81049
|
const s3Service = videoPrefetchManager.getS3Service(dashboardConfig);
|
|
80294
|
-
|
|
80295
|
-
|
|
80296
|
-
|
|
80297
|
-
|
|
80298
|
-
|
|
80299
|
-
|
|
80300
|
-
|
|
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
|
+
};
|
|
80301
81152
|
}, [
|
|
80302
81153
|
isClipsEnabled,
|
|
80303
81154
|
dashboardConfig,
|
|
@@ -80307,7 +81158,8 @@ var WorkspaceDetailView = ({
|
|
|
80307
81158
|
isShiftConfigLoading,
|
|
80308
81159
|
shiftConfig,
|
|
80309
81160
|
timezone,
|
|
80310
|
-
workspace
|
|
81161
|
+
workspace,
|
|
81162
|
+
supabase
|
|
80311
81163
|
]);
|
|
80312
81164
|
const { supervisorName, supervisors } = useLineSupervisor(workspace?.line_id || lineId);
|
|
80313
81165
|
useEffect(() => {
|
|
@@ -81256,7 +82108,7 @@ var WorkspaceDetailView = ({
|
|
|
81256
82108
|
skuAware: isSkuAware,
|
|
81257
82109
|
skuBreakdown: isSkuAware ? realSkuBreakdown : void 0,
|
|
81258
82110
|
activeSkuId,
|
|
81259
|
-
liveSkuId:
|
|
82111
|
+
liveSkuId: metricCardLiveSkuId
|
|
81260
82112
|
}
|
|
81261
82113
|
) : /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
81262
82114
|
WorkspaceMetricCards,
|
|
@@ -81267,7 +82119,7 @@ var WorkspaceDetailView = ({
|
|
|
81267
82119
|
skuAware: isSkuAware,
|
|
81268
82120
|
skuBreakdown: isSkuAware ? realSkuBreakdown : void 0,
|
|
81269
82121
|
activeSkuId,
|
|
81270
|
-
liveSkuId:
|
|
82122
|
+
liveSkuId: metricCardLiveSkuId
|
|
81271
82123
|
}
|
|
81272
82124
|
) })
|
|
81273
82125
|
] }),
|
|
@@ -81438,7 +82290,7 @@ var WorkspaceDetailView = ({
|
|
|
81438
82290
|
skuAware: isSkuAware,
|
|
81439
82291
|
skuBreakdown: isSkuAware ? realSkuBreakdown : void 0,
|
|
81440
82292
|
activeSkuId,
|
|
81441
|
-
liveSkuId:
|
|
82293
|
+
liveSkuId: metricCardLiveSkuId
|
|
81442
82294
|
}
|
|
81443
82295
|
) : /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(
|
|
81444
82296
|
WorkspaceMetricCards,
|
|
@@ -81449,7 +82301,7 @@ var WorkspaceDetailView = ({
|
|
|
81449
82301
|
skuAware: isSkuAware,
|
|
81450
82302
|
skuBreakdown: isSkuAware ? realSkuBreakdown : void 0,
|
|
81451
82303
|
activeSkuId,
|
|
81452
|
-
liveSkuId:
|
|
82304
|
+
liveSkuId: metricCardLiveSkuId
|
|
81453
82305
|
}
|
|
81454
82306
|
) })
|
|
81455
82307
|
] })
|
|
@@ -81526,6 +82378,7 @@ var WorkspaceDetailView = ({
|
|
|
81526
82378
|
totalOutput: workspace?.total_actions,
|
|
81527
82379
|
workspaceMetrics: detailedWorkspaceMetrics || void 0,
|
|
81528
82380
|
prefetchedPercentileCounts: isFastSlowClipFiltersEnabled ? prefetchedPercentileCounts : null,
|
|
82381
|
+
lowMomentsPrefetch,
|
|
81529
82382
|
initialTimeFilter: pendingClipHourFilter,
|
|
81530
82383
|
className: "h-[calc(100vh-10rem)]"
|
|
81531
82384
|
}
|
|
@@ -83164,7 +84017,7 @@ function BottleneckClipsView({
|
|
|
83164
84017
|
) })
|
|
83165
84018
|
] }) });
|
|
83166
84019
|
}
|
|
83167
|
-
var AuthenticatedBottleneckClipsView = withAuth(
|
|
84020
|
+
var AuthenticatedBottleneckClipsView = withAuth(React148__default.memo(BottleneckClipsView));
|
|
83168
84021
|
var BottleneckClipsView_default = BottleneckClipsView;
|
|
83169
84022
|
|
|
83170
84023
|
// src/lib/services/ticketService.ts
|
|
@@ -84007,7 +84860,7 @@ Please ensure:
|
|
|
84007
84860
|
)
|
|
84008
84861
|
] });
|
|
84009
84862
|
}
|
|
84010
|
-
var AuthenticatedTicketsView = withAuth(
|
|
84863
|
+
var AuthenticatedTicketsView = withAuth(React148__default.memo(TicketsView));
|
|
84011
84864
|
var TicketsView_default = TicketsView;
|
|
84012
84865
|
|
|
84013
84866
|
// src/lib/utils/improvementDisplay.ts
|
|
@@ -84978,7 +85831,7 @@ var ImprovementCenterView = () => {
|
|
|
84978
85831
|
setSelectedMemberId("all");
|
|
84979
85832
|
}
|
|
84980
85833
|
}, [memberOptions, selectedMemberId]);
|
|
84981
|
-
const getRecommendationDisplayMetadata =
|
|
85834
|
+
const getRecommendationDisplayMetadata = React148__default.useCallback((rec) => {
|
|
84982
85835
|
const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
|
|
84983
85836
|
return getImprovementDisplayMetadata({
|
|
84984
85837
|
location: rec.location,
|
|
@@ -85452,7 +86305,7 @@ var ThreadSidebar = ({
|
|
|
85452
86305
|
] }) })
|
|
85453
86306
|
] });
|
|
85454
86307
|
};
|
|
85455
|
-
var ProfilePicture =
|
|
86308
|
+
var ProfilePicture = React148__default.memo(({
|
|
85456
86309
|
alt = "Axel",
|
|
85457
86310
|
className = "",
|
|
85458
86311
|
size = "md",
|
|
@@ -88012,7 +88865,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
|
|
|
88012
88865
|
] }),
|
|
88013
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" }) })
|
|
88014
88867
|
] }, index)) });
|
|
88015
|
-
var OperationsOverviewHeader =
|
|
88868
|
+
var OperationsOverviewHeader = React148__default.memo(({
|
|
88016
88869
|
dateRange,
|
|
88017
88870
|
displayDateRange,
|
|
88018
88871
|
trendMode,
|
|
@@ -88033,65 +88886,65 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88033
88886
|
bumpRenderCounter();
|
|
88034
88887
|
const subtitleRange = displayDateRange || dateRange;
|
|
88035
88888
|
const showLiveShiftMeta = isLiveScope && trendMode !== "all";
|
|
88036
|
-
const liveShiftLabel =
|
|
88889
|
+
const liveShiftLabel = React148__default.useMemo(
|
|
88037
88890
|
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
88038
88891
|
[liveShiftName, trendMode]
|
|
88039
88892
|
);
|
|
88040
|
-
const liveShiftIcon =
|
|
88893
|
+
const liveShiftIcon = React148__default.useMemo(
|
|
88041
88894
|
() => getShiftIcon(liveShiftName, trendMode),
|
|
88042
88895
|
[liveShiftName, trendMode]
|
|
88043
88896
|
);
|
|
88044
|
-
const [isFilterOpen, setIsFilterOpen] =
|
|
88045
|
-
const [isLinesDropdownOpen, setIsLinesDropdownOpen] =
|
|
88046
|
-
const filterRef =
|
|
88047
|
-
const filterButtonRef =
|
|
88048
|
-
const mobileFilterButtonRef =
|
|
88049
|
-
const linesDropdownRef =
|
|
88050
|
-
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(() => {
|
|
88051
88904
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
88052
88905
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
|
|
88053
88906
|
}
|
|
88054
88907
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
|
|
88055
88908
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
88056
|
-
const desktopSubtitle =
|
|
88909
|
+
const desktopSubtitle = React148__default.useMemo(() => {
|
|
88057
88910
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
88058
88911
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
|
|
88059
88912
|
}
|
|
88060
88913
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
|
|
88061
88914
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
88062
|
-
const availableLineIds =
|
|
88915
|
+
const availableLineIds = React148__default.useMemo(
|
|
88063
88916
|
() => lineOptions.map((line) => line.id),
|
|
88064
88917
|
[lineOptions]
|
|
88065
88918
|
);
|
|
88066
|
-
const selectedLineIdSet =
|
|
88919
|
+
const selectedLineIdSet = React148__default.useMemo(
|
|
88067
88920
|
() => new Set(selectedLineIds),
|
|
88068
88921
|
[selectedLineIds]
|
|
88069
88922
|
);
|
|
88070
|
-
const isAllLinesSelected =
|
|
88923
|
+
const isAllLinesSelected = React148__default.useMemo(() => {
|
|
88071
88924
|
if (availableLineIds.length === 0) return true;
|
|
88072
88925
|
return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
|
|
88073
88926
|
}, [availableLineIds, selectedLineIdSet]);
|
|
88074
|
-
const activeFilterCount =
|
|
88927
|
+
const activeFilterCount = React148__default.useMemo(() => {
|
|
88075
88928
|
let count = 0;
|
|
88076
88929
|
if (trendMode !== "all") count += 1;
|
|
88077
88930
|
if (selectedSupervisorId !== "all") count += 1;
|
|
88078
88931
|
if (!isAllLinesSelected) count += 1;
|
|
88079
88932
|
return count;
|
|
88080
88933
|
}, [isAllLinesSelected, selectedSupervisorId, trendMode]);
|
|
88081
|
-
const handleFilterToggle =
|
|
88934
|
+
const handleFilterToggle = React148__default.useCallback(() => {
|
|
88082
88935
|
trackCoreEvent("Operations Overview Filter Toggled", {
|
|
88083
88936
|
action: !isFilterOpen ? "open" : "close"
|
|
88084
88937
|
});
|
|
88085
88938
|
setIsFilterOpen((previous) => !previous);
|
|
88086
88939
|
}, [isFilterOpen]);
|
|
88087
|
-
const handleTrendModeChange =
|
|
88940
|
+
const handleTrendModeChange = React148__default.useCallback((event) => {
|
|
88088
88941
|
const nextMode = event.target.value;
|
|
88089
88942
|
trackCoreEvent("Operations Overview Shift Filter Changed", {
|
|
88090
88943
|
shift_mode: nextMode
|
|
88091
88944
|
});
|
|
88092
88945
|
onTrendModeChange(nextMode);
|
|
88093
88946
|
}, [onTrendModeChange]);
|
|
88094
|
-
const handleAllLinesToggle =
|
|
88947
|
+
const handleAllLinesToggle = React148__default.useCallback(() => {
|
|
88095
88948
|
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
88096
88949
|
selected_line_ids: availableLineIds,
|
|
88097
88950
|
selected_line_count: availableLineIds.length,
|
|
@@ -88099,7 +88952,7 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88099
88952
|
});
|
|
88100
88953
|
onSelectedLineIdsChange(availableLineIds);
|
|
88101
88954
|
}, [availableLineIds, onSelectedLineIdsChange]);
|
|
88102
|
-
const handleSupervisorChange =
|
|
88955
|
+
const handleSupervisorChange = React148__default.useCallback((event) => {
|
|
88103
88956
|
const supervisorId = event.target.value;
|
|
88104
88957
|
const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
|
|
88105
88958
|
trackCoreEvent("Operations Overview Supervisor Filter Changed", {
|
|
@@ -88110,7 +88963,7 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88110
88963
|
});
|
|
88111
88964
|
onSelectedSupervisorIdChange(supervisorId);
|
|
88112
88965
|
}, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
|
|
88113
|
-
const handleLineToggle =
|
|
88966
|
+
const handleLineToggle = React148__default.useCallback((lineId) => {
|
|
88114
88967
|
const current = new Set(selectedLineIds);
|
|
88115
88968
|
if (current.has(lineId)) {
|
|
88116
88969
|
if (current.size <= 1) return;
|
|
@@ -88126,13 +88979,13 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88126
88979
|
});
|
|
88127
88980
|
onSelectedLineIdsChange(next);
|
|
88128
88981
|
}, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
|
|
88129
|
-
const handleClearAllFilters =
|
|
88982
|
+
const handleClearAllFilters = React148__default.useCallback(() => {
|
|
88130
88983
|
onTrendModeChange("all");
|
|
88131
88984
|
onSelectedSupervisorIdChange("all");
|
|
88132
88985
|
onSelectedLineIdsChange(availableLineIds);
|
|
88133
88986
|
setIsFilterOpen(false);
|
|
88134
88987
|
}, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
|
|
88135
|
-
|
|
88988
|
+
React148__default.useEffect(() => {
|
|
88136
88989
|
const handleClickOutside = (event) => {
|
|
88137
88990
|
const target = event.target;
|
|
88138
88991
|
if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
|
|
@@ -88367,12 +89220,12 @@ var OperationsOverviewHeader = React147__default.memo(({
|
|
|
88367
89220
|
] }) });
|
|
88368
89221
|
});
|
|
88369
89222
|
OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
|
|
88370
|
-
var OverviewSummaryCards =
|
|
89223
|
+
var OverviewSummaryCards = React148__default.memo(({ store }) => {
|
|
88371
89224
|
bumpRenderCounter();
|
|
88372
89225
|
const scope = useOperationsOverviewScope(store);
|
|
88373
89226
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
88374
89227
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
88375
|
-
const comparisonLabel =
|
|
89228
|
+
const comparisonLabel = React148__default.useMemo(() => {
|
|
88376
89229
|
return formatComparisonWindow({
|
|
88377
89230
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
88378
89231
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -88385,27 +89238,27 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88385
89238
|
scope.previous_range?.day_count,
|
|
88386
89239
|
scope.shift_mode
|
|
88387
89240
|
]);
|
|
88388
|
-
const [isIdleContributorsOpen, setIsIdleContributorsOpen] =
|
|
88389
|
-
const [isIdleContributorsPinned, setIsIdleContributorsPinned] =
|
|
88390
|
-
const idleContributorsRef =
|
|
88391
|
-
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(() => {
|
|
88392
89245
|
return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
|
|
88393
89246
|
positiveIsGood: true,
|
|
88394
89247
|
formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
|
|
88395
89248
|
comparisonLabel
|
|
88396
89249
|
});
|
|
88397
89250
|
}, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
|
|
88398
|
-
const idleBadge =
|
|
89251
|
+
const idleBadge = React148__default.useMemo(() => {
|
|
88399
89252
|
return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
|
|
88400
89253
|
positiveIsGood: false,
|
|
88401
89254
|
formatter: (value) => formatSignedIdleDuration(value),
|
|
88402
89255
|
comparisonLabel
|
|
88403
89256
|
});
|
|
88404
89257
|
}, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
|
|
88405
|
-
const canInspectIdleContributors =
|
|
89258
|
+
const canInspectIdleContributors = React148__default.useMemo(() => {
|
|
88406
89259
|
return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
|
|
88407
89260
|
}, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
|
|
88408
|
-
const idleTopContributors =
|
|
89261
|
+
const idleTopContributors = React148__default.useMemo(() => {
|
|
88409
89262
|
return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
|
|
88410
89263
|
workspaceId: item.workspace_id || "",
|
|
88411
89264
|
workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
|
|
@@ -88413,14 +89266,14 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88413
89266
|
avgIdleSeconds: toNumber4(item.avg_idle_seconds)
|
|
88414
89267
|
})).slice(0, 5);
|
|
88415
89268
|
}, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
|
|
88416
|
-
const showIdleContributorLineNames =
|
|
89269
|
+
const showIdleContributorLineNames = React148__default.useMemo(() => {
|
|
88417
89270
|
return (scope.line_count ?? 0) > 1;
|
|
88418
89271
|
}, [scope.line_count]);
|
|
88419
|
-
const closeIdleContributors =
|
|
89272
|
+
const closeIdleContributors = React148__default.useCallback(() => {
|
|
88420
89273
|
setIsIdleContributorsOpen(false);
|
|
88421
89274
|
setIsIdleContributorsPinned(false);
|
|
88422
89275
|
}, []);
|
|
88423
|
-
const handleIdleContributorsToggle =
|
|
89276
|
+
const handleIdleContributorsToggle = React148__default.useCallback(() => {
|
|
88424
89277
|
if (!canInspectIdleContributors) return;
|
|
88425
89278
|
setIsIdleContributorsPinned((previous) => {
|
|
88426
89279
|
const next = !previous;
|
|
@@ -88428,7 +89281,7 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88428
89281
|
return next;
|
|
88429
89282
|
});
|
|
88430
89283
|
}, [canInspectIdleContributors]);
|
|
88431
|
-
const handleIdleContributorsKeyDown =
|
|
89284
|
+
const handleIdleContributorsKeyDown = React148__default.useCallback((event) => {
|
|
88432
89285
|
if (!canInspectIdleContributors) return;
|
|
88433
89286
|
if (event.key === "Enter" || event.key === " ") {
|
|
88434
89287
|
event.preventDefault();
|
|
@@ -88440,11 +89293,11 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88440
89293
|
closeIdleContributors();
|
|
88441
89294
|
}
|
|
88442
89295
|
}, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
|
|
88443
|
-
|
|
89296
|
+
React148__default.useEffect(() => {
|
|
88444
89297
|
setIsIdleContributorsOpen(false);
|
|
88445
89298
|
setIsIdleContributorsPinned(false);
|
|
88446
89299
|
}, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
|
|
88447
|
-
|
|
89300
|
+
React148__default.useEffect(() => {
|
|
88448
89301
|
if (!isIdleContributorsOpen) return void 0;
|
|
88449
89302
|
const handleClickOutside = (event) => {
|
|
88450
89303
|
if (!isIdleContributorsPinned) return;
|
|
@@ -88582,7 +89435,7 @@ var OverviewSummaryCards = React147__default.memo(({ store }) => {
|
|
|
88582
89435
|
] });
|
|
88583
89436
|
});
|
|
88584
89437
|
OverviewSummaryCards.displayName = "OverviewSummaryCards";
|
|
88585
|
-
var PoorestPerformersCard =
|
|
89438
|
+
var PoorestPerformersCard = React148__default.memo(({
|
|
88586
89439
|
store,
|
|
88587
89440
|
supervisorsByLineId,
|
|
88588
89441
|
onViewAll,
|
|
@@ -88591,9 +89444,9 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88591
89444
|
bumpRenderCounter();
|
|
88592
89445
|
const scope = useOperationsOverviewScope(store);
|
|
88593
89446
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
88594
|
-
const [poorestLineMode, setPoorestLineMode] =
|
|
89447
|
+
const [poorestLineMode, setPoorestLineMode] = React148__default.useState("output");
|
|
88595
89448
|
const availableLineModes = scope.available_line_modes;
|
|
88596
|
-
|
|
89449
|
+
React148__default.useEffect(() => {
|
|
88597
89450
|
const hasOutput = !!availableLineModes?.has_output;
|
|
88598
89451
|
const hasUptime = !!availableLineModes?.has_uptime;
|
|
88599
89452
|
if (hasOutput && !hasUptime && poorestLineMode !== "output") {
|
|
@@ -88602,7 +89455,7 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88602
89455
|
setPoorestLineMode("uptime");
|
|
88603
89456
|
}
|
|
88604
89457
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
88605
|
-
const comparisonLabel =
|
|
89458
|
+
const comparisonLabel = React148__default.useMemo(() => {
|
|
88606
89459
|
return formatComparisonWindow({
|
|
88607
89460
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
88608
89461
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -88616,7 +89469,7 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88616
89469
|
scope.shift_mode
|
|
88617
89470
|
]);
|
|
88618
89471
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
88619
|
-
const mergedPoorestLines =
|
|
89472
|
+
const mergedPoorestLines = React148__default.useMemo(() => {
|
|
88620
89473
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
88621
89474
|
const lineRows = [];
|
|
88622
89475
|
const areaGroups = /* @__PURE__ */ new Map();
|
|
@@ -88696,7 +89549,7 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88696
89549
|
}, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
|
|
88697
89550
|
const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
|
|
88698
89551
|
const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
|
|
88699
|
-
const handlePoorestLineModeChange =
|
|
89552
|
+
const handlePoorestLineModeChange = React148__default.useCallback((mode) => {
|
|
88700
89553
|
trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
|
|
88701
89554
|
setPoorestLineMode(mode);
|
|
88702
89555
|
}, []);
|
|
@@ -88782,14 +89635,14 @@ var PoorestPerformersCard = React147__default.memo(({
|
|
|
88782
89635
|
] });
|
|
88783
89636
|
});
|
|
88784
89637
|
PoorestPerformersCard.displayName = "PoorestPerformersCard";
|
|
88785
|
-
var IdleBreakdownCard =
|
|
89638
|
+
var IdleBreakdownCard = React148__default.memo(({
|
|
88786
89639
|
store,
|
|
88787
89640
|
scopedLineCount
|
|
88788
89641
|
}) => {
|
|
88789
89642
|
bumpRenderCounter();
|
|
88790
89643
|
const idle = useOperationsOverviewIdle(store);
|
|
88791
89644
|
const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
|
|
88792
|
-
const idleBreakdown =
|
|
89645
|
+
const idleBreakdown = React148__default.useMemo(() => {
|
|
88793
89646
|
return idle.data.map((item) => ({
|
|
88794
89647
|
name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
|
|
88795
89648
|
reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
|
|
@@ -88808,7 +89661,7 @@ var IdleBreakdownCard = React147__default.memo(({
|
|
|
88808
89661
|
}))
|
|
88809
89662
|
})).filter((item) => item.value > 0);
|
|
88810
89663
|
}, [idle.data]);
|
|
88811
|
-
const showIdleModuleNotEnabledState =
|
|
89664
|
+
const showIdleModuleNotEnabledState = React148__default.useMemo(() => {
|
|
88812
89665
|
const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
|
|
88813
89666
|
return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
|
|
88814
89667
|
}, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
|
|
@@ -88829,7 +89682,7 @@ var IdleBreakdownCard = React147__default.memo(({
|
|
|
88829
89682
|
] });
|
|
88830
89683
|
});
|
|
88831
89684
|
IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
88832
|
-
var EfficiencyTrendCard =
|
|
89685
|
+
var EfficiencyTrendCard = React148__default.memo(({
|
|
88833
89686
|
store,
|
|
88834
89687
|
dateRange,
|
|
88835
89688
|
appTimezone,
|
|
@@ -88837,14 +89690,14 @@ var EfficiencyTrendCard = React147__default.memo(({
|
|
|
88837
89690
|
}) => {
|
|
88838
89691
|
bumpRenderCounter();
|
|
88839
89692
|
const trend = useOperationsOverviewTrend(store);
|
|
88840
|
-
const currentWeekRange =
|
|
89693
|
+
const currentWeekRange = React148__default.useMemo(
|
|
88841
89694
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
88842
89695
|
[appTimezone]
|
|
88843
89696
|
);
|
|
88844
89697
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
88845
89698
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
88846
89699
|
const isHourlyTrend = trend.data.granularity === "hour";
|
|
88847
|
-
const trendData =
|
|
89700
|
+
const trendData = React148__default.useMemo(() => {
|
|
88848
89701
|
if (isHourlyTrend) {
|
|
88849
89702
|
return (trend.data.points || []).map((point, index) => ({
|
|
88850
89703
|
name: (() => {
|
|
@@ -88916,13 +89769,13 @@ var EfficiencyTrendCard = React147__default.memo(({
|
|
|
88916
89769
|
};
|
|
88917
89770
|
});
|
|
88918
89771
|
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
88919
|
-
const trendTooltipLabelFormatter =
|
|
89772
|
+
const trendTooltipLabelFormatter = React148__default.useCallback((label, payload) => {
|
|
88920
89773
|
if (isHourlyTrend) return label;
|
|
88921
89774
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
88922
89775
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
88923
89776
|
return `${label} (${dayOfWeek})`;
|
|
88924
89777
|
}, [isHourlyTrend]);
|
|
88925
|
-
const trendXAxisTickFormatter =
|
|
89778
|
+
const trendXAxisTickFormatter = React148__default.useCallback((value, index) => {
|
|
88926
89779
|
if (!isHourlyTrend) {
|
|
88927
89780
|
return typeof value === "string" ? value : String(value ?? "");
|
|
88928
89781
|
}
|
|
@@ -88949,7 +89802,7 @@ var EfficiencyTrendCard = React147__default.memo(({
|
|
|
88949
89802
|
] });
|
|
88950
89803
|
});
|
|
88951
89804
|
EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
|
|
88952
|
-
var TopImprovementsCard =
|
|
89805
|
+
var TopImprovementsCard = React148__default.memo(({
|
|
88953
89806
|
store,
|
|
88954
89807
|
supervisorsByLineId,
|
|
88955
89808
|
onViewAll,
|
|
@@ -88958,7 +89811,7 @@ var TopImprovementsCard = React147__default.memo(({
|
|
|
88958
89811
|
bumpRenderCounter();
|
|
88959
89812
|
const improvements = useOperationsOverviewImprovements(store);
|
|
88960
89813
|
const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
|
|
88961
|
-
const displayImprovements =
|
|
89814
|
+
const displayImprovements = React148__default.useMemo(() => {
|
|
88962
89815
|
return improvements.data.map((item) => {
|
|
88963
89816
|
const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
|
|
88964
89817
|
return {
|
|
@@ -89086,33 +89939,33 @@ var useOperationsOverviewRefresh = ({
|
|
|
89086
89939
|
isLiveScope,
|
|
89087
89940
|
enabled = true
|
|
89088
89941
|
}) => {
|
|
89089
|
-
const lineIdsKey =
|
|
89090
|
-
const scopeSignature =
|
|
89942
|
+
const lineIdsKey = React148__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
89943
|
+
const scopeSignature = React148__default.useMemo(
|
|
89091
89944
|
() => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
|
|
89092
89945
|
[companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
|
|
89093
89946
|
);
|
|
89094
|
-
const controllersRef =
|
|
89095
|
-
const requestIdsRef =
|
|
89947
|
+
const controllersRef = React148__default.useRef({});
|
|
89948
|
+
const requestIdsRef = React148__default.useRef({
|
|
89096
89949
|
snapshot: 0,
|
|
89097
89950
|
trend: 0,
|
|
89098
89951
|
idle: 0,
|
|
89099
89952
|
improvements: 0
|
|
89100
89953
|
});
|
|
89101
|
-
const intervalRef =
|
|
89102
|
-
const isPageActiveRef =
|
|
89103
|
-
const lastResumeRefreshAtRef =
|
|
89104
|
-
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(() => {
|
|
89105
89958
|
Object.values(controllersRef.current).forEach((controller) => {
|
|
89106
89959
|
controller?.abort();
|
|
89107
89960
|
});
|
|
89108
89961
|
controllersRef.current = {};
|
|
89109
89962
|
}, []);
|
|
89110
|
-
|
|
89963
|
+
React148__default.useEffect(() => {
|
|
89111
89964
|
return () => {
|
|
89112
89965
|
abortAll();
|
|
89113
89966
|
};
|
|
89114
89967
|
}, [abortAll]);
|
|
89115
|
-
const getIsPageActive =
|
|
89968
|
+
const getIsPageActive = React148__default.useCallback(() => {
|
|
89116
89969
|
if (typeof document === "undefined") {
|
|
89117
89970
|
return true;
|
|
89118
89971
|
}
|
|
@@ -89120,7 +89973,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89120
89973
|
const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
|
|
89121
89974
|
return isVisible && hasFocus;
|
|
89122
89975
|
}, []);
|
|
89123
|
-
const stopPolling =
|
|
89976
|
+
const stopPolling = React148__default.useCallback((reason) => {
|
|
89124
89977
|
if (intervalRef.current === null) {
|
|
89125
89978
|
return;
|
|
89126
89979
|
}
|
|
@@ -89128,7 +89981,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89128
89981
|
intervalRef.current = null;
|
|
89129
89982
|
debugRefreshLog("poll stopped", { reason });
|
|
89130
89983
|
}, []);
|
|
89131
|
-
const runRefresh =
|
|
89984
|
+
const runRefresh = React148__default.useCallback(
|
|
89132
89985
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
89133
89986
|
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
89134
89987
|
const requestId = requestIdsRef.current[section] + 1;
|
|
@@ -89175,7 +90028,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89175
90028
|
},
|
|
89176
90029
|
[companyId, comparisonStrategy, enabled, endKey, lineIds, startKey, supabase, trendMode]
|
|
89177
90030
|
);
|
|
89178
|
-
const refreshSnapshot =
|
|
90031
|
+
const refreshSnapshot = React148__default.useCallback(
|
|
89179
90032
|
async (reason) => {
|
|
89180
90033
|
await runRefresh(
|
|
89181
90034
|
"snapshot",
|
|
@@ -89207,7 +90060,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89207
90060
|
},
|
|
89208
90061
|
[companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
89209
90062
|
);
|
|
89210
|
-
const refreshTrend =
|
|
90063
|
+
const refreshTrend = React148__default.useCallback(
|
|
89211
90064
|
async (reason) => {
|
|
89212
90065
|
await runRefresh(
|
|
89213
90066
|
"trend",
|
|
@@ -89236,7 +90089,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89236
90089
|
},
|
|
89237
90090
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
89238
90091
|
);
|
|
89239
|
-
const refreshIdle =
|
|
90092
|
+
const refreshIdle = React148__default.useCallback(
|
|
89240
90093
|
async (reason) => {
|
|
89241
90094
|
await runRefresh(
|
|
89242
90095
|
"idle",
|
|
@@ -89265,7 +90118,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89265
90118
|
},
|
|
89266
90119
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
89267
90120
|
);
|
|
89268
|
-
const refreshImprovements =
|
|
90121
|
+
const refreshImprovements = React148__default.useCallback(
|
|
89269
90122
|
async (reason) => {
|
|
89270
90123
|
await runRefresh(
|
|
89271
90124
|
"improvements",
|
|
@@ -89295,7 +90148,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89295
90148
|
},
|
|
89296
90149
|
[companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
|
|
89297
90150
|
);
|
|
89298
|
-
const refreshAll =
|
|
90151
|
+
const refreshAll = React148__default.useCallback(
|
|
89299
90152
|
async (reason) => {
|
|
89300
90153
|
await Promise.allSettled([
|
|
89301
90154
|
refreshSnapshot(reason),
|
|
@@ -89306,7 +90159,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89306
90159
|
},
|
|
89307
90160
|
[refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
|
|
89308
90161
|
);
|
|
89309
|
-
const startPolling =
|
|
90162
|
+
const startPolling = React148__default.useCallback((reason) => {
|
|
89310
90163
|
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
89311
90164
|
return;
|
|
89312
90165
|
}
|
|
@@ -89327,7 +90180,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89327
90180
|
}, LIVE_REFRESH_INTERVAL_MS);
|
|
89328
90181
|
debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
|
|
89329
90182
|
}, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
|
|
89330
|
-
const refreshFromResume =
|
|
90183
|
+
const refreshFromResume = React148__default.useCallback((reason) => {
|
|
89331
90184
|
const now4 = Date.now();
|
|
89332
90185
|
if (now4 - lastResumeRefreshAtRef.current < 1e3) {
|
|
89333
90186
|
debugRefreshLog("resume refresh suppressed", { reason });
|
|
@@ -89342,7 +90195,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89342
90195
|
}
|
|
89343
90196
|
});
|
|
89344
90197
|
}, [refreshAll, startPolling, stopPolling]);
|
|
89345
|
-
|
|
90198
|
+
React148__default.useEffect(() => {
|
|
89346
90199
|
if (!enabled) {
|
|
89347
90200
|
stopPolling("disabled");
|
|
89348
90201
|
abortAll();
|
|
@@ -89357,7 +90210,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
89357
90210
|
}
|
|
89358
90211
|
void refreshAll("scope_change");
|
|
89359
90212
|
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
89360
|
-
|
|
90213
|
+
React148__default.useEffect(() => {
|
|
89361
90214
|
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
89362
90215
|
isPageActiveRef.current = false;
|
|
89363
90216
|
stopPolling("live_scope_disabled");
|
|
@@ -89570,55 +90423,55 @@ var PlantHeadView = () => {
|
|
|
89570
90423
|
const { accessibleLineIds } = useUserLineAccess();
|
|
89571
90424
|
const mobileMenuContext = useMobileMenu();
|
|
89572
90425
|
useHideMobileHeader(!!mobileMenuContext);
|
|
89573
|
-
const storeRef =
|
|
90426
|
+
const storeRef = React148__default.useRef(createOperationsOverviewStore());
|
|
89574
90427
|
const store = storeRef.current;
|
|
89575
|
-
const fallbackOperationalDate =
|
|
90428
|
+
const fallbackOperationalDate = React148__default.useMemo(
|
|
89576
90429
|
() => getOperationalDate(appTimezone),
|
|
89577
90430
|
[appTimezone]
|
|
89578
90431
|
);
|
|
89579
|
-
const [dateRange, setDateRange] =
|
|
90432
|
+
const [dateRange, setDateRange] = React148__default.useState(() => ({
|
|
89580
90433
|
startKey: fallbackOperationalDate,
|
|
89581
90434
|
endKey: fallbackOperationalDate
|
|
89582
90435
|
}));
|
|
89583
|
-
const [usesThisWeekComparison, setUsesThisWeekComparison] =
|
|
89584
|
-
const [trendMode, setTrendMode] =
|
|
89585
|
-
const [selectedSupervisorId, setSelectedSupervisorId] =
|
|
89586
|
-
const [selectedLineIds, setSelectedLineIds] =
|
|
89587
|
-
const [isInitialScopeReady, setIsInitialScopeReady] =
|
|
89588
|
-
const [shiftResolutionTick, setShiftResolutionTick] =
|
|
89589
|
-
const hasAutoInitializedScopeRef =
|
|
89590
|
-
const hasUserAdjustedScopeRef =
|
|
89591
|
-
|
|
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(() => {
|
|
89592
90445
|
trackCorePageView("Operations Overview", {
|
|
89593
90446
|
dashboard_surface: "operations_overview"
|
|
89594
90447
|
});
|
|
89595
90448
|
}, []);
|
|
89596
|
-
const currentWeekRange =
|
|
90449
|
+
const currentWeekRange = React148__default.useMemo(
|
|
89597
90450
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
89598
90451
|
[appTimezone]
|
|
89599
90452
|
);
|
|
89600
|
-
const currentWeekDisplayRange =
|
|
90453
|
+
const currentWeekDisplayRange = React148__default.useMemo(
|
|
89601
90454
|
() => getCurrentWeekFullRange(appTimezone),
|
|
89602
90455
|
[appTimezone]
|
|
89603
90456
|
);
|
|
89604
90457
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
89605
|
-
const headerDateRange =
|
|
90458
|
+
const headerDateRange = React148__default.useMemo(() => {
|
|
89606
90459
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
89607
90460
|
return currentWeekDisplayRange;
|
|
89608
90461
|
}
|
|
89609
90462
|
return dateRange;
|
|
89610
90463
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
89611
|
-
const normalizedLineIds =
|
|
90464
|
+
const normalizedLineIds = React148__default.useMemo(
|
|
89612
90465
|
() => Array.from(new Set(
|
|
89613
90466
|
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
89614
90467
|
)).sort(),
|
|
89615
90468
|
[accessibleLineIds, factoryViewId]
|
|
89616
90469
|
);
|
|
89617
|
-
const lineIdsKey =
|
|
90470
|
+
const lineIdsKey = React148__default.useMemo(
|
|
89618
90471
|
() => normalizedLineIds.join(","),
|
|
89619
90472
|
[normalizedLineIds]
|
|
89620
90473
|
);
|
|
89621
|
-
const lineOptions =
|
|
90474
|
+
const lineOptions = React148__default.useMemo(
|
|
89622
90475
|
() => normalizedLineIds.map((lineId) => ({
|
|
89623
90476
|
id: lineId,
|
|
89624
90477
|
name: getLineDisplayName(entityConfig, lineId)
|
|
@@ -89630,7 +90483,7 @@ var PlantHeadView = () => {
|
|
|
89630
90483
|
companyId: entityConfig.companyId,
|
|
89631
90484
|
useBackend: true
|
|
89632
90485
|
});
|
|
89633
|
-
const supervisorOptions =
|
|
90486
|
+
const supervisorOptions = React148__default.useMemo(
|
|
89634
90487
|
() => {
|
|
89635
90488
|
const optionsById = /* @__PURE__ */ new Map();
|
|
89636
90489
|
normalizedLineIds.forEach((lineId) => {
|
|
@@ -89656,7 +90509,7 @@ var PlantHeadView = () => {
|
|
|
89656
90509
|
},
|
|
89657
90510
|
[normalizedLineIds, supervisorsByLineId]
|
|
89658
90511
|
);
|
|
89659
|
-
|
|
90512
|
+
React148__default.useEffect(() => {
|
|
89660
90513
|
if (selectedSupervisorId === "all") {
|
|
89661
90514
|
setSelectedLineIds((previous) => {
|
|
89662
90515
|
if (normalizedLineIds.length === 0) {
|
|
@@ -89682,7 +90535,7 @@ var PlantHeadView = () => {
|
|
|
89682
90535
|
const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
|
|
89683
90536
|
setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
|
|
89684
90537
|
}, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
|
|
89685
|
-
const scopedLineIds =
|
|
90538
|
+
const scopedLineIds = React148__default.useMemo(
|
|
89686
90539
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
89687
90540
|
[normalizedLineIds, selectedLineIds]
|
|
89688
90541
|
);
|
|
@@ -89690,7 +90543,7 @@ var PlantHeadView = () => {
|
|
|
89690
90543
|
shiftConfigMap,
|
|
89691
90544
|
isLoading: isShiftConfigLoading
|
|
89692
90545
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
89693
|
-
const shiftFilterOptions =
|
|
90546
|
+
const shiftFilterOptions = React148__default.useMemo(() => {
|
|
89694
90547
|
const optionsById = /* @__PURE__ */ new Map();
|
|
89695
90548
|
scopedLineIds.forEach((lineId) => {
|
|
89696
90549
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -89729,7 +90582,7 @@ var PlantHeadView = () => {
|
|
|
89729
90582
|
...dynamicOptions
|
|
89730
90583
|
];
|
|
89731
90584
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
89732
|
-
|
|
90585
|
+
React148__default.useEffect(() => {
|
|
89733
90586
|
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
89734
90587
|
return;
|
|
89735
90588
|
}
|
|
@@ -89740,11 +90593,11 @@ var PlantHeadView = () => {
|
|
|
89740
90593
|
clearInterval(intervalId);
|
|
89741
90594
|
};
|
|
89742
90595
|
}, [isShiftConfigLoading, scopedLineIds.length]);
|
|
89743
|
-
const shiftResolutionNow =
|
|
90596
|
+
const shiftResolutionNow = React148__default.useMemo(
|
|
89744
90597
|
() => /* @__PURE__ */ new Date(),
|
|
89745
90598
|
[shiftResolutionTick]
|
|
89746
90599
|
);
|
|
89747
|
-
const earliestDayShiftStartTime =
|
|
90600
|
+
const earliestDayShiftStartTime = React148__default.useMemo(() => {
|
|
89748
90601
|
const candidateStarts = [];
|
|
89749
90602
|
scopedLineIds.forEach((lineId) => {
|
|
89750
90603
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -89780,11 +90633,11 @@ var PlantHeadView = () => {
|
|
|
89780
90633
|
const minutes = earliestMinutes % 60;
|
|
89781
90634
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
89782
90635
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
89783
|
-
const resolvedOperationalToday =
|
|
90636
|
+
const resolvedOperationalToday = React148__default.useMemo(
|
|
89784
90637
|
() => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
|
|
89785
90638
|
[appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
|
|
89786
90639
|
);
|
|
89787
|
-
const activeLineShiftStates =
|
|
90640
|
+
const activeLineShiftStates = React148__default.useMemo(() => {
|
|
89788
90641
|
return scopedLineIds.flatMap((lineId) => {
|
|
89789
90642
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
89790
90643
|
const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
|
|
@@ -89814,7 +90667,7 @@ var PlantHeadView = () => {
|
|
|
89814
90667
|
});
|
|
89815
90668
|
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
89816
90669
|
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
89817
|
-
const hourlyWindowStartTime =
|
|
90670
|
+
const hourlyWindowStartTime = React148__default.useMemo(() => {
|
|
89818
90671
|
if (scopedLineIds.length === 0) {
|
|
89819
90672
|
return null;
|
|
89820
90673
|
}
|
|
@@ -89871,12 +90724,12 @@ var PlantHeadView = () => {
|
|
|
89871
90724
|
const minutes = earliestMinutes % 60;
|
|
89872
90725
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
89873
90726
|
}, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
89874
|
-
const isShiftScopeResolved =
|
|
90727
|
+
const isShiftScopeResolved = React148__default.useMemo(
|
|
89875
90728
|
() => !isShiftConfigLoading,
|
|
89876
90729
|
[isShiftConfigLoading]
|
|
89877
90730
|
);
|
|
89878
|
-
const initializedTimezoneRef =
|
|
89879
|
-
|
|
90731
|
+
const initializedTimezoneRef = React148__default.useRef(appTimezone);
|
|
90732
|
+
React148__default.useEffect(() => {
|
|
89880
90733
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
89881
90734
|
hasAutoInitializedScopeRef.current = false;
|
|
89882
90735
|
hasUserAdjustedScopeRef.current = false;
|
|
@@ -89889,7 +90742,7 @@ var PlantHeadView = () => {
|
|
|
89889
90742
|
setIsInitialScopeReady(false);
|
|
89890
90743
|
initializedTimezoneRef.current = appTimezone;
|
|
89891
90744
|
}, [appTimezone, fallbackOperationalDate]);
|
|
89892
|
-
|
|
90745
|
+
React148__default.useEffect(() => {
|
|
89893
90746
|
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
89894
90747
|
return;
|
|
89895
90748
|
}
|
|
@@ -89914,7 +90767,7 @@ var PlantHeadView = () => {
|
|
|
89914
90767
|
hasAutoInitializedScopeRef.current = true;
|
|
89915
90768
|
setIsInitialScopeReady(true);
|
|
89916
90769
|
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
89917
|
-
const handleDateRangeChange =
|
|
90770
|
+
const handleDateRangeChange = React148__default.useCallback((range, meta) => {
|
|
89918
90771
|
hasUserAdjustedScopeRef.current = true;
|
|
89919
90772
|
setIsInitialScopeReady(true);
|
|
89920
90773
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
@@ -89932,12 +90785,12 @@ var PlantHeadView = () => {
|
|
|
89932
90785
|
return previous;
|
|
89933
90786
|
});
|
|
89934
90787
|
}, []);
|
|
89935
|
-
const handleTrendModeChange =
|
|
90788
|
+
const handleTrendModeChange = React148__default.useCallback((mode) => {
|
|
89936
90789
|
hasUserAdjustedScopeRef.current = true;
|
|
89937
90790
|
setIsInitialScopeReady(true);
|
|
89938
90791
|
setTrendMode(mode);
|
|
89939
90792
|
}, []);
|
|
89940
|
-
const handleSelectedLineIdsChange =
|
|
90793
|
+
const handleSelectedLineIdsChange = React148__default.useCallback((lineIds) => {
|
|
89941
90794
|
setSelectedSupervisorId("all");
|
|
89942
90795
|
if (normalizedLineIds.length === 0) {
|
|
89943
90796
|
setSelectedLineIds([]);
|
|
@@ -89948,10 +90801,10 @@ var PlantHeadView = () => {
|
|
|
89948
90801
|
const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
|
|
89949
90802
|
setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
|
|
89950
90803
|
}, [normalizedLineIds]);
|
|
89951
|
-
const handleSelectedSupervisorIdChange =
|
|
90804
|
+
const handleSelectedSupervisorIdChange = React148__default.useCallback((supervisorId) => {
|
|
89952
90805
|
setSelectedSupervisorId(supervisorId);
|
|
89953
90806
|
}, []);
|
|
89954
|
-
const buildLineMonthlyHistoryUrl =
|
|
90807
|
+
const buildLineMonthlyHistoryUrl = React148__default.useCallback((lineId) => {
|
|
89955
90808
|
const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
|
|
89956
90809
|
const params = new URLSearchParams();
|
|
89957
90810
|
params.set("tab", "monthly_history");
|
|
@@ -89961,15 +90814,15 @@ var PlantHeadView = () => {
|
|
|
89961
90814
|
params.set("rangeEnd", dateRange.endKey);
|
|
89962
90815
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
89963
90816
|
}, [dateRange.endKey, dateRange.startKey]);
|
|
89964
|
-
const handleViewAllPoorestPerformers =
|
|
90817
|
+
const handleViewAllPoorestPerformers = React148__default.useCallback(() => {
|
|
89965
90818
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
89966
90819
|
navigate("/kpis?tab=leaderboard");
|
|
89967
90820
|
}, [navigate]);
|
|
89968
|
-
const handleViewAllImprovements =
|
|
90821
|
+
const handleViewAllImprovements = React148__default.useCallback(() => {
|
|
89969
90822
|
trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
|
|
89970
90823
|
navigate("/improvement-center");
|
|
89971
90824
|
}, [navigate]);
|
|
89972
|
-
const handleOpenImprovement =
|
|
90825
|
+
const handleOpenImprovement = React148__default.useCallback((item) => {
|
|
89973
90826
|
trackCoreEvent("Operations Overview Improvement Clicked", {
|
|
89974
90827
|
issue_id: item.issueId,
|
|
89975
90828
|
issue_number: item.issueNumber,
|
|
@@ -89980,13 +90833,13 @@ var PlantHeadView = () => {
|
|
|
89980
90833
|
});
|
|
89981
90834
|
navigate(`/improvement-center?${params.toString()}`);
|
|
89982
90835
|
}, [navigate]);
|
|
89983
|
-
const comparisonStrategy =
|
|
90836
|
+
const comparisonStrategy = React148__default.useMemo(() => {
|
|
89984
90837
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
89985
90838
|
return "previous_full_week";
|
|
89986
90839
|
}
|
|
89987
90840
|
return void 0;
|
|
89988
90841
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
89989
|
-
const effectiveDateRange =
|
|
90842
|
+
const effectiveDateRange = React148__default.useMemo(() => {
|
|
89990
90843
|
if (isInitialScopeReady) {
|
|
89991
90844
|
return dateRange;
|
|
89992
90845
|
}
|
|
@@ -89996,11 +90849,11 @@ var PlantHeadView = () => {
|
|
|
89996
90849
|
endKey: nextStartKey
|
|
89997
90850
|
};
|
|
89998
90851
|
}, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
|
|
89999
|
-
const effectiveTrendMode =
|
|
90852
|
+
const effectiveTrendMode = React148__default.useMemo(
|
|
90000
90853
|
() => resolvedTrendMode,
|
|
90001
90854
|
[resolvedTrendMode]
|
|
90002
90855
|
);
|
|
90003
|
-
const hasActiveSelectedShiftLine =
|
|
90856
|
+
const hasActiveSelectedShiftLine = React148__default.useMemo(
|
|
90004
90857
|
() => activeLineShiftStates.some((shift) => {
|
|
90005
90858
|
if (shift.date !== resolvedOperationalToday) return false;
|
|
90006
90859
|
if (effectiveTrendMode === "all") return true;
|
|
@@ -90012,7 +90865,7 @@ var PlantHeadView = () => {
|
|
|
90012
90865
|
}),
|
|
90013
90866
|
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
90014
90867
|
);
|
|
90015
|
-
const activeLiveShiftName =
|
|
90868
|
+
const activeLiveShiftName = React148__default.useMemo(
|
|
90016
90869
|
() => {
|
|
90017
90870
|
if (effectiveTrendMode === "all") return null;
|
|
90018
90871
|
const matchingShift = activeLineShiftStates.find((shift) => {
|
|
@@ -90027,17 +90880,17 @@ var PlantHeadView = () => {
|
|
|
90027
90880
|
},
|
|
90028
90881
|
[activeLineShiftStates, effectiveTrendMode, resolvedOperationalToday]
|
|
90029
90882
|
);
|
|
90030
|
-
const hourlyLabelStartTime =
|
|
90883
|
+
const hourlyLabelStartTime = React148__default.useMemo(() => {
|
|
90031
90884
|
if (scopedLineIds.length === 0) {
|
|
90032
90885
|
return null;
|
|
90033
90886
|
}
|
|
90034
90887
|
return hourlyWindowStartTime;
|
|
90035
90888
|
}, [hourlyWindowStartTime, scopedLineIds.length]);
|
|
90036
|
-
const isSingleDayScope =
|
|
90889
|
+
const isSingleDayScope = React148__default.useMemo(
|
|
90037
90890
|
() => effectiveDateRange.startKey === effectiveDateRange.endKey,
|
|
90038
90891
|
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
90039
90892
|
);
|
|
90040
|
-
const isLiveScope =
|
|
90893
|
+
const isLiveScope = React148__default.useMemo(
|
|
90041
90894
|
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && hasActiveSelectedShiftLine,
|
|
90042
90895
|
[
|
|
90043
90896
|
effectiveDateRange.startKey,
|
|
@@ -90047,7 +90900,7 @@ var PlantHeadView = () => {
|
|
|
90047
90900
|
resolvedOperationalToday
|
|
90048
90901
|
]
|
|
90049
90902
|
);
|
|
90050
|
-
const handleOpenLineDetails =
|
|
90903
|
+
const handleOpenLineDetails = React148__default.useCallback((line) => {
|
|
90051
90904
|
trackCoreEvent("Operations Overview Line Clicked", {
|
|
90052
90905
|
line_id: line.rowType === "line" ? line.id : null,
|
|
90053
90906
|
line_name: line.name,
|