@wealthx/shadcn 1.5.37 → 1.5.39
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 +142 -133
- package/CHANGELOG.md +12 -0
- package/dist/{chunk-LSSIWLYU.mjs → chunk-6XNEHTII.mjs} +1 -1
- package/dist/{chunk-ULQ53FRJ.mjs → chunk-7NQKFPXE.mjs} +1 -1
- package/dist/{chunk-734FOOJC.mjs → chunk-B5PSUONN.mjs} +25 -58
- package/dist/{chunk-DSVKEVX6.mjs → chunk-CZOGJC76.mjs} +1 -1
- package/dist/chunk-EFHPSKVF.mjs +192 -0
- package/dist/{chunk-JPGL36WQ.mjs → chunk-FL7DEYUA.mjs} +6 -7
- package/dist/{chunk-2CHH5QOA.mjs → chunk-FQUT5XD6.mjs} +1 -1
- package/dist/chunk-MGIDYXOP.mjs +814 -0
- package/dist/{chunk-OG2VM34K.mjs → chunk-MHBQJVHE.mjs} +1 -1
- 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/file-preview-dialog.js +6 -7
- package/dist/components/ui/file-preview-dialog.mjs +2 -2
- package/dist/components/ui/kanban-column.js +6 -7
- package/dist/components/ui/kanban-column.mjs +3 -3
- package/dist/components/ui/opportunity-card.js +6 -7
- package/dist/components/ui/opportunity-card.mjs +2 -2
- package/dist/components/ui/page-top-bar.js +182 -5
- package/dist/components/ui/page-top-bar.mjs +3 -1
- package/dist/components/ui/pipeline-board.js +6 -7
- package/dist/components/ui/pipeline-board.mjs +4 -4
- package/dist/components/ui/policy-ai/index.js +1636 -0
- package/dist/components/ui/policy-ai/index.mjs +36 -0
- package/dist/components/ui/progress.js +6 -7
- package/dist/components/ui/progress.mjs +1 -1
- package/dist/components/ui/stage-timeline.js +6 -7
- package/dist/components/ui/stage-timeline.mjs +2 -2
- package/dist/components/ui/support-agent/index.js +1131 -0
- package/dist/components/ui/support-agent/index.mjs +27 -0
- package/dist/index.js +5609 -4100
- package/dist/index.mjs +77 -41
- package/dist/styles.css +1 -1
- package/package.json +16 -1
- package/src/components/index.tsx +54 -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/policy-ai/index.tsx +41 -0
- package/src/components/ui/policy-ai/policy-ai-panel.tsx +526 -0
- package/src/components/ui/policy-ai/policy-ai-primitives.tsx +332 -0
- package/src/components/ui/policy-ai/policy-ai-responses.tsx +543 -0
- package/src/components/ui/progress.tsx +15 -12
- 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 +3 -0
|
@@ -31,6 +31,9 @@ import {
|
|
|
31
31
|
import {
|
|
32
32
|
Separator
|
|
33
33
|
} from "./chunk-2GIYVERS.mjs";
|
|
34
|
+
import {
|
|
35
|
+
ChatInputArea
|
|
36
|
+
} from "./chunk-EFHPSKVF.mjs";
|
|
34
37
|
import {
|
|
35
38
|
Textarea
|
|
36
39
|
} from "./chunk-BS75ICOO.mjs";
|
|
@@ -606,6 +609,8 @@ function ChatComposer({
|
|
|
606
609
|
onSendEmail,
|
|
607
610
|
onTakeOver,
|
|
608
611
|
onLetAiHandle,
|
|
612
|
+
onAttachFile,
|
|
613
|
+
onAttachImage,
|
|
609
614
|
emailReplySubject,
|
|
610
615
|
className
|
|
611
616
|
}) {
|
|
@@ -836,33 +841,30 @@ function ChatComposer({
|
|
|
836
841
|
),
|
|
837
842
|
channel === "chat" && /* @__PURE__ */ jsxs3("div", { className: "absolute inset-0 flex flex-col gap-3 p-4", children: [
|
|
838
843
|
/* @__PURE__ */ jsx4(
|
|
839
|
-
|
|
844
|
+
ChatInputArea,
|
|
840
845
|
{
|
|
841
846
|
value: inputValue,
|
|
842
|
-
onChange: (
|
|
843
|
-
|
|
844
|
-
|
|
847
|
+
onChange: (v) => onInputChange == null ? void 0 : onInputChange(v),
|
|
848
|
+
onSend: (text) => onSend == null ? void 0 : onSend(text),
|
|
849
|
+
onAttachFile,
|
|
850
|
+
onAttachImage,
|
|
851
|
+
placeholder: "Reply to lead\u2026",
|
|
852
|
+
hint: false
|
|
845
853
|
}
|
|
846
854
|
),
|
|
847
|
-
/* @__PURE__ */ jsxs3(
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
/* @__PURE__ */ jsx4(Send, { className: "mr-1.5 size-3.5" }),
|
|
861
|
-
"Send"
|
|
862
|
-
]
|
|
863
|
-
}
|
|
864
|
-
)
|
|
865
|
-
] })
|
|
855
|
+
initialChannelRef.current !== "email" && /* @__PURE__ */ jsxs3(
|
|
856
|
+
Button,
|
|
857
|
+
{
|
|
858
|
+
variant: "outline",
|
|
859
|
+
size: "sm",
|
|
860
|
+
className: "self-start",
|
|
861
|
+
onClick: onLetAiHandle,
|
|
862
|
+
children: [
|
|
863
|
+
/* @__PURE__ */ jsx4(Bot2, { className: "mr-1.5 size-3.5" }),
|
|
864
|
+
"Let AI Handle"
|
|
865
|
+
]
|
|
866
|
+
}
|
|
867
|
+
)
|
|
866
868
|
] })
|
|
867
869
|
] })
|
|
868
870
|
)
|
|
@@ -885,6 +887,8 @@ function ChatThread({
|
|
|
885
887
|
onSendEmail,
|
|
886
888
|
onTakeOver,
|
|
887
889
|
onLetAiHandle,
|
|
890
|
+
onAttachFile,
|
|
891
|
+
onAttachImage,
|
|
888
892
|
emailReplySubject,
|
|
889
893
|
onReopen,
|
|
890
894
|
onMarkUrgent,
|
|
@@ -1078,6 +1082,8 @@ function ChatThread({
|
|
|
1078
1082
|
onSendEmail,
|
|
1079
1083
|
onTakeOver,
|
|
1080
1084
|
onLetAiHandle,
|
|
1085
|
+
onAttachFile,
|
|
1086
|
+
onAttachImage,
|
|
1081
1087
|
emailReplySubject
|
|
1082
1088
|
}
|
|
1083
1089
|
)
|
|
@@ -1508,6 +1514,8 @@ function ConversationsPage({
|
|
|
1508
1514
|
onSendEmail,
|
|
1509
1515
|
onTakeOver,
|
|
1510
1516
|
onLetAiHandle,
|
|
1517
|
+
onAttachFile,
|
|
1518
|
+
onAttachImage,
|
|
1511
1519
|
emailReplySubject,
|
|
1512
1520
|
onReopen,
|
|
1513
1521
|
onMarkUrgent,
|
|
@@ -1581,6 +1589,8 @@ function ConversationsPage({
|
|
|
1581
1589
|
onSendEmail,
|
|
1582
1590
|
onTakeOver,
|
|
1583
1591
|
onLetAiHandle,
|
|
1592
|
+
onAttachFile,
|
|
1593
|
+
onAttachImage,
|
|
1584
1594
|
emailReplySubject,
|
|
1585
1595
|
onReopen,
|
|
1586
1596
|
onMarkUrgent,
|
|
@@ -62,8 +62,8 @@ __export(ai_assistant_drawer_exports, {
|
|
|
62
62
|
AiAssistantDrawer: () => AiAssistantDrawer
|
|
63
63
|
});
|
|
64
64
|
module.exports = __toCommonJS(ai_assistant_drawer_exports);
|
|
65
|
-
var
|
|
66
|
-
var
|
|
65
|
+
var React4 = __toESM(require("react"));
|
|
66
|
+
var import_lucide_react5 = require("lucide-react");
|
|
67
67
|
|
|
68
68
|
// src/lib/utils.ts
|
|
69
69
|
var import_clsx = require("clsx");
|
|
@@ -367,10 +367,208 @@ function Badge(_a) {
|
|
|
367
367
|
);
|
|
368
368
|
}
|
|
369
369
|
|
|
370
|
-
// src/components/ui/
|
|
371
|
-
var
|
|
370
|
+
// src/components/ui/chat-input-area.tsx
|
|
371
|
+
var React3 = __toESM(require("react"));
|
|
372
372
|
var import_lucide_react3 = require("lucide-react");
|
|
373
|
+
|
|
374
|
+
// src/components/ui/textarea.tsx
|
|
373
375
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
376
|
+
function Textarea(_a) {
|
|
377
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
378
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
379
|
+
"textarea",
|
|
380
|
+
__spreadValues({
|
|
381
|
+
className: cn(
|
|
382
|
+
// WealthX: removed shadow-xs (flat panels), added font-sans
|
|
383
|
+
"flex field-sizing-content min-h-16 w-full border border-input bg-transparent px-3 py-2 text-body-medium font-sans transition-[color,box-shadow] outline-none placeholder:font-normal placeholder:text-muted-foreground focus-visible:border-primary focus-visible:ring-[3px] focus-visible:ring-primary/20 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:bg-input/30 dark:aria-invalid:ring-destructive/40",
|
|
384
|
+
className
|
|
385
|
+
),
|
|
386
|
+
"data-slot": "textarea"
|
|
387
|
+
}, props)
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/components/ui/chat-input-area.tsx
|
|
392
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
393
|
+
var DEFAULT_HINT = "Enter to send \xB7 Shift+Enter for new line";
|
|
394
|
+
function ChatInputArea({
|
|
395
|
+
value,
|
|
396
|
+
onChange,
|
|
397
|
+
onSend,
|
|
398
|
+
onAttachFile,
|
|
399
|
+
onAttachImage,
|
|
400
|
+
disabled = false,
|
|
401
|
+
placeholder = "Type your message\u2026",
|
|
402
|
+
hint = DEFAULT_HINT,
|
|
403
|
+
maxHeight = 160,
|
|
404
|
+
autoFocus = false,
|
|
405
|
+
className
|
|
406
|
+
}) {
|
|
407
|
+
const textareaRef = React3.useRef(null);
|
|
408
|
+
const fileInputRef = React3.useRef(null);
|
|
409
|
+
const imageInputRef = React3.useRef(null);
|
|
410
|
+
React3.useEffect(() => {
|
|
411
|
+
if (autoFocus) {
|
|
412
|
+
setTimeout(() => {
|
|
413
|
+
var _a;
|
|
414
|
+
return (_a = textareaRef.current) == null ? void 0 : _a.focus();
|
|
415
|
+
}, 50);
|
|
416
|
+
}
|
|
417
|
+
}, [autoFocus]);
|
|
418
|
+
const handleSend = React3.useCallback(() => {
|
|
419
|
+
const text = value.trim();
|
|
420
|
+
if (!text || disabled) return;
|
|
421
|
+
onSend(text);
|
|
422
|
+
if (textareaRef.current) {
|
|
423
|
+
textareaRef.current.style.height = "auto";
|
|
424
|
+
}
|
|
425
|
+
}, [value, disabled, onSend]);
|
|
426
|
+
const handleKeyDown = React3.useCallback(
|
|
427
|
+
(e) => {
|
|
428
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
429
|
+
e.preventDefault();
|
|
430
|
+
handleSend();
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
[handleSend]
|
|
434
|
+
);
|
|
435
|
+
const handleTextareaChange = React3.useCallback(
|
|
436
|
+
(e) => {
|
|
437
|
+
onChange(e.target.value);
|
|
438
|
+
const el = e.target;
|
|
439
|
+
el.style.height = "auto";
|
|
440
|
+
el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`;
|
|
441
|
+
},
|
|
442
|
+
[onChange, maxHeight]
|
|
443
|
+
);
|
|
444
|
+
const handleFileChange = React3.useCallback(
|
|
445
|
+
(e) => {
|
|
446
|
+
var _a;
|
|
447
|
+
if ((_a = e.target.files) == null ? void 0 : _a.length) {
|
|
448
|
+
onAttachFile == null ? void 0 : onAttachFile(e.target.files);
|
|
449
|
+
e.target.value = "";
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
[onAttachFile]
|
|
453
|
+
);
|
|
454
|
+
const handleImageChange = React3.useCallback(
|
|
455
|
+
(e) => {
|
|
456
|
+
var _a;
|
|
457
|
+
if ((_a = e.target.files) == null ? void 0 : _a.length) {
|
|
458
|
+
onAttachImage == null ? void 0 : onAttachImage(e.target.files);
|
|
459
|
+
e.target.value = "";
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
[onAttachImage]
|
|
463
|
+
);
|
|
464
|
+
const showFileButton = typeof onAttachFile === "function";
|
|
465
|
+
const showImageButton = typeof onAttachImage === "function";
|
|
466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
467
|
+
"div",
|
|
468
|
+
{
|
|
469
|
+
"data-slot": "chat-input-area",
|
|
470
|
+
className: cn("flex flex-col gap-1.5", className),
|
|
471
|
+
children: [
|
|
472
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "border border-border bg-background flex flex-col focus-within:ring-1 focus-within:ring-ring", children: [
|
|
473
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
474
|
+
Textarea,
|
|
475
|
+
{
|
|
476
|
+
ref: textareaRef,
|
|
477
|
+
value,
|
|
478
|
+
onChange: handleTextareaChange,
|
|
479
|
+
onKeyDown: handleKeyDown,
|
|
480
|
+
placeholder,
|
|
481
|
+
disabled,
|
|
482
|
+
rows: 3,
|
|
483
|
+
className: "resize-none text-sm border-0 shadow-none focus-visible:ring-0 px-3 pt-3 pb-1 min-h-[72px]",
|
|
484
|
+
"aria-label": placeholder
|
|
485
|
+
}
|
|
486
|
+
),
|
|
487
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between px-2 pb-2", children: [
|
|
488
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-0.5", children: [
|
|
489
|
+
showFileButton && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
490
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
491
|
+
Button,
|
|
492
|
+
{
|
|
493
|
+
variant: "ghost",
|
|
494
|
+
size: "icon-sm",
|
|
495
|
+
type: "button",
|
|
496
|
+
title: "Attach file",
|
|
497
|
+
"aria-label": "Attach file",
|
|
498
|
+
disabled,
|
|
499
|
+
onClick: () => {
|
|
500
|
+
var _a;
|
|
501
|
+
return (_a = fileInputRef.current) == null ? void 0 : _a.click();
|
|
502
|
+
},
|
|
503
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Paperclip, { className: "size-3.5", "aria-hidden": "true" })
|
|
504
|
+
}
|
|
505
|
+
),
|
|
506
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
507
|
+
"input",
|
|
508
|
+
{
|
|
509
|
+
ref: fileInputRef,
|
|
510
|
+
type: "file",
|
|
511
|
+
multiple: true,
|
|
512
|
+
className: "sr-only",
|
|
513
|
+
tabIndex: -1,
|
|
514
|
+
onChange: handleFileChange
|
|
515
|
+
}
|
|
516
|
+
)
|
|
517
|
+
] }),
|
|
518
|
+
showImageButton && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
519
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
520
|
+
Button,
|
|
521
|
+
{
|
|
522
|
+
variant: "ghost",
|
|
523
|
+
size: "icon-sm",
|
|
524
|
+
type: "button",
|
|
525
|
+
title: "Upload image",
|
|
526
|
+
"aria-label": "Upload image",
|
|
527
|
+
disabled,
|
|
528
|
+
onClick: () => {
|
|
529
|
+
var _a;
|
|
530
|
+
return (_a = imageInputRef.current) == null ? void 0 : _a.click();
|
|
531
|
+
},
|
|
532
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.ImagePlus, { className: "size-3.5", "aria-hidden": "true" })
|
|
533
|
+
}
|
|
534
|
+
),
|
|
535
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
536
|
+
"input",
|
|
537
|
+
{
|
|
538
|
+
ref: imageInputRef,
|
|
539
|
+
type: "file",
|
|
540
|
+
multiple: true,
|
|
541
|
+
accept: "image/*",
|
|
542
|
+
className: "sr-only",
|
|
543
|
+
tabIndex: -1,
|
|
544
|
+
onChange: handleImageChange
|
|
545
|
+
}
|
|
546
|
+
)
|
|
547
|
+
] })
|
|
548
|
+
] }),
|
|
549
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
550
|
+
Button,
|
|
551
|
+
{
|
|
552
|
+
size: "icon-sm",
|
|
553
|
+
type: "button",
|
|
554
|
+
"aria-label": "Send message",
|
|
555
|
+
disabled: !value.trim() || disabled,
|
|
556
|
+
onClick: handleSend,
|
|
557
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Send, { className: "size-3.5", "aria-hidden": "true" })
|
|
558
|
+
}
|
|
559
|
+
)
|
|
560
|
+
] })
|
|
561
|
+
] }),
|
|
562
|
+
hint !== false && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs text-muted-foreground", children: hint })
|
|
563
|
+
]
|
|
564
|
+
}
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// src/components/ui/spinner.tsx
|
|
569
|
+
var import_class_variance_authority3 = require("class-variance-authority");
|
|
570
|
+
var import_lucide_react4 = require("lucide-react");
|
|
571
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
374
572
|
var spinnerVariants = (0, import_class_variance_authority3.cva)("animate-spin shrink-0", {
|
|
375
573
|
variants: {
|
|
376
574
|
size: {
|
|
@@ -386,8 +584,8 @@ var spinnerVariants = (0, import_class_variance_authority3.cva)("animate-spin sh
|
|
|
386
584
|
});
|
|
387
585
|
function Spinner(_a) {
|
|
388
586
|
var _b = _a, { className, size } = _b, props = __objRest(_b, ["className", "size"]);
|
|
389
|
-
return /* @__PURE__ */ (0,
|
|
390
|
-
|
|
587
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
588
|
+
import_lucide_react4.LoaderCircle,
|
|
391
589
|
__spreadValues({
|
|
392
590
|
"aria-hidden": "true",
|
|
393
591
|
className: cn(spinnerVariants({ size }), className),
|
|
@@ -396,27 +594,10 @@ function Spinner(_a) {
|
|
|
396
594
|
);
|
|
397
595
|
}
|
|
398
596
|
|
|
399
|
-
// src/components/ui/textarea.tsx
|
|
400
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
401
|
-
function Textarea(_a) {
|
|
402
|
-
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
403
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
404
|
-
"textarea",
|
|
405
|
-
__spreadValues({
|
|
406
|
-
className: cn(
|
|
407
|
-
// WealthX: removed shadow-xs (flat panels), added font-sans
|
|
408
|
-
"flex field-sizing-content min-h-16 w-full border border-input bg-transparent px-3 py-2 text-body-medium font-sans transition-[color,box-shadow] outline-none placeholder:font-normal placeholder:text-muted-foreground focus-visible:border-primary focus-visible:ring-[3px] focus-visible:ring-primary/20 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:bg-input/30 dark:aria-invalid:ring-destructive/40",
|
|
409
|
-
className
|
|
410
|
-
),
|
|
411
|
-
"data-slot": "textarea"
|
|
412
|
-
}, props)
|
|
413
|
-
);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
597
|
// src/components/ui/ai-assistant-drawer.tsx
|
|
417
|
-
var
|
|
598
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
418
599
|
function AiTypingIndicator() {
|
|
419
|
-
return /* @__PURE__ */ (0,
|
|
600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "flex items-center gap-1 py-1", "aria-label": "AI is thinking", children: [0, 150, 300].map((delay) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
420
601
|
"span",
|
|
421
602
|
{
|
|
422
603
|
className: "size-1.5 rounded-full bg-current animate-bounce",
|
|
@@ -429,11 +610,11 @@ function AiTypingIndicator() {
|
|
|
429
610
|
function AiChatBubble({ message }) {
|
|
430
611
|
const isUser = message.role === "user";
|
|
431
612
|
const isEmpty = !message.content.trim();
|
|
432
|
-
return /* @__PURE__ */ (0,
|
|
613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
433
614
|
"div",
|
|
434
615
|
{
|
|
435
616
|
className: cn("flex w-full", isUser ? "justify-end" : "justify-start"),
|
|
436
|
-
children: /* @__PURE__ */ (0,
|
|
617
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
437
618
|
"div",
|
|
438
619
|
{
|
|
439
620
|
className: cn(
|
|
@@ -442,8 +623,8 @@ function AiChatBubble({ message }) {
|
|
|
442
623
|
message.isErrored && "bg-destructive/10 text-destructive"
|
|
443
624
|
),
|
|
444
625
|
children: [
|
|
445
|
-
isEmpty && message.isStreaming ? /* @__PURE__ */ (0,
|
|
446
|
-
message.isErrored && /* @__PURE__ */ (0,
|
|
626
|
+
isEmpty && message.isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AiTypingIndicator, {}) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "whitespace-pre-wrap break-words leading-relaxed", children: message.content }),
|
|
627
|
+
message.isErrored && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "mt-1 text-xs opacity-70", children: "Failed to send. Please try again." })
|
|
447
628
|
]
|
|
448
629
|
}
|
|
449
630
|
)
|
|
@@ -454,7 +635,7 @@ function AiTaskCard({
|
|
|
454
635
|
suggestion,
|
|
455
636
|
onSelect
|
|
456
637
|
}) {
|
|
457
|
-
return /* @__PURE__ */ (0,
|
|
638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
458
639
|
Button,
|
|
459
640
|
{
|
|
460
641
|
type: "button",
|
|
@@ -462,8 +643,8 @@ function AiTaskCard({
|
|
|
462
643
|
onClick: () => onSelect(suggestion.title),
|
|
463
644
|
className: "h-auto w-full flex-col items-start gap-1 border border-border bg-background p-3 text-left hover:bg-muted/50",
|
|
464
645
|
children: [
|
|
465
|
-
/* @__PURE__ */ (0,
|
|
466
|
-
/* @__PURE__ */ (0,
|
|
646
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm font-medium text-foreground", children: suggestion.title }),
|
|
647
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-xs text-muted-foreground", children: suggestion.description })
|
|
467
648
|
]
|
|
468
649
|
}
|
|
469
650
|
);
|
|
@@ -499,47 +680,34 @@ function AiAssistantDrawer({
|
|
|
499
680
|
isStreaming = false,
|
|
500
681
|
isLoading = false,
|
|
501
682
|
onSendMessage,
|
|
683
|
+
onAttachFile,
|
|
684
|
+
onAttachImage,
|
|
502
685
|
onReset,
|
|
503
686
|
className
|
|
504
687
|
}) {
|
|
505
688
|
var _a;
|
|
506
|
-
const [inputValue, setInputValue] =
|
|
507
|
-
const messagesEndRef =
|
|
508
|
-
const textareaRef = React3.useRef(null);
|
|
689
|
+
const [inputValue, setInputValue] = React4.useState("");
|
|
690
|
+
const messagesEndRef = React4.useRef(null);
|
|
509
691
|
const suggestions = taskSuggestions != null ? taskSuggestions : DEFAULT_SUGGESTIONS;
|
|
510
692
|
const hasMessages = messages.length > 0;
|
|
511
|
-
|
|
512
|
-
React3.useEffect(() => {
|
|
693
|
+
React4.useEffect(() => {
|
|
513
694
|
if (!messagesEndRef.current) return;
|
|
514
695
|
messagesEndRef.current.scrollIntoView({
|
|
515
696
|
behavior: "smooth",
|
|
516
697
|
block: "nearest"
|
|
517
698
|
});
|
|
518
699
|
}, [messages.length]);
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
const text = inputValue.trim();
|
|
527
|
-
if (!text || !canSend) return;
|
|
528
|
-
onSendMessage == null ? void 0 : onSendMessage(text);
|
|
529
|
-
setInputValue("");
|
|
530
|
-
}, [inputValue, canSend, onSendMessage]);
|
|
531
|
-
const handleKeyDown = (e) => {
|
|
532
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
533
|
-
e.preventDefault();
|
|
534
|
-
handleSend();
|
|
535
|
-
}
|
|
536
|
-
};
|
|
700
|
+
const handleSend = React4.useCallback(
|
|
701
|
+
(text) => {
|
|
702
|
+
onSendMessage == null ? void 0 : onSendMessage(text);
|
|
703
|
+
setInputValue("");
|
|
704
|
+
},
|
|
705
|
+
[onSendMessage]
|
|
706
|
+
);
|
|
537
707
|
const handleSuggestionSelect = (text) => {
|
|
538
|
-
var _a2;
|
|
539
708
|
setInputValue(text);
|
|
540
|
-
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
541
709
|
};
|
|
542
|
-
return /* @__PURE__ */ (0,
|
|
710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Sheet, { open, onOpenChange: (o) => !o && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
543
711
|
SheetContent,
|
|
544
712
|
{
|
|
545
713
|
side: "right",
|
|
@@ -547,16 +715,16 @@ function AiAssistantDrawer({
|
|
|
547
715
|
className: cn("w-[480px] max-w-full gap-0 p-0", className),
|
|
548
716
|
"data-slot": "ai-assistant-drawer",
|
|
549
717
|
children: [
|
|
550
|
-
/* @__PURE__ */ (0,
|
|
551
|
-
/* @__PURE__ */ (0,
|
|
552
|
-
/* @__PURE__ */ (0,
|
|
553
|
-
/* @__PURE__ */ (0,
|
|
554
|
-
/* @__PURE__ */ (0,
|
|
555
|
-
opportunityName && /* @__PURE__ */ (0,
|
|
718
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between border-b border-border px-4 py-3", children: [
|
|
719
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
720
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-full bg-primary", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react5.Bot, { className: "size-4 text-primary-foreground" }) }),
|
|
721
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col", children: [
|
|
722
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm font-semibold text-foreground", children: "AI Assistant" }),
|
|
723
|
+
opportunityName && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-xs text-muted-foreground", children: opportunityName })
|
|
556
724
|
] })
|
|
557
725
|
] }),
|
|
558
|
-
/* @__PURE__ */ (0,
|
|
559
|
-
onReset && /* @__PURE__ */ (0,
|
|
726
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
727
|
+
onReset && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
560
728
|
Button,
|
|
561
729
|
{
|
|
562
730
|
variant: "ghost",
|
|
@@ -566,12 +734,12 @@ function AiAssistantDrawer({
|
|
|
566
734
|
title: "Reset conversation",
|
|
567
735
|
disabled: isLoading,
|
|
568
736
|
children: [
|
|
569
|
-
/* @__PURE__ */ (0,
|
|
570
|
-
/* @__PURE__ */ (0,
|
|
737
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react5.RotateCcw, { className: "size-4" }),
|
|
738
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "sr-only", children: "Reset conversation" })
|
|
571
739
|
]
|
|
572
740
|
}
|
|
573
741
|
),
|
|
574
|
-
/* @__PURE__ */ (0,
|
|
742
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
575
743
|
Button,
|
|
576
744
|
{
|
|
577
745
|
variant: "ghost",
|
|
@@ -580,25 +748,25 @@ function AiAssistantDrawer({
|
|
|
580
748
|
onClick: onClose,
|
|
581
749
|
title: "Close",
|
|
582
750
|
children: [
|
|
583
|
-
/* @__PURE__ */ (0,
|
|
584
|
-
/* @__PURE__ */ (0,
|
|
751
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react5.X, { className: "size-4" }),
|
|
752
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "sr-only", children: "Close" })
|
|
585
753
|
]
|
|
586
754
|
}
|
|
587
755
|
)
|
|
588
756
|
] })
|
|
589
757
|
] }),
|
|
590
|
-
/* @__PURE__ */ (0,
|
|
758
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex flex-1 flex-col overflow-y-auto", children: isLoading ? (
|
|
591
759
|
/* Loading state */
|
|
592
|
-
/* @__PURE__ */ (0,
|
|
593
|
-
/* @__PURE__ */ (0,
|
|
594
|
-
/* @__PURE__ */ (0,
|
|
760
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex flex-1 items-center justify-center py-20", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
|
|
761
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Spinner, { size: "lg", className: "text-muted-foreground" }),
|
|
762
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-muted-foreground", children: "Initialising\u2026" })
|
|
595
763
|
] }) })
|
|
596
764
|
) : !hasMessages ? (
|
|
597
765
|
/* Empty / welcome state */
|
|
598
|
-
/* @__PURE__ */ (0,
|
|
599
|
-
/* @__PURE__ */ (0,
|
|
600
|
-
/* @__PURE__ */ (0,
|
|
601
|
-
/* @__PURE__ */ (0,
|
|
766
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-6 p-4", children: [
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-3 border border-border bg-muted/30 p-4", children: [
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Badge, { variant: "outline", className: "w-fit gap-1.5", children: [
|
|
769
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
602
770
|
"span",
|
|
603
771
|
{
|
|
604
772
|
className: "size-1.5 rounded-full bg-primary",
|
|
@@ -607,12 +775,12 @@ function AiAssistantDrawer({
|
|
|
607
775
|
),
|
|
608
776
|
"AI Chat for Brokers"
|
|
609
777
|
] }),
|
|
610
|
-
/* @__PURE__ */ (0,
|
|
611
|
-
/* @__PURE__ */ (0,
|
|
778
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-muted-foreground", children: "A safe and secure way to chat about insights that run your business and utilise AI. All chats stay within your environment, all closed off and compliant." }),
|
|
779
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex gap-2", children: [
|
|
612
780
|
{ emoji: "\u{1F916}", label: "Smart" },
|
|
613
781
|
{ emoji: "\u26A1", label: "Fast" },
|
|
614
782
|
{ emoji: "\u{1F512}", label: "Secure" }
|
|
615
|
-
].map(({ emoji, label }) => /* @__PURE__ */ (0,
|
|
783
|
+
].map(({ emoji, label }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
616
784
|
"span",
|
|
617
785
|
{
|
|
618
786
|
className: "border border-border px-2.5 py-1 text-xs text-foreground",
|
|
@@ -625,9 +793,9 @@ function AiAssistantDrawer({
|
|
|
625
793
|
label
|
|
626
794
|
)) })
|
|
627
795
|
] }),
|
|
628
|
-
suggestions.length > 0 && /* @__PURE__ */ (0,
|
|
629
|
-
/* @__PURE__ */ (0,
|
|
630
|
-
/* @__PURE__ */ (0,
|
|
796
|
+
suggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
797
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-xs font-medium text-muted-foreground", children: "Suggested tasks" }),
|
|
798
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "grid grid-cols-2 gap-2", children: suggestions.map((s) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
631
799
|
AiTaskCard,
|
|
632
800
|
{
|
|
633
801
|
suggestion: s,
|
|
@@ -639,44 +807,24 @@ function AiAssistantDrawer({
|
|
|
639
807
|
] })
|
|
640
808
|
) : (
|
|
641
809
|
/* Message list */
|
|
642
|
-
/* @__PURE__ */ (0,
|
|
643
|
-
messages.map((msg) => /* @__PURE__ */ (0,
|
|
644
|
-
isStreaming && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) === "user" && /* @__PURE__ */ (0,
|
|
645
|
-
/* @__PURE__ */ (0,
|
|
810
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-3 p-4", children: [
|
|
811
|
+
messages.map((msg) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AiChatBubble, { message: msg }, msg.id)),
|
|
812
|
+
isStreaming && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) === "user" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "bg-muted px-3 py-2 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AiTypingIndicator, {}) }) }),
|
|
813
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: messagesEndRef })
|
|
646
814
|
] })
|
|
647
815
|
) }),
|
|
648
|
-
/* @__PURE__ */ (0,
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
className: "min-h-0 flex-1 resize-none overflow-hidden py-2 text-sm"
|
|
661
|
-
}
|
|
662
|
-
),
|
|
663
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
664
|
-
Button,
|
|
665
|
-
{
|
|
666
|
-
size: "icon",
|
|
667
|
-
onClick: handleSend,
|
|
668
|
-
disabled: !canSend,
|
|
669
|
-
className: "shrink-0",
|
|
670
|
-
title: "Send",
|
|
671
|
-
children: [
|
|
672
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react4.Send, { className: "size-4" }),
|
|
673
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sr-only", children: "Send message" })
|
|
674
|
-
]
|
|
675
|
-
}
|
|
676
|
-
)
|
|
677
|
-
] }),
|
|
678
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mt-1.5 text-[10px] text-muted-foreground", children: "Enter to send \xB7 Shift+Enter for new line" })
|
|
679
|
-
] })
|
|
816
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "border-t border-border p-3", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
817
|
+
ChatInputArea,
|
|
818
|
+
{
|
|
819
|
+
value: inputValue,
|
|
820
|
+
onChange: setInputValue,
|
|
821
|
+
onSend: handleSend,
|
|
822
|
+
onAttachFile,
|
|
823
|
+
onAttachImage,
|
|
824
|
+
disabled: isLoading || isStreaming,
|
|
825
|
+
placeholder: "Ask me anything\u2026"
|
|
826
|
+
}
|
|
827
|
+
) })
|
|
680
828
|
]
|
|
681
829
|
}
|
|
682
830
|
) });
|