Code Layering Accounts (#4882)
* code layering for accounts * formatting * formatting * formatting
@@ -3,10 +3,8 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import 'vs/css!./media/accountDialog';
|
import 'vs/css!./media/accountDialog';
|
||||||
import 'vs/css!sql/parts/accountManagement/common/media/accountActions';
|
import 'vs/css!./media/accountActions';
|
||||||
import * as DOM from 'vs/base/browser/dom';
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
import { List } from 'vs/base/browser/ui/list/listWidget';
|
import { List } from 'vs/base/browser/ui/list/listWidget';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
@@ -29,10 +27,10 @@ import * as azdata from 'azdata';
|
|||||||
import { Button } from 'sql/base/browser/ui/button/button';
|
import { Button } from 'sql/base/browser/ui/button/button';
|
||||||
import { Modal } from 'sql/workbench/browser/modal/modal';
|
import { Modal } from 'sql/workbench/browser/modal/modal';
|
||||||
import { attachModalDialogStyler, attachButtonStyler, attachPanelStyler } from 'sql/platform/theme/common/styler';
|
import { attachModalDialogStyler, attachButtonStyler, attachPanelStyler } from 'sql/platform/theme/common/styler';
|
||||||
import { AccountViewModel } from 'sql/parts/accountManagement/accountDialog/accountViewModel';
|
import { AccountViewModel } from 'sql/platform/accounts/common/accountViewModel';
|
||||||
import { AddAccountAction } from 'sql/parts/accountManagement/common/accountActions';
|
import { AddAccountAction } from 'sql/platform/accounts/common/accountActions';
|
||||||
import { AccountListRenderer, AccountListDelegate } from 'sql/parts/accountManagement/common/accountListRenderer';
|
import { AccountListRenderer, AccountListDelegate } from 'sql/platform/accounts/browser/accountListRenderer';
|
||||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService';
|
import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService';
|
||||||
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
||||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||||
@@ -149,7 +147,7 @@ export class AccountDialog extends Modal {
|
|||||||
// Load the initial contents of the view model
|
// Load the initial contents of the view model
|
||||||
this.viewModel.initialize()
|
this.viewModel.initialize()
|
||||||
.then(addedProviders => {
|
.then(addedProviders => {
|
||||||
for (let addedProvider of addedProviders) {
|
for (const addedProvider of addedProviders) {
|
||||||
this.addProvider(addedProvider);
|
this.addProvider(addedProvider);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -174,13 +172,13 @@ export class AccountDialog extends Modal {
|
|||||||
this._splitView = new SplitView(this._splitViewContainer);
|
this._splitView = new SplitView(this._splitViewContainer);
|
||||||
|
|
||||||
this._noaccountViewContainer = DOM.$('div.no-account-view');
|
this._noaccountViewContainer = DOM.$('div.no-account-view');
|
||||||
let noAccountTitle = DOM.append(this._noaccountViewContainer, DOM.$('.no-account-view-label'));
|
const noAccountTitle = DOM.append(this._noaccountViewContainer, DOM.$('.no-account-view-label'));
|
||||||
let noAccountLabel = localize('accountDialog.noAccountLabel', 'There is no linked account. Please add an account.');
|
const noAccountLabel = localize('accountDialog.noAccountLabel', 'There is no linked account. Please add an account.');
|
||||||
noAccountTitle.innerText = noAccountLabel;
|
noAccountTitle.innerText = noAccountLabel;
|
||||||
|
|
||||||
// Show the add account button for the first provider
|
// Show the add account button for the first provider
|
||||||
// Todo: If we have more than 1 provider, need to show all add account buttons for all providers
|
// Todo: If we have more than 1 provider, need to show all add account buttons for all providers
|
||||||
let buttonSection = DOM.append(this._noaccountViewContainer, DOM.$('div.button-section'));
|
const buttonSection = DOM.append(this._noaccountViewContainer, DOM.$('div.button-section'));
|
||||||
this._addAccountButton = new Button(buttonSection);
|
this._addAccountButton = new Button(buttonSection);
|
||||||
this._addAccountButton.label = localize('accountDialog.addConnection', 'Add an account');
|
this._addAccountButton.label = localize('accountDialog.addConnection', 'Add an account');
|
||||||
this._register(this._addAccountButton.onDidClick(() => {
|
this._register(this._addAccountButton.onDidClick(() => {
|
||||||
@@ -231,7 +229,7 @@ export class AccountDialog extends Modal {
|
|||||||
this._splitViewContainer.hidden = false;
|
this._splitViewContainer.hidden = false;
|
||||||
this._noaccountViewContainer.hidden = true;
|
this._noaccountViewContainer.hidden = true;
|
||||||
if (values(this._providerViewsMap).length > 0) {
|
if (values(this._providerViewsMap).length > 0) {
|
||||||
let firstView = values(this._providerViewsMap)[0];
|
const firstView = values(this._providerViewsMap)[0];
|
||||||
if (firstView instanceof AccountPanel) {
|
if (firstView instanceof AccountPanel) {
|
||||||
firstView.setSelection([0]);
|
firstView.setSelection([0]);
|
||||||
firstView.focus();
|
firstView.focus();
|
||||||
@@ -240,8 +238,8 @@ export class AccountDialog extends Modal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private isEmptyLinkedAccount(): boolean {
|
private isEmptyLinkedAccount(): boolean {
|
||||||
for (let provider of values(this._providerViewsMap)) {
|
for (const provider of values(this._providerViewsMap)) {
|
||||||
let listView = provider.view;
|
const listView = provider.view;
|
||||||
if (listView && listView.length > 0) {
|
if (listView && listView.length > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -251,7 +249,7 @@ export class AccountDialog extends Modal {
|
|||||||
|
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
for (let provider of values(this._providerViewsMap)) {
|
for (const provider of values(this._providerViewsMap)) {
|
||||||
if (provider.addAccountAction) {
|
if (provider.addAccountAction) {
|
||||||
provider.addAccountAction.dispose();
|
provider.addAccountAction.dispose();
|
||||||
}
|
}
|
||||||
@@ -317,7 +315,7 @@ export class AccountDialog extends Modal {
|
|||||||
|
|
||||||
private removeProvider(removedProvider: azdata.AccountProviderMetadata) {
|
private removeProvider(removedProvider: azdata.AccountProviderMetadata) {
|
||||||
// Skip removing the provider if it doesn't exist
|
// Skip removing the provider if it doesn't exist
|
||||||
let providerView = this._providerViewsMap.get(removedProvider.id);
|
const providerView = this._providerViewsMap.get(removedProvider.id);
|
||||||
if (!providerView || !providerView.view) {
|
if (!providerView || !providerView.view) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -332,7 +330,7 @@ export class AccountDialog extends Modal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateProviderAccounts(args: UpdateAccountListEventParams) {
|
private updateProviderAccounts(args: UpdateAccountListEventParams) {
|
||||||
let providerMapping = this._providerViewsMap.get(args.providerId);
|
const providerMapping = this._providerViewsMap.get(args.providerId);
|
||||||
if (!providerMapping || !providerMapping.view) {
|
if (!providerMapping || !providerMapping.view) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,8 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
import { AccountDialog } from 'sql/parts/accountManagement/accountDialog/accountDialog';
|
import { AccountDialog } from 'sql/platform/accounts/browser/accountDialog';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||||
@@ -28,13 +26,11 @@ export class AccountDialogController {
|
|||||||
* Open account dialog
|
* Open account dialog
|
||||||
*/
|
*/
|
||||||
public openAccountDialog(): void {
|
public openAccountDialog(): void {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
// Create a new dialog if one doesn't exist
|
// Create a new dialog if one doesn't exist
|
||||||
if (!this._accountDialog) {
|
if (!this._accountDialog) {
|
||||||
this._accountDialog = this._instantiationService.createInstance(AccountDialog);
|
this._accountDialog = this._instantiationService.createInstance(AccountDialog);
|
||||||
this._accountDialog.onAddAccountErrorEvent(msg => { self.handleOnAddAccountError(msg); });
|
this._accountDialog.onAddAccountErrorEvent(msg => this.handleOnAddAccountError(msg));
|
||||||
this._accountDialog.onCloseEvent(() => { self.handleOnClose(); });
|
this._accountDialog.onCloseEvent(() => this.handleOnClose());
|
||||||
this._accountDialog.render();
|
this._accountDialog.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3,17 +3,17 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
import 'vs/css!./media/accountListRenderer';
|
||||||
import 'vs/css!sql/parts/accountManagement/common/media/accountListRenderer';
|
import 'vs/css!./media/accountActions';
|
||||||
import 'vs/css!sql/parts/accountManagement/common/media/accountActions';
|
|
||||||
import 'vs/css!sql/media/icons/common-icons';
|
import 'vs/css!sql/media/icons/common-icons';
|
||||||
|
|
||||||
import * as DOM from 'vs/base/browser/dom';
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||||
import { ActionBar, IActionOptions } from 'vs/base/browser/ui/actionbar/actionbar';
|
import { ActionBar, IActionOptions } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
|
||||||
import { RemoveAccountAction, RefreshAccountAction } from 'sql/parts/accountManagement/common/accountActions';
|
import { RemoveAccountAction, RefreshAccountAction } from 'sql/platform/accounts/common/accountActions';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
@@ -114,9 +114,9 @@ export class AccountListRenderer extends AccountPickerListRenderer {
|
|||||||
}
|
}
|
||||||
templateData.actions.clear();
|
templateData.actions.clear();
|
||||||
|
|
||||||
let actionOptions: IActionOptions = { icon: true, label: false };
|
const actionOptions: IActionOptions = { icon: true, label: false };
|
||||||
if (account.isStale) {
|
if (account.isStale) {
|
||||||
let refreshAction = this._instantiationService.createInstance(RefreshAccountAction);
|
const refreshAction = this._instantiationService.createInstance(RefreshAccountAction);
|
||||||
refreshAction.account = account;
|
refreshAction.account = account;
|
||||||
templateData.actions.push(refreshAction, actionOptions);
|
templateData.actions.push(refreshAction, actionOptions);
|
||||||
} else {
|
} else {
|
||||||
@@ -124,7 +124,7 @@ export class AccountListRenderer extends AccountPickerListRenderer {
|
|||||||
// templateData.actions.push(new ApplyFilterAction(ApplyFilterAction.ID, ApplyFilterAction.LABEL), actionOptions);
|
// templateData.actions.push(new ApplyFilterAction(ApplyFilterAction.ID, ApplyFilterAction.LABEL), actionOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
let removeAction = this._instantiationService.createInstance(RemoveAccountAction, account);
|
const removeAction = this._instantiationService.createInstance(RemoveAccountAction, account);
|
||||||
templateData.actions.push(removeAction, actionOptions);
|
templateData.actions.push(removeAction, actionOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,6 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import 'vs/css!./media/accountListStatusbarItem';
|
import 'vs/css!./media/accountListStatusbarItem';
|
||||||
import { Action, IAction } from 'vs/base/common/actions';
|
import { Action, IAction } from 'vs/base/common/actions';
|
||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||||
@@ -16,7 +14,7 @@ import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
|
|||||||
import { Themable, STATUS_BAR_FOREGROUND } from 'vs/workbench/common/theme';
|
import { Themable, STATUS_BAR_FOREGROUND } from 'vs/workbench/common/theme';
|
||||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
|
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
|
|
||||||
export class AccountListStatusbarItem extends Themable implements IStatusbarItem {
|
export class AccountListStatusbarItem extends Themable implements IStatusbarItem {
|
||||||
private _manageLinkedAccountAction: IAction;
|
private _manageLinkedAccountAction: IAction;
|
||||||
@@ -24,7 +22,6 @@ export class AccountListStatusbarItem extends Themable implements IStatusbarItem
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||||
@IAccountManagementService private _accountManagementService: IAccountManagementService,
|
|
||||||
@IThemeService themeService: IThemeService
|
@IThemeService themeService: IThemeService
|
||||||
) {
|
) {
|
||||||
super(themeService);
|
super(themeService);
|
||||||
@@ -3,8 +3,6 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||||
@@ -15,7 +13,7 @@ import { join } from 'path';
|
|||||||
import { createCSSRule } from 'vs/base/browser/dom';
|
import { createCSSRule } from 'vs/base/browser/dom';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
|
|
||||||
import { ManageLinkedAccountAction } from 'sql/parts/accountManagement/accountListStatusbar/accountListStatusbarItem';
|
import { ManageLinkedAccountAction } from 'sql/platform/accounts/browser/accountListStatusbarItem';
|
||||||
|
|
||||||
let actionRegistry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
|
let actionRegistry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
|
||||||
|
|
||||||
@@ -78,10 +76,9 @@ export const accountsContribution: IJSONSchema = {
|
|||||||
ExtensionsRegistry.registerExtensionPoint<IAccountContrib | IAccountContrib[]>({ extensionPoint: 'account-type', jsonSchema: accountsContribution }).setHandler(extensions => {
|
ExtensionsRegistry.registerExtensionPoint<IAccountContrib | IAccountContrib[]>({ extensionPoint: 'account-type', jsonSchema: accountsContribution }).setHandler(extensions => {
|
||||||
|
|
||||||
function handleCommand(account: IAccountContrib, extension: IExtensionPointUser<any>) {
|
function handleCommand(account: IAccountContrib, extension: IExtensionPointUser<any>) {
|
||||||
let { icon, id } = account;
|
const { icon, id } = account;
|
||||||
let iconClass: string;
|
|
||||||
if (icon) {
|
if (icon) {
|
||||||
iconClass = id;
|
const iconClass = id;
|
||||||
if (typeof icon === 'string') {
|
if (typeof icon === 'string') {
|
||||||
const path = join(extension.description.extensionLocation.fsPath, icon);
|
const path = join(extension.description.extensionLocation.fsPath, icon);
|
||||||
createCSSRule(`.icon.${iconClass}`, `background-image: url("${URI.file(path).toString()}")`);
|
createCSSRule(`.icon.${iconClass}`, `background-image: url("${URI.file(path).toString()}")`);
|
||||||
@@ -106,4 +103,3 @@ ExtensionsRegistry.registerExtensionPoint<IAccountContrib | IAccountContrib[]>({
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
import 'vs/css!./media/accountPicker';
|
import 'vs/css!./media/accountPicker';
|
||||||
import * as DOM from 'vs/base/browser/dom';
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
@@ -21,9 +20,9 @@ import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
|
|||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { DropdownList } from 'sql/base/browser/ui/dropdownList/dropdownList';
|
import { DropdownList } from 'sql/base/browser/ui/dropdownList/dropdownList';
|
||||||
import { attachDropdownStyler } from 'sql/platform/theme/common/styler';
|
import { attachDropdownStyler } from 'sql/platform/theme/common/styler';
|
||||||
import { AddAccountAction, RefreshAccountAction } from 'sql/parts/accountManagement/common/accountActions';
|
import { AddAccountAction, RefreshAccountAction } from 'sql/platform/accounts/common/accountActions';
|
||||||
import { AccountPickerListRenderer, AccountListDelegate } from 'sql/parts/accountManagement/common/accountListRenderer';
|
import { AccountPickerListRenderer, AccountListDelegate } from 'sql/platform/accounts/browser/accountListRenderer';
|
||||||
import { AccountPickerViewModel } from 'sql/platform/accountManagement/common/accountPickerViewModel';
|
import { AccountPickerViewModel } from 'sql/platform/accounts/common/accountPickerViewModel';
|
||||||
|
|
||||||
export class AccountPicker extends Disposable {
|
export class AccountPicker extends Disposable {
|
||||||
public static ACCOUNTPICKERLIST_HEIGHT = 47;
|
public static ACCOUNTPICKERLIST_HEIGHT = 47;
|
||||||
@@ -85,8 +84,8 @@ export class AccountPicker extends Disposable {
|
|||||||
*/
|
*/
|
||||||
public createAccountPickerComponent() {
|
public createAccountPickerComponent() {
|
||||||
// Create an account list
|
// Create an account list
|
||||||
let delegate = new AccountListDelegate(AccountPicker.ACCOUNTPICKERLIST_HEIGHT);
|
const delegate = new AccountListDelegate(AccountPicker.ACCOUNTPICKERLIST_HEIGHT);
|
||||||
let accountRenderer = new AccountPickerListRenderer();
|
const accountRenderer = new AccountPickerListRenderer();
|
||||||
this._listContainer = DOM.$('div.account-list-container');
|
this._listContainer = DOM.$('div.account-list-container');
|
||||||
this._accountList = new List<azdata.Account>(this._listContainer, delegate, [accountRenderer]);
|
this._accountList = new List<azdata.Account>(this._listContainer, delegate, [accountRenderer]);
|
||||||
this._register(attachListStyler(this._accountList, this._themeService));
|
this._register(attachListStyler(this._accountList, this._themeService));
|
||||||
@@ -94,13 +93,13 @@ export class AccountPicker extends Disposable {
|
|||||||
this._rootElement = DOM.$('div.account-picker-container');
|
this._rootElement = DOM.$('div.account-picker-container');
|
||||||
|
|
||||||
// Create a dropdown for account picker
|
// Create a dropdown for account picker
|
||||||
let option: IDropdownOptions = {
|
const option: IDropdownOptions = {
|
||||||
contextViewProvider: this._contextViewService,
|
contextViewProvider: this._contextViewService,
|
||||||
labelRenderer: (container) => this.renderLabel(container)
|
labelRenderer: (container) => this.renderLabel(container)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the add account action
|
// Create the add account action
|
||||||
let addAccountAction = this._instantiationService.createInstance(AddAccountAction, this._providerId);
|
const addAccountAction = this._instantiationService.createInstance(AddAccountAction, this._providerId);
|
||||||
addAccountAction.addAccountCompleteEvent(() => this._addAccountCompleteEmitter.fire());
|
addAccountAction.addAccountCompleteEvent(() => this._addAccountCompleteEmitter.fire());
|
||||||
addAccountAction.addAccountErrorEvent((msg) => this._addAccountErrorEmitter.fire(msg));
|
addAccountAction.addAccountErrorEvent((msg) => this._addAccountErrorEmitter.fire(msg));
|
||||||
addAccountAction.addAccountStartEvent(() => this._addAccountStartEmitter.fire());
|
addAccountAction.addAccountStartEvent(() => this._addAccountStartEmitter.fire());
|
||||||
@@ -117,7 +116,7 @@ export class AccountPicker extends Disposable {
|
|||||||
// Create refresh account action
|
// Create refresh account action
|
||||||
this._refreshContainer = DOM.append(this._rootElement, DOM.$('div.refresh-container'));
|
this._refreshContainer = DOM.append(this._rootElement, DOM.$('div.refresh-container'));
|
||||||
DOM.append(this._refreshContainer, DOM.$('div.sql icon warning'));
|
DOM.append(this._refreshContainer, DOM.$('div.sql icon warning'));
|
||||||
let actionBar = new ActionBar(this._refreshContainer, { animated: false });
|
const actionBar = new ActionBar(this._refreshContainer, { animated: false });
|
||||||
this._refreshAccountAction = this._instantiationService.createInstance(RefreshAccountAction);
|
this._refreshAccountAction = this._instantiationService.createInstance(RefreshAccountAction);
|
||||||
actionBar.push(this._refreshAccountAction, { icon: false, label: true });
|
actionBar.push(this._refreshAccountAction, { icon: false, label: true });
|
||||||
|
|
||||||
@@ -165,8 +164,8 @@ export class AccountPicker extends Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let selectedAccounts = this._accountList.getSelectedElements();
|
const selectedAccounts = this._accountList.getSelectedElements();
|
||||||
let account = selectedAccounts ? selectedAccounts[0] : null;
|
const account = selectedAccounts ? selectedAccounts[0] : undefined;
|
||||||
if (account) {
|
if (account) {
|
||||||
const badge = DOM.$('div.badge');
|
const badge = DOM.$('div.badge');
|
||||||
const row = DOM.append(container, DOM.$('div.selected-account-container'));
|
const row = DOM.append(container, DOM.$('div.selected-account-container'));
|
||||||
@@ -190,12 +189,12 @@ 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 null;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateAccountList(accounts: azdata.Account[]): void {
|
private updateAccountList(accounts: azdata.Account[]): void {
|
||||||
// keep the selection to the current one
|
// keep the selection to the current one
|
||||||
let selectedElements = this._accountList.getSelectedElements();
|
const selectedElements = this._accountList.getSelectedElements();
|
||||||
|
|
||||||
// find selected index
|
// find selected index
|
||||||
let selectedIndex: number;
|
let selectedIndex: number;
|
||||||
@@ -227,8 +226,8 @@ export class AccountPicker extends Disposable {
|
|||||||
* Update theming that is specific to account picker
|
* Update theming that is specific to account picker
|
||||||
*/
|
*/
|
||||||
private updateTheme(theme: ITheme): void {
|
private updateTheme(theme: ITheme): void {
|
||||||
let linkColor = theme.getColor(buttonBackground);
|
const linkColor = theme.getColor(buttonBackground);
|
||||||
let link = linkColor ? linkColor.toString() : null;
|
const link = linkColor ? linkColor.toString() : null;
|
||||||
this._refreshContainer.style.color = link;
|
this._refreshContainer.style.color = link;
|
||||||
if (this._refreshContainer) {
|
if (this._refreshContainer) {
|
||||||
this._refreshContainer.style.color = link;
|
this._refreshContainer.style.color = link;
|
||||||
@@ -3,13 +3,12 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
import { IAccountPickerService } from 'sql/platform/accountManagement/common/accountPicker';
|
import { IAccountPickerService } from 'sql/platform/accounts/common/accountPicker';
|
||||||
import { AccountPicker } from 'sql/platform/accountManagement/browser/accountPicker';
|
import { AccountPicker } from 'sql/platform/accounts/browser/accountPicker';
|
||||||
|
|
||||||
export class AccountPickerService implements IAccountPickerService {
|
export class AccountPickerService implements IAccountPickerService {
|
||||||
_serviceBrand: any;
|
_serviceBrand: any;
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
import 'vs/css!./media/autoOAuthDialog';
|
import 'vs/css!./media/autoOAuthDialog';
|
||||||
import { Builder, $ } from 'sql/base/browser/builder';
|
import { Builder, $ } from 'sql/base/browser/builder';
|
||||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
@@ -3,13 +3,12 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
|
|
||||||
import { AutoOAuthDialog } from 'sql/parts/accountManagement/autoOAuthDialog/autoOAuthDialog';
|
import { AutoOAuthDialog } from 'sql/platform/accounts/browser/autoOAuthDialog';
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||||
|
|
||||||
export class AutoOAuthDialogController {
|
export class AutoOAuthDialogController {
|
||||||
@@ -33,7 +32,7 @@ export class AutoOAuthDialogController {
|
|||||||
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 !== null) {
|
||||||
// If a oauth flyout is already open, return an error
|
// If a oauth flyout is already open, return an error
|
||||||
let 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);
|
||||||
return Promise.reject(new Error('Auto OAuth dialog already open'));
|
return Promise.reject(new Error('Auto OAuth dialog already open'));
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,6 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import 'vs/css!./media/firewallRuleDialog';
|
import 'vs/css!./media/firewallRuleDialog';
|
||||||
import { Builder, $ } from 'sql/base/browser/builder';
|
import { Builder, $ } from 'sql/base/browser/builder';
|
||||||
import * as DOM from 'vs/base/browser/dom';
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
@@ -24,10 +22,10 @@ import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
|
|||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { Button } from 'sql/base/browser/ui/button/button';
|
import { Button } from 'sql/base/browser/ui/button/button';
|
||||||
import { Modal } from 'sql/workbench/browser/modal/modal';
|
import { Modal } from 'sql/workbench/browser/modal/modal';
|
||||||
import { FirewallRuleViewModel } from 'sql/parts/accountManagement/firewallRuleDialog/firewallRuleViewModel';
|
import { FirewallRuleViewModel } from 'sql/platform/accounts/common/firewallRuleViewModel';
|
||||||
import { attachModalDialogStyler, attachButtonStyler } from 'sql/platform/theme/common/styler';
|
import { attachModalDialogStyler, attachButtonStyler } from 'sql/platform/theme/common/styler';
|
||||||
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
|
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
|
||||||
import { IAccountPickerService } from 'sql/platform/accountManagement/common/accountPicker';
|
import { IAccountPickerService } from 'sql/platform/accounts/common/accountPicker';
|
||||||
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
||||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||||
|
|
||||||
@@ -173,7 +171,7 @@ export class FirewallRuleDialog extends Modal {
|
|||||||
let firewallRuleSection;
|
let firewallRuleSection;
|
||||||
$().div({ 'class': 'firewall-rule-section new-section' }, (firewallRuleContainer) => {
|
$().div({ 'class': 'firewall-rule-section new-section' }, (firewallRuleContainer) => {
|
||||||
firewallRuleSection = firewallRuleContainer.getHTMLElement();
|
firewallRuleSection = firewallRuleContainer.getHTMLElement();
|
||||||
let firewallRuleLabel = localize('filewallRule', 'Firewall rule');
|
const firewallRuleLabel = localize('filewallRule', 'Firewall rule');
|
||||||
this.createLabelElement(firewallRuleContainer, firewallRuleLabel, true);
|
this.createLabelElement(firewallRuleContainer, firewallRuleLabel, true);
|
||||||
firewallRuleContainer.div({ 'class': 'radio-section' }, (radioContainer) => {
|
firewallRuleContainer.div({ 'class': 'radio-section' }, (radioContainer) => {
|
||||||
const form = DOM.append(radioContainer.getHTMLElement(), DOM.$('form.firewall-rule'));
|
const form = DOM.append(radioContainer.getHTMLElement(), DOM.$('form.firewall-rule'));
|
||||||
@@ -244,8 +242,8 @@ export class FirewallRuleDialog extends Modal {
|
|||||||
|
|
||||||
// Update theming that is specific to firewall rule flyout body
|
// Update theming that is specific to firewall rule flyout body
|
||||||
private updateTheme(theme: ITheme): void {
|
private updateTheme(theme: ITheme): void {
|
||||||
let linkColor = theme.getColor(buttonBackground);
|
const linkColor = theme.getColor(buttonBackground);
|
||||||
let link = linkColor ? linkColor.toString() : null;
|
const link = linkColor ? linkColor.toString() : null;
|
||||||
if (this._helpLink) {
|
if (this._helpLink) {
|
||||||
this._helpLink.style.color = link;
|
this._helpLink.style.color = link;
|
||||||
}
|
}
|
||||||
@@ -3,15 +3,14 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||||
import { FirewallRuleDialog } from 'sql/parts/accountManagement/firewallRuleDialog/firewallRuleDialog';
|
import { FirewallRuleDialog } from 'sql/platform/accounts/browser/firewallRuleDialog';
|
||||||
import { IAccountManagementService, AzureResource } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService, AzureResource } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { IResourceProviderService } from 'sql/workbench/services/resourceProvider/common/resourceProviderService';
|
import { IResourceProviderService } from 'sql/workbench/services/resourceProvider/common/resourceProviderService';
|
||||||
import { Deferred } from 'sql/base/common/promise';
|
import { Deferred } from 'sql/base/common/promise';
|
||||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||||
@@ -59,7 +58,7 @@ export class FirewallRuleDialogController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private handleOnCreateFirewallRule(): void {
|
private handleOnCreateFirewallRule(): void {
|
||||||
let resourceProviderId = this._resourceProviderId;
|
const resourceProviderId = this._resourceProviderId;
|
||||||
|
|
||||||
this._accountManagementService.getSecurityToken(this._firewallRuleDialog.viewModel.selectedAccount, AzureResource.ResourceManagement).then(tokenMappings => {
|
this._accountManagementService.getSecurityToken(this._firewallRuleDialog.viewModel.selectedAccount, AzureResource.ResourceManagement).then(tokenMappings => {
|
||||||
let firewallRuleInfo: azdata.FirewallRuleInfo = {
|
let firewallRuleInfo: azdata.FirewallRuleInfo = {
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
.no-account-view {
|
.no-account-view {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
@@ -102,7 +103,3 @@
|
|||||||
.account-view .monaco-list .monaco-list-row.focused .list-row .actions-container{
|
.account-view .monaco-list .monaco-list-row.focused .list-row .actions-container{
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.account-view .monaco-list .monaco-list-row {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 850 B After Width: | Height: | Size: 850 B |
|
Before Width: | Height: | Size: 918 B After Width: | Height: | Size: 918 B |
|
Before Width: | Height: | Size: 894 B After Width: | Height: | Size: 894 B |
@@ -3,15 +3,13 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { Action } from 'vs/base/common/actions';
|
import { Action } from 'vs/base/common/actions';
|
||||||
|
|
||||||
import { error } from 'sql/base/common/log';
|
import { error } from 'sql/base/common/log';
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { IDialogService, IConfirmation } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService, IConfirmation } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
@@ -47,26 +45,19 @@ export class AddAccountAction extends Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public run(): Promise<boolean> {
|
public run(): Promise<boolean> {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
// Fire the event that we've started adding accounts
|
// Fire the event that we've started adding accounts
|
||||||
this._addAccountStartEmitter.fire();
|
this._addAccountStartEmitter.fire();
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return Promise.resolve(this._accountManagementService.addAccount(this._providerId)
|
||||||
self._accountManagementService.addAccount(self._providerId)
|
.then(() => {
|
||||||
.then(
|
this._addAccountCompleteEmitter.fire();
|
||||||
() => {
|
return true;
|
||||||
self._addAccountCompleteEmitter.fire();
|
}, err => {
|
||||||
resolve(true);
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
error(`Error while adding account: ${err}`);
|
error(`Error while adding account: ${err}`);
|
||||||
self._addAccountErrorEmitter.fire(err);
|
this._addAccountErrorEmitter.fire(err);
|
||||||
self._addAccountCompleteEmitter.fire();
|
this._addAccountCompleteEmitter.fire();
|
||||||
reject(err);
|
}));
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,10 +78,8 @@ export class RemoveAccountAction extends Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public run(): Promise<boolean> {
|
public run(): Promise<boolean> {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
// Ask for Confirm
|
// Ask for Confirm
|
||||||
let confirm: IConfirmation = {
|
const confirm: IConfirmation = {
|
||||||
message: localize('confirmRemoveUserAccountMessage', "Are you sure you want to remove '{0}'?", this._account.displayInfo.displayName),
|
message: localize('confirmRemoveUserAccountMessage', "Are you sure you want to remove '{0}'?", this._account.displayInfo.displayName),
|
||||||
primaryButton: localize('accountActions.yes', 'Yes'),
|
primaryButton: localize('accountActions.yes', 'Yes'),
|
||||||
secondaryButton: localize('accountActions.no', 'No'),
|
secondaryButton: localize('accountActions.no', 'No'),
|
||||||
@@ -101,19 +90,13 @@ export class RemoveAccountAction extends Action {
|
|||||||
if (!result) {
|
if (!result) {
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
} else {
|
} else {
|
||||||
return new Promise((resolve, reject) => {
|
return Promise.resolve(this._accountManagementService.removeAccount(this._account.key)).catch(err => {
|
||||||
self._accountManagementService.removeAccount(self._account.key)
|
|
||||||
.then(
|
|
||||||
(result) => { resolve(result); },
|
|
||||||
(err) => {
|
|
||||||
// Must handle here as this is an independent action
|
// Must handle here as this is an independent action
|
||||||
self._notificationService.notify({
|
this._notificationService.notify({
|
||||||
severity: Severity.Error,
|
severity: Severity.Error,
|
||||||
message: localize('removeAccountFailed', 'Failed to remove account')
|
message: localize('removeAccountFailed', 'Failed to remove account')
|
||||||
});
|
});
|
||||||
resolve(false);
|
return false;
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -154,23 +137,17 @@ export class RefreshAccountAction extends Action {
|
|||||||
super(RefreshAccountAction.ID, RefreshAccountAction.LABEL, 'refresh-account-action icon refresh');
|
super(RefreshAccountAction.ID, RefreshAccountAction.LABEL, 'refresh-account-action icon refresh');
|
||||||
}
|
}
|
||||||
public run(): Promise<boolean> {
|
public run(): Promise<boolean> {
|
||||||
let self = this;
|
if (this.account) {
|
||||||
return new Promise((resolve, reject) => {
|
return Promise.resolve(this._accountManagementService.refreshAccount(this.account)
|
||||||
if (self.account) {
|
.then(() => true,
|
||||||
self._accountManagementService.refreshAccount(self.account)
|
|
||||||
.then(
|
|
||||||
() => {
|
|
||||||
resolve(true);
|
|
||||||
},
|
|
||||||
err => {
|
err => {
|
||||||
error(`Error while refreshing account: ${err}`);
|
error(`Error while refreshing account: ${err}`);
|
||||||
reject(err);
|
return Promise.reject(err);
|
||||||
}
|
}
|
||||||
);
|
));
|
||||||
} else {
|
} else {
|
||||||
let errorMessage = localize('NoAccountToRefresh', 'There is no account to refresh');
|
const errorMessage = localize('NoAccountToRefresh', 'There is no account to refresh');
|
||||||
reject(errorMessage);
|
return Promise.reject(errorMessage);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,6 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Event } from 'vs/base/common/event';
|
import { Event } from 'vs/base/common/event';
|
||||||
|
|
||||||
@@ -3,12 +3,11 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
|
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View model for account picker
|
* View model for account picker
|
||||||
@@ -24,13 +23,11 @@ export class AccountPickerViewModel {
|
|||||||
private _providerId: string,
|
private _providerId: string,
|
||||||
@IAccountManagementService private _accountManagementService: IAccountManagementService
|
@IAccountManagementService private _accountManagementService: IAccountManagementService
|
||||||
) {
|
) {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
// Create our event emitters
|
// Create our event emitters
|
||||||
this._updateAccountListEmitter = new Emitter<UpdateAccountListEventParams>();
|
this._updateAccountListEmitter = new Emitter<UpdateAccountListEventParams>();
|
||||||
|
|
||||||
// Register handlers for any changes to the accounts
|
// Register handlers for any changes to the accounts
|
||||||
this._accountManagementService.updateAccountListEvent(arg => self._updateAccountListEmitter.fire(arg));
|
this._accountManagementService.updateAccountListEvent(arg => this._updateAccountListEmitter.fire(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||||
@@ -41,7 +38,7 @@ export class AccountPickerViewModel {
|
|||||||
public initialize(): Thenable<azdata.Account[]> {
|
public initialize(): Thenable<azdata.Account[]> {
|
||||||
// Load a baseline of the accounts for the provider
|
// Load a baseline of the accounts for the provider
|
||||||
return this._accountManagementService.getAccountsForProvider(this._providerId)
|
return this._accountManagementService.getAccountsForProvider(this._providerId)
|
||||||
.then(null, () => {
|
.then(undefined, () => {
|
||||||
// In the event we failed to lookup accounts for the provider, just send
|
// In the event we failed to lookup accounts for the provider, just send
|
||||||
// back an empty collection
|
// back an empty collection
|
||||||
return [];
|
return [];
|
||||||
@@ -3,11 +3,10 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { AccountAdditionResult } from 'sql/platform/accountManagement/common/eventTypes';
|
import { AccountAdditionResult } from 'sql/platform/accounts/common/eventTypes';
|
||||||
import { IAccountStore } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountStore } from 'sql/platform/accounts/common/interfaces';
|
||||||
|
import { deepClone } from 'vs/base/common/objects';
|
||||||
|
|
||||||
export default class AccountStore implements IAccountStore {
|
export default class AccountStore implements IAccountStore {
|
||||||
// CONSTANTS ///////////////////////////////////////////////////////////
|
// CONSTANTS ///////////////////////////////////////////////////////////
|
||||||
@@ -20,57 +19,47 @@ export default class AccountStore implements IAccountStore {
|
|||||||
|
|
||||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||||
public addOrUpdate(newAccount: azdata.Account): Thenable<AccountAdditionResult> {
|
public addOrUpdate(newAccount: azdata.Account): Thenable<AccountAdditionResult> {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
return this.doOperation(() => {
|
return this.doOperation(() => {
|
||||||
return self.readFromMemento()
|
return this.readFromMemento()
|
||||||
.then(accounts => {
|
.then(accounts => {
|
||||||
// Determine if account exists and proceed accordingly
|
// Determine if account exists and proceed accordingly
|
||||||
let match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, newAccount.key));
|
const match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, newAccount.key));
|
||||||
return match < 0
|
return match < 0
|
||||||
? self.addToAccountList(accounts, newAccount)
|
? this.addToAccountList(accounts, newAccount)
|
||||||
: self.updateAccountList(accounts, newAccount.key, (matchAccount) => { AccountStore.mergeAccounts(newAccount, matchAccount); });
|
: this.updateAccountList(accounts, newAccount.key, matchAccount => AccountStore.mergeAccounts(newAccount, matchAccount));
|
||||||
})
|
})
|
||||||
.then(result => self.writeToMemento(result.updatedAccounts).then(() => result))
|
.then(result => this.writeToMemento(result.updatedAccounts).then(() => result))
|
||||||
.then(result => <AccountAdditionResult>result);
|
.then(result => <AccountAdditionResult>result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAccountsByProvider(providerId: string): Thenable<azdata.Account[]> {
|
public getAccountsByProvider(providerId: string): Thenable<azdata.Account[]> {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
return this.doOperation(() => {
|
return this.doOperation(() => {
|
||||||
return self.readFromMemento()
|
return this.readFromMemento()
|
||||||
.then(accounts => accounts.filter(account => account.key.providerId === providerId));
|
.then(accounts => accounts.filter(account => account.key.providerId === providerId));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAllAccounts(): Thenable<azdata.Account[]> {
|
public getAllAccounts(): Thenable<azdata.Account[]> {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
return this.doOperation(() => {
|
return this.doOperation(() => {
|
||||||
return self.readFromMemento();
|
return this.readFromMemento();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public remove(key: azdata.AccountKey): Thenable<boolean> {
|
public remove(key: azdata.AccountKey): Thenable<boolean> {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
return this.doOperation(() => {
|
return this.doOperation(() => {
|
||||||
return self.readFromMemento()
|
return this.readFromMemento()
|
||||||
.then(accounts => self.removeFromAccountList(accounts, key))
|
.then(accounts => this.removeFromAccountList(accounts, key))
|
||||||
.then(result => self.writeToMemento(result.updatedAccounts).then(() => result))
|
.then(result => this.writeToMemento(result.updatedAccounts).then(() => result))
|
||||||
.then(result => result.accountRemoved);
|
.then(result => result.accountRemoved);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public update(key: azdata.AccountKey, updateOperation: (account: azdata.Account) => void): Thenable<boolean> {
|
public update(key: azdata.AccountKey, updateOperation: (account: azdata.Account) => void): Thenable<boolean> {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
return this.doOperation(() => {
|
return this.doOperation(() => {
|
||||||
return self.readFromMemento()
|
return this.readFromMemento()
|
||||||
.then(accounts => self.updateAccountList(accounts, key, updateOperation))
|
.then(accounts => this.updateAccountList(accounts, key, updateOperation))
|
||||||
.then(result => self.writeToMemento(result.updatedAccounts).then(() => result))
|
.then(result => this.writeToMemento(result.updatedAccounts).then(() => result))
|
||||||
.then(result => result.accountModified);
|
.then(result => result.accountModified);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -111,7 +100,7 @@ export default class AccountStore implements IAccountStore {
|
|||||||
|
|
||||||
private addToAccountList(accounts: azdata.Account[], accountToAdd: azdata.Account): AccountListOperationResult {
|
private addToAccountList(accounts: azdata.Account[], accountToAdd: azdata.Account): AccountListOperationResult {
|
||||||
// Check if the entry already exists
|
// Check if the entry already exists
|
||||||
let match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, accountToAdd.key));
|
const match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, accountToAdd.key));
|
||||||
if (match >= 0) {
|
if (match >= 0) {
|
||||||
// Account already exists, we won't do anything
|
// Account already exists, we won't do anything
|
||||||
return {
|
return {
|
||||||
@@ -136,7 +125,7 @@ export default class AccountStore implements IAccountStore {
|
|||||||
|
|
||||||
private removeFromAccountList(accounts: azdata.Account[], accountToRemove: azdata.AccountKey): AccountListOperationResult {
|
private removeFromAccountList(accounts: azdata.Account[], accountToRemove: azdata.AccountKey): AccountListOperationResult {
|
||||||
// Check if the entry exists
|
// Check if the entry exists
|
||||||
let match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, accountToRemove));
|
const match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, accountToRemove));
|
||||||
if (match >= 0) {
|
if (match >= 0) {
|
||||||
// Account exists, remove it from the account list
|
// Account exists, remove it from the account list
|
||||||
accounts.splice(match, 1);
|
accounts.splice(match, 1);
|
||||||
@@ -153,7 +142,7 @@ export default class AccountStore implements IAccountStore {
|
|||||||
|
|
||||||
private updateAccountList(accounts: azdata.Account[], accountToUpdate: azdata.AccountKey, updateOperation: (account: azdata.Account) => void): AccountListOperationResult {
|
private updateAccountList(accounts: azdata.Account[], accountToUpdate: azdata.AccountKey, updateOperation: (account: azdata.Account) => void): AccountListOperationResult {
|
||||||
// Check if the entry exists
|
// Check if the entry exists
|
||||||
let match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, accountToUpdate));
|
const match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, accountToUpdate));
|
||||||
if (match < 0) {
|
if (match < 0) {
|
||||||
// Account doesn't exist, we won't do anything
|
// Account doesn't exist, we won't do anything
|
||||||
return {
|
return {
|
||||||
@@ -186,14 +175,14 @@ export default class AccountStore implements IAccountStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make a deep copy of the account list to ensure that the memento list isn't obliterated
|
// Make a deep copy of the account list to ensure that the memento list isn't obliterated
|
||||||
accounts = JSON.parse(JSON.stringify(accounts));
|
accounts = deepClone(accounts);
|
||||||
|
|
||||||
return Promise.resolve(accounts);
|
return Promise.resolve(accounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
private writeToMemento(accounts: azdata.Account[]): Thenable<void> {
|
private writeToMemento(accounts: azdata.Account[]): Thenable<void> {
|
||||||
// Store a shallow copy of the account list to disconnect the memento list from the active list
|
// Store a shallow copy of the account list to disconnect the memento list from the active list
|
||||||
this._memento[AccountStore.MEMENTO_KEY] = JSON.parse(JSON.stringify(accounts));
|
this._memento[AccountStore.MEMENTO_KEY] = deepClone(accounts);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,12 +3,10 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View model for account dialog
|
* View model for account dialog
|
||||||
@@ -24,18 +22,16 @@ export class AccountViewModel {
|
|||||||
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; }
|
||||||
|
|
||||||
constructor( @IAccountManagementService private _accountManagementService: IAccountManagementService) {
|
constructor(@IAccountManagementService private _accountManagementService: IAccountManagementService) {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
// Create our event emitters
|
// Create our event emitters
|
||||||
this._addProviderEmitter = new Emitter<AccountProviderAddedEventParams>();
|
this._addProviderEmitter = new Emitter<AccountProviderAddedEventParams>();
|
||||||
this._removeProviderEmitter = new Emitter<azdata.AccountProviderMetadata>();
|
this._removeProviderEmitter = new Emitter<azdata.AccountProviderMetadata>();
|
||||||
this._updateAccountListEmitter = new Emitter<UpdateAccountListEventParams>();
|
this._updateAccountListEmitter = new Emitter<UpdateAccountListEventParams>();
|
||||||
|
|
||||||
// Register handlers for any changes to the providers or accounts
|
// Register handlers for any changes to the providers or accounts
|
||||||
this._accountManagementService.addAccountProviderEvent(arg => self._addProviderEmitter.fire(arg));
|
this._accountManagementService.addAccountProviderEvent(arg => this._addProviderEmitter.fire(arg));
|
||||||
this._accountManagementService.removeAccountProviderEvent(arg => self._removeProviderEmitter.fire(arg));
|
this._accountManagementService.removeAccountProviderEvent(arg => this._removeProviderEmitter.fire(arg));
|
||||||
this._accountManagementService.updateAccountListEvent(arg => self._updateAccountListEmitter.fire(arg));
|
this._accountManagementService.updateAccountListEvent(arg => this._updateAccountListEmitter.fire(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||||
@@ -45,8 +41,6 @@ export class AccountViewModel {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public initialize(): Thenable<AccountProviderAddedEventParams[]> {
|
public initialize(): Thenable<AccountProviderAddedEventParams[]> {
|
||||||
let self = this;
|
|
||||||
|
|
||||||
// Load a baseline of the account provider metadata and accounts
|
// Load a baseline of the account provider metadata and accounts
|
||||||
// 1) Get all the providers from the account management service
|
// 1) Get all the providers from the account management service
|
||||||
// 2) For each provider, get the accounts
|
// 2) For each provider, get the accounts
|
||||||
@@ -54,8 +48,8 @@ export class AccountViewModel {
|
|||||||
return this._accountManagementService.getAccountProviderMetadata()
|
return this._accountManagementService.getAccountProviderMetadata()
|
||||||
.then(
|
.then(
|
||||||
(providers: azdata.AccountProviderMetadata[]) => {
|
(providers: azdata.AccountProviderMetadata[]) => {
|
||||||
let promises = providers.map(provider => {
|
const promises = providers.map(provider => {
|
||||||
return self._accountManagementService.getAccountsForProvider(provider.id)
|
return this._accountManagementService.getAccountsForProvider(provider.id)
|
||||||
.then(
|
.then(
|
||||||
accounts => <AccountProviderAddedEventParams>{
|
accounts => <AccountProviderAddedEventParams>{
|
||||||
addedProvider: provider,
|
addedProvider: provider,
|
||||||
@@ -64,11 +58,9 @@ export class AccountViewModel {
|
|||||||
() => { /* Swallow failures at getting accounts, we'll just hide that provider */ });
|
() => { /* Swallow failures at getting accounts, we'll just hide that provider */ });
|
||||||
});
|
});
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
},
|
}, () => {
|
||||||
() => {
|
|
||||||
/* Swallow failures and just pretend we don't have any providers */
|
/* Swallow failures and just pretend we don't have any providers */
|
||||||
return [];
|
return [];
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,6 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3,11 +3,9 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { Event } from 'vs/base/common/event';
|
import { Event } from 'vs/base/common/event';
|
||||||
import { AccountAdditionResult, AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { AccountAdditionResult, AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
|
||||||
export const SERVICE_ID = 'accountManagementService';
|
export const SERVICE_ID = 'accountManagementService';
|
||||||
@@ -33,7 +33,7 @@ import { Deferred } from 'sql/base/common/promise';
|
|||||||
import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||||
import { values, entries } from 'sql/base/common/objects';
|
import { values, entries } from 'sql/base/common/objects';
|
||||||
import { ConnectionProviderProperties, IConnectionProviderRegistry, Extensions as ConnectionProviderExtensions } from 'sql/workbench/parts/connection/common/connectionProviderExtension';
|
import { ConnectionProviderProperties, IConnectionProviderRegistry, Extensions as ConnectionProviderExtensions } from 'sql/workbench/parts/connection/common/connectionProviderExtension';
|
||||||
import { IAccountManagementService, AzureResource } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService, AzureResource } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { IServerGroupController, IServerGroupDialogCallbacks } from 'sql/platform/serverGroup/common/serverGroupController';
|
import { IServerGroupController, IServerGroupDialogCallbacks } from 'sql/platform/serverGroup/common/serverGroupController';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import {
|
import {
|
||||||
ExtHostAccountManagementShape,
|
ExtHostAccountManagementShape,
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
} from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||||
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||||
import { UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
|
|
||||||
@extHostNamedCustomer(SqlMainContext.MainThreadAccountManagement)
|
@extHostNamedCustomer(SqlMainContext.MainThreadAccountManagement)
|
||||||
export class MainThreadAccountManagement implements MainThreadAccountManagementShape {
|
export class MainThreadAccountManagement implements MainThreadAccountManagementShape {
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
|||||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||||
import { Memento } from 'vs/workbench/common/memento';
|
import { Memento } from 'vs/workbench/common/memento';
|
||||||
|
|
||||||
import AccountStore from 'sql/platform/accountManagement/common/accountStore';
|
import AccountStore from 'sql/platform/accounts/common/accountStore';
|
||||||
import { AccountDialogController } from 'sql/parts/accountManagement/accountDialog/accountDialogController';
|
import { AccountDialogController } from 'sql/platform/accounts/browser/accountDialogController';
|
||||||
import { AutoOAuthDialogController } from 'sql/parts/accountManagement/autoOAuthDialog/autoOAuthDialogController';
|
import { AutoOAuthDialogController } from 'sql/platform/accounts/browser/autoOAuthDialogController';
|
||||||
import { AccountListStatusbarItem } from 'sql/parts/accountManagement/accountListStatusbar/accountListStatusbarItem';
|
import { AccountListStatusbarItem } from 'sql/platform/accounts/browser/accountListStatusbarItem';
|
||||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { Deferred } from 'sql/base/common/promise';
|
import { Deferred } from 'sql/base/common/promise';
|
||||||
|
|
||||||
export class AccountManagementService implements IAccountManagementService {
|
export class AccountManagementService implements IAccountManagementService {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { IConnectionManagementService } from 'sql/platform/connection/common/con
|
|||||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||||
import * as styler from 'sql/platform/theme/common/styler';
|
import * as styler from 'sql/platform/theme/common/styler';
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { IResourceProviderService, IHandleFirewallRuleResult } from 'sql/workben
|
|||||||
import * as Constants from 'sql/common/constants';
|
import * as Constants from 'sql/common/constants';
|
||||||
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
import * as TelemetryKeys from 'sql/common/telemetryKeys';
|
||||||
import * as TelemetryUtils from 'sql/common/telemetryUtilities';
|
import * as TelemetryUtils from 'sql/common/telemetryUtilities';
|
||||||
import { FirewallRuleDialogController } from 'sql/parts/accountManagement/firewallRuleDialog/firewallRuleDialogController';
|
import { FirewallRuleDialogController } from 'sql/platform/accounts/browser/firewallRuleDialogController';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
import { AddAccountAction, RemoveAccountAction } from 'sql/parts/accountManagement/common/accountActions';
|
import { AddAccountAction, RemoveAccountAction } from 'sql/platform/accounts/common/accountActions';
|
||||||
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
||||||
// import { MessageServiceStub } from 'sqltest/stubs/messageServiceStub';
|
// import { MessageServiceStub } from 'sqltest/stubs/messageServiceStub';
|
||||||
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
|
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { AccountDialog } from 'sql/parts/accountManagement/accountDialog/accountDialog';
|
import { AccountDialog } from 'sql/platform/accounts/browser/accountDialog';
|
||||||
import { AccountDialogController } from 'sql/parts/accountManagement/accountDialog/accountDialogController';
|
import { AccountDialogController } from 'sql/platform/accounts/browser/accountDialogController';
|
||||||
import { AccountViewModel } from 'sql/parts/accountManagement/accountDialog/accountViewModel';
|
import { AccountViewModel } from 'sql/platform/accounts/common/accountViewModel';
|
||||||
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
||||||
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
|
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
|
||||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||||
import { AccountListRenderer } from 'sql/parts/accountManagement/common/accountListRenderer';
|
import { AccountListRenderer } from 'sql/platform/accounts/browser/accountListRenderer';
|
||||||
import { ContextKeyServiceStub } from 'sqltest/stubs/contextKeyServiceStub';
|
import { ContextKeyServiceStub } from 'sqltest/stubs/contextKeyServiceStub';
|
||||||
|
|
||||||
// TESTS ///////////////////////////////////////////////////////////////////
|
// TESTS ///////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import * as assert from 'assert';
|
|||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { AccountPicker } from 'sql/platform/accountManagement/browser/accountPicker';
|
import { AccountPicker } from 'sql/platform/accounts/browser/accountPicker';
|
||||||
import { AccountPickerService } from 'sql/platform/accountManagement/browser/accountPickerService';
|
import { AccountPickerService } from 'sql/platform/accounts/browser/accountPickerService';
|
||||||
import { AccountPickerViewModel } from 'sql/platform/accountManagement/common/accountPickerViewModel';
|
import { AccountPickerViewModel } from 'sql/platform/accounts/common/accountPickerViewModel';
|
||||||
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
||||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import * as assert from 'assert';
|
|||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { AccountPickerViewModel } from 'sql/platform/accountManagement/common/accountPickerViewModel';
|
import { AccountPickerViewModel } from 'sql/platform/accounts/common/accountPickerViewModel';
|
||||||
import { UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
||||||
|
|
||||||
// SUITE STATE /////////////////////////////////////////////////////////////
|
// SUITE STATE /////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import * as azdata from 'azdata';
|
|||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { AccountViewModel } from 'sql/parts/accountManagement/accountDialog/accountViewModel';
|
import { AccountViewModel } from 'sql/platform/accounts/common/accountViewModel';
|
||||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
||||||
|
|
||||||
// SUITE STATE /////////////////////////////////////////////////////////////
|
// SUITE STATE /////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import * as TypeMoq from 'typemoq';
|
|||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||||
|
|
||||||
import { AutoOAuthDialog } from 'sql/parts/accountManagement/autoOAuthDialog/autoOAuthDialog';
|
import { AutoOAuthDialog } from 'sql/platform/accounts/browser/autoOAuthDialog';
|
||||||
import { AutoOAuthDialogController } from 'sql/parts/accountManagement/autoOAuthDialog/autoOAuthDialogController';
|
import { AutoOAuthDialogController } from 'sql/platform/accounts/browser/autoOAuthDialogController';
|
||||||
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
||||||
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
|
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
|
||||||
import { ContextKeyServiceStub } from 'sqltest/stubs/contextKeyServiceStub';
|
import { ContextKeyServiceStub } from 'sqltest/stubs/contextKeyServiceStub';
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import * as azdata from 'azdata';
|
|||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } 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/parts/accountManagement/firewallRuleDialog/firewallRuleDialog';
|
import { FirewallRuleDialog } from 'sql/platform/accounts/browser/firewallRuleDialog';
|
||||||
import { FirewallRuleViewModel } from 'sql/parts/accountManagement/firewallRuleDialog/firewallRuleViewModel';
|
import { FirewallRuleViewModel } from 'sql/platform/accounts/common/firewallRuleViewModel';
|
||||||
import { FirewallRuleDialogController } from 'sql/parts/accountManagement/firewallRuleDialog/firewallRuleDialogController';
|
import { FirewallRuleDialogController } from 'sql/platform/accounts/browser/firewallRuleDialogController';
|
||||||
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
import { AccountManagementTestService } from 'sqltest/stubs/accountManagementStubs';
|
||||||
import { ResourceProviderStub } from 'sqltest/stubs/resourceProviderServiceStub';
|
import { ResourceProviderStub } from 'sqltest/stubs/resourceProviderServiceStub';
|
||||||
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
|
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import { FirewallRuleViewModel } from 'sql/parts/accountManagement/firewallRuleDialog/firewallRuleViewModel';
|
import { FirewallRuleViewModel } from 'sql/platform/accounts/common/firewallRuleViewModel';
|
||||||
|
|
||||||
suite('Firewall rule view model tests', () => {
|
suite('Firewall rule view model tests', () => {
|
||||||
let viewModel: FirewallRuleViewModel;
|
let viewModel: FirewallRuleViewModel;
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
import AccountStore from 'sql/platform/accountManagement/common/accountStore';
|
import AccountStore from 'sql/platform/accounts/common/accountStore';
|
||||||
import { AccountDialogController } from 'sql/parts/accountManagement/accountDialog/accountDialogController';
|
import { AccountDialogController } from 'sql/platform/accounts/browser/accountDialogController';
|
||||||
import { AccountManagementService } from 'sql/workbench/services/accountManagement/browser/accountManagementService';
|
import { AccountManagementService } from 'sql/workbench/services/accountManagement/browser/accountManagementService';
|
||||||
import { AccountAdditionResult, AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { AccountAdditionResult, AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
import { IAccountStore } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountStore } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { AccountProviderStub } from 'sqltest/stubs/accountManagementStubs';
|
import { AccountProviderStub } from 'sqltest/stubs/accountManagementStubs';
|
||||||
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
||||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import AccountStore from 'sql/platform/accountManagement/common/accountStore';
|
import AccountStore from 'sql/platform/accounts/common/accountStore';
|
||||||
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
|
||||||
|
|
||||||
suite('Account Store Tests', () => {
|
suite('Account Store Tests', () => {
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { Event } from 'vs/base/common/event';
|
import { Event } from 'vs/base/common/event';
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accountManagement/common/eventTypes';
|
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||||
|
|
||||||
export class AccountManagementTestService implements IAccountManagementService {
|
export class AccountManagementTestService implements IAccountManagementService {
|
||||||
_serviceBrand: any;
|
_serviceBrand: any;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/
|
|||||||
import { IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier';
|
import { IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier';
|
||||||
import { SqlMainContext } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
import { SqlMainContext } from 'sql/workbench/api/node/sqlExtHost.protocol';
|
||||||
import { MainThreadAccountManagement } from 'sql/workbench/api/node/mainThreadAccountManagement';
|
import { MainThreadAccountManagement } from 'sql/workbench/api/node/mainThreadAccountManagement';
|
||||||
import { IAccountManagementService, AzureResource } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService, AzureResource } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
|
||||||
const IRPCProtocol = createDecorator<IRPCProtocol>('rpcProtocol');
|
const IRPCProtocol = createDecorator<IRPCProtocol>('rpcProtocol');
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ import { IFileBrowserDialogController } from 'sql/workbench/services/fileBrowser
|
|||||||
import { FileBrowserDialogController } from 'sql/workbench/services/fileBrowser/browser/fileBrowserDialogController';
|
import { FileBrowserDialogController } from 'sql/workbench/services/fileBrowser/browser/fileBrowserDialogController';
|
||||||
import { IInsightsDialogService } from 'sql/workbench/services/insights/common/insightsDialogService';
|
import { IInsightsDialogService } from 'sql/workbench/services/insights/common/insightsDialogService';
|
||||||
import { InsightsDialogService } from 'sql/workbench/services/insights/browser/insightsDialogService';
|
import { InsightsDialogService } from 'sql/workbench/services/insights/browser/insightsDialogService';
|
||||||
import { IAccountManagementService } from 'sql/platform/accountManagement/common/interfaces';
|
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||||
import { AccountManagementService } from 'sql/workbench/services/accountManagement/browser/accountManagementService';
|
import { AccountManagementService } from 'sql/workbench/services/accountManagement/browser/accountManagementService';
|
||||||
import { IProfilerService } from 'sql/workbench/services/profiler/common/interfaces';
|
import { IProfilerService } from 'sql/workbench/services/profiler/common/interfaces';
|
||||||
import { ProfilerService } from 'sql/workbench/services/profiler/common/profilerService';
|
import { ProfilerService } from 'sql/workbench/services/profiler/common/profilerService';
|
||||||
@@ -211,8 +211,8 @@ import { ISqlOAuthService } from 'sql/platform/oAuth/common/sqlOAuthService';
|
|||||||
import { SqlOAuthService } from 'sql/platform/oAuth/electron-browser/sqlOAuthServiceImpl';
|
import { SqlOAuthService } from 'sql/platform/oAuth/electron-browser/sqlOAuthServiceImpl';
|
||||||
import { IClipboardService as sqlIClipboardService } from 'sql/platform/clipboard/common/clipboardService';
|
import { IClipboardService as sqlIClipboardService } from 'sql/platform/clipboard/common/clipboardService';
|
||||||
import { ClipboardService as sqlClipboardService } from 'sql/platform/clipboard/electron-browser/clipboardService';
|
import { ClipboardService as sqlClipboardService } from 'sql/platform/clipboard/electron-browser/clipboardService';
|
||||||
import { AccountPickerService } from 'sql/platform/accountManagement/browser/accountPickerService';
|
import { AccountPickerService } from 'sql/platform/accounts/browser/accountPickerService';
|
||||||
import { IAccountPickerService } from 'sql/platform/accountManagement/common/accountPicker';
|
import { IAccountPickerService } from 'sql/platform/accounts/common/accountPicker';
|
||||||
import { IResourceProviderService } from 'sql/workbench/services/resourceProvider/common/resourceProviderService';
|
import { IResourceProviderService } from 'sql/workbench/services/resourceProvider/common/resourceProviderService';
|
||||||
import { ResourceProviderService } from 'sql/workbench/services/resourceProvider/browser/resourceProviderService';
|
import { ResourceProviderService } from 'sql/workbench/services/resourceProvider/browser/resourceProviderService';
|
||||||
import { IDashboardViewService } from 'sql/platform/dashboard/common/dashboardViewService';
|
import { IDashboardViewService } from 'sql/platform/dashboard/common/dashboardViewService';
|
||||||
@@ -450,7 +450,7 @@ import 'sql/parts/query/editor/resultsGridContribution';
|
|||||||
import 'sql/parts/profiler/contrib/profiler.contribution';
|
import 'sql/parts/profiler/contrib/profiler.contribution';
|
||||||
import 'sql/parts/profiler/contrib/profilerActions.contribution';
|
import 'sql/parts/profiler/contrib/profilerActions.contribution';
|
||||||
import 'sql/parts/objectExplorer/serverGroupDialog/serverGroup.contribution';
|
import 'sql/parts/objectExplorer/serverGroupDialog/serverGroup.contribution';
|
||||||
import 'sql/parts/accountManagement/common/accountManagement.contribution';
|
import 'sql/platform/accounts/browser/accountManagement.contribution';
|
||||||
/* Insights */
|
/* Insights */
|
||||||
import 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
import 'sql/parts/dashboard/widgets/insights/views/charts/types/barChart.contribution';
|
||||||
import 'sql/parts/dashboard/widgets/insights/views/charts/types/doughnutChart.contribution';
|
import 'sql/parts/dashboard/widgets/insights/views/charts/types/doughnutChart.contribution';
|
||||||
|
|||||||