@greatapps/greatagents-ui 0.3.3 → 0.3.5
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 +214 -3
- package/dist/index.js +2532 -850
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +14 -0
- package/src/components/agents/agent-form-dialog.tsx +109 -29
- package/src/components/agents/agent-tabs.tsx +39 -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/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/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,
|
|
@@ -532,7 +638,7 @@ function useColumns(onEdit, onDelete) {
|
|
|
532
638
|
function AgentsTable({ config, onNavigateToAgent }) {
|
|
533
639
|
const [search, setSearch] = useState("");
|
|
534
640
|
const [page, setPage] = useState(1);
|
|
535
|
-
const queryParams =
|
|
641
|
+
const queryParams = useMemo3(() => {
|
|
536
642
|
const params = {
|
|
537
643
|
limit: "15",
|
|
538
644
|
page: String(page)
|
|
@@ -633,11 +739,39 @@ import {
|
|
|
633
739
|
DialogFooter,
|
|
634
740
|
Button as Button2,
|
|
635
741
|
Input as Input2,
|
|
636
|
-
Label
|
|
742
|
+
Label,
|
|
743
|
+
Switch
|
|
637
744
|
} from "@greatapps/greatauth-ui/ui";
|
|
638
745
|
import { Loader2 } from "lucide-react";
|
|
639
746
|
import { toast as toast2 } from "sonner";
|
|
640
747
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
748
|
+
function msToSeconds(ms) {
|
|
749
|
+
if (ms == null || ms === 0) return "";
|
|
750
|
+
return String(Math.round(ms / 1e3));
|
|
751
|
+
}
|
|
752
|
+
function secondsToMs(seconds) {
|
|
753
|
+
const val = parseFloat(seconds);
|
|
754
|
+
if (isNaN(val) || val <= 0) return void 0;
|
|
755
|
+
return Math.round(val * 1e3);
|
|
756
|
+
}
|
|
757
|
+
function agentToFormState(agent) {
|
|
758
|
+
return {
|
|
759
|
+
title: agent.title,
|
|
760
|
+
photo: agent.photo || "",
|
|
761
|
+
active: agent.active,
|
|
762
|
+
delayTyping: msToSeconds(agent.delay_typing),
|
|
763
|
+
waitingTime: msToSeconds(agent.waiting_time),
|
|
764
|
+
titleError: false
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
var emptyFormState = {
|
|
768
|
+
title: "",
|
|
769
|
+
photo: "",
|
|
770
|
+
active: true,
|
|
771
|
+
delayTyping: "",
|
|
772
|
+
waitingTime: "",
|
|
773
|
+
titleError: false
|
|
774
|
+
};
|
|
641
775
|
function AgentFormDialog({
|
|
642
776
|
config,
|
|
643
777
|
open,
|
|
@@ -647,33 +781,36 @@ function AgentFormDialog({
|
|
|
647
781
|
const isEditing = !!agent;
|
|
648
782
|
const createAgent = useCreateAgent(config);
|
|
649
783
|
const updateAgent = useUpdateAgent(config);
|
|
650
|
-
const [
|
|
651
|
-
const [photo, setPhoto] = useState2("");
|
|
652
|
-
const [delayTyping, setDelayTyping] = useState2("");
|
|
653
|
-
const [waitingTime, setWaitingTime] = useState2("");
|
|
784
|
+
const [form, setForm] = useState2(emptyFormState);
|
|
654
785
|
useEffect(() => {
|
|
655
786
|
if (agent) {
|
|
656
|
-
|
|
657
|
-
setPhoto(agent.photo || "");
|
|
658
|
-
setDelayTyping(agent.delay_typing != null ? String(agent.delay_typing) : "");
|
|
659
|
-
setWaitingTime(agent.waiting_time != null ? String(agent.waiting_time) : "");
|
|
787
|
+
setForm(agentToFormState(agent));
|
|
660
788
|
} else {
|
|
661
|
-
|
|
662
|
-
setPhoto("");
|
|
663
|
-
setDelayTyping("");
|
|
664
|
-
setWaitingTime("");
|
|
789
|
+
setForm(emptyFormState);
|
|
665
790
|
}
|
|
666
791
|
}, [agent, open]);
|
|
792
|
+
function updateField(key, value) {
|
|
793
|
+
setForm((prev) => ({ ...prev, [key]: value }));
|
|
794
|
+
}
|
|
667
795
|
const isPending = createAgent.isPending || updateAgent.isPending;
|
|
668
796
|
async function handleSubmit(e) {
|
|
669
797
|
e.preventDefault();
|
|
670
|
-
if (!title.trim())
|
|
798
|
+
if (!form.title.trim()) {
|
|
799
|
+
updateField("titleError", true);
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
671
802
|
const body = {
|
|
672
|
-
title: title.trim()
|
|
803
|
+
title: form.title.trim(),
|
|
804
|
+
active: form.active
|
|
673
805
|
};
|
|
674
|
-
if (photo.trim()) body.photo = photo.trim();
|
|
675
|
-
if (
|
|
676
|
-
|
|
806
|
+
if (form.photo.trim()) body.photo = form.photo.trim();
|
|
807
|
+
else if (isEditing) body.photo = "";
|
|
808
|
+
const delayMs = secondsToMs(form.delayTyping);
|
|
809
|
+
if (delayMs !== void 0) body.delay_typing = delayMs;
|
|
810
|
+
else if (isEditing) body.delay_typing = 0;
|
|
811
|
+
const waitingMs = secondsToMs(form.waitingTime);
|
|
812
|
+
if (waitingMs !== void 0) body.waiting_time = waitingMs;
|
|
813
|
+
else if (isEditing) body.waiting_time = 0;
|
|
677
814
|
try {
|
|
678
815
|
if (isEditing) {
|
|
679
816
|
await updateAgent.mutateAsync({ id: agent.id, body });
|
|
@@ -699,12 +836,13 @@ function AgentFormDialog({
|
|
|
699
836
|
{
|
|
700
837
|
id: "agent-photo",
|
|
701
838
|
name: "photo",
|
|
702
|
-
value: photo,
|
|
703
|
-
onChange: (e) =>
|
|
839
|
+
value: form.photo,
|
|
840
|
+
onChange: (e) => updateField("photo", e.target.value),
|
|
704
841
|
placeholder: "https://exemplo.com/foto.jpg",
|
|
705
842
|
disabled: isPending
|
|
706
843
|
}
|
|
707
|
-
)
|
|
844
|
+
),
|
|
845
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-muted-foreground", children: "URL da imagem de avatar do agente" })
|
|
708
846
|
] }),
|
|
709
847
|
/* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
710
848
|
/* @__PURE__ */ jsx2(Label, { htmlFor: "agent-title", children: "Nome do Agente *" }),
|
|
@@ -713,46 +851,69 @@ function AgentFormDialog({
|
|
|
713
851
|
{
|
|
714
852
|
id: "agent-title",
|
|
715
853
|
name: "title",
|
|
716
|
-
value: title,
|
|
717
|
-
onChange: (e) =>
|
|
854
|
+
value: form.title,
|
|
855
|
+
onChange: (e) => {
|
|
856
|
+
setForm((prev) => ({
|
|
857
|
+
...prev,
|
|
858
|
+
title: e.target.value,
|
|
859
|
+
titleError: e.target.value.trim() ? false : prev.titleError
|
|
860
|
+
}));
|
|
861
|
+
},
|
|
718
862
|
placeholder: "Ex: Assistente de Agendamento",
|
|
719
863
|
required: true,
|
|
720
864
|
disabled: isPending
|
|
721
865
|
}
|
|
722
|
-
)
|
|
866
|
+
),
|
|
867
|
+
form.titleError && /* @__PURE__ */ jsx2("p", { className: "text-sm text-destructive", children: "Nome \xE9 obrigat\xF3rio" })
|
|
868
|
+
] }),
|
|
869
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3", children: [
|
|
870
|
+
/* @__PURE__ */ jsx2(
|
|
871
|
+
Switch,
|
|
872
|
+
{
|
|
873
|
+
id: "agent-active",
|
|
874
|
+
checked: form.active,
|
|
875
|
+
onCheckedChange: (checked) => updateField("active", checked),
|
|
876
|
+
disabled: isPending
|
|
877
|
+
}
|
|
878
|
+
),
|
|
879
|
+
/* @__PURE__ */ jsx2(Label, { htmlFor: "agent-active", className: "cursor-pointer", children: form.active ? "Ativo" : "Inativo" })
|
|
723
880
|
] }),
|
|
724
881
|
/* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
725
882
|
/* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
726
|
-
/* @__PURE__ */ jsx2(Label, { htmlFor: "agent-delay", children: "Delay de Digita\xE7\xE3o (
|
|
883
|
+
/* @__PURE__ */ jsx2(Label, { htmlFor: "agent-delay", children: "Delay de Digita\xE7\xE3o (s)" }),
|
|
727
884
|
/* @__PURE__ */ jsx2(
|
|
728
885
|
Input2,
|
|
729
886
|
{
|
|
730
887
|
id: "agent-delay",
|
|
731
888
|
name: "delay",
|
|
732
889
|
type: "number",
|
|
733
|
-
value: delayTyping,
|
|
734
|
-
onChange: (e) =>
|
|
890
|
+
value: form.delayTyping,
|
|
891
|
+
onChange: (e) => updateField("delayTyping", e.target.value),
|
|
735
892
|
placeholder: "0",
|
|
736
893
|
min: "0",
|
|
894
|
+
step: "0.5",
|
|
737
895
|
disabled: isPending
|
|
738
896
|
}
|
|
739
|
-
)
|
|
897
|
+
),
|
|
898
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-muted-foreground", children: "Tempo de simula\xE7\xE3o de digita\xE7\xE3o" })
|
|
740
899
|
] }),
|
|
741
900
|
/* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
742
|
-
/* @__PURE__ */ jsx2(Label, { htmlFor: "agent-waiting", children: "Tempo de Espera (
|
|
901
|
+
/* @__PURE__ */ jsx2(Label, { htmlFor: "agent-waiting", children: "Tempo de Espera (s)" }),
|
|
743
902
|
/* @__PURE__ */ jsx2(
|
|
744
903
|
Input2,
|
|
745
904
|
{
|
|
746
905
|
id: "agent-waiting",
|
|
747
906
|
name: "waiting",
|
|
748
907
|
type: "number",
|
|
749
|
-
value: waitingTime,
|
|
750
|
-
onChange: (e) =>
|
|
908
|
+
value: form.waitingTime,
|
|
909
|
+
onChange: (e) => updateField("waitingTime", e.target.value),
|
|
751
910
|
placeholder: "0",
|
|
752
911
|
min: "0",
|
|
912
|
+
step: "0.5",
|
|
753
913
|
disabled: isPending
|
|
754
914
|
}
|
|
755
|
-
)
|
|
915
|
+
),
|
|
916
|
+
/* @__PURE__ */ jsx2("p", { className: "text-xs text-muted-foreground", children: "Espera por mensagens agrupadas" })
|
|
756
917
|
] })
|
|
757
918
|
] }),
|
|
758
919
|
/* @__PURE__ */ jsxs2(DialogFooter, { children: [
|
|
@@ -766,7 +927,7 @@ function AgentFormDialog({
|
|
|
766
927
|
children: "Cancelar"
|
|
767
928
|
}
|
|
768
929
|
),
|
|
769
|
-
/* @__PURE__ */ jsxs2(Button2, { type: "submit", disabled: isPending || !title.trim(), children: [
|
|
930
|
+
/* @__PURE__ */ jsxs2(Button2, { type: "submit", disabled: isPending || !form.title.trim(), children: [
|
|
770
931
|
isPending ? /* @__PURE__ */ jsx2(Loader2, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
771
932
|
isEditing ? "Salvar" : "Criar"
|
|
772
933
|
] })
|
|
@@ -781,7 +942,7 @@ import {
|
|
|
781
942
|
Button as Button3,
|
|
782
943
|
Input as Input3,
|
|
783
944
|
Label as Label2,
|
|
784
|
-
Switch,
|
|
945
|
+
Switch as Switch2,
|
|
785
946
|
Dialog as Dialog2,
|
|
786
947
|
DialogContent as DialogContent2,
|
|
787
948
|
DialogHeader as DialogHeader2,
|
|
@@ -792,30 +953,30 @@ import { Loader2 as Loader22 } from "lucide-react";
|
|
|
792
953
|
import { toast as toast3 } from "sonner";
|
|
793
954
|
import { ImageCropUpload } from "@greatapps/greatauth-ui";
|
|
794
955
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
795
|
-
function
|
|
956
|
+
function msToSeconds2(ms) {
|
|
796
957
|
if (ms == null || ms === 0) return "";
|
|
797
958
|
return String(Math.round(ms / 1e3));
|
|
798
959
|
}
|
|
799
|
-
function
|
|
960
|
+
function secondsToMs2(seconds) {
|
|
800
961
|
const val = parseFloat(seconds);
|
|
801
962
|
if (isNaN(val) || val <= 0) return void 0;
|
|
802
963
|
return Math.round(val * 1e3);
|
|
803
964
|
}
|
|
804
|
-
function
|
|
965
|
+
function agentToFormState2(agent) {
|
|
805
966
|
return {
|
|
806
967
|
title: agent.title,
|
|
807
968
|
photo: agent.photo || "",
|
|
808
969
|
active: agent.active,
|
|
809
|
-
delayTyping:
|
|
810
|
-
waitingTime:
|
|
970
|
+
delayTyping: msToSeconds2(agent.delay_typing),
|
|
971
|
+
waitingTime: msToSeconds2(agent.waiting_time),
|
|
811
972
|
titleError: false
|
|
812
973
|
};
|
|
813
974
|
}
|
|
814
975
|
function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
|
|
815
976
|
const updateAgent = useUpdateAgent(config);
|
|
816
|
-
const [form, setForm] = useState3(() =>
|
|
977
|
+
const [form, setForm] = useState3(() => agentToFormState2(agent));
|
|
817
978
|
useEffect2(() => {
|
|
818
|
-
setForm(
|
|
979
|
+
setForm(agentToFormState2(agent));
|
|
819
980
|
}, [agent]);
|
|
820
981
|
function updateField(key, value) {
|
|
821
982
|
setForm((prev) => ({ ...prev, [key]: value }));
|
|
@@ -832,10 +993,10 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
|
|
|
832
993
|
};
|
|
833
994
|
if (form.photo.trim()) body.photo = form.photo.trim();
|
|
834
995
|
else body.photo = "";
|
|
835
|
-
const delayMs =
|
|
996
|
+
const delayMs = secondsToMs2(form.delayTyping);
|
|
836
997
|
if (delayMs !== void 0) body.delay_typing = delayMs;
|
|
837
998
|
else body.delay_typing = 0;
|
|
838
|
-
const waitingMs =
|
|
999
|
+
const waitingMs = secondsToMs2(form.waitingTime);
|
|
839
1000
|
if (waitingMs !== void 0) body.waiting_time = waitingMs;
|
|
840
1001
|
else body.waiting_time = 0;
|
|
841
1002
|
try {
|
|
@@ -883,7 +1044,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
|
|
|
883
1044
|
] }),
|
|
884
1045
|
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3", children: [
|
|
885
1046
|
/* @__PURE__ */ jsx3(
|
|
886
|
-
|
|
1047
|
+
Switch2,
|
|
887
1048
|
{
|
|
888
1049
|
id: "edit-active",
|
|
889
1050
|
checked: form.active,
|
|
@@ -960,7 +1121,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
|
|
|
960
1121
|
// src/components/agents/agent-tools-list.tsx
|
|
961
1122
|
import { useState as useState4 } from "react";
|
|
962
1123
|
import {
|
|
963
|
-
Switch as
|
|
1124
|
+
Switch as Switch3,
|
|
964
1125
|
Badge as Badge2,
|
|
965
1126
|
Button as Button4,
|
|
966
1127
|
Skeleton,
|
|
@@ -1156,7 +1317,7 @@ function AgentToolsList({ agent, config }) {
|
|
|
1156
1317
|
agentTool.custom_instructions && /* @__PURE__ */ jsx4("p", { className: "truncate text-xs text-muted-foreground", children: agentTool.custom_instructions })
|
|
1157
1318
|
] }),
|
|
1158
1319
|
/* @__PURE__ */ jsx4(
|
|
1159
|
-
|
|
1320
|
+
Switch3,
|
|
1160
1321
|
{
|
|
1161
1322
|
"aria-label": "Ativar/Desativar",
|
|
1162
1323
|
checked: agentTool.enabled,
|
|
@@ -1287,7 +1448,7 @@ import { useState as useState6 } from "react";
|
|
|
1287
1448
|
import {
|
|
1288
1449
|
Input as Input5,
|
|
1289
1450
|
Button as Button5,
|
|
1290
|
-
Switch as
|
|
1451
|
+
Switch as Switch4,
|
|
1291
1452
|
Skeleton as Skeleton2,
|
|
1292
1453
|
Textarea as Textarea2,
|
|
1293
1454
|
Label as Label4,
|
|
@@ -1931,7 +2092,7 @@ function AgentObjectivesList({ agent, config }) {
|
|
|
1931
2092
|
objective.prompt && /* @__PURE__ */ jsx6("p", { className: "line-clamp-2 text-xs text-muted-foreground", children: objective.prompt })
|
|
1932
2093
|
] }),
|
|
1933
2094
|
/* @__PURE__ */ jsx6(
|
|
1934
|
-
|
|
2095
|
+
Switch4,
|
|
1935
2096
|
{
|
|
1936
2097
|
"aria-label": "Ativar/Desativar",
|
|
1937
2098
|
checked: objective.active,
|
|
@@ -2640,229 +2801,1918 @@ function AgentConversationsPanel({
|
|
|
2640
2801
|
) });
|
|
2641
2802
|
}
|
|
2642
2803
|
|
|
2643
|
-
// src/
|
|
2804
|
+
// src/pages/agent-capabilities-page.tsx
|
|
2805
|
+
import { useState as useState15, useCallback as useCallback6 } from "react";
|
|
2644
2806
|
import {
|
|
2645
2807
|
Tabs,
|
|
2646
2808
|
TabsList,
|
|
2647
2809
|
TabsTrigger,
|
|
2648
2810
|
TabsContent
|
|
2649
2811
|
} from "@greatapps/greatauth-ui/ui";
|
|
2650
|
-
import {
|
|
2651
|
-
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2652
|
-
function AgentTabs({ agent, config, renderChatLink }) {
|
|
2653
|
-
return /* @__PURE__ */ jsxs9(Tabs, { defaultValue: "prompt", children: [
|
|
2654
|
-
/* @__PURE__ */ jsxs9(TabsList, { children: [
|
|
2655
|
-
/* @__PURE__ */ jsxs9(TabsTrigger, { value: "prompt", className: "flex items-center gap-1.5", children: [
|
|
2656
|
-
/* @__PURE__ */ jsx11(FileText2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
2657
|
-
"Prompt"
|
|
2658
|
-
] }),
|
|
2659
|
-
/* @__PURE__ */ jsxs9(TabsTrigger, { value: "objetivos", className: "flex items-center gap-1.5", children: [
|
|
2660
|
-
/* @__PURE__ */ jsx11(Target2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
2661
|
-
"Objetivos"
|
|
2662
|
-
] }),
|
|
2663
|
-
/* @__PURE__ */ jsxs9(TabsTrigger, { value: "ferramentas", className: "flex items-center gap-1.5", children: [
|
|
2664
|
-
/* @__PURE__ */ jsx11(Wrench2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
2665
|
-
"Ferramentas"
|
|
2666
|
-
] }),
|
|
2667
|
-
/* @__PURE__ */ jsxs9(TabsTrigger, { value: "conversas", className: "flex items-center gap-1.5", children: [
|
|
2668
|
-
/* @__PURE__ */ jsx11(MessageCircle2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
2669
|
-
"Conversas"
|
|
2670
|
-
] })
|
|
2671
|
-
] }),
|
|
2672
|
-
/* @__PURE__ */ jsx11(TabsContent, { value: "prompt", className: "mt-4", children: /* @__PURE__ */ jsx11(AgentPromptEditor, { agent, config }) }),
|
|
2673
|
-
/* @__PURE__ */ jsx11(TabsContent, { value: "objetivos", className: "mt-4", children: /* @__PURE__ */ jsx11(AgentObjectivesList, { agent, config }) }),
|
|
2674
|
-
/* @__PURE__ */ jsx11(TabsContent, { value: "ferramentas", className: "mt-4", children: /* @__PURE__ */ jsx11(AgentToolsList, { agent, config }) }),
|
|
2675
|
-
/* @__PURE__ */ jsx11(TabsContent, { value: "conversas", className: "mt-4", children: /* @__PURE__ */ jsx11(
|
|
2676
|
-
AgentConversationsPanel,
|
|
2677
|
-
{
|
|
2678
|
-
agent,
|
|
2679
|
-
config,
|
|
2680
|
-
renderChatLink
|
|
2681
|
-
}
|
|
2682
|
-
) })
|
|
2683
|
-
] });
|
|
2684
|
-
}
|
|
2812
|
+
import { Blocks, Plug as Plug3, Settings as Settings4 } from "lucide-react";
|
|
2685
2813
|
|
|
2686
|
-
// src/components/
|
|
2687
|
-
import {
|
|
2688
|
-
import { DataTable as DataTable2 } from "@greatapps/greatauth-ui";
|
|
2814
|
+
// src/components/capabilities/capabilities-tab.tsx
|
|
2815
|
+
import { useState as useState9, useCallback as useCallback4, useRef as useRef2, useEffect as useEffect4, useMemo as useMemo5 } from "react";
|
|
2689
2816
|
import {
|
|
2690
|
-
|
|
2817
|
+
Accordion,
|
|
2818
|
+
AccordionItem,
|
|
2819
|
+
AccordionTrigger,
|
|
2820
|
+
AccordionContent,
|
|
2821
|
+
Switch as Switch5,
|
|
2822
|
+
Checkbox,
|
|
2691
2823
|
Badge as Badge6,
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
TooltipContent as TooltipContent2,
|
|
2695
|
-
AlertDialog as AlertDialog4,
|
|
2696
|
-
AlertDialogAction as AlertDialogAction4,
|
|
2697
|
-
AlertDialogCancel as AlertDialogCancel4,
|
|
2698
|
-
AlertDialogContent as AlertDialogContent4,
|
|
2699
|
-
AlertDialogDescription as AlertDialogDescription4,
|
|
2700
|
-
AlertDialogFooter as AlertDialogFooter4,
|
|
2701
|
-
AlertDialogHeader as AlertDialogHeader4,
|
|
2702
|
-
AlertDialogTitle as AlertDialogTitle4,
|
|
2703
|
-
Button as Button8
|
|
2824
|
+
Button as Button8,
|
|
2825
|
+
Skeleton as Skeleton6
|
|
2704
2826
|
} from "@greatapps/greatauth-ui/ui";
|
|
2705
|
-
import {
|
|
2706
|
-
|
|
2707
|
-
|
|
2827
|
+
import {
|
|
2828
|
+
Calendar,
|
|
2829
|
+
Users,
|
|
2830
|
+
Settings,
|
|
2831
|
+
HeartHandshake,
|
|
2832
|
+
Package,
|
|
2833
|
+
ChevronDown as ChevronDown2
|
|
2834
|
+
} from "lucide-react";
|
|
2708
2835
|
import { toast as toast7 } from "sonner";
|
|
2709
|
-
import {
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2836
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2837
|
+
var OPERATION_LABELS = {
|
|
2838
|
+
list: "Listar",
|
|
2839
|
+
view: "Visualizar",
|
|
2840
|
+
create: "Criar",
|
|
2841
|
+
update: "Atualizar"
|
|
2842
|
+
};
|
|
2843
|
+
function getOperationLabel(slug) {
|
|
2844
|
+
return OPERATION_LABELS[slug] ?? slug;
|
|
2845
|
+
}
|
|
2846
|
+
var CATEGORY_ICONS = {
|
|
2847
|
+
agenda: Calendar,
|
|
2848
|
+
cadastros: Users,
|
|
2849
|
+
infraestrutura: Settings,
|
|
2850
|
+
relacionamentos: HeartHandshake
|
|
2851
|
+
};
|
|
2852
|
+
function getCategoryIcon(slug) {
|
|
2853
|
+
return CATEGORY_ICONS[slug] ?? Package;
|
|
2854
|
+
}
|
|
2855
|
+
function buildStateFromAgent(agentCaps) {
|
|
2856
|
+
const state = /* @__PURE__ */ new Map();
|
|
2857
|
+
for (const cap of agentCaps) {
|
|
2858
|
+
state.set(cap.module, new Set(cap.operations));
|
|
2859
|
+
}
|
|
2860
|
+
return state;
|
|
2861
|
+
}
|
|
2862
|
+
function stateToPayload(state) {
|
|
2863
|
+
const capabilities = [];
|
|
2864
|
+
state.forEach((ops, mod) => {
|
|
2865
|
+
if (ops.size > 0) {
|
|
2866
|
+
capabilities.push({ module: mod, operations: Array.from(ops) });
|
|
2867
|
+
}
|
|
2868
|
+
});
|
|
2869
|
+
return { capabilities };
|
|
2870
|
+
}
|
|
2871
|
+
function cloneState(state) {
|
|
2872
|
+
const next = /* @__PURE__ */ new Map();
|
|
2873
|
+
state.forEach((ops, mod) => next.set(mod, new Set(ops)));
|
|
2874
|
+
return next;
|
|
2875
|
+
}
|
|
2876
|
+
function statesEqual(a, b) {
|
|
2877
|
+
if (a.size !== b.size) return false;
|
|
2878
|
+
for (const [mod, opsA] of a) {
|
|
2879
|
+
const opsB = b.get(mod);
|
|
2880
|
+
if (!opsB || opsA.size !== opsB.size) return false;
|
|
2881
|
+
for (const op of opsA) {
|
|
2882
|
+
if (!opsB.has(op)) return false;
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
return true;
|
|
2886
|
+
}
|
|
2887
|
+
function CapabilitiesTab({ config, agentId }) {
|
|
2888
|
+
const { data: registry, isLoading: isLoadingRegistry } = useCapabilities(config);
|
|
2889
|
+
const { data: agentCaps, isLoading: isLoadingAgent } = useAgentCapabilities(config, agentId);
|
|
2890
|
+
const updateMutation = useUpdateAgentCapabilities(config);
|
|
2891
|
+
const [localState, setLocalState] = useState9(/* @__PURE__ */ new Map());
|
|
2892
|
+
const [serverState, setServerState] = useState9(/* @__PURE__ */ new Map());
|
|
2893
|
+
const [initialized, setInitialized] = useState9(false);
|
|
2894
|
+
const debounceRef = useRef2(null);
|
|
2895
|
+
useEffect4(() => {
|
|
2896
|
+
if (agentCaps && !initialized) {
|
|
2897
|
+
const state = buildStateFromAgent(agentCaps);
|
|
2898
|
+
setLocalState(state);
|
|
2899
|
+
setServerState(cloneState(state));
|
|
2900
|
+
setInitialized(true);
|
|
2901
|
+
}
|
|
2902
|
+
}, [agentCaps, initialized]);
|
|
2903
|
+
useEffect4(() => {
|
|
2904
|
+
setInitialized(false);
|
|
2905
|
+
}, [agentId]);
|
|
2906
|
+
const hasChanges = useMemo5(
|
|
2907
|
+
() => initialized && !statesEqual(localState, serverState),
|
|
2908
|
+
[localState, serverState, initialized]
|
|
2909
|
+
);
|
|
2910
|
+
const scheduleSave = useCallback4(
|
|
2911
|
+
(nextState) => {
|
|
2912
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
2913
|
+
debounceRef.current = setTimeout(() => {
|
|
2914
|
+
const payload = stateToPayload(nextState);
|
|
2915
|
+
updateMutation.mutate(
|
|
2916
|
+
{ agentId, payload },
|
|
2917
|
+
{
|
|
2918
|
+
onSuccess: () => {
|
|
2919
|
+
setServerState(cloneState(nextState));
|
|
2920
|
+
toast7.success("Capacidades salvas");
|
|
2921
|
+
},
|
|
2922
|
+
onError: () => {
|
|
2923
|
+
setLocalState(cloneState(serverState));
|
|
2924
|
+
toast7.error("Erro ao salvar capacidades");
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
);
|
|
2928
|
+
}, 500);
|
|
2722
2929
|
},
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2930
|
+
[agentId, updateMutation, serverState]
|
|
2931
|
+
);
|
|
2932
|
+
const updateState = useCallback4(
|
|
2933
|
+
(updater) => {
|
|
2934
|
+
setLocalState((prev) => {
|
|
2935
|
+
const next = updater(prev);
|
|
2936
|
+
scheduleSave(next);
|
|
2937
|
+
return next;
|
|
2938
|
+
});
|
|
2727
2939
|
},
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2940
|
+
[scheduleSave]
|
|
2941
|
+
);
|
|
2942
|
+
const toggleModule = useCallback4(
|
|
2943
|
+
(mod, enabled) => {
|
|
2944
|
+
updateState((prev) => {
|
|
2945
|
+
const next = cloneState(prev);
|
|
2946
|
+
if (enabled) {
|
|
2947
|
+
next.set(mod.slug, new Set(mod.operations));
|
|
2948
|
+
} else {
|
|
2949
|
+
next.delete(mod.slug);
|
|
2950
|
+
}
|
|
2951
|
+
return next;
|
|
2952
|
+
});
|
|
2736
2953
|
},
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2954
|
+
[updateState]
|
|
2955
|
+
);
|
|
2956
|
+
const toggleOperation = useCallback4(
|
|
2957
|
+
(mod, opSlug, enabled) => {
|
|
2958
|
+
updateState((prev) => {
|
|
2959
|
+
const next = cloneState(prev);
|
|
2960
|
+
const ops = new Set(next.get(mod.slug) ?? []);
|
|
2961
|
+
if (enabled) {
|
|
2962
|
+
ops.add(opSlug);
|
|
2963
|
+
} else {
|
|
2964
|
+
ops.delete(opSlug);
|
|
2965
|
+
}
|
|
2966
|
+
if (ops.size > 0) {
|
|
2967
|
+
next.set(mod.slug, ops);
|
|
2968
|
+
} else {
|
|
2969
|
+
next.delete(mod.slug);
|
|
2970
|
+
}
|
|
2971
|
+
return next;
|
|
2972
|
+
});
|
|
2743
2973
|
},
|
|
2744
|
-
|
|
2745
|
-
id: "actions",
|
|
2746
|
-
size: 80,
|
|
2747
|
-
enableSorting: false,
|
|
2748
|
-
cell: ({ row }) => /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
|
|
2749
|
-
/* @__PURE__ */ jsxs10(Tooltip2, { children: [
|
|
2750
|
-
/* @__PURE__ */ jsx12(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsx12(
|
|
2751
|
-
Button8,
|
|
2752
|
-
{
|
|
2753
|
-
variant: "ghost",
|
|
2754
|
-
size: "icon",
|
|
2755
|
-
className: "h-8 w-8",
|
|
2756
|
-
"aria-label": "Editar",
|
|
2757
|
-
onClick: () => onEdit(row.original),
|
|
2758
|
-
children: /* @__PURE__ */ jsx12(Pencil3, { className: "h-4 w-4" })
|
|
2759
|
-
}
|
|
2760
|
-
) }),
|
|
2761
|
-
/* @__PURE__ */ jsx12(TooltipContent2, { children: "Editar" })
|
|
2762
|
-
] }),
|
|
2763
|
-
/* @__PURE__ */ jsxs10(Tooltip2, { children: [
|
|
2764
|
-
/* @__PURE__ */ jsx12(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsx12(
|
|
2765
|
-
Button8,
|
|
2766
|
-
{
|
|
2767
|
-
variant: "ghost",
|
|
2768
|
-
size: "icon",
|
|
2769
|
-
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
2770
|
-
"aria-label": "Excluir",
|
|
2771
|
-
onClick: () => onDelete(row.original.id),
|
|
2772
|
-
children: /* @__PURE__ */ jsx12(Trash24, { className: "h-4 w-4" })
|
|
2773
|
-
}
|
|
2774
|
-
) }),
|
|
2775
|
-
/* @__PURE__ */ jsx12(TooltipContent2, { children: "Excluir" })
|
|
2776
|
-
] })
|
|
2777
|
-
] })
|
|
2778
|
-
}
|
|
2779
|
-
];
|
|
2780
|
-
}
|
|
2781
|
-
function ToolsTable({ onEdit, config }) {
|
|
2782
|
-
const [search, setSearch] = useState9("");
|
|
2783
|
-
const [page, setPage] = useState9(1);
|
|
2784
|
-
const queryParams = useMemo4(() => {
|
|
2785
|
-
const params = {
|
|
2786
|
-
limit: "15",
|
|
2787
|
-
page: String(page)
|
|
2788
|
-
};
|
|
2789
|
-
if (search) {
|
|
2790
|
-
params.search = search;
|
|
2791
|
-
}
|
|
2792
|
-
return params;
|
|
2793
|
-
}, [search, page]);
|
|
2794
|
-
const { data, isLoading } = useTools(config, queryParams);
|
|
2795
|
-
const deleteTool = useDeleteTool(config);
|
|
2796
|
-
const [deleteId, setDeleteId] = useState9(null);
|
|
2797
|
-
const tools = data?.data || [];
|
|
2798
|
-
const total = data?.total || 0;
|
|
2799
|
-
const columns = useColumns2(
|
|
2800
|
-
(tool) => onEdit(tool),
|
|
2801
|
-
(id) => setDeleteId(id)
|
|
2974
|
+
[updateState]
|
|
2802
2975
|
);
|
|
2803
|
-
|
|
2804
|
-
if (!
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2976
|
+
const enableAll = useCallback4(() => {
|
|
2977
|
+
if (!registry) return;
|
|
2978
|
+
updateState(() => {
|
|
2979
|
+
const next = /* @__PURE__ */ new Map();
|
|
2980
|
+
for (const cat of registry.categories) {
|
|
2981
|
+
for (const mod of cat.modules) {
|
|
2982
|
+
next.set(mod.slug, new Set(mod.operations));
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
return next;
|
|
2811
2986
|
});
|
|
2987
|
+
}, [registry, updateState]);
|
|
2988
|
+
const disableAll = useCallback4(() => {
|
|
2989
|
+
updateState(() => /* @__PURE__ */ new Map());
|
|
2990
|
+
}, [updateState]);
|
|
2991
|
+
const discard = useCallback4(() => {
|
|
2992
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
2993
|
+
setLocalState(cloneState(serverState));
|
|
2994
|
+
}, [serverState]);
|
|
2995
|
+
const saveNow = useCallback4(() => {
|
|
2996
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
2997
|
+
const payload = stateToPayload(localState);
|
|
2998
|
+
updateMutation.mutate(
|
|
2999
|
+
{ agentId, payload },
|
|
3000
|
+
{
|
|
3001
|
+
onSuccess: () => {
|
|
3002
|
+
setServerState(cloneState(localState));
|
|
3003
|
+
toast7.success("Capacidades salvas");
|
|
3004
|
+
},
|
|
3005
|
+
onError: () => {
|
|
3006
|
+
setLocalState(cloneState(serverState));
|
|
3007
|
+
toast7.error("Erro ao salvar capacidades");
|
|
3008
|
+
}
|
|
3009
|
+
}
|
|
3010
|
+
);
|
|
3011
|
+
}, [agentId, localState, serverState, updateMutation]);
|
|
3012
|
+
function countActiveModules(cat) {
|
|
3013
|
+
return cat.modules.filter((m) => (localState.get(m.slug)?.size ?? 0) > 0).length;
|
|
2812
3014
|
}
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
setPage(1);
|
|
3015
|
+
if (isLoadingRegistry || isLoadingAgent) {
|
|
3016
|
+
return /* @__PURE__ */ jsx11("div", { className: "space-y-3", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx11(Skeleton6, { className: "h-14 w-full" }, i)) });
|
|
2816
3017
|
}
|
|
2817
|
-
|
|
2818
|
-
/* @__PURE__ */
|
|
2819
|
-
/* @__PURE__ */
|
|
2820
|
-
/* @__PURE__ */
|
|
2821
|
-
|
|
3018
|
+
if (!registry || !registry.categories.length) {
|
|
3019
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
|
|
3020
|
+
/* @__PURE__ */ jsx11(Package, { className: "h-12 w-12 text-muted-foreground mb-3" }),
|
|
3021
|
+
/* @__PURE__ */ jsx11("h3", { className: "text-base font-medium", children: "Nenhuma capacidade dispon\xEDvel" }),
|
|
3022
|
+
/* @__PURE__ */ jsx11("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." })
|
|
3023
|
+
] });
|
|
3024
|
+
}
|
|
3025
|
+
return /* @__PURE__ */ jsxs9("div", { className: "space-y-4", children: [
|
|
3026
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between", children: [
|
|
3027
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
3028
|
+
/* @__PURE__ */ jsx11("h3", { className: "text-sm font-medium", children: "Capacidades do agente" }),
|
|
3029
|
+
/* @__PURE__ */ jsx11("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." })
|
|
3030
|
+
] }),
|
|
3031
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
3032
|
+
/* @__PURE__ */ jsx11(Button8, { variant: "outline", size: "sm", onClick: enableAll, children: "Ativar tudo" }),
|
|
3033
|
+
/* @__PURE__ */ jsx11(Button8, { variant: "outline", size: "sm", onClick: disableAll, children: "Desativar tudo" })
|
|
3034
|
+
] })
|
|
3035
|
+
] }),
|
|
3036
|
+
/* @__PURE__ */ jsx11(Accordion, { type: "multiple", className: "space-y-2", children: registry.categories.map((cat) => {
|
|
3037
|
+
const Icon = getCategoryIcon(cat.slug);
|
|
3038
|
+
const activeCount = countActiveModules(cat);
|
|
3039
|
+
const totalModules = cat.modules.length;
|
|
3040
|
+
return /* @__PURE__ */ jsxs9(
|
|
3041
|
+
AccordionItem,
|
|
2822
3042
|
{
|
|
2823
|
-
|
|
3043
|
+
value: cat.slug,
|
|
3044
|
+
className: "border rounded-lg px-4",
|
|
3045
|
+
children: [
|
|
3046
|
+
/* @__PURE__ */ jsx11(AccordionTrigger, { className: "hover:no-underline py-3", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3 flex-1", children: [
|
|
3047
|
+
/* @__PURE__ */ jsx11(Icon, { className: "h-4 w-4 text-muted-foreground" }),
|
|
3048
|
+
/* @__PURE__ */ jsx11("span", { className: "font-medium text-sm", children: cat.label }),
|
|
3049
|
+
/* @__PURE__ */ jsxs9(Badge6, { variant: "secondary", className: "text-xs", children: [
|
|
3050
|
+
activeCount,
|
|
3051
|
+
" de ",
|
|
3052
|
+
totalModules,
|
|
3053
|
+
" m\xF3dulos ativos"
|
|
3054
|
+
] })
|
|
3055
|
+
] }) }),
|
|
3056
|
+
/* @__PURE__ */ jsx11(AccordionContent, { className: "pb-3", children: /* @__PURE__ */ jsx11("div", { className: "space-y-1", children: cat.modules.map((mod) => {
|
|
3057
|
+
const enabledOps = localState.get(mod.slug);
|
|
3058
|
+
const isModuleOn = (enabledOps?.size ?? 0) > 0;
|
|
3059
|
+
const allOpsEnabled = enabledOps?.size === mod.operations.length;
|
|
3060
|
+
return /* @__PURE__ */ jsx11(
|
|
3061
|
+
ModuleRow,
|
|
3062
|
+
{
|
|
3063
|
+
module: mod,
|
|
3064
|
+
isOn: isModuleOn,
|
|
3065
|
+
allOpsEnabled,
|
|
3066
|
+
enabledOps: enabledOps ?? /* @__PURE__ */ new Set(),
|
|
3067
|
+
onToggleModule: (on) => toggleModule(mod, on),
|
|
3068
|
+
onToggleOperation: (op, on) => toggleOperation(mod, op, on)
|
|
3069
|
+
},
|
|
3070
|
+
mod.slug
|
|
3071
|
+
);
|
|
3072
|
+
}) }) })
|
|
3073
|
+
]
|
|
3074
|
+
},
|
|
3075
|
+
cat.slug
|
|
3076
|
+
);
|
|
3077
|
+
}) }),
|
|
3078
|
+
hasChanges && /* @__PURE__ */ jsxs9("div", { className: "sticky bottom-0 bg-background border-t py-3 px-4 -mx-4 flex items-center justify-between", children: [
|
|
3079
|
+
/* @__PURE__ */ jsx11("span", { className: "text-sm text-muted-foreground", children: "Voc\xEA tem altera\xE7\xF5es n\xE3o salvas." }),
|
|
3080
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
3081
|
+
/* @__PURE__ */ jsx11(Button8, { variant: "outline", size: "sm", onClick: discard, children: "Descartar" }),
|
|
3082
|
+
/* @__PURE__ */ jsx11(
|
|
3083
|
+
Button8,
|
|
3084
|
+
{
|
|
3085
|
+
size: "sm",
|
|
3086
|
+
onClick: saveNow,
|
|
3087
|
+
disabled: updateMutation.isPending,
|
|
3088
|
+
children: updateMutation.isPending ? "Salvando..." : "Salvar"
|
|
3089
|
+
}
|
|
3090
|
+
)
|
|
3091
|
+
] })
|
|
3092
|
+
] })
|
|
3093
|
+
] });
|
|
3094
|
+
}
|
|
3095
|
+
function ModuleRow({
|
|
3096
|
+
module: mod,
|
|
3097
|
+
isOn,
|
|
3098
|
+
enabledOps,
|
|
3099
|
+
onToggleModule,
|
|
3100
|
+
onToggleOperation
|
|
3101
|
+
}) {
|
|
3102
|
+
const [expanded, setExpanded] = useState9(false);
|
|
3103
|
+
return /* @__PURE__ */ jsxs9("div", { className: "rounded-md border px-3 py-2", children: [
|
|
3104
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between", children: [
|
|
3105
|
+
/* @__PURE__ */ jsxs9(
|
|
3106
|
+
"button",
|
|
3107
|
+
{
|
|
3108
|
+
type: "button",
|
|
3109
|
+
className: "flex items-center gap-2 flex-1 text-left",
|
|
3110
|
+
onClick: () => setExpanded(!expanded),
|
|
3111
|
+
"aria-expanded": expanded,
|
|
3112
|
+
"aria-label": `Expandir ${mod.label}`,
|
|
3113
|
+
children: [
|
|
3114
|
+
/* @__PURE__ */ jsx11(
|
|
3115
|
+
ChevronDown2,
|
|
3116
|
+
{
|
|
3117
|
+
className: `h-3.5 w-3.5 text-muted-foreground transition-transform ${expanded ? "rotate-0" : "-rotate-90"}`
|
|
3118
|
+
}
|
|
3119
|
+
),
|
|
3120
|
+
/* @__PURE__ */ jsx11("span", { className: "text-sm font-medium", children: mod.label }),
|
|
3121
|
+
mod.description && /* @__PURE__ */ jsxs9("span", { className: "text-xs text-muted-foreground hidden sm:inline", children: [
|
|
3122
|
+
"\u2014 ",
|
|
3123
|
+
mod.description
|
|
3124
|
+
] }),
|
|
3125
|
+
isOn && /* @__PURE__ */ jsxs9(Badge6, { variant: "secondary", className: "text-xs ml-1", children: [
|
|
3126
|
+
enabledOps.size,
|
|
3127
|
+
"/",
|
|
3128
|
+
mod.operations.length
|
|
3129
|
+
] })
|
|
3130
|
+
]
|
|
3131
|
+
}
|
|
3132
|
+
),
|
|
3133
|
+
/* @__PURE__ */ jsx11(
|
|
3134
|
+
Switch5,
|
|
3135
|
+
{
|
|
3136
|
+
checked: isOn,
|
|
3137
|
+
onCheckedChange: onToggleModule,
|
|
3138
|
+
"aria-label": `Ativar m\xF3dulo ${mod.label}`
|
|
3139
|
+
}
|
|
3140
|
+
)
|
|
3141
|
+
] }),
|
|
3142
|
+
expanded && /* @__PURE__ */ jsx11("div", { className: "mt-2 ml-6 flex flex-wrap gap-x-5 gap-y-1.5 pb-1", children: mod.operations.map((op) => {
|
|
3143
|
+
const checked = enabledOps.has(op);
|
|
3144
|
+
return /* @__PURE__ */ jsxs9(
|
|
3145
|
+
"label",
|
|
3146
|
+
{
|
|
3147
|
+
className: "flex items-center gap-1.5 text-sm cursor-pointer",
|
|
3148
|
+
children: [
|
|
3149
|
+
/* @__PURE__ */ jsx11(
|
|
3150
|
+
Checkbox,
|
|
3151
|
+
{
|
|
3152
|
+
checked,
|
|
3153
|
+
onCheckedChange: (val) => onToggleOperation(op, val === true),
|
|
3154
|
+
"aria-label": `${getOperationLabel(op)} em ${mod.label}`
|
|
3155
|
+
}
|
|
3156
|
+
),
|
|
3157
|
+
/* @__PURE__ */ jsx11("span", { className: checked ? "" : "text-muted-foreground", children: getOperationLabel(op) })
|
|
3158
|
+
]
|
|
3159
|
+
},
|
|
3160
|
+
op
|
|
3161
|
+
);
|
|
3162
|
+
}) })
|
|
3163
|
+
] });
|
|
3164
|
+
}
|
|
3165
|
+
|
|
3166
|
+
// src/components/capabilities/integration-card.tsx
|
|
3167
|
+
import { Badge as Badge7, Button as Button9, Tooltip as Tooltip2, TooltipContent as TooltipContent2, TooltipTrigger as TooltipTrigger2 } from "@greatapps/greatauth-ui/ui";
|
|
3168
|
+
import {
|
|
3169
|
+
CalendarSync,
|
|
3170
|
+
Plug,
|
|
3171
|
+
Settings as Settings3,
|
|
3172
|
+
RefreshCw,
|
|
3173
|
+
Users as Users2,
|
|
3174
|
+
Clock
|
|
3175
|
+
} from "lucide-react";
|
|
3176
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3177
|
+
var ICON_MAP = {
|
|
3178
|
+
CalendarSync,
|
|
3179
|
+
Plug,
|
|
3180
|
+
Settings: Settings3,
|
|
3181
|
+
RefreshCw,
|
|
3182
|
+
Users: Users2,
|
|
3183
|
+
Clock
|
|
3184
|
+
};
|
|
3185
|
+
function resolveIcon(name) {
|
|
3186
|
+
return ICON_MAP[name] ?? Plug;
|
|
3187
|
+
}
|
|
3188
|
+
var STATE_BADGES = {
|
|
3189
|
+
available: {
|
|
3190
|
+
label: "Dispon\xEDvel",
|
|
3191
|
+
className: "bg-muted text-muted-foreground"
|
|
3192
|
+
},
|
|
3193
|
+
connected: {
|
|
3194
|
+
label: "Conectado",
|
|
3195
|
+
className: "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
|
|
3196
|
+
},
|
|
3197
|
+
expired: {
|
|
3198
|
+
label: "Expirado",
|
|
3199
|
+
className: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
|
|
3200
|
+
},
|
|
3201
|
+
coming_soon: {
|
|
3202
|
+
label: "Em breve",
|
|
3203
|
+
className: "bg-muted text-muted-foreground"
|
|
3204
|
+
}
|
|
3205
|
+
};
|
|
3206
|
+
function getActionLabel(state) {
|
|
3207
|
+
switch (state) {
|
|
3208
|
+
case "available":
|
|
3209
|
+
return "Conectar";
|
|
3210
|
+
case "connected":
|
|
3211
|
+
return "Configurar";
|
|
3212
|
+
case "expired":
|
|
3213
|
+
return "Reconectar";
|
|
3214
|
+
default:
|
|
3215
|
+
return "";
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
function IntegrationCard({ card, onConnect }) {
|
|
3219
|
+
const { definition, state, sharedByAgentsCount } = card;
|
|
3220
|
+
const Icon = resolveIcon(definition.icon);
|
|
3221
|
+
const badge = STATE_BADGES[state];
|
|
3222
|
+
const actionLabel = getActionLabel(state);
|
|
3223
|
+
const isComingSoon = state === "coming_soon";
|
|
3224
|
+
return /* @__PURE__ */ jsxs10(
|
|
3225
|
+
"div",
|
|
3226
|
+
{
|
|
3227
|
+
className: cn(
|
|
3228
|
+
"group relative flex flex-col gap-3 rounded-xl border bg-card p-5 transition-shadow",
|
|
3229
|
+
isComingSoon ? "opacity-60 cursor-default" : "hover:shadow-md cursor-pointer"
|
|
3230
|
+
),
|
|
3231
|
+
role: "button",
|
|
3232
|
+
tabIndex: isComingSoon ? -1 : 0,
|
|
3233
|
+
"aria-label": `${definition.name} \u2014 ${badge.label}`,
|
|
3234
|
+
"aria-disabled": isComingSoon,
|
|
3235
|
+
onClick: () => !isComingSoon && onConnect(card),
|
|
3236
|
+
onKeyDown: (e) => {
|
|
3237
|
+
if (!isComingSoon && (e.key === "Enter" || e.key === " ")) {
|
|
3238
|
+
e.preventDefault();
|
|
3239
|
+
onConnect(card);
|
|
3240
|
+
}
|
|
3241
|
+
},
|
|
3242
|
+
children: [
|
|
3243
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-start justify-between gap-2", children: [
|
|
3244
|
+
/* @__PURE__ */ jsx12("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx12(Icon, { className: "h-5 w-5" }) }),
|
|
3245
|
+
/* @__PURE__ */ jsx12(Badge7, { variant: "outline", className: cn("text-xs", badge.className), children: badge.label })
|
|
3246
|
+
] }),
|
|
3247
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-1", children: [
|
|
3248
|
+
/* @__PURE__ */ jsx12("h3", { className: "text-sm font-semibold leading-tight", children: definition.name }),
|
|
3249
|
+
/* @__PURE__ */ jsx12("p", { className: "text-xs text-muted-foreground leading-relaxed", children: definition.description })
|
|
3250
|
+
] }),
|
|
3251
|
+
/* @__PURE__ */ jsxs10("div", { className: "mt-auto flex items-center justify-between gap-2 pt-1", children: [
|
|
3252
|
+
sharedByAgentsCount > 0 ? /* @__PURE__ */ jsxs10(Tooltip2, { children: [
|
|
3253
|
+
/* @__PURE__ */ jsx12(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs10("span", { className: "inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400", children: [
|
|
3254
|
+
/* @__PURE__ */ jsx12(Users2, { className: "h-3.5 w-3.5" }),
|
|
3255
|
+
"Compartilhada"
|
|
3256
|
+
] }) }),
|
|
3257
|
+
/* @__PURE__ */ jsx12(TooltipContent2, { children: "Esta credencial est\xE1 dispon\xEDvel para todos os agentes da conta" })
|
|
3258
|
+
] }) : /* @__PURE__ */ jsx12("span", {}),
|
|
3259
|
+
!isComingSoon && /* @__PURE__ */ jsx12(
|
|
3260
|
+
Button9,
|
|
3261
|
+
{
|
|
3262
|
+
variant: state === "expired" ? "destructive" : "outline",
|
|
3263
|
+
size: "sm",
|
|
3264
|
+
className: "text-xs",
|
|
3265
|
+
onClick: (e) => {
|
|
3266
|
+
e.stopPropagation();
|
|
3267
|
+
onConnect(card);
|
|
3268
|
+
},
|
|
3269
|
+
children: actionLabel
|
|
3270
|
+
}
|
|
3271
|
+
)
|
|
3272
|
+
] })
|
|
3273
|
+
]
|
|
3274
|
+
}
|
|
3275
|
+
);
|
|
3276
|
+
}
|
|
3277
|
+
|
|
3278
|
+
// src/components/capabilities/integrations-tab.tsx
|
|
3279
|
+
import { Plug as Plug2, Loader2 as Loader24 } from "lucide-react";
|
|
3280
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3281
|
+
function IntegrationsTab({
|
|
3282
|
+
config,
|
|
3283
|
+
agentId,
|
|
3284
|
+
onConnect
|
|
3285
|
+
}) {
|
|
3286
|
+
const { cards, isLoading } = useIntegrationState(config, agentId);
|
|
3287
|
+
if (isLoading) {
|
|
3288
|
+
return /* @__PURE__ */ jsx13("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx13(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
3289
|
+
}
|
|
3290
|
+
if (cards.length === 0) {
|
|
3291
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground", children: [
|
|
3292
|
+
/* @__PURE__ */ jsx13(Plug2, { className: "h-10 w-10" }),
|
|
3293
|
+
/* @__PURE__ */ jsx13("p", { className: "text-sm", children: "Nenhuma integra\xE7\xE3o dispon\xEDvel" })
|
|
3294
|
+
] });
|
|
3295
|
+
}
|
|
3296
|
+
return /* @__PURE__ */ jsx13("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: cards.map((card) => /* @__PURE__ */ jsx13(
|
|
3297
|
+
IntegrationCard,
|
|
3298
|
+
{
|
|
3299
|
+
card,
|
|
3300
|
+
onConnect
|
|
3301
|
+
},
|
|
3302
|
+
card.definition.slug
|
|
3303
|
+
)) });
|
|
3304
|
+
}
|
|
3305
|
+
|
|
3306
|
+
// src/components/capabilities/integration-wizard.tsx
|
|
3307
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef3, useState as useState10 } from "react";
|
|
3308
|
+
import {
|
|
3309
|
+
Dialog as Dialog5,
|
|
3310
|
+
DialogContent as DialogContent5,
|
|
3311
|
+
DialogFooter as DialogFooter5,
|
|
3312
|
+
DialogHeader as DialogHeader5,
|
|
3313
|
+
DialogTitle as DialogTitle5,
|
|
3314
|
+
Button as Button11
|
|
3315
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
3316
|
+
import { Loader2 as Loader27, ChevronLeft, ChevronRight, Check as Check2 } from "lucide-react";
|
|
3317
|
+
import { toast as toast8 } from "sonner";
|
|
3318
|
+
|
|
3319
|
+
// src/components/capabilities/wizard-steps/info-step.tsx
|
|
3320
|
+
import { Check, Info } from "lucide-react";
|
|
3321
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3322
|
+
function InfoStep({ integration, meta }) {
|
|
3323
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-6", children: [
|
|
3324
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-4", children: [
|
|
3325
|
+
meta.icon && /* @__PURE__ */ jsx14("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-muted", children: meta.icon }),
|
|
3326
|
+
/* @__PURE__ */ jsxs12("div", { className: "space-y-1", children: [
|
|
3327
|
+
/* @__PURE__ */ jsx14("h3", { className: "text-lg font-semibold", children: integration.name }),
|
|
3328
|
+
/* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground", children: integration.description })
|
|
3329
|
+
] })
|
|
3330
|
+
] }),
|
|
3331
|
+
meta.capabilities.length > 0 && /* @__PURE__ */ jsxs12("div", { className: "space-y-3", children: [
|
|
3332
|
+
/* @__PURE__ */ jsx14("h4", { className: "text-sm font-medium", children: "O que esta integra\xE7\xE3o permite:" }),
|
|
3333
|
+
/* @__PURE__ */ jsx14("ul", { className: "space-y-2", children: meta.capabilities.map((cap, i) => /* @__PURE__ */ jsxs12("li", { className: "flex items-start gap-2 text-sm", children: [
|
|
3334
|
+
/* @__PURE__ */ jsx14(
|
|
3335
|
+
Check,
|
|
3336
|
+
{
|
|
3337
|
+
"aria-hidden": "true",
|
|
3338
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
|
|
3339
|
+
}
|
|
3340
|
+
),
|
|
3341
|
+
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3342
|
+
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: cap.label }),
|
|
3343
|
+
cap.description && /* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground", children: [
|
|
3344
|
+
" ",
|
|
3345
|
+
"\u2014 ",
|
|
3346
|
+
cap.description
|
|
3347
|
+
] })
|
|
3348
|
+
] })
|
|
3349
|
+
] }, i)) })
|
|
3350
|
+
] }),
|
|
3351
|
+
meta.requirements.length > 0 && /* @__PURE__ */ jsxs12("div", { className: "space-y-3", children: [
|
|
3352
|
+
/* @__PURE__ */ jsx14("h4", { className: "text-sm font-medium", children: "Requisitos:" }),
|
|
3353
|
+
/* @__PURE__ */ jsx14("ul", { className: "space-y-2", children: meta.requirements.map((req, i) => /* @__PURE__ */ jsxs12(
|
|
3354
|
+
"li",
|
|
3355
|
+
{
|
|
3356
|
+
className: "flex items-start gap-2 text-sm text-muted-foreground",
|
|
3357
|
+
children: [
|
|
3358
|
+
/* @__PURE__ */ jsx14(
|
|
3359
|
+
Info,
|
|
3360
|
+
{
|
|
3361
|
+
"aria-hidden": "true",
|
|
3362
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-blue-500"
|
|
3363
|
+
}
|
|
3364
|
+
),
|
|
3365
|
+
/* @__PURE__ */ jsx14("span", { children: req })
|
|
3366
|
+
]
|
|
3367
|
+
},
|
|
3368
|
+
i
|
|
3369
|
+
)) })
|
|
3370
|
+
] })
|
|
3371
|
+
] });
|
|
3372
|
+
}
|
|
3373
|
+
|
|
3374
|
+
// src/components/capabilities/wizard-steps/credentials-step.tsx
|
|
3375
|
+
import { CheckCircle2, Loader2 as Loader25, AlertCircle, Shield } from "lucide-react";
|
|
3376
|
+
import { Button as Button10, Input as Input7, Label as Label5 } from "@greatapps/greatauth-ui/ui";
|
|
3377
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3378
|
+
function CredentialsStep({
|
|
3379
|
+
integration,
|
|
3380
|
+
meta,
|
|
3381
|
+
oauthStatus,
|
|
3382
|
+
oauthResult,
|
|
3383
|
+
apiKey,
|
|
3384
|
+
onApiKeyChange,
|
|
3385
|
+
onStartOAuth,
|
|
3386
|
+
isReconnect = false
|
|
3387
|
+
}) {
|
|
3388
|
+
if (integration.authType === "oauth2") {
|
|
3389
|
+
return /* @__PURE__ */ jsx15(
|
|
3390
|
+
OAuthCredentials,
|
|
3391
|
+
{
|
|
3392
|
+
integration,
|
|
3393
|
+
meta,
|
|
3394
|
+
oauthStatus,
|
|
3395
|
+
oauthResult,
|
|
3396
|
+
onStartOAuth,
|
|
3397
|
+
isReconnect
|
|
3398
|
+
}
|
|
3399
|
+
);
|
|
3400
|
+
}
|
|
3401
|
+
return /* @__PURE__ */ jsx15(ApiKeyCredentials, { apiKey, onApiKeyChange });
|
|
3402
|
+
}
|
|
3403
|
+
function OAuthCredentials({
|
|
3404
|
+
integration,
|
|
3405
|
+
meta,
|
|
3406
|
+
oauthStatus,
|
|
3407
|
+
oauthResult,
|
|
3408
|
+
onStartOAuth,
|
|
3409
|
+
isReconnect
|
|
3410
|
+
}) {
|
|
3411
|
+
const providerLabel = meta.providerLabel || integration.name;
|
|
3412
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-6", children: [
|
|
3413
|
+
/* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
|
|
3414
|
+
/* @__PURE__ */ jsx15("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
|
|
3415
|
+
/* @__PURE__ */ jsx15("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.` })
|
|
3416
|
+
] }),
|
|
3417
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-center gap-4 rounded-lg border p-6", children: [
|
|
3418
|
+
oauthStatus === "idle" && /* @__PURE__ */ jsxs13(Button10, { onClick: onStartOAuth, size: "lg", className: "gap-2", children: [
|
|
3419
|
+
meta.icon,
|
|
3420
|
+
isReconnect ? `Reconectar com ${providerLabel}` : `Conectar com ${providerLabel}`
|
|
3421
|
+
] }),
|
|
3422
|
+
oauthStatus === "waiting" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
3423
|
+
/* @__PURE__ */ jsx15(
|
|
3424
|
+
Loader25,
|
|
3425
|
+
{
|
|
3426
|
+
"aria-hidden": "true",
|
|
3427
|
+
className: "h-8 w-8 animate-spin text-muted-foreground"
|
|
3428
|
+
}
|
|
3429
|
+
),
|
|
3430
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
3431
|
+
/* @__PURE__ */ jsx15("p", { className: "text-sm font-medium", children: "Aguardando autoriza\xE7\xE3o..." }),
|
|
3432
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground", children: "Complete o login na janela que foi aberta." })
|
|
3433
|
+
] })
|
|
3434
|
+
] }),
|
|
3435
|
+
oauthStatus === "success" && oauthResult && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
3436
|
+
/* @__PURE__ */ jsx15(
|
|
3437
|
+
CheckCircle2,
|
|
3438
|
+
{
|
|
3439
|
+
"aria-hidden": "true",
|
|
3440
|
+
className: "h-8 w-8 text-green-600"
|
|
3441
|
+
}
|
|
3442
|
+
),
|
|
3443
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
3444
|
+
/* @__PURE__ */ jsx15("p", { className: "text-sm font-medium text-green-700", children: "Conectado com sucesso!" }),
|
|
3445
|
+
oauthResult.email && /* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground", children: oauthResult.email })
|
|
3446
|
+
] })
|
|
3447
|
+
] }),
|
|
3448
|
+
oauthStatus === "error" && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
3449
|
+
/* @__PURE__ */ jsx15(
|
|
3450
|
+
AlertCircle,
|
|
3451
|
+
{
|
|
3452
|
+
"aria-hidden": "true",
|
|
3453
|
+
className: "h-8 w-8 text-destructive"
|
|
3454
|
+
}
|
|
3455
|
+
),
|
|
3456
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
3457
|
+
/* @__PURE__ */ jsx15("p", { className: "text-sm font-medium text-destructive", children: "Falha na conex\xE3o" }),
|
|
3458
|
+
oauthResult?.error && /* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground", children: oauthResult.error })
|
|
3459
|
+
] }),
|
|
3460
|
+
/* @__PURE__ */ jsx15(Button10, { variant: "outline", onClick: onStartOAuth, size: "sm", children: "Tentar novamente" })
|
|
3461
|
+
] })
|
|
3462
|
+
] }),
|
|
3463
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
|
|
3464
|
+
/* @__PURE__ */ jsx15(
|
|
3465
|
+
Shield,
|
|
3466
|
+
{
|
|
3467
|
+
"aria-hidden": "true",
|
|
3468
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
|
|
3469
|
+
}
|
|
3470
|
+
),
|
|
3471
|
+
/* @__PURE__ */ jsxs13("p", { className: "text-xs text-muted-foreground", children: [
|
|
3472
|
+
"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 ",
|
|
3473
|
+
providerLabel,
|
|
3474
|
+
"."
|
|
3475
|
+
] })
|
|
3476
|
+
] })
|
|
3477
|
+
] });
|
|
3478
|
+
}
|
|
3479
|
+
function ApiKeyCredentials({
|
|
3480
|
+
apiKey,
|
|
3481
|
+
onApiKeyChange
|
|
3482
|
+
}) {
|
|
3483
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-6", children: [
|
|
3484
|
+
/* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
|
|
3485
|
+
/* @__PURE__ */ jsx15("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
|
|
3486
|
+
/* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "Insira a chave de API para conectar a integra\xE7\xE3o." })
|
|
3487
|
+
] }),
|
|
3488
|
+
/* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
|
|
3489
|
+
/* @__PURE__ */ jsx15(Label5, { htmlFor: "integration-api-key", children: "Chave de API" }),
|
|
3490
|
+
/* @__PURE__ */ jsx15(
|
|
3491
|
+
Input7,
|
|
3492
|
+
{
|
|
3493
|
+
id: "integration-api-key",
|
|
3494
|
+
type: "password",
|
|
3495
|
+
autoComplete: "off",
|
|
3496
|
+
placeholder: "Insira sua chave de API...",
|
|
3497
|
+
value: apiKey,
|
|
3498
|
+
onChange: (e) => onApiKeyChange(e.target.value)
|
|
3499
|
+
}
|
|
3500
|
+
)
|
|
3501
|
+
] }),
|
|
3502
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
|
|
3503
|
+
/* @__PURE__ */ jsx15(
|
|
3504
|
+
Shield,
|
|
3505
|
+
{
|
|
3506
|
+
"aria-hidden": "true",
|
|
3507
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
|
|
3508
|
+
}
|
|
3509
|
+
),
|
|
3510
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground", children: "Sua chave de API \xE9 armazenada de forma segura e encriptada. Nunca \xE9 exposta no frontend." })
|
|
3511
|
+
] })
|
|
3512
|
+
] });
|
|
3513
|
+
}
|
|
3514
|
+
|
|
3515
|
+
// src/components/capabilities/wizard-steps/config-step.tsx
|
|
3516
|
+
import { Loader2 as Loader26 } from "lucide-react";
|
|
3517
|
+
import {
|
|
3518
|
+
Label as Label6,
|
|
3519
|
+
Select as Select2,
|
|
3520
|
+
SelectContent as SelectContent2,
|
|
3521
|
+
SelectItem as SelectItem2,
|
|
3522
|
+
SelectTrigger as SelectTrigger2,
|
|
3523
|
+
SelectValue as SelectValue2
|
|
3524
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
3525
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3526
|
+
function ConfigStep({
|
|
3527
|
+
integration,
|
|
3528
|
+
options,
|
|
3529
|
+
isLoading,
|
|
3530
|
+
selectedValue,
|
|
3531
|
+
onValueChange,
|
|
3532
|
+
selectLabel,
|
|
3533
|
+
selectPlaceholder
|
|
3534
|
+
}) {
|
|
3535
|
+
const label = selectLabel || getDefaultLabel(integration.slug);
|
|
3536
|
+
const placeholder = selectPlaceholder || getDefaultPlaceholder(integration.slug);
|
|
3537
|
+
return /* @__PURE__ */ jsxs14("div", { className: "space-y-6", children: [
|
|
3538
|
+
/* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
|
|
3539
|
+
/* @__PURE__ */ jsx16("h3", { className: "text-lg font-semibold", children: "Configura\xE7\xE3o" }),
|
|
3540
|
+
/* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground", children: "Configure as op\xE7\xF5es espec\xEDficas da integra\xE7\xE3o." })
|
|
3541
|
+
] }),
|
|
3542
|
+
isLoading ? /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center gap-3 py-8", children: [
|
|
3543
|
+
/* @__PURE__ */ jsx16(
|
|
3544
|
+
Loader26,
|
|
3545
|
+
{
|
|
3546
|
+
"aria-hidden": "true",
|
|
3547
|
+
className: "h-6 w-6 animate-spin text-muted-foreground"
|
|
3548
|
+
}
|
|
3549
|
+
),
|
|
3550
|
+
/* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground", children: "Carregando op\xE7\xF5es..." })
|
|
3551
|
+
] }) : options.length === 0 ? /* @__PURE__ */ jsx16("div", { className: "rounded-lg border border-dashed p-6 text-center", children: /* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground", children: "Nenhuma op\xE7\xE3o dispon\xEDvel. A configura\xE7\xE3o padr\xE3o ser\xE1 usada." }) }) : /* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
|
|
3552
|
+
/* @__PURE__ */ jsx16(Label6, { htmlFor: "integration-config-select", children: label }),
|
|
3553
|
+
/* @__PURE__ */ jsxs14(Select2, { value: selectedValue, onValueChange, children: [
|
|
3554
|
+
/* @__PURE__ */ jsx16(SelectTrigger2, { id: "integration-config-select", children: /* @__PURE__ */ jsx16(SelectValue2, { placeholder }) }),
|
|
3555
|
+
/* @__PURE__ */ jsx16(SelectContent2, { children: options.map((opt) => /* @__PURE__ */ jsxs14(SelectItem2, { value: opt.id, children: [
|
|
3556
|
+
/* @__PURE__ */ jsx16("span", { children: opt.label }),
|
|
3557
|
+
opt.description && /* @__PURE__ */ jsxs14("span", { className: "ml-2 text-xs text-muted-foreground", children: [
|
|
3558
|
+
"(",
|
|
3559
|
+
opt.description,
|
|
3560
|
+
")"
|
|
3561
|
+
] })
|
|
3562
|
+
] }, opt.id)) })
|
|
3563
|
+
] })
|
|
3564
|
+
] })
|
|
3565
|
+
] });
|
|
3566
|
+
}
|
|
3567
|
+
function getDefaultLabel(slug) {
|
|
3568
|
+
switch (slug) {
|
|
3569
|
+
case "google_calendar":
|
|
3570
|
+
return "Calend\xE1rio";
|
|
3571
|
+
default:
|
|
3572
|
+
return "Op\xE7\xE3o";
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
function getDefaultPlaceholder(slug) {
|
|
3576
|
+
switch (slug) {
|
|
3577
|
+
case "google_calendar":
|
|
3578
|
+
return "Selecione o calend\xE1rio...";
|
|
3579
|
+
default:
|
|
3580
|
+
return "Selecione uma op\xE7\xE3o...";
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
|
|
3584
|
+
// src/components/capabilities/wizard-steps/confirm-step.tsx
|
|
3585
|
+
import { CheckCircle2 as CheckCircle22 } from "lucide-react";
|
|
3586
|
+
import { Label as Label7 } from "@greatapps/greatauth-ui/ui";
|
|
3587
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3588
|
+
function ConfirmStep({
|
|
3589
|
+
integration,
|
|
3590
|
+
oauthResult,
|
|
3591
|
+
selectedConfigOption,
|
|
3592
|
+
enableOnComplete,
|
|
3593
|
+
onEnableChange
|
|
3594
|
+
}) {
|
|
3595
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-6", children: [
|
|
3596
|
+
/* @__PURE__ */ jsxs15("div", { className: "space-y-2", children: [
|
|
3597
|
+
/* @__PURE__ */ jsx17("h3", { className: "text-lg font-semibold", children: "Confirma\xE7\xE3o" }),
|
|
3598
|
+
/* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground", children: "Revise as configura\xE7\xF5es antes de concluir." })
|
|
3599
|
+
] }),
|
|
3600
|
+
/* @__PURE__ */ jsxs15("div", { className: "space-y-3 rounded-lg border p-4", children: [
|
|
3601
|
+
/* @__PURE__ */ jsx17(SummaryRow, { label: "Integra\xE7\xE3o", value: integration.name }),
|
|
3602
|
+
oauthResult?.email && /* @__PURE__ */ jsx17(SummaryRow, { label: "Conta conectada", value: oauthResult.email }),
|
|
3603
|
+
selectedConfigOption && /* @__PURE__ */ jsx17(
|
|
3604
|
+
SummaryRow,
|
|
3605
|
+
{
|
|
3606
|
+
label: getConfigLabel(integration.slug),
|
|
3607
|
+
value: selectedConfigOption.label
|
|
3608
|
+
}
|
|
3609
|
+
),
|
|
3610
|
+
/* @__PURE__ */ jsx17(
|
|
3611
|
+
SummaryRow,
|
|
3612
|
+
{
|
|
3613
|
+
label: "Tipo de autentica\xE7\xE3o",
|
|
3614
|
+
value: integration.authType === "oauth2" ? "OAuth 2.0" : "API Key"
|
|
3615
|
+
}
|
|
3616
|
+
)
|
|
3617
|
+
] }),
|
|
3618
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between rounded-lg border p-4", children: [
|
|
3619
|
+
/* @__PURE__ */ jsxs15("div", { className: "space-y-0.5", children: [
|
|
3620
|
+
/* @__PURE__ */ jsx17(Label7, { htmlFor: "enable-on-complete", className: "text-sm font-medium", children: "Ativar imediatamente" }),
|
|
3621
|
+
/* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground", children: "A integra\xE7\xE3o ficar\xE1 ativa assim que concluir o assistente." })
|
|
3622
|
+
] }),
|
|
3623
|
+
/* @__PURE__ */ jsx17(
|
|
3624
|
+
"button",
|
|
3625
|
+
{
|
|
3626
|
+
id: "enable-on-complete",
|
|
3627
|
+
role: "switch",
|
|
3628
|
+
type: "button",
|
|
3629
|
+
"aria-checked": enableOnComplete,
|
|
3630
|
+
onClick: () => onEnableChange(!enableOnComplete),
|
|
3631
|
+
className: `
|
|
3632
|
+
relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent
|
|
3633
|
+
transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2
|
|
3634
|
+
focus-visible:ring-ring focus-visible:ring-offset-2
|
|
3635
|
+
${enableOnComplete ? "bg-primary" : "bg-muted"}
|
|
3636
|
+
`,
|
|
3637
|
+
children: /* @__PURE__ */ jsx17(
|
|
3638
|
+
"span",
|
|
3639
|
+
{
|
|
3640
|
+
"aria-hidden": "true",
|
|
3641
|
+
className: `
|
|
3642
|
+
pointer-events-none inline-block h-5 w-5 transform rounded-full bg-background shadow-lg
|
|
3643
|
+
ring-0 transition duration-200 ease-in-out
|
|
3644
|
+
${enableOnComplete ? "translate-x-5" : "translate-x-0"}
|
|
3645
|
+
`
|
|
3646
|
+
}
|
|
3647
|
+
)
|
|
3648
|
+
}
|
|
3649
|
+
)
|
|
3650
|
+
] }),
|
|
3651
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 rounded-md bg-green-50 p-3 dark:bg-green-950/20", children: [
|
|
3652
|
+
/* @__PURE__ */ jsx17(
|
|
3653
|
+
CheckCircle22,
|
|
3654
|
+
{
|
|
3655
|
+
"aria-hidden": "true",
|
|
3656
|
+
className: "h-4 w-4 shrink-0 text-green-600"
|
|
3657
|
+
}
|
|
3658
|
+
),
|
|
3659
|
+
/* @__PURE__ */ jsx17("p", { className: "text-xs text-green-700 dark:text-green-400", children: 'Tudo pronto! Clique em "Concluir" para finalizar a configura\xE7\xE3o.' })
|
|
3660
|
+
] })
|
|
3661
|
+
] });
|
|
3662
|
+
}
|
|
3663
|
+
function SummaryRow({ label, value }) {
|
|
3664
|
+
return /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between text-sm", children: [
|
|
3665
|
+
/* @__PURE__ */ jsx17("span", { className: "text-muted-foreground", children: label }),
|
|
3666
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium", children: value })
|
|
3667
|
+
] });
|
|
3668
|
+
}
|
|
3669
|
+
function getConfigLabel(slug) {
|
|
3670
|
+
switch (slug) {
|
|
3671
|
+
case "google_calendar":
|
|
3672
|
+
return "Calend\xE1rio";
|
|
3673
|
+
default:
|
|
3674
|
+
return "Configura\xE7\xE3o";
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
|
|
3678
|
+
// src/components/capabilities/integration-wizard.tsx
|
|
3679
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3680
|
+
var STEPS = ["info", "credentials", "config", "confirm"];
|
|
3681
|
+
var STEP_LABELS = {
|
|
3682
|
+
info: "Informa\xE7\xE3o",
|
|
3683
|
+
credentials: "Credenciais",
|
|
3684
|
+
config: "Configura\xE7\xE3o",
|
|
3685
|
+
confirm: "Confirma\xE7\xE3o"
|
|
3686
|
+
};
|
|
3687
|
+
function IntegrationWizard({
|
|
3688
|
+
open,
|
|
3689
|
+
onOpenChange,
|
|
3690
|
+
integration,
|
|
3691
|
+
meta,
|
|
3692
|
+
agentId: _agentId,
|
|
3693
|
+
config,
|
|
3694
|
+
onComplete,
|
|
3695
|
+
gagentsApiUrl,
|
|
3696
|
+
existingCredentialId,
|
|
3697
|
+
loadConfigOptions,
|
|
3698
|
+
existingConfigValue
|
|
3699
|
+
}) {
|
|
3700
|
+
const isReconnect = !!existingCredentialId;
|
|
3701
|
+
const [currentStep, setCurrentStep] = useState10("info");
|
|
3702
|
+
const currentIndex = STEPS.indexOf(currentStep);
|
|
3703
|
+
const [oauthStatus, setOauthStatus] = useState10("idle");
|
|
3704
|
+
const [oauthResult, setOauthResult] = useState10(null);
|
|
3705
|
+
const popupRef = useRef3(null);
|
|
3706
|
+
const popupPollRef = useRef3(null);
|
|
3707
|
+
const [apiKey, setApiKey] = useState10("");
|
|
3708
|
+
const [configOptions, setConfigOptions] = useState10([]);
|
|
3709
|
+
const [configLoading, setConfigLoading] = useState10(false);
|
|
3710
|
+
const [selectedConfigValue, setSelectedConfigValue] = useState10("");
|
|
3711
|
+
const [enableOnComplete, setEnableOnComplete] = useState10(true);
|
|
3712
|
+
const [isSubmitting, setIsSubmitting] = useState10(false);
|
|
3713
|
+
useEffect5(() => {
|
|
3714
|
+
return () => {
|
|
3715
|
+
if (popupPollRef.current) {
|
|
3716
|
+
clearInterval(popupPollRef.current);
|
|
3717
|
+
}
|
|
3718
|
+
};
|
|
3719
|
+
}, []);
|
|
3720
|
+
useEffect5(() => {
|
|
3721
|
+
if (open) {
|
|
3722
|
+
setCurrentStep("info");
|
|
3723
|
+
setOauthStatus("idle");
|
|
3724
|
+
setOauthResult(null);
|
|
3725
|
+
setApiKey("");
|
|
3726
|
+
setConfigOptions([]);
|
|
3727
|
+
setConfigLoading(false);
|
|
3728
|
+
setSelectedConfigValue(existingConfigValue ?? "");
|
|
3729
|
+
setEnableOnComplete(true);
|
|
3730
|
+
setIsSubmitting(false);
|
|
3731
|
+
} else {
|
|
3732
|
+
if (popupRef.current && !popupRef.current.closed) {
|
|
3733
|
+
popupRef.current.close();
|
|
3734
|
+
}
|
|
3735
|
+
if (popupPollRef.current) {
|
|
3736
|
+
clearInterval(popupPollRef.current);
|
|
3737
|
+
popupPollRef.current = null;
|
|
3738
|
+
}
|
|
3739
|
+
}
|
|
3740
|
+
}, [open]);
|
|
3741
|
+
const handleOAuthMessage = useCallback5(
|
|
3742
|
+
(event) => {
|
|
3743
|
+
try {
|
|
3744
|
+
if (event.origin !== new URL(gagentsApiUrl).origin) return;
|
|
3745
|
+
} catch {
|
|
3746
|
+
return;
|
|
3747
|
+
}
|
|
3748
|
+
if (!event.data || typeof event.data !== "object") return;
|
|
3749
|
+
const msg = event.data;
|
|
3750
|
+
if (msg.type !== "oauth-callback") return;
|
|
3751
|
+
if (msg.success) {
|
|
3752
|
+
setOauthStatus("success");
|
|
3753
|
+
setOauthResult({
|
|
3754
|
+
success: true,
|
|
3755
|
+
email: msg.email,
|
|
3756
|
+
credentialId: msg.credentialId
|
|
3757
|
+
});
|
|
3758
|
+
const credId = msg.credentialId || existingCredentialId;
|
|
3759
|
+
if (credId && loadConfigOptions && meta.hasConfigStep) {
|
|
3760
|
+
setConfigLoading(true);
|
|
3761
|
+
loadConfigOptions(credId).then((opts) => {
|
|
3762
|
+
setConfigOptions(opts);
|
|
3763
|
+
if (opts.length === 1) {
|
|
3764
|
+
setSelectedConfigValue(opts[0].id);
|
|
3765
|
+
}
|
|
3766
|
+
}).catch(() => setConfigOptions([])).finally(() => setConfigLoading(false));
|
|
3767
|
+
}
|
|
3768
|
+
setTimeout(() => {
|
|
3769
|
+
setCurrentStep(meta.hasConfigStep ? "config" : "confirm");
|
|
3770
|
+
}, 1200);
|
|
3771
|
+
} else {
|
|
3772
|
+
setOauthStatus("error");
|
|
3773
|
+
setOauthResult({
|
|
3774
|
+
success: false,
|
|
3775
|
+
error: msg.error || "Falha na autoriza\xE7\xE3o"
|
|
3776
|
+
});
|
|
3777
|
+
}
|
|
3778
|
+
},
|
|
3779
|
+
[gagentsApiUrl, existingCredentialId, meta.hasConfigStep, loadConfigOptions]
|
|
3780
|
+
);
|
|
3781
|
+
useEffect5(() => {
|
|
3782
|
+
if (!open) return;
|
|
3783
|
+
window.addEventListener("message", handleOAuthMessage);
|
|
3784
|
+
return () => window.removeEventListener("message", handleOAuthMessage);
|
|
3785
|
+
}, [open, handleOAuthMessage]);
|
|
3786
|
+
function startOAuth() {
|
|
3787
|
+
const { language = "pt-br", idWl = 1, accountId } = config;
|
|
3788
|
+
const redirectUri = `${window.location.origin}/oauth/callback`;
|
|
3789
|
+
const url = new URL(
|
|
3790
|
+
`${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${accountId}/oauth/authorize/${integration.slug}`
|
|
3791
|
+
);
|
|
3792
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
3793
|
+
setOauthStatus("waiting");
|
|
3794
|
+
const popup = window.open(
|
|
3795
|
+
url.toString(),
|
|
3796
|
+
"oauth-popup",
|
|
3797
|
+
"width=500,height=600,scrollbars=yes,resizable=yes"
|
|
3798
|
+
);
|
|
3799
|
+
popupRef.current = popup;
|
|
3800
|
+
if (popup) {
|
|
3801
|
+
if (popupPollRef.current) {
|
|
3802
|
+
clearInterval(popupPollRef.current);
|
|
3803
|
+
}
|
|
3804
|
+
popupPollRef.current = setInterval(() => {
|
|
3805
|
+
if (popup.closed) {
|
|
3806
|
+
if (popupPollRef.current) {
|
|
3807
|
+
clearInterval(popupPollRef.current);
|
|
3808
|
+
popupPollRef.current = null;
|
|
3809
|
+
}
|
|
3810
|
+
setOauthStatus(
|
|
3811
|
+
(prev) => prev === "waiting" ? "error" : prev
|
|
3812
|
+
);
|
|
3813
|
+
setOauthResult(
|
|
3814
|
+
(prev) => prev === null ? { success: false, error: "Janela fechada antes de concluir" } : prev
|
|
3815
|
+
);
|
|
3816
|
+
}
|
|
3817
|
+
}, 500);
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
function canAdvance() {
|
|
3821
|
+
switch (currentStep) {
|
|
3822
|
+
case "info":
|
|
3823
|
+
return true;
|
|
3824
|
+
case "credentials":
|
|
3825
|
+
if (integration.authType === "oauth2") {
|
|
3826
|
+
return oauthStatus === "success";
|
|
3827
|
+
}
|
|
3828
|
+
return apiKey.trim().length > 0;
|
|
3829
|
+
case "config":
|
|
3830
|
+
return true;
|
|
3831
|
+
case "confirm":
|
|
3832
|
+
return true;
|
|
3833
|
+
default:
|
|
3834
|
+
return false;
|
|
3835
|
+
}
|
|
3836
|
+
}
|
|
3837
|
+
function goNext() {
|
|
3838
|
+
if (!canAdvance()) return;
|
|
3839
|
+
if (currentStep === "credentials" && !meta.hasConfigStep) {
|
|
3840
|
+
setCurrentStep("confirm");
|
|
3841
|
+
return;
|
|
3842
|
+
}
|
|
3843
|
+
const nextIndex = currentIndex + 1;
|
|
3844
|
+
if (nextIndex < STEPS.length) {
|
|
3845
|
+
setCurrentStep(STEPS[nextIndex]);
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
3848
|
+
function goPrev() {
|
|
3849
|
+
if (currentStep === "confirm" && !meta.hasConfigStep) {
|
|
3850
|
+
setCurrentStep("credentials");
|
|
3851
|
+
return;
|
|
3852
|
+
}
|
|
3853
|
+
const prevIndex = currentIndex - 1;
|
|
3854
|
+
if (prevIndex >= 0) {
|
|
3855
|
+
setCurrentStep(STEPS[prevIndex]);
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
async function handleComplete() {
|
|
3859
|
+
setIsSubmitting(true);
|
|
3860
|
+
try {
|
|
3861
|
+
onComplete();
|
|
3862
|
+
onOpenChange(false);
|
|
3863
|
+
toast8.success(
|
|
3864
|
+
`${integration.name} ${isReconnect ? "reconectado" : "configurado"} com sucesso!`
|
|
3865
|
+
);
|
|
3866
|
+
} catch {
|
|
3867
|
+
toast8.error("Erro ao finalizar configura\xE7\xE3o");
|
|
3868
|
+
} finally {
|
|
3869
|
+
setIsSubmitting(false);
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
const selectedConfigOption = configOptions.find((o) => o.id === selectedConfigValue) || null;
|
|
3873
|
+
const isLastStep = currentStep === "confirm";
|
|
3874
|
+
const effectiveSteps = meta.hasConfigStep ? STEPS : STEPS.filter((s) => s !== "config");
|
|
3875
|
+
return /* @__PURE__ */ jsx18(Dialog5, { open, onOpenChange, children: /* @__PURE__ */ jsxs16(DialogContent5, { className: "sm:max-w-lg", children: [
|
|
3876
|
+
/* @__PURE__ */ jsx18(DialogHeader5, { children: /* @__PURE__ */ jsx18(DialogTitle5, { children: integration.name }) }),
|
|
3877
|
+
/* @__PURE__ */ jsx18(StepIndicator, { steps: effectiveSteps, currentStep }),
|
|
3878
|
+
/* @__PURE__ */ jsxs16("div", { className: "min-h-[280px] py-2", children: [
|
|
3879
|
+
currentStep === "info" && /* @__PURE__ */ jsx18(
|
|
3880
|
+
InfoStep,
|
|
3881
|
+
{
|
|
3882
|
+
integration,
|
|
3883
|
+
meta
|
|
3884
|
+
}
|
|
3885
|
+
),
|
|
3886
|
+
currentStep === "credentials" && /* @__PURE__ */ jsx18(
|
|
3887
|
+
CredentialsStep,
|
|
3888
|
+
{
|
|
3889
|
+
integration,
|
|
3890
|
+
meta,
|
|
3891
|
+
oauthStatus,
|
|
3892
|
+
oauthResult,
|
|
3893
|
+
apiKey,
|
|
3894
|
+
onApiKeyChange: setApiKey,
|
|
3895
|
+
onStartOAuth: startOAuth,
|
|
3896
|
+
isReconnect
|
|
3897
|
+
}
|
|
3898
|
+
),
|
|
3899
|
+
currentStep === "config" && /* @__PURE__ */ jsx18(
|
|
3900
|
+
ConfigStep,
|
|
3901
|
+
{
|
|
3902
|
+
integration,
|
|
3903
|
+
options: configOptions,
|
|
3904
|
+
isLoading: configLoading,
|
|
3905
|
+
selectedValue: selectedConfigValue,
|
|
3906
|
+
onValueChange: setSelectedConfigValue
|
|
3907
|
+
}
|
|
3908
|
+
),
|
|
3909
|
+
currentStep === "confirm" && /* @__PURE__ */ jsx18(
|
|
3910
|
+
ConfirmStep,
|
|
3911
|
+
{
|
|
3912
|
+
integration,
|
|
3913
|
+
oauthResult,
|
|
3914
|
+
selectedConfigOption,
|
|
3915
|
+
enableOnComplete,
|
|
3916
|
+
onEnableChange: setEnableOnComplete
|
|
3917
|
+
}
|
|
3918
|
+
)
|
|
3919
|
+
] }),
|
|
3920
|
+
/* @__PURE__ */ jsxs16(DialogFooter5, { className: "flex-row justify-between sm:justify-between", children: [
|
|
3921
|
+
/* @__PURE__ */ jsx18("div", { children: currentStep === "info" ? /* @__PURE__ */ jsx18(
|
|
3922
|
+
Button11,
|
|
3923
|
+
{
|
|
3924
|
+
type: "button",
|
|
3925
|
+
variant: "outline",
|
|
3926
|
+
onClick: () => onOpenChange(false),
|
|
3927
|
+
children: "Cancelar"
|
|
3928
|
+
}
|
|
3929
|
+
) : /* @__PURE__ */ jsxs16(
|
|
3930
|
+
Button11,
|
|
3931
|
+
{
|
|
3932
|
+
type: "button",
|
|
3933
|
+
variant: "outline",
|
|
3934
|
+
onClick: goPrev,
|
|
3935
|
+
className: "gap-1",
|
|
3936
|
+
children: [
|
|
3937
|
+
/* @__PURE__ */ jsx18(ChevronLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
|
|
3938
|
+
"Voltar"
|
|
3939
|
+
]
|
|
3940
|
+
}
|
|
3941
|
+
) }),
|
|
3942
|
+
/* @__PURE__ */ jsx18("div", { children: isLastStep ? /* @__PURE__ */ jsxs16(
|
|
3943
|
+
Button11,
|
|
3944
|
+
{
|
|
3945
|
+
type: "button",
|
|
3946
|
+
onClick: handleComplete,
|
|
3947
|
+
disabled: isSubmitting,
|
|
3948
|
+
className: "gap-1",
|
|
3949
|
+
children: [
|
|
3950
|
+
isSubmitting ? /* @__PURE__ */ jsx18(
|
|
3951
|
+
Loader27,
|
|
3952
|
+
{
|
|
3953
|
+
"aria-hidden": "true",
|
|
3954
|
+
className: "h-4 w-4 animate-spin"
|
|
3955
|
+
}
|
|
3956
|
+
) : /* @__PURE__ */ jsx18(Check2, { "aria-hidden": "true", className: "h-4 w-4" }),
|
|
3957
|
+
"Concluir"
|
|
3958
|
+
]
|
|
3959
|
+
}
|
|
3960
|
+
) : /* @__PURE__ */ jsxs16(
|
|
3961
|
+
Button11,
|
|
3962
|
+
{
|
|
3963
|
+
type: "button",
|
|
3964
|
+
onClick: goNext,
|
|
3965
|
+
disabled: !canAdvance(),
|
|
3966
|
+
className: "gap-1",
|
|
3967
|
+
children: [
|
|
3968
|
+
"Continuar",
|
|
3969
|
+
/* @__PURE__ */ jsx18(ChevronRight, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
3970
|
+
]
|
|
3971
|
+
}
|
|
3972
|
+
) })
|
|
3973
|
+
] })
|
|
3974
|
+
] }) });
|
|
3975
|
+
}
|
|
3976
|
+
function StepIndicator({
|
|
3977
|
+
steps,
|
|
3978
|
+
currentStep
|
|
3979
|
+
}) {
|
|
3980
|
+
const currentIndex = steps.indexOf(currentStep);
|
|
3981
|
+
return /* @__PURE__ */ jsx18(
|
|
3982
|
+
"div",
|
|
3983
|
+
{
|
|
3984
|
+
className: "flex items-center justify-center gap-1 py-2",
|
|
3985
|
+
role: "list",
|
|
3986
|
+
"aria-label": "Passos do assistente",
|
|
3987
|
+
children: steps.map((step, i) => {
|
|
3988
|
+
const isCompleted = i < currentIndex;
|
|
3989
|
+
const isCurrent = step === currentStep;
|
|
3990
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex items-center", role: "listitem", children: [
|
|
3991
|
+
/* @__PURE__ */ jsx18(
|
|
3992
|
+
"div",
|
|
3993
|
+
{
|
|
3994
|
+
className: `
|
|
3995
|
+
flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium
|
|
3996
|
+
transition-colors duration-200
|
|
3997
|
+
${isCurrent ? "bg-primary text-primary-foreground" : isCompleted ? "bg-green-600 text-white" : "bg-muted text-muted-foreground"}
|
|
3998
|
+
`,
|
|
3999
|
+
"aria-current": isCurrent ? "step" : void 0,
|
|
4000
|
+
"aria-label": `${STEP_LABELS[step]}${isCompleted ? " (conclu\xEDdo)" : isCurrent ? " (atual)" : ""}`,
|
|
4001
|
+
children: isCompleted ? /* @__PURE__ */ jsx18(Check2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : i + 1
|
|
4002
|
+
}
|
|
4003
|
+
),
|
|
4004
|
+
/* @__PURE__ */ jsx18(
|
|
4005
|
+
"span",
|
|
4006
|
+
{
|
|
4007
|
+
className: `
|
|
4008
|
+
ml-1.5 hidden text-xs sm:inline
|
|
4009
|
+
${isCurrent ? "font-medium text-foreground" : "text-muted-foreground"}
|
|
4010
|
+
`,
|
|
4011
|
+
children: STEP_LABELS[step]
|
|
4012
|
+
}
|
|
4013
|
+
),
|
|
4014
|
+
i < steps.length - 1 && /* @__PURE__ */ jsx18(
|
|
4015
|
+
"div",
|
|
4016
|
+
{
|
|
4017
|
+
className: `
|
|
4018
|
+
mx-2 h-px w-6
|
|
4019
|
+
${i < currentIndex ? "bg-green-600" : "bg-border"}
|
|
4020
|
+
`
|
|
4021
|
+
}
|
|
4022
|
+
)
|
|
4023
|
+
] }, step);
|
|
4024
|
+
})
|
|
4025
|
+
}
|
|
4026
|
+
);
|
|
4027
|
+
}
|
|
4028
|
+
|
|
4029
|
+
// src/components/capabilities/advanced-tab.tsx
|
|
4030
|
+
import { useState as useState14 } from "react";
|
|
4031
|
+
|
|
4032
|
+
// src/components/tools/tools-table.tsx
|
|
4033
|
+
import { useMemo as useMemo6, useState as useState11 } from "react";
|
|
4034
|
+
import { DataTable as DataTable2 } from "@greatapps/greatauth-ui";
|
|
4035
|
+
import {
|
|
4036
|
+
Input as Input8,
|
|
4037
|
+
Badge as Badge8,
|
|
4038
|
+
Tooltip as Tooltip3,
|
|
4039
|
+
TooltipTrigger as TooltipTrigger3,
|
|
4040
|
+
TooltipContent as TooltipContent3,
|
|
4041
|
+
AlertDialog as AlertDialog4,
|
|
4042
|
+
AlertDialogAction as AlertDialogAction4,
|
|
4043
|
+
AlertDialogCancel as AlertDialogCancel4,
|
|
4044
|
+
AlertDialogContent as AlertDialogContent4,
|
|
4045
|
+
AlertDialogDescription as AlertDialogDescription4,
|
|
4046
|
+
AlertDialogFooter as AlertDialogFooter4,
|
|
4047
|
+
AlertDialogHeader as AlertDialogHeader4,
|
|
4048
|
+
AlertDialogTitle as AlertDialogTitle4,
|
|
4049
|
+
Button as Button12
|
|
4050
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
4051
|
+
import { Pencil as Pencil3, Trash2 as Trash24, Search as Search2 } from "lucide-react";
|
|
4052
|
+
import { format as format2 } from "date-fns";
|
|
4053
|
+
import { ptBR as ptBR2 } from "date-fns/locale";
|
|
4054
|
+
import { toast as toast9 } from "sonner";
|
|
4055
|
+
import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4056
|
+
function useColumns2(onEdit, onDelete) {
|
|
4057
|
+
return [
|
|
4058
|
+
{
|
|
4059
|
+
accessorKey: "name",
|
|
4060
|
+
header: "Nome",
|
|
4061
|
+
cell: ({ row }) => /* @__PURE__ */ jsx19("span", { className: "font-medium", children: row.original.name }),
|
|
4062
|
+
sortingFn: (rowA, rowB) => rowA.original.name.toLowerCase().localeCompare(rowB.original.name.toLowerCase())
|
|
4063
|
+
},
|
|
4064
|
+
{
|
|
4065
|
+
accessorKey: "slug",
|
|
4066
|
+
header: "Slug",
|
|
4067
|
+
cell: ({ row }) => /* @__PURE__ */ jsx19("span", { className: "text-muted-foreground text-sm font-mono", children: row.original.slug || "\u2014" })
|
|
4068
|
+
},
|
|
4069
|
+
{
|
|
4070
|
+
accessorKey: "type",
|
|
4071
|
+
header: "Tipo",
|
|
4072
|
+
cell: ({ row }) => /* @__PURE__ */ jsx19(Badge8, { variant: "secondary", children: row.original.type })
|
|
4073
|
+
},
|
|
4074
|
+
{
|
|
4075
|
+
accessorKey: "description",
|
|
4076
|
+
header: "Descri\xE7\xE3o",
|
|
4077
|
+
cell: ({ row }) => {
|
|
4078
|
+
const desc = row.original.description;
|
|
4079
|
+
if (!desc) return /* @__PURE__ */ jsx19("span", { className: "text-muted-foreground text-sm", children: "\u2014" });
|
|
4080
|
+
return /* @__PURE__ */ jsx19("span", { className: "text-muted-foreground text-sm", children: desc.length > 50 ? `${desc.slice(0, 50)}\u2026` : desc });
|
|
4081
|
+
}
|
|
4082
|
+
},
|
|
4083
|
+
{
|
|
4084
|
+
accessorKey: "datetime_add",
|
|
4085
|
+
header: "Criado em",
|
|
4086
|
+
cell: ({ row }) => /* @__PURE__ */ jsx19("span", { className: "text-muted-foreground text-sm", children: format2(new Date(row.original.datetime_add), "dd/MM/yyyy", {
|
|
4087
|
+
locale: ptBR2
|
|
4088
|
+
}) })
|
|
4089
|
+
},
|
|
4090
|
+
{
|
|
4091
|
+
id: "actions",
|
|
4092
|
+
size: 80,
|
|
4093
|
+
enableSorting: false,
|
|
4094
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1", children: [
|
|
4095
|
+
/* @__PURE__ */ jsxs17(Tooltip3, { children: [
|
|
4096
|
+
/* @__PURE__ */ jsx19(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx19(
|
|
4097
|
+
Button12,
|
|
4098
|
+
{
|
|
4099
|
+
variant: "ghost",
|
|
4100
|
+
size: "icon",
|
|
4101
|
+
className: "h-8 w-8",
|
|
4102
|
+
"aria-label": "Editar",
|
|
4103
|
+
onClick: () => onEdit(row.original),
|
|
4104
|
+
children: /* @__PURE__ */ jsx19(Pencil3, { className: "h-4 w-4" })
|
|
4105
|
+
}
|
|
4106
|
+
) }),
|
|
4107
|
+
/* @__PURE__ */ jsx19(TooltipContent3, { children: "Editar" })
|
|
4108
|
+
] }),
|
|
4109
|
+
/* @__PURE__ */ jsxs17(Tooltip3, { children: [
|
|
4110
|
+
/* @__PURE__ */ jsx19(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx19(
|
|
4111
|
+
Button12,
|
|
4112
|
+
{
|
|
4113
|
+
variant: "ghost",
|
|
4114
|
+
size: "icon",
|
|
4115
|
+
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
4116
|
+
"aria-label": "Excluir",
|
|
4117
|
+
onClick: () => onDelete(row.original.id),
|
|
4118
|
+
children: /* @__PURE__ */ jsx19(Trash24, { className: "h-4 w-4" })
|
|
4119
|
+
}
|
|
4120
|
+
) }),
|
|
4121
|
+
/* @__PURE__ */ jsx19(TooltipContent3, { children: "Excluir" })
|
|
4122
|
+
] })
|
|
4123
|
+
] })
|
|
4124
|
+
}
|
|
4125
|
+
];
|
|
4126
|
+
}
|
|
4127
|
+
function ToolsTable({ onEdit, config }) {
|
|
4128
|
+
const [search, setSearch] = useState11("");
|
|
4129
|
+
const [page, setPage] = useState11(1);
|
|
4130
|
+
const queryParams = useMemo6(() => {
|
|
4131
|
+
const params = {
|
|
4132
|
+
limit: "15",
|
|
4133
|
+
page: String(page)
|
|
4134
|
+
};
|
|
4135
|
+
if (search) {
|
|
4136
|
+
params.search = search;
|
|
4137
|
+
}
|
|
4138
|
+
return params;
|
|
4139
|
+
}, [search, page]);
|
|
4140
|
+
const { data, isLoading } = useTools(config, queryParams);
|
|
4141
|
+
const deleteTool = useDeleteTool(config);
|
|
4142
|
+
const [deleteId, setDeleteId] = useState11(null);
|
|
4143
|
+
const tools = data?.data || [];
|
|
4144
|
+
const total = data?.total || 0;
|
|
4145
|
+
const columns = useColumns2(
|
|
4146
|
+
(tool) => onEdit(tool),
|
|
4147
|
+
(id) => setDeleteId(id)
|
|
4148
|
+
);
|
|
4149
|
+
function handleDelete() {
|
|
4150
|
+
if (!deleteId) return;
|
|
4151
|
+
deleteTool.mutate(deleteId, {
|
|
4152
|
+
onSuccess: () => {
|
|
4153
|
+
toast9.success("Ferramenta exclu\xEDda");
|
|
4154
|
+
setDeleteId(null);
|
|
4155
|
+
},
|
|
4156
|
+
onError: () => toast9.error("Erro ao excluir ferramenta")
|
|
4157
|
+
});
|
|
4158
|
+
}
|
|
4159
|
+
function handleSearchChange(value) {
|
|
4160
|
+
setSearch(value);
|
|
4161
|
+
setPage(1);
|
|
4162
|
+
}
|
|
4163
|
+
return /* @__PURE__ */ jsxs17(Fragment2, { children: [
|
|
4164
|
+
/* @__PURE__ */ jsx19("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs17("div", { className: "relative flex-1 max-w-md", children: [
|
|
4165
|
+
/* @__PURE__ */ jsx19(Search2, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
4166
|
+
/* @__PURE__ */ jsx19(
|
|
4167
|
+
Input8,
|
|
4168
|
+
{
|
|
4169
|
+
placeholder: "Buscar ferramentas\\u2026",
|
|
2824
4170
|
"aria-label": "Buscar ferramentas",
|
|
2825
4171
|
name: "search",
|
|
2826
4172
|
autoComplete: "off",
|
|
2827
4173
|
value: search,
|
|
2828
|
-
onChange: (e) => handleSearchChange(e.target.value),
|
|
4174
|
+
onChange: (e) => handleSearchChange(e.target.value),
|
|
4175
|
+
className: "pl-9"
|
|
4176
|
+
}
|
|
4177
|
+
)
|
|
4178
|
+
] }) }),
|
|
4179
|
+
/* @__PURE__ */ jsx19(
|
|
4180
|
+
DataTable2,
|
|
4181
|
+
{
|
|
4182
|
+
columns,
|
|
4183
|
+
data: tools,
|
|
4184
|
+
isLoading,
|
|
4185
|
+
emptyMessage: "Nenhuma ferramenta encontrada",
|
|
4186
|
+
total,
|
|
4187
|
+
page,
|
|
4188
|
+
onPageChange: setPage,
|
|
4189
|
+
pageSize: 15
|
|
4190
|
+
}
|
|
4191
|
+
),
|
|
4192
|
+
/* @__PURE__ */ jsx19(
|
|
4193
|
+
AlertDialog4,
|
|
4194
|
+
{
|
|
4195
|
+
open: !!deleteId,
|
|
4196
|
+
onOpenChange: (open) => !open && setDeleteId(null),
|
|
4197
|
+
children: /* @__PURE__ */ jsxs17(AlertDialogContent4, { children: [
|
|
4198
|
+
/* @__PURE__ */ jsxs17(AlertDialogHeader4, { children: [
|
|
4199
|
+
/* @__PURE__ */ jsx19(AlertDialogTitle4, { children: "Excluir ferramenta?" }),
|
|
4200
|
+
/* @__PURE__ */ jsx19(AlertDialogDescription4, { children: "Esta a\xE7\xE3o n\xE3o pode ser desfeita. A ferramenta ser\xE1 removida permanentemente." })
|
|
4201
|
+
] }),
|
|
4202
|
+
/* @__PURE__ */ jsxs17(AlertDialogFooter4, { children: [
|
|
4203
|
+
/* @__PURE__ */ jsx19(AlertDialogCancel4, { variant: "outline", size: "default", children: "Cancelar" }),
|
|
4204
|
+
/* @__PURE__ */ jsx19(
|
|
4205
|
+
AlertDialogAction4,
|
|
4206
|
+
{
|
|
4207
|
+
variant: "default",
|
|
4208
|
+
size: "default",
|
|
4209
|
+
onClick: handleDelete,
|
|
4210
|
+
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
4211
|
+
children: "Excluir"
|
|
4212
|
+
}
|
|
4213
|
+
)
|
|
4214
|
+
] })
|
|
4215
|
+
] })
|
|
4216
|
+
}
|
|
4217
|
+
)
|
|
4218
|
+
] });
|
|
4219
|
+
}
|
|
4220
|
+
|
|
4221
|
+
// src/components/tools/tool-credentials-form.tsx
|
|
4222
|
+
import { useMemo as useMemo7, useState as useState12 } from "react";
|
|
4223
|
+
import { DataTable as DataTable3 } from "@greatapps/greatauth-ui";
|
|
4224
|
+
import {
|
|
4225
|
+
Input as Input9,
|
|
4226
|
+
Button as Button13,
|
|
4227
|
+
Badge as Badge9,
|
|
4228
|
+
Tooltip as Tooltip4,
|
|
4229
|
+
TooltipTrigger as TooltipTrigger4,
|
|
4230
|
+
TooltipContent as TooltipContent4,
|
|
4231
|
+
Dialog as Dialog6,
|
|
4232
|
+
DialogContent as DialogContent6,
|
|
4233
|
+
DialogHeader as DialogHeader6,
|
|
4234
|
+
DialogTitle as DialogTitle6,
|
|
4235
|
+
DialogFooter as DialogFooter6,
|
|
4236
|
+
AlertDialog as AlertDialog5,
|
|
4237
|
+
AlertDialogAction as AlertDialogAction5,
|
|
4238
|
+
AlertDialogCancel as AlertDialogCancel5,
|
|
4239
|
+
AlertDialogContent as AlertDialogContent5,
|
|
4240
|
+
AlertDialogDescription as AlertDialogDescription5,
|
|
4241
|
+
AlertDialogFooter as AlertDialogFooter5,
|
|
4242
|
+
AlertDialogHeader as AlertDialogHeader5,
|
|
4243
|
+
AlertDialogTitle as AlertDialogTitle5,
|
|
4244
|
+
Select as Select3,
|
|
4245
|
+
SelectContent as SelectContent3,
|
|
4246
|
+
SelectItem as SelectItem3,
|
|
4247
|
+
SelectTrigger as SelectTrigger3,
|
|
4248
|
+
SelectValue as SelectValue3
|
|
4249
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
4250
|
+
import { Trash2 as Trash25, Pencil as Pencil4, Link, Search as Search3 } from "lucide-react";
|
|
4251
|
+
import { format as format3 } from "date-fns";
|
|
4252
|
+
import { ptBR as ptBR3 } from "date-fns/locale";
|
|
4253
|
+
import { toast as toast10 } from "sonner";
|
|
4254
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4255
|
+
function formatDate2(dateStr) {
|
|
4256
|
+
if (!dateStr) return "Sem expira\xE7\xE3o";
|
|
4257
|
+
return format3(new Date(dateStr), "dd/MM/yyyy", { locale: ptBR3 });
|
|
4258
|
+
}
|
|
4259
|
+
function useColumns3(tools, onEdit, onConnect, onRemove) {
|
|
4260
|
+
function getToolName(idTool) {
|
|
4261
|
+
if (!idTool) return "\u2014";
|
|
4262
|
+
const tool = tools.find((t) => t.id === idTool);
|
|
4263
|
+
return tool?.name || `Ferramenta #${idTool}`;
|
|
4264
|
+
}
|
|
4265
|
+
function getToolType(idTool) {
|
|
4266
|
+
if (!idTool) return null;
|
|
4267
|
+
const tool = tools.find((t) => t.id === idTool);
|
|
4268
|
+
return tool?.type || null;
|
|
4269
|
+
}
|
|
4270
|
+
return [
|
|
4271
|
+
{
|
|
4272
|
+
accessorKey: "label",
|
|
4273
|
+
header: "Label",
|
|
4274
|
+
cell: ({ row }) => /* @__PURE__ */ jsx20("span", { className: "font-medium", children: row.original.label || "\u2014" })
|
|
4275
|
+
},
|
|
4276
|
+
{
|
|
4277
|
+
accessorKey: "id_tool",
|
|
4278
|
+
header: "Ferramenta",
|
|
4279
|
+
cell: ({ row }) => /* @__PURE__ */ jsx20("span", { className: "text-sm", children: getToolName(row.original.id_tool) })
|
|
4280
|
+
},
|
|
4281
|
+
{
|
|
4282
|
+
accessorKey: "status",
|
|
4283
|
+
header: "Status",
|
|
4284
|
+
cell: ({ row }) => /* @__PURE__ */ jsx20(
|
|
4285
|
+
Badge9,
|
|
4286
|
+
{
|
|
4287
|
+
variant: row.original.status === "active" ? "default" : "destructive",
|
|
4288
|
+
children: row.original.status === "active" ? "Ativo" : "Expirado"
|
|
4289
|
+
}
|
|
4290
|
+
)
|
|
4291
|
+
},
|
|
4292
|
+
{
|
|
4293
|
+
accessorKey: "expires_at",
|
|
4294
|
+
header: "Expira em",
|
|
4295
|
+
cell: ({ row }) => /* @__PURE__ */ jsx20("span", { className: "text-muted-foreground text-sm", children: formatDate2(row.original.expires_at) })
|
|
4296
|
+
},
|
|
4297
|
+
{
|
|
4298
|
+
accessorKey: "datetime_add",
|
|
4299
|
+
header: "Criado em",
|
|
4300
|
+
cell: ({ row }) => /* @__PURE__ */ jsx20("span", { className: "text-muted-foreground text-sm", children: formatDate2(row.original.datetime_add) })
|
|
4301
|
+
},
|
|
4302
|
+
{
|
|
4303
|
+
id: "actions",
|
|
4304
|
+
header: "A\xE7\xF5es",
|
|
4305
|
+
size: 100,
|
|
4306
|
+
enableSorting: false,
|
|
4307
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-1", children: [
|
|
4308
|
+
getToolType(row.original.id_tool) === "oauth2" && /* @__PURE__ */ jsxs18(Tooltip4, { children: [
|
|
4309
|
+
/* @__PURE__ */ jsx20(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
4310
|
+
Button13,
|
|
4311
|
+
{
|
|
4312
|
+
variant: "ghost",
|
|
4313
|
+
size: "icon",
|
|
4314
|
+
className: "h-8 w-8",
|
|
4315
|
+
"aria-label": "Vincular",
|
|
4316
|
+
disabled: true,
|
|
4317
|
+
children: /* @__PURE__ */ jsx20(Link, { className: "h-4 w-4" })
|
|
4318
|
+
}
|
|
4319
|
+
) }),
|
|
4320
|
+
/* @__PURE__ */ jsx20(TooltipContent4, { children: "Em breve" })
|
|
4321
|
+
] }),
|
|
4322
|
+
/* @__PURE__ */ jsxs18(Tooltip4, { children: [
|
|
4323
|
+
/* @__PURE__ */ jsx20(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
4324
|
+
Button13,
|
|
4325
|
+
{
|
|
4326
|
+
variant: "ghost",
|
|
4327
|
+
size: "icon",
|
|
4328
|
+
className: "h-8 w-8",
|
|
4329
|
+
"aria-label": "Editar",
|
|
4330
|
+
onClick: () => onEdit(row.original),
|
|
4331
|
+
children: /* @__PURE__ */ jsx20(Pencil4, { className: "h-4 w-4" })
|
|
4332
|
+
}
|
|
4333
|
+
) }),
|
|
4334
|
+
/* @__PURE__ */ jsx20(TooltipContent4, { children: "Editar" })
|
|
4335
|
+
] }),
|
|
4336
|
+
/* @__PURE__ */ jsxs18(Tooltip4, { children: [
|
|
4337
|
+
/* @__PURE__ */ jsx20(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
4338
|
+
Button13,
|
|
4339
|
+
{
|
|
4340
|
+
variant: "ghost",
|
|
4341
|
+
size: "icon",
|
|
4342
|
+
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
4343
|
+
"aria-label": "Excluir",
|
|
4344
|
+
onClick: () => onRemove(row.original),
|
|
4345
|
+
children: /* @__PURE__ */ jsx20(Trash25, { className: "h-4 w-4" })
|
|
4346
|
+
}
|
|
4347
|
+
) }),
|
|
4348
|
+
/* @__PURE__ */ jsx20(TooltipContent4, { children: "Remover" })
|
|
4349
|
+
] })
|
|
4350
|
+
] })
|
|
4351
|
+
}
|
|
4352
|
+
];
|
|
4353
|
+
}
|
|
4354
|
+
function ToolCredentialsForm({
|
|
4355
|
+
credentials,
|
|
4356
|
+
isLoading,
|
|
4357
|
+
config,
|
|
4358
|
+
gagentsApiUrl,
|
|
4359
|
+
createOpen: externalCreateOpen,
|
|
4360
|
+
onCreateOpenChange
|
|
4361
|
+
}) {
|
|
4362
|
+
const createMutation = useCreateToolCredential(config);
|
|
4363
|
+
const updateMutation = useUpdateToolCredential(config);
|
|
4364
|
+
const deleteMutation = useDeleteToolCredential(config);
|
|
4365
|
+
const { data: toolsData } = useTools(config);
|
|
4366
|
+
const tools = toolsData?.data || [];
|
|
4367
|
+
const [search, setSearch] = useState12("");
|
|
4368
|
+
const [internalCreateOpen, setInternalCreateOpen] = useState12(false);
|
|
4369
|
+
const showCreateDialog = externalCreateOpen ?? internalCreateOpen;
|
|
4370
|
+
const setShowCreateDialog = onCreateOpenChange ?? setInternalCreateOpen;
|
|
4371
|
+
const [createForm, setCreateForm] = useState12({
|
|
4372
|
+
id_tool: "",
|
|
4373
|
+
label: "",
|
|
4374
|
+
credentials_encrypted: "",
|
|
4375
|
+
expires_at: ""
|
|
4376
|
+
});
|
|
4377
|
+
const [editTarget, setEditTarget] = useState12(null);
|
|
4378
|
+
const [editForm, setEditForm] = useState12({
|
|
4379
|
+
id_tool: "",
|
|
4380
|
+
label: "",
|
|
4381
|
+
credentials_encrypted: "",
|
|
4382
|
+
expires_at: "",
|
|
4383
|
+
status: ""
|
|
4384
|
+
});
|
|
4385
|
+
const [removeTarget, setRemoveTarget] = useState12(null);
|
|
4386
|
+
const filteredCredentials = useMemo7(() => {
|
|
4387
|
+
if (!search) return credentials;
|
|
4388
|
+
const term = search.toLowerCase();
|
|
4389
|
+
return credentials.filter((cred) => {
|
|
4390
|
+
const toolName = tools.find((t) => t.id === cred.id_tool)?.name || "";
|
|
4391
|
+
return (cred.label || "").toLowerCase().includes(term) || toolName.toLowerCase().includes(term);
|
|
4392
|
+
});
|
|
4393
|
+
}, [credentials, search, tools]);
|
|
4394
|
+
const columns = useColumns3(
|
|
4395
|
+
tools,
|
|
4396
|
+
(cred) => startEdit(cred),
|
|
4397
|
+
(cred) => handleConnect(cred),
|
|
4398
|
+
(cred) => setRemoveTarget(cred)
|
|
4399
|
+
);
|
|
4400
|
+
async function handleCreate() {
|
|
4401
|
+
const idTool = parseInt(createForm.id_tool, 10);
|
|
4402
|
+
if (!idTool || !createForm.label.trim() || !createForm.credentials_encrypted.trim()) return;
|
|
4403
|
+
try {
|
|
4404
|
+
const result = await createMutation.mutateAsync({
|
|
4405
|
+
id_tool: idTool,
|
|
4406
|
+
label: createForm.label.trim(),
|
|
4407
|
+
credentials_encrypted: createForm.credentials_encrypted.trim(),
|
|
4408
|
+
...createForm.expires_at ? { expires_at: createForm.expires_at } : {}
|
|
4409
|
+
});
|
|
4410
|
+
if (result.status === 1) {
|
|
4411
|
+
toast10.success("Credencial criada");
|
|
4412
|
+
setShowCreateDialog(false);
|
|
4413
|
+
setCreateForm({ id_tool: "", label: "", credentials_encrypted: "", expires_at: "" });
|
|
4414
|
+
} else {
|
|
4415
|
+
toast10.error(result.message || "Erro ao criar credencial");
|
|
4416
|
+
}
|
|
4417
|
+
} catch {
|
|
4418
|
+
toast10.error("Erro ao criar credencial");
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4421
|
+
function startEdit(cred) {
|
|
4422
|
+
setEditTarget(cred);
|
|
4423
|
+
setEditForm({
|
|
4424
|
+
id_tool: cred.id_tool ? String(cred.id_tool) : "",
|
|
4425
|
+
label: cred.label || "",
|
|
4426
|
+
credentials_encrypted: "",
|
|
4427
|
+
expires_at: cred.expires_at || "",
|
|
4428
|
+
status: cred.status
|
|
4429
|
+
});
|
|
4430
|
+
}
|
|
4431
|
+
async function handleSaveEdit() {
|
|
4432
|
+
if (!editTarget) return;
|
|
4433
|
+
const body = {};
|
|
4434
|
+
const newIdTool = editForm.id_tool ? parseInt(editForm.id_tool, 10) : null;
|
|
4435
|
+
if (newIdTool && newIdTool !== editTarget.id_tool) {
|
|
4436
|
+
body.id_tool = newIdTool;
|
|
4437
|
+
}
|
|
4438
|
+
if (editForm.label.trim() && editForm.label.trim() !== (editTarget.label || "")) {
|
|
4439
|
+
body.label = editForm.label.trim();
|
|
4440
|
+
}
|
|
4441
|
+
if (editForm.credentials_encrypted.trim()) {
|
|
4442
|
+
body.credentials_encrypted = editForm.credentials_encrypted.trim();
|
|
4443
|
+
}
|
|
4444
|
+
if (editForm.expires_at !== (editTarget.expires_at || "")) {
|
|
4445
|
+
body.expires_at = editForm.expires_at || null;
|
|
4446
|
+
}
|
|
4447
|
+
if (editForm.status && editForm.status !== editTarget.status) {
|
|
4448
|
+
body.status = editForm.status;
|
|
4449
|
+
}
|
|
4450
|
+
if (Object.keys(body).length === 0) {
|
|
4451
|
+
setEditTarget(null);
|
|
4452
|
+
return;
|
|
4453
|
+
}
|
|
4454
|
+
try {
|
|
4455
|
+
const result = await updateMutation.mutateAsync({
|
|
4456
|
+
id: editTarget.id,
|
|
4457
|
+
body
|
|
4458
|
+
});
|
|
4459
|
+
if (result.status === 1) {
|
|
4460
|
+
toast10.success("Credencial atualizada");
|
|
4461
|
+
setEditTarget(null);
|
|
4462
|
+
} else {
|
|
4463
|
+
toast10.error(result.message || "Erro ao atualizar credencial");
|
|
4464
|
+
}
|
|
4465
|
+
} catch {
|
|
4466
|
+
toast10.error("Erro ao atualizar credencial");
|
|
4467
|
+
}
|
|
4468
|
+
}
|
|
4469
|
+
async function handleRemove() {
|
|
4470
|
+
if (!removeTarget) return;
|
|
4471
|
+
try {
|
|
4472
|
+
const result = await deleteMutation.mutateAsync(removeTarget.id);
|
|
4473
|
+
if (result.status === 1) {
|
|
4474
|
+
toast10.success("Credencial removida");
|
|
4475
|
+
} else {
|
|
4476
|
+
toast10.error(result.message || "Erro ao remover credencial");
|
|
4477
|
+
}
|
|
4478
|
+
} catch {
|
|
4479
|
+
toast10.error("Erro ao remover credencial");
|
|
4480
|
+
} finally {
|
|
4481
|
+
setRemoveTarget(null);
|
|
4482
|
+
}
|
|
4483
|
+
}
|
|
4484
|
+
function handleConnect(cred) {
|
|
4485
|
+
if (!config.accountId || !config.token) return;
|
|
4486
|
+
const language = config.language ?? "pt-br";
|
|
4487
|
+
const idWl = config.idWl ?? 1;
|
|
4488
|
+
const url = `${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${config.accountId}/oauth/connect?id_tool=${cred.id_tool}`;
|
|
4489
|
+
window.open(url, "_blank");
|
|
4490
|
+
}
|
|
4491
|
+
return /* @__PURE__ */ jsxs18("div", { className: "space-y-4", children: [
|
|
4492
|
+
/* @__PURE__ */ jsx20("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs18("div", { className: "relative flex-1 max-w-md", children: [
|
|
4493
|
+
/* @__PURE__ */ jsx20(Search3, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
4494
|
+
/* @__PURE__ */ jsx20(
|
|
4495
|
+
Input9,
|
|
4496
|
+
{
|
|
4497
|
+
placeholder: "Buscar credenciais\\u2026",
|
|
4498
|
+
"aria-label": "Buscar credenciais",
|
|
4499
|
+
name: "search",
|
|
4500
|
+
autoComplete: "off",
|
|
4501
|
+
value: search,
|
|
4502
|
+
onChange: (e) => setSearch(e.target.value),
|
|
2829
4503
|
className: "pl-9"
|
|
2830
4504
|
}
|
|
2831
4505
|
)
|
|
2832
4506
|
] }) }),
|
|
2833
|
-
/* @__PURE__ */
|
|
2834
|
-
|
|
4507
|
+
/* @__PURE__ */ jsx20(
|
|
4508
|
+
DataTable3,
|
|
2835
4509
|
{
|
|
2836
4510
|
columns,
|
|
2837
|
-
data:
|
|
4511
|
+
data: filteredCredentials,
|
|
2838
4512
|
isLoading,
|
|
2839
|
-
emptyMessage: "Nenhuma
|
|
2840
|
-
total,
|
|
2841
|
-
page,
|
|
2842
|
-
onPageChange: setPage,
|
|
2843
|
-
pageSize: 15
|
|
4513
|
+
emptyMessage: "Nenhuma credencial encontrada"
|
|
2844
4514
|
}
|
|
2845
4515
|
),
|
|
2846
|
-
/* @__PURE__ */
|
|
2847
|
-
|
|
4516
|
+
/* @__PURE__ */ jsx20(Dialog6, { open: showCreateDialog, onOpenChange: setShowCreateDialog, children: /* @__PURE__ */ jsxs18(DialogContent6, { children: [
|
|
4517
|
+
/* @__PURE__ */ jsx20(DialogHeader6, { children: /* @__PURE__ */ jsx20(DialogTitle6, { children: "Nova Credencial" }) }),
|
|
4518
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-4", children: [
|
|
4519
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4520
|
+
/* @__PURE__ */ jsx20("label", { htmlFor: "cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
|
|
4521
|
+
/* @__PURE__ */ jsxs18(
|
|
4522
|
+
Select3,
|
|
4523
|
+
{
|
|
4524
|
+
value: createForm.id_tool,
|
|
4525
|
+
onValueChange: (val) => setCreateForm((f) => ({ ...f, id_tool: val })),
|
|
4526
|
+
children: [
|
|
4527
|
+
/* @__PURE__ */ jsx20(SelectTrigger3, { id: "cred-tool", children: /* @__PURE__ */ jsx20(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
|
|
4528
|
+
/* @__PURE__ */ jsx20(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx20(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
|
|
4529
|
+
]
|
|
4530
|
+
}
|
|
4531
|
+
)
|
|
4532
|
+
] }),
|
|
4533
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4534
|
+
/* @__PURE__ */ jsx20("label", { htmlFor: "cred-label", className: "mb-1 block text-sm font-medium", children: "Label *" }),
|
|
4535
|
+
/* @__PURE__ */ jsx20(
|
|
4536
|
+
Input9,
|
|
4537
|
+
{
|
|
4538
|
+
id: "cred-label",
|
|
4539
|
+
name: "label",
|
|
4540
|
+
value: createForm.label,
|
|
4541
|
+
onChange: (e) => setCreateForm((f) => ({ ...f, label: e.target.value })),
|
|
4542
|
+
placeholder: "Ex: Google Calendar - Cl\xEDnica S\xE3o Paulo"
|
|
4543
|
+
}
|
|
4544
|
+
)
|
|
4545
|
+
] }),
|
|
4546
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4547
|
+
/* @__PURE__ */ jsx20("label", { htmlFor: "cred-credential", className: "mb-1 block text-sm font-medium", children: "Credencial *" }),
|
|
4548
|
+
/* @__PURE__ */ jsx20(
|
|
4549
|
+
Input9,
|
|
4550
|
+
{
|
|
4551
|
+
id: "cred-credential",
|
|
4552
|
+
name: "credential",
|
|
4553
|
+
autoComplete: "off",
|
|
4554
|
+
type: "password",
|
|
4555
|
+
value: createForm.credentials_encrypted,
|
|
4556
|
+
onChange: (e) => setCreateForm((f) => ({
|
|
4557
|
+
...f,
|
|
4558
|
+
credentials_encrypted: e.target.value
|
|
4559
|
+
})),
|
|
4560
|
+
placeholder: "Credencial encriptada"
|
|
4561
|
+
}
|
|
4562
|
+
)
|
|
4563
|
+
] }),
|
|
4564
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4565
|
+
/* @__PURE__ */ jsx20("label", { htmlFor: "cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o (opcional)" }),
|
|
4566
|
+
/* @__PURE__ */ jsx20(
|
|
4567
|
+
Input9,
|
|
4568
|
+
{
|
|
4569
|
+
id: "cred-expires",
|
|
4570
|
+
name: "expires",
|
|
4571
|
+
type: "date",
|
|
4572
|
+
value: createForm.expires_at,
|
|
4573
|
+
onChange: (e) => setCreateForm((f) => ({ ...f, expires_at: e.target.value }))
|
|
4574
|
+
}
|
|
4575
|
+
)
|
|
4576
|
+
] })
|
|
4577
|
+
] }),
|
|
4578
|
+
/* @__PURE__ */ jsxs18(DialogFooter6, { children: [
|
|
4579
|
+
/* @__PURE__ */ jsx20(
|
|
4580
|
+
Button13,
|
|
4581
|
+
{
|
|
4582
|
+
variant: "outline",
|
|
4583
|
+
onClick: () => setShowCreateDialog(false),
|
|
4584
|
+
children: "Cancelar"
|
|
4585
|
+
}
|
|
4586
|
+
),
|
|
4587
|
+
/* @__PURE__ */ jsx20(
|
|
4588
|
+
Button13,
|
|
4589
|
+
{
|
|
4590
|
+
onClick: handleCreate,
|
|
4591
|
+
disabled: !createForm.id_tool || !createForm.label.trim() || !createForm.credentials_encrypted.trim() || createMutation.isPending,
|
|
4592
|
+
children: "Criar"
|
|
4593
|
+
}
|
|
4594
|
+
)
|
|
4595
|
+
] })
|
|
4596
|
+
] }) }),
|
|
4597
|
+
/* @__PURE__ */ jsx20(
|
|
4598
|
+
Dialog6,
|
|
4599
|
+
{
|
|
4600
|
+
open: !!editTarget,
|
|
4601
|
+
onOpenChange: (open) => !open && setEditTarget(null),
|
|
4602
|
+
children: /* @__PURE__ */ jsxs18(DialogContent6, { children: [
|
|
4603
|
+
/* @__PURE__ */ jsx20(DialogHeader6, { children: /* @__PURE__ */ jsx20(DialogTitle6, { children: "Editar Credencial" }) }),
|
|
4604
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-4", children: [
|
|
4605
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4606
|
+
/* @__PURE__ */ jsx20("label", { htmlFor: "edit-cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
|
|
4607
|
+
/* @__PURE__ */ jsxs18(
|
|
4608
|
+
Select3,
|
|
4609
|
+
{
|
|
4610
|
+
value: editForm.id_tool,
|
|
4611
|
+
onValueChange: (val) => setEditForm((f) => ({ ...f, id_tool: val })),
|
|
4612
|
+
children: [
|
|
4613
|
+
/* @__PURE__ */ jsx20(SelectTrigger3, { id: "edit-cred-tool", children: /* @__PURE__ */ jsx20(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
|
|
4614
|
+
/* @__PURE__ */ jsx20(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx20(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
|
|
4615
|
+
]
|
|
4616
|
+
}
|
|
4617
|
+
)
|
|
4618
|
+
] }),
|
|
4619
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4620
|
+
/* @__PURE__ */ jsx20("label", { htmlFor: "edit-cred-label", className: "mb-1 block text-sm font-medium", children: "Label" }),
|
|
4621
|
+
/* @__PURE__ */ jsx20(
|
|
4622
|
+
Input9,
|
|
4623
|
+
{
|
|
4624
|
+
id: "edit-cred-label",
|
|
4625
|
+
name: "label",
|
|
4626
|
+
value: editForm.label,
|
|
4627
|
+
onChange: (e) => setEditForm((f) => ({ ...f, label: e.target.value })),
|
|
4628
|
+
placeholder: "Label da credencial"
|
|
4629
|
+
}
|
|
4630
|
+
)
|
|
4631
|
+
] }),
|
|
4632
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4633
|
+
/* @__PURE__ */ jsx20("label", { htmlFor: "edit-cred-credential", className: "mb-1 block text-sm font-medium", children: "Nova Credencial (vazio = manter atual)" }),
|
|
4634
|
+
/* @__PURE__ */ jsx20(
|
|
4635
|
+
Input9,
|
|
4636
|
+
{
|
|
4637
|
+
id: "edit-cred-credential",
|
|
4638
|
+
name: "credential",
|
|
4639
|
+
autoComplete: "off",
|
|
4640
|
+
type: "password",
|
|
4641
|
+
value: editForm.credentials_encrypted,
|
|
4642
|
+
onChange: (e) => setEditForm((f) => ({
|
|
4643
|
+
...f,
|
|
4644
|
+
credentials_encrypted: e.target.value
|
|
4645
|
+
})),
|
|
4646
|
+
placeholder: "Nova credencial"
|
|
4647
|
+
}
|
|
4648
|
+
)
|
|
4649
|
+
] }),
|
|
4650
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4651
|
+
/* @__PURE__ */ jsx20("label", { htmlFor: "edit-cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o" }),
|
|
4652
|
+
/* @__PURE__ */ jsx20(
|
|
4653
|
+
Input9,
|
|
4654
|
+
{
|
|
4655
|
+
id: "edit-cred-expires",
|
|
4656
|
+
name: "expires",
|
|
4657
|
+
type: "date",
|
|
4658
|
+
value: editForm.expires_at,
|
|
4659
|
+
onChange: (e) => setEditForm((f) => ({ ...f, expires_at: e.target.value }))
|
|
4660
|
+
}
|
|
4661
|
+
)
|
|
4662
|
+
] }),
|
|
4663
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4664
|
+
/* @__PURE__ */ jsx20("label", { htmlFor: "edit-cred-status", className: "mb-1 block text-sm font-medium", children: "Status" }),
|
|
4665
|
+
/* @__PURE__ */ jsxs18(
|
|
4666
|
+
Select3,
|
|
4667
|
+
{
|
|
4668
|
+
value: editForm.status || void 0,
|
|
4669
|
+
onValueChange: (val) => setEditForm((f) => ({
|
|
4670
|
+
...f,
|
|
4671
|
+
status: val
|
|
4672
|
+
})),
|
|
4673
|
+
children: [
|
|
4674
|
+
/* @__PURE__ */ jsx20(SelectTrigger3, { id: "edit-cred-status", children: /* @__PURE__ */ jsx20(SelectValue3, {}) }),
|
|
4675
|
+
/* @__PURE__ */ jsxs18(SelectContent3, { children: [
|
|
4676
|
+
/* @__PURE__ */ jsx20(SelectItem3, { value: "active", children: "Ativo" }),
|
|
4677
|
+
/* @__PURE__ */ jsx20(SelectItem3, { value: "expired", children: "Expirado" })
|
|
4678
|
+
] })
|
|
4679
|
+
]
|
|
4680
|
+
}
|
|
4681
|
+
)
|
|
4682
|
+
] })
|
|
4683
|
+
] }),
|
|
4684
|
+
/* @__PURE__ */ jsxs18(DialogFooter6, { children: [
|
|
4685
|
+
/* @__PURE__ */ jsx20(Button13, { variant: "outline", onClick: () => setEditTarget(null), children: "Cancelar" }),
|
|
4686
|
+
/* @__PURE__ */ jsx20(
|
|
4687
|
+
Button13,
|
|
4688
|
+
{
|
|
4689
|
+
onClick: handleSaveEdit,
|
|
4690
|
+
disabled: updateMutation.isPending,
|
|
4691
|
+
children: "Salvar"
|
|
4692
|
+
}
|
|
4693
|
+
)
|
|
4694
|
+
] })
|
|
4695
|
+
] })
|
|
4696
|
+
}
|
|
4697
|
+
),
|
|
4698
|
+
/* @__PURE__ */ jsx20(
|
|
4699
|
+
AlertDialog5,
|
|
2848
4700
|
{
|
|
2849
|
-
open: !!
|
|
2850
|
-
onOpenChange: (open) => !open &&
|
|
2851
|
-
children: /* @__PURE__ */
|
|
2852
|
-
/* @__PURE__ */
|
|
2853
|
-
/* @__PURE__ */
|
|
2854
|
-
/* @__PURE__ */
|
|
4701
|
+
open: !!removeTarget,
|
|
4702
|
+
onOpenChange: (open) => !open && setRemoveTarget(null),
|
|
4703
|
+
children: /* @__PURE__ */ jsxs18(AlertDialogContent5, { children: [
|
|
4704
|
+
/* @__PURE__ */ jsxs18(AlertDialogHeader5, { children: [
|
|
4705
|
+
/* @__PURE__ */ jsx20(AlertDialogTitle5, { children: "Remover credencial?" }),
|
|
4706
|
+
/* @__PURE__ */ jsx20(AlertDialogDescription5, { children: "A credencial ser\xE1 removida permanentemente." })
|
|
2855
4707
|
] }),
|
|
2856
|
-
/* @__PURE__ */
|
|
2857
|
-
/* @__PURE__ */
|
|
2858
|
-
/* @__PURE__ */
|
|
2859
|
-
|
|
4708
|
+
/* @__PURE__ */ jsxs18(AlertDialogFooter5, { children: [
|
|
4709
|
+
/* @__PURE__ */ jsx20(AlertDialogCancel5, { children: "Cancelar" }),
|
|
4710
|
+
/* @__PURE__ */ jsx20(
|
|
4711
|
+
AlertDialogAction5,
|
|
2860
4712
|
{
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
2865
|
-
children: "Excluir"
|
|
4713
|
+
onClick: handleRemove,
|
|
4714
|
+
disabled: deleteMutation.isPending,
|
|
4715
|
+
children: "Remover"
|
|
2866
4716
|
}
|
|
2867
4717
|
)
|
|
2868
4718
|
] })
|
|
@@ -2873,26 +4723,26 @@ function ToolsTable({ onEdit, config }) {
|
|
|
2873
4723
|
}
|
|
2874
4724
|
|
|
2875
4725
|
// src/components/tools/tool-form-dialog.tsx
|
|
2876
|
-
import { useState as
|
|
4726
|
+
import { useState as useState13 } from "react";
|
|
2877
4727
|
import {
|
|
2878
|
-
Dialog as
|
|
2879
|
-
DialogContent as
|
|
2880
|
-
DialogHeader as
|
|
2881
|
-
DialogTitle as
|
|
2882
|
-
DialogFooter as
|
|
2883
|
-
Button as
|
|
2884
|
-
Input as
|
|
4728
|
+
Dialog as Dialog7,
|
|
4729
|
+
DialogContent as DialogContent7,
|
|
4730
|
+
DialogHeader as DialogHeader7,
|
|
4731
|
+
DialogTitle as DialogTitle7,
|
|
4732
|
+
DialogFooter as DialogFooter7,
|
|
4733
|
+
Button as Button14,
|
|
4734
|
+
Input as Input10,
|
|
2885
4735
|
Textarea as Textarea3,
|
|
2886
|
-
Label as
|
|
2887
|
-
Select as
|
|
2888
|
-
SelectContent as
|
|
2889
|
-
SelectItem as
|
|
2890
|
-
SelectTrigger as
|
|
2891
|
-
SelectValue as
|
|
4736
|
+
Label as Label8,
|
|
4737
|
+
Select as Select4,
|
|
4738
|
+
SelectContent as SelectContent4,
|
|
4739
|
+
SelectItem as SelectItem4,
|
|
4740
|
+
SelectTrigger as SelectTrigger4,
|
|
4741
|
+
SelectValue as SelectValue4
|
|
2892
4742
|
} from "@greatapps/greatauth-ui/ui";
|
|
2893
|
-
import { Loader2 as
|
|
2894
|
-
import { toast as
|
|
2895
|
-
import { jsx as
|
|
4743
|
+
import { Loader2 as Loader28 } from "lucide-react";
|
|
4744
|
+
import { toast as toast11 } from "sonner";
|
|
4745
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2896
4746
|
var TOOL_AUTH_TYPES = [
|
|
2897
4747
|
{ value: "none", label: "Nenhuma" },
|
|
2898
4748
|
{ value: "api_key", label: "API Key" },
|
|
@@ -2939,9 +4789,9 @@ function ToolFormDialog({
|
|
|
2939
4789
|
const isEditing = !!tool;
|
|
2940
4790
|
const createTool = useCreateTool(config);
|
|
2941
4791
|
const updateTool = useUpdateTool(config);
|
|
2942
|
-
const [form, setForm] =
|
|
2943
|
-
const [slugManuallyEdited, setSlugManuallyEdited] =
|
|
2944
|
-
const [lastResetKey, setLastResetKey] =
|
|
4792
|
+
const [form, setForm] = useState13(() => toolToFormState(tool));
|
|
4793
|
+
const [slugManuallyEdited, setSlugManuallyEdited] = useState13(false);
|
|
4794
|
+
const [lastResetKey, setLastResetKey] = useState13(
|
|
2945
4795
|
() => `${tool?.id}-${open}`
|
|
2946
4796
|
);
|
|
2947
4797
|
const resetKey = `${tool?.id}-${open}`;
|
|
@@ -2988,27 +4838,27 @@ function ToolFormDialog({
|
|
|
2988
4838
|
try {
|
|
2989
4839
|
if (isEditing) {
|
|
2990
4840
|
await updateTool.mutateAsync({ id: tool.id, body });
|
|
2991
|
-
|
|
4841
|
+
toast11.success("Ferramenta atualizada");
|
|
2992
4842
|
} else {
|
|
2993
4843
|
await createTool.mutateAsync(
|
|
2994
4844
|
body
|
|
2995
4845
|
);
|
|
2996
|
-
|
|
4846
|
+
toast11.success("Ferramenta criada");
|
|
2997
4847
|
}
|
|
2998
4848
|
onOpenChange(false);
|
|
2999
4849
|
} catch (err) {
|
|
3000
|
-
|
|
4850
|
+
toast11.error(
|
|
3001
4851
|
err instanceof Error ? err.message : isEditing ? "Erro ao atualizar ferramenta" : "Erro ao criar ferramenta"
|
|
3002
4852
|
);
|
|
3003
4853
|
}
|
|
3004
4854
|
}
|
|
3005
|
-
return /* @__PURE__ */
|
|
3006
|
-
/* @__PURE__ */
|
|
3007
|
-
/* @__PURE__ */
|
|
3008
|
-
/* @__PURE__ */
|
|
3009
|
-
/* @__PURE__ */
|
|
3010
|
-
/* @__PURE__ */
|
|
3011
|
-
|
|
4855
|
+
return /* @__PURE__ */ jsx21(Dialog7, { open, onOpenChange, children: /* @__PURE__ */ jsxs19(DialogContent7, { className: "sm:max-w-lg", children: [
|
|
4856
|
+
/* @__PURE__ */ jsx21(DialogHeader7, { children: /* @__PURE__ */ jsx21(DialogTitle7, { children: isEditing ? "Editar Ferramenta" : "Nova Ferramenta" }) }),
|
|
4857
|
+
/* @__PURE__ */ jsxs19("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
4858
|
+
/* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4859
|
+
/* @__PURE__ */ jsx21(Label8, { htmlFor: "tool-name", children: "Nome *" }),
|
|
4860
|
+
/* @__PURE__ */ jsx21(
|
|
4861
|
+
Input10,
|
|
3012
4862
|
{
|
|
3013
4863
|
id: "tool-name",
|
|
3014
4864
|
name: "name",
|
|
@@ -3026,12 +4876,12 @@ function ToolFormDialog({
|
|
|
3026
4876
|
disabled: isPending
|
|
3027
4877
|
}
|
|
3028
4878
|
),
|
|
3029
|
-
form.nameError && /* @__PURE__ */
|
|
4879
|
+
form.nameError && /* @__PURE__ */ jsx21("p", { className: "text-sm text-destructive", children: "Nome \xE9 obrigat\xF3rio" })
|
|
3030
4880
|
] }),
|
|
3031
|
-
/* @__PURE__ */
|
|
3032
|
-
/* @__PURE__ */
|
|
3033
|
-
/* @__PURE__ */
|
|
3034
|
-
|
|
4881
|
+
/* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4882
|
+
/* @__PURE__ */ jsx21(Label8, { htmlFor: "tool-slug", children: "Slug (identificador \xFAnico) *" }),
|
|
4883
|
+
/* @__PURE__ */ jsx21(
|
|
4884
|
+
Input10,
|
|
3035
4885
|
{
|
|
3036
4886
|
id: "tool-slug",
|
|
3037
4887
|
name: "slug",
|
|
@@ -3048,13 +4898,13 @@ function ToolFormDialog({
|
|
|
3048
4898
|
disabled: isPending
|
|
3049
4899
|
}
|
|
3050
4900
|
),
|
|
3051
|
-
/* @__PURE__ */
|
|
3052
|
-
form.slugError && /* @__PURE__ */
|
|
4901
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: "Gerado automaticamente a partir do nome. Usado internamente para identificar a ferramenta." }),
|
|
4902
|
+
form.slugError && /* @__PURE__ */ jsx21("p", { className: "text-sm text-destructive", children: "Slug \xE9 obrigat\xF3rio" })
|
|
3053
4903
|
] }),
|
|
3054
|
-
/* @__PURE__ */
|
|
3055
|
-
/* @__PURE__ */
|
|
3056
|
-
/* @__PURE__ */
|
|
3057
|
-
|
|
4904
|
+
/* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4905
|
+
/* @__PURE__ */ jsx21(Label8, { htmlFor: "tool-type", children: "Tipo de Autentica\xE7\xE3o *" }),
|
|
4906
|
+
/* @__PURE__ */ jsxs19(
|
|
4907
|
+
Select4,
|
|
3058
4908
|
{
|
|
3059
4909
|
value: form.type,
|
|
3060
4910
|
onValueChange: (value) => {
|
|
@@ -3066,17 +4916,17 @@ function ToolFormDialog({
|
|
|
3066
4916
|
},
|
|
3067
4917
|
disabled: isPending,
|
|
3068
4918
|
children: [
|
|
3069
|
-
/* @__PURE__ */
|
|
3070
|
-
/* @__PURE__ */
|
|
4919
|
+
/* @__PURE__ */ jsx21(SelectTrigger4, { id: "tool-type", children: /* @__PURE__ */ jsx21(SelectValue4, { placeholder: "Selecione o tipo" }) }),
|
|
4920
|
+
/* @__PURE__ */ jsx21(SelectContent4, { children: TOOL_AUTH_TYPES.map((t) => /* @__PURE__ */ jsx21(SelectItem4, { value: t.value, children: t.label }, t.value)) })
|
|
3071
4921
|
]
|
|
3072
4922
|
}
|
|
3073
4923
|
),
|
|
3074
|
-
/* @__PURE__ */
|
|
3075
|
-
form.typeError && /* @__PURE__ */
|
|
4924
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: "Define se a ferramenta requer credenciais para funcionar." }),
|
|
4925
|
+
form.typeError && /* @__PURE__ */ jsx21("p", { className: "text-sm text-destructive", children: "Tipo \xE9 obrigat\xF3rio" })
|
|
3076
4926
|
] }),
|
|
3077
|
-
/* @__PURE__ */
|
|
3078
|
-
/* @__PURE__ */
|
|
3079
|
-
/* @__PURE__ */
|
|
4927
|
+
/* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4928
|
+
/* @__PURE__ */ jsx21(Label8, { htmlFor: "tool-description", children: "Descri\xE7\xE3o" }),
|
|
4929
|
+
/* @__PURE__ */ jsx21(
|
|
3080
4930
|
Textarea3,
|
|
3081
4931
|
{
|
|
3082
4932
|
id: "tool-description",
|
|
@@ -3089,9 +4939,9 @@ function ToolFormDialog({
|
|
|
3089
4939
|
}
|
|
3090
4940
|
)
|
|
3091
4941
|
] }),
|
|
3092
|
-
/* @__PURE__ */
|
|
3093
|
-
/* @__PURE__ */
|
|
3094
|
-
/* @__PURE__ */
|
|
4942
|
+
/* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4943
|
+
/* @__PURE__ */ jsx21(Label8, { htmlFor: "tool-function-defs", children: "Defini\xE7\xF5es de Fun\xE7\xE3o (JSON)" }),
|
|
4944
|
+
/* @__PURE__ */ jsx21(
|
|
3095
4945
|
Textarea3,
|
|
3096
4946
|
{
|
|
3097
4947
|
id: "tool-function-defs",
|
|
@@ -3123,12 +4973,12 @@ function ToolFormDialog({
|
|
|
3123
4973
|
disabled: isPending
|
|
3124
4974
|
}
|
|
3125
4975
|
),
|
|
3126
|
-
/* @__PURE__ */
|
|
3127
|
-
form.jsonError && /* @__PURE__ */
|
|
4976
|
+
/* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: "Array de defini\xE7\xF5es no formato OpenAI Function Calling." }),
|
|
4977
|
+
form.jsonError && /* @__PURE__ */ jsx21("p", { className: "text-sm text-destructive", children: "JSON inv\xE1lido" })
|
|
3128
4978
|
] }),
|
|
3129
|
-
/* @__PURE__ */
|
|
3130
|
-
/* @__PURE__ */
|
|
3131
|
-
|
|
4979
|
+
/* @__PURE__ */ jsxs19(DialogFooter7, { children: [
|
|
4980
|
+
/* @__PURE__ */ jsx21(
|
|
4981
|
+
Button14,
|
|
3132
4982
|
{
|
|
3133
4983
|
type: "button",
|
|
3134
4984
|
variant: "outline",
|
|
@@ -3137,8 +4987,8 @@ function ToolFormDialog({
|
|
|
3137
4987
|
children: "Cancelar"
|
|
3138
4988
|
}
|
|
3139
4989
|
),
|
|
3140
|
-
/* @__PURE__ */
|
|
3141
|
-
isPending ? /* @__PURE__ */
|
|
4990
|
+
/* @__PURE__ */ jsxs19(Button14, { type: "submit", disabled: isPending, children: [
|
|
4991
|
+
isPending ? /* @__PURE__ */ jsx21(Loader28, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
3142
4992
|
isEditing ? "Salvar" : "Criar"
|
|
3143
4993
|
] })
|
|
3144
4994
|
] })
|
|
@@ -3146,535 +4996,247 @@ function ToolFormDialog({
|
|
|
3146
4996
|
] }) });
|
|
3147
4997
|
}
|
|
3148
4998
|
|
|
3149
|
-
// src/components/
|
|
3150
|
-
import {
|
|
3151
|
-
import {
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
DialogContent as DialogContent6,
|
|
3161
|
-
DialogHeader as DialogHeader6,
|
|
3162
|
-
DialogTitle as DialogTitle6,
|
|
3163
|
-
DialogFooter as DialogFooter6,
|
|
3164
|
-
AlertDialog as AlertDialog5,
|
|
3165
|
-
AlertDialogAction as AlertDialogAction5,
|
|
3166
|
-
AlertDialogCancel as AlertDialogCancel5,
|
|
3167
|
-
AlertDialogContent as AlertDialogContent5,
|
|
3168
|
-
AlertDialogDescription as AlertDialogDescription5,
|
|
3169
|
-
AlertDialogFooter as AlertDialogFooter5,
|
|
3170
|
-
AlertDialogHeader as AlertDialogHeader5,
|
|
3171
|
-
AlertDialogTitle as AlertDialogTitle5,
|
|
3172
|
-
Select as Select3,
|
|
3173
|
-
SelectContent as SelectContent3,
|
|
3174
|
-
SelectItem as SelectItem3,
|
|
3175
|
-
SelectTrigger as SelectTrigger3,
|
|
3176
|
-
SelectValue as SelectValue3
|
|
3177
|
-
} from "@greatapps/greatauth-ui/ui";
|
|
3178
|
-
import { Trash2 as Trash25, Pencil as Pencil4, Link, Search as Search3 } from "lucide-react";
|
|
3179
|
-
import { format as format3 } from "date-fns";
|
|
3180
|
-
import { ptBR as ptBR3 } from "date-fns/locale";
|
|
3181
|
-
import { toast as toast9 } from "sonner";
|
|
3182
|
-
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3183
|
-
function formatDate2(dateStr) {
|
|
3184
|
-
if (!dateStr) return "Sem expira\xE7\xE3o";
|
|
3185
|
-
return format3(new Date(dateStr), "dd/MM/yyyy", { locale: ptBR3 });
|
|
3186
|
-
}
|
|
3187
|
-
function useColumns3(tools, onEdit, onConnect, onRemove) {
|
|
3188
|
-
function getToolName(idTool) {
|
|
3189
|
-
if (!idTool) return "\u2014";
|
|
3190
|
-
const tool = tools.find((t) => t.id === idTool);
|
|
3191
|
-
return tool?.name || `Ferramenta #${idTool}`;
|
|
3192
|
-
}
|
|
3193
|
-
function getToolType(idTool) {
|
|
3194
|
-
if (!idTool) return null;
|
|
3195
|
-
const tool = tools.find((t) => t.id === idTool);
|
|
3196
|
-
return tool?.type || null;
|
|
3197
|
-
}
|
|
3198
|
-
return [
|
|
3199
|
-
{
|
|
3200
|
-
accessorKey: "label",
|
|
3201
|
-
header: "Label",
|
|
3202
|
-
cell: ({ row }) => /* @__PURE__ */ jsx14("span", { className: "font-medium", children: row.original.label || "\u2014" })
|
|
3203
|
-
},
|
|
3204
|
-
{
|
|
3205
|
-
accessorKey: "id_tool",
|
|
3206
|
-
header: "Ferramenta",
|
|
3207
|
-
cell: ({ row }) => /* @__PURE__ */ jsx14("span", { className: "text-sm", children: getToolName(row.original.id_tool) })
|
|
3208
|
-
},
|
|
3209
|
-
{
|
|
3210
|
-
accessorKey: "status",
|
|
3211
|
-
header: "Status",
|
|
3212
|
-
cell: ({ row }) => /* @__PURE__ */ jsx14(
|
|
3213
|
-
Badge7,
|
|
3214
|
-
{
|
|
3215
|
-
variant: row.original.status === "active" ? "default" : "destructive",
|
|
3216
|
-
children: row.original.status === "active" ? "Ativo" : "Expirado"
|
|
3217
|
-
}
|
|
3218
|
-
)
|
|
3219
|
-
},
|
|
3220
|
-
{
|
|
3221
|
-
accessorKey: "expires_at",
|
|
3222
|
-
header: "Expira em",
|
|
3223
|
-
cell: ({ row }) => /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground text-sm", children: formatDate2(row.original.expires_at) })
|
|
3224
|
-
},
|
|
3225
|
-
{
|
|
3226
|
-
accessorKey: "datetime_add",
|
|
3227
|
-
header: "Criado em",
|
|
3228
|
-
cell: ({ row }) => /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground text-sm", children: formatDate2(row.original.datetime_add) })
|
|
3229
|
-
},
|
|
3230
|
-
{
|
|
3231
|
-
id: "actions",
|
|
3232
|
-
header: "A\xE7\xF5es",
|
|
3233
|
-
size: 100,
|
|
3234
|
-
enableSorting: false,
|
|
3235
|
-
cell: ({ row }) => /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1", children: [
|
|
3236
|
-
getToolType(row.original.id_tool) === "oauth2" && /* @__PURE__ */ jsxs12(Tooltip3, { children: [
|
|
3237
|
-
/* @__PURE__ */ jsx14(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx14(
|
|
3238
|
-
Button10,
|
|
3239
|
-
{
|
|
3240
|
-
variant: "ghost",
|
|
3241
|
-
size: "icon",
|
|
3242
|
-
className: "h-8 w-8",
|
|
3243
|
-
"aria-label": "Vincular",
|
|
3244
|
-
disabled: true,
|
|
3245
|
-
children: /* @__PURE__ */ jsx14(Link, { className: "h-4 w-4" })
|
|
3246
|
-
}
|
|
3247
|
-
) }),
|
|
3248
|
-
/* @__PURE__ */ jsx14(TooltipContent3, { children: "Em breve" })
|
|
3249
|
-
] }),
|
|
3250
|
-
/* @__PURE__ */ jsxs12(Tooltip3, { children: [
|
|
3251
|
-
/* @__PURE__ */ jsx14(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx14(
|
|
3252
|
-
Button10,
|
|
3253
|
-
{
|
|
3254
|
-
variant: "ghost",
|
|
3255
|
-
size: "icon",
|
|
3256
|
-
className: "h-8 w-8",
|
|
3257
|
-
"aria-label": "Editar",
|
|
3258
|
-
onClick: () => onEdit(row.original),
|
|
3259
|
-
children: /* @__PURE__ */ jsx14(Pencil4, { className: "h-4 w-4" })
|
|
3260
|
-
}
|
|
3261
|
-
) }),
|
|
3262
|
-
/* @__PURE__ */ jsx14(TooltipContent3, { children: "Editar" })
|
|
3263
|
-
] }),
|
|
3264
|
-
/* @__PURE__ */ jsxs12(Tooltip3, { children: [
|
|
3265
|
-
/* @__PURE__ */ jsx14(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx14(
|
|
3266
|
-
Button10,
|
|
3267
|
-
{
|
|
3268
|
-
variant: "ghost",
|
|
3269
|
-
size: "icon",
|
|
3270
|
-
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
3271
|
-
"aria-label": "Excluir",
|
|
3272
|
-
onClick: () => onRemove(row.original),
|
|
3273
|
-
children: /* @__PURE__ */ jsx14(Trash25, { className: "h-4 w-4" })
|
|
3274
|
-
}
|
|
3275
|
-
) }),
|
|
3276
|
-
/* @__PURE__ */ jsx14(TooltipContent3, { children: "Remover" })
|
|
3277
|
-
] })
|
|
3278
|
-
] })
|
|
3279
|
-
}
|
|
3280
|
-
];
|
|
3281
|
-
}
|
|
3282
|
-
function ToolCredentialsForm({
|
|
3283
|
-
credentials,
|
|
3284
|
-
isLoading,
|
|
3285
|
-
config,
|
|
3286
|
-
gagentsApiUrl,
|
|
3287
|
-
createOpen: externalCreateOpen,
|
|
3288
|
-
onCreateOpenChange
|
|
3289
|
-
}) {
|
|
3290
|
-
const createMutation = useCreateToolCredential(config);
|
|
3291
|
-
const updateMutation = useUpdateToolCredential(config);
|
|
3292
|
-
const deleteMutation = useDeleteToolCredential(config);
|
|
3293
|
-
const { data: toolsData } = useTools(config);
|
|
3294
|
-
const tools = toolsData?.data || [];
|
|
3295
|
-
const [search, setSearch] = useState11("");
|
|
3296
|
-
const [internalCreateOpen, setInternalCreateOpen] = useState11(false);
|
|
3297
|
-
const showCreateDialog = externalCreateOpen ?? internalCreateOpen;
|
|
3298
|
-
const setShowCreateDialog = onCreateOpenChange ?? setInternalCreateOpen;
|
|
3299
|
-
const [createForm, setCreateForm] = useState11({
|
|
3300
|
-
id_tool: "",
|
|
3301
|
-
label: "",
|
|
3302
|
-
credentials_encrypted: "",
|
|
3303
|
-
expires_at: ""
|
|
3304
|
-
});
|
|
3305
|
-
const [editTarget, setEditTarget] = useState11(null);
|
|
3306
|
-
const [editForm, setEditForm] = useState11({
|
|
3307
|
-
id_tool: "",
|
|
3308
|
-
label: "",
|
|
3309
|
-
credentials_encrypted: "",
|
|
3310
|
-
expires_at: "",
|
|
3311
|
-
status: ""
|
|
3312
|
-
});
|
|
3313
|
-
const [removeTarget, setRemoveTarget] = useState11(null);
|
|
3314
|
-
const filteredCredentials = useMemo5(() => {
|
|
3315
|
-
if (!search) return credentials;
|
|
3316
|
-
const term = search.toLowerCase();
|
|
3317
|
-
return credentials.filter((cred) => {
|
|
3318
|
-
const toolName = tools.find((t) => t.id === cred.id_tool)?.name || "";
|
|
3319
|
-
return (cred.label || "").toLowerCase().includes(term) || toolName.toLowerCase().includes(term);
|
|
3320
|
-
});
|
|
3321
|
-
}, [credentials, search, tools]);
|
|
3322
|
-
const columns = useColumns3(
|
|
3323
|
-
tools,
|
|
3324
|
-
(cred) => startEdit(cred),
|
|
3325
|
-
(cred) => handleConnect(cred),
|
|
3326
|
-
(cred) => setRemoveTarget(cred)
|
|
3327
|
-
);
|
|
3328
|
-
async function handleCreate() {
|
|
3329
|
-
const idTool = parseInt(createForm.id_tool, 10);
|
|
3330
|
-
if (!idTool || !createForm.label.trim() || !createForm.credentials_encrypted.trim()) return;
|
|
3331
|
-
try {
|
|
3332
|
-
const result = await createMutation.mutateAsync({
|
|
3333
|
-
id_tool: idTool,
|
|
3334
|
-
label: createForm.label.trim(),
|
|
3335
|
-
credentials_encrypted: createForm.credentials_encrypted.trim(),
|
|
3336
|
-
...createForm.expires_at ? { expires_at: createForm.expires_at } : {}
|
|
3337
|
-
});
|
|
3338
|
-
if (result.status === 1) {
|
|
3339
|
-
toast9.success("Credencial criada");
|
|
3340
|
-
setShowCreateDialog(false);
|
|
3341
|
-
setCreateForm({ id_tool: "", label: "", credentials_encrypted: "", expires_at: "" });
|
|
3342
|
-
} else {
|
|
3343
|
-
toast9.error(result.message || "Erro ao criar credencial");
|
|
3344
|
-
}
|
|
3345
|
-
} catch {
|
|
3346
|
-
toast9.error("Erro ao criar credencial");
|
|
3347
|
-
}
|
|
3348
|
-
}
|
|
3349
|
-
function startEdit(cred) {
|
|
3350
|
-
setEditTarget(cred);
|
|
3351
|
-
setEditForm({
|
|
3352
|
-
id_tool: cred.id_tool ? String(cred.id_tool) : "",
|
|
3353
|
-
label: cred.label || "",
|
|
3354
|
-
credentials_encrypted: "",
|
|
3355
|
-
expires_at: cred.expires_at || "",
|
|
3356
|
-
status: cred.status
|
|
3357
|
-
});
|
|
3358
|
-
}
|
|
3359
|
-
async function handleSaveEdit() {
|
|
3360
|
-
if (!editTarget) return;
|
|
3361
|
-
const body = {};
|
|
3362
|
-
const newIdTool = editForm.id_tool ? parseInt(editForm.id_tool, 10) : null;
|
|
3363
|
-
if (newIdTool && newIdTool !== editTarget.id_tool) {
|
|
3364
|
-
body.id_tool = newIdTool;
|
|
3365
|
-
}
|
|
3366
|
-
if (editForm.label.trim() && editForm.label.trim() !== (editTarget.label || "")) {
|
|
3367
|
-
body.label = editForm.label.trim();
|
|
3368
|
-
}
|
|
3369
|
-
if (editForm.credentials_encrypted.trim()) {
|
|
3370
|
-
body.credentials_encrypted = editForm.credentials_encrypted.trim();
|
|
3371
|
-
}
|
|
3372
|
-
if (editForm.expires_at !== (editTarget.expires_at || "")) {
|
|
3373
|
-
body.expires_at = editForm.expires_at || null;
|
|
3374
|
-
}
|
|
3375
|
-
if (editForm.status && editForm.status !== editTarget.status) {
|
|
3376
|
-
body.status = editForm.status;
|
|
3377
|
-
}
|
|
3378
|
-
if (Object.keys(body).length === 0) {
|
|
3379
|
-
setEditTarget(null);
|
|
3380
|
-
return;
|
|
3381
|
-
}
|
|
3382
|
-
try {
|
|
3383
|
-
const result = await updateMutation.mutateAsync({
|
|
3384
|
-
id: editTarget.id,
|
|
3385
|
-
body
|
|
3386
|
-
});
|
|
3387
|
-
if (result.status === 1) {
|
|
3388
|
-
toast9.success("Credencial atualizada");
|
|
3389
|
-
setEditTarget(null);
|
|
3390
|
-
} else {
|
|
3391
|
-
toast9.error(result.message || "Erro ao atualizar credencial");
|
|
3392
|
-
}
|
|
3393
|
-
} catch {
|
|
3394
|
-
toast9.error("Erro ao atualizar credencial");
|
|
3395
|
-
}
|
|
3396
|
-
}
|
|
3397
|
-
async function handleRemove() {
|
|
3398
|
-
if (!removeTarget) return;
|
|
3399
|
-
try {
|
|
3400
|
-
const result = await deleteMutation.mutateAsync(removeTarget.id);
|
|
3401
|
-
if (result.status === 1) {
|
|
3402
|
-
toast9.success("Credencial removida");
|
|
3403
|
-
} else {
|
|
3404
|
-
toast9.error(result.message || "Erro ao remover credencial");
|
|
3405
|
-
}
|
|
3406
|
-
} catch {
|
|
3407
|
-
toast9.error("Erro ao remover credencial");
|
|
3408
|
-
} finally {
|
|
3409
|
-
setRemoveTarget(null);
|
|
3410
|
-
}
|
|
4999
|
+
// src/components/capabilities/advanced-tab.tsx
|
|
5000
|
+
import { Info as Info2 } from "lucide-react";
|
|
5001
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
5002
|
+
function AdvancedTab({ config, agentId, gagentsApiUrl }) {
|
|
5003
|
+
const { data: credentialsData, isLoading: isLoadingCredentials } = useToolCredentials(config);
|
|
5004
|
+
const credentials = credentialsData?.data ?? [];
|
|
5005
|
+
const [editingTool, setEditingTool] = useState14(null);
|
|
5006
|
+
const [showToolForm, setShowToolForm] = useState14(false);
|
|
5007
|
+
function handleEditTool(tool) {
|
|
5008
|
+
setEditingTool(tool);
|
|
5009
|
+
setShowToolForm(true);
|
|
3411
5010
|
}
|
|
3412
|
-
function
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
const idWl = config.idWl ?? 1;
|
|
3416
|
-
const url = `${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${config.accountId}/oauth/connect?id_tool=${cred.id_tool}`;
|
|
3417
|
-
window.open(url, "_blank");
|
|
5011
|
+
function handleToolFormOpenChange(open) {
|
|
5012
|
+
setShowToolForm(open);
|
|
5013
|
+
if (!open) setEditingTool(null);
|
|
3418
5014
|
}
|
|
3419
|
-
return /* @__PURE__ */
|
|
3420
|
-
/* @__PURE__ */
|
|
3421
|
-
/* @__PURE__ */
|
|
3422
|
-
/* @__PURE__ */
|
|
3423
|
-
|
|
5015
|
+
return /* @__PURE__ */ jsxs20("div", { className: "space-y-8", children: [
|
|
5016
|
+
/* @__PURE__ */ jsxs20("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: [
|
|
5017
|
+
/* @__PURE__ */ jsx22(Info2, { className: "mt-0.5 h-4 w-4 shrink-0 text-blue-600 dark:text-blue-400" }),
|
|
5018
|
+
/* @__PURE__ */ jsxs20("p", { className: "text-sm text-blue-800 dark:text-blue-300", children: [
|
|
5019
|
+
"Use as abas ",
|
|
5020
|
+
/* @__PURE__ */ jsx22("strong", { children: "Capacidades" }),
|
|
5021
|
+
" e ",
|
|
5022
|
+
/* @__PURE__ */ jsx22("strong", { children: "Integra\xE7\xF5es" }),
|
|
5023
|
+
" para configura\xE7\xE3o simplificada. Esta aba oferece controlo manual avan\xE7ado sobre ferramentas e credenciais."
|
|
5024
|
+
] })
|
|
5025
|
+
] }),
|
|
5026
|
+
/* @__PURE__ */ jsxs20("section", { className: "space-y-3", children: [
|
|
5027
|
+
/* @__PURE__ */ jsx22("h3", { className: "text-sm font-medium", children: "Ferramentas" }),
|
|
5028
|
+
/* @__PURE__ */ jsx22(ToolsTable, { onEdit: handleEditTool, config })
|
|
5029
|
+
] }),
|
|
5030
|
+
/* @__PURE__ */ jsxs20("section", { className: "space-y-3", children: [
|
|
5031
|
+
/* @__PURE__ */ jsx22("h3", { className: "text-sm font-medium", children: "Credenciais" }),
|
|
5032
|
+
/* @__PURE__ */ jsx22(
|
|
5033
|
+
ToolCredentialsForm,
|
|
3424
5034
|
{
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
value: search,
|
|
3430
|
-
onChange: (e) => setSearch(e.target.value),
|
|
3431
|
-
className: "pl-9"
|
|
5035
|
+
credentials,
|
|
5036
|
+
isLoading: isLoadingCredentials,
|
|
5037
|
+
config,
|
|
5038
|
+
gagentsApiUrl
|
|
3432
5039
|
}
|
|
3433
5040
|
)
|
|
3434
|
-
] })
|
|
3435
|
-
/* @__PURE__ */
|
|
3436
|
-
|
|
5041
|
+
] }),
|
|
5042
|
+
/* @__PURE__ */ jsx22(
|
|
5043
|
+
ToolFormDialog,
|
|
3437
5044
|
{
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
5045
|
+
open: showToolForm,
|
|
5046
|
+
onOpenChange: handleToolFormOpenChange,
|
|
5047
|
+
tool: editingTool ?? void 0,
|
|
5048
|
+
config
|
|
3442
5049
|
}
|
|
3443
|
-
)
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
5050
|
+
)
|
|
5051
|
+
] });
|
|
5052
|
+
}
|
|
5053
|
+
|
|
5054
|
+
// src/pages/agent-capabilities-page.tsx
|
|
5055
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5056
|
+
function defaultResolveWizardMeta(card) {
|
|
5057
|
+
return {
|
|
5058
|
+
capabilities: [
|
|
5059
|
+
{ label: card.definition.name, description: card.definition.description }
|
|
5060
|
+
],
|
|
5061
|
+
requirements: [],
|
|
5062
|
+
hasConfigStep: false
|
|
5063
|
+
};
|
|
5064
|
+
}
|
|
5065
|
+
function AgentCapabilitiesPage({
|
|
5066
|
+
config,
|
|
5067
|
+
agentId,
|
|
5068
|
+
gagentsApiUrl,
|
|
5069
|
+
resolveWizardMeta = defaultResolveWizardMeta,
|
|
5070
|
+
loadConfigOptions,
|
|
5071
|
+
onWizardComplete
|
|
5072
|
+
}) {
|
|
5073
|
+
const [wizardOpen, setWizardOpen] = useState15(false);
|
|
5074
|
+
const [activeCard, setActiveCard] = useState15(null);
|
|
5075
|
+
const handleConnect = useCallback6(
|
|
5076
|
+
(card) => {
|
|
5077
|
+
setActiveCard(card);
|
|
5078
|
+
setWizardOpen(true);
|
|
5079
|
+
},
|
|
5080
|
+
[]
|
|
5081
|
+
);
|
|
5082
|
+
const handleWizardComplete = useCallback6(() => {
|
|
5083
|
+
setWizardOpen(false);
|
|
5084
|
+
setActiveCard(null);
|
|
5085
|
+
onWizardComplete?.();
|
|
5086
|
+
}, [onWizardComplete]);
|
|
5087
|
+
const handleWizardOpenChange = useCallback6((open) => {
|
|
5088
|
+
setWizardOpen(open);
|
|
5089
|
+
if (!open) setActiveCard(null);
|
|
5090
|
+
}, []);
|
|
5091
|
+
const wizardMeta = activeCard ? resolveWizardMeta(activeCard) : null;
|
|
5092
|
+
return /* @__PURE__ */ jsxs21("div", { className: "space-y-4", children: [
|
|
5093
|
+
/* @__PURE__ */ jsxs21("div", { children: [
|
|
5094
|
+
/* @__PURE__ */ jsx23("h2", { className: "text-lg font-semibold", children: "Capacidades e Integra\xE7\xF5es" }),
|
|
5095
|
+
/* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "Configure o que este agente pode fazer e quais servi\xE7os externos ele utiliza." })
|
|
5096
|
+
] }),
|
|
5097
|
+
/* @__PURE__ */ jsxs21(Tabs, { defaultValue: "capacidades", children: [
|
|
5098
|
+
/* @__PURE__ */ jsxs21(TabsList, { children: [
|
|
5099
|
+
/* @__PURE__ */ jsxs21(TabsTrigger, { value: "capacidades", className: "flex items-center gap-1.5", children: [
|
|
5100
|
+
/* @__PURE__ */ jsx23(Blocks, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5101
|
+
"Capacidades"
|
|
3473
5102
|
] }),
|
|
3474
|
-
/* @__PURE__ */
|
|
3475
|
-
/* @__PURE__ */
|
|
3476
|
-
|
|
3477
|
-
Input9,
|
|
3478
|
-
{
|
|
3479
|
-
id: "cred-credential",
|
|
3480
|
-
name: "credential",
|
|
3481
|
-
autoComplete: "off",
|
|
3482
|
-
type: "password",
|
|
3483
|
-
value: createForm.credentials_encrypted,
|
|
3484
|
-
onChange: (e) => setCreateForm((f) => ({
|
|
3485
|
-
...f,
|
|
3486
|
-
credentials_encrypted: e.target.value
|
|
3487
|
-
})),
|
|
3488
|
-
placeholder: "Credencial encriptada"
|
|
3489
|
-
}
|
|
3490
|
-
)
|
|
5103
|
+
/* @__PURE__ */ jsxs21(TabsTrigger, { value: "integracoes", className: "flex items-center gap-1.5", children: [
|
|
5104
|
+
/* @__PURE__ */ jsx23(Plug3, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5105
|
+
"Integra\xE7\xF5es"
|
|
3491
5106
|
] }),
|
|
3492
|
-
/* @__PURE__ */
|
|
3493
|
-
/* @__PURE__ */
|
|
3494
|
-
|
|
3495
|
-
Input9,
|
|
3496
|
-
{
|
|
3497
|
-
id: "cred-expires",
|
|
3498
|
-
name: "expires",
|
|
3499
|
-
type: "date",
|
|
3500
|
-
value: createForm.expires_at,
|
|
3501
|
-
onChange: (e) => setCreateForm((f) => ({ ...f, expires_at: e.target.value }))
|
|
3502
|
-
}
|
|
3503
|
-
)
|
|
5107
|
+
/* @__PURE__ */ jsxs21(TabsTrigger, { value: "avancado", className: "flex items-center gap-1.5", children: [
|
|
5108
|
+
/* @__PURE__ */ jsx23(Settings4, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5109
|
+
"Avan\xE7ado"
|
|
3504
5110
|
] })
|
|
3505
5111
|
] }),
|
|
3506
|
-
/* @__PURE__ */
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
5112
|
+
/* @__PURE__ */ jsx23(TabsContent, { value: "capacidades", className: "mt-4", children: /* @__PURE__ */ jsx23(CapabilitiesTab, { config, agentId }) }),
|
|
5113
|
+
/* @__PURE__ */ jsx23(TabsContent, { value: "integracoes", className: "mt-4", children: /* @__PURE__ */ jsx23(
|
|
5114
|
+
IntegrationsTab,
|
|
5115
|
+
{
|
|
5116
|
+
config,
|
|
5117
|
+
agentId,
|
|
5118
|
+
onConnect: handleConnect
|
|
5119
|
+
}
|
|
5120
|
+
) }),
|
|
5121
|
+
/* @__PURE__ */ jsx23(TabsContent, { value: "avancado", className: "mt-4", children: /* @__PURE__ */ jsx23(
|
|
5122
|
+
AdvancedTab,
|
|
5123
|
+
{
|
|
5124
|
+
config,
|
|
5125
|
+
agentId,
|
|
5126
|
+
gagentsApiUrl
|
|
5127
|
+
}
|
|
5128
|
+
) })
|
|
5129
|
+
] }),
|
|
5130
|
+
activeCard && wizardMeta && /* @__PURE__ */ jsx23(
|
|
5131
|
+
IntegrationWizard,
|
|
5132
|
+
{
|
|
5133
|
+
open: wizardOpen,
|
|
5134
|
+
onOpenChange: handleWizardOpenChange,
|
|
5135
|
+
integration: activeCard.definition,
|
|
5136
|
+
meta: wizardMeta,
|
|
5137
|
+
agentId,
|
|
5138
|
+
config,
|
|
5139
|
+
onComplete: handleWizardComplete,
|
|
5140
|
+
gagentsApiUrl,
|
|
5141
|
+
existingCredentialId: activeCard.credential?.id,
|
|
5142
|
+
loadConfigOptions
|
|
5143
|
+
}
|
|
5144
|
+
)
|
|
5145
|
+
] });
|
|
5146
|
+
}
|
|
5147
|
+
|
|
5148
|
+
// src/components/agents/agent-tabs.tsx
|
|
5149
|
+
import {
|
|
5150
|
+
Tabs as Tabs2,
|
|
5151
|
+
TabsList as TabsList2,
|
|
5152
|
+
TabsTrigger as TabsTrigger2,
|
|
5153
|
+
TabsContent as TabsContent2
|
|
5154
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
5155
|
+
import { Wrench as Wrench2, Target as Target2, FileText as FileText2, MessageCircle as MessageCircle2, Blocks as Blocks2 } from "lucide-react";
|
|
5156
|
+
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5157
|
+
function AgentTabs({
|
|
5158
|
+
agent,
|
|
5159
|
+
config,
|
|
5160
|
+
renderChatLink,
|
|
5161
|
+
gagentsApiUrl,
|
|
5162
|
+
resolveWizardMeta,
|
|
5163
|
+
loadConfigOptions,
|
|
5164
|
+
onWizardComplete
|
|
5165
|
+
}) {
|
|
5166
|
+
const apiUrl = gagentsApiUrl || config.baseUrl;
|
|
5167
|
+
return /* @__PURE__ */ jsxs22(Tabs2, { defaultValue: "prompt", children: [
|
|
5168
|
+
/* @__PURE__ */ jsxs22(TabsList2, { children: [
|
|
5169
|
+
/* @__PURE__ */ jsxs22(TabsTrigger2, { value: "prompt", className: "flex items-center gap-1.5", children: [
|
|
5170
|
+
/* @__PURE__ */ jsx24(FileText2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5171
|
+
"Prompt"
|
|
5172
|
+
] }),
|
|
5173
|
+
/* @__PURE__ */ jsxs22(TabsTrigger2, { value: "objetivos", className: "flex items-center gap-1.5", children: [
|
|
5174
|
+
/* @__PURE__ */ jsx24(Target2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5175
|
+
"Objetivos"
|
|
5176
|
+
] }),
|
|
5177
|
+
/* @__PURE__ */ jsxs22(TabsTrigger2, { value: "ferramentas", className: "flex items-center gap-1.5", children: [
|
|
5178
|
+
/* @__PURE__ */ jsx24(Wrench2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5179
|
+
"Ferramentas"
|
|
5180
|
+
] }),
|
|
5181
|
+
/* @__PURE__ */ jsxs22(TabsTrigger2, { value: "capacidades", className: "flex items-center gap-1.5", children: [
|
|
5182
|
+
/* @__PURE__ */ jsx24(Blocks2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5183
|
+
"Capacidades"
|
|
5184
|
+
] }),
|
|
5185
|
+
/* @__PURE__ */ jsxs22(TabsTrigger2, { value: "conversas", className: "flex items-center gap-1.5", children: [
|
|
5186
|
+
/* @__PURE__ */ jsx24(MessageCircle2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5187
|
+
"Conversas"
|
|
3523
5188
|
] })
|
|
3524
|
-
] })
|
|
3525
|
-
/* @__PURE__ */
|
|
3526
|
-
|
|
5189
|
+
] }),
|
|
5190
|
+
/* @__PURE__ */ jsx24(TabsContent2, { value: "prompt", className: "mt-4", children: /* @__PURE__ */ jsx24(AgentPromptEditor, { agent, config }) }),
|
|
5191
|
+
/* @__PURE__ */ jsx24(TabsContent2, { value: "objetivos", className: "mt-4", children: /* @__PURE__ */ jsx24(AgentObjectivesList, { agent, config }) }),
|
|
5192
|
+
/* @__PURE__ */ jsx24(TabsContent2, { value: "ferramentas", className: "mt-4", children: /* @__PURE__ */ jsx24(AgentToolsList, { agent, config }) }),
|
|
5193
|
+
/* @__PURE__ */ jsx24(TabsContent2, { value: "capacidades", className: "mt-4", children: /* @__PURE__ */ jsx24(
|
|
5194
|
+
AgentCapabilitiesPage,
|
|
3527
5195
|
{
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
|
|
3535
|
-
/* @__PURE__ */ jsxs12(
|
|
3536
|
-
Select3,
|
|
3537
|
-
{
|
|
3538
|
-
value: editForm.id_tool,
|
|
3539
|
-
onValueChange: (val) => setEditForm((f) => ({ ...f, id_tool: val })),
|
|
3540
|
-
children: [
|
|
3541
|
-
/* @__PURE__ */ jsx14(SelectTrigger3, { id: "edit-cred-tool", children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
|
|
3542
|
-
/* @__PURE__ */ jsx14(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx14(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
|
|
3543
|
-
]
|
|
3544
|
-
}
|
|
3545
|
-
)
|
|
3546
|
-
] }),
|
|
3547
|
-
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3548
|
-
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-label", className: "mb-1 block text-sm font-medium", children: "Label" }),
|
|
3549
|
-
/* @__PURE__ */ jsx14(
|
|
3550
|
-
Input9,
|
|
3551
|
-
{
|
|
3552
|
-
id: "edit-cred-label",
|
|
3553
|
-
name: "label",
|
|
3554
|
-
value: editForm.label,
|
|
3555
|
-
onChange: (e) => setEditForm((f) => ({ ...f, label: e.target.value })),
|
|
3556
|
-
placeholder: "Label da credencial"
|
|
3557
|
-
}
|
|
3558
|
-
)
|
|
3559
|
-
] }),
|
|
3560
|
-
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3561
|
-
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-credential", className: "mb-1 block text-sm font-medium", children: "Nova Credencial (vazio = manter atual)" }),
|
|
3562
|
-
/* @__PURE__ */ jsx14(
|
|
3563
|
-
Input9,
|
|
3564
|
-
{
|
|
3565
|
-
id: "edit-cred-credential",
|
|
3566
|
-
name: "credential",
|
|
3567
|
-
autoComplete: "off",
|
|
3568
|
-
type: "password",
|
|
3569
|
-
value: editForm.credentials_encrypted,
|
|
3570
|
-
onChange: (e) => setEditForm((f) => ({
|
|
3571
|
-
...f,
|
|
3572
|
-
credentials_encrypted: e.target.value
|
|
3573
|
-
})),
|
|
3574
|
-
placeholder: "Nova credencial"
|
|
3575
|
-
}
|
|
3576
|
-
)
|
|
3577
|
-
] }),
|
|
3578
|
-
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3579
|
-
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o" }),
|
|
3580
|
-
/* @__PURE__ */ jsx14(
|
|
3581
|
-
Input9,
|
|
3582
|
-
{
|
|
3583
|
-
id: "edit-cred-expires",
|
|
3584
|
-
name: "expires",
|
|
3585
|
-
type: "date",
|
|
3586
|
-
value: editForm.expires_at,
|
|
3587
|
-
onChange: (e) => setEditForm((f) => ({ ...f, expires_at: e.target.value }))
|
|
3588
|
-
}
|
|
3589
|
-
)
|
|
3590
|
-
] }),
|
|
3591
|
-
/* @__PURE__ */ jsxs12("div", { children: [
|
|
3592
|
-
/* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-status", className: "mb-1 block text-sm font-medium", children: "Status" }),
|
|
3593
|
-
/* @__PURE__ */ jsxs12(
|
|
3594
|
-
Select3,
|
|
3595
|
-
{
|
|
3596
|
-
value: editForm.status || void 0,
|
|
3597
|
-
onValueChange: (val) => setEditForm((f) => ({
|
|
3598
|
-
...f,
|
|
3599
|
-
status: val
|
|
3600
|
-
})),
|
|
3601
|
-
children: [
|
|
3602
|
-
/* @__PURE__ */ jsx14(SelectTrigger3, { id: "edit-cred-status", children: /* @__PURE__ */ jsx14(SelectValue3, {}) }),
|
|
3603
|
-
/* @__PURE__ */ jsxs12(SelectContent3, { children: [
|
|
3604
|
-
/* @__PURE__ */ jsx14(SelectItem3, { value: "active", children: "Ativo" }),
|
|
3605
|
-
/* @__PURE__ */ jsx14(SelectItem3, { value: "expired", children: "Expirado" })
|
|
3606
|
-
] })
|
|
3607
|
-
]
|
|
3608
|
-
}
|
|
3609
|
-
)
|
|
3610
|
-
] })
|
|
3611
|
-
] }),
|
|
3612
|
-
/* @__PURE__ */ jsxs12(DialogFooter6, { children: [
|
|
3613
|
-
/* @__PURE__ */ jsx14(Button10, { variant: "outline", onClick: () => setEditTarget(null), children: "Cancelar" }),
|
|
3614
|
-
/* @__PURE__ */ jsx14(
|
|
3615
|
-
Button10,
|
|
3616
|
-
{
|
|
3617
|
-
onClick: handleSaveEdit,
|
|
3618
|
-
disabled: updateMutation.isPending,
|
|
3619
|
-
children: "Salvar"
|
|
3620
|
-
}
|
|
3621
|
-
)
|
|
3622
|
-
] })
|
|
3623
|
-
] })
|
|
5196
|
+
config,
|
|
5197
|
+
agentId: agent.id,
|
|
5198
|
+
gagentsApiUrl: apiUrl,
|
|
5199
|
+
resolveWizardMeta,
|
|
5200
|
+
loadConfigOptions,
|
|
5201
|
+
onWizardComplete
|
|
3624
5202
|
}
|
|
3625
|
-
),
|
|
3626
|
-
/* @__PURE__ */
|
|
3627
|
-
|
|
5203
|
+
) }),
|
|
5204
|
+
/* @__PURE__ */ jsx24(TabsContent2, { value: "conversas", className: "mt-4", children: /* @__PURE__ */ jsx24(
|
|
5205
|
+
AgentConversationsPanel,
|
|
3628
5206
|
{
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
/* @__PURE__ */ jsxs12(AlertDialogHeader5, { children: [
|
|
3633
|
-
/* @__PURE__ */ jsx14(AlertDialogTitle5, { children: "Remover credencial?" }),
|
|
3634
|
-
/* @__PURE__ */ jsx14(AlertDialogDescription5, { children: "A credencial ser\xE1 removida permanentemente." })
|
|
3635
|
-
] }),
|
|
3636
|
-
/* @__PURE__ */ jsxs12(AlertDialogFooter5, { children: [
|
|
3637
|
-
/* @__PURE__ */ jsx14(AlertDialogCancel5, { children: "Cancelar" }),
|
|
3638
|
-
/* @__PURE__ */ jsx14(
|
|
3639
|
-
AlertDialogAction5,
|
|
3640
|
-
{
|
|
3641
|
-
onClick: handleRemove,
|
|
3642
|
-
disabled: deleteMutation.isPending,
|
|
3643
|
-
children: "Remover"
|
|
3644
|
-
}
|
|
3645
|
-
)
|
|
3646
|
-
] })
|
|
3647
|
-
] })
|
|
5207
|
+
agent,
|
|
5208
|
+
config,
|
|
5209
|
+
renderChatLink
|
|
3648
5210
|
}
|
|
3649
|
-
)
|
|
5211
|
+
) })
|
|
3650
5212
|
] });
|
|
3651
5213
|
}
|
|
3652
5214
|
|
|
3653
5215
|
// src/pages/agents-page.tsx
|
|
3654
|
-
import { useState as
|
|
3655
|
-
import { Button as
|
|
5216
|
+
import { useState as useState16 } from "react";
|
|
5217
|
+
import { Button as Button15 } from "@greatapps/greatauth-ui/ui";
|
|
3656
5218
|
import { Plus as Plus3 } from "lucide-react";
|
|
3657
|
-
import { jsx as
|
|
5219
|
+
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3658
5220
|
function AgentsPage({
|
|
3659
5221
|
config,
|
|
3660
5222
|
onNavigateToAgent,
|
|
3661
5223
|
title = "Agentes AI",
|
|
3662
5224
|
subtitle = "Gerencie seus agentes de atendimento inteligente"
|
|
3663
5225
|
}) {
|
|
3664
|
-
const [createOpen, setCreateOpen] =
|
|
3665
|
-
return /* @__PURE__ */
|
|
3666
|
-
/* @__PURE__ */
|
|
3667
|
-
/* @__PURE__ */
|
|
3668
|
-
/* @__PURE__ */
|
|
3669
|
-
/* @__PURE__ */
|
|
5226
|
+
const [createOpen, setCreateOpen] = useState16(false);
|
|
5227
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5228
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between", children: [
|
|
5229
|
+
/* @__PURE__ */ jsxs23("div", { children: [
|
|
5230
|
+
/* @__PURE__ */ jsx25("h1", { className: "text-xl font-semibold", children: title }),
|
|
5231
|
+
/* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
3670
5232
|
] }),
|
|
3671
|
-
/* @__PURE__ */
|
|
3672
|
-
/* @__PURE__ */
|
|
5233
|
+
/* @__PURE__ */ jsxs23(Button15, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5234
|
+
/* @__PURE__ */ jsx25(Plus3, { className: "mr-2 h-4 w-4" }),
|
|
3673
5235
|
"Novo Agente"
|
|
3674
5236
|
] })
|
|
3675
5237
|
] }),
|
|
3676
|
-
/* @__PURE__ */
|
|
3677
|
-
/* @__PURE__ */
|
|
5238
|
+
/* @__PURE__ */ jsx25(AgentsTable, { config, onNavigateToAgent }),
|
|
5239
|
+
/* @__PURE__ */ jsx25(
|
|
3678
5240
|
AgentFormDialog,
|
|
3679
5241
|
{
|
|
3680
5242
|
config,
|
|
@@ -3686,11 +5248,11 @@ function AgentsPage({
|
|
|
3686
5248
|
}
|
|
3687
5249
|
|
|
3688
5250
|
// src/pages/agent-detail-page.tsx
|
|
3689
|
-
import { useState as
|
|
3690
|
-
import { Badge as
|
|
5251
|
+
import { useState as useState17 } from "react";
|
|
5252
|
+
import { Badge as Badge10, Button as Button16, Skeleton as Skeleton7 } from "@greatapps/greatauth-ui/ui";
|
|
3691
5253
|
import { EntityAvatar as EntityAvatar2 } from "@greatapps/greatauth-ui";
|
|
3692
5254
|
import { ArrowLeft, Pencil as Pencil5 } from "lucide-react";
|
|
3693
|
-
import { jsx as
|
|
5255
|
+
import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3694
5256
|
function AgentDetailPage({
|
|
3695
5257
|
config,
|
|
3696
5258
|
agentId,
|
|
@@ -3698,43 +5260,43 @@ function AgentDetailPage({
|
|
|
3698
5260
|
renderChatLink
|
|
3699
5261
|
}) {
|
|
3700
5262
|
const { data: agent, isLoading } = useAgent(config, agentId);
|
|
3701
|
-
const [editOpen, setEditOpen] =
|
|
5263
|
+
const [editOpen, setEditOpen] = useState17(false);
|
|
3702
5264
|
if (isLoading) {
|
|
3703
|
-
return /* @__PURE__ */
|
|
3704
|
-
/* @__PURE__ */
|
|
3705
|
-
/* @__PURE__ */
|
|
3706
|
-
/* @__PURE__ */
|
|
3707
|
-
/* @__PURE__ */
|
|
5265
|
+
return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-4 p-4", children: [
|
|
5266
|
+
/* @__PURE__ */ jsx26(Skeleton7, { className: "h-4 w-32" }),
|
|
5267
|
+
/* @__PURE__ */ jsx26(Skeleton7, { className: "h-8 w-48" }),
|
|
5268
|
+
/* @__PURE__ */ jsx26(Skeleton7, { className: "h-10 w-full" }),
|
|
5269
|
+
/* @__PURE__ */ jsx26(Skeleton7, { className: "h-64 w-full" })
|
|
3708
5270
|
] });
|
|
3709
5271
|
}
|
|
3710
5272
|
if (!agent) {
|
|
3711
|
-
return /* @__PURE__ */
|
|
3712
|
-
/* @__PURE__ */
|
|
3713
|
-
onBack && /* @__PURE__ */
|
|
3714
|
-
/* @__PURE__ */
|
|
5273
|
+
return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [
|
|
5274
|
+
/* @__PURE__ */ jsx26("p", { className: "text-muted-foreground", children: "Agente n\xE3o encontrado" }),
|
|
5275
|
+
onBack && /* @__PURE__ */ jsxs24(Button16, { variant: "ghost", size: "sm", onClick: onBack, children: [
|
|
5276
|
+
/* @__PURE__ */ jsx26(ArrowLeft, { className: "mr-2 h-4 w-4" }),
|
|
3715
5277
|
"Voltar para agentes"
|
|
3716
5278
|
] })
|
|
3717
5279
|
] });
|
|
3718
5280
|
}
|
|
3719
|
-
return /* @__PURE__ */
|
|
3720
|
-
/* @__PURE__ */
|
|
3721
|
-
/* @__PURE__ */
|
|
3722
|
-
onBack && /* @__PURE__ */
|
|
3723
|
-
|
|
5281
|
+
return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-6 p-4 md:p-6", children: [
|
|
5282
|
+
/* @__PURE__ */ jsx26("div", { className: "rounded-lg border p-4 md:p-6", children: /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:gap-6", children: [
|
|
5283
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-start gap-3 flex-1", children: [
|
|
5284
|
+
onBack && /* @__PURE__ */ jsx26(
|
|
5285
|
+
Button16,
|
|
3724
5286
|
{
|
|
3725
5287
|
variant: "ghost",
|
|
3726
5288
|
size: "icon",
|
|
3727
5289
|
"aria-label": "Voltar",
|
|
3728
5290
|
className: "shrink-0 mt-1",
|
|
3729
5291
|
onClick: onBack,
|
|
3730
|
-
children: /* @__PURE__ */
|
|
5292
|
+
children: /* @__PURE__ */ jsx26(ArrowLeft, { className: "h-4 w-4" })
|
|
3731
5293
|
}
|
|
3732
5294
|
),
|
|
3733
|
-
/* @__PURE__ */
|
|
3734
|
-
/* @__PURE__ */
|
|
3735
|
-
/* @__PURE__ */
|
|
3736
|
-
/* @__PURE__ */
|
|
3737
|
-
|
|
5295
|
+
/* @__PURE__ */ jsx26(EntityAvatar2, { photo: agent.photo, name: agent.title, size: "xl" }),
|
|
5296
|
+
/* @__PURE__ */ jsx26("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
5297
|
+
/* @__PURE__ */ jsx26("h1", { className: "text-xl font-semibold", children: agent.title }),
|
|
5298
|
+
/* @__PURE__ */ jsx26(
|
|
5299
|
+
Badge10,
|
|
3738
5300
|
{
|
|
3739
5301
|
variant: agent.active ? "default" : "destructive",
|
|
3740
5302
|
className: "text-xs",
|
|
@@ -3743,21 +5305,21 @@ function AgentDetailPage({
|
|
|
3743
5305
|
)
|
|
3744
5306
|
] }) })
|
|
3745
5307
|
] }),
|
|
3746
|
-
/* @__PURE__ */
|
|
3747
|
-
|
|
5308
|
+
/* @__PURE__ */ jsxs24(
|
|
5309
|
+
Button16,
|
|
3748
5310
|
{
|
|
3749
5311
|
variant: "outline",
|
|
3750
5312
|
size: "sm",
|
|
3751
5313
|
className: "shrink-0 self-start",
|
|
3752
5314
|
onClick: () => setEditOpen(true),
|
|
3753
5315
|
children: [
|
|
3754
|
-
/* @__PURE__ */
|
|
5316
|
+
/* @__PURE__ */ jsx26(Pencil5, { className: "mr-2 h-4 w-4" }),
|
|
3755
5317
|
"Editar"
|
|
3756
5318
|
]
|
|
3757
5319
|
}
|
|
3758
5320
|
)
|
|
3759
5321
|
] }) }),
|
|
3760
|
-
/* @__PURE__ */
|
|
5322
|
+
/* @__PURE__ */ jsx26(
|
|
3761
5323
|
AgentTabs,
|
|
3762
5324
|
{
|
|
3763
5325
|
agent,
|
|
@@ -3765,7 +5327,7 @@ function AgentDetailPage({
|
|
|
3765
5327
|
renderChatLink
|
|
3766
5328
|
}
|
|
3767
5329
|
),
|
|
3768
|
-
editOpen && /* @__PURE__ */
|
|
5330
|
+
editOpen && /* @__PURE__ */ jsx26(
|
|
3769
5331
|
AgentEditForm,
|
|
3770
5332
|
{
|
|
3771
5333
|
agent,
|
|
@@ -3779,30 +5341,30 @@ function AgentDetailPage({
|
|
|
3779
5341
|
}
|
|
3780
5342
|
|
|
3781
5343
|
// src/pages/tools-page.tsx
|
|
3782
|
-
import { useState as
|
|
3783
|
-
import { Button as
|
|
5344
|
+
import { useState as useState18 } from "react";
|
|
5345
|
+
import { Button as Button17 } from "@greatapps/greatauth-ui/ui";
|
|
3784
5346
|
import { Plus as Plus4 } from "lucide-react";
|
|
3785
|
-
import { jsx as
|
|
5347
|
+
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3786
5348
|
function ToolsPage({
|
|
3787
5349
|
config,
|
|
3788
5350
|
title = "Ferramentas",
|
|
3789
5351
|
subtitle = "Gerencie as ferramentas dispon\xEDveis para seus agentes"
|
|
3790
5352
|
}) {
|
|
3791
|
-
const [createOpen, setCreateOpen] =
|
|
3792
|
-
const [editTool, setEditTool] =
|
|
3793
|
-
return /* @__PURE__ */
|
|
3794
|
-
/* @__PURE__ */
|
|
3795
|
-
/* @__PURE__ */
|
|
3796
|
-
/* @__PURE__ */
|
|
3797
|
-
/* @__PURE__ */
|
|
5353
|
+
const [createOpen, setCreateOpen] = useState18(false);
|
|
5354
|
+
const [editTool, setEditTool] = useState18(void 0);
|
|
5355
|
+
return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5356
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between", children: [
|
|
5357
|
+
/* @__PURE__ */ jsxs25("div", { children: [
|
|
5358
|
+
/* @__PURE__ */ jsx27("h1", { className: "text-xl font-semibold", children: title }),
|
|
5359
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
3798
5360
|
] }),
|
|
3799
|
-
/* @__PURE__ */
|
|
3800
|
-
/* @__PURE__ */
|
|
5361
|
+
/* @__PURE__ */ jsxs25(Button17, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5362
|
+
/* @__PURE__ */ jsx27(Plus4, { className: "mr-2 h-4 w-4" }),
|
|
3801
5363
|
"Nova Ferramenta"
|
|
3802
5364
|
] })
|
|
3803
5365
|
] }),
|
|
3804
|
-
/* @__PURE__ */
|
|
3805
|
-
/* @__PURE__ */
|
|
5366
|
+
/* @__PURE__ */ jsx27(ToolsTable, { config, onEdit: (tool) => setEditTool(tool) }),
|
|
5367
|
+
/* @__PURE__ */ jsx27(
|
|
3806
5368
|
ToolFormDialog,
|
|
3807
5369
|
{
|
|
3808
5370
|
config,
|
|
@@ -3810,7 +5372,7 @@ function ToolsPage({
|
|
|
3810
5372
|
onOpenChange: setCreateOpen
|
|
3811
5373
|
}
|
|
3812
5374
|
),
|
|
3813
|
-
/* @__PURE__ */
|
|
5375
|
+
/* @__PURE__ */ jsx27(
|
|
3814
5376
|
ToolFormDialog,
|
|
3815
5377
|
{
|
|
3816
5378
|
config,
|
|
@@ -3823,10 +5385,10 @@ function ToolsPage({
|
|
|
3823
5385
|
}
|
|
3824
5386
|
|
|
3825
5387
|
// src/pages/credentials-page.tsx
|
|
3826
|
-
import { useState as
|
|
3827
|
-
import { Button as
|
|
5388
|
+
import { useState as useState19 } from "react";
|
|
5389
|
+
import { Button as Button18 } from "@greatapps/greatauth-ui/ui";
|
|
3828
5390
|
import { Plus as Plus5 } from "lucide-react";
|
|
3829
|
-
import { jsx as
|
|
5391
|
+
import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3830
5392
|
function CredentialsPage({
|
|
3831
5393
|
config,
|
|
3832
5394
|
gagentsApiUrl,
|
|
@@ -3834,20 +5396,20 @@ function CredentialsPage({
|
|
|
3834
5396
|
subtitle = "Gerencie as credenciais de autentica\xE7\xE3o das ferramentas"
|
|
3835
5397
|
}) {
|
|
3836
5398
|
const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
|
|
3837
|
-
const [createOpen, setCreateOpen] =
|
|
5399
|
+
const [createOpen, setCreateOpen] = useState19(false);
|
|
3838
5400
|
const credentials = credentialsData?.data || [];
|
|
3839
|
-
return /* @__PURE__ */
|
|
3840
|
-
/* @__PURE__ */
|
|
3841
|
-
/* @__PURE__ */
|
|
3842
|
-
/* @__PURE__ */
|
|
3843
|
-
/* @__PURE__ */
|
|
5401
|
+
return /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5402
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between", children: [
|
|
5403
|
+
/* @__PURE__ */ jsxs26("div", { children: [
|
|
5404
|
+
/* @__PURE__ */ jsx28("h1", { className: "text-xl font-semibold", children: title }),
|
|
5405
|
+
/* @__PURE__ */ jsx28("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
3844
5406
|
] }),
|
|
3845
|
-
/* @__PURE__ */
|
|
3846
|
-
/* @__PURE__ */
|
|
5407
|
+
/* @__PURE__ */ jsxs26(Button18, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5408
|
+
/* @__PURE__ */ jsx28(Plus5, { className: "mr-2 h-4 w-4" }),
|
|
3847
5409
|
"Nova Credencial"
|
|
3848
5410
|
] })
|
|
3849
5411
|
] }),
|
|
3850
|
-
/* @__PURE__ */
|
|
5412
|
+
/* @__PURE__ */ jsx28(
|
|
3851
5413
|
ToolCredentialsForm,
|
|
3852
5414
|
{
|
|
3853
5415
|
config,
|
|
@@ -3860,7 +5422,117 @@ function CredentialsPage({
|
|
|
3860
5422
|
)
|
|
3861
5423
|
] });
|
|
3862
5424
|
}
|
|
5425
|
+
|
|
5426
|
+
// src/pages/integrations-management-page.tsx
|
|
5427
|
+
import { useState as useState20, useMemo as useMemo8 } from "react";
|
|
5428
|
+
import {
|
|
5429
|
+
Badge as Badge11,
|
|
5430
|
+
Button as Button19,
|
|
5431
|
+
Tabs as Tabs3,
|
|
5432
|
+
TabsContent as TabsContent3,
|
|
5433
|
+
TabsList as TabsList3,
|
|
5434
|
+
TabsTrigger as TabsTrigger3
|
|
5435
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
5436
|
+
import { Plus as Plus6, Plug as Plug4, KeyRound, Info as Info3 } from "lucide-react";
|
|
5437
|
+
import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5438
|
+
function useCredentialAgentSummary(credentials, tools, agents) {
|
|
5439
|
+
return useMemo8(() => {
|
|
5440
|
+
const toolIdsWithCredentials = new Set(
|
|
5441
|
+
credentials.map((c) => c.id_tool).filter(Boolean)
|
|
5442
|
+
);
|
|
5443
|
+
const linkedCount = credentials.filter(
|
|
5444
|
+
(c) => c.id_tool && toolIdsWithCredentials.has(c.id_tool)
|
|
5445
|
+
).length;
|
|
5446
|
+
return {
|
|
5447
|
+
totalCredentials: credentials.length,
|
|
5448
|
+
linkedToTools: linkedCount,
|
|
5449
|
+
totalAgents: agents.length,
|
|
5450
|
+
totalTools: tools.length
|
|
5451
|
+
};
|
|
5452
|
+
}, [credentials, tools, agents]);
|
|
5453
|
+
}
|
|
5454
|
+
function IntegrationsManagementPage({
|
|
5455
|
+
config,
|
|
5456
|
+
gagentsApiUrl,
|
|
5457
|
+
onConnect,
|
|
5458
|
+
title = "Integra\xE7\xF5es e Credenciais",
|
|
5459
|
+
subtitle = "Gerencie todas as integra\xE7\xF5es e credenciais da conta."
|
|
5460
|
+
}) {
|
|
5461
|
+
const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
|
|
5462
|
+
const { data: agentsData } = useAgents(config);
|
|
5463
|
+
const { data: toolsData } = useTools(config);
|
|
5464
|
+
const [createOpen, setCreateOpen] = useState20(false);
|
|
5465
|
+
const credentials = credentialsData?.data || [];
|
|
5466
|
+
const agents = agentsData?.data || [];
|
|
5467
|
+
const tools = toolsData?.data || [];
|
|
5468
|
+
const summary = useCredentialAgentSummary(credentials, tools, agents);
|
|
5469
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5470
|
+
/* @__PURE__ */ jsx29("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs27("div", { children: [
|
|
5471
|
+
/* @__PURE__ */ jsx29("h1", { className: "text-xl font-semibold", children: title }),
|
|
5472
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
5473
|
+
] }) }),
|
|
5474
|
+
/* @__PURE__ */ jsxs27(Tabs3, { defaultValue: "integrations", className: "w-full", children: [
|
|
5475
|
+
/* @__PURE__ */ jsxs27(TabsList3, { children: [
|
|
5476
|
+
/* @__PURE__ */ jsxs27(TabsTrigger3, { value: "integrations", className: "gap-2", children: [
|
|
5477
|
+
/* @__PURE__ */ jsx29(Plug4, { className: "h-4 w-4" }),
|
|
5478
|
+
"Integra\xE7\xF5es"
|
|
5479
|
+
] }),
|
|
5480
|
+
/* @__PURE__ */ jsxs27(TabsTrigger3, { value: "credentials", className: "gap-2", children: [
|
|
5481
|
+
/* @__PURE__ */ jsx29(KeyRound, { className: "h-4 w-4" }),
|
|
5482
|
+
"Credenciais"
|
|
5483
|
+
] })
|
|
5484
|
+
] }),
|
|
5485
|
+
/* @__PURE__ */ jsx29(TabsContent3, { value: "integrations", className: "mt-4", children: /* @__PURE__ */ jsx29(
|
|
5486
|
+
IntegrationsTab,
|
|
5487
|
+
{
|
|
5488
|
+
config,
|
|
5489
|
+
agentId: null,
|
|
5490
|
+
onConnect: onConnect ?? (() => {
|
|
5491
|
+
})
|
|
5492
|
+
}
|
|
5493
|
+
) }),
|
|
5494
|
+
/* @__PURE__ */ jsxs27(TabsContent3, { value: "credentials", className: "mt-4", children: [
|
|
5495
|
+
!credentialsLoading && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-4 rounded-lg border bg-muted/50 px-4 py-3 mb-4", children: [
|
|
5496
|
+
/* @__PURE__ */ jsx29(Info3, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
|
|
5497
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex flex-wrap items-center gap-3 text-sm", children: [
|
|
5498
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
5499
|
+
/* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalCredentials }),
|
|
5500
|
+
summary.totalCredentials === 1 ? "credencial configurada" : "credenciais configuradas"
|
|
5501
|
+
] }),
|
|
5502
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
|
|
5503
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
5504
|
+
/* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.linkedToTools }),
|
|
5505
|
+
summary.linkedToTools === 1 ? "vinculada a ferramentas" : "vinculadas a ferramentas"
|
|
5506
|
+
] }),
|
|
5507
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
|
|
5508
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
5509
|
+
/* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalAgents }),
|
|
5510
|
+
summary.totalAgents === 1 ? "agente na conta" : "agentes na conta"
|
|
5511
|
+
] })
|
|
5512
|
+
] })
|
|
5513
|
+
] }),
|
|
5514
|
+
/* @__PURE__ */ jsx29("div", { className: "flex items-center justify-end mb-4", children: /* @__PURE__ */ jsxs27(Button19, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5515
|
+
/* @__PURE__ */ jsx29(Plus6, { className: "mr-2 h-4 w-4" }),
|
|
5516
|
+
"Nova Credencial"
|
|
5517
|
+
] }) }),
|
|
5518
|
+
/* @__PURE__ */ jsx29(
|
|
5519
|
+
ToolCredentialsForm,
|
|
5520
|
+
{
|
|
5521
|
+
config,
|
|
5522
|
+
gagentsApiUrl,
|
|
5523
|
+
credentials,
|
|
5524
|
+
isLoading: credentialsLoading,
|
|
5525
|
+
createOpen,
|
|
5526
|
+
onCreateOpenChange: setCreateOpen
|
|
5527
|
+
}
|
|
5528
|
+
)
|
|
5529
|
+
] })
|
|
5530
|
+
] })
|
|
5531
|
+
] });
|
|
5532
|
+
}
|
|
3863
5533
|
export {
|
|
5534
|
+
AdvancedTab,
|
|
5535
|
+
AgentCapabilitiesPage,
|
|
3864
5536
|
AgentConversationsPanel,
|
|
3865
5537
|
AgentConversationsTable,
|
|
3866
5538
|
AgentDetailPage,
|
|
@@ -3872,8 +5544,14 @@ export {
|
|
|
3872
5544
|
AgentToolsList,
|
|
3873
5545
|
AgentsPage,
|
|
3874
5546
|
AgentsTable,
|
|
5547
|
+
CapabilitiesTab,
|
|
3875
5548
|
ConversationView,
|
|
3876
5549
|
CredentialsPage,
|
|
5550
|
+
INTEGRATIONS_REGISTRY,
|
|
5551
|
+
IntegrationCard,
|
|
5552
|
+
IntegrationWizard,
|
|
5553
|
+
IntegrationsManagementPage,
|
|
5554
|
+
IntegrationsTab,
|
|
3877
5555
|
Sortable,
|
|
3878
5556
|
SortableContent,
|
|
3879
5557
|
SortableItem,
|
|
@@ -3887,9 +5565,11 @@ export {
|
|
|
3887
5565
|
createGagentsClient,
|
|
3888
5566
|
useAddAgentTool,
|
|
3889
5567
|
useAgent,
|
|
5568
|
+
useAgentCapabilities,
|
|
3890
5569
|
useAgentConversations,
|
|
3891
5570
|
useAgentTools,
|
|
3892
5571
|
useAgents,
|
|
5572
|
+
useCapabilities,
|
|
3893
5573
|
useContactUsers,
|
|
3894
5574
|
useConversation,
|
|
3895
5575
|
useConversations,
|
|
@@ -3903,6 +5583,7 @@ export {
|
|
|
3903
5583
|
useDeleteToolCredential,
|
|
3904
5584
|
useGagentsClient,
|
|
3905
5585
|
useGagentsContacts,
|
|
5586
|
+
useIntegrationState,
|
|
3906
5587
|
useObjectives,
|
|
3907
5588
|
usePromptVersions,
|
|
3908
5589
|
useRemoveAgentTool,
|
|
@@ -3910,6 +5591,7 @@ export {
|
|
|
3910
5591
|
useToolCredentials,
|
|
3911
5592
|
useTools,
|
|
3912
5593
|
useUpdateAgent,
|
|
5594
|
+
useUpdateAgentCapabilities,
|
|
3913
5595
|
useUpdateAgentTool,
|
|
3914
5596
|
useUpdateObjective,
|
|
3915
5597
|
useUpdateTool,
|