diff --git a/.changeset/fn-041-settings-search-chat-layout.md b/.changeset/fn-041-settings-search-chat-layout.md new file mode 100644 index 0000000000..d3e8cdefdc --- /dev/null +++ b/.changeset/fn-041-settings-search-chat-layout.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Make the conversation layout setting discoverable in dashboard Settings search. +category: fix +dev: Adds the missing Appearance search entry and focused cross-surface regression coverage. diff --git a/packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx b/packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx index 72d3ec40fa..c91c9db385 100644 --- a/packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx +++ b/packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx @@ -770,6 +770,57 @@ describe("SettingsModal", () => { expect(screen.getAllByText(/No settings sections match/).length).toBeGreaterThan(0); }); + /* + * FNXC:SettingsSearch 2026-08-19-14:19: + * The migrated index must make the existing conversation-layout row discoverable + * through every Settings presentation: desktop search is open, mobile search is + * expanded explicitly, and embedded Settings uses the same production modal. + * Clicking each result verifies the real row anchor rather than a test-only stub. + */ + it.each([ + { + name: "desktop modal by label", + viewport: "desktop" as const, + presentation: undefined, + query: "conversation layout", + expandSearch: false, + }, + { + name: "mobile modal by help text", + viewport: "mobile" as const, + presentation: undefined, + query: "full width", + expandSearch: true, + }, + { + name: "embedded Settings by field key", + viewport: "mobile" as const, + presentation: "embedded" as const, + query: "chatMessageLayout", + expandSearch: true, + }, + ])("discovers chat message layout in the $name", async ({ viewport, presentation, query, expandSearch }) => { + viewportMode = viewport; + renderModal({ presentation }); + await waitForSettingsModalReady(); + + if (expandSearch) { + await settingsModalUser.click(screen.getByLabelText("Show search")); + } + const search = screen.getByTestId("settings-search-input"); + await settingsModalUser.type(search, query); + + expect(screen.getAllByTestId("settings-search-hit-chatMessageLayout")).toHaveLength(1); + // FNXC:SettingsSearch 2026-08-19-14:19: jsdom lacks the browser scroll API used by the production row-jump effect. + Object.defineProperty(HTMLElement.prototype, "scrollIntoView", { + configurable: true, + value: vi.fn(), + }); + await settingsModalUser.click(screen.getByTestId("settings-search-hit-chatMessageLayout")); + expect(screen.getAllByTestId("settings-search-hit-chatMessageLayout")).toHaveLength(1); + expect(document.querySelectorAll('[data-settings-key="chatMessageLayout"]')).toHaveLength(1); + }); + it("keeps duplicate global and project labels searchable while preserving no-results clearing", async () => { renderModal(); await waitForSettingsModalReady(); diff --git a/packages/dashboard/app/components/settings/sections/AppearanceSection.search.ts b/packages/dashboard/app/components/settings/sections/AppearanceSection.search.ts index e5a460c353..7a67e3f3ce 100644 --- a/packages/dashboard/app/components/settings/sections/AppearanceSection.search.ts +++ b/packages/dashboard/app/components/settings/sections/AppearanceSection.search.ts @@ -8,6 +8,21 @@ import type { SettingsSearchEntry } from "../search/types"; export const appearanceSearchEntries: SettingsSearchEntry[] = [ + /* + * FNXC:SettingsSearch 2026-08-19-14:19: + * Every rendered descriptor must have one co-located searchable entry. Keep + * the project-scoped conversation layout metadata identical to AppearanceSection + * so label, help, and field-key queries all reach the existing control. + */ + { + sectionId: "appearance", + key: "chatMessageLayout", + labelKey: "settings.appearance.chatMessageLayout", + labelFallback: "Conversation layout", + helpKey: "settings.appearance.chatMessageLayoutHelp", + helpFallback: + "Choose Bubbles or Full width for normal Chat, Quick Chat, dock Chat, task Activity, and Planner Chat. Project-scoped; default: Bubbles.", + }, { sectionId: "appearance", key: "openTasksInRightSidebar",