@greatapps/greatagents-ui 0.3.11 → 0.3.13

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
@@ -2497,16 +2497,6 @@ function AgentConversationsPanel({
2497
2497
  ) });
2498
2498
  }
2499
2499
 
2500
- // src/pages/agent-capabilities-page.tsx
2501
- import { useState as useState13, useCallback as useCallback6 } from "react";
2502
- import {
2503
- Tabs,
2504
- TabsList,
2505
- TabsTrigger,
2506
- TabsContent
2507
- } from "@greatapps/greatauth-ui/ui";
2508
- import { Blocks, Plug as Plug3, Settings as Settings3 } from "lucide-react";
2509
-
2510
2500
  // src/components/capabilities/capabilities-tab.tsx
2511
2501
  import { useState as useState8, useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo5 } from "react";
2512
2502
  import {
@@ -2826,980 +2816,483 @@ function ModuleRow({
2826
2816
  ] });
2827
2817
  }
2828
2818
 
2829
- // src/components/capabilities/integration-card.tsx
2830
- import { Badge as Badge6, Button as Button8, Tooltip as Tooltip2, TooltipContent as TooltipContent2, TooltipTrigger as TooltipTrigger2 } from "@greatapps/greatauth-ui/ui";
2831
- import {
2832
- CalendarSync,
2833
- Plug,
2834
- Settings as Settings2,
2835
- RefreshCw,
2836
- Users as Users2,
2837
- Clock,
2838
- Plus as Plus2
2839
- } from "lucide-react";
2819
+ // src/components/capabilities/integrations-tab.tsx
2820
+ import { useCallback as useCallback5 } from "react";
2821
+ import { Switch as Switch5, Tooltip as Tooltip2, TooltipContent as TooltipContent2, TooltipTrigger as TooltipTrigger2 } from "@greatapps/greatauth-ui/ui";
2822
+ import { Plug, Loader2 as Loader25 } from "lucide-react";
2823
+ import { CalendarSync } from "lucide-react";
2840
2824
  import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
2841
2825
  var ICON_MAP = {
2842
2826
  CalendarSync,
2843
- Plug,
2844
- Settings: Settings2,
2845
- RefreshCw,
2846
- Users: Users2,
2847
- Clock,
2848
- Plus: Plus2
2827
+ Plug
2849
2828
  };
2850
2829
  function resolveIcon(name) {
2851
2830
  return ICON_MAP[name] ?? Plug;
2852
2831
  }
2853
- var STATE_BADGES = {
2854
- available: {
2855
- label: "Dispon\xEDvel",
2856
- className: "bg-muted text-muted-foreground"
2857
- },
2858
- connected: {
2859
- label: "Conectado",
2860
- className: "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
2861
- },
2862
- expired: {
2863
- label: "Expirado",
2864
- className: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
2865
- },
2866
- coming_soon: {
2867
- label: "Em breve",
2868
- className: "bg-muted text-muted-foreground"
2869
- }
2870
- };
2871
- function getActionLabel(card) {
2872
- if (card.isAddNew) return "Conectar";
2873
- switch (card.state) {
2874
- case "available":
2875
- return "Conectar";
2876
- case "connected":
2877
- return "Configurar";
2878
- case "expired":
2879
- return "Reconectar";
2880
- default:
2881
- return "";
2882
- }
2883
- }
2884
- function IntegrationCard({ card, onConnect }) {
2885
- const { definition, state, sharedByAgentsCount, isAddNew, accountLabel } = card;
2886
- const Icon = resolveIcon(definition.icon);
2887
- const isComingSoon = state === "coming_soon";
2888
- const actionLabel = getActionLabel(card);
2889
- if (isAddNew) {
2890
- return /* @__PURE__ */ jsxs9(
2891
- "div",
2892
- {
2893
- className: cn(
2894
- "group relative flex flex-col gap-3 rounded-xl border border-dashed bg-card/50 p-5 transition-shadow",
2895
- "hover:shadow-md hover:border-solid hover:bg-card cursor-pointer"
2896
- ),
2897
- role: "button",
2898
- tabIndex: 0,
2899
- "aria-label": `Adicionar conta ${definition.name}`,
2900
- onClick: () => onConnect(card),
2901
- onKeyDown: (e) => {
2902
- if (e.key === "Enter" || e.key === " ") {
2903
- e.preventDefault();
2904
- onConnect(card);
2905
- }
2906
- },
2907
- children: [
2908
- /* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between gap-2", children: [
2909
- /* @__PURE__ */ jsx11("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/5 text-primary/60", children: /* @__PURE__ */ jsx11(Icon, { className: "h-5 w-5" }) }),
2910
- /* @__PURE__ */ jsx11(Badge6, { variant: "outline", className: "text-xs bg-muted text-muted-foreground", children: "Adicionar" })
2911
- ] }),
2912
- /* @__PURE__ */ jsxs9("div", { className: "space-y-1", children: [
2913
- /* @__PURE__ */ jsx11("h3", { className: "text-sm font-semibold leading-tight text-muted-foreground", children: definition.name }),
2914
- /* @__PURE__ */ jsxs9("p", { className: "text-xs text-muted-foreground/70 leading-relaxed flex items-center gap-1", children: [
2915
- /* @__PURE__ */ jsx11(Plus2, { className: "h-3 w-3" }),
2916
- "Adicionar conta"
2917
- ] })
2918
- ] }),
2919
- /* @__PURE__ */ jsx11("div", { className: "mt-auto flex items-center justify-end pt-1", children: /* @__PURE__ */ jsx11(
2920
- Button8,
2921
- {
2922
- variant: "outline",
2923
- size: "sm",
2924
- className: "text-xs",
2925
- onClick: (e) => {
2926
- e.stopPropagation();
2927
- onConnect(card);
2928
- },
2929
- children: actionLabel
2930
- }
2931
- ) })
2932
- ]
2933
- }
2934
- );
2935
- }
2936
- const badge = STATE_BADGES[state];
2937
- return /* @__PURE__ */ jsxs9(
2938
- "div",
2939
- {
2940
- className: cn(
2941
- "group relative flex flex-col gap-3 rounded-xl border bg-card p-5 transition-shadow",
2942
- isComingSoon ? "opacity-60 cursor-default" : "hover:shadow-md cursor-pointer"
2943
- ),
2944
- role: "button",
2945
- tabIndex: isComingSoon ? -1 : 0,
2946
- "aria-label": `${definition.name}${accountLabel ? ` \u2014 ${accountLabel}` : ""} \u2014 ${badge.label}`,
2947
- "aria-disabled": isComingSoon,
2948
- onClick: () => !isComingSoon && onConnect(card),
2949
- onKeyDown: (e) => {
2950
- if (!isComingSoon && (e.key === "Enter" || e.key === " ")) {
2951
- e.preventDefault();
2952
- onConnect(card);
2953
- }
2954
- },
2955
- children: [
2956
- /* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between gap-2", children: [
2957
- /* @__PURE__ */ jsx11("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx11(Icon, { className: "h-5 w-5" }) }),
2958
- /* @__PURE__ */ jsx11(Badge6, { variant: "outline", className: cn("text-xs", badge.className), children: badge.label })
2959
- ] }),
2960
- /* @__PURE__ */ jsxs9("div", { className: "space-y-1", children: [
2961
- /* @__PURE__ */ jsx11("h3", { className: "text-sm font-semibold leading-tight", children: definition.name }),
2962
- accountLabel ? /* @__PURE__ */ jsx11("p", { className: "text-xs text-muted-foreground leading-relaxed truncate", title: accountLabel, children: accountLabel }) : /* @__PURE__ */ jsx11("p", { className: "text-xs text-muted-foreground leading-relaxed", children: definition.description })
2963
- ] }),
2964
- /* @__PURE__ */ jsxs9("div", { className: "mt-auto flex items-center justify-between gap-2 pt-1", children: [
2965
- sharedByAgentsCount > 0 ? /* @__PURE__ */ jsxs9(Tooltip2, { children: [
2966
- /* @__PURE__ */ jsx11(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs9("span", { className: "inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400", children: [
2967
- /* @__PURE__ */ jsx11(Users2, { className: "h-3.5 w-3.5" }),
2968
- "Compartilhada"
2969
- ] }) }),
2970
- /* @__PURE__ */ jsx11(TooltipContent2, { children: "Esta credencial est\xE1 dispon\xEDvel para todos os agentes da conta" })
2971
- ] }) : /* @__PURE__ */ jsx11("span", {}),
2972
- !isComingSoon && /* @__PURE__ */ jsx11(
2973
- Button8,
2974
- {
2975
- variant: state === "expired" ? "destructive" : "outline",
2976
- size: "sm",
2977
- className: "text-xs",
2978
- onClick: (e) => {
2979
- e.stopPropagation();
2980
- onConnect(card);
2981
- },
2982
- children: actionLabel
2983
- }
2984
- )
2985
- ] })
2986
- ]
2987
- }
2988
- );
2989
- }
2990
-
2991
- // src/components/capabilities/integrations-tab.tsx
2992
- import { Plug as Plug2, Loader2 as Loader25 } from "lucide-react";
2993
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2994
- function getCardKey(card) {
2995
- if (card.credentialId) {
2996
- return `${card.definition.slug}-cred-${card.credentialId}`;
2997
- }
2998
- if (card.isAddNew) {
2999
- return `${card.definition.slug}-add-new`;
3000
- }
3001
- return card.definition.slug;
3002
- }
3003
2832
  function IntegrationsTab({
3004
2833
  config,
3005
- agentId,
3006
- onConnect
2834
+ agentId
3007
2835
  }) {
3008
- const { cards, isLoading } = useIntegrationState(config, agentId);
3009
- if (isLoading) {
3010
- return /* @__PURE__ */ jsx12("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx12(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
3011
- }
3012
- if (cards.length === 0) {
3013
- return /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground", children: [
3014
- /* @__PURE__ */ jsx12(Plug2, { className: "h-10 w-10" }),
3015
- /* @__PURE__ */ jsx12("p", { className: "text-sm", children: "Nenhuma integra\xE7\xE3o dispon\xEDvel" })
3016
- ] });
3017
- }
2836
+ const { cards, isLoading } = useIntegrationState(config, null);
2837
+ const { data: toolsData } = useTools(config);
2838
+ const { data: agentToolsData, isLoading: agentToolsLoading } = useAgentTools(config, agentId);
2839
+ const addAgentTool = useAddAgentTool(config);
2840
+ const removeAgentTool = useRemoveAgentTool(config);
2841
+ const tools = toolsData?.data ?? [];
2842
+ const agentTools = agentToolsData?.data ?? [];
3018
2843
  const connectedCards = cards.filter(
3019
2844
  (c) => !c.isAddNew && (c.state === "connected" || c.state === "expired")
3020
2845
  );
3021
- const otherCards = cards.filter(
3022
- (c) => c.isAddNew || c.state === "coming_soon"
2846
+ const handleToggle = useCallback5(
2847
+ (credentialId, toolSlug, checked) => {
2848
+ const tool = tools.find((t) => t.slug === toolSlug);
2849
+ if (!tool) return;
2850
+ if (checked) {
2851
+ addAgentTool.mutate({
2852
+ idAgent: agentId,
2853
+ body: { id_tool: tool.id, enabled: true }
2854
+ });
2855
+ } else {
2856
+ const agentTool = agentTools.find((at) => at.id_tool === tool.id);
2857
+ if (agentTool) {
2858
+ removeAgentTool.mutate({ idAgent: agentId, id: agentTool.id });
2859
+ }
2860
+ }
2861
+ },
2862
+ [tools, agentTools, agentId, addAgentTool, removeAgentTool]
3023
2863
  );
3024
- return /* @__PURE__ */ jsxs10("div", { className: "space-y-6", children: [
3025
- connectedCards.length > 0 && /* @__PURE__ */ jsxs10("div", { children: [
3026
- /* @__PURE__ */ jsx12("h3", { className: "mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: "Contas conectadas" }),
3027
- /* @__PURE__ */ jsx12("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: connectedCards.map((card) => /* @__PURE__ */ jsx12(
3028
- IntegrationCard,
2864
+ if (isLoading || agentToolsLoading) {
2865
+ return /* @__PURE__ */ jsx11("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx11(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
2866
+ }
2867
+ if (connectedCards.length === 0) {
2868
+ return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground", children: [
2869
+ /* @__PURE__ */ jsx11(Plug, { className: "h-10 w-10" }),
2870
+ /* @__PURE__ */ jsx11("p", { className: "text-sm font-medium", children: "Nenhuma integra\xE7\xE3o conectada" }),
2871
+ /* @__PURE__ */ jsx11("p", { className: "text-xs text-center max-w-sm", children: "Conecte integra\xE7\xF5es na p\xE1gina de Integra\xE7\xF5es da conta para que possam ser ativadas neste agente." })
2872
+ ] });
2873
+ }
2874
+ return /* @__PURE__ */ jsxs9("div", { className: "space-y-4", children: [
2875
+ /* @__PURE__ */ jsx11("p", { className: "text-xs text-muted-foreground", children: "Ative ou desative as integra\xE7\xF5es conectadas na conta para este agente." }),
2876
+ /* @__PURE__ */ jsx11("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: connectedCards.map((card) => {
2877
+ const Icon = resolveIcon(card.definition.icon);
2878
+ const tool = tools.find((t) => t.slug === card.definition.slug);
2879
+ const isLinked = tool ? agentTools.some((at) => at.id_tool === tool.id) : false;
2880
+ const isMutating = addAgentTool.isPending || removeAgentTool.isPending;
2881
+ return /* @__PURE__ */ jsxs9(
2882
+ "div",
3029
2883
  {
3030
- card,
3031
- onConnect
2884
+ className: cn(
2885
+ "flex items-center gap-3 rounded-xl border bg-card p-4 transition-shadow",
2886
+ isLinked ? "border-primary/30 shadow-sm" : "opacity-75"
2887
+ ),
2888
+ children: [
2889
+ /* @__PURE__ */ jsx11("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx11(Icon, { className: "h-4.5 w-4.5" }) }),
2890
+ /* @__PURE__ */ jsxs9("div", { className: "flex-1 min-w-0", children: [
2891
+ /* @__PURE__ */ jsx11("h4", { className: "text-sm font-medium leading-tight truncate", children: card.definition.name }),
2892
+ card.accountLabel && /* @__PURE__ */ jsxs9(Tooltip2, { children: [
2893
+ /* @__PURE__ */ jsx11(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsx11("p", { className: "text-xs text-muted-foreground truncate", title: card.accountLabel, children: card.accountLabel }) }),
2894
+ /* @__PURE__ */ jsx11(TooltipContent2, { children: card.accountLabel })
2895
+ ] }),
2896
+ card.state === "expired" && /* @__PURE__ */ jsx11("p", { className: "text-xs text-amber-600 dark:text-amber-400", children: "Expirado" })
2897
+ ] }),
2898
+ /* @__PURE__ */ jsx11(
2899
+ Switch5,
2900
+ {
2901
+ checked: isLinked,
2902
+ disabled: isMutating,
2903
+ onCheckedChange: (checked) => card.credentialId && handleToggle(card.credentialId, card.definition.slug, checked),
2904
+ "aria-label": `${isLinked ? "Desativar" : "Ativar"} ${card.definition.name} para este agente`
2905
+ }
2906
+ )
2907
+ ]
3032
2908
  },
3033
- getCardKey(card)
3034
- )) })
2909
+ `${card.definition.slug}-cred-${card.credentialId}`
2910
+ );
2911
+ }) })
2912
+ ] });
2913
+ }
2914
+
2915
+ // src/components/agents/agent-tabs.tsx
2916
+ import {
2917
+ Tabs,
2918
+ TabsList,
2919
+ TabsTrigger,
2920
+ TabsContent
2921
+ } from "@greatapps/greatauth-ui/ui";
2922
+ import { Target as Target2, FileText as FileText2, MessageCircle as MessageCircle2, Blocks, Plug as Plug2 } from "lucide-react";
2923
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2924
+ function AgentTabs({
2925
+ agent,
2926
+ config,
2927
+ renderChatLink
2928
+ }) {
2929
+ return /* @__PURE__ */ jsxs10(Tabs, { defaultValue: "prompt", children: [
2930
+ /* @__PURE__ */ jsxs10(TabsList, { children: [
2931
+ /* @__PURE__ */ jsxs10(TabsTrigger, { value: "prompt", className: "flex items-center gap-1.5", children: [
2932
+ /* @__PURE__ */ jsx12(FileText2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2933
+ "Prompt"
2934
+ ] }),
2935
+ /* @__PURE__ */ jsxs10(TabsTrigger, { value: "objetivos", className: "flex items-center gap-1.5", children: [
2936
+ /* @__PURE__ */ jsx12(Target2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2937
+ "Objetivos"
2938
+ ] }),
2939
+ /* @__PURE__ */ jsxs10(TabsTrigger, { value: "capacidades", className: "flex items-center gap-1.5", children: [
2940
+ /* @__PURE__ */ jsx12(Blocks, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2941
+ "Capacidades"
2942
+ ] }),
2943
+ /* @__PURE__ */ jsxs10(TabsTrigger, { value: "integracoes", className: "flex items-center gap-1.5", children: [
2944
+ /* @__PURE__ */ jsx12(Plug2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2945
+ "Integra\xE7\xF5es"
2946
+ ] }),
2947
+ /* @__PURE__ */ jsxs10(TabsTrigger, { value: "conversas", className: "flex items-center gap-1.5", children: [
2948
+ /* @__PURE__ */ jsx12(MessageCircle2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2949
+ "Conversas"
2950
+ ] })
3035
2951
  ] }),
3036
- otherCards.length > 0 && /* @__PURE__ */ jsxs10("div", { children: [
3037
- connectedCards.length > 0 && /* @__PURE__ */ jsx12("h3", { className: "mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: "Adicionar integra\xE7\xE3o" }),
3038
- /* @__PURE__ */ jsx12("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: otherCards.map((card) => /* @__PURE__ */ jsx12(
3039
- IntegrationCard,
3040
- {
3041
- card,
3042
- onConnect
3043
- },
3044
- getCardKey(card)
3045
- )) })
3046
- ] })
2952
+ /* @__PURE__ */ jsx12(TabsContent, { value: "prompt", className: "mt-4", children: /* @__PURE__ */ jsx12(AgentPromptEditor, { agent, config }) }),
2953
+ /* @__PURE__ */ jsx12(TabsContent, { value: "objetivos", className: "mt-4", children: /* @__PURE__ */ jsx12(AgentObjectivesList, { agent, config }) }),
2954
+ /* @__PURE__ */ jsx12(TabsContent, { value: "capacidades", className: "mt-4", children: /* @__PURE__ */ jsx12(CapabilitiesTab, { config, agentId: agent.id }) }),
2955
+ /* @__PURE__ */ jsx12(TabsContent, { value: "integracoes", className: "mt-4", children: /* @__PURE__ */ jsx12(IntegrationsTab, { config, agentId: agent.id }) }),
2956
+ /* @__PURE__ */ jsx12(TabsContent, { value: "conversas", className: "mt-4", children: /* @__PURE__ */ jsx12(
2957
+ AgentConversationsPanel,
2958
+ {
2959
+ agent,
2960
+ config,
2961
+ renderChatLink
2962
+ }
2963
+ ) })
3047
2964
  ] });
3048
2965
  }
3049
2966
 
3050
- // src/components/capabilities/integration-wizard.tsx
3051
- import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef2, useState as useState9 } from "react";
2967
+ // src/components/agents/agent-tools-list.tsx
2968
+ import { useState as useState9 } from "react";
3052
2969
  import {
2970
+ Switch as Switch6,
2971
+ Badge as Badge6,
2972
+ Button as Button8,
2973
+ Skeleton as Skeleton6,
2974
+ AlertDialog as AlertDialog3,
2975
+ AlertDialogAction as AlertDialogAction3,
2976
+ AlertDialogCancel as AlertDialogCancel3,
2977
+ AlertDialogContent as AlertDialogContent3,
2978
+ AlertDialogDescription as AlertDialogDescription3,
2979
+ AlertDialogFooter as AlertDialogFooter3,
2980
+ AlertDialogHeader as AlertDialogHeader3,
2981
+ AlertDialogTitle as AlertDialogTitle3,
2982
+ Popover,
2983
+ PopoverContent,
2984
+ PopoverTrigger,
2985
+ Input as Input6,
2986
+ Textarea as Textarea2,
3053
2987
  Dialog as Dialog4,
3054
2988
  DialogContent as DialogContent4,
3055
- DialogFooter as DialogFooter4,
3056
2989
  DialogHeader as DialogHeader4,
3057
2990
  DialogTitle as DialogTitle4,
3058
- Button as Button10
2991
+ DialogFooter as DialogFooter4,
2992
+ Label as Label4,
2993
+ Select,
2994
+ SelectContent,
2995
+ SelectItem,
2996
+ SelectTrigger,
2997
+ SelectValue
3059
2998
  } from "@greatapps/greatauth-ui/ui";
3060
- import { Loader2 as Loader28, ChevronLeft, ChevronRight, Check as Check2 } from "lucide-react";
2999
+ import {
3000
+ Trash2 as Trash23,
3001
+ Plus as Plus2,
3002
+ Wrench,
3003
+ Settings2
3004
+ } from "lucide-react";
3061
3005
  import { toast as toast7 } from "sonner";
3062
-
3063
- // src/components/capabilities/wizard-steps/info-step.tsx
3064
- import { Check, Info } from "lucide-react";
3065
3006
  import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
3066
- function InfoStep({ integration, meta }) {
3067
- return /* @__PURE__ */ jsxs11("div", { className: "space-y-6", children: [
3068
- /* @__PURE__ */ jsxs11("div", { className: "flex items-start gap-4", children: [
3069
- meta.icon && /* @__PURE__ */ jsx13("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-muted", children: meta.icon }),
3070
- /* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
3071
- /* @__PURE__ */ jsx13("h3", { className: "text-lg font-semibold", children: integration.name }),
3072
- /* @__PURE__ */ jsx13("p", { className: "text-sm text-muted-foreground", children: integration.description })
3073
- ] })
3074
- ] }),
3075
- meta.capabilities.length > 0 && /* @__PURE__ */ jsxs11("div", { className: "space-y-3", children: [
3076
- /* @__PURE__ */ jsx13("h4", { className: "text-sm font-medium", children: "O que esta integra\xE7\xE3o permite:" }),
3077
- /* @__PURE__ */ jsx13("ul", { className: "space-y-2", children: meta.capabilities.map((cap, i) => /* @__PURE__ */ jsxs11("li", { className: "flex items-start gap-2 text-sm", children: [
3078
- /* @__PURE__ */ jsx13(
3079
- Check,
3080
- {
3081
- "aria-hidden": "true",
3082
- className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
3083
- }
3084
- ),
3085
- /* @__PURE__ */ jsxs11("div", { children: [
3086
- /* @__PURE__ */ jsx13("span", { className: "font-medium", children: cap.label }),
3087
- cap.description && /* @__PURE__ */ jsxs11("span", { className: "text-muted-foreground", children: [
3088
- " ",
3089
- "\u2014 ",
3090
- cap.description
3091
- ] })
3092
- ] })
3093
- ] }, i)) })
3094
- ] }),
3095
- meta.requirements.length > 0 && /* @__PURE__ */ jsxs11("div", { className: "space-y-3", children: [
3096
- /* @__PURE__ */ jsx13("h4", { className: "text-sm font-medium", children: "Requisitos:" }),
3097
- /* @__PURE__ */ jsx13("ul", { className: "space-y-2", children: meta.requirements.map((req, i) => /* @__PURE__ */ jsxs11(
3098
- "li",
3099
- {
3100
- className: "flex items-start gap-2 text-sm text-muted-foreground",
3101
- children: [
3102
- /* @__PURE__ */ jsx13(
3103
- Info,
3104
- {
3105
- "aria-hidden": "true",
3106
- className: "mt-0.5 h-4 w-4 shrink-0 text-blue-500"
3107
- }
3108
- ),
3109
- /* @__PURE__ */ jsx13("span", { children: req })
3110
- ]
3111
- },
3112
- i
3113
- )) })
3114
- ] })
3115
- ] });
3116
- }
3117
-
3118
- // src/components/capabilities/wizard-steps/credentials-step.tsx
3119
- import { CheckCircle2, Loader2 as Loader26, AlertCircle, Shield } from "lucide-react";
3120
- import { Button as Button9, Input as Input6, Label as Label4 } from "@greatapps/greatauth-ui/ui";
3121
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
3122
- function CredentialsStep({
3123
- integration,
3124
- meta,
3125
- oauthStatus,
3126
- oauthResult,
3127
- apiKey,
3128
- onApiKeyChange,
3129
- onStartOAuth,
3130
- isReconnect = false
3131
- }) {
3132
- if (integration.authType === "oauth2") {
3133
- return /* @__PURE__ */ jsx14(
3134
- OAuthCredentials,
3135
- {
3136
- integration,
3137
- meta,
3138
- oauthStatus,
3139
- oauthResult,
3140
- onStartOAuth,
3141
- isReconnect
3142
- }
3143
- );
3144
- }
3145
- return /* @__PURE__ */ jsx14(ApiKeyCredentials, { apiKey, onApiKeyChange });
3146
- }
3147
- function OAuthCredentials({
3148
- integration,
3149
- meta,
3150
- oauthStatus,
3151
- oauthResult,
3152
- onStartOAuth,
3153
- isReconnect
3154
- }) {
3155
- const providerLabel = meta.providerLabel || integration.name;
3156
- return /* @__PURE__ */ jsxs12("div", { className: "space-y-6", children: [
3157
- /* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
3158
- /* @__PURE__ */ jsx14("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
3159
- /* @__PURE__ */ jsx14("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.` })
3160
- ] }),
3161
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center gap-4 rounded-lg border p-6", children: [
3162
- oauthStatus === "idle" && /* @__PURE__ */ jsxs12(
3163
- Button9,
3164
- {
3165
- onClick: onStartOAuth,
3166
- size: "lg",
3167
- className: "gap-2",
3168
- children: [
3169
- meta.icon,
3170
- isReconnect ? `Reconectar com ${providerLabel}` : `Conectar com ${providerLabel}`
3171
- ]
3172
- }
3173
- ),
3174
- oauthStatus === "waiting" && /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center gap-3 text-center", children: [
3175
- /* @__PURE__ */ jsx14(
3176
- Loader26,
3177
- {
3178
- "aria-hidden": "true",
3179
- className: "h-8 w-8 animate-spin text-muted-foreground"
3180
- }
3181
- ),
3182
- /* @__PURE__ */ jsxs12("div", { children: [
3183
- /* @__PURE__ */ jsx14("p", { className: "text-sm font-medium", children: "Aguardando autoriza\xE7\xE3o..." }),
3184
- /* @__PURE__ */ jsx14("p", { className: "text-xs text-muted-foreground", children: "Complete o login na janela que foi aberta." })
3185
- ] })
3186
- ] }),
3187
- oauthStatus === "success" && oauthResult && /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center gap-3 text-center", children: [
3188
- /* @__PURE__ */ jsx14(
3189
- CheckCircle2,
3190
- {
3191
- "aria-hidden": "true",
3192
- className: "h-8 w-8 text-green-600"
3193
- }
3194
- ),
3195
- /* @__PURE__ */ jsxs12("div", { children: [
3196
- /* @__PURE__ */ jsx14("p", { className: "text-sm font-medium text-green-700", children: "Conectado com sucesso!" }),
3197
- oauthResult.email && /* @__PURE__ */ jsx14("p", { className: "text-xs text-muted-foreground", children: oauthResult.email })
3198
- ] })
3199
- ] }),
3200
- oauthStatus === "error" && /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center gap-3 text-center", children: [
3201
- /* @__PURE__ */ jsx14(
3202
- AlertCircle,
3203
- {
3204
- "aria-hidden": "true",
3205
- className: "h-8 w-8 text-destructive"
3206
- }
3207
- ),
3208
- /* @__PURE__ */ jsxs12("div", { children: [
3209
- /* @__PURE__ */ jsx14("p", { className: "text-sm font-medium text-destructive", children: "Falha na conex\xE3o" }),
3210
- oauthResult?.error && /* @__PURE__ */ jsx14("p", { className: "text-xs text-muted-foreground", children: oauthResult.error })
3211
- ] }),
3212
- /* @__PURE__ */ jsx14(Button9, { variant: "outline", onClick: onStartOAuth, size: "sm", children: "Tentar novamente" })
3213
- ] })
3214
- ] }),
3215
- /* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
3216
- /* @__PURE__ */ jsx14(
3217
- Shield,
3218
- {
3219
- "aria-hidden": "true",
3220
- className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
3221
- }
3222
- ),
3223
- /* @__PURE__ */ jsxs12("p", { className: "text-xs text-muted-foreground", children: [
3224
- "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 ",
3225
- providerLabel,
3226
- "."
3227
- ] })
3228
- ] })
3229
- ] });
3230
- }
3231
- function ApiKeyCredentials({
3232
- apiKey,
3233
- onApiKeyChange
3234
- }) {
3235
- return /* @__PURE__ */ jsxs12("div", { className: "space-y-6", children: [
3236
- /* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
3237
- /* @__PURE__ */ jsx14("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
3238
- /* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground", children: "Insira a chave de API para conectar a integra\xE7\xE3o." })
3239
- ] }),
3240
- /* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
3241
- /* @__PURE__ */ jsx14(Label4, { htmlFor: "integration-api-key", children: "Chave de API" }),
3242
- /* @__PURE__ */ jsx14(
3243
- Input6,
3244
- {
3245
- id: "integration-api-key",
3246
- type: "password",
3247
- autoComplete: "off",
3248
- placeholder: "Insira sua chave de API...",
3249
- value: apiKey,
3250
- onChange: (e) => onApiKeyChange(e.target.value)
3251
- }
3252
- )
3253
- ] }),
3254
- /* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
3255
- /* @__PURE__ */ jsx14(
3256
- Shield,
3257
- {
3258
- "aria-hidden": "true",
3259
- className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
3260
- }
3261
- ),
3262
- /* @__PURE__ */ jsx14("p", { className: "text-xs text-muted-foreground", children: "Sua chave de API \xE9 armazenada de forma segura e encriptada. Nunca \xE9 exposta no frontend." })
3263
- ] })
3264
- ] });
3265
- }
3266
-
3267
- // src/components/capabilities/wizard-steps/config-step.tsx
3268
- import { Loader2 as Loader27 } from "lucide-react";
3269
- import {
3270
- Label as Label5,
3271
- Select,
3272
- SelectContent,
3273
- SelectItem,
3274
- SelectTrigger,
3275
- SelectValue
3276
- } from "@greatapps/greatauth-ui/ui";
3277
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
3278
- function ConfigStep({
3279
- integration,
3280
- options,
3281
- isLoading,
3282
- selectedValue,
3283
- onValueChange,
3284
- selectLabel,
3285
- selectPlaceholder
3286
- }) {
3287
- const label = selectLabel || getDefaultLabel(integration.slug);
3288
- const placeholder = selectPlaceholder || getDefaultPlaceholder(integration.slug);
3289
- return /* @__PURE__ */ jsxs13("div", { className: "space-y-6", children: [
3290
- /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3291
- /* @__PURE__ */ jsx15("h3", { className: "text-lg font-semibold", children: "Configura\xE7\xE3o" }),
3292
- /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "Configure as op\xE7\xF5es espec\xEDficas da integra\xE7\xE3o." })
3293
- ] }),
3294
- isLoading ? /* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-center gap-3 py-8", children: [
3295
- /* @__PURE__ */ jsx15(
3296
- Loader27,
3297
- {
3298
- "aria-hidden": "true",
3299
- className: "h-6 w-6 animate-spin text-muted-foreground"
3300
- }
3301
- ),
3302
- /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "Carregando op\xE7\xF5es..." })
3303
- ] }) : options.length === 0 ? /* @__PURE__ */ jsx15("div", { className: "rounded-lg border border-dashed p-6 text-center", children: /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "Nenhuma op\xE7\xE3o dispon\xEDvel. A configura\xE7\xE3o padr\xE3o ser\xE1 usada." }) }) : /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3304
- /* @__PURE__ */ jsx15(Label5, { htmlFor: "integration-config-select", children: label }),
3305
- /* @__PURE__ */ jsxs13(Select, { value: selectedValue, onValueChange, children: [
3306
- /* @__PURE__ */ jsx15(SelectTrigger, { id: "integration-config-select", children: /* @__PURE__ */ jsx15(SelectValue, { placeholder }) }),
3307
- /* @__PURE__ */ jsx15(SelectContent, { children: options.map((opt) => /* @__PURE__ */ jsxs13(SelectItem, { value: opt.id, children: [
3308
- /* @__PURE__ */ jsx15("span", { children: opt.label }),
3309
- opt.description && /* @__PURE__ */ jsxs13("span", { className: "ml-2 text-xs text-muted-foreground", children: [
3310
- "(",
3311
- opt.description,
3312
- ")"
3313
- ] })
3314
- ] }, opt.id)) })
3315
- ] })
3316
- ] })
3317
- ] });
3318
- }
3319
- function getDefaultLabel(slug) {
3320
- switch (slug) {
3321
- case "google_calendar":
3322
- return "Calend\xE1rio";
3323
- default:
3324
- return "Op\xE7\xE3o";
3325
- }
3326
- }
3327
- function getDefaultPlaceholder(slug) {
3328
- switch (slug) {
3329
- case "google_calendar":
3330
- return "Selecione o calend\xE1rio...";
3331
- default:
3332
- return "Selecione uma op\xE7\xE3o...";
3333
- }
3334
- }
3335
-
3336
- // src/components/capabilities/wizard-steps/confirm-step.tsx
3337
- import { CheckCircle2 as CheckCircle22 } from "lucide-react";
3338
- import { Label as Label6 } from "@greatapps/greatauth-ui/ui";
3339
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
3340
- function ConfirmStep({
3341
- integration,
3342
- oauthResult,
3343
- selectedConfigOption,
3344
- enableOnComplete,
3345
- onEnableChange
3346
- }) {
3347
- return /* @__PURE__ */ jsxs14("div", { className: "space-y-6", children: [
3348
- /* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
3349
- /* @__PURE__ */ jsx16("h3", { className: "text-lg font-semibold", children: "Confirma\xE7\xE3o" }),
3350
- /* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground", children: "Revise as configura\xE7\xF5es antes de concluir." })
3351
- ] }),
3352
- /* @__PURE__ */ jsxs14("div", { className: "space-y-3 rounded-lg border p-4", children: [
3353
- /* @__PURE__ */ jsx16(SummaryRow, { label: "Integra\xE7\xE3o", value: integration.name }),
3354
- oauthResult?.email && /* @__PURE__ */ jsx16(SummaryRow, { label: "Conta conectada", value: oauthResult.email }),
3355
- selectedConfigOption && /* @__PURE__ */ jsx16(
3356
- SummaryRow,
3357
- {
3358
- label: getConfigLabel(integration.slug),
3359
- value: selectedConfigOption.label
3360
- }
3361
- ),
3362
- /* @__PURE__ */ jsx16(
3363
- SummaryRow,
3364
- {
3365
- label: "Tipo de autentica\xE7\xE3o",
3366
- value: integration.authType === "oauth2" ? "OAuth 2.0" : "API Key"
3367
- }
3368
- )
3369
- ] }),
3370
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between rounded-lg border p-4", children: [
3371
- /* @__PURE__ */ jsxs14("div", { className: "space-y-0.5", children: [
3372
- /* @__PURE__ */ jsx16(Label6, { htmlFor: "enable-on-complete", className: "text-sm font-medium", children: "Ativar imediatamente" }),
3373
- /* @__PURE__ */ jsx16("p", { className: "text-xs text-muted-foreground", children: "A integra\xE7\xE3o ficar\xE1 ativa assim que concluir o assistente." })
3374
- ] }),
3375
- /* @__PURE__ */ jsx16(
3376
- "button",
3377
- {
3378
- id: "enable-on-complete",
3379
- role: "switch",
3380
- type: "button",
3381
- "aria-checked": enableOnComplete,
3382
- onClick: () => onEnableChange(!enableOnComplete),
3383
- className: `
3384
- relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent
3385
- transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2
3386
- focus-visible:ring-ring focus-visible:ring-offset-2
3387
- ${enableOnComplete ? "bg-primary" : "bg-muted"}
3388
- `,
3389
- children: /* @__PURE__ */ jsx16(
3390
- "span",
3391
- {
3392
- "aria-hidden": "true",
3393
- className: `
3394
- pointer-events-none inline-block h-5 w-5 transform rounded-full bg-background shadow-lg
3395
- ring-0 transition duration-200 ease-in-out
3396
- ${enableOnComplete ? "translate-x-5" : "translate-x-0"}
3397
- `
3398
- }
3399
- )
3400
- }
3401
- )
3402
- ] }),
3403
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 rounded-md bg-green-50 p-3 dark:bg-green-950/20", children: [
3404
- /* @__PURE__ */ jsx16(
3405
- CheckCircle22,
3406
- {
3407
- "aria-hidden": "true",
3408
- className: "h-4 w-4 shrink-0 text-green-600"
3409
- }
3410
- ),
3411
- /* @__PURE__ */ jsx16("p", { className: "text-xs text-green-700 dark:text-green-400", children: 'Tudo pronto! Clique em "Concluir" para finalizar a configura\xE7\xE3o.' })
3412
- ] })
3413
- ] });
3414
- }
3415
- function SummaryRow({ label, value }) {
3416
- return /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between text-sm", children: [
3417
- /* @__PURE__ */ jsx16("span", { className: "text-muted-foreground", children: label }),
3418
- /* @__PURE__ */ jsx16("span", { className: "font-medium", children: value })
3419
- ] });
3420
- }
3421
- function getConfigLabel(slug) {
3422
- switch (slug) {
3423
- case "google_calendar":
3424
- return "Calend\xE1rio";
3425
- default:
3426
- return "Configura\xE7\xE3o";
3427
- }
3428
- }
3429
-
3430
- // src/components/capabilities/integration-wizard.tsx
3431
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
3432
- var STEPS = ["info", "credentials", "config", "confirm"];
3433
- var STEP_LABELS = {
3434
- info: "Informa\xE7\xE3o",
3435
- credentials: "Credenciais",
3436
- config: "Configura\xE7\xE3o",
3437
- confirm: "Confirma\xE7\xE3o"
3438
- };
3439
- function IntegrationWizard({
3440
- open,
3441
- onOpenChange,
3442
- integration,
3443
- meta,
3444
- agentId: _agentId,
3445
- config,
3446
- onComplete,
3447
- gagentsApiUrl,
3448
- existingCredentialId,
3449
- loadConfigOptions,
3450
- existingConfigValue
3451
- }) {
3452
- const isReconnect = !!existingCredentialId;
3453
- const [currentStep, setCurrentStep] = useState9("info");
3454
- const currentIndex = STEPS.indexOf(currentStep);
3455
- const [oauthStatus, setOauthStatus] = useState9("idle");
3456
- const [oauthResult, setOauthResult] = useState9(null);
3457
- const popupRef = useRef2(null);
3458
- const popupPollRef = useRef2(null);
3459
- const [apiKey, setApiKey] = useState9("");
3460
- const [configOptions, setConfigOptions] = useState9([]);
3461
- const [configLoading, setConfigLoading] = useState9(false);
3462
- const [selectedConfigValue, setSelectedConfigValue] = useState9("");
3463
- const [enableOnComplete, setEnableOnComplete] = useState9(true);
3464
- const [isSubmitting, setIsSubmitting] = useState9(false);
3465
- useEffect5(() => {
3466
- return () => {
3467
- if (popupPollRef.current) {
3468
- clearInterval(popupPollRef.current);
3469
- }
3470
- };
3471
- }, []);
3472
- useEffect5(() => {
3473
- if (open) {
3474
- setCurrentStep("info");
3475
- setOauthStatus("idle");
3476
- setOauthResult(null);
3477
- setApiKey("");
3478
- setConfigOptions([]);
3479
- setConfigLoading(false);
3480
- setSelectedConfigValue(existingConfigValue ?? "");
3481
- setEnableOnComplete(true);
3482
- setIsSubmitting(false);
3483
- } else {
3484
- if (popupRef.current && !popupRef.current.closed) {
3485
- popupRef.current.close();
3486
- }
3487
- if (popupPollRef.current) {
3488
- clearInterval(popupPollRef.current);
3489
- popupPollRef.current = null;
3490
- }
3491
- }
3492
- }, [open]);
3493
- const handleOAuthMessage = useCallback5(
3494
- (event) => {
3495
- try {
3496
- if (event.origin !== new URL(gagentsApiUrl).origin) return;
3497
- } catch {
3498
- return;
3499
- }
3500
- if (!event.data || typeof event.data !== "object") return;
3501
- const msg = event.data;
3502
- if (msg.type !== "oauth-callback") return;
3503
- if (msg.success) {
3504
- setOauthStatus("success");
3505
- setOauthResult({
3506
- success: true,
3507
- email: msg.email,
3508
- credentialId: msg.credentialId
3509
- });
3510
- const credId = msg.credentialId || existingCredentialId;
3511
- if (credId && loadConfigOptions && meta.hasConfigStep) {
3512
- setConfigLoading(true);
3513
- loadConfigOptions(credId).then((opts) => {
3514
- setConfigOptions(opts);
3515
- if (opts.length === 1) {
3516
- setSelectedConfigValue(opts[0].id);
3517
- }
3518
- }).catch(() => setConfigOptions([])).finally(() => setConfigLoading(false));
3519
- }
3520
- setTimeout(() => {
3521
- setCurrentStep(meta.hasConfigStep ? "config" : "confirm");
3522
- }, 1200);
3523
- } else {
3524
- setOauthStatus("error");
3525
- setOauthResult({
3526
- success: false,
3527
- error: msg.error || "Falha na autoriza\xE7\xE3o"
3528
- });
3529
- }
3530
- },
3531
- [gagentsApiUrl, existingCredentialId, meta.hasConfigStep, loadConfigOptions]
3007
+ function AgentToolsList({ agent, config }) {
3008
+ const { data: agentToolsData, isLoading } = useAgentTools(config, agent.id);
3009
+ const { data: allToolsData } = useTools(config);
3010
+ const addMutation = useAddAgentTool(config);
3011
+ const removeMutation = useRemoveAgentTool(config);
3012
+ const updateMutation = useUpdateAgentTool(config);
3013
+ const [removeTarget, setRemoveTarget] = useState9(null);
3014
+ const [addOpen, setAddOpen] = useState9(false);
3015
+ const [search, setSearch] = useState9("");
3016
+ const [configTarget, setConfigTarget] = useState9(null);
3017
+ const [configInstructions, setConfigInstructions] = useState9("");
3018
+ const [configCredentialId, setConfigCredentialId] = useState9("");
3019
+ const { data: credentialsData } = useToolCredentials(config);
3020
+ const allCredentials = credentialsData?.data || [];
3021
+ const agentTools = agentToolsData?.data || [];
3022
+ const allTools = (allToolsData?.data || []).filter((t) => !t.slug?.startsWith("gclinic_"));
3023
+ const assignedToolIds = new Set(agentTools.map((at) => at.id_tool));
3024
+ const visibleAgentTools = agentTools.filter((at) => {
3025
+ const tool = allTools.find((t) => t.id === at.id_tool);
3026
+ return !tool || !tool.slug?.startsWith("gclinic_");
3027
+ });
3028
+ const availableTools = allTools.filter((t) => !assignedToolIds.has(t.id));
3029
+ const filteredAvailable = availableTools.filter(
3030
+ (t) => t.name.toLowerCase().includes(search.toLowerCase())
3532
3031
  );
3533
- useEffect5(() => {
3534
- if (!open) return;
3535
- window.addEventListener("message", handleOAuthMessage);
3536
- return () => window.removeEventListener("message", handleOAuthMessage);
3537
- }, [open, handleOAuthMessage]);
3538
- async function startOAuth() {
3539
- const { language = "pt-br", idWl = 1, accountId, token } = config;
3540
- setOauthStatus("waiting");
3032
+ function getToolInfo(idTool) {
3033
+ return allTools.find((t) => t.id === idTool);
3034
+ }
3035
+ async function handleToggleEnabled(agentTool, checked) {
3541
3036
  try {
3542
- let authorizeUrl = `${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${accountId}/oauth/authorize/${integration.slug}`;
3543
- if (existingCredentialId) {
3544
- authorizeUrl += `?credential_id=${existingCredentialId}`;
3545
- }
3546
- const response = await fetch(authorizeUrl, {
3547
- headers: { Authorization: `Bearer ${token}` }
3037
+ await updateMutation.mutateAsync({
3038
+ idAgent: agent.id,
3039
+ id: agentTool.id,
3040
+ body: { enabled: checked }
3548
3041
  });
3549
- const result = await response.json();
3550
- if (result.status !== 1 || !result.data?.auth_url) {
3551
- setOauthStatus("error");
3552
- setOauthResult({
3553
- success: false,
3554
- error: result.message || "Erro ao obter URL de autoriza\xE7\xE3o"
3555
- });
3556
- return;
3557
- }
3558
- const popup = window.open(
3559
- result.data.auth_url,
3560
- "oauth-popup",
3561
- "width=500,height=600,scrollbars=yes,resizable=yes"
3562
- );
3563
- popupRef.current = popup;
3564
- if (popup) {
3565
- if (popupPollRef.current) {
3566
- clearInterval(popupPollRef.current);
3567
- }
3568
- popupPollRef.current = setInterval(() => {
3569
- if (popup.closed) {
3570
- if (popupPollRef.current) {
3571
- clearInterval(popupPollRef.current);
3572
- popupPollRef.current = null;
3573
- }
3574
- setOauthStatus(
3575
- (prev) => prev === "waiting" ? "error" : prev
3576
- );
3577
- setOauthResult(
3578
- (prev) => prev === null ? { success: false, error: "Janela fechada antes de concluir" } : prev
3579
- );
3580
- }
3581
- }, 500);
3582
- }
3042
+ toast7.success(checked ? "Ferramenta ativada" : "Ferramenta desativada");
3583
3043
  } catch (err) {
3584
- setOauthStatus("error");
3585
- setOauthResult({
3586
- success: false,
3587
- error: "Erro de rede ao obter URL de autoriza\xE7\xE3o"
3588
- });
3589
- }
3590
- }
3591
- function canAdvance() {
3592
- switch (currentStep) {
3593
- case "info":
3594
- return true;
3595
- case "credentials":
3596
- if (integration.authType === "oauth2") {
3597
- return oauthStatus === "success";
3598
- }
3599
- return apiKey.trim().length > 0;
3600
- case "config":
3601
- return true;
3602
- case "confirm":
3603
- return true;
3604
- default:
3605
- return false;
3606
- }
3607
- }
3608
- function goNext() {
3609
- if (!canAdvance()) return;
3610
- if (currentStep === "credentials" && !meta.hasConfigStep) {
3611
- setCurrentStep("confirm");
3612
- return;
3613
- }
3614
- const nextIndex = currentIndex + 1;
3615
- if (nextIndex < STEPS.length) {
3616
- setCurrentStep(STEPS[nextIndex]);
3044
+ toast7.error(
3045
+ err instanceof Error ? err.message : "Erro ao alterar estado da ferramenta"
3046
+ );
3617
3047
  }
3618
3048
  }
3619
- function goPrev() {
3620
- if (currentStep === "confirm" && !meta.hasConfigStep) {
3621
- setCurrentStep("credentials");
3622
- return;
3623
- }
3624
- const prevIndex = currentIndex - 1;
3625
- if (prevIndex >= 0) {
3626
- setCurrentStep(STEPS[prevIndex]);
3049
+ async function handleAdd(tool) {
3050
+ try {
3051
+ await addMutation.mutateAsync({
3052
+ idAgent: agent.id,
3053
+ body: { id_tool: tool.id }
3054
+ });
3055
+ toast7.success("Ferramenta adicionada");
3056
+ setAddOpen(false);
3057
+ setSearch("");
3058
+ } catch (err) {
3059
+ toast7.error(
3060
+ err instanceof Error ? err.message : "Erro ao adicionar ferramenta"
3061
+ );
3627
3062
  }
3628
3063
  }
3629
- async function handleComplete() {
3630
- setIsSubmitting(true);
3064
+ async function handleRemove() {
3065
+ if (!removeTarget) return;
3631
3066
  try {
3632
- onComplete();
3633
- onOpenChange(false);
3634
- toast7.success(
3635
- `${integration.name} ${isReconnect ? "reconectado" : "configurado"} com sucesso!`
3067
+ await removeMutation.mutateAsync({
3068
+ idAgent: agent.id,
3069
+ id: removeTarget.id
3070
+ });
3071
+ toast7.success("Ferramenta removida");
3072
+ } catch (err) {
3073
+ toast7.error(
3074
+ err instanceof Error ? err.message : "Erro ao remover ferramenta"
3636
3075
  );
3637
- } catch {
3638
- toast7.error("Erro ao finalizar configura\xE7\xE3o");
3639
3076
  } finally {
3640
- setIsSubmitting(false);
3077
+ setRemoveTarget(null);
3641
3078
  }
3642
3079
  }
3643
- const selectedConfigOption = configOptions.find((o) => o.id === selectedConfigValue) || null;
3644
- const isLastStep = currentStep === "confirm";
3645
- const effectiveSteps = meta.hasConfigStep ? STEPS : STEPS.filter((s) => s !== "config");
3646
- return /* @__PURE__ */ jsx17(Dialog4, { open, onOpenChange, children: /* @__PURE__ */ jsxs15(DialogContent4, { className: "sm:max-w-lg", children: [
3647
- /* @__PURE__ */ jsx17(DialogHeader4, { children: /* @__PURE__ */ jsx17(DialogTitle4, { children: integration.name }) }),
3648
- /* @__PURE__ */ jsx17(StepIndicator, { steps: effectiveSteps, currentStep }),
3649
- /* @__PURE__ */ jsxs15("div", { className: "min-h-[280px] py-2", children: [
3650
- currentStep === "info" && /* @__PURE__ */ jsx17(
3651
- InfoStep,
3652
- {
3653
- integration,
3654
- meta
3655
- }
3656
- ),
3657
- currentStep === "credentials" && /* @__PURE__ */ jsx17(
3658
- CredentialsStep,
3659
- {
3660
- integration,
3661
- meta,
3662
- oauthStatus,
3663
- oauthResult,
3664
- apiKey,
3665
- onApiKeyChange: setApiKey,
3666
- onStartOAuth: startOAuth,
3667
- isReconnect
3668
- }
3669
- ),
3670
- currentStep === "config" && /* @__PURE__ */ jsx17(
3671
- ConfigStep,
3672
- {
3673
- integration,
3674
- options: configOptions,
3675
- isLoading: configLoading,
3676
- selectedValue: selectedConfigValue,
3677
- onValueChange: setSelectedConfigValue
3678
- }
3679
- ),
3680
- currentStep === "confirm" && /* @__PURE__ */ jsx17(
3681
- ConfirmStep,
3682
- {
3683
- integration,
3684
- oauthResult,
3685
- selectedConfigOption,
3686
- enableOnComplete,
3687
- onEnableChange: setEnableOnComplete
3080
+ function openConfig(agentTool) {
3081
+ setConfigTarget(agentTool);
3082
+ setConfigInstructions(agentTool.custom_instructions || "");
3083
+ setConfigCredentialId(agentTool.id_tool_credential ? String(agentTool.id_tool_credential) : "");
3084
+ }
3085
+ async function handleSaveConfig() {
3086
+ if (!configTarget) return;
3087
+ try {
3088
+ const newCredentialId = configCredentialId ? parseInt(configCredentialId, 10) : null;
3089
+ await updateMutation.mutateAsync({
3090
+ idAgent: agent.id,
3091
+ id: configTarget.id,
3092
+ body: {
3093
+ custom_instructions: configInstructions.trim() || null,
3094
+ id_tool_credential: newCredentialId
3688
3095
  }
3689
- )
3096
+ });
3097
+ toast7.success("Configura\xE7\xE3o atualizada");
3098
+ setConfigTarget(null);
3099
+ } catch (err) {
3100
+ toast7.error(
3101
+ err instanceof Error ? err.message : "Erro ao atualizar configura\xE7\xE3o"
3102
+ );
3103
+ }
3104
+ }
3105
+ if (isLoading) {
3106
+ return /* @__PURE__ */ jsx13("div", { className: "space-y-3 p-4", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx13(Skeleton6, { className: "h-14 w-full" }, i)) });
3107
+ }
3108
+ return /* @__PURE__ */ jsxs11("div", { className: "space-y-4 p-4", children: [
3109
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between", children: [
3110
+ /* @__PURE__ */ jsxs11("h3", { className: "text-sm font-medium text-muted-foreground", children: [
3111
+ visibleAgentTools.length,
3112
+ " ferramenta",
3113
+ visibleAgentTools.length !== 1 ? "s" : "",
3114
+ " associada",
3115
+ visibleAgentTools.length !== 1 ? "s" : ""
3116
+ ] }),
3117
+ /* @__PURE__ */ jsxs11(Popover, { open: addOpen, onOpenChange: setAddOpen, children: [
3118
+ /* @__PURE__ */ jsx13(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(Button8, { size: "sm", disabled: availableTools.length === 0, children: [
3119
+ /* @__PURE__ */ jsx13(Plus2, { className: "mr-2 h-4 w-4" }),
3120
+ "Adicionar Ferramenta"
3121
+ ] }) }),
3122
+ /* @__PURE__ */ jsxs11(PopoverContent, { className: "w-72 p-0", align: "end", children: [
3123
+ /* @__PURE__ */ jsx13("div", { className: "p-2", children: /* @__PURE__ */ jsx13(
3124
+ Input6,
3125
+ {
3126
+ placeholder: "Buscar ferramenta\\u2026",
3127
+ "aria-label": "Buscar ferramenta",
3128
+ name: "search",
3129
+ value: search,
3130
+ onChange: (e) => setSearch(e.target.value),
3131
+ className: "h-8"
3132
+ }
3133
+ ) }),
3134
+ /* @__PURE__ */ jsx13("div", { className: "max-h-48 overflow-y-auto", children: filteredAvailable.length === 0 ? /* @__PURE__ */ jsx13("p", { className: "p-3 text-center text-sm text-muted-foreground", children: "Nenhuma ferramenta dispon\xEDvel" }) : filteredAvailable.map((tool) => /* @__PURE__ */ jsxs11(
3135
+ "button",
3136
+ {
3137
+ type: "button",
3138
+ className: "flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-accent",
3139
+ onClick: () => handleAdd(tool),
3140
+ disabled: addMutation.isPending,
3141
+ children: [
3142
+ /* @__PURE__ */ jsx13(Wrench, { className: "h-4 w-4 text-muted-foreground" }),
3143
+ /* @__PURE__ */ jsx13("span", { className: "flex-1 font-medium", children: tool.name }),
3144
+ /* @__PURE__ */ jsx13(Badge6, { variant: "secondary", className: "text-xs", children: tool.type })
3145
+ ]
3146
+ },
3147
+ tool.id
3148
+ )) })
3149
+ ] })
3150
+ ] })
3690
3151
  ] }),
3691
- /* @__PURE__ */ jsxs15(DialogFooter4, { className: "flex-row justify-between sm:justify-between", children: [
3692
- /* @__PURE__ */ jsx17("div", { children: currentStep === "info" ? /* @__PURE__ */ jsx17(
3693
- Button10,
3694
- {
3695
- type: "button",
3696
- variant: "outline",
3697
- onClick: () => onOpenChange(false),
3698
- children: "Cancelar"
3699
- }
3700
- ) : /* @__PURE__ */ jsxs15(
3701
- Button10,
3702
- {
3703
- type: "button",
3704
- variant: "outline",
3705
- onClick: goPrev,
3706
- className: "gap-1",
3707
- children: [
3708
- /* @__PURE__ */ jsx17(ChevronLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
3709
- "Voltar"
3710
- ]
3711
- }
3712
- ) }),
3713
- /* @__PURE__ */ jsx17("div", { children: isLastStep ? /* @__PURE__ */ jsxs15(
3714
- Button10,
3152
+ visibleAgentTools.length === 0 ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col items-center justify-center rounded-lg border border-dashed p-8 text-center", children: [
3153
+ /* @__PURE__ */ jsx13(Wrench, { className: "mb-2 h-8 w-8 text-muted-foreground" }),
3154
+ /* @__PURE__ */ jsx13("p", { className: "text-sm text-muted-foreground", children: "Nenhuma ferramenta associada. Clique em 'Adicionar Ferramenta' para come\xE7ar." })
3155
+ ] }) : /* @__PURE__ */ jsx13("div", { className: "space-y-2", children: visibleAgentTools.map((agentTool) => {
3156
+ const tool = getToolInfo(agentTool.id_tool);
3157
+ return /* @__PURE__ */ jsxs11(
3158
+ "div",
3715
3159
  {
3716
- type: "button",
3717
- onClick: handleComplete,
3718
- disabled: isSubmitting,
3719
- className: "gap-1",
3160
+ className: "flex items-center gap-3 rounded-lg border bg-card p-3",
3720
3161
  children: [
3721
- isSubmitting ? /* @__PURE__ */ jsx17(
3722
- Loader28,
3162
+ /* @__PURE__ */ jsxs11("div", { className: "flex flex-1 flex-col gap-1 min-w-0", children: [
3163
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
3164
+ /* @__PURE__ */ jsx13("span", { className: "truncate font-medium", children: tool?.name || `Ferramenta #${agentTool.id_tool}` }),
3165
+ tool?.type && /* @__PURE__ */ jsx13(Badge6, { variant: "secondary", className: "shrink-0 text-xs", children: tool.type })
3166
+ ] }),
3167
+ agentTool.custom_instructions && /* @__PURE__ */ jsx13("p", { className: "truncate text-xs text-muted-foreground", children: agentTool.custom_instructions })
3168
+ ] }),
3169
+ /* @__PURE__ */ jsx13(
3170
+ Switch6,
3723
3171
  {
3724
- "aria-hidden": "true",
3725
- className: "h-4 w-4 animate-spin"
3172
+ "aria-label": "Ativar/Desativar",
3173
+ checked: agentTool.enabled,
3174
+ onCheckedChange: (checked) => handleToggleEnabled(agentTool, checked),
3175
+ disabled: updateMutation.isPending
3726
3176
  }
3727
- ) : /* @__PURE__ */ jsx17(Check2, { "aria-hidden": "true", className: "h-4 w-4" }),
3728
- "Concluir"
3729
- ]
3730
- }
3731
- ) : /* @__PURE__ */ jsxs15(
3732
- Button10,
3733
- {
3734
- type: "button",
3735
- onClick: goNext,
3736
- disabled: !canAdvance(),
3737
- className: "gap-1",
3738
- children: [
3739
- "Continuar",
3740
- /* @__PURE__ */ jsx17(ChevronRight, { "aria-hidden": "true", className: "h-4 w-4" })
3177
+ ),
3178
+ /* @__PURE__ */ jsx13(
3179
+ Button8,
3180
+ {
3181
+ variant: "ghost",
3182
+ size: "icon",
3183
+ "aria-label": "Configurar",
3184
+ className: "shrink-0 text-muted-foreground hover:text-foreground",
3185
+ onClick: () => openConfig(agentTool),
3186
+ title: "Configurar instru\xE7\xF5es",
3187
+ children: /* @__PURE__ */ jsx13(Settings2, { className: "h-4 w-4" })
3188
+ }
3189
+ ),
3190
+ /* @__PURE__ */ jsx13(
3191
+ Button8,
3192
+ {
3193
+ variant: "ghost",
3194
+ size: "icon",
3195
+ "aria-label": "Remover",
3196
+ className: "shrink-0 text-muted-foreground hover:text-destructive",
3197
+ onClick: () => setRemoveTarget(agentTool),
3198
+ children: /* @__PURE__ */ jsx13(Trash23, { className: "h-4 w-4" })
3199
+ }
3200
+ )
3741
3201
  ]
3742
- }
3743
- ) })
3744
- ] })
3745
- ] }) });
3746
- }
3747
- function StepIndicator({
3748
- steps,
3749
- currentStep
3750
- }) {
3751
- const currentIndex = steps.indexOf(currentStep);
3752
- return /* @__PURE__ */ jsx17(
3753
- "div",
3754
- {
3755
- className: "flex items-center justify-center gap-1 py-2",
3756
- role: "list",
3757
- "aria-label": "Passos do assistente",
3758
- children: steps.map((step, i) => {
3759
- const isCompleted = i < currentIndex;
3760
- const isCurrent = step === currentStep;
3761
- return /* @__PURE__ */ jsxs15("div", { className: "flex items-center", role: "listitem", children: [
3762
- /* @__PURE__ */ jsx17(
3763
- "div",
3764
- {
3765
- className: `
3766
- flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium
3767
- transition-colors duration-200
3768
- ${isCurrent ? "bg-primary text-primary-foreground" : isCompleted ? "bg-green-600 text-white" : "bg-muted text-muted-foreground"}
3769
- `,
3770
- "aria-current": isCurrent ? "step" : void 0,
3771
- "aria-label": `${STEP_LABELS[step]}${isCompleted ? " (conclu\xEDdo)" : isCurrent ? " (atual)" : ""}`,
3772
- children: isCompleted ? /* @__PURE__ */ jsx17(Check2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : i + 1
3773
- }
3774
- ),
3775
- /* @__PURE__ */ jsx17(
3776
- "span",
3777
- {
3778
- className: `
3779
- ml-1.5 hidden text-xs sm:inline
3780
- ${isCurrent ? "font-medium text-foreground" : "text-muted-foreground"}
3781
- `,
3782
- children: STEP_LABELS[step]
3783
- }
3784
- ),
3785
- i < steps.length - 1 && /* @__PURE__ */ jsx17(
3786
- "div",
3787
- {
3788
- className: `
3789
- mx-2 h-px w-6
3790
- ${i < currentIndex ? "bg-green-600" : "bg-border"}
3791
- `
3792
- }
3793
- )
3794
- ] }, step);
3795
- })
3796
- }
3797
- );
3202
+ },
3203
+ agentTool.id
3204
+ );
3205
+ }) }),
3206
+ /* @__PURE__ */ jsx13(
3207
+ Dialog4,
3208
+ {
3209
+ open: !!configTarget,
3210
+ onOpenChange: (open) => !open && setConfigTarget(null),
3211
+ children: /* @__PURE__ */ jsxs11(DialogContent4, { className: "sm:max-w-lg", children: [
3212
+ /* @__PURE__ */ jsx13(DialogHeader4, { children: /* @__PURE__ */ jsx13(DialogTitle4, { children: "Instru\xE7\xF5es da Ferramenta" }) }),
3213
+ /* @__PURE__ */ jsxs11("div", { className: "space-y-4", children: [
3214
+ configTarget && getToolInfo(configTarget.id_tool)?.type !== "none" && /* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
3215
+ /* @__PURE__ */ jsx13(Label4, { htmlFor: "tool-credential", children: "Credencial" }),
3216
+ /* @__PURE__ */ jsxs11(
3217
+ Select,
3218
+ {
3219
+ value: configCredentialId || void 0,
3220
+ onValueChange: (val) => setConfigCredentialId(val === "__none__" ? "" : val),
3221
+ children: [
3222
+ /* @__PURE__ */ jsx13(SelectTrigger, { id: "tool-credential", children: /* @__PURE__ */ jsx13(SelectValue, { placeholder: "Selecione uma credencial (opcional)" }) }),
3223
+ /* @__PURE__ */ jsxs11(SelectContent, { children: [
3224
+ /* @__PURE__ */ jsx13(SelectItem, { value: "__none__", children: "Nenhuma (autom\xE1tico)" }),
3225
+ allCredentials.filter((c) => configTarget && c.id_tool === configTarget.id_tool && c.status === "active").map((c) => /* @__PURE__ */ jsx13(SelectItem, { value: String(c.id), children: c.label || `Credencial #${c.id}` }, c.id))
3226
+ ] })
3227
+ ]
3228
+ }
3229
+ ),
3230
+ /* @__PURE__ */ jsx13("p", { className: "text-xs text-muted-foreground", children: "Vincule uma credencial espec\xEDfica a esta ferramenta neste agente." })
3231
+ ] }),
3232
+ /* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
3233
+ /* @__PURE__ */ jsx13(Label4, { htmlFor: "tool-instructions", children: "Instru\xE7\xF5es Personalizadas" }),
3234
+ /* @__PURE__ */ jsx13(
3235
+ Textarea2,
3236
+ {
3237
+ id: "tool-instructions",
3238
+ name: "instructions",
3239
+ value: configInstructions,
3240
+ onChange: (e) => setConfigInstructions(e.target.value),
3241
+ placeholder: "Instru\\u00e7\\u00f5es sobre como e quando o agente deve usar esta ferramenta\\u2026",
3242
+ rows: 6
3243
+ }
3244
+ ),
3245
+ /* @__PURE__ */ jsx13("p", { className: "text-xs text-muted-foreground", children: "Este texto \xE9 adicionado ao prompt do agente para orientar o uso da ferramenta." })
3246
+ ] })
3247
+ ] }),
3248
+ /* @__PURE__ */ jsxs11(DialogFooter4, { children: [
3249
+ /* @__PURE__ */ jsx13(
3250
+ Button8,
3251
+ {
3252
+ variant: "outline",
3253
+ onClick: () => setConfigTarget(null),
3254
+ children: "Cancelar"
3255
+ }
3256
+ ),
3257
+ /* @__PURE__ */ jsx13(
3258
+ Button8,
3259
+ {
3260
+ onClick: handleSaveConfig,
3261
+ disabled: updateMutation.isPending,
3262
+ children: "Salvar"
3263
+ }
3264
+ )
3265
+ ] })
3266
+ ] })
3267
+ }
3268
+ ),
3269
+ /* @__PURE__ */ jsx13(
3270
+ AlertDialog3,
3271
+ {
3272
+ open: !!removeTarget,
3273
+ onOpenChange: (open) => !open && setRemoveTarget(null),
3274
+ children: /* @__PURE__ */ jsxs11(AlertDialogContent3, { children: [
3275
+ /* @__PURE__ */ jsxs11(AlertDialogHeader3, { children: [
3276
+ /* @__PURE__ */ jsx13(AlertDialogTitle3, { children: "Remover ferramenta?" }),
3277
+ /* @__PURE__ */ jsx13(AlertDialogDescription3, { children: "A ferramenta ser\xE1 desassociada deste agente." })
3278
+ ] }),
3279
+ /* @__PURE__ */ jsxs11(AlertDialogFooter3, { children: [
3280
+ /* @__PURE__ */ jsx13(AlertDialogCancel3, { children: "Cancelar" }),
3281
+ /* @__PURE__ */ jsx13(
3282
+ AlertDialogAction3,
3283
+ {
3284
+ onClick: handleRemove,
3285
+ disabled: removeMutation.isPending,
3286
+ children: "Remover"
3287
+ }
3288
+ )
3289
+ ] })
3290
+ ] })
3291
+ }
3292
+ )
3293
+ ] });
3798
3294
  }
3799
3295
 
3800
- // src/components/capabilities/advanced-tab.tsx
3801
- import { useState as useState12 } from "react";
3802
-
3803
3296
  // src/components/tools/tools-table.tsx
3804
3297
  import { useMemo as useMemo6, useState as useState10 } from "react";
3805
3298
  import { DataTable as DataTable2 } from "@greatapps/greatauth-ui";
@@ -3809,52 +3302,52 @@ import {
3809
3302
  Tooltip as Tooltip3,
3810
3303
  TooltipTrigger as TooltipTrigger3,
3811
3304
  TooltipContent as TooltipContent3,
3812
- AlertDialog as AlertDialog3,
3813
- AlertDialogAction as AlertDialogAction3,
3814
- AlertDialogCancel as AlertDialogCancel3,
3815
- AlertDialogContent as AlertDialogContent3,
3816
- AlertDialogDescription as AlertDialogDescription3,
3817
- AlertDialogFooter as AlertDialogFooter3,
3818
- AlertDialogHeader as AlertDialogHeader3,
3819
- AlertDialogTitle as AlertDialogTitle3,
3820
- Button as Button11
3305
+ AlertDialog as AlertDialog4,
3306
+ AlertDialogAction as AlertDialogAction4,
3307
+ AlertDialogCancel as AlertDialogCancel4,
3308
+ AlertDialogContent as AlertDialogContent4,
3309
+ AlertDialogDescription as AlertDialogDescription4,
3310
+ AlertDialogFooter as AlertDialogFooter4,
3311
+ AlertDialogHeader as AlertDialogHeader4,
3312
+ AlertDialogTitle as AlertDialogTitle4,
3313
+ Button as Button9
3821
3314
  } from "@greatapps/greatauth-ui/ui";
3822
- import { Pencil as Pencil3, Trash2 as Trash23, Search as Search2 } from "lucide-react";
3315
+ import { Pencil as Pencil3, Trash2 as Trash24, Search as Search2 } from "lucide-react";
3823
3316
  import { format as format2 } from "date-fns";
3824
3317
  import { ptBR as ptBR2 } from "date-fns/locale";
3825
3318
  import { toast as toast8 } from "sonner";
3826
- import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
3319
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
3827
3320
  function useColumns2(onEdit, onDelete) {
3828
3321
  return [
3829
3322
  {
3830
3323
  accessorKey: "name",
3831
3324
  header: "Nome",
3832
- cell: ({ row }) => /* @__PURE__ */ jsx18("span", { className: "font-medium", children: row.original.name }),
3325
+ cell: ({ row }) => /* @__PURE__ */ jsx14("span", { className: "font-medium", children: row.original.name }),
3833
3326
  sortingFn: (rowA, rowB) => rowA.original.name.toLowerCase().localeCompare(rowB.original.name.toLowerCase())
3834
3327
  },
3835
3328
  {
3836
3329
  accessorKey: "slug",
3837
3330
  header: "Slug",
3838
- cell: ({ row }) => /* @__PURE__ */ jsx18("span", { className: "text-muted-foreground text-sm font-mono", children: row.original.slug || "\u2014" })
3331
+ cell: ({ row }) => /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground text-sm font-mono", children: row.original.slug || "\u2014" })
3839
3332
  },
3840
3333
  {
3841
3334
  accessorKey: "type",
3842
3335
  header: "Tipo",
3843
- cell: ({ row }) => /* @__PURE__ */ jsx18(Badge7, { variant: "secondary", children: row.original.type })
3336
+ cell: ({ row }) => /* @__PURE__ */ jsx14(Badge7, { variant: "secondary", children: row.original.type })
3844
3337
  },
3845
3338
  {
3846
3339
  accessorKey: "description",
3847
3340
  header: "Descri\xE7\xE3o",
3848
3341
  cell: ({ row }) => {
3849
3342
  const desc = row.original.description;
3850
- if (!desc) return /* @__PURE__ */ jsx18("span", { className: "text-muted-foreground text-sm", children: "\u2014" });
3851
- return /* @__PURE__ */ jsx18("span", { className: "text-muted-foreground text-sm", children: desc.length > 50 ? `${desc.slice(0, 50)}\u2026` : desc });
3343
+ if (!desc) return /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground text-sm", children: "\u2014" });
3344
+ return /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground text-sm", children: desc.length > 50 ? `${desc.slice(0, 50)}\u2026` : desc });
3852
3345
  }
3853
3346
  },
3854
3347
  {
3855
3348
  accessorKey: "datetime_add",
3856
3349
  header: "Criado em",
3857
- cell: ({ row }) => /* @__PURE__ */ jsx18("span", { className: "text-muted-foreground text-sm", children: format2(new Date(row.original.datetime_add), "dd/MM/yyyy", {
3350
+ cell: ({ row }) => /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground text-sm", children: format2(new Date(row.original.datetime_add), "dd/MM/yyyy", {
3858
3351
  locale: ptBR2
3859
3352
  }) })
3860
3353
  },
@@ -3862,34 +3355,34 @@ function useColumns2(onEdit, onDelete) {
3862
3355
  id: "actions",
3863
3356
  size: 80,
3864
3357
  enableSorting: false,
3865
- cell: ({ row }) => /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1", children: [
3866
- /* @__PURE__ */ jsxs16(Tooltip3, { children: [
3867
- /* @__PURE__ */ jsx18(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx18(
3868
- Button11,
3358
+ cell: ({ row }) => /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1", children: [
3359
+ /* @__PURE__ */ jsxs12(Tooltip3, { children: [
3360
+ /* @__PURE__ */ jsx14(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx14(
3361
+ Button9,
3869
3362
  {
3870
3363
  variant: "ghost",
3871
3364
  size: "icon",
3872
3365
  className: "h-8 w-8",
3873
3366
  "aria-label": "Editar",
3874
3367
  onClick: () => onEdit(row.original),
3875
- children: /* @__PURE__ */ jsx18(Pencil3, { className: "h-4 w-4" })
3368
+ children: /* @__PURE__ */ jsx14(Pencil3, { className: "h-4 w-4" })
3876
3369
  }
3877
3370
  ) }),
3878
- /* @__PURE__ */ jsx18(TooltipContent3, { children: "Editar" })
3371
+ /* @__PURE__ */ jsx14(TooltipContent3, { children: "Editar" })
3879
3372
  ] }),
3880
- /* @__PURE__ */ jsxs16(Tooltip3, { children: [
3881
- /* @__PURE__ */ jsx18(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx18(
3882
- Button11,
3373
+ /* @__PURE__ */ jsxs12(Tooltip3, { children: [
3374
+ /* @__PURE__ */ jsx14(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx14(
3375
+ Button9,
3883
3376
  {
3884
3377
  variant: "ghost",
3885
3378
  size: "icon",
3886
3379
  className: "h-8 w-8 text-destructive hover:text-destructive",
3887
3380
  "aria-label": "Excluir",
3888
3381
  onClick: () => onDelete(row.original.id),
3889
- children: /* @__PURE__ */ jsx18(Trash23, { className: "h-4 w-4" })
3382
+ children: /* @__PURE__ */ jsx14(Trash24, { className: "h-4 w-4" })
3890
3383
  }
3891
3384
  ) }),
3892
- /* @__PURE__ */ jsx18(TooltipContent3, { children: "Excluir" })
3385
+ /* @__PURE__ */ jsx14(TooltipContent3, { children: "Excluir" })
3893
3386
  ] })
3894
3387
  ] })
3895
3388
  }
@@ -3932,10 +3425,10 @@ function ToolsTable({ onEdit, config }) {
3932
3425
  setSearch(value);
3933
3426
  setPage(1);
3934
3427
  }
3935
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
3936
- /* @__PURE__ */ jsx18("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs16("div", { className: "relative flex-1 max-w-md", children: [
3937
- /* @__PURE__ */ jsx18(Search2, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
3938
- /* @__PURE__ */ jsx18(
3428
+ return /* @__PURE__ */ jsxs12(Fragment2, { children: [
3429
+ /* @__PURE__ */ jsx14("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs12("div", { className: "relative flex-1 max-w-md", children: [
3430
+ /* @__PURE__ */ jsx14(Search2, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
3431
+ /* @__PURE__ */ jsx14(
3939
3432
  Input7,
3940
3433
  {
3941
3434
  placeholder: "Buscar ferramentas\\u2026",
@@ -3948,7 +3441,7 @@ function ToolsTable({ onEdit, config }) {
3948
3441
  }
3949
3442
  )
3950
3443
  ] }) }),
3951
- /* @__PURE__ */ jsx18(
3444
+ /* @__PURE__ */ jsx14(
3952
3445
  DataTable2,
3953
3446
  {
3954
3447
  columns,
@@ -3961,20 +3454,20 @@ function ToolsTable({ onEdit, config }) {
3961
3454
  pageSize: 15
3962
3455
  }
3963
3456
  ),
3964
- /* @__PURE__ */ jsx18(
3965
- AlertDialog3,
3457
+ /* @__PURE__ */ jsx14(
3458
+ AlertDialog4,
3966
3459
  {
3967
3460
  open: !!deleteId,
3968
3461
  onOpenChange: (open) => !open && setDeleteId(null),
3969
- children: /* @__PURE__ */ jsxs16(AlertDialogContent3, { children: [
3970
- /* @__PURE__ */ jsxs16(AlertDialogHeader3, { children: [
3971
- /* @__PURE__ */ jsx18(AlertDialogTitle3, { children: "Excluir ferramenta?" }),
3972
- /* @__PURE__ */ jsx18(AlertDialogDescription3, { children: "Esta a\xE7\xE3o n\xE3o pode ser desfeita. A ferramenta ser\xE1 removida permanentemente." })
3462
+ children: /* @__PURE__ */ jsxs12(AlertDialogContent4, { children: [
3463
+ /* @__PURE__ */ jsxs12(AlertDialogHeader4, { children: [
3464
+ /* @__PURE__ */ jsx14(AlertDialogTitle4, { children: "Excluir ferramenta?" }),
3465
+ /* @__PURE__ */ jsx14(AlertDialogDescription4, { children: "Esta a\xE7\xE3o n\xE3o pode ser desfeita. A ferramenta ser\xE1 removida permanentemente." })
3973
3466
  ] }),
3974
- /* @__PURE__ */ jsxs16(AlertDialogFooter3, { children: [
3975
- /* @__PURE__ */ jsx18(AlertDialogCancel3, { variant: "outline", size: "default", children: "Cancelar" }),
3976
- /* @__PURE__ */ jsx18(
3977
- AlertDialogAction3,
3467
+ /* @__PURE__ */ jsxs12(AlertDialogFooter4, { children: [
3468
+ /* @__PURE__ */ jsx14(AlertDialogCancel4, { variant: "outline", size: "default", children: "Cancelar" }),
3469
+ /* @__PURE__ */ jsx14(
3470
+ AlertDialogAction4,
3978
3471
  {
3979
3472
  variant: "default",
3980
3473
  size: "default",
@@ -3998,19 +3491,19 @@ import {
3998
3491
  DialogHeader as DialogHeader5,
3999
3492
  DialogTitle as DialogTitle5,
4000
3493
  DialogFooter as DialogFooter5,
4001
- Button as Button12,
3494
+ Button as Button10,
4002
3495
  Input as Input8,
4003
- Textarea as Textarea2,
4004
- Label as Label7,
3496
+ Textarea as Textarea3,
3497
+ Label as Label5,
4005
3498
  Select as Select2,
4006
3499
  SelectContent as SelectContent2,
4007
3500
  SelectItem as SelectItem2,
4008
3501
  SelectTrigger as SelectTrigger2,
4009
3502
  SelectValue as SelectValue2
4010
3503
  } from "@greatapps/greatauth-ui/ui";
4011
- import { Loader2 as Loader29 } from "lucide-react";
3504
+ import { Loader2 as Loader26 } from "lucide-react";
4012
3505
  import { toast as toast9 } from "sonner";
4013
- import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
3506
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
4014
3507
  var TOOL_AUTH_TYPES = [
4015
3508
  { value: "none", label: "Nenhuma" },
4016
3509
  { value: "api_key", label: "API Key" },
@@ -4120,12 +3613,12 @@ function ToolFormDialog({
4120
3613
  );
4121
3614
  }
4122
3615
  }
4123
- return /* @__PURE__ */ jsx19(Dialog5, { open, onOpenChange, children: /* @__PURE__ */ jsxs17(DialogContent5, { className: "sm:max-w-lg", children: [
4124
- /* @__PURE__ */ jsx19(DialogHeader5, { children: /* @__PURE__ */ jsx19(DialogTitle5, { children: isEditing ? "Editar Ferramenta" : "Nova Ferramenta" }) }),
4125
- /* @__PURE__ */ jsxs17("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
4126
- /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
4127
- /* @__PURE__ */ jsx19(Label7, { htmlFor: "tool-name", children: "Nome *" }),
4128
- /* @__PURE__ */ jsx19(
3616
+ return /* @__PURE__ */ jsx15(Dialog5, { open, onOpenChange, children: /* @__PURE__ */ jsxs13(DialogContent5, { className: "sm:max-w-lg", children: [
3617
+ /* @__PURE__ */ jsx15(DialogHeader5, { children: /* @__PURE__ */ jsx15(DialogTitle5, { children: isEditing ? "Editar Ferramenta" : "Nova Ferramenta" }) }),
3618
+ /* @__PURE__ */ jsxs13("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
3619
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3620
+ /* @__PURE__ */ jsx15(Label5, { htmlFor: "tool-name", children: "Nome *" }),
3621
+ /* @__PURE__ */ jsx15(
4129
3622
  Input8,
4130
3623
  {
4131
3624
  id: "tool-name",
@@ -4133,628 +3626,615 @@ function ToolFormDialog({
4133
3626
  value: form.name,
4134
3627
  onChange: (e) => {
4135
3628
  const name = e.target.value;
4136
- setForm((prev) => ({
4137
- ...prev,
4138
- name,
4139
- nameError: name.trim() ? false : prev.nameError,
4140
- ...!slugManuallyEdited && !isEditing ? { slug: slugify2(name), slugError: false } : {}
4141
- }));
4142
- },
4143
- placeholder: "Ex: Google Calendar",
4144
- disabled: isPending
4145
- }
4146
- ),
4147
- form.nameError && /* @__PURE__ */ jsx19("p", { className: "text-sm text-destructive", children: "Nome \xE9 obrigat\xF3rio" })
4148
- ] }),
4149
- /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
4150
- /* @__PURE__ */ jsx19(Label7, { htmlFor: "tool-slug", children: "Slug (identificador \xFAnico) *" }),
4151
- /* @__PURE__ */ jsx19(
4152
- Input8,
4153
- {
4154
- id: "tool-slug",
4155
- name: "slug",
4156
- value: form.slug,
4157
- onChange: (e) => {
4158
- setSlugManuallyEdited(true);
4159
- setForm((prev) => ({
4160
- ...prev,
4161
- slug: e.target.value,
4162
- slugError: e.target.value.trim() ? false : prev.slugError
4163
- }));
4164
- },
4165
- placeholder: "Ex: google-calendar",
4166
- disabled: isPending
4167
- }
4168
- ),
4169
- /* @__PURE__ */ jsx19("p", { className: "text-xs text-muted-foreground", children: "Gerado automaticamente a partir do nome. Usado internamente para identificar a ferramenta." }),
4170
- form.slugError && /* @__PURE__ */ jsx19("p", { className: "text-sm text-destructive", children: "Slug \xE9 obrigat\xF3rio" })
4171
- ] }),
4172
- /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
4173
- /* @__PURE__ */ jsx19(Label7, { htmlFor: "tool-type", children: "Tipo de Autentica\xE7\xE3o *" }),
4174
- /* @__PURE__ */ jsxs17(
4175
- Select2,
4176
- {
4177
- value: form.type,
4178
- onValueChange: (value) => {
4179
- setForm((prev) => ({
4180
- ...prev,
4181
- type: value,
4182
- typeError: false
4183
- }));
4184
- },
4185
- disabled: isPending,
4186
- children: [
4187
- /* @__PURE__ */ jsx19(SelectTrigger2, { id: "tool-type", children: /* @__PURE__ */ jsx19(SelectValue2, { placeholder: "Selecione o tipo" }) }),
4188
- /* @__PURE__ */ jsx19(SelectContent2, { children: TOOL_AUTH_TYPES.map((t) => /* @__PURE__ */ jsx19(SelectItem2, { value: t.value, children: t.label }, t.value)) })
4189
- ]
4190
- }
4191
- ),
4192
- /* @__PURE__ */ jsx19("p", { className: "text-xs text-muted-foreground", children: "Define se a ferramenta requer credenciais para funcionar." }),
4193
- form.typeError && /* @__PURE__ */ jsx19("p", { className: "text-sm text-destructive", children: "Tipo \xE9 obrigat\xF3rio" })
4194
- ] }),
4195
- /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
4196
- /* @__PURE__ */ jsx19(Label7, { htmlFor: "tool-description", children: "Descri\xE7\xE3o" }),
4197
- /* @__PURE__ */ jsx19(
4198
- Textarea2,
4199
- {
4200
- id: "tool-description",
4201
- name: "description",
4202
- value: form.description,
4203
- onChange: (e) => setForm((prev) => ({ ...prev, description: e.target.value })),
4204
- placeholder: "Descri\\u00e7\\u00e3o da ferramenta\\u2026",
4205
- rows: 3,
4206
- disabled: isPending
4207
- }
4208
- )
4209
- ] }),
4210
- /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
4211
- /* @__PURE__ */ jsx19(Label7, { htmlFor: "tool-function-defs", children: "Defini\xE7\xF5es de Fun\xE7\xE3o (JSON)" }),
4212
- /* @__PURE__ */ jsx19(
4213
- Textarea2,
4214
- {
4215
- id: "tool-function-defs",
4216
- name: "functionDefs",
4217
- value: form.functionDefinitions,
4218
- onChange: (e) => {
4219
- setForm((prev) => ({
4220
- ...prev,
4221
- functionDefinitions: e.target.value,
4222
- jsonError: false
4223
- }));
4224
- },
4225
- placeholder: `[
4226
- {
4227
- "type": "function",
4228
- "function": {
4229
- "name": "nome_da_funcao",
4230
- "description": "O que a fun\xE7\xE3o faz",
4231
- "parameters": {
4232
- "type": "object",
4233
- "properties": { \u2026 },
4234
- "required": [\u2026]
4235
- }
4236
- }
4237
- }
4238
- ]`,
4239
- rows: 10,
4240
- className: "font-mono text-sm",
4241
- disabled: isPending
4242
- }
4243
- ),
4244
- /* @__PURE__ */ jsx19("p", { className: "text-xs text-muted-foreground", children: "Array de defini\xE7\xF5es no formato OpenAI Function Calling." }),
4245
- form.jsonError && /* @__PURE__ */ jsx19("p", { className: "text-sm text-destructive", children: "JSON inv\xE1lido" })
4246
- ] }),
4247
- /* @__PURE__ */ jsxs17(DialogFooter5, { children: [
4248
- /* @__PURE__ */ jsx19(
4249
- Button12,
4250
- {
4251
- type: "button",
4252
- variant: "outline",
4253
- onClick: () => onOpenChange(false),
4254
- disabled: isPending,
4255
- children: "Cancelar"
4256
- }
4257
- ),
4258
- /* @__PURE__ */ jsxs17(Button12, { type: "submit", disabled: isPending, children: [
4259
- isPending ? /* @__PURE__ */ jsx19(Loader29, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }) : null,
4260
- isEditing ? "Salvar" : "Criar"
4261
- ] })
4262
- ] })
4263
- ] })
4264
- ] }) });
4265
- }
4266
-
4267
- // src/components/capabilities/advanced-tab.tsx
4268
- import { Info as Info2 } from "lucide-react";
4269
- import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
4270
- function AdvancedTab({ config, agentId, gagentsApiUrl }) {
4271
- const [editingTool, setEditingTool] = useState12(null);
4272
- const [showToolForm, setShowToolForm] = useState12(false);
4273
- function handleEditTool(tool) {
4274
- setEditingTool(tool);
4275
- setShowToolForm(true);
4276
- }
4277
- function handleToolFormOpenChange(open) {
4278
- setShowToolForm(open);
4279
- if (!open) setEditingTool(null);
4280
- }
4281
- return /* @__PURE__ */ jsxs18("div", { className: "space-y-8", children: [
4282
- /* @__PURE__ */ jsxs18("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: [
4283
- /* @__PURE__ */ jsx20(Info2, { className: "mt-0.5 h-4 w-4 shrink-0 text-blue-600 dark:text-blue-400" }),
4284
- /* @__PURE__ */ jsxs18("p", { className: "text-sm text-blue-800 dark:text-blue-300", children: [
4285
- "Use as abas ",
4286
- /* @__PURE__ */ jsx20("strong", { children: "Capacidades" }),
4287
- " e ",
4288
- /* @__PURE__ */ jsx20("strong", { children: "Integra\xE7\xF5es" }),
4289
- " para configura\xE7\xE3o simplificada. Esta aba oferece controlo manual avan\xE7ado sobre ferramentas. As credenciais s\xE3o geridas dentro de cada ferramenta."
4290
- ] })
4291
- ] }),
4292
- /* @__PURE__ */ jsxs18("section", { className: "space-y-3", children: [
4293
- /* @__PURE__ */ jsx20("h3", { className: "text-sm font-medium", children: "Ferramentas" }),
4294
- /* @__PURE__ */ jsx20(ToolsTable, { onEdit: handleEditTool, config })
4295
- ] }),
4296
- /* @__PURE__ */ jsx20(
4297
- ToolFormDialog,
4298
- {
4299
- open: showToolForm,
4300
- onOpenChange: handleToolFormOpenChange,
4301
- tool: editingTool ?? void 0,
4302
- config
4303
- }
4304
- )
4305
- ] });
4306
- }
4307
-
4308
- // src/pages/agent-capabilities-page.tsx
4309
- import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
4310
- function defaultResolveWizardMeta(card) {
4311
- return {
4312
- capabilities: [
4313
- { label: card.definition.name, description: card.definition.description }
4314
- ],
4315
- requirements: [],
4316
- hasConfigStep: false
4317
- };
4318
- }
4319
- function AgentCapabilitiesPage({
4320
- config,
4321
- agentId,
4322
- gagentsApiUrl,
4323
- resolveWizardMeta = defaultResolveWizardMeta,
4324
- loadConfigOptions,
4325
- onWizardComplete
4326
- }) {
4327
- const [wizardOpen, setWizardOpen] = useState13(false);
4328
- const [activeCard, setActiveCard] = useState13(null);
4329
- const handleConnect = useCallback6(
4330
- (card) => {
4331
- setActiveCard(card);
4332
- setWizardOpen(true);
4333
- },
4334
- []
4335
- );
4336
- const handleWizardComplete = useCallback6(() => {
4337
- setWizardOpen(false);
4338
- setActiveCard(null);
4339
- onWizardComplete?.();
4340
- }, [onWizardComplete]);
4341
- const handleWizardOpenChange = useCallback6((open) => {
4342
- setWizardOpen(open);
4343
- if (!open) setActiveCard(null);
4344
- }, []);
4345
- const wizardMeta = activeCard ? resolveWizardMeta(activeCard) : null;
4346
- return /* @__PURE__ */ jsxs19("div", { className: "space-y-4", children: [
4347
- /* @__PURE__ */ jsxs19("div", { children: [
4348
- /* @__PURE__ */ jsx21("h2", { className: "text-lg font-semibold", children: "Capacidades e Integra\xE7\xF5es" }),
4349
- /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Configure o que este agente pode fazer e quais servi\xE7os externos ele utiliza." })
4350
- ] }),
4351
- /* @__PURE__ */ jsxs19(Tabs, { defaultValue: "capacidades", children: [
4352
- /* @__PURE__ */ jsxs19(TabsList, { children: [
4353
- /* @__PURE__ */ jsxs19(TabsTrigger, { value: "capacidades", className: "flex items-center gap-1.5", children: [
4354
- /* @__PURE__ */ jsx21(Blocks, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
4355
- "Capacidades"
4356
- ] }),
4357
- /* @__PURE__ */ jsxs19(TabsTrigger, { value: "integracoes", className: "flex items-center gap-1.5", children: [
4358
- /* @__PURE__ */ jsx21(Plug3, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
4359
- "Integra\xE7\xF5es"
4360
- ] }),
4361
- /* @__PURE__ */ jsxs19(TabsTrigger, { value: "avancado", className: "flex items-center gap-1.5", children: [
4362
- /* @__PURE__ */ jsx21(Settings3, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
4363
- "Avan\xE7ado"
4364
- ] })
4365
- ] }),
4366
- /* @__PURE__ */ jsx21(TabsContent, { value: "capacidades", className: "mt-4", children: /* @__PURE__ */ jsx21(CapabilitiesTab, { config, agentId }) }),
4367
- /* @__PURE__ */ jsx21(TabsContent, { value: "integracoes", className: "mt-4", children: /* @__PURE__ */ jsx21(
4368
- IntegrationsTab,
4369
- {
4370
- config,
4371
- agentId,
4372
- onConnect: handleConnect
4373
- }
4374
- ) }),
4375
- /* @__PURE__ */ jsx21(TabsContent, { value: "avancado", className: "mt-4", children: /* @__PURE__ */ jsx21(
4376
- AdvancedTab,
4377
- {
4378
- config,
4379
- agentId,
4380
- gagentsApiUrl
4381
- }
4382
- ) })
4383
- ] }),
4384
- activeCard && wizardMeta && /* @__PURE__ */ jsx21(
4385
- IntegrationWizard,
4386
- {
4387
- open: wizardOpen,
4388
- onOpenChange: handleWizardOpenChange,
4389
- integration: activeCard.definition,
4390
- meta: wizardMeta,
4391
- agentId,
4392
- config,
4393
- onComplete: handleWizardComplete,
4394
- gagentsApiUrl,
4395
- existingCredentialId: activeCard.credential?.id,
4396
- loadConfigOptions
4397
- }
4398
- )
4399
- ] });
4400
- }
4401
-
4402
- // src/components/agents/agent-tabs.tsx
4403
- import {
4404
- Tabs as Tabs2,
4405
- TabsList as TabsList2,
4406
- TabsTrigger as TabsTrigger2,
4407
- TabsContent as TabsContent2
4408
- } from "@greatapps/greatauth-ui/ui";
4409
- import { Target as Target2, FileText as FileText2, MessageCircle as MessageCircle2, Blocks as Blocks2 } from "lucide-react";
4410
- import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
4411
- function AgentTabs({
4412
- agent,
4413
- config,
4414
- renderChatLink,
4415
- gagentsApiUrl,
4416
- resolveWizardMeta,
4417
- loadConfigOptions,
4418
- onWizardComplete
4419
- }) {
4420
- const apiUrl = gagentsApiUrl || config.baseUrl;
4421
- return /* @__PURE__ */ jsxs20(Tabs2, { defaultValue: "prompt", children: [
4422
- /* @__PURE__ */ jsxs20(TabsList2, { children: [
4423
- /* @__PURE__ */ jsxs20(TabsTrigger2, { value: "prompt", className: "flex items-center gap-1.5", children: [
4424
- /* @__PURE__ */ jsx22(FileText2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
4425
- "Prompt"
3629
+ setForm((prev) => ({
3630
+ ...prev,
3631
+ name,
3632
+ nameError: name.trim() ? false : prev.nameError,
3633
+ ...!slugManuallyEdited && !isEditing ? { slug: slugify2(name), slugError: false } : {}
3634
+ }));
3635
+ },
3636
+ placeholder: "Ex: Google Calendar",
3637
+ disabled: isPending
3638
+ }
3639
+ ),
3640
+ form.nameError && /* @__PURE__ */ jsx15("p", { className: "text-sm text-destructive", children: "Nome \xE9 obrigat\xF3rio" })
4426
3641
  ] }),
4427
- /* @__PURE__ */ jsxs20(TabsTrigger2, { value: "objetivos", className: "flex items-center gap-1.5", children: [
4428
- /* @__PURE__ */ jsx22(Target2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
4429
- "Objetivos"
3642
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3643
+ /* @__PURE__ */ jsx15(Label5, { htmlFor: "tool-slug", children: "Slug (identificador \xFAnico) *" }),
3644
+ /* @__PURE__ */ jsx15(
3645
+ Input8,
3646
+ {
3647
+ id: "tool-slug",
3648
+ name: "slug",
3649
+ value: form.slug,
3650
+ onChange: (e) => {
3651
+ setSlugManuallyEdited(true);
3652
+ setForm((prev) => ({
3653
+ ...prev,
3654
+ slug: e.target.value,
3655
+ slugError: e.target.value.trim() ? false : prev.slugError
3656
+ }));
3657
+ },
3658
+ placeholder: "Ex: google-calendar",
3659
+ disabled: isPending
3660
+ }
3661
+ ),
3662
+ /* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground", children: "Gerado automaticamente a partir do nome. Usado internamente para identificar a ferramenta." }),
3663
+ form.slugError && /* @__PURE__ */ jsx15("p", { className: "text-sm text-destructive", children: "Slug \xE9 obrigat\xF3rio" })
4430
3664
  ] }),
4431
- /* @__PURE__ */ jsxs20(TabsTrigger2, { value: "capacidades", className: "flex items-center gap-1.5", children: [
4432
- /* @__PURE__ */ jsx22(Blocks2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
4433
- "Capacidades"
3665
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3666
+ /* @__PURE__ */ jsx15(Label5, { htmlFor: "tool-type", children: "Tipo de Autentica\xE7\xE3o *" }),
3667
+ /* @__PURE__ */ jsxs13(
3668
+ Select2,
3669
+ {
3670
+ value: form.type,
3671
+ onValueChange: (value) => {
3672
+ setForm((prev) => ({
3673
+ ...prev,
3674
+ type: value,
3675
+ typeError: false
3676
+ }));
3677
+ },
3678
+ disabled: isPending,
3679
+ children: [
3680
+ /* @__PURE__ */ jsx15(SelectTrigger2, { id: "tool-type", children: /* @__PURE__ */ jsx15(SelectValue2, { placeholder: "Selecione o tipo" }) }),
3681
+ /* @__PURE__ */ jsx15(SelectContent2, { children: TOOL_AUTH_TYPES.map((t) => /* @__PURE__ */ jsx15(SelectItem2, { value: t.value, children: t.label }, t.value)) })
3682
+ ]
3683
+ }
3684
+ ),
3685
+ /* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground", children: "Define se a ferramenta requer credenciais para funcionar." }),
3686
+ form.typeError && /* @__PURE__ */ jsx15("p", { className: "text-sm text-destructive", children: "Tipo \xE9 obrigat\xF3rio" })
4434
3687
  ] }),
4435
- /* @__PURE__ */ jsxs20(TabsTrigger2, { value: "conversas", className: "flex items-center gap-1.5", children: [
4436
- /* @__PURE__ */ jsx22(MessageCircle2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
4437
- "Conversas"
4438
- ] })
4439
- ] }),
4440
- /* @__PURE__ */ jsx22(TabsContent2, { value: "prompt", className: "mt-4", children: /* @__PURE__ */ jsx22(AgentPromptEditor, { agent, config }) }),
4441
- /* @__PURE__ */ jsx22(TabsContent2, { value: "objetivos", className: "mt-4", children: /* @__PURE__ */ jsx22(AgentObjectivesList, { agent, config }) }),
4442
- /* @__PURE__ */ jsx22(TabsContent2, { value: "capacidades", className: "mt-4", children: /* @__PURE__ */ jsx22(
4443
- AgentCapabilitiesPage,
4444
- {
4445
- config,
4446
- agentId: agent.id,
4447
- gagentsApiUrl: apiUrl,
4448
- resolveWizardMeta,
4449
- loadConfigOptions,
4450
- onWizardComplete
4451
- }
4452
- ) }),
4453
- /* @__PURE__ */ jsx22(TabsContent2, { value: "conversas", className: "mt-4", children: /* @__PURE__ */ jsx22(
4454
- AgentConversationsPanel,
4455
- {
4456
- agent,
4457
- config,
4458
- renderChatLink
3688
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3689
+ /* @__PURE__ */ jsx15(Label5, { htmlFor: "tool-description", children: "Descri\xE7\xE3o" }),
3690
+ /* @__PURE__ */ jsx15(
3691
+ Textarea3,
3692
+ {
3693
+ id: "tool-description",
3694
+ name: "description",
3695
+ value: form.description,
3696
+ onChange: (e) => setForm((prev) => ({ ...prev, description: e.target.value })),
3697
+ placeholder: "Descri\\u00e7\\u00e3o da ferramenta\\u2026",
3698
+ rows: 3,
3699
+ disabled: isPending
3700
+ }
3701
+ )
3702
+ ] }),
3703
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3704
+ /* @__PURE__ */ jsx15(Label5, { htmlFor: "tool-function-defs", children: "Defini\xE7\xF5es de Fun\xE7\xE3o (JSON)" }),
3705
+ /* @__PURE__ */ jsx15(
3706
+ Textarea3,
3707
+ {
3708
+ id: "tool-function-defs",
3709
+ name: "functionDefs",
3710
+ value: form.functionDefinitions,
3711
+ onChange: (e) => {
3712
+ setForm((prev) => ({
3713
+ ...prev,
3714
+ functionDefinitions: e.target.value,
3715
+ jsonError: false
3716
+ }));
3717
+ },
3718
+ placeholder: `[
3719
+ {
3720
+ "type": "function",
3721
+ "function": {
3722
+ "name": "nome_da_funcao",
3723
+ "description": "O que a fun\xE7\xE3o faz",
3724
+ "parameters": {
3725
+ "type": "object",
3726
+ "properties": { \u2026 },
3727
+ "required": [\u2026]
4459
3728
  }
4460
- ) })
4461
- ] });
3729
+ }
3730
+ }
3731
+ ]`,
3732
+ rows: 10,
3733
+ className: "font-mono text-sm",
3734
+ disabled: isPending
3735
+ }
3736
+ ),
3737
+ /* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground", children: "Array de defini\xE7\xF5es no formato OpenAI Function Calling." }),
3738
+ form.jsonError && /* @__PURE__ */ jsx15("p", { className: "text-sm text-destructive", children: "JSON inv\xE1lido" })
3739
+ ] }),
3740
+ /* @__PURE__ */ jsxs13(DialogFooter5, { children: [
3741
+ /* @__PURE__ */ jsx15(
3742
+ Button10,
3743
+ {
3744
+ type: "button",
3745
+ variant: "outline",
3746
+ onClick: () => onOpenChange(false),
3747
+ disabled: isPending,
3748
+ children: "Cancelar"
3749
+ }
3750
+ ),
3751
+ /* @__PURE__ */ jsxs13(Button10, { type: "submit", disabled: isPending, children: [
3752
+ isPending ? /* @__PURE__ */ jsx15(Loader26, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }) : null,
3753
+ isEditing ? "Salvar" : "Criar"
3754
+ ] })
3755
+ ] })
3756
+ ] })
3757
+ ] }) });
4462
3758
  }
4463
3759
 
4464
- // src/components/agents/agent-tools-list.tsx
4465
- import { useState as useState14 } from "react";
3760
+ // src/components/tools/tool-credentials-form.tsx
3761
+ import { useMemo as useMemo7, useState as useState12 } from "react";
3762
+ import { DataTable as DataTable3 } from "@greatapps/greatauth-ui";
4466
3763
  import {
4467
- Switch as Switch5,
4468
- Badge as Badge8,
4469
- Button as Button13,
4470
- Skeleton as Skeleton6,
4471
- AlertDialog as AlertDialog4,
4472
- AlertDialogAction as AlertDialogAction4,
4473
- AlertDialogCancel as AlertDialogCancel4,
4474
- AlertDialogContent as AlertDialogContent4,
4475
- AlertDialogDescription as AlertDialogDescription4,
4476
- AlertDialogFooter as AlertDialogFooter4,
4477
- AlertDialogHeader as AlertDialogHeader4,
4478
- AlertDialogTitle as AlertDialogTitle4,
4479
- Popover,
4480
- PopoverContent,
4481
- PopoverTrigger,
4482
3764
  Input as Input9,
4483
- Textarea as Textarea3,
3765
+ Button as Button11,
3766
+ Badge as Badge8,
3767
+ Tooltip as Tooltip4,
3768
+ TooltipTrigger as TooltipTrigger4,
3769
+ TooltipContent as TooltipContent4,
4484
3770
  Dialog as Dialog6,
4485
3771
  DialogContent as DialogContent6,
4486
3772
  DialogHeader as DialogHeader6,
4487
3773
  DialogTitle as DialogTitle6,
4488
3774
  DialogFooter as DialogFooter6,
4489
- Label as Label8,
3775
+ AlertDialog as AlertDialog5,
3776
+ AlertDialogAction as AlertDialogAction5,
3777
+ AlertDialogCancel as AlertDialogCancel5,
3778
+ AlertDialogContent as AlertDialogContent5,
3779
+ AlertDialogDescription as AlertDialogDescription5,
3780
+ AlertDialogFooter as AlertDialogFooter5,
3781
+ AlertDialogHeader as AlertDialogHeader5,
3782
+ AlertDialogTitle as AlertDialogTitle5,
4490
3783
  Select as Select3,
4491
3784
  SelectContent as SelectContent3,
4492
3785
  SelectItem as SelectItem3,
4493
3786
  SelectTrigger as SelectTrigger3,
4494
3787
  SelectValue as SelectValue3
4495
3788
  } from "@greatapps/greatauth-ui/ui";
4496
- import {
4497
- Trash2 as Trash24,
4498
- Plus as Plus3,
4499
- Wrench,
4500
- Settings2 as Settings22
4501
- } from "lucide-react";
3789
+ import { Trash2 as Trash25, Pencil as Pencil4, Link, Search as Search3 } from "lucide-react";
3790
+ import { format as format3 } from "date-fns";
3791
+ import { ptBR as ptBR3 } from "date-fns/locale";
4502
3792
  import { toast as toast10 } from "sonner";
4503
- import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
4504
- function AgentToolsList({ agent, config }) {
4505
- const { data: agentToolsData, isLoading } = useAgentTools(config, agent.id);
4506
- const { data: allToolsData } = useTools(config);
4507
- const addMutation = useAddAgentTool(config);
4508
- const removeMutation = useRemoveAgentTool(config);
4509
- const updateMutation = useUpdateAgentTool(config);
4510
- const [removeTarget, setRemoveTarget] = useState14(null);
4511
- const [addOpen, setAddOpen] = useState14(false);
4512
- const [search, setSearch] = useState14("");
4513
- const [configTarget, setConfigTarget] = useState14(null);
4514
- const [configInstructions, setConfigInstructions] = useState14("");
4515
- const [configCredentialId, setConfigCredentialId] = useState14("");
4516
- const { data: credentialsData } = useToolCredentials(config);
4517
- const allCredentials = credentialsData?.data || [];
4518
- const agentTools = agentToolsData?.data || [];
4519
- const allTools = (allToolsData?.data || []).filter((t) => !t.slug?.startsWith("gclinic_"));
4520
- const assignedToolIds = new Set(agentTools.map((at) => at.id_tool));
4521
- const visibleAgentTools = agentTools.filter((at) => {
4522
- const tool = allTools.find((t) => t.id === at.id_tool);
4523
- return !tool || !tool.slug?.startsWith("gclinic_");
3793
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
3794
+ function formatDate2(dateStr) {
3795
+ if (!dateStr) return "Sem expira\xE7\xE3o";
3796
+ return format3(new Date(dateStr), "dd/MM/yyyy", { locale: ptBR3 });
3797
+ }
3798
+ function useColumns3(tools, onEdit, onConnect, onRemove) {
3799
+ function getToolName(idTool) {
3800
+ if (!idTool) return "\u2014";
3801
+ const tool = tools.find((t) => t.id === idTool);
3802
+ return tool?.name || `Ferramenta #${idTool}`;
3803
+ }
3804
+ function getToolType(idTool) {
3805
+ if (!idTool) return null;
3806
+ const tool = tools.find((t) => t.id === idTool);
3807
+ return tool?.type || null;
3808
+ }
3809
+ return [
3810
+ {
3811
+ accessorKey: "label",
3812
+ header: "Label",
3813
+ cell: ({ row }) => /* @__PURE__ */ jsx16("span", { className: "font-medium", children: row.original.label || "\u2014" })
3814
+ },
3815
+ {
3816
+ accessorKey: "id_tool",
3817
+ header: "Ferramenta",
3818
+ cell: ({ row }) => /* @__PURE__ */ jsx16("span", { className: "text-sm", children: getToolName(row.original.id_tool) })
3819
+ },
3820
+ {
3821
+ accessorKey: "status",
3822
+ header: "Status",
3823
+ cell: ({ row }) => /* @__PURE__ */ jsx16(
3824
+ Badge8,
3825
+ {
3826
+ variant: row.original.status === "active" ? "default" : "destructive",
3827
+ children: row.original.status === "active" ? "Ativo" : "Expirado"
3828
+ }
3829
+ )
3830
+ },
3831
+ {
3832
+ accessorKey: "expires_at",
3833
+ header: "Expira em",
3834
+ cell: ({ row }) => /* @__PURE__ */ jsx16("span", { className: "text-muted-foreground text-sm", children: formatDate2(row.original.expires_at) })
3835
+ },
3836
+ {
3837
+ accessorKey: "datetime_add",
3838
+ header: "Criado em",
3839
+ cell: ({ row }) => /* @__PURE__ */ jsx16("span", { className: "text-muted-foreground text-sm", children: formatDate2(row.original.datetime_add) })
3840
+ },
3841
+ {
3842
+ id: "actions",
3843
+ header: "A\xE7\xF5es",
3844
+ size: 100,
3845
+ enableSorting: false,
3846
+ cell: ({ row }) => /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-1", children: [
3847
+ getToolType(row.original.id_tool) === "oauth2" && /* @__PURE__ */ jsxs14(Tooltip4, { children: [
3848
+ /* @__PURE__ */ jsx16(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx16(
3849
+ Button11,
3850
+ {
3851
+ variant: "ghost",
3852
+ size: "icon",
3853
+ className: "h-8 w-8",
3854
+ "aria-label": "Vincular",
3855
+ disabled: true,
3856
+ children: /* @__PURE__ */ jsx16(Link, { className: "h-4 w-4" })
3857
+ }
3858
+ ) }),
3859
+ /* @__PURE__ */ jsx16(TooltipContent4, { children: "Em breve" })
3860
+ ] }),
3861
+ /* @__PURE__ */ jsxs14(Tooltip4, { children: [
3862
+ /* @__PURE__ */ jsx16(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx16(
3863
+ Button11,
3864
+ {
3865
+ variant: "ghost",
3866
+ size: "icon",
3867
+ className: "h-8 w-8",
3868
+ "aria-label": "Editar",
3869
+ onClick: () => onEdit(row.original),
3870
+ children: /* @__PURE__ */ jsx16(Pencil4, { className: "h-4 w-4" })
3871
+ }
3872
+ ) }),
3873
+ /* @__PURE__ */ jsx16(TooltipContent4, { children: "Editar" })
3874
+ ] }),
3875
+ /* @__PURE__ */ jsxs14(Tooltip4, { children: [
3876
+ /* @__PURE__ */ jsx16(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx16(
3877
+ Button11,
3878
+ {
3879
+ variant: "ghost",
3880
+ size: "icon",
3881
+ className: "h-8 w-8 text-destructive hover:text-destructive",
3882
+ "aria-label": "Excluir",
3883
+ onClick: () => onRemove(row.original),
3884
+ children: /* @__PURE__ */ jsx16(Trash25, { className: "h-4 w-4" })
3885
+ }
3886
+ ) }),
3887
+ /* @__PURE__ */ jsx16(TooltipContent4, { children: "Remover" })
3888
+ ] })
3889
+ ] })
3890
+ }
3891
+ ];
3892
+ }
3893
+ function ToolCredentialsForm({
3894
+ credentials,
3895
+ isLoading,
3896
+ config,
3897
+ gagentsApiUrl,
3898
+ createOpen: externalCreateOpen,
3899
+ onCreateOpenChange
3900
+ }) {
3901
+ const createMutation = useCreateToolCredential(config);
3902
+ const updateMutation = useUpdateToolCredential(config);
3903
+ const deleteMutation = useDeleteToolCredential(config);
3904
+ const { data: toolsData } = useTools(config);
3905
+ const tools = (toolsData?.data || []).filter((t) => !t.slug?.startsWith("gclinic_"));
3906
+ const [search, setSearch] = useState12("");
3907
+ const [internalCreateOpen, setInternalCreateOpen] = useState12(false);
3908
+ const showCreateDialog = externalCreateOpen ?? internalCreateOpen;
3909
+ const setShowCreateDialog = onCreateOpenChange ?? setInternalCreateOpen;
3910
+ const [createForm, setCreateForm] = useState12({
3911
+ id_tool: "",
3912
+ label: "",
3913
+ credentials_encrypted: "",
3914
+ expires_at: ""
4524
3915
  });
4525
- const availableTools = allTools.filter((t) => !assignedToolIds.has(t.id));
4526
- const filteredAvailable = availableTools.filter(
4527
- (t) => t.name.toLowerCase().includes(search.toLowerCase())
3916
+ const [editTarget, setEditTarget] = useState12(null);
3917
+ const [editForm, setEditForm] = useState12({
3918
+ id_tool: "",
3919
+ label: "",
3920
+ credentials_encrypted: "",
3921
+ expires_at: "",
3922
+ status: ""
3923
+ });
3924
+ const [removeTarget, setRemoveTarget] = useState12(null);
3925
+ const internalToolIds = useMemo7(() => {
3926
+ const allRawTools = toolsData?.data || [];
3927
+ return new Set(
3928
+ allRawTools.filter((t) => t.slug?.startsWith("gclinic_")).map((t) => t.id)
3929
+ );
3930
+ }, [toolsData]);
3931
+ const filteredCredentials = useMemo7(() => {
3932
+ const visible = credentials.filter(
3933
+ (cred) => !cred.id_tool || !internalToolIds.has(cred.id_tool)
3934
+ );
3935
+ if (!search) return visible;
3936
+ const term = search.toLowerCase();
3937
+ return visible.filter((cred) => {
3938
+ const toolName = tools.find((t) => t.id === cred.id_tool)?.name || "";
3939
+ return (cred.label || "").toLowerCase().includes(term) || toolName.toLowerCase().includes(term);
3940
+ });
3941
+ }, [credentials, search, tools, internalToolIds]);
3942
+ const columns = useColumns3(
3943
+ tools,
3944
+ (cred) => startEdit(cred),
3945
+ (cred) => handleConnect(cred),
3946
+ (cred) => setRemoveTarget(cred)
4528
3947
  );
4529
- function getToolInfo(idTool) {
4530
- return allTools.find((t) => t.id === idTool);
4531
- }
4532
- async function handleToggleEnabled(agentTool, checked) {
3948
+ async function handleCreate() {
3949
+ const idTool = parseInt(createForm.id_tool, 10);
3950
+ if (!idTool || !createForm.label.trim() || !createForm.credentials_encrypted.trim()) return;
4533
3951
  try {
4534
- await updateMutation.mutateAsync({
4535
- idAgent: agent.id,
4536
- id: agentTool.id,
4537
- body: { enabled: checked }
3952
+ const result = await createMutation.mutateAsync({
3953
+ id_tool: idTool,
3954
+ label: createForm.label.trim(),
3955
+ credentials_encrypted: createForm.credentials_encrypted.trim(),
3956
+ ...createForm.expires_at ? { expires_at: createForm.expires_at } : {}
4538
3957
  });
4539
- toast10.success(checked ? "Ferramenta ativada" : "Ferramenta desativada");
4540
- } catch (err) {
4541
- toast10.error(
4542
- err instanceof Error ? err.message : "Erro ao alterar estado da ferramenta"
4543
- );
3958
+ if (result.status === 1) {
3959
+ toast10.success("Credencial criada");
3960
+ setShowCreateDialog(false);
3961
+ setCreateForm({ id_tool: "", label: "", credentials_encrypted: "", expires_at: "" });
3962
+ } else {
3963
+ toast10.error(result.message || "Erro ao criar credencial");
3964
+ }
3965
+ } catch {
3966
+ toast10.error("Erro ao criar credencial");
4544
3967
  }
4545
3968
  }
4546
- async function handleAdd(tool) {
3969
+ function startEdit(cred) {
3970
+ setEditTarget(cred);
3971
+ setEditForm({
3972
+ id_tool: cred.id_tool ? String(cred.id_tool) : "",
3973
+ label: cred.label || "",
3974
+ credentials_encrypted: "",
3975
+ expires_at: cred.expires_at || "",
3976
+ status: cred.status
3977
+ });
3978
+ }
3979
+ async function handleSaveEdit() {
3980
+ if (!editTarget) return;
3981
+ const body = {};
3982
+ const newIdTool = editForm.id_tool ? parseInt(editForm.id_tool, 10) : null;
3983
+ if (newIdTool && newIdTool !== editTarget.id_tool) {
3984
+ body.id_tool = newIdTool;
3985
+ }
3986
+ if (editForm.label.trim() && editForm.label.trim() !== (editTarget.label || "")) {
3987
+ body.label = editForm.label.trim();
3988
+ }
3989
+ if (editForm.credentials_encrypted.trim()) {
3990
+ body.credentials_encrypted = editForm.credentials_encrypted.trim();
3991
+ }
3992
+ if (editForm.expires_at !== (editTarget.expires_at || "")) {
3993
+ body.expires_at = editForm.expires_at || null;
3994
+ }
3995
+ if (editForm.status && editForm.status !== editTarget.status) {
3996
+ body.status = editForm.status;
3997
+ }
3998
+ if (Object.keys(body).length === 0) {
3999
+ setEditTarget(null);
4000
+ return;
4001
+ }
4547
4002
  try {
4548
- await addMutation.mutateAsync({
4549
- idAgent: agent.id,
4550
- body: { id_tool: tool.id }
4003
+ const result = await updateMutation.mutateAsync({
4004
+ id: editTarget.id,
4005
+ body
4551
4006
  });
4552
- toast10.success("Ferramenta adicionada");
4553
- setAddOpen(false);
4554
- setSearch("");
4555
- } catch (err) {
4556
- toast10.error(
4557
- err instanceof Error ? err.message : "Erro ao adicionar ferramenta"
4558
- );
4007
+ if (result.status === 1) {
4008
+ toast10.success("Credencial atualizada");
4009
+ setEditTarget(null);
4010
+ } else {
4011
+ toast10.error(result.message || "Erro ao atualizar credencial");
4012
+ }
4013
+ } catch {
4014
+ toast10.error("Erro ao atualizar credencial");
4559
4015
  }
4560
4016
  }
4561
4017
  async function handleRemove() {
4562
4018
  if (!removeTarget) return;
4563
4019
  try {
4564
- await removeMutation.mutateAsync({
4565
- idAgent: agent.id,
4566
- id: removeTarget.id
4567
- });
4568
- toast10.success("Ferramenta removida");
4569
- } catch (err) {
4570
- toast10.error(
4571
- err instanceof Error ? err.message : "Erro ao remover ferramenta"
4572
- );
4020
+ const result = await deleteMutation.mutateAsync(removeTarget.id);
4021
+ if (result.status === 1) {
4022
+ toast10.success("Credencial removida");
4023
+ } else {
4024
+ toast10.error(result.message || "Erro ao remover credencial");
4025
+ }
4026
+ } catch {
4027
+ toast10.error("Erro ao remover credencial");
4573
4028
  } finally {
4574
4029
  setRemoveTarget(null);
4575
4030
  }
4576
4031
  }
4577
- function openConfig(agentTool) {
4578
- setConfigTarget(agentTool);
4579
- setConfigInstructions(agentTool.custom_instructions || "");
4580
- setConfigCredentialId(agentTool.id_tool_credential ? String(agentTool.id_tool_credential) : "");
4032
+ function handleConnect(cred) {
4033
+ if (!config.accountId || !config.token) return;
4034
+ const language = config.language ?? "pt-br";
4035
+ const idWl = config.idWl ?? 1;
4036
+ const url = `${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${config.accountId}/oauth/connect?id_tool=${cred.id_tool}`;
4037
+ window.open(url, "_blank");
4581
4038
  }
4582
- async function handleSaveConfig() {
4583
- if (!configTarget) return;
4584
- try {
4585
- const newCredentialId = configCredentialId ? parseInt(configCredentialId, 10) : null;
4586
- await updateMutation.mutateAsync({
4587
- idAgent: agent.id,
4588
- id: configTarget.id,
4589
- body: {
4590
- custom_instructions: configInstructions.trim() || null,
4591
- id_tool_credential: newCredentialId
4039
+ return /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
4040
+ /* @__PURE__ */ jsx16("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs14("div", { className: "relative flex-1 max-w-md", children: [
4041
+ /* @__PURE__ */ jsx16(Search3, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
4042
+ /* @__PURE__ */ jsx16(
4043
+ Input9,
4044
+ {
4045
+ placeholder: "Buscar credenciais\\u2026",
4046
+ "aria-label": "Buscar credenciais",
4047
+ name: "search",
4048
+ autoComplete: "off",
4049
+ value: search,
4050
+ onChange: (e) => setSearch(e.target.value),
4051
+ className: "pl-9"
4592
4052
  }
4593
- });
4594
- toast10.success("Configura\xE7\xE3o atualizada");
4595
- setConfigTarget(null);
4596
- } catch (err) {
4597
- toast10.error(
4598
- err instanceof Error ? err.message : "Erro ao atualizar configura\xE7\xE3o"
4599
- );
4600
- }
4601
- }
4602
- if (isLoading) {
4603
- return /* @__PURE__ */ jsx23("div", { className: "space-y-3 p-4", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx23(Skeleton6, { className: "h-14 w-full" }, i)) });
4604
- }
4605
- return /* @__PURE__ */ jsxs21("div", { className: "space-y-4 p-4", children: [
4606
- /* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between", children: [
4607
- /* @__PURE__ */ jsxs21("h3", { className: "text-sm font-medium text-muted-foreground", children: [
4608
- visibleAgentTools.length,
4609
- " ferramenta",
4610
- visibleAgentTools.length !== 1 ? "s" : "",
4611
- " associada",
4612
- visibleAgentTools.length !== 1 ? "s" : ""
4613
- ] }),
4614
- /* @__PURE__ */ jsxs21(Popover, { open: addOpen, onOpenChange: setAddOpen, children: [
4615
- /* @__PURE__ */ jsx23(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs21(Button13, { size: "sm", disabled: availableTools.length === 0, children: [
4616
- /* @__PURE__ */ jsx23(Plus3, { className: "mr-2 h-4 w-4" }),
4617
- "Adicionar Ferramenta"
4618
- ] }) }),
4619
- /* @__PURE__ */ jsxs21(PopoverContent, { className: "w-72 p-0", align: "end", children: [
4620
- /* @__PURE__ */ jsx23("div", { className: "p-2", children: /* @__PURE__ */ jsx23(
4053
+ )
4054
+ ] }) }),
4055
+ /* @__PURE__ */ jsx16(
4056
+ DataTable3,
4057
+ {
4058
+ columns,
4059
+ data: filteredCredentials,
4060
+ isLoading,
4061
+ emptyMessage: "Nenhuma credencial encontrada"
4062
+ }
4063
+ ),
4064
+ /* @__PURE__ */ jsx16(Dialog6, { open: showCreateDialog, onOpenChange: setShowCreateDialog, children: /* @__PURE__ */ jsxs14(DialogContent6, { children: [
4065
+ /* @__PURE__ */ jsx16(DialogHeader6, { children: /* @__PURE__ */ jsx16(DialogTitle6, { children: "Nova Credencial" }) }),
4066
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
4067
+ /* @__PURE__ */ jsxs14("div", { children: [
4068
+ /* @__PURE__ */ jsx16("label", { htmlFor: "cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
4069
+ /* @__PURE__ */ jsxs14(
4070
+ Select3,
4071
+ {
4072
+ value: createForm.id_tool,
4073
+ onValueChange: (val) => setCreateForm((f) => ({ ...f, id_tool: val })),
4074
+ children: [
4075
+ /* @__PURE__ */ jsx16(SelectTrigger3, { id: "cred-tool", children: /* @__PURE__ */ jsx16(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
4076
+ /* @__PURE__ */ jsx16(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx16(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
4077
+ ]
4078
+ }
4079
+ )
4080
+ ] }),
4081
+ /* @__PURE__ */ jsxs14("div", { children: [
4082
+ /* @__PURE__ */ jsx16("label", { htmlFor: "cred-label", className: "mb-1 block text-sm font-medium", children: "Label *" }),
4083
+ /* @__PURE__ */ jsx16(
4621
4084
  Input9,
4622
4085
  {
4623
- placeholder: "Buscar ferramenta\\u2026",
4624
- "aria-label": "Buscar ferramenta",
4625
- name: "search",
4626
- value: search,
4627
- onChange: (e) => setSearch(e.target.value),
4628
- className: "h-8"
4086
+ id: "cred-label",
4087
+ name: "label",
4088
+ value: createForm.label,
4089
+ onChange: (e) => setCreateForm((f) => ({ ...f, label: e.target.value })),
4090
+ placeholder: "Ex: Google Calendar - Cl\xEDnica S\xE3o Paulo"
4629
4091
  }
4630
- ) }),
4631
- /* @__PURE__ */ jsx23("div", { className: "max-h-48 overflow-y-auto", children: filteredAvailable.length === 0 ? /* @__PURE__ */ jsx23("p", { className: "p-3 text-center text-sm text-muted-foreground", children: "Nenhuma ferramenta dispon\xEDvel" }) : filteredAvailable.map((tool) => /* @__PURE__ */ jsxs21(
4632
- "button",
4092
+ )
4093
+ ] }),
4094
+ /* @__PURE__ */ jsxs14("div", { children: [
4095
+ /* @__PURE__ */ jsx16("label", { htmlFor: "cred-credential", className: "mb-1 block text-sm font-medium", children: "Credencial *" }),
4096
+ /* @__PURE__ */ jsx16(
4097
+ Input9,
4633
4098
  {
4634
- type: "button",
4635
- className: "flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-accent",
4636
- onClick: () => handleAdd(tool),
4637
- disabled: addMutation.isPending,
4638
- children: [
4639
- /* @__PURE__ */ jsx23(Wrench, { className: "h-4 w-4 text-muted-foreground" }),
4640
- /* @__PURE__ */ jsx23("span", { className: "flex-1 font-medium", children: tool.name }),
4641
- /* @__PURE__ */ jsx23(Badge8, { variant: "secondary", className: "text-xs", children: tool.type })
4642
- ]
4643
- },
4644
- tool.id
4645
- )) })
4646
- ] })
4647
- ] })
4648
- ] }),
4649
- visibleAgentTools.length === 0 ? /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center justify-center rounded-lg border border-dashed p-8 text-center", children: [
4650
- /* @__PURE__ */ jsx23(Wrench, { className: "mb-2 h-8 w-8 text-muted-foreground" }),
4651
- /* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "Nenhuma ferramenta associada. Clique em 'Adicionar Ferramenta' para come\xE7ar." })
4652
- ] }) : /* @__PURE__ */ jsx23("div", { className: "space-y-2", children: visibleAgentTools.map((agentTool) => {
4653
- const tool = getToolInfo(agentTool.id_tool);
4654
- return /* @__PURE__ */ jsxs21(
4655
- "div",
4656
- {
4657
- className: "flex items-center gap-3 rounded-lg border bg-card p-3",
4658
- children: [
4659
- /* @__PURE__ */ jsxs21("div", { className: "flex flex-1 flex-col gap-1 min-w-0", children: [
4660
- /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-2", children: [
4661
- /* @__PURE__ */ jsx23("span", { className: "truncate font-medium", children: tool?.name || `Ferramenta #${agentTool.id_tool}` }),
4662
- tool?.type && /* @__PURE__ */ jsx23(Badge8, { variant: "secondary", className: "shrink-0 text-xs", children: tool.type })
4663
- ] }),
4664
- agentTool.custom_instructions && /* @__PURE__ */ jsx23("p", { className: "truncate text-xs text-muted-foreground", children: agentTool.custom_instructions })
4665
- ] }),
4666
- /* @__PURE__ */ jsx23(
4667
- Switch5,
4668
- {
4669
- "aria-label": "Ativar/Desativar",
4670
- checked: agentTool.enabled,
4671
- onCheckedChange: (checked) => handleToggleEnabled(agentTool, checked),
4672
- disabled: updateMutation.isPending
4673
- }
4674
- ),
4675
- /* @__PURE__ */ jsx23(
4676
- Button13,
4677
- {
4678
- variant: "ghost",
4679
- size: "icon",
4680
- "aria-label": "Configurar",
4681
- className: "shrink-0 text-muted-foreground hover:text-foreground",
4682
- onClick: () => openConfig(agentTool),
4683
- title: "Configurar instru\xE7\xF5es",
4684
- children: /* @__PURE__ */ jsx23(Settings22, { className: "h-4 w-4" })
4685
- }
4686
- ),
4687
- /* @__PURE__ */ jsx23(
4688
- Button13,
4689
- {
4690
- variant: "ghost",
4691
- size: "icon",
4692
- "aria-label": "Remover",
4693
- className: "shrink-0 text-muted-foreground hover:text-destructive",
4694
- onClick: () => setRemoveTarget(agentTool),
4695
- children: /* @__PURE__ */ jsx23(Trash24, { className: "h-4 w-4" })
4696
- }
4697
- )
4698
- ]
4699
- },
4700
- agentTool.id
4701
- );
4702
- }) }),
4703
- /* @__PURE__ */ jsx23(
4099
+ id: "cred-credential",
4100
+ name: "credential",
4101
+ autoComplete: "off",
4102
+ type: "password",
4103
+ value: createForm.credentials_encrypted,
4104
+ onChange: (e) => setCreateForm((f) => ({
4105
+ ...f,
4106
+ credentials_encrypted: e.target.value
4107
+ })),
4108
+ placeholder: "Credencial encriptada"
4109
+ }
4110
+ )
4111
+ ] }),
4112
+ /* @__PURE__ */ jsxs14("div", { children: [
4113
+ /* @__PURE__ */ jsx16("label", { htmlFor: "cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o (opcional)" }),
4114
+ /* @__PURE__ */ jsx16(
4115
+ Input9,
4116
+ {
4117
+ id: "cred-expires",
4118
+ name: "expires",
4119
+ type: "date",
4120
+ value: createForm.expires_at,
4121
+ onChange: (e) => setCreateForm((f) => ({ ...f, expires_at: e.target.value }))
4122
+ }
4123
+ )
4124
+ ] })
4125
+ ] }),
4126
+ /* @__PURE__ */ jsxs14(DialogFooter6, { children: [
4127
+ /* @__PURE__ */ jsx16(
4128
+ Button11,
4129
+ {
4130
+ variant: "outline",
4131
+ onClick: () => setShowCreateDialog(false),
4132
+ children: "Cancelar"
4133
+ }
4134
+ ),
4135
+ /* @__PURE__ */ jsx16(
4136
+ Button11,
4137
+ {
4138
+ onClick: handleCreate,
4139
+ disabled: !createForm.id_tool || !createForm.label.trim() || !createForm.credentials_encrypted.trim() || createMutation.isPending,
4140
+ children: "Criar"
4141
+ }
4142
+ )
4143
+ ] })
4144
+ ] }) }),
4145
+ /* @__PURE__ */ jsx16(
4704
4146
  Dialog6,
4705
4147
  {
4706
- open: !!configTarget,
4707
- onOpenChange: (open) => !open && setConfigTarget(null),
4708
- children: /* @__PURE__ */ jsxs21(DialogContent6, { className: "sm:max-w-lg", children: [
4709
- /* @__PURE__ */ jsx23(DialogHeader6, { children: /* @__PURE__ */ jsx23(DialogTitle6, { children: "Instru\xE7\xF5es da Ferramenta" }) }),
4710
- /* @__PURE__ */ jsxs21("div", { className: "space-y-4", children: [
4711
- configTarget && getToolInfo(configTarget.id_tool)?.type !== "none" && /* @__PURE__ */ jsxs21("div", { className: "space-y-2", children: [
4712
- /* @__PURE__ */ jsx23(Label8, { htmlFor: "tool-credential", children: "Credencial" }),
4713
- /* @__PURE__ */ jsxs21(
4148
+ open: !!editTarget,
4149
+ onOpenChange: (open) => !open && setEditTarget(null),
4150
+ children: /* @__PURE__ */ jsxs14(DialogContent6, { children: [
4151
+ /* @__PURE__ */ jsx16(DialogHeader6, { children: /* @__PURE__ */ jsx16(DialogTitle6, { children: "Editar Credencial" }) }),
4152
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
4153
+ /* @__PURE__ */ jsxs14("div", { children: [
4154
+ /* @__PURE__ */ jsx16("label", { htmlFor: "edit-cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
4155
+ /* @__PURE__ */ jsxs14(
4714
4156
  Select3,
4715
4157
  {
4716
- value: configCredentialId || void 0,
4717
- onValueChange: (val) => setConfigCredentialId(val === "__none__" ? "" : val),
4158
+ value: editForm.id_tool,
4159
+ onValueChange: (val) => setEditForm((f) => ({ ...f, id_tool: val })),
4718
4160
  children: [
4719
- /* @__PURE__ */ jsx23(SelectTrigger3, { id: "tool-credential", children: /* @__PURE__ */ jsx23(SelectValue3, { placeholder: "Selecione uma credencial (opcional)" }) }),
4720
- /* @__PURE__ */ jsxs21(SelectContent3, { children: [
4721
- /* @__PURE__ */ jsx23(SelectItem3, { value: "__none__", children: "Nenhuma (autom\xE1tico)" }),
4722
- allCredentials.filter((c) => configTarget && c.id_tool === configTarget.id_tool && c.status === "active").map((c) => /* @__PURE__ */ jsx23(SelectItem3, { value: String(c.id), children: c.label || `Credencial #${c.id}` }, c.id))
4723
- ] })
4161
+ /* @__PURE__ */ jsx16(SelectTrigger3, { id: "edit-cred-tool", children: /* @__PURE__ */ jsx16(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
4162
+ /* @__PURE__ */ jsx16(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx16(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
4724
4163
  ]
4725
4164
  }
4726
- ),
4727
- /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: "Vincule uma credencial espec\xEDfica a esta ferramenta neste agente." })
4165
+ )
4728
4166
  ] }),
4729
- /* @__PURE__ */ jsxs21("div", { className: "space-y-2", children: [
4730
- /* @__PURE__ */ jsx23(Label8, { htmlFor: "tool-instructions", children: "Instru\xE7\xF5es Personalizadas" }),
4731
- /* @__PURE__ */ jsx23(
4732
- Textarea3,
4167
+ /* @__PURE__ */ jsxs14("div", { children: [
4168
+ /* @__PURE__ */ jsx16("label", { htmlFor: "edit-cred-label", className: "mb-1 block text-sm font-medium", children: "Label" }),
4169
+ /* @__PURE__ */ jsx16(
4170
+ Input9,
4733
4171
  {
4734
- id: "tool-instructions",
4735
- name: "instructions",
4736
- value: configInstructions,
4737
- onChange: (e) => setConfigInstructions(e.target.value),
4738
- placeholder: "Instru\\u00e7\\u00f5es sobre como e quando o agente deve usar esta ferramenta\\u2026",
4739
- rows: 6
4172
+ id: "edit-cred-label",
4173
+ name: "label",
4174
+ value: editForm.label,
4175
+ onChange: (e) => setEditForm((f) => ({ ...f, label: e.target.value })),
4176
+ placeholder: "Label da credencial"
4740
4177
  }
4741
- ),
4742
- /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: "Este texto \xE9 adicionado ao prompt do agente para orientar o uso da ferramenta." })
4178
+ )
4179
+ ] }),
4180
+ /* @__PURE__ */ jsxs14("div", { children: [
4181
+ /* @__PURE__ */ jsx16("label", { htmlFor: "edit-cred-credential", className: "mb-1 block text-sm font-medium", children: "Nova Credencial (vazio = manter atual)" }),
4182
+ /* @__PURE__ */ jsx16(
4183
+ Input9,
4184
+ {
4185
+ id: "edit-cred-credential",
4186
+ name: "credential",
4187
+ autoComplete: "off",
4188
+ type: "password",
4189
+ value: editForm.credentials_encrypted,
4190
+ onChange: (e) => setEditForm((f) => ({
4191
+ ...f,
4192
+ credentials_encrypted: e.target.value
4193
+ })),
4194
+ placeholder: "Nova credencial"
4195
+ }
4196
+ )
4197
+ ] }),
4198
+ /* @__PURE__ */ jsxs14("div", { children: [
4199
+ /* @__PURE__ */ jsx16("label", { htmlFor: "edit-cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o" }),
4200
+ /* @__PURE__ */ jsx16(
4201
+ Input9,
4202
+ {
4203
+ id: "edit-cred-expires",
4204
+ name: "expires",
4205
+ type: "date",
4206
+ value: editForm.expires_at,
4207
+ onChange: (e) => setEditForm((f) => ({ ...f, expires_at: e.target.value }))
4208
+ }
4209
+ )
4210
+ ] }),
4211
+ /* @__PURE__ */ jsxs14("div", { children: [
4212
+ /* @__PURE__ */ jsx16("label", { htmlFor: "edit-cred-status", className: "mb-1 block text-sm font-medium", children: "Status" }),
4213
+ /* @__PURE__ */ jsxs14(
4214
+ Select3,
4215
+ {
4216
+ value: editForm.status || void 0,
4217
+ onValueChange: (val) => setEditForm((f) => ({
4218
+ ...f,
4219
+ status: val
4220
+ })),
4221
+ children: [
4222
+ /* @__PURE__ */ jsx16(SelectTrigger3, { id: "edit-cred-status", children: /* @__PURE__ */ jsx16(SelectValue3, {}) }),
4223
+ /* @__PURE__ */ jsxs14(SelectContent3, { children: [
4224
+ /* @__PURE__ */ jsx16(SelectItem3, { value: "active", children: "Ativo" }),
4225
+ /* @__PURE__ */ jsx16(SelectItem3, { value: "expired", children: "Expirado" })
4226
+ ] })
4227
+ ]
4228
+ }
4229
+ )
4743
4230
  ] })
4744
4231
  ] }),
4745
- /* @__PURE__ */ jsxs21(DialogFooter6, { children: [
4746
- /* @__PURE__ */ jsx23(
4747
- Button13,
4232
+ /* @__PURE__ */ jsxs14(DialogFooter6, { children: [
4233
+ /* @__PURE__ */ jsx16(Button11, { variant: "outline", onClick: () => setEditTarget(null), children: "Cancelar" }),
4234
+ /* @__PURE__ */ jsx16(
4235
+ Button11,
4748
4236
  {
4749
- variant: "outline",
4750
- onClick: () => setConfigTarget(null),
4751
- children: "Cancelar"
4752
- }
4753
- ),
4754
- /* @__PURE__ */ jsx23(
4755
- Button13,
4756
- {
4757
- onClick: handleSaveConfig,
4237
+ onClick: handleSaveEdit,
4758
4238
  disabled: updateMutation.isPending,
4759
4239
  children: "Salvar"
4760
4240
  }
@@ -4763,571 +4243,1012 @@ function AgentToolsList({ agent, config }) {
4763
4243
  ] })
4764
4244
  }
4765
4245
  ),
4766
- /* @__PURE__ */ jsx23(
4767
- AlertDialog4,
4246
+ /* @__PURE__ */ jsx16(
4247
+ AlertDialog5,
4248
+ {
4249
+ open: !!removeTarget,
4250
+ onOpenChange: (open) => !open && setRemoveTarget(null),
4251
+ children: /* @__PURE__ */ jsxs14(AlertDialogContent5, { children: [
4252
+ /* @__PURE__ */ jsxs14(AlertDialogHeader5, { children: [
4253
+ /* @__PURE__ */ jsx16(AlertDialogTitle5, { children: "Remover credencial?" }),
4254
+ /* @__PURE__ */ jsx16(AlertDialogDescription5, { children: "A credencial ser\xE1 removida permanentemente." })
4255
+ ] }),
4256
+ /* @__PURE__ */ jsxs14(AlertDialogFooter5, { children: [
4257
+ /* @__PURE__ */ jsx16(AlertDialogCancel5, { children: "Cancelar" }),
4258
+ /* @__PURE__ */ jsx16(
4259
+ AlertDialogAction5,
4260
+ {
4261
+ onClick: handleRemove,
4262
+ disabled: deleteMutation.isPending,
4263
+ children: "Remover"
4264
+ }
4265
+ )
4266
+ ] })
4267
+ ] })
4268
+ }
4269
+ )
4270
+ ] });
4271
+ }
4272
+
4273
+ // src/components/capabilities/integration-card.tsx
4274
+ import { Badge as Badge9, Button as Button12, Tooltip as Tooltip5, TooltipContent as TooltipContent5, TooltipTrigger as TooltipTrigger5 } from "@greatapps/greatauth-ui/ui";
4275
+ import {
4276
+ CalendarSync as CalendarSync2,
4277
+ Plug as Plug3,
4278
+ Settings as Settings3,
4279
+ RefreshCw,
4280
+ Users as Users2,
4281
+ Clock,
4282
+ Plus as Plus3
4283
+ } from "lucide-react";
4284
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
4285
+ var ICON_MAP2 = {
4286
+ CalendarSync: CalendarSync2,
4287
+ Plug: Plug3,
4288
+ Settings: Settings3,
4289
+ RefreshCw,
4290
+ Users: Users2,
4291
+ Clock,
4292
+ Plus: Plus3
4293
+ };
4294
+ function resolveIcon2(name) {
4295
+ return ICON_MAP2[name] ?? Plug3;
4296
+ }
4297
+ var STATE_BADGES = {
4298
+ available: {
4299
+ label: "Dispon\xEDvel",
4300
+ className: "bg-muted text-muted-foreground"
4301
+ },
4302
+ connected: {
4303
+ label: "Conectado",
4304
+ className: "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
4305
+ },
4306
+ expired: {
4307
+ label: "Expirado",
4308
+ className: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
4309
+ },
4310
+ coming_soon: {
4311
+ label: "Em breve",
4312
+ className: "bg-muted text-muted-foreground"
4313
+ }
4314
+ };
4315
+ function getActionLabel(card) {
4316
+ if (card.isAddNew) return "Conectar";
4317
+ switch (card.state) {
4318
+ case "available":
4319
+ return "Conectar";
4320
+ case "connected":
4321
+ return "Configurar";
4322
+ case "expired":
4323
+ return "Reconectar";
4324
+ default:
4325
+ return "";
4326
+ }
4327
+ }
4328
+ function IntegrationCard({ card, onConnect }) {
4329
+ const { definition, state, sharedByAgentsCount, isAddNew, accountLabel } = card;
4330
+ const Icon = resolveIcon2(definition.icon);
4331
+ const isComingSoon = state === "coming_soon";
4332
+ const actionLabel = getActionLabel(card);
4333
+ if (isAddNew) {
4334
+ return /* @__PURE__ */ jsxs15(
4335
+ "div",
4336
+ {
4337
+ className: cn(
4338
+ "group relative flex flex-col gap-3 rounded-xl border border-dashed bg-card/50 p-5 transition-shadow",
4339
+ "hover:shadow-md hover:border-solid hover:bg-card cursor-pointer"
4340
+ ),
4341
+ role: "button",
4342
+ tabIndex: 0,
4343
+ "aria-label": `Adicionar conta ${definition.name}`,
4344
+ onClick: () => onConnect(card),
4345
+ onKeyDown: (e) => {
4346
+ if (e.key === "Enter" || e.key === " ") {
4347
+ e.preventDefault();
4348
+ onConnect(card);
4349
+ }
4350
+ },
4351
+ children: [
4352
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-2", children: [
4353
+ /* @__PURE__ */ jsx17("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/5 text-primary/60", children: /* @__PURE__ */ jsx17(Icon, { className: "h-5 w-5" }) }),
4354
+ /* @__PURE__ */ jsx17(Badge9, { variant: "outline", className: "text-xs bg-muted text-muted-foreground", children: "Adicionar" })
4355
+ ] }),
4356
+ /* @__PURE__ */ jsxs15("div", { className: "space-y-1", children: [
4357
+ /* @__PURE__ */ jsx17("h3", { className: "text-sm font-semibold leading-tight text-muted-foreground", children: definition.name }),
4358
+ /* @__PURE__ */ jsxs15("p", { className: "text-xs text-muted-foreground/70 leading-relaxed flex items-center gap-1", children: [
4359
+ /* @__PURE__ */ jsx17(Plus3, { className: "h-3 w-3" }),
4360
+ "Adicionar conta"
4361
+ ] })
4362
+ ] }),
4363
+ /* @__PURE__ */ jsx17("div", { className: "mt-auto flex items-center justify-end pt-1", children: /* @__PURE__ */ jsx17(
4364
+ Button12,
4365
+ {
4366
+ variant: "outline",
4367
+ size: "sm",
4368
+ className: "text-xs",
4369
+ onClick: (e) => {
4370
+ e.stopPropagation();
4371
+ onConnect(card);
4372
+ },
4373
+ children: actionLabel
4374
+ }
4375
+ ) })
4376
+ ]
4377
+ }
4378
+ );
4379
+ }
4380
+ const badge = STATE_BADGES[state];
4381
+ return /* @__PURE__ */ jsxs15(
4382
+ "div",
4383
+ {
4384
+ className: cn(
4385
+ "group relative flex flex-col gap-3 rounded-xl border bg-card p-5 transition-shadow",
4386
+ isComingSoon ? "opacity-60 cursor-default" : "hover:shadow-md cursor-pointer"
4387
+ ),
4388
+ role: "button",
4389
+ tabIndex: isComingSoon ? -1 : 0,
4390
+ "aria-label": `${definition.name}${accountLabel ? ` \u2014 ${accountLabel}` : ""} \u2014 ${badge.label}`,
4391
+ "aria-disabled": isComingSoon,
4392
+ onClick: () => !isComingSoon && onConnect(card),
4393
+ onKeyDown: (e) => {
4394
+ if (!isComingSoon && (e.key === "Enter" || e.key === " ")) {
4395
+ e.preventDefault();
4396
+ onConnect(card);
4397
+ }
4398
+ },
4399
+ children: [
4400
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-2", children: [
4401
+ /* @__PURE__ */ jsx17("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx17(Icon, { className: "h-5 w-5" }) }),
4402
+ /* @__PURE__ */ jsx17(Badge9, { variant: "outline", className: cn("text-xs", badge.className), children: badge.label })
4403
+ ] }),
4404
+ /* @__PURE__ */ jsxs15("div", { className: "space-y-1", children: [
4405
+ /* @__PURE__ */ jsx17("h3", { className: "text-sm font-semibold leading-tight", children: definition.name }),
4406
+ accountLabel ? /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground leading-relaxed truncate", title: accountLabel, children: accountLabel }) : /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground leading-relaxed", children: definition.description })
4407
+ ] }),
4408
+ /* @__PURE__ */ jsxs15("div", { className: "mt-auto flex items-center justify-between gap-2 pt-1", children: [
4409
+ sharedByAgentsCount > 0 ? /* @__PURE__ */ jsxs15(Tooltip5, { children: [
4410
+ /* @__PURE__ */ jsx17(TooltipTrigger5, { asChild: true, children: /* @__PURE__ */ jsxs15("span", { className: "inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400", children: [
4411
+ /* @__PURE__ */ jsx17(Users2, { className: "h-3.5 w-3.5" }),
4412
+ "Compartilhada"
4413
+ ] }) }),
4414
+ /* @__PURE__ */ jsx17(TooltipContent5, { children: "Esta credencial est\xE1 dispon\xEDvel para todos os agentes da conta" })
4415
+ ] }) : /* @__PURE__ */ jsx17("span", {}),
4416
+ !isComingSoon && /* @__PURE__ */ jsx17(
4417
+ Button12,
4418
+ {
4419
+ variant: state === "expired" ? "destructive" : "outline",
4420
+ size: "sm",
4421
+ className: "text-xs",
4422
+ onClick: (e) => {
4423
+ e.stopPropagation();
4424
+ onConnect(card);
4425
+ },
4426
+ children: actionLabel
4427
+ }
4428
+ )
4429
+ ] })
4430
+ ]
4431
+ }
4432
+ );
4433
+ }
4434
+
4435
+ // src/components/capabilities/advanced-tab.tsx
4436
+ import { useState as useState13 } from "react";
4437
+ import { Info } from "lucide-react";
4438
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
4439
+ function AdvancedTab({ config, agentId, gagentsApiUrl }) {
4440
+ const [editingTool, setEditingTool] = useState13(null);
4441
+ const [showToolForm, setShowToolForm] = useState13(false);
4442
+ function handleEditTool(tool) {
4443
+ setEditingTool(tool);
4444
+ setShowToolForm(true);
4445
+ }
4446
+ function handleToolFormOpenChange(open) {
4447
+ setShowToolForm(open);
4448
+ if (!open) setEditingTool(null);
4449
+ }
4450
+ return /* @__PURE__ */ jsxs16("div", { className: "space-y-8", children: [
4451
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-3 rounded-lg border border-blue-200 bg-blue-50 p-4 dark:border-blue-900 dark:bg-blue-950/30", children: [
4452
+ /* @__PURE__ */ jsx18(Info, { className: "mt-0.5 h-4 w-4 shrink-0 text-blue-600 dark:text-blue-400" }),
4453
+ /* @__PURE__ */ jsxs16("p", { className: "text-sm text-blue-800 dark:text-blue-300", children: [
4454
+ "Use as abas ",
4455
+ /* @__PURE__ */ jsx18("strong", { children: "Capacidades" }),
4456
+ " e ",
4457
+ /* @__PURE__ */ jsx18("strong", { children: "Integra\xE7\xF5es" }),
4458
+ " para configura\xE7\xE3o simplificada. Esta aba oferece controlo manual avan\xE7ado sobre ferramentas. As credenciais s\xE3o geridas dentro de cada ferramenta."
4459
+ ] })
4460
+ ] }),
4461
+ /* @__PURE__ */ jsxs16("section", { className: "space-y-3", children: [
4462
+ /* @__PURE__ */ jsx18("h3", { className: "text-sm font-medium", children: "Ferramentas" }),
4463
+ /* @__PURE__ */ jsx18(ToolsTable, { onEdit: handleEditTool, config })
4464
+ ] }),
4465
+ /* @__PURE__ */ jsx18(
4466
+ ToolFormDialog,
4768
4467
  {
4769
- open: !!removeTarget,
4770
- onOpenChange: (open) => !open && setRemoveTarget(null),
4771
- children: /* @__PURE__ */ jsxs21(AlertDialogContent4, { children: [
4772
- /* @__PURE__ */ jsxs21(AlertDialogHeader4, { children: [
4773
- /* @__PURE__ */ jsx23(AlertDialogTitle4, { children: "Remover ferramenta?" }),
4774
- /* @__PURE__ */ jsx23(AlertDialogDescription4, { children: "A ferramenta ser\xE1 desassociada deste agente." })
4775
- ] }),
4776
- /* @__PURE__ */ jsxs21(AlertDialogFooter4, { children: [
4777
- /* @__PURE__ */ jsx23(AlertDialogCancel4, { children: "Cancelar" }),
4778
- /* @__PURE__ */ jsx23(
4779
- AlertDialogAction4,
4780
- {
4781
- onClick: handleRemove,
4782
- disabled: removeMutation.isPending,
4783
- children: "Remover"
4784
- }
4785
- )
4786
- ] })
4787
- ] })
4468
+ open: showToolForm,
4469
+ onOpenChange: handleToolFormOpenChange,
4470
+ tool: editingTool ?? void 0,
4471
+ config
4788
4472
  }
4789
4473
  )
4790
4474
  ] });
4791
4475
  }
4792
4476
 
4793
- // src/components/tools/tool-credentials-form.tsx
4794
- import { useMemo as useMemo7, useState as useState15 } from "react";
4795
- import { DataTable as DataTable3 } from "@greatapps/greatauth-ui";
4477
+ // src/components/capabilities/integration-wizard.tsx
4478
+ import { useCallback as useCallback6, useEffect as useEffect5, useRef as useRef2, useState as useState14 } from "react";
4796
4479
  import {
4797
- Input as Input10,
4798
- Button as Button14,
4799
- Badge as Badge9,
4800
- Tooltip as Tooltip4,
4801
- TooltipTrigger as TooltipTrigger4,
4802
- TooltipContent as TooltipContent4,
4803
4480
  Dialog as Dialog7,
4804
4481
  DialogContent as DialogContent7,
4482
+ DialogFooter as DialogFooter7,
4805
4483
  DialogHeader as DialogHeader7,
4806
4484
  DialogTitle as DialogTitle7,
4807
- DialogFooter as DialogFooter7,
4808
- AlertDialog as AlertDialog5,
4809
- AlertDialogAction as AlertDialogAction5,
4810
- AlertDialogCancel as AlertDialogCancel5,
4811
- AlertDialogContent as AlertDialogContent5,
4812
- AlertDialogDescription as AlertDialogDescription5,
4813
- AlertDialogFooter as AlertDialogFooter5,
4814
- AlertDialogHeader as AlertDialogHeader5,
4815
- AlertDialogTitle as AlertDialogTitle5,
4485
+ Button as Button14
4486
+ } from "@greatapps/greatauth-ui/ui";
4487
+ import { Loader2 as Loader29, ChevronLeft, ChevronRight, Check as Check2 } from "lucide-react";
4488
+ import { toast as toast11 } from "sonner";
4489
+
4490
+ // src/components/capabilities/wizard-steps/info-step.tsx
4491
+ import { Check, Info as Info2 } from "lucide-react";
4492
+ import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
4493
+ function InfoStep({ integration, meta }) {
4494
+ return /* @__PURE__ */ jsxs17("div", { className: "space-y-6", children: [
4495
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-4", children: [
4496
+ meta.icon && /* @__PURE__ */ jsx19("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-muted", children: meta.icon }),
4497
+ /* @__PURE__ */ jsxs17("div", { className: "space-y-1", children: [
4498
+ /* @__PURE__ */ jsx19("h3", { className: "text-lg font-semibold", children: integration.name }),
4499
+ /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: integration.description })
4500
+ ] })
4501
+ ] }),
4502
+ meta.capabilities.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
4503
+ /* @__PURE__ */ jsx19("h4", { className: "text-sm font-medium", children: "O que esta integra\xE7\xE3o permite:" }),
4504
+ /* @__PURE__ */ jsx19("ul", { className: "space-y-2", children: meta.capabilities.map((cap, i) => /* @__PURE__ */ jsxs17("li", { className: "flex items-start gap-2 text-sm", children: [
4505
+ /* @__PURE__ */ jsx19(
4506
+ Check,
4507
+ {
4508
+ "aria-hidden": "true",
4509
+ className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
4510
+ }
4511
+ ),
4512
+ /* @__PURE__ */ jsxs17("div", { children: [
4513
+ /* @__PURE__ */ jsx19("span", { className: "font-medium", children: cap.label }),
4514
+ cap.description && /* @__PURE__ */ jsxs17("span", { className: "text-muted-foreground", children: [
4515
+ " ",
4516
+ "\u2014 ",
4517
+ cap.description
4518
+ ] })
4519
+ ] })
4520
+ ] }, i)) })
4521
+ ] }),
4522
+ meta.requirements.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
4523
+ /* @__PURE__ */ jsx19("h4", { className: "text-sm font-medium", children: "Requisitos:" }),
4524
+ /* @__PURE__ */ jsx19("ul", { className: "space-y-2", children: meta.requirements.map((req, i) => /* @__PURE__ */ jsxs17(
4525
+ "li",
4526
+ {
4527
+ className: "flex items-start gap-2 text-sm text-muted-foreground",
4528
+ children: [
4529
+ /* @__PURE__ */ jsx19(
4530
+ Info2,
4531
+ {
4532
+ "aria-hidden": "true",
4533
+ className: "mt-0.5 h-4 w-4 shrink-0 text-blue-500"
4534
+ }
4535
+ ),
4536
+ /* @__PURE__ */ jsx19("span", { children: req })
4537
+ ]
4538
+ },
4539
+ i
4540
+ )) })
4541
+ ] })
4542
+ ] });
4543
+ }
4544
+
4545
+ // src/components/capabilities/wizard-steps/credentials-step.tsx
4546
+ import { CheckCircle2, Loader2 as Loader27, AlertCircle, Shield } from "lucide-react";
4547
+ import { Button as Button13, Input as Input10, Label as Label6 } from "@greatapps/greatauth-ui/ui";
4548
+ import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
4549
+ function CredentialsStep({
4550
+ integration,
4551
+ meta,
4552
+ oauthStatus,
4553
+ oauthResult,
4554
+ apiKey,
4555
+ onApiKeyChange,
4556
+ onStartOAuth,
4557
+ isReconnect = false
4558
+ }) {
4559
+ if (integration.authType === "oauth2") {
4560
+ return /* @__PURE__ */ jsx20(
4561
+ OAuthCredentials,
4562
+ {
4563
+ integration,
4564
+ meta,
4565
+ oauthStatus,
4566
+ oauthResult,
4567
+ onStartOAuth,
4568
+ isReconnect
4569
+ }
4570
+ );
4571
+ }
4572
+ return /* @__PURE__ */ jsx20(ApiKeyCredentials, { apiKey, onApiKeyChange });
4573
+ }
4574
+ function OAuthCredentials({
4575
+ integration,
4576
+ meta,
4577
+ oauthStatus,
4578
+ oauthResult,
4579
+ onStartOAuth,
4580
+ isReconnect
4581
+ }) {
4582
+ const providerLabel = meta.providerLabel || integration.name;
4583
+ return /* @__PURE__ */ jsxs18("div", { className: "space-y-6", children: [
4584
+ /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
4585
+ /* @__PURE__ */ jsx20("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
4586
+ /* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: isReconnect ? `Reconecte sua conta ${providerLabel} para renovar a autoriza\xE7\xE3o.` : `Conecte sua conta ${providerLabel} para permitir o acesso.` })
4587
+ ] }),
4588
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-4 rounded-lg border p-6", children: [
4589
+ oauthStatus === "idle" && /* @__PURE__ */ jsxs18(
4590
+ Button13,
4591
+ {
4592
+ onClick: onStartOAuth,
4593
+ size: "lg",
4594
+ className: "gap-2",
4595
+ children: [
4596
+ meta.icon,
4597
+ isReconnect ? `Reconectar com ${providerLabel}` : `Conectar com ${providerLabel}`
4598
+ ]
4599
+ }
4600
+ ),
4601
+ oauthStatus === "waiting" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
4602
+ /* @__PURE__ */ jsx20(
4603
+ Loader27,
4604
+ {
4605
+ "aria-hidden": "true",
4606
+ className: "h-8 w-8 animate-spin text-muted-foreground"
4607
+ }
4608
+ ),
4609
+ /* @__PURE__ */ jsxs18("div", { children: [
4610
+ /* @__PURE__ */ jsx20("p", { className: "text-sm font-medium", children: "Aguardando autoriza\xE7\xE3o..." }),
4611
+ /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: "Complete o login na janela que foi aberta." })
4612
+ ] })
4613
+ ] }),
4614
+ oauthStatus === "success" && oauthResult && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
4615
+ /* @__PURE__ */ jsx20(
4616
+ CheckCircle2,
4617
+ {
4618
+ "aria-hidden": "true",
4619
+ className: "h-8 w-8 text-green-600"
4620
+ }
4621
+ ),
4622
+ /* @__PURE__ */ jsxs18("div", { children: [
4623
+ /* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-green-700", children: "Conectado com sucesso!" }),
4624
+ oauthResult.email && /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: oauthResult.email })
4625
+ ] })
4626
+ ] }),
4627
+ oauthStatus === "error" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
4628
+ /* @__PURE__ */ jsx20(
4629
+ AlertCircle,
4630
+ {
4631
+ "aria-hidden": "true",
4632
+ className: "h-8 w-8 text-destructive"
4633
+ }
4634
+ ),
4635
+ /* @__PURE__ */ jsxs18("div", { children: [
4636
+ /* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-destructive", children: "Falha na conex\xE3o" }),
4637
+ oauthResult?.error && /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: oauthResult.error })
4638
+ ] }),
4639
+ /* @__PURE__ */ jsx20(Button13, { variant: "outline", onClick: onStartOAuth, size: "sm", children: "Tentar novamente" })
4640
+ ] })
4641
+ ] }),
4642
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
4643
+ /* @__PURE__ */ jsx20(
4644
+ Shield,
4645
+ {
4646
+ "aria-hidden": "true",
4647
+ className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
4648
+ }
4649
+ ),
4650
+ /* @__PURE__ */ jsxs18("p", { className: "text-xs text-muted-foreground", children: [
4651
+ "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 ",
4652
+ providerLabel,
4653
+ "."
4654
+ ] })
4655
+ ] })
4656
+ ] });
4657
+ }
4658
+ function ApiKeyCredentials({
4659
+ apiKey,
4660
+ onApiKeyChange
4661
+ }) {
4662
+ return /* @__PURE__ */ jsxs18("div", { className: "space-y-6", children: [
4663
+ /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
4664
+ /* @__PURE__ */ jsx20("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
4665
+ /* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "Insira a chave de API para conectar a integra\xE7\xE3o." })
4666
+ ] }),
4667
+ /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
4668
+ /* @__PURE__ */ jsx20(Label6, { htmlFor: "integration-api-key", children: "Chave de API" }),
4669
+ /* @__PURE__ */ jsx20(
4670
+ Input10,
4671
+ {
4672
+ id: "integration-api-key",
4673
+ type: "password",
4674
+ autoComplete: "off",
4675
+ placeholder: "Insira sua chave de API...",
4676
+ value: apiKey,
4677
+ onChange: (e) => onApiKeyChange(e.target.value)
4678
+ }
4679
+ )
4680
+ ] }),
4681
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
4682
+ /* @__PURE__ */ jsx20(
4683
+ Shield,
4684
+ {
4685
+ "aria-hidden": "true",
4686
+ className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
4687
+ }
4688
+ ),
4689
+ /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: "Sua chave de API \xE9 armazenada de forma segura e encriptada. Nunca \xE9 exposta no frontend." })
4690
+ ] })
4691
+ ] });
4692
+ }
4693
+
4694
+ // src/components/capabilities/wizard-steps/config-step.tsx
4695
+ import { Loader2 as Loader28 } from "lucide-react";
4696
+ import {
4697
+ Label as Label7,
4816
4698
  Select as Select4,
4817
4699
  SelectContent as SelectContent4,
4818
4700
  SelectItem as SelectItem4,
4819
4701
  SelectTrigger as SelectTrigger4,
4820
4702
  SelectValue as SelectValue4
4821
4703
  } from "@greatapps/greatauth-ui/ui";
4822
- import { Trash2 as Trash25, Pencil as Pencil4, Link, Search as Search3 } from "lucide-react";
4823
- import { format as format3 } from "date-fns";
4824
- import { ptBR as ptBR3 } from "date-fns/locale";
4825
- import { toast as toast11 } from "sonner";
4826
- import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
4827
- function formatDate2(dateStr) {
4828
- if (!dateStr) return "Sem expira\xE7\xE3o";
4829
- return format3(new Date(dateStr), "dd/MM/yyyy", { locale: ptBR3 });
4704
+ import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
4705
+ function ConfigStep({
4706
+ integration,
4707
+ options,
4708
+ isLoading,
4709
+ selectedValue,
4710
+ onValueChange,
4711
+ selectLabel,
4712
+ selectPlaceholder
4713
+ }) {
4714
+ const label = selectLabel || getDefaultLabel(integration.slug);
4715
+ const placeholder = selectPlaceholder || getDefaultPlaceholder(integration.slug);
4716
+ return /* @__PURE__ */ jsxs19("div", { className: "space-y-6", children: [
4717
+ /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
4718
+ /* @__PURE__ */ jsx21("h3", { className: "text-lg font-semibold", children: "Configura\xE7\xE3o" }),
4719
+ /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Configure as op\xE7\xF5es espec\xEDficas da integra\xE7\xE3o." })
4720
+ ] }),
4721
+ isLoading ? /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-3 py-8", children: [
4722
+ /* @__PURE__ */ jsx21(
4723
+ Loader28,
4724
+ {
4725
+ "aria-hidden": "true",
4726
+ className: "h-6 w-6 animate-spin text-muted-foreground"
4727
+ }
4728
+ ),
4729
+ /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Carregando op\xE7\xF5es..." })
4730
+ ] }) : options.length === 0 ? /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-dashed p-6 text-center", children: /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Nenhuma op\xE7\xE3o dispon\xEDvel. A configura\xE7\xE3o padr\xE3o ser\xE1 usada." }) }) : /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
4731
+ /* @__PURE__ */ jsx21(Label7, { htmlFor: "integration-config-select", children: label }),
4732
+ /* @__PURE__ */ jsxs19(Select4, { value: selectedValue, onValueChange, children: [
4733
+ /* @__PURE__ */ jsx21(SelectTrigger4, { id: "integration-config-select", children: /* @__PURE__ */ jsx21(SelectValue4, { placeholder }) }),
4734
+ /* @__PURE__ */ jsx21(SelectContent4, { children: options.map((opt) => /* @__PURE__ */ jsxs19(SelectItem4, { value: opt.id, children: [
4735
+ /* @__PURE__ */ jsx21("span", { children: opt.label }),
4736
+ opt.description && /* @__PURE__ */ jsxs19("span", { className: "ml-2 text-xs text-muted-foreground", children: [
4737
+ "(",
4738
+ opt.description,
4739
+ ")"
4740
+ ] })
4741
+ ] }, opt.id)) })
4742
+ ] })
4743
+ ] })
4744
+ ] });
4830
4745
  }
4831
- function useColumns3(tools, onEdit, onConnect, onRemove) {
4832
- function getToolName(idTool) {
4833
- if (!idTool) return "\u2014";
4834
- const tool = tools.find((t) => t.id === idTool);
4835
- return tool?.name || `Ferramenta #${idTool}`;
4836
- }
4837
- function getToolType(idTool) {
4838
- if (!idTool) return null;
4839
- const tool = tools.find((t) => t.id === idTool);
4840
- return tool?.type || null;
4746
+ function getDefaultLabel(slug) {
4747
+ switch (slug) {
4748
+ case "google_calendar":
4749
+ return "Calend\xE1rio";
4750
+ default:
4751
+ return "Op\xE7\xE3o";
4841
4752
  }
4842
- return [
4843
- {
4844
- accessorKey: "label",
4845
- header: "Label",
4846
- cell: ({ row }) => /* @__PURE__ */ jsx24("span", { className: "font-medium", children: row.original.label || "\u2014" })
4847
- },
4848
- {
4849
- accessorKey: "id_tool",
4850
- header: "Ferramenta",
4851
- cell: ({ row }) => /* @__PURE__ */ jsx24("span", { className: "text-sm", children: getToolName(row.original.id_tool) })
4852
- },
4853
- {
4854
- accessorKey: "status",
4855
- header: "Status",
4856
- cell: ({ row }) => /* @__PURE__ */ jsx24(
4857
- Badge9,
4753
+ }
4754
+ function getDefaultPlaceholder(slug) {
4755
+ switch (slug) {
4756
+ case "google_calendar":
4757
+ return "Selecione o calend\xE1rio...";
4758
+ default:
4759
+ return "Selecione uma op\xE7\xE3o...";
4760
+ }
4761
+ }
4762
+
4763
+ // src/components/capabilities/wizard-steps/confirm-step.tsx
4764
+ import { CheckCircle2 as CheckCircle22 } from "lucide-react";
4765
+ import { Label as Label8 } from "@greatapps/greatauth-ui/ui";
4766
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
4767
+ function ConfirmStep({
4768
+ integration,
4769
+ oauthResult,
4770
+ selectedConfigOption,
4771
+ enableOnComplete,
4772
+ onEnableChange
4773
+ }) {
4774
+ return /* @__PURE__ */ jsxs20("div", { className: "space-y-6", children: [
4775
+ /* @__PURE__ */ jsxs20("div", { className: "space-y-2", children: [
4776
+ /* @__PURE__ */ jsx22("h3", { className: "text-lg font-semibold", children: "Confirma\xE7\xE3o" }),
4777
+ /* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Revise as configura\xE7\xF5es antes de concluir." })
4778
+ ] }),
4779
+ /* @__PURE__ */ jsxs20("div", { className: "space-y-3 rounded-lg border p-4", children: [
4780
+ /* @__PURE__ */ jsx22(SummaryRow, { label: "Integra\xE7\xE3o", value: integration.name }),
4781
+ oauthResult?.email && /* @__PURE__ */ jsx22(SummaryRow, { label: "Conta conectada", value: oauthResult.email }),
4782
+ selectedConfigOption && /* @__PURE__ */ jsx22(
4783
+ SummaryRow,
4858
4784
  {
4859
- variant: row.original.status === "active" ? "default" : "destructive",
4860
- children: row.original.status === "active" ? "Ativo" : "Expirado"
4785
+ label: getConfigLabel(integration.slug),
4786
+ value: selectedConfigOption.label
4787
+ }
4788
+ ),
4789
+ /* @__PURE__ */ jsx22(
4790
+ SummaryRow,
4791
+ {
4792
+ label: "Tipo de autentica\xE7\xE3o",
4793
+ value: integration.authType === "oauth2" ? "OAuth 2.0" : "API Key"
4861
4794
  }
4862
4795
  )
4863
- },
4864
- {
4865
- accessorKey: "expires_at",
4866
- header: "Expira em",
4867
- cell: ({ row }) => /* @__PURE__ */ jsx24("span", { className: "text-muted-foreground text-sm", children: formatDate2(row.original.expires_at) })
4868
- },
4869
- {
4870
- accessorKey: "datetime_add",
4871
- header: "Criado em",
4872
- cell: ({ row }) => /* @__PURE__ */ jsx24("span", { className: "text-muted-foreground text-sm", children: formatDate2(row.original.datetime_add) })
4873
- },
4874
- {
4875
- id: "actions",
4876
- header: "A\xE7\xF5es",
4877
- size: 100,
4878
- enableSorting: false,
4879
- cell: ({ row }) => /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1", children: [
4880
- getToolType(row.original.id_tool) === "oauth2" && /* @__PURE__ */ jsxs22(Tooltip4, { children: [
4881
- /* @__PURE__ */ jsx24(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx24(
4882
- Button14,
4883
- {
4884
- variant: "ghost",
4885
- size: "icon",
4886
- className: "h-8 w-8",
4887
- "aria-label": "Vincular",
4888
- disabled: true,
4889
- children: /* @__PURE__ */ jsx24(Link, { className: "h-4 w-4" })
4890
- }
4891
- ) }),
4892
- /* @__PURE__ */ jsx24(TooltipContent4, { children: "Em breve" })
4893
- ] }),
4894
- /* @__PURE__ */ jsxs22(Tooltip4, { children: [
4895
- /* @__PURE__ */ jsx24(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx24(
4896
- Button14,
4897
- {
4898
- variant: "ghost",
4899
- size: "icon",
4900
- className: "h-8 w-8",
4901
- "aria-label": "Editar",
4902
- onClick: () => onEdit(row.original),
4903
- children: /* @__PURE__ */ jsx24(Pencil4, { className: "h-4 w-4" })
4904
- }
4905
- ) }),
4906
- /* @__PURE__ */ jsx24(TooltipContent4, { children: "Editar" })
4907
- ] }),
4908
- /* @__PURE__ */ jsxs22(Tooltip4, { children: [
4909
- /* @__PURE__ */ jsx24(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx24(
4910
- Button14,
4796
+ ] }),
4797
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between rounded-lg border p-4", children: [
4798
+ /* @__PURE__ */ jsxs20("div", { className: "space-y-0.5", children: [
4799
+ /* @__PURE__ */ jsx22(Label8, { htmlFor: "enable-on-complete", className: "text-sm font-medium", children: "Ativar imediatamente" }),
4800
+ /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: "A integra\xE7\xE3o ficar\xE1 ativa assim que concluir o assistente." })
4801
+ ] }),
4802
+ /* @__PURE__ */ jsx22(
4803
+ "button",
4804
+ {
4805
+ id: "enable-on-complete",
4806
+ role: "switch",
4807
+ type: "button",
4808
+ "aria-checked": enableOnComplete,
4809
+ onClick: () => onEnableChange(!enableOnComplete),
4810
+ className: `
4811
+ relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent
4812
+ transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2
4813
+ focus-visible:ring-ring focus-visible:ring-offset-2
4814
+ ${enableOnComplete ? "bg-primary" : "bg-muted"}
4815
+ `,
4816
+ children: /* @__PURE__ */ jsx22(
4817
+ "span",
4911
4818
  {
4912
- variant: "ghost",
4913
- size: "icon",
4914
- className: "h-8 w-8 text-destructive hover:text-destructive",
4915
- "aria-label": "Excluir",
4916
- onClick: () => onRemove(row.original),
4917
- children: /* @__PURE__ */ jsx24(Trash25, { className: "h-4 w-4" })
4819
+ "aria-hidden": "true",
4820
+ className: `
4821
+ pointer-events-none inline-block h-5 w-5 transform rounded-full bg-background shadow-lg
4822
+ ring-0 transition duration-200 ease-in-out
4823
+ ${enableOnComplete ? "translate-x-5" : "translate-x-0"}
4824
+ `
4918
4825
  }
4919
- ) }),
4920
- /* @__PURE__ */ jsx24(TooltipContent4, { children: "Remover" })
4921
- ] })
4922
- ] })
4923
- }
4924
- ];
4826
+ )
4827
+ }
4828
+ )
4829
+ ] }),
4830
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 rounded-md bg-green-50 p-3 dark:bg-green-950/20", children: [
4831
+ /* @__PURE__ */ jsx22(
4832
+ CheckCircle22,
4833
+ {
4834
+ "aria-hidden": "true",
4835
+ className: "h-4 w-4 shrink-0 text-green-600"
4836
+ }
4837
+ ),
4838
+ /* @__PURE__ */ jsx22("p", { className: "text-xs text-green-700 dark:text-green-400", children: 'Tudo pronto! Clique em "Concluir" para finalizar a configura\xE7\xE3o.' })
4839
+ ] })
4840
+ ] });
4925
4841
  }
4926
- function ToolCredentialsForm({
4927
- credentials,
4928
- isLoading,
4842
+ function SummaryRow({ label, value }) {
4843
+ return /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between text-sm", children: [
4844
+ /* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: label }),
4845
+ /* @__PURE__ */ jsx22("span", { className: "font-medium", children: value })
4846
+ ] });
4847
+ }
4848
+ function getConfigLabel(slug) {
4849
+ switch (slug) {
4850
+ case "google_calendar":
4851
+ return "Calend\xE1rio";
4852
+ default:
4853
+ return "Configura\xE7\xE3o";
4854
+ }
4855
+ }
4856
+
4857
+ // src/components/capabilities/integration-wizard.tsx
4858
+ import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
4859
+ var STEPS = ["info", "credentials", "config", "confirm"];
4860
+ var STEP_LABELS = {
4861
+ info: "Informa\xE7\xE3o",
4862
+ credentials: "Credenciais",
4863
+ config: "Configura\xE7\xE3o",
4864
+ confirm: "Confirma\xE7\xE3o"
4865
+ };
4866
+ function IntegrationWizard({
4867
+ open,
4868
+ onOpenChange,
4869
+ integration,
4870
+ meta,
4871
+ agentId: _agentId,
4929
4872
  config,
4873
+ onComplete,
4930
4874
  gagentsApiUrl,
4931
- createOpen: externalCreateOpen,
4932
- onCreateOpenChange
4875
+ existingCredentialId,
4876
+ loadConfigOptions,
4877
+ existingConfigValue
4933
4878
  }) {
4934
- const createMutation = useCreateToolCredential(config);
4935
- const updateMutation = useUpdateToolCredential(config);
4936
- const deleteMutation = useDeleteToolCredential(config);
4937
- const { data: toolsData } = useTools(config);
4938
- const tools = (toolsData?.data || []).filter((t) => !t.slug?.startsWith("gclinic_"));
4939
- const [search, setSearch] = useState15("");
4940
- const [internalCreateOpen, setInternalCreateOpen] = useState15(false);
4941
- const showCreateDialog = externalCreateOpen ?? internalCreateOpen;
4942
- const setShowCreateDialog = onCreateOpenChange ?? setInternalCreateOpen;
4943
- const [createForm, setCreateForm] = useState15({
4944
- id_tool: "",
4945
- label: "",
4946
- credentials_encrypted: "",
4947
- expires_at: ""
4948
- });
4949
- const [editTarget, setEditTarget] = useState15(null);
4950
- const [editForm, setEditForm] = useState15({
4951
- id_tool: "",
4952
- label: "",
4953
- credentials_encrypted: "",
4954
- expires_at: "",
4955
- status: ""
4956
- });
4957
- const [removeTarget, setRemoveTarget] = useState15(null);
4958
- const internalToolIds = useMemo7(() => {
4959
- const allRawTools = toolsData?.data || [];
4960
- return new Set(
4961
- allRawTools.filter((t) => t.slug?.startsWith("gclinic_")).map((t) => t.id)
4962
- );
4963
- }, [toolsData]);
4964
- const filteredCredentials = useMemo7(() => {
4965
- const visible = credentials.filter(
4966
- (cred) => !cred.id_tool || !internalToolIds.has(cred.id_tool)
4967
- );
4968
- if (!search) return visible;
4969
- const term = search.toLowerCase();
4970
- return visible.filter((cred) => {
4971
- const toolName = tools.find((t) => t.id === cred.id_tool)?.name || "";
4972
- return (cred.label || "").toLowerCase().includes(term) || toolName.toLowerCase().includes(term);
4973
- });
4974
- }, [credentials, search, tools, internalToolIds]);
4975
- const columns = useColumns3(
4976
- tools,
4977
- (cred) => startEdit(cred),
4978
- (cred) => handleConnect(cred),
4979
- (cred) => setRemoveTarget(cred)
4879
+ const isReconnect = !!existingCredentialId;
4880
+ const [currentStep, setCurrentStep] = useState14("info");
4881
+ const currentIndex = STEPS.indexOf(currentStep);
4882
+ const [oauthStatus, setOauthStatus] = useState14("idle");
4883
+ const [oauthResult, setOauthResult] = useState14(null);
4884
+ const popupRef = useRef2(null);
4885
+ const popupPollRef = useRef2(null);
4886
+ const [apiKey, setApiKey] = useState14("");
4887
+ const [configOptions, setConfigOptions] = useState14([]);
4888
+ const [configLoading, setConfigLoading] = useState14(false);
4889
+ const [selectedConfigValue, setSelectedConfigValue] = useState14("");
4890
+ const [enableOnComplete, setEnableOnComplete] = useState14(true);
4891
+ const [isSubmitting, setIsSubmitting] = useState14(false);
4892
+ useEffect5(() => {
4893
+ return () => {
4894
+ if (popupPollRef.current) {
4895
+ clearInterval(popupPollRef.current);
4896
+ }
4897
+ };
4898
+ }, []);
4899
+ useEffect5(() => {
4900
+ if (open) {
4901
+ setCurrentStep("info");
4902
+ setOauthStatus("idle");
4903
+ setOauthResult(null);
4904
+ setApiKey("");
4905
+ setConfigOptions([]);
4906
+ setConfigLoading(false);
4907
+ setSelectedConfigValue(existingConfigValue ?? "");
4908
+ setEnableOnComplete(true);
4909
+ setIsSubmitting(false);
4910
+ } else {
4911
+ if (popupRef.current && !popupRef.current.closed) {
4912
+ popupRef.current.close();
4913
+ }
4914
+ if (popupPollRef.current) {
4915
+ clearInterval(popupPollRef.current);
4916
+ popupPollRef.current = null;
4917
+ }
4918
+ }
4919
+ }, [open]);
4920
+ const handleOAuthMessage = useCallback6(
4921
+ (event) => {
4922
+ try {
4923
+ if (event.origin !== new URL(gagentsApiUrl).origin) return;
4924
+ } catch {
4925
+ return;
4926
+ }
4927
+ if (!event.data || typeof event.data !== "object") return;
4928
+ const msg = event.data;
4929
+ if (msg.type !== "oauth-callback") return;
4930
+ if (msg.success) {
4931
+ setOauthStatus("success");
4932
+ setOauthResult({
4933
+ success: true,
4934
+ email: msg.email,
4935
+ credentialId: msg.credentialId
4936
+ });
4937
+ const credId = msg.credentialId || existingCredentialId;
4938
+ if (credId && loadConfigOptions && meta.hasConfigStep) {
4939
+ setConfigLoading(true);
4940
+ loadConfigOptions(credId).then((opts) => {
4941
+ setConfigOptions(opts);
4942
+ if (opts.length === 1) {
4943
+ setSelectedConfigValue(opts[0].id);
4944
+ }
4945
+ }).catch(() => setConfigOptions([])).finally(() => setConfigLoading(false));
4946
+ }
4947
+ setTimeout(() => {
4948
+ setCurrentStep(meta.hasConfigStep ? "config" : "confirm");
4949
+ }, 1200);
4950
+ } else {
4951
+ setOauthStatus("error");
4952
+ setOauthResult({
4953
+ success: false,
4954
+ error: msg.error || "Falha na autoriza\xE7\xE3o"
4955
+ });
4956
+ }
4957
+ },
4958
+ [gagentsApiUrl, existingCredentialId, meta.hasConfigStep, loadConfigOptions]
4980
4959
  );
4981
- async function handleCreate() {
4982
- const idTool = parseInt(createForm.id_tool, 10);
4983
- if (!idTool || !createForm.label.trim() || !createForm.credentials_encrypted.trim()) return;
4960
+ useEffect5(() => {
4961
+ if (!open) return;
4962
+ window.addEventListener("message", handleOAuthMessage);
4963
+ return () => window.removeEventListener("message", handleOAuthMessage);
4964
+ }, [open, handleOAuthMessage]);
4965
+ async function startOAuth() {
4966
+ const { language = "pt-br", idWl = 1, accountId, token } = config;
4967
+ setOauthStatus("waiting");
4984
4968
  try {
4985
- const result = await createMutation.mutateAsync({
4986
- id_tool: idTool,
4987
- label: createForm.label.trim(),
4988
- credentials_encrypted: createForm.credentials_encrypted.trim(),
4989
- ...createForm.expires_at ? { expires_at: createForm.expires_at } : {}
4969
+ let authorizeUrl = `${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${accountId}/oauth/authorize/${integration.slug}`;
4970
+ if (existingCredentialId) {
4971
+ authorizeUrl += `?credential_id=${existingCredentialId}`;
4972
+ }
4973
+ const response = await fetch(authorizeUrl, {
4974
+ headers: { Authorization: `Bearer ${token}` }
4990
4975
  });
4991
- if (result.status === 1) {
4992
- toast11.success("Credencial criada");
4993
- setShowCreateDialog(false);
4994
- setCreateForm({ id_tool: "", label: "", credentials_encrypted: "", expires_at: "" });
4995
- } else {
4996
- toast11.error(result.message || "Erro ao criar credencial");
4976
+ const result = await response.json();
4977
+ if (result.status !== 1 || !result.data?.auth_url) {
4978
+ setOauthStatus("error");
4979
+ setOauthResult({
4980
+ success: false,
4981
+ error: result.message || "Erro ao obter URL de autoriza\xE7\xE3o"
4982
+ });
4983
+ return;
4997
4984
  }
4998
- } catch {
4999
- toast11.error("Erro ao criar credencial");
4985
+ const popup = window.open(
4986
+ result.data.auth_url,
4987
+ "oauth-popup",
4988
+ "width=500,height=600,scrollbars=yes,resizable=yes"
4989
+ );
4990
+ popupRef.current = popup;
4991
+ if (popup) {
4992
+ if (popupPollRef.current) {
4993
+ clearInterval(popupPollRef.current);
4994
+ }
4995
+ popupPollRef.current = setInterval(() => {
4996
+ if (popup.closed) {
4997
+ if (popupPollRef.current) {
4998
+ clearInterval(popupPollRef.current);
4999
+ popupPollRef.current = null;
5000
+ }
5001
+ setOauthStatus(
5002
+ (prev) => prev === "waiting" ? "error" : prev
5003
+ );
5004
+ setOauthResult(
5005
+ (prev) => prev === null ? { success: false, error: "Janela fechada antes de concluir" } : prev
5006
+ );
5007
+ }
5008
+ }, 500);
5009
+ }
5010
+ } catch (err) {
5011
+ setOauthStatus("error");
5012
+ setOauthResult({
5013
+ success: false,
5014
+ error: "Erro de rede ao obter URL de autoriza\xE7\xE3o"
5015
+ });
5000
5016
  }
5001
5017
  }
5002
- function startEdit(cred) {
5003
- setEditTarget(cred);
5004
- setEditForm({
5005
- id_tool: cred.id_tool ? String(cred.id_tool) : "",
5006
- label: cred.label || "",
5007
- credentials_encrypted: "",
5008
- expires_at: cred.expires_at || "",
5009
- status: cred.status
5010
- });
5011
- }
5012
- async function handleSaveEdit() {
5013
- if (!editTarget) return;
5014
- const body = {};
5015
- const newIdTool = editForm.id_tool ? parseInt(editForm.id_tool, 10) : null;
5016
- if (newIdTool && newIdTool !== editTarget.id_tool) {
5017
- body.id_tool = newIdTool;
5018
- }
5019
- if (editForm.label.trim() && editForm.label.trim() !== (editTarget.label || "")) {
5020
- body.label = editForm.label.trim();
5021
- }
5022
- if (editForm.credentials_encrypted.trim()) {
5023
- body.credentials_encrypted = editForm.credentials_encrypted.trim();
5018
+ function canAdvance() {
5019
+ switch (currentStep) {
5020
+ case "info":
5021
+ return true;
5022
+ case "credentials":
5023
+ if (integration.authType === "oauth2") {
5024
+ return oauthStatus === "success";
5025
+ }
5026
+ return apiKey.trim().length > 0;
5027
+ case "config":
5028
+ return true;
5029
+ case "confirm":
5030
+ return true;
5031
+ default:
5032
+ return false;
5024
5033
  }
5025
- if (editForm.expires_at !== (editTarget.expires_at || "")) {
5026
- body.expires_at = editForm.expires_at || null;
5034
+ }
5035
+ function goNext() {
5036
+ if (!canAdvance()) return;
5037
+ if (currentStep === "credentials" && !meta.hasConfigStep) {
5038
+ setCurrentStep("confirm");
5039
+ return;
5027
5040
  }
5028
- if (editForm.status && editForm.status !== editTarget.status) {
5029
- body.status = editForm.status;
5041
+ const nextIndex = currentIndex + 1;
5042
+ if (nextIndex < STEPS.length) {
5043
+ setCurrentStep(STEPS[nextIndex]);
5030
5044
  }
5031
- if (Object.keys(body).length === 0) {
5032
- setEditTarget(null);
5045
+ }
5046
+ function goPrev() {
5047
+ if (currentStep === "confirm" && !meta.hasConfigStep) {
5048
+ setCurrentStep("credentials");
5033
5049
  return;
5034
5050
  }
5035
- try {
5036
- const result = await updateMutation.mutateAsync({
5037
- id: editTarget.id,
5038
- body
5039
- });
5040
- if (result.status === 1) {
5041
- toast11.success("Credencial atualizada");
5042
- setEditTarget(null);
5043
- } else {
5044
- toast11.error(result.message || "Erro ao atualizar credencial");
5045
- }
5046
- } catch {
5047
- toast11.error("Erro ao atualizar credencial");
5051
+ const prevIndex = currentIndex - 1;
5052
+ if (prevIndex >= 0) {
5053
+ setCurrentStep(STEPS[prevIndex]);
5048
5054
  }
5049
5055
  }
5050
- async function handleRemove() {
5051
- if (!removeTarget) return;
5056
+ async function handleComplete() {
5057
+ setIsSubmitting(true);
5052
5058
  try {
5053
- const result = await deleteMutation.mutateAsync(removeTarget.id);
5054
- if (result.status === 1) {
5055
- toast11.success("Credencial removida");
5056
- } else {
5057
- toast11.error(result.message || "Erro ao remover credencial");
5058
- }
5059
+ onComplete();
5060
+ onOpenChange(false);
5061
+ toast11.success(
5062
+ `${integration.name} ${isReconnect ? "reconectado" : "configurado"} com sucesso!`
5063
+ );
5059
5064
  } catch {
5060
- toast11.error("Erro ao remover credencial");
5065
+ toast11.error("Erro ao finalizar configura\xE7\xE3o");
5061
5066
  } finally {
5062
- setRemoveTarget(null);
5067
+ setIsSubmitting(false);
5063
5068
  }
5064
5069
  }
5065
- function handleConnect(cred) {
5066
- if (!config.accountId || !config.token) return;
5067
- const language = config.language ?? "pt-br";
5068
- const idWl = config.idWl ?? 1;
5069
- const url = `${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${config.accountId}/oauth/connect?id_tool=${cred.id_tool}`;
5070
- window.open(url, "_blank");
5071
- }
5072
- return /* @__PURE__ */ jsxs22("div", { className: "space-y-4", children: [
5073
- /* @__PURE__ */ jsx24("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs22("div", { className: "relative flex-1 max-w-md", children: [
5074
- /* @__PURE__ */ jsx24(Search3, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
5075
- /* @__PURE__ */ jsx24(
5076
- Input10,
5070
+ const selectedConfigOption = configOptions.find((o) => o.id === selectedConfigValue) || null;
5071
+ const isLastStep = currentStep === "confirm";
5072
+ const effectiveSteps = meta.hasConfigStep ? STEPS : STEPS.filter((s) => s !== "config");
5073
+ return /* @__PURE__ */ jsx23(Dialog7, { open, onOpenChange, children: /* @__PURE__ */ jsxs21(DialogContent7, { className: "sm:max-w-lg", children: [
5074
+ /* @__PURE__ */ jsx23(DialogHeader7, { children: /* @__PURE__ */ jsx23(DialogTitle7, { children: integration.name }) }),
5075
+ /* @__PURE__ */ jsx23(StepIndicator, { steps: effectiveSteps, currentStep }),
5076
+ /* @__PURE__ */ jsxs21("div", { className: "min-h-[280px] py-2", children: [
5077
+ currentStep === "info" && /* @__PURE__ */ jsx23(
5078
+ InfoStep,
5077
5079
  {
5078
- placeholder: "Buscar credenciais\\u2026",
5079
- "aria-label": "Buscar credenciais",
5080
- name: "search",
5081
- autoComplete: "off",
5082
- value: search,
5083
- onChange: (e) => setSearch(e.target.value),
5084
- className: "pl-9"
5080
+ integration,
5081
+ meta
5082
+ }
5083
+ ),
5084
+ currentStep === "credentials" && /* @__PURE__ */ jsx23(
5085
+ CredentialsStep,
5086
+ {
5087
+ integration,
5088
+ meta,
5089
+ oauthStatus,
5090
+ oauthResult,
5091
+ apiKey,
5092
+ onApiKeyChange: setApiKey,
5093
+ onStartOAuth: startOAuth,
5094
+ isReconnect
5095
+ }
5096
+ ),
5097
+ currentStep === "config" && /* @__PURE__ */ jsx23(
5098
+ ConfigStep,
5099
+ {
5100
+ integration,
5101
+ options: configOptions,
5102
+ isLoading: configLoading,
5103
+ selectedValue: selectedConfigValue,
5104
+ onValueChange: setSelectedConfigValue
5105
+ }
5106
+ ),
5107
+ currentStep === "confirm" && /* @__PURE__ */ jsx23(
5108
+ ConfirmStep,
5109
+ {
5110
+ integration,
5111
+ oauthResult,
5112
+ selectedConfigOption,
5113
+ enableOnComplete,
5114
+ onEnableChange: setEnableOnComplete
5085
5115
  }
5086
5116
  )
5087
- ] }) }),
5088
- /* @__PURE__ */ jsx24(
5089
- DataTable3,
5090
- {
5091
- columns,
5092
- data: filteredCredentials,
5093
- isLoading,
5094
- emptyMessage: "Nenhuma credencial encontrada"
5095
- }
5096
- ),
5097
- /* @__PURE__ */ jsx24(Dialog7, { open: showCreateDialog, onOpenChange: setShowCreateDialog, children: /* @__PURE__ */ jsxs22(DialogContent7, { children: [
5098
- /* @__PURE__ */ jsx24(DialogHeader7, { children: /* @__PURE__ */ jsx24(DialogTitle7, { children: "Nova Credencial" }) }),
5099
- /* @__PURE__ */ jsxs22("div", { className: "space-y-4", children: [
5100
- /* @__PURE__ */ jsxs22("div", { children: [
5101
- /* @__PURE__ */ jsx24("label", { htmlFor: "cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
5102
- /* @__PURE__ */ jsxs22(
5103
- Select4,
5104
- {
5105
- value: createForm.id_tool,
5106
- onValueChange: (val) => setCreateForm((f) => ({ ...f, id_tool: val })),
5107
- children: [
5108
- /* @__PURE__ */ jsx24(SelectTrigger4, { id: "cred-tool", children: /* @__PURE__ */ jsx24(SelectValue4, { placeholder: "Selecione a ferramenta" }) }),
5109
- /* @__PURE__ */ jsx24(SelectContent4, { children: tools.map((tool) => /* @__PURE__ */ jsx24(SelectItem4, { value: String(tool.id), children: tool.name }, tool.id)) })
5110
- ]
5111
- }
5112
- )
5113
- ] }),
5114
- /* @__PURE__ */ jsxs22("div", { children: [
5115
- /* @__PURE__ */ jsx24("label", { htmlFor: "cred-label", className: "mb-1 block text-sm font-medium", children: "Label *" }),
5116
- /* @__PURE__ */ jsx24(
5117
- Input10,
5117
+ ] }),
5118
+ /* @__PURE__ */ jsxs21(DialogFooter7, { className: "flex-row justify-between sm:justify-between", children: [
5119
+ /* @__PURE__ */ jsx23("div", { children: currentStep === "info" ? /* @__PURE__ */ jsx23(
5120
+ Button14,
5121
+ {
5122
+ type: "button",
5123
+ variant: "outline",
5124
+ onClick: () => onOpenChange(false),
5125
+ children: "Cancelar"
5126
+ }
5127
+ ) : /* @__PURE__ */ jsxs21(
5128
+ Button14,
5129
+ {
5130
+ type: "button",
5131
+ variant: "outline",
5132
+ onClick: goPrev,
5133
+ className: "gap-1",
5134
+ children: [
5135
+ /* @__PURE__ */ jsx23(ChevronLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
5136
+ "Voltar"
5137
+ ]
5138
+ }
5139
+ ) }),
5140
+ /* @__PURE__ */ jsx23("div", { children: isLastStep ? /* @__PURE__ */ jsxs21(
5141
+ Button14,
5142
+ {
5143
+ type: "button",
5144
+ onClick: handleComplete,
5145
+ disabled: isSubmitting,
5146
+ className: "gap-1",
5147
+ children: [
5148
+ isSubmitting ? /* @__PURE__ */ jsx23(
5149
+ Loader29,
5150
+ {
5151
+ "aria-hidden": "true",
5152
+ className: "h-4 w-4 animate-spin"
5153
+ }
5154
+ ) : /* @__PURE__ */ jsx23(Check2, { "aria-hidden": "true", className: "h-4 w-4" }),
5155
+ "Concluir"
5156
+ ]
5157
+ }
5158
+ ) : /* @__PURE__ */ jsxs21(
5159
+ Button14,
5160
+ {
5161
+ type: "button",
5162
+ onClick: goNext,
5163
+ disabled: !canAdvance(),
5164
+ className: "gap-1",
5165
+ children: [
5166
+ "Continuar",
5167
+ /* @__PURE__ */ jsx23(ChevronRight, { "aria-hidden": "true", className: "h-4 w-4" })
5168
+ ]
5169
+ }
5170
+ ) })
5171
+ ] })
5172
+ ] }) });
5173
+ }
5174
+ function StepIndicator({
5175
+ steps,
5176
+ currentStep
5177
+ }) {
5178
+ const currentIndex = steps.indexOf(currentStep);
5179
+ return /* @__PURE__ */ jsx23(
5180
+ "div",
5181
+ {
5182
+ className: "flex items-center justify-center gap-1 py-2",
5183
+ role: "list",
5184
+ "aria-label": "Passos do assistente",
5185
+ children: steps.map((step, i) => {
5186
+ const isCompleted = i < currentIndex;
5187
+ const isCurrent = step === currentStep;
5188
+ return /* @__PURE__ */ jsxs21("div", { className: "flex items-center", role: "listitem", children: [
5189
+ /* @__PURE__ */ jsx23(
5190
+ "div",
5118
5191
  {
5119
- id: "cred-label",
5120
- name: "label",
5121
- value: createForm.label,
5122
- onChange: (e) => setCreateForm((f) => ({ ...f, label: e.target.value })),
5123
- placeholder: "Ex: Google Calendar - Cl\xEDnica S\xE3o Paulo"
5192
+ className: `
5193
+ flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium
5194
+ transition-colors duration-200
5195
+ ${isCurrent ? "bg-primary text-primary-foreground" : isCompleted ? "bg-green-600 text-white" : "bg-muted text-muted-foreground"}
5196
+ `,
5197
+ "aria-current": isCurrent ? "step" : void 0,
5198
+ "aria-label": `${STEP_LABELS[step]}${isCompleted ? " (conclu\xEDdo)" : isCurrent ? " (atual)" : ""}`,
5199
+ children: isCompleted ? /* @__PURE__ */ jsx23(Check2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : i + 1
5124
5200
  }
5125
- )
5126
- ] }),
5127
- /* @__PURE__ */ jsxs22("div", { children: [
5128
- /* @__PURE__ */ jsx24("label", { htmlFor: "cred-credential", className: "mb-1 block text-sm font-medium", children: "Credencial *" }),
5129
- /* @__PURE__ */ jsx24(
5130
- Input10,
5201
+ ),
5202
+ /* @__PURE__ */ jsx23(
5203
+ "span",
5131
5204
  {
5132
- id: "cred-credential",
5133
- name: "credential",
5134
- autoComplete: "off",
5135
- type: "password",
5136
- value: createForm.credentials_encrypted,
5137
- onChange: (e) => setCreateForm((f) => ({
5138
- ...f,
5139
- credentials_encrypted: e.target.value
5140
- })),
5141
- placeholder: "Credencial encriptada"
5205
+ className: `
5206
+ ml-1.5 hidden text-xs sm:inline
5207
+ ${isCurrent ? "font-medium text-foreground" : "text-muted-foreground"}
5208
+ `,
5209
+ children: STEP_LABELS[step]
5142
5210
  }
5143
- )
5144
- ] }),
5145
- /* @__PURE__ */ jsxs22("div", { children: [
5146
- /* @__PURE__ */ jsx24("label", { htmlFor: "cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o (opcional)" }),
5147
- /* @__PURE__ */ jsx24(
5148
- Input10,
5211
+ ),
5212
+ i < steps.length - 1 && /* @__PURE__ */ jsx23(
5213
+ "div",
5149
5214
  {
5150
- id: "cred-expires",
5151
- name: "expires",
5152
- type: "date",
5153
- value: createForm.expires_at,
5154
- onChange: (e) => setCreateForm((f) => ({ ...f, expires_at: e.target.value }))
5215
+ className: `
5216
+ mx-2 h-px w-6
5217
+ ${i < currentIndex ? "bg-green-600" : "bg-border"}
5218
+ `
5155
5219
  }
5156
5220
  )
5157
- ] })
5158
- ] }),
5159
- /* @__PURE__ */ jsxs22(DialogFooter7, { children: [
5160
- /* @__PURE__ */ jsx24(
5161
- Button14,
5162
- {
5163
- variant: "outline",
5164
- onClick: () => setShowCreateDialog(false),
5165
- children: "Cancelar"
5166
- }
5167
- ),
5168
- /* @__PURE__ */ jsx24(
5169
- Button14,
5170
- {
5171
- onClick: handleCreate,
5172
- disabled: !createForm.id_tool || !createForm.label.trim() || !createForm.credentials_encrypted.trim() || createMutation.isPending,
5173
- children: "Criar"
5174
- }
5175
- )
5176
- ] })
5177
- ] }) }),
5178
- /* @__PURE__ */ jsx24(
5179
- Dialog7,
5180
- {
5181
- open: !!editTarget,
5182
- onOpenChange: (open) => !open && setEditTarget(null),
5183
- children: /* @__PURE__ */ jsxs22(DialogContent7, { children: [
5184
- /* @__PURE__ */ jsx24(DialogHeader7, { children: /* @__PURE__ */ jsx24(DialogTitle7, { children: "Editar Credencial" }) }),
5185
- /* @__PURE__ */ jsxs22("div", { className: "space-y-4", children: [
5186
- /* @__PURE__ */ jsxs22("div", { children: [
5187
- /* @__PURE__ */ jsx24("label", { htmlFor: "edit-cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
5188
- /* @__PURE__ */ jsxs22(
5189
- Select4,
5190
- {
5191
- value: editForm.id_tool,
5192
- onValueChange: (val) => setEditForm((f) => ({ ...f, id_tool: val })),
5193
- children: [
5194
- /* @__PURE__ */ jsx24(SelectTrigger4, { id: "edit-cred-tool", children: /* @__PURE__ */ jsx24(SelectValue4, { placeholder: "Selecione a ferramenta" }) }),
5195
- /* @__PURE__ */ jsx24(SelectContent4, { children: tools.map((tool) => /* @__PURE__ */ jsx24(SelectItem4, { value: String(tool.id), children: tool.name }, tool.id)) })
5196
- ]
5197
- }
5198
- )
5199
- ] }),
5200
- /* @__PURE__ */ jsxs22("div", { children: [
5201
- /* @__PURE__ */ jsx24("label", { htmlFor: "edit-cred-label", className: "mb-1 block text-sm font-medium", children: "Label" }),
5202
- /* @__PURE__ */ jsx24(
5203
- Input10,
5204
- {
5205
- id: "edit-cred-label",
5206
- name: "label",
5207
- value: editForm.label,
5208
- onChange: (e) => setEditForm((f) => ({ ...f, label: e.target.value })),
5209
- placeholder: "Label da credencial"
5210
- }
5211
- )
5212
- ] }),
5213
- /* @__PURE__ */ jsxs22("div", { children: [
5214
- /* @__PURE__ */ jsx24("label", { htmlFor: "edit-cred-credential", className: "mb-1 block text-sm font-medium", children: "Nova Credencial (vazio = manter atual)" }),
5215
- /* @__PURE__ */ jsx24(
5216
- Input10,
5217
- {
5218
- id: "edit-cred-credential",
5219
- name: "credential",
5220
- autoComplete: "off",
5221
- type: "password",
5222
- value: editForm.credentials_encrypted,
5223
- onChange: (e) => setEditForm((f) => ({
5224
- ...f,
5225
- credentials_encrypted: e.target.value
5226
- })),
5227
- placeholder: "Nova credencial"
5228
- }
5229
- )
5230
- ] }),
5231
- /* @__PURE__ */ jsxs22("div", { children: [
5232
- /* @__PURE__ */ jsx24("label", { htmlFor: "edit-cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o" }),
5233
- /* @__PURE__ */ jsx24(
5234
- Input10,
5235
- {
5236
- id: "edit-cred-expires",
5237
- name: "expires",
5238
- type: "date",
5239
- value: editForm.expires_at,
5240
- onChange: (e) => setEditForm((f) => ({ ...f, expires_at: e.target.value }))
5241
- }
5242
- )
5243
- ] }),
5244
- /* @__PURE__ */ jsxs22("div", { children: [
5245
- /* @__PURE__ */ jsx24("label", { htmlFor: "edit-cred-status", className: "mb-1 block text-sm font-medium", children: "Status" }),
5246
- /* @__PURE__ */ jsxs22(
5247
- Select4,
5248
- {
5249
- value: editForm.status || void 0,
5250
- onValueChange: (val) => setEditForm((f) => ({
5251
- ...f,
5252
- status: val
5253
- })),
5254
- children: [
5255
- /* @__PURE__ */ jsx24(SelectTrigger4, { id: "edit-cred-status", children: /* @__PURE__ */ jsx24(SelectValue4, {}) }),
5256
- /* @__PURE__ */ jsxs22(SelectContent4, { children: [
5257
- /* @__PURE__ */ jsx24(SelectItem4, { value: "active", children: "Ativo" }),
5258
- /* @__PURE__ */ jsx24(SelectItem4, { value: "expired", children: "Expirado" })
5259
- ] })
5260
- ]
5261
- }
5262
- )
5263
- ] })
5264
- ] }),
5265
- /* @__PURE__ */ jsxs22(DialogFooter7, { children: [
5266
- /* @__PURE__ */ jsx24(Button14, { variant: "outline", onClick: () => setEditTarget(null), children: "Cancelar" }),
5267
- /* @__PURE__ */ jsx24(
5268
- Button14,
5269
- {
5270
- onClick: handleSaveEdit,
5271
- disabled: updateMutation.isPending,
5272
- children: "Salvar"
5273
- }
5274
- )
5275
- ] })
5276
- ] })
5277
- }
5278
- ),
5279
- /* @__PURE__ */ jsx24(
5280
- AlertDialog5,
5281
- {
5282
- open: !!removeTarget,
5283
- onOpenChange: (open) => !open && setRemoveTarget(null),
5284
- children: /* @__PURE__ */ jsxs22(AlertDialogContent5, { children: [
5285
- /* @__PURE__ */ jsxs22(AlertDialogHeader5, { children: [
5286
- /* @__PURE__ */ jsx24(AlertDialogTitle5, { children: "Remover credencial?" }),
5287
- /* @__PURE__ */ jsx24(AlertDialogDescription5, { children: "A credencial ser\xE1 removida permanentemente." })
5288
- ] }),
5289
- /* @__PURE__ */ jsxs22(AlertDialogFooter5, { children: [
5290
- /* @__PURE__ */ jsx24(AlertDialogCancel5, { children: "Cancelar" }),
5291
- /* @__PURE__ */ jsx24(
5292
- AlertDialogAction5,
5293
- {
5294
- onClick: handleRemove,
5295
- disabled: deleteMutation.isPending,
5296
- children: "Remover"
5297
- }
5298
- )
5299
- ] })
5300
- ] })
5301
- }
5302
- )
5303
- ] });
5221
+ ] }, step);
5222
+ })
5223
+ }
5224
+ );
5304
5225
  }
5305
5226
 
5306
5227
  // src/pages/agents-page.tsx
5307
- import { useState as useState16 } from "react";
5228
+ import { useState as useState15 } from "react";
5308
5229
  import { Button as Button15 } from "@greatapps/greatauth-ui/ui";
5309
5230
  import { Plus as Plus4 } from "lucide-react";
5310
- import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
5231
+ import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
5311
5232
  function AgentsPage({
5312
5233
  config,
5313
5234
  onNavigateToAgent,
5314
5235
  title = "Agentes AI",
5315
5236
  subtitle = "Gerencie seus agentes de atendimento inteligente"
5316
5237
  }) {
5317
- const [createOpen, setCreateOpen] = useState16(false);
5318
- return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5319
- /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between", children: [
5320
- /* @__PURE__ */ jsxs23("div", { children: [
5321
- /* @__PURE__ */ jsx25("h1", { className: "text-xl font-semibold", children: title }),
5322
- /* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: subtitle })
5238
+ const [createOpen, setCreateOpen] = useState15(false);
5239
+ return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5240
+ /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between", children: [
5241
+ /* @__PURE__ */ jsxs22("div", { children: [
5242
+ /* @__PURE__ */ jsx24("h1", { className: "text-xl font-semibold", children: title }),
5243
+ /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: subtitle })
5323
5244
  ] }),
5324
- /* @__PURE__ */ jsxs23(Button15, { onClick: () => setCreateOpen(true), size: "sm", children: [
5325
- /* @__PURE__ */ jsx25(Plus4, { className: "mr-2 h-4 w-4" }),
5245
+ /* @__PURE__ */ jsxs22(Button15, { onClick: () => setCreateOpen(true), size: "sm", children: [
5246
+ /* @__PURE__ */ jsx24(Plus4, { className: "mr-2 h-4 w-4" }),
5326
5247
  "Novo Agente"
5327
5248
  ] })
5328
5249
  ] }),
5329
- /* @__PURE__ */ jsx25(AgentsTable, { config, onNavigateToAgent }),
5330
- /* @__PURE__ */ jsx25(
5250
+ /* @__PURE__ */ jsx24(AgentsTable, { config, onNavigateToAgent }),
5251
+ /* @__PURE__ */ jsx24(
5331
5252
  AgentFormDialog,
5332
5253
  {
5333
5254
  config,
@@ -5339,11 +5260,11 @@ function AgentsPage({
5339
5260
  }
5340
5261
 
5341
5262
  // src/pages/agent-detail-page.tsx
5342
- import { useState as useState17 } from "react";
5263
+ import { useState as useState16 } from "react";
5343
5264
  import { Badge as Badge10, Button as Button16, Skeleton as Skeleton7 } from "@greatapps/greatauth-ui/ui";
5344
5265
  import { EntityAvatar as EntityAvatar2 } from "@greatapps/greatauth-ui";
5345
5266
  import { ArrowLeft, Pencil as Pencil5 } from "lucide-react";
5346
- import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
5267
+ import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
5347
5268
  function AgentDetailPage({
5348
5269
  config,
5349
5270
  agentId,
@@ -5351,28 +5272,28 @@ function AgentDetailPage({
5351
5272
  renderChatLink
5352
5273
  }) {
5353
5274
  const { data: agent, isLoading } = useAgent(config, agentId);
5354
- const [editOpen, setEditOpen] = useState17(false);
5275
+ const [editOpen, setEditOpen] = useState16(false);
5355
5276
  if (isLoading) {
5356
- return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-4 p-4", children: [
5357
- /* @__PURE__ */ jsx26(Skeleton7, { className: "h-4 w-32" }),
5358
- /* @__PURE__ */ jsx26(Skeleton7, { className: "h-8 w-48" }),
5359
- /* @__PURE__ */ jsx26(Skeleton7, { className: "h-10 w-full" }),
5360
- /* @__PURE__ */ jsx26(Skeleton7, { className: "h-64 w-full" })
5277
+ return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 p-4", children: [
5278
+ /* @__PURE__ */ jsx25(Skeleton7, { className: "h-4 w-32" }),
5279
+ /* @__PURE__ */ jsx25(Skeleton7, { className: "h-8 w-48" }),
5280
+ /* @__PURE__ */ jsx25(Skeleton7, { className: "h-10 w-full" }),
5281
+ /* @__PURE__ */ jsx25(Skeleton7, { className: "h-64 w-full" })
5361
5282
  ] });
5362
5283
  }
5363
5284
  if (!agent) {
5364
- return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [
5365
- /* @__PURE__ */ jsx26("p", { className: "text-muted-foreground", children: "Agente n\xE3o encontrado" }),
5366
- onBack && /* @__PURE__ */ jsxs24(Button16, { variant: "ghost", size: "sm", onClick: onBack, children: [
5367
- /* @__PURE__ */ jsx26(ArrowLeft, { className: "mr-2 h-4 w-4" }),
5285
+ return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [
5286
+ /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: "Agente n\xE3o encontrado" }),
5287
+ onBack && /* @__PURE__ */ jsxs23(Button16, { variant: "ghost", size: "sm", onClick: onBack, children: [
5288
+ /* @__PURE__ */ jsx25(ArrowLeft, { className: "mr-2 h-4 w-4" }),
5368
5289
  "Voltar para agentes"
5369
5290
  ] })
5370
5291
  ] });
5371
5292
  }
5372
- return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-6 p-4 md:p-6", children: [
5373
- /* @__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: [
5374
- /* @__PURE__ */ jsxs24("div", { className: "flex items-start gap-3 flex-1", children: [
5375
- onBack && /* @__PURE__ */ jsx26(
5293
+ return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-6 p-4 md:p-6", children: [
5294
+ /* @__PURE__ */ jsx25("div", { className: "rounded-lg border p-4 md:p-6", children: /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:gap-6", children: [
5295
+ /* @__PURE__ */ jsxs23("div", { className: "flex items-start gap-3 flex-1", children: [
5296
+ onBack && /* @__PURE__ */ jsx25(
5376
5297
  Button16,
5377
5298
  {
5378
5299
  variant: "ghost",
@@ -5380,13 +5301,13 @@ function AgentDetailPage({
5380
5301
  "aria-label": "Voltar",
5381
5302
  className: "shrink-0 mt-1",
5382
5303
  onClick: onBack,
5383
- children: /* @__PURE__ */ jsx26(ArrowLeft, { className: "h-4 w-4" })
5304
+ children: /* @__PURE__ */ jsx25(ArrowLeft, { className: "h-4 w-4" })
5384
5305
  }
5385
5306
  ),
5386
- /* @__PURE__ */ jsx26(EntityAvatar2, { photo: agent.photo, name: agent.title, size: "xl" }),
5387
- /* @__PURE__ */ jsx26("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2 flex-wrap", children: [
5388
- /* @__PURE__ */ jsx26("h1", { className: "text-xl font-semibold", children: agent.title }),
5389
- /* @__PURE__ */ jsx26(
5307
+ /* @__PURE__ */ jsx25(EntityAvatar2, { photo: agent.photo, name: agent.title, size: "xl" }),
5308
+ /* @__PURE__ */ jsx25("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 flex-wrap", children: [
5309
+ /* @__PURE__ */ jsx25("h1", { className: "text-xl font-semibold", children: agent.title }),
5310
+ /* @__PURE__ */ jsx25(
5390
5311
  Badge10,
5391
5312
  {
5392
5313
  variant: agent.active ? "default" : "destructive",
@@ -5396,7 +5317,7 @@ function AgentDetailPage({
5396
5317
  )
5397
5318
  ] }) })
5398
5319
  ] }),
5399
- /* @__PURE__ */ jsxs24(
5320
+ /* @__PURE__ */ jsxs23(
5400
5321
  Button16,
5401
5322
  {
5402
5323
  variant: "outline",
@@ -5404,13 +5325,13 @@ function AgentDetailPage({
5404
5325
  className: "shrink-0 self-start",
5405
5326
  onClick: () => setEditOpen(true),
5406
5327
  children: [
5407
- /* @__PURE__ */ jsx26(Pencil5, { className: "mr-2 h-4 w-4" }),
5328
+ /* @__PURE__ */ jsx25(Pencil5, { className: "mr-2 h-4 w-4" }),
5408
5329
  "Editar"
5409
5330
  ]
5410
5331
  }
5411
5332
  )
5412
5333
  ] }) }),
5413
- /* @__PURE__ */ jsx26(
5334
+ /* @__PURE__ */ jsx25(
5414
5335
  AgentTabs,
5415
5336
  {
5416
5337
  agent,
@@ -5418,7 +5339,7 @@ function AgentDetailPage({
5418
5339
  renderChatLink
5419
5340
  }
5420
5341
  ),
5421
- editOpen && /* @__PURE__ */ jsx26(
5342
+ editOpen && /* @__PURE__ */ jsx25(
5422
5343
  AgentEditForm,
5423
5344
  {
5424
5345
  agent,
@@ -5431,8 +5352,56 @@ function AgentDetailPage({
5431
5352
  ] });
5432
5353
  }
5433
5354
 
5355
+ // src/pages/agent-capabilities-page.tsx
5356
+ import {
5357
+ Tabs as Tabs2,
5358
+ TabsList as TabsList2,
5359
+ TabsTrigger as TabsTrigger2,
5360
+ TabsContent as TabsContent2
5361
+ } from "@greatapps/greatauth-ui/ui";
5362
+ import { Blocks as Blocks2, Plug as Plug4, Settings as Settings4 } from "lucide-react";
5363
+ import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
5364
+ function AgentCapabilitiesPage({
5365
+ config,
5366
+ agentId,
5367
+ gagentsApiUrl
5368
+ }) {
5369
+ return /* @__PURE__ */ jsxs24("div", { className: "space-y-4", children: [
5370
+ /* @__PURE__ */ jsxs24("div", { children: [
5371
+ /* @__PURE__ */ jsx26("h2", { className: "text-lg font-semibold", children: "Capacidades e Integra\xE7\xF5es" }),
5372
+ /* @__PURE__ */ jsx26("p", { className: "text-sm text-muted-foreground", children: "Configure o que este agente pode fazer e quais integra\xE7\xF5es ele utiliza." })
5373
+ ] }),
5374
+ /* @__PURE__ */ jsxs24(Tabs2, { defaultValue: "capacidades", children: [
5375
+ /* @__PURE__ */ jsxs24(TabsList2, { children: [
5376
+ /* @__PURE__ */ jsxs24(TabsTrigger2, { value: "capacidades", className: "flex items-center gap-1.5", children: [
5377
+ /* @__PURE__ */ jsx26(Blocks2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
5378
+ "Capacidades"
5379
+ ] }),
5380
+ /* @__PURE__ */ jsxs24(TabsTrigger2, { value: "integracoes", className: "flex items-center gap-1.5", children: [
5381
+ /* @__PURE__ */ jsx26(Plug4, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
5382
+ "Integra\xE7\xF5es"
5383
+ ] }),
5384
+ /* @__PURE__ */ jsxs24(TabsTrigger2, { value: "avancado", className: "flex items-center gap-1.5", children: [
5385
+ /* @__PURE__ */ jsx26(Settings4, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
5386
+ "Avan\xE7ado"
5387
+ ] })
5388
+ ] }),
5389
+ /* @__PURE__ */ jsx26(TabsContent2, { value: "capacidades", className: "mt-4", children: /* @__PURE__ */ jsx26(CapabilitiesTab, { config, agentId }) }),
5390
+ /* @__PURE__ */ jsx26(TabsContent2, { value: "integracoes", className: "mt-4", children: /* @__PURE__ */ jsx26(IntegrationsTab, { config, agentId }) }),
5391
+ /* @__PURE__ */ jsx26(TabsContent2, { value: "avancado", className: "mt-4", children: /* @__PURE__ */ jsx26(
5392
+ AdvancedTab,
5393
+ {
5394
+ config,
5395
+ agentId,
5396
+ gagentsApiUrl
5397
+ }
5398
+ ) })
5399
+ ] })
5400
+ ] });
5401
+ }
5402
+
5434
5403
  // src/pages/tools-page.tsx
5435
- import { useState as useState18 } from "react";
5404
+ import { useState as useState17 } from "react";
5436
5405
  import { Button as Button17 } from "@greatapps/greatauth-ui/ui";
5437
5406
  import { Plus as Plus5 } from "lucide-react";
5438
5407
  import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
@@ -5441,8 +5410,8 @@ function ToolsPage({
5441
5410
  title = "Ferramentas",
5442
5411
  subtitle = "Gerencie as ferramentas dispon\xEDveis para seus agentes"
5443
5412
  }) {
5444
- const [createOpen, setCreateOpen] = useState18(false);
5445
- const [editTool, setEditTool] = useState18(void 0);
5413
+ const [createOpen, setCreateOpen] = useState17(false);
5414
+ const [editTool, setEditTool] = useState17(void 0);
5446
5415
  return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5447
5416
  /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between", children: [
5448
5417
  /* @__PURE__ */ jsxs25("div", { children: [
@@ -5476,7 +5445,7 @@ function ToolsPage({
5476
5445
  }
5477
5446
 
5478
5447
  // src/pages/credentials-page.tsx
5479
- import { useState as useState19 } from "react";
5448
+ import { useState as useState18 } from "react";
5480
5449
  import { Button as Button18 } from "@greatapps/greatauth-ui/ui";
5481
5450
  import { Plus as Plus6 } from "lucide-react";
5482
5451
  import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
@@ -5487,7 +5456,7 @@ function CredentialsPage({
5487
5456
  subtitle = "Gerencie as credenciais de autentica\xE7\xE3o das ferramentas"
5488
5457
  }) {
5489
5458
  const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
5490
- const [createOpen, setCreateOpen] = useState19(false);
5459
+ const [createOpen, setCreateOpen] = useState18(false);
5491
5460
  const credentials = credentialsData?.data || [];
5492
5461
  return /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5493
5462
  /* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between", children: [
@@ -5515,7 +5484,7 @@ function CredentialsPage({
5515
5484
  }
5516
5485
 
5517
5486
  // src/pages/integrations-management-page.tsx
5518
- import { useState as useState20, useMemo as useMemo8 } from "react";
5487
+ import { useState as useState19, useMemo as useMemo8, useCallback as useCallback7 } from "react";
5519
5488
  import {
5520
5489
  Badge as Badge11,
5521
5490
  Button as Button19,
@@ -5524,7 +5493,7 @@ import {
5524
5493
  TabsList as TabsList3,
5525
5494
  TabsTrigger as TabsTrigger3
5526
5495
  } from "@greatapps/greatauth-ui/ui";
5527
- import { Plus as Plus7, Plug as Plug4, KeyRound, Info as Info3 } from "lucide-react";
5496
+ import { Plus as Plus7, Plug as Plug5, KeyRound, Info as Info3, Loader2 as Loader210 } from "lucide-react";
5528
5497
  import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
5529
5498
  function useCredentialAgentSummary(credentials, tools, agents) {
5530
5499
  return useMemo8(() => {
@@ -5545,18 +5514,49 @@ function useCredentialAgentSummary(credentials, tools, agents) {
5545
5514
  function IntegrationsManagementPage({
5546
5515
  config,
5547
5516
  gagentsApiUrl,
5548
- onConnect,
5517
+ resolveWizardMeta,
5518
+ loadConfigOptions,
5519
+ onWizardComplete,
5549
5520
  title = "Integra\xE7\xF5es e Credenciais",
5550
5521
  subtitle = "Gerencie todas as integra\xE7\xF5es e credenciais da conta."
5551
5522
  }) {
5552
5523
  const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
5553
5524
  const { data: agentsData } = useAgents(config);
5554
5525
  const { data: toolsData } = useTools(config);
5555
- const [createOpen, setCreateOpen] = useState20(false);
5526
+ const [createOpen, setCreateOpen] = useState19(false);
5527
+ const { cards, isLoading: cardsLoading } = useIntegrationState(config, null);
5528
+ const [wizardOpen, setWizardOpen] = useState19(false);
5529
+ const [activeCard, setActiveCard] = useState19(null);
5556
5530
  const credentials = credentialsData?.data || [];
5557
5531
  const agents = agentsData?.data || [];
5558
5532
  const tools = toolsData?.data || [];
5559
5533
  const summary = useCredentialAgentSummary(credentials, tools, agents);
5534
+ const handleConnect = useCallback7((card) => {
5535
+ setActiveCard(card);
5536
+ setWizardOpen(true);
5537
+ }, []);
5538
+ const handleWizardClose = useCallback7((open) => {
5539
+ if (!open) {
5540
+ setActiveCard(null);
5541
+ }
5542
+ setWizardOpen(open);
5543
+ }, []);
5544
+ const handleWizardComplete = useCallback7(() => {
5545
+ setWizardOpen(false);
5546
+ setActiveCard(null);
5547
+ onWizardComplete?.();
5548
+ }, [onWizardComplete]);
5549
+ const wizardMeta = activeCard ? resolveWizardMeta?.(activeCard) ?? {
5550
+ capabilities: [],
5551
+ requirements: [],
5552
+ hasConfigStep: false
5553
+ } : null;
5554
+ const connectedCards = cards.filter(
5555
+ (c) => !c.isAddNew && (c.state === "connected" || c.state === "expired")
5556
+ );
5557
+ const otherCards = cards.filter(
5558
+ (c) => c.isAddNew || c.state === "coming_soon"
5559
+ );
5560
5560
  return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5561
5561
  /* @__PURE__ */ jsx29("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs27("div", { children: [
5562
5562
  /* @__PURE__ */ jsx29("h1", { className: "text-xl font-semibold", children: title }),
@@ -5565,7 +5565,7 @@ function IntegrationsManagementPage({
5565
5565
  /* @__PURE__ */ jsxs27(Tabs3, { defaultValue: "integrations", className: "w-full", children: [
5566
5566
  /* @__PURE__ */ jsxs27(TabsList3, { children: [
5567
5567
  /* @__PURE__ */ jsxs27(TabsTrigger3, { value: "integrations", className: "gap-2", children: [
5568
- /* @__PURE__ */ jsx29(Plug4, { className: "h-4 w-4" }),
5568
+ /* @__PURE__ */ jsx29(Plug5, { className: "h-4 w-4" }),
5569
5569
  "Integra\xE7\xF5es"
5570
5570
  ] }),
5571
5571
  /* @__PURE__ */ jsxs27(TabsTrigger3, { value: "credentials", className: "gap-2", children: [
@@ -5573,15 +5573,36 @@ function IntegrationsManagementPage({
5573
5573
  "Credenciais"
5574
5574
  ] })
5575
5575
  ] }),
5576
- /* @__PURE__ */ jsx29(TabsContent3, { value: "integrations", className: "mt-4", children: /* @__PURE__ */ jsx29(
5577
- IntegrationsTab,
5578
- {
5579
- config,
5580
- agentId: null,
5581
- onConnect: onConnect ?? (() => {
5582
- })
5583
- }
5584
- ) }),
5576
+ /* @__PURE__ */ jsx29(TabsContent3, { value: "integrations", className: "mt-4", children: cardsLoading ? /* @__PURE__ */ jsx29("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx29(Loader210, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : cards.length === 0 ? /* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground", children: [
5577
+ /* @__PURE__ */ jsx29(Plug5, { className: "h-10 w-10" }),
5578
+ /* @__PURE__ */ jsx29("p", { className: "text-sm", children: "Nenhuma integra\xE7\xE3o dispon\xEDvel" })
5579
+ ] }) : /* @__PURE__ */ jsxs27("div", { className: "space-y-6", children: [
5580
+ connectedCards.length > 0 && /* @__PURE__ */ jsxs27("div", { children: [
5581
+ /* @__PURE__ */ jsx29("h3", { className: "mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: "Contas conectadas" }),
5582
+ /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: connectedCards.map((card) => /* @__PURE__ */ jsx29(
5583
+ IntegrationCard,
5584
+ {
5585
+ card,
5586
+ onConnect: handleConnect
5587
+ },
5588
+ `${card.definition.slug}-cred-${card.credentialId}`
5589
+ )) })
5590
+ ] }),
5591
+ otherCards.length > 0 && /* @__PURE__ */ jsxs27("div", { children: [
5592
+ connectedCards.length > 0 && /* @__PURE__ */ jsx29("h3", { className: "mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: "Adicionar integra\xE7\xE3o" }),
5593
+ /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: otherCards.map((card) => {
5594
+ const key = card.isAddNew ? `${card.definition.slug}-add-new` : card.definition.slug;
5595
+ return /* @__PURE__ */ jsx29(
5596
+ IntegrationCard,
5597
+ {
5598
+ card,
5599
+ onConnect: handleConnect
5600
+ },
5601
+ key
5602
+ );
5603
+ }) })
5604
+ ] })
5605
+ ] }) }),
5585
5606
  /* @__PURE__ */ jsxs27(TabsContent3, { value: "credentials", className: "mt-4", children: [
5586
5607
  !credentialsLoading && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-4 rounded-lg border bg-muted/50 px-4 py-3 mb-4", children: [
5587
5608
  /* @__PURE__ */ jsx29(Info3, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
@@ -5618,7 +5639,22 @@ function IntegrationsManagementPage({
5618
5639
  }
5619
5640
  )
5620
5641
  ] })
5621
- ] })
5642
+ ] }),
5643
+ activeCard && wizardMeta && /* @__PURE__ */ jsx29(
5644
+ IntegrationWizard,
5645
+ {
5646
+ open: wizardOpen,
5647
+ onOpenChange: handleWizardClose,
5648
+ integration: activeCard.definition,
5649
+ meta: wizardMeta,
5650
+ agentId: 0,
5651
+ config,
5652
+ gagentsApiUrl,
5653
+ existingCredentialId: activeCard.credentialId,
5654
+ onComplete: handleWizardComplete,
5655
+ loadConfigOptions
5656
+ }
5657
+ )
5622
5658
  ] });
5623
5659
  }
5624
5660
  export {