Connection Dialog: Dropdown for database name (#583)

* dropdown now lets databases

* show databases for SQL Login too

* localized strings

* removed unnecesssary logic

* fixed dropdown height, case-insensitive filter and alignement

* added cache for connections
This commit is contained in:
Aditya Bist
2018-02-07 06:21:03 +05:30
committed by GitHub
parent 579e6bf0cb
commit a8c7c69509
4 changed files with 85 additions and 18 deletions

View File

@@ -36,7 +36,7 @@ export class DropdownRenderer implements tree.IRenderer {
public renderTemplate(tree: tree.ITree, templateId: string, container: HTMLElement) {
const row = $('div.list-row').style('height', '22px').style('padding-left', '5px').getHTMLElement();
DOM.append(container, row);
const label = $('span.label').style('margin', 'auto').getHTMLElement();
const label = $('span.label').style('margin', 'auto').style('vertical-align', 'middle').getHTMLElement();
DOM.append(row, label);
return { label };
@@ -91,7 +91,7 @@ export class DropdownFilter extends TreeDefaults.DefaultFilter {
public filterString: string;
public isVisible(tree: tree.ITree, element: Resource): boolean {
return element.value.includes(this.filterString);
return element.value.toLowerCase().includes(this.filterString.toLowerCase());
}
}

View File

@@ -26,6 +26,8 @@ export class ConnectionController implements IConnectionComponentController {
private _model: IConnectionProfile;
private _providerOptions: data.ConnectionOption[];
private _providerName: string;
/* key: uri, value : list of databases */
private _databaseCache = new Map<string, string[]>();
constructor(container: HTMLElement,
connectionManagementService: IConnectionManagementService,
@@ -43,11 +45,50 @@ export class ConnectionController implements IConnectionComponentController {
onSetConnectButton: (enable: boolean) => this._callback.onSetConnectButton(enable),
onCreateNewServerGroup: () => this.onCreateNewServerGroup(),
onAdvancedProperties: () => this.handleOnAdvancedProperties(),
onSetAzureTimeOut: () => this.handleonSetAzureTimeOut()
onSetAzureTimeOut: () => this.handleonSetAzureTimeOut(),
onFetchDatabases: (serverName: string, authenticationType: string, userName?: string, password?: string) => this.onFetchDatabases(
serverName, authenticationType, userName, password).then(result => {
return result;
})
}, providerName);
this._providerName = providerName;
}
private onFetchDatabases(serverName: string, authenticationType: string, userName?: string, password?: string): Promise<string[]> {
let tempProfile = this._model;
tempProfile.serverName = serverName;
tempProfile.authenticationType = authenticationType;
tempProfile.userName = userName;
tempProfile.password = password;
let uri = this._connectionManagementService.getConnectionId(tempProfile);
return new Promise<string[]>((resolve, reject) => {
if (this._databaseCache.has(uri)) {
let cachedDatabases : string[] = this._databaseCache.get(uri);
if (cachedDatabases !== null) {
resolve(cachedDatabases);
} else {
reject();
}
} else {
this._connectionManagementService.connect(tempProfile, uri).then(connResult => {
if (connResult && connResult.connected) {
this._connectionManagementService.listDatabases(uri).then(result => {
if (result && result.databaseNames) {
this._databaseCache.set(uri, result.databaseNames);
resolve(result.databaseNames);
} else {
this._databaseCache.set(uri, null);
reject();
}
})
} else {
reject(connResult.errorMessage);
}
});
}
});
}
private onCreateNewServerGroup(): void {
this._connectionManagementService.showCreateServerGroupDialog({
onAddGroup: (groupName) => this._connectionWidget.updateServerGroup(this.getAllServerGroups(), groupName),

View File

@@ -43,6 +43,7 @@ export interface IConnectionComponentCallbacks {
onCreateNewServerGroup?: () => void;
onAdvancedProperties?: () => void;
onSetAzureTimeOut?: () => void;
onFetchDatabases?: (serverName: string, authenticationType: string, userName?: string, password?: string) => Promise<string[]>;
}
export interface IConnectionComponentController {

View File

@@ -21,12 +21,13 @@ import * as Constants from 'sql/parts/connection/common/constants';
import { ConnectionProfileGroup, IConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import * as styler from 'vs/platform/theme/common/styler';
import { attachInputBoxStyler, attachButtonStyler } from 'sql/common/theme/styler';
import { attachInputBoxStyler, attachButtonStyler, attachEditableDropdownStyler } from 'sql/common/theme/styler';
import * as DOM from 'vs/base/browser/dom';
import data = require('data');
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { localize } from 'vs/nls';
import { OS, OperatingSystem } from 'vs/base/common/platform';
import { Dropdown } from 'sql/base/browser/ui/editableDropdown/dropdown';
export class ConnectionWidget {
private _builder: Builder;
@@ -34,7 +35,7 @@ export class ConnectionWidget {
private _previousGroupOption: string;
private _serverGroupOptions: IConnectionProfileGroup[];
private _serverNameInputBox: InputBox;
private _databaseNameInputBox: InputBox;
private _databaseNameInputBox: Dropdown;
private _userNameInputBox: InputBox;
private _passwordInputBox: InputBox;
private _password: string;
@@ -51,6 +52,8 @@ export class ConnectionWidget {
[Constants.mssqlProviderName]: [new AuthenticationType(Constants.integrated, false), new AuthenticationType(Constants.sqlLogin, true)]
};
private _saveProfile: boolean;
private _defaultDatabaseName: string = localize('defaultDatabaseOption', '<Default>');
private _loadingDatabaseName: string = localize('loadingDatabaseOption', 'Loading...');
public DefaultServerGroup: IConnectionProfileGroup = {
id: '',
name: localize('defaultServerGroup', '<Default>'),
@@ -151,11 +154,12 @@ export class ConnectionWidget {
let databaseOption = this._optionsMaps[ConnectionOptionSpecialType.databaseName];
let databaseNameBuilder = DialogHelper.appendRow(this._tableContainer, databaseOption.displayName, 'connection-label', 'connection-input');
this._databaseNameInputBox = new InputBox(databaseNameBuilder.getHTMLElement(), this._contextViewService, {
validationOptions: {
validation: (value: string) => (!value && databaseOption.isRequired) ? ({ type: MessageType.ERROR, content: databaseOption.displayName + errorMessage }) : null
},
placeholder: (databaseOption.defaultValue || '')
this._databaseNameInputBox = new Dropdown(databaseNameBuilder.getHTMLElement(), this._contextViewService, this._themeService, {
values: [this._defaultDatabaseName, this._loadingDatabaseName],
strictSelection : false,
placeholder: this._defaultDatabaseName,
maxHeight: 125
});
let serverGroupLabel = localize('serverGroup', 'Server group');
@@ -208,7 +212,7 @@ export class ConnectionWidget {
private registerListeners(): void {
// Theme styler
this._toDispose.push(attachInputBoxStyler(this._serverNameInputBox, this._themeService));
this._toDispose.push(attachInputBoxStyler(this._databaseNameInputBox, this._themeService));
this._toDispose.push(attachEditableDropdownStyler(this._databaseNameInputBox, this._themeService));
this._toDispose.push(attachInputBoxStyler(this._userNameInputBox, this._themeService));
this._toDispose.push(attachInputBoxStyler(this._passwordInputBox, this._themeService));
this._toDispose.push(styler.attachSelectBoxStyler(this._serverGroupSelectBox, this._themeService));
@@ -238,6 +242,31 @@ export class ConnectionWidget {
this._toDispose.push(this._passwordInputBox.onDidChange(passwordInput => {
this._password = passwordInput;
}));
this._toDispose.push(this._databaseNameInputBox.onFocus(() => {
if (this.serverName) {
this._databaseNameInputBox.values = [this._loadingDatabaseName];
this._callbacks.onFetchDatabases(this.serverName, this.authenticationType, this.userName, this._password).then(databases => {
if (databases) {
this._databaseNameInputBox.values = databases;
} else {
this._databaseNameInputBox.values = [this._defaultDatabaseName];
}
}).catch(() => {
this._databaseNameInputBox.values = [this._defaultDatabaseName];
});
} else {
this._databaseNameInputBox.values = [this._defaultDatabaseName];
}
}));
this._toDispose.push(this._databaseNameInputBox.onValueChange(s => {
if (s === this._defaultDatabaseName || s === this._loadingDatabaseName) {
this._databaseNameInputBox.value = '';
} else {
this._databaseNameInputBox.value = s;
}
}));
}
private onGroupSelected(selectedGroup: string) {
@@ -393,7 +422,7 @@ export class ConnectionWidget {
this._serverGroupSelectBox.disable();
this._serverNameInputBox.disable();
this._databaseNameInputBox.disable();
this._databaseNameInputBox.enabled = false;
this._userNameInputBox.disable();
this._passwordInputBox.disable();
this._rememberPasswordCheckBox.enabled = false;
@@ -407,7 +436,7 @@ export class ConnectionWidget {
this._serverGroupSelectBox.enable();
this._serverNameInputBox.enable();
this._databaseNameInputBox.enable();
this._databaseNameInputBox.enabled = true;
let currentAuthType: AuthenticationType = undefined;
if (this._authTypeSelectBox) {
this._authTypeSelectBox.enable();
@@ -462,11 +491,7 @@ export class ConnectionWidget {
this._passwordInputBox.focus();
isFocused = true;
}
let validateDatabaseName = this._databaseNameInputBox.validate();
if (!validateDatabaseName && !isFocused) {
this._databaseNameInputBox.focus();
}
return validateServerName && validateUserName && validatePassword && validateDatabaseName;
return validateServerName && validateUserName && validatePassword;
}
public connect(model: IConnectionProfile): boolean {