@greatapps/greatagents-ui 0.3.26 → 0.3.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/greatagents-ui",
3
- "version": "0.3.26",
3
+ "version": "0.3.27",
4
4
  "description": "Shared agents UI components for Great platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -250,6 +250,26 @@ export function createGagentsClient(config: GagentsClientConfig) {
250
250
  { provider },
251
251
  ),
252
252
 
253
+ // --- Publish ---
254
+ publishAgent: async (
255
+ idAccount: number,
256
+ agentId: number,
257
+ changeNotes?: string,
258
+ ): Promise<ApiResponse<{ version: number }>> => {
259
+ const url = buildUrl(idAccount, `agents/${agentId}/publish`);
260
+ const res = await fetch(url, {
261
+ method: "POST",
262
+ headers: {
263
+ Authorization: `Bearer ${token}`,
264
+ "Content-Type": "application/json",
265
+ },
266
+ body: JSON.stringify({ change_notes: changeNotes || "" }),
267
+ });
268
+ const json = (await res.json()) as ApiResponse<{ version: number }>;
269
+ if (json.status === 0 && !res.ok) throw new Error(json.message || "Erro ao publicar");
270
+ return json;
271
+ },
272
+
253
273
  // --- Capabilities ---
254
274
  getCapabilities: (idAccount: number) =>
255
275
  request<CapabilitiesResponse>("GET", idAccount, "capabilities"),
@@ -2,7 +2,7 @@
2
2
  export { type GagentsHookConfig, useGagentsClient } from "./types";
3
3
 
4
4
  // Agents
5
- export { useAgents, useAgent, useCreateAgent, useUpdateAgent, useDeleteAgent } from "./use-agents";
5
+ export { useAgents, useAgent, useCreateAgent, useUpdateAgent, usePublishAgent, useDeleteAgent } from "./use-agents";
6
6
 
7
7
  // Tools
8
8
  export { useTools, useTool, useCreateTool, useUpdateTool, useDeleteTool } from "./use-tools";
@@ -81,6 +81,26 @@ export function useUpdateAgent(config: GagentsHookConfig) {
81
81
  });
82
82
  }
83
83
 
84
+ export function usePublishAgent(config: GagentsHookConfig) {
85
+ const queryClient = useQueryClient();
86
+ const client = useGagentsClient(config);
87
+
88
+ return useMutation({
89
+ mutationFn: async (variables: { id: number; changeNotes?: string }) => {
90
+ return client.publishAgent(Number(config.accountId), variables.id, variables.changeNotes);
91
+ },
92
+ onSuccess: (_data, variables) => {
93
+ queryClient.invalidateQueries({ queryKey: ["greatagents", "agents"] });
94
+ queryClient.invalidateQueries({
95
+ queryKey: ["greatagents", "agent", config.accountId, variables.id],
96
+ });
97
+ queryClient.invalidateQueries({
98
+ queryKey: ["greatagents", "prompt-versions", config.accountId, variables.id],
99
+ });
100
+ },
101
+ });
102
+ }
103
+
84
104
  export function useDeleteAgent(config: GagentsHookConfig) {
85
105
  const client = useGagentsClient(config);
86
106
  const queryClient = useQueryClient();
@@ -1,10 +1,24 @@
1
1
  import { useState } from "react";
2
- import { useAgent } from "../hooks";
2
+ import { useAgent, usePublishAgent } from "../hooks";
3
3
  import { AgentTabs } from "../components/agents/agent-tabs";
4
4
  import { AgentEditForm } from "../components/agents/agent-edit-form";
5
- import { Badge, Button, Skeleton } from "@greatapps/greatauth-ui/ui";
5
+ import {
6
+ AlertDialog,
7
+ AlertDialogAction,
8
+ AlertDialogCancel,
9
+ AlertDialogContent,
10
+ AlertDialogDescription,
11
+ AlertDialogFooter,
12
+ AlertDialogHeader,
13
+ AlertDialogTitle,
14
+ Badge,
15
+ Button,
16
+ Input,
17
+ Skeleton,
18
+ } from "@greatapps/greatauth-ui/ui";
6
19
  import { EntityAvatar } from "@greatapps/greatauth-ui";
7
- import { ArrowLeft, Pencil } from "lucide-react";
20
+ import { ArrowLeft, Loader2, Pencil, Upload } from "lucide-react";
21
+ import { toast } from "sonner";
8
22
  import type { GagentsHookConfig } from "../hooks/types";
9
23
 
10
24
  export interface AgentDetailPageProps {
@@ -21,7 +35,26 @@ export function AgentDetailPage({
21
35
  renderChatLink,
22
36
  }: AgentDetailPageProps) {
23
37
  const { data: agent, isLoading } = useAgent(config, agentId);
38
+ const publishAgent = usePublishAgent(config);
24
39
  const [editOpen, setEditOpen] = useState(false);
40
+ const [publishOpen, setPublishOpen] = useState(false);
41
+ const [publishNotes, setPublishNotes] = useState("");
42
+
43
+ async function handlePublish() {
44
+ if (!agent) return;
45
+ try {
46
+ const result = await publishAgent.mutateAsync({ id: agent.id, changeNotes: publishNotes.trim() });
47
+ setPublishOpen(false);
48
+ setPublishNotes("");
49
+ if (result.message?.includes("Sem alterações")) {
50
+ toast.info(result.message);
51
+ } else {
52
+ toast.success(result.message || "Agente publicado");
53
+ }
54
+ } catch (err) {
55
+ toast.error(err instanceof Error ? err.message : "Erro ao publicar agente");
56
+ }
57
+ }
25
58
 
26
59
  if (isLoading) {
27
60
  return (
@@ -80,15 +113,29 @@ export function AgentDetailPage({
80
113
  </div>
81
114
  </div>
82
115
 
83
- <Button
84
- variant="outline"
85
- size="sm"
86
- className="shrink-0 self-start"
87
- onClick={() => setEditOpen(true)}
88
- >
89
- <Pencil className="mr-2 h-4 w-4" />
90
- Editar
91
- </Button>
116
+ <div className="flex gap-2 shrink-0 self-start">
117
+ <Button
118
+ variant="default"
119
+ size="sm"
120
+ onClick={() => setPublishOpen(true)}
121
+ disabled={publishAgent.isPending}
122
+ >
123
+ {publishAgent.isPending ? (
124
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
125
+ ) : (
126
+ <Upload className="mr-2 h-4 w-4" />
127
+ )}
128
+ Publicar
129
+ </Button>
130
+ <Button
131
+ variant="outline"
132
+ size="sm"
133
+ onClick={() => setEditOpen(true)}
134
+ >
135
+ <Pencil className="mr-2 h-4 w-4" />
136
+ Editar
137
+ </Button>
138
+ </div>
92
139
  </div>
93
140
  </div>
94
141
 
@@ -107,6 +154,37 @@ export function AgentDetailPage({
107
154
  onOpenChange={setEditOpen}
108
155
  />
109
156
  )}
157
+
158
+ <AlertDialog open={publishOpen} onOpenChange={setPublishOpen}>
159
+ <AlertDialogContent>
160
+ <AlertDialogHeader>
161
+ <AlertDialogTitle>Publicar nova versão do agente?</AlertDialogTitle>
162
+ <AlertDialogDescription>
163
+ O prompt será actualizado com todas as configurações actuais e uma nova versão será criada.
164
+ </AlertDialogDescription>
165
+ </AlertDialogHeader>
166
+ <div className="py-2">
167
+ <Input
168
+ value={publishNotes}
169
+ onChange={(e) => setPublishNotes(e.target.value)}
170
+ placeholder="O que mudou? (opcional)"
171
+ onKeyDown={(e) => {
172
+ if (e.key === "Enter") {
173
+ e.preventDefault();
174
+ handlePublish();
175
+ }
176
+ }}
177
+ />
178
+ </div>
179
+ <AlertDialogFooter>
180
+ <AlertDialogCancel onClick={() => { setPublishNotes(""); }}>Cancelar</AlertDialogCancel>
181
+ <AlertDialogAction onClick={handlePublish} disabled={publishAgent.isPending}>
182
+ {publishAgent.isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
183
+ Publicar
184
+ </AlertDialogAction>
185
+ </AlertDialogFooter>
186
+ </AlertDialogContent>
187
+ </AlertDialog>
110
188
  </div>
111
189
  );
112
190
  }