@wealthx/shadcn 1.5.27 → 1.5.29
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 +88 -88
- package/CHANGELOG.md +12 -0
- package/dist/{chunk-CE2WONIY.mjs → chunk-AE4JKISB.mjs} +27 -31
- package/dist/chunk-BZWQU52U.mjs +1025 -0
- package/dist/components/ui/ai-builder/index.js +1026 -9
- package/dist/components/ui/ai-builder/index.mjs +27 -3
- package/dist/components/ui/ai-conversations/index.js +27 -31
- package/dist/components/ui/ai-conversations/index.mjs +1 -1
- package/dist/index.js +4989 -4949
- package/dist/index.mjs +2 -2
- package/dist/styles.css +1 -1
- package/package.json +4 -1
- package/src/components/ui/ai-builder/agent-card.tsx +7 -5
- package/src/components/ui/ai-builder/agent-settings.tsx +709 -0
- package/src/components/ui/ai-builder/index.tsx +27 -0
- package/src/components/ui/ai-builder/service-config-modal.tsx +48 -6
- package/src/components/ui/ai-builder/types.ts +26 -0
- package/src/components/ui/ai-conversations/thread.tsx +9 -11
- package/src/styles/styles-css.ts +1 -1
- package/dist/chunk-HSL23TOM.mjs +0 -443
|
@@ -0,0 +1,1025 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Tooltip,
|
|
3
|
+
TooltipContent,
|
|
4
|
+
TooltipProvider,
|
|
5
|
+
TooltipTrigger
|
|
6
|
+
} from "./chunk-3S6KVFF5.mjs";
|
|
7
|
+
import {
|
|
8
|
+
Card,
|
|
9
|
+
CardContent
|
|
10
|
+
} from "./chunk-3VDET466.mjs";
|
|
11
|
+
import {
|
|
12
|
+
Switch
|
|
13
|
+
} from "./chunk-PNSYFE3K.mjs";
|
|
14
|
+
import {
|
|
15
|
+
Tabs,
|
|
16
|
+
TabsContent,
|
|
17
|
+
TabsList,
|
|
18
|
+
TabsTrigger
|
|
19
|
+
} from "./chunk-WE4YKBDE.mjs";
|
|
20
|
+
import {
|
|
21
|
+
Table,
|
|
22
|
+
TableBody,
|
|
23
|
+
TableCell,
|
|
24
|
+
TableHead,
|
|
25
|
+
TableHeader,
|
|
26
|
+
TableRow
|
|
27
|
+
} from "./chunk-GT3RU6GA.mjs";
|
|
28
|
+
import {
|
|
29
|
+
Checkbox
|
|
30
|
+
} from "./chunk-IKXYTCSB.mjs";
|
|
31
|
+
import {
|
|
32
|
+
Select,
|
|
33
|
+
SelectContent,
|
|
34
|
+
SelectItem,
|
|
35
|
+
SelectTrigger,
|
|
36
|
+
SelectValue
|
|
37
|
+
} from "./chunk-K6VCC2MK.mjs";
|
|
38
|
+
import {
|
|
39
|
+
Dialog,
|
|
40
|
+
DialogContent,
|
|
41
|
+
DialogDescription,
|
|
42
|
+
DialogFooter,
|
|
43
|
+
DialogHeader,
|
|
44
|
+
DialogTitle
|
|
45
|
+
} from "./chunk-T5FRVEJQ.mjs";
|
|
46
|
+
import {
|
|
47
|
+
Avatar,
|
|
48
|
+
AvatarFallback,
|
|
49
|
+
AvatarImage
|
|
50
|
+
} from "./chunk-H6NQTIF4.mjs";
|
|
51
|
+
import {
|
|
52
|
+
Separator
|
|
53
|
+
} from "./chunk-2GIYVERS.mjs";
|
|
54
|
+
import {
|
|
55
|
+
Textarea
|
|
56
|
+
} from "./chunk-BS75ICOO.mjs";
|
|
57
|
+
import {
|
|
58
|
+
Badge
|
|
59
|
+
} from "./chunk-X6RC5UWB.mjs";
|
|
60
|
+
import {
|
|
61
|
+
Label
|
|
62
|
+
} from "./chunk-LSRGA5BI.mjs";
|
|
63
|
+
import {
|
|
64
|
+
Input
|
|
65
|
+
} from "./chunk-LBTHZSBT.mjs";
|
|
66
|
+
import {
|
|
67
|
+
Button
|
|
68
|
+
} from "./chunk-NOOEKOWY.mjs";
|
|
69
|
+
import {
|
|
70
|
+
cn
|
|
71
|
+
} from "./chunk-AFML43VJ.mjs";
|
|
72
|
+
import {
|
|
73
|
+
__async,
|
|
74
|
+
__spreadProps,
|
|
75
|
+
__spreadValues
|
|
76
|
+
} from "./chunk-WNQUEZJF.mjs";
|
|
77
|
+
|
|
78
|
+
// src/components/ui/ai-builder/agent-card.tsx
|
|
79
|
+
import { MoreHorizontal } from "lucide-react";
|
|
80
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
81
|
+
var AGENT_FEATURES = [
|
|
82
|
+
{
|
|
83
|
+
title: "Lead Capture",
|
|
84
|
+
description: "Automatically collect and qualify leads from website visitors."
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
title: "Initial Engagement",
|
|
88
|
+
description: "Instantly respond to inquiries with personalised mortgage guidance."
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
title: "Smart Follow-Up",
|
|
92
|
+
description: "Re-engage cold leads with timely, context-aware follow-up messages."
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
title: "Appointment Scheduling",
|
|
96
|
+
description: "Book qualified leads directly into advisor calendars without manual coordination."
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
title: "Performance Tracking",
|
|
100
|
+
description: "Monitor agent activity, response rates, and conversion metrics."
|
|
101
|
+
}
|
|
102
|
+
];
|
|
103
|
+
function AgentCard({
|
|
104
|
+
agent,
|
|
105
|
+
onToggle,
|
|
106
|
+
onMenuClick,
|
|
107
|
+
className
|
|
108
|
+
}) {
|
|
109
|
+
const { id, title, description, tags, isEnabled, infoBadge, isComingSoon } = agent;
|
|
110
|
+
return /* @__PURE__ */ jsxs(
|
|
111
|
+
Card,
|
|
112
|
+
{
|
|
113
|
+
className: cn(
|
|
114
|
+
"flex flex-col gap-3 p-4 transition-opacity",
|
|
115
|
+
isComingSoon && "opacity-60",
|
|
116
|
+
className
|
|
117
|
+
),
|
|
118
|
+
children: [
|
|
119
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
120
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 items-center gap-2 min-w-0", children: [
|
|
121
|
+
/* @__PURE__ */ jsx(
|
|
122
|
+
"span",
|
|
123
|
+
{
|
|
124
|
+
className: cn(
|
|
125
|
+
"mt-0.5 size-2 shrink-0 rounded-full",
|
|
126
|
+
isEnabled && !isComingSoon ? "bg-success" : "bg-muted-foreground/40"
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
),
|
|
130
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-label-medium leading-tight", children: title }),
|
|
131
|
+
isComingSoon && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "shrink-0 text-xs", children: "Coming Soon" })
|
|
132
|
+
] }),
|
|
133
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
134
|
+
/* @__PURE__ */ jsx(
|
|
135
|
+
Switch,
|
|
136
|
+
{
|
|
137
|
+
checked: isEnabled,
|
|
138
|
+
disabled: isComingSoon,
|
|
139
|
+
onCheckedChange: (checked) => onToggle(id, checked),
|
|
140
|
+
"aria-label": `Toggle ${title}`
|
|
141
|
+
}
|
|
142
|
+
),
|
|
143
|
+
/* @__PURE__ */ jsx(
|
|
144
|
+
Button,
|
|
145
|
+
{
|
|
146
|
+
variant: "ghost",
|
|
147
|
+
size: "icon",
|
|
148
|
+
className: "h-7 w-7",
|
|
149
|
+
onClick: () => onMenuClick(id),
|
|
150
|
+
"aria-label": `View details for ${title}`,
|
|
151
|
+
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" })
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
] })
|
|
155
|
+
] }),
|
|
156
|
+
/* @__PURE__ */ jsx("p", { className: "text-body-small text-muted-foreground flex-1", children: description }),
|
|
157
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
158
|
+
infoBadge && /* @__PURE__ */ jsx("p", { className: "bg-info/10 text-info px-2 py-1 text-caption", children: infoBadge }),
|
|
159
|
+
tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: tags.map((tag) => /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: tag }, tag)) })
|
|
160
|
+
] })
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
function AgentMenuModal({
|
|
166
|
+
open,
|
|
167
|
+
onOpenChange,
|
|
168
|
+
agentTitle,
|
|
169
|
+
description = "AI-powered lead management that works around the clock to grow your mortgage business.",
|
|
170
|
+
features = AGENT_FEATURES
|
|
171
|
+
}) {
|
|
172
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-lg", children: [
|
|
173
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
174
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: agentTitle }),
|
|
175
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: description })
|
|
176
|
+
] }),
|
|
177
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3 py-2", children: features.map((feature, index) => /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
|
|
178
|
+
/* @__PURE__ */ jsx(
|
|
179
|
+
Badge,
|
|
180
|
+
{
|
|
181
|
+
variant: "default",
|
|
182
|
+
className: "h-6 w-6 shrink-0 p-0 text-xs font-bold",
|
|
183
|
+
children: index + 1
|
|
184
|
+
}
|
|
185
|
+
),
|
|
186
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
187
|
+
/* @__PURE__ */ jsx("p", { className: "text-label-medium", children: feature.title }),
|
|
188
|
+
/* @__PURE__ */ jsx("p", { className: "text-body-small text-muted-foreground", children: feature.description })
|
|
189
|
+
] })
|
|
190
|
+
] }, feature.title)) })
|
|
191
|
+
] }) });
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/components/ui/ai-builder/integration-card.tsx
|
|
195
|
+
import { useState } from "react";
|
|
196
|
+
import { Check, CheckCircle2, Copy, Settings, User } from "lucide-react";
|
|
197
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
198
|
+
function IntegrationServiceCard({
|
|
199
|
+
title,
|
|
200
|
+
imageUrl,
|
|
201
|
+
iconNode,
|
|
202
|
+
description,
|
|
203
|
+
isConnected,
|
|
204
|
+
onCardClick,
|
|
205
|
+
onSettingsClick,
|
|
206
|
+
className
|
|
207
|
+
}) {
|
|
208
|
+
return /* @__PURE__ */ jsxs2(
|
|
209
|
+
Card,
|
|
210
|
+
{
|
|
211
|
+
className: cn(
|
|
212
|
+
"flex flex-col gap-3 p-4",
|
|
213
|
+
!isConnected && "cursor-pointer transition-colors hover:bg-accent/50",
|
|
214
|
+
className
|
|
215
|
+
),
|
|
216
|
+
onClick: !isConnected ? onCardClick : void 0,
|
|
217
|
+
children: [
|
|
218
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-start gap-3", children: [
|
|
219
|
+
/* @__PURE__ */ jsxs2(Avatar, { className: "h-10 w-10 shrink-0", children: [
|
|
220
|
+
imageUrl && /* @__PURE__ */ jsx2(AvatarImage, { src: imageUrl, alt: title }),
|
|
221
|
+
/* @__PURE__ */ jsx2(AvatarFallback, { className: iconNode ? "bg-transparent p-0.5" : "", children: iconNode != null ? iconNode : /* @__PURE__ */ jsx2(User, { className: "h-5 w-5" }) })
|
|
222
|
+
] }),
|
|
223
|
+
/* @__PURE__ */ jsx2("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
224
|
+
/* @__PURE__ */ jsx2("span", { className: "text-base font-semibold", children: title }),
|
|
225
|
+
isConnected && /* @__PURE__ */ jsxs2(Badge, { variant: "success", className: "gap-1 text-xs", children: [
|
|
226
|
+
/* @__PURE__ */ jsx2(CheckCircle2, { className: "h-3 w-3" }),
|
|
227
|
+
"Connected"
|
|
228
|
+
] })
|
|
229
|
+
] }) }),
|
|
230
|
+
isConnected && /* @__PURE__ */ jsx2(
|
|
231
|
+
Button,
|
|
232
|
+
{
|
|
233
|
+
variant: "ghost",
|
|
234
|
+
size: "icon",
|
|
235
|
+
className: "h-7 w-7 shrink-0",
|
|
236
|
+
onClick: (e) => {
|
|
237
|
+
e.stopPropagation();
|
|
238
|
+
onSettingsClick();
|
|
239
|
+
},
|
|
240
|
+
"aria-label": `Settings for ${title}`,
|
|
241
|
+
children: /* @__PURE__ */ jsx2(Settings, { className: "h-4 w-4" })
|
|
242
|
+
}
|
|
243
|
+
)
|
|
244
|
+
] }),
|
|
245
|
+
/* @__PURE__ */ jsx2("p", { className: "text-sm leading-relaxed text-muted-foreground", children: description })
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
function IntegrationInstructionCard({
|
|
251
|
+
title,
|
|
252
|
+
codeBlock,
|
|
253
|
+
onCopy,
|
|
254
|
+
className
|
|
255
|
+
}) {
|
|
256
|
+
const [copied, setCopied] = useState(false);
|
|
257
|
+
const handleCopy = () => __async(null, null, function* () {
|
|
258
|
+
try {
|
|
259
|
+
yield navigator.clipboard.writeText(codeBlock);
|
|
260
|
+
setCopied(true);
|
|
261
|
+
onCopy == null ? void 0 : onCopy();
|
|
262
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
263
|
+
} catch (e) {
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
return /* @__PURE__ */ jsxs2(Card, { className: cn("flex flex-col gap-3 p-4", className), children: [
|
|
267
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-2", children: [
|
|
268
|
+
/* @__PURE__ */ jsx2("h3", { className: "text-sm font-semibold", children: title }),
|
|
269
|
+
/* @__PURE__ */ jsx2(
|
|
270
|
+
Button,
|
|
271
|
+
{
|
|
272
|
+
variant: "outline",
|
|
273
|
+
size: "sm",
|
|
274
|
+
className: "h-7 gap-1.5 text-xs",
|
|
275
|
+
onClick: handleCopy,
|
|
276
|
+
children: copied ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
277
|
+
/* @__PURE__ */ jsx2(Check, { className: "h-3 w-3" }),
|
|
278
|
+
"Copied"
|
|
279
|
+
] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
280
|
+
/* @__PURE__ */ jsx2(Copy, { className: "h-3 w-3" }),
|
|
281
|
+
"Copy"
|
|
282
|
+
] })
|
|
283
|
+
}
|
|
284
|
+
)
|
|
285
|
+
] }),
|
|
286
|
+
/* @__PURE__ */ jsx2("pre", { className: "bg-muted overflow-x-auto p-3 text-xs leading-relaxed", children: /* @__PURE__ */ jsx2("code", { children: codeBlock }) })
|
|
287
|
+
] });
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/components/ui/ai-builder/service-config-modal.tsx
|
|
291
|
+
import { Check as Check2, CheckCircle2 as CheckCircle22, Clock, Mail, Shield, User as User2 } from "lucide-react";
|
|
292
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
293
|
+
function ServiceConfigurationModal({
|
|
294
|
+
open,
|
|
295
|
+
onOpenChange,
|
|
296
|
+
serviceTitle,
|
|
297
|
+
isConnected,
|
|
298
|
+
serviceData,
|
|
299
|
+
iconNode,
|
|
300
|
+
connectPermissions,
|
|
301
|
+
connectDescription = "Link your account to enable automated workflows with WealthX.",
|
|
302
|
+
onConnect,
|
|
303
|
+
onDisconnect,
|
|
304
|
+
onReconnect
|
|
305
|
+
}) {
|
|
306
|
+
return /* @__PURE__ */ jsx3(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx3(DialogContent, { className: "flex max-h-[90vh] flex-col max-w-md", children: isConnected ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
307
|
+
/* @__PURE__ */ jsxs3(DialogHeader, { children: [
|
|
308
|
+
/* @__PURE__ */ jsx3(DialogTitle, { children: serviceTitle }),
|
|
309
|
+
/* @__PURE__ */ jsx3(DialogDescription, { children: "Manage your integration settings." })
|
|
310
|
+
] }),
|
|
311
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto py-2", children: [
|
|
312
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 px-3 py-2 text-xs font-medium bg-success/10 text-success", children: [
|
|
313
|
+
/* @__PURE__ */ jsx3(CheckCircle22, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
314
|
+
"Active \u2014 integration is running"
|
|
315
|
+
] }),
|
|
316
|
+
serviceData && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
317
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
|
|
318
|
+
/* @__PURE__ */ jsx3("p", { className: "text-overline text-muted-foreground", children: "Account Information" }),
|
|
319
|
+
/* @__PURE__ */ jsx3(Card, { className: "py-0", children: /* @__PURE__ */ jsxs3(CardContent, { className: "flex flex-col gap-3 p-3", children: [
|
|
320
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
321
|
+
/* @__PURE__ */ jsx3(User2, { className: "text-muted-foreground h-4 w-4 shrink-0" }),
|
|
322
|
+
/* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
|
|
323
|
+
serviceData.accountIdentifierLabel,
|
|
324
|
+
":"
|
|
325
|
+
] }),
|
|
326
|
+
/* @__PURE__ */ jsx3("span", { className: "font-medium", children: serviceData.accountIdentifier })
|
|
327
|
+
] }),
|
|
328
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
329
|
+
/* @__PURE__ */ jsx3(Clock, { className: "text-muted-foreground h-4 w-4 shrink-0" }),
|
|
330
|
+
/* @__PURE__ */ jsx3("span", { className: "text-muted-foreground", children: "Connected on:" }),
|
|
331
|
+
/* @__PURE__ */ jsx3("span", { className: "font-medium", children: serviceData.connectedOn })
|
|
332
|
+
] }),
|
|
333
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
334
|
+
/* @__PURE__ */ jsx3(Clock, { className: "text-muted-foreground h-4 w-4 shrink-0" }),
|
|
335
|
+
/* @__PURE__ */ jsx3("span", { className: "text-muted-foreground", children: "Last synced:" }),
|
|
336
|
+
/* @__PURE__ */ jsx3("span", { className: "font-medium", children: serviceData.lastSynced })
|
|
337
|
+
] })
|
|
338
|
+
] }) })
|
|
339
|
+
] }),
|
|
340
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
|
|
341
|
+
/* @__PURE__ */ jsx3("p", { className: "text-overline text-muted-foreground", children: "Granted Permissions" }),
|
|
342
|
+
/* @__PURE__ */ jsx3(Card, { className: "py-0", children: /* @__PURE__ */ jsx3(CardContent, { className: "flex flex-col gap-2 p-3", children: serviceData.permissions.map((permission) => /* @__PURE__ */ jsxs3(
|
|
343
|
+
"div",
|
|
344
|
+
{
|
|
345
|
+
className: "flex items-center gap-2 text-sm",
|
|
346
|
+
children: [
|
|
347
|
+
/* @__PURE__ */ jsx3(Shield, { className: "text-success h-4 w-4 shrink-0" }),
|
|
348
|
+
/* @__PURE__ */ jsx3("span", { children: permission })
|
|
349
|
+
]
|
|
350
|
+
},
|
|
351
|
+
permission
|
|
352
|
+
)) }) })
|
|
353
|
+
] }),
|
|
354
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
|
|
355
|
+
/* @__PURE__ */ jsx3("p", { className: "text-overline text-muted-foreground", children: "Sync Settings" }),
|
|
356
|
+
/* @__PURE__ */ jsx3(Card, { className: "py-0", children: /* @__PURE__ */ jsxs3(CardContent, { className: "flex items-center justify-between gap-3 p-3", children: [
|
|
357
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-0.5", children: [
|
|
358
|
+
/* @__PURE__ */ jsx3("p", { className: "text-sm font-medium", children: serviceData.syncLabel }),
|
|
359
|
+
/* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-sm", children: serviceData.syncDescription })
|
|
360
|
+
] }),
|
|
361
|
+
/* @__PURE__ */ jsx3(
|
|
362
|
+
Switch,
|
|
363
|
+
{
|
|
364
|
+
checked: serviceData.syncEnabled,
|
|
365
|
+
onCheckedChange: serviceData.onSyncToggle,
|
|
366
|
+
"aria-label": serviceData.syncLabel
|
|
367
|
+
}
|
|
368
|
+
)
|
|
369
|
+
] }) })
|
|
370
|
+
] }),
|
|
371
|
+
serviceData.emailCategories && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
|
|
372
|
+
/* @__PURE__ */ jsxs3("div", { children: [
|
|
373
|
+
/* @__PURE__ */ jsx3("p", { className: "text-overline text-muted-foreground", children: "Email Filters" }),
|
|
374
|
+
/* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-sm mt-0.5", children: "Choose which inbox categories to sync into WealthX." })
|
|
375
|
+
] }),
|
|
376
|
+
/* @__PURE__ */ jsx3(Card, { className: "py-0", children: /* @__PURE__ */ jsx3(CardContent, { className: "flex flex-col gap-3 p-3", children: serviceData.emailCategories.available.map(
|
|
377
|
+
(category) => {
|
|
378
|
+
const checked = serviceData.emailCategories.selected.includes(
|
|
379
|
+
category
|
|
380
|
+
);
|
|
381
|
+
return /* @__PURE__ */ jsxs3(
|
|
382
|
+
"div",
|
|
383
|
+
{
|
|
384
|
+
className: "flex items-center gap-2",
|
|
385
|
+
children: [
|
|
386
|
+
/* @__PURE__ */ jsx3(
|
|
387
|
+
Checkbox,
|
|
388
|
+
{
|
|
389
|
+
id: `email-cat-${category}`,
|
|
390
|
+
checked,
|
|
391
|
+
onCheckedChange: (v) => {
|
|
392
|
+
const next = v ? [
|
|
393
|
+
...serviceData.emailCategories.selected,
|
|
394
|
+
category
|
|
395
|
+
] : serviceData.emailCategories.selected.filter(
|
|
396
|
+
(c) => c !== category
|
|
397
|
+
);
|
|
398
|
+
serviceData.emailCategories.onChange(
|
|
399
|
+
next
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
),
|
|
404
|
+
/* @__PURE__ */ jsx3(
|
|
405
|
+
"label",
|
|
406
|
+
{
|
|
407
|
+
htmlFor: `email-cat-${category}`,
|
|
408
|
+
className: "text-sm cursor-pointer select-none",
|
|
409
|
+
children: category
|
|
410
|
+
}
|
|
411
|
+
)
|
|
412
|
+
]
|
|
413
|
+
},
|
|
414
|
+
category
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
) }) })
|
|
418
|
+
] }),
|
|
419
|
+
serviceData.emailFilters && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
|
|
420
|
+
/* @__PURE__ */ jsxs3("div", { children: [
|
|
421
|
+
/* @__PURE__ */ jsx3("p", { className: "text-overline text-muted-foreground", children: "Email Filters" }),
|
|
422
|
+
/* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-sm mt-0.5", children: serviceData.emailFilters.description })
|
|
423
|
+
] }),
|
|
424
|
+
/* @__PURE__ */ jsx3(Card, { className: "py-0", children: /* @__PURE__ */ jsx3(CardContent, { className: "flex flex-col gap-3 p-3 max-h-48 overflow-y-auto", children: serviceData.emailFilters.categories.map(
|
|
425
|
+
(category) => /* @__PURE__ */ jsxs3(
|
|
426
|
+
"div",
|
|
427
|
+
{
|
|
428
|
+
className: "flex items-center gap-2",
|
|
429
|
+
children: [
|
|
430
|
+
/* @__PURE__ */ jsx3(
|
|
431
|
+
Checkbox,
|
|
432
|
+
{
|
|
433
|
+
id: `email-cat-${category.id}`,
|
|
434
|
+
checked: category.enabled,
|
|
435
|
+
onCheckedChange: (v) => serviceData.emailFilters.onFilterChange(
|
|
436
|
+
category.id,
|
|
437
|
+
!!v
|
|
438
|
+
)
|
|
439
|
+
}
|
|
440
|
+
),
|
|
441
|
+
/* @__PURE__ */ jsx3(
|
|
442
|
+
"label",
|
|
443
|
+
{
|
|
444
|
+
htmlFor: `email-cat-${category.id}`,
|
|
445
|
+
className: "text-sm cursor-pointer select-none",
|
|
446
|
+
children: category.label
|
|
447
|
+
}
|
|
448
|
+
)
|
|
449
|
+
]
|
|
450
|
+
},
|
|
451
|
+
category.id
|
|
452
|
+
)
|
|
453
|
+
) }) })
|
|
454
|
+
] })
|
|
455
|
+
] })
|
|
456
|
+
] }),
|
|
457
|
+
/* @__PURE__ */ jsxs3(DialogFooter, { children: [
|
|
458
|
+
/* @__PURE__ */ jsx3(
|
|
459
|
+
Button,
|
|
460
|
+
{
|
|
461
|
+
variant: "destructive",
|
|
462
|
+
size: "sm",
|
|
463
|
+
onClick: onDisconnect,
|
|
464
|
+
className: "mr-auto",
|
|
465
|
+
children: "Disconnect"
|
|
466
|
+
}
|
|
467
|
+
),
|
|
468
|
+
/* @__PURE__ */ jsx3(
|
|
469
|
+
Button,
|
|
470
|
+
{
|
|
471
|
+
variant: "outline-secondary",
|
|
472
|
+
size: "sm",
|
|
473
|
+
onClick: () => onOpenChange(false),
|
|
474
|
+
children: "Cancel"
|
|
475
|
+
}
|
|
476
|
+
),
|
|
477
|
+
/* @__PURE__ */ jsx3(Button, { size: "sm", onClick: onReconnect, children: "Reconnect" })
|
|
478
|
+
] })
|
|
479
|
+
] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
480
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-4 py-2", children: [
|
|
481
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3", children: [
|
|
482
|
+
/* @__PURE__ */ jsx3("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center bg-muted", children: iconNode != null ? iconNode : /* @__PURE__ */ jsx3(Mail, { className: "h-5 w-5 text-muted-foreground" }) }),
|
|
483
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-0.5", children: [
|
|
484
|
+
/* @__PURE__ */ jsxs3("p", { className: "text-sm font-semibold", children: [
|
|
485
|
+
"Connect ",
|
|
486
|
+
serviceTitle
|
|
487
|
+
] }),
|
|
488
|
+
/* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: connectDescription })
|
|
489
|
+
] })
|
|
490
|
+
] }),
|
|
491
|
+
connectPermissions && connectPermissions.length > 0 && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2 border border-border px-4 py-3", children: [
|
|
492
|
+
/* @__PURE__ */ jsx3("p", { className: "text-overline text-muted-foreground", children: "Permissions requested" }),
|
|
493
|
+
connectPermissions.map((perm) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
|
|
494
|
+
/* @__PURE__ */ jsx3(Check2, { className: "h-3.5 w-3.5 shrink-0 text-success" }),
|
|
495
|
+
/* @__PURE__ */ jsx3("span", { className: "text-sm text-muted-foreground", children: perm })
|
|
496
|
+
] }, perm))
|
|
497
|
+
] })
|
|
498
|
+
] }),
|
|
499
|
+
/* @__PURE__ */ jsxs3(DialogFooter, { children: [
|
|
500
|
+
/* @__PURE__ */ jsx3(
|
|
501
|
+
Button,
|
|
502
|
+
{
|
|
503
|
+
variant: "outline-secondary",
|
|
504
|
+
size: "sm",
|
|
505
|
+
onClick: () => onOpenChange(false),
|
|
506
|
+
children: "Cancel"
|
|
507
|
+
}
|
|
508
|
+
),
|
|
509
|
+
/* @__PURE__ */ jsx3(Button, { size: "sm", onClick: onConnect, children: "Connect" })
|
|
510
|
+
] })
|
|
511
|
+
] }) }) });
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// src/components/ui/ai-builder/agent-settings.tsx
|
|
515
|
+
import React2 from "react";
|
|
516
|
+
import {
|
|
517
|
+
closestCenter,
|
|
518
|
+
DndContext,
|
|
519
|
+
KeyboardSensor,
|
|
520
|
+
PointerSensor,
|
|
521
|
+
useSensor,
|
|
522
|
+
useSensors
|
|
523
|
+
} from "@dnd-kit/core";
|
|
524
|
+
import {
|
|
525
|
+
SortableContext,
|
|
526
|
+
sortableKeyboardCoordinates,
|
|
527
|
+
useSortable,
|
|
528
|
+
verticalListSortingStrategy
|
|
529
|
+
} from "@dnd-kit/sortable";
|
|
530
|
+
import { CSS } from "@dnd-kit/utilities";
|
|
531
|
+
import {
|
|
532
|
+
Download,
|
|
533
|
+
GripVertical,
|
|
534
|
+
Info,
|
|
535
|
+
Pencil,
|
|
536
|
+
Plus,
|
|
537
|
+
Trash2,
|
|
538
|
+
Upload
|
|
539
|
+
} from "lucide-react";
|
|
540
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
541
|
+
function SectionHeader({
|
|
542
|
+
title,
|
|
543
|
+
description,
|
|
544
|
+
className
|
|
545
|
+
}) {
|
|
546
|
+
return /* @__PURE__ */ jsxs4("div", { className: cn("flex flex-col gap-0.5", className), children: [
|
|
547
|
+
/* @__PURE__ */ jsx4("h2", { className: "text-h5", children: title }),
|
|
548
|
+
/* @__PURE__ */ jsx4("p", { className: "text-body-small text-muted-foreground", children: description })
|
|
549
|
+
] });
|
|
550
|
+
}
|
|
551
|
+
function SettingRow({
|
|
552
|
+
icon,
|
|
553
|
+
label,
|
|
554
|
+
description,
|
|
555
|
+
control,
|
|
556
|
+
className
|
|
557
|
+
}) {
|
|
558
|
+
return /* @__PURE__ */ jsxs4("div", { className: cn("flex items-center gap-4 py-4", className), children: [
|
|
559
|
+
/* @__PURE__ */ jsx4("div", { className: "flex size-10 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: icon }),
|
|
560
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-1 flex-col gap-0.5", children: [
|
|
561
|
+
/* @__PURE__ */ jsx4("span", { className: "text-sm font-semibold", children: label }),
|
|
562
|
+
/* @__PURE__ */ jsx4("span", { className: "text-caption text-muted-foreground", children: description })
|
|
563
|
+
] }),
|
|
564
|
+
/* @__PURE__ */ jsx4("div", { className: "shrink-0", children: control })
|
|
565
|
+
] });
|
|
566
|
+
}
|
|
567
|
+
function SettingCard({ rows, className }) {
|
|
568
|
+
return /* @__PURE__ */ jsx4("div", { className: cn("rounded-none border px-4", className), children: rows.map((row, i) => /* @__PURE__ */ jsxs4(React2.Fragment, { children: [
|
|
569
|
+
/* @__PURE__ */ jsx4(SettingRow, __spreadValues({}, row)),
|
|
570
|
+
i < rows.length - 1 && /* @__PURE__ */ jsx4(Separator, {})
|
|
571
|
+
] }, row.label)) });
|
|
572
|
+
}
|
|
573
|
+
function AgentConfigForm({
|
|
574
|
+
config,
|
|
575
|
+
onChange,
|
|
576
|
+
className
|
|
577
|
+
}) {
|
|
578
|
+
return /* @__PURE__ */ jsxs4(
|
|
579
|
+
"div",
|
|
580
|
+
{
|
|
581
|
+
className: cn("flex flex-col gap-4 rounded-none border p-6", className),
|
|
582
|
+
children: [
|
|
583
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-1.5", children: [
|
|
584
|
+
/* @__PURE__ */ jsx4(Label, { htmlFor: "agent-name", children: "Agent Name" }),
|
|
585
|
+
/* @__PURE__ */ jsx4(
|
|
586
|
+
Input,
|
|
587
|
+
{
|
|
588
|
+
id: "agent-name",
|
|
589
|
+
value: config.name,
|
|
590
|
+
onChange: (e) => onChange(__spreadProps(__spreadValues({}, config), { name: e.target.value }))
|
|
591
|
+
}
|
|
592
|
+
)
|
|
593
|
+
] }),
|
|
594
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-1.5", children: [
|
|
595
|
+
/* @__PURE__ */ jsx4(Label, { htmlFor: "agent-desc", children: "Business Description" }),
|
|
596
|
+
/* @__PURE__ */ jsx4(
|
|
597
|
+
Textarea,
|
|
598
|
+
{
|
|
599
|
+
id: "agent-desc",
|
|
600
|
+
rows: 4,
|
|
601
|
+
placeholder: "What business is this agent for? What industry?",
|
|
602
|
+
value: config.businessDescription,
|
|
603
|
+
onChange: (e) => onChange(__spreadProps(__spreadValues({}, config), { businessDescription: e.target.value }))
|
|
604
|
+
}
|
|
605
|
+
)
|
|
606
|
+
] })
|
|
607
|
+
]
|
|
608
|
+
}
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
function ResponseTemplateEditModal({
|
|
612
|
+
open,
|
|
613
|
+
onOpenChange,
|
|
614
|
+
channel,
|
|
615
|
+
content,
|
|
616
|
+
onConfirm
|
|
617
|
+
}) {
|
|
618
|
+
const [draft, setDraft] = React2.useState(content);
|
|
619
|
+
React2.useEffect(() => {
|
|
620
|
+
if (open) setDraft(content);
|
|
621
|
+
}, [open, content]);
|
|
622
|
+
const isEmail = channel === "email";
|
|
623
|
+
const channelLabel = isEmail ? "Email" : "Chat";
|
|
624
|
+
const helperText = isEmail ? "Use {customer} to insert the customer name and {answer} to insert the response" : "Use {answer} to insert the response";
|
|
625
|
+
return /* @__PURE__ */ jsx4(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs4(DialogContent, { className: "max-w-lg", children: [
|
|
626
|
+
/* @__PURE__ */ jsx4(DialogHeader, { children: /* @__PURE__ */ jsxs4(DialogTitle, { children: [
|
|
627
|
+
"Edit ",
|
|
628
|
+
channelLabel,
|
|
629
|
+
" response template"
|
|
630
|
+
] }) }),
|
|
631
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-1.5 py-2", children: [
|
|
632
|
+
/* @__PURE__ */ jsxs4(Label, { htmlFor: "template-content", children: [
|
|
633
|
+
channelLabel,
|
|
634
|
+
" template content",
|
|
635
|
+
" ",
|
|
636
|
+
/* @__PURE__ */ jsx4("span", { className: "text-destructive", children: "*" })
|
|
637
|
+
] }),
|
|
638
|
+
/* @__PURE__ */ jsx4(
|
|
639
|
+
Textarea,
|
|
640
|
+
{
|
|
641
|
+
id: "template-content",
|
|
642
|
+
rows: 6,
|
|
643
|
+
placeholder: `Enter content for ${channelLabel} template`,
|
|
644
|
+
value: draft,
|
|
645
|
+
onChange: (e) => setDraft(e.target.value)
|
|
646
|
+
}
|
|
647
|
+
),
|
|
648
|
+
/* @__PURE__ */ jsx4("p", { className: "text-caption text-muted-foreground", children: helperText })
|
|
649
|
+
] }),
|
|
650
|
+
/* @__PURE__ */ jsxs4(DialogFooter, { children: [
|
|
651
|
+
/* @__PURE__ */ jsx4(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
|
|
652
|
+
/* @__PURE__ */ jsx4(
|
|
653
|
+
Button,
|
|
654
|
+
{
|
|
655
|
+
onClick: () => {
|
|
656
|
+
onConfirm(draft);
|
|
657
|
+
onOpenChange(false);
|
|
658
|
+
},
|
|
659
|
+
children: "Confirm"
|
|
660
|
+
}
|
|
661
|
+
)
|
|
662
|
+
] })
|
|
663
|
+
] }) });
|
|
664
|
+
}
|
|
665
|
+
function RuleOrderBadge({ order, className }) {
|
|
666
|
+
return /* @__PURE__ */ jsxs4(Badge, { variant: "secondary", className, children: [
|
|
667
|
+
"#",
|
|
668
|
+
order
|
|
669
|
+
] });
|
|
670
|
+
}
|
|
671
|
+
function SortableRuleRow({
|
|
672
|
+
rule,
|
|
673
|
+
index,
|
|
674
|
+
onEdit,
|
|
675
|
+
onDelete,
|
|
676
|
+
onToggle
|
|
677
|
+
}) {
|
|
678
|
+
const {
|
|
679
|
+
attributes,
|
|
680
|
+
listeners,
|
|
681
|
+
setNodeRef,
|
|
682
|
+
transform,
|
|
683
|
+
transition,
|
|
684
|
+
isDragging
|
|
685
|
+
} = useSortable({ id: rule.id });
|
|
686
|
+
const style = {
|
|
687
|
+
transform: CSS.Transform.toString(transform),
|
|
688
|
+
transition
|
|
689
|
+
};
|
|
690
|
+
return /* @__PURE__ */ jsxs4(
|
|
691
|
+
TableRow,
|
|
692
|
+
{
|
|
693
|
+
ref: setNodeRef,
|
|
694
|
+
style,
|
|
695
|
+
className: cn(isDragging && "opacity-50 bg-muted/40"),
|
|
696
|
+
children: [
|
|
697
|
+
/* @__PURE__ */ jsx4(TableCell, { children: /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
|
|
698
|
+
/* @__PURE__ */ jsx4(
|
|
699
|
+
"button",
|
|
700
|
+
__spreadProps(__spreadValues(__spreadValues({
|
|
701
|
+
type: "button",
|
|
702
|
+
className: "cursor-grab touch-none text-muted-foreground hover:text-foreground active:cursor-grabbing",
|
|
703
|
+
"aria-label": `Drag to reorder rule ${index + 1}`
|
|
704
|
+
}, attributes), listeners), {
|
|
705
|
+
children: /* @__PURE__ */ jsx4(GripVertical, { className: "h-4 w-4" })
|
|
706
|
+
})
|
|
707
|
+
),
|
|
708
|
+
/* @__PURE__ */ jsx4(RuleOrderBadge, { order: index + 1 })
|
|
709
|
+
] }) }),
|
|
710
|
+
/* @__PURE__ */ jsx4(TableCell, { className: "text-body-small overflow-hidden", children: /* @__PURE__ */ jsx4("div", { className: "break-words whitespace-normal", children: rule.text }) }),
|
|
711
|
+
/* @__PURE__ */ jsx4(TableCell, { children: /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-end gap-1", children: [
|
|
712
|
+
/* @__PURE__ */ jsx4(
|
|
713
|
+
Switch,
|
|
714
|
+
{
|
|
715
|
+
checked: rule.isEnabled,
|
|
716
|
+
onCheckedChange: (checked) => onToggle(rule.id, checked),
|
|
717
|
+
"aria-label": `Toggle rule ${index + 1}`
|
|
718
|
+
}
|
|
719
|
+
),
|
|
720
|
+
/* @__PURE__ */ jsx4(
|
|
721
|
+
Button,
|
|
722
|
+
{
|
|
723
|
+
variant: "ghost",
|
|
724
|
+
size: "icon",
|
|
725
|
+
className: "h-8 w-8",
|
|
726
|
+
onClick: () => onEdit(rule.id),
|
|
727
|
+
"aria-label": `Edit rule ${index + 1}`,
|
|
728
|
+
children: /* @__PURE__ */ jsx4(Pencil, { className: "h-3.5 w-3.5" })
|
|
729
|
+
}
|
|
730
|
+
),
|
|
731
|
+
/* @__PURE__ */ jsx4(
|
|
732
|
+
Button,
|
|
733
|
+
{
|
|
734
|
+
variant: "ghost",
|
|
735
|
+
size: "icon",
|
|
736
|
+
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
737
|
+
onClick: () => onDelete(rule.id),
|
|
738
|
+
"aria-label": `Delete rule ${index + 1}`,
|
|
739
|
+
children: /* @__PURE__ */ jsx4(Trash2, { className: "h-3.5 w-3.5" })
|
|
740
|
+
}
|
|
741
|
+
)
|
|
742
|
+
] }) })
|
|
743
|
+
]
|
|
744
|
+
}
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
function RuleTable({
|
|
748
|
+
rules,
|
|
749
|
+
onEdit,
|
|
750
|
+
onDelete,
|
|
751
|
+
onToggle,
|
|
752
|
+
onReorder
|
|
753
|
+
}) {
|
|
754
|
+
const sensors = useSensors(
|
|
755
|
+
useSensor(PointerSensor),
|
|
756
|
+
useSensor(KeyboardSensor, {
|
|
757
|
+
coordinateGetter: sortableKeyboardCoordinates
|
|
758
|
+
})
|
|
759
|
+
);
|
|
760
|
+
function handleDragEnd(event) {
|
|
761
|
+
const { active, over } = event;
|
|
762
|
+
if (over && active.id !== over.id && onReorder) {
|
|
763
|
+
onReorder(String(active.id), String(over.id));
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
if (rules.length === 0) {
|
|
767
|
+
return /* @__PURE__ */ jsx4("div", { className: "flex h-24 items-center justify-center text-body-small text-muted-foreground", children: "No rules added yet." });
|
|
768
|
+
}
|
|
769
|
+
return /* @__PURE__ */ jsx4(
|
|
770
|
+
DndContext,
|
|
771
|
+
{
|
|
772
|
+
sensors,
|
|
773
|
+
collisionDetection: closestCenter,
|
|
774
|
+
onDragEnd: handleDragEnd,
|
|
775
|
+
children: /* @__PURE__ */ jsx4(
|
|
776
|
+
SortableContext,
|
|
777
|
+
{
|
|
778
|
+
items: rules.map((r) => r.id),
|
|
779
|
+
strategy: verticalListSortingStrategy,
|
|
780
|
+
children: /* @__PURE__ */ jsxs4(Table, { className: "table-fixed", children: [
|
|
781
|
+
/* @__PURE__ */ jsx4(TableHeader, { children: /* @__PURE__ */ jsxs4(TableRow, { children: [
|
|
782
|
+
/* @__PURE__ */ jsx4(TableHead, { className: "w-28", children: /* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-1.5", children: [
|
|
783
|
+
"Order",
|
|
784
|
+
/* @__PURE__ */ jsx4(TooltipProvider, { children: /* @__PURE__ */ jsxs4(Tooltip, { children: [
|
|
785
|
+
/* @__PURE__ */ jsx4(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx4(Info, { className: "h-3.5 w-3.5 text-muted-foreground cursor-default" }) }),
|
|
786
|
+
/* @__PURE__ */ jsx4(TooltipContent, { children: "Drag rows to reorder rules" })
|
|
787
|
+
] }) })
|
|
788
|
+
] }) }),
|
|
789
|
+
/* @__PURE__ */ jsx4(TableHead, { children: "Rule Set" }),
|
|
790
|
+
/* @__PURE__ */ jsx4(TableHead, { className: "w-36 text-right", children: "Actions" })
|
|
791
|
+
] }) }),
|
|
792
|
+
/* @__PURE__ */ jsx4(TableBody, { children: rules.map((rule, index) => /* @__PURE__ */ jsx4(
|
|
793
|
+
SortableRuleRow,
|
|
794
|
+
{
|
|
795
|
+
rule,
|
|
796
|
+
index,
|
|
797
|
+
onEdit,
|
|
798
|
+
onDelete,
|
|
799
|
+
onToggle
|
|
800
|
+
},
|
|
801
|
+
rule.id
|
|
802
|
+
)) })
|
|
803
|
+
] })
|
|
804
|
+
}
|
|
805
|
+
)
|
|
806
|
+
}
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
function RuleTabContent({
|
|
810
|
+
rules,
|
|
811
|
+
description,
|
|
812
|
+
onEditRule,
|
|
813
|
+
onDeleteRule,
|
|
814
|
+
onToggleRule,
|
|
815
|
+
onReorderRules,
|
|
816
|
+
rowsPerPage
|
|
817
|
+
}) {
|
|
818
|
+
return /* @__PURE__ */ jsxs4("div", { className: "mt-4 flex flex-col gap-3", children: [
|
|
819
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-start gap-2 rounded-none border border-blue-200 bg-blue-50 p-3", children: [
|
|
820
|
+
/* @__PURE__ */ jsx4(Info, { className: "mt-0.5 h-4 w-4 shrink-0 text-blue-600" }),
|
|
821
|
+
/* @__PURE__ */ jsx4("p", { className: "text-caption text-blue-700", children: description })
|
|
822
|
+
] }),
|
|
823
|
+
/* @__PURE__ */ jsx4(
|
|
824
|
+
RuleTable,
|
|
825
|
+
{
|
|
826
|
+
rules,
|
|
827
|
+
onEdit: onEditRule,
|
|
828
|
+
onDelete: onDeleteRule,
|
|
829
|
+
onToggle: onToggleRule,
|
|
830
|
+
onReorder: onReorderRules
|
|
831
|
+
}
|
|
832
|
+
),
|
|
833
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-end gap-2 pt-2 text-body-small text-muted-foreground", children: [
|
|
834
|
+
/* @__PURE__ */ jsx4("span", { children: "Rows per page:" }),
|
|
835
|
+
/* @__PURE__ */ jsxs4(Select, { defaultValue: String(rowsPerPage), children: [
|
|
836
|
+
/* @__PURE__ */ jsx4(SelectTrigger, { className: "h-8 w-20", children: /* @__PURE__ */ jsx4(SelectValue, {}) }),
|
|
837
|
+
/* @__PURE__ */ jsxs4(SelectContent, { children: [
|
|
838
|
+
/* @__PURE__ */ jsx4(SelectItem, { value: "5", children: "5" }),
|
|
839
|
+
/* @__PURE__ */ jsx4(SelectItem, { value: "10", children: "10" }),
|
|
840
|
+
/* @__PURE__ */ jsx4(SelectItem, { value: "20", children: "20" }),
|
|
841
|
+
/* @__PURE__ */ jsx4(SelectItem, { value: "50", children: "50" })
|
|
842
|
+
] })
|
|
843
|
+
] })
|
|
844
|
+
] })
|
|
845
|
+
] });
|
|
846
|
+
}
|
|
847
|
+
function RuleSetSection({
|
|
848
|
+
standardRules,
|
|
849
|
+
handoffRules,
|
|
850
|
+
onAddRule,
|
|
851
|
+
onEditRule,
|
|
852
|
+
onDeleteRule,
|
|
853
|
+
onToggleRule,
|
|
854
|
+
onReorderRules,
|
|
855
|
+
onExport,
|
|
856
|
+
onImport,
|
|
857
|
+
rowsPerPage = 10,
|
|
858
|
+
className
|
|
859
|
+
}) {
|
|
860
|
+
const [activeTab, setActiveTab] = React2.useState(
|
|
861
|
+
"standard"
|
|
862
|
+
);
|
|
863
|
+
return /* @__PURE__ */ jsxs4("div", { className: cn("flex flex-col gap-4", className), children: [
|
|
864
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-start justify-between gap-4", children: [
|
|
865
|
+
/* @__PURE__ */ jsx4(
|
|
866
|
+
SectionHeader,
|
|
867
|
+
{
|
|
868
|
+
title: "Rule Set",
|
|
869
|
+
description: "You can adjust the behavior and response method of the Agent through rules."
|
|
870
|
+
}
|
|
871
|
+
),
|
|
872
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
873
|
+
/* @__PURE__ */ jsxs4(Button, { variant: "outline", size: "sm", onClick: onExport, children: [
|
|
874
|
+
/* @__PURE__ */ jsx4(Download, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
875
|
+
"Export"
|
|
876
|
+
] }),
|
|
877
|
+
/* @__PURE__ */ jsxs4(Button, { variant: "outline", size: "sm", onClick: onImport, children: [
|
|
878
|
+
/* @__PURE__ */ jsx4(Upload, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
879
|
+
"Import"
|
|
880
|
+
] }),
|
|
881
|
+
/* @__PURE__ */ jsxs4(Button, { size: "sm", onClick: () => onAddRule(activeTab), children: [
|
|
882
|
+
/* @__PURE__ */ jsx4(Plus, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
883
|
+
"Add rule"
|
|
884
|
+
] })
|
|
885
|
+
] })
|
|
886
|
+
] }),
|
|
887
|
+
/* @__PURE__ */ jsxs4(
|
|
888
|
+
Tabs,
|
|
889
|
+
{
|
|
890
|
+
defaultValue: "standard",
|
|
891
|
+
onValueChange: (v) => setActiveTab(v),
|
|
892
|
+
children: [
|
|
893
|
+
/* @__PURE__ */ jsxs4(TabsList, { className: "w-full", children: [
|
|
894
|
+
/* @__PURE__ */ jsx4(TabsTrigger, { value: "standard", className: "flex-1", children: "Standard Rules" }),
|
|
895
|
+
/* @__PURE__ */ jsx4(TabsTrigger, { value: "handoff", className: "flex-1", children: "Hand-off Rules" })
|
|
896
|
+
] }),
|
|
897
|
+
/* @__PURE__ */ jsx4(TabsContent, { value: "standard", children: /* @__PURE__ */ jsx4(
|
|
898
|
+
RuleTabContent,
|
|
899
|
+
{
|
|
900
|
+
rules: standardRules,
|
|
901
|
+
description: "Standard rules guide AI behavior during response generation. These rules help the AI understand how to respond appropriately.",
|
|
902
|
+
onEditRule,
|
|
903
|
+
onDeleteRule,
|
|
904
|
+
onToggleRule,
|
|
905
|
+
onReorderRules,
|
|
906
|
+
rowsPerPage
|
|
907
|
+
}
|
|
908
|
+
) }),
|
|
909
|
+
/* @__PURE__ */ jsx4(TabsContent, { value: "handoff", children: /* @__PURE__ */ jsx4(
|
|
910
|
+
RuleTabContent,
|
|
911
|
+
{
|
|
912
|
+
rules: handoffRules,
|
|
913
|
+
description: "Hand-off rules define when the AI should transfer a conversation to a human agent.",
|
|
914
|
+
onEditRule,
|
|
915
|
+
onDeleteRule,
|
|
916
|
+
onToggleRule,
|
|
917
|
+
onReorderRules,
|
|
918
|
+
rowsPerPage
|
|
919
|
+
}
|
|
920
|
+
) })
|
|
921
|
+
]
|
|
922
|
+
}
|
|
923
|
+
)
|
|
924
|
+
] });
|
|
925
|
+
}
|
|
926
|
+
function AddEditRuleModal({
|
|
927
|
+
open,
|
|
928
|
+
onOpenChange,
|
|
929
|
+
rule,
|
|
930
|
+
defaultType = "standard",
|
|
931
|
+
onConfirm
|
|
932
|
+
}) {
|
|
933
|
+
var _a;
|
|
934
|
+
const RULE_TYPE_LABELS = {
|
|
935
|
+
standard: "Standard Rule",
|
|
936
|
+
handoff: "Hand-off Rule"
|
|
937
|
+
};
|
|
938
|
+
const LABEL_TO_TYPE = {
|
|
939
|
+
"Standard Rule": "standard",
|
|
940
|
+
"Hand-off Rule": "handoff"
|
|
941
|
+
};
|
|
942
|
+
const isEdit = !!rule;
|
|
943
|
+
const [draft, setDraft] = React2.useState((_a = rule == null ? void 0 : rule.text) != null ? _a : "");
|
|
944
|
+
const [ruleType, setRuleType] = React2.useState(
|
|
945
|
+
defaultType
|
|
946
|
+
);
|
|
947
|
+
React2.useEffect(() => {
|
|
948
|
+
var _a2;
|
|
949
|
+
if (open) {
|
|
950
|
+
setDraft((_a2 = rule == null ? void 0 : rule.text) != null ? _a2 : "");
|
|
951
|
+
setRuleType(defaultType);
|
|
952
|
+
}
|
|
953
|
+
}, [open, rule, defaultType]);
|
|
954
|
+
return /* @__PURE__ */ jsx4(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs4(DialogContent, { className: "max-w-lg", children: [
|
|
955
|
+
/* @__PURE__ */ jsx4(DialogHeader, { children: /* @__PURE__ */ jsx4(DialogTitle, { children: isEdit ? "Edit Rule" : "Add Rule" }) }),
|
|
956
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-3 py-2", children: [
|
|
957
|
+
!isEdit && /* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-1.5", children: [
|
|
958
|
+
/* @__PURE__ */ jsxs4(Label, { htmlFor: "rule-type", children: [
|
|
959
|
+
"Rule Type ",
|
|
960
|
+
/* @__PURE__ */ jsx4("span", { className: "text-destructive", children: "*" })
|
|
961
|
+
] }),
|
|
962
|
+
/* @__PURE__ */ jsxs4(
|
|
963
|
+
Select,
|
|
964
|
+
{
|
|
965
|
+
value: RULE_TYPE_LABELS[ruleType],
|
|
966
|
+
onValueChange: (v) => setRuleType(LABEL_TO_TYPE[v]),
|
|
967
|
+
children: [
|
|
968
|
+
/* @__PURE__ */ jsx4(SelectTrigger, { id: "rule-type", className: "w-full", children: /* @__PURE__ */ jsx4(SelectValue, {}) }),
|
|
969
|
+
/* @__PURE__ */ jsxs4(SelectContent, { children: [
|
|
970
|
+
/* @__PURE__ */ jsx4(SelectItem, { value: "Standard Rule", children: "Standard Rule" }),
|
|
971
|
+
/* @__PURE__ */ jsx4(SelectItem, { value: "Hand-off Rule", children: "Hand-off Rule" })
|
|
972
|
+
] })
|
|
973
|
+
]
|
|
974
|
+
}
|
|
975
|
+
)
|
|
976
|
+
] }),
|
|
977
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-1.5", children: [
|
|
978
|
+
/* @__PURE__ */ jsxs4(Label, { htmlFor: "rule-draft", children: [
|
|
979
|
+
"Rule ",
|
|
980
|
+
/* @__PURE__ */ jsx4("span", { className: "text-destructive", children: "*" })
|
|
981
|
+
] }),
|
|
982
|
+
/* @__PURE__ */ jsx4(
|
|
983
|
+
Textarea,
|
|
984
|
+
{
|
|
985
|
+
id: "rule-draft",
|
|
986
|
+
rows: 4,
|
|
987
|
+
placeholder: "Describe the rule the agent should follow\u2026",
|
|
988
|
+
value: draft,
|
|
989
|
+
onChange: (e) => setDraft(e.target.value)
|
|
990
|
+
}
|
|
991
|
+
)
|
|
992
|
+
] })
|
|
993
|
+
] }),
|
|
994
|
+
/* @__PURE__ */ jsxs4(DialogFooter, { children: [
|
|
995
|
+
/* @__PURE__ */ jsx4(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
|
|
996
|
+
/* @__PURE__ */ jsx4(
|
|
997
|
+
Button,
|
|
998
|
+
{
|
|
999
|
+
disabled: !draft.trim(),
|
|
1000
|
+
onClick: () => {
|
|
1001
|
+
onConfirm(draft.trim(), ruleType);
|
|
1002
|
+
onOpenChange(false);
|
|
1003
|
+
},
|
|
1004
|
+
children: isEdit ? "Save" : "Add"
|
|
1005
|
+
}
|
|
1006
|
+
)
|
|
1007
|
+
] })
|
|
1008
|
+
] }) });
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
export {
|
|
1012
|
+
AgentCard,
|
|
1013
|
+
AgentMenuModal,
|
|
1014
|
+
IntegrationServiceCard,
|
|
1015
|
+
IntegrationInstructionCard,
|
|
1016
|
+
ServiceConfigurationModal,
|
|
1017
|
+
SectionHeader,
|
|
1018
|
+
SettingRow,
|
|
1019
|
+
SettingCard,
|
|
1020
|
+
AgentConfigForm,
|
|
1021
|
+
ResponseTemplateEditModal,
|
|
1022
|
+
RuleOrderBadge,
|
|
1023
|
+
RuleSetSection,
|
|
1024
|
+
AddEditRuleModal
|
|
1025
|
+
};
|