Skip to content

Commit 77cd0ab

Browse files
authored
Render a select box for adding static keys in object renderer (microsoft#101308)
1 parent 9e6f0dd commit 77cd0ab

2 files changed

Lines changed: 45 additions & 4 deletions

File tree

src/vs/workbench/contrib/preferences/browser/settingsTree.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticip
4444
import { getIgnoredSettings } from 'vs/platform/userDataSync/common/settingsMerge';
4545
import { ITOCEntry } from 'vs/workbench/contrib/preferences/browser/settingsLayout';
4646
import { ISettingsEditorViewState, settingKeyToDisplayFormat, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
47-
import { ExcludeSettingWidget, ISettingListChangeEvent, IListDataItem, ListSettingWidget, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ObjectSettingWidget, IObjectDataItem, IObjectEnumOption, ObjectValue, IObjectValueSuggester } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
47+
import { ExcludeSettingWidget, ISettingListChangeEvent, IListDataItem, ListSettingWidget, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ObjectSettingWidget, IObjectDataItem, IObjectEnumOption, ObjectValue, IObjectValueSuggester, IObjectKeySuggester } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
4848
import { SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences';
4949
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
5050
import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
@@ -174,6 +174,26 @@ function getObjectDisplayValue(element: SettingsTreeSettingElement): IObjectData
174174
});
175175
}
176176

177+
function createObjectKeySuggester(element: SettingsTreeSettingElement): IObjectKeySuggester {
178+
const { objectProperties } = element.setting;
179+
const allStaticKeys = Object.keys(objectProperties ?? {});
180+
181+
return keys => {
182+
const existingKeys = new Set(keys);
183+
const enumOptions: IObjectEnumOption[] = [];
184+
185+
allStaticKeys.forEach(staticKey => {
186+
if (!existingKeys.has(staticKey)) {
187+
enumOptions.push({ value: staticKey, description: objectProperties![staticKey].description });
188+
}
189+
});
190+
191+
return enumOptions.length > 0
192+
? { type: 'enum', data: enumOptions[0].value, options: enumOptions }
193+
: undefined;
194+
};
195+
}
196+
177197
function createObjectValueSuggester(element: SettingsTreeSettingElement): IObjectValueSuggester {
178198
const { objectProperties, objectPatternProperties, objectAdditionalProperties } = element.setting;
179199

@@ -204,8 +224,11 @@ function createObjectValueSuggester(element: SettingsTreeSettingElement): IObjec
204224

205225
if (type === 'boolean') {
206226
return { type, data: suggestedSchema.default ?? true };
227+
} else if (type === 'enum') {
228+
const options = getEnumOptionsFromSchema(suggestedSchema);
229+
return { type, data: suggestedSchema.default ?? options[0].value, options };
207230
} else {
208-
return { type, data: suggestedSchema.default ?? '', options: getEnumOptionsFromSchema(suggestedSchema) };
231+
return { type, data: suggestedSchema.default ?? '' };
209232
}
210233
}
211234

@@ -1084,6 +1107,7 @@ export class SettingObjectRenderer extends AbstractSettingRenderer implements IT
10841107
isDefined(dataElement.setting.objectPatternProperties) ||
10851108
!areAllPropertiesDefined(Object.keys(dataElement.setting.objectProperties ?? {}), items)
10861109
),
1110+
keySuggester: createObjectKeySuggester(dataElement),
10871111
valueSuggester: createObjectValueSuggester(dataElement),
10881112
});
10891113

src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,8 +659,13 @@ export interface IObjectValueSuggester {
659659
(key: string): ObjectValue | undefined;
660660
}
661661

662+
export interface IObjectKeySuggester {
663+
(existingKeys: string[]): IObjectEnumData | undefined;
664+
}
665+
662666
interface IObjectSetValueOptions {
663667
showAddButton: boolean;
668+
keySuggester: IObjectKeySuggester;
664669
valueSuggester: IObjectValueSuggester;
665670
}
666671

@@ -674,10 +679,12 @@ interface IObjectRenderEditWidgetOptions {
674679

675680
export class ObjectSettingWidget extends AbstractListSettingWidget<IObjectDataItem> {
676681
private showAddButton: boolean = true;
677-
private valueSuggester: IObjectValueSuggester = () => undefined;;
682+
private keySuggester: IObjectKeySuggester = () => undefined;
683+
private valueSuggester: IObjectValueSuggester = () => undefined;
678684

679685
setValue(listData: IObjectDataItem[], options?: IObjectSetValueOptions): void {
680686
this.showAddButton = options?.showAddButton ?? this.showAddButton;
687+
this.keySuggester = options?.keySuggester ?? this.keySuggester;
681688
this.valueSuggester = options?.valueSuggester ?? this.valueSuggester;
682689
super.setValue(listData);
683690
}
@@ -784,7 +791,17 @@ export class ObjectSettingWidget extends AbstractListSettingWidget<IObjectDataIt
784791
let keyElement: HTMLElement;
785792

786793
if (this.showAddButton) {
787-
const { widget, element } = this.renderEditWidget(item.key, {
794+
if (this.isItemNew(item)) {
795+
const suggestedKey = this.keySuggester(this.model.items.map(({ key: { data } }) => data));
796+
797+
if (isDefined(suggestedKey)) {
798+
changedItem.key = suggestedKey;
799+
const suggestedValue = this.valueSuggester(changedItem.key.data);
800+
onValueChange(suggestedValue ?? changedItem.value);
801+
}
802+
}
803+
804+
const { widget, element } = this.renderEditWidget(changedItem.key, {
788805
idx,
789806
isKey: true,
790807
originalItem: item,

0 commit comments

Comments
 (0)