diff --git a/CHANGELOG.md b/CHANGELOG.md index 091b86a..11b5682 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ - Start screen of Settings UI will use the cached list of configs instead of reloading them - This should make navigating to the start screen (especially when navigating back and forth between configs) faster - The Refresh button is now renamed to Reload and will still reload the configs (from disk, remote workspaces, ...) +- Add support for extending configs to the Settings UI (#268) + - This adds a visual editor to the Settings UI for the `extend` config option ### Development changes diff --git a/common/src/fileSystemConfig.ts b/common/src/fileSystemConfig.ts index ae256c3..d5db4b7 100644 --- a/common/src/fileSystemConfig.ts +++ b/common/src/fileSystemConfig.ts @@ -89,7 +89,7 @@ export interface FileSystemConfig extends ConnectConfig { group?: string; /** Whether to merge this "lower" config (e.g. from workspace settings) into higher configs (e.g. from global settings) */ merge?: boolean; - /** Names of other configs to merge into this config. Errors if not found. Later entries have priority. Settings defined in this config itself have even higher priority */ + /** Names of other existing configs to merge into this config. Earlier entries overridden by later entries overridden by this config itself */ extend?: string | string[]; /** Path on the remote server that should be opened by default when creating a terminal or using the `Add as Workspace folder` command/button. Defaults to `/` */ root?: string; diff --git a/webview/src/ConfigEditor/fields.tsx b/webview/src/ConfigEditor/fields.tsx index 3251f6d..2cabbc8 100644 --- a/webview/src/ConfigEditor/fields.tsx +++ b/webview/src/ConfigEditor/fields.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import { FieldCheckbox } from '../FieldTypes/checkbox'; import { FieldDropdown } from '../FieldTypes/dropdown'; import { FieldDropdownWithInput } from '../FieldTypes/dropdownwithinput'; +import { FieldConfigList } from '../FieldTypes/list'; import { FieldNumber } from '../FieldTypes/number'; import { FieldPath } from '../FieldTypes/path'; import { FieldString } from '../FieldTypes/string'; @@ -27,14 +28,6 @@ export function name(config: FileSystemConfig, onChange: FSCChanged<'name'>): Re return } -export function merge(config: FileSystemConfig, onChange: FSCChanged<'merge'>): React.ReactElement { - const callback = (newValue: string) => onChange('merge', newValue === 'Yes' || undefined); - const description = 'Whether to merge this "lower" config (e.g. from workspace settings) into higher configs (e.g. from global settings)'; - const values = ['Yes', 'No']; - const value = config.merge ? 'Yes' : 'No'; - return -} - export function label(config: FileSystemConfig, onChange: FSCChanged<'label'>): React.ReactElement { const callback = (newValue?: string) => onChange('label', newValue); const description = 'Label to display in some UI places (e.g. popups)'; @@ -47,6 +40,21 @@ export function group(config: FileSystemConfig, onChange: FSCChanged<'group'>): return } +export function merge(config: FileSystemConfig, onChange: FSCChanged<'merge'>): React.ReactElement { + const callback = (newValue: string) => onChange('merge', newValue === 'Yes' || undefined); + const description = 'Whether to merge this "lower" config (e.g. from workspace settings) into higher configs (e.g. from global settings)'; + const values = ['Yes', 'No']; + const value = config.merge ? 'Yes' : 'No'; + return +} + +export function extend(config: FileSystemConfig, onChange: FSCChanged<'extend'>): React.ReactElement { + const callback = (newValue?: string | string[]) => onChange('extend', newValue); + const description = 'Names of other existing configs to merge into this config. Earlier entries overridden by later entries overridden by this config itself'; + const value = typeof config.extend === 'string' ? [config.extend] : config.extend; + return +} + export function putty(config: FileSystemConfig, onChange: FSCChanged<'putty'>): React.ReactElement { const callback = (newValue: string) => onChange('putty', newValue === '' ? true : newValue); const description = 'A name of a PuTTY session, or `true` to find the PuTTY session from the host address'; @@ -163,7 +171,7 @@ export function taskCommand(config: FileSystemConfig, onChange: FSCChanged<'task export type FieldFactory = (config: FileSystemConfig, onChange: FSCChanged, onChangeMultiple: FSCChangedMultiple) => React.ReactElement | null; export const FIELDS: FieldFactory[] = [ - name, merge, label, group, putty, host, port, + name, label, group, merge, extend, putty, host, port, root, agent, username, password, privateKeyPath, passphrase, newFileMode, agentForward, sftpCommand, sftpSudo, terminalCommand, taskCommand, PROXY_FIELD];