diff --git a/extensions/sql-migration/package.json b/extensions/sql-migration/package.json index 5af176b140..821b8dc64d 100644 --- a/extensions/sql-migration/package.json +++ b/extensions/sql-migration/package.json @@ -2,7 +2,7 @@ "name": "sql-migration", "displayName": "%displayName%", "description": "%description%", - "version": "0.0.6", + "version": "0.0.7", "publisher": "Microsoft", "preview": true, "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt", diff --git a/extensions/sql-migration/src/constants/strings.ts b/extensions/sql-migration/src/constants/strings.ts index 3d3bfac4f4..f41b35b65b 100644 --- a/extensions/sql-migration/src/constants/strings.ts +++ b/extensions/sql-migration/src/constants/strings.ts @@ -13,6 +13,12 @@ export const WIZARD_TITLE = localize('sql-migration.wizard.title', "SQL Migratio export const SOURCE_CONFIGURATION_PAGE_TITLE = localize('sql.migration.wizard.source_configuration.title', "SQL Source Configuration"); // //#endregion +// Assessments Progress Page +export const ASSESSMENT_PROGRESS = localize('sql.migration.assessments.progress', "Assessments Progress"); +export const ASSESSMENT_IN_PROGRESS = localize('sql.migration.assessment.in.progress', "Assessment in progress"); +export function ASSESSMENT_IN_PROGRESS_CONTENT(dbName: string) { + return localize('sql.migration.assessment.in.progress.content', "We are assessing the databases in your SQL server instance {0} to identify the right Azure SQL target.\n\nThis may take some time.", dbName); +} export const COLLECTING_SOURCE_CONFIGURATIONS = localize('sql.migration.collecting_source_configurations', "Collecting source configurations"); export const COLLECTING_SOURCE_CONFIGURATIONS_INFO = localize('sql.migration.collecting_source_configurations.info', "We need to collect some information about how your data is configured currently.\nThis may take some time."); export const COLLECTING_SOURCE_CONFIGURATIONS_ERROR = (error: string = ''): string => { diff --git a/extensions/sql-migration/src/wizard/skuRecommendationPage.ts b/extensions/sql-migration/src/wizard/skuRecommendationPage.ts index 34d30aa698..ef7c865b98 100644 --- a/extensions/sql-migration/src/wizard/skuRecommendationPage.ts +++ b/extensions/sql-migration/src/wizard/skuRecommendationPage.ts @@ -34,6 +34,13 @@ export class SKURecommendationPage extends MigrationWizardPage { private _rbg!: azdata.RadioCardGroupComponent; private eventListener!: vscode.Disposable; private _rbgLoader!: azdata.LoadingComponent; + private _progressContainer!: azdata.FlexContainer; + private _assessmentComponent!: azdata.FlexContainer; + private _assessmentProgress!: azdata.TextComponent; + private _assessmentInfo!: azdata.TextComponent; + private _formContainer!: azdata.ComponentBuilder; + private _assessmentLoader!: azdata.LoadingComponent; + private _rootContainer!: azdata.FlexContainer; private _supportedProducts: Product[] = [ { @@ -48,6 +55,7 @@ export class SKURecommendationPage extends MigrationWizardPage { } ]; + constructor(wizard: azdata.window.Wizard, migrationStateModel: MigrationStateModel) { super(wizard, azdata.window.createWizardPage(constants.SKU_RECOMMENDATION_PAGE_TITLE), migrationStateModel); } @@ -150,8 +158,9 @@ export class SKURecommendationPage extends MigrationWizardPage { - this._view = view; - const formContainer = view.modelBuilder.formContainer().withFormItems( + + + this._formContainer = view.modelBuilder.formContainer().withFormItems( [ { title: '', @@ -172,8 +181,32 @@ export class SKURecommendationPage extends MigrationWizardPage { component: targetContainer } ] - ); - await view.initializeModel(formContainer.component()); + ).withProps({ + CSSStyles: { + display: 'none' + } + }); + + this._assessmentComponent = this._view.modelBuilder.flexContainer().withLayout({ + height: '100%', + flexFlow: 'column' + }).withProps({ + CSSStyles: { + 'margin-left': '30px' + } + }).component(); + + this._assessmentComponent.addItem(this.createAssessmentProgress(), { flex: '0 0 auto' }); + this._assessmentComponent.addItem(await this.createAssessmentInfo(), { flex: '0 0 auto' }); + + this._rootContainer = this._view.modelBuilder.flexContainer().withLayout({ + height: '100%', + flexFlow: 'column' + }).component(); + this._rootContainer.addItem(this._assessmentComponent, { flex: '0 0 auto' }); + this._rootContainer.addItem(this._formContainer.component(), { flex: '0 0 auto' }); + + await this._view.initializeModel(this._rootContainer); } private createStatusComponent(view: azdata.ModelView): azdata.TextComponent { @@ -300,6 +333,7 @@ export class SKURecommendationPage extends MigrationWizardPage { } private async constructDetails(): Promise { + this._assessmentLoader.loading = true; const serverName = (await this.migrationStateModel.getSourceConnectionProfile()).serverName; this._igComponent.value = constants.ASSESSMENT_COMPLETED(serverName); try { @@ -308,7 +342,9 @@ export class SKURecommendationPage extends MigrationWizardPage { } catch (e) { console.log(e); } + this.refreshCardText(); + this._assessmentLoader.loading = false; } private createAzureSubscriptionText(view: azdata.ModelView): azdata.TextComponent { @@ -370,8 +406,6 @@ export class SKURecommendationPage extends MigrationWizardPage { public async onPageEnter(): Promise { - this.constructDetails(); - this.populateSubscriptionDropdown(); this.wizard.registerNavigationValidator((pageChangeInfo) => { const errors: string[] = []; this.wizard.message = { @@ -412,6 +446,19 @@ export class SKURecommendationPage extends MigrationWizardPage { } return true; }); + this.wizard.nextButton.enabled = false; + if (!this.migrationStateModel._assessmentResults) { + await this.constructDetails(); + } + this._assessmentComponent.updateCssStyles({ + display: 'none' + }); + this._formContainer.component().updateCssStyles({ + display: 'block' + }); + + this.populateSubscriptionDropdown(); + this.wizard.nextButton.enabled = true; } public async onPageLeave(): Promise { @@ -474,6 +521,40 @@ export class SKURecommendationPage extends MigrationWizardPage { } this._rbgLoader.loading = false; } + + private createAssessmentProgress(): azdata.FlexContainer { + + this._assessmentLoader = this._view.modelBuilder.loadingComponent().component(); + this._assessmentProgress = this._view.modelBuilder.text().withProps({ + value: constants.ASSESSMENT_IN_PROGRESS, + CSSStyles: { + 'font-size': '18px', + 'line-height': '24px', + 'margin-right': '20px' + } + }).component(); + + this._progressContainer = this._view.modelBuilder.flexContainer().withLayout({ + height: '100%', + flexFlow: 'row' + }).component(); + + this._progressContainer.addItem(this._assessmentProgress, { flex: '0 0 auto' }); + this._progressContainer.addItem(this._assessmentLoader, { flex: '0 0 auto' }); + return this._progressContainer; + } + + private async createAssessmentInfo(): Promise { + this._assessmentInfo = this._view.modelBuilder.text().withProps({ + value: constants.ASSESSMENT_IN_PROGRESS_CONTENT((await this.migrationStateModel.getSourceConnectionProfile()).serverName), + CSSStyles: { + 'font-size': '13px', + 'line-height': '18px', + 'font-weight': '600', + } + }).component(); + return this._assessmentInfo; + } } diff --git a/extensions/sql-migration/src/wizard/wizardController.ts b/extensions/sql-migration/src/wizard/wizardController.ts index e97efd6e06..2ef1bce3be 100644 --- a/extensions/sql-migration/src/wizard/wizardController.ts +++ b/extensions/sql-migration/src/wizard/wizardController.ts @@ -37,7 +37,6 @@ export class WizardController { wizard.generateScriptButton.enabled = false; wizard.generateScriptButton.hidden = true; const skuRecommendationPage = new SKURecommendationPage(wizard, stateModel); - // const subscriptionSelectionPage = new SubscriptionSelectionPage(wizard, stateModel); const migrationModePage = new MigrationModePage(wizard, stateModel); const azureAccountsPage = new AccountsSelectionPage(wizard, stateModel); const sourceConfigurationPage = new SqlSourceConfigurationPage(wizard, stateModel); @@ -46,7 +45,6 @@ export class WizardController { const summaryPage = new SummaryPage(wizard, stateModel); const pages: MigrationWizardPage[] = [ - // subscriptionSelectionPage, azureAccountsPage, sourceConfigurationPage, skuRecommendationPage,