@wealthx/shadcn 1.5.36 → 1.5.38
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/.turbo/turbo-build.log +125 -119
- package/CHANGELOG.md +12 -0
- package/dist/{chunk-734FOOJC.mjs → chunk-B5PSUONN.mjs} +25 -58
- package/dist/chunk-EFHPSKVF.mjs +192 -0
- package/dist/{chunk-NB3ZL36B.mjs → chunk-MZI77ZMX.mjs} +17 -2
- package/dist/chunk-R7M657QL.mjs +587 -0
- package/dist/{chunk-DIH2NZZ3.mjs → chunk-RRROLESJ.mjs} +33 -23
- package/dist/components/ui/ai-assistant-drawer.js +269 -121
- package/dist/components/ui/ai-assistant-drawer.mjs +2 -1
- package/dist/components/ui/ai-conversations/index.js +474 -286
- package/dist/components/ui/ai-conversations/index.mjs +2 -1
- package/dist/components/ui/chat-input-area.js +429 -0
- package/dist/components/ui/chat-input-area.mjs +11 -0
- package/dist/components/ui/page-top-bar.js +182 -5
- package/dist/components/ui/page-top-bar.mjs +3 -1
- package/dist/components/ui/support-agent/index.js +1131 -0
- package/dist/components/ui/support-agent/index.mjs +27 -0
- package/dist/index.js +4760 -4027
- package/dist/index.mjs +54 -36
- package/dist/styles.css +1 -1
- package/package.json +11 -1
- package/src/components/index.tsx +24 -0
- package/src/components/ui/ai-assistant-drawer.tsx +24 -51
- package/src/components/ui/ai-conversations/index.tsx +16 -8
- package/src/components/ui/ai-conversations/thread.tsx +38 -27
- package/src/components/ui/chat-input-area.tsx +244 -0
- package/src/components/ui/page-top-bar.tsx +31 -5
- package/src/components/ui/support-agent/index.tsx +25 -0
- package/src/components/ui/support-agent/support-agent-fab.tsx +116 -0
- package/src/components/ui/support-agent/support-agent-panel.tsx +498 -0
- package/src/components/ui/support-agent/support-agent-primitives.tsx +354 -0
- package/src/styles/globals.css +1 -0
- package/src/styles/styles-css.ts +1 -1
- package/tsup.config.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wealthx/shadcn",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.38",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -559,11 +559,21 @@
|
|
|
559
559
|
"import": "./dist/components/ui/ai-assistant-drawer.mjs",
|
|
560
560
|
"require": "./dist/components/ui/ai-assistant-drawer.js"
|
|
561
561
|
},
|
|
562
|
+
"./support-agent": {
|
|
563
|
+
"types": "./src/components/ui/support-agent/index.tsx",
|
|
564
|
+
"import": "./dist/components/ui/support-agent/index.mjs",
|
|
565
|
+
"require": "./dist/components/ui/support-agent/index.js"
|
|
566
|
+
},
|
|
562
567
|
"./ai-conversations": {
|
|
563
568
|
"types": "./src/components/ui/ai-conversations/index.tsx",
|
|
564
569
|
"import": "./dist/components/ui/ai-conversations/index.mjs",
|
|
565
570
|
"require": "./dist/components/ui/ai-conversations/index.js"
|
|
566
571
|
},
|
|
572
|
+
"./chat-input-area": {
|
|
573
|
+
"types": "./src/components/ui/chat-input-area.tsx",
|
|
574
|
+
"import": "./dist/components/ui/chat-input-area.mjs",
|
|
575
|
+
"require": "./dist/components/ui/chat-input-area.js"
|
|
576
|
+
},
|
|
567
577
|
"./chat-widget-primitives": {
|
|
568
578
|
"types": "./src/components/ui/chat-widget-primitives.tsx",
|
|
569
579
|
"import": "./dist/components/ui/chat-widget-primitives.mjs",
|
package/src/components/index.tsx
CHANGED
|
@@ -115,6 +115,30 @@ export type {
|
|
|
115
115
|
AiTaskSuggestion,
|
|
116
116
|
} from "./ui/ai-assistant-drawer";
|
|
117
117
|
|
|
118
|
+
export {
|
|
119
|
+
SupportContextChip,
|
|
120
|
+
SupportSuggestedQuestion,
|
|
121
|
+
SupportStepGuideCard,
|
|
122
|
+
SupportArticleCard,
|
|
123
|
+
SupportAgentFAB,
|
|
124
|
+
SupportAgentPanel,
|
|
125
|
+
} from "./ui/support-agent";
|
|
126
|
+
export type {
|
|
127
|
+
SupportAgentContext,
|
|
128
|
+
SupportAgentStep,
|
|
129
|
+
SupportAgentRichContent,
|
|
130
|
+
SupportContextChipProps,
|
|
131
|
+
SupportSuggestedQuestionProps,
|
|
132
|
+
SupportStepGuideCardProps,
|
|
133
|
+
SupportArticleCardProps,
|
|
134
|
+
SupportAgentFABProps,
|
|
135
|
+
SupportAgentMessage,
|
|
136
|
+
SupportAgentPanelProps,
|
|
137
|
+
} from "./ui/support-agent";
|
|
138
|
+
|
|
139
|
+
export { ChatInputArea } from "./ui/chat-input-area";
|
|
140
|
+
export type { ChatInputAreaProps } from "./ui/chat-input-area";
|
|
141
|
+
|
|
118
142
|
export {
|
|
119
143
|
ChatWidgetLauncher,
|
|
120
144
|
ChatWidgetHeader,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { Bot, RotateCcw,
|
|
2
|
+
import { Bot, RotateCcw, X } from "lucide-react";
|
|
3
3
|
import { cn } from "@/lib/utils";
|
|
4
4
|
import { Sheet, SheetContent } from "@/components/ui/sheet";
|
|
5
5
|
import { Button } from "@/components/ui/button";
|
|
6
6
|
import { Badge } from "@/components/ui/badge";
|
|
7
|
+
import { ChatInputArea } from "@/components/ui/chat-input-area";
|
|
7
8
|
import { Spinner } from "@/components/ui/spinner";
|
|
8
|
-
import { Textarea } from "@/components/ui/textarea";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* AiAssistantDrawer — WealthX DS (L5 Drawer)
|
|
@@ -66,6 +66,10 @@ export interface AiAssistantDrawerProps {
|
|
|
66
66
|
isLoading?: boolean;
|
|
67
67
|
/** Called when the user submits a message. Input is cleared after this fires. */
|
|
68
68
|
onSendMessage?: (text: string) => void;
|
|
69
|
+
/** Called when the user selects files via the attachment button. */
|
|
70
|
+
onAttachFile?: (files: FileList) => void;
|
|
71
|
+
/** Called when the user selects images via the image upload button. */
|
|
72
|
+
onAttachImage?: (files: FileList) => void;
|
|
69
73
|
/** Called when the user clicks the reload/reset button. */
|
|
70
74
|
onReset?: () => void;
|
|
71
75
|
className?: string;
|
|
@@ -193,16 +197,16 @@ export function AiAssistantDrawer({
|
|
|
193
197
|
isStreaming = false,
|
|
194
198
|
isLoading = false,
|
|
195
199
|
onSendMessage,
|
|
200
|
+
onAttachFile,
|
|
201
|
+
onAttachImage,
|
|
196
202
|
onReset,
|
|
197
203
|
className,
|
|
198
204
|
}: AiAssistantDrawerProps) {
|
|
199
205
|
const [inputValue, setInputValue] = React.useState("");
|
|
200
206
|
const messagesEndRef = React.useRef<HTMLDivElement>(null);
|
|
201
|
-
const textareaRef = React.useRef<HTMLTextAreaElement>(null);
|
|
202
207
|
|
|
203
208
|
const suggestions = taskSuggestions ?? DEFAULT_SUGGESTIONS;
|
|
204
209
|
const hasMessages = messages.length > 0;
|
|
205
|
-
const canSend = inputValue.trim().length > 0 && !isStreaming && !isLoading;
|
|
206
210
|
|
|
207
211
|
// Auto-scroll to latest message
|
|
208
212
|
React.useEffect(() => {
|
|
@@ -213,31 +217,16 @@ export function AiAssistantDrawer({
|
|
|
213
217
|
});
|
|
214
218
|
}, [messages.length]);
|
|
215
219
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const handleSend = React.useCallback(() => {
|
|
225
|
-
const text = inputValue.trim();
|
|
226
|
-
if (!text || !canSend) return;
|
|
227
|
-
onSendMessage?.(text);
|
|
228
|
-
setInputValue("");
|
|
229
|
-
}, [inputValue, canSend, onSendMessage]);
|
|
230
|
-
|
|
231
|
-
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
|
232
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
233
|
-
e.preventDefault();
|
|
234
|
-
handleSend();
|
|
235
|
-
}
|
|
236
|
-
};
|
|
220
|
+
const handleSend = React.useCallback(
|
|
221
|
+
(text: string) => {
|
|
222
|
+
onSendMessage?.(text);
|
|
223
|
+
setInputValue("");
|
|
224
|
+
},
|
|
225
|
+
[onSendMessage],
|
|
226
|
+
);
|
|
237
227
|
|
|
238
228
|
const handleSuggestionSelect = (text: string) => {
|
|
239
229
|
setInputValue(text);
|
|
240
|
-
textareaRef.current?.focus();
|
|
241
230
|
};
|
|
242
231
|
|
|
243
232
|
return (
|
|
@@ -377,31 +366,15 @@ export function AiAssistantDrawer({
|
|
|
377
366
|
|
|
378
367
|
{/* Footer — input bar */}
|
|
379
368
|
<div className="border-t border-border p-3">
|
|
380
|
-
<
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
className="min-h-0 flex-1 resize-none overflow-hidden py-2 text-sm"
|
|
390
|
-
/>
|
|
391
|
-
<Button
|
|
392
|
-
size="icon"
|
|
393
|
-
onClick={handleSend}
|
|
394
|
-
disabled={!canSend}
|
|
395
|
-
className="shrink-0"
|
|
396
|
-
title="Send"
|
|
397
|
-
>
|
|
398
|
-
<Send className="size-4" />
|
|
399
|
-
<span className="sr-only">Send message</span>
|
|
400
|
-
</Button>
|
|
401
|
-
</div>
|
|
402
|
-
<p className="mt-1.5 text-[10px] text-muted-foreground">
|
|
403
|
-
Enter to send · Shift+Enter for new line
|
|
404
|
-
</p>
|
|
369
|
+
<ChatInputArea
|
|
370
|
+
value={inputValue}
|
|
371
|
+
onChange={setInputValue}
|
|
372
|
+
onSend={handleSend}
|
|
373
|
+
onAttachFile={onAttachFile}
|
|
374
|
+
onAttachImage={onAttachImage}
|
|
375
|
+
disabled={isLoading || isStreaming}
|
|
376
|
+
placeholder="Ask me anything…"
|
|
377
|
+
/>
|
|
405
378
|
</div>
|
|
406
379
|
</SheetContent>
|
|
407
380
|
</Sheet>
|
|
@@ -107,6 +107,10 @@ export interface ConversationsPageProps {
|
|
|
107
107
|
onSendEmail?: (payload: AiConvEmailPayload) => void;
|
|
108
108
|
onTakeOver?: () => void;
|
|
109
109
|
onLetAiHandle?: () => void;
|
|
110
|
+
/** Called when the user selects files via the attachment button in the composer. */
|
|
111
|
+
onAttachFile?: (files: FileList) => void;
|
|
112
|
+
/** Called when the user selects images via the image upload button in the composer. */
|
|
113
|
+
onAttachImage?: (files: FileList) => void;
|
|
110
114
|
/** Pre-fills the email Subject field with "Re: [emailReplySubject]" for reply threads. */
|
|
111
115
|
emailReplySubject?: string;
|
|
112
116
|
onReopen?: () => void;
|
|
@@ -168,6 +172,8 @@ export function ConversationsPage({
|
|
|
168
172
|
onSendEmail,
|
|
169
173
|
onTakeOver,
|
|
170
174
|
onLetAiHandle,
|
|
175
|
+
onAttachFile,
|
|
176
|
+
onAttachImage,
|
|
171
177
|
emailReplySubject,
|
|
172
178
|
onReopen,
|
|
173
179
|
onMarkUrgent,
|
|
@@ -187,7 +193,7 @@ export function ConversationsPage({
|
|
|
187
193
|
className,
|
|
188
194
|
}: ConversationsPageProps) {
|
|
189
195
|
const [mobilePanel, setMobilePanel] = useState<"list" | "chat" | "lead">(
|
|
190
|
-
"list"
|
|
196
|
+
"list",
|
|
191
197
|
);
|
|
192
198
|
|
|
193
199
|
const handleSelectConversation = (id: string) => {
|
|
@@ -222,7 +228,7 @@ export function ConversationsPage({
|
|
|
222
228
|
onLoadMore={onLoadMore}
|
|
223
229
|
className={cn(
|
|
224
230
|
"shrink-0 md:w-[320px]",
|
|
225
|
-
mobilePanel === "list" ? "flex w-full md:flex" : "hidden md:flex"
|
|
231
|
+
mobilePanel === "list" ? "flex w-full md:flex" : "hidden md:flex",
|
|
226
232
|
)}
|
|
227
233
|
/>
|
|
228
234
|
|
|
@@ -244,6 +250,8 @@ export function ConversationsPage({
|
|
|
244
250
|
onSendEmail={onSendEmail}
|
|
245
251
|
onTakeOver={onTakeOver}
|
|
246
252
|
onLetAiHandle={onLetAiHandle}
|
|
253
|
+
onAttachFile={onAttachFile}
|
|
254
|
+
onAttachImage={onAttachImage}
|
|
247
255
|
emailReplySubject={emailReplySubject}
|
|
248
256
|
onReopen={onReopen}
|
|
249
257
|
onMarkUrgent={onMarkUrgent}
|
|
@@ -259,14 +267,14 @@ export function ConversationsPage({
|
|
|
259
267
|
"min-w-0 flex-1 border-r border-border",
|
|
260
268
|
mobilePanel === "chat"
|
|
261
269
|
? "flex flex-col md:flex"
|
|
262
|
-
: "hidden md:flex"
|
|
270
|
+
: "hidden md:flex",
|
|
263
271
|
)}
|
|
264
272
|
/>
|
|
265
273
|
) : (
|
|
266
274
|
<div
|
|
267
275
|
className={cn(
|
|
268
276
|
"min-w-0 flex-1 items-center justify-center border-r border-border bg-muted/10",
|
|
269
|
-
mobilePanel === "chat" ? "flex md:flex" : "hidden md:flex"
|
|
277
|
+
mobilePanel === "chat" ? "flex md:flex" : "hidden md:flex",
|
|
270
278
|
)}
|
|
271
279
|
>
|
|
272
280
|
<div className="flex flex-col items-center gap-2 text-muted-foreground">
|
|
@@ -285,7 +293,7 @@ export function ConversationsPage({
|
|
|
285
293
|
? "flex w-full shrink-0 flex-col"
|
|
286
294
|
: "hidden",
|
|
287
295
|
"md:block md:shrink-0 md:overflow-hidden md:transition-[width] md:duration-200 md:ease-in-out",
|
|
288
|
-
showLeadPanel ? "md:w-[320px]" : "md:w-0"
|
|
296
|
+
showLeadPanel ? "md:w-[320px]" : "md:w-0",
|
|
289
297
|
)}
|
|
290
298
|
>
|
|
291
299
|
<LeadInfoPanel
|
|
@@ -364,13 +372,13 @@ export function AiConvAssignAdvisorDialog({
|
|
|
364
372
|
const [roleFilter, setRoleFilter] = useState("");
|
|
365
373
|
|
|
366
374
|
const roles = Array.from(
|
|
367
|
-
new Set(advisors.map((a) => a.role).filter(Boolean))
|
|
375
|
+
new Set(advisors.map((a) => a.role).filter(Boolean)),
|
|
368
376
|
) as string[];
|
|
369
377
|
|
|
370
378
|
const filtered = advisors.filter(
|
|
371
379
|
(a) =>
|
|
372
380
|
a.name.toLowerCase().includes(search.toLowerCase()) &&
|
|
373
|
-
(!roleFilter || a.role === roleFilter)
|
|
381
|
+
(!roleFilter || a.role === roleFilter),
|
|
374
382
|
);
|
|
375
383
|
|
|
376
384
|
const handleOpenChange = (v: boolean) => {
|
|
@@ -436,7 +444,7 @@ export function AiConvAssignAdvisorDialog({
|
|
|
436
444
|
onClick={() => onValueChange(advisor.id)}
|
|
437
445
|
className={cn(
|
|
438
446
|
"flex w-full items-center gap-3 px-3 py-2.5 text-left text-sm transition-colors hover:bg-muted",
|
|
439
|
-
value === advisor.id && "bg-muted font-medium"
|
|
447
|
+
value === advisor.id && "bg-muted font-medium",
|
|
440
448
|
)}
|
|
441
449
|
>
|
|
442
450
|
<Avatar size="sm">
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
import { Separator } from "@/components/ui/separator";
|
|
40
40
|
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
41
41
|
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
|
|
42
|
-
import {
|
|
42
|
+
import { ChatInputArea } from "@/components/ui/chat-input-area";
|
|
43
43
|
import type {
|
|
44
44
|
AiConvChannel,
|
|
45
45
|
AiConvContact,
|
|
@@ -88,6 +88,10 @@ export interface ChatComposerProps {
|
|
|
88
88
|
onSendEmail?: (payload: AiConvEmailPayload) => void;
|
|
89
89
|
onTakeOver?: () => void;
|
|
90
90
|
onLetAiHandle?: () => void;
|
|
91
|
+
/** Called when the user selects files via the attachment button. */
|
|
92
|
+
onAttachFile?: (files: FileList) => void;
|
|
93
|
+
/** Called when the user selects images via the image upload button. */
|
|
94
|
+
onAttachImage?: (files: FileList) => void;
|
|
91
95
|
/** Pre-fills the Subject field with "Re: [emailReplySubject]" for email threads. */
|
|
92
96
|
emailReplySubject?: string;
|
|
93
97
|
className?: string;
|
|
@@ -114,7 +118,7 @@ function ComposerToolbarButton({
|
|
|
114
118
|
"flex size-7 items-center justify-center transition-colors",
|
|
115
119
|
pressed
|
|
116
120
|
? "bg-foreground text-background"
|
|
117
|
-
: "text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
121
|
+
: "text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
118
122
|
)}
|
|
119
123
|
>
|
|
120
124
|
<Icon className="size-3.5" />
|
|
@@ -156,7 +160,7 @@ function ComposerLinkPopover({
|
|
|
156
160
|
"flex size-7 items-center justify-center transition-colors",
|
|
157
161
|
editor?.isActive("link")
|
|
158
162
|
? "bg-foreground text-background"
|
|
159
|
-
: "text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
163
|
+
: "text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
160
164
|
)}
|
|
161
165
|
>
|
|
162
166
|
<Link2 className="size-3.5" />
|
|
@@ -210,6 +214,8 @@ export function ChatComposer({
|
|
|
210
214
|
onSendEmail,
|
|
211
215
|
onTakeOver,
|
|
212
216
|
onLetAiHandle,
|
|
217
|
+
onAttachFile,
|
|
218
|
+
onAttachImage,
|
|
213
219
|
emailReplySubject,
|
|
214
220
|
className,
|
|
215
221
|
}: ChatComposerProps) {
|
|
@@ -217,16 +223,16 @@ export function ChatComposer({
|
|
|
217
223
|
// Force chat when email isn't integrated so the panel never lands on a hidden tab.
|
|
218
224
|
const initialChannelRef = React.useRef(channelProp);
|
|
219
225
|
const [channel, setChannel] = React.useState<AiConvChannel>(
|
|
220
|
-
isEmailIntegrated ? channelProp : "chat"
|
|
226
|
+
isEmailIntegrated ? channelProp : "chat",
|
|
221
227
|
);
|
|
222
228
|
const [emailTo, setEmailTo] = React.useState(contactEmail);
|
|
223
229
|
const [emailCc, setEmailCc] = React.useState("");
|
|
224
230
|
const [showCc, setShowCc] = React.useState(false);
|
|
225
231
|
const [emailSubject, setEmailSubject] = React.useState(
|
|
226
|
-
emailReplySubject ? `Re: ${emailReplySubject}` : ""
|
|
232
|
+
emailReplySubject ? `Re: ${emailReplySubject}` : "",
|
|
227
233
|
);
|
|
228
234
|
const [emailMode, setEmailMode] = React.useState<"reply" | "new">(
|
|
229
|
-
emailReplySubject ? "reply" : "new"
|
|
235
|
+
emailReplySubject ? "reply" : "new",
|
|
230
236
|
);
|
|
231
237
|
|
|
232
238
|
const [, forceUpdate] = React.useReducer((x: number) => x + 1, 0);
|
|
@@ -272,7 +278,7 @@ export function ChatComposer({
|
|
|
272
278
|
<div
|
|
273
279
|
className={cn(
|
|
274
280
|
"flex flex-col border-t border-border bg-background",
|
|
275
|
-
className
|
|
281
|
+
className,
|
|
276
282
|
)}
|
|
277
283
|
>
|
|
278
284
|
{isEmailIntegrated && (
|
|
@@ -316,7 +322,7 @@ export function ChatComposer({
|
|
|
316
322
|
<div
|
|
317
323
|
className={cn(
|
|
318
324
|
"flex flex-col",
|
|
319
|
-
channel !== "email" && "invisible pointer-events-none"
|
|
325
|
+
channel !== "email" && "invisible pointer-events-none",
|
|
320
326
|
)}
|
|
321
327
|
aria-hidden={channel !== "email"}
|
|
322
328
|
>
|
|
@@ -432,29 +438,26 @@ export function ChatComposer({
|
|
|
432
438
|
{/* Chat compose — absolute overlay, fills exact same height as email panel */}
|
|
433
439
|
{channel === "chat" && (
|
|
434
440
|
<div className="absolute inset-0 flex flex-col gap-3 p-4">
|
|
435
|
-
<
|
|
441
|
+
<ChatInputArea
|
|
436
442
|
value={inputValue}
|
|
437
|
-
onChange={(
|
|
438
|
-
|
|
439
|
-
|
|
443
|
+
onChange={(v) => onInputChange?.(v)}
|
|
444
|
+
onSend={(text) => onSend?.(text)}
|
|
445
|
+
onAttachFile={onAttachFile}
|
|
446
|
+
onAttachImage={onAttachImage}
|
|
447
|
+
placeholder="Reply to lead…"
|
|
448
|
+
hint={false}
|
|
440
449
|
/>
|
|
441
|
-
|
|
442
|
-
{initialChannelRef.current !== "email" && (
|
|
443
|
-
<Button variant="outline" size="sm" onClick={onLetAiHandle}>
|
|
444
|
-
<Bot className="mr-1.5 size-3.5" />
|
|
445
|
-
Let AI Handle
|
|
446
|
-
</Button>
|
|
447
|
-
)}
|
|
450
|
+
{initialChannelRef.current !== "email" && (
|
|
448
451
|
<Button
|
|
452
|
+
variant="outline"
|
|
449
453
|
size="sm"
|
|
450
|
-
className="
|
|
451
|
-
onClick={
|
|
452
|
-
disabled={!inputValue.trim()}
|
|
454
|
+
className="self-start"
|
|
455
|
+
onClick={onLetAiHandle}
|
|
453
456
|
>
|
|
454
|
-
<
|
|
455
|
-
|
|
457
|
+
<Bot className="mr-1.5 size-3.5" />
|
|
458
|
+
Let AI Handle
|
|
456
459
|
</Button>
|
|
457
|
-
|
|
460
|
+
)}
|
|
458
461
|
</div>
|
|
459
462
|
)}
|
|
460
463
|
</div>
|
|
@@ -486,6 +489,10 @@ export interface ChatThreadProps {
|
|
|
486
489
|
onSendEmail?: (payload: AiConvEmailPayload) => void;
|
|
487
490
|
onTakeOver?: () => void;
|
|
488
491
|
onLetAiHandle?: () => void;
|
|
492
|
+
/** Called when the user selects files via the attachment button in the composer. */
|
|
493
|
+
onAttachFile?: (files: FileList) => void;
|
|
494
|
+
/** Called when the user selects images via the image upload button in the composer. */
|
|
495
|
+
onAttachImage?: (files: FileList) => void;
|
|
489
496
|
/** Pre-fills the email Subject field with "Re: [emailReplySubject]" for reply threads. */
|
|
490
497
|
emailReplySubject?: string;
|
|
491
498
|
onReopen?: () => void;
|
|
@@ -521,6 +528,8 @@ export function ChatThread({
|
|
|
521
528
|
onSendEmail,
|
|
522
529
|
onTakeOver,
|
|
523
530
|
onLetAiHandle,
|
|
531
|
+
onAttachFile,
|
|
532
|
+
onAttachImage,
|
|
524
533
|
emailReplySubject,
|
|
525
534
|
onReopen,
|
|
526
535
|
onMarkUrgent,
|
|
@@ -598,7 +607,7 @@ export function ChatThread({
|
|
|
598
607
|
<div
|
|
599
608
|
className={cn(
|
|
600
609
|
PANEL_HEADER_HEIGHT,
|
|
601
|
-
"flex items-center gap-3 border-b border-border px-4"
|
|
610
|
+
"flex items-center gap-3 border-b border-border px-4",
|
|
602
611
|
)}
|
|
603
612
|
>
|
|
604
613
|
{onBack && (
|
|
@@ -651,7 +660,7 @@ export function ChatThread({
|
|
|
651
660
|
<DropdownMenuTrigger
|
|
652
661
|
className={cn(
|
|
653
662
|
buttonVariants({ variant: "ghost", size: "icon" }),
|
|
654
|
-
"size-8"
|
|
663
|
+
"size-8",
|
|
655
664
|
)}
|
|
656
665
|
aria-label="More actions"
|
|
657
666
|
>
|
|
@@ -762,6 +771,8 @@ export function ChatThread({
|
|
|
762
771
|
onSendEmail={onSendEmail}
|
|
763
772
|
onTakeOver={onTakeOver}
|
|
764
773
|
onLetAiHandle={onLetAiHandle}
|
|
774
|
+
onAttachFile={onAttachFile}
|
|
775
|
+
onAttachImage={onAttachImage}
|
|
765
776
|
emailReplySubject={emailReplySubject}
|
|
766
777
|
/>
|
|
767
778
|
)}
|