@optifye/dashboard-core 6.9.5 → 6.9.7
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.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +319 -99
- package/dist/index.mjs +320 -100
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import Hls2 from 'hls.js';
|
|
|
11
11
|
import useSWR from 'swr';
|
|
12
12
|
import { noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds, memo as memo$1 } from 'motion-utils';
|
|
13
13
|
import { getValueTransition, hover, press, isPrimaryPointer, GroupPlaybackControls, setDragLock, supportsLinearEasing, attachTimeline, isGenerator, calcGeneratorDuration, isWaapiSupportedEasing, mapEasingToNativeEasing, maxGeneratorDuration, generateLinearEasing, isBezierDefinition } from 'motion-dom';
|
|
14
|
-
import { Camera, ChevronDown, ChevronUp, Check, Map as Map$1, Video, ShieldCheck, Star, Award, ArrowLeft, X, Coffee, Plus, Clock, Calendar, Save, AlertCircle, Loader2, Minus, ArrowDown, ArrowUp,
|
|
14
|
+
import { Camera, ChevronDown, ChevronUp, Check, Map as Map$1, Video, ShieldCheck, Star, Award, ArrowLeft, X, Coffee, Plus, Clock, Calendar, Save, AlertCircle, Loader2, Minus, ArrowDown, ArrowUp, ChevronLeft, ChevronRight, Pause, Play, XCircle, Maximize2, Sparkles, TrendingUp, Settings2, CheckCircle2, RefreshCw, TrendingDown, FolderOpen, Folder, HelpCircle, Sliders, Activity, Layers, Filter, Search, Edit2, AlertTriangle, CheckCircle, Building2, Mail, Users, User, Lock, ArrowRight, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, MessageSquare, Trash2, Menu, Send, Copy, UserCheck, LogOut, Package, UserPlus, Settings, LifeBuoy, EyeOff, Eye, MoreVertical, UserCog, Zap, Shield, UserCircle } from 'lucide-react';
|
|
15
15
|
import { toast } from 'sonner';
|
|
16
16
|
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, PieChart, Pie, Cell, ReferenceLine, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
|
|
17
17
|
import { Slot } from '@radix-ui/react-slot';
|
|
@@ -9573,8 +9573,13 @@ var getAllWorkspaceDisplayNamesAsync = async (companyId, lineId) => {
|
|
|
9573
9573
|
return { ...runtimeWorkspaceDisplayNames[lineId] };
|
|
9574
9574
|
}
|
|
9575
9575
|
const allNames = {};
|
|
9576
|
-
Object.
|
|
9577
|
-
Object.
|
|
9576
|
+
Object.entries(runtimeWorkspaceDisplayNames).forEach(([lineId2, lineNames]) => {
|
|
9577
|
+
Object.entries(lineNames).forEach(([workspaceId, displayName]) => {
|
|
9578
|
+
allNames[`${lineId2}_${workspaceId}`] = displayName;
|
|
9579
|
+
if (!allNames[workspaceId]) {
|
|
9580
|
+
allNames[workspaceId] = displayName;
|
|
9581
|
+
}
|
|
9582
|
+
});
|
|
9578
9583
|
});
|
|
9579
9584
|
return allNames;
|
|
9580
9585
|
};
|
|
@@ -24699,7 +24704,11 @@ var VideoGridView = React23__default.memo(({
|
|
|
24699
24704
|
isVeryLowEfficiency,
|
|
24700
24705
|
cropping: workspaceCropping,
|
|
24701
24706
|
canvasFps: canvasConfig?.fps,
|
|
24702
|
-
displayName:
|
|
24707
|
+
displayName: (
|
|
24708
|
+
// Create line-aware lookup key: lineId_workspaceName
|
|
24709
|
+
// This ensures correct mapping when multiple lines have same workspace names
|
|
24710
|
+
displayNames[`${workspace.line_id}_${workspace.workspace_name}`] || displayNames[workspace.workspace_name] || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id)
|
|
24711
|
+
),
|
|
24703
24712
|
useRAF: canvasConfig?.useRAF,
|
|
24704
24713
|
compact: !selectedLine,
|
|
24705
24714
|
onMouseEnter: onWorkspaceHover ? () => onWorkspaceHover(workspaceId) : void 0,
|
|
@@ -24748,7 +24757,7 @@ var MapGridView = React23__default.memo(({
|
|
|
24748
24757
|
efficiency: workspace.efficiency,
|
|
24749
24758
|
action_count: workspace.action_count
|
|
24750
24759
|
});
|
|
24751
|
-
const displayName = displayNames[workspace.workspace_name] || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
24760
|
+
const displayName = displayNames[`${workspace.line_id}_${workspace.workspace_name}`] || displayNames[workspace.workspace_name] || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
24752
24761
|
const navParams = getWorkspaceNavigationParams(workspaceId, displayName, workspace.line_id);
|
|
24753
24762
|
router.push(`/workspace/${workspaceId}${navParams}`);
|
|
24754
24763
|
}, [router, displayNames]);
|
|
@@ -24777,7 +24786,7 @@ var MapGridView = React23__default.memo(({
|
|
|
24777
24786
|
if (!workspace) return null;
|
|
24778
24787
|
const workspaceId = workspace.workspace_uuid || workspace.workspace_name;
|
|
24779
24788
|
getPerformanceColor(workspace.efficiency);
|
|
24780
|
-
const workspaceDisplayName = displayNames[workspace.workspace_name] || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
24789
|
+
const workspaceDisplayName = displayNames[`${workspace.line_id}_${workspace.workspace_name}`] || displayNames[workspace.workspace_name] || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
|
|
24781
24790
|
return /* @__PURE__ */ jsx(
|
|
24782
24791
|
motion.div,
|
|
24783
24792
|
{
|
|
@@ -25623,18 +25632,30 @@ var BreakNotificationPopup = ({
|
|
|
25623
25632
|
className = "",
|
|
25624
25633
|
lineNames = {}
|
|
25625
25634
|
}) => {
|
|
25626
|
-
const [
|
|
25635
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
25636
|
+
const [visibleBreaks, setVisibleBreaks] = useState(activeBreaks);
|
|
25627
25637
|
const [currentTime, setCurrentTime] = useState(/* @__PURE__ */ new Date());
|
|
25638
|
+
useEffect(() => {
|
|
25639
|
+
setVisibleBreaks(activeBreaks);
|
|
25640
|
+
if (currentIndex >= activeBreaks.length) {
|
|
25641
|
+
setCurrentIndex(Math.max(0, activeBreaks.length - 1));
|
|
25642
|
+
}
|
|
25643
|
+
}, [activeBreaks, currentIndex]);
|
|
25628
25644
|
useEffect(() => {
|
|
25629
25645
|
const timer = setInterval(() => {
|
|
25630
25646
|
setCurrentTime(/* @__PURE__ */ new Date());
|
|
25631
25647
|
}, 6e4);
|
|
25632
25648
|
return () => clearInterval(timer);
|
|
25633
25649
|
}, []);
|
|
25634
|
-
const
|
|
25635
|
-
setIsDismissed(true);
|
|
25650
|
+
const handleDismissAll = () => {
|
|
25636
25651
|
onDismiss?.();
|
|
25637
25652
|
};
|
|
25653
|
+
const handleNext = () => {
|
|
25654
|
+
setCurrentIndex((prev) => (prev + 1) % visibleBreaks.length);
|
|
25655
|
+
};
|
|
25656
|
+
const handlePrevious = () => {
|
|
25657
|
+
setCurrentIndex((prev) => (prev - 1 + visibleBreaks.length) % visibleBreaks.length);
|
|
25658
|
+
};
|
|
25638
25659
|
const formatTime3 = (minutes) => {
|
|
25639
25660
|
const hours = Math.floor(minutes / 60);
|
|
25640
25661
|
const mins = minutes % 60;
|
|
@@ -25643,69 +25664,130 @@ var BreakNotificationPopup = ({
|
|
|
25643
25664
|
}
|
|
25644
25665
|
return `${mins}m`;
|
|
25645
25666
|
};
|
|
25646
|
-
|
|
25667
|
+
const formatTo12Hour = (time24) => {
|
|
25668
|
+
const [hours, minutes] = time24.split(":").map(Number);
|
|
25669
|
+
if (isNaN(hours) || isNaN(minutes)) {
|
|
25670
|
+
return time24;
|
|
25671
|
+
}
|
|
25672
|
+
const period = hours >= 12 ? "PM" : "AM";
|
|
25673
|
+
const hours12 = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
|
|
25674
|
+
return `${hours12}:${minutes.toString().padStart(2, "0")} ${period}`;
|
|
25675
|
+
};
|
|
25676
|
+
if (!isVisible || visibleBreaks.length === 0) {
|
|
25647
25677
|
return null;
|
|
25648
25678
|
}
|
|
25649
|
-
|
|
25650
|
-
|
|
25651
|
-
{
|
|
25652
|
-
|
|
25653
|
-
|
|
25654
|
-
|
|
25655
|
-
|
|
25656
|
-
|
|
25657
|
-
|
|
25658
|
-
|
|
25659
|
-
|
|
25660
|
-
|
|
25661
|
-
|
|
25662
|
-
|
|
25663
|
-
|
|
25664
|
-
|
|
25665
|
-
|
|
25666
|
-
|
|
25667
|
-
|
|
25668
|
-
|
|
25679
|
+
const currentBreak = visibleBreaks[currentIndex];
|
|
25680
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsxs("div", { className: `fixed right-4 top-24 z-50 max-w-xs w-full ${className}`, children: [
|
|
25681
|
+
visibleBreaks.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25682
|
+
/* @__PURE__ */ jsx(
|
|
25683
|
+
"div",
|
|
25684
|
+
{
|
|
25685
|
+
className: "absolute inset-0 bg-white rounded-lg border border-gray-300 shadow-lg",
|
|
25686
|
+
style: {
|
|
25687
|
+
transform: "translateY(12px) scale(0.94)",
|
|
25688
|
+
opacity: 0.6,
|
|
25689
|
+
zIndex: -2
|
|
25690
|
+
}
|
|
25691
|
+
}
|
|
25692
|
+
),
|
|
25693
|
+
visibleBreaks.length > 2 && /* @__PURE__ */ jsx(
|
|
25694
|
+
"div",
|
|
25695
|
+
{
|
|
25696
|
+
className: "absolute inset-0 bg-white rounded-lg border border-gray-200 shadow-md",
|
|
25697
|
+
style: {
|
|
25698
|
+
transform: "translateY(6px) scale(0.97)",
|
|
25699
|
+
opacity: 0.8,
|
|
25700
|
+
zIndex: -1
|
|
25701
|
+
}
|
|
25702
|
+
}
|
|
25703
|
+
)
|
|
25704
|
+
] }),
|
|
25705
|
+
/* @__PURE__ */ jsx(
|
|
25706
|
+
motion.div,
|
|
25707
|
+
{
|
|
25708
|
+
initial: { opacity: 0, x: 100, y: -20 },
|
|
25709
|
+
animate: { opacity: 1, x: 0, y: 0 },
|
|
25710
|
+
exit: { opacity: 0, x: -100, y: -20 },
|
|
25711
|
+
transition: { duration: 0.3, ease: "easeOut" },
|
|
25712
|
+
className: "relative z-10",
|
|
25713
|
+
children: /* @__PURE__ */ jsx("div", { className: "bg-white text-gray-900 rounded-lg border border-gray-200 shadow-xl overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
|
|
25714
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 flex-1", children: [
|
|
25715
|
+
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(AxelOrb, { size: "md" }) }),
|
|
25716
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
25717
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
|
|
25718
|
+
/* @__PURE__ */ jsxs("h4", { className: "font-semibold text-sm text-gray-900", children: [
|
|
25719
|
+
currentBreak.remarks || "Break",
|
|
25720
|
+
lineNames[currentBreak.lineId] && /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-500 ml-1", children: [
|
|
25721
|
+
"\u2022 ",
|
|
25722
|
+
lineNames[currentBreak.lineId]
|
|
25723
|
+
] })
|
|
25724
|
+
] }),
|
|
25725
|
+
/* @__PURE__ */ jsx(Coffee, { className: "w-4 h-4 text-amber-500" })
|
|
25669
25726
|
] }),
|
|
25670
|
-
/* @__PURE__ */
|
|
25671
|
-
|
|
25672
|
-
|
|
25673
|
-
|
|
25674
|
-
|
|
25675
|
-
"
|
|
25676
|
-
|
|
25677
|
-
|
|
25678
|
-
|
|
25679
|
-
|
|
25680
|
-
|
|
25681
|
-
"
|
|
25682
|
-
|
|
25683
|
-
|
|
25684
|
-
|
|
25685
|
-
|
|
25686
|
-
|
|
25687
|
-
|
|
25688
|
-
width: `${Math.min(100, Math.max(0, breakItem.elapsedMinutes / breakItem.duration * 100))}%`
|
|
25727
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-600 mb-1", children: [
|
|
25728
|
+
formatTo12Hour(currentBreak.startTime),
|
|
25729
|
+
" - ",
|
|
25730
|
+
formatTo12Hour(currentBreak.endTime)
|
|
25731
|
+
] }),
|
|
25732
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 mb-2", children: [
|
|
25733
|
+
formatTime3(currentBreak.elapsedMinutes),
|
|
25734
|
+
" elapsed of ",
|
|
25735
|
+
formatTime3(currentBreak.duration),
|
|
25736
|
+
" total"
|
|
25737
|
+
] }),
|
|
25738
|
+
/* @__PURE__ */ jsx("div", { className: "w-full bg-gray-200 rounded-full h-1.5", children: /* @__PURE__ */ jsx(
|
|
25739
|
+
"div",
|
|
25740
|
+
{
|
|
25741
|
+
className: "h-1.5 bg-blue-500 rounded-full transition-all duration-1000",
|
|
25742
|
+
style: {
|
|
25743
|
+
width: `${Math.min(100, Math.max(0, currentBreak.elapsedMinutes / currentBreak.duration * 100))}%`
|
|
25744
|
+
}
|
|
25689
25745
|
}
|
|
25690
|
-
}
|
|
25691
|
-
|
|
25692
|
-
|
|
25693
|
-
|
|
25694
|
-
|
|
25695
|
-
|
|
25696
|
-
|
|
25697
|
-
|
|
25698
|
-
|
|
25699
|
-
|
|
25700
|
-
|
|
25701
|
-
|
|
25702
|
-
|
|
25703
|
-
|
|
25704
|
-
|
|
25705
|
-
|
|
25706
|
-
|
|
25707
|
-
|
|
25708
|
-
|
|
25746
|
+
) }),
|
|
25747
|
+
visibleBreaks.length > 1 && /* @__PURE__ */ jsx("div", { className: "mt-3 pt-2 border-t border-gray-100", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
25748
|
+
/* @__PURE__ */ jsx(
|
|
25749
|
+
"button",
|
|
25750
|
+
{
|
|
25751
|
+
onClick: handlePrevious,
|
|
25752
|
+
className: "p-1 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full transition-colors",
|
|
25753
|
+
"aria-label": "Previous break",
|
|
25754
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "w-4 h-4" })
|
|
25755
|
+
}
|
|
25756
|
+
),
|
|
25757
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500", children: [
|
|
25758
|
+
currentIndex + 1,
|
|
25759
|
+
" of ",
|
|
25760
|
+
visibleBreaks.length,
|
|
25761
|
+
" breaks"
|
|
25762
|
+
] }),
|
|
25763
|
+
/* @__PURE__ */ jsx(
|
|
25764
|
+
"button",
|
|
25765
|
+
{
|
|
25766
|
+
onClick: handleNext,
|
|
25767
|
+
className: "p-1 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full transition-colors",
|
|
25768
|
+
"aria-label": "Next break",
|
|
25769
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4" })
|
|
25770
|
+
}
|
|
25771
|
+
)
|
|
25772
|
+
] }) })
|
|
25773
|
+
] })
|
|
25774
|
+
] }),
|
|
25775
|
+
/* @__PURE__ */ jsx(
|
|
25776
|
+
"button",
|
|
25777
|
+
{
|
|
25778
|
+
onClick: handleDismissAll,
|
|
25779
|
+
onTouchStart: () => {
|
|
25780
|
+
},
|
|
25781
|
+
className: "ml-2 text-gray-400 hover:text-gray-600 transition-colors p-2 sm:p-1 rounded-full hover:bg-gray-100 active:bg-gray-200 touch-manipulation min-h-[44px] min-w-[44px] sm:min-h-0 sm:min-w-0 flex items-center justify-center flex-shrink-0",
|
|
25782
|
+
"aria-label": "Dismiss all breaks",
|
|
25783
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4 sm:w-3 sm:h-3" })
|
|
25784
|
+
}
|
|
25785
|
+
)
|
|
25786
|
+
] }) }) })
|
|
25787
|
+
},
|
|
25788
|
+
currentIndex
|
|
25789
|
+
)
|
|
25790
|
+
] }) });
|
|
25709
25791
|
};
|
|
25710
25792
|
async function fetchAxelNotifications() {
|
|
25711
25793
|
try {
|
|
@@ -26669,8 +26751,11 @@ var VideoPlayer = React23__default.forwardRef(({
|
|
|
26669
26751
|
experimentalLLHLS: false,
|
|
26670
26752
|
// Disable Low Latency HLS for VOD
|
|
26671
26753
|
// Connection settings
|
|
26672
|
-
|
|
26673
|
-
//
|
|
26754
|
+
// Chrome 130+ started throwing "Cannot perform Construct on a detached ArrayBuffer"
|
|
26755
|
+
// whenever the transmux worker tried to rehydrate transferred buffers that originated
|
|
26756
|
+
// from Blob-based playlists. Disabling the worker keeps playback stable at the cost
|
|
26757
|
+
// of slightly higher main-thread usage, which is acceptable for the dashboard usage.
|
|
26758
|
+
enableWorker: false,
|
|
26674
26759
|
progressive: true,
|
|
26675
26760
|
// Progressive download
|
|
26676
26761
|
// Adaptive bitrate settings (if multi-quality available)
|
|
@@ -27680,10 +27765,30 @@ function useWorkspaceCrop(workspaceId) {
|
|
|
27680
27765
|
}, [workspaceId]);
|
|
27681
27766
|
return { crop, isLoading, error };
|
|
27682
27767
|
}
|
|
27683
|
-
var
|
|
27768
|
+
var parseCycleTime = (value) => {
|
|
27769
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
27770
|
+
return value;
|
|
27771
|
+
}
|
|
27772
|
+
if (typeof value === "string") {
|
|
27773
|
+
const parsed = Number(value);
|
|
27774
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
27775
|
+
}
|
|
27776
|
+
return null;
|
|
27777
|
+
};
|
|
27778
|
+
var extractCycleTimeSeconds = (clip) => {
|
|
27779
|
+
return parseCycleTime(clip?.cycleTimeSeconds) ?? parseCycleTime(clip?.cycle_time_seconds) ?? parseCycleTime(clip?.duration) ?? parseCycleTime(clip?.original_task_metadata?.cycle_time) ?? null;
|
|
27780
|
+
};
|
|
27781
|
+
var getSeverityIcon = (severity, categoryId, cycleTimeSeconds, targetCycleTime) => {
|
|
27684
27782
|
if (categoryId === "idle_time" || categoryId === "low_value" || categoryId === "longest-idles") {
|
|
27685
27783
|
return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3 w-3 text-red-500" });
|
|
27686
27784
|
}
|
|
27785
|
+
if (categoryId === "cycle_completion" && targetCycleTime && targetCycleTime > 0 && cycleTimeSeconds !== null && cycleTimeSeconds !== void 0) {
|
|
27786
|
+
if (cycleTimeSeconds <= targetCycleTime) {
|
|
27787
|
+
return /* @__PURE__ */ jsx(CheckCircle, { className: "h-3 w-3 text-green-500" });
|
|
27788
|
+
} else {
|
|
27789
|
+
return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3 w-3 text-red-500" });
|
|
27790
|
+
}
|
|
27791
|
+
}
|
|
27687
27792
|
switch (severity) {
|
|
27688
27793
|
case "high":
|
|
27689
27794
|
return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3 w-3 text-red-500" });
|
|
@@ -27738,7 +27843,8 @@ var FileManagerFilters = ({
|
|
|
27738
27843
|
workspaceId,
|
|
27739
27844
|
date,
|
|
27740
27845
|
shift,
|
|
27741
|
-
className = ""
|
|
27846
|
+
className = "",
|
|
27847
|
+
targetCycleTime = null
|
|
27742
27848
|
}) => {
|
|
27743
27849
|
const [expandedNodes, setExpandedNodes] = useState(/* @__PURE__ */ new Set());
|
|
27744
27850
|
const [startTime, setStartTime] = useState("");
|
|
@@ -27758,6 +27864,26 @@ var FileManagerFilters = ({
|
|
|
27758
27864
|
const [percentileCounts, setPercentileCounts] = useState({});
|
|
27759
27865
|
const [percentileClips, setPercentileClips] = useState({});
|
|
27760
27866
|
const [loadingPercentile, setLoadingPercentile] = useState(false);
|
|
27867
|
+
const resolvedTargetCycleTime = targetCycleTime && targetCycleTime > 0 ? targetCycleTime : null;
|
|
27868
|
+
const getClipBadge = useCallback((node) => {
|
|
27869
|
+
if (node.categoryId === "idle_time" || node.categoryId === "low_value") {
|
|
27870
|
+
return { text: "Idle", className: "bg-red-100 text-red-700" };
|
|
27871
|
+
}
|
|
27872
|
+
if (node.categoryId === "cycle_completion" && resolvedTargetCycleTime && node.cycleTimeSeconds !== void 0 && node.cycleTimeSeconds !== null) {
|
|
27873
|
+
const isFast = node.cycleTimeSeconds <= resolvedTargetCycleTime;
|
|
27874
|
+
return {
|
|
27875
|
+
text: isFast ? "Fast" : "Slow",
|
|
27876
|
+
className: isFast ? "bg-green-100 text-green-700" : "bg-red-100 text-red-700"
|
|
27877
|
+
};
|
|
27878
|
+
}
|
|
27879
|
+
if (node.severity === "high") {
|
|
27880
|
+
return { text: "Slow", className: "bg-red-100 text-red-700" };
|
|
27881
|
+
}
|
|
27882
|
+
if (node.severity === "medium") {
|
|
27883
|
+
return { text: "Average", className: "bg-yellow-100 text-yellow-700" };
|
|
27884
|
+
}
|
|
27885
|
+
return { text: "Fast", className: "bg-green-100 text-green-700" };
|
|
27886
|
+
}, [resolvedTargetCycleTime]);
|
|
27761
27887
|
const fetchClipMetadata = useCallback(async (categoryId, page = 1) => {
|
|
27762
27888
|
if (!workspaceId || !date || shift === void 0) {
|
|
27763
27889
|
console.warn("[FileManager] Missing required params for clip metadata fetch");
|
|
@@ -27995,18 +28121,20 @@ var FileManagerFilters = ({
|
|
|
27995
28121
|
timeZone: timezone
|
|
27996
28122
|
// Use database timezone for display
|
|
27997
28123
|
});
|
|
28124
|
+
const cycleTime = extractCycleTimeSeconds(clip);
|
|
27998
28125
|
return {
|
|
27999
28126
|
id: clip.id,
|
|
28000
28127
|
label: `${timeString}${clip.duration && category.id !== "idle_time" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`,
|
|
28001
28128
|
type: "video",
|
|
28002
|
-
icon: getSeverityIcon(clip.severity, category.id),
|
|
28129
|
+
icon: getSeverityIcon(clip.severity, category.id, cycleTime, resolvedTargetCycleTime),
|
|
28003
28130
|
timestamp: clip.clip_timestamp,
|
|
28004
28131
|
severity: clip.severity,
|
|
28005
28132
|
clipId: clip.clipId,
|
|
28006
28133
|
// Store stable UUID for navigation
|
|
28007
28134
|
categoryId: category.id,
|
|
28008
|
-
clipPosition: index + 1
|
|
28135
|
+
clipPosition: index + 1,
|
|
28009
28136
|
// Store 1-based position
|
|
28137
|
+
cycleTimeSeconds: cycleTime
|
|
28010
28138
|
};
|
|
28011
28139
|
});
|
|
28012
28140
|
regularCategoryNodes.push({
|
|
@@ -28045,15 +28173,17 @@ var FileManagerFilters = ({
|
|
|
28045
28173
|
minute: "2-digit",
|
|
28046
28174
|
timeZone: timezone
|
|
28047
28175
|
});
|
|
28176
|
+
const cycleTime = extractCycleTimeSeconds(clip);
|
|
28048
28177
|
return {
|
|
28049
28178
|
id: clip.id,
|
|
28050
28179
|
label: `${timeString}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
|
|
28051
28180
|
type: "video",
|
|
28052
|
-
icon: getSeverityIcon(clip.severity, "fast-cycles"),
|
|
28181
|
+
icon: getSeverityIcon(clip.severity, "fast-cycles", cycleTime, resolvedTargetCycleTime),
|
|
28053
28182
|
timestamp: clip.creation_timestamp,
|
|
28054
28183
|
severity: clip.severity,
|
|
28055
28184
|
clipId: clip.id,
|
|
28056
|
-
categoryId: "fast-cycles"
|
|
28185
|
+
categoryId: "fast-cycles",
|
|
28186
|
+
cycleTimeSeconds: cycleTime
|
|
28057
28187
|
};
|
|
28058
28188
|
})
|
|
28059
28189
|
},
|
|
@@ -28075,15 +28205,17 @@ var FileManagerFilters = ({
|
|
|
28075
28205
|
minute: "2-digit",
|
|
28076
28206
|
timeZone: timezone
|
|
28077
28207
|
});
|
|
28208
|
+
const cycleTime = extractCycleTimeSeconds(clip);
|
|
28078
28209
|
return {
|
|
28079
28210
|
id: clip.id,
|
|
28080
28211
|
label: `${timeString}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
|
|
28081
28212
|
type: "video",
|
|
28082
|
-
icon: getSeverityIcon(clip.severity, "slow-cycles"),
|
|
28213
|
+
icon: getSeverityIcon(clip.severity, "slow-cycles", cycleTime, resolvedTargetCycleTime),
|
|
28083
28214
|
timestamp: clip.creation_timestamp,
|
|
28084
28215
|
severity: clip.severity,
|
|
28085
28216
|
clipId: clip.id,
|
|
28086
|
-
categoryId: "slow-cycles"
|
|
28217
|
+
categoryId: "slow-cycles",
|
|
28218
|
+
cycleTimeSeconds: cycleTime
|
|
28087
28219
|
};
|
|
28088
28220
|
})
|
|
28089
28221
|
}
|
|
@@ -28204,7 +28336,10 @@ var FileManagerFilters = ({
|
|
|
28204
28336
|
/* @__PURE__ */ jsx("div", { className: `font-semibold tracking-tight ${node.type === "category" || node.type === "percentile-category" ? "text-slate-800 text-sm" : "text-slate-700 text-xs"} ${isCurrentVideo ? "text-blue-700 font-bold" : ""} group-hover:text-slate-900 transition-colors duration-200`, children: node.label }),
|
|
28205
28337
|
node.type === "category" && categories.find((c) => c.id === node.id)?.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: categories.find((c) => c.id === node.id)?.description }),
|
|
28206
28338
|
node.type === "percentile-category" && node.subtitle && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: node.subtitle }),
|
|
28207
|
-
node.type === "video" && node.severity
|
|
28339
|
+
node.type === "video" && (node.severity || node.categoryId === "cycle_completion" || node.categoryId === "idle_time" || node.categoryId === "low_value") && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 capitalize mt-0.5 font-medium", children: (() => {
|
|
28340
|
+
const badge = getClipBadge(node);
|
|
28341
|
+
return /* @__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 });
|
|
28342
|
+
})() })
|
|
28208
28343
|
] }),
|
|
28209
28344
|
node.count !== void 0 && (node.type === "category" || node.type === "percentile-category") && /* @__PURE__ */ jsx("div", { className: "flex items-center ml-2", children: /* @__PURE__ */ jsx("span", { className: `px-2.5 py-1 text-sm font-bold rounded-lg shadow-sm border backdrop-blur-sm flex-shrink-0 group-hover:scale-105 transition-all duration-200 ${colorClasses ? `${colorClasses.bg} ${colorClasses.text} ${colorClasses.border} bg-opacity-80` : "bg-slate-100/80 text-slate-700 border-slate-200/60"}`, children: node.count }) })
|
|
28210
28345
|
] })
|
|
@@ -28871,6 +29006,19 @@ var BottlenecksContent = ({
|
|
|
28871
29006
|
}
|
|
28872
29007
|
}, [shift, date, timezone, shiftConfig, workspaceId]);
|
|
28873
29008
|
const { crop: workspaceCrop} = useWorkspaceCrop(workspaceId);
|
|
29009
|
+
const { metrics: workspaceMetrics } = useWorkspaceDetailedMetrics(
|
|
29010
|
+
workspaceId,
|
|
29011
|
+
date,
|
|
29012
|
+
shift !== void 0 && shift !== null ? Number(shift) : void 0
|
|
29013
|
+
);
|
|
29014
|
+
const workspaceTargetCycleTimeRaw = workspaceMetrics?.ideal_cycle_time;
|
|
29015
|
+
const workspaceTargetCycleTime = (() => {
|
|
29016
|
+
if (workspaceTargetCycleTimeRaw === void 0 || workspaceTargetCycleTimeRaw === null) {
|
|
29017
|
+
return null;
|
|
29018
|
+
}
|
|
29019
|
+
const numericValue = typeof workspaceTargetCycleTimeRaw === "number" ? workspaceTargetCycleTimeRaw : Number(workspaceTargetCycleTimeRaw);
|
|
29020
|
+
return Number.isFinite(numericValue) ? numericValue : null;
|
|
29021
|
+
})();
|
|
28874
29022
|
const videoRef = useRef(null);
|
|
28875
29023
|
const [initialFilter, setInitialFilter] = useState("");
|
|
28876
29024
|
const currentIndexRef = useRef(0);
|
|
@@ -29813,21 +29961,33 @@ var BottlenecksContent = ({
|
|
|
29813
29961
|
return () => window.removeEventListener("keydown", handleEscape);
|
|
29814
29962
|
}
|
|
29815
29963
|
}, [isFullscreen, exitFullscreen]);
|
|
29816
|
-
const getClipTypeLabel = (video) => {
|
|
29964
|
+
const getClipTypeLabel = useCallback((video) => {
|
|
29817
29965
|
if (!video) return "";
|
|
29818
29966
|
const currentFilter = activeFilterRef.current;
|
|
29967
|
+
const targetCycleTime = workspaceTargetCycleTime || 0;
|
|
29819
29968
|
if (isPercentileCategory(currentFilter)) {
|
|
29820
29969
|
const percentileValue = video.percentile?.toFixed(1);
|
|
29821
|
-
|
|
29822
|
-
|
|
29823
|
-
|
|
29824
|
-
|
|
29825
|
-
|
|
29826
|
-
|
|
29827
|
-
|
|
29828
|
-
|
|
29829
|
-
|
|
29970
|
+
const cycleTime = video.cycle_time_seconds || 0;
|
|
29971
|
+
if (currentFilter === "fast-cycles" || currentFilter === "slow-cycles") {
|
|
29972
|
+
if (targetCycleTime > 0 && cycleTime > 0) {
|
|
29973
|
+
if (cycleTime < targetCycleTime) {
|
|
29974
|
+
return `\u26A1 Fast Cycle ${percentileValue ? `(${percentileValue}%)` : ""}`;
|
|
29975
|
+
} else {
|
|
29976
|
+
return `\u{1F40C} Slow Cycle ${percentileValue ? `(${percentileValue}%)` : ""}`;
|
|
29977
|
+
}
|
|
29978
|
+
} else {
|
|
29979
|
+
switch (currentFilter) {
|
|
29980
|
+
case "fast-cycles":
|
|
29981
|
+
return `\u26A1 Fast Cycle ${percentileValue ? `(${percentileValue}%)` : ""}`;
|
|
29982
|
+
case "slow-cycles":
|
|
29983
|
+
return `\u{1F40C} Slow Cycle ${percentileValue ? `(${percentileValue}%)` : ""}`;
|
|
29984
|
+
}
|
|
29985
|
+
}
|
|
29830
29986
|
}
|
|
29987
|
+
if (currentFilter === "longest-idles") {
|
|
29988
|
+
return `\u23F0 Long Idle ${percentileValue ? `(${percentileValue}%)` : ""}`;
|
|
29989
|
+
}
|
|
29990
|
+
return video.description || "Performance Clip";
|
|
29831
29991
|
}
|
|
29832
29992
|
switch (video.type) {
|
|
29833
29993
|
case "low_value":
|
|
@@ -29846,7 +30006,7 @@ var BottlenecksContent = ({
|
|
|
29846
30006
|
default:
|
|
29847
30007
|
return video.description || "";
|
|
29848
30008
|
}
|
|
29849
|
-
};
|
|
30009
|
+
}, [workspaceTargetCycleTime]);
|
|
29850
30010
|
if (!dashboardConfig?.s3Config) {
|
|
29851
30011
|
return /* @__PURE__ */ jsxs("div", { className: "flex-grow p-4 flex flex-col items-center justify-center h-[calc(100vh-12rem)] text-center", children: [
|
|
29852
30012
|
/* @__PURE__ */ jsx(XCircle, { className: "w-12 h-12 text-red-400 mb-3" }),
|
|
@@ -30118,12 +30278,32 @@ var BottlenecksContent = ({
|
|
|
30118
30278
|
badgeText = "Idle";
|
|
30119
30279
|
badgeColor = "bg-red-100 text-red-700";
|
|
30120
30280
|
} else {
|
|
30121
|
-
|
|
30122
|
-
|
|
30123
|
-
|
|
30281
|
+
const parseCycleTime2 = (value) => {
|
|
30282
|
+
if (typeof value === "number") return isNaN(value) ? null : value;
|
|
30283
|
+
if (typeof value === "string") {
|
|
30284
|
+
const parsed = parseFloat(value);
|
|
30285
|
+
return isNaN(parsed) ? null : parsed;
|
|
30286
|
+
}
|
|
30287
|
+
return null;
|
|
30288
|
+
};
|
|
30289
|
+
const clipCycleTime = parseCycleTime2(clip.cycle_time_seconds) ?? parseCycleTime2(clip.duration) ?? parseCycleTime2(clip.original_task_metadata?.cycle_time);
|
|
30290
|
+
const targetCycleTime = workspaceTargetCycleTime && workspaceTargetCycleTime > 0 ? workspaceTargetCycleTime : null;
|
|
30291
|
+
if (clipCycleTime && targetCycleTime) {
|
|
30292
|
+
if (clipCycleTime <= targetCycleTime) {
|
|
30293
|
+
badgeText = "Fast";
|
|
30294
|
+
badgeColor = "bg-green-100 text-green-700";
|
|
30295
|
+
} else {
|
|
30296
|
+
badgeText = "Slow";
|
|
30297
|
+
badgeColor = "bg-red-100 text-red-700";
|
|
30298
|
+
}
|
|
30124
30299
|
} else {
|
|
30125
|
-
|
|
30126
|
-
|
|
30300
|
+
if (clip.severity === "high" || clip.duration && clip.duration > 60) {
|
|
30301
|
+
badgeText = "Slow";
|
|
30302
|
+
badgeColor = "bg-red-100 text-red-700";
|
|
30303
|
+
} else {
|
|
30304
|
+
badgeText = "Average";
|
|
30305
|
+
badgeColor = "bg-yellow-100 text-yellow-700";
|
|
30306
|
+
}
|
|
30127
30307
|
}
|
|
30128
30308
|
}
|
|
30129
30309
|
return /* @__PURE__ */ jsx(
|
|
@@ -30166,6 +30346,7 @@ var BottlenecksContent = ({
|
|
|
30166
30346
|
workspaceId,
|
|
30167
30347
|
date: date || getOperationalDate(timezone),
|
|
30168
30348
|
shift: effectiveShift,
|
|
30349
|
+
targetCycleTime: workspaceTargetCycleTime,
|
|
30169
30350
|
onFilterChange: (filterId) => {
|
|
30170
30351
|
updateActiveFilter(filterId);
|
|
30171
30352
|
const category = categoriesToShow.find((cat) => cat.type === filterId);
|
|
@@ -41453,7 +41634,6 @@ function HomeView({
|
|
|
41453
41634
|
factoryName = "Simba Beer - Line 1"
|
|
41454
41635
|
}) {
|
|
41455
41636
|
const [isHydrated, setIsHydrated] = useState(false);
|
|
41456
|
-
const [selectedLineId, setSelectedLineId] = useState(factoryViewId);
|
|
41457
41637
|
const [isChangingFilter, setIsChangingFilter] = useState(false);
|
|
41458
41638
|
const [errorMessage, setErrorMessage] = useState(null);
|
|
41459
41639
|
const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
|
|
@@ -41470,9 +41650,36 @@ function HomeView({
|
|
|
41470
41650
|
}
|
|
41471
41651
|
return [factoryViewId, ...allLineIds];
|
|
41472
41652
|
}, [factoryViewId, allLineIds, isSupervisor, hasMultipleLines]);
|
|
41653
|
+
const LINE_FILTER_STORAGE_KEY = "optifye_home_line_filter";
|
|
41654
|
+
const [selectedLineId, setSelectedLineId] = useState(() => {
|
|
41655
|
+
if (typeof window === "undefined") {
|
|
41656
|
+
return factoryViewId;
|
|
41657
|
+
}
|
|
41658
|
+
try {
|
|
41659
|
+
const savedLineId = sessionStorage.getItem(LINE_FILTER_STORAGE_KEY);
|
|
41660
|
+
if (savedLineId) {
|
|
41661
|
+
const allAvailableIds = [factoryViewId, ...allLineIds];
|
|
41662
|
+
if (allAvailableIds.includes(savedLineId)) {
|
|
41663
|
+
return savedLineId;
|
|
41664
|
+
}
|
|
41665
|
+
}
|
|
41666
|
+
} catch (error) {
|
|
41667
|
+
console.warn("Failed to read line filter from sessionStorage:", error);
|
|
41668
|
+
}
|
|
41669
|
+
return factoryViewId;
|
|
41670
|
+
});
|
|
41473
41671
|
useEffect(() => {
|
|
41474
41672
|
if (user) {
|
|
41475
41673
|
if (isSupervisor && allLineIds.length > 0) {
|
|
41674
|
+
try {
|
|
41675
|
+
const savedLineId = sessionStorage.getItem(LINE_FILTER_STORAGE_KEY);
|
|
41676
|
+
if (savedLineId && allLineIds.includes(savedLineId)) {
|
|
41677
|
+
setSelectedLineId(savedLineId);
|
|
41678
|
+
return;
|
|
41679
|
+
}
|
|
41680
|
+
} catch (error) {
|
|
41681
|
+
console.warn("Failed to read line filter from sessionStorage:", error);
|
|
41682
|
+
}
|
|
41476
41683
|
setSelectedLineId(allLineIds[0]);
|
|
41477
41684
|
}
|
|
41478
41685
|
}
|
|
@@ -41507,11 +41714,12 @@ function HomeView({
|
|
|
41507
41714
|
};
|
|
41508
41715
|
initDisplayNames();
|
|
41509
41716
|
}, [selectedLineId, factoryViewId, allLineIds]);
|
|
41717
|
+
const displayNameLineId = selectedLineId === factoryViewId ? void 0 : selectedLineId;
|
|
41510
41718
|
const {
|
|
41511
41719
|
displayNames: workspaceDisplayNames,
|
|
41512
41720
|
loading: displayNamesLoading,
|
|
41513
41721
|
error: displayNamesError
|
|
41514
|
-
} = useWorkspaceDisplayNames(
|
|
41722
|
+
} = useWorkspaceDisplayNames(displayNameLineId, void 0);
|
|
41515
41723
|
useCallback(() => {
|
|
41516
41724
|
console.log("Refetching KPIs after line metrics update");
|
|
41517
41725
|
}, []);
|
|
@@ -41552,6 +41760,12 @@ function HomeView({
|
|
|
41552
41760
|
}
|
|
41553
41761
|
return allActiveBreaks.filter((breakItem) => breakItem.lineId === selectedLineId);
|
|
41554
41762
|
}, [allActiveBreaks, selectedLineId, factoryViewId]);
|
|
41763
|
+
const [breakNotificationsDismissed, setBreakNotificationsDismissed] = useState(false);
|
|
41764
|
+
useEffect(() => {
|
|
41765
|
+
if (activeBreaks.length > 0) {
|
|
41766
|
+
setBreakNotificationsDismissed(false);
|
|
41767
|
+
}
|
|
41768
|
+
}, [activeBreaks.length]);
|
|
41555
41769
|
const showBottleneckNotification = useCallback(async (bottleneck) => {
|
|
41556
41770
|
try {
|
|
41557
41771
|
console.log("\u{1F514} [Notification] Raw bottleneck data:", bottleneck);
|
|
@@ -41850,7 +42064,12 @@ function HomeView({
|
|
|
41850
42064
|
const handleLineChange = useCallback((value) => {
|
|
41851
42065
|
setIsChangingFilter(true);
|
|
41852
42066
|
setSelectedLineId(value);
|
|
41853
|
-
|
|
42067
|
+
try {
|
|
42068
|
+
sessionStorage.setItem(LINE_FILTER_STORAGE_KEY, value);
|
|
42069
|
+
} catch (error) {
|
|
42070
|
+
console.warn("Failed to save line filter to sessionStorage:", error);
|
|
42071
|
+
}
|
|
42072
|
+
}, [LINE_FILTER_STORAGE_KEY]);
|
|
41854
42073
|
useEffect(() => {
|
|
41855
42074
|
if (!metricsLoading && !kpisLoading && isChangingFilter) {
|
|
41856
42075
|
if (workspaceMetrics.length > 0 || selectedLineId === factoryViewId) {
|
|
@@ -41875,7 +42094,7 @@ function HomeView({
|
|
|
41875
42094
|
/* @__PURE__ */ jsx(SelectContent, { className: "z-50 bg-white shadow-lg border border-gray-200 rounded-md text-xs sm:text-sm", children: availableLineIds.map((id3) => /* @__PURE__ */ jsx(SelectItem, { value: id3, children: lineNames[id3] || (id3 === factoryViewId ? "All Lines" : `Line ${id3.substring(0, 4)}`) }, id3)) })
|
|
41876
42095
|
] });
|
|
41877
42096
|
}, [availableLineIds, handleLineChange, selectedLineId, lineNames, factoryViewId, allLineIds.length]);
|
|
41878
|
-
const isInitialLoading = !isHydrated || displayNamesLoading || !displayNamesInitialized
|
|
42097
|
+
const isInitialLoading = !isHydrated || displayNamesLoading || !displayNamesInitialized;
|
|
41879
42098
|
const isDataLoading = metricsLoading || kpisLoading;
|
|
41880
42099
|
if (isInitialLoading) {
|
|
41881
42100
|
return /* @__PURE__ */ jsx(LoadingPageCmp, { message: "Loading Dashboard..." });
|
|
@@ -41963,7 +42182,8 @@ function HomeView({
|
|
|
41963
42182
|
{
|
|
41964
42183
|
activeBreaks,
|
|
41965
42184
|
lineNames,
|
|
41966
|
-
isVisible: !breaksLoading && !breaksError
|
|
42185
|
+
isVisible: !breaksLoading && !breaksError && !breakNotificationsDismissed,
|
|
42186
|
+
onDismiss: () => setBreakNotificationsDismissed(true)
|
|
41967
42187
|
}
|
|
41968
42188
|
),
|
|
41969
42189
|
/* @__PURE__ */ jsx(
|