@greatapps/greatagents-ui 0.3.3 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +204 -1
- package/dist/index.js +1675 -76
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +14 -0
- package/src/components/capabilities/advanced-tab.tsx +82 -0
- package/src/components/capabilities/capabilities-tab.tsx +475 -0
- package/src/components/capabilities/integration-card.tsx +162 -0
- package/src/components/capabilities/integration-wizard.tsx +537 -0
- package/src/components/capabilities/integrations-tab.tsx +61 -0
- package/src/components/capabilities/types.ts +48 -0
- package/src/components/capabilities/wizard-steps/config-step.tsx +117 -0
- package/src/components/capabilities/wizard-steps/confirm-step.tsx +123 -0
- package/src/components/capabilities/wizard-steps/credentials-step.tsx +205 -0
- package/src/components/capabilities/wizard-steps/info-step.tsx +78 -0
- package/src/data/integrations-registry.ts +23 -0
- package/src/hooks/index.ts +10 -0
- package/src/hooks/use-capabilities.ts +50 -0
- package/src/hooks/use-integrations.ts +114 -0
- package/src/index.ts +34 -0
- package/src/pages/agent-capabilities-page.tsx +159 -0
- package/src/pages/index.ts +2 -0
- package/src/pages/integrations-management-page.tsx +166 -0
- package/src/types/capabilities.ts +32 -0
- package/src/types/index.ts +10 -0
package/dist/index.js
CHANGED
|
@@ -88,7 +88,11 @@ function createGagentsClient(config) {
|
|
|
88
88
|
`calendar/disconnect/${encodeURIComponent(externalReference)}`,
|
|
89
89
|
void 0,
|
|
90
90
|
{ provider }
|
|
91
|
-
)
|
|
91
|
+
),
|
|
92
|
+
// --- Capabilities ---
|
|
93
|
+
getCapabilities: (idAccount) => request("GET", idAccount, "capabilities"),
|
|
94
|
+
getAgentCapabilities: (idAccount, idAgent) => request("GET", idAccount, `agents/${idAgent}/capabilities`),
|
|
95
|
+
updateAgentCapabilities: (idAccount, idAgent, body) => request("PUT", idAccount, `agents/${idAgent}/capabilities`, body)
|
|
92
96
|
};
|
|
93
97
|
}
|
|
94
98
|
|
|
@@ -444,8 +448,110 @@ function useGagentsContacts(config, params) {
|
|
|
444
448
|
});
|
|
445
449
|
}
|
|
446
450
|
|
|
451
|
+
// src/hooks/use-capabilities.ts
|
|
452
|
+
import { useQuery as useQuery8, useMutation as useMutation6, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
|
|
453
|
+
function useCapabilities(config) {
|
|
454
|
+
const client = useGagentsClient(config);
|
|
455
|
+
return useQuery8({
|
|
456
|
+
queryKey: ["greatagents", "capabilities", config.accountId],
|
|
457
|
+
queryFn: async () => {
|
|
458
|
+
const res = await client.getCapabilities(config.accountId);
|
|
459
|
+
return res.data ?? { product: null, categories: [] };
|
|
460
|
+
},
|
|
461
|
+
enabled: !!config.token && !!config.accountId
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
function useAgentCapabilities(config, agentId) {
|
|
465
|
+
const client = useGagentsClient(config);
|
|
466
|
+
return useQuery8({
|
|
467
|
+
queryKey: ["greatagents", "agent-capabilities", config.accountId, agentId],
|
|
468
|
+
queryFn: async () => {
|
|
469
|
+
const res = await client.getAgentCapabilities(config.accountId, agentId);
|
|
470
|
+
const d = res.data;
|
|
471
|
+
return Array.isArray(d) ? d : [];
|
|
472
|
+
},
|
|
473
|
+
enabled: !!config.token && !!config.accountId && !!agentId
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function useUpdateAgentCapabilities(config) {
|
|
477
|
+
const client = useGagentsClient(config);
|
|
478
|
+
const queryClient = useQueryClient6();
|
|
479
|
+
return useMutation6({
|
|
480
|
+
mutationFn: ({ agentId, payload }) => client.updateAgentCapabilities(config.accountId, agentId, payload),
|
|
481
|
+
onSuccess: (_data, variables) => {
|
|
482
|
+
queryClient.invalidateQueries({
|
|
483
|
+
queryKey: ["greatagents", "agent-capabilities", config.accountId, variables.agentId]
|
|
484
|
+
});
|
|
485
|
+
queryClient.invalidateQueries({
|
|
486
|
+
queryKey: ["greatagents", "agent-tools"]
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// src/hooks/use-integrations.ts
|
|
493
|
+
import { useMemo as useMemo2 } from "react";
|
|
494
|
+
|
|
495
|
+
// src/data/integrations-registry.ts
|
|
496
|
+
var INTEGRATIONS_REGISTRY = [
|
|
497
|
+
{
|
|
498
|
+
slug: "google_calendar",
|
|
499
|
+
name: "Google Agenda",
|
|
500
|
+
description: "Sincronize agendamentos com o Google Calendar",
|
|
501
|
+
icon: "CalendarSync",
|
|
502
|
+
authType: "oauth2",
|
|
503
|
+
status: "available"
|
|
504
|
+
}
|
|
505
|
+
// Future integrations — add entries here without code changes
|
|
506
|
+
];
|
|
507
|
+
|
|
508
|
+
// src/hooks/use-integrations.ts
|
|
509
|
+
function useIntegrationState(config, agentId) {
|
|
510
|
+
const { data: credentialsData, isLoading: loadingCredentials } = useToolCredentials(config);
|
|
511
|
+
const { data: toolsData, isLoading: loadingTools } = useTools(config);
|
|
512
|
+
const { data: agentToolsData, isLoading: loadingAgentTools } = useAgentTools(
|
|
513
|
+
config,
|
|
514
|
+
agentId ?? 0
|
|
515
|
+
);
|
|
516
|
+
const isLoading = loadingCredentials || loadingTools || loadingAgentTools;
|
|
517
|
+
const cards = useMemo2(() => {
|
|
518
|
+
const credentials = credentialsData?.data ?? [];
|
|
519
|
+
const tools = toolsData?.data ?? [];
|
|
520
|
+
const agentTools = agentToolsData?.data ?? [];
|
|
521
|
+
return INTEGRATIONS_REGISTRY.map((def) => {
|
|
522
|
+
if (def.status === "coming_soon") {
|
|
523
|
+
return {
|
|
524
|
+
definition: def,
|
|
525
|
+
state: "coming_soon",
|
|
526
|
+
credential: null,
|
|
527
|
+
tool: null,
|
|
528
|
+
sharedByAgentsCount: 0,
|
|
529
|
+
linkedToAgent: false
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
const matchedTool = tools.find((t) => t.slug === def.slug) ?? null;
|
|
533
|
+
const matchedCredential = matchedTool ? credentials.find((c) => c.id_tool === matchedTool.id) ?? null : null;
|
|
534
|
+
const linkedToAgent = matchedTool ? agentTools.some((at) => at.id_tool === matchedTool.id) : false;
|
|
535
|
+
const sharedByAgentsCount = matchedCredential ? 1 : 0;
|
|
536
|
+
let state = "available";
|
|
537
|
+
if (matchedCredential) {
|
|
538
|
+
state = matchedCredential.status === "expired" ? "expired" : "connected";
|
|
539
|
+
}
|
|
540
|
+
return {
|
|
541
|
+
definition: def,
|
|
542
|
+
state,
|
|
543
|
+
credential: matchedCredential,
|
|
544
|
+
tool: matchedTool,
|
|
545
|
+
sharedByAgentsCount,
|
|
546
|
+
linkedToAgent
|
|
547
|
+
};
|
|
548
|
+
});
|
|
549
|
+
}, [credentialsData, toolsData, agentToolsData]);
|
|
550
|
+
return { cards, isLoading };
|
|
551
|
+
}
|
|
552
|
+
|
|
447
553
|
// src/components/agents/agents-table.tsx
|
|
448
|
-
import { useMemo as
|
|
554
|
+
import { useMemo as useMemo3, useState } from "react";
|
|
449
555
|
import { DataTable } from "@greatapps/greatauth-ui";
|
|
450
556
|
import {
|
|
451
557
|
Input,
|
|
@@ -532,7 +638,7 @@ function useColumns(onEdit, onDelete) {
|
|
|
532
638
|
function AgentsTable({ config, onNavigateToAgent }) {
|
|
533
639
|
const [search, setSearch] = useState("");
|
|
534
640
|
const [page, setPage] = useState(1);
|
|
535
|
-
const queryParams =
|
|
641
|
+
const queryParams = useMemo3(() => {
|
|
536
642
|
const params = {
|
|
537
643
|
limit: "15",
|
|
538
644
|
page: String(page)
|
|
@@ -2684,7 +2790,7 @@ function AgentTabs({ agent, config, renderChatLink }) {
|
|
|
2684
2790
|
}
|
|
2685
2791
|
|
|
2686
2792
|
// src/components/tools/tools-table.tsx
|
|
2687
|
-
import { useMemo as
|
|
2793
|
+
import { useMemo as useMemo5, useState as useState9 } from "react";
|
|
2688
2794
|
import { DataTable as DataTable2 } from "@greatapps/greatauth-ui";
|
|
2689
2795
|
import {
|
|
2690
2796
|
Input as Input7,
|
|
@@ -2781,7 +2887,7 @@ function useColumns2(onEdit, onDelete) {
|
|
|
2781
2887
|
function ToolsTable({ onEdit, config }) {
|
|
2782
2888
|
const [search, setSearch] = useState9("");
|
|
2783
2889
|
const [page, setPage] = useState9(1);
|
|
2784
|
-
const queryParams =
|
|
2890
|
+
const queryParams = useMemo5(() => {
|
|
2785
2891
|
const params = {
|
|
2786
2892
|
limit: "15",
|
|
2787
2893
|
page: String(page)
|
|
@@ -3147,7 +3253,7 @@ function ToolFormDialog({
|
|
|
3147
3253
|
}
|
|
3148
3254
|
|
|
3149
3255
|
// src/components/tools/tool-credentials-form.tsx
|
|
3150
|
-
import { useMemo as
|
|
3256
|
+
import { useMemo as useMemo6, useState as useState11 } from "react";
|
|
3151
3257
|
import { DataTable as DataTable3 } from "@greatapps/greatauth-ui";
|
|
3152
3258
|
import {
|
|
3153
3259
|
Input as Input9,
|
|
@@ -3311,7 +3417,7 @@ function ToolCredentialsForm({
|
|
|
3311
3417
|
status: ""
|
|
3312
3418
|
});
|
|
3313
3419
|
const [removeTarget, setRemoveTarget] = useState11(null);
|
|
3314
|
-
const filteredCredentials =
|
|
3420
|
+
const filteredCredentials = useMemo6(() => {
|
|
3315
3421
|
if (!search) return credentials;
|
|
3316
3422
|
const term = search.toLowerCase();
|
|
3317
3423
|
return credentials.filter((cred) => {
|
|
@@ -3650,31 +3756,1302 @@ function ToolCredentialsForm({
|
|
|
3650
3756
|
] });
|
|
3651
3757
|
}
|
|
3652
3758
|
|
|
3759
|
+
// src/components/capabilities/integration-card.tsx
|
|
3760
|
+
import { Badge as Badge8, Button as Button11, Tooltip as Tooltip4, TooltipContent as TooltipContent4, TooltipTrigger as TooltipTrigger4 } from "@greatapps/greatauth-ui/ui";
|
|
3761
|
+
import {
|
|
3762
|
+
CalendarSync,
|
|
3763
|
+
Plug,
|
|
3764
|
+
Settings,
|
|
3765
|
+
RefreshCw,
|
|
3766
|
+
Users,
|
|
3767
|
+
Clock
|
|
3768
|
+
} from "lucide-react";
|
|
3769
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3770
|
+
var ICON_MAP = {
|
|
3771
|
+
CalendarSync,
|
|
3772
|
+
Plug,
|
|
3773
|
+
Settings,
|
|
3774
|
+
RefreshCw,
|
|
3775
|
+
Users,
|
|
3776
|
+
Clock
|
|
3777
|
+
};
|
|
3778
|
+
function resolveIcon(name) {
|
|
3779
|
+
return ICON_MAP[name] ?? Plug;
|
|
3780
|
+
}
|
|
3781
|
+
var STATE_BADGES = {
|
|
3782
|
+
available: {
|
|
3783
|
+
label: "Dispon\xEDvel",
|
|
3784
|
+
className: "bg-muted text-muted-foreground"
|
|
3785
|
+
},
|
|
3786
|
+
connected: {
|
|
3787
|
+
label: "Conectado",
|
|
3788
|
+
className: "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
|
|
3789
|
+
},
|
|
3790
|
+
expired: {
|
|
3791
|
+
label: "Expirado",
|
|
3792
|
+
className: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
|
|
3793
|
+
},
|
|
3794
|
+
coming_soon: {
|
|
3795
|
+
label: "Em breve",
|
|
3796
|
+
className: "bg-muted text-muted-foreground"
|
|
3797
|
+
}
|
|
3798
|
+
};
|
|
3799
|
+
function getActionLabel(state) {
|
|
3800
|
+
switch (state) {
|
|
3801
|
+
case "available":
|
|
3802
|
+
return "Conectar";
|
|
3803
|
+
case "connected":
|
|
3804
|
+
return "Configurar";
|
|
3805
|
+
case "expired":
|
|
3806
|
+
return "Reconectar";
|
|
3807
|
+
default:
|
|
3808
|
+
return "";
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
function IntegrationCard({ card, onConnect }) {
|
|
3812
|
+
const { definition, state, sharedByAgentsCount } = card;
|
|
3813
|
+
const Icon = resolveIcon(definition.icon);
|
|
3814
|
+
const badge = STATE_BADGES[state];
|
|
3815
|
+
const actionLabel = getActionLabel(state);
|
|
3816
|
+
const isComingSoon = state === "coming_soon";
|
|
3817
|
+
return /* @__PURE__ */ jsxs13(
|
|
3818
|
+
"div",
|
|
3819
|
+
{
|
|
3820
|
+
className: cn(
|
|
3821
|
+
"group relative flex flex-col gap-3 rounded-xl border bg-card p-5 transition-shadow",
|
|
3822
|
+
isComingSoon ? "opacity-60 cursor-default" : "hover:shadow-md cursor-pointer"
|
|
3823
|
+
),
|
|
3824
|
+
role: "button",
|
|
3825
|
+
tabIndex: isComingSoon ? -1 : 0,
|
|
3826
|
+
"aria-label": `${definition.name} \u2014 ${badge.label}`,
|
|
3827
|
+
"aria-disabled": isComingSoon,
|
|
3828
|
+
onClick: () => !isComingSoon && onConnect(card),
|
|
3829
|
+
onKeyDown: (e) => {
|
|
3830
|
+
if (!isComingSoon && (e.key === "Enter" || e.key === " ")) {
|
|
3831
|
+
e.preventDefault();
|
|
3832
|
+
onConnect(card);
|
|
3833
|
+
}
|
|
3834
|
+
},
|
|
3835
|
+
children: [
|
|
3836
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-start justify-between gap-2", children: [
|
|
3837
|
+
/* @__PURE__ */ jsx15("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx15(Icon, { className: "h-5 w-5" }) }),
|
|
3838
|
+
/* @__PURE__ */ jsx15(Badge8, { variant: "outline", className: cn("text-xs", badge.className), children: badge.label })
|
|
3839
|
+
] }),
|
|
3840
|
+
/* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
|
|
3841
|
+
/* @__PURE__ */ jsx15("h3", { className: "text-sm font-semibold leading-tight", children: definition.name }),
|
|
3842
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground leading-relaxed", children: definition.description })
|
|
3843
|
+
] }),
|
|
3844
|
+
/* @__PURE__ */ jsxs13("div", { className: "mt-auto flex items-center justify-between gap-2 pt-1", children: [
|
|
3845
|
+
sharedByAgentsCount > 0 ? /* @__PURE__ */ jsxs13(Tooltip4, { children: [
|
|
3846
|
+
/* @__PURE__ */ jsx15(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsxs13("span", { className: "inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400", children: [
|
|
3847
|
+
/* @__PURE__ */ jsx15(Users, { className: "h-3.5 w-3.5" }),
|
|
3848
|
+
"Compartilhada"
|
|
3849
|
+
] }) }),
|
|
3850
|
+
/* @__PURE__ */ jsx15(TooltipContent4, { children: "Esta credencial est\xE1 dispon\xEDvel para todos os agentes da conta" })
|
|
3851
|
+
] }) : /* @__PURE__ */ jsx15("span", {}),
|
|
3852
|
+
!isComingSoon && /* @__PURE__ */ jsx15(
|
|
3853
|
+
Button11,
|
|
3854
|
+
{
|
|
3855
|
+
variant: state === "expired" ? "destructive" : "outline",
|
|
3856
|
+
size: "sm",
|
|
3857
|
+
className: "text-xs",
|
|
3858
|
+
onClick: (e) => {
|
|
3859
|
+
e.stopPropagation();
|
|
3860
|
+
onConnect(card);
|
|
3861
|
+
},
|
|
3862
|
+
children: actionLabel
|
|
3863
|
+
}
|
|
3864
|
+
)
|
|
3865
|
+
] })
|
|
3866
|
+
]
|
|
3867
|
+
}
|
|
3868
|
+
);
|
|
3869
|
+
}
|
|
3870
|
+
|
|
3871
|
+
// src/components/capabilities/integrations-tab.tsx
|
|
3872
|
+
import { Plug as Plug2, Loader2 as Loader25 } from "lucide-react";
|
|
3873
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3874
|
+
function IntegrationsTab({
|
|
3875
|
+
config,
|
|
3876
|
+
agentId,
|
|
3877
|
+
onConnect
|
|
3878
|
+
}) {
|
|
3879
|
+
const { cards, isLoading } = useIntegrationState(config, agentId);
|
|
3880
|
+
if (isLoading) {
|
|
3881
|
+
return /* @__PURE__ */ jsx16("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx16(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
3882
|
+
}
|
|
3883
|
+
if (cards.length === 0) {
|
|
3884
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground", children: [
|
|
3885
|
+
/* @__PURE__ */ jsx16(Plug2, { className: "h-10 w-10" }),
|
|
3886
|
+
/* @__PURE__ */ jsx16("p", { className: "text-sm", children: "Nenhuma integra\xE7\xE3o dispon\xEDvel" })
|
|
3887
|
+
] });
|
|
3888
|
+
}
|
|
3889
|
+
return /* @__PURE__ */ jsx16("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: cards.map((card) => /* @__PURE__ */ jsx16(
|
|
3890
|
+
IntegrationCard,
|
|
3891
|
+
{
|
|
3892
|
+
card,
|
|
3893
|
+
onConnect
|
|
3894
|
+
},
|
|
3895
|
+
card.definition.slug
|
|
3896
|
+
)) });
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
// src/components/capabilities/capabilities-tab.tsx
|
|
3900
|
+
import { useState as useState12, useCallback as useCallback4, useRef as useRef2, useEffect as useEffect4, useMemo as useMemo7 } from "react";
|
|
3901
|
+
import {
|
|
3902
|
+
Accordion,
|
|
3903
|
+
AccordionItem,
|
|
3904
|
+
AccordionTrigger,
|
|
3905
|
+
AccordionContent,
|
|
3906
|
+
Switch as Switch4,
|
|
3907
|
+
Checkbox,
|
|
3908
|
+
Badge as Badge9,
|
|
3909
|
+
Button as Button12,
|
|
3910
|
+
Skeleton as Skeleton6
|
|
3911
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
3912
|
+
import {
|
|
3913
|
+
Calendar,
|
|
3914
|
+
Users as Users2,
|
|
3915
|
+
Settings as Settings3,
|
|
3916
|
+
HeartHandshake,
|
|
3917
|
+
Package,
|
|
3918
|
+
ChevronDown as ChevronDown2
|
|
3919
|
+
} from "lucide-react";
|
|
3920
|
+
import { toast as toast10 } from "sonner";
|
|
3921
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3922
|
+
var OPERATION_LABELS = {
|
|
3923
|
+
list: "Listar",
|
|
3924
|
+
view: "Visualizar",
|
|
3925
|
+
create: "Criar",
|
|
3926
|
+
update: "Atualizar"
|
|
3927
|
+
};
|
|
3928
|
+
function getOperationLabel(slug) {
|
|
3929
|
+
return OPERATION_LABELS[slug] ?? slug;
|
|
3930
|
+
}
|
|
3931
|
+
var CATEGORY_ICONS = {
|
|
3932
|
+
agenda: Calendar,
|
|
3933
|
+
cadastros: Users2,
|
|
3934
|
+
infraestrutura: Settings3,
|
|
3935
|
+
relacionamentos: HeartHandshake
|
|
3936
|
+
};
|
|
3937
|
+
function getCategoryIcon(slug) {
|
|
3938
|
+
return CATEGORY_ICONS[slug] ?? Package;
|
|
3939
|
+
}
|
|
3940
|
+
function buildStateFromAgent(agentCaps) {
|
|
3941
|
+
const state = /* @__PURE__ */ new Map();
|
|
3942
|
+
for (const cap of agentCaps) {
|
|
3943
|
+
state.set(cap.module, new Set(cap.operations));
|
|
3944
|
+
}
|
|
3945
|
+
return state;
|
|
3946
|
+
}
|
|
3947
|
+
function stateToPayload(state) {
|
|
3948
|
+
const capabilities = [];
|
|
3949
|
+
state.forEach((ops, mod) => {
|
|
3950
|
+
if (ops.size > 0) {
|
|
3951
|
+
capabilities.push({ module: mod, operations: Array.from(ops) });
|
|
3952
|
+
}
|
|
3953
|
+
});
|
|
3954
|
+
return { capabilities };
|
|
3955
|
+
}
|
|
3956
|
+
function cloneState(state) {
|
|
3957
|
+
const next = /* @__PURE__ */ new Map();
|
|
3958
|
+
state.forEach((ops, mod) => next.set(mod, new Set(ops)));
|
|
3959
|
+
return next;
|
|
3960
|
+
}
|
|
3961
|
+
function statesEqual(a, b) {
|
|
3962
|
+
if (a.size !== b.size) return false;
|
|
3963
|
+
for (const [mod, opsA] of a) {
|
|
3964
|
+
const opsB = b.get(mod);
|
|
3965
|
+
if (!opsB || opsA.size !== opsB.size) return false;
|
|
3966
|
+
for (const op of opsA) {
|
|
3967
|
+
if (!opsB.has(op)) return false;
|
|
3968
|
+
}
|
|
3969
|
+
}
|
|
3970
|
+
return true;
|
|
3971
|
+
}
|
|
3972
|
+
function CapabilitiesTab({ config, agentId }) {
|
|
3973
|
+
const { data: registry, isLoading: isLoadingRegistry } = useCapabilities(config);
|
|
3974
|
+
const { data: agentCaps, isLoading: isLoadingAgent } = useAgentCapabilities(config, agentId);
|
|
3975
|
+
const updateMutation = useUpdateAgentCapabilities(config);
|
|
3976
|
+
const [localState, setLocalState] = useState12(/* @__PURE__ */ new Map());
|
|
3977
|
+
const [serverState, setServerState] = useState12(/* @__PURE__ */ new Map());
|
|
3978
|
+
const [initialized, setInitialized] = useState12(false);
|
|
3979
|
+
const debounceRef = useRef2(null);
|
|
3980
|
+
useEffect4(() => {
|
|
3981
|
+
if (agentCaps && !initialized) {
|
|
3982
|
+
const state = buildStateFromAgent(agentCaps);
|
|
3983
|
+
setLocalState(state);
|
|
3984
|
+
setServerState(cloneState(state));
|
|
3985
|
+
setInitialized(true);
|
|
3986
|
+
}
|
|
3987
|
+
}, [agentCaps, initialized]);
|
|
3988
|
+
useEffect4(() => {
|
|
3989
|
+
setInitialized(false);
|
|
3990
|
+
}, [agentId]);
|
|
3991
|
+
const hasChanges = useMemo7(
|
|
3992
|
+
() => initialized && !statesEqual(localState, serverState),
|
|
3993
|
+
[localState, serverState, initialized]
|
|
3994
|
+
);
|
|
3995
|
+
const scheduleSave = useCallback4(
|
|
3996
|
+
(nextState) => {
|
|
3997
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
3998
|
+
debounceRef.current = setTimeout(() => {
|
|
3999
|
+
const payload = stateToPayload(nextState);
|
|
4000
|
+
updateMutation.mutate(
|
|
4001
|
+
{ agentId, payload },
|
|
4002
|
+
{
|
|
4003
|
+
onSuccess: () => {
|
|
4004
|
+
setServerState(cloneState(nextState));
|
|
4005
|
+
toast10.success("Capacidades salvas");
|
|
4006
|
+
},
|
|
4007
|
+
onError: () => {
|
|
4008
|
+
setLocalState(cloneState(serverState));
|
|
4009
|
+
toast10.error("Erro ao salvar capacidades");
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
);
|
|
4013
|
+
}, 500);
|
|
4014
|
+
},
|
|
4015
|
+
[agentId, updateMutation, serverState]
|
|
4016
|
+
);
|
|
4017
|
+
const updateState = useCallback4(
|
|
4018
|
+
(updater) => {
|
|
4019
|
+
setLocalState((prev) => {
|
|
4020
|
+
const next = updater(prev);
|
|
4021
|
+
scheduleSave(next);
|
|
4022
|
+
return next;
|
|
4023
|
+
});
|
|
4024
|
+
},
|
|
4025
|
+
[scheduleSave]
|
|
4026
|
+
);
|
|
4027
|
+
const toggleModule = useCallback4(
|
|
4028
|
+
(mod, enabled) => {
|
|
4029
|
+
updateState((prev) => {
|
|
4030
|
+
const next = cloneState(prev);
|
|
4031
|
+
if (enabled) {
|
|
4032
|
+
next.set(mod.slug, new Set(mod.operations));
|
|
4033
|
+
} else {
|
|
4034
|
+
next.delete(mod.slug);
|
|
4035
|
+
}
|
|
4036
|
+
return next;
|
|
4037
|
+
});
|
|
4038
|
+
},
|
|
4039
|
+
[updateState]
|
|
4040
|
+
);
|
|
4041
|
+
const toggleOperation = useCallback4(
|
|
4042
|
+
(mod, opSlug, enabled) => {
|
|
4043
|
+
updateState((prev) => {
|
|
4044
|
+
const next = cloneState(prev);
|
|
4045
|
+
const ops = new Set(next.get(mod.slug) ?? []);
|
|
4046
|
+
if (enabled) {
|
|
4047
|
+
ops.add(opSlug);
|
|
4048
|
+
} else {
|
|
4049
|
+
ops.delete(opSlug);
|
|
4050
|
+
}
|
|
4051
|
+
if (ops.size > 0) {
|
|
4052
|
+
next.set(mod.slug, ops);
|
|
4053
|
+
} else {
|
|
4054
|
+
next.delete(mod.slug);
|
|
4055
|
+
}
|
|
4056
|
+
return next;
|
|
4057
|
+
});
|
|
4058
|
+
},
|
|
4059
|
+
[updateState]
|
|
4060
|
+
);
|
|
4061
|
+
const enableAll = useCallback4(() => {
|
|
4062
|
+
if (!registry) return;
|
|
4063
|
+
updateState(() => {
|
|
4064
|
+
const next = /* @__PURE__ */ new Map();
|
|
4065
|
+
for (const cat of registry.categories) {
|
|
4066
|
+
for (const mod of cat.modules) {
|
|
4067
|
+
next.set(mod.slug, new Set(mod.operations));
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
return next;
|
|
4071
|
+
});
|
|
4072
|
+
}, [registry, updateState]);
|
|
4073
|
+
const disableAll = useCallback4(() => {
|
|
4074
|
+
updateState(() => /* @__PURE__ */ new Map());
|
|
4075
|
+
}, [updateState]);
|
|
4076
|
+
const discard = useCallback4(() => {
|
|
4077
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
4078
|
+
setLocalState(cloneState(serverState));
|
|
4079
|
+
}, [serverState]);
|
|
4080
|
+
const saveNow = useCallback4(() => {
|
|
4081
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
4082
|
+
const payload = stateToPayload(localState);
|
|
4083
|
+
updateMutation.mutate(
|
|
4084
|
+
{ agentId, payload },
|
|
4085
|
+
{
|
|
4086
|
+
onSuccess: () => {
|
|
4087
|
+
setServerState(cloneState(localState));
|
|
4088
|
+
toast10.success("Capacidades salvas");
|
|
4089
|
+
},
|
|
4090
|
+
onError: () => {
|
|
4091
|
+
setLocalState(cloneState(serverState));
|
|
4092
|
+
toast10.error("Erro ao salvar capacidades");
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
);
|
|
4096
|
+
}, [agentId, localState, serverState, updateMutation]);
|
|
4097
|
+
function countActiveModules(cat) {
|
|
4098
|
+
return cat.modules.filter((m) => (localState.get(m.slug)?.size ?? 0) > 0).length;
|
|
4099
|
+
}
|
|
4100
|
+
if (isLoadingRegistry || isLoadingAgent) {
|
|
4101
|
+
return /* @__PURE__ */ jsx17("div", { className: "space-y-3", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx17(Skeleton6, { className: "h-14 w-full" }, i)) });
|
|
4102
|
+
}
|
|
4103
|
+
if (!registry || !registry.categories.length) {
|
|
4104
|
+
return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
|
|
4105
|
+
/* @__PURE__ */ jsx17(Package, { className: "h-12 w-12 text-muted-foreground mb-3" }),
|
|
4106
|
+
/* @__PURE__ */ jsx17("h3", { className: "text-base font-medium", children: "Nenhuma capacidade dispon\xEDvel" }),
|
|
4107
|
+
/* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground mt-1 max-w-sm", children: "Este produto ainda n\xE3o possui capacidades registadas. As capacidades ser\xE3o adicionadas automaticamente quando o produto for configurado." })
|
|
4108
|
+
] });
|
|
4109
|
+
}
|
|
4110
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-4", children: [
|
|
4111
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
4112
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
4113
|
+
/* @__PURE__ */ jsx17("h3", { className: "text-sm font-medium", children: "Capacidades do agente" }),
|
|
4114
|
+
/* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Ative ou desative m\xF3dulos e opera\xE7\xF5es dispon\xEDveis para este agente." })
|
|
4115
|
+
] }),
|
|
4116
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
4117
|
+
/* @__PURE__ */ jsx17(Button12, { variant: "outline", size: "sm", onClick: enableAll, children: "Ativar tudo" }),
|
|
4118
|
+
/* @__PURE__ */ jsx17(Button12, { variant: "outline", size: "sm", onClick: disableAll, children: "Desativar tudo" })
|
|
4119
|
+
] })
|
|
4120
|
+
] }),
|
|
4121
|
+
/* @__PURE__ */ jsx17(Accordion, { type: "multiple", className: "space-y-2", children: registry.categories.map((cat) => {
|
|
4122
|
+
const Icon = getCategoryIcon(cat.slug);
|
|
4123
|
+
const activeCount = countActiveModules(cat);
|
|
4124
|
+
const totalModules = cat.modules.length;
|
|
4125
|
+
return /* @__PURE__ */ jsxs15(
|
|
4126
|
+
AccordionItem,
|
|
4127
|
+
{
|
|
4128
|
+
value: cat.slug,
|
|
4129
|
+
className: "border rounded-lg px-4",
|
|
4130
|
+
children: [
|
|
4131
|
+
/* @__PURE__ */ jsx17(AccordionTrigger, { className: "hover:no-underline py-3", children: /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-3 flex-1", children: [
|
|
4132
|
+
/* @__PURE__ */ jsx17(Icon, { className: "h-4 w-4 text-muted-foreground" }),
|
|
4133
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium text-sm", children: cat.label }),
|
|
4134
|
+
/* @__PURE__ */ jsxs15(Badge9, { variant: "secondary", className: "text-xs", children: [
|
|
4135
|
+
activeCount,
|
|
4136
|
+
" de ",
|
|
4137
|
+
totalModules,
|
|
4138
|
+
" m\xF3dulos ativos"
|
|
4139
|
+
] })
|
|
4140
|
+
] }) }),
|
|
4141
|
+
/* @__PURE__ */ jsx17(AccordionContent, { className: "pb-3", children: /* @__PURE__ */ jsx17("div", { className: "space-y-1", children: cat.modules.map((mod) => {
|
|
4142
|
+
const enabledOps = localState.get(mod.slug);
|
|
4143
|
+
const isModuleOn = (enabledOps?.size ?? 0) > 0;
|
|
4144
|
+
const allOpsEnabled = enabledOps?.size === mod.operations.length;
|
|
4145
|
+
return /* @__PURE__ */ jsx17(
|
|
4146
|
+
ModuleRow,
|
|
4147
|
+
{
|
|
4148
|
+
module: mod,
|
|
4149
|
+
isOn: isModuleOn,
|
|
4150
|
+
allOpsEnabled,
|
|
4151
|
+
enabledOps: enabledOps ?? /* @__PURE__ */ new Set(),
|
|
4152
|
+
onToggleModule: (on) => toggleModule(mod, on),
|
|
4153
|
+
onToggleOperation: (op, on) => toggleOperation(mod, op, on)
|
|
4154
|
+
},
|
|
4155
|
+
mod.slug
|
|
4156
|
+
);
|
|
4157
|
+
}) }) })
|
|
4158
|
+
]
|
|
4159
|
+
},
|
|
4160
|
+
cat.slug
|
|
4161
|
+
);
|
|
4162
|
+
}) }),
|
|
4163
|
+
hasChanges && /* @__PURE__ */ jsxs15("div", { className: "sticky bottom-0 bg-background border-t py-3 px-4 -mx-4 flex items-center justify-between", children: [
|
|
4164
|
+
/* @__PURE__ */ jsx17("span", { className: "text-sm text-muted-foreground", children: "Voc\xEA tem altera\xE7\xF5es n\xE3o salvas." }),
|
|
4165
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
4166
|
+
/* @__PURE__ */ jsx17(Button12, { variant: "outline", size: "sm", onClick: discard, children: "Descartar" }),
|
|
4167
|
+
/* @__PURE__ */ jsx17(
|
|
4168
|
+
Button12,
|
|
4169
|
+
{
|
|
4170
|
+
size: "sm",
|
|
4171
|
+
onClick: saveNow,
|
|
4172
|
+
disabled: updateMutation.isPending,
|
|
4173
|
+
children: updateMutation.isPending ? "Salvando..." : "Salvar"
|
|
4174
|
+
}
|
|
4175
|
+
)
|
|
4176
|
+
] })
|
|
4177
|
+
] })
|
|
4178
|
+
] });
|
|
4179
|
+
}
|
|
4180
|
+
function ModuleRow({
|
|
4181
|
+
module: mod,
|
|
4182
|
+
isOn,
|
|
4183
|
+
enabledOps,
|
|
4184
|
+
onToggleModule,
|
|
4185
|
+
onToggleOperation
|
|
4186
|
+
}) {
|
|
4187
|
+
const [expanded, setExpanded] = useState12(false);
|
|
4188
|
+
return /* @__PURE__ */ jsxs15("div", { className: "rounded-md border px-3 py-2", children: [
|
|
4189
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
4190
|
+
/* @__PURE__ */ jsxs15(
|
|
4191
|
+
"button",
|
|
4192
|
+
{
|
|
4193
|
+
type: "button",
|
|
4194
|
+
className: "flex items-center gap-2 flex-1 text-left",
|
|
4195
|
+
onClick: () => setExpanded(!expanded),
|
|
4196
|
+
"aria-expanded": expanded,
|
|
4197
|
+
"aria-label": `Expandir ${mod.label}`,
|
|
4198
|
+
children: [
|
|
4199
|
+
/* @__PURE__ */ jsx17(
|
|
4200
|
+
ChevronDown2,
|
|
4201
|
+
{
|
|
4202
|
+
className: `h-3.5 w-3.5 text-muted-foreground transition-transform ${expanded ? "rotate-0" : "-rotate-90"}`
|
|
4203
|
+
}
|
|
4204
|
+
),
|
|
4205
|
+
/* @__PURE__ */ jsx17("span", { className: "text-sm font-medium", children: mod.label }),
|
|
4206
|
+
mod.description && /* @__PURE__ */ jsxs15("span", { className: "text-xs text-muted-foreground hidden sm:inline", children: [
|
|
4207
|
+
"\u2014 ",
|
|
4208
|
+
mod.description
|
|
4209
|
+
] }),
|
|
4210
|
+
isOn && /* @__PURE__ */ jsxs15(Badge9, { variant: "secondary", className: "text-xs ml-1", children: [
|
|
4211
|
+
enabledOps.size,
|
|
4212
|
+
"/",
|
|
4213
|
+
mod.operations.length
|
|
4214
|
+
] })
|
|
4215
|
+
]
|
|
4216
|
+
}
|
|
4217
|
+
),
|
|
4218
|
+
/* @__PURE__ */ jsx17(
|
|
4219
|
+
Switch4,
|
|
4220
|
+
{
|
|
4221
|
+
checked: isOn,
|
|
4222
|
+
onCheckedChange: onToggleModule,
|
|
4223
|
+
"aria-label": `Ativar m\xF3dulo ${mod.label}`
|
|
4224
|
+
}
|
|
4225
|
+
)
|
|
4226
|
+
] }),
|
|
4227
|
+
expanded && /* @__PURE__ */ jsx17("div", { className: "mt-2 ml-6 flex flex-wrap gap-x-5 gap-y-1.5 pb-1", children: mod.operations.map((op) => {
|
|
4228
|
+
const checked = enabledOps.has(op);
|
|
4229
|
+
return /* @__PURE__ */ jsxs15(
|
|
4230
|
+
"label",
|
|
4231
|
+
{
|
|
4232
|
+
className: "flex items-center gap-1.5 text-sm cursor-pointer",
|
|
4233
|
+
children: [
|
|
4234
|
+
/* @__PURE__ */ jsx17(
|
|
4235
|
+
Checkbox,
|
|
4236
|
+
{
|
|
4237
|
+
checked,
|
|
4238
|
+
onCheckedChange: (val) => onToggleOperation(op, val === true),
|
|
4239
|
+
"aria-label": `${getOperationLabel(op)} em ${mod.label}`
|
|
4240
|
+
}
|
|
4241
|
+
),
|
|
4242
|
+
/* @__PURE__ */ jsx17("span", { className: checked ? "" : "text-muted-foreground", children: getOperationLabel(op) })
|
|
4243
|
+
]
|
|
4244
|
+
},
|
|
4245
|
+
op
|
|
4246
|
+
);
|
|
4247
|
+
}) })
|
|
4248
|
+
] });
|
|
4249
|
+
}
|
|
4250
|
+
|
|
4251
|
+
// src/components/capabilities/advanced-tab.tsx
|
|
4252
|
+
import { useState as useState13 } from "react";
|
|
4253
|
+
import { Info } from "lucide-react";
|
|
4254
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4255
|
+
function AdvancedTab({ config, agentId, gagentsApiUrl }) {
|
|
4256
|
+
const { data: credentialsData, isLoading: isLoadingCredentials } = useToolCredentials(config);
|
|
4257
|
+
const credentials = credentialsData?.data ?? [];
|
|
4258
|
+
const [editingTool, setEditingTool] = useState13(null);
|
|
4259
|
+
const [showToolForm, setShowToolForm] = useState13(false);
|
|
4260
|
+
function handleEditTool(tool) {
|
|
4261
|
+
setEditingTool(tool);
|
|
4262
|
+
setShowToolForm(true);
|
|
4263
|
+
}
|
|
4264
|
+
function handleToolFormOpenChange(open) {
|
|
4265
|
+
setShowToolForm(open);
|
|
4266
|
+
if (!open) setEditingTool(null);
|
|
4267
|
+
}
|
|
4268
|
+
return /* @__PURE__ */ jsxs16("div", { className: "space-y-8", children: [
|
|
4269
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-3 rounded-lg border border-blue-200 bg-blue-50 p-4 dark:border-blue-900 dark:bg-blue-950/30", children: [
|
|
4270
|
+
/* @__PURE__ */ jsx18(Info, { className: "mt-0.5 h-4 w-4 shrink-0 text-blue-600 dark:text-blue-400" }),
|
|
4271
|
+
/* @__PURE__ */ jsxs16("p", { className: "text-sm text-blue-800 dark:text-blue-300", children: [
|
|
4272
|
+
"Use as abas ",
|
|
4273
|
+
/* @__PURE__ */ jsx18("strong", { children: "Capacidades" }),
|
|
4274
|
+
" e ",
|
|
4275
|
+
/* @__PURE__ */ jsx18("strong", { children: "Integra\xE7\xF5es" }),
|
|
4276
|
+
" para configura\xE7\xE3o simplificada. Esta aba oferece controlo manual avan\xE7ado sobre ferramentas e credenciais."
|
|
4277
|
+
] })
|
|
4278
|
+
] }),
|
|
4279
|
+
/* @__PURE__ */ jsxs16("section", { className: "space-y-3", children: [
|
|
4280
|
+
/* @__PURE__ */ jsx18("h3", { className: "text-sm font-medium", children: "Ferramentas" }),
|
|
4281
|
+
/* @__PURE__ */ jsx18(ToolsTable, { onEdit: handleEditTool, config })
|
|
4282
|
+
] }),
|
|
4283
|
+
/* @__PURE__ */ jsxs16("section", { className: "space-y-3", children: [
|
|
4284
|
+
/* @__PURE__ */ jsx18("h3", { className: "text-sm font-medium", children: "Credenciais" }),
|
|
4285
|
+
/* @__PURE__ */ jsx18(
|
|
4286
|
+
ToolCredentialsForm,
|
|
4287
|
+
{
|
|
4288
|
+
credentials,
|
|
4289
|
+
isLoading: isLoadingCredentials,
|
|
4290
|
+
config,
|
|
4291
|
+
gagentsApiUrl
|
|
4292
|
+
}
|
|
4293
|
+
)
|
|
4294
|
+
] }),
|
|
4295
|
+
/* @__PURE__ */ jsx18(
|
|
4296
|
+
ToolFormDialog,
|
|
4297
|
+
{
|
|
4298
|
+
open: showToolForm,
|
|
4299
|
+
onOpenChange: handleToolFormOpenChange,
|
|
4300
|
+
tool: editingTool ?? void 0,
|
|
4301
|
+
config
|
|
4302
|
+
}
|
|
4303
|
+
)
|
|
4304
|
+
] });
|
|
4305
|
+
}
|
|
4306
|
+
|
|
4307
|
+
// src/components/capabilities/integration-wizard.tsx
|
|
4308
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef3, useState as useState14 } from "react";
|
|
4309
|
+
import {
|
|
4310
|
+
Dialog as Dialog7,
|
|
4311
|
+
DialogContent as DialogContent7,
|
|
4312
|
+
DialogFooter as DialogFooter7,
|
|
4313
|
+
DialogHeader as DialogHeader7,
|
|
4314
|
+
DialogTitle as DialogTitle7,
|
|
4315
|
+
Button as Button14
|
|
4316
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
4317
|
+
import { Loader2 as Loader28, ChevronLeft, ChevronRight, Check as Check2 } from "lucide-react";
|
|
4318
|
+
import { toast as toast11 } from "sonner";
|
|
4319
|
+
|
|
4320
|
+
// src/components/capabilities/wizard-steps/info-step.tsx
|
|
4321
|
+
import { Check, Info as Info2 } from "lucide-react";
|
|
4322
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4323
|
+
function InfoStep({ integration, meta }) {
|
|
4324
|
+
return /* @__PURE__ */ jsxs17("div", { className: "space-y-6", children: [
|
|
4325
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-4", children: [
|
|
4326
|
+
meta.icon && /* @__PURE__ */ jsx19("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-muted", children: meta.icon }),
|
|
4327
|
+
/* @__PURE__ */ jsxs17("div", { className: "space-y-1", children: [
|
|
4328
|
+
/* @__PURE__ */ jsx19("h3", { className: "text-lg font-semibold", children: integration.name }),
|
|
4329
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: integration.description })
|
|
4330
|
+
] })
|
|
4331
|
+
] }),
|
|
4332
|
+
meta.capabilities.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
|
|
4333
|
+
/* @__PURE__ */ jsx19("h4", { className: "text-sm font-medium", children: "O que esta integra\xE7\xE3o permite:" }),
|
|
4334
|
+
/* @__PURE__ */ jsx19("ul", { className: "space-y-2", children: meta.capabilities.map((cap, i) => /* @__PURE__ */ jsxs17("li", { className: "flex items-start gap-2 text-sm", children: [
|
|
4335
|
+
/* @__PURE__ */ jsx19(
|
|
4336
|
+
Check,
|
|
4337
|
+
{
|
|
4338
|
+
"aria-hidden": "true",
|
|
4339
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
|
|
4340
|
+
}
|
|
4341
|
+
),
|
|
4342
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
4343
|
+
/* @__PURE__ */ jsx19("span", { className: "font-medium", children: cap.label }),
|
|
4344
|
+
cap.description && /* @__PURE__ */ jsxs17("span", { className: "text-muted-foreground", children: [
|
|
4345
|
+
" ",
|
|
4346
|
+
"\u2014 ",
|
|
4347
|
+
cap.description
|
|
4348
|
+
] })
|
|
4349
|
+
] })
|
|
4350
|
+
] }, i)) })
|
|
4351
|
+
] }),
|
|
4352
|
+
meta.requirements.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
|
|
4353
|
+
/* @__PURE__ */ jsx19("h4", { className: "text-sm font-medium", children: "Requisitos:" }),
|
|
4354
|
+
/* @__PURE__ */ jsx19("ul", { className: "space-y-2", children: meta.requirements.map((req, i) => /* @__PURE__ */ jsxs17(
|
|
4355
|
+
"li",
|
|
4356
|
+
{
|
|
4357
|
+
className: "flex items-start gap-2 text-sm text-muted-foreground",
|
|
4358
|
+
children: [
|
|
4359
|
+
/* @__PURE__ */ jsx19(
|
|
4360
|
+
Info2,
|
|
4361
|
+
{
|
|
4362
|
+
"aria-hidden": "true",
|
|
4363
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-blue-500"
|
|
4364
|
+
}
|
|
4365
|
+
),
|
|
4366
|
+
/* @__PURE__ */ jsx19("span", { children: req })
|
|
4367
|
+
]
|
|
4368
|
+
},
|
|
4369
|
+
i
|
|
4370
|
+
)) })
|
|
4371
|
+
] })
|
|
4372
|
+
] });
|
|
4373
|
+
}
|
|
4374
|
+
|
|
4375
|
+
// src/components/capabilities/wizard-steps/credentials-step.tsx
|
|
4376
|
+
import { CheckCircle2, Loader2 as Loader26, AlertCircle, Shield } from "lucide-react";
|
|
4377
|
+
import { Button as Button13, Input as Input10, Label as Label6 } from "@greatapps/greatauth-ui/ui";
|
|
4378
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4379
|
+
function CredentialsStep({
|
|
4380
|
+
integration,
|
|
4381
|
+
meta,
|
|
4382
|
+
oauthStatus,
|
|
4383
|
+
oauthResult,
|
|
4384
|
+
apiKey,
|
|
4385
|
+
onApiKeyChange,
|
|
4386
|
+
onStartOAuth,
|
|
4387
|
+
isReconnect = false
|
|
4388
|
+
}) {
|
|
4389
|
+
if (integration.authType === "oauth2") {
|
|
4390
|
+
return /* @__PURE__ */ jsx20(
|
|
4391
|
+
OAuthCredentials,
|
|
4392
|
+
{
|
|
4393
|
+
integration,
|
|
4394
|
+
meta,
|
|
4395
|
+
oauthStatus,
|
|
4396
|
+
oauthResult,
|
|
4397
|
+
onStartOAuth,
|
|
4398
|
+
isReconnect
|
|
4399
|
+
}
|
|
4400
|
+
);
|
|
4401
|
+
}
|
|
4402
|
+
return /* @__PURE__ */ jsx20(ApiKeyCredentials, { apiKey, onApiKeyChange });
|
|
4403
|
+
}
|
|
4404
|
+
function OAuthCredentials({
|
|
4405
|
+
integration,
|
|
4406
|
+
meta,
|
|
4407
|
+
oauthStatus,
|
|
4408
|
+
oauthResult,
|
|
4409
|
+
onStartOAuth,
|
|
4410
|
+
isReconnect
|
|
4411
|
+
}) {
|
|
4412
|
+
const providerLabel = meta.providerLabel || integration.name;
|
|
4413
|
+
return /* @__PURE__ */ jsxs18("div", { className: "space-y-6", children: [
|
|
4414
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
4415
|
+
/* @__PURE__ */ jsx20("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
|
|
4416
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: isReconnect ? `Reconecte sua conta ${providerLabel} para renovar a autoriza\xE7\xE3o.` : `Conecte sua conta ${providerLabel} para permitir o acesso.` })
|
|
4417
|
+
] }),
|
|
4418
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-4 rounded-lg border p-6", children: [
|
|
4419
|
+
oauthStatus === "idle" && /* @__PURE__ */ jsxs18(Button13, { onClick: onStartOAuth, size: "lg", className: "gap-2", children: [
|
|
4420
|
+
meta.icon,
|
|
4421
|
+
isReconnect ? `Reconectar com ${providerLabel}` : `Conectar com ${providerLabel}`
|
|
4422
|
+
] }),
|
|
4423
|
+
oauthStatus === "waiting" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
4424
|
+
/* @__PURE__ */ jsx20(
|
|
4425
|
+
Loader26,
|
|
4426
|
+
{
|
|
4427
|
+
"aria-hidden": "true",
|
|
4428
|
+
className: "h-8 w-8 animate-spin text-muted-foreground"
|
|
4429
|
+
}
|
|
4430
|
+
),
|
|
4431
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4432
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm font-medium", children: "Aguardando autoriza\xE7\xE3o..." }),
|
|
4433
|
+
/* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: "Complete o login na janela que foi aberta." })
|
|
4434
|
+
] })
|
|
4435
|
+
] }),
|
|
4436
|
+
oauthStatus === "success" && oauthResult && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
4437
|
+
/* @__PURE__ */ jsx20(
|
|
4438
|
+
CheckCircle2,
|
|
4439
|
+
{
|
|
4440
|
+
"aria-hidden": "true",
|
|
4441
|
+
className: "h-8 w-8 text-green-600"
|
|
4442
|
+
}
|
|
4443
|
+
),
|
|
4444
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4445
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-green-700", children: "Conectado com sucesso!" }),
|
|
4446
|
+
oauthResult.email && /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: oauthResult.email })
|
|
4447
|
+
] })
|
|
4448
|
+
] }),
|
|
4449
|
+
oauthStatus === "error" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
4450
|
+
/* @__PURE__ */ jsx20(
|
|
4451
|
+
AlertCircle,
|
|
4452
|
+
{
|
|
4453
|
+
"aria-hidden": "true",
|
|
4454
|
+
className: "h-8 w-8 text-destructive"
|
|
4455
|
+
}
|
|
4456
|
+
),
|
|
4457
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
4458
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-destructive", children: "Falha na conex\xE3o" }),
|
|
4459
|
+
oauthResult?.error && /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: oauthResult.error })
|
|
4460
|
+
] }),
|
|
4461
|
+
/* @__PURE__ */ jsx20(Button13, { variant: "outline", onClick: onStartOAuth, size: "sm", children: "Tentar novamente" })
|
|
4462
|
+
] })
|
|
4463
|
+
] }),
|
|
4464
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
|
|
4465
|
+
/* @__PURE__ */ jsx20(
|
|
4466
|
+
Shield,
|
|
4467
|
+
{
|
|
4468
|
+
"aria-hidden": "true",
|
|
4469
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
|
|
4470
|
+
}
|
|
4471
|
+
),
|
|
4472
|
+
/* @__PURE__ */ jsxs18("p", { className: "text-xs text-muted-foreground", children: [
|
|
4473
|
+
"Seus dados est\xE3o seguros. Usamos OAuth 2.0 para autentica\xE7\xE3o \u2014 nunca armazenamos sua senha. Voc\xEA pode revogar o acesso a qualquer momento nas configura\xE7\xF5es da sua conta ",
|
|
4474
|
+
providerLabel,
|
|
4475
|
+
"."
|
|
4476
|
+
] })
|
|
4477
|
+
] })
|
|
4478
|
+
] });
|
|
4479
|
+
}
|
|
4480
|
+
function ApiKeyCredentials({
|
|
4481
|
+
apiKey,
|
|
4482
|
+
onApiKeyChange
|
|
4483
|
+
}) {
|
|
4484
|
+
return /* @__PURE__ */ jsxs18("div", { className: "space-y-6", children: [
|
|
4485
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
4486
|
+
/* @__PURE__ */ jsx20("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
|
|
4487
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "Insira a chave de API para conectar a integra\xE7\xE3o." })
|
|
4488
|
+
] }),
|
|
4489
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
4490
|
+
/* @__PURE__ */ jsx20(Label6, { htmlFor: "integration-api-key", children: "Chave de API" }),
|
|
4491
|
+
/* @__PURE__ */ jsx20(
|
|
4492
|
+
Input10,
|
|
4493
|
+
{
|
|
4494
|
+
id: "integration-api-key",
|
|
4495
|
+
type: "password",
|
|
4496
|
+
autoComplete: "off",
|
|
4497
|
+
placeholder: "Insira sua chave de API...",
|
|
4498
|
+
value: apiKey,
|
|
4499
|
+
onChange: (e) => onApiKeyChange(e.target.value)
|
|
4500
|
+
}
|
|
4501
|
+
)
|
|
4502
|
+
] }),
|
|
4503
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
|
|
4504
|
+
/* @__PURE__ */ jsx20(
|
|
4505
|
+
Shield,
|
|
4506
|
+
{
|
|
4507
|
+
"aria-hidden": "true",
|
|
4508
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
|
|
4509
|
+
}
|
|
4510
|
+
),
|
|
4511
|
+
/* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: "Sua chave de API \xE9 armazenada de forma segura e encriptada. Nunca \xE9 exposta no frontend." })
|
|
4512
|
+
] })
|
|
4513
|
+
] });
|
|
4514
|
+
}
|
|
4515
|
+
|
|
4516
|
+
// src/components/capabilities/wizard-steps/config-step.tsx
|
|
4517
|
+
import { Loader2 as Loader27 } from "lucide-react";
|
|
4518
|
+
import {
|
|
4519
|
+
Label as Label7,
|
|
4520
|
+
Select as Select4,
|
|
4521
|
+
SelectContent as SelectContent4,
|
|
4522
|
+
SelectItem as SelectItem4,
|
|
4523
|
+
SelectTrigger as SelectTrigger4,
|
|
4524
|
+
SelectValue as SelectValue4
|
|
4525
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
4526
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4527
|
+
function ConfigStep({
|
|
4528
|
+
integration,
|
|
4529
|
+
options,
|
|
4530
|
+
isLoading,
|
|
4531
|
+
selectedValue,
|
|
4532
|
+
onValueChange,
|
|
4533
|
+
selectLabel,
|
|
4534
|
+
selectPlaceholder
|
|
4535
|
+
}) {
|
|
4536
|
+
const label = selectLabel || getDefaultLabel(integration.slug);
|
|
4537
|
+
const placeholder = selectPlaceholder || getDefaultPlaceholder(integration.slug);
|
|
4538
|
+
return /* @__PURE__ */ jsxs19("div", { className: "space-y-6", children: [
|
|
4539
|
+
/* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4540
|
+
/* @__PURE__ */ jsx21("h3", { className: "text-lg font-semibold", children: "Configura\xE7\xE3o" }),
|
|
4541
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Configure as op\xE7\xF5es espec\xEDficas da integra\xE7\xE3o." })
|
|
4542
|
+
] }),
|
|
4543
|
+
isLoading ? /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-3 py-8", children: [
|
|
4544
|
+
/* @__PURE__ */ jsx21(
|
|
4545
|
+
Loader27,
|
|
4546
|
+
{
|
|
4547
|
+
"aria-hidden": "true",
|
|
4548
|
+
className: "h-6 w-6 animate-spin text-muted-foreground"
|
|
4549
|
+
}
|
|
4550
|
+
),
|
|
4551
|
+
/* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Carregando op\xE7\xF5es..." })
|
|
4552
|
+
] }) : options.length === 0 ? /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-dashed p-6 text-center", children: /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Nenhuma op\xE7\xE3o dispon\xEDvel. A configura\xE7\xE3o padr\xE3o ser\xE1 usada." }) }) : /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4553
|
+
/* @__PURE__ */ jsx21(Label7, { htmlFor: "integration-config-select", children: label }),
|
|
4554
|
+
/* @__PURE__ */ jsxs19(Select4, { value: selectedValue, onValueChange, children: [
|
|
4555
|
+
/* @__PURE__ */ jsx21(SelectTrigger4, { id: "integration-config-select", children: /* @__PURE__ */ jsx21(SelectValue4, { placeholder }) }),
|
|
4556
|
+
/* @__PURE__ */ jsx21(SelectContent4, { children: options.map((opt) => /* @__PURE__ */ jsxs19(SelectItem4, { value: opt.id, children: [
|
|
4557
|
+
/* @__PURE__ */ jsx21("span", { children: opt.label }),
|
|
4558
|
+
opt.description && /* @__PURE__ */ jsxs19("span", { className: "ml-2 text-xs text-muted-foreground", children: [
|
|
4559
|
+
"(",
|
|
4560
|
+
opt.description,
|
|
4561
|
+
")"
|
|
4562
|
+
] })
|
|
4563
|
+
] }, opt.id)) })
|
|
4564
|
+
] })
|
|
4565
|
+
] })
|
|
4566
|
+
] });
|
|
4567
|
+
}
|
|
4568
|
+
function getDefaultLabel(slug) {
|
|
4569
|
+
switch (slug) {
|
|
4570
|
+
case "google_calendar":
|
|
4571
|
+
return "Calend\xE1rio";
|
|
4572
|
+
default:
|
|
4573
|
+
return "Op\xE7\xE3o";
|
|
4574
|
+
}
|
|
4575
|
+
}
|
|
4576
|
+
function getDefaultPlaceholder(slug) {
|
|
4577
|
+
switch (slug) {
|
|
4578
|
+
case "google_calendar":
|
|
4579
|
+
return "Selecione o calend\xE1rio...";
|
|
4580
|
+
default:
|
|
4581
|
+
return "Selecione uma op\xE7\xE3o...";
|
|
4582
|
+
}
|
|
4583
|
+
}
|
|
4584
|
+
|
|
4585
|
+
// src/components/capabilities/wizard-steps/confirm-step.tsx
|
|
4586
|
+
import { CheckCircle2 as CheckCircle22 } from "lucide-react";
|
|
4587
|
+
import { Label as Label8 } from "@greatapps/greatauth-ui/ui";
|
|
4588
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4589
|
+
function ConfirmStep({
|
|
4590
|
+
integration,
|
|
4591
|
+
oauthResult,
|
|
4592
|
+
selectedConfigOption,
|
|
4593
|
+
enableOnComplete,
|
|
4594
|
+
onEnableChange
|
|
4595
|
+
}) {
|
|
4596
|
+
return /* @__PURE__ */ jsxs20("div", { className: "space-y-6", children: [
|
|
4597
|
+
/* @__PURE__ */ jsxs20("div", { className: "space-y-2", children: [
|
|
4598
|
+
/* @__PURE__ */ jsx22("h3", { className: "text-lg font-semibold", children: "Confirma\xE7\xE3o" }),
|
|
4599
|
+
/* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Revise as configura\xE7\xF5es antes de concluir." })
|
|
4600
|
+
] }),
|
|
4601
|
+
/* @__PURE__ */ jsxs20("div", { className: "space-y-3 rounded-lg border p-4", children: [
|
|
4602
|
+
/* @__PURE__ */ jsx22(SummaryRow, { label: "Integra\xE7\xE3o", value: integration.name }),
|
|
4603
|
+
oauthResult?.email && /* @__PURE__ */ jsx22(SummaryRow, { label: "Conta conectada", value: oauthResult.email }),
|
|
4604
|
+
selectedConfigOption && /* @__PURE__ */ jsx22(
|
|
4605
|
+
SummaryRow,
|
|
4606
|
+
{
|
|
4607
|
+
label: getConfigLabel(integration.slug),
|
|
4608
|
+
value: selectedConfigOption.label
|
|
4609
|
+
}
|
|
4610
|
+
),
|
|
4611
|
+
/* @__PURE__ */ jsx22(
|
|
4612
|
+
SummaryRow,
|
|
4613
|
+
{
|
|
4614
|
+
label: "Tipo de autentica\xE7\xE3o",
|
|
4615
|
+
value: integration.authType === "oauth2" ? "OAuth 2.0" : "API Key"
|
|
4616
|
+
}
|
|
4617
|
+
)
|
|
4618
|
+
] }),
|
|
4619
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between rounded-lg border p-4", children: [
|
|
4620
|
+
/* @__PURE__ */ jsxs20("div", { className: "space-y-0.5", children: [
|
|
4621
|
+
/* @__PURE__ */ jsx22(Label8, { htmlFor: "enable-on-complete", className: "text-sm font-medium", children: "Ativar imediatamente" }),
|
|
4622
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: "A integra\xE7\xE3o ficar\xE1 ativa assim que concluir o assistente." })
|
|
4623
|
+
] }),
|
|
4624
|
+
/* @__PURE__ */ jsx22(
|
|
4625
|
+
"button",
|
|
4626
|
+
{
|
|
4627
|
+
id: "enable-on-complete",
|
|
4628
|
+
role: "switch",
|
|
4629
|
+
type: "button",
|
|
4630
|
+
"aria-checked": enableOnComplete,
|
|
4631
|
+
onClick: () => onEnableChange(!enableOnComplete),
|
|
4632
|
+
className: `
|
|
4633
|
+
relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent
|
|
4634
|
+
transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2
|
|
4635
|
+
focus-visible:ring-ring focus-visible:ring-offset-2
|
|
4636
|
+
${enableOnComplete ? "bg-primary" : "bg-muted"}
|
|
4637
|
+
`,
|
|
4638
|
+
children: /* @__PURE__ */ jsx22(
|
|
4639
|
+
"span",
|
|
4640
|
+
{
|
|
4641
|
+
"aria-hidden": "true",
|
|
4642
|
+
className: `
|
|
4643
|
+
pointer-events-none inline-block h-5 w-5 transform rounded-full bg-background shadow-lg
|
|
4644
|
+
ring-0 transition duration-200 ease-in-out
|
|
4645
|
+
${enableOnComplete ? "translate-x-5" : "translate-x-0"}
|
|
4646
|
+
`
|
|
4647
|
+
}
|
|
4648
|
+
)
|
|
4649
|
+
}
|
|
4650
|
+
)
|
|
4651
|
+
] }),
|
|
4652
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 rounded-md bg-green-50 p-3 dark:bg-green-950/20", children: [
|
|
4653
|
+
/* @__PURE__ */ jsx22(
|
|
4654
|
+
CheckCircle22,
|
|
4655
|
+
{
|
|
4656
|
+
"aria-hidden": "true",
|
|
4657
|
+
className: "h-4 w-4 shrink-0 text-green-600"
|
|
4658
|
+
}
|
|
4659
|
+
),
|
|
4660
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-green-700 dark:text-green-400", children: 'Tudo pronto! Clique em "Concluir" para finalizar a configura\xE7\xE3o.' })
|
|
4661
|
+
] })
|
|
4662
|
+
] });
|
|
4663
|
+
}
|
|
4664
|
+
function SummaryRow({ label, value }) {
|
|
4665
|
+
return /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between text-sm", children: [
|
|
4666
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: label }),
|
|
4667
|
+
/* @__PURE__ */ jsx22("span", { className: "font-medium", children: value })
|
|
4668
|
+
] });
|
|
4669
|
+
}
|
|
4670
|
+
function getConfigLabel(slug) {
|
|
4671
|
+
switch (slug) {
|
|
4672
|
+
case "google_calendar":
|
|
4673
|
+
return "Calend\xE1rio";
|
|
4674
|
+
default:
|
|
4675
|
+
return "Configura\xE7\xE3o";
|
|
4676
|
+
}
|
|
4677
|
+
}
|
|
4678
|
+
|
|
4679
|
+
// src/components/capabilities/integration-wizard.tsx
|
|
4680
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4681
|
+
var STEPS = ["info", "credentials", "config", "confirm"];
|
|
4682
|
+
var STEP_LABELS = {
|
|
4683
|
+
info: "Informa\xE7\xE3o",
|
|
4684
|
+
credentials: "Credenciais",
|
|
4685
|
+
config: "Configura\xE7\xE3o",
|
|
4686
|
+
confirm: "Confirma\xE7\xE3o"
|
|
4687
|
+
};
|
|
4688
|
+
function IntegrationWizard({
|
|
4689
|
+
open,
|
|
4690
|
+
onOpenChange,
|
|
4691
|
+
integration,
|
|
4692
|
+
meta,
|
|
4693
|
+
agentId: _agentId,
|
|
4694
|
+
config,
|
|
4695
|
+
onComplete,
|
|
4696
|
+
gagentsApiUrl,
|
|
4697
|
+
existingCredentialId,
|
|
4698
|
+
loadConfigOptions,
|
|
4699
|
+
existingConfigValue
|
|
4700
|
+
}) {
|
|
4701
|
+
const isReconnect = !!existingCredentialId;
|
|
4702
|
+
const [currentStep, setCurrentStep] = useState14("info");
|
|
4703
|
+
const currentIndex = STEPS.indexOf(currentStep);
|
|
4704
|
+
const [oauthStatus, setOauthStatus] = useState14("idle");
|
|
4705
|
+
const [oauthResult, setOauthResult] = useState14(null);
|
|
4706
|
+
const popupRef = useRef3(null);
|
|
4707
|
+
const popupPollRef = useRef3(null);
|
|
4708
|
+
const [apiKey, setApiKey] = useState14("");
|
|
4709
|
+
const [configOptions, setConfigOptions] = useState14([]);
|
|
4710
|
+
const [configLoading, setConfigLoading] = useState14(false);
|
|
4711
|
+
const [selectedConfigValue, setSelectedConfigValue] = useState14("");
|
|
4712
|
+
const [enableOnComplete, setEnableOnComplete] = useState14(true);
|
|
4713
|
+
const [isSubmitting, setIsSubmitting] = useState14(false);
|
|
4714
|
+
useEffect5(() => {
|
|
4715
|
+
return () => {
|
|
4716
|
+
if (popupPollRef.current) {
|
|
4717
|
+
clearInterval(popupPollRef.current);
|
|
4718
|
+
}
|
|
4719
|
+
};
|
|
4720
|
+
}, []);
|
|
4721
|
+
useEffect5(() => {
|
|
4722
|
+
if (open) {
|
|
4723
|
+
setCurrentStep("info");
|
|
4724
|
+
setOauthStatus("idle");
|
|
4725
|
+
setOauthResult(null);
|
|
4726
|
+
setApiKey("");
|
|
4727
|
+
setConfigOptions([]);
|
|
4728
|
+
setConfigLoading(false);
|
|
4729
|
+
setSelectedConfigValue(existingConfigValue ?? "");
|
|
4730
|
+
setEnableOnComplete(true);
|
|
4731
|
+
setIsSubmitting(false);
|
|
4732
|
+
} else {
|
|
4733
|
+
if (popupRef.current && !popupRef.current.closed) {
|
|
4734
|
+
popupRef.current.close();
|
|
4735
|
+
}
|
|
4736
|
+
if (popupPollRef.current) {
|
|
4737
|
+
clearInterval(popupPollRef.current);
|
|
4738
|
+
popupPollRef.current = null;
|
|
4739
|
+
}
|
|
4740
|
+
}
|
|
4741
|
+
}, [open]);
|
|
4742
|
+
const handleOAuthMessage = useCallback5(
|
|
4743
|
+
(event) => {
|
|
4744
|
+
try {
|
|
4745
|
+
if (event.origin !== new URL(gagentsApiUrl).origin) return;
|
|
4746
|
+
} catch {
|
|
4747
|
+
return;
|
|
4748
|
+
}
|
|
4749
|
+
if (!event.data || typeof event.data !== "object") return;
|
|
4750
|
+
const msg = event.data;
|
|
4751
|
+
if (msg.type !== "oauth-callback") return;
|
|
4752
|
+
if (msg.success) {
|
|
4753
|
+
setOauthStatus("success");
|
|
4754
|
+
setOauthResult({
|
|
4755
|
+
success: true,
|
|
4756
|
+
email: msg.email,
|
|
4757
|
+
credentialId: msg.credentialId
|
|
4758
|
+
});
|
|
4759
|
+
const credId = msg.credentialId || existingCredentialId;
|
|
4760
|
+
if (credId && loadConfigOptions && meta.hasConfigStep) {
|
|
4761
|
+
setConfigLoading(true);
|
|
4762
|
+
loadConfigOptions(credId).then((opts) => {
|
|
4763
|
+
setConfigOptions(opts);
|
|
4764
|
+
if (opts.length === 1) {
|
|
4765
|
+
setSelectedConfigValue(opts[0].id);
|
|
4766
|
+
}
|
|
4767
|
+
}).catch(() => setConfigOptions([])).finally(() => setConfigLoading(false));
|
|
4768
|
+
}
|
|
4769
|
+
setTimeout(() => {
|
|
4770
|
+
setCurrentStep(meta.hasConfigStep ? "config" : "confirm");
|
|
4771
|
+
}, 1200);
|
|
4772
|
+
} else {
|
|
4773
|
+
setOauthStatus("error");
|
|
4774
|
+
setOauthResult({
|
|
4775
|
+
success: false,
|
|
4776
|
+
error: msg.error || "Falha na autoriza\xE7\xE3o"
|
|
4777
|
+
});
|
|
4778
|
+
}
|
|
4779
|
+
},
|
|
4780
|
+
[gagentsApiUrl, existingCredentialId, meta.hasConfigStep, loadConfigOptions]
|
|
4781
|
+
);
|
|
4782
|
+
useEffect5(() => {
|
|
4783
|
+
if (!open) return;
|
|
4784
|
+
window.addEventListener("message", handleOAuthMessage);
|
|
4785
|
+
return () => window.removeEventListener("message", handleOAuthMessage);
|
|
4786
|
+
}, [open, handleOAuthMessage]);
|
|
4787
|
+
function startOAuth() {
|
|
4788
|
+
const { language = "pt-br", idWl = 1, accountId } = config;
|
|
4789
|
+
const redirectUri = `${window.location.origin}/oauth/callback`;
|
|
4790
|
+
const url = new URL(
|
|
4791
|
+
`${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${accountId}/oauth/authorize/${integration.slug}`
|
|
4792
|
+
);
|
|
4793
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
4794
|
+
setOauthStatus("waiting");
|
|
4795
|
+
const popup = window.open(
|
|
4796
|
+
url.toString(),
|
|
4797
|
+
"oauth-popup",
|
|
4798
|
+
"width=500,height=600,scrollbars=yes,resizable=yes"
|
|
4799
|
+
);
|
|
4800
|
+
popupRef.current = popup;
|
|
4801
|
+
if (popup) {
|
|
4802
|
+
if (popupPollRef.current) {
|
|
4803
|
+
clearInterval(popupPollRef.current);
|
|
4804
|
+
}
|
|
4805
|
+
popupPollRef.current = setInterval(() => {
|
|
4806
|
+
if (popup.closed) {
|
|
4807
|
+
if (popupPollRef.current) {
|
|
4808
|
+
clearInterval(popupPollRef.current);
|
|
4809
|
+
popupPollRef.current = null;
|
|
4810
|
+
}
|
|
4811
|
+
setOauthStatus(
|
|
4812
|
+
(prev) => prev === "waiting" ? "error" : prev
|
|
4813
|
+
);
|
|
4814
|
+
setOauthResult(
|
|
4815
|
+
(prev) => prev === null ? { success: false, error: "Janela fechada antes de concluir" } : prev
|
|
4816
|
+
);
|
|
4817
|
+
}
|
|
4818
|
+
}, 500);
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
function canAdvance() {
|
|
4822
|
+
switch (currentStep) {
|
|
4823
|
+
case "info":
|
|
4824
|
+
return true;
|
|
4825
|
+
case "credentials":
|
|
4826
|
+
if (integration.authType === "oauth2") {
|
|
4827
|
+
return oauthStatus === "success";
|
|
4828
|
+
}
|
|
4829
|
+
return apiKey.trim().length > 0;
|
|
4830
|
+
case "config":
|
|
4831
|
+
return true;
|
|
4832
|
+
case "confirm":
|
|
4833
|
+
return true;
|
|
4834
|
+
default:
|
|
4835
|
+
return false;
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
function goNext() {
|
|
4839
|
+
if (!canAdvance()) return;
|
|
4840
|
+
if (currentStep === "credentials" && !meta.hasConfigStep) {
|
|
4841
|
+
setCurrentStep("confirm");
|
|
4842
|
+
return;
|
|
4843
|
+
}
|
|
4844
|
+
const nextIndex = currentIndex + 1;
|
|
4845
|
+
if (nextIndex < STEPS.length) {
|
|
4846
|
+
setCurrentStep(STEPS[nextIndex]);
|
|
4847
|
+
}
|
|
4848
|
+
}
|
|
4849
|
+
function goPrev() {
|
|
4850
|
+
if (currentStep === "confirm" && !meta.hasConfigStep) {
|
|
4851
|
+
setCurrentStep("credentials");
|
|
4852
|
+
return;
|
|
4853
|
+
}
|
|
4854
|
+
const prevIndex = currentIndex - 1;
|
|
4855
|
+
if (prevIndex >= 0) {
|
|
4856
|
+
setCurrentStep(STEPS[prevIndex]);
|
|
4857
|
+
}
|
|
4858
|
+
}
|
|
4859
|
+
async function handleComplete() {
|
|
4860
|
+
setIsSubmitting(true);
|
|
4861
|
+
try {
|
|
4862
|
+
onComplete();
|
|
4863
|
+
onOpenChange(false);
|
|
4864
|
+
toast11.success(
|
|
4865
|
+
`${integration.name} ${isReconnect ? "reconectado" : "configurado"} com sucesso!`
|
|
4866
|
+
);
|
|
4867
|
+
} catch {
|
|
4868
|
+
toast11.error("Erro ao finalizar configura\xE7\xE3o");
|
|
4869
|
+
} finally {
|
|
4870
|
+
setIsSubmitting(false);
|
|
4871
|
+
}
|
|
4872
|
+
}
|
|
4873
|
+
const selectedConfigOption = configOptions.find((o) => o.id === selectedConfigValue) || null;
|
|
4874
|
+
const isLastStep = currentStep === "confirm";
|
|
4875
|
+
const effectiveSteps = meta.hasConfigStep ? STEPS : STEPS.filter((s) => s !== "config");
|
|
4876
|
+
return /* @__PURE__ */ jsx23(Dialog7, { open, onOpenChange, children: /* @__PURE__ */ jsxs21(DialogContent7, { className: "sm:max-w-lg", children: [
|
|
4877
|
+
/* @__PURE__ */ jsx23(DialogHeader7, { children: /* @__PURE__ */ jsx23(DialogTitle7, { children: integration.name }) }),
|
|
4878
|
+
/* @__PURE__ */ jsx23(StepIndicator, { steps: effectiveSteps, currentStep }),
|
|
4879
|
+
/* @__PURE__ */ jsxs21("div", { className: "min-h-[280px] py-2", children: [
|
|
4880
|
+
currentStep === "info" && /* @__PURE__ */ jsx23(
|
|
4881
|
+
InfoStep,
|
|
4882
|
+
{
|
|
4883
|
+
integration,
|
|
4884
|
+
meta
|
|
4885
|
+
}
|
|
4886
|
+
),
|
|
4887
|
+
currentStep === "credentials" && /* @__PURE__ */ jsx23(
|
|
4888
|
+
CredentialsStep,
|
|
4889
|
+
{
|
|
4890
|
+
integration,
|
|
4891
|
+
meta,
|
|
4892
|
+
oauthStatus,
|
|
4893
|
+
oauthResult,
|
|
4894
|
+
apiKey,
|
|
4895
|
+
onApiKeyChange: setApiKey,
|
|
4896
|
+
onStartOAuth: startOAuth,
|
|
4897
|
+
isReconnect
|
|
4898
|
+
}
|
|
4899
|
+
),
|
|
4900
|
+
currentStep === "config" && /* @__PURE__ */ jsx23(
|
|
4901
|
+
ConfigStep,
|
|
4902
|
+
{
|
|
4903
|
+
integration,
|
|
4904
|
+
options: configOptions,
|
|
4905
|
+
isLoading: configLoading,
|
|
4906
|
+
selectedValue: selectedConfigValue,
|
|
4907
|
+
onValueChange: setSelectedConfigValue
|
|
4908
|
+
}
|
|
4909
|
+
),
|
|
4910
|
+
currentStep === "confirm" && /* @__PURE__ */ jsx23(
|
|
4911
|
+
ConfirmStep,
|
|
4912
|
+
{
|
|
4913
|
+
integration,
|
|
4914
|
+
oauthResult,
|
|
4915
|
+
selectedConfigOption,
|
|
4916
|
+
enableOnComplete,
|
|
4917
|
+
onEnableChange: setEnableOnComplete
|
|
4918
|
+
}
|
|
4919
|
+
)
|
|
4920
|
+
] }),
|
|
4921
|
+
/* @__PURE__ */ jsxs21(DialogFooter7, { className: "flex-row justify-between sm:justify-between", children: [
|
|
4922
|
+
/* @__PURE__ */ jsx23("div", { children: currentStep === "info" ? /* @__PURE__ */ jsx23(
|
|
4923
|
+
Button14,
|
|
4924
|
+
{
|
|
4925
|
+
type: "button",
|
|
4926
|
+
variant: "outline",
|
|
4927
|
+
onClick: () => onOpenChange(false),
|
|
4928
|
+
children: "Cancelar"
|
|
4929
|
+
}
|
|
4930
|
+
) : /* @__PURE__ */ jsxs21(
|
|
4931
|
+
Button14,
|
|
4932
|
+
{
|
|
4933
|
+
type: "button",
|
|
4934
|
+
variant: "outline",
|
|
4935
|
+
onClick: goPrev,
|
|
4936
|
+
className: "gap-1",
|
|
4937
|
+
children: [
|
|
4938
|
+
/* @__PURE__ */ jsx23(ChevronLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
|
|
4939
|
+
"Voltar"
|
|
4940
|
+
]
|
|
4941
|
+
}
|
|
4942
|
+
) }),
|
|
4943
|
+
/* @__PURE__ */ jsx23("div", { children: isLastStep ? /* @__PURE__ */ jsxs21(
|
|
4944
|
+
Button14,
|
|
4945
|
+
{
|
|
4946
|
+
type: "button",
|
|
4947
|
+
onClick: handleComplete,
|
|
4948
|
+
disabled: isSubmitting,
|
|
4949
|
+
className: "gap-1",
|
|
4950
|
+
children: [
|
|
4951
|
+
isSubmitting ? /* @__PURE__ */ jsx23(
|
|
4952
|
+
Loader28,
|
|
4953
|
+
{
|
|
4954
|
+
"aria-hidden": "true",
|
|
4955
|
+
className: "h-4 w-4 animate-spin"
|
|
4956
|
+
}
|
|
4957
|
+
) : /* @__PURE__ */ jsx23(Check2, { "aria-hidden": "true", className: "h-4 w-4" }),
|
|
4958
|
+
"Concluir"
|
|
4959
|
+
]
|
|
4960
|
+
}
|
|
4961
|
+
) : /* @__PURE__ */ jsxs21(
|
|
4962
|
+
Button14,
|
|
4963
|
+
{
|
|
4964
|
+
type: "button",
|
|
4965
|
+
onClick: goNext,
|
|
4966
|
+
disabled: !canAdvance(),
|
|
4967
|
+
className: "gap-1",
|
|
4968
|
+
children: [
|
|
4969
|
+
"Continuar",
|
|
4970
|
+
/* @__PURE__ */ jsx23(ChevronRight, { "aria-hidden": "true", className: "h-4 w-4" })
|
|
4971
|
+
]
|
|
4972
|
+
}
|
|
4973
|
+
) })
|
|
4974
|
+
] })
|
|
4975
|
+
] }) });
|
|
4976
|
+
}
|
|
4977
|
+
function StepIndicator({
|
|
4978
|
+
steps,
|
|
4979
|
+
currentStep
|
|
4980
|
+
}) {
|
|
4981
|
+
const currentIndex = steps.indexOf(currentStep);
|
|
4982
|
+
return /* @__PURE__ */ jsx23(
|
|
4983
|
+
"div",
|
|
4984
|
+
{
|
|
4985
|
+
className: "flex items-center justify-center gap-1 py-2",
|
|
4986
|
+
role: "list",
|
|
4987
|
+
"aria-label": "Passos do assistente",
|
|
4988
|
+
children: steps.map((step, i) => {
|
|
4989
|
+
const isCompleted = i < currentIndex;
|
|
4990
|
+
const isCurrent = step === currentStep;
|
|
4991
|
+
return /* @__PURE__ */ jsxs21("div", { className: "flex items-center", role: "listitem", children: [
|
|
4992
|
+
/* @__PURE__ */ jsx23(
|
|
4993
|
+
"div",
|
|
4994
|
+
{
|
|
4995
|
+
className: `
|
|
4996
|
+
flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium
|
|
4997
|
+
transition-colors duration-200
|
|
4998
|
+
${isCurrent ? "bg-primary text-primary-foreground" : isCompleted ? "bg-green-600 text-white" : "bg-muted text-muted-foreground"}
|
|
4999
|
+
`,
|
|
5000
|
+
"aria-current": isCurrent ? "step" : void 0,
|
|
5001
|
+
"aria-label": `${STEP_LABELS[step]}${isCompleted ? " (conclu\xEDdo)" : isCurrent ? " (atual)" : ""}`,
|
|
5002
|
+
children: isCompleted ? /* @__PURE__ */ jsx23(Check2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : i + 1
|
|
5003
|
+
}
|
|
5004
|
+
),
|
|
5005
|
+
/* @__PURE__ */ jsx23(
|
|
5006
|
+
"span",
|
|
5007
|
+
{
|
|
5008
|
+
className: `
|
|
5009
|
+
ml-1.5 hidden text-xs sm:inline
|
|
5010
|
+
${isCurrent ? "font-medium text-foreground" : "text-muted-foreground"}
|
|
5011
|
+
`,
|
|
5012
|
+
children: STEP_LABELS[step]
|
|
5013
|
+
}
|
|
5014
|
+
),
|
|
5015
|
+
i < steps.length - 1 && /* @__PURE__ */ jsx23(
|
|
5016
|
+
"div",
|
|
5017
|
+
{
|
|
5018
|
+
className: `
|
|
5019
|
+
mx-2 h-px w-6
|
|
5020
|
+
${i < currentIndex ? "bg-green-600" : "bg-border"}
|
|
5021
|
+
`
|
|
5022
|
+
}
|
|
5023
|
+
)
|
|
5024
|
+
] }, step);
|
|
5025
|
+
})
|
|
5026
|
+
}
|
|
5027
|
+
);
|
|
5028
|
+
}
|
|
5029
|
+
|
|
3653
5030
|
// src/pages/agents-page.tsx
|
|
3654
|
-
import { useState as
|
|
3655
|
-
import { Button as
|
|
5031
|
+
import { useState as useState15 } from "react";
|
|
5032
|
+
import { Button as Button15 } from "@greatapps/greatauth-ui/ui";
|
|
3656
5033
|
import { Plus as Plus3 } from "lucide-react";
|
|
3657
|
-
import { jsx as
|
|
5034
|
+
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3658
5035
|
function AgentsPage({
|
|
3659
5036
|
config,
|
|
3660
5037
|
onNavigateToAgent,
|
|
3661
5038
|
title = "Agentes AI",
|
|
3662
5039
|
subtitle = "Gerencie seus agentes de atendimento inteligente"
|
|
3663
5040
|
}) {
|
|
3664
|
-
const [createOpen, setCreateOpen] =
|
|
3665
|
-
return /* @__PURE__ */
|
|
3666
|
-
/* @__PURE__ */
|
|
3667
|
-
/* @__PURE__ */
|
|
3668
|
-
/* @__PURE__ */
|
|
3669
|
-
/* @__PURE__ */
|
|
5041
|
+
const [createOpen, setCreateOpen] = useState15(false);
|
|
5042
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5043
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between", children: [
|
|
5044
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
5045
|
+
/* @__PURE__ */ jsx24("h1", { className: "text-xl font-semibold", children: title }),
|
|
5046
|
+
/* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
3670
5047
|
] }),
|
|
3671
|
-
/* @__PURE__ */
|
|
3672
|
-
/* @__PURE__ */
|
|
5048
|
+
/* @__PURE__ */ jsxs22(Button15, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5049
|
+
/* @__PURE__ */ jsx24(Plus3, { className: "mr-2 h-4 w-4" }),
|
|
3673
5050
|
"Novo Agente"
|
|
3674
5051
|
] })
|
|
3675
5052
|
] }),
|
|
3676
|
-
/* @__PURE__ */
|
|
3677
|
-
/* @__PURE__ */
|
|
5053
|
+
/* @__PURE__ */ jsx24(AgentsTable, { config, onNavigateToAgent }),
|
|
5054
|
+
/* @__PURE__ */ jsx24(
|
|
3678
5055
|
AgentFormDialog,
|
|
3679
5056
|
{
|
|
3680
5057
|
config,
|
|
@@ -3686,11 +5063,11 @@ function AgentsPage({
|
|
|
3686
5063
|
}
|
|
3687
5064
|
|
|
3688
5065
|
// src/pages/agent-detail-page.tsx
|
|
3689
|
-
import { useState as
|
|
3690
|
-
import { Badge as
|
|
5066
|
+
import { useState as useState16 } from "react";
|
|
5067
|
+
import { Badge as Badge10, Button as Button16, Skeleton as Skeleton7 } from "@greatapps/greatauth-ui/ui";
|
|
3691
5068
|
import { EntityAvatar as EntityAvatar2 } from "@greatapps/greatauth-ui";
|
|
3692
5069
|
import { ArrowLeft, Pencil as Pencil5 } from "lucide-react";
|
|
3693
|
-
import { jsx as
|
|
5070
|
+
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3694
5071
|
function AgentDetailPage({
|
|
3695
5072
|
config,
|
|
3696
5073
|
agentId,
|
|
@@ -3698,43 +5075,43 @@ function AgentDetailPage({
|
|
|
3698
5075
|
renderChatLink
|
|
3699
5076
|
}) {
|
|
3700
5077
|
const { data: agent, isLoading } = useAgent(config, agentId);
|
|
3701
|
-
const [editOpen, setEditOpen] =
|
|
5078
|
+
const [editOpen, setEditOpen] = useState16(false);
|
|
3702
5079
|
if (isLoading) {
|
|
3703
|
-
return /* @__PURE__ */
|
|
3704
|
-
/* @__PURE__ */
|
|
3705
|
-
/* @__PURE__ */
|
|
3706
|
-
/* @__PURE__ */
|
|
3707
|
-
/* @__PURE__ */
|
|
5080
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 p-4", children: [
|
|
5081
|
+
/* @__PURE__ */ jsx25(Skeleton7, { className: "h-4 w-32" }),
|
|
5082
|
+
/* @__PURE__ */ jsx25(Skeleton7, { className: "h-8 w-48" }),
|
|
5083
|
+
/* @__PURE__ */ jsx25(Skeleton7, { className: "h-10 w-full" }),
|
|
5084
|
+
/* @__PURE__ */ jsx25(Skeleton7, { className: "h-64 w-full" })
|
|
3708
5085
|
] });
|
|
3709
5086
|
}
|
|
3710
5087
|
if (!agent) {
|
|
3711
|
-
return /* @__PURE__ */
|
|
3712
|
-
/* @__PURE__ */
|
|
3713
|
-
onBack && /* @__PURE__ */
|
|
3714
|
-
/* @__PURE__ */
|
|
5088
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [
|
|
5089
|
+
/* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: "Agente n\xE3o encontrado" }),
|
|
5090
|
+
onBack && /* @__PURE__ */ jsxs23(Button16, { variant: "ghost", size: "sm", onClick: onBack, children: [
|
|
5091
|
+
/* @__PURE__ */ jsx25(ArrowLeft, { className: "mr-2 h-4 w-4" }),
|
|
3715
5092
|
"Voltar para agentes"
|
|
3716
5093
|
] })
|
|
3717
5094
|
] });
|
|
3718
5095
|
}
|
|
3719
|
-
return /* @__PURE__ */
|
|
3720
|
-
/* @__PURE__ */
|
|
3721
|
-
/* @__PURE__ */
|
|
3722
|
-
onBack && /* @__PURE__ */
|
|
3723
|
-
|
|
5096
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-6 p-4 md:p-6", children: [
|
|
5097
|
+
/* @__PURE__ */ jsx25("div", { className: "rounded-lg border p-4 md:p-6", children: /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:gap-6", children: [
|
|
5098
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-start gap-3 flex-1", children: [
|
|
5099
|
+
onBack && /* @__PURE__ */ jsx25(
|
|
5100
|
+
Button16,
|
|
3724
5101
|
{
|
|
3725
5102
|
variant: "ghost",
|
|
3726
5103
|
size: "icon",
|
|
3727
5104
|
"aria-label": "Voltar",
|
|
3728
5105
|
className: "shrink-0 mt-1",
|
|
3729
5106
|
onClick: onBack,
|
|
3730
|
-
children: /* @__PURE__ */
|
|
5107
|
+
children: /* @__PURE__ */ jsx25(ArrowLeft, { className: "h-4 w-4" })
|
|
3731
5108
|
}
|
|
3732
5109
|
),
|
|
3733
|
-
/* @__PURE__ */
|
|
3734
|
-
/* @__PURE__ */
|
|
3735
|
-
/* @__PURE__ */
|
|
3736
|
-
/* @__PURE__ */
|
|
3737
|
-
|
|
5110
|
+
/* @__PURE__ */ jsx25(EntityAvatar2, { photo: agent.photo, name: agent.title, size: "xl" }),
|
|
5111
|
+
/* @__PURE__ */ jsx25("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
5112
|
+
/* @__PURE__ */ jsx25("h1", { className: "text-xl font-semibold", children: agent.title }),
|
|
5113
|
+
/* @__PURE__ */ jsx25(
|
|
5114
|
+
Badge10,
|
|
3738
5115
|
{
|
|
3739
5116
|
variant: agent.active ? "default" : "destructive",
|
|
3740
5117
|
className: "text-xs",
|
|
@@ -3743,21 +5120,21 @@ function AgentDetailPage({
|
|
|
3743
5120
|
)
|
|
3744
5121
|
] }) })
|
|
3745
5122
|
] }),
|
|
3746
|
-
/* @__PURE__ */
|
|
3747
|
-
|
|
5123
|
+
/* @__PURE__ */ jsxs23(
|
|
5124
|
+
Button16,
|
|
3748
5125
|
{
|
|
3749
5126
|
variant: "outline",
|
|
3750
5127
|
size: "sm",
|
|
3751
5128
|
className: "shrink-0 self-start",
|
|
3752
5129
|
onClick: () => setEditOpen(true),
|
|
3753
5130
|
children: [
|
|
3754
|
-
/* @__PURE__ */
|
|
5131
|
+
/* @__PURE__ */ jsx25(Pencil5, { className: "mr-2 h-4 w-4" }),
|
|
3755
5132
|
"Editar"
|
|
3756
5133
|
]
|
|
3757
5134
|
}
|
|
3758
5135
|
)
|
|
3759
5136
|
] }) }),
|
|
3760
|
-
/* @__PURE__ */
|
|
5137
|
+
/* @__PURE__ */ jsx25(
|
|
3761
5138
|
AgentTabs,
|
|
3762
5139
|
{
|
|
3763
5140
|
agent,
|
|
@@ -3765,7 +5142,7 @@ function AgentDetailPage({
|
|
|
3765
5142
|
renderChatLink
|
|
3766
5143
|
}
|
|
3767
5144
|
),
|
|
3768
|
-
editOpen && /* @__PURE__ */
|
|
5145
|
+
editOpen && /* @__PURE__ */ jsx25(
|
|
3769
5146
|
AgentEditForm,
|
|
3770
5147
|
{
|
|
3771
5148
|
agent,
|
|
@@ -3778,31 +5155,133 @@ function AgentDetailPage({
|
|
|
3778
5155
|
] });
|
|
3779
5156
|
}
|
|
3780
5157
|
|
|
5158
|
+
// src/pages/agent-capabilities-page.tsx
|
|
5159
|
+
import { useState as useState17, useCallback as useCallback6 } from "react";
|
|
5160
|
+
import {
|
|
5161
|
+
Tabs as Tabs2,
|
|
5162
|
+
TabsList as TabsList2,
|
|
5163
|
+
TabsTrigger as TabsTrigger2,
|
|
5164
|
+
TabsContent as TabsContent2
|
|
5165
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
5166
|
+
import { Blocks, Plug as Plug3, Settings as Settings4 } from "lucide-react";
|
|
5167
|
+
import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5168
|
+
function defaultResolveWizardMeta(card) {
|
|
5169
|
+
return {
|
|
5170
|
+
capabilities: [
|
|
5171
|
+
{ label: card.definition.name, description: card.definition.description }
|
|
5172
|
+
],
|
|
5173
|
+
requirements: [],
|
|
5174
|
+
hasConfigStep: false
|
|
5175
|
+
};
|
|
5176
|
+
}
|
|
5177
|
+
function AgentCapabilitiesPage({
|
|
5178
|
+
config,
|
|
5179
|
+
agentId,
|
|
5180
|
+
gagentsApiUrl,
|
|
5181
|
+
resolveWizardMeta = defaultResolveWizardMeta,
|
|
5182
|
+
loadConfigOptions,
|
|
5183
|
+
onWizardComplete
|
|
5184
|
+
}) {
|
|
5185
|
+
const [wizardOpen, setWizardOpen] = useState17(false);
|
|
5186
|
+
const [activeCard, setActiveCard] = useState17(null);
|
|
5187
|
+
const handleConnect = useCallback6(
|
|
5188
|
+
(card) => {
|
|
5189
|
+
setActiveCard(card);
|
|
5190
|
+
setWizardOpen(true);
|
|
5191
|
+
},
|
|
5192
|
+
[]
|
|
5193
|
+
);
|
|
5194
|
+
const handleWizardComplete = useCallback6(() => {
|
|
5195
|
+
setWizardOpen(false);
|
|
5196
|
+
setActiveCard(null);
|
|
5197
|
+
onWizardComplete?.();
|
|
5198
|
+
}, [onWizardComplete]);
|
|
5199
|
+
const handleWizardOpenChange = useCallback6((open) => {
|
|
5200
|
+
setWizardOpen(open);
|
|
5201
|
+
if (!open) setActiveCard(null);
|
|
5202
|
+
}, []);
|
|
5203
|
+
const wizardMeta = activeCard ? resolveWizardMeta(activeCard) : null;
|
|
5204
|
+
return /* @__PURE__ */ jsxs24("div", { className: "space-y-4", children: [
|
|
5205
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
5206
|
+
/* @__PURE__ */ jsx26("h2", { className: "text-lg font-semibold", children: "Capacidades e Integra\xE7\xF5es" }),
|
|
5207
|
+
/* @__PURE__ */ jsx26("p", { className: "text-sm text-muted-foreground", children: "Configure o que este agente pode fazer e quais servi\xE7os externos ele utiliza." })
|
|
5208
|
+
] }),
|
|
5209
|
+
/* @__PURE__ */ jsxs24(Tabs2, { defaultValue: "capacidades", children: [
|
|
5210
|
+
/* @__PURE__ */ jsxs24(TabsList2, { children: [
|
|
5211
|
+
/* @__PURE__ */ jsxs24(TabsTrigger2, { value: "capacidades", className: "flex items-center gap-1.5", children: [
|
|
5212
|
+
/* @__PURE__ */ jsx26(Blocks, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5213
|
+
"Capacidades"
|
|
5214
|
+
] }),
|
|
5215
|
+
/* @__PURE__ */ jsxs24(TabsTrigger2, { value: "integracoes", className: "flex items-center gap-1.5", children: [
|
|
5216
|
+
/* @__PURE__ */ jsx26(Plug3, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5217
|
+
"Integra\xE7\xF5es"
|
|
5218
|
+
] }),
|
|
5219
|
+
/* @__PURE__ */ jsxs24(TabsTrigger2, { value: "avancado", className: "flex items-center gap-1.5", children: [
|
|
5220
|
+
/* @__PURE__ */ jsx26(Settings4, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5221
|
+
"Avan\xE7ado"
|
|
5222
|
+
] })
|
|
5223
|
+
] }),
|
|
5224
|
+
/* @__PURE__ */ jsx26(TabsContent2, { value: "capacidades", className: "mt-4", children: /* @__PURE__ */ jsx26(CapabilitiesTab, { config, agentId }) }),
|
|
5225
|
+
/* @__PURE__ */ jsx26(TabsContent2, { value: "integracoes", className: "mt-4", children: /* @__PURE__ */ jsx26(
|
|
5226
|
+
IntegrationsTab,
|
|
5227
|
+
{
|
|
5228
|
+
config,
|
|
5229
|
+
agentId,
|
|
5230
|
+
onConnect: handleConnect
|
|
5231
|
+
}
|
|
5232
|
+
) }),
|
|
5233
|
+
/* @__PURE__ */ jsx26(TabsContent2, { value: "avancado", className: "mt-4", children: /* @__PURE__ */ jsx26(
|
|
5234
|
+
AdvancedTab,
|
|
5235
|
+
{
|
|
5236
|
+
config,
|
|
5237
|
+
agentId,
|
|
5238
|
+
gagentsApiUrl
|
|
5239
|
+
}
|
|
5240
|
+
) })
|
|
5241
|
+
] }),
|
|
5242
|
+
activeCard && wizardMeta && /* @__PURE__ */ jsx26(
|
|
5243
|
+
IntegrationWizard,
|
|
5244
|
+
{
|
|
5245
|
+
open: wizardOpen,
|
|
5246
|
+
onOpenChange: handleWizardOpenChange,
|
|
5247
|
+
integration: activeCard.definition,
|
|
5248
|
+
meta: wizardMeta,
|
|
5249
|
+
agentId,
|
|
5250
|
+
config,
|
|
5251
|
+
onComplete: handleWizardComplete,
|
|
5252
|
+
gagentsApiUrl,
|
|
5253
|
+
existingCredentialId: activeCard.credential?.id,
|
|
5254
|
+
loadConfigOptions
|
|
5255
|
+
}
|
|
5256
|
+
)
|
|
5257
|
+
] });
|
|
5258
|
+
}
|
|
5259
|
+
|
|
3781
5260
|
// src/pages/tools-page.tsx
|
|
3782
|
-
import { useState as
|
|
3783
|
-
import { Button as
|
|
5261
|
+
import { useState as useState18 } from "react";
|
|
5262
|
+
import { Button as Button17 } from "@greatapps/greatauth-ui/ui";
|
|
3784
5263
|
import { Plus as Plus4 } from "lucide-react";
|
|
3785
|
-
import { jsx as
|
|
5264
|
+
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3786
5265
|
function ToolsPage({
|
|
3787
5266
|
config,
|
|
3788
5267
|
title = "Ferramentas",
|
|
3789
5268
|
subtitle = "Gerencie as ferramentas dispon\xEDveis para seus agentes"
|
|
3790
5269
|
}) {
|
|
3791
|
-
const [createOpen, setCreateOpen] =
|
|
3792
|
-
const [editTool, setEditTool] =
|
|
3793
|
-
return /* @__PURE__ */
|
|
3794
|
-
/* @__PURE__ */
|
|
3795
|
-
/* @__PURE__ */
|
|
3796
|
-
/* @__PURE__ */
|
|
3797
|
-
/* @__PURE__ */
|
|
5270
|
+
const [createOpen, setCreateOpen] = useState18(false);
|
|
5271
|
+
const [editTool, setEditTool] = useState18(void 0);
|
|
5272
|
+
return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5273
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between", children: [
|
|
5274
|
+
/* @__PURE__ */ jsxs25("div", { children: [
|
|
5275
|
+
/* @__PURE__ */ jsx27("h1", { className: "text-xl font-semibold", children: title }),
|
|
5276
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
3798
5277
|
] }),
|
|
3799
|
-
/* @__PURE__ */
|
|
3800
|
-
/* @__PURE__ */
|
|
5278
|
+
/* @__PURE__ */ jsxs25(Button17, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5279
|
+
/* @__PURE__ */ jsx27(Plus4, { className: "mr-2 h-4 w-4" }),
|
|
3801
5280
|
"Nova Ferramenta"
|
|
3802
5281
|
] })
|
|
3803
5282
|
] }),
|
|
3804
|
-
/* @__PURE__ */
|
|
3805
|
-
/* @__PURE__ */
|
|
5283
|
+
/* @__PURE__ */ jsx27(ToolsTable, { config, onEdit: (tool) => setEditTool(tool) }),
|
|
5284
|
+
/* @__PURE__ */ jsx27(
|
|
3806
5285
|
ToolFormDialog,
|
|
3807
5286
|
{
|
|
3808
5287
|
config,
|
|
@@ -3810,7 +5289,7 @@ function ToolsPage({
|
|
|
3810
5289
|
onOpenChange: setCreateOpen
|
|
3811
5290
|
}
|
|
3812
5291
|
),
|
|
3813
|
-
/* @__PURE__ */
|
|
5292
|
+
/* @__PURE__ */ jsx27(
|
|
3814
5293
|
ToolFormDialog,
|
|
3815
5294
|
{
|
|
3816
5295
|
config,
|
|
@@ -3823,10 +5302,10 @@ function ToolsPage({
|
|
|
3823
5302
|
}
|
|
3824
5303
|
|
|
3825
5304
|
// src/pages/credentials-page.tsx
|
|
3826
|
-
import { useState as
|
|
3827
|
-
import { Button as
|
|
5305
|
+
import { useState as useState19 } from "react";
|
|
5306
|
+
import { Button as Button18 } from "@greatapps/greatauth-ui/ui";
|
|
3828
5307
|
import { Plus as Plus5 } from "lucide-react";
|
|
3829
|
-
import { jsx as
|
|
5308
|
+
import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3830
5309
|
function CredentialsPage({
|
|
3831
5310
|
config,
|
|
3832
5311
|
gagentsApiUrl,
|
|
@@ -3834,20 +5313,20 @@ function CredentialsPage({
|
|
|
3834
5313
|
subtitle = "Gerencie as credenciais de autentica\xE7\xE3o das ferramentas"
|
|
3835
5314
|
}) {
|
|
3836
5315
|
const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
|
|
3837
|
-
const [createOpen, setCreateOpen] =
|
|
5316
|
+
const [createOpen, setCreateOpen] = useState19(false);
|
|
3838
5317
|
const credentials = credentialsData?.data || [];
|
|
3839
|
-
return /* @__PURE__ */
|
|
3840
|
-
/* @__PURE__ */
|
|
3841
|
-
/* @__PURE__ */
|
|
3842
|
-
/* @__PURE__ */
|
|
3843
|
-
/* @__PURE__ */
|
|
5318
|
+
return /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5319
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between", children: [
|
|
5320
|
+
/* @__PURE__ */ jsxs26("div", { children: [
|
|
5321
|
+
/* @__PURE__ */ jsx28("h1", { className: "text-xl font-semibold", children: title }),
|
|
5322
|
+
/* @__PURE__ */ jsx28("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
3844
5323
|
] }),
|
|
3845
|
-
/* @__PURE__ */
|
|
3846
|
-
/* @__PURE__ */
|
|
5324
|
+
/* @__PURE__ */ jsxs26(Button18, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5325
|
+
/* @__PURE__ */ jsx28(Plus5, { className: "mr-2 h-4 w-4" }),
|
|
3847
5326
|
"Nova Credencial"
|
|
3848
5327
|
] })
|
|
3849
5328
|
] }),
|
|
3850
|
-
/* @__PURE__ */
|
|
5329
|
+
/* @__PURE__ */ jsx28(
|
|
3851
5330
|
ToolCredentialsForm,
|
|
3852
5331
|
{
|
|
3853
5332
|
config,
|
|
@@ -3860,7 +5339,117 @@ function CredentialsPage({
|
|
|
3860
5339
|
)
|
|
3861
5340
|
] });
|
|
3862
5341
|
}
|
|
5342
|
+
|
|
5343
|
+
// src/pages/integrations-management-page.tsx
|
|
5344
|
+
import { useState as useState20, useMemo as useMemo8 } from "react";
|
|
5345
|
+
import {
|
|
5346
|
+
Badge as Badge11,
|
|
5347
|
+
Button as Button19,
|
|
5348
|
+
Tabs as Tabs3,
|
|
5349
|
+
TabsContent as TabsContent3,
|
|
5350
|
+
TabsList as TabsList3,
|
|
5351
|
+
TabsTrigger as TabsTrigger3
|
|
5352
|
+
} from "@greatapps/greatauth-ui/ui";
|
|
5353
|
+
import { Plus as Plus6, Plug as Plug4, KeyRound, Info as Info3 } from "lucide-react";
|
|
5354
|
+
import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5355
|
+
function useCredentialAgentSummary(credentials, tools, agents) {
|
|
5356
|
+
return useMemo8(() => {
|
|
5357
|
+
const toolIdsWithCredentials = new Set(
|
|
5358
|
+
credentials.map((c) => c.id_tool).filter(Boolean)
|
|
5359
|
+
);
|
|
5360
|
+
const linkedCount = credentials.filter(
|
|
5361
|
+
(c) => c.id_tool && toolIdsWithCredentials.has(c.id_tool)
|
|
5362
|
+
).length;
|
|
5363
|
+
return {
|
|
5364
|
+
totalCredentials: credentials.length,
|
|
5365
|
+
linkedToTools: linkedCount,
|
|
5366
|
+
totalAgents: agents.length,
|
|
5367
|
+
totalTools: tools.length
|
|
5368
|
+
};
|
|
5369
|
+
}, [credentials, tools, agents]);
|
|
5370
|
+
}
|
|
5371
|
+
function IntegrationsManagementPage({
|
|
5372
|
+
config,
|
|
5373
|
+
gagentsApiUrl,
|
|
5374
|
+
onConnect,
|
|
5375
|
+
title = "Integra\xE7\xF5es e Credenciais",
|
|
5376
|
+
subtitle = "Gerencie todas as integra\xE7\xF5es e credenciais da conta."
|
|
5377
|
+
}) {
|
|
5378
|
+
const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
|
|
5379
|
+
const { data: agentsData } = useAgents(config);
|
|
5380
|
+
const { data: toolsData } = useTools(config);
|
|
5381
|
+
const [createOpen, setCreateOpen] = useState20(false);
|
|
5382
|
+
const credentials = credentialsData?.data || [];
|
|
5383
|
+
const agents = agentsData?.data || [];
|
|
5384
|
+
const tools = toolsData?.data || [];
|
|
5385
|
+
const summary = useCredentialAgentSummary(credentials, tools, agents);
|
|
5386
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
|
|
5387
|
+
/* @__PURE__ */ jsx29("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs27("div", { children: [
|
|
5388
|
+
/* @__PURE__ */ jsx29("h1", { className: "text-xl font-semibold", children: title }),
|
|
5389
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: subtitle })
|
|
5390
|
+
] }) }),
|
|
5391
|
+
/* @__PURE__ */ jsxs27(Tabs3, { defaultValue: "integrations", className: "w-full", children: [
|
|
5392
|
+
/* @__PURE__ */ jsxs27(TabsList3, { children: [
|
|
5393
|
+
/* @__PURE__ */ jsxs27(TabsTrigger3, { value: "integrations", className: "gap-2", children: [
|
|
5394
|
+
/* @__PURE__ */ jsx29(Plug4, { className: "h-4 w-4" }),
|
|
5395
|
+
"Integra\xE7\xF5es"
|
|
5396
|
+
] }),
|
|
5397
|
+
/* @__PURE__ */ jsxs27(TabsTrigger3, { value: "credentials", className: "gap-2", children: [
|
|
5398
|
+
/* @__PURE__ */ jsx29(KeyRound, { className: "h-4 w-4" }),
|
|
5399
|
+
"Credenciais"
|
|
5400
|
+
] })
|
|
5401
|
+
] }),
|
|
5402
|
+
/* @__PURE__ */ jsx29(TabsContent3, { value: "integrations", className: "mt-4", children: /* @__PURE__ */ jsx29(
|
|
5403
|
+
IntegrationsTab,
|
|
5404
|
+
{
|
|
5405
|
+
config,
|
|
5406
|
+
agentId: null,
|
|
5407
|
+
onConnect: onConnect ?? (() => {
|
|
5408
|
+
})
|
|
5409
|
+
}
|
|
5410
|
+
) }),
|
|
5411
|
+
/* @__PURE__ */ jsxs27(TabsContent3, { value: "credentials", className: "mt-4", children: [
|
|
5412
|
+
!credentialsLoading && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-4 rounded-lg border bg-muted/50 px-4 py-3 mb-4", children: [
|
|
5413
|
+
/* @__PURE__ */ jsx29(Info3, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
|
|
5414
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex flex-wrap items-center gap-3 text-sm", children: [
|
|
5415
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
5416
|
+
/* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalCredentials }),
|
|
5417
|
+
summary.totalCredentials === 1 ? "credencial configurada" : "credenciais configuradas"
|
|
5418
|
+
] }),
|
|
5419
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
|
|
5420
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
5421
|
+
/* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.linkedToTools }),
|
|
5422
|
+
summary.linkedToTools === 1 ? "vinculada a ferramentas" : "vinculadas a ferramentas"
|
|
5423
|
+
] }),
|
|
5424
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
|
|
5425
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
5426
|
+
/* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalAgents }),
|
|
5427
|
+
summary.totalAgents === 1 ? "agente na conta" : "agentes na conta"
|
|
5428
|
+
] })
|
|
5429
|
+
] })
|
|
5430
|
+
] }),
|
|
5431
|
+
/* @__PURE__ */ jsx29("div", { className: "flex items-center justify-end mb-4", children: /* @__PURE__ */ jsxs27(Button19, { onClick: () => setCreateOpen(true), size: "sm", children: [
|
|
5432
|
+
/* @__PURE__ */ jsx29(Plus6, { className: "mr-2 h-4 w-4" }),
|
|
5433
|
+
"Nova Credencial"
|
|
5434
|
+
] }) }),
|
|
5435
|
+
/* @__PURE__ */ jsx29(
|
|
5436
|
+
ToolCredentialsForm,
|
|
5437
|
+
{
|
|
5438
|
+
config,
|
|
5439
|
+
gagentsApiUrl,
|
|
5440
|
+
credentials,
|
|
5441
|
+
isLoading: credentialsLoading,
|
|
5442
|
+
createOpen,
|
|
5443
|
+
onCreateOpenChange: setCreateOpen
|
|
5444
|
+
}
|
|
5445
|
+
)
|
|
5446
|
+
] })
|
|
5447
|
+
] })
|
|
5448
|
+
] });
|
|
5449
|
+
}
|
|
3863
5450
|
export {
|
|
5451
|
+
AdvancedTab,
|
|
5452
|
+
AgentCapabilitiesPage,
|
|
3864
5453
|
AgentConversationsPanel,
|
|
3865
5454
|
AgentConversationsTable,
|
|
3866
5455
|
AgentDetailPage,
|
|
@@ -3872,8 +5461,14 @@ export {
|
|
|
3872
5461
|
AgentToolsList,
|
|
3873
5462
|
AgentsPage,
|
|
3874
5463
|
AgentsTable,
|
|
5464
|
+
CapabilitiesTab,
|
|
3875
5465
|
ConversationView,
|
|
3876
5466
|
CredentialsPage,
|
|
5467
|
+
INTEGRATIONS_REGISTRY,
|
|
5468
|
+
IntegrationCard,
|
|
5469
|
+
IntegrationWizard,
|
|
5470
|
+
IntegrationsManagementPage,
|
|
5471
|
+
IntegrationsTab,
|
|
3877
5472
|
Sortable,
|
|
3878
5473
|
SortableContent,
|
|
3879
5474
|
SortableItem,
|
|
@@ -3887,9 +5482,11 @@ export {
|
|
|
3887
5482
|
createGagentsClient,
|
|
3888
5483
|
useAddAgentTool,
|
|
3889
5484
|
useAgent,
|
|
5485
|
+
useAgentCapabilities,
|
|
3890
5486
|
useAgentConversations,
|
|
3891
5487
|
useAgentTools,
|
|
3892
5488
|
useAgents,
|
|
5489
|
+
useCapabilities,
|
|
3893
5490
|
useContactUsers,
|
|
3894
5491
|
useConversation,
|
|
3895
5492
|
useConversations,
|
|
@@ -3903,6 +5500,7 @@ export {
|
|
|
3903
5500
|
useDeleteToolCredential,
|
|
3904
5501
|
useGagentsClient,
|
|
3905
5502
|
useGagentsContacts,
|
|
5503
|
+
useIntegrationState,
|
|
3906
5504
|
useObjectives,
|
|
3907
5505
|
usePromptVersions,
|
|
3908
5506
|
useRemoveAgentTool,
|
|
@@ -3910,6 +5508,7 @@ export {
|
|
|
3910
5508
|
useToolCredentials,
|
|
3911
5509
|
useTools,
|
|
3912
5510
|
useUpdateAgent,
|
|
5511
|
+
useUpdateAgentCapabilities,
|
|
3913
5512
|
useUpdateAgentTool,
|
|
3914
5513
|
useUpdateObjective,
|
|
3915
5514
|
useUpdateTool,
|