@greatapps/greatagents-ui 0.3.2 → 0.3.4
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 +204 -1
- package/dist/index.js +1797 -125
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +14 -0
- package/src/components/agents/agent-edit-form.tsx +4 -1
- package/src/components/agents/agent-form-dialog.tsx +5 -1
- package/src/components/agents/agent-objectives-list.tsx +15 -6
- package/src/components/agents/agent-prompt-editor.tsx +9 -5
- package/src/components/agents/agent-tabs.tsx +4 -4
- package/src/components/agents/agent-tools-list.tsx +12 -5
- package/src/components/agents/agents-table.tsx +7 -2
- package/src/components/capabilities/advanced-tab.tsx +82 -0
- package/src/components/capabilities/capabilities-tab.tsx +475 -0
- package/src/components/capabilities/integration-card.tsx +162 -0
- package/src/components/capabilities/integration-wizard.tsx +537 -0
- package/src/components/capabilities/integrations-tab.tsx +61 -0
- package/src/components/capabilities/types.ts +48 -0
- package/src/components/capabilities/wizard-steps/config-step.tsx +117 -0
- package/src/components/capabilities/wizard-steps/confirm-step.tsx +123 -0
- package/src/components/capabilities/wizard-steps/credentials-step.tsx +205 -0
- package/src/components/capabilities/wizard-steps/info-step.tsx +78 -0
- package/src/components/conversations/agent-conversations-table.tsx +13 -2
- package/src/components/conversations/conversation-view.tsx +2 -2
- package/src/components/tools/tool-credentials-form.tsx +34 -14
- package/src/components/tools/tool-form-dialog.tsx +9 -5
- package/src/components/tools/tools-table.tsx +8 -3
- package/src/data/integrations-registry.ts +23 -0
- package/src/hooks/index.ts +10 -0
- package/src/hooks/use-capabilities.ts +50 -0
- package/src/hooks/use-integrations.ts +114 -0
- package/src/index.ts +34 -0
- package/src/pages/agent-capabilities-page.tsx +159 -0
- package/src/pages/agent-detail-page.tsx +1 -0
- package/src/pages/index.ts +2 -0
- package/src/pages/integrations-management-page.tsx +166 -0
- package/src/types/capabilities.ts +32 -0
- package/src/types/index.ts +10 -0
package/dist/index.js
CHANGED
|
@@ -88,7 +88,11 @@ function createGagentsClient(config) {
|
|
|
88
88
|
`calendar/disconnect/${encodeURIComponent(externalReference)}`,
|
|
89
89
|
void 0,
|
|
90
90
|
{ provider }
|
|
91
|
-
)
|
|
91
|
+
),
|
|
92
|
+
// --- Capabilities ---
|
|
93
|
+
getCapabilities: (idAccount) => request("GET", idAccount, "capabilities"),
|
|
94
|
+
getAgentCapabilities: (idAccount, idAgent) => request("GET", idAccount, `agents/${idAgent}/capabilities`),
|
|
95
|
+
updateAgentCapabilities: (idAccount, idAgent, body) => request("PUT", idAccount, `agents/${idAgent}/capabilities`, body)
|
|
92
96
|
};
|
|
93
97
|
}
|
|
94
98
|
|
|
@@ -444,8 +448,110 @@ function useGagentsContacts(config, params) {
|
|
|
444
448
|
});
|
|
445
449
|
}
|
|
446
450
|
|
|
451
|
+
// src/hooks/use-capabilities.ts
|
|
452
|
+
import { useQuery as useQuery8, useMutation as useMutation6, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
|
|
453
|
+
function useCapabilities(config) {
|
|
454
|
+
const client = useGagentsClient(config);
|
|
455
|
+
return useQuery8({
|
|
456
|
+
queryKey: ["greatagents", "capabilities", config.accountId],
|
|
457
|
+
queryFn: async () => {
|
|
458
|
+
const res = await client.getCapabilities(config.accountId);
|
|
459
|
+
return res.data ?? { product: null, categories: [] };
|
|
460
|
+
},
|
|
461
|
+
enabled: !!config.token && !!config.accountId
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
function useAgentCapabilities(config, agentId) {
|
|
465
|
+
const client = useGagentsClient(config);
|
|
466
|
+
return useQuery8({
|
|
467
|
+
queryKey: ["greatagents", "agent-capabilities", config.accountId, agentId],
|
|
468
|
+
queryFn: async () => {
|
|
469
|
+
const res = await client.getAgentCapabilities(config.accountId, agentId);
|
|
470
|
+
const d = res.data;
|
|
471
|
+
return Array.isArray(d) ? d : [];
|
|
472
|
+
},
|
|
473
|
+
enabled: !!config.token && !!config.accountId && !!agentId
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function useUpdateAgentCapabilities(config) {
|
|
477
|
+
const client = useGagentsClient(config);
|
|
478
|
+
const queryClient = useQueryClient6();
|
|
479
|
+
return useMutation6({
|
|
480
|
+
mutationFn: ({ agentId, payload }) => client.updateAgentCapabilities(config.accountId, agentId, payload),
|
|
481
|
+
onSuccess: (_data, variables) => {
|
|
482
|
+
queryClient.invalidateQueries({
|
|
483
|
+
queryKey: ["greatagents", "agent-capabilities", config.accountId, variables.agentId]
|
|
484
|
+
});
|
|
485
|
+
queryClient.invalidateQueries({
|
|
486
|
+
queryKey: ["greatagents", "agent-tools"]
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// src/hooks/use-integrations.ts
|
|
493
|
+
import { useMemo as useMemo2 } from "react";
|
|
494
|
+
|
|
495
|
+
// src/data/integrations-registry.ts
|
|
496
|
+
var INTEGRATIONS_REGISTRY = [
|
|
497
|
+
{
|
|
498
|
+
slug: "google_calendar",
|
|
499
|
+
name: "Google Agenda",
|
|
500
|
+
description: "Sincronize agendamentos com o Google Calendar",
|
|
501
|
+
icon: "CalendarSync",
|
|
502
|
+
authType: "oauth2",
|
|
503
|
+
status: "available"
|
|
504
|
+
}
|
|
505
|
+
// Future integrations — add entries here without code changes
|
|
506
|
+
];
|
|
507
|
+
|
|
508
|
+
// src/hooks/use-integrations.ts
|
|
509
|
+
function useIntegrationState(config, agentId) {
|
|
510
|
+
const { data: credentialsData, isLoading: loadingCredentials } = useToolCredentials(config);
|
|
511
|
+
const { data: toolsData, isLoading: loadingTools } = useTools(config);
|
|
512
|
+
const { data: agentToolsData, isLoading: loadingAgentTools } = useAgentTools(
|
|
513
|
+
config,
|
|
514
|
+
agentId ?? 0
|
|
515
|
+
);
|
|
516
|
+
const isLoading = loadingCredentials || loadingTools || loadingAgentTools;
|
|
517
|
+
const cards = useMemo2(() => {
|
|
518
|
+
const credentials = credentialsData?.data ?? [];
|
|
519
|
+
const tools = toolsData?.data ?? [];
|
|
520
|
+
const agentTools = agentToolsData?.data ?? [];
|
|
521
|
+
return INTEGRATIONS_REGISTRY.map((def) => {
|
|
522
|
+
if (def.status === "coming_soon") {
|
|
523
|
+
return {
|
|
524
|
+
definition: def,
|
|
525
|
+
state: "coming_soon",
|
|
526
|
+
credential: null,
|
|
527
|
+
tool: null,
|
|
528
|
+
sharedByAgentsCount: 0,
|
|
529
|
+
linkedToAgent: false
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
const matchedTool = tools.find((t) => t.slug === def.slug) ?? null;
|
|
533
|
+
const matchedCredential = matchedTool ? credentials.find((c) => c.id_tool === matchedTool.id) ?? null : null;
|
|
534
|
+
const linkedToAgent = matchedTool ? agentTools.some((at) => at.id_tool === matchedTool.id) : false;
|
|
535
|
+
const sharedByAgentsCount = matchedCredential ? 1 : 0;
|
|
536
|
+
let state = "available";
|
|
537
|
+
if (matchedCredential) {
|
|
538
|
+
state = matchedCredential.status === "expired" ? "expired" : "connected";
|
|
539
|
+
}
|
|
540
|
+
return {
|
|
541
|
+
definition: def,
|
|
542
|
+
state,
|
|
543
|
+
credential: matchedCredential,
|
|
544
|
+
tool: matchedTool,
|
|
545
|
+
sharedByAgentsCount,
|
|
546
|
+
linkedToAgent
|
|
547
|
+
};
|
|
548
|
+
});
|
|
549
|
+
}, [credentialsData, toolsData, agentToolsData]);
|
|
550
|
+
return { cards, isLoading };
|
|
551
|
+
}
|
|
552
|
+
|
|
447
553
|
// src/components/agents/agents-table.tsx
|
|
448
|
-
import { useMemo as
|
|
554
|
+
import { useMemo as useMemo3, useState } from "react";
|
|
449
555
|
import { DataTable } from "@greatapps/greatauth-ui";
|
|
450
556
|
import {
|
|
451
557
|
Input,
|
|
@@ -504,6 +610,7 @@ function useColumns(onEdit, onDelete) {
|
|
|
504
610
|
variant: "ghost",
|
|
505
611
|
size: "icon",
|
|
506
612
|
className: "h-8 w-8",
|
|
613
|
+
"aria-label": "Editar",
|
|
507
614
|
onClick: () => onEdit(row.original),
|
|
508
615
|
children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
|
|
509
616
|
}
|
|
@@ -517,6 +624,7 @@ function useColumns(onEdit, onDelete) {
|
|
|
517
624
|
variant: "ghost",
|
|
518
625
|
size: "icon",
|
|
519
626
|
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
627
|
+
"aria-label": "Excluir",
|
|
520
628
|
onClick: () => onDelete(row.original.id),
|
|
521
629
|
children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
|
|
522
630
|
}
|
|
@@ -530,7 +638,7 @@ function useColumns(onEdit, onDelete) {
|
|
|
530
638
|
function AgentsTable({ config, onNavigateToAgent }) {
|
|
531
639
|
const [search, setSearch] = useState("");
|
|
532
640
|
const [page, setPage] = useState(1);
|
|
533
|
-
const queryParams =
|
|
641
|
+
const queryParams = useMemo3(() => {
|
|
534
642
|
const params = {
|
|
535
643
|
limit: "15",
|
|
536
644
|
page: String(page)
|
|
@@ -565,11 +673,14 @@ function AgentsTable({ config, onNavigateToAgent }) {
|
|
|
565
673
|
}
|
|
566
674
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
567
675
|
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs("div", { className: "relative flex-1 max-w-md", children: [
|
|
568
|
-
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
676
|
+
/* @__PURE__ */ jsx(Search, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
569
677
|
/* @__PURE__ */ jsx(
|
|
570
678
|
Input,
|
|
571
679
|
{
|
|
572
|
-
placeholder: "Buscar agentes
|
|
680
|
+
placeholder: "Buscar agentes\\u2026",
|
|
681
|
+
"aria-label": "Buscar agentes",
|
|
682
|
+
name: "search",
|
|
683
|
+
autoComplete: "off",
|
|
573
684
|
value: search,
|
|
574
685
|
onChange: (e) => handleSearchChange(e.target.value),
|
|
575
686
|
className: "pl-9"
|
|
@@ -693,6 +804,7 @@ function AgentFormDialog({
|
|
|
693
804
|
Input2,
|
|
694
805
|
{
|
|
695
806
|
id: "agent-photo",
|
|
807
|
+
name: "photo",
|
|
696
808
|
value: photo,
|
|
697
809
|
onChange: (e) => setPhoto(e.target.value),
|
|
698
810
|
placeholder: "https://exemplo.com/foto.jpg",
|
|
@@ -706,6 +818,7 @@ function AgentFormDialog({
|
|
|
706
818
|
Input2,
|
|
707
819
|
{
|
|
708
820
|
id: "agent-title",
|
|
821
|
+
name: "title",
|
|
709
822
|
value: title,
|
|
710
823
|
onChange: (e) => setTitle(e.target.value),
|
|
711
824
|
placeholder: "Ex: Assistente de Agendamento",
|
|
@@ -721,6 +834,7 @@ function AgentFormDialog({
|
|
|
721
834
|
Input2,
|
|
722
835
|
{
|
|
723
836
|
id: "agent-delay",
|
|
837
|
+
name: "delay",
|
|
724
838
|
type: "number",
|
|
725
839
|
value: delayTyping,
|
|
726
840
|
onChange: (e) => setDelayTyping(e.target.value),
|
|
@@ -736,6 +850,7 @@ function AgentFormDialog({
|
|
|
736
850
|
Input2,
|
|
737
851
|
{
|
|
738
852
|
id: "agent-waiting",
|
|
853
|
+
name: "waiting",
|
|
739
854
|
type: "number",
|
|
740
855
|
value: waitingTime,
|
|
741
856
|
onChange: (e) => setWaitingTime(e.target.value),
|
|
@@ -758,7 +873,7 @@ function AgentFormDialog({
|
|
|
758
873
|
}
|
|
759
874
|
),
|
|
760
875
|
/* @__PURE__ */ jsxs2(Button2, { type: "submit", disabled: isPending || !title.trim(), children: [
|
|
761
|
-
isPending ? /* @__PURE__ */ jsx2(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
876
|
+
isPending ? /* @__PURE__ */ jsx2(Loader2, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
762
877
|
isEditing ? "Salvar" : "Criar"
|
|
763
878
|
] })
|
|
764
879
|
] })
|
|
@@ -857,6 +972,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
|
|
|
857
972
|
Input3,
|
|
858
973
|
{
|
|
859
974
|
id: "edit-title",
|
|
975
|
+
name: "title",
|
|
860
976
|
value: form.title,
|
|
861
977
|
onChange: (e) => {
|
|
862
978
|
setForm((prev) => ({
|
|
@@ -890,6 +1006,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
|
|
|
890
1006
|
Input3,
|
|
891
1007
|
{
|
|
892
1008
|
id: "edit-delay",
|
|
1009
|
+
name: "delay",
|
|
893
1010
|
type: "number",
|
|
894
1011
|
value: form.delayTyping,
|
|
895
1012
|
onChange: (e) => updateField("delayTyping", e.target.value),
|
|
@@ -907,6 +1024,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
|
|
|
907
1024
|
Input3,
|
|
908
1025
|
{
|
|
909
1026
|
id: "edit-waiting",
|
|
1027
|
+
name: "waiting",
|
|
910
1028
|
type: "number",
|
|
911
1029
|
value: form.waitingTime,
|
|
912
1030
|
onChange: (e) => updateField("waitingTime", e.target.value),
|
|
@@ -931,7 +1049,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
|
|
|
931
1049
|
}
|
|
932
1050
|
),
|
|
933
1051
|
/* @__PURE__ */ jsxs3(Button3, { type: "submit", disabled: updateAgent.isPending, children: [
|
|
934
|
-
updateAgent.isPending && /* @__PURE__ */ jsx3(Loader22, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
1052
|
+
updateAgent.isPending && /* @__PURE__ */ jsx3(Loader22, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }),
|
|
935
1053
|
"Salvar"
|
|
936
1054
|
] })
|
|
937
1055
|
] })
|
|
@@ -1100,7 +1218,9 @@ function AgentToolsList({ agent, config }) {
|
|
|
1100
1218
|
/* @__PURE__ */ jsx4("div", { className: "p-2", children: /* @__PURE__ */ jsx4(
|
|
1101
1219
|
Input4,
|
|
1102
1220
|
{
|
|
1103
|
-
placeholder: "Buscar ferramenta
|
|
1221
|
+
placeholder: "Buscar ferramenta\\u2026",
|
|
1222
|
+
"aria-label": "Buscar ferramenta",
|
|
1223
|
+
name: "search",
|
|
1104
1224
|
value: search,
|
|
1105
1225
|
onChange: (e) => setSearch(e.target.value),
|
|
1106
1226
|
className: "h-8"
|
|
@@ -1144,6 +1264,7 @@ function AgentToolsList({ agent, config }) {
|
|
|
1144
1264
|
/* @__PURE__ */ jsx4(
|
|
1145
1265
|
Switch2,
|
|
1146
1266
|
{
|
|
1267
|
+
"aria-label": "Ativar/Desativar",
|
|
1147
1268
|
checked: agentTool.enabled,
|
|
1148
1269
|
onCheckedChange: (checked) => handleToggleEnabled(agentTool, checked),
|
|
1149
1270
|
disabled: updateMutation.isPending
|
|
@@ -1154,6 +1275,7 @@ function AgentToolsList({ agent, config }) {
|
|
|
1154
1275
|
{
|
|
1155
1276
|
variant: "ghost",
|
|
1156
1277
|
size: "icon",
|
|
1278
|
+
"aria-label": "Configurar",
|
|
1157
1279
|
className: "shrink-0 text-muted-foreground hover:text-foreground",
|
|
1158
1280
|
onClick: () => openConfig(agentTool),
|
|
1159
1281
|
title: "Configurar instru\xE7\xF5es",
|
|
@@ -1165,6 +1287,7 @@ function AgentToolsList({ agent, config }) {
|
|
|
1165
1287
|
{
|
|
1166
1288
|
variant: "ghost",
|
|
1167
1289
|
size: "icon",
|
|
1290
|
+
"aria-label": "Remover",
|
|
1168
1291
|
className: "shrink-0 text-muted-foreground hover:text-destructive",
|
|
1169
1292
|
onClick: () => setRemoveTarget(agentTool),
|
|
1170
1293
|
children: /* @__PURE__ */ jsx4(Trash22, { className: "h-4 w-4" })
|
|
@@ -1184,14 +1307,14 @@ function AgentToolsList({ agent, config }) {
|
|
|
1184
1307
|
/* @__PURE__ */ jsx4(DialogHeader3, { children: /* @__PURE__ */ jsx4(DialogTitle3, { children: "Instru\xE7\xF5es da Ferramenta" }) }),
|
|
1185
1308
|
/* @__PURE__ */ jsxs4("div", { className: "space-y-4", children: [
|
|
1186
1309
|
configTarget && getToolInfo(configTarget.id_tool)?.type !== "none" && /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
1187
|
-
/* @__PURE__ */ jsx4(Label3, { children: "Credencial" }),
|
|
1310
|
+
/* @__PURE__ */ jsx4(Label3, { htmlFor: "tool-credential", children: "Credencial" }),
|
|
1188
1311
|
/* @__PURE__ */ jsxs4(
|
|
1189
1312
|
Select,
|
|
1190
1313
|
{
|
|
1191
1314
|
value: configCredentialId || void 0,
|
|
1192
1315
|
onValueChange: (val) => setConfigCredentialId(val === "__none__" ? "" : val),
|
|
1193
1316
|
children: [
|
|
1194
|
-
/* @__PURE__ */ jsx4(SelectTrigger, { children: /* @__PURE__ */ jsx4(SelectValue, { placeholder: "Selecione uma credencial (opcional)" }) }),
|
|
1317
|
+
/* @__PURE__ */ jsx4(SelectTrigger, { id: "tool-credential", children: /* @__PURE__ */ jsx4(SelectValue, { placeholder: "Selecione uma credencial (opcional)" }) }),
|
|
1195
1318
|
/* @__PURE__ */ jsxs4(SelectContent, { children: [
|
|
1196
1319
|
/* @__PURE__ */ jsx4(SelectItem, { value: "__none__", children: "Nenhuma (autom\xE1tico)" }),
|
|
1197
1320
|
allCredentials.filter((c) => configTarget && c.id_tool === configTarget.id_tool && c.status === "active").map((c) => /* @__PURE__ */ jsx4(SelectItem, { value: String(c.id), children: c.label || `Credencial #${c.id}` }, c.id))
|
|
@@ -1202,13 +1325,15 @@ function AgentToolsList({ agent, config }) {
|
|
|
1202
1325
|
/* @__PURE__ */ jsx4("p", { className: "text-xs text-muted-foreground", children: "Vincule uma credencial espec\xEDfica a esta ferramenta neste agente." })
|
|
1203
1326
|
] }),
|
|
1204
1327
|
/* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
1205
|
-
/* @__PURE__ */ jsx4(Label3, { children: "Instru\xE7\xF5es Personalizadas" }),
|
|
1328
|
+
/* @__PURE__ */ jsx4(Label3, { htmlFor: "tool-instructions", children: "Instru\xE7\xF5es Personalizadas" }),
|
|
1206
1329
|
/* @__PURE__ */ jsx4(
|
|
1207
1330
|
Textarea,
|
|
1208
1331
|
{
|
|
1332
|
+
id: "tool-instructions",
|
|
1333
|
+
name: "instructions",
|
|
1209
1334
|
value: configInstructions,
|
|
1210
1335
|
onChange: (e) => setConfigInstructions(e.target.value),
|
|
1211
|
-
placeholder: "Instru
|
|
1336
|
+
placeholder: "Instru\\u00e7\\u00f5es sobre como e quando o agente deve usar esta ferramenta\\u2026",
|
|
1212
1337
|
rows: 6
|
|
1213
1338
|
}
|
|
1214
1339
|
),
|
|
@@ -1903,7 +2028,7 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1903
2028
|
value: objective.id,
|
|
1904
2029
|
className: "flex items-center gap-3 rounded-lg border bg-card p-3",
|
|
1905
2030
|
children: [
|
|
1906
|
-
/* @__PURE__ */ jsx6(SortableItemHandle, { className: "shrink-0 text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ jsx6(GripVertical, { className: "h-5 w-5" }) }),
|
|
2031
|
+
/* @__PURE__ */ jsx6(SortableItemHandle, { className: "shrink-0 text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ jsx6(GripVertical, { "aria-hidden": "true", className: "h-5 w-5" }) }),
|
|
1907
2032
|
/* @__PURE__ */ jsxs5("div", { className: "flex flex-1 flex-col gap-1 min-w-0", children: [
|
|
1908
2033
|
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
|
|
1909
2034
|
/* @__PURE__ */ jsx6("span", { className: "truncate font-medium", children: objective.title }),
|
|
@@ -1914,6 +2039,7 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1914
2039
|
/* @__PURE__ */ jsx6(
|
|
1915
2040
|
Switch3,
|
|
1916
2041
|
{
|
|
2042
|
+
"aria-label": "Ativar/Desativar",
|
|
1917
2043
|
checked: objective.active,
|
|
1918
2044
|
onCheckedChange: (checked) => handleToggleActive(objective, checked),
|
|
1919
2045
|
disabled: updateMutation.isPending
|
|
@@ -1924,6 +2050,7 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1924
2050
|
{
|
|
1925
2051
|
variant: "ghost",
|
|
1926
2052
|
size: "icon",
|
|
2053
|
+
"aria-label": "Editar",
|
|
1927
2054
|
className: "shrink-0 text-muted-foreground hover:text-foreground",
|
|
1928
2055
|
onClick: () => openEdit(objective),
|
|
1929
2056
|
children: /* @__PURE__ */ jsx6(Pencil2, { className: "h-4 w-4" })
|
|
@@ -1934,6 +2061,7 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1934
2061
|
{
|
|
1935
2062
|
variant: "ghost",
|
|
1936
2063
|
size: "icon",
|
|
2064
|
+
"aria-label": "Excluir",
|
|
1937
2065
|
className: "shrink-0 text-muted-foreground hover:text-destructive",
|
|
1938
2066
|
onClick: () => setRemoveTarget(objective),
|
|
1939
2067
|
children: /* @__PURE__ */ jsx6(Trash23, { className: "h-4 w-4" })
|
|
@@ -1946,7 +2074,7 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1946
2074
|
/* @__PURE__ */ jsx6(SortableOverlay, { children: ({ value }) => {
|
|
1947
2075
|
const obj = sortedObjectives.find((o) => o.id === value);
|
|
1948
2076
|
return /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3 rounded-lg border bg-card p-3 shadow-lg", children: [
|
|
1949
|
-
/* @__PURE__ */ jsx6(GripVertical, { className: "h-5 w-5 text-muted-foreground" }),
|
|
2077
|
+
/* @__PURE__ */ jsx6(GripVertical, { "aria-hidden": "true", className: "h-5 w-5 text-muted-foreground" }),
|
|
1950
2078
|
/* @__PURE__ */ jsx6("span", { className: "font-medium", children: obj?.title })
|
|
1951
2079
|
] });
|
|
1952
2080
|
} })
|
|
@@ -1957,10 +2085,12 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1957
2085
|
/* @__PURE__ */ jsx6(DialogHeader4, { children: /* @__PURE__ */ jsx6(DialogTitle4, { children: editTarget ? "Editar Objetivo" : "Novo Objetivo" }) }),
|
|
1958
2086
|
/* @__PURE__ */ jsxs5("div", { className: "space-y-4", children: [
|
|
1959
2087
|
/* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
|
|
1960
|
-
/* @__PURE__ */ jsx6(Label4, { children: "T\xEDtulo *" }),
|
|
2088
|
+
/* @__PURE__ */ jsx6(Label4, { htmlFor: "objective-title", children: "T\xEDtulo *" }),
|
|
1961
2089
|
/* @__PURE__ */ jsx6(
|
|
1962
2090
|
Input5,
|
|
1963
2091
|
{
|
|
2092
|
+
id: "objective-title",
|
|
2093
|
+
name: "title",
|
|
1964
2094
|
value: form.title,
|
|
1965
2095
|
onChange: (e) => {
|
|
1966
2096
|
const title = e.target.value;
|
|
@@ -1975,10 +2105,12 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1975
2105
|
)
|
|
1976
2106
|
] }),
|
|
1977
2107
|
/* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
|
|
1978
|
-
/* @__PURE__ */ jsx6(Label4, { children: "Slug (identificador) *" }),
|
|
2108
|
+
/* @__PURE__ */ jsx6(Label4, { htmlFor: "objective-slug", children: "Slug (identificador) *" }),
|
|
1979
2109
|
/* @__PURE__ */ jsx6(
|
|
1980
2110
|
Input5,
|
|
1981
2111
|
{
|
|
2112
|
+
id: "objective-slug",
|
|
2113
|
+
name: "slug",
|
|
1982
2114
|
value: form.slug,
|
|
1983
2115
|
onChange: (e) => {
|
|
1984
2116
|
setSlugManual(true);
|
|
@@ -1991,13 +2123,15 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1991
2123
|
/* @__PURE__ */ jsx6("p", { className: "text-xs text-muted-foreground", children: "Gerado automaticamente. Usado pelo agente para identificar o objetivo." })
|
|
1992
2124
|
] }),
|
|
1993
2125
|
/* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
|
|
1994
|
-
/* @__PURE__ */ jsx6(Label4, { children: "Instru\xE7\xF5es do Objetivo" }),
|
|
2126
|
+
/* @__PURE__ */ jsx6(Label4, { htmlFor: "objective-prompt", children: "Instru\xE7\xF5es do Objetivo" }),
|
|
1995
2127
|
/* @__PURE__ */ jsx6(
|
|
1996
2128
|
Textarea2,
|
|
1997
2129
|
{
|
|
2130
|
+
id: "objective-prompt",
|
|
2131
|
+
name: "prompt",
|
|
1998
2132
|
value: form.prompt,
|
|
1999
2133
|
onChange: (e) => setForm((f) => ({ ...f, prompt: e.target.value })),
|
|
2000
|
-
placeholder: "Instru
|
|
2134
|
+
placeholder: "Instru\\u00e7\\u00f5es detalhadas que o agente seguir\\u00e1 quando este objetivo for ativado\\u2026",
|
|
2001
2135
|
rows: 8
|
|
2002
2136
|
}
|
|
2003
2137
|
),
|
|
@@ -2206,22 +2340,24 @@ function AgentPromptEditor({ config, agent }) {
|
|
|
2206
2340
|
"textarea",
|
|
2207
2341
|
{
|
|
2208
2342
|
ref: textareaRef,
|
|
2343
|
+
"aria-label": "Prompt do sistema",
|
|
2344
|
+
name: "prompt",
|
|
2209
2345
|
value: promptText,
|
|
2210
2346
|
onChange: (e) => setPromptText(e.target.value),
|
|
2211
2347
|
onKeyDown: handleKeyDown,
|
|
2212
|
-
placeholder: "Escreva o prompt do sistema aqui
|
|
2348
|
+
placeholder: "Escreva o prompt do sistema aqui\\u2026",
|
|
2213
2349
|
disabled: updateAgent.isPending,
|
|
2214
2350
|
className: "w-full resize-none rounded-lg border bg-background p-3 font-mono text-sm leading-relaxed focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50",
|
|
2215
2351
|
style: { minHeight: "300px" }
|
|
2216
2352
|
}
|
|
2217
2353
|
),
|
|
2218
2354
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
|
|
2219
|
-
/* @__PURE__ */ jsxs6("span", { children: [
|
|
2355
|
+
/* @__PURE__ */ jsxs6("span", { className: "tabular-nums", children: [
|
|
2220
2356
|
charCount.toLocaleString("pt-BR"),
|
|
2221
2357
|
" caracteres"
|
|
2222
2358
|
] }),
|
|
2223
2359
|
/* @__PURE__ */ jsx7("span", { children: "\xB7" }),
|
|
2224
|
-
/* @__PURE__ */ jsxs6("span", { children: [
|
|
2360
|
+
/* @__PURE__ */ jsxs6("span", { className: "tabular-nums", children: [
|
|
2225
2361
|
"~",
|
|
2226
2362
|
tokenEstimate.toLocaleString("pt-BR"),
|
|
2227
2363
|
" tokens"
|
|
@@ -2232,6 +2368,8 @@ function AgentPromptEditor({ config, agent }) {
|
|
|
2232
2368
|
/* @__PURE__ */ jsx7(
|
|
2233
2369
|
Input6,
|
|
2234
2370
|
{
|
|
2371
|
+
"aria-label": "Notas da altera\xE7\xE3o",
|
|
2372
|
+
name: "changeNotes",
|
|
2235
2373
|
value: changeNotes,
|
|
2236
2374
|
onChange: (e) => setChangeNotes(e.target.value),
|
|
2237
2375
|
placeholder: "O que mudou? (opcional)",
|
|
@@ -2356,7 +2494,7 @@ function AgentPromptEditor({ config, agent }) {
|
|
|
2356
2494
|
onClick: () => setCompareVersionId(isComparing ? null : version.id),
|
|
2357
2495
|
className: "flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground",
|
|
2358
2496
|
children: [
|
|
2359
|
-
/* @__PURE__ */ jsx7(FileText, { className: "h-3 w-3" }),
|
|
2497
|
+
/* @__PURE__ */ jsx7(FileText, { "aria-hidden": "true", className: "h-3 w-3" }),
|
|
2360
2498
|
isComparing ? "Ocultar diff" : "Comparar"
|
|
2361
2499
|
]
|
|
2362
2500
|
}
|
|
@@ -2368,7 +2506,7 @@ function AgentPromptEditor({ config, agent }) {
|
|
|
2368
2506
|
onClick: () => handleRestore(version),
|
|
2369
2507
|
className: "flex items-center gap-1 text-xs text-primary hover:underline",
|
|
2370
2508
|
children: [
|
|
2371
|
-
/* @__PURE__ */ jsx7(RotateCcw, { className: "h-3 w-3" }),
|
|
2509
|
+
/* @__PURE__ */ jsx7(RotateCcw, { "aria-hidden": "true", className: "h-3 w-3" }),
|
|
2372
2510
|
"Restaurar"
|
|
2373
2511
|
]
|
|
2374
2512
|
}
|
|
@@ -2422,7 +2560,7 @@ function ConversationView({
|
|
|
2422
2560
|
if (!conversation) {
|
|
2423
2561
|
return /* @__PURE__ */ jsx8("div", { className: "rounded-lg border bg-card p-4", children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between", children: [
|
|
2424
2562
|
/* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: "Conversa n\xE3o encontrada." }),
|
|
2425
|
-
/* @__PURE__ */ jsx8(Button7, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx8(X, { className: "h-4 w-4" }) })
|
|
2563
|
+
/* @__PURE__ */ jsx8(Button7, { variant: "ghost", size: "icon", "aria-label": "Fechar", onClick: onClose, children: /* @__PURE__ */ jsx8(X, { className: "h-4 w-4" }) })
|
|
2426
2564
|
] }) });
|
|
2427
2565
|
}
|
|
2428
2566
|
return /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border bg-card p-4 space-y-4", children: [
|
|
@@ -2431,7 +2569,7 @@ function ConversationView({
|
|
|
2431
2569
|
"Detalhes da conversa #",
|
|
2432
2570
|
conversation.id
|
|
2433
2571
|
] }),
|
|
2434
|
-
/* @__PURE__ */ jsx8("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsx8(Button7, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx8(X, { className: "h-4 w-4" }) }) })
|
|
2572
|
+
/* @__PURE__ */ jsx8("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsx8(Button7, { variant: "ghost", size: "icon", "aria-label": "Fechar", onClick: onClose, children: /* @__PURE__ */ jsx8(X, { className: "h-4 w-4" }) }) })
|
|
2435
2573
|
] }),
|
|
2436
2574
|
conversation.id_external ? renderChatLink ? renderChatLink(conversation.id_external) : /* @__PURE__ */ jsx8(Button7, { variant: "outline", size: "sm", asChild: true, children: /* @__PURE__ */ jsxs7("a", { href: `/gchat/inbox/${conversation.id_external}`, children: [
|
|
2437
2575
|
/* @__PURE__ */ jsx8(MessageSquare, { className: "mr-2 h-4 w-4" }),
|
|
@@ -2524,16 +2662,26 @@ function AgentConversationsTable({
|
|
|
2524
2662
|
TableRow,
|
|
2525
2663
|
{
|
|
2526
2664
|
className: "cursor-pointer",
|
|
2665
|
+
role: "button",
|
|
2666
|
+
tabIndex: 0,
|
|
2527
2667
|
onClick: () => setSelectedId(
|
|
2528
2668
|
selectedId === conversation.id ? null : conversation.id
|
|
2529
2669
|
),
|
|
2670
|
+
onKeyDown: (e) => {
|
|
2671
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2672
|
+
e.preventDefault();
|
|
2673
|
+
setSelectedId(
|
|
2674
|
+
selectedId === conversation.id ? null : conversation.id
|
|
2675
|
+
);
|
|
2676
|
+
}
|
|
2677
|
+
},
|
|
2530
2678
|
"data-state": selectedId === conversation.id ? "selected" : void 0,
|
|
2531
2679
|
children: [
|
|
2532
2680
|
/* @__PURE__ */ jsx9(TableCell, { className: "font-mono text-xs", children: conversation.id }),
|
|
2533
2681
|
/* @__PURE__ */ jsx9(TableCell, { children: contactsMap?.get(conversation.id_contact) ?? conversation.id_contact }),
|
|
2534
2682
|
/* @__PURE__ */ jsx9(TableCell, { children: conversation.id_objective && objectivesMap?.get(conversation.id_objective) ? /* @__PURE__ */ jsx9(Badge5, { variant: "secondary", className: "text-xs", children: objectivesMap.get(conversation.id_objective) }) : /* @__PURE__ */ jsx9("span", { className: "text-xs text-muted-foreground", children: "\u2014" }) }),
|
|
2535
|
-
/* @__PURE__ */ jsx9(TableCell, { className: "text-right", children: conversation.message_count ?? "\u2014" }),
|
|
2536
|
-
/* @__PURE__ */ jsx9(TableCell, { className: "text-right", children: conversation.usage_tokens ?? "\u2014" }),
|
|
2683
|
+
/* @__PURE__ */ jsx9(TableCell, { className: "text-right tabular-nums", children: conversation.message_count ?? "\u2014" }),
|
|
2684
|
+
/* @__PURE__ */ jsx9(TableCell, { className: "text-right tabular-nums", children: conversation.usage_tokens ?? "\u2014" }),
|
|
2537
2685
|
/* @__PURE__ */ jsx9(TableCell, { children: new Date(conversation.datetime_add).toLocaleDateString("pt-BR") }),
|
|
2538
2686
|
/* @__PURE__ */ jsx9(TableCell, { children: formatRelativeDate(conversation.datetime_alt) }),
|
|
2539
2687
|
/* @__PURE__ */ jsx9(TableCell, { children: conversation.id_external ? renderChatLink ? /* @__PURE__ */ jsx9("span", { onClick: (e) => e.stopPropagation(), children: renderChatLink(conversation.id_external) }) : /* @__PURE__ */ jsx9(
|
|
@@ -2541,6 +2689,7 @@ function AgentConversationsTable({
|
|
|
2541
2689
|
{
|
|
2542
2690
|
href: `/gchat/inbox/${conversation.id_external}`,
|
|
2543
2691
|
title: "Ver no Chat",
|
|
2692
|
+
"aria-label": "Ver no Chat",
|
|
2544
2693
|
onClick: (e) => e.stopPropagation(),
|
|
2545
2694
|
className: "inline-flex items-center justify-center rounded-md p-1.5 text-muted-foreground hover:text-foreground hover:bg-accent transition-colors",
|
|
2546
2695
|
children: /* @__PURE__ */ jsx9(ExternalLink, { className: "h-4 w-4" })
|
|
@@ -2610,19 +2759,19 @@ function AgentTabs({ agent, config, renderChatLink }) {
|
|
|
2610
2759
|
return /* @__PURE__ */ jsxs9(Tabs, { defaultValue: "prompt", children: [
|
|
2611
2760
|
/* @__PURE__ */ jsxs9(TabsList, { children: [
|
|
2612
2761
|
/* @__PURE__ */ jsxs9(TabsTrigger, { value: "prompt", className: "flex items-center gap-1.5", children: [
|
|
2613
|
-
/* @__PURE__ */ jsx11(FileText2, { className: "h-3.5 w-3.5" }),
|
|
2762
|
+
/* @__PURE__ */ jsx11(FileText2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
2614
2763
|
"Prompt"
|
|
2615
2764
|
] }),
|
|
2616
2765
|
/* @__PURE__ */ jsxs9(TabsTrigger, { value: "objetivos", className: "flex items-center gap-1.5", children: [
|
|
2617
|
-
/* @__PURE__ */ jsx11(Target2, { className: "h-3.5 w-3.5" }),
|
|
2766
|
+
/* @__PURE__ */ jsx11(Target2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
2618
2767
|
"Objetivos"
|
|
2619
2768
|
] }),
|
|
2620
2769
|
/* @__PURE__ */ jsxs9(TabsTrigger, { value: "ferramentas", className: "flex items-center gap-1.5", children: [
|
|
2621
|
-
/* @__PURE__ */ jsx11(Wrench2, { className: "h-3.5 w-3.5" }),
|
|
2770
|
+
/* @__PURE__ */ jsx11(Wrench2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
2622
2771
|
"Ferramentas"
|
|
2623
2772
|
] }),
|
|
2624
2773
|
/* @__PURE__ */ jsxs9(TabsTrigger, { value: "conversas", className: "flex items-center gap-1.5", children: [
|
|
2625
|
-
/* @__PURE__ */ jsx11(MessageCircle2, { className: "h-3.5 w-3.5" }),
|
|
2774
|
+
/* @__PURE__ */ jsx11(MessageCircle2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
2626
2775
|
"Conversas"
|
|
2627
2776
|
] })
|
|
2628
2777
|
] }),
|
|
@@ -2641,7 +2790,7 @@ function AgentTabs({ agent, config, renderChatLink }) {
|
|
|
2641
2790
|
}
|
|
2642
2791
|
|
|
2643
2792
|
// src/components/tools/tools-table.tsx
|
|
2644
|
-
import { useMemo as
|
|
2793
|
+
import { useMemo as useMemo5, useState as useState9 } from "react";
|
|
2645
2794
|
import { DataTable as DataTable2 } from "@greatapps/greatauth-ui";
|
|
2646
2795
|
import {
|
|
2647
2796
|
Input as Input7,
|
|
@@ -2688,7 +2837,7 @@ function useColumns2(onEdit, onDelete) {
|
|
|
2688
2837
|
cell: ({ row }) => {
|
|
2689
2838
|
const desc = row.original.description;
|
|
2690
2839
|
if (!desc) return /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm", children: "\u2014" });
|
|
2691
|
-
return /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm", children: desc.length > 50 ? `${desc.slice(0, 50)}
|
|
2840
|
+
return /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm", children: desc.length > 50 ? `${desc.slice(0, 50)}\u2026` : desc });
|
|
2692
2841
|
}
|
|
2693
2842
|
},
|
|
2694
2843
|
{
|
|
@@ -2710,6 +2859,7 @@ function useColumns2(onEdit, onDelete) {
|
|
|
2710
2859
|
variant: "ghost",
|
|
2711
2860
|
size: "icon",
|
|
2712
2861
|
className: "h-8 w-8",
|
|
2862
|
+
"aria-label": "Editar",
|
|
2713
2863
|
onClick: () => onEdit(row.original),
|
|
2714
2864
|
children: /* @__PURE__ */ jsx12(Pencil3, { className: "h-4 w-4" })
|
|
2715
2865
|
}
|
|
@@ -2723,6 +2873,7 @@ function useColumns2(onEdit, onDelete) {
|
|
|
2723
2873
|
variant: "ghost",
|
|
2724
2874
|
size: "icon",
|
|
2725
2875
|
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
2876
|
+
"aria-label": "Excluir",
|
|
2726
2877
|
onClick: () => onDelete(row.original.id),
|
|
2727
2878
|
children: /* @__PURE__ */ jsx12(Trash24, { className: "h-4 w-4" })
|
|
2728
2879
|
}
|
|
@@ -2736,7 +2887,7 @@ function useColumns2(onEdit, onDelete) {
|
|
|
2736
2887
|
function ToolsTable({ onEdit, config }) {
|
|
2737
2888
|
const [search, setSearch] = useState9("");
|
|
2738
2889
|
const [page, setPage] = useState9(1);
|
|
2739
|
-
const queryParams =
|
|
2890
|
+
const queryParams = useMemo5(() => {
|
|
2740
2891
|
const params = {
|
|
2741
2892
|
limit: "15",
|
|
2742
2893
|
page: String(page)
|
|
@@ -2771,11 +2922,14 @@ function ToolsTable({ onEdit, config }) {
|
|
|
2771
2922
|
}
|
|
2772
2923
|
return /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
2773
2924
|
/* @__PURE__ */ jsx12("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs10("div", { className: "relative flex-1 max-w-md", children: [
|
|
2774
|
-
/* @__PURE__ */ jsx12(Search2, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2925
|
+
/* @__PURE__ */ jsx12(Search2, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2775
2926
|
/* @__PURE__ */ jsx12(
|
|
2776
2927
|
Input7,
|
|
2777
2928
|
{
|
|
2778
|
-
placeholder: "Buscar ferramentas
|
|
2929
|
+
placeholder: "Buscar ferramentas\\u2026",
|
|
2930
|
+
"aria-label": "Buscar ferramentas",
|
|
2931
|
+
name: "search",
|
|
2932
|
+
autoComplete: "off",
|
|
2779
2933
|
value: search,
|
|
2780
2934
|
onChange: (e) => handleSearchChange(e.target.value),
|
|
2781
2935
|
className: "pl-9"
|
|
@@ -2963,6 +3117,7 @@ function ToolFormDialog({
|
|
|
2963
3117
|
Input8,
|
|
2964
3118
|
{
|
|
2965
3119
|
id: "tool-name",
|
|
3120
|
+
name: "name",
|
|
2966
3121
|
value: form.name,
|
|
2967
3122
|
onChange: (e) => {
|
|
2968
3123
|
const name = e.target.value;
|
|
@@ -2985,6 +3140,7 @@ function ToolFormDialog({
|
|
|
2985
3140
|
Input8,
|
|
2986
3141
|
{
|
|
2987
3142
|
id: "tool-slug",
|
|
3143
|
+
name: "slug",
|
|
2988
3144
|
value: form.slug,
|
|
2989
3145
|
onChange: (e) => {
|
|
2990
3146
|
setSlugManuallyEdited(true);
|
|
@@ -3030,9 +3186,10 @@ function ToolFormDialog({
|
|
|
3030
3186
|
Textarea3,
|
|
3031
3187
|
{
|
|
3032
3188
|
id: "tool-description",
|
|
3189
|
+
name: "description",
|
|
3033
3190
|
value: form.description,
|
|
3034
3191
|
onChange: (e) => setForm((prev) => ({ ...prev, description: e.target.value })),
|
|
3035
|
-
placeholder: "Descri
|
|
3192
|
+
placeholder: "Descri\\u00e7\\u00e3o da ferramenta\\u2026",
|
|
3036
3193
|
rows: 3,
|
|
3037
3194
|
disabled: isPending
|
|
3038
3195
|
}
|
|
@@ -3044,6 +3201,7 @@ function ToolFormDialog({
|
|
|
3044
3201
|
Textarea3,
|
|
3045
3202
|
{
|
|
3046
3203
|
id: "tool-function-defs",
|
|
3204
|
+
name: "functionDefs",
|
|
3047
3205
|
value: form.functionDefinitions,
|
|
3048
3206
|
onChange: (e) => {
|
|
3049
3207
|
setForm((prev) => ({
|
|
@@ -3060,8 +3218,8 @@ function ToolFormDialog({
|
|
|
3060
3218
|
"description": "O que a fun\xE7\xE3o faz",
|
|
3061
3219
|
"parameters": {
|
|
3062
3220
|
"type": "object",
|
|
3063
|
-
"properties": {
|
|
3064
|
-
"required": [
|
|
3221
|
+
"properties": { \u2026 },
|
|
3222
|
+
"required": [\u2026]
|
|
3065
3223
|
}
|
|
3066
3224
|
}
|
|
3067
3225
|
}
|
|
@@ -3086,7 +3244,7 @@ function ToolFormDialog({
|
|
|
3086
3244
|
}
|
|
3087
3245
|
),
|
|
3088
3246
|
/* @__PURE__ */ jsxs11(Button9, { type: "submit", disabled: isPending, children: [
|
|
3089
|
-
isPending ? /* @__PURE__ */ jsx13(Loader24, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
3247
|
+
isPending ? /* @__PURE__ */ jsx13(Loader24, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
3090
3248
|
isEditing ? "Salvar" : "Criar"
|
|
3091
3249
|
] })
|
|
3092
3250
|
] })
|
|
@@ -3095,7 +3253,7 @@ function ToolFormDialog({
|
|
|
3095
3253
|
}
|
|
3096
3254
|
|
|
3097
3255
|
// src/components/tools/tool-credentials-form.tsx
|
|
3098
|
-
import { useMemo as
|
|
3256
|
+
import { useMemo as useMemo6, useState as useState11 } from "react";
|
|
3099
3257
|
import { DataTable as DataTable3 } from "@greatapps/greatauth-ui";
|
|
3100
3258
|
import {
|
|
3101
3259
|
Input as Input9,
|
|
@@ -3188,6 +3346,7 @@ function useColumns3(tools, onEdit, onConnect, onRemove) {
|
|
|
3188
3346
|
variant: "ghost",
|
|
3189
3347
|
size: "icon",
|
|
3190
3348
|
className: "h-8 w-8",
|
|
3349
|
+
"aria-label": "Vincular",
|
|
3191
3350
|
disabled: true,
|
|
3192
3351
|
children: /* @__PURE__ */ jsx14(Link, { className: "h-4 w-4" })
|
|
3193
3352
|
}
|
|
@@ -3201,6 +3360,7 @@ function useColumns3(tools, onEdit, onConnect, onRemove) {
|
|
|
3201
3360
|
variant: "ghost",
|
|
3202
3361
|
size: "icon",
|
|
3203
3362
|
className: "h-8 w-8",
|
|
3363
|
+
"aria-label": "Editar",
|
|
3204
3364
|
onClick: () => onEdit(row.original),
|
|
3205
3365
|
children: /* @__PURE__ */ jsx14(Pencil4, { className: "h-4 w-4" })
|
|
3206
3366
|
}
|
|
@@ -3214,6 +3374,7 @@ function useColumns3(tools, onEdit, onConnect, onRemove) {
|
|
|
3214
3374
|
variant: "ghost",
|
|
3215
3375
|
size: "icon",
|
|
3216
3376
|
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
3377
|
+
"aria-label": "Excluir",
|
|
3217
3378
|
onClick: () => onRemove(row.original),
|
|
3218
3379
|
children: /* @__PURE__ */ jsx14(Trash25, { className: "h-4 w-4" })
|
|
3219
3380
|
}
|
|
@@ -3256,7 +3417,7 @@ function ToolCredentialsForm({
|
|
|
3256
3417
|
status: ""
|
|
3257
3418
|
});
|
|
3258
3419
|
const [removeTarget, setRemoveTarget] = useState11(null);
|
|
3259
|
-
const filteredCredentials =
|
|
3420
|
+
const filteredCredentials = useMemo6(() => {
|
|
3260
3421
|
if (!search) return credentials;
|
|
3261
3422
|
const term = search.toLowerCase();
|
|
3262
3423
|
return credentials.filter((cred) => {
|
|
@@ -3363,11 +3524,14 @@ function ToolCredentialsForm({
|
|
|
3363
3524
|
}
|
|
3364
3525
|
return /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
|
|
3365
3526
|
/* @__PURE__ */ jsx14("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs12("div", { className: "relative flex-1 max-w-md", children: [
|
|
3366
|
-
/* @__PURE__ */ jsx14(Search3, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
3527
|
+
/* @__PURE__ */ jsx14(Search3, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
3367
3528
|
/* @__PURE__ */ jsx14(
|
|
3368
3529
|
Input9,
|
|
3369
3530
|
{
|
|
3370
|
-
placeholder: "Buscar credenciais
|
|
3531
|
+
placeholder: "Buscar credenciais\\u2026",
|
|
3532
|
+
"aria-label": "Buscar credenciais",
|
|
3533
|
+
name: "search",
|
|
3534
|
+
autoComplete: "off",
|
|
3371
3535
|
value: search,
|
|
3372
3536
|
onChange: (e) => setSearch(e.target.value),
|
|
3373
3537
|
className: "pl-9"
|
|
@@ -3387,24 +3551,26 @@ function ToolCredentialsForm({
|
|
|
3387
3551
|
/* @__PURE__ */ jsx14(DialogHeader6, { children: /* @__PURE__ */ jsx14(DialogTitle6, { children: "Nova Credencial" }) }),
|
|
3388
3552
|
/* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
|
|
3389
3553
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3390
|
-
/* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
|
|
3554
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
|
|
3391
3555
|
/* @__PURE__ */ jsxs12(
|
|
3392
3556
|
Select3,
|
|
3393
3557
|
{
|
|
3394
3558
|
value: createForm.id_tool,
|
|
3395
3559
|
onValueChange: (val) => setCreateForm((f) => ({ ...f, id_tool: val })),
|
|
3396
3560
|
children: [
|
|
3397
|
-
/* @__PURE__ */ jsx14(SelectTrigger3, { children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
|
|
3561
|
+
/* @__PURE__ */ jsx14(SelectTrigger3, { id: "cred-tool", children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
|
|
3398
3562
|
/* @__PURE__ */ jsx14(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx14(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
|
|
3399
3563
|
]
|
|
3400
3564
|
}
|
|
3401
3565
|
)
|
|
3402
3566
|
] }),
|
|
3403
3567
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3404
|
-
/* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Label *" }),
|
|
3568
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "cred-label", className: "mb-1 block text-sm font-medium", children: "Label *" }),
|
|
3405
3569
|
/* @__PURE__ */ jsx14(
|
|
3406
3570
|
Input9,
|
|
3407
3571
|
{
|
|
3572
|
+
id: "cred-label",
|
|
3573
|
+
name: "label",
|
|
3408
3574
|
value: createForm.label,
|
|
3409
3575
|
onChange: (e) => setCreateForm((f) => ({ ...f, label: e.target.value })),
|
|
3410
3576
|
placeholder: "Ex: Google Calendar - Cl\xEDnica S\xE3o Paulo"
|
|
@@ -3412,10 +3578,13 @@ function ToolCredentialsForm({
|
|
|
3412
3578
|
)
|
|
3413
3579
|
] }),
|
|
3414
3580
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3415
|
-
/* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Credencial *" }),
|
|
3581
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "cred-credential", className: "mb-1 block text-sm font-medium", children: "Credencial *" }),
|
|
3416
3582
|
/* @__PURE__ */ jsx14(
|
|
3417
3583
|
Input9,
|
|
3418
3584
|
{
|
|
3585
|
+
id: "cred-credential",
|
|
3586
|
+
name: "credential",
|
|
3587
|
+
autoComplete: "off",
|
|
3419
3588
|
type: "password",
|
|
3420
3589
|
value: createForm.credentials_encrypted,
|
|
3421
3590
|
onChange: (e) => setCreateForm((f) => ({
|
|
@@ -3427,10 +3596,12 @@ function ToolCredentialsForm({
|
|
|
3427
3596
|
)
|
|
3428
3597
|
] }),
|
|
3429
3598
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3430
|
-
/* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o (opcional)" }),
|
|
3599
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o (opcional)" }),
|
|
3431
3600
|
/* @__PURE__ */ jsx14(
|
|
3432
3601
|
Input9,
|
|
3433
3602
|
{
|
|
3603
|
+
id: "cred-expires",
|
|
3604
|
+
name: "expires",
|
|
3434
3605
|
type: "date",
|
|
3435
3606
|
value: createForm.expires_at,
|
|
3436
3607
|
onChange: (e) => setCreateForm((f) => ({ ...f, expires_at: e.target.value }))
|
|
@@ -3466,24 +3637,26 @@ function ToolCredentialsForm({
|
|
|
3466
3637
|
/* @__PURE__ */ jsx14(DialogHeader6, { children: /* @__PURE__ */ jsx14(DialogTitle6, { children: "Editar Credencial" }) }),
|
|
3467
3638
|
/* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
|
|
3468
3639
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3469
|
-
/* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
|
|
3640
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
|
|
3470
3641
|
/* @__PURE__ */ jsxs12(
|
|
3471
3642
|
Select3,
|
|
3472
3643
|
{
|
|
3473
3644
|
value: editForm.id_tool,
|
|
3474
3645
|
onValueChange: (val) => setEditForm((f) => ({ ...f, id_tool: val })),
|
|
3475
3646
|
children: [
|
|
3476
|
-
/* @__PURE__ */ jsx14(SelectTrigger3, { children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
|
|
3647
|
+
/* @__PURE__ */ jsx14(SelectTrigger3, { id: "edit-cred-tool", children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
|
|
3477
3648
|
/* @__PURE__ */ jsx14(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx14(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
|
|
3478
3649
|
]
|
|
3479
3650
|
}
|
|
3480
3651
|
)
|
|
3481
3652
|
] }),
|
|
3482
3653
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3483
|
-
/* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Label" }),
|
|
3654
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-label", className: "mb-1 block text-sm font-medium", children: "Label" }),
|
|
3484
3655
|
/* @__PURE__ */ jsx14(
|
|
3485
3656
|
Input9,
|
|
3486
3657
|
{
|
|
3658
|
+
id: "edit-cred-label",
|
|
3659
|
+
name: "label",
|
|
3487
3660
|
value: editForm.label,
|
|
3488
3661
|
onChange: (e) => setEditForm((f) => ({ ...f, label: e.target.value })),
|
|
3489
3662
|
placeholder: "Label da credencial"
|
|
@@ -3491,10 +3664,13 @@ function ToolCredentialsForm({
|
|
|
3491
3664
|
)
|
|
3492
3665
|
] }),
|
|
3493
3666
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3494
|
-
/* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Nova Credencial (vazio = manter atual)" }),
|
|
3667
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-credential", className: "mb-1 block text-sm font-medium", children: "Nova Credencial (vazio = manter atual)" }),
|
|
3495
3668
|
/* @__PURE__ */ jsx14(
|
|
3496
3669
|
Input9,
|
|
3497
3670
|
{
|
|
3671
|
+
id: "edit-cred-credential",
|
|
3672
|
+
name: "credential",
|
|
3673
|
+
autoComplete: "off",
|
|
3498
3674
|
type: "password",
|
|
3499
3675
|
value: editForm.credentials_encrypted,
|
|
3500
3676
|
onChange: (e) => setEditForm((f) => ({
|
|
@@ -3506,10 +3682,12 @@ function ToolCredentialsForm({
|
|
|
3506
3682
|
)
|
|
3507
3683
|
] }),
|
|
3508
3684
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3509
|
-
/* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o" }),
|
|
3685
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o" }),
|
|
3510
3686
|
/* @__PURE__ */ jsx14(
|
|
3511
3687
|
Input9,
|
|
3512
3688
|
{
|
|
3689
|
+
id: "edit-cred-expires",
|
|
3690
|
+
name: "expires",
|
|
3513
3691
|
type: "date",
|
|
3514
3692
|
value: editForm.expires_at,
|
|
3515
3693
|
onChange: (e) => setEditForm((f) => ({ ...f, expires_at: e.target.value }))
|
|
@@ -3517,7 +3695,7 @@ function ToolCredentialsForm({
|
|
|
3517
3695
|
)
|
|
3518
3696
|
] }),
|
|
3519
3697
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3520
|
-
/* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Status" }),
|
|
3698
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-status", className: "mb-1 block text-sm font-medium", children: "Status" }),
|
|
3521
3699
|
/* @__PURE__ */ jsxs12(
|
|
3522
3700
|
Select3,
|
|
3523
3701
|
{
|
|
@@ -3527,7 +3705,7 @@ function ToolCredentialsForm({
|
|
|
3527
3705
|
status: val
|
|
3528
3706
|
})),
|
|
3529
3707
|
children: [
|
|
3530
|
-
/* @__PURE__ */ jsx14(SelectTrigger3, { children: /* @__PURE__ */ jsx14(SelectValue3, {}) }),
|
|
3708
|
+
/* @__PURE__ */ jsx14(SelectTrigger3, { id: "edit-cred-status", children: /* @__PURE__ */ jsx14(SelectValue3, {}) }),
|
|
3531
3709
|
/* @__PURE__ */ jsxs12(SelectContent3, { children: [
|
|
3532
3710
|
/* @__PURE__ */ jsx14(SelectItem3, { value: "active", children: "Ativo" }),
|
|
3533
3711
|
/* @__PURE__ */ jsx14(SelectItem3, { value: "expired", children: "Expirado" })
|
|
@@ -3578,31 +3756,1302 @@ function ToolCredentialsForm({
|
|
|
3578
3756
|
] });
|
|
3579
3757
|
}
|
|
3580
3758
|
|
|
3759
|
+
// src/components/capabilities/integration-card.tsx
|
|
3760
|
+
import { Badge as Badge8, Button as Button11, Tooltip as Tooltip4, TooltipContent as TooltipContent4, TooltipTrigger as TooltipTrigger4 } from "@greatapps/greatauth-ui/ui";
|
|
3761
|
+
import {
|
|
3762
|
+
CalendarSync,
|
|
3763
|
+
Plug,
|
|
3764
|
+
Settings,
|
|
3765
|
+
RefreshCw,
|
|
3766
|
+
Users,
|
|
3767
|
+
Clock
|
|
3768
|
+
} from "lucide-react";
|
|
3769
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3770
|
+
var ICON_MAP = {
|
|
3771
|
+
CalendarSync,
|
|
3772
|
+
Plug,
|
|
3773
|
+
Settings,
|
|
3774
|
+
RefreshCw,
|
|
3775
|
+
Users,
|
|
3776
|
+
Clock
|
|
3777
|
+
};
|
|
3778
|
+
function resolveIcon(name) {
|
|
3779
|
+
return ICON_MAP[name] ?? Plug;
|
|
3780
|
+
}
|
|
3781
|
+
var STATE_BADGES = {
|
|
3782
|
+
available: {
|
|
3783
|
+
label: "Dispon\xEDvel",
|
|
3784
|
+
className: "bg-muted text-muted-foreground"
|
|
3785
|
+
},
|
|
3786
|
+
connected: {
|
|
3787
|
+
label: "Conectado",
|
|
3788
|
+
className: "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
|
|
3789
|
+
},
|
|
3790
|
+
expired: {
|
|
3791
|
+
label: "Expirado",
|
|
3792
|
+
className: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
|
|
3793
|
+
},
|
|
3794
|
+
coming_soon: {
|
|
3795
|
+
label: "Em breve",
|
|
3796
|
+
className: "bg-muted text-muted-foreground"
|
|
3797
|
+
}
|
|
3798
|
+
};
|
|
3799
|
+
function getActionLabel(state) {
|
|
3800
|
+
switch (state) {
|
|
3801
|
+
case "available":
|
|
3802
|
+
return "Conectar";
|
|
3803
|
+
case "connected":
|
|
3804
|
+
return "Configurar";
|
|
3805
|
+
case "expired":
|
|
3806
|
+
return "Reconectar";
|
|
3807
|
+
default:
|
|
3808
|
+
return "";
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
function IntegrationCard({ card, onConnect }) {
|
|
3812
|
+
const { definition, state, sharedByAgentsCount } = card;
|
|
3813
|
+
const Icon = resolveIcon(definition.icon);
|
|
3814
|
+
const badge = STATE_BADGES[state];
|
|
3815
|
+
const actionLabel = getActionLabel(state);
|
|
3816
|
+
const isComingSoon = state === "coming_soon";
|
|
3817
|
+
return /* @__PURE__ */ jsxs13(
|
|
3818
|
+
"div",
|
|
3819
|
+
{
|
|
3820
|
+
className: cn(
|
|
3821
|
+
"group relative flex flex-col gap-3 rounded-xl border bg-card p-5 transition-shadow",
|
|
3822
|
+
isComingSoon ? "opacity-60 cursor-default" : "hover:shadow-md cursor-pointer"
|
|
3823
|
+
),
|
|
3824
|
+
role: "button",
|
|
3825
|
+
tabIndex: isComingSoon ? -1 : 0,
|
|
3826
|
+
"aria-label": `${definition.name} \u2014 ${badge.label}`,
|
|
3827
|
+
"aria-disabled": isComingSoon,
|
|
3828
|
+
onClick: () => !isComingSoon && onConnect(card),
|
|
3829
|
+
onKeyDown: (e) => {
|
|
3830
|
+
if (!isComingSoon && (e.key === "Enter" || e.key === " ")) {
|
|
3831
|
+
e.preventDefault();
|
|
3832
|
+
onConnect(card);
|
|
3833
|
+
}
|
|
3834
|
+
},
|
|
3835
|
+
children: [
|
|
3836
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-start justify-between gap-2", children: [
|
|
3837
|
+
/* @__PURE__ */ jsx15("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx15(Icon, { className: "h-5 w-5" }) }),
|
|
3838
|
+
/* @__PURE__ */ jsx15(Badge8, { variant: "outline", className: cn("text-xs", badge.className), children: badge.label })
|
|
3839
|
+
] }),
|
|
3840
|
+
/* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
|
|
3841
|
+
/* @__PURE__ */ jsx15("h3", { className: "text-sm font-semibold leading-tight", children: definition.name }),
|
|
3842
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground leading-relaxed", children: definition.description })
|
|
3843
|
+
] }),
|
|
3844
|
+
/* @__PURE__ */ jsxs13("div", { className: "mt-auto flex items-center justify-between gap-2 pt-1", children: [
|
|
3845
|
+
sharedByAgentsCount > 0 ? /* @__PURE__ */ jsxs13(Tooltip4, { children: [
|
|
3846
|
+
/* @__PURE__ */ jsx15(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsxs13("span", { className: "inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400", children: [
|
|
3847
|
+
/* @__PURE__ */ jsx15(Users, { className: "h-3.5 w-3.5" }),
|
|
3848
|
+
"Compartilhada"
|
|
3849
|
+
] }) }),
|
|
3850
|
+
/* @__PURE__ */ jsx15(TooltipContent4, { children: "Esta credencial est\xE1 dispon\xEDvel para todos os agentes da conta" })
|
|
3851
|
+
] }) : /* @__PURE__ */ jsx15("span", {}),
|
|
3852
|
+
!isComingSoon && /* @__PURE__ */ jsx15(
|
|
3853
|
+
Button11,
|
|
3854
|
+
{
|
|
3855
|
+
variant: state === "expired" ? "destructive" : "outline",
|
|
3856
|
+
size: "sm",
|
|
3857
|
+
className: "text-xs",
|
|
3858
|
+
onClick: (e) => {
|
|
3859
|
+
e.stopPropagation();
|
|
3860
|
+
onConnect(card);
|
|
3861
|
+
},
|
|
3862
|
+
children: actionLabel
|
|
3863
|
+
}
|
|
3864
|
+
)
|
|
3865
|
+
] })
|
|
3866
|
+
]
|
|
3867
|
+
}
|
|
3868
|
+
);
|
|
3869
|
+
}
|
|
3870
|
+
|
|
3871
|
+
// src/components/capabilities/integrations-tab.tsx
|
|
3872
|
+
import { Plug as Plug2, Loader2 as Loader25 } from "lucide-react";
|
|
3873
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3874
|
+
function IntegrationsTab({
|
|
3875
|
+
config,
|
|
3876
|
+
agentId,
|
|
3877
|
+
onConnect
|
|
3878
|
+
}) {
|
|
3879
|
+
const { cards, isLoading } = useIntegrationState(config, agentId);
|
|
3880
|
+
if (isLoading) {
|
|
3881
|
+
return /* @__PURE__ */ jsx16("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx16(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
3882
|
+
}
|
|
3883
|
+
if (cards.length === 0) {
|
|
3884
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground", children: [
|
|
3885
|
+
/* @__PURE__ */ jsx16(Plug2, { className: "h-10 w-10" }),
|
|
3886
|
+
/* @__PURE__ */ jsx16("p", { className: "text-sm", children: "Nenhuma integra\xE7\xE3o dispon\xEDvel" })
|
|
3887
|
+
] });
|
|
3888
|
+
}
|
|
3889
|
+
return /* @__PURE__ */ jsx16("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: cards.map((card) => /* @__PURE__ */ jsx16(
|
|
3890
|
+
IntegrationCard,
|
|
3891
|
+
{
|
|
3892
|
+
card,
|
|
3893
|
+
onConnect
|
|
3894
|
+
},
|
|
3895
|
+
card.definition.slug
|
|
3896
|
+
)) });
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
// src/components/capabilities/capabilities-tab.tsx
|
|
3900
|
+
import { useState as useState12, useCallback as useCallback4, useRef as useRef2, useEffect as useEffect4, useMemo as useMemo7 } from "react";
|
|
3901
|
+
import {
|
|
3902
|
+
Accordion,
|
|
3903
|
+
AccordionItem,
|
|
3904
|
+
AccordionTrigger,
|
|
3905
|
+
AccordionContent,
|
|
3906
|
+
Switch as Switch4,
|
|
3907
|
+
Checkbox,
|
|
3908
|
+
Badge as Badge9,
|
|
3909
|
+
Button as Button12,
|
|
3910
|
+
Skeleton as Skeleton6
|
|
3911
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
3912
|
+
import {
|
|
3913
|
+
Calendar,
|
|
3914
|
+
Users as Users2,
|
|
3915
|
+
Settings as Settings3,
|
|
3916
|
+
HeartHandshake,
|
|
3917
|
+
Package,
|
|
3918
|
+
ChevronDown as ChevronDown2
|
|
3919
|
+
} from "lucide-react";
|
|
3920
|
+
import { toast as toast10 } from "sonner";
|
|
3921
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3922
|
+
var OPERATION_LABELS = {
|
|
3923
|
+
list: "Listar",
|
|
3924
|
+
view: "Visualizar",
|
|
3925
|
+
create: "Criar",
|
|
3926
|
+
update: "Atualizar"
|
|
3927
|
+
};
|
|
3928
|
+
function getOperationLabel(slug) {
|
|
3929
|
+
return OPERATION_LABELS[slug] ?? slug;
|
|
3930
|
+
}
|
|
3931
|
+
var CATEGORY_ICONS = {
|
|
3932
|
+
agenda: Calendar,
|
|
3933
|
+
cadastros: Users2,
|
|
3934
|
+
infraestrutura: Settings3,
|
|
3935
|
+
relacionamentos: HeartHandshake
|
|
3936
|
+
};
|
|
3937
|
+
function getCategoryIcon(slug) {
|
|
3938
|
+
return CATEGORY_ICONS[slug] ?? Package;
|
|
3939
|
+
}
|
|
3940
|
+
function buildStateFromAgent(agentCaps) {
|
|
3941
|
+
const state = /* @__PURE__ */ new Map();
|
|
3942
|
+
for (const cap of agentCaps) {
|
|
3943
|
+
state.set(cap.module, new Set(cap.operations));
|
|
3944
|
+
}
|
|
3945
|
+
return state;
|
|
3946
|
+
}
|
|
3947
|
+
function stateToPayload(state) {
|
|
3948
|
+
const capabilities = [];
|
|
3949
|
+
state.forEach((ops, mod) => {
|
|
3950
|
+
if (ops.size > 0) {
|
|
3951
|
+
capabilities.push({ module: mod, operations: Array.from(ops) });
|
|
3952
|
+
}
|
|
3953
|
+
});
|
|
3954
|
+
return { capabilities };
|
|
3955
|
+
}
|
|
3956
|
+
function cloneState(state) {
|
|
3957
|
+
const next = /* @__PURE__ */ new Map();
|
|
3958
|
+
state.forEach((ops, mod) => next.set(mod, new Set(ops)));
|
|
3959
|
+
return next;
|
|
3960
|
+
}
|
|
3961
|
+
function statesEqual(a, b) {
|
|
3962
|
+
if (a.size !== b.size) return false;
|
|
3963
|
+
for (const [mod, opsA] of a) {
|
|
3964
|
+
const opsB = b.get(mod);
|
|
3965
|
+
if (!opsB || opsA.size !== opsB.size) return false;
|
|
3966
|
+
for (const op of opsA) {
|
|
3967
|
+
if (!opsB.has(op)) return false;
|
|
3968
|
+
}
|
|
3969
|
+
}
|
|
3970
|
+
return true;
|
|
3971
|
+
}
|
|
3972
|
+
function CapabilitiesTab({ config, agentId }) {
|
|
3973
|
+
const { data: registry, isLoading: isLoadingRegistry } = useCapabilities(config);
|
|
3974
|
+
const { data: agentCaps, isLoading: isLoadingAgent } = useAgentCapabilities(config, agentId);
|
|
3975
|
+
const updateMutation = useUpdateAgentCapabilities(config);
|
|
3976
|
+
const [localState, setLocalState] = useState12(/* @__PURE__ */ new Map());
|
|
3977
|
+
const [serverState, setServerState] = useState12(/* @__PURE__ */ new Map());
|
|
3978
|
+
const [initialized, setInitialized] = useState12(false);
|
|
3979
|
+
const debounceRef = useRef2(null);
|
|
3980
|
+
useEffect4(() => {
|
|
3981
|
+
if (agentCaps && !initialized) {
|
|
3982
|
+
const state = buildStateFromAgent(agentCaps);
|
|
3983
|
+
setLocalState(state);
|
|
3984
|
+
setServerState(cloneState(state));
|
|
3985
|
+
setInitialized(true);
|
|
3986
|
+
}
|
|
3987
|
+
}, [agentCaps, initialized]);
|
|
3988
|
+
useEffect4(() => {
|
|
3989
|
+
setInitialized(false);
|
|
3990
|
+
}, [agentId]);
|
|
3991
|
+
const hasChanges = useMemo7(
|
|
3992
|
+
() => initialized && !statesEqual(localState, serverState),
|
|
3993
|
+
[localState, serverState, initialized]
|
|
3994
|
+
);
|
|
3995
|
+
const scheduleSave = useCallback4(
|
|
3996
|
+
(nextState) => {
|
|
3997
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
3998
|
+
debounceRef.current = setTimeout(() => {
|
|
3999
|
+
const payload = stateToPayload(nextState);
|
|
4000
|
+
updateMutation.mutate(
|
|
4001
|
+
{ agentId, payload },
|
|
4002
|
+
{
|
|
4003
|
+
onSuccess: () => {
|
|
4004
|
+
setServerState(cloneState(nextState));
|
|
4005
|
+
toast10.success("Capacidades salvas");
|
|
4006
|
+
},
|
|
4007
|
+
onError: () => {
|
|
4008
|
+
setLocalState(cloneState(serverState));
|
|
4009
|
+
toast10.error("Erro ao salvar capacidades");
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
);
|
|
4013
|
+
}, 500);
|
|
4014
|
+
},
|
|
4015
|
+
[agentId, updateMutation, serverState]
|
|
4016
|
+
);
|
|
4017
|
+
const updateState = useCallback4(
|
|
4018
|
+
(updater) => {
|
|
4019
|
+
setLocalState((prev) => {
|
|
4020
|
+
const next = updater(prev);
|
|
4021
|
+
scheduleSave(next);
|
|
4022
|
+
return next;
|
|
4023
|
+
});
|
|
4024
|
+
},
|
|
4025
|
+
[scheduleSave]
|
|
4026
|
+
);
|
|
4027
|
+
const toggleModule = useCallback4(
|
|
4028
|
+
(mod, enabled) => {
|
|
4029
|
+
updateState((prev) => {
|
|
4030
|
+
const next = cloneState(prev);
|
|
4031
|
+
if (enabled) {
|
|
4032
|
+
next.set(mod.slug, new Set(mod.operations));
|
|
4033
|
+
} else {
|
|
4034
|
+
next.delete(mod.slug);
|
|
4035
|
+
}
|
|
4036
|
+
return next;
|
|
4037
|
+
});
|
|
4038
|
+
},
|
|
4039
|
+
[updateState]
|
|
4040
|
+
);
|
|
4041
|
+
const toggleOperation = useCallback4(
|
|
4042
|
+
(mod, opSlug, enabled) => {
|
|
4043
|
+
updateState((prev) => {
|
|
4044
|
+
const next = cloneState(prev);
|
|
4045
|
+
const ops = new Set(next.get(mod.slug) ?? []);
|
|
4046
|
+
if (enabled) {
|
|
4047
|
+
ops.add(opSlug);
|
|
4048
|
+
} else {
|
|
4049
|
+
ops.delete(opSlug);
|
|
4050
|
+
}
|
|
4051
|
+
if (ops.size > 0) {
|
|
4052
|
+
next.set(mod.slug, ops);
|
|
4053
|
+
} else {
|
|
4054
|
+
next.delete(mod.slug);
|
|
4055
|
+
}
|
|
4056
|
+
return next;
|
|
4057
|
+
});
|
|
4058
|
+
},
|
|
4059
|
+
[updateState]
|
|
4060
|
+
);
|
|
4061
|
+
const enableAll = useCallback4(() => {
|
|
4062
|
+
if (!registry) return;
|
|
4063
|
+
updateState(() => {
|
|
4064
|
+
const next = /* @__PURE__ */ new Map();
|
|
4065
|
+
for (const cat of registry.categories) {
|
|
4066
|
+
for (const mod of cat.modules) {
|
|
4067
|
+
next.set(mod.slug, new Set(mod.operations));
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
return next;
|
|
4071
|
+
});
|
|
4072
|
+
}, [registry, updateState]);
|
|
4073
|
+
const disableAll = useCallback4(() => {
|
|
4074
|
+
updateState(() => /* @__PURE__ */ new Map());
|
|
4075
|
+
}, [updateState]);
|
|
4076
|
+
const discard = useCallback4(() => {
|
|
4077
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
4078
|
+
setLocalState(cloneState(serverState));
|
|
4079
|
+
}, [serverState]);
|
|
4080
|
+
const saveNow = useCallback4(() => {
|
|
4081
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
4082
|
+
const payload = stateToPayload(localState);
|
|
4083
|
+
updateMutation.mutate(
|
|
4084
|
+
{ agentId, payload },
|
|
4085
|
+
{
|
|
4086
|
+
onSuccess: () => {
|
|
4087
|
+
setServerState(cloneState(localState));
|
|
4088
|
+
toast10.success("Capacidades salvas");
|
|
4089
|
+
},
|
|
4090
|
+
onError: () => {
|
|
4091
|
+
setLocalState(cloneState(serverState));
|
|
4092
|
+
toast10.error("Erro ao salvar capacidades");
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
);
|
|
4096
|
+
}, [agentId, localState, serverState, updateMutation]);
|
|
4097
|
+
function countActiveModules(cat) {
|
|
4098
|
+
return cat.modules.filter((m) => (localState.get(m.slug)?.size ?? 0) > 0).length;
|
|
4099
|
+
}
|
|
4100
|
+
if (isLoadingRegistry || isLoadingAgent) {
|
|
4101
|
+
return /* @__PURE__ */ jsx17("div", { className: "space-y-3", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx17(Skeleton6, { className: "h-14 w-full" }, i)) });
|
|
4102
|
+
}
|
|
4103
|
+
if (!registry || !registry.categories.length) {
|
|
4104
|
+
return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
|
|
4105
|
+
/* @__PURE__ */ jsx17(Package, { className: "h-12 w-12 text-muted-foreground mb-3" }),
|
|
4106
|
+
/* @__PURE__ */ jsx17("h3", { className: "text-base font-medium", children: "Nenhuma capacidade dispon\xEDvel" }),
|
|
4107
|
+
/* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground mt-1 max-w-sm", children: "Este produto ainda n\xE3o possui capacidades registadas. As capacidades ser\xE3o adicionadas automaticamente quando o produto for configurado." })
|
|
4108
|
+
] });
|
|
4109
|
+
}
|
|
4110
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-4", children: [
|
|
4111
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
4112
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
4113
|
+
/* @__PURE__ */ jsx17("h3", { className: "text-sm font-medium", children: "Capacidades do agente" }),
|
|
4114
|
+
/* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Ative ou desative m\xF3dulos e opera\xE7\xF5es dispon\xEDveis para este agente." })
|
|
4115
|
+
] }),
|
|
4116
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
4117
|
+
/* @__PURE__ */ jsx17(Button12, { variant: "outline", size: "sm", onClick: enableAll, children: "Ativar tudo" }),
|
|
4118
|
+
/* @__PURE__ */ jsx17(Button12, { variant: "outline", size: "sm", onClick: disableAll, children: "Desativar tudo" })
|
|
4119
|
+
] })
|
|
4120
|
+
] }),
|
|
4121
|
+
/* @__PURE__ */ jsx17(Accordion, { type: "multiple", className: "space-y-2", children: registry.categories.map((cat) => {
|
|
4122
|
+
const Icon = getCategoryIcon(cat.slug);
|
|
4123
|
+
const activeCount = countActiveModules(cat);
|
|
4124
|
+
const totalModules = cat.modules.length;
|
|
4125
|
+
return /* @__PURE__ */ jsxs15(
|
|
4126
|
+
AccordionItem,
|
|
4127
|
+
{
|
|
4128
|
+
value: cat.slug,
|
|
4129
|
+
className: "border rounded-lg px-4",
|
|
4130
|
+
children: [
|
|
4131
|
+
/* @__PURE__ */ jsx17(AccordionTrigger, { className: "hover:no-underline py-3", children: /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-3 flex-1", children: [
|
|
4132
|
+
/* @__PURE__ */ jsx17(Icon, { className: "h-4 w-4 text-muted-foreground" }),
|
|
4133
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium text-sm", children: cat.label }),
|
|
4134
|
+
/* @__PURE__ */ jsxs15(Badge9, { variant: "secondary", className: "text-xs", children: [
|
|
4135
|
+
activeCount,
|
|
4136
|
+
" de ",
|
|
4137
|
+
totalModules,
|
|
4138
|
+
" m\xF3dulos ativos"
|
|
4139
|
+
] })
|
|
4140
|
+
] }) }),
|
|
4141
|
+
/* @__PURE__ */ jsx17(AccordionContent, { className: "pb-3", children: /* @__PURE__ */ jsx17("div", { className: "space-y-1", children: cat.modules.map((mod) => {
|
|
4142
|
+
const enabledOps = localState.get(mod.slug);
|
|
4143
|
+
const isModuleOn = (enabledOps?.size ?? 0) > 0;
|
|
4144
|
+
const allOpsEnabled = enabledOps?.size === mod.operations.length;
|
|
4145
|
+
return /* @__PURE__ */ jsx17(
|
|
4146
|
+
ModuleRow,
|
|
4147
|
+
{
|
|
4148
|
+
module: mod,
|
|
4149
|
+
isOn: isModuleOn,
|
|
4150
|
+
allOpsEnabled,
|
|
4151
|
+
enabledOps: enabledOps ?? /* @__PURE__ */ new Set(),
|
|
4152
|
+
onToggleModule: (on) => toggleModule(mod, on),
|
|
4153
|
+
onToggleOperation: (op, on) => toggleOperation(mod, op, on)
|
|
4154
|
+
},
|
|
4155
|
+
mod.slug
|
|
4156
|
+
);
|
|
4157
|
+
}) }) })
|
|
4158
|
+
]
|
|
4159
|
+
},
|
|
4160
|
+
cat.slug
|
|
4161
|
+
);
|
|
4162
|
+
}) }),
|
|
4163
|
+
hasChanges && /* @__PURE__ */ jsxs15("div", { className: "sticky bottom-0 bg-background border-t py-3 px-4 -mx-4 flex items-center justify-between", children: [
|
|
4164
|
+
/* @__PURE__ */ jsx17("span", { className: "text-sm text-muted-foreground", children: "Voc\xEA tem altera\xE7\xF5es n\xE3o salvas." }),
|
|
4165
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
4166
|
+
/* @__PURE__ */ jsx17(Button12, { variant: "outline", size: "sm", onClick: discard, children: "Descartar" }),
|
|
4167
|
+
/* @__PURE__ */ jsx17(
|
|
4168
|
+
Button12,
|
|
4169
|
+
{
|
|
4170
|
+
size: "sm",
|
|
4171
|
+
onClick: saveNow,
|
|
4172
|
+
disabled: updateMutation.isPending,
|
|
4173
|
+
children: updateMutation.isPending ? "Salvando..." : "Salvar"
|
|
4174
|
+
}
|
|
4175
|
+
)
|
|
4176
|
+
] })
|
|
4177
|
+
] })
|
|
4178
|
+
] });
|
|
4179
|
+
}
|
|
4180
|
+
function ModuleRow({
|
|
4181
|
+
module: mod,
|
|
4182
|
+
isOn,
|
|
4183
|
+
enabledOps,
|
|
4184
|
+
onToggleModule,
|
|
4185
|
+
onToggleOperation
|
|
4186
|
+
}) {
|
|
4187
|
+
const [expanded, setExpanded] = useState12(false);
|
|
4188
|
+
return /* @__PURE__ */ jsxs15("div", { className: "rounded-md border px-3 py-2", children: [
|
|
4189
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
4190
|
+
/* @__PURE__ */ jsxs15(
|
|
4191
|
+
"button",
|
|
4192
|
+
{
|
|
4193
|
+
type: "button",
|
|
4194
|
+
className: "flex items-center gap-2 flex-1 text-left",
|
|
4195
|
+
onClick: () => setExpanded(!expanded),
|
|
4196
|
+
"aria-expanded": expanded,
|
|
4197
|
+
"aria-label": `Expandir ${mod.label}`,
|
|
4198
|
+
children: [
|
|
4199
|
+
/* @__PURE__ */ jsx17(
|
|
4200
|
+
ChevronDown2,
|
|
4201
|
+
{
|
|
4202
|
+
className: `h-3.5 w-3.5 text-muted-foreground transition-transform ${expanded ? "rotate-0" : "-rotate-90"}`
|
|
4203
|
+
}
|
|
4204
|
+
),
|
|
4205
|
+
/* @__PURE__ */ jsx17("span", { className: "text-sm font-medium", children: mod.label }),
|
|
4206
|
+
mod.description && /* @__PURE__ */ jsxs15("span", { className: "text-xs text-muted-foreground hidden sm:inline", children: [
|
|
4207
|
+
"\u2014 ",
|
|
4208
|
+
mod.description
|
|
4209
|
+
] }),
|
|
4210
|
+
isOn && /* @__PURE__ */ jsxs15(Badge9, { variant: "secondary", className: "text-xs ml-1", children: [
|
|
4211
|
+
enabledOps.size,
|
|
4212
|
+
"/",
|
|
4213
|
+
mod.operations.length
|
|
4214
|
+
] })
|
|
4215
|
+
]
|
|
4216
|
+
}
|
|
4217
|
+
),
|
|
4218
|
+
/* @__PURE__ */ jsx17(
|
|
4219
|
+
Switch4,
|
|
4220
|
+
{
|
|
4221
|
+
checked: isOn,
|
|
4222
|
+
onCheckedChange: onToggleModule,
|
|
4223
|
+
"aria-label": `Ativar m\xF3dulo ${mod.label}`
|
|
4224
|
+
}
|
|
4225
|
+
)
|
|
4226
|
+
] }),
|
|
4227
|
+
expanded && /* @__PURE__ */ jsx17("div", { className: "mt-2 ml-6 flex flex-wrap gap-x-5 gap-y-1.5 pb-1", children: mod.operations.map((op) => {
|
|
4228
|
+
const checked = enabledOps.has(op);
|
|
4229
|
+
return /* @__PURE__ */ jsxs15(
|
|
4230
|
+
"label",
|
|
4231
|
+
{
|
|
4232
|
+
className: "flex items-center gap-1.5 text-sm cursor-pointer",
|
|
4233
|
+
children: [
|
|
4234
|
+
/* @__PURE__ */ jsx17(
|
|
4235
|
+
Checkbox,
|
|
4236
|
+
{
|
|
4237
|
+
checked,
|
|
4238
|
+
onCheckedChange: (val) => onToggleOperation(op, val === true),
|
|
4239
|
+
"aria-label": `${getOperationLabel(op)} em ${mod.label}`
|
|
4240
|
+
}
|
|
4241
|
+
),
|
|
4242
|
+
/* @__PURE__ */ jsx17("span", { className: checked ? "" : "text-muted-foreground", children: getOperationLabel(op) })
|
|
4243
|
+
]
|
|
4244
|
+
},
|
|
4245
|
+
op
|
|
4246
|
+
);
|
|
4247
|
+
}) })
|
|
4248
|
+
] });
|
|
4249
|
+
}
|
|
4250
|
+
|
|
4251
|
+
// src/components/capabilities/advanced-tab.tsx
|
|
4252
|
+
import { useState as useState13 } from "react";
|
|
4253
|
+
import { Info } from "lucide-react";
|
|
4254
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4255
|
+
function AdvancedTab({ config, agentId, gagentsApiUrl }) {
|
|
4256
|
+
const { data: credentialsData, isLoading: isLoadingCredentials } = useToolCredentials(config);
|
|
4257
|
+
const credentials = credentialsData?.data ?? [];
|
|
4258
|
+
const [editingTool, setEditingTool] = useState13(null);
|
|
4259
|
+
const [showToolForm, setShowToolForm] = useState13(false);
|
|
4260
|
+
function handleEditTool(tool) {
|
|
4261
|
+
setEditingTool(tool);
|
|
4262
|
+
setShowToolForm(true);
|
|
4263
|
+
}
|
|
4264
|
+
function handleToolFormOpenChange(open) {
|
|
4265
|
+
setShowToolForm(open);
|
|
4266
|
+
if (!open) setEditingTool(null);
|
|
4267
|
+
}
|
|
4268
|
+
return /* @__PURE__ */ jsxs16("div", { className: "space-y-8", children: [
|
|
4269
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-3 rounded-lg border border-blue-200 bg-blue-50 p-4 dark:border-blue-900 dark:bg-blue-950/30", children: [
|
|
4270
|
+
/* @__PURE__ */ jsx18(Info, { className: "mt-0.5 h-4 w-4 shrink-0 text-blue-600 dark:text-blue-400" }),
|
|
4271
|
+
/* @__PURE__ */ jsxs16("p", { className: "text-sm text-blue-800 dark:text-blue-300", children: [
|
|
4272
|
+
"Use as abas ",
|
|
4273
|
+
/* @__PURE__ */ jsx18("strong", { children: "Capacidades" }),
|
|
4274
|
+
" e ",
|
|
4275
|
+
/* @__PURE__ */ jsx18("strong", { children: "Integra\xE7\xF5es" }),
|
|
4276
|
+
" para configura\xE7\xE3o simplificada. Esta aba oferece controlo manual avan\xE7ado sobre ferramentas e credenciais."
|
|
4277
|
+
] })
|
|
4278
|
+
] }),
|
|
4279
|
+
/* @__PURE__ */ jsxs16("section", { className: "space-y-3", children: [
|
|
4280
|
+
/* @__PURE__ */ jsx18("h3", { className: "text-sm font-medium", children: "Ferramentas" }),
|
|
4281
|
+
/* @__PURE__ */ jsx18(ToolsTable, { onEdit: handleEditTool, config })
|
|
4282
|
+
] }),
|
|
4283
|
+
/* @__PURE__ */ jsxs16("section", { className: "space-y-3", children: [
|
|
4284
|
+
/* @__PURE__ */ jsx18("h3", { className: "text-sm font-medium", children: "Credenciais" }),
|
|
4285
|
+
/* @__PURE__ */ jsx18(
|
|
4286
|
+
ToolCredentialsForm,
|
|
4287
|
+
{
|
|
4288
|
+
credentials,
|
|
4289
|
+
isLoading: isLoadingCredentials,
|
|
4290
|
+
config,
|
|
4291
|
+
gagentsApiUrl
|
|
4292
|
+
}
|
|
4293
|
+
)
|
|
4294
|
+
] }),
|
|
4295
|
+
/* @__PURE__ */ jsx18(
|
|
4296
|
+
ToolFormDialog,
|
|
4297
|
+
{
|
|
4298
|
+
open: showToolForm,
|
|
4299
|
+
onOpenChange: handleToolFormOpenChange,
|
|
4300
|
+
tool: editingTool ?? void 0,
|
|
4301
|
+
config
|
|
4302
|
+
}
|
|
4303
|
+
)
|
|
4304
|
+
] });
|
|
4305
|
+
}
|
|
4306
|
+
|
|
4307
|
+
// src/components/capabilities/integration-wizard.tsx
|
|
4308
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef3, useState as useState14 } from "react";
|
|
4309
|
+
import {
|
|
4310
|
+
Dialog as Dialog7,
|
|
4311
|
+
DialogContent as DialogContent7,
|
|
4312
|
+
DialogFooter as DialogFooter7,
|
|
4313
|
+
DialogHeader as DialogHeader7,
|
|
4314
|
+
DialogTitle as DialogTitle7,
|
|
4315
|
+
Button as Button14
|
|
4316
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
4317
|
+
import { Loader2 as Loader28, ChevronLeft, ChevronRight, Check as Check2 } from "lucide-react";
|
|
4318
|
+
import { toast as toast11 } from "sonner";
|
|
4319
|
+
|
|
4320
|
+
// src/components/capabilities/wizard-steps/info-step.tsx
|
|
4321
|
+
import { Check, Info as Info2 } from "lucide-react";
|
|
4322
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4323
|
+
function InfoStep({ integration, meta }) {
|
|
4324
|
+
return /* @__PURE__ */ jsxs17("div", { className: "space-y-6", children: [
|
|
4325
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-4", children: [
|
|
4326
|
+
meta.icon && /* @__PURE__ */ jsx19("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-muted", children: meta.icon }),
|
|
4327
|
+
/* @__PURE__ */ jsxs17("div", { className: "space-y-1", children: [
|
|
4328
|
+
/* @__PURE__ */ jsx19("h3", { className: "text-lg font-semibold", children: integration.name }),
|
|
4329
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: integration.description })
|
|
4330
|
+
] })
|
|
4331
|
+
] }),
|
|
4332
|
+
meta.capabilities.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
|
|
4333
|
+
/* @__PURE__ */ jsx19("h4", { className: "text-sm font-medium", children: "O que esta integra\xE7\xE3o permite:" }),
|
|
4334
|
+
/* @__PURE__ */ jsx19("ul", { className: "space-y-2", children: meta.capabilities.map((cap, i) => /* @__PURE__ */ jsxs17("li", { className: "flex items-start gap-2 text-sm", children: [
|
|
4335
|
+
/* @__PURE__ */ jsx19(
|
|
4336
|
+
Check,
|
|
4337
|
+
{
|
|
4338
|
+
"aria-hidden": "true",
|
|
4339
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
|
|
4340
|
+
}
|
|
4341
|
+
),
|
|
4342
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
4343
|
+
/* @__PURE__ */ jsx19("span", { className: "font-medium", children: cap.label }),
|
|
4344
|
+
cap.description && /* @__PURE__ */ jsxs17("span", { className: "text-muted-foreground", children: [
|
|
4345
|
+
" ",
|
|
4346
|
+
"\u2014 ",
|
|
4347
|
+
cap.description
|
|
4348
|
+
] })
|
|
4349
|
+
] })
|
|
4350
|
+
] }, i)) })
|
|
4351
|
+
] }),
|
|
4352
|
+
meta.requirements.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
|
|
4353
|
+
/* @__PURE__ */ jsx19("h4", { className: "text-sm font-medium", children: "Requisitos:" }),
|
|
4354
|
+
/* @__PURE__ */ jsx19("ul", { className: "space-y-2", children: meta.requirements.map((req, i) => /* @__PURE__ */ jsxs17(
|
|
4355
|
+
"li",
|
|
4356
|
+
{
|
|
4357
|
+
className: "flex items-start gap-2 text-sm text-muted-foreground",
|
|
4358
|
+
children: [
|
|
4359
|
+
/* @__PURE__ */ jsx19(
|
|
4360
|
+
Info2,
|
|
4361
|
+
{
|
|
4362
|
+
"aria-hidden": "true",
|
|
4363
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-blue-500"
|
|
4364
|
+
}
|
|
4365
|
+
),
|
|
4366
|
+
/* @__PURE__ */ jsx19("span", { children: req })
|
|
4367
|
+
]
|
|
4368
|
+
},
|
|
4369
|
+
i
|
|
4370
|
+
)) })
|
|
4371
|
+
] })
|
|
4372
|
+
] });
|
|
4373
|
+
}
|
|
4374
|
+
|
|
4375
|
+
// src/components/capabilities/wizard-steps/credentials-step.tsx
|
|
4376
|
+
import { CheckCircle2, Loader2 as Loader26, AlertCircle, Shield } from "lucide-react";
|
|
4377
|
+
import { Button as Button13, Input as Input10, Label as Label6 } from "@greatapps/greatauth-ui/ui";
|
|
4378
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4379
|
+
function CredentialsStep({
|
|
4380
|
+
integration,
|
|
4381
|
+
meta,
|
|
4382
|
+
oauthStatus,
|
|
4383
|
+
oauthResult,
|
|
4384
|
+
apiKey,
|
|
4385
|
+
onApiKeyChange,
|
|
4386
|
+
onStartOAuth,
|
|
4387
|
+
isReconnect = false
|
|
4388
|
+
}) {
|
|
4389
|
+
if (integration.authType === "oauth2") {
|
|
4390
|
+
return /* @__PURE__ */ jsx20(
|
|
4391
|
+
OAuthCredentials,
|
|
4392
|
+
{
|
|
4393
|
+
integration,
|
|
4394
|
+
meta,
|
|
4395
|
+
oauthStatus,
|
|
4396
|
+
oauthResult,
|
|
4397
|
+
onStartOAuth,
|
|
4398
|
+
isReconnect
|
|
4399
|
+
}
|
|
4400
|
+
);
|
|
4401
|
+
}
|
|
4402
|
+
return /* @__PURE__ */ jsx20(ApiKeyCredentials, { apiKey, onApiKeyChange });
|
|
4403
|
+
}
|
|
4404
|
+
function OAuthCredentials({
|
|
4405
|
+
integration,
|
|
4406
|
+
meta,
|
|
4407
|
+
oauthStatus,
|
|
4408
|
+
oauthResult,
|
|
4409
|
+
onStartOAuth,
|
|
4410
|
+
isReconnect
|
|
4411
|
+
}) {
|
|
4412
|
+
const providerLabel = meta.providerLabel || integration.name;
|
|
4413
|
+
return /* @__PURE__ */ jsxs18("div", { className: "space-y-6", children: [
|
|
4414
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
4415
|
+
/* @__PURE__ */ jsx20("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
|
|
4416
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: isReconnect ? `Reconecte sua conta ${providerLabel} para renovar a autoriza\xE7\xE3o.` : `Conecte sua conta ${providerLabel} para permitir o acesso.` })
|
|
4417
|
+
] }),
|
|
4418
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-4 rounded-lg border p-6", children: [
|
|
4419
|
+
oauthStatus === "idle" && /* @__PURE__ */ jsxs18(Button13, { onClick: onStartOAuth, size: "lg", className: "gap-2", children: [
|
|
4420
|
+
meta.icon,
|
|
4421
|
+
isReconnect ? `Reconectar com ${providerLabel}` : `Conectar com ${providerLabel}`
|
|
4422
|
+
] }),
|
|
4423
|
+
oauthStatus === "waiting" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
4424
|
+
/* @__PURE__ */ jsx20(
|
|
4425
|
+
Loader26,
|
|
4426
|
+
{
|
|
4427
|
+
"aria-hidden": "true",
|
|
4428
|
+
className: "h-8 w-8 animate-spin text-muted-foreground"
|
|
4429
|
+
}
|
|
4430
|
+
),
|
|
4431
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4432
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm font-medium", children: "Aguardando autoriza\xE7\xE3o..." }),
|
|
4433
|
+
/* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: "Complete o login na janela que foi aberta." })
|
|
4434
|
+
] })
|
|
4435
|
+
] }),
|
|
4436
|
+
oauthStatus === "success" && oauthResult && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
4437
|
+
/* @__PURE__ */ jsx20(
|
|
4438
|
+
CheckCircle2,
|
|
4439
|
+
{
|
|
4440
|
+
"aria-hidden": "true",
|
|
4441
|
+
className: "h-8 w-8 text-green-600"
|
|
4442
|
+
}
|
|
4443
|
+
),
|
|
4444
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4445
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-green-700", children: "Conectado com sucesso!" }),
|
|
4446
|
+
oauthResult.email && /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: oauthResult.email })
|
|
4447
|
+
] })
|
|
4448
|
+
] }),
|
|
4449
|
+
oauthStatus === "error" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
4450
|
+
/* @__PURE__ */ jsx20(
|
|
4451
|
+
AlertCircle,
|
|
4452
|
+
{
|
|
4453
|
+
"aria-hidden": "true",
|
|
4454
|
+
className: "h-8 w-8 text-destructive"
|
|
4455
|
+
}
|
|
4456
|
+
),
|
|
4457
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4458
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-destructive", children: "Falha na conex\xE3o" }),
|
|
4459
|
+
oauthResult?.error && /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: oauthResult.error })
|
|
4460
|
+
] }),
|
|
4461
|
+
/* @__PURE__ */ jsx20(Button13, { variant: "outline", onClick: onStartOAuth, size: "sm", children: "Tentar novamente" })
|
|
4462
|
+
] })
|
|
4463
|
+
] }),
|
|
4464
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
|
|
4465
|
+
/* @__PURE__ */ jsx20(
|
|
4466
|
+
Shield,
|
|
4467
|
+
{
|
|
4468
|
+
"aria-hidden": "true",
|
|
4469
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
|
|
4470
|
+
}
|
|
4471
|
+
),
|
|
4472
|
+
/* @__PURE__ */ jsxs18("p", { className: "text-xs text-muted-foreground", children: [
|
|
4473
|
+
"Seus dados est\xE3o seguros. Usamos OAuth 2.0 para autentica\xE7\xE3o \u2014 nunca armazenamos sua senha. Voc\xEA pode revogar o acesso a qualquer momento nas configura\xE7\xF5es da sua conta ",
|
|
4474
|
+
providerLabel,
|
|
4475
|
+
"."
|
|
4476
|
+
] })
|
|
4477
|
+
] })
|
|
4478
|
+
] });
|
|
4479
|
+
}
|
|
4480
|
+
function ApiKeyCredentials({
|
|
4481
|
+
apiKey,
|
|
4482
|
+
onApiKeyChange
|
|
4483
|
+
}) {
|
|
4484
|
+
return /* @__PURE__ */ jsxs18("div", { className: "space-y-6", children: [
|
|
4485
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
4486
|
+
/* @__PURE__ */ jsx20("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
|
|
4487
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "Insira a chave de API para conectar a integra\xE7\xE3o." })
|
|
4488
|
+
] }),
|
|
4489
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
4490
|
+
/* @__PURE__ */ jsx20(Label6, { htmlFor: "integration-api-key", children: "Chave de API" }),
|
|
4491
|
+
/* @__PURE__ */ jsx20(
|
|
4492
|
+
Input10,
|
|
4493
|
+
{
|
|
4494
|
+
id: "integration-api-key",
|
|
4495
|
+
type: "password",
|
|
4496
|
+
autoComplete: "off",
|
|
4497
|
+
placeholder: "Insira sua chave de API...",
|
|
4498
|
+
value: apiKey,
|
|
4499
|
+
onChange: (e) => onApiKeyChange(e.target.value)
|
|
4500
|
+
}
|
|
4501
|
+
)
|
|
4502
|
+
] }),
|
|
4503
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
|
|
4504
|
+
/* @__PURE__ */ jsx20(
|
|
4505
|
+
Shield,
|
|
4506
|
+
{
|
|
4507
|
+
"aria-hidden": "true",
|
|
4508
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
|
|
4509
|
+
}
|
|
4510
|
+
),
|
|
4511
|
+
/* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: "Sua chave de API \xE9 armazenada de forma segura e encriptada. Nunca \xE9 exposta no frontend." })
|
|
4512
|
+
] })
|
|
4513
|
+
] });
|
|
4514
|
+
}
|
|
4515
|
+
|
|
4516
|
+
// src/components/capabilities/wizard-steps/config-step.tsx
|
|
4517
|
+
import { Loader2 as Loader27 } from "lucide-react";
|
|
4518
|
+
import {
|
|
4519
|
+
Label as Label7,
|
|
4520
|
+
Select as Select4,
|
|
4521
|
+
SelectContent as SelectContent4,
|
|
4522
|
+
SelectItem as SelectItem4,
|
|
4523
|
+
SelectTrigger as SelectTrigger4,
|
|
4524
|
+
SelectValue as SelectValue4
|
|
4525
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
4526
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4527
|
+
function ConfigStep({
|
|
4528
|
+
integration,
|
|
4529
|
+
options,
|
|
4530
|
+
isLoading,
|
|
4531
|
+
selectedValue,
|
|
4532
|
+
onValueChange,
|
|
4533
|
+
selectLabel,
|
|
4534
|
+
selectPlaceholder
|
|
4535
|
+
}) {
|
|
4536
|
+
const label = selectLabel || getDefaultLabel(integration.slug);
|
|
4537
|
+
const placeholder = selectPlaceholder || getDefaultPlaceholder(integration.slug);
|
|
4538
|
+
return /* @__PURE__ */ jsxs19("div", { className: "space-y-6", children: [
|
|
4539
|
+
/* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4540
|
+
/* @__PURE__ */ jsx21("h3", { className: "text-lg font-semibold", children: "Configura\xE7\xE3o" }),
|
|
4541
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Configure as op\xE7\xF5es espec\xEDficas da integra\xE7\xE3o." })
|
|
4542
|
+
] }),
|
|
4543
|
+
isLoading ? /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-3 py-8", children: [
|
|
4544
|
+
/* @__PURE__ */ jsx21(
|
|
4545
|
+
Loader27,
|
|
4546
|
+
{
|
|
4547
|
+
"aria-hidden": "true",
|
|
4548
|
+
className: "h-6 w-6 animate-spin text-muted-foreground"
|
|
4549
|
+
}
|
|
4550
|
+
),
|
|
4551
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Carregando op\xE7\xF5es..." })
|
|
4552
|
+
] }) : options.length === 0 ? /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-dashed p-6 text-center", children: /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Nenhuma op\xE7\xE3o dispon\xEDvel. A configura\xE7\xE3o padr\xE3o ser\xE1 usada." }) }) : /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4553
|
+
/* @__PURE__ */ jsx21(Label7, { htmlFor: "integration-config-select", children: label }),
|
|
4554
|
+
/* @__PURE__ */ jsxs19(Select4, { value: selectedValue, onValueChange, children: [
|
|
4555
|
+
/* @__PURE__ */ jsx21(SelectTrigger4, { id: "integration-config-select", children: /* @__PURE__ */ jsx21(SelectValue4, { placeholder }) }),
|
|
4556
|
+
/* @__PURE__ */ jsx21(SelectContent4, { children: options.map((opt) => /* @__PURE__ */ jsxs19(SelectItem4, { value: opt.id, children: [
|
|
4557
|
+
/* @__PURE__ */ jsx21("span", { children: opt.label }),
|
|
4558
|
+
opt.description && /* @__PURE__ */ jsxs19("span", { className: "ml-2 text-xs text-muted-foreground", children: [
|
|
4559
|
+
"(",
|
|
4560
|
+
opt.description,
|
|
4561
|
+
")"
|
|
4562
|
+
] })
|
|
4563
|
+
] }, opt.id)) })
|
|
4564
|
+
] })
|
|
4565
|
+
] })
|
|
4566
|
+
] });
|
|
4567
|
+
}
|
|
4568
|
+
function getDefaultLabel(slug) {
|
|
4569
|
+
switch (slug) {
|
|
4570
|
+
case "google_calendar":
|
|
4571
|
+
return "Calend\xE1rio";
|
|
4572
|
+
default:
|
|
4573
|
+
return "Op\xE7\xE3o";
|
|
4574
|
+
}
|
|
4575
|
+
}
|
|
4576
|
+
function getDefaultPlaceholder(slug) {
|
|
4577
|
+
switch (slug) {
|
|
4578
|
+
case "google_calendar":
|
|
4579
|
+
return "Selecione o calend\xE1rio...";
|
|
4580
|
+
default:
|
|
4581
|
+
return "Selecione uma op\xE7\xE3o...";
|
|
4582
|
+
}
|
|
4583
|
+
}
|
|
4584
|
+
|
|
4585
|
+
// src/components/capabilities/wizard-steps/confirm-step.tsx
|
|
4586
|
+
import { CheckCircle2 as CheckCircle22 } from "lucide-react";
|
|
4587
|
+
import { Label as Label8 } from "@greatapps/greatauth-ui/ui";
|
|
4588
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4589
|
+
function ConfirmStep({
|
|
4590
|
+
integration,
|
|
4591
|
+
oauthResult,
|
|
4592
|
+
selectedConfigOption,
|
|
4593
|
+
enableOnComplete,
|
|
4594
|
+
onEnableChange
|
|
4595
|
+
}) {
|
|
4596
|
+
return /* @__PURE__ */ jsxs20("div", { className: "space-y-6", children: [
|
|
4597
|
+
/* @__PURE__ */ jsxs20("div", { className: "space-y-2", children: [
|
|
4598
|
+
/* @__PURE__ */ jsx22("h3", { className: "text-lg font-semibold", children: "Confirma\xE7\xE3o" }),
|
|
4599
|
+
/* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Revise as configura\xE7\xF5es antes de concluir." })
|
|
4600
|
+
] }),
|
|
4601
|
+
/* @__PURE__ */ jsxs20("div", { className: "space-y-3 rounded-lg border p-4", children: [
|
|
4602
|
+
/* @__PURE__ */ jsx22(SummaryRow, { label: "Integra\xE7\xE3o", value: integration.name }),
|
|
4603
|
+
oauthResult?.email && /* @__PURE__ */ jsx22(SummaryRow, { label: "Conta conectada", value: oauthResult.email }),
|
|
4604
|
+
selectedConfigOption && /* @__PURE__ */ jsx22(
|
|
4605
|
+
SummaryRow,
|
|
4606
|
+
{
|
|
4607
|
+
label: getConfigLabel(integration.slug),
|
|
4608
|
+
value: selectedConfigOption.label
|
|
4609
|
+
}
|
|
4610
|
+
),
|
|
4611
|
+
/* @__PURE__ */ jsx22(
|
|
4612
|
+
SummaryRow,
|
|
4613
|
+
{
|
|
4614
|
+
label: "Tipo de autentica\xE7\xE3o",
|
|
4615
|
+
value: integration.authType === "oauth2" ? "OAuth 2.0" : "API Key"
|
|
4616
|
+
}
|
|
4617
|
+
)
|
|
4618
|
+
] }),
|
|
4619
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between rounded-lg border p-4", children: [
|
|
4620
|
+
/* @__PURE__ */ jsxs20("div", { className: "space-y-0.5", children: [
|
|
4621
|
+
/* @__PURE__ */ jsx22(Label8, { htmlFor: "enable-on-complete", className: "text-sm font-medium", children: "Ativar imediatamente" }),
|
|
4622
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: "A integra\xE7\xE3o ficar\xE1 ativa assim que concluir o assistente." })
|
|
4623
|
+
] }),
|
|
4624
|
+
/* @__PURE__ */ jsx22(
|
|
4625
|
+
"button",
|
|
4626
|
+
{
|
|
4627
|
+
id: "enable-on-complete",
|
|
4628
|
+
role: "switch",
|
|
4629
|
+
type: "button",
|
|
4630
|
+
"aria-checked": enableOnComplete,
|
|
4631
|
+
onClick: () => onEnableChange(!enableOnComplete),
|
|
4632
|
+
className: `
|
|
4633
|
+
relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent
|
|
4634
|
+
transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2
|
|
4635
|
+
focus-visible:ring-ring focus-visible:ring-offset-2
|
|
4636
|
+
${enableOnComplete ? "bg-primary" : "bg-muted"}
|
|
4637
|
+
`,
|
|
4638
|
+
children: /* @__PURE__ */ jsx22(
|
|
4639
|
+
"span",
|
|
4640
|
+
{
|
|
4641
|
+
"aria-hidden": "true",
|
|
4642
|
+
className: `
|
|
4643
|
+
pointer-events-none inline-block h-5 w-5 transform rounded-full bg-background shadow-lg
|
|
4644
|
+
ring-0 transition duration-200 ease-in-out
|
|
4645
|
+
${enableOnComplete ? "translate-x-5" : "translate-x-0"}
|
|
4646
|
+
`
|
|
4647
|
+
}
|
|
4648
|
+
)
|
|
4649
|
+
}
|
|
4650
|
+
)
|
|
4651
|
+
] }),
|
|
4652
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 rounded-md bg-green-50 p-3 dark:bg-green-950/20", children: [
|
|
4653
|
+
/* @__PURE__ */ jsx22(
|
|
4654
|
+
CheckCircle22,
|
|
4655
|
+
{
|
|
4656
|
+
"aria-hidden": "true",
|
|
4657
|
+
className: "h-4 w-4 shrink-0 text-green-600"
|
|
4658
|
+
}
|
|
4659
|
+
),
|
|
4660
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-green-700 dark:text-green-400", children: 'Tudo pronto! Clique em "Concluir" para finalizar a configura\xE7\xE3o.' })
|
|
4661
|
+
] })
|
|
4662
|
+
] });
|
|
4663
|
+
}
|
|
4664
|
+
function SummaryRow({ label, value }) {
|
|
4665
|
+
return /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between text-sm", children: [
|
|
4666
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: label }),
|
|
4667
|
+
/* @__PURE__ */ jsx22("span", { className: "font-medium", children: value })
|
|
4668
|
+
] });
|
|
4669
|
+
}
|
|
4670
|
+
function getConfigLabel(slug) {
|
|
4671
|
+
switch (slug) {
|
|
4672
|
+
case "google_calendar":
|
|
4673
|
+
return "Calend\xE1rio";
|
|
4674
|
+
default:
|
|
4675
|
+
return "Configura\xE7\xE3o";
|
|
4676
|
+
}
|
|
4677
|
+
}
|
|
4678
|
+
|
|
4679
|
+
// src/components/capabilities/integration-wizard.tsx
|
|
4680
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4681
|
+
var STEPS = ["info", "credentials", "config", "confirm"];
|
|
4682
|
+
var STEP_LABELS = {
|
|
4683
|
+
info: "Informa\xE7\xE3o",
|
|
4684
|
+
credentials: "Credenciais",
|
|
4685
|
+
config: "Configura\xE7\xE3o",
|
|
4686
|
+
confirm: "Confirma\xE7\xE3o"
|
|
4687
|
+
};
|
|
4688
|
+
function IntegrationWizard({
|
|
4689
|
+
open,
|
|
4690
|
+
onOpenChange,
|
|
4691
|
+
integration,
|
|
4692
|
+
meta,
|
|
4693
|
+
agentId: _agentId,
|
|
4694
|
+
config,
|
|
4695
|
+
onComplete,
|
|
4696
|
+
gagentsApiUrl,
|
|
4697
|
+
existingCredentialId,
|
|
4698
|
+
loadConfigOptions,
|
|
4699
|
+
existingConfigValue
|
|
4700
|
+
}) {
|
|
4701
|
+
const isReconnect = !!existingCredentialId;
|
|
4702
|
+
const [currentStep, setCurrentStep] = useState14("info");
|
|
4703
|
+
const currentIndex = STEPS.indexOf(currentStep);
|
|
4704
|
+
const [oauthStatus, setOauthStatus] = useState14("idle");
|
|
4705
|
+
const [oauthResult, setOauthResult] = useState14(null);
|
|
4706
|
+
const popupRef = useRef3(null);
|
|
4707
|
+
const popupPollRef = useRef3(null);
|
|
4708
|
+
const [apiKey, setApiKey] = useState14("");
|
|
4709
|
+
const [configOptions, setConfigOptions] = useState14([]);
|
|
4710
|
+
const [configLoading, setConfigLoading] = useState14(false);
|
|
4711
|
+
const [selectedConfigValue, setSelectedConfigValue] = useState14("");
|
|
4712
|
+
const [enableOnComplete, setEnableOnComplete] = useState14(true);
|
|
4713
|
+
const [isSubmitting, setIsSubmitting] = useState14(false);
|
|
4714
|
+
useEffect5(() => {
|
|
4715
|
+
return () => {
|
|
4716
|
+
if (popupPollRef.current) {
|
|
4717
|
+
clearInterval(popupPollRef.current);
|
|
4718
|
+
}
|
|
4719
|
+
};
|
|
4720
|
+
}, []);
|
|
4721
|
+
useEffect5(() => {
|
|
4722
|
+
if (open) {
|
|
4723
|
+
setCurrentStep("info");
|
|
4724
|
+
setOauthStatus("idle");
|
|
4725
|
+
setOauthResult(null);
|
|
4726
|
+
setApiKey("");
|
|
4727
|
+
setConfigOptions([]);
|
|
4728
|
+
setConfigLoading(false);
|
|
4729
|
+
setSelectedConfigValue(existingConfigValue ?? "");
|
|
4730
|
+
setEnableOnComplete(true);
|
|
4731
|
+
setIsSubmitting(false);
|
|
4732
|
+
} else {
|
|
4733
|
+
if (popupRef.current && !popupRef.current.closed) {
|
|
4734
|
+
popupRef.current.close();
|
|
4735
|
+
}
|
|
4736
|
+
if (popupPollRef.current) {
|
|
4737
|
+
clearInterval(popupPollRef.current);
|
|
4738
|
+
popupPollRef.current = null;
|
|
4739
|
+
}
|
|
4740
|
+
}
|
|
4741
|
+
}, [open]);
|
|
4742
|
+
const handleOAuthMessage = useCallback5(
|
|
4743
|
+
(event) => {
|
|
4744
|
+
try {
|
|
4745
|
+
if (event.origin !== new URL(gagentsApiUrl).origin) return;
|
|
4746
|
+
} catch {
|
|
4747
|
+
return;
|
|
4748
|
+
}
|
|
4749
|
+
if (!event.data || typeof event.data !== "object") return;
|
|
4750
|
+
const msg = event.data;
|
|
4751
|
+
if (msg.type !== "oauth-callback") return;
|
|
4752
|
+
if (msg.success) {
|
|
4753
|
+
setOauthStatus("success");
|
|
4754
|
+
setOauthResult({
|
|
4755
|
+
success: true,
|
|
4756
|
+
email: msg.email,
|
|
4757
|
+
credentialId: msg.credentialId
|
|
4758
|
+
});
|
|
4759
|
+
const credId = msg.credentialId || existingCredentialId;
|
|
4760
|
+
if (credId && loadConfigOptions && meta.hasConfigStep) {
|
|
4761
|
+
setConfigLoading(true);
|
|
4762
|
+
loadConfigOptions(credId).then((opts) => {
|
|
4763
|
+
setConfigOptions(opts);
|
|
4764
|
+
if (opts.length === 1) {
|
|
4765
|
+
setSelectedConfigValue(opts[0].id);
|
|
4766
|
+
}
|
|
4767
|
+
}).catch(() => setConfigOptions([])).finally(() => setConfigLoading(false));
|
|
4768
|
+
}
|
|
4769
|
+
setTimeout(() => {
|
|
4770
|
+
setCurrentStep(meta.hasConfigStep ? "config" : "confirm");
|
|
4771
|
+
}, 1200);
|
|
4772
|
+
} else {
|
|
4773
|
+
setOauthStatus("error");
|
|
4774
|
+
setOauthResult({
|
|
4775
|
+
success: false,
|
|
4776
|
+
error: msg.error || "Falha na autoriza\xE7\xE3o"
|
|
4777
|
+
});
|
|
4778
|
+
}
|
|
4779
|
+
},
|
|
4780
|
+
[gagentsApiUrl, existingCredentialId, meta.hasConfigStep, loadConfigOptions]
|
|
4781
|
+
);
|
|
4782
|
+
useEffect5(() => {
|
|
4783
|
+
if (!open) return;
|
|
4784
|
+
window.addEventListener("message", handleOAuthMessage);
|
|
4785
|
+
return () => window.removeEventListener("message", handleOAuthMessage);
|
|
4786
|
+
}, [open, handleOAuthMessage]);
|
|
4787
|
+
function startOAuth() {
|
|
4788
|
+
const { language = "pt-br", idWl = 1, accountId } = config;
|
|
4789
|
+
const redirectUri = `${window.location.origin}/oauth/callback`;
|
|
4790
|
+
const url = new URL(
|
|
4791
|
+
`${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${accountId}/oauth/authorize/${integration.slug}`
|
|
4792
|
+
);
|
|
4793
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
4794
|
+
setOauthStatus("waiting");
|
|
4795
|
+
const popup = window.open(
|
|
4796
|
+
url.toString(),
|
|
4797
|
+
"oauth-popup",
|
|
4798
|
+
"width=500,height=600,scrollbars=yes,resizable=yes"
|
|
4799
|
+
);
|
|
4800
|
+
popupRef.current = popup;
|
|
4801
|
+
if (popup) {
|
|
4802
|
+
if (popupPollRef.current) {
|
|
4803
|
+
clearInterval(popupPollRef.current);
|
|
4804
|
+
}
|
|
4805
|
+
popupPollRef.current = setInterval(() => {
|
|
4806
|
+
if (popup.closed) {
|
|
4807
|
+
if (popupPollRef.current) {
|
|
4808
|
+
clearInterval(popupPollRef.current);
|
|
4809
|
+
popupPollRef.current = null;
|
|
4810
|
+
}
|
|
4811
|
+
setOauthStatus(
|
|
4812
|
+
(prev) => prev === "waiting" ? "error" : prev
|
|
4813
|
+
);
|
|
4814
|
+
setOauthResult(
|
|
4815
|
+
(prev) => prev === null ? { success: false, error: "Janela fechada antes de concluir" } : prev
|
|
4816
|
+
);
|
|
4817
|
+
}
|
|
4818
|
+
}, 500);
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
function canAdvance() {
|
|
4822
|
+
switch (currentStep) {
|
|
4823
|
+
case "info":
|
|
4824
|
+
return true;
|
|
4825
|
+
case "credentials":
|
|
4826
|
+
if (integration.authType === "oauth2") {
|
|
4827
|
+
return oauthStatus === "success";
|
|
4828
|
+
}
|
|
4829
|
+
return apiKey.trim().length > 0;
|
|
4830
|
+
case "config":
|
|
4831
|
+
return true;
|
|
4832
|
+
case "confirm":
|
|
4833
|
+
return true;
|
|
4834
|
+
default:
|
|
4835
|
+
return false;
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
function goNext() {
|
|
4839
|
+
if (!canAdvance()) return;
|
|
4840
|
+
if (currentStep === "credentials" && !meta.hasConfigStep) {
|
|
4841
|
+
setCurrentStep("confirm");
|
|
4842
|
+
return;
|
|
4843
|
+
}
|
|
4844
|
+
const nextIndex = currentIndex + 1;
|
|
4845
|
+
if (nextIndex < STEPS.length) {
|
|
4846
|
+
setCurrentStep(STEPS[nextIndex]);
|
|
4847
|
+
}
|
|
4848
|
+
}
|
|
4849
|
+
function goPrev() {
|
|
4850
|
+
if (currentStep === "confirm" && !meta.hasConfigStep) {
|
|
4851
|
+
setCurrentStep("credentials");
|
|
4852
|
+
return;
|
|
4853
|
+
}
|
|
4854
|
+
const prevIndex = currentIndex - 1;
|
|
4855
|
+
if (prevIndex >= 0) {
|
|
4856
|
+
setCurrentStep(STEPS[prevIndex]);
|
|
4857
|
+
}
|
|
4858
|
+
}
|
|
4859
|
+
async function handleComplete() {
|
|
4860
|
+
setIsSubmitting(true);
|
|
4861
|
+
try {
|
|
4862
|
+
onComplete();
|
|
4863
|
+
onOpenChange(false);
|
|
4864
|
+
toast11.success(
|
|
4865
|
+
`${integration.name} ${isReconnect ? "reconectado" : "configurado"} com sucesso!`
|
|
4866
|
+
);
|
|
4867
|
+
} catch {
|
|
4868
|
+
toast11.error("Erro ao finalizar configura\xE7\xE3o");
|
|
4869
|
+
} finally {
|
|
4870
|
+
setIsSubmitting(false);
|
|
4871
|
+
}
|
|
4872
|
+
}
|
|
4873
|
+
const selectedConfigOption = configOptions.find((o) => o.id === selectedConfigValue) || null;
|
|
4874
|
+
const isLastStep = currentStep === "confirm";
|
|
4875
|
+
const effectiveSteps = meta.hasConfigStep ? STEPS : STEPS.filter((s) => s !== "config");
|
|
4876
|
+
return /* @__PURE__ */ jsx23(Dialog7, { open, onOpenChange, children: /* @__PURE__ */ jsxs21(DialogContent7, { className: "sm:max-w-lg", children: [
|
|
4877
|
+
/* @__PURE__ */ jsx23(DialogHeader7, { children: /* @__PURE__ */ jsx23(DialogTitle7, { children: integration.name }) }),
|
|
4878
|
+
/* @__PURE__ */ jsx23(StepIndicator, { steps: effectiveSteps, currentStep }),
|
|
4879
|
+
/* @__PURE__ */ jsxs21("div", { className: "min-h-[280px] py-2", children: [
|
|
4880
|
+
currentStep === "info" && /* @__PURE__ */ jsx23(
|
|
4881
|
+
InfoStep,
|
|
4882
|
+
{
|
|
4883
|
+
integration,
|
|
4884
|
+
meta
|
|
4885
|
+
}
|
|
4886
|
+
),
|
|
4887
|
+
currentStep === "credentials" && /* @__PURE__ */ jsx23(
|
|
4888
|
+
CredentialsStep,
|
|
4889
|
+
{
|
|
4890
|
+
integration,
|
|
4891
|
+
meta,
|
|
4892
|
+
oauthStatus,
|
|
4893
|
+
oauthResult,
|
|
4894
|
+
apiKey,
|
|
4895
|
+
onApiKeyChange: setApiKey,
|
|
4896
|
+
onStartOAuth: startOAuth,
|
|
4897
|
+
isReconnect
|
|
4898
|
+
}
|
|
4899
|
+
),
|
|
4900
|
+
currentStep === "config" && /* @__PURE__ */ jsx23(
|
|
4901
|
+
ConfigStep,
|
|
4902
|
+
{
|
|
4903
|
+
integration,
|
|
4904
|
+
options: configOptions,
|
|
4905
|
+
isLoading: configLoading,
|
|
4906
|
+
selectedValue: selectedConfigValue,
|
|
4907
|
+
onValueChange: setSelectedConfigValue
|
|
4908
|
+
}
|
|
4909
|
+
),
|
|
4910
|
+
currentStep === "confirm" && /* @__PURE__ */ jsx23(
|
|
4911
|
+
ConfirmStep,
|
|
4912
|
+
{
|
|
4913
|
+
integration,
|
|
4914
|
+
oauthResult,
|
|
4915
|
+
selectedConfigOption,
|
|
4916
|
+
enableOnComplete,
|
|
4917
|
+
onEnableChange: setEnableOnComplete
|
|
4918
|
+
}
|
|
4919
|
+
)
|
|
4920
|
+
] }),
|
|
4921
|
+
/* @__PURE__ */ jsxs21(DialogFooter7, { className: "flex-row justify-between sm:justify-between", children: [
|
|
4922
|
+
/* @__PURE__ */ jsx23("div", { children: currentStep === "info" ? /* @__PURE__ */ jsx23(
|
|
4923
|
+
Button14,
|
|
4924
|
+
{
|
|
4925
|
+
type: "button",
|
|
4926
|
+
variant: "outline",
|
|
4927
|
+
onClick: () => onOpenChange(false),
|
|
4928
|
+
children: "Cancelar"
|
|
4929
|
+
}
|
|
4930
|
+
) : /* @__PURE__ */ jsxs21(
|
|
4931
|
+
Button14,
|
|
4932
|
+
{
|
|
4933
|
+
type: "button",
|
|
4934
|
+
variant: "outline",
|
|
4935
|
+
onClick: goPrev,
|
|
4936
|
+
className: "gap-1",
|
|
4937
|
+
children: [
|
|
4938
|
+
/* @__PURE__ */ jsx23(ChevronLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
|
|
4939
|
+
"Voltar"
|
|
4940
|
+
]
|
|
4941
|
+
}
|
|
4942
|
+
) }),
|
|
4943
|
+
/* @__PURE__ */ jsx23("div", { children: isLastStep ? /* @__PURE__ */ jsxs21(
|
|
4944
|
+
Button14,
|
|
4945
|
+
{
|
|
4946
|
+
type: "button",
|
|
4947
|
+
onClick: handleComplete,
|
|
4948
|
+
disabled: isSubmitting,
|
|
4949
|
+
className: "gap-1",
|
|
4950
|
+
children: [
|
|
4951
|
+
isSubmitting ? /* @__PURE__ */ jsx23(
|
|
4952
|
+
Loader28,
|
|
4953
|
+
{
|
|
4954
|
+
"aria-hidden": "true",
|
|
4955
|
+
className: "h-4 w-4 animate-spin"
|
|
4956
|
+
}
|
|
4957
|
+
) : /* @__PURE__ */ jsx23(Check2, { "aria-hidden": "true", className: "h-4 w-4" }),
|
|
4958
|
+
"Concluir"
|
|
4959
|
+
]
|
|
4960
|
+
}
|
|
4961
|
+
) : /* @__PURE__ */ jsxs21(
|
|
4962
|
+
Button14,
|
|
4963
|
+
{
|
|
4964
|
+
type: "button",
|
|
4965
|
+
onClick: goNext,
|
|
4966
|
+
disabled: !canAdvance(),
|
|
4967
|
+
className: "gap-1",
|
|
4968
|
+
children: [
|
|
4969
|
+
"Continuar",
|
|
4970
|
+
/* @__PURE__ */ jsx23(ChevronRight, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
4971
|
+
]
|
|
4972
|
+
}
|
|
4973
|
+
) })
|
|
4974
|
+
] })
|
|
4975
|
+
] }) });
|
|
4976
|
+
}
|
|
4977
|
+
function StepIndicator({
|
|
4978
|
+
steps,
|
|
4979
|
+
currentStep
|
|
4980
|
+
}) {
|
|
4981
|
+
const currentIndex = steps.indexOf(currentStep);
|
|
4982
|
+
return /* @__PURE__ */ jsx23(
|
|
4983
|
+
"div",
|
|
4984
|
+
{
|
|
4985
|
+
className: "flex items-center justify-center gap-1 py-2",
|
|
4986
|
+
role: "list",
|
|
4987
|
+
"aria-label": "Passos do assistente",
|
|
4988
|
+
children: steps.map((step, i) => {
|
|
4989
|
+
const isCompleted = i < currentIndex;
|
|
4990
|
+
const isCurrent = step === currentStep;
|
|
4991
|
+
return /* @__PURE__ */ jsxs21("div", { className: "flex items-center", role: "listitem", children: [
|
|
4992
|
+
/* @__PURE__ */ jsx23(
|
|
4993
|
+
"div",
|
|
4994
|
+
{
|
|
4995
|
+
className: `
|
|
4996
|
+
flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium
|
|
4997
|
+
transition-colors duration-200
|
|
4998
|
+
${isCurrent ? "bg-primary text-primary-foreground" : isCompleted ? "bg-green-600 text-white" : "bg-muted text-muted-foreground"}
|
|
4999
|
+
`,
|
|
5000
|
+
"aria-current": isCurrent ? "step" : void 0,
|
|
5001
|
+
"aria-label": `${STEP_LABELS[step]}${isCompleted ? " (conclu\xEDdo)" : isCurrent ? " (atual)" : ""}`,
|
|
5002
|
+
children: isCompleted ? /* @__PURE__ */ jsx23(Check2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : i + 1
|
|
5003
|
+
}
|
|
5004
|
+
),
|
|
5005
|
+
/* @__PURE__ */ jsx23(
|
|
5006
|
+
"span",
|
|
5007
|
+
{
|
|
5008
|
+
className: `
|
|
5009
|
+
ml-1.5 hidden text-xs sm:inline
|
|
5010
|
+
${isCurrent ? "font-medium text-foreground" : "text-muted-foreground"}
|
|
5011
|
+
`,
|
|
5012
|
+
children: STEP_LABELS[step]
|
|
5013
|
+
}
|
|
5014
|
+
),
|
|
5015
|
+
i < steps.length - 1 && /* @__PURE__ */ jsx23(
|
|
5016
|
+
"div",
|
|
5017
|
+
{
|
|
5018
|
+
className: `
|
|
5019
|
+
mx-2 h-px w-6
|
|
5020
|
+
${i < currentIndex ? "bg-green-600" : "bg-border"}
|
|
5021
|
+
`
|
|
5022
|
+
}
|
|
5023
|
+
)
|
|
5024
|
+
] }, step);
|
|
5025
|
+
})
|
|
5026
|
+
}
|
|
5027
|
+
);
|
|
5028
|
+
}
|
|
5029
|
+
|
|
3581
5030
|
// src/pages/agents-page.tsx
|
|
3582
|
-
import { useState as
|
|
3583
|
-
import { Button as
|
|
5031
|
+
import { useState as useState15 } from "react";
|
|
5032
|
+
import { Button as Button15 } from "@greatapps/greatauth-ui/ui";
|
|
3584
5033
|
import { Plus as Plus3 } from "lucide-react";
|
|
3585
|
-
import { jsx as
|
|
5034
|
+
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3586
5035
|
function AgentsPage({
|
|
3587
5036
|
config,
|
|
3588
5037
|
onNavigateToAgent,
|
|
3589
5038
|
title = "Agentes AI",
|
|
3590
5039
|
subtitle = "Gerencie seus agentes de atendimento inteligente"
|
|
3591
5040
|
}) {
|
|
3592
|
-
const [createOpen, setCreateOpen] =
|
|
3593
|
-
return /* @__PURE__ */
|
|
3594
|
-
/* @__PURE__ */
|
|
3595
|
-
/* @__PURE__ */
|
|
3596
|
-
/* @__PURE__ */
|
|
3597
|
-
/* @__PURE__ */
|
|
5041
|
+
const [createOpen, setCreateOpen] = useState15(false);
|
|
5042
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5043
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between", children: [
|
|
5044
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
5045
|
+
/* @__PURE__ */ jsx24("h1", { className: "text-xl font-semibold", children: title }),
|
|
5046
|
+
/* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
3598
5047
|
] }),
|
|
3599
|
-
/* @__PURE__ */
|
|
3600
|
-
/* @__PURE__ */
|
|
5048
|
+
/* @__PURE__ */ jsxs22(Button15, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5049
|
+
/* @__PURE__ */ jsx24(Plus3, { className: "mr-2 h-4 w-4" }),
|
|
3601
5050
|
"Novo Agente"
|
|
3602
5051
|
] })
|
|
3603
5052
|
] }),
|
|
3604
|
-
/* @__PURE__ */
|
|
3605
|
-
/* @__PURE__ */
|
|
5053
|
+
/* @__PURE__ */ jsx24(AgentsTable, { config, onNavigateToAgent }),
|
|
5054
|
+
/* @__PURE__ */ jsx24(
|
|
3606
5055
|
AgentFormDialog,
|
|
3607
5056
|
{
|
|
3608
5057
|
config,
|
|
@@ -3614,11 +5063,11 @@ function AgentsPage({
|
|
|
3614
5063
|
}
|
|
3615
5064
|
|
|
3616
5065
|
// src/pages/agent-detail-page.tsx
|
|
3617
|
-
import { useState as
|
|
3618
|
-
import { Badge as
|
|
5066
|
+
import { useState as useState16 } from "react";
|
|
5067
|
+
import { Badge as Badge10, Button as Button16, Skeleton as Skeleton7 } from "@greatapps/greatauth-ui/ui";
|
|
3619
5068
|
import { EntityAvatar as EntityAvatar2 } from "@greatapps/greatauth-ui";
|
|
3620
5069
|
import { ArrowLeft, Pencil as Pencil5 } from "lucide-react";
|
|
3621
|
-
import { jsx as
|
|
5070
|
+
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3622
5071
|
function AgentDetailPage({
|
|
3623
5072
|
config,
|
|
3624
5073
|
agentId,
|
|
@@ -3626,42 +5075,43 @@ function AgentDetailPage({
|
|
|
3626
5075
|
renderChatLink
|
|
3627
5076
|
}) {
|
|
3628
5077
|
const { data: agent, isLoading } = useAgent(config, agentId);
|
|
3629
|
-
const [editOpen, setEditOpen] =
|
|
5078
|
+
const [editOpen, setEditOpen] = useState16(false);
|
|
3630
5079
|
if (isLoading) {
|
|
3631
|
-
return /* @__PURE__ */
|
|
3632
|
-
/* @__PURE__ */
|
|
3633
|
-
/* @__PURE__ */
|
|
3634
|
-
/* @__PURE__ */
|
|
3635
|
-
/* @__PURE__ */
|
|
5080
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 p-4", children: [
|
|
5081
|
+
/* @__PURE__ */ jsx25(Skeleton7, { className: "h-4 w-32" }),
|
|
5082
|
+
/* @__PURE__ */ jsx25(Skeleton7, { className: "h-8 w-48" }),
|
|
5083
|
+
/* @__PURE__ */ jsx25(Skeleton7, { className: "h-10 w-full" }),
|
|
5084
|
+
/* @__PURE__ */ jsx25(Skeleton7, { className: "h-64 w-full" })
|
|
3636
5085
|
] });
|
|
3637
5086
|
}
|
|
3638
5087
|
if (!agent) {
|
|
3639
|
-
return /* @__PURE__ */
|
|
3640
|
-
/* @__PURE__ */
|
|
3641
|
-
onBack && /* @__PURE__ */
|
|
3642
|
-
/* @__PURE__ */
|
|
5088
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [
|
|
5089
|
+
/* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: "Agente n\xE3o encontrado" }),
|
|
5090
|
+
onBack && /* @__PURE__ */ jsxs23(Button16, { variant: "ghost", size: "sm", onClick: onBack, children: [
|
|
5091
|
+
/* @__PURE__ */ jsx25(ArrowLeft, { className: "mr-2 h-4 w-4" }),
|
|
3643
5092
|
"Voltar para agentes"
|
|
3644
5093
|
] })
|
|
3645
5094
|
] });
|
|
3646
5095
|
}
|
|
3647
|
-
return /* @__PURE__ */
|
|
3648
|
-
/* @__PURE__ */
|
|
3649
|
-
/* @__PURE__ */
|
|
3650
|
-
onBack && /* @__PURE__ */
|
|
3651
|
-
|
|
5096
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-6 p-4 md:p-6", children: [
|
|
5097
|
+
/* @__PURE__ */ jsx25("div", { className: "rounded-lg border p-4 md:p-6", children: /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:gap-6", children: [
|
|
5098
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-start gap-3 flex-1", children: [
|
|
5099
|
+
onBack && /* @__PURE__ */ jsx25(
|
|
5100
|
+
Button16,
|
|
3652
5101
|
{
|
|
3653
5102
|
variant: "ghost",
|
|
3654
5103
|
size: "icon",
|
|
5104
|
+
"aria-label": "Voltar",
|
|
3655
5105
|
className: "shrink-0 mt-1",
|
|
3656
5106
|
onClick: onBack,
|
|
3657
|
-
children: /* @__PURE__ */
|
|
5107
|
+
children: /* @__PURE__ */ jsx25(ArrowLeft, { className: "h-4 w-4" })
|
|
3658
5108
|
}
|
|
3659
5109
|
),
|
|
3660
|
-
/* @__PURE__ */
|
|
3661
|
-
/* @__PURE__ */
|
|
3662
|
-
/* @__PURE__ */
|
|
3663
|
-
/* @__PURE__ */
|
|
3664
|
-
|
|
5110
|
+
/* @__PURE__ */ jsx25(EntityAvatar2, { photo: agent.photo, name: agent.title, size: "xl" }),
|
|
5111
|
+
/* @__PURE__ */ jsx25("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
5112
|
+
/* @__PURE__ */ jsx25("h1", { className: "text-xl font-semibold", children: agent.title }),
|
|
5113
|
+
/* @__PURE__ */ jsx25(
|
|
5114
|
+
Badge10,
|
|
3665
5115
|
{
|
|
3666
5116
|
variant: agent.active ? "default" : "destructive",
|
|
3667
5117
|
className: "text-xs",
|
|
@@ -3670,21 +5120,21 @@ function AgentDetailPage({
|
|
|
3670
5120
|
)
|
|
3671
5121
|
] }) })
|
|
3672
5122
|
] }),
|
|
3673
|
-
/* @__PURE__ */
|
|
3674
|
-
|
|
5123
|
+
/* @__PURE__ */ jsxs23(
|
|
5124
|
+
Button16,
|
|
3675
5125
|
{
|
|
3676
5126
|
variant: "outline",
|
|
3677
5127
|
size: "sm",
|
|
3678
5128
|
className: "shrink-0 self-start",
|
|
3679
5129
|
onClick: () => setEditOpen(true),
|
|
3680
5130
|
children: [
|
|
3681
|
-
/* @__PURE__ */
|
|
5131
|
+
/* @__PURE__ */ jsx25(Pencil5, { className: "mr-2 h-4 w-4" }),
|
|
3682
5132
|
"Editar"
|
|
3683
5133
|
]
|
|
3684
5134
|
}
|
|
3685
5135
|
)
|
|
3686
5136
|
] }) }),
|
|
3687
|
-
/* @__PURE__ */
|
|
5137
|
+
/* @__PURE__ */ jsx25(
|
|
3688
5138
|
AgentTabs,
|
|
3689
5139
|
{
|
|
3690
5140
|
agent,
|
|
@@ -3692,7 +5142,7 @@ function AgentDetailPage({
|
|
|
3692
5142
|
renderChatLink
|
|
3693
5143
|
}
|
|
3694
5144
|
),
|
|
3695
|
-
editOpen && /* @__PURE__ */
|
|
5145
|
+
editOpen && /* @__PURE__ */ jsx25(
|
|
3696
5146
|
AgentEditForm,
|
|
3697
5147
|
{
|
|
3698
5148
|
agent,
|
|
@@ -3705,31 +5155,133 @@ function AgentDetailPage({
|
|
|
3705
5155
|
] });
|
|
3706
5156
|
}
|
|
3707
5157
|
|
|
5158
|
+
// src/pages/agent-capabilities-page.tsx
|
|
5159
|
+
import { useState as useState17, useCallback as useCallback6 } from "react";
|
|
5160
|
+
import {
|
|
5161
|
+
Tabs as Tabs2,
|
|
5162
|
+
TabsList as TabsList2,
|
|
5163
|
+
TabsTrigger as TabsTrigger2,
|
|
5164
|
+
TabsContent as TabsContent2
|
|
5165
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
5166
|
+
import { Blocks, Plug as Plug3, Settings as Settings4 } from "lucide-react";
|
|
5167
|
+
import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5168
|
+
function defaultResolveWizardMeta(card) {
|
|
5169
|
+
return {
|
|
5170
|
+
capabilities: [
|
|
5171
|
+
{ label: card.definition.name, description: card.definition.description }
|
|
5172
|
+
],
|
|
5173
|
+
requirements: [],
|
|
5174
|
+
hasConfigStep: false
|
|
5175
|
+
};
|
|
5176
|
+
}
|
|
5177
|
+
function AgentCapabilitiesPage({
|
|
5178
|
+
config,
|
|
5179
|
+
agentId,
|
|
5180
|
+
gagentsApiUrl,
|
|
5181
|
+
resolveWizardMeta = defaultResolveWizardMeta,
|
|
5182
|
+
loadConfigOptions,
|
|
5183
|
+
onWizardComplete
|
|
5184
|
+
}) {
|
|
5185
|
+
const [wizardOpen, setWizardOpen] = useState17(false);
|
|
5186
|
+
const [activeCard, setActiveCard] = useState17(null);
|
|
5187
|
+
const handleConnect = useCallback6(
|
|
5188
|
+
(card) => {
|
|
5189
|
+
setActiveCard(card);
|
|
5190
|
+
setWizardOpen(true);
|
|
5191
|
+
},
|
|
5192
|
+
[]
|
|
5193
|
+
);
|
|
5194
|
+
const handleWizardComplete = useCallback6(() => {
|
|
5195
|
+
setWizardOpen(false);
|
|
5196
|
+
setActiveCard(null);
|
|
5197
|
+
onWizardComplete?.();
|
|
5198
|
+
}, [onWizardComplete]);
|
|
5199
|
+
const handleWizardOpenChange = useCallback6((open) => {
|
|
5200
|
+
setWizardOpen(open);
|
|
5201
|
+
if (!open) setActiveCard(null);
|
|
5202
|
+
}, []);
|
|
5203
|
+
const wizardMeta = activeCard ? resolveWizardMeta(activeCard) : null;
|
|
5204
|
+
return /* @__PURE__ */ jsxs24("div", { className: "space-y-4", children: [
|
|
5205
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
5206
|
+
/* @__PURE__ */ jsx26("h2", { className: "text-lg font-semibold", children: "Capacidades e Integra\xE7\xF5es" }),
|
|
5207
|
+
/* @__PURE__ */ jsx26("p", { className: "text-sm text-muted-foreground", children: "Configure o que este agente pode fazer e quais servi\xE7os externos ele utiliza." })
|
|
5208
|
+
] }),
|
|
5209
|
+
/* @__PURE__ */ jsxs24(Tabs2, { defaultValue: "capacidades", children: [
|
|
5210
|
+
/* @__PURE__ */ jsxs24(TabsList2, { children: [
|
|
5211
|
+
/* @__PURE__ */ jsxs24(TabsTrigger2, { value: "capacidades", className: "flex items-center gap-1.5", children: [
|
|
5212
|
+
/* @__PURE__ */ jsx26(Blocks, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5213
|
+
"Capacidades"
|
|
5214
|
+
] }),
|
|
5215
|
+
/* @__PURE__ */ jsxs24(TabsTrigger2, { value: "integracoes", className: "flex items-center gap-1.5", children: [
|
|
5216
|
+
/* @__PURE__ */ jsx26(Plug3, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5217
|
+
"Integra\xE7\xF5es"
|
|
5218
|
+
] }),
|
|
5219
|
+
/* @__PURE__ */ jsxs24(TabsTrigger2, { value: "avancado", className: "flex items-center gap-1.5", children: [
|
|
5220
|
+
/* @__PURE__ */ jsx26(Settings4, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5221
|
+
"Avan\xE7ado"
|
|
5222
|
+
] })
|
|
5223
|
+
] }),
|
|
5224
|
+
/* @__PURE__ */ jsx26(TabsContent2, { value: "capacidades", className: "mt-4", children: /* @__PURE__ */ jsx26(CapabilitiesTab, { config, agentId }) }),
|
|
5225
|
+
/* @__PURE__ */ jsx26(TabsContent2, { value: "integracoes", className: "mt-4", children: /* @__PURE__ */ jsx26(
|
|
5226
|
+
IntegrationsTab,
|
|
5227
|
+
{
|
|
5228
|
+
config,
|
|
5229
|
+
agentId,
|
|
5230
|
+
onConnect: handleConnect
|
|
5231
|
+
}
|
|
5232
|
+
) }),
|
|
5233
|
+
/* @__PURE__ */ jsx26(TabsContent2, { value: "avancado", className: "mt-4", children: /* @__PURE__ */ jsx26(
|
|
5234
|
+
AdvancedTab,
|
|
5235
|
+
{
|
|
5236
|
+
config,
|
|
5237
|
+
agentId,
|
|
5238
|
+
gagentsApiUrl
|
|
5239
|
+
}
|
|
5240
|
+
) })
|
|
5241
|
+
] }),
|
|
5242
|
+
activeCard && wizardMeta && /* @__PURE__ */ jsx26(
|
|
5243
|
+
IntegrationWizard,
|
|
5244
|
+
{
|
|
5245
|
+
open: wizardOpen,
|
|
5246
|
+
onOpenChange: handleWizardOpenChange,
|
|
5247
|
+
integration: activeCard.definition,
|
|
5248
|
+
meta: wizardMeta,
|
|
5249
|
+
agentId,
|
|
5250
|
+
config,
|
|
5251
|
+
onComplete: handleWizardComplete,
|
|
5252
|
+
gagentsApiUrl,
|
|
5253
|
+
existingCredentialId: activeCard.credential?.id,
|
|
5254
|
+
loadConfigOptions
|
|
5255
|
+
}
|
|
5256
|
+
)
|
|
5257
|
+
] });
|
|
5258
|
+
}
|
|
5259
|
+
|
|
3708
5260
|
// src/pages/tools-page.tsx
|
|
3709
|
-
import { useState as
|
|
3710
|
-
import { Button as
|
|
5261
|
+
import { useState as useState18 } from "react";
|
|
5262
|
+
import { Button as Button17 } from "@greatapps/greatauth-ui/ui";
|
|
3711
5263
|
import { Plus as Plus4 } from "lucide-react";
|
|
3712
|
-
import { jsx as
|
|
5264
|
+
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3713
5265
|
function ToolsPage({
|
|
3714
5266
|
config,
|
|
3715
5267
|
title = "Ferramentas",
|
|
3716
5268
|
subtitle = "Gerencie as ferramentas dispon\xEDveis para seus agentes"
|
|
3717
5269
|
}) {
|
|
3718
|
-
const [createOpen, setCreateOpen] =
|
|
3719
|
-
const [editTool, setEditTool] =
|
|
3720
|
-
return /* @__PURE__ */
|
|
3721
|
-
/* @__PURE__ */
|
|
3722
|
-
/* @__PURE__ */
|
|
3723
|
-
/* @__PURE__ */
|
|
3724
|
-
/* @__PURE__ */
|
|
5270
|
+
const [createOpen, setCreateOpen] = useState18(false);
|
|
5271
|
+
const [editTool, setEditTool] = useState18(void 0);
|
|
5272
|
+
return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5273
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between", children: [
|
|
5274
|
+
/* @__PURE__ */ jsxs25("div", { children: [
|
|
5275
|
+
/* @__PURE__ */ jsx27("h1", { className: "text-xl font-semibold", children: title }),
|
|
5276
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
3725
5277
|
] }),
|
|
3726
|
-
/* @__PURE__ */
|
|
3727
|
-
/* @__PURE__ */
|
|
5278
|
+
/* @__PURE__ */ jsxs25(Button17, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5279
|
+
/* @__PURE__ */ jsx27(Plus4, { className: "mr-2 h-4 w-4" }),
|
|
3728
5280
|
"Nova Ferramenta"
|
|
3729
5281
|
] })
|
|
3730
5282
|
] }),
|
|
3731
|
-
/* @__PURE__ */
|
|
3732
|
-
/* @__PURE__ */
|
|
5283
|
+
/* @__PURE__ */ jsx27(ToolsTable, { config, onEdit: (tool) => setEditTool(tool) }),
|
|
5284
|
+
/* @__PURE__ */ jsx27(
|
|
3733
5285
|
ToolFormDialog,
|
|
3734
5286
|
{
|
|
3735
5287
|
config,
|
|
@@ -3737,7 +5289,7 @@ function ToolsPage({
|
|
|
3737
5289
|
onOpenChange: setCreateOpen
|
|
3738
5290
|
}
|
|
3739
5291
|
),
|
|
3740
|
-
/* @__PURE__ */
|
|
5292
|
+
/* @__PURE__ */ jsx27(
|
|
3741
5293
|
ToolFormDialog,
|
|
3742
5294
|
{
|
|
3743
5295
|
config,
|
|
@@ -3750,10 +5302,10 @@ function ToolsPage({
|
|
|
3750
5302
|
}
|
|
3751
5303
|
|
|
3752
5304
|
// src/pages/credentials-page.tsx
|
|
3753
|
-
import { useState as
|
|
3754
|
-
import { Button as
|
|
5305
|
+
import { useState as useState19 } from "react";
|
|
5306
|
+
import { Button as Button18 } from "@greatapps/greatauth-ui/ui";
|
|
3755
5307
|
import { Plus as Plus5 } from "lucide-react";
|
|
3756
|
-
import { jsx as
|
|
5308
|
+
import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3757
5309
|
function CredentialsPage({
|
|
3758
5310
|
config,
|
|
3759
5311
|
gagentsApiUrl,
|
|
@@ -3761,20 +5313,20 @@ function CredentialsPage({
|
|
|
3761
5313
|
subtitle = "Gerencie as credenciais de autentica\xE7\xE3o das ferramentas"
|
|
3762
5314
|
}) {
|
|
3763
5315
|
const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
|
|
3764
|
-
const [createOpen, setCreateOpen] =
|
|
5316
|
+
const [createOpen, setCreateOpen] = useState19(false);
|
|
3765
5317
|
const credentials = credentialsData?.data || [];
|
|
3766
|
-
return /* @__PURE__ */
|
|
3767
|
-
/* @__PURE__ */
|
|
3768
|
-
/* @__PURE__ */
|
|
3769
|
-
/* @__PURE__ */
|
|
3770
|
-
/* @__PURE__ */
|
|
5318
|
+
return /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5319
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between", children: [
|
|
5320
|
+
/* @__PURE__ */ jsxs26("div", { children: [
|
|
5321
|
+
/* @__PURE__ */ jsx28("h1", { className: "text-xl font-semibold", children: title }),
|
|
5322
|
+
/* @__PURE__ */ jsx28("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
3771
5323
|
] }),
|
|
3772
|
-
/* @__PURE__ */
|
|
3773
|
-
/* @__PURE__ */
|
|
5324
|
+
/* @__PURE__ */ jsxs26(Button18, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5325
|
+
/* @__PURE__ */ jsx28(Plus5, { className: "mr-2 h-4 w-4" }),
|
|
3774
5326
|
"Nova Credencial"
|
|
3775
5327
|
] })
|
|
3776
5328
|
] }),
|
|
3777
|
-
/* @__PURE__ */
|
|
5329
|
+
/* @__PURE__ */ jsx28(
|
|
3778
5330
|
ToolCredentialsForm,
|
|
3779
5331
|
{
|
|
3780
5332
|
config,
|
|
@@ -3787,7 +5339,117 @@ function CredentialsPage({
|
|
|
3787
5339
|
)
|
|
3788
5340
|
] });
|
|
3789
5341
|
}
|
|
5342
|
+
|
|
5343
|
+
// src/pages/integrations-management-page.tsx
|
|
5344
|
+
import { useState as useState20, useMemo as useMemo8 } from "react";
|
|
5345
|
+
import {
|
|
5346
|
+
Badge as Badge11,
|
|
5347
|
+
Button as Button19,
|
|
5348
|
+
Tabs as Tabs3,
|
|
5349
|
+
TabsContent as TabsContent3,
|
|
5350
|
+
TabsList as TabsList3,
|
|
5351
|
+
TabsTrigger as TabsTrigger3
|
|
5352
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
5353
|
+
import { Plus as Plus6, Plug as Plug4, KeyRound, Info as Info3 } from "lucide-react";
|
|
5354
|
+
import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5355
|
+
function useCredentialAgentSummary(credentials, tools, agents) {
|
|
5356
|
+
return useMemo8(() => {
|
|
5357
|
+
const toolIdsWithCredentials = new Set(
|
|
5358
|
+
credentials.map((c) => c.id_tool).filter(Boolean)
|
|
5359
|
+
);
|
|
5360
|
+
const linkedCount = credentials.filter(
|
|
5361
|
+
(c) => c.id_tool && toolIdsWithCredentials.has(c.id_tool)
|
|
5362
|
+
).length;
|
|
5363
|
+
return {
|
|
5364
|
+
totalCredentials: credentials.length,
|
|
5365
|
+
linkedToTools: linkedCount,
|
|
5366
|
+
totalAgents: agents.length,
|
|
5367
|
+
totalTools: tools.length
|
|
5368
|
+
};
|
|
5369
|
+
}, [credentials, tools, agents]);
|
|
5370
|
+
}
|
|
5371
|
+
function IntegrationsManagementPage({
|
|
5372
|
+
config,
|
|
5373
|
+
gagentsApiUrl,
|
|
5374
|
+
onConnect,
|
|
5375
|
+
title = "Integra\xE7\xF5es e Credenciais",
|
|
5376
|
+
subtitle = "Gerencie todas as integra\xE7\xF5es e credenciais da conta."
|
|
5377
|
+
}) {
|
|
5378
|
+
const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
|
|
5379
|
+
const { data: agentsData } = useAgents(config);
|
|
5380
|
+
const { data: toolsData } = useTools(config);
|
|
5381
|
+
const [createOpen, setCreateOpen] = useState20(false);
|
|
5382
|
+
const credentials = credentialsData?.data || [];
|
|
5383
|
+
const agents = agentsData?.data || [];
|
|
5384
|
+
const tools = toolsData?.data || [];
|
|
5385
|
+
const summary = useCredentialAgentSummary(credentials, tools, agents);
|
|
5386
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5387
|
+
/* @__PURE__ */ jsx29("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs27("div", { children: [
|
|
5388
|
+
/* @__PURE__ */ jsx29("h1", { className: "text-xl font-semibold", children: title }),
|
|
5389
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
5390
|
+
] }) }),
|
|
5391
|
+
/* @__PURE__ */ jsxs27(Tabs3, { defaultValue: "integrations", className: "w-full", children: [
|
|
5392
|
+
/* @__PURE__ */ jsxs27(TabsList3, { children: [
|
|
5393
|
+
/* @__PURE__ */ jsxs27(TabsTrigger3, { value: "integrations", className: "gap-2", children: [
|
|
5394
|
+
/* @__PURE__ */ jsx29(Plug4, { className: "h-4 w-4" }),
|
|
5395
|
+
"Integra\xE7\xF5es"
|
|
5396
|
+
] }),
|
|
5397
|
+
/* @__PURE__ */ jsxs27(TabsTrigger3, { value: "credentials", className: "gap-2", children: [
|
|
5398
|
+
/* @__PURE__ */ jsx29(KeyRound, { className: "h-4 w-4" }),
|
|
5399
|
+
"Credenciais"
|
|
5400
|
+
] })
|
|
5401
|
+
] }),
|
|
5402
|
+
/* @__PURE__ */ jsx29(TabsContent3, { value: "integrations", className: "mt-4", children: /* @__PURE__ */ jsx29(
|
|
5403
|
+
IntegrationsTab,
|
|
5404
|
+
{
|
|
5405
|
+
config,
|
|
5406
|
+
agentId: null,
|
|
5407
|
+
onConnect: onConnect ?? (() => {
|
|
5408
|
+
})
|
|
5409
|
+
}
|
|
5410
|
+
) }),
|
|
5411
|
+
/* @__PURE__ */ jsxs27(TabsContent3, { value: "credentials", className: "mt-4", children: [
|
|
5412
|
+
!credentialsLoading && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-4 rounded-lg border bg-muted/50 px-4 py-3 mb-4", children: [
|
|
5413
|
+
/* @__PURE__ */ jsx29(Info3, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
|
|
5414
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex flex-wrap items-center gap-3 text-sm", children: [
|
|
5415
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
5416
|
+
/* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalCredentials }),
|
|
5417
|
+
summary.totalCredentials === 1 ? "credencial configurada" : "credenciais configuradas"
|
|
5418
|
+
] }),
|
|
5419
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
|
|
5420
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
5421
|
+
/* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.linkedToTools }),
|
|
5422
|
+
summary.linkedToTools === 1 ? "vinculada a ferramentas" : "vinculadas a ferramentas"
|
|
5423
|
+
] }),
|
|
5424
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
|
|
5425
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
5426
|
+
/* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalAgents }),
|
|
5427
|
+
summary.totalAgents === 1 ? "agente na conta" : "agentes na conta"
|
|
5428
|
+
] })
|
|
5429
|
+
] })
|
|
5430
|
+
] }),
|
|
5431
|
+
/* @__PURE__ */ jsx29("div", { className: "flex items-center justify-end mb-4", children: /* @__PURE__ */ jsxs27(Button19, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5432
|
+
/* @__PURE__ */ jsx29(Plus6, { className: "mr-2 h-4 w-4" }),
|
|
5433
|
+
"Nova Credencial"
|
|
5434
|
+
] }) }),
|
|
5435
|
+
/* @__PURE__ */ jsx29(
|
|
5436
|
+
ToolCredentialsForm,
|
|
5437
|
+
{
|
|
5438
|
+
config,
|
|
5439
|
+
gagentsApiUrl,
|
|
5440
|
+
credentials,
|
|
5441
|
+
isLoading: credentialsLoading,
|
|
5442
|
+
createOpen,
|
|
5443
|
+
onCreateOpenChange: setCreateOpen
|
|
5444
|
+
}
|
|
5445
|
+
)
|
|
5446
|
+
] })
|
|
5447
|
+
] })
|
|
5448
|
+
] });
|
|
5449
|
+
}
|
|
3790
5450
|
export {
|
|
5451
|
+
AdvancedTab,
|
|
5452
|
+
AgentCapabilitiesPage,
|
|
3791
5453
|
AgentConversationsPanel,
|
|
3792
5454
|
AgentConversationsTable,
|
|
3793
5455
|
AgentDetailPage,
|
|
@@ -3799,8 +5461,14 @@ export {
|
|
|
3799
5461
|
AgentToolsList,
|
|
3800
5462
|
AgentsPage,
|
|
3801
5463
|
AgentsTable,
|
|
5464
|
+
CapabilitiesTab,
|
|
3802
5465
|
ConversationView,
|
|
3803
5466
|
CredentialsPage,
|
|
5467
|
+
INTEGRATIONS_REGISTRY,
|
|
5468
|
+
IntegrationCard,
|
|
5469
|
+
IntegrationWizard,
|
|
5470
|
+
IntegrationsManagementPage,
|
|
5471
|
+
IntegrationsTab,
|
|
3804
5472
|
Sortable,
|
|
3805
5473
|
SortableContent,
|
|
3806
5474
|
SortableItem,
|
|
@@ -3814,9 +5482,11 @@ export {
|
|
|
3814
5482
|
createGagentsClient,
|
|
3815
5483
|
useAddAgentTool,
|
|
3816
5484
|
useAgent,
|
|
5485
|
+
useAgentCapabilities,
|
|
3817
5486
|
useAgentConversations,
|
|
3818
5487
|
useAgentTools,
|
|
3819
5488
|
useAgents,
|
|
5489
|
+
useCapabilities,
|
|
3820
5490
|
useContactUsers,
|
|
3821
5491
|
useConversation,
|
|
3822
5492
|
useConversations,
|
|
@@ -3830,6 +5500,7 @@ export {
|
|
|
3830
5500
|
useDeleteToolCredential,
|
|
3831
5501
|
useGagentsClient,
|
|
3832
5502
|
useGagentsContacts,
|
|
5503
|
+
useIntegrationState,
|
|
3833
5504
|
useObjectives,
|
|
3834
5505
|
usePromptVersions,
|
|
3835
5506
|
useRemoveAgentTool,
|
|
@@ -3837,6 +5508,7 @@ export {
|
|
|
3837
5508
|
useToolCredentials,
|
|
3838
5509
|
useTools,
|
|
3839
5510
|
useUpdateAgent,
|
|
5511
|
+
useUpdateAgentCapabilities,
|
|
3840
5512
|
useUpdateAgentTool,
|
|
3841
5513
|
useUpdateObjective,
|
|
3842
5514
|
useUpdateTool,
|