diff --git a/.changeset/fn-7880-reset-mobile-label.md b/.changeset/fn-7880-reset-mobile-label.md new file mode 100644 index 0000000000..382d9fd8c8 --- /dev/null +++ b/.changeset/fn-7880-reset-mobile-label.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Shorten the Settings "Reset Settings" button to "Reset" on mobile. +category: fix +dev: SettingsModal reset button now uses settings.reset.buttonShort at viewportMode==="mobile"; confirmation dialog unchanged. diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index fd1b8e87ef..9b43d13777 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -24,8 +24,10 @@ Every user-editable setting's help text (the `.settings-description`/`` h ## Reset Settings - -The Settings footer includes a **Reset Settings** button, next to Import/Export, in both the Settings modal and the embedded Settings page (desktop and mobile). Selecting it opens a confirmation dialog with two destructive choices, plus Cancel: + +The Settings footer includes a **Reset Settings** button, next to Import/Export, in both the Settings modal and the embedded Settings page. On mobile the same button is labeled **Reset** to preserve footer space; desktop and tablet keep **Reset Settings**. Selecting it opens a confirmation dialog with two destructive choices, plus Cancel: - **Reset this menu ({{section}})** — resets only the settings owned by the currently active section, at that section's own scope (global or project). A global section (for example Appearance) writes the section's keys back to their canonical defaults. A project section (for example Merge) clears the section's keys back to their inherited/default value. No other section's settings are touched. - **Reset all project settings** — resets every project-scoped setting for the current project back to its default/inherited value. This never touches global (cross-project) settings. diff --git a/packages/dashboard/app/components/SettingsModal.tsx b/packages/dashboard/app/components/SettingsModal.tsx index a5dc0451aa..ef3512c9c5 100644 --- a/packages/dashboard/app/components/SettingsModal.tsx +++ b/packages/dashboard/app/components/SettingsModal.tsx @@ -4130,6 +4130,9 @@ export function SettingsModal({ embedded (SettingsView) presentations — the footer is not gated by isEmbedded (only Cancel is), so this button renders in both automatically (FN-7506 Surface Enumeration: modal + embedded). + + FNXC:SettingsReset 2026-07-12-00:00: + The mobile Settings footer needs the compact Reset label to preserve horizontal space alongside Help, version, Import, Export, Cancel, and Save. Desktop and tablet keep the full Reset Settings wording while the existing destructive confirmation dialog remains unchanged. */}
diff --git a/packages/dashboard/app/components/__tests__/settings-mobile.test.tsx b/packages/dashboard/app/components/__tests__/settings-mobile.test.tsx index 3a0256b132..4377bdf4f0 100644 --- a/packages/dashboard/app/components/__tests__/settings-mobile.test.tsx +++ b/packages/dashboard/app/components/__tests__/settings-mobile.test.tsx @@ -241,14 +241,21 @@ describe("SettingsModal mobile adaptations", () => { FN-7506 mobile surface coverage: the Reset Settings button and its confirmation dialog must be reachable and usable at the mobile breakpoint, with no horizontal overflow, mirroring the desktop assertions in SettingsModal.general.test.tsx. + + FNXC:SettingsReset 2026-07-12-00:00: + FN-7880 mobile label coverage: the same footer affordance renders in modal and + embedded SettingsView presentations, but only the mobile viewport shortens the + visible label to Reset. Desktop and tablet keep Reset Settings. */ - it("renders and operates the Reset Settings button/dialog at the mobile breakpoint", async () => { + it("renders and operates the compact Reset button/dialog at the mobile breakpoint", async () => { mockSettingsViewport(true); const { findByTestId, container } = render(); await waitFor(() => expect(fetchSettings).toHaveBeenCalled()); const resetBtn = await findByTestId("settings-reset"); expect(container.querySelector(".modal-actions")?.contains(resetBtn)).toBe(true); + expect(resetBtn).toHaveTextContent(/^Reset$/); + expect(resetBtn).not.toHaveTextContent("Reset Settings"); const user = userEvent.setup({ delay: null, pointerEventsCheck: 0 }); await user.click(resetBtn); @@ -261,6 +268,34 @@ describe("SettingsModal mobile adaptations", () => { expect(updateSettings).not.toHaveBeenCalled(); }); + it("uses viewport-specific reset labels in modal and embedded footers", async () => { + mockSettingsViewport(true); + const mobileModal = render(); + await waitFor(() => expect(fetchSettings).toHaveBeenCalled()); + expect(await mobileModal.findByTestId("settings-reset")).toHaveTextContent(/^Reset$/); + mobileModal.unmount(); + + vi.clearAllMocks(); + mockSettingsViewport(true); + const mobileEmbedded = render(); + await waitFor(() => expect(fetchSettings).toHaveBeenCalled()); + expect(await mobileEmbedded.findByTestId("settings-reset")).toHaveTextContent(/^Reset$/); + mobileEmbedded.unmount(); + + vi.clearAllMocks(); + mockSettingsViewport(false); + const desktopModal = render(); + await waitFor(() => expect(fetchSettings).toHaveBeenCalled()); + expect(await desktopModal.findByTestId("settings-reset")).toHaveTextContent(/^Reset Settings$/); + desktopModal.unmount(); + + vi.clearAllMocks(); + mockSettingsViewport(false); + const desktopEmbedded = render(); + await waitFor(() => expect(fetchSettings).toHaveBeenCalled()); + expect(await desktopEmbedded.findByTestId("settings-reset")).toHaveTextContent(/^Reset Settings$/); + }); + it("renders the compact app version label in mobile layout", async () => { mockSettingsViewport(true); const { findByText, queryByText, container } = render(); diff --git a/packages/i18n/locales/en/app.json b/packages/i18n/locales/en/app.json index 84cdb350ae..b08b5d32e9 100644 --- a/packages/i18n/locales/en/app.json +++ b/packages/i18n/locales/en/app.json @@ -6710,6 +6710,7 @@ }, "reset": { "button": "Reset Settings", + "buttonShort": "Reset", "buttonTitle": "Reset settings to their defaults", "dialogAriaLabel": "Reset settings", "dialogTitle": "Reset Settings", diff --git a/packages/i18n/locales/zh-CN/app.json b/packages/i18n/locales/zh-CN/app.json index b83200f334..dfe12e6033 100644 --- a/packages/i18n/locales/zh-CN/app.json +++ b/packages/i18n/locales/zh-CN/app.json @@ -6684,6 +6684,7 @@ }, "reset": { "button": "Reset Settings", + "buttonShort": "Reset", "buttonTitle": "Reset settings to their defaults", "dialogAriaLabel": "Reset settings", "dialogTitle": "Reset Settings", diff --git a/packages/i18n/src/resources.d.ts b/packages/i18n/src/resources.d.ts index 1b553d56f9..fd3eabccd3 100644 --- a/packages/i18n/src/resources.d.ts +++ b/packages/i18n/src/resources.d.ts @@ -6538,6 +6538,7 @@ export default interface Resources { "reset": { "allProjectResetSuccess": "All project settings reset to defaults", "button": "Reset Settings", + "buttonShort": "Reset", "buttonTitle": "Reset settings to their defaults", "dialogAriaLabel": "Reset settings", "dialogBody": "Choose what to reset to its defaults. This cannot be undone.",