Strict Null Checks on platform/accounts (#6735)

* add some patches for strict null

* renable strict null checks

* wip

* finish adding account to strict nulls

* fix backup component

* wip

* fix tests
This commit is contained in:
Anthony Dresser
2019-08-14 20:26:21 -07:00
committed by GitHub
parent 7b8530a21e
commit 4966ed8b42
22 changed files with 153 additions and 161 deletions

View File

@@ -33,26 +33,29 @@ export class AccountListDelegate implements IListVirtualDelegate<azdata.Account>
} }
} }
export interface AccountListTemplate { export interface AccountPickerListTemplate {
root: HTMLElement; root: HTMLElement;
icon: HTMLElement; icon: HTMLElement;
badgeContent: HTMLElement; badgeContent: HTMLElement;
contextualDisplayName: HTMLElement; contextualDisplayName: HTMLElement;
label: HTMLElement; label: HTMLElement;
displayName: HTMLElement; displayName: HTMLElement;
content?: HTMLElement;
actions?: ActionBar;
} }
export class AccountPickerListRenderer implements IListRenderer<azdata.Account, AccountListTemplate> { export interface AccountListTemplate extends AccountPickerListTemplate {
content: HTMLElement;
actions: ActionBar;
}
export class AccountPickerListRenderer implements IListRenderer<azdata.Account, AccountPickerListTemplate> {
public static TEMPLATE_ID = 'accountListRenderer'; public static TEMPLATE_ID = 'accountListRenderer';
public get templateId(): string { public get templateId(): string {
return AccountPickerListRenderer.TEMPLATE_ID; return AccountPickerListRenderer.TEMPLATE_ID;
} }
public renderTemplate(container: HTMLElement): AccountListTemplate { public renderTemplate(container: HTMLElement): AccountPickerListTemplate {
const tableTemplate: AccountListTemplate = Object.create(null); const tableTemplate: AccountPickerListTemplate = Object.create(null);
const badge = DOM.$('div.badge'); const badge = DOM.$('div.badge');
tableTemplate.root = DOM.append(container, DOM.$('div.list-row.account-picker-list')); tableTemplate.root = DOM.append(container, DOM.$('div.list-row.account-picker-list'));
tableTemplate.icon = DOM.append(tableTemplate.root, DOM.$('div.icon')); tableTemplate.icon = DOM.append(tableTemplate.root, DOM.$('div.icon'));
@@ -64,7 +67,7 @@ export class AccountPickerListRenderer implements IListRenderer<azdata.Account,
return tableTemplate; return tableTemplate;
} }
public renderElement(account: azdata.Account, index: number, templateData: AccountListTemplate): void { public renderElement(account: azdata.Account, index: number, templateData: AccountPickerListTemplate): void {
// Set the account icon // Set the account icon
templateData.icon.classList.add('account-logo', account.displayInfo.accountType); templateData.icon.classList.add('account-logo', account.displayInfo.accountType);
@@ -84,11 +87,11 @@ export class AccountPickerListRenderer implements IListRenderer<azdata.Account,
} }
} }
public disposeTemplate(template: AccountListTemplate): void { public disposeTemplate(template: AccountPickerListTemplate): void {
// noop // noop
} }
public disposeElement(element: azdata.Account, index: number, templateData: AccountListTemplate): void { public disposeElement(element: azdata.Account, index: number, templateData: AccountPickerListTemplate): void {
// noop // noop
} }
} }
@@ -105,7 +108,7 @@ export class AccountListRenderer extends AccountPickerListRenderer {
} }
public renderTemplate(container: HTMLElement): AccountListTemplate { public renderTemplate(container: HTMLElement): AccountListTemplate {
const tableTemplate = super.renderTemplate(container); const tableTemplate = super.renderTemplate(container) as AccountListTemplate;
tableTemplate.content = DOM.append(tableTemplate.label, DOM.$('div.content')); tableTemplate.content = DOM.append(tableTemplate.label, DOM.$('div.content'));
tableTemplate.actions = new ActionBar(tableTemplate.root, { animated: false }); tableTemplate.actions = new ActionBar(tableTemplate.root, { animated: false });

View File

@@ -44,8 +44,8 @@ export class AccountPicker extends Disposable {
private _addAccountStartEmitter: Emitter<void>; private _addAccountStartEmitter: Emitter<void>;
public get addAccountStartEvent(): Event<void> { return this._addAccountStartEmitter.event; } public get addAccountStartEvent(): Event<void> { return this._addAccountStartEmitter.event; }
private _onAccountSelectionChangeEvent: Emitter<azdata.Account>; private _onAccountSelectionChangeEvent: Emitter<azdata.Account | undefined>;
public get onAccountSelectionChangeEvent(): Event<azdata.Account> { return this._onAccountSelectionChangeEvent.event; } public get onAccountSelectionChangeEvent(): Event<azdata.Account | undefined> { return this._onAccountSelectionChangeEvent.event; }
constructor( constructor(
private _providerId: string, private _providerId: string,
@@ -145,7 +145,7 @@ export class AccountPicker extends Disposable {
} }
// PRIVATE HELPERS ///////////////////////////////////////////////////// // PRIVATE HELPERS /////////////////////////////////////////////////////
private onAccountSelectionChange(account: azdata.Account) { private onAccountSelectionChange(account: azdata.Account | undefined) {
this.viewModel.selectedAccount = account; this.viewModel.selectedAccount = account;
if (account && account.isStale) { if (account && account.isStale) {
this._refreshAccountAction.account = account; this._refreshAccountAction.account = account;
@@ -157,7 +157,7 @@ export class AccountPicker extends Disposable {
this._onAccountSelectionChangeEvent.fire(account); this._onAccountSelectionChangeEvent.fire(account);
} }
private renderLabel(container: HTMLElement): IDisposable { private renderLabel(container: HTMLElement): IDisposable | null {
if (container.hasChildNodes()) { if (container.hasChildNodes()) {
for (let i = 0; i < container.childNodes.length; i++) { for (let i = 0; i < container.childNodes.length; i++) {
container.removeChild(container.childNodes.item(i)); container.removeChild(container.childNodes.item(i));
@@ -189,7 +189,7 @@ export class AccountPicker extends Disposable {
const row = DOM.append(container, DOM.$('div.no-account-container')); const row = DOM.append(container, DOM.$('div.no-account-container'));
row.innerText = AddAccountAction.LABEL + '...'; row.innerText = AddAccountAction.LABEL + '...';
} }
return undefined; return null;
} }
private updateAccountList(accounts: azdata.Account[]): void { private updateAccountList(accounts: azdata.Account[]): void {
@@ -197,7 +197,7 @@ export class AccountPicker extends Disposable {
const selectedElements = this._accountList.getSelectedElements(); const selectedElements = this._accountList.getSelectedElements();
// find selected index // find selected index
let selectedIndex: number; let selectedIndex: number | undefined;
if (selectedElements.length > 0 && accounts.length > 0) { if (selectedElements.length > 0 && accounts.length > 0) {
selectedIndex = accounts.findIndex((account) => { selectedIndex = accounts.findIndex((account) => {
return (account.key.accountId === selectedElements[0].key.accountId); return (account.key.accountId === selectedElements[0].key.accountId);

View File

@@ -25,8 +25,8 @@ export class AccountPickerService implements IAccountPickerService {
private _addAccountStartEmitter: Emitter<void>; private _addAccountStartEmitter: Emitter<void>;
public get addAccountStartEvent(): Event<void> { return this._addAccountStartEmitter.event; } public get addAccountStartEvent(): Event<void> { return this._addAccountStartEmitter.event; }
private _onAccountSelectionChangeEvent: Emitter<azdata.Account>; private _onAccountSelectionChangeEvent: Emitter<azdata.Account | undefined>;
public get onAccountSelectionChangeEvent(): Event<azdata.Account> { return this._onAccountSelectionChangeEvent.event; } public get onAccountSelectionChangeEvent(): Event<azdata.Account | undefined> { return this._onAccountSelectionChangeEvent.event; }
constructor( constructor(
@IInstantiationService private _instantiationService: IInstantiationService @IInstantiationService private _instantiationService: IInstantiationService
@@ -41,7 +41,7 @@ export class AccountPickerService implements IAccountPickerService {
/** /**
* Get selected account * Get selected account
*/ */
public get selectedAccount(): azdata.Account { public get selectedAccount(): azdata.Account | undefined {
return this._accountPicker.viewModel.selectedAccount; return this._accountPicker.viewModel.selectedAccount;
} }

View File

@@ -14,7 +14,7 @@ import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMess
export class AutoOAuthDialogController { export class AutoOAuthDialogController {
// MEMBER VARIABLES //////////////////////////////////////////////////// // MEMBER VARIABLES ////////////////////////////////////////////////////
private _autoOAuthDialog: AutoOAuthDialog; private _autoOAuthDialog: AutoOAuthDialog;
private _providerId: string; private _providerId?: string;
private _userCode: string; private _userCode: string;
private _uri: string; private _uri: string;
@@ -22,15 +22,13 @@ export class AutoOAuthDialogController {
@IInstantiationService private _instantiationService: IInstantiationService, @IInstantiationService private _instantiationService: IInstantiationService,
@IAccountManagementService private _accountManagementService: IAccountManagementService, @IAccountManagementService private _accountManagementService: IAccountManagementService,
@IErrorMessageService private _errorMessageService: IErrorMessageService @IErrorMessageService private _errorMessageService: IErrorMessageService
) { ) { }
this._providerId = null;
}
/** /**
* Open auto OAuth dialog * Open auto OAuth dialog
*/ */
public openAutoOAuthDialog(providerId: string, title: string, message: string, userCode: string, uri: string): Thenable<void> { public openAutoOAuthDialog(providerId: string, title: string, message: string, userCode: string, uri: string): Thenable<void> {
if (this._providerId !== null) { if (this._providerId !== undefined) {
// If a oauth flyout is already open, return an error // If a oauth flyout is already open, return an error
const errorMessage = localize('oauthFlyoutIsAlreadyOpen', "Cannot start auto OAuth. An auto OAuth is already in progress."); const errorMessage = localize('oauthFlyoutIsAlreadyOpen', "Cannot start auto OAuth. An auto OAuth is already in progress.");
this._errorMessageService.showDialog(Severity.Error, '', errorMessage); this._errorMessageService.showDialog(Severity.Error, '', errorMessage);
@@ -60,16 +58,16 @@ export class AutoOAuthDialogController {
*/ */
public closeAutoOAuthDialog(): void { public closeAutoOAuthDialog(): void {
this._autoOAuthDialog.close(); this._autoOAuthDialog.close();
this._providerId = null; this._providerId = undefined;
} }
// PRIVATE HELPERS ///////////////////////////////////////////////////// // PRIVATE HELPERS /////////////////////////////////////////////////////
private handleOnCancel(): void { private handleOnCancel(): void {
this._accountManagementService.cancelAutoOAuthDeviceCode(this._providerId); this._accountManagementService.cancelAutoOAuthDeviceCode(this._providerId!); // this should be always true
} }
private handleOnClose(): void { private handleOnClose(): void {
this._providerId = null; this._providerId = undefined;
} }
private handleOnAddAccount(): void { private handleOnAddAccount(): void {

View File

@@ -278,7 +278,7 @@ export class FirewallRuleDialog extends Modal {
} }
} }
public onAccountSelectionChange(account: azdata.Account): void { public onAccountSelectionChange(account: azdata.Account | undefined): void {
this.viewModel.selectedAccount = account; this.viewModel.selectedAccount = account;
if (account && !account.isStale) { if (account && !account.isStale) {
this._createButton.enabled = true; this._createButton.enabled = true;

View File

@@ -57,31 +57,28 @@ export class FirewallRuleDialogController {
this._errorMessageService.showDialog(Severity.Error, this._addAccountErrorTitle, message); this._errorMessageService.showDialog(Severity.Error, this._addAccountErrorTitle, message);
} }
private handleOnCreateFirewallRule(): void { private async handleOnCreateFirewallRule(): Promise<void> {
const resourceProviderId = this._resourceProviderId; const resourceProviderId = this._resourceProviderId;
try {
this._accountManagementService.getSecurityToken(this._firewallRuleDialog.viewModel.selectedAccount, AzureResource.ResourceManagement).then(tokenMappings => { const securityTokenMappings = await this._accountManagementService.getSecurityToken(this._firewallRuleDialog.viewModel.selectedAccount!, AzureResource.ResourceManagement);
let firewallRuleInfo: azdata.FirewallRuleInfo = { const firewallRuleInfo: azdata.FirewallRuleInfo = {
startIpAddress: this._firewallRuleDialog.viewModel.isIPAddressSelected ? this._firewallRuleDialog.viewModel.defaultIPAddress : this._firewallRuleDialog.viewModel.fromSubnetIPRange, startIpAddress: this._firewallRuleDialog.viewModel.isIPAddressSelected ? this._firewallRuleDialog.viewModel.defaultIPAddress : this._firewallRuleDialog.viewModel.fromSubnetIPRange,
endIpAddress: this._firewallRuleDialog.viewModel.isIPAddressSelected ? this._firewallRuleDialog.viewModel.defaultIPAddress : this._firewallRuleDialog.viewModel.toSubnetIPRange, endIpAddress: this._firewallRuleDialog.viewModel.isIPAddressSelected ? this._firewallRuleDialog.viewModel.defaultIPAddress : this._firewallRuleDialog.viewModel.toSubnetIPRange,
serverName: this._connection.serverName, serverName: this._connection.serverName,
securityTokenMappings: tokenMappings securityTokenMappings
}; };
this._resourceProviderService.createFirewallRule(this._firewallRuleDialog.viewModel.selectedAccount, firewallRuleInfo, resourceProviderId).then(createFirewallRuleResponse => { const response = await this._resourceProviderService.createFirewallRule(this._firewallRuleDialog.viewModel.selectedAccount!, firewallRuleInfo, resourceProviderId);
if (createFirewallRuleResponse.result) { if (response.result) {
this._firewallRuleDialog.close(); this._firewallRuleDialog.close();
this._deferredPromise.resolve(true); this._deferredPromise.resolve(true);
} else { } else {
this._errorMessageService.showDialog(Severity.Error, this._firewallRuleErrorTitle, createFirewallRuleResponse.errorMessage); this._errorMessageService.showDialog(Severity.Error, this._firewallRuleErrorTitle, response.errorMessage);
} }
this._firewallRuleDialog.onServiceComplete(); this._firewallRuleDialog.onServiceComplete();
}, error => { } catch (e) {
this.showError(error); this.showError(e);
}); }
}, error => {
this.showError(error);
});
} }
private showError(error: any): void { private showError(error: any): void {

View File

@@ -15,6 +15,6 @@ export interface IAccountPickerService {
addAccountCompleteEvent: Event<void>; addAccountCompleteEvent: Event<void>;
addAccountErrorEvent: Event<string>; addAccountErrorEvent: Event<string>;
addAccountStartEvent: Event<void>; addAccountStartEvent: Event<void>;
onAccountSelectionChangeEvent: Event<azdata.Account>; onAccountSelectionChangeEvent: Event<azdata.Account | undefined>;
selectedAccount: azdata.Account; selectedAccount: azdata.Account | undefined;
} }

View File

@@ -17,7 +17,7 @@ export class AccountPickerViewModel {
private _updateAccountListEmitter: Emitter<UpdateAccountListEventParams>; private _updateAccountListEmitter: Emitter<UpdateAccountListEventParams>;
public get updateAccountListEvent(): Event<UpdateAccountListEventParams> { return this._updateAccountListEmitter.event; } public get updateAccountListEvent(): Event<UpdateAccountListEventParams> { return this._updateAccountListEmitter.event; }
public selectedAccount: azdata.Account; public selectedAccount: azdata.Account | undefined;
constructor( constructor(
private _providerId: string, private _providerId: string,

View File

@@ -89,7 +89,7 @@ export default class AccountStore implements IAccountStore {
activeOperation = activeOperation.then(op); activeOperation = activeOperation.then(op);
// Add a catch at the end to make sure we can continue after any errors // Add a catch at the end to make sure we can continue after any errors
activeOperation = activeOperation.then(null, (err) => { activeOperation = activeOperation.then(undefined, (err) => {
// TODO: Log the error // TODO: Log the error
}); });
@@ -107,7 +107,7 @@ export default class AccountStore implements IAccountStore {
accountAdded: false, accountAdded: false,
accountModified: false, accountModified: false,
accountRemoved: false, accountRemoved: false,
changedAccount: null, changedAccount: undefined,
updatedAccounts: accounts updatedAccounts: accounts
}; };
} }
@@ -135,7 +135,7 @@ export default class AccountStore implements IAccountStore {
accountAdded: false, accountAdded: false,
accountModified: false, accountModified: false,
accountRemoved: match >= 0, accountRemoved: match >= 0,
changedAccount: null, changedAccount: undefined,
updatedAccounts: accounts updatedAccounts: accounts
}; };
} }
@@ -149,7 +149,7 @@ export default class AccountStore implements IAccountStore {
accountAdded: false, accountAdded: false,
accountModified: false, accountModified: false,
accountRemoved: false, accountRemoved: false,
changedAccount: null, changedAccount: undefined,
updatedAccounts: accounts updatedAccounts: accounts
}; };
} }

View File

@@ -22,7 +22,7 @@ export interface AccountAdditionResult {
/** /**
* The account that was added/updated (with any updates applied) * The account that was added/updated (with any updates applied)
*/ */
changedAccount: azdata.Account; changedAccount: azdata.Account | undefined;
} }
/** /**

View File

@@ -10,7 +10,7 @@ import * as azdata from 'azdata';
*/ */
export class FirewallRuleViewModel { export class FirewallRuleViewModel {
public isIPAddressSelected: boolean; public isIPAddressSelected: boolean;
public selectedAccount: azdata.Account; public selectedAccount: azdata.Account | undefined;
private _defaultIPAddress: string; private _defaultIPAddress: string;
private _defaultFromSubnetIPRange: string; private _defaultFromSubnetIPRange: string;

View File

@@ -20,7 +20,7 @@ suite('Account Management Dialog Controller Tests', () => {
test('Open Account Dialog - Dialog Doesn\'t Exist', () => { test('Open Account Dialog - Dialog Doesn\'t Exist', () => {
// Setup: Create instance of the controller // Setup: Create instance of the controller
let instantiationService = createInstantiationService(); let instantiationService = createInstantiationService();
let controller = new AccountDialogController(instantiationService, undefined); let controller = new AccountDialogController(instantiationService, undefined!);
assert.strictEqual(controller.accountDialog, undefined); assert.strictEqual(controller.accountDialog, undefined);
// If: I open the account dialog when one hasn't been opened // If: I open the account dialog when one hasn't been opened
@@ -34,7 +34,7 @@ suite('Account Management Dialog Controller Tests', () => {
test('Open Account Dialog - Dialog Exists', () => { test('Open Account Dialog - Dialog Exists', () => {
// Setup: Create instance of the controller with an account dialog already loaded // Setup: Create instance of the controller with an account dialog already loaded
let instantiationService = createInstantiationService(); let instantiationService = createInstantiationService();
let controller = new AccountDialogController(instantiationService, undefined); let controller = new AccountDialogController(instantiationService, undefined!);
controller.openAccountDialog(); controller.openAccountDialog();
let accountDialog = controller.accountDialog; let accountDialog = controller.accountDialog;
@@ -86,7 +86,7 @@ function createInstantiationService(addAccountFailureEmitter?: Emitter<string>):
.returns(() => undefined); .returns(() => undefined);
// Create a mock account dialog // Create a mock account dialog
let accountDialog = new AccountDialog(null, null, instantiationService.object, null, null, null, null, new MockContextKeyService(), null, undefined, undefined); let accountDialog = new AccountDialog(undefined!, undefined!, instantiationService.object, undefined!, undefined!, undefined!, undefined!, new MockContextKeyService(), undefined!, undefined!, undefined!);
let mockAccountDialog = TypeMoq.Mock.ofInstance(accountDialog); let mockAccountDialog = TypeMoq.Mock.ofInstance(accountDialog);
mockAccountDialog.setup(x => x.onAddAccountErrorEvent) mockAccountDialog.setup(x => x.onAddAccountErrorEvent)
.returns(() => { return addAccountFailureEmitter ? addAccountFailureEmitter.event : mockEvent.event; }); .returns(() => { return addAccountFailureEmitter ? addAccountFailureEmitter.event : mockEvent.event; });

View File

@@ -13,6 +13,7 @@ import { AccountPickerService } from 'sql/platform/accounts/browser/accountPicke
import { AccountPickerViewModel } from 'sql/platform/accounts/common/accountPickerViewModel'; import { AccountPickerViewModel } from 'sql/platform/accounts/common/accountPickerViewModel';
import { TestAccountManagementService } from 'sql/platform/accounts/test/common/testAccountManagementService'; import { TestAccountManagementService } from 'sql/platform/accounts/test/common/testAccountManagementService';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
// SUITE STATE ///////////////////////////////////////////////////////////// // SUITE STATE /////////////////////////////////////////////////////////////
let mockAddAccountCompleteEmitter: Emitter<void>; let mockAddAccountCompleteEmitter: Emitter<void>;
@@ -98,7 +99,8 @@ function createInstantiationService(): InstantiationService {
.returns(() => mockAccountViewModel.object); .returns(() => mockAccountViewModel.object);
// Create a mock account picker // Create a mock account picker
let accountPicker = new AccountPicker(null, null, instantiationService.object, null);
let accountPicker = new AccountPicker('provider', new TestThemeService(), instantiationService.object, undefined!);
let mockAccountDialog = TypeMoq.Mock.ofInstance(accountPicker); let mockAccountDialog = TypeMoq.Mock.ofInstance(accountPicker);
mockAccountDialog.setup(x => x.addAccountCompleteEvent) mockAccountDialog.setup(x => x.addAccountCompleteEvent)

View File

@@ -37,7 +37,7 @@ suite('auto OAuth dialog controller tests', () => {
mockOnCloseEvent = new Emitter<void>(); mockOnCloseEvent = new Emitter<void>();
// Create a mock auto OAuth dialog // Create a mock auto OAuth dialog
let autoOAuthDialog = new AutoOAuthDialog(null, null, null, null, new MockContextKeyService(), null, undefined, undefined); let autoOAuthDialog = new AutoOAuthDialog(undefined!, undefined!, undefined!, undefined!, new MockContextKeyService(), undefined!, undefined!, undefined!);
mockAutoOAuthDialog = TypeMoq.Mock.ofInstance(autoOAuthDialog); mockAutoOAuthDialog = TypeMoq.Mock.ofInstance(autoOAuthDialog);
mockAutoOAuthDialog.setup(x => x.onCancel).returns(() => mockOnCancelEvent.event); mockAutoOAuthDialog.setup(x => x.onCancel).returns(() => mockOnCancelEvent.event);

View File

@@ -5,7 +5,7 @@
import * as azdata from 'azdata'; import * as azdata from 'azdata';
import * as TypeMoq from 'typemoq'; import * as TypeMoq from 'typemoq';
import { Emitter } from 'vs/base/common/event'; import { Emitter, Event } from 'vs/base/common/event';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { FirewallRuleDialog } from 'sql/platform/accounts/browser/firewallRuleDialog'; import { FirewallRuleDialog } from 'sql/platform/accounts/browser/firewallRuleDialog';
import { FirewallRuleViewModel } from 'sql/platform/accounts/common/firewallRuleViewModel'; import { FirewallRuleViewModel } from 'sql/platform/accounts/common/firewallRuleViewModel';
@@ -60,7 +60,7 @@ suite('Firewall rule dialog controller tests', () => {
.returns(() => mockFirewallRuleViewModel.object); .returns(() => mockFirewallRuleViewModel.object);
// Create a mock account picker // Create a mock account picker
let firewallRuleDialog = new FirewallRuleDialog(null, null, null, instantiationService.object, null, null, new MockContextKeyService(), null, null, undefined, undefined); let firewallRuleDialog = new FirewallRuleDialog(undefined!, undefined!, undefined!, instantiationService.object, undefined!, undefined!, new MockContextKeyService(), undefined!, undefined!, undefined!, undefined!);
mockFirewallRuleDialog = TypeMoq.Mock.ofInstance(firewallRuleDialog); mockFirewallRuleDialog = TypeMoq.Mock.ofInstance(firewallRuleDialog);
let mockEvent = new Emitter<any>(); let mockEvent = new Emitter<any>();
@@ -87,12 +87,12 @@ suite('Firewall rule dialog controller tests', () => {
savePassword: true, savePassword: true,
groupFullName: 'g2/g2-2', groupFullName: 'g2/g2-2',
groupId: 'group id', groupId: 'group id',
getOptionsKey: undefined, getOptionsKey: () => '',
matches: undefined, matches: () => false,
providerName: mssqlProviderName, providerName: mssqlProviderName,
options: {}, options: {},
saveProfile: true, saveProfile: true,
id: undefined id: ''
}; };
}); });
@@ -103,7 +103,7 @@ suite('Firewall rule dialog controller tests', () => {
mockErrorMessageService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())); mockErrorMessageService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()));
// ... Create instance of the controller with an opened dialog // ... Create instance of the controller with an opened dialog
let controller = new FirewallRuleDialogController(instantiationService.object, null, null, mockErrorMessageService.object); let controller = new FirewallRuleDialogController(instantiationService.object, undefined!, undefined!, mockErrorMessageService.object);
controller.openFirewallRuleDialog(connectionProfile, IPAddress, 'resourceID'); controller.openFirewallRuleDialog(connectionProfile, IPAddress, 'resourceID');
// If: The firewall rule dialog reports a failure // If: The firewall rule dialog reports a failure
@@ -114,7 +114,7 @@ suite('Firewall rule dialog controller tests', () => {
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
}); });
test('create firewall rule success', (done) => { test('create firewall rule success', async () => {
let deferredPromise = new Deferred(); let deferredPromise = new Deferred();
mockFirewallRuleDialog.setup(x => x.onServiceComplete()) mockFirewallRuleDialog.setup(x => x.onServiceComplete())
@@ -129,24 +129,22 @@ suite('Firewall rule dialog controller tests', () => {
let mockResourceProvider = getMockResourceProvider(true, { result: true, errorMessage: '' }); let mockResourceProvider = getMockResourceProvider(true, { result: true, errorMessage: '' });
// ... Create instance of the controller with an opened dialog // ... Create instance of the controller with an opened dialog
let controller = new FirewallRuleDialogController(instantiationService.object, mockResourceProvider.object, mockAccountManagementService.object, null); let controller = new FirewallRuleDialogController(instantiationService.object, mockResourceProvider.object, mockAccountManagementService.object, undefined!);
controller.openFirewallRuleDialog(connectionProfile, IPAddress, 'resourceID'); controller.openFirewallRuleDialog(connectionProfile, IPAddress, 'resourceID');
// If: The firewall rule dialog's create firewall rule get fired // If: The firewall rule dialog's create firewall rule get fired
mockOnCreateFirewallRule.fire(); mockOnCreateFirewallRule.fire();
// Then: it should get security token from account management service and call create firewall rule in resource provider // Then: it should get security token from account management service and call create firewall rule in resource provider
deferredPromise.promise.then(() => { await deferredPromise;
mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockFirewallRuleDialog.verify(x => x.close(), TypeMoq.Times.once()); mockFirewallRuleDialog.verify(x => x.close(), TypeMoq.Times.once());
mockFirewallRuleDialog.verify(x => x.onServiceComplete(), TypeMoq.Times.once()); mockFirewallRuleDialog.verify(x => x.onServiceComplete(), TypeMoq.Times.once());
done();
});
}); });
test('create firewall rule fails during getSecurity', (done) => { test('create firewall rule fails during getSecurity', async () => {
let deferredPromise = new Deferred(); let deferredPromise = new Deferred<{}>();
// ... Create a mock instance of the error message service // ... Create a mock instance of the error message service
let mockErrorMessageService = getMockErrorMessageService(deferredPromise); let mockErrorMessageService = getMockErrorMessageService(deferredPromise);
@@ -165,16 +163,14 @@ suite('Firewall rule dialog controller tests', () => {
mockOnCreateFirewallRule.fire(); mockOnCreateFirewallRule.fire();
// Then: it should get security token from account management service and an error dialog should have been opened // Then: it should get security token from account management service and an error dialog should have been opened
deferredPromise.promise.then(() => { await deferredPromise;
mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.never()); mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.never());
done();
});
}); });
test('create firewall rule fails during createFirewallRule in ResourceProvider - result is false', (done) => { test('create firewall rule fails during createFirewallRule in ResourceProvider - result is false', async () => {
let deferredPromise = new Deferred(); let deferredPromise = new Deferred<{}>();
// ... Create a mock instance of the error message service // ... Create a mock instance of the error message service
let mockErrorMessageService = getMockErrorMessageService(deferredPromise); let mockErrorMessageService = getMockErrorMessageService(deferredPromise);
@@ -193,16 +189,15 @@ suite('Firewall rule dialog controller tests', () => {
mockOnCreateFirewallRule.fire(); mockOnCreateFirewallRule.fire();
// Then: it should get security token from account management service and an error dialog should have been opened // Then: it should get security token from account management service and an error dialog should have been opened
deferredPromise.promise.then(() => { await deferredPromise;
mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
done(); mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
});
}); });
test('create firewall rule fails during createFirewallRule in ResourceProvider - reject promise', (done) => { test('create firewall rule fails during createFirewallRule in ResourceProvider - reject promise', async () => {
let deferredPromise = new Deferred(); let deferredPromise = new Deferred<{}>();
// ... Create a mock instance of the error message service // ... Create a mock instance of the error message service
let mockErrorMessageService = getMockErrorMessageService(deferredPromise); let mockErrorMessageService = getMockErrorMessageService(deferredPromise);
@@ -221,12 +216,10 @@ suite('Firewall rule dialog controller tests', () => {
mockOnCreateFirewallRule.fire(); mockOnCreateFirewallRule.fire();
// Then: it should get security token from account management service and an error dialog should have been opened // Then: it should get security token from account management service and an error dialog should have been opened
deferredPromise.promise.then(() => { await deferredPromise;
mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
done();
});
}); });
}); });
@@ -234,7 +227,7 @@ function getMockAccountManagementService(resolveSecurityToken: boolean): TypeMoq
let accountManagementTestService = new TestAccountManagementService(); let accountManagementTestService = new TestAccountManagementService();
let mockAccountManagementService = TypeMoq.Mock.ofInstance(accountManagementTestService); let mockAccountManagementService = TypeMoq.Mock.ofInstance(accountManagementTestService);
mockAccountManagementService.setup(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny())) mockAccountManagementService.setup(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.returns(() => resolveSecurityToken ? Promise.resolve({}) : Promise.reject(null).then()); .returns(() => resolveSecurityToken ? Promise.resolve({}) : Promise.reject(null));
return mockAccountManagementService; return mockAccountManagementService;
} }
@@ -242,7 +235,7 @@ function getMockResourceProvider(resolveCreateFirewallRule: boolean, response?:
let resourceProviderStub = new TestResourceProvider(); let resourceProviderStub = new TestResourceProvider();
let mockResourceProvider = TypeMoq.Mock.ofInstance(resourceProviderStub); let mockResourceProvider = TypeMoq.Mock.ofInstance(resourceProviderStub);
mockResourceProvider.setup(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) mockResourceProvider.setup(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.returns(() => resolveCreateFirewallRule ? Promise.resolve(response) : Promise.reject(null).then()); .returns(() => resolveCreateFirewallRule ? Promise.resolve(response) : Promise.reject(null));
return mockResourceProvider; return mockResourceProvider;
} }

View File

@@ -21,7 +21,7 @@ suite('Account Store Tests', () => {
// ... I should have gotten back a result indicating the account was added // ... I should have gotten back a result indicating the account was added
assert.ok(result.accountAdded); assert.ok(result.accountAdded);
assert.ok(!result.accountModified); assert.ok(!result.accountModified);
assertAccountEqual(result.changedAccount, account1); assertAccountEqual(result.changedAccount!, account1);
// ... The memento should have been initialized and account added // ... The memento should have been initialized and account added
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY])); assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
@@ -47,7 +47,7 @@ suite('Account Store Tests', () => {
// ... I should have gotten back a result indicating the account was added // ... I should have gotten back a result indicating the account was added
assert.ok(result.accountAdded); assert.ok(result.accountAdded);
assert.ok(!result.accountModified); assert.ok(!result.accountModified);
assertAccountEqual(result.changedAccount, account1); assertAccountEqual(result.changedAccount!, account1);
// ... The memento should have the account added // ... The memento should have the account added
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY])); assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
@@ -77,7 +77,7 @@ suite('Account Store Tests', () => {
// ... I should have gotten back a result indicating the account was updated // ... I should have gotten back a result indicating the account was updated
assert.ok(result.accountModified); assert.ok(result.accountModified);
assert.ok(!result.accountAdded); assert.ok(!result.accountAdded);
assertAccountEqual(result.changedAccount, param); assertAccountEqual(result.changedAccount!, param);
// ... The memento should have been initialized and account updated // ... The memento should have been initialized and account updated
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY])); assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));

View File

@@ -11,20 +11,20 @@ import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 's
export class TestAccountManagementService implements IAccountManagementService { export class TestAccountManagementService implements IAccountManagementService {
_serviceBrand: any; _serviceBrand: any;
public get addAccountProviderEvent(): Event<AccountProviderAddedEventParams> { return () => { return undefined; }; } public get addAccountProviderEvent(): Event<AccountProviderAddedEventParams> { return Event.None; }
public get removeAccountProviderEvent(): Event<azdata.AccountProviderMetadata> { return () => { return undefined; }; } public get removeAccountProviderEvent(): Event<azdata.AccountProviderMetadata> { return Event.None; }
public get updateAccountListEvent(): Event<UpdateAccountListEventParams> { return () => { return undefined; }; } public get updateAccountListEvent(): Event<UpdateAccountListEventParams> { return Event.None; }
accountUpdated(account: azdata.Account): Thenable<void> { accountUpdated(account: azdata.Account): Thenable<void> {
return undefined; return Promise.resolve();
} }
addAccount(providerId: string): Thenable<void> { addAccount(providerId: string): Thenable<void> {
return undefined; return Promise.resolve();
} }
beginAutoOAuthDeviceCode(title: string, message: string, userCode: string, uri: string): Thenable<void> { beginAutoOAuthDeviceCode(title: string, message: string, userCode: string, uri: string): Thenable<void> {
return undefined; return Promise.resolve();
} }
cancelAutoOAuthDeviceCode(providerId: string): void { cancelAutoOAuthDeviceCode(providerId: string): void {
@@ -40,27 +40,27 @@ export class TestAccountManagementService implements IAccountManagementService {
} }
getAccountProviderMetadata(): Thenable<azdata.AccountProviderMetadata[]> { getAccountProviderMetadata(): Thenable<azdata.AccountProviderMetadata[]> {
return undefined; return Promise.resolve([]);
} }
getAccountsForProvider(providerId: string): Thenable<azdata.Account[]> { getAccountsForProvider(providerId: string): Thenable<azdata.Account[]> {
return undefined; return Promise.resolve([]);
} }
getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Thenable<{}> { getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Thenable<{}> {
return undefined; return Promise.resolve([]);
} }
removeAccount(accountKey: azdata.AccountKey): Thenable<boolean> { removeAccount(accountKey: azdata.AccountKey): Thenable<boolean> {
return undefined; throw new Error('Method not implemented');
} }
refreshAccount(account: azdata.Account): Thenable<azdata.Account> { refreshAccount(account: azdata.Account): Thenable<azdata.Account> {
return undefined; throw new Error('Method not implemented');
} }
openAccountListDialog(): Promise<any> { openAccountListDialog(): Promise<any> {
return undefined; return Promise.resolve();
} }
registerProvider(providerMetadata: azdata.AccountProviderMetadata, provider: azdata.AccountProvider): void { registerProvider(providerMetadata: azdata.AccountProviderMetadata, provider: azdata.AccountProvider): void {
@@ -94,7 +94,7 @@ export class AccountProviderStub implements azdata.AccountProvider {
} }
prompt(): Thenable<azdata.Account> { prompt(): Thenable<azdata.Account> {
return Promise.resolve(undefined); throw new Error('Method not implemented');
} }
refresh(account: azdata.Account): Thenable<azdata.Account> { refresh(account: azdata.Account): Thenable<azdata.Account> {

View File

@@ -581,8 +581,7 @@ export class ConnectionProfile {
options: { [name: string]: any }; options: { [name: string]: any };
static createFrom(options: any[]): ConnectionProfile { static createFrom(options: any[]): ConnectionProfile {
// create from options throw new Error('Method not implemented');
return undefined;
} }
} }

View File

@@ -43,6 +43,10 @@ export interface IModalDialogStyles {
dialogBorder?: Color; dialogBorder?: Color;
dialogHeaderAndFooterBackground?: Color; dialogHeaderAndFooterBackground?: Color;
dialogBodyBackground?: Color; dialogBodyBackground?: Color;
footerBackgroundColor?: Color;
footerBorderTopWidth?: Color;
footerBorderTopStyle?: Color;
footerBorderTopColor?: Color;
} }
export interface IModalOptions { export interface IModalOptions {
@@ -55,14 +59,6 @@ export interface IModalOptions {
hasSpinner?: boolean; hasSpinner?: boolean;
} }
// Needed for angular component dialogs to style modal footer
export class ModalFooterStyle {
public static backgroundColor;
public static borderTopWidth;
public static borderTopStyle;
public static borderTopColor;
}
const defaultOptions: IModalOptions = { const defaultOptions: IModalOptions = {
isFlyout: true, isFlyout: true,
isWide: false, isWide: false,
@@ -93,10 +89,10 @@ export abstract class Modal extends Disposable implements IThemable {
private _lastFocusableElement: HTMLElement; private _lastFocusableElement: HTMLElement;
private _focusedElementBeforeOpen: HTMLElement; private _focusedElementBeforeOpen: HTMLElement;
private _dialogForeground: Color; private _dialogForeground?: Color;
private _dialogBorder: Color; private _dialogBorder?: Color;
private _dialogHeaderAndFooterBackground: Color; private _dialogHeaderAndFooterBackground?: Color;
private _dialogBodyBackground: Color; private _dialogBodyBackground?: Color;
private _modalDialog: HTMLElement; private _modalDialog: HTMLElement;
private _modalHeaderSection: HTMLElement; private _modalHeaderSection: HTMLElement;
@@ -336,12 +332,12 @@ export abstract class Modal extends Disposable implements IThemable {
* Shows the modal and attaches key listeners * Shows the modal and attaches key listeners
*/ */
protected show() { protected show() {
this._modalShowingContext.get().push(this._staticKey); this._modalShowingContext.get()!.push(this._staticKey);
DOM.append(this.layoutService.container, this._bodyContainer); DOM.append(this.layoutService.container, this._bodyContainer);
this.setFocusableElements(); this.setFocusableElements();
this._keydownListener = DOM.addDisposableListener(document, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => { this._keydownListener = DOM.addDisposableListener(document, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
let context = this._modalShowingContext.get(); let context = this._modalShowingContext.get()!;
if (context[context.length - 1] === this._staticKey) { if (context[context.length - 1] === this._staticKey) {
let event = new StandardKeyboardEvent(e); let event = new StandardKeyboardEvent(e);
if (event.equals(KeyCode.Enter)) { if (event.equals(KeyCode.Enter)) {
@@ -372,7 +368,7 @@ export abstract class Modal extends Disposable implements IThemable {
* Hides the modal and removes key listeners * Hides the modal and removes key listeners
*/ */
protected hide() { protected hide() {
this._modalShowingContext.get().pop(); this._modalShowingContext.get()!.pop();
this._bodyContainer.remove(); this._bodyContainer.remove();
if (this._focusedElementBeforeOpen) { if (this._focusedElementBeforeOpen) {
this._focusedElementBeforeOpen.focus(); this._focusedElementBeforeOpen.focus();
@@ -438,7 +434,7 @@ export abstract class Modal extends Disposable implements IThemable {
* @param level Severity level of the message * @param level Severity level of the message
* @param description Description of the message * @param description Description of the message
*/ */
protected setError(message: string, level: MessageLevel = MessageLevel.Error, description: string = '') { protected setError(message: string | undefined, level: MessageLevel = MessageLevel.Error, description: string = '') {
if (this._modalOptions.hasErrors) { if (this._modalOptions.hasErrors) {
this._messageSummaryText = message ? message : ''; this._messageSummaryText = message ? message : '';
this._messageDetailText = description ? description : ''; this._messageDetailText = description ? description : '';
@@ -461,8 +457,8 @@ export abstract class Modal extends Disposable implements IThemable {
this._messageIcon.title = severityText; this._messageIcon.title = severityText;
this._messageSeverity.innerText = severityText; this._messageSeverity.innerText = severityText;
this._messageSummary.innerText = message; this._messageSummary.innerText = message!;
this._messageSummary.title = message; this._messageSummary.title = message!;
this._messageDetail.innerText = description; this._messageDetail.innerText = description;
} }
DOM.hide(this._messageDetail); DOM.hide(this._messageDetail);
@@ -491,7 +487,7 @@ export abstract class Modal extends Disposable implements IThemable {
/** /**
* Return background color of header and footer * Return background color of header and footer
*/ */
protected get headerAndFooterBackground(): string { protected get headerAndFooterBackground(): string | null {
return this._dialogHeaderAndFooterBackground ? this._dialogHeaderAndFooterBackground.toString() : null; return this._dialogHeaderAndFooterBackground ? this._dialogHeaderAndFooterBackground.toString() : null;
} }
@@ -533,10 +529,8 @@ export abstract class Modal extends Disposable implements IThemable {
const border = this._dialogBorder ? this._dialogBorder.toString() : null; const border = this._dialogBorder ? this._dialogBorder.toString() : null;
const headerAndFooterBackground = this._dialogHeaderAndFooterBackground ? this._dialogHeaderAndFooterBackground.toString() : null; const headerAndFooterBackground = this._dialogHeaderAndFooterBackground ? this._dialogHeaderAndFooterBackground.toString() : null;
const bodyBackground = this._dialogBodyBackground ? this._dialogBodyBackground.toString() : null; const bodyBackground = this._dialogBodyBackground ? this._dialogBodyBackground.toString() : null;
ModalFooterStyle.backgroundColor = headerAndFooterBackground; const footerBorderTopWidth = border ? '1px' : null;
ModalFooterStyle.borderTopWidth = border ? '1px' : null; const footerBorderTopStyle = border ? 'solid' : null;
ModalFooterStyle.borderTopStyle = border ? 'solid' : null;
ModalFooterStyle.borderTopColor = border;
if (this._closeButtonInHeader) { if (this._closeButtonInHeader) {
this._closeButtonInHeader.style.color = foreground; this._closeButtonInHeader.style.color = foreground;
@@ -567,10 +561,10 @@ export abstract class Modal extends Disposable implements IThemable {
} }
if (this._modalFooterSection) { if (this._modalFooterSection) {
this._modalFooterSection.style.backgroundColor = ModalFooterStyle.backgroundColor; this._modalFooterSection.style.backgroundColor = headerAndFooterBackground;
this._modalFooterSection.style.borderTopWidth = ModalFooterStyle.borderTopWidth; this._modalFooterSection.style.borderTopWidth = footerBorderTopWidth;
this._modalFooterSection.style.borderTopStyle = ModalFooterStyle.borderTopStyle; this._modalFooterSection.style.borderTopStyle = footerBorderTopStyle;
this._modalFooterSection.style.borderTopColor = ModalFooterStyle.borderTopColor; this._modalFooterSection.style.borderTopColor = border;
} }
} }

View File

@@ -10,7 +10,6 @@ import { Button } from 'sql/base/browser/ui/button/button';
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox'; import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox';
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox'; import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
import { ListBox } from 'sql/base/browser/ui/listBox/listBox'; import { ListBox } from 'sql/base/browser/ui/listBox/listBox';
import { ModalFooterStyle } from 'sql/workbench/browser/modal/modal';
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox'; import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
import { attachButtonStyler, attachListBoxStyler, attachInputBoxStyler, attachSelectBoxStyler, attachCheckboxStyler } from 'sql/platform/theme/common/styler'; import { attachButtonStyler, attachListBoxStyler, attachInputBoxStyler, attachSelectBoxStyler, attachCheckboxStyler } from 'sql/platform/theme/common/styler';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
@@ -20,6 +19,7 @@ import * as FileValidationConstants from 'sql/workbench/services/fileBrowser/com
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement'; import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { IFileBrowserDialogController } from 'sql/workbench/services/fileBrowser/common/fileBrowserDialogController'; import { IFileBrowserDialogController } from 'sql/workbench/services/fileBrowser/common/fileBrowserDialogController';
import { IBackupUiService } from 'sql/workbench/services/backup/common/backupUiService'; import { IBackupUiService } from 'sql/workbench/services/backup/common/backupUiService';
import * as cr from 'vs/platform/theme/common/colorRegistry';
import { MessageType } from 'vs/base/browser/ui/inputbox/inputBox'; import { MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
import * as lifecycle from 'vs/base/common/lifecycle'; import * as lifecycle from 'vs/base/common/lifecycle';
@@ -32,6 +32,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox'; import { ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
import { KeyCode } from 'vs/base/common/keyCodes'; import { KeyCode } from 'vs/base/common/keyCodes';
import { ITheme } from 'vs/platform/theme/common/themeService';
export const BACKUP_SELECTOR: string = 'backup-component'; export const BACKUP_SELECTOR: string = 'backup-component';
@@ -350,7 +351,7 @@ export class BackupComponent {
this.mediaDescriptionBox.disable(); this.mediaDescriptionBox.disable();
this.registerListeners(); this.registerListeners();
this.updateTheme(); this.updateTheme(this.themeService.getTheme());
} }
ngAfterViewInit() { ngAfterViewInit() {
@@ -549,17 +550,21 @@ export class BackupComponent {
this.backupRetainDaysChanged(days); this.backupRetainDaysChanged(days);
})); }));
this._toDispose.push(this.themeService.onDidColorThemeChange(e => this.updateTheme())); this._toDispose.push(this.themeService.onDidColorThemeChange(e => this.updateTheme(e)));
} }
// Update theming that is specific to backup dialog // Update theming that is specific to backup dialog
private updateTheme(): void { private updateTheme(theme: ITheme): void {
// set modal footer style // set modal footer style
let footerHtmlElement: HTMLElement = <HTMLElement>this.modalFooterElement.nativeElement; let footerHtmlElement: HTMLElement = <HTMLElement>this.modalFooterElement.nativeElement;
footerHtmlElement.style.backgroundColor = ModalFooterStyle.backgroundColor; const backgroundColor = theme.getColor(cr.foreground);
footerHtmlElement.style.borderTopWidth = ModalFooterStyle.borderTopWidth; const border = theme.getColor(cr.contrastBorder) ? theme.getColor(cr.contrastBorder).toString() : null;
footerHtmlElement.style.borderTopStyle = ModalFooterStyle.borderTopStyle; const footerBorderTopWidth = border ? '1px' : null;
footerHtmlElement.style.borderTopColor = ModalFooterStyle.borderTopColor; const footerBorderTopStyle = border ? 'solid' : null;
footerHtmlElement.style.backgroundColor = backgroundColor ? backgroundColor.toString() : null;
footerHtmlElement.style.borderTopWidth = footerBorderTopWidth;
footerHtmlElement.style.borderTopStyle = footerBorderTopStyle;
footerHtmlElement.style.borderTopColor = border;
} }
private addButtonClickHandler(button: Button, handler: () => void) { private addButtonClickHandler(button: Button, handler: () => void) {

View File

@@ -10,23 +10,23 @@ import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
export class TestResourceProvider implements IResourceProviderService { export class TestResourceProvider implements IResourceProviderService {
_serviceBrand: any; _serviceBrand: any;
registerProvider(providerId: string, provider: azdata.ResourceProvider) { registerProvider(providerId: string, provider: azdata.ResourceProvider): void {
} }
unregisterProvider(ProviderId: string) { unregisterProvider(ProviderId: string): void {
} }
createFirewallRule(selectedAccount: azdata.Account, firewallruleInfo: azdata.FirewallRuleInfo, resourceProviderId: string): Promise<azdata.CreateFirewallRuleResponse> { createFirewallRule(selectedAccount: azdata.Account, firewallruleInfo: azdata.FirewallRuleInfo, resourceProviderId: string): Promise<azdata.CreateFirewallRuleResponse> {
return undefined; throw new Error('Method not implemented');
} }
handleFirewallRule(errorCode: number, errorMessage: string, connectionTypeId: string): Promise<IHandleFirewallRuleResult> { handleFirewallRule(errorCode: number, errorMessage: string, connectionTypeId: string): Promise<IHandleFirewallRuleResult> {
return undefined; throw new Error('Method not implemented');
} }
showFirewallRuleDialog(connection: IConnectionProfile, ipAddress: string, resourceProviderId: string): Promise<boolean> { showFirewallRuleDialog(connection: IConnectionProfile, ipAddress: string, resourceProviderId: string): Promise<boolean> {
return undefined; return Promise.resolve(true);
} }
} }

View File

@@ -18,6 +18,7 @@
"./sql/base/**/*.ts", "./sql/base/**/*.ts",
"./sql/editor/**/*.ts", "./sql/editor/**/*.ts",
"./sql/platform/angularEventing/**/*.ts", "./sql/platform/angularEventing/**/*.ts",
"./sql/platform/accounts/**/*.ts",
"./sql/platform/clipboard/**/*.ts", "./sql/platform/clipboard/**/*.ts",
"./sql/platform/credentials/**/*.ts", "./sql/platform/credentials/**/*.ts",
"./sql/platform/theme/**/*.ts", "./sql/platform/theme/**/*.ts",