@optifye/dashboard-core 6.11.15 → 6.11.17
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 +35 -2
- package/dist/index.d.ts +35 -2
- package/dist/index.js +1338 -558
- package/dist/index.mjs +1337 -560
- 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';
|
|
@@ -3266,11 +3266,9 @@ var normalizeShiftDefinitions = (timezone, shiftConfig) => {
|
|
|
3266
3266
|
}
|
|
3267
3267
|
return { shifts: legacyShifts, timezone: fallbackTimezone };
|
|
3268
3268
|
};
|
|
3269
|
-
var
|
|
3269
|
+
var determineActiveShiftFromDefinitions = (timezone, shifts, now4 = /* @__PURE__ */ new Date()) => {
|
|
3270
3270
|
const zonedNow = toZonedTime(now4, timezone);
|
|
3271
3271
|
const currentMinutes = zonedNow.getHours() * 60 + zonedNow.getMinutes();
|
|
3272
|
-
let chosen;
|
|
3273
|
-
let operationalDate = getOperationalDate(timezone, now4, shifts[0].startTime);
|
|
3274
3272
|
for (const shift of shifts) {
|
|
3275
3273
|
const start = parseTimeToMinutes(shift.startTime);
|
|
3276
3274
|
const endRaw = parseTimeToMinutes(shift.endTime);
|
|
@@ -3278,32 +3276,47 @@ var determineShiftFromDefinitions = (timezone, shifts, now4 = /* @__PURE__ */ ne
|
|
|
3278
3276
|
const wraps = end <= start;
|
|
3279
3277
|
if (wraps) end += 1440;
|
|
3280
3278
|
if (start <= currentMinutes && currentMinutes < end) {
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3279
|
+
return {
|
|
3280
|
+
shiftId: shift.shiftId,
|
|
3281
|
+
shiftName: shift.shiftName,
|
|
3282
|
+
startTime: shift.startTime,
|
|
3283
|
+
endTime: shift.endTime,
|
|
3284
|
+
timezone,
|
|
3285
|
+
date: getOperationalDate(timezone, now4, shift.startTime)
|
|
3286
|
+
};
|
|
3284
3287
|
}
|
|
3285
3288
|
if (start <= currentMinutes + 1440 && currentMinutes + 1440 < end) {
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
+
return {
|
|
3290
|
+
shiftId: shift.shiftId,
|
|
3291
|
+
shiftName: shift.shiftName,
|
|
3292
|
+
startTime: shift.startTime,
|
|
3293
|
+
endTime: shift.endTime,
|
|
3294
|
+
timezone,
|
|
3295
|
+
date: getOperationalDate(timezone, now4, shift.startTime)
|
|
3296
|
+
};
|
|
3289
3297
|
}
|
|
3290
3298
|
}
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3299
|
+
return null;
|
|
3300
|
+
};
|
|
3301
|
+
var getCurrentShift = (timezone, shiftConfig, now4 = /* @__PURE__ */ new Date()) => {
|
|
3302
|
+
const { shifts, timezone: effectiveTz } = normalizeShiftDefinitions(timezone, shiftConfig);
|
|
3303
|
+
const activeShift = determineActiveShiftFromDefinitions(effectiveTz, shifts, now4);
|
|
3304
|
+
if (activeShift) {
|
|
3305
|
+
return activeShift;
|
|
3294
3306
|
}
|
|
3307
|
+
const fallbackShift = shifts[0];
|
|
3295
3308
|
return {
|
|
3296
|
-
shiftId:
|
|
3297
|
-
shiftName:
|
|
3298
|
-
startTime:
|
|
3299
|
-
endTime:
|
|
3300
|
-
timezone,
|
|
3301
|
-
date:
|
|
3309
|
+
shiftId: fallbackShift.shiftId,
|
|
3310
|
+
shiftName: fallbackShift.shiftName,
|
|
3311
|
+
startTime: fallbackShift.startTime,
|
|
3312
|
+
endTime: fallbackShift.endTime,
|
|
3313
|
+
timezone: effectiveTz,
|
|
3314
|
+
date: getOperationalDate(effectiveTz, now4, fallbackShift.startTime)
|
|
3302
3315
|
};
|
|
3303
3316
|
};
|
|
3304
|
-
var
|
|
3317
|
+
var getActiveShift = (timezone, shiftConfig, now4 = /* @__PURE__ */ new Date()) => {
|
|
3305
3318
|
const { shifts, timezone: effectiveTz } = normalizeShiftDefinitions(timezone, shiftConfig);
|
|
3306
|
-
return
|
|
3319
|
+
return determineActiveShiftFromDefinitions(effectiveTz, shifts, now4);
|
|
3307
3320
|
};
|
|
3308
3321
|
var isTransitionPeriod = (timezone, shiftConfig, now4 = /* @__PURE__ */ new Date()) => {
|
|
3309
3322
|
const transitionMinutes = shiftConfig?.transitionPeriodMinutes ?? DEFAULT_TRANSITION_MINUTES;
|
|
@@ -12835,6 +12848,7 @@ var useShiftGroups = ({
|
|
|
12835
12848
|
}) => {
|
|
12836
12849
|
const [shiftGroups, setShiftGroups] = useState([]);
|
|
12837
12850
|
const [shiftGroupsKey, setShiftGroupsKey] = useState("");
|
|
12851
|
+
const [hasComputed, setHasComputed] = useState(false);
|
|
12838
12852
|
const lastKeyRef = useRef("");
|
|
12839
12853
|
const mapRef = useRef(shiftConfigMap);
|
|
12840
12854
|
useEffect(() => {
|
|
@@ -12845,6 +12859,7 @@ var useShiftGroups = ({
|
|
|
12845
12859
|
lastKeyRef.current = "";
|
|
12846
12860
|
setShiftGroups([]);
|
|
12847
12861
|
setShiftGroupsKey("");
|
|
12862
|
+
setHasComputed(false);
|
|
12848
12863
|
return;
|
|
12849
12864
|
}
|
|
12850
12865
|
let isMounted = true;
|
|
@@ -12857,6 +12872,7 @@ var useShiftGroups = ({
|
|
|
12857
12872
|
setShiftGroups(groups);
|
|
12858
12873
|
setShiftGroupsKey(key);
|
|
12859
12874
|
}
|
|
12875
|
+
setHasComputed(true);
|
|
12860
12876
|
};
|
|
12861
12877
|
compute();
|
|
12862
12878
|
const intervalId = setInterval(compute, pollIntervalMs);
|
|
@@ -12865,7 +12881,7 @@ var useShiftGroups = ({
|
|
|
12865
12881
|
clearInterval(intervalId);
|
|
12866
12882
|
};
|
|
12867
12883
|
}, [enabled, shiftConfigMap.size, timezone, pollIntervalMs]);
|
|
12868
|
-
return { shiftGroups, shiftGroupsKey };
|
|
12884
|
+
return { shiftGroups, shiftGroupsKey, hasComputed };
|
|
12869
12885
|
};
|
|
12870
12886
|
|
|
12871
12887
|
// src/lib/types/efficiencyLegend.ts
|
|
@@ -12927,52 +12943,6 @@ function getEfficiencyTextColorClasses(efficiency, legend = DEFAULT_EFFICIENCY_L
|
|
|
12927
12943
|
}
|
|
12928
12944
|
}
|
|
12929
12945
|
|
|
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
12946
|
// src/lib/hooks/useDashboardMetrics.ts
|
|
12977
12947
|
var DEBUG_DASHBOARD_LOGS = process.env.NEXT_PUBLIC_DEBUG_DASHBOARD === "true";
|
|
12978
12948
|
var logDebug = (...args) => {
|
|
@@ -13061,7 +13031,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13061
13031
|
const abortControllerRef = useRef(null);
|
|
13062
13032
|
const lastFetchKeyRef = useRef(null);
|
|
13063
13033
|
const inFlightFetchKeyRef = useRef(null);
|
|
13064
|
-
const recentFlowCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
13065
13034
|
const updateQueueRef = useRef(false);
|
|
13066
13035
|
const onLineMetricsUpdateRef = useRef(onLineMetricsUpdate);
|
|
13067
13036
|
const shiftGroupsRef = useRef(shiftGroups);
|
|
@@ -13095,7 +13064,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13095
13064
|
setError(null);
|
|
13096
13065
|
lastFetchKeyRef.current = null;
|
|
13097
13066
|
inFlightFetchKeyRef.current = null;
|
|
13098
|
-
recentFlowCacheRef.current = /* @__PURE__ */ new Map();
|
|
13099
13067
|
}, [lineId]);
|
|
13100
13068
|
const fetchAllMetrics = useCallback(async (options = {}) => {
|
|
13101
13069
|
const { force = false } = options;
|
|
@@ -13370,12 +13338,9 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13370
13338
|
actionType: item.action_type,
|
|
13371
13339
|
actionName: item.action_name
|
|
13372
13340
|
}),
|
|
13373
|
-
recent_flow_mode: item.recent_flow_mode ?? void 0,
|
|
13374
13341
|
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
13342
|
recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
|
|
13343
|
+
recent_flow_computed_at: item.recent_flow_computed_at ?? null,
|
|
13379
13344
|
incoming_wip_current: item.incoming_wip_current ?? null,
|
|
13380
13345
|
incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
|
|
13381
13346
|
incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null
|
|
@@ -13386,16 +13351,11 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13386
13351
|
const wsNumB = parseInt(b.workspace_name?.replace(/[^0-9]/g, "") || "0");
|
|
13387
13352
|
return wsNumA - wsNumB;
|
|
13388
13353
|
});
|
|
13389
|
-
|
|
13390
|
-
workspaces: mergedWorkspaceData,
|
|
13391
|
-
cache: nextRecentFlowCache
|
|
13392
|
-
} = mergeWorkspaceRecentFlowMetrics(transformedWorkspaceData, recentFlowCacheRef.current);
|
|
13393
|
-
recentFlowCacheRef.current = nextRecentFlowCache;
|
|
13394
|
-
mergedWorkspaceData.forEach((metric) => {
|
|
13354
|
+
transformedWorkspaceData.forEach((metric) => {
|
|
13395
13355
|
workspaceMetricsStore.setOverview(metric);
|
|
13396
13356
|
});
|
|
13397
13357
|
const newMetricsState = {
|
|
13398
|
-
workspaceMetrics:
|
|
13358
|
+
workspaceMetrics: transformedWorkspaceData,
|
|
13399
13359
|
lineMetrics: allLineMetrics || [],
|
|
13400
13360
|
metadata: { hasFlowBuffers, idleTimeVlmByLine },
|
|
13401
13361
|
efficiencyLegend: efficiencyLegend ?? DEFAULT_EFFICIENCY_LEGEND
|
|
@@ -16820,7 +16780,7 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16820
16780
|
const [isLoading, setIsLoading] = useState(true);
|
|
16821
16781
|
const [error, setError] = useState(null);
|
|
16822
16782
|
const supabase = useSupabase();
|
|
16823
|
-
const
|
|
16783
|
+
const parseTimeToMinutes4 = (timeStr) => {
|
|
16824
16784
|
const [hours, minutes] = timeStr.split(":").map(Number);
|
|
16825
16785
|
return hours * 60 + minutes;
|
|
16826
16786
|
};
|
|
@@ -16829,8 +16789,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16829
16789
|
return now4.getHours() * 60 + now4.getMinutes();
|
|
16830
16790
|
};
|
|
16831
16791
|
const isTimeInBreak = (breakStart, breakEnd, currentMinutes) => {
|
|
16832
|
-
const startMinutes =
|
|
16833
|
-
const endMinutes =
|
|
16792
|
+
const startMinutes = parseTimeToMinutes4(breakStart);
|
|
16793
|
+
const endMinutes = parseTimeToMinutes4(breakEnd);
|
|
16834
16794
|
if (endMinutes < startMinutes) {
|
|
16835
16795
|
return currentMinutes >= startMinutes || currentMinutes < endMinutes;
|
|
16836
16796
|
} else {
|
|
@@ -16838,8 +16798,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16838
16798
|
}
|
|
16839
16799
|
};
|
|
16840
16800
|
const calculateBreakProgress = (breakStart, breakEnd, currentMinutes) => {
|
|
16841
|
-
const startMinutes =
|
|
16842
|
-
const endMinutes =
|
|
16801
|
+
const startMinutes = parseTimeToMinutes4(breakStart);
|
|
16802
|
+
const endMinutes = parseTimeToMinutes4(breakEnd);
|
|
16843
16803
|
let elapsedMinutes = 0;
|
|
16844
16804
|
let remainingMinutes = 0;
|
|
16845
16805
|
if (endMinutes < startMinutes) {
|
|
@@ -16857,8 +16817,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16857
16817
|
return { elapsedMinutes, remainingMinutes };
|
|
16858
16818
|
};
|
|
16859
16819
|
const isTimeInShift = (startTime, endTime, currentMinutes) => {
|
|
16860
|
-
const startMinutes =
|
|
16861
|
-
const endMinutes =
|
|
16820
|
+
const startMinutes = parseTimeToMinutes4(startTime);
|
|
16821
|
+
const endMinutes = parseTimeToMinutes4(endTime);
|
|
16862
16822
|
if (endMinutes < startMinutes) {
|
|
16863
16823
|
return currentMinutes >= startMinutes || currentMinutes < endMinutes;
|
|
16864
16824
|
} else {
|
|
@@ -16918,8 +16878,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16918
16878
|
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
16919
16879
|
let duration = breakItem.duration || 0;
|
|
16920
16880
|
if (!duration || duration === 0) {
|
|
16921
|
-
const startMinutes =
|
|
16922
|
-
const endMinutes =
|
|
16881
|
+
const startMinutes = parseTimeToMinutes4(startTime);
|
|
16882
|
+
const endMinutes = parseTimeToMinutes4(endTime);
|
|
16923
16883
|
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
16924
16884
|
}
|
|
16925
16885
|
return {
|
|
@@ -16935,8 +16895,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16935
16895
|
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
16936
16896
|
let duration = breakItem.duration || 0;
|
|
16937
16897
|
if (!duration || duration === 0) {
|
|
16938
|
-
const startMinutes =
|
|
16939
|
-
const endMinutes =
|
|
16898
|
+
const startMinutes = parseTimeToMinutes4(startTime);
|
|
16899
|
+
const endMinutes = parseTimeToMinutes4(endTime);
|
|
16940
16900
|
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
16941
16901
|
}
|
|
16942
16902
|
return {
|
|
@@ -23017,6 +22977,16 @@ var createThrottledReload = (interval = 5e3, maxReloads = 3) => {
|
|
|
23017
22977
|
};
|
|
23018
22978
|
var throttledReloadDashboard = createThrottledReload(5e3, 3);
|
|
23019
22979
|
|
|
22980
|
+
// src/lib/utils/dev/localDevTestLogin.ts
|
|
22981
|
+
var isLoopbackHostname = (hostname) => {
|
|
22982
|
+
const normalized = String(hostname || "").trim().toLowerCase();
|
|
22983
|
+
return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1";
|
|
22984
|
+
};
|
|
22985
|
+
var shouldEnableLocalDevTestLogin = ({
|
|
22986
|
+
enabledFlag,
|
|
22987
|
+
hostname
|
|
22988
|
+
}) => enabledFlag && isLoopbackHostname(hostname);
|
|
22989
|
+
|
|
23020
22990
|
// src/lib/utils/index.ts
|
|
23021
22991
|
var formatIdleTime = (idleTimeInSeconds) => {
|
|
23022
22992
|
if (!idleTimeInSeconds || idleTimeInSeconds <= 0) {
|
|
@@ -31201,12 +31171,16 @@ var LoginPage = ({
|
|
|
31201
31171
|
onRateLimitCheck,
|
|
31202
31172
|
logoSrc = optifye_logo_default,
|
|
31203
31173
|
logoAlt = "Optifye",
|
|
31204
|
-
brandName = "Optifye"
|
|
31174
|
+
brandName = "Optifye",
|
|
31175
|
+
showDevTestLogin = false,
|
|
31176
|
+
devTestLoginLabel = "Sign in as Test User",
|
|
31177
|
+
onDevTestLogin
|
|
31205
31178
|
}) => {
|
|
31206
31179
|
const [email, setEmail] = useState("");
|
|
31207
31180
|
const [otp, setOtp] = useState("");
|
|
31208
31181
|
const [step, setStep] = useState("email");
|
|
31209
31182
|
const [loading, setLoading] = useState(false);
|
|
31183
|
+
const [devLoginLoading, setDevLoginLoading] = useState(false);
|
|
31210
31184
|
const [error, setError] = useState(null);
|
|
31211
31185
|
const [countdown, setCountdown] = useState(0);
|
|
31212
31186
|
const supabase = useSupabase();
|
|
@@ -31270,6 +31244,25 @@ var LoginPage = ({
|
|
|
31270
31244
|
startCountdown();
|
|
31271
31245
|
}
|
|
31272
31246
|
};
|
|
31247
|
+
const handleDevTestLogin = async () => {
|
|
31248
|
+
if (!onDevTestLogin) {
|
|
31249
|
+
return;
|
|
31250
|
+
}
|
|
31251
|
+
setDevLoginLoading(true);
|
|
31252
|
+
setError(null);
|
|
31253
|
+
try {
|
|
31254
|
+
const result = await onDevTestLogin();
|
|
31255
|
+
const nextError = typeof result === "object" && result !== null && "error" in result ? result.error : null;
|
|
31256
|
+
if (typeof nextError === "string" && nextError.trim()) {
|
|
31257
|
+
setError(nextError);
|
|
31258
|
+
}
|
|
31259
|
+
} catch (err) {
|
|
31260
|
+
console.error("Dev test login failed:", err);
|
|
31261
|
+
setError("Dev test login unavailable.");
|
|
31262
|
+
} finally {
|
|
31263
|
+
setDevLoginLoading(false);
|
|
31264
|
+
}
|
|
31265
|
+
};
|
|
31273
31266
|
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
31267
|
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-2xl shadow-xl border border-slate-200 p-8", children: [
|
|
31275
31268
|
/* @__PURE__ */ jsxs("div", { className: "text-center mb-8", children: [
|
|
@@ -31310,7 +31303,7 @@ var LoginPage = ({
|
|
|
31310
31303
|
"button",
|
|
31311
31304
|
{
|
|
31312
31305
|
type: "submit",
|
|
31313
|
-
disabled: loading,
|
|
31306
|
+
disabled: loading || devLoginLoading,
|
|
31314
31307
|
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
31308
|
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31316
31309
|
/* @__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 +31313,31 @@ var LoginPage = ({
|
|
|
31320
31313
|
"Sending..."
|
|
31321
31314
|
] }) : "Continue with Email"
|
|
31322
31315
|
}
|
|
31323
|
-
)
|
|
31316
|
+
),
|
|
31317
|
+
showDevTestLogin && onDevTestLogin ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
31318
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
31319
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-slate-200" }),
|
|
31320
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium uppercase tracking-[0.2em] text-slate-400", children: "Local Dev" }),
|
|
31321
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-slate-200" })
|
|
31322
|
+
] }),
|
|
31323
|
+
/* @__PURE__ */ jsx(
|
|
31324
|
+
"button",
|
|
31325
|
+
{
|
|
31326
|
+
type: "button",
|
|
31327
|
+
disabled: loading || devLoginLoading,
|
|
31328
|
+
onClick: () => void handleDevTestLogin(),
|
|
31329
|
+
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",
|
|
31330
|
+
children: devLoginLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31331
|
+
/* @__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: [
|
|
31332
|
+
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
31333
|
+
/* @__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" })
|
|
31334
|
+
] }),
|
|
31335
|
+
"Signing In..."
|
|
31336
|
+
] }) : devTestLoginLabel
|
|
31337
|
+
}
|
|
31338
|
+
),
|
|
31339
|
+
/* @__PURE__ */ jsx("p", { className: "text-center text-xs text-slate-500", children: "Localhost-only convenience login for the shared test account." })
|
|
31340
|
+
] }) : null
|
|
31324
31341
|
] }) : /* @__PURE__ */ jsxs("form", { className: "space-y-6", onSubmit: handleVerifyOTP, children: [
|
|
31325
31342
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
31326
31343
|
/* @__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 +31362,7 @@ var LoginPage = ({
|
|
|
31345
31362
|
"button",
|
|
31346
31363
|
{
|
|
31347
31364
|
type: "submit",
|
|
31348
|
-
disabled: loading || otp.length !== 6,
|
|
31365
|
+
disabled: loading || devLoginLoading || otp.length !== 6,
|
|
31349
31366
|
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
31367
|
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31351
31368
|
/* @__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: [
|
|
@@ -32170,6 +32187,7 @@ var LineChartComponent = ({
|
|
|
32170
32187
|
xAxisLabel,
|
|
32171
32188
|
xAxisTickFormatter,
|
|
32172
32189
|
// Pass through for X-axis tick formatting
|
|
32190
|
+
xAxisInterval,
|
|
32173
32191
|
yAxisLabel,
|
|
32174
32192
|
yAxisUnit,
|
|
32175
32193
|
yAxisDomain,
|
|
@@ -32186,31 +32204,35 @@ var LineChartComponent = ({
|
|
|
32186
32204
|
...restOfChartProps
|
|
32187
32205
|
}) => {
|
|
32188
32206
|
const containerRef = React141__default.useRef(null);
|
|
32189
|
-
const [
|
|
32190
|
-
const
|
|
32191
|
-
const { formatNumber } = useFormatNumber();
|
|
32207
|
+
const [dimensions, setDimensions] = React141__default.useState({ width: 0, height: 0 });
|
|
32208
|
+
const [hasValidData, setHasValidData] = React141__default.useState(false);
|
|
32192
32209
|
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);
|
|
32210
|
+
const currentHasValidData = data && lines && lines.length > 0 && data.some(
|
|
32211
|
+
(item) => lines.some((line) => {
|
|
32212
|
+
const val = item[line.dataKey];
|
|
32213
|
+
return typeof val === "number" && val > 0;
|
|
32214
|
+
})
|
|
32215
|
+
);
|
|
32216
|
+
if (currentHasValidData && !hasValidData) {
|
|
32217
|
+
setHasValidData(true);
|
|
32205
32218
|
}
|
|
32206
|
-
|
|
32207
|
-
|
|
32208
|
-
|
|
32209
|
-
|
|
32210
|
-
|
|
32211
|
-
|
|
32212
|
-
|
|
32219
|
+
}, [data, lines, hasValidData]);
|
|
32220
|
+
React141__default.useEffect(() => {
|
|
32221
|
+
if (!containerRef.current) return;
|
|
32222
|
+
const observer = new ResizeObserver((entries) => {
|
|
32223
|
+
const entry = entries[0];
|
|
32224
|
+
if (entry) {
|
|
32225
|
+
setDimensions({
|
|
32226
|
+
width: entry.contentRect.width,
|
|
32227
|
+
height: entry.contentRect.height
|
|
32228
|
+
});
|
|
32229
|
+
}
|
|
32230
|
+
});
|
|
32231
|
+
observer.observe(containerRef.current);
|
|
32232
|
+
return () => observer.disconnect();
|
|
32213
32233
|
}, []);
|
|
32234
|
+
const themeConfig = useThemeConfig();
|
|
32235
|
+
const { formatNumber } = useFormatNumber();
|
|
32214
32236
|
const yAxisTickFormatter = (value) => {
|
|
32215
32237
|
return `${formatNumber(value)}${yAxisUnit || ""}`;
|
|
32216
32238
|
};
|
|
@@ -32232,57 +32254,72 @@ var LineChartComponent = ({
|
|
|
32232
32254
|
const gridStrokeColor = themeConfig?.gray?.["300"] || "#ccc";
|
|
32233
32255
|
const axisTickFillColor = themeConfig?.gray?.["600"] || "#666";
|
|
32234
32256
|
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
|
-
|
|
32257
|
+
const renderChartContent = (chartWidth, chartHeight) => /* @__PURE__ */ jsxs(
|
|
32258
|
+
LineChart$1,
|
|
32259
|
+
{
|
|
32260
|
+
width: chartWidth,
|
|
32261
|
+
height: chartHeight,
|
|
32262
|
+
data,
|
|
32263
|
+
margin: { top: 5, right: 30, left: 20, bottom: 20 },
|
|
32264
|
+
...restOfChartProps,
|
|
32265
|
+
children: [
|
|
32266
|
+
showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStrokeColor }),
|
|
32267
|
+
/* @__PURE__ */ jsx(
|
|
32268
|
+
XAxis,
|
|
32269
|
+
{
|
|
32270
|
+
dataKey: xAxisDataKey,
|
|
32271
|
+
label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -10 } : void 0,
|
|
32272
|
+
tickFormatter: xAxisTickFormatter,
|
|
32273
|
+
interval: xAxisInterval,
|
|
32274
|
+
tick: { fontSize: 12, fill: axisTickFillColor },
|
|
32275
|
+
stroke: axisStrokeColor
|
|
32276
|
+
}
|
|
32277
|
+
),
|
|
32278
|
+
/* @__PURE__ */ jsx(
|
|
32279
|
+
YAxis,
|
|
32280
|
+
{
|
|
32281
|
+
label: yAxisLabel ? { value: yAxisLabel, angle: -90, position: "insideLeft" } : void 0,
|
|
32282
|
+
tickFormatter: yAxisTickFormatter,
|
|
32283
|
+
domain: yAxisDomain,
|
|
32284
|
+
tick: { fontSize: 12, fill: axisTickFillColor },
|
|
32285
|
+
stroke: axisStrokeColor
|
|
32286
|
+
}
|
|
32287
|
+
),
|
|
32288
|
+
showTooltip && /* @__PURE__ */ jsx(
|
|
32289
|
+
Tooltip,
|
|
32290
|
+
{
|
|
32291
|
+
formatter: tooltipFormatter || defaultTooltipFormatter,
|
|
32292
|
+
labelFormatter: tooltipLabelFormatter,
|
|
32293
|
+
itemStyle: { color: "#111827" },
|
|
32294
|
+
cursor: { strokeDasharray: "3 3" }
|
|
32295
|
+
}
|
|
32296
|
+
),
|
|
32297
|
+
showLegend && /* @__PURE__ */ jsx(Legend, { payload: legendPayload }),
|
|
32298
|
+
lines.map((lineConfig, index) => {
|
|
32299
|
+
const lineProps = {
|
|
32300
|
+
...lineConfig,
|
|
32301
|
+
key: lineConfig.dataKey,
|
|
32302
|
+
type: lineConfig.type || "monotone",
|
|
32303
|
+
stroke: lineConfig.stroke || defaultColors[index % defaultColors.length],
|
|
32304
|
+
activeDot: lineConfig.activeDot !== void 0 ? lineConfig.activeDot : { r: 6 },
|
|
32305
|
+
isAnimationActive: true,
|
|
32306
|
+
animationDuration: 1500,
|
|
32307
|
+
animationBegin: 300
|
|
32308
|
+
};
|
|
32309
|
+
return /* @__PURE__ */ jsx(Line, { ...lineProps, children: lineConfig.labelList && /* @__PURE__ */ jsx(
|
|
32310
|
+
LabelList,
|
|
32311
|
+
{
|
|
32312
|
+
dataKey: lineConfig.dataKey,
|
|
32313
|
+
position: "top",
|
|
32314
|
+
formatter: (value) => formatNumber(value),
|
|
32315
|
+
...typeof lineConfig.labelList === "object" ? lineConfig.labelList : {}
|
|
32316
|
+
}
|
|
32317
|
+
) });
|
|
32318
|
+
})
|
|
32319
|
+
]
|
|
32320
|
+
},
|
|
32321
|
+
hasValidData ? "valid" : "empty"
|
|
32322
|
+
);
|
|
32286
32323
|
if (responsive) {
|
|
32287
32324
|
return /* @__PURE__ */ jsx(
|
|
32288
32325
|
"div",
|
|
@@ -32290,11 +32327,20 @@ var LineChartComponent = ({
|
|
|
32290
32327
|
ref: containerRef,
|
|
32291
32328
|
className: clsx(fillContainer ? "w-full h-full" : "w-full h-auto", className),
|
|
32292
32329
|
style: fillContainer ? { height: "100%", minHeight: "50px", minWidth: "100px" } : { aspectRatio: `${aspect}/1`, minHeight: "50px", minWidth: "100px" },
|
|
32293
|
-
children:
|
|
32330
|
+
children: /* @__PURE__ */ jsx(
|
|
32331
|
+
motion.div,
|
|
32332
|
+
{
|
|
32333
|
+
initial: { opacity: 0 },
|
|
32334
|
+
animate: { opacity: 1 },
|
|
32335
|
+
transition: { duration: 0.5 },
|
|
32336
|
+
className: "w-full h-full",
|
|
32337
|
+
children: dimensions.width > 0 && dimensions.height > 0 && renderChartContent(dimensions.width, dimensions.height)
|
|
32338
|
+
}
|
|
32339
|
+
)
|
|
32294
32340
|
}
|
|
32295
32341
|
);
|
|
32296
32342
|
}
|
|
32297
|
-
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children:
|
|
32343
|
+
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
|
|
32298
32344
|
};
|
|
32299
32345
|
var LineChart = React141__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
32300
32346
|
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 +32608,35 @@ var CycleTimeOverTimeChart = ({
|
|
|
32562
32608
|
}) => {
|
|
32563
32609
|
const MAX_DATA_POINTS = 40;
|
|
32564
32610
|
const containerRef = React141__default.useRef(null);
|
|
32565
|
-
const [
|
|
32566
|
-
const
|
|
32611
|
+
const [dimensions, setDimensions] = React141__default.useState({ width: 0, height: 0 });
|
|
32612
|
+
const [hasValidData, setHasValidData] = React141__default.useState(false);
|
|
32613
|
+
React141__default.useEffect(() => {
|
|
32614
|
+
const currentHasValidData = data && data.some((val) => val !== null && val > 0);
|
|
32615
|
+
if (currentHasValidData && !hasValidData) {
|
|
32616
|
+
setHasValidData(true);
|
|
32617
|
+
}
|
|
32618
|
+
}, [data, hasValidData]);
|
|
32619
|
+
React141__default.useEffect(() => {
|
|
32620
|
+
if (!containerRef.current) return;
|
|
32621
|
+
const observer = new ResizeObserver((entries) => {
|
|
32622
|
+
const entry = entries[0];
|
|
32623
|
+
if (entry) {
|
|
32624
|
+
setDimensions({
|
|
32625
|
+
width: entry.contentRect.width,
|
|
32626
|
+
height: entry.contentRect.height
|
|
32627
|
+
});
|
|
32628
|
+
}
|
|
32629
|
+
});
|
|
32630
|
+
observer.observe(containerRef.current);
|
|
32631
|
+
return () => observer.disconnect();
|
|
32632
|
+
}, []);
|
|
32633
|
+
const parseTimeToMinutes4 = (value) => {
|
|
32567
32634
|
const [hours, minutes] = value.split(":").map(Number);
|
|
32568
32635
|
if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return 0;
|
|
32569
32636
|
return hours * 60 + minutes;
|
|
32570
32637
|
};
|
|
32571
32638
|
const formatHourLabel = (slotIndex) => {
|
|
32572
|
-
const baseMinutes =
|
|
32639
|
+
const baseMinutes = parseTimeToMinutes4(shiftStart);
|
|
32573
32640
|
const absoluteMinutes = baseMinutes + slotIndex * 60;
|
|
32574
32641
|
const hour24 = Math.floor(absoluteMinutes % (24 * 60) / 60);
|
|
32575
32642
|
const ampm = hour24 >= 12 ? "PM" : "AM";
|
|
@@ -32588,52 +32655,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32588
32655
|
const displayData = getDisplayData(data);
|
|
32589
32656
|
const DURATION = displayData.length;
|
|
32590
32657
|
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
32658
|
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
32659
|
const labelInterval = React141__default.useMemo(() => {
|
|
32638
32660
|
if (xAxisMode === "hourly") {
|
|
32639
32661
|
return Math.max(1, Math.ceil(DURATION / 8));
|
|
@@ -32841,144 +32863,154 @@ var CycleTimeOverTimeChart = ({
|
|
|
32841
32863
|
return /* @__PURE__ */ jsxs(
|
|
32842
32864
|
"div",
|
|
32843
32865
|
{
|
|
32844
|
-
ref: containerRef,
|
|
32845
32866
|
className: `w-full h-full min-w-0 flex flex-col relative pb-2 ${className}`,
|
|
32846
32867
|
style: { minHeight: "200px", minWidth: 0 },
|
|
32847
32868
|
children: [
|
|
32848
32869
|
renderLegend(),
|
|
32849
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 w-full",
|
|
32850
|
-
|
|
32870
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 w-full", ref: containerRef, children: /* @__PURE__ */ jsx(
|
|
32871
|
+
motion.div,
|
|
32851
32872
|
{
|
|
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"
|
|
32873
|
+
initial: { opacity: 0 },
|
|
32874
|
+
animate: { opacity: 1 },
|
|
32875
|
+
transition: { duration: 0.5 },
|
|
32876
|
+
className: "w-full h-full",
|
|
32877
|
+
children: dimensions.width > 0 && dimensions.height > 0 && /* @__PURE__ */ jsxs(
|
|
32878
|
+
LineChart$1,
|
|
32879
|
+
{
|
|
32880
|
+
width: dimensions.width,
|
|
32881
|
+
height: dimensions.height,
|
|
32882
|
+
data: chartData,
|
|
32883
|
+
margin: {
|
|
32884
|
+
top: 5,
|
|
32885
|
+
right: 30,
|
|
32886
|
+
bottom: 25,
|
|
32887
|
+
left: 10
|
|
32976
32888
|
},
|
|
32977
|
-
|
|
32978
|
-
|
|
32979
|
-
|
|
32889
|
+
children: [
|
|
32890
|
+
/* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", vertical: false }),
|
|
32891
|
+
/* @__PURE__ */ jsx(
|
|
32892
|
+
XAxis,
|
|
32893
|
+
{
|
|
32894
|
+
dataKey: "label",
|
|
32895
|
+
tick: { fontSize: 11 },
|
|
32896
|
+
interval: 0,
|
|
32897
|
+
angle: xAxisMode === "hourly" ? 0 : -30,
|
|
32898
|
+
textAnchor: xAxisMode === "hourly" ? "middle" : "end",
|
|
32899
|
+
tickMargin: xAxisMode === "hourly" ? 8 : 15,
|
|
32900
|
+
height: xAxisMode === "hourly" ? 40 : 60
|
|
32901
|
+
}
|
|
32902
|
+
),
|
|
32903
|
+
/* @__PURE__ */ jsx(
|
|
32904
|
+
YAxis,
|
|
32905
|
+
{
|
|
32906
|
+
tickMargin: 8,
|
|
32907
|
+
width: 45,
|
|
32908
|
+
yAxisId: "cycle",
|
|
32909
|
+
domain: ["auto", "auto"],
|
|
32910
|
+
ticks: [0, idealCycleTime, ...Array.from({ length: 4 }, (_, i) => (i + 1) * Math.ceil(idealCycleTime / 2))].sort((a, b) => a - b),
|
|
32911
|
+
tickFormatter: (value) => String(value),
|
|
32912
|
+
tick: (props) => {
|
|
32913
|
+
const { x, y, payload } = props;
|
|
32914
|
+
const displayValue = typeof payload.value === "number" ? payload.value.toFixed(1) : String(payload.value);
|
|
32915
|
+
return /* @__PURE__ */ jsx("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ jsx(
|
|
32916
|
+
"text",
|
|
32917
|
+
{
|
|
32918
|
+
x: 0,
|
|
32919
|
+
y: 0,
|
|
32920
|
+
dy: 4,
|
|
32921
|
+
textAnchor: "end",
|
|
32922
|
+
fill: payload.value === idealCycleTime ? "#E34329" : "#666",
|
|
32923
|
+
fontSize: 12,
|
|
32924
|
+
fontWeight: payload.value === idealCycleTime ? "bold" : "normal",
|
|
32925
|
+
children: displayValue
|
|
32926
|
+
},
|
|
32927
|
+
`tick-${payload.value}-${x}-${y}`
|
|
32928
|
+
) });
|
|
32929
|
+
}
|
|
32930
|
+
}
|
|
32931
|
+
),
|
|
32932
|
+
showIdleTime && /* @__PURE__ */ jsx(
|
|
32933
|
+
YAxis,
|
|
32934
|
+
{
|
|
32935
|
+
yAxisId: "idle",
|
|
32936
|
+
orientation: "right",
|
|
32937
|
+
tickMargin: 8,
|
|
32938
|
+
width: 35,
|
|
32939
|
+
domain: [0, 60],
|
|
32940
|
+
tickFormatter: (value) => `${value}m`,
|
|
32941
|
+
tick: { fontSize: 11, fill: "#f59e0b" },
|
|
32942
|
+
axisLine: false,
|
|
32943
|
+
tickLine: false
|
|
32944
|
+
}
|
|
32945
|
+
),
|
|
32946
|
+
/* @__PURE__ */ jsx(
|
|
32947
|
+
Tooltip,
|
|
32948
|
+
{
|
|
32949
|
+
cursor: { stroke: "#E5E7EB", strokeWidth: 1 },
|
|
32950
|
+
content: renderChartTooltip,
|
|
32951
|
+
animationDuration: 200
|
|
32952
|
+
}
|
|
32953
|
+
),
|
|
32954
|
+
/* @__PURE__ */ jsx(
|
|
32955
|
+
ReferenceLine,
|
|
32956
|
+
{
|
|
32957
|
+
y: idealCycleTime,
|
|
32958
|
+
yAxisId: "cycle",
|
|
32959
|
+
stroke: "#E34329",
|
|
32960
|
+
strokeDasharray: "3 3",
|
|
32961
|
+
strokeWidth: 2,
|
|
32962
|
+
label: {
|
|
32963
|
+
position: "right",
|
|
32964
|
+
value: `${idealCycleTime.toFixed(1)}s`,
|
|
32965
|
+
fill: "#E34329",
|
|
32966
|
+
fontSize: 12,
|
|
32967
|
+
fontWeight: 500
|
|
32968
|
+
}
|
|
32969
|
+
}
|
|
32970
|
+
),
|
|
32971
|
+
/* @__PURE__ */ jsx(
|
|
32972
|
+
Line,
|
|
32973
|
+
{
|
|
32974
|
+
type: "monotone",
|
|
32975
|
+
yAxisId: "cycle",
|
|
32976
|
+
dataKey: "cycleTime",
|
|
32977
|
+
stroke: "#3B82F6",
|
|
32978
|
+
strokeWidth: 2,
|
|
32979
|
+
connectNulls: false,
|
|
32980
|
+
dot: renderCycleDot,
|
|
32981
|
+
activeDot: renderCycleActiveDot,
|
|
32982
|
+
isAnimationActive: true,
|
|
32983
|
+
animationBegin: 300,
|
|
32984
|
+
animationDuration: 1500,
|
|
32985
|
+
animationEasing: "ease-out"
|
|
32986
|
+
},
|
|
32987
|
+
`${effectiveDatasetKey}:cycle`
|
|
32988
|
+
),
|
|
32989
|
+
showIdleTime && /* @__PURE__ */ jsx(
|
|
32990
|
+
Line,
|
|
32991
|
+
{
|
|
32992
|
+
type: "monotone",
|
|
32993
|
+
yAxisId: "idle",
|
|
32994
|
+
dataKey: "idleMinutes",
|
|
32995
|
+
stroke: "#f59e0b",
|
|
32996
|
+
strokeWidth: 2,
|
|
32997
|
+
strokeDasharray: "4 4",
|
|
32998
|
+
connectNulls: false,
|
|
32999
|
+
dot: renderIdleDot,
|
|
33000
|
+
activeDot: renderIdleActiveDot,
|
|
33001
|
+
isAnimationActive: true,
|
|
33002
|
+
animationBegin: 300,
|
|
33003
|
+
animationDuration: 1500,
|
|
33004
|
+
animationEasing: "ease-out"
|
|
33005
|
+
},
|
|
33006
|
+
`${effectiveDatasetKey}:idle`
|
|
33007
|
+
)
|
|
33008
|
+
]
|
|
33009
|
+
},
|
|
33010
|
+
hasValidData ? "valid" : "empty"
|
|
33011
|
+
)
|
|
32980
33012
|
}
|
|
32981
|
-
) })
|
|
33013
|
+
) })
|
|
32982
33014
|
]
|
|
32983
33015
|
}
|
|
32984
33016
|
);
|
|
@@ -33828,10 +33860,10 @@ var HourlyOutputChart = React141__default.memo(HourlyOutputChartComponent, (prev
|
|
|
33828
33860
|
HourlyOutputChart.displayName = "HourlyOutputChart";
|
|
33829
33861
|
|
|
33830
33862
|
// src/components/dashboard/grid/videoGridMetricUtils.ts
|
|
33831
|
-
var VIDEO_GRID_LEGEND_LABEL = "
|
|
33863
|
+
var VIDEO_GRID_LEGEND_LABEL = "7 Minute Efficiency";
|
|
33832
33864
|
var MAP_GRID_LEGEND_LABEL = "Efficiency";
|
|
33833
|
-
var MIXED_VIDEO_GRID_LEGEND_LABEL = "
|
|
33834
|
-
var
|
|
33865
|
+
var MIXED_VIDEO_GRID_LEGEND_LABEL = "Efficiency";
|
|
33866
|
+
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
33835
33867
|
var isVideoGridRecentFlowEnabled = (workspace) => isRecentFlowVideoGridMetricMode(
|
|
33836
33868
|
workspace.video_grid_metric_mode,
|
|
33837
33869
|
workspace.assembly_enabled === true
|
|
@@ -33840,11 +33872,11 @@ var isVideoGridWipGated = (workspace) => isWipGatedVideoGridMetricMode(
|
|
|
33840
33872
|
workspace.video_grid_metric_mode,
|
|
33841
33873
|
workspace.assembly_enabled === true
|
|
33842
33874
|
);
|
|
33843
|
-
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) &&
|
|
33875
|
+
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) && isFiniteNumber(workspace.recent_flow_percent);
|
|
33844
33876
|
var isVideoGridRecentFlowUnavailable = (workspace) => isVideoGridRecentFlowEnabled(workspace) && !hasVideoGridRecentFlow(workspace);
|
|
33845
33877
|
var getVideoGridMetricValue = (workspace) => {
|
|
33846
33878
|
const recentFlowPercent = workspace.recent_flow_percent;
|
|
33847
|
-
if (hasVideoGridRecentFlow(workspace) &&
|
|
33879
|
+
if (hasVideoGridRecentFlow(workspace) && isFiniteNumber(recentFlowPercent)) {
|
|
33848
33880
|
return recentFlowPercent;
|
|
33849
33881
|
}
|
|
33850
33882
|
if (isVideoGridRecentFlowUnavailable(workspace)) {
|
|
@@ -33855,7 +33887,7 @@ var getVideoGridMetricValue = (workspace) => {
|
|
|
33855
33887
|
var hasIncomingWipMapping = (workspace) => Boolean(workspace.incoming_wip_buffer_name);
|
|
33856
33888
|
var getVideoGridBaseColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
33857
33889
|
const metricValue = getVideoGridMetricValue(workspace);
|
|
33858
|
-
if (!
|
|
33890
|
+
if (!isFiniteNumber(metricValue)) {
|
|
33859
33891
|
return "neutral";
|
|
33860
33892
|
}
|
|
33861
33893
|
return getEfficiencyColor(metricValue, legend);
|
|
@@ -33870,7 +33902,7 @@ var isLowWipGreenOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
|
33870
33902
|
if (!hasIncomingWipMapping(workspace)) {
|
|
33871
33903
|
return false;
|
|
33872
33904
|
}
|
|
33873
|
-
return
|
|
33905
|
+
return isFiniteNumber(workspace.incoming_wip_current) && workspace.incoming_wip_current <= 1;
|
|
33874
33906
|
};
|
|
33875
33907
|
var toMinuteBucket = (minuteBucket) => Number.isFinite(minuteBucket) ? Math.floor(minuteBucket) : Math.floor(Date.now() / 6e4);
|
|
33876
33908
|
var getEffectiveFlowMinuteBucket = (workspace) => {
|
|
@@ -33912,7 +33944,7 @@ var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) =>
|
|
|
33912
33944
|
if (!hasIncomingWipMapping(workspace)) {
|
|
33913
33945
|
return baseColor;
|
|
33914
33946
|
}
|
|
33915
|
-
if (!
|
|
33947
|
+
if (!isFiniteNumber(workspace.incoming_wip_current)) {
|
|
33916
33948
|
return "neutral";
|
|
33917
33949
|
}
|
|
33918
33950
|
if (isLowWipGreenOverride(workspace, legend)) {
|
|
@@ -33982,8 +34014,9 @@ var VideoCard = React141__default.memo(({
|
|
|
33982
34014
|
const isRecentFlowCard = isVideoGridRecentFlowEnabled(workspace);
|
|
33983
34015
|
const hasDisplayMetric = typeof videoGridDisplayValue === "number" && Number.isFinite(videoGridDisplayValue);
|
|
33984
34016
|
const hasBarMetric = typeof videoGridMetricValue === "number" && Number.isFinite(videoGridMetricValue);
|
|
34017
|
+
const shouldRenderMetricBadge = hasDisplayMetric;
|
|
33985
34018
|
const badgeTitle = hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
33986
|
-
const badgeLabel =
|
|
34019
|
+
const badgeLabel = `${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
33987
34020
|
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
33988
34021
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
33989
34022
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
@@ -34059,7 +34092,7 @@ var VideoCard = React141__default.memo(({
|
|
|
34059
34092
|
lastSeenText
|
|
34060
34093
|
] })
|
|
34061
34094
|
] }) }),
|
|
34062
|
-
/* @__PURE__ */ jsx("div", { className: `absolute ${compact ? "top-1 right-1" : "top-2 right-2"} z-30`, children: /* @__PURE__ */ jsx(
|
|
34095
|
+
shouldRenderMetricBadge && /* @__PURE__ */ jsx("div", { className: `absolute ${compact ? "top-1 right-1" : "top-2 right-2"} z-30`, children: /* @__PURE__ */ jsx(
|
|
34063
34096
|
"div",
|
|
34064
34097
|
{
|
|
34065
34098
|
"data-testid": "video-card-metric-badge",
|
|
@@ -34104,7 +34137,7 @@ var VideoCard = React141__default.memo(({
|
|
|
34104
34137
|
}
|
|
34105
34138
|
);
|
|
34106
34139
|
}, (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.
|
|
34140
|
+
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
34141
|
return false;
|
|
34109
34142
|
}
|
|
34110
34143
|
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 +44605,7 @@ var ShiftDisplay = memo$1(({ className, variant = "default", lineId }) => {
|
|
|
44572
44605
|
return null;
|
|
44573
44606
|
}
|
|
44574
44607
|
};
|
|
44575
|
-
const
|
|
44608
|
+
const getShiftIcon2 = (shift) => {
|
|
44576
44609
|
if (shift === "Day") {
|
|
44577
44610
|
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
44611
|
} else {
|
|
@@ -44598,7 +44631,7 @@ var ShiftDisplay = memo$1(({ className, variant = "default", lineId }) => {
|
|
|
44598
44631
|
}
|
|
44599
44632
|
if (variant === "enhanced") {
|
|
44600
44633
|
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:
|
|
44634
|
+
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children: getShiftIcon2(currentShiftText) }),
|
|
44602
44635
|
/* @__PURE__ */ jsxs("span", { className: "text-base font-medium text-blue-800", children: [
|
|
44603
44636
|
currentShiftText,
|
|
44604
44637
|
" Shift"
|
|
@@ -44606,7 +44639,7 @@ var ShiftDisplay = memo$1(({ className, variant = "default", lineId }) => {
|
|
|
44606
44639
|
] });
|
|
44607
44640
|
}
|
|
44608
44641
|
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:
|
|
44642
|
+
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children: getShiftIcon2(currentShiftText) }),
|
|
44610
44643
|
/* @__PURE__ */ jsxs("span", { className: "text-base font-medium text-blue-800", children: [
|
|
44611
44644
|
currentShiftText,
|
|
44612
44645
|
" Shift"
|
|
@@ -47243,7 +47276,7 @@ var LinePdfGenerator = ({
|
|
|
47243
47276
|
doc.setLineWidth(0.8);
|
|
47244
47277
|
doc.line(20, 123, 190, 123);
|
|
47245
47278
|
const hourlyOverviewStartY = 128;
|
|
47246
|
-
const
|
|
47279
|
+
const parseTimeToMinutes4 = (timeStr) => {
|
|
47247
47280
|
const [hours, minutes] = timeStr.split(":");
|
|
47248
47281
|
const hour = parseInt(hours, 10);
|
|
47249
47282
|
const minute = parseInt(minutes || "0", 10);
|
|
@@ -47276,7 +47309,7 @@ var LinePdfGenerator = ({
|
|
|
47276
47309
|
};
|
|
47277
47310
|
};
|
|
47278
47311
|
const getHourlyTimeRanges = (startTimeStr, endTimeStr) => {
|
|
47279
|
-
const startMinutes =
|
|
47312
|
+
const startMinutes = parseTimeToMinutes4(startTimeStr);
|
|
47280
47313
|
if (Number.isNaN(startMinutes)) {
|
|
47281
47314
|
return [];
|
|
47282
47315
|
}
|
|
@@ -47284,7 +47317,7 @@ var LinePdfGenerator = ({
|
|
|
47284
47317
|
const defaultHours = 11;
|
|
47285
47318
|
return Array.from({ length: defaultHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
|
|
47286
47319
|
}
|
|
47287
|
-
const endMinutes =
|
|
47320
|
+
const endMinutes = parseTimeToMinutes4(endTimeStr);
|
|
47288
47321
|
if (Number.isNaN(endMinutes)) {
|
|
47289
47322
|
const fallbackHours = 11;
|
|
47290
47323
|
return Array.from({ length: fallbackHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
|
|
@@ -49053,7 +49086,7 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
49053
49086
|
minute: "2-digit",
|
|
49054
49087
|
hour12: true
|
|
49055
49088
|
});
|
|
49056
|
-
const
|
|
49089
|
+
const parseTimeToMinutes4 = (timeValue) => {
|
|
49057
49090
|
const [hourPart, minutePart] = timeValue.split(":").map(Number);
|
|
49058
49091
|
const hour = Number.isFinite(hourPart) ? hourPart : 0;
|
|
49059
49092
|
const minute = Number.isFinite(minutePart) ? minutePart : 0;
|
|
@@ -49070,8 +49103,8 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
49070
49103
|
const IST_OFFSET_MINUTES = 330;
|
|
49071
49104
|
return Date.UTC(year, month - 1, day, hour, minute) - IST_OFFSET_MINUTES * 60 * 1e3;
|
|
49072
49105
|
};
|
|
49073
|
-
const shiftStartMinutes =
|
|
49074
|
-
const shiftEndMinutes =
|
|
49106
|
+
const shiftStartMinutes = parseTimeToMinutes4(workspace.shift_start);
|
|
49107
|
+
const shiftEndMinutes = parseTimeToMinutes4(workspace.shift_end);
|
|
49075
49108
|
const wrapsMidnight = shiftEndMinutes <= shiftStartMinutes;
|
|
49076
49109
|
const shiftStartUtcMs = toShiftUtcMs(workspace.date, workspace.shift_start);
|
|
49077
49110
|
const shiftEndUtcMs = toShiftUtcMs(workspace.date, workspace.shift_end) + (wrapsMidnight ? 24 * 60 * 60 * 1e3 : 0);
|
|
@@ -49786,8 +49819,7 @@ var WorkspaceCycleTimeMetricCards = ({
|
|
|
49786
49819
|
{
|
|
49787
49820
|
data: idleTimeData.chartData,
|
|
49788
49821
|
isLoading: idleTimeData.isLoading,
|
|
49789
|
-
error: idleTimeData.error
|
|
49790
|
-
variant: "bar"
|
|
49822
|
+
error: idleTimeData.error
|
|
49791
49823
|
}
|
|
49792
49824
|
) })
|
|
49793
49825
|
] })
|
|
@@ -51378,7 +51410,7 @@ var DashboardHeader = memo$1(({ lineTitle, className = "", headerControls, lineI
|
|
|
51378
51410
|
const rawName = currentShift.shiftName || "Day";
|
|
51379
51411
|
return rawName.toLowerCase().includes("shift") ? rawName : `${rawName} Shift`;
|
|
51380
51412
|
};
|
|
51381
|
-
const
|
|
51413
|
+
const getShiftIcon2 = () => {
|
|
51382
51414
|
const currentShift = getCurrentShift(timezone, shiftConfig);
|
|
51383
51415
|
const shiftName = (currentShift.shiftName || "").toLowerCase();
|
|
51384
51416
|
if (shiftName.includes("day") || shiftName.includes("morning") || currentShift.shiftId === 0) {
|
|
@@ -51412,7 +51444,7 @@ var DashboardHeader = memo$1(({ lineTitle, className = "", headerControls, lineI
|
|
|
51412
51444
|
/* @__PURE__ */ jsx("span", { className: "font-medium", children: /* @__PURE__ */ jsx(Timer2, {}) }),
|
|
51413
51445
|
/* @__PURE__ */ jsx("span", { className: "text-gray-300", children: "|" }),
|
|
51414
51446
|
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:
|
|
51447
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-75", children: getShiftIcon2() }),
|
|
51416
51448
|
getShiftName()
|
|
51417
51449
|
] })
|
|
51418
51450
|
] })
|
|
@@ -51429,7 +51461,7 @@ var DashboardHeader = memo$1(({ lineTitle, className = "", headerControls, lineI
|
|
|
51429
51461
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 inline-flex flex-wrap items-center gap-3", children: [
|
|
51430
51462
|
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-600 whitespace-nowrap", children: /* @__PURE__ */ jsx(Timer2, {}) }),
|
|
51431
51463
|
/* @__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:
|
|
51464
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children: getShiftIcon2() }),
|
|
51433
51465
|
/* @__PURE__ */ jsx("span", { className: "text-xs md:text-sm font-medium text-gray-600 whitespace-nowrap", children: getShiftName() })
|
|
51434
51466
|
] }) })
|
|
51435
51467
|
] })
|
|
@@ -58400,7 +58432,7 @@ var FactoryView = ({
|
|
|
58400
58432
|
const currentShift = getCurrentShiftInfo();
|
|
58401
58433
|
return (currentShift.shiftName || "Day").replace(/ Shift$/i, "");
|
|
58402
58434
|
};
|
|
58403
|
-
const
|
|
58435
|
+
const getShiftIcon2 = () => {
|
|
58404
58436
|
const currentShift = getCurrentShiftInfo();
|
|
58405
58437
|
const shiftNameLower = (currentShift.shiftName || "").toLowerCase();
|
|
58406
58438
|
if (shiftNameLower.includes("day") || shiftNameLower.includes("morning") || currentShift.shiftId === 0) {
|
|
@@ -58446,7 +58478,7 @@ var FactoryView = ({
|
|
|
58446
58478
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center justify-center gap-2", children: [
|
|
58447
58479
|
/* @__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
58480
|
/* @__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:
|
|
58481
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2() }),
|
|
58450
58482
|
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-gray-700", children: [
|
|
58451
58483
|
getShiftName(),
|
|
58452
58484
|
" Shift"
|
|
@@ -58465,7 +58497,7 @@ var FactoryView = ({
|
|
|
58465
58497
|
" IST"
|
|
58466
58498
|
] }),
|
|
58467
58499
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1", children: [
|
|
58468
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children:
|
|
58500
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children: getShiftIcon2() }),
|
|
58469
58501
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-gray-600", children: [
|
|
58470
58502
|
getShiftName(),
|
|
58471
58503
|
" Shift"
|
|
@@ -61177,7 +61209,7 @@ var KPIDetailView = ({
|
|
|
61177
61209
|
const getShiftName = useCallback((shiftId) => {
|
|
61178
61210
|
return getShiftNameById(shiftId, configuredTimezone, shiftConfig);
|
|
61179
61211
|
}, [configuredTimezone, shiftConfig]);
|
|
61180
|
-
const
|
|
61212
|
+
const getShiftIcon2 = useCallback((shiftId) => {
|
|
61181
61213
|
if (shiftId === 0) {
|
|
61182
61214
|
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
61215
|
}
|
|
@@ -62057,7 +62089,7 @@ var KPIDetailView = ({
|
|
|
62057
62089
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
|
|
62058
62090
|
/* @__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
62091
|
/* @__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:
|
|
62092
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(chartMetrics.shift_id ?? 0) }),
|
|
62061
62093
|
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-gray-700", children: [
|
|
62062
62094
|
getShiftName(chartMetrics.shift_id ?? 0).replace(/ Shift$/i, ""),
|
|
62063
62095
|
" Shift"
|
|
@@ -62083,7 +62115,7 @@ var KPIDetailView = ({
|
|
|
62083
62115
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" })
|
|
62084
62116
|
] }),
|
|
62085
62117
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
62086
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
62118
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(chartMetrics.shift_id ?? 0) }),
|
|
62087
62119
|
/* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: [
|
|
62088
62120
|
getShiftName(chartMetrics.shift_id ?? 0).replace(/ Shift$/i, ""),
|
|
62089
62121
|
" Shift"
|
|
@@ -62101,7 +62133,7 @@ var KPIDetailView = ({
|
|
|
62101
62133
|
return `${startDate.toLocaleDateString("en-US", { month: "short", day: "numeric" })} - ${endDate.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })}`;
|
|
62102
62134
|
})() }) }),
|
|
62103
62135
|
/* @__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:
|
|
62136
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(selectedShiftId) }),
|
|
62105
62137
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: getShiftName(selectedShiftId) })
|
|
62106
62138
|
] })
|
|
62107
62139
|
] }),
|
|
@@ -62118,7 +62150,7 @@ var KPIDetailView = ({
|
|
|
62118
62150
|
] }),
|
|
62119
62151
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" }),
|
|
62120
62152
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
62121
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
62153
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(selectedShiftId) }),
|
|
62122
62154
|
/* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: [
|
|
62123
62155
|
getShiftName(selectedShiftId).replace(/ Shift$/i, ""),
|
|
62124
62156
|
" Shift"
|
|
@@ -63494,7 +63526,7 @@ var KPIsOverviewView = ({
|
|
|
63494
63526
|
const headerShiftId = showHistoricalLeaderboardHeader ? effectiveLeaderboardShiftId : currentShiftDetails.shiftId;
|
|
63495
63527
|
const headerShiftName = getShiftNameById(headerShiftId, configuredTimezone, shiftConfig).replace(/ Shift$/i, "");
|
|
63496
63528
|
const headerDateLabel = isMonthlyMode ? getMonthRange() : formatLocalDate2(headerDateKey);
|
|
63497
|
-
const
|
|
63529
|
+
const getShiftIcon2 = (shiftId) => {
|
|
63498
63530
|
const shiftNameLower = getShiftNameById(shiftId, configuredTimezone, shiftConfig).toLowerCase();
|
|
63499
63531
|
if (shiftNameLower.includes("day") || shiftNameLower.includes("morning") || shiftId === 0) {
|
|
63500
63532
|
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 +63643,7 @@ var KPIsOverviewView = ({
|
|
|
63611
63643
|
/* @__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
63644
|
!isMonthlyMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63613
63645
|
/* @__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:
|
|
63646
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(headerShiftId) }),
|
|
63615
63647
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: headerShiftName })
|
|
63616
63648
|
] }),
|
|
63617
63649
|
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 +63839,7 @@ var KPIsOverviewView = ({
|
|
|
63807
63839
|
!isMonthlyMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63808
63840
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" }),
|
|
63809
63841
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
63810
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
63842
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(headerShiftId) }),
|
|
63811
63843
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-semibold uppercase tracking-wider", children: [
|
|
63812
63844
|
headerShiftName,
|
|
63813
63845
|
" Shift"
|
|
@@ -63951,6 +63983,52 @@ var KPIsOverviewView = ({
|
|
|
63951
63983
|
] });
|
|
63952
63984
|
};
|
|
63953
63985
|
var KPIsOverviewView_default = KPIsOverviewView;
|
|
63986
|
+
var toFiniteNumber = (value) => {
|
|
63987
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
63988
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
63989
|
+
const parsed = Number(value);
|
|
63990
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
63991
|
+
}
|
|
63992
|
+
return null;
|
|
63993
|
+
};
|
|
63994
|
+
var getCycleRatio = (workspace) => {
|
|
63995
|
+
const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
|
|
63996
|
+
const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
|
|
63997
|
+
if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
|
|
63998
|
+
return null;
|
|
63999
|
+
}
|
|
64000
|
+
return idealCycleTime / avgCycleTime;
|
|
64001
|
+
};
|
|
64002
|
+
var formatCycleTimeValue = (value) => {
|
|
64003
|
+
const numericValue = toFiniteNumber(value);
|
|
64004
|
+
if (numericValue === null || numericValue <= 0) return "--";
|
|
64005
|
+
return `${numericValue.toFixed(1)}s`;
|
|
64006
|
+
};
|
|
64007
|
+
var CycleTimeComparison = memo$1(({
|
|
64008
|
+
workspace,
|
|
64009
|
+
variant = "table"
|
|
64010
|
+
}) => {
|
|
64011
|
+
const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
64012
|
+
const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
64013
|
+
if (variant === "mobile") {
|
|
64014
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center justify-between py-2 border-t border-gray-100", children: [
|
|
64015
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Standard Cycle Time" }),
|
|
64016
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums text-gray-500", children: standardValue })
|
|
64017
|
+
] });
|
|
64018
|
+
}
|
|
64019
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64020
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
64021
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Average" }),
|
|
64022
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums text-gray-900", children: averageValue })
|
|
64023
|
+
] }),
|
|
64024
|
+
/* @__PURE__ */ jsx("div", { className: "h-6 w-px bg-gray-200" }),
|
|
64025
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
64026
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Standard" }),
|
|
64027
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums text-gray-500", children: standardValue })
|
|
64028
|
+
] })
|
|
64029
|
+
] });
|
|
64030
|
+
}, (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);
|
|
64031
|
+
CycleTimeComparison.displayName = "CycleTimeComparison";
|
|
63954
64032
|
var IsolatedTimer = memo$1(() => {
|
|
63955
64033
|
return /* @__PURE__ */ jsx(ISTTimer_default, {});
|
|
63956
64034
|
});
|
|
@@ -63968,11 +64046,11 @@ var HeaderRibbon = memo$1(({
|
|
|
63968
64046
|
currentDate,
|
|
63969
64047
|
currentMobileDate,
|
|
63970
64048
|
shiftId,
|
|
63971
|
-
getShiftIcon,
|
|
64049
|
+
getShiftIcon: getShiftIcon2,
|
|
63972
64050
|
getShiftName,
|
|
63973
64051
|
showTimer = true
|
|
63974
64052
|
}) => {
|
|
63975
|
-
const shiftIcon = useMemo(() =>
|
|
64053
|
+
const shiftIcon = useMemo(() => getShiftIcon2(shiftId), [getShiftIcon2, shiftId]);
|
|
63976
64054
|
const shiftName = useMemo(() => getShiftName(shiftId), [getShiftName, shiftId]);
|
|
63977
64055
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63978
64056
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
|
|
@@ -64014,8 +64092,9 @@ var MobileWorkspaceCard = memo$1(({
|
|
|
64014
64092
|
isClickable,
|
|
64015
64093
|
onWorkspaceClick,
|
|
64016
64094
|
getMedalIcon,
|
|
64017
|
-
|
|
64018
|
-
|
|
64095
|
+
metricLabel,
|
|
64096
|
+
isAssemblyMode
|
|
64097
|
+
}) => /* @__PURE__ */ jsxs(
|
|
64019
64098
|
motion.div,
|
|
64020
64099
|
{
|
|
64021
64100
|
layout: true,
|
|
@@ -64026,28 +64105,31 @@ var MobileWorkspaceCard = memo$1(({
|
|
|
64026
64105
|
},
|
|
64027
64106
|
onClick: isClickable ? () => onWorkspaceClick(workspace, rank) : void 0,
|
|
64028
64107
|
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
|
-
|
|
64108
|
+
children: [
|
|
64109
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2 gap-3", children: [
|
|
64110
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64111
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
64112
|
+
/* @__PURE__ */ jsxs("div", { className: "text-2xl font-bold text-gray-700", children: [
|
|
64113
|
+
"#",
|
|
64114
|
+
rank
|
|
64115
|
+
] }),
|
|
64116
|
+
getMedalIcon(rank)
|
|
64035
64117
|
] }),
|
|
64036
|
-
|
|
64118
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
64119
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-900", children: workspace.displayName }),
|
|
64120
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: workspace.lineName })
|
|
64121
|
+
] })
|
|
64037
64122
|
] }),
|
|
64038
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
64039
|
-
/* @__PURE__ */ jsx("div", { className: "font-
|
|
64040
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children:
|
|
64123
|
+
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
64124
|
+
/* @__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 }) }),
|
|
64125
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: metricLabel })
|
|
64041
64126
|
] })
|
|
64042
64127
|
] }),
|
|
64043
|
-
/* @__PURE__ */
|
|
64044
|
-
|
|
64045
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: efficiencyLabel })
|
|
64046
|
-
] })
|
|
64047
|
-
] })
|
|
64128
|
+
isAssemblyMode && /* @__PURE__ */ jsx(CycleTimeComparison, { workspace, variant: "mobile" })
|
|
64129
|
+
]
|
|
64048
64130
|
}
|
|
64049
64131
|
), (prevProps, nextProps) => {
|
|
64050
|
-
return prevProps.
|
|
64132
|
+
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
64133
|
});
|
|
64052
64134
|
MobileWorkspaceCard.displayName = "MobileWorkspaceCard";
|
|
64053
64135
|
var DesktopWorkspaceRow = memo$1(({
|
|
@@ -64056,7 +64138,8 @@ var DesktopWorkspaceRow = memo$1(({
|
|
|
64056
64138
|
rowClass,
|
|
64057
64139
|
isClickable,
|
|
64058
64140
|
onWorkspaceClick,
|
|
64059
|
-
getMedalIcon
|
|
64141
|
+
getMedalIcon,
|
|
64142
|
+
isAssemblyMode
|
|
64060
64143
|
}) => /* @__PURE__ */ jsxs(
|
|
64061
64144
|
motion.tr,
|
|
64062
64145
|
{
|
|
@@ -64073,11 +64156,11 @@ var DesktopWorkspaceRow = memo$1(({
|
|
|
64073
64156
|
] }) }),
|
|
64074
64157
|
/* @__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
64158
|
/* @__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:
|
|
64159
|
+
/* @__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
64160
|
]
|
|
64078
64161
|
}
|
|
64079
64162
|
), (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;
|
|
64163
|
+
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
64164
|
});
|
|
64082
64165
|
DesktopWorkspaceRow.displayName = "DesktopWorkspaceRow";
|
|
64083
64166
|
var LeaderboardDetailView = memo$1(({
|
|
@@ -64099,6 +64182,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64099
64182
|
const supabase = useSupabase();
|
|
64100
64183
|
const [sortAscending, setSortAscending] = useState(false);
|
|
64101
64184
|
const [viewType, setViewType] = useState("operator");
|
|
64185
|
+
const [outputCategory, setOutputCategory] = useState("standard");
|
|
64102
64186
|
const [activeTab, setActiveTab] = useState("today");
|
|
64103
64187
|
const timezone = useAppTimezone();
|
|
64104
64188
|
const staticShiftConfig = useShiftConfig();
|
|
@@ -64177,6 +64261,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64177
64261
|
const monthlyRequestKeyRef = useRef(null);
|
|
64178
64262
|
const leaderboardUpdateQueuedRef = useRef(false);
|
|
64179
64263
|
const leaderboardUpdateTimerRef = useRef(null);
|
|
64264
|
+
const leaderboardViewTrackedRef = useRef(null);
|
|
64180
64265
|
const filterRef = useRef(null);
|
|
64181
64266
|
const filterButtonRef = useRef(null);
|
|
64182
64267
|
const mobileFilterButtonRef = useRef(null);
|
|
@@ -64309,6 +64394,17 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64309
64394
|
}
|
|
64310
64395
|
return Array.from(uniqueLines.entries()).map(([id3, name]) => ({ id: id3, label: name }));
|
|
64311
64396
|
}, [configuredLineIds, lines, getLineName]);
|
|
64397
|
+
const scopedLines = useMemo(() => {
|
|
64398
|
+
const configuredLineIdSet = new Set(configuredLineIds);
|
|
64399
|
+
return lines.filter((line) => configuredLineIds.length === 0 || configuredLineIdSet.has(line.id));
|
|
64400
|
+
}, [configuredLineIds, lines]);
|
|
64401
|
+
const scopedLineAssemblyMap = useMemo(() => {
|
|
64402
|
+
const map = /* @__PURE__ */ new Map();
|
|
64403
|
+
scopedLines.forEach((line) => {
|
|
64404
|
+
map.set(line.id, line.assembly === true);
|
|
64405
|
+
});
|
|
64406
|
+
return map;
|
|
64407
|
+
}, [scopedLines]);
|
|
64312
64408
|
const shiftOptions = useMemo(() => {
|
|
64313
64409
|
if (activeShiftConfig?.shifts && activeShiftConfig.shifts.length > 0) {
|
|
64314
64410
|
return activeShiftConfig.shifts.map((shift2) => ({
|
|
@@ -64332,6 +64428,33 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64332
64428
|
const parsed = Number(selectedShiftFilter);
|
|
64333
64429
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
64334
64430
|
}, [selectedShiftFilter]);
|
|
64431
|
+
const outputScopeLines = useMemo(() => {
|
|
64432
|
+
const outputLines = scopedLines.filter((line) => (line.monitoring_mode ?? "output") !== "uptime");
|
|
64433
|
+
if (selectedLineFilter === "all") {
|
|
64434
|
+
return outputLines;
|
|
64435
|
+
}
|
|
64436
|
+
return outputLines.filter((line) => line.id === selectedLineFilter);
|
|
64437
|
+
}, [scopedLines, selectedLineFilter]);
|
|
64438
|
+
const hasAssemblyOutputScope = useMemo(
|
|
64439
|
+
() => outputScopeLines.some((line) => line.assembly === true),
|
|
64440
|
+
[outputScopeLines]
|
|
64441
|
+
);
|
|
64442
|
+
const hasStandardOutputScope = useMemo(
|
|
64443
|
+
() => outputScopeLines.some((line) => line.assembly !== true),
|
|
64444
|
+
[outputScopeLines]
|
|
64445
|
+
);
|
|
64446
|
+
const showOutputCategoryDropdown = viewType === "operator" && hasAssemblyOutputScope && hasStandardOutputScope;
|
|
64447
|
+
const isAssemblyMode = viewType === "operator" && outputCategory === "assembly";
|
|
64448
|
+
useEffect(() => {
|
|
64449
|
+
if (viewType !== "operator") return;
|
|
64450
|
+
if (hasAssemblyOutputScope && !hasStandardOutputScope && outputCategory !== "assembly") {
|
|
64451
|
+
setOutputCategory("assembly");
|
|
64452
|
+
return;
|
|
64453
|
+
}
|
|
64454
|
+
if (hasStandardOutputScope && !hasAssemblyOutputScope && outputCategory !== "standard") {
|
|
64455
|
+
setOutputCategory("standard");
|
|
64456
|
+
}
|
|
64457
|
+
}, [viewType, hasAssemblyOutputScope, hasStandardOutputScope, outputCategory]);
|
|
64335
64458
|
const handleLineFilterChange = useCallback((value) => {
|
|
64336
64459
|
setSelectedLineFilter(value);
|
|
64337
64460
|
}, []);
|
|
@@ -64341,17 +64464,19 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64341
64464
|
const clearFilters = useCallback(() => {
|
|
64342
64465
|
setSortAscending(false);
|
|
64343
64466
|
setSelectedLineFilter("all");
|
|
64467
|
+
setOutputCategory("standard");
|
|
64344
64468
|
setSelectedShiftFilter(currentShiftInfo.shiftId.toString());
|
|
64345
64469
|
}, [currentShiftInfo.shiftId]);
|
|
64346
64470
|
const activeFiltersCount = useMemo(() => {
|
|
64347
64471
|
let count = 0;
|
|
64348
64472
|
if (sortAscending) count++;
|
|
64349
64473
|
if (selectedLineFilter !== "all") count++;
|
|
64474
|
+
if (showOutputCategoryDropdown && outputCategory !== "standard") count++;
|
|
64350
64475
|
if (selectedShiftFilter !== currentShiftInfo.shiftId.toString()) {
|
|
64351
64476
|
count++;
|
|
64352
64477
|
}
|
|
64353
64478
|
return count;
|
|
64354
|
-
}, [sortAscending, selectedLineFilter, selectedShiftFilter, currentShiftInfo.shiftId]);
|
|
64479
|
+
}, [sortAscending, selectedLineFilter, outputCategory, showOutputCategoryDropdown, selectedShiftFilter, currentShiftInfo.shiftId]);
|
|
64355
64480
|
const shouldFetchShiftConfigs = !date && shiftId === void 0;
|
|
64356
64481
|
const {
|
|
64357
64482
|
shiftConfigMap: multiLineShiftConfigMap,
|
|
@@ -64403,7 +64528,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64403
64528
|
action_count: entry.total_output || 0,
|
|
64404
64529
|
pph: entry.avg_pph || 0,
|
|
64405
64530
|
performance_score: entry.performance_score ?? 0,
|
|
64406
|
-
avg_cycle_time: entry.avg_cycle_time
|
|
64531
|
+
avg_cycle_time: toFiniteNumber(entry.avg_cycle_time) ?? 0,
|
|
64532
|
+
ideal_cycle_time: toFiniteNumber(entry.ideal_cycle_time) ?? void 0,
|
|
64407
64533
|
trend: 0,
|
|
64408
64534
|
predicted_output: 0,
|
|
64409
64535
|
efficiency: entry.efficiency || 0,
|
|
@@ -64581,7 +64707,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64581
64707
|
const currentShift = getCurrentShift(timezone || "Asia/Kolkata", activeShiftConfig);
|
|
64582
64708
|
return currentShift.shiftName || getShiftNameById(currentShift.shiftId, timezone || "Asia/Kolkata", activeShiftConfig);
|
|
64583
64709
|
}, [timezone, activeShiftConfig, shiftGroups]);
|
|
64584
|
-
const
|
|
64710
|
+
const getShiftIcon2 = useCallback((shiftId2) => {
|
|
64585
64711
|
if (shiftId2 === void 0 && shiftGroups.length > 1) {
|
|
64586
64712
|
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
64713
|
}
|
|
@@ -64647,15 +64773,20 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64647
64773
|
if (!canOpenWorkspace(workspace.line_id)) {
|
|
64648
64774
|
return;
|
|
64649
64775
|
}
|
|
64776
|
+
const cycleRatio = getCycleRatio(workspace);
|
|
64650
64777
|
trackCoreEvent("Workspace from Leaderboard Clicked", {
|
|
64651
64778
|
workspace_name: workspace.workspace_name,
|
|
64652
64779
|
workspace_id: workspace.workspace_uuid,
|
|
64653
64780
|
rank,
|
|
64654
64781
|
total_workspaces: workspacesLengthRef.current,
|
|
64655
64782
|
// Use ref instead of state to avoid dependency
|
|
64783
|
+
metric_context: viewType === "machine" ? "machine" : outputCategory,
|
|
64656
64784
|
efficiency: workspace.efficiency,
|
|
64657
64785
|
action_count: workspace.action_count,
|
|
64658
|
-
action_threshold: workspace.action_threshold
|
|
64786
|
+
action_threshold: workspace.action_threshold,
|
|
64787
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
64788
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null,
|
|
64789
|
+
cycle_ratio: cycleRatio
|
|
64659
64790
|
});
|
|
64660
64791
|
const displayName = workspace.displayName || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
64661
64792
|
const navParams = workspace.workspace_uuid ? getWorkspaceNavigationParams(workspace.workspace_uuid, displayName, workspace.line_id) : "";
|
|
@@ -64679,7 +64810,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64679
64810
|
const combinedParams = navParams ? `${navParams}&${contextParamString}` : `?${contextParamString}`;
|
|
64680
64811
|
navigation.navigate(`/workspace/${workspace.workspace_uuid}${combinedParams}`);
|
|
64681
64812
|
}
|
|
64682
|
-
}, [canOpenWorkspace, onWorkspaceClick, navigation, date, shiftId]);
|
|
64813
|
+
}, [canOpenWorkspace, onWorkspaceClick, navigation, date, shiftId, outputCategory, viewType]);
|
|
64683
64814
|
useEffect(() => {
|
|
64684
64815
|
workspacesLengthRef.current = activeEntries.length || 0;
|
|
64685
64816
|
}, [activeEntries.length]);
|
|
@@ -64700,16 +64831,20 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64700
64831
|
return activeEntries.map((ws) => ({
|
|
64701
64832
|
...ws,
|
|
64702
64833
|
displayName: ws.displayName || getWorkspaceDisplayName(ws.workspace_name, ws.line_id),
|
|
64703
|
-
lineName: getLineName(ws.line_id)
|
|
64834
|
+
lineName: getLineName(ws.line_id),
|
|
64835
|
+
isAssemblyLine: scopedLineAssemblyMap.get(ws.line_id) === true
|
|
64704
64836
|
}));
|
|
64705
|
-
}, [activeEntries, getLineName]);
|
|
64837
|
+
}, [activeEntries, getLineName, scopedLineAssemblyMap]);
|
|
64706
64838
|
const sortedWorkspaces = useMemo(() => {
|
|
64707
64839
|
let filtered = [...workspaceDisplayData];
|
|
64708
64840
|
filtered = filtered.filter((ws) => {
|
|
64709
64841
|
if (viewType === "machine") {
|
|
64710
64842
|
return ws.monitoring_mode === "uptime";
|
|
64711
64843
|
}
|
|
64712
|
-
|
|
64844
|
+
if (ws.monitoring_mode === "uptime") {
|
|
64845
|
+
return false;
|
|
64846
|
+
}
|
|
64847
|
+
return isAssemblyMode ? ws.isAssemblyLine : !ws.isAssemblyLine;
|
|
64713
64848
|
});
|
|
64714
64849
|
if (selectedLineFilter !== "all") {
|
|
64715
64850
|
filtered = filtered.filter((ws) => ws.line_id === selectedLineFilter);
|
|
@@ -64718,13 +64853,61 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64718
64853
|
filtered = filtered.filter((ws) => ws.shift_id?.toString() === selectedShiftFilter);
|
|
64719
64854
|
}
|
|
64720
64855
|
return filtered.sort((a, b) => {
|
|
64856
|
+
if (isAssemblyMode) {
|
|
64857
|
+
const ratioA = getCycleRatio(a);
|
|
64858
|
+
const ratioB = getCycleRatio(b);
|
|
64859
|
+
if (ratioA === null && ratioB === null) return 0;
|
|
64860
|
+
if (ratioA === null) return 1;
|
|
64861
|
+
if (ratioB === null) return -1;
|
|
64862
|
+
return sortAscending ? ratioA - ratioB : ratioB - ratioA;
|
|
64863
|
+
}
|
|
64721
64864
|
const effA = a.efficiency || 0;
|
|
64722
64865
|
const effB = b.efficiency || 0;
|
|
64723
64866
|
return sortAscending ? effA - effB : effB - effA;
|
|
64724
64867
|
});
|
|
64725
|
-
}, [workspaceDisplayData, sortAscending, selectedLineFilter, selectedShiftFilter, activeTab, viewType]);
|
|
64868
|
+
}, [workspaceDisplayData, sortAscending, selectedLineFilter, selectedShiftFilter, activeTab, viewType, isAssemblyMode]);
|
|
64726
64869
|
const loading = activeTab === "today" ? todayLoading : monthlyLoading;
|
|
64727
64870
|
const error = activeTab === "today" ? todayError : monthlyError;
|
|
64871
|
+
useEffect(() => {
|
|
64872
|
+
if (loading || error || sortedWorkspaces.length === 0) return;
|
|
64873
|
+
const trackingKey = [
|
|
64874
|
+
activeTab,
|
|
64875
|
+
viewType,
|
|
64876
|
+
outputCategory,
|
|
64877
|
+
selectedLineFilter,
|
|
64878
|
+
selectedShiftFilter,
|
|
64879
|
+
sortAscending ? "asc" : "desc",
|
|
64880
|
+
sortedWorkspaces.length
|
|
64881
|
+
].join("|");
|
|
64882
|
+
if (leaderboardViewTrackedRef.current === trackingKey) return;
|
|
64883
|
+
leaderboardViewTrackedRef.current = trackingKey;
|
|
64884
|
+
const topWorkspace = sortedWorkspaces[0];
|
|
64885
|
+
trackCoreEvent("Workspace Leaderboard View Loaded", {
|
|
64886
|
+
time_range: activeTab,
|
|
64887
|
+
view_type: viewType,
|
|
64888
|
+
metric_context: viewType === "machine" ? "machine" : outputCategory,
|
|
64889
|
+
line_filter: selectedLineFilter,
|
|
64890
|
+
shift_filter: selectedShiftFilter,
|
|
64891
|
+
sort_direction: sortAscending ? "asc" : "desc",
|
|
64892
|
+
workspace_count: sortedWorkspaces.length,
|
|
64893
|
+
top_workspace_id: topWorkspace?.workspace_uuid ?? null,
|
|
64894
|
+
top_workspace_name: topWorkspace?.workspace_name ?? null,
|
|
64895
|
+
top_efficiency: topWorkspace?.efficiency ?? null,
|
|
64896
|
+
top_avg_cycle_time: topWorkspace?.avg_cycle_time ?? null,
|
|
64897
|
+
top_ideal_cycle_time: topWorkspace?.ideal_cycle_time ?? null,
|
|
64898
|
+
top_cycle_ratio: topWorkspace ? getCycleRatio(topWorkspace) : null
|
|
64899
|
+
});
|
|
64900
|
+
}, [
|
|
64901
|
+
loading,
|
|
64902
|
+
error,
|
|
64903
|
+
sortedWorkspaces,
|
|
64904
|
+
activeTab,
|
|
64905
|
+
viewType,
|
|
64906
|
+
outputCategory,
|
|
64907
|
+
selectedLineFilter,
|
|
64908
|
+
selectedShiftFilter,
|
|
64909
|
+
sortAscending
|
|
64910
|
+
]);
|
|
64728
64911
|
const currentDateFormatted = useMemo(() => {
|
|
64729
64912
|
const dateStr = (/* @__PURE__ */ new Date()).toDateString();
|
|
64730
64913
|
return formatDate2(new Date(dateStr));
|
|
@@ -64742,7 +64925,9 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64742
64925
|
error.message
|
|
64743
64926
|
] }) });
|
|
64744
64927
|
}
|
|
64745
|
-
const
|
|
64928
|
+
const metricLabel = viewType === "machine" ? "Utilization" : isAssemblyMode ? "Cycle Time" : "Efficiency";
|
|
64929
|
+
const descendingSortLabel = "Highest to Lowest";
|
|
64930
|
+
const ascendingSortLabel = "Lowest to Highest";
|
|
64746
64931
|
return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 flex flex-col ${className}`, style: { willChange: "contents" }, children: [
|
|
64747
64932
|
/* @__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
64933
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
@@ -64792,7 +64977,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64792
64977
|
] }),
|
|
64793
64978
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
64794
64979
|
/* @__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:
|
|
64980
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: metricLabel }),
|
|
64796
64981
|
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
64797
64982
|
"select",
|
|
64798
64983
|
{
|
|
@@ -64801,8 +64986,25 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64801
64986
|
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
64987
|
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
64988
|
children: [
|
|
64804
|
-
/* @__PURE__ */ jsx("option", { value: "desc", children:
|
|
64805
|
-
/* @__PURE__ */ jsx("option", { value: "asc", children:
|
|
64989
|
+
/* @__PURE__ */ jsx("option", { value: "desc", children: descendingSortLabel }),
|
|
64990
|
+
/* @__PURE__ */ jsx("option", { value: "asc", children: ascendingSortLabel })
|
|
64991
|
+
]
|
|
64992
|
+
}
|
|
64993
|
+
) })
|
|
64994
|
+
] }),
|
|
64995
|
+
showOutputCategoryDropdown && /* @__PURE__ */ jsxs("div", { className: "space-y-1 sm:hidden", children: [
|
|
64996
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Output Type" }),
|
|
64997
|
+
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
64998
|
+
"select",
|
|
64999
|
+
{
|
|
65000
|
+
"aria-label": "Output leaderboard category",
|
|
65001
|
+
value: outputCategory,
|
|
65002
|
+
onChange: (e) => setOutputCategory(e.target.value),
|
|
65003
|
+
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",
|
|
65004
|
+
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` },
|
|
65005
|
+
children: [
|
|
65006
|
+
/* @__PURE__ */ jsx("option", { value: "standard", children: "Standard" }),
|
|
65007
|
+
/* @__PURE__ */ jsx("option", { value: "assembly", children: "Assembly" })
|
|
64806
65008
|
]
|
|
64807
65009
|
}
|
|
64808
65010
|
) })
|
|
@@ -64844,7 +65046,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64844
65046
|
currentDate: activeTab === "monthly" ? monthlyRangeText : currentDateFormatted,
|
|
64845
65047
|
currentMobileDate: activeTab === "monthly" ? monthlyRangeText : currentMobileDateFormatted,
|
|
64846
65048
|
shiftId: activeTab === "monthly" ? monthlyShiftId : todayShiftId,
|
|
64847
|
-
getShiftIcon,
|
|
65049
|
+
getShiftIcon: getShiftIcon2,
|
|
64848
65050
|
getShiftName,
|
|
64849
65051
|
showTimer: activeTab === "today"
|
|
64850
65052
|
}
|
|
@@ -64942,6 +65144,20 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64942
65144
|
]
|
|
64943
65145
|
}
|
|
64944
65146
|
) }),
|
|
65147
|
+
showOutputCategoryDropdown && /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
65148
|
+
"select",
|
|
65149
|
+
{
|
|
65150
|
+
"aria-label": "Output leaderboard category",
|
|
65151
|
+
value: outputCategory,
|
|
65152
|
+
onChange: (e) => setOutputCategory(e.target.value),
|
|
65153
|
+
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",
|
|
65154
|
+
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` },
|
|
65155
|
+
children: [
|
|
65156
|
+
/* @__PURE__ */ jsx("option", { value: "standard", children: "Standard" }),
|
|
65157
|
+
/* @__PURE__ */ jsx("option", { value: "assembly", children: "Assembly" })
|
|
65158
|
+
]
|
|
65159
|
+
}
|
|
65160
|
+
) }),
|
|
64945
65161
|
/* @__PURE__ */ jsxs(
|
|
64946
65162
|
"button",
|
|
64947
65163
|
{
|
|
@@ -64973,7 +65189,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64973
65189
|
isClickable: canOpenWorkspace(ws.line_id),
|
|
64974
65190
|
onWorkspaceClick: stableHandleWorkspaceClick,
|
|
64975
65191
|
getMedalIcon: stableGetMedalIcon,
|
|
64976
|
-
|
|
65192
|
+
metricLabel,
|
|
65193
|
+
isAssemblyMode
|
|
64977
65194
|
},
|
|
64978
65195
|
ws.workspace_uuid
|
|
64979
65196
|
);
|
|
@@ -64984,7 +65201,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64984
65201
|
/* @__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
65202
|
/* @__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
65203
|
/* @__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:
|
|
65204
|
+
/* @__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
65205
|
] }) }),
|
|
64989
65206
|
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-100", children: sortedWorkspaces.map((ws, index) => {
|
|
64990
65207
|
const isTopThree = index < 3;
|
|
@@ -64997,7 +65214,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64997
65214
|
rowClass,
|
|
64998
65215
|
isClickable: canOpenWorkspace(ws.line_id),
|
|
64999
65216
|
onWorkspaceClick: stableHandleWorkspaceClick,
|
|
65000
|
-
getMedalIcon: stableGetMedalIcon
|
|
65217
|
+
getMedalIcon: stableGetMedalIcon,
|
|
65218
|
+
isAssemblyMode
|
|
65001
65219
|
},
|
|
65002
65220
|
ws.workspace_uuid
|
|
65003
65221
|
);
|
|
@@ -65015,7 +65233,10 @@ function LoginView({
|
|
|
65015
65233
|
logoSrc = optifye_logo_default,
|
|
65016
65234
|
logoAlt = "Optifye",
|
|
65017
65235
|
brandName = "Optifye",
|
|
65018
|
-
onRateLimitCheck
|
|
65236
|
+
onRateLimitCheck,
|
|
65237
|
+
showDevTestLogin = false,
|
|
65238
|
+
devTestLoginLabel,
|
|
65239
|
+
onDevTestLogin
|
|
65019
65240
|
}) {
|
|
65020
65241
|
return /* @__PURE__ */ jsx(
|
|
65021
65242
|
LoginPage,
|
|
@@ -65023,7 +65244,10 @@ function LoginView({
|
|
|
65023
65244
|
logoSrc,
|
|
65024
65245
|
logoAlt,
|
|
65025
65246
|
brandName,
|
|
65026
|
-
onRateLimitCheck
|
|
65247
|
+
onRateLimitCheck,
|
|
65248
|
+
showDevTestLogin,
|
|
65249
|
+
devTestLoginLabel,
|
|
65250
|
+
onDevTestLogin
|
|
65027
65251
|
}
|
|
65028
65252
|
);
|
|
65029
65253
|
}
|
|
@@ -68211,20 +68435,30 @@ function useTimezone(options = {}) {
|
|
|
68211
68435
|
}
|
|
68212
68436
|
|
|
68213
68437
|
// src/views/workspace-detail-view.utils.ts
|
|
68214
|
-
var
|
|
68438
|
+
var getWorkspaceDetailLayoutMode = ({
|
|
68215
68439
|
workspace,
|
|
68216
68440
|
showCycleTimeChart
|
|
68217
68441
|
}) => {
|
|
68218
68442
|
if (workspace?.monitoring_mode === "uptime") {
|
|
68219
|
-
return "
|
|
68443
|
+
return "uptime";
|
|
68220
68444
|
}
|
|
68221
68445
|
if (showCycleTimeChart === false) {
|
|
68222
68446
|
return "output";
|
|
68223
68447
|
}
|
|
68224
|
-
|
|
68448
|
+
return shouldUseAssemblyCycleTimeLayout(workspace) ? "assembly_cycle" : "output";
|
|
68449
|
+
};
|
|
68450
|
+
var getCycleTimeRenderState = ({
|
|
68451
|
+
workspace,
|
|
68452
|
+
authoritativeMetrics,
|
|
68453
|
+
showCycleTimeChart
|
|
68454
|
+
}) => {
|
|
68455
|
+
if (getWorkspaceDetailLayoutMode({ workspace, showCycleTimeChart }) !== "assembly_cycle") {
|
|
68225
68456
|
return "output";
|
|
68226
68457
|
}
|
|
68227
|
-
|
|
68458
|
+
if (!authoritativeMetrics) {
|
|
68459
|
+
return "chart_loading";
|
|
68460
|
+
}
|
|
68461
|
+
return authoritativeMetrics.cycle_time_data_status === "missing_clips" ? "cycle_unavailable" : "cycle_chart";
|
|
68228
68462
|
};
|
|
68229
68463
|
var formatDateInTimezone = (date = /* @__PURE__ */ new Date(), timezone, options) => {
|
|
68230
68464
|
const defaultOptions = {
|
|
@@ -68632,33 +68866,34 @@ var WorkspaceDetailView = ({
|
|
|
68632
68866
|
idle_time_hourly: void 0
|
|
68633
68867
|
};
|
|
68634
68868
|
}, [cachedOverviewMetrics, shiftConfig?.shifts]);
|
|
68635
|
-
const
|
|
68869
|
+
const authoritativeCycleMetrics = isHistoricView ? historicMetrics : liveMetrics;
|
|
68870
|
+
const workspace = authoritativeCycleMetrics || cachedDetailedMetrics || overviewFallback;
|
|
68636
68871
|
const { timezone: cycleTimeTimezone } = useTimezone({
|
|
68637
68872
|
lineId: effectiveLineId || workspace?.line_id || void 0,
|
|
68638
68873
|
workspaceId: workspaceId || void 0
|
|
68639
68874
|
});
|
|
68640
68875
|
const effectiveCycleTimeTimezone = cycleTimeTimezone || timezone;
|
|
68641
|
-
const detailedWorkspaceMetrics =
|
|
68876
|
+
const detailedWorkspaceMetrics = authoritativeCycleMetrics || cachedDetailedMetrics;
|
|
68642
68877
|
const cycleTimeChartData = useMemo(
|
|
68643
|
-
() => Array.isArray(
|
|
68878
|
+
() => Array.isArray(authoritativeCycleMetrics?.hourly_cycle_times) ? authoritativeCycleMetrics.hourly_cycle_times.map((value) => {
|
|
68644
68879
|
const numericValue = Number(value);
|
|
68645
68880
|
return Number.isFinite(numericValue) ? numericValue : 0;
|
|
68646
68881
|
}) : [],
|
|
68647
|
-
[
|
|
68882
|
+
[authoritativeCycleMetrics?.hourly_cycle_times]
|
|
68648
68883
|
);
|
|
68649
68884
|
const maskedCycleTimeChartData = useMemo(
|
|
68650
68885
|
() => maskFutureHourlySeries({
|
|
68651
68886
|
data: cycleTimeChartData,
|
|
68652
|
-
shiftStart:
|
|
68653
|
-
shiftEnd:
|
|
68654
|
-
shiftDate:
|
|
68887
|
+
shiftStart: authoritativeCycleMetrics?.shift_start,
|
|
68888
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end,
|
|
68889
|
+
shiftDate: authoritativeCycleMetrics?.date || date || calculatedOperationalDate || null,
|
|
68655
68890
|
timezone: effectiveCycleTimeTimezone
|
|
68656
68891
|
}),
|
|
68657
68892
|
[
|
|
68658
68893
|
cycleTimeChartData,
|
|
68659
|
-
|
|
68660
|
-
|
|
68661
|
-
|
|
68894
|
+
authoritativeCycleMetrics?.shift_start,
|
|
68895
|
+
authoritativeCycleMetrics?.shift_end,
|
|
68896
|
+
authoritativeCycleMetrics?.date,
|
|
68662
68897
|
date,
|
|
68663
68898
|
calculatedOperationalDate,
|
|
68664
68899
|
effectiveCycleTimeTimezone
|
|
@@ -68666,13 +68901,13 @@ var WorkspaceDetailView = ({
|
|
|
68666
68901
|
);
|
|
68667
68902
|
const cycleTimeDatasetKey = useMemo(
|
|
68668
68903
|
() => [
|
|
68669
|
-
|
|
68670
|
-
date ||
|
|
68671
|
-
parsedShiftId ??
|
|
68904
|
+
authoritativeCycleMetrics?.workspace_id || workspaceId || "workspace",
|
|
68905
|
+
date || authoritativeCycleMetrics?.date || "live",
|
|
68906
|
+
parsedShiftId ?? authoritativeCycleMetrics?.shift_id ?? "current",
|
|
68672
68907
|
"hourly",
|
|
68673
68908
|
"backend"
|
|
68674
68909
|
].join(":"),
|
|
68675
|
-
[
|
|
68910
|
+
[authoritativeCycleMetrics?.workspace_id, workspaceId, date, authoritativeCycleMetrics?.date, parsedShiftId, authoritativeCycleMetrics?.shift_id]
|
|
68676
68911
|
);
|
|
68677
68912
|
const hasWorkspaceSnapshot = Boolean(workspace);
|
|
68678
68913
|
const loading = ((isHistoricView ? historicLoading : liveLoading) || isShiftConfigLoading) && !hasWorkspaceSnapshot;
|
|
@@ -68921,30 +69156,46 @@ var WorkspaceDetailView = ({
|
|
|
68921
69156
|
action_type: workspace.action_type
|
|
68922
69157
|
} : null;
|
|
68923
69158
|
const isAssemblyWorkspace = shouldUseAssemblyCycleTimeLayout(workspaceCycleTimeEligibility);
|
|
68924
|
-
const
|
|
69159
|
+
const layoutMode = getWorkspaceDetailLayoutMode({
|
|
68925
69160
|
workspace: workspace ? {
|
|
68926
69161
|
monitoring_mode: workspace.monitoring_mode,
|
|
68927
69162
|
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
68928
69163
|
action_family: workspace.action_family,
|
|
68929
|
-
action_type: workspace.action_type
|
|
68930
|
-
cycle_time_data_status: workspace.cycle_time_data_status
|
|
69164
|
+
action_type: workspace.action_type
|
|
68931
69165
|
} : null,
|
|
68932
69166
|
showCycleTimeChart
|
|
68933
69167
|
});
|
|
68934
|
-
const
|
|
69168
|
+
const isAssemblyCycleLayout = layoutMode === "assembly_cycle";
|
|
69169
|
+
const isOutputLayout = layoutMode === "output";
|
|
69170
|
+
const cycleTimePresentation = getCycleTimeRenderState({
|
|
69171
|
+
workspace: workspace ? {
|
|
69172
|
+
monitoring_mode: workspace.monitoring_mode,
|
|
69173
|
+
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
69174
|
+
action_family: workspace.action_family,
|
|
69175
|
+
action_type: workspace.action_type
|
|
69176
|
+
} : null,
|
|
69177
|
+
authoritativeMetrics: authoritativeCycleMetrics ? {
|
|
69178
|
+
cycle_time_data_status: authoritativeCycleMetrics.cycle_time_data_status
|
|
69179
|
+
} : null,
|
|
69180
|
+
showCycleTimeChart
|
|
69181
|
+
});
|
|
69182
|
+
const shouldShowCycleTimeChart = cycleTimePresentation === "cycle_chart";
|
|
68935
69183
|
const shouldShowCycleTimeUnavailableState = cycleTimePresentation === "cycle_unavailable";
|
|
68936
|
-
const
|
|
69184
|
+
const shouldShowCycleTimeLoadingState = cycleTimePresentation === "chart_loading";
|
|
69185
|
+
const shouldShowAssemblyOverviewLoadingState = isAssemblyCycleLayout && shouldShowCycleTimeLoadingState && hasWorkspaceSnapshot;
|
|
69186
|
+
const showIdleBreakdownChart = !isAssemblyCycleLayout && idleTimeVlmEnabled;
|
|
69187
|
+
const canToggleChartIdleTime = !isUptimeMode && !shouldShowCycleTimeLoadingState && !shouldShowCycleTimeUnavailableState;
|
|
68937
69188
|
const idleClipDate = date || workspace?.date || calculatedOperationalDate || getOperationalDate(timezone);
|
|
68938
69189
|
const idleClipShiftId = parsedShiftId ?? workspace?.shift_id;
|
|
68939
69190
|
const rawHourlyIdleMinutes = useMemo(() => {
|
|
68940
69191
|
if (!shouldShowCycleTimeChart || !workspace?.idle_time_hourly || !workspace?.shift_start) return [];
|
|
68941
|
-
const
|
|
69192
|
+
const parseTimeToMinutes4 = (time2) => {
|
|
68942
69193
|
const [h, m] = time2.split(":").map(Number);
|
|
68943
69194
|
if (!Number.isFinite(h) || !Number.isFinite(m)) return 0;
|
|
68944
69195
|
return h * 60 + m;
|
|
68945
69196
|
};
|
|
68946
|
-
const startTotal =
|
|
68947
|
-
const endTotalRaw = workspace.shift_end ?
|
|
69197
|
+
const startTotal = parseTimeToMinutes4(workspace.shift_start);
|
|
69198
|
+
const endTotalRaw = workspace.shift_end ? parseTimeToMinutes4(workspace.shift_end) : startTotal + 11 * 60;
|
|
68948
69199
|
const endTotal = endTotalRaw <= startTotal ? endTotalRaw + 24 * 60 : endTotalRaw;
|
|
68949
69200
|
const shiftDuration = Math.max(60, endTotal - startTotal);
|
|
68950
69201
|
const totalHourSlots = Math.max(1, Math.ceil(shiftDuration / 60));
|
|
@@ -68994,6 +69245,18 @@ var WorkspaceDetailView = ({
|
|
|
68994
69245
|
workspace.cycle_completion_clip_count
|
|
68995
69246
|
] })
|
|
68996
69247
|
] }), [workspace?.cycle_completion_clip_count]);
|
|
69248
|
+
const assemblyOverviewLoadingView = useMemo(() => /* @__PURE__ */ jsxs("div", { className: "space-y-4 pb-4", "data-testid": "assembly-overview-loading-state", children: [
|
|
69249
|
+
/* @__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: [
|
|
69250
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 bg-gray-200 rounded-full w-3/4 mx-auto" }),
|
|
69251
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 bg-gray-100 rounded-full w-full" }),
|
|
69252
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 bg-gray-100 rounded-full w-5/6 mx-auto" })
|
|
69253
|
+
] }) }) }),
|
|
69254
|
+
/* @__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: [
|
|
69255
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-24 bg-gray-200 rounded" }),
|
|
69256
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 w-20 bg-gray-100 rounded" }),
|
|
69257
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 w-28 bg-gray-100 rounded" })
|
|
69258
|
+
] }) }, index)) })
|
|
69259
|
+
] }), []);
|
|
68997
69260
|
const shiftDurationMinutes = useMemo(
|
|
68998
69261
|
() => getShiftDurationMinutes(workspace?.shift_start, workspace?.shift_end),
|
|
68999
69262
|
[workspace?.shift_start, workspace?.shift_end]
|
|
@@ -69048,7 +69311,7 @@ var WorkspaceDetailView = ({
|
|
|
69048
69311
|
}, [isUptimeMode, uptimeSeries, shiftDurationMinutes, elapsedShiftMinutes, workspace?.idle_time]);
|
|
69049
69312
|
const overviewTabLabel = isUptimeMode ? "Utilization" : "Efficiency";
|
|
69050
69313
|
const idleClipFetchEnabled = Boolean(
|
|
69051
|
-
workspaceId && idleClipDate && idleClipShiftId !== void 0 && activeTab === "overview" && idleTimeVlmEnabled &&
|
|
69314
|
+
workspaceId && idleClipDate && idleClipShiftId !== void 0 && activeTab === "overview" && idleTimeVlmEnabled && isOutputLayout
|
|
69052
69315
|
);
|
|
69053
69316
|
const {
|
|
69054
69317
|
idleClips: idleTimeClips,
|
|
@@ -69119,7 +69382,7 @@ var WorkspaceDetailView = ({
|
|
|
69119
69382
|
}
|
|
69120
69383
|
}
|
|
69121
69384
|
};
|
|
69122
|
-
const
|
|
69385
|
+
const getShiftIcon2 = (shiftType) => {
|
|
69123
69386
|
const shiftTypeLower = shiftType?.toLowerCase() || "";
|
|
69124
69387
|
if (shiftTypeLower.includes("day") || shiftTypeLower.includes("morning")) {
|
|
69125
69388
|
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 +69531,7 @@ var WorkspaceDetailView = ({
|
|
|
69268
69531
|
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: (() => {
|
|
69269
69532
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
69270
69533
|
const shiftName = shift2?.shiftName || (selectedShift === 0 ? "Day Shift" : "Night Shift");
|
|
69271
|
-
return
|
|
69534
|
+
return getShiftIcon2(shiftName);
|
|
69272
69535
|
})() }),
|
|
69273
69536
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: (() => {
|
|
69274
69537
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
@@ -69296,7 +69559,7 @@ var WorkspaceDetailView = ({
|
|
|
69296
69559
|
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: (() => {
|
|
69297
69560
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
69298
69561
|
const shiftName = shift2?.shiftName || (selectedShift === 0 ? "Day Shift" : "Night Shift");
|
|
69299
|
-
return
|
|
69562
|
+
return getShiftIcon2(shiftName);
|
|
69300
69563
|
})() }),
|
|
69301
69564
|
/* @__PURE__ */ jsx("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: (() => {
|
|
69302
69565
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
@@ -69309,7 +69572,7 @@ var WorkspaceDetailView = ({
|
|
|
69309
69572
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
|
|
69310
69573
|
/* @__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
69574
|
/* @__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:
|
|
69575
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(workspace.shift_type) }),
|
|
69313
69576
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: workspace.shift_type })
|
|
69314
69577
|
] }),
|
|
69315
69578
|
!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 +69603,7 @@ var WorkspaceDetailView = ({
|
|
|
69340
69603
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" })
|
|
69341
69604
|
] }),
|
|
69342
69605
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
69343
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
69606
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(workspace.shift_type) }),
|
|
69344
69607
|
/* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: [
|
|
69345
69608
|
workspace.shift_type.replace(/ Shift$/i, ""),
|
|
69346
69609
|
" Shift"
|
|
@@ -69459,9 +69722,9 @@ var WorkspaceDetailView = ({
|
|
|
69459
69722
|
] })
|
|
69460
69723
|
] }),
|
|
69461
69724
|
/* @__PURE__ */ jsxs("div", { className: "flex-grow p-1.5 sm:p-2 lg:p-4", children: [
|
|
69462
|
-
activeTab === "overview" && /* @__PURE__ */
|
|
69725
|
+
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
69726
|
/* @__PURE__ */ jsxs("div", { className: "block lg:hidden space-y-6 pb-6", children: [
|
|
69464
|
-
|
|
69727
|
+
isOutputLayout && !isUptimeMode && /* @__PURE__ */ jsxs(
|
|
69465
69728
|
motion.div,
|
|
69466
69729
|
{
|
|
69467
69730
|
className: "bg-white rounded-lg shadow-sm p-6 h-[300px]",
|
|
@@ -69489,8 +69752,8 @@ var WorkspaceDetailView = ({
|
|
|
69489
69752
|
animate: "animate",
|
|
69490
69753
|
children: [
|
|
69491
69754
|
/* @__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
|
-
|
|
69755
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : isAssemblyCycleLayout ? "Cycle time trend" : "Hourly Output" }),
|
|
69756
|
+
canToggleChartIdleTime && /* @__PURE__ */ jsx(
|
|
69494
69757
|
"button",
|
|
69495
69758
|
{
|
|
69496
69759
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69519,19 +69782,19 @@ var WorkspaceDetailView = ({
|
|
|
69519
69782
|
timezone,
|
|
69520
69783
|
elapsedMinutes: elapsedShiftMinutes
|
|
69521
69784
|
}
|
|
69522
|
-
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69785
|
+
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69523
69786
|
CycleTimeOverTimeChart,
|
|
69524
69787
|
{
|
|
69525
69788
|
data: maskedCycleTimeChartData,
|
|
69526
|
-
idealCycleTime:
|
|
69527
|
-
shiftStart:
|
|
69528
|
-
shiftEnd:
|
|
69789
|
+
idealCycleTime: authoritativeCycleMetrics?.ideal_cycle_time || 0,
|
|
69790
|
+
shiftStart: authoritativeCycleMetrics?.shift_start || "",
|
|
69791
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end || "",
|
|
69529
69792
|
xAxisMode: "hourly",
|
|
69530
69793
|
datasetKey: cycleTimeDatasetKey,
|
|
69531
69794
|
showIdleTime: showChartIdleTime,
|
|
69532
69795
|
idleTimeData: hourlyIdleMinutes
|
|
69533
69796
|
}
|
|
69534
|
-
) : /* @__PURE__ */ jsx(
|
|
69797
|
+
) : null : /* @__PURE__ */ jsx(
|
|
69535
69798
|
HourlyOutputChart2,
|
|
69536
69799
|
{
|
|
69537
69800
|
data: workspace.hourly_action_counts || [],
|
|
@@ -69551,7 +69814,7 @@ var WorkspaceDetailView = ({
|
|
|
69551
69814
|
]
|
|
69552
69815
|
}
|
|
69553
69816
|
),
|
|
69554
|
-
|
|
69817
|
+
showIdleBreakdownChart && /* @__PURE__ */ jsxs(
|
|
69555
69818
|
motion.div,
|
|
69556
69819
|
{
|
|
69557
69820
|
className: "bg-white rounded-lg shadow-sm p-4 h-[300px]",
|
|
@@ -69571,7 +69834,7 @@ var WorkspaceDetailView = ({
|
|
|
69571
69834
|
]
|
|
69572
69835
|
}
|
|
69573
69836
|
),
|
|
69574
|
-
isUptimeMode ? /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData }) :
|
|
69837
|
+
isUptimeMode ? /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData }) : isAssemblyCycleLayout ? /* @__PURE__ */ jsx(
|
|
69575
69838
|
WorkspaceCycleTimeMetricCards,
|
|
69576
69839
|
{
|
|
69577
69840
|
workspace,
|
|
@@ -69591,7 +69854,7 @@ var WorkspaceDetailView = ({
|
|
|
69591
69854
|
desktopTopSectionClass
|
|
69592
69855
|
),
|
|
69593
69856
|
children: [
|
|
69594
|
-
|
|
69857
|
+
isOutputLayout && !isUptimeMode && /* @__PURE__ */ jsxs(
|
|
69595
69858
|
motion.div,
|
|
69596
69859
|
{
|
|
69597
69860
|
className: "bg-white rounded-lg shadow-sm p-4 lg:col-span-2 flex flex-col min-h-0",
|
|
@@ -69615,15 +69878,15 @@ var WorkspaceDetailView = ({
|
|
|
69615
69878
|
{
|
|
69616
69879
|
className: clsx(
|
|
69617
69880
|
"bg-white rounded-lg shadow-sm p-4 flex flex-col min-h-0",
|
|
69618
|
-
isUptimeMode && showIdleBreakdownChart ? "lg:col-span-2" :
|
|
69881
|
+
isUptimeMode && showIdleBreakdownChart ? "lg:col-span-2" : isAssemblyCycleLayout || isUptimeMode ? "lg:col-span-10" : idleTimeVlmEnabled ? "lg:col-span-6" : "lg:col-span-8"
|
|
69619
69882
|
),
|
|
69620
69883
|
variants: chartCardVariants,
|
|
69621
69884
|
initial: "initial",
|
|
69622
69885
|
animate: "animate",
|
|
69623
69886
|
children: [
|
|
69624
69887
|
/* @__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
|
-
|
|
69888
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : isAssemblyCycleLayout ? "Cycle time trend" : "Hourly Output" }),
|
|
69889
|
+
canToggleChartIdleTime && /* @__PURE__ */ jsx(
|
|
69627
69890
|
"button",
|
|
69628
69891
|
{
|
|
69629
69892
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69648,19 +69911,19 @@ var WorkspaceDetailView = ({
|
|
|
69648
69911
|
timezone,
|
|
69649
69912
|
elapsedMinutes: elapsedShiftMinutes
|
|
69650
69913
|
}
|
|
69651
|
-
) : shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69914
|
+
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69652
69915
|
CycleTimeOverTimeChart,
|
|
69653
69916
|
{
|
|
69654
69917
|
data: maskedCycleTimeChartData,
|
|
69655
|
-
idealCycleTime:
|
|
69656
|
-
shiftStart:
|
|
69657
|
-
shiftEnd:
|
|
69918
|
+
idealCycleTime: authoritativeCycleMetrics?.ideal_cycle_time || 0,
|
|
69919
|
+
shiftStart: authoritativeCycleMetrics?.shift_start || "",
|
|
69920
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end || "",
|
|
69658
69921
|
xAxisMode: "hourly",
|
|
69659
69922
|
datasetKey: cycleTimeDatasetKey,
|
|
69660
69923
|
showIdleTime: showChartIdleTime,
|
|
69661
69924
|
idleTimeData: hourlyIdleMinutes
|
|
69662
69925
|
}
|
|
69663
|
-
) : /* @__PURE__ */ jsx(
|
|
69926
|
+
) : null : /* @__PURE__ */ jsx(
|
|
69664
69927
|
HourlyOutputChart2,
|
|
69665
69928
|
{
|
|
69666
69929
|
data: workspace.hourly_action_counts || [],
|
|
@@ -69678,7 +69941,7 @@ var WorkspaceDetailView = ({
|
|
|
69678
69941
|
]
|
|
69679
69942
|
}
|
|
69680
69943
|
),
|
|
69681
|
-
|
|
69944
|
+
showIdleBreakdownChart && /* @__PURE__ */ jsxs(
|
|
69682
69945
|
motion.div,
|
|
69683
69946
|
{
|
|
69684
69947
|
className: clsx(
|
|
@@ -69704,7 +69967,7 @@ var WorkspaceDetailView = ({
|
|
|
69704
69967
|
]
|
|
69705
69968
|
}
|
|
69706
69969
|
),
|
|
69707
|
-
isUptimeMode ? /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData, className: "flex-1" }) }) :
|
|
69970
|
+
isUptimeMode ? /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData, className: "flex-1" }) }) : isAssemblyCycleLayout ? /* @__PURE__ */ jsx(
|
|
69708
69971
|
WorkspaceCycleTimeMetricCards,
|
|
69709
69972
|
{
|
|
69710
69973
|
workspace,
|
|
@@ -69715,7 +69978,7 @@ var WorkspaceDetailView = ({
|
|
|
69715
69978
|
}
|
|
69716
69979
|
) : /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, legend: efficiencyLegend, className: "flex-1" }) })
|
|
69717
69980
|
] })
|
|
69718
|
-
] }),
|
|
69981
|
+
] }) }),
|
|
69719
69982
|
activeTab === "monthly_history" && /* @__PURE__ */ jsxs("div", { className: "h-[calc(100vh-10rem)] overflow-y-auto px-2 sm:px-4 lg:px-0", children: [
|
|
69720
69983
|
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
69984
|
/* @__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 +72610,7 @@ var normalizeLabel = (value) => {
|
|
|
72347
72610
|
const trimmed = value.trim();
|
|
72348
72611
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
72349
72612
|
};
|
|
72350
|
-
var
|
|
72613
|
+
var toFiniteNumber2 = (value) => {
|
|
72351
72614
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
72352
72615
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
72353
72616
|
const parsed = Number(value);
|
|
@@ -72381,7 +72644,7 @@ var formatImprovementPieceGain = (pcsGain) => {
|
|
|
72381
72644
|
var getPositiveImprovementGain = ({
|
|
72382
72645
|
estimated_gain_pieces
|
|
72383
72646
|
}) => {
|
|
72384
|
-
const issueGain =
|
|
72647
|
+
const issueGain = toFiniteNumber2(estimated_gain_pieces);
|
|
72385
72648
|
return {
|
|
72386
72649
|
pcsGain: issueGain !== null && issueGain > 0 ? issueGain : null
|
|
72387
72650
|
};
|
|
@@ -72389,7 +72652,7 @@ var getPositiveImprovementGain = ({
|
|
|
72389
72652
|
var getImprovementPcsGainSortValue = (input) => {
|
|
72390
72653
|
const { pcsGain } = getPositiveImprovementGain(input);
|
|
72391
72654
|
if (pcsGain !== null) return pcsGain;
|
|
72392
|
-
const raw =
|
|
72655
|
+
const raw = toFiniteNumber2(input.estimated_gain_pieces);
|
|
72393
72656
|
return raw ?? null;
|
|
72394
72657
|
};
|
|
72395
72658
|
var getImprovementDisplayMetadata = ({
|
|
@@ -72409,7 +72672,7 @@ var getImprovementDisplayMetadata = ({
|
|
|
72409
72672
|
metadataLabel: [workstationLabel, lineLabel, supervisorLabel].join(" \xB7 ")
|
|
72410
72673
|
};
|
|
72411
72674
|
};
|
|
72412
|
-
var
|
|
72675
|
+
var toFiniteNumber3 = (value) => {
|
|
72413
72676
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
72414
72677
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
72415
72678
|
const parsed = Number(value);
|
|
@@ -72437,15 +72700,15 @@ var compareImprovementRecommendationPriority = (left, right) => {
|
|
|
72437
72700
|
if (leftIndustrial !== rightIndustrial) {
|
|
72438
72701
|
return rightIndustrial - leftIndustrial;
|
|
72439
72702
|
}
|
|
72440
|
-
const leftGain =
|
|
72441
|
-
const rightGain =
|
|
72703
|
+
const leftGain = toFiniteNumber3(left.estimated_gain_pieces);
|
|
72704
|
+
const rightGain = toFiniteNumber3(right.estimated_gain_pieces);
|
|
72442
72705
|
if (leftGain !== rightGain) {
|
|
72443
72706
|
if (leftGain === null) return 1;
|
|
72444
72707
|
if (rightGain === null) return -1;
|
|
72445
72708
|
return rightGain - leftGain;
|
|
72446
72709
|
}
|
|
72447
|
-
const leftRatio =
|
|
72448
|
-
const rightRatio =
|
|
72710
|
+
const leftRatio = toFiniteNumber3(left.gain_to_target_ratio);
|
|
72711
|
+
const rightRatio = toFiniteNumber3(right.gain_to_target_ratio);
|
|
72449
72712
|
if (leftRatio !== rightRatio) {
|
|
72450
72713
|
if (leftRatio === null) return 1;
|
|
72451
72714
|
if (rightRatio === null) return -1;
|
|
@@ -75750,6 +76013,7 @@ var EMPTY_OVERVIEW_POOREST_LINES = {
|
|
|
75750
76013
|
};
|
|
75751
76014
|
var EMPTY_OVERVIEW_TREND = {
|
|
75752
76015
|
shift_mode: "all",
|
|
76016
|
+
granularity: "day",
|
|
75753
76017
|
points: []
|
|
75754
76018
|
};
|
|
75755
76019
|
var EMPTY_IDLE_BREAKDOWN = [];
|
|
@@ -75822,8 +76086,11 @@ var normalizePoorestLines = (value) => ({
|
|
|
75822
76086
|
});
|
|
75823
76087
|
var normalizeTrend = (value) => ({
|
|
75824
76088
|
shift_mode: value?.shift_mode || "all",
|
|
76089
|
+
granularity: value?.granularity === "hour" ? "hour" : "day",
|
|
75825
76090
|
points: (value?.points || []).map((point) => ({
|
|
75826
76091
|
date: point?.date,
|
|
76092
|
+
label: point?.label,
|
|
76093
|
+
hour_index: normalizeNumber(point?.hour_index),
|
|
75827
76094
|
avg_efficiency: normalizeNumber(point?.avg_efficiency)
|
|
75828
76095
|
}))
|
|
75829
76096
|
});
|
|
@@ -76165,17 +76432,25 @@ var formatSignedIdleDuration = (seconds) => {
|
|
|
76165
76432
|
const sign = seconds > 0 ? "+" : "-";
|
|
76166
76433
|
return `${sign}${formatIdleDuration(Math.abs(seconds))}`;
|
|
76167
76434
|
};
|
|
76168
|
-
var formatComparisonWindow = (
|
|
76435
|
+
var formatComparisonWindow = ({
|
|
76436
|
+
currentDayCount,
|
|
76437
|
+
previousDayCount,
|
|
76438
|
+
comparisonStrategy,
|
|
76439
|
+
shiftMode
|
|
76440
|
+
}) => {
|
|
76169
76441
|
if (comparisonStrategy === "previous_full_week") return "last week";
|
|
76170
|
-
if (
|
|
76171
|
-
|
|
76442
|
+
if (comparisonStrategy === "matched_range" && currentDayCount === 1 && previousDayCount === 1) {
|
|
76443
|
+
return "previous day";
|
|
76444
|
+
}
|
|
76445
|
+
if (!previousDayCount || !Number.isFinite(previousDayCount)) return "previous range";
|
|
76446
|
+
return `previous ${previousDayCount} ${previousDayCount === 1 ? "day" : "days"}`;
|
|
76172
76447
|
};
|
|
76173
76448
|
var buildDeltaBadge = (delta, options) => {
|
|
76174
76449
|
if (delta === null || delta === void 0 || !Number.isFinite(delta)) {
|
|
76175
76450
|
return {
|
|
76176
76451
|
icon: null,
|
|
76177
|
-
className: "bg-slate-100 text-slate-
|
|
76178
|
-
text:
|
|
76452
|
+
className: "bg-slate-100 text-slate-400",
|
|
76453
|
+
text: "\u2014"
|
|
76179
76454
|
};
|
|
76180
76455
|
}
|
|
76181
76456
|
const direction = delta >= 0 ? "up" : "down";
|
|
@@ -76186,6 +76461,34 @@ var buildDeltaBadge = (delta, options) => {
|
|
|
76186
76461
|
text: `${options.formatter(delta)} vs ${options.comparisonLabel}`
|
|
76187
76462
|
};
|
|
76188
76463
|
};
|
|
76464
|
+
var normalizeShiftLabel = (shiftName, shiftMode) => {
|
|
76465
|
+
if (shiftMode === "all") {
|
|
76466
|
+
return "All Shifts";
|
|
76467
|
+
}
|
|
76468
|
+
const trimmedName = shiftName?.trim();
|
|
76469
|
+
if (trimmedName) {
|
|
76470
|
+
const normalizedName = trimmedName.toLowerCase();
|
|
76471
|
+
if (normalizedName === "day") return "Day Shift";
|
|
76472
|
+
if (normalizedName === "night") return "Night Shift";
|
|
76473
|
+
return /shift/i.test(trimmedName) ? trimmedName : `${trimmedName} Shift`;
|
|
76474
|
+
}
|
|
76475
|
+
if (shiftMode === "night") return "Night Shift";
|
|
76476
|
+
return "Day Shift";
|
|
76477
|
+
};
|
|
76478
|
+
var getShiftIcon = (shiftName, shiftMode) => {
|
|
76479
|
+
const normalizedName = (shiftName || "").toLowerCase();
|
|
76480
|
+
const normalizedMode = shiftMode || "day";
|
|
76481
|
+
if (normalizedMode === "all") {
|
|
76482
|
+
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" }) });
|
|
76483
|
+
}
|
|
76484
|
+
if (normalizedName.includes("day") || normalizedName.includes("morning") || normalizedMode === "day") {
|
|
76485
|
+
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" }) });
|
|
76486
|
+
}
|
|
76487
|
+
if (normalizedName.includes("night") || normalizedName.includes("evening") || normalizedMode === "night") {
|
|
76488
|
+
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" }) });
|
|
76489
|
+
}
|
|
76490
|
+
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" }) });
|
|
76491
|
+
};
|
|
76189
76492
|
var buildLineDeltaTone = (delta, comparisonLabel) => {
|
|
76190
76493
|
if (delta === null || delta === void 0 || !Number.isFinite(delta)) {
|
|
76191
76494
|
return {
|
|
@@ -76241,6 +76544,8 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76241
76544
|
dateRange,
|
|
76242
76545
|
displayDateRange,
|
|
76243
76546
|
trendMode,
|
|
76547
|
+
isLiveScope,
|
|
76548
|
+
liveShiftName,
|
|
76244
76549
|
lineOptions,
|
|
76245
76550
|
supervisorOptions,
|
|
76246
76551
|
selectedSupervisorId,
|
|
@@ -76254,6 +76559,15 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76254
76559
|
}) => {
|
|
76255
76560
|
bumpRenderCounter();
|
|
76256
76561
|
const subtitleRange = displayDateRange || dateRange;
|
|
76562
|
+
const showLiveShiftMeta = isLiveScope && trendMode !== "all";
|
|
76563
|
+
const liveShiftLabel = React141__default.useMemo(
|
|
76564
|
+
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
76565
|
+
[liveShiftName, trendMode]
|
|
76566
|
+
);
|
|
76567
|
+
const liveShiftIcon = React141__default.useMemo(
|
|
76568
|
+
() => getShiftIcon(liveShiftName, trendMode),
|
|
76569
|
+
[liveShiftName, trendMode]
|
|
76570
|
+
);
|
|
76257
76571
|
const [isFilterOpen, setIsFilterOpen] = React141__default.useState(false);
|
|
76258
76572
|
const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React141__default.useState(false);
|
|
76259
76573
|
const filterRef = React141__default.useRef(null);
|
|
@@ -76370,9 +76684,25 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76370
76684
|
className: "flex-shrink-0 -ml-1"
|
|
76371
76685
|
}
|
|
76372
76686
|
) : /* @__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
|
-
|
|
76687
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center min-w-0", children: [
|
|
76688
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-1.5 min-w-0 max-w-[240px]", children: [
|
|
76689
|
+
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900 leading-tight text-center truncate", children: "Operations Overview" }),
|
|
76690
|
+
isLiveScope ? /* @__PURE__ */ jsx(
|
|
76691
|
+
"div",
|
|
76692
|
+
{
|
|
76693
|
+
"data-testid": "operations-overview-live-indicator",
|
|
76694
|
+
className: "h-2 w-2 rounded-full bg-emerald-500 animate-pulse ring-2 ring-emerald-500/20 flex-shrink-0"
|
|
76695
|
+
}
|
|
76696
|
+
) : null
|
|
76697
|
+
] }),
|
|
76698
|
+
/* @__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: [
|
|
76699
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-center", children: mobileSubtitle }),
|
|
76700
|
+
showLiveShiftMeta ? /* @__PURE__ */ jsx("span", { className: "text-slate-300", children: "|" }) : null,
|
|
76701
|
+
showLiveShiftMeta ? /* @__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: [
|
|
76702
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-75 shrink-0", children: liveShiftIcon }),
|
|
76703
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: liveShiftLabel })
|
|
76704
|
+
] }) }) : null
|
|
76705
|
+
] })
|
|
76376
76706
|
] }),
|
|
76377
76707
|
/* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 flex items-center gap-1.5", children: [
|
|
76378
76708
|
/* @__PURE__ */ jsx(
|
|
@@ -76391,22 +76721,40 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76391
76721
|
{
|
|
76392
76722
|
ref: mobileFilterButtonRef,
|
|
76393
76723
|
onClick: handleFilterToggle,
|
|
76394
|
-
className: `p-2 rounded-full transition-colors relative ${isFilterOpen || activeFilterCount > 0 ? "bg-
|
|
76724
|
+
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
76725
|
"aria-label": "Open filters",
|
|
76396
76726
|
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-
|
|
76727
|
+
/* @__PURE__ */ jsx(Filter, { className: "w-5 h-5" }),
|
|
76728
|
+
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
76729
|
]
|
|
76400
76730
|
}
|
|
76401
76731
|
)
|
|
76402
76732
|
] })
|
|
76403
76733
|
] }) }),
|
|
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
|
-
|
|
76734
|
+
/* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center relative min-h-[64px]", children: [
|
|
76735
|
+
/* @__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: [
|
|
76736
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 min-w-0 max-w-full", children: [
|
|
76737
|
+
/* @__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" }),
|
|
76738
|
+
isLiveScope ? /* @__PURE__ */ jsx(
|
|
76739
|
+
"div",
|
|
76740
|
+
{
|
|
76741
|
+
"data-testid": "operations-overview-live-indicator",
|
|
76742
|
+
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"
|
|
76743
|
+
}
|
|
76744
|
+
) : null
|
|
76745
|
+
] }),
|
|
76746
|
+
/* @__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: [
|
|
76747
|
+
/* @__PURE__ */ jsx("span", { children: desktopSubtitle }),
|
|
76748
|
+
showLiveShiftMeta ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
76749
|
+
/* @__PURE__ */ jsx("span", { className: "text-slate-300", children: "|" }),
|
|
76750
|
+
/* @__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: [
|
|
76751
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-75", children: liveShiftIcon }),
|
|
76752
|
+
liveShiftLabel
|
|
76753
|
+
] }) })
|
|
76754
|
+
] }) : null
|
|
76755
|
+
] })
|
|
76408
76756
|
] }),
|
|
76409
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute right-0 flex items-center gap-3", children: [
|
|
76757
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute right-0 flex items-center gap-3 shrink-0", children: [
|
|
76410
76758
|
/* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx(
|
|
76411
76759
|
MonthlyRangeFilter_default,
|
|
76412
76760
|
{
|
|
@@ -76423,12 +76771,12 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76423
76771
|
{
|
|
76424
76772
|
ref: filterButtonRef,
|
|
76425
76773
|
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-
|
|
76774
|
+
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
76775
|
"aria-label": "Open filters",
|
|
76428
76776
|
children: [
|
|
76429
|
-
/* @__PURE__ */ jsx(Filter, { className: `w-[18px] h-[18px] ${activeFilterCount > 0 ? "text-
|
|
76777
|
+
/* @__PURE__ */ jsx(Filter, { className: `w-[18px] h-[18px] ${isFilterOpen || activeFilterCount > 0 ? "text-slate-500" : "text-slate-400"}` }),
|
|
76430
76778
|
"Filters",
|
|
76431
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 ml-0.5 transition-transform duration-200 ${isFilterOpen ? "rotate-180" : ""}` })
|
|
76779
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 ml-0.5 text-slate-400 transition-transform duration-200 ${isFilterOpen ? "rotate-180" : ""}` })
|
|
76432
76780
|
]
|
|
76433
76781
|
}
|
|
76434
76782
|
)
|
|
@@ -76556,11 +76904,18 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76556
76904
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
76557
76905
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
76558
76906
|
const comparisonLabel = React141__default.useMemo(() => {
|
|
76559
|
-
return formatComparisonWindow(
|
|
76560
|
-
scope.
|
|
76561
|
-
scope.
|
|
76562
|
-
|
|
76563
|
-
|
|
76907
|
+
return formatComparisonWindow({
|
|
76908
|
+
currentDayCount: scope.current_range?.day_count ?? null,
|
|
76909
|
+
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
76910
|
+
comparisonStrategy: scope.comparison_strategy,
|
|
76911
|
+
shiftMode: scope.shift_mode
|
|
76912
|
+
});
|
|
76913
|
+
}, [
|
|
76914
|
+
scope.comparison_strategy,
|
|
76915
|
+
scope.current_range?.day_count,
|
|
76916
|
+
scope.previous_range?.day_count,
|
|
76917
|
+
scope.shift_mode
|
|
76918
|
+
]);
|
|
76564
76919
|
const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React141__default.useState(false);
|
|
76565
76920
|
const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React141__default.useState(false);
|
|
76566
76921
|
const idleContributorsRef = React141__default.useRef(null);
|
|
@@ -76650,10 +77005,17 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76650
77005
|
roundOne(snapshot.data.summary.plant_efficiency.current),
|
|
76651
77006
|
"%"
|
|
76652
77007
|
] }),
|
|
76653
|
-
/* @__PURE__ */ jsxs(
|
|
76654
|
-
|
|
76655
|
-
|
|
76656
|
-
|
|
77008
|
+
/* @__PURE__ */ jsxs(
|
|
77009
|
+
"div",
|
|
77010
|
+
{
|
|
77011
|
+
"data-testid": "operations-overview-efficiency-delta",
|
|
77012
|
+
className: `flex items-center gap-1 px-2.5 py-1 rounded-full ${plantEfficiencyBadge.className}`,
|
|
77013
|
+
children: [
|
|
77014
|
+
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,
|
|
77015
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-sm font-medium", children: plantEfficiencyBadge.text })
|
|
77016
|
+
]
|
|
77017
|
+
}
|
|
77018
|
+
)
|
|
76657
77019
|
] }) : /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-slate-400", children: "No efficiency data available" })
|
|
76658
77020
|
] }),
|
|
76659
77021
|
/* @__PURE__ */ jsxs(
|
|
@@ -76699,10 +77061,17 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76699
77061
|
/* @__PURE__ */ jsx("div", { className: "mb-1", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-700", children: "Idle Time per Workstation" }) }),
|
|
76700
77062
|
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
77063
|
/* @__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
|
-
|
|
77064
|
+
/* @__PURE__ */ jsxs(
|
|
77065
|
+
"div",
|
|
77066
|
+
{
|
|
77067
|
+
"data-testid": "operations-overview-idle-delta",
|
|
77068
|
+
className: `flex items-center gap-1 px-2.5 py-1 rounded-full ${idleBadge.className}`,
|
|
77069
|
+
children: [
|
|
77070
|
+
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,
|
|
77071
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-sm font-medium", children: idleBadge.text })
|
|
77072
|
+
]
|
|
77073
|
+
}
|
|
77074
|
+
)
|
|
76706
77075
|
] }) : /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-slate-400", children: "No idle time data available" })
|
|
76707
77076
|
]
|
|
76708
77077
|
}
|
|
@@ -76765,11 +77134,18 @@ var PoorestPerformersCard = React141__default.memo(({
|
|
|
76765
77134
|
}
|
|
76766
77135
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
76767
77136
|
const comparisonLabel = React141__default.useMemo(() => {
|
|
76768
|
-
return formatComparisonWindow(
|
|
76769
|
-
scope.
|
|
76770
|
-
scope.
|
|
76771
|
-
|
|
76772
|
-
|
|
77137
|
+
return formatComparisonWindow({
|
|
77138
|
+
currentDayCount: scope.current_range?.day_count ?? null,
|
|
77139
|
+
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
77140
|
+
comparisonStrategy: scope.comparison_strategy,
|
|
77141
|
+
shiftMode: scope.shift_mode
|
|
77142
|
+
});
|
|
77143
|
+
}, [
|
|
77144
|
+
scope.comparison_strategy,
|
|
77145
|
+
scope.current_range?.day_count,
|
|
77146
|
+
scope.previous_range?.day_count,
|
|
77147
|
+
scope.shift_mode
|
|
77148
|
+
]);
|
|
76773
77149
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
76774
77150
|
const mergedPoorestLines = React141__default.useMemo(() => {
|
|
76775
77151
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
@@ -76926,7 +77302,8 @@ IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
|
76926
77302
|
var EfficiencyTrendCard = React141__default.memo(({
|
|
76927
77303
|
store,
|
|
76928
77304
|
dateRange,
|
|
76929
|
-
appTimezone
|
|
77305
|
+
appTimezone,
|
|
77306
|
+
hourlyLabelStartTime
|
|
76930
77307
|
}) => {
|
|
76931
77308
|
bumpRenderCounter();
|
|
76932
77309
|
const trend = useOperationsOverviewTrend(store);
|
|
@@ -76936,7 +77313,41 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
76936
77313
|
);
|
|
76937
77314
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
76938
77315
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
77316
|
+
const isHourlyTrend = trend.data.granularity === "hour";
|
|
76939
77317
|
const trendData = React141__default.useMemo(() => {
|
|
77318
|
+
if (isHourlyTrend) {
|
|
77319
|
+
return (trend.data.points || []).map((point, index) => ({
|
|
77320
|
+
name: (() => {
|
|
77321
|
+
const rawLabel = point.label?.trim() || "";
|
|
77322
|
+
if (rawLabel) {
|
|
77323
|
+
return rawLabel;
|
|
77324
|
+
}
|
|
77325
|
+
if (!hourlyLabelStartTime) {
|
|
77326
|
+
return "";
|
|
77327
|
+
}
|
|
77328
|
+
const hourIndex = typeof point.hour_index === "number" ? point.hour_index : index;
|
|
77329
|
+
const [hoursPart, minutesPart] = hourlyLabelStartTime.split(":");
|
|
77330
|
+
const startHours = Number(hoursPart);
|
|
77331
|
+
const startMinutes = Number(minutesPart);
|
|
77332
|
+
if (!Number.isFinite(startHours) || !Number.isFinite(startMinutes)) {
|
|
77333
|
+
return "";
|
|
77334
|
+
}
|
|
77335
|
+
const totalMinutes = startHours * 60 + startMinutes + hourIndex * 60;
|
|
77336
|
+
const hour24 = Math.floor(totalMinutes / 60) % 24;
|
|
77337
|
+
const minutes = totalMinutes % 60;
|
|
77338
|
+
const suffix = hour24 < 12 ? "AM" : "PM";
|
|
77339
|
+
const hour12 = hour24 % 12 || 12;
|
|
77340
|
+
if (minutes === 0) {
|
|
77341
|
+
return `${hour12} ${suffix}`;
|
|
77342
|
+
}
|
|
77343
|
+
return `${hour12}:${minutes.toString().padStart(2, "0")} ${suffix}`;
|
|
77344
|
+
})(),
|
|
77345
|
+
efficiency: (() => {
|
|
77346
|
+
const value = toNumber3(point.avg_efficiency);
|
|
77347
|
+
return value === null ? void 0 : value;
|
|
77348
|
+
})()
|
|
77349
|
+
}));
|
|
77350
|
+
}
|
|
76940
77351
|
const pointsByDate = new Map(
|
|
76941
77352
|
(trend.data.points || []).flatMap((point) => {
|
|
76942
77353
|
if (!point.date) return [];
|
|
@@ -76974,12 +77385,19 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
76974
77385
|
})()
|
|
76975
77386
|
};
|
|
76976
77387
|
});
|
|
76977
|
-
}, [currentWeekRange.startKey, isCurrentWeekToDateRange, trend.data.points]);
|
|
77388
|
+
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
76978
77389
|
const trendTooltipLabelFormatter = React141__default.useCallback((label, payload) => {
|
|
77390
|
+
if (isHourlyTrend) return label;
|
|
76979
77391
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
76980
77392
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
76981
77393
|
return `${label} (${dayOfWeek})`;
|
|
76982
|
-
}, []);
|
|
77394
|
+
}, [isHourlyTrend]);
|
|
77395
|
+
const trendXAxisTickFormatter = React141__default.useCallback((value, index) => {
|
|
77396
|
+
if (!isHourlyTrend) {
|
|
77397
|
+
return typeof value === "string" ? value : String(value ?? "");
|
|
77398
|
+
}
|
|
77399
|
+
return index % 2 === 0 ? typeof value === "string" ? value : String(value ?? "") : "";
|
|
77400
|
+
}, [isHourlyTrend]);
|
|
76983
77401
|
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
77402
|
/* @__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
77403
|
/* @__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(
|
|
@@ -76988,6 +77406,8 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
76988
77406
|
data: trendData,
|
|
76989
77407
|
lines: efficiencyLineConfig,
|
|
76990
77408
|
xAxisDataKey: "name",
|
|
77409
|
+
xAxisInterval: isHourlyTrend ? 0 : void 0,
|
|
77410
|
+
xAxisTickFormatter: trendXAxisTickFormatter,
|
|
76991
77411
|
yAxisUnit: "%",
|
|
76992
77412
|
yAxisDomain: [0, 100],
|
|
76993
77413
|
showLegend: false,
|
|
@@ -77133,7 +77553,8 @@ var useOperationsOverviewRefresh = ({
|
|
|
77133
77553
|
endKey,
|
|
77134
77554
|
trendMode,
|
|
77135
77555
|
comparisonStrategy,
|
|
77136
|
-
isLiveScope
|
|
77556
|
+
isLiveScope,
|
|
77557
|
+
enabled = true
|
|
77137
77558
|
}) => {
|
|
77138
77559
|
const lineIdsKey = React141__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
77139
77560
|
const scopeSignature = React141__default.useMemo(
|
|
@@ -77179,7 +77600,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77179
77600
|
}, []);
|
|
77180
77601
|
const runRefresh = React141__default.useCallback(
|
|
77181
77602
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
77182
|
-
if (!supabase || !companyId || lineIds.length === 0) return;
|
|
77603
|
+
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
77183
77604
|
const requestId = requestIdsRef.current[section] + 1;
|
|
77184
77605
|
requestIdsRef.current[section] = requestId;
|
|
77185
77606
|
controllersRef.current[section]?.abort();
|
|
@@ -77199,7 +77620,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77199
77620
|
onError(error instanceof Error ? error.message : `Failed to refresh ${section}`);
|
|
77200
77621
|
}
|
|
77201
77622
|
},
|
|
77202
|
-
[companyId, lineIds.length, supabase]
|
|
77623
|
+
[companyId, enabled, lineIds.length, supabase]
|
|
77203
77624
|
);
|
|
77204
77625
|
const refreshSnapshot = React141__default.useCallback(
|
|
77205
77626
|
async (reason) => {
|
|
@@ -77369,6 +77790,12 @@ var useOperationsOverviewRefresh = ({
|
|
|
77369
77790
|
});
|
|
77370
77791
|
}, [refreshAll, startPolling, stopPolling]);
|
|
77371
77792
|
React141__default.useEffect(() => {
|
|
77793
|
+
if (!enabled) {
|
|
77794
|
+
stopPolling("disabled");
|
|
77795
|
+
abortAll();
|
|
77796
|
+
store.reset();
|
|
77797
|
+
return;
|
|
77798
|
+
}
|
|
77372
77799
|
if (!supabase || !companyId || lineIds.length === 0) {
|
|
77373
77800
|
stopPolling("scope_invalid");
|
|
77374
77801
|
abortAll();
|
|
@@ -77376,9 +77803,9 @@ var useOperationsOverviewRefresh = ({
|
|
|
77376
77803
|
return;
|
|
77377
77804
|
}
|
|
77378
77805
|
void refreshAll("scope_change");
|
|
77379
|
-
}, [abortAll, companyId, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
77806
|
+
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
77380
77807
|
React141__default.useEffect(() => {
|
|
77381
|
-
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
77808
|
+
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
77382
77809
|
isPageActiveRef.current = false;
|
|
77383
77810
|
stopPolling("live_scope_disabled");
|
|
77384
77811
|
return;
|
|
@@ -77434,11 +77861,119 @@ var useOperationsOverviewRefresh = ({
|
|
|
77434
77861
|
window.removeEventListener("pageshow", handlePageShow);
|
|
77435
77862
|
window.removeEventListener("pagehide", handlePageHide);
|
|
77436
77863
|
};
|
|
77437
|
-
}, [companyId, getIsPageActive, isLiveScope, lineIds.length, refreshFromResume, startPolling, stopPolling, supabase]);
|
|
77864
|
+
}, [companyId, enabled, getIsPageActive, isLiveScope, lineIds.length, refreshFromResume, startPolling, stopPolling, supabase]);
|
|
77865
|
+
};
|
|
77866
|
+
var parseTimeToMinutes3 = (value) => {
|
|
77867
|
+
if (!value) return null;
|
|
77868
|
+
const parts = value.split(":");
|
|
77869
|
+
if (parts.length < 2) return null;
|
|
77870
|
+
const hours = Number(parts[0]);
|
|
77871
|
+
const minutes = Number(parts[1]);
|
|
77872
|
+
if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return null;
|
|
77873
|
+
if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null;
|
|
77874
|
+
return hours * 60 + minutes;
|
|
77875
|
+
};
|
|
77876
|
+
var normalizeShiftId = (value) => {
|
|
77877
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
77878
|
+
return value;
|
|
77879
|
+
}
|
|
77880
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
77881
|
+
const parsed = Number(value);
|
|
77882
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
77883
|
+
}
|
|
77884
|
+
return null;
|
|
77885
|
+
};
|
|
77886
|
+
var classifyShiftBucket = ({
|
|
77887
|
+
shiftName,
|
|
77888
|
+
shiftId,
|
|
77889
|
+
startTime,
|
|
77890
|
+
endTime
|
|
77891
|
+
}) => {
|
|
77892
|
+
const normalizedName = (shiftName || "").trim().toLowerCase();
|
|
77893
|
+
if (normalizedName) {
|
|
77894
|
+
if (["night", "graveyard", "evening"].some((keyword) => normalizedName.includes(keyword))) {
|
|
77895
|
+
return "night";
|
|
77896
|
+
}
|
|
77897
|
+
if (["day", "morning"].some((keyword) => normalizedName.includes(keyword))) {
|
|
77898
|
+
return "day";
|
|
77899
|
+
}
|
|
77900
|
+
}
|
|
77901
|
+
const startMinutes = parseTimeToMinutes3(startTime);
|
|
77902
|
+
const endMinutes = parseTimeToMinutes3(endTime);
|
|
77903
|
+
if (startMinutes !== null) {
|
|
77904
|
+
if (startMinutes >= 4 * 60 && startMinutes < 18 * 60) return "day";
|
|
77905
|
+
return "night";
|
|
77906
|
+
}
|
|
77907
|
+
if (endMinutes !== null) {
|
|
77908
|
+
if (endMinutes >= 6 * 60 && endMinutes <= 21 * 60) return "day";
|
|
77909
|
+
return "night";
|
|
77910
|
+
}
|
|
77911
|
+
const normalizedShiftId = normalizeShiftId(shiftId);
|
|
77912
|
+
if (normalizedShiftId === 0) return "day";
|
|
77913
|
+
if (normalizedShiftId === 1) return "night";
|
|
77914
|
+
return null;
|
|
77915
|
+
};
|
|
77916
|
+
var getShiftWindowsForConfig = (shiftConfig, timezone) => {
|
|
77917
|
+
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
77918
|
+
return shiftConfig.shifts.map((shift) => ({
|
|
77919
|
+
shiftId: shift.shiftId,
|
|
77920
|
+
shiftName: shift.shiftName,
|
|
77921
|
+
startTime: shift.startTime,
|
|
77922
|
+
endTime: shift.endTime
|
|
77923
|
+
}));
|
|
77924
|
+
}
|
|
77925
|
+
const windows = [];
|
|
77926
|
+
if (shiftConfig?.dayShift) {
|
|
77927
|
+
windows.push({
|
|
77928
|
+
shiftId: shiftConfig.dayShift.id ?? 0,
|
|
77929
|
+
shiftName: shiftConfig.dayShift.name || "Day Shift",
|
|
77930
|
+
startTime: shiftConfig.dayShift.startTime || "06:00",
|
|
77931
|
+
endTime: shiftConfig.dayShift.endTime || "18:00"
|
|
77932
|
+
});
|
|
77933
|
+
}
|
|
77934
|
+
if (shiftConfig?.nightShift) {
|
|
77935
|
+
windows.push({
|
|
77936
|
+
shiftId: shiftConfig.nightShift.id ?? 1,
|
|
77937
|
+
shiftName: shiftConfig.nightShift.name || "Night Shift",
|
|
77938
|
+
startTime: shiftConfig.nightShift.startTime || "18:00",
|
|
77939
|
+
endTime: shiftConfig.nightShift.endTime || "06:00"
|
|
77940
|
+
});
|
|
77941
|
+
}
|
|
77942
|
+
if (windows.length > 0) {
|
|
77943
|
+
return windows;
|
|
77944
|
+
}
|
|
77945
|
+
return [
|
|
77946
|
+
{
|
|
77947
|
+
shiftId: 0,
|
|
77948
|
+
shiftName: "Day Shift",
|
|
77949
|
+
startTime: "06:00",
|
|
77950
|
+
endTime: "18:00"
|
|
77951
|
+
},
|
|
77952
|
+
{
|
|
77953
|
+
shiftId: 1,
|
|
77954
|
+
shiftName: "Night Shift",
|
|
77955
|
+
startTime: "18:00",
|
|
77956
|
+
endTime: "06:00"
|
|
77957
|
+
}
|
|
77958
|
+
];
|
|
77959
|
+
};
|
|
77960
|
+
var normalizeShiftWindowMinutes = (startTime, endTime) => {
|
|
77961
|
+
const startMinutes = parseTimeToMinutes3(startTime);
|
|
77962
|
+
const endMinutesRaw = parseTimeToMinutes3(endTime);
|
|
77963
|
+
if (startMinutes === null || endMinutesRaw === null) {
|
|
77964
|
+
return null;
|
|
77965
|
+
}
|
|
77966
|
+
let endMinutes = endMinutesRaw;
|
|
77967
|
+
if (endMinutes <= startMinutes) {
|
|
77968
|
+
endMinutes += 24 * 60;
|
|
77969
|
+
}
|
|
77970
|
+
return { startMinutes, endMinutes };
|
|
77438
77971
|
};
|
|
77439
77972
|
var PlantHeadView = () => {
|
|
77440
77973
|
const supabase = useSupabase();
|
|
77441
77974
|
const entityConfig = useEntityConfig();
|
|
77975
|
+
const factoryViewId = entityConfig.factoryViewId || "factory";
|
|
77976
|
+
const staticShiftConfig = useShiftConfig();
|
|
77442
77977
|
const appTimezone = useAppTimezone() || "UTC";
|
|
77443
77978
|
const { navigate } = useNavigation();
|
|
77444
77979
|
const { accessibleLineIds } = useUserLineAccess();
|
|
@@ -77446,11 +77981,22 @@ var PlantHeadView = () => {
|
|
|
77446
77981
|
useHideMobileHeader(!!mobileMenuContext);
|
|
77447
77982
|
const storeRef = React141__default.useRef(createOperationsOverviewStore());
|
|
77448
77983
|
const store = storeRef.current;
|
|
77449
|
-
const
|
|
77450
|
-
|
|
77984
|
+
const fallbackOperationalDate = React141__default.useMemo(
|
|
77985
|
+
() => getOperationalDate(appTimezone),
|
|
77986
|
+
[appTimezone]
|
|
77987
|
+
);
|
|
77988
|
+
const [dateRange, setDateRange] = React141__default.useState(() => ({
|
|
77989
|
+
startKey: fallbackOperationalDate,
|
|
77990
|
+
endKey: fallbackOperationalDate
|
|
77991
|
+
}));
|
|
77992
|
+
const [usesThisWeekComparison, setUsesThisWeekComparison] = React141__default.useState(false);
|
|
77451
77993
|
const [trendMode, setTrendMode] = React141__default.useState("all");
|
|
77452
77994
|
const [selectedSupervisorId, setSelectedSupervisorId] = React141__default.useState("all");
|
|
77453
77995
|
const [selectedLineIds, setSelectedLineIds] = React141__default.useState([]);
|
|
77996
|
+
const [isInitialScopeReady, setIsInitialScopeReady] = React141__default.useState(false);
|
|
77997
|
+
const [shiftResolutionTick, setShiftResolutionTick] = React141__default.useState(0);
|
|
77998
|
+
const hasAutoInitializedScopeRef = React141__default.useRef(false);
|
|
77999
|
+
const hasUserAdjustedScopeRef = React141__default.useRef(false);
|
|
77454
78000
|
React141__default.useEffect(() => {
|
|
77455
78001
|
trackCorePageView("Operations Overview", {
|
|
77456
78002
|
dashboard_surface: "operations_overview"
|
|
@@ -77472,8 +78018,10 @@ var PlantHeadView = () => {
|
|
|
77472
78018
|
return dateRange;
|
|
77473
78019
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
77474
78020
|
const normalizedLineIds = React141__default.useMemo(
|
|
77475
|
-
() => Array.from(new Set(
|
|
77476
|
-
|
|
78021
|
+
() => Array.from(new Set(
|
|
78022
|
+
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
78023
|
+
)).sort(),
|
|
78024
|
+
[accessibleLineIds, factoryViewId]
|
|
77477
78025
|
);
|
|
77478
78026
|
const lineIdsKey = React141__default.useMemo(
|
|
77479
78027
|
() => normalizedLineIds.join(","),
|
|
@@ -77547,14 +78095,198 @@ var PlantHeadView = () => {
|
|
|
77547
78095
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
77548
78096
|
[normalizedLineIds, selectedLineIds]
|
|
77549
78097
|
);
|
|
78098
|
+
const {
|
|
78099
|
+
shiftConfigMap,
|
|
78100
|
+
isLoading: isShiftConfigLoading
|
|
78101
|
+
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
78102
|
+
React141__default.useEffect(() => {
|
|
78103
|
+
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
78104
|
+
return;
|
|
78105
|
+
}
|
|
78106
|
+
const intervalId = window.setInterval(() => {
|
|
78107
|
+
setShiftResolutionTick((previous) => previous + 1);
|
|
78108
|
+
}, 6e4);
|
|
78109
|
+
return () => {
|
|
78110
|
+
clearInterval(intervalId);
|
|
78111
|
+
};
|
|
78112
|
+
}, [isShiftConfigLoading, scopedLineIds.length]);
|
|
78113
|
+
const shiftResolutionNow = React141__default.useMemo(
|
|
78114
|
+
() => /* @__PURE__ */ new Date(),
|
|
78115
|
+
[shiftResolutionTick]
|
|
78116
|
+
);
|
|
78117
|
+
const earliestDayShiftStartTime = React141__default.useMemo(() => {
|
|
78118
|
+
const candidateStarts = [];
|
|
78119
|
+
scopedLineIds.forEach((lineId) => {
|
|
78120
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78121
|
+
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
78122
|
+
const bucket = classifyShiftBucket({
|
|
78123
|
+
shiftName: shift.shiftName,
|
|
78124
|
+
shiftId: shift.shiftId,
|
|
78125
|
+
startTime: shift.startTime,
|
|
78126
|
+
endTime: shift.endTime
|
|
78127
|
+
});
|
|
78128
|
+
const startMinutes = parseTimeToMinutes3(shift.startTime);
|
|
78129
|
+
if (bucket === "day" && startMinutes !== null) {
|
|
78130
|
+
candidateStarts.push(startMinutes);
|
|
78131
|
+
}
|
|
78132
|
+
});
|
|
78133
|
+
});
|
|
78134
|
+
if (candidateStarts.length === 0) {
|
|
78135
|
+
scopedLineIds.forEach((lineId) => {
|
|
78136
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78137
|
+
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
78138
|
+
const startMinutes = parseTimeToMinutes3(shift.startTime);
|
|
78139
|
+
if (startMinutes !== null) {
|
|
78140
|
+
candidateStarts.push(startMinutes);
|
|
78141
|
+
}
|
|
78142
|
+
});
|
|
78143
|
+
});
|
|
78144
|
+
}
|
|
78145
|
+
if (candidateStarts.length === 0) {
|
|
78146
|
+
return "06:00";
|
|
78147
|
+
}
|
|
78148
|
+
const earliestMinutes = Math.min(...candidateStarts);
|
|
78149
|
+
const hours = Math.floor(earliestMinutes / 60);
|
|
78150
|
+
const minutes = earliestMinutes % 60;
|
|
78151
|
+
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
78152
|
+
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
78153
|
+
const resolvedOperationalToday = React141__default.useMemo(
|
|
78154
|
+
() => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
|
|
78155
|
+
[appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
|
|
78156
|
+
);
|
|
78157
|
+
const activeLineShiftStates = React141__default.useMemo(() => {
|
|
78158
|
+
return scopedLineIds.flatMap((lineId) => {
|
|
78159
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78160
|
+
const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
|
|
78161
|
+
if (!activeShift) {
|
|
78162
|
+
return [];
|
|
78163
|
+
}
|
|
78164
|
+
const trendBucket = classifyShiftBucket({
|
|
78165
|
+
shiftName: activeShift.shiftName,
|
|
78166
|
+
shiftId: activeShift.shiftId,
|
|
78167
|
+
startTime: activeShift.startTime,
|
|
78168
|
+
endTime: activeShift.endTime
|
|
78169
|
+
});
|
|
78170
|
+
if (!trendBucket || trendBucket === "all") {
|
|
78171
|
+
return [];
|
|
78172
|
+
}
|
|
78173
|
+
return [{
|
|
78174
|
+
lineId,
|
|
78175
|
+
trendMode: trendBucket,
|
|
78176
|
+
shiftId: activeShift.shiftId,
|
|
78177
|
+
shiftName: activeShift.shiftName || null,
|
|
78178
|
+
startTime: activeShift.startTime || null,
|
|
78179
|
+
endTime: activeShift.endTime || null,
|
|
78180
|
+
date: activeShift.date
|
|
78181
|
+
}];
|
|
78182
|
+
});
|
|
78183
|
+
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
78184
|
+
const hasActiveDayShiftLine = React141__default.useMemo(
|
|
78185
|
+
() => activeLineShiftStates.some((shift) => shift.trendMode === "day" && shift.date === resolvedOperationalToday),
|
|
78186
|
+
[activeLineShiftStates, resolvedOperationalToday]
|
|
78187
|
+
);
|
|
78188
|
+
const hasActiveNightShiftLine = React141__default.useMemo(
|
|
78189
|
+
() => activeLineShiftStates.some((shift) => shift.trendMode === "night" && shift.date === resolvedOperationalToday),
|
|
78190
|
+
[activeLineShiftStates, resolvedOperationalToday]
|
|
78191
|
+
);
|
|
78192
|
+
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
78193
|
+
const hourlyWindowStartTime = React141__default.useMemo(() => {
|
|
78194
|
+
if (scopedLineIds.length === 0) {
|
|
78195
|
+
return null;
|
|
78196
|
+
}
|
|
78197
|
+
const startCandidates = [];
|
|
78198
|
+
const endCandidates = [];
|
|
78199
|
+
scopedLineIds.forEach((lineId) => {
|
|
78200
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78201
|
+
getShiftWindowsForConfig(shiftConfig).forEach((shift) => {
|
|
78202
|
+
const bucket = classifyShiftBucket({
|
|
78203
|
+
shiftName: shift.shiftName,
|
|
78204
|
+
shiftId: shift.shiftId,
|
|
78205
|
+
startTime: shift.startTime,
|
|
78206
|
+
endTime: shift.endTime
|
|
78207
|
+
});
|
|
78208
|
+
if (resolvedTrendMode !== "all" && bucket !== resolvedTrendMode) {
|
|
78209
|
+
return;
|
|
78210
|
+
}
|
|
78211
|
+
const normalizedWindow = normalizeShiftWindowMinutes(shift.startTime, shift.endTime);
|
|
78212
|
+
if (!normalizedWindow) {
|
|
78213
|
+
return;
|
|
78214
|
+
}
|
|
78215
|
+
startCandidates.push(normalizedWindow.startMinutes);
|
|
78216
|
+
endCandidates.push(normalizedWindow.endMinutes);
|
|
78217
|
+
});
|
|
78218
|
+
});
|
|
78219
|
+
if (resolvedTrendMode === "all") {
|
|
78220
|
+
const dayStartCandidates = startCandidates.length > 0 ? scopedLineIds.flatMap((lineId) => {
|
|
78221
|
+
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78222
|
+
return getShiftWindowsForConfig(shiftConfig).map((shift) => {
|
|
78223
|
+
const bucket = classifyShiftBucket({
|
|
78224
|
+
shiftName: shift.shiftName,
|
|
78225
|
+
shiftId: shift.shiftId,
|
|
78226
|
+
startTime: shift.startTime,
|
|
78227
|
+
endTime: shift.endTime
|
|
78228
|
+
});
|
|
78229
|
+
return bucket === "day" ? parseTimeToMinutes3(shift.startTime) : null;
|
|
78230
|
+
}).filter((value) => value !== null);
|
|
78231
|
+
}) : [];
|
|
78232
|
+
if (dayStartCandidates.length > 0) {
|
|
78233
|
+
startCandidates.splice(0, startCandidates.length, ...dayStartCandidates);
|
|
78234
|
+
}
|
|
78235
|
+
}
|
|
78236
|
+
if (startCandidates.length === 0 || endCandidates.length === 0) {
|
|
78237
|
+
return null;
|
|
78238
|
+
}
|
|
78239
|
+
const earliestMinutes = Math.min(...startCandidates);
|
|
78240
|
+
const hours = Math.floor(earliestMinutes / 60);
|
|
78241
|
+
const minutes = earliestMinutes % 60;
|
|
78242
|
+
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
78243
|
+
}, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
78244
|
+
const isShiftScopeResolved = React141__default.useMemo(
|
|
78245
|
+
() => !isShiftConfigLoading,
|
|
78246
|
+
[isShiftConfigLoading]
|
|
78247
|
+
);
|
|
77550
78248
|
const initializedTimezoneRef = React141__default.useRef(appTimezone);
|
|
77551
78249
|
React141__default.useEffect(() => {
|
|
77552
78250
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
77553
|
-
|
|
77554
|
-
|
|
78251
|
+
hasAutoInitializedScopeRef.current = false;
|
|
78252
|
+
hasUserAdjustedScopeRef.current = false;
|
|
78253
|
+
setDateRange({
|
|
78254
|
+
startKey: fallbackOperationalDate,
|
|
78255
|
+
endKey: fallbackOperationalDate
|
|
78256
|
+
});
|
|
78257
|
+
setTrendMode("all");
|
|
78258
|
+
setUsesThisWeekComparison(false);
|
|
78259
|
+
setIsInitialScopeReady(false);
|
|
77555
78260
|
initializedTimezoneRef.current = appTimezone;
|
|
77556
|
-
}, [appTimezone]);
|
|
78261
|
+
}, [appTimezone, fallbackOperationalDate]);
|
|
78262
|
+
React141__default.useEffect(() => {
|
|
78263
|
+
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
78264
|
+
return;
|
|
78265
|
+
}
|
|
78266
|
+
if (scopedLineIds.length === 0) {
|
|
78267
|
+
return;
|
|
78268
|
+
}
|
|
78269
|
+
if (!isShiftScopeResolved) {
|
|
78270
|
+
return;
|
|
78271
|
+
}
|
|
78272
|
+
setDateRange((previous) => {
|
|
78273
|
+
const nextStartKey = resolvedOperationalToday || fallbackOperationalDate;
|
|
78274
|
+
if (previous.startKey === nextStartKey && previous.endKey === nextStartKey) {
|
|
78275
|
+
return previous;
|
|
78276
|
+
}
|
|
78277
|
+
return {
|
|
78278
|
+
startKey: nextStartKey,
|
|
78279
|
+
endKey: nextStartKey
|
|
78280
|
+
};
|
|
78281
|
+
});
|
|
78282
|
+
setTrendMode("all");
|
|
78283
|
+
setUsesThisWeekComparison(false);
|
|
78284
|
+
hasAutoInitializedScopeRef.current = true;
|
|
78285
|
+
setIsInitialScopeReady(true);
|
|
78286
|
+
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
77557
78287
|
const handleDateRangeChange = React141__default.useCallback((range, meta) => {
|
|
78288
|
+
hasUserAdjustedScopeRef.current = true;
|
|
78289
|
+
setIsInitialScopeReady(true);
|
|
77558
78290
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
77559
78291
|
start_date: range.startKey,
|
|
77560
78292
|
end_date: range.endKey
|
|
@@ -77571,6 +78303,8 @@ var PlantHeadView = () => {
|
|
|
77571
78303
|
});
|
|
77572
78304
|
}, []);
|
|
77573
78305
|
const handleTrendModeChange = React141__default.useCallback((mode) => {
|
|
78306
|
+
hasUserAdjustedScopeRef.current = true;
|
|
78307
|
+
setIsInitialScopeReady(true);
|
|
77574
78308
|
setTrendMode(mode);
|
|
77575
78309
|
}, []);
|
|
77576
78310
|
const handleSelectedLineIdsChange = React141__default.useCallback((lineIds) => {
|
|
@@ -77597,15 +78331,6 @@ var PlantHeadView = () => {
|
|
|
77597
78331
|
params.set("rangeEnd", dateRange.endKey);
|
|
77598
78332
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
77599
78333
|
}, [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
78334
|
const handleViewAllPoorestPerformers = React141__default.useCallback(() => {
|
|
77610
78335
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
77611
78336
|
navigate("/kpis?tab=leaderboard");
|
|
@@ -77631,16 +78356,65 @@ var PlantHeadView = () => {
|
|
|
77631
78356
|
}
|
|
77632
78357
|
return void 0;
|
|
77633
78358
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
78359
|
+
const effectiveDateRange = React141__default.useMemo(() => {
|
|
78360
|
+
if (isInitialScopeReady) {
|
|
78361
|
+
return dateRange;
|
|
78362
|
+
}
|
|
78363
|
+
const nextStartKey = resolvedOperationalToday || fallbackOperationalDate;
|
|
78364
|
+
return {
|
|
78365
|
+
startKey: nextStartKey,
|
|
78366
|
+
endKey: nextStartKey
|
|
78367
|
+
};
|
|
78368
|
+
}, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
|
|
78369
|
+
const effectiveTrendMode = React141__default.useMemo(
|
|
78370
|
+
() => resolvedTrendMode,
|
|
78371
|
+
[resolvedTrendMode]
|
|
78372
|
+
);
|
|
78373
|
+
const hourlyLabelStartTime = React141__default.useMemo(() => {
|
|
78374
|
+
if (scopedLineIds.length === 0) {
|
|
78375
|
+
return null;
|
|
78376
|
+
}
|
|
78377
|
+
return hourlyWindowStartTime;
|
|
78378
|
+
}, [hourlyWindowStartTime, scopedLineIds.length]);
|
|
78379
|
+
const isSingleDayScope = React141__default.useMemo(
|
|
78380
|
+
() => effectiveDateRange.startKey === effectiveDateRange.endKey,
|
|
78381
|
+
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
78382
|
+
);
|
|
78383
|
+
const isLiveScope = React141__default.useMemo(
|
|
78384
|
+
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && (effectiveTrendMode === "all" || effectiveTrendMode === "day" && hasActiveDayShiftLine || effectiveTrendMode === "night" && hasActiveNightShiftLine),
|
|
78385
|
+
[
|
|
78386
|
+
effectiveDateRange.startKey,
|
|
78387
|
+
effectiveTrendMode,
|
|
78388
|
+
hasActiveDayShiftLine,
|
|
78389
|
+
hasActiveNightShiftLine,
|
|
78390
|
+
isSingleDayScope,
|
|
78391
|
+
resolvedOperationalToday
|
|
78392
|
+
]
|
|
78393
|
+
);
|
|
78394
|
+
const handleOpenLineDetails = React141__default.useCallback((lineId, lineName) => {
|
|
78395
|
+
trackCoreEvent("Operations Overview Line Clicked", {
|
|
78396
|
+
line_id: lineId,
|
|
78397
|
+
line_name: lineName,
|
|
78398
|
+
range_start: dateRange.startKey,
|
|
78399
|
+
range_end: dateRange.endKey
|
|
78400
|
+
});
|
|
78401
|
+
if (isLiveScope) {
|
|
78402
|
+
navigate(`/kpis/${lineId}?returnTo=${encodeURIComponent("/")}`);
|
|
78403
|
+
return;
|
|
78404
|
+
}
|
|
78405
|
+
navigate(buildLineMonthlyHistoryUrl(lineId));
|
|
78406
|
+
}, [buildLineMonthlyHistoryUrl, dateRange.endKey, dateRange.startKey, isLiveScope, navigate]);
|
|
77634
78407
|
useOperationsOverviewRefresh({
|
|
77635
78408
|
store,
|
|
77636
78409
|
supabase,
|
|
77637
78410
|
companyId: entityConfig.companyId,
|
|
77638
78411
|
lineIds: scopedLineIds,
|
|
77639
|
-
startKey:
|
|
77640
|
-
endKey:
|
|
77641
|
-
trendMode,
|
|
78412
|
+
startKey: effectiveDateRange.startKey,
|
|
78413
|
+
endKey: effectiveDateRange.endKey,
|
|
78414
|
+
trendMode: effectiveTrendMode,
|
|
77642
78415
|
comparisonStrategy,
|
|
77643
|
-
isLiveScope
|
|
78416
|
+
isLiveScope,
|
|
78417
|
+
enabled: scopedLineIds.length > 0 && isShiftScopeResolved
|
|
77644
78418
|
});
|
|
77645
78419
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-h-screen bg-slate-50 w-full font-sans", children: [
|
|
77646
78420
|
/* @__PURE__ */ jsx(
|
|
@@ -77649,6 +78423,8 @@ var PlantHeadView = () => {
|
|
|
77649
78423
|
dateRange,
|
|
77650
78424
|
displayDateRange: headerDateRange,
|
|
77651
78425
|
trendMode,
|
|
78426
|
+
isLiveScope,
|
|
78427
|
+
liveShiftName: isLiveScope && trendMode !== "all" ? trendMode : null,
|
|
77652
78428
|
lineOptions,
|
|
77653
78429
|
supervisorOptions,
|
|
77654
78430
|
selectedSupervisorId,
|
|
@@ -77671,7 +78447,7 @@ var PlantHeadView = () => {
|
|
|
77671
78447
|
store,
|
|
77672
78448
|
supervisorsByLineId,
|
|
77673
78449
|
onViewAll: handleViewAllPoorestPerformers,
|
|
77674
|
-
onLineClick:
|
|
78450
|
+
onLineClick: handleOpenLineDetails
|
|
77675
78451
|
}
|
|
77676
78452
|
),
|
|
77677
78453
|
/* @__PURE__ */ jsx(
|
|
@@ -77688,7 +78464,8 @@ var PlantHeadView = () => {
|
|
|
77688
78464
|
{
|
|
77689
78465
|
store,
|
|
77690
78466
|
dateRange,
|
|
77691
|
-
appTimezone
|
|
78467
|
+
appTimezone,
|
|
78468
|
+
hourlyLabelStartTime
|
|
77692
78469
|
}
|
|
77693
78470
|
),
|
|
77694
78471
|
/* @__PURE__ */ jsx(
|
|
@@ -78182,4 +78959,4 @@ var streamProxyConfig = {
|
|
|
78182
78959
|
}
|
|
78183
78960
|
};
|
|
78184
78961
|
|
|
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 };
|
|
78962
|
+
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, getActiveShift, 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 };
|