@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.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 useMemo2, useState } from "react";
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 = useMemo2(() => {
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 [title, setTitle] = useState2("");
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
- setTitle(agent.title);
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
- setTitle("");
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()) return;
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 (delayTyping.trim()) body.delay_typing = Number(delayTyping);
676
- if (waitingTime.trim()) body.waiting_time = Number(waitingTime);
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) => setPhoto(e.target.value),
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) => setTitle(e.target.value),
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 (ms)" }),
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) => setDelayTyping(e.target.value),
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 (ms)" }),
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) => setWaitingTime(e.target.value),
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 msToSeconds(ms) {
956
+ function msToSeconds2(ms) {
796
957
  if (ms == null || ms === 0) return "";
797
958
  return String(Math.round(ms / 1e3));
798
959
  }
799
- function secondsToMs(seconds) {
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 agentToFormState(agent) {
965
+ function agentToFormState2(agent) {
805
966
  return {
806
967
  title: agent.title,
807
968
  photo: agent.photo || "",
808
969
  active: agent.active,
809
- delayTyping: msToSeconds(agent.delay_typing),
810
- waitingTime: msToSeconds(agent.waiting_time),
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(() => agentToFormState(agent));
977
+ const [form, setForm] = useState3(() => agentToFormState2(agent));
817
978
  useEffect2(() => {
818
- setForm(agentToFormState(agent));
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 = secondsToMs(form.delayTyping);
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 = secondsToMs(form.waitingTime);
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
- Switch,
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 Switch2,
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
- Switch2,
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 Switch3,
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
- Switch3,
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/components/agents/agent-tabs.tsx
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 { Wrench as Wrench2, Target as Target2, FileText as FileText2, MessageCircle as MessageCircle2 } from "lucide-react";
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/tools/tools-table.tsx
2687
- import { useMemo as useMemo4, useState as useState9 } from "react";
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
- Input as Input7,
2817
+ Accordion,
2818
+ AccordionItem,
2819
+ AccordionTrigger,
2820
+ AccordionContent,
2821
+ Switch as Switch5,
2822
+ Checkbox,
2691
2823
  Badge as Badge6,
2692
- Tooltip as Tooltip2,
2693
- TooltipTrigger as TooltipTrigger2,
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 { Pencil as Pencil3, Trash2 as Trash24, Search as Search2 } from "lucide-react";
2706
- import { format as format2 } from "date-fns";
2707
- import { ptBR as ptBR2 } from "date-fns/locale";
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 { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2710
- function useColumns2(onEdit, onDelete) {
2711
- return [
2712
- {
2713
- accessorKey: "name",
2714
- header: "Nome",
2715
- cell: ({ row }) => /* @__PURE__ */ jsx12("span", { className: "font-medium", children: row.original.name }),
2716
- sortingFn: (rowA, rowB) => rowA.original.name.toLowerCase().localeCompare(rowB.original.name.toLowerCase())
2717
- },
2718
- {
2719
- accessorKey: "slug",
2720
- header: "Slug",
2721
- cell: ({ row }) => /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm font-mono", children: row.original.slug || "\u2014" })
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
- accessorKey: "type",
2725
- header: "Tipo",
2726
- cell: ({ row }) => /* @__PURE__ */ jsx12(Badge6, { variant: "secondary", children: row.original.type })
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
- accessorKey: "description",
2730
- header: "Descri\xE7\xE3o",
2731
- cell: ({ row }) => {
2732
- const desc = row.original.description;
2733
- if (!desc) return /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm", children: "\u2014" });
2734
- return /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm", children: desc.length > 50 ? `${desc.slice(0, 50)}\u2026` : desc });
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
- accessorKey: "datetime_add",
2739
- header: "Criado em",
2740
- cell: ({ row }) => /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm", children: format2(new Date(row.original.datetime_add), "dd/MM/yyyy", {
2741
- locale: ptBR2
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
- function handleDelete() {
2804
- if (!deleteId) return;
2805
- deleteTool.mutate(deleteId, {
2806
- onSuccess: () => {
2807
- toast7.success("Ferramenta exclu\xEDda");
2808
- setDeleteId(null);
2809
- },
2810
- onError: () => toast7.error("Erro ao excluir ferramenta")
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
- function handleSearchChange(value) {
2814
- setSearch(value);
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
- return /* @__PURE__ */ jsxs10(Fragment2, { children: [
2818
- /* @__PURE__ */ jsx12("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs10("div", { className: "relative flex-1 max-w-md", children: [
2819
- /* @__PURE__ */ jsx12(Search2, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2820
- /* @__PURE__ */ jsx12(
2821
- Input7,
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
- placeholder: "Buscar ferramentas\\u2026",
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__ */ jsx12(
2834
- DataTable2,
4507
+ /* @__PURE__ */ jsx20(
4508
+ DataTable3,
2835
4509
  {
2836
4510
  columns,
2837
- data: tools,
4511
+ data: filteredCredentials,
2838
4512
  isLoading,
2839
- emptyMessage: "Nenhuma ferramenta encontrada",
2840
- total,
2841
- page,
2842
- onPageChange: setPage,
2843
- pageSize: 15
4513
+ emptyMessage: "Nenhuma credencial encontrada"
2844
4514
  }
2845
4515
  ),
2846
- /* @__PURE__ */ jsx12(
2847
- AlertDialog4,
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: !!deleteId,
2850
- onOpenChange: (open) => !open && setDeleteId(null),
2851
- children: /* @__PURE__ */ jsxs10(AlertDialogContent4, { children: [
2852
- /* @__PURE__ */ jsxs10(AlertDialogHeader4, { children: [
2853
- /* @__PURE__ */ jsx12(AlertDialogTitle4, { children: "Excluir ferramenta?" }),
2854
- /* @__PURE__ */ jsx12(AlertDialogDescription4, { children: "Esta a\xE7\xE3o n\xE3o pode ser desfeita. A ferramenta ser\xE1 removida permanentemente." })
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__ */ jsxs10(AlertDialogFooter4, { children: [
2857
- /* @__PURE__ */ jsx12(AlertDialogCancel4, { variant: "outline", size: "default", children: "Cancelar" }),
2858
- /* @__PURE__ */ jsx12(
2859
- AlertDialogAction4,
4708
+ /* @__PURE__ */ jsxs18(AlertDialogFooter5, { children: [
4709
+ /* @__PURE__ */ jsx20(AlertDialogCancel5, { children: "Cancelar" }),
4710
+ /* @__PURE__ */ jsx20(
4711
+ AlertDialogAction5,
2860
4712
  {
2861
- variant: "default",
2862
- size: "default",
2863
- onClick: handleDelete,
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 useState10 } from "react";
4726
+ import { useState as useState13 } from "react";
2877
4727
  import {
2878
- Dialog as Dialog5,
2879
- DialogContent as DialogContent5,
2880
- DialogHeader as DialogHeader5,
2881
- DialogTitle as DialogTitle5,
2882
- DialogFooter as DialogFooter5,
2883
- Button as Button9,
2884
- Input as Input8,
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 Label5,
2887
- Select as Select2,
2888
- SelectContent as SelectContent2,
2889
- SelectItem as SelectItem2,
2890
- SelectTrigger as SelectTrigger2,
2891
- SelectValue as SelectValue2
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 Loader24 } from "lucide-react";
2894
- import { toast as toast8 } from "sonner";
2895
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
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] = useState10(() => toolToFormState(tool));
2943
- const [slugManuallyEdited, setSlugManuallyEdited] = useState10(false);
2944
- const [lastResetKey, setLastResetKey] = useState10(
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
- toast8.success("Ferramenta atualizada");
4841
+ toast11.success("Ferramenta atualizada");
2992
4842
  } else {
2993
4843
  await createTool.mutateAsync(
2994
4844
  body
2995
4845
  );
2996
- toast8.success("Ferramenta criada");
4846
+ toast11.success("Ferramenta criada");
2997
4847
  }
2998
4848
  onOpenChange(false);
2999
4849
  } catch (err) {
3000
- toast8.error(
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__ */ jsx13(Dialog5, { open, onOpenChange, children: /* @__PURE__ */ jsxs11(DialogContent5, { className: "sm:max-w-lg", children: [
3006
- /* @__PURE__ */ jsx13(DialogHeader5, { children: /* @__PURE__ */ jsx13(DialogTitle5, { children: isEditing ? "Editar Ferramenta" : "Nova Ferramenta" }) }),
3007
- /* @__PURE__ */ jsxs11("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
3008
- /* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
3009
- /* @__PURE__ */ jsx13(Label5, { htmlFor: "tool-name", children: "Nome *" }),
3010
- /* @__PURE__ */ jsx13(
3011
- Input8,
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__ */ jsx13("p", { className: "text-sm text-destructive", children: "Nome \xE9 obrigat\xF3rio" })
4879
+ form.nameError && /* @__PURE__ */ jsx21("p", { className: "text-sm text-destructive", children: "Nome \xE9 obrigat\xF3rio" })
3030
4880
  ] }),
3031
- /* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
3032
- /* @__PURE__ */ jsx13(Label5, { htmlFor: "tool-slug", children: "Slug (identificador \xFAnico) *" }),
3033
- /* @__PURE__ */ jsx13(
3034
- Input8,
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__ */ jsx13("p", { className: "text-xs text-muted-foreground", children: "Gerado automaticamente a partir do nome. Usado internamente para identificar a ferramenta." }),
3052
- form.slugError && /* @__PURE__ */ jsx13("p", { className: "text-sm text-destructive", children: "Slug \xE9 obrigat\xF3rio" })
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__ */ jsxs11("div", { className: "space-y-2", children: [
3055
- /* @__PURE__ */ jsx13(Label5, { htmlFor: "tool-type", children: "Tipo de Autentica\xE7\xE3o *" }),
3056
- /* @__PURE__ */ jsxs11(
3057
- Select2,
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__ */ jsx13(SelectTrigger2, { id: "tool-type", children: /* @__PURE__ */ jsx13(SelectValue2, { placeholder: "Selecione o tipo" }) }),
3070
- /* @__PURE__ */ jsx13(SelectContent2, { children: TOOL_AUTH_TYPES.map((t) => /* @__PURE__ */ jsx13(SelectItem2, { value: t.value, children: t.label }, t.value)) })
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__ */ jsx13("p", { className: "text-xs text-muted-foreground", children: "Define se a ferramenta requer credenciais para funcionar." }),
3075
- form.typeError && /* @__PURE__ */ jsx13("p", { className: "text-sm text-destructive", children: "Tipo \xE9 obrigat\xF3rio" })
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__ */ jsxs11("div", { className: "space-y-2", children: [
3078
- /* @__PURE__ */ jsx13(Label5, { htmlFor: "tool-description", children: "Descri\xE7\xE3o" }),
3079
- /* @__PURE__ */ jsx13(
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__ */ jsxs11("div", { className: "space-y-2", children: [
3093
- /* @__PURE__ */ jsx13(Label5, { htmlFor: "tool-function-defs", children: "Defini\xE7\xF5es de Fun\xE7\xE3o (JSON)" }),
3094
- /* @__PURE__ */ jsx13(
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__ */ jsx13("p", { className: "text-xs text-muted-foreground", children: "Array de defini\xE7\xF5es no formato OpenAI Function Calling." }),
3127
- form.jsonError && /* @__PURE__ */ jsx13("p", { className: "text-sm text-destructive", children: "JSON inv\xE1lido" })
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__ */ jsxs11(DialogFooter5, { children: [
3130
- /* @__PURE__ */ jsx13(
3131
- Button9,
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__ */ jsxs11(Button9, { type: "submit", disabled: isPending, children: [
3141
- isPending ? /* @__PURE__ */ jsx13(Loader24, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }) : null,
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/tools/tool-credentials-form.tsx
3150
- import { useMemo as useMemo5, useState as useState11 } from "react";
3151
- import { DataTable as DataTable3 } from "@greatapps/greatauth-ui";
3152
- import {
3153
- Input as Input9,
3154
- Button as Button10,
3155
- Badge as Badge7,
3156
- Tooltip as Tooltip3,
3157
- TooltipTrigger as TooltipTrigger3,
3158
- TooltipContent as TooltipContent3,
3159
- Dialog as Dialog6,
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 handleConnect(cred) {
3413
- if (!config.accountId || !config.token) return;
3414
- const language = config.language ?? "pt-br";
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__ */ jsxs12("div", { className: "space-y-4", children: [
3420
- /* @__PURE__ */ jsx14("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs12("div", { className: "relative flex-1 max-w-md", children: [
3421
- /* @__PURE__ */ jsx14(Search3, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
3422
- /* @__PURE__ */ jsx14(
3423
- Input9,
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
- placeholder: "Buscar credenciais\\u2026",
3426
- "aria-label": "Buscar credenciais",
3427
- name: "search",
3428
- autoComplete: "off",
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__ */ jsx14(
3436
- DataTable3,
5041
+ ] }),
5042
+ /* @__PURE__ */ jsx22(
5043
+ ToolFormDialog,
3437
5044
  {
3438
- columns,
3439
- data: filteredCredentials,
3440
- isLoading,
3441
- emptyMessage: "Nenhuma credencial encontrada"
5045
+ open: showToolForm,
5046
+ onOpenChange: handleToolFormOpenChange,
5047
+ tool: editingTool ?? void 0,
5048
+ config
3442
5049
  }
3443
- ),
3444
- /* @__PURE__ */ jsx14(Dialog6, { open: showCreateDialog, onOpenChange: setShowCreateDialog, children: /* @__PURE__ */ jsxs12(DialogContent6, { children: [
3445
- /* @__PURE__ */ jsx14(DialogHeader6, { children: /* @__PURE__ */ jsx14(DialogTitle6, { children: "Nova Credencial" }) }),
3446
- /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
3447
- /* @__PURE__ */ jsxs12("div", { children: [
3448
- /* @__PURE__ */ jsx14("label", { htmlFor: "cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
3449
- /* @__PURE__ */ jsxs12(
3450
- Select3,
3451
- {
3452
- value: createForm.id_tool,
3453
- onValueChange: (val) => setCreateForm((f) => ({ ...f, id_tool: val })),
3454
- children: [
3455
- /* @__PURE__ */ jsx14(SelectTrigger3, { id: "cred-tool", children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
3456
- /* @__PURE__ */ jsx14(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx14(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
3457
- ]
3458
- }
3459
- )
3460
- ] }),
3461
- /* @__PURE__ */ jsxs12("div", { children: [
3462
- /* @__PURE__ */ jsx14("label", { htmlFor: "cred-label", className: "mb-1 block text-sm font-medium", children: "Label *" }),
3463
- /* @__PURE__ */ jsx14(
3464
- Input9,
3465
- {
3466
- id: "cred-label",
3467
- name: "label",
3468
- value: createForm.label,
3469
- onChange: (e) => setCreateForm((f) => ({ ...f, label: e.target.value })),
3470
- placeholder: "Ex: Google Calendar - Cl\xEDnica S\xE3o Paulo"
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__ */ jsxs12("div", { children: [
3475
- /* @__PURE__ */ jsx14("label", { htmlFor: "cred-credential", className: "mb-1 block text-sm font-medium", children: "Credencial *" }),
3476
- /* @__PURE__ */ jsx14(
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__ */ jsxs12("div", { children: [
3493
- /* @__PURE__ */ jsx14("label", { htmlFor: "cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o (opcional)" }),
3494
- /* @__PURE__ */ jsx14(
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__ */ jsxs12(DialogFooter6, { children: [
3507
- /* @__PURE__ */ jsx14(
3508
- Button10,
3509
- {
3510
- variant: "outline",
3511
- onClick: () => setShowCreateDialog(false),
3512
- children: "Cancelar"
3513
- }
3514
- ),
3515
- /* @__PURE__ */ jsx14(
3516
- Button10,
3517
- {
3518
- onClick: handleCreate,
3519
- disabled: !createForm.id_tool || !createForm.label.trim() || !createForm.credentials_encrypted.trim() || createMutation.isPending,
3520
- children: "Criar"
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__ */ jsx14(
3526
- Dialog6,
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
- open: !!editTarget,
3529
- onOpenChange: (open) => !open && setEditTarget(null),
3530
- children: /* @__PURE__ */ jsxs12(DialogContent6, { children: [
3531
- /* @__PURE__ */ jsx14(DialogHeader6, { children: /* @__PURE__ */ jsx14(DialogTitle6, { children: "Editar Credencial" }) }),
3532
- /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
3533
- /* @__PURE__ */ jsxs12("div", { children: [
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__ */ jsx14(
3627
- AlertDialog5,
5203
+ ) }),
5204
+ /* @__PURE__ */ jsx24(TabsContent2, { value: "conversas", className: "mt-4", children: /* @__PURE__ */ jsx24(
5205
+ AgentConversationsPanel,
3628
5206
  {
3629
- open: !!removeTarget,
3630
- onOpenChange: (open) => !open && setRemoveTarget(null),
3631
- children: /* @__PURE__ */ jsxs12(AlertDialogContent5, { children: [
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 useState12 } from "react";
3655
- import { Button as Button11 } from "@greatapps/greatauth-ui/ui";
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 jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
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] = useState12(false);
3665
- return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
3666
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
3667
- /* @__PURE__ */ jsxs13("div", { children: [
3668
- /* @__PURE__ */ jsx15("h1", { className: "text-xl font-semibold", children: title }),
3669
- /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: subtitle })
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__ */ jsxs13(Button11, { onClick: () => setCreateOpen(true), size: "sm", children: [
3672
- /* @__PURE__ */ jsx15(Plus3, { className: "mr-2 h-4 w-4" }),
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__ */ jsx15(AgentsTable, { config, onNavigateToAgent }),
3677
- /* @__PURE__ */ jsx15(
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 useState13 } from "react";
3690
- import { Badge as Badge8, Button as Button12, Skeleton as Skeleton6 } from "@greatapps/greatauth-ui/ui";
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 jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
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] = useState13(false);
5263
+ const [editOpen, setEditOpen] = useState17(false);
3702
5264
  if (isLoading) {
3703
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-4 p-4", children: [
3704
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-4 w-32" }),
3705
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-8 w-48" }),
3706
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-10 w-full" }),
3707
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-64 w-full" })
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__ */ jsxs14("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [
3712
- /* @__PURE__ */ jsx16("p", { className: "text-muted-foreground", children: "Agente n\xE3o encontrado" }),
3713
- onBack && /* @__PURE__ */ jsxs14(Button12, { variant: "ghost", size: "sm", onClick: onBack, children: [
3714
- /* @__PURE__ */ jsx16(ArrowLeft, { className: "mr-2 h-4 w-4" }),
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__ */ jsxs14("div", { className: "flex flex-col gap-6 p-4 md:p-6", children: [
3720
- /* @__PURE__ */ jsx16("div", { className: "rounded-lg border p-4 md:p-6", children: /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:gap-6", children: [
3721
- /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 flex-1", children: [
3722
- onBack && /* @__PURE__ */ jsx16(
3723
- Button12,
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__ */ jsx16(ArrowLeft, { className: "h-4 w-4" })
5292
+ children: /* @__PURE__ */ jsx26(ArrowLeft, { className: "h-4 w-4" })
3731
5293
  }
3732
5294
  ),
3733
- /* @__PURE__ */ jsx16(EntityAvatar2, { photo: agent.photo, name: agent.title, size: "xl" }),
3734
- /* @__PURE__ */ jsx16("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 flex-wrap", children: [
3735
- /* @__PURE__ */ jsx16("h1", { className: "text-xl font-semibold", children: agent.title }),
3736
- /* @__PURE__ */ jsx16(
3737
- Badge8,
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__ */ jsxs14(
3747
- Button12,
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__ */ jsx16(Pencil5, { className: "mr-2 h-4 w-4" }),
5316
+ /* @__PURE__ */ jsx26(Pencil5, { className: "mr-2 h-4 w-4" }),
3755
5317
  "Editar"
3756
5318
  ]
3757
5319
  }
3758
5320
  )
3759
5321
  ] }) }),
3760
- /* @__PURE__ */ jsx16(
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__ */ jsx16(
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 useState14 } from "react";
3783
- import { Button as Button13 } from "@greatapps/greatauth-ui/ui";
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 jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
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] = useState14(false);
3792
- const [editTool, setEditTool] = useState14(void 0);
3793
- return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
3794
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
3795
- /* @__PURE__ */ jsxs15("div", { children: [
3796
- /* @__PURE__ */ jsx17("h1", { className: "text-xl font-semibold", children: title }),
3797
- /* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground", children: subtitle })
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__ */ jsxs15(Button13, { onClick: () => setCreateOpen(true), size: "sm", children: [
3800
- /* @__PURE__ */ jsx17(Plus4, { className: "mr-2 h-4 w-4" }),
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__ */ jsx17(ToolsTable, { config, onEdit: (tool) => setEditTool(tool) }),
3805
- /* @__PURE__ */ jsx17(
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__ */ jsx17(
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 useState15 } from "react";
3827
- import { Button as Button14 } from "@greatapps/greatauth-ui/ui";
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 jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
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] = useState15(false);
5399
+ const [createOpen, setCreateOpen] = useState19(false);
3838
5400
  const credentials = credentialsData?.data || [];
3839
- return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
3840
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between", children: [
3841
- /* @__PURE__ */ jsxs16("div", { children: [
3842
- /* @__PURE__ */ jsx18("h1", { className: "text-xl font-semibold", children: title }),
3843
- /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: subtitle })
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__ */ jsxs16(Button14, { onClick: () => setCreateOpen(true), size: "sm", children: [
3846
- /* @__PURE__ */ jsx18(Plus5, { className: "mr-2 h-4 w-4" }),
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__ */ jsx18(
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,