@greatapps/greatagents-ui 0.3.12 → 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +50 -68
- package/dist/index.js +1956 -2315
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/agents/agent-tabs.tsx +41 -104
- package/src/components/capabilities/capabilities-tab.tsx +2 -2
- package/src/components/capabilities/integration-card.tsx +3 -21
- package/src/components/capabilities/integrations-tab.tsx +112 -68
- package/src/components/tools/tool-credentials-form.tsx +1 -374
- package/src/pages/agent-capabilities-page.tsx +2 -83
- package/src/pages/credentials-page.tsx +0 -10
- package/src/pages/integrations-management-page.tsx +129 -31
|
@@ -3,8 +3,6 @@ import type { ColumnDef } from "@tanstack/react-table";
|
|
|
3
3
|
import type { Tool, ToolCredential } from "../../types";
|
|
4
4
|
import type { GagentsHookConfig } from "../../hooks/types";
|
|
5
5
|
import {
|
|
6
|
-
useCreateToolCredential,
|
|
7
|
-
useUpdateToolCredential,
|
|
8
6
|
useDeleteToolCredential,
|
|
9
7
|
} from "../../hooks";
|
|
10
8
|
import { useTools } from "../../hooks";
|
|
@@ -16,11 +14,6 @@ import {
|
|
|
16
14
|
Tooltip,
|
|
17
15
|
TooltipTrigger,
|
|
18
16
|
TooltipContent,
|
|
19
|
-
Dialog,
|
|
20
|
-
DialogContent,
|
|
21
|
-
DialogHeader,
|
|
22
|
-
DialogTitle,
|
|
23
|
-
DialogFooter,
|
|
24
17
|
AlertDialog,
|
|
25
18
|
AlertDialogAction,
|
|
26
19
|
AlertDialogCancel,
|
|
@@ -29,13 +22,8 @@ import {
|
|
|
29
22
|
AlertDialogFooter,
|
|
30
23
|
AlertDialogHeader,
|
|
31
24
|
AlertDialogTitle,
|
|
32
|
-
Select,
|
|
33
|
-
SelectContent,
|
|
34
|
-
SelectItem,
|
|
35
|
-
SelectTrigger,
|
|
36
|
-
SelectValue,
|
|
37
25
|
} from "@greatapps/greatauth-ui/ui";
|
|
38
|
-
import { Trash2,
|
|
26
|
+
import { Trash2, Search } from "lucide-react";
|
|
39
27
|
import { format } from "date-fns";
|
|
40
28
|
import { ptBR } from "date-fns/locale";
|
|
41
29
|
import { toast } from "sonner";
|
|
@@ -45,8 +33,6 @@ interface ToolCredentialsFormProps {
|
|
|
45
33
|
isLoading: boolean;
|
|
46
34
|
config: GagentsHookConfig;
|
|
47
35
|
gagentsApiUrl: string;
|
|
48
|
-
createOpen?: boolean;
|
|
49
|
-
onCreateOpenChange?: (open: boolean) => void;
|
|
50
36
|
}
|
|
51
37
|
|
|
52
38
|
function formatDate(dateStr: string | null): string {
|
|
@@ -56,8 +42,6 @@ function formatDate(dateStr: string | null): string {
|
|
|
56
42
|
|
|
57
43
|
function useColumns(
|
|
58
44
|
tools: Tool[],
|
|
59
|
-
onEdit: (cred: ToolCredential) => void,
|
|
60
|
-
onConnect: (cred: ToolCredential) => void,
|
|
61
45
|
onRemove: (cred: ToolCredential) => void,
|
|
62
46
|
): ColumnDef<ToolCredential>[] {
|
|
63
47
|
function getToolName(idTool: number | null): string {
|
|
@@ -66,12 +50,6 @@ function useColumns(
|
|
|
66
50
|
return tool?.name || `Ferramenta #${idTool}`;
|
|
67
51
|
}
|
|
68
52
|
|
|
69
|
-
function getToolType(idTool: number | null): string | null {
|
|
70
|
-
if (!idTool) return null;
|
|
71
|
-
const tool = tools.find((t) => t.id === idTool);
|
|
72
|
-
return tool?.type || null;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
53
|
return [
|
|
76
54
|
{
|
|
77
55
|
accessorKey: "label",
|
|
@@ -123,36 +101,6 @@ function useColumns(
|
|
|
123
101
|
enableSorting: false,
|
|
124
102
|
cell: ({ row }) => (
|
|
125
103
|
<div className="flex items-center gap-1">
|
|
126
|
-
{getToolType(row.original.id_tool) === "oauth2" && (
|
|
127
|
-
<Tooltip>
|
|
128
|
-
<TooltipTrigger asChild>
|
|
129
|
-
<Button
|
|
130
|
-
variant="ghost"
|
|
131
|
-
size="icon"
|
|
132
|
-
className="h-8 w-8"
|
|
133
|
-
aria-label="Vincular"
|
|
134
|
-
disabled
|
|
135
|
-
>
|
|
136
|
-
<Link className="h-4 w-4" />
|
|
137
|
-
</Button>
|
|
138
|
-
</TooltipTrigger>
|
|
139
|
-
<TooltipContent>Em breve</TooltipContent>
|
|
140
|
-
</Tooltip>
|
|
141
|
-
)}
|
|
142
|
-
<Tooltip>
|
|
143
|
-
<TooltipTrigger asChild>
|
|
144
|
-
<Button
|
|
145
|
-
variant="ghost"
|
|
146
|
-
size="icon"
|
|
147
|
-
className="h-8 w-8"
|
|
148
|
-
aria-label="Editar"
|
|
149
|
-
onClick={() => onEdit(row.original)}
|
|
150
|
-
>
|
|
151
|
-
<Pencil className="h-4 w-4" />
|
|
152
|
-
</Button>
|
|
153
|
-
</TooltipTrigger>
|
|
154
|
-
<TooltipContent>Editar</TooltipContent>
|
|
155
|
-
</Tooltip>
|
|
156
104
|
<Tooltip>
|
|
157
105
|
<TooltipTrigger asChild>
|
|
158
106
|
<Button
|
|
@@ -178,35 +126,12 @@ export function ToolCredentialsForm({
|
|
|
178
126
|
isLoading,
|
|
179
127
|
config,
|
|
180
128
|
gagentsApiUrl,
|
|
181
|
-
createOpen: externalCreateOpen,
|
|
182
|
-
onCreateOpenChange,
|
|
183
129
|
}: ToolCredentialsFormProps) {
|
|
184
|
-
const createMutation = useCreateToolCredential(config);
|
|
185
|
-
const updateMutation = useUpdateToolCredential(config);
|
|
186
130
|
const deleteMutation = useDeleteToolCredential(config);
|
|
187
131
|
const { data: toolsData } = useTools(config);
|
|
188
132
|
const tools: Tool[] = (toolsData?.data || []).filter((t: Tool) => !t.slug?.startsWith("gclinic_"));
|
|
189
133
|
|
|
190
134
|
const [search, setSearch] = useState("");
|
|
191
|
-
const [internalCreateOpen, setInternalCreateOpen] = useState(false);
|
|
192
|
-
const showCreateDialog = externalCreateOpen ?? internalCreateOpen;
|
|
193
|
-
const setShowCreateDialog = onCreateOpenChange ?? setInternalCreateOpen;
|
|
194
|
-
const [createForm, setCreateForm] = useState({
|
|
195
|
-
id_tool: "",
|
|
196
|
-
label: "",
|
|
197
|
-
credentials_encrypted: "",
|
|
198
|
-
expires_at: "",
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
const [editTarget, setEditTarget] = useState<ToolCredential | null>(null);
|
|
202
|
-
const [editForm, setEditForm] = useState({
|
|
203
|
-
id_tool: "",
|
|
204
|
-
label: "",
|
|
205
|
-
credentials_encrypted: "",
|
|
206
|
-
expires_at: "",
|
|
207
|
-
status: "" as "active" | "expired" | "",
|
|
208
|
-
});
|
|
209
|
-
|
|
210
135
|
const [removeTarget, setRemoveTarget] = useState<ToolCredential | null>(null);
|
|
211
136
|
|
|
212
137
|
// Build a set of internal tool IDs to exclude from credentials display
|
|
@@ -237,86 +162,9 @@ export function ToolCredentialsForm({
|
|
|
237
162
|
|
|
238
163
|
const columns = useColumns(
|
|
239
164
|
tools,
|
|
240
|
-
(cred) => startEdit(cred),
|
|
241
|
-
(cred) => handleConnect(cred),
|
|
242
165
|
(cred) => setRemoveTarget(cred),
|
|
243
166
|
);
|
|
244
167
|
|
|
245
|
-
async function handleCreate() {
|
|
246
|
-
const idTool = parseInt(createForm.id_tool, 10);
|
|
247
|
-
if (!idTool || !createForm.label.trim() || !createForm.credentials_encrypted.trim()) return;
|
|
248
|
-
|
|
249
|
-
try {
|
|
250
|
-
const result = await createMutation.mutateAsync({
|
|
251
|
-
id_tool: idTool,
|
|
252
|
-
label: createForm.label.trim(),
|
|
253
|
-
credentials_encrypted: createForm.credentials_encrypted.trim(),
|
|
254
|
-
...(createForm.expires_at ? { expires_at: createForm.expires_at } : {}),
|
|
255
|
-
});
|
|
256
|
-
if (result.status === 1) {
|
|
257
|
-
toast.success("Credencial criada");
|
|
258
|
-
setShowCreateDialog(false);
|
|
259
|
-
setCreateForm({ id_tool: "", label: "", credentials_encrypted: "", expires_at: "" });
|
|
260
|
-
} else {
|
|
261
|
-
toast.error(result.message || "Erro ao criar credencial");
|
|
262
|
-
}
|
|
263
|
-
} catch {
|
|
264
|
-
toast.error("Erro ao criar credencial");
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
function startEdit(cred: ToolCredential) {
|
|
269
|
-
setEditTarget(cred);
|
|
270
|
-
setEditForm({
|
|
271
|
-
id_tool: cred.id_tool ? String(cred.id_tool) : "",
|
|
272
|
-
label: cred.label || "",
|
|
273
|
-
credentials_encrypted: "",
|
|
274
|
-
expires_at: cred.expires_at || "",
|
|
275
|
-
status: cred.status,
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
async function handleSaveEdit() {
|
|
280
|
-
if (!editTarget) return;
|
|
281
|
-
const body: Record<string, unknown> = {};
|
|
282
|
-
const newIdTool = editForm.id_tool ? parseInt(editForm.id_tool, 10) : null;
|
|
283
|
-
if (newIdTool && newIdTool !== editTarget.id_tool) {
|
|
284
|
-
body.id_tool = newIdTool;
|
|
285
|
-
}
|
|
286
|
-
if (editForm.label.trim() && editForm.label.trim() !== (editTarget.label || "")) {
|
|
287
|
-
body.label = editForm.label.trim();
|
|
288
|
-
}
|
|
289
|
-
if (editForm.credentials_encrypted.trim()) {
|
|
290
|
-
body.credentials_encrypted = editForm.credentials_encrypted.trim();
|
|
291
|
-
}
|
|
292
|
-
if (editForm.expires_at !== (editTarget.expires_at || "")) {
|
|
293
|
-
body.expires_at = editForm.expires_at || null;
|
|
294
|
-
}
|
|
295
|
-
if (editForm.status && editForm.status !== editTarget.status) {
|
|
296
|
-
body.status = editForm.status;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
if (Object.keys(body).length === 0) {
|
|
300
|
-
setEditTarget(null);
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
try {
|
|
305
|
-
const result = await updateMutation.mutateAsync({
|
|
306
|
-
id: editTarget.id,
|
|
307
|
-
body: body as Parameters<typeof updateMutation.mutateAsync>[0]["body"],
|
|
308
|
-
});
|
|
309
|
-
if (result.status === 1) {
|
|
310
|
-
toast.success("Credencial atualizada");
|
|
311
|
-
setEditTarget(null);
|
|
312
|
-
} else {
|
|
313
|
-
toast.error(result.message || "Erro ao atualizar credencial");
|
|
314
|
-
}
|
|
315
|
-
} catch {
|
|
316
|
-
toast.error("Erro ao atualizar credencial");
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
168
|
async function handleRemove() {
|
|
321
169
|
if (!removeTarget) return;
|
|
322
170
|
try {
|
|
@@ -333,14 +181,6 @@ export function ToolCredentialsForm({
|
|
|
333
181
|
}
|
|
334
182
|
}
|
|
335
183
|
|
|
336
|
-
function handleConnect(cred: ToolCredential) {
|
|
337
|
-
if (!config.accountId || !config.token) return;
|
|
338
|
-
const language = config.language ?? "pt-br";
|
|
339
|
-
const idWl = config.idWl ?? 1;
|
|
340
|
-
const url = `${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${config.accountId}/oauth/connect?id_tool=${cred.id_tool}`;
|
|
341
|
-
window.open(url, "_blank");
|
|
342
|
-
}
|
|
343
|
-
|
|
344
184
|
return (
|
|
345
185
|
<div className="space-y-4">
|
|
346
186
|
<div className="flex items-center gap-3">
|
|
@@ -365,219 +205,6 @@ export function ToolCredentialsForm({
|
|
|
365
205
|
emptyMessage="Nenhuma credencial encontrada"
|
|
366
206
|
/>
|
|
367
207
|
|
|
368
|
-
{/* Create Dialog */}
|
|
369
|
-
<Dialog open={showCreateDialog} onOpenChange={setShowCreateDialog}>
|
|
370
|
-
<DialogContent>
|
|
371
|
-
<DialogHeader>
|
|
372
|
-
<DialogTitle>Nova Credencial</DialogTitle>
|
|
373
|
-
</DialogHeader>
|
|
374
|
-
<div className="space-y-4">
|
|
375
|
-
<div>
|
|
376
|
-
<label htmlFor="cred-tool" className="mb-1 block text-sm font-medium">
|
|
377
|
-
Ferramenta *
|
|
378
|
-
</label>
|
|
379
|
-
<Select
|
|
380
|
-
value={createForm.id_tool}
|
|
381
|
-
onValueChange={(val) =>
|
|
382
|
-
setCreateForm((f) => ({ ...f, id_tool: val }))
|
|
383
|
-
}
|
|
384
|
-
>
|
|
385
|
-
<SelectTrigger id="cred-tool">
|
|
386
|
-
<SelectValue placeholder="Selecione a ferramenta" />
|
|
387
|
-
</SelectTrigger>
|
|
388
|
-
<SelectContent>
|
|
389
|
-
{tools.map((tool) => (
|
|
390
|
-
<SelectItem key={tool.id} value={String(tool.id)}>
|
|
391
|
-
{tool.name}
|
|
392
|
-
</SelectItem>
|
|
393
|
-
))}
|
|
394
|
-
</SelectContent>
|
|
395
|
-
</Select>
|
|
396
|
-
</div>
|
|
397
|
-
<div>
|
|
398
|
-
<label htmlFor="cred-label" className="mb-1 block text-sm font-medium">
|
|
399
|
-
Label *
|
|
400
|
-
</label>
|
|
401
|
-
<Input
|
|
402
|
-
id="cred-label"
|
|
403
|
-
name="label"
|
|
404
|
-
value={createForm.label}
|
|
405
|
-
onChange={(e) =>
|
|
406
|
-
setCreateForm((f) => ({ ...f, label: e.target.value }))
|
|
407
|
-
}
|
|
408
|
-
placeholder="Ex: Google Calendar - Clínica São Paulo"
|
|
409
|
-
/>
|
|
410
|
-
</div>
|
|
411
|
-
<div>
|
|
412
|
-
<label htmlFor="cred-credential" className="mb-1 block text-sm font-medium">
|
|
413
|
-
Credencial *
|
|
414
|
-
</label>
|
|
415
|
-
<Input
|
|
416
|
-
id="cred-credential"
|
|
417
|
-
name="credential"
|
|
418
|
-
autoComplete="off"
|
|
419
|
-
type="password"
|
|
420
|
-
value={createForm.credentials_encrypted}
|
|
421
|
-
onChange={(e) =>
|
|
422
|
-
setCreateForm((f) => ({
|
|
423
|
-
...f,
|
|
424
|
-
credentials_encrypted: e.target.value,
|
|
425
|
-
}))
|
|
426
|
-
}
|
|
427
|
-
placeholder="Credencial encriptada"
|
|
428
|
-
/>
|
|
429
|
-
</div>
|
|
430
|
-
<div>
|
|
431
|
-
<label htmlFor="cred-expires" className="mb-1 block text-sm font-medium">
|
|
432
|
-
Data de Expiração (opcional)
|
|
433
|
-
</label>
|
|
434
|
-
<Input
|
|
435
|
-
id="cred-expires"
|
|
436
|
-
name="expires"
|
|
437
|
-
type="date"
|
|
438
|
-
value={createForm.expires_at}
|
|
439
|
-
onChange={(e) =>
|
|
440
|
-
setCreateForm((f) => ({ ...f, expires_at: e.target.value }))
|
|
441
|
-
}
|
|
442
|
-
/>
|
|
443
|
-
</div>
|
|
444
|
-
</div>
|
|
445
|
-
<DialogFooter>
|
|
446
|
-
<Button
|
|
447
|
-
variant="outline"
|
|
448
|
-
onClick={() => setShowCreateDialog(false)}
|
|
449
|
-
>
|
|
450
|
-
Cancelar
|
|
451
|
-
</Button>
|
|
452
|
-
<Button
|
|
453
|
-
onClick={handleCreate}
|
|
454
|
-
disabled={
|
|
455
|
-
!createForm.id_tool ||
|
|
456
|
-
!createForm.label.trim() ||
|
|
457
|
-
!createForm.credentials_encrypted.trim() ||
|
|
458
|
-
createMutation.isPending
|
|
459
|
-
}
|
|
460
|
-
>
|
|
461
|
-
Criar
|
|
462
|
-
</Button>
|
|
463
|
-
</DialogFooter>
|
|
464
|
-
</DialogContent>
|
|
465
|
-
</Dialog>
|
|
466
|
-
|
|
467
|
-
{/* Edit Dialog */}
|
|
468
|
-
<Dialog
|
|
469
|
-
open={!!editTarget}
|
|
470
|
-
onOpenChange={(open) => !open && setEditTarget(null)}
|
|
471
|
-
>
|
|
472
|
-
<DialogContent>
|
|
473
|
-
<DialogHeader>
|
|
474
|
-
<DialogTitle>Editar Credencial</DialogTitle>
|
|
475
|
-
</DialogHeader>
|
|
476
|
-
<div className="space-y-4">
|
|
477
|
-
<div>
|
|
478
|
-
<label htmlFor="edit-cred-tool" className="mb-1 block text-sm font-medium">
|
|
479
|
-
Ferramenta *
|
|
480
|
-
</label>
|
|
481
|
-
<Select
|
|
482
|
-
value={editForm.id_tool}
|
|
483
|
-
onValueChange={(val) =>
|
|
484
|
-
setEditForm((f) => ({ ...f, id_tool: val }))
|
|
485
|
-
}
|
|
486
|
-
>
|
|
487
|
-
<SelectTrigger id="edit-cred-tool">
|
|
488
|
-
<SelectValue placeholder="Selecione a ferramenta" />
|
|
489
|
-
</SelectTrigger>
|
|
490
|
-
<SelectContent>
|
|
491
|
-
{tools.map((tool) => (
|
|
492
|
-
<SelectItem key={tool.id} value={String(tool.id)}>
|
|
493
|
-
{tool.name}
|
|
494
|
-
</SelectItem>
|
|
495
|
-
))}
|
|
496
|
-
</SelectContent>
|
|
497
|
-
</Select>
|
|
498
|
-
</div>
|
|
499
|
-
<div>
|
|
500
|
-
<label htmlFor="edit-cred-label" className="mb-1 block text-sm font-medium">
|
|
501
|
-
Label
|
|
502
|
-
</label>
|
|
503
|
-
<Input
|
|
504
|
-
id="edit-cred-label"
|
|
505
|
-
name="label"
|
|
506
|
-
value={editForm.label}
|
|
507
|
-
onChange={(e) =>
|
|
508
|
-
setEditForm((f) => ({ ...f, label: e.target.value }))
|
|
509
|
-
}
|
|
510
|
-
placeholder="Label da credencial"
|
|
511
|
-
/>
|
|
512
|
-
</div>
|
|
513
|
-
<div>
|
|
514
|
-
<label htmlFor="edit-cred-credential" className="mb-1 block text-sm font-medium">
|
|
515
|
-
Nova Credencial (vazio = manter atual)
|
|
516
|
-
</label>
|
|
517
|
-
<Input
|
|
518
|
-
id="edit-cred-credential"
|
|
519
|
-
name="credential"
|
|
520
|
-
autoComplete="off"
|
|
521
|
-
type="password"
|
|
522
|
-
value={editForm.credentials_encrypted}
|
|
523
|
-
onChange={(e) =>
|
|
524
|
-
setEditForm((f) => ({
|
|
525
|
-
...f,
|
|
526
|
-
credentials_encrypted: e.target.value,
|
|
527
|
-
}))
|
|
528
|
-
}
|
|
529
|
-
placeholder="Nova credencial"
|
|
530
|
-
/>
|
|
531
|
-
</div>
|
|
532
|
-
<div>
|
|
533
|
-
<label htmlFor="edit-cred-expires" className="mb-1 block text-sm font-medium">
|
|
534
|
-
Data de Expiração
|
|
535
|
-
</label>
|
|
536
|
-
<Input
|
|
537
|
-
id="edit-cred-expires"
|
|
538
|
-
name="expires"
|
|
539
|
-
type="date"
|
|
540
|
-
value={editForm.expires_at}
|
|
541
|
-
onChange={(e) =>
|
|
542
|
-
setEditForm((f) => ({ ...f, expires_at: e.target.value }))
|
|
543
|
-
}
|
|
544
|
-
/>
|
|
545
|
-
</div>
|
|
546
|
-
<div>
|
|
547
|
-
<label htmlFor="edit-cred-status" className="mb-1 block text-sm font-medium">Status</label>
|
|
548
|
-
<Select
|
|
549
|
-
value={editForm.status || undefined}
|
|
550
|
-
onValueChange={(val) =>
|
|
551
|
-
setEditForm((f) => ({
|
|
552
|
-
...f,
|
|
553
|
-
status: val as "active" | "expired",
|
|
554
|
-
}))
|
|
555
|
-
}
|
|
556
|
-
>
|
|
557
|
-
<SelectTrigger id="edit-cred-status">
|
|
558
|
-
<SelectValue />
|
|
559
|
-
</SelectTrigger>
|
|
560
|
-
<SelectContent>
|
|
561
|
-
<SelectItem value="active">Ativo</SelectItem>
|
|
562
|
-
<SelectItem value="expired">Expirado</SelectItem>
|
|
563
|
-
</SelectContent>
|
|
564
|
-
</Select>
|
|
565
|
-
</div>
|
|
566
|
-
</div>
|
|
567
|
-
<DialogFooter>
|
|
568
|
-
<Button variant="outline" onClick={() => setEditTarget(null)}>
|
|
569
|
-
Cancelar
|
|
570
|
-
</Button>
|
|
571
|
-
<Button
|
|
572
|
-
onClick={handleSaveEdit}
|
|
573
|
-
disabled={updateMutation.isPending}
|
|
574
|
-
>
|
|
575
|
-
Salvar
|
|
576
|
-
</Button>
|
|
577
|
-
</DialogFooter>
|
|
578
|
-
</DialogContent>
|
|
579
|
-
</Dialog>
|
|
580
|
-
|
|
581
208
|
{/* Delete confirmation */}
|
|
582
209
|
<AlertDialog
|
|
583
210
|
open={!!removeTarget}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState, useCallback } from "react";
|
|
4
3
|
import {
|
|
5
4
|
Tabs,
|
|
6
5
|
TabsList,
|
|
@@ -10,13 +9,9 @@ import {
|
|
|
10
9
|
import { Blocks, Plug, Settings } from "lucide-react";
|
|
11
10
|
|
|
12
11
|
import type { GagentsHookConfig } from "../hooks/types";
|
|
13
|
-
import type { IntegrationCardData } from "../hooks/use-integrations";
|
|
14
|
-
import type { WizardIntegrationMeta } from "../components/capabilities/types";
|
|
15
12
|
import { CapabilitiesTab } from "../components/capabilities/capabilities-tab";
|
|
16
13
|
import { IntegrationsTab } from "../components/capabilities/integrations-tab";
|
|
17
|
-
import { IntegrationWizard } from "../components/capabilities/integration-wizard";
|
|
18
14
|
import { AdvancedTab } from "../components/capabilities/advanced-tab";
|
|
19
|
-
import type { ConfigOption } from "../components/capabilities/wizard-steps/config-step";
|
|
20
15
|
|
|
21
16
|
// ---------------------------------------------------------------------------
|
|
22
17
|
// Props
|
|
@@ -26,33 +21,6 @@ export interface AgentCapabilitiesPageProps {
|
|
|
26
21
|
config: GagentsHookConfig;
|
|
27
22
|
agentId: number;
|
|
28
23
|
gagentsApiUrl: string;
|
|
29
|
-
/**
|
|
30
|
-
* Resolve wizard metadata for a given integration card.
|
|
31
|
-
* The consuming app provides this so the wizard gets correct
|
|
32
|
-
* capabilities, requirements, and config step flag.
|
|
33
|
-
*/
|
|
34
|
-
resolveWizardMeta?: (card: IntegrationCardData) => WizardIntegrationMeta;
|
|
35
|
-
/**
|
|
36
|
-
* Callback to load config options after OAuth completes
|
|
37
|
-
* (e.g. load Google Calendar list). Forwarded to IntegrationWizard.
|
|
38
|
-
*/
|
|
39
|
-
loadConfigOptions?: (credentialId: number) => Promise<ConfigOption[]>;
|
|
40
|
-
/** Called after wizard completes successfully. */
|
|
41
|
-
onWizardComplete?: () => void;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// ---------------------------------------------------------------------------
|
|
45
|
-
// Default wizard meta resolver
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
|
-
|
|
48
|
-
function defaultResolveWizardMeta(card: IntegrationCardData): WizardIntegrationMeta {
|
|
49
|
-
return {
|
|
50
|
-
capabilities: [
|
|
51
|
-
{ label: card.definition.name, description: card.definition.description },
|
|
52
|
-
],
|
|
53
|
-
requirements: [],
|
|
54
|
-
hasConfigStep: false,
|
|
55
|
-
};
|
|
56
24
|
}
|
|
57
25
|
|
|
58
26
|
// ---------------------------------------------------------------------------
|
|
@@ -63,42 +31,13 @@ export function AgentCapabilitiesPage({
|
|
|
63
31
|
config,
|
|
64
32
|
agentId,
|
|
65
33
|
gagentsApiUrl,
|
|
66
|
-
resolveWizardMeta = defaultResolveWizardMeta,
|
|
67
|
-
loadConfigOptions,
|
|
68
|
-
onWizardComplete,
|
|
69
34
|
}: AgentCapabilitiesPageProps) {
|
|
70
|
-
// Wizard dialog state
|
|
71
|
-
const [wizardOpen, setWizardOpen] = useState(false);
|
|
72
|
-
const [activeCard, setActiveCard] = useState<IntegrationCardData | null>(null);
|
|
73
|
-
|
|
74
|
-
const handleConnect = useCallback(
|
|
75
|
-
(card: IntegrationCardData) => {
|
|
76
|
-
setActiveCard(card);
|
|
77
|
-
setWizardOpen(true);
|
|
78
|
-
},
|
|
79
|
-
[],
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
const handleWizardComplete = useCallback(() => {
|
|
83
|
-
setWizardOpen(false);
|
|
84
|
-
setActiveCard(null);
|
|
85
|
-
onWizardComplete?.();
|
|
86
|
-
}, [onWizardComplete]);
|
|
87
|
-
|
|
88
|
-
const handleWizardOpenChange = useCallback((open: boolean) => {
|
|
89
|
-
setWizardOpen(open);
|
|
90
|
-
if (!open) setActiveCard(null);
|
|
91
|
-
}, []);
|
|
92
|
-
|
|
93
|
-
// Derive wizard meta from active card
|
|
94
|
-
const wizardMeta = activeCard ? resolveWizardMeta(activeCard) : null;
|
|
95
|
-
|
|
96
35
|
return (
|
|
97
36
|
<div className="space-y-4">
|
|
98
37
|
<div>
|
|
99
38
|
<h2 className="text-lg font-semibold">Capacidades e Integrações</h2>
|
|
100
39
|
<p className="text-sm text-muted-foreground">
|
|
101
|
-
Configure o que este agente pode fazer e quais
|
|
40
|
+
Configure o que este agente pode fazer e quais integrações ele utiliza.
|
|
102
41
|
</p>
|
|
103
42
|
</div>
|
|
104
43
|
|
|
@@ -123,11 +62,7 @@ export function AgentCapabilitiesPage({
|
|
|
123
62
|
</TabsContent>
|
|
124
63
|
|
|
125
64
|
<TabsContent value="integracoes" className="mt-4">
|
|
126
|
-
<IntegrationsTab
|
|
127
|
-
config={config}
|
|
128
|
-
agentId={agentId}
|
|
129
|
-
onConnect={handleConnect}
|
|
130
|
-
/>
|
|
65
|
+
<IntegrationsTab config={config} agentId={agentId} />
|
|
131
66
|
</TabsContent>
|
|
132
67
|
|
|
133
68
|
<TabsContent value="avancado" className="mt-4">
|
|
@@ -138,22 +73,6 @@ export function AgentCapabilitiesPage({
|
|
|
138
73
|
/>
|
|
139
74
|
</TabsContent>
|
|
140
75
|
</Tabs>
|
|
141
|
-
|
|
142
|
-
{/* Integration Wizard Dialog */}
|
|
143
|
-
{activeCard && wizardMeta && (
|
|
144
|
-
<IntegrationWizard
|
|
145
|
-
open={wizardOpen}
|
|
146
|
-
onOpenChange={handleWizardOpenChange}
|
|
147
|
-
integration={activeCard.definition}
|
|
148
|
-
meta={wizardMeta}
|
|
149
|
-
agentId={agentId}
|
|
150
|
-
config={config}
|
|
151
|
-
onComplete={handleWizardComplete}
|
|
152
|
-
gagentsApiUrl={gagentsApiUrl}
|
|
153
|
-
existingCredentialId={activeCard.credential?.id}
|
|
154
|
-
loadConfigOptions={loadConfigOptions}
|
|
155
|
-
/>
|
|
156
|
-
)}
|
|
157
76
|
</div>
|
|
158
77
|
);
|
|
159
78
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
1
|
import { useToolCredentials } from "../hooks";
|
|
3
2
|
import { ToolCredentialsForm } from "../components/tools/tool-credentials-form";
|
|
4
|
-
import { Button } from "@greatapps/greatauth-ui/ui";
|
|
5
|
-
import { Plus } from "lucide-react";
|
|
6
3
|
import type { GagentsHookConfig } from "../hooks/types";
|
|
7
4
|
|
|
8
5
|
export interface CredentialsPageProps {
|
|
@@ -20,7 +17,6 @@ export function CredentialsPage({
|
|
|
20
17
|
}: CredentialsPageProps) {
|
|
21
18
|
const { data: credentialsData, isLoading: credentialsLoading } =
|
|
22
19
|
useToolCredentials(config);
|
|
23
|
-
const [createOpen, setCreateOpen] = useState(false);
|
|
24
20
|
|
|
25
21
|
const credentials = credentialsData?.data || [];
|
|
26
22
|
|
|
@@ -31,10 +27,6 @@ export function CredentialsPage({
|
|
|
31
27
|
<h1 className="text-xl font-semibold">{title}</h1>
|
|
32
28
|
<p className="text-sm text-muted-foreground">{subtitle}</p>
|
|
33
29
|
</div>
|
|
34
|
-
<Button onClick={() => setCreateOpen(true)} size="sm">
|
|
35
|
-
<Plus className="mr-2 h-4 w-4" />
|
|
36
|
-
Nova Credencial
|
|
37
|
-
</Button>
|
|
38
30
|
</div>
|
|
39
31
|
|
|
40
32
|
<ToolCredentialsForm
|
|
@@ -42,8 +34,6 @@ export function CredentialsPage({
|
|
|
42
34
|
gagentsApiUrl={gagentsApiUrl}
|
|
43
35
|
credentials={credentials}
|
|
44
36
|
isLoading={credentialsLoading}
|
|
45
|
-
createOpen={createOpen}
|
|
46
|
-
onCreateOpenChange={setCreateOpen}
|
|
47
37
|
/>
|
|
48
38
|
</div>
|
|
49
39
|
);
|