mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Adding on change event in editable dropdowns when value is changes through code. (#14952)
* Adding onChange events in editable dropdowns for values changed through code. * moved event generation from angular wrapper to core component * Moving event firing to value setter * converting back updateSelection to private method * Removing extra check * Fixing broken tests by mocking used stuff * Fixing onTextChange event * Adding some tests * Adding necessary tests * small test name edit * Fix an assert message
This commit is contained in:
@@ -98,11 +98,13 @@ export class SKURecommendationPage extends MigrationWizardPage {
|
|||||||
width: WIZARD_INPUT_COMPONENT_WIDTH
|
width: WIZARD_INPUT_COMPONENT_WIDTH
|
||||||
}).component();
|
}).component();
|
||||||
this._managedInstanceSubscriptionDropdown = view.modelBuilder.dropDown().withProps({
|
this._managedInstanceSubscriptionDropdown = view.modelBuilder.dropDown().withProps({
|
||||||
width: WIZARD_INPUT_COMPONENT_WIDTH
|
width: WIZARD_INPUT_COMPONENT_WIDTH,
|
||||||
|
editable: true
|
||||||
}).component();
|
}).component();
|
||||||
this._managedInstanceSubscriptionDropdown.onValueChanged((e) => {
|
this._managedInstanceSubscriptionDropdown.onValueChanged((e) => {
|
||||||
if (e.selected) {
|
if (e) {
|
||||||
this.migrationStateModel._targetSubscription = this.migrationStateModel.getSubscription(e.index);
|
const selectedIndex = (<azdata.CategoryValue[]>this._managedInstanceSubscriptionDropdown.values)?.findIndex(v => v.displayName === e);
|
||||||
|
this.migrationStateModel._targetSubscription = this.migrationStateModel.getSubscription(selectedIndex);
|
||||||
this.migrationStateModel._targetServerInstance = undefined!;
|
this.migrationStateModel._targetServerInstance = undefined!;
|
||||||
this.migrationStateModel._sqlMigrationService = undefined!;
|
this.migrationStateModel._sqlMigrationService = undefined!;
|
||||||
this.populateLocationAndResourceGroupDropdown();
|
this.populateLocationAndResourceGroupDropdown();
|
||||||
@@ -393,6 +395,7 @@ export class SKURecommendationPage extends MigrationWizardPage {
|
|||||||
this._resourceDropdown.loading = true;
|
this._resourceDropdown.loading = true;
|
||||||
try {
|
try {
|
||||||
this._managedInstanceSubscriptionDropdown.values = await this.migrationStateModel.getSubscriptionsDropdownValues();
|
this._managedInstanceSubscriptionDropdown.values = await this.migrationStateModel.getSubscriptionsDropdownValues();
|
||||||
|
this._managedInstanceSubscriptionDropdown.value = this._managedInstanceSubscriptionDropdown.values[0];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ export class Dropdown extends Disposable implements IListVirtualDelegate<string>
|
|||||||
private _options: IDropdownOptions;
|
private _options: IDropdownOptions;
|
||||||
private _dataSource = new DropdownDataSource();
|
private _dataSource = new DropdownDataSource();
|
||||||
public fireOnTextChange?: boolean;
|
public fireOnTextChange?: boolean;
|
||||||
|
private _previousValue: string;
|
||||||
|
|
||||||
private _onBlur = this._register(new Emitter<void>());
|
private _onBlur = this._register(new Emitter<void>());
|
||||||
public onBlur: Event<void> = this._onBlur.event;
|
public onBlur: Event<void> = this._onBlur.event;
|
||||||
@@ -228,7 +229,6 @@ export class Dropdown extends Disposable implements IListVirtualDelegate<string>
|
|||||||
}
|
}
|
||||||
if (this.fireOnTextChange) {
|
if (this.fireOnTextChange) {
|
||||||
this.value = e;
|
this.value = e;
|
||||||
this._onValueChange.fire(e);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -253,7 +253,7 @@ export class Dropdown extends Disposable implements IListVirtualDelegate<string>
|
|||||||
return this._selectListContainer.classList.contains('visible');
|
return this._selectListContainer.classList.contains('visible');
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setDropdownVisibility(visible: boolean): void {
|
public setDropdownVisibility(visible: boolean): void {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
this._selectListContainer.classList.add('visible');
|
this._selectListContainer.classList.add('visible');
|
||||||
} else {
|
} else {
|
||||||
@@ -264,7 +264,6 @@ export class Dropdown extends Disposable implements IListVirtualDelegate<string>
|
|||||||
|
|
||||||
private _updateSelection(newValue: string): void {
|
private _updateSelection(newValue: string): void {
|
||||||
this.value = newValue;
|
this.value = newValue;
|
||||||
this._onValueChange.fire(newValue);
|
|
||||||
this._input.focus();
|
this._input.focus();
|
||||||
this._hideList();
|
this._hideList();
|
||||||
}
|
}
|
||||||
@@ -277,12 +276,12 @@ export class Dropdown extends Disposable implements IListVirtualDelegate<string>
|
|||||||
this.contextViewService.showContextView({
|
this.contextViewService.showContextView({
|
||||||
getAnchor: () => this._inputContainer,
|
getAnchor: () => this._inputContainer,
|
||||||
render: container => {
|
render: container => {
|
||||||
this._setDropdownVisibility(true);
|
this.setDropdownVisibility(true);
|
||||||
DOM.append(container, this._selectListContainer);
|
DOM.append(container, this._selectListContainer);
|
||||||
this._updateDropDownList();
|
this._updateDropDownList();
|
||||||
return {
|
return {
|
||||||
dispose: () => {
|
dispose: () => {
|
||||||
this._setDropdownVisibility(false);
|
this.setDropdownVisibility(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -332,7 +331,11 @@ export class Dropdown extends Disposable implements IListVirtualDelegate<string>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public set value(val: string) {
|
public set value(val: string) {
|
||||||
this._input.value = val;
|
if (this._previousValue !== val) {
|
||||||
|
this._input.value = val;
|
||||||
|
this._previousValue = val;
|
||||||
|
this._onValueChange.fire(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get inputElement(): HTMLInputElement {
|
public get inputElement(): HTMLInputElement {
|
||||||
@@ -384,4 +387,12 @@ export class Dropdown extends Disposable implements IListVirtualDelegate<string>
|
|||||||
public set ariaLabel(val: string) {
|
public set ariaLabel(val: string) {
|
||||||
this._input.setAriaLabel(val);
|
this._input.setAriaLabel(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get input(): InputBox {
|
||||||
|
return this._input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get selectList(): List<IDropdownListItem> {
|
||||||
|
return this._selectList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { Dropdown, IDropdownOptions } from 'sql/base/parts/editableDropdown/browser/dropdown';
|
||||||
|
|
||||||
|
const options: IDropdownOptions = {
|
||||||
|
values: [
|
||||||
|
'foo1',
|
||||||
|
'foo2',
|
||||||
|
'foobar3',
|
||||||
|
'foobar4'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
suite('Editable dropdown tests', () => {
|
||||||
|
let container: HTMLElement;
|
||||||
|
setup(() => {
|
||||||
|
container = document.createElement('div');
|
||||||
|
container.style.position = 'absolute';
|
||||||
|
container.style.width = `${200}px`;
|
||||||
|
container.style.height = `${200}px`;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('default value for editable dropdown is empty', () => {
|
||||||
|
const dropdown = new Dropdown(container, undefined, options);
|
||||||
|
assert(dropdown.value === '');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('changing value through code fires onValueChange event', () => {
|
||||||
|
const dropdown = new Dropdown(container, undefined, options);
|
||||||
|
let count = 0;
|
||||||
|
dropdown.onValueChange((e) => {
|
||||||
|
count++;
|
||||||
|
});
|
||||||
|
dropdown.value = options.values[0];
|
||||||
|
|
||||||
|
assert(count === 1, 'onValueChange event was not fired');
|
||||||
|
dropdown.value = options.values[0];
|
||||||
|
assert(count === 1, 'onValueChange event should not be fired for setting the same value again');
|
||||||
|
dropdown.value = options.values[1];
|
||||||
|
assert(count === 2, 'onValueChange event was not fired for setting a new value of the dropdown');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('changing value through input text fires onValue Change event', () => {
|
||||||
|
const dropdown = new Dropdown(container, undefined, options);
|
||||||
|
let count = 0;
|
||||||
|
dropdown.onValueChange((e) => {
|
||||||
|
count++;
|
||||||
|
});
|
||||||
|
|
||||||
|
dropdown.fireOnTextChange = true;
|
||||||
|
dropdown.setDropdownVisibility(true);
|
||||||
|
dropdown.input.value = options.values[0];
|
||||||
|
assert(count === 1, 'onValueChange event was not fired for an option from the dropdown list');
|
||||||
|
dropdown.input.value = 'foo';
|
||||||
|
assert(count === 2, 'onValueChange event was not fired for a value not in dropdown list');
|
||||||
|
assert(dropdown.selectList.length === 4, 'list does not have all the values that are matching the input box text');
|
||||||
|
assert(dropdown.value = 'foo');
|
||||||
|
dropdown.input.value = 'foobar';
|
||||||
|
assert(count === 3, 'onValueChange event was not fired for a value not in dropdown list');
|
||||||
|
assert(dropdown.selectList.length === 2, 'list does not have all the values that are matching the input box text');
|
||||||
|
assert(dropdown.value = 'foobar');
|
||||||
|
|
||||||
|
dropdown.fireOnTextChange = false;
|
||||||
|
dropdown.input.value = options.values[0];
|
||||||
|
assert(count === 3, 'onValueChange event was fired with input box value change even after setting the fireOnTextChange to false');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -466,6 +466,7 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{
|
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{
|
||||||
databaseName: databaseName
|
databaseName: databaseName
|
||||||
});
|
});
|
||||||
|
connectionManagementService.setup(x => x.changeDatabase(TypeMoq.It.isAnyString(), TypeMoq.It.isAnyString())).returns(() => Promise.resolve(true));
|
||||||
|
|
||||||
// If I query without having initialized anything, state should be clear
|
// If I query without having initialized anything, state should be clear
|
||||||
listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, configurationService.object, undefined);
|
listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, configurationService.object, undefined);
|
||||||
@@ -497,6 +498,7 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let databaseName = 'foobar';
|
let databaseName = 'foobar';
|
||||||
connectionManagementService.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
connectionManagementService.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
||||||
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
||||||
|
connectionManagementService.setup(x => x.changeDatabase(TypeMoq.It.isAnyString(), TypeMoq.It.isAnyString())).returns(() => Promise.resolve(true));
|
||||||
|
|
||||||
// ... Create a database dropdown that has been connected
|
// ... Create a database dropdown that has been connected
|
||||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, configurationService.object, undefined);
|
let listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, configurationService.object, undefined);
|
||||||
@@ -519,6 +521,7 @@ suite('SQL QueryAction Tests', () => {
|
|||||||
let databaseName = 'foobar';
|
let databaseName = 'foobar';
|
||||||
connectionManagementService.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
connectionManagementService.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
||||||
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
||||||
|
connectionManagementService.setup(x => x.changeDatabase(TypeMoq.It.isAnyString(), TypeMoq.It.isAnyString())).returns(() => Promise.resolve(true));
|
||||||
|
|
||||||
// ... Create a database dropdown that has been connected
|
// ... Create a database dropdown that has been connected
|
||||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, configurationService.object, undefined);
|
let listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, configurationService.object, undefined);
|
||||||
|
|||||||
Reference in New Issue
Block a user