Add account loading screen until provider accounts have finished loading (#18692)

* Added wait for accounts to be loaded to prevent premature loading

* revert changes

* WIP loading screen

* added work in progress emitter.

* added test event fire

* added test for accountDialogController emitter

* fixed test

* added event emitters inside accountDialog

* WIP changes to loading

* added fixed filter removed unnecessary emitters

* added working loading page

* fix for spaces

* added improvements

* fixed space

* added loading provider label xlf

* moved spinner = false to show views

* Added loadingSpinner

* removed additional localization

* removed change to css

* removed newline

* small changes

* fixed spaces

* fixed line positions

* removed loadingComplete

* added spinner container (so that account loading spinner appears on top)

* added small fix

* changed wording

* changed wording slightly

* removed comment
This commit is contained in:
Alex Ma
2022-03-14 09:44:09 -07:00
committed by GitHub
parent 02093f8497
commit 26e6cd28c2
3 changed files with 28 additions and 10 deletions

View File

@@ -87,7 +87,7 @@ function createInstantiationService(addAccountFailureEmitter?: Emitter<string>):
.returns(() => undefined);
// Create a mock account dialog
let accountDialog = new AccountDialog(undefined!, undefined!, instantiationService.object, undefined!, undefined!, undefined!, undefined!, new MockContextKeyService(), undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!);
let accountDialog = new AccountDialog(undefined!, undefined!, instantiationService.object, undefined!, undefined!, undefined!, undefined!, new MockContextKeyService(), undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!);
let mockAccountDialog = TypeMoq.Mock.ofInstance(accountDialog);
mockAccountDialog.setup(x => x.onAddAccountErrorEvent)
.returns(() => { return addAccountFailureEmitter ? addAccountFailureEmitter.event : mockEvent.event; });

View File

@@ -45,7 +45,9 @@ import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { Registry } from 'vs/platform/registry/common/platform';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { Iterable } from 'vs/base/common/iterator';
import { LoadingSpinner } from 'sql/base/browser/ui/loadingSpinner/loadingSpinner';
import { Tenant, TenantListDelegate, TenantListRenderer } from 'sql/workbench/services/accountManagement/browser/tenantListRenderer';
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
export const VIEWLET_ID = 'workbench.view.accountpanel';
@@ -130,6 +132,7 @@ export class AccountDialog extends Modal {
// MEMBER VARIABLES ////////////////////////////////////////////////////
private _providerViewsMap = new Map<string, IProviderViewUiComponent>();
private _loadingSpinner: LoadingSpinner;
private _closeButton?: Button;
private _addAccountButton?: Button;
@@ -161,7 +164,8 @@ export class AccountDialog extends Modal {
@IQuickInputService private _quickInputService: IQuickInputService,
@INotificationService private _notificationService: INotificationService,
@IOpenerService protected readonly openerService: IOpenerService,
@ITelemetryService private readonly vstelemetryService: ITelemetryService
@ITelemetryService private readonly vstelemetryService: ITelemetryService,
@IAccountManagementService private readonly _accountManagementService: IAccountManagementService,
) {
super(
localize('linkedAccounts', "Linked accounts"),
@@ -172,8 +176,7 @@ export class AccountDialog extends Modal {
themeService,
logService,
textResourcePropertiesService,
contextKeyService,
{ hasSpinner: true }
contextKeyService
);
// Setup the event emitters
@@ -209,6 +212,9 @@ export class AccountDialog extends Modal {
protected renderBody(container: HTMLElement) {
this._container = container;
this._loadingSpinner = new LoadingSpinner(this._container, { showText: true, fullSize: true });
this._splitViewContainer = DOM.$('div.account-view.monaco-pane-view');
DOM.append(container, this._splitViewContainer);
this._splitView = new SplitView(this._splitViewContainer);
@@ -252,23 +258,37 @@ export class AccountDialog extends Modal {
this.hide(hideReason);
}
public open() {
public async open() {
let accountMetadata = await this._accountManagementService.getAccountProviderMetadata();
this.show();
if (!this.isEmptyLinkedAccount()) {
this.showSplitView();
} else {
}
else if (accountMetadata.length === 0) {
this.showLoadingSpinner();
}
else {
this.showNoAccountContainer();
}
}
private showNoAccountContainer() {
this._loadingSpinner.loading = false;
this._splitViewContainer!.hidden = true;
this._noaccountViewContainer!.hidden = false;
this._addAccountButton!.focus();
}
private showLoadingSpinner() {
this._loadingSpinner.loadingMessage = localize('accountDialog.loadingProviderLabel', "Loading accounts...");
this._loadingSpinner.loading = true;
this._splitViewContainer!.hidden = true;
this._noaccountViewContainer!.hidden = true;
}
private showSplitView() {
this._loadingSpinner.loading = false;
this._splitViewContainer!.hidden = false;
this._noaccountViewContainer!.hidden = true;
if (Iterable.consume(this._providerViewsMap.values()).length > 0) {
@@ -318,9 +338,7 @@ export class AccountDialog extends Modal {
AddAccountAction,
newProvider.addedProvider.id
);
addAccountAction.addAccountCompleteEvent(() => this.spinner = false);
addAccountAction.addAccountErrorEvent(msg => this._onAddAccountErrorEmitter.fire(msg));
addAccountAction.addAccountStartEvent(() => this.spinner = true);
let providerView = new AccountPanel(
{

View File

@@ -377,8 +377,8 @@ export class AccountManagementService implements IAccountManagementService {
const accounts = await this._accountStore.getAccountsByProvider(providerMetadata.id);
const updatedAccounts = await provider.initialize(accounts);
// Don't add the accounts that are about to get deleted to the cache.
this._providers[providerMetadata.id].accounts = updatedAccounts.filter(s => s.delete === false);
// Don't add the accounts that are explicitly marked to be deleted to the cache.
this._providers[providerMetadata.id].accounts = updatedAccounts.filter(s => !s.delete);
const writePromises = updatedAccounts.map(async (account) => {
if (account.delete === true) {