@optifye/dashboard-core 6.11.11 → 6.11.13
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 +92 -40
- package/dist/index.d.mts +88 -24
- package/dist/index.d.ts +88 -24
- package/dist/index.js +1466 -694
- package/dist/index.mjs +1460 -693
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -10,8 +10,8 @@ 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, Copy, Settings, LifeBuoy, EyeOff, Zap, Flame, Crown, Medal } from 'lucide-react';
|
|
13
14
|
import { memo, noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds } from 'motion-utils';
|
|
14
|
-
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, Wrench, XCircle, Package, UserX, Zap, HelpCircle, Tag, Palette, CheckCircle2, RefreshCw, TrendingDown, FolderOpen, Folder, Sliders, Activity, Layers, Search, Edit2, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, Pencil, UserCheck, LogOut, Film, MessageSquare, Menu, Send, Copy, Settings, LifeBuoy, EyeOff, Flame, Crown, Medal } from 'lucide-react';
|
|
15
15
|
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, ReferenceLine, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, PieChart, Pie, Cell, 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';
|
|
@@ -3417,6 +3417,25 @@ function isValidFactoryViewConfiguration(entityConfig) {
|
|
|
3417
3417
|
return lineIds.length > 0;
|
|
3418
3418
|
}
|
|
3419
3419
|
|
|
3420
|
+
// src/lib/constants/videoGridMetricMode.ts
|
|
3421
|
+
var VALID_VIDEO_GRID_METRIC_MODES = /* @__PURE__ */ new Set([
|
|
3422
|
+
"efficiency",
|
|
3423
|
+
"recent_flow",
|
|
3424
|
+
"recent_flow_wip_gated"
|
|
3425
|
+
]);
|
|
3426
|
+
var normalizeVideoGridMetricMode = (value, assemblyEnabled = false) => {
|
|
3427
|
+
const normalized = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
3428
|
+
if (VALID_VIDEO_GRID_METRIC_MODES.has(normalized)) {
|
|
3429
|
+
return normalized;
|
|
3430
|
+
}
|
|
3431
|
+
return assemblyEnabled ? "recent_flow_wip_gated" : "efficiency";
|
|
3432
|
+
};
|
|
3433
|
+
var isRecentFlowVideoGridMetricMode = (value, assemblyEnabled = false) => {
|
|
3434
|
+
const normalized = normalizeVideoGridMetricMode(value, assemblyEnabled);
|
|
3435
|
+
return normalized === "recent_flow" || normalized === "recent_flow_wip_gated";
|
|
3436
|
+
};
|
|
3437
|
+
var isWipGatedVideoGridMetricMode = (value, assemblyEnabled = false) => normalizeVideoGridMetricMode(value, assemblyEnabled) === "recent_flow_wip_gated";
|
|
3438
|
+
|
|
3420
3439
|
// src/lib/services/lineMetricsSelection.ts
|
|
3421
3440
|
var toTimestamp = (value) => {
|
|
3422
3441
|
if (typeof value !== "string") return 0;
|
|
@@ -3878,7 +3897,7 @@ var dashboardService = {
|
|
|
3878
3897
|
company_name: data.company_name || "Company X",
|
|
3879
3898
|
date: data.date,
|
|
3880
3899
|
shift_id: data.shift_id,
|
|
3881
|
-
action_name: data.action_name || "",
|
|
3900
|
+
action_name: data.action_display_name || data.action_name || "",
|
|
3882
3901
|
shift_start: data.shift_start || (data.shift_id === (shiftConfig.dayShift?.id ?? 0) ? shiftConfig.dayShift?.startTime : shiftConfig.nightShift?.startTime) || "00:00",
|
|
3883
3902
|
shift_end: data.shift_end || (data.shift_id === (shiftConfig.dayShift?.id ?? 0) ? shiftConfig.dayShift?.endTime : shiftConfig.nightShift?.endTime) || "00:00",
|
|
3884
3903
|
shift_type: data.shift_type || (data.shift_id === (shiftConfig.dayShift?.id ?? 0) ? "Day" : "Night"),
|
|
@@ -3947,7 +3966,9 @@ var dashboardService = {
|
|
|
3947
3966
|
company_id,
|
|
3948
3967
|
companies!lines_company_id_fkey(company_name:name),
|
|
3949
3968
|
enable,
|
|
3950
|
-
monitoring_mode
|
|
3969
|
+
monitoring_mode,
|
|
3970
|
+
assembly,
|
|
3971
|
+
video_grid_metric_mode
|
|
3951
3972
|
`).eq("enable", true);
|
|
3952
3973
|
if (companyId) {
|
|
3953
3974
|
query = query.eq("company_id", companyId);
|
|
@@ -3967,7 +3988,12 @@ var dashboardService = {
|
|
|
3967
3988
|
company_name: line.companies?.company_name ?? "N/A",
|
|
3968
3989
|
enable: line.enable ?? true,
|
|
3969
3990
|
// Default to true if not specified
|
|
3970
|
-
monitoring_mode: line.monitoring_mode ?? "output"
|
|
3991
|
+
monitoring_mode: line.monitoring_mode ?? "output",
|
|
3992
|
+
assembly: line.assembly ?? false,
|
|
3993
|
+
video_grid_metric_mode: normalizeVideoGridMetricMode(
|
|
3994
|
+
line.video_grid_metric_mode,
|
|
3995
|
+
line.assembly ?? false
|
|
3996
|
+
)
|
|
3971
3997
|
}));
|
|
3972
3998
|
return transformedLines;
|
|
3973
3999
|
} catch (err) {
|
|
@@ -4004,7 +4030,7 @@ var dashboardService = {
|
|
|
4004
4030
|
}
|
|
4005
4031
|
const lineIdsToQuery = configuredLineIds;
|
|
4006
4032
|
const [line1Result, metricsResult2] = await Promise.all([
|
|
4007
|
-
supabase.from(linesTable).select("id, line_name, factory_id, monitoring_mode, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", defaultLineId).single(),
|
|
4033
|
+
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(),
|
|
4008
4034
|
supabase.from(lineMetricsTable).select("*").in("line_id", lineIdsToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
4009
4035
|
]);
|
|
4010
4036
|
if (line1Result.error) throw line1Result.error;
|
|
@@ -4083,7 +4109,7 @@ var dashboardService = {
|
|
|
4083
4109
|
throw new Error("Company ID must be configured for detailed line requests.");
|
|
4084
4110
|
}
|
|
4085
4111
|
const [lineResult, metricsResult] = await Promise.all([
|
|
4086
|
-
supabase.from(linesTable).select("id, line_name, factory_id, monitoring_mode, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", lineIdToQuery).single(),
|
|
4112
|
+
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(),
|
|
4087
4113
|
supabase.from(lineMetricsTable).select("*").eq("line_id", lineIdToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
4088
4114
|
]);
|
|
4089
4115
|
if (lineResult.error) throw lineResult.error;
|
|
@@ -4899,25 +4925,25 @@ var workspaceService = {
|
|
|
4899
4925
|
if (!configuredFactoryId) {
|
|
4900
4926
|
throw new Error("Factory ID (entityConfig.factoryId) must be configured to update line thresholds.");
|
|
4901
4927
|
}
|
|
4902
|
-
let outputWorkspaces = workspaces.filter((ws) => ws.action_type === "
|
|
4928
|
+
let outputWorkspaces = workspaces.filter((ws) => ws.action_type === "output");
|
|
4903
4929
|
if (outputWorkspaces.length === 0) {
|
|
4904
|
-
const
|
|
4905
|
-
const
|
|
4930
|
+
const outputKeywords = ["output", "packaging", "package", "packing", "pack"];
|
|
4931
|
+
const possibleOutputWorkspaces = workspaces.filter((ws) => {
|
|
4906
4932
|
if (ws.workspace_id && typeof ws.workspace_id === "string") {
|
|
4907
4933
|
const wsIdLower = ws.workspace_id.toLowerCase();
|
|
4908
|
-
return
|
|
4934
|
+
return outputKeywords.some((keyword) => wsIdLower.includes(keyword));
|
|
4909
4935
|
}
|
|
4910
4936
|
return false;
|
|
4911
4937
|
});
|
|
4912
|
-
if (
|
|
4913
|
-
outputWorkspaces =
|
|
4938
|
+
if (possibleOutputWorkspaces.length > 0) {
|
|
4939
|
+
outputWorkspaces = possibleOutputWorkspaces;
|
|
4914
4940
|
} else {
|
|
4915
|
-
console.warn("[WorkspaceService] Unable to determine
|
|
4941
|
+
console.warn("[WorkspaceService] Unable to determine output-family workspaces for threshold calculation. Using all workspaces.");
|
|
4916
4942
|
outputWorkspaces = workspaces;
|
|
4917
4943
|
}
|
|
4918
4944
|
}
|
|
4919
4945
|
if (outputWorkspaces.length === 0 && workspaces.length > 0) {
|
|
4920
|
-
console.warn('[WorkspaceService] No workspaces with action_type "
|
|
4946
|
+
console.warn('[WorkspaceService] No workspaces with action_type "output" found for line threshold calculation. Thresholds might be zero.');
|
|
4921
4947
|
}
|
|
4922
4948
|
const totalDayOutput = outputWorkspaces.reduce((sum, ws) => sum + (ws.action_total_day_output || 0), 0);
|
|
4923
4949
|
const totalPPH = outputWorkspaces.reduce((sum, ws) => sum + (ws.action_pph_threshold || 0), 0);
|
|
@@ -8437,7 +8463,11 @@ var LinesService = class {
|
|
|
8437
8463
|
createdAt: line.created_at,
|
|
8438
8464
|
factoryId: line.factory_id,
|
|
8439
8465
|
monitoringMode: line.monitoring_mode ?? "output",
|
|
8440
|
-
assembly: line.assembly ?? false
|
|
8466
|
+
assembly: line.assembly ?? false,
|
|
8467
|
+
videoGridMetricMode: normalizeVideoGridMetricMode(
|
|
8468
|
+
line.video_grid_metric_mode,
|
|
8469
|
+
line.assembly ?? false
|
|
8470
|
+
)
|
|
8441
8471
|
}));
|
|
8442
8472
|
} catch (error) {
|
|
8443
8473
|
console.error("Error fetching lines:", error);
|
|
@@ -8481,7 +8511,11 @@ var LinesService = class {
|
|
|
8481
8511
|
createdAt: line.created_at,
|
|
8482
8512
|
factoryId: line.factory_id,
|
|
8483
8513
|
monitoringMode: line.monitoring_mode ?? "output",
|
|
8484
|
-
assembly: line.assembly ?? false
|
|
8514
|
+
assembly: line.assembly ?? false,
|
|
8515
|
+
videoGridMetricMode: normalizeVideoGridMetricMode(
|
|
8516
|
+
line.video_grid_metric_mode,
|
|
8517
|
+
line.assembly ?? false
|
|
8518
|
+
)
|
|
8485
8519
|
}));
|
|
8486
8520
|
} catch (error) {
|
|
8487
8521
|
console.error("Error fetching all lines:", error);
|
|
@@ -8533,7 +8567,12 @@ var LinesService = class {
|
|
|
8533
8567
|
isActive: data.enable,
|
|
8534
8568
|
createdAt: data.created_at,
|
|
8535
8569
|
factoryId: data.factory_id,
|
|
8536
|
-
monitoringMode: data.monitoring_mode ?? "output"
|
|
8570
|
+
monitoringMode: data.monitoring_mode ?? "output",
|
|
8571
|
+
assembly: data.assembly ?? false,
|
|
8572
|
+
videoGridMetricMode: normalizeVideoGridMetricMode(
|
|
8573
|
+
data.video_grid_metric_mode,
|
|
8574
|
+
data.assembly ?? false
|
|
8575
|
+
)
|
|
8537
8576
|
};
|
|
8538
8577
|
} catch (error) {
|
|
8539
8578
|
console.error("Error fetching line:", error);
|
|
@@ -9674,78 +9713,6 @@ var createStorageService = (supabase) => ({
|
|
|
9674
9713
|
}
|
|
9675
9714
|
});
|
|
9676
9715
|
|
|
9677
|
-
// src/lib/constants/idleTimeColors.ts
|
|
9678
|
-
var IDLE_TIME_REASON_COLORS = {
|
|
9679
|
-
"Operator Absent": {
|
|
9680
|
-
hex: "#dc2626",
|
|
9681
|
-
// red-600 - Critical/Urgent
|
|
9682
|
-
text: "text-red-600",
|
|
9683
|
-
bg: "bg-red-50",
|
|
9684
|
-
border: "border-red-200"
|
|
9685
|
-
},
|
|
9686
|
-
"No Material": {
|
|
9687
|
-
hex: "#f59e0b",
|
|
9688
|
-
// amber-500 - Warning/Supply Chain
|
|
9689
|
-
text: "text-amber-600",
|
|
9690
|
-
bg: "bg-amber-50",
|
|
9691
|
-
border: "border-amber-200"
|
|
9692
|
-
},
|
|
9693
|
-
"Machine Downtime": {
|
|
9694
|
-
hex: "#3b82f6",
|
|
9695
|
-
// blue-500 - Scheduled/Technical
|
|
9696
|
-
text: "text-blue-600",
|
|
9697
|
-
bg: "bg-blue-50",
|
|
9698
|
-
border: "border-blue-200"
|
|
9699
|
-
},
|
|
9700
|
-
"Operator Idle": {
|
|
9701
|
-
hex: "#8b5cf6",
|
|
9702
|
-
// violet-500 - Low Priority/Behavioral
|
|
9703
|
-
text: "text-violet-600",
|
|
9704
|
-
bg: "bg-violet-50",
|
|
9705
|
-
border: "border-violet-200"
|
|
9706
|
-
}
|
|
9707
|
-
};
|
|
9708
|
-
var FALLBACK_HEX_COLORS = [
|
|
9709
|
-
"#dc2626",
|
|
9710
|
-
// red-600
|
|
9711
|
-
"#ea580c",
|
|
9712
|
-
// orange-600
|
|
9713
|
-
"#ca8a04",
|
|
9714
|
-
// yellow-600
|
|
9715
|
-
"#16a34a",
|
|
9716
|
-
// green-600
|
|
9717
|
-
"#0891b2",
|
|
9718
|
-
// cyan-600
|
|
9719
|
-
"#2563eb",
|
|
9720
|
-
// blue-600
|
|
9721
|
-
"#7c3aed",
|
|
9722
|
-
// violet-600
|
|
9723
|
-
"#c026d3"
|
|
9724
|
-
// fuchsia-600
|
|
9725
|
-
];
|
|
9726
|
-
var DEFAULT_CONFIG3 = {
|
|
9727
|
-
hex: "#9ca3af",
|
|
9728
|
-
text: "text-gray-500",
|
|
9729
|
-
bg: "bg-gray-50",
|
|
9730
|
-
border: "border-gray-200"
|
|
9731
|
-
};
|
|
9732
|
-
function getIdleTimeReasonColor(reason, index = 0) {
|
|
9733
|
-
const normalizedReason = reason.includes("_") ? reason.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ") : reason;
|
|
9734
|
-
if (IDLE_TIME_REASON_COLORS[normalizedReason]) {
|
|
9735
|
-
return IDLE_TIME_REASON_COLORS[normalizedReason];
|
|
9736
|
-
}
|
|
9737
|
-
const lowerReason = normalizedReason.toLowerCase();
|
|
9738
|
-
const foundKey = Object.keys(IDLE_TIME_REASON_COLORS).find((k) => k.toLowerCase() === lowerReason);
|
|
9739
|
-
if (foundKey) {
|
|
9740
|
-
return IDLE_TIME_REASON_COLORS[foundKey];
|
|
9741
|
-
}
|
|
9742
|
-
const fallbackHex = FALLBACK_HEX_COLORS[index % FALLBACK_HEX_COLORS.length];
|
|
9743
|
-
return {
|
|
9744
|
-
...DEFAULT_CONFIG3,
|
|
9745
|
-
hex: fallbackHex
|
|
9746
|
-
};
|
|
9747
|
-
}
|
|
9748
|
-
|
|
9749
9716
|
// src/lib/services/idleTimeReasonService.ts
|
|
9750
9717
|
async function fetchIdleTimeReasons(params) {
|
|
9751
9718
|
const { workspaceId, lineId, date, shiftId, startDate, endDate, token } = params;
|
|
@@ -9803,7 +9770,12 @@ async function fetchIdleTimeReasons(params) {
|
|
|
9803
9770
|
}
|
|
9804
9771
|
function transformToChartData(data) {
|
|
9805
9772
|
return data.reasons.map((reason) => ({
|
|
9806
|
-
name: formatReasonLabel(reason.reason),
|
|
9773
|
+
name: reason.display_name || formatReasonLabel(reason.reason_key || reason.reason),
|
|
9774
|
+
reasonKey: reason.reason_key || reason.reason,
|
|
9775
|
+
displayName: reason.display_name || formatReasonLabel(reason.reason_key || reason.reason),
|
|
9776
|
+
paletteToken: reason.palette_token,
|
|
9777
|
+
iconToken: reason.icon_token,
|
|
9778
|
+
isKnown: reason.is_known,
|
|
9807
9779
|
value: reason.percentage,
|
|
9808
9780
|
totalDurationSeconds: reason.total_duration_seconds,
|
|
9809
9781
|
efficiencyLossPercentage: reason.efficiency_loss_percentage ?? null
|
|
@@ -9812,9 +9784,6 @@ function transformToChartData(data) {
|
|
|
9812
9784
|
function formatReasonLabel(reason) {
|
|
9813
9785
|
return reason.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
9814
9786
|
}
|
|
9815
|
-
function getReasonColor(reason, index = 0) {
|
|
9816
|
-
return getIdleTimeReasonColor(reason, index).hex;
|
|
9817
|
-
}
|
|
9818
9787
|
|
|
9819
9788
|
// src/lib/services/sessionTracker.ts
|
|
9820
9789
|
function generateSessionId() {
|
|
@@ -11537,6 +11506,52 @@ var workspaceMetricsStore = {
|
|
|
11537
11506
|
}
|
|
11538
11507
|
};
|
|
11539
11508
|
|
|
11509
|
+
// src/lib/constants/actions.ts
|
|
11510
|
+
var ACTION_NAMES = {
|
|
11511
|
+
/** Assembly operations */
|
|
11512
|
+
ASSEMBLY: "Assembly",
|
|
11513
|
+
/** Packaging operations */
|
|
11514
|
+
PACKAGING: "Packaging",
|
|
11515
|
+
/** Output operations (user-facing label for the legacy packaging family) */
|
|
11516
|
+
OUTPUT: "Output",
|
|
11517
|
+
/** Inspection operations */
|
|
11518
|
+
INSPECTION: "Inspection",
|
|
11519
|
+
/** Testing operations */
|
|
11520
|
+
TESTING: "Testing",
|
|
11521
|
+
/** Quality control operations */
|
|
11522
|
+
QUALITY_CONTROL: "Quality Control"
|
|
11523
|
+
};
|
|
11524
|
+
var ACTION_FAMILIES = {
|
|
11525
|
+
ASSEMBLY: "assembly",
|
|
11526
|
+
OUTPUT: "output",
|
|
11527
|
+
OTHER: "other"
|
|
11528
|
+
};
|
|
11529
|
+
var normalizeActionFamily = (params) => {
|
|
11530
|
+
const explicitValue = (params.actionFamily ?? params.actionType ?? "").trim().toLowerCase();
|
|
11531
|
+
if (explicitValue === ACTION_FAMILIES.ASSEMBLY) return ACTION_FAMILIES.ASSEMBLY;
|
|
11532
|
+
if (explicitValue === ACTION_FAMILIES.OUTPUT || explicitValue === "packaging") {
|
|
11533
|
+
return ACTION_FAMILIES.OUTPUT;
|
|
11534
|
+
}
|
|
11535
|
+
if (explicitValue === ACTION_FAMILIES.OTHER) return ACTION_FAMILIES.OTHER;
|
|
11536
|
+
const normalizedName = (params.actionName ?? "").trim().toLowerCase();
|
|
11537
|
+
if (!normalizedName) return null;
|
|
11538
|
+
if (normalizedName === "output" || normalizedName.includes("packag")) {
|
|
11539
|
+
return ACTION_FAMILIES.OUTPUT;
|
|
11540
|
+
}
|
|
11541
|
+
if (normalizedName.includes("assembly")) {
|
|
11542
|
+
return ACTION_FAMILIES.ASSEMBLY;
|
|
11543
|
+
}
|
|
11544
|
+
return ACTION_FAMILIES.OTHER;
|
|
11545
|
+
};
|
|
11546
|
+
var getActionDisplayName = (params) => {
|
|
11547
|
+
const explicitDisplayName = (params.displayName ?? "").trim();
|
|
11548
|
+
if (explicitDisplayName) return explicitDisplayName;
|
|
11549
|
+
const family = normalizeActionFamily(params);
|
|
11550
|
+
if (family === ACTION_FAMILIES.OUTPUT) return ACTION_NAMES.OUTPUT;
|
|
11551
|
+
if (family === ACTION_FAMILIES.ASSEMBLY) return ACTION_NAMES.ASSEMBLY;
|
|
11552
|
+
return (params.actionName ?? "").trim();
|
|
11553
|
+
};
|
|
11554
|
+
|
|
11540
11555
|
// src/lib/utils/workspaceMetricsTransform.ts
|
|
11541
11556
|
var coerceNumber = (value, fallback = 0) => {
|
|
11542
11557
|
const num = typeof value === "number" ? value : Number(value);
|
|
@@ -11726,10 +11741,17 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
11726
11741
|
const targetOutput = coerceNumber(data.target_output ?? data.total_day_output, 0);
|
|
11727
11742
|
const idealOutput = coerceNumber(data.ideal_output ?? data.ideal_output_until_now, 0);
|
|
11728
11743
|
const outputDifference = totalActions - idealOutput;
|
|
11744
|
+
const hourlyCycleTimes = Array.isArray(data.hourly_cycle_times) ? data.hourly_cycle_times.map((value) => coerceNumber(value, 0)) : [];
|
|
11729
11745
|
const totalWorkspacesValue = coerceNumber(
|
|
11730
11746
|
data.total_workspaces ?? lineMetricsById?.[data.line_id || ""]?.total_workspaces ?? workspaceConfig.totalWorkspaces,
|
|
11731
11747
|
0
|
|
11732
11748
|
);
|
|
11749
|
+
const actionFamily = normalizeActionFamily({
|
|
11750
|
+
actionFamily: data.action_family,
|
|
11751
|
+
actionType: data.action_type,
|
|
11752
|
+
actionName: data.action_name
|
|
11753
|
+
});
|
|
11754
|
+
const actionType = actionFamily === "assembly" || actionFamily === "output" ? actionFamily : null;
|
|
11733
11755
|
return {
|
|
11734
11756
|
workspace_id: data.workspace_id,
|
|
11735
11757
|
workspace_name: data.workspace_name,
|
|
@@ -11740,8 +11762,20 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
11740
11762
|
company_name: data.company_name || "",
|
|
11741
11763
|
date: data.date,
|
|
11742
11764
|
shift_id: shiftId,
|
|
11743
|
-
action_name:
|
|
11744
|
-
|
|
11765
|
+
action_name: getActionDisplayName({
|
|
11766
|
+
displayName: data.action_display_name,
|
|
11767
|
+
actionFamily: data.action_family,
|
|
11768
|
+
actionType: data.action_type,
|
|
11769
|
+
actionName: data.action_name
|
|
11770
|
+
}),
|
|
11771
|
+
action_type: actionType,
|
|
11772
|
+
action_family: actionFamily,
|
|
11773
|
+
action_display_name: getActionDisplayName({
|
|
11774
|
+
displayName: data.action_display_name,
|
|
11775
|
+
actionFamily: data.action_family,
|
|
11776
|
+
actionType: data.action_type,
|
|
11777
|
+
actionName: data.action_name
|
|
11778
|
+
}),
|
|
11745
11779
|
shift_start: shiftStart,
|
|
11746
11780
|
shift_end: shiftEnd,
|
|
11747
11781
|
shift_type: shiftType,
|
|
@@ -11754,6 +11788,7 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
11754
11788
|
avg_efficiency: coerceNumber(data.efficiency ?? data.avg_efficiency, 0),
|
|
11755
11789
|
total_actions: totalActions,
|
|
11756
11790
|
hourly_action_counts: hourlyActionCounts,
|
|
11791
|
+
hourly_cycle_times: hourlyCycleTimes,
|
|
11757
11792
|
workspace_rank: coerceNumber(data.workspace_rank, 0),
|
|
11758
11793
|
total_workspaces: totalWorkspacesValue,
|
|
11759
11794
|
ideal_output_until_now: idealOutput,
|
|
@@ -13292,6 +13327,12 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13292
13327
|
const transformedWorkspaceData = allWorkspaceMetrics.map((item) => {
|
|
13293
13328
|
const idleTimeValue = typeof item.idle_time === "number" ? item.idle_time : Number(item.idle_time);
|
|
13294
13329
|
const idleTimeSeconds = Number.isFinite(idleTimeValue) ? idleTimeValue : void 0;
|
|
13330
|
+
const actionFamily = normalizeActionFamily({
|
|
13331
|
+
actionFamily: item.action_family,
|
|
13332
|
+
actionType: item.action_type,
|
|
13333
|
+
actionName: item.action_name
|
|
13334
|
+
});
|
|
13335
|
+
const actionType = actionFamily === "assembly" || actionFamily === "output" ? actionFamily : null;
|
|
13295
13336
|
return {
|
|
13296
13337
|
company_id: item.company_id || companyId,
|
|
13297
13338
|
line_id: item.line_id,
|
|
@@ -13311,7 +13352,18 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId, userAccessibleLineIds
|
|
|
13311
13352
|
monitoring_mode: item.monitoring_mode ?? void 0,
|
|
13312
13353
|
idle_time: idleTimeSeconds,
|
|
13313
13354
|
assembly_enabled: item.assembly_enabled ?? false,
|
|
13314
|
-
|
|
13355
|
+
video_grid_metric_mode: normalizeVideoGridMetricMode(
|
|
13356
|
+
item.video_grid_metric_mode,
|
|
13357
|
+
item.assembly_enabled ?? false
|
|
13358
|
+
),
|
|
13359
|
+
action_type: actionType,
|
|
13360
|
+
action_family: actionFamily,
|
|
13361
|
+
action_display_name: getActionDisplayName({
|
|
13362
|
+
displayName: item.action_display_name,
|
|
13363
|
+
actionFamily: item.action_family,
|
|
13364
|
+
actionType: item.action_type,
|
|
13365
|
+
actionName: item.action_name
|
|
13366
|
+
}),
|
|
13315
13367
|
recent_flow_mode: item.recent_flow_mode ?? void 0,
|
|
13316
13368
|
recent_flow_percent: item.recent_flow_percent ?? null,
|
|
13317
13369
|
recent_flow_actual_rate_pph: item.recent_flow_actual_rate_pph ?? null,
|
|
@@ -19231,8 +19283,115 @@ function useIdleTimeReasons({
|
|
|
19231
19283
|
refetch: fetchData
|
|
19232
19284
|
};
|
|
19233
19285
|
}
|
|
19286
|
+
var DEFAULT_PALETTE_TOKEN = "slate";
|
|
19287
|
+
var DEFAULT_ICON_TOKEN = "help-circle";
|
|
19288
|
+
var PALETTE_CONFIG = {
|
|
19289
|
+
red: {
|
|
19290
|
+
hex: "#dc2626",
|
|
19291
|
+
textClass: "text-red-600",
|
|
19292
|
+
bgClass: "bg-red-50",
|
|
19293
|
+
borderClass: "border-red-200"
|
|
19294
|
+
},
|
|
19295
|
+
amber: {
|
|
19296
|
+
hex: "#f59e0b",
|
|
19297
|
+
textClass: "text-amber-600",
|
|
19298
|
+
bgClass: "bg-amber-50",
|
|
19299
|
+
borderClass: "border-amber-200"
|
|
19300
|
+
},
|
|
19301
|
+
blue: {
|
|
19302
|
+
hex: "#3b82f6",
|
|
19303
|
+
textClass: "text-blue-600",
|
|
19304
|
+
bgClass: "bg-blue-50",
|
|
19305
|
+
borderClass: "border-blue-200"
|
|
19306
|
+
},
|
|
19307
|
+
violet: {
|
|
19308
|
+
hex: "#8b5cf6",
|
|
19309
|
+
textClass: "text-violet-600",
|
|
19310
|
+
bgClass: "bg-violet-50",
|
|
19311
|
+
borderClass: "border-violet-200"
|
|
19312
|
+
},
|
|
19313
|
+
emerald: {
|
|
19314
|
+
hex: "#10b981",
|
|
19315
|
+
textClass: "text-emerald-600",
|
|
19316
|
+
bgClass: "bg-emerald-50",
|
|
19317
|
+
borderClass: "border-emerald-200"
|
|
19318
|
+
},
|
|
19319
|
+
cyan: {
|
|
19320
|
+
hex: "#0891b2",
|
|
19321
|
+
textClass: "text-cyan-600",
|
|
19322
|
+
bgClass: "bg-cyan-50",
|
|
19323
|
+
borderClass: "border-cyan-200"
|
|
19324
|
+
},
|
|
19325
|
+
slate: {
|
|
19326
|
+
hex: "#64748b",
|
|
19327
|
+
textClass: "text-slate-600",
|
|
19328
|
+
bgClass: "bg-slate-50",
|
|
19329
|
+
borderClass: "border-slate-200"
|
|
19330
|
+
}
|
|
19331
|
+
};
|
|
19332
|
+
var ICON_CONFIG = {
|
|
19333
|
+
"alert-triangle": AlertTriangle,
|
|
19334
|
+
"refresh-cw": RefreshCw,
|
|
19335
|
+
package: Package,
|
|
19336
|
+
clock: Clock,
|
|
19337
|
+
"user-x": UserX,
|
|
19338
|
+
wrench: Wrench,
|
|
19339
|
+
activity: Activity,
|
|
19340
|
+
"help-circle": HelpCircle
|
|
19341
|
+
};
|
|
19342
|
+
var humanizeIdleReasonLabel = (value) => {
|
|
19343
|
+
const text = String(value || "").trim();
|
|
19344
|
+
if (!text) {
|
|
19345
|
+
return "Unknown";
|
|
19346
|
+
}
|
|
19347
|
+
return text.replace(/_/g, " ").split(/\s+/).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
19348
|
+
};
|
|
19349
|
+
var normalizePaletteToken = (value) => {
|
|
19350
|
+
const token = String(value || "").trim().toLowerCase();
|
|
19351
|
+
if (token in PALETTE_CONFIG) {
|
|
19352
|
+
return token;
|
|
19353
|
+
}
|
|
19354
|
+
return DEFAULT_PALETTE_TOKEN;
|
|
19355
|
+
};
|
|
19356
|
+
var normalizeIconToken = (value) => {
|
|
19357
|
+
const token = String(value || "").trim().toLowerCase();
|
|
19358
|
+
if (token in ICON_CONFIG) {
|
|
19359
|
+
return token;
|
|
19360
|
+
}
|
|
19361
|
+
return DEFAULT_ICON_TOKEN;
|
|
19362
|
+
};
|
|
19363
|
+
var getIdleReasonPresentation = (metadata) => {
|
|
19364
|
+
const label = typeof metadata?.label === "string" && metadata.label.trim() ? metadata.label.trim() : null;
|
|
19365
|
+
const displayName = typeof metadata?.displayName === "string" && metadata.displayName.trim() ? metadata.displayName.trim() : humanizeIdleReasonLabel(label);
|
|
19366
|
+
const paletteToken = normalizePaletteToken(metadata?.paletteToken);
|
|
19367
|
+
const iconToken = normalizeIconToken(metadata?.iconToken);
|
|
19368
|
+
return {
|
|
19369
|
+
label,
|
|
19370
|
+
displayName,
|
|
19371
|
+
paletteToken,
|
|
19372
|
+
iconToken,
|
|
19373
|
+
isKnown: Boolean(metadata?.isKnown),
|
|
19374
|
+
Icon: ICON_CONFIG[iconToken],
|
|
19375
|
+
...PALETTE_CONFIG[paletteToken]
|
|
19376
|
+
};
|
|
19377
|
+
};
|
|
19378
|
+
var getIdleReasonHexColor = (metadata) => getIdleReasonPresentation(metadata).hex;
|
|
19234
19379
|
|
|
19235
19380
|
// src/lib/services/clipClassificationService.ts
|
|
19381
|
+
var normalizeClassification = (value) => {
|
|
19382
|
+
const rawLabel = typeof value?.label === "string" ? value.label.trim() : "";
|
|
19383
|
+
const label = rawLabel || void 0;
|
|
19384
|
+
const parsedConfidence = typeof value?.confidence === "number" ? value.confidence : typeof value?.confidence === "string" ? Number(value.confidence) : void 0;
|
|
19385
|
+
return {
|
|
19386
|
+
status: value?.status === "classified" ? "classified" : "processing",
|
|
19387
|
+
label,
|
|
19388
|
+
displayName: typeof value?.display_name === "string" ? value.display_name : label ? humanizeIdleReasonLabel(label) : void 0,
|
|
19389
|
+
paletteToken: typeof value?.palette_token === "string" ? value.palette_token : void 0,
|
|
19390
|
+
iconToken: typeof value?.icon_token === "string" ? value.icon_token : void 0,
|
|
19391
|
+
isKnown: typeof value?.is_known === "boolean" ? value.is_known : void 0,
|
|
19392
|
+
confidence: parsedConfidence !== void 0 && Number.isFinite(parsedConfidence) ? parsedConfidence : void 0
|
|
19393
|
+
};
|
|
19394
|
+
};
|
|
19236
19395
|
function parseCleanLabel(rawLabel) {
|
|
19237
19396
|
if (!rawLabel) return null;
|
|
19238
19397
|
const patterns = [
|
|
@@ -19286,7 +19445,13 @@ async function fetchClassifications(clipIds, token) {
|
|
|
19286
19445
|
);
|
|
19287
19446
|
}
|
|
19288
19447
|
const data = await response.json();
|
|
19289
|
-
|
|
19448
|
+
const rawClassifications = data.classifications || {};
|
|
19449
|
+
return Object.fromEntries(
|
|
19450
|
+
Object.entries(rawClassifications).map(([clipId, classification]) => [
|
|
19451
|
+
clipId,
|
|
19452
|
+
normalizeClassification(classification)
|
|
19453
|
+
])
|
|
19454
|
+
);
|
|
19290
19455
|
} catch (error) {
|
|
19291
19456
|
console.error("Error fetching chunk:", error);
|
|
19292
19457
|
return Object.fromEntries(
|
|
@@ -19327,21 +19492,30 @@ function useClassificationRealtimeUpdates({
|
|
|
19327
19492
|
},
|
|
19328
19493
|
(payload) => {
|
|
19329
19494
|
console.log("[useClassificationRealtimeUpdates] New classification:", payload);
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
|
|
19335
|
-
|
|
19336
|
-
|
|
19337
|
-
|
|
19338
|
-
|
|
19339
|
-
|
|
19340
|
-
|
|
19495
|
+
void (async () => {
|
|
19496
|
+
try {
|
|
19497
|
+
const { clip_id, clip_label, confidence_score } = payload.new;
|
|
19498
|
+
const token = await getAccessTokenOrRedirect(supabase, { redirectReason: "session_expired" });
|
|
19499
|
+
const fetched = await fetchClassifications([clip_id], token);
|
|
19500
|
+
const classification = fetched[clip_id];
|
|
19501
|
+
if (classification) {
|
|
19502
|
+
onClassificationUpdate(clip_id, classification);
|
|
19503
|
+
return;
|
|
19504
|
+
}
|
|
19505
|
+
const parsedLabel = parseCleanLabel(clip_label);
|
|
19506
|
+
if (parsedLabel) {
|
|
19507
|
+
onClassificationUpdate(clip_id, {
|
|
19508
|
+
status: "classified",
|
|
19509
|
+
label: parsedLabel,
|
|
19510
|
+
confidence: confidence_score || 0
|
|
19511
|
+
});
|
|
19512
|
+
} else {
|
|
19513
|
+
console.warn("[useClassificationRealtimeUpdates] Failed to parse label:", clip_label);
|
|
19514
|
+
}
|
|
19515
|
+
} catch (error) {
|
|
19516
|
+
console.error("[useClassificationRealtimeUpdates] Error processing update:", error);
|
|
19341
19517
|
}
|
|
19342
|
-
}
|
|
19343
|
-
console.error("[useClassificationRealtimeUpdates] Error processing update:", error);
|
|
19344
|
-
}
|
|
19518
|
+
})();
|
|
19345
19519
|
}
|
|
19346
19520
|
).subscribe((status) => {
|
|
19347
19521
|
console.log(`[useClassificationRealtimeUpdates] Subscription status:`, status);
|
|
@@ -32373,90 +32547,99 @@ var CycleTimeOverTimeChart = ({
|
|
|
32373
32547
|
data,
|
|
32374
32548
|
idealCycleTime,
|
|
32375
32549
|
shiftStart,
|
|
32376
|
-
|
|
32550
|
+
shiftEnd,
|
|
32551
|
+
xAxisMode = "recent",
|
|
32552
|
+
datasetKey,
|
|
32553
|
+
className = "",
|
|
32554
|
+
showIdleTime = false,
|
|
32555
|
+
idleTimeData = []
|
|
32377
32556
|
}) => {
|
|
32378
32557
|
const MAX_DATA_POINTS = 40;
|
|
32379
32558
|
const containerRef = React141__default.useRef(null);
|
|
32380
32559
|
const [containerReady, setContainerReady] = React141__default.useState(false);
|
|
32381
|
-
const
|
|
32382
|
-
const [hours, minutes] =
|
|
32383
|
-
|
|
32560
|
+
const parseTimeToMinutes3 = (value) => {
|
|
32561
|
+
const [hours, minutes] = value.split(":").map(Number);
|
|
32562
|
+
if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return 0;
|
|
32563
|
+
return hours * 60 + minutes;
|
|
32384
32564
|
};
|
|
32385
|
-
|
|
32386
|
-
|
|
32387
|
-
|
|
32565
|
+
const formatHourLabel = (slotIndex) => {
|
|
32566
|
+
const baseMinutes = parseTimeToMinutes3(shiftStart);
|
|
32567
|
+
const absoluteMinutes = baseMinutes + slotIndex * 60;
|
|
32568
|
+
const hour24 = Math.floor(absoluteMinutes % (24 * 60) / 60);
|
|
32569
|
+
const ampm = hour24 >= 12 ? "PM" : "AM";
|
|
32570
|
+
const hour12 = hour24 % 12 || 12;
|
|
32571
|
+
return `${hour12}${ampm}`;
|
|
32572
|
+
};
|
|
32573
|
+
const formatHourRangeLabel = (slotIndex) => {
|
|
32574
|
+
const startLabel = formatHourLabel(slotIndex);
|
|
32575
|
+
const endLabel = shiftEnd && slotIndex === DURATION - 1 ? formatHourLabel(slotIndex + 1) : formatHourLabel(slotIndex + 1);
|
|
32576
|
+
return `${startLabel} - ${endLabel}`;
|
|
32388
32577
|
};
|
|
32578
|
+
const getDisplayData = React141__default.useCallback((rawData) => {
|
|
32579
|
+
if (xAxisMode === "hourly") return rawData;
|
|
32580
|
+
return rawData.slice(Math.max(0, rawData.length - MAX_DATA_POINTS));
|
|
32581
|
+
}, [xAxisMode]);
|
|
32389
32582
|
const displayData = getDisplayData(data);
|
|
32390
32583
|
const DURATION = displayData.length;
|
|
32391
|
-
const
|
|
32392
|
-
const
|
|
32393
|
-
const
|
|
32394
|
-
const
|
|
32395
|
-
|
|
32396
|
-
|
|
32397
|
-
|
|
32398
|
-
const animate = (currentTime) => {
|
|
32399
|
-
const elapsed = currentTime - startTime;
|
|
32400
|
-
const progress7 = Math.min(elapsed / duration, 1);
|
|
32401
|
-
const easeOutQuint = (t) => 1 - Math.pow(1 - t, 5);
|
|
32402
|
-
const easedProgress = easeOutQuint(progress7);
|
|
32403
|
-
const newData = startData.map((start, index) => {
|
|
32404
|
-
const target = targetData[index] || 0;
|
|
32405
|
-
const change = target - start;
|
|
32406
|
-
const scaleFactor = Math.min(1, 50 / Math.abs(change || 1));
|
|
32407
|
-
const adjustedEasing = progress7 * (scaleFactor + (1 - scaleFactor) * easedProgress);
|
|
32408
|
-
return start + change * adjustedEasing;
|
|
32409
|
-
});
|
|
32410
|
-
setAnimatedData(newData);
|
|
32411
|
-
prevDataRef.current = newData;
|
|
32412
|
-
if (progress7 < 1) {
|
|
32413
|
-
animationFrameRef.current = requestAnimationFrame(animate);
|
|
32414
|
-
} else {
|
|
32415
|
-
setAnimatedData(targetData);
|
|
32416
|
-
prevDataRef.current = targetData;
|
|
32417
|
-
}
|
|
32418
|
-
};
|
|
32419
|
-
if (animationFrameRef.current) {
|
|
32420
|
-
cancelAnimationFrame(animationFrameRef.current);
|
|
32421
|
-
}
|
|
32422
|
-
animationFrameRef.current = requestAnimationFrame(animate);
|
|
32423
|
-
}, []);
|
|
32584
|
+
const effectiveDatasetKey = datasetKey || `cycle-time:${xAxisMode}`;
|
|
32585
|
+
const [animatedDatasetKey, setAnimatedDatasetKey] = React141__default.useState(null);
|
|
32586
|
+
const shouldAnimate = animatedDatasetKey !== effectiveDatasetKey;
|
|
32587
|
+
const handleAnimationEnd = React141__default.useCallback(() => {
|
|
32588
|
+
setAnimatedDatasetKey((currentValue) => currentValue === effectiveDatasetKey ? currentValue : effectiveDatasetKey);
|
|
32589
|
+
}, [effectiveDatasetKey]);
|
|
32590
|
+
const finalData = displayData;
|
|
32424
32591
|
React141__default.useEffect(() => {
|
|
32425
|
-
|
|
32426
|
-
|
|
32427
|
-
|
|
32592
|
+
const containerNode = containerRef.current;
|
|
32593
|
+
if (!containerNode) {
|
|
32594
|
+
setContainerReady(true);
|
|
32595
|
+
return void 0;
|
|
32428
32596
|
}
|
|
32429
|
-
|
|
32430
|
-
|
|
32431
|
-
cancelAnimationFrame(animationFrameRef.current);
|
|
32432
|
-
}
|
|
32433
|
-
};
|
|
32434
|
-
}, [data, animateToNewData]);
|
|
32435
|
-
React141__default.useEffect(() => {
|
|
32597
|
+
let frameId = null;
|
|
32598
|
+
let resizeObserver = null;
|
|
32436
32599
|
const checkContainerDimensions = () => {
|
|
32437
|
-
|
|
32438
|
-
|
|
32439
|
-
|
|
32440
|
-
|
|
32441
|
-
}
|
|
32600
|
+
const rect = containerNode.getBoundingClientRect();
|
|
32601
|
+
const isReady = rect.width > 0 && rect.height > 0;
|
|
32602
|
+
if (isReady) {
|
|
32603
|
+
setContainerReady(true);
|
|
32442
32604
|
}
|
|
32605
|
+
return isReady;
|
|
32443
32606
|
};
|
|
32444
|
-
checkContainerDimensions()
|
|
32445
|
-
|
|
32446
|
-
if (containerRef.current) {
|
|
32447
|
-
resizeObserver.observe(containerRef.current);
|
|
32607
|
+
if (checkContainerDimensions()) {
|
|
32608
|
+
return void 0;
|
|
32448
32609
|
}
|
|
32449
|
-
|
|
32610
|
+
frameId = window.requestAnimationFrame(() => {
|
|
32611
|
+
checkContainerDimensions();
|
|
32612
|
+
});
|
|
32613
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
32614
|
+
resizeObserver = new ResizeObserver(() => {
|
|
32615
|
+
if (checkContainerDimensions() && resizeObserver) {
|
|
32616
|
+
resizeObserver.disconnect();
|
|
32617
|
+
resizeObserver = null;
|
|
32618
|
+
}
|
|
32619
|
+
});
|
|
32620
|
+
resizeObserver.observe(containerNode);
|
|
32621
|
+
} else {
|
|
32450
32622
|
setContainerReady(true);
|
|
32451
|
-
}
|
|
32623
|
+
}
|
|
32452
32624
|
return () => {
|
|
32453
|
-
|
|
32454
|
-
|
|
32625
|
+
if (frameId !== null) {
|
|
32626
|
+
window.cancelAnimationFrame(frameId);
|
|
32627
|
+
}
|
|
32628
|
+
resizeObserver?.disconnect();
|
|
32455
32629
|
};
|
|
32456
32630
|
}, []);
|
|
32631
|
+
const labelInterval = React141__default.useMemo(() => {
|
|
32632
|
+
if (xAxisMode === "hourly") {
|
|
32633
|
+
return Math.max(1, Math.ceil(DURATION / 8));
|
|
32634
|
+
}
|
|
32635
|
+
return 5;
|
|
32636
|
+
}, [xAxisMode, DURATION]);
|
|
32457
32637
|
const formatTimeLabel = (dataIndex) => {
|
|
32458
32638
|
if (DURATION === 0) return "";
|
|
32459
|
-
if (dataIndex %
|
|
32639
|
+
if (dataIndex % labelInterval !== 0 && dataIndex !== DURATION - 1) return "";
|
|
32640
|
+
if (xAxisMode === "hourly") {
|
|
32641
|
+
return formatHourLabel(dataIndex);
|
|
32642
|
+
}
|
|
32460
32643
|
const timeAgo = (DURATION - 1 - dataIndex) * 90;
|
|
32461
32644
|
const minutes = Math.floor(timeAgo / 60);
|
|
32462
32645
|
const seconds = timeAgo % 60;
|
|
@@ -32470,6 +32653,9 @@ var CycleTimeOverTimeChart = ({
|
|
|
32470
32653
|
};
|
|
32471
32654
|
const formatTooltipTime = (dataIndex) => {
|
|
32472
32655
|
if (DURATION === 0) return "";
|
|
32656
|
+
if (xAxisMode === "hourly") {
|
|
32657
|
+
return formatHourRangeLabel(dataIndex);
|
|
32658
|
+
}
|
|
32473
32659
|
const timeAgo = (DURATION - 1 - dataIndex) * 90;
|
|
32474
32660
|
const minutes = Math.floor(timeAgo / 60);
|
|
32475
32661
|
const seconds = timeAgo % 60;
|
|
@@ -32483,39 +32669,40 @@ var CycleTimeOverTimeChart = ({
|
|
|
32483
32669
|
return `${minutes} minutes ${seconds} seconds ago`;
|
|
32484
32670
|
}
|
|
32485
32671
|
};
|
|
32486
|
-
const chartData = Array.from({ length: DURATION }, (_, i) => {
|
|
32672
|
+
const chartData = React141__default.useMemo(() => Array.from({ length: DURATION }, (_, i) => {
|
|
32487
32673
|
return {
|
|
32488
32674
|
timeIndex: i,
|
|
32489
32675
|
label: formatTimeLabel(i),
|
|
32490
32676
|
tooltip: formatTooltipTime(i),
|
|
32491
|
-
cycleTime:
|
|
32492
|
-
|
|
32677
|
+
cycleTime: finalData[i] || 0,
|
|
32678
|
+
idleMinutes: showIdleTime && idleTimeData && idleTimeData[i] || 0,
|
|
32679
|
+
color: (finalData[i] || 0) <= idealCycleTime ? "#00AB45" : "#E34329"
|
|
32493
32680
|
};
|
|
32494
|
-
});
|
|
32495
|
-
const renderLegend = () =>
|
|
32496
|
-
|
|
32497
|
-
/* @__PURE__ */ jsxs("
|
|
32498
|
-
"
|
|
32499
|
-
|
|
32500
|
-
|
|
32501
|
-
|
|
32502
|
-
] }) });
|
|
32681
|
+
}), [DURATION, finalData, showIdleTime, idleTimeData, idealCycleTime]);
|
|
32682
|
+
const renderLegend = () => {
|
|
32683
|
+
if (!showIdleTime) return null;
|
|
32684
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-start text-[10px] font-bold text-gray-500 mb-6 tracking-[0.05em] gap-5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
32685
|
+
/* @__PURE__ */ jsx("div", { className: "w-2.5 h-2.5 rounded-full bg-[#f59e0b]" }),
|
|
32686
|
+
/* @__PURE__ */ jsx("span", { children: "Idle Time (min)" })
|
|
32687
|
+
] }) });
|
|
32688
|
+
};
|
|
32503
32689
|
return /* @__PURE__ */ jsxs(
|
|
32504
32690
|
"div",
|
|
32505
32691
|
{
|
|
32506
32692
|
ref: containerRef,
|
|
32507
|
-
className: `w-full h-full min-w-0 relative pb-
|
|
32693
|
+
className: `w-full h-full min-w-0 flex flex-col relative pb-2 ${className}`,
|
|
32508
32694
|
style: { minHeight: "200px", minWidth: 0 },
|
|
32509
32695
|
children: [
|
|
32510
|
-
|
|
32696
|
+
renderLegend(),
|
|
32697
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 w-full", children: containerReady ? /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
|
|
32511
32698
|
LineChart$1,
|
|
32512
32699
|
{
|
|
32513
32700
|
data: chartData,
|
|
32514
32701
|
margin: {
|
|
32515
|
-
top:
|
|
32702
|
+
top: 5,
|
|
32516
32703
|
right: 30,
|
|
32517
32704
|
bottom: 25,
|
|
32518
|
-
left:
|
|
32705
|
+
left: 10
|
|
32519
32706
|
},
|
|
32520
32707
|
children: [
|
|
32521
32708
|
/* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", vertical: false }),
|
|
@@ -32525,17 +32712,18 @@ var CycleTimeOverTimeChart = ({
|
|
|
32525
32712
|
dataKey: "label",
|
|
32526
32713
|
tick: { fontSize: 11 },
|
|
32527
32714
|
interval: 0,
|
|
32528
|
-
angle: -30,
|
|
32529
|
-
textAnchor: "end",
|
|
32530
|
-
tickMargin: 15,
|
|
32531
|
-
height: 60
|
|
32715
|
+
angle: xAxisMode === "hourly" ? 0 : -30,
|
|
32716
|
+
textAnchor: xAxisMode === "hourly" ? "middle" : "end",
|
|
32717
|
+
tickMargin: xAxisMode === "hourly" ? 8 : 15,
|
|
32718
|
+
height: xAxisMode === "hourly" ? 40 : 60
|
|
32532
32719
|
}
|
|
32533
32720
|
),
|
|
32534
32721
|
/* @__PURE__ */ jsx(
|
|
32535
32722
|
YAxis,
|
|
32536
32723
|
{
|
|
32537
32724
|
tickMargin: 8,
|
|
32538
|
-
width:
|
|
32725
|
+
width: 45,
|
|
32726
|
+
yAxisId: "cycle",
|
|
32539
32727
|
domain: ["auto", "auto"],
|
|
32540
32728
|
ticks: [0, idealCycleTime, ...Array.from({ length: 4 }, (_, i) => (i + 1) * Math.ceil(idealCycleTime / 2))].sort((a, b) => a - b),
|
|
32541
32729
|
tickFormatter: (value) => String(value),
|
|
@@ -32559,6 +32747,20 @@ var CycleTimeOverTimeChart = ({
|
|
|
32559
32747
|
}
|
|
32560
32748
|
}
|
|
32561
32749
|
),
|
|
32750
|
+
showIdleTime && /* @__PURE__ */ jsx(
|
|
32751
|
+
YAxis,
|
|
32752
|
+
{
|
|
32753
|
+
yAxisId: "idle",
|
|
32754
|
+
orientation: "right",
|
|
32755
|
+
tickMargin: 8,
|
|
32756
|
+
width: 35,
|
|
32757
|
+
domain: [0, 60],
|
|
32758
|
+
tickFormatter: (value) => `${value}m`,
|
|
32759
|
+
tick: { fontSize: 11, fill: "#f59e0b" },
|
|
32760
|
+
axisLine: false,
|
|
32761
|
+
tickLine: false
|
|
32762
|
+
}
|
|
32763
|
+
),
|
|
32562
32764
|
/* @__PURE__ */ jsx(
|
|
32563
32765
|
Tooltip,
|
|
32564
32766
|
{
|
|
@@ -32586,8 +32788,11 @@ var CycleTimeOverTimeChart = ({
|
|
|
32586
32788
|
}
|
|
32587
32789
|
return label;
|
|
32588
32790
|
},
|
|
32589
|
-
formatter: (value) => {
|
|
32791
|
+
formatter: (value, name) => {
|
|
32590
32792
|
const numValue = typeof value === "number" ? value : Number(value);
|
|
32793
|
+
if (name === "idleMinutes") {
|
|
32794
|
+
return [`${numValue.toFixed(0)} minutes`, "Idle Time"];
|
|
32795
|
+
}
|
|
32591
32796
|
return [`${numValue.toFixed(1)} seconds`, "Cycle Time"];
|
|
32592
32797
|
},
|
|
32593
32798
|
animationDuration: 200
|
|
@@ -32597,6 +32802,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32597
32802
|
ReferenceLine,
|
|
32598
32803
|
{
|
|
32599
32804
|
y: idealCycleTime,
|
|
32805
|
+
yAxisId: "cycle",
|
|
32600
32806
|
stroke: "#E34329",
|
|
32601
32807
|
strokeDasharray: "3 3",
|
|
32602
32808
|
strokeWidth: 2,
|
|
@@ -32613,6 +32819,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
32613
32819
|
Line,
|
|
32614
32820
|
{
|
|
32615
32821
|
type: "monotone",
|
|
32822
|
+
yAxisId: "cycle",
|
|
32616
32823
|
dataKey: "cycleTime",
|
|
32617
32824
|
stroke: "#3B82F6",
|
|
32618
32825
|
strokeWidth: 2,
|
|
@@ -32662,15 +32869,35 @@ var CycleTimeOverTimeChart = ({
|
|
|
32662
32869
|
}
|
|
32663
32870
|
);
|
|
32664
32871
|
},
|
|
32872
|
+
isAnimationActive: shouldAnimate,
|
|
32665
32873
|
animationBegin: 0,
|
|
32666
|
-
animationDuration:
|
|
32874
|
+
animationDuration: 1200,
|
|
32875
|
+
animationEasing: "ease-out",
|
|
32876
|
+
onAnimationEnd: handleAnimationEnd
|
|
32877
|
+
},
|
|
32878
|
+
`${effectiveDatasetKey}:cycle`
|
|
32879
|
+
),
|
|
32880
|
+
showIdleTime && /* @__PURE__ */ jsx(
|
|
32881
|
+
Line,
|
|
32882
|
+
{
|
|
32883
|
+
type: "monotone",
|
|
32884
|
+
yAxisId: "idle",
|
|
32885
|
+
dataKey: "idleMinutes",
|
|
32886
|
+
stroke: "#f59e0b",
|
|
32887
|
+
strokeWidth: 2,
|
|
32888
|
+
strokeDasharray: "4 4",
|
|
32889
|
+
dot: { r: 4, fill: "#f59e0b", stroke: "#fff", strokeWidth: 1 },
|
|
32890
|
+
activeDot: { r: 6, fill: "#f59e0b", stroke: "#fff", strokeWidth: 2 },
|
|
32891
|
+
isAnimationActive: shouldAnimate,
|
|
32892
|
+
animationBegin: 0,
|
|
32893
|
+
animationDuration: 1200,
|
|
32667
32894
|
animationEasing: "ease-out"
|
|
32668
|
-
}
|
|
32895
|
+
},
|
|
32896
|
+
`${effectiveDatasetKey}:idle`
|
|
32669
32897
|
)
|
|
32670
32898
|
]
|
|
32671
32899
|
}
|
|
32672
|
-
) }) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center bg-gray-50 rounded-lg", children: /* @__PURE__ */ jsx("div", { className: "text-gray-500 text-sm", children: "Loading chart..." }) })
|
|
32673
|
-
renderLegend()
|
|
32900
|
+
) }) : /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center bg-gray-50 rounded-lg", children: /* @__PURE__ */ jsx("div", { className: "text-gray-500 text-sm", children: "Loading chart..." }) }) })
|
|
32674
32901
|
]
|
|
32675
32902
|
}
|
|
32676
32903
|
);
|
|
@@ -32862,7 +33089,7 @@ var HourlyOutputChartComponent = ({
|
|
|
32862
33089
|
if (!classification.label) {
|
|
32863
33090
|
return "Reason unavailable";
|
|
32864
33091
|
}
|
|
32865
|
-
return classification.label.replace(/_/g, " ");
|
|
33092
|
+
return classification.displayName || classification.label.replace(/_/g, " ");
|
|
32866
33093
|
}, [idleClipRanges, idleTimeClipClassifications]);
|
|
32867
33094
|
const { shiftDuration, shiftEndTime, hasPartialLastHour } = React141__default.useMemo(() => {
|
|
32868
33095
|
console.log("[HourlyOutputChart] Calculating shift duration with:", {
|
|
@@ -33520,23 +33747,82 @@ var HourlyOutputChart = React141__default.memo(HourlyOutputChartComponent, (prev
|
|
|
33520
33747
|
HourlyOutputChart.displayName = "HourlyOutputChart";
|
|
33521
33748
|
|
|
33522
33749
|
// src/components/dashboard/grid/videoGridMetricUtils.ts
|
|
33523
|
-
var VIDEO_GRID_LEGEND_LABEL = "
|
|
33750
|
+
var VIDEO_GRID_LEGEND_LABEL = "Flow";
|
|
33524
33751
|
var MAP_GRID_LEGEND_LABEL = "Efficiency";
|
|
33525
33752
|
var MIXED_VIDEO_GRID_LEGEND_LABEL = "Flow / Efficiency";
|
|
33526
33753
|
var isFiniteNumber2 = (value) => typeof value === "number" && Number.isFinite(value);
|
|
33527
|
-
var
|
|
33528
|
-
|
|
33754
|
+
var isVideoGridRecentFlowEnabled = (workspace) => isRecentFlowVideoGridMetricMode(
|
|
33755
|
+
workspace.video_grid_metric_mode,
|
|
33756
|
+
workspace.assembly_enabled === true
|
|
33757
|
+
);
|
|
33758
|
+
var isVideoGridWipGated = (workspace) => isWipGatedVideoGridMetricMode(
|
|
33759
|
+
workspace.video_grid_metric_mode,
|
|
33760
|
+
workspace.assembly_enabled === true
|
|
33761
|
+
);
|
|
33762
|
+
var hasVideoGridRecentFlow = (workspace) => isVideoGridRecentFlowEnabled(workspace) && isFiniteNumber2(workspace.recent_flow_percent);
|
|
33763
|
+
var isVideoGridRecentFlowUnavailable = (workspace) => isVideoGridRecentFlowEnabled(workspace) && !hasVideoGridRecentFlow(workspace);
|
|
33529
33764
|
var getVideoGridMetricValue = (workspace) => {
|
|
33530
33765
|
const recentFlowPercent = workspace.recent_flow_percent;
|
|
33531
|
-
if (
|
|
33766
|
+
if (hasVideoGridRecentFlow(workspace) && isFiniteNumber2(recentFlowPercent)) {
|
|
33532
33767
|
return recentFlowPercent;
|
|
33533
33768
|
}
|
|
33769
|
+
if (isVideoGridRecentFlowUnavailable(workspace)) {
|
|
33770
|
+
return null;
|
|
33771
|
+
}
|
|
33534
33772
|
return workspace.efficiency;
|
|
33535
33773
|
};
|
|
33536
33774
|
var hasIncomingWipMapping = (workspace) => Boolean(workspace.incoming_wip_buffer_name);
|
|
33775
|
+
var getVideoGridBaseColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
33776
|
+
const metricValue = getVideoGridMetricValue(workspace);
|
|
33777
|
+
if (!isFiniteNumber2(metricValue)) {
|
|
33778
|
+
return "neutral";
|
|
33779
|
+
}
|
|
33780
|
+
return getEfficiencyColor(metricValue, legend);
|
|
33781
|
+
};
|
|
33782
|
+
var isLowWipGreenOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
33783
|
+
if (!hasVideoGridRecentFlow(workspace) || !isVideoGridWipGated(workspace)) {
|
|
33784
|
+
return false;
|
|
33785
|
+
}
|
|
33786
|
+
if (getVideoGridBaseColorState(workspace, legend) !== "red") {
|
|
33787
|
+
return false;
|
|
33788
|
+
}
|
|
33789
|
+
if (!hasIncomingWipMapping(workspace)) {
|
|
33790
|
+
return false;
|
|
33791
|
+
}
|
|
33792
|
+
return isFiniteNumber2(workspace.incoming_wip_current) && workspace.incoming_wip_current <= 1;
|
|
33793
|
+
};
|
|
33794
|
+
var toMinuteBucket = (minuteBucket) => Number.isFinite(minuteBucket) ? Math.floor(minuteBucket) : Math.floor(Date.now() / 6e4);
|
|
33795
|
+
var getEffectiveFlowMinuteBucket = (workspace) => {
|
|
33796
|
+
const effectiveAt = workspace.recent_flow_effective_end_at;
|
|
33797
|
+
if (!effectiveAt) {
|
|
33798
|
+
return void 0;
|
|
33799
|
+
}
|
|
33800
|
+
const timestamp = Date.parse(effectiveAt);
|
|
33801
|
+
if (!Number.isFinite(timestamp)) {
|
|
33802
|
+
return void 0;
|
|
33803
|
+
}
|
|
33804
|
+
return Math.floor(timestamp / 6e4);
|
|
33805
|
+
};
|
|
33806
|
+
var hashWorkspaceKey = (workspace) => {
|
|
33807
|
+
const workspaceKey = workspace.workspace_uuid || workspace.workspace_name || "unknown";
|
|
33808
|
+
let hash = 0;
|
|
33809
|
+
for (let index = 0; index < workspaceKey.length; index += 1) {
|
|
33810
|
+
hash = (hash * 31 + workspaceKey.charCodeAt(index)) % 2147483647;
|
|
33811
|
+
}
|
|
33812
|
+
return hash;
|
|
33813
|
+
};
|
|
33814
|
+
var getSyntheticLowWipDisplayValue = (workspace, minuteBucket) => {
|
|
33815
|
+
const bucket = getEffectiveFlowMinuteBucket(workspace) ?? toMinuteBucket(minuteBucket);
|
|
33816
|
+
const offset = (hashWorkspaceKey(workspace) % 11 + bucket % 11 + 11) % 11;
|
|
33817
|
+
return 100 + offset;
|
|
33818
|
+
};
|
|
33819
|
+
var getVideoGridDisplayValue = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND, minuteBucket) => isLowWipGreenOverride(workspace, legend) ? getSyntheticLowWipDisplayValue(workspace, minuteBucket) : getVideoGridMetricValue(workspace);
|
|
33537
33820
|
var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
|
|
33538
|
-
const baseColor =
|
|
33539
|
-
if (!
|
|
33821
|
+
const baseColor = getVideoGridBaseColorState(workspace, legend);
|
|
33822
|
+
if (!hasVideoGridRecentFlow(workspace)) {
|
|
33823
|
+
return baseColor;
|
|
33824
|
+
}
|
|
33825
|
+
if (!isVideoGridWipGated(workspace)) {
|
|
33540
33826
|
return baseColor;
|
|
33541
33827
|
}
|
|
33542
33828
|
if (baseColor !== "red") {
|
|
@@ -33548,7 +33834,7 @@ var getVideoGridColorState = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) =>
|
|
|
33548
33834
|
if (!isFiniteNumber2(workspace.incoming_wip_current)) {
|
|
33549
33835
|
return "neutral";
|
|
33550
33836
|
}
|
|
33551
|
-
if (workspace
|
|
33837
|
+
if (isLowWipGreenOverride(workspace, legend)) {
|
|
33552
33838
|
return "green";
|
|
33553
33839
|
}
|
|
33554
33840
|
return baseColor;
|
|
@@ -33558,11 +33844,11 @@ var getVideoGridLegendLabel = (workspaces) => {
|
|
|
33558
33844
|
if (visibleWorkspaces.length === 0) {
|
|
33559
33845
|
return MAP_GRID_LEGEND_LABEL;
|
|
33560
33846
|
}
|
|
33561
|
-
const
|
|
33562
|
-
if (
|
|
33847
|
+
const recentFlowEnabledCount = visibleWorkspaces.filter(isVideoGridRecentFlowEnabled).length;
|
|
33848
|
+
if (recentFlowEnabledCount === 0) {
|
|
33563
33849
|
return MAP_GRID_LEGEND_LABEL;
|
|
33564
33850
|
}
|
|
33565
|
-
if (
|
|
33851
|
+
if (recentFlowEnabledCount === visibleWorkspaces.length) {
|
|
33566
33852
|
return VIDEO_GRID_LEGEND_LABEL;
|
|
33567
33853
|
}
|
|
33568
33854
|
return MIXED_VIDEO_GRID_LEGEND_LABEL;
|
|
@@ -33589,6 +33875,7 @@ var VideoCard = React141__default.memo(({
|
|
|
33589
33875
|
useRAF = true,
|
|
33590
33876
|
className = "",
|
|
33591
33877
|
compact = false,
|
|
33878
|
+
displayMinuteBucket,
|
|
33592
33879
|
displayName,
|
|
33593
33880
|
lastSeenLabel,
|
|
33594
33881
|
onMouseEnter,
|
|
@@ -33609,8 +33896,13 @@ var VideoCard = React141__default.memo(({
|
|
|
33609
33896
|
const lastSeenText = lastSeenLabel || "Unknown";
|
|
33610
33897
|
const workspaceDisplayName = displayName || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
33611
33898
|
const videoGridMetricValue = getVideoGridMetricValue(workspace);
|
|
33899
|
+
const videoGridDisplayValue = getVideoGridDisplayValue(workspace, effectiveLegend, displayMinuteBucket);
|
|
33612
33900
|
const videoGridColorState = getVideoGridColorState(workspace, effectiveLegend);
|
|
33613
|
-
const
|
|
33901
|
+
const isRecentFlowCard = isVideoGridRecentFlowEnabled(workspace);
|
|
33902
|
+
const hasDisplayMetric = typeof videoGridDisplayValue === "number" && Number.isFinite(videoGridDisplayValue);
|
|
33903
|
+
const hasBarMetric = typeof videoGridMetricValue === "number" && Number.isFinite(videoGridMetricValue);
|
|
33904
|
+
const badgeTitle = hasVideoGridRecentFlow(workspace) ? `Flow ${Math.round(videoGridDisplayValue ?? 0)}%` : isRecentFlowCard ? "Flow unavailable" : `Efficiency ${Math.round(videoGridDisplayValue ?? 0)}%`;
|
|
33905
|
+
const badgeLabel = hasDisplayMetric ? `${Math.round(videoGridDisplayValue)}%` : "X";
|
|
33614
33906
|
const efficiencyOverlayClass = videoGridColorState === "green" ? "bg-[#00D654]/25" : videoGridColorState === "yellow" ? "bg-[#FFD700]/30" : videoGridColorState === "red" ? "bg-[#FF2D0A]/30" : "bg-transparent";
|
|
33615
33907
|
const efficiencyBarClass = videoGridColorState === "green" ? "bg-[#00AB45]" : videoGridColorState === "yellow" ? "bg-[#FFB020]" : videoGridColorState === "red" ? "bg-[#E34329]" : "bg-gray-500/70";
|
|
33616
33908
|
const efficiencyStatus = videoGridColorState === "green" ? "High" : videoGridColorState === "yellow" ? "Medium" : videoGridColorState === "red" ? "Low" : "Neutral";
|
|
@@ -33689,19 +33981,18 @@ var VideoCard = React141__default.memo(({
|
|
|
33689
33981
|
/* @__PURE__ */ jsx("div", { className: `absolute ${compact ? "top-1 right-1" : "top-2 right-2"} z-30`, children: /* @__PURE__ */ jsx(
|
|
33690
33982
|
"div",
|
|
33691
33983
|
{
|
|
33984
|
+
"data-testid": "video-card-metric-badge",
|
|
33692
33985
|
className: `bg-black/70 backdrop-blur-sm rounded ${compact ? "px-1.5 py-1" : "px-2 py-1"} text-white border border-white/10`,
|
|
33693
33986
|
title: badgeTitle,
|
|
33694
|
-
children: /* @__PURE__ */
|
|
33695
|
-
Math.round(videoGridMetricValue),
|
|
33696
|
-
"%"
|
|
33697
|
-
] })
|
|
33987
|
+
children: /* @__PURE__ */ jsx("span", { className: `${compact ? "text-[10px]" : "text-xs"} font-semibold`, children: badgeLabel })
|
|
33698
33988
|
}
|
|
33699
33989
|
) }),
|
|
33700
33990
|
/* @__PURE__ */ jsx("div", { className: `absolute bottom-0 left-0 right-0 ${compact ? "h-0.5" : "h-1"} bg-black/50 z-30`, children: /* @__PURE__ */ jsx(
|
|
33701
33991
|
"div",
|
|
33702
33992
|
{
|
|
33993
|
+
"data-testid": "video-card-metric-bar",
|
|
33703
33994
|
className: `h-full ${efficiencyBarClass} transition-all duration-500`,
|
|
33704
|
-
style: { width: `${Math.min(100, videoGridMetricValue)}%` }
|
|
33995
|
+
style: { width: `${hasBarMetric ? Math.min(100, Math.max(0, videoGridMetricValue)) : videoGridColorState === "neutral" ? 100 : 0}%` }
|
|
33705
33996
|
}
|
|
33706
33997
|
) })
|
|
33707
33998
|
] }),
|
|
@@ -33732,7 +34023,7 @@ var VideoCard = React141__default.memo(({
|
|
|
33732
34023
|
}
|
|
33733
34024
|
);
|
|
33734
34025
|
}, (prevProps, nextProps) => {
|
|
33735
|
-
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || 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) {
|
|
34026
|
+
if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_mode !== nextProps.workspace.recent_flow_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) {
|
|
33736
34027
|
return false;
|
|
33737
34028
|
}
|
|
33738
34029
|
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) {
|
|
@@ -33750,6 +34041,9 @@ var VideoCard = React141__default.memo(({
|
|
|
33750
34041
|
if (prevProps.compact !== nextProps.compact) {
|
|
33751
34042
|
return false;
|
|
33752
34043
|
}
|
|
34044
|
+
if (prevProps.displayMinuteBucket !== nextProps.displayMinuteBucket) {
|
|
34045
|
+
return false;
|
|
34046
|
+
}
|
|
33753
34047
|
if (prevProps.hlsUrl !== nextProps.hlsUrl || prevProps.shouldPlay !== nextProps.shouldPlay) {
|
|
33754
34048
|
return false;
|
|
33755
34049
|
}
|
|
@@ -34033,6 +34327,7 @@ var VideoGridView = React141__default.memo(({
|
|
|
34033
34327
|
stream_source: isR2Stream ? "r2" : "media_config"
|
|
34034
34328
|
});
|
|
34035
34329
|
}, []);
|
|
34330
|
+
const displayMinuteBucket = Math.floor(Date.now() / 6e4);
|
|
34036
34331
|
return /* @__PURE__ */ jsx("div", { className: `relative overflow-hidden h-full w-full ${className}`, children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "h-full w-full p-3 sm:p-2", children: /* @__PURE__ */ jsx(
|
|
34037
34332
|
"div",
|
|
34038
34333
|
{
|
|
@@ -34122,6 +34417,7 @@ var VideoGridView = React141__default.memo(({
|
|
|
34122
34417
|
),
|
|
34123
34418
|
lastSeenLabel: card.lastSeenLabel,
|
|
34124
34419
|
useRAF: effectiveUseRAF,
|
|
34420
|
+
displayMinuteBucket,
|
|
34125
34421
|
compact: !selectedLine,
|
|
34126
34422
|
onMouseEnter: onWorkspaceHover ? () => onWorkspaceHover(card.workspaceId) : void 0,
|
|
34127
34423
|
onMouseLeave: onWorkspaceHoverEnd ? () => onWorkspaceHoverEnd(card.workspaceId) : void 0
|
|
@@ -39251,45 +39547,56 @@ var FileManagerFilters = ({
|
|
|
39251
39547
|
});
|
|
39252
39548
|
const [loadingPercentile, setLoadingPercentile] = useState(false);
|
|
39253
39549
|
const resolvedTargetCycleTime = targetCycleTime && targetCycleTime > 0 ? targetCycleTime : null;
|
|
39254
|
-
const
|
|
39255
|
-
const
|
|
39256
|
-
|
|
39257
|
-
|
|
39258
|
-
|
|
39259
|
-
|
|
39260
|
-
|
|
39261
|
-
|
|
39262
|
-
|
|
39263
|
-
|
|
39550
|
+
const getIdleTimeClassification = useCallback((clipId) => {
|
|
39551
|
+
const classification = mergedClipClassifications[clipId];
|
|
39552
|
+
return classification || null;
|
|
39553
|
+
}, [mergedClipClassifications]);
|
|
39554
|
+
const getRootCauseConfig = useCallback((classification) => {
|
|
39555
|
+
if (!classification || classification.status === "processing") {
|
|
39556
|
+
return null;
|
|
39557
|
+
}
|
|
39558
|
+
const presentation = getIdleReasonPresentation({
|
|
39559
|
+
label: classification.label,
|
|
39560
|
+
displayName: classification.displayName,
|
|
39561
|
+
paletteToken: classification.paletteToken,
|
|
39562
|
+
iconToken: classification.iconToken,
|
|
39563
|
+
isKnown: classification.isKnown
|
|
39564
|
+
});
|
|
39264
39565
|
return {
|
|
39265
|
-
color:
|
|
39266
|
-
bgColor:
|
|
39267
|
-
borderColor:
|
|
39268
|
-
Icon:
|
|
39269
|
-
iconColor:
|
|
39566
|
+
color: presentation.textClass,
|
|
39567
|
+
bgColor: presentation.bgClass,
|
|
39568
|
+
borderColor: presentation.borderClass,
|
|
39569
|
+
Icon: presentation.Icon,
|
|
39570
|
+
iconColor: presentation.textClass,
|
|
39571
|
+
displayName: presentation.displayName
|
|
39270
39572
|
};
|
|
39271
|
-
};
|
|
39272
|
-
const normalizeIdleReasonLabel = useCallback((label) => {
|
|
39273
|
-
return label.replace(/_/g, " ").trim();
|
|
39274
39573
|
}, []);
|
|
39275
|
-
const getIdleTimeRootCause = useCallback((clipId) => {
|
|
39276
|
-
const classification = mergedClipClassifications[clipId];
|
|
39277
|
-
if (!classification) return "processing";
|
|
39278
|
-
if (classification.status === "processing") return "processing";
|
|
39279
|
-
return classification.label || "processing";
|
|
39280
|
-
}, [mergedClipClassifications]);
|
|
39281
39574
|
const idleReasonOptions = useMemo(() => {
|
|
39282
39575
|
const idleClips = clipMetadata["idle_time"] || [];
|
|
39283
|
-
const uniqueReasons = /* @__PURE__ */ new
|
|
39576
|
+
const uniqueReasons = /* @__PURE__ */ new Map();
|
|
39284
39577
|
idleClips.forEach((clip) => {
|
|
39285
39578
|
const clipId = clip.clipId || clip.id;
|
|
39286
39579
|
if (!clipId) return;
|
|
39287
|
-
const
|
|
39288
|
-
if (!
|
|
39289
|
-
|
|
39580
|
+
const classification = getIdleTimeClassification(clipId);
|
|
39581
|
+
if (!classification || classification.status === "processing" || !classification.label) {
|
|
39582
|
+
return;
|
|
39583
|
+
}
|
|
39584
|
+
if (!uniqueReasons.has(classification.label)) {
|
|
39585
|
+
uniqueReasons.set(classification.label, {
|
|
39586
|
+
label: classification.label,
|
|
39587
|
+
displayName: classification.displayName || classification.label.replace(/_/g, " "),
|
|
39588
|
+
paletteToken: classification.paletteToken,
|
|
39589
|
+
iconToken: classification.iconToken,
|
|
39590
|
+
isKnown: classification.isKnown
|
|
39591
|
+
});
|
|
39592
|
+
}
|
|
39290
39593
|
});
|
|
39291
|
-
return Array.from(uniqueReasons).sort((a, b) => a.localeCompare(b));
|
|
39292
|
-
}, [clipMetadata,
|
|
39594
|
+
return Array.from(uniqueReasons.values()).sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
39595
|
+
}, [clipMetadata, getIdleTimeClassification]);
|
|
39596
|
+
const selectedIdleReasonOption = useMemo(
|
|
39597
|
+
() => idleReasonOptions.find((reason) => reason.label === idleLabelFilter) || null,
|
|
39598
|
+
[idleReasonOptions, idleLabelFilter]
|
|
39599
|
+
);
|
|
39293
39600
|
const getClipBadge = useCallback((node) => {
|
|
39294
39601
|
if (node.categoryId === "idle_time" || node.categoryId === "low_value") {
|
|
39295
39602
|
return { text: "Idle", className: "bg-red-100 text-red-700" };
|
|
@@ -39361,6 +39668,10 @@ var FileManagerFilters = ({
|
|
|
39361
39668
|
seededClassifications[clip.clipId] = {
|
|
39362
39669
|
status: clip.classification_status,
|
|
39363
39670
|
label: clip.classification_label || void 0,
|
|
39671
|
+
displayName: clip.classification_display_name || void 0,
|
|
39672
|
+
paletteToken: clip.classification_palette_token || void 0,
|
|
39673
|
+
iconToken: clip.classification_icon_token || void 0,
|
|
39674
|
+
isKnown: clip.classification_is_known ?? void 0,
|
|
39364
39675
|
confidence: clip.classification_confidence ?? void 0
|
|
39365
39676
|
};
|
|
39366
39677
|
}
|
|
@@ -39744,7 +40055,7 @@ var FileManagerFilters = ({
|
|
|
39744
40055
|
return slot ? slot.label : value;
|
|
39745
40056
|
}, [timeSlots]);
|
|
39746
40057
|
const isClipInTimeRange = useCallback((clipTimestamp) => {
|
|
39747
|
-
if (!
|
|
40058
|
+
if (!startTime || !endTime) {
|
|
39748
40059
|
return true;
|
|
39749
40060
|
}
|
|
39750
40061
|
try {
|
|
@@ -39770,9 +40081,8 @@ var FileManagerFilters = ({
|
|
|
39770
40081
|
let filteredClips = categoryClips.filter((clip) => isClipInTimeRange(clip.clip_timestamp));
|
|
39771
40082
|
if (category.id === "idle_time" && idleLabelFilter) {
|
|
39772
40083
|
filteredClips = filteredClips.filter((clip) => {
|
|
39773
|
-
const
|
|
39774
|
-
|
|
39775
|
-
return normalizedRootCause === idleLabelFilter;
|
|
40084
|
+
const classification = getIdleTimeClassification(clip.clipId || clip.id);
|
|
40085
|
+
return classification?.label === idleLabelFilter;
|
|
39776
40086
|
});
|
|
39777
40087
|
}
|
|
39778
40088
|
const displayCount = isTimeFilterActive || category.id === "idle_time" && idleLabelFilter ? filteredClips.length : categoryCount;
|
|
@@ -39802,8 +40112,9 @@ var FileManagerFilters = ({
|
|
|
39802
40112
|
clipPosition: index + 1,
|
|
39803
40113
|
// Store 1-based position
|
|
39804
40114
|
cycleTimeSeconds: cycleTime,
|
|
39805
|
-
duration: clip.duration
|
|
40115
|
+
duration: clip.duration,
|
|
39806
40116
|
// Store duration for custom badge rendering
|
|
40117
|
+
cycleItemCount: clip.cycle_item_count ?? null
|
|
39807
40118
|
};
|
|
39808
40119
|
});
|
|
39809
40120
|
regularCategoryNodes.push({
|
|
@@ -40059,14 +40370,14 @@ var FileManagerFilters = ({
|
|
|
40059
40370
|
/* @__PURE__ */ jsx("div", { className: `flex-shrink-0 mr-3 ${node.type === "category" || node.type === "percentile-category" ? "p-2 rounded-lg shadow-sm group-hover:scale-110 transition-transform duration-200" : "p-0.5"} ${colorClasses && (node.type === "category" || node.type === "percentile-category") ? `${colorClasses.bg} border border-white/60` : ""}`, children: node.type === "video" && (node.categoryId === "idle_time" || node.categoryId === "low_value") ? (
|
|
40060
40371
|
// Show root cause icon for idle time clips
|
|
40061
40372
|
(() => {
|
|
40062
|
-
const
|
|
40063
|
-
if (
|
|
40373
|
+
const classification = getIdleTimeClassification(node.clipId || node.id);
|
|
40374
|
+
if (!classification || classification.status === "processing") {
|
|
40064
40375
|
return /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5 text-purple-500", strokeWidth: 2.5 });
|
|
40065
40376
|
}
|
|
40066
40377
|
if (!idleTimeVlmEnabled && node.categoryId === "idle_time") {
|
|
40067
40378
|
return /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5 text-purple-500", strokeWidth: 2.5 });
|
|
40068
40379
|
}
|
|
40069
|
-
const config = getRootCauseConfig(
|
|
40380
|
+
const config = getRootCauseConfig(classification);
|
|
40070
40381
|
if (config) {
|
|
40071
40382
|
const IconComponent = config.Icon;
|
|
40072
40383
|
return /* @__PURE__ */ jsx(IconComponent, { className: `h-3.5 w-3.5 ${config.iconColor}`, strokeWidth: 2.5 });
|
|
@@ -40088,10 +40399,10 @@ var FileManagerFilters = ({
|
|
|
40088
40399
|
return /* @__PURE__ */ jsx("div", { className: `inline-flex items-center px-2 py-0.5 rounded-md border text-[10px] font-bold ${isLong ? "bg-purple-50 text-purple-700 border-purple-200" : "bg-gray-50 text-gray-600 border-gray-200"}`, children: isLong ? "Long" : "Short" });
|
|
40089
40400
|
}
|
|
40090
40401
|
const clipId = node.clipId || node.id;
|
|
40091
|
-
const
|
|
40092
|
-
const isProcessing =
|
|
40093
|
-
const
|
|
40094
|
-
const
|
|
40402
|
+
const classification = getIdleTimeClassification(clipId);
|
|
40403
|
+
const isProcessing = !classification || classification.status === "processing";
|
|
40404
|
+
const config = isProcessing ? null : getRootCauseConfig(classification);
|
|
40405
|
+
const displayLabel = config?.displayName || "Analyzing...";
|
|
40095
40406
|
const bgClass = config ? config.bgColor : "bg-slate-50";
|
|
40096
40407
|
const textClass = config ? config.color : "text-slate-700";
|
|
40097
40408
|
const borderClass = config ? config.borderColor : "border-slate-200";
|
|
@@ -40101,7 +40412,13 @@ var FileManagerFilters = ({
|
|
|
40101
40412
|
// Show badge for other clips
|
|
40102
40413
|
(() => {
|
|
40103
40414
|
const badge = getClipBadge(node);
|
|
40104
|
-
return /* @__PURE__ */
|
|
40415
|
+
return /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1.5", children: [
|
|
40416
|
+
/* @__PURE__ */ jsx("span", { className: `inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-medium ${badge.className}`, children: badge.text }),
|
|
40417
|
+
node.categoryId === "cycle_completion" && node.cycleItemCount && node.cycleItemCount > 1 ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-semibold bg-blue-100 text-blue-700 border border-blue-200", children: [
|
|
40418
|
+
"x",
|
|
40419
|
+
node.cycleItemCount
|
|
40420
|
+
] }) : null
|
|
40421
|
+
] });
|
|
40105
40422
|
})()
|
|
40106
40423
|
) })
|
|
40107
40424
|
] }),
|
|
@@ -40189,7 +40506,7 @@ var FileManagerFilters = ({
|
|
|
40189
40506
|
idleLabelFilter && activeFilter === "idle_time" && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 text-xs text-purple-600 bg-purple-50/60 px-3 py-1.5 rounded-lg border border-purple-100", children: [
|
|
40190
40507
|
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
40191
40508
|
"Reason: ",
|
|
40192
|
-
idleLabelFilter.replace(/_/g, " ")
|
|
40509
|
+
selectedIdleReasonOption?.displayName || idleLabelFilter.replace(/_/g, " ")
|
|
40193
40510
|
] }),
|
|
40194
40511
|
/* @__PURE__ */ jsx(
|
|
40195
40512
|
"button",
|
|
@@ -40238,21 +40555,31 @@ var FileManagerFilters = ({
|
|
|
40238
40555
|
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
40239
40556
|
"Loading idle reasons..."
|
|
40240
40557
|
] }) : idleReasonOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-sm text-slate-500", children: "No classified idle reasons found yet." }) : idleReasonOptions.map((reason) => {
|
|
40241
|
-
const config = getRootCauseConfig(
|
|
40558
|
+
const config = getRootCauseConfig({
|
|
40559
|
+
status: "classified",
|
|
40560
|
+
label: reason.label,
|
|
40561
|
+
displayName: reason.displayName,
|
|
40562
|
+
paletteToken: reason.paletteToken,
|
|
40563
|
+
iconToken: reason.iconToken,
|
|
40564
|
+
isKnown: reason.isKnown
|
|
40565
|
+
});
|
|
40566
|
+
if (!config) {
|
|
40567
|
+
return null;
|
|
40568
|
+
}
|
|
40242
40569
|
return /* @__PURE__ */ jsxs(
|
|
40243
40570
|
"button",
|
|
40244
40571
|
{
|
|
40245
40572
|
onClick: () => {
|
|
40246
|
-
setIdleLabelFilter(reason);
|
|
40573
|
+
setIdleLabelFilter(reason.label);
|
|
40247
40574
|
setShowIdleLabelFilterModal(false);
|
|
40248
40575
|
},
|
|
40249
|
-
className: `w-full px-3 py-2 text-left text-sm rounded-lg transition-colors flex items-center gap-2 mb-1 ${idleLabelFilter === reason ? "bg-purple-50 text-purple-700 font-medium" : "text-slate-700 hover:bg-slate-50"}`,
|
|
40576
|
+
className: `w-full px-3 py-2 text-left text-sm rounded-lg transition-colors flex items-center gap-2 mb-1 ${idleLabelFilter === reason.label ? "bg-purple-50 text-purple-700 font-medium" : "text-slate-700 hover:bg-slate-50"}`,
|
|
40250
40577
|
children: [
|
|
40251
40578
|
/* @__PURE__ */ jsx(config.Icon, { className: `h-3.5 w-3.5 ${config.iconColor}` }),
|
|
40252
|
-
reason
|
|
40579
|
+
reason.displayName
|
|
40253
40580
|
]
|
|
40254
40581
|
},
|
|
40255
|
-
reason
|
|
40582
|
+
reason.label
|
|
40256
40583
|
);
|
|
40257
40584
|
}) })
|
|
40258
40585
|
]
|
|
@@ -40367,33 +40694,14 @@ var FileManagerFilters = ({
|
|
|
40367
40694
|
slot.value
|
|
40368
40695
|
)) })
|
|
40369
40696
|
] })
|
|
40370
|
-
] }) })
|
|
40371
|
-
/* @__PURE__ */ jsx("div", { className: "px-4 py-3 border-t border-slate-200 bg-white rounded-b-xl", children: /* @__PURE__ */ jsx(
|
|
40372
|
-
"button",
|
|
40373
|
-
{
|
|
40374
|
-
onClick: () => {
|
|
40375
|
-
if (startTime && endTime) {
|
|
40376
|
-
setIsTimeFilterActive(true);
|
|
40377
|
-
}
|
|
40378
|
-
setShowTimeFilterModal(false);
|
|
40379
|
-
setStartSearchTerm("");
|
|
40380
|
-
setEndSearchTerm("");
|
|
40381
|
-
},
|
|
40382
|
-
disabled: !startTime || !endTime,
|
|
40383
|
-
className: `
|
|
40384
|
-
w-full px-4 py-2 text-sm font-semibold rounded-lg transition-all
|
|
40385
|
-
${startTime && endTime ? "bg-blue-600 text-white hover:bg-blue-700 active:scale-[0.98]" : "bg-slate-200 text-slate-400 cursor-not-allowed"}
|
|
40386
|
-
`,
|
|
40387
|
-
children: "Apply"
|
|
40388
|
-
}
|
|
40389
|
-
) })
|
|
40697
|
+
] }) })
|
|
40390
40698
|
]
|
|
40391
40699
|
}
|
|
40392
40700
|
)
|
|
40393
40701
|
] }),
|
|
40394
40702
|
/* @__PURE__ */ jsxs("div", { className: "px-4 py-3 flex-1 min-h-0 overflow-y-auto scrollbar-thin", children: [
|
|
40395
40703
|
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: filterTree.map((node) => renderNode(node)) }),
|
|
40396
|
-
filterTree.length === 0 &&
|
|
40704
|
+
filterTree.length === 0 && (startTime || endTime) && /* @__PURE__ */ jsxs("div", { className: "text-center py-12", children: [
|
|
40397
40705
|
/* @__PURE__ */ jsx("div", { className: "text-slate-300 mb-4", children: /* @__PURE__ */ jsx(Clock, { className: "h-12 w-12 mx-auto" }) }),
|
|
40398
40706
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-slate-700 mb-2", children: "No clips found" }),
|
|
40399
40707
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-slate-500 mb-4", children: "No clips match the selected time range" }),
|
|
@@ -40403,18 +40711,19 @@ var FileManagerFilters = ({
|
|
|
40403
40711
|
onClick: () => {
|
|
40404
40712
|
setStartTime("");
|
|
40405
40713
|
setEndTime("");
|
|
40714
|
+
setIsTimeFilterActive(false);
|
|
40406
40715
|
},
|
|
40407
40716
|
className: "inline-flex items-center px-4 py-2 bg-blue-50 text-blue-600 text-sm font-medium rounded-lg hover:bg-blue-100 transition-colors duration-200",
|
|
40408
40717
|
children: "Clear time filter"
|
|
40409
40718
|
}
|
|
40410
40719
|
)
|
|
40411
40720
|
] }),
|
|
40412
|
-
filterTree.length === 0 && !
|
|
40721
|
+
filterTree.length === 0 && !startTime && !endTime && categories.length === 0 && /* @__PURE__ */ jsxs("div", { className: "text-center py-12", children: [
|
|
40413
40722
|
/* @__PURE__ */ jsx("div", { className: "text-slate-300 mb-4", children: /* @__PURE__ */ jsx(HelpCircle, { className: "h-12 w-12 mx-auto" }) }),
|
|
40414
40723
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-slate-700 mb-2", children: "No clip types available" }),
|
|
40415
40724
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-slate-500", children: "Loading clip categories..." })
|
|
40416
40725
|
] }),
|
|
40417
|
-
filterTree.length === 0 && !
|
|
40726
|
+
filterTree.length === 0 && !startTime && !endTime && categories.length > 0 && /* @__PURE__ */ jsxs("div", { className: "text-center py-12", children: [
|
|
40418
40727
|
/* @__PURE__ */ jsx("div", { className: "text-slate-300 mb-4", children: /* @__PURE__ */ jsx(Play, { className: "h-12 w-12 mx-auto" }) }),
|
|
40419
40728
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-slate-700 mb-2", children: "No clips available" }),
|
|
40420
40729
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-slate-500", children: "No clips found for the selected time period" })
|
|
@@ -40818,6 +41127,34 @@ function useClipsRealtimeUpdates({
|
|
|
40818
41127
|
hasNewClips: newClipsNotification !== null && newClipsNotification.count > 0
|
|
40819
41128
|
};
|
|
40820
41129
|
}
|
|
41130
|
+
var parseFiniteNumber2 = (value) => {
|
|
41131
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
41132
|
+
return value;
|
|
41133
|
+
}
|
|
41134
|
+
if (typeof value === "string") {
|
|
41135
|
+
const parsed = Number(value);
|
|
41136
|
+
if (Number.isFinite(parsed)) {
|
|
41137
|
+
return parsed;
|
|
41138
|
+
}
|
|
41139
|
+
}
|
|
41140
|
+
return null;
|
|
41141
|
+
};
|
|
41142
|
+
var getMultiCycleItemCount = (clip) => {
|
|
41143
|
+
if (!clip || clip.categoryId !== "cycle_completion") {
|
|
41144
|
+
return null;
|
|
41145
|
+
}
|
|
41146
|
+
const cycleItemCount = parseFiniteNumber2(clip.cycle_item_count);
|
|
41147
|
+
return cycleItemCount !== null && cycleItemCount > 1 ? cycleItemCount : null;
|
|
41148
|
+
};
|
|
41149
|
+
var OVERLAY_ICON_COLOR_BY_PALETTE = {
|
|
41150
|
+
red: "text-red-300",
|
|
41151
|
+
amber: "text-amber-300",
|
|
41152
|
+
blue: "text-blue-300",
|
|
41153
|
+
violet: "text-violet-300",
|
|
41154
|
+
emerald: "text-emerald-300",
|
|
41155
|
+
cyan: "text-cyan-300",
|
|
41156
|
+
slate: "text-slate-200"
|
|
41157
|
+
};
|
|
40821
41158
|
var BottlenecksContent = ({
|
|
40822
41159
|
workspaceId,
|
|
40823
41160
|
workspaceName,
|
|
@@ -41558,6 +41895,10 @@ var BottlenecksContent = ({
|
|
|
41558
41895
|
classificationUpdates[clipId] = {
|
|
41559
41896
|
status,
|
|
41560
41897
|
label: clip.classification_label || void 0,
|
|
41898
|
+
displayName: clip.classification_display_name || void 0,
|
|
41899
|
+
paletteToken: clip.classification_palette_token || void 0,
|
|
41900
|
+
iconToken: clip.classification_icon_token || void 0,
|
|
41901
|
+
isKnown: clip.classification_is_known ?? void 0,
|
|
41561
41902
|
confidence: clip.classification_confidence ?? void 0
|
|
41562
41903
|
};
|
|
41563
41904
|
});
|
|
@@ -42342,79 +42683,13 @@ var BottlenecksContent = ({
|
|
|
42342
42683
|
return () => window.removeEventListener("keydown", handleEscape);
|
|
42343
42684
|
}
|
|
42344
42685
|
}, [isFullscreen, exitFullscreen]);
|
|
42345
|
-
const
|
|
42346
|
-
"Machine Breakdown": {
|
|
42347
|
-
color: "text-white",
|
|
42348
|
-
bgColor: "bg-black/60 backdrop-blur-sm",
|
|
42349
|
-
borderColor: "border-transparent",
|
|
42350
|
-
Icon: AlertTriangle,
|
|
42351
|
-
iconColor: "text-red-500",
|
|
42352
|
-
// Standard red for high visibility on dark
|
|
42353
|
-
dotColor: "bg-red-600"
|
|
42354
|
-
},
|
|
42355
|
-
"Other": {
|
|
42356
|
-
color: "text-white",
|
|
42357
|
-
bgColor: "bg-black/60 backdrop-blur-sm",
|
|
42358
|
-
borderColor: "border-transparent",
|
|
42359
|
-
Icon: HelpCircle,
|
|
42360
|
-
iconColor: "text-gray-400",
|
|
42361
|
-
dotColor: "bg-gray-500"
|
|
42362
|
-
},
|
|
42363
|
-
"Power Outage": {
|
|
42364
|
-
color: "text-white",
|
|
42365
|
-
bgColor: "bg-black/60 backdrop-blur-sm",
|
|
42366
|
-
borderColor: "border-transparent",
|
|
42367
|
-
Icon: Zap,
|
|
42368
|
-
iconColor: "text-red-400",
|
|
42369
|
-
// Lighter red
|
|
42370
|
-
dotColor: "bg-red-500"
|
|
42371
|
-
},
|
|
42372
|
-
"Worker Absent": {
|
|
42373
|
-
color: "text-white",
|
|
42374
|
-
bgColor: "bg-black/60 backdrop-blur-sm",
|
|
42375
|
-
borderColor: "border-transparent",
|
|
42376
|
-
Icon: UserX,
|
|
42377
|
-
iconColor: "text-red-400",
|
|
42378
|
-
// Lighter red
|
|
42379
|
-
dotColor: "bg-red-500"
|
|
42380
|
-
},
|
|
42381
|
-
"Material Shortage": {
|
|
42382
|
-
color: "text-white",
|
|
42383
|
-
bgColor: "bg-black/60 backdrop-blur-sm",
|
|
42384
|
-
borderColor: "border-transparent",
|
|
42385
|
-
Icon: Package,
|
|
42386
|
-
iconColor: "text-red-300",
|
|
42387
|
-
// Even lighter red
|
|
42388
|
-
dotColor: "bg-red-400"
|
|
42389
|
-
},
|
|
42390
|
-
"Quality Issue": {
|
|
42391
|
-
color: "text-white",
|
|
42392
|
-
bgColor: "bg-black/60 backdrop-blur-sm",
|
|
42393
|
-
borderColor: "border-transparent",
|
|
42394
|
-
Icon: XCircle,
|
|
42395
|
-
iconColor: "text-red-300",
|
|
42396
|
-
// Even lighter red
|
|
42397
|
-
dotColor: "bg-red-400"
|
|
42398
|
-
},
|
|
42399
|
-
"Scheduled Maintenance": {
|
|
42400
|
-
color: "text-white",
|
|
42401
|
-
bgColor: "bg-black/60 backdrop-blur-sm",
|
|
42402
|
-
borderColor: "border-transparent",
|
|
42403
|
-
Icon: Wrench,
|
|
42404
|
-
iconColor: "text-red-200",
|
|
42405
|
-
// Very light red
|
|
42406
|
-
dotColor: "bg-red-300"
|
|
42407
|
-
}
|
|
42408
|
-
};
|
|
42409
|
-
const getIdleTimeRootCause = useCallback((video) => {
|
|
42686
|
+
const getIdleTimeClassification = useCallback((video) => {
|
|
42410
42687
|
if (video.type !== "idle_time") return null;
|
|
42411
42688
|
const videoId = video.id || video.clipId;
|
|
42412
|
-
if (!videoId) return
|
|
42689
|
+
if (!videoId) return null;
|
|
42413
42690
|
const classification = clipClassifications[videoId];
|
|
42414
|
-
console.log(`[
|
|
42415
|
-
|
|
42416
|
-
if (classification.status === "processing") return "processing";
|
|
42417
|
-
return classification.label || "processing";
|
|
42691
|
+
console.log(`[getIdleTimeClassification] Looking up ${videoId}: `, classification);
|
|
42692
|
+
return classification || null;
|
|
42418
42693
|
}, [clipClassifications]);
|
|
42419
42694
|
const getIdleTimeConfidence = useCallback((video) => {
|
|
42420
42695
|
if (video.type !== "idle_time") return null;
|
|
@@ -42425,36 +42700,35 @@ var BottlenecksContent = ({
|
|
|
42425
42700
|
if (classification.status === "processing") return null;
|
|
42426
42701
|
return classification.confidence ?? null;
|
|
42427
42702
|
}, [clipClassifications]);
|
|
42428
|
-
const
|
|
42429
|
-
|
|
42430
|
-
}, []);
|
|
42431
|
-
const getRootCauseConfig = useCallback((rootCause) => {
|
|
42432
|
-
if (!rootCause) return null;
|
|
42433
|
-
if (rootCause === "processing") {
|
|
42703
|
+
const getRootCauseConfig = useCallback((classification) => {
|
|
42704
|
+
if (!classification || classification.status === "processing") {
|
|
42434
42705
|
return {
|
|
42435
42706
|
color: "text-white",
|
|
42436
42707
|
bgColor: "bg-black/60 backdrop-blur-sm",
|
|
42437
|
-
borderColor: "border-
|
|
42708
|
+
borderColor: "border-white/10",
|
|
42438
42709
|
Icon: Clock,
|
|
42439
|
-
iconColor: "text-purple-
|
|
42440
|
-
dotColor: "bg-
|
|
42710
|
+
iconColor: "text-purple-300",
|
|
42711
|
+
dotColor: "bg-purple-400",
|
|
42441
42712
|
displayName: "Analyzing..."
|
|
42442
42713
|
};
|
|
42443
42714
|
}
|
|
42444
|
-
const
|
|
42445
|
-
|
|
42446
|
-
|
|
42447
|
-
|
|
42715
|
+
const presentation = getIdleReasonPresentation({
|
|
42716
|
+
label: classification.label,
|
|
42717
|
+
displayName: classification.displayName,
|
|
42718
|
+
paletteToken: classification.paletteToken,
|
|
42719
|
+
iconToken: classification.iconToken,
|
|
42720
|
+
isKnown: classification.isKnown
|
|
42721
|
+
});
|
|
42448
42722
|
return {
|
|
42449
42723
|
color: "text-white",
|
|
42450
42724
|
bgColor: "bg-black/60 backdrop-blur-sm",
|
|
42451
|
-
borderColor: "border-
|
|
42452
|
-
Icon:
|
|
42453
|
-
iconColor:
|
|
42454
|
-
dotColor:
|
|
42455
|
-
displayName:
|
|
42725
|
+
borderColor: "border-white/10",
|
|
42726
|
+
Icon: presentation.Icon,
|
|
42727
|
+
iconColor: OVERLAY_ICON_COLOR_BY_PALETTE[presentation.paletteToken] || OVERLAY_ICON_COLOR_BY_PALETTE.slate,
|
|
42728
|
+
dotColor: presentation.bgClass,
|
|
42729
|
+
displayName: presentation.displayName
|
|
42456
42730
|
};
|
|
42457
|
-
}, [
|
|
42731
|
+
}, []);
|
|
42458
42732
|
const getClipTypeLabel = useCallback((video) => {
|
|
42459
42733
|
if (!video) return "";
|
|
42460
42734
|
const currentFilter = activeFilterRef.current;
|
|
@@ -42619,15 +42893,15 @@ var BottlenecksContent = ({
|
|
|
42619
42893
|
(currentVideo.type === "cycle_completion" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds || currentVideo.type === "idle_time" || currentVideo.type === "low_value" ? currentVideo.type === "idle_time" ? (
|
|
42620
42894
|
// Show full colored badge for idle time
|
|
42621
42895
|
(() => {
|
|
42622
|
-
const
|
|
42896
|
+
const classification = getIdleTimeClassification(currentVideo);
|
|
42623
42897
|
const confidence = getIdleTimeConfidence(currentVideo);
|
|
42624
|
-
const config = getRootCauseConfig(
|
|
42898
|
+
const config = getRootCauseConfig(classification);
|
|
42625
42899
|
if (!config) return null;
|
|
42626
42900
|
const IconComponent = config.Icon;
|
|
42627
42901
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
42628
|
-
idleTimeVlmEnabled && /* @__PURE__ */ jsx("div", { className: "absolute top-3 left-3 z-10", children: /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center gap-1.5 px-2.5 py-1.5
|
|
42629
|
-
/* @__PURE__ */ jsx(IconComponent, { className: `h-3.5 w-3.5 ${config.iconColor}`, strokeWidth: 2.5 }),
|
|
42630
|
-
/* @__PURE__ */ jsx("span", { className: `font-medium text-xs ${config.color}`, children: config.displayName ||
|
|
42902
|
+
idleTimeVlmEnabled && /* @__PURE__ */ jsx("div", { className: "absolute top-3 left-3 z-10", children: /* @__PURE__ */ jsxs("div", { className: `inline-flex max-w-[18rem] items-center gap-1.5 rounded-md border px-2.5 py-1.5 shadow-lg ${config.bgColor} ${config.borderColor}`, children: [
|
|
42903
|
+
/* @__PURE__ */ jsx(IconComponent, { className: `h-3.5 w-3.5 flex-shrink-0 ${config.iconColor}`, strokeWidth: 2.5 }),
|
|
42904
|
+
/* @__PURE__ */ jsx("span", { className: `truncate font-medium text-xs ${config.color}`, children: config.displayName || "Analyzing..." })
|
|
42631
42905
|
] }) }),
|
|
42632
42906
|
idleTimeVlmEnabled && confidence !== null && (() => {
|
|
42633
42907
|
const confidencePercent = confidence * 100;
|
|
@@ -42662,9 +42936,9 @@ var BottlenecksContent = ({
|
|
|
42662
42936
|
currentVideo.type === "idle_time" ? (
|
|
42663
42937
|
// Show full colored badge for idle time
|
|
42664
42938
|
(() => {
|
|
42665
|
-
const
|
|
42939
|
+
const classification = getIdleTimeClassification(currentVideo);
|
|
42666
42940
|
const confidence = getIdleTimeConfidence(currentVideo);
|
|
42667
|
-
const config = getRootCauseConfig(
|
|
42941
|
+
const config = getRootCauseConfig(classification);
|
|
42668
42942
|
if (!config) return null;
|
|
42669
42943
|
const IconComponent = config.Icon;
|
|
42670
42944
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -42673,9 +42947,9 @@ var BottlenecksContent = ({
|
|
|
42673
42947
|
(confidence * 100).toFixed(0),
|
|
42674
42948
|
"%"
|
|
42675
42949
|
] }) }) }),
|
|
42676
|
-
idleTimeVlmEnabled && /* @__PURE__ */ jsx("div", { className: "absolute top-3 right-3 z-10", children: /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center gap-1.5 px-2.5 py-1.5
|
|
42677
|
-
/* @__PURE__ */ jsx(IconComponent, { className: `h-3.5 w-3.5 ${config.iconColor}`, strokeWidth: 2.5 }),
|
|
42678
|
-
/* @__PURE__ */ jsx("span", { className: `font-medium text-xs ${config.color}`, children:
|
|
42950
|
+
idleTimeVlmEnabled && /* @__PURE__ */ jsx("div", { className: "absolute top-3 right-3 z-10", children: /* @__PURE__ */ jsxs("div", { className: `inline-flex max-w-[18rem] items-center gap-1.5 rounded-md border px-2.5 py-1.5 shadow-lg ${config.bgColor} ${config.borderColor}`, children: [
|
|
42951
|
+
/* @__PURE__ */ jsx(IconComponent, { className: `h-3.5 w-3.5 flex-shrink-0 ${config.iconColor}`, strokeWidth: 2.5 }),
|
|
42952
|
+
/* @__PURE__ */ jsx("span", { className: `truncate font-medium text-xs ${config.color}`, children: config.displayName || "Analyzing..." })
|
|
42679
42953
|
] }) })
|
|
42680
42954
|
] });
|
|
42681
42955
|
})()
|
|
@@ -42715,6 +42989,7 @@ var BottlenecksContent = ({
|
|
|
42715
42989
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No clips found" })
|
|
42716
42990
|
] }) : /* @__PURE__ */ jsx("div", { className: "space-y-2", children: triageClips.map((clip, index) => {
|
|
42717
42991
|
const isIdleTime = clip.categoryId === "idle_time";
|
|
42992
|
+
const cycleItemCount = getMultiCycleItemCount(clip);
|
|
42718
42993
|
const timeString = isIdleTime && clip.idle_start_time && clip.idle_end_time ? formatIdleTimeRange(clip.idle_start_time, clip.idle_end_time, timezone) : new Date(clip.clip_timestamp).toLocaleTimeString("en-US", {
|
|
42719
42994
|
hour12: true,
|
|
42720
42995
|
hour: "numeric",
|
|
@@ -42767,15 +43042,15 @@ var BottlenecksContent = ({
|
|
|
42767
43042
|
// Idle time clips - show root cause label below time
|
|
42768
43043
|
(() => {
|
|
42769
43044
|
const clipId = clip.id || clip.clipId;
|
|
42770
|
-
const
|
|
43045
|
+
const classification = getIdleTimeClassification({
|
|
42771
43046
|
id: clipId,
|
|
42772
43047
|
type: "idle_time",
|
|
42773
43048
|
creation_timestamp: clip.clip_timestamp
|
|
42774
43049
|
});
|
|
42775
|
-
console.log(`[BottlenecksContent] Sidebar clip ${clipId}:
|
|
42776
|
-
const config = getRootCauseConfig(
|
|
43050
|
+
console.log(`[BottlenecksContent] Sidebar clip ${clipId}: classification=`, clipClassifications[clipId]);
|
|
43051
|
+
const config = getRootCauseConfig(classification);
|
|
42777
43052
|
if (!config) {
|
|
42778
|
-
console.log(`[BottlenecksContent] No config found for
|
|
43053
|
+
console.log(`[BottlenecksContent] No config found for classification on clip: ${clipId}`);
|
|
42779
43054
|
return null;
|
|
42780
43055
|
}
|
|
42781
43056
|
const IconComponent = config.Icon;
|
|
@@ -42790,7 +43065,7 @@ var BottlenecksContent = ({
|
|
|
42790
43065
|
] }) })
|
|
42791
43066
|
] }),
|
|
42792
43067
|
/* @__PURE__ */ jsx("div", { className: "pl-6", children: idleTimeVlmEnabled ? /* @__PURE__ */ jsx("span", { className: "inline-flex items-center px-2 py-0.5 rounded-md border text-xs font-medium bg-gray-50 text-gray-700 border-gray-200", children: (() => {
|
|
42793
|
-
const displayText = config.displayName ||
|
|
43068
|
+
const displayText = config.displayName || "Analyzing...";
|
|
42794
43069
|
console.log(`[BottlenecksContent] Displaying label: "${displayText}" for clip ${clipId}`);
|
|
42795
43070
|
return displayText;
|
|
42796
43071
|
})() }) : (() => {
|
|
@@ -42810,7 +43085,13 @@ var BottlenecksContent = ({
|
|
|
42810
43085
|
clip.duration ? `${clip.duration.toFixed(1)}s` : "N/A",
|
|
42811
43086
|
")"
|
|
42812
43087
|
] }) }),
|
|
42813
|
-
/* @__PURE__ */
|
|
43088
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
43089
|
+
cycleItemCount ? /* @__PURE__ */ jsxs("span", { className: "px-2 py-1 text-xs font-semibold rounded border border-blue-200 bg-blue-100 text-blue-700", children: [
|
|
43090
|
+
"x",
|
|
43091
|
+
cycleItemCount
|
|
43092
|
+
] }) : null,
|
|
43093
|
+
/* @__PURE__ */ jsx("span", { className: `px-2 py-1 text-xs font-semibold rounded ${badgeColor}`, children: badgeText })
|
|
43094
|
+
] })
|
|
42814
43095
|
] })
|
|
42815
43096
|
)
|
|
42816
43097
|
},
|
|
@@ -42903,15 +43184,15 @@ var BottlenecksContent = ({
|
|
|
42903
43184
|
(currentVideo.type === "cycle_completion" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds || currentVideo.type === "idle_time" || currentVideo.type === "low_value" ? currentVideo.type === "idle_time" ? (
|
|
42904
43185
|
// Show full colored badge for idle time
|
|
42905
43186
|
(() => {
|
|
42906
|
-
const
|
|
43187
|
+
const classification = getIdleTimeClassification(currentVideo);
|
|
42907
43188
|
const confidence = getIdleTimeConfidence(currentVideo);
|
|
42908
|
-
const config = getRootCauseConfig(
|
|
43189
|
+
const config = getRootCauseConfig(classification);
|
|
42909
43190
|
if (!config) return null;
|
|
42910
43191
|
const IconComponent = config.Icon;
|
|
42911
43192
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
42912
|
-
idleTimeVlmEnabled && /* @__PURE__ */ jsx("div", { className: "absolute top-4 left-4 z-50", children: /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center gap-2 px-3 py-2
|
|
42913
|
-
/* @__PURE__ */ jsx(IconComponent, { className: `h-4 w-4 ${config.iconColor}`, strokeWidth: 2.5 }),
|
|
42914
|
-
/* @__PURE__ */ jsx("span", { className: `font-medium text-sm ${config.color}`, children:
|
|
43193
|
+
idleTimeVlmEnabled && /* @__PURE__ */ jsx("div", { className: "absolute top-4 left-4 z-50", children: /* @__PURE__ */ jsxs("div", { className: `inline-flex max-w-[20rem] items-center gap-2 rounded-md border px-3 py-2 shadow-lg ${config.bgColor} ${config.borderColor}`, children: [
|
|
43194
|
+
/* @__PURE__ */ jsx(IconComponent, { className: `h-4 w-4 flex-shrink-0 ${config.iconColor}`, strokeWidth: 2.5 }),
|
|
43195
|
+
/* @__PURE__ */ jsx("span", { className: `truncate font-medium text-sm ${config.color}`, children: config.displayName || "Analyzing..." })
|
|
42915
43196
|
] }) }),
|
|
42916
43197
|
idleTimeVlmEnabled && confidence !== null && /* @__PURE__ */ jsx("div", { className: "absolute top-4 right-4 z-50", children: /* @__PURE__ */ jsx("div", { className: "inline-flex items-center gap-1.5 px-3 py-2 rounded-lg bg-black/70 backdrop-blur-sm shadow-lg border border-white/10", children: /* @__PURE__ */ jsxs("span", { className: "font-medium text-sm text-white", children: [
|
|
42917
43198
|
"AI Confidence: ",
|
|
@@ -42933,9 +43214,9 @@ var BottlenecksContent = ({
|
|
|
42933
43214
|
] }) }) : currentVideo.type === "idle_time" ? (
|
|
42934
43215
|
// Show full colored badge for idle time
|
|
42935
43216
|
(() => {
|
|
42936
|
-
const
|
|
43217
|
+
const classification = getIdleTimeClassification(currentVideo);
|
|
42937
43218
|
const confidence = getIdleTimeConfidence(currentVideo);
|
|
42938
|
-
const config = getRootCauseConfig(
|
|
43219
|
+
const config = getRootCauseConfig(classification);
|
|
42939
43220
|
if (!config) return null;
|
|
42940
43221
|
const IconComponent = config.Icon;
|
|
42941
43222
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -42944,9 +43225,9 @@ var BottlenecksContent = ({
|
|
|
42944
43225
|
(confidence * 100).toFixed(0),
|
|
42945
43226
|
"%"
|
|
42946
43227
|
] }) }) }),
|
|
42947
|
-
idleTimeVlmEnabled && /* @__PURE__ */ jsx("div", { className: "absolute top-4 right-20 z-50", children: /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center gap-2 px-3 py-2
|
|
42948
|
-
/* @__PURE__ */ jsx(IconComponent, { className: `h-4 w-4 ${config.iconColor}`, strokeWidth: 2.5 }),
|
|
42949
|
-
/* @__PURE__ */ jsx("span", { className: `font-medium text-sm ${config.color}`, children:
|
|
43228
|
+
idleTimeVlmEnabled && /* @__PURE__ */ jsx("div", { className: "absolute top-4 right-20 z-50", children: /* @__PURE__ */ jsxs("div", { className: `inline-flex max-w-[20rem] items-center gap-2 rounded-md border px-3 py-2 shadow-lg ${config.bgColor} ${config.borderColor}`, children: [
|
|
43229
|
+
/* @__PURE__ */ jsx(IconComponent, { className: `h-4 w-4 flex-shrink-0 ${config.iconColor}`, strokeWidth: 2.5 }),
|
|
43230
|
+
/* @__PURE__ */ jsx("span", { className: `truncate font-medium text-sm ${config.color}`, children: config.displayName || "Analyzing..." })
|
|
42950
43231
|
] }) })
|
|
42951
43232
|
] });
|
|
42952
43233
|
})()
|
|
@@ -44895,16 +45176,6 @@ var LineHistoryCalendar = ({
|
|
|
44895
45176
|
] });
|
|
44896
45177
|
};
|
|
44897
45178
|
var LineHistoryCalendar_default = LineHistoryCalendar;
|
|
44898
|
-
var STATIC_COLORS = {
|
|
44899
|
-
"Operator Absent": "#dc2626",
|
|
44900
|
-
// red-600 - Critical/Urgent
|
|
44901
|
-
"No Material": "#f59e0b",
|
|
44902
|
-
// amber-500 - Warning/Supply Chain
|
|
44903
|
-
"Machine Downtime": "#3b82f6",
|
|
44904
|
-
// blue-500 - Scheduled/Technical
|
|
44905
|
-
"Operator Idle": "#8b5cf6"
|
|
44906
|
-
// violet-500 - Low Priority/Behavioral
|
|
44907
|
-
};
|
|
44908
45179
|
var PRODUCTIVE_COLOR = "#00AB45";
|
|
44909
45180
|
var IDLE_COLOR = "#e5e7eb";
|
|
44910
45181
|
var formatDuration = (seconds) => {
|
|
@@ -44927,19 +45198,21 @@ var formatDuration = (seconds) => {
|
|
|
44927
45198
|
}
|
|
44928
45199
|
return parts.join(" ");
|
|
44929
45200
|
};
|
|
44930
|
-
var getColorForEntry = (
|
|
44931
|
-
const normalized = name.trim().toLowerCase();
|
|
45201
|
+
var getColorForEntry = (entry) => {
|
|
45202
|
+
const normalized = entry.name.trim().toLowerCase();
|
|
44932
45203
|
if (normalized === "productive" || normalized === "productive time") {
|
|
44933
45204
|
return PRODUCTIVE_COLOR;
|
|
44934
45205
|
}
|
|
44935
45206
|
if (normalized === "idle" || normalized === "idle time") {
|
|
44936
45207
|
return IDLE_COLOR;
|
|
44937
45208
|
}
|
|
44938
|
-
|
|
44939
|
-
|
|
44940
|
-
|
|
44941
|
-
|
|
44942
|
-
|
|
45209
|
+
return getIdleReasonHexColor({
|
|
45210
|
+
label: entry.reasonKey || entry.name,
|
|
45211
|
+
displayName: entry.displayName || entry.name,
|
|
45212
|
+
paletteToken: entry.paletteToken,
|
|
45213
|
+
iconToken: entry.iconToken,
|
|
45214
|
+
isKnown: entry.isKnown
|
|
45215
|
+
});
|
|
44943
45216
|
};
|
|
44944
45217
|
var CustomTooltip = ({ active, payload, hideTotalDuration }) => {
|
|
44945
45218
|
if (active && payload && payload.length) {
|
|
@@ -44953,8 +45226,8 @@ var CustomTooltip = ({ active, payload, hideTotalDuration }) => {
|
|
|
44953
45226
|
const hasContributors = contributors.length > 0;
|
|
44954
45227
|
return /* @__PURE__ */ jsxs("div", { className: "bg-white p-3 border border-gray-100 shadow-lg rounded-lg text-xs z-50 min-w-[280px]", children: [
|
|
44955
45228
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pb-2 mb-2 border-b border-slate-100", children: [
|
|
44956
|
-
/* @__PURE__ */ jsx("div", { className: "w-2.5 h-2.5 rounded-full flex-shrink-0", style: { backgroundColor: payload[0].payload.fill || getColorForEntry(payload[0].
|
|
44957
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold text-slate-800 text-[13px]", children: payload[0].name.replace(/_/g, " ") })
|
|
45229
|
+
/* @__PURE__ */ jsx("div", { className: "w-2.5 h-2.5 rounded-full flex-shrink-0", style: { backgroundColor: payload[0].payload.fill || getColorForEntry(payload[0].payload) } }),
|
|
45230
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-slate-800 text-[13px]", children: datum?.displayName || payload[0].name.replace(/_/g, " ") })
|
|
44958
45231
|
] }),
|
|
44959
45232
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5 pb-1", children: [
|
|
44960
45233
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center gap-4", children: [
|
|
@@ -45015,7 +45288,8 @@ var IdleTimeReasonChartComponent = ({
|
|
|
45015
45288
|
isLoading = false,
|
|
45016
45289
|
error = null,
|
|
45017
45290
|
hideTotalDuration = false,
|
|
45018
|
-
updateAnimation = "replay"
|
|
45291
|
+
updateAnimation = "replay",
|
|
45292
|
+
variant = "pie"
|
|
45019
45293
|
}) => {
|
|
45020
45294
|
const [activeData, setActiveData] = React141__default.useState([]);
|
|
45021
45295
|
React141__default.useEffect(() => {
|
|
@@ -45060,6 +45334,73 @@ var IdleTimeReasonChartComponent = ({
|
|
|
45060
45334
|
if (!data || data.length === 0) {
|
|
45061
45335
|
return /* @__PURE__ */ jsx(EmptyState, { message: "No Idle Time reasons available" });
|
|
45062
45336
|
}
|
|
45337
|
+
if (variant === "bar") {
|
|
45338
|
+
return /* @__PURE__ */ jsx(
|
|
45339
|
+
"div",
|
|
45340
|
+
{
|
|
45341
|
+
className: "w-full h-full flex items-center overflow-visible focus:outline-none",
|
|
45342
|
+
tabIndex: -1,
|
|
45343
|
+
onFocus: (e) => e.currentTarget.blur(),
|
|
45344
|
+
children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
|
|
45345
|
+
BarChart$1,
|
|
45346
|
+
{
|
|
45347
|
+
data: activeData,
|
|
45348
|
+
layout: "vertical",
|
|
45349
|
+
margin: { top: 5, right: 30, left: 10, bottom: 5 },
|
|
45350
|
+
barCategoryGap: 8,
|
|
45351
|
+
barGap: 2,
|
|
45352
|
+
children: [
|
|
45353
|
+
/* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", horizontal: false, vertical: true }),
|
|
45354
|
+
/* @__PURE__ */ jsx(
|
|
45355
|
+
XAxis,
|
|
45356
|
+
{
|
|
45357
|
+
type: "number",
|
|
45358
|
+
hide: false,
|
|
45359
|
+
domain: [0, 100],
|
|
45360
|
+
ticks: [0, 20, 40, 60, 80, 100],
|
|
45361
|
+
tickFormatter: (val) => `${val}%`,
|
|
45362
|
+
tick: { fontSize: 10, fill: "#6b7280" },
|
|
45363
|
+
axisLine: { stroke: "#e5e7eb" },
|
|
45364
|
+
tickLine: false
|
|
45365
|
+
}
|
|
45366
|
+
),
|
|
45367
|
+
/* @__PURE__ */ jsx(
|
|
45368
|
+
YAxis,
|
|
45369
|
+
{
|
|
45370
|
+
type: "category",
|
|
45371
|
+
dataKey: "name",
|
|
45372
|
+
tick: { fontSize: 11, fill: "#4b5563" },
|
|
45373
|
+
tickFormatter: (val) => typeof val === "string" ? val.replace(/_/g, " ") : val,
|
|
45374
|
+
width: 90,
|
|
45375
|
+
axisLine: false,
|
|
45376
|
+
tickLine: false
|
|
45377
|
+
}
|
|
45378
|
+
),
|
|
45379
|
+
/* @__PURE__ */ jsx(
|
|
45380
|
+
Tooltip,
|
|
45381
|
+
{
|
|
45382
|
+
cursor: { fill: "rgba(0,0,0,0.04)" },
|
|
45383
|
+
content: /* @__PURE__ */ jsx(CustomTooltip, { hideTotalDuration })
|
|
45384
|
+
}
|
|
45385
|
+
),
|
|
45386
|
+
/* @__PURE__ */ jsx(
|
|
45387
|
+
Bar,
|
|
45388
|
+
{
|
|
45389
|
+
dataKey: "value",
|
|
45390
|
+
radius: [0, 4, 4, 0],
|
|
45391
|
+
animationDuration: 1500,
|
|
45392
|
+
animationEasing: "ease-out",
|
|
45393
|
+
isAnimationActive: true,
|
|
45394
|
+
barSize: 20,
|
|
45395
|
+
children: activeData.map((entry, index) => /* @__PURE__ */ jsx(Cell, { fill: getColorForEntry(entry) }, `cell-${index}`))
|
|
45396
|
+
}
|
|
45397
|
+
)
|
|
45398
|
+
]
|
|
45399
|
+
}
|
|
45400
|
+
) })
|
|
45401
|
+
}
|
|
45402
|
+
);
|
|
45403
|
+
}
|
|
45063
45404
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
45064
45405
|
/* @__PURE__ */ jsx("style", { children: `
|
|
45065
45406
|
.recharts-wrapper:focus,
|
|
@@ -45121,7 +45462,7 @@ var IdleTimeReasonChartComponent = ({
|
|
|
45121
45462
|
children: activeData.map((entry, index) => /* @__PURE__ */ jsx(
|
|
45122
45463
|
Cell,
|
|
45123
45464
|
{
|
|
45124
|
-
fill: getColorForEntry(entry
|
|
45465
|
+
fill: getColorForEntry(entry),
|
|
45125
45466
|
strokeWidth: 0
|
|
45126
45467
|
},
|
|
45127
45468
|
`cell-${index}`
|
|
@@ -45138,10 +45479,10 @@ var IdleTimeReasonChartComponent = ({
|
|
|
45138
45479
|
"span",
|
|
45139
45480
|
{
|
|
45140
45481
|
className: "inline-block w-2.5 h-2.5 rounded-full mr-1.5 mt-0.5 flex-shrink-0",
|
|
45141
|
-
style: { backgroundColor: getColorForEntry(entry
|
|
45482
|
+
style: { backgroundColor: getColorForEntry(entry) }
|
|
45142
45483
|
}
|
|
45143
45484
|
),
|
|
45144
|
-
/* @__PURE__ */ jsx("span", { className: "text-gray-600 leading-tight text-[11px] sm:text-xs break-words", children: entry.name.replace(/_/g, " ") })
|
|
45485
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-600 leading-tight text-[11px] sm:text-xs break-words", children: entry.displayName || entry.name.replace(/_/g, " ") })
|
|
45145
45486
|
] }, `item-${index}`)) }) })
|
|
45146
45487
|
]
|
|
45147
45488
|
}
|
|
@@ -45266,7 +45607,6 @@ var LineMonthlyHistory = ({
|
|
|
45266
45607
|
const { isIdleTimeVlmEnabled } = useIdleTimeVlmConfig();
|
|
45267
45608
|
const idleTimeVlmEnabled = isIdleTimeVlmEnabled(lineId);
|
|
45268
45609
|
const isUptimeMode = monitoringMode === "uptime";
|
|
45269
|
-
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
45270
45610
|
const chartKey = useMemo(() => `${lineId}-${month}-${year}-${selectedShiftId}-${rangeStart}-${rangeEnd}`, [lineId, month, year, selectedShiftId, rangeStart, rangeEnd]);
|
|
45271
45611
|
const monthBounds = useMemo(() => getMonthKeyBounds(year, month), [year, month]);
|
|
45272
45612
|
const normalizedRange = useMemo(() => {
|
|
@@ -45314,20 +45654,20 @@ var LineMonthlyHistory = ({
|
|
|
45314
45654
|
{ efficiency: 0, underperforming: 0, totalWorkspaces: 0, count: 0 }
|
|
45315
45655
|
);
|
|
45316
45656
|
const avgEfficiency = averages.count > 0 ? averages.efficiency / averages.count : 0;
|
|
45317
|
-
const
|
|
45657
|
+
const outputAverages = (analysisMonthlyData || []).reduce(
|
|
45318
45658
|
(acc, day) => {
|
|
45319
45659
|
const shiftData = getShiftData2(day, selectedShiftId);
|
|
45320
45660
|
if (!shiftData || !hasRealData(shiftData)) {
|
|
45321
45661
|
return acc;
|
|
45322
45662
|
}
|
|
45323
|
-
const status = getEfficiencyColor(shiftData.avg_efficiency || 0, effectiveLegend);
|
|
45324
45663
|
return {
|
|
45325
|
-
|
|
45326
|
-
|
|
45664
|
+
output: acc.output + (shiftData.output || 0),
|
|
45665
|
+
count: acc.count + 1
|
|
45327
45666
|
};
|
|
45328
45667
|
},
|
|
45329
|
-
{
|
|
45668
|
+
{ output: 0, count: 0 }
|
|
45330
45669
|
);
|
|
45670
|
+
const avgOutput = outputAverages.count > 0 ? outputAverages.output / outputAverages.count : 0;
|
|
45331
45671
|
const uptimeSummary = useMemo(() => {
|
|
45332
45672
|
if (!isUptimeMode) return null;
|
|
45333
45673
|
const validDays = (analysisMonthlyData || []).map((day) => getShiftData2(day, selectedShiftId)).filter((shiftData) => shiftData && hasRealData(shiftData)).map((shiftData) => ({ shiftData, totals: getUptimeTotals(shiftData) }));
|
|
@@ -45360,6 +45700,10 @@ var LineMonthlyHistory = ({
|
|
|
45360
45700
|
const efficiencyImproved = efficiencyDelta >= 0;
|
|
45361
45701
|
const EfficiencyTrendIcon = efficiencyImproved ? ArrowUp : ArrowDown;
|
|
45362
45702
|
const efficiencyTrendText = `${Math.abs(efficiencyDelta).toFixed(1)}%`;
|
|
45703
|
+
const outputDelta = trendSummary?.avg_daily_output?.delta_pp ?? 0;
|
|
45704
|
+
const outputImproved = outputDelta >= 0;
|
|
45705
|
+
const OutputTrendIcon = outputImproved ? ArrowUp : ArrowDown;
|
|
45706
|
+
const outputTrendText = `${Math.abs(outputDelta).toFixed(1)}%`;
|
|
45363
45707
|
const utilizationDelta = efficiencyDelta;
|
|
45364
45708
|
const utilizationImproved = utilizationDelta >= 0;
|
|
45365
45709
|
const UtilizationTrendIcon = utilizationImproved ? ArrowUp : ArrowDown;
|
|
@@ -45644,12 +45988,17 @@ var LineMonthlyHistory = ({
|
|
|
45644
45988
|
] })
|
|
45645
45989
|
] }),
|
|
45646
45990
|
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex flex-col justify-between", children: [
|
|
45647
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-bold text-gray-700 mb-2", children: "
|
|
45648
|
-
/* @__PURE__ */
|
|
45649
|
-
|
|
45650
|
-
"
|
|
45651
|
-
|
|
45652
|
-
|
|
45991
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-bold text-gray-700 mb-2", children: "Avg. Output" }),
|
|
45992
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-nowrap", children: [
|
|
45993
|
+
/* @__PURE__ */ jsx("div", { className: "text-xl font-bold text-gray-900", children: Math.round(avgOutput).toLocaleString() }),
|
|
45994
|
+
/* @__PURE__ */ jsxs("div", { className: `flex items-center gap-1 ${outputImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-1.5 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
45995
|
+
/* @__PURE__ */ jsx(OutputTrendIcon, { className: "w-3 h-3" }),
|
|
45996
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
45997
|
+
outputTrendText,
|
|
45998
|
+
" vs last month"
|
|
45999
|
+
] })
|
|
46000
|
+
] })
|
|
46001
|
+
] })
|
|
45653
46002
|
] })
|
|
45654
46003
|
] }),
|
|
45655
46004
|
isUptimeMode ? /* @__PURE__ */ jsxs("div", { className: `grid grid-cols-1 ${idleTimeVlmEnabled ? "sm:grid-cols-2" : "sm:grid-cols-1"} gap-2 sm:gap-3 lg:gap-4`, children: [
|
|
@@ -46168,11 +46517,6 @@ var LineMonthlyPdfGenerator = ({
|
|
|
46168
46517
|
doc.text("Working Days:", 25, kpiStartY + kpiSpacing * 2);
|
|
46169
46518
|
doc.setFont("helvetica", "bold");
|
|
46170
46519
|
doc.text(`${outputMetrics.totalDays} days`, 120, kpiStartY + kpiSpacing * 2);
|
|
46171
|
-
createKPIBox(kpiStartY + kpiSpacing * 3);
|
|
46172
|
-
doc.setFont("helvetica", "normal");
|
|
46173
|
-
doc.text("Underperforming Days:", 25, kpiStartY + kpiSpacing * 3);
|
|
46174
|
-
doc.setFont("helvetica", "bold");
|
|
46175
|
-
doc.text(`${outputMetrics.underperformingDays} of ${outputMetrics.totalDays}`, 120, kpiStartY + kpiSpacing * 3);
|
|
46176
46520
|
}
|
|
46177
46521
|
} else {
|
|
46178
46522
|
doc.setFontSize(12);
|
|
@@ -47750,7 +48094,8 @@ var WorkspaceMonthlyHistory = ({
|
|
|
47750
48094
|
availableShifts,
|
|
47751
48095
|
monthlyDataLoading = false,
|
|
47752
48096
|
className = "",
|
|
47753
|
-
trendSummary
|
|
48097
|
+
trendSummary,
|
|
48098
|
+
isAssemblyWorkspace = false
|
|
47754
48099
|
}) => {
|
|
47755
48100
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
47756
48101
|
const isUptimeMode = monitoringMode === "uptime";
|
|
@@ -47989,12 +48334,8 @@ var WorkspaceMonthlyHistory = ({
|
|
|
47989
48334
|
}, [analysisMonthlyData, selectedShiftId, isUptimeMode, shiftWorkSeconds]);
|
|
47990
48335
|
const efficiencyDelta = trendSummary?.avg_efficiency?.delta_pp ?? 0;
|
|
47991
48336
|
const efficiencyImproved = efficiencyDelta >= 0;
|
|
47992
|
-
const outputDeltaRaw = trendSummary?.avg_daily_output?.delta_pp ?? 0;
|
|
47993
48337
|
const cycleDeltaRaw = trendSummary?.avg_cycle_time?.delta_seconds ?? 0;
|
|
47994
|
-
const outputPrev = trendSummary?.avg_daily_output?.previous ?? 0;
|
|
47995
48338
|
const cyclePrev = trendSummary?.avg_cycle_time?.previous ?? 0;
|
|
47996
|
-
const outputDelta = outputPrev ? outputDeltaRaw / outputPrev * 100 : 0;
|
|
47997
|
-
const outputImproved = outputDelta >= 0;
|
|
47998
48339
|
const cycleDelta = cyclePrev ? cycleDeltaRaw / cyclePrev * 100 : 0;
|
|
47999
48340
|
const cycleWorsened = cycleDelta > 0;
|
|
48000
48341
|
const utilizationDelta = efficiencyDelta;
|
|
@@ -48074,7 +48415,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
48074
48415
|
shift.id
|
|
48075
48416
|
)) }) }),
|
|
48076
48417
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
|
|
48077
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6", children: [
|
|
48418
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-4 sm:p-6 flex flex-col", children: [
|
|
48078
48419
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-2", children: WEEKDAYS3.map((day, idx) => /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-gray-500 dark:text-gray-400 text-center", children: day }, day)) }),
|
|
48079
48420
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-2 mt-6", children: calendarData.calendar.map((day, index) => {
|
|
48080
48421
|
const dayNumber = index >= calendarData.startOffset ? index - calendarData.startOffset + 1 : null;
|
|
@@ -48162,8 +48503,32 @@ var WorkspaceMonthlyHistory = ({
|
|
|
48162
48503
|
) }, index);
|
|
48163
48504
|
}) })
|
|
48164
48505
|
] }),
|
|
48165
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
48166
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-
|
|
48506
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 h-full", children: [
|
|
48507
|
+
isAssemblyWorkspace && !isUptimeMode ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
|
|
48508
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex flex-col justify-between", children: [
|
|
48509
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-gray-600 mb-1", children: "Avg Idle Time" }),
|
|
48510
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-nowrap", children: [
|
|
48511
|
+
/* @__PURE__ */ jsx("div", { className: "text-2xl font-bold text-gray-900", children: formatIdleTime(metrics2?.avgIdleTime ?? 0) }),
|
|
48512
|
+
/* @__PURE__ */ jsxs("div", { className: `flex items-center gap-1 ${idleImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
48513
|
+
idleImproved ? /* @__PURE__ */ jsx(ArrowDown, { className: "w-3 h-3" }) : /* @__PURE__ */ jsx(ArrowUp, { className: "w-3 h-3" }),
|
|
48514
|
+
/* @__PURE__ */ jsx("span", { children: idleTrendText })
|
|
48515
|
+
] })
|
|
48516
|
+
] })
|
|
48517
|
+
] }),
|
|
48518
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex flex-col justify-between", children: [
|
|
48519
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-gray-600 mb-1", children: "Avg Cycle Time" }),
|
|
48520
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-nowrap", children: [
|
|
48521
|
+
/* @__PURE__ */ jsxs("div", { className: "text-2xl font-bold text-gray-900", children: [
|
|
48522
|
+
metrics2?.avgCycleTime ?? 0,
|
|
48523
|
+
"s"
|
|
48524
|
+
] }),
|
|
48525
|
+
/* @__PURE__ */ jsxs("div", { className: `flex items-center gap-1 ${cycleWorsened ? "bg-red-50 text-red-600" : "bg-emerald-50 text-emerald-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
48526
|
+
cycleWorsened ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3 h-3" }) : /* @__PURE__ */ jsx(ArrowDown, { className: "w-3 h-3" }),
|
|
48527
|
+
/* @__PURE__ */ jsx("span", { children: `${Math.abs(cycleDelta).toFixed(1)}% vs last month` })
|
|
48528
|
+
] })
|
|
48529
|
+
] })
|
|
48530
|
+
] })
|
|
48531
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: `grid grid-cols-1 gap-4 ${isUptimeMode ? "md:grid-cols-3" : "md:grid-cols-2"}`, children: [
|
|
48167
48532
|
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex flex-col justify-between", children: [
|
|
48168
48533
|
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-gray-600 mb-1", children: isUptimeMode ? "Avg Utilization" : "Avg Efficiency" }),
|
|
48169
48534
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-nowrap", children: [
|
|
@@ -48177,16 +48542,13 @@ var WorkspaceMonthlyHistory = ({
|
|
|
48177
48542
|
] })
|
|
48178
48543
|
] })
|
|
48179
48544
|
] }),
|
|
48180
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex flex-col justify-between", children: [
|
|
48181
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-gray-600 mb-1", children:
|
|
48545
|
+
isUptimeMode && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex flex-col justify-between", children: [
|
|
48546
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-gray-600 mb-1", children: "Avg Idle Time" }),
|
|
48182
48547
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-nowrap", children: [
|
|
48183
|
-
/* @__PURE__ */ jsx("div", { className: "text-2xl font-bold text-gray-900", children:
|
|
48184
|
-
|
|
48548
|
+
/* @__PURE__ */ jsx("div", { className: "text-2xl font-bold text-gray-900", children: formatIdleTime(metrics2?.avgIdleTime ?? 0) }),
|
|
48549
|
+
/* @__PURE__ */ jsxs("div", { className: `flex items-center gap-1 ${idleImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
48185
48550
|
idleImproved ? /* @__PURE__ */ jsx(ArrowDown, { className: "w-3 h-3" }) : /* @__PURE__ */ jsx(ArrowUp, { className: "w-3 h-3" }),
|
|
48186
48551
|
/* @__PURE__ */ jsx("span", { children: idleTrendText })
|
|
48187
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: `flex items-center gap-1 ${outputImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
48188
|
-
outputImproved ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3 h-3" }) : /* @__PURE__ */ jsx(ArrowDown, { className: "w-3 h-3" }),
|
|
48189
|
-
/* @__PURE__ */ jsx("span", { children: `${Math.abs(outputDelta).toFixed(1)}% vs last month` })
|
|
48190
48552
|
] })
|
|
48191
48553
|
] })
|
|
48192
48554
|
] }),
|
|
@@ -48208,9 +48570,9 @@ var WorkspaceMonthlyHistory = ({
|
|
|
48208
48570
|
] })
|
|
48209
48571
|
] }),
|
|
48210
48572
|
/* @__PURE__ */ jsxs("div", { className: `grid grid-cols-1 ${idleTimeVlmEnabled ? "sm:grid-cols-2" : "sm:grid-cols-1"} gap-4`, children: [
|
|
48211
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4", children: [
|
|
48573
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex flex-col", children: [
|
|
48212
48574
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700 mb-3 text-left", children: isUptimeMode ? "Utilization" : "Time Utilization" }),
|
|
48213
|
-
pieChartData.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "w-full
|
|
48575
|
+
pieChartData.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "w-full flex items-center overflow-hidden h-[160px]", children: [
|
|
48214
48576
|
/* @__PURE__ */ jsx("div", { className: "flex-1 h-full min-w-0 relative flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "relative w-full aspect-square max-h-full", style: { maxWidth: "min(100%, 280px)", containerType: "inline-size" }, children: [
|
|
48215
48577
|
/* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsx(PieChart, { children: /* @__PURE__ */ jsx(
|
|
48216
48578
|
Pie,
|
|
@@ -48283,7 +48645,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
48283
48645
|
] }) })
|
|
48284
48646
|
] }) : /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[160px]", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400", children: "No data available" }) })
|
|
48285
48647
|
] }),
|
|
48286
|
-
idleTimeVlmEnabled && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 h-full", children: [
|
|
48648
|
+
idleTimeVlmEnabled && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 h-full flex flex-col", children: [
|
|
48287
48649
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700 mb-3 text-left", children: "Idle Time Breakdown" }),
|
|
48288
48650
|
/* @__PURE__ */ jsx("div", { className: "h-[160px]", children: /* @__PURE__ */ jsx(
|
|
48289
48651
|
IdleTimeReasonChart,
|
|
@@ -48295,7 +48657,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
48295
48657
|
) })
|
|
48296
48658
|
] })
|
|
48297
48659
|
] }),
|
|
48298
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex-1", children: [
|
|
48660
|
+
(!isAssemblyWorkspace || isUptimeMode) && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex-1", children: [
|
|
48299
48661
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700 mb-3 text-left", children: isUptimeMode ? "Daily Utilization" : "Daily Output" }),
|
|
48300
48662
|
/* @__PURE__ */ jsx("div", { style: { height: "220px" }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
|
|
48301
48663
|
BarChart$1,
|
|
@@ -48493,7 +48855,7 @@ var WorkspaceWhatsAppShareButton = ({
|
|
|
48493
48855
|
}
|
|
48494
48856
|
);
|
|
48495
48857
|
};
|
|
48496
|
-
var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiencyLegend }) => {
|
|
48858
|
+
var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiencyLegend, hourlyCycleTimes }) => {
|
|
48497
48859
|
const [isGenerating, setIsGenerating] = useState(false);
|
|
48498
48860
|
const entityConfig = useEntityConfig();
|
|
48499
48861
|
const effectiveLegend = efficiencyLegend || DEFAULT_EFFICIENCY_LEGEND;
|
|
@@ -48501,6 +48863,7 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48501
48863
|
setIsGenerating(true);
|
|
48502
48864
|
try {
|
|
48503
48865
|
const isUptimeMode = workspace.monitoring_mode === "uptime";
|
|
48866
|
+
const isAssemblyCycleMode = !isUptimeMode && workspace.line_assembly_enabled === true && workspace.action_type === "assembly";
|
|
48504
48867
|
const shiftMinutes = getShiftDurationMinutes(workspace.shift_start, workspace.shift_end);
|
|
48505
48868
|
const shiftSeconds = shiftMinutes ? shiftMinutes * 60 : 0;
|
|
48506
48869
|
const idleSeconds = Math.max(workspace.idle_time || 0, 0);
|
|
@@ -48561,9 +48924,38 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48561
48924
|
minute: "2-digit",
|
|
48562
48925
|
hour12: true
|
|
48563
48926
|
});
|
|
48927
|
+
const shiftEndTime = (/* @__PURE__ */ new Date(`2000-01-01 ${workspace.shift_end}`)).toLocaleTimeString("en-IN", {
|
|
48928
|
+
hour: "2-digit",
|
|
48929
|
+
minute: "2-digit",
|
|
48930
|
+
hour12: true
|
|
48931
|
+
});
|
|
48932
|
+
const parseTimeToMinutes3 = (timeValue) => {
|
|
48933
|
+
const [hourPart, minutePart] = timeValue.split(":").map(Number);
|
|
48934
|
+
const hour = Number.isFinite(hourPart) ? hourPart : 0;
|
|
48935
|
+
const minute = Number.isFinite(minutePart) ? minutePart : 0;
|
|
48936
|
+
return hour * 60 + minute;
|
|
48937
|
+
};
|
|
48938
|
+
const toShiftUtcMs = (dateKey, timeValue) => {
|
|
48939
|
+
const [yearPart, monthPart, dayPart] = dateKey.split("-").map(Number);
|
|
48940
|
+
const year = Number.isFinite(yearPart) ? yearPart : 1970;
|
|
48941
|
+
const month = Number.isFinite(monthPart) ? monthPart : 1;
|
|
48942
|
+
const day = Number.isFinite(dayPart) ? dayPart : 1;
|
|
48943
|
+
const [hourPart, minutePart] = timeValue.split(":").map(Number);
|
|
48944
|
+
const hour = Number.isFinite(hourPart) ? hourPart : 0;
|
|
48945
|
+
const minute = Number.isFinite(minutePart) ? minutePart : 0;
|
|
48946
|
+
const IST_OFFSET_MINUTES = 330;
|
|
48947
|
+
return Date.UTC(year, month - 1, day, hour, minute) - IST_OFFSET_MINUTES * 60 * 1e3;
|
|
48948
|
+
};
|
|
48949
|
+
const shiftStartMinutes = parseTimeToMinutes3(workspace.shift_start);
|
|
48950
|
+
const shiftEndMinutes = parseTimeToMinutes3(workspace.shift_end);
|
|
48951
|
+
const wrapsMidnight = shiftEndMinutes <= shiftStartMinutes;
|
|
48952
|
+
const shiftStartUtcMs = toShiftUtcMs(workspace.date, workspace.shift_start);
|
|
48953
|
+
const shiftEndUtcMs = toShiftUtcMs(workspace.date, workspace.shift_end) + (wrapsMidnight ? 24 * 60 * 60 * 1e3 : 0);
|
|
48954
|
+
const isShiftInProgress = Date.now() >= shiftStartUtcMs && Date.now() < shiftEndUtcMs;
|
|
48955
|
+
const reportPeriodEndTime = isShiftInProgress ? currentTime : shiftEndTime;
|
|
48564
48956
|
doc.setFontSize(12);
|
|
48565
48957
|
doc.setTextColor(80, 80, 80);
|
|
48566
|
-
doc.text(`Report Period: ${shiftStartTime} - ${
|
|
48958
|
+
doc.text(`Report Period: ${shiftStartTime} - ${reportPeriodEndTime}`, 20, 79);
|
|
48567
48959
|
doc.setTextColor(0, 0, 0);
|
|
48568
48960
|
doc.setDrawColor(180, 180, 180);
|
|
48569
48961
|
doc.setLineWidth(0.8);
|
|
@@ -48577,10 +48969,8 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48577
48969
|
};
|
|
48578
48970
|
const perfOverviewStartY = 93;
|
|
48579
48971
|
const hasIdleTimeReason = idleTimeReasons && idleTimeReasons.length > 0;
|
|
48580
|
-
|
|
48581
|
-
|
|
48582
|
-
perfOverviewHeight = hasIdleTimeReason ? 70 : 60;
|
|
48583
|
-
}
|
|
48972
|
+
const perfOverviewRows = isUptimeMode ? 3 : isAssemblyCycleMode ? 2 : 4;
|
|
48973
|
+
const perfOverviewHeight = 30 + perfOverviewRows * 10 + (hasIdleTimeReason ? 10 : 0);
|
|
48584
48974
|
doc.setFillColor(245, 245, 245);
|
|
48585
48975
|
doc.roundedRect(15, perfOverviewStartY, 180, perfOverviewHeight, 3, 3, "F");
|
|
48586
48976
|
doc.setFontSize(18);
|
|
@@ -48608,6 +48998,19 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48608
48998
|
doc.text("Stoppages:", 25, kpiStartY + kpiSpacing * 2);
|
|
48609
48999
|
doc.setFont("helvetica", "bold");
|
|
48610
49000
|
doc.text(`${workspace.total_actions}`, 120, kpiStartY + kpiSpacing * 2);
|
|
49001
|
+
} else if (isAssemblyCycleMode) {
|
|
49002
|
+
createKPIBox(kpiStartY);
|
|
49003
|
+
doc.setFontSize(11);
|
|
49004
|
+
doc.setFont("helvetica", "normal");
|
|
49005
|
+
doc.text("Average Cycle Time:", 25, kpiStartY);
|
|
49006
|
+
doc.setFont("helvetica", "bold");
|
|
49007
|
+
doc.text(`${(workspace.avg_cycle_time || 0).toFixed(1)}s`, 120, kpiStartY);
|
|
49008
|
+
createKPIBox(kpiStartY + kpiSpacing);
|
|
49009
|
+
doc.setFont("helvetica", "normal");
|
|
49010
|
+
doc.text("Total Idle Time:", 25, kpiStartY + kpiSpacing);
|
|
49011
|
+
doc.setFont("helvetica", "bold");
|
|
49012
|
+
const idleTimeFormatted = formatIdleTime(workspace.idle_time);
|
|
49013
|
+
doc.text(idleTimeFormatted, 120, kpiStartY + kpiSpacing);
|
|
48611
49014
|
} else {
|
|
48612
49015
|
createKPIBox(kpiStartY);
|
|
48613
49016
|
doc.setFontSize(11);
|
|
@@ -48644,17 +49047,11 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48644
49047
|
const reasonText = `${reasonName} (${topReason.value.toFixed(1)}%)`;
|
|
48645
49048
|
doc.text(reasonText, 120, reasonY);
|
|
48646
49049
|
}
|
|
48647
|
-
|
|
48648
|
-
if (isUptimeMode) {
|
|
48649
|
-
separatorBeforeHourlyY -= 10;
|
|
48650
|
-
}
|
|
49050
|
+
const separatorBeforeHourlyY = perfOverviewStartY + perfOverviewHeight + 10;
|
|
48651
49051
|
doc.setDrawColor(180, 180, 180);
|
|
48652
49052
|
doc.setLineWidth(0.8);
|
|
48653
49053
|
doc.line(20, separatorBeforeHourlyY, 190, separatorBeforeHourlyY);
|
|
48654
|
-
|
|
48655
|
-
if (isUptimeMode) {
|
|
48656
|
-
hourlyPerfStartY -= 10;
|
|
48657
|
-
}
|
|
49054
|
+
const hourlyPerfStartY = separatorBeforeHourlyY + 5;
|
|
48658
49055
|
const uptimeSeries = isUptimeMode ? buildUptimeSeries({
|
|
48659
49056
|
idleTimeHourly: workspace.idle_time_hourly,
|
|
48660
49057
|
shiftStart: workspace.shift_start,
|
|
@@ -48672,8 +49069,9 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48672
49069
|
const uptimePercent = total > 0 ? Math.round(activeMinutes / total * 100) : 0;
|
|
48673
49070
|
return { activeMinutes, idleMinutes, uptimePercent };
|
|
48674
49071
|
}) : [];
|
|
48675
|
-
const hourlyData = isUptimeMode ? hourlyUptime : workspace.hourly_action_counts || [];
|
|
49072
|
+
const hourlyData = isUptimeMode ? hourlyUptime : isAssemblyCycleMode ? hourlyCycleTimes && hourlyCycleTimes.length > 0 ? hourlyCycleTimes : workspace.hourly_action_counts || [] : workspace.hourly_action_counts || [];
|
|
48676
49073
|
const hourlyTarget = workspace.pph_threshold;
|
|
49074
|
+
const cycleTarget = workspace.ideal_cycle_time || 0;
|
|
48677
49075
|
const pageHeight = doc.internal.pageSize.height;
|
|
48678
49076
|
const maxContentY = pageHeight - 15;
|
|
48679
49077
|
const baseTableStartY = hourlyPerfStartY + 31;
|
|
@@ -48698,12 +49096,16 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48698
49096
|
doc.setFont("helvetica", "bold");
|
|
48699
49097
|
doc.setTextColor(40, 40, 40);
|
|
48700
49098
|
const hourlyTitleY = hourlyPerfStartY + 10;
|
|
48701
|
-
doc.text(
|
|
49099
|
+
doc.text(
|
|
49100
|
+
isUptimeMode ? "Hourly Utilization" : isAssemblyCycleMode ? "Hourly Cycle Time" : "Hourly Performance",
|
|
49101
|
+
20,
|
|
49102
|
+
hourlyTitleY
|
|
49103
|
+
);
|
|
48702
49104
|
doc.setTextColor(0, 0, 0);
|
|
48703
49105
|
const headerY = titleFontSize === 16 ? hourlyPerfStartY + 18 : hourlyPerfStartY + 20;
|
|
48704
49106
|
const gridTopY = headerY - 5;
|
|
48705
49107
|
const headerBottomY = gridTopY + 8;
|
|
48706
|
-
const colBoundaries = isUptimeMode ? [20, 105, 190] : [20, 70, 100, 130, 155, 190];
|
|
49108
|
+
const colBoundaries = isUptimeMode ? [20, 105, 190] : isAssemblyCycleMode ? [20, 85, 125, 165, 190] : [20, 70, 100, 130, 155, 190];
|
|
48707
49109
|
const totalRows = hourlyData.length;
|
|
48708
49110
|
const gridBottomY = headerBottomY + totalRows * rowHeight;
|
|
48709
49111
|
const tableHeight = gridBottomY - gridTopY;
|
|
@@ -48724,6 +49126,10 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48724
49126
|
doc.text("Time Range", 25, headerTextY);
|
|
48725
49127
|
if (isUptimeMode) {
|
|
48726
49128
|
doc.text("Utilization", 147, headerTextY);
|
|
49129
|
+
} else if (isAssemblyCycleMode) {
|
|
49130
|
+
doc.text("Standard", 90, headerTextY);
|
|
49131
|
+
doc.text("Average", 130, headerTextY);
|
|
49132
|
+
doc.text("Status", 170, headerTextY);
|
|
48727
49133
|
} else {
|
|
48728
49134
|
doc.text("Output", 75, headerTextY);
|
|
48729
49135
|
doc.text("Target", 105, headerTextY);
|
|
@@ -48772,6 +49178,25 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons, efficiency
|
|
|
48772
49178
|
if (isUptimeMode) {
|
|
48773
49179
|
const utilizationStr = dataCollected ? `${uptimePercent}%` : "TBD";
|
|
48774
49180
|
doc.text(utilizationStr, 147, yPos);
|
|
49181
|
+
} else if (isAssemblyCycleMode) {
|
|
49182
|
+
const actualCycleTime = Number(outputValue) || 0;
|
|
49183
|
+
const standardCycleStr = `${cycleTarget.toFixed(1)}s`;
|
|
49184
|
+
const actualCycleStr = dataCollected ? `${actualCycleTime.toFixed(1)}s` : "TBD";
|
|
49185
|
+
doc.text(standardCycleStr, 90, yPos);
|
|
49186
|
+
doc.text(actualCycleStr, 130, yPos);
|
|
49187
|
+
if (!dataCollected) {
|
|
49188
|
+
doc.setTextColor(100, 100, 100);
|
|
49189
|
+
doc.text("-", 170, yPos);
|
|
49190
|
+
} else if (actualCycleTime > 0 && actualCycleTime <= cycleTarget) {
|
|
49191
|
+
doc.setTextColor(0, 171, 69);
|
|
49192
|
+
doc.setFont("ZapfDingbats", "normal");
|
|
49193
|
+
doc.text("4", 170, yPos);
|
|
49194
|
+
doc.setFont("helvetica", "normal");
|
|
49195
|
+
} else {
|
|
49196
|
+
doc.setTextColor(227, 67, 41);
|
|
49197
|
+
doc.text("\xD7", 170, yPos);
|
|
49198
|
+
}
|
|
49199
|
+
doc.setTextColor(0, 0, 0);
|
|
48775
49200
|
} else {
|
|
48776
49201
|
doc.text(outputStr, 75, yPos);
|
|
48777
49202
|
doc.text(targetStr, 105, yPos);
|
|
@@ -48843,7 +49268,8 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
48843
49268
|
shiftConfig,
|
|
48844
49269
|
efficiencyLegend,
|
|
48845
49270
|
className,
|
|
48846
|
-
compact = false
|
|
49271
|
+
compact = false,
|
|
49272
|
+
isAssemblyWorkspace = false
|
|
48847
49273
|
}) => {
|
|
48848
49274
|
const [isGenerating, setIsGenerating] = useState(false);
|
|
48849
49275
|
const effectiveLegend = efficiencyLegend || DEFAULT_EFFICIENCY_LEGEND;
|
|
@@ -48966,6 +49392,7 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
48966
49392
|
avgOutput: filteredShifts.reduce((sum, shift) => sum + shift.output, 0) / filteredShifts.length,
|
|
48967
49393
|
avgCycleTime: filteredShifts.reduce((sum, shift) => sum + shift.cycleTime, 0) / filteredShifts.length,
|
|
48968
49394
|
avgPph: filteredShifts.reduce((sum, shift) => sum + shift.pph, 0) / filteredShifts.length,
|
|
49395
|
+
avgIdleTime: filteredShifts.reduce((sum, shift) => sum + shift.idleTime, 0) / filteredShifts.length,
|
|
48969
49396
|
totalDays: filteredShifts.length,
|
|
48970
49397
|
underperformingDays: filteredShifts.filter((shift) => shift.efficiency < effectiveLegend.green_min).length
|
|
48971
49398
|
} : null;
|
|
@@ -48977,7 +49404,8 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
48977
49404
|
doc.roundedRect(22, y - 7, 165, 12, 2, 2, "S");
|
|
48978
49405
|
};
|
|
48979
49406
|
doc.setFillColor(245, 245, 245);
|
|
48980
|
-
|
|
49407
|
+
const isAssemblyWorkspaceAndNotUptime = !isUptimeMode && isAssemblyWorkspace;
|
|
49408
|
+
doc.roundedRect(15, 95, 180, isAssemblyWorkspaceAndNotUptime ? 40 : 70, 3, 3, "F");
|
|
48981
49409
|
doc.setFontSize(18);
|
|
48982
49410
|
doc.setFont("helvetica", "bold");
|
|
48983
49411
|
doc.setTextColor(40, 40, 40);
|
|
@@ -49016,32 +49444,41 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
49016
49444
|
doc.text(`${uptimeMetrics.underperformingDays} of ${uptimeMetrics.totalDays}`, 120, kpiStartY + kpiSpacing * 4);
|
|
49017
49445
|
} else {
|
|
49018
49446
|
const outputMetrics = monthlyMetrics;
|
|
49019
|
-
|
|
49020
|
-
|
|
49021
|
-
|
|
49022
|
-
|
|
49023
|
-
|
|
49024
|
-
|
|
49025
|
-
|
|
49026
|
-
|
|
49027
|
-
|
|
49028
|
-
|
|
49029
|
-
|
|
49030
|
-
|
|
49031
|
-
|
|
49032
|
-
|
|
49033
|
-
|
|
49034
|
-
|
|
49035
|
-
|
|
49036
|
-
|
|
49037
|
-
|
|
49038
|
-
|
|
49039
|
-
|
|
49040
|
-
|
|
49041
|
-
|
|
49042
|
-
|
|
49043
|
-
|
|
49044
|
-
|
|
49447
|
+
if (!isAssemblyWorkspace) {
|
|
49448
|
+
createKPIBox(kpiStartY);
|
|
49449
|
+
doc.setFontSize(11);
|
|
49450
|
+
doc.setFont("helvetica", "normal");
|
|
49451
|
+
doc.text("Average Efficiency:", 25, kpiStartY);
|
|
49452
|
+
doc.setFont("helvetica", "bold");
|
|
49453
|
+
doc.text(`${outputMetrics.avgEfficiency.toFixed(1)}% (Target: ${Math.round(effectiveLegend.green_min)}%)`, 120, kpiStartY);
|
|
49454
|
+
createKPIBox(kpiStartY + kpiSpacing);
|
|
49455
|
+
doc.setFont("helvetica", "normal");
|
|
49456
|
+
doc.text("Average PPH:", 25, kpiStartY + kpiSpacing);
|
|
49457
|
+
doc.setFont("helvetica", "bold");
|
|
49458
|
+
doc.text(`${outputMetrics.avgPph.toFixed(1)} per hour`, 120, kpiStartY + kpiSpacing);
|
|
49459
|
+
createKPIBox(kpiStartY + kpiSpacing * 2);
|
|
49460
|
+
doc.setFont("helvetica", "normal");
|
|
49461
|
+
doc.text("Working Days:", 25, kpiStartY + kpiSpacing * 2);
|
|
49462
|
+
doc.setFont("helvetica", "bold");
|
|
49463
|
+
doc.text(`${outputMetrics.totalDays} days`, 120, kpiStartY + kpiSpacing * 2);
|
|
49464
|
+
createKPIBox(kpiStartY + kpiSpacing * 3);
|
|
49465
|
+
doc.setFont("helvetica", "normal");
|
|
49466
|
+
doc.text("Underperforming Days:", 25, kpiStartY + kpiSpacing * 3);
|
|
49467
|
+
doc.setFont("helvetica", "bold");
|
|
49468
|
+
doc.text(`${outputMetrics.underperformingDays} of ${outputMetrics.totalDays}`, 120, kpiStartY + kpiSpacing * 3);
|
|
49469
|
+
} else {
|
|
49470
|
+
createKPIBox(kpiStartY);
|
|
49471
|
+
doc.setFontSize(11);
|
|
49472
|
+
doc.setFont("helvetica", "normal");
|
|
49473
|
+
doc.text("Average Cycle Time:", 25, kpiStartY);
|
|
49474
|
+
doc.setFont("helvetica", "bold");
|
|
49475
|
+
doc.text(`${Math.round(outputMetrics.avgCycleTime)}s`, 120, kpiStartY);
|
|
49476
|
+
createKPIBox(kpiStartY + kpiSpacing);
|
|
49477
|
+
doc.setFont("helvetica", "normal");
|
|
49478
|
+
doc.text("Average Idle Time:", 25, kpiStartY + kpiSpacing);
|
|
49479
|
+
doc.setFont("helvetica", "bold");
|
|
49480
|
+
doc.text(formatIdleTime(outputMetrics.avgIdleTime ?? 0), 120, kpiStartY + kpiSpacing);
|
|
49481
|
+
}
|
|
49045
49482
|
}
|
|
49046
49483
|
} else {
|
|
49047
49484
|
doc.setFontSize(12);
|
|
@@ -49052,29 +49489,33 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
49052
49489
|
}
|
|
49053
49490
|
doc.setDrawColor(180, 180, 180);
|
|
49054
49491
|
doc.setLineWidth(0.8);
|
|
49055
|
-
|
|
49492
|
+
const separatorY = isAssemblyWorkspaceAndNotUptime ? 150 : 180;
|
|
49493
|
+
doc.line(20, separatorY, 190, separatorY);
|
|
49056
49494
|
doc.setFillColor(245, 245, 245);
|
|
49057
|
-
|
|
49495
|
+
const dailySectionY = isAssemblyWorkspaceAndNotUptime ? 155 : 185;
|
|
49496
|
+
doc.roundedRect(15, dailySectionY, 180, 85, 3, 3, "F");
|
|
49058
49497
|
doc.setFontSize(18);
|
|
49059
49498
|
doc.setFont("helvetica", "bold");
|
|
49060
49499
|
doc.setTextColor(40, 40, 40);
|
|
49061
|
-
doc.text(isUptimeMode ? "Daily Utilization Summary" : "Daily Performance Summary", 20,
|
|
49500
|
+
doc.text(isUptimeMode ? "Daily Utilization Summary" : "Daily Performance Summary", 20, dailySectionY + 10);
|
|
49062
49501
|
doc.setTextColor(0, 0, 0);
|
|
49063
49502
|
if (validDays.length > 0) {
|
|
49064
49503
|
doc.setFontSize(10);
|
|
49065
49504
|
doc.setFont("helvetica", "bold");
|
|
49066
49505
|
doc.setFillColor(240, 240, 240);
|
|
49067
|
-
|
|
49068
|
-
doc.
|
|
49069
|
-
|
|
49070
|
-
doc.text(
|
|
49071
|
-
doc.text(isUptimeMode ? "
|
|
49072
|
-
doc.text("
|
|
49506
|
+
const tableHeaderY = dailySectionY + 15;
|
|
49507
|
+
doc.roundedRect(20, tableHeaderY, 170, 7, 1, 1, "F");
|
|
49508
|
+
const textY = tableHeaderY + 5;
|
|
49509
|
+
doc.text("Date", 25, textY);
|
|
49510
|
+
doc.text(isUptimeMode ? "Productive" : isAssemblyWorkspace ? "Cycle Time" : "Actual", 60, textY);
|
|
49511
|
+
doc.text(isUptimeMode ? "Idle" : isAssemblyWorkspace ? "Target CT" : "Standard", 95, textY);
|
|
49512
|
+
doc.text(isUptimeMode ? "Utilization" : "Efficiency", 135, textY);
|
|
49513
|
+
doc.text("Status", 170, textY);
|
|
49073
49514
|
doc.setLineWidth(0.2);
|
|
49074
49515
|
doc.setDrawColor(220, 220, 220);
|
|
49075
|
-
doc.line(20,
|
|
49516
|
+
doc.line(20, textY + 3, 190, textY + 3);
|
|
49076
49517
|
doc.setFont("helvetica", "normal");
|
|
49077
|
-
let yPos =
|
|
49518
|
+
let yPos = textY + 10;
|
|
49078
49519
|
const recentDays = validDays.slice(-10).reverse();
|
|
49079
49520
|
recentDays.forEach((dayData, index) => {
|
|
49080
49521
|
if (yPos > 260) return;
|
|
@@ -49108,8 +49549,13 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
49108
49549
|
}
|
|
49109
49550
|
doc.setTextColor(0, 0, 0);
|
|
49110
49551
|
} else {
|
|
49111
|
-
|
|
49112
|
-
|
|
49552
|
+
if (isAssemblyWorkspace) {
|
|
49553
|
+
doc.text(`${shift.cycleTime.toFixed(1)}`, 60, yPos);
|
|
49554
|
+
doc.text(`${shift.pphThreshold > 0 ? (3600 / shift.pphThreshold).toFixed(1) : "-"}`, 95, yPos);
|
|
49555
|
+
} else {
|
|
49556
|
+
doc.text(`${shift.output}`, 60, yPos);
|
|
49557
|
+
doc.text(`${shift.targetOutput}`, 95, yPos);
|
|
49558
|
+
}
|
|
49113
49559
|
doc.text(`${shift.efficiency.toFixed(1)}%`, 135, yPos);
|
|
49114
49560
|
if (shift.efficiency >= effectiveLegend.green_min) {
|
|
49115
49561
|
doc.setTextColor(0, 171, 69);
|
|
@@ -49124,12 +49570,12 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
49124
49570
|
});
|
|
49125
49571
|
doc.setLineWidth(0.2);
|
|
49126
49572
|
doc.setDrawColor(220, 220, 220);
|
|
49127
|
-
doc.roundedRect(20,
|
|
49573
|
+
doc.roundedRect(20, tableHeaderY, 170, yPos - tableHeaderY - 3, 1, 1, "S");
|
|
49128
49574
|
} else {
|
|
49129
49575
|
doc.setFontSize(12);
|
|
49130
49576
|
doc.setFont("helvetica", "normal");
|
|
49131
49577
|
doc.setTextColor(100, 100, 100);
|
|
49132
|
-
doc.text("No daily data available for this month", 25,
|
|
49578
|
+
doc.text("No daily data available for this month", 25, dailySectionY + 30);
|
|
49133
49579
|
doc.setTextColor(0, 0, 0);
|
|
49134
49580
|
}
|
|
49135
49581
|
doc.setFontSize(9);
|
|
@@ -49162,46 +49608,64 @@ var WorkspaceCycleTimeMetricCards = ({
|
|
|
49162
49608
|
workspace,
|
|
49163
49609
|
className,
|
|
49164
49610
|
legend,
|
|
49165
|
-
layout: layout2 = "grid"
|
|
49611
|
+
layout: layout2 = "grid",
|
|
49612
|
+
isAssemblyWorkspace = false,
|
|
49613
|
+
idleTimeData
|
|
49166
49614
|
}) => {
|
|
49167
49615
|
const effectiveLegend = legend || DEFAULT_EFFICIENCY_LEGEND;
|
|
49168
49616
|
const efficiencyValue = workspace.avg_efficiency || 0;
|
|
49169
49617
|
const efficiencyTarget = effectiveLegend.green_min;
|
|
49170
49618
|
const efficiencyColor = getEfficiencyHexColor(efficiencyValue, effectiveLegend);
|
|
49171
|
-
const hideEfficiencyCard = shouldHideWorkspaceEfficiencyCard(workspace);
|
|
49172
|
-
const
|
|
49619
|
+
const hideEfficiencyCard = isAssemblyWorkspace || shouldHideWorkspaceEfficiencyCard(workspace);
|
|
49620
|
+
const totalCards = 2 + (hideEfficiencyCard ? 0 : 1) + (idleTimeData ? 1 : 0);
|
|
49621
|
+
let gridColsClass = "lg:grid-cols-3";
|
|
49622
|
+
if (totalCards === 4) gridColsClass = "lg:grid-cols-4";
|
|
49623
|
+
else if (totalCards === 2) gridColsClass = "lg:grid-cols-2";
|
|
49624
|
+
const containerClassName = layout2 === "stack" ? `space-y-4 ${className || ""}` : `grid grid-cols-1 gap-4 sm:gap-3 sm:grid-cols-2 ${gridColsClass} w-full h-full min-h-0 ${className || ""}`;
|
|
49173
49625
|
return /* @__PURE__ */ jsxs("div", { className: containerClassName, children: [
|
|
49174
|
-
!hideEfficiencyCard && /* @__PURE__ */ jsxs(Card2, { children: [
|
|
49175
|
-
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-
|
|
49176
|
-
/* @__PURE__ */
|
|
49177
|
-
/* @__PURE__ */ jsxs("p", { className: "text-5xl font-bold", style: { color: efficiencyColor }, children: [
|
|
49626
|
+
!hideEfficiencyCard && /* @__PURE__ */ jsxs(Card2, { className: "flex flex-col bg-white shadow-sm border border-gray-200 h-full min-h-[150px] sm:min-h-0 rounded-xl", children: [
|
|
49627
|
+
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-1 pt-5 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-[15px] font-bold text-center text-gray-900 tracking-wide", children: "Efficiency" }) }),
|
|
49628
|
+
/* @__PURE__ */ jsxs(CardContent2, { className: "flex-1 flex flex-col items-center justify-center pb-6", children: [
|
|
49629
|
+
/* @__PURE__ */ jsxs("p", { className: "text-5xl font-bold tracking-tight", style: { color: efficiencyColor }, children: [
|
|
49178
49630
|
efficiencyValue.toFixed(1),
|
|
49179
49631
|
"%"
|
|
49180
49632
|
] }),
|
|
49181
|
-
/* @__PURE__ */ jsxs("p", { className: "text-
|
|
49633
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 mt-1 font-medium tracking-wide", children: [
|
|
49182
49634
|
"Target: ",
|
|
49183
49635
|
Math.round(efficiencyTarget),
|
|
49184
49636
|
"%"
|
|
49185
49637
|
] })
|
|
49186
|
-
] })
|
|
49638
|
+
] })
|
|
49187
49639
|
] }),
|
|
49188
|
-
/* @__PURE__ */ jsxs(Card2, { children: [
|
|
49189
|
-
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-
|
|
49190
|
-
/* @__PURE__ */
|
|
49191
|
-
/* @__PURE__ */ jsx("p", { className: `text-5xl font-bold ${workspace.avg_cycle_time > (workspace.ideal_cycle_time || 0) ? "text-red-500" : "text-
|
|
49192
|
-
/* @__PURE__ */ jsxs("p", { className: "text-
|
|
49640
|
+
/* @__PURE__ */ jsxs(Card2, { className: "flex flex-col bg-white shadow-sm border border-gray-200 h-full min-h-[150px] sm:min-h-0 rounded-xl", children: [
|
|
49641
|
+
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-1 pt-5 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-[15px] font-bold text-center text-gray-900 tracking-wide", children: "Cycle Time (s)" }) }),
|
|
49642
|
+
/* @__PURE__ */ jsxs(CardContent2, { className: "flex-1 flex flex-col items-center justify-center pb-6", children: [
|
|
49643
|
+
/* @__PURE__ */ jsx("p", { className: `text-5xl font-bold tracking-tight ${workspace.avg_cycle_time > (workspace.ideal_cycle_time || 0) ? "text-red-500" : "text-[#34C759]"}`, children: workspace.avg_cycle_time.toFixed(1) }),
|
|
49644
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 mt-1 font-medium tracking-wide", children: [
|
|
49193
49645
|
"Standard: ",
|
|
49194
49646
|
workspace.ideal_cycle_time?.toFixed(1) || 0,
|
|
49195
49647
|
"s"
|
|
49196
49648
|
] })
|
|
49197
|
-
] })
|
|
49649
|
+
] })
|
|
49198
49650
|
] }),
|
|
49199
|
-
/* @__PURE__ */ jsxs(Card2, { children: [
|
|
49200
|
-
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-
|
|
49201
|
-
/* @__PURE__ */
|
|
49202
|
-
/* @__PURE__ */ jsx("p", { className: `text-
|
|
49203
|
-
/* @__PURE__ */ jsx("p", { className: "text-
|
|
49204
|
-
] })
|
|
49651
|
+
/* @__PURE__ */ jsxs(Card2, { className: "flex flex-col bg-white shadow-sm border border-gray-200 h-full min-h-[150px] sm:min-h-0 rounded-xl", children: [
|
|
49652
|
+
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-1 pt-5 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-[15px] font-bold text-center text-gray-900 tracking-wide", children: "Idle Time" }) }),
|
|
49653
|
+
/* @__PURE__ */ jsxs(CardContent2, { className: "flex-1 flex flex-col items-center justify-center pb-6", children: [
|
|
49654
|
+
/* @__PURE__ */ jsx("p", { className: `text-5xl font-bold tracking-tight ${!workspace.idle_time || workspace.idle_time <= 0 ? "text-[#34C759]" : workspace.idle_time <= 300 ? "text-yellow-500" : "text-red-500"}`, children: formatIdleTime(workspace.idle_time) }),
|
|
49655
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 mt-1 font-medium tracking-wide", children: "Total idle time" })
|
|
49656
|
+
] })
|
|
49657
|
+
] }),
|
|
49658
|
+
idleTimeData && /* @__PURE__ */ jsxs(Card2, { className: "flex flex-col bg-white shadow-sm border border-gray-200 h-full min-h-[150px] sm:min-h-0 rounded-xl", children: [
|
|
49659
|
+
/* @__PURE__ */ jsx(CardHeader2, { className: "pb-1 pt-5 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-[15px] font-bold text-center text-gray-900 tracking-wide", children: "Idle Time Breakdown" }) }),
|
|
49660
|
+
/* @__PURE__ */ jsx(CardContent2, { className: "flex-1 p-2 flex items-center justify-center h-full sm:h-auto min-h-[120px] sm:min-h-[100px]", children: /* @__PURE__ */ jsx(
|
|
49661
|
+
IdleTimeReasonChart,
|
|
49662
|
+
{
|
|
49663
|
+
data: idleTimeData.chartData,
|
|
49664
|
+
isLoading: idleTimeData.isLoading,
|
|
49665
|
+
error: idleTimeData.error,
|
|
49666
|
+
variant: "bar"
|
|
49667
|
+
}
|
|
49668
|
+
) })
|
|
49205
49669
|
] })
|
|
49206
49670
|
] });
|
|
49207
49671
|
};
|
|
@@ -49339,13 +49803,13 @@ var getWorkspaceStyles = (position, isPlaceholder = false) => {
|
|
|
49339
49803
|
${isPlaceholder ? "cursor-default" : ""}`;
|
|
49340
49804
|
};
|
|
49341
49805
|
var formatPercentRange = (min, max) => {
|
|
49342
|
-
const
|
|
49806
|
+
const format9 = (value) => Number.isInteger(value) ? `${value}` : value.toFixed(1);
|
|
49343
49807
|
if (min >= 100 || max >= 100) {
|
|
49344
|
-
return `${
|
|
49808
|
+
return `${format9(min)}+%`;
|
|
49345
49809
|
}
|
|
49346
|
-
return `${
|
|
49810
|
+
return `${format9(min)}-${format9(max)}%`;
|
|
49347
49811
|
};
|
|
49348
|
-
var
|
|
49812
|
+
var Legend5 = ({
|
|
49349
49813
|
useBottleneckLabel = false,
|
|
49350
49814
|
legend,
|
|
49351
49815
|
metricLabel = "Efficiency"
|
|
@@ -49531,7 +49995,7 @@ var WorkspaceGrid = React141__default.memo(({
|
|
|
49531
49995
|
return /* @__PURE__ */ jsxs("div", { className: `relative w-full h-full overflow-hidden ${className}`, children: [
|
|
49532
49996
|
/* @__PURE__ */ jsxs("div", { className: "absolute top-0 left-2 sm:left-4 right-2 sm:right-8 z-20", children: [
|
|
49533
49997
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-between py-1 sm:py-1.5 gap-2", children: [
|
|
49534
|
-
/* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsx(
|
|
49998
|
+
/* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsx(Legend5, { legend, useBottleneckLabel: hasFlowBuffers, metricLabel: legendMetricLabel }) }),
|
|
49535
49999
|
mapViewEnabled && /* @__PURE__ */ jsx(
|
|
49536
50000
|
"button",
|
|
49537
50001
|
{
|
|
@@ -49548,7 +50012,7 @@ var WorkspaceGrid = React141__default.memo(({
|
|
|
49548
50012
|
}
|
|
49549
50013
|
)
|
|
49550
50014
|
] }),
|
|
49551
|
-
/* @__PURE__ */ jsx("div", { className: "sm:hidden mt-1 mr-32", children: /* @__PURE__ */ jsx(
|
|
50015
|
+
/* @__PURE__ */ jsx("div", { className: "sm:hidden mt-1 mr-32", children: /* @__PURE__ */ jsx(Legend5, { legend, useBottleneckLabel: hasFlowBuffers, metricLabel: legendMetricLabel }) })
|
|
49552
50016
|
] }),
|
|
49553
50017
|
/* @__PURE__ */ jsx("div", { className: "absolute top-14 sm:top-16 left-0 right-0 bottom-0", children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: viewMode === "video" ? /* @__PURE__ */ jsx(
|
|
49554
50018
|
motion.div,
|
|
@@ -50059,7 +50523,7 @@ var KPISection = memo$1(({
|
|
|
50059
50523
|
value: showSkeleton ? "" : kpis.efficiency.value,
|
|
50060
50524
|
change: effChange,
|
|
50061
50525
|
trend: effTrend,
|
|
50062
|
-
trendLabel: "
|
|
50526
|
+
trendLabel: "vs yesterday",
|
|
50063
50527
|
trendMode: "pill",
|
|
50064
50528
|
suffix: "%",
|
|
50065
50529
|
showZeroChange: true,
|
|
@@ -52295,7 +52759,7 @@ var SideNavBar = memo$1(({
|
|
|
52295
52759
|
setIsAlertsOpen(willOpen);
|
|
52296
52760
|
setIsSettingsOpen(false);
|
|
52297
52761
|
if (willOpen) {
|
|
52298
|
-
trackCoreEvent("Alerts
|
|
52762
|
+
trackCoreEvent("Alerts page clicked", { source: "side_nav" });
|
|
52299
52763
|
void refreshAlertsSummary();
|
|
52300
52764
|
}
|
|
52301
52765
|
},
|
|
@@ -52450,7 +52914,7 @@ var SideNavBar = memo$1(({
|
|
|
52450
52914
|
{
|
|
52451
52915
|
onClick: () => {
|
|
52452
52916
|
setIsAlertsOpen(true);
|
|
52453
|
-
trackCoreEvent("Alerts
|
|
52917
|
+
trackCoreEvent("Alerts page clicked", { source: "side_nav_mobile" });
|
|
52454
52918
|
void refreshAlertsSummary();
|
|
52455
52919
|
onMobileMenuClose?.();
|
|
52456
52920
|
},
|
|
@@ -59660,7 +60124,8 @@ var MonthlyRangeFilter = ({
|
|
|
59660
60124
|
onMonthNavigate,
|
|
59661
60125
|
className,
|
|
59662
60126
|
variant = "default",
|
|
59663
|
-
showLabel = true
|
|
60127
|
+
showLabel = true,
|
|
60128
|
+
singleDateOnly = false
|
|
59664
60129
|
}) => {
|
|
59665
60130
|
const todayKey = useMemo(
|
|
59666
60131
|
() => formatInTimeZone(/* @__PURE__ */ new Date(), timezone || "UTC", "yyyy-MM-dd"),
|
|
@@ -59748,6 +60213,12 @@ var MonthlyRangeFilter = ({
|
|
|
59748
60213
|
}
|
|
59749
60214
|
setActivePreset("Custom");
|
|
59750
60215
|
setPendingChangeMeta({ source: "custom" });
|
|
60216
|
+
if (singleDateOnly) {
|
|
60217
|
+
setRangeStart(day);
|
|
60218
|
+
setRangeEnd(day);
|
|
60219
|
+
setSelecting(false);
|
|
60220
|
+
return;
|
|
60221
|
+
}
|
|
59751
60222
|
if (!selecting || !rangeStart) {
|
|
59752
60223
|
setRangeStart(day);
|
|
59753
60224
|
setRangeEnd(null);
|
|
@@ -59782,6 +60253,13 @@ var MonthlyRangeFilter = ({
|
|
|
59782
60253
|
};
|
|
59783
60254
|
const handleApply = () => {
|
|
59784
60255
|
if (rangeStart) {
|
|
60256
|
+
if (singleDateOnly) {
|
|
60257
|
+
const selected = startOfDay(rangeStart) > startOfDay(today) ? startOfDay(today) : startOfDay(rangeStart);
|
|
60258
|
+
const dateKey = format(selected, "yyyy-MM-dd");
|
|
60259
|
+
onChange({ startKey: dateKey, endKey: dateKey }, pendingChangeMeta || { source: "custom" });
|
|
60260
|
+
setIsOpen(false);
|
|
60261
|
+
return;
|
|
60262
|
+
}
|
|
59785
60263
|
const boundedStart = startOfDay(rangeStart) > startOfDay(today) ? startOfDay(today) : startOfDay(rangeStart);
|
|
59786
60264
|
const candidateEnd = rangeEnd || rangeStart;
|
|
59787
60265
|
const boundedEnd = startOfDay(candidateEnd) > startOfDay(today) ? startOfDay(today) : startOfDay(candidateEnd);
|
|
@@ -59876,7 +60354,7 @@ var MonthlyRangeFilter = ({
|
|
|
59876
60354
|
"overflow-hidden bg-white animate-in fade-in zoom-in-95 duration-200 flex",
|
|
59877
60355
|
isInline ? "relative mt-2 w-full rounded-xl border border-gray-200" : "absolute right-0 z-50 mt-2 w-[520px] rounded-xl border border-gray-100 shadow-2xl"
|
|
59878
60356
|
), children: [
|
|
59879
|
-
/* @__PURE__ */ jsxs("div", { className: "w-40 bg-
|
|
60357
|
+
!singleDateOnly && /* @__PURE__ */ jsxs("div", { className: "w-40 bg-gray-50 border-r border-gray-100 p-4 flex flex-col justify-between", children: [
|
|
59880
60358
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
59881
60359
|
presets.map((preset) => /* @__PURE__ */ jsx(
|
|
59882
60360
|
"button",
|
|
@@ -59885,7 +60363,7 @@ var MonthlyRangeFilter = ({
|
|
|
59885
60363
|
onClick: () => handlePresetClick(preset),
|
|
59886
60364
|
className: clsx(
|
|
59887
60365
|
"w-full text-left px-3 py-2 text-sm rounded-lg transition-all duration-200",
|
|
59888
|
-
activePreset === preset.label ? "bg-
|
|
60366
|
+
activePreset === preset.label ? "bg-blue-50 text-blue-600 font-semibold" : "text-gray-600 hover:bg-gray-100/80"
|
|
59889
60367
|
),
|
|
59890
60368
|
children: preset.label
|
|
59891
60369
|
},
|
|
@@ -59898,7 +60376,7 @@ var MonthlyRangeFilter = ({
|
|
|
59898
60376
|
onClick: () => setActivePreset("Custom"),
|
|
59899
60377
|
className: clsx(
|
|
59900
60378
|
"w-full text-left px-3 py-2 text-sm rounded-lg transition-all duration-200",
|
|
59901
|
-
activePreset === "Custom" ? "bg-
|
|
60379
|
+
activePreset === "Custom" ? "bg-blue-50 text-blue-600 font-semibold" : "text-gray-600 hover:bg-gray-100/80"
|
|
59902
60380
|
),
|
|
59903
60381
|
children: "Custom"
|
|
59904
60382
|
}
|
|
@@ -59920,7 +60398,7 @@ var MonthlyRangeFilter = ({
|
|
|
59920
60398
|
type: "button",
|
|
59921
60399
|
onClick: handleApply,
|
|
59922
60400
|
disabled: !rangeStart,
|
|
59923
|
-
className: "w-full py-2.5 bg-
|
|
60401
|
+
className: "w-full py-2.5 bg-blue-600 text-white text-sm font-semibold rounded-lg hover:bg-blue-700 transition-all disabled:opacity-50 disabled:cursor-not-allowed",
|
|
59924
60402
|
children: "Apply"
|
|
59925
60403
|
}
|
|
59926
60404
|
)
|
|
@@ -59970,9 +60448,9 @@ var MonthlyRangeFilter = ({
|
|
|
59970
60448
|
const dayNum = day.getDate();
|
|
59971
60449
|
const isFutureDay = startOfDay(day) > startOfDay(today);
|
|
59972
60450
|
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
59973
|
-
inRange && !isStart && !isEnd && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 -inset-x-0.5 bg-
|
|
59974
|
-
inRange && isStart && !isSingleDaySelection && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 right-0 left-1/2 bg-
|
|
59975
|
-
inRange && isEnd && !isSingleDaySelection && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 right-1/2 bg-
|
|
60451
|
+
inRange && !isStart && !isEnd && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 -inset-x-0.5 bg-blue-50 z-0" }),
|
|
60452
|
+
inRange && isStart && !isSingleDaySelection && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 right-0 left-1/2 bg-blue-50 z-0" }),
|
|
60453
|
+
inRange && isEnd && !isSingleDaySelection && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 right-1/2 bg-blue-50 z-0" }),
|
|
59976
60454
|
/* @__PURE__ */ jsx(
|
|
59977
60455
|
"button",
|
|
59978
60456
|
{
|
|
@@ -59981,19 +60459,47 @@ var MonthlyRangeFilter = ({
|
|
|
59981
60459
|
disabled: isFutureDay,
|
|
59982
60460
|
className: clsx(
|
|
59983
60461
|
"h-10 w-full flex items-center justify-center text-sm font-semibold transition-all duration-150 relative z-10",
|
|
59984
|
-
|
|
60462
|
+
// Future day NOT in range
|
|
60463
|
+
isFutureDay && !inRange && "text-gray-300 cursor-not-allowed",
|
|
59985
60464
|
// Not in range
|
|
59986
|
-
!isFutureDay && !inRange && "text-gray-700 hover:bg-gray-
|
|
60465
|
+
!isFutureDay && !inRange && "text-gray-700 hover:bg-gray-100 rounded-lg",
|
|
59987
60466
|
// Middle of range
|
|
59988
|
-
inRange && !isStart && !isEnd &&
|
|
60467
|
+
inRange && !isStart && !isEnd && clsx(
|
|
60468
|
+
"text-blue-600",
|
|
60469
|
+
isFutureDay && "cursor-not-allowed opacity-60"
|
|
60470
|
+
),
|
|
59989
60471
|
// Start/End of range or Single selection
|
|
59990
|
-
(isStart || isEnd) &&
|
|
60472
|
+
(isStart || isEnd) && clsx(
|
|
60473
|
+
"bg-blue-600 text-white rounded-lg shadow-sm",
|
|
60474
|
+
isFutureDay && "cursor-not-allowed opacity-80"
|
|
60475
|
+
)
|
|
59991
60476
|
),
|
|
59992
60477
|
children: dayNum
|
|
59993
60478
|
}
|
|
59994
60479
|
)
|
|
59995
60480
|
] }, day.toISOString());
|
|
59996
|
-
}) })
|
|
60481
|
+
}) }),
|
|
60482
|
+
singleDateOnly && /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-center justify-end gap-2 border-t border-gray-100 pt-3", children: [
|
|
60483
|
+
/* @__PURE__ */ jsx(
|
|
60484
|
+
"button",
|
|
60485
|
+
{
|
|
60486
|
+
type: "button",
|
|
60487
|
+
onClick: handleReset,
|
|
60488
|
+
className: "px-3 py-1.5 text-sm font-medium text-gray-500 hover:text-gray-700 transition-colors",
|
|
60489
|
+
children: "Reset"
|
|
60490
|
+
}
|
|
60491
|
+
),
|
|
60492
|
+
/* @__PURE__ */ jsx(
|
|
60493
|
+
"button",
|
|
60494
|
+
{
|
|
60495
|
+
type: "button",
|
|
60496
|
+
onClick: handleApply,
|
|
60497
|
+
disabled: !rangeStart,
|
|
60498
|
+
className: "px-4 py-1.5 bg-blue-600 text-white text-sm font-semibold rounded-lg hover:bg-blue-700 transition-all disabled:opacity-50 disabled:cursor-not-allowed",
|
|
60499
|
+
children: "Apply"
|
|
60500
|
+
}
|
|
60501
|
+
)
|
|
60502
|
+
] })
|
|
59997
60503
|
] })
|
|
59998
60504
|
] })
|
|
59999
60505
|
] });
|
|
@@ -61770,7 +62276,36 @@ var getMonthDateInfo = (timezone) => {
|
|
|
61770
62276
|
const monthEndDate = fromZonedTime(`${monthEndKey}T23:59:59`, timezone);
|
|
61771
62277
|
return { startDate, endDate, monthEndDate };
|
|
61772
62278
|
};
|
|
61773
|
-
var
|
|
62279
|
+
var createKpisOverviewUrl = ({
|
|
62280
|
+
tab,
|
|
62281
|
+
date,
|
|
62282
|
+
shift
|
|
62283
|
+
}) => {
|
|
62284
|
+
const params = new URLSearchParams();
|
|
62285
|
+
if (tab) {
|
|
62286
|
+
params.set("tab", tab);
|
|
62287
|
+
}
|
|
62288
|
+
if (date) {
|
|
62289
|
+
params.set("date", date);
|
|
62290
|
+
}
|
|
62291
|
+
if (typeof shift === "number" && Number.isFinite(shift)) {
|
|
62292
|
+
params.set("shift", shift.toString());
|
|
62293
|
+
}
|
|
62294
|
+
const queryString = params.toString();
|
|
62295
|
+
return queryString ? `/kpis?${queryString}` : "/kpis";
|
|
62296
|
+
};
|
|
62297
|
+
var getZonedDateAtMidday = (dateKey, timezone) => fromZonedTime(`${dateKey}T12:00:00`, timezone);
|
|
62298
|
+
var formatDateKey = (dateKey, timezone, options) => {
|
|
62299
|
+
try {
|
|
62300
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
62301
|
+
...options,
|
|
62302
|
+
timeZone: timezone
|
|
62303
|
+
}).format(getZonedDateAtMidday(dateKey, timezone));
|
|
62304
|
+
} catch {
|
|
62305
|
+
return dateKey;
|
|
62306
|
+
}
|
|
62307
|
+
};
|
|
62308
|
+
var LeaderboardCountdown = ({ targetDate, format: format9, finishedLabel = "Finished", placeholder = "--", onFinished }) => {
|
|
61774
62309
|
const [time2, setTime] = useState("");
|
|
61775
62310
|
const hasFinishedRef = useRef(false);
|
|
61776
62311
|
useEffect(() => {
|
|
@@ -61792,7 +62327,7 @@ var LeaderboardCountdown = ({ targetDate, format: format8, finishedLabel = "Fini
|
|
|
61792
62327
|
}
|
|
61793
62328
|
return;
|
|
61794
62329
|
}
|
|
61795
|
-
if (
|
|
62330
|
+
if (format9 === "days") {
|
|
61796
62331
|
const days = Math.floor(diff / (1e3 * 60 * 60 * 24));
|
|
61797
62332
|
const hours = Math.floor(diff % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60));
|
|
61798
62333
|
setTime(`${days} days ${hours} hours`);
|
|
@@ -61807,7 +62342,7 @@ var LeaderboardCountdown = ({ targetDate, format: format8, finishedLabel = "Fini
|
|
|
61807
62342
|
tick();
|
|
61808
62343
|
const interval = setInterval(tick, 1e3);
|
|
61809
62344
|
return () => clearInterval(interval);
|
|
61810
|
-
}, [targetDate,
|
|
62345
|
+
}, [targetDate, format9, finishedLabel, placeholder, onFinished]);
|
|
61811
62346
|
return /* @__PURE__ */ jsx(Fragment, { children: time2 });
|
|
61812
62347
|
};
|
|
61813
62348
|
var LinesLeaderboard = ({
|
|
@@ -61825,7 +62360,9 @@ var LinesLeaderboard = ({
|
|
|
61825
62360
|
shiftEndDate,
|
|
61826
62361
|
monthEndDate,
|
|
61827
62362
|
viewType,
|
|
61828
|
-
setViewType
|
|
62363
|
+
setViewType,
|
|
62364
|
+
timezone: _timezone,
|
|
62365
|
+
isHistoricalDaily
|
|
61829
62366
|
}) => {
|
|
61830
62367
|
const formatEfficiency = (value) => typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "--";
|
|
61831
62368
|
const assignedLineIdSet = React141__default.useMemo(
|
|
@@ -61918,10 +62455,10 @@ var LinesLeaderboard = ({
|
|
|
61918
62455
|
}
|
|
61919
62456
|
}, [timeRange, leaderboardData, isLoadingToday, isLoadingMonthly]);
|
|
61920
62457
|
const topThree = leaderboardData.slice(0, 3);
|
|
61921
|
-
leaderboardData.slice(3);
|
|
61922
62458
|
const countdownTarget = timeRange === "monthly" ? monthEndDate : shiftEndDate;
|
|
61923
62459
|
const countdownFormat = timeRange === "monthly" ? "days" : "clock";
|
|
61924
62460
|
const countdownFinishedLabel = timeRange === "monthly" ? "Finished" : "Shift Ended";
|
|
62461
|
+
const showCountdown = timeRange === "monthly" || !isHistoricalDaily;
|
|
61925
62462
|
const handleCountdownFinished = React141__default.useCallback(() => {
|
|
61926
62463
|
trackCoreEvent("Leaderboard Countdown Finished", {
|
|
61927
62464
|
countdown_type: timeRange === "monthly" ? "month_end" : "shift_end",
|
|
@@ -61995,7 +62532,7 @@ var LinesLeaderboard = ({
|
|
|
61995
62532
|
}
|
|
61996
62533
|
)
|
|
61997
62534
|
] }),
|
|
61998
|
-
/* @__PURE__ */ jsx("div", { className: "md:absolute md:right-0 md:top-1/2 md:-translate-y-1/2 flex items-center gap-
|
|
62535
|
+
/* @__PURE__ */ jsx("div", { className: "md:absolute md:right-0 md:top-1/2 md:-translate-y-1/2 flex flex-wrap items-center justify-center md:justify-end gap-2", children: showCountdown && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 px-4 py-2 bg-white rounded-full shadow-sm border border-gray-100", children: [
|
|
61999
62536
|
/* @__PURE__ */ jsx(Clock, { className: "w-4 h-4 text-orange-500" }),
|
|
62000
62537
|
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
|
|
62001
62538
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider", children: "Ends in" }),
|
|
@@ -62116,7 +62653,7 @@ var LinesLeaderboard = ({
|
|
|
62116
62653
|
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-900", children: item.supervisorName })
|
|
62117
62654
|
] }) }),
|
|
62118
62655
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 whitespace-nowrap text-sm text-gray-500", children: item.line.line_name }),
|
|
62119
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 whitespace-nowrap text-right", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col items-end", children: /* @__PURE__ */ jsx("span", { className: "text-sm font-
|
|
62656
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 whitespace-nowrap text-right", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col items-end", children: /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-gray-900", children: formatEfficiency(item.efficiency) }) }) })
|
|
62120
62657
|
]
|
|
62121
62658
|
},
|
|
62122
62659
|
item.id
|
|
@@ -62290,6 +62827,9 @@ var KPIsOverviewView = ({
|
|
|
62290
62827
|
const [activeTab, setActiveTab] = useState("today");
|
|
62291
62828
|
const [timeRange, setTimeRange] = useState("today");
|
|
62292
62829
|
const [viewType, setViewType] = useState("operator");
|
|
62830
|
+
const [selectedLeaderboardDate, setSelectedLeaderboardDate] = useState("");
|
|
62831
|
+
const [selectedLeaderboardShiftId, setSelectedLeaderboardShiftId] = useState(0);
|
|
62832
|
+
const [hasHydratedLeaderboardRouteState, setHasHydratedLeaderboardRouteState] = useState(false);
|
|
62293
62833
|
const [loading, setLoading] = useState(true);
|
|
62294
62834
|
const [error, setError] = useState(null);
|
|
62295
62835
|
const [topPerformer, setTopPerformer] = useState({
|
|
@@ -62311,13 +62851,6 @@ var KPIsOverviewView = ({
|
|
|
62311
62851
|
const [monthlyError, setMonthlyError] = useState(null);
|
|
62312
62852
|
const dailyRequestKeyRef = useRef(null);
|
|
62313
62853
|
const monthlyRequestKeyRef = useRef(null);
|
|
62314
|
-
useEffect(() => {
|
|
62315
|
-
if (!router.isReady) return;
|
|
62316
|
-
const tab = router.query.tab;
|
|
62317
|
-
if (tab === "leaderboard") {
|
|
62318
|
-
setActiveTab("leaderboard");
|
|
62319
|
-
}
|
|
62320
|
-
}, [router.isReady, router.query.tab]);
|
|
62321
62854
|
const supabase = useSupabase();
|
|
62322
62855
|
const { user } = useAuth();
|
|
62323
62856
|
const dashboardConfig = useDashboardConfig();
|
|
@@ -62403,7 +62936,77 @@ var KPIsOverviewView = ({
|
|
|
62403
62936
|
() => getShiftEndDate(currentShiftDetails, configuredTimezone),
|
|
62404
62937
|
[currentShiftDetails, configuredTimezone]
|
|
62405
62938
|
);
|
|
62406
|
-
|
|
62939
|
+
React141__default.useMemo(() => {
|
|
62940
|
+
if (shiftConfig?.shifts && shiftConfig.shifts.length > 0) {
|
|
62941
|
+
return shiftConfig.shifts.map((shift) => ({
|
|
62942
|
+
id: shift.shiftId,
|
|
62943
|
+
label: shift.shiftName || `Shift ${shift.shiftId}`,
|
|
62944
|
+
startTime: shift.startTime,
|
|
62945
|
+
endTime: shift.endTime
|
|
62946
|
+
}));
|
|
62947
|
+
}
|
|
62948
|
+
return [
|
|
62949
|
+
{ id: 0, label: "Day Shift", startTime: "06:00", endTime: "18:00" },
|
|
62950
|
+
{ id: 1, label: "Night Shift", startTime: "18:00", endTime: "06:00" }
|
|
62951
|
+
];
|
|
62952
|
+
}, [shiftConfig]);
|
|
62953
|
+
const effectiveLeaderboardDate = selectedLeaderboardDate || currentShiftDate;
|
|
62954
|
+
const effectiveLeaderboardShiftId = Number.isFinite(selectedLeaderboardShiftId) ? selectedLeaderboardShiftId : currentShiftId;
|
|
62955
|
+
const isHistoricalLeaderboardDaily = activeTab === "leaderboard" && timeRange === "today" && (effectiveLeaderboardDate !== currentShiftDate || effectiveLeaderboardShiftId !== currentShiftId);
|
|
62956
|
+
useEffect(() => {
|
|
62957
|
+
if (!router.isReady) return;
|
|
62958
|
+
const tabQuery = router.query.tab;
|
|
62959
|
+
const dateQuery = router.query.date;
|
|
62960
|
+
const shiftQuery = router.query.shift;
|
|
62961
|
+
const parsedShiftQuery = typeof shiftQuery === "string" ? Number.parseInt(shiftQuery, 10) : Number.NaN;
|
|
62962
|
+
const hasHistoricalQuery = tabQuery === "leaderboard" && typeof dateQuery === "string" && Number.isFinite(parsedShiftQuery);
|
|
62963
|
+
setActiveTab(tabQuery === "leaderboard" ? "leaderboard" : "today");
|
|
62964
|
+
if (hasHistoricalQuery) {
|
|
62965
|
+
setSelectedLeaderboardDate(dateQuery);
|
|
62966
|
+
setSelectedLeaderboardShiftId(parsedShiftQuery);
|
|
62967
|
+
setTimeRange("today");
|
|
62968
|
+
} else {
|
|
62969
|
+
setSelectedLeaderboardDate(currentShiftDate);
|
|
62970
|
+
setSelectedLeaderboardShiftId(currentShiftId);
|
|
62971
|
+
}
|
|
62972
|
+
setHasHydratedLeaderboardRouteState(true);
|
|
62973
|
+
}, [
|
|
62974
|
+
router.isReady,
|
|
62975
|
+
router.query.tab,
|
|
62976
|
+
router.query.date,
|
|
62977
|
+
router.query.shift,
|
|
62978
|
+
currentShiftDate,
|
|
62979
|
+
currentShiftId
|
|
62980
|
+
]);
|
|
62981
|
+
useEffect(() => {
|
|
62982
|
+
if (!router.isReady || !hasHydratedLeaderboardRouteState) return;
|
|
62983
|
+
const expectedTab = activeTab === "leaderboard" ? "leaderboard" : void 0;
|
|
62984
|
+
const expectedDate = activeTab === "leaderboard" && timeRange === "today" && isHistoricalLeaderboardDaily ? effectiveLeaderboardDate : void 0;
|
|
62985
|
+
const expectedShift = expectedDate !== void 0 ? effectiveLeaderboardShiftId.toString() : void 0;
|
|
62986
|
+
const currentTab = typeof router.query.tab === "string" ? router.query.tab : void 0;
|
|
62987
|
+
const currentDateQuery = typeof router.query.date === "string" ? router.query.date : void 0;
|
|
62988
|
+
const currentShiftQuery = typeof router.query.shift === "string" ? router.query.shift : void 0;
|
|
62989
|
+
if (currentTab === expectedTab && currentDateQuery === expectedDate && currentShiftQuery === expectedShift) {
|
|
62990
|
+
return;
|
|
62991
|
+
}
|
|
62992
|
+
void router.replace(
|
|
62993
|
+
createKpisOverviewUrl({
|
|
62994
|
+
tab: expectedTab === "leaderboard" ? "leaderboard" : void 0,
|
|
62995
|
+
date: expectedDate,
|
|
62996
|
+
shift: expectedShift !== void 0 ? Number.parseInt(expectedShift, 10) : void 0
|
|
62997
|
+
}),
|
|
62998
|
+
void 0,
|
|
62999
|
+
{ shallow: true }
|
|
63000
|
+
);
|
|
63001
|
+
}, [
|
|
63002
|
+
router,
|
|
63003
|
+
activeTab,
|
|
63004
|
+
timeRange,
|
|
63005
|
+
effectiveLeaderboardDate,
|
|
63006
|
+
effectiveLeaderboardShiftId,
|
|
63007
|
+
hasHydratedLeaderboardRouteState,
|
|
63008
|
+
isHistoricalLeaderboardDaily
|
|
63009
|
+
]);
|
|
62407
63010
|
const factoryViewId = entityConfig.factoryViewId || "factory";
|
|
62408
63011
|
const {
|
|
62409
63012
|
lineMetrics,
|
|
@@ -62578,10 +63181,10 @@ var KPIsOverviewView = ({
|
|
|
62578
63181
|
}, [supabase, resolvedCompanyId, leaderboardLinesForView, monthStartDate, monthEndDateKey, viewType]);
|
|
62579
63182
|
const fetchDailyLeaderboard = useCallback(async () => {
|
|
62580
63183
|
if (!supabase || !resolvedCompanyId || leaderboardLinesForView.length === 0) return;
|
|
62581
|
-
if (!
|
|
63184
|
+
if (!effectiveLeaderboardDate) return;
|
|
62582
63185
|
const targetLineIds = leaderboardLinesForView.map((line) => line.id);
|
|
62583
63186
|
const lineIdsKey = targetLineIds.slice().sort().join(",");
|
|
62584
|
-
const requestKey = `${resolvedCompanyId}|${
|
|
63187
|
+
const requestKey = `${resolvedCompanyId}|${effectiveLeaderboardDate}|${effectiveLeaderboardShiftId}|${lineIdsKey}`;
|
|
62585
63188
|
if (dailyRequestKeyRef.current === requestKey) return;
|
|
62586
63189
|
dailyRequestKeyRef.current = requestKey;
|
|
62587
63190
|
setDailyLoading(true);
|
|
@@ -62589,8 +63192,8 @@ var KPIsOverviewView = ({
|
|
|
62589
63192
|
try {
|
|
62590
63193
|
const entries = await lineLeaderboardService.getDailyLineLeaderboard(supabase, {
|
|
62591
63194
|
companyId: resolvedCompanyId,
|
|
62592
|
-
date:
|
|
62593
|
-
shiftId:
|
|
63195
|
+
date: effectiveLeaderboardDate,
|
|
63196
|
+
shiftId: effectiveLeaderboardShiftId,
|
|
62594
63197
|
lineIds: targetLineIds,
|
|
62595
63198
|
lineMode: viewType === "machine" ? "uptime" : "output"
|
|
62596
63199
|
});
|
|
@@ -62608,7 +63211,14 @@ var KPIsOverviewView = ({
|
|
|
62608
63211
|
} finally {
|
|
62609
63212
|
setDailyLoading(false);
|
|
62610
63213
|
}
|
|
62611
|
-
}, [
|
|
63214
|
+
}, [
|
|
63215
|
+
supabase,
|
|
63216
|
+
resolvedCompanyId,
|
|
63217
|
+
leaderboardLinesForView,
|
|
63218
|
+
effectiveLeaderboardDate,
|
|
63219
|
+
effectiveLeaderboardShiftId,
|
|
63220
|
+
viewType
|
|
63221
|
+
]);
|
|
62612
63222
|
useEffect(() => {
|
|
62613
63223
|
if (activeTab !== "leaderboard") return;
|
|
62614
63224
|
fetchMonthlyLeaderboard();
|
|
@@ -62697,6 +63307,12 @@ var KPIsOverviewView = ({
|
|
|
62697
63307
|
trackProps.status = isEfficiencyOnTrack(kpis.efficiency?.value) ? "On Track" : "Behind";
|
|
62698
63308
|
}
|
|
62699
63309
|
trackCoreEvent("Line Card Clicked", trackProps);
|
|
63310
|
+
if (activeTab === "leaderboard" && timeRange === "today" && isHistoricalLeaderboardDaily) {
|
|
63311
|
+
navigation.navigate(
|
|
63312
|
+
`/kpis/${line.id}?date=${encodeURIComponent(effectiveLeaderboardDate)}&shift=${effectiveLeaderboardShiftId}`
|
|
63313
|
+
);
|
|
63314
|
+
return;
|
|
63315
|
+
}
|
|
62700
63316
|
navigation.navigate(`/kpis/${line.id}`);
|
|
62701
63317
|
};
|
|
62702
63318
|
const handleBackClick = useCallback(() => {
|
|
@@ -62722,21 +63338,24 @@ var KPIsOverviewView = ({
|
|
|
62722
63338
|
});
|
|
62723
63339
|
setActiveTab(newTab);
|
|
62724
63340
|
}, [activeTab, leaderboardLines.length, lines.length]);
|
|
62725
|
-
const formatLocalDate2 = (
|
|
62726
|
-
|
|
63341
|
+
const formatLocalDate2 = useCallback((dateKey) => {
|
|
63342
|
+
return formatDateKey(dateKey, configuredTimezone, {
|
|
62727
63343
|
year: "numeric",
|
|
62728
63344
|
month: "long",
|
|
62729
63345
|
day: "numeric"
|
|
62730
|
-
};
|
|
62731
|
-
|
|
62732
|
-
};
|
|
63346
|
+
});
|
|
63347
|
+
}, [configuredTimezone]);
|
|
62733
63348
|
const getMonthRange = () => {
|
|
62734
|
-
const
|
|
62735
|
-
const
|
|
62736
|
-
const
|
|
62737
|
-
|
|
62738
|
-
|
|
62739
|
-
|
|
63349
|
+
const zonedNow = toZonedTime(/* @__PURE__ */ new Date(), configuredTimezone);
|
|
63350
|
+
const startOfMonthKey = buildDateKey(zonedNow.getFullYear(), zonedNow.getMonth(), 1);
|
|
63351
|
+
const endOfMonthKey = buildDateKey(
|
|
63352
|
+
zonedNow.getFullYear(),
|
|
63353
|
+
zonedNow.getMonth(),
|
|
63354
|
+
new Date(zonedNow.getFullYear(), zonedNow.getMonth() + 1, 0).getDate()
|
|
63355
|
+
);
|
|
63356
|
+
const startLabel = formatDateKey(startOfMonthKey, configuredTimezone, { month: "short", day: "numeric" });
|
|
63357
|
+
const endLabel = formatDateKey(endOfMonthKey, configuredTimezone, { month: "short", day: "numeric" });
|
|
63358
|
+
return `${startLabel} - ${endLabel}, ${zonedNow.getFullYear()}`;
|
|
62740
63359
|
};
|
|
62741
63360
|
const isMonthlyMode = activeTab === "leaderboard" && timeRange === "monthly";
|
|
62742
63361
|
const isLeaderboardLoading = timeRange === "today" ? dailyLoading : monthlyLoading;
|
|
@@ -62745,8 +63364,13 @@ var KPIsOverviewView = ({
|
|
|
62745
63364
|
const showTopPerformerImage = Boolean(topPerformer.imageUrl) && !topPerformerImageError;
|
|
62746
63365
|
typeof topPerformer.efficiency === "number" && Number.isFinite(topPerformer.efficiency);
|
|
62747
63366
|
topPerformerLoading ? "--" : typeof topPerformer.efficiency === "number" && Number.isFinite(topPerformer.efficiency) ? `${topPerformer.efficiency.toFixed(1)}%` : "--";
|
|
63367
|
+
const showHistoricalLeaderboardHeader = activeTab === "leaderboard" && timeRange === "today" && isHistoricalLeaderboardDaily;
|
|
63368
|
+
const headerDateKey = activeTab === "leaderboard" && timeRange === "today" ? effectiveLeaderboardDate : monthEndDateKey;
|
|
63369
|
+
const headerShiftId = showHistoricalLeaderboardHeader ? effectiveLeaderboardShiftId : currentShiftDetails.shiftId;
|
|
63370
|
+
const headerShiftName = getShiftNameById(headerShiftId, configuredTimezone, shiftConfig).replace(/ Shift$/i, "");
|
|
63371
|
+
const headerDateLabel = isMonthlyMode ? getMonthRange() : formatLocalDate2(headerDateKey);
|
|
62748
63372
|
const getShiftIcon = (shiftId) => {
|
|
62749
|
-
const shiftNameLower =
|
|
63373
|
+
const shiftNameLower = getShiftNameById(shiftId, configuredTimezone, shiftConfig).toLowerCase();
|
|
62750
63374
|
if (shiftNameLower.includes("day") || shiftNameLower.includes("morning") || shiftId === 0) {
|
|
62751
63375
|
return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
|
|
62752
63376
|
}
|
|
@@ -62849,18 +63473,26 @@ var KPIsOverviewView = ({
|
|
|
62849
63473
|
),
|
|
62850
63474
|
/* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
62851
63475
|
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-gray-900", children: activeTab === "leaderboard" ? "Leaderboard" : "Overview" }),
|
|
62852
|
-
/* @__PURE__ */ jsx(
|
|
63476
|
+
/* @__PURE__ */ jsx(
|
|
63477
|
+
"div",
|
|
63478
|
+
{
|
|
63479
|
+
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"}`
|
|
63480
|
+
}
|
|
63481
|
+
)
|
|
62853
63482
|
] }) }),
|
|
62854
63483
|
/* @__PURE__ */ jsx("div", { className: "w-12" })
|
|
62855
63484
|
] }),
|
|
62856
63485
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center justify-center gap-2", children: [
|
|
62857
|
-
/* @__PURE__ */ jsx("div", { className: `inline-flex items-center bg-gray-100 rounded-full ${isMonthlyMode ? "px-4 py-1.5 ring-1 ring-gray-200 shadow-sm" : "px-2.5 py-1"}`, children: /* @__PURE__ */ jsx("span", { className: `font-medium text-gray-700 ${isMonthlyMode ? "text-sm" : "text-xs"}`, children:
|
|
63486
|
+
/* @__PURE__ */ jsx("div", { className: `inline-flex items-center bg-gray-100 rounded-full ${isMonthlyMode ? "px-4 py-1.5 ring-1 ring-gray-200 shadow-sm" : "px-2.5 py-1"}`, children: /* @__PURE__ */ jsx("span", { className: `font-medium text-gray-700 ${isMonthlyMode ? "text-sm" : "text-xs"}`, children: headerDateLabel }) }),
|
|
62858
63487
|
!isMonthlyMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62859
63488
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
|
|
62860
|
-
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon(
|
|
62861
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children:
|
|
63489
|
+
/* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon(headerShiftId) }),
|
|
63490
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: headerShiftName })
|
|
62862
63491
|
] }),
|
|
62863
|
-
/* @__PURE__ */
|
|
63492
|
+
showHistoricalLeaderboardHeader ? /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-amber-50 text-amber-700 rounded-full", children: [
|
|
63493
|
+
/* @__PURE__ */ jsx(Clock, { className: "w-3 h-3" }),
|
|
63494
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: "Historical" })
|
|
63495
|
+
] }) : /* @__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, {}) }) })
|
|
62864
63496
|
] })
|
|
62865
63497
|
] }),
|
|
62866
63498
|
activeTab !== "leaderboard" && /* @__PURE__ */ jsx("div", { className: "mt-4 bg-white shadow-md hover:shadow-lg transition-all duration-300 ease-out hover:scale-[1.01] relative rounded-2xl border border-amber-100 pl-2 pr-4 py-1.5 flex items-center justify-between group", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 min-w-0", children: [
|
|
@@ -62961,7 +63593,12 @@ var KPIsOverviewView = ({
|
|
|
62961
63593
|
) }),
|
|
62962
63594
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
62963
63595
|
/* @__PURE__ */ jsx("h1", { className: "text-2xl md:text-3xl lg:text-4xl font-semibold text-gray-900 tracking-tight", children: activeTab === "leaderboard" ? "Leaderboard" : "Overview" }),
|
|
62964
|
-
/* @__PURE__ */ jsx(
|
|
63596
|
+
/* @__PURE__ */ jsx(
|
|
63597
|
+
"div",
|
|
63598
|
+
{
|
|
63599
|
+
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"}`
|
|
63600
|
+
}
|
|
63601
|
+
)
|
|
62965
63602
|
] }),
|
|
62966
63603
|
!topPerformerLoading && activeTab !== "leaderboard" && /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-1/2 -translate-y-1/2 z-10", children: /* @__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: [
|
|
62967
63604
|
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
@@ -63031,7 +63668,7 @@ var KPIsOverviewView = ({
|
|
|
63031
63668
|
] }) })
|
|
63032
63669
|
] }),
|
|
63033
63670
|
/* @__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: [
|
|
63034
|
-
!isMonthlyMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63671
|
+
!isMonthlyMode && !showHistoricalLeaderboardHeader && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63035
63672
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-700", children: [
|
|
63036
63673
|
/* @__PURE__ */ jsx("svg", { className: "w-4 h-4 opacity-70", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
63037
63674
|
/* @__PURE__ */ jsx("span", { className: "text-base font-semibold tabular-nums", children: /* @__PURE__ */ jsx(ISTTimer_default, {}) })
|
|
@@ -63040,16 +63677,23 @@ var KPIsOverviewView = ({
|
|
|
63040
63677
|
] }),
|
|
63041
63678
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
63042
63679
|
/* @__PURE__ */ jsx("svg", { className: `w-4 h-4 opacity-70 ${isMonthlyMode ? "scale-110" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
63043
|
-
/* @__PURE__ */ jsx("span", { className: `${isMonthlyMode ? "text-base font-medium" : "text-sm font-medium"}`, children:
|
|
63680
|
+
/* @__PURE__ */ jsx("span", { className: `${isMonthlyMode ? "text-base font-medium" : "text-sm font-medium"}`, children: headerDateLabel })
|
|
63044
63681
|
] }),
|
|
63045
63682
|
!isMonthlyMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63046
63683
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" }),
|
|
63047
63684
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-blue-600", children: [
|
|
63048
|
-
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon(
|
|
63685
|
+
/* @__PURE__ */ jsx("div", { className: "opacity-70", children: getShiftIcon(headerShiftId) }),
|
|
63049
63686
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-semibold uppercase tracking-wider", children: [
|
|
63050
|
-
|
|
63687
|
+
headerShiftName,
|
|
63051
63688
|
" Shift"
|
|
63052
63689
|
] })
|
|
63690
|
+
] }),
|
|
63691
|
+
showHistoricalLeaderboardHeader && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63692
|
+
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-200" }),
|
|
63693
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-2.5 py-1 bg-amber-50 text-amber-700 rounded-full border border-amber-200", children: [
|
|
63694
|
+
/* @__PURE__ */ jsx(Clock, { className: "w-3.5 h-3.5" }),
|
|
63695
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wider", children: "Historical" })
|
|
63696
|
+
] })
|
|
63053
63697
|
] })
|
|
63054
63698
|
] })
|
|
63055
63699
|
] }) }),
|
|
@@ -63072,19 +63716,52 @@ var KPIsOverviewView = ({
|
|
|
63072
63716
|
}
|
|
63073
63717
|
)
|
|
63074
63718
|
] }),
|
|
63075
|
-
|
|
63076
|
-
"
|
|
63077
|
-
|
|
63078
|
-
|
|
63079
|
-
|
|
63080
|
-
|
|
63081
|
-
|
|
63082
|
-
|
|
63083
|
-
|
|
63084
|
-
|
|
63085
|
-
|
|
63086
|
-
|
|
63087
|
-
|
|
63719
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
63720
|
+
activeTab === "leaderboard" && timeRange === "today" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
63721
|
+
/* @__PURE__ */ jsx(
|
|
63722
|
+
MonthlyRangeFilter_default,
|
|
63723
|
+
{
|
|
63724
|
+
month: parseDateKeyToDate(effectiveLeaderboardDate).getMonth(),
|
|
63725
|
+
year: parseDateKeyToDate(effectiveLeaderboardDate).getFullYear(),
|
|
63726
|
+
timezone: configuredTimezone,
|
|
63727
|
+
value: {
|
|
63728
|
+
startKey: effectiveLeaderboardDate,
|
|
63729
|
+
endKey: effectiveLeaderboardDate
|
|
63730
|
+
},
|
|
63731
|
+
onChange: (range) => {
|
|
63732
|
+
setSelectedLeaderboardDate(range.startKey);
|
|
63733
|
+
},
|
|
63734
|
+
showLabel: false,
|
|
63735
|
+
singleDateOnly: true
|
|
63736
|
+
}
|
|
63737
|
+
),
|
|
63738
|
+
isHistoricalLeaderboardDaily && /* @__PURE__ */ jsx(
|
|
63739
|
+
"button",
|
|
63740
|
+
{
|
|
63741
|
+
type: "button",
|
|
63742
|
+
onClick: () => {
|
|
63743
|
+
setSelectedLeaderboardDate(currentShiftDate);
|
|
63744
|
+
setSelectedLeaderboardShiftId(currentShiftId);
|
|
63745
|
+
},
|
|
63746
|
+
className: "text-xs font-medium text-blue-600 hover:text-blue-700 whitespace-nowrap",
|
|
63747
|
+
children: "Return to Live"
|
|
63748
|
+
}
|
|
63749
|
+
)
|
|
63750
|
+
] }),
|
|
63751
|
+
(activeTab === "leaderboard" || activeTab === "today") && showViewTypeDropdown && /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsxs(
|
|
63752
|
+
"select",
|
|
63753
|
+
{
|
|
63754
|
+
value: viewType,
|
|
63755
|
+
onChange: (e) => setViewType(e.target.value),
|
|
63756
|
+
className: "appearance-none pl-3 pr-8 py-1.5 text-sm font-medium bg-white border border-gray-200 hover:border-gray-300 rounded-lg text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all cursor-pointer shadow-sm",
|
|
63757
|
+
style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.5rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.2em 1.2em` },
|
|
63758
|
+
children: [
|
|
63759
|
+
/* @__PURE__ */ jsx("option", { value: "operator", children: "Workforce" }),
|
|
63760
|
+
/* @__PURE__ */ jsx("option", { value: "machine", children: "Machine" })
|
|
63761
|
+
]
|
|
63762
|
+
}
|
|
63763
|
+
) })
|
|
63764
|
+
] })
|
|
63088
63765
|
] })
|
|
63089
63766
|
] })
|
|
63090
63767
|
] }) }),
|
|
@@ -63129,7 +63806,9 @@ var KPIsOverviewView = ({
|
|
|
63129
63806
|
shiftEndDate,
|
|
63130
63807
|
monthEndDate,
|
|
63131
63808
|
viewType,
|
|
63132
|
-
setViewType
|
|
63809
|
+
setViewType,
|
|
63810
|
+
timezone: configuredTimezone,
|
|
63811
|
+
isHistoricalDaily: isHistoricalLeaderboardDaily
|
|
63133
63812
|
}
|
|
63134
63813
|
) })
|
|
63135
63814
|
) })
|
|
@@ -64671,51 +65350,41 @@ var ClipsCostView = () => {
|
|
|
64671
65350
|
/* @__PURE__ */ jsx("div", { className: "min-w-[120px]" })
|
|
64672
65351
|
] }) })
|
|
64673
65352
|
] }) }),
|
|
64674
|
-
/* @__PURE__ */ jsx("main", { className: "flex-1 p-4 sm:p-6 lg:p-8 max-w-
|
|
65353
|
+
/* @__PURE__ */ jsx("main", { className: "flex-1 p-4 sm:p-6 lg:p-8 max-w-5xl mx-auto w-full", children: error ? /* @__PURE__ */ jsxs("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg flex items-start gap-3 text-red-700 animate-in fade-in slide-in-from-top-2 max-w-2xl mx-auto", children: [
|
|
64675
65354
|
/* @__PURE__ */ jsx(AlertCircle, { className: "h-5 w-5 flex-shrink-0 mt-0.5" }),
|
|
64676
65355
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
64677
65356
|
/* @__PURE__ */ jsx("h3", { className: "font-medium", children: "Error loading usage data" }),
|
|
64678
65357
|
/* @__PURE__ */ jsx("p", { className: "text-sm mt-1 text-red-600", children: error })
|
|
64679
65358
|
] })
|
|
64680
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: "
|
|
64681
|
-
/* @__PURE__ */ jsx(Card2, { className: "overflow-hidden shadow-sm border-gray-200 bg-white", children: /* @__PURE__ */ jsx(CardContent2, { className: "p-
|
|
64682
|
-
/* @__PURE__ */ jsx("div", { className: "p-
|
|
64683
|
-
/* @__PURE__ */ jsx("h2", { className: "text-
|
|
64684
|
-
/* @__PURE__ */ jsx("p", { className: "text-
|
|
64685
|
-
/* @__PURE__ */ jsx("div", { className: "text-
|
|
64686
|
-
|
|
64687
|
-
|
|
64688
|
-
|
|
64689
|
-
|
|
65359
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "mt-8 grid grid-cols-1 lg:grid-cols-3 gap-6 animate-in fade-in slide-in-from-bottom-4 duration-500", children: [
|
|
65360
|
+
/* @__PURE__ */ jsx("div", { className: "lg:col-span-2", children: /* @__PURE__ */ jsx(Card2, { className: "overflow-hidden shadow-sm border-gray-200 bg-white h-full flex flex-col justify-center", children: /* @__PURE__ */ jsx(CardContent2, { className: "p-10 lg:p-14", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center text-center", children: [
|
|
65361
|
+
/* @__PURE__ */ jsx("div", { className: "p-4 bg-blue-50/50 rounded-2xl mb-6 ring-1 ring-blue-100/50", children: /* @__PURE__ */ jsx(Film, { className: "h-10 w-10 text-blue-600", strokeWidth: 1.5 }) }),
|
|
65362
|
+
/* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-gray-600 uppercase tracking-widest mb-3", children: "Current Month Usage" }),
|
|
65363
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-400 mb-6", children: formatMonthLabel(data?.monthStart) }),
|
|
65364
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-baseline gap-2 mb-2", children: /* @__PURE__ */ jsx("div", { className: "text-7xl font-bold text-gray-900 tabular-nums tracking-tighter", children: formatNumber(data?.monthlyClassifications || 0) }) }),
|
|
65365
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-4", children: "Clips analyzed and processed by our AI pipeline" })
|
|
65366
|
+
] }) }) }) }),
|
|
65367
|
+
/* @__PURE__ */ jsx("div", { className: "lg:col-span-1", children: /* @__PURE__ */ jsx(Card2, { className: "overflow-hidden shadow-sm border-gray-200 bg-white h-full", children: /* @__PURE__ */ jsxs(CardContent2, { className: "p-6 lg:p-8 flex flex-col h-full", children: [
|
|
65368
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-6 uppercase tracking-widest", children: "Previous Months" }),
|
|
65369
|
+
(data?.historicalMonthlyClassifications?.length || 0) === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center text-center py-8", children: [
|
|
65370
|
+
/* @__PURE__ */ jsx("div", { className: "p-3 bg-gray-50 rounded-full mb-3", children: /* @__PURE__ */ jsx(Film, { className: "h-6 w-6 text-gray-400", strokeWidth: 1.5 }) }),
|
|
65371
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No historical month usage yet." })
|
|
65372
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "space-y-3 flex-1 overflow-y-auto pr-2", children: data?.historicalMonthlyClassifications.map((item) => /* @__PURE__ */ jsxs(
|
|
64690
65373
|
"div",
|
|
64691
65374
|
{
|
|
64692
|
-
className: "flex items-center justify-between rounded-
|
|
65375
|
+
className: "group flex items-center justify-between rounded-xl border border-gray-100 bg-gray-50/50 hover:bg-white hover:border-gray-200 hover:shadow-sm px-4 py-3.5 transition-all duration-200",
|
|
64693
65376
|
children: [
|
|
64694
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-gray-
|
|
64695
|
-
/* @__PURE__ */ jsx("span", { className: "text-
|
|
65377
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-600 group-hover:text-gray-900 transition-colors", children: formatMonthLabel(item.monthStart) }),
|
|
65378
|
+
/* @__PURE__ */ jsx("span", { className: "text-base font-semibold text-gray-900 tabular-nums", children: formatNumber(item.classifications) })
|
|
64696
65379
|
]
|
|
64697
65380
|
},
|
|
64698
65381
|
item.monthStart
|
|
64699
65382
|
)) })
|
|
64700
|
-
] }) })
|
|
65383
|
+
] }) }) })
|
|
64701
65384
|
] }) })
|
|
64702
65385
|
] });
|
|
64703
65386
|
};
|
|
64704
65387
|
var ClipsCostView_default = ClipsCostView;
|
|
64705
|
-
|
|
64706
|
-
// src/lib/constants/actions.ts
|
|
64707
|
-
var ACTION_NAMES = {
|
|
64708
|
-
/** Assembly operations */
|
|
64709
|
-
ASSEMBLY: "Assembly",
|
|
64710
|
-
/** Packaging operations */
|
|
64711
|
-
PACKAGING: "Packaging",
|
|
64712
|
-
/** Inspection operations */
|
|
64713
|
-
INSPECTION: "Inspection",
|
|
64714
|
-
/** Testing operations */
|
|
64715
|
-
TESTING: "Testing",
|
|
64716
|
-
/** Quality control operations */
|
|
64717
|
-
QUALITY_CONTROL: "Quality Control"
|
|
64718
|
-
};
|
|
64719
65388
|
var calculateShiftHours = (startTime, endTime, breaks = []) => {
|
|
64720
65389
|
if (!startTime || !endTime) return 8;
|
|
64721
65390
|
const [startHour, startMinute] = startTime.split(":").map(Number);
|
|
@@ -65297,9 +65966,9 @@ var ShiftsView = ({
|
|
|
65297
65966
|
const actionIds = Array.from(
|
|
65298
65967
|
new Set(currentThresholds.map((threshold) => threshold.action_id).filter(Boolean))
|
|
65299
65968
|
);
|
|
65300
|
-
const
|
|
65969
|
+
const actionMetadataById = /* @__PURE__ */ new Map();
|
|
65301
65970
|
if (actionIds.length > 0) {
|
|
65302
|
-
const { data: actionRows, error: actionsError } = await supabase.from("actions").select("id, action_name").in("id", actionIds);
|
|
65971
|
+
const { data: actionRows, error: actionsError } = await supabase.from("actions").select("id, action_name, action_family").in("id", actionIds);
|
|
65303
65972
|
if (actionsError) {
|
|
65304
65973
|
console.warn(
|
|
65305
65974
|
`[ShiftsView] Failed to resolve action names for line ${lineId}, shift ${shift.shiftId}: ${actionsError.message}`
|
|
@@ -65307,7 +65976,13 @@ var ShiftsView = ({
|
|
|
65307
65976
|
} else {
|
|
65308
65977
|
(actionRows || []).forEach((actionRow) => {
|
|
65309
65978
|
if (actionRow.id && actionRow.action_name) {
|
|
65310
|
-
|
|
65979
|
+
actionMetadataById.set(actionRow.id, {
|
|
65980
|
+
action_name: actionRow.action_name,
|
|
65981
|
+
action_family: normalizeActionFamily({
|
|
65982
|
+
actionFamily: actionRow.action_family,
|
|
65983
|
+
actionName: actionRow.action_name
|
|
65984
|
+
})
|
|
65985
|
+
});
|
|
65311
65986
|
}
|
|
65312
65987
|
});
|
|
65313
65988
|
}
|
|
@@ -65328,7 +66003,7 @@ var ShiftsView = ({
|
|
|
65328
66003
|
nextDayOutput = dayOutputToKeep;
|
|
65329
66004
|
nextPPH = newShiftHours > 0 ? Math.round(dayOutputToKeep / newShiftHours) : 0;
|
|
65330
66005
|
}
|
|
65331
|
-
const resolvedActionName = (typeof threshold.action_name === "string" && threshold.action_name.trim().length > 0 ? threshold.action_name :
|
|
66006
|
+
const resolvedActionName = (typeof threshold.action_name === "string" && threshold.action_name.trim().length > 0 ? threshold.action_name : actionMetadataById.get(threshold.action_id)?.action_name) || ACTION_NAMES.ASSEMBLY;
|
|
65332
66007
|
return {
|
|
65333
66008
|
line_id: threshold.line_id || lineId,
|
|
65334
66009
|
shift_id: shift.shiftId,
|
|
@@ -65349,18 +66024,20 @@ var ShiftsView = ({
|
|
|
65349
66024
|
`Failed to update action thresholds for line ${lineId}, shift ${shift.shiftId}: ${thresholdsUpsertError.message}`
|
|
65350
66025
|
);
|
|
65351
66026
|
}
|
|
65352
|
-
const
|
|
65353
|
-
Array.from(
|
|
66027
|
+
const outputActionIds = new Set(
|
|
66028
|
+
Array.from(actionMetadataById.entries()).filter(([, action]) => action.action_family === ACTION_FAMILIES.OUTPUT).map(([actionId]) => actionId)
|
|
65354
66029
|
);
|
|
65355
|
-
const
|
|
65356
|
-
if (
|
|
65357
|
-
return
|
|
66030
|
+
const outputThresholds = recalculatedThresholds.filter((threshold) => {
|
|
66031
|
+
if (outputActionIds.has(threshold.action_id)) return true;
|
|
66032
|
+
return normalizeActionFamily({
|
|
66033
|
+
actionName: threshold.action_name
|
|
66034
|
+
}) === ACTION_FAMILIES.OUTPUT;
|
|
65358
66035
|
});
|
|
65359
|
-
const thresholdDayOutput =
|
|
66036
|
+
const thresholdDayOutput = outputThresholds.reduce(
|
|
65360
66037
|
(sum, threshold) => sum + (Number(threshold.total_day_output) || 0),
|
|
65361
66038
|
0
|
|
65362
66039
|
);
|
|
65363
|
-
const thresholdPPH =
|
|
66040
|
+
const thresholdPPH = outputThresholds.reduce(
|
|
65364
66041
|
(sum, threshold) => sum + (Number(threshold.pph_threshold) || 0),
|
|
65365
66042
|
0
|
|
65366
66043
|
);
|
|
@@ -66571,7 +67248,7 @@ var TargetsViewUI = ({
|
|
|
66571
67248
|
"aria-label": `Action type for ${formattedName}`,
|
|
66572
67249
|
children: [
|
|
66573
67250
|
/* @__PURE__ */ jsx("option", { value: "assembly", className: "py-2", children: "Assembly" }),
|
|
66574
|
-
/* @__PURE__ */ jsx("option", { value: "
|
|
67251
|
+
/* @__PURE__ */ jsx("option", { value: "output", className: "py-2", children: ACTION_NAMES.OUTPUT })
|
|
66575
67252
|
]
|
|
66576
67253
|
}
|
|
66577
67254
|
) }),
|
|
@@ -66642,7 +67319,7 @@ var TargetsViewUI = ({
|
|
|
66642
67319
|
"aria-label": `Action type for ${formattedName}`,
|
|
66643
67320
|
children: [
|
|
66644
67321
|
/* @__PURE__ */ jsx("option", { value: "assembly", children: "Assembly" }),
|
|
66645
|
-
/* @__PURE__ */ jsx("option", { value: "
|
|
67322
|
+
/* @__PURE__ */ jsx("option", { value: "output", children: ACTION_NAMES.OUTPUT })
|
|
66646
67323
|
]
|
|
66647
67324
|
}
|
|
66648
67325
|
)
|
|
@@ -66847,14 +67524,20 @@ var TargetsView = ({
|
|
|
66847
67524
|
throw new Error("Failed to fetch bulk targets data");
|
|
66848
67525
|
}
|
|
66849
67526
|
const { data } = bulkResponse;
|
|
66850
|
-
const assemblyAction = Object.values(data.actions).find((a) =>
|
|
66851
|
-
|
|
66852
|
-
|
|
67527
|
+
const assemblyAction = data.actions[ACTION_FAMILIES.ASSEMBLY] || Object.values(data.actions).find((a) => normalizeActionFamily({
|
|
67528
|
+
actionFamily: a.action_family,
|
|
67529
|
+
actionName: a.action_name
|
|
67530
|
+
}) === ACTION_FAMILIES.ASSEMBLY);
|
|
67531
|
+
const outputAction = data.actions[ACTION_FAMILIES.OUTPUT] || Object.values(data.actions).find((a) => normalizeActionFamily({
|
|
67532
|
+
actionFamily: a.action_family,
|
|
67533
|
+
actionName: a.action_name
|
|
67534
|
+
}) === ACTION_FAMILIES.OUTPUT);
|
|
67535
|
+
if (!assemblyAction || !outputAction) {
|
|
66853
67536
|
throw new Error("Could not find required actions in bulk response");
|
|
66854
67537
|
}
|
|
66855
67538
|
const actionIdsData = {
|
|
66856
67539
|
assembly: assemblyAction.id,
|
|
66857
|
-
|
|
67540
|
+
output: outputAction.id
|
|
66858
67541
|
};
|
|
66859
67542
|
setActionIds(actionIdsData);
|
|
66860
67543
|
const newAllShiftsData = {};
|
|
@@ -66899,12 +67582,16 @@ var TargetsView = ({
|
|
|
66899
67582
|
let actionType = "assembly";
|
|
66900
67583
|
let actionId = actionIdsData.assembly;
|
|
66901
67584
|
const effectiveActionId = threshold?.action_id ?? ws.action_id;
|
|
66902
|
-
|
|
66903
|
-
|
|
66904
|
-
|
|
66905
|
-
}
|
|
67585
|
+
const effectiveActionFamily = normalizeActionFamily({
|
|
67586
|
+
actionFamily: threshold?.action_family,
|
|
67587
|
+
actionType: ws.action_type
|
|
67588
|
+
});
|
|
67589
|
+
if (effectiveActionFamily === ACTION_FAMILIES.OUTPUT || effectiveActionId === outputAction.id || !effectiveActionId && ws.action_type === "output") {
|
|
67590
|
+
actionType = "output";
|
|
67591
|
+
actionId = effectiveActionId || outputAction.id;
|
|
67592
|
+
} else if (effectiveActionFamily === ACTION_FAMILIES.ASSEMBLY || effectiveActionId === assemblyAction.id || !effectiveActionId && ws.action_type === "assembly") {
|
|
66906
67593
|
actionType = "assembly";
|
|
66907
|
-
actionId = assemblyAction.id;
|
|
67594
|
+
actionId = effectiveActionId || assemblyAction.id;
|
|
66908
67595
|
}
|
|
66909
67596
|
return {
|
|
66910
67597
|
id: ws.id,
|
|
@@ -67176,7 +67863,9 @@ var TargetsView = ({
|
|
|
67176
67863
|
// Round to whole number
|
|
67177
67864
|
ideal_cycle_time: Number(ws.targetCycleTime) || 0,
|
|
67178
67865
|
total_day_output: Number(ws.targetDayOutput) || 0,
|
|
67179
|
-
action_name: ws.actionType === "assembly" ? ACTION_NAMES.ASSEMBLY : ACTION_NAMES.
|
|
67866
|
+
action_name: ws.actionType === "assembly" ? ACTION_NAMES.ASSEMBLY : ACTION_NAMES.OUTPUT,
|
|
67867
|
+
action_family: ws.actionType,
|
|
67868
|
+
display_name: ws.actionType === "assembly" ? ACTION_NAMES.ASSEMBLY : ACTION_NAMES.OUTPUT,
|
|
67180
67869
|
updated_by: currentEffectiveUserId,
|
|
67181
67870
|
// Use the potentially hardcoded ID
|
|
67182
67871
|
...skuEnabled && lineDataToSave.selectedSKU ? { sku_id: lineDataToSave.selectedSKU.id } : {}
|
|
@@ -67184,7 +67873,7 @@ var TargetsView = ({
|
|
|
67184
67873
|
console.log(`[handleSaveLine] workspaceThresholdUpdates for ${lineId}:`, workspaceThresholdUpdates);
|
|
67185
67874
|
await workspaceService.updateActionThresholds(workspaceThresholdUpdates);
|
|
67186
67875
|
console.log(`[handleSaveLine] Successfully updated action thresholds for ${lineId}`);
|
|
67187
|
-
const
|
|
67876
|
+
const outputWorkspaces = lineDataToSave.workspaces.filter((ws) => ws.actionType === "output");
|
|
67188
67877
|
let resolvedLineThresholdSkuId = lineDataToSave.selectedSKU?.id || null;
|
|
67189
67878
|
if (!resolvedLineThresholdSkuId) {
|
|
67190
67879
|
const { data: dummySkuRows, error: dummySkuError } = await supabase.from("skus").select("id").eq("line_id", lineId).eq("sku_definition", "dummy_definition").eq("is_active", true).limit(1);
|
|
@@ -67202,8 +67891,8 @@ var TargetsView = ({
|
|
|
67202
67891
|
date: currentDate,
|
|
67203
67892
|
shift_id: selectedShift,
|
|
67204
67893
|
product_code: lineDataToSave.productId,
|
|
67205
|
-
threshold_day_output:
|
|
67206
|
-
threshold_pph:
|
|
67894
|
+
threshold_day_output: outputWorkspaces.reduce((acc, ws) => acc + (Number(ws.targetDayOutput) || 0), 0),
|
|
67895
|
+
threshold_pph: outputWorkspaces.reduce((acc, ws) => acc + (ws.targetPPH ? Math.round(Number(ws.targetPPH)) : 0), 0),
|
|
67207
67896
|
// Round each PPH value
|
|
67208
67897
|
sku_id: resolvedLineThresholdSkuId
|
|
67209
67898
|
};
|
|
@@ -67731,6 +68420,7 @@ var WorkspaceDetailView = ({
|
|
|
67731
68420
|
avg_efficiency: Number(cachedOverviewMetrics.efficiency || 0),
|
|
67732
68421
|
total_actions: totalActions,
|
|
67733
68422
|
hourly_action_counts: [],
|
|
68423
|
+
hourly_cycle_times: [],
|
|
67734
68424
|
workspace_rank: 0,
|
|
67735
68425
|
total_workspaces: 0,
|
|
67736
68426
|
ideal_output_until_now: idealOutput,
|
|
@@ -67741,6 +68431,22 @@ var WorkspaceDetailView = ({
|
|
|
67741
68431
|
}, [cachedOverviewMetrics, shiftConfig?.shifts]);
|
|
67742
68432
|
const workspace = (isHistoricView ? historicMetrics : liveMetrics) || cachedDetailedMetrics || overviewFallback;
|
|
67743
68433
|
const detailedWorkspaceMetrics = (isHistoricView ? historicMetrics : liveMetrics) || cachedDetailedMetrics;
|
|
68434
|
+
const cycleTimeChartData = useMemo(
|
|
68435
|
+
() => Array.isArray(workspace?.hourly_cycle_times) ? workspace.hourly_cycle_times.map((value) => {
|
|
68436
|
+
const numericValue = Number(value);
|
|
68437
|
+
return Number.isFinite(numericValue) ? numericValue : 0;
|
|
68438
|
+
}) : [],
|
|
68439
|
+
[workspace?.hourly_cycle_times]
|
|
68440
|
+
);
|
|
68441
|
+
const cycleTimeDatasetKey = useMemo(
|
|
68442
|
+
() => [
|
|
68443
|
+
workspace?.workspace_id || workspaceId || "workspace",
|
|
68444
|
+
date || workspace?.date || "live",
|
|
68445
|
+
parsedShiftId ?? workspace?.shift_id ?? "current",
|
|
68446
|
+
"hourly"
|
|
68447
|
+
].join(":"),
|
|
68448
|
+
[workspace?.workspace_id, workspaceId, date, workspace?.date, parsedShiftId, workspace?.shift_id]
|
|
68449
|
+
);
|
|
67744
68450
|
const hasWorkspaceSnapshot = Boolean(workspace);
|
|
67745
68451
|
const loading = ((isHistoricView ? historicLoading : liveLoading) || isShiftConfigLoading) && !hasWorkspaceSnapshot;
|
|
67746
68452
|
const error = isHistoricView ? historicError : liveError;
|
|
@@ -67982,10 +68688,47 @@ var WorkspaceDetailView = ({
|
|
|
67982
68688
|
return filterDataByDateKeyRange(monthlyData, range);
|
|
67983
68689
|
}, [monthlyData, range]);
|
|
67984
68690
|
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
|
|
67985
|
-
const
|
|
68691
|
+
const workspaceActionType = workspace && "action_type" in workspace ? workspace.action_type : void 0;
|
|
68692
|
+
const workspaceAssemblyEnabled = workspace && "line_assembly_enabled" in workspace ? workspace.line_assembly_enabled === true : false;
|
|
68693
|
+
const isAssemblyWorkspace = workspaceActionType === "assembly" || workspaceAssemblyEnabled;
|
|
68694
|
+
const shouldShowCycleTimeChart = !isUptimeMode && (showCycleTimeChart ?? isAssemblyWorkspace);
|
|
67986
68695
|
const showIdleBreakdownChart = !shouldShowCycleTimeChart && idleTimeVlmEnabled;
|
|
67987
68696
|
const idleClipDate = date || workspace?.date || calculatedOperationalDate || getOperationalDate(timezone);
|
|
67988
68697
|
const idleClipShiftId = parsedShiftId ?? workspace?.shift_id;
|
|
68698
|
+
const hourlyIdleMinutes = useMemo(() => {
|
|
68699
|
+
if (!shouldShowCycleTimeChart || !workspace?.idle_time_hourly || !workspace?.shift_start) return [];
|
|
68700
|
+
const parseTimeToMinutes3 = (time2) => {
|
|
68701
|
+
const [h, m] = time2.split(":").map(Number);
|
|
68702
|
+
if (!Number.isFinite(h) || !Number.isFinite(m)) return 0;
|
|
68703
|
+
return h * 60 + m;
|
|
68704
|
+
};
|
|
68705
|
+
const startTotal = parseTimeToMinutes3(workspace.shift_start);
|
|
68706
|
+
const endTotalRaw = workspace.shift_end ? parseTimeToMinutes3(workspace.shift_end) : startTotal + 11 * 60;
|
|
68707
|
+
const endTotal = endTotalRaw <= startTotal ? endTotalRaw + 24 * 60 : endTotalRaw;
|
|
68708
|
+
const shiftDuration = Math.max(60, endTotal - startTotal);
|
|
68709
|
+
const totalHourSlots = Math.max(1, Math.ceil(shiftDuration / 60));
|
|
68710
|
+
const idleTimeHourlyObj = workspace.idle_time_hourly || {};
|
|
68711
|
+
const result = Array(totalHourSlots).fill(0);
|
|
68712
|
+
for (let i = 0; i < totalHourSlots; i++) {
|
|
68713
|
+
const startSlotMins = startTotal + i * 60;
|
|
68714
|
+
let endSlotMins = startSlotMins + 60;
|
|
68715
|
+
if (endSlotMins > endTotal) endSlotMins = endTotal;
|
|
68716
|
+
let idleCount = 0;
|
|
68717
|
+
for (let m = startSlotMins; m < endSlotMins; m++) {
|
|
68718
|
+
const hourKey = Math.floor(m / 60) % 24;
|
|
68719
|
+
const minuteKey = m % 60;
|
|
68720
|
+
const hourData = idleTimeHourlyObj[hourKey.toString()] || [];
|
|
68721
|
+
if (Array.isArray(hourData)) {
|
|
68722
|
+
const val = hourData[minuteKey];
|
|
68723
|
+
if (val === 1 || val === "1") {
|
|
68724
|
+
idleCount++;
|
|
68725
|
+
}
|
|
68726
|
+
}
|
|
68727
|
+
}
|
|
68728
|
+
result[i] = idleCount;
|
|
68729
|
+
}
|
|
68730
|
+
return result;
|
|
68731
|
+
}, [shouldShowCycleTimeChart, workspace?.idle_time_hourly, workspace?.shift_start, workspace?.shift_end]);
|
|
67989
68732
|
const shiftDurationMinutes = useMemo(
|
|
67990
68733
|
() => getShiftDurationMinutes(workspace?.shift_start, workspace?.shift_end),
|
|
67991
68734
|
[workspace?.shift_start, workspace?.shift_end]
|
|
@@ -68058,7 +68801,7 @@ var WorkspaceDetailView = ({
|
|
|
68058
68801
|
}
|
|
68059
68802
|
}, [returnUrl]);
|
|
68060
68803
|
const handleBackNavigation = () => {
|
|
68061
|
-
if (
|
|
68804
|
+
if (isHistoricView) {
|
|
68062
68805
|
setActiveTab("monthly_history");
|
|
68063
68806
|
if (onNavigate) {
|
|
68064
68807
|
const params = new URLSearchParams();
|
|
@@ -68222,7 +68965,7 @@ var WorkspaceDetailView = ({
|
|
|
68222
68965
|
BackButtonMinimal,
|
|
68223
68966
|
{
|
|
68224
68967
|
onClick: handleBackNavigation,
|
|
68225
|
-
text: previousView === "line_monthly_history" ? "Back to Line History" : returnUrl && returnUrl.includes("monthly_history") ? "Back to Line History" : returnUrl && returnUrl.includes("/kpis/") ? "Back to KPIs" : returnUrl && returnUrl.includes("/leaderboard/") ? "Back to Leaderboard" :
|
|
68968
|
+
text: previousView === "line_monthly_history" ? "Back to Line History" : returnUrl && returnUrl.includes("monthly_history") ? "Back to Line History" : returnUrl && returnUrl.includes("/kpis/") ? "Back to KPIs" : returnUrl && returnUrl.includes("/leaderboard/") ? "Back to Leaderboard" : isHistoricView && activeTab !== "monthly_history" ? "Back to Monthly History" : "Back",
|
|
68226
68969
|
size: "default",
|
|
68227
68970
|
"aria-label": "Navigate back to previous page"
|
|
68228
68971
|
}
|
|
@@ -68399,7 +69142,8 @@ var WorkspaceDetailView = ({
|
|
|
68399
69142
|
{
|
|
68400
69143
|
workspace,
|
|
68401
69144
|
idleTimeReasons: idleTimeChartData,
|
|
68402
|
-
efficiencyLegend
|
|
69145
|
+
efficiencyLegend,
|
|
69146
|
+
hourlyCycleTimes: cycleTimeChartData
|
|
68403
69147
|
}
|
|
68404
69148
|
) }),
|
|
68405
69149
|
activeTab === "monthly_history" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -68480,7 +69224,7 @@ var WorkspaceDetailView = ({
|
|
|
68480
69224
|
animate: "animate",
|
|
68481
69225
|
children: [
|
|
68482
69226
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
|
|
68483
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-
|
|
69227
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : shouldShowCycleTimeChart ? "Cycle time trend" : "Hourly Output" }),
|
|
68484
69228
|
!isUptimeMode && /* @__PURE__ */ jsx(
|
|
68485
69229
|
"button",
|
|
68486
69230
|
{
|
|
@@ -68513,9 +69257,14 @@ var WorkspaceDetailView = ({
|
|
|
68513
69257
|
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
68514
69258
|
CycleTimeOverTimeChart,
|
|
68515
69259
|
{
|
|
68516
|
-
data:
|
|
69260
|
+
data: cycleTimeChartData,
|
|
68517
69261
|
idealCycleTime: workspace.ideal_cycle_time || 0,
|
|
68518
|
-
shiftStart: workspace.shift_start || ""
|
|
69262
|
+
shiftStart: workspace.shift_start || "",
|
|
69263
|
+
shiftEnd: workspace.shift_end || "",
|
|
69264
|
+
xAxisMode: "hourly",
|
|
69265
|
+
datasetKey: cycleTimeDatasetKey,
|
|
69266
|
+
showIdleTime: showChartIdleTime,
|
|
69267
|
+
idleTimeData: hourlyIdleMinutes
|
|
68519
69268
|
}
|
|
68520
69269
|
) : /* @__PURE__ */ jsx(
|
|
68521
69270
|
HourlyOutputChart2,
|
|
@@ -68562,7 +69311,8 @@ var WorkspaceDetailView = ({
|
|
|
68562
69311
|
{
|
|
68563
69312
|
workspace,
|
|
68564
69313
|
legend: efficiencyLegend,
|
|
68565
|
-
layout: "stack"
|
|
69314
|
+
layout: "stack",
|
|
69315
|
+
idleTimeData: idleTimeVlmEnabled ? idleTimeData : void 0
|
|
68566
69316
|
}
|
|
68567
69317
|
) : /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, legend: efficiencyLegend, className: "flex-1" }) })
|
|
68568
69318
|
] }),
|
|
@@ -68607,7 +69357,7 @@ var WorkspaceDetailView = ({
|
|
|
68607
69357
|
animate: "animate",
|
|
68608
69358
|
children: [
|
|
68609
69359
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 mb-4 flex-none", children: [
|
|
68610
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-
|
|
69360
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-bold text-gray-700", children: isUptimeMode ? "Machine Utilization" : shouldShowCycleTimeChart ? "Cycle time trend" : "Hourly Output" }),
|
|
68611
69361
|
!isUptimeMode && /* @__PURE__ */ jsx(
|
|
68612
69362
|
"button",
|
|
68613
69363
|
{
|
|
@@ -68636,9 +69386,14 @@ var WorkspaceDetailView = ({
|
|
|
68636
69386
|
) : shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
|
|
68637
69387
|
CycleTimeOverTimeChart,
|
|
68638
69388
|
{
|
|
68639
|
-
data:
|
|
69389
|
+
data: cycleTimeChartData,
|
|
68640
69390
|
idealCycleTime: workspace.ideal_cycle_time || 0,
|
|
68641
|
-
shiftStart: workspace.shift_start || ""
|
|
69391
|
+
shiftStart: workspace.shift_start || "",
|
|
69392
|
+
shiftEnd: workspace.shift_end || "",
|
|
69393
|
+
xAxisMode: "hourly",
|
|
69394
|
+
datasetKey: cycleTimeDatasetKey,
|
|
69395
|
+
showIdleTime: showChartIdleTime,
|
|
69396
|
+
idleTimeData: hourlyIdleMinutes
|
|
68642
69397
|
}
|
|
68643
69398
|
) : /* @__PURE__ */ jsx(
|
|
68644
69399
|
HourlyOutputChart2,
|
|
@@ -68690,7 +69445,8 @@ var WorkspaceDetailView = ({
|
|
|
68690
69445
|
workspace,
|
|
68691
69446
|
legend: efficiencyLegend,
|
|
68692
69447
|
layout: "grid",
|
|
68693
|
-
className: desktopBottomSectionClass
|
|
69448
|
+
className: desktopBottomSectionClass,
|
|
69449
|
+
idleTimeData: idleTimeVlmEnabled ? idleTimeData : void 0
|
|
68694
69450
|
}
|
|
68695
69451
|
) : /* @__PURE__ */ jsx("div", { className: clsx("flex min-h-0", desktopBottomSectionClass), children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, legend: efficiencyLegend, className: "flex-1" }) })
|
|
68696
69452
|
] })
|
|
@@ -68720,6 +69476,7 @@ var WorkspaceDetailView = ({
|
|
|
68720
69476
|
availableShifts: shiftConfig?.shifts?.map((s) => ({ id: s.shiftId, name: s.shiftName })),
|
|
68721
69477
|
legend: efficiencyLegend,
|
|
68722
69478
|
trendSummary: workspaceMonthlyTrend,
|
|
69479
|
+
isAssemblyWorkspace,
|
|
68723
69480
|
onDateSelect: (selectedDate, shiftId) => {
|
|
68724
69481
|
if (onDateSelect) {
|
|
68725
69482
|
onDateSelect(selectedDate, shiftId);
|
|
@@ -74807,6 +75564,11 @@ var normalizeTrend = (value) => ({
|
|
|
74807
75564
|
});
|
|
74808
75565
|
var normalizeIdleBreakdown = (value) => (value || []).map((item) => ({
|
|
74809
75566
|
reason: item?.reason?.trim() || "Unknown",
|
|
75567
|
+
reason_key: item?.reason_key?.trim() || item?.reason?.trim() || "unknown",
|
|
75568
|
+
display_name: item?.display_name?.trim() || void 0,
|
|
75569
|
+
palette_token: item?.palette_token?.trim() || void 0,
|
|
75570
|
+
icon_token: item?.icon_token?.trim() || void 0,
|
|
75571
|
+
is_known: typeof item?.is_known === "boolean" ? item.is_known : null,
|
|
74810
75572
|
percentage: normalizeNumber(item?.percentage),
|
|
74811
75573
|
total_duration_seconds: normalizeNumber(item?.total_duration_seconds),
|
|
74812
75574
|
efficiency_loss_percentage: normalizeNumber(item?.efficiency_loss_percentage),
|
|
@@ -75858,7 +76620,12 @@ var IdleBreakdownCard = React141__default.memo(({
|
|
|
75858
76620
|
const showInitialSkeleton = idle.loading && idle.lastUpdated === null;
|
|
75859
76621
|
const idleBreakdown = React141__default.useMemo(() => {
|
|
75860
76622
|
return idle.data.map((item) => ({
|
|
75861
|
-
name: item.reason?.trim() || "Unknown",
|
|
76623
|
+
name: item.display_name?.trim() || item.reason?.trim() || "Unknown",
|
|
76624
|
+
reasonKey: item.reason_key?.trim() || item.reason?.trim() || "unknown",
|
|
76625
|
+
displayName: item.display_name?.trim() || item.reason?.trim() || "Unknown",
|
|
76626
|
+
paletteToken: item.palette_token?.trim(),
|
|
76627
|
+
iconToken: item.icon_token?.trim(),
|
|
76628
|
+
isKnown: item.is_known ?? void 0,
|
|
75862
76629
|
value: toNumber3(item.percentage) || 0,
|
|
75863
76630
|
totalDurationSeconds: toNumber3(item.total_duration_seconds),
|
|
75864
76631
|
efficiencyLossPercentage: toNumber3(item.efficiency_loss_percentage),
|
|
@@ -77150,4 +77917,4 @@ var streamProxyConfig = {
|
|
|
77150
77917
|
}
|
|
77151
77918
|
};
|
|
77152
77919
|
|
|
77153
|
-
export { 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, Legend6 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, 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, getReasonColor, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isPrefetchError, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeDateKeyRange, normalizeRoleLevel, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|
|
77920
|
+
export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isLegacyConfiguration, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|