@aircall/blocks 0.7.0 → 0.9.0
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/globals.css +1 -1
- package/dist/index.d.ts +282 -34
- package/dist/index.js +766 -145
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Badge, Button, CounterBadge, DropdownMenu, DropdownMenuAddon, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Field, FieldDescription, FieldError, FieldLabel, InputGroup, InputGroupButton, InputGroupTextarea, Popover, PopoverContent, PopoverTrigger, Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, SidebarProvider, TabsList, Tooltip, TooltipContent, TooltipTrigger, cn, registerI18nNamespace, useDsTranslation, useSidebar } from "@aircall/ds";
|
|
1
|
+
import { Anchor, Badge, Button, CounterBadge, DropdownMenu, DropdownMenuAddon, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Field, FieldDescription, FieldError, FieldLabel, HoverCard, HoverCardContent, HoverCardTrigger, InputGroup, InputGroupButton, InputGroupTextarea, Item, ItemActions, ItemContent, ItemGroup, ItemMedia, ItemTitle, Popover, PopoverContent, PopoverTrigger, Separator, Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, SidebarProvider, TabsList, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipTrigger, cn, registerI18nNamespace, useDsTranslation, useSidebar } from "@aircall/ds";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { AircallLogo, ArrowUp, Check, ChevronLeft, ChevronRight, Copy, Ellipsis, ExternalLink, FileText, LockKeyhole, MessageSquare, Minus, PanelLeft, PanelLeftClose, PanelLeftOpen, Plus, Search, Settings, Sprout, Square, ThumbsDown, ThumbsDownFilled, ThumbsUp, ThumbsUpFilled, TriangleAlert
|
|
5
|
+
import { AircallLogo, AircallMark, ArrowUp, Check, ChevronDown, ChevronLeft, ChevronRight, Copy, Ellipsis, ExternalLink, FileText, LockKeyhole, Menu, MessageSquare, Minus, PanelLeft, PanelLeftClose, PanelLeftOpen, Plus, Search, Settings, Sprout, Square, SquareArrowOutUpRight, ThumbsDown, ThumbsDownFilled, ThumbsUp, ThumbsUpFilled, TriangleAlert } from "@aircall/react-icons";
|
|
6
6
|
import ReactMarkdown from "react-markdown";
|
|
7
7
|
import remarkGfm from "remark-gfm";
|
|
8
8
|
import { useCallbackRef, useControllableState, useIsMounted, useUnmount } from "@aircall/hooks";
|
|
@@ -28,7 +28,39 @@ const de = {
|
|
|
28
28
|
"chatbotInput.placeholder": "Stellen Sie eine Frage...",
|
|
29
29
|
"chatbotInput.messageLabel": "Nachricht",
|
|
30
30
|
"chatbotInput.stopGenerating": "Generierung stoppen",
|
|
31
|
-
"chatbotInput.sendMessage": "Nachricht senden"
|
|
31
|
+
"chatbotInput.sendMessage": "Nachricht senden",
|
|
32
|
+
"productBadge.beta": "Beta",
|
|
33
|
+
"productBadge.new": "Neu",
|
|
34
|
+
"productBadge.deprecated": "Veraltet",
|
|
35
|
+
"productBadge.trial": "Testversion",
|
|
36
|
+
"productBadge.professional": "Professional",
|
|
37
|
+
"roleBadge.agent": "Agent",
|
|
38
|
+
"roleBadge.supervisor": "Supervisor",
|
|
39
|
+
"roleBadge.admin": "Admin",
|
|
40
|
+
"roleBadge.owner": "Inhaber",
|
|
41
|
+
"chatbotResponse.copy": "Kopieren",
|
|
42
|
+
"chatbotResponse.helpful": "Hilfreich",
|
|
43
|
+
"chatbotResponse.notHelpful": "Nicht hilfreich",
|
|
44
|
+
"chatbotResponse.sourceCount_one": "{{count}} Quelle",
|
|
45
|
+
"chatbotResponse.sourceCount_other": "{{count}} Quellen",
|
|
46
|
+
"chatbotResponse.openSource": "{{title}} öffnen",
|
|
47
|
+
"chatbotPanel.sendFeedback": "Feedback senden",
|
|
48
|
+
"chatbotPanel.collapsePanel": "Panel einklappen",
|
|
49
|
+
"chatbotPanel.expandPanel": "Panel ausklappen",
|
|
50
|
+
"chatbotPanel.closePanel": "Panel schließen",
|
|
51
|
+
"chatbotSidebar.newChat": "Neuer Chat",
|
|
52
|
+
"chatbotSidebar.optionsFor": "Optionen für {{title}}",
|
|
53
|
+
"chatbotPage.footerBeforeLink": "Sie interagieren mit einem KI-Assistenten (Beta). Durch die Nutzung dieser Funktion akzeptieren Sie die ",
|
|
54
|
+
"chatbotPage.betaTermsLink": "Beta-Bedingungen",
|
|
55
|
+
"chatbotPage.footerAfterLink": " von Aircall. Die Antworten können ungenau oder unvollständig sein. Bitte überprüfen Sie diese bevor Sie sich darauf verlassen.",
|
|
56
|
+
"chatbotPage.scrollToBottom": "Nach unten scrollen",
|
|
57
|
+
"chatbotPanel.title": "Aircall fragen",
|
|
58
|
+
"chatbotPanel.emptyTitle": "Brauchen Sie Hilfe mit Aircall?",
|
|
59
|
+
"chatbotPanel.emptyDescription": "Finden Sie Antworten, entdecken Sie Funktionen und erhalten Sie Hilfe beim Verständnis von Aircall",
|
|
60
|
+
"chatbotPanel.disclaimerBefore": "Sie interagieren mit einem KI-Assistenten (Beta). Durch die Nutzung dieser Funktion akzeptieren Sie die ",
|
|
61
|
+
"chatbotPanel.disclaimerLink": "Beta-Bedingungen",
|
|
62
|
+
"chatbotPanel.disclaimerAfter": " von Aircall. Antworten können ungenau oder unvollständig sein. Bitte überprüfen Sie sie, bevor Sie sich darauf verlassen.",
|
|
63
|
+
"chatbotPanel.resizeHandle": "Panel-Größe ändern"
|
|
32
64
|
};
|
|
33
65
|
var de_default = de;
|
|
34
66
|
|
|
@@ -50,7 +82,39 @@ const en = {
|
|
|
50
82
|
"chatbotInput.placeholder": "Ask anything...",
|
|
51
83
|
"chatbotInput.messageLabel": "Message",
|
|
52
84
|
"chatbotInput.stopGenerating": "Stop generating",
|
|
53
|
-
"chatbotInput.sendMessage": "Send message"
|
|
85
|
+
"chatbotInput.sendMessage": "Send message",
|
|
86
|
+
"productBadge.beta": "Beta",
|
|
87
|
+
"productBadge.new": "New",
|
|
88
|
+
"productBadge.deprecated": "Deprecated",
|
|
89
|
+
"productBadge.trial": "Trial",
|
|
90
|
+
"productBadge.professional": "Professional",
|
|
91
|
+
"roleBadge.agent": "Agent",
|
|
92
|
+
"roleBadge.supervisor": "Supervisor",
|
|
93
|
+
"roleBadge.admin": "Admin",
|
|
94
|
+
"roleBadge.owner": "Owner",
|
|
95
|
+
"chatbotResponse.copy": "Copy",
|
|
96
|
+
"chatbotResponse.helpful": "Helpful",
|
|
97
|
+
"chatbotResponse.notHelpful": "Not helpful",
|
|
98
|
+
"chatbotResponse.sourceCount_one": "{{count}} Source",
|
|
99
|
+
"chatbotResponse.sourceCount_other": "{{count}} Sources",
|
|
100
|
+
"chatbotResponse.openSource": "Open {{title}}",
|
|
101
|
+
"chatbotPanel.sendFeedback": "Send feedback",
|
|
102
|
+
"chatbotPanel.collapsePanel": "Collapse panel",
|
|
103
|
+
"chatbotPanel.expandPanel": "Expand panel",
|
|
104
|
+
"chatbotPanel.closePanel": "Close panel",
|
|
105
|
+
"chatbotSidebar.newChat": "New chat",
|
|
106
|
+
"chatbotSidebar.optionsFor": "Options for {{title}}",
|
|
107
|
+
"chatbotPage.footerBeforeLink": "You are interacting with an AI assistant (Beta). By using this feature you accept Aircall's ",
|
|
108
|
+
"chatbotPage.betaTermsLink": "Beta terms",
|
|
109
|
+
"chatbotPage.footerAfterLink": ". Responses may be inaccurate or incomplete. Please verify before relying on them.",
|
|
110
|
+
"chatbotPage.scrollToBottom": "Scroll to bottom",
|
|
111
|
+
"chatbotPanel.title": "Ask Aircall",
|
|
112
|
+
"chatbotPanel.emptyTitle": "Need help with Aircall?",
|
|
113
|
+
"chatbotPanel.emptyDescription": "Find answers, explore features, and get help understanding Aircall",
|
|
114
|
+
"chatbotPanel.disclaimerBefore": "You are interacting with an AI assistant (Beta). By using this feature you accept Aircall's ",
|
|
115
|
+
"chatbotPanel.disclaimerLink": "Beta terms",
|
|
116
|
+
"chatbotPanel.disclaimerAfter": ". Responses may be inaccurate or incomplete. Please verify before relying on them.",
|
|
117
|
+
"chatbotPanel.resizeHandle": "Resize panel"
|
|
54
118
|
};
|
|
55
119
|
var en_default = en;
|
|
56
120
|
|
|
@@ -72,7 +136,39 @@ const es = {
|
|
|
72
136
|
"chatbotInput.placeholder": "Pregunta lo que quieras...",
|
|
73
137
|
"chatbotInput.messageLabel": "Mensaje",
|
|
74
138
|
"chatbotInput.stopGenerating": "Detener la generación",
|
|
75
|
-
"chatbotInput.sendMessage": "Enviar mensaje"
|
|
139
|
+
"chatbotInput.sendMessage": "Enviar mensaje",
|
|
140
|
+
"productBadge.beta": "Beta",
|
|
141
|
+
"productBadge.new": "Nuevo",
|
|
142
|
+
"productBadge.deprecated": "Obsoleto",
|
|
143
|
+
"productBadge.trial": "Prueba",
|
|
144
|
+
"productBadge.professional": "Profesional",
|
|
145
|
+
"roleBadge.agent": "Agente",
|
|
146
|
+
"roleBadge.supervisor": "Supervisor",
|
|
147
|
+
"roleBadge.admin": "Administrador",
|
|
148
|
+
"roleBadge.owner": "Propietario",
|
|
149
|
+
"chatbotResponse.copy": "Copiar",
|
|
150
|
+
"chatbotResponse.helpful": "Útil",
|
|
151
|
+
"chatbotResponse.notHelpful": "No útil",
|
|
152
|
+
"chatbotResponse.sourceCount_one": "{{count}} Fuente",
|
|
153
|
+
"chatbotResponse.sourceCount_other": "{{count}} Fuentes",
|
|
154
|
+
"chatbotResponse.openSource": "Abrir {{title}}",
|
|
155
|
+
"chatbotPanel.sendFeedback": "Enviar comentarios",
|
|
156
|
+
"chatbotPanel.collapsePanel": "Contraer panel",
|
|
157
|
+
"chatbotPanel.expandPanel": "Expandir panel",
|
|
158
|
+
"chatbotPanel.closePanel": "Cerrar panel",
|
|
159
|
+
"chatbotSidebar.newChat": "Nueva conversación",
|
|
160
|
+
"chatbotSidebar.optionsFor": "Opciones para {{title}}",
|
|
161
|
+
"chatbotPage.footerBeforeLink": "Estás interactuando con un asistente de IA (Beta). Al usar esta función, aceptas los ",
|
|
162
|
+
"chatbotPage.betaTermsLink": "términos Beta",
|
|
163
|
+
"chatbotPage.footerAfterLink": " de Aircall. Las respuestas pueden ser inexactas o incompletas. Por favor verifica antes de confiar en ellas.",
|
|
164
|
+
"chatbotPage.scrollToBottom": "Desplazarse hacia abajo",
|
|
165
|
+
"chatbotPanel.title": "Preguntar a Aircall",
|
|
166
|
+
"chatbotPanel.emptyTitle": "¿Necesitas ayuda con Aircall?",
|
|
167
|
+
"chatbotPanel.emptyDescription": "Encuentra respuestas, explora funciones y obtén ayuda para entender Aircall",
|
|
168
|
+
"chatbotPanel.disclaimerBefore": "Estás interactuando con un asistente de IA (Beta). Al usar esta función, aceptas los ",
|
|
169
|
+
"chatbotPanel.disclaimerLink": "términos de la Beta",
|
|
170
|
+
"chatbotPanel.disclaimerAfter": " de Aircall. Las respuestas pueden ser inexactas o incompletas. Verifícalas antes de confiar en ellas.",
|
|
171
|
+
"chatbotPanel.resizeHandle": "Redimensionar el panel"
|
|
76
172
|
};
|
|
77
173
|
var es_default = es;
|
|
78
174
|
|
|
@@ -94,7 +190,39 @@ const fr = {
|
|
|
94
190
|
"chatbotInput.placeholder": "Posez votre question...",
|
|
95
191
|
"chatbotInput.messageLabel": "Message",
|
|
96
192
|
"chatbotInput.stopGenerating": "Arrêter la génération",
|
|
97
|
-
"chatbotInput.sendMessage": "Envoyer un message"
|
|
193
|
+
"chatbotInput.sendMessage": "Envoyer un message",
|
|
194
|
+
"productBadge.beta": "Bêta",
|
|
195
|
+
"productBadge.new": "Nouveau",
|
|
196
|
+
"productBadge.deprecated": "Obsolète",
|
|
197
|
+
"productBadge.trial": "Essai",
|
|
198
|
+
"productBadge.professional": "Professionnel",
|
|
199
|
+
"roleBadge.agent": "Agent",
|
|
200
|
+
"roleBadge.supervisor": "Superviseur",
|
|
201
|
+
"roleBadge.admin": "Admin",
|
|
202
|
+
"roleBadge.owner": "Propriétaire",
|
|
203
|
+
"chatbotResponse.copy": "Copier",
|
|
204
|
+
"chatbotResponse.helpful": "Utile",
|
|
205
|
+
"chatbotResponse.notHelpful": "Pas utile",
|
|
206
|
+
"chatbotResponse.sourceCount_one": "{{count}} Source",
|
|
207
|
+
"chatbotResponse.sourceCount_other": "{{count}} Sources",
|
|
208
|
+
"chatbotResponse.openSource": "Ouvrir {{title}}",
|
|
209
|
+
"chatbotPanel.sendFeedback": "Envoyer un commentaire",
|
|
210
|
+
"chatbotPanel.collapsePanel": "Réduire le panneau",
|
|
211
|
+
"chatbotPanel.expandPanel": "Développer le panneau",
|
|
212
|
+
"chatbotPanel.closePanel": "Fermer le panneau",
|
|
213
|
+
"chatbotSidebar.newChat": "Nouvelle conversation",
|
|
214
|
+
"chatbotSidebar.optionsFor": "Options pour {{title}}",
|
|
215
|
+
"chatbotPage.footerBeforeLink": "Vous interagissez avec un assistant IA (Bêta). En utilisant cette fonctionnalité, vous acceptez les ",
|
|
216
|
+
"chatbotPage.betaTermsLink": "conditions Bêta",
|
|
217
|
+
"chatbotPage.footerAfterLink": " d'Aircall. Les réponses peuvent être inexactes ou incomplètes. Veuillez vérifier avant de vous y fier.",
|
|
218
|
+
"chatbotPage.scrollToBottom": "Défiler vers le bas",
|
|
219
|
+
"chatbotPanel.title": "Demander à Aircall",
|
|
220
|
+
"chatbotPanel.emptyTitle": "Besoin d'aide avec Aircall ?",
|
|
221
|
+
"chatbotPanel.emptyDescription": "Trouvez des réponses, explorez les fonctionnalités et obtenez de l’aide pour comprendre Aircall",
|
|
222
|
+
"chatbotPanel.disclaimerBefore": "Vous interagissez avec un assistant IA (bêta). En utilisant cette fonctionnalité, vous acceptez les ",
|
|
223
|
+
"chatbotPanel.disclaimerLink": "conditions de la bêta",
|
|
224
|
+
"chatbotPanel.disclaimerAfter": " d’Aircall. Les réponses peuvent être inexactes ou incomplètes. Veuillez les vérifier avant de vous y fier.",
|
|
225
|
+
"chatbotPanel.resizeHandle": "Redimensionner le panneau"
|
|
98
226
|
};
|
|
99
227
|
var fr_default = fr;
|
|
100
228
|
|
|
@@ -116,7 +244,39 @@ const it = {
|
|
|
116
244
|
"chatbotInput.placeholder": "Chiedi qualsiasi cosa...",
|
|
117
245
|
"chatbotInput.messageLabel": "Messaggio",
|
|
118
246
|
"chatbotInput.stopGenerating": "Interrompi la generazione",
|
|
119
|
-
"chatbotInput.sendMessage": "Invia messaggio"
|
|
247
|
+
"chatbotInput.sendMessage": "Invia messaggio",
|
|
248
|
+
"productBadge.beta": "Beta",
|
|
249
|
+
"productBadge.new": "Nuovo",
|
|
250
|
+
"productBadge.deprecated": "Obsoleto",
|
|
251
|
+
"productBadge.trial": "Prova",
|
|
252
|
+
"productBadge.professional": "Professional",
|
|
253
|
+
"roleBadge.agent": "Agente",
|
|
254
|
+
"roleBadge.supervisor": "Supervisore",
|
|
255
|
+
"roleBadge.admin": "Admin",
|
|
256
|
+
"roleBadge.owner": "Proprietario",
|
|
257
|
+
"chatbotResponse.copy": "Copia",
|
|
258
|
+
"chatbotResponse.helpful": "Utile",
|
|
259
|
+
"chatbotResponse.notHelpful": "Non utile",
|
|
260
|
+
"chatbotResponse.sourceCount_one": "{{count}} Fonte",
|
|
261
|
+
"chatbotResponse.sourceCount_other": "{{count}} Fonti",
|
|
262
|
+
"chatbotResponse.openSource": "Apri {{title}}",
|
|
263
|
+
"chatbotPanel.sendFeedback": "Invia feedback",
|
|
264
|
+
"chatbotPanel.collapsePanel": "Comprimi pannello",
|
|
265
|
+
"chatbotPanel.expandPanel": "Espandi pannello",
|
|
266
|
+
"chatbotPanel.closePanel": "Chiudi pannello",
|
|
267
|
+
"chatbotSidebar.newChat": "Nuova chat",
|
|
268
|
+
"chatbotSidebar.optionsFor": "Opzioni per {{title}}",
|
|
269
|
+
"chatbotPage.footerBeforeLink": "Stai interagendo con un assistente IA (Beta). Usando questa funzione, accetti i ",
|
|
270
|
+
"chatbotPage.betaTermsLink": "termini Beta",
|
|
271
|
+
"chatbotPage.footerAfterLink": " di Aircall. Le risposte potrebbero essere inesatte o incomplete. Si prega di verificare prima di affidarsi ad esse.",
|
|
272
|
+
"chatbotPage.scrollToBottom": "Scorri verso il basso",
|
|
273
|
+
"chatbotPanel.title": "Chiedi ad Aircall",
|
|
274
|
+
"chatbotPanel.emptyTitle": "Hai bisogno di aiuto con Aircall?",
|
|
275
|
+
"chatbotPanel.emptyDescription": "Trova risposte, esplora le funzionalità e ottieni aiuto per comprendere Aircall",
|
|
276
|
+
"chatbotPanel.disclaimerBefore": "Stai interagendo con un assistente IA (Beta). Utilizzando questa funzionalità accetti i ",
|
|
277
|
+
"chatbotPanel.disclaimerLink": "termini della Beta",
|
|
278
|
+
"chatbotPanel.disclaimerAfter": " di Aircall. Le risposte possono essere inesatte o incomplete. Verificale prima di farne affidamento.",
|
|
279
|
+
"chatbotPanel.resizeHandle": "Ridimensiona il pannello"
|
|
120
280
|
};
|
|
121
281
|
var it_default = it;
|
|
122
282
|
|
|
@@ -458,76 +618,41 @@ CopyButtonLabel.displayName = "CopyButtonLabel";
|
|
|
458
618
|
//#endregion
|
|
459
619
|
//#region src/components/chatbot-response-block.tsx
|
|
460
620
|
function SourcesBadge({ sources }) {
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
className: "cursor-default rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
491
|
-
onPointerEnter: handlePointerEnter,
|
|
492
|
-
onPointerLeave: handlePointerLeave,
|
|
493
|
-
children: /* @__PURE__ */ jsx(Badge, {
|
|
494
|
-
className: "!rounded-full !bg-charcoal-400/20",
|
|
495
|
-
children: `${sources.length} ${sources.length === 1 ? "Source" : "Sources"}`
|
|
496
|
-
})
|
|
497
|
-
}), /* @__PURE__ */ jsx(PopoverContent, {
|
|
498
|
-
side: "top",
|
|
499
|
-
align: "start",
|
|
500
|
-
sideOffset: 8,
|
|
501
|
-
className: "w-80",
|
|
502
|
-
onPointerEnter: handlePointerEnter,
|
|
503
|
-
onPointerLeave: handlePointerLeave,
|
|
504
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
505
|
-
role: "list",
|
|
506
|
-
className: "flex flex-col",
|
|
507
|
-
children: sources.map((source) => /* @__PURE__ */ jsxs("div", {
|
|
508
|
-
role: "listitem",
|
|
509
|
-
className: "flex items-center gap-2 px-2 py-2",
|
|
510
|
-
children: [
|
|
511
|
-
/* @__PURE__ */ jsx(FileText, { className: "size-3.5 shrink-0 text-foreground" }),
|
|
512
|
-
/* @__PURE__ */ jsx("span", {
|
|
513
|
-
className: "min-w-0 flex-1 line-clamp-2 text-sm",
|
|
514
|
-
children: source.title
|
|
515
|
-
}),
|
|
516
|
-
/* @__PURE__ */ jsx("a", {
|
|
517
|
-
href: source.url,
|
|
518
|
-
target: "_blank",
|
|
519
|
-
rel: "noreferrer",
|
|
520
|
-
"aria-label": `Open ${source.title}`,
|
|
521
|
-
className: "shrink-0 text-foreground hover:text-primary",
|
|
522
|
-
children: /* @__PURE__ */ jsx(ExternalLink, { className: "size-3.5" })
|
|
523
|
-
})
|
|
524
|
-
]
|
|
525
|
-
}, source.url))
|
|
621
|
+
const t = useDsTranslation("blocks");
|
|
622
|
+
return /* @__PURE__ */ jsxs(HoverCard, { children: [/* @__PURE__ */ jsx(HoverCardTrigger, {
|
|
623
|
+
render: /* @__PURE__ */ jsx(Button, {
|
|
624
|
+
variant: "secondary",
|
|
625
|
+
size: "sm"
|
|
626
|
+
}),
|
|
627
|
+
children: t("chatbotResponse.sourceCount", { count: sources.length })
|
|
628
|
+
}), /* @__PURE__ */ jsx(HoverCardContent, {
|
|
629
|
+
side: "top",
|
|
630
|
+
align: "start",
|
|
631
|
+
className: "w-80 p-1",
|
|
632
|
+
children: /* @__PURE__ */ jsx(ItemGroup, { children: sources.map((source) => /* @__PURE__ */ jsx("div", {
|
|
633
|
+
role: "listitem",
|
|
634
|
+
children: /* @__PURE__ */ jsxs(Item, {
|
|
635
|
+
size: "xs",
|
|
636
|
+
render: /* @__PURE__ */ jsx("a", {
|
|
637
|
+
href: source.url,
|
|
638
|
+
target: "_blank",
|
|
639
|
+
rel: "noreferrer noopener",
|
|
640
|
+
"aria-label": t("chatbotResponse.openSource", { title: source.title })
|
|
641
|
+
}),
|
|
642
|
+
children: [
|
|
643
|
+
/* @__PURE__ */ jsx(ItemMedia, {
|
|
644
|
+
variant: "icon",
|
|
645
|
+
children: /* @__PURE__ */ jsx(FileText, {})
|
|
646
|
+
}),
|
|
647
|
+
/* @__PURE__ */ jsx(ItemContent, { children: /* @__PURE__ */ jsx(ItemTitle, { children: source.title }) }),
|
|
648
|
+
/* @__PURE__ */ jsx(ItemActions, { children: /* @__PURE__ */ jsx(ExternalLink, { className: "size-4" }) })
|
|
649
|
+
]
|
|
526
650
|
})
|
|
527
|
-
})
|
|
528
|
-
});
|
|
651
|
+
}, source.url)) })
|
|
652
|
+
})] });
|
|
529
653
|
}
|
|
530
654
|
function ChatbotResponseBlock({ messageId, markdown, streaming = false, sources, onFeedback, className }) {
|
|
655
|
+
const t = useDsTranslation("blocks");
|
|
531
656
|
const [feedback, setFeedback] = useState(null);
|
|
532
657
|
const onFeedbackRef = useCallbackRef(onFeedback);
|
|
533
658
|
const isMounted = useRef(false);
|
|
@@ -628,7 +753,7 @@ function ChatbotResponseBlock({ messageId, markdown, streaming = false, sources,
|
|
|
628
753
|
value: markdown,
|
|
629
754
|
variant: "ghost",
|
|
630
755
|
size: "icon-sm",
|
|
631
|
-
"aria-label": "
|
|
756
|
+
"aria-label": t("chatbotResponse.copy"),
|
|
632
757
|
children: /* @__PURE__ */ jsx(CopyButtonIcon, {})
|
|
633
758
|
}),
|
|
634
759
|
/* @__PURE__ */ jsx(Button, {
|
|
@@ -636,7 +761,7 @@ function ChatbotResponseBlock({ messageId, markdown, streaming = false, sources,
|
|
|
636
761
|
variant: "ghost",
|
|
637
762
|
size: "icon-sm",
|
|
638
763
|
"aria-pressed": feedback === "up",
|
|
639
|
-
"aria-label": "
|
|
764
|
+
"aria-label": t("chatbotResponse.helpful"),
|
|
640
765
|
onClick: () => handleFeedback("up"),
|
|
641
766
|
className: cn(feedback === "up" && "text-primary"),
|
|
642
767
|
children: feedback === "up" ? /* @__PURE__ */ jsx(ThumbsUpFilled, {}) : /* @__PURE__ */ jsx(ThumbsUp, {})
|
|
@@ -646,7 +771,7 @@ function ChatbotResponseBlock({ messageId, markdown, streaming = false, sources,
|
|
|
646
771
|
variant: "ghost",
|
|
647
772
|
size: "icon-sm",
|
|
648
773
|
"aria-pressed": feedback === "down",
|
|
649
|
-
"aria-label": "
|
|
774
|
+
"aria-label": t("chatbotResponse.notHelpful"),
|
|
650
775
|
onClick: () => handleFeedback("down"),
|
|
651
776
|
className: cn(feedback === "down" && "text-primary"),
|
|
652
777
|
children: feedback === "down" ? /* @__PURE__ */ jsx(ThumbsDownFilled, {}) : /* @__PURE__ */ jsx(ThumbsDown, {})
|
|
@@ -669,23 +794,237 @@ const ChatbotPage = React.forwardRef((componentProps, forwardRef) => {
|
|
|
669
794
|
});
|
|
670
795
|
});
|
|
671
796
|
ChatbotPage.displayName = "ChatbotPage";
|
|
797
|
+
/**
|
|
798
|
+
* Content area that fills the right side of `ChatbotPage`. Use alongside
|
|
799
|
+
* `ChatbotSidebar` as a direct child of `ChatbotPage`.
|
|
800
|
+
*
|
|
801
|
+
* In the **idle state** place `ChatbotPageBody`, then `ChatbotPageFooter`.
|
|
802
|
+
* In the **active conversation state** place `ChatbotPageConversation`,
|
|
803
|
+
* `ChatbotPageInputBar`, then `ChatbotPageFooter`.
|
|
804
|
+
*
|
|
805
|
+
* @example
|
|
806
|
+
* ```tsx
|
|
807
|
+
* <ChatbotPage>
|
|
808
|
+
* <ChatbotSidebar conversations={[...]} />
|
|
809
|
+
* <ChatbotPageContent>
|
|
810
|
+
* <ChatbotPageBody>
|
|
811
|
+
* <ChatbotPageHeading>Need help with Aircall?</ChatbotPageHeading>
|
|
812
|
+
* <ChatbotInput />
|
|
813
|
+
* <ChatbotExpandSuggestion categories={[...]} suggestions={[...]} />
|
|
814
|
+
* </ChatbotPageBody>
|
|
815
|
+
* <ChatbotPageFooter betaTermsHref="https://legal.aircall.io/..." />
|
|
816
|
+
* </ChatbotPageContent>
|
|
817
|
+
* </ChatbotPage>
|
|
818
|
+
* ```
|
|
819
|
+
*/
|
|
820
|
+
const ChatbotPageContent = React.forwardRef((componentProps, forwardRef) => {
|
|
821
|
+
const { className, ...props } = componentProps;
|
|
822
|
+
return /* @__PURE__ */ jsx("div", {
|
|
823
|
+
ref: forwardRef,
|
|
824
|
+
"data-slot": "chatbot-page-content",
|
|
825
|
+
className: cn("flex flex-1 flex-col items-center bg-background px-4", className),
|
|
826
|
+
...props
|
|
827
|
+
});
|
|
828
|
+
});
|
|
829
|
+
ChatbotPageContent.displayName = "ChatbotPageContent";
|
|
830
|
+
/**
|
|
831
|
+
* Centered content area for the idle/empty state inside `ChatbotPageContent`.
|
|
832
|
+
* Constrains children to a max-width of 896px and vertically centers them.
|
|
833
|
+
* Place `ChatbotPageHeading`, `ChatbotInput`, and `ChatbotExpandSuggestion`
|
|
834
|
+
* as children.
|
|
835
|
+
*/
|
|
836
|
+
const ChatbotPageBody = React.forwardRef((componentProps, forwardRef) => {
|
|
837
|
+
const { className, ...props } = componentProps;
|
|
838
|
+
return /* @__PURE__ */ jsx("div", {
|
|
839
|
+
ref: forwardRef,
|
|
840
|
+
"data-slot": "chatbot-page-body",
|
|
841
|
+
className: cn("relative z-[2] flex w-full max-w-[896px] flex-1 flex-col items-center justify-center gap-6", className),
|
|
842
|
+
...props
|
|
843
|
+
});
|
|
844
|
+
});
|
|
845
|
+
ChatbotPageBody.displayName = "ChatbotPageBody";
|
|
846
|
+
/**
|
|
847
|
+
* Centered heading displayed above the input area in the idle state.
|
|
848
|
+
* Renders an `<h2>` element styled at 24px / medium weight.
|
|
849
|
+
*
|
|
850
|
+
* @example
|
|
851
|
+
* ```tsx
|
|
852
|
+
* <ChatbotPageHeading>Need help with Aircall?</ChatbotPageHeading>
|
|
853
|
+
* ```
|
|
854
|
+
*/
|
|
855
|
+
const ChatbotPageHeading = React.forwardRef((componentProps, forwardRef) => {
|
|
856
|
+
const { className, ...props } = componentProps;
|
|
857
|
+
return /* @__PURE__ */ jsx("h2", {
|
|
858
|
+
ref: forwardRef,
|
|
859
|
+
"data-slot": "chatbot-page-heading",
|
|
860
|
+
className: cn("min-w-full text-center text-2xl font-medium text-foreground", className),
|
|
861
|
+
...props
|
|
862
|
+
});
|
|
863
|
+
});
|
|
864
|
+
ChatbotPageHeading.displayName = "ChatbotPageHeading";
|
|
865
|
+
/**
|
|
866
|
+
* Footer bar showing the AI beta disclaimer. The "Beta terms" phrase is
|
|
867
|
+
* rendered as an external `Anchor` link pointing to `betaTermsHref`.
|
|
868
|
+
*
|
|
869
|
+
* @example
|
|
870
|
+
* ```tsx
|
|
871
|
+
* <ChatbotPageFooter betaTermsHref="https://legal.aircall.io/#template-9jw4r0usl" />
|
|
872
|
+
* ```
|
|
873
|
+
*/
|
|
874
|
+
const ChatbotPageFooter = React.forwardRef((componentProps, forwardRef) => {
|
|
875
|
+
const { className, betaTermsHref, ...props } = componentProps;
|
|
876
|
+
const t = useDsTranslation("blocks");
|
|
877
|
+
return /* @__PURE__ */ jsx("div", {
|
|
878
|
+
ref: forwardRef,
|
|
879
|
+
"data-slot": "chatbot-page-footer",
|
|
880
|
+
className: cn("relative z-[1] flex w-full shrink-0 flex-col items-center justify-center pb-4", className),
|
|
881
|
+
...props,
|
|
882
|
+
children: /* @__PURE__ */ jsxs("p", {
|
|
883
|
+
className: "text-center text-xs text-muted-foreground",
|
|
884
|
+
children: [
|
|
885
|
+
t("chatbotPage.footerBeforeLink"),
|
|
886
|
+
/* @__PURE__ */ jsx(Anchor, {
|
|
887
|
+
href: betaTermsHref,
|
|
888
|
+
target: "_blank",
|
|
889
|
+
rel: "noopener noreferrer",
|
|
890
|
+
children: t("chatbotPage.betaTermsLink")
|
|
891
|
+
}),
|
|
892
|
+
t("chatbotPage.footerAfterLink")
|
|
893
|
+
]
|
|
894
|
+
})
|
|
895
|
+
});
|
|
896
|
+
});
|
|
897
|
+
ChatbotPageFooter.displayName = "ChatbotPageFooter";
|
|
898
|
+
/**
|
|
899
|
+
* Scrollable conversation thread for the active chatbot state. Place
|
|
900
|
+
* `ChatbotUserMessage` and `ChatbotResponseBlock` as alternating children.
|
|
901
|
+
* Use alongside `ChatbotPageInputBar` and `ChatbotPageFooter` inside
|
|
902
|
+
* `ChatbotPageContent`.
|
|
903
|
+
*
|
|
904
|
+
* The component is `relative` so consumers can absolutely-position a
|
|
905
|
+
* scroll-to-bottom FAB inside it.
|
|
906
|
+
*
|
|
907
|
+
* @example
|
|
908
|
+
* ```tsx
|
|
909
|
+
* <ChatbotPageContent>
|
|
910
|
+
* <ChatbotPageConversation>
|
|
911
|
+
* <ChatbotUserMessage>How do I set my phone line?</ChatbotUserMessage>
|
|
912
|
+
* <ChatbotResponseBlock messageId="1" markdown="..." />
|
|
913
|
+
* </ChatbotPageConversation>
|
|
914
|
+
* <ChatbotPageInputBar>
|
|
915
|
+
* <ChatbotInput size="large" />
|
|
916
|
+
* </ChatbotPageInputBar>
|
|
917
|
+
* <ChatbotPageFooter betaTermsHref="https://legal.aircall.io/..." />
|
|
918
|
+
* </ChatbotPageContent>
|
|
919
|
+
* ```
|
|
920
|
+
*/
|
|
921
|
+
const ChatbotPageConversation = React.forwardRef((componentProps, forwardRef) => {
|
|
922
|
+
const { className, children, ...props } = componentProps;
|
|
923
|
+
const innerRef = React.useRef(null);
|
|
924
|
+
const [atBottom, setAtBottom] = React.useState(true);
|
|
925
|
+
const t = useDsTranslation("blocks");
|
|
926
|
+
const handleScroll = React.useCallback(() => {
|
|
927
|
+
const el = innerRef.current;
|
|
928
|
+
if (!el) return;
|
|
929
|
+
setAtBottom(el.scrollHeight - el.scrollTop - el.clientHeight < 8);
|
|
930
|
+
}, []);
|
|
931
|
+
React.useEffect(() => {
|
|
932
|
+
const el = innerRef.current;
|
|
933
|
+
if (!el) return;
|
|
934
|
+
el.addEventListener("scroll", handleScroll, { passive: true });
|
|
935
|
+
return () => el.removeEventListener("scroll", handleScroll);
|
|
936
|
+
}, [handleScroll]);
|
|
937
|
+
const scrollToBottom = React.useCallback(() => {
|
|
938
|
+
innerRef.current?.scrollTo({
|
|
939
|
+
top: innerRef.current.scrollHeight,
|
|
940
|
+
behavior: "smooth"
|
|
941
|
+
});
|
|
942
|
+
}, []);
|
|
943
|
+
const mergedRef = React.useCallback((node) => {
|
|
944
|
+
innerRef.current = node;
|
|
945
|
+
if (typeof forwardRef === "function") forwardRef(node);
|
|
946
|
+
else if (forwardRef) forwardRef.current = node;
|
|
947
|
+
}, [forwardRef]);
|
|
948
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
949
|
+
"data-slot": "chatbot-page-conversation",
|
|
950
|
+
className: cn("relative z-[2] flex flex-col overflow-hidden w-full max-w-[896px] flex-1", className),
|
|
951
|
+
...props,
|
|
952
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
953
|
+
ref: mergedRef,
|
|
954
|
+
className: cn("flex flex-1 flex-col gap-6 overflow-y-auto px-6 py-4", "[scrollbar-width:thin] [scrollbar-color:transparent_transparent] hover:[scrollbar-color:rgba(0,0,0,0.15)_transparent]", "[&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-transparent [&:hover::-webkit-scrollbar-thumb]:bg-black/20"),
|
|
955
|
+
children
|
|
956
|
+
}), !atBottom && /* @__PURE__ */ jsx("div", {
|
|
957
|
+
className: "absolute bottom-4 right-6 z-10",
|
|
958
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
959
|
+
variant: "outline",
|
|
960
|
+
size: "icon-lg",
|
|
961
|
+
className: "shadow-lg",
|
|
962
|
+
"aria-label": t("chatbotPage.scrollToBottom"),
|
|
963
|
+
onClick: scrollToBottom,
|
|
964
|
+
children: /* @__PURE__ */ jsx(ChevronDown, {})
|
|
965
|
+
})
|
|
966
|
+
})]
|
|
967
|
+
});
|
|
968
|
+
});
|
|
969
|
+
ChatbotPageConversation.displayName = "ChatbotPageConversation";
|
|
970
|
+
/**
|
|
971
|
+
* Wrapper that anchors `ChatbotInput` to the bottom of `ChatbotPageContent`
|
|
972
|
+
* at the correct max-width. Place between `ChatbotPageConversation` and
|
|
973
|
+
* `ChatbotPageFooter`.
|
|
974
|
+
*
|
|
975
|
+
* @example
|
|
976
|
+
* ```tsx
|
|
977
|
+
* <ChatbotPageInputBar>
|
|
978
|
+
* <ChatbotInput size="large" />
|
|
979
|
+
* </ChatbotPageInputBar>
|
|
980
|
+
* ```
|
|
981
|
+
*/
|
|
982
|
+
const ChatbotPageInputBar = React.forwardRef((componentProps, forwardRef) => {
|
|
983
|
+
const { className, ...props } = componentProps;
|
|
984
|
+
return /* @__PURE__ */ jsx("div", {
|
|
985
|
+
ref: forwardRef,
|
|
986
|
+
"data-slot": "chatbot-page-input-bar",
|
|
987
|
+
className: cn("relative z-[1] flex w-full max-w-[896px] shrink-0 flex-col pb-4", className),
|
|
988
|
+
...props
|
|
989
|
+
});
|
|
990
|
+
});
|
|
991
|
+
ChatbotPageInputBar.displayName = "ChatbotPageInputBar";
|
|
672
992
|
|
|
673
993
|
//#endregion
|
|
674
994
|
//#region src/components/chatbot-panel-header.tsx
|
|
675
995
|
/**
|
|
676
|
-
* Header bar for the chatbot panel.
|
|
677
|
-
*
|
|
678
|
-
*
|
|
679
|
-
*
|
|
996
|
+
* Header bar for the chatbot panel. Each control renders only when its handler is
|
|
997
|
+
* provided. The leading ☰ opens a Popover (conversation history) when
|
|
998
|
+
* `menuContent` is set, otherwise fires `onMenu`; with no menu handler it falls
|
|
999
|
+
* back to a non-interactive panel indicator. Title is optional — pass an empty
|
|
1000
|
+
* string to hide it.
|
|
680
1001
|
*/
|
|
681
|
-
function ChatbotPanelHeader({ title = "Ask Aircall",
|
|
1002
|
+
function ChatbotPanelHeader({ title = "Ask Aircall", onMenu, menuContent, menuOpen, onMenuOpenChange, onFeedback, onExpand, open = false, onOpenChange, onClose, className, ...props }) {
|
|
1003
|
+
const t = useDsTranslation("blocks");
|
|
1004
|
+
const menuButton = /* @__PURE__ */ jsx(Button, {
|
|
1005
|
+
variant: "ghost",
|
|
1006
|
+
size: "icon",
|
|
1007
|
+
"aria-label": "Open menu",
|
|
1008
|
+
onClick: onMenu,
|
|
1009
|
+
children: /* @__PURE__ */ jsx(Menu, { className: "size-4" })
|
|
1010
|
+
});
|
|
682
1011
|
return /* @__PURE__ */ jsxs("div", {
|
|
683
1012
|
"data-slot": "chatbot-panel-header",
|
|
684
1013
|
"data-state": open ? "open" : "closed",
|
|
685
1014
|
className: cn("flex w-full items-center gap-2 border-b border-border bg-background p-2", className),
|
|
686
1015
|
...props,
|
|
687
1016
|
children: [
|
|
688
|
-
/* @__PURE__ */
|
|
1017
|
+
menuContent != null ? /* @__PURE__ */ jsxs(Popover, {
|
|
1018
|
+
open: menuOpen,
|
|
1019
|
+
onOpenChange: onMenuOpenChange,
|
|
1020
|
+
children: [/* @__PURE__ */ jsx(PopoverTrigger, { render: menuButton }), /* @__PURE__ */ jsx(PopoverContent, {
|
|
1021
|
+
align: "start",
|
|
1022
|
+
alignOffset: 6,
|
|
1023
|
+
sideOffset: 4,
|
|
1024
|
+
className: "h-[404px] w-80 gap-0 p-0",
|
|
1025
|
+
children: menuContent
|
|
1026
|
+
})]
|
|
1027
|
+
}) : onMenu != null ? menuButton : /* @__PURE__ */ jsx("span", {
|
|
689
1028
|
"aria-hidden": "true",
|
|
690
1029
|
className: "flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground",
|
|
691
1030
|
children: /* @__PURE__ */ jsx(PanelLeft, { className: "size-4" })
|
|
@@ -697,23 +1036,30 @@ function ChatbotPanelHeader({ title = "Ask Aircall", open, onOpenChange, onFeedb
|
|
|
697
1036
|
onFeedback != null && /* @__PURE__ */ jsx(Button, {
|
|
698
1037
|
variant: "ghost",
|
|
699
1038
|
size: "icon",
|
|
700
|
-
"aria-label": "
|
|
1039
|
+
"aria-label": t("chatbotPanel.sendFeedback"),
|
|
701
1040
|
onClick: onFeedback,
|
|
702
1041
|
children: /* @__PURE__ */ jsx(MessageSquare, { className: "size-4" })
|
|
703
1042
|
}),
|
|
704
|
-
/* @__PURE__ */ jsx(Button, {
|
|
1043
|
+
onExpand != null && /* @__PURE__ */ jsx(Button, {
|
|
1044
|
+
variant: "ghost",
|
|
1045
|
+
size: "icon",
|
|
1046
|
+
"aria-label": "Expand to fullscreen",
|
|
1047
|
+
onClick: onExpand,
|
|
1048
|
+
children: /* @__PURE__ */ jsx(SquareArrowOutUpRight, { className: "size-4" })
|
|
1049
|
+
}),
|
|
1050
|
+
onOpenChange != null && /* @__PURE__ */ jsx(Button, {
|
|
705
1051
|
variant: "ghost",
|
|
706
1052
|
size: "icon",
|
|
707
|
-
"aria-label": open ? "
|
|
1053
|
+
"aria-label": open ? t("chatbotPanel.collapsePanel") : t("chatbotPanel.expandPanel"),
|
|
708
1054
|
onClick: () => onOpenChange(!open),
|
|
709
1055
|
children: open ? /* @__PURE__ */ jsx(Minus, { className: "size-4" }) : /* @__PURE__ */ jsx(Plus, { className: "size-4" })
|
|
710
1056
|
}),
|
|
711
1057
|
onClose != null && /* @__PURE__ */ jsx(Button, {
|
|
712
1058
|
variant: "ghost",
|
|
713
1059
|
size: "icon",
|
|
714
|
-
"aria-label": "
|
|
1060
|
+
"aria-label": t("chatbotPanel.closePanel"),
|
|
715
1061
|
onClick: onClose,
|
|
716
|
-
children: /* @__PURE__ */ jsx(
|
|
1062
|
+
children: /* @__PURE__ */ jsx(Minus, { className: "size-4" })
|
|
717
1063
|
})
|
|
718
1064
|
]
|
|
719
1065
|
});
|
|
@@ -722,45 +1068,52 @@ function ChatbotPanelHeader({ title = "Ask Aircall", open, onOpenChange, onFeedb
|
|
|
722
1068
|
//#endregion
|
|
723
1069
|
//#region src/components/chatbot-sidebar.tsx
|
|
724
1070
|
const ChatbotSidebar = React.forwardRef((componentProps, forwardRef) => {
|
|
725
|
-
const { conversations, activeConversationId, onNewChat, onSelectConversation, renderConversationMenuContent, recentLabel = "Recent", className } = componentProps;
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
children:
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
const isActive = conversation.id === activeConversationId;
|
|
736
|
-
return /* @__PURE__ */ jsx(SidebarMenuItem, { children: renderConversationMenuContent ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
737
|
-
/* @__PURE__ */ jsx(SidebarMenuButton, {
|
|
738
|
-
isActive,
|
|
739
|
-
onClick: () => onSelectConversation?.(conversation.id),
|
|
740
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
741
|
-
className: "min-w-0 truncate",
|
|
742
|
-
children: conversation.title
|
|
743
|
-
})
|
|
744
|
-
}),
|
|
745
|
-
/* @__PURE__ */ jsx(SidebarMenuAction, {
|
|
746
|
-
showOnHover: true,
|
|
747
|
-
render: /* @__PURE__ */ jsx(DropdownMenuTrigger, {}),
|
|
748
|
-
"aria-label": `Options for ${conversation.title}`,
|
|
749
|
-
children: /* @__PURE__ */ jsx(Ellipsis, {})
|
|
750
|
-
}),
|
|
751
|
-
/* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
752
|
-
side: "right",
|
|
753
|
-
children: renderConversationMenuContent(conversation)
|
|
754
|
-
})
|
|
755
|
-
] }) : /* @__PURE__ */ jsx(SidebarMenuButton, {
|
|
1071
|
+
const { conversations, activeConversationId, onNewChat, onSelectConversation, renderConversationMenuContent, recentLabel = "Recent", popup = false, className } = componentProps;
|
|
1072
|
+
const t = useDsTranslation("blocks");
|
|
1073
|
+
const content = /* @__PURE__ */ jsxs(SidebarContent, { children: [/* @__PURE__ */ jsx(SidebarGroup, { children: /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(SidebarMenuButton, {
|
|
1074
|
+
isActive: !activeConversationId || !conversations.some((c) => c.id === activeConversationId),
|
|
1075
|
+
onClick: onNewChat,
|
|
1076
|
+
children: [/* @__PURE__ */ jsx(Plus, {}), /* @__PURE__ */ jsx("span", { children: t("chatbotSidebar.newChat") })]
|
|
1077
|
+
}) }) }) }), conversations.length > 0 && /* @__PURE__ */ jsxs(SidebarGroup, { children: [/* @__PURE__ */ jsx(SidebarGroupLabel, { children: recentLabel }), /* @__PURE__ */ jsx(SidebarMenu, { children: conversations.map((conversation) => {
|
|
1078
|
+
const isActive = conversation.id === activeConversationId;
|
|
1079
|
+
return /* @__PURE__ */ jsx(SidebarMenuItem, { children: renderConversationMenuContent ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
1080
|
+
/* @__PURE__ */ jsx(SidebarMenuButton, {
|
|
756
1081
|
isActive,
|
|
757
1082
|
onClick: () => onSelectConversation?.(conversation.id),
|
|
758
1083
|
children: /* @__PURE__ */ jsx("span", {
|
|
759
1084
|
className: "min-w-0 truncate",
|
|
760
1085
|
children: conversation.title
|
|
761
1086
|
})
|
|
762
|
-
})
|
|
763
|
-
|
|
1087
|
+
}),
|
|
1088
|
+
/* @__PURE__ */ jsx(SidebarMenuAction, {
|
|
1089
|
+
showOnHover: true,
|
|
1090
|
+
render: /* @__PURE__ */ jsx(DropdownMenuTrigger, {}),
|
|
1091
|
+
"aria-label": t("chatbotSidebar.optionsFor", { title: conversation.title }),
|
|
1092
|
+
children: /* @__PURE__ */ jsx(Ellipsis, {})
|
|
1093
|
+
}),
|
|
1094
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
1095
|
+
side: "right",
|
|
1096
|
+
children: renderConversationMenuContent(conversation)
|
|
1097
|
+
})
|
|
1098
|
+
] }) : /* @__PURE__ */ jsx(SidebarMenuButton, {
|
|
1099
|
+
isActive,
|
|
1100
|
+
onClick: () => onSelectConversation?.(conversation.id),
|
|
1101
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
1102
|
+
className: "min-w-0 truncate",
|
|
1103
|
+
children: conversation.title
|
|
1104
|
+
})
|
|
1105
|
+
}) }, conversation.id);
|
|
1106
|
+
}) })] })] });
|
|
1107
|
+
if (popup) return /* @__PURE__ */ jsx("div", {
|
|
1108
|
+
ref: forwardRef,
|
|
1109
|
+
className: cn("flex h-full w-full flex-col", className),
|
|
1110
|
+
children: content
|
|
1111
|
+
});
|
|
1112
|
+
return /* @__PURE__ */ jsx(Sidebar, {
|
|
1113
|
+
ref: forwardRef,
|
|
1114
|
+
collapsible: "none",
|
|
1115
|
+
className,
|
|
1116
|
+
children: content
|
|
764
1117
|
});
|
|
765
1118
|
});
|
|
766
1119
|
ChatbotSidebar.displayName = "ChatbotSidebar";
|
|
@@ -773,13 +1126,22 @@ const textareaVariants = cva([
|
|
|
773
1126
|
"disabled:bg-transparent dark:disabled:bg-transparent disabled:opacity-100",
|
|
774
1127
|
"[scrollbar-color:rgba(0,0,0,0.1)_transparent] [scrollbar-width:thin] [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-black/10 [&::-webkit-scrollbar-track]:bg-transparent"
|
|
775
1128
|
], {
|
|
776
|
-
variants: {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
1129
|
+
variants: {
|
|
1130
|
+
size: {
|
|
1131
|
+
default: "max-h-20",
|
|
1132
|
+
large: "max-h-32"
|
|
1133
|
+
},
|
|
1134
|
+
expanded: {
|
|
1135
|
+
true: "min-h-20",
|
|
1136
|
+
false: ""
|
|
1137
|
+
}
|
|
1138
|
+
},
|
|
1139
|
+
defaultVariants: {
|
|
1140
|
+
size: "default",
|
|
1141
|
+
expanded: false
|
|
1142
|
+
}
|
|
781
1143
|
});
|
|
782
|
-
function ChatbotInput({ className, value, onValueChange, onSubmit, onStop, placeholder, loading = false, size = "default", disabled, ...textareaProps }) {
|
|
1144
|
+
function ChatbotInput({ className, value, onValueChange, onSubmit, onStop, placeholder, loading = false, size = "default", expanded = false, disabled, ...textareaProps }) {
|
|
783
1145
|
const t = useDsTranslation("blocks");
|
|
784
1146
|
const [currentValue = "", setCurrentValue] = useControllableState({
|
|
785
1147
|
prop: value,
|
|
@@ -816,7 +1178,10 @@ function ChatbotInput({ className, value, onValueChange, onSubmit, onStop, place
|
|
|
816
1178
|
disabled,
|
|
817
1179
|
onChange: handleChange,
|
|
818
1180
|
onKeyDown: handleKeyDown,
|
|
819
|
-
className: cn(textareaVariants({
|
|
1181
|
+
className: cn(textareaVariants({
|
|
1182
|
+
size,
|
|
1183
|
+
expanded
|
|
1184
|
+
}))
|
|
820
1185
|
}), /* @__PURE__ */ jsx("div", {
|
|
821
1186
|
className: "flex shrink-0 items-center gap-2",
|
|
822
1187
|
children: loading ? /* @__PURE__ */ jsx(InputGroupButton, {
|
|
@@ -1115,32 +1480,35 @@ DashboardPageHeaderAction.displayName = "DashboardPageHeaderAction";
|
|
|
1115
1480
|
|
|
1116
1481
|
//#endregion
|
|
1117
1482
|
//#region src/components/product-badges.tsx
|
|
1118
|
-
const GRADIENT_BASE = cn("border-transparent text-foreground", "bg-[image:linear-gradient(90deg,var(--badge-overlay),var(--badge-overlay)),linear-gradient(90deg,var(--badge-accent),var(--badge-accent))]");
|
|
1483
|
+
const GRADIENT_BASE = cn("border-transparent bg-transparent text-foreground", "bg-[image:linear-gradient(90deg,var(--badge-overlay),var(--badge-overlay)),linear-gradient(90deg,var(--badge-accent),var(--badge-accent))]");
|
|
1119
1484
|
const productBadgeVariants = cva(GRADIENT_BASE, { variants: { type: {
|
|
1120
1485
|
beta: "[--badge-accent:var(--color-blue-300)]",
|
|
1121
1486
|
new: "[--badge-accent:var(--color-green-300)]",
|
|
1122
1487
|
deprecated: "[--badge-accent:var(--color-yellow-300)]",
|
|
1123
1488
|
trial: "[--badge-accent:var(--color-blue-300)]"
|
|
1124
1489
|
} } });
|
|
1125
|
-
const
|
|
1126
|
-
beta: "
|
|
1127
|
-
new: "
|
|
1128
|
-
deprecated: "
|
|
1129
|
-
trial: "
|
|
1490
|
+
const PRODUCT_BADGE_KEY = {
|
|
1491
|
+
beta: "productBadge.beta",
|
|
1492
|
+
new: "productBadge.new",
|
|
1493
|
+
deprecated: "productBadge.deprecated",
|
|
1494
|
+
trial: "productBadge.trial"
|
|
1130
1495
|
};
|
|
1131
1496
|
function createProductBadge(type) {
|
|
1132
|
-
const
|
|
1497
|
+
const labelKey = PRODUCT_BADGE_KEY[type];
|
|
1133
1498
|
const ProductBadge = React.forwardRef((componentProps, forwardRef) => {
|
|
1134
1499
|
const { className, ...props } = componentProps;
|
|
1500
|
+
const t = useDsTranslation("blocks");
|
|
1135
1501
|
return /* @__PURE__ */ jsx(Badge, {
|
|
1136
1502
|
ref: forwardRef,
|
|
1137
1503
|
"data-slot": `badge-${type}`,
|
|
1504
|
+
color: "charcoal",
|
|
1505
|
+
tone: "dark",
|
|
1138
1506
|
className: cn(productBadgeVariants({ type }), className),
|
|
1139
1507
|
...props,
|
|
1140
|
-
children:
|
|
1508
|
+
children: t(labelKey)
|
|
1141
1509
|
});
|
|
1142
1510
|
});
|
|
1143
|
-
ProductBadge.displayName =
|
|
1511
|
+
ProductBadge.displayName = `${type.charAt(0).toUpperCase()}${type.slice(1)}Badge`;
|
|
1144
1512
|
return ProductBadge;
|
|
1145
1513
|
}
|
|
1146
1514
|
/** Blue pill — feature in beta, not yet GA */
|
|
@@ -1154,13 +1522,14 @@ const TrialBadge = createProductBadge("trial");
|
|
|
1154
1522
|
/** Charcoal pill — Professional tier (no gradient; solid secondary Badge) */
|
|
1155
1523
|
const ProfessionalBadge = React.forwardRef((componentProps, forwardRef) => {
|
|
1156
1524
|
const { className, ...props } = componentProps;
|
|
1525
|
+
const t = useDsTranslation("blocks");
|
|
1157
1526
|
return /* @__PURE__ */ jsx(Badge, {
|
|
1158
1527
|
ref: forwardRef,
|
|
1159
1528
|
"data-slot": "badge-professional",
|
|
1160
1529
|
tone: "dark",
|
|
1161
1530
|
color: "charcoal",
|
|
1162
1531
|
...props,
|
|
1163
|
-
children: "
|
|
1532
|
+
children: t("productBadge.professional")
|
|
1164
1533
|
});
|
|
1165
1534
|
});
|
|
1166
1535
|
ProfessionalBadge.displayName = "ProfessionalBadge";
|
|
@@ -1170,20 +1539,23 @@ const roleBadgeVariants = cva(GRADIENT_BASE, { variants: { role: {
|
|
|
1170
1539
|
admin: "[--badge-accent:var(--color-purple-500)]",
|
|
1171
1540
|
owner: "[--badge-accent:var(--color-green-400)]"
|
|
1172
1541
|
} } });
|
|
1173
|
-
const
|
|
1174
|
-
agent: "
|
|
1175
|
-
supervisor: "
|
|
1176
|
-
admin: "
|
|
1177
|
-
owner: "
|
|
1542
|
+
const ROLE_BADGE_KEY = {
|
|
1543
|
+
agent: "roleBadge.agent",
|
|
1544
|
+
supervisor: "roleBadge.supervisor",
|
|
1545
|
+
admin: "roleBadge.admin",
|
|
1546
|
+
owner: "roleBadge.owner"
|
|
1178
1547
|
};
|
|
1179
1548
|
const RoleBadge = React.forwardRef((componentProps, forwardRef) => {
|
|
1180
1549
|
const { role, className, ...props } = componentProps;
|
|
1550
|
+
const t = useDsTranslation("blocks");
|
|
1181
1551
|
return /* @__PURE__ */ jsx(Badge, {
|
|
1182
1552
|
ref: forwardRef,
|
|
1183
1553
|
"data-slot": `badge-${role}`,
|
|
1554
|
+
color: "charcoal",
|
|
1555
|
+
tone: "dark",
|
|
1184
1556
|
className: cn(roleBadgeVariants({ role }), className),
|
|
1185
1557
|
...props,
|
|
1186
|
-
children:
|
|
1558
|
+
children: t(ROLE_BADGE_KEY[role])
|
|
1187
1559
|
});
|
|
1188
1560
|
});
|
|
1189
1561
|
RoleBadge.displayName = "RoleBadge";
|
|
@@ -1216,6 +1588,255 @@ function ChatbotPanelTrigger({ children = "Ask anything", icon = /* @__PURE__ */
|
|
|
1216
1588
|
});
|
|
1217
1589
|
}
|
|
1218
1590
|
|
|
1591
|
+
//#endregion
|
|
1592
|
+
//#region src/components/chatbot-expand-suggestion.tsx
|
|
1593
|
+
const ChatbotExpandSuggestion = React.forwardRef((componentProps, forwardRef) => {
|
|
1594
|
+
const { categories, selectedCategory: selectedCategoryProp, onCategoryChange, label = "Suggestions", suggestions, onSuggestionClick, className, ...props } = componentProps;
|
|
1595
|
+
const [selectedCategory, setSelectedCategory] = useControllableState({
|
|
1596
|
+
prop: selectedCategoryProp,
|
|
1597
|
+
onChange: onCategoryChange
|
|
1598
|
+
});
|
|
1599
|
+
const hasCategories = categories != null && categories.length > 0;
|
|
1600
|
+
const hasSuggestions = suggestions != null && suggestions.length > 0;
|
|
1601
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1602
|
+
ref: forwardRef,
|
|
1603
|
+
className: cn("flex w-full flex-col items-center gap-6", className),
|
|
1604
|
+
...props,
|
|
1605
|
+
children: [hasCategories && /* @__PURE__ */ jsx(ToggleGroup, {
|
|
1606
|
+
variant: "outline",
|
|
1607
|
+
spacing: 2,
|
|
1608
|
+
value: selectedCategory != null ? [selectedCategory] : [],
|
|
1609
|
+
onValueChange: (vals) => setSelectedCategory(vals.at(-1)),
|
|
1610
|
+
children: categories.map((cat) => /* @__PURE__ */ jsx(ToggleGroupItem, {
|
|
1611
|
+
value: cat.value,
|
|
1612
|
+
className: "data-pressed:bg-secondary data-pressed:text-secondary-foreground data-pressed:border-secondary",
|
|
1613
|
+
children: cat.label
|
|
1614
|
+
}, cat.value))
|
|
1615
|
+
}), hasSuggestions && /* @__PURE__ */ jsxs("div", {
|
|
1616
|
+
className: "flex w-full flex-col gap-2",
|
|
1617
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1618
|
+
className: "px-3 py-2",
|
|
1619
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
1620
|
+
className: "text-sm font-semibold text-foreground leading-none",
|
|
1621
|
+
children: label
|
|
1622
|
+
})
|
|
1623
|
+
}), suggestions.map((suggestion, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [/* @__PURE__ */ jsx(Item, {
|
|
1624
|
+
render: /* @__PURE__ */ jsx("button", { type: "button" }),
|
|
1625
|
+
size: "sm",
|
|
1626
|
+
className: "cursor-pointer",
|
|
1627
|
+
onClick: () => onSuggestionClick?.(suggestion),
|
|
1628
|
+
children: /* @__PURE__ */ jsx(ItemContent, { children: /* @__PURE__ */ jsx(ItemTitle, { children: suggestion.text }) })
|
|
1629
|
+
}), index < suggestions.length - 1 && /* @__PURE__ */ jsx(Separator, {})] }, suggestion.id))]
|
|
1630
|
+
})]
|
|
1631
|
+
});
|
|
1632
|
+
});
|
|
1633
|
+
ChatbotExpandSuggestion.displayName = "ChatbotExpandSuggestion";
|
|
1634
|
+
|
|
1635
|
+
//#endregion
|
|
1636
|
+
//#region src/components/chatbot-panel.tsx
|
|
1637
|
+
/** Resize bounds (px), from Figma: min 320 / max 768 / default 400. */
|
|
1638
|
+
const DEFAULT_WIDTH = 400;
|
|
1639
|
+
const MIN_WIDTH = 320;
|
|
1640
|
+
const MAX_WIDTH = 768;
|
|
1641
|
+
/** Width delta applied per Arrow key press on the resize handle. */
|
|
1642
|
+
const KEYBOARD_RESIZE_STEP = 16;
|
|
1643
|
+
const DISCLAIMER_LINK_HREF = "https://legal.aircall.io/#template-9jw4r0usl";
|
|
1644
|
+
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
1645
|
+
function ChatbotPanel({ title, onMenu, conversations, activeConversationId, onNewChat, onSelectConversation, renderConversationMenuContent, onExpand, onClose, emptyTitle, emptyDescription, suggestions = [], onSuggestionSelect, inputValue, onInputValueChange, onSubmit, onStop, loading = false, placeholder, autoFocus, disclaimer, resizable = true, defaultWidth = DEFAULT_WIDTH, minWidth = MIN_WIDTH, maxWidth = MAX_WIDTH, onWidthChange, className, style, children, ...props }) {
|
|
1646
|
+
const t = useDsTranslation("blocks");
|
|
1647
|
+
const [menuOpen, setMenuOpen] = React.useState(false);
|
|
1648
|
+
const [width, setWidth] = React.useState(() => clamp(defaultWidth, minWidth, maxWidth));
|
|
1649
|
+
const applyWidth = React.useCallback((next) => {
|
|
1650
|
+
const clamped = clamp(next, minWidth, maxWidth);
|
|
1651
|
+
setWidth(clamped);
|
|
1652
|
+
onWidthChange?.(clamped);
|
|
1653
|
+
}, [
|
|
1654
|
+
minWidth,
|
|
1655
|
+
maxWidth,
|
|
1656
|
+
onWidthChange
|
|
1657
|
+
]);
|
|
1658
|
+
const dragRef = React.useRef(null);
|
|
1659
|
+
React.useEffect(() => {
|
|
1660
|
+
if (!resizable) return void 0;
|
|
1661
|
+
const handlePointerMove = (event) => {
|
|
1662
|
+
const drag = dragRef.current;
|
|
1663
|
+
if (!drag) return;
|
|
1664
|
+
applyWidth(drag.startWidth - (event.clientX - drag.startX));
|
|
1665
|
+
};
|
|
1666
|
+
const handlePointerUp = () => {
|
|
1667
|
+
dragRef.current = null;
|
|
1668
|
+
};
|
|
1669
|
+
window.addEventListener("pointermove", handlePointerMove);
|
|
1670
|
+
window.addEventListener("pointerup", handlePointerUp);
|
|
1671
|
+
window.addEventListener("pointercancel", handlePointerUp);
|
|
1672
|
+
return () => {
|
|
1673
|
+
window.removeEventListener("pointermove", handlePointerMove);
|
|
1674
|
+
window.removeEventListener("pointerup", handlePointerUp);
|
|
1675
|
+
window.removeEventListener("pointercancel", handlePointerUp);
|
|
1676
|
+
};
|
|
1677
|
+
}, [resizable, applyWidth]);
|
|
1678
|
+
const handleResizeKeyDown = (event) => {
|
|
1679
|
+
if (event.key === "ArrowLeft") {
|
|
1680
|
+
event.preventDefault();
|
|
1681
|
+
applyWidth(width + KEYBOARD_RESIZE_STEP);
|
|
1682
|
+
} else if (event.key === "ArrowRight") {
|
|
1683
|
+
event.preventDefault();
|
|
1684
|
+
applyWidth(width - KEYBOARD_RESIZE_STEP);
|
|
1685
|
+
}
|
|
1686
|
+
};
|
|
1687
|
+
const hasConversation = React.Children.toArray(children).length > 0;
|
|
1688
|
+
const bodyRef = React.useRef(null);
|
|
1689
|
+
const [showScrollDown, setShowScrollDown] = React.useState(false);
|
|
1690
|
+
const updateScrollState = React.useCallback(() => {
|
|
1691
|
+
const el = bodyRef.current;
|
|
1692
|
+
if (!el) return;
|
|
1693
|
+
setShowScrollDown(el.scrollHeight - el.scrollTop - el.clientHeight > 8);
|
|
1694
|
+
}, []);
|
|
1695
|
+
React.useLayoutEffect(() => {
|
|
1696
|
+
updateScrollState();
|
|
1697
|
+
}, [
|
|
1698
|
+
children,
|
|
1699
|
+
width,
|
|
1700
|
+
updateScrollState
|
|
1701
|
+
]);
|
|
1702
|
+
const scrollToBottom = () => {
|
|
1703
|
+
bodyRef.current?.scrollTo({
|
|
1704
|
+
top: bodyRef.current.scrollHeight,
|
|
1705
|
+
behavior: "smooth"
|
|
1706
|
+
});
|
|
1707
|
+
};
|
|
1708
|
+
const resolvedDisclaimer = disclaimer === void 0 ? /* @__PURE__ */ jsxs("p", {
|
|
1709
|
+
className: "text-xs text-muted-foreground",
|
|
1710
|
+
children: [
|
|
1711
|
+
t("chatbotPanel.disclaimerBefore"),
|
|
1712
|
+
/* @__PURE__ */ jsx("a", {
|
|
1713
|
+
href: DISCLAIMER_LINK_HREF,
|
|
1714
|
+
target: "_blank",
|
|
1715
|
+
rel: "noreferrer",
|
|
1716
|
+
className: "text-primary underline",
|
|
1717
|
+
children: t("chatbotPanel.disclaimerLink")
|
|
1718
|
+
}),
|
|
1719
|
+
t("chatbotPanel.disclaimerAfter")
|
|
1720
|
+
]
|
|
1721
|
+
}) : disclaimer;
|
|
1722
|
+
const menuContent = conversations != null ? /* @__PURE__ */ jsx(SidebarProvider, {
|
|
1723
|
+
className: "!min-h-0 flex-1",
|
|
1724
|
+
style: { "--sidebar-width": "20rem" },
|
|
1725
|
+
children: /* @__PURE__ */ jsx(ChatbotSidebar, {
|
|
1726
|
+
popup: true,
|
|
1727
|
+
className: "[&_[data-slot=sidebar-content]]:gap-0",
|
|
1728
|
+
conversations,
|
|
1729
|
+
activeConversationId,
|
|
1730
|
+
onNewChat: onNewChat && (() => {
|
|
1731
|
+
onNewChat();
|
|
1732
|
+
setMenuOpen(false);
|
|
1733
|
+
}),
|
|
1734
|
+
onSelectConversation: onSelectConversation && ((id) => {
|
|
1735
|
+
onSelectConversation(id);
|
|
1736
|
+
setMenuOpen(false);
|
|
1737
|
+
}),
|
|
1738
|
+
renderConversationMenuContent
|
|
1739
|
+
})
|
|
1740
|
+
}) : void 0;
|
|
1741
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1742
|
+
"data-slot": "chatbot-panel",
|
|
1743
|
+
className: cn("relative flex h-full flex-col overflow-clip rounded-xl border border-border bg-background", className),
|
|
1744
|
+
style: {
|
|
1745
|
+
width,
|
|
1746
|
+
...style
|
|
1747
|
+
},
|
|
1748
|
+
...props,
|
|
1749
|
+
children: [
|
|
1750
|
+
resizable && /* @__PURE__ */ jsx("div", {
|
|
1751
|
+
role: "separator",
|
|
1752
|
+
"aria-orientation": "vertical",
|
|
1753
|
+
"aria-label": t("chatbotPanel.resizeHandle"),
|
|
1754
|
+
"aria-valuenow": width,
|
|
1755
|
+
"aria-valuemin": minWidth,
|
|
1756
|
+
"aria-valuemax": maxWidth,
|
|
1757
|
+
tabIndex: 0,
|
|
1758
|
+
onPointerDown: (event) => {
|
|
1759
|
+
dragRef.current = {
|
|
1760
|
+
startX: event.clientX,
|
|
1761
|
+
startWidth: width
|
|
1762
|
+
};
|
|
1763
|
+
},
|
|
1764
|
+
onKeyDown: handleResizeKeyDown,
|
|
1765
|
+
className: cn("absolute inset-y-0 left-0 z-10 w-1.5 cursor-ew-resize touch-none select-none", "hover:bg-border/60 focus-visible:bg-border/60 focus-visible:outline-none")
|
|
1766
|
+
}),
|
|
1767
|
+
/* @__PURE__ */ jsx(ChatbotPanelHeader, {
|
|
1768
|
+
title: title ?? t("chatbotPanel.title"),
|
|
1769
|
+
onMenu,
|
|
1770
|
+
menuContent,
|
|
1771
|
+
menuOpen: conversations != null ? menuOpen : void 0,
|
|
1772
|
+
onMenuOpenChange: setMenuOpen,
|
|
1773
|
+
onExpand,
|
|
1774
|
+
onClose
|
|
1775
|
+
}),
|
|
1776
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1777
|
+
className: "relative flex min-h-0 flex-1 flex-col",
|
|
1778
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1779
|
+
ref: bodyRef,
|
|
1780
|
+
"data-slot": "chatbot-panel-body",
|
|
1781
|
+
onScroll: updateScrollState,
|
|
1782
|
+
className: "flex min-h-0 flex-1 flex-col overflow-y-auto px-6 py-4",
|
|
1783
|
+
children: hasConversation ? /* @__PURE__ */ jsx("div", {
|
|
1784
|
+
className: "flex flex-col gap-6",
|
|
1785
|
+
children
|
|
1786
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
1787
|
+
"data-slot": "chatbot-panel-empty",
|
|
1788
|
+
className: "flex flex-1 flex-col items-center",
|
|
1789
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1790
|
+
className: "flex flex-1 flex-col items-center justify-center gap-2 text-center",
|
|
1791
|
+
children: [
|
|
1792
|
+
/* @__PURE__ */ jsx("span", {
|
|
1793
|
+
"aria-hidden": "true",
|
|
1794
|
+
className: "grid size-12 place-items-center rounded-full border border-green-400 bg-[#00bd82] shadow-[0px_0px_8px_0px_var(--color-green-300)] [&_path]:fill-current [&_svg]:size-7 text-white dark:text-[#101820]",
|
|
1795
|
+
children: /* @__PURE__ */ jsx(AircallMark, {})
|
|
1796
|
+
}),
|
|
1797
|
+
/* @__PURE__ */ jsx("h2", {
|
|
1798
|
+
className: "text-sm font-medium text-foreground",
|
|
1799
|
+
children: emptyTitle ?? t("chatbotPanel.emptyTitle")
|
|
1800
|
+
}),
|
|
1801
|
+
/* @__PURE__ */ jsx("p", {
|
|
1802
|
+
className: "max-w-[280px] text-sm text-muted-foreground",
|
|
1803
|
+
children: emptyDescription ?? t("chatbotPanel.emptyDescription")
|
|
1804
|
+
})
|
|
1805
|
+
]
|
|
1806
|
+
}), suggestions.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
1807
|
+
className: "flex w-full flex-col items-center gap-2 py-4",
|
|
1808
|
+
children: suggestions.map((suggestion) => /* @__PURE__ */ jsx(ChatbotPanelSuggestion, {
|
|
1809
|
+
onClick: () => onSuggestionSelect?.(suggestion),
|
|
1810
|
+
children: suggestion.label
|
|
1811
|
+
}, suggestion.id ?? suggestion.label))
|
|
1812
|
+
})]
|
|
1813
|
+
})
|
|
1814
|
+
}), hasConversation && showScrollDown && /* @__PURE__ */ jsx(Button, {
|
|
1815
|
+
variant: "outline",
|
|
1816
|
+
size: "icon",
|
|
1817
|
+
"aria-label": "Scroll to bottom",
|
|
1818
|
+
onClick: scrollToBottom,
|
|
1819
|
+
className: "absolute right-4 bottom-4 size-10 rounded-md shadow-lg",
|
|
1820
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-6" })
|
|
1821
|
+
})]
|
|
1822
|
+
}),
|
|
1823
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1824
|
+
"data-slot": "chatbot-panel-footer",
|
|
1825
|
+
className: "flex flex-col gap-2.5 bg-gradient-to-b from-background/10 to-background px-4 pt-0 pb-4",
|
|
1826
|
+
children: [/* @__PURE__ */ jsx(ChatbotInput, {
|
|
1827
|
+
value: inputValue,
|
|
1828
|
+
onValueChange: onInputValueChange,
|
|
1829
|
+
onSubmit,
|
|
1830
|
+
onStop,
|
|
1831
|
+
loading,
|
|
1832
|
+
placeholder,
|
|
1833
|
+
autoFocus
|
|
1834
|
+
}), resolvedDisclaimer]
|
|
1835
|
+
})
|
|
1836
|
+
]
|
|
1837
|
+
});
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1219
1840
|
//#endregion
|
|
1220
1841
|
//#region src/form/form-context.ts
|
|
1221
1842
|
/**
|
|
@@ -2030,4 +2651,4 @@ function DashboardSidebarNav({ groups, renderLink }) {
|
|
|
2030
2651
|
}
|
|
2031
2652
|
|
|
2032
2653
|
//#endregion
|
|
2033
|
-
export { BetaBadge, CardSaveBar, ChatbotInput, ChatbotPage, ChatbotPanelHeader, ChatbotPanelSuggestion, ChatbotPanelTrigger, ChatbotResponseBlock, ChatbotSidebar, ChatbotUserMessage, ComingSoonDescription, ComingSoonEmptyState, ComingSoonMedia, ComingSoonTitle, CommonForm, CopyButton, CopyButtonIcon, CopyButtonLabel, DashboardPage, DashboardPageBanner, DashboardPageContent, DashboardPageHeader, DashboardPageHeaderAction, DashboardPageHeaderActions, DashboardPageHeaderDescription, DashboardPageHeaderNav, DashboardPageHeaderNavBack, DashboardPageHeaderPrefix, DashboardPageHeaderSubtitle, DashboardPageHeaderTitle, DashboardPageHeaderTitleGroup, DashboardPageMain, DashboardPageTabs, DashboardSidebar, DashboardSidebarContent, DashboardSidebarFooter, DashboardSidebarGroup, DashboardSidebarGroupLabel, DashboardSidebarHeader, DashboardSidebarMenu, DashboardSidebarMenuBadge, DashboardSidebarMenuButton, DashboardSidebarMenuItem, DashboardSidebarNav, DashboardSidebarProvider, DashboardSidebarSubmenu, DashboardSidebarSubmenuItem, DashboardSidebarSubmenuSeparator, DashboardSidebarTrigger, DashboardStandalonePage, DashboardStandalonePageAction, DashboardStandalonePageActions, DashboardStandalonePageContent, DashboardStandalonePageHeader, DashboardStandalonePageTitle, DeprecatedBadge, EmptyState, EmptyStateActions, EmptyStateButton, EmptyStateDescription, EmptyStateExternalLink, EmptyStateHeader, EmptyStateMedia, EmptyStateTitle, FormComboboxField, FormFieldBase, FormInputField, FormMultiComboboxField, FormNumberField, FormOTPField, FormRadioGroupField, FormSelectField, FormSliderField, FormSwitchField, FormTextareaField, FormToggleGroupField, NewBadge, NoDataDescription, NoDataEmptyState, NoDataMedia, NoDataTitle, NoSupportDescription, NoSupportEmptyState, NoSupportMedia, NoSupportTitle, NotFoundDescription, NotFoundEmptyState, NotFoundMedia, NotFoundTitle, ProfessionalBadge, RestrictedAccessDescription, RestrictedAccessEmptyState, RestrictedAccessMedia, RestrictedAccessTitle, RoleBadge, SaveBar, SubmitButton, TrialBadge, UnknownErrorDescription, UnknownErrorEmptyState, UnknownErrorMedia, UnknownErrorTitle, fieldContext, formContext, toFieldErrors, useCopyToClipboard, useSidebar as useDashboardSidebar, useFieldContext, useForm, useFormContext, withForm };
|
|
2654
|
+
export { BetaBadge, CardSaveBar, ChatbotExpandSuggestion, ChatbotInput, ChatbotPage, ChatbotPageBody, ChatbotPageContent, ChatbotPageConversation, ChatbotPageFooter, ChatbotPageHeading, ChatbotPageInputBar, ChatbotPanel, ChatbotPanelHeader, ChatbotPanelSuggestion, ChatbotPanelTrigger, ChatbotResponseBlock, ChatbotSidebar, ChatbotUserMessage, ComingSoonDescription, ComingSoonEmptyState, ComingSoonMedia, ComingSoonTitle, CommonForm, CopyButton, CopyButtonIcon, CopyButtonLabel, DashboardPage, DashboardPageBanner, DashboardPageContent, DashboardPageHeader, DashboardPageHeaderAction, DashboardPageHeaderActions, DashboardPageHeaderDescription, DashboardPageHeaderNav, DashboardPageHeaderNavBack, DashboardPageHeaderPrefix, DashboardPageHeaderSubtitle, DashboardPageHeaderTitle, DashboardPageHeaderTitleGroup, DashboardPageMain, DashboardPageTabs, DashboardSidebar, DashboardSidebarContent, DashboardSidebarFooter, DashboardSidebarGroup, DashboardSidebarGroupLabel, DashboardSidebarHeader, DashboardSidebarMenu, DashboardSidebarMenuBadge, DashboardSidebarMenuButton, DashboardSidebarMenuItem, DashboardSidebarNav, DashboardSidebarProvider, DashboardSidebarSubmenu, DashboardSidebarSubmenuItem, DashboardSidebarSubmenuSeparator, DashboardSidebarTrigger, DashboardStandalonePage, DashboardStandalonePageAction, DashboardStandalonePageActions, DashboardStandalonePageContent, DashboardStandalonePageHeader, DashboardStandalonePageTitle, DeprecatedBadge, EmptyState, EmptyStateActions, EmptyStateButton, EmptyStateDescription, EmptyStateExternalLink, EmptyStateHeader, EmptyStateMedia, EmptyStateTitle, FormComboboxField, FormFieldBase, FormInputField, FormMultiComboboxField, FormNumberField, FormOTPField, FormRadioGroupField, FormSelectField, FormSliderField, FormSwitchField, FormTextareaField, FormToggleGroupField, NewBadge, NoDataDescription, NoDataEmptyState, NoDataMedia, NoDataTitle, NoSupportDescription, NoSupportEmptyState, NoSupportMedia, NoSupportTitle, NotFoundDescription, NotFoundEmptyState, NotFoundMedia, NotFoundTitle, ProfessionalBadge, RestrictedAccessDescription, RestrictedAccessEmptyState, RestrictedAccessMedia, RestrictedAccessTitle, RoleBadge, SaveBar, SubmitButton, TrialBadge, UnknownErrorDescription, UnknownErrorEmptyState, UnknownErrorMedia, UnknownErrorTitle, fieldContext, formContext, toFieldErrors, useCopyToClipboard, useSidebar as useDashboardSidebar, useFieldContext, useForm, useFormContext, withForm };
|