mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
accessibility setting based select database dropdown (#2579)
This commit is contained in:
5
src/sql/parts/query/editor/media/queryActions.css
Normal file
5
src/sql/parts/query/editor/media/queryActions.css
Normal file
@@ -0,0 +1,5 @@
|
||||
.monaco-select-box {
|
||||
cursor: pointer;
|
||||
min-width: 150px;
|
||||
padding: 2px;
|
||||
}
|
||||
@@ -43,7 +43,6 @@ import {
|
||||
import { IQueryModelService } from 'sql/parts/query/execution/queryModel';
|
||||
import { IEditorDescriptorService } from 'sql/parts/query/editor/editorDescriptorService';
|
||||
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
|
||||
import { attachEditableDropdownStyler } from 'sql/common/theme/styler';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
@@ -500,7 +499,7 @@ export class QueryEditor extends BaseEditor {
|
||||
public get listDatabasesActionItem(): ListDatabasesActionItem {
|
||||
if (!this._listDatabasesActionItem) {
|
||||
this._listDatabasesActionItem = this._instantiationService.createInstance(ListDatabasesActionItem, this, this._listDatabasesAction);
|
||||
this._register(attachEditableDropdownStyler(this._listDatabasesActionItem, this.themeService));
|
||||
this._register(this._listDatabasesActionItem.attachStyler(this.themeService));
|
||||
}
|
||||
return this._listDatabasesActionItem;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!sql/parts/query/editor/media/queryActions';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Builder, $ } from 'vs/base/browser/builder';
|
||||
import { Dropdown } from 'sql/base/browser/ui/editableDropdown/dropdown';
|
||||
@@ -12,6 +13,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { attachEditableDropdownStyler, attachSelectBoxStyler } from 'sql/common/theme/styler';
|
||||
|
||||
import { ISelectionData } from 'sqlops';
|
||||
import {
|
||||
@@ -25,6 +27,8 @@ import { QueryEditor } from 'sql/parts/query/editor/queryEditor';
|
||||
import { IQueryModelService } from 'sql/parts/query/execution/queryModel';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
/**
|
||||
* Action class that query-based Actions will extend. This base class automatically handles activating and
|
||||
@@ -431,6 +435,9 @@ export class ListDatabasesActionItem extends EventEmitter implements IActionItem
|
||||
private _isConnected: boolean;
|
||||
private $databaseListDropdown: Builder;
|
||||
private _dropdown: Dropdown;
|
||||
private _databaseSelectBox: SelectBox;
|
||||
private _isInAccessibilityMode: boolean;
|
||||
private readonly _selectDatabaseString: string = nls.localize("selectDatabase", "Select Database");
|
||||
|
||||
// CONSTRUCTOR /////////////////////////////////////////////////////////
|
||||
constructor(
|
||||
@@ -439,23 +446,33 @@ export class ListDatabasesActionItem extends EventEmitter implements IActionItem
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@INotificationService private _notificationService: INotificationService,
|
||||
@IContextViewService contextViewProvider: IContextViewService,
|
||||
@IThemeService themeService: IThemeService
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
this._toDispose = [];
|
||||
this.$databaseListDropdown = $('.databaseListDropdown');
|
||||
let selectString = nls.localize("selectDatabase", "Select Database");
|
||||
this._isInAccessibilityMode = this._configurationService.getValue('editor.accessibilitySupport') === 'on';
|
||||
|
||||
if (this._isInAccessibilityMode) {
|
||||
this._databaseSelectBox = new SelectBox([this._selectDatabaseString], this._selectDatabaseString, contextViewProvider, undefined, { ariaLabel: this._selectDatabaseString });
|
||||
this._databaseSelectBox.render(this.$databaseListDropdown.getHTMLElement());
|
||||
this._databaseSelectBox.onDidSelect(e => { this.databaseSelected(e.selected); });
|
||||
this._databaseSelectBox.disable();
|
||||
|
||||
} else {
|
||||
this._dropdown = new Dropdown(this.$databaseListDropdown.getHTMLElement(), contextViewProvider, themeService, {
|
||||
strictSelection: true,
|
||||
placeholder: selectString,
|
||||
ariaLabel: selectString,
|
||||
placeholder: this._selectDatabaseString,
|
||||
ariaLabel: this._selectDatabaseString,
|
||||
actionLabel: nls.localize('listDatabases.toggleDatabaseNameDropdown', 'Select Database Toggle Dropdown')
|
||||
});
|
||||
this._dropdown.onValueChange(s => this.databaseSelected(s));
|
||||
this._toDispose.push(this._dropdown.onFocus(() => { self.onDropdownFocus(); }));
|
||||
}
|
||||
|
||||
// Register event handlers
|
||||
let self = this;
|
||||
this._toDispose.push(this._dropdown.onFocus(() => { self.onDropdownFocus(); }));
|
||||
this._toDispose.push(this._connectionManagementService.onConnectionChanged(params => { self.onConnectionChanged(params); }));
|
||||
}
|
||||
|
||||
@@ -465,8 +482,13 @@ export class ListDatabasesActionItem extends EventEmitter implements IActionItem
|
||||
}
|
||||
|
||||
public style(styles) {
|
||||
if (this._isInAccessibilityMode) {
|
||||
this._databaseSelectBox.style(styles);
|
||||
}
|
||||
else {
|
||||
this._dropdown.style(styles);
|
||||
}
|
||||
}
|
||||
|
||||
public setActionContext(context: any): void {
|
||||
this._context = context;
|
||||
@@ -477,12 +499,28 @@ export class ListDatabasesActionItem extends EventEmitter implements IActionItem
|
||||
}
|
||||
|
||||
public focus(): void {
|
||||
if (this._isInAccessibilityMode) {
|
||||
this._databaseSelectBox.focus();
|
||||
} else {
|
||||
this._dropdown.focus();
|
||||
}
|
||||
}
|
||||
|
||||
public blur(): void {
|
||||
if (this._isInAccessibilityMode) {
|
||||
this._databaseSelectBox.blur();
|
||||
} else {
|
||||
this._dropdown.blur();
|
||||
}
|
||||
}
|
||||
|
||||
public attachStyler(themeService: IThemeService): IDisposable {
|
||||
if (this._isInAccessibilityMode) {
|
||||
return attachSelectBoxStyler(this, themeService);
|
||||
} else {
|
||||
return attachEditableDropdownStyler(this, themeService);
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose = dispose(this._toDispose);
|
||||
@@ -496,10 +534,16 @@ export class ListDatabasesActionItem extends EventEmitter implements IActionItem
|
||||
|
||||
public onDisconnect(): void {
|
||||
this._isConnected = false;
|
||||
this._dropdown.enabled = false;
|
||||
this._currentDatabaseName = undefined;
|
||||
|
||||
if (this._isInAccessibilityMode) {
|
||||
this._databaseSelectBox.disable();
|
||||
this._databaseSelectBox.setOptions([this._selectDatabaseString]);
|
||||
} else {
|
||||
this._dropdown.enabled = false;
|
||||
this._dropdown.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE HELPERS /////////////////////////////////////////////////////
|
||||
private databaseSelected(dbName: string): void {
|
||||
@@ -545,8 +589,12 @@ export class ListDatabasesActionItem extends EventEmitter implements IActionItem
|
||||
}
|
||||
|
||||
private resetDatabaseName() {
|
||||
if (this._isInAccessibilityMode) {
|
||||
this._databaseSelectBox.selectWithOptionName(this.getCurrentDatabaseName());
|
||||
} else {
|
||||
this._dropdown.value = this.getCurrentDatabaseName();
|
||||
}
|
||||
}
|
||||
|
||||
private onConnectionChanged(connParams: IConnectionParams): void {
|
||||
if (!connParams) {
|
||||
@@ -579,10 +627,27 @@ export class ListDatabasesActionItem extends EventEmitter implements IActionItem
|
||||
|
||||
private updateConnection(databaseName: string) {
|
||||
this._isConnected = true;
|
||||
this._dropdown.enabled = true;
|
||||
this._currentDatabaseName = databaseName;
|
||||
|
||||
if (this._isInAccessibilityMode) {
|
||||
this._databaseSelectBox.enable();
|
||||
let self = this;
|
||||
let uri = self._editor.connectedUri;
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
self._connectionManagementService.listDatabases(uri)
|
||||
.then(result => {
|
||||
if (result && result.databaseNames) {
|
||||
this._databaseSelectBox.setOptions(result.databaseNames);
|
||||
}
|
||||
this._databaseSelectBox.selectWithOptionName(databaseName);
|
||||
});
|
||||
} else {
|
||||
this._dropdown.enabled = true;
|
||||
this._dropdown.value = databaseName;
|
||||
}
|
||||
}
|
||||
|
||||
// TESTING PROPERTIES //////////////////////////////////////////////////
|
||||
public get currentDatabaseName(): string {
|
||||
|
||||
@@ -28,6 +28,7 @@ import { ConnectionManagementService } from 'sql/parts/connection/common/connect
|
||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||
|
||||
import { TestThemeService } from 'sqltest/stubs/themeTestService';
|
||||
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
|
||||
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import * as assert from 'assert';
|
||||
@@ -40,6 +41,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
let editor: TypeMoq.Mock<QueryEditor>;
|
||||
let calledRunQueryOnInput: boolean = undefined;
|
||||
let testQueryInput: TypeMoq.Mock<QueryInput>;
|
||||
let configurationService: TypeMoq.Mock<ConfigurationService>;
|
||||
|
||||
setup(() => {
|
||||
// Setup a reusable mock QueryInput
|
||||
@@ -56,6 +58,13 @@ suite('SQL QueryAction Tests', () => {
|
||||
editor.setup(x => x.getSelection()).returns(() => undefined);
|
||||
editor.setup(x => x.getSelection(false)).returns(() => undefined);
|
||||
editor.setup(x => x.isSelectionEmpty()).returns(() => false);
|
||||
configurationService = TypeMoq.Mock.ofInstance({
|
||||
getValue: () => undefined,
|
||||
onDidChangeConfiguration: () => undefined
|
||||
} as any);
|
||||
configurationService.setup(x => x.getValue(TypeMoq.It.isAny())).returns(() => {
|
||||
return {};
|
||||
});
|
||||
});
|
||||
|
||||
test('setClass sets child CSS class correctly', (done) => {
|
||||
@@ -463,7 +472,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
});
|
||||
|
||||
// If I query without having initialized anything, state should be clear
|
||||
listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, undefined, undefined);
|
||||
listItem = new ListDatabasesActionItem(editor.object, undefined, connectionManagementService.object, undefined, undefined, undefined, configurationService.object);
|
||||
|
||||
assert.equal(listItem.isEnabled(), false, 'do not expect dropdown enabled unless connected');
|
||||
assert.equal(listItem.currentDatabaseName, undefined, 'do not expect dropdown to have entries unless connected');
|
||||
@@ -498,7 +507,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
cms.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
||||
|
||||
// ... Create a database dropdown that has been connected
|
||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, cms.object, null, null, null);
|
||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, cms.object, null, null, null, configurationService.object);
|
||||
listItem.onConnected();
|
||||
|
||||
// If: I raise a connection changed event
|
||||
@@ -522,7 +531,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
cms.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => <IConnectionProfile>{ databaseName: databaseName });
|
||||
|
||||
// ... Create a database dropdown that has been connected
|
||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, cms.object, null, null, null);
|
||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, cms.object, null, null, null, configurationService.object);
|
||||
listItem.onConnected();
|
||||
|
||||
// If: I raise a connection changed event for the 'wrong' URI
|
||||
@@ -549,7 +558,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
cms.setup(x => x.onConnectionChanged).returns(() => dbChangedEmitter.event);
|
||||
|
||||
// ... Create a database dropdown
|
||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, cms.object, null, null, null);
|
||||
let listItem = new ListDatabasesActionItem(editor.object, undefined, cms.object, null, null, null, configurationService.object);
|
||||
|
||||
// If: I raise a connection changed event
|
||||
let eventParams = <IConnectionParams>{
|
||||
|
||||
@@ -93,7 +93,7 @@ suite('SQL QueryEditor Tests', () => {
|
||||
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((classDef, editor, action) => {
|
||||
if (classDef.ID) {
|
||||
if (classDef.ID === 'listDatabaseQueryActionItem') {
|
||||
return new ListDatabasesActionItem(editor, action, connectionManagementService.object, undefined, undefined, undefined);
|
||||
return new ListDatabasesActionItem(editor, action, connectionManagementService.object, undefined, undefined, undefined, configurationService.object);
|
||||
}
|
||||
}
|
||||
// Default
|
||||
@@ -344,7 +344,7 @@ suite('SQL QueryEditor Tests', () => {
|
||||
queryActionInstantiationService.setup(x => x.createInstance(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
|
||||
.returns((definition, editor, action, selectBox) => {
|
||||
if (definition.ID === 'listDatabaseQueryActionItem') {
|
||||
let item = new ListDatabasesActionItem(editor, action, queryConnectionService.object, undefined, undefined, undefined);
|
||||
let item = new ListDatabasesActionItem(editor, action, queryConnectionService.object, undefined, undefined, undefined,configurationService.object);
|
||||
return item;
|
||||
}
|
||||
// Default
|
||||
|
||||
Reference in New Issue
Block a user