mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-26 09:35:38 -05:00
Code Layering Accounts (#4882)
* code layering for accounts * formatting * formatting * formatting
This commit is contained in:
153
src/sql/platform/accounts/common/accountActions.ts
Normal file
153
src/sql/platform/accounts/common/accountActions.ts
Normal file
@@ -0,0 +1,153 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
|
||||
import { error } from 'sql/base/common/log';
|
||||
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||
import { IDialogService, IConfirmation } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
|
||||
/**
|
||||
* Actions to add a new account
|
||||
*/
|
||||
export class AddAccountAction extends Action {
|
||||
// CONSTANTS ///////////////////////////////////////////////////////////
|
||||
public static ID = 'account.addLinkedAccount';
|
||||
public static LABEL = localize('addAccount', 'Add an account');
|
||||
|
||||
// EVENTING ////////////////////////////////////////////////////////////
|
||||
private _addAccountCompleteEmitter: Emitter<void>;
|
||||
public get addAccountCompleteEvent(): Event<void> { return this._addAccountCompleteEmitter.event; }
|
||||
|
||||
private _addAccountErrorEmitter: Emitter<string>;
|
||||
public get addAccountErrorEvent(): Event<string> { return this._addAccountErrorEmitter.event; }
|
||||
|
||||
private _addAccountStartEmitter: Emitter<void>;
|
||||
public get addAccountStartEvent(): Event<void> { return this._addAccountStartEmitter.event; }
|
||||
|
||||
constructor(
|
||||
private _providerId: string,
|
||||
@IAccountManagementService private _accountManagementService: IAccountManagementService
|
||||
) {
|
||||
super(AddAccountAction.ID, AddAccountAction.LABEL);
|
||||
this.class = 'add-linked-account-action';
|
||||
|
||||
this._addAccountCompleteEmitter = new Emitter<void>();
|
||||
this._addAccountErrorEmitter = new Emitter<string>();
|
||||
this._addAccountStartEmitter = new Emitter<void>();
|
||||
}
|
||||
|
||||
public run(): Promise<boolean> {
|
||||
|
||||
// Fire the event that we've started adding accounts
|
||||
this._addAccountStartEmitter.fire();
|
||||
|
||||
return Promise.resolve(this._accountManagementService.addAccount(this._providerId)
|
||||
.then(() => {
|
||||
this._addAccountCompleteEmitter.fire();
|
||||
return true;
|
||||
}, err => {
|
||||
error(`Error while adding account: ${err}`);
|
||||
this._addAccountErrorEmitter.fire(err);
|
||||
this._addAccountCompleteEmitter.fire();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions to remove the account
|
||||
*/
|
||||
export class RemoveAccountAction extends Action {
|
||||
public static ID = 'account.removeAccount';
|
||||
public static LABEL = localize('removeAccount', 'Remove account');
|
||||
|
||||
constructor(
|
||||
private _account: azdata.Account,
|
||||
@IDialogService private _dialogService: IDialogService,
|
||||
@INotificationService private _notificationService: INotificationService,
|
||||
@IAccountManagementService private _accountManagementService: IAccountManagementService
|
||||
) {
|
||||
super(RemoveAccountAction.ID, RemoveAccountAction.LABEL, 'remove-account-action icon remove');
|
||||
}
|
||||
|
||||
public run(): Promise<boolean> {
|
||||
// Ask for Confirm
|
||||
const confirm: IConfirmation = {
|
||||
message: localize('confirmRemoveUserAccountMessage', "Are you sure you want to remove '{0}'?", this._account.displayInfo.displayName),
|
||||
primaryButton: localize('accountActions.yes', 'Yes'),
|
||||
secondaryButton: localize('accountActions.no', 'No'),
|
||||
type: 'question'
|
||||
};
|
||||
|
||||
return this._dialogService.confirm(confirm).then(result => {
|
||||
if (!result) {
|
||||
return Promise.resolve(false);
|
||||
} else {
|
||||
return Promise.resolve(this._accountManagementService.removeAccount(this._account.key)).catch(err => {
|
||||
// Must handle here as this is an independent action
|
||||
this._notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: localize('removeAccountFailed', 'Failed to remove account')
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions to apply filter to the account
|
||||
*/
|
||||
export class ApplyFilterAction extends Action {
|
||||
public static ID = 'account.applyFilters';
|
||||
public static LABEL = localize('applyFilters', 'Apply Filters');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string
|
||||
) {
|
||||
super(id, label, 'apply-filters-action icon filter');
|
||||
}
|
||||
|
||||
public run(): Promise<boolean> {
|
||||
// Todo: apply filter to the account
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions to refresh the account
|
||||
*/
|
||||
export class RefreshAccountAction extends Action {
|
||||
public static ID = 'account.refresh';
|
||||
public static LABEL = localize('refreshAccount', 'Reenter your credentials');
|
||||
public account: azdata.Account;
|
||||
|
||||
constructor(
|
||||
@IAccountManagementService private _accountManagementService: IAccountManagementService
|
||||
) {
|
||||
super(RefreshAccountAction.ID, RefreshAccountAction.LABEL, 'refresh-account-action icon refresh');
|
||||
}
|
||||
public run(): Promise<boolean> {
|
||||
if (this.account) {
|
||||
return Promise.resolve(this._accountManagementService.refreshAccount(this.account)
|
||||
.then(() => true,
|
||||
err => {
|
||||
error(`Error while refreshing account: ${err}`);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
));
|
||||
} else {
|
||||
const errorMessage = localize('NoAccountToRefresh', 'There is no account to refresh');
|
||||
return Promise.reject(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/sql/platform/accounts/common/accountPicker.ts
Normal file
20
src/sql/platform/accounts/common/accountPicker.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
export const IAccountPickerService = createDecorator<IAccountPickerService>('AccountPickerService');
|
||||
export interface IAccountPickerService {
|
||||
_serviceBrand: any;
|
||||
renderAccountPicker(container: HTMLElement): void;
|
||||
addAccountCompleteEvent: Event<void>;
|
||||
addAccountErrorEvent: Event<string>;
|
||||
addAccountStartEvent: Event<void>;
|
||||
onAccountSelectionChangeEvent: Event<azdata.Account>;
|
||||
selectedAccount: azdata.Account;
|
||||
}
|
||||
47
src/sql/platform/accounts/common/accountPickerViewModel.ts
Normal file
47
src/sql/platform/accounts/common/accountPickerViewModel.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||
import { UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||
|
||||
/**
|
||||
* View model for account picker
|
||||
*/
|
||||
export class AccountPickerViewModel {
|
||||
// EVENTING ////////////////////////////////////////////////////////////
|
||||
private _updateAccountListEmitter: Emitter<UpdateAccountListEventParams>;
|
||||
public get updateAccountListEvent(): Event<UpdateAccountListEventParams> { return this._updateAccountListEmitter.event; }
|
||||
|
||||
public selectedAccount: azdata.Account;
|
||||
|
||||
constructor(
|
||||
private _providerId: string,
|
||||
@IAccountManagementService private _accountManagementService: IAccountManagementService
|
||||
) {
|
||||
// Create our event emitters
|
||||
this._updateAccountListEmitter = new Emitter<UpdateAccountListEventParams>();
|
||||
|
||||
// Register handlers for any changes to the accounts
|
||||
this._accountManagementService.updateAccountListEvent(arg => this._updateAccountListEmitter.fire(arg));
|
||||
}
|
||||
|
||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||
/**
|
||||
* Loads an initial list of accounts from the account management service
|
||||
* @return {Thenable<Account[]>} Promise to return the list of accounts
|
||||
*/
|
||||
public initialize(): Thenable<azdata.Account[]> {
|
||||
// Load a baseline of the accounts for the provider
|
||||
return this._accountManagementService.getAccountsForProvider(this._providerId)
|
||||
.then(undefined, () => {
|
||||
// In the event we failed to lookup accounts for the provider, just send
|
||||
// back an empty collection
|
||||
return [];
|
||||
});
|
||||
}
|
||||
}
|
||||
193
src/sql/platform/accounts/common/accountStore.ts
Normal file
193
src/sql/platform/accounts/common/accountStore.ts
Normal file
@@ -0,0 +1,193 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { AccountAdditionResult } from 'sql/platform/accounts/common/eventTypes';
|
||||
import { IAccountStore } from 'sql/platform/accounts/common/interfaces';
|
||||
import { deepClone } from 'vs/base/common/objects';
|
||||
|
||||
export default class AccountStore implements IAccountStore {
|
||||
// CONSTANTS ///////////////////////////////////////////////////////////
|
||||
public static MEMENTO_KEY: string = 'Microsoft.SqlTools.Accounts';
|
||||
|
||||
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
||||
private _activeOperation: Thenable<any>;
|
||||
|
||||
constructor(private _memento: object) { }
|
||||
|
||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||
public addOrUpdate(newAccount: azdata.Account): Thenable<AccountAdditionResult> {
|
||||
return this.doOperation(() => {
|
||||
return this.readFromMemento()
|
||||
.then(accounts => {
|
||||
// Determine if account exists and proceed accordingly
|
||||
const match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, newAccount.key));
|
||||
return match < 0
|
||||
? this.addToAccountList(accounts, newAccount)
|
||||
: this.updateAccountList(accounts, newAccount.key, matchAccount => AccountStore.mergeAccounts(newAccount, matchAccount));
|
||||
})
|
||||
.then(result => this.writeToMemento(result.updatedAccounts).then(() => result))
|
||||
.then(result => <AccountAdditionResult>result);
|
||||
});
|
||||
}
|
||||
|
||||
public getAccountsByProvider(providerId: string): Thenable<azdata.Account[]> {
|
||||
return this.doOperation(() => {
|
||||
return this.readFromMemento()
|
||||
.then(accounts => accounts.filter(account => account.key.providerId === providerId));
|
||||
});
|
||||
}
|
||||
|
||||
public getAllAccounts(): Thenable<azdata.Account[]> {
|
||||
return this.doOperation(() => {
|
||||
return this.readFromMemento();
|
||||
});
|
||||
}
|
||||
|
||||
public remove(key: azdata.AccountKey): Thenable<boolean> {
|
||||
return this.doOperation(() => {
|
||||
return this.readFromMemento()
|
||||
.then(accounts => this.removeFromAccountList(accounts, key))
|
||||
.then(result => this.writeToMemento(result.updatedAccounts).then(() => result))
|
||||
.then(result => result.accountRemoved);
|
||||
});
|
||||
}
|
||||
|
||||
public update(key: azdata.AccountKey, updateOperation: (account: azdata.Account) => void): Thenable<boolean> {
|
||||
return this.doOperation(() => {
|
||||
return this.readFromMemento()
|
||||
.then(accounts => this.updateAccountList(accounts, key, updateOperation))
|
||||
.then(result => this.writeToMemento(result.updatedAccounts).then(() => result))
|
||||
.then(result => result.accountModified);
|
||||
});
|
||||
}
|
||||
|
||||
// PRIVATE METHODS /////////////////////////////////////////////////////
|
||||
private static findAccountByKey(key1: azdata.AccountKey, key2: azdata.AccountKey): boolean {
|
||||
// Provider ID and Account ID must match
|
||||
return key1.providerId === key2.providerId && key1.accountId === key2.accountId;
|
||||
}
|
||||
|
||||
private static mergeAccounts(source: azdata.Account, target: azdata.Account): void {
|
||||
// Take any display info changes
|
||||
target.displayInfo = source.displayInfo;
|
||||
|
||||
// Take all property changes
|
||||
target.properties = source.properties;
|
||||
|
||||
// Take any stale changes
|
||||
target.isStale = source.isStale;
|
||||
}
|
||||
|
||||
private doOperation<T>(op: () => Thenable<T>) {
|
||||
// Initialize the active operation to an empty promise if necessary
|
||||
let activeOperation = this._activeOperation || Promise.resolve<any>(null);
|
||||
|
||||
// Chain the operation to perform to the end of the existing promise
|
||||
activeOperation = activeOperation.then(op);
|
||||
|
||||
// Add a catch at the end to make sure we can continue after any errors
|
||||
activeOperation = activeOperation.then(null, (err) => {
|
||||
// TODO: Log the error
|
||||
});
|
||||
|
||||
// Point the current active operation to this one
|
||||
this._activeOperation = activeOperation;
|
||||
return <Promise<T>>this._activeOperation;
|
||||
}
|
||||
|
||||
private addToAccountList(accounts: azdata.Account[], accountToAdd: azdata.Account): AccountListOperationResult {
|
||||
// Check if the entry already exists
|
||||
const match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, accountToAdd.key));
|
||||
if (match >= 0) {
|
||||
// Account already exists, we won't do anything
|
||||
return {
|
||||
accountAdded: false,
|
||||
accountModified: false,
|
||||
accountRemoved: false,
|
||||
changedAccount: null,
|
||||
updatedAccounts: accounts
|
||||
};
|
||||
}
|
||||
|
||||
// Add the account to the store
|
||||
accounts.push(accountToAdd);
|
||||
return {
|
||||
accountAdded: true,
|
||||
accountModified: false,
|
||||
accountRemoved: false,
|
||||
changedAccount: accountToAdd,
|
||||
updatedAccounts: accounts
|
||||
};
|
||||
}
|
||||
|
||||
private removeFromAccountList(accounts: azdata.Account[], accountToRemove: azdata.AccountKey): AccountListOperationResult {
|
||||
// Check if the entry exists
|
||||
const match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, accountToRemove));
|
||||
if (match >= 0) {
|
||||
// Account exists, remove it from the account list
|
||||
accounts.splice(match, 1);
|
||||
}
|
||||
|
||||
return {
|
||||
accountAdded: false,
|
||||
accountModified: false,
|
||||
accountRemoved: match >= 0,
|
||||
changedAccount: null,
|
||||
updatedAccounts: accounts
|
||||
};
|
||||
}
|
||||
|
||||
private updateAccountList(accounts: azdata.Account[], accountToUpdate: azdata.AccountKey, updateOperation: (account: azdata.Account) => void): AccountListOperationResult {
|
||||
// Check if the entry exists
|
||||
const match = accounts.findIndex(account => AccountStore.findAccountByKey(account.key, accountToUpdate));
|
||||
if (match < 0) {
|
||||
// Account doesn't exist, we won't do anything
|
||||
return {
|
||||
accountAdded: false,
|
||||
accountModified: false,
|
||||
accountRemoved: false,
|
||||
changedAccount: null,
|
||||
updatedAccounts: accounts
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Account exists, apply the update operation to it
|
||||
updateOperation(accounts[match]);
|
||||
return {
|
||||
accountAdded: false,
|
||||
accountModified: true,
|
||||
accountRemoved: false,
|
||||
changedAccount: accounts[match],
|
||||
updatedAccounts: accounts
|
||||
};
|
||||
}
|
||||
|
||||
// MEMENTO IO METHODS //////////////////////////////////////////////////
|
||||
private readFromMemento(): Thenable<azdata.Account[]> {
|
||||
// Initialize the account list if it isn't already
|
||||
let accounts = this._memento[AccountStore.MEMENTO_KEY];
|
||||
if (!accounts) {
|
||||
accounts = [];
|
||||
}
|
||||
|
||||
// Make a deep copy of the account list to ensure that the memento list isn't obliterated
|
||||
accounts = deepClone(accounts);
|
||||
|
||||
return Promise.resolve(accounts);
|
||||
}
|
||||
|
||||
private writeToMemento(accounts: azdata.Account[]): Thenable<void> {
|
||||
// Store a shallow copy of the account list to disconnect the memento list from the active list
|
||||
this._memento[AccountStore.MEMENTO_KEY] = deepClone(accounts);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
interface AccountListOperationResult extends AccountAdditionResult {
|
||||
accountRemoved: boolean;
|
||||
updatedAccounts: azdata.Account[];
|
||||
}
|
||||
66
src/sql/platform/accounts/common/accountViewModel.ts
Normal file
66
src/sql/platform/accounts/common/accountViewModel.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||
|
||||
/**
|
||||
* View model for account dialog
|
||||
*/
|
||||
export class AccountViewModel {
|
||||
// EVENTING ///////////////////////////////////////////////////////
|
||||
private _addProviderEmitter: Emitter<AccountProviderAddedEventParams>;
|
||||
public get addProviderEvent(): Event<AccountProviderAddedEventParams> { return this._addProviderEmitter.event; }
|
||||
|
||||
private _removeProviderEmitter: Emitter<azdata.AccountProviderMetadata>;
|
||||
public get removeProviderEvent(): Event<azdata.AccountProviderMetadata> { return this._removeProviderEmitter.event; }
|
||||
|
||||
private _updateAccountListEmitter: Emitter<UpdateAccountListEventParams>;
|
||||
public get updateAccountListEvent(): Event<UpdateAccountListEventParams> { return this._updateAccountListEmitter.event; }
|
||||
|
||||
constructor(@IAccountManagementService private _accountManagementService: IAccountManagementService) {
|
||||
// Create our event emitters
|
||||
this._addProviderEmitter = new Emitter<AccountProviderAddedEventParams>();
|
||||
this._removeProviderEmitter = new Emitter<azdata.AccountProviderMetadata>();
|
||||
this._updateAccountListEmitter = new Emitter<UpdateAccountListEventParams>();
|
||||
|
||||
// Register handlers for any changes to the providers or accounts
|
||||
this._accountManagementService.addAccountProviderEvent(arg => this._addProviderEmitter.fire(arg));
|
||||
this._accountManagementService.removeAccountProviderEvent(arg => this._removeProviderEmitter.fire(arg));
|
||||
this._accountManagementService.updateAccountListEvent(arg => this._updateAccountListEmitter.fire(arg));
|
||||
}
|
||||
|
||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||
/**
|
||||
* Loads an initial list of account providers and accounts from the account management service
|
||||
* and fires an event after each provider/accounts has been loaded.
|
||||
*
|
||||
*/
|
||||
public initialize(): Thenable<AccountProviderAddedEventParams[]> {
|
||||
// Load a baseline of the account provider metadata and accounts
|
||||
// 1) Get all the providers from the account management service
|
||||
// 2) For each provider, get the accounts
|
||||
// 3) Build parameters to add a provider and return it
|
||||
return this._accountManagementService.getAccountProviderMetadata()
|
||||
.then(
|
||||
(providers: azdata.AccountProviderMetadata[]) => {
|
||||
const promises = providers.map(provider => {
|
||||
return this._accountManagementService.getAccountsForProvider(provider.id)
|
||||
.then(
|
||||
accounts => <AccountProviderAddedEventParams>{
|
||||
addedProvider: provider,
|
||||
initialAccounts: accounts
|
||||
},
|
||||
() => { /* Swallow failures at getting accounts, we'll just hide that provider */ });
|
||||
});
|
||||
return Promise.all(promises);
|
||||
}, () => {
|
||||
/* Swallow failures and just pretend we don't have any providers */
|
||||
return [];
|
||||
});
|
||||
}
|
||||
}
|
||||
56
src/sql/platform/accounts/common/eventTypes.ts
Normal file
56
src/sql/platform/accounts/common/eventTypes.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
/**
|
||||
* Result from calling add/update on the account store
|
||||
*/
|
||||
export interface AccountAdditionResult {
|
||||
/**
|
||||
* Whether or not an account was added in the add/update process
|
||||
*/
|
||||
accountAdded: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not an account was updated in the add/update process
|
||||
*/
|
||||
accountModified: boolean;
|
||||
|
||||
/**
|
||||
* The account that was added/updated (with any updates applied)
|
||||
*/
|
||||
changedAccount: azdata.Account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters that go along with an account provider being added
|
||||
*/
|
||||
export interface AccountProviderAddedEventParams {
|
||||
/**
|
||||
* The provider that was registered
|
||||
*/
|
||||
addedProvider: azdata.AccountProviderMetadata;
|
||||
|
||||
/**
|
||||
* The accounts that were rehydrated with the provider
|
||||
*/
|
||||
initialAccounts: azdata.Account[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters that go along when a provider's account list changes
|
||||
*/
|
||||
export interface UpdateAccountListEventParams {
|
||||
/**
|
||||
* ID of the provider who's account list changes
|
||||
*/
|
||||
providerId: string;
|
||||
|
||||
/**
|
||||
* Updated list of accounts, sorted appropriately
|
||||
*/
|
||||
accountList: azdata.Account[];
|
||||
}
|
||||
66
src/sql/platform/accounts/common/firewallRuleViewModel.ts
Normal file
66
src/sql/platform/accounts/common/firewallRuleViewModel.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
/**
|
||||
* View model for firewall rule dialog
|
||||
*/
|
||||
export class FirewallRuleViewModel {
|
||||
public isIPAddressSelected: boolean;
|
||||
public selectedAccount: azdata.Account;
|
||||
|
||||
private _defaultIPAddress: string;
|
||||
private _defaultFromSubnetIPRange: string;
|
||||
private _defaultToSubnetIPRange: string;
|
||||
private _fromSubnetIPRange: string;
|
||||
private _toSubnetIPRange: string;
|
||||
|
||||
constructor() {
|
||||
this.isIPAddressSelected = true;
|
||||
}
|
||||
|
||||
public get defaultIPAddress(): string {
|
||||
return this._defaultIPAddress;
|
||||
}
|
||||
|
||||
public get defaultFromSubnetIPRange(): string {
|
||||
return this._defaultFromSubnetIPRange;
|
||||
}
|
||||
|
||||
public get defaultToSubnetIPRange(): string {
|
||||
return this._defaultToSubnetIPRange;
|
||||
}
|
||||
|
||||
public set fromSubnetIPRange(IPAddress: string) {
|
||||
this._fromSubnetIPRange = IPAddress;
|
||||
}
|
||||
|
||||
public get fromSubnetIPRange(): string {
|
||||
if (this._fromSubnetIPRange) {
|
||||
return this._fromSubnetIPRange;
|
||||
} else {
|
||||
return this._defaultFromSubnetIPRange;
|
||||
}
|
||||
}
|
||||
|
||||
public set toSubnetIPRange(IPAddress: string) {
|
||||
this._toSubnetIPRange = IPAddress;
|
||||
}
|
||||
|
||||
public get toSubnetIPRange(): string {
|
||||
if (this._toSubnetIPRange) {
|
||||
return this._toSubnetIPRange;
|
||||
} else {
|
||||
return this._defaultToSubnetIPRange;
|
||||
}
|
||||
}
|
||||
|
||||
public updateDefaultValues(ipAddress: string): void {
|
||||
this._defaultIPAddress = ipAddress;
|
||||
this._defaultFromSubnetIPRange = ipAddress.replace(/\.[0-9]+$/g, '.0');
|
||||
this._defaultToSubnetIPRange = ipAddress.replace(/\.[0-9]+$/g, '.255');
|
||||
}
|
||||
}
|
||||
89
src/sql/platform/accounts/common/interfaces.ts
Normal file
89
src/sql/platform/accounts/common/interfaces.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { AccountAdditionResult, AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export const SERVICE_ID = 'accountManagementService';
|
||||
|
||||
export const IAccountManagementService = createDecorator<IAccountManagementService>(SERVICE_ID);
|
||||
|
||||
export interface IAccountManagementService {
|
||||
_serviceBrand: any;
|
||||
|
||||
// ACCOUNT MANAGEMENT METHODS //////////////////////////////////////////
|
||||
accountUpdated(account: azdata.Account): Thenable<void>;
|
||||
addAccount(providerId: string): Thenable<void>;
|
||||
getAccountProviderMetadata(): Thenable<azdata.AccountProviderMetadata[]>;
|
||||
getAccountsForProvider(providerId: string): Thenable<azdata.Account[]>;
|
||||
getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Thenable<{}>;
|
||||
removeAccount(accountKey: azdata.AccountKey): Thenable<boolean>;
|
||||
refreshAccount(account: azdata.Account): Thenable<azdata.Account>;
|
||||
|
||||
// UI METHODS //////////////////////////////////////////////////////////
|
||||
openAccountListDialog(): Thenable<void>;
|
||||
beginAutoOAuthDeviceCode(providerId: string, title: string, message: string, userCode: string, uri: string): Thenable<void>;
|
||||
endAutoOAuthDeviceCode(): void;
|
||||
cancelAutoOAuthDeviceCode(providerId: string): void;
|
||||
copyUserCodeAndOpenBrowser(userCode: string, uri: string): void;
|
||||
|
||||
// SERVICE MANAGEMENT METHODS /////////////////////////////////////////
|
||||
registerProvider(providerMetadata: azdata.AccountProviderMetadata, provider: azdata.AccountProvider): void;
|
||||
unregisterProvider(providerMetadata: azdata.AccountProviderMetadata): void;
|
||||
|
||||
// EVENTING ////////////////////////////////////////////////////////////
|
||||
readonly addAccountProviderEvent: Event<AccountProviderAddedEventParams>;
|
||||
readonly removeAccountProviderEvent: Event<azdata.AccountProviderMetadata>;
|
||||
readonly updateAccountListEvent: Event<UpdateAccountListEventParams>;
|
||||
}
|
||||
|
||||
// Enum matching the AzureResource enum from azdata.d.ts
|
||||
export enum AzureResource {
|
||||
ResourceManagement = 0,
|
||||
Sql = 1
|
||||
}
|
||||
|
||||
export interface IAccountStore {
|
||||
/**
|
||||
* Adds the provided account if the account doesn't exist. Updates the account if it already exists
|
||||
* @param {Account} account Account to add/update
|
||||
* @return {Thenable<AccountAdditionResult>} Results of the add/update operation
|
||||
*/
|
||||
addOrUpdate(account: azdata.Account): Thenable<AccountAdditionResult>;
|
||||
|
||||
/**
|
||||
* Retrieves all accounts, filtered by provider ID
|
||||
* @param {string} providerId ID of the provider to filter by
|
||||
* @return {Thenable<Account[]>} Promise to return all accounts that belong to the provided provider
|
||||
*/
|
||||
getAccountsByProvider(providerId: string): Thenable<azdata.Account[]>;
|
||||
|
||||
/**
|
||||
* Retrieves all accounts in the store. Returns empty array if store is not initialized
|
||||
* @return {Thenable<Account[]>} Promise to return all accounts
|
||||
*/
|
||||
getAllAccounts(): Thenable<azdata.Account[]>;
|
||||
|
||||
/**
|
||||
* Removes an account.
|
||||
* Returns false if the account was not found.
|
||||
* Otherwise, returns true.
|
||||
* @param key - The key of an account.
|
||||
* @returns True if the account was removed, false if the account doesn't exist
|
||||
*/
|
||||
remove(key: azdata.AccountKey): Thenable<boolean>;
|
||||
|
||||
/**
|
||||
* Updates the custom properties stored with an account.
|
||||
* Returns null if no account was found to update.
|
||||
* Otherwise, returns a new updated account instance.
|
||||
* @param key - The key of an account.
|
||||
* @param updateOperation - Operation to perform on the matching account
|
||||
* @returns True if the account was modified, false if the account doesn't exist
|
||||
*/
|
||||
update(key: azdata.AccountKey, updateOperation: (account: azdata.Account) => void): Thenable<boolean>;
|
||||
}
|
||||
Reference in New Issue
Block a user