@optifye/dashboard-core 6.10.14 → 6.10.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1 -12
- package/dist/index.d.ts +1 -12
- package/dist/index.js +180 -2137
- package/dist/index.mjs +185 -2141
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import React24__default, { createContext, useRef, useCallback, useState, useMemo
|
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { useRouter } from 'next/router';
|
|
5
5
|
import { fromZonedTime, toZonedTime, formatInTimeZone } from 'date-fns-tz';
|
|
6
|
-
import {
|
|
6
|
+
import { subDays, format, parseISO, isValid, addMinutes, differenceInMinutes, formatDistanceToNow, isToday, isFuture, addDays, startOfDay, isBefore, startOfMonth, endOfMonth, eachDayOfInterval, getDay, isSameDay, isWithinInterval, subMonths, addMonths } from 'date-fns';
|
|
7
7
|
import mixpanel from 'mixpanel-browser';
|
|
8
8
|
import { EventEmitter } from 'events';
|
|
9
9
|
import { createClient, REALTIME_SUBSCRIBE_STATES } from '@supabase/supabase-js';
|
|
@@ -11,13 +11,13 @@ import Hls3, { Events, ErrorTypes } 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, ChevronLeft, ChevronRight, TrendingUp, Sparkles, Pause, Play, Wrench, XCircle, Package, UserX, Zap, HelpCircle, AlertTriangle, Tag, Palette, CheckCircle2, RefreshCw, TrendingDown, FolderOpen, Folder, Sliders, Activity, Layers, Filter, Search, Edit2, ArrowRight, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3,
|
|
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, TrendingUp, Sparkles, Pause, Play, Wrench, XCircle, Package, UserX, Zap, HelpCircle, AlertTriangle, Tag, Palette, CheckCircle2, RefreshCw, TrendingDown, FolderOpen, Folder, Sliders, Activity, Layers, Filter, Search, Edit2, ArrowRight, CheckCircle, User, Users, Shield, Building2, Mail, Lock, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, UserPlus, UserCog, Trash2, Eye, MoreVertical, BarChart3, UserCheck, LogOut, MessageSquare, Settings, LifeBuoy, EyeOff, UserCircle } from 'lucide-react';
|
|
15
15
|
import { toast } from 'sonner';
|
|
16
|
-
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, ReferenceLine, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, PieChart, Pie, Cell
|
|
16
|
+
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, ReferenceLine, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, PieChart, Pie, Cell } from 'recharts';
|
|
17
17
|
import { Slot } from '@radix-ui/react-slot';
|
|
18
18
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
19
19
|
import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
|
|
20
|
-
import { XMarkIcon, ArrowRightIcon, HomeIcon, TrophyIcon, ChartBarIcon, LightBulbIcon, AdjustmentsHorizontalIcon, ClockIcon, UsersIcon, TicketIcon, CubeIcon,
|
|
20
|
+
import { XMarkIcon, ArrowRightIcon, HomeIcon, TrophyIcon, ChartBarIcon, LightBulbIcon, AdjustmentsHorizontalIcon, ClockIcon, UsersIcon, TicketIcon, CubeIcon, QuestionMarkCircleIcon, HeartIcon, UserCircleIcon, ExclamationCircleIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ChevronDownIcon, Bars3Icon, CheckCircleIcon, ChatBubbleLeftRightIcon, ArrowLeftIcon, XCircleIcon, FunnelIcon, CalendarIcon, ChevronRightIcon, ChevronLeftIcon, InformationCircleIcon, PlayCircleIcon } from '@heroicons/react/24/outline';
|
|
21
21
|
import { CheckIcon } from '@heroicons/react/24/solid';
|
|
22
22
|
import html2canvas from 'html2canvas';
|
|
23
23
|
import jsPDF, { jsPDF as jsPDF$1 } from 'jspdf';
|
|
@@ -13289,7 +13289,6 @@ function useAccessControl() {
|
|
|
13289
13289
|
"/shifts",
|
|
13290
13290
|
"/supervisor-management",
|
|
13291
13291
|
"/skus",
|
|
13292
|
-
"/ai-agent",
|
|
13293
13292
|
"/help",
|
|
13294
13293
|
"/health",
|
|
13295
13294
|
"/profile",
|
|
@@ -13305,7 +13304,6 @@ function useAccessControl() {
|
|
|
13305
13304
|
"/shifts",
|
|
13306
13305
|
"/supervisor-management",
|
|
13307
13306
|
"/skus",
|
|
13308
|
-
"/ai-agent",
|
|
13309
13307
|
"/help",
|
|
13310
13308
|
"/health",
|
|
13311
13309
|
"/profile",
|
|
@@ -13321,7 +13319,6 @@ function useAccessControl() {
|
|
|
13321
13319
|
"/shifts",
|
|
13322
13320
|
"/supervisor-management",
|
|
13323
13321
|
"/skus",
|
|
13324
|
-
"/ai-agent",
|
|
13325
13322
|
"/help",
|
|
13326
13323
|
"/health",
|
|
13327
13324
|
"/profile",
|
|
@@ -13336,7 +13333,6 @@ function useAccessControl() {
|
|
|
13336
13333
|
"/targets",
|
|
13337
13334
|
"/shifts",
|
|
13338
13335
|
"/skus",
|
|
13339
|
-
"/ai-agent",
|
|
13340
13336
|
"/help",
|
|
13341
13337
|
"/health",
|
|
13342
13338
|
"/profile",
|
|
@@ -26793,7 +26789,7 @@ var HourlyOutputChartComponent = ({
|
|
|
26793
26789
|
return { hour, minute, decimalHour };
|
|
26794
26790
|
};
|
|
26795
26791
|
const shiftStartTime = getTimeFromTimeString(shiftStart);
|
|
26796
|
-
|
|
26792
|
+
React24__default.useMemo(() => {
|
|
26797
26793
|
if (!shiftDate || !timezone) return null;
|
|
26798
26794
|
const hour = shiftStartTime.hour.toString().padStart(2, "0");
|
|
26799
26795
|
const minute = shiftStartTime.minute.toString().padStart(2, "0");
|
|
@@ -26807,7 +26803,7 @@ var HourlyOutputChartComponent = ({
|
|
|
26807
26803
|
end: clip.idle_end_time ? new Date(clip.idle_end_time) : null
|
|
26808
26804
|
})).filter((clip) => clip.start && clip.end);
|
|
26809
26805
|
}, [idleTimeClips]);
|
|
26810
|
-
|
|
26806
|
+
React24__default.useCallback((rangeStart, rangeEnd) => {
|
|
26811
26807
|
if (!rangeStart || !rangeEnd || idleClipRanges.length === 0) {
|
|
26812
26808
|
return "Reason unavailable";
|
|
26813
26809
|
}
|
|
@@ -27300,22 +27296,22 @@ var HourlyOutputChartComponent = ({
|
|
|
27300
27296
|
const startTime = formatIdleTimestamp(range.start);
|
|
27301
27297
|
const endTime = formatIdleTimestamp(range.end + 1);
|
|
27302
27298
|
const fallbackIndex = chartData.findIndex((item) => item.timeRange === data2.timeRange);
|
|
27303
|
-
|
|
27304
|
-
const safeHourOffset = hourOffset >= 0 ? hourOffset : 0;
|
|
27305
|
-
const rangeStartDate = shiftStartDateTime ? addMinutes(shiftStartDateTime, safeHourOffset * 60 + range.start) : null;
|
|
27306
|
-
const rangeEndDate = shiftStartDateTime ? addMinutes(shiftStartDateTime, safeHourOffset * 60 + range.end + 1) : null;
|
|
27307
|
-
const reasonLabel = getIdleReasonForRange(rangeStartDate, rangeEndDate);
|
|
27299
|
+
Number.isFinite(data2.hourIndex) ? data2.hourIndex : fallbackIndex;
|
|
27308
27300
|
return /* @__PURE__ */ jsxs("div", { className: "text-gray-600 flex items-center gap-2 text-xs", children: [
|
|
27309
27301
|
/* @__PURE__ */ jsx("span", { className: "inline-block w-1.5 h-1.5 bg-orange-400 rounded-full flex-shrink-0" }),
|
|
27310
|
-
/* @__PURE__ */
|
|
27311
|
-
|
|
27312
|
-
|
|
27313
|
-
|
|
27314
|
-
|
|
27315
|
-
|
|
27316
|
-
|
|
27317
|
-
|
|
27318
|
-
|
|
27302
|
+
/* @__PURE__ */ jsx("span", { children: duration === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
27303
|
+
startTime,
|
|
27304
|
+
" (",
|
|
27305
|
+
duration,
|
|
27306
|
+
" min)"
|
|
27307
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
27308
|
+
startTime,
|
|
27309
|
+
" - ",
|
|
27310
|
+
endTime,
|
|
27311
|
+
" (",
|
|
27312
|
+
duration,
|
|
27313
|
+
" mins)"
|
|
27314
|
+
] }) })
|
|
27319
27315
|
] }, index);
|
|
27320
27316
|
}) })
|
|
27321
27317
|
] })
|
|
@@ -42606,17 +42602,6 @@ var SideNavBar = memo(({
|
|
|
42606
42602
|
});
|
|
42607
42603
|
onMobileMenuClose?.();
|
|
42608
42604
|
}, [navigate, onMobileMenuClose]);
|
|
42609
|
-
const handleAIAgentClick = useCallback(() => {
|
|
42610
|
-
navigate("/ai-agent", {
|
|
42611
|
-
trackingEvent: {
|
|
42612
|
-
name: "AI Agent Page Clicked",
|
|
42613
|
-
properties: {
|
|
42614
|
-
source: "side_nav"
|
|
42615
|
-
}
|
|
42616
|
-
}
|
|
42617
|
-
});
|
|
42618
|
-
onMobileMenuClose?.();
|
|
42619
|
-
}, [navigate, onMobileMenuClose]);
|
|
42620
42605
|
const handleProfileClick = useCallback(() => {
|
|
42621
42606
|
navigate("/profile", {
|
|
42622
42607
|
trackingEvent: {
|
|
@@ -42674,7 +42659,6 @@ var SideNavBar = memo(({
|
|
|
42674
42659
|
const teamManagementButtonClasses = useMemo(() => getButtonClasses("/team-management"), [getButtonClasses, pathname]);
|
|
42675
42660
|
const ticketsButtonClasses = useMemo(() => getButtonClasses("/tickets"), [getButtonClasses, pathname]);
|
|
42676
42661
|
useMemo(() => getButtonClasses("/supervisor-management"), [getButtonClasses, pathname]);
|
|
42677
|
-
const aiAgentButtonClasses = useMemo(() => getButtonClasses("/ai-agent"), [getButtonClasses, pathname]);
|
|
42678
42662
|
const profileButtonClasses = useMemo(() => getButtonClasses("/profile"), [getButtonClasses, pathname]);
|
|
42679
42663
|
const helpButtonClasses = useMemo(() => getButtonClasses("/help"), [getButtonClasses, pathname]);
|
|
42680
42664
|
const skusButtonClasses = useMemo(() => getButtonClasses("/skus"), [getButtonClasses, pathname]);
|
|
@@ -42828,24 +42812,6 @@ var SideNavBar = memo(({
|
|
|
42828
42812
|
]
|
|
42829
42813
|
}
|
|
42830
42814
|
),
|
|
42831
|
-
/* @__PURE__ */ jsxs(
|
|
42832
|
-
"button",
|
|
42833
|
-
{
|
|
42834
|
-
onClick: handleAIAgentClick,
|
|
42835
|
-
className: aiAgentButtonClasses,
|
|
42836
|
-
"aria-label": "AI Manufacturing Expert",
|
|
42837
|
-
tabIndex: 0,
|
|
42838
|
-
role: "tab",
|
|
42839
|
-
"aria-selected": pathname === "/ai-agent" || pathname.startsWith("/ai-agent/"),
|
|
42840
|
-
children: [
|
|
42841
|
-
/* @__PURE__ */ jsx(SparklesIcon, { className: "w-5 h-5 mb-1" }),
|
|
42842
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
|
|
42843
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs sm:text-[10px] font-medium leading-tight", children: "Axel" }),
|
|
42844
|
-
/* @__PURE__ */ jsx("span", { className: "text-[8px] px-1.5 py-0.5 bg-orange-100 text-orange-600 rounded-full font-medium leading-none mt-0.5", children: "BETA" })
|
|
42845
|
-
] })
|
|
42846
|
-
]
|
|
42847
|
-
}
|
|
42848
|
-
),
|
|
42849
42815
|
/* @__PURE__ */ jsxs(
|
|
42850
42816
|
"button",
|
|
42851
42817
|
{
|
|
@@ -43026,21 +42992,6 @@ var SideNavBar = memo(({
|
|
|
43026
42992
|
]
|
|
43027
42993
|
}
|
|
43028
42994
|
),
|
|
43029
|
-
/* @__PURE__ */ jsxs(
|
|
43030
|
-
"button",
|
|
43031
|
-
{
|
|
43032
|
-
onClick: handleMobileNavClick(handleAIAgentClick),
|
|
43033
|
-
className: getMobileButtonClass("/ai-agent"),
|
|
43034
|
-
"aria-label": "AI Manufacturing Expert",
|
|
43035
|
-
children: [
|
|
43036
|
-
/* @__PURE__ */ jsx(SparklesIcon, { className: getIconClass("/ai-agent") }),
|
|
43037
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
43038
|
-
/* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Axel AI" }),
|
|
43039
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs px-2 py-0.5 bg-orange-100 text-orange-600 rounded-full font-medium leading-none mt-1 self-start", children: "BETA" })
|
|
43040
|
-
] })
|
|
43041
|
-
]
|
|
43042
|
-
}
|
|
43043
|
-
),
|
|
43044
42995
|
/* @__PURE__ */ jsxs(
|
|
43045
42996
|
"button",
|
|
43046
42997
|
{
|
|
@@ -43228,7 +43179,6 @@ var Header = ({
|
|
|
43228
43179
|
if (pathname === "/") return "Factory View";
|
|
43229
43180
|
if (pathname.startsWith("/workspace/")) return "Workspace Details";
|
|
43230
43181
|
if (pathname.startsWith("/kpis/")) return "Line KPIs";
|
|
43231
|
-
if (pathname.startsWith("/ai-agent")) return "Axel - AI Manufacturing Expert";
|
|
43232
43182
|
return "Optifye";
|
|
43233
43183
|
};
|
|
43234
43184
|
const handleLogout = async () => {
|
|
@@ -47197,2056 +47147,6 @@ var AcceptInviteView = (props) => {
|
|
|
47197
47147
|
return /* @__PURE__ */ jsx(AcceptInvite, { ...props });
|
|
47198
47148
|
};
|
|
47199
47149
|
var AcceptInviteView_default = AcceptInviteView;
|
|
47200
|
-
var ThreadSidebar = ({
|
|
47201
|
-
activeThreadId,
|
|
47202
|
-
onSelectThread,
|
|
47203
|
-
onNewThread,
|
|
47204
|
-
className = ""
|
|
47205
|
-
}) => {
|
|
47206
|
-
const { threads, isLoading, error, deleteThread: deleteThread2 } = useThreads();
|
|
47207
|
-
const [deletingId, setDeletingId] = useState(null);
|
|
47208
|
-
const handleDelete = async (e, threadId) => {
|
|
47209
|
-
e.stopPropagation();
|
|
47210
|
-
if (confirm("Are you sure you want to delete this conversation?")) {
|
|
47211
|
-
setDeletingId(threadId);
|
|
47212
|
-
try {
|
|
47213
|
-
await deleteThread2(threadId);
|
|
47214
|
-
if (activeThreadId === threadId) {
|
|
47215
|
-
onNewThread();
|
|
47216
|
-
}
|
|
47217
|
-
} catch (error2) {
|
|
47218
|
-
console.error("Error deleting thread:", error2);
|
|
47219
|
-
alert("Failed to delete conversation. Please try again.");
|
|
47220
|
-
} finally {
|
|
47221
|
-
setDeletingId(null);
|
|
47222
|
-
}
|
|
47223
|
-
}
|
|
47224
|
-
};
|
|
47225
|
-
const formatDate2 = (dateString) => {
|
|
47226
|
-
const date = new Date(dateString);
|
|
47227
|
-
const now2 = /* @__PURE__ */ new Date();
|
|
47228
|
-
const diffMs = now2.getTime() - date.getTime();
|
|
47229
|
-
const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
|
|
47230
|
-
if (diffDays === 0) {
|
|
47231
|
-
return "Today";
|
|
47232
|
-
} else if (diffDays === 1) {
|
|
47233
|
-
return "Yesterday";
|
|
47234
|
-
} else if (diffDays < 7) {
|
|
47235
|
-
return date.toLocaleDateString("en-US", { weekday: "short" });
|
|
47236
|
-
} else {
|
|
47237
|
-
return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
47238
|
-
}
|
|
47239
|
-
};
|
|
47240
|
-
if (error) {
|
|
47241
|
-
return /* @__PURE__ */ jsx("div", { className: `p-4 text-red-600 text-sm ${className}`, children: "Failed to load conversations" });
|
|
47242
|
-
}
|
|
47243
|
-
return /* @__PURE__ */ jsxs("div", { className: `flex flex-col h-screen bg-gray-50 border-r border-gray-200 ${className}`, children: [
|
|
47244
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 p-4 border-b border-gray-200", children: [
|
|
47245
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Chat History" }),
|
|
47246
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-1", children: "Your previous conversations" })
|
|
47247
|
-
] }),
|
|
47248
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto min-h-0", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center p-8", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "sm" }) }) : threads.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center text-gray-500 text-sm", children: "No conversations yet" }) : /* @__PURE__ */ jsx("div", { className: "py-2", children: threads.map((thread) => /* @__PURE__ */ jsxs(
|
|
47249
|
-
"div",
|
|
47250
|
-
{
|
|
47251
|
-
onClick: () => onSelectThread(thread.id),
|
|
47252
|
-
className: `group relative flex items-start gap-3 px-4 py-3 cursor-pointer transition-all ${activeThreadId === thread.id ? "bg-blue-50 border-l-4 border-blue-600 hover:bg-blue-100" : "hover:bg-gray-100 border-l-4 border-transparent"}`,
|
|
47253
|
-
children: [
|
|
47254
|
-
/* @__PURE__ */ jsx(MessageSquare, { className: `w-4 h-4 mt-0.5 flex-shrink-0 ${activeThreadId === thread.id ? "text-blue-600" : "text-gray-400"}` }),
|
|
47255
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
47256
|
-
/* @__PURE__ */ jsx("h3", { className: `text-sm font-medium truncate ${activeThreadId === thread.id ? "text-blue-900" : "text-gray-900"}`, children: thread.title || "Untitled Chat" }),
|
|
47257
|
-
/* @__PURE__ */ jsx("p", { className: `text-xs mt-0.5 ${activeThreadId === thread.id ? "text-blue-700" : "text-gray-500"}`, children: formatDate2(thread.created_at) })
|
|
47258
|
-
] }),
|
|
47259
|
-
deletingId === thread.id ? /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsx(
|
|
47260
|
-
"button",
|
|
47261
|
-
{
|
|
47262
|
-
onClick: (e) => handleDelete(e, thread.id),
|
|
47263
|
-
className: "flex-shrink-0 opacity-0 group-hover:opacity-100 p-1 hover:bg-gray-200 rounded transition-all",
|
|
47264
|
-
title: "Delete conversation",
|
|
47265
|
-
children: /* @__PURE__ */ jsx(Trash2, { className: "w-3.5 h-3.5 text-gray-500" })
|
|
47266
|
-
}
|
|
47267
|
-
)
|
|
47268
|
-
]
|
|
47269
|
-
},
|
|
47270
|
-
thread.id
|
|
47271
|
-
)) }) }),
|
|
47272
|
-
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0 p-4 border-t border-gray-200", children: /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 text-center", children: [
|
|
47273
|
-
threads.length,
|
|
47274
|
-
" conversation",
|
|
47275
|
-
threads.length !== 1 ? "s" : ""
|
|
47276
|
-
] }) })
|
|
47277
|
-
] });
|
|
47278
|
-
};
|
|
47279
|
-
var ProfilePicture = React24__default.memo(({
|
|
47280
|
-
alt = "Axel",
|
|
47281
|
-
className = "",
|
|
47282
|
-
size = "md",
|
|
47283
|
-
animate = false
|
|
47284
|
-
}) => {
|
|
47285
|
-
return /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(AxelOrb, { size, animate }) });
|
|
47286
|
-
});
|
|
47287
|
-
ProfilePicture.displayName = "ProfilePicture";
|
|
47288
|
-
var GREETING_MESSAGES = [
|
|
47289
|
-
"How can I help you today?",
|
|
47290
|
-
"What would you like to know?",
|
|
47291
|
-
"Ready to optimize your operations?",
|
|
47292
|
-
"How can I assist you today?"
|
|
47293
|
-
];
|
|
47294
|
-
var getDailyGreeting = () => {
|
|
47295
|
-
const now2 = /* @__PURE__ */ new Date();
|
|
47296
|
-
const startOfYear = new Date(now2.getFullYear(), 0, 0);
|
|
47297
|
-
const diff = now2.getTime() - startOfYear.getTime();
|
|
47298
|
-
const oneDay = 1e3 * 60 * 60 * 24;
|
|
47299
|
-
const dayOfYear = Math.floor(diff / oneDay);
|
|
47300
|
-
const index = dayOfYear % GREETING_MESSAGES.length;
|
|
47301
|
-
return GREETING_MESSAGES[index];
|
|
47302
|
-
};
|
|
47303
|
-
var AIAgentView = () => {
|
|
47304
|
-
const { navigate, pathname } = useNavigation();
|
|
47305
|
-
const config = useDashboardConfig();
|
|
47306
|
-
const entityConfig = useEntityConfig();
|
|
47307
|
-
const dateTimeConfig = useDateTimeConfig();
|
|
47308
|
-
const shiftConfig = useShiftConfig();
|
|
47309
|
-
const { formatNumber } = useFormatNumber();
|
|
47310
|
-
const [inputValue, setInputValue] = useState("");
|
|
47311
|
-
const [loadingThreads, setLoadingThreads] = useState(/* @__PURE__ */ new Set());
|
|
47312
|
-
const [lastError, setLastError] = useState(null);
|
|
47313
|
-
const [copiedMessageId, setCopiedMessageId] = useState(null);
|
|
47314
|
-
const [activeThreadId, setActiveThreadId] = useState(void 0);
|
|
47315
|
-
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
|
47316
|
-
const [streamingStates, setStreamingStates] = useState(/* @__PURE__ */ new Map());
|
|
47317
|
-
const [userId, setUserId] = useState(null);
|
|
47318
|
-
const [pendingThreadId, setPendingThreadId] = useState(null);
|
|
47319
|
-
const [isTransitioning, setIsTransitioning] = useState(false);
|
|
47320
|
-
const [typedText, setTypedText] = useState("");
|
|
47321
|
-
const [newChatCount, setNewChatCount] = useState(0);
|
|
47322
|
-
const [greetingReset, setGreetingReset] = useState(0);
|
|
47323
|
-
const [hasStartedTyping, setHasStartedTyping] = useState(false);
|
|
47324
|
-
const [typingStartTime, setTypingStartTime] = useState(null);
|
|
47325
|
-
const [lastTypingTime, setLastTypingTime] = useState(null);
|
|
47326
|
-
const [characterCount, setCharacterCount] = useState(0);
|
|
47327
|
-
const typingTimeoutRef = useRef(null);
|
|
47328
|
-
const currentGreeting = useMemo(() => getDailyGreeting(), [greetingReset]);
|
|
47329
|
-
const isThreadLoading = (threadId) => {
|
|
47330
|
-
return threadId ? loadingThreads.has(threadId) : false;
|
|
47331
|
-
};
|
|
47332
|
-
const getStreamingState = (threadId) => {
|
|
47333
|
-
return threadId ? streamingStates.get(threadId) || { message: "", reasoning: "" } : { message: "", reasoning: "" };
|
|
47334
|
-
};
|
|
47335
|
-
const trackTypingStart = () => {
|
|
47336
|
-
if (!hasStartedTyping) {
|
|
47337
|
-
const now2 = Date.now();
|
|
47338
|
-
setHasStartedTyping(true);
|
|
47339
|
-
setTypingStartTime(now2);
|
|
47340
|
-
setLastTypingTime(now2);
|
|
47341
|
-
trackCoreEvent("AI Agent Input Started", {
|
|
47342
|
-
line_id: lineId,
|
|
47343
|
-
company_id: companyId,
|
|
47344
|
-
shift_id: shiftId,
|
|
47345
|
-
active_thread_id: activeThreadId,
|
|
47346
|
-
has_existing_messages: messages.length > 0,
|
|
47347
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
47348
|
-
});
|
|
47349
|
-
}
|
|
47350
|
-
};
|
|
47351
|
-
const trackTypingProgress = (newValue) => {
|
|
47352
|
-
const now2 = Date.now();
|
|
47353
|
-
setLastTypingTime(now2);
|
|
47354
|
-
setCharacterCount(newValue.length);
|
|
47355
|
-
if (typingTimeoutRef.current) {
|
|
47356
|
-
clearTimeout(typingTimeoutRef.current);
|
|
47357
|
-
}
|
|
47358
|
-
typingTimeoutRef.current = setTimeout(() => {
|
|
47359
|
-
if (hasStartedTyping && typingStartTime && newValue.length > 0) {
|
|
47360
|
-
const typingDuration = now2 - typingStartTime;
|
|
47361
|
-
trackCoreEvent("AI Agent Input Typing Progress", {
|
|
47362
|
-
line_id: lineId,
|
|
47363
|
-
company_id: companyId,
|
|
47364
|
-
shift_id: shiftId,
|
|
47365
|
-
active_thread_id: activeThreadId,
|
|
47366
|
-
character_count: newValue.length,
|
|
47367
|
-
typing_duration_ms: typingDuration,
|
|
47368
|
-
has_existing_messages: messages.length > 0,
|
|
47369
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
47370
|
-
});
|
|
47371
|
-
}
|
|
47372
|
-
}, 2e3);
|
|
47373
|
-
};
|
|
47374
|
-
const trackMessageSent = (messageContent) => {
|
|
47375
|
-
if (hasStartedTyping && typingStartTime) {
|
|
47376
|
-
const now2 = Date.now();
|
|
47377
|
-
const totalTypingDuration = now2 - typingStartTime;
|
|
47378
|
-
trackCoreEvent("AI Agent Message Sent", {
|
|
47379
|
-
line_id: lineId,
|
|
47380
|
-
company_id: companyId,
|
|
47381
|
-
shift_id: shiftId,
|
|
47382
|
-
active_thread_id: activeThreadId,
|
|
47383
|
-
message_length: messageContent.length,
|
|
47384
|
-
character_count: messageContent.length,
|
|
47385
|
-
typing_duration_ms: totalTypingDuration,
|
|
47386
|
-
has_existing_messages: messages.length > 0,
|
|
47387
|
-
is_new_conversation: !activeThreadId,
|
|
47388
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
47389
|
-
});
|
|
47390
|
-
}
|
|
47391
|
-
resetTypingState();
|
|
47392
|
-
};
|
|
47393
|
-
const resetTypingState = () => {
|
|
47394
|
-
setHasStartedTyping(false);
|
|
47395
|
-
setTypingStartTime(null);
|
|
47396
|
-
setLastTypingTime(null);
|
|
47397
|
-
setCharacterCount(0);
|
|
47398
|
-
if (typingTimeoutRef.current) {
|
|
47399
|
-
clearTimeout(typingTimeoutRef.current);
|
|
47400
|
-
typingTimeoutRef.current = null;
|
|
47401
|
-
}
|
|
47402
|
-
};
|
|
47403
|
-
const textareaRef = useRef(null);
|
|
47404
|
-
const messagesEndRef = useRef(null);
|
|
47405
|
-
const containerRef = useRef(null);
|
|
47406
|
-
const renderedContentCache = useRef(/* @__PURE__ */ new Map());
|
|
47407
|
-
const { createThread, mutate: mutateThreads } = useThreads();
|
|
47408
|
-
const { messages, addMessage, setMessages } = useMessages(activeThreadId);
|
|
47409
|
-
const agnoApiUrl = config.endpoints?.agnoApiUrl || "https://fastapi-production-111f9.up.railway.app";
|
|
47410
|
-
const sseClient = useMemo(() => {
|
|
47411
|
-
console.log("[AIAgentView] Using AGNO API URL:", agnoApiUrl);
|
|
47412
|
-
return new SSEChatClient(agnoApiUrl);
|
|
47413
|
-
}, [agnoApiUrl]);
|
|
47414
|
-
const getLineIdFromPath = () => {
|
|
47415
|
-
const pathParts = pathname.split("/");
|
|
47416
|
-
const lineIdIndex = pathParts.findIndex((part) => part === "ai-agent") + 1;
|
|
47417
|
-
if (lineIdIndex > 0 && lineIdIndex < pathParts.length) {
|
|
47418
|
-
return pathParts[lineIdIndex];
|
|
47419
|
-
}
|
|
47420
|
-
return entityConfig.defaultLineId || LINE_1_UUID;
|
|
47421
|
-
};
|
|
47422
|
-
const lineId = getLineIdFromPath();
|
|
47423
|
-
const { shiftId } = getCurrentShift(dateTimeConfig.defaultTimezone || "Asia/Kolkata", shiftConfig);
|
|
47424
|
-
const companyId = entityConfig.companyId || "default-company-id";
|
|
47425
|
-
const configuredLineIds = getConfiguredLineIds(entityConfig);
|
|
47426
|
-
const lineDisplayNames = getAllLineDisplayNames(entityConfig);
|
|
47427
|
-
const allLines = configuredLineIds.map((id3) => ({
|
|
47428
|
-
id: id3,
|
|
47429
|
-
name: lineDisplayNames[id3] || `Line ${id3.substring(0, 8)}`
|
|
47430
|
-
}));
|
|
47431
|
-
const ACTIVE_THREAD_STORAGE_KEY = `ai-agent-active-thread-${lineId}`;
|
|
47432
|
-
useLayoutEffect(() => {
|
|
47433
|
-
const savedThreadId = localStorage.getItem(ACTIVE_THREAD_STORAGE_KEY);
|
|
47434
|
-
if (savedThreadId && savedThreadId !== "undefined") {
|
|
47435
|
-
setActiveThreadId(savedThreadId);
|
|
47436
|
-
}
|
|
47437
|
-
}, [ACTIVE_THREAD_STORAGE_KEY]);
|
|
47438
|
-
useEffect(() => {
|
|
47439
|
-
if (activeThreadId) {
|
|
47440
|
-
localStorage.setItem(ACTIVE_THREAD_STORAGE_KEY, activeThreadId);
|
|
47441
|
-
} else {
|
|
47442
|
-
localStorage.removeItem(ACTIVE_THREAD_STORAGE_KEY);
|
|
47443
|
-
}
|
|
47444
|
-
}, [activeThreadId, ACTIVE_THREAD_STORAGE_KEY]);
|
|
47445
|
-
useEffect(() => {
|
|
47446
|
-
const handleVisibilityChange = () => {
|
|
47447
|
-
if (document.visibilityState === "hidden" && activeThreadId) {
|
|
47448
|
-
localStorage.setItem(ACTIVE_THREAD_STORAGE_KEY, activeThreadId);
|
|
47449
|
-
}
|
|
47450
|
-
};
|
|
47451
|
-
const handleBeforeUnload = () => {
|
|
47452
|
-
if (activeThreadId) {
|
|
47453
|
-
localStorage.setItem(ACTIVE_THREAD_STORAGE_KEY, activeThreadId);
|
|
47454
|
-
}
|
|
47455
|
-
};
|
|
47456
|
-
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
47457
|
-
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
47458
|
-
return () => {
|
|
47459
|
-
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
47460
|
-
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
47461
|
-
if (activeThreadId) {
|
|
47462
|
-
localStorage.setItem(ACTIVE_THREAD_STORAGE_KEY, activeThreadId);
|
|
47463
|
-
}
|
|
47464
|
-
};
|
|
47465
|
-
}, [activeThreadId, ACTIVE_THREAD_STORAGE_KEY]);
|
|
47466
|
-
useEffect(() => {
|
|
47467
|
-
if (textareaRef.current) {
|
|
47468
|
-
textareaRef.current.style.height = "auto";
|
|
47469
|
-
textareaRef.current.style.height = `${Math.min(textareaRef.current.scrollHeight, 120)}px`;
|
|
47470
|
-
}
|
|
47471
|
-
}, [inputValue]);
|
|
47472
|
-
const scrollToBottom = () => {
|
|
47473
|
-
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
47474
|
-
};
|
|
47475
|
-
useEffect(() => {
|
|
47476
|
-
if (activeThreadId && messages.length > 0) {
|
|
47477
|
-
setTimeout(scrollToBottom, 100);
|
|
47478
|
-
}
|
|
47479
|
-
}, [activeThreadId]);
|
|
47480
|
-
useEffect(() => {
|
|
47481
|
-
if (messages.length === 0 && !isTransitioning) {
|
|
47482
|
-
let index = 0;
|
|
47483
|
-
setTypedText("");
|
|
47484
|
-
const typeInterval = setInterval(() => {
|
|
47485
|
-
if (index < currentGreeting.length) {
|
|
47486
|
-
setTypedText(currentGreeting.substring(0, index + 1));
|
|
47487
|
-
index++;
|
|
47488
|
-
} else {
|
|
47489
|
-
clearInterval(typeInterval);
|
|
47490
|
-
}
|
|
47491
|
-
}, 50);
|
|
47492
|
-
return () => clearInterval(typeInterval);
|
|
47493
|
-
}
|
|
47494
|
-
}, [messages.length, isTransitioning, greetingReset, currentGreeting]);
|
|
47495
|
-
useEffect(() => {
|
|
47496
|
-
if (isSidebarOpen) {
|
|
47497
|
-
setNewChatCount(0);
|
|
47498
|
-
}
|
|
47499
|
-
}, [isSidebarOpen]);
|
|
47500
|
-
const copyToClipboard = async (text, messageId) => {
|
|
47501
|
-
try {
|
|
47502
|
-
await navigator.clipboard.writeText(text);
|
|
47503
|
-
setCopiedMessageId(messageId);
|
|
47504
|
-
setTimeout(() => setCopiedMessageId(null), 2e3);
|
|
47505
|
-
} catch (err) {
|
|
47506
|
-
console.error("Failed to copy text: ", err);
|
|
47507
|
-
}
|
|
47508
|
-
};
|
|
47509
|
-
const handleNewThread = () => {
|
|
47510
|
-
setActiveThreadId(void 0);
|
|
47511
|
-
setMessages([]);
|
|
47512
|
-
setInputValue("");
|
|
47513
|
-
setPendingThreadId(null);
|
|
47514
|
-
setTypedText("");
|
|
47515
|
-
setGreetingReset((prev) => prev + 1);
|
|
47516
|
-
resetTypingState();
|
|
47517
|
-
localStorage.removeItem(ACTIVE_THREAD_STORAGE_KEY);
|
|
47518
|
-
textareaRef.current?.focus();
|
|
47519
|
-
};
|
|
47520
|
-
useEffect(() => {
|
|
47521
|
-
return () => {
|
|
47522
|
-
if (typingTimeoutRef.current) {
|
|
47523
|
-
clearTimeout(typingTimeoutRef.current);
|
|
47524
|
-
}
|
|
47525
|
-
};
|
|
47526
|
-
}, []);
|
|
47527
|
-
useEffect(() => {
|
|
47528
|
-
const checkAuth = async () => {
|
|
47529
|
-
const supabase2 = _getSupabaseInstance();
|
|
47530
|
-
const { data: { session } } = await supabase2.auth.getSession();
|
|
47531
|
-
if (session?.user) {
|
|
47532
|
-
setUserId(session.user.id);
|
|
47533
|
-
console.log("[AIAgentView] User authenticated:", session.user.id);
|
|
47534
|
-
} else {
|
|
47535
|
-
console.log("[AIAgentView] No authenticated session found");
|
|
47536
|
-
}
|
|
47537
|
-
};
|
|
47538
|
-
checkAuth();
|
|
47539
|
-
const supabase = _getSupabaseInstance();
|
|
47540
|
-
const { data: { subscription } } = supabase.auth.onAuthStateChange((event, session) => {
|
|
47541
|
-
if (session?.user) {
|
|
47542
|
-
setUserId(session.user.id);
|
|
47543
|
-
} else {
|
|
47544
|
-
setUserId(null);
|
|
47545
|
-
}
|
|
47546
|
-
});
|
|
47547
|
-
return () => {
|
|
47548
|
-
subscription.unsubscribe();
|
|
47549
|
-
};
|
|
47550
|
-
}, []);
|
|
47551
|
-
const handleSubmit = async (e) => {
|
|
47552
|
-
e.preventDefault();
|
|
47553
|
-
if (!inputValue.trim() || !userId) return;
|
|
47554
|
-
let currentThreadId = activeThreadId || `temp-${Date.now()}`;
|
|
47555
|
-
if (isThreadLoading(currentThreadId)) return;
|
|
47556
|
-
const userMessage = inputValue.trim();
|
|
47557
|
-
trackMessageSent(userMessage);
|
|
47558
|
-
if (displayMessages.length === 0) {
|
|
47559
|
-
setIsTransitioning(true);
|
|
47560
|
-
setTimeout(() => {
|
|
47561
|
-
setIsTransitioning(false);
|
|
47562
|
-
}, 800);
|
|
47563
|
-
}
|
|
47564
|
-
setInputValue("");
|
|
47565
|
-
setLoadingThreads((prev) => new Set(prev).add(currentThreadId));
|
|
47566
|
-
setLastError(null);
|
|
47567
|
-
if (!activeThreadId) {
|
|
47568
|
-
setPendingThreadId(currentThreadId);
|
|
47569
|
-
}
|
|
47570
|
-
setStreamingStates((prev) => {
|
|
47571
|
-
const newMap = new Map(prev);
|
|
47572
|
-
newMap.set(currentThreadId, { message: "", reasoning: "" });
|
|
47573
|
-
return newMap;
|
|
47574
|
-
});
|
|
47575
|
-
const tempUserMessage = {
|
|
47576
|
-
id: Date.now(),
|
|
47577
|
-
// Temporary ID
|
|
47578
|
-
thread_id: activeThreadId || "",
|
|
47579
|
-
role: "user",
|
|
47580
|
-
content: userMessage,
|
|
47581
|
-
reasoning: null,
|
|
47582
|
-
model_id: null,
|
|
47583
|
-
token_usage: null,
|
|
47584
|
-
metadata: null,
|
|
47585
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
47586
|
-
position: messages.length
|
|
47587
|
-
};
|
|
47588
|
-
setMessages((prev) => [...prev, tempUserMessage]);
|
|
47589
|
-
setTimeout(scrollToBottom, 100);
|
|
47590
|
-
try {
|
|
47591
|
-
await sseClient.sendMessage(
|
|
47592
|
-
userMessage,
|
|
47593
|
-
userId,
|
|
47594
|
-
activeThreadId || null,
|
|
47595
|
-
{
|
|
47596
|
-
companyId,
|
|
47597
|
-
lineId,
|
|
47598
|
-
shiftId,
|
|
47599
|
-
allLines
|
|
47600
|
-
},
|
|
47601
|
-
{
|
|
47602
|
-
onThreadCreated: (threadId) => {
|
|
47603
|
-
if (!activeThreadId) {
|
|
47604
|
-
const oldThreadId = currentThreadId;
|
|
47605
|
-
currentThreadId = threadId;
|
|
47606
|
-
setActiveThreadId(threadId);
|
|
47607
|
-
setPendingThreadId(null);
|
|
47608
|
-
if (!isSidebarOpen) {
|
|
47609
|
-
setNewChatCount((prev) => prev + 1);
|
|
47610
|
-
}
|
|
47611
|
-
setLoadingThreads((prev) => {
|
|
47612
|
-
const newSet = new Set(prev);
|
|
47613
|
-
if (newSet.has(oldThreadId)) {
|
|
47614
|
-
newSet.delete(oldThreadId);
|
|
47615
|
-
newSet.add(threadId);
|
|
47616
|
-
}
|
|
47617
|
-
return newSet;
|
|
47618
|
-
});
|
|
47619
|
-
setStreamingStates((prev) => {
|
|
47620
|
-
const newMap = new Map(prev);
|
|
47621
|
-
const streamingState = newMap.get(oldThreadId);
|
|
47622
|
-
if (streamingState) {
|
|
47623
|
-
newMap.delete(oldThreadId);
|
|
47624
|
-
newMap.set(threadId, streamingState);
|
|
47625
|
-
}
|
|
47626
|
-
return newMap;
|
|
47627
|
-
});
|
|
47628
|
-
mutateThreads();
|
|
47629
|
-
}
|
|
47630
|
-
},
|
|
47631
|
-
onMessage: (text) => {
|
|
47632
|
-
setStreamingStates((prev) => {
|
|
47633
|
-
const newMap = new Map(prev);
|
|
47634
|
-
const current = newMap.get(currentThreadId) || { message: "", reasoning: "" };
|
|
47635
|
-
newMap.set(currentThreadId, { ...current, message: current.message + text });
|
|
47636
|
-
return newMap;
|
|
47637
|
-
});
|
|
47638
|
-
},
|
|
47639
|
-
onComplete: async (messageId) => {
|
|
47640
|
-
if (currentThreadId && !currentThreadId.startsWith("temp-")) {
|
|
47641
|
-
const updatedMessages = await getAllThreadMessages(currentThreadId);
|
|
47642
|
-
setMessages(updatedMessages);
|
|
47643
|
-
}
|
|
47644
|
-
setStreamingStates((prev) => {
|
|
47645
|
-
const newMap = new Map(prev);
|
|
47646
|
-
newMap.delete(currentThreadId);
|
|
47647
|
-
return newMap;
|
|
47648
|
-
});
|
|
47649
|
-
setLoadingThreads((prev) => {
|
|
47650
|
-
const newSet = new Set(prev);
|
|
47651
|
-
newSet.delete(currentThreadId);
|
|
47652
|
-
return newSet;
|
|
47653
|
-
});
|
|
47654
|
-
if (!activeThreadId) {
|
|
47655
|
-
setPendingThreadId(null);
|
|
47656
|
-
}
|
|
47657
|
-
},
|
|
47658
|
-
onError: (error) => {
|
|
47659
|
-
console.error("Chat error:", error);
|
|
47660
|
-
setLastError(error);
|
|
47661
|
-
setLoadingThreads((prev) => {
|
|
47662
|
-
const newSet = new Set(prev);
|
|
47663
|
-
newSet.delete(currentThreadId);
|
|
47664
|
-
return newSet;
|
|
47665
|
-
});
|
|
47666
|
-
setStreamingStates((prev) => {
|
|
47667
|
-
const newMap = new Map(prev);
|
|
47668
|
-
newMap.delete(currentThreadId);
|
|
47669
|
-
return newMap;
|
|
47670
|
-
});
|
|
47671
|
-
if (!activeThreadId) {
|
|
47672
|
-
setPendingThreadId(null);
|
|
47673
|
-
}
|
|
47674
|
-
setMessages((prev) => prev.slice(0, -1));
|
|
47675
|
-
}
|
|
47676
|
-
}
|
|
47677
|
-
);
|
|
47678
|
-
} catch (error) {
|
|
47679
|
-
console.error("[AIAgentView] Error in chat:", error);
|
|
47680
|
-
const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
47681
|
-
setLastError(errorMessage);
|
|
47682
|
-
setLoadingThreads((prev) => {
|
|
47683
|
-
const newSet = new Set(prev);
|
|
47684
|
-
newSet.delete(currentThreadId);
|
|
47685
|
-
return newSet;
|
|
47686
|
-
});
|
|
47687
|
-
setStreamingStates((prev) => {
|
|
47688
|
-
const newMap = new Map(prev);
|
|
47689
|
-
newMap.delete(currentThreadId);
|
|
47690
|
-
return newMap;
|
|
47691
|
-
});
|
|
47692
|
-
if (!activeThreadId) {
|
|
47693
|
-
setPendingThreadId(null);
|
|
47694
|
-
}
|
|
47695
|
-
setMessages((prev) => prev.slice(0, -1));
|
|
47696
|
-
}
|
|
47697
|
-
};
|
|
47698
|
-
const handleKeyDown = (e) => {
|
|
47699
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
47700
|
-
e.preventDefault();
|
|
47701
|
-
if (!isCurrentThreadLoading) {
|
|
47702
|
-
handleSubmit(e);
|
|
47703
|
-
}
|
|
47704
|
-
}
|
|
47705
|
-
};
|
|
47706
|
-
const formatMessage = (content) => {
|
|
47707
|
-
const processInlineFormatting = (text) => {
|
|
47708
|
-
text = text.replace(/\*\*(.*?)\*\*/g, '<strong class="font-semibold text-gray-900">$1</strong>');
|
|
47709
|
-
text = text.replace(/`([^`]+)`/g, '<code class="bg-gray-100 px-1.5 py-0.5 rounded text-sm font-mono text-gray-800">$1</code>');
|
|
47710
|
-
return text;
|
|
47711
|
-
};
|
|
47712
|
-
const parseTableFromText = (lines2, startIndex) => {
|
|
47713
|
-
const tableLines = [];
|
|
47714
|
-
let i = startIndex;
|
|
47715
|
-
while (i < lines2.length) {
|
|
47716
|
-
const line = lines2[i].trim();
|
|
47717
|
-
if (!line) {
|
|
47718
|
-
i++;
|
|
47719
|
-
break;
|
|
47720
|
-
}
|
|
47721
|
-
if (line.includes("|") || line.match(/^[-|=\s]+$/)) {
|
|
47722
|
-
tableLines.push(line);
|
|
47723
|
-
i++;
|
|
47724
|
-
} else {
|
|
47725
|
-
break;
|
|
47726
|
-
}
|
|
47727
|
-
}
|
|
47728
|
-
if (tableLines.length === 0) return { html: "", endIndex: startIndex };
|
|
47729
|
-
const dataLines = tableLines.filter((line) => !line.match(/^[-|=\s]+$/));
|
|
47730
|
-
if (dataLines.length === 0) return { html: "", endIndex: i };
|
|
47731
|
-
let headerRow = [];
|
|
47732
|
-
let dataRows = [];
|
|
47733
|
-
const firstLine = dataLines[0];
|
|
47734
|
-
if (firstLine.includes("|")) {
|
|
47735
|
-
const cells = firstLine.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
|
|
47736
|
-
if (cells.length >= 2) {
|
|
47737
|
-
headerRow = cells;
|
|
47738
|
-
for (let j = 1; j < dataLines.length; j++) {
|
|
47739
|
-
const row = dataLines[j];
|
|
47740
|
-
if (row.includes("|")) {
|
|
47741
|
-
const rowCells = row.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
|
|
47742
|
-
while (rowCells.length < headerRow.length) rowCells.push("");
|
|
47743
|
-
if (rowCells.length > headerRow.length) rowCells.splice(headerRow.length);
|
|
47744
|
-
dataRows.push(rowCells);
|
|
47745
|
-
}
|
|
47746
|
-
}
|
|
47747
|
-
}
|
|
47748
|
-
}
|
|
47749
|
-
if (headerRow.length === 0) {
|
|
47750
|
-
for (const line of dataLines) {
|
|
47751
|
-
if (line.includes("|")) {
|
|
47752
|
-
const rowCells = line.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
|
|
47753
|
-
if (rowCells.length >= 2) {
|
|
47754
|
-
dataRows.push(rowCells);
|
|
47755
|
-
}
|
|
47756
|
-
}
|
|
47757
|
-
}
|
|
47758
|
-
if (dataRows.length > 0 && dataRows[0].length > 0) {
|
|
47759
|
-
headerRow = dataRows[0].map((_, index) => `Column ${index + 1}`);
|
|
47760
|
-
}
|
|
47761
|
-
}
|
|
47762
|
-
if (headerRow.length > 0 && dataRows.length > 0) {
|
|
47763
|
-
let tableHtml = '<div class="overflow-x-auto my-4"><table class="min-w-full border-collapse border border-gray-300 rounded-lg shadow-sm">';
|
|
47764
|
-
tableHtml += '<thead class="bg-gray-50">';
|
|
47765
|
-
tableHtml += "<tr>";
|
|
47766
|
-
headerRow.forEach((header) => {
|
|
47767
|
-
tableHtml += `<th class="border border-gray-300 px-4 py-2 text-left font-semibold text-gray-900">${processInlineFormatting(header)}</th>`;
|
|
47768
|
-
});
|
|
47769
|
-
tableHtml += "</tr>";
|
|
47770
|
-
tableHtml += "</thead>";
|
|
47771
|
-
tableHtml += '<tbody class="bg-white divide-y divide-gray-200">';
|
|
47772
|
-
dataRows.forEach((row, rowIndex) => {
|
|
47773
|
-
tableHtml += `<tr class="${rowIndex % 2 === 0 ? "bg-white" : "bg-gray-50"}">`;
|
|
47774
|
-
row.forEach((cell) => {
|
|
47775
|
-
tableHtml += `<td class="border border-gray-300 px-4 py-2 text-gray-800">${processInlineFormatting(cell)}</td>`;
|
|
47776
|
-
});
|
|
47777
|
-
tableHtml += "</tr>";
|
|
47778
|
-
});
|
|
47779
|
-
tableHtml += "</tbody>";
|
|
47780
|
-
tableHtml += "</table></div>";
|
|
47781
|
-
return { html: tableHtml, endIndex: i };
|
|
47782
|
-
}
|
|
47783
|
-
return { html: "", endIndex: startIndex };
|
|
47784
|
-
};
|
|
47785
|
-
const processedContent = content;
|
|
47786
|
-
const lines = processedContent.split("\n");
|
|
47787
|
-
const formattedLines = [];
|
|
47788
|
-
let inList = false;
|
|
47789
|
-
for (let i = 0; i < lines.length; i++) {
|
|
47790
|
-
let line = lines[i];
|
|
47791
|
-
const trimmedLine = line.trim();
|
|
47792
|
-
if (!trimmedLine) {
|
|
47793
|
-
if (inList) {
|
|
47794
|
-
formattedLines.push("</ul>");
|
|
47795
|
-
inList = false;
|
|
47796
|
-
}
|
|
47797
|
-
formattedLines.push("<br/>");
|
|
47798
|
-
continue;
|
|
47799
|
-
}
|
|
47800
|
-
if (trimmedLine.includes("|") && (trimmedLine.match(/\|/g) || []).length >= 1) {
|
|
47801
|
-
if (inList) {
|
|
47802
|
-
formattedLines.push("</ul>");
|
|
47803
|
-
inList = false;
|
|
47804
|
-
}
|
|
47805
|
-
const tableResult = parseTableFromText(lines, i);
|
|
47806
|
-
if (tableResult.html) {
|
|
47807
|
-
formattedLines.push(tableResult.html);
|
|
47808
|
-
i = tableResult.endIndex - 1;
|
|
47809
|
-
continue;
|
|
47810
|
-
}
|
|
47811
|
-
}
|
|
47812
|
-
if (trimmedLine.startsWith("###")) {
|
|
47813
|
-
if (inList) {
|
|
47814
|
-
formattedLines.push("</ul>");
|
|
47815
|
-
inList = false;
|
|
47816
|
-
}
|
|
47817
|
-
const headerText = processInlineFormatting(trimmedLine.replace(/^###\s*/, ""));
|
|
47818
|
-
formattedLines.push(`<h3 class="text-lg font-semibold text-gray-900 mt-4 mb-2">${headerText}</h3>`);
|
|
47819
|
-
continue;
|
|
47820
|
-
} else if (trimmedLine.startsWith("##")) {
|
|
47821
|
-
if (inList) {
|
|
47822
|
-
formattedLines.push("</ul>");
|
|
47823
|
-
inList = false;
|
|
47824
|
-
}
|
|
47825
|
-
const headerText = processInlineFormatting(trimmedLine.replace(/^##\s*/, ""));
|
|
47826
|
-
formattedLines.push(`<h2 class="text-xl font-semibold text-gray-900 mt-4 mb-2">${headerText}</h2>`);
|
|
47827
|
-
continue;
|
|
47828
|
-
} else if (trimmedLine.startsWith("#")) {
|
|
47829
|
-
if (inList) {
|
|
47830
|
-
formattedLines.push("</ul>");
|
|
47831
|
-
inList = false;
|
|
47832
|
-
}
|
|
47833
|
-
const headerText = processInlineFormatting(trimmedLine.replace(/^#\s*/, ""));
|
|
47834
|
-
formattedLines.push(`<h1 class="text-3xl font-semibold text-gray-900 mt-4 mb-3">${headerText}</h1>`);
|
|
47835
|
-
continue;
|
|
47836
|
-
}
|
|
47837
|
-
const listMatch = trimmedLine.match(/^([-*•]\s+|\d+\.\s+|^\s*[-*•]\s+)/);
|
|
47838
|
-
if (listMatch) {
|
|
47839
|
-
if (!inList) {
|
|
47840
|
-
formattedLines.push('<ul class="space-y-1 mt-2 mb-2">');
|
|
47841
|
-
inList = true;
|
|
47842
|
-
}
|
|
47843
|
-
const listContent = processInlineFormatting(trimmedLine.replace(/^([-*•]\s+|\d+\.\s+|\s*[-*•]\s+)/, ""));
|
|
47844
|
-
formattedLines.push(`<li class="ml-4 text-gray-700 flex items-start"><span class="mr-2 text-gray-500">\u2022</span><span>${listContent}</span></li>`);
|
|
47845
|
-
continue;
|
|
47846
|
-
} else if (inList) {
|
|
47847
|
-
formattedLines.push("</ul>");
|
|
47848
|
-
inList = false;
|
|
47849
|
-
}
|
|
47850
|
-
if (trimmedLine.match(/^---+$/)) {
|
|
47851
|
-
formattedLines.push('<hr class="my-4 border-gray-200"/>');
|
|
47852
|
-
continue;
|
|
47853
|
-
}
|
|
47854
|
-
if (trimmedLine) {
|
|
47855
|
-
const processedLine = processInlineFormatting(line);
|
|
47856
|
-
if (trimmedLine.endsWith(":") && trimmedLine.length < 50 && !trimmedLine.includes("**")) {
|
|
47857
|
-
formattedLines.push(`<h3 class="text-lg font-semibold text-gray-900 mt-4 mb-2">${processedLine}</h3>`);
|
|
47858
|
-
} else {
|
|
47859
|
-
formattedLines.push(`<p class="text-gray-800 leading-relaxed mb-2">${processedLine}</p>`);
|
|
47860
|
-
}
|
|
47861
|
-
}
|
|
47862
|
-
}
|
|
47863
|
-
if (inList) {
|
|
47864
|
-
formattedLines.push("</ul>");
|
|
47865
|
-
}
|
|
47866
|
-
return formattedLines.join("");
|
|
47867
|
-
};
|
|
47868
|
-
const formatTime5 = (timestamp) => {
|
|
47869
|
-
const date = new Date(timestamp);
|
|
47870
|
-
return date.toLocaleTimeString([], {
|
|
47871
|
-
hour: "2-digit",
|
|
47872
|
-
minute: "2-digit",
|
|
47873
|
-
hour12: false
|
|
47874
|
-
});
|
|
47875
|
-
};
|
|
47876
|
-
const displayMessages = [...messages];
|
|
47877
|
-
const effectiveThreadId = activeThreadId || pendingThreadId || void 0;
|
|
47878
|
-
const currentStreaming = getStreamingState(effectiveThreadId);
|
|
47879
|
-
const isCurrentThreadLoading = isThreadLoading(effectiveThreadId);
|
|
47880
|
-
if (isCurrentThreadLoading && currentStreaming.message) {
|
|
47881
|
-
displayMessages.push({
|
|
47882
|
-
id: -1,
|
|
47883
|
-
// Use -1 for streaming message to identify it
|
|
47884
|
-
thread_id: activeThreadId || "",
|
|
47885
|
-
role: "assistant",
|
|
47886
|
-
content: currentStreaming.message,
|
|
47887
|
-
reasoning: currentStreaming.reasoning || null,
|
|
47888
|
-
model_id: "gpt-4o-mini",
|
|
47889
|
-
token_usage: null,
|
|
47890
|
-
metadata: null,
|
|
47891
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
47892
|
-
position: messages.length
|
|
47893
|
-
});
|
|
47894
|
-
}
|
|
47895
|
-
const renderAssistantContent = (content) => {
|
|
47896
|
-
const cached = renderedContentCache.current.get(content);
|
|
47897
|
-
if (cached) {
|
|
47898
|
-
return cached;
|
|
47899
|
-
}
|
|
47900
|
-
const parseChartPatterns = (text) => {
|
|
47901
|
-
const chartElements = [];
|
|
47902
|
-
let lastIndex = 0;
|
|
47903
|
-
console.log("[DEBUG] Parsing chart patterns from text:", text);
|
|
47904
|
-
const chartRegex = /\[\s*(?:Calling\s+|CALL\s+)?(create_[a-z_]+)\s*\(([\s\S]*?)\)\s*\]/g;
|
|
47905
|
-
let match;
|
|
47906
|
-
const processedIndices = /* @__PURE__ */ new Set();
|
|
47907
|
-
let matchCount = 0;
|
|
47908
|
-
while ((match = chartRegex.exec(text)) !== null) {
|
|
47909
|
-
matchCount++;
|
|
47910
|
-
const startIndex = match.index;
|
|
47911
|
-
const endIndex = startIndex + match[0].length;
|
|
47912
|
-
console.log(`[DEBUG] Found chart pattern #${matchCount}:`, {
|
|
47913
|
-
fullMatch: match[0],
|
|
47914
|
-
chartType: match[1],
|
|
47915
|
-
argsString: match[2],
|
|
47916
|
-
startIndex,
|
|
47917
|
-
endIndex
|
|
47918
|
-
});
|
|
47919
|
-
if (!processedIndices.has(startIndex)) {
|
|
47920
|
-
processedIndices.add(startIndex);
|
|
47921
|
-
if (startIndex > lastIndex) {
|
|
47922
|
-
const beforeText = text.substring(lastIndex, startIndex);
|
|
47923
|
-
chartElements.push(
|
|
47924
|
-
/* @__PURE__ */ jsx(
|
|
47925
|
-
"div",
|
|
47926
|
-
{
|
|
47927
|
-
dangerouslySetInnerHTML: { __html: formatMessage(beforeText) }
|
|
47928
|
-
},
|
|
47929
|
-
`text-${lastIndex}`
|
|
47930
|
-
)
|
|
47931
|
-
);
|
|
47932
|
-
}
|
|
47933
|
-
const chartType = match[1];
|
|
47934
|
-
const argsString = match[2];
|
|
47935
|
-
try {
|
|
47936
|
-
const args = parseChartArguments(argsString);
|
|
47937
|
-
const chartElement = renderChart(chartType, args, startIndex);
|
|
47938
|
-
if (chartElement) {
|
|
47939
|
-
console.log(`[DEBUG] Successfully rendered chart: ${chartType}`);
|
|
47940
|
-
chartElements.push(chartElement);
|
|
47941
|
-
} else {
|
|
47942
|
-
console.warn(`[DEBUG] Chart element was null for type: ${chartType}`);
|
|
47943
|
-
console.warn(`[DEBUG] Args were:`, args);
|
|
47944
|
-
chartElements.push(
|
|
47945
|
-
/* @__PURE__ */ jsxs(
|
|
47946
|
-
"div",
|
|
47947
|
-
{
|
|
47948
|
-
className: "text-red-500 text-sm border border-red-300 bg-red-50 p-3 rounded",
|
|
47949
|
-
children: [
|
|
47950
|
-
/* @__PURE__ */ jsx("strong", { children: "Chart Rendering Error:" }),
|
|
47951
|
-
" Failed to render ",
|
|
47952
|
-
chartType,
|
|
47953
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
47954
|
-
/* @__PURE__ */ jsxs("small", { children: [
|
|
47955
|
-
"Check console for details. Args: ",
|
|
47956
|
-
JSON.stringify(args, null, 2)
|
|
47957
|
-
] })
|
|
47958
|
-
]
|
|
47959
|
-
},
|
|
47960
|
-
`error-${startIndex}`
|
|
47961
|
-
)
|
|
47962
|
-
);
|
|
47963
|
-
}
|
|
47964
|
-
} catch (error) {
|
|
47965
|
-
console.error(`Failed to parse chart ${chartType}:`, error);
|
|
47966
|
-
console.error(`Args string was:`, argsString);
|
|
47967
|
-
chartElements.push(
|
|
47968
|
-
/* @__PURE__ */ jsxs(
|
|
47969
|
-
"div",
|
|
47970
|
-
{
|
|
47971
|
-
className: "text-red-500 text-sm border border-red-300 bg-red-50 p-3 rounded",
|
|
47972
|
-
children: [
|
|
47973
|
-
/* @__PURE__ */ jsx("strong", { children: "Chart Parsing Error:" }),
|
|
47974
|
-
" Failed to parse ",
|
|
47975
|
-
chartType,
|
|
47976
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
47977
|
-
/* @__PURE__ */ jsxs("small", { children: [
|
|
47978
|
-
"Error: ",
|
|
47979
|
-
error instanceof Error ? error.message : String(error)
|
|
47980
|
-
] }),
|
|
47981
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
47982
|
-
/* @__PURE__ */ jsxs("small", { children: [
|
|
47983
|
-
"Original: ",
|
|
47984
|
-
match[0]
|
|
47985
|
-
] })
|
|
47986
|
-
]
|
|
47987
|
-
},
|
|
47988
|
-
`error-${startIndex}`
|
|
47989
|
-
)
|
|
47990
|
-
);
|
|
47991
|
-
}
|
|
47992
|
-
lastIndex = endIndex;
|
|
47993
|
-
}
|
|
47994
|
-
}
|
|
47995
|
-
console.log(`[DEBUG] Total chart patterns found: ${matchCount}`);
|
|
47996
|
-
if (lastIndex < text.length) {
|
|
47997
|
-
const remainingText = text.substring(lastIndex);
|
|
47998
|
-
chartElements.push(
|
|
47999
|
-
/* @__PURE__ */ jsx(
|
|
48000
|
-
"div",
|
|
48001
|
-
{
|
|
48002
|
-
dangerouslySetInnerHTML: { __html: formatMessage(remainingText) }
|
|
48003
|
-
},
|
|
48004
|
-
`text-${lastIndex}`
|
|
48005
|
-
)
|
|
48006
|
-
);
|
|
48007
|
-
}
|
|
48008
|
-
if (chartElements.length === 1 && lastIndex === 0) {
|
|
48009
|
-
console.log("[DEBUG] No charts found in text, returning null");
|
|
48010
|
-
return null;
|
|
48011
|
-
}
|
|
48012
|
-
console.log(`[DEBUG] Returning ${chartElements.length} chart elements`);
|
|
48013
|
-
return chartElements;
|
|
48014
|
-
};
|
|
48015
|
-
const parseChartArguments = (argsString) => {
|
|
48016
|
-
console.log("[DEBUG] Parsing chart arguments:", argsString);
|
|
48017
|
-
const extractParameters = (str) => {
|
|
48018
|
-
const params = {};
|
|
48019
|
-
let currentPos = 0;
|
|
48020
|
-
while (currentPos < str.length) {
|
|
48021
|
-
while (currentPos < str.length && /\s|,/.test(str[currentPos])) {
|
|
48022
|
-
currentPos++;
|
|
48023
|
-
}
|
|
48024
|
-
if (currentPos >= str.length) break;
|
|
48025
|
-
const paramMatch = str.substring(currentPos).match(/^(\w+)\s*=/);
|
|
48026
|
-
if (!paramMatch) {
|
|
48027
|
-
console.warn("[DEBUG] No parameter name found at position", currentPos);
|
|
48028
|
-
break;
|
|
48029
|
-
}
|
|
48030
|
-
const paramName = paramMatch[1];
|
|
48031
|
-
currentPos += paramMatch[0].length;
|
|
48032
|
-
while (currentPos < str.length && /\s/.test(str[currentPos])) {
|
|
48033
|
-
currentPos++;
|
|
48034
|
-
}
|
|
48035
|
-
if (currentPos >= str.length) break;
|
|
48036
|
-
let value;
|
|
48037
|
-
let valueEnd;
|
|
48038
|
-
if (str[currentPos] === "[") {
|
|
48039
|
-
let bracketCount = 0;
|
|
48040
|
-
let arrayStart = currentPos;
|
|
48041
|
-
valueEnd = str.length;
|
|
48042
|
-
for (let i = currentPos; i < str.length; i++) {
|
|
48043
|
-
if (str[i] === "[") bracketCount++;
|
|
48044
|
-
else if (str[i] === "]") bracketCount--;
|
|
48045
|
-
if (bracketCount === 0) {
|
|
48046
|
-
valueEnd = i + 1;
|
|
48047
|
-
break;
|
|
48048
|
-
}
|
|
48049
|
-
}
|
|
48050
|
-
if (bracketCount !== 0) {
|
|
48051
|
-
console.error("[DEBUG] Unmatched brackets in array value");
|
|
48052
|
-
break;
|
|
48053
|
-
}
|
|
48054
|
-
const arrayStr = str.substring(arrayStart, valueEnd);
|
|
48055
|
-
console.log(`[DEBUG] Found array parameter: ${paramName} = ${arrayStr}`);
|
|
48056
|
-
try {
|
|
48057
|
-
value = JSON.parse(arrayStr);
|
|
48058
|
-
console.log(`[DEBUG] Successfully parsed array ${paramName}:`, value);
|
|
48059
|
-
} catch (e) {
|
|
48060
|
-
console.error(`[DEBUG] Failed to parse array ${paramName}:`, e);
|
|
48061
|
-
console.error(`Array value that failed:`, arrayStr);
|
|
48062
|
-
value = arrayStr;
|
|
48063
|
-
}
|
|
48064
|
-
} else if (str[currentPos] === "{") {
|
|
48065
|
-
let braceCount = 0;
|
|
48066
|
-
let objectStart = currentPos;
|
|
48067
|
-
valueEnd = str.length;
|
|
48068
|
-
for (let i = currentPos; i < str.length; i++) {
|
|
48069
|
-
if (str[i] === "{") braceCount++;
|
|
48070
|
-
else if (str[i] === "}") braceCount--;
|
|
48071
|
-
if (braceCount === 0) {
|
|
48072
|
-
valueEnd = i + 1;
|
|
48073
|
-
break;
|
|
48074
|
-
}
|
|
48075
|
-
}
|
|
48076
|
-
if (braceCount !== 0) {
|
|
48077
|
-
console.error("[DEBUG] Unmatched braces in object value");
|
|
48078
|
-
break;
|
|
48079
|
-
}
|
|
48080
|
-
const objectStr = str.substring(objectStart, valueEnd);
|
|
48081
|
-
console.log(`[DEBUG] Found object parameter: ${paramName} = ${objectStr}`);
|
|
48082
|
-
try {
|
|
48083
|
-
value = JSON.parse(objectStr);
|
|
48084
|
-
console.log(`[DEBUG] Successfully parsed object ${paramName}:`, value);
|
|
48085
|
-
} catch (e) {
|
|
48086
|
-
console.error(`[DEBUG] Failed to parse object ${paramName}:`, e);
|
|
48087
|
-
console.error(`Object value that failed:`, objectStr);
|
|
48088
|
-
value = objectStr;
|
|
48089
|
-
}
|
|
48090
|
-
} else if (str[currentPos] === '"') {
|
|
48091
|
-
let stringStart = currentPos + 1;
|
|
48092
|
-
let stringEnd = stringStart;
|
|
48093
|
-
while (stringEnd < str.length) {
|
|
48094
|
-
if (str[stringEnd] === '"' && str[stringEnd - 1] !== "\\") {
|
|
48095
|
-
break;
|
|
48096
|
-
}
|
|
48097
|
-
stringEnd++;
|
|
48098
|
-
}
|
|
48099
|
-
if (stringEnd >= str.length) {
|
|
48100
|
-
console.error("[DEBUG] Unterminated string value");
|
|
48101
|
-
valueEnd = str.length;
|
|
48102
|
-
break;
|
|
48103
|
-
}
|
|
48104
|
-
value = str.substring(stringStart, stringEnd);
|
|
48105
|
-
valueEnd = stringEnd + 1;
|
|
48106
|
-
console.log(`[DEBUG] Found string parameter: ${paramName} = "${value}"`);
|
|
48107
|
-
} else {
|
|
48108
|
-
let valueStart = currentPos;
|
|
48109
|
-
let valueEndPos = valueStart;
|
|
48110
|
-
while (valueEndPos < str.length && str[valueEndPos] !== ",") {
|
|
48111
|
-
valueEndPos++;
|
|
48112
|
-
}
|
|
48113
|
-
const rawValue = str.substring(valueStart, valueEndPos).trim();
|
|
48114
|
-
valueEnd = valueEndPos;
|
|
48115
|
-
if (rawValue === "true" || rawValue === "True") {
|
|
48116
|
-
value = true;
|
|
48117
|
-
} else if (rawValue === "false" || rawValue === "False") {
|
|
48118
|
-
value = false;
|
|
48119
|
-
} else if (rawValue === "null" || rawValue === "None") {
|
|
48120
|
-
value = null;
|
|
48121
|
-
} else if (!isNaN(Number(rawValue)) && rawValue !== "") {
|
|
48122
|
-
value = Number(rawValue);
|
|
48123
|
-
} else {
|
|
48124
|
-
value = rawValue;
|
|
48125
|
-
}
|
|
48126
|
-
console.log(`[DEBUG] Found unquoted parameter: ${paramName} = ${rawValue} (parsed as ${typeof value})`);
|
|
48127
|
-
}
|
|
48128
|
-
params[paramName] = value;
|
|
48129
|
-
currentPos = valueEnd;
|
|
48130
|
-
}
|
|
48131
|
-
return params;
|
|
48132
|
-
};
|
|
48133
|
-
const result = extractParameters(argsString);
|
|
48134
|
-
console.log("[DEBUG] Final parsed arguments:", result);
|
|
48135
|
-
return result;
|
|
48136
|
-
};
|
|
48137
|
-
const renderChart = (chartType, args, key) => {
|
|
48138
|
-
console.log(`[DEBUG] Attempting to render chart type: ${chartType}`, args);
|
|
48139
|
-
const CHART_COLORS = {
|
|
48140
|
-
primary: "#3b82f6",
|
|
48141
|
-
// blue-500
|
|
48142
|
-
secondary: "#10b981",
|
|
48143
|
-
// green-500
|
|
48144
|
-
accent: "#f59e0b",
|
|
48145
|
-
// amber-500
|
|
48146
|
-
danger: "#ef4444",
|
|
48147
|
-
// red-500
|
|
48148
|
-
violet: "#8b5cf6",
|
|
48149
|
-
// violet-500
|
|
48150
|
-
cyan: "#06b6d4",
|
|
48151
|
-
// cyan-500
|
|
48152
|
-
orange: "#f97316",
|
|
48153
|
-
// orange-500
|
|
48154
|
-
indigo: "#6366f1"
|
|
48155
|
-
// indigo-500
|
|
48156
|
-
};
|
|
48157
|
-
const CHART_COLOR_PALETTE = Object.values(CHART_COLORS);
|
|
48158
|
-
const CHART_STYLES = {
|
|
48159
|
-
grid: {
|
|
48160
|
-
strokeDasharray: "3 3",
|
|
48161
|
-
stroke: "#e5e7eb"
|
|
48162
|
-
// gray-300
|
|
48163
|
-
},
|
|
48164
|
-
axis: {
|
|
48165
|
-
tick: { fontSize: 12, fill: "#4b5563" },
|
|
48166
|
-
// gray-600
|
|
48167
|
-
stroke: "#9ca3af"
|
|
48168
|
-
// gray-400
|
|
48169
|
-
},
|
|
48170
|
-
margin: { top: 10, right: 30, left: 20, bottom: 40 },
|
|
48171
|
-
barRadius: [4, 4, 0, 0]
|
|
48172
|
-
// Top corners rounded
|
|
48173
|
-
};
|
|
48174
|
-
const CustomTooltip4 = ({ active, payload, label }) => {
|
|
48175
|
-
if (active && payload && payload.length) {
|
|
48176
|
-
return /* @__PURE__ */ jsxs("div", { className: "bg-white px-4 py-3 shadow-lg rounded-lg border border-gray-200", children: [
|
|
48177
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 mb-1", children: label }),
|
|
48178
|
-
payload.map((entry, index) => /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-600", style: { color: entry.color }, children: [
|
|
48179
|
-
entry.name,
|
|
48180
|
-
": ",
|
|
48181
|
-
typeof entry.value === "number" ? formatNumber(entry.value) : entry.value,
|
|
48182
|
-
args.unit || ""
|
|
48183
|
-
] }, index))
|
|
48184
|
-
] });
|
|
48185
|
-
}
|
|
48186
|
-
return null;
|
|
48187
|
-
};
|
|
48188
|
-
const DualAxisTooltip = ({ active, payload, label }) => {
|
|
48189
|
-
if (active && payload && payload.length) {
|
|
48190
|
-
return /* @__PURE__ */ jsxs("div", { className: "bg-white px-4 py-3 shadow-lg rounded-lg border border-gray-200", children: [
|
|
48191
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 mb-2", children: label }),
|
|
48192
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: payload.map((entry, index) => {
|
|
48193
|
-
const value = typeof entry.value === "number" ? formatNumber(entry.value) : entry.value;
|
|
48194
|
-
const unit = entry.dataKey === args.left_y_field ? args.left_unit || "" : entry.dataKey === args.right_y_field ? args.right_unit || "" : "";
|
|
48195
|
-
return /* @__PURE__ */ jsxs("p", { className: "text-sm", style: { color: entry.color }, children: [
|
|
48196
|
-
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
48197
|
-
entry.name,
|
|
48198
|
-
":"
|
|
48199
|
-
] }),
|
|
48200
|
-
" ",
|
|
48201
|
-
value,
|
|
48202
|
-
unit
|
|
48203
|
-
] }, index);
|
|
48204
|
-
}) })
|
|
48205
|
-
] });
|
|
48206
|
-
}
|
|
48207
|
-
return null;
|
|
48208
|
-
};
|
|
48209
|
-
const formatXAxisTick = (value) => {
|
|
48210
|
-
if (typeof value === "string") {
|
|
48211
|
-
if (value.match(/^\d{2}\/\d{2}\s/)) {
|
|
48212
|
-
return value;
|
|
48213
|
-
}
|
|
48214
|
-
if (value.length > 15) {
|
|
48215
|
-
return value.substring(0, 12) + "...";
|
|
48216
|
-
}
|
|
48217
|
-
}
|
|
48218
|
-
return value;
|
|
48219
|
-
};
|
|
48220
|
-
const ChartWrapper = ({ children, title }) => /* @__PURE__ */ jsxs("div", { className: "my-6 bg-white rounded-xl shadow-sm border border-gray-200 p-6", children: [
|
|
48221
|
-
title && /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold text-gray-900 mb-4", children: title }),
|
|
48222
|
-
children
|
|
48223
|
-
] });
|
|
48224
|
-
switch (chartType) {
|
|
48225
|
-
case "create_gauge_chart":
|
|
48226
|
-
console.log("[DEBUG] Rendering gauge chart");
|
|
48227
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "h-64 w-full flex justify-center", children: /* @__PURE__ */ jsx(
|
|
48228
|
-
GaugeChart,
|
|
48229
|
-
{
|
|
48230
|
-
value: args.value || 0,
|
|
48231
|
-
min: args.min_value || 0,
|
|
48232
|
-
max: args.max_value || 100,
|
|
48233
|
-
target: args.target,
|
|
48234
|
-
label: args.label || "",
|
|
48235
|
-
unit: args.unit || "",
|
|
48236
|
-
thresholds: args.thresholds,
|
|
48237
|
-
className: "w-full max-w-sm"
|
|
48238
|
-
}
|
|
48239
|
-
) }) }, `gauge-${key}`);
|
|
48240
|
-
case "create_bar_chart":
|
|
48241
|
-
console.log("[DEBUG] Rendering bar chart");
|
|
48242
|
-
if (!args.data || !args.x_field || !args.y_field) {
|
|
48243
|
-
console.error("Bar chart missing required parameters:", { data: !!args.data, x_field: !!args.x_field, y_field: !!args.y_field });
|
|
48244
|
-
return null;
|
|
48245
|
-
}
|
|
48246
|
-
if (!Array.isArray(args.data)) {
|
|
48247
|
-
console.error("Bar chart data must be an array, got:", typeof args.data, args.data);
|
|
48248
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48249
|
-
"Error: Chart data must be an array. Received: ",
|
|
48250
|
-
typeof args.data
|
|
48251
|
-
] }) }, `bar-error-${key}`);
|
|
48252
|
-
}
|
|
48253
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "w-full h-64", style: { minHeight: "200px", minWidth: "300px" }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(BarChart$1, { data: args.data, margin: CHART_STYLES.margin, children: [
|
|
48254
|
-
/* @__PURE__ */ jsx(CartesianGrid, { ...CHART_STYLES.grid }),
|
|
48255
|
-
/* @__PURE__ */ jsx(
|
|
48256
|
-
XAxis,
|
|
48257
|
-
{
|
|
48258
|
-
dataKey: args.x_field,
|
|
48259
|
-
...CHART_STYLES.axis,
|
|
48260
|
-
angle: -45,
|
|
48261
|
-
textAnchor: "end",
|
|
48262
|
-
height: 60,
|
|
48263
|
-
interval: 0,
|
|
48264
|
-
tickFormatter: formatXAxisTick
|
|
48265
|
-
}
|
|
48266
|
-
),
|
|
48267
|
-
/* @__PURE__ */ jsx(
|
|
48268
|
-
YAxis,
|
|
48269
|
-
{
|
|
48270
|
-
...CHART_STYLES.axis,
|
|
48271
|
-
tickFormatter: (value) => formatNumber(value)
|
|
48272
|
-
}
|
|
48273
|
-
),
|
|
48274
|
-
/* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(CustomTooltip4, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
|
|
48275
|
-
/* @__PURE__ */ jsx(
|
|
48276
|
-
Bar,
|
|
48277
|
-
{
|
|
48278
|
-
dataKey: args.y_field,
|
|
48279
|
-
fill: args.color || CHART_COLORS.primary,
|
|
48280
|
-
radius: CHART_STYLES.barRadius
|
|
48281
|
-
}
|
|
48282
|
-
)
|
|
48283
|
-
] }) }) }) }, `bar-${key}`);
|
|
48284
|
-
case "create_line_chart":
|
|
48285
|
-
console.log("[DEBUG] Rendering line chart");
|
|
48286
|
-
if (!args.data || !args.x_field || !args.y_field) {
|
|
48287
|
-
console.error("Line chart missing required parameters:", { data: !!args.data, x_field: !!args.x_field, y_field: !!args.y_field });
|
|
48288
|
-
return null;
|
|
48289
|
-
}
|
|
48290
|
-
if (!Array.isArray(args.data)) {
|
|
48291
|
-
console.error("Line chart data must be an array, got:", typeof args.data, args.data);
|
|
48292
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48293
|
-
"Error: Chart data must be an array. Received: ",
|
|
48294
|
-
typeof args.data
|
|
48295
|
-
] }) }, `line-error-${key}`);
|
|
48296
|
-
}
|
|
48297
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "w-full h-64", style: { minHeight: "200px", minWidth: "300px" }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(LineChart$1, { data: args.data, margin: CHART_STYLES.margin, children: [
|
|
48298
|
-
/* @__PURE__ */ jsx(CartesianGrid, { ...CHART_STYLES.grid }),
|
|
48299
|
-
/* @__PURE__ */ jsx(
|
|
48300
|
-
XAxis,
|
|
48301
|
-
{
|
|
48302
|
-
dataKey: args.x_field,
|
|
48303
|
-
...CHART_STYLES.axis,
|
|
48304
|
-
angle: -45,
|
|
48305
|
-
textAnchor: "end",
|
|
48306
|
-
height: 60,
|
|
48307
|
-
interval: 0,
|
|
48308
|
-
tickFormatter: formatXAxisTick
|
|
48309
|
-
}
|
|
48310
|
-
),
|
|
48311
|
-
/* @__PURE__ */ jsx(
|
|
48312
|
-
YAxis,
|
|
48313
|
-
{
|
|
48314
|
-
...CHART_STYLES.axis,
|
|
48315
|
-
tickFormatter: (value) => formatNumber(value)
|
|
48316
|
-
}
|
|
48317
|
-
),
|
|
48318
|
-
/* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(CustomTooltip4, {}), cursor: { strokeDasharray: "3 3" } }),
|
|
48319
|
-
/* @__PURE__ */ jsx(
|
|
48320
|
-
Line,
|
|
48321
|
-
{
|
|
48322
|
-
type: "monotone",
|
|
48323
|
-
dataKey: args.y_field,
|
|
48324
|
-
stroke: CHART_COLORS.primary,
|
|
48325
|
-
strokeWidth: 2,
|
|
48326
|
-
dot: { r: 4, fill: CHART_COLORS.primary },
|
|
48327
|
-
activeDot: { r: 6 }
|
|
48328
|
-
}
|
|
48329
|
-
)
|
|
48330
|
-
] }) }) }) }, `line-${key}`);
|
|
48331
|
-
case "create_pie_chart":
|
|
48332
|
-
console.log("[DEBUG] Rendering pie chart");
|
|
48333
|
-
if (!args.data || !args.label_field || !args.value_field) {
|
|
48334
|
-
console.error("Pie chart missing required parameters:", { data: !!args.data, label_field: !!args.label_field, value_field: !!args.value_field });
|
|
48335
|
-
console.error("Available args:", Object.keys(args));
|
|
48336
|
-
return null;
|
|
48337
|
-
}
|
|
48338
|
-
if (!Array.isArray(args.data)) {
|
|
48339
|
-
console.error("Pie chart data must be an array, got:", typeof args.data, args.data);
|
|
48340
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48341
|
-
"Error: Chart data must be an array. Received: ",
|
|
48342
|
-
typeof args.data
|
|
48343
|
-
] }) }, `pie-error-${key}`);
|
|
48344
|
-
}
|
|
48345
|
-
const pieData = args.data.map((item) => ({
|
|
48346
|
-
name: item[args.label_field],
|
|
48347
|
-
value: item[args.value_field]
|
|
48348
|
-
}));
|
|
48349
|
-
console.log("[DEBUG] Pie chart data transformed:", pieData);
|
|
48350
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "h-64 w-full max-w-md mx-auto", children: /* @__PURE__ */ jsx(
|
|
48351
|
-
PieChart4,
|
|
48352
|
-
{
|
|
48353
|
-
data: pieData,
|
|
48354
|
-
showPercentages: args.show_percentages || false,
|
|
48355
|
-
colors: CHART_COLOR_PALETTE
|
|
48356
|
-
}
|
|
48357
|
-
) }) }, `pie-${key}`);
|
|
48358
|
-
case "create_comparison_table":
|
|
48359
|
-
console.log("[DEBUG] Rendering comparison table");
|
|
48360
|
-
if (!args.data) {
|
|
48361
|
-
console.error("Comparison table missing required data");
|
|
48362
|
-
return null;
|
|
48363
|
-
}
|
|
48364
|
-
if (!Array.isArray(args.data)) {
|
|
48365
|
-
console.error("Comparison table data must be an array, got:", typeof args.data, args.data);
|
|
48366
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48367
|
-
"Error: Table data must be an array. Received: ",
|
|
48368
|
-
typeof args.data
|
|
48369
|
-
] }) }, `table-error-${key}`);
|
|
48370
|
-
}
|
|
48371
|
-
const columns = args.columns || Object.keys(args.data[0] || {});
|
|
48372
|
-
let sortedData = [...args.data];
|
|
48373
|
-
if (args.sort_by && columns.includes(args.sort_by)) {
|
|
48374
|
-
sortedData.sort((a, b) => {
|
|
48375
|
-
const aVal = a[args.sort_by];
|
|
48376
|
-
const bVal = b[args.sort_by];
|
|
48377
|
-
const comparison = aVal > bVal ? 1 : aVal < bVal ? -1 : 0;
|
|
48378
|
-
return args.sort_descending === false ? comparison : -comparison;
|
|
48379
|
-
});
|
|
48380
|
-
}
|
|
48381
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-lg border border-gray-200", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
|
|
48382
|
-
/* @__PURE__ */ jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsx(
|
|
48383
|
-
"th",
|
|
48384
|
-
{
|
|
48385
|
-
className: `px-6 py-3 text-left text-xs font-medium text-gray-600 uppercase tracking-wider ${col === args.highlight_column ? "bg-blue-50" : ""}`,
|
|
48386
|
-
children: col
|
|
48387
|
-
},
|
|
48388
|
-
col
|
|
48389
|
-
)) }) }),
|
|
48390
|
-
/* @__PURE__ */ jsx("tbody", { className: "bg-white divide-y divide-gray-200", children: sortedData.map((row, rowIdx) => /* @__PURE__ */ jsx("tr", { className: rowIdx % 2 === 0 ? "bg-white" : "bg-gray-50", children: columns.map((col) => /* @__PURE__ */ jsx(
|
|
48391
|
-
"td",
|
|
48392
|
-
{
|
|
48393
|
-
className: `px-6 py-4 whitespace-nowrap text-sm ${col === args.highlight_column ? "font-medium text-blue-600 bg-blue-50" : "text-gray-900"}`,
|
|
48394
|
-
children: typeof row[col] === "number" ? formatNumber(row[col]) : row[col]
|
|
48395
|
-
},
|
|
48396
|
-
col
|
|
48397
|
-
)) }, rowIdx)) })
|
|
48398
|
-
] }) }) }, `table-${key}`);
|
|
48399
|
-
case "create_multi_line_chart":
|
|
48400
|
-
console.log("[DEBUG] Rendering multi-line chart");
|
|
48401
|
-
if (!args.data || !args.x_field || !args.y_fields || !args.legend) {
|
|
48402
|
-
console.error("Multi-line chart missing required parameters:", {
|
|
48403
|
-
data: !!args.data,
|
|
48404
|
-
x_field: !!args.x_field,
|
|
48405
|
-
y_fields: !!args.y_fields,
|
|
48406
|
-
legend: !!args.legend
|
|
48407
|
-
});
|
|
48408
|
-
return null;
|
|
48409
|
-
}
|
|
48410
|
-
if (!Array.isArray(args.data)) {
|
|
48411
|
-
console.error("Multi-line chart data must be an array, got:", typeof args.data, args.data);
|
|
48412
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48413
|
-
"Error: Chart data must be an array. Received: ",
|
|
48414
|
-
typeof args.data
|
|
48415
|
-
] }) }, `multi-line-error-${key}`);
|
|
48416
|
-
}
|
|
48417
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(LineChart$1, { data: args.data, margin: CHART_STYLES.margin, children: [
|
|
48418
|
-
/* @__PURE__ */ jsx(CartesianGrid, { ...CHART_STYLES.grid }),
|
|
48419
|
-
/* @__PURE__ */ jsx(
|
|
48420
|
-
XAxis,
|
|
48421
|
-
{
|
|
48422
|
-
dataKey: args.x_field,
|
|
48423
|
-
...CHART_STYLES.axis,
|
|
48424
|
-
angle: -45,
|
|
48425
|
-
textAnchor: "end",
|
|
48426
|
-
height: 60,
|
|
48427
|
-
interval: 0,
|
|
48428
|
-
tickFormatter: formatXAxisTick
|
|
48429
|
-
}
|
|
48430
|
-
),
|
|
48431
|
-
/* @__PURE__ */ jsx(
|
|
48432
|
-
YAxis,
|
|
48433
|
-
{
|
|
48434
|
-
...CHART_STYLES.axis,
|
|
48435
|
-
tickFormatter: (value) => formatNumber(value)
|
|
48436
|
-
}
|
|
48437
|
-
),
|
|
48438
|
-
/* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(CustomTooltip4, {}), cursor: { strokeDasharray: "3 3" } }),
|
|
48439
|
-
/* @__PURE__ */ jsx(
|
|
48440
|
-
Legend,
|
|
48441
|
-
{
|
|
48442
|
-
wrapperStyle: { paddingTop: "20px" },
|
|
48443
|
-
formatter: (value) => /* @__PURE__ */ jsx("span", { className: "text-sm", children: value })
|
|
48444
|
-
}
|
|
48445
|
-
),
|
|
48446
|
-
args.y_fields.map((field, index) => /* @__PURE__ */ jsx(
|
|
48447
|
-
Line,
|
|
48448
|
-
{
|
|
48449
|
-
type: "monotone",
|
|
48450
|
-
dataKey: field,
|
|
48451
|
-
stroke: CHART_COLOR_PALETTE[index % CHART_COLOR_PALETTE.length],
|
|
48452
|
-
strokeWidth: 2,
|
|
48453
|
-
name: args.legend[index] || field,
|
|
48454
|
-
dot: { r: 4 },
|
|
48455
|
-
activeDot: { r: 6 }
|
|
48456
|
-
},
|
|
48457
|
-
field
|
|
48458
|
-
))
|
|
48459
|
-
] }) }) }) }, `multi-line-${key}`);
|
|
48460
|
-
case "create_stacked_bar_chart":
|
|
48461
|
-
console.log("[DEBUG] Rendering stacked bar chart");
|
|
48462
|
-
if (!args.data || !args.x_field || !args.stack_fields) {
|
|
48463
|
-
console.error("Stacked bar chart missing required parameters:", {
|
|
48464
|
-
data: !!args.data,
|
|
48465
|
-
x_field: !!args.x_field,
|
|
48466
|
-
stack_fields: !!args.stack_fields
|
|
48467
|
-
});
|
|
48468
|
-
return null;
|
|
48469
|
-
}
|
|
48470
|
-
if (!Array.isArray(args.data)) {
|
|
48471
|
-
console.error("Stacked bar chart data must be an array, got:", typeof args.data, args.data);
|
|
48472
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48473
|
-
"Error: Chart data must be an array. Received: ",
|
|
48474
|
-
typeof args.data
|
|
48475
|
-
] }) }, `stacked-bar-error-${key}`);
|
|
48476
|
-
}
|
|
48477
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(BarChart$1, { data: args.data, margin: CHART_STYLES.margin, children: [
|
|
48478
|
-
/* @__PURE__ */ jsx(CartesianGrid, { ...CHART_STYLES.grid }),
|
|
48479
|
-
/* @__PURE__ */ jsx(
|
|
48480
|
-
XAxis,
|
|
48481
|
-
{
|
|
48482
|
-
dataKey: args.x_field,
|
|
48483
|
-
...CHART_STYLES.axis,
|
|
48484
|
-
angle: -45,
|
|
48485
|
-
textAnchor: "end",
|
|
48486
|
-
height: 60,
|
|
48487
|
-
interval: 0,
|
|
48488
|
-
tickFormatter: formatXAxisTick
|
|
48489
|
-
}
|
|
48490
|
-
),
|
|
48491
|
-
/* @__PURE__ */ jsx(
|
|
48492
|
-
YAxis,
|
|
48493
|
-
{
|
|
48494
|
-
...CHART_STYLES.axis,
|
|
48495
|
-
tickFormatter: (value) => formatNumber(value)
|
|
48496
|
-
}
|
|
48497
|
-
),
|
|
48498
|
-
/* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(CustomTooltip4, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
|
|
48499
|
-
/* @__PURE__ */ jsx(
|
|
48500
|
-
Legend,
|
|
48501
|
-
{
|
|
48502
|
-
wrapperStyle: { paddingTop: "20px" },
|
|
48503
|
-
formatter: (value) => /* @__PURE__ */ jsx("span", { className: "text-sm", children: value })
|
|
48504
|
-
}
|
|
48505
|
-
),
|
|
48506
|
-
args.stack_fields.map((field, index) => /* @__PURE__ */ jsx(
|
|
48507
|
-
Bar,
|
|
48508
|
-
{
|
|
48509
|
-
dataKey: field,
|
|
48510
|
-
stackId: "stack",
|
|
48511
|
-
fill: CHART_COLOR_PALETTE[index % CHART_COLOR_PALETTE.length],
|
|
48512
|
-
name: field,
|
|
48513
|
-
radius: index === args.stack_fields.length - 1 ? CHART_STYLES.barRadius : void 0
|
|
48514
|
-
},
|
|
48515
|
-
field
|
|
48516
|
-
))
|
|
48517
|
-
] }) }) }) }, `stacked-bar-${key}`);
|
|
48518
|
-
case "create_dual_axis_chart":
|
|
48519
|
-
console.log("[DEBUG] Rendering dual-axis chart");
|
|
48520
|
-
if (!args.data || !args.x_field || !args.left_y_field || !args.right_y_field) {
|
|
48521
|
-
console.error("Dual-axis chart missing required parameters:", {
|
|
48522
|
-
data: !!args.data,
|
|
48523
|
-
x_field: !!args.x_field,
|
|
48524
|
-
left_y_field: !!args.left_y_field,
|
|
48525
|
-
right_y_field: !!args.right_y_field
|
|
48526
|
-
});
|
|
48527
|
-
return null;
|
|
48528
|
-
}
|
|
48529
|
-
if (!Array.isArray(args.data)) {
|
|
48530
|
-
console.error("Dual-axis chart data must be an array, got:", typeof args.data, args.data);
|
|
48531
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48532
|
-
"Error: Chart data must be an array. Received: ",
|
|
48533
|
-
typeof args.data
|
|
48534
|
-
] }) }, `dual-axis-error-${key}`);
|
|
48535
|
-
}
|
|
48536
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
|
|
48537
|
-
/* @__PURE__ */ jsx(CartesianGrid, { ...CHART_STYLES.grid }),
|
|
48538
|
-
/* @__PURE__ */ jsx(
|
|
48539
|
-
XAxis,
|
|
48540
|
-
{
|
|
48541
|
-
dataKey: args.x_field,
|
|
48542
|
-
...CHART_STYLES.axis,
|
|
48543
|
-
angle: -45,
|
|
48544
|
-
textAnchor: "end",
|
|
48545
|
-
height: 100,
|
|
48546
|
-
interval: 0,
|
|
48547
|
-
tickFormatter: formatXAxisTick
|
|
48548
|
-
}
|
|
48549
|
-
),
|
|
48550
|
-
/* @__PURE__ */ jsx(
|
|
48551
|
-
YAxis,
|
|
48552
|
-
{
|
|
48553
|
-
yAxisId: "left",
|
|
48554
|
-
orientation: "left",
|
|
48555
|
-
label: {
|
|
48556
|
-
value: args.left_label || args.left_y_field,
|
|
48557
|
-
angle: -90,
|
|
48558
|
-
position: "insideLeft",
|
|
48559
|
-
style: { textAnchor: "middle", fill: "#4b5563" }
|
|
48560
|
-
},
|
|
48561
|
-
...CHART_STYLES.axis,
|
|
48562
|
-
tickFormatter: (value) => `${formatNumber(value)}${args.left_unit || ""}`
|
|
48563
|
-
}
|
|
48564
|
-
),
|
|
48565
|
-
/* @__PURE__ */ jsx(
|
|
48566
|
-
YAxis,
|
|
48567
|
-
{
|
|
48568
|
-
yAxisId: "right",
|
|
48569
|
-
orientation: "right",
|
|
48570
|
-
label: {
|
|
48571
|
-
value: args.right_label || args.right_y_field,
|
|
48572
|
-
angle: 90,
|
|
48573
|
-
position: "insideRight",
|
|
48574
|
-
style: { textAnchor: "middle", fill: "#4b5563" }
|
|
48575
|
-
},
|
|
48576
|
-
...CHART_STYLES.axis,
|
|
48577
|
-
tickFormatter: (value) => `${formatNumber(value)}${args.right_unit || ""}`
|
|
48578
|
-
}
|
|
48579
|
-
),
|
|
48580
|
-
/* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(DualAxisTooltip, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
|
|
48581
|
-
/* @__PURE__ */ jsx(
|
|
48582
|
-
Legend,
|
|
48583
|
-
{
|
|
48584
|
-
wrapperStyle: { paddingTop: "20px" },
|
|
48585
|
-
formatter: (value) => /* @__PURE__ */ jsx("span", { className: "text-sm", children: value })
|
|
48586
|
-
}
|
|
48587
|
-
),
|
|
48588
|
-
/* @__PURE__ */ jsx(
|
|
48589
|
-
Bar,
|
|
48590
|
-
{
|
|
48591
|
-
yAxisId: "left",
|
|
48592
|
-
dataKey: args.left_y_field,
|
|
48593
|
-
fill: CHART_COLORS.primary,
|
|
48594
|
-
name: args.left_label || args.left_y_field,
|
|
48595
|
-
radius: CHART_STYLES.barRadius
|
|
48596
|
-
}
|
|
48597
|
-
),
|
|
48598
|
-
/* @__PURE__ */ jsx(
|
|
48599
|
-
Line,
|
|
48600
|
-
{
|
|
48601
|
-
yAxisId: "right",
|
|
48602
|
-
type: "monotone",
|
|
48603
|
-
dataKey: args.right_y_field,
|
|
48604
|
-
stroke: CHART_COLORS.danger,
|
|
48605
|
-
strokeWidth: 3,
|
|
48606
|
-
name: args.right_label || args.right_y_field,
|
|
48607
|
-
dot: { r: 5, fill: CHART_COLORS.danger },
|
|
48608
|
-
activeDot: { r: 7 }
|
|
48609
|
-
}
|
|
48610
|
-
)
|
|
48611
|
-
] }) }) }) }, `dual-axis-${key}`);
|
|
48612
|
-
case "create_scatter_plot":
|
|
48613
|
-
console.log("[DEBUG] Rendering scatter plot");
|
|
48614
|
-
if (!args.data || !args.x_field || !args.y_field || !args.group_field) {
|
|
48615
|
-
console.error("Scatter plot missing required parameters:", {
|
|
48616
|
-
data: !!args.data,
|
|
48617
|
-
x_field: !!args.x_field,
|
|
48618
|
-
y_field: !!args.y_field,
|
|
48619
|
-
group_field: !!args.group_field
|
|
48620
|
-
});
|
|
48621
|
-
return null;
|
|
48622
|
-
}
|
|
48623
|
-
if (!Array.isArray(args.data)) {
|
|
48624
|
-
console.error("Scatter plot data must be an array, got:", typeof args.data, args.data);
|
|
48625
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48626
|
-
"Error: Chart data must be an array. Received: ",
|
|
48627
|
-
typeof args.data
|
|
48628
|
-
] }) }, `scatter-error-${key}`);
|
|
48629
|
-
}
|
|
48630
|
-
const groupedData = args.data.reduce((acc, item) => {
|
|
48631
|
-
const group = item[args.group_field];
|
|
48632
|
-
if (!acc[group]) {
|
|
48633
|
-
acc[group] = [];
|
|
48634
|
-
}
|
|
48635
|
-
acc[group].push(item);
|
|
48636
|
-
return acc;
|
|
48637
|
-
}, {});
|
|
48638
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(ScatterChart, { margin: CHART_STYLES.margin, children: [
|
|
48639
|
-
/* @__PURE__ */ jsx(CartesianGrid, { ...CHART_STYLES.grid }),
|
|
48640
|
-
/* @__PURE__ */ jsx(
|
|
48641
|
-
XAxis,
|
|
48642
|
-
{
|
|
48643
|
-
dataKey: args.x_field,
|
|
48644
|
-
type: "number",
|
|
48645
|
-
name: args.x_field,
|
|
48646
|
-
...CHART_STYLES.axis
|
|
48647
|
-
}
|
|
48648
|
-
),
|
|
48649
|
-
/* @__PURE__ */ jsx(
|
|
48650
|
-
YAxis,
|
|
48651
|
-
{
|
|
48652
|
-
dataKey: args.y_field,
|
|
48653
|
-
type: "number",
|
|
48654
|
-
name: args.y_field,
|
|
48655
|
-
...CHART_STYLES.axis
|
|
48656
|
-
}
|
|
48657
|
-
),
|
|
48658
|
-
/* @__PURE__ */ jsx(
|
|
48659
|
-
Tooltip,
|
|
48660
|
-
{
|
|
48661
|
-
cursor: { strokeDasharray: "3 3" },
|
|
48662
|
-
content: /* @__PURE__ */ jsx(CustomTooltip4, {})
|
|
48663
|
-
}
|
|
48664
|
-
),
|
|
48665
|
-
/* @__PURE__ */ jsx(
|
|
48666
|
-
Legend,
|
|
48667
|
-
{
|
|
48668
|
-
wrapperStyle: { paddingTop: "20px" },
|
|
48669
|
-
formatter: (value) => /* @__PURE__ */ jsx("span", { className: "text-sm", children: value })
|
|
48670
|
-
}
|
|
48671
|
-
),
|
|
48672
|
-
Object.entries(groupedData).map(([group, data], index) => /* @__PURE__ */ jsx(
|
|
48673
|
-
Scatter,
|
|
48674
|
-
{
|
|
48675
|
-
name: group,
|
|
48676
|
-
data,
|
|
48677
|
-
fill: CHART_COLOR_PALETTE[index % CHART_COLOR_PALETTE.length]
|
|
48678
|
-
},
|
|
48679
|
-
group
|
|
48680
|
-
))
|
|
48681
|
-
] }) }) }) }, `scatter-${key}`);
|
|
48682
|
-
case "create_combo_chart":
|
|
48683
|
-
console.log("[DEBUG] Rendering combo chart");
|
|
48684
|
-
if (!args.data || !args.x_field || !args.bar_field || !args.line_field) {
|
|
48685
|
-
console.error("Combo chart missing required parameters:", {
|
|
48686
|
-
data: !!args.data,
|
|
48687
|
-
x_field: !!args.x_field,
|
|
48688
|
-
bar_field: !!args.bar_field,
|
|
48689
|
-
line_field: !!args.line_field
|
|
48690
|
-
});
|
|
48691
|
-
return null;
|
|
48692
|
-
}
|
|
48693
|
-
if (!Array.isArray(args.data)) {
|
|
48694
|
-
console.error("Combo chart data must be an array, got:", typeof args.data, args.data);
|
|
48695
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48696
|
-
"Error: Chart data must be an array. Received: ",
|
|
48697
|
-
typeof args.data
|
|
48698
|
-
] }) }, `combo-error-${key}`);
|
|
48699
|
-
}
|
|
48700
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
|
|
48701
|
-
/* @__PURE__ */ jsx(CartesianGrid, { ...CHART_STYLES.grid }),
|
|
48702
|
-
/* @__PURE__ */ jsx(
|
|
48703
|
-
XAxis,
|
|
48704
|
-
{
|
|
48705
|
-
dataKey: args.x_field,
|
|
48706
|
-
...CHART_STYLES.axis,
|
|
48707
|
-
angle: -45,
|
|
48708
|
-
textAnchor: "end",
|
|
48709
|
-
height: 100,
|
|
48710
|
-
interval: 0,
|
|
48711
|
-
tickFormatter: formatXAxisTick
|
|
48712
|
-
}
|
|
48713
|
-
),
|
|
48714
|
-
/* @__PURE__ */ jsx(
|
|
48715
|
-
YAxis,
|
|
48716
|
-
{
|
|
48717
|
-
yAxisId: "left",
|
|
48718
|
-
orientation: "left",
|
|
48719
|
-
...CHART_STYLES.axis,
|
|
48720
|
-
tickFormatter: (value) => formatNumber(value)
|
|
48721
|
-
}
|
|
48722
|
-
),
|
|
48723
|
-
/* @__PURE__ */ jsx(
|
|
48724
|
-
YAxis,
|
|
48725
|
-
{
|
|
48726
|
-
yAxisId: "right",
|
|
48727
|
-
orientation: "right",
|
|
48728
|
-
...CHART_STYLES.axis,
|
|
48729
|
-
tickFormatter: (value) => formatNumber(value)
|
|
48730
|
-
}
|
|
48731
|
-
),
|
|
48732
|
-
/* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(CustomTooltip4, {}), cursor: { fill: "rgba(0, 0, 0, 0.05)" } }),
|
|
48733
|
-
/* @__PURE__ */ jsx(
|
|
48734
|
-
Legend,
|
|
48735
|
-
{
|
|
48736
|
-
wrapperStyle: { paddingTop: "20px" },
|
|
48737
|
-
formatter: (value) => /* @__PURE__ */ jsx("span", { className: "text-sm", children: value })
|
|
48738
|
-
}
|
|
48739
|
-
),
|
|
48740
|
-
/* @__PURE__ */ jsx(
|
|
48741
|
-
Bar,
|
|
48742
|
-
{
|
|
48743
|
-
yAxisId: "left",
|
|
48744
|
-
dataKey: args.bar_field,
|
|
48745
|
-
fill: CHART_COLORS.primary,
|
|
48746
|
-
name: args.bar_field,
|
|
48747
|
-
radius: CHART_STYLES.barRadius
|
|
48748
|
-
}
|
|
48749
|
-
),
|
|
48750
|
-
/* @__PURE__ */ jsx(
|
|
48751
|
-
Line,
|
|
48752
|
-
{
|
|
48753
|
-
yAxisId: "right",
|
|
48754
|
-
type: "monotone",
|
|
48755
|
-
dataKey: args.line_field,
|
|
48756
|
-
stroke: CHART_COLORS.danger,
|
|
48757
|
-
strokeWidth: 3,
|
|
48758
|
-
name: args.line_field,
|
|
48759
|
-
dot: { r: 5 },
|
|
48760
|
-
activeDot: { r: 7 }
|
|
48761
|
-
}
|
|
48762
|
-
)
|
|
48763
|
-
] }) }) }) }, `combo-${key}`);
|
|
48764
|
-
case "create_area_chart":
|
|
48765
|
-
console.log("[DEBUG] Rendering area chart");
|
|
48766
|
-
if (!args.data || !args.x_field || !args.y_field) {
|
|
48767
|
-
console.error("Area chart missing required parameters:", {
|
|
48768
|
-
data: !!args.data,
|
|
48769
|
-
x_field: !!args.x_field,
|
|
48770
|
-
y_field: !!args.y_field
|
|
48771
|
-
});
|
|
48772
|
-
return null;
|
|
48773
|
-
}
|
|
48774
|
-
if (!Array.isArray(args.data)) {
|
|
48775
|
-
console.error("Area chart data must be an array, got:", typeof args.data, args.data);
|
|
48776
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsxs("div", { className: "text-red-500 text-sm", children: [
|
|
48777
|
-
"Error: Chart data must be an array. Received: ",
|
|
48778
|
-
typeof args.data
|
|
48779
|
-
] }) }, `area-error-${key}`);
|
|
48780
|
-
}
|
|
48781
|
-
return /* @__PURE__ */ jsx(ChartWrapper, { title: args.title, children: /* @__PURE__ */ jsx("div", { className: "w-full h-80", style: { minHeight: "250px", minWidth: "300px" }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(ComposedChart, { data: args.data, margin: { ...CHART_STYLES.margin, bottom: 80 }, children: [
|
|
48782
|
-
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "colorGradient", x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
48783
|
-
/* @__PURE__ */ jsx("stop", { offset: "5%", stopColor: CHART_COLORS.primary, stopOpacity: 0.8 }),
|
|
48784
|
-
/* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: CHART_COLORS.primary, stopOpacity: 0.1 })
|
|
48785
|
-
] }) }),
|
|
48786
|
-
/* @__PURE__ */ jsx(CartesianGrid, { ...CHART_STYLES.grid }),
|
|
48787
|
-
/* @__PURE__ */ jsx(
|
|
48788
|
-
XAxis,
|
|
48789
|
-
{
|
|
48790
|
-
dataKey: args.x_field,
|
|
48791
|
-
...CHART_STYLES.axis,
|
|
48792
|
-
angle: -45,
|
|
48793
|
-
textAnchor: "end",
|
|
48794
|
-
height: 100,
|
|
48795
|
-
interval: 0,
|
|
48796
|
-
tickFormatter: formatXAxisTick
|
|
48797
|
-
}
|
|
48798
|
-
),
|
|
48799
|
-
/* @__PURE__ */ jsx(
|
|
48800
|
-
YAxis,
|
|
48801
|
-
{
|
|
48802
|
-
...CHART_STYLES.axis,
|
|
48803
|
-
tickFormatter: (value) => formatNumber(value)
|
|
48804
|
-
}
|
|
48805
|
-
),
|
|
48806
|
-
/* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(CustomTooltip4, {}), cursor: { strokeDasharray: "3 3" } }),
|
|
48807
|
-
/* @__PURE__ */ jsx(
|
|
48808
|
-
Legend,
|
|
48809
|
-
{
|
|
48810
|
-
wrapperStyle: { paddingTop: "20px" },
|
|
48811
|
-
formatter: (value) => /* @__PURE__ */ jsx("span", { className: "text-sm", children: value })
|
|
48812
|
-
}
|
|
48813
|
-
),
|
|
48814
|
-
/* @__PURE__ */ jsx(
|
|
48815
|
-
Area,
|
|
48816
|
-
{
|
|
48817
|
-
type: "monotone",
|
|
48818
|
-
dataKey: args.y_field,
|
|
48819
|
-
stroke: CHART_COLORS.primary,
|
|
48820
|
-
strokeWidth: 2,
|
|
48821
|
-
fill: args.fill !== false ? "url(#colorGradient)" : "none",
|
|
48822
|
-
name: args.y_field,
|
|
48823
|
-
dot: { r: 4, fill: CHART_COLORS.primary },
|
|
48824
|
-
activeDot: { r: 6 }
|
|
48825
|
-
}
|
|
48826
|
-
)
|
|
48827
|
-
] }) }) }) }, `area-${key}`);
|
|
48828
|
-
default:
|
|
48829
|
-
console.warn(`Unknown chart type: ${chartType}`);
|
|
48830
|
-
return null;
|
|
48831
|
-
}
|
|
48832
|
-
};
|
|
48833
|
-
const chartContent = parseChartPatterns(content);
|
|
48834
|
-
let finalNode;
|
|
48835
|
-
if (chartContent) {
|
|
48836
|
-
finalNode = /* @__PURE__ */ jsx("div", { className: "formatted-content", children: chartContent });
|
|
48837
|
-
} else {
|
|
48838
|
-
finalNode = /* @__PURE__ */ jsx(
|
|
48839
|
-
"div",
|
|
48840
|
-
{
|
|
48841
|
-
className: "formatted-content",
|
|
48842
|
-
dangerouslySetInnerHTML: { __html: formatMessage(content) }
|
|
48843
|
-
}
|
|
48844
|
-
);
|
|
48845
|
-
}
|
|
48846
|
-
renderedContentCache.current.set(content, finalNode);
|
|
48847
|
-
return finalNode;
|
|
48848
|
-
};
|
|
48849
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex h-screen bg-white", children: [
|
|
48850
|
-
/* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: {
|
|
48851
|
-
__html: `
|
|
48852
|
-
@keyframes slideDown {
|
|
48853
|
-
0% {
|
|
48854
|
-
transform: translateY(-40vh);
|
|
48855
|
-
opacity: 1;
|
|
48856
|
-
}
|
|
48857
|
-
100% {
|
|
48858
|
-
transform: translateY(0);
|
|
48859
|
-
opacity: 1;
|
|
48860
|
-
}
|
|
48861
|
-
}
|
|
48862
|
-
|
|
48863
|
-
@keyframes waveLoad {
|
|
48864
|
-
0% {
|
|
48865
|
-
background-position: -200% 0;
|
|
48866
|
-
}
|
|
48867
|
-
100% {
|
|
48868
|
-
background-position: 200% 0;
|
|
48869
|
-
}
|
|
48870
|
-
}
|
|
48871
|
-
|
|
48872
|
-
.thinking-wave {
|
|
48873
|
-
background: linear-gradient(
|
|
48874
|
-
90deg,
|
|
48875
|
-
#6b7280 0%,
|
|
48876
|
-
#6b7280 40%,
|
|
48877
|
-
#3b82f6 50%,
|
|
48878
|
-
#6b7280 60%,
|
|
48879
|
-
#6b7280 100%
|
|
48880
|
-
);
|
|
48881
|
-
background-size: 200% 100%;
|
|
48882
|
-
-webkit-background-clip: text;
|
|
48883
|
-
background-clip: text;
|
|
48884
|
-
-webkit-text-fill-color: transparent;
|
|
48885
|
-
animation: waveLoad 3s ease-in-out infinite;
|
|
48886
|
-
}
|
|
48887
|
-
`
|
|
48888
|
-
} }),
|
|
48889
|
-
/* @__PURE__ */ jsxs("div", { className: `flex-1 flex flex-col h-screen transition-all duration-300 ${isSidebarOpen ? "lg:mr-80 mr-0" : "mr-0"}`, children: [
|
|
48890
|
-
/* @__PURE__ */ jsxs("header", { className: "flex-shrink-0 bg-white px-3 sm:px-6 md:px-8 py-2 sm:py-5 md:py-6 shadow-sm border-b border-gray-200/80 sticky top-0 z-10", children: [
|
|
48891
|
-
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
48892
|
-
/* @__PURE__ */ jsx(
|
|
48893
|
-
"button",
|
|
48894
|
-
{
|
|
48895
|
-
onClick: () => navigate("/"),
|
|
48896
|
-
className: "p-2 -ml-2 rounded-full active:bg-gray-100 transition-colors",
|
|
48897
|
-
"aria-label": "Navigate back",
|
|
48898
|
-
children: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5 text-gray-700", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
48899
|
-
}
|
|
48900
|
-
),
|
|
48901
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center", children: [
|
|
48902
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
48903
|
-
/* @__PURE__ */ jsx("h1", { className: "text-base font-semibold text-gray-900", children: "Chat with Axel" }),
|
|
48904
|
-
/* @__PURE__ */ jsxs("div", { className: "relative flex h-2 w-2", children: [
|
|
48905
|
-
/* @__PURE__ */ jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
|
|
48906
|
-
/* @__PURE__ */ jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-green-500" })
|
|
48907
|
-
] })
|
|
48908
|
-
] }),
|
|
48909
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-gray-500", children: /* @__PURE__ */ jsx(ISTTimer_default, {}) })
|
|
48910
|
-
] }),
|
|
48911
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
48912
|
-
/* @__PURE__ */ jsx(
|
|
48913
|
-
"button",
|
|
48914
|
-
{
|
|
48915
|
-
onClick: handleNewThread,
|
|
48916
|
-
className: "p-2 rounded-full active:bg-gray-100 transition-colors",
|
|
48917
|
-
"aria-label": "New chat",
|
|
48918
|
-
title: "New chat",
|
|
48919
|
-
children: /* @__PURE__ */ jsx(RefreshCw, { className: "w-5 h-5 text-gray-700" })
|
|
48920
|
-
}
|
|
48921
|
-
),
|
|
48922
|
-
/* @__PURE__ */ jsx(
|
|
48923
|
-
"button",
|
|
48924
|
-
{
|
|
48925
|
-
onClick: () => setIsSidebarOpen(!isSidebarOpen),
|
|
48926
|
-
className: "relative p-2 -mr-2 rounded-full active:bg-gray-100 transition-colors",
|
|
48927
|
-
"aria-label": "Toggle chat history",
|
|
48928
|
-
title: isSidebarOpen ? "Hide history" : "Show history",
|
|
48929
|
-
children: isSidebarOpen ? /* @__PURE__ */ jsx(X, { className: "w-5 h-5 text-gray-700" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
48930
|
-
/* @__PURE__ */ jsx(Menu, { className: "w-5 h-5 text-gray-700" }),
|
|
48931
|
-
newChatCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute top-1 right-1 bg-red-500 text-white text-[9px] rounded-full w-4 h-4 flex items-center justify-center font-medium", children: newChatCount })
|
|
48932
|
-
] })
|
|
48933
|
-
}
|
|
48934
|
-
)
|
|
48935
|
-
] })
|
|
48936
|
-
] }) }),
|
|
48937
|
-
/* @__PURE__ */ jsxs("div", { className: "hidden sm:flex items-center justify-between relative", children: [
|
|
48938
|
-
/* @__PURE__ */ jsx("div", { className: "absolute left-0", children: /* @__PURE__ */ jsx(
|
|
48939
|
-
BackButtonMinimal,
|
|
48940
|
-
{
|
|
48941
|
-
onClick: () => navigate("/"),
|
|
48942
|
-
text: "Back",
|
|
48943
|
-
size: "default",
|
|
48944
|
-
"aria-label": "Navigate back to dashboard"
|
|
48945
|
-
}
|
|
48946
|
-
) }),
|
|
48947
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 text-center mx-auto", children: [
|
|
48948
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-3 mb-1", children: [
|
|
48949
|
-
/* @__PURE__ */ jsx("h1", { className: "text-xl md:text-2xl lg:text-3xl font-semibold text-gray-900", children: "Chat with Axel" }),
|
|
48950
|
-
/* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 md:h-2 md:w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
48951
|
-
] }),
|
|
48952
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: /* @__PURE__ */ jsx(ISTTimer_default, {}) }) })
|
|
48953
|
-
] }),
|
|
48954
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute right-0 flex items-center gap-2", children: [
|
|
48955
|
-
/* @__PURE__ */ jsxs(
|
|
48956
|
-
"button",
|
|
48957
|
-
{
|
|
48958
|
-
onClick: handleNewThread,
|
|
48959
|
-
className: "flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium",
|
|
48960
|
-
children: [
|
|
48961
|
-
/* @__PURE__ */ jsx(RefreshCw, { className: "w-4 h-4" }),
|
|
48962
|
-
/* @__PURE__ */ jsx("span", { children: "New Chat" })
|
|
48963
|
-
]
|
|
48964
|
-
}
|
|
48965
|
-
),
|
|
48966
|
-
/* @__PURE__ */ jsx(
|
|
48967
|
-
"button",
|
|
48968
|
-
{
|
|
48969
|
-
onClick: () => setIsSidebarOpen(!isSidebarOpen),
|
|
48970
|
-
className: "relative flex items-center gap-2 px-4 py-2 text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors text-sm font-medium",
|
|
48971
|
-
"aria-label": "Toggle chat history",
|
|
48972
|
-
children: isSidebarOpen ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
48973
|
-
/* @__PURE__ */ jsx(X, { className: "w-4 h-4" }),
|
|
48974
|
-
/* @__PURE__ */ jsx("span", { children: "Hide History" })
|
|
48975
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
48976
|
-
/* @__PURE__ */ jsx(Menu, { className: "w-4 h-4" }),
|
|
48977
|
-
/* @__PURE__ */ jsx("span", { children: "Chat History" }),
|
|
48978
|
-
newChatCount > 0 && /* @__PURE__ */ jsx("span", { className: "ml-1 bg-red-500 text-white text-xs rounded-full px-2 py-0.5 font-medium", children: newChatCount })
|
|
48979
|
-
] })
|
|
48980
|
-
}
|
|
48981
|
-
)
|
|
48982
|
-
] })
|
|
48983
|
-
] })
|
|
48984
|
-
] }),
|
|
48985
|
-
/* @__PURE__ */ jsx(
|
|
48986
|
-
"main",
|
|
48987
|
-
{
|
|
48988
|
-
ref: containerRef,
|
|
48989
|
-
className: `flex-1 bg-gray-50/50 min-h-0 ${displayMessages.length === 0 && !isTransitioning ? "flex items-center justify-center" : "overflow-y-auto"}`,
|
|
48990
|
-
children: !activeThreadId && displayMessages.length === 0 && !isTransitioning ? (
|
|
48991
|
-
/* Centered welcome and input for new chat */
|
|
48992
|
-
/* @__PURE__ */ jsxs("div", { className: "w-full max-w-3xl mx-auto px-3 sm:px-4 md:px-6 flex flex-col items-center justify-center space-y-8 sm:space-y-12 -mt-8 sm:-mt-16", children: [
|
|
48993
|
-
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
48994
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center mb-4 sm:mb-6 md:mb-8", children: /* @__PURE__ */ jsx(ProfilePicture, { alt: "Axel - AI Manufacturing Expert", size: "2xl", animate: true }) }),
|
|
48995
|
-
/* @__PURE__ */ jsxs("h2", { className: "text-lg sm:text-xl md:text-2xl lg:text-3xl font-semibold text-gray-900 px-2 sm:px-4", children: [
|
|
48996
|
-
typedText,
|
|
48997
|
-
typedText.length < currentGreeting.length && /* @__PURE__ */ jsx("span", { className: "animate-pulse", children: "|" })
|
|
48998
|
-
] })
|
|
48999
|
-
] }),
|
|
49000
|
-
/* @__PURE__ */ jsx("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
|
|
49001
|
-
/* @__PURE__ */ jsx("div", { className: "relative bg-white rounded-2xl sm:rounded-3xl shadow-lg border border-gray-200 focus-within:border-gray-300 transition-all duration-200", children: /* @__PURE__ */ jsx("div", { className: "flex items-end gap-2 p-3 sm:p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex-1 relative", children: [
|
|
49002
|
-
/* @__PURE__ */ jsx(
|
|
49003
|
-
"textarea",
|
|
49004
|
-
{
|
|
49005
|
-
ref: textareaRef,
|
|
49006
|
-
value: inputValue,
|
|
49007
|
-
onChange: (e) => {
|
|
49008
|
-
const newValue = e.target.value;
|
|
49009
|
-
setInputValue(newValue);
|
|
49010
|
-
if (newValue.length > 0 && !hasStartedTyping) {
|
|
49011
|
-
trackTypingStart();
|
|
49012
|
-
}
|
|
49013
|
-
if (newValue.length > 0) {
|
|
49014
|
-
trackTypingProgress(newValue);
|
|
49015
|
-
}
|
|
49016
|
-
if (newValue.length === 0) {
|
|
49017
|
-
resetTypingState();
|
|
49018
|
-
}
|
|
49019
|
-
},
|
|
49020
|
-
onKeyDown: handleKeyDown,
|
|
49021
|
-
onFocus: () => {
|
|
49022
|
-
trackCoreEvent("AI Agent Input Focused", {
|
|
49023
|
-
line_id: lineId,
|
|
49024
|
-
company_id: companyId,
|
|
49025
|
-
shift_id: shiftId,
|
|
49026
|
-
active_thread_id: activeThreadId,
|
|
49027
|
-
has_existing_messages: messages.length > 0,
|
|
49028
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
49029
|
-
});
|
|
49030
|
-
},
|
|
49031
|
-
placeholder: "Ask me anything about your shop-floor",
|
|
49032
|
-
className: "w-full resize-none bg-transparent px-3 sm:px-4 py-3 sm:py-2 pr-12 sm:pr-14 focus:outline-none placeholder-gray-500 text-gray-900 text-sm sm:text-base leading-relaxed",
|
|
49033
|
-
rows: 1,
|
|
49034
|
-
style: { minHeight: "40px", maxHeight: "120px" }
|
|
49035
|
-
}
|
|
49036
|
-
),
|
|
49037
|
-
/* @__PURE__ */ jsx("div", { className: "absolute right-2 sm:right-3 bottom-2 sm:bottom-2 flex items-center gap-2", children: /* @__PURE__ */ jsx(
|
|
49038
|
-
"button",
|
|
49039
|
-
{
|
|
49040
|
-
type: "submit",
|
|
49041
|
-
disabled: !inputValue.trim() || isCurrentThreadLoading,
|
|
49042
|
-
className: "inline-flex items-center justify-center w-8 h-8 sm:w-9 sm:h-9 bg-gray-900 text-white rounded-full hover:bg-gray-800 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-gray-500/20",
|
|
49043
|
-
children: /* @__PURE__ */ jsx(Send, { className: "w-4 h-4" })
|
|
49044
|
-
}
|
|
49045
|
-
) })
|
|
49046
|
-
] }) }) }),
|
|
49047
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row items-center justify-center gap-2 sm:gap-4 mt-2 text-xs text-gray-400", children: [
|
|
49048
|
-
/* @__PURE__ */ jsx("span", { className: "text-center", children: isCurrentThreadLoading ? "You can type your next message while Axel responds" : "Press Enter to send \u2022 Shift+Enter for new line" }),
|
|
49049
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
49050
|
-
/* @__PURE__ */ jsx("div", { className: `w-1.5 h-1.5 rounded-full ${isCurrentThreadLoading ? "bg-orange-500" : "bg-green-500"}` }),
|
|
49051
|
-
/* @__PURE__ */ jsx("span", { children: isCurrentThreadLoading ? "Responding..." : "Connected" })
|
|
49052
|
-
] })
|
|
49053
|
-
] })
|
|
49054
|
-
] }) })
|
|
49055
|
-
] })
|
|
49056
|
-
) : isTransitioning ? (
|
|
49057
|
-
/* Transition state - show user message first, then thinking */
|
|
49058
|
-
/* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto px-3 sm:px-4 md:px-6 py-4 sm:py-6 pb-24 sm:pb-32", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4 sm:space-y-6", children: [
|
|
49059
|
-
displayMessages.map((message, index) => /* @__PURE__ */ jsxs(
|
|
49060
|
-
"div",
|
|
49061
|
-
{
|
|
49062
|
-
className: `flex gap-2 sm:gap-3 md:gap-4 ${message.role === "user" ? "justify-end" : "justify-start"}`,
|
|
49063
|
-
children: [
|
|
49064
|
-
message.role === "assistant" && /* @__PURE__ */ jsx(ProfilePicture, {}),
|
|
49065
|
-
/* @__PURE__ */ jsx("div", { className: `max-w-none w-full group ${message.role === "user" ? "order-1" : ""}`, children: /* @__PURE__ */ jsx(
|
|
49066
|
-
"div",
|
|
49067
|
-
{
|
|
49068
|
-
className: `relative px-3 sm:px-4 md:px-5 py-3 sm:py-4 rounded-xl sm:rounded-2xl shadow-sm ${message.role === "user" ? "bg-blue-600 text-white max-w-[90%] sm:max-w-[85%] ml-auto" : "bg-white border border-gray-200/80 max-w-full"}`,
|
|
49069
|
-
children: /* @__PURE__ */ jsxs("div", { className: `${message.role === "user" ? "text-white" : "text-gray-800"}`, children: [
|
|
49070
|
-
message.role === "assistant" ? message.id === -1 ? /* @__PURE__ */ jsx(
|
|
49071
|
-
"div",
|
|
49072
|
-
{
|
|
49073
|
-
className: "formatted-content",
|
|
49074
|
-
dangerouslySetInnerHTML: { __html: formatMessage(message.content) }
|
|
49075
|
-
}
|
|
49076
|
-
) : renderAssistantContent(message.content) : /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap leading-relaxed", children: message.content }),
|
|
49077
|
-
message.id === -1 && /* @__PURE__ */ jsx("span", { className: "inline-block w-0.5 h-4 bg-gray-400 animate-pulse ml-0.5" })
|
|
49078
|
-
] })
|
|
49079
|
-
}
|
|
49080
|
-
) })
|
|
49081
|
-
]
|
|
49082
|
-
},
|
|
49083
|
-
message.id === -1 ? "streaming-message" : `${message.id}-${index}`
|
|
49084
|
-
)),
|
|
49085
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-4 justify-start", children: [
|
|
49086
|
-
/* @__PURE__ */ jsx(ProfilePicture, {}),
|
|
49087
|
-
/* @__PURE__ */ jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx("span", { className: "text-sm font-medium thinking-wave", children: "Thinking" }) }) })
|
|
49088
|
-
] })
|
|
49089
|
-
] }) })
|
|
49090
|
-
) : (
|
|
49091
|
-
/* Regular chat view with messages */
|
|
49092
|
-
/* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto px-3 sm:px-4 md:px-6 py-3 sm:py-6 pb-20 sm:pb-32", children: /* @__PURE__ */ jsxs("div", { className: "space-y-3 sm:space-y-6", children: [
|
|
49093
|
-
displayMessages.map((message, index) => /* @__PURE__ */ jsxs(
|
|
49094
|
-
"div",
|
|
49095
|
-
{
|
|
49096
|
-
className: `flex gap-2 sm:gap-3 md:gap-4 ${message.role === "user" ? "justify-end" : "justify-start"}`,
|
|
49097
|
-
children: [
|
|
49098
|
-
message.role === "assistant" && /* @__PURE__ */ jsx(ProfilePicture, {}),
|
|
49099
|
-
/* @__PURE__ */ jsxs("div", { className: `max-w-none w-full group ${message.role === "user" ? "order-1" : ""}`, children: [
|
|
49100
|
-
/* @__PURE__ */ jsxs(
|
|
49101
|
-
"div",
|
|
49102
|
-
{
|
|
49103
|
-
className: `relative px-3 sm:px-4 md:px-5 py-2.5 sm:py-4 rounded-2xl sm:rounded-2xl shadow-sm ${message.role === "user" ? "bg-blue-500 sm:bg-blue-600 text-white max-w-[85%] sm:max-w-[85%] ml-auto" : "bg-gray-100 sm:bg-white sm:border sm:border-gray-200/80 max-w-full"}`,
|
|
49104
|
-
children: [
|
|
49105
|
-
/* @__PURE__ */ jsxs("div", { className: `${message.role === "user" ? "text-white" : "text-gray-800"}`, children: [
|
|
49106
|
-
message.role === "assistant" ? message.id === -1 ? /* @__PURE__ */ jsx(
|
|
49107
|
-
"div",
|
|
49108
|
-
{
|
|
49109
|
-
className: "formatted-content",
|
|
49110
|
-
dangerouslySetInnerHTML: { __html: formatMessage(message.content) }
|
|
49111
|
-
}
|
|
49112
|
-
) : renderAssistantContent(message.content) : /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap leading-relaxed", children: message.content }),
|
|
49113
|
-
message.id === -1 && /* @__PURE__ */ jsx("span", { className: "inline-block w-0.5 h-4 bg-gray-400 animate-pulse ml-0.5" })
|
|
49114
|
-
] }),
|
|
49115
|
-
message.role === "assistant" && message.id !== -1 && /* @__PURE__ */ jsx(
|
|
49116
|
-
"button",
|
|
49117
|
-
{
|
|
49118
|
-
onClick: () => copyToClipboard(message.content, message.id.toString()),
|
|
49119
|
-
className: "absolute top-2 sm:top-3 right-2 sm:right-3 opacity-100 sm:opacity-0 group-hover:opacity-100 transition-opacity duration-200 p-1 sm:p-1.5 hover:bg-gray-100 rounded-lg",
|
|
49120
|
-
title: "Copy message",
|
|
49121
|
-
children: copiedMessageId === message.id.toString() ? /* @__PURE__ */ jsx(Check, { className: "w-3.5 h-3.5 sm:w-4 sm:h-4 text-green-600" }) : /* @__PURE__ */ jsx(Copy, { className: "w-3.5 h-3.5 sm:w-4 sm:h-4 text-gray-500" })
|
|
49122
|
-
}
|
|
49123
|
-
),
|
|
49124
|
-
message.reasoning && /* @__PURE__ */ jsxs("details", { className: "mt-3 pt-3 border-t border-gray-200", children: [
|
|
49125
|
-
/* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-sm text-gray-600 hover:text-gray-800", children: "View reasoning" }),
|
|
49126
|
-
/* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-gray-600", children: message.reasoning })
|
|
49127
|
-
] })
|
|
49128
|
-
]
|
|
49129
|
-
}
|
|
49130
|
-
),
|
|
49131
|
-
/* @__PURE__ */ jsxs("div", { className: `mt-1.5 sm:mt-2 flex items-center gap-2 text-xs text-gray-400 ${message.role === "user" ? "justify-end" : "justify-start"}`, children: [
|
|
49132
|
-
/* @__PURE__ */ jsx("span", { children: formatTime5(message.created_at) }),
|
|
49133
|
-
message.role === "assistant" && message.id !== -1 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
49134
|
-
/* @__PURE__ */ jsx("div", { className: "w-1 h-1 bg-gray-300 rounded-full" }),
|
|
49135
|
-
/* @__PURE__ */ jsx("span", { children: "Axel" })
|
|
49136
|
-
] })
|
|
49137
|
-
] })
|
|
49138
|
-
] })
|
|
49139
|
-
]
|
|
49140
|
-
},
|
|
49141
|
-
message.id === -1 ? "streaming-message" : `${message.id}-${index}`
|
|
49142
|
-
)),
|
|
49143
|
-
lastError && /* @__PURE__ */ jsxs("div", { className: "flex gap-4 justify-start", children: [
|
|
49144
|
-
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx("div", { className: "w-12 h-12 rounded-xl bg-red-100 flex items-center justify-center", children: /* @__PURE__ */ jsx(AlertCircle, { className: "w-6 h-6 text-red-600" }) }) }),
|
|
49145
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-red-50 border border-red-200 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: [
|
|
49146
|
-
/* @__PURE__ */ jsx("p", { className: "text-red-800 text-sm", children: lastError }),
|
|
49147
|
-
/* @__PURE__ */ jsx(
|
|
49148
|
-
"button",
|
|
49149
|
-
{
|
|
49150
|
-
onClick: () => setLastError(null),
|
|
49151
|
-
className: "mt-2 text-xs text-red-600 hover:text-red-800 underline",
|
|
49152
|
-
children: "Dismiss"
|
|
49153
|
-
}
|
|
49154
|
-
)
|
|
49155
|
-
] })
|
|
49156
|
-
] }),
|
|
49157
|
-
isCurrentThreadLoading && !currentStreaming.message && /* @__PURE__ */ jsxs("div", { className: "flex gap-4 justify-start", children: [
|
|
49158
|
-
/* @__PURE__ */ jsx(ProfilePicture, {}),
|
|
49159
|
-
/* @__PURE__ */ jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx("span", { className: "text-sm font-medium thinking-wave", children: "Thinking" }) }) })
|
|
49160
|
-
] }),
|
|
49161
|
-
/* @__PURE__ */ jsx("div", { ref: messagesEndRef })
|
|
49162
|
-
] }) })
|
|
49163
|
-
)
|
|
49164
|
-
}
|
|
49165
|
-
),
|
|
49166
|
-
(displayMessages.length > 0 || isTransitioning) && /* @__PURE__ */ jsx("footer", { className: `fixed bottom-0 left-0 right-0 bg-gradient-to-t from-white via-white/95 to-transparent sm:from-gray-50/50 sm:to-transparent pointer-events-none ${isSidebarOpen ? "lg:right-80" : "right-0"}`, children: /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto p-2 sm:p-4 md:p-6 pointer-events-auto", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
|
|
49167
|
-
/* @__PURE__ */ jsx(
|
|
49168
|
-
"div",
|
|
49169
|
-
{
|
|
49170
|
-
className: `relative bg-white rounded-xl sm:rounded-3xl shadow-md sm:shadow-lg border border-gray-200 focus-within:border-blue-400 sm:focus-within:border-gray-300 transition-all duration-200 ${isTransitioning ? "animate-slide-down" : ""}`,
|
|
49171
|
-
style: isTransitioning ? {
|
|
49172
|
-
animation: "slideDown 0.8s cubic-bezier(0.4, 0, 0.2, 1) forwards"
|
|
49173
|
-
} : {},
|
|
49174
|
-
children: /* @__PURE__ */ jsx("div", { className: "flex items-end gap-1 sm:gap-2 p-2 sm:p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex-1 relative", children: [
|
|
49175
|
-
/* @__PURE__ */ jsx(
|
|
49176
|
-
"textarea",
|
|
49177
|
-
{
|
|
49178
|
-
ref: textareaRef,
|
|
49179
|
-
value: inputValue,
|
|
49180
|
-
onChange: (e) => {
|
|
49181
|
-
const newValue = e.target.value;
|
|
49182
|
-
setInputValue(newValue);
|
|
49183
|
-
if (newValue.length > 0 && !hasStartedTyping) {
|
|
49184
|
-
trackTypingStart();
|
|
49185
|
-
}
|
|
49186
|
-
if (newValue.length > 0) {
|
|
49187
|
-
trackTypingProgress(newValue);
|
|
49188
|
-
}
|
|
49189
|
-
if (newValue.length === 0) {
|
|
49190
|
-
resetTypingState();
|
|
49191
|
-
}
|
|
49192
|
-
},
|
|
49193
|
-
onKeyDown: handleKeyDown,
|
|
49194
|
-
onFocus: () => {
|
|
49195
|
-
trackCoreEvent("AI Agent Input Focused", {
|
|
49196
|
-
line_id: lineId,
|
|
49197
|
-
company_id: companyId,
|
|
49198
|
-
shift_id: shiftId,
|
|
49199
|
-
active_thread_id: activeThreadId,
|
|
49200
|
-
has_existing_messages: messages.length > 0,
|
|
49201
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
49202
|
-
});
|
|
49203
|
-
},
|
|
49204
|
-
placeholder: "Message Axel...",
|
|
49205
|
-
className: "w-full resize-none bg-transparent px-2 sm:px-4 py-2 sm:py-2 pr-10 sm:pr-14 focus:outline-none placeholder-gray-400 sm:placeholder-gray-500 text-gray-900 text-sm sm:text-base leading-relaxed",
|
|
49206
|
-
rows: 1,
|
|
49207
|
-
style: { minHeight: "36px", maxHeight: "120px" }
|
|
49208
|
-
}
|
|
49209
|
-
),
|
|
49210
|
-
/* @__PURE__ */ jsx("div", { className: "absolute right-1 sm:right-3 bottom-1 sm:bottom-2 flex items-center gap-2", children: /* @__PURE__ */ jsx(
|
|
49211
|
-
"button",
|
|
49212
|
-
{
|
|
49213
|
-
type: "submit",
|
|
49214
|
-
disabled: !inputValue.trim() || isCurrentThreadLoading,
|
|
49215
|
-
className: "inline-flex items-center justify-center w-7 h-7 sm:w-9 sm:h-9 bg-blue-500 sm:bg-gray-900 text-white rounded-full active:scale-95 sm:hover:bg-gray-800 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-blue-400/20 sm:focus:ring-gray-500/20",
|
|
49216
|
-
children: /* @__PURE__ */ jsx(Send, { className: "w-3.5 h-3.5 sm:w-4 sm:h-4" })
|
|
49217
|
-
}
|
|
49218
|
-
) })
|
|
49219
|
-
] }) })
|
|
49220
|
-
}
|
|
49221
|
-
),
|
|
49222
|
-
/* @__PURE__ */ jsxs("div", { className: "hidden sm:flex flex-col sm:flex-row items-center justify-center gap-2 sm:gap-4 mt-2 text-xs text-gray-400", children: [
|
|
49223
|
-
/* @__PURE__ */ jsx("span", { className: "text-center", children: isCurrentThreadLoading ? "You can type your next message while Axel responds" : "Press Enter to send \u2022 Shift+Enter for new line" }),
|
|
49224
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
49225
|
-
/* @__PURE__ */ jsx("div", { className: `w-1.5 h-1.5 rounded-full ${isCurrentThreadLoading ? "bg-orange-500" : "bg-green-500"}` }),
|
|
49226
|
-
/* @__PURE__ */ jsx("span", { children: isCurrentThreadLoading ? "Responding..." : "Connected" })
|
|
49227
|
-
] })
|
|
49228
|
-
] })
|
|
49229
|
-
] }) }) })
|
|
49230
|
-
] }),
|
|
49231
|
-
/* @__PURE__ */ jsx("div", { className: `fixed inset-0 sm:inset-auto sm:right-0 sm:top-0 z-20 h-screen transition-transform duration-300 ease-in-out ${isSidebarOpen ? "translate-x-0" : "translate-x-full"}`, children: /* @__PURE__ */ jsx("div", { className: "w-full sm:w-96 lg:w-80 h-full bg-white sm:border-l sm:border-gray-200 shadow-lg", children: /* @__PURE__ */ jsx(
|
|
49232
|
-
ThreadSidebar,
|
|
49233
|
-
{
|
|
49234
|
-
activeThreadId,
|
|
49235
|
-
onSelectThread: setActiveThreadId,
|
|
49236
|
-
onNewThread: handleNewThread,
|
|
49237
|
-
className: "h-full"
|
|
49238
|
-
}
|
|
49239
|
-
) }) }),
|
|
49240
|
-
isSidebarOpen && /* @__PURE__ */ jsx(
|
|
49241
|
-
"div",
|
|
49242
|
-
{
|
|
49243
|
-
className: "fixed inset-0 bg-black bg-opacity-30 z-10 lg:hidden",
|
|
49244
|
-
onClick: () => setIsSidebarOpen(false)
|
|
49245
|
-
}
|
|
49246
|
-
)
|
|
49247
|
-
] });
|
|
49248
|
-
};
|
|
49249
|
-
var AIAgentView_default = AIAgentView;
|
|
49250
47150
|
function AuthCallbackView({
|
|
49251
47151
|
redirectTo = "/",
|
|
49252
47152
|
errorRedirect = "/login"
|
|
@@ -53303,6 +51203,14 @@ var ShiftsView = ({
|
|
|
53303
51203
|
className = ""
|
|
53304
51204
|
}) => {
|
|
53305
51205
|
const supabase = useSupabase();
|
|
51206
|
+
const { lines: dbLines } = useLines();
|
|
51207
|
+
const mergedLineNames = useMemo(() => {
|
|
51208
|
+
const merged = { ...lineNames };
|
|
51209
|
+
dbLines.forEach((line) => {
|
|
51210
|
+
merged[line.id] = line.line_name;
|
|
51211
|
+
});
|
|
51212
|
+
return merged;
|
|
51213
|
+
}, [lineNames, dbLines]);
|
|
53306
51214
|
useEffect(() => {
|
|
53307
51215
|
console.log("[ShiftsView] Component mounted/re-rendered", {
|
|
53308
51216
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -53378,7 +51286,7 @@ var ShiftsView = ({
|
|
|
53378
51286
|
return enabledConfigs.map((config) => {
|
|
53379
51287
|
const rows = shiftsByLine[config.id] || [];
|
|
53380
51288
|
const builtConfig = buildShiftConfigFromOperatingHoursRows(rows);
|
|
53381
|
-
const lineName = lineNameMap[config.id] ||
|
|
51289
|
+
const lineName = lineNameMap[config.id] || mergedLineNames[config.id] || `Line ${config.id.substring(0, 4)}`;
|
|
53382
51290
|
const sortedShifts = [...builtConfig.shifts || []].sort((a, b) => a.shiftId - b.shiftId);
|
|
53383
51291
|
return {
|
|
53384
51292
|
...config,
|
|
@@ -54937,6 +52845,14 @@ var TargetsView = ({
|
|
|
54937
52845
|
const supabase = useSupabase();
|
|
54938
52846
|
const effectiveUserId = userId || "6bf6f271-1e55-4a95-9b89-1c3820b58739";
|
|
54939
52847
|
const dashboardConfig = useDashboardConfig();
|
|
52848
|
+
const { lines: dbLines } = useLines();
|
|
52849
|
+
const mergedLineNames = useMemo(() => {
|
|
52850
|
+
const merged = { ...lineNames };
|
|
52851
|
+
dbLines.forEach((line) => {
|
|
52852
|
+
merged[line.id] = line.line_name;
|
|
52853
|
+
});
|
|
52854
|
+
return merged;
|
|
52855
|
+
}, [lineNames, dbLines]);
|
|
54940
52856
|
const { legend, updateLegend } = useEfficiencyLegend(companyId);
|
|
54941
52857
|
const { skus, isLoading: skusLoading } = useSKUs(companyId);
|
|
54942
52858
|
const skuEnabled = dashboardConfig?.skuConfig?.enabled || false;
|
|
@@ -55330,7 +53246,7 @@ var TargetsView = ({
|
|
|
55330
53246
|
const { error: lineUpsertError } = await supabase.from("line_thresholds").upsert(lineThresholdData, { onConflict: "factory_id,line_id,date,shift_id" });
|
|
55331
53247
|
if (lineUpsertError) {
|
|
55332
53248
|
console.error(`[handleSaveLine] Error upserting line_thresholds for ${lineId}:`, lineUpsertError);
|
|
55333
|
-
toast.error(`Failed to save line thresholds for ${
|
|
53249
|
+
toast.error(`Failed to save line thresholds for ${mergedLineNames[lineId] || lineId}`);
|
|
55334
53250
|
throw lineUpsertError;
|
|
55335
53251
|
}
|
|
55336
53252
|
console.log(`[handleSaveLine] Successfully upserted line_thresholds for ${lineId}`);
|
|
@@ -55360,19 +53276,19 @@ var TargetsView = ({
|
|
|
55360
53276
|
});
|
|
55361
53277
|
console.log(`[handleSaveLine] Cleared user edited fields for line ${lineId}`);
|
|
55362
53278
|
setSaveSuccess((prev) => ({ ...prev, [lineId]: true }));
|
|
55363
|
-
toast.success(`${
|
|
53279
|
+
toast.success(`${mergedLineNames[lineId] || lineId} targets saved successfully`);
|
|
55364
53280
|
if (onSaveChanges) onSaveChanges(lineId);
|
|
55365
53281
|
setTimeout(() => setSaveSuccess((prev) => ({ ...prev, [lineId]: false })), 3e3);
|
|
55366
53282
|
console.log(`[handleSaveLine] Save process completed successfully for ${lineId}`);
|
|
55367
53283
|
} catch (error) {
|
|
55368
53284
|
console.error(`[handleSaveLine] Error saving targets for ${lineId}:`, error);
|
|
55369
53285
|
const errorMessage = typeof error === "object" && error !== null && "message" in error ? error.message : "Unknown error";
|
|
55370
|
-
toast.error(`Failed to save ${
|
|
53286
|
+
toast.error(`Failed to save ${mergedLineNames[lineId] || lineId} targets: ${errorMessage}`);
|
|
55371
53287
|
} finally {
|
|
55372
53288
|
setSavingLines((prev) => ({ ...prev, [lineId]: false }));
|
|
55373
53289
|
console.log(`[handleSaveLine] Set savingLines to false for ${lineId} in finally block`);
|
|
55374
53290
|
}
|
|
55375
|
-
}, [canSaveTargets, supabase, lineWorkspaces, selectedShift,
|
|
53291
|
+
}, [canSaveTargets, supabase, lineWorkspaces, selectedShift, mergedLineNames, onSaveChanges, skuEnabled, dashboardConfig]);
|
|
55376
53292
|
const handleSaveLegend = useCallback(async (nextLegend) => {
|
|
55377
53293
|
if (!canSaveTargets) {
|
|
55378
53294
|
toast.error("You do not have permission to update the legend.");
|
|
@@ -55421,7 +53337,7 @@ var TargetsView = ({
|
|
|
55421
53337
|
{
|
|
55422
53338
|
isLoading: isLoading || skusLoading,
|
|
55423
53339
|
lineWorkspaces,
|
|
55424
|
-
lineNames,
|
|
53340
|
+
lineNames: mergedLineNames,
|
|
55425
53341
|
dropdownStates,
|
|
55426
53342
|
savingLines,
|
|
55427
53343
|
saveSuccess,
|
|
@@ -59524,16 +57440,59 @@ var ImprovementCenterView = () => {
|
|
|
59524
57440
|
const diffDays = Math.max(0, Math.floor((now2.getTime() - firstSeen.getTime()) / (1e3 * 60 * 60 * 24)));
|
|
59525
57441
|
return Math.max(1, Math.ceil(diffDays / 7));
|
|
59526
57442
|
};
|
|
57443
|
+
const toZonedDate = (value) => {
|
|
57444
|
+
if (!value) return void 0;
|
|
57445
|
+
const raw = new Date(value);
|
|
57446
|
+
if (Number.isNaN(raw.getTime())) return void 0;
|
|
57447
|
+
return new Date(raw.toLocaleString("en-US", { timeZone: timezone }));
|
|
57448
|
+
};
|
|
57449
|
+
const getDaySuffix = (day) => {
|
|
57450
|
+
const dayMod = day % 100;
|
|
57451
|
+
if (dayMod >= 11 && dayMod <= 13) return "th";
|
|
57452
|
+
if (day % 10 === 1) return "st";
|
|
57453
|
+
if (day % 10 === 2) return "nd";
|
|
57454
|
+
if (day % 10 === 3) return "rd";
|
|
57455
|
+
return "th";
|
|
57456
|
+
};
|
|
59527
57457
|
const formatOpenedDate = (firstSeenAt) => {
|
|
59528
57458
|
if (!firstSeenAt) return void 0;
|
|
59529
|
-
const
|
|
59530
|
-
if (
|
|
59531
|
-
const zoned = new Date(raw.toLocaleString("en-US", { timeZone: timezone }));
|
|
57459
|
+
const zoned = toZonedDate(firstSeenAt);
|
|
57460
|
+
if (!zoned) return void 0;
|
|
59532
57461
|
const day = zoned.getDate();
|
|
59533
57462
|
const month = zoned.toLocaleString("en-US", { month: "short" });
|
|
59534
|
-
|
|
59535
|
-
|
|
59536
|
-
|
|
57463
|
+
return `${day}${getDaySuffix(day)} ${month}`;
|
|
57464
|
+
};
|
|
57465
|
+
const formatMonthDay = (date) => {
|
|
57466
|
+
const month = date.toLocaleString("en-US", { month: "short" });
|
|
57467
|
+
return `${month} ${date.getDate()}`;
|
|
57468
|
+
};
|
|
57469
|
+
const formatDayMonth = (date, withSuffix = true) => {
|
|
57470
|
+
const day = date.getDate();
|
|
57471
|
+
const month = date.toLocaleString("en-US", { month: "short" });
|
|
57472
|
+
return withSuffix ? `${day}${getDaySuffix(day)} ${month}` : `${day} ${month}`;
|
|
57473
|
+
};
|
|
57474
|
+
const formatPeriodRange = (start, end) => {
|
|
57475
|
+
const startDate = toZonedDate(start);
|
|
57476
|
+
const endDate = toZonedDate(end);
|
|
57477
|
+
if (!startDate || !endDate) return void 0;
|
|
57478
|
+
return `${formatMonthDay(startDate)} - ${formatMonthDay(endDate)}`;
|
|
57479
|
+
};
|
|
57480
|
+
const stripPeriodFromDescription = (description, start, end) => {
|
|
57481
|
+
if (!description) return description;
|
|
57482
|
+
const startDate = toZonedDate(start);
|
|
57483
|
+
const endDate = toZonedDate(end);
|
|
57484
|
+
if (!startDate || !endDate) return description;
|
|
57485
|
+
const labels = [
|
|
57486
|
+
`${formatMonthDay(startDate)} - ${formatMonthDay(endDate)}`,
|
|
57487
|
+
`${formatDayMonth(startDate)} - ${formatDayMonth(endDate)}`,
|
|
57488
|
+
`${formatDayMonth(startDate, false)} - ${formatDayMonth(endDate, false)}`
|
|
57489
|
+
];
|
|
57490
|
+
let cleaned = description;
|
|
57491
|
+
labels.forEach((label) => {
|
|
57492
|
+
cleaned = cleaned.replace(`(${label})`, "").replace(` (${label})`, "");
|
|
57493
|
+
});
|
|
57494
|
+
cleaned = cleaned.replace(/\s{2,}/g, " ").replace(/\s+([.,])/g, "$1").trim();
|
|
57495
|
+
return cleaned;
|
|
59537
57496
|
};
|
|
59538
57497
|
const configuredLines = useMemo(() => {
|
|
59539
57498
|
return entityConfig.lines || entityConfig.lineNames || {};
|
|
@@ -59743,7 +57702,7 @@ var ImprovementCenterView = () => {
|
|
|
59743
57702
|
}
|
|
59744
57703
|
if (selectedMemberId !== "all" && !(rec.assigned_user_ids?.includes(selectedMemberId) || rec.assigned_to_user_id === selectedMemberId)) return false;
|
|
59745
57704
|
return true;
|
|
59746
|
-
}).sort((a, b) => (
|
|
57705
|
+
}).sort((a, b) => (a.issue_number || 0) - (b.issue_number || 0));
|
|
59747
57706
|
}, [recommendations, selectedLineId, selectedStatus, selectedShift, selectedWeeksRange, selectedMemberId]);
|
|
59748
57707
|
const stats = useMemo(() => {
|
|
59749
57708
|
const baseFiltered = recommendations.filter((rec) => {
|
|
@@ -59965,7 +57924,9 @@ var ImprovementCenterView = () => {
|
|
|
59965
57924
|
filteredRecommendations.length > 0 ? filteredRecommendations.map((rec, index) => {
|
|
59966
57925
|
const weeksOpen = rec.weeks_open || 1;
|
|
59967
57926
|
const openLabel = weeksOpen <= 1 ? "Opened this week" : `Opened for ${weeksOpen} weeks`;
|
|
59968
|
-
|
|
57927
|
+
formatOpenedDate(rec.first_seen_at);
|
|
57928
|
+
const periodLabel = formatPeriodRange(rec.period_start, rec.period_end);
|
|
57929
|
+
const description = stripPeriodFromDescription(rec.description, rec.period_start, rec.period_end);
|
|
59969
57930
|
return /* @__PURE__ */ jsx(
|
|
59970
57931
|
motion.div,
|
|
59971
57932
|
{
|
|
@@ -59988,10 +57949,6 @@ var ImprovementCenterView = () => {
|
|
|
59988
57949
|
/* @__PURE__ */ jsx(ClockIcon, { className: "w-3.5 h-3.5" }),
|
|
59989
57950
|
openLabel
|
|
59990
57951
|
] }),
|
|
59991
|
-
openedOnLabel && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium text-gray-600 bg-gray-100 border border-gray-200", children: [
|
|
59992
|
-
"Opened on ",
|
|
59993
|
-
openedOnLabel
|
|
59994
|
-
] }),
|
|
59995
57952
|
rec.assigned_user_ids && rec.assigned_user_ids.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
59996
57953
|
/* @__PURE__ */ jsx("div", { className: "h-3 w-px bg-gray-200" }),
|
|
59997
57954
|
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: rec.assigned_user_ids.map((uid) => {
|
|
@@ -60018,14 +57975,22 @@ var ImprovementCenterView = () => {
|
|
|
60018
57975
|
(rec.shift_label || rec.shift_id !== void 0) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
60019
57976
|
/* @__PURE__ */ jsx("span", { children: "\u2022" }),
|
|
60020
57977
|
/* @__PURE__ */ jsx("span", { className: "uppercase tracking-wide text-xs pt-0.5 text-gray-500 font-medium", children: rec.shift_label || `Shift ${rec.shift_id}` })
|
|
57978
|
+
] }),
|
|
57979
|
+
periodLabel && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
57980
|
+
/* @__PURE__ */ jsx("span", { children: "\u2022" }),
|
|
57981
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-500 font-medium", children: periodLabel })
|
|
60021
57982
|
] })
|
|
60022
57983
|
] })
|
|
60023
57984
|
] })
|
|
60024
57985
|
] }) }),
|
|
60025
|
-
/* @__PURE__ */ jsx("div", { className: "prose prose-sm text-gray-600", children: /* @__PURE__ */ jsx("p", { children:
|
|
57986
|
+
/* @__PURE__ */ jsx("div", { className: "prose prose-sm text-gray-600", children: /* @__PURE__ */ jsx("p", { children: description }) }),
|
|
60026
57987
|
rec.resolution_instructions && /* @__PURE__ */ jsx("div", { className: "bg-blue-50 border border-blue-100 rounded-lg p-3", children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-blue-800 font-medium flex items-start gap-2", children: [
|
|
60027
57988
|
/* @__PURE__ */ jsx(CheckCircleIcon, { className: "w-5 h-5 flex-shrink-0" }),
|
|
60028
|
-
|
|
57989
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
57990
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold", children: "Resolution Condition:" }),
|
|
57991
|
+
" ",
|
|
57992
|
+
rec.resolution_instructions
|
|
57993
|
+
] })
|
|
60029
57994
|
] }) })
|
|
60030
57995
|
] }),
|
|
60031
57996
|
/* @__PURE__ */ jsx("div", { className: "w-full md:w-1/2 lg:w-5/12 bg-gray-50 rounded-lg p-4 border border-gray-100", children: Array.isArray(rec.evidence) && rec.evidence.length > 0 ? /* @__PURE__ */ jsx(
|
|
@@ -60516,5 +58481,84 @@ var streamProxyConfig = {
|
|
|
60516
58481
|
responseLimit: false
|
|
60517
58482
|
}
|
|
60518
58483
|
};
|
|
58484
|
+
var ThreadSidebar = ({
|
|
58485
|
+
activeThreadId,
|
|
58486
|
+
onSelectThread,
|
|
58487
|
+
onNewThread,
|
|
58488
|
+
className = ""
|
|
58489
|
+
}) => {
|
|
58490
|
+
const { threads, isLoading, error, deleteThread: deleteThread2 } = useThreads();
|
|
58491
|
+
const [deletingId, setDeletingId] = useState(null);
|
|
58492
|
+
const handleDelete = async (e, threadId) => {
|
|
58493
|
+
e.stopPropagation();
|
|
58494
|
+
if (confirm("Are you sure you want to delete this conversation?")) {
|
|
58495
|
+
setDeletingId(threadId);
|
|
58496
|
+
try {
|
|
58497
|
+
await deleteThread2(threadId);
|
|
58498
|
+
if (activeThreadId === threadId) {
|
|
58499
|
+
onNewThread();
|
|
58500
|
+
}
|
|
58501
|
+
} catch (error2) {
|
|
58502
|
+
console.error("Error deleting thread:", error2);
|
|
58503
|
+
alert("Failed to delete conversation. Please try again.");
|
|
58504
|
+
} finally {
|
|
58505
|
+
setDeletingId(null);
|
|
58506
|
+
}
|
|
58507
|
+
}
|
|
58508
|
+
};
|
|
58509
|
+
const formatDate2 = (dateString) => {
|
|
58510
|
+
const date = new Date(dateString);
|
|
58511
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
58512
|
+
const diffMs = now2.getTime() - date.getTime();
|
|
58513
|
+
const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
|
|
58514
|
+
if (diffDays === 0) {
|
|
58515
|
+
return "Today";
|
|
58516
|
+
} else if (diffDays === 1) {
|
|
58517
|
+
return "Yesterday";
|
|
58518
|
+
} else if (diffDays < 7) {
|
|
58519
|
+
return date.toLocaleDateString("en-US", { weekday: "short" });
|
|
58520
|
+
} else {
|
|
58521
|
+
return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
58522
|
+
}
|
|
58523
|
+
};
|
|
58524
|
+
if (error) {
|
|
58525
|
+
return /* @__PURE__ */ jsx("div", { className: `p-4 text-red-600 text-sm ${className}`, children: "Failed to load conversations" });
|
|
58526
|
+
}
|
|
58527
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex flex-col h-screen bg-gray-50 border-r border-gray-200 ${className}`, children: [
|
|
58528
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 p-4 border-b border-gray-200", children: [
|
|
58529
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Chat History" }),
|
|
58530
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-1", children: "Your previous conversations" })
|
|
58531
|
+
] }),
|
|
58532
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto min-h-0", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center p-8", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "sm" }) }) : threads.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center text-gray-500 text-sm", children: "No conversations yet" }) : /* @__PURE__ */ jsx("div", { className: "py-2", children: threads.map((thread) => /* @__PURE__ */ jsxs(
|
|
58533
|
+
"div",
|
|
58534
|
+
{
|
|
58535
|
+
onClick: () => onSelectThread(thread.id),
|
|
58536
|
+
className: `group relative flex items-start gap-3 px-4 py-3 cursor-pointer transition-all ${activeThreadId === thread.id ? "bg-blue-50 border-l-4 border-blue-600 hover:bg-blue-100" : "hover:bg-gray-100 border-l-4 border-transparent"}`,
|
|
58537
|
+
children: [
|
|
58538
|
+
/* @__PURE__ */ jsx(MessageSquare, { className: `w-4 h-4 mt-0.5 flex-shrink-0 ${activeThreadId === thread.id ? "text-blue-600" : "text-gray-400"}` }),
|
|
58539
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
58540
|
+
/* @__PURE__ */ jsx("h3", { className: `text-sm font-medium truncate ${activeThreadId === thread.id ? "text-blue-900" : "text-gray-900"}`, children: thread.title || "Untitled Chat" }),
|
|
58541
|
+
/* @__PURE__ */ jsx("p", { className: `text-xs mt-0.5 ${activeThreadId === thread.id ? "text-blue-700" : "text-gray-500"}`, children: formatDate2(thread.created_at) })
|
|
58542
|
+
] }),
|
|
58543
|
+
deletingId === thread.id ? /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsx(
|
|
58544
|
+
"button",
|
|
58545
|
+
{
|
|
58546
|
+
onClick: (e) => handleDelete(e, thread.id),
|
|
58547
|
+
className: "flex-shrink-0 opacity-0 group-hover:opacity-100 p-1 hover:bg-gray-200 rounded transition-all",
|
|
58548
|
+
title: "Delete conversation",
|
|
58549
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "w-3.5 h-3.5 text-gray-500" })
|
|
58550
|
+
}
|
|
58551
|
+
)
|
|
58552
|
+
]
|
|
58553
|
+
},
|
|
58554
|
+
thread.id
|
|
58555
|
+
)) }) }),
|
|
58556
|
+
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0 p-4 border-t border-gray-200", children: /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 text-center", children: [
|
|
58557
|
+
threads.length,
|
|
58558
|
+
" conversation",
|
|
58559
|
+
threads.length !== 1 ? "s" : ""
|
|
58560
|
+
] }) })
|
|
58561
|
+
] });
|
|
58562
|
+
};
|
|
60519
58563
|
|
|
60520
|
-
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, 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, 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, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, 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, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, 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, 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, TeamUsagePdfGenerator, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, buildDateKey, buildKPIsFromLineMetricsRow, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAvailableShiftIds, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getReasonColor, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isFullMonthRange, isLegacyConfiguration, isPrefetchError, isSafari, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeDateKeyRange, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, 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, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMultiLineShiftConfigs, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|
|
58564
|
+
export { ACTION_NAMES, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, 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, 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, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, 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, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, 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, 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, TeamUsagePdfGenerator, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, buildDateKey, buildKPIsFromLineMetricsRow, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAvailableShiftIds, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getReasonColor, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isFullMonthRange, isLegacyConfiguration, isPrefetchError, isSafari, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeDateKeyRange, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, 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, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMultiLineShiftConfigs, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
|