mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Introduces event queue processor to create a consistent UI (#11780)
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { MigrationStateModel } from './stateMachine';
|
import { MigrationStateModel, StateChangeEvent } from './stateMachine';
|
||||||
export abstract class MigrationWizardPage {
|
export abstract class MigrationWizardPage {
|
||||||
constructor(protected readonly wizardPage: azdata.window.WizardPage, protected readonly migrationStateModel: MigrationStateModel) { }
|
constructor(protected readonly wizardPage: azdata.window.WizardPage, protected readonly migrationStateModel: MigrationStateModel) { }
|
||||||
|
|
||||||
@@ -16,5 +16,37 @@ export abstract class MigrationWizardPage {
|
|||||||
|
|
||||||
public abstract async onPageEnter(): Promise<void>;
|
public abstract async onPageEnter(): Promise<void>;
|
||||||
public abstract async onPageLeave(): Promise<void>;
|
public abstract async onPageLeave(): Promise<void>;
|
||||||
|
|
||||||
|
private readonly stateChanges: (() => Promise<void>)[] = [];
|
||||||
|
protected async onStateChangeEvent(e: StateChangeEvent) {
|
||||||
|
|
||||||
|
this.stateChanges.push((): Promise<void> => {
|
||||||
|
return this.handleStateChange(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.enableQueueProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private queueActive = false;
|
||||||
|
private async enableQueueProcessor(): Promise<void> {
|
||||||
|
if (this.queueActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.queueActive = true;
|
||||||
|
while (true) {
|
||||||
|
const stateChangeFunction = this.stateChanges.shift();
|
||||||
|
if (!stateChangeFunction) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await stateChangeFunction();
|
||||||
|
} catch (ex) {
|
||||||
|
console.error(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.queueActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract async handleStateChange(e: StateChangeEvent): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export enum State {
|
|||||||
export interface Model {
|
export interface Model {
|
||||||
readonly sourceConnection: azdata.connection.Connection;
|
readonly sourceConnection: azdata.connection.Connection;
|
||||||
readonly currentState: State;
|
readonly currentState: State;
|
||||||
|
gatheringInformationError: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StateChangeEvent {
|
export interface StateChangeEvent {
|
||||||
@@ -37,6 +38,7 @@ export interface StateChangeEvent {
|
|||||||
export class MigrationStateModel implements Model, vscode.Disposable {
|
export class MigrationStateModel implements Model, vscode.Disposable {
|
||||||
private _stateChangeEventEmitter = new vscode.EventEmitter<StateChangeEvent>();
|
private _stateChangeEventEmitter = new vscode.EventEmitter<StateChangeEvent>();
|
||||||
private _currentState: State;
|
private _currentState: State;
|
||||||
|
private _gatheringInformationError: string | undefined;
|
||||||
|
|
||||||
constructor(private readonly _sourceConnection: azdata.connection.Connection) {
|
constructor(private readonly _sourceConnection: azdata.connection.Connection) {
|
||||||
this._currentState = State.INIT;
|
this._currentState = State.INIT;
|
||||||
@@ -58,6 +60,14 @@ export class MigrationStateModel implements Model, vscode.Disposable {
|
|||||||
this._stateChangeEventEmitter.fire({ oldState, newState: this.currentState });
|
this._stateChangeEventEmitter.fire({ oldState, newState: this.currentState });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get gatheringInformationError(): string | undefined {
|
||||||
|
return this._gatheringInformationError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set gatheringInformationError(error: string | undefined) {
|
||||||
|
this._gatheringInformationError = error;
|
||||||
|
}
|
||||||
|
|
||||||
public get stateChangeEvent(): vscode.Event<StateChangeEvent> {
|
public get stateChangeEvent(): vscode.Event<StateChangeEvent> {
|
||||||
return this._stateChangeEventEmitter.event;
|
return this._stateChangeEventEmitter.event;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { MigrationWizardPage } from '../models/migrationWizardPage';
|
import { MigrationWizardPage } from '../models/migrationWizardPage';
|
||||||
import { SOURCE_CONFIGURATION_PAGE_TITLE, COLLECTING_SOURCE_CONFIGURATIONS, COLLECTING_SOURCE_CONFIGURATIONS_INFO, COLLECTING_SOURCE_CONFIGURATIONS_ERROR } from '../models/strings';
|
import { SOURCE_CONFIGURATION_PAGE_TITLE, COLLECTING_SOURCE_CONFIGURATIONS, COLLECTING_SOURCE_CONFIGURATIONS_INFO, COLLECTING_SOURCE_CONFIGURATIONS_ERROR } from '../models/strings';
|
||||||
import { MigrationStateModel } from '../models/stateMachine';
|
import { MigrationStateModel, StateChangeEvent, State } from '../models/stateMachine';
|
||||||
|
import { Disposable } from 'vscode';
|
||||||
|
|
||||||
export class SourceConfigurationPage extends MigrationWizardPage {
|
export class SourceConfigurationPage extends MigrationWizardPage {
|
||||||
constructor(migrationStateModel: MigrationStateModel) {
|
constructor(migrationStateModel: MigrationStateModel) {
|
||||||
@@ -29,19 +30,11 @@ export class SourceConfigurationPage extends MigrationWizardPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async registerContent(view: azdata.ModelView) {
|
private async registerContent(view: azdata.ModelView) {
|
||||||
await this.createGatheringInformationPage(view);
|
await this.initialState(view);
|
||||||
setTimeout(async () => {
|
|
||||||
console.log('doing it');
|
|
||||||
try {
|
|
||||||
await this.createErrorInInformationGatheringPage(view);
|
|
||||||
} catch (ex) {
|
|
||||||
console.log(ex);
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private gatheringInfoComponent!: azdata.FormComponent;
|
private gatheringInfoComponent!: azdata.FormComponent;
|
||||||
private async createGatheringInformationPage(view: azdata.ModelView) {
|
private async initialState(view: azdata.ModelView) {
|
||||||
this.gatheringInfoComponent = this.createGatheringInfoComponent(view);
|
this.gatheringInfoComponent = this.createGatheringInfoComponent(view);
|
||||||
const form = view.modelBuilder.formContainer().withFormItems(
|
const form = view.modelBuilder.formContainer().withFormItems(
|
||||||
[
|
[
|
||||||
@@ -59,9 +52,13 @@ export class SourceConfigurationPage extends MigrationWizardPage {
|
|||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private async createErrorInInformationGatheringPage(view: azdata.ModelView) {
|
private async enterErrorState() {
|
||||||
const component = this.gatheringInfoComponent.component as azdata.TextComponent;
|
const component = this.gatheringInfoComponent.component as azdata.TextComponent;
|
||||||
component.value = COLLECTING_SOURCE_CONFIGURATIONS_ERROR('Some error');
|
component.value = COLLECTING_SOURCE_CONFIGURATIONS_ERROR(this.migrationStateModel.gatheringInformationError);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async enterTargetSelectionState() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region component builders
|
//#region component builders
|
||||||
@@ -79,11 +76,22 @@ export class SourceConfigurationPage extends MigrationWizardPage {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
public async onPageEnter(): Promise<void> {
|
|
||||||
|
|
||||||
|
private eventListener: Disposable | undefined;
|
||||||
|
public async onPageEnter(): Promise<void> {
|
||||||
|
this.eventListener = this.migrationStateModel.stateChangeEvent(async (e) => this.onStateChangeEvent(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async onPageLeave(): Promise<void> {
|
public async onPageLeave(): Promise<void> {
|
||||||
|
this.eventListener?.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async handleStateChange(e: StateChangeEvent): Promise<void> {
|
||||||
|
switch (e.newState) {
|
||||||
|
case State.COLLECTION_SOURCE_INFO_ERROR:
|
||||||
|
return this.enterErrorState();
|
||||||
|
case State.TARGET_SELECTION:
|
||||||
|
return this.enterTargetSelectionState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user