fix: filter interaction with settings search regressed (#293187)

This commit is contained in:
Raymond Zhao
2026-02-05 11:11:38 -08:00
committed by GitHub
parent 82714b58c8
commit 2bb11a0af2
3 changed files with 24 additions and 27 deletions

View File

@@ -879,7 +879,7 @@ export class SettingsEditor2 extends EditorPane {
// If the target display category is different than the source's, unfocus the category
// so that we can render all found settings again.
// Then, the reveal call will correctly find the target setting.
if (this.viewState.filterToCategory && evt.source.displayCategory !== targetElement.displayCategory) {
if (this.viewState.categoryFilter && evt.source.displayCategory !== targetElement.displayCategory) {
this.tocTree.setFocus([]);
}
try {
@@ -1054,8 +1054,8 @@ export class SettingsEditor2 extends EditorPane {
const scrollBehavior = this.configurationService.getValue<'paginated' | 'continuous'>(SCROLL_BEHAVIOR_KEY);
if (this.searchResultModel || scrollBehavior === 'paginated') {
// In search mode or paginated mode, filter to show only the selected category
if (this.viewState.filterToCategory !== element) {
this.viewState.filterToCategory = element ?? undefined;
if (this.viewState.categoryFilter !== element) {
this.viewState.categoryFilter = element ?? undefined;
// Force render in this case, because
// onDidClickSetting relies on the updated view.
this.renderTree(undefined, true);
@@ -1063,8 +1063,8 @@ export class SettingsEditor2 extends EditorPane {
}
} else {
// In continuous mode, clear any category filter that may have been set in paginated mode
if (this.viewState.filterToCategory) {
this.viewState.filterToCategory = undefined;
if (this.viewState.categoryFilter) {
this.viewState.categoryFilter = undefined;
this.renderTree(undefined, true);
}
if (element && (!e.browserEvent || !(<IFocusEventFromScroll>e.browserEvent).fromScroll)) {
@@ -1709,7 +1709,7 @@ export class SettingsEditor2 extends EditorPane {
if (Array.isArray(rootChildren) && rootChildren.length > 0) {
const firstCategory = rootChildren[0];
if (firstCategory instanceof SettingsTreeGroupElement) {
this.viewState.filterToCategory = firstCategory;
this.viewState.categoryFilter = firstCategory;
this.tocTree.setFocus([firstCategory]);
this.tocTree.setSelection([firstCategory]);
}
@@ -1918,7 +1918,7 @@ export class SettingsEditor2 extends EditorPane {
if (expandResults) {
this.tocTree.setFocus([]);
this.viewState.filterToCategory = undefined;
this.viewState.categoryFilter = undefined;
}
this.tocTreeModel.currentSearchModel = this.searchResultModel;
@@ -2040,7 +2040,7 @@ export class SettingsEditor2 extends EditorPane {
this.tocTreeModel.currentSearchModel = this.searchResultModel;
if (expandResults) {
this.tocTree.setFocus([]);
this.viewState.filterToCategory = undefined;
this.viewState.categoryFilter = undefined;
this.tocTree.expandAll();
this.settingsTree.scrollTop = 0;
}

View File

@@ -2419,14 +2419,14 @@ function escapeInvisibleChars(enumValue: string): string {
export class SettingsTreeFilter implements ITreeFilter<SettingsTreeElement> {
constructor(
private viewState: ISettingsEditorViewState,
private filterGroups: boolean,
private isFilteringGroups: boolean,
@IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService,
) { }
filter(element: SettingsTreeElement, parentVisibility: TreeVisibility): TreeFilterResult<void> {
// Filter during search
if (this.viewState.filterToCategory && element instanceof SettingsTreeSettingElement) {
if (!this.settingBelongsToCategory(element, this.viewState.filterToCategory)) {
if (this.viewState.categoryFilter && element instanceof SettingsTreeSettingElement) {
if (!this.settingContainedInGroup(element.setting, this.viewState.categoryFilter)) {
return false;
}
}
@@ -2442,8 +2442,8 @@ export class SettingsTreeFilter implements ITreeFilter<SettingsTreeElement> {
// Group with no visible children
if (element instanceof SettingsTreeGroupElement) {
// When filtering to a specific category, only show that category and its descendants
if (this.filterGroups && this.viewState.filterToCategory) {
if (!this.groupIsRelatedToCategory(element, this.viewState.filterToCategory)) {
if (this.isFilteringGroups && this.viewState.categoryFilter) {
if (!this.groupIsRelatedToCategory(element, this.viewState.categoryFilter)) {
return false;
}
// For groups related to the category, skip the count check and recurse
@@ -2460,7 +2460,7 @@ export class SettingsTreeFilter implements ITreeFilter<SettingsTreeElement> {
// Filtered "new extensions" button
if (element instanceof SettingsTreeNewExtensionsElement) {
if (this.viewState.tagFilters?.size || this.viewState.filterToCategory) {
if (this.viewState.tagFilters?.size || this.viewState.categoryFilter) {
return false;
}
}
@@ -2468,19 +2468,16 @@ export class SettingsTreeFilter implements ITreeFilter<SettingsTreeElement> {
return true;
}
/**
* Checks if a setting element belongs to the category or any of its subcategories
* by traversing up the setting's parent chain using IDs.
*/
private settingBelongsToCategory(element: SettingsTreeSettingElement, category: SettingsTreeGroupElement): boolean {
let parent = element.parent;
while (parent) {
if (parent.id === category.id) {
return true;
private settingContainedInGroup(setting: ISetting, group: SettingsTreeGroupElement): boolean {
return group.children.some(child => {
if (child instanceof SettingsTreeGroupElement) {
return this.settingContainedInGroup(setting, child);
} else if (child instanceof SettingsTreeSettingElement) {
return child.setting.key === setting.key;
} else {
return false;
}
parent = parent.parent;
}
return false;
});
}
/**

View File

@@ -34,7 +34,7 @@ export interface ISettingsEditorViewState {
featureFilters?: Set<string>;
idFilters?: Set<string>;
languageFilter?: string;
filterToCategory?: SettingsTreeGroupElement;
categoryFilter?: SettingsTreeGroupElement;
}
export abstract class SettingsTreeElement extends Disposable {