mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor(site): convert archive agent callbacks to React Query mutations (#22542)
This commit is contained in:
@@ -876,10 +876,10 @@ const AgentDetail: FC = () => {
|
||||
};
|
||||
|
||||
const handleArchiveAndDeleteWorkspaceAction = () => {
|
||||
if (!agentId || isArchived) {
|
||||
if (!agentId || isArchived || !workspaceId) {
|
||||
return;
|
||||
}
|
||||
requestArchiveAndDeleteWorkspace(agentId);
|
||||
requestArchiveAndDeleteWorkspace(agentId, workspaceId);
|
||||
};
|
||||
|
||||
if (chatQuery.isLoading) {
|
||||
|
||||
@@ -88,7 +88,10 @@ export interface AgentsOutletContext {
|
||||
setChatErrorReason: (chatId: string, reason: string) => void;
|
||||
clearChatErrorReason: (chatId: string) => void;
|
||||
requestArchiveAgent: (chatId: string) => void;
|
||||
requestArchiveAndDeleteWorkspace: (chatId: string) => void;
|
||||
requestArchiveAndDeleteWorkspace: (
|
||||
chatId: string,
|
||||
workspaceId: string,
|
||||
) => void;
|
||||
isSidebarCollapsed: boolean;
|
||||
onToggleSidebarCollapsed: () => void;
|
||||
}
|
||||
@@ -151,11 +154,40 @@ const AgentsPage: FC = () => {
|
||||
const chatModelsQuery = useQuery(chatModels());
|
||||
const chatModelConfigsQuery = useQuery(chatModelConfigs());
|
||||
const createMutation = useMutation(createChat(queryClient));
|
||||
const archiveMutation = useMutation(archiveChat(queryClient));
|
||||
const deleteWorkspaceMutation = useMutation({
|
||||
mutationFn: (workspaceId: string) => API.deleteWorkspace(workspaceId),
|
||||
const archiveAgentMutation = useMutation({
|
||||
...archiveChat(queryClient),
|
||||
onSuccess: async (_data, chatId) => {
|
||||
clearChatErrorReason(chatId);
|
||||
await queryClient.invalidateQueries({ queryKey: chatKey(chatId) });
|
||||
toast.success("Agent archived.");
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(getErrorMessage(error, "Failed to archive agent."));
|
||||
},
|
||||
});
|
||||
const archiveAndDeleteMutation = useMutation({
|
||||
mutationFn: async ({
|
||||
chatId,
|
||||
workspaceId,
|
||||
}: {
|
||||
chatId: string;
|
||||
workspaceId: string;
|
||||
}) => {
|
||||
await API.archiveChat(chatId);
|
||||
await API.deleteWorkspace(workspaceId);
|
||||
return { chatId, workspaceId };
|
||||
},
|
||||
onSuccess: async ({ chatId }) => {
|
||||
clearChatErrorReason(chatId);
|
||||
await queryClient.invalidateQueries({ queryKey: chatsKey });
|
||||
await queryClient.invalidateQueries({ queryKey: chatKey(chatId) });
|
||||
toast.success("Agent archived.");
|
||||
toast.success("Workspace deletion initiated.");
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(getErrorMessage(error, "Failed to archive agent."));
|
||||
},
|
||||
});
|
||||
const [archivingChatId, setArchivingChatId] = useState<string | null>(null);
|
||||
|
||||
const [isConfigureAgentsDialogOpen, setConfigureAgentsDialogOpen] =
|
||||
useState(false);
|
||||
@@ -219,64 +251,30 @@ const AgentsPage: FC = () => {
|
||||
});
|
||||
}, []);
|
||||
const chatList = chatsQuery.data ?? [];
|
||||
const isArchiving =
|
||||
archiveAgentMutation.isPending || archiveAndDeleteMutation.isPending;
|
||||
const archivingChatId =
|
||||
(archiveAgentMutation.isPending
|
||||
? archiveAgentMutation.variables
|
||||
: undefined) ??
|
||||
(archiveAndDeleteMutation.isPending
|
||||
? archiveAndDeleteMutation.variables?.chatId
|
||||
: undefined);
|
||||
const requestArchiveAgent = useCallback(
|
||||
async (chatId: string) => {
|
||||
if (archiveMutation.isPending) {
|
||||
return;
|
||||
}
|
||||
|
||||
setArchivingChatId(chatId);
|
||||
|
||||
try {
|
||||
await archiveMutation.mutateAsync(chatId);
|
||||
clearChatErrorReason(chatId);
|
||||
await queryClient.invalidateQueries({ queryKey: chatKey(chatId) });
|
||||
toast.success("Agent archived.");
|
||||
} catch (error) {
|
||||
toast.error(getErrorMessage(error, "Failed to archive agent."));
|
||||
} finally {
|
||||
setArchivingChatId(null);
|
||||
(chatId: string) => {
|
||||
if (!isArchiving) {
|
||||
archiveAgentMutation.mutate(chatId);
|
||||
}
|
||||
},
|
||||
[archiveMutation, queryClient, clearChatErrorReason],
|
||||
[isArchiving, archiveAgentMutation],
|
||||
);
|
||||
const requestArchiveAndDeleteWorkspace = useCallback(
|
||||
async (chatId: string) => {
|
||||
if (archiveMutation.isPending || deleteWorkspaceMutation.isPending) {
|
||||
return;
|
||||
}
|
||||
|
||||
setArchivingChatId(chatId);
|
||||
|
||||
try {
|
||||
await archiveMutation.mutateAsync(chatId);
|
||||
clearChatErrorReason(chatId);
|
||||
await queryClient.invalidateQueries({ queryKey: chatKey(chatId) });
|
||||
toast.success("Agent archived.");
|
||||
} catch (error) {
|
||||
toast.error(getErrorMessage(error, "Failed to archive agent."));
|
||||
return;
|
||||
} finally {
|
||||
setArchivingChatId(null);
|
||||
}
|
||||
|
||||
const chat = chatList.find((c) => c.id === chatId);
|
||||
if (chat?.workspace_id) {
|
||||
try {
|
||||
await deleteWorkspaceMutation.mutateAsync(chat.workspace_id);
|
||||
toast.success("Workspace deletion initiated.");
|
||||
} catch (error) {
|
||||
toast.error(getErrorMessage(error, "Failed to delete workspace."));
|
||||
}
|
||||
(chatId: string, workspaceId: string) => {
|
||||
if (!isArchiving) {
|
||||
archiveAndDeleteMutation.mutate({ chatId, workspaceId });
|
||||
}
|
||||
},
|
||||
[
|
||||
archiveMutation,
|
||||
deleteWorkspaceMutation,
|
||||
queryClient,
|
||||
clearChatErrorReason,
|
||||
chatList,
|
||||
],
|
||||
[isArchiving, archiveAndDeleteMutation],
|
||||
);
|
||||
const handleToggleSidebarCollapsed = useCallback(
|
||||
() => setIsSidebarCollapsed((prev) => !prev),
|
||||
@@ -457,7 +455,7 @@ const AgentsPage: FC = () => {
|
||||
onArchiveAndDeleteWorkspace={requestArchiveAndDeleteWorkspace}
|
||||
onNewAgent={handleNewAgent}
|
||||
isCreating={createMutation.isPending}
|
||||
isArchiving={archiveMutation.isPending}
|
||||
isArchiving={isArchiving}
|
||||
archivingChatId={archivingChatId}
|
||||
isLoading={chatsQuery.isLoading}
|
||||
loadError={chatsQuery.isError ? chatsQuery.error : undefined}
|
||||
|
||||
@@ -52,7 +52,7 @@ interface AgentsSidebarProps {
|
||||
modelConfigs: readonly ChatModelConfig[];
|
||||
logoUrl?: string;
|
||||
onArchiveAgent: (chatId: string) => void;
|
||||
onArchiveAndDeleteWorkspace: (chatId: string) => void;
|
||||
onArchiveAndDeleteWorkspace: (chatId: string, workspaceId: string) => void;
|
||||
onNewAgent: () => void;
|
||||
isCreating: boolean;
|
||||
isArchiving?: boolean;
|
||||
@@ -266,7 +266,10 @@ interface ChatTreeContextValue {
|
||||
readonly archivingChatId: string | null;
|
||||
readonly toggleExpanded: (chatID: string) => void;
|
||||
readonly onArchiveAgent: (chatId: string) => void;
|
||||
readonly onArchiveAndDeleteWorkspace: (chatId: string) => void;
|
||||
readonly onArchiveAndDeleteWorkspace: (
|
||||
chatId: string,
|
||||
workspaceId: string,
|
||||
) => void;
|
||||
}
|
||||
|
||||
const ChatTreeContext = createContext<ChatTreeContextValue | null>(null);
|
||||
@@ -329,6 +332,7 @@ const ChatTreeNode = memo<ChatTreeNodeProps>(({ chat, isChildNode }) => {
|
||||
const filesChangedLabel = `${changedFiles} ${
|
||||
changedFiles === 1 ? "file" : "files"
|
||||
}`;
|
||||
const workspaceId = chat.workspace_id;
|
||||
const isArchivingThisChat = isArchiving && archivingChatId === chat.id;
|
||||
const isExpanded = normalizedSearch ? true : (expandedById[chatID] ?? false);
|
||||
const isExecuting =
|
||||
@@ -473,12 +477,15 @@ const ChatTreeNode = memo<ChatTreeNodeProps>(({ chat, isChildNode }) => {
|
||||
<ArchiveIcon className="h-3.5 w-3.5" />
|
||||
Archive agent
|
||||
</DropdownMenuItem>
|
||||
{chat.workspace_id && (
|
||||
{workspaceId && (
|
||||
<DropdownMenuItem
|
||||
className="text-content-destructive focus:text-content-destructive"
|
||||
disabled={isArchiving}
|
||||
onSelect={() => onArchiveAndDeleteWorkspace(chat.id)}
|
||||
onSelect={() =>
|
||||
onArchiveAndDeleteWorkspace(chat.id, workspaceId)
|
||||
}
|
||||
>
|
||||
{" "}
|
||||
<Trash2Icon className="h-3.5 w-3.5" />
|
||||
Archive & delete workspace
|
||||
</DropdownMenuItem>
|
||||
|
||||
Reference in New Issue
Block a user