@optifye/dashboard-core 6.11.15 → 6.11.16
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 +26 -3
- package/dist/index.d.mts +28 -2
- package/dist/index.d.ts +28 -2
- package/dist/index.js +1115 -534
- package/dist/index.mjs +1115 -536
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import Hls, { Events, ErrorTypes } from 'hls.js';
|
|
|
12
12
|
import useSWR from 'swr';
|
|
13
13
|
import { Camera, AlertTriangle, ChevronDown, ChevronUp, Check, Map as Map$1, Video, ShieldCheck, Star, Award, Filter, X, Coffee, Plus, ArrowUp, ArrowDown, ArrowRight, ArrowLeft, Clock, Calendar, Save, AlertCircle, Loader2, Minus, ChevronLeft, ChevronRight, TrendingUp, Sparkles, Pause, Play, XCircle, HelpCircle, Activity, Wrench, UserX, Package, RefreshCw, Palette, CheckCircle2, TrendingDown, FolderOpen, Folder, Tag, Sliders, Layers, Search, Edit2, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Copy, Settings, LifeBuoy, EyeOff, Zap, Flame, Crown, Medal } from 'lucide-react';
|
|
14
14
|
import { memo, noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds } from 'motion-utils';
|
|
15
|
-
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, ReferenceLine, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line,
|
|
15
|
+
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, ReferenceLine, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, PieChart, Pie, Cell, LineChart as LineChart$1, Line, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
|
|
16
16
|
import { Slot } from '@radix-ui/react-slot';
|
|
17
17
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
18
18
|
import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
|
|
@@ -12835,6 +12835,7 @@ var useShiftGroups = ({
|
|
|
12835
12835
|
}) => {
|
|
12836
12836
|
const [shiftGroups, setShiftGroups] = useState([]);
|
|
12837
12837
|
const [shiftGroupsKey, setShiftGroupsKey] = useState("");
|
|
12838
|
+
const [hasComputed, setHasComputed] = useState(false);
|
|
12838
12839
|
const lastKeyRef = useRef("");
|
|
12839
12840
|
const mapRef = useRef(shiftConfigMap);
|
|
12840
12841
|
useEffect(() => {
|
|
@@ -12845,6 +12846,7 @@ var useShiftGroups = ({
|
|
|
12845
12846
|
lastKeyRef.current = "";
|
|
12846
12847
|
setShiftGroups([]);
|
|
12847
12848
|
setShiftGroupsKey("");
|
|
12849
|
+
setHasComputed(false);
|
|
12848
12850
|
return;
|
|
12849
12851
|
}
|
|
12850
12852
|
let isMounted = true;
|
|
@@ -12857,6 +12859,7 @@ var useShiftGroups = ({
|
|
|
12857
12859
|
setShiftGroups(groups);
|
|
12858
12860
|
setShiftGroupsKey(key);
|
|
12859
12861
|
}
|
|
12862
|
+
setHasComputed(true);
|
|
12860
12863
|
};
|
|
12861
12864
|
compute();
|
|
12862
12865
|
const intervalId = setInterval(compute, pollIntervalMs);
|
|
@@ -12865,7 +12868,7 @@ var useShiftGroups = ({
|
|
|
12865
12868
|
clearInterval(intervalId);
|
|
12866
12869
|
};
|
|
12867
12870
|
}, [enabled, shiftConfigMap.size, timezone, pollIntervalMs]);
|
|
12868
|
-
return { shiftGroups, shiftGroupsKey };
|
|
12871
|
+
return { shiftGroups, shiftGroupsKey, hasComputed };
|
|
12869
12872
|
};
|
|
12870
12873
|
|
|
12871
12874
|
// src/lib/types/efficiencyLegend.ts
|
|
@@ -12927,52 +12930,6 @@ function getEfficiencyTextColorClasses(efficiency, legend = DEFAULT_EFFICIENCY_L
|
|
|
12927
12930
|
}
|
|
12928
12931
|
}
|
|
12929
12932
|
|
|
12930
|
-
// src/lib/hooks/useDashboardMetrics.recentFlow.ts
|
|
12931
|
-
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
12932
|
-
var getWorkspaceRecentFlowCacheKey = (workspace) => {
|
|
12933
|
-
const workspaceKey = workspace.workspace_uuid || workspace.workspace_name || "unknown";
|
|
12934
|
-
return `${workspaceKey}|${workspace.date}|${workspace.shift_id}`;
|
|
12935
|
-
};
|
|
12936
|
-
var toRecentFlowSnapshot = (workspace) => {
|
|
12937
|
-
if (!isFiniteNumber(workspace.recent_flow_percent)) {
|
|
12938
|
-
return null;
|
|
12939
|
-
}
|
|
12940
|
-
return {
|
|
12941
|
-
recent_flow_percent: workspace.recent_flow_percent,
|
|
12942
|
-
recent_flow_actual_rate_pph: workspace.recent_flow_actual_rate_pph ?? null,
|
|
12943
|
-
recent_flow_healthy_rate_pph: workspace.recent_flow_healthy_rate_pph ?? null,
|
|
12944
|
-
recent_flow_window_minutes: workspace.recent_flow_window_minutes ?? null,
|
|
12945
|
-
recent_flow_effective_end_at: workspace.recent_flow_effective_end_at ?? null
|
|
12946
|
-
};
|
|
12947
|
-
};
|
|
12948
|
-
var mergeWorkspaceRecentFlowMetrics = (workspaces, previousCache) => {
|
|
12949
|
-
const nextCache = /* @__PURE__ */ new Map();
|
|
12950
|
-
const mergedWorkspaces = workspaces.map((workspace) => {
|
|
12951
|
-
const cacheKey = getWorkspaceRecentFlowCacheKey(workspace);
|
|
12952
|
-
const currentSnapshot = toRecentFlowSnapshot(workspace);
|
|
12953
|
-
if (workspace.recent_flow_mode === "computed" && currentSnapshot) {
|
|
12954
|
-
nextCache.set(cacheKey, currentSnapshot);
|
|
12955
|
-
return workspace;
|
|
12956
|
-
}
|
|
12957
|
-
if (workspace.recent_flow_mode === "hold") {
|
|
12958
|
-
const cachedSnapshot = previousCache.get(cacheKey);
|
|
12959
|
-
if (cachedSnapshot) {
|
|
12960
|
-
nextCache.set(cacheKey, cachedSnapshot);
|
|
12961
|
-
return {
|
|
12962
|
-
...workspace,
|
|
12963
|
-
...cachedSnapshot,
|
|
12964
|
-
recent_flow_mode: "hold"
|
|
12965
|
-
};
|
|
12966
|
-
}
|
|
12967
|
-
}
|
|
12968
|
-
return workspace;
|
|
12969
|
-
});
|
|
12970
|
-
return {
|
|
12971
|
-
workspaces: mergedWorkspaces,
|
|
12972
|
-
cache: nextCache
|
|
12973
|
-
};
|
|
12974
|
-
};
|
|
12975
|
-
|
|
12976
12933
|
// src/lib/hooks/useDashboardMetrics.ts
|
|
12977
12934
|
var DEBUG_DASHBOARD_LOGS = process.env.NEXT_PUBLIC_DEBUG_DASHBOARD === "true";
|
|
12978
12935
|
var logDebug = (...args) => {
|
|
@@ -13061,7 +13018,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13061
13018
|
const abortControllerRef = useRef(null);
|
|
13062
13019
|
const lastFetchKeyRef = useRef(null);
|
|
13063
13020
|
const inFlightFetchKeyRef = useRef(null);
|
|
13064
|
-
const recentFlowCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
13065
13021
|
const updateQueueRef = useRef(false);
|
|
13066
13022
|
const onLineMetricsUpdateRef = useRef(onLineMetricsUpdate);
|
|
13067
13023
|
const shiftGroupsRef = useRef(shiftGroups);
|
|
@@ -13095,7 +13051,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13095
13051
|
setError(null);
|
|
13096
13052
|
lastFetchKeyRef.current = null;
|
|
13097
13053
|
inFlightFetchKeyRef.current = null;
|
|
13098
|
-
recentFlowCacheRef.current = /* @__PURE__ */ new Map();
|
|
13099
13054
|
}, [lineId]);
|
|
13100
13055
|
const fetchAllMetrics = useCallback(async (options = {}) => {
|
|
13101
13056
|
const { force = false } = options;
|
|
@@ -13370,12 +13325,9 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13370
13325
|
actionType: item.action_type,
|
|
13371
13326
|
actionName: item.action_name
|
|
13372
13327
|
}),
|
|
13373
|
-
recent_flow_mode: item.recent_flow_mode ?? void 0,
|
|
13374
13328
|
recent_flow_percent: item.recent_flow_percent ?? null,
|
|
13375
|
-
recent_flow_actual_rate_pph: item.recent_flow_actual_rate_pph ?? null,
|
|
13376
|
-
recent_flow_healthy_rate_pph: item.recent_flow_healthy_rate_pph ?? null,
|
|
13377
|
-
recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
|
|
13378
13329
|
recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
|
|
13330
|
+
recent_flow_computed_at: item.recent_flow_computed_at ?? null,
|
|
13379
13331
|
incoming_wip_current: item.incoming_wip_current ?? null,
|
|
13380
13332
|
incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
|
|
13381
13333
|
incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null
|
|
@@ -13386,16 +13338,11 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13386
13338
|
const wsNumB = parseInt(b.workspace_name?.replace(/[^0-9]/g, "") || "0");
|
|
13387
13339
|
return wsNumA - wsNumB;
|
|
13388
13340
|
});
|
|
13389
|
-
|
|
13390
|
-
workspaces: mergedWorkspaceData,
|
|
13391
|
-
cache: nextRecentFlowCache
|
|
13392
|
-
} = mergeWorkspaceRecentFlowMetrics(transformedWorkspaceData, recentFlowCacheRef.current);
|
|
13393
|
-
recentFlowCacheRef.current = nextRecentFlowCache;
|
|
13394
|
-
mergedWorkspaceData.forEach((metric) => {
|
|
13341
|
+
transformedWorkspaceData.forEach((metric) => {
|
|
13395
13342
|
workspaceMetricsStore.setOverview(metric);
|
|
13396
13343
|
});
|
|
13397
13344
|
const newMetricsState = {
|
|
13398
|
-
workspaceMetrics:
|
|
13345
|
+
workspaceMetrics: transformedWorkspaceData,
|
|
13399
13346
|
lineMetrics: allLineMetrics || [],
|
|
13400
13347
|
metadata: { hasFlowBuffers, idleTimeVlmByLine },
|
|
13401
13348
|
efficiencyLegend: efficiencyLegend ?? DEFAULT_EFFICIENCY_LEGEND
|
|
@@ -16820,7 +16767,7 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16820
16767
|
const [isLoading, setIsLoading] = useState(true);
|
|
16821
16768
|
const [error, setError] = useState(null);
|
|
16822
16769
|
const supabase = useSupabase();
|
|
16823
|
-
const
|
|
16770
|
+
const parseTimeToMinutes4 = (timeStr) => {
|
|
16824
16771
|
const [hours, minutes] = timeStr.split(":").map(Number);
|
|
16825
16772
|
return hours * 60 + minutes;
|
|
16826
16773
|
};
|
|
@@ -16829,8 +16776,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16829
16776
|
return now4.getHours() * 60 + now4.getMinutes();
|
|
16830
16777
|
};
|
|
16831
16778
|
const isTimeInBreak = (breakStart, breakEnd, currentMinutes) => {
|
|
16832
|
-
const startMinutes =
|
|
16833
|
-
const endMinutes =
|
|
16779
|
+
const startMinutes = parseTimeToMinutes4(breakStart);
|
|
16780
|
+
const endMinutes = parseTimeToMinutes4(breakEnd);
|
|
16834
16781
|
if (endMinutes < startMinutes) {
|
|
16835
16782
|
return currentMinutes >= startMinutes || currentMinutes < endMinutes;
|
|
16836
16783
|
} else {
|
|
@@ -16838,8 +16785,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16838
16785
|
}
|
|
16839
16786
|
};
|
|
16840
16787
|
const calculateBreakProgress = (breakStart, breakEnd, currentMinutes) => {
|
|
16841
|
-
const startMinutes =
|
|
16842
|
-
const endMinutes =
|
|
16788
|
+
const startMinutes = parseTimeToMinutes4(breakStart);
|
|
16789
|
+
const endMinutes = parseTimeToMinutes4(breakEnd);
|
|
16843
16790
|
let elapsedMinutes = 0;
|
|
16844
16791
|
let remainingMinutes = 0;
|
|
16845
16792
|
if (endMinutes < startMinutes) {
|
|
@@ -16857,8 +16804,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16857
16804
|
return { elapsedMinutes, remainingMinutes };
|
|
16858
16805
|
};
|
|
16859
16806
|
const isTimeInShift = (startTime, endTime, currentMinutes) => {
|
|
16860
|
-
const startMinutes =
|
|
16861
|
-
const endMinutes =
|
|
16807
|
+
const startMinutes = parseTimeToMinutes4(startTime);
|
|
16808
|
+
const endMinutes = parseTimeToMinutes4(endTime);
|
|
16862
16809
|
if (endMinutes < startMinutes) {
|
|
16863
16810
|
return currentMinutes >= startMinutes || currentMinutes < endMinutes;
|
|
16864
16811
|
} else {
|
|
@@ -16918,8 +16865,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16918
16865
|
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
16919
16866
|
let duration = breakItem.duration || 0;
|
|
16920
16867
|
if (!duration || duration === 0) {
|
|
16921
|
-
const startMinutes =
|
|
16922
|
-
const endMinutes =
|
|
16868
|
+
const startMinutes = parseTimeToMinutes4(startTime);
|
|
16869
|
+
const endMinutes = parseTimeToMinutes4(endTime);
|
|
16923
16870
|
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
16924
16871
|
}
|
|
16925
16872
|
return {
|
|
@@ -16935,8 +16882,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16935
16882
|
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
16936
16883
|
let duration = breakItem.duration || 0;
|
|
16937
16884
|
if (!duration || duration === 0) {
|
|
16938
|
-
const startMinutes =
|
|
16939
|
-
const endMinutes =
|
|
16885
|
+
const startMinutes = parseTimeToMinutes4(startTime);
|
|
16886
|
+
const endMinutes = parseTimeToMinutes4(endTime);
|
|
16940
16887
|
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
16941
16888
|
}
|
|
16942
16889
|
return {
|
|
@@ -23017,6 +22964,16 @@ var createThrottledReload = (interval = 5e3, maxReloads = 3) => {
|
|
|
23017
22964
|
};
|
|
23018
22965
|
var throttledReloadDashboard = createThrottledReload(5e3, 3);
|
|
23019
22966
|
|
|
22967
|
+
// src/lib/utils/dev/localDevTestLogin.ts
|
|
22968
|
+
var isLoopbackHostname = (hostname) => {
|
|
22969
|
+
const normalized = String(hostname || "").trim().toLowerCase();
|
|
22970
|
+
return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1";
|
|
22971
|
+
};
|
|
22972
|
+
var shouldEnableLocalDevTestLogin = ({
|
|
22973
|
+
enabledFlag,
|
|
22974
|
+
hostname
|
|
22975
|
+
}) => enabledFlag && isLoopbackHostname(hostname);
|
|
22976
|
+
|
|
23020
22977
|
// src/lib/utils/index.ts
|
|
23021
22978
|
var formatIdleTime = (idleTimeInSeconds) => {
|
|
23022
22979
|
if (!idleTimeInSeconds || idleTimeInSeconds <= 0) {
|
|
@@ -31201,12 +31158,16 @@ var LoginPage = ({
|
|
|
31201
31158
|
onRateLimitCheck,
|
|
31202
31159
|
logoSrc = optifye_logo_default,
|
|
31203
31160
|
logoAlt = "Optifye",
|
|
31204
|
-
brandName = "Optifye"
|
|
31161
|
+
brandName = "Optifye",
|
|
31162
|
+
showDevTestLogin = false,
|
|
31163
|
+
devTestLoginLabel = "Sign in as Test User",
|
|
31164
|
+
onDevTestLogin
|
|
31205
31165
|
}) => {
|
|
31206
31166
|
const [email, setEmail] = useState("");
|
|
31207
31167
|
const [otp, setOtp] = useState("");
|
|
31208
31168
|
const [step, setStep] = useState("email");
|
|
31209
31169
|
const [loading, setLoading] = useState(false);
|
|
31170
|
+
const [devLoginLoading, setDevLoginLoading] = useState(false);
|
|
31210
31171
|
const [error, setError] = useState(null);
|
|
31211
31172
|
const [countdown, setCountdown] = useState(0);
|
|
31212
31173
|
const supabase = useSupabase();
|
|
@@ -31270,6 +31231,25 @@ var LoginPage = ({
|
|
|
31270
31231
|
startCountdown();
|
|
31271
31232
|
}
|
|
31272
31233
|
};
|
|
31234
|
+
const handleDevTestLogin = async () => {
|
|
31235
|
+
if (!onDevTestLogin) {
|
|
31236
|
+
return;
|
|
31237
|
+
}
|
|
31238
|
+
setDevLoginLoading(true);
|
|
31239
|
+
setError(null);
|
|
31240
|
+
try {
|
|
31241
|
+
const result = await onDevTestLogin();
|
|
31242
|
+
const nextError = typeof result === "object" && result !== null && "error" in result ? result.error : null;
|
|
31243
|
+
if (typeof nextError === "string" && nextError.trim()) {
|
|
31244
|
+
setError(nextError);
|
|
31245
|
+
}
|
|
31246
|
+
} catch (err) {
|
|
31247
|
+
console.error("Dev test login failed:", err);
|
|
31248
|
+
setError("Dev test login unavailable.");
|
|
31249
|
+
} finally {
|
|
31250
|
+
setDevLoginLoading(false);
|
|
31251
|
+
}
|
|
31252
|
+
};
|
|
31273
31253
|
return /* @__PURE__ */ jsx("div", { className: "min-h-screen flex items-center justify-center bg-gradient-to-br from-slate-50 to-slate-100", children: /* @__PURE__ */ jsxs("div", { className: "max-w-md w-full mx-4", children: [
|
|
31274
31254
|
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-2xl shadow-xl border border-slate-200 p-8", children: [
|
|
31275
31255
|
/* @__PURE__ */ jsxs("div", { className: "text-center mb-8", children: [
|
|
@@ -31310,7 +31290,7 @@ var LoginPage = ({
|
|
|
31310
31290
|
"button",
|
|
31311
31291
|
{
|
|
31312
31292
|
type: "submit",
|
|
31313
|
-
disabled: loading,
|
|
31293
|
+
disabled: loading || devLoginLoading,
|
|
31314
31294
|
className: "w-full py-3 px-4 bg-slate-900 hover:bg-slate-800 focus:ring-2 focus:ring-slate-600 focus:ring-offset-2 text-white font-medium rounded-xl transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center",
|
|
31315
31295
|
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31316
31296
|
/* @__PURE__ */ jsxs("svg", { className: "animate-spin -ml-1 mr-3 h-4 w-4 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
@@ -31320,7 +31300,31 @@ var LoginPage = ({
|
|
|
31320
31300
|
"Sending..."
|
|
31321
31301
|
] }) : "Continue with Email"
|
|
31322
31302
|
}
|
|
31323
|
-
)
|
|
31303
|
+
),
|
|
31304
|
+
showDevTestLogin && onDevTestLogin ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
31305
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
31306
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-slate-200" }),
|
|
31307
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium uppercase tracking-[0.2em] text-slate-400", children: "Local Dev" }),
|
|
31308
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-slate-200" })
|
|
31309
|
+
] }),
|
|
31310
|
+
/* @__PURE__ */ jsx(
|
|
31311
|
+
"button",
|
|
31312
|
+
{
|
|
31313
|
+
type: "button",
|
|
31314
|
+
disabled: loading || devLoginLoading,
|
|
31315
|
+
onClick: () => void handleDevTestLogin(),
|
|
31316
|
+
className: "w-full py-3 px-4 bg-white hover:bg-slate-50 focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 text-slate-700 font-medium rounded-xl border border-slate-200 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center",
|
|
31317
|
+
children: devLoginLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31318
|
+
/* @__PURE__ */ jsxs("svg", { className: "animate-spin -ml-1 mr-3 h-4 w-4 text-slate-700", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
31319
|
+
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
31320
|
+
/* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
|
|
31321
|
+
] }),
|
|
31322
|
+
"Signing In..."
|
|
31323
|
+
] }) : devTestLoginLabel
|
|
31324
|
+
}
|
|
31325
|
+
),
|
|
31326
|
+
/* @__PURE__ */ jsx("p", { className: "text-center text-xs text-slate-500", children: "Localhost-only convenience login for the shared test account." })
|
|
31327
|
+
] }) : null
|
|
31324
31328
|
] }) : /* @__PURE__ */ jsxs("form", { className: "space-y-6", onSubmit: handleVerifyOTP, children: [
|
|
31325
31329
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
31326
31330
|
/* @__PURE__ */ jsx("label", { htmlFor: "otp", className: "block text-sm font-medium text-slate-700 mb-2 text-center", children: "Enter the 6-digit code sent to" }),
|
|
@@ -31345,7 +31349,7 @@ var LoginPage = ({
|
|
|
31345
31349
|
"button",
|
|
31346
31350
|
{
|
|
31347
31351
|
type: "submit",
|
|
31348
|
-
disabled: loading || otp.length !== 6,
|
|
31352
|
+
disabled: loading || devLoginLoading || otp.length !== 6,
|
|
31349
31353
|
className: "w-full py-3 px-4 bg-slate-900 hover:bg-slate-800 focus:ring-2 focus:ring-slate-600 focus:ring-offset-2 text-white font-medium rounded-xl transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center",
|
|
31350
31354
|
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31351
31355
|
/* @__PURE__ */ jsxs("svg", { className: "animate-spin -ml-1 mr-3 h-4 w-4 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
@@ -32186,31 +32190,35 @@ var LineChartComponent = ({
|
|
|
32186
32190
|
...restOfChartProps
|
|
32187
32191
|
}) => {
|
|
32188
32192
|
const containerRef = React141__default.useRef(null);
|
|
32189
|
-
const [
|
|
32190
|
-
const
|
|
32191
|
-
const { formatNumber } = useFormatNumber();
|
|
32193
|
+
const [dimensions, setDimensions] = React141__default.useState({ width: 0, height: 0 });
|
|
32194
|
+
const [hasValidData, setHasValidData] = React141__default.useState(false);
|
|
32192
32195
|
React141__default.useEffect(() => {
|
|
32193
|
-
const
|
|
32194
|
-
|
|
32195
|
-
const
|
|
32196
|
-
|
|
32197
|
-
|
|
32198
|
-
|
|
32199
|
-
|
|
32200
|
-
|
|
32201
|
-
checkContainerDimensions();
|
|
32202
|
-
const resizeObserver = new ResizeObserver(checkContainerDimensions);
|
|
32203
|
-
if (containerRef.current) {
|
|
32204
|
-
resizeObserver.observe(containerRef.current);
|
|
32196
|
+
const currentHasValidData = data && lines && lines.length > 0 && data.some(
|
|
32197
|
+
(item) => lines.some((line) => {
|
|
32198
|
+
const val = item[line.dataKey];
|
|
32199
|
+
return typeof val === "number" && val > 0;
|
|
32200
|
+
})
|
|
32201
|
+
);
|
|
32202
|
+
if (currentHasValidData && !hasValidData) {
|
|
32203
|
+
setHasValidData(true);
|
|
32205
32204
|
}
|
|
32206
|
-
|
|
32207
|
-
|
|
32208
|
-
|
|
32209
|
-
|
|
32210
|
-
|
|
32211
|
-
|
|
32212
|
-
|
|
32205
|
+
}, [data, lines, hasValidData]);
|
|
32206
|
+
React141__default.useEffect(() => {
|
|
32207
|
+
if (!containerRef.current) return;
|
|
32208
|
+
const observer = new ResizeObserver((entries) => {
|
|
32209
|
+
const entry = entries[0];
|
|
32210
|
+
if (entry) {
|
|
32211
|
+
setDimensions({
|
|
32212
|
+
width: entry.contentRect.width,
|
|
32213
|
+
height: entry.contentRect.height
|
|
32214
|
+
});
|
|
32215
|
+
}
|
|
32216
|
+
});
|
|
32217
|
+
observer.observe(containerRef.current);
|
|
32218
|
+
return () => observer.disconnect();
|
|
32213
32219
|
}, []);
|
|
32220
|
+
const themeConfig = useThemeConfig();
|
|
32221
|
+
const { formatNumber } = useFormatNumber();
|
|
32214
32222
|
const yAxisTickFormatter = (value) => {
|
|
32215
32223
|
return `${formatNumber(value)}${yAxisUnit || ""}`;
|
|
32216
32224
|
};
|
|
@@ -32232,57 +32240,71 @@ var LineChartComponent = ({
|
|
|
32232
32240
|
const gridStrokeColor = themeConfig?.gray?.["300"] || "#ccc";
|
|
32233
32241
|
const axisTickFillColor = themeConfig?.gray?.["600"] || "#666";
|
|
32234
32242
|
const axisStrokeColor = themeConfig?.gray?.["400"] || "#999";
|
|
32235
|
-
const
|
|
32236
|
-
|
|
32237
|
-
|
|
32238
|
-
|
|
32239
|
-
|
|
32240
|
-
|
|
32241
|
-
|
|
32242
|
-
|
|
32243
|
-
|
|
32244
|
-
stroke:
|
|
32245
|
-
|
|
32246
|
-
|
|
32247
|
-
|
|
32248
|
-
|
|
32249
|
-
|
|
32250
|
-
|
|
32251
|
-
|
|
32252
|
-
|
|
32253
|
-
|
|
32254
|
-
|
|
32255
|
-
|
|
32256
|
-
|
|
32257
|
-
|
|
32258
|
-
|
|
32259
|
-
|
|
32260
|
-
|
|
32261
|
-
|
|
32262
|
-
|
|
32263
|
-
|
|
32264
|
-
|
|
32265
|
-
|
|
32266
|
-
|
|
32267
|
-
|
|
32268
|
-
|
|
32269
|
-
|
|
32270
|
-
|
|
32271
|
-
|
|
32272
|
-
|
|
32273
|
-
|
|
32274
|
-
|
|
32275
|
-
|
|
32276
|
-
|
|
32277
|
-
|
|
32278
|
-
|
|
32279
|
-
|
|
32280
|
-
|
|
32281
|
-
|
|
32282
|
-
|
|
32283
|
-
|
|
32284
|
-
|
|
32285
|
-
|
|
32243
|
+
const renderChartContent = (chartWidth, chartHeight) => /* @__PURE__ */ jsxs(
|
|
32244
|
+
LineChart$1,
|
|
32245
|
+
{
|
|
32246
|
+
width: chartWidth,
|
|
32247
|
+
height: chartHeight,
|
|
32248
|
+
data,
|
|
32249
|
+
margin: { top: 5, right: 30, left: 20, bottom: 20 },
|
|
32250
|
+
...restOfChartProps,
|
|
32251
|
+
children: [
|
|
32252
|
+
showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStrokeColor }),
|
|
32253
|
+
/* @__PURE__ */ jsx(
|
|
32254
|
+
XAxis,
|
|
32255
|
+
{
|
|
32256
|
+
dataKey: xAxisDataKey,
|
|
32257
|
+
label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -10 } : void 0,
|
|
32258
|
+
tickFormatter: xAxisTickFormatter,
|
|
32259
|
+
tick: { fontSize: 12, fill: axisTickFillColor },
|
|
32260
|
+
stroke: axisStrokeColor
|
|
32261
|
+
}
|
|
32262
|
+
),
|
|
32263
|
+
/* @__PURE__ */ jsx(
|
|
32264
|
+
YAxis,
|
|
32265
|
+
{
|
|
32266
|
+
label: yAxisLabel ? { value: yAxisLabel, angle: -90, position: "insideLeft" } : void 0,
|
|
32267
|
+
tickFormatter: yAxisTickFormatter,
|
|
32268
|
+
domain: yAxisDomain,
|
|
32269
|
+
tick: { fontSize: 12, fill: axisTickFillColor },
|
|
32270
|
+
stroke: axisStrokeColor
|
|
32271
|
+
}
|
|
32272
|
+
),
|
|
32273
|
+
showTooltip && /* @__PURE__ */ jsx(
|
|
32274
|
+
Tooltip,
|
|
32275
|
+
{
|
|
32276
|
+
formatter: tooltipFormatter || defaultTooltipFormatter,
|
|
32277
|
+
labelFormatter: tooltipLabelFormatter,
|
|
32278
|
+
itemStyle: { color: "#111827" },
|
|
32279
|
+
cursor: { strokeDasharray: "3 3" }
|
|
32280
|
+
}
|
|
32281
|
+
),
|
|
32282
|
+
showLegend && /* @__PURE__ */ jsx(Legend, { payload: legendPayload }),
|
|
32283
|
+
lines.map((lineConfig, index) => {
|
|
32284
|
+
const lineProps = {
|
|
32285
|
+
...lineConfig,
|
|
32286
|
+
key: lineConfig.dataKey,
|
|
32287
|
+
type: lineConfig.type || "monotone",
|
|
32288
|
+
stroke: lineConfig.stroke || defaultColors[index % defaultColors.length],
|
|
32289
|
+
activeDot: lineConfig.activeDot !== void 0 ? lineConfig.activeDot : { r: 6 },
|
|
32290
|
+
isAnimationActive: true,
|
|
32291
|
+
animationDuration: 1500,
|
|
32292
|
+
animationBegin: 300
|
|
32293
|
+
};
|
|
32294
|
+
return /* @__PURE__ */ jsx(Line, { ...lineProps, children: lineConfig.labelList && /* @__PURE__ */ jsx(
|
|
32295
|
+
LabelList,
|
|
32296
|
+
{
|
|
32297
|
+
dataKey: lineConfig.dataKey,
|
|
32298
|
+
position: "top",
|
|
32299
|
+
formatter: (value) => formatNumber(value),
|
|
32300
|
+
...typeof lineConfig.labelList === "object" ? lineConfig.labelList : {}
|
|
32301
|
+
}
|
|
32302
|
+
) });
|
|
32303
|
+
})
|
|
32304
|
+
]
|
|
32305
|
+
},
|
|
32306
|
+
hasValidData ? "valid" : "empty"
|
|
32307
|
+
);
|
|
32286
32308
|
if (responsive) {
|
|
32287
32309
|
return /* @__PURE__ */ jsx(
|
|
32288
32310
|
"div",
|
|
@@ -32290,11 +32312,20 @@ var LineChartComponent = ({
|
|
|
32290
32312
|
ref: containerRef,
|
|
32291
32313
|
className: clsx(fillContainer ? "w-full h-full" : "w-full h-auto", className),
|
|
32292
32314
|
style: fillContainer ? { height: "100%", minHeight: "50px", minWidth: "100px" } : { aspectRatio: `${aspect}/1`, minHeight: "50px", minWidth: "100px" },
|
|
32293
|
-
children:
|
|
32315
|
+
children: /* @__PURE__ */ jsx(
|
|
32316
|
+
motion.div,
|
|
32317
|
+
{
|
|
32318
|
+
initial: { opacity: 0 },
|
|
32319
|
+
animate: { opacity: 1 },
|
|
32320
|
+
transition: { duration: 0.5 },
|
|
32321
|
+
className: "w-full h-full",
|
|
32322
|
+
children: dimensions.width > 0 && dimensions.height > 0 && renderChartContent(dimensions.width, dimensions.height)
|
|
32323
|
+
}
|
|
32324
|
+
)
|
|
32294
32325
|
}
|
|
32295
32326
|
);
|
|
32296
32327
|
}
|
|
32297
|
-
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children:
|
|
32328
|
+
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
|
|
32298
32329
|
};
|
|
32299
32330
|
var LineChart = React141__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
32300
32331
|
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)) {
|
|
@@ -32562,14 +32593,35 @@ var CycleTimeOverTimeChart = ({
|
|
|
32562
32593
|
}) => {
|
|
32563
32594
|
const MAX_DATA_POINTS = 40;
|
|
32564
32595
|
const containerRef = React141__default.useRef(null);
|
|
32565
|
-
const [
|
|
32566
|
-
const
|
|
32596
|
+
const [dimensions, setDimensions] = React141__default.useState({ width: 0, height: 0 });
|
|
32597
|
+
const [hasValidData, setHasValidData] = React141__default.useState(false);
|
|
32598
|
+
React141__default.useEffect(() => {
|
|
32599
|
+
const currentHasValidData = data && data.some((val) => val !== null && val > 0);
|
|
32600
|
+
if (currentHasValidData && !hasValidData) {
|
|
32601
|
+
setHasValidData(true);
|
|
32602
|
+
}
|
|
32603
|
+
}, [data, hasValidData]);
|
|
32604
|
+
React141__default.useEffect(() => {
|
|
32605
|
+
if (!containerRef.current) return;
|
|
32606
|
+
const observer = new ResizeObserver((entries) => {
|
|
32607
|
+
const entry = entries[0];
|
|
32608
|
+
if (entry) {
|
|
32609
|
+
setDimensions({
|
|
32610
|
+
width: entry.contentRect.width,
|
|
32611
|
+
height: entry.contentRect.height
|
|
32612
|
+
});
|
|
32613
|
+
}
|
|
32614
|
+
});
|
|
32615
|
+
observer.observe(containerRef.current);
|
|
32616
|
+
return () => observer.disconnect();
|
|
32617
|
+
}, []);
|
|
32618
|
+
const parseTimeToMinutes4 = (value) => {
|
|
32567
32619
|
const [hours, minutes] = value.split(":").map(Number);
|
|
32568
32620
|
if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return 0;
|
|
32569
32621
|
return hours * 60 + minutes;
|
|
32570
32622
|
};
|
|
32571
32623
|
const formatHourLabel = (slotIndex) => {
|
|
32572
|
-
const baseMinutes =
|
|
32624
|
+
const baseMinutes = parseTimeToMinutes4(shiftStart);
|
|
32573
32625
|
const absoluteMinutes = baseMinutes + slotIndex * 60;
|
|
32574
32626
|
const hour24 = Math.floor(absoluteMinutes % (24 * 60) / 60);
|
|
32575
32627
|
const ampm = hour24 >= 12 ? "PM" : "AM";
|
|
@@ -32588,52 +32640,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32588
32640
|
const displayData = getDisplayData(data);
|
|
32589
32641
|
const DURATION = displayData.length;
|
|
32590
32642
|
const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
|
|
32591
|
-
const [animatedDatasetKey, setAnimatedDatasetKey] = React141__default.useState(null);
|
|
32592
|
-
const shouldAnimate = animatedDatasetKey !== effectiveDatasetKey;
|
|
32593
|
-
const handleAnimationEnd = React141__default.useCallback(() => {
|
|
32594
|
-
setAnimatedDatasetKey((currentValue) => currentValue === effectiveDatasetKey ? currentValue : effectiveDatasetKey);
|
|
32595
|
-
}, [effectiveDatasetKey]);
|
|
32596
32643
|
const finalData = displayData;
|
|
32597
|
-
React141__default.useEffect(() => {
|
|
32598
|
-
const containerNode = containerRef.current;
|
|
32599
|
-
if (!containerNode) {
|
|
32600
|
-
setContainerReady(true);
|
|
32601
|
-
return void 0;
|
|
32602
|
-
}
|
|
32603
|
-
let frameId = null;
|
|
32604
|
-
let resizeObserver = null;
|
|
32605
|
-
const checkContainerDimensions = () => {
|
|
32606
|
-
const rect = containerNode.getBoundingClientRect();
|
|
32607
|
-
const isReady = rect.width > 0 && rect.height > 0;
|
|
32608
|
-
if (isReady) {
|
|
32609
|
-
setContainerReady(true);
|
|
32610
|
-
}
|
|
32611
|
-
return isReady;
|
|
32612
|
-
};
|
|
32613
|
-
if (checkContainerDimensions()) {
|
|
32614
|
-
return void 0;
|
|
32615
|
-
}
|
|
32616
|
-
frameId = window.requestAnimationFrame(() => {
|
|
32617
|
-
checkContainerDimensions();
|
|
32618
|
-
});
|
|
32619
|
-
if (typeof ResizeObserver !== "undefined") {
|
|
32620
|
-
resizeObserver = new ResizeObserver(() => {
|
|
32621
|
-
if (checkContainerDimensions() && resizeObserver) {
|
|
32622
|
-
resizeObserver.disconnect();
|
|
32623
|
-
resizeObserver = null;
|
|
32624
|
-
}
|
|
32625
|
-
});
|
|
32626
|
-
resizeObserver.observe(containerNode);
|
|
32627
|
-
} else {
|
|
32628
|
-
setContainerReady(true);
|
|
32629
|
-
}
|
|
32630
|
-
return () => {
|
|
32631
|
-
if (frameId !== null) {
|
|
32632
|
-
window.cancelAnimationFrame(frameId);
|
|
32633
|
-
}
|
|
32634
|
-
resizeObserver?.disconnect();
|
|
32635
|
-
};
|
|
32636
|
-
}, []);
|
|
32637
32644
|
const labelInterval = React141__default.useMemo(() => {
|
|
32638
32645
|
if (xAxisMode === "hourly") {
|
|
32639
32646
|
return Math.max(1, Math.ceil(DURATION / 8));
|
|
@@ -32841,144 +32848,154 @@ var CycleTimeOverTimeChart = ({
|
|
|
32841
32848
|
return /* @__PURE__ */ jsxs(
|
|
32842
32849
|
"div",
|
|
32843
32850
|
{
|
|
32844
|
-
ref: containerRef,
|
|
32845
32851
|
className: `w-full h-full min-w-0 flex flex-col relative pb-2 ${className}`,
|
|
32846
32852
|
style: { minHeight: "200px", minWidth: 0 },
|
|
32847
32853
|
children: [
|
|
32848
32854
|
renderLegend(),
|
|
32849
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 w-full",
|
|
32850
|
-
|
|
32855
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 w-full", ref: containerRef, children: /* @__PURE__ */ jsx(
|
|
32856
|
+
motion.div,
|
|
32851
32857
|
{
|
|
32852
|
-
|
|
32853
|
-
|
|
32854
|
-
|
|
32855
|
-
|
|
32856
|
-
|
|
32857
|
-
|
|
32858
|
-
|
|
32859
|
-
|
|
32860
|
-
|
|
32861
|
-
|
|
32862
|
-
|
|
32863
|
-
|
|
32864
|
-
|
|
32865
|
-
|
|
32866
|
-
|
|
32867
|
-
angle: xAxisMode === "hourly" ? 0 : -30,
|
|
32868
|
-
textAnchor: xAxisMode === "hourly" ? "middle" : "end",
|
|
32869
|
-
tickMargin: xAxisMode === "hourly" ? 8 : 15,
|
|
32870
|
-
height: xAxisMode === "hourly" ? 40 : 60
|
|
32871
|
-
}
|
|
32872
|
-
),
|
|
32873
|
-
/* @__PURE__ */ jsx(
|
|
32874
|
-
YAxis,
|
|
32875
|
-
{
|
|
32876
|
-
tickMargin: 8,
|
|
32877
|
-
width: 45,
|
|
32878
|
-
yAxisId: "cycle",
|
|
32879
|
-
domain: ["auto", "auto"],
|
|
32880
|
-
ticks: [0, idealCycleTime, ...Array.from({ length: 4 }, (_, i) => (i + 1) * Math.ceil(idealCycleTime / 2))].sort((a, b) => a - b),
|
|
32881
|
-
tickFormatter: (value) => String(value),
|
|
32882
|
-
tick: (props) => {
|
|
32883
|
-
const { x, y, payload } = props;
|
|
32884
|
-
const displayValue = typeof payload.value === "number" ? payload.value.toFixed(1) : String(payload.value);
|
|
32885
|
-
return /* @__PURE__ */ jsx("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ jsx(
|
|
32886
|
-
"text",
|
|
32887
|
-
{
|
|
32888
|
-
x: 0,
|
|
32889
|
-
y: 0,
|
|
32890
|
-
dy: 4,
|
|
32891
|
-
textAnchor: "end",
|
|
32892
|
-
fill: payload.value === idealCycleTime ? "#E34329" : "#666",
|
|
32893
|
-
fontSize: 12,
|
|
32894
|
-
fontWeight: payload.value === idealCycleTime ? "bold" : "normal",
|
|
32895
|
-
children: displayValue
|
|
32896
|
-
},
|
|
32897
|
-
`tick-${payload.value}-${x}-${y}`
|
|
32898
|
-
) });
|
|
32899
|
-
}
|
|
32900
|
-
}
|
|
32901
|
-
),
|
|
32902
|
-
showIdleTime && /* @__PURE__ */ jsx(
|
|
32903
|
-
YAxis,
|
|
32904
|
-
{
|
|
32905
|
-
yAxisId: "idle",
|
|
32906
|
-
orientation: "right",
|
|
32907
|
-
tickMargin: 8,
|
|
32908
|
-
width: 35,
|
|
32909
|
-
domain: [0, 60],
|
|
32910
|
-
tickFormatter: (value) => `${value}m`,
|
|
32911
|
-
tick: { fontSize: 11, fill: "#f59e0b" },
|
|
32912
|
-
axisLine: false,
|
|
32913
|
-
tickLine: false
|
|
32914
|
-
}
|
|
32915
|
-
),
|
|
32916
|
-
/* @__PURE__ */ jsx(
|
|
32917
|
-
Tooltip,
|
|
32918
|
-
{
|
|
32919
|
-
cursor: { stroke: "#E5E7EB", strokeWidth: 1 },
|
|
32920
|
-
content: renderChartTooltip,
|
|
32921
|
-
animationDuration: 200
|
|
32922
|
-
}
|
|
32923
|
-
),
|
|
32924
|
-
/* @__PURE__ */ jsx(
|
|
32925
|
-
ReferenceLine,
|
|
32926
|
-
{
|
|
32927
|
-
y: idealCycleTime,
|
|
32928
|
-
yAxisId: "cycle",
|
|
32929
|
-
stroke: "#E34329",
|
|
32930
|
-
strokeDasharray: "3 3",
|
|
32931
|
-
strokeWidth: 2,
|
|
32932
|
-
label: {
|
|
32933
|
-
position: "right",
|
|
32934
|
-
value: `${idealCycleTime.toFixed(1)}s`,
|
|
32935
|
-
fill: "#E34329",
|
|
32936
|
-
fontSize: 12,
|
|
32937
|
-
fontWeight: 500
|
|
32938
|
-
}
|
|
32939
|
-
}
|
|
32940
|
-
),
|
|
32941
|
-
/* @__PURE__ */ jsx(
|
|
32942
|
-
Line,
|
|
32943
|
-
{
|
|
32944
|
-
type: "monotone",
|
|
32945
|
-
yAxisId: "cycle",
|
|
32946
|
-
dataKey: "cycleTime",
|
|
32947
|
-
stroke: "#3B82F6",
|
|
32948
|
-
strokeWidth: 2,
|
|
32949
|
-
connectNulls: false,
|
|
32950
|
-
dot: renderCycleDot,
|
|
32951
|
-
activeDot: renderCycleActiveDot,
|
|
32952
|
-
isAnimationActive: shouldAnimate,
|
|
32953
|
-
animationBegin: 0,
|
|
32954
|
-
animationDuration: 1200,
|
|
32955
|
-
animationEasing: "ease-out",
|
|
32956
|
-
onAnimationEnd: handleAnimationEnd
|
|
32957
|
-
},
|
|
32958
|
-
`${effectiveDatasetKey}:cycle`
|
|
32959
|
-
),
|
|
32960
|
-
showIdleTime && /* @__PURE__ */ jsx(
|
|
32961
|
-
Line,
|
|
32962
|
-
{
|
|
32963
|
-
type: "monotone",
|
|
32964
|
-
yAxisId: "idle",
|
|
32965
|
-
dataKey: "idleMinutes",
|
|
32966
|
-
stroke: "#f59e0b",
|
|
32967
|
-
strokeWidth: 2,
|
|
32968
|
-
strokeDasharray: "4 4",
|
|
32969
|
-
connectNulls: false,
|
|
32970
|
-
dot: renderIdleDot,
|
|
32971
|
-
activeDot: renderIdleActiveDot,
|
|
32972
|
-
isAnimationActive: shouldAnimate,
|
|
32973
|
-
animationBegin: 0,
|
|
32974
|
-
animationDuration: 1200,
|
|
32975
|
-
animationEasing: "ease-out"
|
|
32858
|
+
initial: { opacity: 0 },
|
|
32859
|
+
animate: { opacity: 1 },
|
|
32860
|
+
transition: { duration: 0.5 },
|
|
32861
|
+
className: "w-full h-full",
|
|
32862
|
+
children: dimensions.width > 0 && dimensions.height > 0 && /* @__PURE__ */ jsxs(
|
|
32863
|
+
LineChart$1,
|
|
32864
|
+
{
|
|
32865
|
+
width: dimensions.width,
|
|
32866
|
+
height: dimensions.height,
|
|
32867
|
+
data: chartData,
|
|
32868
|
+
margin: {
|
|
32869
|
+
top: 5,
|
|
32870
|
+
right: 30,
|
|
32871
|
+
bottom: 25,
|
|
32872
|
+
left: 10
|
|
32976
32873
|
},
|
|
32977
|
-
|
|
32978
|
-
|
|
32979
|
-
|
|
32874
|
+
children: [
|
|
32875
|
+
/* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", vertical: false }),
|
|
32876
|
+
/* @__PURE__ */ jsx(
|
|
32877
|
+
XAxis,
|
|
32878
|
+
{
|
|
32879
|
+
dataKey: "label",
|
|
32880
|
+
tick: { fontSize: 11 },
|
|
32881
|
+
interval: 0,
|
|
32882
|
+
angle: xAxisMode === "hourly" ? 0 : -30,
|
|
32883
|
+
textAnchor: xAxisMode === "hourly" ? "middle" : "end",
|
|
32884
|
+
tickMargin: xAxisMode === "hourly" ? 8 : 15,
|
|
32885
|
+
height: xAxisMode === "hourly" ? 40 : 60
|
|
32886
|
+
}
|
|
32887
|
+
),
|
|
32888
|
+
/* @__PURE__ */ jsx(
|
|
32889
|
+
YAxis,
|
|
32890
|
+
{
|
|
32891
|
+
tickMargin: 8,
|
|
32892
|
+
width: 45,
|
|
32893
|
+
yAxisId: "cycle",
|
|
32894
|
+
domain: ["auto", "auto"],
|
|
32895
|
+
ticks: [0, idealCycleTime, ...Array.from({ length: 4 }, (_, i) => (i + 1) * Math.ceil(idealCycleTime / 2))].sort((a, b) => a - b),
|
|
32896
|
+
tickFormatter: (value) => String(value),
|
|
32897
|
+
tick: (props) => {
|
|
32898
|
+
const { x, y, payload } = props;
|
|
32899
|
+
const displayValue = typeof payload.value === "number" ? payload.value.toFixed(1) : String(payload.value);
|
|
32900
|
+
return /* @__PURE__ */ jsx("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ jsx(
|
|
32901
|
+
"text",
|
|
32902
|
+
{
|
|
32903
|
+
x: 0,
|
|
32904
|
+
y: 0,
|
|
32905
|
+
dy: 4,
|
|
32906
|
+
textAnchor: "end",
|
|
32907
|
+
fill: payload.value === idealCycleTime ? "#E34329" : "#666",
|
|
32908
|
+
fontSize: 12,
|
|
32909
|
+
fontWeight: payload.value === idealCycleTime ? "bold" : "normal",
|
|
32910
|
+
children: displayValue
|
|
32911
|
+
},
|
|
32912
|
+
`tick-${payload.value}-${x}-${y}`
|
|
32913
|
+
) });
|
|
32914
|
+
}
|
|
32915
|
+
}
|
|
32916
|
+
),
|
|
32917
|
+
showIdleTime && /* @__PURE__ */ jsx(
|
|
32918
|
+
YAxis,
|
|
32919
|
+
{
|
|
32920
|
+
yAxisId: "idle",
|
|
32921
|
+
orientation: "right",
|
|
32922
|
+
tickMargin: 8,
|
|
32923
|
+
width: 35,
|
|
32924
|
+
domain: [0, 60],
|
|
32925
|
+
tickFormatter: (value) => `${value}m`,
|
|
32926
|
+
tick: { fontSize: 11, fill: "#f59e0b" },
|
|
32927
|
+
axisLine: false,
|
|
32928
|
+
tickLine: false
|
|
32929
|
+
}
|
|
32930
|
+
),
|
|
32931
|
+
/* @__PURE__ */ jsx(
|
|
32932
|
+
Tooltip,
|
|
32933
|
+
{
|
|
32934
|
+
cursor: { stroke: "#E5E7EB", strokeWidth: 1 },
|
|
32935
|
+
content: renderChartTooltip,
|
|
32936
|
+
animationDuration: 200
|
|
32937
|
+
}
|
|
32938
|
+
),
|
|
32939
|
+
/* @__PURE__ */ jsx(
|
|
32940
|
+
ReferenceLine,
|
|
32941
|
+
{
|
|
32942
|
+
y: idealCycleTime,
|
|
32943
|
+
yAxisId: "cycle",
|
|
32944
|
+
stroke: "#E34329",
|
|
32945
|
+
strokeDasharray: "3 3",
|
|
32946
|
+
strokeWidth: 2,
|
|
32947
|
+
label: {
|
|
32948
|
+
position: "right",
|
|
32949
|
+
value: `${idealCycleTime.toFixed(1)}s`,
|
|
32950
|
+
fill: "#E34329",
|
|
32951
|
+
fontSize: 12,
|
|
32952
|
+
fontWeight: 500
|
|
32953
|
+
}
|
|
32954
|
+
}
|
|
32955
|
+
),
|
|
32956
|
+
/* @__PURE__ */ jsx(
|
|
32957
|
+
Line,
|
|
32958
|
+
{
|
|
32959
|
+
type: "monotone",
|
|
32960
|
+
yAxisId: "cycle",
|
|
32961
|
+
dataKey: "cycleTime",
|
|
32962
|
+
stroke: "#3B82F6",
|
|
32963
|
+
strokeWidth: 2,
|
|
32964
|
+
connectNulls: false,
|
|
32965
|
+
dot: renderCycleDot,
|
|
32966
|
+
activeDot: renderCycleActiveDot,
|
|
32967
|
+
isAnimationActive: true,
|
|
32968
|
+
animationBegin: 300,
|
|
32969
|
+
animationDuration: 1500,
|
|
32970
|
+
animationEasing: "ease-out"
|
|
32971
|
+
},
|
|
32972
|
+
`${effectiveDatasetKey}:cycle`
|
|
32973
|
+
),
|
|
32974
|
+
showIdleTime && /* @__PURE__ */ jsx(
|
|
32975
|
+
Line,
|
|
32976
|
+
{
|
|
32977
|
+
type: "monotone",
|
|
32978
|
+
yAxisId: "idle",
|
|
32979
|
+
dataKey: "idleMinutes",
|
|
32980
|
+
stroke: "#f59e0b",
|
|
32981
|
+
strokeWidth: 2,
|
|
32982
|
+
strokeDasharray: "4 4",
|
|
32983
|
+
connectNulls: false,
|
|
32984
|
+
dot: renderIdleDot,
|
|
32985
|
+
activeDot: renderIdleActiveDot,
|
|
32986
|
+
isAnimationActive: true,
|
|
32987
|
+
animationBegin: 300,
|
|
32988
|
+
animationDuration: 1500,
|
|
32989
|
+
animationEasing: "ease-out"
|
|
32990
|
+
},
|
|
32991
|
+
`${effectiveDatasetKey}:idle`
|
|
32992
|
+
)
|
|
32993
|
+
]
|
|
32994
|
+
},
|
|
32995
|
+
hasValidData ? "valid" : "empty"
|
|
32996
|
+
)
|
|
32980
32997
|
}
|
|
32981
|
-
) })
|
|
32998
|
+
) })
|
|
32982
32999
|
]
|
|
32983
33000
|
}
|
|
32984
33001
|
);
|
|
@@ -33828,10 +33845,10 @@ var HourlyOutputChart = React141__default.memo(HourlyOutputChartComponent, (prev
|
|
|
33828
33845
|
HourlyOutputChart.displayName = "HourlyOutputChart";
|
|
33829
33846
|
|
|
33830
33847
|
// src/components/dashboard/grid/videoGridMetricUtils.ts
|
|
33831
|
-
var VIDEO_GRID_LEGEND_LABEL = "
|
|
33848
|
+
var VIDEO_GRID_LEGEND_LABEL = "7 Minute Efficiency";
|
|
33832
33849
|
var MAP_GRID_LEGEND_LABEL = "Efficiency";
|
|
33833
|
-
var MIXED_VIDEO_GRID_LEGEND_LABEL = "
|
|
33834
|
-
var
|
|
33850
|
+
var MIXED_VIDEO_GRID_LEGEND_LABEL = "Efficiency";
|
|
33851
|
+
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
33835
33852
|
var isVideoGridRecentFlowEnabled = (workspace) => isRecentFlowVideoGridMetricMode(
|
|
33836
33853
|
workspace.video_grid_metric_mode,
|
|
33837
33854
|
workspace.assembly_enabled === true
|
|
@@ -33840,11 +33857,11 @@ var isVideoGridWipGated = (workspace) => isWipGatedVideoGridMetricMode(
|
|
|
33840
33857
|
workspace.video_grid_metric_mode,
|
|
33841
33858
|
workspace.assembly_enabled === true
|
|
33842
33859
|
);
|
|
33843
|
-
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) &&
|
|
33860
|
+
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) && isFiniteNumber(workspace.recent_flow_percent);
|
|
33844
33861
|
var isVideoGridRecentFlowUnavailable = (workspace) => isVideoGridRecentFlowEnabled(workspace) && !hasVideoGridRecentFlow(workspace);
|
|
33845
33862
|
var getVideoGridMetricValue = (workspace) => {
|
|
33846
33863
|
const recentFlowPercent = workspace.recent_flow_percent;
|
|
33847
|
-
if (hasVideoGridRecentFlow(workspace) &&
|
|
33864
|
+
if (hasVideoGridRecentFlow(workspace) && isFiniteNumber(recentFlowPercent)) {
|
|
33848
33865
|
return recentFlowPercent;
|
|
33849
33866
|
}
|
|
33850
33867
|
if (isVideoGridRecentFlowUnavailable(workspace)) {
|
|
@@ -33855,7 +33872,7 @@ var getVideoGridMetricValue = (workspace) => {
|
|
|
33855
33872
|
var hasIncomingWipMapping = (workspace) => Boolean(workspace.incoming_wip_buffer_name);
|
|
33856
33873
|
var getVideoGridBaseColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
33857
33874
|
const metricValue = getVideoGridMetricValue(workspace);
|
|
33858
|
-
if (!
|
|
33875
|
+
if (!isFiniteNumber(metricValue)) {
|
|
33859
33876
|
return "neutral";
|
|
33860
33877
|
}
|
|
33861
33878
|
return getEfficiencyColor(metricValue, legend);
|
|
@@ -33870,7 +33887,7 @@ var isLowWipGreenOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
|
33870
33887
|
if (!hasIncomingWipMapping(workspace)) {
|
|
33871
33888
|
return false;
|
|
33872
33889
|
}
|
|
33873
|
-
return
|
|
33890
|
+
return isFiniteNumber(workspace.incoming_wip_current) && workspace.incoming_wip_current <= 1;
|
|
33874
33891
|
};
|
|
33875
33892
|
var toMinuteBucket = (minuteBucket) => Number.isFinite(minuteBucket) ? Math.floor(minuteBucket) : Math.floor(Date.now() / 6e4);
|
|
33876
33893
|
var getEffectiveFlowMinuteBucket = (workspace) => {
|
|
@@ -33912,7 +33929,7 @@ var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) =>
|
|
|
33912
33929
|
if (!hasIncomingWipMapping(workspace)) {
|
|
33913
33930
|
return baseColor;
|
|
33914
33931
|
}
|
|
33915
|
-
if (!
|
|
33932
|
+
if (!isFiniteNumber(workspace.incoming_wip_current)) {
|
|
33916
33933
|
return "neutral";
|
|
33917
33934
|
}
|
|
33918
33935
|
if (isLowWipGreenOverride(workspace, legend)) {
|
|
@@ -34104,7 +34121,7 @@ var VideoCard = React141__default.memo(({
|
|
|
34104
34121
|
}
|
|
34105
34122
|
);
|
|
34106
34123
|
}, (prevProps, nextProps) => {
|
|
34107
|
-
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.
|
|
34124
|
+
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
34108
34125
|
return false;
|
|
34109
34126
|
}
|
|
34110
34127
|
if (prevProps.workspace.workspace_uuid !== nextProps.workspace.workspace_uuid || prevProps.workspace.workspace_name !== nextProps.workspace.workspace_name || prevProps.workspace.line_id !== nextProps.workspace.line_id) {
|
|
@@ -44572,7 +44589,7 @@ var ShiftDisplay = memo$1(({ className, variant = "default", lineId }) => {
|
|
|
44572
44589
|
return null;
|
|
44573
44590
|
}
|
|
44574
44591
|
};
|
|
44575
|
-
const
|
|
44592
|
+
const getShiftIcon2 = (shift) => {
|
|
44576
44593
|
if (shift === "Day") {
|
|
44577
44594
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z", clipRule: "evenodd" }) });
|
|
44578
44595
|
} else {
|
|
@@ -44598,7 +44615,7 @@ var ShiftDisplay = memo$1(({ className, variant = "default", lineId }) => {
|
|
|
44598
44615
|
}
|
|
44599
44616
|
if (variant === "enhanced") {
|
|
44600
44617
|
return /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center gap-2 bg-blue-50 rounded-lg px-3 py-1.5 ${className ?? ""}`, children: [
|
|
44601
|
-
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children:
|
|
44618
|
+
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children: getShiftIcon2(currentShiftText) }),
|
|
44602
44619
|
/* @__PURE__ */ jsxs("span", { className: "text-base font-medium text-blue-800", children: [
|
|
44603
44620
|
currentShiftText,
|
|
44604
44621
|
" Shift"
|
|
@@ -44606,7 +44623,7 @@ var ShiftDisplay = memo$1(({ className, variant = "default", lineId }) => {
|
|
|
44606
44623
|
] });
|
|
44607
44624
|
}
|
|
44608
44625
|
return /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center gap-2 bg-blue-50 rounded-lg px-3 py-1.5 ${className ?? ""}`, children: [
|
|
44609
|
-
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children:
|
|
44626
|
+
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children: getShiftIcon2(currentShiftText) }),
|
|
44610
44627
|
/* @__PURE__ */ jsxs("span", { className: "text-base font-medium text-blue-800", children: [
|
|
44611
44628
|
currentShiftText,
|
|
44612
44629
|
" Shift"
|
|
@@ -47243,7 +47260,7 @@ var LinePdfGenerator = ({
|
|
|
47243
47260
|
doc.setLineWidth(0.8);
|
|
47244
47261
|
doc.line(20, 123, 190, 123);
|
|
47245
47262
|
const hourlyOverviewStartY = 128;
|
|
47246
|
-
const
|
|
47263
|
+
const parseTimeToMinutes4 = (timeStr) => {
|
|
47247
47264
|
const [hours, minutes] = timeStr.split(":");
|
|
47248
47265
|
const hour = parseInt(hours, 10);
|
|
47249
47266
|
const minute = parseInt(minutes || "0", 10);
|
|
@@ -47276,7 +47293,7 @@ var LinePdfGenerator = ({
|
|
|
47276
47293
|
};
|
|
47277
47294
|
};
|
|
47278
47295
|
const getHourlyTimeRanges = (startTimeStr, endTimeStr) => {
|
|
47279
|
-
const startMinutes =
|
|
47296
|
+
const startMinutes = parseTimeToMinutes4(startTimeStr);
|
|
47280
47297
|
if (Number.isNaN(startMinutes)) {
|
|
47281
47298
|
return [];
|
|
47282
47299
|
}
|
|
@@ -47284,7 +47301,7 @@ var LinePdfGenerator = ({
|
|
|
47284
47301
|
const defaultHours = 11;
|
|
47285
47302
|
return Array.from({ length: defaultHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
|
|
47286
47303
|
}
|
|
47287
|
-
const endMinutes =
|
|
47304
|
+
const endMinutes = parseTimeToMinutes4(endTimeStr);
|
|
47288
47305
|
if (Number.isNaN(endMinutes)) {
|
|
47289
47306
|
const fallbackHours = 11;
|
|
47290
47307
|
return Array.from({ length: fallbackHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
|
|
@@ -49053,7 +49070,7 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
49053
49070
|
minute: "2-digit",
|
|
49054
49071
|
hour12: true
|
|
49055
49072
|
});
|
|
49056
|
-
const
|
|
49073
|
+
const parseTimeToMinutes4 = (timeValue) => {
|
|
49057
49074
|
const [hourPart, minutePart] = timeValue.split(":").map(Number);
|
|
49058
49075
|
const hour = Number.isFinite(hourPart) ? hourPart : 0;
|
|
49059
49076
|
const minute = Number.isFinite(minutePart) ? minutePart : 0;
|
|
@@ -49070,8 +49087,8 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
49070
49087
|
const IST_OFFSET_MINUTES = 330;
|
|
49071
49088
|
return Date.UTC(year, month - 1, day, hour, minute) - IST_OFFSET_MINUTES * 60 * 1e3;
|
|
49072
49089
|
};
|
|
49073
|
-
const shiftStartMinutes =
|
|
49074
|
-
const shiftEndMinutes =
|
|
49090
|
+
const shiftStartMinutes = parseTimeToMinutes4(workspace.shift_start);
|
|
49091
|
+
const shiftEndMinutes = parseTimeToMinutes4(workspace.shift_end);
|
|
49075
49092
|
const wrapsMidnight = shiftEndMinutes <= shiftStartMinutes;
|
|
49076
49093
|
const shiftStartUtcMs = toShiftUtcMs(workspace.date, workspace.shift_start);
|
|
49077
49094
|
const shiftEndUtcMs = toShiftUtcMs(workspace.date, workspace.shift_end) + (wrapsMidnight ? 24 * 60 * 60 * 1e3 : 0);
|
|
@@ -51378,7 +51395,7 @@ var DashboardHeader = memo$1(({ lineTitle, className = "", headerControls, lineI
|
|
|
51378
51395
|
const rawName = currentShift.shiftName || "Day";
|
|
51379
51396
|
return rawName.toLowerCase().includes("shift") ? rawName : `${rawName} Shift`;
|
|
51380
51397
|
};
|
|
51381
|
-
const
|
|
51398
|
+
const getShiftIcon2 = () => {
|
|
51382
51399
|
const currentShift = getCurrentShift(timezone, shiftConfig);
|
|
51383
51400
|
const shiftName = (currentShift.shiftName || "").toLowerCase();
|
|
51384
51401
|
if (shiftName.includes("day") || shiftName.includes("morning") || currentShift.shiftId === 0) {
|
|
@@ -51412,7 +51429,7 @@ var DashboardHeader = memo$1(({ lineTitle, className = "", headerControls, lineI
|
|
|
51412
51429
|
/* @__PURE__ */ jsx("span", { className: "font-medium", children: /* @__PURE__ */ jsx(Timer2, {}) }),
|
|
51413
51430
|
/* @__PURE__ */ jsx("span", { className: "text-gray-300", children: "|" }),
|
|
51414
51431
|
isShiftConfigLoading ? /* @__PURE__ */ jsx("div", { className: "h-3.5 w-16 bg-gray-200 rounded animate-pulse" }) : /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 font-medium", children: [
|
|
51415
|
-
/* @__PURE__ */ jsx("span", { className: "opacity-75", children:
|
|
51432
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-75", children: getShiftIcon2() }),
|
|
51416
51433
|
getShiftName()
|
|
51417
51434
|
] })
|
|
51418
51435
|
] })
|
|
@@ -51429,7 +51446,7 @@ var DashboardHeader = memo$1(({ lineTitle, className = "", headerControls, lineI
|
|
|
51429
51446
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 inline-flex flex-wrap items-center gap-3", children: [
|
|
51430
51447
|
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-600 whitespace-nowrap", children: /* @__PURE__ */ jsx(Timer2, {}) }),
|
|
51431
51448
|
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center gap-1", children: isShiftConfigLoading ? /* @__PURE__ */ jsx("div", { className: "h-4 w-20 bg-gray-200 rounded animate-pulse" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
51432
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children:
|
|
51449
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children: getShiftIcon2() }),
|
|
51433
51450
|
/* @__PURE__ */ jsx("span", { className: "text-xs md:text-sm font-medium text-gray-600 whitespace-nowrap", children: getShiftName() })
|
|
51434
51451
|
] }) })
|
|
51435
51452
|
] })
|
|
@@ -58400,7 +58417,7 @@ var FactoryView = ({
|
|
|
58400
58417
|
const currentShift = getCurrentShiftInfo();
|
|
58401
58418
|
return (currentShift.shiftName || "Day").replace(/ Shift$/i, "");
|
|
58402
58419
|
};
|
|
58403
|
-
const
|
|
58420
|
+
const getShiftIcon2 = () => {
|
|
58404
58421
|
const currentShift = getCurrentShiftInfo();
|
|
58405
58422
|
const shiftNameLower = (currentShift.shiftName || "").toLowerCase();
|
|
58406
58423
|
if (shiftNameLower.includes("day") || shiftNameLower.includes("morning") || currentShift.shiftId === 0) {
|
|
@@ -58446,7 +58463,7 @@ var FactoryView = ({
|
|
|
58446
58463
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center justify-center gap-2", children: [
|
|
58447
58464
|
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-gray-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: /* @__PURE__ */ jsx(ISTTimer_default, {}) }) }),
|
|
58448
58465
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
58449
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
58466
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2() }),
|
|
58450
58467
|
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-gray-700", children: [
|
|
58451
58468
|
getShiftName(),
|
|
58452
58469
|
" Shift"
|
|
@@ -58465,7 +58482,7 @@ var FactoryView = ({
|
|
|
58465
58482
|
" IST"
|
|
58466
58483
|
] }),
|
|
58467
58484
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1", children: [
|
|
58468
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children:
|
|
58485
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children: getShiftIcon2() }),
|
|
58469
58486
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-gray-600", children: [
|
|
58470
58487
|
getShiftName(),
|
|
58471
58488
|
" Shift"
|
|
@@ -61177,7 +61194,7 @@ var KPIDetailView = ({
|
|
|
61177
61194
|
const getShiftName = useCallback((shiftId) => {
|
|
61178
61195
|
return getShiftNameById(shiftId, configuredTimezone, shiftConfig);
|
|
61179
61196
|
}, [configuredTimezone, shiftConfig]);
|
|
61180
|
-
const
|
|
61197
|
+
const getShiftIcon2 = useCallback((shiftId) => {
|
|
61181
61198
|
if (shiftId === 0) {
|
|
61182
61199
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
61183
61200
|
}
|
|
@@ -62057,7 +62074,7 @@ var KPIDetailView = ({
|
|
|
62057
62074
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
|
|
62058
62075
|
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-gray-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: chartMetrics && formatLocalDate(new Date(chartMetrics.date)) }) }),
|
|
62059
62076
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
62060
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
62077
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(chartMetrics.shift_id ?? 0) }),
|
|
62061
62078
|
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-gray-700", children: [
|
|
62062
62079
|
getShiftName(chartMetrics.shift_id ?? 0).replace(/ Shift$/i, ""),
|
|
62063
62080
|
" Shift"
|
|
@@ -62083,7 +62100,7 @@ var KPIDetailView = ({
|
|
|
62083
62100
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" })
|
|
62084
62101
|
] }),
|
|
62085
62102
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
62086
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
62103
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(chartMetrics.shift_id ?? 0) }),
|
|
62087
62104
|
/* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: [
|
|
62088
62105
|
getShiftName(chartMetrics.shift_id ?? 0).replace(/ Shift$/i, ""),
|
|
62089
62106
|
" Shift"
|
|
@@ -62101,7 +62118,7 @@ var KPIDetailView = ({
|
|
|
62101
62118
|
return `${startDate.toLocaleDateString("en-US", { month: "short", day: "numeric" })} - ${endDate.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })}`;
|
|
62102
62119
|
})() }) }),
|
|
62103
62120
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
62104
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
62121
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(selectedShiftId) }),
|
|
62105
62122
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: getShiftName(selectedShiftId) })
|
|
62106
62123
|
] })
|
|
62107
62124
|
] }),
|
|
@@ -62118,7 +62135,7 @@ var KPIDetailView = ({
|
|
|
62118
62135
|
] }),
|
|
62119
62136
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" }),
|
|
62120
62137
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
62121
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
62138
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(selectedShiftId) }),
|
|
62122
62139
|
/* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: [
|
|
62123
62140
|
getShiftName(selectedShiftId).replace(/ Shift$/i, ""),
|
|
62124
62141
|
" Shift"
|
|
@@ -63494,7 +63511,7 @@ var KPIsOverviewView = ({
|
|
|
63494
63511
|
const headerShiftId = showHistoricalLeaderboardHeader ? effectiveLeaderboardShiftId : currentShiftDetails.shiftId;
|
|
63495
63512
|
const headerShiftName = getShiftNameById(headerShiftId, configuredTimezone, shiftConfig).replace(/ Shift$/i, "");
|
|
63496
63513
|
const headerDateLabel = isMonthlyMode ? getMonthRange() : formatLocalDate2(headerDateKey);
|
|
63497
|
-
const
|
|
63514
|
+
const getShiftIcon2 = (shiftId) => {
|
|
63498
63515
|
const shiftNameLower = getShiftNameById(shiftId, configuredTimezone, shiftConfig).toLowerCase();
|
|
63499
63516
|
if (shiftNameLower.includes("day") || shiftNameLower.includes("morning") || shiftId === 0) {
|
|
63500
63517
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
@@ -63611,7 +63628,7 @@ var KPIsOverviewView = ({
|
|
|
63611
63628
|
/* @__PURE__ */ jsx("div", { className: `inline-flex items-center bg-gray-100 rounded-full ${isMonthlyMode ? "px-4 py-1.5 ring-1 ring-gray-200 shadow-sm" : "px-2.5 py-1"}`, children: /* @__PURE__ */ jsx("span", { className: `font-medium text-gray-700 ${isMonthlyMode ? "text-sm" : "text-xs"}`, children: headerDateLabel }) }),
|
|
63612
63629
|
!isMonthlyMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63613
63630
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
63614
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
63631
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(headerShiftId) }),
|
|
63615
63632
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: headerShiftName })
|
|
63616
63633
|
] }),
|
|
63617
63634
|
showHistoricalLeaderboardHeader ? /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-amber-50 text-amber-700 rounded-full", children: [
|
|
@@ -63807,7 +63824,7 @@ var KPIsOverviewView = ({
|
|
|
63807
63824
|
!isMonthlyMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63808
63825
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" }),
|
|
63809
63826
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
63810
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
63827
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(headerShiftId) }),
|
|
63811
63828
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-semibold uppercase tracking-wider", children: [
|
|
63812
63829
|
headerShiftName,
|
|
63813
63830
|
" Shift"
|
|
@@ -63951,6 +63968,52 @@ var KPIsOverviewView = ({
|
|
|
63951
63968
|
] });
|
|
63952
63969
|
};
|
|
63953
63970
|
var KPIsOverviewView_default = KPIsOverviewView;
|
|
63971
|
+
var toFiniteNumber = (value) => {
|
|
63972
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
63973
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
63974
|
+
const parsed = Number(value);
|
|
63975
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
63976
|
+
}
|
|
63977
|
+
return null;
|
|
63978
|
+
};
|
|
63979
|
+
var getCycleRatio = (workspace) => {
|
|
63980
|
+
const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
|
|
63981
|
+
const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
|
|
63982
|
+
if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
|
|
63983
|
+
return null;
|
|
63984
|
+
}
|
|
63985
|
+
return idealCycleTime / avgCycleTime;
|
|
63986
|
+
};
|
|
63987
|
+
var formatCycleTimeValue = (value) => {
|
|
63988
|
+
const numericValue = toFiniteNumber(value);
|
|
63989
|
+
if (numericValue === null || numericValue <= 0) return "--";
|
|
63990
|
+
return `${numericValue.toFixed(1)}s`;
|
|
63991
|
+
};
|
|
63992
|
+
var CycleTimeComparison = memo$1(({
|
|
63993
|
+
workspace,
|
|
63994
|
+
variant = "table"
|
|
63995
|
+
}) => {
|
|
63996
|
+
const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
63997
|
+
const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
63998
|
+
if (variant === "mobile") {
|
|
63999
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center justify-between py-2 border-t border-gray-100", children: [
|
|
64000
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Standard Cycle Time" }),
|
|
64001
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums text-gray-500", children: standardValue })
|
|
64002
|
+
] });
|
|
64003
|
+
}
|
|
64004
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64005
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
64006
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Average" }),
|
|
64007
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums text-gray-900", children: averageValue })
|
|
64008
|
+
] }),
|
|
64009
|
+
/* @__PURE__ */ jsx("div", { className: "h-6 w-px bg-gray-200" }),
|
|
64010
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
64011
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Standard" }),
|
|
64012
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums text-gray-500", children: standardValue })
|
|
64013
|
+
] })
|
|
64014
|
+
] });
|
|
64015
|
+
}, (prevProps, nextProps) => prevProps.variant === nextProps.variant && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
|
|
64016
|
+
CycleTimeComparison.displayName = "CycleTimeComparison";
|
|
63954
64017
|
var IsolatedTimer = memo$1(() => {
|
|
63955
64018
|
return /* @__PURE__ */ jsx(ISTTimer_default, {});
|
|
63956
64019
|
});
|
|
@@ -63968,11 +64031,11 @@ var HeaderRibbon = memo$1(({
|
|
|
63968
64031
|
currentDate,
|
|
63969
64032
|
currentMobileDate,
|
|
63970
64033
|
shiftId,
|
|
63971
|
-
getShiftIcon,
|
|
64034
|
+
getShiftIcon: getShiftIcon2,
|
|
63972
64035
|
getShiftName,
|
|
63973
64036
|
showTimer = true
|
|
63974
64037
|
}) => {
|
|
63975
|
-
const shiftIcon = useMemo(() =>
|
|
64038
|
+
const shiftIcon = useMemo(() => getShiftIcon2(shiftId), [getShiftIcon2, shiftId]);
|
|
63976
64039
|
const shiftName = useMemo(() => getShiftName(shiftId), [getShiftName, shiftId]);
|
|
63977
64040
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63978
64041
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
|
|
@@ -64014,8 +64077,9 @@ var MobileWorkspaceCard = memo$1(({
|
|
|
64014
64077
|
isClickable,
|
|
64015
64078
|
onWorkspaceClick,
|
|
64016
64079
|
getMedalIcon,
|
|
64017
|
-
|
|
64018
|
-
|
|
64080
|
+
metricLabel,
|
|
64081
|
+
isAssemblyMode
|
|
64082
|
+
}) => /* @__PURE__ */ jsxs(
|
|
64019
64083
|
motion.div,
|
|
64020
64084
|
{
|
|
64021
64085
|
layout: true,
|
|
@@ -64026,28 +64090,31 @@ var MobileWorkspaceCard = memo$1(({
|
|
|
64026
64090
|
},
|
|
64027
64091
|
onClick: isClickable ? () => onWorkspaceClick(workspace, rank) : void 0,
|
|
64028
64092
|
className: `${cardClass} p-3 rounded-lg border shadow-sm active:scale-[0.98] ${isClickable ? "cursor-pointer" : "cursor-not-allowed opacity-75"}`,
|
|
64029
|
-
children:
|
|
64030
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64031
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
64032
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
64033
|
-
"
|
|
64034
|
-
|
|
64093
|
+
children: [
|
|
64094
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2 gap-3", children: [
|
|
64095
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64096
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
64097
|
+
/* @__PURE__ */ jsxs("div", { className: "text-2xl font-bold text-gray-700", children: [
|
|
64098
|
+
"#",
|
|
64099
|
+
rank
|
|
64100
|
+
] }),
|
|
64101
|
+
getMedalIcon(rank)
|
|
64035
64102
|
] }),
|
|
64036
|
-
|
|
64103
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
64104
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-900", children: workspace.displayName }),
|
|
64105
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: workspace.lineName })
|
|
64106
|
+
] })
|
|
64037
64107
|
] }),
|
|
64038
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
64039
|
-
/* @__PURE__ */ jsx("div", { className: "font-
|
|
64040
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children:
|
|
64108
|
+
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
64109
|
+
/* @__PURE__ */ jsx("div", { className: "font-bold text-gray-900 text-lg", children: isAssemblyMode ? /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formatCycleTimeValue(workspace.avg_cycle_time) }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) }),
|
|
64110
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: metricLabel })
|
|
64041
64111
|
] })
|
|
64042
64112
|
] }),
|
|
64043
|
-
/* @__PURE__ */
|
|
64044
|
-
|
|
64045
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: efficiencyLabel })
|
|
64046
|
-
] })
|
|
64047
|
-
] })
|
|
64113
|
+
isAssemblyMode && /* @__PURE__ */ jsx(CycleTimeComparison, { workspace, variant: "mobile" })
|
|
64114
|
+
]
|
|
64048
64115
|
}
|
|
64049
64116
|
), (prevProps, nextProps) => {
|
|
64050
|
-
return prevProps.
|
|
64117
|
+
return prevProps.metricLabel === nextProps.metricLabel && prevProps.isAssemblyMode === nextProps.isAssemblyMode && prevProps.rank === nextProps.rank && prevProps.cardClass === nextProps.cardClass && prevProps.isClickable === nextProps.isClickable && prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.efficiency === nextProps.workspace.efficiency && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time && prevProps.workspace.action_count === nextProps.workspace.action_count && prevProps.workspace.action_threshold === nextProps.workspace.action_threshold && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.displayName === nextProps.workspace.displayName && prevProps.workspace.lineName === nextProps.workspace.lineName;
|
|
64051
64118
|
});
|
|
64052
64119
|
MobileWorkspaceCard.displayName = "MobileWorkspaceCard";
|
|
64053
64120
|
var DesktopWorkspaceRow = memo$1(({
|
|
@@ -64056,7 +64123,8 @@ var DesktopWorkspaceRow = memo$1(({
|
|
|
64056
64123
|
rowClass,
|
|
64057
64124
|
isClickable,
|
|
64058
64125
|
onWorkspaceClick,
|
|
64059
|
-
getMedalIcon
|
|
64126
|
+
getMedalIcon,
|
|
64127
|
+
isAssemblyMode
|
|
64060
64128
|
}) => /* @__PURE__ */ jsxs(
|
|
64061
64129
|
motion.tr,
|
|
64062
64130
|
{
|
|
@@ -64073,11 +64141,11 @@ var DesktopWorkspaceRow = memo$1(({
|
|
|
64073
64141
|
] }) }),
|
|
64074
64142
|
/* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: workspace.displayName }) }),
|
|
64075
64143
|
/* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: workspace.lineName }) }),
|
|
64076
|
-
/* @__PURE__ */ jsx("td", { className:
|
|
64144
|
+
/* @__PURE__ */ jsx("td", { className: `px-3 py-2.5 sm:p-4 text-sm sm:text-base font-medium ${isAssemblyMode ? "" : "whitespace-nowrap"}`, children: isAssemblyMode ? /* @__PURE__ */ jsx(CycleTimeComparison, { workspace, variant: "table" }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) })
|
|
64077
64145
|
]
|
|
64078
64146
|
}
|
|
64079
64147
|
), (prevProps, nextProps) => {
|
|
64080
|
-
return prevProps.index === nextProps.index && prevProps.rowClass === nextProps.rowClass && prevProps.isClickable === nextProps.isClickable && prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.efficiency === nextProps.workspace.efficiency && prevProps.workspace.displayName === nextProps.workspace.displayName && prevProps.workspace.lineName === nextProps.workspace.lineName;
|
|
64148
|
+
return prevProps.index === nextProps.index && prevProps.rowClass === nextProps.rowClass && prevProps.isClickable === nextProps.isClickable && prevProps.isAssemblyMode === nextProps.isAssemblyMode && prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.efficiency === nextProps.workspace.efficiency && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.displayName === nextProps.workspace.displayName && prevProps.workspace.lineName === nextProps.workspace.lineName;
|
|
64081
64149
|
});
|
|
64082
64150
|
DesktopWorkspaceRow.displayName = "DesktopWorkspaceRow";
|
|
64083
64151
|
var LeaderboardDetailView = memo$1(({
|
|
@@ -64099,6 +64167,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64099
64167
|
const supabase = useSupabase();
|
|
64100
64168
|
const [sortAscending, setSortAscending] = useState(false);
|
|
64101
64169
|
const [viewType, setViewType] = useState("operator");
|
|
64170
|
+
const [outputCategory, setOutputCategory] = useState("standard");
|
|
64102
64171
|
const [activeTab, setActiveTab] = useState("today");
|
|
64103
64172
|
const timezone = useAppTimezone();
|
|
64104
64173
|
const staticShiftConfig = useShiftConfig();
|
|
@@ -64177,6 +64246,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64177
64246
|
const monthlyRequestKeyRef = useRef(null);
|
|
64178
64247
|
const leaderboardUpdateQueuedRef = useRef(false);
|
|
64179
64248
|
const leaderboardUpdateTimerRef = useRef(null);
|
|
64249
|
+
const leaderboardViewTrackedRef = useRef(null);
|
|
64180
64250
|
const filterRef = useRef(null);
|
|
64181
64251
|
const filterButtonRef = useRef(null);
|
|
64182
64252
|
const mobileFilterButtonRef = useRef(null);
|
|
@@ -64309,6 +64379,17 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64309
64379
|
}
|
|
64310
64380
|
return Array.from(uniqueLines.entries()).map(([id3, name]) => ({ id: id3, label: name }));
|
|
64311
64381
|
}, [configuredLineIds, lines, getLineName]);
|
|
64382
|
+
const scopedLines = useMemo(() => {
|
|
64383
|
+
const configuredLineIdSet = new Set(configuredLineIds);
|
|
64384
|
+
return lines.filter((line) => configuredLineIds.length === 0 || configuredLineIdSet.has(line.id));
|
|
64385
|
+
}, [configuredLineIds, lines]);
|
|
64386
|
+
const scopedLineAssemblyMap = useMemo(() => {
|
|
64387
|
+
const map = /* @__PURE__ */ new Map();
|
|
64388
|
+
scopedLines.forEach((line) => {
|
|
64389
|
+
map.set(line.id, line.assembly === true);
|
|
64390
|
+
});
|
|
64391
|
+
return map;
|
|
64392
|
+
}, [scopedLines]);
|
|
64312
64393
|
const shiftOptions = useMemo(() => {
|
|
64313
64394
|
if (activeShiftConfig?.shifts && activeShiftConfig.shifts.length > 0) {
|
|
64314
64395
|
return activeShiftConfig.shifts.map((shift2) => ({
|
|
@@ -64332,6 +64413,33 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64332
64413
|
const parsed = Number(selectedShiftFilter);
|
|
64333
64414
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
64334
64415
|
}, [selectedShiftFilter]);
|
|
64416
|
+
const outputScopeLines = useMemo(() => {
|
|
64417
|
+
const outputLines = scopedLines.filter((line) => (line.monitoring_mode ?? "output") !== "uptime");
|
|
64418
|
+
if (selectedLineFilter === "all") {
|
|
64419
|
+
return outputLines;
|
|
64420
|
+
}
|
|
64421
|
+
return outputLines.filter((line) => line.id === selectedLineFilter);
|
|
64422
|
+
}, [scopedLines, selectedLineFilter]);
|
|
64423
|
+
const hasAssemblyOutputScope = useMemo(
|
|
64424
|
+
() => outputScopeLines.some((line) => line.assembly === true),
|
|
64425
|
+
[outputScopeLines]
|
|
64426
|
+
);
|
|
64427
|
+
const hasStandardOutputScope = useMemo(
|
|
64428
|
+
() => outputScopeLines.some((line) => line.assembly !== true),
|
|
64429
|
+
[outputScopeLines]
|
|
64430
|
+
);
|
|
64431
|
+
const showOutputCategoryDropdown = viewType === "operator" && hasAssemblyOutputScope && hasStandardOutputScope;
|
|
64432
|
+
const isAssemblyMode = viewType === "operator" && outputCategory === "assembly";
|
|
64433
|
+
useEffect(() => {
|
|
64434
|
+
if (viewType !== "operator") return;
|
|
64435
|
+
if (hasAssemblyOutputScope && !hasStandardOutputScope && outputCategory !== "assembly") {
|
|
64436
|
+
setOutputCategory("assembly");
|
|
64437
|
+
return;
|
|
64438
|
+
}
|
|
64439
|
+
if (hasStandardOutputScope && !hasAssemblyOutputScope && outputCategory !== "standard") {
|
|
64440
|
+
setOutputCategory("standard");
|
|
64441
|
+
}
|
|
64442
|
+
}, [viewType, hasAssemblyOutputScope, hasStandardOutputScope, outputCategory]);
|
|
64335
64443
|
const handleLineFilterChange = useCallback((value) => {
|
|
64336
64444
|
setSelectedLineFilter(value);
|
|
64337
64445
|
}, []);
|
|
@@ -64341,17 +64449,19 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64341
64449
|
const clearFilters = useCallback(() => {
|
|
64342
64450
|
setSortAscending(false);
|
|
64343
64451
|
setSelectedLineFilter("all");
|
|
64452
|
+
setOutputCategory("standard");
|
|
64344
64453
|
setSelectedShiftFilter(currentShiftInfo.shiftId.toString());
|
|
64345
64454
|
}, [currentShiftInfo.shiftId]);
|
|
64346
64455
|
const activeFiltersCount = useMemo(() => {
|
|
64347
64456
|
let count = 0;
|
|
64348
64457
|
if (sortAscending) count++;
|
|
64349
64458
|
if (selectedLineFilter !== "all") count++;
|
|
64459
|
+
if (showOutputCategoryDropdown && outputCategory !== "standard") count++;
|
|
64350
64460
|
if (selectedShiftFilter !== currentShiftInfo.shiftId.toString()) {
|
|
64351
64461
|
count++;
|
|
64352
64462
|
}
|
|
64353
64463
|
return count;
|
|
64354
|
-
}, [sortAscending, selectedLineFilter, selectedShiftFilter, currentShiftInfo.shiftId]);
|
|
64464
|
+
}, [sortAscending, selectedLineFilter, outputCategory, showOutputCategoryDropdown, selectedShiftFilter, currentShiftInfo.shiftId]);
|
|
64355
64465
|
const shouldFetchShiftConfigs = !date && shiftId === void 0;
|
|
64356
64466
|
const {
|
|
64357
64467
|
shiftConfigMap: multiLineShiftConfigMap,
|
|
@@ -64403,7 +64513,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64403
64513
|
action_count: entry.total_output || 0,
|
|
64404
64514
|
pph: entry.avg_pph || 0,
|
|
64405
64515
|
performance_score: entry.performance_score ?? 0,
|
|
64406
|
-
avg_cycle_time: entry.avg_cycle_time
|
|
64516
|
+
avg_cycle_time: toFiniteNumber(entry.avg_cycle_time) ?? 0,
|
|
64517
|
+
ideal_cycle_time: toFiniteNumber(entry.ideal_cycle_time) ?? void 0,
|
|
64407
64518
|
trend: 0,
|
|
64408
64519
|
predicted_output: 0,
|
|
64409
64520
|
efficiency: entry.efficiency || 0,
|
|
@@ -64581,7 +64692,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64581
64692
|
const currentShift = getCurrentShift(timezone || "Asia/Kolkata", activeShiftConfig);
|
|
64582
64693
|
return currentShift.shiftName || getShiftNameById(currentShift.shiftId, timezone || "Asia/Kolkata", activeShiftConfig);
|
|
64583
64694
|
}, [timezone, activeShiftConfig, shiftGroups]);
|
|
64584
|
-
const
|
|
64695
|
+
const getShiftIcon2 = useCallback((shiftId2) => {
|
|
64585
64696
|
if (shiftId2 === void 0 && shiftGroups.length > 1) {
|
|
64586
64697
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" }) });
|
|
64587
64698
|
}
|
|
@@ -64647,15 +64758,20 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64647
64758
|
if (!canOpenWorkspace(workspace.line_id)) {
|
|
64648
64759
|
return;
|
|
64649
64760
|
}
|
|
64761
|
+
const cycleRatio = getCycleRatio(workspace);
|
|
64650
64762
|
trackCoreEvent("Workspace from Leaderboard Clicked", {
|
|
64651
64763
|
workspace_name: workspace.workspace_name,
|
|
64652
64764
|
workspace_id: workspace.workspace_uuid,
|
|
64653
64765
|
rank,
|
|
64654
64766
|
total_workspaces: workspacesLengthRef.current,
|
|
64655
64767
|
// Use ref instead of state to avoid dependency
|
|
64768
|
+
metric_context: viewType === "machine" ? "machine" : outputCategory,
|
|
64656
64769
|
efficiency: workspace.efficiency,
|
|
64657
64770
|
action_count: workspace.action_count,
|
|
64658
|
-
action_threshold: workspace.action_threshold
|
|
64771
|
+
action_threshold: workspace.action_threshold,
|
|
64772
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
64773
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null,
|
|
64774
|
+
cycle_ratio: cycleRatio
|
|
64659
64775
|
});
|
|
64660
64776
|
const displayName = workspace.displayName || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
64661
64777
|
const navParams = workspace.workspace_uuid ? getWorkspaceNavigationParams(workspace.workspace_uuid, displayName, workspace.line_id) : "";
|
|
@@ -64679,7 +64795,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64679
64795
|
const combinedParams = navParams ? `${navParams}&${contextParamString}` : `?${contextParamString}`;
|
|
64680
64796
|
navigation.navigate(`/workspace/${workspace.workspace_uuid}${combinedParams}`);
|
|
64681
64797
|
}
|
|
64682
|
-
}, [canOpenWorkspace, onWorkspaceClick, navigation, date, shiftId]);
|
|
64798
|
+
}, [canOpenWorkspace, onWorkspaceClick, navigation, date, shiftId, outputCategory, viewType]);
|
|
64683
64799
|
useEffect(() => {
|
|
64684
64800
|
workspacesLengthRef.current = activeEntries.length || 0;
|
|
64685
64801
|
}, [activeEntries.length]);
|
|
@@ -64700,16 +64816,20 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64700
64816
|
return activeEntries.map((ws) => ({
|
|
64701
64817
|
...ws,
|
|
64702
64818
|
displayName: ws.displayName || getWorkspaceDisplayName(ws.workspace_name, ws.line_id),
|
|
64703
|
-
lineName: getLineName(ws.line_id)
|
|
64819
|
+
lineName: getLineName(ws.line_id),
|
|
64820
|
+
isAssemblyLine: scopedLineAssemblyMap.get(ws.line_id) === true
|
|
64704
64821
|
}));
|
|
64705
|
-
}, [activeEntries, getLineName]);
|
|
64822
|
+
}, [activeEntries, getLineName, scopedLineAssemblyMap]);
|
|
64706
64823
|
const sortedWorkspaces = useMemo(() => {
|
|
64707
64824
|
let filtered = [...workspaceDisplayData];
|
|
64708
64825
|
filtered = filtered.filter((ws) => {
|
|
64709
64826
|
if (viewType === "machine") {
|
|
64710
64827
|
return ws.monitoring_mode === "uptime";
|
|
64711
64828
|
}
|
|
64712
|
-
|
|
64829
|
+
if (ws.monitoring_mode === "uptime") {
|
|
64830
|
+
return false;
|
|
64831
|
+
}
|
|
64832
|
+
return isAssemblyMode ? ws.isAssemblyLine : !ws.isAssemblyLine;
|
|
64713
64833
|
});
|
|
64714
64834
|
if (selectedLineFilter !== "all") {
|
|
64715
64835
|
filtered = filtered.filter((ws) => ws.line_id === selectedLineFilter);
|
|
@@ -64718,13 +64838,61 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64718
64838
|
filtered = filtered.filter((ws) => ws.shift_id?.toString() === selectedShiftFilter);
|
|
64719
64839
|
}
|
|
64720
64840
|
return filtered.sort((a, b) => {
|
|
64841
|
+
if (isAssemblyMode) {
|
|
64842
|
+
const ratioA = getCycleRatio(a);
|
|
64843
|
+
const ratioB = getCycleRatio(b);
|
|
64844
|
+
if (ratioA === null && ratioB === null) return 0;
|
|
64845
|
+
if (ratioA === null) return 1;
|
|
64846
|
+
if (ratioB === null) return -1;
|
|
64847
|
+
return sortAscending ? ratioA - ratioB : ratioB - ratioA;
|
|
64848
|
+
}
|
|
64721
64849
|
const effA = a.efficiency || 0;
|
|
64722
64850
|
const effB = b.efficiency || 0;
|
|
64723
64851
|
return sortAscending ? effA - effB : effB - effA;
|
|
64724
64852
|
});
|
|
64725
|
-
}, [workspaceDisplayData, sortAscending, selectedLineFilter, selectedShiftFilter, activeTab, viewType]);
|
|
64853
|
+
}, [workspaceDisplayData, sortAscending, selectedLineFilter, selectedShiftFilter, activeTab, viewType, isAssemblyMode]);
|
|
64726
64854
|
const loading = activeTab === "today" ? todayLoading : monthlyLoading;
|
|
64727
64855
|
const error = activeTab === "today" ? todayError : monthlyError;
|
|
64856
|
+
useEffect(() => {
|
|
64857
|
+
if (loading || error || sortedWorkspaces.length === 0) return;
|
|
64858
|
+
const trackingKey = [
|
|
64859
|
+
activeTab,
|
|
64860
|
+
viewType,
|
|
64861
|
+
outputCategory,
|
|
64862
|
+
selectedLineFilter,
|
|
64863
|
+
selectedShiftFilter,
|
|
64864
|
+
sortAscending ? "asc" : "desc",
|
|
64865
|
+
sortedWorkspaces.length
|
|
64866
|
+
].join("|");
|
|
64867
|
+
if (leaderboardViewTrackedRef.current === trackingKey) return;
|
|
64868
|
+
leaderboardViewTrackedRef.current = trackingKey;
|
|
64869
|
+
const topWorkspace = sortedWorkspaces[0];
|
|
64870
|
+
trackCoreEvent("Workspace Leaderboard View Loaded", {
|
|
64871
|
+
time_range: activeTab,
|
|
64872
|
+
view_type: viewType,
|
|
64873
|
+
metric_context: viewType === "machine" ? "machine" : outputCategory,
|
|
64874
|
+
line_filter: selectedLineFilter,
|
|
64875
|
+
shift_filter: selectedShiftFilter,
|
|
64876
|
+
sort_direction: sortAscending ? "asc" : "desc",
|
|
64877
|
+
workspace_count: sortedWorkspaces.length,
|
|
64878
|
+
top_workspace_id: topWorkspace?.workspace_uuid ?? null,
|
|
64879
|
+
top_workspace_name: topWorkspace?.workspace_name ?? null,
|
|
64880
|
+
top_efficiency: topWorkspace?.efficiency ?? null,
|
|
64881
|
+
top_avg_cycle_time: topWorkspace?.avg_cycle_time ?? null,
|
|
64882
|
+
top_ideal_cycle_time: topWorkspace?.ideal_cycle_time ?? null,
|
|
64883
|
+
top_cycle_ratio: topWorkspace ? getCycleRatio(topWorkspace) : null
|
|
64884
|
+
});
|
|
64885
|
+
}, [
|
|
64886
|
+
loading,
|
|
64887
|
+
error,
|
|
64888
|
+
sortedWorkspaces,
|
|
64889
|
+
activeTab,
|
|
64890
|
+
viewType,
|
|
64891
|
+
outputCategory,
|
|
64892
|
+
selectedLineFilter,
|
|
64893
|
+
selectedShiftFilter,
|
|
64894
|
+
sortAscending
|
|
64895
|
+
]);
|
|
64728
64896
|
const currentDateFormatted = useMemo(() => {
|
|
64729
64897
|
const dateStr = (/* @__PURE__ */ new Date()).toDateString();
|
|
64730
64898
|
return formatDate2(new Date(dateStr));
|
|
@@ -64742,7 +64910,9 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64742
64910
|
error.message
|
|
64743
64911
|
] }) });
|
|
64744
64912
|
}
|
|
64745
|
-
const
|
|
64913
|
+
const metricLabel = viewType === "machine" ? "Utilization" : isAssemblyMode ? "Cycle Time" : "Efficiency";
|
|
64914
|
+
const descendingSortLabel = "Highest to Lowest";
|
|
64915
|
+
const ascendingSortLabel = "Lowest to Highest";
|
|
64746
64916
|
return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 flex flex-col ${className}`, style: { willChange: "contents" }, children: [
|
|
64747
64917
|
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-20 bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 md:px-8 py-2 sm:py-2.5", children: [
|
|
64748
64918
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
@@ -64792,7 +64962,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64792
64962
|
] }),
|
|
64793
64963
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
64794
64964
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
64795
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children:
|
|
64965
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: metricLabel }),
|
|
64796
64966
|
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
64797
64967
|
"select",
|
|
64798
64968
|
{
|
|
@@ -64801,8 +64971,25 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64801
64971
|
className: "w-full appearance-none pl-3 pr-8 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer",
|
|
64802
64972
|
style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.75rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
|
|
64803
64973
|
children: [
|
|
64804
|
-
/* @__PURE__ */ jsx("option", { value: "desc", children:
|
|
64805
|
-
/* @__PURE__ */ jsx("option", { value: "asc", children:
|
|
64974
|
+
/* @__PURE__ */ jsx("option", { value: "desc", children: descendingSortLabel }),
|
|
64975
|
+
/* @__PURE__ */ jsx("option", { value: "asc", children: ascendingSortLabel })
|
|
64976
|
+
]
|
|
64977
|
+
}
|
|
64978
|
+
) })
|
|
64979
|
+
] }),
|
|
64980
|
+
showOutputCategoryDropdown && /* @__PURE__ */ jsxs("div", { className: "space-y-1 sm:hidden", children: [
|
|
64981
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Output Type" }),
|
|
64982
|
+
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
64983
|
+
"select",
|
|
64984
|
+
{
|
|
64985
|
+
"aria-label": "Output leaderboard category",
|
|
64986
|
+
value: outputCategory,
|
|
64987
|
+
onChange: (e) => setOutputCategory(e.target.value),
|
|
64988
|
+
className: "w-full appearance-none pl-3 pr-8 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer",
|
|
64989
|
+
style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.75rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
|
|
64990
|
+
children: [
|
|
64991
|
+
/* @__PURE__ */ jsx("option", { value: "standard", children: "Standard" }),
|
|
64992
|
+
/* @__PURE__ */ jsx("option", { value: "assembly", children: "Assembly" })
|
|
64806
64993
|
]
|
|
64807
64994
|
}
|
|
64808
64995
|
) })
|
|
@@ -64844,7 +65031,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64844
65031
|
currentDate: activeTab === "monthly" ? monthlyRangeText : currentDateFormatted,
|
|
64845
65032
|
currentMobileDate: activeTab === "monthly" ? monthlyRangeText : currentMobileDateFormatted,
|
|
64846
65033
|
shiftId: activeTab === "monthly" ? monthlyShiftId : todayShiftId,
|
|
64847
|
-
getShiftIcon,
|
|
65034
|
+
getShiftIcon: getShiftIcon2,
|
|
64848
65035
|
getShiftName,
|
|
64849
65036
|
showTimer: activeTab === "today"
|
|
64850
65037
|
}
|
|
@@ -64942,6 +65129,20 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64942
65129
|
]
|
|
64943
65130
|
}
|
|
64944
65131
|
) }),
|
|
65132
|
+
showOutputCategoryDropdown && /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
65133
|
+
"select",
|
|
65134
|
+
{
|
|
65135
|
+
"aria-label": "Output leaderboard category",
|
|
65136
|
+
value: outputCategory,
|
|
65137
|
+
onChange: (e) => setOutputCategory(e.target.value),
|
|
65138
|
+
className: "appearance-none pl-3 pr-8 py-1.5 text-sm font-medium bg-white border border-gray-200 hover:border-gray-300 rounded-lg text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all cursor-pointer shadow-sm",
|
|
65139
|
+
style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.5rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
|
|
65140
|
+
children: [
|
|
65141
|
+
/* @__PURE__ */ jsx("option", { value: "standard", children: "Standard" }),
|
|
65142
|
+
/* @__PURE__ */ jsx("option", { value: "assembly", children: "Assembly" })
|
|
65143
|
+
]
|
|
65144
|
+
}
|
|
65145
|
+
) }),
|
|
64945
65146
|
/* @__PURE__ */ jsxs(
|
|
64946
65147
|
"button",
|
|
64947
65148
|
{
|
|
@@ -64973,7 +65174,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64973
65174
|
isClickable: canOpenWorkspace(ws.line_id),
|
|
64974
65175
|
onWorkspaceClick: stableHandleWorkspaceClick,
|
|
64975
65176
|
getMedalIcon: stableGetMedalIcon,
|
|
64976
|
-
|
|
65177
|
+
metricLabel,
|
|
65178
|
+
isAssemblyMode
|
|
64977
65179
|
},
|
|
64978
65180
|
ws.workspace_uuid
|
|
64979
65181
|
);
|
|
@@ -64984,7 +65186,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64984
65186
|
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: "Rank" }),
|
|
64985
65187
|
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: "Workspace" }),
|
|
64986
65188
|
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: "Line" }),
|
|
64987
|
-
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children:
|
|
65189
|
+
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: metricLabel })
|
|
64988
65190
|
] }) }),
|
|
64989
65191
|
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-100", children: sortedWorkspaces.map((ws, index) => {
|
|
64990
65192
|
const isTopThree = index < 3;
|
|
@@ -64997,7 +65199,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64997
65199
|
rowClass,
|
|
64998
65200
|
isClickable: canOpenWorkspace(ws.line_id),
|
|
64999
65201
|
onWorkspaceClick: stableHandleWorkspaceClick,
|
|
65000
|
-
getMedalIcon: stableGetMedalIcon
|
|
65202
|
+
getMedalIcon: stableGetMedalIcon,
|
|
65203
|
+
isAssemblyMode
|
|
65001
65204
|
},
|
|
65002
65205
|
ws.workspace_uuid
|
|
65003
65206
|
);
|
|
@@ -65015,7 +65218,10 @@ function LoginView({
|
|
|
65015
65218
|
logoSrc = optifye_logo_default,
|
|
65016
65219
|
logoAlt = "Optifye",
|
|
65017
65220
|
brandName = "Optifye",
|
|
65018
|
-
onRateLimitCheck
|
|
65221
|
+
onRateLimitCheck,
|
|
65222
|
+
showDevTestLogin = false,
|
|
65223
|
+
devTestLoginLabel,
|
|
65224
|
+
onDevTestLogin
|
|
65019
65225
|
}) {
|
|
65020
65226
|
return /* @__PURE__ */ jsx(
|
|
65021
65227
|
LoginPage,
|
|
@@ -65023,7 +65229,10 @@ function LoginView({
|
|
|
65023
65229
|
logoSrc,
|
|
65024
65230
|
logoAlt,
|
|
65025
65231
|
brandName,
|
|
65026
|
-
onRateLimitCheck
|
|
65232
|
+
onRateLimitCheck,
|
|
65233
|
+
showDevTestLogin,
|
|
65234
|
+
devTestLoginLabel,
|
|
65235
|
+
onDevTestLogin
|
|
65027
65236
|
}
|
|
65028
65237
|
);
|
|
65029
65238
|
}
|
|
@@ -68211,20 +68420,30 @@ function useTimezone(options = {}) {
|
|
|
68211
68420
|
}
|
|
68212
68421
|
|
|
68213
68422
|
// src/views/workspace-detail-view.utils.ts
|
|
68214
|
-
var
|
|
68423
|
+
var getWorkspaceDetailLayoutMode = ({
|
|
68215
68424
|
workspace,
|
|
68216
68425
|
showCycleTimeChart
|
|
68217
68426
|
}) => {
|
|
68218
68427
|
if (workspace?.monitoring_mode === "uptime") {
|
|
68219
|
-
return "
|
|
68428
|
+
return "uptime";
|
|
68220
68429
|
}
|
|
68221
68430
|
if (showCycleTimeChart === false) {
|
|
68222
68431
|
return "output";
|
|
68223
68432
|
}
|
|
68224
|
-
|
|
68433
|
+
return shouldUseAssemblyCycleTimeLayout(workspace) ? "assembly_cycle" : "output";
|
|
68434
|
+
};
|
|
68435
|
+
var getCycleTimeRenderState = ({
|
|
68436
|
+
workspace,
|
|
68437
|
+
authoritativeMetrics,
|
|
68438
|
+
showCycleTimeChart
|
|
68439
|
+
}) => {
|
|
68440
|
+
if (getWorkspaceDetailLayoutMode({ workspace, showCycleTimeChart }) !== "assembly_cycle") {
|
|
68225
68441
|
return "output";
|
|
68226
68442
|
}
|
|
68227
|
-
|
|
68443
|
+
if (!authoritativeMetrics) {
|
|
68444
|
+
return "chart_loading";
|
|
68445
|
+
}
|
|
68446
|
+
return authoritativeMetrics.cycle_time_data_status === "missing_clips" ? "cycle_unavailable" : "cycle_chart";
|
|
68228
68447
|
};
|
|
68229
68448
|
var formatDateInTimezone = (date = /* @__PURE__ */ new Date(), timezone, options) => {
|
|
68230
68449
|
const defaultOptions = {
|
|
@@ -68632,33 +68851,34 @@ var WorkspaceDetailView = ({
|
|
|
68632
68851
|
idle_time_hourly: void 0
|
|
68633
68852
|
};
|
|
68634
68853
|
}, [cachedOverviewMetrics, shiftConfig?.shifts]);
|
|
68635
|
-
const
|
|
68854
|
+
const authoritativeCycleMetrics = isHistoricView ? historicMetrics : liveMetrics;
|
|
68855
|
+
const workspace = authoritativeCycleMetrics || cachedDetailedMetrics || overviewFallback;
|
|
68636
68856
|
const { timezone: cycleTimeTimezone } = useTimezone({
|
|
68637
68857
|
lineId: effectiveLineId || workspace?.line_id || void 0,
|
|
68638
68858
|
workspaceId: workspaceId || void 0
|
|
68639
68859
|
});
|
|
68640
68860
|
const effectiveCycleTimeTimezone = cycleTimeTimezone || timezone;
|
|
68641
|
-
const detailedWorkspaceMetrics =
|
|
68861
|
+
const detailedWorkspaceMetrics = authoritativeCycleMetrics || cachedDetailedMetrics;
|
|
68642
68862
|
const cycleTimeChartData = useMemo(
|
|
68643
|
-
() => Array.isArray(
|
|
68863
|
+
() => Array.isArray(authoritativeCycleMetrics?.hourly_cycle_times) ? authoritativeCycleMetrics.hourly_cycle_times.map((value) => {
|
|
68644
68864
|
const numericValue = Number(value);
|
|
68645
68865
|
return Number.isFinite(numericValue) ? numericValue : 0;
|
|
68646
68866
|
}) : [],
|
|
68647
|
-
[
|
|
68867
|
+
[authoritativeCycleMetrics?.hourly_cycle_times]
|
|
68648
68868
|
);
|
|
68649
68869
|
const maskedCycleTimeChartData = useMemo(
|
|
68650
68870
|
() => maskFutureHourlySeries({
|
|
68651
68871
|
data: cycleTimeChartData,
|
|
68652
|
-
shiftStart:
|
|
68653
|
-
shiftEnd:
|
|
68654
|
-
shiftDate:
|
|
68872
|
+
shiftStart: authoritativeCycleMetrics?.shift_start,
|
|
68873
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end,
|
|
68874
|
+
shiftDate: authoritativeCycleMetrics?.date || date || calculatedOperationalDate || null,
|
|
68655
68875
|
timezone: effectiveCycleTimeTimezone
|
|
68656
68876
|
}),
|
|
68657
68877
|
[
|
|
68658
68878
|
cycleTimeChartData,
|
|
68659
|
-
|
|
68660
|
-
|
|
68661
|
-
|
|
68879
|
+
authoritativeCycleMetrics?.shift_start,
|
|
68880
|
+
authoritativeCycleMetrics?.shift_end,
|
|
68881
|
+
authoritativeCycleMetrics?.date,
|
|
68662
68882
|
date,
|
|
68663
68883
|
calculatedOperationalDate,
|
|
68664
68884
|
effectiveCycleTimeTimezone
|
|
@@ -68666,13 +68886,13 @@ var WorkspaceDetailView = ({
|
|
|
68666
68886
|
);
|
|
68667
68887
|
const cycleTimeDatasetKey = useMemo(
|
|
68668
68888
|
() => [
|
|
68669
|
-
|
|
68670
|
-
date ||
|
|
68671
|
-
parsedShiftId ??
|
|
68889
|
+
authoritativeCycleMetrics?.workspace_id || workspaceId || "workspace",
|
|
68890
|
+
date || authoritativeCycleMetrics?.date || "live",
|
|
68891
|
+
parsedShiftId ?? authoritativeCycleMetrics?.shift_id ?? "current",
|
|
68672
68892
|
"hourly",
|
|
68673
68893
|
"backend"
|
|
68674
68894
|
].join(":"),
|
|
68675
|
-
[
|
|
68895
|
+
[authoritativeCycleMetrics?.workspace_id, workspaceId, date, authoritativeCycleMetrics?.date, parsedShiftId, authoritativeCycleMetrics?.shift_id]
|
|
68676
68896
|
);
|
|
68677
68897
|
const hasWorkspaceSnapshot = Boolean(workspace);
|
|
68678
68898
|
const loading = ((isHistoricView ? historicLoading : liveLoading) || isShiftConfigLoading) && !hasWorkspaceSnapshot;
|
|
@@ -68921,30 +69141,46 @@ var WorkspaceDetailView = ({
|
|
|
68921
69141
|
action_type: workspace.action_type
|
|
68922
69142
|
} : null;
|
|
68923
69143
|
const isAssemblyWorkspace = shouldUseAssemblyCycleTimeLayout(workspaceCycleTimeEligibility);
|
|
68924
|
-
const
|
|
69144
|
+
const layoutMode = getWorkspaceDetailLayoutMode({
|
|
69145
|
+
workspace: workspace ? {
|
|
69146
|
+
monitoring_mode: workspace.monitoring_mode,
|
|
69147
|
+
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
69148
|
+
action_family: workspace.action_family,
|
|
69149
|
+
action_type: workspace.action_type
|
|
69150
|
+
} : null,
|
|
69151
|
+
showCycleTimeChart
|
|
69152
|
+
});
|
|
69153
|
+
const isAssemblyCycleLayout = layoutMode === "assembly_cycle";
|
|
69154
|
+
const isOutputLayout = layoutMode === "output";
|
|
69155
|
+
const cycleTimePresentation = getCycleTimeRenderState({
|
|
68925
69156
|
workspace: workspace ? {
|
|
68926
69157
|
monitoring_mode: workspace.monitoring_mode,
|
|
68927
69158
|
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
68928
69159
|
action_family: workspace.action_family,
|
|
68929
|
-
action_type: workspace.action_type
|
|
68930
|
-
|
|
69160
|
+
action_type: workspace.action_type
|
|
69161
|
+
} : null,
|
|
69162
|
+
authoritativeMetrics: authoritativeCycleMetrics ? {
|
|
69163
|
+
cycle_time_data_status: authoritativeCycleMetrics.cycle_time_data_status
|
|
68931
69164
|
} : null,
|
|
68932
69165
|
showCycleTimeChart
|
|
68933
69166
|
});
|
|
68934
|
-
const shouldShowCycleTimeChart = cycleTimePresentation
|
|
69167
|
+
const shouldShowCycleTimeChart = cycleTimePresentation === "cycle_chart";
|
|
68935
69168
|
const shouldShowCycleTimeUnavailableState = cycleTimePresentation === "cycle_unavailable";
|
|
68936
|
-
const
|
|
69169
|
+
const shouldShowCycleTimeLoadingState = cycleTimePresentation === "chart_loading";
|
|
69170
|
+
const shouldShowAssemblyOverviewLoadingState = isAssemblyCycleLayout && shouldShowCycleTimeLoadingState && hasWorkspaceSnapshot;
|
|
69171
|
+
const showIdleBreakdownChart = !isAssemblyCycleLayout && idleTimeVlmEnabled;
|
|
69172
|
+
const canToggleChartIdleTime = !isUptimeMode && !shouldShowCycleTimeLoadingState && !shouldShowCycleTimeUnavailableState;
|
|
68937
69173
|
const idleClipDate = date || workspace?.date || calculatedOperationalDate || getOperationalDate(timezone);
|
|
68938
69174
|
const idleClipShiftId = parsedShiftId ?? workspace?.shift_id;
|
|
68939
69175
|
const rawHourlyIdleMinutes = useMemo(() => {
|
|
68940
69176
|
if (!shouldShowCycleTimeChart || !workspace?.idle_time_hourly || !workspace?.shift_start) return [];
|
|
68941
|
-
const
|
|
69177
|
+
const parseTimeToMinutes4 = (time2) => {
|
|
68942
69178
|
const [h, m] = time2.split(":").map(Number);
|
|
68943
69179
|
if (!Number.isFinite(h) || !Number.isFinite(m)) return 0;
|
|
68944
69180
|
return h * 60 + m;
|
|
68945
69181
|
};
|
|
68946
|
-
const startTotal =
|
|
68947
|
-
const endTotalRaw = workspace.shift_end ?
|
|
69182
|
+
const startTotal = parseTimeToMinutes4(workspace.shift_start);
|
|
69183
|
+
const endTotalRaw = workspace.shift_end ? parseTimeToMinutes4(workspace.shift_end) : startTotal + 11 * 60;
|
|
68948
69184
|
const endTotal = endTotalRaw <= startTotal ? endTotalRaw + 24 * 60 : endTotalRaw;
|
|
68949
69185
|
const shiftDuration = Math.max(60, endTotal - startTotal);
|
|
68950
69186
|
const totalHourSlots = Math.max(1, Math.ceil(shiftDuration / 60));
|
|
@@ -68994,6 +69230,18 @@ var WorkspaceDetailView = ({
|
|
|
68994
69230
|
workspace.cycle_completion_clip_count
|
|
68995
69231
|
] })
|
|
68996
69232
|
] }), [workspace?.cycle_completion_clip_count]);
|
|
69233
|
+
const assemblyOverviewLoadingView = useMemo(() => /* @__PURE__ */ jsxs("div", { className: "space-y-4 pb-4", "data-testid": "assembly-overview-loading-state", children: [
|
|
69234
|
+
/* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg shadow-sm p-6 lg:p-8", children: /* @__PURE__ */ jsx("div", { className: "min-h-[280px] lg:min-h-[340px] flex flex-col justify-center", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-xl mx-auto animate-pulse space-y-3", children: [
|
|
69235
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 bg-gray-200 rounded-full w-3/4 mx-auto" }),
|
|
69236
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 bg-gray-100 rounded-full w-full" }),
|
|
69237
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 bg-gray-100 rounded-full w-5/6 mx-auto" })
|
|
69238
|
+
] }) }) }),
|
|
69239
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: [0, 1, 2].map((index) => /* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg shadow-sm p-5", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse space-y-3", children: [
|
|
69240
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-24 bg-gray-200 rounded" }),
|
|
69241
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 w-20 bg-gray-100 rounded" }),
|
|
69242
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 w-28 bg-gray-100 rounded" })
|
|
69243
|
+
] }) }, index)) })
|
|
69244
|
+
] }), []);
|
|
68997
69245
|
const shiftDurationMinutes = useMemo(
|
|
68998
69246
|
() => getShiftDurationMinutes(workspace?.shift_start, workspace?.shift_end),
|
|
68999
69247
|
[workspace?.shift_start, workspace?.shift_end]
|
|
@@ -69048,7 +69296,7 @@ var WorkspaceDetailView = ({
|
|
|
69048
69296
|
}, [isUptimeMode, uptimeSeries, shiftDurationMinutes, elapsedShiftMinutes, workspace?.idle_time]);
|
|
69049
69297
|
const overviewTabLabel = isUptimeMode ? "Utilization" : "Efficiency";
|
|
69050
69298
|
const idleClipFetchEnabled = Boolean(
|
|
69051
|
-
workspaceId && idleClipDate && idleClipShiftId !== void 0 && activeTab === "overview" && idleTimeVlmEnabled &&
|
|
69299
|
+
workspaceId && idleClipDate && idleClipShiftId !== void 0 && activeTab === "overview" && idleTimeVlmEnabled && isOutputLayout
|
|
69052
69300
|
);
|
|
69053
69301
|
const {
|
|
69054
69302
|
idleClips: idleTimeClips,
|
|
@@ -69119,7 +69367,7 @@ var WorkspaceDetailView = ({
|
|
|
69119
69367
|
}
|
|
69120
69368
|
}
|
|
69121
69369
|
};
|
|
69122
|
-
const
|
|
69370
|
+
const getShiftIcon2 = (shiftType) => {
|
|
69123
69371
|
const shiftTypeLower = shiftType?.toLowerCase() || "";
|
|
69124
69372
|
if (shiftTypeLower.includes("day") || shiftTypeLower.includes("morning")) {
|
|
69125
69373
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
@@ -69268,7 +69516,7 @@ var WorkspaceDetailView = ({
|
|
|
69268
69516
|
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: (() => {
|
|
69269
69517
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
69270
69518
|
const shiftName = shift2?.shiftName || (selectedShift === 0 ? "Day Shift" : "Night Shift");
|
|
69271
|
-
return
|
|
69519
|
+
return getShiftIcon2(shiftName);
|
|
69272
69520
|
})() }),
|
|
69273
69521
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: (() => {
|
|
69274
69522
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
@@ -69296,7 +69544,7 @@ var WorkspaceDetailView = ({
|
|
|
69296
69544
|
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: (() => {
|
|
69297
69545
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
69298
69546
|
const shiftName = shift2?.shiftName || (selectedShift === 0 ? "Day Shift" : "Night Shift");
|
|
69299
|
-
return
|
|
69547
|
+
return getShiftIcon2(shiftName);
|
|
69300
69548
|
})() }),
|
|
69301
69549
|
/* @__PURE__ */ jsx("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: (() => {
|
|
69302
69550
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
@@ -69309,7 +69557,7 @@ var WorkspaceDetailView = ({
|
|
|
69309
69557
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
|
|
69310
69558
|
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-gray-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: formatISTDate2(new Date(workspace.date)) }) }),
|
|
69311
69559
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
69312
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
69560
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(workspace.shift_type) }),
|
|
69313
69561
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: workspace.shift_type })
|
|
69314
69562
|
] }),
|
|
69315
69563
|
!date && !shift && !usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-green-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-green-700", children: /* @__PURE__ */ jsx(LiveTimer, {}) }) }) : date ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-blue-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-blue-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-amber-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-amber-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : null
|
|
@@ -69340,7 +69588,7 @@ var WorkspaceDetailView = ({
|
|
|
69340
69588
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" })
|
|
69341
69589
|
] }),
|
|
69342
69590
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
69343
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
69591
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(workspace.shift_type) }),
|
|
69344
69592
|
/* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: [
|
|
69345
69593
|
workspace.shift_type.replace(/ Shift$/i, ""),
|
|
69346
69594
|
" Shift"
|
|
@@ -69459,9 +69707,9 @@ var WorkspaceDetailView = ({
|
|
|
69459
69707
|
] })
|
|
69460
69708
|
] }),
|
|
69461
69709
|
/* @__PURE__ */ jsxs("div", { className: "flex-grow p-1.5 sm:p-2 lg:p-4", children: [
|
|
69462
|
-
activeTab === "overview" && /* @__PURE__ */
|
|
69710
|
+
activeTab === "overview" && /* @__PURE__ */ jsx("div", { className: "flex flex-col h-full lg:h-[calc(100vh-12rem)] overflow-y-auto lg:min-h-0 pb-4", children: shouldShowAssemblyOverviewLoadingState ? assemblyOverviewLoadingView : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
69463
69711
|
/* @__PURE__ */ jsxs("div", { className: "block lg:hidden space-y-6 pb-6", children: [
|
|
69464
|
-
|
|
69712
|
+
isOutputLayout && !isUptimeMode && /* @__PURE__ */ jsxs(
|
|
69465
69713
|
motion.div,
|
|
69466
69714
|
{
|
|
69467
69715
|
className: "bg-white rounded-lg shadow-sm p-6 h-[300px]",
|
|
@@ -69489,8 +69737,8 @@ var WorkspaceDetailView = ({
|
|
|
69489
69737
|
animate: "animate",
|
|
69490
69738
|
children: [
|
|
69491
69739
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
|
|
69492
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" :
|
|
69493
|
-
|
|
69740
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : isAssemblyCycleLayout ? "Cycle time trend" : "Hourly Output" }),
|
|
69741
|
+
canToggleChartIdleTime && /* @__PURE__ */ jsx(
|
|
69494
69742
|
"button",
|
|
69495
69743
|
{
|
|
69496
69744
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69519,19 +69767,19 @@ var WorkspaceDetailView = ({
|
|
|
69519
69767
|
timezone,
|
|
69520
69768
|
elapsedMinutes: elapsedShiftMinutes
|
|
69521
69769
|
}
|
|
69522
|
-
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69770
|
+
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69523
69771
|
CycleTimeOverTimeChart,
|
|
69524
69772
|
{
|
|
69525
69773
|
data: maskedCycleTimeChartData,
|
|
69526
|
-
idealCycleTime:
|
|
69527
|
-
shiftStart:
|
|
69528
|
-
shiftEnd:
|
|
69774
|
+
idealCycleTime: authoritativeCycleMetrics?.ideal_cycle_time || 0,
|
|
69775
|
+
shiftStart: authoritativeCycleMetrics?.shift_start || "",
|
|
69776
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end || "",
|
|
69529
69777
|
xAxisMode: "hourly",
|
|
69530
69778
|
datasetKey: cycleTimeDatasetKey,
|
|
69531
69779
|
showIdleTime: showChartIdleTime,
|
|
69532
69780
|
idleTimeData: hourlyIdleMinutes
|
|
69533
69781
|
}
|
|
69534
|
-
) : /* @__PURE__ */ jsx(
|
|
69782
|
+
) : null : /* @__PURE__ */ jsx(
|
|
69535
69783
|
HourlyOutputChart2,
|
|
69536
69784
|
{
|
|
69537
69785
|
data: workspace.hourly_action_counts || [],
|
|
@@ -69551,7 +69799,7 @@ var WorkspaceDetailView = ({
|
|
|
69551
69799
|
]
|
|
69552
69800
|
}
|
|
69553
69801
|
),
|
|
69554
|
-
|
|
69802
|
+
showIdleBreakdownChart && /* @__PURE__ */ jsxs(
|
|
69555
69803
|
motion.div,
|
|
69556
69804
|
{
|
|
69557
69805
|
className: "bg-white rounded-lg shadow-sm p-4 h-[300px]",
|
|
@@ -69571,7 +69819,7 @@ var WorkspaceDetailView = ({
|
|
|
69571
69819
|
]
|
|
69572
69820
|
}
|
|
69573
69821
|
),
|
|
69574
|
-
isUptimeMode ? /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData }) :
|
|
69822
|
+
isUptimeMode ? /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData }) : isAssemblyCycleLayout ? /* @__PURE__ */ jsx(
|
|
69575
69823
|
WorkspaceCycleTimeMetricCards,
|
|
69576
69824
|
{
|
|
69577
69825
|
workspace,
|
|
@@ -69591,7 +69839,7 @@ var WorkspaceDetailView = ({
|
|
|
69591
69839
|
desktopTopSectionClass
|
|
69592
69840
|
),
|
|
69593
69841
|
children: [
|
|
69594
|
-
|
|
69842
|
+
isOutputLayout && !isUptimeMode && /* @__PURE__ */ jsxs(
|
|
69595
69843
|
motion.div,
|
|
69596
69844
|
{
|
|
69597
69845
|
className: "bg-white rounded-lg shadow-sm p-4 lg:col-span-2 flex flex-col min-h-0",
|
|
@@ -69615,15 +69863,15 @@ var WorkspaceDetailView = ({
|
|
|
69615
69863
|
{
|
|
69616
69864
|
className: clsx(
|
|
69617
69865
|
"bg-white rounded-lg shadow-sm p-4 flex flex-col min-h-0",
|
|
69618
|
-
isUptimeMode && showIdleBreakdownChart ? "lg:col-span-2" :
|
|
69866
|
+
isUptimeMode && showIdleBreakdownChart ? "lg:col-span-2" : isAssemblyCycleLayout || isUptimeMode ? "lg:col-span-10" : idleTimeVlmEnabled ? "lg:col-span-6" : "lg:col-span-8"
|
|
69619
69867
|
),
|
|
69620
69868
|
variants: chartCardVariants,
|
|
69621
69869
|
initial: "initial",
|
|
69622
69870
|
animate: "animate",
|
|
69623
69871
|
children: [
|
|
69624
69872
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 mb-4 flex-none", children: [
|
|
69625
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" :
|
|
69626
|
-
|
|
69873
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : isAssemblyCycleLayout ? "Cycle time trend" : "Hourly Output" }),
|
|
69874
|
+
canToggleChartIdleTime && /* @__PURE__ */ jsx(
|
|
69627
69875
|
"button",
|
|
69628
69876
|
{
|
|
69629
69877
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69648,19 +69896,19 @@ var WorkspaceDetailView = ({
|
|
|
69648
69896
|
timezone,
|
|
69649
69897
|
elapsedMinutes: elapsedShiftMinutes
|
|
69650
69898
|
}
|
|
69651
|
-
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69899
|
+
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69652
69900
|
CycleTimeOverTimeChart,
|
|
69653
69901
|
{
|
|
69654
69902
|
data: maskedCycleTimeChartData,
|
|
69655
|
-
idealCycleTime:
|
|
69656
|
-
shiftStart:
|
|
69657
|
-
shiftEnd:
|
|
69903
|
+
idealCycleTime: authoritativeCycleMetrics?.ideal_cycle_time || 0,
|
|
69904
|
+
shiftStart: authoritativeCycleMetrics?.shift_start || "",
|
|
69905
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end || "",
|
|
69658
69906
|
xAxisMode: "hourly",
|
|
69659
69907
|
datasetKey: cycleTimeDatasetKey,
|
|
69660
69908
|
showIdleTime: showChartIdleTime,
|
|
69661
69909
|
idleTimeData: hourlyIdleMinutes
|
|
69662
69910
|
}
|
|
69663
|
-
) : /* @__PURE__ */ jsx(
|
|
69911
|
+
) : null : /* @__PURE__ */ jsx(
|
|
69664
69912
|
HourlyOutputChart2,
|
|
69665
69913
|
{
|
|
69666
69914
|
data: workspace.hourly_action_counts || [],
|
|
@@ -69678,7 +69926,7 @@ var WorkspaceDetailView = ({
|
|
|
69678
69926
|
]
|
|
69679
69927
|
}
|
|
69680
69928
|
),
|
|
69681
|
-
|
|
69929
|
+
showIdleBreakdownChart && /* @__PURE__ */ jsxs(
|
|
69682
69930
|
motion.div,
|
|
69683
69931
|
{
|
|
69684
69932
|
className: clsx(
|
|
@@ -69704,7 +69952,7 @@ var WorkspaceDetailView = ({
|
|
|
69704
69952
|
]
|
|
69705
69953
|
}
|
|
69706
69954
|
),
|
|
69707
|
-
isUptimeMode ? /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData, className: "flex-1" }) }) :
|
|
69955
|
+
isUptimeMode ? /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData, className: "flex-1" }) }) : isAssemblyCycleLayout ? /* @__PURE__ */ jsx(
|
|
69708
69956
|
WorkspaceCycleTimeMetricCards,
|
|
69709
69957
|
{
|
|
69710
69958
|
workspace,
|
|
@@ -69715,7 +69963,7 @@ var WorkspaceDetailView = ({
|
|
|
69715
69963
|
}
|
|
69716
69964
|
) : /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, legend: efficiencyLegend, className: "flex-1" }) })
|
|
69717
69965
|
] })
|
|
69718
|
-
] }),
|
|
69966
|
+
] }) }),
|
|
69719
69967
|
activeTab === "monthly_history" && /* @__PURE__ */ jsxs("div", { className: "h-[calc(100vh-10rem)] overflow-y-auto px-2 sm:px-4 lg:px-0", children: [
|
|
69720
69968
|
usingFallbackData && !date && !shift && /* @__PURE__ */ jsx("div", { className: "mb-3 sm:mb-4 bg-amber-50 border border-amber-200 rounded-lg px-3 sm:px-4 py-2 sm:py-3 text-amber-800", children: /* @__PURE__ */ jsxs("p", { className: "text-xs sm:text-sm font-medium flex items-center", children: [
|
|
69721
69969
|
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-4 w-4 sm:h-5 sm:w-5 mr-2", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }),
|
|
@@ -72347,7 +72595,7 @@ var normalizeLabel = (value) => {
|
|
|
72347
72595
|
const trimmed = value.trim();
|
|
72348
72596
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
72349
72597
|
};
|
|
72350
|
-
var
|
|
72598
|
+
var toFiniteNumber2 = (value) => {
|
|
72351
72599
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
72352
72600
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
72353
72601
|
const parsed = Number(value);
|
|
@@ -72381,7 +72629,7 @@ var formatImprovementPieceGain = (pcsGain) => {
|
|
|
72381
72629
|
var getPositiveImprovementGain = ({
|
|
72382
72630
|
estimated_gain_pieces
|
|
72383
72631
|
}) => {
|
|
72384
|
-
const issueGain =
|
|
72632
|
+
const issueGain = toFiniteNumber2(estimated_gain_pieces);
|
|
72385
72633
|
return {
|
|
72386
72634
|
pcsGain: issueGain !== null && issueGain > 0 ? issueGain : null
|
|
72387
72635
|
};
|
|
@@ -72389,7 +72637,7 @@ var getPositiveImprovementGain = ({
|
|
|
72389
72637
|
var getImprovementPcsGainSortValue = (input) => {
|
|
72390
72638
|
const { pcsGain } = getPositiveImprovementGain(input);
|
|
72391
72639
|
if (pcsGain !== null) return pcsGain;
|
|
72392
|
-
const raw =
|
|
72640
|
+
const raw = toFiniteNumber2(input.estimated_gain_pieces);
|
|
72393
72641
|
return raw ?? null;
|
|
72394
72642
|
};
|
|
72395
72643
|
var getImprovementDisplayMetadata = ({
|
|
@@ -72409,7 +72657,7 @@ var getImprovementDisplayMetadata = ({
|
|
|
72409
72657
|
metadataLabel: [workstationLabel, lineLabel, supervisorLabel].join(" \xB7 ")
|
|
72410
72658
|
};
|
|
72411
72659
|
};
|
|
72412
|
-
var
|
|
72660
|
+
var toFiniteNumber3 = (value) => {
|
|
72413
72661
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
72414
72662
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
72415
72663
|
const parsed = Number(value);
|
|
@@ -72437,15 +72685,15 @@ var compareImprovementRecommendationPriority = (left, right) => {
|
|
|
72437
72685
|
if (leftIndustrial !== rightIndustrial) {
|
|
72438
72686
|
return rightIndustrial - leftIndustrial;
|
|
72439
72687
|
}
|
|
72440
|
-
const leftGain =
|
|
72441
|
-
const rightGain =
|
|
72688
|
+
const leftGain = toFiniteNumber3(left.estimated_gain_pieces);
|
|
72689
|
+
const rightGain = toFiniteNumber3(right.estimated_gain_pieces);
|
|
72442
72690
|
if (leftGain !== rightGain) {
|
|
72443
72691
|
if (leftGain === null) return 1;
|
|
72444
72692
|
if (rightGain === null) return -1;
|
|
72445
72693
|
return rightGain - leftGain;
|
|
72446
72694
|
}
|
|
72447
|
-
const leftRatio =
|
|
72448
|
-
const rightRatio =
|
|
72695
|
+
const leftRatio = toFiniteNumber3(left.gain_to_target_ratio);
|
|
72696
|
+
const rightRatio = toFiniteNumber3(right.gain_to_target_ratio);
|
|
72449
72697
|
if (leftRatio !== rightRatio) {
|
|
72450
72698
|
if (leftRatio === null) return 1;
|
|
72451
72699
|
if (rightRatio === null) return -1;
|
|
@@ -75750,6 +75998,7 @@ var EMPTY_OVERVIEW_POOREST_LINES = {
|
|
|
75750
75998
|
};
|
|
75751
75999
|
var EMPTY_OVERVIEW_TREND = {
|
|
75752
76000
|
shift_mode: "all",
|
|
76001
|
+
granularity: "day",
|
|
75753
76002
|
points: []
|
|
75754
76003
|
};
|
|
75755
76004
|
var EMPTY_IDLE_BREAKDOWN = [];
|
|
@@ -75822,8 +76071,11 @@ var normalizePoorestLines = (value) => ({
|
|
|
75822
76071
|
});
|
|
75823
76072
|
var normalizeTrend = (value) => ({
|
|
75824
76073
|
shift_mode: value?.shift_mode || "all",
|
|
76074
|
+
granularity: value?.granularity === "hour" ? "hour" : "day",
|
|
75825
76075
|
points: (value?.points || []).map((point) => ({
|
|
75826
76076
|
date: point?.date,
|
|
76077
|
+
label: point?.label,
|
|
76078
|
+
hour_index: normalizeNumber(point?.hour_index),
|
|
75827
76079
|
avg_efficiency: normalizeNumber(point?.avg_efficiency)
|
|
75828
76080
|
}))
|
|
75829
76081
|
});
|
|
@@ -76165,17 +76417,25 @@ var formatSignedIdleDuration = (seconds) => {
|
|
|
76165
76417
|
const sign = seconds > 0 ? "+" : "-";
|
|
76166
76418
|
return `${sign}${formatIdleDuration(Math.abs(seconds))}`;
|
|
76167
76419
|
};
|
|
76168
|
-
var formatComparisonWindow = (
|
|
76420
|
+
var formatComparisonWindow = ({
|
|
76421
|
+
currentDayCount,
|
|
76422
|
+
previousDayCount,
|
|
76423
|
+
comparisonStrategy,
|
|
76424
|
+
shiftMode
|
|
76425
|
+
}) => {
|
|
76169
76426
|
if (comparisonStrategy === "previous_full_week") return "last week";
|
|
76170
|
-
if (
|
|
76171
|
-
|
|
76427
|
+
if (comparisonStrategy === "matched_range" && shiftMode !== "all" && currentDayCount === 1 && previousDayCount === 1) {
|
|
76428
|
+
return "previous day";
|
|
76429
|
+
}
|
|
76430
|
+
if (!previousDayCount || !Number.isFinite(previousDayCount)) return "previous range";
|
|
76431
|
+
return `previous ${previousDayCount} ${previousDayCount === 1 ? "day" : "days"}`;
|
|
76172
76432
|
};
|
|
76173
76433
|
var buildDeltaBadge = (delta, options) => {
|
|
76174
76434
|
if (delta === null || delta === void 0 || !Number.isFinite(delta)) {
|
|
76175
76435
|
return {
|
|
76176
76436
|
icon: null,
|
|
76177
|
-
className: "bg-slate-100 text-slate-
|
|
76178
|
-
text:
|
|
76437
|
+
className: "bg-slate-100 text-slate-400",
|
|
76438
|
+
text: "\u2014"
|
|
76179
76439
|
};
|
|
76180
76440
|
}
|
|
76181
76441
|
const direction = delta >= 0 ? "up" : "down";
|
|
@@ -76186,6 +76446,25 @@ var buildDeltaBadge = (delta, options) => {
|
|
|
76186
76446
|
text: `${options.formatter(delta)} vs ${options.comparisonLabel}`
|
|
76187
76447
|
};
|
|
76188
76448
|
};
|
|
76449
|
+
var normalizeShiftLabel = (shiftName, shiftMode) => {
|
|
76450
|
+
const trimmedName = shiftName?.trim();
|
|
76451
|
+
if (trimmedName) {
|
|
76452
|
+
return /shift/i.test(trimmedName) ? trimmedName : `${trimmedName} Shift`;
|
|
76453
|
+
}
|
|
76454
|
+
if (shiftMode === "night") return "Night Shift";
|
|
76455
|
+
return "Day Shift";
|
|
76456
|
+
};
|
|
76457
|
+
var getShiftIcon = (shiftName, shiftMode) => {
|
|
76458
|
+
const normalizedName = (shiftName || "").toLowerCase();
|
|
76459
|
+
const normalizedMode = shiftMode || "day";
|
|
76460
|
+
if (normalizedName.includes("day") || normalizedName.includes("morning") || normalizedMode === "day") {
|
|
76461
|
+
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
76462
|
+
}
|
|
76463
|
+
if (normalizedName.includes("night") || normalizedName.includes("evening") || normalizedMode === "night") {
|
|
76464
|
+
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" }) });
|
|
76465
|
+
}
|
|
76466
|
+
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" }) });
|
|
76467
|
+
};
|
|
76189
76468
|
var buildLineDeltaTone = (delta, comparisonLabel) => {
|
|
76190
76469
|
if (delta === null || delta === void 0 || !Number.isFinite(delta)) {
|
|
76191
76470
|
return {
|
|
@@ -76241,6 +76520,8 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76241
76520
|
dateRange,
|
|
76242
76521
|
displayDateRange,
|
|
76243
76522
|
trendMode,
|
|
76523
|
+
isLiveScope,
|
|
76524
|
+
liveShiftName,
|
|
76244
76525
|
lineOptions,
|
|
76245
76526
|
supervisorOptions,
|
|
76246
76527
|
selectedSupervisorId,
|
|
@@ -76254,6 +76535,14 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76254
76535
|
}) => {
|
|
76255
76536
|
bumpRenderCounter();
|
|
76256
76537
|
const subtitleRange = displayDateRange || dateRange;
|
|
76538
|
+
const liveShiftLabel = React141__default.useMemo(
|
|
76539
|
+
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
76540
|
+
[liveShiftName, trendMode]
|
|
76541
|
+
);
|
|
76542
|
+
const liveShiftIcon = React141__default.useMemo(
|
|
76543
|
+
() => getShiftIcon(liveShiftName, trendMode),
|
|
76544
|
+
[liveShiftName, trendMode]
|
|
76545
|
+
);
|
|
76257
76546
|
const [isFilterOpen, setIsFilterOpen] = React141__default.useState(false);
|
|
76258
76547
|
const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React141__default.useState(false);
|
|
76259
76548
|
const filterRef = React141__default.useRef(null);
|
|
@@ -76370,9 +76659,25 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76370
76659
|
className: "flex-shrink-0 -ml-1"
|
|
76371
76660
|
}
|
|
76372
76661
|
) : /* @__PURE__ */ jsx("div", { className: "w-8 flex-shrink-0" }),
|
|
76373
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center", children: [
|
|
76374
|
-
/* @__PURE__ */
|
|
76375
|
-
|
|
76662
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center min-w-0", children: [
|
|
76663
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-1.5 min-w-0 max-w-[240px]", children: [
|
|
76664
|
+
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900 leading-tight text-center truncate", children: "Operations Overview" }),
|
|
76665
|
+
isLiveScope ? /* @__PURE__ */ jsx(
|
|
76666
|
+
"div",
|
|
76667
|
+
{
|
|
76668
|
+
"data-testid": "operations-overview-live-indicator",
|
|
76669
|
+
className: "h-2 w-2 rounded-full bg-emerald-500 animate-pulse ring-2 ring-emerald-500/20 flex-shrink-0"
|
|
76670
|
+
}
|
|
76671
|
+
) : null
|
|
76672
|
+
] }),
|
|
76673
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1 flex flex-wrap items-center justify-center gap-x-2 gap-y-1 text-[11px] font-medium text-slate-500 min-w-0", children: [
|
|
76674
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-center", children: mobileSubtitle }),
|
|
76675
|
+
isLiveScope ? /* @__PURE__ */ jsx("span", { className: "text-slate-300", children: "|" }) : null,
|
|
76676
|
+
isLiveScope ? /* @__PURE__ */ jsx("span", { "data-testid": "operations-overview-live-meta", className: "inline-flex items-center gap-1.5 text-gray-600 min-w-0", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 justify-center truncate", children: [
|
|
76677
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-75 shrink-0", children: liveShiftIcon }),
|
|
76678
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: liveShiftLabel })
|
|
76679
|
+
] }) }) : null
|
|
76680
|
+
] })
|
|
76376
76681
|
] }),
|
|
76377
76682
|
/* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 flex items-center gap-1.5", children: [
|
|
76378
76683
|
/* @__PURE__ */ jsx(
|
|
@@ -76391,22 +76696,40 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76391
76696
|
{
|
|
76392
76697
|
ref: mobileFilterButtonRef,
|
|
76393
76698
|
onClick: handleFilterToggle,
|
|
76394
|
-
className: `p-2 rounded-full transition-colors relative ${isFilterOpen || activeFilterCount > 0 ? "bg-
|
|
76699
|
+
className: `p-2 rounded-full transition-colors relative ${isFilterOpen || activeFilterCount > 0 ? "bg-slate-100 text-slate-700" : "active:bg-gray-100 text-slate-600"}`,
|
|
76395
76700
|
"aria-label": "Open filters",
|
|
76396
76701
|
children: [
|
|
76397
|
-
/* @__PURE__ */ jsx(Filter, { className:
|
|
76398
|
-
activeFilterCount > 0 ? /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 flex items-center justify-center w-4 h-4 bg-
|
|
76702
|
+
/* @__PURE__ */ jsx(Filter, { className: "w-5 h-5" }),
|
|
76703
|
+
activeFilterCount > 0 ? /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 flex items-center justify-center w-4 h-4 bg-slate-700 text-white text-[10px] rounded-full font-bold", children: activeFilterCount }) : null
|
|
76399
76704
|
]
|
|
76400
76705
|
}
|
|
76401
76706
|
)
|
|
76402
76707
|
] })
|
|
76403
76708
|
] }) }),
|
|
76404
|
-
/* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center relative min-h-[
|
|
76405
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute left-1/2 -translate-x-1/2 flex flex-col items-center
|
|
76406
|
-
/* @__PURE__ */
|
|
76407
|
-
|
|
76709
|
+
/* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center relative min-h-[64px]", children: [
|
|
76710
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute left-1/2 -translate-x-1/2 flex flex-col items-center min-w-0 max-w-[min(70vw,720px)]", children: [
|
|
76711
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 min-w-0 max-w-full", children: [
|
|
76712
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl md:text-3xl lg:text-4xl font-semibold text-gray-900 tracking-tight leading-tight text-center truncate max-w-full", children: "Operations Overview" }),
|
|
76713
|
+
isLiveScope ? /* @__PURE__ */ jsx(
|
|
76714
|
+
"div",
|
|
76715
|
+
{
|
|
76716
|
+
"data-testid": "operations-overview-live-indicator",
|
|
76717
|
+
className: "h-1.5 w-1.5 md:h-2 md:w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1 flex-shrink-0"
|
|
76718
|
+
}
|
|
76719
|
+
) : null
|
|
76720
|
+
] }),
|
|
76721
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center justify-center gap-x-3 gap-y-1 text-xs sm:text-sm font-medium text-slate-500 text-center", children: [
|
|
76722
|
+
/* @__PURE__ */ jsx("span", { children: desktopSubtitle }),
|
|
76723
|
+
isLiveScope ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
76724
|
+
/* @__PURE__ */ jsx("span", { className: "text-slate-300", children: "|" }),
|
|
76725
|
+
/* @__PURE__ */ jsx("span", { "data-testid": "operations-overview-live-meta", className: "inline-flex items-center gap-1.5 text-gray-600", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 justify-center", children: [
|
|
76726
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-75", children: liveShiftIcon }),
|
|
76727
|
+
liveShiftLabel
|
|
76728
|
+
] }) })
|
|
76729
|
+
] }) : null
|
|
76730
|
+
] })
|
|
76408
76731
|
] }),
|
|
76409
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute right-0 flex items-center gap-3", children: [
|
|
76732
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute right-0 flex items-center gap-3 shrink-0", children: [
|
|
76410
76733
|
/* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx(
|
|
76411
76734
|
MonthlyRangeFilter_default,
|
|
76412
76735
|
{
|
|
@@ -76423,12 +76746,12 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76423
76746
|
{
|
|
76424
76747
|
ref: filterButtonRef,
|
|
76425
76748
|
onClick: handleFilterToggle,
|
|
76426
|
-
className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || activeFilterCount > 0 ? "border-
|
|
76749
|
+
className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || activeFilterCount > 0 ? "border-slate-300 bg-slate-50 text-slate-700" : "border-slate-200 bg-white text-slate-600 hover:bg-slate-50 hover:text-slate-700"}`,
|
|
76427
76750
|
"aria-label": "Open filters",
|
|
76428
76751
|
children: [
|
|
76429
|
-
/* @__PURE__ */ jsx(Filter, { className: `w-[18px] h-[18px] ${activeFilterCount > 0 ? "text-
|
|
76752
|
+
/* @__PURE__ */ jsx(Filter, { className: `w-[18px] h-[18px] ${isFilterOpen || activeFilterCount > 0 ? "text-slate-500" : "text-slate-400"}` }),
|
|
76430
76753
|
"Filters",
|
|
76431
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 ml-0.5 transition-transform duration-200 ${isFilterOpen ? "rotate-180" : ""}` })
|
|
76754
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 ml-0.5 text-slate-400 transition-transform duration-200 ${isFilterOpen ? "rotate-180" : ""}` })
|
|
76432
76755
|
]
|
|
76433
76756
|
}
|
|
76434
76757
|
)
|
|
@@ -76556,11 +76879,18 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76556
76879
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
76557
76880
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
76558
76881
|
const comparisonLabel = React141__default.useMemo(() => {
|
|
76559
|
-
return formatComparisonWindow(
|
|
76560
|
-
scope.
|
|
76561
|
-
scope.
|
|
76562
|
-
|
|
76563
|
-
|
|
76882
|
+
return formatComparisonWindow({
|
|
76883
|
+
currentDayCount: scope.current_range?.day_count ?? null,
|
|
76884
|
+
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
76885
|
+
comparisonStrategy: scope.comparison_strategy,
|
|
76886
|
+
shiftMode: scope.shift_mode
|
|
76887
|
+
});
|
|
76888
|
+
}, [
|
|
76889
|
+
scope.comparison_strategy,
|
|
76890
|
+
scope.current_range?.day_count,
|
|
76891
|
+
scope.previous_range?.day_count,
|
|
76892
|
+
scope.shift_mode
|
|
76893
|
+
]);
|
|
76564
76894
|
const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React141__default.useState(false);
|
|
76565
76895
|
const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React141__default.useState(false);
|
|
76566
76896
|
const idleContributorsRef = React141__default.useRef(null);
|
|
@@ -76650,10 +76980,17 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76650
76980
|
roundOne(snapshot.data.summary.plant_efficiency.current),
|
|
76651
76981
|
"%"
|
|
76652
76982
|
] }),
|
|
76653
|
-
/* @__PURE__ */ jsxs(
|
|
76654
|
-
|
|
76655
|
-
|
|
76656
|
-
|
|
76983
|
+
/* @__PURE__ */ jsxs(
|
|
76984
|
+
"div",
|
|
76985
|
+
{
|
|
76986
|
+
"data-testid": "operations-overview-efficiency-delta",
|
|
76987
|
+
className: `flex items-center gap-1 px-2.5 py-1 rounded-full ${plantEfficiencyBadge.className}`,
|
|
76988
|
+
children: [
|
|
76989
|
+
plantEfficiencyBadge.icon === "up" ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : plantEfficiencyBadge.icon === "down" ? /* @__PURE__ */ jsx(ArrowDown, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : null,
|
|
76990
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-sm font-medium", children: plantEfficiencyBadge.text })
|
|
76991
|
+
]
|
|
76992
|
+
}
|
|
76993
|
+
)
|
|
76657
76994
|
] }) : /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-slate-400", children: "No efficiency data available" })
|
|
76658
76995
|
] }),
|
|
76659
76996
|
/* @__PURE__ */ jsxs(
|
|
@@ -76699,10 +77036,17 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76699
77036
|
/* @__PURE__ */ jsx("div", { className: "mb-1", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-700", children: "Idle Time per Workstation" }) }),
|
|
76700
77037
|
showSnapshotSkeleton ? /* @__PURE__ */ jsx(OverviewMetricCardSkeleton, {}) : snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:gap-3 mt-1", children: [
|
|
76701
77038
|
/* @__PURE__ */ jsx("span", { className: "text-2xl sm:text-3xl font-bold text-slate-800 tracking-tight", children: formatIdleDuration(snapshot.data.summary.avg_idle_per_workstation.current_seconds) }),
|
|
76702
|
-
/* @__PURE__ */ jsxs(
|
|
76703
|
-
|
|
76704
|
-
|
|
76705
|
-
|
|
77039
|
+
/* @__PURE__ */ jsxs(
|
|
77040
|
+
"div",
|
|
77041
|
+
{
|
|
77042
|
+
"data-testid": "operations-overview-idle-delta",
|
|
77043
|
+
className: `flex items-center gap-1 px-2.5 py-1 rounded-full ${idleBadge.className}`,
|
|
77044
|
+
children: [
|
|
77045
|
+
idleBadge.icon === "up" ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : idleBadge.icon === "down" ? /* @__PURE__ */ jsx(ArrowDown, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : null,
|
|
77046
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-sm font-medium", children: idleBadge.text })
|
|
77047
|
+
]
|
|
77048
|
+
}
|
|
77049
|
+
)
|
|
76706
77050
|
] }) : /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-slate-400", children: "No idle time data available" })
|
|
76707
77051
|
]
|
|
76708
77052
|
}
|
|
@@ -76765,11 +77109,18 @@ var PoorestPerformersCard = React141__default.memo(({
|
|
|
76765
77109
|
}
|
|
76766
77110
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
76767
77111
|
const comparisonLabel = React141__default.useMemo(() => {
|
|
76768
|
-
return formatComparisonWindow(
|
|
76769
|
-
scope.
|
|
76770
|
-
scope.
|
|
76771
|
-
|
|
76772
|
-
|
|
77112
|
+
return formatComparisonWindow({
|
|
77113
|
+
currentDayCount: scope.current_range?.day_count ?? null,
|
|
77114
|
+
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
77115
|
+
comparisonStrategy: scope.comparison_strategy,
|
|
77116
|
+
shiftMode: scope.shift_mode
|
|
77117
|
+
});
|
|
77118
|
+
}, [
|
|
77119
|
+
scope.comparison_strategy,
|
|
77120
|
+
scope.current_range?.day_count,
|
|
77121
|
+
scope.previous_range?.day_count,
|
|
77122
|
+
scope.shift_mode
|
|
77123
|
+
]);
|
|
76773
77124
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
76774
77125
|
const mergedPoorestLines = React141__default.useMemo(() => {
|
|
76775
77126
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
@@ -76926,7 +77277,8 @@ IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
|
76926
77277
|
var EfficiencyTrendCard = React141__default.memo(({
|
|
76927
77278
|
store,
|
|
76928
77279
|
dateRange,
|
|
76929
|
-
appTimezone
|
|
77280
|
+
appTimezone,
|
|
77281
|
+
hourlyLabelStartTime
|
|
76930
77282
|
}) => {
|
|
76931
77283
|
bumpRenderCounter();
|
|
76932
77284
|
const trend = useOperationsOverviewTrend(store);
|
|
@@ -76936,7 +77288,41 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
76936
77288
|
);
|
|
76937
77289
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
76938
77290
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
77291
|
+
const isHourlyTrend = trend.data.granularity === "hour";
|
|
76939
77292
|
const trendData = React141__default.useMemo(() => {
|
|
77293
|
+
if (isHourlyTrend) {
|
|
77294
|
+
return (trend.data.points || []).map((point, index) => ({
|
|
77295
|
+
name: (() => {
|
|
77296
|
+
const rawLabel = point.label?.trim() || "";
|
|
77297
|
+
if (!hourlyLabelStartTime) {
|
|
77298
|
+
return rawLabel || `Hour ${index + 1}`;
|
|
77299
|
+
}
|
|
77300
|
+
if (rawLabel && !/^Hour\s+\d+$/i.test(rawLabel)) {
|
|
77301
|
+
return rawLabel;
|
|
77302
|
+
}
|
|
77303
|
+
const hourIndex = typeof point.hour_index === "number" ? point.hour_index : index;
|
|
77304
|
+
const [hoursPart, minutesPart] = hourlyLabelStartTime.split(":");
|
|
77305
|
+
const startHours = Number(hoursPart);
|
|
77306
|
+
const startMinutes = Number(minutesPart);
|
|
77307
|
+
if (!Number.isFinite(startHours) || !Number.isFinite(startMinutes)) {
|
|
77308
|
+
return rawLabel || `Hour ${index + 1}`;
|
|
77309
|
+
}
|
|
77310
|
+
const totalMinutes = startHours * 60 + startMinutes + hourIndex * 60;
|
|
77311
|
+
const hour24 = Math.floor(totalMinutes / 60) % 24;
|
|
77312
|
+
const minutes = totalMinutes % 60;
|
|
77313
|
+
const suffix = hour24 < 12 ? "AM" : "PM";
|
|
77314
|
+
const hour12 = hour24 % 12 || 12;
|
|
77315
|
+
if (minutes === 0) {
|
|
77316
|
+
return `${hour12} ${suffix}`;
|
|
77317
|
+
}
|
|
77318
|
+
return `${hour12}:${minutes.toString().padStart(2, "0")} ${suffix}`;
|
|
77319
|
+
})(),
|
|
77320
|
+
efficiency: (() => {
|
|
77321
|
+
const value = toNumber3(point.avg_efficiency);
|
|
77322
|
+
return value === null ? void 0 : value;
|
|
77323
|
+
})()
|
|
77324
|
+
}));
|
|
77325
|
+
}
|
|
76940
77326
|
const pointsByDate = new Map(
|
|
76941
77327
|
(trend.data.points || []).flatMap((point) => {
|
|
76942
77328
|
if (!point.date) return [];
|
|
@@ -76974,12 +77360,13 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
76974
77360
|
})()
|
|
76975
77361
|
};
|
|
76976
77362
|
});
|
|
76977
|
-
}, [currentWeekRange.startKey, isCurrentWeekToDateRange, trend.data.points]);
|
|
77363
|
+
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
76978
77364
|
const trendTooltipLabelFormatter = React141__default.useCallback((label, payload) => {
|
|
77365
|
+
if (isHourlyTrend) return label;
|
|
76979
77366
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
76980
77367
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
76981
77368
|
return `${label} (${dayOfWeek})`;
|
|
76982
|
-
}, []);
|
|
77369
|
+
}, [isHourlyTrend]);
|
|
76983
77370
|
return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-[0_2px_10px_-3px_rgba(6,81,237,0.1)] border border-slate-100 flex flex-col overflow-hidden text-left", children: [
|
|
76984
77371
|
/* @__PURE__ */ jsx("div", { className: "px-6 py-5 flex-none flex justify-between items-center border-b border-slate-50/50", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-700", children: "Efficiency Trend" }) }),
|
|
76985
77372
|
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-[250px] w-full p-4 pt-4 relative", children: showInitialSkeleton ? /* @__PURE__ */ jsx(OverviewChartSkeleton, {}) : /* @__PURE__ */ jsx("div", { className: "absolute inset-0 pb-2 pr-4 pl-1", children: /* @__PURE__ */ jsx(
|
|
@@ -77133,7 +77520,8 @@ var useOperationsOverviewRefresh = ({
|
|
|
77133
77520
|
endKey,
|
|
77134
77521
|
trendMode,
|
|
77135
77522
|
comparisonStrategy,
|
|
77136
|
-
isLiveScope
|
|
77523
|
+
isLiveScope,
|
|
77524
|
+
enabled = true
|
|
77137
77525
|
}) => {
|
|
77138
77526
|
const lineIdsKey = React141__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
77139
77527
|
const scopeSignature = React141__default.useMemo(
|
|
@@ -77179,7 +77567,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77179
77567
|
}, []);
|
|
77180
77568
|
const runRefresh = React141__default.useCallback(
|
|
77181
77569
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
77182
|
-
if (!supabase || !companyId || lineIds.length === 0) return;
|
|
77570
|
+
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
77183
77571
|
const requestId = requestIdsRef.current[section] + 1;
|
|
77184
77572
|
requestIdsRef.current[section] = requestId;
|
|
77185
77573
|
controllersRef.current[section]?.abort();
|
|
@@ -77199,7 +77587,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77199
77587
|
onError(error instanceof Error ? error.message : `Failed to refresh ${section}`);
|
|
77200
77588
|
}
|
|
77201
77589
|
},
|
|
77202
|
-
[companyId, lineIds.length, supabase]
|
|
77590
|
+
[companyId, enabled, lineIds.length, supabase]
|
|
77203
77591
|
);
|
|
77204
77592
|
const refreshSnapshot = React141__default.useCallback(
|
|
77205
77593
|
async (reason) => {
|
|
@@ -77369,6 +77757,12 @@ var useOperationsOverviewRefresh = ({
|
|
|
77369
77757
|
});
|
|
77370
77758
|
}, [refreshAll, startPolling, stopPolling]);
|
|
77371
77759
|
React141__default.useEffect(() => {
|
|
77760
|
+
if (!enabled) {
|
|
77761
|
+
stopPolling("disabled");
|
|
77762
|
+
abortAll();
|
|
77763
|
+
store.reset();
|
|
77764
|
+
return;
|
|
77765
|
+
}
|
|
77372
77766
|
if (!supabase || !companyId || lineIds.length === 0) {
|
|
77373
77767
|
stopPolling("scope_invalid");
|
|
77374
77768
|
abortAll();
|
|
@@ -77376,9 +77770,9 @@ var useOperationsOverviewRefresh = ({
|
|
|
77376
77770
|
return;
|
|
77377
77771
|
}
|
|
77378
77772
|
void refreshAll("scope_change");
|
|
77379
|
-
}, [abortAll, companyId, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
77773
|
+
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
77380
77774
|
React141__default.useEffect(() => {
|
|
77381
|
-
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
77775
|
+
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
77382
77776
|
isPageActiveRef.current = false;
|
|
77383
77777
|
stopPolling("live_scope_disabled");
|
|
77384
77778
|
return;
|
|
@@ -77434,11 +77828,63 @@ var useOperationsOverviewRefresh = ({
|
|
|
77434
77828
|
window.removeEventListener("pageshow", handlePageShow);
|
|
77435
77829
|
window.removeEventListener("pagehide", handlePageHide);
|
|
77436
77830
|
};
|
|
77437
|
-
}, [companyId, getIsPageActive, isLiveScope, lineIds.length, refreshFromResume, startPolling, stopPolling, supabase]);
|
|
77831
|
+
}, [companyId, enabled, getIsPageActive, isLiveScope, lineIds.length, refreshFromResume, startPolling, stopPolling, supabase]);
|
|
77832
|
+
};
|
|
77833
|
+
var parseTimeToMinutes3 = (value) => {
|
|
77834
|
+
if (!value) return null;
|
|
77835
|
+
const parts = value.split(":");
|
|
77836
|
+
if (parts.length < 2) return null;
|
|
77837
|
+
const hours = Number(parts[0]);
|
|
77838
|
+
const minutes = Number(parts[1]);
|
|
77839
|
+
if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return null;
|
|
77840
|
+
if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null;
|
|
77841
|
+
return hours * 60 + minutes;
|
|
77842
|
+
};
|
|
77843
|
+
var normalizeShiftId = (value) => {
|
|
77844
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
77845
|
+
return value;
|
|
77846
|
+
}
|
|
77847
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
77848
|
+
const parsed = Number(value);
|
|
77849
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
77850
|
+
}
|
|
77851
|
+
return null;
|
|
77852
|
+
};
|
|
77853
|
+
var classifyShiftBucket = ({
|
|
77854
|
+
shiftName,
|
|
77855
|
+
shiftId,
|
|
77856
|
+
startTime,
|
|
77857
|
+
endTime
|
|
77858
|
+
}) => {
|
|
77859
|
+
const normalizedName = (shiftName || "").trim().toLowerCase();
|
|
77860
|
+
if (normalizedName) {
|
|
77861
|
+
if (["night", "graveyard", "evening"].some((keyword) => normalizedName.includes(keyword))) {
|
|
77862
|
+
return "night";
|
|
77863
|
+
}
|
|
77864
|
+
if (["day", "morning"].some((keyword) => normalizedName.includes(keyword))) {
|
|
77865
|
+
return "day";
|
|
77866
|
+
}
|
|
77867
|
+
}
|
|
77868
|
+
const startMinutes = parseTimeToMinutes3(startTime);
|
|
77869
|
+
const endMinutes = parseTimeToMinutes3(endTime);
|
|
77870
|
+
if (startMinutes !== null) {
|
|
77871
|
+
if (startMinutes >= 4 * 60 && startMinutes < 18 * 60) return "day";
|
|
77872
|
+
return "night";
|
|
77873
|
+
}
|
|
77874
|
+
if (endMinutes !== null) {
|
|
77875
|
+
if (endMinutes >= 6 * 60 && endMinutes <= 21 * 60) return "day";
|
|
77876
|
+
return "night";
|
|
77877
|
+
}
|
|
77878
|
+
const normalizedShiftId = normalizeShiftId(shiftId);
|
|
77879
|
+
if (normalizedShiftId === 0) return "day";
|
|
77880
|
+
if (normalizedShiftId === 1) return "night";
|
|
77881
|
+
return null;
|
|
77438
77882
|
};
|
|
77439
77883
|
var PlantHeadView = () => {
|
|
77440
77884
|
const supabase = useSupabase();
|
|
77441
77885
|
const entityConfig = useEntityConfig();
|
|
77886
|
+
const factoryViewId = entityConfig.factoryViewId || "factory";
|
|
77887
|
+
const staticShiftConfig = useShiftConfig();
|
|
77442
77888
|
const appTimezone = useAppTimezone() || "UTC";
|
|
77443
77889
|
const { navigate } = useNavigation();
|
|
77444
77890
|
const { accessibleLineIds } = useUserLineAccess();
|
|
@@ -77446,11 +77892,21 @@ var PlantHeadView = () => {
|
|
|
77446
77892
|
useHideMobileHeader(!!mobileMenuContext);
|
|
77447
77893
|
const storeRef = React141__default.useRef(createOperationsOverviewStore());
|
|
77448
77894
|
const store = storeRef.current;
|
|
77449
|
-
const
|
|
77450
|
-
|
|
77895
|
+
const fallbackOperationalDate = React141__default.useMemo(
|
|
77896
|
+
() => getOperationalDate(appTimezone),
|
|
77897
|
+
[appTimezone]
|
|
77898
|
+
);
|
|
77899
|
+
const [dateRange, setDateRange] = React141__default.useState(() => ({
|
|
77900
|
+
startKey: fallbackOperationalDate,
|
|
77901
|
+
endKey: fallbackOperationalDate
|
|
77902
|
+
}));
|
|
77903
|
+
const [usesThisWeekComparison, setUsesThisWeekComparison] = React141__default.useState(false);
|
|
77451
77904
|
const [trendMode, setTrendMode] = React141__default.useState("all");
|
|
77452
77905
|
const [selectedSupervisorId, setSelectedSupervisorId] = React141__default.useState("all");
|
|
77453
77906
|
const [selectedLineIds, setSelectedLineIds] = React141__default.useState([]);
|
|
77907
|
+
const [isInitialScopeReady, setIsInitialScopeReady] = React141__default.useState(false);
|
|
77908
|
+
const hasAutoInitializedScopeRef = React141__default.useRef(false);
|
|
77909
|
+
const hasUserAdjustedScopeRef = React141__default.useRef(false);
|
|
77454
77910
|
React141__default.useEffect(() => {
|
|
77455
77911
|
trackCorePageView("Operations Overview", {
|
|
77456
77912
|
dashboard_surface: "operations_overview"
|
|
@@ -77472,8 +77928,10 @@ var PlantHeadView = () => {
|
|
|
77472
77928
|
return dateRange;
|
|
77473
77929
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
77474
77930
|
const normalizedLineIds = React141__default.useMemo(
|
|
77475
|
-
() => Array.from(new Set(
|
|
77476
|
-
|
|
77931
|
+
() => Array.from(new Set(
|
|
77932
|
+
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
77933
|
+
)).sort(),
|
|
77934
|
+
[accessibleLineIds, factoryViewId]
|
|
77477
77935
|
);
|
|
77478
77936
|
const lineIdsKey = React141__default.useMemo(
|
|
77479
77937
|
() => normalizedLineIds.join(","),
|
|
@@ -77547,14 +78005,81 @@ var PlantHeadView = () => {
|
|
|
77547
78005
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
77548
78006
|
[normalizedLineIds, selectedLineIds]
|
|
77549
78007
|
);
|
|
78008
|
+
const {
|
|
78009
|
+
shiftConfigMap,
|
|
78010
|
+
isLoading: isShiftConfigLoading
|
|
78011
|
+
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
78012
|
+
const { shiftGroups, hasComputed: hasComputedShiftGroups } = useShiftGroups({
|
|
78013
|
+
enabled: scopedLineIds.length > 0 && !isShiftConfigLoading,
|
|
78014
|
+
shiftConfigMap,
|
|
78015
|
+
timezone: appTimezone
|
|
78016
|
+
});
|
|
78017
|
+
const currentShiftScope = React141__default.useMemo(() => {
|
|
78018
|
+
if (shiftGroups.length !== 1) return null;
|
|
78019
|
+
const group = shiftGroups[0];
|
|
78020
|
+
const referenceLineId = group.lineIds[0];
|
|
78021
|
+
const referenceShiftConfig = referenceLineId ? shiftConfigMap.get(referenceLineId) : null;
|
|
78022
|
+
const normalizedGroupShiftId = normalizeShiftId(group.shiftId);
|
|
78023
|
+
const shiftDefinition = referenceShiftConfig?.shifts?.find((shift) => normalizeShiftId(shift.shiftId) === normalizedGroupShiftId);
|
|
78024
|
+
const resolvedMode = classifyShiftBucket({
|
|
78025
|
+
shiftName: group.shiftName,
|
|
78026
|
+
shiftId: normalizedGroupShiftId,
|
|
78027
|
+
startTime: shiftDefinition?.startTime,
|
|
78028
|
+
endTime: shiftDefinition?.endTime
|
|
78029
|
+
});
|
|
78030
|
+
if (!resolvedMode || resolvedMode === "all") return null;
|
|
78031
|
+
return {
|
|
78032
|
+
date: group.date,
|
|
78033
|
+
trendMode: resolvedMode,
|
|
78034
|
+
shiftName: shiftDefinition?.shiftName || group.shiftName || null
|
|
78035
|
+
};
|
|
78036
|
+
}, [shiftConfigMap, shiftGroups]);
|
|
78037
|
+
const isShiftScopeResolved = React141__default.useMemo(
|
|
78038
|
+
() => !isShiftConfigLoading && hasComputedShiftGroups,
|
|
78039
|
+
[hasComputedShiftGroups, isShiftConfigLoading]
|
|
78040
|
+
);
|
|
77550
78041
|
const initializedTimezoneRef = React141__default.useRef(appTimezone);
|
|
77551
78042
|
React141__default.useEffect(() => {
|
|
77552
78043
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
77553
|
-
|
|
77554
|
-
|
|
78044
|
+
hasAutoInitializedScopeRef.current = false;
|
|
78045
|
+
hasUserAdjustedScopeRef.current = false;
|
|
78046
|
+
setDateRange({
|
|
78047
|
+
startKey: fallbackOperationalDate,
|
|
78048
|
+
endKey: fallbackOperationalDate
|
|
78049
|
+
});
|
|
78050
|
+
setTrendMode("all");
|
|
78051
|
+
setUsesThisWeekComparison(false);
|
|
78052
|
+
setIsInitialScopeReady(false);
|
|
77555
78053
|
initializedTimezoneRef.current = appTimezone;
|
|
77556
|
-
}, [appTimezone]);
|
|
78054
|
+
}, [appTimezone, fallbackOperationalDate]);
|
|
78055
|
+
React141__default.useEffect(() => {
|
|
78056
|
+
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
78057
|
+
return;
|
|
78058
|
+
}
|
|
78059
|
+
if (scopedLineIds.length === 0) {
|
|
78060
|
+
return;
|
|
78061
|
+
}
|
|
78062
|
+
if (!isShiftScopeResolved) {
|
|
78063
|
+
return;
|
|
78064
|
+
}
|
|
78065
|
+
setDateRange((previous) => {
|
|
78066
|
+
const nextStartKey = currentShiftScope?.date || fallbackOperationalDate;
|
|
78067
|
+
if (previous.startKey === nextStartKey && previous.endKey === nextStartKey) {
|
|
78068
|
+
return previous;
|
|
78069
|
+
}
|
|
78070
|
+
return {
|
|
78071
|
+
startKey: nextStartKey,
|
|
78072
|
+
endKey: nextStartKey
|
|
78073
|
+
};
|
|
78074
|
+
});
|
|
78075
|
+
setTrendMode(currentShiftScope?.trendMode || "all");
|
|
78076
|
+
setUsesThisWeekComparison(false);
|
|
78077
|
+
hasAutoInitializedScopeRef.current = true;
|
|
78078
|
+
setIsInitialScopeReady(true);
|
|
78079
|
+
}, [currentShiftScope, fallbackOperationalDate, isShiftScopeResolved, scopedLineIds.length]);
|
|
77557
78080
|
const handleDateRangeChange = React141__default.useCallback((range, meta) => {
|
|
78081
|
+
hasUserAdjustedScopeRef.current = true;
|
|
78082
|
+
setIsInitialScopeReady(true);
|
|
77558
78083
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
77559
78084
|
start_date: range.startKey,
|
|
77560
78085
|
end_date: range.endKey
|
|
@@ -77571,6 +78096,8 @@ var PlantHeadView = () => {
|
|
|
77571
78096
|
});
|
|
77572
78097
|
}, []);
|
|
77573
78098
|
const handleTrendModeChange = React141__default.useCallback((mode) => {
|
|
78099
|
+
hasUserAdjustedScopeRef.current = true;
|
|
78100
|
+
setIsInitialScopeReady(true);
|
|
77574
78101
|
setTrendMode(mode);
|
|
77575
78102
|
}, []);
|
|
77576
78103
|
const handleSelectedLineIdsChange = React141__default.useCallback((lineIds) => {
|
|
@@ -77597,15 +78124,6 @@ var PlantHeadView = () => {
|
|
|
77597
78124
|
params.set("rangeEnd", dateRange.endKey);
|
|
77598
78125
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
77599
78126
|
}, [dateRange.endKey, dateRange.startKey]);
|
|
77600
|
-
const handleOpenLineMonthlyHistory = React141__default.useCallback((lineId, lineName) => {
|
|
77601
|
-
trackCoreEvent("Operations Overview Line Clicked", {
|
|
77602
|
-
line_id: lineId,
|
|
77603
|
-
line_name: lineName,
|
|
77604
|
-
range_start: dateRange.startKey,
|
|
77605
|
-
range_end: dateRange.endKey
|
|
77606
|
-
});
|
|
77607
|
-
navigate(buildLineMonthlyHistoryUrl(lineId));
|
|
77608
|
-
}, [buildLineMonthlyHistoryUrl, dateRange.endKey, dateRange.startKey, navigate]);
|
|
77609
78127
|
const handleViewAllPoorestPerformers = React141__default.useCallback(() => {
|
|
77610
78128
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
77611
78129
|
navigate("/kpis?tab=leaderboard");
|
|
@@ -77631,16 +78149,74 @@ var PlantHeadView = () => {
|
|
|
77631
78149
|
}
|
|
77632
78150
|
return void 0;
|
|
77633
78151
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
78152
|
+
const effectiveDateRange = React141__default.useMemo(() => {
|
|
78153
|
+
if (isInitialScopeReady) {
|
|
78154
|
+
return dateRange;
|
|
78155
|
+
}
|
|
78156
|
+
const nextStartKey = currentShiftScope?.date || fallbackOperationalDate;
|
|
78157
|
+
return {
|
|
78158
|
+
startKey: nextStartKey,
|
|
78159
|
+
endKey: nextStartKey
|
|
78160
|
+
};
|
|
78161
|
+
}, [currentShiftScope, dateRange, fallbackOperationalDate, isInitialScopeReady]);
|
|
78162
|
+
const effectiveTrendMode = React141__default.useMemo(
|
|
78163
|
+
() => isInitialScopeReady ? trendMode : currentShiftScope?.trendMode || "all",
|
|
78164
|
+
[currentShiftScope, isInitialScopeReady, trendMode]
|
|
78165
|
+
);
|
|
78166
|
+
const hourlyLabelStartTime = React141__default.useMemo(() => {
|
|
78167
|
+
if (effectiveTrendMode === "all" || scopedLineIds.length === 0) {
|
|
78168
|
+
return null;
|
|
78169
|
+
}
|
|
78170
|
+
const shiftStartTimes = /* @__PURE__ */ new Set();
|
|
78171
|
+
scopedLineIds.forEach((lineId) => {
|
|
78172
|
+
const shiftConfig = shiftConfigMap.get(lineId);
|
|
78173
|
+
const matchingShift = shiftConfig?.shifts?.find((shift) => classifyShiftBucket({
|
|
78174
|
+
shiftName: shift.shiftName,
|
|
78175
|
+
shiftId: shift.shiftId,
|
|
78176
|
+
startTime: shift.startTime,
|
|
78177
|
+
endTime: shift.endTime
|
|
78178
|
+
}) === effectiveTrendMode);
|
|
78179
|
+
if (matchingShift?.startTime) {
|
|
78180
|
+
shiftStartTimes.add(matchingShift.startTime);
|
|
78181
|
+
}
|
|
78182
|
+
});
|
|
78183
|
+
if (shiftStartTimes.size !== 1) {
|
|
78184
|
+
return null;
|
|
78185
|
+
}
|
|
78186
|
+
return Array.from(shiftStartTimes)[0] || null;
|
|
78187
|
+
}, [effectiveTrendMode, scopedLineIds, shiftConfigMap]);
|
|
78188
|
+
const isSingleDayShiftScope = React141__default.useMemo(
|
|
78189
|
+
() => effectiveDateRange.startKey === effectiveDateRange.endKey && effectiveTrendMode !== "all",
|
|
78190
|
+
[effectiveDateRange.endKey, effectiveDateRange.startKey, effectiveTrendMode]
|
|
78191
|
+
);
|
|
78192
|
+
const isLiveScope = React141__default.useMemo(
|
|
78193
|
+
() => isSingleDayShiftScope && currentShiftScope !== null && effectiveDateRange.startKey === currentShiftScope.date && effectiveTrendMode === currentShiftScope.trendMode,
|
|
78194
|
+
[currentShiftScope, effectiveDateRange.startKey, effectiveTrendMode, isSingleDayShiftScope]
|
|
78195
|
+
);
|
|
78196
|
+
const handleOpenLineDetails = React141__default.useCallback((lineId, lineName) => {
|
|
78197
|
+
trackCoreEvent("Operations Overview Line Clicked", {
|
|
78198
|
+
line_id: lineId,
|
|
78199
|
+
line_name: lineName,
|
|
78200
|
+
range_start: dateRange.startKey,
|
|
78201
|
+
range_end: dateRange.endKey
|
|
78202
|
+
});
|
|
78203
|
+
if (isLiveScope) {
|
|
78204
|
+
navigate(`/kpis/${lineId}?returnTo=${encodeURIComponent("/")}`);
|
|
78205
|
+
return;
|
|
78206
|
+
}
|
|
78207
|
+
navigate(buildLineMonthlyHistoryUrl(lineId));
|
|
78208
|
+
}, [buildLineMonthlyHistoryUrl, dateRange.endKey, dateRange.startKey, isLiveScope, navigate]);
|
|
77634
78209
|
useOperationsOverviewRefresh({
|
|
77635
78210
|
store,
|
|
77636
78211
|
supabase,
|
|
77637
78212
|
companyId: entityConfig.companyId,
|
|
77638
78213
|
lineIds: scopedLineIds,
|
|
77639
|
-
startKey:
|
|
77640
|
-
endKey:
|
|
77641
|
-
trendMode,
|
|
78214
|
+
startKey: effectiveDateRange.startKey,
|
|
78215
|
+
endKey: effectiveDateRange.endKey,
|
|
78216
|
+
trendMode: effectiveTrendMode,
|
|
77642
78217
|
comparisonStrategy,
|
|
77643
|
-
isLiveScope
|
|
78218
|
+
isLiveScope,
|
|
78219
|
+
enabled: scopedLineIds.length > 0 && isShiftScopeResolved
|
|
77644
78220
|
});
|
|
77645
78221
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-h-screen bg-slate-50 w-full font-sans", children: [
|
|
77646
78222
|
/* @__PURE__ */ jsx(
|
|
@@ -77649,6 +78225,8 @@ var PlantHeadView = () => {
|
|
|
77649
78225
|
dateRange,
|
|
77650
78226
|
displayDateRange: headerDateRange,
|
|
77651
78227
|
trendMode,
|
|
78228
|
+
isLiveScope,
|
|
78229
|
+
liveShiftName: currentShiftScope?.shiftName || null,
|
|
77652
78230
|
lineOptions,
|
|
77653
78231
|
supervisorOptions,
|
|
77654
78232
|
selectedSupervisorId,
|
|
@@ -77671,7 +78249,7 @@ var PlantHeadView = () => {
|
|
|
77671
78249
|
store,
|
|
77672
78250
|
supervisorsByLineId,
|
|
77673
78251
|
onViewAll: handleViewAllPoorestPerformers,
|
|
77674
|
-
onLineClick:
|
|
78252
|
+
onLineClick: handleOpenLineDetails
|
|
77675
78253
|
}
|
|
77676
78254
|
),
|
|
77677
78255
|
/* @__PURE__ */ jsx(
|
|
@@ -77688,7 +78266,8 @@ var PlantHeadView = () => {
|
|
|
77688
78266
|
{
|
|
77689
78267
|
store,
|
|
77690
78268
|
dateRange,
|
|
77691
|
-
appTimezone
|
|
78269
|
+
appTimezone,
|
|
78270
|
+
hourlyLabelStartTime
|
|
77692
78271
|
}
|
|
77693
78272
|
),
|
|
77694
78273
|
/* @__PURE__ */ jsx(
|
|
@@ -78182,4 +78761,4 @@ var streamProxyConfig = {
|
|
|
78182
78761
|
}
|
|
78183
78762
|
};
|
|
78184
78763
|
|
|
78185
|
-
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|
|
78764
|
+
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|