@greatapps/greatagents-ui 0.3.12 → 0.3.14
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 +50 -68
- package/dist/index.js +1956 -2315
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/agents/agent-tabs.tsx +41 -104
- package/src/components/capabilities/capabilities-tab.tsx +2 -2
- package/src/components/capabilities/integration-card.tsx +3 -21
- package/src/components/capabilities/integrations-tab.tsx +112 -68
- package/src/components/tools/tool-credentials-form.tsx +1 -374
- package/src/pages/agent-capabilities-page.tsx +2 -83
- package/src/pages/credentials-page.tsx +0 -10
- package/src/pages/integrations-management-page.tsx +129 -31
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo, useCallback, useState } from "react";
|
|
4
4
|
import { useToolCredentials, useAgents, useTools } from "../hooks";
|
|
5
5
|
import { ToolCredentialsForm } from "../components/tools/tool-credentials-form";
|
|
6
|
-
import {
|
|
6
|
+
import { IntegrationCard } from "../components/capabilities/integration-card";
|
|
7
|
+
import { IntegrationWizard } from "../components/capabilities/integration-wizard";
|
|
8
|
+
import { useIntegrationState, type IntegrationCardData } from "../hooks/use-integrations";
|
|
9
|
+
import type { WizardIntegrationMeta } from "../components/capabilities/types";
|
|
10
|
+
import type { ConfigOption } from "../components/capabilities/wizard-steps/config-step";
|
|
7
11
|
import {
|
|
8
12
|
Badge,
|
|
9
13
|
Button,
|
|
@@ -12,28 +16,25 @@ import {
|
|
|
12
16
|
TabsList,
|
|
13
17
|
TabsTrigger,
|
|
14
18
|
} from "@greatapps/greatauth-ui/ui";
|
|
15
|
-
import {
|
|
19
|
+
import { Plug, KeyRound, Info, Loader2 } from "lucide-react";
|
|
16
20
|
import type { GagentsHookConfig } from "../hooks/types";
|
|
17
|
-
import type { IntegrationCardData } from "../hooks/use-integrations";
|
|
18
21
|
import type { Agent, Tool, ToolCredential } from "../types";
|
|
19
22
|
|
|
20
23
|
export interface IntegrationsManagementPageProps {
|
|
21
24
|
config: GagentsHookConfig;
|
|
22
25
|
gagentsApiUrl: string;
|
|
23
|
-
/**
|
|
24
|
-
|
|
26
|
+
/** Resolve wizard metadata for a given integration card. */
|
|
27
|
+
resolveWizardMeta?: (card: IntegrationCardData) => WizardIntegrationMeta;
|
|
28
|
+
/** Load config options after OAuth completes (e.g. list of calendars). */
|
|
29
|
+
loadConfigOptions?: (credentialId: number) => Promise<ConfigOption[]>;
|
|
30
|
+
/** Called after wizard completes successfully. */
|
|
31
|
+
onWizardComplete?: () => void;
|
|
25
32
|
title?: string;
|
|
26
33
|
subtitle?: string;
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
/**
|
|
30
|
-
* Build a map of credential id
|
|
31
|
-
* Cross-references tools (which link credential via id) with agents
|
|
32
|
-
* that have agent_tools referencing those tools.
|
|
33
|
-
*
|
|
34
|
-
* Since we don't have an account-level agent_tools endpoint, we
|
|
35
|
-
* approximate by checking which tools are linked to credentials and
|
|
36
|
-
* showing credential-level stats.
|
|
37
|
+
* Build a map of credential id -> list of agent names that use it.
|
|
37
38
|
*/
|
|
38
39
|
function useCredentialAgentSummary(
|
|
39
40
|
credentials: ToolCredential[],
|
|
@@ -41,12 +42,10 @@ function useCredentialAgentSummary(
|
|
|
41
42
|
agents: Agent[],
|
|
42
43
|
) {
|
|
43
44
|
return useMemo(() => {
|
|
44
|
-
// Build a set of tool IDs that have credentials
|
|
45
45
|
const toolIdsWithCredentials = new Set(
|
|
46
46
|
credentials.map((c) => c.id_tool).filter(Boolean),
|
|
47
47
|
);
|
|
48
48
|
|
|
49
|
-
// Count how many credentials are linked to tools that agents could use
|
|
50
49
|
const linkedCount = credentials.filter(
|
|
51
50
|
(c) => c.id_tool && toolIdsWithCredentials.has(c.id_tool),
|
|
52
51
|
).length;
|
|
@@ -63,7 +62,9 @@ function useCredentialAgentSummary(
|
|
|
63
62
|
export function IntegrationsManagementPage({
|
|
64
63
|
config,
|
|
65
64
|
gagentsApiUrl,
|
|
66
|
-
|
|
65
|
+
resolveWizardMeta,
|
|
66
|
+
loadConfigOptions,
|
|
67
|
+
onWizardComplete,
|
|
67
68
|
title = "Integrações e Credenciais",
|
|
68
69
|
subtitle = "Gerencie todas as integrações e credenciais da conta.",
|
|
69
70
|
}: IntegrationsManagementPageProps) {
|
|
@@ -71,7 +72,12 @@ export function IntegrationsManagementPage({
|
|
|
71
72
|
useToolCredentials(config);
|
|
72
73
|
const { data: agentsData } = useAgents(config);
|
|
73
74
|
const { data: toolsData } = useTools(config);
|
|
74
|
-
|
|
75
|
+
// Integration cards state (account-level, agentId=null)
|
|
76
|
+
const { cards, isLoading: cardsLoading } = useIntegrationState(config, null);
|
|
77
|
+
|
|
78
|
+
// Wizard state
|
|
79
|
+
const [wizardOpen, setWizardOpen] = useState(false);
|
|
80
|
+
const [activeCard, setActiveCard] = useState<IntegrationCardData | null>(null);
|
|
75
81
|
|
|
76
82
|
const credentials = credentialsData?.data || [];
|
|
77
83
|
const agents: Agent[] = agentsData?.data || [];
|
|
@@ -79,6 +85,41 @@ export function IntegrationsManagementPage({
|
|
|
79
85
|
|
|
80
86
|
const summary = useCredentialAgentSummary(credentials, tools, agents);
|
|
81
87
|
|
|
88
|
+
const handleConnect = useCallback((card: IntegrationCardData) => {
|
|
89
|
+
setActiveCard(card);
|
|
90
|
+
setWizardOpen(true);
|
|
91
|
+
}, []);
|
|
92
|
+
|
|
93
|
+
const handleWizardClose = useCallback((open: boolean) => {
|
|
94
|
+
if (!open) {
|
|
95
|
+
setActiveCard(null);
|
|
96
|
+
}
|
|
97
|
+
setWizardOpen(open);
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
const handleWizardComplete = useCallback(() => {
|
|
101
|
+
setWizardOpen(false);
|
|
102
|
+
setActiveCard(null);
|
|
103
|
+
onWizardComplete?.();
|
|
104
|
+
}, [onWizardComplete]);
|
|
105
|
+
|
|
106
|
+
// Resolve wizard meta with sensible defaults
|
|
107
|
+
const wizardMeta: WizardIntegrationMeta | null = activeCard
|
|
108
|
+
? (resolveWizardMeta?.(activeCard) ?? {
|
|
109
|
+
capabilities: [],
|
|
110
|
+
requirements: [],
|
|
111
|
+
hasConfigStep: false,
|
|
112
|
+
})
|
|
113
|
+
: null;
|
|
114
|
+
|
|
115
|
+
// Split integration cards
|
|
116
|
+
const connectedCards = cards.filter(
|
|
117
|
+
(c) => !c.isAddNew && (c.state === "connected" || c.state === "expired"),
|
|
118
|
+
);
|
|
119
|
+
const otherCards = cards.filter(
|
|
120
|
+
(c) => c.isAddNew || c.state === "coming_soon",
|
|
121
|
+
);
|
|
122
|
+
|
|
82
123
|
return (
|
|
83
124
|
<div className="flex flex-col gap-4 p-4 md:p-6">
|
|
84
125
|
<div className="flex items-center justify-between">
|
|
@@ -101,11 +142,61 @@ export function IntegrationsManagementPage({
|
|
|
101
142
|
</TabsList>
|
|
102
143
|
|
|
103
144
|
<TabsContent value="integrations" className="mt-4">
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
145
|
+
{cardsLoading ? (
|
|
146
|
+
<div className="flex items-center justify-center py-16">
|
|
147
|
+
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
|
|
148
|
+
</div>
|
|
149
|
+
) : cards.length === 0 ? (
|
|
150
|
+
<div className="flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground">
|
|
151
|
+
<Plug className="h-10 w-10" />
|
|
152
|
+
<p className="text-sm">Nenhuma integração disponível</p>
|
|
153
|
+
</div>
|
|
154
|
+
) : (
|
|
155
|
+
<div className="space-y-6">
|
|
156
|
+
{/* Connected accounts */}
|
|
157
|
+
{connectedCards.length > 0 && (
|
|
158
|
+
<div>
|
|
159
|
+
<h3 className="mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground">
|
|
160
|
+
Contas conectadas
|
|
161
|
+
</h3>
|
|
162
|
+
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
163
|
+
{connectedCards.map((card) => (
|
|
164
|
+
<IntegrationCard
|
|
165
|
+
key={`${card.definition.slug}-cred-${card.credentialId}`}
|
|
166
|
+
card={card}
|
|
167
|
+
onConnect={handleConnect}
|
|
168
|
+
/>
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
)}
|
|
173
|
+
|
|
174
|
+
{/* Add new / coming soon */}
|
|
175
|
+
{otherCards.length > 0 && (
|
|
176
|
+
<div>
|
|
177
|
+
{connectedCards.length > 0 && (
|
|
178
|
+
<h3 className="mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground">
|
|
179
|
+
Adicionar integração
|
|
180
|
+
</h3>
|
|
181
|
+
)}
|
|
182
|
+
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
183
|
+
{otherCards.map((card) => {
|
|
184
|
+
const key = card.isAddNew
|
|
185
|
+
? `${card.definition.slug}-add-new`
|
|
186
|
+
: card.definition.slug;
|
|
187
|
+
return (
|
|
188
|
+
<IntegrationCard
|
|
189
|
+
key={key}
|
|
190
|
+
card={card}
|
|
191
|
+
onConnect={handleConnect}
|
|
192
|
+
/>
|
|
193
|
+
);
|
|
194
|
+
})}
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
)}
|
|
198
|
+
</div>
|
|
199
|
+
)}
|
|
109
200
|
</TabsContent>
|
|
110
201
|
|
|
111
202
|
<TabsContent value="credentials" className="mt-4">
|
|
@@ -144,23 +235,30 @@ export function IntegrationsManagementPage({
|
|
|
144
235
|
</div>
|
|
145
236
|
)}
|
|
146
237
|
|
|
147
|
-
<div className="flex items-center justify-end mb-4">
|
|
148
|
-
<Button onClick={() => setCreateOpen(true)} size="sm">
|
|
149
|
-
<Plus className="mr-2 h-4 w-4" />
|
|
150
|
-
Nova Credencial
|
|
151
|
-
</Button>
|
|
152
|
-
</div>
|
|
153
|
-
|
|
154
238
|
<ToolCredentialsForm
|
|
155
239
|
config={config}
|
|
156
240
|
gagentsApiUrl={gagentsApiUrl}
|
|
157
241
|
credentials={credentials}
|
|
158
242
|
isLoading={credentialsLoading}
|
|
159
|
-
createOpen={createOpen}
|
|
160
|
-
onCreateOpenChange={setCreateOpen}
|
|
161
243
|
/>
|
|
162
244
|
</TabsContent>
|
|
163
245
|
</Tabs>
|
|
246
|
+
|
|
247
|
+
{/* Integration Wizard */}
|
|
248
|
+
{activeCard && wizardMeta && (
|
|
249
|
+
<IntegrationWizard
|
|
250
|
+
open={wizardOpen}
|
|
251
|
+
onOpenChange={handleWizardClose}
|
|
252
|
+
integration={activeCard.definition}
|
|
253
|
+
meta={wizardMeta}
|
|
254
|
+
agentId={0}
|
|
255
|
+
config={config}
|
|
256
|
+
gagentsApiUrl={gagentsApiUrl}
|
|
257
|
+
existingCredentialId={activeCard.credentialId}
|
|
258
|
+
onComplete={handleWizardComplete}
|
|
259
|
+
loadConfigOptions={loadConfigOptions}
|
|
260
|
+
/>
|
|
261
|
+
)}
|
|
164
262
|
</div>
|
|
165
263
|
);
|
|
166
264
|
}
|