@optifye/dashboard-core 6.11.14 → 6.11.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +36 -3
- package/dist/index.d.mts +40 -4
- package/dist/index.d.ts +40 -4
- package/dist/index.js +1437 -603
- package/dist/index.mjs +1437 -605
- 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';
|
|
@@ -11742,6 +11742,9 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
11742
11742
|
const idealOutput = coerceNumber(data.ideal_output ?? data.ideal_output_until_now, 0);
|
|
11743
11743
|
const outputDifference = totalActions - idealOutput;
|
|
11744
11744
|
const hourlyCycleTimes = Array.isArray(data.hourly_cycle_times) ? data.hourly_cycle_times.map((value) => coerceNumber(value, 0)) : [];
|
|
11745
|
+
const cycleCompletionClipCount = data.cycle_completion_clip_count === null || data.cycle_completion_clip_count === void 0 ? null : coerceNumber(data.cycle_completion_clip_count, 0);
|
|
11746
|
+
const cycleTimeDataStatus = data.cycle_time_data_status === "missing_clips" ? "missing_clips" : data.cycle_time_data_status === "available" ? "available" : null;
|
|
11747
|
+
const cycleTimeTimezone = typeof data.cycle_time_timezone === "string" ? data.cycle_time_timezone : null;
|
|
11745
11748
|
const totalWorkspacesValue = coerceNumber(
|
|
11746
11749
|
data.total_workspaces ?? lineMetricsById?.[data.line_id || ""]?.total_workspaces ?? workspaceConfig.totalWorkspaces,
|
|
11747
11750
|
0
|
|
@@ -11789,6 +11792,9 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
11789
11792
|
total_actions: totalActions,
|
|
11790
11793
|
hourly_action_counts: hourlyActionCounts,
|
|
11791
11794
|
hourly_cycle_times: hourlyCycleTimes,
|
|
11795
|
+
cycle_completion_clip_count: cycleCompletionClipCount,
|
|
11796
|
+
cycle_time_data_status: cycleTimeDataStatus,
|
|
11797
|
+
cycle_time_timezone: cycleTimeTimezone,
|
|
11792
11798
|
workspace_rank: coerceNumber(data.workspace_rank, 0),
|
|
11793
11799
|
total_workspaces: totalWorkspacesValue,
|
|
11794
11800
|
ideal_output_until_now: idealOutput,
|
|
@@ -12829,6 +12835,7 @@ var useShiftGroups = ({
|
|
|
12829
12835
|
}) => {
|
|
12830
12836
|
const [shiftGroups, setShiftGroups] = useState([]);
|
|
12831
12837
|
const [shiftGroupsKey, setShiftGroupsKey] = useState("");
|
|
12838
|
+
const [hasComputed, setHasComputed] = useState(false);
|
|
12832
12839
|
const lastKeyRef = useRef("");
|
|
12833
12840
|
const mapRef = useRef(shiftConfigMap);
|
|
12834
12841
|
useEffect(() => {
|
|
@@ -12839,6 +12846,7 @@ var useShiftGroups = ({
|
|
|
12839
12846
|
lastKeyRef.current = "";
|
|
12840
12847
|
setShiftGroups([]);
|
|
12841
12848
|
setShiftGroupsKey("");
|
|
12849
|
+
setHasComputed(false);
|
|
12842
12850
|
return;
|
|
12843
12851
|
}
|
|
12844
12852
|
let isMounted = true;
|
|
@@ -12851,6 +12859,7 @@ var useShiftGroups = ({
|
|
|
12851
12859
|
setShiftGroups(groups);
|
|
12852
12860
|
setShiftGroupsKey(key);
|
|
12853
12861
|
}
|
|
12862
|
+
setHasComputed(true);
|
|
12854
12863
|
};
|
|
12855
12864
|
compute();
|
|
12856
12865
|
const intervalId = setInterval(compute, pollIntervalMs);
|
|
@@ -12859,7 +12868,7 @@ var useShiftGroups = ({
|
|
|
12859
12868
|
clearInterval(intervalId);
|
|
12860
12869
|
};
|
|
12861
12870
|
}, [enabled, shiftConfigMap.size, timezone, pollIntervalMs]);
|
|
12862
|
-
return { shiftGroups, shiftGroupsKey };
|
|
12871
|
+
return { shiftGroups, shiftGroupsKey, hasComputed };
|
|
12863
12872
|
};
|
|
12864
12873
|
|
|
12865
12874
|
// src/lib/types/efficiencyLegend.ts
|
|
@@ -12921,52 +12930,6 @@ function getEfficiencyTextColorClasses(efficiency, legend = DEFAULT_EFFICIENCY_L
|
|
|
12921
12930
|
}
|
|
12922
12931
|
}
|
|
12923
12932
|
|
|
12924
|
-
// src/lib/hooks/useDashboardMetrics.recentFlow.ts
|
|
12925
|
-
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
12926
|
-
var getWorkspaceRecentFlowCacheKey = (workspace) => {
|
|
12927
|
-
const workspaceKey = workspace.workspace_uuid || workspace.workspace_name || "unknown";
|
|
12928
|
-
return `${workspaceKey}|${workspace.date}|${workspace.shift_id}`;
|
|
12929
|
-
};
|
|
12930
|
-
var toRecentFlowSnapshot = (workspace) => {
|
|
12931
|
-
if (!isFiniteNumber(workspace.recent_flow_percent)) {
|
|
12932
|
-
return null;
|
|
12933
|
-
}
|
|
12934
|
-
return {
|
|
12935
|
-
recent_flow_percent: workspace.recent_flow_percent,
|
|
12936
|
-
recent_flow_actual_rate_pph: workspace.recent_flow_actual_rate_pph ?? null,
|
|
12937
|
-
recent_flow_healthy_rate_pph: workspace.recent_flow_healthy_rate_pph ?? null,
|
|
12938
|
-
recent_flow_window_minutes: workspace.recent_flow_window_minutes ?? null,
|
|
12939
|
-
recent_flow_effective_end_at: workspace.recent_flow_effective_end_at ?? null
|
|
12940
|
-
};
|
|
12941
|
-
};
|
|
12942
|
-
var mergeWorkspaceRecentFlowMetrics = (workspaces, previousCache) => {
|
|
12943
|
-
const nextCache = /* @__PURE__ */ new Map();
|
|
12944
|
-
const mergedWorkspaces = workspaces.map((workspace) => {
|
|
12945
|
-
const cacheKey = getWorkspaceRecentFlowCacheKey(workspace);
|
|
12946
|
-
const currentSnapshot = toRecentFlowSnapshot(workspace);
|
|
12947
|
-
if (workspace.recent_flow_mode === "computed" && currentSnapshot) {
|
|
12948
|
-
nextCache.set(cacheKey, currentSnapshot);
|
|
12949
|
-
return workspace;
|
|
12950
|
-
}
|
|
12951
|
-
if (workspace.recent_flow_mode === "hold") {
|
|
12952
|
-
const cachedSnapshot = previousCache.get(cacheKey);
|
|
12953
|
-
if (cachedSnapshot) {
|
|
12954
|
-
nextCache.set(cacheKey, cachedSnapshot);
|
|
12955
|
-
return {
|
|
12956
|
-
...workspace,
|
|
12957
|
-
...cachedSnapshot,
|
|
12958
|
-
recent_flow_mode: "hold"
|
|
12959
|
-
};
|
|
12960
|
-
}
|
|
12961
|
-
}
|
|
12962
|
-
return workspace;
|
|
12963
|
-
});
|
|
12964
|
-
return {
|
|
12965
|
-
workspaces: mergedWorkspaces,
|
|
12966
|
-
cache: nextCache
|
|
12967
|
-
};
|
|
12968
|
-
};
|
|
12969
|
-
|
|
12970
12933
|
// src/lib/hooks/useDashboardMetrics.ts
|
|
12971
12934
|
var DEBUG_DASHBOARD_LOGS = process.env.NEXT_PUBLIC_DEBUG_DASHBOARD === "true";
|
|
12972
12935
|
var logDebug = (...args) => {
|
|
@@ -13055,7 +13018,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13055
13018
|
const abortControllerRef = useRef(null);
|
|
13056
13019
|
const lastFetchKeyRef = useRef(null);
|
|
13057
13020
|
const inFlightFetchKeyRef = useRef(null);
|
|
13058
|
-
const recentFlowCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
13059
13021
|
const updateQueueRef = useRef(false);
|
|
13060
13022
|
const onLineMetricsUpdateRef = useRef(onLineMetricsUpdate);
|
|
13061
13023
|
const shiftGroupsRef = useRef(shiftGroups);
|
|
@@ -13089,7 +13051,6 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13089
13051
|
setError(null);
|
|
13090
13052
|
lastFetchKeyRef.current = null;
|
|
13091
13053
|
inFlightFetchKeyRef.current = null;
|
|
13092
|
-
recentFlowCacheRef.current = /* @__PURE__ */ new Map();
|
|
13093
13054
|
}, [lineId]);
|
|
13094
13055
|
const fetchAllMetrics = useCallback(async (options = {}) => {
|
|
13095
13056
|
const { force = false } = options;
|
|
@@ -13364,12 +13325,9 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13364
13325
|
actionType: item.action_type,
|
|
13365
13326
|
actionName: item.action_name
|
|
13366
13327
|
}),
|
|
13367
|
-
recent_flow_mode: item.recent_flow_mode ?? void 0,
|
|
13368
13328
|
recent_flow_percent: item.recent_flow_percent ?? null,
|
|
13369
|
-
recent_flow_actual_rate_pph: item.recent_flow_actual_rate_pph ?? null,
|
|
13370
|
-
recent_flow_healthy_rate_pph: item.recent_flow_healthy_rate_pph ?? null,
|
|
13371
|
-
recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
|
|
13372
13329
|
recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
|
|
13330
|
+
recent_flow_computed_at: item.recent_flow_computed_at ?? null,
|
|
13373
13331
|
incoming_wip_current: item.incoming_wip_current ?? null,
|
|
13374
13332
|
incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
|
|
13375
13333
|
incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null
|
|
@@ -13380,16 +13338,11 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13380
13338
|
const wsNumB = parseInt(b.workspace_name?.replace(/[^0-9]/g, "") || "0");
|
|
13381
13339
|
return wsNumA - wsNumB;
|
|
13382
13340
|
});
|
|
13383
|
-
|
|
13384
|
-
workspaces: mergedWorkspaceData,
|
|
13385
|
-
cache: nextRecentFlowCache
|
|
13386
|
-
} = mergeWorkspaceRecentFlowMetrics(transformedWorkspaceData, recentFlowCacheRef.current);
|
|
13387
|
-
recentFlowCacheRef.current = nextRecentFlowCache;
|
|
13388
|
-
mergedWorkspaceData.forEach((metric) => {
|
|
13341
|
+
transformedWorkspaceData.forEach((metric) => {
|
|
13389
13342
|
workspaceMetricsStore.setOverview(metric);
|
|
13390
13343
|
});
|
|
13391
13344
|
const newMetricsState = {
|
|
13392
|
-
workspaceMetrics:
|
|
13345
|
+
workspaceMetrics: transformedWorkspaceData,
|
|
13393
13346
|
lineMetrics: allLineMetrics || [],
|
|
13394
13347
|
metadata: { hasFlowBuffers, idleTimeVlmByLine },
|
|
13395
13348
|
efficiencyLegend: efficiencyLegend ?? DEFAULT_EFFICIENCY_LEGEND
|
|
@@ -16814,7 +16767,7 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16814
16767
|
const [isLoading, setIsLoading] = useState(true);
|
|
16815
16768
|
const [error, setError] = useState(null);
|
|
16816
16769
|
const supabase = useSupabase();
|
|
16817
|
-
const
|
|
16770
|
+
const parseTimeToMinutes4 = (timeStr) => {
|
|
16818
16771
|
const [hours, minutes] = timeStr.split(":").map(Number);
|
|
16819
16772
|
return hours * 60 + minutes;
|
|
16820
16773
|
};
|
|
@@ -16823,8 +16776,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16823
16776
|
return now4.getHours() * 60 + now4.getMinutes();
|
|
16824
16777
|
};
|
|
16825
16778
|
const isTimeInBreak = (breakStart, breakEnd, currentMinutes) => {
|
|
16826
|
-
const startMinutes =
|
|
16827
|
-
const endMinutes =
|
|
16779
|
+
const startMinutes = parseTimeToMinutes4(breakStart);
|
|
16780
|
+
const endMinutes = parseTimeToMinutes4(breakEnd);
|
|
16828
16781
|
if (endMinutes < startMinutes) {
|
|
16829
16782
|
return currentMinutes >= startMinutes || currentMinutes < endMinutes;
|
|
16830
16783
|
} else {
|
|
@@ -16832,8 +16785,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16832
16785
|
}
|
|
16833
16786
|
};
|
|
16834
16787
|
const calculateBreakProgress = (breakStart, breakEnd, currentMinutes) => {
|
|
16835
|
-
const startMinutes =
|
|
16836
|
-
const endMinutes =
|
|
16788
|
+
const startMinutes = parseTimeToMinutes4(breakStart);
|
|
16789
|
+
const endMinutes = parseTimeToMinutes4(breakEnd);
|
|
16837
16790
|
let elapsedMinutes = 0;
|
|
16838
16791
|
let remainingMinutes = 0;
|
|
16839
16792
|
if (endMinutes < startMinutes) {
|
|
@@ -16851,8 +16804,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16851
16804
|
return { elapsedMinutes, remainingMinutes };
|
|
16852
16805
|
};
|
|
16853
16806
|
const isTimeInShift = (startTime, endTime, currentMinutes) => {
|
|
16854
|
-
const startMinutes =
|
|
16855
|
-
const endMinutes =
|
|
16807
|
+
const startMinutes = parseTimeToMinutes4(startTime);
|
|
16808
|
+
const endMinutes = parseTimeToMinutes4(endTime);
|
|
16856
16809
|
if (endMinutes < startMinutes) {
|
|
16857
16810
|
return currentMinutes >= startMinutes || currentMinutes < endMinutes;
|
|
16858
16811
|
} else {
|
|
@@ -16912,8 +16865,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16912
16865
|
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
16913
16866
|
let duration = breakItem.duration || 0;
|
|
16914
16867
|
if (!duration || duration === 0) {
|
|
16915
|
-
const startMinutes =
|
|
16916
|
-
const endMinutes =
|
|
16868
|
+
const startMinutes = parseTimeToMinutes4(startTime);
|
|
16869
|
+
const endMinutes = parseTimeToMinutes4(endTime);
|
|
16917
16870
|
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
16918
16871
|
}
|
|
16919
16872
|
return {
|
|
@@ -16929,8 +16882,8 @@ var useActiveBreaks = (lineIds) => {
|
|
|
16929
16882
|
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
16930
16883
|
let duration = breakItem.duration || 0;
|
|
16931
16884
|
if (!duration || duration === 0) {
|
|
16932
|
-
const startMinutes =
|
|
16933
|
-
const endMinutes =
|
|
16885
|
+
const startMinutes = parseTimeToMinutes4(startTime);
|
|
16886
|
+
const endMinutes = parseTimeToMinutes4(endTime);
|
|
16934
16887
|
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
16935
16888
|
}
|
|
16936
16889
|
return {
|
|
@@ -23011,6 +22964,16 @@ var createThrottledReload = (interval = 5e3, maxReloads = 3) => {
|
|
|
23011
22964
|
};
|
|
23012
22965
|
var throttledReloadDashboard = createThrottledReload(5e3, 3);
|
|
23013
22966
|
|
|
22967
|
+
// src/lib/utils/dev/localDevTestLogin.ts
|
|
22968
|
+
var isLoopbackHostname = (hostname) => {
|
|
22969
|
+
const normalized = String(hostname || "").trim().toLowerCase();
|
|
22970
|
+
return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1";
|
|
22971
|
+
};
|
|
22972
|
+
var shouldEnableLocalDevTestLogin = ({
|
|
22973
|
+
enabledFlag,
|
|
22974
|
+
hostname
|
|
22975
|
+
}) => enabledFlag && isLoopbackHostname(hostname);
|
|
22976
|
+
|
|
23014
22977
|
// src/lib/utils/index.ts
|
|
23015
22978
|
var formatIdleTime = (idleTimeInSeconds) => {
|
|
23016
22979
|
if (!idleTimeInSeconds || idleTimeInSeconds <= 0) {
|
|
@@ -31195,12 +31158,16 @@ var LoginPage = ({
|
|
|
31195
31158
|
onRateLimitCheck,
|
|
31196
31159
|
logoSrc = optifye_logo_default,
|
|
31197
31160
|
logoAlt = "Optifye",
|
|
31198
|
-
brandName = "Optifye"
|
|
31161
|
+
brandName = "Optifye",
|
|
31162
|
+
showDevTestLogin = false,
|
|
31163
|
+
devTestLoginLabel = "Sign in as Test User",
|
|
31164
|
+
onDevTestLogin
|
|
31199
31165
|
}) => {
|
|
31200
31166
|
const [email, setEmail] = useState("");
|
|
31201
31167
|
const [otp, setOtp] = useState("");
|
|
31202
31168
|
const [step, setStep] = useState("email");
|
|
31203
31169
|
const [loading, setLoading] = useState(false);
|
|
31170
|
+
const [devLoginLoading, setDevLoginLoading] = useState(false);
|
|
31204
31171
|
const [error, setError] = useState(null);
|
|
31205
31172
|
const [countdown, setCountdown] = useState(0);
|
|
31206
31173
|
const supabase = useSupabase();
|
|
@@ -31264,6 +31231,25 @@ var LoginPage = ({
|
|
|
31264
31231
|
startCountdown();
|
|
31265
31232
|
}
|
|
31266
31233
|
};
|
|
31234
|
+
const handleDevTestLogin = async () => {
|
|
31235
|
+
if (!onDevTestLogin) {
|
|
31236
|
+
return;
|
|
31237
|
+
}
|
|
31238
|
+
setDevLoginLoading(true);
|
|
31239
|
+
setError(null);
|
|
31240
|
+
try {
|
|
31241
|
+
const result = await onDevTestLogin();
|
|
31242
|
+
const nextError = typeof result === "object" && result !== null && "error" in result ? result.error : null;
|
|
31243
|
+
if (typeof nextError === "string" && nextError.trim()) {
|
|
31244
|
+
setError(nextError);
|
|
31245
|
+
}
|
|
31246
|
+
} catch (err) {
|
|
31247
|
+
console.error("Dev test login failed:", err);
|
|
31248
|
+
setError("Dev test login unavailable.");
|
|
31249
|
+
} finally {
|
|
31250
|
+
setDevLoginLoading(false);
|
|
31251
|
+
}
|
|
31252
|
+
};
|
|
31267
31253
|
return /* @__PURE__ */ jsx("div", { className: "min-h-screen flex items-center justify-center bg-gradient-to-br from-slate-50 to-slate-100", children: /* @__PURE__ */ jsxs("div", { className: "max-w-md w-full mx-4", children: [
|
|
31268
31254
|
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-2xl shadow-xl border border-slate-200 p-8", children: [
|
|
31269
31255
|
/* @__PURE__ */ jsxs("div", { className: "text-center mb-8", children: [
|
|
@@ -31304,7 +31290,7 @@ var LoginPage = ({
|
|
|
31304
31290
|
"button",
|
|
31305
31291
|
{
|
|
31306
31292
|
type: "submit",
|
|
31307
|
-
disabled: loading,
|
|
31293
|
+
disabled: loading || devLoginLoading,
|
|
31308
31294
|
className: "w-full py-3 px-4 bg-slate-900 hover:bg-slate-800 focus:ring-2 focus:ring-slate-600 focus:ring-offset-2 text-white font-medium rounded-xl transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center",
|
|
31309
31295
|
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31310
31296
|
/* @__PURE__ */ jsxs("svg", { className: "animate-spin -ml-1 mr-3 h-4 w-4 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
@@ -31314,7 +31300,31 @@ var LoginPage = ({
|
|
|
31314
31300
|
"Sending..."
|
|
31315
31301
|
] }) : "Continue with Email"
|
|
31316
31302
|
}
|
|
31317
|
-
)
|
|
31303
|
+
),
|
|
31304
|
+
showDevTestLogin && onDevTestLogin ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
31305
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
31306
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-slate-200" }),
|
|
31307
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium uppercase tracking-[0.2em] text-slate-400", children: "Local Dev" }),
|
|
31308
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-slate-200" })
|
|
31309
|
+
] }),
|
|
31310
|
+
/* @__PURE__ */ jsx(
|
|
31311
|
+
"button",
|
|
31312
|
+
{
|
|
31313
|
+
type: "button",
|
|
31314
|
+
disabled: loading || devLoginLoading,
|
|
31315
|
+
onClick: () => void handleDevTestLogin(),
|
|
31316
|
+
className: "w-full py-3 px-4 bg-white hover:bg-slate-50 focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 text-slate-700 font-medium rounded-xl border border-slate-200 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center",
|
|
31317
|
+
children: devLoginLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31318
|
+
/* @__PURE__ */ jsxs("svg", { className: "animate-spin -ml-1 mr-3 h-4 w-4 text-slate-700", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
31319
|
+
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
31320
|
+
/* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
|
|
31321
|
+
] }),
|
|
31322
|
+
"Signing In..."
|
|
31323
|
+
] }) : devTestLoginLabel
|
|
31324
|
+
}
|
|
31325
|
+
),
|
|
31326
|
+
/* @__PURE__ */ jsx("p", { className: "text-center text-xs text-slate-500", children: "Localhost-only convenience login for the shared test account." })
|
|
31327
|
+
] }) : null
|
|
31318
31328
|
] }) : /* @__PURE__ */ jsxs("form", { className: "space-y-6", onSubmit: handleVerifyOTP, children: [
|
|
31319
31329
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
31320
31330
|
/* @__PURE__ */ jsx("label", { htmlFor: "otp", className: "block text-sm font-medium text-slate-700 mb-2 text-center", children: "Enter the 6-digit code sent to" }),
|
|
@@ -31339,7 +31349,7 @@ var LoginPage = ({
|
|
|
31339
31349
|
"button",
|
|
31340
31350
|
{
|
|
31341
31351
|
type: "submit",
|
|
31342
|
-
disabled: loading || otp.length !== 6,
|
|
31352
|
+
disabled: loading || devLoginLoading || otp.length !== 6,
|
|
31343
31353
|
className: "w-full py-3 px-4 bg-slate-900 hover:bg-slate-800 focus:ring-2 focus:ring-slate-600 focus:ring-offset-2 text-white font-medium rounded-xl transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center",
|
|
31344
31354
|
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31345
31355
|
/* @__PURE__ */ jsxs("svg", { className: "animate-spin -ml-1 mr-3 h-4 w-4 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
@@ -32180,31 +32190,35 @@ var LineChartComponent = ({
|
|
|
32180
32190
|
...restOfChartProps
|
|
32181
32191
|
}) => {
|
|
32182
32192
|
const containerRef = React141__default.useRef(null);
|
|
32183
|
-
const [
|
|
32184
|
-
const
|
|
32185
|
-
const { formatNumber } = useFormatNumber();
|
|
32193
|
+
const [dimensions, setDimensions] = React141__default.useState({ width: 0, height: 0 });
|
|
32194
|
+
const [hasValidData, setHasValidData] = React141__default.useState(false);
|
|
32186
32195
|
React141__default.useEffect(() => {
|
|
32187
|
-
const
|
|
32188
|
-
|
|
32189
|
-
const
|
|
32190
|
-
|
|
32191
|
-
|
|
32192
|
-
|
|
32193
|
-
|
|
32194
|
-
|
|
32195
|
-
checkContainerDimensions();
|
|
32196
|
-
const resizeObserver = new ResizeObserver(checkContainerDimensions);
|
|
32197
|
-
if (containerRef.current) {
|
|
32198
|
-
resizeObserver.observe(containerRef.current);
|
|
32196
|
+
const currentHasValidData = data && lines && lines.length > 0 && data.some(
|
|
32197
|
+
(item) => lines.some((line) => {
|
|
32198
|
+
const val = item[line.dataKey];
|
|
32199
|
+
return typeof val === "number" && val > 0;
|
|
32200
|
+
})
|
|
32201
|
+
);
|
|
32202
|
+
if (currentHasValidData && !hasValidData) {
|
|
32203
|
+
setHasValidData(true);
|
|
32199
32204
|
}
|
|
32200
|
-
|
|
32201
|
-
|
|
32202
|
-
|
|
32203
|
-
|
|
32204
|
-
|
|
32205
|
-
|
|
32206
|
-
|
|
32205
|
+
}, [data, lines, hasValidData]);
|
|
32206
|
+
React141__default.useEffect(() => {
|
|
32207
|
+
if (!containerRef.current) return;
|
|
32208
|
+
const observer = new ResizeObserver((entries) => {
|
|
32209
|
+
const entry = entries[0];
|
|
32210
|
+
if (entry) {
|
|
32211
|
+
setDimensions({
|
|
32212
|
+
width: entry.contentRect.width,
|
|
32213
|
+
height: entry.contentRect.height
|
|
32214
|
+
});
|
|
32215
|
+
}
|
|
32216
|
+
});
|
|
32217
|
+
observer.observe(containerRef.current);
|
|
32218
|
+
return () => observer.disconnect();
|
|
32207
32219
|
}, []);
|
|
32220
|
+
const themeConfig = useThemeConfig();
|
|
32221
|
+
const { formatNumber } = useFormatNumber();
|
|
32208
32222
|
const yAxisTickFormatter = (value) => {
|
|
32209
32223
|
return `${formatNumber(value)}${yAxisUnit || ""}`;
|
|
32210
32224
|
};
|
|
@@ -32226,57 +32240,71 @@ var LineChartComponent = ({
|
|
|
32226
32240
|
const gridStrokeColor = themeConfig?.gray?.["300"] || "#ccc";
|
|
32227
32241
|
const axisTickFillColor = themeConfig?.gray?.["600"] || "#666";
|
|
32228
32242
|
const axisStrokeColor = themeConfig?.gray?.["400"] || "#999";
|
|
32229
|
-
const
|
|
32230
|
-
|
|
32231
|
-
|
|
32232
|
-
|
|
32233
|
-
|
|
32234
|
-
|
|
32235
|
-
|
|
32236
|
-
|
|
32237
|
-
|
|
32238
|
-
stroke:
|
|
32239
|
-
|
|
32240
|
-
|
|
32241
|
-
|
|
32242
|
-
|
|
32243
|
-
|
|
32244
|
-
|
|
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
|
-
|
|
32243
|
+
const renderChartContent = (chartWidth, chartHeight) => /* @__PURE__ */ jsxs(
|
|
32244
|
+
LineChart$1,
|
|
32245
|
+
{
|
|
32246
|
+
width: chartWidth,
|
|
32247
|
+
height: chartHeight,
|
|
32248
|
+
data,
|
|
32249
|
+
margin: { top: 5, right: 30, left: 20, bottom: 20 },
|
|
32250
|
+
...restOfChartProps,
|
|
32251
|
+
children: [
|
|
32252
|
+
showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStrokeColor }),
|
|
32253
|
+
/* @__PURE__ */ jsx(
|
|
32254
|
+
XAxis,
|
|
32255
|
+
{
|
|
32256
|
+
dataKey: xAxisDataKey,
|
|
32257
|
+
label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -10 } : void 0,
|
|
32258
|
+
tickFormatter: xAxisTickFormatter,
|
|
32259
|
+
tick: { fontSize: 12, fill: axisTickFillColor },
|
|
32260
|
+
stroke: axisStrokeColor
|
|
32261
|
+
}
|
|
32262
|
+
),
|
|
32263
|
+
/* @__PURE__ */ jsx(
|
|
32264
|
+
YAxis,
|
|
32265
|
+
{
|
|
32266
|
+
label: yAxisLabel ? { value: yAxisLabel, angle: -90, position: "insideLeft" } : void 0,
|
|
32267
|
+
tickFormatter: yAxisTickFormatter,
|
|
32268
|
+
domain: yAxisDomain,
|
|
32269
|
+
tick: { fontSize: 12, fill: axisTickFillColor },
|
|
32270
|
+
stroke: axisStrokeColor
|
|
32271
|
+
}
|
|
32272
|
+
),
|
|
32273
|
+
showTooltip && /* @__PURE__ */ jsx(
|
|
32274
|
+
Tooltip,
|
|
32275
|
+
{
|
|
32276
|
+
formatter: tooltipFormatter || defaultTooltipFormatter,
|
|
32277
|
+
labelFormatter: tooltipLabelFormatter,
|
|
32278
|
+
itemStyle: { color: "#111827" },
|
|
32279
|
+
cursor: { strokeDasharray: "3 3" }
|
|
32280
|
+
}
|
|
32281
|
+
),
|
|
32282
|
+
showLegend && /* @__PURE__ */ jsx(Legend, { payload: legendPayload }),
|
|
32283
|
+
lines.map((lineConfig, index) => {
|
|
32284
|
+
const lineProps = {
|
|
32285
|
+
...lineConfig,
|
|
32286
|
+
key: lineConfig.dataKey,
|
|
32287
|
+
type: lineConfig.type || "monotone",
|
|
32288
|
+
stroke: lineConfig.stroke || defaultColors[index % defaultColors.length],
|
|
32289
|
+
activeDot: lineConfig.activeDot !== void 0 ? lineConfig.activeDot : { r: 6 },
|
|
32290
|
+
isAnimationActive: true,
|
|
32291
|
+
animationDuration: 1500,
|
|
32292
|
+
animationBegin: 300
|
|
32293
|
+
};
|
|
32294
|
+
return /* @__PURE__ */ jsx(Line, { ...lineProps, children: lineConfig.labelList && /* @__PURE__ */ jsx(
|
|
32295
|
+
LabelList,
|
|
32296
|
+
{
|
|
32297
|
+
dataKey: lineConfig.dataKey,
|
|
32298
|
+
position: "top",
|
|
32299
|
+
formatter: (value) => formatNumber(value),
|
|
32300
|
+
...typeof lineConfig.labelList === "object" ? lineConfig.labelList : {}
|
|
32301
|
+
}
|
|
32302
|
+
) });
|
|
32303
|
+
})
|
|
32304
|
+
]
|
|
32305
|
+
},
|
|
32306
|
+
hasValidData ? "valid" : "empty"
|
|
32307
|
+
);
|
|
32280
32308
|
if (responsive) {
|
|
32281
32309
|
return /* @__PURE__ */ jsx(
|
|
32282
32310
|
"div",
|
|
@@ -32284,11 +32312,20 @@ var LineChartComponent = ({
|
|
|
32284
32312
|
ref: containerRef,
|
|
32285
32313
|
className: clsx(fillContainer ? "w-full h-full" : "w-full h-auto", className),
|
|
32286
32314
|
style: fillContainer ? { height: "100%", minHeight: "50px", minWidth: "100px" } : { aspectRatio: `${aspect}/1`, minHeight: "50px", minWidth: "100px" },
|
|
32287
|
-
children:
|
|
32315
|
+
children: /* @__PURE__ */ jsx(
|
|
32316
|
+
motion.div,
|
|
32317
|
+
{
|
|
32318
|
+
initial: { opacity: 0 },
|
|
32319
|
+
animate: { opacity: 1 },
|
|
32320
|
+
transition: { duration: 0.5 },
|
|
32321
|
+
className: "w-full h-full",
|
|
32322
|
+
children: dimensions.width > 0 && dimensions.height > 0 && renderChartContent(dimensions.width, dimensions.height)
|
|
32323
|
+
}
|
|
32324
|
+
)
|
|
32288
32325
|
}
|
|
32289
32326
|
);
|
|
32290
32327
|
}
|
|
32291
|
-
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children:
|
|
32328
|
+
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
|
|
32292
32329
|
};
|
|
32293
32330
|
var LineChart = React141__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
32294
32331
|
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect || JSON.stringify(prevProps.yAxisDomain) !== JSON.stringify(nextProps.yAxisDomain)) {
|
|
@@ -32556,14 +32593,35 @@ var CycleTimeOverTimeChart = ({
|
|
|
32556
32593
|
}) => {
|
|
32557
32594
|
const MAX_DATA_POINTS = 40;
|
|
32558
32595
|
const containerRef = React141__default.useRef(null);
|
|
32559
|
-
const [
|
|
32560
|
-
const
|
|
32596
|
+
const [dimensions, setDimensions] = React141__default.useState({ width: 0, height: 0 });
|
|
32597
|
+
const [hasValidData, setHasValidData] = React141__default.useState(false);
|
|
32598
|
+
React141__default.useEffect(() => {
|
|
32599
|
+
const currentHasValidData = data && data.some((val) => val !== null && val > 0);
|
|
32600
|
+
if (currentHasValidData && !hasValidData) {
|
|
32601
|
+
setHasValidData(true);
|
|
32602
|
+
}
|
|
32603
|
+
}, [data, hasValidData]);
|
|
32604
|
+
React141__default.useEffect(() => {
|
|
32605
|
+
if (!containerRef.current) return;
|
|
32606
|
+
const observer = new ResizeObserver((entries) => {
|
|
32607
|
+
const entry = entries[0];
|
|
32608
|
+
if (entry) {
|
|
32609
|
+
setDimensions({
|
|
32610
|
+
width: entry.contentRect.width,
|
|
32611
|
+
height: entry.contentRect.height
|
|
32612
|
+
});
|
|
32613
|
+
}
|
|
32614
|
+
});
|
|
32615
|
+
observer.observe(containerRef.current);
|
|
32616
|
+
return () => observer.disconnect();
|
|
32617
|
+
}, []);
|
|
32618
|
+
const parseTimeToMinutes4 = (value) => {
|
|
32561
32619
|
const [hours, minutes] = value.split(":").map(Number);
|
|
32562
32620
|
if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return 0;
|
|
32563
32621
|
return hours * 60 + minutes;
|
|
32564
32622
|
};
|
|
32565
32623
|
const formatHourLabel = (slotIndex) => {
|
|
32566
|
-
const baseMinutes =
|
|
32624
|
+
const baseMinutes = parseTimeToMinutes4(shiftStart);
|
|
32567
32625
|
const absoluteMinutes = baseMinutes + slotIndex * 60;
|
|
32568
32626
|
const hour24 = Math.floor(absoluteMinutes % (24 * 60) / 60);
|
|
32569
32627
|
const ampm = hour24 >= 12 ? "PM" : "AM";
|
|
@@ -32582,52 +32640,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32582
32640
|
const displayData = getDisplayData(data);
|
|
32583
32641
|
const DURATION = displayData.length;
|
|
32584
32642
|
const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
|
|
32585
|
-
const [animatedDatasetKey, setAnimatedDatasetKey] = React141__default.useState(null);
|
|
32586
|
-
const shouldAnimate = animatedDatasetKey !== effectiveDatasetKey;
|
|
32587
|
-
const handleAnimationEnd = React141__default.useCallback(() => {
|
|
32588
|
-
setAnimatedDatasetKey((currentValue) => currentValue === effectiveDatasetKey ? currentValue : effectiveDatasetKey);
|
|
32589
|
-
}, [effectiveDatasetKey]);
|
|
32590
32643
|
const finalData = displayData;
|
|
32591
|
-
React141__default.useEffect(() => {
|
|
32592
|
-
const containerNode = containerRef.current;
|
|
32593
|
-
if (!containerNode) {
|
|
32594
|
-
setContainerReady(true);
|
|
32595
|
-
return void 0;
|
|
32596
|
-
}
|
|
32597
|
-
let frameId = null;
|
|
32598
|
-
let resizeObserver = null;
|
|
32599
|
-
const checkContainerDimensions = () => {
|
|
32600
|
-
const rect = containerNode.getBoundingClientRect();
|
|
32601
|
-
const isReady = rect.width > 0 && rect.height > 0;
|
|
32602
|
-
if (isReady) {
|
|
32603
|
-
setContainerReady(true);
|
|
32604
|
-
}
|
|
32605
|
-
return isReady;
|
|
32606
|
-
};
|
|
32607
|
-
if (checkContainerDimensions()) {
|
|
32608
|
-
return void 0;
|
|
32609
|
-
}
|
|
32610
|
-
frameId = window.requestAnimationFrame(() => {
|
|
32611
|
-
checkContainerDimensions();
|
|
32612
|
-
});
|
|
32613
|
-
if (typeof ResizeObserver !== "undefined") {
|
|
32614
|
-
resizeObserver = new ResizeObserver(() => {
|
|
32615
|
-
if (checkContainerDimensions() && resizeObserver) {
|
|
32616
|
-
resizeObserver.disconnect();
|
|
32617
|
-
resizeObserver = null;
|
|
32618
|
-
}
|
|
32619
|
-
});
|
|
32620
|
-
resizeObserver.observe(containerNode);
|
|
32621
|
-
} else {
|
|
32622
|
-
setContainerReady(true);
|
|
32623
|
-
}
|
|
32624
|
-
return () => {
|
|
32625
|
-
if (frameId !== null) {
|
|
32626
|
-
window.cancelAnimationFrame(frameId);
|
|
32627
|
-
}
|
|
32628
|
-
resizeObserver?.disconnect();
|
|
32629
|
-
};
|
|
32630
|
-
}, []);
|
|
32631
32644
|
const labelInterval = React141__default.useMemo(() => {
|
|
32632
32645
|
if (xAxisMode === "hourly") {
|
|
32633
32646
|
return Math.max(1, Math.ceil(DURATION / 8));
|
|
@@ -32669,16 +32682,162 @@ var CycleTimeOverTimeChart = ({
|
|
|
32669
32682
|
return `${minutes} minutes ${seconds} seconds ago`;
|
|
32670
32683
|
}
|
|
32671
32684
|
};
|
|
32685
|
+
const getNumericValue = React141__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
|
|
32686
|
+
const renderChartTooltip = React141__default.useCallback((tooltipProps) => {
|
|
32687
|
+
const { active, payload } = tooltipProps;
|
|
32688
|
+
if (!active || !Array.isArray(payload) || payload.length === 0) {
|
|
32689
|
+
return null;
|
|
32690
|
+
}
|
|
32691
|
+
const visibleEntries = payload.filter((entry) => getNumericValue(entry.value) !== null);
|
|
32692
|
+
if (!visibleEntries.length) {
|
|
32693
|
+
return null;
|
|
32694
|
+
}
|
|
32695
|
+
return /* @__PURE__ */ jsxs(
|
|
32696
|
+
"div",
|
|
32697
|
+
{
|
|
32698
|
+
style: {
|
|
32699
|
+
backgroundColor: "white",
|
|
32700
|
+
border: "none",
|
|
32701
|
+
borderRadius: "8px",
|
|
32702
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.1)",
|
|
32703
|
+
padding: "8px 12px",
|
|
32704
|
+
fontSize: "13px"
|
|
32705
|
+
},
|
|
32706
|
+
children: [
|
|
32707
|
+
/* @__PURE__ */ jsx(
|
|
32708
|
+
"div",
|
|
32709
|
+
{
|
|
32710
|
+
style: {
|
|
32711
|
+
color: "#374151",
|
|
32712
|
+
fontWeight: 600,
|
|
32713
|
+
marginBottom: "4px"
|
|
32714
|
+
},
|
|
32715
|
+
children: payload[0]?.payload?.tooltip || ""
|
|
32716
|
+
}
|
|
32717
|
+
),
|
|
32718
|
+
visibleEntries.map((entry) => {
|
|
32719
|
+
const numericValue = getNumericValue(entry.value);
|
|
32720
|
+
if (numericValue === null) {
|
|
32721
|
+
return null;
|
|
32722
|
+
}
|
|
32723
|
+
return /* @__PURE__ */ jsx(
|
|
32724
|
+
"div",
|
|
32725
|
+
{
|
|
32726
|
+
style: {
|
|
32727
|
+
color: "#4B5563",
|
|
32728
|
+
padding: "2px 0"
|
|
32729
|
+
},
|
|
32730
|
+
children: entry.name === "idleMinutes" ? `Idle Time: ${numericValue.toFixed(0)} minutes` : `Cycle Time: ${numericValue.toFixed(1)} seconds`
|
|
32731
|
+
},
|
|
32732
|
+
`${entry.name}-${numericValue}`
|
|
32733
|
+
);
|
|
32734
|
+
})
|
|
32735
|
+
]
|
|
32736
|
+
}
|
|
32737
|
+
);
|
|
32738
|
+
}, [getNumericValue]);
|
|
32739
|
+
const renderCycleDot = React141__default.useCallback((props) => {
|
|
32740
|
+
const { cx: cx2, cy, payload } = props;
|
|
32741
|
+
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
32742
|
+
if (cycleTime === null) {
|
|
32743
|
+
return /* @__PURE__ */ jsx("g", {});
|
|
32744
|
+
}
|
|
32745
|
+
return /* @__PURE__ */ jsx(
|
|
32746
|
+
"circle",
|
|
32747
|
+
{
|
|
32748
|
+
cx: cx2,
|
|
32749
|
+
cy,
|
|
32750
|
+
r: 4,
|
|
32751
|
+
fill: cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32752
|
+
stroke: "#fff",
|
|
32753
|
+
strokeWidth: 1,
|
|
32754
|
+
style: {
|
|
32755
|
+
filter: "brightness(1)",
|
|
32756
|
+
transition: "filter 0.3s ease, transform 0.3s ease",
|
|
32757
|
+
cursor: "pointer"
|
|
32758
|
+
},
|
|
32759
|
+
onMouseEnter: (e) => {
|
|
32760
|
+
const target = e.target;
|
|
32761
|
+
target.style.filter = "brightness(1.2)";
|
|
32762
|
+
target.style.transform = "scale(1.2)";
|
|
32763
|
+
},
|
|
32764
|
+
onMouseLeave: (e) => {
|
|
32765
|
+
const target = e.target;
|
|
32766
|
+
target.style.filter = "brightness(1)";
|
|
32767
|
+
target.style.transform = "scale(1)";
|
|
32768
|
+
}
|
|
32769
|
+
}
|
|
32770
|
+
);
|
|
32771
|
+
}, [getNumericValue, idealCycleTime]);
|
|
32772
|
+
const renderCycleActiveDot = React141__default.useCallback((props) => {
|
|
32773
|
+
const { cx: cx2, cy, payload } = props;
|
|
32774
|
+
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
32775
|
+
if (cycleTime === null) {
|
|
32776
|
+
return /* @__PURE__ */ jsx("g", {});
|
|
32777
|
+
}
|
|
32778
|
+
return /* @__PURE__ */ jsx(
|
|
32779
|
+
"circle",
|
|
32780
|
+
{
|
|
32781
|
+
cx: cx2,
|
|
32782
|
+
cy,
|
|
32783
|
+
r: 6,
|
|
32784
|
+
fill: cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32785
|
+
stroke: "#fff",
|
|
32786
|
+
strokeWidth: 2,
|
|
32787
|
+
style: {
|
|
32788
|
+
filter: "drop-shadow(0 0 2px rgba(0,0,0,0.2))"
|
|
32789
|
+
}
|
|
32790
|
+
}
|
|
32791
|
+
);
|
|
32792
|
+
}, [getNumericValue, idealCycleTime]);
|
|
32793
|
+
const renderIdleDot = React141__default.useCallback((props) => {
|
|
32794
|
+
const { cx: cx2, cy, payload } = props;
|
|
32795
|
+
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
32796
|
+
if (idleMinutes === null) {
|
|
32797
|
+
return /* @__PURE__ */ jsx("g", {});
|
|
32798
|
+
}
|
|
32799
|
+
return /* @__PURE__ */ jsx(
|
|
32800
|
+
"circle",
|
|
32801
|
+
{
|
|
32802
|
+
cx: cx2,
|
|
32803
|
+
cy,
|
|
32804
|
+
r: 4,
|
|
32805
|
+
fill: "#f59e0b",
|
|
32806
|
+
stroke: "#fff",
|
|
32807
|
+
strokeWidth: 1
|
|
32808
|
+
}
|
|
32809
|
+
);
|
|
32810
|
+
}, [getNumericValue]);
|
|
32811
|
+
const renderIdleActiveDot = React141__default.useCallback((props) => {
|
|
32812
|
+
const { cx: cx2, cy, payload } = props;
|
|
32813
|
+
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
32814
|
+
if (idleMinutes === null) {
|
|
32815
|
+
return /* @__PURE__ */ jsx("g", {});
|
|
32816
|
+
}
|
|
32817
|
+
return /* @__PURE__ */ jsx(
|
|
32818
|
+
"circle",
|
|
32819
|
+
{
|
|
32820
|
+
cx: cx2,
|
|
32821
|
+
cy,
|
|
32822
|
+
r: 6,
|
|
32823
|
+
fill: "#f59e0b",
|
|
32824
|
+
stroke: "#fff",
|
|
32825
|
+
strokeWidth: 2
|
|
32826
|
+
}
|
|
32827
|
+
);
|
|
32828
|
+
}, [getNumericValue]);
|
|
32672
32829
|
const chartData = React141__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
|
|
32830
|
+
const cycleTime = getNumericValue(finalData[i]);
|
|
32831
|
+
const idleMinutes = showIdleTime ? getNumericValue(idleTimeData[i]) : null;
|
|
32673
32832
|
return {
|
|
32674
32833
|
timeIndex: i,
|
|
32675
32834
|
label: formatTimeLabel(i),
|
|
32676
32835
|
tooltip: formatTooltipTime(i),
|
|
32677
|
-
cycleTime
|
|
32678
|
-
idleMinutes
|
|
32679
|
-
color:
|
|
32836
|
+
cycleTime,
|
|
32837
|
+
idleMinutes,
|
|
32838
|
+
color: cycleTime !== null && cycleTime <= idealCycleTime ? "#00AB45" : "#E34329"
|
|
32680
32839
|
};
|
|
32681
|
-
}), [DURATION, finalData, showIdleTime, idleTimeData, idealCycleTime]);
|
|
32840
|
+
}), [DURATION, finalData, showIdleTime, idleTimeData, idealCycleTime, getNumericValue]);
|
|
32682
32841
|
const renderLegend = () => {
|
|
32683
32842
|
if (!showIdleTime) return null;
|
|
32684
32843
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-start text-[10px] font-bold text-gray-500 mb-6 tracking-[0.05em] gap-5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
@@ -32689,215 +32848,154 @@ var CycleTimeOverTimeChart = ({
|
|
|
32689
32848
|
return /* @__PURE__ */ jsxs(
|
|
32690
32849
|
"div",
|
|
32691
32850
|
{
|
|
32692
|
-
ref: containerRef,
|
|
32693
32851
|
className: `w-full h-full min-w-0 flex flex-col relative pb-2 ${className}`,
|
|
32694
32852
|
style: { minHeight: "200px", minWidth: 0 },
|
|
32695
32853
|
children: [
|
|
32696
32854
|
renderLegend(),
|
|
32697
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 w-full",
|
|
32698
|
-
|
|
32855
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 w-full", ref: containerRef, children: /* @__PURE__ */ jsx(
|
|
32856
|
+
motion.div,
|
|
32699
32857
|
{
|
|
32700
|
-
|
|
32701
|
-
|
|
32702
|
-
|
|
32703
|
-
|
|
32704
|
-
|
|
32705
|
-
|
|
32706
|
-
|
|
32707
|
-
|
|
32708
|
-
|
|
32709
|
-
|
|
32710
|
-
|
|
32711
|
-
|
|
32712
|
-
|
|
32713
|
-
|
|
32714
|
-
|
|
32715
|
-
|
|
32716
|
-
|
|
32717
|
-
|
|
32718
|
-
|
|
32719
|
-
|
|
32720
|
-
|
|
32721
|
-
|
|
32722
|
-
|
|
32723
|
-
|
|
32724
|
-
|
|
32725
|
-
|
|
32726
|
-
|
|
32727
|
-
|
|
32728
|
-
ticks: [0, idealCycleTime, ...Array.from({ length: 4 }, (_, i) => (i + 1) * Math.ceil(idealCycleTime / 2))].sort((a, b) => a - b),
|
|
32729
|
-
tickFormatter: (value) => String(value),
|
|
32730
|
-
tick: (props) => {
|
|
32731
|
-
const { x, y, payload } = props;
|
|
32732
|
-
const displayValue = typeof payload.value === "number" ? payload.value.toFixed(1) : String(payload.value);
|
|
32733
|
-
return /* @__PURE__ */ jsx("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ jsx(
|
|
32734
|
-
"text",
|
|
32735
|
-
{
|
|
32736
|
-
x: 0,
|
|
32737
|
-
y: 0,
|
|
32738
|
-
dy: 4,
|
|
32739
|
-
textAnchor: "end",
|
|
32740
|
-
fill: payload.value === idealCycleTime ? "#E34329" : "#666",
|
|
32741
|
-
fontSize: 12,
|
|
32742
|
-
fontWeight: payload.value === idealCycleTime ? "bold" : "normal",
|
|
32743
|
-
children: displayValue
|
|
32744
|
-
},
|
|
32745
|
-
`tick-${payload.value}-${x}-${y}`
|
|
32746
|
-
) });
|
|
32747
|
-
}
|
|
32748
|
-
}
|
|
32749
|
-
),
|
|
32750
|
-
showIdleTime && /* @__PURE__ */ jsx(
|
|
32751
|
-
YAxis,
|
|
32752
|
-
{
|
|
32753
|
-
yAxisId: "idle",
|
|
32754
|
-
orientation: "right",
|
|
32755
|
-
tickMargin: 8,
|
|
32756
|
-
width: 35,
|
|
32757
|
-
domain: [0, 60],
|
|
32758
|
-
tickFormatter: (value) => `${value}m`,
|
|
32759
|
-
tick: { fontSize: 11, fill: "#f59e0b" },
|
|
32760
|
-
axisLine: false,
|
|
32761
|
-
tickLine: false
|
|
32762
|
-
}
|
|
32763
|
-
),
|
|
32764
|
-
/* @__PURE__ */ jsx(
|
|
32765
|
-
Tooltip,
|
|
32766
|
-
{
|
|
32767
|
-
cursor: { stroke: "#E5E7EB", strokeWidth: 1 },
|
|
32768
|
-
contentStyle: {
|
|
32769
|
-
backgroundColor: "white",
|
|
32770
|
-
border: "none",
|
|
32771
|
-
borderRadius: "8px",
|
|
32772
|
-
boxShadow: "0 4px 12px rgba(0,0,0,0.1)",
|
|
32773
|
-
padding: "8px 12px",
|
|
32774
|
-
fontSize: "13px"
|
|
32775
|
-
},
|
|
32776
|
-
labelStyle: {
|
|
32777
|
-
color: "#374151",
|
|
32778
|
-
fontWeight: 600,
|
|
32779
|
-
marginBottom: "4px"
|
|
32780
|
-
},
|
|
32781
|
-
itemStyle: {
|
|
32782
|
-
color: "#4B5563",
|
|
32783
|
-
padding: "2px 0"
|
|
32784
|
-
},
|
|
32785
|
-
labelFormatter: (label, payload) => {
|
|
32786
|
-
if (payload && payload[0]) {
|
|
32787
|
-
return payload[0].payload.tooltip;
|
|
32788
|
-
}
|
|
32789
|
-
return label;
|
|
32790
|
-
},
|
|
32791
|
-
formatter: (value, name) => {
|
|
32792
|
-
const numValue = typeof value === "number" ? value : Number(value);
|
|
32793
|
-
if (name === "idleMinutes") {
|
|
32794
|
-
return [`${numValue.toFixed(0)} minutes`, "Idle Time"];
|
|
32858
|
+
initial: { opacity: 0 },
|
|
32859
|
+
animate: { opacity: 1 },
|
|
32860
|
+
transition: { duration: 0.5 },
|
|
32861
|
+
className: "w-full h-full",
|
|
32862
|
+
children: dimensions.width > 0 && dimensions.height > 0 && /* @__PURE__ */ jsxs(
|
|
32863
|
+
LineChart$1,
|
|
32864
|
+
{
|
|
32865
|
+
width: dimensions.width,
|
|
32866
|
+
height: dimensions.height,
|
|
32867
|
+
data: chartData,
|
|
32868
|
+
margin: {
|
|
32869
|
+
top: 5,
|
|
32870
|
+
right: 30,
|
|
32871
|
+
bottom: 25,
|
|
32872
|
+
left: 10
|
|
32873
|
+
},
|
|
32874
|
+
children: [
|
|
32875
|
+
/* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", vertical: false }),
|
|
32876
|
+
/* @__PURE__ */ jsx(
|
|
32877
|
+
XAxis,
|
|
32878
|
+
{
|
|
32879
|
+
dataKey: "label",
|
|
32880
|
+
tick: { fontSize: 11 },
|
|
32881
|
+
interval: 0,
|
|
32882
|
+
angle: xAxisMode === "hourly" ? 0 : -30,
|
|
32883
|
+
textAnchor: xAxisMode === "hourly" ? "middle" : "end",
|
|
32884
|
+
tickMargin: xAxisMode === "hourly" ? 8 : 15,
|
|
32885
|
+
height: xAxisMode === "hourly" ? 40 : 60
|
|
32795
32886
|
}
|
|
32796
|
-
|
|
32797
|
-
|
|
32798
|
-
|
|
32799
|
-
|
|
32800
|
-
|
|
32801
|
-
|
|
32802
|
-
|
|
32803
|
-
|
|
32804
|
-
|
|
32805
|
-
|
|
32806
|
-
|
|
32807
|
-
|
|
32808
|
-
|
|
32809
|
-
|
|
32810
|
-
|
|
32811
|
-
|
|
32812
|
-
|
|
32813
|
-
|
|
32814
|
-
|
|
32815
|
-
|
|
32816
|
-
|
|
32817
|
-
|
|
32818
|
-
|
|
32819
|
-
|
|
32820
|
-
|
|
32821
|
-
|
|
32822
|
-
|
|
32823
|
-
dataKey: "cycleTime",
|
|
32824
|
-
stroke: "#3B82F6",
|
|
32825
|
-
strokeWidth: 2,
|
|
32826
|
-
dot: (props) => {
|
|
32827
|
-
const { cx: cx2, cy, payload } = props;
|
|
32828
|
-
return /* @__PURE__ */ jsx(
|
|
32829
|
-
"circle",
|
|
32830
|
-
{
|
|
32831
|
-
cx: cx2,
|
|
32832
|
-
cy,
|
|
32833
|
-
r: 4,
|
|
32834
|
-
fill: payload.cycleTime <= idealCycleTime ? "#00AB45" : "#E34329",
|
|
32835
|
-
stroke: "#fff",
|
|
32836
|
-
strokeWidth: 1,
|
|
32837
|
-
style: {
|
|
32838
|
-
filter: "brightness(1)",
|
|
32839
|
-
transition: "filter 0.3s ease, transform 0.3s ease",
|
|
32840
|
-
cursor: "pointer"
|
|
32841
|
-
},
|
|
32842
|
-
onMouseEnter: (e) => {
|
|
32843
|
-
const target = e.target;
|
|
32844
|
-
target.style.filter = "brightness(1.2)";
|
|
32845
|
-
target.style.transform = "scale(1.2)";
|
|
32846
|
-
},
|
|
32847
|
-
onMouseLeave: (e) => {
|
|
32848
|
-
const target = e.target;
|
|
32849
|
-
target.style.filter = "brightness(1)";
|
|
32850
|
-
target.style.transform = "scale(1)";
|
|
32851
|
-
}
|
|
32887
|
+
),
|
|
32888
|
+
/* @__PURE__ */ jsx(
|
|
32889
|
+
YAxis,
|
|
32890
|
+
{
|
|
32891
|
+
tickMargin: 8,
|
|
32892
|
+
width: 45,
|
|
32893
|
+
yAxisId: "cycle",
|
|
32894
|
+
domain: ["auto", "auto"],
|
|
32895
|
+
ticks: [0, idealCycleTime, ...Array.from({ length: 4 }, (_, i) => (i + 1) * Math.ceil(idealCycleTime / 2))].sort((a, b) => a - b),
|
|
32896
|
+
tickFormatter: (value) => String(value),
|
|
32897
|
+
tick: (props) => {
|
|
32898
|
+
const { x, y, payload } = props;
|
|
32899
|
+
const displayValue = typeof payload.value === "number" ? payload.value.toFixed(1) : String(payload.value);
|
|
32900
|
+
return /* @__PURE__ */ jsx("g", { transform: `translate(${x},${y})`, children: /* @__PURE__ */ jsx(
|
|
32901
|
+
"text",
|
|
32902
|
+
{
|
|
32903
|
+
x: 0,
|
|
32904
|
+
y: 0,
|
|
32905
|
+
dy: 4,
|
|
32906
|
+
textAnchor: "end",
|
|
32907
|
+
fill: payload.value === idealCycleTime ? "#E34329" : "#666",
|
|
32908
|
+
fontSize: 12,
|
|
32909
|
+
fontWeight: payload.value === idealCycleTime ? "bold" : "normal",
|
|
32910
|
+
children: displayValue
|
|
32911
|
+
},
|
|
32912
|
+
`tick-${payload.value}-${x}-${y}`
|
|
32913
|
+
) });
|
|
32852
32914
|
}
|
|
32853
|
-
|
|
32854
|
-
|
|
32855
|
-
|
|
32856
|
-
|
|
32857
|
-
|
|
32858
|
-
"
|
|
32859
|
-
|
|
32860
|
-
|
|
32861
|
-
|
|
32862
|
-
|
|
32863
|
-
|
|
32864
|
-
|
|
32865
|
-
|
|
32866
|
-
|
|
32867
|
-
|
|
32868
|
-
|
|
32915
|
+
}
|
|
32916
|
+
),
|
|
32917
|
+
showIdleTime && /* @__PURE__ */ jsx(
|
|
32918
|
+
YAxis,
|
|
32919
|
+
{
|
|
32920
|
+
yAxisId: "idle",
|
|
32921
|
+
orientation: "right",
|
|
32922
|
+
tickMargin: 8,
|
|
32923
|
+
width: 35,
|
|
32924
|
+
domain: [0, 60],
|
|
32925
|
+
tickFormatter: (value) => `${value}m`,
|
|
32926
|
+
tick: { fontSize: 11, fill: "#f59e0b" },
|
|
32927
|
+
axisLine: false,
|
|
32928
|
+
tickLine: false
|
|
32929
|
+
}
|
|
32930
|
+
),
|
|
32931
|
+
/* @__PURE__ */ jsx(
|
|
32932
|
+
Tooltip,
|
|
32933
|
+
{
|
|
32934
|
+
cursor: { stroke: "#E5E7EB", strokeWidth: 1 },
|
|
32935
|
+
content: renderChartTooltip,
|
|
32936
|
+
animationDuration: 200
|
|
32937
|
+
}
|
|
32938
|
+
),
|
|
32939
|
+
/* @__PURE__ */ jsx(
|
|
32940
|
+
ReferenceLine,
|
|
32941
|
+
{
|
|
32942
|
+
y: idealCycleTime,
|
|
32943
|
+
yAxisId: "cycle",
|
|
32944
|
+
stroke: "#E34329",
|
|
32945
|
+
strokeDasharray: "3 3",
|
|
32946
|
+
strokeWidth: 2,
|
|
32947
|
+
label: {
|
|
32948
|
+
position: "right",
|
|
32949
|
+
value: `${idealCycleTime.toFixed(1)}s`,
|
|
32950
|
+
fill: "#E34329",
|
|
32951
|
+
fontSize: 12,
|
|
32952
|
+
fontWeight: 500
|
|
32869
32953
|
}
|
|
32870
|
-
|
|
32871
|
-
|
|
32872
|
-
|
|
32873
|
-
|
|
32874
|
-
|
|
32875
|
-
|
|
32876
|
-
|
|
32877
|
-
|
|
32878
|
-
|
|
32879
|
-
|
|
32880
|
-
|
|
32881
|
-
|
|
32882
|
-
|
|
32883
|
-
|
|
32884
|
-
|
|
32885
|
-
|
|
32886
|
-
|
|
32887
|
-
|
|
32888
|
-
|
|
32889
|
-
|
|
32890
|
-
|
|
32891
|
-
|
|
32892
|
-
|
|
32893
|
-
|
|
32894
|
-
|
|
32895
|
-
|
|
32896
|
-
|
|
32897
|
-
|
|
32898
|
-
|
|
32954
|
+
}
|
|
32955
|
+
),
|
|
32956
|
+
/* @__PURE__ */ jsx(
|
|
32957
|
+
Line,
|
|
32958
|
+
{
|
|
32959
|
+
type: "monotone",
|
|
32960
|
+
yAxisId: "cycle",
|
|
32961
|
+
dataKey: "cycleTime",
|
|
32962
|
+
stroke: "#3B82F6",
|
|
32963
|
+
strokeWidth: 2,
|
|
32964
|
+
connectNulls: false,
|
|
32965
|
+
dot: renderCycleDot,
|
|
32966
|
+
activeDot: renderCycleActiveDot,
|
|
32967
|
+
isAnimationActive: true,
|
|
32968
|
+
animationBegin: 300,
|
|
32969
|
+
animationDuration: 1500,
|
|
32970
|
+
animationEasing: "ease-out"
|
|
32971
|
+
},
|
|
32972
|
+
`${effectiveDatasetKey}:cycle`
|
|
32973
|
+
),
|
|
32974
|
+
showIdleTime && /* @__PURE__ */ jsx(
|
|
32975
|
+
Line,
|
|
32976
|
+
{
|
|
32977
|
+
type: "monotone",
|
|
32978
|
+
yAxisId: "idle",
|
|
32979
|
+
dataKey: "idleMinutes",
|
|
32980
|
+
stroke: "#f59e0b",
|
|
32981
|
+
strokeWidth: 2,
|
|
32982
|
+
strokeDasharray: "4 4",
|
|
32983
|
+
connectNulls: false,
|
|
32984
|
+
dot: renderIdleDot,
|
|
32985
|
+
activeDot: renderIdleActiveDot,
|
|
32986
|
+
isAnimationActive: true,
|
|
32987
|
+
animationBegin: 300,
|
|
32988
|
+
animationDuration: 1500,
|
|
32989
|
+
animationEasing: "ease-out"
|
|
32990
|
+
},
|
|
32991
|
+
`${effectiveDatasetKey}:idle`
|
|
32992
|
+
)
|
|
32993
|
+
]
|
|
32994
|
+
},
|
|
32995
|
+
hasValidData ? "valid" : "empty"
|
|
32996
|
+
)
|
|
32899
32997
|
}
|
|
32900
|
-
) })
|
|
32998
|
+
) })
|
|
32901
32999
|
]
|
|
32902
33000
|
}
|
|
32903
33001
|
);
|
|
@@ -33747,10 +33845,10 @@ var HourlyOutputChart = React141__default.memo(HourlyOutputChartComponent, (prev
|
|
|
33747
33845
|
HourlyOutputChart.displayName = "HourlyOutputChart";
|
|
33748
33846
|
|
|
33749
33847
|
// src/components/dashboard/grid/videoGridMetricUtils.ts
|
|
33750
|
-
var VIDEO_GRID_LEGEND_LABEL = "
|
|
33848
|
+
var VIDEO_GRID_LEGEND_LABEL = "7 Minute Efficiency";
|
|
33751
33849
|
var MAP_GRID_LEGEND_LABEL = "Efficiency";
|
|
33752
|
-
var MIXED_VIDEO_GRID_LEGEND_LABEL = "
|
|
33753
|
-
var
|
|
33850
|
+
var MIXED_VIDEO_GRID_LEGEND_LABEL = "Efficiency";
|
|
33851
|
+
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
33754
33852
|
var isVideoGridRecentFlowEnabled = (workspace) => isRecentFlowVideoGridMetricMode(
|
|
33755
33853
|
workspace.video_grid_metric_mode,
|
|
33756
33854
|
workspace.assembly_enabled === true
|
|
@@ -33759,11 +33857,11 @@ var isVideoGridWipGated = (workspace) => isWipGatedVideoGridMetricMode(
|
|
|
33759
33857
|
workspace.video_grid_metric_mode,
|
|
33760
33858
|
workspace.assembly_enabled === true
|
|
33761
33859
|
);
|
|
33762
|
-
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) &&
|
|
33860
|
+
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) && isFiniteNumber(workspace.recent_flow_percent);
|
|
33763
33861
|
var isVideoGridRecentFlowUnavailable = (workspace) => isVideoGridRecentFlowEnabled(workspace) && !hasVideoGridRecentFlow(workspace);
|
|
33764
33862
|
var getVideoGridMetricValue = (workspace) => {
|
|
33765
33863
|
const recentFlowPercent = workspace.recent_flow_percent;
|
|
33766
|
-
if (hasVideoGridRecentFlow(workspace) &&
|
|
33864
|
+
if (hasVideoGridRecentFlow(workspace) && isFiniteNumber(recentFlowPercent)) {
|
|
33767
33865
|
return recentFlowPercent;
|
|
33768
33866
|
}
|
|
33769
33867
|
if (isVideoGridRecentFlowUnavailable(workspace)) {
|
|
@@ -33774,7 +33872,7 @@ var getVideoGridMetricValue = (workspace) => {
|
|
|
33774
33872
|
var hasIncomingWipMapping = (workspace) => Boolean(workspace.incoming_wip_buffer_name);
|
|
33775
33873
|
var getVideoGridBaseColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
33776
33874
|
const metricValue = getVideoGridMetricValue(workspace);
|
|
33777
|
-
if (!
|
|
33875
|
+
if (!isFiniteNumber(metricValue)) {
|
|
33778
33876
|
return "neutral";
|
|
33779
33877
|
}
|
|
33780
33878
|
return getEfficiencyColor(metricValue, legend);
|
|
@@ -33789,7 +33887,7 @@ var isLowWipGreenOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
|
33789
33887
|
if (!hasIncomingWipMapping(workspace)) {
|
|
33790
33888
|
return false;
|
|
33791
33889
|
}
|
|
33792
|
-
return
|
|
33890
|
+
return isFiniteNumber(workspace.incoming_wip_current) && workspace.incoming_wip_current <= 1;
|
|
33793
33891
|
};
|
|
33794
33892
|
var toMinuteBucket = (minuteBucket) => Number.isFinite(minuteBucket) ? Math.floor(minuteBucket) : Math.floor(Date.now() / 6e4);
|
|
33795
33893
|
var getEffectiveFlowMinuteBucket = (workspace) => {
|
|
@@ -33831,7 +33929,7 @@ var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) =>
|
|
|
33831
33929
|
if (!hasIncomingWipMapping(workspace)) {
|
|
33832
33930
|
return baseColor;
|
|
33833
33931
|
}
|
|
33834
|
-
if (!
|
|
33932
|
+
if (!isFiniteNumber(workspace.incoming_wip_current)) {
|
|
33835
33933
|
return "neutral";
|
|
33836
33934
|
}
|
|
33837
33935
|
if (isLowWipGreenOverride(workspace, legend)) {
|
|
@@ -34023,7 +34121,7 @@ var VideoCard = React141__default.memo(({
|
|
|
34023
34121
|
}
|
|
34024
34122
|
);
|
|
34025
34123
|
}, (prevProps, nextProps) => {
|
|
34026
|
-
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.
|
|
34124
|
+
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
34027
34125
|
return false;
|
|
34028
34126
|
}
|
|
34029
34127
|
if (prevProps.workspace.workspace_uuid !== nextProps.workspace.workspace_uuid || prevProps.workspace.workspace_name !== nextProps.workspace.workspace_name || prevProps.workspace.line_id !== nextProps.workspace.line_id) {
|
|
@@ -34615,8 +34713,20 @@ var CardFooter2 = (props) => {
|
|
|
34615
34713
|
return /* @__PURE__ */ jsx(RegisteredCardFooter, { ...props });
|
|
34616
34714
|
};
|
|
34617
34715
|
|
|
34716
|
+
// src/lib/utils/workspaceDetailCycleTime.ts
|
|
34717
|
+
var resolveWorkspaceDetailActionFamily = (workspace) => {
|
|
34718
|
+
if (workspace?.action_family === "assembly" || workspace?.action_family === "output" || workspace?.action_family === "other") {
|
|
34719
|
+
return workspace.action_family;
|
|
34720
|
+
}
|
|
34721
|
+
if (workspace?.action_type === "assembly" || workspace?.action_type === "output") {
|
|
34722
|
+
return workspace.action_type;
|
|
34723
|
+
}
|
|
34724
|
+
return null;
|
|
34725
|
+
};
|
|
34726
|
+
var shouldUseAssemblyCycleTimeLayout = (workspace) => workspace?.line_assembly_enabled === true && resolveWorkspaceDetailActionFamily(workspace) === "assembly";
|
|
34727
|
+
|
|
34618
34728
|
// src/components/dashboard/workspace/workspaceDetailCardRules.ts
|
|
34619
|
-
var shouldHideWorkspaceEfficiencyCard = (workspace) => workspace
|
|
34729
|
+
var shouldHideWorkspaceEfficiencyCard = (workspace) => shouldUseAssemblyCycleTimeLayout(workspace);
|
|
34620
34730
|
var WorkspaceMetricCardsImpl = ({
|
|
34621
34731
|
workspace,
|
|
34622
34732
|
className,
|
|
@@ -35325,6 +35435,37 @@ var getShiftElapsedMinutes = ({
|
|
|
35325
35435
|
const elapsed = differenceInMinutes(now4, shiftStartDate);
|
|
35326
35436
|
return Math.min(Math.max(elapsed, 0), shiftMinutes);
|
|
35327
35437
|
};
|
|
35438
|
+
var maskFutureHourlySeries = ({
|
|
35439
|
+
data,
|
|
35440
|
+
shiftStart,
|
|
35441
|
+
shiftEnd,
|
|
35442
|
+
shiftDate,
|
|
35443
|
+
timezone,
|
|
35444
|
+
now: now4 = /* @__PURE__ */ new Date()
|
|
35445
|
+
}) => {
|
|
35446
|
+
if (!Array.isArray(data)) {
|
|
35447
|
+
return [];
|
|
35448
|
+
}
|
|
35449
|
+
const normalizedData = data.map((value) => typeof value === "number" && Number.isFinite(value) ? value : null);
|
|
35450
|
+
if (!normalizedData.length) {
|
|
35451
|
+
return normalizedData;
|
|
35452
|
+
}
|
|
35453
|
+
const shiftMinutes = getShiftDurationMinutes(shiftStart, shiftEnd);
|
|
35454
|
+
const elapsedMinutes = getShiftElapsedMinutes({
|
|
35455
|
+
shiftStart,
|
|
35456
|
+
shiftEnd,
|
|
35457
|
+
shiftDate,
|
|
35458
|
+
timezone,
|
|
35459
|
+
now: now4
|
|
35460
|
+
});
|
|
35461
|
+
if (shiftMinutes === null || elapsedMinutes === null || elapsedMinutes >= shiftMinutes) {
|
|
35462
|
+
return normalizedData;
|
|
35463
|
+
}
|
|
35464
|
+
return normalizedData.map((value, index) => {
|
|
35465
|
+
const slotStartMinutes = index * 60;
|
|
35466
|
+
return slotStartMinutes > elapsedMinutes ? null : value;
|
|
35467
|
+
});
|
|
35468
|
+
};
|
|
35328
35469
|
var buildUptimeSeries = ({
|
|
35329
35470
|
idleTimeHourly,
|
|
35330
35471
|
shiftStart,
|
|
@@ -44448,7 +44589,7 @@ var ShiftDisplay = memo$1(({ className, variant = "default", lineId }) => {
|
|
|
44448
44589
|
return null;
|
|
44449
44590
|
}
|
|
44450
44591
|
};
|
|
44451
|
-
const
|
|
44592
|
+
const getShiftIcon2 = (shift) => {
|
|
44452
44593
|
if (shift === "Day") {
|
|
44453
44594
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z", clipRule: "evenodd" }) });
|
|
44454
44595
|
} else {
|
|
@@ -44474,7 +44615,7 @@ var ShiftDisplay = memo$1(({ className, variant = "default", lineId }) => {
|
|
|
44474
44615
|
}
|
|
44475
44616
|
if (variant === "enhanced") {
|
|
44476
44617
|
return /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center gap-2 bg-blue-50 rounded-lg px-3 py-1.5 ${className ?? ""}`, children: [
|
|
44477
|
-
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children:
|
|
44618
|
+
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children: getShiftIcon2(currentShiftText) }),
|
|
44478
44619
|
/* @__PURE__ */ jsxs("span", { className: "text-base font-medium text-blue-800", children: [
|
|
44479
44620
|
currentShiftText,
|
|
44480
44621
|
" Shift"
|
|
@@ -44482,7 +44623,7 @@ var ShiftDisplay = memo$1(({ className, variant = "default", lineId }) => {
|
|
|
44482
44623
|
] });
|
|
44483
44624
|
}
|
|
44484
44625
|
return /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center gap-2 bg-blue-50 rounded-lg px-3 py-1.5 ${className ?? ""}`, children: [
|
|
44485
|
-
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children:
|
|
44626
|
+
/* @__PURE__ */ jsx("div", { className: "text-blue-800", children: getShiftIcon2(currentShiftText) }),
|
|
44486
44627
|
/* @__PURE__ */ jsxs("span", { className: "text-base font-medium text-blue-800", children: [
|
|
44487
44628
|
currentShiftText,
|
|
44488
44629
|
" Shift"
|
|
@@ -47119,7 +47260,7 @@ var LinePdfGenerator = ({
|
|
|
47119
47260
|
doc.setLineWidth(0.8);
|
|
47120
47261
|
doc.line(20, 123, 190, 123);
|
|
47121
47262
|
const hourlyOverviewStartY = 128;
|
|
47122
|
-
const
|
|
47263
|
+
const parseTimeToMinutes4 = (timeStr) => {
|
|
47123
47264
|
const [hours, minutes] = timeStr.split(":");
|
|
47124
47265
|
const hour = parseInt(hours, 10);
|
|
47125
47266
|
const minute = parseInt(minutes || "0", 10);
|
|
@@ -47152,7 +47293,7 @@ var LinePdfGenerator = ({
|
|
|
47152
47293
|
};
|
|
47153
47294
|
};
|
|
47154
47295
|
const getHourlyTimeRanges = (startTimeStr, endTimeStr) => {
|
|
47155
|
-
const startMinutes =
|
|
47296
|
+
const startMinutes = parseTimeToMinutes4(startTimeStr);
|
|
47156
47297
|
if (Number.isNaN(startMinutes)) {
|
|
47157
47298
|
return [];
|
|
47158
47299
|
}
|
|
@@ -47160,7 +47301,7 @@ var LinePdfGenerator = ({
|
|
|
47160
47301
|
const defaultHours = 11;
|
|
47161
47302
|
return Array.from({ length: defaultHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
|
|
47162
47303
|
}
|
|
47163
|
-
const endMinutes =
|
|
47304
|
+
const endMinutes = parseTimeToMinutes4(endTimeStr);
|
|
47164
47305
|
if (Number.isNaN(endMinutes)) {
|
|
47165
47306
|
const fallbackHours = 11;
|
|
47166
47307
|
return Array.from({ length: fallbackHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
|
|
@@ -48863,7 +49004,7 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48863
49004
|
setIsGenerating(true);
|
|
48864
49005
|
try {
|
|
48865
49006
|
const isUptimeMode = workspace.monitoring_mode === "uptime";
|
|
48866
|
-
const isAssemblyCycleMode = !isUptimeMode && workspace
|
|
49007
|
+
const isAssemblyCycleMode = !isUptimeMode && shouldUseAssemblyCycleTimeLayout(workspace);
|
|
48867
49008
|
const shiftMinutes = getShiftDurationMinutes(workspace.shift_start, workspace.shift_end);
|
|
48868
49009
|
const shiftSeconds = shiftMinutes ? shiftMinutes * 60 : 0;
|
|
48869
49010
|
const idleSeconds = Math.max(workspace.idle_time || 0, 0);
|
|
@@ -48929,7 +49070,7 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48929
49070
|
minute: "2-digit",
|
|
48930
49071
|
hour12: true
|
|
48931
49072
|
});
|
|
48932
|
-
const
|
|
49073
|
+
const parseTimeToMinutes4 = (timeValue) => {
|
|
48933
49074
|
const [hourPart, minutePart] = timeValue.split(":").map(Number);
|
|
48934
49075
|
const hour = Number.isFinite(hourPart) ? hourPart : 0;
|
|
48935
49076
|
const minute = Number.isFinite(minutePart) ? minutePart : 0;
|
|
@@ -48946,8 +49087,8 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48946
49087
|
const IST_OFFSET_MINUTES = 330;
|
|
48947
49088
|
return Date.UTC(year, month - 1, day, hour, minute) - IST_OFFSET_MINUTES * 60 * 1e3;
|
|
48948
49089
|
};
|
|
48949
|
-
const shiftStartMinutes =
|
|
48950
|
-
const shiftEndMinutes =
|
|
49090
|
+
const shiftStartMinutes = parseTimeToMinutes4(workspace.shift_start);
|
|
49091
|
+
const shiftEndMinutes = parseTimeToMinutes4(workspace.shift_end);
|
|
48951
49092
|
const wrapsMidnight = shiftEndMinutes <= shiftStartMinutes;
|
|
48952
49093
|
const shiftStartUtcMs = toShiftUtcMs(workspace.date, workspace.shift_start);
|
|
48953
49094
|
const shiftEndUtcMs = toShiftUtcMs(workspace.date, workspace.shift_end) + (wrapsMidnight ? 24 * 60 * 60 * 1e3 : 0);
|
|
@@ -51254,7 +51395,7 @@ var DashboardHeader = memo$1(({ lineTitle, className = "", headerControls, lineI
|
|
|
51254
51395
|
const rawName = currentShift.shiftName || "Day";
|
|
51255
51396
|
return rawName.toLowerCase().includes("shift") ? rawName : `${rawName} Shift`;
|
|
51256
51397
|
};
|
|
51257
|
-
const
|
|
51398
|
+
const getShiftIcon2 = () => {
|
|
51258
51399
|
const currentShift = getCurrentShift(timezone, shiftConfig);
|
|
51259
51400
|
const shiftName = (currentShift.shiftName || "").toLowerCase();
|
|
51260
51401
|
if (shiftName.includes("day") || shiftName.includes("morning") || currentShift.shiftId === 0) {
|
|
@@ -51288,7 +51429,7 @@ var DashboardHeader = memo$1(({ lineTitle, className = "", headerControls, lineI
|
|
|
51288
51429
|
/* @__PURE__ */ jsx("span", { className: "font-medium", children: /* @__PURE__ */ jsx(Timer2, {}) }),
|
|
51289
51430
|
/* @__PURE__ */ jsx("span", { className: "text-gray-300", children: "|" }),
|
|
51290
51431
|
isShiftConfigLoading ? /* @__PURE__ */ jsx("div", { className: "h-3.5 w-16 bg-gray-200 rounded animate-pulse" }) : /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 font-medium", children: [
|
|
51291
|
-
/* @__PURE__ */ jsx("span", { className: "opacity-75", children:
|
|
51432
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-75", children: getShiftIcon2() }),
|
|
51292
51433
|
getShiftName()
|
|
51293
51434
|
] })
|
|
51294
51435
|
] })
|
|
@@ -51305,7 +51446,7 @@ var DashboardHeader = memo$1(({ lineTitle, className = "", headerControls, lineI
|
|
|
51305
51446
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 inline-flex flex-wrap items-center gap-3", children: [
|
|
51306
51447
|
/* @__PURE__ */ jsx("div", { className: "text-xs md:text-sm font-medium text-gray-600 whitespace-nowrap", children: /* @__PURE__ */ jsx(Timer2, {}) }),
|
|
51307
51448
|
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center gap-1", children: isShiftConfigLoading ? /* @__PURE__ */ jsx("div", { className: "h-4 w-20 bg-gray-200 rounded animate-pulse" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
51308
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children:
|
|
51449
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children: getShiftIcon2() }),
|
|
51309
51450
|
/* @__PURE__ */ jsx("span", { className: "text-xs md:text-sm font-medium text-gray-600 whitespace-nowrap", children: getShiftName() })
|
|
51310
51451
|
] }) })
|
|
51311
51452
|
] })
|
|
@@ -58276,7 +58417,7 @@ var FactoryView = ({
|
|
|
58276
58417
|
const currentShift = getCurrentShiftInfo();
|
|
58277
58418
|
return (currentShift.shiftName || "Day").replace(/ Shift$/i, "");
|
|
58278
58419
|
};
|
|
58279
|
-
const
|
|
58420
|
+
const getShiftIcon2 = () => {
|
|
58280
58421
|
const currentShift = getCurrentShiftInfo();
|
|
58281
58422
|
const shiftNameLower = (currentShift.shiftName || "").toLowerCase();
|
|
58282
58423
|
if (shiftNameLower.includes("day") || shiftNameLower.includes("morning") || currentShift.shiftId === 0) {
|
|
@@ -58322,7 +58463,7 @@ var FactoryView = ({
|
|
|
58322
58463
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center justify-center gap-2", children: [
|
|
58323
58464
|
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-gray-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: /* @__PURE__ */ jsx(ISTTimer_default, {}) }) }),
|
|
58324
58465
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
58325
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
58466
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2() }),
|
|
58326
58467
|
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-gray-700", children: [
|
|
58327
58468
|
getShiftName(),
|
|
58328
58469
|
" Shift"
|
|
@@ -58341,7 +58482,7 @@ var FactoryView = ({
|
|
|
58341
58482
|
" IST"
|
|
58342
58483
|
] }),
|
|
58343
58484
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1", children: [
|
|
58344
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children:
|
|
58485
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children: getShiftIcon2() }),
|
|
58345
58486
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-gray-600", children: [
|
|
58346
58487
|
getShiftName(),
|
|
58347
58488
|
" Shift"
|
|
@@ -61053,7 +61194,7 @@ var KPIDetailView = ({
|
|
|
61053
61194
|
const getShiftName = useCallback((shiftId) => {
|
|
61054
61195
|
return getShiftNameById(shiftId, configuredTimezone, shiftConfig);
|
|
61055
61196
|
}, [configuredTimezone, shiftConfig]);
|
|
61056
|
-
const
|
|
61197
|
+
const getShiftIcon2 = useCallback((shiftId) => {
|
|
61057
61198
|
if (shiftId === 0) {
|
|
61058
61199
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
61059
61200
|
}
|
|
@@ -61933,7 +62074,7 @@ var KPIDetailView = ({
|
|
|
61933
62074
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
|
|
61934
62075
|
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-gray-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: chartMetrics && formatLocalDate(new Date(chartMetrics.date)) }) }),
|
|
61935
62076
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
61936
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
62077
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(chartMetrics.shift_id ?? 0) }),
|
|
61937
62078
|
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-gray-700", children: [
|
|
61938
62079
|
getShiftName(chartMetrics.shift_id ?? 0).replace(/ Shift$/i, ""),
|
|
61939
62080
|
" Shift"
|
|
@@ -61959,7 +62100,7 @@ var KPIDetailView = ({
|
|
|
61959
62100
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" })
|
|
61960
62101
|
] }),
|
|
61961
62102
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
61962
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
62103
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(chartMetrics.shift_id ?? 0) }),
|
|
61963
62104
|
/* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: [
|
|
61964
62105
|
getShiftName(chartMetrics.shift_id ?? 0).replace(/ Shift$/i, ""),
|
|
61965
62106
|
" Shift"
|
|
@@ -61977,7 +62118,7 @@ var KPIDetailView = ({
|
|
|
61977
62118
|
return `${startDate.toLocaleDateString("en-US", { month: "short", day: "numeric" })} - ${endDate.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })}`;
|
|
61978
62119
|
})() }) }),
|
|
61979
62120
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
61980
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
62121
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(selectedShiftId) }),
|
|
61981
62122
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: getShiftName(selectedShiftId) })
|
|
61982
62123
|
] })
|
|
61983
62124
|
] }),
|
|
@@ -61994,7 +62135,7 @@ var KPIDetailView = ({
|
|
|
61994
62135
|
] }),
|
|
61995
62136
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" }),
|
|
61996
62137
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
61997
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
62138
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(selectedShiftId) }),
|
|
61998
62139
|
/* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: [
|
|
61999
62140
|
getShiftName(selectedShiftId).replace(/ Shift$/i, ""),
|
|
62000
62141
|
" Shift"
|
|
@@ -63370,7 +63511,7 @@ var KPIsOverviewView = ({
|
|
|
63370
63511
|
const headerShiftId = showHistoricalLeaderboardHeader ? effectiveLeaderboardShiftId : currentShiftDetails.shiftId;
|
|
63371
63512
|
const headerShiftName = getShiftNameById(headerShiftId, configuredTimezone, shiftConfig).replace(/ Shift$/i, "");
|
|
63372
63513
|
const headerDateLabel = isMonthlyMode ? getMonthRange() : formatLocalDate2(headerDateKey);
|
|
63373
|
-
const
|
|
63514
|
+
const getShiftIcon2 = (shiftId) => {
|
|
63374
63515
|
const shiftNameLower = getShiftNameById(shiftId, configuredTimezone, shiftConfig).toLowerCase();
|
|
63375
63516
|
if (shiftNameLower.includes("day") || shiftNameLower.includes("morning") || shiftId === 0) {
|
|
63376
63517
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
@@ -63487,7 +63628,7 @@ var KPIsOverviewView = ({
|
|
|
63487
63628
|
/* @__PURE__ */ jsx("div", { className: `inline-flex items-center bg-gray-100 rounded-full ${isMonthlyMode ? "px-4 py-1.5 ring-1 ring-gray-200 shadow-sm" : "px-2.5 py-1"}`, children: /* @__PURE__ */ jsx("span", { className: `font-medium text-gray-700 ${isMonthlyMode ? "text-sm" : "text-xs"}`, children: headerDateLabel }) }),
|
|
63488
63629
|
!isMonthlyMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63489
63630
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
63490
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
63631
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(headerShiftId) }),
|
|
63491
63632
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: headerShiftName })
|
|
63492
63633
|
] }),
|
|
63493
63634
|
showHistoricalLeaderboardHeader ? /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-amber-50 text-amber-700 rounded-full", children: [
|
|
@@ -63683,7 +63824,7 @@ var KPIsOverviewView = ({
|
|
|
63683
63824
|
!isMonthlyMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63684
63825
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" }),
|
|
63685
63826
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
63686
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
63827
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(headerShiftId) }),
|
|
63687
63828
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-semibold uppercase tracking-wider", children: [
|
|
63688
63829
|
headerShiftName,
|
|
63689
63830
|
" Shift"
|
|
@@ -63827,6 +63968,52 @@ var KPIsOverviewView = ({
|
|
|
63827
63968
|
] });
|
|
63828
63969
|
};
|
|
63829
63970
|
var KPIsOverviewView_default = KPIsOverviewView;
|
|
63971
|
+
var toFiniteNumber = (value) => {
|
|
63972
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
63973
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
63974
|
+
const parsed = Number(value);
|
|
63975
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
63976
|
+
}
|
|
63977
|
+
return null;
|
|
63978
|
+
};
|
|
63979
|
+
var getCycleRatio = (workspace) => {
|
|
63980
|
+
const idealCycleTime = toFiniteNumber(workspace.ideal_cycle_time);
|
|
63981
|
+
const avgCycleTime = toFiniteNumber(workspace.avg_cycle_time);
|
|
63982
|
+
if (idealCycleTime === null || avgCycleTime === null || idealCycleTime <= 0 || avgCycleTime <= 0) {
|
|
63983
|
+
return null;
|
|
63984
|
+
}
|
|
63985
|
+
return idealCycleTime / avgCycleTime;
|
|
63986
|
+
};
|
|
63987
|
+
var formatCycleTimeValue = (value) => {
|
|
63988
|
+
const numericValue = toFiniteNumber(value);
|
|
63989
|
+
if (numericValue === null || numericValue <= 0) return "--";
|
|
63990
|
+
return `${numericValue.toFixed(1)}s`;
|
|
63991
|
+
};
|
|
63992
|
+
var CycleTimeComparison = memo$1(({
|
|
63993
|
+
workspace,
|
|
63994
|
+
variant = "table"
|
|
63995
|
+
}) => {
|
|
63996
|
+
const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
63997
|
+
const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
63998
|
+
if (variant === "mobile") {
|
|
63999
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center justify-between py-2 border-t border-gray-100", children: [
|
|
64000
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Standard Cycle Time" }),
|
|
64001
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums text-gray-500", children: standardValue })
|
|
64002
|
+
] });
|
|
64003
|
+
}
|
|
64004
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64005
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
64006
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Average" }),
|
|
64007
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums text-gray-900", children: averageValue })
|
|
64008
|
+
] }),
|
|
64009
|
+
/* @__PURE__ */ jsx("div", { className: "h-6 w-px bg-gray-200" }),
|
|
64010
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
64011
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Standard" }),
|
|
64012
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums text-gray-500", children: standardValue })
|
|
64013
|
+
] })
|
|
64014
|
+
] });
|
|
64015
|
+
}, (prevProps, nextProps) => prevProps.variant === nextProps.variant && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
|
|
64016
|
+
CycleTimeComparison.displayName = "CycleTimeComparison";
|
|
63830
64017
|
var IsolatedTimer = memo$1(() => {
|
|
63831
64018
|
return /* @__PURE__ */ jsx(ISTTimer_default, {});
|
|
63832
64019
|
});
|
|
@@ -63844,11 +64031,11 @@ var HeaderRibbon = memo$1(({
|
|
|
63844
64031
|
currentDate,
|
|
63845
64032
|
currentMobileDate,
|
|
63846
64033
|
shiftId,
|
|
63847
|
-
getShiftIcon,
|
|
64034
|
+
getShiftIcon: getShiftIcon2,
|
|
63848
64035
|
getShiftName,
|
|
63849
64036
|
showTimer = true
|
|
63850
64037
|
}) => {
|
|
63851
|
-
const shiftIcon = useMemo(() =>
|
|
64038
|
+
const shiftIcon = useMemo(() => getShiftIcon2(shiftId), [getShiftIcon2, shiftId]);
|
|
63852
64039
|
const shiftName = useMemo(() => getShiftName(shiftId), [getShiftName, shiftId]);
|
|
63853
64040
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63854
64041
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
|
|
@@ -63890,8 +64077,9 @@ var MobileWorkspaceCard = memo$1(({
|
|
|
63890
64077
|
isClickable,
|
|
63891
64078
|
onWorkspaceClick,
|
|
63892
64079
|
getMedalIcon,
|
|
63893
|
-
|
|
63894
|
-
|
|
64080
|
+
metricLabel,
|
|
64081
|
+
isAssemblyMode
|
|
64082
|
+
}) => /* @__PURE__ */ jsxs(
|
|
63895
64083
|
motion.div,
|
|
63896
64084
|
{
|
|
63897
64085
|
layout: true,
|
|
@@ -63902,28 +64090,31 @@ var MobileWorkspaceCard = memo$1(({
|
|
|
63902
64090
|
},
|
|
63903
64091
|
onClick: isClickable ? () => onWorkspaceClick(workspace, rank) : void 0,
|
|
63904
64092
|
className: `${cardClass} p-3 rounded-lg border shadow-sm active:scale-[0.98] ${isClickable ? "cursor-pointer" : "cursor-not-allowed opacity-75"}`,
|
|
63905
|
-
children:
|
|
63906
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
63907
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
63908
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
63909
|
-
"
|
|
63910
|
-
|
|
64093
|
+
children: [
|
|
64094
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2 gap-3", children: [
|
|
64095
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64096
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
64097
|
+
/* @__PURE__ */ jsxs("div", { className: "text-2xl font-bold text-gray-700", children: [
|
|
64098
|
+
"#",
|
|
64099
|
+
rank
|
|
64100
|
+
] }),
|
|
64101
|
+
getMedalIcon(rank)
|
|
63911
64102
|
] }),
|
|
63912
|
-
|
|
64103
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
64104
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-900", children: workspace.displayName }),
|
|
64105
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: workspace.lineName })
|
|
64106
|
+
] })
|
|
63913
64107
|
] }),
|
|
63914
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
63915
|
-
/* @__PURE__ */ jsx("div", { className: "font-
|
|
63916
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children:
|
|
64108
|
+
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
64109
|
+
/* @__PURE__ */ jsx("div", { className: "font-bold text-gray-900 text-lg", children: isAssemblyMode ? /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formatCycleTimeValue(workspace.avg_cycle_time) }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) }),
|
|
64110
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: metricLabel })
|
|
63917
64111
|
] })
|
|
63918
64112
|
] }),
|
|
63919
|
-
/* @__PURE__ */
|
|
63920
|
-
|
|
63921
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: efficiencyLabel })
|
|
63922
|
-
] })
|
|
63923
|
-
] })
|
|
64113
|
+
isAssemblyMode && /* @__PURE__ */ jsx(CycleTimeComparison, { workspace, variant: "mobile" })
|
|
64114
|
+
]
|
|
63924
64115
|
}
|
|
63925
64116
|
), (prevProps, nextProps) => {
|
|
63926
|
-
return prevProps.
|
|
64117
|
+
return prevProps.metricLabel === nextProps.metricLabel && prevProps.isAssemblyMode === nextProps.isAssemblyMode && prevProps.rank === nextProps.rank && prevProps.cardClass === nextProps.cardClass && prevProps.isClickable === nextProps.isClickable && prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.efficiency === nextProps.workspace.efficiency && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time && prevProps.workspace.action_count === nextProps.workspace.action_count && prevProps.workspace.action_threshold === nextProps.workspace.action_threshold && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.displayName === nextProps.workspace.displayName && prevProps.workspace.lineName === nextProps.workspace.lineName;
|
|
63927
64118
|
});
|
|
63928
64119
|
MobileWorkspaceCard.displayName = "MobileWorkspaceCard";
|
|
63929
64120
|
var DesktopWorkspaceRow = memo$1(({
|
|
@@ -63932,7 +64123,8 @@ var DesktopWorkspaceRow = memo$1(({
|
|
|
63932
64123
|
rowClass,
|
|
63933
64124
|
isClickable,
|
|
63934
64125
|
onWorkspaceClick,
|
|
63935
|
-
getMedalIcon
|
|
64126
|
+
getMedalIcon,
|
|
64127
|
+
isAssemblyMode
|
|
63936
64128
|
}) => /* @__PURE__ */ jsxs(
|
|
63937
64129
|
motion.tr,
|
|
63938
64130
|
{
|
|
@@ -63949,11 +64141,11 @@ var DesktopWorkspaceRow = memo$1(({
|
|
|
63949
64141
|
] }) }),
|
|
63950
64142
|
/* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: workspace.displayName }) }),
|
|
63951
64143
|
/* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: workspace.lineName }) }),
|
|
63952
|
-
/* @__PURE__ */ jsx("td", { className:
|
|
64144
|
+
/* @__PURE__ */ jsx("td", { className: `px-3 py-2.5 sm:p-4 text-sm sm:text-base font-medium ${isAssemblyMode ? "" : "whitespace-nowrap"}`, children: isAssemblyMode ? /* @__PURE__ */ jsx(CycleTimeComparison, { workspace, variant: "table" }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) })
|
|
63953
64145
|
]
|
|
63954
64146
|
}
|
|
63955
64147
|
), (prevProps, nextProps) => {
|
|
63956
|
-
return prevProps.index === nextProps.index && prevProps.rowClass === nextProps.rowClass && prevProps.isClickable === nextProps.isClickable && prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.efficiency === nextProps.workspace.efficiency && prevProps.workspace.displayName === nextProps.workspace.displayName && prevProps.workspace.lineName === nextProps.workspace.lineName;
|
|
64148
|
+
return prevProps.index === nextProps.index && prevProps.rowClass === nextProps.rowClass && prevProps.isClickable === nextProps.isClickable && prevProps.isAssemblyMode === nextProps.isAssemblyMode && prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.efficiency === nextProps.workspace.efficiency && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.displayName === nextProps.workspace.displayName && prevProps.workspace.lineName === nextProps.workspace.lineName;
|
|
63957
64149
|
});
|
|
63958
64150
|
DesktopWorkspaceRow.displayName = "DesktopWorkspaceRow";
|
|
63959
64151
|
var LeaderboardDetailView = memo$1(({
|
|
@@ -63975,6 +64167,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
63975
64167
|
const supabase = useSupabase();
|
|
63976
64168
|
const [sortAscending, setSortAscending] = useState(false);
|
|
63977
64169
|
const [viewType, setViewType] = useState("operator");
|
|
64170
|
+
const [outputCategory, setOutputCategory] = useState("standard");
|
|
63978
64171
|
const [activeTab, setActiveTab] = useState("today");
|
|
63979
64172
|
const timezone = useAppTimezone();
|
|
63980
64173
|
const staticShiftConfig = useShiftConfig();
|
|
@@ -64053,6 +64246,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64053
64246
|
const monthlyRequestKeyRef = useRef(null);
|
|
64054
64247
|
const leaderboardUpdateQueuedRef = useRef(false);
|
|
64055
64248
|
const leaderboardUpdateTimerRef = useRef(null);
|
|
64249
|
+
const leaderboardViewTrackedRef = useRef(null);
|
|
64056
64250
|
const filterRef = useRef(null);
|
|
64057
64251
|
const filterButtonRef = useRef(null);
|
|
64058
64252
|
const mobileFilterButtonRef = useRef(null);
|
|
@@ -64185,6 +64379,17 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64185
64379
|
}
|
|
64186
64380
|
return Array.from(uniqueLines.entries()).map(([id3, name]) => ({ id: id3, label: name }));
|
|
64187
64381
|
}, [configuredLineIds, lines, getLineName]);
|
|
64382
|
+
const scopedLines = useMemo(() => {
|
|
64383
|
+
const configuredLineIdSet = new Set(configuredLineIds);
|
|
64384
|
+
return lines.filter((line) => configuredLineIds.length === 0 || configuredLineIdSet.has(line.id));
|
|
64385
|
+
}, [configuredLineIds, lines]);
|
|
64386
|
+
const scopedLineAssemblyMap = useMemo(() => {
|
|
64387
|
+
const map = /* @__PURE__ */ new Map();
|
|
64388
|
+
scopedLines.forEach((line) => {
|
|
64389
|
+
map.set(line.id, line.assembly === true);
|
|
64390
|
+
});
|
|
64391
|
+
return map;
|
|
64392
|
+
}, [scopedLines]);
|
|
64188
64393
|
const shiftOptions = useMemo(() => {
|
|
64189
64394
|
if (activeShiftConfig?.shifts && activeShiftConfig.shifts.length > 0) {
|
|
64190
64395
|
return activeShiftConfig.shifts.map((shift2) => ({
|
|
@@ -64208,6 +64413,33 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64208
64413
|
const parsed = Number(selectedShiftFilter);
|
|
64209
64414
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
64210
64415
|
}, [selectedShiftFilter]);
|
|
64416
|
+
const outputScopeLines = useMemo(() => {
|
|
64417
|
+
const outputLines = scopedLines.filter((line) => (line.monitoring_mode ?? "output") !== "uptime");
|
|
64418
|
+
if (selectedLineFilter === "all") {
|
|
64419
|
+
return outputLines;
|
|
64420
|
+
}
|
|
64421
|
+
return outputLines.filter((line) => line.id === selectedLineFilter);
|
|
64422
|
+
}, [scopedLines, selectedLineFilter]);
|
|
64423
|
+
const hasAssemblyOutputScope = useMemo(
|
|
64424
|
+
() => outputScopeLines.some((line) => line.assembly === true),
|
|
64425
|
+
[outputScopeLines]
|
|
64426
|
+
);
|
|
64427
|
+
const hasStandardOutputScope = useMemo(
|
|
64428
|
+
() => outputScopeLines.some((line) => line.assembly !== true),
|
|
64429
|
+
[outputScopeLines]
|
|
64430
|
+
);
|
|
64431
|
+
const showOutputCategoryDropdown = viewType === "operator" && hasAssemblyOutputScope && hasStandardOutputScope;
|
|
64432
|
+
const isAssemblyMode = viewType === "operator" && outputCategory === "assembly";
|
|
64433
|
+
useEffect(() => {
|
|
64434
|
+
if (viewType !== "operator") return;
|
|
64435
|
+
if (hasAssemblyOutputScope && !hasStandardOutputScope && outputCategory !== "assembly") {
|
|
64436
|
+
setOutputCategory("assembly");
|
|
64437
|
+
return;
|
|
64438
|
+
}
|
|
64439
|
+
if (hasStandardOutputScope && !hasAssemblyOutputScope && outputCategory !== "standard") {
|
|
64440
|
+
setOutputCategory("standard");
|
|
64441
|
+
}
|
|
64442
|
+
}, [viewType, hasAssemblyOutputScope, hasStandardOutputScope, outputCategory]);
|
|
64211
64443
|
const handleLineFilterChange = useCallback((value) => {
|
|
64212
64444
|
setSelectedLineFilter(value);
|
|
64213
64445
|
}, []);
|
|
@@ -64217,17 +64449,19 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64217
64449
|
const clearFilters = useCallback(() => {
|
|
64218
64450
|
setSortAscending(false);
|
|
64219
64451
|
setSelectedLineFilter("all");
|
|
64452
|
+
setOutputCategory("standard");
|
|
64220
64453
|
setSelectedShiftFilter(currentShiftInfo.shiftId.toString());
|
|
64221
64454
|
}, [currentShiftInfo.shiftId]);
|
|
64222
64455
|
const activeFiltersCount = useMemo(() => {
|
|
64223
64456
|
let count = 0;
|
|
64224
64457
|
if (sortAscending) count++;
|
|
64225
64458
|
if (selectedLineFilter !== "all") count++;
|
|
64459
|
+
if (showOutputCategoryDropdown && outputCategory !== "standard") count++;
|
|
64226
64460
|
if (selectedShiftFilter !== currentShiftInfo.shiftId.toString()) {
|
|
64227
64461
|
count++;
|
|
64228
64462
|
}
|
|
64229
64463
|
return count;
|
|
64230
|
-
}, [sortAscending, selectedLineFilter, selectedShiftFilter, currentShiftInfo.shiftId]);
|
|
64464
|
+
}, [sortAscending, selectedLineFilter, outputCategory, showOutputCategoryDropdown, selectedShiftFilter, currentShiftInfo.shiftId]);
|
|
64231
64465
|
const shouldFetchShiftConfigs = !date && shiftId === void 0;
|
|
64232
64466
|
const {
|
|
64233
64467
|
shiftConfigMap: multiLineShiftConfigMap,
|
|
@@ -64279,7 +64513,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64279
64513
|
action_count: entry.total_output || 0,
|
|
64280
64514
|
pph: entry.avg_pph || 0,
|
|
64281
64515
|
performance_score: entry.performance_score ?? 0,
|
|
64282
|
-
avg_cycle_time: entry.avg_cycle_time
|
|
64516
|
+
avg_cycle_time: toFiniteNumber(entry.avg_cycle_time) ?? 0,
|
|
64517
|
+
ideal_cycle_time: toFiniteNumber(entry.ideal_cycle_time) ?? void 0,
|
|
64283
64518
|
trend: 0,
|
|
64284
64519
|
predicted_output: 0,
|
|
64285
64520
|
efficiency: entry.efficiency || 0,
|
|
@@ -64457,7 +64692,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64457
64692
|
const currentShift = getCurrentShift(timezone || "Asia/Kolkata", activeShiftConfig);
|
|
64458
64693
|
return currentShift.shiftName || getShiftNameById(currentShift.shiftId, timezone || "Asia/Kolkata", activeShiftConfig);
|
|
64459
64694
|
}, [timezone, activeShiftConfig, shiftGroups]);
|
|
64460
|
-
const
|
|
64695
|
+
const getShiftIcon2 = useCallback((shiftId2) => {
|
|
64461
64696
|
if (shiftId2 === void 0 && shiftGroups.length > 1) {
|
|
64462
64697
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" }) });
|
|
64463
64698
|
}
|
|
@@ -64523,15 +64758,20 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64523
64758
|
if (!canOpenWorkspace(workspace.line_id)) {
|
|
64524
64759
|
return;
|
|
64525
64760
|
}
|
|
64761
|
+
const cycleRatio = getCycleRatio(workspace);
|
|
64526
64762
|
trackCoreEvent("Workspace from Leaderboard Clicked", {
|
|
64527
64763
|
workspace_name: workspace.workspace_name,
|
|
64528
64764
|
workspace_id: workspace.workspace_uuid,
|
|
64529
64765
|
rank,
|
|
64530
64766
|
total_workspaces: workspacesLengthRef.current,
|
|
64531
64767
|
// Use ref instead of state to avoid dependency
|
|
64768
|
+
metric_context: viewType === "machine" ? "machine" : outputCategory,
|
|
64532
64769
|
efficiency: workspace.efficiency,
|
|
64533
64770
|
action_count: workspace.action_count,
|
|
64534
|
-
action_threshold: workspace.action_threshold
|
|
64771
|
+
action_threshold: workspace.action_threshold,
|
|
64772
|
+
avg_cycle_time: workspace.avg_cycle_time,
|
|
64773
|
+
ideal_cycle_time: workspace.ideal_cycle_time ?? null,
|
|
64774
|
+
cycle_ratio: cycleRatio
|
|
64535
64775
|
});
|
|
64536
64776
|
const displayName = workspace.displayName || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
64537
64777
|
const navParams = workspace.workspace_uuid ? getWorkspaceNavigationParams(workspace.workspace_uuid, displayName, workspace.line_id) : "";
|
|
@@ -64555,7 +64795,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64555
64795
|
const combinedParams = navParams ? `${navParams}&${contextParamString}` : `?${contextParamString}`;
|
|
64556
64796
|
navigation.navigate(`/workspace/${workspace.workspace_uuid}${combinedParams}`);
|
|
64557
64797
|
}
|
|
64558
|
-
}, [canOpenWorkspace, onWorkspaceClick, navigation, date, shiftId]);
|
|
64798
|
+
}, [canOpenWorkspace, onWorkspaceClick, navigation, date, shiftId, outputCategory, viewType]);
|
|
64559
64799
|
useEffect(() => {
|
|
64560
64800
|
workspacesLengthRef.current = activeEntries.length || 0;
|
|
64561
64801
|
}, [activeEntries.length]);
|
|
@@ -64576,16 +64816,20 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64576
64816
|
return activeEntries.map((ws) => ({
|
|
64577
64817
|
...ws,
|
|
64578
64818
|
displayName: ws.displayName || getWorkspaceDisplayName(ws.workspace_name, ws.line_id),
|
|
64579
|
-
lineName: getLineName(ws.line_id)
|
|
64819
|
+
lineName: getLineName(ws.line_id),
|
|
64820
|
+
isAssemblyLine: scopedLineAssemblyMap.get(ws.line_id) === true
|
|
64580
64821
|
}));
|
|
64581
|
-
}, [activeEntries, getLineName]);
|
|
64822
|
+
}, [activeEntries, getLineName, scopedLineAssemblyMap]);
|
|
64582
64823
|
const sortedWorkspaces = useMemo(() => {
|
|
64583
64824
|
let filtered = [...workspaceDisplayData];
|
|
64584
64825
|
filtered = filtered.filter((ws) => {
|
|
64585
64826
|
if (viewType === "machine") {
|
|
64586
64827
|
return ws.monitoring_mode === "uptime";
|
|
64587
64828
|
}
|
|
64588
|
-
|
|
64829
|
+
if (ws.monitoring_mode === "uptime") {
|
|
64830
|
+
return false;
|
|
64831
|
+
}
|
|
64832
|
+
return isAssemblyMode ? ws.isAssemblyLine : !ws.isAssemblyLine;
|
|
64589
64833
|
});
|
|
64590
64834
|
if (selectedLineFilter !== "all") {
|
|
64591
64835
|
filtered = filtered.filter((ws) => ws.line_id === selectedLineFilter);
|
|
@@ -64594,13 +64838,61 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64594
64838
|
filtered = filtered.filter((ws) => ws.shift_id?.toString() === selectedShiftFilter);
|
|
64595
64839
|
}
|
|
64596
64840
|
return filtered.sort((a, b) => {
|
|
64841
|
+
if (isAssemblyMode) {
|
|
64842
|
+
const ratioA = getCycleRatio(a);
|
|
64843
|
+
const ratioB = getCycleRatio(b);
|
|
64844
|
+
if (ratioA === null && ratioB === null) return 0;
|
|
64845
|
+
if (ratioA === null) return 1;
|
|
64846
|
+
if (ratioB === null) return -1;
|
|
64847
|
+
return sortAscending ? ratioA - ratioB : ratioB - ratioA;
|
|
64848
|
+
}
|
|
64597
64849
|
const effA = a.efficiency || 0;
|
|
64598
64850
|
const effB = b.efficiency || 0;
|
|
64599
64851
|
return sortAscending ? effA - effB : effB - effA;
|
|
64600
64852
|
});
|
|
64601
|
-
}, [workspaceDisplayData, sortAscending, selectedLineFilter, selectedShiftFilter, activeTab, viewType]);
|
|
64853
|
+
}, [workspaceDisplayData, sortAscending, selectedLineFilter, selectedShiftFilter, activeTab, viewType, isAssemblyMode]);
|
|
64602
64854
|
const loading = activeTab === "today" ? todayLoading : monthlyLoading;
|
|
64603
64855
|
const error = activeTab === "today" ? todayError : monthlyError;
|
|
64856
|
+
useEffect(() => {
|
|
64857
|
+
if (loading || error || sortedWorkspaces.length === 0) return;
|
|
64858
|
+
const trackingKey = [
|
|
64859
|
+
activeTab,
|
|
64860
|
+
viewType,
|
|
64861
|
+
outputCategory,
|
|
64862
|
+
selectedLineFilter,
|
|
64863
|
+
selectedShiftFilter,
|
|
64864
|
+
sortAscending ? "asc" : "desc",
|
|
64865
|
+
sortedWorkspaces.length
|
|
64866
|
+
].join("|");
|
|
64867
|
+
if (leaderboardViewTrackedRef.current === trackingKey) return;
|
|
64868
|
+
leaderboardViewTrackedRef.current = trackingKey;
|
|
64869
|
+
const topWorkspace = sortedWorkspaces[0];
|
|
64870
|
+
trackCoreEvent("Workspace Leaderboard View Loaded", {
|
|
64871
|
+
time_range: activeTab,
|
|
64872
|
+
view_type: viewType,
|
|
64873
|
+
metric_context: viewType === "machine" ? "machine" : outputCategory,
|
|
64874
|
+
line_filter: selectedLineFilter,
|
|
64875
|
+
shift_filter: selectedShiftFilter,
|
|
64876
|
+
sort_direction: sortAscending ? "asc" : "desc",
|
|
64877
|
+
workspace_count: sortedWorkspaces.length,
|
|
64878
|
+
top_workspace_id: topWorkspace?.workspace_uuid ?? null,
|
|
64879
|
+
top_workspace_name: topWorkspace?.workspace_name ?? null,
|
|
64880
|
+
top_efficiency: topWorkspace?.efficiency ?? null,
|
|
64881
|
+
top_avg_cycle_time: topWorkspace?.avg_cycle_time ?? null,
|
|
64882
|
+
top_ideal_cycle_time: topWorkspace?.ideal_cycle_time ?? null,
|
|
64883
|
+
top_cycle_ratio: topWorkspace ? getCycleRatio(topWorkspace) : null
|
|
64884
|
+
});
|
|
64885
|
+
}, [
|
|
64886
|
+
loading,
|
|
64887
|
+
error,
|
|
64888
|
+
sortedWorkspaces,
|
|
64889
|
+
activeTab,
|
|
64890
|
+
viewType,
|
|
64891
|
+
outputCategory,
|
|
64892
|
+
selectedLineFilter,
|
|
64893
|
+
selectedShiftFilter,
|
|
64894
|
+
sortAscending
|
|
64895
|
+
]);
|
|
64604
64896
|
const currentDateFormatted = useMemo(() => {
|
|
64605
64897
|
const dateStr = (/* @__PURE__ */ new Date()).toDateString();
|
|
64606
64898
|
return formatDate2(new Date(dateStr));
|
|
@@ -64618,7 +64910,9 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64618
64910
|
error.message
|
|
64619
64911
|
] }) });
|
|
64620
64912
|
}
|
|
64621
|
-
const
|
|
64913
|
+
const metricLabel = viewType === "machine" ? "Utilization" : isAssemblyMode ? "Cycle Time" : "Efficiency";
|
|
64914
|
+
const descendingSortLabel = "Highest to Lowest";
|
|
64915
|
+
const ascendingSortLabel = "Lowest to Highest";
|
|
64622
64916
|
return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 flex flex-col ${className}`, style: { willChange: "contents" }, children: [
|
|
64623
64917
|
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-20 bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 md:px-8 py-2 sm:py-2.5", children: [
|
|
64624
64918
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
@@ -64668,7 +64962,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64668
64962
|
] }),
|
|
64669
64963
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
64670
64964
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
64671
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children:
|
|
64965
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: metricLabel }),
|
|
64672
64966
|
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
64673
64967
|
"select",
|
|
64674
64968
|
{
|
|
@@ -64677,8 +64971,25 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64677
64971
|
className: "w-full appearance-none pl-3 pr-8 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer",
|
|
64678
64972
|
style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.75rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
|
|
64679
64973
|
children: [
|
|
64680
|
-
/* @__PURE__ */ jsx("option", { value: "desc", children:
|
|
64681
|
-
/* @__PURE__ */ jsx("option", { value: "asc", children:
|
|
64974
|
+
/* @__PURE__ */ jsx("option", { value: "desc", children: descendingSortLabel }),
|
|
64975
|
+
/* @__PURE__ */ jsx("option", { value: "asc", children: ascendingSortLabel })
|
|
64976
|
+
]
|
|
64977
|
+
}
|
|
64978
|
+
) })
|
|
64979
|
+
] }),
|
|
64980
|
+
showOutputCategoryDropdown && /* @__PURE__ */ jsxs("div", { className: "space-y-1 sm:hidden", children: [
|
|
64981
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Output Type" }),
|
|
64982
|
+
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
64983
|
+
"select",
|
|
64984
|
+
{
|
|
64985
|
+
"aria-label": "Output leaderboard category",
|
|
64986
|
+
value: outputCategory,
|
|
64987
|
+
onChange: (e) => setOutputCategory(e.target.value),
|
|
64988
|
+
className: "w-full appearance-none pl-3 pr-8 py-2 text-sm bg-gray-50 border border-gray-200 hover:border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all cursor-pointer",
|
|
64989
|
+
style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.75rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
|
|
64990
|
+
children: [
|
|
64991
|
+
/* @__PURE__ */ jsx("option", { value: "standard", children: "Standard" }),
|
|
64992
|
+
/* @__PURE__ */ jsx("option", { value: "assembly", children: "Assembly" })
|
|
64682
64993
|
]
|
|
64683
64994
|
}
|
|
64684
64995
|
) })
|
|
@@ -64720,7 +65031,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64720
65031
|
currentDate: activeTab === "monthly" ? monthlyRangeText : currentDateFormatted,
|
|
64721
65032
|
currentMobileDate: activeTab === "monthly" ? monthlyRangeText : currentMobileDateFormatted,
|
|
64722
65033
|
shiftId: activeTab === "monthly" ? monthlyShiftId : todayShiftId,
|
|
64723
|
-
getShiftIcon,
|
|
65034
|
+
getShiftIcon: getShiftIcon2,
|
|
64724
65035
|
getShiftName,
|
|
64725
65036
|
showTimer: activeTab === "today"
|
|
64726
65037
|
}
|
|
@@ -64818,6 +65129,20 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64818
65129
|
]
|
|
64819
65130
|
}
|
|
64820
65131
|
) }),
|
|
65132
|
+
showOutputCategoryDropdown && /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
65133
|
+
"select",
|
|
65134
|
+
{
|
|
65135
|
+
"aria-label": "Output leaderboard category",
|
|
65136
|
+
value: outputCategory,
|
|
65137
|
+
onChange: (e) => setOutputCategory(e.target.value),
|
|
65138
|
+
className: "appearance-none pl-3 pr-8 py-1.5 text-sm font-medium bg-white border border-gray-200 hover:border-gray-300 rounded-lg text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all cursor-pointer shadow-sm",
|
|
65139
|
+
style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.5rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
|
|
65140
|
+
children: [
|
|
65141
|
+
/* @__PURE__ */ jsx("option", { value: "standard", children: "Standard" }),
|
|
65142
|
+
/* @__PURE__ */ jsx("option", { value: "assembly", children: "Assembly" })
|
|
65143
|
+
]
|
|
65144
|
+
}
|
|
65145
|
+
) }),
|
|
64821
65146
|
/* @__PURE__ */ jsxs(
|
|
64822
65147
|
"button",
|
|
64823
65148
|
{
|
|
@@ -64849,7 +65174,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64849
65174
|
isClickable: canOpenWorkspace(ws.line_id),
|
|
64850
65175
|
onWorkspaceClick: stableHandleWorkspaceClick,
|
|
64851
65176
|
getMedalIcon: stableGetMedalIcon,
|
|
64852
|
-
|
|
65177
|
+
metricLabel,
|
|
65178
|
+
isAssemblyMode
|
|
64853
65179
|
},
|
|
64854
65180
|
ws.workspace_uuid
|
|
64855
65181
|
);
|
|
@@ -64860,7 +65186,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64860
65186
|
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: "Rank" }),
|
|
64861
65187
|
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: "Workspace" }),
|
|
64862
65188
|
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: "Line" }),
|
|
64863
|
-
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children:
|
|
65189
|
+
/* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: metricLabel })
|
|
64864
65190
|
] }) }),
|
|
64865
65191
|
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-100", children: sortedWorkspaces.map((ws, index) => {
|
|
64866
65192
|
const isTopThree = index < 3;
|
|
@@ -64873,7 +65199,8 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64873
65199
|
rowClass,
|
|
64874
65200
|
isClickable: canOpenWorkspace(ws.line_id),
|
|
64875
65201
|
onWorkspaceClick: stableHandleWorkspaceClick,
|
|
64876
|
-
getMedalIcon: stableGetMedalIcon
|
|
65202
|
+
getMedalIcon: stableGetMedalIcon,
|
|
65203
|
+
isAssemblyMode
|
|
64877
65204
|
},
|
|
64878
65205
|
ws.workspace_uuid
|
|
64879
65206
|
);
|
|
@@ -64891,7 +65218,10 @@ function LoginView({
|
|
|
64891
65218
|
logoSrc = optifye_logo_default,
|
|
64892
65219
|
logoAlt = "Optifye",
|
|
64893
65220
|
brandName = "Optifye",
|
|
64894
|
-
onRateLimitCheck
|
|
65221
|
+
onRateLimitCheck,
|
|
65222
|
+
showDevTestLogin = false,
|
|
65223
|
+
devTestLoginLabel,
|
|
65224
|
+
onDevTestLogin
|
|
64895
65225
|
}) {
|
|
64896
65226
|
return /* @__PURE__ */ jsx(
|
|
64897
65227
|
LoginPage,
|
|
@@ -64899,7 +65229,10 @@ function LoginView({
|
|
|
64899
65229
|
logoSrc,
|
|
64900
65230
|
logoAlt,
|
|
64901
65231
|
brandName,
|
|
64902
|
-
onRateLimitCheck
|
|
65232
|
+
onRateLimitCheck,
|
|
65233
|
+
showDevTestLogin,
|
|
65234
|
+
devTestLoginLabel,
|
|
65235
|
+
onDevTestLogin
|
|
64903
65236
|
}
|
|
64904
65237
|
);
|
|
64905
65238
|
}
|
|
@@ -68034,8 +68367,84 @@ var TargetsView = ({
|
|
|
68034
68367
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
68035
68368
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
68036
68369
|
var AuthenticatedTargetsView = withAuth(React141__default.memo(TargetsViewWithDisplayNames));
|
|
68370
|
+
function useTimezone(options = {}) {
|
|
68371
|
+
const dashboardConfig = useDashboardConfig();
|
|
68372
|
+
const workspaceConfig = useWorkspaceConfig();
|
|
68373
|
+
const defaultTimezone = dashboardConfig?.dateTimeConfig?.defaultTimezone || "Asia/Kolkata";
|
|
68374
|
+
const [timezone, setTimezone] = useState(defaultTimezone);
|
|
68375
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
68376
|
+
const [error, setError] = useState(null);
|
|
68377
|
+
const fetchTimezone = useCallback(async () => {
|
|
68378
|
+
setIsLoading(true);
|
|
68379
|
+
setError(null);
|
|
68380
|
+
try {
|
|
68381
|
+
let fetchedTimezone = defaultTimezone;
|
|
68382
|
+
if (options.lineId) {
|
|
68383
|
+
fetchedTimezone = await timezoneService.getTimezoneForLine(options.lineId, defaultTimezone);
|
|
68384
|
+
} else if (options.workspaceId || workspaceConfig && "id" in workspaceConfig) {
|
|
68385
|
+
const wsId = options.workspaceId || (workspaceConfig && "id" in workspaceConfig ? workspaceConfig.id : void 0);
|
|
68386
|
+
if (wsId) {
|
|
68387
|
+
fetchedTimezone = await timezoneService.getTimezoneForWorkspace(wsId, defaultTimezone);
|
|
68388
|
+
}
|
|
68389
|
+
} else if (options.companyId || dashboardConfig && "company" in dashboardConfig) {
|
|
68390
|
+
const compId = options.companyId || (dashboardConfig && "company" in dashboardConfig ? dashboardConfig.company?.id : void 0);
|
|
68391
|
+
if (compId) {
|
|
68392
|
+
fetchedTimezone = await timezoneService.getTimezoneForCompany(compId, defaultTimezone);
|
|
68393
|
+
}
|
|
68394
|
+
}
|
|
68395
|
+
setTimezone(fetchedTimezone);
|
|
68396
|
+
} catch (err) {
|
|
68397
|
+
console.error("Error fetching timezone:", err);
|
|
68398
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch timezone"));
|
|
68399
|
+
setTimezone(defaultTimezone);
|
|
68400
|
+
} finally {
|
|
68401
|
+
setIsLoading(false);
|
|
68402
|
+
}
|
|
68403
|
+
}, [
|
|
68404
|
+
options.lineId,
|
|
68405
|
+
options.workspaceId,
|
|
68406
|
+
options.companyId,
|
|
68407
|
+
workspaceConfig,
|
|
68408
|
+
dashboardConfig,
|
|
68409
|
+
defaultTimezone
|
|
68410
|
+
]);
|
|
68411
|
+
useEffect(() => {
|
|
68412
|
+
fetchTimezone();
|
|
68413
|
+
}, [fetchTimezone]);
|
|
68414
|
+
return {
|
|
68415
|
+
timezone,
|
|
68416
|
+
isLoading,
|
|
68417
|
+
error,
|
|
68418
|
+
refetch: fetchTimezone
|
|
68419
|
+
};
|
|
68420
|
+
}
|
|
68037
68421
|
|
|
68038
68422
|
// src/views/workspace-detail-view.utils.ts
|
|
68423
|
+
var getWorkspaceDetailLayoutMode = ({
|
|
68424
|
+
workspace,
|
|
68425
|
+
showCycleTimeChart
|
|
68426
|
+
}) => {
|
|
68427
|
+
if (workspace?.monitoring_mode === "uptime") {
|
|
68428
|
+
return "uptime";
|
|
68429
|
+
}
|
|
68430
|
+
if (showCycleTimeChart === false) {
|
|
68431
|
+
return "output";
|
|
68432
|
+
}
|
|
68433
|
+
return shouldUseAssemblyCycleTimeLayout(workspace) ? "assembly_cycle" : "output";
|
|
68434
|
+
};
|
|
68435
|
+
var getCycleTimeRenderState = ({
|
|
68436
|
+
workspace,
|
|
68437
|
+
authoritativeMetrics,
|
|
68438
|
+
showCycleTimeChart
|
|
68439
|
+
}) => {
|
|
68440
|
+
if (getWorkspaceDetailLayoutMode({ workspace, showCycleTimeChart }) !== "assembly_cycle") {
|
|
68441
|
+
return "output";
|
|
68442
|
+
}
|
|
68443
|
+
if (!authoritativeMetrics) {
|
|
68444
|
+
return "chart_loading";
|
|
68445
|
+
}
|
|
68446
|
+
return authoritativeMetrics.cycle_time_data_status === "missing_clips" ? "cycle_unavailable" : "cycle_chart";
|
|
68447
|
+
};
|
|
68039
68448
|
var formatDateInTimezone = (date = /* @__PURE__ */ new Date(), timezone, options) => {
|
|
68040
68449
|
const defaultOptions = {
|
|
68041
68450
|
day: "numeric",
|
|
@@ -68419,6 +68828,7 @@ var WorkspaceDetailView = ({
|
|
|
68419
68828
|
date: cachedOverviewMetrics.date,
|
|
68420
68829
|
shift_id: cachedOverviewMetrics.shift_id,
|
|
68421
68830
|
action_name: "",
|
|
68831
|
+
action_family: cachedOverviewMetrics.action_family ?? null,
|
|
68422
68832
|
action_type: cachedOverviewMetrics.action_type ?? null,
|
|
68423
68833
|
monitoring_mode: cachedOverviewMetrics.monitoring_mode ?? "output",
|
|
68424
68834
|
shift_start: shiftDefinition?.startTime || "",
|
|
@@ -68441,23 +68851,48 @@ var WorkspaceDetailView = ({
|
|
|
68441
68851
|
idle_time_hourly: void 0
|
|
68442
68852
|
};
|
|
68443
68853
|
}, [cachedOverviewMetrics, shiftConfig?.shifts]);
|
|
68444
|
-
const
|
|
68445
|
-
const
|
|
68854
|
+
const authoritativeCycleMetrics = isHistoricView ? historicMetrics : liveMetrics;
|
|
68855
|
+
const workspace = authoritativeCycleMetrics || cachedDetailedMetrics || overviewFallback;
|
|
68856
|
+
const { timezone: cycleTimeTimezone } = useTimezone({
|
|
68857
|
+
lineId: effectiveLineId || workspace?.line_id || void 0,
|
|
68858
|
+
workspaceId: workspaceId || void 0
|
|
68859
|
+
});
|
|
68860
|
+
const effectiveCycleTimeTimezone = cycleTimeTimezone || timezone;
|
|
68861
|
+
const detailedWorkspaceMetrics = authoritativeCycleMetrics || cachedDetailedMetrics;
|
|
68446
68862
|
const cycleTimeChartData = useMemo(
|
|
68447
|
-
() => Array.isArray(
|
|
68863
|
+
() => Array.isArray(authoritativeCycleMetrics?.hourly_cycle_times) ? authoritativeCycleMetrics.hourly_cycle_times.map((value) => {
|
|
68448
68864
|
const numericValue = Number(value);
|
|
68449
68865
|
return Number.isFinite(numericValue) ? numericValue : 0;
|
|
68450
68866
|
}) : [],
|
|
68451
|
-
[
|
|
68867
|
+
[authoritativeCycleMetrics?.hourly_cycle_times]
|
|
68868
|
+
);
|
|
68869
|
+
const maskedCycleTimeChartData = useMemo(
|
|
68870
|
+
() => maskFutureHourlySeries({
|
|
68871
|
+
data: cycleTimeChartData,
|
|
68872
|
+
shiftStart: authoritativeCycleMetrics?.shift_start,
|
|
68873
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end,
|
|
68874
|
+
shiftDate: authoritativeCycleMetrics?.date || date || calculatedOperationalDate || null,
|
|
68875
|
+
timezone: effectiveCycleTimeTimezone
|
|
68876
|
+
}),
|
|
68877
|
+
[
|
|
68878
|
+
cycleTimeChartData,
|
|
68879
|
+
authoritativeCycleMetrics?.shift_start,
|
|
68880
|
+
authoritativeCycleMetrics?.shift_end,
|
|
68881
|
+
authoritativeCycleMetrics?.date,
|
|
68882
|
+
date,
|
|
68883
|
+
calculatedOperationalDate,
|
|
68884
|
+
effectiveCycleTimeTimezone
|
|
68885
|
+
]
|
|
68452
68886
|
);
|
|
68453
68887
|
const cycleTimeDatasetKey = useMemo(
|
|
68454
68888
|
() => [
|
|
68455
|
-
|
|
68456
|
-
date ||
|
|
68457
|
-
parsedShiftId ??
|
|
68458
|
-
"hourly"
|
|
68889
|
+
authoritativeCycleMetrics?.workspace_id || workspaceId || "workspace",
|
|
68890
|
+
date || authoritativeCycleMetrics?.date || "live",
|
|
68891
|
+
parsedShiftId ?? authoritativeCycleMetrics?.shift_id ?? "current",
|
|
68892
|
+
"hourly",
|
|
68893
|
+
"backend"
|
|
68459
68894
|
].join(":"),
|
|
68460
|
-
[
|
|
68895
|
+
[authoritativeCycleMetrics?.workspace_id, workspaceId, date, authoritativeCycleMetrics?.date, parsedShiftId, authoritativeCycleMetrics?.shift_id]
|
|
68461
68896
|
);
|
|
68462
68897
|
const hasWorkspaceSnapshot = Boolean(workspace);
|
|
68463
68898
|
const loading = ((isHistoricView ? historicLoading : liveLoading) || isShiftConfigLoading) && !hasWorkspaceSnapshot;
|
|
@@ -68700,22 +69135,52 @@ var WorkspaceDetailView = ({
|
|
|
68700
69135
|
return filterDataByDateKeyRange(monthlyData, range);
|
|
68701
69136
|
}, [monthlyData, range]);
|
|
68702
69137
|
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
|
|
68703
|
-
const
|
|
68704
|
-
|
|
68705
|
-
|
|
68706
|
-
|
|
68707
|
-
|
|
69138
|
+
const workspaceCycleTimeEligibility = workspace ? {
|
|
69139
|
+
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
69140
|
+
action_family: workspace.action_family,
|
|
69141
|
+
action_type: workspace.action_type
|
|
69142
|
+
} : null;
|
|
69143
|
+
const isAssemblyWorkspace = shouldUseAssemblyCycleTimeLayout(workspaceCycleTimeEligibility);
|
|
69144
|
+
const layoutMode = getWorkspaceDetailLayoutMode({
|
|
69145
|
+
workspace: workspace ? {
|
|
69146
|
+
monitoring_mode: workspace.monitoring_mode,
|
|
69147
|
+
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
69148
|
+
action_family: workspace.action_family,
|
|
69149
|
+
action_type: workspace.action_type
|
|
69150
|
+
} : null,
|
|
69151
|
+
showCycleTimeChart
|
|
69152
|
+
});
|
|
69153
|
+
const isAssemblyCycleLayout = layoutMode === "assembly_cycle";
|
|
69154
|
+
const isOutputLayout = layoutMode === "output";
|
|
69155
|
+
const cycleTimePresentation = getCycleTimeRenderState({
|
|
69156
|
+
workspace: workspace ? {
|
|
69157
|
+
monitoring_mode: workspace.monitoring_mode,
|
|
69158
|
+
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
69159
|
+
action_family: workspace.action_family,
|
|
69160
|
+
action_type: workspace.action_type
|
|
69161
|
+
} : null,
|
|
69162
|
+
authoritativeMetrics: authoritativeCycleMetrics ? {
|
|
69163
|
+
cycle_time_data_status: authoritativeCycleMetrics.cycle_time_data_status
|
|
69164
|
+
} : null,
|
|
69165
|
+
showCycleTimeChart
|
|
69166
|
+
});
|
|
69167
|
+
const shouldShowCycleTimeChart = cycleTimePresentation === "cycle_chart";
|
|
69168
|
+
const shouldShowCycleTimeUnavailableState = cycleTimePresentation === "cycle_unavailable";
|
|
69169
|
+
const shouldShowCycleTimeLoadingState = cycleTimePresentation === "chart_loading";
|
|
69170
|
+
const shouldShowAssemblyOverviewLoadingState = isAssemblyCycleLayout && shouldShowCycleTimeLoadingState && hasWorkspaceSnapshot;
|
|
69171
|
+
const showIdleBreakdownChart = !isAssemblyCycleLayout && idleTimeVlmEnabled;
|
|
69172
|
+
const canToggleChartIdleTime = !isUptimeMode && !shouldShowCycleTimeLoadingState && !shouldShowCycleTimeUnavailableState;
|
|
68708
69173
|
const idleClipDate = date || workspace?.date || calculatedOperationalDate || getOperationalDate(timezone);
|
|
68709
69174
|
const idleClipShiftId = parsedShiftId ?? workspace?.shift_id;
|
|
68710
|
-
const
|
|
69175
|
+
const rawHourlyIdleMinutes = useMemo(() => {
|
|
68711
69176
|
if (!shouldShowCycleTimeChart || !workspace?.idle_time_hourly || !workspace?.shift_start) return [];
|
|
68712
|
-
const
|
|
69177
|
+
const parseTimeToMinutes4 = (time2) => {
|
|
68713
69178
|
const [h, m] = time2.split(":").map(Number);
|
|
68714
69179
|
if (!Number.isFinite(h) || !Number.isFinite(m)) return 0;
|
|
68715
69180
|
return h * 60 + m;
|
|
68716
69181
|
};
|
|
68717
|
-
const startTotal =
|
|
68718
|
-
const endTotalRaw = workspace.shift_end ?
|
|
69182
|
+
const startTotal = parseTimeToMinutes4(workspace.shift_start);
|
|
69183
|
+
const endTotalRaw = workspace.shift_end ? parseTimeToMinutes4(workspace.shift_end) : startTotal + 11 * 60;
|
|
68719
69184
|
const endTotal = endTotalRaw <= startTotal ? endTotalRaw + 24 * 60 : endTotalRaw;
|
|
68720
69185
|
const shiftDuration = Math.max(60, endTotal - startTotal);
|
|
68721
69186
|
const totalHourSlots = Math.max(1, Math.ceil(shiftDuration / 60));
|
|
@@ -68741,6 +69206,42 @@ var WorkspaceDetailView = ({
|
|
|
68741
69206
|
}
|
|
68742
69207
|
return result;
|
|
68743
69208
|
}, [shouldShowCycleTimeChart, workspace?.idle_time_hourly, workspace?.shift_start, workspace?.shift_end]);
|
|
69209
|
+
const hourlyIdleMinutes = useMemo(
|
|
69210
|
+
() => maskFutureHourlySeries({
|
|
69211
|
+
data: rawHourlyIdleMinutes,
|
|
69212
|
+
shiftStart: workspace?.shift_start,
|
|
69213
|
+
shiftEnd: workspace?.shift_end,
|
|
69214
|
+
shiftDate: idleClipDate,
|
|
69215
|
+
timezone: effectiveCycleTimeTimezone
|
|
69216
|
+
}),
|
|
69217
|
+
[
|
|
69218
|
+
rawHourlyIdleMinutes,
|
|
69219
|
+
workspace?.shift_start,
|
|
69220
|
+
workspace?.shift_end,
|
|
69221
|
+
idleClipDate,
|
|
69222
|
+
effectiveCycleTimeTimezone
|
|
69223
|
+
]
|
|
69224
|
+
);
|
|
69225
|
+
const cycleTimeUnavailableView = useMemo(() => /* @__PURE__ */ jsxs("div", { className: "w-full h-full rounded-lg border border-amber-200 bg-amber-50/70 px-6 py-5 text-center flex flex-col items-center justify-center", children: [
|
|
69226
|
+
/* @__PURE__ */ jsx("h4", { className: "text-base font-semibold text-amber-900", children: "Cycle data unavailable" }),
|
|
69227
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 max-w-md text-sm text-amber-800", children: "This workstation has cycle-time metrics for the selected shift, but no matching `cycle_completion` clips were found for the chart." }),
|
|
69228
|
+
typeof workspace?.cycle_completion_clip_count === "number" && /* @__PURE__ */ jsxs("p", { className: "mt-3 text-xs font-medium uppercase tracking-[0.08em] text-amber-700", children: [
|
|
69229
|
+
"matched cycle clips: ",
|
|
69230
|
+
workspace.cycle_completion_clip_count
|
|
69231
|
+
] })
|
|
69232
|
+
] }), [workspace?.cycle_completion_clip_count]);
|
|
69233
|
+
const assemblyOverviewLoadingView = useMemo(() => /* @__PURE__ */ jsxs("div", { className: "space-y-4 pb-4", "data-testid": "assembly-overview-loading-state", children: [
|
|
69234
|
+
/* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg shadow-sm p-6 lg:p-8", children: /* @__PURE__ */ jsx("div", { className: "min-h-[280px] lg:min-h-[340px] flex flex-col justify-center", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-xl mx-auto animate-pulse space-y-3", children: [
|
|
69235
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 bg-gray-200 rounded-full w-3/4 mx-auto" }),
|
|
69236
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 bg-gray-100 rounded-full w-full" }),
|
|
69237
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 bg-gray-100 rounded-full w-5/6 mx-auto" })
|
|
69238
|
+
] }) }) }),
|
|
69239
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: [0, 1, 2].map((index) => /* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg shadow-sm p-5", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse space-y-3", children: [
|
|
69240
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-24 bg-gray-200 rounded" }),
|
|
69241
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 w-20 bg-gray-100 rounded" }),
|
|
69242
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 w-28 bg-gray-100 rounded" })
|
|
69243
|
+
] }) }, index)) })
|
|
69244
|
+
] }), []);
|
|
68744
69245
|
const shiftDurationMinutes = useMemo(
|
|
68745
69246
|
() => getShiftDurationMinutes(workspace?.shift_start, workspace?.shift_end),
|
|
68746
69247
|
[workspace?.shift_start, workspace?.shift_end]
|
|
@@ -68795,7 +69296,7 @@ var WorkspaceDetailView = ({
|
|
|
68795
69296
|
}, [isUptimeMode, uptimeSeries, shiftDurationMinutes, elapsedShiftMinutes, workspace?.idle_time]);
|
|
68796
69297
|
const overviewTabLabel = isUptimeMode ? "Utilization" : "Efficiency";
|
|
68797
69298
|
const idleClipFetchEnabled = Boolean(
|
|
68798
|
-
workspaceId && idleClipDate && idleClipShiftId !== void 0 && activeTab === "overview" && idleTimeVlmEnabled &&
|
|
69299
|
+
workspaceId && idleClipDate && idleClipShiftId !== void 0 && activeTab === "overview" && idleTimeVlmEnabled && isOutputLayout
|
|
68799
69300
|
);
|
|
68800
69301
|
const {
|
|
68801
69302
|
idleClips: idleTimeClips,
|
|
@@ -68866,7 +69367,7 @@ var WorkspaceDetailView = ({
|
|
|
68866
69367
|
}
|
|
68867
69368
|
}
|
|
68868
69369
|
};
|
|
68869
|
-
const
|
|
69370
|
+
const getShiftIcon2 = (shiftType) => {
|
|
68870
69371
|
const shiftTypeLower = shiftType?.toLowerCase() || "";
|
|
68871
69372
|
if (shiftTypeLower.includes("day") || shiftTypeLower.includes("morning")) {
|
|
68872
69373
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
@@ -69015,7 +69516,7 @@ var WorkspaceDetailView = ({
|
|
|
69015
69516
|
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: (() => {
|
|
69016
69517
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
69017
69518
|
const shiftName = shift2?.shiftName || (selectedShift === 0 ? "Day Shift" : "Night Shift");
|
|
69018
|
-
return
|
|
69519
|
+
return getShiftIcon2(shiftName);
|
|
69019
69520
|
})() }),
|
|
69020
69521
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: (() => {
|
|
69021
69522
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
@@ -69043,7 +69544,7 @@ var WorkspaceDetailView = ({
|
|
|
69043
69544
|
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: (() => {
|
|
69044
69545
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
69045
69546
|
const shiftName = shift2?.shiftName || (selectedShift === 0 ? "Day Shift" : "Night Shift");
|
|
69046
|
-
return
|
|
69547
|
+
return getShiftIcon2(shiftName);
|
|
69047
69548
|
})() }),
|
|
69048
69549
|
/* @__PURE__ */ jsx("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: (() => {
|
|
69049
69550
|
const shift2 = shiftConfig?.shifts?.find((s) => s.shiftId === selectedShift);
|
|
@@ -69056,7 +69557,7 @@ var WorkspaceDetailView = ({
|
|
|
69056
69557
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
|
|
69057
69558
|
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-gray-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: formatISTDate2(new Date(workspace.date)) }) }),
|
|
69058
69559
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
69059
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children:
|
|
69560
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(workspace.shift_type) }),
|
|
69060
69561
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: workspace.shift_type })
|
|
69061
69562
|
] }),
|
|
69062
69563
|
!date && !shift && !usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-green-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-green-700", children: /* @__PURE__ */ jsx(LiveTimer, {}) }) }) : date ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-blue-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-blue-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-amber-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-amber-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : null
|
|
@@ -69087,7 +69588,7 @@ var WorkspaceDetailView = ({
|
|
|
69087
69588
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" })
|
|
69088
69589
|
] }),
|
|
69089
69590
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
69090
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children:
|
|
69591
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon2(workspace.shift_type) }),
|
|
69091
69592
|
/* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-semibold uppercase tracking-wider", children: [
|
|
69092
69593
|
workspace.shift_type.replace(/ Shift$/i, ""),
|
|
69093
69594
|
" Shift"
|
|
@@ -69206,9 +69707,9 @@ var WorkspaceDetailView = ({
|
|
|
69206
69707
|
] })
|
|
69207
69708
|
] }),
|
|
69208
69709
|
/* @__PURE__ */ jsxs("div", { className: "flex-grow p-1.5 sm:p-2 lg:p-4", children: [
|
|
69209
|
-
activeTab === "overview" && /* @__PURE__ */
|
|
69710
|
+
activeTab === "overview" && /* @__PURE__ */ jsx("div", { className: "flex flex-col h-full lg:h-[calc(100vh-12rem)] overflow-y-auto lg:min-h-0 pb-4", children: shouldShowAssemblyOverviewLoadingState ? assemblyOverviewLoadingView : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
69210
69711
|
/* @__PURE__ */ jsxs("div", { className: "block lg:hidden space-y-6 pb-6", children: [
|
|
69211
|
-
|
|
69712
|
+
isOutputLayout && !isUptimeMode && /* @__PURE__ */ jsxs(
|
|
69212
69713
|
motion.div,
|
|
69213
69714
|
{
|
|
69214
69715
|
className: "bg-white rounded-lg shadow-sm p-6 h-[300px]",
|
|
@@ -69236,8 +69737,8 @@ var WorkspaceDetailView = ({
|
|
|
69236
69737
|
animate: "animate",
|
|
69237
69738
|
children: [
|
|
69238
69739
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
|
|
69239
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" :
|
|
69240
|
-
|
|
69740
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : isAssemblyCycleLayout ? "Cycle time trend" : "Hourly Output" }),
|
|
69741
|
+
canToggleChartIdleTime && /* @__PURE__ */ jsx(
|
|
69241
69742
|
"button",
|
|
69242
69743
|
{
|
|
69243
69744
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69266,19 +69767,19 @@ var WorkspaceDetailView = ({
|
|
|
69266
69767
|
timezone,
|
|
69267
69768
|
elapsedMinutes: elapsedShiftMinutes
|
|
69268
69769
|
}
|
|
69269
|
-
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69770
|
+
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69270
69771
|
CycleTimeOverTimeChart,
|
|
69271
69772
|
{
|
|
69272
|
-
data:
|
|
69273
|
-
idealCycleTime:
|
|
69274
|
-
shiftStart:
|
|
69275
|
-
shiftEnd:
|
|
69773
|
+
data: maskedCycleTimeChartData,
|
|
69774
|
+
idealCycleTime: authoritativeCycleMetrics?.ideal_cycle_time || 0,
|
|
69775
|
+
shiftStart: authoritativeCycleMetrics?.shift_start || "",
|
|
69776
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end || "",
|
|
69276
69777
|
xAxisMode: "hourly",
|
|
69277
69778
|
datasetKey: cycleTimeDatasetKey,
|
|
69278
69779
|
showIdleTime: showChartIdleTime,
|
|
69279
69780
|
idleTimeData: hourlyIdleMinutes
|
|
69280
69781
|
}
|
|
69281
|
-
) : /* @__PURE__ */ jsx(
|
|
69782
|
+
) : null : /* @__PURE__ */ jsx(
|
|
69282
69783
|
HourlyOutputChart2,
|
|
69283
69784
|
{
|
|
69284
69785
|
data: workspace.hourly_action_counts || [],
|
|
@@ -69298,7 +69799,7 @@ var WorkspaceDetailView = ({
|
|
|
69298
69799
|
]
|
|
69299
69800
|
}
|
|
69300
69801
|
),
|
|
69301
|
-
|
|
69802
|
+
showIdleBreakdownChart && /* @__PURE__ */ jsxs(
|
|
69302
69803
|
motion.div,
|
|
69303
69804
|
{
|
|
69304
69805
|
className: "bg-white rounded-lg shadow-sm p-4 h-[300px]",
|
|
@@ -69318,7 +69819,7 @@ var WorkspaceDetailView = ({
|
|
|
69318
69819
|
]
|
|
69319
69820
|
}
|
|
69320
69821
|
),
|
|
69321
|
-
isUptimeMode ? /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData }) :
|
|
69822
|
+
isUptimeMode ? /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData }) : isAssemblyCycleLayout ? /* @__PURE__ */ jsx(
|
|
69322
69823
|
WorkspaceCycleTimeMetricCards,
|
|
69323
69824
|
{
|
|
69324
69825
|
workspace,
|
|
@@ -69338,7 +69839,7 @@ var WorkspaceDetailView = ({
|
|
|
69338
69839
|
desktopTopSectionClass
|
|
69339
69840
|
),
|
|
69340
69841
|
children: [
|
|
69341
|
-
|
|
69842
|
+
isOutputLayout && !isUptimeMode && /* @__PURE__ */ jsxs(
|
|
69342
69843
|
motion.div,
|
|
69343
69844
|
{
|
|
69344
69845
|
className: "bg-white rounded-lg shadow-sm p-4 lg:col-span-2 flex flex-col min-h-0",
|
|
@@ -69362,15 +69863,15 @@ var WorkspaceDetailView = ({
|
|
|
69362
69863
|
{
|
|
69363
69864
|
className: clsx(
|
|
69364
69865
|
"bg-white rounded-lg shadow-sm p-4 flex flex-col min-h-0",
|
|
69365
|
-
isUptimeMode && showIdleBreakdownChart ? "lg:col-span-2" :
|
|
69866
|
+
isUptimeMode && showIdleBreakdownChart ? "lg:col-span-2" : isAssemblyCycleLayout || isUptimeMode ? "lg:col-span-10" : idleTimeVlmEnabled ? "lg:col-span-6" : "lg:col-span-8"
|
|
69366
69867
|
),
|
|
69367
69868
|
variants: chartCardVariants,
|
|
69368
69869
|
initial: "initial",
|
|
69369
69870
|
animate: "animate",
|
|
69370
69871
|
children: [
|
|
69371
69872
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 mb-4 flex-none", children: [
|
|
69372
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" :
|
|
69373
|
-
|
|
69873
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : isAssemblyCycleLayout ? "Cycle time trend" : "Hourly Output" }),
|
|
69874
|
+
canToggleChartIdleTime && /* @__PURE__ */ jsx(
|
|
69374
69875
|
"button",
|
|
69375
69876
|
{
|
|
69376
69877
|
onClick: () => setShowChartIdleTime(!showChartIdleTime),
|
|
@@ -69395,19 +69896,19 @@ var WorkspaceDetailView = ({
|
|
|
69395
69896
|
timezone,
|
|
69396
69897
|
elapsedMinutes: elapsedShiftMinutes
|
|
69397
69898
|
}
|
|
69398
|
-
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69899
|
+
) : isAssemblyCycleLayout ? shouldShowCycleTimeUnavailableState ? cycleTimeUnavailableView : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
69399
69900
|
CycleTimeOverTimeChart,
|
|
69400
69901
|
{
|
|
69401
|
-
data:
|
|
69402
|
-
idealCycleTime:
|
|
69403
|
-
shiftStart:
|
|
69404
|
-
shiftEnd:
|
|
69902
|
+
data: maskedCycleTimeChartData,
|
|
69903
|
+
idealCycleTime: authoritativeCycleMetrics?.ideal_cycle_time || 0,
|
|
69904
|
+
shiftStart: authoritativeCycleMetrics?.shift_start || "",
|
|
69905
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end || "",
|
|
69405
69906
|
xAxisMode: "hourly",
|
|
69406
69907
|
datasetKey: cycleTimeDatasetKey,
|
|
69407
69908
|
showIdleTime: showChartIdleTime,
|
|
69408
69909
|
idleTimeData: hourlyIdleMinutes
|
|
69409
69910
|
}
|
|
69410
|
-
) : /* @__PURE__ */ jsx(
|
|
69911
|
+
) : null : /* @__PURE__ */ jsx(
|
|
69411
69912
|
HourlyOutputChart2,
|
|
69412
69913
|
{
|
|
69413
69914
|
data: workspace.hourly_action_counts || [],
|
|
@@ -69425,7 +69926,7 @@ var WorkspaceDetailView = ({
|
|
|
69425
69926
|
]
|
|
69426
69927
|
}
|
|
69427
69928
|
),
|
|
69428
|
-
|
|
69929
|
+
showIdleBreakdownChart && /* @__PURE__ */ jsxs(
|
|
69429
69930
|
motion.div,
|
|
69430
69931
|
{
|
|
69431
69932
|
className: clsx(
|
|
@@ -69451,7 +69952,7 @@ var WorkspaceDetailView = ({
|
|
|
69451
69952
|
]
|
|
69452
69953
|
}
|
|
69453
69954
|
),
|
|
69454
|
-
isUptimeMode ? /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData, className: "flex-1" }) }) :
|
|
69955
|
+
isUptimeMode ? /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(UptimeMetricCards, { workspace, uptimePieData, className: "flex-1" }) }) : isAssemblyCycleLayout ? /* @__PURE__ */ jsx(
|
|
69455
69956
|
WorkspaceCycleTimeMetricCards,
|
|
69456
69957
|
{
|
|
69457
69958
|
workspace,
|
|
@@ -69462,7 +69963,7 @@ var WorkspaceDetailView = ({
|
|
|
69462
69963
|
}
|
|
69463
69964
|
) : /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, legend: efficiencyLegend, className: "flex-1" }) })
|
|
69464
69965
|
] })
|
|
69465
|
-
] }),
|
|
69966
|
+
] }) }),
|
|
69466
69967
|
activeTab === "monthly_history" && /* @__PURE__ */ jsxs("div", { className: "h-[calc(100vh-10rem)] overflow-y-auto px-2 sm:px-4 lg:px-0", children: [
|
|
69467
69968
|
usingFallbackData && !date && !shift && /* @__PURE__ */ jsx("div", { className: "mb-3 sm:mb-4 bg-amber-50 border border-amber-200 rounded-lg px-3 sm:px-4 py-2 sm:py-3 text-amber-800", children: /* @__PURE__ */ jsxs("p", { className: "text-xs sm:text-sm font-medium flex items-center", children: [
|
|
69468
69969
|
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-4 w-4 sm:h-5 sm:w-5 mr-2", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }),
|
|
@@ -72094,7 +72595,7 @@ var normalizeLabel = (value) => {
|
|
|
72094
72595
|
const trimmed = value.trim();
|
|
72095
72596
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
72096
72597
|
};
|
|
72097
|
-
var
|
|
72598
|
+
var toFiniteNumber2 = (value) => {
|
|
72098
72599
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
72099
72600
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
72100
72601
|
const parsed = Number(value);
|
|
@@ -72128,7 +72629,7 @@ var formatImprovementPieceGain = (pcsGain) => {
|
|
|
72128
72629
|
var getPositiveImprovementGain = ({
|
|
72129
72630
|
estimated_gain_pieces
|
|
72130
72631
|
}) => {
|
|
72131
|
-
const issueGain =
|
|
72632
|
+
const issueGain = toFiniteNumber2(estimated_gain_pieces);
|
|
72132
72633
|
return {
|
|
72133
72634
|
pcsGain: issueGain !== null && issueGain > 0 ? issueGain : null
|
|
72134
72635
|
};
|
|
@@ -72136,7 +72637,7 @@ var getPositiveImprovementGain = ({
|
|
|
72136
72637
|
var getImprovementPcsGainSortValue = (input) => {
|
|
72137
72638
|
const { pcsGain } = getPositiveImprovementGain(input);
|
|
72138
72639
|
if (pcsGain !== null) return pcsGain;
|
|
72139
|
-
const raw =
|
|
72640
|
+
const raw = toFiniteNumber2(input.estimated_gain_pieces);
|
|
72140
72641
|
return raw ?? null;
|
|
72141
72642
|
};
|
|
72142
72643
|
var getImprovementDisplayMetadata = ({
|
|
@@ -72156,7 +72657,7 @@ var getImprovementDisplayMetadata = ({
|
|
|
72156
72657
|
metadataLabel: [workstationLabel, lineLabel, supervisorLabel].join(" \xB7 ")
|
|
72157
72658
|
};
|
|
72158
72659
|
};
|
|
72159
|
-
var
|
|
72660
|
+
var toFiniteNumber3 = (value) => {
|
|
72160
72661
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
72161
72662
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
72162
72663
|
const parsed = Number(value);
|
|
@@ -72184,15 +72685,15 @@ var compareImprovementRecommendationPriority = (left, right) => {
|
|
|
72184
72685
|
if (leftIndustrial !== rightIndustrial) {
|
|
72185
72686
|
return rightIndustrial - leftIndustrial;
|
|
72186
72687
|
}
|
|
72187
|
-
const leftGain =
|
|
72188
|
-
const rightGain =
|
|
72688
|
+
const leftGain = toFiniteNumber3(left.estimated_gain_pieces);
|
|
72689
|
+
const rightGain = toFiniteNumber3(right.estimated_gain_pieces);
|
|
72189
72690
|
if (leftGain !== rightGain) {
|
|
72190
72691
|
if (leftGain === null) return 1;
|
|
72191
72692
|
if (rightGain === null) return -1;
|
|
72192
72693
|
return rightGain - leftGain;
|
|
72193
72694
|
}
|
|
72194
|
-
const leftRatio =
|
|
72195
|
-
const rightRatio =
|
|
72695
|
+
const leftRatio = toFiniteNumber3(left.gain_to_target_ratio);
|
|
72696
|
+
const rightRatio = toFiniteNumber3(right.gain_to_target_ratio);
|
|
72196
72697
|
if (leftRatio !== rightRatio) {
|
|
72197
72698
|
if (leftRatio === null) return 1;
|
|
72198
72699
|
if (rightRatio === null) return -1;
|
|
@@ -75497,6 +75998,7 @@ var EMPTY_OVERVIEW_POOREST_LINES = {
|
|
|
75497
75998
|
};
|
|
75498
75999
|
var EMPTY_OVERVIEW_TREND = {
|
|
75499
76000
|
shift_mode: "all",
|
|
76001
|
+
granularity: "day",
|
|
75500
76002
|
points: []
|
|
75501
76003
|
};
|
|
75502
76004
|
var EMPTY_IDLE_BREAKDOWN = [];
|
|
@@ -75569,8 +76071,11 @@ var normalizePoorestLines = (value) => ({
|
|
|
75569
76071
|
});
|
|
75570
76072
|
var normalizeTrend = (value) => ({
|
|
75571
76073
|
shift_mode: value?.shift_mode || "all",
|
|
76074
|
+
granularity: value?.granularity === "hour" ? "hour" : "day",
|
|
75572
76075
|
points: (value?.points || []).map((point) => ({
|
|
75573
76076
|
date: point?.date,
|
|
76077
|
+
label: point?.label,
|
|
76078
|
+
hour_index: normalizeNumber(point?.hour_index),
|
|
75574
76079
|
avg_efficiency: normalizeNumber(point?.avg_efficiency)
|
|
75575
76080
|
}))
|
|
75576
76081
|
});
|
|
@@ -75912,17 +76417,25 @@ var formatSignedIdleDuration = (seconds) => {
|
|
|
75912
76417
|
const sign = seconds > 0 ? "+" : "-";
|
|
75913
76418
|
return `${sign}${formatIdleDuration(Math.abs(seconds))}`;
|
|
75914
76419
|
};
|
|
75915
|
-
var formatComparisonWindow = (
|
|
76420
|
+
var formatComparisonWindow = ({
|
|
76421
|
+
currentDayCount,
|
|
76422
|
+
previousDayCount,
|
|
76423
|
+
comparisonStrategy,
|
|
76424
|
+
shiftMode
|
|
76425
|
+
}) => {
|
|
75916
76426
|
if (comparisonStrategy === "previous_full_week") return "last week";
|
|
75917
|
-
if (
|
|
75918
|
-
|
|
76427
|
+
if (comparisonStrategy === "matched_range" && shiftMode !== "all" && currentDayCount === 1 && previousDayCount === 1) {
|
|
76428
|
+
return "previous day";
|
|
76429
|
+
}
|
|
76430
|
+
if (!previousDayCount || !Number.isFinite(previousDayCount)) return "previous range";
|
|
76431
|
+
return `previous ${previousDayCount} ${previousDayCount === 1 ? "day" : "days"}`;
|
|
75919
76432
|
};
|
|
75920
76433
|
var buildDeltaBadge = (delta, options) => {
|
|
75921
76434
|
if (delta === null || delta === void 0 || !Number.isFinite(delta)) {
|
|
75922
76435
|
return {
|
|
75923
76436
|
icon: null,
|
|
75924
|
-
className: "bg-slate-100 text-slate-
|
|
75925
|
-
text:
|
|
76437
|
+
className: "bg-slate-100 text-slate-400",
|
|
76438
|
+
text: "\u2014"
|
|
75926
76439
|
};
|
|
75927
76440
|
}
|
|
75928
76441
|
const direction = delta >= 0 ? "up" : "down";
|
|
@@ -75933,6 +76446,25 @@ var buildDeltaBadge = (delta, options) => {
|
|
|
75933
76446
|
text: `${options.formatter(delta)} vs ${options.comparisonLabel}`
|
|
75934
76447
|
};
|
|
75935
76448
|
};
|
|
76449
|
+
var normalizeShiftLabel = (shiftName, shiftMode) => {
|
|
76450
|
+
const trimmedName = shiftName?.trim();
|
|
76451
|
+
if (trimmedName) {
|
|
76452
|
+
return /shift/i.test(trimmedName) ? trimmedName : `${trimmedName} Shift`;
|
|
76453
|
+
}
|
|
76454
|
+
if (shiftMode === "night") return "Night Shift";
|
|
76455
|
+
return "Day Shift";
|
|
76456
|
+
};
|
|
76457
|
+
var getShiftIcon = (shiftName, shiftMode) => {
|
|
76458
|
+
const normalizedName = (shiftName || "").toLowerCase();
|
|
76459
|
+
const normalizedMode = shiftMode || "day";
|
|
76460
|
+
if (normalizedName.includes("day") || normalizedName.includes("morning") || normalizedMode === "day") {
|
|
76461
|
+
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
76462
|
+
}
|
|
76463
|
+
if (normalizedName.includes("night") || normalizedName.includes("evening") || normalizedMode === "night") {
|
|
76464
|
+
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" }) });
|
|
76465
|
+
}
|
|
76466
|
+
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" }) });
|
|
76467
|
+
};
|
|
75936
76468
|
var buildLineDeltaTone = (delta, comparisonLabel) => {
|
|
75937
76469
|
if (delta === null || delta === void 0 || !Number.isFinite(delta)) {
|
|
75938
76470
|
return {
|
|
@@ -75988,6 +76520,8 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
75988
76520
|
dateRange,
|
|
75989
76521
|
displayDateRange,
|
|
75990
76522
|
trendMode,
|
|
76523
|
+
isLiveScope,
|
|
76524
|
+
liveShiftName,
|
|
75991
76525
|
lineOptions,
|
|
75992
76526
|
supervisorOptions,
|
|
75993
76527
|
selectedSupervisorId,
|
|
@@ -76001,6 +76535,14 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76001
76535
|
}) => {
|
|
76002
76536
|
bumpRenderCounter();
|
|
76003
76537
|
const subtitleRange = displayDateRange || dateRange;
|
|
76538
|
+
const liveShiftLabel = React141__default.useMemo(
|
|
76539
|
+
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
76540
|
+
[liveShiftName, trendMode]
|
|
76541
|
+
);
|
|
76542
|
+
const liveShiftIcon = React141__default.useMemo(
|
|
76543
|
+
() => getShiftIcon(liveShiftName, trendMode),
|
|
76544
|
+
[liveShiftName, trendMode]
|
|
76545
|
+
);
|
|
76004
76546
|
const [isFilterOpen, setIsFilterOpen] = React141__default.useState(false);
|
|
76005
76547
|
const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React141__default.useState(false);
|
|
76006
76548
|
const filterRef = React141__default.useRef(null);
|
|
@@ -76117,9 +76659,25 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76117
76659
|
className: "flex-shrink-0 -ml-1"
|
|
76118
76660
|
}
|
|
76119
76661
|
) : /* @__PURE__ */ jsx("div", { className: "w-8 flex-shrink-0" }),
|
|
76120
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center", children: [
|
|
76121
|
-
/* @__PURE__ */
|
|
76122
|
-
|
|
76662
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center min-w-0", children: [
|
|
76663
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-1.5 min-w-0 max-w-[240px]", children: [
|
|
76664
|
+
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900 leading-tight text-center truncate", children: "Operations Overview" }),
|
|
76665
|
+
isLiveScope ? /* @__PURE__ */ jsx(
|
|
76666
|
+
"div",
|
|
76667
|
+
{
|
|
76668
|
+
"data-testid": "operations-overview-live-indicator",
|
|
76669
|
+
className: "h-2 w-2 rounded-full bg-emerald-500 animate-pulse ring-2 ring-emerald-500/20 flex-shrink-0"
|
|
76670
|
+
}
|
|
76671
|
+
) : null
|
|
76672
|
+
] }),
|
|
76673
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1 flex flex-wrap items-center justify-center gap-x-2 gap-y-1 text-[11px] font-medium text-slate-500 min-w-0", children: [
|
|
76674
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-center", children: mobileSubtitle }),
|
|
76675
|
+
isLiveScope ? /* @__PURE__ */ jsx("span", { className: "text-slate-300", children: "|" }) : null,
|
|
76676
|
+
isLiveScope ? /* @__PURE__ */ jsx("span", { "data-testid": "operations-overview-live-meta", className: "inline-flex items-center gap-1.5 text-gray-600 min-w-0", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 justify-center truncate", children: [
|
|
76677
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-75 shrink-0", children: liveShiftIcon }),
|
|
76678
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: liveShiftLabel })
|
|
76679
|
+
] }) }) : null
|
|
76680
|
+
] })
|
|
76123
76681
|
] }),
|
|
76124
76682
|
/* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 flex items-center gap-1.5", children: [
|
|
76125
76683
|
/* @__PURE__ */ jsx(
|
|
@@ -76138,22 +76696,40 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76138
76696
|
{
|
|
76139
76697
|
ref: mobileFilterButtonRef,
|
|
76140
76698
|
onClick: handleFilterToggle,
|
|
76141
|
-
className: `p-2 rounded-full transition-colors relative ${isFilterOpen || activeFilterCount > 0 ? "bg-
|
|
76699
|
+
className: `p-2 rounded-full transition-colors relative ${isFilterOpen || activeFilterCount > 0 ? "bg-slate-100 text-slate-700" : "active:bg-gray-100 text-slate-600"}`,
|
|
76142
76700
|
"aria-label": "Open filters",
|
|
76143
76701
|
children: [
|
|
76144
|
-
/* @__PURE__ */ jsx(Filter, { className:
|
|
76145
|
-
activeFilterCount > 0 ? /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 flex items-center justify-center w-4 h-4 bg-
|
|
76702
|
+
/* @__PURE__ */ jsx(Filter, { className: "w-5 h-5" }),
|
|
76703
|
+
activeFilterCount > 0 ? /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 flex items-center justify-center w-4 h-4 bg-slate-700 text-white text-[10px] rounded-full font-bold", children: activeFilterCount }) : null
|
|
76146
76704
|
]
|
|
76147
76705
|
}
|
|
76148
76706
|
)
|
|
76149
76707
|
] })
|
|
76150
76708
|
] }) }),
|
|
76151
|
-
/* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center relative min-h-[
|
|
76152
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute left-1/2 -translate-x-1/2 flex flex-col items-center
|
|
76153
|
-
/* @__PURE__ */
|
|
76154
|
-
|
|
76709
|
+
/* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center relative min-h-[64px]", children: [
|
|
76710
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute left-1/2 -translate-x-1/2 flex flex-col items-center min-w-0 max-w-[min(70vw,720px)]", children: [
|
|
76711
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 min-w-0 max-w-full", children: [
|
|
76712
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl md:text-3xl lg:text-4xl font-semibold text-gray-900 tracking-tight leading-tight text-center truncate max-w-full", children: "Operations Overview" }),
|
|
76713
|
+
isLiveScope ? /* @__PURE__ */ jsx(
|
|
76714
|
+
"div",
|
|
76715
|
+
{
|
|
76716
|
+
"data-testid": "operations-overview-live-indicator",
|
|
76717
|
+
className: "h-1.5 w-1.5 md:h-2 md:w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1 flex-shrink-0"
|
|
76718
|
+
}
|
|
76719
|
+
) : null
|
|
76720
|
+
] }),
|
|
76721
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center justify-center gap-x-3 gap-y-1 text-xs sm:text-sm font-medium text-slate-500 text-center", children: [
|
|
76722
|
+
/* @__PURE__ */ jsx("span", { children: desktopSubtitle }),
|
|
76723
|
+
isLiveScope ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
76724
|
+
/* @__PURE__ */ jsx("span", { className: "text-slate-300", children: "|" }),
|
|
76725
|
+
/* @__PURE__ */ jsx("span", { "data-testid": "operations-overview-live-meta", className: "inline-flex items-center gap-1.5 text-gray-600", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 justify-center", children: [
|
|
76726
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-75", children: liveShiftIcon }),
|
|
76727
|
+
liveShiftLabel
|
|
76728
|
+
] }) })
|
|
76729
|
+
] }) : null
|
|
76730
|
+
] })
|
|
76155
76731
|
] }),
|
|
76156
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute right-0 flex items-center gap-3", children: [
|
|
76732
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute right-0 flex items-center gap-3 shrink-0", children: [
|
|
76157
76733
|
/* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx(
|
|
76158
76734
|
MonthlyRangeFilter_default,
|
|
76159
76735
|
{
|
|
@@ -76170,12 +76746,12 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76170
76746
|
{
|
|
76171
76747
|
ref: filterButtonRef,
|
|
76172
76748
|
onClick: handleFilterToggle,
|
|
76173
|
-
className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || activeFilterCount > 0 ? "border-
|
|
76749
|
+
className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || activeFilterCount > 0 ? "border-slate-300 bg-slate-50 text-slate-700" : "border-slate-200 bg-white text-slate-600 hover:bg-slate-50 hover:text-slate-700"}`,
|
|
76174
76750
|
"aria-label": "Open filters",
|
|
76175
76751
|
children: [
|
|
76176
|
-
/* @__PURE__ */ jsx(Filter, { className: `w-[18px] h-[18px] ${activeFilterCount > 0 ? "text-
|
|
76752
|
+
/* @__PURE__ */ jsx(Filter, { className: `w-[18px] h-[18px] ${isFilterOpen || activeFilterCount > 0 ? "text-slate-500" : "text-slate-400"}` }),
|
|
76177
76753
|
"Filters",
|
|
76178
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 ml-0.5 transition-transform duration-200 ${isFilterOpen ? "rotate-180" : ""}` })
|
|
76754
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 ml-0.5 text-slate-400 transition-transform duration-200 ${isFilterOpen ? "rotate-180" : ""}` })
|
|
76179
76755
|
]
|
|
76180
76756
|
}
|
|
76181
76757
|
)
|
|
@@ -76303,11 +76879,18 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76303
76879
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
76304
76880
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
76305
76881
|
const comparisonLabel = React141__default.useMemo(() => {
|
|
76306
|
-
return formatComparisonWindow(
|
|
76307
|
-
scope.
|
|
76308
|
-
scope.
|
|
76309
|
-
|
|
76310
|
-
|
|
76882
|
+
return formatComparisonWindow({
|
|
76883
|
+
currentDayCount: scope.current_range?.day_count ?? null,
|
|
76884
|
+
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
76885
|
+
comparisonStrategy: scope.comparison_strategy,
|
|
76886
|
+
shiftMode: scope.shift_mode
|
|
76887
|
+
});
|
|
76888
|
+
}, [
|
|
76889
|
+
scope.comparison_strategy,
|
|
76890
|
+
scope.current_range?.day_count,
|
|
76891
|
+
scope.previous_range?.day_count,
|
|
76892
|
+
scope.shift_mode
|
|
76893
|
+
]);
|
|
76311
76894
|
const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React141__default.useState(false);
|
|
76312
76895
|
const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React141__default.useState(false);
|
|
76313
76896
|
const idleContributorsRef = React141__default.useRef(null);
|
|
@@ -76397,10 +76980,17 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76397
76980
|
roundOne(snapshot.data.summary.plant_efficiency.current),
|
|
76398
76981
|
"%"
|
|
76399
76982
|
] }),
|
|
76400
|
-
/* @__PURE__ */ jsxs(
|
|
76401
|
-
|
|
76402
|
-
|
|
76403
|
-
|
|
76983
|
+
/* @__PURE__ */ jsxs(
|
|
76984
|
+
"div",
|
|
76985
|
+
{
|
|
76986
|
+
"data-testid": "operations-overview-efficiency-delta",
|
|
76987
|
+
className: `flex items-center gap-1 px-2.5 py-1 rounded-full ${plantEfficiencyBadge.className}`,
|
|
76988
|
+
children: [
|
|
76989
|
+
plantEfficiencyBadge.icon === "up" ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : plantEfficiencyBadge.icon === "down" ? /* @__PURE__ */ jsx(ArrowDown, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : null,
|
|
76990
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-sm font-medium", children: plantEfficiencyBadge.text })
|
|
76991
|
+
]
|
|
76992
|
+
}
|
|
76993
|
+
)
|
|
76404
76994
|
] }) : /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-slate-400", children: "No efficiency data available" })
|
|
76405
76995
|
] }),
|
|
76406
76996
|
/* @__PURE__ */ jsxs(
|
|
@@ -76446,10 +77036,17 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76446
77036
|
/* @__PURE__ */ jsx("div", { className: "mb-1", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-700", children: "Idle Time per Workstation" }) }),
|
|
76447
77037
|
showSnapshotSkeleton ? /* @__PURE__ */ jsx(OverviewMetricCardSkeleton, {}) : snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:gap-3 mt-1", children: [
|
|
76448
77038
|
/* @__PURE__ */ jsx("span", { className: "text-2xl sm:text-3xl font-bold text-slate-800 tracking-tight", children: formatIdleDuration(snapshot.data.summary.avg_idle_per_workstation.current_seconds) }),
|
|
76449
|
-
/* @__PURE__ */ jsxs(
|
|
76450
|
-
|
|
76451
|
-
|
|
76452
|
-
|
|
77039
|
+
/* @__PURE__ */ jsxs(
|
|
77040
|
+
"div",
|
|
77041
|
+
{
|
|
77042
|
+
"data-testid": "operations-overview-idle-delta",
|
|
77043
|
+
className: `flex items-center gap-1 px-2.5 py-1 rounded-full ${idleBadge.className}`,
|
|
77044
|
+
children: [
|
|
77045
|
+
idleBadge.icon === "up" ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : idleBadge.icon === "down" ? /* @__PURE__ */ jsx(ArrowDown, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }) : null,
|
|
77046
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-sm font-medium", children: idleBadge.text })
|
|
77047
|
+
]
|
|
77048
|
+
}
|
|
77049
|
+
)
|
|
76453
77050
|
] }) : /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-slate-400", children: "No idle time data available" })
|
|
76454
77051
|
]
|
|
76455
77052
|
}
|
|
@@ -76512,11 +77109,18 @@ var PoorestPerformersCard = React141__default.memo(({
|
|
|
76512
77109
|
}
|
|
76513
77110
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
76514
77111
|
const comparisonLabel = React141__default.useMemo(() => {
|
|
76515
|
-
return formatComparisonWindow(
|
|
76516
|
-
scope.
|
|
76517
|
-
scope.
|
|
76518
|
-
|
|
76519
|
-
|
|
77112
|
+
return formatComparisonWindow({
|
|
77113
|
+
currentDayCount: scope.current_range?.day_count ?? null,
|
|
77114
|
+
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
77115
|
+
comparisonStrategy: scope.comparison_strategy,
|
|
77116
|
+
shiftMode: scope.shift_mode
|
|
77117
|
+
});
|
|
77118
|
+
}, [
|
|
77119
|
+
scope.comparison_strategy,
|
|
77120
|
+
scope.current_range?.day_count,
|
|
77121
|
+
scope.previous_range?.day_count,
|
|
77122
|
+
scope.shift_mode
|
|
77123
|
+
]);
|
|
76520
77124
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
76521
77125
|
const mergedPoorestLines = React141__default.useMemo(() => {
|
|
76522
77126
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
@@ -76673,7 +77277,8 @@ IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
|
76673
77277
|
var EfficiencyTrendCard = React141__default.memo(({
|
|
76674
77278
|
store,
|
|
76675
77279
|
dateRange,
|
|
76676
|
-
appTimezone
|
|
77280
|
+
appTimezone,
|
|
77281
|
+
hourlyLabelStartTime
|
|
76677
77282
|
}) => {
|
|
76678
77283
|
bumpRenderCounter();
|
|
76679
77284
|
const trend = useOperationsOverviewTrend(store);
|
|
@@ -76683,7 +77288,41 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
76683
77288
|
);
|
|
76684
77289
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
76685
77290
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
77291
|
+
const isHourlyTrend = trend.data.granularity === "hour";
|
|
76686
77292
|
const trendData = React141__default.useMemo(() => {
|
|
77293
|
+
if (isHourlyTrend) {
|
|
77294
|
+
return (trend.data.points || []).map((point, index) => ({
|
|
77295
|
+
name: (() => {
|
|
77296
|
+
const rawLabel = point.label?.trim() || "";
|
|
77297
|
+
if (!hourlyLabelStartTime) {
|
|
77298
|
+
return rawLabel || `Hour ${index + 1}`;
|
|
77299
|
+
}
|
|
77300
|
+
if (rawLabel && !/^Hour\s+\d+$/i.test(rawLabel)) {
|
|
77301
|
+
return rawLabel;
|
|
77302
|
+
}
|
|
77303
|
+
const hourIndex = typeof point.hour_index === "number" ? point.hour_index : index;
|
|
77304
|
+
const [hoursPart, minutesPart] = hourlyLabelStartTime.split(":");
|
|
77305
|
+
const startHours = Number(hoursPart);
|
|
77306
|
+
const startMinutes = Number(minutesPart);
|
|
77307
|
+
if (!Number.isFinite(startHours) || !Number.isFinite(startMinutes)) {
|
|
77308
|
+
return rawLabel || `Hour ${index + 1}`;
|
|
77309
|
+
}
|
|
77310
|
+
const totalMinutes = startHours * 60 + startMinutes + hourIndex * 60;
|
|
77311
|
+
const hour24 = Math.floor(totalMinutes / 60) % 24;
|
|
77312
|
+
const minutes = totalMinutes % 60;
|
|
77313
|
+
const suffix = hour24 < 12 ? "AM" : "PM";
|
|
77314
|
+
const hour12 = hour24 % 12 || 12;
|
|
77315
|
+
if (minutes === 0) {
|
|
77316
|
+
return `${hour12} ${suffix}`;
|
|
77317
|
+
}
|
|
77318
|
+
return `${hour12}:${minutes.toString().padStart(2, "0")} ${suffix}`;
|
|
77319
|
+
})(),
|
|
77320
|
+
efficiency: (() => {
|
|
77321
|
+
const value = toNumber3(point.avg_efficiency);
|
|
77322
|
+
return value === null ? void 0 : value;
|
|
77323
|
+
})()
|
|
77324
|
+
}));
|
|
77325
|
+
}
|
|
76687
77326
|
const pointsByDate = new Map(
|
|
76688
77327
|
(trend.data.points || []).flatMap((point) => {
|
|
76689
77328
|
if (!point.date) return [];
|
|
@@ -76721,12 +77360,13 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
76721
77360
|
})()
|
|
76722
77361
|
};
|
|
76723
77362
|
});
|
|
76724
|
-
}, [currentWeekRange.startKey, isCurrentWeekToDateRange, trend.data.points]);
|
|
77363
|
+
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
76725
77364
|
const trendTooltipLabelFormatter = React141__default.useCallback((label, payload) => {
|
|
77365
|
+
if (isHourlyTrend) return label;
|
|
76726
77366
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
76727
77367
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
76728
77368
|
return `${label} (${dayOfWeek})`;
|
|
76729
|
-
}, []);
|
|
77369
|
+
}, [isHourlyTrend]);
|
|
76730
77370
|
return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-[0_2px_10px_-3px_rgba(6,81,237,0.1)] border border-slate-100 flex flex-col overflow-hidden text-left", children: [
|
|
76731
77371
|
/* @__PURE__ */ jsx("div", { className: "px-6 py-5 flex-none flex justify-between items-center border-b border-slate-50/50", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-700", children: "Efficiency Trend" }) }),
|
|
76732
77372
|
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-[250px] w-full p-4 pt-4 relative", children: showInitialSkeleton ? /* @__PURE__ */ jsx(OverviewChartSkeleton, {}) : /* @__PURE__ */ jsx("div", { className: "absolute inset-0 pb-2 pr-4 pl-1", children: /* @__PURE__ */ jsx(
|
|
@@ -76880,7 +77520,8 @@ var useOperationsOverviewRefresh = ({
|
|
|
76880
77520
|
endKey,
|
|
76881
77521
|
trendMode,
|
|
76882
77522
|
comparisonStrategy,
|
|
76883
|
-
isLiveScope
|
|
77523
|
+
isLiveScope,
|
|
77524
|
+
enabled = true
|
|
76884
77525
|
}) => {
|
|
76885
77526
|
const lineIdsKey = React141__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
76886
77527
|
const scopeSignature = React141__default.useMemo(
|
|
@@ -76926,7 +77567,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
76926
77567
|
}, []);
|
|
76927
77568
|
const runRefresh = React141__default.useCallback(
|
|
76928
77569
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
76929
|
-
if (!supabase || !companyId || lineIds.length === 0) return;
|
|
77570
|
+
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
76930
77571
|
const requestId = requestIdsRef.current[section] + 1;
|
|
76931
77572
|
requestIdsRef.current[section] = requestId;
|
|
76932
77573
|
controllersRef.current[section]?.abort();
|
|
@@ -76946,7 +77587,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
76946
77587
|
onError(error instanceof Error ? error.message : `Failed to refresh ${section}`);
|
|
76947
77588
|
}
|
|
76948
77589
|
},
|
|
76949
|
-
[companyId, lineIds.length, supabase]
|
|
77590
|
+
[companyId, enabled, lineIds.length, supabase]
|
|
76950
77591
|
);
|
|
76951
77592
|
const refreshSnapshot = React141__default.useCallback(
|
|
76952
77593
|
async (reason) => {
|
|
@@ -77116,6 +77757,12 @@ var useOperationsOverviewRefresh = ({
|
|
|
77116
77757
|
});
|
|
77117
77758
|
}, [refreshAll, startPolling, stopPolling]);
|
|
77118
77759
|
React141__default.useEffect(() => {
|
|
77760
|
+
if (!enabled) {
|
|
77761
|
+
stopPolling("disabled");
|
|
77762
|
+
abortAll();
|
|
77763
|
+
store.reset();
|
|
77764
|
+
return;
|
|
77765
|
+
}
|
|
77119
77766
|
if (!supabase || !companyId || lineIds.length === 0) {
|
|
77120
77767
|
stopPolling("scope_invalid");
|
|
77121
77768
|
abortAll();
|
|
@@ -77123,9 +77770,9 @@ var useOperationsOverviewRefresh = ({
|
|
|
77123
77770
|
return;
|
|
77124
77771
|
}
|
|
77125
77772
|
void refreshAll("scope_change");
|
|
77126
|
-
}, [abortAll, companyId, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
77773
|
+
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
77127
77774
|
React141__default.useEffect(() => {
|
|
77128
|
-
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
77775
|
+
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
77129
77776
|
isPageActiveRef.current = false;
|
|
77130
77777
|
stopPolling("live_scope_disabled");
|
|
77131
77778
|
return;
|
|
@@ -77181,11 +77828,63 @@ var useOperationsOverviewRefresh = ({
|
|
|
77181
77828
|
window.removeEventListener("pageshow", handlePageShow);
|
|
77182
77829
|
window.removeEventListener("pagehide", handlePageHide);
|
|
77183
77830
|
};
|
|
77184
|
-
}, [companyId, getIsPageActive, isLiveScope, lineIds.length, refreshFromResume, startPolling, stopPolling, supabase]);
|
|
77831
|
+
}, [companyId, enabled, getIsPageActive, isLiveScope, lineIds.length, refreshFromResume, startPolling, stopPolling, supabase]);
|
|
77832
|
+
};
|
|
77833
|
+
var parseTimeToMinutes3 = (value) => {
|
|
77834
|
+
if (!value) return null;
|
|
77835
|
+
const parts = value.split(":");
|
|
77836
|
+
if (parts.length < 2) return null;
|
|
77837
|
+
const hours = Number(parts[0]);
|
|
77838
|
+
const minutes = Number(parts[1]);
|
|
77839
|
+
if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return null;
|
|
77840
|
+
if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null;
|
|
77841
|
+
return hours * 60 + minutes;
|
|
77842
|
+
};
|
|
77843
|
+
var normalizeShiftId = (value) => {
|
|
77844
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
77845
|
+
return value;
|
|
77846
|
+
}
|
|
77847
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
77848
|
+
const parsed = Number(value);
|
|
77849
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
77850
|
+
}
|
|
77851
|
+
return null;
|
|
77852
|
+
};
|
|
77853
|
+
var classifyShiftBucket = ({
|
|
77854
|
+
shiftName,
|
|
77855
|
+
shiftId,
|
|
77856
|
+
startTime,
|
|
77857
|
+
endTime
|
|
77858
|
+
}) => {
|
|
77859
|
+
const normalizedName = (shiftName || "").trim().toLowerCase();
|
|
77860
|
+
if (normalizedName) {
|
|
77861
|
+
if (["night", "graveyard", "evening"].some((keyword) => normalizedName.includes(keyword))) {
|
|
77862
|
+
return "night";
|
|
77863
|
+
}
|
|
77864
|
+
if (["day", "morning"].some((keyword) => normalizedName.includes(keyword))) {
|
|
77865
|
+
return "day";
|
|
77866
|
+
}
|
|
77867
|
+
}
|
|
77868
|
+
const startMinutes = parseTimeToMinutes3(startTime);
|
|
77869
|
+
const endMinutes = parseTimeToMinutes3(endTime);
|
|
77870
|
+
if (startMinutes !== null) {
|
|
77871
|
+
if (startMinutes >= 4 * 60 && startMinutes < 18 * 60) return "day";
|
|
77872
|
+
return "night";
|
|
77873
|
+
}
|
|
77874
|
+
if (endMinutes !== null) {
|
|
77875
|
+
if (endMinutes >= 6 * 60 && endMinutes <= 21 * 60) return "day";
|
|
77876
|
+
return "night";
|
|
77877
|
+
}
|
|
77878
|
+
const normalizedShiftId = normalizeShiftId(shiftId);
|
|
77879
|
+
if (normalizedShiftId === 0) return "day";
|
|
77880
|
+
if (normalizedShiftId === 1) return "night";
|
|
77881
|
+
return null;
|
|
77185
77882
|
};
|
|
77186
77883
|
var PlantHeadView = () => {
|
|
77187
77884
|
const supabase = useSupabase();
|
|
77188
77885
|
const entityConfig = useEntityConfig();
|
|
77886
|
+
const factoryViewId = entityConfig.factoryViewId || "factory";
|
|
77887
|
+
const staticShiftConfig = useShiftConfig();
|
|
77189
77888
|
const appTimezone = useAppTimezone() || "UTC";
|
|
77190
77889
|
const { navigate } = useNavigation();
|
|
77191
77890
|
const { accessibleLineIds } = useUserLineAccess();
|
|
@@ -77193,11 +77892,21 @@ var PlantHeadView = () => {
|
|
|
77193
77892
|
useHideMobileHeader(!!mobileMenuContext);
|
|
77194
77893
|
const storeRef = React141__default.useRef(createOperationsOverviewStore());
|
|
77195
77894
|
const store = storeRef.current;
|
|
77196
|
-
const
|
|
77197
|
-
|
|
77895
|
+
const fallbackOperationalDate = React141__default.useMemo(
|
|
77896
|
+
() => getOperationalDate(appTimezone),
|
|
77897
|
+
[appTimezone]
|
|
77898
|
+
);
|
|
77899
|
+
const [dateRange, setDateRange] = React141__default.useState(() => ({
|
|
77900
|
+
startKey: fallbackOperationalDate,
|
|
77901
|
+
endKey: fallbackOperationalDate
|
|
77902
|
+
}));
|
|
77903
|
+
const [usesThisWeekComparison, setUsesThisWeekComparison] = React141__default.useState(false);
|
|
77198
77904
|
const [trendMode, setTrendMode] = React141__default.useState("all");
|
|
77199
77905
|
const [selectedSupervisorId, setSelectedSupervisorId] = React141__default.useState("all");
|
|
77200
77906
|
const [selectedLineIds, setSelectedLineIds] = React141__default.useState([]);
|
|
77907
|
+
const [isInitialScopeReady, setIsInitialScopeReady] = React141__default.useState(false);
|
|
77908
|
+
const hasAutoInitializedScopeRef = React141__default.useRef(false);
|
|
77909
|
+
const hasUserAdjustedScopeRef = React141__default.useRef(false);
|
|
77201
77910
|
React141__default.useEffect(() => {
|
|
77202
77911
|
trackCorePageView("Operations Overview", {
|
|
77203
77912
|
dashboard_surface: "operations_overview"
|
|
@@ -77219,8 +77928,10 @@ var PlantHeadView = () => {
|
|
|
77219
77928
|
return dateRange;
|
|
77220
77929
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
77221
77930
|
const normalizedLineIds = React141__default.useMemo(
|
|
77222
|
-
() => Array.from(new Set(
|
|
77223
|
-
|
|
77931
|
+
() => Array.from(new Set(
|
|
77932
|
+
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
77933
|
+
)).sort(),
|
|
77934
|
+
[accessibleLineIds, factoryViewId]
|
|
77224
77935
|
);
|
|
77225
77936
|
const lineIdsKey = React141__default.useMemo(
|
|
77226
77937
|
() => normalizedLineIds.join(","),
|
|
@@ -77294,14 +78005,81 @@ var PlantHeadView = () => {
|
|
|
77294
78005
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
77295
78006
|
[normalizedLineIds, selectedLineIds]
|
|
77296
78007
|
);
|
|
78008
|
+
const {
|
|
78009
|
+
shiftConfigMap,
|
|
78010
|
+
isLoading: isShiftConfigLoading
|
|
78011
|
+
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
78012
|
+
const { shiftGroups, hasComputed: hasComputedShiftGroups } = useShiftGroups({
|
|
78013
|
+
enabled: scopedLineIds.length > 0 && !isShiftConfigLoading,
|
|
78014
|
+
shiftConfigMap,
|
|
78015
|
+
timezone: appTimezone
|
|
78016
|
+
});
|
|
78017
|
+
const currentShiftScope = React141__default.useMemo(() => {
|
|
78018
|
+
if (shiftGroups.length !== 1) return null;
|
|
78019
|
+
const group = shiftGroups[0];
|
|
78020
|
+
const referenceLineId = group.lineIds[0];
|
|
78021
|
+
const referenceShiftConfig = referenceLineId ? shiftConfigMap.get(referenceLineId) : null;
|
|
78022
|
+
const normalizedGroupShiftId = normalizeShiftId(group.shiftId);
|
|
78023
|
+
const shiftDefinition = referenceShiftConfig?.shifts?.find((shift) => normalizeShiftId(shift.shiftId) === normalizedGroupShiftId);
|
|
78024
|
+
const resolvedMode = classifyShiftBucket({
|
|
78025
|
+
shiftName: group.shiftName,
|
|
78026
|
+
shiftId: normalizedGroupShiftId,
|
|
78027
|
+
startTime: shiftDefinition?.startTime,
|
|
78028
|
+
endTime: shiftDefinition?.endTime
|
|
78029
|
+
});
|
|
78030
|
+
if (!resolvedMode || resolvedMode === "all") return null;
|
|
78031
|
+
return {
|
|
78032
|
+
date: group.date,
|
|
78033
|
+
trendMode: resolvedMode,
|
|
78034
|
+
shiftName: shiftDefinition?.shiftName || group.shiftName || null
|
|
78035
|
+
};
|
|
78036
|
+
}, [shiftConfigMap, shiftGroups]);
|
|
78037
|
+
const isShiftScopeResolved = React141__default.useMemo(
|
|
78038
|
+
() => !isShiftConfigLoading && hasComputedShiftGroups,
|
|
78039
|
+
[hasComputedShiftGroups, isShiftConfigLoading]
|
|
78040
|
+
);
|
|
77297
78041
|
const initializedTimezoneRef = React141__default.useRef(appTimezone);
|
|
77298
78042
|
React141__default.useEffect(() => {
|
|
77299
78043
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
77300
|
-
|
|
77301
|
-
|
|
78044
|
+
hasAutoInitializedScopeRef.current = false;
|
|
78045
|
+
hasUserAdjustedScopeRef.current = false;
|
|
78046
|
+
setDateRange({
|
|
78047
|
+
startKey: fallbackOperationalDate,
|
|
78048
|
+
endKey: fallbackOperationalDate
|
|
78049
|
+
});
|
|
78050
|
+
setTrendMode("all");
|
|
78051
|
+
setUsesThisWeekComparison(false);
|
|
78052
|
+
setIsInitialScopeReady(false);
|
|
77302
78053
|
initializedTimezoneRef.current = appTimezone;
|
|
77303
|
-
}, [appTimezone]);
|
|
78054
|
+
}, [appTimezone, fallbackOperationalDate]);
|
|
78055
|
+
React141__default.useEffect(() => {
|
|
78056
|
+
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
78057
|
+
return;
|
|
78058
|
+
}
|
|
78059
|
+
if (scopedLineIds.length === 0) {
|
|
78060
|
+
return;
|
|
78061
|
+
}
|
|
78062
|
+
if (!isShiftScopeResolved) {
|
|
78063
|
+
return;
|
|
78064
|
+
}
|
|
78065
|
+
setDateRange((previous) => {
|
|
78066
|
+
const nextStartKey = currentShiftScope?.date || fallbackOperationalDate;
|
|
78067
|
+
if (previous.startKey === nextStartKey && previous.endKey === nextStartKey) {
|
|
78068
|
+
return previous;
|
|
78069
|
+
}
|
|
78070
|
+
return {
|
|
78071
|
+
startKey: nextStartKey,
|
|
78072
|
+
endKey: nextStartKey
|
|
78073
|
+
};
|
|
78074
|
+
});
|
|
78075
|
+
setTrendMode(currentShiftScope?.trendMode || "all");
|
|
78076
|
+
setUsesThisWeekComparison(false);
|
|
78077
|
+
hasAutoInitializedScopeRef.current = true;
|
|
78078
|
+
setIsInitialScopeReady(true);
|
|
78079
|
+
}, [currentShiftScope, fallbackOperationalDate, isShiftScopeResolved, scopedLineIds.length]);
|
|
77304
78080
|
const handleDateRangeChange = React141__default.useCallback((range, meta) => {
|
|
78081
|
+
hasUserAdjustedScopeRef.current = true;
|
|
78082
|
+
setIsInitialScopeReady(true);
|
|
77305
78083
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
77306
78084
|
start_date: range.startKey,
|
|
77307
78085
|
end_date: range.endKey
|
|
@@ -77318,6 +78096,8 @@ var PlantHeadView = () => {
|
|
|
77318
78096
|
});
|
|
77319
78097
|
}, []);
|
|
77320
78098
|
const handleTrendModeChange = React141__default.useCallback((mode) => {
|
|
78099
|
+
hasUserAdjustedScopeRef.current = true;
|
|
78100
|
+
setIsInitialScopeReady(true);
|
|
77321
78101
|
setTrendMode(mode);
|
|
77322
78102
|
}, []);
|
|
77323
78103
|
const handleSelectedLineIdsChange = React141__default.useCallback((lineIds) => {
|
|
@@ -77344,15 +78124,6 @@ var PlantHeadView = () => {
|
|
|
77344
78124
|
params.set("rangeEnd", dateRange.endKey);
|
|
77345
78125
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
77346
78126
|
}, [dateRange.endKey, dateRange.startKey]);
|
|
77347
|
-
const handleOpenLineMonthlyHistory = React141__default.useCallback((lineId, lineName) => {
|
|
77348
|
-
trackCoreEvent("Operations Overview Line Clicked", {
|
|
77349
|
-
line_id: lineId,
|
|
77350
|
-
line_name: lineName,
|
|
77351
|
-
range_start: dateRange.startKey,
|
|
77352
|
-
range_end: dateRange.endKey
|
|
77353
|
-
});
|
|
77354
|
-
navigate(buildLineMonthlyHistoryUrl(lineId));
|
|
77355
|
-
}, [buildLineMonthlyHistoryUrl, dateRange.endKey, dateRange.startKey, navigate]);
|
|
77356
78127
|
const handleViewAllPoorestPerformers = React141__default.useCallback(() => {
|
|
77357
78128
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
77358
78129
|
navigate("/kpis?tab=leaderboard");
|
|
@@ -77378,16 +78149,74 @@ var PlantHeadView = () => {
|
|
|
77378
78149
|
}
|
|
77379
78150
|
return void 0;
|
|
77380
78151
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
78152
|
+
const effectiveDateRange = React141__default.useMemo(() => {
|
|
78153
|
+
if (isInitialScopeReady) {
|
|
78154
|
+
return dateRange;
|
|
78155
|
+
}
|
|
78156
|
+
const nextStartKey = currentShiftScope?.date || fallbackOperationalDate;
|
|
78157
|
+
return {
|
|
78158
|
+
startKey: nextStartKey,
|
|
78159
|
+
endKey: nextStartKey
|
|
78160
|
+
};
|
|
78161
|
+
}, [currentShiftScope, dateRange, fallbackOperationalDate, isInitialScopeReady]);
|
|
78162
|
+
const effectiveTrendMode = React141__default.useMemo(
|
|
78163
|
+
() => isInitialScopeReady ? trendMode : currentShiftScope?.trendMode || "all",
|
|
78164
|
+
[currentShiftScope, isInitialScopeReady, trendMode]
|
|
78165
|
+
);
|
|
78166
|
+
const hourlyLabelStartTime = React141__default.useMemo(() => {
|
|
78167
|
+
if (effectiveTrendMode === "all" || scopedLineIds.length === 0) {
|
|
78168
|
+
return null;
|
|
78169
|
+
}
|
|
78170
|
+
const shiftStartTimes = /* @__PURE__ */ new Set();
|
|
78171
|
+
scopedLineIds.forEach((lineId) => {
|
|
78172
|
+
const shiftConfig = shiftConfigMap.get(lineId);
|
|
78173
|
+
const matchingShift = shiftConfig?.shifts?.find((shift) => classifyShiftBucket({
|
|
78174
|
+
shiftName: shift.shiftName,
|
|
78175
|
+
shiftId: shift.shiftId,
|
|
78176
|
+
startTime: shift.startTime,
|
|
78177
|
+
endTime: shift.endTime
|
|
78178
|
+
}) === effectiveTrendMode);
|
|
78179
|
+
if (matchingShift?.startTime) {
|
|
78180
|
+
shiftStartTimes.add(matchingShift.startTime);
|
|
78181
|
+
}
|
|
78182
|
+
});
|
|
78183
|
+
if (shiftStartTimes.size !== 1) {
|
|
78184
|
+
return null;
|
|
78185
|
+
}
|
|
78186
|
+
return Array.from(shiftStartTimes)[0] || null;
|
|
78187
|
+
}, [effectiveTrendMode, scopedLineIds, shiftConfigMap]);
|
|
78188
|
+
const isSingleDayShiftScope = React141__default.useMemo(
|
|
78189
|
+
() => effectiveDateRange.startKey === effectiveDateRange.endKey && effectiveTrendMode !== "all",
|
|
78190
|
+
[effectiveDateRange.endKey, effectiveDateRange.startKey, effectiveTrendMode]
|
|
78191
|
+
);
|
|
78192
|
+
const isLiveScope = React141__default.useMemo(
|
|
78193
|
+
() => isSingleDayShiftScope && currentShiftScope !== null && effectiveDateRange.startKey === currentShiftScope.date && effectiveTrendMode === currentShiftScope.trendMode,
|
|
78194
|
+
[currentShiftScope, effectiveDateRange.startKey, effectiveTrendMode, isSingleDayShiftScope]
|
|
78195
|
+
);
|
|
78196
|
+
const handleOpenLineDetails = React141__default.useCallback((lineId, lineName) => {
|
|
78197
|
+
trackCoreEvent("Operations Overview Line Clicked", {
|
|
78198
|
+
line_id: lineId,
|
|
78199
|
+
line_name: lineName,
|
|
78200
|
+
range_start: dateRange.startKey,
|
|
78201
|
+
range_end: dateRange.endKey
|
|
78202
|
+
});
|
|
78203
|
+
if (isLiveScope) {
|
|
78204
|
+
navigate(`/kpis/${lineId}?returnTo=${encodeURIComponent("/")}`);
|
|
78205
|
+
return;
|
|
78206
|
+
}
|
|
78207
|
+
navigate(buildLineMonthlyHistoryUrl(lineId));
|
|
78208
|
+
}, [buildLineMonthlyHistoryUrl, dateRange.endKey, dateRange.startKey, isLiveScope, navigate]);
|
|
77381
78209
|
useOperationsOverviewRefresh({
|
|
77382
78210
|
store,
|
|
77383
78211
|
supabase,
|
|
77384
78212
|
companyId: entityConfig.companyId,
|
|
77385
78213
|
lineIds: scopedLineIds,
|
|
77386
|
-
startKey:
|
|
77387
|
-
endKey:
|
|
77388
|
-
trendMode,
|
|
78214
|
+
startKey: effectiveDateRange.startKey,
|
|
78215
|
+
endKey: effectiveDateRange.endKey,
|
|
78216
|
+
trendMode: effectiveTrendMode,
|
|
77389
78217
|
comparisonStrategy,
|
|
77390
|
-
isLiveScope
|
|
78218
|
+
isLiveScope,
|
|
78219
|
+
enabled: scopedLineIds.length > 0 && isShiftScopeResolved
|
|
77391
78220
|
});
|
|
77392
78221
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-h-screen bg-slate-50 w-full font-sans", children: [
|
|
77393
78222
|
/* @__PURE__ */ jsx(
|
|
@@ -77396,6 +78225,8 @@ var PlantHeadView = () => {
|
|
|
77396
78225
|
dateRange,
|
|
77397
78226
|
displayDateRange: headerDateRange,
|
|
77398
78227
|
trendMode,
|
|
78228
|
+
isLiveScope,
|
|
78229
|
+
liveShiftName: currentShiftScope?.shiftName || null,
|
|
77399
78230
|
lineOptions,
|
|
77400
78231
|
supervisorOptions,
|
|
77401
78232
|
selectedSupervisorId,
|
|
@@ -77418,7 +78249,7 @@ var PlantHeadView = () => {
|
|
|
77418
78249
|
store,
|
|
77419
78250
|
supervisorsByLineId,
|
|
77420
78251
|
onViewAll: handleViewAllPoorestPerformers,
|
|
77421
|
-
onLineClick:
|
|
78252
|
+
onLineClick: handleOpenLineDetails
|
|
77422
78253
|
}
|
|
77423
78254
|
),
|
|
77424
78255
|
/* @__PURE__ */ jsx(
|
|
@@ -77435,7 +78266,8 @@ var PlantHeadView = () => {
|
|
|
77435
78266
|
{
|
|
77436
78267
|
store,
|
|
77437
78268
|
dateRange,
|
|
77438
|
-
appTimezone
|
|
78269
|
+
appTimezone,
|
|
78270
|
+
hourlyLabelStartTime
|
|
77439
78271
|
}
|
|
77440
78272
|
),
|
|
77441
78273
|
/* @__PURE__ */ jsx(
|
|
@@ -77929,4 +78761,4 @@ var streamProxyConfig = {
|
|
|
77929
78761
|
}
|
|
77930
78762
|
};
|
|
77931
78763
|
|
|
77932
|
-
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|
|
78764
|
+
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|