diff --git a/.changeset/calm-settings-navigation.md b/.changeset/calm-settings-navigation.md new file mode 100644 index 0000000000..c2e943425c --- /dev/null +++ b/.changeset/calm-settings-navigation.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": minor +--- + +summary: Add a persistent Advanced settings toggle that keeps uncommon Settings sections hidden by default. +category: feature +dev: The browser-local disclosure applies to desktop, mobile, and Settings search without changing saved settings. diff --git a/docs/screenshots/settings-advanced/desktop-advanced.png b/docs/screenshots/settings-advanced/desktop-advanced.png new file mode 100644 index 0000000000..121a43d4c6 --- /dev/null +++ b/docs/screenshots/settings-advanced/desktop-advanced.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:674d24e02998d9ccdf85ffbc2dc8dc4fa1c070964ef4096b33aed8f8e3d56459 +size 189060 diff --git a/docs/screenshots/settings-advanced/desktop-basic.png b/docs/screenshots/settings-advanced/desktop-basic.png new file mode 100644 index 0000000000..dac9349202 --- /dev/null +++ b/docs/screenshots/settings-advanced/desktop-basic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b2d0d6d3bddc2f06f178658b6162a088f73154c86b1f3d515728ac0f8169673 +size 182222 diff --git a/docs/screenshots/settings-advanced/mobile-advanced.png b/docs/screenshots/settings-advanced/mobile-advanced.png new file mode 100644 index 0000000000..7c27793aa7 --- /dev/null +++ b/docs/screenshots/settings-advanced/mobile-advanced.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:429955254d3ee2cac2e0b40016c158e00d37034488b69b2cb0d4411231c3354f +size 258818 diff --git a/docs/screenshots/settings-advanced/mobile-basic.png b/docs/screenshots/settings-advanced/mobile-basic.png new file mode 100644 index 0000000000..189e07c840 --- /dev/null +++ b/docs/screenshots/settings-advanced/mobile-basic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b9441fcaa82f557113c685622b792f1a8c898971b2709f256ba6e5f9c1dd945 +size 258732 diff --git a/packages/dashboard/app/components/SettingsModal.css b/packages/dashboard/app/components/SettingsModal.css index ecedddbd42..f92152d2f9 100644 --- a/packages/dashboard/app/components/SettingsModal.css +++ b/packages/dashboard/app/components/SettingsModal.css @@ -641,6 +641,27 @@ Fix the invariant for BOTH presentations (standalone modal + embedded SettingsVi border-bottom: var(--btn-border-width) solid var(--border); } +/* +FNXC:SettingsSimplification 2026-07-10-23:24: +The Advanced settings preference is a navigation-level disclosure, so keep it visually adjacent to section search/picking in both desktop and mobile layouts and retain a full-row click target. +*/ +.settings-advanced-toggle { + display: flex; + align-items: center; + gap: var(--space-sm); + padding: var(--space-sm); + border-bottom: var(--btn-border-width) solid var(--border); + color: var(--text); + font-size: 0.8rem; + font-weight: 600; + cursor: pointer; +} + +.settings-advanced-toggle input { + margin: 0; + cursor: pointer; +} + /* FNXC:Settings 2026-07-09-12:00: the row wraps label + input + results; on desktop it always renders (see .settings-search-toggle below, hidden here). On mobile the inline section-picker toggle controls whether this wrapper mounts below the picker, avoiding an empty padded shell above the picker while collapsed. */ .settings-search-row { display: flex; @@ -2282,6 +2303,11 @@ The header row wraps so the badge drops below the heading on narrow widths inste padding: var(--space-sm) var(--space-md) var(--space-sm); } + .settings-advanced-toggle { + padding: 0 var(--space-md) var(--space-sm); + border-bottom: none; + } + /* FNXC:Settings 2026-07-09-12:00: mobile-only collapse-by-default toggle sits in the section picker control row so search and section navigation share one horizontal affordance row. The row starts collapsed and expands to the full search row below the picker on tap. */ .settings-search-toggle { --settings-search-toggle-touch-target: calc(var(--space-lg) + var(--space-lg) + var(--space-xs)); diff --git a/packages/dashboard/app/components/SettingsModal.tsx b/packages/dashboard/app/components/SettingsModal.tsx index 4a66330d81..41ddfb9c20 100644 --- a/packages/dashboard/app/components/SettingsModal.tsx +++ b/packages/dashboard/app/components/SettingsModal.tsx @@ -238,6 +238,52 @@ type SettingsSection = { const MOBILE_SETTINGS_MEDIA_QUERY = "(max-width: 768px)"; const DEFAULT_MEMORY_EDITOR_PATH = ".fusion/memory/DREAMS.md"; +const ADVANCED_SETTINGS_STORAGE_KEY = "fusion:settings:show-advanced"; + +/* +FNXC:SettingsSimplification 2026-07-10-23:24: +Settings opens in a focused mode that omits specialist integration, runtime, diagnostics, and infrastructure sections. The Advanced settings switch restores every section, applies consistently to desktop navigation, mobile navigation, and search, and persists only as a browser-local display preference so it never changes or exports project settings. +*/ +const ADVANCED_SETTINGS_SECTION_IDS = new Set([ + "node-sync", + "global-mcp", + "cli-agents", + "research-global", + "remote", + "experimental", + "hermes-runtime", + "openclaw-runtime", + "paperclip-runtime", + "scheduled-evals", + "node-routing", + "agent-permissions", + "memory", + "backups", + "research-project", + "secrets", + "mcp", + "prompts", + "plugins", +]); + +function readAdvancedSettingsPreference(): boolean { + try { + return localStorage.getItem(ADVANCED_SETTINGS_STORAGE_KEY) === "true"; + } catch { + return false; + } +} + +function removeEmptySettingsGroups(sections: SettingsSection[]): SettingsSection[] { + return sections.filter((section, index) => { + if (!section.isGroupHeader) return true; + for (const candidate of sections.slice(index + 1)) { + if (candidate.isGroupHeader) return false; + return true; + } + return false; + }); +} function normalizeSettingsSearchText(value: string): string { return value.trim().toLocaleLowerCase(); @@ -978,6 +1024,22 @@ export function SettingsModal({ : false), ); const [settingsSearchQuery, setSettingsSearchQuery] = useState(""); + const [showAdvancedSettings, setShowAdvancedSettings] = useState(() => { + const requestedSection = initialSection === "pi-extensions" ? "plugins" : initialSection; + /* + FNXC:SettingsSimplification 2026-07-10-23:24: + Product links that intentionally open a specific advanced section must remain usable. Reveal advanced navigation for that Settings session, but do not persist the implicit reveal; only a direct user toggle changes the local-storage preference. + */ + return readAdvancedSettingsPreference() || (requestedSection !== undefined && ADVANCED_SETTINGS_SECTION_IDS.has(requestedSection)); + }); + const handleAdvancedSettingsChange = useCallback((enabled: boolean) => { + setShowAdvancedSettings(enabled); + try { + localStorage.setItem(ADVANCED_SETTINGS_STORAGE_KEY, String(enabled)); + } catch { + // Storage can be unavailable in private/locked-down browser contexts; the in-session preference still works. + } + }, []); /* * FNXC:Settings 2026-07-09-00:00: * Mobile Settings previously always rendered the `.settings-search` row (label + input + result @@ -1042,7 +1104,11 @@ export function SettingsModal({ const experimentalFeatures = form.experimentalFeatures ?? {}; const researchViewEnabled = isExperimentalFeatureEnabled(experimentalFeatures, "researchView"); const evalsViewEnabled = isExperimentalFeatureEnabled(experimentalFeatures, "evalsView"); - const visibleSections = useMemo(() => SETTINGS_SECTIONS.filter((section) => { + const visibleSections = useMemo(() => removeEmptySettingsGroups(SETTINGS_SECTIONS.filter((section) => { + if (!showAdvancedSettings && ADVANCED_SETTINGS_SECTION_IDS.has(section.id)) { + return false; + } + if (section.id === "research-global" || section.id === "research-project") { return researchViewEnabled; } @@ -1052,7 +1118,7 @@ export function SettingsModal({ } return true; - }), [researchViewEnabled, evalsViewEnabled]); + })), [researchViewEnabled, evalsViewEnabled, showAdvancedSettings]); const firstVisibleSectionId = visibleSections.some((section) => section.id === DEFAULT_SETTINGS_SECTION) ? DEFAULT_SETTINGS_SECTION : resolveFirstSelectableSettingsSection(visibleSections, firstNonHeaderSection?.id ?? "general"); @@ -3740,6 +3806,14 @@ export function SettingsModal({ )} + {settingsSearchRowVisible && (