diff --git a/.changeset/fn-7062-remote-access-rename.md b/.changeset/fn-7062-remote-access-rename.md new file mode 100644 index 0000000000..0751023738 --- /dev/null +++ b/.changeset/fn-7062-remote-access-rename.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Rename the Remote Access settings section (drops the stale "& Node Sync" suffix). +category: fix +dev: The standalone Node Sync settings section is unchanged. diff --git a/docs/plans/2026-06-04-002-feat-workflow-settings-mechanism-plan.md b/docs/plans/2026-06-04-002-feat-workflow-settings-mechanism-plan.md index bc52ed8039..b6e93b9333 100644 --- a/docs/plans/2026-06-04-002-feat-workflow-settings-mechanism-plan.md +++ b/docs/plans/2026-06-04-002-feat-workflow-settings-mechanism-plan.md @@ -294,7 +294,7 @@ The schema-object key removal (from `DEFAULT_PROJECT_SETTINGS`) ships in the sam - **Requirements:** R9, R10, R11 - **Dependencies:** U4, U5, U8 - **Files:** `packages/dashboard/app/components/SettingsModal.tsx`, `packages/dashboard/app/components/SettingsModal.css`, `packages/dashboard/app/components/settings/sections/` (new per-section components + CSS), `packages/dashboard/app/hooks/useAppSettings.ts`, `packages/dashboard/app/__tests__/SettingsModal.test.tsx` -- **Approach:** Keep the proven shell mechanics — `SETTINGS_SECTIONS` nav model with group headers, `visibleSections` gating, save-splitting via `isGlobalSettingsKey`/`isProjectSettingsKey`, null-as-delete, changed-only project writes — but extract each section into a descriptor-driven component under `settings/sections/`. Remove moved settings from their sections; where a section's content moved wholesale (per-phase model lanes, step-execution and review knobs), render a redirect stub row that opens the workflow editor with the Settings panel pre-selected via a query/hash param (e.g. `?panel=settings`, read by `WorkflowNodeEditor` on mount — deterministic and testable), targeting the project's default workflow (one release, per KTD-5). Target IA for the regroup (group headers → sections): **Account** (Authentication); **Global** — General, Appearance, Models & Providers (merging global-models + openrouter + onboarding), Notifications (ntfy/webhook/failure), Research, Remote Access & Node Sync (merging remote + node-sync), Experimental; **Runtimes** unchanged; **Project** — General, Commands & Scripts, Git & Worktrees, Scheduling & Capacity, GitHub Integration, Agents & Permissions, Memory & Backups, Research, Secrets, Plugins. Former project-models and review/step sections collapse into redirect stubs under Project. Section renames keep stable section `id`s where a section survives so deep links and `DEFAULT_SETTINGS_SECTION` stay valid. Device-local three-tier prefs (theme/language/font scale) keep their hooks untouched. The 7,900-line file shrinks to shell + imports. +- **Approach:** Keep the proven shell mechanics — `SETTINGS_SECTIONS` nav model with group headers, `visibleSections` gating, save-splitting via `isGlobalSettingsKey`/`isProjectSettingsKey`, null-as-delete, changed-only project writes — but extract each section into a descriptor-driven component under `settings/sections/`. Remove moved settings from their sections; where a section's content moved wholesale (per-phase model lanes, step-execution and review knobs), render a redirect stub row that opens the workflow editor with the Settings panel pre-selected via a query/hash param (e.g. `?panel=settings`, read by `WorkflowNodeEditor` on mount — deterministic and testable), targeting the project's default workflow (one release, per KTD-5). Target IA for the regroup (group headers → sections): **Account** (Authentication); **Global** — General, Appearance, Models & Providers (merging global-models + openrouter + onboarding), Notifications (ntfy/webhook/failure), Research, Remote Access, Node Sync (kept as distinct remote + node-sync entries), Experimental; **Runtimes** unchanged; **Project** — General, Commands & Scripts, Git & Worktrees, Scheduling & Capacity, GitHub Integration, Agents & Permissions, Memory & Backups, Research, Secrets, Plugins. Former project-models and review/step sections collapse into redirect stubs under Project. Section renames keep stable section `id`s where a section survives so deep links and `DEFAULT_SETTINGS_SECTION` stay valid. Device-local three-tier prefs (theme/language/font scale) keep their hooks untouched. The 7,900-line file shrinks to shell + imports. - **Execution note:** Land section-by-section in reviewable slices rather than one mega-commit — this is the branch most exposed to the extraction-vs-semantics merge hazard; if `main` changes a setting's behavior mid-flight, port the semantic change to the section's new home and run the union suite. - **Test scenarios:** - Save-split regression: editing one global + one project setting in the same session produces the same `updateGlobalSettings`/`updateSettings` patches as before the redesign (characterization of the split function). diff --git a/packages/dashboard/app/components/SettingsModal.tsx b/packages/dashboard/app/components/SettingsModal.tsx index c8e0b142b1..4ff4022098 100644 --- a/packages/dashboard/app/components/SettingsModal.tsx +++ b/packages/dashboard/app/components/SettingsModal.tsx @@ -235,7 +235,11 @@ const SETTINGS_SECTIONS: SettingsSection[] = [ { id: "global-mcp", label: "MCP Servers", labelKey: "settings.nav.globalMcp", scope: "global" }, { id: "cli-agents", label: "CLI Agents", labelKey: "settings.nav.cliAgents", scope: "global" }, { id: "research-global", label: "Research Defaults", labelKey: "settings.nav.researchGlobal", scope: "global" }, - { id: "remote", label: "Remote Access & Node Sync", labelKey: "settings.nav.remote", scope: "global" }, + /* + FNXC:SettingsNavigation 2026-06-26-09:20: + FN-7062 requires the remote settings nav entry to read "Remote Access" only. The stale "& Node Sync" suffix belongs to the separate Node Sync settings section, while this section body already uses the Remote Access heading. + */ + { id: "remote", label: "Remote Access", labelKey: "settings.nav.remote", scope: "global" }, { id: "experimental", label: "Experimental Features", labelKey: "settings.nav.experimental", scope: "global" }, // Runtimes group (plugin runtimes with their own settings) diff --git a/packages/dashboard/app/components/__tests__/SettingsModal.scheduling-merge.test.tsx b/packages/dashboard/app/components/__tests__/SettingsModal.scheduling-merge.test.tsx index 111127cb3f..0f844d3154 100644 --- a/packages/dashboard/app/components/__tests__/SettingsModal.scheduling-merge.test.tsx +++ b/packages/dashboard/app/components/__tests__/SettingsModal.scheduling-merge.test.tsx @@ -1409,6 +1409,22 @@ describe("SettingsModal", () => { expect(await screen.findByRole("button", { name: /Remote Access/i })).toBeInTheDocument(); }); + it("labels the remote nav entry independently from the standalone Node Sync entry", async () => { + mockFetchSettings.mockResolvedValue({ + ...defaultSettings, + experimentalFeatures: {}, + }); + + renderModal(); + await waitForSettingsModalReady(); + + // Desktop and mobile settings navs share SETTINGS_SECTIONS, so this single render guards the shared label source. + expect(screen.getByRole("button", { name: "Remote Access" })).toBeInTheDocument(); + expect(screen.queryByRole("button", { name: /Remote Access & Node Sync/i })).not.toBeInTheDocument(); + expect(screen.queryByRole("button", { name: /& Node Sync/i })).not.toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Node Sync" })).toBeInTheDocument(); + }); + it.each([ ["experimentalFeatures undefined", undefined], ["experimentalFeatures empty", {}],