Skip to content

Desktop: Add search field to Config screen to filter settings#14779

Closed
Payel-Manna wants to merge 11 commits intolaurent22:devfrom
Payel-Manna:fix/config-screen-search-14763
Closed

Desktop: Add search field to Config screen to filter settings#14779
Payel-Manna wants to merge 11 commits intolaurent22:devfrom
Payel-Manna:fix/config-screen-search-14763

Conversation

@Payel-Manna
Copy link
Copy Markdown

@Payel-Manna Payel-Manna commented Mar 16, 2026

Closes #14763

Problem

The desktop Config screen had no way to search for settings by name or
description. Users had to manually browse each section to find a setting.
The mobile app already has this feature but it was missing on desktop.

Solution

Adds a SearchInput field at the top of the Config screen. When a query
is typed, settings are filtered across all sections by label and
description (case-insensitive). A clear (×) button resets the view.
When search is empty, normal section/tab behaviour is fully preserved.

The filter logic is extracted into filterSettingsByQuery.ts — a
standalone utility with no UI dependencies, making it fully testable.

Test Plan

Unit tests added in ConfigScreen.test.tsx covering:

  • Match by label ✅
  • Match by description ✅
  • No results for unmatched query ✅
  • Case insensitivity ✅
  • Results across multiple sections ✅
  • Function-based label support ✅

Manual testing:

  • Typed "sync" → sync settings shown from all sections ✅
  • Typed "xyzabc" → "No results" shown ✅
  • Clicked × → search cleared, normal view restored ✅
  • Normal section navigation unaffected when search is empty ✅

Video

configScreen

AI Assistance Disclosure

I used AI assistance (Claude) to help debug issues during development,
specifically to identify the correct SearchInput component API and fix
TypeScript type errors. All logic was written and verified by me.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 16, 2026

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 16, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a search input to the desktop Config screen, a new filterSettingsByQuery utility (default export) to match labels/descriptions, UI wiring for search state/handlers, tests for the filter, and updates to ignore and Yarn RC files.

Changes

Cohort / File(s) Summary
Repo ignores & config
/.eslintignore, /.gitignore, /.yarnrc.yml
Added two ConfigScreen paths to ignore lists; reverted/adjusted Yarn configuration entries (restored hoisting/linker settings and removed prior checksum/log override blocks).
Config screen UI
packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx
Integrated SearchInput, added searchQuery state with onSearchChange/onSearchClear, and conditional rendering to show flat matched setting components or a "No results" message when searching.
Filter util & tests
packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts, packages/app-desktop/gui/ConfigScreen/ConfigScreen.test.tsx
Added default-exported filterSettingsByQuery that returns matching setting keys by case-insensitive label/description matching (supports label as function) and tests covering label/description matches, case-insensitivity, multi-section search, no-match, and function-labels.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant UI as ConfigScreen (UI)
    participant Filter as filterSettingsByQuery
    participant Meta as Settings Metadata

    User->>UI: Type query / clear search
    UI->>Filter: filterSettingsByQuery(sections, query, AppType)
    Filter->>Meta: Read labels/descriptions (string or function)
    Meta-->>Filter: Return matching keys
    Filter-->>UI: Matched keys
    UI->>UI: Render matched setting components or "No results"
Loading
🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title accurately and clearly summarizes the main change: adding a search field to the Config screen to filter settings.
Description check ✅ Passed The pull request description is comprehensive and directly related to the changeset, explaining the problem, solution, test coverage, and manual verification.
Linked Issues check ✅ Passed The pull request fully addresses all coding requirements from issue #14763: search field added, filters by label and description (case-insensitive), and clear button implemented.
Out of Scope Changes check ✅ Passed Changes to .eslintignore, .gitignore, and .yarnrc.yml appear tangential to the core feature but support its implementation and testing infrastructure without introducing unrelated functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Pr Description Must Follow Guidelines ✅ Passed The pull request description includes all three required sections: Problem/user-impact (search functionality gap in desktop Config screen), Solution (SearchInput field with filtering), and Test Plan (unit tests and manual verification steps).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can get early access to new features in CodeRabbit.

Enable the early_access setting to enable early access features such as new models, tools, and more.

@coderabbitai coderabbitai Bot added enhancement Feature requests and code enhancements desktop All desktop platforms search labels Mar 16, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
packages/app-desktop/gui/ConfigScreen/ConfigScreen.test.tsx (1)

4-18: Add a test for metadata entries without description.

packages/lib/models/Setting.ts (Line 604) explicitly guards for missing descriptions, so this is a real edge case worth pinning down in this suite.

🧪 Suggested test addition
+	test('handles settings with no description', () => {
+		const sectionsWithoutDescription = [
+			{
+				name: 'general',
+				metadatas: [
+					{ key: 'theme', label: 'Theme' },
+				],
+			},
+		];
+		const result = filterSettingsByQuery(sectionsWithoutDescription as any, 'theme', AppType.Desktop);
+		expect(result).toContain('theme');
+	});

Based on learnings: Applies to **/*.{test,spec}.{ts,tsx,js,jsx} : Focus on testing essential behaviour and edge cases — avoid adding tests for every minor detail.

Also applies to: 20-60

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.test.tsx` around lines 4 -
18, Add a test in ConfigScreen.test.tsx that covers metadata entries missing the
description by extending the existing mockSections used in the tests (the
mockSections array) with a section or metadata object that omits the description
field, then render the ConfigScreen (or the specific component under test) and
assert it handles the missing description safely (no crash and expected UI
output, e.g., label/key is still shown). Reference the mockSections constant and
the test that renders ConfigScreen to locate where to add this case; ensure the
test exercises the codepath that maps metadata descriptions (covered by
packages/lib/models/Setting.ts guards) so the component gracefully handles
undefined description values.
packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts (1)

12-15: Normalise the query once (and trim) before iterating metadata.

This avoids repeated toLowerCase() calls and treats whitespace-only input as empty search.

♻️ Suggested refactor
 ): string[] => {
+  const normalisedQuery = query.trim().toLowerCase();
+  if (!normalisedQuery) return [];
+
   const matchedKeys: string[] = [];
   for (const section of sections) {
     for (const md of section.metadatas) {
       const label = (typeof md.label === 'function' ? md.label(appType) : md.label) || '';
       const desc = (typeof md.description === 'function' ? md.description(appType) : md.description) || '';
-      if (label.toLowerCase().includes(query.toLowerCase()) || desc.toLowerCase().includes(query.toLowerCase())) {
+      if (label.toLowerCase().includes(normalisedQuery) || desc.toLowerCase().includes(normalisedQuery)) {
         matchedKeys.push(md.key);
       }
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts` around lines
12 - 15, Normalize and trim the incoming query once before the loop to avoid
repeated toLowerCase() calls and to treat whitespace-only input as empty; e.g.,
compute a single const normalizedQuery = (query || '').trim().toLowerCase() and
then use normalizedQuery in the checks instead of calling query.toLowerCase()
repeatedly when testing label and desc (where label is derived from
md.label/appType and desc from md.description/appType) and when deciding whether
to push md.key into matchedKeys.
packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx (1)

494-502: Use theme-driven spacing for the search container instead of hard-coded padding.

This makes the new UI consistent with app-wide styling behaviour and theme evolution.

🎨 Suggested adjustment
-  <div style={{ padding: '10px 10px 0 10px' }}>
+  <div style={{ padding: theme.configScreenPadding, paddingBottom: 0 }}>

Based on learnings: Applies to readme/dev/packages/{app-desktop,app-mobile}/**/*.{ts,tsx} : For GUI style changes in Desktop and mobile clients, refer to packages/lib/theme.ts for all styling information.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx` around lines 494 -
502, Replace the hard-coded inline padding on the div wrapping SearchInput in
the ConfigScreen render (the container around SearchInput in the ConfigScreen
component) with theme-driven spacing from the shared theme
(packages/lib/theme.ts); remove the style={{ padding: '10px 10px 0 10px' }} and
instead apply the theme spacing via the project's styling approach (e.g.,
useTheme()/withTheme() or a CSS class that reads theme.space/spacing) so the
container uses the centralized spacing tokens consistent with other GUI
components.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx`:
- Around line 509-521: The bug: setting containerStyle.display = "none" whenever
screenComp is truthy hides search results and keeps save/apply disabled during
search; change the condition to only hide the main config list when a specific
screen is open (this.state.screenName) and not when in search mode (e.g., when
this.state.searchQuery or a isSearching flag is present); update the logic
around screenComp usage so save/apply enablement checks the active mode instead
of blindly using screenComp (reference symbols: screenComp,
this.state.screenName, containerStyle, this.screenFromName, and the save/apply
enable code near lines using screenComp) so search results and buttons remain
visible/active while still hiding the list when a dedicated screen is shown.
- Around line 297-301: The conditional rendering of the secondary sync status
line in statusComp uses messages.length >= 1 but accesses messages[1], causing
an off-by-one; update the guard to messages.length >= 2 so the
<p>{messages[1]}</p> is only rendered when a second message exists (locate the
statusComp block and the messages array usage to apply this change).
- Around line 44-50: Update ConfigScreenComponent by replacing all any usages
with concrete types: create interfaces ConfigScreenProps and ConfigScreenState
and use React.Component<ConfigScreenProps, ConfigScreenState> and
constructor(props: ConfigScreenProps). Type the private rowStyle_ as
React.CSSProperties | null. Replace untyped event params with DOM event types
(e.g., React.MouseEvent, React.ChangeEvent<HTMLInputElement>) in handler
signatures. Define explicit interfaces for the render method params (e.g.,
interface Section { id: string; title: string; ... } and interface Setting {
key: string; value: string; type: string; ... }) and annotate renderSection and
renderSettings with those types. Finally, strongly type mapStateToProps to
accept the app RootState (or appropriate Redux state type) and return
ConfigScreenProps to remove anys from Redux mapping. Ensure all referenced
symbols (ConfigScreenComponent, rowStyle_, constructor, renderSection,
renderSettings, mapStateToProps) are updated accordingly.

In `@packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts`:
- Around line 3-8: Replace the loose any[] type on the sections parameter of
filterSettingsByQuery with the exported MetadataBySection type from the Setting
module: update the function signature in filterSettingsByQuery to use sections:
MetadataBySection and add/import MetadataBySection from the Setting module if
it's not already imported; ensure usages that access section.metadatas still
compile and adjust any related type annotations or exports so the function and
call sites use MetadataBySection consistently.

---

Nitpick comments:
In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.test.tsx`:
- Around line 4-18: Add a test in ConfigScreen.test.tsx that covers metadata
entries missing the description by extending the existing mockSections used in
the tests (the mockSections array) with a section or metadata object that omits
the description field, then render the ConfigScreen (or the specific component
under test) and assert it handles the missing description safely (no crash and
expected UI output, e.g., label/key is still shown). Reference the mockSections
constant and the test that renders ConfigScreen to locate where to add this
case; ensure the test exercises the codepath that maps metadata descriptions
(covered by packages/lib/models/Setting.ts guards) so the component gracefully
handles undefined description values.

In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx`:
- Around line 494-502: Replace the hard-coded inline padding on the div wrapping
SearchInput in the ConfigScreen render (the container around SearchInput in the
ConfigScreen component) with theme-driven spacing from the shared theme
(packages/lib/theme.ts); remove the style={{ padding: '10px 10px 0 10px' }} and
instead apply the theme spacing via the project's styling approach (e.g.,
useTheme()/withTheme() or a CSS class that reads theme.space/spacing) so the
container uses the centralized spacing tokens consistent with other GUI
components.

In `@packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts`:
- Around line 12-15: Normalize and trim the incoming query once before the loop
to avoid repeated toLowerCase() calls and to treat whitespace-only input as
empty; e.g., compute a single const normalizedQuery = (query ||
'').trim().toLowerCase() and then use normalizedQuery in the checks instead of
calling query.toLowerCase() repeatedly when testing label and desc (where label
is derived from md.label/appType and desc from md.description/appType) and when
deciding whether to push md.key into matchedKeys.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 97d9051d-5127-408f-ab1e-41482ca23faa

📥 Commits

Reviewing files that changed from the base of the PR and between c9dace8 and 403a8d5.

⛔ Files ignored due to path filters (1)
  • packages/app-clipper/popup/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • .eslintignore
  • .gitignore
  • .yarnrc.yml
  • packages/app-desktop/gui/ConfigScreen/ConfigScreen.test.tsx
  • packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx
  • packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts

Comment thread packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx Outdated
Comment thread packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx Outdated
Comment thread packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx Outdated
Comment on lines +3 to +8
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const filterSettingsByQuery = (
sections: any[],
query: string,
appType: AppType,
): string[] => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check the actual file content
cat -n packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts | head -30

Repository: laurent22/joplin

Length of output: 1016


🏁 Script executed:

# Search for MetadataBySection type definition
rg "MetadataBySection" packages/app-desktop/ -A 3 -B 1

Repository: laurent22/joplin

Length of output: 880


🏁 Script executed:

# Check what types are currently exported from the Setting module
rg "export.*type|export.*interface" `@joplin/lib/models/Setting.ts` -A 2

Repository: laurent22/joplin

Length of output: 129


🏁 Script executed:

# Find the Setting module file
find . -name "Setting.ts" -o -name "Setting.tsx" | grep -E "lib|models"

Repository: laurent22/joplin

Length of output: 92


🏁 Script executed:

# Try searching with rg for MetadataBySection definition
rg "type MetadataBySection|interface MetadataBySection" -A 5

Repository: laurent22/joplin

Length of output: 443


🏁 Script executed:

# Check the packages/lib structure
ls -la packages/lib/models/ 2>/dev/null | head -20

Repository: laurent22/joplin

Length of output: 1300


🏁 Script executed:

# Find SettingMetadataSection type definition
rg "type SettingMetadataSection|interface SettingMetadataSection" -A 10 packages/lib/models/Setting.ts

Repository: laurent22/joplin

Length of output: 363


🏁 Script executed:

# Check current imports in the target file
cat -n packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts | head -5

Repository: laurent22/joplin

Length of output: 299


🏁 Script executed:

# Verify if MetadataBySection is already exported from the Setting module and accessible
rg "export.*MetadataBySection" packages/lib/models/Setting.ts

Repository: laurent22/joplin

Length of output: 117


Replace any[] with MetadataBySection type.

The sections parameter uses any[], which violates TypeScript guidelines. The proper type MetadataBySection is already exported from the Setting module and matches the code's usage (accessing section.metadatas).

🛠️ Suggested typing fix
-import { AppType } from '@joplin/lib/models/Setting';
+import { AppType, MetadataBySection } from '@joplin/lib/models/Setting';

-// eslint-disable-next-line `@typescript-eslint/no-explicit-any` -- Old code before rule was applied
 const filterSettingsByQuery = (
-  sections: any[],
+  sections: MetadataBySection,
   query: string,
   appType: AppType,
 ): string[] => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts` around lines
3 - 8, Replace the loose any[] type on the sections parameter of
filterSettingsByQuery with the exported MetadataBySection type from the Setting
module: update the function signature in filterSettingsByQuery to use sections:
MetadataBySection and add/import MetadataBySection from the Setting module if
it's not already imported; ensure usages that access section.metadatas still
compile and adjust any related type annotations or exports so the function and
call sites use MetadataBySection consistently.

@Payel-Manna
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Mar 17, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx (1)

509-520: ⚠️ Potential issue | 🟠 Major

Search mode still inherits the screen-only hiding logic.

If a screen-based section is already open, Line 518 hides the same containerStyle used for the search results at Lines 587-593, and Lines 619-620 stay disabled because screenComp remains truthy. Typing in the new search field from Encryption/Keymap therefore shows nothing and blocks editing.

💡 Suggested change
-		const screenComp = this.state.screenName ? (
+		const isSearchMode = !!this.state.searchQuery;
+		const screenComp = !isSearchMode && this.state.screenName ? (
 			<div
-				className="config-screen-content-wrapper"
-				style={{ overflow: "scroll", flex: 1 }}
+				className='config-screen-content-wrapper'
+				style={{ overflow: 'scroll', flex: 1 }}
 			>
 				{this.screenFromName(this.state.screenName)}
 			</div>
 		) : null;
@@
-		const mainContent = this.state.searchQuery ? (
+		const mainContent = isSearchMode ? (

Also applies to: 587-620

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx` around lines 509 -
520, The current logic hides the shared containerStyle whenever screenComp
(derived from this.state.screenName via screenFromName) is truthy, which also
hides search results and keeps UI controls disabled; introduce an isSearching
boolean (derived from the search input state you already have, e.g.,
this.state.searchQuery or this.state.searchTerm) and change the conditional
checks so the containerStyle display and any disabled props only apply when
screenComp is truthy AND not isSearching (e.g., if (screenComp && !isSearching)
containerStyle.display = "none"; and use (screenComp && !isSearching) for
button/field disabled checks) so opening a search field in a screened section
shows results and enables editing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx`:
- Around line 1-638: The file fails lint due to indentation and spacing (rules:
indent, `@typescript-eslint/indent`, curly, comma-spacing,
type-annotation-spacing); reformat the entire ConfigScreen.tsx to use tabs
(project guideline) and correct spacing/brace placement so eslint passes — focus
on correcting indentation and spacing in the methods and JSX around
ConfigScreenComponent (constructor, componentDidMount, render,
sectionToComponent, settingToComponent, sidebar_selectionChange,
handleSettingButton) and the JSX blocks for searchBar, tabComponents, and
mainContent; run the repository formatter/eslint auto-fix (e.g. prettier/eslint
--fix) or apply the project's tab-based formatting rules to ensure all commas,
type annotations, and curly braces follow the repo style before committing.

In `@packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts`:
- Line 27: The file ends without a trailing newline causing an eol-last lint
failure; open the file containing the export default filterSettingsByQuery and
add a single newline character at the end of the file (ensure the file
terminates with a blank line so the final line ends with a newline).

---

Duplicate comments:
In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx`:
- Around line 509-520: The current logic hides the shared containerStyle
whenever screenComp (derived from this.state.screenName via screenFromName) is
truthy, which also hides search results and keeps UI controls disabled;
introduce an isSearching boolean (derived from the search input state you
already have, e.g., this.state.searchQuery or this.state.searchTerm) and change
the conditional checks so the containerStyle display and any disabled props only
apply when screenComp is truthy AND not isSearching (e.g., if (screenComp &&
!isSearching) containerStyle.display = "none"; and use (screenComp &&
!isSearching) for button/field disabled checks) so opening a search field in a
screened section shows results and enables editing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e6f08b09-eff1-46c9-86a6-e2bab874e7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 403a8d5 and 141f888.

📒 Files selected for processing (3)
  • packages/app-desktop/gui/ConfigScreen/ConfigScreen.test.tsx
  • packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx
  • packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/app-desktop/gui/ConfigScreen/ConfigScreen.test.tsx

Comment thread packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx Outdated
Comment thread packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (3)
packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx (3)

432-442: ⚠️ Potential issue | 🟠 Major

Reformat the new render block to tabs; lint is failing on these added lines.

The newly added search/render block uses space-based indentation and currently violates repo indentation rules, which will keep CI red.

As per coding guidelines: **/*.{ts,tsx,js,jsx}: Use tabs for indentation.

Also applies to: 467-532

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx` around lines 432 -
442, The new JSX block for searchBar is indented with spaces which violates the
repo rule requiring tabs; update the indentation of the entire search/render
block (the const searchBar declaration and its JSX children using SearchInput,
including props value={this.state.searchQuery}, onChange={this.onSearchChange},
onSearchButtonClick={this.onSearchClear}, searchStarted and placeholder) to use
tabs instead of spaces, and apply the same tabs-based reformatting to the
additional affected lines around the render (the other search/render lines
referenced) so linting passes.

449-451: ⚠️ Potential issue | 🟠 Major

Search mode is still coupled to screen mode and can hide results.

When screenName is set, Line 451 hides containerStyle. In search mode, the same container is reused (Line 503), so results can disappear; save/apply also remain disabled via screenComp checks on Line 527-528.

🐛 Suggested fix
+		const isSearchMode = !!this.state.searchQuery;
-		const screenComp = this.state.screenName ? <div className="config-screen-content-wrapper" style={{ overflow: 'scroll', flex: 1 }}>{this.screenFromName(this.state.screenName)}</div> : null;
+		const screenComp = !isSearchMode && this.state.screenName ? <div className='config-screen-content-wrapper' style={{ overflow: 'scroll', flex: 1 }}>{this.screenFromName(this.state.screenName)}</div> : null;

-		if (screenComp) containerStyle.display = 'none';
+		if (!isSearchMode && screenComp) containerStyle.display = 'none';

-const mainContent = this.state.searchQuery ? (
+const mainContent = isSearchMode ? (
@@
-				onSaveClick={screenComp ? null : this.onSaveClick}
-				onApplyClick={screenComp ? null : this.onApplyClick}
+				onSaveClick={!isSearchMode && screenComp ? null : this.onSaveClick}
+				onApplyClick={!isSearchMode && screenComp ? null : this.onApplyClick}

Also applies to: 503-510, 525-529

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx` around lines 449 -
451, The code hides the main container whenever screenComp is truthy (computed
from this.state.screenName), which also unintentionally hides search results and
disables save/apply when in search mode; update the conditional checks that use
screenComp (including the assignment to containerStyle.display and the
save/apply gating around where screenComp is checked) to only treat screen mode
as exclusive when not in search mode (e.g., change checks from "if (screenComp)"
to "if (screenComp && !this.state.isSearchMode)" or the equivalent boolean that
indicates search is active), and apply the same guarded logic to the other
occurrences near where search UI is rendered so screenFromName, screenComp, and
containerStyle no longer interfere with search results or button states.

72-74: ⚠️ Potential issue | 🟠 Major

Replace any in search change handler with the SearchInput event type.

onSearchChange currently uses event: any on Line 72, which violates the TypeScript type safety guideline. Use the OnChangeEvent interface exported by SearchInput.

Suggested fix
-import SearchInput from '../lib/SearchInput/SearchInput';
+import SearchInput, { OnChangeEvent } from '../lib/SearchInput/SearchInput';
@@
-	private onSearchChange = (event: any) => {
+	private onSearchChange = (event: OnChangeEvent) => {
 		this.setState({ searchQuery: event.value });
 	};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx` around lines 72 - 74,
Replace the loose any type on the search handler by importing and using the
specific OnChangeEvent from SearchInput: update the onSearchChange signature
(method onSearchChange) to accept event: OnChangeEvent, import OnChangeEvent
from the SearchInput module, and keep using event.value to setState({
searchQuery: event.value }) so the handler is type-safe and aligns with the
SearchInput event interface.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx`:
- Around line 432-442: The new JSX block for searchBar is indented with spaces
which violates the repo rule requiring tabs; update the indentation of the
entire search/render block (the const searchBar declaration and its JSX children
using SearchInput, including props value={this.state.searchQuery},
onChange={this.onSearchChange}, onSearchButtonClick={this.onSearchClear},
searchStarted and placeholder) to use tabs instead of spaces, and apply the same
tabs-based reformatting to the additional affected lines around the render (the
other search/render lines referenced) so linting passes.
- Around line 449-451: The code hides the main container whenever screenComp is
truthy (computed from this.state.screenName), which also unintentionally hides
search results and disables save/apply when in search mode; update the
conditional checks that use screenComp (including the assignment to
containerStyle.display and the save/apply gating around where screenComp is
checked) to only treat screen mode as exclusive when not in search mode (e.g.,
change checks from "if (screenComp)" to "if (screenComp &&
!this.state.isSearchMode)" or the equivalent boolean that indicates search is
active), and apply the same guarded logic to the other occurrences near where
search UI is rendered so screenFromName, screenComp, and containerStyle no
longer interfere with search results or button states.
- Around line 72-74: Replace the loose any type on the search handler by
importing and using the specific OnChangeEvent from SearchInput: update the
onSearchChange signature (method onSearchChange) to accept event: OnChangeEvent,
import OnChangeEvent from the SearchInput module, and keep using event.value to
setState({ searchQuery: event.value }) so the handler is type-safe and aligns
with the SearchInput event interface.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c832963d-ea7e-460e-92ba-0442d418399c

📥 Commits

Reviewing files that changed from the base of the PR and between 141f888 and a016461.

📒 Files selected for processing (2)
  • packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx
  • packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/app-desktop/gui/ConfigScreen/filterSettingsByQuery.ts

@laurent22
Copy link
Copy Markdown
Owner

Hello, unfortunately we no longer need this pull request as there's a duplicate here, that will probably merge instead: #14820

@laurent22 laurent22 closed this Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

desktop All desktop platforms enhancement Feature requests and code enhancements search

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for searching for settings in the desktop app

2 participants