@optifye/dashboard-core 6.11.17 → 6.11.19
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 +73 -8
- package/dist/index.d.mts +59 -1
- package/dist/index.d.ts +59 -1
- package/dist/index.js +3468 -2879
- package/dist/index.mjs +1496 -908
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React142 from 'react';
|
|
2
|
+
import React142__default, { createContext, useRef, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore, useId, Children, isValidElement, useInsertionEffect, startTransition, Fragment as Fragment$1, createElement, Component } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { useRouter } from 'next/router';
|
|
5
5
|
import { toast } from 'sonner';
|
|
6
|
-
import {
|
|
6
|
+
import { formatInTimeZone, fromZonedTime, toZonedTime } from 'date-fns-tz';
|
|
7
7
|
import { format, addDays, subMonths, endOfMonth, startOfMonth, endOfDay, eachDayOfInterval, getDay, isSameDay, isWithinInterval, startOfDay, parseISO, subDays, differenceInMinutes, addMinutes, addMonths, isValid, formatDistanceToNow, isToday, isFuture, isBefore } from 'date-fns';
|
|
8
8
|
import mixpanel from 'mixpanel-browser';
|
|
9
9
|
import { EventEmitter } from 'events';
|
|
10
10
|
import { createClient, REALTIME_SUBSCRIBE_STATES } from '@supabase/supabase-js';
|
|
11
11
|
import Hls, { Events, ErrorTypes } from 'hls.js';
|
|
12
12
|
import useSWR from 'swr';
|
|
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,
|
|
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, Copy, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Settings, LifeBuoy, EyeOff, Zap, Flame, Crown, Medal } from 'lucide-react';
|
|
14
14
|
import { memo, noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds } from 'motion-utils';
|
|
15
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';
|
|
19
|
-
import { AdjustmentsHorizontalIcon, ClockIcon, UsersIcon, UserCircleIcon, TicketIcon, CurrencyDollarIcon, QuestionMarkCircleIcon, XMarkIcon, ArrowRightIcon, Bars3Icon, HomeIcon, VideoCameraIcon, TrophyIcon, ChartBarIcon, LightBulbIcon, CubeIcon, HeartIcon,
|
|
19
|
+
import { AdjustmentsHorizontalIcon, ClockIcon, UsersIcon, UserCircleIcon, TicketIcon, CurrencyDollarIcon, QuestionMarkCircleIcon, XMarkIcon, InformationCircleIcon, ArrowRightIcon, Bars3Icon, HomeIcon, VideoCameraIcon, TrophyIcon, ChartBarIcon, LightBulbIcon, CubeIcon, HeartIcon, Cog6ToothIcon, ChevronRightIcon, ArrowRightStartOnRectangleIcon, ExclamationCircleIcon, ExclamationTriangleIcon, CalendarIcon, ChevronDownIcon, ChevronLeftIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ArrowDownTrayIcon, CheckCircleIcon, ChatBubbleLeftRightIcon, XCircleIcon, FunnelIcon, EyeIcon, ArrowLeftIcon, PlayCircleIcon } from '@heroicons/react/24/outline';
|
|
20
20
|
import { CheckIcon } from '@heroicons/react/24/solid';
|
|
21
21
|
import html2canvas from 'html2canvas';
|
|
22
22
|
import jsPDF, { jsPDF as jsPDF$1 } from 'jspdf';
|
|
@@ -1938,14 +1938,14 @@ var useIdleTimeVlmConfig = () => {
|
|
|
1938
1938
|
}
|
|
1939
1939
|
return context;
|
|
1940
1940
|
};
|
|
1941
|
-
var DashboardConfigContext =
|
|
1941
|
+
var DashboardConfigContext = React142.createContext(void 0);
|
|
1942
1942
|
var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
1943
|
-
const fullConfig =
|
|
1943
|
+
const fullConfig = React142.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
|
|
1944
1944
|
_setDashboardConfigInstance(fullConfig);
|
|
1945
|
-
|
|
1945
|
+
React142.useEffect(() => {
|
|
1946
1946
|
_setDashboardConfigInstance(fullConfig);
|
|
1947
1947
|
}, [fullConfig]);
|
|
1948
|
-
|
|
1948
|
+
React142.useEffect(() => {
|
|
1949
1949
|
if (!fullConfig.theme) return;
|
|
1950
1950
|
const styleId = "dashboard-core-theme-vars";
|
|
1951
1951
|
let styleEl = document.getElementById(styleId);
|
|
@@ -1971,7 +1971,7 @@ var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
|
1971
1971
|
return /* @__PURE__ */ jsx(DashboardConfigContext.Provider, { value: fullConfig, children: /* @__PURE__ */ jsx(IdleTimeVlmConfigProvider, { children }) });
|
|
1972
1972
|
};
|
|
1973
1973
|
var useDashboardConfig = () => {
|
|
1974
|
-
const ctx =
|
|
1974
|
+
const ctx = React142.useContext(DashboardConfigContext);
|
|
1975
1975
|
if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
|
|
1976
1976
|
return ctx;
|
|
1977
1977
|
};
|
|
@@ -3981,7 +3981,8 @@ var dashboardService = {
|
|
|
3981
3981
|
enable,
|
|
3982
3982
|
monitoring_mode,
|
|
3983
3983
|
assembly,
|
|
3984
|
-
video_grid_metric_mode
|
|
3984
|
+
video_grid_metric_mode,
|
|
3985
|
+
recent_flow_window_minutes
|
|
3985
3986
|
`).eq("enable", true);
|
|
3986
3987
|
if (companyId) {
|
|
3987
3988
|
query = query.eq("company_id", companyId);
|
|
@@ -4006,7 +4007,8 @@ var dashboardService = {
|
|
|
4006
4007
|
video_grid_metric_mode: normalizeVideoGridMetricMode(
|
|
4007
4008
|
line.video_grid_metric_mode,
|
|
4008
4009
|
line.assembly ?? false
|
|
4009
|
-
)
|
|
4010
|
+
),
|
|
4011
|
+
recent_flow_window_minutes: line.recent_flow_window_minutes ?? 7
|
|
4010
4012
|
}));
|
|
4011
4013
|
return transformedLines;
|
|
4012
4014
|
} catch (err) {
|
|
@@ -4043,7 +4045,7 @@ var dashboardService = {
|
|
|
4043
4045
|
}
|
|
4044
4046
|
const lineIdsToQuery = configuredLineIds;
|
|
4045
4047
|
const [line1Result, metricsResult2] = await Promise.all([
|
|
4046
|
-
supabase.from(linesTable).select("id, line_name, factory_id, monitoring_mode, assembly, video_grid_metric_mode, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", defaultLineId).single(),
|
|
4048
|
+
supabase.from(linesTable).select("id, line_name, factory_id, monitoring_mode, assembly, video_grid_metric_mode, recent_flow_window_minutes, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", defaultLineId).single(),
|
|
4047
4049
|
supabase.from(lineMetricsTable).select("*").in("line_id", lineIdsToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
4048
4050
|
]);
|
|
4049
4051
|
if (line1Result.error) throw line1Result.error;
|
|
@@ -4099,6 +4101,7 @@ var dashboardService = {
|
|
|
4099
4101
|
date: queryDate,
|
|
4100
4102
|
shift_id: queryShiftId,
|
|
4101
4103
|
monitoring_mode: line1Data.monitoring_mode ?? void 0,
|
|
4104
|
+
recent_flow_window_minutes: line1Data.recent_flow_window_minutes ?? 7,
|
|
4102
4105
|
metrics: {
|
|
4103
4106
|
avg_efficiency: avgEfficiency,
|
|
4104
4107
|
avg_cycle_time: combinedMetricsData.avg_cycle_time / numLines,
|
|
@@ -4122,7 +4125,7 @@ var dashboardService = {
|
|
|
4122
4125
|
throw new Error("Company ID must be configured for detailed line requests.");
|
|
4123
4126
|
}
|
|
4124
4127
|
const [lineResult, metricsResult] = await Promise.all([
|
|
4125
|
-
supabase.from(linesTable).select("id, line_name, factory_id, monitoring_mode, assembly, video_grid_metric_mode, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", lineIdToQuery).single(),
|
|
4128
|
+
supabase.from(linesTable).select("id, line_name, factory_id, monitoring_mode, assembly, video_grid_metric_mode, recent_flow_window_minutes, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", lineIdToQuery).single(),
|
|
4126
4129
|
supabase.from(lineMetricsTable).select("*").eq("line_id", lineIdToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
4127
4130
|
]);
|
|
4128
4131
|
if (lineResult.error) throw lineResult.error;
|
|
@@ -4147,6 +4150,7 @@ var dashboardService = {
|
|
|
4147
4150
|
date: queryDate,
|
|
4148
4151
|
shift_id: queryShiftId,
|
|
4149
4152
|
monitoring_mode: lineData.monitoring_mode ?? void 0,
|
|
4153
|
+
recent_flow_window_minutes: lineData.recent_flow_window_minutes ?? 7,
|
|
4150
4154
|
metrics: {
|
|
4151
4155
|
avg_efficiency: metrics2?.avg_efficiency ?? 0,
|
|
4152
4156
|
avg_cycle_time: metrics2?.avg_cycle_time || 0,
|
|
@@ -4635,6 +4639,11 @@ var workspaceService = {
|
|
|
4635
4639
|
_workspaceVideoStreamsInFlight: /* @__PURE__ */ new Map(),
|
|
4636
4640
|
_workspaceVideoStreamsCacheExpiryMs: 5 * 60 * 1e3,
|
|
4637
4641
|
// 5 minutes cache
|
|
4642
|
+
// Cache for workspace camera IPs derived from CV configs
|
|
4643
|
+
_workspaceCameraIpsCache: /* @__PURE__ */ new Map(),
|
|
4644
|
+
_workspaceCameraIpsInFlight: /* @__PURE__ */ new Map(),
|
|
4645
|
+
_workspaceCameraIpsCacheExpiryMs: 5 * 60 * 1e3,
|
|
4646
|
+
// 5 minutes cache
|
|
4638
4647
|
async getWorkspaces(lineId, options) {
|
|
4639
4648
|
const enabledOnly = options?.enabledOnly ?? false;
|
|
4640
4649
|
const force = options?.force ?? false;
|
|
@@ -4736,6 +4745,61 @@ var workspaceService = {
|
|
|
4736
4745
|
this._workspaceVideoStreamsInFlight.set(cacheKey, fetchPromise);
|
|
4737
4746
|
return fetchPromise;
|
|
4738
4747
|
},
|
|
4748
|
+
async getWorkspaceCameraIps(params) {
|
|
4749
|
+
const workspaceIds = (params.workspaceIds || []).filter(Boolean);
|
|
4750
|
+
const lineIds = (params.lineIds || []).filter(Boolean);
|
|
4751
|
+
const force = params.force ?? false;
|
|
4752
|
+
if (!workspaceIds.length && !lineIds.length) {
|
|
4753
|
+
return {};
|
|
4754
|
+
}
|
|
4755
|
+
const workspaceKey = workspaceIds.slice().sort().join(",");
|
|
4756
|
+
const lineKey = lineIds.slice().sort().join(",");
|
|
4757
|
+
const cacheKey = workspaceKey ? `workspaces:${workspaceKey}` : `lines:${lineKey}`;
|
|
4758
|
+
const now4 = Date.now();
|
|
4759
|
+
const cached = this._workspaceCameraIpsCache.get(cacheKey);
|
|
4760
|
+
if (!force && cached && now4 - cached.timestamp < this._workspaceCameraIpsCacheExpiryMs) {
|
|
4761
|
+
return cached.cameraIps;
|
|
4762
|
+
}
|
|
4763
|
+
const inFlight = this._workspaceCameraIpsInFlight.get(cacheKey);
|
|
4764
|
+
if (!force && inFlight) {
|
|
4765
|
+
return inFlight;
|
|
4766
|
+
}
|
|
4767
|
+
const fetchPromise = (async () => {
|
|
4768
|
+
try {
|
|
4769
|
+
const token = await getAuthToken2();
|
|
4770
|
+
const apiUrl = getBackendUrl2();
|
|
4771
|
+
const response = await fetch(`${apiUrl}/api/workspaces/camera-ips`, {
|
|
4772
|
+
method: "POST",
|
|
4773
|
+
headers: {
|
|
4774
|
+
"Authorization": `Bearer ${token}`,
|
|
4775
|
+
"Content-Type": "application/json"
|
|
4776
|
+
},
|
|
4777
|
+
body: JSON.stringify({
|
|
4778
|
+
workspace_ids: workspaceIds.length ? workspaceIds : void 0,
|
|
4779
|
+
line_ids: lineIds.length ? lineIds : void 0
|
|
4780
|
+
})
|
|
4781
|
+
});
|
|
4782
|
+
if (!response.ok) {
|
|
4783
|
+
const errorText = await response.text();
|
|
4784
|
+
throw new Error(`Backend API error (${response.status}): ${errorText}`);
|
|
4785
|
+
}
|
|
4786
|
+
const data = await response.json();
|
|
4787
|
+
const cameraIps = data.camera_ips || {};
|
|
4788
|
+
this._workspaceCameraIpsCache.set(cacheKey, {
|
|
4789
|
+
cameraIps,
|
|
4790
|
+
timestamp: Date.now()
|
|
4791
|
+
});
|
|
4792
|
+
return cameraIps;
|
|
4793
|
+
} catch (error) {
|
|
4794
|
+
console.error("Error fetching workspace camera IPs:", error);
|
|
4795
|
+
throw error;
|
|
4796
|
+
} finally {
|
|
4797
|
+
this._workspaceCameraIpsInFlight.delete(cacheKey);
|
|
4798
|
+
}
|
|
4799
|
+
})();
|
|
4800
|
+
this._workspaceCameraIpsInFlight.set(cacheKey, fetchPromise);
|
|
4801
|
+
return fetchPromise;
|
|
4802
|
+
},
|
|
4739
4803
|
/**
|
|
4740
4804
|
* Fetches workspace display names from the database
|
|
4741
4805
|
* Returns a map of workspace_id -> display_name
|
|
@@ -8480,7 +8544,8 @@ var LinesService = class {
|
|
|
8480
8544
|
videoGridMetricMode: normalizeVideoGridMetricMode(
|
|
8481
8545
|
line.video_grid_metric_mode,
|
|
8482
8546
|
line.assembly ?? false
|
|
8483
|
-
)
|
|
8547
|
+
),
|
|
8548
|
+
recentFlowWindowMinutes: line.recent_flow_window_minutes ?? 7
|
|
8484
8549
|
}));
|
|
8485
8550
|
} catch (error) {
|
|
8486
8551
|
console.error("Error fetching lines:", error);
|
|
@@ -8528,7 +8593,8 @@ var LinesService = class {
|
|
|
8528
8593
|
videoGridMetricMode: normalizeVideoGridMetricMode(
|
|
8529
8594
|
line.video_grid_metric_mode,
|
|
8530
8595
|
line.assembly ?? false
|
|
8531
|
-
)
|
|
8596
|
+
),
|
|
8597
|
+
recentFlowWindowMinutes: line.recent_flow_window_minutes ?? 7
|
|
8532
8598
|
}));
|
|
8533
8599
|
} catch (error) {
|
|
8534
8600
|
console.error("Error fetching all lines:", error);
|
|
@@ -8585,7 +8651,8 @@ var LinesService = class {
|
|
|
8585
8651
|
videoGridMetricMode: normalizeVideoGridMetricMode(
|
|
8586
8652
|
data.video_grid_metric_mode,
|
|
8587
8653
|
data.assembly ?? false
|
|
8588
|
-
)
|
|
8654
|
+
),
|
|
8655
|
+
recentFlowWindowMinutes: data.recent_flow_window_minutes ?? 7
|
|
8589
8656
|
};
|
|
8590
8657
|
} catch (error) {
|
|
8591
8658
|
console.error("Error fetching line:", error);
|
|
@@ -11123,7 +11190,7 @@ var useMobileMenu = () => {
|
|
|
11123
11190
|
};
|
|
11124
11191
|
var useHideMobileHeader = (shouldHide = true) => {
|
|
11125
11192
|
const context = useMobileMenu();
|
|
11126
|
-
|
|
11193
|
+
React142__default.useEffect(() => {
|
|
11127
11194
|
if (context && shouldHide) {
|
|
11128
11195
|
context.setHideMobileHeader(true);
|
|
11129
11196
|
return () => {
|
|
@@ -13339,6 +13406,7 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13339
13406
|
actionName: item.action_name
|
|
13340
13407
|
}),
|
|
13341
13408
|
recent_flow_percent: item.recent_flow_percent ?? null,
|
|
13409
|
+
recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
|
|
13342
13410
|
recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
|
|
13343
13411
|
recent_flow_computed_at: item.recent_flow_computed_at ?? null,
|
|
13344
13412
|
incoming_wip_current: item.incoming_wip_current ?? null,
|
|
@@ -19883,6 +19951,53 @@ function useCompanyClipsCost() {
|
|
|
19883
19951
|
refetch: fetchData
|
|
19884
19952
|
};
|
|
19885
19953
|
}
|
|
19954
|
+
function useCompanyHasVlmEnabledLine(options = {}) {
|
|
19955
|
+
const { enabled = true } = options;
|
|
19956
|
+
const { user } = useAuth();
|
|
19957
|
+
const supabase = useSupabase();
|
|
19958
|
+
const entityConfig = useEntityConfig();
|
|
19959
|
+
const [hasVlmEnabledLine, setHasVlmEnabledLine] = useState(false);
|
|
19960
|
+
const [isLoading, setIsLoading] = useState(enabled);
|
|
19961
|
+
const companyId = user?.properties?.company_id || user?.company_id || entityConfig.companyId;
|
|
19962
|
+
useEffect(() => {
|
|
19963
|
+
let isCancelled = false;
|
|
19964
|
+
const load = async () => {
|
|
19965
|
+
if (!enabled || !companyId || !supabase) {
|
|
19966
|
+
setHasVlmEnabledLine(false);
|
|
19967
|
+
setIsLoading(false);
|
|
19968
|
+
return;
|
|
19969
|
+
}
|
|
19970
|
+
setIsLoading(true);
|
|
19971
|
+
try {
|
|
19972
|
+
const { data, error } = await supabase.from("lines").select("id").eq("company_id", companyId).eq("idle_time_vlm_enabled", true).limit(1);
|
|
19973
|
+
if (error) {
|
|
19974
|
+
throw error;
|
|
19975
|
+
}
|
|
19976
|
+
if (isCancelled) {
|
|
19977
|
+
return;
|
|
19978
|
+
}
|
|
19979
|
+
setHasVlmEnabledLine((data?.length || 0) > 0);
|
|
19980
|
+
} catch (error) {
|
|
19981
|
+
console.error("[useCompanyHasVlmEnabledLine] Error:", error);
|
|
19982
|
+
if (!isCancelled) {
|
|
19983
|
+
setHasVlmEnabledLine(false);
|
|
19984
|
+
}
|
|
19985
|
+
} finally {
|
|
19986
|
+
if (!isCancelled) {
|
|
19987
|
+
setIsLoading(false);
|
|
19988
|
+
}
|
|
19989
|
+
}
|
|
19990
|
+
};
|
|
19991
|
+
void load();
|
|
19992
|
+
return () => {
|
|
19993
|
+
isCancelled = true;
|
|
19994
|
+
};
|
|
19995
|
+
}, [companyId, enabled, supabase]);
|
|
19996
|
+
return {
|
|
19997
|
+
hasVlmEnabledLine,
|
|
19998
|
+
isLoading
|
|
19999
|
+
};
|
|
20000
|
+
}
|
|
19886
20001
|
|
|
19887
20002
|
// src/lib/utils/api.ts
|
|
19888
20003
|
var apiUtils = {
|
|
@@ -23115,7 +23230,7 @@ var MotionConfigContext = createContext({
|
|
|
23115
23230
|
});
|
|
23116
23231
|
|
|
23117
23232
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
|
|
23118
|
-
var PopChildMeasure = class extends
|
|
23233
|
+
var PopChildMeasure = class extends React142.Component {
|
|
23119
23234
|
getSnapshotBeforeUpdate(prevProps) {
|
|
23120
23235
|
const element = this.props.childRef.current;
|
|
23121
23236
|
if (element && prevProps.isPresent && !this.props.isPresent) {
|
|
@@ -23170,7 +23285,7 @@ function PopChild({ children, isPresent }) {
|
|
|
23170
23285
|
document.head.removeChild(style);
|
|
23171
23286
|
};
|
|
23172
23287
|
}, [isPresent]);
|
|
23173
|
-
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children:
|
|
23288
|
+
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React142.cloneElement(children, { ref }) });
|
|
23174
23289
|
}
|
|
23175
23290
|
|
|
23176
23291
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
|
|
@@ -23207,7 +23322,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
|
|
|
23207
23322
|
useMemo(() => {
|
|
23208
23323
|
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
|
23209
23324
|
}, [isPresent]);
|
|
23210
|
-
|
|
23325
|
+
React142.useEffect(() => {
|
|
23211
23326
|
!isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
|
|
23212
23327
|
}, [isPresent]);
|
|
23213
23328
|
if (mode === "popLayout") {
|
|
@@ -30992,7 +31107,7 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
30992
31107
|
requireAuth: true,
|
|
30993
31108
|
...options
|
|
30994
31109
|
};
|
|
30995
|
-
const WithAuthComponent =
|
|
31110
|
+
const WithAuthComponent = React142.memo(function WithAuthComponent2(props) {
|
|
30996
31111
|
const {
|
|
30997
31112
|
session,
|
|
30998
31113
|
user,
|
|
@@ -31003,9 +31118,9 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31003
31118
|
retrySessionHydration
|
|
31004
31119
|
} = useAuth();
|
|
31005
31120
|
const router = useRouter();
|
|
31006
|
-
const [localLoading, setLocalLoading] =
|
|
31007
|
-
const [loadingTimeoutReached, setLoadingTimeoutReached] =
|
|
31008
|
-
|
|
31121
|
+
const [localLoading, setLocalLoading] = React142.useState(loading);
|
|
31122
|
+
const [loadingTimeoutReached, setLoadingTimeoutReached] = React142.useState(false);
|
|
31123
|
+
React142.useEffect(() => {
|
|
31009
31124
|
if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
|
|
31010
31125
|
console.log("withAuth state:", {
|
|
31011
31126
|
loading,
|
|
@@ -31017,7 +31132,7 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31017
31132
|
});
|
|
31018
31133
|
}
|
|
31019
31134
|
}, [authStatus, error, loading, session, user]);
|
|
31020
|
-
const handleLoadingTimeout =
|
|
31135
|
+
const handleLoadingTimeout = React142.useCallback(() => {
|
|
31021
31136
|
console.warn("[withAuth] Loading timeout reached");
|
|
31022
31137
|
setLoadingTimeoutReached(true);
|
|
31023
31138
|
if (hasStoredSupabaseSession()) {
|
|
@@ -31029,13 +31144,13 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
31029
31144
|
router.replace(defaultOptions.redirectTo);
|
|
31030
31145
|
}
|
|
31031
31146
|
}, [retrySessionHydration, router]);
|
|
31032
|
-
|
|
31147
|
+
React142.useEffect(() => {
|
|
31033
31148
|
if (!loading && authStatus !== "recovering" && defaultOptions.requireAuth && !session && !error) {
|
|
31034
31149
|
console.log("[withAuth] No session found, redirecting to login");
|
|
31035
31150
|
router.replace(defaultOptions.redirectTo);
|
|
31036
31151
|
}
|
|
31037
31152
|
}, [authStatus, defaultOptions.requireAuth, error, loading, router, session]);
|
|
31038
|
-
|
|
31153
|
+
React142.useEffect(() => {
|
|
31039
31154
|
setLocalLoading(loading);
|
|
31040
31155
|
}, [loading]);
|
|
31041
31156
|
if (loading || localLoading) {
|
|
@@ -32034,11 +32149,11 @@ var BarChartComponent = ({
|
|
|
32034
32149
|
aspect = 2,
|
|
32035
32150
|
...restOfChartProps
|
|
32036
32151
|
}) => {
|
|
32037
|
-
const containerRef =
|
|
32038
|
-
const [containerReady, setContainerReady] =
|
|
32152
|
+
const containerRef = React142__default.useRef(null);
|
|
32153
|
+
const [containerReady, setContainerReady] = React142__default.useState(false);
|
|
32039
32154
|
const themeConfig = useThemeConfig();
|
|
32040
32155
|
const { formatNumber } = useFormatNumber();
|
|
32041
|
-
|
|
32156
|
+
React142__default.useEffect(() => {
|
|
32042
32157
|
const checkContainerDimensions = () => {
|
|
32043
32158
|
if (containerRef.current) {
|
|
32044
32159
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -32152,7 +32267,7 @@ var BarChartComponent = ({
|
|
|
32152
32267
|
}
|
|
32153
32268
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
32154
32269
|
};
|
|
32155
|
-
var BarChart =
|
|
32270
|
+
var BarChart = React142__default.memo(BarChartComponent, (prevProps, nextProps) => {
|
|
32156
32271
|
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || JSON.stringify(prevProps.referenceLines || []) !== JSON.stringify(nextProps.referenceLines || []) || prevProps.layout !== nextProps.layout || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect) {
|
|
32157
32272
|
return false;
|
|
32158
32273
|
}
|
|
@@ -32203,10 +32318,10 @@ var LineChartComponent = ({
|
|
|
32203
32318
|
fillContainer = false,
|
|
32204
32319
|
...restOfChartProps
|
|
32205
32320
|
}) => {
|
|
32206
|
-
const containerRef =
|
|
32207
|
-
const [dimensions, setDimensions] =
|
|
32208
|
-
const [hasValidData, setHasValidData] =
|
|
32209
|
-
|
|
32321
|
+
const containerRef = React142__default.useRef(null);
|
|
32322
|
+
const [dimensions, setDimensions] = React142__default.useState({ width: 0, height: 0 });
|
|
32323
|
+
const [hasValidData, setHasValidData] = React142__default.useState(false);
|
|
32324
|
+
React142__default.useEffect(() => {
|
|
32210
32325
|
const currentHasValidData = data && lines && lines.length > 0 && data.some(
|
|
32211
32326
|
(item) => lines.some((line) => {
|
|
32212
32327
|
const val = item[line.dataKey];
|
|
@@ -32217,7 +32332,7 @@ var LineChartComponent = ({
|
|
|
32217
32332
|
setHasValidData(true);
|
|
32218
32333
|
}
|
|
32219
32334
|
}, [data, lines, hasValidData]);
|
|
32220
|
-
|
|
32335
|
+
React142__default.useEffect(() => {
|
|
32221
32336
|
if (!containerRef.current) return;
|
|
32222
32337
|
const observer = new ResizeObserver((entries) => {
|
|
32223
32338
|
const entry = entries[0];
|
|
@@ -32342,7 +32457,7 @@ var LineChartComponent = ({
|
|
|
32342
32457
|
}
|
|
32343
32458
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: renderChartContent(restOfChartProps.width, restOfChartProps.height) });
|
|
32344
32459
|
};
|
|
32345
|
-
var LineChart =
|
|
32460
|
+
var LineChart = React142__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
32346
32461
|
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)) {
|
|
32347
32462
|
return false;
|
|
32348
32463
|
}
|
|
@@ -32436,7 +32551,7 @@ var OutputProgressChartComponent = ({
|
|
|
32436
32551
|
] }) })
|
|
32437
32552
|
] }) });
|
|
32438
32553
|
};
|
|
32439
|
-
var OutputProgressChart =
|
|
32554
|
+
var OutputProgressChart = React142__default.memo(OutputProgressChartComponent);
|
|
32440
32555
|
OutputProgressChart.displayName = "OutputProgressChart";
|
|
32441
32556
|
var LargeOutputProgressChart = ({
|
|
32442
32557
|
currentOutput,
|
|
@@ -32576,7 +32691,7 @@ var CycleTimeChartComponent = ({
|
|
|
32576
32691
|
}
|
|
32577
32692
|
) }) });
|
|
32578
32693
|
};
|
|
32579
|
-
var CycleTimeChart =
|
|
32694
|
+
var CycleTimeChart = React142__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
|
|
32580
32695
|
if (prevProps.className !== nextProps.className) {
|
|
32581
32696
|
return false;
|
|
32582
32697
|
}
|
|
@@ -32595,6 +32710,212 @@ var CycleTimeChart = React141__default.memo(CycleTimeChartComponent, (prevProps,
|
|
|
32595
32710
|
});
|
|
32596
32711
|
});
|
|
32597
32712
|
CycleTimeChart.displayName = "CycleTimeChart";
|
|
32713
|
+
|
|
32714
|
+
// src/lib/utils/hourlyIdle.ts
|
|
32715
|
+
var DEFAULT_SHIFT_DURATION = 11;
|
|
32716
|
+
var normalizeMinuteSeries = (idleTimeHourly) => {
|
|
32717
|
+
if (!idleTimeHourly || typeof idleTimeHourly !== "object") {
|
|
32718
|
+
return {};
|
|
32719
|
+
}
|
|
32720
|
+
return Object.fromEntries(
|
|
32721
|
+
Object.entries(idleTimeHourly).map(([key, value]) => {
|
|
32722
|
+
if (Array.isArray(value)) {
|
|
32723
|
+
return [key, value];
|
|
32724
|
+
}
|
|
32725
|
+
if (value && Array.isArray(value.values)) {
|
|
32726
|
+
return [key, value.values];
|
|
32727
|
+
}
|
|
32728
|
+
return [key, []];
|
|
32729
|
+
})
|
|
32730
|
+
);
|
|
32731
|
+
};
|
|
32732
|
+
var parseTimeString = (timeValue) => {
|
|
32733
|
+
const [hoursPart, minutesPart] = timeValue.split(":");
|
|
32734
|
+
const hour = Number.parseInt(hoursPart, 10);
|
|
32735
|
+
const minute = Number.parseInt(minutesPart ?? "0", 10);
|
|
32736
|
+
const safeHour = Number.isFinite(hour) ? hour : 0;
|
|
32737
|
+
const safeMinute = Number.isFinite(minute) ? minute : 0;
|
|
32738
|
+
return {
|
|
32739
|
+
hour: safeHour,
|
|
32740
|
+
minute: safeMinute,
|
|
32741
|
+
decimalHour: safeHour + safeMinute / 60
|
|
32742
|
+
};
|
|
32743
|
+
};
|
|
32744
|
+
var buildShiftLayout = ({
|
|
32745
|
+
shiftStart,
|
|
32746
|
+
shiftEnd
|
|
32747
|
+
}) => {
|
|
32748
|
+
const shiftStartTime = parseTimeString(shiftStart);
|
|
32749
|
+
if (!shiftEnd) {
|
|
32750
|
+
return {
|
|
32751
|
+
shiftDuration: DEFAULT_SHIFT_DURATION,
|
|
32752
|
+
shiftStartTime,
|
|
32753
|
+
shiftEndTime: null,
|
|
32754
|
+
hasPartialLastHour: false
|
|
32755
|
+
};
|
|
32756
|
+
}
|
|
32757
|
+
const shiftEndTime = parseTimeString(shiftEnd);
|
|
32758
|
+
let duration = shiftEndTime.decimalHour - shiftStartTime.decimalHour;
|
|
32759
|
+
if (duration <= 0) {
|
|
32760
|
+
duration += 24;
|
|
32761
|
+
}
|
|
32762
|
+
const hasPartialLastHour = shiftEndTime.minute > 0 && shiftEndTime.minute < 60;
|
|
32763
|
+
const shiftDuration = hasPartialLastHour ? Math.ceil(duration) : Math.round(duration);
|
|
32764
|
+
return {
|
|
32765
|
+
shiftDuration,
|
|
32766
|
+
shiftStartTime,
|
|
32767
|
+
shiftEndTime,
|
|
32768
|
+
hasPartialLastHour
|
|
32769
|
+
};
|
|
32770
|
+
};
|
|
32771
|
+
var formatCompactTime = (hour, minute) => {
|
|
32772
|
+
const period = hour >= 12 ? "PM" : "AM";
|
|
32773
|
+
const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
|
|
32774
|
+
if (minute === 0) {
|
|
32775
|
+
return `${hour12}${period}`;
|
|
32776
|
+
}
|
|
32777
|
+
return `${hour12}:${minute.toString().padStart(2, "0")}${period}`;
|
|
32778
|
+
};
|
|
32779
|
+
var formatFullTime = (hour, minute) => {
|
|
32780
|
+
const period = hour >= 12 ? "PM" : "AM";
|
|
32781
|
+
const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
|
|
32782
|
+
return `${hour12}:${minute.toString().padStart(2, "0")} ${period}`;
|
|
32783
|
+
};
|
|
32784
|
+
var getSlotTimeBounds = (hourIndex, layout2) => {
|
|
32785
|
+
const isLastHour = hourIndex === layout2.shiftDuration - 1;
|
|
32786
|
+
const startDecimalHour = layout2.shiftStartTime.decimalHour + hourIndex;
|
|
32787
|
+
const startHour = Math.floor(startDecimalHour) % 24;
|
|
32788
|
+
const startMinute = Math.round(startDecimalHour % 1 * 60);
|
|
32789
|
+
let endHour;
|
|
32790
|
+
let endMinute;
|
|
32791
|
+
if (isLastHour && layout2.shiftEndTime) {
|
|
32792
|
+
endHour = layout2.shiftEndTime.hour;
|
|
32793
|
+
endMinute = layout2.shiftEndTime.minute;
|
|
32794
|
+
} else {
|
|
32795
|
+
const endDecimalHour = startDecimalHour + 1;
|
|
32796
|
+
endHour = Math.floor(endDecimalHour) % 24;
|
|
32797
|
+
endMinute = Math.round(endDecimalHour % 1 * 60);
|
|
32798
|
+
}
|
|
32799
|
+
return {
|
|
32800
|
+
startHour,
|
|
32801
|
+
startMinute,
|
|
32802
|
+
endHour,
|
|
32803
|
+
endMinute
|
|
32804
|
+
};
|
|
32805
|
+
};
|
|
32806
|
+
var getIdleArrayForHour = (hourIndex, idleTimeHourly, layout2) => {
|
|
32807
|
+
const actualHour = (layout2.shiftStartTime.hour + hourIndex) % 24;
|
|
32808
|
+
const startMinute = layout2.shiftStartTime.minute;
|
|
32809
|
+
if (startMinute > 0) {
|
|
32810
|
+
if (hourIndex === 0) {
|
|
32811
|
+
const firstHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
32812
|
+
const nextHourData2 = idleTimeHourly[((actualHour + 1) % 24).toString()] || [];
|
|
32813
|
+
return [
|
|
32814
|
+
...firstHourData.slice(startMinute),
|
|
32815
|
+
...nextHourData2.slice(0, startMinute)
|
|
32816
|
+
];
|
|
32817
|
+
}
|
|
32818
|
+
if (hourIndex < layout2.shiftDuration - 1) {
|
|
32819
|
+
const currentHourData3 = idleTimeHourly[actualHour.toString()] || [];
|
|
32820
|
+
const nextHourData2 = idleTimeHourly[((actualHour + 1) % 24).toString()] || [];
|
|
32821
|
+
return [
|
|
32822
|
+
...currentHourData3.slice(startMinute),
|
|
32823
|
+
...nextHourData2.slice(0, startMinute)
|
|
32824
|
+
];
|
|
32825
|
+
}
|
|
32826
|
+
if (layout2.hasPartialLastHour && layout2.shiftEndTime) {
|
|
32827
|
+
const currentHourData3 = idleTimeHourly[actualHour.toString()] || [];
|
|
32828
|
+
const nextHourData2 = idleTimeHourly[((actualHour + 1) % 24).toString()] || [];
|
|
32829
|
+
return [
|
|
32830
|
+
...currentHourData3.slice(startMinute),
|
|
32831
|
+
...nextHourData2.slice(0, layout2.shiftEndTime.minute)
|
|
32832
|
+
];
|
|
32833
|
+
}
|
|
32834
|
+
const currentHourData2 = idleTimeHourly[actualHour.toString()] || [];
|
|
32835
|
+
const nextHourData = idleTimeHourly[((actualHour + 1) % 24).toString()] || [];
|
|
32836
|
+
return [
|
|
32837
|
+
...currentHourData2.slice(startMinute),
|
|
32838
|
+
...nextHourData.slice(0, startMinute)
|
|
32839
|
+
];
|
|
32840
|
+
}
|
|
32841
|
+
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
32842
|
+
if (hourIndex === layout2.shiftDuration - 1 && layout2.hasPartialLastHour && layout2.shiftEndTime) {
|
|
32843
|
+
return currentHourData.slice(0, layout2.shiftEndTime.minute);
|
|
32844
|
+
}
|
|
32845
|
+
return currentHourData;
|
|
32846
|
+
};
|
|
32847
|
+
var buildHourlyIdleSlots = ({
|
|
32848
|
+
idleTimeHourly,
|
|
32849
|
+
shiftStart,
|
|
32850
|
+
shiftEnd
|
|
32851
|
+
}) => {
|
|
32852
|
+
const normalizedIdleTimeHourly = normalizeMinuteSeries(idleTimeHourly);
|
|
32853
|
+
const layout2 = buildShiftLayout({ shiftStart, shiftEnd });
|
|
32854
|
+
return Array.from({ length: layout2.shiftDuration }, (_, hourIndex) => {
|
|
32855
|
+
const { startHour, startMinute, endHour, endMinute } = getSlotTimeBounds(hourIndex, layout2);
|
|
32856
|
+
const idleArray = getIdleArrayForHour(hourIndex, normalizedIdleTimeHourly, layout2);
|
|
32857
|
+
const idleMinutes = idleArray.filter((value) => value === 1 || value === "1").length;
|
|
32858
|
+
return {
|
|
32859
|
+
hourIndex,
|
|
32860
|
+
hour: `${formatCompactTime(startHour, startMinute)}-${formatCompactTime(endHour, endMinute)}`,
|
|
32861
|
+
timeRange: `${formatFullTime(startHour, startMinute)} - ${formatFullTime(endHour, endMinute)}`,
|
|
32862
|
+
idleMinutes,
|
|
32863
|
+
idleArray
|
|
32864
|
+
};
|
|
32865
|
+
});
|
|
32866
|
+
};
|
|
32867
|
+
var formatIdleTimestamp = ({
|
|
32868
|
+
shiftStart,
|
|
32869
|
+
hourIndex,
|
|
32870
|
+
minuteIndex
|
|
32871
|
+
}) => {
|
|
32872
|
+
const shiftStartTime = parseTimeString(shiftStart);
|
|
32873
|
+
const totalMinutes = (shiftStartTime.hour + hourIndex) * 60 + shiftStartTime.minute + minuteIndex;
|
|
32874
|
+
const hour = Math.floor(totalMinutes / 60) % 24;
|
|
32875
|
+
const minute = totalMinutes % 60;
|
|
32876
|
+
return formatFullTime(hour, minute);
|
|
32877
|
+
};
|
|
32878
|
+
var getHourlyIdlePeriods = ({
|
|
32879
|
+
idleArray,
|
|
32880
|
+
shiftStart,
|
|
32881
|
+
hourIndex
|
|
32882
|
+
}) => {
|
|
32883
|
+
if (!Array.isArray(idleArray) || idleArray.length === 0) {
|
|
32884
|
+
return [];
|
|
32885
|
+
}
|
|
32886
|
+
const periods = [];
|
|
32887
|
+
let currentRange = null;
|
|
32888
|
+
idleArray.forEach((value, minuteIndex) => {
|
|
32889
|
+
if (value === 1 || value === "1") {
|
|
32890
|
+
if (!currentRange) {
|
|
32891
|
+
currentRange = { start: minuteIndex, end: minuteIndex };
|
|
32892
|
+
} else {
|
|
32893
|
+
currentRange.end = minuteIndex;
|
|
32894
|
+
}
|
|
32895
|
+
} else if (value !== "x" && currentRange) {
|
|
32896
|
+
periods.push(currentRange);
|
|
32897
|
+
currentRange = null;
|
|
32898
|
+
}
|
|
32899
|
+
});
|
|
32900
|
+
if (currentRange) {
|
|
32901
|
+
periods.push(currentRange);
|
|
32902
|
+
}
|
|
32903
|
+
return periods.map((period) => ({
|
|
32904
|
+
start: period.start,
|
|
32905
|
+
end: period.end,
|
|
32906
|
+
duration: period.end - period.start + 1,
|
|
32907
|
+
startTime: formatIdleTimestamp({
|
|
32908
|
+
shiftStart,
|
|
32909
|
+
hourIndex,
|
|
32910
|
+
minuteIndex: period.start
|
|
32911
|
+
}),
|
|
32912
|
+
endTime: formatIdleTimestamp({
|
|
32913
|
+
shiftStart,
|
|
32914
|
+
hourIndex,
|
|
32915
|
+
minuteIndex: period.end + 1
|
|
32916
|
+
})
|
|
32917
|
+
}));
|
|
32918
|
+
};
|
|
32598
32919
|
var CycleTimeOverTimeChart = ({
|
|
32599
32920
|
data,
|
|
32600
32921
|
idealCycleTime,
|
|
@@ -32604,19 +32925,20 @@ var CycleTimeOverTimeChart = ({
|
|
|
32604
32925
|
datasetKey,
|
|
32605
32926
|
className = "",
|
|
32606
32927
|
showIdleTime = false,
|
|
32607
|
-
idleTimeData = []
|
|
32928
|
+
idleTimeData = [],
|
|
32929
|
+
idleTimeSlots = []
|
|
32608
32930
|
}) => {
|
|
32609
32931
|
const MAX_DATA_POINTS = 40;
|
|
32610
|
-
const containerRef =
|
|
32611
|
-
const [dimensions, setDimensions] =
|
|
32612
|
-
const [hasValidData, setHasValidData] =
|
|
32613
|
-
|
|
32932
|
+
const containerRef = React142__default.useRef(null);
|
|
32933
|
+
const [dimensions, setDimensions] = React142__default.useState({ width: 0, height: 0 });
|
|
32934
|
+
const [hasValidData, setHasValidData] = React142__default.useState(false);
|
|
32935
|
+
React142__default.useEffect(() => {
|
|
32614
32936
|
const currentHasValidData = data && data.some((val) => val !== null && val > 0);
|
|
32615
32937
|
if (currentHasValidData && !hasValidData) {
|
|
32616
32938
|
setHasValidData(true);
|
|
32617
32939
|
}
|
|
32618
32940
|
}, [data, hasValidData]);
|
|
32619
|
-
|
|
32941
|
+
React142__default.useEffect(() => {
|
|
32620
32942
|
if (!containerRef.current) return;
|
|
32621
32943
|
const observer = new ResizeObserver((entries) => {
|
|
32622
32944
|
const entry = entries[0];
|
|
@@ -32648,7 +32970,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32648
32970
|
const endLabel = shiftEnd && slotIndex === DURATION - 1 ? formatHourLabel(slotIndex + 1) : formatHourLabel(slotIndex + 1);
|
|
32649
32971
|
return `${startLabel} - ${endLabel}`;
|
|
32650
32972
|
};
|
|
32651
|
-
const getDisplayData =
|
|
32973
|
+
const getDisplayData = React142__default.useCallback((rawData) => {
|
|
32652
32974
|
if (xAxisMode === "hourly") return rawData;
|
|
32653
32975
|
return rawData.slice(Math.max(0, rawData.length - MAX_DATA_POINTS));
|
|
32654
32976
|
}, [xAxisMode]);
|
|
@@ -32656,7 +32978,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32656
32978
|
const DURATION = displayData.length;
|
|
32657
32979
|
const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
|
|
32658
32980
|
const finalData = displayData;
|
|
32659
|
-
const labelInterval =
|
|
32981
|
+
const labelInterval = React142__default.useMemo(() => {
|
|
32660
32982
|
if (xAxisMode === "hourly") {
|
|
32661
32983
|
return Math.max(1, Math.ceil(DURATION / 8));
|
|
32662
32984
|
}
|
|
@@ -32697,8 +33019,8 @@ var CycleTimeOverTimeChart = ({
|
|
|
32697
33019
|
return `${minutes} minutes ${seconds} seconds ago`;
|
|
32698
33020
|
}
|
|
32699
33021
|
};
|
|
32700
|
-
const getNumericValue =
|
|
32701
|
-
const renderChartTooltip =
|
|
33022
|
+
const getNumericValue = React142__default.useCallback((value) => typeof value === "number" && Number.isFinite(value) ? value : null, []);
|
|
33023
|
+
const renderChartTooltip = React142__default.useCallback((tooltipProps) => {
|
|
32702
33024
|
const { active, payload } = tooltipProps;
|
|
32703
33025
|
if (!active || !Array.isArray(payload) || payload.length === 0) {
|
|
32704
33026
|
return null;
|
|
@@ -32707,51 +33029,61 @@ var CycleTimeOverTimeChart = ({
|
|
|
32707
33029
|
if (!visibleEntries.length) {
|
|
32708
33030
|
return null;
|
|
32709
33031
|
}
|
|
32710
|
-
|
|
32711
|
-
|
|
32712
|
-
|
|
32713
|
-
|
|
32714
|
-
|
|
32715
|
-
|
|
32716
|
-
|
|
32717
|
-
|
|
32718
|
-
|
|
32719
|
-
|
|
32720
|
-
|
|
32721
|
-
|
|
32722
|
-
|
|
32723
|
-
|
|
32724
|
-
|
|
32725
|
-
|
|
32726
|
-
|
|
32727
|
-
|
|
32728
|
-
|
|
32729
|
-
|
|
32730
|
-
|
|
32731
|
-
|
|
32732
|
-
|
|
32733
|
-
|
|
32734
|
-
|
|
32735
|
-
|
|
32736
|
-
|
|
32737
|
-
|
|
32738
|
-
|
|
32739
|
-
|
|
32740
|
-
|
|
32741
|
-
|
|
32742
|
-
|
|
32743
|
-
|
|
32744
|
-
|
|
32745
|
-
|
|
32746
|
-
|
|
32747
|
-
|
|
32748
|
-
|
|
32749
|
-
|
|
32750
|
-
|
|
32751
|
-
|
|
32752
|
-
|
|
32753
|
-
|
|
32754
|
-
|
|
33032
|
+
const dataPoint = payload[0]?.payload || {};
|
|
33033
|
+
const idlePeriods = showIdleTime && typeof dataPoint.idleMinutes === "number" && dataPoint.idleMinutes > 0 ? getHourlyIdlePeriods({
|
|
33034
|
+
idleArray: dataPoint.idleArray,
|
|
33035
|
+
shiftStart,
|
|
33036
|
+
hourIndex: Number.isFinite(dataPoint.hourIndex) ? dataPoint.hourIndex : 0
|
|
33037
|
+
}) : [];
|
|
33038
|
+
return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-xl border border-gray-100 p-4 min-w-[220px]", children: [
|
|
33039
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsx("p", { className: "font-semibold text-gray-900 text-sm", children: dataPoint.timeRange || dataPoint.tooltip || "" }) }),
|
|
33040
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
33041
|
+
visibleEntries.map((entry) => {
|
|
33042
|
+
const numericValue = getNumericValue(entry.value);
|
|
33043
|
+
if (numericValue === null) {
|
|
33044
|
+
return null;
|
|
33045
|
+
}
|
|
33046
|
+
if (entry.name === "idleMinutes") {
|
|
33047
|
+
if (!showIdleTime) return null;
|
|
33048
|
+
return /* @__PURE__ */ jsx("div", { className: "border-t border-gray-100 pt-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
33049
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: "Idle Time" }),
|
|
33050
|
+
/* @__PURE__ */ jsxs("span", { className: "font-semibold text-orange-600 text-sm", children: [
|
|
33051
|
+
numericValue.toFixed(0),
|
|
33052
|
+
" minutes"
|
|
33053
|
+
] })
|
|
33054
|
+
] }) }, `${entry.name}-${numericValue}`);
|
|
33055
|
+
}
|
|
33056
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
33057
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: "Cycle Time" }),
|
|
33058
|
+
/* @__PURE__ */ jsxs("span", { className: "font-semibold text-gray-900 text-sm", children: [
|
|
33059
|
+
numericValue.toFixed(1),
|
|
33060
|
+
" seconds"
|
|
33061
|
+
] })
|
|
33062
|
+
] }, `${entry.name}-${numericValue}`);
|
|
33063
|
+
}),
|
|
33064
|
+
idlePeriods.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-3 bg-gray-50 rounded-lg p-2.5", children: [
|
|
33065
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-gray-700 text-xs mb-2", children: "Idle periods:" }),
|
|
33066
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1 max-h-32 overflow-y-auto pr-1", children: idlePeriods.map((period, index) => /* @__PURE__ */ jsxs("div", { className: "text-gray-600 flex items-center gap-2 text-xs", children: [
|
|
33067
|
+
/* @__PURE__ */ jsx("span", { className: "inline-block w-1.5 h-1.5 bg-orange-400 rounded-full flex-shrink-0" }),
|
|
33068
|
+
/* @__PURE__ */ jsx("span", { children: period.duration === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33069
|
+
period.startTime,
|
|
33070
|
+
" (",
|
|
33071
|
+
period.duration,
|
|
33072
|
+
" min)"
|
|
33073
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33074
|
+
period.startTime,
|
|
33075
|
+
" - ",
|
|
33076
|
+
period.endTime,
|
|
33077
|
+
" (",
|
|
33078
|
+
period.duration,
|
|
33079
|
+
" mins)"
|
|
33080
|
+
] }) })
|
|
33081
|
+
] }, index)) })
|
|
33082
|
+
] })
|
|
33083
|
+
] })
|
|
33084
|
+
] });
|
|
33085
|
+
}, [getNumericValue, shiftStart, showIdleTime]);
|
|
33086
|
+
const renderCycleDot = React142__default.useCallback((props) => {
|
|
32755
33087
|
const { cx: cx2, cy, payload } = props;
|
|
32756
33088
|
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
32757
33089
|
if (cycleTime === null) {
|
|
@@ -32784,7 +33116,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32784
33116
|
}
|
|
32785
33117
|
);
|
|
32786
33118
|
}, [getNumericValue, idealCycleTime]);
|
|
32787
|
-
const renderCycleActiveDot =
|
|
33119
|
+
const renderCycleActiveDot = React142__default.useCallback((props) => {
|
|
32788
33120
|
const { cx: cx2, cy, payload } = props;
|
|
32789
33121
|
const cycleTime = getNumericValue(payload?.cycleTime);
|
|
32790
33122
|
if (cycleTime === null) {
|
|
@@ -32805,7 +33137,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32805
33137
|
}
|
|
32806
33138
|
);
|
|
32807
33139
|
}, [getNumericValue, idealCycleTime]);
|
|
32808
|
-
const renderIdleDot =
|
|
33140
|
+
const renderIdleDot = React142__default.useCallback((props) => {
|
|
32809
33141
|
const { cx: cx2, cy, payload } = props;
|
|
32810
33142
|
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
32811
33143
|
if (idleMinutes === null) {
|
|
@@ -32819,14 +33151,18 @@ var CycleTimeOverTimeChart = ({
|
|
|
32819
33151
|
r: 4,
|
|
32820
33152
|
fill: "#f59e0b",
|
|
32821
33153
|
stroke: "#fff",
|
|
32822
|
-
strokeWidth: 1
|
|
33154
|
+
strokeWidth: 1,
|
|
33155
|
+
style: {
|
|
33156
|
+
opacity: showIdleTime ? 1 : 0,
|
|
33157
|
+
transition: "opacity 0.3s ease-in-out"
|
|
33158
|
+
}
|
|
32823
33159
|
}
|
|
32824
33160
|
);
|
|
32825
|
-
}, [getNumericValue]);
|
|
32826
|
-
const renderIdleActiveDot =
|
|
33161
|
+
}, [getNumericValue, showIdleTime]);
|
|
33162
|
+
const renderIdleActiveDot = React142__default.useCallback((props) => {
|
|
32827
33163
|
const { cx: cx2, cy, payload } = props;
|
|
32828
33164
|
const idleMinutes = getNumericValue(payload?.idleMinutes);
|
|
32829
|
-
if (idleMinutes === null) {
|
|
33165
|
+
if (idleMinutes === null || !showIdleTime) {
|
|
32830
33166
|
return /* @__PURE__ */ jsx("g", {});
|
|
32831
33167
|
}
|
|
32832
33168
|
return /* @__PURE__ */ jsx(
|
|
@@ -32840,25 +33176,40 @@ var CycleTimeOverTimeChart = ({
|
|
|
32840
33176
|
strokeWidth: 2
|
|
32841
33177
|
}
|
|
32842
33178
|
);
|
|
32843
|
-
}, [getNumericValue]);
|
|
32844
|
-
const chartData =
|
|
33179
|
+
}, [getNumericValue, showIdleTime]);
|
|
33180
|
+
const chartData = React142__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
|
|
32845
33181
|
const cycleTime = getNumericValue(finalData[i]);
|
|
32846
|
-
const
|
|
33182
|
+
const useIdleSlots = idleTimeSlots.length > 0;
|
|
33183
|
+
const idleSlot = useIdleSlots ? idleTimeSlots[i] ?? null : null;
|
|
33184
|
+
const idleMinutes = useIdleSlots ? idleSlot?.idleMinutes ?? null : getNumericValue(idleTimeData[i]);
|
|
32847
33185
|
return {
|
|
32848
33186
|
timeIndex: i,
|
|
32849
33187
|
label: formatTimeLabel(i),
|
|
32850
|
-
tooltip: formatTooltipTime(i),
|
|
33188
|
+
tooltip: idleSlot?.timeRange || formatTooltipTime(i),
|
|
33189
|
+
timeRange: idleSlot?.timeRange || formatTooltipTime(i),
|
|
33190
|
+
hourIndex: idleSlot?.hourIndex ?? i,
|
|
32851
33191
|
cycleTime,
|
|
32852
33192
|
idleMinutes,
|
|
33193
|
+
idleArray: idleSlot?.idleArray || [],
|
|
32853
33194
|
color: cycleTime !== null && cycleTime <= idealCycleTime ? "#00AB45" : "#E34329"
|
|
32854
33195
|
};
|
|
32855
|
-
}), [DURATION, finalData,
|
|
33196
|
+
}), [DURATION, finalData, idleTimeData, idleTimeSlots, idealCycleTime, getNumericValue]);
|
|
32856
33197
|
const renderLegend = () => {
|
|
32857
|
-
|
|
32858
|
-
|
|
32859
|
-
|
|
32860
|
-
|
|
32861
|
-
|
|
33198
|
+
return /* @__PURE__ */ jsx(
|
|
33199
|
+
"div",
|
|
33200
|
+
{
|
|
33201
|
+
className: "flex items-center justify-start text-[10px] font-bold text-gray-500 mb-6 tracking-[0.05em] gap-5",
|
|
33202
|
+
style: {
|
|
33203
|
+
opacity: showIdleTime ? 1 : 0,
|
|
33204
|
+
pointerEvents: showIdleTime ? "auto" : "none",
|
|
33205
|
+
transition: "opacity 0.3s ease-in-out"
|
|
33206
|
+
},
|
|
33207
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
33208
|
+
/* @__PURE__ */ jsx("div", { className: "w-2.5 h-2.5 rounded-full bg-[#f59e0b]" }),
|
|
33209
|
+
/* @__PURE__ */ jsx("span", { children: "Idle Time (min)" })
|
|
33210
|
+
] })
|
|
33211
|
+
}
|
|
33212
|
+
);
|
|
32862
33213
|
};
|
|
32863
33214
|
return /* @__PURE__ */ jsxs(
|
|
32864
33215
|
"div",
|
|
@@ -32929,7 +33280,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32929
33280
|
}
|
|
32930
33281
|
}
|
|
32931
33282
|
),
|
|
32932
|
-
|
|
33283
|
+
/* @__PURE__ */ jsx(
|
|
32933
33284
|
YAxis,
|
|
32934
33285
|
{
|
|
32935
33286
|
yAxisId: "idle",
|
|
@@ -32938,7 +33289,11 @@ var CycleTimeOverTimeChart = ({
|
|
|
32938
33289
|
width: 35,
|
|
32939
33290
|
domain: [0, 60],
|
|
32940
33291
|
tickFormatter: (value) => `${value}m`,
|
|
32941
|
-
tick: {
|
|
33292
|
+
tick: {
|
|
33293
|
+
fontSize: 11,
|
|
33294
|
+
fill: showIdleTime ? "#f59e0b" : "transparent",
|
|
33295
|
+
style: { transition: "fill 0.3s ease-in-out" }
|
|
33296
|
+
},
|
|
32942
33297
|
axisLine: false,
|
|
32943
33298
|
tickLine: false
|
|
32944
33299
|
}
|
|
@@ -32986,7 +33341,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32986
33341
|
},
|
|
32987
33342
|
`${effectiveDatasetKey}:cycle`
|
|
32988
33343
|
),
|
|
32989
|
-
|
|
33344
|
+
/* @__PURE__ */ jsx(
|
|
32990
33345
|
Line,
|
|
32991
33346
|
{
|
|
32992
33347
|
type: "monotone",
|
|
@@ -33001,7 +33356,11 @@ var CycleTimeOverTimeChart = ({
|
|
|
33001
33356
|
isAnimationActive: true,
|
|
33002
33357
|
animationBegin: 300,
|
|
33003
33358
|
animationDuration: 1500,
|
|
33004
|
-
animationEasing: "ease-out"
|
|
33359
|
+
animationEasing: "ease-out",
|
|
33360
|
+
style: {
|
|
33361
|
+
strokeOpacity: showIdleTime ? 1 : 0,
|
|
33362
|
+
transition: "stroke-opacity 0.3s ease-in-out"
|
|
33363
|
+
}
|
|
33005
33364
|
},
|
|
33006
33365
|
`${effectiveDatasetKey}:idle`
|
|
33007
33366
|
)
|
|
@@ -33015,7 +33374,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
33015
33374
|
}
|
|
33016
33375
|
);
|
|
33017
33376
|
};
|
|
33018
|
-
var Card =
|
|
33377
|
+
var Card = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33019
33378
|
"div",
|
|
33020
33379
|
{
|
|
33021
33380
|
ref,
|
|
@@ -33027,7 +33386,7 @@ var Card = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
33027
33386
|
}
|
|
33028
33387
|
));
|
|
33029
33388
|
Card.displayName = "Card";
|
|
33030
|
-
var CardHeader =
|
|
33389
|
+
var CardHeader = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33031
33390
|
"div",
|
|
33032
33391
|
{
|
|
33033
33392
|
ref,
|
|
@@ -33036,7 +33395,7 @@ var CardHeader = React141.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
33036
33395
|
}
|
|
33037
33396
|
));
|
|
33038
33397
|
CardHeader.displayName = "CardHeader";
|
|
33039
|
-
var CardTitle =
|
|
33398
|
+
var CardTitle = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33040
33399
|
"h3",
|
|
33041
33400
|
{
|
|
33042
33401
|
ref,
|
|
@@ -33048,7 +33407,7 @@ var CardTitle = React141.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
33048
33407
|
}
|
|
33049
33408
|
));
|
|
33050
33409
|
CardTitle.displayName = "CardTitle";
|
|
33051
|
-
var CardDescription =
|
|
33410
|
+
var CardDescription = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33052
33411
|
"p",
|
|
33053
33412
|
{
|
|
33054
33413
|
ref,
|
|
@@ -33057,9 +33416,9 @@ var CardDescription = React141.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
33057
33416
|
}
|
|
33058
33417
|
));
|
|
33059
33418
|
CardDescription.displayName = "CardDescription";
|
|
33060
|
-
var CardContent =
|
|
33419
|
+
var CardContent = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
|
|
33061
33420
|
CardContent.displayName = "CardContent";
|
|
33062
|
-
var CardFooter =
|
|
33421
|
+
var CardFooter = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
33063
33422
|
"div",
|
|
33064
33423
|
{
|
|
33065
33424
|
ref,
|
|
@@ -33135,7 +33494,7 @@ var buttonVariants = cva(
|
|
|
33135
33494
|
}
|
|
33136
33495
|
}
|
|
33137
33496
|
);
|
|
33138
|
-
var Button =
|
|
33497
|
+
var Button = React142.forwardRef(
|
|
33139
33498
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
33140
33499
|
const Comp = asChild ? Slot : "button";
|
|
33141
33500
|
return /* @__PURE__ */ jsx(
|
|
@@ -33156,95 +33515,26 @@ var HourlyOutputChartComponent = ({
|
|
|
33156
33515
|
shiftEnd,
|
|
33157
33516
|
showIdleTime = false,
|
|
33158
33517
|
idleTimeHourly,
|
|
33159
|
-
idleTimeClips,
|
|
33160
|
-
idleTimeClipClassifications,
|
|
33161
|
-
shiftDate,
|
|
33162
|
-
timezone,
|
|
33163
33518
|
className = ""
|
|
33164
33519
|
}) => {
|
|
33165
|
-
const containerRef =
|
|
33166
|
-
const [containerReady, setContainerReady] =
|
|
33167
|
-
const [containerWidth, setContainerWidth] =
|
|
33168
|
-
const
|
|
33169
|
-
|
|
33170
|
-
|
|
33171
|
-
const minute = parseInt(minutes || "0");
|
|
33172
|
-
const decimalHour = hour + minute / 60;
|
|
33173
|
-
return { hour, minute, decimalHour };
|
|
33174
|
-
};
|
|
33175
|
-
const shiftStartTime = getTimeFromTimeString2(shiftStart);
|
|
33176
|
-
React141__default.useMemo(() => {
|
|
33177
|
-
if (!shiftDate || !timezone) return null;
|
|
33178
|
-
const hour = shiftStartTime.hour.toString().padStart(2, "0");
|
|
33179
|
-
const minute = shiftStartTime.minute.toString().padStart(2, "0");
|
|
33180
|
-
return fromZonedTime(`${shiftDate}T${hour}:${minute}:00`, timezone);
|
|
33181
|
-
}, [shiftDate, timezone, shiftStartTime.hour, shiftStartTime.minute]);
|
|
33182
|
-
const idleClipRanges = React141__default.useMemo(() => {
|
|
33183
|
-
if (!idleTimeClips || idleTimeClips.length === 0) return [];
|
|
33184
|
-
return idleTimeClips.map((clip) => ({
|
|
33185
|
-
id: clip.id,
|
|
33186
|
-
start: clip.idle_start_time ? new Date(clip.idle_start_time) : null,
|
|
33187
|
-
end: clip.idle_end_time ? new Date(clip.idle_end_time) : null
|
|
33188
|
-
})).filter((clip) => clip.start && clip.end);
|
|
33189
|
-
}, [idleTimeClips]);
|
|
33190
|
-
React141__default.useCallback((rangeStart, rangeEnd) => {
|
|
33191
|
-
if (!rangeStart || !rangeEnd || idleClipRanges.length === 0) {
|
|
33192
|
-
return "Reason unavailable";
|
|
33193
|
-
}
|
|
33194
|
-
const matchingClip = idleClipRanges.find((clip) => rangeStart >= clip.start && rangeEnd <= clip.end) || idleClipRanges.find((clip) => rangeStart < clip.end && rangeEnd > clip.start);
|
|
33195
|
-
if (!matchingClip) {
|
|
33196
|
-
return "Reason unavailable";
|
|
33197
|
-
}
|
|
33198
|
-
const classification = idleTimeClipClassifications?.[matchingClip.id];
|
|
33199
|
-
if (!classification || classification.status === "processing") {
|
|
33200
|
-
return "Analyzing...";
|
|
33201
|
-
}
|
|
33202
|
-
if (!classification.label) {
|
|
33203
|
-
return "Reason unavailable";
|
|
33204
|
-
}
|
|
33205
|
-
return classification.displayName || classification.label.replace(/_/g, " ");
|
|
33206
|
-
}, [idleClipRanges, idleTimeClipClassifications]);
|
|
33207
|
-
const { shiftDuration, shiftEndTime, hasPartialLastHour } = React141__default.useMemo(() => {
|
|
33208
|
-
console.log("[HourlyOutputChart] Calculating shift duration with:", {
|
|
33520
|
+
const containerRef = React142__default.useRef(null);
|
|
33521
|
+
const [containerReady, setContainerReady] = React142__default.useState(false);
|
|
33522
|
+
const [containerWidth, setContainerWidth] = React142__default.useState(0);
|
|
33523
|
+
const idleSlots = React142__default.useMemo(
|
|
33524
|
+
() => buildHourlyIdleSlots({
|
|
33525
|
+
idleTimeHourly,
|
|
33209
33526
|
shiftStart,
|
|
33210
|
-
shiftEnd
|
|
33211
|
-
|
|
33212
|
-
|
|
33213
|
-
|
|
33214
|
-
|
|
33215
|
-
|
|
33216
|
-
shiftDuration: 11,
|
|
33217
|
-
shiftEndTime: null,
|
|
33218
|
-
hasPartialLastHour: false
|
|
33219
|
-
};
|
|
33220
|
-
}
|
|
33221
|
-
const endTime = getTimeFromTimeString2(shiftEnd);
|
|
33222
|
-
let duration = endTime.decimalHour - shiftStartTime.decimalHour;
|
|
33223
|
-
if (duration <= 0) {
|
|
33224
|
-
duration += 24;
|
|
33225
|
-
}
|
|
33226
|
-
const hasPartial = endTime.minute > 0 && endTime.minute < 60;
|
|
33227
|
-
const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
|
|
33228
|
-
console.log("[HourlyOutputChart] Shift calculation results:", {
|
|
33229
|
-
endTime,
|
|
33230
|
-
duration,
|
|
33231
|
-
hasPartial,
|
|
33232
|
-
hourCount
|
|
33233
|
-
});
|
|
33234
|
-
return {
|
|
33235
|
-
shiftDuration: hourCount,
|
|
33236
|
-
shiftEndTime: endTime,
|
|
33237
|
-
hasPartialLastHour: hasPartial
|
|
33238
|
-
};
|
|
33239
|
-
}, [shiftEnd, shiftStartTime.decimalHour]);
|
|
33240
|
-
const SHIFT_DURATION = shiftDuration;
|
|
33241
|
-
shiftEndTime ? shiftEndTime.hour : (shiftStartTime.hour + SHIFT_DURATION) % 24;
|
|
33242
|
-
const [animatedData, setAnimatedData] = React141__default.useState(
|
|
33527
|
+
shiftEnd
|
|
33528
|
+
}),
|
|
33529
|
+
[idleTimeHourly, shiftStart, shiftEnd]
|
|
33530
|
+
);
|
|
33531
|
+
const SHIFT_DURATION = idleSlots.length;
|
|
33532
|
+
const [animatedData, setAnimatedData] = React142__default.useState(
|
|
33243
33533
|
() => Array(SHIFT_DURATION).fill(0)
|
|
33244
33534
|
);
|
|
33245
|
-
const prevDataRef =
|
|
33246
|
-
const animationFrameRef =
|
|
33247
|
-
|
|
33535
|
+
const prevDataRef = React142__default.useRef(Array(SHIFT_DURATION).fill(0));
|
|
33536
|
+
const animationFrameRef = React142__default.useRef(null);
|
|
33537
|
+
React142__default.useEffect(() => {
|
|
33248
33538
|
setAnimatedData((prev) => {
|
|
33249
33539
|
if (prev.length !== SHIFT_DURATION) {
|
|
33250
33540
|
return Array(SHIFT_DURATION).fill(0);
|
|
@@ -33253,14 +33543,14 @@ var HourlyOutputChartComponent = ({
|
|
|
33253
33543
|
});
|
|
33254
33544
|
prevDataRef.current = Array(SHIFT_DURATION).fill(0);
|
|
33255
33545
|
}, [SHIFT_DURATION]);
|
|
33256
|
-
const [idleBarState, setIdleBarState] =
|
|
33546
|
+
const [idleBarState, setIdleBarState] = React142__default.useState({
|
|
33257
33547
|
visible: showIdleTime,
|
|
33258
33548
|
key: 0,
|
|
33259
33549
|
shouldAnimate: false
|
|
33260
33550
|
});
|
|
33261
|
-
const prevShowIdleTimeRef =
|
|
33262
|
-
const stateUpdateTimeoutRef =
|
|
33263
|
-
|
|
33551
|
+
const prevShowIdleTimeRef = React142__default.useRef(showIdleTime);
|
|
33552
|
+
const stateUpdateTimeoutRef = React142__default.useRef(null);
|
|
33553
|
+
React142__default.useEffect(() => {
|
|
33264
33554
|
if (stateUpdateTimeoutRef.current) {
|
|
33265
33555
|
clearTimeout(stateUpdateTimeoutRef.current);
|
|
33266
33556
|
}
|
|
@@ -33285,7 +33575,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33285
33575
|
}
|
|
33286
33576
|
};
|
|
33287
33577
|
}, [showIdleTime]);
|
|
33288
|
-
const animateToNewData =
|
|
33578
|
+
const animateToNewData = React142__default.useCallback((targetData) => {
|
|
33289
33579
|
const startData = [...prevDataRef.current];
|
|
33290
33580
|
const startTime = performance.now();
|
|
33291
33581
|
const duration = 1200;
|
|
@@ -33315,7 +33605,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33315
33605
|
}
|
|
33316
33606
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
33317
33607
|
}, []);
|
|
33318
|
-
|
|
33608
|
+
React142__default.useEffect(() => {
|
|
33319
33609
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
33320
33610
|
const shiftData = data.slice(0, SHIFT_DURATION);
|
|
33321
33611
|
animateToNewData(shiftData);
|
|
@@ -33326,7 +33616,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33326
33616
|
}
|
|
33327
33617
|
};
|
|
33328
33618
|
}, [data, animateToNewData]);
|
|
33329
|
-
|
|
33619
|
+
React142__default.useEffect(() => {
|
|
33330
33620
|
const checkContainerDimensions = () => {
|
|
33331
33621
|
if (containerRef.current) {
|
|
33332
33622
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -33352,7 +33642,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33352
33642
|
clearTimeout(fallbackTimeout);
|
|
33353
33643
|
};
|
|
33354
33644
|
}, []);
|
|
33355
|
-
const xAxisConfig =
|
|
33645
|
+
const xAxisConfig = React142__default.useMemo(() => {
|
|
33356
33646
|
if (containerWidth >= 960) {
|
|
33357
33647
|
return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12 };
|
|
33358
33648
|
}
|
|
@@ -33361,122 +33651,23 @@ var HourlyOutputChartComponent = ({
|
|
|
33361
33651
|
}
|
|
33362
33652
|
return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6 };
|
|
33363
33653
|
}, [containerWidth]);
|
|
33364
|
-
const
|
|
33365
|
-
const isLastHour = hourIndex === SHIFT_DURATION - 1;
|
|
33366
|
-
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
33367
|
-
const startHour = Math.floor(startDecimalHour) % 24;
|
|
33368
|
-
const startMinute = Math.round(startDecimalHour % 1 * 60);
|
|
33369
|
-
let endHour, endMinute;
|
|
33370
|
-
if (isLastHour && shiftEndTime) {
|
|
33371
|
-
endHour = shiftEndTime.hour;
|
|
33372
|
-
endMinute = shiftEndTime.minute;
|
|
33373
|
-
} else {
|
|
33374
|
-
const endDecimalHour = startDecimalHour + 1;
|
|
33375
|
-
endHour = Math.floor(endDecimalHour) % 24;
|
|
33376
|
-
endMinute = Math.round(endDecimalHour % 1 * 60);
|
|
33377
|
-
}
|
|
33378
|
-
const formatTime5 = (h, m) => {
|
|
33379
|
-
const period = h >= 12 ? "PM" : "AM";
|
|
33380
|
-
const hour12 = h === 0 ? 12 : h > 12 ? h - 12 : h;
|
|
33381
|
-
if (m === 0) {
|
|
33382
|
-
return `${hour12}${period}`;
|
|
33383
|
-
}
|
|
33384
|
-
return `${hour12}:${m.toString().padStart(2, "0")}${period}`;
|
|
33385
|
-
};
|
|
33386
|
-
return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
|
|
33387
|
-
}, [shiftStartTime.decimalHour, SHIFT_DURATION, shiftEndTime]);
|
|
33388
|
-
const formatTimeRange2 = React141__default.useCallback((hourIndex) => {
|
|
33389
|
-
const isLastHour = hourIndex === SHIFT_DURATION - 1;
|
|
33390
|
-
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
33391
|
-
const startHour = Math.floor(startDecimalHour) % 24;
|
|
33392
|
-
const startMinute = Math.round(startDecimalHour % 1 * 60);
|
|
33393
|
-
let endHour, endMinute;
|
|
33394
|
-
if (isLastHour && shiftEndTime) {
|
|
33395
|
-
endHour = shiftEndTime.hour;
|
|
33396
|
-
endMinute = shiftEndTime.minute;
|
|
33397
|
-
} else {
|
|
33398
|
-
const endDecimalHour = startDecimalHour + 1;
|
|
33399
|
-
endHour = Math.floor(endDecimalHour) % 24;
|
|
33400
|
-
endMinute = Math.round(endDecimalHour % 1 * 60);
|
|
33401
|
-
}
|
|
33402
|
-
const formatTime5 = (h, m) => {
|
|
33403
|
-
const period = h >= 12 ? "PM" : "AM";
|
|
33404
|
-
const hour12 = h === 0 ? 12 : h > 12 ? h - 12 : h;
|
|
33405
|
-
return `${hour12}:${m.toString().padStart(2, "0")} ${period}`;
|
|
33406
|
-
};
|
|
33407
|
-
return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
|
|
33408
|
-
}, [shiftStartTime.decimalHour, SHIFT_DURATION, shiftEndTime]);
|
|
33409
|
-
const chartData = React141__default.useMemo(() => {
|
|
33654
|
+
const chartData = React142__default.useMemo(() => {
|
|
33410
33655
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
33411
|
-
const
|
|
33412
|
-
const startMinute = shiftStartTime.minute;
|
|
33413
|
-
let idleArray = [];
|
|
33414
|
-
let idleMinutes = 0;
|
|
33415
|
-
if (idleTimeHourly) {
|
|
33416
|
-
if (startMinute > 0) {
|
|
33417
|
-
if (i === 0) {
|
|
33418
|
-
const firstHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
33419
|
-
const nextHour = (actualHour + 1) % 24;
|
|
33420
|
-
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
33421
|
-
idleArray = [
|
|
33422
|
-
...firstHourData.slice(startMinute) || [],
|
|
33423
|
-
...nextHourData.slice(0, startMinute) || []
|
|
33424
|
-
];
|
|
33425
|
-
} else if (i < SHIFT_DURATION - 1) {
|
|
33426
|
-
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
33427
|
-
const nextHour = (actualHour + 1) % 24;
|
|
33428
|
-
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
33429
|
-
idleArray = [
|
|
33430
|
-
...currentHourData.slice(startMinute) || [],
|
|
33431
|
-
...nextHourData.slice(0, startMinute) || []
|
|
33432
|
-
];
|
|
33433
|
-
} else {
|
|
33434
|
-
const hasPartialLastHour2 = shiftEndTime && shiftEndTime.minute > 0 && shiftEndTime.minute < 60;
|
|
33435
|
-
if (hasPartialLastHour2) {
|
|
33436
|
-
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
33437
|
-
const nextHour = (actualHour + 1) % 24;
|
|
33438
|
-
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
33439
|
-
if (startMinute > 0) {
|
|
33440
|
-
const firstPart = currentHourData.slice(startMinute) || [];
|
|
33441
|
-
const secondPart = nextHourData.slice(0, shiftEndTime.minute) || [];
|
|
33442
|
-
idleArray = [...firstPart, ...secondPart];
|
|
33443
|
-
} else {
|
|
33444
|
-
idleArray = currentHourData.slice(0, shiftEndTime.minute) || [];
|
|
33445
|
-
}
|
|
33446
|
-
} else {
|
|
33447
|
-
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
33448
|
-
const nextHour = (actualHour + 1) % 24;
|
|
33449
|
-
const nextHourData = idleTimeHourly[nextHour.toString()] || [];
|
|
33450
|
-
idleArray = [
|
|
33451
|
-
...currentHourData.slice(startMinute) || [],
|
|
33452
|
-
...nextHourData.slice(0, startMinute) || []
|
|
33453
|
-
];
|
|
33454
|
-
}
|
|
33455
|
-
}
|
|
33456
|
-
} else {
|
|
33457
|
-
const currentHourData = idleTimeHourly[actualHour.toString()] || [];
|
|
33458
|
-
if (i === SHIFT_DURATION - 1 && shiftEndTime && shiftEndTime.minute > 0 && shiftEndTime.minute < 60) {
|
|
33459
|
-
idleArray = currentHourData.slice(0, shiftEndTime.minute) || [];
|
|
33460
|
-
} else {
|
|
33461
|
-
idleArray = currentHourData || [];
|
|
33462
|
-
}
|
|
33463
|
-
}
|
|
33464
|
-
}
|
|
33465
|
-
idleMinutes = idleArray.filter((val) => val === "1" || val === 1).length;
|
|
33656
|
+
const idleSlot = idleSlots[i];
|
|
33466
33657
|
return {
|
|
33467
|
-
hourIndex: i,
|
|
33468
|
-
hour:
|
|
33469
|
-
timeRange:
|
|
33658
|
+
hourIndex: idleSlot?.hourIndex ?? i,
|
|
33659
|
+
hour: idleSlot?.hour || "",
|
|
33660
|
+
timeRange: idleSlot?.timeRange || "",
|
|
33470
33661
|
output: animatedData[i] || 0,
|
|
33471
33662
|
originalOutput: data[i] || 0,
|
|
33472
33663
|
// Keep original data for labels
|
|
33473
33664
|
color: (animatedData[i] || 0) >= Math.round(pphThreshold) ? "#00AB45" : "#E34329",
|
|
33474
|
-
idleMinutes,
|
|
33475
|
-
idleArray
|
|
33665
|
+
idleMinutes: idleSlot?.idleMinutes || 0,
|
|
33666
|
+
idleArray: idleSlot?.idleArray || []
|
|
33476
33667
|
};
|
|
33477
33668
|
});
|
|
33478
|
-
}, [animatedData, data, pphThreshold,
|
|
33479
|
-
const IdleBar =
|
|
33669
|
+
}, [animatedData, data, pphThreshold, idleSlots, SHIFT_DURATION]);
|
|
33670
|
+
const IdleBar = React142__default.useMemo(() => {
|
|
33480
33671
|
if (!idleBarState.visible) return null;
|
|
33481
33672
|
return /* @__PURE__ */ jsx(
|
|
33482
33673
|
Bar,
|
|
@@ -33637,36 +33828,11 @@ var HourlyOutputChartComponent = ({
|
|
|
33637
33828
|
content: (props) => {
|
|
33638
33829
|
if (!props.active || !props.payload || props.payload.length === 0) return null;
|
|
33639
33830
|
const data2 = props.payload[0].payload;
|
|
33640
|
-
const
|
|
33641
|
-
|
|
33642
|
-
|
|
33643
|
-
data2.
|
|
33644
|
-
|
|
33645
|
-
if (!currentRange) {
|
|
33646
|
-
currentRange = { start: idx, end: idx };
|
|
33647
|
-
} else {
|
|
33648
|
-
currentRange.end = idx;
|
|
33649
|
-
}
|
|
33650
|
-
} else if (val !== "x" && currentRange) {
|
|
33651
|
-
idleRanges.push(currentRange);
|
|
33652
|
-
currentRange = null;
|
|
33653
|
-
}
|
|
33654
|
-
});
|
|
33655
|
-
if (currentRange) {
|
|
33656
|
-
idleRanges.push(currentRange);
|
|
33657
|
-
}
|
|
33658
|
-
}
|
|
33659
|
-
const formatIdleTimestamp = (minuteIdx) => {
|
|
33660
|
-
const fallbackIndex = chartData.findIndex((item) => item.timeRange === data2.timeRange);
|
|
33661
|
-
const hourOffset = Number.isFinite(data2.hourIndex) ? data2.hourIndex : fallbackIndex;
|
|
33662
|
-
const safeHourOffset = hourOffset >= 0 ? hourOffset : 0;
|
|
33663
|
-
const totalMinutes = (shiftStartTime.hour + safeHourOffset) * 60 + shiftStartTime.minute + minuteIdx;
|
|
33664
|
-
const hour = Math.floor(totalMinutes / 60) % 24;
|
|
33665
|
-
const minute = totalMinutes % 60;
|
|
33666
|
-
const period = hour >= 12 ? "PM" : "AM";
|
|
33667
|
-
const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
|
|
33668
|
-
return `${hour12}:${minute.toString().padStart(2, "0")} ${period}`;
|
|
33669
|
-
};
|
|
33831
|
+
const idlePeriods = showIdleTime ? getHourlyIdlePeriods({
|
|
33832
|
+
idleArray: data2.idleArray,
|
|
33833
|
+
shiftStart,
|
|
33834
|
+
hourIndex: Number.isFinite(data2.hourIndex) ? data2.hourIndex : 0
|
|
33835
|
+
}) : [];
|
|
33670
33836
|
return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-xl border border-gray-100 p-4 min-w-[220px]", children: [
|
|
33671
33837
|
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsx("p", { className: "font-semibold text-gray-900 text-sm", children: data2.timeRange }) }),
|
|
33672
33838
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
@@ -33685,27 +33851,22 @@ var HourlyOutputChartComponent = ({
|
|
|
33685
33851
|
" minutes"
|
|
33686
33852
|
] })
|
|
33687
33853
|
] }) }),
|
|
33688
|
-
|
|
33854
|
+
idlePeriods.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-3 bg-gray-50 rounded-lg p-2.5", children: [
|
|
33689
33855
|
/* @__PURE__ */ jsx("p", { className: "font-medium text-gray-700 text-xs mb-2", children: "Idle periods:" }),
|
|
33690
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-1 max-h-32 overflow-y-auto pr-1", children:
|
|
33691
|
-
const duration = range.end - range.start + 1;
|
|
33692
|
-
const startTime = formatIdleTimestamp(range.start);
|
|
33693
|
-
const endTime = formatIdleTimestamp(range.end + 1);
|
|
33694
|
-
const fallbackIndex = chartData.findIndex((item) => item.timeRange === data2.timeRange);
|
|
33695
|
-
Number.isFinite(data2.hourIndex) ? data2.hourIndex : fallbackIndex;
|
|
33856
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1 max-h-32 overflow-y-auto pr-1", children: idlePeriods.map((period, index) => {
|
|
33696
33857
|
return /* @__PURE__ */ jsxs("div", { className: "text-gray-600 flex items-center gap-2 text-xs", children: [
|
|
33697
33858
|
/* @__PURE__ */ jsx("span", { className: "inline-block w-1.5 h-1.5 bg-orange-400 rounded-full flex-shrink-0" }),
|
|
33698
|
-
/* @__PURE__ */ jsx("span", { children: duration === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33699
|
-
startTime,
|
|
33859
|
+
/* @__PURE__ */ jsx("span", { children: period.duration === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33860
|
+
period.startTime,
|
|
33700
33861
|
" (",
|
|
33701
|
-
duration,
|
|
33862
|
+
period.duration,
|
|
33702
33863
|
" min)"
|
|
33703
33864
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33704
|
-
startTime,
|
|
33865
|
+
period.startTime,
|
|
33705
33866
|
" - ",
|
|
33706
|
-
endTime,
|
|
33867
|
+
period.endTime,
|
|
33707
33868
|
" (",
|
|
33708
|
-
duration,
|
|
33869
|
+
period.duration,
|
|
33709
33870
|
" mins)"
|
|
33710
33871
|
] }) })
|
|
33711
33872
|
] }, index);
|
|
@@ -33804,7 +33965,7 @@ var HourlyOutputChartComponent = ({
|
|
|
33804
33965
|
}
|
|
33805
33966
|
);
|
|
33806
33967
|
};
|
|
33807
|
-
var HourlyOutputChart =
|
|
33968
|
+
var HourlyOutputChart = React142__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
|
|
33808
33969
|
if (prevProps.pphThreshold !== nextProps.pphThreshold || prevProps.shiftStart !== nextProps.shiftStart || prevProps.shiftEnd !== nextProps.shiftEnd || prevProps.shiftDate !== nextProps.shiftDate || prevProps.timezone !== nextProps.timezone || prevProps.showIdleTime !== nextProps.showIdleTime || prevProps.className !== nextProps.className) {
|
|
33809
33970
|
return false;
|
|
33810
33971
|
}
|
|
@@ -33860,9 +34021,8 @@ var HourlyOutputChart = React141__default.memo(HourlyOutputChartComponent, (prev
|
|
|
33860
34021
|
HourlyOutputChart.displayName = "HourlyOutputChart";
|
|
33861
34022
|
|
|
33862
34023
|
// src/components/dashboard/grid/videoGridMetricUtils.ts
|
|
33863
|
-
var VIDEO_GRID_LEGEND_LABEL = "7 Minute Efficiency";
|
|
33864
34024
|
var MAP_GRID_LEGEND_LABEL = "Efficiency";
|
|
33865
|
-
var MIXED_VIDEO_GRID_LEGEND_LABEL = "Efficiency";
|
|
34025
|
+
var MIXED_VIDEO_GRID_LEGEND_LABEL = "Flow Efficiency";
|
|
33866
34026
|
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
33867
34027
|
var isVideoGridRecentFlowEnabled = (workspace) => isRecentFlowVideoGridMetricMode(
|
|
33868
34028
|
workspace.video_grid_metric_mode,
|
|
@@ -33893,6 +34053,9 @@ var getVideoGridBaseColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND)
|
|
|
33893
34053
|
return getEfficiencyColor(metricValue, legend);
|
|
33894
34054
|
};
|
|
33895
34055
|
var isLowWipGreenOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
34056
|
+
if (workspace.scheduled_break_active === true) {
|
|
34057
|
+
return false;
|
|
34058
|
+
}
|
|
33896
34059
|
if (!hasVideoGridRecentFlow(workspace) || !isVideoGridWipGated(workspace)) {
|
|
33897
34060
|
return false;
|
|
33898
34061
|
}
|
|
@@ -33961,8 +34124,15 @@ var getVideoGridLegendLabel = (workspaces) => {
|
|
|
33961
34124
|
if (recentFlowEnabledCount === 0) {
|
|
33962
34125
|
return MAP_GRID_LEGEND_LABEL;
|
|
33963
34126
|
}
|
|
34127
|
+
const recentFlowWindows = new Set(
|
|
34128
|
+
visibleWorkspaces.filter(isVideoGridRecentFlowEnabled).map((workspace) => workspace.recent_flow_window_minutes ?? 7).filter((value) => typeof value === "number" && Number.isFinite(value))
|
|
34129
|
+
);
|
|
33964
34130
|
if (recentFlowEnabledCount === visibleWorkspaces.length) {
|
|
33965
|
-
|
|
34131
|
+
if (recentFlowWindows.size === 1) {
|
|
34132
|
+
const [windowMinutes] = Array.from(recentFlowWindows);
|
|
34133
|
+
return `${windowMinutes} Minute Efficiency`;
|
|
34134
|
+
}
|
|
34135
|
+
return MIXED_VIDEO_GRID_LEGEND_LABEL;
|
|
33966
34136
|
}
|
|
33967
34137
|
return MIXED_VIDEO_GRID_LEGEND_LABEL;
|
|
33968
34138
|
};
|
|
@@ -33975,7 +34145,7 @@ function getTrendArrowAndColor(trend) {
|
|
|
33975
34145
|
return { arrow: "\u2192", color: "text-gray-400" };
|
|
33976
34146
|
}
|
|
33977
34147
|
}
|
|
33978
|
-
var VideoCard =
|
|
34148
|
+
var VideoCard = React142__default.memo(({
|
|
33979
34149
|
workspace,
|
|
33980
34150
|
hlsUrl,
|
|
33981
34151
|
shouldPlay,
|
|
@@ -34137,7 +34307,7 @@ var VideoCard = React141__default.memo(({
|
|
|
34137
34307
|
}
|
|
34138
34308
|
);
|
|
34139
34309
|
}, (prevProps, nextProps) => {
|
|
34140
|
-
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
|
|
34310
|
+
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.scheduled_break_active !== nextProps.workspace.scheduled_break_active || 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) {
|
|
34141
34311
|
return false;
|
|
34142
34312
|
}
|
|
34143
34313
|
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) {
|
|
@@ -34173,7 +34343,7 @@ var logDebug2 = (...args) => {
|
|
|
34173
34343
|
if (!DEBUG_DASHBOARD_LOGS2) return;
|
|
34174
34344
|
console.log(...args);
|
|
34175
34345
|
};
|
|
34176
|
-
var VideoGridView =
|
|
34346
|
+
var VideoGridView = React142__default.memo(({
|
|
34177
34347
|
workspaces,
|
|
34178
34348
|
selectedLine,
|
|
34179
34349
|
className = "",
|
|
@@ -34545,7 +34715,7 @@ var VideoGridView = React141__default.memo(({
|
|
|
34545
34715
|
) }) });
|
|
34546
34716
|
});
|
|
34547
34717
|
VideoGridView.displayName = "VideoGridView";
|
|
34548
|
-
var MapGridView =
|
|
34718
|
+
var MapGridView = React142__default.memo(({
|
|
34549
34719
|
workspaces,
|
|
34550
34720
|
className = "",
|
|
34551
34721
|
displayNames = {},
|
|
@@ -35384,7 +35554,7 @@ var UptimeLineChartComponent = ({ points, className = "" }) => {
|
|
|
35384
35554
|
)
|
|
35385
35555
|
] }) }) });
|
|
35386
35556
|
};
|
|
35387
|
-
var UptimeLineChart =
|
|
35557
|
+
var UptimeLineChart = React142__default.memo(UptimeLineChartComponent);
|
|
35388
35558
|
var padTime = (value) => value.toString().padStart(2, "0");
|
|
35389
35559
|
var parseTime = (timeValue) => {
|
|
35390
35560
|
if (!timeValue) return null;
|
|
@@ -35624,10 +35794,10 @@ var HourlyUptimeChartComponent = ({
|
|
|
35624
35794
|
elapsedMinutes,
|
|
35625
35795
|
className = ""
|
|
35626
35796
|
}) => {
|
|
35627
|
-
const containerRef =
|
|
35628
|
-
const [containerReady, setContainerReady] =
|
|
35629
|
-
const [containerWidth, setContainerWidth] =
|
|
35630
|
-
const uptimeSeries =
|
|
35797
|
+
const containerRef = React142__default.useRef(null);
|
|
35798
|
+
const [containerReady, setContainerReady] = React142__default.useState(false);
|
|
35799
|
+
const [containerWidth, setContainerWidth] = React142__default.useState(0);
|
|
35800
|
+
const uptimeSeries = React142__default.useMemo(() => buildUptimeSeries({
|
|
35631
35801
|
idleTimeHourly,
|
|
35632
35802
|
shiftStart,
|
|
35633
35803
|
shiftEnd,
|
|
@@ -35636,11 +35806,11 @@ var HourlyUptimeChartComponent = ({
|
|
|
35636
35806
|
elapsedMinutes
|
|
35637
35807
|
}), [idleTimeHourly, shiftStart, shiftEnd, shiftDate, timezone, elapsedMinutes]);
|
|
35638
35808
|
const hasAggregateData = Boolean(hourlyAggregates && hourlyAggregates.length > 0);
|
|
35639
|
-
const shiftStartTime =
|
|
35809
|
+
const shiftStartTime = React142__default.useMemo(
|
|
35640
35810
|
() => getTimeFromTimeString(shiftStart),
|
|
35641
35811
|
[shiftStart]
|
|
35642
35812
|
);
|
|
35643
|
-
const { shiftDuration, shiftEndTime } =
|
|
35813
|
+
const { shiftDuration, shiftEndTime } = React142__default.useMemo(() => {
|
|
35644
35814
|
if (!shiftEnd) {
|
|
35645
35815
|
const fallbackHours = uptimeSeries.shiftMinutes > 0 ? Math.ceil(uptimeSeries.shiftMinutes / 60) : 0;
|
|
35646
35816
|
return { shiftDuration: fallbackHours, shiftEndTime: null };
|
|
@@ -35654,7 +35824,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
35654
35824
|
const hourCount = hasPartial ? Math.ceil(duration) : Math.round(duration);
|
|
35655
35825
|
return { shiftDuration: hourCount, shiftEndTime: endTime };
|
|
35656
35826
|
}, [shiftEnd, shiftStartTime.decimalHour, uptimeSeries.shiftMinutes]);
|
|
35657
|
-
const formatHour =
|
|
35827
|
+
const formatHour = React142__default.useCallback((hourIndex) => {
|
|
35658
35828
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
35659
35829
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
35660
35830
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -35679,7 +35849,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
35679
35849
|
};
|
|
35680
35850
|
return `${formatTime5(startHour, startMinute)}-${formatTime5(endHour, endMinute)}`;
|
|
35681
35851
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
35682
|
-
const formatTimeRange2 =
|
|
35852
|
+
const formatTimeRange2 = React142__default.useCallback((hourIndex) => {
|
|
35683
35853
|
const isLastHour = hourIndex === shiftDuration - 1;
|
|
35684
35854
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
35685
35855
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
@@ -35701,7 +35871,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
35701
35871
|
};
|
|
35702
35872
|
return `${formatTime5(startHour, startMinute)} - ${formatTime5(endHour, endMinute)}`;
|
|
35703
35873
|
}, [shiftDuration, shiftStartTime.decimalHour, shiftEndTime]);
|
|
35704
|
-
const chartData =
|
|
35874
|
+
const chartData = React142__default.useMemo(() => {
|
|
35705
35875
|
if (shiftDuration <= 0) return [];
|
|
35706
35876
|
if (hasAggregateData) {
|
|
35707
35877
|
return hourlyAggregates.map((entry, hourIndex) => ({
|
|
@@ -35743,7 +35913,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
35743
35913
|
}, [hasAggregateData, hourlyAggregates, uptimeSeries.points, uptimeSeries.elapsedMinutes, uptimeSeries.shiftMinutes, shiftDuration, formatHour, formatTimeRange2]);
|
|
35744
35914
|
const maxYValue = 100;
|
|
35745
35915
|
const yAxisTicks = [0, 25, 50, 75, 100];
|
|
35746
|
-
|
|
35916
|
+
React142__default.useEffect(() => {
|
|
35747
35917
|
const checkContainerDimensions = () => {
|
|
35748
35918
|
if (containerRef.current) {
|
|
35749
35919
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -35769,7 +35939,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
35769
35939
|
clearTimeout(fallbackTimeout);
|
|
35770
35940
|
};
|
|
35771
35941
|
}, []);
|
|
35772
|
-
const xAxisConfig =
|
|
35942
|
+
const xAxisConfig = React142__default.useMemo(() => {
|
|
35773
35943
|
if (containerWidth >= 960) {
|
|
35774
35944
|
return { interval: 0, angle: -45, height: 92, tickFont: 10, tickMargin: 12, labelMode: "full" };
|
|
35775
35945
|
}
|
|
@@ -35778,7 +35948,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
35778
35948
|
}
|
|
35779
35949
|
return { interval: 0, angle: -30, height: 64, tickFont: 9, tickMargin: 6, labelMode: "start" };
|
|
35780
35950
|
}, [containerWidth]);
|
|
35781
|
-
const formatXAxisTick =
|
|
35951
|
+
const formatXAxisTick = React142__default.useCallback((raw) => {
|
|
35782
35952
|
const label = typeof raw === "string" ? raw : String(raw);
|
|
35783
35953
|
if (xAxisConfig.labelMode === "full") return label;
|
|
35784
35954
|
const parts = label.split("-");
|
|
@@ -35909,7 +36079,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
35909
36079
|
idleRanges.push(currentRange);
|
|
35910
36080
|
}
|
|
35911
36081
|
}
|
|
35912
|
-
const
|
|
36082
|
+
const formatIdleTimestamp2 = (minuteIdx) => {
|
|
35913
36083
|
const totalMinutes = (shiftStartTime.hour + data.hourIndex) * 60 + shiftStartTime.minute + minuteIdx;
|
|
35914
36084
|
const hour = Math.floor(totalMinutes / 60) % 24;
|
|
35915
36085
|
const minute = totalMinutes % 60;
|
|
@@ -35939,8 +36109,8 @@ var HourlyUptimeChartComponent = ({
|
|
|
35939
36109
|
/* @__PURE__ */ jsx("p", { className: "font-medium text-gray-700 text-xs mb-2", children: "Idle periods:" }),
|
|
35940
36110
|
/* @__PURE__ */ jsx("div", { className: "space-y-1 max-h-32 overflow-y-auto pr-1", children: idleRanges.map((range, index) => {
|
|
35941
36111
|
const duration = range.end - range.start + 1;
|
|
35942
|
-
const startTime =
|
|
35943
|
-
const endTime =
|
|
36112
|
+
const startTime = formatIdleTimestamp2(range.start);
|
|
36113
|
+
const endTime = formatIdleTimestamp2(range.end + 1);
|
|
35944
36114
|
return /* @__PURE__ */ jsxs("div", { className: "text-gray-600 flex items-center gap-2 text-xs", children: [
|
|
35945
36115
|
/* @__PURE__ */ jsx("span", { className: "inline-block w-1.5 h-1.5 bg-orange-400 rounded-full flex-shrink-0" }),
|
|
35946
36116
|
/* @__PURE__ */ jsx("span", { children: duration === 1 ? `${startTime} (${duration} min)` : `${startTime} - ${endTime} (${duration} mins)` })
|
|
@@ -35984,7 +36154,7 @@ var HourlyUptimeChartComponent = ({
|
|
|
35984
36154
|
}
|
|
35985
36155
|
);
|
|
35986
36156
|
};
|
|
35987
|
-
var HourlyUptimeChart =
|
|
36157
|
+
var HourlyUptimeChart = React142__default.memo(HourlyUptimeChartComponent);
|
|
35988
36158
|
var DEFAULT_COLORS2 = ["#00AB45", "#ef4444"];
|
|
35989
36159
|
var UptimeDonutChartComponent = ({
|
|
35990
36160
|
data,
|
|
@@ -36054,7 +36224,7 @@ var UptimeDonutChartComponent = ({
|
|
|
36054
36224
|
] }) })
|
|
36055
36225
|
] }) });
|
|
36056
36226
|
};
|
|
36057
|
-
var UptimeDonutChart =
|
|
36227
|
+
var UptimeDonutChart = React142__default.memo(UptimeDonutChartComponent);
|
|
36058
36228
|
UptimeDonutChart.displayName = "UptimeDonutChart";
|
|
36059
36229
|
var TrendIcon = ({ trend }) => {
|
|
36060
36230
|
if (trend === "up") {
|
|
@@ -36173,7 +36343,7 @@ var EmptyStateMessage = ({
|
|
|
36173
36343
|
iconClassName
|
|
36174
36344
|
}) => {
|
|
36175
36345
|
let IconContent = null;
|
|
36176
|
-
if (
|
|
36346
|
+
if (React142__default.isValidElement(iconType)) {
|
|
36177
36347
|
IconContent = iconType;
|
|
36178
36348
|
} else if (typeof iconType === "string") {
|
|
36179
36349
|
const MappedIcon = IconMap[iconType];
|
|
@@ -36826,6 +36996,7 @@ var VideoControls = ({
|
|
|
36826
36996
|
return /* @__PURE__ */ jsxs(
|
|
36827
36997
|
"div",
|
|
36828
36998
|
{
|
|
36999
|
+
onClick: (e) => e.stopPropagation(),
|
|
36829
37000
|
className: `absolute bottom-0 left-0 right-0 px-3 pb-3 pt-12 bg-gradient-to-t from-black/80 via-black/40 to-transparent transition-opacity duration-300 ${controlsVisible ? "opacity-100" : "opacity-0 pointer-events-none"} ${className}`,
|
|
36830
37001
|
style: { touchAction: "none" },
|
|
36831
37002
|
children: [
|
|
@@ -37869,13 +38040,11 @@ var HlsVideoPlayer = forwardRef(({
|
|
|
37869
38040
|
player: playerLikeObject()
|
|
37870
38041
|
}), [play, pause, currentTimeProp, durationProp, paused, mute, volumeProp, playbackRateProp, dispose, isReady, playerLikeObject]);
|
|
37871
38042
|
const handleContainerClick = useCallback(() => {
|
|
37872
|
-
|
|
37873
|
-
handleTogglePlay();
|
|
37874
|
-
}
|
|
38043
|
+
handleTogglePlay();
|
|
37875
38044
|
if (onClick) {
|
|
37876
38045
|
onClick();
|
|
37877
38046
|
}
|
|
37878
|
-
}, [onClick,
|
|
38047
|
+
}, [onClick, handleTogglePlay]);
|
|
37879
38048
|
return /* @__PURE__ */ jsxs(
|
|
37880
38049
|
"div",
|
|
37881
38050
|
{
|
|
@@ -38300,9 +38469,7 @@ var CroppedHlsVideoPlayer = forwardRef(({
|
|
|
38300
38469
|
return /* @__PURE__ */ jsx(HlsVideoPlayer, { ref, ...videoProps, onClick, controls });
|
|
38301
38470
|
}
|
|
38302
38471
|
const handleClick = () => {
|
|
38303
|
-
|
|
38304
|
-
handleTogglePlay();
|
|
38305
|
-
}
|
|
38472
|
+
handleTogglePlay();
|
|
38306
38473
|
if (onClick) onClick();
|
|
38307
38474
|
};
|
|
38308
38475
|
return /* @__PURE__ */ jsxs(
|
|
@@ -38458,7 +38625,7 @@ function Skeleton({ className, ...props }) {
|
|
|
38458
38625
|
var Select = SelectPrimitive.Root;
|
|
38459
38626
|
var SelectGroup = SelectPrimitive.Group;
|
|
38460
38627
|
var SelectValue = SelectPrimitive.Value;
|
|
38461
|
-
var SelectTrigger =
|
|
38628
|
+
var SelectTrigger = React142.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
38462
38629
|
SelectPrimitive.Trigger,
|
|
38463
38630
|
{
|
|
38464
38631
|
ref,
|
|
@@ -38474,7 +38641,7 @@ var SelectTrigger = React141.forwardRef(({ className, children, ...props }, ref)
|
|
|
38474
38641
|
}
|
|
38475
38642
|
));
|
|
38476
38643
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
38477
|
-
var SelectScrollUpButton =
|
|
38644
|
+
var SelectScrollUpButton = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38478
38645
|
SelectPrimitive.ScrollUpButton,
|
|
38479
38646
|
{
|
|
38480
38647
|
ref,
|
|
@@ -38484,7 +38651,7 @@ var SelectScrollUpButton = React141.forwardRef(({ className, ...props }, ref) =>
|
|
|
38484
38651
|
}
|
|
38485
38652
|
));
|
|
38486
38653
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
38487
|
-
var SelectScrollDownButton =
|
|
38654
|
+
var SelectScrollDownButton = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38488
38655
|
SelectPrimitive.ScrollDownButton,
|
|
38489
38656
|
{
|
|
38490
38657
|
ref,
|
|
@@ -38494,7 +38661,7 @@ var SelectScrollDownButton = React141.forwardRef(({ className, ...props }, ref)
|
|
|
38494
38661
|
}
|
|
38495
38662
|
));
|
|
38496
38663
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
38497
|
-
var SelectContent =
|
|
38664
|
+
var SelectContent = React142.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
38498
38665
|
SelectPrimitive.Content,
|
|
38499
38666
|
{
|
|
38500
38667
|
ref,
|
|
@@ -38522,7 +38689,7 @@ var SelectContent = React141.forwardRef(({ className, children, position = "popp
|
|
|
38522
38689
|
}
|
|
38523
38690
|
) }));
|
|
38524
38691
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
38525
|
-
var SelectLabel =
|
|
38692
|
+
var SelectLabel = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38526
38693
|
SelectPrimitive.Label,
|
|
38527
38694
|
{
|
|
38528
38695
|
ref,
|
|
@@ -38531,7 +38698,7 @@ var SelectLabel = React141.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
38531
38698
|
}
|
|
38532
38699
|
));
|
|
38533
38700
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
38534
|
-
var SelectItem =
|
|
38701
|
+
var SelectItem = React142.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
38535
38702
|
SelectPrimitive.Item,
|
|
38536
38703
|
{
|
|
38537
38704
|
ref,
|
|
@@ -38547,7 +38714,7 @@ var SelectItem = React141.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
38547
38714
|
}
|
|
38548
38715
|
));
|
|
38549
38716
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
38550
|
-
var SelectSeparator =
|
|
38717
|
+
var SelectSeparator = React142.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
38551
38718
|
SelectPrimitive.Separator,
|
|
38552
38719
|
{
|
|
38553
38720
|
ref,
|
|
@@ -38846,7 +39013,7 @@ var TimePickerDropdown = ({
|
|
|
38846
39013
|
] })
|
|
38847
39014
|
] });
|
|
38848
39015
|
};
|
|
38849
|
-
var SilentErrorBoundary = class extends
|
|
39016
|
+
var SilentErrorBoundary = class extends React142__default.Component {
|
|
38850
39017
|
constructor(props) {
|
|
38851
39018
|
super(props);
|
|
38852
39019
|
this.handleClearAndReload = () => {
|
|
@@ -42805,17 +42972,6 @@ var BottlenecksContent = ({
|
|
|
42805
42972
|
window.addEventListener("keydown", handleKeyDown);
|
|
42806
42973
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
42807
42974
|
}, [handlePrevious, handleNext]);
|
|
42808
|
-
const togglePlayback = () => {
|
|
42809
|
-
const player = videoRef.current?.player;
|
|
42810
|
-
if (!player) return;
|
|
42811
|
-
if (player.paused()) {
|
|
42812
|
-
player.play()?.catch((err) => {
|
|
42813
|
-
console.error("Error playing video:", err);
|
|
42814
|
-
});
|
|
42815
|
-
} else {
|
|
42816
|
-
player.pause();
|
|
42817
|
-
}
|
|
42818
|
-
};
|
|
42819
42975
|
const handlePlaybackSpeedChange = useCallback((speed) => {
|
|
42820
42976
|
setPlaybackSpeed(speed);
|
|
42821
42977
|
if (videoRef.current?.playbackRate) {
|
|
@@ -42985,7 +43141,6 @@ var BottlenecksContent = ({
|
|
|
42985
43141
|
poster: "",
|
|
42986
43142
|
className: "w-full h-full",
|
|
42987
43143
|
crop: workspaceCrop?.crop,
|
|
42988
|
-
onClick: togglePlayback,
|
|
42989
43144
|
autoplay: true,
|
|
42990
43145
|
playsInline: true,
|
|
42991
43146
|
loop: false,
|
|
@@ -43410,7 +43565,6 @@ var BottlenecksContent = ({
|
|
|
43410
43565
|
poster: "",
|
|
43411
43566
|
className: "w-full h-full",
|
|
43412
43567
|
crop: workspaceCrop?.crop,
|
|
43413
|
-
onClick: togglePlayback,
|
|
43414
43568
|
autoplay: true,
|
|
43415
43569
|
playsInline: true,
|
|
43416
43570
|
loop: false,
|
|
@@ -43929,7 +44083,7 @@ function DiagnosisVideoModal({
|
|
|
43929
44083
|
src: playlistUrl,
|
|
43930
44084
|
className: "w-full h-full",
|
|
43931
44085
|
crop: null,
|
|
43932
|
-
|
|
44086
|
+
controls: false,
|
|
43933
44087
|
autoplay: false,
|
|
43934
44088
|
playsInline: true,
|
|
43935
44089
|
loop: false,
|
|
@@ -45448,8 +45602,8 @@ var IdleTimeReasonChartComponent = ({
|
|
|
45448
45602
|
updateAnimation = "replay",
|
|
45449
45603
|
variant = "pie"
|
|
45450
45604
|
}) => {
|
|
45451
|
-
const [activeData, setActiveData] =
|
|
45452
|
-
|
|
45605
|
+
const [activeData, setActiveData] = React142__default.useState([]);
|
|
45606
|
+
React142__default.useEffect(() => {
|
|
45453
45607
|
if (updateAnimation === "smooth") {
|
|
45454
45608
|
setActiveData(data && data.length > 0 ? data : []);
|
|
45455
45609
|
return;
|
|
@@ -45468,7 +45622,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
45468
45622
|
setActiveData([]);
|
|
45469
45623
|
}
|
|
45470
45624
|
}, [data, updateAnimation]);
|
|
45471
|
-
|
|
45625
|
+
React142__default.useEffect(() => {
|
|
45472
45626
|
if (!data || data.length === 0) return;
|
|
45473
45627
|
data.forEach((entry, index) => {
|
|
45474
45628
|
if (entry.name.toLowerCase().includes("other")) {
|
|
@@ -45476,7 +45630,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
45476
45630
|
}
|
|
45477
45631
|
});
|
|
45478
45632
|
}, [data]);
|
|
45479
|
-
const pieKey =
|
|
45633
|
+
const pieKey = React142__default.useMemo(() => {
|
|
45480
45634
|
if (updateAnimation === "smooth") {
|
|
45481
45635
|
return "smooth";
|
|
45482
45636
|
}
|
|
@@ -45646,7 +45800,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
45646
45800
|
)
|
|
45647
45801
|
] });
|
|
45648
45802
|
};
|
|
45649
|
-
var IdleTimeReasonChart =
|
|
45803
|
+
var IdleTimeReasonChart = React142__default.memo(IdleTimeReasonChartComponent);
|
|
45650
45804
|
IdleTimeReasonChart.displayName = "IdleTimeReasonChart";
|
|
45651
45805
|
var IdleTimeReasonChart_default = IdleTimeReasonChart;
|
|
45652
45806
|
var DEFAULT_PERFORMANCE_DATA = {
|
|
@@ -46921,10 +47075,17 @@ Underperforming Workspaces: ${lineInfo.metrics.underperforming_workspaces} / ${l
|
|
|
46921
47075
|
var LinePdfGenerator = ({
|
|
46922
47076
|
lineInfo,
|
|
46923
47077
|
workspaceData,
|
|
47078
|
+
issueResolutionSummary,
|
|
46924
47079
|
shiftName,
|
|
46925
47080
|
className
|
|
46926
47081
|
}) => {
|
|
46927
47082
|
const [isGenerating, setIsGenerating] = useState(false);
|
|
47083
|
+
const formatResolutionDuration2 = (seconds) => {
|
|
47084
|
+
if (seconds === null || seconds === void 0 || seconds <= 0) {
|
|
47085
|
+
return "-";
|
|
47086
|
+
}
|
|
47087
|
+
return formatIdleTime(Math.max(0, Math.floor(seconds)));
|
|
47088
|
+
};
|
|
46928
47089
|
const generatePDF = async () => {
|
|
46929
47090
|
setIsGenerating(true);
|
|
46930
47091
|
try {
|
|
@@ -47264,9 +47425,11 @@ var LinePdfGenerator = ({
|
|
|
47264
47425
|
doc.text(`${lineInfo.metrics.current_output} / ${lineInfo.metrics.line_threshold}`, 120, kpiStartY);
|
|
47265
47426
|
createKPIBox(kpiStartY + kpiSpacing);
|
|
47266
47427
|
doc.setFont("helvetica", "normal");
|
|
47267
|
-
doc.text("
|
|
47428
|
+
doc.text("Average Issue Resolution Time:", 25, kpiStartY + kpiSpacing);
|
|
47268
47429
|
doc.setFont("helvetica", "bold");
|
|
47269
|
-
|
|
47430
|
+
const resolutionSeconds = issueResolutionSummary ? issueResolutionSummary.mean_resolution_seconds ?? issueResolutionSummary.median_resolution_seconds : null;
|
|
47431
|
+
const displayValue = resolutionSeconds !== null ? formatResolutionDuration2(resolutionSeconds) : "-";
|
|
47432
|
+
doc.text(displayValue, 120, kpiStartY + kpiSpacing);
|
|
47270
47433
|
createKPIBox(kpiStartY + kpiSpacing * 2);
|
|
47271
47434
|
doc.setFont("helvetica", "normal");
|
|
47272
47435
|
doc.text("Average Efficiency:", 25, kpiStartY + kpiSpacing * 2);
|
|
@@ -50004,7 +50167,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
50004
50167
|
return prevProps.data.efficiency === nextProps.data.efficiency && prevProps.data.trend_score === nextProps.data.trend_score && prevProps.data.workspace_id === nextProps.data.workspace_id && prevProps.data.workspace_name === nextProps.data.workspace_name && prevProps.isBottleneck === nextProps.isBottleneck && prevProps.isLowEfficiency === nextProps.isLowEfficiency && prevProps.isVeryLowEfficiency === nextProps.isVeryLowEfficiency && prevLegend.green_min === nextLegend.green_min && prevLegend.green_max === nextLegend.green_max && prevLegend.yellow_min === nextLegend.yellow_min && prevLegend.yellow_max === nextLegend.yellow_max && prevLegend.red_min === nextLegend.red_min && prevLegend.red_max === nextLegend.red_max && prevLegend.critical_threshold === nextLegend.critical_threshold && // Position doesn't need deep equality check as it's generally static
|
|
50005
50168
|
prevProps.position.id === nextProps.position.id;
|
|
50006
50169
|
};
|
|
50007
|
-
var WorkspaceGridItem =
|
|
50170
|
+
var WorkspaceGridItem = React142__default.memo(({
|
|
50008
50171
|
data,
|
|
50009
50172
|
position,
|
|
50010
50173
|
isBottleneck = false,
|
|
@@ -50099,7 +50262,7 @@ var WorkspaceGridItem = React141__default.memo(({
|
|
|
50099
50262
|
);
|
|
50100
50263
|
}, arePropsEqual);
|
|
50101
50264
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
50102
|
-
var WorkspaceGrid =
|
|
50265
|
+
var WorkspaceGrid = React142__default.memo(({
|
|
50103
50266
|
workspaces,
|
|
50104
50267
|
isPdfMode = false,
|
|
50105
50268
|
customWorkspacePositions,
|
|
@@ -50358,7 +50521,7 @@ var KPICard = ({
|
|
|
50358
50521
|
}) => {
|
|
50359
50522
|
useThemeConfig();
|
|
50360
50523
|
const { formatNumber } = useFormatNumber();
|
|
50361
|
-
const trendInfo =
|
|
50524
|
+
const trendInfo = React142__default.useMemo(() => {
|
|
50362
50525
|
let trendValue = trend || "neutral";
|
|
50363
50526
|
if (change !== void 0 && trend === void 0) {
|
|
50364
50527
|
trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
|
|
@@ -50385,7 +50548,7 @@ var KPICard = ({
|
|
|
50385
50548
|
const shouldShowTrend = !(change === 0 && trend === void 0);
|
|
50386
50549
|
return { trendValue, Icon: Icon2, colorClass, bgClass, shouldShowTrend };
|
|
50387
50550
|
}, [trend, change]);
|
|
50388
|
-
const formattedValue =
|
|
50551
|
+
const formattedValue = React142__default.useMemo(() => {
|
|
50389
50552
|
if (title === "Quality Compliance" && typeof value === "number") {
|
|
50390
50553
|
return value.toFixed(1);
|
|
50391
50554
|
}
|
|
@@ -50399,7 +50562,7 @@ var KPICard = ({
|
|
|
50399
50562
|
}
|
|
50400
50563
|
return value;
|
|
50401
50564
|
}, [value, title]);
|
|
50402
|
-
const formattedChange =
|
|
50565
|
+
const formattedChange = React142__default.useMemo(() => {
|
|
50403
50566
|
if (change === void 0 || change === 0 && !showZeroChange) return null;
|
|
50404
50567
|
const absChange = Math.abs(change);
|
|
50405
50568
|
return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
|
|
@@ -50773,6 +50936,7 @@ var WorkspaceHealthCard = ({
|
|
|
50773
50936
|
className = "",
|
|
50774
50937
|
onViewDetails
|
|
50775
50938
|
}) => {
|
|
50939
|
+
const [copiedIp, setCopiedIp] = useState(false);
|
|
50776
50940
|
const getStatusConfig = () => {
|
|
50777
50941
|
switch (workspace.status) {
|
|
50778
50942
|
case "healthy":
|
|
@@ -50947,6 +51111,34 @@ var WorkspaceHealthCard = ({
|
|
|
50947
51111
|
/* @__PURE__ */ jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
|
|
50948
51112
|
] })
|
|
50949
51113
|
] }),
|
|
51114
|
+
workspace.cameraIp ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-2 mt-1.5 -mx-2 rounded-md bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800/60 group/ip transition-colors hover:bg-slate-100/50 dark:hover:bg-slate-800/50", children: [
|
|
51115
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
51116
|
+
/* @__PURE__ */ jsx(Video, { className: "h-3.5 w-3.5 text-slate-400" }),
|
|
51117
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium uppercase tracking-wide text-slate-500", children: "Camera IP" })
|
|
51118
|
+
] }),
|
|
51119
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
51120
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-slate-700 dark:text-slate-300 select-all", children: workspace.cameraIp }),
|
|
51121
|
+
/* @__PURE__ */ jsx(
|
|
51122
|
+
"button",
|
|
51123
|
+
{
|
|
51124
|
+
onClick: (e) => {
|
|
51125
|
+
e.stopPropagation();
|
|
51126
|
+
e.preventDefault();
|
|
51127
|
+
navigator.clipboard.writeText(workspace.cameraIp);
|
|
51128
|
+
setCopiedIp(true);
|
|
51129
|
+
setTimeout(() => setCopiedIp(false), 2e3);
|
|
51130
|
+
},
|
|
51131
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-600 hover:bg-slate-200 dark:hover:bg-slate-700 dark:hover:text-slate-300 transition-all opacity-0 group-hover/ip:opacity-100 focus:opacity-100",
|
|
51132
|
+
title: "Copy IP address",
|
|
51133
|
+
"aria-label": "Copy IP address",
|
|
51134
|
+
children: copiedIp ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-emerald-500" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" })
|
|
51135
|
+
}
|
|
51136
|
+
)
|
|
51137
|
+
] })
|
|
51138
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 min-h-[1rem]", children: [
|
|
51139
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium uppercase tracking-wide text-slate-500", children: "Camera IP:" }),
|
|
51140
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: "N/A" })
|
|
51141
|
+
] }),
|
|
50950
51142
|
/* @__PURE__ */ jsx("div", { className: "mt-3 pt-3 border-t border-slate-100 dark:border-slate-800", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
50951
51143
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-slate-500 uppercase tracking-wide", children: downtimeConfig.label }),
|
|
50952
51144
|
/* @__PURE__ */ jsx("span", { className: clsx("text-sm font-semibold", downtimeConfig.className), children: downtimeConfig.text })
|
|
@@ -51877,7 +52069,7 @@ var Breadcrumbs = ({ items }) => {
|
|
|
51877
52069
|
}
|
|
51878
52070
|
}
|
|
51879
52071
|
};
|
|
51880
|
-
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
52072
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(React142__default.Fragment, { children: [
|
|
51881
52073
|
index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
|
|
51882
52074
|
/* @__PURE__ */ jsxs(
|
|
51883
52075
|
"span",
|
|
@@ -52438,7 +52630,11 @@ var SideNavBar = memo$1(({
|
|
|
52438
52630
|
dashboardConfig?.supervisorConfig?.enabled || false;
|
|
52439
52631
|
const showSupervisorManagement = false;
|
|
52440
52632
|
const ticketsEnabled = dashboardConfig?.ticketsConfig?.enabled ?? true;
|
|
52441
|
-
const
|
|
52633
|
+
const canViewBillingByRole = canRoleViewClipsCost(role);
|
|
52634
|
+
const { hasVlmEnabledLine } = useCompanyHasVlmEnabledLine({
|
|
52635
|
+
enabled: canViewBillingByRole
|
|
52636
|
+
});
|
|
52637
|
+
const showBillingLink = canViewBillingByRole && hasVlmEnabledLine;
|
|
52442
52638
|
console.log("\u{1F50D} [SideNavBar] dashboardConfig:", dashboardConfig);
|
|
52443
52639
|
console.log("\u{1F50D} [SideNavBar] ticketsConfig:", dashboardConfig?.ticketsConfig);
|
|
52444
52640
|
console.log("\u{1F50D} [SideNavBar] ticketsEnabled:", ticketsEnabled);
|
|
@@ -52637,7 +52833,6 @@ var SideNavBar = memo$1(({
|
|
|
52637
52833
|
return prev;
|
|
52638
52834
|
});
|
|
52639
52835
|
}, [alertsCount, isAlertsOpen]);
|
|
52640
|
-
const unreadCount = alertsCount !== null ? Math.max(0, alertsCount - lastViewedCount) : 0;
|
|
52641
52836
|
const alertsTriggerRef = useRef(null);
|
|
52642
52837
|
const alertsCompanyId = entityConfig.companyId || user?.company_id;
|
|
52643
52838
|
const showAlertsButton = (role === "supervisor" || role === "optifye") && !!alertsCompanyId && !!supabase;
|
|
@@ -52777,7 +52972,7 @@ var SideNavBar = memo$1(({
|
|
|
52777
52972
|
${isActive ? "bg-blue-50/80 text-blue-600 font-medium" : "hover:bg-gray-50 text-gray-500 hover:text-gray-700 font-medium active:bg-gray-100"}
|
|
52778
52973
|
transition-all duration-200 ease-out focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2`;
|
|
52779
52974
|
}, [isSettingsOpen, settingsItems]);
|
|
52780
|
-
|
|
52975
|
+
useMemo(() => {
|
|
52781
52976
|
const isActive = isAlertsOpen;
|
|
52782
52977
|
return `w-full flex flex-col items-center justify-center py-4 sm:py-3 px-2 sm:px-1 rounded-lg relative group min-h-[44px] sm:min-h-0
|
|
52783
52978
|
${isActive ? "bg-blue-50/80 text-blue-600 font-medium" : "hover:bg-gray-50 text-gray-500 hover:text-gray-700 font-medium active:bg-gray-100"}
|
|
@@ -52905,54 +53100,25 @@ var SideNavBar = memo$1(({
|
|
|
52905
53100
|
)
|
|
52906
53101
|
] })
|
|
52907
53102
|
] }),
|
|
52908
|
-
/* @__PURE__ */
|
|
52909
|
-
|
|
52910
|
-
|
|
52911
|
-
|
|
52912
|
-
|
|
52913
|
-
|
|
52914
|
-
|
|
52915
|
-
|
|
52916
|
-
|
|
52917
|
-
|
|
52918
|
-
|
|
52919
|
-
|
|
52920
|
-
|
|
52921
|
-
|
|
52922
|
-
className:
|
|
52923
|
-
"
|
|
52924
|
-
|
|
52925
|
-
|
|
52926
|
-
|
|
52927
|
-
children: [
|
|
52928
|
-
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
52929
|
-
/* @__PURE__ */ jsx(BellIcon, { className: "w-5 h-5 mb-1" }),
|
|
52930
|
-
unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1.5 -right-1.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-red-500 px-1 text-[9px] font-bold text-white shadow-sm ring-2 ring-white", children: unreadCount > 99 ? "99+" : unreadCount })
|
|
52931
|
-
] }),
|
|
52932
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight mt-1", children: "Alerts" })
|
|
52933
|
-
]
|
|
52934
|
-
}
|
|
52935
|
-
),
|
|
52936
|
-
settingsItems.length > 0 && /* @__PURE__ */ jsxs(
|
|
52937
|
-
"button",
|
|
52938
|
-
{
|
|
52939
|
-
ref: settingsTriggerRef,
|
|
52940
|
-
onClick: () => {
|
|
52941
|
-
setIsSettingsOpen(!isSettingsOpen);
|
|
52942
|
-
setIsAlertsOpen(false);
|
|
52943
|
-
},
|
|
52944
|
-
className: settingsButtonClasses,
|
|
52945
|
-
"aria-label": "Settings",
|
|
52946
|
-
tabIndex: 0,
|
|
52947
|
-
role: "tab",
|
|
52948
|
-
"aria-selected": isSettingsOpen || settingsItems.some((item) => item.isActive),
|
|
52949
|
-
children: [
|
|
52950
|
-
/* @__PURE__ */ jsx(Cog6ToothIcon, { className: "w-5 h-5 mb-1" }),
|
|
52951
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Settings" })
|
|
52952
|
-
]
|
|
52953
|
-
}
|
|
52954
|
-
)
|
|
52955
|
-
] })
|
|
53103
|
+
/* @__PURE__ */ jsx("div", { className: "w-full py-4 px-4 border-t border-gray-100 flex-shrink-0 flex flex-col gap-2", children: settingsItems.length > 0 && /* @__PURE__ */ jsxs(
|
|
53104
|
+
"button",
|
|
53105
|
+
{
|
|
53106
|
+
ref: settingsTriggerRef,
|
|
53107
|
+
onClick: () => {
|
|
53108
|
+
setIsSettingsOpen(!isSettingsOpen);
|
|
53109
|
+
setIsAlertsOpen(false);
|
|
53110
|
+
},
|
|
53111
|
+
className: settingsButtonClasses,
|
|
53112
|
+
"aria-label": "Settings",
|
|
53113
|
+
tabIndex: 0,
|
|
53114
|
+
role: "tab",
|
|
53115
|
+
"aria-selected": isSettingsOpen || settingsItems.some((item) => item.isActive),
|
|
53116
|
+
children: [
|
|
53117
|
+
/* @__PURE__ */ jsx(Cog6ToothIcon, { className: "w-5 h-5 mb-1" }),
|
|
53118
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Settings" })
|
|
53119
|
+
]
|
|
53120
|
+
}
|
|
53121
|
+
) })
|
|
52956
53122
|
] });
|
|
52957
53123
|
const MobileNavigationContent = () => {
|
|
52958
53124
|
const isActive = (path) => {
|
|
@@ -53065,26 +53231,6 @@ var SideNavBar = memo$1(({
|
|
|
53065
53231
|
/* @__PURE__ */ jsxs("div", { className: "mt-8 pt-6 border-t border-gray-100", children: [
|
|
53066
53232
|
/* @__PURE__ */ jsx("h3", { className: "px-5 mb-3 text-[10px] font-bold text-gray-400 uppercase tracking-widest", children: "Settings & Support" }),
|
|
53067
53233
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
53068
|
-
showAlertsButton && /* @__PURE__ */ jsxs(
|
|
53069
|
-
"button",
|
|
53070
|
-
{
|
|
53071
|
-
onClick: () => {
|
|
53072
|
-
setIsAlertsOpen(true);
|
|
53073
|
-
trackCoreEvent("Alerts page clicked", { source: "side_nav_mobile" });
|
|
53074
|
-
void refreshAlertsSummary();
|
|
53075
|
-
onMobileMenuClose?.();
|
|
53076
|
-
},
|
|
53077
|
-
className: getMobileButtonClass("/alerts"),
|
|
53078
|
-
"aria-label": "Alerts",
|
|
53079
|
-
children: [
|
|
53080
|
-
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
53081
|
-
/* @__PURE__ */ jsx(BellIcon, { className: getIconClass("/alerts") }),
|
|
53082
|
-
unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1.5 -right-1.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-red-500 px-1 text-[9px] font-bold text-white shadow-sm ring-2 ring-white", children: unreadCount > 99 ? "99+" : unreadCount })
|
|
53083
|
-
] }),
|
|
53084
|
-
/* @__PURE__ */ jsx("span", { className: "text-base font-medium ml-3", children: "Alerts" })
|
|
53085
|
-
]
|
|
53086
|
-
}
|
|
53087
|
-
),
|
|
53088
53234
|
canAccessPath("/targets") && /* @__PURE__ */ jsxs(
|
|
53089
53235
|
"button",
|
|
53090
53236
|
{
|
|
@@ -53399,7 +53545,7 @@ var AwardBadge = ({
|
|
|
53399
53545
|
}) => {
|
|
53400
53546
|
const styles2 = getBadgeStyles(type);
|
|
53401
53547
|
const Icon2 = CustomIcon || getDefaultIcon(type);
|
|
53402
|
-
const randomDelay =
|
|
53548
|
+
const randomDelay = React142__default.useMemo(() => Math.random() * 2, []);
|
|
53403
53549
|
const floatingAnimation = {
|
|
53404
53550
|
animate: {
|
|
53405
53551
|
y: [0, -10, 0],
|
|
@@ -59314,6 +59460,17 @@ function HomeView({
|
|
|
59314
59460
|
}
|
|
59315
59461
|
return allActiveBreaks.filter((breakItem) => breakItem.lineId === selectedLineId);
|
|
59316
59462
|
}, [allActiveBreaks, selectedLineId, factoryViewId]);
|
|
59463
|
+
const activeBreakLineIds = useMemo(
|
|
59464
|
+
() => new Set(activeBreaks.map((breakItem) => breakItem.lineId)),
|
|
59465
|
+
[activeBreaks]
|
|
59466
|
+
);
|
|
59467
|
+
const workspaceMetricsWithBreakState = useMemo(
|
|
59468
|
+
() => workspaceMetrics.map((workspace) => ({
|
|
59469
|
+
...workspace,
|
|
59470
|
+
scheduled_break_active: activeBreakLineIds.has(workspace.line_id)
|
|
59471
|
+
})),
|
|
59472
|
+
[workspaceMetrics, activeBreakLineIds]
|
|
59473
|
+
);
|
|
59317
59474
|
const [breakNotificationsDismissed, setBreakNotificationsDismissed] = useState(false);
|
|
59318
59475
|
useEffect(() => {
|
|
59319
59476
|
if (activeBreaks.length > 0) {
|
|
@@ -59788,15 +59945,15 @@ function HomeView({
|
|
|
59788
59945
|
) }) }),
|
|
59789
59946
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative", children: [
|
|
59790
59947
|
/* @__PURE__ */ jsx("div", { className: "absolute right-2 top-1 sm:right-6 sm:top-3 z-30 flex items-center space-x-2", children: lineSelectorComponent && lineSelectorComponent }),
|
|
59791
|
-
/* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-100px)] sm:min-h-0", children:
|
|
59948
|
+
/* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-100px)] sm:min-h-0", children: workspaceMetricsWithBreakState.length > 0 ? /* @__PURE__ */ jsx(
|
|
59792
59949
|
motion.div,
|
|
59793
59950
|
{
|
|
59794
59951
|
initial: { opacity: 0, scale: 0.98 },
|
|
59795
59952
|
animate: { opacity: 1, scale: 1 },
|
|
59796
59953
|
transition: { duration: 0.3 },
|
|
59797
59954
|
className: "h-full",
|
|
59798
|
-
children:
|
|
59799
|
-
workspaces:
|
|
59955
|
+
children: React142__default.createElement(WorkspaceGrid, {
|
|
59956
|
+
workspaces: workspaceMetricsWithBreakState,
|
|
59800
59957
|
lineNames,
|
|
59801
59958
|
factoryView: factoryViewId,
|
|
59802
59959
|
legend: efficiencyLegend,
|
|
@@ -59826,7 +59983,7 @@ function HomeView({
|
|
|
59826
59983
|
animate: { opacity: 1, scale: 1 },
|
|
59827
59984
|
transition: { duration: 0.3 },
|
|
59828
59985
|
className: "h-full",
|
|
59829
|
-
children:
|
|
59986
|
+
children: React142__default.createElement(WorkspaceGrid, {
|
|
59830
59987
|
workspaces: [],
|
|
59831
59988
|
// Show empty grid while loading
|
|
59832
59989
|
lineNames,
|
|
@@ -59893,7 +60050,7 @@ function HomeView({
|
|
|
59893
60050
|
}
|
|
59894
60051
|
);
|
|
59895
60052
|
}
|
|
59896
|
-
var AuthenticatedHomeView = withAuth(
|
|
60053
|
+
var AuthenticatedHomeView = withAuth(React142__default.memo(HomeView));
|
|
59897
60054
|
var HomeView_default = HomeView;
|
|
59898
60055
|
function withWorkspaceDisplayNames(Component3, options = {}) {
|
|
59899
60056
|
const {
|
|
@@ -60076,6 +60233,295 @@ var lineDetailStore = {
|
|
|
60076
60233
|
}
|
|
60077
60234
|
};
|
|
60078
60235
|
|
|
60236
|
+
// src/lib/hooks/useLineDetailPageData.ts
|
|
60237
|
+
var buildLineInfoSnapshot = (lineDetails, metrics2) => {
|
|
60238
|
+
if (!lineDetails || !metrics2) {
|
|
60239
|
+
return null;
|
|
60240
|
+
}
|
|
60241
|
+
return {
|
|
60242
|
+
line_id: lineDetails.id,
|
|
60243
|
+
line_name: lineDetails.line_name,
|
|
60244
|
+
company_id: "",
|
|
60245
|
+
company_name: "",
|
|
60246
|
+
factory_id: lineDetails.factory_id,
|
|
60247
|
+
factory_name: lineDetails.factory.factory_name,
|
|
60248
|
+
shift_id: metrics2.shift_id ?? 0,
|
|
60249
|
+
date: metrics2.date || "",
|
|
60250
|
+
monitoring_mode: lineDetails.monitoring_mode ?? void 0,
|
|
60251
|
+
metrics: {
|
|
60252
|
+
avg_efficiency: metrics2.avg_efficiency ?? 0,
|
|
60253
|
+
avg_cycle_time: metrics2.avg_cycle_time ?? 0,
|
|
60254
|
+
current_output: metrics2.current_output ?? 0,
|
|
60255
|
+
ideal_output: metrics2.ideal_output ?? 0,
|
|
60256
|
+
total_workspaces: metrics2.total_workspaces ?? 0,
|
|
60257
|
+
underperforming_workspaces: metrics2.underperforming_workspaces ?? 0,
|
|
60258
|
+
underperforming_workspace_names: metrics2.underperforming_workspace_names || [],
|
|
60259
|
+
underperforming_workspace_uuids: metrics2.underperforming_workspace_uuids || [],
|
|
60260
|
+
output_array: metrics2.output_array || [],
|
|
60261
|
+
output_hourly: metrics2.output_hourly,
|
|
60262
|
+
line_threshold: metrics2.line_threshold ?? 0,
|
|
60263
|
+
threshold_pph: metrics2.threshold_pph ?? 0,
|
|
60264
|
+
shift_start: metrics2.shift_start || "06:00",
|
|
60265
|
+
shift_end: metrics2.shift_end || "14:00",
|
|
60266
|
+
last_updated: metrics2.last_updated || (/* @__PURE__ */ new Date()).toISOString(),
|
|
60267
|
+
poorest_performing_workspaces: metrics2.poorest_performing_workspaces || [],
|
|
60268
|
+
idle_time_hourly: metrics2.idle_time_hourly || null
|
|
60269
|
+
}
|
|
60270
|
+
};
|
|
60271
|
+
};
|
|
60272
|
+
var transformWorkspaceMetrics = (workspaceData, lineId, companyId, queryDate, queryShiftId) => (workspaceData || []).map((item) => ({
|
|
60273
|
+
company_id: item.company_id || companyId,
|
|
60274
|
+
line_id: item.line_id || lineId,
|
|
60275
|
+
shift_id: item.shift_id ?? queryShiftId,
|
|
60276
|
+
date: item.date || queryDate,
|
|
60277
|
+
workspace_uuid: item.workspace_id,
|
|
60278
|
+
workspace_name: item.workspace_name,
|
|
60279
|
+
action_count: item.total_output || 0,
|
|
60280
|
+
pph: item.avg_pph || 0,
|
|
60281
|
+
performance_score: item.performance_score || 0,
|
|
60282
|
+
avg_cycle_time: item.avg_cycle_time || 0,
|
|
60283
|
+
trend: item.trend_score === 1 ? 2 : 0,
|
|
60284
|
+
predicted_output: item.ideal_output || 0,
|
|
60285
|
+
efficiency: item.efficiency || 0,
|
|
60286
|
+
action_threshold: item.total_day_output || 0,
|
|
60287
|
+
idle_time: item.idle_time ?? void 0,
|
|
60288
|
+
idle_time_hourly: item.idle_time_hourly || null,
|
|
60289
|
+
shift_start: item.shift_start || void 0,
|
|
60290
|
+
shift_end: item.shift_end || void 0,
|
|
60291
|
+
monitoring_mode: item.monitoring_mode ?? void 0,
|
|
60292
|
+
assembly_enabled: item.assembly_enabled ?? false,
|
|
60293
|
+
video_grid_metric_mode: item.video_grid_metric_mode ?? void 0,
|
|
60294
|
+
action_type: item.action_type ?? void 0,
|
|
60295
|
+
action_family: item.action_family ?? void 0,
|
|
60296
|
+
action_display_name: item.action_display_name ?? void 0,
|
|
60297
|
+
recent_flow_percent: item.recent_flow_percent ?? null,
|
|
60298
|
+
recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
|
|
60299
|
+
recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
|
|
60300
|
+
recent_flow_computed_at: item.recent_flow_computed_at ?? null,
|
|
60301
|
+
incoming_wip_current: item.incoming_wip_current ?? null,
|
|
60302
|
+
incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
|
|
60303
|
+
incoming_wip_buffer_name: item.incoming_wip_buffer_name ?? null,
|
|
60304
|
+
show_exclamation: item.show_exclamation ?? void 0
|
|
60305
|
+
})).sort((a, b) => a.workspace_name.localeCompare(b.workspace_name));
|
|
60306
|
+
var transformLineDetails = (lineId, detailResponse) => {
|
|
60307
|
+
if (!detailResponse.line_details) {
|
|
60308
|
+
return null;
|
|
60309
|
+
}
|
|
60310
|
+
return {
|
|
60311
|
+
id: lineId,
|
|
60312
|
+
line_name: detailResponse.line_details.line_name || "Line",
|
|
60313
|
+
factory_id: detailResponse.line_details.factory_id || "",
|
|
60314
|
+
factory: {
|
|
60315
|
+
id: detailResponse.line_details.factory_id || "",
|
|
60316
|
+
factory_name: detailResponse.line_details.factory_name || ""
|
|
60317
|
+
},
|
|
60318
|
+
monitoring_mode: detailResponse.line_details.monitoring_mode ?? void 0
|
|
60319
|
+
};
|
|
60320
|
+
};
|
|
60321
|
+
var transformLineMetrics = (lineId, detailResponse, queryDate, queryShiftId) => {
|
|
60322
|
+
const poorestPerformingWorkspaces = detailResponse.poorest_performing_workspaces || [];
|
|
60323
|
+
const baseMetrics = detailResponse.line_metrics;
|
|
60324
|
+
if (!baseMetrics) {
|
|
60325
|
+
return {
|
|
60326
|
+
line_id: lineId,
|
|
60327
|
+
shift_id: queryShiftId,
|
|
60328
|
+
date: queryDate,
|
|
60329
|
+
factory_id: detailResponse.line_details?.factory_id || "",
|
|
60330
|
+
avg_efficiency: 0,
|
|
60331
|
+
avg_cycle_time: 0,
|
|
60332
|
+
current_output: 0,
|
|
60333
|
+
ideal_output: 0,
|
|
60334
|
+
total_workspaces: 0,
|
|
60335
|
+
underperforming_workspaces: 0,
|
|
60336
|
+
underperforming_workspace_names: [],
|
|
60337
|
+
underperforming_workspace_uuids: [],
|
|
60338
|
+
output_array: [],
|
|
60339
|
+
line_threshold: 0,
|
|
60340
|
+
threshold_pph: 0,
|
|
60341
|
+
shift_start: "06:00",
|
|
60342
|
+
shift_end: "14:00",
|
|
60343
|
+
last_updated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
60344
|
+
poorest_performing_workspaces: poorestPerformingWorkspaces,
|
|
60345
|
+
idle_time_hourly: {}
|
|
60346
|
+
};
|
|
60347
|
+
}
|
|
60348
|
+
return {
|
|
60349
|
+
...baseMetrics,
|
|
60350
|
+
line_id: lineId,
|
|
60351
|
+
shift_id: baseMetrics.shift_id ?? queryShiftId,
|
|
60352
|
+
date: baseMetrics.date ?? queryDate,
|
|
60353
|
+
factory_id: baseMetrics.factory_id ?? detailResponse.line_details?.factory_id ?? "",
|
|
60354
|
+
poorest_performing_workspaces: poorestPerformingWorkspaces
|
|
60355
|
+
};
|
|
60356
|
+
};
|
|
60357
|
+
var useLineDetailPageData = ({
|
|
60358
|
+
lineId,
|
|
60359
|
+
companyId,
|
|
60360
|
+
timezone,
|
|
60361
|
+
shiftConfig,
|
|
60362
|
+
date: urlDate,
|
|
60363
|
+
shiftId: urlShiftId,
|
|
60364
|
+
enabled = true
|
|
60365
|
+
}) => {
|
|
60366
|
+
const supabase = useSupabase();
|
|
60367
|
+
const { hydrateFromBackend } = useIdleTimeVlmConfig();
|
|
60368
|
+
const realtimeEnabled = enabled && urlDate === void 0 && urlShiftId === void 0;
|
|
60369
|
+
const { shiftKey: operationalShiftKey } = useOperationalShiftKey({
|
|
60370
|
+
enabled: realtimeEnabled,
|
|
60371
|
+
timezone,
|
|
60372
|
+
shiftConfig: shiftConfig || void 0
|
|
60373
|
+
});
|
|
60374
|
+
const currentShift = useMemo(
|
|
60375
|
+
() => shiftConfig ? getCurrentShift(timezone, shiftConfig) : null,
|
|
60376
|
+
[timezone, shiftConfig, operationalShiftKey]
|
|
60377
|
+
);
|
|
60378
|
+
const queryShiftId = useMemo(
|
|
60379
|
+
() => urlShiftId !== void 0 ? urlShiftId : currentShift?.shiftId ?? 0,
|
|
60380
|
+
[urlShiftId, currentShift]
|
|
60381
|
+
);
|
|
60382
|
+
const queryDate = useMemo(
|
|
60383
|
+
() => urlDate || getOperationalDate(timezone),
|
|
60384
|
+
[urlDate, timezone]
|
|
60385
|
+
);
|
|
60386
|
+
const [detailResponse, setDetailResponse] = useState(null);
|
|
60387
|
+
const [loading, setLoading] = useState(true);
|
|
60388
|
+
const [error, setError] = useState(null);
|
|
60389
|
+
const channelsRef = useRef([]);
|
|
60390
|
+
const requestIdRef = useRef(0);
|
|
60391
|
+
const fetchTimeoutRef = useRef(null);
|
|
60392
|
+
const fetchDetail = useCallback(async () => {
|
|
60393
|
+
if (!enabled || !supabase || !lineId || !companyId) {
|
|
60394
|
+
setLoading(false);
|
|
60395
|
+
if (!companyId) {
|
|
60396
|
+
setError({ message: "Company ID is not configured", code: "CONFIG_ERROR" });
|
|
60397
|
+
}
|
|
60398
|
+
return;
|
|
60399
|
+
}
|
|
60400
|
+
const requestId = requestIdRef.current + 1;
|
|
60401
|
+
requestIdRef.current = requestId;
|
|
60402
|
+
setLoading(true);
|
|
60403
|
+
setError(null);
|
|
60404
|
+
try {
|
|
60405
|
+
const nextDetail = await fetchLineDetail(supabase, {
|
|
60406
|
+
lineId,
|
|
60407
|
+
date: queryDate,
|
|
60408
|
+
shiftId: queryShiftId,
|
|
60409
|
+
companyId
|
|
60410
|
+
});
|
|
60411
|
+
if (requestId !== requestIdRef.current) {
|
|
60412
|
+
return;
|
|
60413
|
+
}
|
|
60414
|
+
hydrateFromBackend(nextDetail?.idle_time_vlm_by_line);
|
|
60415
|
+
setDetailResponse(nextDetail);
|
|
60416
|
+
const metrics3 = transformLineMetrics(lineId, nextDetail, queryDate, queryShiftId);
|
|
60417
|
+
const lineDetails2 = transformLineDetails(lineId, nextDetail);
|
|
60418
|
+
const workspaces2 = transformWorkspaceMetrics(
|
|
60419
|
+
nextDetail.workspace_metrics || [],
|
|
60420
|
+
lineId,
|
|
60421
|
+
companyId,
|
|
60422
|
+
queryDate,
|
|
60423
|
+
queryShiftId
|
|
60424
|
+
);
|
|
60425
|
+
const lineInfo2 = buildLineInfoSnapshot(lineDetails2, metrics3);
|
|
60426
|
+
if (lineInfo2) {
|
|
60427
|
+
lineDetailStore.setSnapshot(lineId, lineInfo2.date, lineInfo2.shift_id, {
|
|
60428
|
+
lineInfo: lineInfo2,
|
|
60429
|
+
workspaces: workspaces2
|
|
60430
|
+
});
|
|
60431
|
+
}
|
|
60432
|
+
} catch (err) {
|
|
60433
|
+
if (requestId !== requestIdRef.current) {
|
|
60434
|
+
return;
|
|
60435
|
+
}
|
|
60436
|
+
setError({ message: err.message, code: err.code || "FETCH_ERROR" });
|
|
60437
|
+
} finally {
|
|
60438
|
+
if (requestId === requestIdRef.current) {
|
|
60439
|
+
setLoading(false);
|
|
60440
|
+
}
|
|
60441
|
+
}
|
|
60442
|
+
}, [enabled, supabase, lineId, companyId, queryDate, queryShiftId, hydrateFromBackend]);
|
|
60443
|
+
const queueUpdate = useCallback(() => {
|
|
60444
|
+
if (fetchTimeoutRef.current) {
|
|
60445
|
+
clearTimeout(fetchTimeoutRef.current);
|
|
60446
|
+
}
|
|
60447
|
+
fetchTimeoutRef.current = setTimeout(() => {
|
|
60448
|
+
fetchDetail();
|
|
60449
|
+
fetchTimeoutRef.current = null;
|
|
60450
|
+
}, 300);
|
|
60451
|
+
}, [fetchDetail]);
|
|
60452
|
+
useEffect(() => {
|
|
60453
|
+
if (!enabled) {
|
|
60454
|
+
setLoading(false);
|
|
60455
|
+
return;
|
|
60456
|
+
}
|
|
60457
|
+
fetchDetail();
|
|
60458
|
+
}, [enabled, fetchDetail]);
|
|
60459
|
+
useEffect(() => {
|
|
60460
|
+
channelsRef.current.forEach((channel) => {
|
|
60461
|
+
supabase.removeChannel(channel);
|
|
60462
|
+
});
|
|
60463
|
+
channelsRef.current = [];
|
|
60464
|
+
if (!supabase || !companyId || !lineId || !realtimeEnabled) {
|
|
60465
|
+
return;
|
|
60466
|
+
}
|
|
60467
|
+
const metricsTable = `${getMetricsTablePrefix()}_${companyId.replace(/-/g, "_")}`;
|
|
60468
|
+
const timestamp = Date.now();
|
|
60469
|
+
const currentDate = queryDate;
|
|
60470
|
+
const currentShiftId = queryShiftId;
|
|
60471
|
+
const lineFilter = `line_id=eq.${lineId}`;
|
|
60472
|
+
const createChannel = (name, table, filter2) => supabase.channel(`${name}-${timestamp}`).on(
|
|
60473
|
+
"postgres_changes",
|
|
60474
|
+
{ event: "*", schema: "public", table, filter: filter2 },
|
|
60475
|
+
(payload) => {
|
|
60476
|
+
const payloadData = payload.new || payload.old;
|
|
60477
|
+
if (payloadData?.date !== currentDate || payloadData?.shift_id !== currentShiftId) {
|
|
60478
|
+
return;
|
|
60479
|
+
}
|
|
60480
|
+
queueUpdate();
|
|
60481
|
+
}
|
|
60482
|
+
).subscribe();
|
|
60483
|
+
channelsRef.current = [
|
|
60484
|
+
createChannel("line-detail-line-metrics", "line_metrics", lineFilter),
|
|
60485
|
+
createChannel("line-detail-performance-metrics", metricsTable, lineFilter),
|
|
60486
|
+
createChannel("line-detail-wip-buffer-metrics", "wip_buffer_metrics", lineFilter)
|
|
60487
|
+
];
|
|
60488
|
+
return () => {
|
|
60489
|
+
if (fetchTimeoutRef.current) {
|
|
60490
|
+
clearTimeout(fetchTimeoutRef.current);
|
|
60491
|
+
fetchTimeoutRef.current = null;
|
|
60492
|
+
}
|
|
60493
|
+
channelsRef.current.forEach((channel) => {
|
|
60494
|
+
supabase.removeChannel(channel);
|
|
60495
|
+
});
|
|
60496
|
+
channelsRef.current = [];
|
|
60497
|
+
};
|
|
60498
|
+
}, [supabase, companyId, lineId, realtimeEnabled, queryDate, queryShiftId, queueUpdate]);
|
|
60499
|
+
const metrics2 = useMemo(
|
|
60500
|
+
() => detailResponse ? transformLineMetrics(lineId, detailResponse, queryDate, queryShiftId) : null,
|
|
60501
|
+
[detailResponse, lineId, queryDate, queryShiftId]
|
|
60502
|
+
);
|
|
60503
|
+
const lineDetails = useMemo(
|
|
60504
|
+
() => detailResponse ? transformLineDetails(lineId, detailResponse) : null,
|
|
60505
|
+
[detailResponse, lineId]
|
|
60506
|
+
);
|
|
60507
|
+
const workspaces = useMemo(
|
|
60508
|
+
() => detailResponse && companyId ? transformWorkspaceMetrics(detailResponse.workspace_metrics || [], lineId, companyId, queryDate, queryShiftId) : [],
|
|
60509
|
+
[detailResponse, companyId, lineId, queryDate, queryShiftId]
|
|
60510
|
+
);
|
|
60511
|
+
const lineInfo = useMemo(() => buildLineInfoSnapshot(lineDetails, metrics2), [lineDetails, metrics2]);
|
|
60512
|
+
return {
|
|
60513
|
+
detailResponse,
|
|
60514
|
+
lineDetails,
|
|
60515
|
+
metrics: metrics2,
|
|
60516
|
+
workspaces,
|
|
60517
|
+
lineInfo,
|
|
60518
|
+
issueResolutionSummary: detailResponse?.issue_resolution_summary ?? null,
|
|
60519
|
+
loading,
|
|
60520
|
+
error,
|
|
60521
|
+
refresh: () => fetchDetail()
|
|
60522
|
+
};
|
|
60523
|
+
};
|
|
60524
|
+
|
|
60079
60525
|
// src/lib/services/efficiencyLegendService.ts
|
|
60080
60526
|
var EfficiencyLegendService = class {
|
|
60081
60527
|
// 5 minutes
|
|
@@ -60670,21 +61116,45 @@ var formatLocalDate = (date) => {
|
|
|
60670
61116
|
};
|
|
60671
61117
|
return date.toLocaleDateString("en-US", options);
|
|
60672
61118
|
};
|
|
61119
|
+
var formatResolutionDuration = (seconds) => {
|
|
61120
|
+
if (seconds === null || seconds === void 0 || seconds <= 0) {
|
|
61121
|
+
return "-";
|
|
61122
|
+
}
|
|
61123
|
+
return formatIdleTime(Math.max(0, Math.floor(seconds)));
|
|
61124
|
+
};
|
|
61125
|
+
var getIssueResolutionSecondaryText = (summary) => {
|
|
61126
|
+
if (!summary) {
|
|
61127
|
+
return "No issue data";
|
|
61128
|
+
}
|
|
61129
|
+
const parts = [`${summary.resolved_issue_count} resolved`];
|
|
61130
|
+
if ((summary.open_issue_count || 0) > 0) {
|
|
61131
|
+
parts.push(`oldest open ${formatResolutionDuration(summary.oldest_open_issue_age_seconds)}`);
|
|
61132
|
+
}
|
|
61133
|
+
return parts.join(" \u2022 ");
|
|
61134
|
+
};
|
|
60673
61135
|
var MetricCards = memo$1(({
|
|
60674
61136
|
lineInfo,
|
|
61137
|
+
issueResolutionSummary,
|
|
60675
61138
|
idleTimeData,
|
|
60676
61139
|
showIdleTime,
|
|
60677
61140
|
efficiencyLegend
|
|
60678
61141
|
}) => {
|
|
60679
61142
|
const efficiency = lineInfo?.metrics.avg_efficiency || 0;
|
|
60680
61143
|
const efficiencyColorClass = getEfficiencyTextColorClasses(efficiency, efficiencyLegend);
|
|
61144
|
+
const showIssueResolutionCard = Boolean(issueResolutionSummary);
|
|
61145
|
+
const largeGridColumns = showIdleTime ? showIssueResolutionCard ? "lg:grid-cols-5" : "lg:grid-cols-4" : showIssueResolutionCard ? "lg:grid-cols-4" : "lg:grid-cols-3";
|
|
61146
|
+
const shouldMaskIssueResolution = efficiency < 5;
|
|
61147
|
+
const issueResolutionValue = shouldMaskIssueResolution ? "-" : formatResolutionDuration(
|
|
61148
|
+
issueResolutionSummary?.mean_resolution_seconds ?? issueResolutionSummary?.median_resolution_seconds
|
|
61149
|
+
);
|
|
61150
|
+
getIssueResolutionSecondaryText(issueResolutionSummary);
|
|
60681
61151
|
return /* @__PURE__ */ jsxs(
|
|
60682
61152
|
motion.div,
|
|
60683
61153
|
{
|
|
60684
61154
|
variants: containerVariants,
|
|
60685
61155
|
initial: "initial",
|
|
60686
61156
|
animate: "animate",
|
|
60687
|
-
className: `grid grid-cols-1 sm:grid-cols-2 ${
|
|
61157
|
+
className: `grid grid-cols-1 sm:grid-cols-2 ${largeGridColumns} gap-3 sm:gap-4 mb-2 h-auto lg:flex-[2] lg:min-h-[250px]`,
|
|
60688
61158
|
children: [
|
|
60689
61159
|
/* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
60690
61160
|
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 mb-2 text-center", children: "Line Output" }),
|
|
@@ -60713,6 +61183,28 @@ var MetricCards = memo$1(({
|
|
|
60713
61183
|
"%"
|
|
60714
61184
|
] }) })
|
|
60715
61185
|
] }),
|
|
61186
|
+
showIssueResolutionCard && /* @__PURE__ */ jsxs(
|
|
61187
|
+
motion.div,
|
|
61188
|
+
{
|
|
61189
|
+
variants: itemVariants,
|
|
61190
|
+
className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 h-[240px] sm:h-[260px] md:h-auto",
|
|
61191
|
+
children: [
|
|
61192
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-1.5 mb-2 relative group z-10", children: [
|
|
61193
|
+
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700", children: "Average Issue Resolution Time" }),
|
|
61194
|
+
/* @__PURE__ */ jsx(InformationCircleIcon, { className: "w-4 h-4 text-gray-400 cursor-help" }),
|
|
61195
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute top-full left-1/2 transform -translate-x-1/2 mt-2.5 w-[260px] p-3 bg-white rounded-lg shadow-xl border border-gray-200 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 pointer-events-none z-50", children: [
|
|
61196
|
+
/* @__PURE__ */ jsx("p", { className: "text-center text-xs text-gray-600 leading-relaxed mb-2.5 px-1", children: "The average time a supervisor takes to resolve a workstation in red." }),
|
|
61197
|
+
/* @__PURE__ */ jsx("div", { className: "bg-gray-50 rounded-md py-1.5 border border-gray-100/80", children: /* @__PURE__ */ jsxs("p", { className: "text-center font-medium text-[11px] text-gray-500", children: [
|
|
61198
|
+
((issueResolutionSummary?.resolved_issue_count || 0) + (issueResolutionSummary?.open_issue_count || 0)).toLocaleString(),
|
|
61199
|
+
" recorded issues"
|
|
61200
|
+
] }) }),
|
|
61201
|
+
/* @__PURE__ */ jsx("div", { className: "absolute -top-1.5 left-1/2 transform -translate-x-1/2 w-3 h-3 bg-white border-l border-t border-gray-200 rotate-45" })
|
|
61202
|
+
] })
|
|
61203
|
+
] }),
|
|
61204
|
+
/* @__PURE__ */ jsx("div", { className: "h-[calc(100%-2.5rem)] flex flex-col items-center justify-center gap-3", children: /* @__PURE__ */ jsx("span", { className: `text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold ${shouldMaskIssueResolution ? "text-gray-400" : "text-gray-900"}`, children: issueResolutionValue }) })
|
|
61205
|
+
]
|
|
61206
|
+
}
|
|
61207
|
+
),
|
|
60716
61208
|
showIdleTime && /* @__PURE__ */ jsxs(motion.div, { variants: itemVariants, className: "bg-white rounded-xl shadow-sm p-3 sm:p-4 overflow-hidden h-[240px] sm:h-[260px] md:h-auto", children: [
|
|
60717
61209
|
/* @__PURE__ */ jsx("h2", { className: "text-sm sm:text-base font-bold text-gray-700 text-center mb-2", children: "Idle Time Breakdown" }),
|
|
60718
61210
|
/* @__PURE__ */ jsx("div", { className: "h-[calc(100%-2.5rem)]", children: /* @__PURE__ */ jsx(
|
|
@@ -60733,6 +61225,8 @@ var MetricCards = memo$1(({
|
|
|
60733
61225
|
if (prevProps.efficiencyLegend !== nextProps.efficiencyLegend) return false;
|
|
60734
61226
|
const prevMetrics = prevProps.lineInfo.metrics;
|
|
60735
61227
|
const nextMetrics = nextProps.lineInfo.metrics;
|
|
61228
|
+
const prevIssueSummary = prevProps.issueResolutionSummary;
|
|
61229
|
+
const nextIssueSummary = nextProps.issueResolutionSummary;
|
|
60736
61230
|
const prevIdleChartSignature = JSON.stringify(
|
|
60737
61231
|
(prevProps.idleTimeData?.chartData || []).map((entry) => ({
|
|
60738
61232
|
name: entry.name,
|
|
@@ -60751,6 +61245,9 @@ var MetricCards = memo$1(({
|
|
|
60751
61245
|
);
|
|
60752
61246
|
const idleTimeChanged = prevProps.idleTimeData?.isLoading !== nextProps.idleTimeData?.isLoading || prevProps.idleTimeData?.error !== nextProps.idleTimeData?.error || prevIdleChartSignature !== nextIdleChartSignature || prevProps.idleTimeData?.data?.total_idle_time_seconds !== nextProps.idleTimeData?.data?.total_idle_time_seconds || prevProps.idleTimeData?.data?.scope_work_seconds !== nextProps.idleTimeData?.data?.scope_work_seconds;
|
|
60753
61247
|
if (idleTimeChanged) return false;
|
|
61248
|
+
if (prevIssueSummary?.mean_resolution_seconds !== nextIssueSummary?.mean_resolution_seconds || prevIssueSummary?.median_resolution_seconds !== nextIssueSummary?.median_resolution_seconds || prevIssueSummary?.resolved_issue_count !== nextIssueSummary?.resolved_issue_count || prevIssueSummary?.open_issue_count !== nextIssueSummary?.open_issue_count || prevIssueSummary?.oldest_open_issue_age_seconds !== nextIssueSummary?.oldest_open_issue_age_seconds || prevIssueSummary?.total_issue_seconds !== nextIssueSummary?.total_issue_seconds) {
|
|
61249
|
+
return false;
|
|
61250
|
+
}
|
|
60754
61251
|
return prevMetrics.current_output === nextMetrics.current_output && prevMetrics.line_threshold === nextMetrics.line_threshold && prevMetrics.underperforming_workspaces === nextMetrics.underperforming_workspaces && prevMetrics.total_workspaces === nextMetrics.total_workspaces && prevMetrics.avg_efficiency === nextMetrics.avg_efficiency;
|
|
60755
61252
|
});
|
|
60756
61253
|
MetricCards.displayName = "MetricCards";
|
|
@@ -61257,11 +61754,16 @@ var KPIDetailView = ({
|
|
|
61257
61754
|
const {
|
|
61258
61755
|
metrics: metrics2,
|
|
61259
61756
|
lineDetails,
|
|
61260
|
-
|
|
61261
|
-
|
|
61262
|
-
|
|
61263
|
-
|
|
61757
|
+
workspaces,
|
|
61758
|
+
issueResolutionSummary,
|
|
61759
|
+
loading: lineDetailLoading,
|
|
61760
|
+
error: lineDetailError,
|
|
61761
|
+
refresh: refreshLineDetail
|
|
61762
|
+
} = useLineDetailPageData({
|
|
61264
61763
|
lineId,
|
|
61764
|
+
companyId: resolvedCompanyId,
|
|
61765
|
+
timezone: configuredTimezone,
|
|
61766
|
+
shiftConfig,
|
|
61265
61767
|
date: typeof urlDate === "string" ? urlDate : void 0,
|
|
61266
61768
|
shiftId: parsedShiftId,
|
|
61267
61769
|
enabled: !isShiftConfigLoading && (!historicalRouteRequested || historicalParamsReady)
|
|
@@ -61269,16 +61771,11 @@ var KPIDetailView = ({
|
|
|
61269
61771
|
const resolvedMonitoringMode = lineDetails?.monitoring_mode ?? "output";
|
|
61270
61772
|
const isUptimeMode = resolvedMonitoringMode === "uptime";
|
|
61271
61773
|
const overviewTabLabel = isUptimeMode ? "Utilization" : "Efficiency";
|
|
61272
|
-
const
|
|
61273
|
-
|
|
61274
|
-
|
|
61275
|
-
|
|
61276
|
-
|
|
61277
|
-
} = useLineWorkspaceMetrics(lineId, {
|
|
61278
|
-
initialDate: typeof urlDate === "string" ? urlDate : void 0,
|
|
61279
|
-
initialShiftId: parsedShiftId,
|
|
61280
|
-
enabled: !isShiftConfigLoading && (!historicalRouteRequested || historicalParamsReady)
|
|
61281
|
-
});
|
|
61774
|
+
const lineMetricsLoading = lineDetailLoading;
|
|
61775
|
+
const workspacesLoading = lineDetailLoading;
|
|
61776
|
+
const lineMetricsError = lineDetailError;
|
|
61777
|
+
const workspacesError = lineDetailError;
|
|
61778
|
+
const refreshMetrics = refreshLineDetail;
|
|
61282
61779
|
const idleTimeDate = historicalRouteRequested ? historicalParamsReady ? urlDate : void 0 : typeof urlDate === "string" ? urlDate : metrics2?.date || cachedLineInfo?.date;
|
|
61283
61780
|
const idleTimeShiftId = historicalRouteRequested ? historicalParamsReady ? parsedShiftId : void 0 : parsedShiftId ?? metrics2?.shift_id ?? cachedLineInfo?.shift_id;
|
|
61284
61781
|
const idleTimeEnabled = activeTab === "overview" && !!lineId && idleTimeVlmEnabled && !!idleTimeDate && idleTimeShiftId !== void 0 && (!historicalRouteRequested || historicalParamsReady);
|
|
@@ -61994,7 +62491,6 @@ var KPIDetailView = ({
|
|
|
61994
62491
|
{
|
|
61995
62492
|
onClick: () => {
|
|
61996
62493
|
refreshMetrics();
|
|
61997
|
-
refreshWorkspaces();
|
|
61998
62494
|
},
|
|
61999
62495
|
className: "mt-4 px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
|
|
62000
62496
|
children: "Try Again"
|
|
@@ -62021,7 +62517,7 @@ var KPIDetailView = ({
|
|
|
62021
62517
|
return /* @__PURE__ */ jsx(LoadingPage, { message: "Processing line data..." });
|
|
62022
62518
|
}
|
|
62023
62519
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
62024
|
-
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-
|
|
62520
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
|
|
62025
62521
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
62026
62522
|
/* @__PURE__ */ jsx(
|
|
62027
62523
|
"button",
|
|
@@ -62197,7 +62693,7 @@ var KPIDetailView = ({
|
|
|
62197
62693
|
)
|
|
62198
62694
|
] }),
|
|
62199
62695
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 ml-auto", children: [
|
|
62200
|
-
resolvedLineInfo && activeTab === "overview" && /* @__PURE__ */ jsx(LinePdfGenerator, { lineInfo: resolvedLineInfo, workspaceData: resolvedWorkspaces || [], shiftName: getShiftName(resolvedLineInfo.shift_id) }),
|
|
62696
|
+
resolvedLineInfo && activeTab === "overview" && /* @__PURE__ */ jsx(LinePdfGenerator, { lineInfo: resolvedLineInfo, workspaceData: resolvedWorkspaces || [], issueResolutionSummary, shiftName: getShiftName(resolvedLineInfo.shift_id) }),
|
|
62201
62697
|
activeTab === "monthly_history" && !urlDate && !urlShift && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62202
62698
|
/* @__PURE__ */ jsx(
|
|
62203
62699
|
MonthlyRangeFilter_default,
|
|
@@ -62256,6 +62752,7 @@ var KPIDetailView = ({
|
|
|
62256
62752
|
MetricCards,
|
|
62257
62753
|
{
|
|
62258
62754
|
lineInfo: resolvedLineInfo,
|
|
62755
|
+
issueResolutionSummary,
|
|
62259
62756
|
idleTimeData,
|
|
62260
62757
|
showIdleTime: idleTimeVlmEnabled,
|
|
62261
62758
|
efficiencyLegend
|
|
@@ -62353,6 +62850,7 @@ var KPIDetailView = ({
|
|
|
62353
62850
|
MetricCards,
|
|
62354
62851
|
{
|
|
62355
62852
|
lineInfo: resolvedLineInfo,
|
|
62853
|
+
issueResolutionSummary,
|
|
62356
62854
|
idleTimeData,
|
|
62357
62855
|
showIdleTime: idleTimeVlmEnabled,
|
|
62358
62856
|
efficiencyLegend
|
|
@@ -62522,18 +63020,18 @@ var LinesLeaderboard = ({
|
|
|
62522
63020
|
isHistoricalDaily
|
|
62523
63021
|
}) => {
|
|
62524
63022
|
const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
|
|
62525
|
-
const assignedLineIdSet =
|
|
63023
|
+
const assignedLineIdSet = React142__default.useMemo(
|
|
62526
63024
|
() => new Set(assignedLineIds || []),
|
|
62527
63025
|
[assignedLineIds]
|
|
62528
63026
|
);
|
|
62529
|
-
const canClickLine =
|
|
63027
|
+
const canClickLine = React142__default.useCallback(
|
|
62530
63028
|
(lineId) => {
|
|
62531
63029
|
if (!assignedLineIds) return true;
|
|
62532
63030
|
return assignedLineIdSet.has(lineId);
|
|
62533
63031
|
},
|
|
62534
63032
|
[assignedLineIds, assignedLineIdSet]
|
|
62535
63033
|
);
|
|
62536
|
-
const handleTimeRangeChange =
|
|
63034
|
+
const handleTimeRangeChange = React142__default.useCallback((newRange) => {
|
|
62537
63035
|
if (newRange === timeRange) return;
|
|
62538
63036
|
trackCoreEvent("Leaderboard Time Range Changed", {
|
|
62539
63037
|
from_range: timeRange,
|
|
@@ -62544,7 +63042,7 @@ var LinesLeaderboard = ({
|
|
|
62544
63042
|
});
|
|
62545
63043
|
setTimeRange(newRange);
|
|
62546
63044
|
}, [timeRange, lines.length, monthlyEfficiencyByLineId, setTimeRange]);
|
|
62547
|
-
const handleLeaderboardLineClick =
|
|
63045
|
+
const handleLeaderboardLineClick = React142__default.useCallback((item, clickSource) => {
|
|
62548
63046
|
if (!canClickLine(item.line.id)) return;
|
|
62549
63047
|
trackCoreEvent("Leaderboard Line Clicked", {
|
|
62550
63048
|
line_id: item.line.id,
|
|
@@ -62558,8 +63056,8 @@ var LinesLeaderboard = ({
|
|
|
62558
63056
|
});
|
|
62559
63057
|
onLineClick(item.line);
|
|
62560
63058
|
}, [canClickLine, onLineClick, timeRange]);
|
|
62561
|
-
const viewLoadedTrackedRef =
|
|
62562
|
-
const leaderboardData =
|
|
63059
|
+
const viewLoadedTrackedRef = React142__default.useRef(null);
|
|
63060
|
+
const leaderboardData = React142__default.useMemo(() => {
|
|
62563
63061
|
const loading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
62564
63062
|
const efficiencyMap = timeRange === "today" ? todayEfficiencyByLineId : monthlyEfficiencyByLineId;
|
|
62565
63063
|
return lines.map((line) => {
|
|
@@ -62590,7 +63088,7 @@ var LinesLeaderboard = ({
|
|
|
62590
63088
|
isLoadingToday,
|
|
62591
63089
|
isLoadingMonthly
|
|
62592
63090
|
]);
|
|
62593
|
-
|
|
63091
|
+
React142__default.useEffect(() => {
|
|
62594
63092
|
const isLoading = timeRange === "today" ? isLoadingToday : isLoadingMonthly;
|
|
62595
63093
|
const trackingKey = `${timeRange}-${leaderboardData.length}`;
|
|
62596
63094
|
if (leaderboardData.length > 0 && !isLoading && viewLoadedTrackedRef.current !== trackingKey) {
|
|
@@ -62616,7 +63114,7 @@ var LinesLeaderboard = ({
|
|
|
62616
63114
|
const countdownFormat = timeRange === "monthly" ? "days" : "clock";
|
|
62617
63115
|
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift Ended";
|
|
62618
63116
|
const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
|
|
62619
|
-
const handleCountdownFinished =
|
|
63117
|
+
const handleCountdownFinished = React142__default.useCallback(() => {
|
|
62620
63118
|
trackCoreEvent("Leaderboard Countdown Finished", {
|
|
62621
63119
|
countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
|
|
62622
63120
|
time_range: timeRange,
|
|
@@ -62643,7 +63141,7 @@ var LinesLeaderboard = ({
|
|
|
62643
63141
|
return "bg-white border-gray-100";
|
|
62644
63142
|
}
|
|
62645
63143
|
};
|
|
62646
|
-
|
|
63144
|
+
React142__default.useEffect(() => {
|
|
62647
63145
|
const style = document.createElement("style");
|
|
62648
63146
|
style.innerHTML = `
|
|
62649
63147
|
@keyframes float {
|
|
@@ -62830,7 +63328,7 @@ var LineCard = ({
|
|
|
62830
63328
|
supervisors
|
|
62831
63329
|
}) => {
|
|
62832
63330
|
const isUptimeLine = (line.monitoring_mode ?? "output") === "uptime";
|
|
62833
|
-
const isOnTrack =
|
|
63331
|
+
const isOnTrack = React142__default.useMemo(() => {
|
|
62834
63332
|
if (!kpis) return null;
|
|
62835
63333
|
return isEfficiencyOnTrack(kpis.efficiency.value);
|
|
62836
63334
|
}, [kpis]);
|
|
@@ -62988,6 +63486,9 @@ var KPIsOverviewView = ({
|
|
|
62988
63486
|
const [selectedLeaderboardShiftId, setSelectedLeaderboardShiftId] = useState(0);
|
|
62989
63487
|
const [hasHydratedLeaderboardRouteState, setHasHydratedLeaderboardRouteState] = useState(false);
|
|
62990
63488
|
const [loading, setLoading] = useState(true);
|
|
63489
|
+
const [isFilterOpen, setIsFilterOpen] = useState(false);
|
|
63490
|
+
const filterRef = useRef(null);
|
|
63491
|
+
const filterButtonRef = useRef(null);
|
|
62991
63492
|
const [error, setError] = useState(null);
|
|
62992
63493
|
const [topPerformer, setTopPerformer] = useState({
|
|
62993
63494
|
name: "Top Performer",
|
|
@@ -63025,46 +63526,46 @@ var KPIsOverviewView = ({
|
|
|
63025
63526
|
const configuredTimezone = dbTimezone || dateTimeConfig.defaultTimezone || "UTC";
|
|
63026
63527
|
const { startDate: monthStartDate, endDate: monthEndDateKey, monthEndDate } = getMonthDateInfo(configuredTimezone);
|
|
63027
63528
|
const isSuperAdmin = user?.scope_mode === "SUPER_ADMIN" || !!user?.access_scope?.is_super_admin;
|
|
63028
|
-
const scopedLineIds =
|
|
63529
|
+
const scopedLineIds = React142__default.useMemo(
|
|
63029
63530
|
() => Array.isArray(user?.access_scope?.line_ids) ? user.access_scope.line_ids.filter((lineId) => typeof lineId === "string" && lineId.length > 0) : [],
|
|
63030
63531
|
[user?.access_scope?.line_ids]
|
|
63031
63532
|
);
|
|
63032
63533
|
const hasCanonicalScope = !!user?.scope_mode || !!user?.access_scope;
|
|
63033
63534
|
const scopeRole = (user?.role_level || user?.role || "").toLowerCase();
|
|
63034
63535
|
const isStrictLineScopedRole = scopeRole === "supervisor" || isFactoryScopedRole(scopeRole);
|
|
63035
|
-
const resolvedAssignedLineIds =
|
|
63536
|
+
const resolvedAssignedLineIds = React142__default.useMemo(() => {
|
|
63036
63537
|
if (isSuperAdmin) return [];
|
|
63037
63538
|
if (scopedLineIds.length > 0) return scopedLineIds;
|
|
63038
63539
|
if (lineIds && lineIds.length > 0) return lineIds;
|
|
63039
63540
|
if (isStrictLineScopedRole && hasCanonicalScope) return [];
|
|
63040
63541
|
return [];
|
|
63041
63542
|
}, [isSuperAdmin, scopedLineIds, lineIds, isStrictLineScopedRole, hasCanonicalScope]);
|
|
63042
|
-
const assignedLineIdSet =
|
|
63543
|
+
const assignedLineIdSet = React142__default.useMemo(
|
|
63043
63544
|
() => new Set(resolvedAssignedLineIds),
|
|
63044
63545
|
[resolvedAssignedLineIds]
|
|
63045
63546
|
);
|
|
63046
|
-
const metricsLineIds =
|
|
63547
|
+
const metricsLineIds = React142__default.useMemo(() => {
|
|
63047
63548
|
if (isSuperAdmin) {
|
|
63048
63549
|
return lineIds ?? [];
|
|
63049
63550
|
}
|
|
63050
63551
|
return resolvedAssignedLineIds;
|
|
63051
63552
|
}, [isSuperAdmin, lineIds, resolvedAssignedLineIds]);
|
|
63052
63553
|
const assignedLineIdsForLeaderboard = isSuperAdmin ? void 0 : resolvedAssignedLineIds;
|
|
63053
|
-
const leaderboardLinesForView =
|
|
63554
|
+
const leaderboardLinesForView = React142__default.useMemo(() => {
|
|
63054
63555
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
63055
63556
|
return leaderboardLines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
63056
63557
|
}, [leaderboardLines, viewType]);
|
|
63057
|
-
const linesForView =
|
|
63558
|
+
const linesForView = React142__default.useMemo(() => {
|
|
63058
63559
|
const targetMode = viewType === "machine" ? "uptime" : "output";
|
|
63059
63560
|
return lines.filter((line) => (line.monitoring_mode ?? "output") === targetMode);
|
|
63060
63561
|
}, [lines, viewType]);
|
|
63061
|
-
const relevantLinesForMode =
|
|
63562
|
+
const relevantLinesForMode = React142__default.useMemo(() => {
|
|
63062
63563
|
if (activeTab === "leaderboard") {
|
|
63063
63564
|
return leaderboardLines.length > 0 ? leaderboardLines : lines;
|
|
63064
63565
|
}
|
|
63065
63566
|
return lines;
|
|
63066
63567
|
}, [activeTab, leaderboardLines, lines]);
|
|
63067
|
-
const { hasUptime, hasOutput } =
|
|
63568
|
+
const { hasUptime, hasOutput } = React142__default.useMemo(() => {
|
|
63068
63569
|
let uptime = false;
|
|
63069
63570
|
let output = false;
|
|
63070
63571
|
for (const line of relevantLinesForMode) {
|
|
@@ -63089,11 +63590,32 @@ var KPIsOverviewView = ({
|
|
|
63089
63590
|
const currentShiftDetails = getCurrentShift(configuredTimezone, shiftConfig);
|
|
63090
63591
|
const currentShiftDate = currentShiftDetails.date;
|
|
63091
63592
|
const currentShiftId = currentShiftDetails.shiftId;
|
|
63092
|
-
const
|
|
63593
|
+
const activeFiltersCount = React142__default.useMemo(() => {
|
|
63594
|
+
let count = 0;
|
|
63595
|
+
if (selectedLeaderboardShiftId !== currentShiftId) {
|
|
63596
|
+
count++;
|
|
63597
|
+
}
|
|
63598
|
+
return count;
|
|
63599
|
+
}, [selectedLeaderboardShiftId, currentShiftId]);
|
|
63600
|
+
const clearFilters = React142__default.useCallback(() => {
|
|
63601
|
+
setSelectedLeaderboardShiftId(currentShiftId);
|
|
63602
|
+
}, [currentShiftId]);
|
|
63603
|
+
useEffect(() => {
|
|
63604
|
+
const handleClickOutside = (event) => {
|
|
63605
|
+
const target = event.target;
|
|
63606
|
+
if (filterButtonRef.current?.contains(target)) return;
|
|
63607
|
+
if (filterRef.current && !filterRef.current.contains(target)) {
|
|
63608
|
+
setIsFilterOpen(false);
|
|
63609
|
+
}
|
|
63610
|
+
};
|
|
63611
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
63612
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
63613
|
+
}, []);
|
|
63614
|
+
const shiftEndDate = React142__default.useMemo(
|
|
63093
63615
|
() => getShiftEndDate(currentShiftDetails, configuredTimezone),
|
|
63094
63616
|
[currentShiftDetails, configuredTimezone]
|
|
63095
63617
|
);
|
|
63096
|
-
const leaderboardShiftOptions =
|
|
63618
|
+
const leaderboardShiftOptions = React142__default.useMemo(() => {
|
|
63097
63619
|
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
63098
63620
|
return shiftConfig.shifts.map((shift) => ({
|
|
63099
63621
|
id: shift.shiftId,
|
|
@@ -63173,15 +63695,15 @@ var KPIsOverviewView = ({
|
|
|
63173
63695
|
lineId: factoryViewId,
|
|
63174
63696
|
userAccessibleLineIds: metricsLineIds
|
|
63175
63697
|
});
|
|
63176
|
-
const defaultKPIs =
|
|
63177
|
-
const kpisByLineId =
|
|
63698
|
+
const defaultKPIs = React142__default.useMemo(() => createDefaultKPIs(), []);
|
|
63699
|
+
const kpisByLineId = React142__default.useMemo(() => {
|
|
63178
63700
|
const map = /* @__PURE__ */ new Map();
|
|
63179
63701
|
lineMetrics.forEach((row) => {
|
|
63180
63702
|
if (row?.line_id) map.set(row.line_id, buildKPIsFromLineMetricsRow(row));
|
|
63181
63703
|
});
|
|
63182
63704
|
return map;
|
|
63183
63705
|
}, [lineMetrics]);
|
|
63184
|
-
const supervisorLineIds =
|
|
63706
|
+
const supervisorLineIds = React142__default.useMemo(
|
|
63185
63707
|
() => (leaderboardLines.length > 0 ? leaderboardLines : lines).map((l) => l.id),
|
|
63186
63708
|
[leaderboardLines, lines]
|
|
63187
63709
|
);
|
|
@@ -63544,7 +64066,7 @@ var KPIsOverviewView = ({
|
|
|
63544
64066
|
}
|
|
63545
64067
|
if (error) {
|
|
63546
64068
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
63547
|
-
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-
|
|
64069
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
|
|
63548
64070
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
63549
64071
|
mobileMenuContext && /* @__PURE__ */ jsx(
|
|
63550
64072
|
HamburgerButton,
|
|
@@ -63580,7 +64102,7 @@ var KPIsOverviewView = ({
|
|
|
63580
64102
|
}
|
|
63581
64103
|
if (lines.length === 0) {
|
|
63582
64104
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
63583
|
-
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-
|
|
64105
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
|
|
63584
64106
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
63585
64107
|
mobileMenuContext && /* @__PURE__ */ jsx(
|
|
63586
64108
|
HamburgerButton,
|
|
@@ -63618,7 +64140,7 @@ var KPIsOverviewView = ({
|
|
|
63618
64140
|
] });
|
|
63619
64141
|
}
|
|
63620
64142
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
63621
|
-
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-
|
|
64143
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
|
|
63622
64144
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden", children: [
|
|
63623
64145
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
63624
64146
|
mobileMenuContext && /* @__PURE__ */ jsx(
|
|
@@ -63630,12 +64152,7 @@ var KPIsOverviewView = ({
|
|
|
63630
64152
|
),
|
|
63631
64153
|
/* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
63632
64154
|
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900", children: activeTab === "leaderboard" ? "Leaderboard" : "Overview" }),
|
|
63633
|
-
/* @__PURE__ */ jsx(
|
|
63634
|
-
"div",
|
|
63635
|
-
{
|
|
63636
|
-
className: `h-2 w-2 rounded-full ring-2 ${showHistoricalLeaderboardHeader ? "bg-amber-500 ring-amber-500/20" : "bg-emerald-500 animate-pulse ring-emerald-500/20"}`
|
|
63637
|
-
}
|
|
63638
|
-
)
|
|
64155
|
+
!showHistoricalLeaderboardHeader && /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-emerald-500 animate-pulse ring-2 ring-emerald-500/20" })
|
|
63639
64156
|
] }) }),
|
|
63640
64157
|
/* @__PURE__ */ jsx("div", { className: "w-12" })
|
|
63641
64158
|
] }),
|
|
@@ -63646,9 +64163,23 @@ var KPIsOverviewView = ({
|
|
|
63646
64163
|
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon2(headerShiftId) }),
|
|
63647
64164
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: headerShiftName })
|
|
63648
64165
|
] }),
|
|
63649
|
-
showHistoricalLeaderboardHeader ? /* @__PURE__ */ jsxs("div", { className: "
|
|
63650
|
-
/* @__PURE__ */
|
|
63651
|
-
|
|
64166
|
+
showHistoricalLeaderboardHeader ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
64167
|
+
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-amber-50 text-amber-700 rounded-full", children: [
|
|
64168
|
+
/* @__PURE__ */ jsx(Clock, { className: "w-3 h-3" }),
|
|
64169
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: "Historical" })
|
|
64170
|
+
] }),
|
|
64171
|
+
activeTab === "leaderboard" && isHistoricalLeaderboardDaily && /* @__PURE__ */ jsx(
|
|
64172
|
+
"button",
|
|
64173
|
+
{
|
|
64174
|
+
type: "button",
|
|
64175
|
+
onClick: () => {
|
|
64176
|
+
setSelectedLeaderboardDate(currentShiftDate);
|
|
64177
|
+
setSelectedLeaderboardShiftId(currentShiftId);
|
|
64178
|
+
},
|
|
64179
|
+
className: "text-[10px] font-medium text-blue-600 hover:text-blue-700 hover:underline bg-blue-50 px-2 py-1 rounded-md",
|
|
64180
|
+
children: "Return to Live"
|
|
64181
|
+
}
|
|
64182
|
+
)
|
|
63652
64183
|
] }) : /* @__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(ISTTimer_default, {}) }) })
|
|
63653
64184
|
] })
|
|
63654
64185
|
] }),
|
|
@@ -63750,79 +64281,88 @@ var KPIsOverviewView = ({
|
|
|
63750
64281
|
) }),
|
|
63751
64282
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
63752
64283
|
/* @__PURE__ */ jsx("h1", { className: "text-2xl md:text-3xl lg:text-4xl font-semibold text-gray-900 tracking-tight", children: activeTab === "leaderboard" ? "Leaderboard" : "Overview" }),
|
|
63753
|
-
/* @__PURE__ */ jsx(
|
|
63754
|
-
"div",
|
|
63755
|
-
{
|
|
63756
|
-
className: `h-2.5 w-2.5 rounded-full ring-4 flex-shrink-0 ${showHistoricalLeaderboardHeader ? "bg-amber-500 ring-amber-500/10" : "bg-emerald-500 animate-pulse ring-emerald-500/10"}`
|
|
63757
|
-
}
|
|
63758
|
-
)
|
|
64284
|
+
!showHistoricalLeaderboardHeader && /* @__PURE__ */ jsx("div", { className: "h-2.5 w-2.5 rounded-full ring-4 flex-shrink-0 bg-emerald-500 animate-pulse ring-emerald-500/10" })
|
|
63759
64285
|
] }),
|
|
63760
|
-
|
|
63761
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
63762
|
-
|
|
63763
|
-
"
|
|
63764
|
-
|
|
63765
|
-
src: topPerformer.imageUrl || "",
|
|
63766
|
-
alt: topPerformer.name,
|
|
63767
|
-
className: "w-full h-full object-cover",
|
|
63768
|
-
onError: () => setTopPerformerImageError(true)
|
|
63769
|
-
}
|
|
63770
|
-
) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-sm font-bold text-amber-600 uppercase", children: topPerformer.initials }) }),
|
|
63771
|
-
topPerformer.supervisors && topPerformer.supervisors.length > 1 && /* @__PURE__ */ jsxs("div", { className: "flex -space-x-2", children: [
|
|
63772
|
-
topPerformer.supervisors.slice(0, 3).map((supervisor, idx) => /* @__PURE__ */ jsxs(
|
|
63773
|
-
"div",
|
|
64286
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center", children: [
|
|
64287
|
+
!topPerformerLoading && activeTab !== "leaderboard" && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-2xl border border-amber-200 shadow-md pl-1.5 pr-4 py-1.5 flex items-center gap-4 transition-all hover:shadow-lg hover:border-amber-300 group", children: [
|
|
64288
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
64289
|
+
(!topPerformer.supervisors || topPerformer.supervisors.length <= 1) && /* @__PURE__ */ jsx("div", { className: "w-10 h-10 rounded-full ring-2 ring-amber-100 overflow-hidden bg-amber-50 shadow-inner flex-shrink-0 transition-transform group-hover:scale-105", children: showTopPerformerImage ? /* @__PURE__ */ jsx(
|
|
64290
|
+
"img",
|
|
63774
64291
|
{
|
|
63775
|
-
|
|
63776
|
-
|
|
63777
|
-
|
|
63778
|
-
|
|
63779
|
-
|
|
63780
|
-
|
|
63781
|
-
|
|
63782
|
-
|
|
63783
|
-
|
|
63784
|
-
|
|
63785
|
-
|
|
63786
|
-
|
|
63787
|
-
|
|
63788
|
-
/* @__PURE__ */ jsx(
|
|
63789
|
-
|
|
63790
|
-
|
|
63791
|
-
|
|
63792
|
-
|
|
63793
|
-
|
|
63794
|
-
|
|
63795
|
-
|
|
63796
|
-
|
|
64292
|
+
src: topPerformer.imageUrl || "",
|
|
64293
|
+
alt: topPerformer.name,
|
|
64294
|
+
className: "w-full h-full object-cover",
|
|
64295
|
+
onError: () => setTopPerformerImageError(true)
|
|
64296
|
+
}
|
|
64297
|
+
) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-sm font-bold text-amber-600 uppercase", children: topPerformer.initials }) }),
|
|
64298
|
+
topPerformer.supervisors && topPerformer.supervisors.length > 1 && /* @__PURE__ */ jsxs("div", { className: "flex -space-x-2", children: [
|
|
64299
|
+
topPerformer.supervisors.slice(0, 3).map((supervisor, idx) => /* @__PURE__ */ jsxs(
|
|
64300
|
+
"div",
|
|
64301
|
+
{
|
|
64302
|
+
className: "relative inline-block w-10 h-10 rounded-full ring-2 ring-white bg-amber-50 shadow-sm z-0 hover:z-10 transition-all hover:scale-110 group/avatar",
|
|
64303
|
+
style: { zIndex: 3 - idx },
|
|
64304
|
+
children: [
|
|
64305
|
+
supervisor.imageUrl ? /* @__PURE__ */ jsx(
|
|
64306
|
+
"img",
|
|
64307
|
+
{
|
|
64308
|
+
src: supervisor.imageUrl,
|
|
64309
|
+
alt: supervisor.name,
|
|
64310
|
+
className: "w-full h-full object-cover rounded-full"
|
|
64311
|
+
}
|
|
64312
|
+
) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-sm font-bold text-amber-600 uppercase rounded-full", children: supervisor.initials }),
|
|
64313
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 bg-gray-900 text-white text-[10px] font-medium rounded shadow-lg opacity-0 group-hover/avatar:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-20", children: [
|
|
64314
|
+
supervisor.name,
|
|
64315
|
+
/* @__PURE__ */ jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 -mt-[1px] border-4 border-transparent border-t-gray-900" })
|
|
64316
|
+
] })
|
|
64317
|
+
]
|
|
64318
|
+
},
|
|
64319
|
+
supervisor.userId
|
|
64320
|
+
)),
|
|
64321
|
+
topPerformer.supervisors.length > 3 && /* @__PURE__ */ jsxs("div", { className: "inline-flex w-10 h-10 rounded-full ring-2 ring-white bg-amber-100 items-center justify-center text-sm font-medium text-amber-700 z-0", children: [
|
|
64322
|
+
"+",
|
|
64323
|
+
topPerformer.supervisors.length - 3
|
|
64324
|
+
] })
|
|
63797
64325
|
] })
|
|
63798
|
-
] })
|
|
63799
|
-
] }),
|
|
63800
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
63801
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[10px] leading-tight mb-1", children: [
|
|
63802
|
-
/* @__PURE__ */ jsx("span", { className: "font-bold text-amber-600 uppercase tracking-widest", children: "Performer of the month" }),
|
|
63803
|
-
/* @__PURE__ */ jsx("span", { className: "text-amber-200 opacity-50", children: "\u2022" }),
|
|
63804
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-400", children: topPerformer.periodLabel })
|
|
63805
64326
|
] }),
|
|
63806
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
63807
|
-
/* @__PURE__ */
|
|
63808
|
-
|
|
63809
|
-
{
|
|
63810
|
-
|
|
63811
|
-
|
|
63812
|
-
|
|
63813
|
-
|
|
63814
|
-
|
|
63815
|
-
|
|
63816
|
-
|
|
63817
|
-
|
|
63818
|
-
|
|
63819
|
-
|
|
63820
|
-
|
|
63821
|
-
}
|
|
63822
|
-
|
|
64327
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
64328
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[10px] leading-tight mb-1", children: [
|
|
64329
|
+
/* @__PURE__ */ jsx("span", { className: "font-bold text-amber-600 uppercase tracking-widest", children: "Performer of the month" }),
|
|
64330
|
+
/* @__PURE__ */ jsx("span", { className: "text-amber-200 opacity-50", children: "\u2022" }),
|
|
64331
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-400", children: topPerformer.periodLabel })
|
|
64332
|
+
] }),
|
|
64333
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 leading-tight", children: [
|
|
64334
|
+
/* @__PURE__ */ jsx("div", { className: "max-w-[140px]", children: /* @__PURE__ */ jsx(
|
|
64335
|
+
FittingTitle,
|
|
64336
|
+
{
|
|
64337
|
+
title: topPerformer.name,
|
|
64338
|
+
as: "span",
|
|
64339
|
+
className: "text-sm text-gray-900 font-bold"
|
|
64340
|
+
}
|
|
64341
|
+
) }),
|
|
64342
|
+
/* @__PURE__ */ jsx("span", { className: "w-px h-3.5 bg-gray-200 flex-shrink-0" }),
|
|
64343
|
+
/* @__PURE__ */ jsx("div", { className: "max-w-[150px]", children: /* @__PURE__ */ jsx(
|
|
64344
|
+
FittingTitle,
|
|
64345
|
+
{
|
|
64346
|
+
title: topPerformer.unit,
|
|
64347
|
+
className: "text-xs font-medium text-gray-500"
|
|
64348
|
+
}
|
|
64349
|
+
) })
|
|
64350
|
+
] })
|
|
63823
64351
|
] })
|
|
63824
|
-
] })
|
|
63825
|
-
|
|
64352
|
+
] }),
|
|
64353
|
+
activeTab === "leaderboard" && isHistoricalLeaderboardDaily && /* @__PURE__ */ jsx(
|
|
64354
|
+
"button",
|
|
64355
|
+
{
|
|
64356
|
+
type: "button",
|
|
64357
|
+
onClick: () => {
|
|
64358
|
+
setSelectedLeaderboardDate(currentShiftDate);
|
|
64359
|
+
setSelectedLeaderboardShiftId(currentShiftId);
|
|
64360
|
+
},
|
|
64361
|
+
className: "text-xs sm:text-sm font-medium text-blue-600 bg-blue-50 border border-blue-100 hover:bg-blue-100 hover:text-blue-700 px-3 py-1.5 rounded-lg transition-colors shadow-sm ml-4 whitespace-nowrap",
|
|
64362
|
+
children: "Return to Live"
|
|
64363
|
+
}
|
|
64364
|
+
)
|
|
64365
|
+
] })
|
|
63826
64366
|
] }),
|
|
63827
64367
|
/* @__PURE__ */ jsx("div", { className: "bg-blue-50/50 px-4 py-2 rounded-xl border border-blue-100/50 backdrop-blur-sm", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-6", children: [
|
|
63828
64368
|
!isMonthlyMode && !showHistoricalLeaderboardHeader && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -63892,29 +64432,49 @@ var KPIsOverviewView = ({
|
|
|
63892
64432
|
singleDateOnly: true
|
|
63893
64433
|
}
|
|
63894
64434
|
),
|
|
63895
|
-
/* @__PURE__ */
|
|
63896
|
-
|
|
63897
|
-
|
|
63898
|
-
|
|
63899
|
-
|
|
63900
|
-
|
|
63901
|
-
|
|
63902
|
-
|
|
63903
|
-
|
|
63904
|
-
|
|
63905
|
-
|
|
63906
|
-
|
|
63907
|
-
|
|
63908
|
-
|
|
63909
|
-
|
|
63910
|
-
|
|
63911
|
-
|
|
63912
|
-
|
|
63913
|
-
|
|
63914
|
-
|
|
63915
|
-
|
|
63916
|
-
|
|
63917
|
-
|
|
64435
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
64436
|
+
/* @__PURE__ */ jsxs(
|
|
64437
|
+
"button",
|
|
64438
|
+
{
|
|
64439
|
+
ref: filterButtonRef,
|
|
64440
|
+
onClick: () => setIsFilterOpen(!isFilterOpen),
|
|
64441
|
+
className: `flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-all shadow-sm ${isFilterOpen || activeFiltersCount > 0 ? "bg-blue-50 border-blue-200 text-blue-700" : "bg-white border-gray-200 text-gray-700 hover:bg-gray-50"}`,
|
|
64442
|
+
children: [
|
|
64443
|
+
/* @__PURE__ */ jsx(Filter, { className: "w-4 h-4" }),
|
|
64444
|
+
/* @__PURE__ */ jsx("span", { children: "Filters" }),
|
|
64445
|
+
activeFiltersCount > 0 && /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center w-5 h-5 bg-blue-100 text-blue-700 text-xs rounded-full font-bold ml-1", children: activeFiltersCount }),
|
|
64446
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `w-3 h-3 ml-1 transition-transform ${isFilterOpen ? "rotate-180" : ""}` })
|
|
64447
|
+
]
|
|
64448
|
+
}
|
|
64449
|
+
),
|
|
64450
|
+
isFilterOpen && /* @__PURE__ */ jsxs("div", { ref: filterRef, className: "absolute right-0 top-full mt-2 w-72 bg-white rounded-xl shadow-xl border border-gray-100 p-4 z-50", children: [
|
|
64451
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
64452
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Filter View" }),
|
|
64453
|
+
activeFiltersCount > 0 && /* @__PURE__ */ jsx(
|
|
64454
|
+
"button",
|
|
64455
|
+
{
|
|
64456
|
+
onClick: clearFilters,
|
|
64457
|
+
className: "text-xs text-red-600 hover:text-red-700 font-medium",
|
|
64458
|
+
children: "Clear all"
|
|
64459
|
+
}
|
|
64460
|
+
)
|
|
64461
|
+
] }),
|
|
64462
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
64463
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: "Shift" }),
|
|
64464
|
+
/* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
|
|
64465
|
+
"select",
|
|
64466
|
+
{
|
|
64467
|
+
"aria-label": "Leaderboard shift",
|
|
64468
|
+
value: effectiveLeaderboardShiftId,
|
|
64469
|
+
onChange: (e) => setSelectedLeaderboardShiftId(Number(e.target.value)),
|
|
64470
|
+
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",
|
|
64471
|
+
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` },
|
|
64472
|
+
children: leaderboardShiftOptions.map((shiftOption) => /* @__PURE__ */ jsx("option", { value: shiftOption.id, children: shiftOption.label }, shiftOption.id))
|
|
64473
|
+
}
|
|
64474
|
+
) })
|
|
64475
|
+
] }) })
|
|
64476
|
+
] })
|
|
64477
|
+
] })
|
|
63918
64478
|
] }),
|
|
63919
64479
|
(activeTab === "leaderboard" || activeTab === "today") && showViewTypeDropdown && /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
63920
64480
|
"select",
|
|
@@ -64005,29 +64565,16 @@ var formatCycleTimeValue = (value) => {
|
|
|
64005
64565
|
return `${numericValue.toFixed(1)}s`;
|
|
64006
64566
|
};
|
|
64007
64567
|
var CycleTimeComparison = memo$1(({
|
|
64008
|
-
workspace
|
|
64009
|
-
variant = "table"
|
|
64568
|
+
workspace
|
|
64010
64569
|
}) => {
|
|
64011
64570
|
const averageValue = formatCycleTimeValue(workspace.avg_cycle_time);
|
|
64012
64571
|
const standardValue = formatCycleTimeValue(workspace.ideal_cycle_time);
|
|
64013
|
-
|
|
64014
|
-
|
|
64015
|
-
|
|
64016
|
-
|
|
64017
|
-
] });
|
|
64018
|
-
}
|
|
64019
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64020
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
64021
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Average" }),
|
|
64022
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums text-gray-900", children: averageValue })
|
|
64023
|
-
] }),
|
|
64024
|
-
/* @__PURE__ */ jsx("div", { className: "h-6 w-px bg-gray-200" }),
|
|
64025
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
64026
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-gray-500", children: "Standard" }),
|
|
64027
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums text-gray-500", children: standardValue })
|
|
64028
|
-
] })
|
|
64572
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 tabular-nums", children: [
|
|
64573
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: averageValue }),
|
|
64574
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-400 font-normal", children: "/" }),
|
|
64575
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-500", children: standardValue })
|
|
64029
64576
|
] });
|
|
64030
|
-
}, (prevProps, nextProps) => prevProps.
|
|
64577
|
+
}, (prevProps, nextProps) => prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.ideal_cycle_time === nextProps.workspace.ideal_cycle_time);
|
|
64031
64578
|
CycleTimeComparison.displayName = "CycleTimeComparison";
|
|
64032
64579
|
var IsolatedTimer = memo$1(() => {
|
|
64033
64580
|
return /* @__PURE__ */ jsx(ISTTimer_default, {});
|
|
@@ -64094,7 +64641,7 @@ var MobileWorkspaceCard = memo$1(({
|
|
|
64094
64641
|
getMedalIcon,
|
|
64095
64642
|
metricLabel,
|
|
64096
64643
|
isAssemblyMode
|
|
64097
|
-
}) => /* @__PURE__ */
|
|
64644
|
+
}) => /* @__PURE__ */ jsx(
|
|
64098
64645
|
motion.div,
|
|
64099
64646
|
{
|
|
64100
64647
|
layout: true,
|
|
@@ -64105,28 +64652,25 @@ var MobileWorkspaceCard = memo$1(({
|
|
|
64105
64652
|
},
|
|
64106
64653
|
onClick: isClickable ? () => onWorkspaceClick(workspace, rank) : void 0,
|
|
64107
64654
|
className: `${cardClass} p-3 rounded-lg border shadow-sm active:scale-[0.98] ${isClickable ? "cursor-pointer" : "cursor-not-allowed opacity-75"}`,
|
|
64108
|
-
children: [
|
|
64109
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center
|
|
64110
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
64111
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
64112
|
-
|
|
64113
|
-
|
|
64114
|
-
rank
|
|
64115
|
-
] }),
|
|
64116
|
-
getMedalIcon(rank)
|
|
64655
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2 gap-3", children: [
|
|
64656
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64657
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
64658
|
+
/* @__PURE__ */ jsxs("div", { className: "text-2xl font-bold text-gray-700", children: [
|
|
64659
|
+
"#",
|
|
64660
|
+
rank
|
|
64117
64661
|
] }),
|
|
64118
|
-
|
|
64119
|
-
/* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-900", children: workspace.displayName }),
|
|
64120
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: workspace.lineName })
|
|
64121
|
-
] })
|
|
64662
|
+
getMedalIcon(rank)
|
|
64122
64663
|
] }),
|
|
64123
|
-
/* @__PURE__ */ jsxs("div", {
|
|
64124
|
-
/* @__PURE__ */ jsx("div", { className: "font-
|
|
64125
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children:
|
|
64664
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
64665
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-900", children: workspace.displayName }),
|
|
64666
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: workspace.lineName })
|
|
64126
64667
|
] })
|
|
64127
64668
|
] }),
|
|
64128
|
-
|
|
64129
|
-
|
|
64669
|
+
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
64670
|
+
/* @__PURE__ */ jsx("div", { className: "font-bold text-gray-900 text-lg flex justify-end", children: isAssemblyMode ? /* @__PURE__ */ jsx(CycleTimeComparison, { workspace }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) }),
|
|
64671
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: metricLabel })
|
|
64672
|
+
] })
|
|
64673
|
+
] })
|
|
64130
64674
|
}
|
|
64131
64675
|
), (prevProps, nextProps) => {
|
|
64132
64676
|
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;
|
|
@@ -64156,7 +64700,7 @@ var DesktopWorkspaceRow = memo$1(({
|
|
|
64156
64700
|
] }) }),
|
|
64157
64701
|
/* @__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 }) }),
|
|
64158
64702
|
/* @__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 }) }),
|
|
64159
|
-
/* @__PURE__ */ jsx("td", { className: `px-3 py-2.5 sm:p-4 text-sm sm:text-base font-medium ${isAssemblyMode ? "" : "whitespace-nowrap"}`, children: isAssemblyMode ? /* @__PURE__ */ jsx(CycleTimeComparison, { workspace
|
|
64703
|
+
/* @__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 }) : /* @__PURE__ */ jsx(AnimatedEfficiency, { value: workspace.efficiency || 0 }) })
|
|
64160
64704
|
]
|
|
64161
64705
|
}
|
|
64162
64706
|
), (prevProps, nextProps) => {
|
|
@@ -64283,7 +64827,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64283
64827
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
64284
64828
|
}, []);
|
|
64285
64829
|
const [isMobile, setIsMobile] = useState(false);
|
|
64286
|
-
|
|
64830
|
+
React142__default.useEffect(() => {
|
|
64287
64831
|
const checkMobile = () => setIsMobile(window.innerWidth < 640);
|
|
64288
64832
|
checkMobile();
|
|
64289
64833
|
window.addEventListener("resize", checkMobile);
|
|
@@ -64929,7 +65473,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64929
65473
|
const descendingSortLabel = "Highest to Lowest";
|
|
64930
65474
|
const ascendingSortLabel = "Lowest to Highest";
|
|
64931
65475
|
return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 flex flex-col ${className}`, style: { willChange: "contents" }, children: [
|
|
64932
|
-
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-
|
|
65476
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 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: [
|
|
64933
65477
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
64934
65478
|
mobileMenuContext && /* @__PURE__ */ jsx(
|
|
64935
65479
|
HamburgerButton,
|
|
@@ -64940,7 +65484,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64940
65484
|
),
|
|
64941
65485
|
/* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
64942
65486
|
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900", children: "Leaderboard" }),
|
|
64943
|
-
/* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-emerald-500 animate-pulse ring-2 ring-emerald-500/20" })
|
|
65487
|
+
realtimeEnabled && /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-emerald-500 animate-pulse ring-2 ring-emerald-500/20" })
|
|
64944
65488
|
] }) }),
|
|
64945
65489
|
/* @__PURE__ */ jsx("div", { className: "w-9" })
|
|
64946
65490
|
] }) }),
|
|
@@ -64956,7 +65500,7 @@ var LeaderboardDetailView = memo$1(({
|
|
|
64956
65500
|
) }),
|
|
64957
65501
|
/* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2 max-w-[calc(100%-200px)]", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64958
65502
|
/* @__PURE__ */ jsx("h1", { className: "text-lg md:text-xl lg:text-2xl xl:text-3xl font-semibold text-gray-900 truncate", children: "Leaderboard" }),
|
|
64959
|
-
/* @__PURE__ */ jsxs("div", { className: "relative flex h-2.5 w-2.5", children: [
|
|
65503
|
+
realtimeEnabled && /* @__PURE__ */ jsxs("div", { className: "relative flex h-2.5 w-2.5", children: [
|
|
64960
65504
|
/* @__PURE__ */ jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
|
|
64961
65505
|
/* @__PURE__ */ jsx("span", { className: "relative inline-flex rounded-full h-2.5 w-2.5 bg-green-500" })
|
|
64962
65506
|
] })
|
|
@@ -65454,7 +65998,7 @@ var ProfileView = () => {
|
|
|
65454
65998
|
] }) });
|
|
65455
65999
|
}
|
|
65456
66000
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
65457
|
-
/* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-
|
|
66001
|
+
/* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0", children: [
|
|
65458
66002
|
/* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3", children: [
|
|
65459
66003
|
/* @__PURE__ */ jsxs("div", { className: "sm:hidden flex items-center justify-between", children: [
|
|
65460
66004
|
/* @__PURE__ */ jsx("div", { className: "flex items-center", children: mobileMenuContext && /* @__PURE__ */ jsx(
|
|
@@ -65678,7 +66222,7 @@ var ClipsCostView = () => {
|
|
|
65678
66222
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-screen bg-gray-50", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "lg", message: "Loading usage data..." }) });
|
|
65679
66223
|
}
|
|
65680
66224
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
|
|
65681
|
-
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-
|
|
66225
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b border-gray-200 shadow-sm flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4 w-full", children: [
|
|
65682
66226
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
65683
66227
|
/* @__PURE__ */ jsx("div", { className: "flex items-center", children: mobileMenuContext && /* @__PURE__ */ jsx(
|
|
65684
66228
|
HamburgerButton,
|
|
@@ -66565,7 +67109,7 @@ var ShiftsView = ({
|
|
|
66565
67109
|
}
|
|
66566
67110
|
}, [lineConfigs, recalculateTargetsForShiftHourChanges, supabase, showToast]);
|
|
66567
67111
|
return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 ${className}`, children: [
|
|
66568
|
-
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-
|
|
67112
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 lg:px-8 py-3 sm:py-4", children: [
|
|
66569
67113
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
66570
67114
|
mobileMenuContext && /* @__PURE__ */ jsx(
|
|
66571
67115
|
HamburgerButton,
|
|
@@ -66679,7 +67223,7 @@ var ShiftsView = ({
|
|
|
66679
67223
|
] })
|
|
66680
67224
|
] });
|
|
66681
67225
|
};
|
|
66682
|
-
var AuthenticatedShiftsView = withAuth(
|
|
67226
|
+
var AuthenticatedShiftsView = withAuth(React142__default.memo(ShiftsView));
|
|
66683
67227
|
var ShiftsView_default = ShiftsView;
|
|
66684
67228
|
|
|
66685
67229
|
// src/views/TargetsView.utils.ts
|
|
@@ -68381,7 +68925,7 @@ var TargetsView = ({
|
|
|
68381
68925
|
};
|
|
68382
68926
|
var TargetsViewWithDisplayNames = withAllWorkspaceDisplayNames(TargetsView);
|
|
68383
68927
|
var TargetsView_default = TargetsViewWithDisplayNames;
|
|
68384
|
-
var AuthenticatedTargetsView = withAuth(
|
|
68928
|
+
var AuthenticatedTargetsView = withAuth(React142__default.memo(TargetsViewWithDisplayNames));
|
|
68385
68929
|
function useTimezone(options = {}) {
|
|
68386
68930
|
const dashboardConfig = useDashboardConfig();
|
|
68387
68931
|
const workspaceConfig = useWorkspaceConfig();
|
|
@@ -69187,56 +69731,43 @@ var WorkspaceDetailView = ({
|
|
|
69187
69731
|
const canToggleChartIdleTime = !isUptimeMode && !shouldShowCycleTimeLoadingState && !shouldShowCycleTimeUnavailableState;
|
|
69188
69732
|
const idleClipDate = date || workspace?.date || calculatedOperationalDate || getOperationalDate(timezone);
|
|
69189
69733
|
const idleClipShiftId = parsedShiftId ?? workspace?.shift_id;
|
|
69190
|
-
const
|
|
69191
|
-
|
|
69192
|
-
|
|
69193
|
-
|
|
69194
|
-
|
|
69195
|
-
|
|
69196
|
-
|
|
69197
|
-
|
|
69198
|
-
|
|
69199
|
-
|
|
69200
|
-
|
|
69201
|
-
|
|
69202
|
-
|
|
69203
|
-
|
|
69204
|
-
|
|
69205
|
-
|
|
69206
|
-
|
|
69207
|
-
if (endSlotMins > endTotal) endSlotMins = endTotal;
|
|
69208
|
-
let idleCount = 0;
|
|
69209
|
-
for (let m = startSlotMins; m < endSlotMins; m++) {
|
|
69210
|
-
const hourKey = Math.floor(m / 60) % 24;
|
|
69211
|
-
const minuteKey = m % 60;
|
|
69212
|
-
const hourData = idleTimeHourlyObj[hourKey.toString()] || [];
|
|
69213
|
-
if (Array.isArray(hourData)) {
|
|
69214
|
-
const val = hourData[minuteKey];
|
|
69215
|
-
if (val === 1 || val === "1") {
|
|
69216
|
-
idleCount++;
|
|
69217
|
-
}
|
|
69218
|
-
}
|
|
69219
|
-
}
|
|
69220
|
-
result[i] = idleCount;
|
|
69221
|
-
}
|
|
69222
|
-
return result;
|
|
69223
|
-
}, [shouldShowCycleTimeChart, workspace?.idle_time_hourly, workspace?.shift_start, workspace?.shift_end]);
|
|
69734
|
+
const rawHourlyIdleSlots = useMemo(
|
|
69735
|
+
() => !shouldShowCycleTimeChart || !authoritativeCycleMetrics?.shift_start ? [] : buildHourlyIdleSlots({
|
|
69736
|
+
idleTimeHourly: authoritativeCycleMetrics.idle_time_hourly,
|
|
69737
|
+
shiftStart: authoritativeCycleMetrics.shift_start,
|
|
69738
|
+
shiftEnd: authoritativeCycleMetrics.shift_end
|
|
69739
|
+
}),
|
|
69740
|
+
[
|
|
69741
|
+
shouldShowCycleTimeChart,
|
|
69742
|
+
authoritativeCycleMetrics?.idle_time_hourly,
|
|
69743
|
+
authoritativeCycleMetrics?.shift_start,
|
|
69744
|
+
authoritativeCycleMetrics?.shift_end
|
|
69745
|
+
]
|
|
69746
|
+
);
|
|
69747
|
+
const rawHourlyIdleMinutes = useMemo(
|
|
69748
|
+
() => rawHourlyIdleSlots.map((slot) => slot.idleMinutes),
|
|
69749
|
+
[rawHourlyIdleSlots]
|
|
69750
|
+
);
|
|
69224
69751
|
const hourlyIdleMinutes = useMemo(
|
|
69225
69752
|
() => maskFutureHourlySeries({
|
|
69226
69753
|
data: rawHourlyIdleMinutes,
|
|
69227
|
-
shiftStart:
|
|
69228
|
-
shiftEnd:
|
|
69754
|
+
shiftStart: authoritativeCycleMetrics?.shift_start,
|
|
69755
|
+
shiftEnd: authoritativeCycleMetrics?.shift_end,
|
|
69229
69756
|
shiftDate: idleClipDate,
|
|
69230
69757
|
timezone: effectiveCycleTimeTimezone
|
|
69231
69758
|
}),
|
|
69232
69759
|
[
|
|
69233
69760
|
rawHourlyIdleMinutes,
|
|
69234
|
-
|
|
69235
|
-
|
|
69761
|
+
authoritativeCycleMetrics?.shift_start,
|
|
69762
|
+
authoritativeCycleMetrics?.shift_end,
|
|
69236
69763
|
idleClipDate,
|
|
69237
69764
|
effectiveCycleTimeTimezone
|
|
69238
69765
|
]
|
|
69239
69766
|
);
|
|
69767
|
+
const hourlyIdleSlots = useMemo(
|
|
69768
|
+
() => rawHourlyIdleSlots.map((slot, index) => hourlyIdleMinutes[index] === null ? null : slot),
|
|
69769
|
+
[rawHourlyIdleSlots, hourlyIdleMinutes]
|
|
69770
|
+
);
|
|
69240
69771
|
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: [
|
|
69241
69772
|
/* @__PURE__ */ jsx("h4", { className: "text-base font-semibold text-amber-900", children: "Cycle data unavailable" }),
|
|
69242
69773
|
/* @__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." }),
|
|
@@ -69403,7 +69934,7 @@ var WorkspaceDetailView = ({
|
|
|
69403
69934
|
animate: { opacity: 1 },
|
|
69404
69935
|
transition: { duration: 0.3 },
|
|
69405
69936
|
children: /* @__PURE__ */ jsxs("div", { className: "min-h-screen w-full flex flex-col bg-slate-50", children: [
|
|
69406
|
-
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-
|
|
69937
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 px-3 sm:px-4 md:px-5 lg:px-6 py-2 sm:py-2.5 lg:py-3 flex flex-col shadow-sm bg-white", children: /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
|
|
69407
69938
|
/* @__PURE__ */ jsx("div", { className: "absolute left-0 animate-pulse", children: /* @__PURE__ */ jsx("div", { className: "h-6 sm:h-7 md:h-8 w-16 sm:w-20 bg-gray-200 rounded" }) }),
|
|
69408
69939
|
/* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2 animate-pulse max-w-[calc(100%-160px)] sm:max-w-[calc(100%-200px)]", children: /* @__PURE__ */ jsx("div", { className: "h-5 sm:h-6 md:h-7 w-28 sm:w-36 md:w-40 bg-gray-200 rounded" }) }),
|
|
69409
69940
|
/* @__PURE__ */ jsx("div", { className: "w-full h-8" })
|
|
@@ -69465,7 +69996,7 @@ var WorkspaceDetailView = ({
|
|
|
69465
69996
|
initial: { opacity: 1 },
|
|
69466
69997
|
animate: { opacity: 1 },
|
|
69467
69998
|
children: /* @__PURE__ */ jsxs("div", { className: "min-h-screen w-full flex flex-col bg-slate-50", children: [
|
|
69468
|
-
/* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-
|
|
69999
|
+
/* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-40 px-3 sm:px-4 md:px-5 lg:px-6 py-3 sm:py-3 lg:py-3.5 flex flex-col shadow-sm bg-white", children: [
|
|
69469
70000
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
69470
70001
|
/* @__PURE__ */ jsx(
|
|
69471
70002
|
"button",
|
|
@@ -69792,7 +70323,8 @@ var WorkspaceDetailView = ({
|
|
|
69792
70323
|
xAxisMode: "hourly",
|
|
69793
70324
|
datasetKey: cycleTimeDatasetKey,
|
|
69794
70325
|
showIdleTime: showChartIdleTime,
|
|
69795
|
-
idleTimeData: hourlyIdleMinutes
|
|
70326
|
+
idleTimeData: hourlyIdleMinutes,
|
|
70327
|
+
idleTimeSlots: hourlyIdleSlots
|
|
69796
70328
|
}
|
|
69797
70329
|
) : null : /* @__PURE__ */ jsx(
|
|
69798
70330
|
HourlyOutputChart2,
|
|
@@ -69921,7 +70453,8 @@ var WorkspaceDetailView = ({
|
|
|
69921
70453
|
xAxisMode: "hourly",
|
|
69922
70454
|
datasetKey: cycleTimeDatasetKey,
|
|
69923
70455
|
showIdleTime: showChartIdleTime,
|
|
69924
|
-
idleTimeData: hourlyIdleMinutes
|
|
70456
|
+
idleTimeData: hourlyIdleMinutes,
|
|
70457
|
+
idleTimeSlots: hourlyIdleSlots
|
|
69925
70458
|
}
|
|
69926
70459
|
) : null : /* @__PURE__ */ jsx(
|
|
69927
70460
|
HourlyOutputChart2,
|
|
@@ -70141,7 +70674,7 @@ var SKUManagementView = () => {
|
|
|
70141
70674
|
] }) });
|
|
70142
70675
|
}
|
|
70143
70676
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-slate-50", children: [
|
|
70144
|
-
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-
|
|
70677
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-4 md:px-6 lg:px-8 py-3 sm:py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 sm:gap-4 relative", children: [
|
|
70145
70678
|
/* @__PURE__ */ jsx("div", { className: "sm:absolute sm:left-0", children: /* @__PURE__ */ jsx(
|
|
70146
70679
|
BackButtonMinimal,
|
|
70147
70680
|
{
|
|
@@ -70279,8 +70812,29 @@ var useWorkspaceHealth = (options) => {
|
|
|
70279
70812
|
date: options.date,
|
|
70280
70813
|
shiftId: options.shiftId
|
|
70281
70814
|
});
|
|
70282
|
-
|
|
70283
|
-
|
|
70815
|
+
let cameraIpMap = {};
|
|
70816
|
+
const workspaceIds = workspacesWithStatus.map((workspace) => workspace.workspace_id).filter(Boolean);
|
|
70817
|
+
if (workspaceIds.length > 0) {
|
|
70818
|
+
try {
|
|
70819
|
+
cameraIpMap = await workspaceService.getWorkspaceCameraIps({ workspaceIds });
|
|
70820
|
+
} catch (cameraError) {
|
|
70821
|
+
console.error("[useWorkspaceHealth] Error fetching camera IPs:", cameraError);
|
|
70822
|
+
}
|
|
70823
|
+
}
|
|
70824
|
+
const workspacesWithCameraIps = workspacesWithStatus.map((workspace) => {
|
|
70825
|
+
const cameraInfo = cameraIpMap[workspace.workspace_id];
|
|
70826
|
+
if (!cameraInfo) {
|
|
70827
|
+
return workspace;
|
|
70828
|
+
}
|
|
70829
|
+
return {
|
|
70830
|
+
...workspace,
|
|
70831
|
+
cameraIp: cameraInfo.camera_ip ?? null,
|
|
70832
|
+
cameraResolutionMode: cameraInfo.resolution_mode ?? null,
|
|
70833
|
+
effectiveCameraUuid: cameraInfo.effective_camera_uuid ?? null
|
|
70834
|
+
};
|
|
70835
|
+
});
|
|
70836
|
+
setWorkspaces(workspacesWithCameraIps);
|
|
70837
|
+
setSummary(computeSummary(workspacesWithCameraIps));
|
|
70284
70838
|
} catch (err) {
|
|
70285
70839
|
console.error("[useWorkspaceHealth] Error fetching workspace health:", err);
|
|
70286
70840
|
setError({ message: err.message, code: err.code || "FETCH_ERROR" });
|
|
@@ -70646,7 +71200,7 @@ var WorkspaceUptimeDetailModal = ({
|
|
|
70646
71200
|
role: "document",
|
|
70647
71201
|
"aria-labelledby": "uptime-detail-title",
|
|
70648
71202
|
children: [
|
|
70649
|
-
/* @__PURE__ */ jsxs("header", { className: "flex items-start justify-between border-b border-gray-100 px-8 py-6 sticky top-0 z-
|
|
71203
|
+
/* @__PURE__ */ jsxs("header", { className: "flex items-start justify-between border-b border-gray-100 px-8 py-6 sticky top-0 z-40 bg-white rounded-t-2xl", children: [
|
|
70650
71204
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 mr-4", children: [
|
|
70651
71205
|
/* @__PURE__ */ jsx("h2", { id: "uptime-detail-title", className: "text-2xl font-semibold text-gray-900 truncate mb-3", children: workspace.workspace_display_name || `Workspace ${workspace.workspace_id.slice(0, 6)}` }),
|
|
70652
71206
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 text-sm text-gray-600", children: [
|
|
@@ -70656,7 +71210,7 @@ var WorkspaceUptimeDetailModal = ({
|
|
|
70656
71210
|
/* @__PURE__ */ jsx("span", { className: "text-gray-600", children: formatTimeRange(shiftStart, shiftEnd, timezone) })
|
|
70657
71211
|
] })
|
|
70658
71212
|
] }),
|
|
70659
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-2", children: [
|
|
71213
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2", children: [
|
|
70660
71214
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
70661
71215
|
/* @__PURE__ */ jsx("div", { className: `w-2 h-2 rounded-full ${workspace.status === "healthy" ? "bg-emerald-500 animate-pulse" : workspace.status === "warning" ? "bg-amber-500" : "bg-rose-500"}` }),
|
|
70662
71216
|
/* @__PURE__ */ jsx("span", { className: `text-xs font-medium ${workspace.status === "healthy" ? "text-emerald-700" : workspace.status === "warning" ? "text-amber-700" : "text-rose-700"}`, children: workspace.status === "healthy" ? "Operational" : workspace.status === "warning" ? "Intermittent" : "Down" })
|
|
@@ -70665,6 +71219,13 @@ var WorkspaceUptimeDetailModal = ({
|
|
|
70665
71219
|
/* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500", children: [
|
|
70666
71220
|
"Last heartbeat ",
|
|
70667
71221
|
workspace.timeSinceLastUpdate
|
|
71222
|
+
] }),
|
|
71223
|
+
workspace.cameraIp && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
71224
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-300 hidden sm:inline", children: "\u2022" }),
|
|
71225
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 bg-slate-50 dark:bg-slate-800/50 px-2 py-0.5 rounded border border-slate-100 dark:border-slate-700/50 group", title: "Camera IP", children: [
|
|
71226
|
+
/* @__PURE__ */ jsx(Video, { className: "h-3 w-3 text-slate-400" }),
|
|
71227
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-slate-600 dark:text-slate-300 select-all", children: workspace.cameraIp })
|
|
71228
|
+
] })
|
|
70668
71229
|
] })
|
|
70669
71230
|
] })
|
|
70670
71231
|
] }),
|
|
@@ -70866,7 +71427,7 @@ var WorkspaceHealthView = ({
|
|
|
70866
71427
|
}
|
|
70867
71428
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
70868
71429
|
/* @__PURE__ */ jsxs("div", { className: clsx("min-h-screen bg-slate-50", className), children: [
|
|
70869
|
-
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-
|
|
71430
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b border-gray-200 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4", children: [
|
|
70870
71431
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
70871
71432
|
mobileMenuContext && /* @__PURE__ */ jsx(
|
|
70872
71433
|
HamburgerButton,
|
|
@@ -71200,7 +71761,7 @@ var SupervisorManagementView = ({
|
|
|
71200
71761
|
) }) });
|
|
71201
71762
|
}
|
|
71202
71763
|
return /* @__PURE__ */ jsxs("div", { className: clsx("min-h-screen bg-slate-50", className), children: [
|
|
71203
|
-
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-
|
|
71764
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-4 md:px-6 lg:px-8 py-3 sm:py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center relative", children: [
|
|
71204
71765
|
/* @__PURE__ */ jsx("div", { className: "sm:absolute sm:left-0", children: /* @__PURE__ */ jsx(
|
|
71205
71766
|
BackButtonMinimal,
|
|
71206
71767
|
{
|
|
@@ -71622,7 +72183,7 @@ var TeamManagementView = ({
|
|
|
71622
72183
|
) }) });
|
|
71623
72184
|
}
|
|
71624
72185
|
return /* @__PURE__ */ jsxs("div", { className: cn("min-h-screen bg-slate-50", className), children: [
|
|
71625
|
-
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-
|
|
72186
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-40 bg-white border-b border-gray-200 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 lg:px-8 py-3 sm:py-4", children: [
|
|
71626
72187
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
71627
72188
|
mobileMenuContext && /* @__PURE__ */ jsx(
|
|
71628
72189
|
HamburgerButton,
|
|
@@ -71766,7 +72327,7 @@ function BottleneckClipsView({
|
|
|
71766
72327
|
) })
|
|
71767
72328
|
] }) });
|
|
71768
72329
|
}
|
|
71769
|
-
var AuthenticatedBottleneckClipsView = withAuth(
|
|
72330
|
+
var AuthenticatedBottleneckClipsView = withAuth(React142__default.memo(BottleneckClipsView));
|
|
71770
72331
|
var BottleneckClipsView_default = BottleneckClipsView;
|
|
71771
72332
|
|
|
71772
72333
|
// src/lib/services/ticketService.ts
|
|
@@ -72597,7 +73158,7 @@ Please ensure:
|
|
|
72597
73158
|
)
|
|
72598
73159
|
] });
|
|
72599
73160
|
}
|
|
72600
|
-
var AuthenticatedTicketsView = withAuth(
|
|
73161
|
+
var AuthenticatedTicketsView = withAuth(React142__default.memo(TicketsView));
|
|
72601
73162
|
var TicketsView_default = TicketsView;
|
|
72602
73163
|
|
|
72603
73164
|
// src/lib/utils/improvementDisplay.ts
|
|
@@ -72927,6 +73488,18 @@ var buildInitials = (name) => {
|
|
|
72927
73488
|
const second = parts.length > 1 ? parts[1]?.[0] || "" : "";
|
|
72928
73489
|
return `${first}${second}`.toUpperCase();
|
|
72929
73490
|
};
|
|
73491
|
+
var getRecommendationAssignedUserIds = (recommendation) => {
|
|
73492
|
+
if (Array.isArray(recommendation.assigned_user_ids) && recommendation.assigned_user_ids.length > 0) {
|
|
73493
|
+
return recommendation.assigned_user_ids.filter(
|
|
73494
|
+
(userId) => typeof userId === "string" && userId.trim().length > 0
|
|
73495
|
+
);
|
|
73496
|
+
}
|
|
73497
|
+
return recommendation.assigned_to_user_id ? [recommendation.assigned_to_user_id] : [];
|
|
73498
|
+
};
|
|
73499
|
+
var recommendationMatchesMember = (recommendation, memberId) => {
|
|
73500
|
+
if (memberId === "all") return true;
|
|
73501
|
+
return getRecommendationAssignedUserIds(recommendation).includes(memberId);
|
|
73502
|
+
};
|
|
72930
73503
|
var getQueryParam = (value) => {
|
|
72931
73504
|
if (typeof value === "string") {
|
|
72932
73505
|
const trimmed = value.trim();
|
|
@@ -73021,7 +73594,6 @@ var ClipVideoCarousel = ({ clips, clipsService }) => {
|
|
|
73021
73594
|
currentVideo.cycle_time_seconds.toFixed(1),
|
|
73022
73595
|
"s"
|
|
73023
73596
|
] }),
|
|
73024
|
-
!loading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none group-hover:opacity-0 transition-opacity", children: /* @__PURE__ */ jsx(PlayCircleIcon, { className: "w-16 h-16 text-white opacity-80" }) }),
|
|
73025
73597
|
videos.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
73026
73598
|
/* @__PURE__ */ jsx(
|
|
73027
73599
|
"button",
|
|
@@ -73418,10 +73990,7 @@ var ImprovementCenterView = () => {
|
|
|
73418
73990
|
if (!supabase || !companyId) return;
|
|
73419
73991
|
try {
|
|
73420
73992
|
const userService2 = createUserManagementService(supabase);
|
|
73421
|
-
const users = await userService2.getCompanyUsers(
|
|
73422
|
-
companyId,
|
|
73423
|
-
"supervisor,owner,industrial_engineer"
|
|
73424
|
-
);
|
|
73993
|
+
const users = await userService2.getCompanyUsers(companyId);
|
|
73425
73994
|
if (cancelled) return;
|
|
73426
73995
|
const membersById = /* @__PURE__ */ new Map();
|
|
73427
73996
|
users.forEach((user2) => {
|
|
@@ -73525,18 +74094,8 @@ var ImprovementCenterView = () => {
|
|
|
73525
74094
|
const teamMembersById = useMemo(() => {
|
|
73526
74095
|
return new Map(teamMembers.map((member) => [member.id, member]));
|
|
73527
74096
|
}, [teamMembers]);
|
|
73528
|
-
const
|
|
73529
|
-
|
|
73530
|
-
return getImprovementDisplayMetadata({
|
|
73531
|
-
location: rec.location,
|
|
73532
|
-
line: rec.line,
|
|
73533
|
-
workspaceId: rec.workspace_id,
|
|
73534
|
-
supervisors
|
|
73535
|
-
});
|
|
73536
|
-
}, [supervisorsByLineId]);
|
|
73537
|
-
const filteredRecommendations = useMemo(() => {
|
|
73538
|
-
const hasActiveFilters = selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedSortBy !== "all";
|
|
73539
|
-
const sortedRecommendations = recommendations.filter((rec) => {
|
|
74097
|
+
const recommendationsMatchingViewFilters = useMemo(() => {
|
|
74098
|
+
return recommendations.filter((rec) => {
|
|
73540
74099
|
if (selectedLineId !== "all" && rec.line_id !== selectedLineId) return false;
|
|
73541
74100
|
if (selectedStatus === "resolved" && rec.ticket_status !== "solved") return false;
|
|
73542
74101
|
if (selectedStatus === "unresolved" && rec.ticket_status === "solved") return false;
|
|
@@ -73547,9 +74106,41 @@ var ImprovementCenterView = () => {
|
|
|
73547
74106
|
if (selectedWeeksRange === "2" && weeks !== 2) return false;
|
|
73548
74107
|
if (selectedWeeksRange === "3+" && weeks < 3) return false;
|
|
73549
74108
|
}
|
|
73550
|
-
if (selectedMemberId !== "all" && !(rec.assigned_user_ids?.includes(selectedMemberId) || rec.assigned_to_user_id === selectedMemberId)) return false;
|
|
73551
74109
|
return true;
|
|
73552
|
-
})
|
|
74110
|
+
});
|
|
74111
|
+
}, [recommendations, selectedLineId, selectedShift, selectedStatus, selectedWeeksRange]);
|
|
74112
|
+
const memberOptions = useMemo(() => {
|
|
74113
|
+
const uniqueAssigneeIds = /* @__PURE__ */ new Set();
|
|
74114
|
+
recommendationsMatchingViewFilters.forEach((recommendation) => {
|
|
74115
|
+
getRecommendationAssignedUserIds(recommendation).forEach((userId) => {
|
|
74116
|
+
uniqueAssigneeIds.add(userId);
|
|
74117
|
+
});
|
|
74118
|
+
});
|
|
74119
|
+
const options = Array.from(uniqueAssigneeIds).map((userId) => ({
|
|
74120
|
+
id: userId,
|
|
74121
|
+
label: teamMembersById.get(userId)?.name || userId
|
|
74122
|
+
})).sort((left, right) => left.label.localeCompare(right.label));
|
|
74123
|
+
return [{ id: "all", label: "All Members" }, ...options];
|
|
74124
|
+
}, [recommendationsMatchingViewFilters, teamMembersById]);
|
|
74125
|
+
useEffect(() => {
|
|
74126
|
+
if (selectedMemberId === "all") return;
|
|
74127
|
+
const memberStillAvailable = memberOptions.some((option) => option.id === selectedMemberId);
|
|
74128
|
+
if (!memberStillAvailable) {
|
|
74129
|
+
setSelectedMemberId("all");
|
|
74130
|
+
}
|
|
74131
|
+
}, [memberOptions, selectedMemberId]);
|
|
74132
|
+
const getRecommendationDisplayMetadata = React142__default.useCallback((rec) => {
|
|
74133
|
+
const supervisors = rec.line_id ? supervisorsByLineId.get(rec.line_id) || [] : [];
|
|
74134
|
+
return getImprovementDisplayMetadata({
|
|
74135
|
+
location: rec.location,
|
|
74136
|
+
line: rec.line,
|
|
74137
|
+
workspaceId: rec.workspace_id,
|
|
74138
|
+
supervisors
|
|
74139
|
+
});
|
|
74140
|
+
}, [supervisorsByLineId]);
|
|
74141
|
+
const filteredRecommendations = useMemo(() => {
|
|
74142
|
+
const hasActiveFilters = selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" || selectedSortBy !== "all";
|
|
74143
|
+
const sortedRecommendations = recommendationsMatchingViewFilters.filter((rec) => recommendationMatchesMember(rec, selectedMemberId)).sort((a, b) => {
|
|
73553
74144
|
if (selectedSortBy === "highest_to_lowest" || selectedSortBy === "lowest_to_highest") {
|
|
73554
74145
|
const gainA = getImprovementPcsGainSortValue(a);
|
|
73555
74146
|
const gainB = getImprovementPcsGainSortValue(b);
|
|
@@ -73580,12 +74171,8 @@ var ImprovementCenterView = () => {
|
|
|
73580
74171
|
];
|
|
73581
74172
|
}, [
|
|
73582
74173
|
focusIssueId,
|
|
73583
|
-
|
|
73584
|
-
selectedLineId,
|
|
74174
|
+
recommendationsMatchingViewFilters,
|
|
73585
74175
|
selectedMemberId,
|
|
73586
|
-
selectedShift,
|
|
73587
|
-
selectedStatus,
|
|
73588
|
-
selectedWeeksRange,
|
|
73589
74176
|
selectedSortBy
|
|
73590
74177
|
]);
|
|
73591
74178
|
const stats = useMemo(() => {
|
|
@@ -73598,7 +74185,7 @@ var ImprovementCenterView = () => {
|
|
|
73598
74185
|
if (selectedWeeksRange === "2" && weeks !== 2) return false;
|
|
73599
74186
|
if (selectedWeeksRange === "3+" && weeks < 3) return false;
|
|
73600
74187
|
}
|
|
73601
|
-
if (
|
|
74188
|
+
if (!recommendationMatchesMember(rec, selectedMemberId)) return false;
|
|
73602
74189
|
return true;
|
|
73603
74190
|
});
|
|
73604
74191
|
const total = baseFiltered.length;
|
|
@@ -73777,7 +74364,7 @@ var ImprovementCenterView = () => {
|
|
|
73777
74364
|
{ value: selectedSortBy, onChange: handleSortByChange, options: [{ id: "all", label: "All" }, { id: "highest_to_lowest", label: "Highest to Lowest" }, { id: "lowest_to_highest", label: "Lowest to Highest" }], label: "Priority" },
|
|
73778
74365
|
{ value: selectedShift, onChange: handleShiftFilterChange, options: shiftOptions, label: "Shift" },
|
|
73779
74366
|
{ value: selectedWeeksRange, onChange: handleWeeksFilterChange, options: weekOptions.map((o) => o.id), labels: weekOptions, label: "Duration" },
|
|
73780
|
-
{ value: selectedMemberId, onChange: handleMemberFilterChange, options:
|
|
74367
|
+
{ value: selectedMemberId, onChange: handleMemberFilterChange, options: memberOptions, label: "Member" },
|
|
73781
74368
|
{ value: selectedLineId, onChange: handleLineFilterChange, options: lineOptions.map((o) => o.id), labels: lineOptions, label: "Line" }
|
|
73782
74369
|
].map((filter2, idx) => /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
73783
74370
|
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-gray-500 uppercase tracking-wide ml-1", children: filter2.label }),
|
|
@@ -73786,6 +74373,7 @@ var ImprovementCenterView = () => {
|
|
|
73786
74373
|
{
|
|
73787
74374
|
value: filter2.value,
|
|
73788
74375
|
onChange: (e) => filter2.onChange(e.target.value),
|
|
74376
|
+
"aria-label": `${filter2.label} filter`,
|
|
73789
74377
|
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",
|
|
73790
74378
|
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` },
|
|
73791
74379
|
children: filter2.options.map((opt) => {
|
|
@@ -74015,7 +74603,7 @@ var ThreadSidebar = ({
|
|
|
74015
74603
|
] }) })
|
|
74016
74604
|
] });
|
|
74017
74605
|
};
|
|
74018
|
-
var ProfilePicture =
|
|
74606
|
+
var ProfilePicture = React142__default.memo(({
|
|
74019
74607
|
alt = "Axel",
|
|
74020
74608
|
className = "",
|
|
74021
74609
|
size = "md",
|
|
@@ -75628,7 +76216,7 @@ var AIAgentView = () => {
|
|
|
75628
76216
|
`
|
|
75629
76217
|
} }),
|
|
75630
76218
|
/* @__PURE__ */ jsxs("div", { className: `flex-1 flex flex-col h-screen transition-all duration-300 ${isSidebarOpen ? "lg:mr-80 mr-0" : "mr-0"}`, children: [
|
|
75631
|
-
/* @__PURE__ */ jsxs("header", { className: "flex-shrink-0 bg-white px-3 sm:px-6 md:px-8 py-2 sm:py-5 md:py-6 shadow-sm border-b border-gray-200/80 sticky top-0 z-
|
|
76219
|
+
/* @__PURE__ */ jsxs("header", { className: "flex-shrink-0 bg-white px-3 sm:px-6 md:px-8 py-2 sm:py-5 md:py-6 shadow-sm border-b border-gray-200/80 sticky top-0 z-40", children: [
|
|
75632
76220
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
75633
76221
|
mobileMenuContext && /* @__PURE__ */ jsx(
|
|
75634
76222
|
HamburgerButton,
|
|
@@ -76540,7 +77128,7 @@ var OverviewImprovementsSkeleton = () => /* @__PURE__ */ jsx("div", { className:
|
|
|
76540
77128
|
] }),
|
|
76541
77129
|
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end flex-shrink-0 ml-4", children: /* @__PURE__ */ jsx(SectionPulse, { className: "h-6 w-20 rounded-full" }) })
|
|
76542
77130
|
] }, index)) });
|
|
76543
|
-
var OperationsOverviewHeader =
|
|
77131
|
+
var OperationsOverviewHeader = React142__default.memo(({
|
|
76544
77132
|
dateRange,
|
|
76545
77133
|
displayDateRange,
|
|
76546
77134
|
trendMode,
|
|
@@ -76560,65 +77148,65 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76560
77148
|
bumpRenderCounter();
|
|
76561
77149
|
const subtitleRange = displayDateRange || dateRange;
|
|
76562
77150
|
const showLiveShiftMeta = isLiveScope && trendMode !== "all";
|
|
76563
|
-
const liveShiftLabel =
|
|
77151
|
+
const liveShiftLabel = React142__default.useMemo(
|
|
76564
77152
|
() => normalizeShiftLabel(liveShiftName, trendMode),
|
|
76565
77153
|
[liveShiftName, trendMode]
|
|
76566
77154
|
);
|
|
76567
|
-
const liveShiftIcon =
|
|
77155
|
+
const liveShiftIcon = React142__default.useMemo(
|
|
76568
77156
|
() => getShiftIcon(liveShiftName, trendMode),
|
|
76569
77157
|
[liveShiftName, trendMode]
|
|
76570
77158
|
);
|
|
76571
|
-
const [isFilterOpen, setIsFilterOpen] =
|
|
76572
|
-
const [isLinesDropdownOpen, setIsLinesDropdownOpen] =
|
|
76573
|
-
const filterRef =
|
|
76574
|
-
const filterButtonRef =
|
|
76575
|
-
const mobileFilterButtonRef =
|
|
76576
|
-
const linesDropdownRef =
|
|
76577
|
-
const mobileSubtitle =
|
|
77159
|
+
const [isFilterOpen, setIsFilterOpen] = React142__default.useState(false);
|
|
77160
|
+
const [isLinesDropdownOpen, setIsLinesDropdownOpen] = React142__default.useState(false);
|
|
77161
|
+
const filterRef = React142__default.useRef(null);
|
|
77162
|
+
const filterButtonRef = React142__default.useRef(null);
|
|
77163
|
+
const mobileFilterButtonRef = React142__default.useRef(null);
|
|
77164
|
+
const linesDropdownRef = React142__default.useRef(null);
|
|
77165
|
+
const mobileSubtitle = React142__default.useMemo(() => {
|
|
76578
77166
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
76579
77167
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMM, yyyy");
|
|
76580
77168
|
}
|
|
76581
77169
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMM")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMM, yyyy")}`;
|
|
76582
77170
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
76583
|
-
const desktopSubtitle =
|
|
77171
|
+
const desktopSubtitle = React142__default.useMemo(() => {
|
|
76584
77172
|
if (subtitleRange.startKey === subtitleRange.endKey) {
|
|
76585
77173
|
return format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy");
|
|
76586
77174
|
}
|
|
76587
77175
|
return `${format(parseDateKeyToDate(subtitleRange.startKey), "do MMMM, yyyy")} - ${format(parseDateKeyToDate(subtitleRange.endKey), "do MMMM, yyyy")}`;
|
|
76588
77176
|
}, [subtitleRange.endKey, subtitleRange.startKey]);
|
|
76589
|
-
const availableLineIds =
|
|
77177
|
+
const availableLineIds = React142__default.useMemo(
|
|
76590
77178
|
() => lineOptions.map((line) => line.id),
|
|
76591
77179
|
[lineOptions]
|
|
76592
77180
|
);
|
|
76593
|
-
const selectedLineIdSet =
|
|
77181
|
+
const selectedLineIdSet = React142__default.useMemo(
|
|
76594
77182
|
() => new Set(selectedLineIds),
|
|
76595
77183
|
[selectedLineIds]
|
|
76596
77184
|
);
|
|
76597
|
-
const isAllLinesSelected =
|
|
77185
|
+
const isAllLinesSelected = React142__default.useMemo(() => {
|
|
76598
77186
|
if (availableLineIds.length === 0) return true;
|
|
76599
77187
|
return availableLineIds.every((lineId) => selectedLineIdSet.has(lineId));
|
|
76600
77188
|
}, [availableLineIds, selectedLineIdSet]);
|
|
76601
|
-
const activeFilterCount =
|
|
77189
|
+
const activeFilterCount = React142__default.useMemo(() => {
|
|
76602
77190
|
let count = 0;
|
|
76603
77191
|
if (trendMode !== "all") count += 1;
|
|
76604
77192
|
if (selectedSupervisorId !== "all") count += 1;
|
|
76605
77193
|
if (!isAllLinesSelected) count += 1;
|
|
76606
77194
|
return count;
|
|
76607
77195
|
}, [isAllLinesSelected, selectedSupervisorId, trendMode]);
|
|
76608
|
-
const handleFilterToggle =
|
|
77196
|
+
const handleFilterToggle = React142__default.useCallback(() => {
|
|
76609
77197
|
trackCoreEvent("Operations Overview Filter Toggled", {
|
|
76610
77198
|
action: !isFilterOpen ? "open" : "close"
|
|
76611
77199
|
});
|
|
76612
77200
|
setIsFilterOpen((previous) => !previous);
|
|
76613
77201
|
}, [isFilterOpen]);
|
|
76614
|
-
const handleTrendModeChange =
|
|
77202
|
+
const handleTrendModeChange = React142__default.useCallback((event) => {
|
|
76615
77203
|
const nextMode = event.target.value;
|
|
76616
77204
|
trackCoreEvent("Operations Overview Shift Filter Changed", {
|
|
76617
77205
|
shift_mode: nextMode
|
|
76618
77206
|
});
|
|
76619
77207
|
onTrendModeChange(nextMode);
|
|
76620
77208
|
}, [onTrendModeChange]);
|
|
76621
|
-
const handleAllLinesToggle =
|
|
77209
|
+
const handleAllLinesToggle = React142__default.useCallback(() => {
|
|
76622
77210
|
trackCoreEvent("Operations Overview Line Filter Changed", {
|
|
76623
77211
|
selected_line_ids: availableLineIds,
|
|
76624
77212
|
selected_line_count: availableLineIds.length,
|
|
@@ -76626,7 +77214,7 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76626
77214
|
});
|
|
76627
77215
|
onSelectedLineIdsChange(availableLineIds);
|
|
76628
77216
|
}, [availableLineIds, onSelectedLineIdsChange]);
|
|
76629
|
-
const handleSupervisorChange =
|
|
77217
|
+
const handleSupervisorChange = React142__default.useCallback((event) => {
|
|
76630
77218
|
const supervisorId = event.target.value;
|
|
76631
77219
|
const selectedSupervisor = supervisorOptions.find((option) => option.id === supervisorId);
|
|
76632
77220
|
trackCoreEvent("Operations Overview Supervisor Filter Changed", {
|
|
@@ -76637,7 +77225,7 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76637
77225
|
});
|
|
76638
77226
|
onSelectedSupervisorIdChange(supervisorId);
|
|
76639
77227
|
}, [availableLineIds, onSelectedSupervisorIdChange, supervisorOptions]);
|
|
76640
|
-
const handleLineToggle =
|
|
77228
|
+
const handleLineToggle = React142__default.useCallback((lineId) => {
|
|
76641
77229
|
const current = new Set(selectedLineIds);
|
|
76642
77230
|
if (current.has(lineId)) {
|
|
76643
77231
|
if (current.size <= 1) return;
|
|
@@ -76653,13 +77241,13 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76653
77241
|
});
|
|
76654
77242
|
onSelectedLineIdsChange(next);
|
|
76655
77243
|
}, [availableLineIds, onSelectedLineIdsChange, selectedLineIds]);
|
|
76656
|
-
const handleClearAllFilters =
|
|
77244
|
+
const handleClearAllFilters = React142__default.useCallback(() => {
|
|
76657
77245
|
onTrendModeChange("all");
|
|
76658
77246
|
onSelectedSupervisorIdChange("all");
|
|
76659
77247
|
onSelectedLineIdsChange(availableLineIds);
|
|
76660
77248
|
setIsFilterOpen(false);
|
|
76661
77249
|
}, [availableLineIds, onSelectedLineIdsChange, onSelectedSupervisorIdChange, onTrendModeChange]);
|
|
76662
|
-
|
|
77250
|
+
React142__default.useEffect(() => {
|
|
76663
77251
|
const handleClickOutside = (event) => {
|
|
76664
77252
|
const target = event.target;
|
|
76665
77253
|
if (filterRef.current && !filterRef.current.contains(target) && filterButtonRef.current && !filterButtonRef.current.contains(target) && mobileFilterButtonRef.current && !mobileFilterButtonRef.current.contains(target)) {
|
|
@@ -76674,7 +77262,7 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76674
77262
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
76675
77263
|
};
|
|
76676
77264
|
}, []);
|
|
76677
|
-
return /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-
|
|
77265
|
+
return /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-40 bg-white border-b flex-shrink-0 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-4 md:px-6 py-2 sm:py-3 relative", children: [
|
|
76678
77266
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
76679
77267
|
mobileMenuContext ? /* @__PURE__ */ jsx(
|
|
76680
77268
|
HamburgerButton,
|
|
@@ -76898,12 +77486,12 @@ var OperationsOverviewHeader = React141__default.memo(({
|
|
|
76898
77486
|
] }) });
|
|
76899
77487
|
});
|
|
76900
77488
|
OperationsOverviewHeader.displayName = "OperationsOverviewHeader";
|
|
76901
|
-
var OverviewSummaryCards =
|
|
77489
|
+
var OverviewSummaryCards = React142__default.memo(({ store }) => {
|
|
76902
77490
|
bumpRenderCounter();
|
|
76903
77491
|
const scope = useOperationsOverviewScope(store);
|
|
76904
77492
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
76905
77493
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
76906
|
-
const comparisonLabel =
|
|
77494
|
+
const comparisonLabel = React142__default.useMemo(() => {
|
|
76907
77495
|
return formatComparisonWindow({
|
|
76908
77496
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
76909
77497
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -76916,27 +77504,27 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76916
77504
|
scope.previous_range?.day_count,
|
|
76917
77505
|
scope.shift_mode
|
|
76918
77506
|
]);
|
|
76919
|
-
const [isIdleContributorsOpen, setIsIdleContributorsOpen] =
|
|
76920
|
-
const [isIdleContributorsPinned, setIsIdleContributorsPinned] =
|
|
76921
|
-
const idleContributorsRef =
|
|
76922
|
-
const plantEfficiencyBadge =
|
|
77507
|
+
const [isIdleContributorsOpen, setIsIdleContributorsOpen] = React142__default.useState(false);
|
|
77508
|
+
const [isIdleContributorsPinned, setIsIdleContributorsPinned] = React142__default.useState(false);
|
|
77509
|
+
const idleContributorsRef = React142__default.useRef(null);
|
|
77510
|
+
const plantEfficiencyBadge = React142__default.useMemo(() => {
|
|
76923
77511
|
return buildDeltaBadge(snapshot.data.summary.plant_efficiency?.delta_pp, {
|
|
76924
77512
|
positiveIsGood: true,
|
|
76925
77513
|
formatter: (value) => `${value >= 0 ? "+" : ""}${roundOne(value)}%`,
|
|
76926
77514
|
comparisonLabel
|
|
76927
77515
|
});
|
|
76928
77516
|
}, [comparisonLabel, snapshot.data.summary.plant_efficiency?.delta_pp]);
|
|
76929
|
-
const idleBadge =
|
|
77517
|
+
const idleBadge = React142__default.useMemo(() => {
|
|
76930
77518
|
return buildDeltaBadge(snapshot.data.summary.avg_idle_per_workstation?.delta_seconds, {
|
|
76931
77519
|
positiveIsGood: false,
|
|
76932
77520
|
formatter: (value) => formatSignedIdleDuration(value),
|
|
76933
77521
|
comparisonLabel
|
|
76934
77522
|
});
|
|
76935
77523
|
}, [comparisonLabel, snapshot.data.summary.avg_idle_per_workstation?.delta_seconds]);
|
|
76936
|
-
const canInspectIdleContributors =
|
|
77524
|
+
const canInspectIdleContributors = React142__default.useMemo(() => {
|
|
76937
77525
|
return !showSnapshotSkeleton && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== null && snapshot.data.summary.avg_idle_per_workstation?.current_seconds !== void 0;
|
|
76938
77526
|
}, [showSnapshotSkeleton, snapshot.data.summary.avg_idle_per_workstation?.current_seconds]);
|
|
76939
|
-
const idleTopContributors =
|
|
77527
|
+
const idleTopContributors = React142__default.useMemo(() => {
|
|
76940
77528
|
return (snapshot.data.summary.avg_idle_per_workstation?.top_contributors || []).map((item) => ({
|
|
76941
77529
|
workspaceId: item.workspace_id || "",
|
|
76942
77530
|
workspaceName: item.workspace_name?.trim() || item.workspace_id || "Unknown",
|
|
@@ -76944,14 +77532,14 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76944
77532
|
avgIdleSeconds: toNumber3(item.avg_idle_seconds)
|
|
76945
77533
|
})).slice(0, 5);
|
|
76946
77534
|
}, [snapshot.data.summary.avg_idle_per_workstation?.top_contributors]);
|
|
76947
|
-
const showIdleContributorLineNames =
|
|
77535
|
+
const showIdleContributorLineNames = React142__default.useMemo(() => {
|
|
76948
77536
|
return (scope.line_count ?? 0) > 1;
|
|
76949
77537
|
}, [scope.line_count]);
|
|
76950
|
-
const closeIdleContributors =
|
|
77538
|
+
const closeIdleContributors = React142__default.useCallback(() => {
|
|
76951
77539
|
setIsIdleContributorsOpen(false);
|
|
76952
77540
|
setIsIdleContributorsPinned(false);
|
|
76953
77541
|
}, []);
|
|
76954
|
-
const handleIdleContributorsToggle =
|
|
77542
|
+
const handleIdleContributorsToggle = React142__default.useCallback(() => {
|
|
76955
77543
|
if (!canInspectIdleContributors) return;
|
|
76956
77544
|
setIsIdleContributorsPinned((previous) => {
|
|
76957
77545
|
const next = !previous;
|
|
@@ -76959,7 +77547,7 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76959
77547
|
return next;
|
|
76960
77548
|
});
|
|
76961
77549
|
}, [canInspectIdleContributors]);
|
|
76962
|
-
const handleIdleContributorsKeyDown =
|
|
77550
|
+
const handleIdleContributorsKeyDown = React142__default.useCallback((event) => {
|
|
76963
77551
|
if (!canInspectIdleContributors) return;
|
|
76964
77552
|
if (event.key === "Enter" || event.key === " ") {
|
|
76965
77553
|
event.preventDefault();
|
|
@@ -76971,11 +77559,11 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
76971
77559
|
closeIdleContributors();
|
|
76972
77560
|
}
|
|
76973
77561
|
}, [canInspectIdleContributors, closeIdleContributors, handleIdleContributorsToggle]);
|
|
76974
|
-
|
|
77562
|
+
React142__default.useEffect(() => {
|
|
76975
77563
|
setIsIdleContributorsOpen(false);
|
|
76976
77564
|
setIsIdleContributorsPinned(false);
|
|
76977
77565
|
}, [scope.comparison_strategy, scope.current_range?.start_date, scope.current_range?.end_date, scope.line_count, scope.shift_mode]);
|
|
76978
|
-
|
|
77566
|
+
React142__default.useEffect(() => {
|
|
76979
77567
|
if (!isIdleContributorsOpen) return void 0;
|
|
76980
77568
|
const handleClickOutside = (event) => {
|
|
76981
77569
|
if (!isIdleContributorsPinned) return;
|
|
@@ -77113,7 +77701,7 @@ var OverviewSummaryCards = React141__default.memo(({ store }) => {
|
|
|
77113
77701
|
] });
|
|
77114
77702
|
});
|
|
77115
77703
|
OverviewSummaryCards.displayName = "OverviewSummaryCards";
|
|
77116
|
-
var PoorestPerformersCard =
|
|
77704
|
+
var PoorestPerformersCard = React142__default.memo(({
|
|
77117
77705
|
store,
|
|
77118
77706
|
supervisorsByLineId,
|
|
77119
77707
|
onViewAll,
|
|
@@ -77122,9 +77710,9 @@ var PoorestPerformersCard = React141__default.memo(({
|
|
|
77122
77710
|
bumpRenderCounter();
|
|
77123
77711
|
const scope = useOperationsOverviewScope(store);
|
|
77124
77712
|
const snapshot = useOperationsOverviewSnapshot(store);
|
|
77125
|
-
const [poorestLineMode, setPoorestLineMode] =
|
|
77713
|
+
const [poorestLineMode, setPoorestLineMode] = React142__default.useState("output");
|
|
77126
77714
|
const availableLineModes = scope.available_line_modes;
|
|
77127
|
-
|
|
77715
|
+
React142__default.useEffect(() => {
|
|
77128
77716
|
const hasOutput = !!availableLineModes?.has_output;
|
|
77129
77717
|
const hasUptime = !!availableLineModes?.has_uptime;
|
|
77130
77718
|
if (hasOutput && !hasUptime && poorestLineMode !== "output") {
|
|
@@ -77133,7 +77721,7 @@ var PoorestPerformersCard = React141__default.memo(({
|
|
|
77133
77721
|
setPoorestLineMode("uptime");
|
|
77134
77722
|
}
|
|
77135
77723
|
}, [availableLineModes?.has_output, availableLineModes?.has_uptime, poorestLineMode]);
|
|
77136
|
-
const comparisonLabel =
|
|
77724
|
+
const comparisonLabel = React142__default.useMemo(() => {
|
|
77137
77725
|
return formatComparisonWindow({
|
|
77138
77726
|
currentDayCount: scope.current_range?.day_count ?? null,
|
|
77139
77727
|
previousDayCount: scope.previous_range?.day_count ?? null,
|
|
@@ -77147,7 +77735,7 @@ var PoorestPerformersCard = React141__default.memo(({
|
|
|
77147
77735
|
scope.shift_mode
|
|
77148
77736
|
]);
|
|
77149
77737
|
const showSnapshotSkeleton = snapshot.loading && !snapshot.hasLoadedOnce;
|
|
77150
|
-
const mergedPoorestLines =
|
|
77738
|
+
const mergedPoorestLines = React142__default.useMemo(() => {
|
|
77151
77739
|
const rows = snapshot.data.poorest_lines?.[poorestLineMode] || [];
|
|
77152
77740
|
return rows.slice(0, 3).map((line) => {
|
|
77153
77741
|
const lineId = line.line_id || "";
|
|
@@ -77166,7 +77754,7 @@ var PoorestPerformersCard = React141__default.memo(({
|
|
|
77166
77754
|
}, [poorestLineMode, snapshot.data.poorest_lines, supervisorsByLineId]);
|
|
77167
77755
|
const showPoorestModeToggle = !!availableLineModes?.has_output && !!availableLineModes?.has_uptime;
|
|
77168
77756
|
const poorestMetricLabel = poorestLineMode === "uptime" ? "Uptime" : "Efficiency";
|
|
77169
|
-
const handlePoorestLineModeChange =
|
|
77757
|
+
const handlePoorestLineModeChange = React142__default.useCallback((mode) => {
|
|
77170
77758
|
trackCoreEvent("Operations Overview Poorest Line Mode Changed", { mode });
|
|
77171
77759
|
setPoorestLineMode(mode);
|
|
77172
77760
|
}, []);
|
|
@@ -77252,14 +77840,14 @@ var PoorestPerformersCard = React141__default.memo(({
|
|
|
77252
77840
|
] });
|
|
77253
77841
|
});
|
|
77254
77842
|
PoorestPerformersCard.displayName = "PoorestPerformersCard";
|
|
77255
|
-
var IdleBreakdownCard =
|
|
77843
|
+
var IdleBreakdownCard = React142__default.memo(({
|
|
77256
77844
|
store,
|
|
77257
77845
|
scopedLineCount
|
|
77258
77846
|
}) => {
|
|
77259
77847
|
bumpRenderCounter();
|
|
77260
77848
|
const idle = useOperationsOverviewIdle(store);
|
|
77261
77849
|
const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
|
|
77262
|
-
const idleBreakdown =
|
|
77850
|
+
const idleBreakdown = React142__default.useMemo(() => {
|
|
77263
77851
|
return idle.data.map((item) => ({
|
|
77264
77852
|
name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
|
|
77265
77853
|
reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
|
|
@@ -77278,7 +77866,7 @@ var IdleBreakdownCard = React141__default.memo(({
|
|
|
77278
77866
|
}))
|
|
77279
77867
|
})).filter((item) => item.value > 0);
|
|
77280
77868
|
}, [idle.data]);
|
|
77281
|
-
const showIdleModuleNotEnabledState =
|
|
77869
|
+
const showIdleModuleNotEnabledState = React142__default.useMemo(() => {
|
|
77282
77870
|
const enabledLineCount = idle.scope.idle_time_vlm_enabled_line_count;
|
|
77283
77871
|
return !showInitialSkeleton && scopedLineCount > 0 && typeof enabledLineCount === "number" && enabledLineCount === 0;
|
|
77284
77872
|
}, [idle.scope.idle_time_vlm_enabled_line_count, scopedLineCount, showInitialSkeleton]);
|
|
@@ -77299,7 +77887,7 @@ var IdleBreakdownCard = React141__default.memo(({
|
|
|
77299
77887
|
] });
|
|
77300
77888
|
});
|
|
77301
77889
|
IdleBreakdownCard.displayName = "IdleBreakdownCard";
|
|
77302
|
-
var EfficiencyTrendCard =
|
|
77890
|
+
var EfficiencyTrendCard = React142__default.memo(({
|
|
77303
77891
|
store,
|
|
77304
77892
|
dateRange,
|
|
77305
77893
|
appTimezone,
|
|
@@ -77307,14 +77895,14 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
77307
77895
|
}) => {
|
|
77308
77896
|
bumpRenderCounter();
|
|
77309
77897
|
const trend = useOperationsOverviewTrend(store);
|
|
77310
|
-
const currentWeekRange =
|
|
77898
|
+
const currentWeekRange = React142__default.useMemo(
|
|
77311
77899
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
77312
77900
|
[appTimezone]
|
|
77313
77901
|
);
|
|
77314
77902
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
77315
77903
|
const showInitialSkeleton = trend.loading && trend.lastUpdated === null;
|
|
77316
77904
|
const isHourlyTrend = trend.data.granularity === "hour";
|
|
77317
|
-
const trendData =
|
|
77905
|
+
const trendData = React142__default.useMemo(() => {
|
|
77318
77906
|
if (isHourlyTrend) {
|
|
77319
77907
|
return (trend.data.points || []).map((point, index) => ({
|
|
77320
77908
|
name: (() => {
|
|
@@ -77386,13 +77974,13 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
77386
77974
|
};
|
|
77387
77975
|
});
|
|
77388
77976
|
}, [currentWeekRange.startKey, hourlyLabelStartTime, isCurrentWeekToDateRange, isHourlyTrend, trend.data.points]);
|
|
77389
|
-
const trendTooltipLabelFormatter =
|
|
77977
|
+
const trendTooltipLabelFormatter = React142__default.useCallback((label, payload) => {
|
|
77390
77978
|
if (isHourlyTrend) return label;
|
|
77391
77979
|
const dayOfWeek = payload?.[0]?.payload?.dayOfWeek;
|
|
77392
77980
|
if (!dayOfWeek || typeof label !== "string") return label;
|
|
77393
77981
|
return `${label} (${dayOfWeek})`;
|
|
77394
77982
|
}, [isHourlyTrend]);
|
|
77395
|
-
const trendXAxisTickFormatter =
|
|
77983
|
+
const trendXAxisTickFormatter = React142__default.useCallback((value, index) => {
|
|
77396
77984
|
if (!isHourlyTrend) {
|
|
77397
77985
|
return typeof value === "string" ? value : String(value ?? "");
|
|
77398
77986
|
}
|
|
@@ -77419,7 +78007,7 @@ var EfficiencyTrendCard = React141__default.memo(({
|
|
|
77419
78007
|
] });
|
|
77420
78008
|
});
|
|
77421
78009
|
EfficiencyTrendCard.displayName = "EfficiencyTrendCard";
|
|
77422
|
-
var TopImprovementsCard =
|
|
78010
|
+
var TopImprovementsCard = React142__default.memo(({
|
|
77423
78011
|
store,
|
|
77424
78012
|
supervisorsByLineId,
|
|
77425
78013
|
onViewAll,
|
|
@@ -77428,7 +78016,7 @@ var TopImprovementsCard = React141__default.memo(({
|
|
|
77428
78016
|
bumpRenderCounter();
|
|
77429
78017
|
const improvements = useOperationsOverviewImprovements(store);
|
|
77430
78018
|
const showInitialSkeleton = improvements.loading && improvements.lastUpdated === null;
|
|
77431
|
-
const displayImprovements =
|
|
78019
|
+
const displayImprovements = React142__default.useMemo(() => {
|
|
77432
78020
|
return improvements.data.map((item) => {
|
|
77433
78021
|
const supervisors = item.lineId ? supervisorsByLineId.get(item.lineId) || [] : [];
|
|
77434
78022
|
return {
|
|
@@ -77465,7 +78053,7 @@ var TopImprovementsCard = React141__default.memo(({
|
|
|
77465
78053
|
className: "flex items-center justify-between py-3 border-b border-slate-50 last:border-0 group cursor-pointer",
|
|
77466
78054
|
children: [
|
|
77467
78055
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0 pr-4", children: [
|
|
77468
|
-
item.ticketLabel ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-
|
|
78056
|
+
item.ticketLabel ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-start flex-shrink-0 w-16", children: /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center min-w-[48px] max-w-[64px] truncate rounded-full border border-indigo-100 bg-indigo-50 px-2 py-0.5 text-[10px] font-semibold text-indigo-600", children: item.ticketLabel }) }) : null,
|
|
77469
78057
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
77470
78058
|
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 min-w-0 mb-0.5", children: /* @__PURE__ */ jsx("h4", { className: "text-[13px] font-semibold text-slate-800 truncate transition-colors group-hover:text-indigo-600", children: item.title }) }),
|
|
77471
78059
|
/* @__PURE__ */ jsx(
|
|
@@ -77556,33 +78144,33 @@ var useOperationsOverviewRefresh = ({
|
|
|
77556
78144
|
isLiveScope,
|
|
77557
78145
|
enabled = true
|
|
77558
78146
|
}) => {
|
|
77559
|
-
const lineIdsKey =
|
|
77560
|
-
const scopeSignature =
|
|
78147
|
+
const lineIdsKey = React142__default.useMemo(() => lineIds.join(","), [lineIds]);
|
|
78148
|
+
const scopeSignature = React142__default.useMemo(
|
|
77561
78149
|
() => [companyId || "", startKey, endKey, trendMode, comparisonStrategy || "", lineIdsKey].join("::"),
|
|
77562
78150
|
[companyId, comparisonStrategy, endKey, lineIdsKey, startKey, trendMode]
|
|
77563
78151
|
);
|
|
77564
|
-
const controllersRef =
|
|
77565
|
-
const requestIdsRef =
|
|
78152
|
+
const controllersRef = React142__default.useRef({});
|
|
78153
|
+
const requestIdsRef = React142__default.useRef({
|
|
77566
78154
|
snapshot: 0,
|
|
77567
78155
|
trend: 0,
|
|
77568
78156
|
idle: 0,
|
|
77569
78157
|
improvements: 0
|
|
77570
78158
|
});
|
|
77571
|
-
const intervalRef =
|
|
77572
|
-
const isPageActiveRef =
|
|
77573
|
-
const lastResumeRefreshAtRef =
|
|
77574
|
-
const abortAll =
|
|
78159
|
+
const intervalRef = React142__default.useRef(null);
|
|
78160
|
+
const isPageActiveRef = React142__default.useRef(true);
|
|
78161
|
+
const lastResumeRefreshAtRef = React142__default.useRef(0);
|
|
78162
|
+
const abortAll = React142__default.useCallback(() => {
|
|
77575
78163
|
Object.values(controllersRef.current).forEach((controller) => {
|
|
77576
78164
|
controller?.abort();
|
|
77577
78165
|
});
|
|
77578
78166
|
controllersRef.current = {};
|
|
77579
78167
|
}, []);
|
|
77580
|
-
|
|
78168
|
+
React142__default.useEffect(() => {
|
|
77581
78169
|
return () => {
|
|
77582
78170
|
abortAll();
|
|
77583
78171
|
};
|
|
77584
78172
|
}, [abortAll]);
|
|
77585
|
-
const getIsPageActive =
|
|
78173
|
+
const getIsPageActive = React142__default.useCallback(() => {
|
|
77586
78174
|
if (typeof document === "undefined") {
|
|
77587
78175
|
return true;
|
|
77588
78176
|
}
|
|
@@ -77590,7 +78178,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77590
78178
|
const hasFocus = typeof document.hasFocus === "function" ? document.hasFocus() : true;
|
|
77591
78179
|
return isVisible && hasFocus;
|
|
77592
78180
|
}, []);
|
|
77593
|
-
const stopPolling =
|
|
78181
|
+
const stopPolling = React142__default.useCallback((reason) => {
|
|
77594
78182
|
if (intervalRef.current === null) {
|
|
77595
78183
|
return;
|
|
77596
78184
|
}
|
|
@@ -77598,7 +78186,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77598
78186
|
intervalRef.current = null;
|
|
77599
78187
|
debugRefreshLog("poll stopped", { reason });
|
|
77600
78188
|
}, []);
|
|
77601
|
-
const runRefresh =
|
|
78189
|
+
const runRefresh = React142__default.useCallback(
|
|
77602
78190
|
async (section, begin, onSuccess, onError, request, reason) => {
|
|
77603
78191
|
if (!enabled || !supabase || !companyId || lineIds.length === 0) return;
|
|
77604
78192
|
const requestId = requestIdsRef.current[section] + 1;
|
|
@@ -77622,7 +78210,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77622
78210
|
},
|
|
77623
78211
|
[companyId, enabled, lineIds.length, supabase]
|
|
77624
78212
|
);
|
|
77625
|
-
const refreshSnapshot =
|
|
78213
|
+
const refreshSnapshot = React142__default.useCallback(
|
|
77626
78214
|
async (reason) => {
|
|
77627
78215
|
await runRefresh(
|
|
77628
78216
|
"snapshot",
|
|
@@ -77654,7 +78242,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77654
78242
|
},
|
|
77655
78243
|
[companyId, comparisonStrategy, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
77656
78244
|
);
|
|
77657
|
-
const refreshTrend =
|
|
78245
|
+
const refreshTrend = React142__default.useCallback(
|
|
77658
78246
|
async (reason) => {
|
|
77659
78247
|
await runRefresh(
|
|
77660
78248
|
"trend",
|
|
@@ -77683,7 +78271,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77683
78271
|
},
|
|
77684
78272
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
77685
78273
|
);
|
|
77686
|
-
const refreshIdle =
|
|
78274
|
+
const refreshIdle = React142__default.useCallback(
|
|
77687
78275
|
async (reason) => {
|
|
77688
78276
|
await runRefresh(
|
|
77689
78277
|
"idle",
|
|
@@ -77712,7 +78300,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77712
78300
|
},
|
|
77713
78301
|
[companyId, endKey, lineIdsKey, runRefresh, scopeSignature, startKey, store, supabase, trendMode]
|
|
77714
78302
|
);
|
|
77715
|
-
const refreshImprovements =
|
|
78303
|
+
const refreshImprovements = React142__default.useCallback(
|
|
77716
78304
|
async (reason) => {
|
|
77717
78305
|
await runRefresh(
|
|
77718
78306
|
"improvements",
|
|
@@ -77742,7 +78330,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77742
78330
|
},
|
|
77743
78331
|
[companyId, lineIds, lineIdsKey, runRefresh, scopeSignature, store, supabase]
|
|
77744
78332
|
);
|
|
77745
|
-
const refreshAll =
|
|
78333
|
+
const refreshAll = React142__default.useCallback(
|
|
77746
78334
|
async (reason) => {
|
|
77747
78335
|
await Promise.allSettled([
|
|
77748
78336
|
refreshSnapshot(reason),
|
|
@@ -77753,7 +78341,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77753
78341
|
},
|
|
77754
78342
|
[refreshIdle, refreshImprovements, refreshSnapshot, refreshTrend]
|
|
77755
78343
|
);
|
|
77756
|
-
const startPolling =
|
|
78344
|
+
const startPolling = React142__default.useCallback((reason) => {
|
|
77757
78345
|
if (!isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
77758
78346
|
return;
|
|
77759
78347
|
}
|
|
@@ -77774,7 +78362,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77774
78362
|
}, LIVE_REFRESH_INTERVAL_MS);
|
|
77775
78363
|
debugRefreshLog("poll started", { reason, intervalMs: LIVE_REFRESH_INTERVAL_MS });
|
|
77776
78364
|
}, [companyId, isLiveScope, lineIds.length, refreshAll, stopPolling, supabase]);
|
|
77777
|
-
const refreshFromResume =
|
|
78365
|
+
const refreshFromResume = React142__default.useCallback((reason) => {
|
|
77778
78366
|
const now4 = Date.now();
|
|
77779
78367
|
if (now4 - lastResumeRefreshAtRef.current < 1e3) {
|
|
77780
78368
|
debugRefreshLog("resume refresh suppressed", { reason });
|
|
@@ -77789,7 +78377,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77789
78377
|
}
|
|
77790
78378
|
});
|
|
77791
78379
|
}, [refreshAll, startPolling, stopPolling]);
|
|
77792
|
-
|
|
78380
|
+
React142__default.useEffect(() => {
|
|
77793
78381
|
if (!enabled) {
|
|
77794
78382
|
stopPolling("disabled");
|
|
77795
78383
|
abortAll();
|
|
@@ -77804,7 +78392,7 @@ var useOperationsOverviewRefresh = ({
|
|
|
77804
78392
|
}
|
|
77805
78393
|
void refreshAll("scope_change");
|
|
77806
78394
|
}, [abortAll, companyId, enabled, lineIds.length, refreshAll, scopeSignature, stopPolling, store, supabase]);
|
|
77807
|
-
|
|
78395
|
+
React142__default.useEffect(() => {
|
|
77808
78396
|
if (!enabled || !isLiveScope || !supabase || !companyId || lineIds.length === 0) {
|
|
77809
78397
|
isPageActiveRef.current = false;
|
|
77810
78398
|
stopPolling("live_scope_disabled");
|
|
@@ -77979,55 +78567,55 @@ var PlantHeadView = () => {
|
|
|
77979
78567
|
const { accessibleLineIds } = useUserLineAccess();
|
|
77980
78568
|
const mobileMenuContext = useMobileMenu();
|
|
77981
78569
|
useHideMobileHeader(!!mobileMenuContext);
|
|
77982
|
-
const storeRef =
|
|
78570
|
+
const storeRef = React142__default.useRef(createOperationsOverviewStore());
|
|
77983
78571
|
const store = storeRef.current;
|
|
77984
|
-
const fallbackOperationalDate =
|
|
78572
|
+
const fallbackOperationalDate = React142__default.useMemo(
|
|
77985
78573
|
() => getOperationalDate(appTimezone),
|
|
77986
78574
|
[appTimezone]
|
|
77987
78575
|
);
|
|
77988
|
-
const [dateRange, setDateRange] =
|
|
78576
|
+
const [dateRange, setDateRange] = React142__default.useState(() => ({
|
|
77989
78577
|
startKey: fallbackOperationalDate,
|
|
77990
78578
|
endKey: fallbackOperationalDate
|
|
77991
78579
|
}));
|
|
77992
|
-
const [usesThisWeekComparison, setUsesThisWeekComparison] =
|
|
77993
|
-
const [trendMode, setTrendMode] =
|
|
77994
|
-
const [selectedSupervisorId, setSelectedSupervisorId] =
|
|
77995
|
-
const [selectedLineIds, setSelectedLineIds] =
|
|
77996
|
-
const [isInitialScopeReady, setIsInitialScopeReady] =
|
|
77997
|
-
const [shiftResolutionTick, setShiftResolutionTick] =
|
|
77998
|
-
const hasAutoInitializedScopeRef =
|
|
77999
|
-
const hasUserAdjustedScopeRef =
|
|
78000
|
-
|
|
78580
|
+
const [usesThisWeekComparison, setUsesThisWeekComparison] = React142__default.useState(false);
|
|
78581
|
+
const [trendMode, setTrendMode] = React142__default.useState("all");
|
|
78582
|
+
const [selectedSupervisorId, setSelectedSupervisorId] = React142__default.useState("all");
|
|
78583
|
+
const [selectedLineIds, setSelectedLineIds] = React142__default.useState([]);
|
|
78584
|
+
const [isInitialScopeReady, setIsInitialScopeReady] = React142__default.useState(false);
|
|
78585
|
+
const [shiftResolutionTick, setShiftResolutionTick] = React142__default.useState(0);
|
|
78586
|
+
const hasAutoInitializedScopeRef = React142__default.useRef(false);
|
|
78587
|
+
const hasUserAdjustedScopeRef = React142__default.useRef(false);
|
|
78588
|
+
React142__default.useEffect(() => {
|
|
78001
78589
|
trackCorePageView("Operations Overview", {
|
|
78002
78590
|
dashboard_surface: "operations_overview"
|
|
78003
78591
|
});
|
|
78004
78592
|
}, []);
|
|
78005
|
-
const currentWeekRange =
|
|
78593
|
+
const currentWeekRange = React142__default.useMemo(
|
|
78006
78594
|
() => getCurrentWeekToDateRange(appTimezone),
|
|
78007
78595
|
[appTimezone]
|
|
78008
78596
|
);
|
|
78009
|
-
const currentWeekDisplayRange =
|
|
78597
|
+
const currentWeekDisplayRange = React142__default.useMemo(
|
|
78010
78598
|
() => getCurrentWeekFullRange(appTimezone),
|
|
78011
78599
|
[appTimezone]
|
|
78012
78600
|
);
|
|
78013
78601
|
const isCurrentWeekToDateRange = dateRange.startKey === currentWeekRange.startKey && dateRange.endKey === currentWeekRange.endKey;
|
|
78014
|
-
const headerDateRange =
|
|
78602
|
+
const headerDateRange = React142__default.useMemo(() => {
|
|
78015
78603
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
78016
78604
|
return currentWeekDisplayRange;
|
|
78017
78605
|
}
|
|
78018
78606
|
return dateRange;
|
|
78019
78607
|
}, [currentWeekDisplayRange, dateRange, isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
78020
|
-
const normalizedLineIds =
|
|
78608
|
+
const normalizedLineIds = React142__default.useMemo(
|
|
78021
78609
|
() => Array.from(new Set(
|
|
78022
78610
|
(accessibleLineIds || []).filter(Boolean).filter((lineId) => lineId !== factoryViewId)
|
|
78023
78611
|
)).sort(),
|
|
78024
78612
|
[accessibleLineIds, factoryViewId]
|
|
78025
78613
|
);
|
|
78026
|
-
const lineIdsKey =
|
|
78614
|
+
const lineIdsKey = React142__default.useMemo(
|
|
78027
78615
|
() => normalizedLineIds.join(","),
|
|
78028
78616
|
[normalizedLineIds]
|
|
78029
78617
|
);
|
|
78030
|
-
const lineOptions =
|
|
78618
|
+
const lineOptions = React142__default.useMemo(
|
|
78031
78619
|
() => normalizedLineIds.map((lineId) => ({
|
|
78032
78620
|
id: lineId,
|
|
78033
78621
|
name: getLineDisplayName(entityConfig, lineId)
|
|
@@ -78039,7 +78627,7 @@ var PlantHeadView = () => {
|
|
|
78039
78627
|
companyId: entityConfig.companyId,
|
|
78040
78628
|
useBackend: true
|
|
78041
78629
|
});
|
|
78042
|
-
const supervisorOptions =
|
|
78630
|
+
const supervisorOptions = React142__default.useMemo(
|
|
78043
78631
|
() => {
|
|
78044
78632
|
const optionsById = /* @__PURE__ */ new Map();
|
|
78045
78633
|
normalizedLineIds.forEach((lineId) => {
|
|
@@ -78065,7 +78653,7 @@ var PlantHeadView = () => {
|
|
|
78065
78653
|
},
|
|
78066
78654
|
[normalizedLineIds, supervisorsByLineId]
|
|
78067
78655
|
);
|
|
78068
|
-
|
|
78656
|
+
React142__default.useEffect(() => {
|
|
78069
78657
|
if (selectedSupervisorId === "all") {
|
|
78070
78658
|
setSelectedLineIds((previous) => {
|
|
78071
78659
|
if (normalizedLineIds.length === 0) {
|
|
@@ -78091,7 +78679,7 @@ var PlantHeadView = () => {
|
|
|
78091
78679
|
const scopedSupervisorLineIds = normalizedLineIds.filter((lineId) => supervisorLineIdSet.has(lineId));
|
|
78092
78680
|
setSelectedLineIds((previous) => previous.length === scopedSupervisorLineIds.length && previous.every((lineId, index) => lineId === scopedSupervisorLineIds[index]) ? previous : scopedSupervisorLineIds);
|
|
78093
78681
|
}, [lineIdsKey, normalizedLineIds, selectedSupervisorId, supervisorOptions]);
|
|
78094
|
-
const scopedLineIds =
|
|
78682
|
+
const scopedLineIds = React142__default.useMemo(
|
|
78095
78683
|
() => selectedLineIds.length > 0 ? selectedLineIds : normalizedLineIds,
|
|
78096
78684
|
[normalizedLineIds, selectedLineIds]
|
|
78097
78685
|
);
|
|
@@ -78099,7 +78687,7 @@ var PlantHeadView = () => {
|
|
|
78099
78687
|
shiftConfigMap,
|
|
78100
78688
|
isLoading: isShiftConfigLoading
|
|
78101
78689
|
} = useMultiLineShiftConfigs(scopedLineIds, staticShiftConfig);
|
|
78102
|
-
|
|
78690
|
+
React142__default.useEffect(() => {
|
|
78103
78691
|
if (scopedLineIds.length === 0 || isShiftConfigLoading) {
|
|
78104
78692
|
return;
|
|
78105
78693
|
}
|
|
@@ -78110,11 +78698,11 @@ var PlantHeadView = () => {
|
|
|
78110
78698
|
clearInterval(intervalId);
|
|
78111
78699
|
};
|
|
78112
78700
|
}, [isShiftConfigLoading, scopedLineIds.length]);
|
|
78113
|
-
const shiftResolutionNow =
|
|
78701
|
+
const shiftResolutionNow = React142__default.useMemo(
|
|
78114
78702
|
() => /* @__PURE__ */ new Date(),
|
|
78115
78703
|
[shiftResolutionTick]
|
|
78116
78704
|
);
|
|
78117
|
-
const earliestDayShiftStartTime =
|
|
78705
|
+
const earliestDayShiftStartTime = React142__default.useMemo(() => {
|
|
78118
78706
|
const candidateStarts = [];
|
|
78119
78707
|
scopedLineIds.forEach((lineId) => {
|
|
78120
78708
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
@@ -78150,11 +78738,11 @@ var PlantHeadView = () => {
|
|
|
78150
78738
|
const minutes = earliestMinutes % 60;
|
|
78151
78739
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
78152
78740
|
}, [appTimezone, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
78153
|
-
const resolvedOperationalToday =
|
|
78741
|
+
const resolvedOperationalToday = React142__default.useMemo(
|
|
78154
78742
|
() => getOperationalDate(appTimezone, shiftResolutionNow, earliestDayShiftStartTime),
|
|
78155
78743
|
[appTimezone, earliestDayShiftStartTime, shiftResolutionNow]
|
|
78156
78744
|
);
|
|
78157
|
-
const activeLineShiftStates =
|
|
78745
|
+
const activeLineShiftStates = React142__default.useMemo(() => {
|
|
78158
78746
|
return scopedLineIds.flatMap((lineId) => {
|
|
78159
78747
|
const shiftConfig = shiftConfigMap.get(lineId) || staticShiftConfig;
|
|
78160
78748
|
const activeShift = getActiveShift(appTimezone, shiftConfig, shiftResolutionNow);
|
|
@@ -78181,16 +78769,16 @@ var PlantHeadView = () => {
|
|
|
78181
78769
|
}];
|
|
78182
78770
|
});
|
|
78183
78771
|
}, [appTimezone, scopedLineIds, shiftConfigMap, shiftResolutionNow, staticShiftConfig]);
|
|
78184
|
-
const hasActiveDayShiftLine =
|
|
78772
|
+
const hasActiveDayShiftLine = React142__default.useMemo(
|
|
78185
78773
|
() => activeLineShiftStates.some((shift) => shift.trendMode === "day" && shift.date === resolvedOperationalToday),
|
|
78186
78774
|
[activeLineShiftStates, resolvedOperationalToday]
|
|
78187
78775
|
);
|
|
78188
|
-
const hasActiveNightShiftLine =
|
|
78776
|
+
const hasActiveNightShiftLine = React142__default.useMemo(
|
|
78189
78777
|
() => activeLineShiftStates.some((shift) => shift.trendMode === "night" && shift.date === resolvedOperationalToday),
|
|
78190
78778
|
[activeLineShiftStates, resolvedOperationalToday]
|
|
78191
78779
|
);
|
|
78192
78780
|
const resolvedTrendMode = isInitialScopeReady ? trendMode : "all";
|
|
78193
|
-
const hourlyWindowStartTime =
|
|
78781
|
+
const hourlyWindowStartTime = React142__default.useMemo(() => {
|
|
78194
78782
|
if (scopedLineIds.length === 0) {
|
|
78195
78783
|
return null;
|
|
78196
78784
|
}
|
|
@@ -78241,12 +78829,12 @@ var PlantHeadView = () => {
|
|
|
78241
78829
|
const minutes = earliestMinutes % 60;
|
|
78242
78830
|
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
78243
78831
|
}, [appTimezone, resolvedTrendMode, scopedLineIds, shiftConfigMap, staticShiftConfig]);
|
|
78244
|
-
const isShiftScopeResolved =
|
|
78832
|
+
const isShiftScopeResolved = React142__default.useMemo(
|
|
78245
78833
|
() => !isShiftConfigLoading,
|
|
78246
78834
|
[isShiftConfigLoading]
|
|
78247
78835
|
);
|
|
78248
|
-
const initializedTimezoneRef =
|
|
78249
|
-
|
|
78836
|
+
const initializedTimezoneRef = React142__default.useRef(appTimezone);
|
|
78837
|
+
React142__default.useEffect(() => {
|
|
78250
78838
|
if (initializedTimezoneRef.current === appTimezone) return;
|
|
78251
78839
|
hasAutoInitializedScopeRef.current = false;
|
|
78252
78840
|
hasUserAdjustedScopeRef.current = false;
|
|
@@ -78259,7 +78847,7 @@ var PlantHeadView = () => {
|
|
|
78259
78847
|
setIsInitialScopeReady(false);
|
|
78260
78848
|
initializedTimezoneRef.current = appTimezone;
|
|
78261
78849
|
}, [appTimezone, fallbackOperationalDate]);
|
|
78262
|
-
|
|
78850
|
+
React142__default.useEffect(() => {
|
|
78263
78851
|
if (hasAutoInitializedScopeRef.current || hasUserAdjustedScopeRef.current) {
|
|
78264
78852
|
return;
|
|
78265
78853
|
}
|
|
@@ -78284,7 +78872,7 @@ var PlantHeadView = () => {
|
|
|
78284
78872
|
hasAutoInitializedScopeRef.current = true;
|
|
78285
78873
|
setIsInitialScopeReady(true);
|
|
78286
78874
|
}, [fallbackOperationalDate, isShiftScopeResolved, resolvedOperationalToday, scopedLineIds.length]);
|
|
78287
|
-
const handleDateRangeChange =
|
|
78875
|
+
const handleDateRangeChange = React142__default.useCallback((range, meta) => {
|
|
78288
78876
|
hasUserAdjustedScopeRef.current = true;
|
|
78289
78877
|
setIsInitialScopeReady(true);
|
|
78290
78878
|
trackCoreEvent("Operations Overview Date Range Changed", {
|
|
@@ -78302,12 +78890,12 @@ var PlantHeadView = () => {
|
|
|
78302
78890
|
return previous;
|
|
78303
78891
|
});
|
|
78304
78892
|
}, []);
|
|
78305
|
-
const handleTrendModeChange =
|
|
78893
|
+
const handleTrendModeChange = React142__default.useCallback((mode) => {
|
|
78306
78894
|
hasUserAdjustedScopeRef.current = true;
|
|
78307
78895
|
setIsInitialScopeReady(true);
|
|
78308
78896
|
setTrendMode(mode);
|
|
78309
78897
|
}, []);
|
|
78310
|
-
const handleSelectedLineIdsChange =
|
|
78898
|
+
const handleSelectedLineIdsChange = React142__default.useCallback((lineIds) => {
|
|
78311
78899
|
setSelectedSupervisorId("all");
|
|
78312
78900
|
if (normalizedLineIds.length === 0) {
|
|
78313
78901
|
setSelectedLineIds([]);
|
|
@@ -78318,10 +78906,10 @@ var PlantHeadView = () => {
|
|
|
78318
78906
|
const next = normalizedLineIds.filter((lineId) => selectedSet.has(lineId));
|
|
78319
78907
|
setSelectedLineIds(next.length > 0 ? next : normalizedLineIds);
|
|
78320
78908
|
}, [normalizedLineIds]);
|
|
78321
|
-
const handleSelectedSupervisorIdChange =
|
|
78909
|
+
const handleSelectedSupervisorIdChange = React142__default.useCallback((supervisorId) => {
|
|
78322
78910
|
setSelectedSupervisorId(supervisorId);
|
|
78323
78911
|
}, []);
|
|
78324
|
-
const buildLineMonthlyHistoryUrl =
|
|
78912
|
+
const buildLineMonthlyHistoryUrl = React142__default.useCallback((lineId) => {
|
|
78325
78913
|
const rangeStartDate = parseDateKeyToDate(dateRange.startKey);
|
|
78326
78914
|
const params = new URLSearchParams();
|
|
78327
78915
|
params.set("tab", "monthly_history");
|
|
@@ -78331,15 +78919,15 @@ var PlantHeadView = () => {
|
|
|
78331
78919
|
params.set("rangeEnd", dateRange.endKey);
|
|
78332
78920
|
return `/kpis/${lineId}?${params.toString()}`;
|
|
78333
78921
|
}, [dateRange.endKey, dateRange.startKey]);
|
|
78334
|
-
const handleViewAllPoorestPerformers =
|
|
78922
|
+
const handleViewAllPoorestPerformers = React142__default.useCallback(() => {
|
|
78335
78923
|
trackCoreEvent("Operations Overview View All Clicked", { section: "poorest_performers" });
|
|
78336
78924
|
navigate("/kpis?tab=leaderboard");
|
|
78337
78925
|
}, [navigate]);
|
|
78338
|
-
const handleViewAllImprovements =
|
|
78926
|
+
const handleViewAllImprovements = React142__default.useCallback(() => {
|
|
78339
78927
|
trackCoreEvent("Operations Overview View All Clicked", { section: "improvements" });
|
|
78340
78928
|
navigate("/improvement-center");
|
|
78341
78929
|
}, [navigate]);
|
|
78342
|
-
const handleOpenImprovement =
|
|
78930
|
+
const handleOpenImprovement = React142__default.useCallback((item) => {
|
|
78343
78931
|
trackCoreEvent("Operations Overview Improvement Clicked", {
|
|
78344
78932
|
issue_id: item.issueId,
|
|
78345
78933
|
issue_number: item.issueNumber,
|
|
@@ -78350,13 +78938,13 @@ var PlantHeadView = () => {
|
|
|
78350
78938
|
});
|
|
78351
78939
|
navigate(`/improvement-center?${params.toString()}`);
|
|
78352
78940
|
}, [navigate]);
|
|
78353
|
-
const comparisonStrategy =
|
|
78941
|
+
const comparisonStrategy = React142__default.useMemo(() => {
|
|
78354
78942
|
if (usesThisWeekComparison && isCurrentWeekToDateRange) {
|
|
78355
78943
|
return "previous_full_week";
|
|
78356
78944
|
}
|
|
78357
78945
|
return void 0;
|
|
78358
78946
|
}, [isCurrentWeekToDateRange, usesThisWeekComparison]);
|
|
78359
|
-
const effectiveDateRange =
|
|
78947
|
+
const effectiveDateRange = React142__default.useMemo(() => {
|
|
78360
78948
|
if (isInitialScopeReady) {
|
|
78361
78949
|
return dateRange;
|
|
78362
78950
|
}
|
|
@@ -78366,21 +78954,21 @@ var PlantHeadView = () => {
|
|
|
78366
78954
|
endKey: nextStartKey
|
|
78367
78955
|
};
|
|
78368
78956
|
}, [dateRange, fallbackOperationalDate, isInitialScopeReady, resolvedOperationalToday]);
|
|
78369
|
-
const effectiveTrendMode =
|
|
78957
|
+
const effectiveTrendMode = React142__default.useMemo(
|
|
78370
78958
|
() => resolvedTrendMode,
|
|
78371
78959
|
[resolvedTrendMode]
|
|
78372
78960
|
);
|
|
78373
|
-
const hourlyLabelStartTime =
|
|
78961
|
+
const hourlyLabelStartTime = React142__default.useMemo(() => {
|
|
78374
78962
|
if (scopedLineIds.length === 0) {
|
|
78375
78963
|
return null;
|
|
78376
78964
|
}
|
|
78377
78965
|
return hourlyWindowStartTime;
|
|
78378
78966
|
}, [hourlyWindowStartTime, scopedLineIds.length]);
|
|
78379
|
-
const isSingleDayScope =
|
|
78967
|
+
const isSingleDayScope = React142__default.useMemo(
|
|
78380
78968
|
() => effectiveDateRange.startKey === effectiveDateRange.endKey,
|
|
78381
78969
|
[effectiveDateRange.endKey, effectiveDateRange.startKey]
|
|
78382
78970
|
);
|
|
78383
|
-
const isLiveScope =
|
|
78971
|
+
const isLiveScope = React142__default.useMemo(
|
|
78384
78972
|
() => isSingleDayScope && effectiveDateRange.startKey === resolvedOperationalToday && (effectiveTrendMode === "all" || effectiveTrendMode === "day" && hasActiveDayShiftLine || effectiveTrendMode === "night" && hasActiveNightShiftLine),
|
|
78385
78973
|
[
|
|
78386
78974
|
effectiveDateRange.startKey,
|
|
@@ -78391,7 +78979,7 @@ var PlantHeadView = () => {
|
|
|
78391
78979
|
resolvedOperationalToday
|
|
78392
78980
|
]
|
|
78393
78981
|
);
|
|
78394
|
-
const handleOpenLineDetails =
|
|
78982
|
+
const handleOpenLineDetails = React142__default.useCallback((lineId, lineName) => {
|
|
78395
78983
|
trackCoreEvent("Operations Overview Line Clicked", {
|
|
78396
78984
|
line_id: lineId,
|
|
78397
78985
|
line_name: lineName,
|
|
@@ -78959,4 +79547,4 @@ var streamProxyConfig = {
|
|
|
78959
79547
|
}
|
|
78960
79548
|
};
|
|
78961
79549
|
|
|
78962
|
-
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|
|
79550
|
+
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyHasVlmEnabledLine, 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 };
|