@copilotz/chat-ui 0.8.5 → 0.8.6
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.cjs +589 -236
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +614 -259
- package/dist/index.js.map +1 -1
- package/dist/styles.css +25 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
useCallback as useCallback4,
|
|
4
4
|
useEffect as useEffect10,
|
|
5
|
-
useMemo as
|
|
5
|
+
useMemo as useMemo6,
|
|
6
6
|
useRef as useRef6,
|
|
7
7
|
useState as useState9
|
|
8
8
|
} from "react";
|
|
@@ -79,6 +79,15 @@ var defaultChatConfig = {
|
|
|
79
79
|
renameThread: "Rename",
|
|
80
80
|
archiveThread: "Archive",
|
|
81
81
|
unarchiveThread: "Unarchive",
|
|
82
|
+
manageTags: "Manage tags",
|
|
83
|
+
tags: "Tags",
|
|
84
|
+
addTag: "Add tag",
|
|
85
|
+
removeTag: "Remove tag",
|
|
86
|
+
tagNamePlaceholder: "Tag name",
|
|
87
|
+
untagged: "Untagged",
|
|
88
|
+
groupBy: "Group by",
|
|
89
|
+
groupByDate: "Date",
|
|
90
|
+
groupByTag: "Tag",
|
|
82
91
|
today: "Today",
|
|
83
92
|
yesterday: "Yesterday",
|
|
84
93
|
createNewThread: "Create New Conversation",
|
|
@@ -112,6 +121,13 @@ var defaultChatConfig = {
|
|
|
112
121
|
enableRegeneration: true,
|
|
113
122
|
showActivity: true,
|
|
114
123
|
showActivityDetails: true,
|
|
124
|
+
threadTags: {
|
|
125
|
+
enabled: false,
|
|
126
|
+
groupingEnabled: true,
|
|
127
|
+
defaultGroupBy: "date",
|
|
128
|
+
allowCreate: true,
|
|
129
|
+
allowDrag: true
|
|
130
|
+
},
|
|
115
131
|
maxAttachments: 4,
|
|
116
132
|
maxFileSize: 10 * 1024 * 1024
|
|
117
133
|
// 10MB
|
|
@@ -144,7 +160,8 @@ var defaultChatConfig = {
|
|
|
144
160
|
createProvider: void 0
|
|
145
161
|
},
|
|
146
162
|
customComponent: {},
|
|
147
|
-
headerActions: null
|
|
163
|
+
headerActions: null,
|
|
164
|
+
headerMenuItems: []
|
|
148
165
|
};
|
|
149
166
|
function mergeConfig(_baseConfig, userConfig) {
|
|
150
167
|
if (!userConfig) return defaultChatConfig;
|
|
@@ -178,7 +195,8 @@ function mergeConfig(_baseConfig, userConfig) {
|
|
|
178
195
|
...userConfig.agentSelector
|
|
179
196
|
},
|
|
180
197
|
customComponent: userConfig.customComponent || defaultChatConfig.customComponent,
|
|
181
|
-
headerActions: userConfig.headerActions || defaultChatConfig.headerActions
|
|
198
|
+
headerActions: userConfig.headerActions || defaultChatConfig.headerActions,
|
|
199
|
+
headerMenuItems: userConfig.headerMenuItems || defaultChatConfig.headerMenuItems
|
|
182
200
|
};
|
|
183
201
|
}
|
|
184
202
|
|
|
@@ -1328,7 +1346,7 @@ var Message = memo2(({
|
|
|
1328
1346
|
}, arePropsEqual);
|
|
1329
1347
|
|
|
1330
1348
|
// src/components/chat/Sidebar.tsx
|
|
1331
|
-
import { useEffect as useEffect7, useRef as useRef4, useState as useState5 } from "react";
|
|
1349
|
+
import { useEffect as useEffect7, useMemo as useMemo3, useRef as useRef4, useState as useState5 } from "react";
|
|
1332
1350
|
|
|
1333
1351
|
// src/components/ui/input.tsx
|
|
1334
1352
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
@@ -2214,10 +2232,12 @@ import {
|
|
|
2214
2232
|
Bot,
|
|
2215
2233
|
Edit2,
|
|
2216
2234
|
Filter,
|
|
2235
|
+
Tag,
|
|
2217
2236
|
MoreHorizontal,
|
|
2218
2237
|
Plus,
|
|
2219
2238
|
Search,
|
|
2220
|
-
Trash2
|
|
2239
|
+
Trash2,
|
|
2240
|
+
X as X2
|
|
2221
2241
|
} from "lucide-react";
|
|
2222
2242
|
|
|
2223
2243
|
// src/components/chat/UserMenu.tsx
|
|
@@ -2434,6 +2454,37 @@ var ThreadInitialsIcon = ({ title }) => {
|
|
|
2434
2454
|
const initials = title?.split(" ").map((n) => n[0]).slice(0, 2).join("").toUpperCase() || "?";
|
|
2435
2455
|
return /* @__PURE__ */ jsx18("div", { className: "flex shrink-0 items-center justify-center rounded bg-muted text-[10px] font-medium", children: initials });
|
|
2436
2456
|
};
|
|
2457
|
+
function slugTagName(name) {
|
|
2458
|
+
const slug = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
2459
|
+
return slug || "tag";
|
|
2460
|
+
}
|
|
2461
|
+
function createThreadTag(name) {
|
|
2462
|
+
return {
|
|
2463
|
+
id: `tag_${slugTagName(name)}`,
|
|
2464
|
+
name: name.trim()
|
|
2465
|
+
};
|
|
2466
|
+
}
|
|
2467
|
+
function mergeThreadTags(tags, tag) {
|
|
2468
|
+
const nameKey = tag.name.trim().toLowerCase();
|
|
2469
|
+
if (!nameKey) return tags;
|
|
2470
|
+
if (tags.some(
|
|
2471
|
+
(existing) => existing.id === tag.id || existing.name.trim().toLowerCase() === nameKey
|
|
2472
|
+
)) {
|
|
2473
|
+
return tags;
|
|
2474
|
+
}
|
|
2475
|
+
return [...tags, tag];
|
|
2476
|
+
}
|
|
2477
|
+
function collectThreadTags(threads) {
|
|
2478
|
+
const tags = [];
|
|
2479
|
+
for (const thread of threads) {
|
|
2480
|
+
for (const tag of thread.tags ?? []) {
|
|
2481
|
+
if (!tags.some((existing) => existing.id === tag.id)) {
|
|
2482
|
+
tags.push(tag);
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
return tags.sort((a, b) => a.name.localeCompare(b.name));
|
|
2487
|
+
}
|
|
2437
2488
|
var Sidebar2 = ({
|
|
2438
2489
|
threads,
|
|
2439
2490
|
currentThreadId,
|
|
@@ -2443,6 +2494,7 @@ var Sidebar2 = ({
|
|
|
2443
2494
|
onRenameThread,
|
|
2444
2495
|
onDeleteThread,
|
|
2445
2496
|
onArchiveThread,
|
|
2497
|
+
onUpdateThreadTags,
|
|
2446
2498
|
// User menu props
|
|
2447
2499
|
user,
|
|
2448
2500
|
userMenuCallbacks,
|
|
@@ -2457,7 +2509,20 @@ var Sidebar2 = ({
|
|
|
2457
2509
|
const [deleteThreadId, setDeleteThreadId] = useState5(null);
|
|
2458
2510
|
const [editingThreadId, setEditingThreadId] = useState5(null);
|
|
2459
2511
|
const [editTitle, setEditTitle] = useState5("");
|
|
2512
|
+
const [tagDialogThreadId, setTagDialogThreadId] = useState5(
|
|
2513
|
+
null
|
|
2514
|
+
);
|
|
2515
|
+
const [newTagName, setNewTagName] = useState5("");
|
|
2516
|
+
const [draggingThreadId, setDraggingThreadId] = useState5(null);
|
|
2517
|
+
const [dragOverTagId, setDragOverTagId] = useState5(null);
|
|
2460
2518
|
const inputRef = useRef4(null);
|
|
2519
|
+
const threadTagsConfig = config.features?.threadTags;
|
|
2520
|
+
const tagsEnabled = !!threadTagsConfig?.enabled;
|
|
2521
|
+
const canUpdateTags = tagsEnabled && !!onUpdateThreadTags;
|
|
2522
|
+
const canDragTags = canUpdateTags && threadTagsConfig?.allowDrag !== false;
|
|
2523
|
+
const [groupBy, setGroupBy] = useState5(
|
|
2524
|
+
threadTagsConfig?.defaultGroupBy === "tag" ? "tag" : "date"
|
|
2525
|
+
);
|
|
2461
2526
|
const { setOpen } = useSidebar();
|
|
2462
2527
|
useEffect7(() => {
|
|
2463
2528
|
if (editingThreadId && inputRef.current) {
|
|
@@ -2467,38 +2532,98 @@ var Sidebar2 = ({
|
|
|
2467
2532
|
}, [editingThreadId]);
|
|
2468
2533
|
const filteredThreads = threads.filter((thread) => {
|
|
2469
2534
|
const title = (thread.title ?? "").toString();
|
|
2470
|
-
const matchesSearch = title.toLowerCase().includes(
|
|
2471
|
-
searchQuery.toLowerCase()
|
|
2472
|
-
);
|
|
2535
|
+
const matchesSearch = title.toLowerCase().includes(searchQuery.toLowerCase());
|
|
2473
2536
|
const matchesArchiveFilter = showArchived || !thread.isArchived;
|
|
2474
2537
|
return matchesSearch && matchesArchiveFilter;
|
|
2475
2538
|
});
|
|
2476
|
-
const
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2539
|
+
const allTags = useMemo3(() => collectThreadTags(threads), [threads]);
|
|
2540
|
+
const threadGroups = useMemo3(() => {
|
|
2541
|
+
if (tagsEnabled && groupBy === "tag") {
|
|
2542
|
+
const groups2 = allTags.map((tag) => ({
|
|
2543
|
+
key: tag.id,
|
|
2544
|
+
label: tag.name,
|
|
2545
|
+
tag,
|
|
2546
|
+
threads: filteredThreads.filter(
|
|
2547
|
+
(thread) => (thread.tags ?? []).some((threadTag) => threadTag.id === tag.id)
|
|
2548
|
+
)
|
|
2549
|
+
})).filter((group) => group.threads.length > 0);
|
|
2550
|
+
const untagged = filteredThreads.filter(
|
|
2551
|
+
(thread) => (thread.tags ?? []).length === 0
|
|
2552
|
+
);
|
|
2553
|
+
if (untagged.length > 0) {
|
|
2554
|
+
groups2.push({
|
|
2555
|
+
key: "untagged",
|
|
2556
|
+
label: config.labels?.untagged || "Untagged",
|
|
2557
|
+
threads: untagged
|
|
2558
|
+
});
|
|
2559
|
+
}
|
|
2560
|
+
return groups2;
|
|
2561
|
+
}
|
|
2562
|
+
const groups = [];
|
|
2563
|
+
const groupMap = /* @__PURE__ */ new Map();
|
|
2564
|
+
for (const thread of filteredThreads) {
|
|
2565
|
+
const date = new Date(thread.updatedAt);
|
|
2566
|
+
const today = /* @__PURE__ */ new Date();
|
|
2567
|
+
const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1e3);
|
|
2568
|
+
let groupKey;
|
|
2569
|
+
if (date.toDateString() === today.toDateString()) {
|
|
2570
|
+
groupKey = config.labels?.today || "Today";
|
|
2571
|
+
} else if (date.toDateString() === yesterday.toDateString()) {
|
|
2572
|
+
groupKey = config.labels?.yesterday || "Yesterday";
|
|
2573
|
+
} else {
|
|
2574
|
+
groupKey = date.toLocaleDateString("en-US", {
|
|
2575
|
+
weekday: "long",
|
|
2576
|
+
day: "2-digit",
|
|
2577
|
+
month: "long"
|
|
2578
|
+
});
|
|
2579
|
+
}
|
|
2580
|
+
const existing = groupMap.get(groupKey);
|
|
2581
|
+
if (existing) {
|
|
2582
|
+
existing.threads.push(thread);
|
|
2583
|
+
} else {
|
|
2584
|
+
const group = { key: groupKey, label: groupKey, threads: [thread] };
|
|
2585
|
+
groupMap.set(groupKey, group);
|
|
2586
|
+
groups.push(group);
|
|
2587
|
+
}
|
|
2494
2588
|
}
|
|
2495
|
-
groups[groupKey].push(thread);
|
|
2496
2589
|
return groups;
|
|
2497
|
-
},
|
|
2590
|
+
}, [
|
|
2591
|
+
allTags,
|
|
2592
|
+
config.labels?.today,
|
|
2593
|
+
config.labels?.untagged,
|
|
2594
|
+
config.labels?.yesterday,
|
|
2595
|
+
filteredThreads,
|
|
2596
|
+
groupBy,
|
|
2597
|
+
tagsEnabled
|
|
2598
|
+
]);
|
|
2599
|
+
const tagDialogThread = tagDialogThreadId ? threads.find((thread) => thread.id === tagDialogThreadId) ?? null : null;
|
|
2498
2600
|
const handleDeleteThread = (threadId) => {
|
|
2499
2601
|
onDeleteThread?.(threadId);
|
|
2500
2602
|
setDeleteThreadId(null);
|
|
2501
2603
|
};
|
|
2604
|
+
const updateThreadTags = (thread, tags) => {
|
|
2605
|
+
onUpdateThreadTags?.(thread.id, tags);
|
|
2606
|
+
};
|
|
2607
|
+
const addTagToThread = (thread, tag) => {
|
|
2608
|
+
updateThreadTags(thread, mergeThreadTags(thread.tags ?? [], tag));
|
|
2609
|
+
};
|
|
2610
|
+
const removeTagFromThread = (thread, tagId) => {
|
|
2611
|
+
updateThreadTags(
|
|
2612
|
+
thread,
|
|
2613
|
+
(thread.tags ?? []).filter((tag) => tag.id !== tagId)
|
|
2614
|
+
);
|
|
2615
|
+
};
|
|
2616
|
+
const handleCreateTag = () => {
|
|
2617
|
+
if (!tagDialogThread || !newTagName.trim()) return;
|
|
2618
|
+
addTagToThread(tagDialogThread, createThreadTag(newTagName));
|
|
2619
|
+
setNewTagName("");
|
|
2620
|
+
};
|
|
2621
|
+
const handleDropOnTag = (tag) => {
|
|
2622
|
+
const thread = draggingThreadId ? threads.find((candidate) => candidate.id === draggingThreadId) : null;
|
|
2623
|
+
if (thread) addTagToThread(thread, tag);
|
|
2624
|
+
setDraggingThreadId(null);
|
|
2625
|
+
setDragOverTagId(null);
|
|
2626
|
+
};
|
|
2502
2627
|
const startEditing = (thread) => {
|
|
2503
2628
|
setEditingThreadId(thread.id);
|
|
2504
2629
|
setEditTitle(thread.title || "");
|
|
@@ -2586,92 +2711,175 @@ var Sidebar2 = ({
|
|
|
2586
2711
|
]
|
|
2587
2712
|
}
|
|
2588
2713
|
) }),
|
|
2589
|
-
|
|
2590
|
-
/* @__PURE__ */ jsx18("
|
|
2591
|
-
/* @__PURE__ */
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
/* @__PURE__ */ jsx18(SidebarGroupContent, { children: /* @__PURE__ */ jsx18(SidebarMenu, { children: groupThreads.map((thread) => /* @__PURE__ */ jsxs11(SidebarMenuItem, { children: [
|
|
2595
|
-
editingThreadId === thread.id ? /* @__PURE__ */ jsx18("div", { className: "flex items-center gap-1 px-2 py-1", children: /* @__PURE__ */ jsx18(
|
|
2596
|
-
Input,
|
|
2714
|
+
tagsEnabled && threadTagsConfig?.groupingEnabled !== false && /* @__PURE__ */ jsx18("div", { className: "px-4 py-2 group-data-[collapsible=icon]:hidden", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between rounded-md border border-sidebar-border bg-sidebar-accent/40 p-1", children: [
|
|
2715
|
+
/* @__PURE__ */ jsx18("span", { className: "px-2 text-[11px] text-muted-foreground", children: config.labels?.groupBy || "Group by" }),
|
|
2716
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex gap-1", children: [
|
|
2717
|
+
/* @__PURE__ */ jsx18(
|
|
2718
|
+
Button,
|
|
2597
2719
|
{
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
saveEdit();
|
|
2604
|
-
}
|
|
2605
|
-
if (e.key === "Escape") {
|
|
2606
|
-
cancelEdit();
|
|
2607
|
-
}
|
|
2608
|
-
},
|
|
2609
|
-
onBlur: saveEdit,
|
|
2610
|
-
className: "h-7 text-sm"
|
|
2720
|
+
variant: groupBy === "date" ? "secondary" : "ghost",
|
|
2721
|
+
size: "sm",
|
|
2722
|
+
onClick: () => setGroupBy("date"),
|
|
2723
|
+
className: "h-6 px-2 text-xs",
|
|
2724
|
+
children: config.labels?.groupByDate || "Date"
|
|
2611
2725
|
}
|
|
2612
|
-
)
|
|
2613
|
-
|
|
2726
|
+
),
|
|
2727
|
+
/* @__PURE__ */ jsx18(
|
|
2728
|
+
Button,
|
|
2614
2729
|
{
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
/* @__PURE__ */ jsx18("div", { className: "flex flex-col items-start gap-0.5 flex-1 min-w-0 group-data-[collapsible=icon]:hidden", children: /* @__PURE__ */ jsx18("span", { className: "truncate w-full", children: thread.title || "New Chat" }) }),
|
|
2621
|
-
thread.isArchived && /* @__PURE__ */ jsx18(Archive, { className: "ml-auto h-3 w-3 opacity-50 group-data-[collapsible=icon]:hidden" })
|
|
2622
|
-
]
|
|
2730
|
+
variant: groupBy === "tag" ? "secondary" : "ghost",
|
|
2731
|
+
size: "sm",
|
|
2732
|
+
onClick: () => setGroupBy("tag"),
|
|
2733
|
+
className: "h-6 px-2 text-xs",
|
|
2734
|
+
children: config.labels?.groupByTag || "Tag"
|
|
2623
2735
|
}
|
|
2624
|
-
)
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2736
|
+
)
|
|
2737
|
+
] })
|
|
2738
|
+
] }) }),
|
|
2739
|
+
threadGroups.length === 0 ? /* @__PURE__ */ jsxs11("div", { className: "px-4 py-8 text-center text-muted-foreground group-data-[collapsible=icon]:hidden", children: [
|
|
2740
|
+
/* @__PURE__ */ jsx18("div", { className: "mx-auto h-8 w-8 mb-2 flex items-center justify-center rounded-full bg-muted/50", children: /* @__PURE__ */ jsx18(Plus, { className: "h-4 w-4 opacity-50" }) }),
|
|
2741
|
+
/* @__PURE__ */ jsx18("p", { className: "text-xs", children: searchQuery ? config.labels?.noThreadsFound || "No conversations found" : config.labels?.noThreadsYet || "No conversations yet" })
|
|
2742
|
+
] }) : threadGroups.map((group) => /* @__PURE__ */ jsxs11(
|
|
2743
|
+
SidebarGroup,
|
|
2744
|
+
{
|
|
2745
|
+
className: "mt-2",
|
|
2746
|
+
onDragOver: (event) => {
|
|
2747
|
+
if (!canDragTags || !group.tag) return;
|
|
2748
|
+
event.preventDefault();
|
|
2749
|
+
setDragOverTagId(group.tag.id);
|
|
2750
|
+
},
|
|
2751
|
+
onDragLeave: () => {
|
|
2752
|
+
if (dragOverTagId === group.tag?.id) setDragOverTagId(null);
|
|
2753
|
+
},
|
|
2754
|
+
onDrop: (event) => {
|
|
2755
|
+
if (!canDragTags || !group.tag) return;
|
|
2756
|
+
event.preventDefault();
|
|
2757
|
+
handleDropOnTag(group.tag);
|
|
2758
|
+
},
|
|
2759
|
+
children: [
|
|
2630
2760
|
/* @__PURE__ */ jsxs11(
|
|
2631
|
-
|
|
2761
|
+
SidebarGroupLabel,
|
|
2632
2762
|
{
|
|
2633
|
-
className: "
|
|
2634
|
-
side: "right",
|
|
2635
|
-
align: "start",
|
|
2763
|
+
className: `group-data-[collapsible=icon]:hidden ${dragOverTagId === group.tag?.id ? "rounded-md bg-sidebar-accent text-sidebar-accent-foreground" : ""}`,
|
|
2636
2764
|
children: [
|
|
2637
|
-
/* @__PURE__ */
|
|
2638
|
-
|
|
2639
|
-
{
|
|
2640
|
-
onClick: () => startEditing(thread),
|
|
2641
|
-
children: [
|
|
2642
|
-
/* @__PURE__ */ jsx18(Edit2, { className: "mr-2 h-4 w-4" }),
|
|
2643
|
-
/* @__PURE__ */ jsx18("span", { children: config.labels?.renameThread || "Rename" })
|
|
2644
|
-
]
|
|
2645
|
-
}
|
|
2646
|
-
),
|
|
2647
|
-
/* @__PURE__ */ jsxs11(
|
|
2648
|
-
DropdownMenuItem,
|
|
2649
|
-
{
|
|
2650
|
-
onClick: () => onArchiveThread?.(thread.id),
|
|
2651
|
-
children: [
|
|
2652
|
-
/* @__PURE__ */ jsx18(Archive, { className: "mr-2 h-4 w-4" }),
|
|
2653
|
-
/* @__PURE__ */ jsx18("span", { children: thread.isArchived ? config.labels?.unarchiveThread || "Unarchive" : config.labels?.archiveThread || "Archive" })
|
|
2654
|
-
]
|
|
2655
|
-
}
|
|
2656
|
-
),
|
|
2657
|
-
/* @__PURE__ */ jsx18(DropdownMenuSeparator, {}),
|
|
2658
|
-
/* @__PURE__ */ jsxs11(
|
|
2659
|
-
DropdownMenuItem,
|
|
2660
|
-
{
|
|
2661
|
-
onClick: () => setDeleteThreadId(thread.id),
|
|
2662
|
-
className: "text-destructive focus:text-destructive",
|
|
2663
|
-
children: [
|
|
2664
|
-
/* @__PURE__ */ jsx18(Trash2, { className: "mr-2 h-4 w-4" }),
|
|
2665
|
-
/* @__PURE__ */ jsx18("span", { children: config.labels?.deleteThread || "Delete" })
|
|
2666
|
-
]
|
|
2667
|
-
}
|
|
2668
|
-
)
|
|
2765
|
+
group.tag && /* @__PURE__ */ jsx18(Tag, { className: "mr-1 h-3 w-3" }),
|
|
2766
|
+
group.label
|
|
2669
2767
|
]
|
|
2670
2768
|
}
|
|
2671
|
-
)
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2769
|
+
),
|
|
2770
|
+
/* @__PURE__ */ jsx18(SidebarGroupContent, { children: /* @__PURE__ */ jsx18(SidebarMenu, { children: group.threads.map((thread) => /* @__PURE__ */ jsxs11(SidebarMenuItem, { children: [
|
|
2771
|
+
editingThreadId === thread.id ? /* @__PURE__ */ jsx18("div", { className: "flex items-center gap-1 px-2 py-1", children: /* @__PURE__ */ jsx18(
|
|
2772
|
+
Input,
|
|
2773
|
+
{
|
|
2774
|
+
ref: inputRef,
|
|
2775
|
+
value: editTitle,
|
|
2776
|
+
onChange: (e) => setEditTitle(e.target.value),
|
|
2777
|
+
onKeyDown: (e) => {
|
|
2778
|
+
if (e.key === "Enter") {
|
|
2779
|
+
saveEdit();
|
|
2780
|
+
}
|
|
2781
|
+
if (e.key === "Escape") {
|
|
2782
|
+
cancelEdit();
|
|
2783
|
+
}
|
|
2784
|
+
},
|
|
2785
|
+
onBlur: saveEdit,
|
|
2786
|
+
className: "h-7 text-sm"
|
|
2787
|
+
}
|
|
2788
|
+
) }) : /* @__PURE__ */ jsxs11(
|
|
2789
|
+
SidebarMenuButton,
|
|
2790
|
+
{
|
|
2791
|
+
isActive: currentThreadId === thread.id,
|
|
2792
|
+
onClick: () => onSelectThread?.(thread.id),
|
|
2793
|
+
tooltip: thread.title,
|
|
2794
|
+
draggable: canDragTags,
|
|
2795
|
+
onDragStart: () => setDraggingThreadId(thread.id),
|
|
2796
|
+
onDragEnd: () => {
|
|
2797
|
+
setDraggingThreadId(null);
|
|
2798
|
+
setDragOverTagId(null);
|
|
2799
|
+
},
|
|
2800
|
+
children: [
|
|
2801
|
+
/* @__PURE__ */ jsx18(ThreadInitialsIcon, { title: thread.title || "?" }),
|
|
2802
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col items-start gap-0.5 flex-1 min-w-0 group-data-[collapsible=icon]:hidden", children: [
|
|
2803
|
+
/* @__PURE__ */ jsx18("span", { className: "truncate w-full", children: thread.title || "New Chat" }),
|
|
2804
|
+
tagsEnabled && (thread.tags ?? []).length > 0 && /* @__PURE__ */ jsx18("span", { className: "flex max-w-full flex-wrap gap-1", children: (thread.tags ?? []).slice(0, 2).map((tag) => /* @__PURE__ */ jsx18(
|
|
2805
|
+
"span",
|
|
2806
|
+
{
|
|
2807
|
+
className: "max-w-20 truncate rounded bg-sidebar-accent px-1.5 py-0.5 text-[10px] text-muted-foreground",
|
|
2808
|
+
children: tag.name
|
|
2809
|
+
},
|
|
2810
|
+
tag.id
|
|
2811
|
+
)) })
|
|
2812
|
+
] }),
|
|
2813
|
+
thread.isArchived && /* @__PURE__ */ jsx18(Archive, { className: "ml-auto h-3 w-3 opacity-50 group-data-[collapsible=icon]:hidden" })
|
|
2814
|
+
]
|
|
2815
|
+
}
|
|
2816
|
+
),
|
|
2817
|
+
!editingThreadId && /* @__PURE__ */ jsxs11(DropdownMenu, { children: [
|
|
2818
|
+
/* @__PURE__ */ jsx18(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(SidebarMenuAction, { showOnHover: true, children: [
|
|
2819
|
+
/* @__PURE__ */ jsx18(MoreHorizontal, {}),
|
|
2820
|
+
/* @__PURE__ */ jsx18("span", { className: "sr-only", children: "More" })
|
|
2821
|
+
] }) }),
|
|
2822
|
+
/* @__PURE__ */ jsxs11(
|
|
2823
|
+
DropdownMenuContent,
|
|
2824
|
+
{
|
|
2825
|
+
className: "w-48",
|
|
2826
|
+
side: "right",
|
|
2827
|
+
align: "start",
|
|
2828
|
+
children: [
|
|
2829
|
+
/* @__PURE__ */ jsxs11(
|
|
2830
|
+
DropdownMenuItem,
|
|
2831
|
+
{
|
|
2832
|
+
onClick: () => startEditing(thread),
|
|
2833
|
+
children: [
|
|
2834
|
+
/* @__PURE__ */ jsx18(Edit2, { className: "mr-2 h-4 w-4" }),
|
|
2835
|
+
/* @__PURE__ */ jsx18("span", { children: config.labels?.renameThread || "Rename" })
|
|
2836
|
+
]
|
|
2837
|
+
}
|
|
2838
|
+
),
|
|
2839
|
+
/* @__PURE__ */ jsxs11(
|
|
2840
|
+
DropdownMenuItem,
|
|
2841
|
+
{
|
|
2842
|
+
onClick: () => onArchiveThread?.(thread.id),
|
|
2843
|
+
children: [
|
|
2844
|
+
/* @__PURE__ */ jsx18(Archive, { className: "mr-2 h-4 w-4" }),
|
|
2845
|
+
/* @__PURE__ */ jsx18("span", { children: thread.isArchived ? config.labels?.unarchiveThread || "Unarchive" : config.labels?.archiveThread || "Archive" })
|
|
2846
|
+
]
|
|
2847
|
+
}
|
|
2848
|
+
),
|
|
2849
|
+
canUpdateTags && /* @__PURE__ */ jsxs11(
|
|
2850
|
+
DropdownMenuItem,
|
|
2851
|
+
{
|
|
2852
|
+
onClick: () => {
|
|
2853
|
+
setTagDialogThreadId(thread.id);
|
|
2854
|
+
setNewTagName("");
|
|
2855
|
+
},
|
|
2856
|
+
children: [
|
|
2857
|
+
/* @__PURE__ */ jsx18(Tag, { className: "mr-2 h-4 w-4" }),
|
|
2858
|
+
/* @__PURE__ */ jsx18("span", { children: config.labels?.manageTags || "Manage tags" })
|
|
2859
|
+
]
|
|
2860
|
+
}
|
|
2861
|
+
),
|
|
2862
|
+
/* @__PURE__ */ jsx18(DropdownMenuSeparator, {}),
|
|
2863
|
+
/* @__PURE__ */ jsxs11(
|
|
2864
|
+
DropdownMenuItem,
|
|
2865
|
+
{
|
|
2866
|
+
onClick: () => setDeleteThreadId(thread.id),
|
|
2867
|
+
className: "text-destructive focus:text-destructive",
|
|
2868
|
+
children: [
|
|
2869
|
+
/* @__PURE__ */ jsx18(Trash2, { className: "mr-2 h-4 w-4" }),
|
|
2870
|
+
/* @__PURE__ */ jsx18("span", { children: config.labels?.deleteThread || "Delete" })
|
|
2871
|
+
]
|
|
2872
|
+
}
|
|
2873
|
+
)
|
|
2874
|
+
]
|
|
2875
|
+
}
|
|
2876
|
+
)
|
|
2877
|
+
] })
|
|
2878
|
+
] }, thread.id)) }) })
|
|
2879
|
+
]
|
|
2880
|
+
},
|
|
2881
|
+
group.key
|
|
2882
|
+
))
|
|
2675
2883
|
] }),
|
|
2676
2884
|
/* @__PURE__ */ jsx18(SidebarFooter, { children: /* @__PURE__ */ jsx18(
|
|
2677
2885
|
UserMenu,
|
|
@@ -2686,6 +2894,94 @@ var Sidebar2 = ({
|
|
|
2686
2894
|
}
|
|
2687
2895
|
) }),
|
|
2688
2896
|
/* @__PURE__ */ jsx18(SidebarRail, {}),
|
|
2897
|
+
tagDialogThread && /* @__PURE__ */ jsx18(
|
|
2898
|
+
Dialog,
|
|
2899
|
+
{
|
|
2900
|
+
open: !!tagDialogThread,
|
|
2901
|
+
onOpenChange: (open) => {
|
|
2902
|
+
if (!open) {
|
|
2903
|
+
setTagDialogThreadId(null);
|
|
2904
|
+
setNewTagName("");
|
|
2905
|
+
}
|
|
2906
|
+
},
|
|
2907
|
+
children: /* @__PURE__ */ jsxs11(DialogContent, { children: [
|
|
2908
|
+
/* @__PURE__ */ jsxs11(DialogHeader, { children: [
|
|
2909
|
+
/* @__PURE__ */ jsx18(DialogTitle, { children: config.labels?.manageTags || "Manage tags" }),
|
|
2910
|
+
/* @__PURE__ */ jsx18(DialogDescription, { children: tagDialogThread.title || "New Chat" })
|
|
2911
|
+
] }),
|
|
2912
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-4", children: [
|
|
2913
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
|
|
2914
|
+
/* @__PURE__ */ jsx18("div", { className: "text-sm font-medium", children: config.labels?.tags || "Tags" }),
|
|
2915
|
+
(tagDialogThread.tags ?? []).length === 0 ? /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: config.labels?.untagged || "Untagged" }) : /* @__PURE__ */ jsx18("div", { className: "flex flex-wrap gap-2", children: (tagDialogThread.tags ?? []).map((tag) => /* @__PURE__ */ jsxs11(
|
|
2916
|
+
"span",
|
|
2917
|
+
{
|
|
2918
|
+
className: "inline-flex items-center gap-1 rounded-md bg-muted px-2 py-1 text-sm",
|
|
2919
|
+
children: [
|
|
2920
|
+
tag.name,
|
|
2921
|
+
/* @__PURE__ */ jsx18(
|
|
2922
|
+
"button",
|
|
2923
|
+
{
|
|
2924
|
+
type: "button",
|
|
2925
|
+
className: "rounded hover:bg-background",
|
|
2926
|
+
onClick: () => removeTagFromThread(tagDialogThread, tag.id),
|
|
2927
|
+
"aria-label": config.labels?.removeTag || "Remove tag",
|
|
2928
|
+
children: /* @__PURE__ */ jsx18(X2, { className: "h-3 w-3" })
|
|
2929
|
+
}
|
|
2930
|
+
)
|
|
2931
|
+
]
|
|
2932
|
+
},
|
|
2933
|
+
tag.id
|
|
2934
|
+
)) })
|
|
2935
|
+
] }),
|
|
2936
|
+
allTags.length > 0 && /* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
|
|
2937
|
+
/* @__PURE__ */ jsx18("div", { className: "text-sm font-medium", children: config.labels?.addTag || "Add tag" }),
|
|
2938
|
+
/* @__PURE__ */ jsx18("div", { className: "flex flex-wrap gap-2", children: allTags.map((tag) => {
|
|
2939
|
+
const assigned = (tagDialogThread.tags ?? []).some(
|
|
2940
|
+
(threadTag) => threadTag.id === tag.id
|
|
2941
|
+
);
|
|
2942
|
+
return /* @__PURE__ */ jsx18(
|
|
2943
|
+
Button,
|
|
2944
|
+
{
|
|
2945
|
+
type: "button",
|
|
2946
|
+
variant: assigned ? "secondary" : "outline",
|
|
2947
|
+
size: "sm",
|
|
2948
|
+
disabled: assigned,
|
|
2949
|
+
onClick: () => addTagToThread(tagDialogThread, tag),
|
|
2950
|
+
children: tag.name
|
|
2951
|
+
},
|
|
2952
|
+
tag.id
|
|
2953
|
+
);
|
|
2954
|
+
}) })
|
|
2955
|
+
] }),
|
|
2956
|
+
threadTagsConfig?.allowCreate !== false && /* @__PURE__ */ jsxs11("div", { className: "flex gap-2", children: [
|
|
2957
|
+
/* @__PURE__ */ jsx18(
|
|
2958
|
+
Input,
|
|
2959
|
+
{
|
|
2960
|
+
value: newTagName,
|
|
2961
|
+
onChange: (event) => setNewTagName(event.target.value),
|
|
2962
|
+
placeholder: config.labels?.tagNamePlaceholder || "Tag name",
|
|
2963
|
+
onKeyDown: (event) => {
|
|
2964
|
+
if (event.key === "Enter") {
|
|
2965
|
+
event.preventDefault();
|
|
2966
|
+
handleCreateTag();
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
),
|
|
2971
|
+
/* @__PURE__ */ jsx18(
|
|
2972
|
+
Button,
|
|
2973
|
+
{
|
|
2974
|
+
type: "button",
|
|
2975
|
+
onClick: handleCreateTag,
|
|
2976
|
+
disabled: !newTagName.trim(),
|
|
2977
|
+
children: config.labels?.addTag || "Add tag"
|
|
2978
|
+
}
|
|
2979
|
+
)
|
|
2980
|
+
] })
|
|
2981
|
+
] })
|
|
2982
|
+
] })
|
|
2983
|
+
}
|
|
2984
|
+
),
|
|
2689
2985
|
deleteThreadId && /* @__PURE__ */ jsx18(
|
|
2690
2986
|
AlertDialog,
|
|
2691
2987
|
{
|
|
@@ -2771,8 +3067,8 @@ import {
|
|
|
2771
3067
|
} from "lucide-react";
|
|
2772
3068
|
|
|
2773
3069
|
// src/components/chat/AgentSelectors.tsx
|
|
2774
|
-
import { memo as memo3, useMemo as
|
|
2775
|
-
import { Check as Check3, ChevronDown as ChevronDown2, Users, AtSign, X as
|
|
3070
|
+
import { memo as memo3, useMemo as useMemo4 } from "react";
|
|
3071
|
+
import { Check as Check3, ChevronDown as ChevronDown2, Users, AtSign, X as X3 } from "lucide-react";
|
|
2776
3072
|
import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2777
3073
|
var ParticipantsSelector = memo3(({
|
|
2778
3074
|
agents,
|
|
@@ -2782,8 +3078,8 @@ var ParticipantsSelector = memo3(({
|
|
|
2782
3078
|
maxVisible = 3,
|
|
2783
3079
|
disabled = false
|
|
2784
3080
|
}) => {
|
|
2785
|
-
const agentsWithColors =
|
|
2786
|
-
const selectedAgents =
|
|
3081
|
+
const agentsWithColors = useMemo4(() => assignAgentColors(agents), [agents]);
|
|
3082
|
+
const selectedAgents = useMemo4(
|
|
2787
3083
|
() => agentsWithColors.filter((a) => participantIds.includes(a.id)),
|
|
2788
3084
|
[agentsWithColors, participantIds]
|
|
2789
3085
|
);
|
|
@@ -2880,8 +3176,8 @@ var TargetAgentSelector = memo3(({
|
|
|
2880
3176
|
placeholder = "Select agent",
|
|
2881
3177
|
disabled = false
|
|
2882
3178
|
}) => {
|
|
2883
|
-
const agentsWithColors =
|
|
2884
|
-
const selectedAgent =
|
|
3179
|
+
const agentsWithColors = useMemo4(() => assignAgentColors(agents), [agents]);
|
|
3180
|
+
const selectedAgent = useMemo4(
|
|
2885
3181
|
() => agentsWithColors.find((a) => a.id === targetAgentId),
|
|
2886
3182
|
[agentsWithColors, targetAgentId]
|
|
2887
3183
|
);
|
|
@@ -2988,7 +3284,7 @@ var AgentBadge = memo3(({
|
|
|
2988
3284
|
e.stopPropagation();
|
|
2989
3285
|
onRemove();
|
|
2990
3286
|
},
|
|
2991
|
-
children: /* @__PURE__ */ jsx20(
|
|
3287
|
+
children: /* @__PURE__ */ jsx20(X3, { className: "h-3 w-3" })
|
|
2992
3288
|
}
|
|
2993
3289
|
)
|
|
2994
3290
|
]
|
|
@@ -3158,6 +3454,20 @@ var ChatHeader = ({
|
|
|
3158
3454
|
] }),
|
|
3159
3455
|
/* @__PURE__ */ jsx21(DropdownMenuSeparator, {})
|
|
3160
3456
|
] }),
|
|
3457
|
+
config.headerMenuItems?.map((item) => /* @__PURE__ */ jsxs13(
|
|
3458
|
+
DropdownMenuItem,
|
|
3459
|
+
{
|
|
3460
|
+
onClick: item.onSelect,
|
|
3461
|
+
disabled: item.disabled,
|
|
3462
|
+
variant: item.variant,
|
|
3463
|
+
children: [
|
|
3464
|
+
item.icon ? /* @__PURE__ */ jsx21("span", { className: "h-4 w-4 mr-2 flex items-center justify-center", children: item.icon }) : null,
|
|
3465
|
+
item.label
|
|
3466
|
+
]
|
|
3467
|
+
},
|
|
3468
|
+
item.id
|
|
3469
|
+
)),
|
|
3470
|
+
config.headerMenuItems && config.headerMenuItems.length > 0 && /* @__PURE__ */ jsx21(DropdownMenuSeparator, {}),
|
|
3161
3471
|
onExportData && /* @__PURE__ */ jsxs13(DropdownMenuItem, { onClick: onExportData, children: [
|
|
3162
3472
|
/* @__PURE__ */ jsx21(Download2, { className: "h-4 w-4 mr-2" }),
|
|
3163
3473
|
config.labels?.exportData || "Export Data"
|
|
@@ -3200,7 +3510,7 @@ var ChatHeader = ({
|
|
|
3200
3510
|
import React13, { useState as useState7, useRef as useRef5, useCallback as useCallback3, useEffect as useEffect9, memo as memo4 } from "react";
|
|
3201
3511
|
|
|
3202
3512
|
// src/components/chat/UserContext.tsx
|
|
3203
|
-
import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect8, useMemo as
|
|
3513
|
+
import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo5, useState as useState6 } from "react";
|
|
3204
3514
|
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
3205
3515
|
var Ctx = createContext2(void 0);
|
|
3206
3516
|
var ChatUserContextProvider = ({ children, initial }) => {
|
|
@@ -3223,7 +3533,7 @@ var ChatUserContextProvider = ({ children, initial }) => {
|
|
|
3223
3533
|
return { ...prev, ...partial, updatedAt: Date.now() };
|
|
3224
3534
|
});
|
|
3225
3535
|
}, []);
|
|
3226
|
-
const value =
|
|
3536
|
+
const value = useMemo5(() => ({
|
|
3227
3537
|
context: ctx,
|
|
3228
3538
|
setContext: setPartial,
|
|
3229
3539
|
resetContext: () => setCtx({ updatedAt: Date.now() })
|
|
@@ -3590,7 +3900,7 @@ function Progress({
|
|
|
3590
3900
|
}
|
|
3591
3901
|
|
|
3592
3902
|
// src/components/chat/VoiceComposer.tsx
|
|
3593
|
-
import { Keyboard, Loader2, Mic, Send, Square, Trash2 as Trash23, X as
|
|
3903
|
+
import { Keyboard, Loader2, Mic, Send, Square, Trash2 as Trash23, X as X4 } from "lucide-react";
|
|
3594
3904
|
import { jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3595
3905
|
var formatDuration = (durationMs) => {
|
|
3596
3906
|
const totalSeconds = Math.max(0, Math.floor(durationMs / 1e3));
|
|
@@ -3776,7 +4086,7 @@ var VoiceComposer = ({
|
|
|
3776
4086
|
isAutoSendActive && autoSendDelayMs > 0 && /* @__PURE__ */ jsx24("div", { className: "mt-3 flex justify-center", children: /* @__PURE__ */ jsx24("div", { className: "inline-flex items-center rounded-full border bg-background px-3 py-1 text-xs text-muted-foreground", children: interpolateSeconds(labels?.voiceAutoSendIn, countdownSeconds) }) }),
|
|
3777
4087
|
/* @__PURE__ */ jsxs14("div", { className: "mt-4 grid grid-cols-1 gap-2 sm:flex sm:items-center sm:justify-end", children: [
|
|
3778
4088
|
isAutoSendActive && /* @__PURE__ */ jsxs14(Button, { type: "button", variant: "ghost", size: "sm", onClick: onCancelAutoSend, disabled, className: "w-full sm:w-auto", children: [
|
|
3779
|
-
/* @__PURE__ */ jsx24(
|
|
4089
|
+
/* @__PURE__ */ jsx24(X4, { className: "h-4 w-4" }),
|
|
3780
4090
|
labels?.voiceCancel || "Cancel"
|
|
3781
4091
|
] }),
|
|
3782
4092
|
/* @__PURE__ */ jsxs14(Button, { type: "button", size: "sm", onClick: onSendNow, disabled, className: "w-full sm:w-auto", children: [
|
|
@@ -3797,7 +4107,7 @@ import {
|
|
|
3797
4107
|
Image as Image2,
|
|
3798
4108
|
Video,
|
|
3799
4109
|
FileText as FileText2,
|
|
3800
|
-
X as
|
|
4110
|
+
X as X5,
|
|
3801
4111
|
Square as Square2,
|
|
3802
4112
|
Play,
|
|
3803
4113
|
Pause,
|
|
@@ -3881,7 +4191,7 @@ var FileUploadItem = memo4(function FileUploadItem2({ file, progress, onCancel }
|
|
|
3881
4191
|
size: "icon",
|
|
3882
4192
|
className: "h-6 w-6",
|
|
3883
4193
|
onClick: onCancel,
|
|
3884
|
-
children: /* @__PURE__ */ jsx25(
|
|
4194
|
+
children: /* @__PURE__ */ jsx25(X5, { className: "h-3 w-3" })
|
|
3885
4195
|
}
|
|
3886
4196
|
)
|
|
3887
4197
|
] }) }) });
|
|
@@ -3938,7 +4248,7 @@ var AttachmentPreview = memo4(function AttachmentPreview2({ attachment, onRemove
|
|
|
3938
4248
|
size: "icon",
|
|
3939
4249
|
className: "h-6 w-6",
|
|
3940
4250
|
onClick: onRemove,
|
|
3941
|
-
children: /* @__PURE__ */ jsx25(
|
|
4251
|
+
children: /* @__PURE__ */ jsx25(X5, { className: "h-3 w-3" })
|
|
3942
4252
|
}
|
|
3943
4253
|
) })
|
|
3944
4254
|
] }),
|
|
@@ -3959,7 +4269,7 @@ var AttachmentPreview = memo4(function AttachmentPreview2({ attachment, onRemove
|
|
|
3959
4269
|
size: "icon",
|
|
3960
4270
|
className: "h-6 w-6",
|
|
3961
4271
|
onClick: onRemove,
|
|
3962
|
-
children: /* @__PURE__ */ jsx25(
|
|
4272
|
+
children: /* @__PURE__ */ jsx25(X5, { className: "h-3 w-3" })
|
|
3963
4273
|
}
|
|
3964
4274
|
) }),
|
|
3965
4275
|
/* @__PURE__ */ jsx25(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration2(attachment.durationMs) })
|
|
@@ -3997,7 +4307,7 @@ var AttachmentPreview = memo4(function AttachmentPreview2({ attachment, onRemove
|
|
|
3997
4307
|
size: "icon",
|
|
3998
4308
|
className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
3999
4309
|
onClick: onRemove,
|
|
4000
|
-
children: /* @__PURE__ */ jsx25(
|
|
4310
|
+
children: /* @__PURE__ */ jsx25(X5, { className: "h-3 w-3" })
|
|
4001
4311
|
}
|
|
4002
4312
|
)
|
|
4003
4313
|
] }),
|
|
@@ -4014,7 +4324,7 @@ var AttachmentPreview = memo4(function AttachmentPreview2({ attachment, onRemove
|
|
|
4014
4324
|
size: "icon",
|
|
4015
4325
|
className: "h-6 w-6 opacity-0 transition-opacity group-hover:opacity-100",
|
|
4016
4326
|
onClick: onRemove,
|
|
4017
|
-
children: /* @__PURE__ */ jsx25(
|
|
4327
|
+
children: /* @__PURE__ */ jsx25(X5, { className: "h-3 w-3" })
|
|
4018
4328
|
}
|
|
4019
4329
|
)
|
|
4020
4330
|
] }),
|
|
@@ -4867,7 +5177,7 @@ import {
|
|
|
4867
5177
|
Bot as Bot3,
|
|
4868
5178
|
Pencil,
|
|
4869
5179
|
Check as Check5,
|
|
4870
|
-
X as
|
|
5180
|
+
X as X6
|
|
4871
5181
|
} from "lucide-react";
|
|
4872
5182
|
import { Fragment as Fragment7, jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4873
5183
|
var getInitials2 = (name, email) => {
|
|
@@ -5167,7 +5477,7 @@ var UserProfile = ({
|
|
|
5167
5477
|
className: "h-7 px-2",
|
|
5168
5478
|
onClick: handleCancelEdit,
|
|
5169
5479
|
children: [
|
|
5170
|
-
/* @__PURE__ */ jsx27(
|
|
5480
|
+
/* @__PURE__ */ jsx27(X6, { className: "h-3.5 w-3.5 mr-1" }),
|
|
5171
5481
|
"Cancelar"
|
|
5172
5482
|
]
|
|
5173
5483
|
}
|
|
@@ -5377,7 +5687,7 @@ var ChatUI = ({
|
|
|
5377
5687
|
initialInput,
|
|
5378
5688
|
onInitialInputConsumed
|
|
5379
5689
|
}) => {
|
|
5380
|
-
const config =
|
|
5690
|
+
const config = useMemo6(
|
|
5381
5691
|
() => mergeConfig(defaultChatConfig, userConfig),
|
|
5382
5692
|
[userConfig]
|
|
5383
5693
|
);
|
|
@@ -5440,9 +5750,10 @@ var ChatUI = ({
|
|
|
5440
5750
|
}, [attachments]);
|
|
5441
5751
|
const [isCustomMounted, setIsCustomMounted] = useState9(false);
|
|
5442
5752
|
const [isCustomVisible, setIsCustomVisible] = useState9(false);
|
|
5443
|
-
const groupedMessages =
|
|
5444
|
-
messages
|
|
5445
|
-
|
|
5753
|
+
const groupedMessages = useMemo6(
|
|
5754
|
+
() => groupMessagesForRender(messages),
|
|
5755
|
+
[messages]
|
|
5756
|
+
);
|
|
5446
5757
|
const virtualizer = useVirtualizer({
|
|
5447
5758
|
count: groupedMessages.length,
|
|
5448
5759
|
getScrollElement: () => scrollAreaRef.current,
|
|
@@ -5568,7 +5879,8 @@ var ChatUI = ({
|
|
|
5568
5879
|
});
|
|
5569
5880
|
}, [groupedMessages, isLoadingOlderMessages, virtualizer]);
|
|
5570
5881
|
const requestOlderMessages = useCallback4(() => {
|
|
5571
|
-
if (!onLoadOlderMessages || !hasMoreMessagesBefore || isLoadingOlderMessages)
|
|
5882
|
+
if (!onLoadOlderMessages || !hasMoreMessagesBefore || isLoadingOlderMessages)
|
|
5883
|
+
return;
|
|
5572
5884
|
const viewport = scrollAreaRef.current;
|
|
5573
5885
|
prependSnapshotRef.current = viewport ? {
|
|
5574
5886
|
scrollHeight: viewport.scrollHeight,
|
|
@@ -5600,55 +5912,68 @@ var ChatUI = ({
|
|
|
5600
5912
|
return next;
|
|
5601
5913
|
});
|
|
5602
5914
|
}, [groupedMessages]);
|
|
5603
|
-
const handleScroll = useCallback4(
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5915
|
+
const handleScroll = useCallback4(
|
|
5916
|
+
(e) => {
|
|
5917
|
+
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
|
|
5918
|
+
const isAtBottom = scrollHeight - scrollTop - clientHeight < 50;
|
|
5919
|
+
const isNearTop = scrollTop < 120;
|
|
5920
|
+
if (isNearTop && hasMoreMessagesBefore && !isLoadingOlderMessages) {
|
|
5921
|
+
requestOlderMessages();
|
|
5922
|
+
}
|
|
5923
|
+
setState((prev) => {
|
|
5924
|
+
if (prev.isAtBottom === isAtBottom) return prev;
|
|
5925
|
+
return { ...prev, isAtBottom };
|
|
5926
|
+
});
|
|
5927
|
+
},
|
|
5928
|
+
[hasMoreMessagesBefore, isLoadingOlderMessages, requestOlderMessages]
|
|
5929
|
+
);
|
|
5930
|
+
const handleSendMessage = useCallback4(
|
|
5931
|
+
(content, messageAttachments = []) => {
|
|
5932
|
+
if (!content.trim() && messageAttachments.length === 0) return;
|
|
5933
|
+
callbacks.onSendMessage?.(
|
|
5934
|
+
content,
|
|
5935
|
+
messageAttachments,
|
|
5936
|
+
createStateCallback()
|
|
5937
|
+
);
|
|
5938
|
+
if (initialInputApplied.current && !initialInputConsumedRef.current) {
|
|
5939
|
+
initialInputConsumedRef.current = true;
|
|
5940
|
+
onInitialInputConsumed?.();
|
|
5941
|
+
}
|
|
5942
|
+
setInputValue("");
|
|
5943
|
+
setAttachments([]);
|
|
5944
|
+
},
|
|
5945
|
+
[callbacks, createStateCallback, onInitialInputConsumed]
|
|
5946
|
+
);
|
|
5947
|
+
const handleMessageAction = useCallback4(
|
|
5948
|
+
(event) => {
|
|
5949
|
+
const { action, messageId, content } = event;
|
|
5950
|
+
switch (action) {
|
|
5951
|
+
case "copy":
|
|
5952
|
+
callbacks.onCopyMessage?.(
|
|
5953
|
+
messageId,
|
|
5954
|
+
content || "",
|
|
5955
|
+
createStateCallback()
|
|
5956
|
+
);
|
|
5957
|
+
break;
|
|
5958
|
+
case "edit":
|
|
5959
|
+
if (content) {
|
|
5960
|
+
callbacks.onEditMessage?.(
|
|
5961
|
+
messageId,
|
|
5962
|
+
content,
|
|
5963
|
+
createStateCallback()
|
|
5964
|
+
);
|
|
5965
|
+
}
|
|
5966
|
+
break;
|
|
5967
|
+
case "regenerate":
|
|
5968
|
+
callbacks.onRegenerateMessage?.(messageId, createStateCallback());
|
|
5969
|
+
break;
|
|
5970
|
+
case "delete":
|
|
5971
|
+
callbacks.onDeleteMessage?.(messageId, createStateCallback());
|
|
5972
|
+
break;
|
|
5973
|
+
}
|
|
5974
|
+
},
|
|
5975
|
+
[callbacks, createStateCallback]
|
|
5976
|
+
);
|
|
5652
5977
|
const handleToggleMessageExpansion = useCallback4((messageId) => {
|
|
5653
5978
|
setExpandedMessageIds((prev) => {
|
|
5654
5979
|
if (prev[messageId]) {
|
|
@@ -5662,51 +5987,79 @@ var ChatUI = ({
|
|
|
5662
5987
|
};
|
|
5663
5988
|
});
|
|
5664
5989
|
}, []);
|
|
5665
|
-
const handleCreateThread = useCallback4(
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
callbacks
|
|
5670
|
-
|
|
5990
|
+
const handleCreateThread = useCallback4(
|
|
5991
|
+
(title) => {
|
|
5992
|
+
callbacks.onCreateThread?.(title, createStateCallback());
|
|
5993
|
+
},
|
|
5994
|
+
[callbacks, createStateCallback]
|
|
5995
|
+
);
|
|
5996
|
+
const handleSelectThread = useCallback4(
|
|
5997
|
+
(threadId) => {
|
|
5998
|
+
callbacks.onSelectThread?.(threadId, createStateCallback());
|
|
5999
|
+
},
|
|
6000
|
+
[callbacks, createStateCallback]
|
|
6001
|
+
);
|
|
5671
6002
|
const handleRenameThread = useCallback4(
|
|
5672
6003
|
(threadId, newTitle) => {
|
|
5673
6004
|
callbacks.onRenameThread?.(threadId, newTitle, createStateCallback());
|
|
5674
6005
|
},
|
|
5675
6006
|
[callbacks, createStateCallback]
|
|
5676
6007
|
);
|
|
5677
|
-
const handleDeleteThread = useCallback4(
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
callbacks
|
|
5682
|
-
|
|
6008
|
+
const handleDeleteThread = useCallback4(
|
|
6009
|
+
(threadId) => {
|
|
6010
|
+
callbacks.onDeleteThread?.(threadId, createStateCallback());
|
|
6011
|
+
},
|
|
6012
|
+
[callbacks, createStateCallback]
|
|
6013
|
+
);
|
|
6014
|
+
const handleArchiveThread = useCallback4(
|
|
6015
|
+
(threadId) => {
|
|
6016
|
+
callbacks.onArchiveThread?.(threadId, createStateCallback());
|
|
6017
|
+
},
|
|
6018
|
+
[callbacks, createStateCallback]
|
|
6019
|
+
);
|
|
6020
|
+
const handleUpdateThreadTags = useCallback4(
|
|
6021
|
+
(threadId, tags) => {
|
|
6022
|
+
callbacks.onUpdateThreadTags?.(
|
|
6023
|
+
threadId,
|
|
6024
|
+
tags ?? [],
|
|
6025
|
+
createStateCallback()
|
|
6026
|
+
);
|
|
6027
|
+
},
|
|
6028
|
+
[callbacks, createStateCallback]
|
|
6029
|
+
);
|
|
5683
6030
|
const closeSidebar = useCallback4(() => {
|
|
5684
6031
|
setState((prev) => ({ ...prev, showSidebar: false }));
|
|
5685
6032
|
}, []);
|
|
5686
6033
|
const handleCustomComponentToggle = useCallback4(() => {
|
|
5687
6034
|
setState((prev) => ({ ...prev, showSidebar: !prev.showSidebar }));
|
|
5688
6035
|
}, []);
|
|
5689
|
-
const sidebarUser =
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
6036
|
+
const sidebarUser = useMemo6(
|
|
6037
|
+
() => user ? {
|
|
6038
|
+
id: user.id,
|
|
6039
|
+
name: user.name,
|
|
6040
|
+
email: user.email,
|
|
6041
|
+
avatar: user.avatar
|
|
6042
|
+
} : null,
|
|
6043
|
+
[user?.id, user?.name, user?.email, user?.avatar]
|
|
6044
|
+
);
|
|
5695
6045
|
const handleViewProfile = useCallback4(() => {
|
|
5696
6046
|
setIsUserProfileOpen(true);
|
|
5697
6047
|
callbacks.onViewProfile?.();
|
|
5698
6048
|
}, [callbacks.onViewProfile]);
|
|
5699
|
-
const sidebarUserMenuCallbacks =
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
6049
|
+
const sidebarUserMenuCallbacks = useMemo6(
|
|
6050
|
+
() => ({
|
|
6051
|
+
onViewProfile: handleViewProfile,
|
|
6052
|
+
onOpenSettings: callbacks.onOpenSettings,
|
|
6053
|
+
onThemeChange: callbacks.onThemeChange,
|
|
6054
|
+
onLogout: callbacks.onLogout
|
|
6055
|
+
}),
|
|
6056
|
+
[
|
|
6057
|
+
handleViewProfile,
|
|
6058
|
+
callbacks.onOpenSettings,
|
|
6059
|
+
callbacks.onThemeChange,
|
|
6060
|
+
callbacks.onLogout
|
|
6061
|
+
]
|
|
6062
|
+
);
|
|
5710
6063
|
const renderCustomComponent = useCallback4(() => {
|
|
5711
6064
|
const component = config?.customComponent?.component;
|
|
5712
6065
|
if (!component) return null;
|
|
@@ -5787,55 +6140,58 @@ var ChatUI = ({
|
|
|
5787
6140
|
);
|
|
5788
6141
|
}) });
|
|
5789
6142
|
const isMultiAgentMode = config.agentSelector?.mode === "multi";
|
|
5790
|
-
const messageProps =
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
6143
|
+
const messageProps = useMemo6(
|
|
6144
|
+
() => ({
|
|
6145
|
+
userAvatar: user?.avatar,
|
|
6146
|
+
userName: user?.name,
|
|
6147
|
+
assistantAvatar: assistant?.avatar,
|
|
6148
|
+
assistantName: assistant?.name,
|
|
6149
|
+
showTimestamp: config.ui.showTimestamps,
|
|
6150
|
+
showAvatar: config.ui.showAvatars,
|
|
6151
|
+
enableCopy: config.features.enableMessageCopy,
|
|
6152
|
+
enableEdit: config.features.enableMessageEditing,
|
|
6153
|
+
enableRegenerate: config.features.enableRegeneration,
|
|
6154
|
+
showActivity: config.features.showActivity,
|
|
6155
|
+
showActivityDetails: config.features.showActivityDetails,
|
|
6156
|
+
compactMode: config.ui.compactMode,
|
|
6157
|
+
onAction: handleMessageAction,
|
|
6158
|
+
labels: config.labels,
|
|
6159
|
+
showMoreLabel: config.labels.showMoreMessage,
|
|
6160
|
+
showLessLabel: config.labels.showLessMessage,
|
|
6161
|
+
collapseLongMessages: config.ui.collapseLongMessages,
|
|
6162
|
+
collapseLongMessagesForUserOnly: config.ui.collapseLongMessagesForUserOnly,
|
|
6163
|
+
longMessagePreviewChars: config.ui.longMessagePreviewChars,
|
|
6164
|
+
longMessageChunkChars: config.ui.longMessageChunkChars,
|
|
6165
|
+
renderUserMarkdown: config.ui.renderUserMarkdown,
|
|
6166
|
+
markdown: config.markdown,
|
|
6167
|
+
onToggleExpanded: handleToggleMessageExpansion
|
|
6168
|
+
}),
|
|
6169
|
+
[
|
|
6170
|
+
user?.avatar,
|
|
6171
|
+
user?.name,
|
|
6172
|
+
assistant?.avatar,
|
|
6173
|
+
assistant?.name,
|
|
6174
|
+
config.ui.showTimestamps,
|
|
6175
|
+
config.ui.showAvatars,
|
|
6176
|
+
config.ui.compactMode,
|
|
6177
|
+
config.features.enableMessageCopy,
|
|
6178
|
+
config.features.enableMessageEditing,
|
|
6179
|
+
config.features.enableRegeneration,
|
|
6180
|
+
config.features.showActivity,
|
|
6181
|
+
config.features.showActivityDetails,
|
|
6182
|
+
config.labels,
|
|
6183
|
+
config.labels.showMoreMessage,
|
|
6184
|
+
config.labels.showLessMessage,
|
|
6185
|
+
config.ui.collapseLongMessages,
|
|
6186
|
+
config.ui.collapseLongMessagesForUserOnly,
|
|
6187
|
+
config.ui.longMessagePreviewChars,
|
|
6188
|
+
config.ui.longMessageChunkChars,
|
|
6189
|
+
config.ui.renderUserMarkdown,
|
|
6190
|
+
config.markdown,
|
|
6191
|
+
handleMessageAction,
|
|
6192
|
+
handleToggleMessageExpansion
|
|
6193
|
+
]
|
|
6194
|
+
);
|
|
5839
6195
|
const shouldShowAgentSelector = Boolean(
|
|
5840
6196
|
config.agentSelector?.enabled && agentOptions.length > 0 && (!config.agentSelector?.hideIfSingle || agentOptions.length > 1) && (isMultiAgentMode ? onParticipantsChange : onSelectAgent)
|
|
5841
6197
|
);
|
|
@@ -5855,6 +6211,7 @@ var ChatUI = ({
|
|
|
5855
6211
|
onRenameThread: handleRenameThread,
|
|
5856
6212
|
onDeleteThread: handleDeleteThread,
|
|
5857
6213
|
onArchiveThread: handleArchiveThread,
|
|
6214
|
+
onUpdateThreadTags: handleUpdateThreadTags,
|
|
5858
6215
|
user: sidebarUser,
|
|
5859
6216
|
userMenuCallbacks: sidebarUserMenuCallbacks,
|
|
5860
6217
|
currentTheme: config.ui.theme === "auto" ? "system" : config.ui.theme,
|
|
@@ -5868,9 +6225,7 @@ var ChatUI = ({
|
|
|
5868
6225
|
ChatHeader,
|
|
5869
6226
|
{
|
|
5870
6227
|
config,
|
|
5871
|
-
currentThreadTitle: threads.find(
|
|
5872
|
-
(t) => t.id === state.selectedThreadId
|
|
5873
|
-
)?.title,
|
|
6228
|
+
currentThreadTitle: threads.find((t) => t.id === state.selectedThreadId)?.title,
|
|
5874
6229
|
isMobile,
|
|
5875
6230
|
onCustomComponentToggle: handleCustomComponentToggle,
|
|
5876
6231
|
onNewThread: handleCreateThread,
|