diff --git a/src/sql/base/browser/ui/selectBox/selectBox.ts b/src/sql/base/browser/ui/selectBox/selectBox.ts index 8562fa91fd..3505136085 100644 --- a/src/sql/base/browser/ui/selectBox/selectBox.ts +++ b/src/sql/base/browser/ui/selectBox/selectBox.ts @@ -5,7 +5,7 @@ import 'vs/css!./media/selectBox'; -import { SelectBox as vsSelectBox, ISelectBoxStyles as vsISelectBoxStyles, ISelectBoxOptions, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox'; +import { SelectBox as vsSelectBox, ISelectBoxStyles as vsISelectBoxStyles, ISelectBoxOptions, ISelectOptionItem, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox'; import { Color } from 'vs/base/common/color'; import { IContextViewProvider, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; import * as dom from 'vs/base/browser/dom'; @@ -38,8 +38,6 @@ export interface ISelectBoxStyles extends vsISelectBoxStyles { inputValidationErrorForeground?: Color; } -export class SelectBoxEmptyError extends Error { } - export class SelectBox extends vsSelectBox { private _optionsDictionary: Map; private _dialogOptions: SelectOptionItemSQL[]; @@ -67,30 +65,18 @@ export class SelectBox extends vsSelectBox { private element?: HTMLElement; constructor(options: SelectOptionItemSQL[] | string[], selectedOption: string, contextViewProvider: IContextViewProvider, container?: HTMLElement, selectBoxOptions?: ISelectBoxOptions) { - let optionItems: SelectOptionItemSQL[]; - - if (Array.isArray(options) && typeof (options[0]) === 'string') { - optionItems = (options).map(o => { - return { text: o, value: o } as SelectOptionItemSQL; - }); - } else { - optionItems = options as SelectOptionItemSQL[]; - } - + let optionItems: SelectOptionItemSQL[] = SelectBox.createOptions(options); super(optionItems, 0, contextViewProvider, undefined, selectBoxOptions); - this._optionsDictionary = new Map(); - for (let i = 0; i < options.length; i++) { - this._optionsDictionary.set(optionItems[i].value, i); - } + + this.populateOptionsDictionary(optionItems); const option = this._optionsDictionary.get(selectedOption); if (option) { super.select(option); } + this._selectedOption = selectedOption; - this._dialogOptions = optionItems; - this._register(this.onDidSelect(newInput => { - const selected = optionItems[newInput.index]; - this._selectedOption = selected.value; + this._register(this.onDidSelect(newSelect => { + this.onSelect(newSelect); })); this.enabledSelectBackground = this.selectBackground; @@ -133,6 +119,38 @@ export class SelectBox extends vsSelectBox { } } + public onSelect(newInput: ISelectData) { + const selected = this._dialogOptions[newInput.index]; + this._selectedOption = selected.value; + } + + private static createOptions(options: SelectOptionItemSQL[] | string[] | ISelectOptionItem[]): SelectOptionItemSQL[] { + let selectOptions: SelectOptionItemSQL[]; + if (Array.isArray(options) && typeof (options[0]) === 'string') { + selectOptions = options.map(o => { + return { text: o, value: o } as SelectOptionItemSQL; + }); + } else { // Handle both SelectOptionItemSql and ISelectOptionItem + const temp = (options as SelectOptionItemSQL[]); + selectOptions = temp.map(opt => { + if (opt.value === undefined) { + opt.value = opt.text; + } + return opt; + }); + } + + return selectOptions; + } + + public populateOptionsDictionary(options: SelectOptionItemSQL[]) { + this._optionsDictionary = new Map(); + for (let i = 0; i < options.length; i++) { + this._optionsDictionary.set(options[i].value, i); + } + this._dialogOptions = options; + } + public style(styles: ISelectBoxStyles): void { super.style(styles); this.enabledSelectBackground = this.selectBackground; @@ -168,18 +186,10 @@ export class SelectBox extends vsSelectBox { } } - public setOptions(options: string[] | ISelectOptionItem[], selected?: number): void { - let selectOptions: SelectOptionItemSQL[]; - if (options.length > 0 && typeof options[0] !== 'string') { - selectOptions = options as SelectOptionItemSQL[]; - } else { - selectOptions = (options as string[]).map(o => { return { text: o, value: o } as SelectOptionItemSQL; }); - } - this._optionsDictionary = new Map(); - for (let i = 0; i < selectOptions.length; i++) { - this._optionsDictionary.set(selectOptions[i].value, i); - } - this._dialogOptions = selectOptions; + + public setOptions(options: string[] | SelectOptionItemSQL[] | ISelectOptionItem[], selected?: number): void { + let selectOptions: SelectOptionItemSQL[] = SelectBox.createOptions(options); + this.populateOptionsDictionary(selectOptions); super.setOptions(selectOptions, selected); } diff --git a/src/sql/base/test/browser/ui/selectBox/selectBox.test.ts b/src/sql/base/test/browser/ui/selectBox/selectBox.test.ts new file mode 100644 index 0000000000..ab10eb352f --- /dev/null +++ b/src/sql/base/test/browser/ui/selectBox/selectBox.test.ts @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { SelectBox, SelectOptionItemSQL } from 'sql/base/browser/ui/selectBox/selectBox'; +import { deepClone, equals } from 'vs/base/common/objects'; + +const options: SelectOptionItemSQL[] = [ + { text: 't1', value: 'v1' }, + { text: 't2', value: 'v2' } +]; + +suite('Select Box tests', () => { + test('default value', () => { + + const sb = new SelectBox(options, options[1].value, undefined, undefined, undefined); + + assert(sb.value === options[1].value); + }); + + test('values change', () => { + const sb = new SelectBox(options, options[1].value, undefined, undefined, undefined); + const newOptions = deepClone(options); + { + const moreOptions: SelectOptionItemSQL[] = [ + { text: 't3', value: 'v3' }, + { text: 't4', value: 'v4' } + ]; + + newOptions.push(...moreOptions); + } + + sb.setOptions(newOptions); + assert(equals(sb.values, newOptions.map(s => s.value))); + }); + + test('the selected option changes', () => { + const sb = new SelectBox(options, options[1].value, undefined, undefined, undefined); + + sb.onSelect({ + index: 0, + selected: options[0].value + }); + + assert(sb.value === options[0].value); + }); + + test('values get auto populated', () => { + const newOptions = deepClone(options).map(s => { return { text: s.text, value: undefined }; }); + const sb = new SelectBox(newOptions, undefined, undefined, undefined, undefined); + + assert(equals(sb.values, newOptions.map(s => s.text))); + }); +});