From 44096b0e4408a1738a788da719009c574d66be02 Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 9 Mar 2026 15:00:30 +0800 Subject: [PATCH] refactor: remove backup path display from OpenClaw save toasts Backup paths are internal implementation details not actionable by users. Simplify toast notifications to show only success/failure messages. --- .../openclaw/AgentsDefaultsPanel.tsx | 11 +---- src/components/openclaw/EnvPanel.tsx | 11 +---- src/components/openclaw/ToolsPanel.tsx | 11 +---- src/hooks/useProviderActions.ts | 12 +----- tests/hooks/useProviderActions.test.tsx | 43 +++++++++++++++++++ 5 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/components/openclaw/AgentsDefaultsPanel.tsx b/src/components/openclaw/AgentsDefaultsPanel.tsx index 45b97999..2a334a5c 100644 --- a/src/components/openclaw/AgentsDefaultsPanel.tsx +++ b/src/components/openclaw/AgentsDefaultsPanel.tsx @@ -169,15 +169,8 @@ const AgentsDefaultsPanel: React.FC = () => { if (concNum !== undefined) updated.maxConcurrent = concNum; else delete updated.maxConcurrent; - const outcome = await saveAgentsMutation.mutateAsync(updated); - toast.success(t("openclaw.agents.saveSuccess"), { - description: outcome.backupPath - ? t("openclaw.backupCreated", { - path: outcome.backupPath, - defaultValue: "Backup created: {{path}}", - }) - : undefined, - }); + await saveAgentsMutation.mutateAsync(updated); + toast.success(t("openclaw.agents.saveSuccess")); } catch (error) { const detail = extractErrorMessage(error); toast.error(t("openclaw.agents.saveFailed"), { diff --git a/src/components/openclaw/EnvPanel.tsx b/src/components/openclaw/EnvPanel.tsx index e08aa7fe..3137c38b 100644 --- a/src/components/openclaw/EnvPanel.tsx +++ b/src/components/openclaw/EnvPanel.tsx @@ -41,15 +41,8 @@ const EnvPanel: React.FC = () => { const handleSave = async () => { try { const env = parseOpenClawEnvEditorValue(editorValue); - const outcome = await saveEnvMutation.mutateAsync(env); - toast.success(t("openclaw.env.saveSuccess"), { - description: outcome.backupPath - ? t("openclaw.backupCreated", { - path: outcome.backupPath, - defaultValue: "Backup created: {{path}}", - }) - : undefined, - }); + await saveEnvMutation.mutateAsync(env); + toast.success(t("openclaw.env.saveSuccess")); } catch (error) { const detail = extractErrorMessage(error); let description = detail || undefined; diff --git a/src/components/openclaw/ToolsPanel.tsx b/src/components/openclaw/ToolsPanel.tsx index daecf4b9..65b1f462 100644 --- a/src/components/openclaw/ToolsPanel.tsx +++ b/src/components/openclaw/ToolsPanel.tsx @@ -85,15 +85,8 @@ const ToolsPanel: React.FC = () => { deny: denyList.map((item) => item.value).filter((s) => s.trim()), }; - const outcome = await saveToolsMutation.mutateAsync(newConfig); - toast.success(t("openclaw.tools.saveSuccess"), { - description: outcome.backupPath - ? t("openclaw.backupCreated", { - path: outcome.backupPath, - defaultValue: "Backup created: {{path}}", - }) - : undefined, - }); + await saveToolsMutation.mutateAsync(newConfig); + toast.success(t("openclaw.tools.saveSuccess")); } catch (error) { const detail = extractErrorMessage(error); toast.error(t("openclaw.tools.saveFailed"), { diff --git a/src/hooks/useProviderActions.ts b/src/hooks/useProviderActions.ts index b5ce2bcd..bc11722d 100644 --- a/src/hooks/useProviderActions.ts +++ b/src/hooks/useProviderActions.ts @@ -261,7 +261,7 @@ export function useProviderActions(activeApp: AppId) { }; try { - const outcome = await openclawApi.setDefaultModel(model); + await openclawApi.setDefaultModel(model); await queryClient.invalidateQueries({ queryKey: openclawKeys.defaultModel, }); @@ -272,15 +272,7 @@ export function useProviderActions(activeApp: AppId) { t("notifications.openclawDefaultModelSet", { defaultValue: "已设为默认模型", }), - { - closeButton: true, - description: outcome.backupPath - ? t("openclaw.backupCreated", { - path: outcome.backupPath, - defaultValue: "Backup created: {{path}}", - }) - : undefined, - }, + { closeButton: true }, ); } catch (error) { const detail = diff --git a/tests/hooks/useProviderActions.test.tsx b/tests/hooks/useProviderActions.test.tsx index b02226ba..5f447326 100644 --- a/tests/hooks/useProviderActions.test.tsx +++ b/tests/hooks/useProviderActions.test.tsx @@ -53,6 +53,9 @@ const providersApiUpdateMock = vi.fn(); const providersApiUpdateTrayMenuMock = vi.fn(); const settingsApiGetMock = vi.fn(); const settingsApiApplyMock = vi.fn(); +const openclawApiGetModelCatalogMock = vi.fn(); +const openclawApiGetDefaultModelMock = vi.fn(); +const openclawApiSetDefaultModelMock = vi.fn(); vi.mock("@/lib/api", () => ({ providersApi: { @@ -65,6 +68,14 @@ vi.mock("@/lib/api", () => ({ applyClaudePluginConfig: (...args: unknown[]) => settingsApiApplyMock(...args), }, + openclawApi: { + getModelCatalog: (...args: unknown[]) => + openclawApiGetModelCatalogMock(...args), + getDefaultModel: (...args: unknown[]) => + openclawApiGetDefaultModelMock(...args), + setDefaultModel: (...args: unknown[]) => + openclawApiSetDefaultModelMock(...args), + }, })); interface WrapperProps { @@ -100,6 +111,9 @@ beforeEach(() => { providersApiUpdateTrayMenuMock.mockReset(); settingsApiGetMock.mockReset(); settingsApiApplyMock.mockReset(); + openclawApiGetModelCatalogMock.mockReset(); + openclawApiGetDefaultModelMock.mockReset(); + openclawApiSetDefaultModelMock.mockReset(); toastSuccessMock.mockReset(); toastErrorMock.mockReset(); @@ -450,6 +464,35 @@ describe("useProviderActions", () => { expect(result.current.isLoading).toBe(true); }); + + it("does not show backup details when setting OpenClaw default model", async () => { + openclawApiSetDefaultModelMock.mockResolvedValueOnce({ + backupPath: "/tmp/openclaw-backup.json5", + warnings: [], + }); + + const { wrapper } = createWrapper(); + const provider = createProvider({ + settingsConfig: { + models: [{ id: "gpt-4.1" }, { id: "gpt-4.1-mini" }], + }, + }); + + const { result } = renderHook(() => useProviderActions("openclaw"), { + wrapper, + }); + + await act(async () => { + await result.current.setAsDefaultModel(provider); + }); + + expect(openclawApiSetDefaultModelMock).toHaveBeenCalledWith({ + primary: "provider-1/gpt-4.1", + fallbacks: ["provider-1/gpt-4.1-mini"], + }); + expect(toastSuccessMock).toHaveBeenCalledTimes(1); + expect(toastSuccessMock.mock.calls[0]?.[1]).toEqual({ closeButton: true }); + }); }); it("clears loading flag when all mutations idle", () => { addProviderMutation.isPending = false;