[Sql Migration] Stabilize save and close logic and fix related ux bugs (#18579)

* add loadSavedInfo function in stateMachine; only open wizard if didLoadSavedInfo

* * add loadSavedInfo function in stateMachine; only open wizard if didLoadSavedInfo
* replaced savedInfo.miggrationServiceId string with sqlMigrationServer object
* selectDatbasesFromList helper function to check previously selected dbs in dbSelectorPage and sqlDatabaseTree

* * remove savedInfo references from targetSelectionPage, migrationModePage
* add selectDefaultDropdownValue helper to stateMachine to handle unify savedInfo selection logic
* add updateDropdownLoadingStatus to targetSelectionPage
* check if values exist before making api calls in statemachine

* removed savedInfo references from databaseBackupPage, integrationRuntimePage

* databaseBackupPage - targetDatabaseNames, networkShares, blobs need to rely on savedInfo as user may update the list of migrationdbs during the retry/saveAndClose

* re-add serverAssessments to savedInfo; only getAssessments if it does not exist or needs to be updated; fix networkShare type savedInfo

* rename _assessmentDbs to _databasesForAssessment; _migrationDbs to _databasesForMigration

* load blobs/networkshares savedinfo; move selectDefaultDropdownValue to utils

* fix selectDefaultDropdownValue; refreshDatabaseBackupPage when user changes target subscription or location
This commit is contained in:
Rachel Kim
2022-03-04 16:00:44 -08:00
committed by GitHub
parent c9aa3e9f4b
commit 33259764f7
17 changed files with 621 additions and 643 deletions

View File

@@ -5,7 +5,7 @@
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { MigrationStateModel, MigrationTargetType, Page } from '../../models/stateMachine';
import { MigrationStateModel, MigrationTargetType } from '../../models/stateMachine';
import { SqlDatabaseTree } from './sqlDatabasesTree';
import { SqlMigrationImpactedObjectInfo } from '../../../../mssql/src/mssql';
import { SKURecommendationPage } from '../../wizard/skuRecommendationPage';
@@ -32,9 +32,6 @@ export class AssessmentResultsDialog {
constructor(public ownerUri: string, public model: MigrationStateModel, public title: string, private _skuRecommendationPage: SKURecommendationPage, private _targetType: MigrationTargetType) {
this._model = model;
if (this._model.resumeAssessment && this._model.savedInfo.closedPage >= Page.DatabaseBackup) {
this._model._databaseAssessment = <string[]>this._model.savedInfo.databaseAssessment;
}
this._tree = new SqlDatabaseTree(this._model, this._targetType);
}
@@ -87,16 +84,31 @@ export class AssessmentResultsDialog {
}
protected async execute() {
if (this._targetType === MigrationTargetType.SQLVM) {
this._model._vmDbs = this._tree.selectedDbs();
} else {
this._model._miDbs = this._tree.selectedDbs();
const selectedDbs = this._tree.selectedDbs();
switch (this._targetType) {
case MigrationTargetType.SQLMI: {
this.didUpdateDatabasesForMigration(this._model._miDbs, selectedDbs);
this._model._miDbs = selectedDbs;
break;
}
case MigrationTargetType.SQLVM: {
this.didUpdateDatabasesForMigration(this._model._vmDbs, selectedDbs);
this._model._vmDbs = selectedDbs;
break;
}
}
await this._skuRecommendationPage.refreshCardText();
this.model.refreshDatabaseBackupPage = true;
this._isOpen = false;
}
private didUpdateDatabasesForMigration(priorDbs: string[], selectedDbs: string[]) {
this._model._didUpdateDatabasesForMigration = selectedDbs.length === 0
|| selectedDbs.length !== priorDbs.length
|| priorDbs.some(db => selectedDbs.indexOf(db) < 0);
}
protected async cancel() {
this._isOpen = false;
}

View File

@@ -50,6 +50,16 @@ export class SavedAssessmentDialog {
reject(ex);
}
});
dialog.registerCloseValidator(async () => {
if (this.stateModel.resumeAssessment) {
if (!this.stateModel.loadSavedInfo()) {
void vscode.window.showInformationMessage(constants.OPEN_SAVED_INFO_ERROR);
return false;
}
}
return true;
});
});
}
@@ -67,14 +77,8 @@ export class SavedAssessmentDialog {
}
protected async execute() {
if (this.stateModel.resumeAssessment) {
const wizardController = new WizardController(this.context, this.stateModel);
await wizardController.openWizard(this.stateModel.sourceConnectionId);
} else {
// normal flow
const wizardController = new WizardController(this.context, this.stateModel);
await wizardController.openWizard(this.stateModel.sourceConnectionId);
}
const wizardController = new WizardController(this.context, this.stateModel);
await wizardController.openWizard(this.stateModel.sourceConnectionId);
this._isOpen = false;
}
@@ -90,7 +94,7 @@ export class SavedAssessmentDialog {
const buttonGroup = 'resumeMigration';
const radioStart = view.modelBuilder.radioButton().withProps({
label: constants.START_MIGRATION,
label: constants.START_NEW_SESSION,
name: buttonGroup,
CSSStyles: {
...styles.BODY_CSS,
@@ -105,7 +109,7 @@ export class SavedAssessmentDialog {
}
});
const radioContinue = view.modelBuilder.radioButton().withProps({
label: constants.CONTINUE_MIGRATION,
label: constants.RESUME_SESSION,
name: buttonGroup,
CSSStyles: {
...styles.BODY_CSS,
@@ -122,11 +126,9 @@ export class SavedAssessmentDialog {
const flex = view.modelBuilder.flexContainer()
.withLayout({
flexFlow: 'column',
height: '100%',
width: '100%',
}).withProps({
CSSStyles: {
'margin': '20px 15px',
'padding': '20px 15px',
}
}).component();
flex.addItem(radioStart, { flex: '0 0 auto' });
@@ -134,5 +136,4 @@ export class SavedAssessmentDialog {
return flex;
}
}

View File

@@ -5,12 +5,13 @@
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { SqlMigrationAssessmentResultItem, SqlMigrationImpactedObjectInfo } from '../../../../mssql/src/mssql';
import { MigrationStateModel, MigrationTargetType, Page } from '../../models/stateMachine';
import { MigrationStateModel, MigrationTargetType } from '../../models/stateMachine';
import * as constants from '../../constants/strings';
import { debounce } from '../../api/utils';
import { IconPath, IconPathHelper } from '../../constants/iconPathHelper';
import * as styles from '../../constants/styles';
import { EOL } from 'os';
import { selectDatabasesFromList } from '../../constants/helper';
const styleLeft: azdata.CssStyles = {
'border': 'none',
@@ -142,7 +143,7 @@ export class SqlDatabaseTree {
...styles.BOLD_NOTE_CSS,
'margin': '0px 15px 0px 15px'
},
value: constants.DATABASES(0, this._model._databaseAssessment?.length)
value: constants.DATABASES(0, this._model._databasesForAssessment?.length)
}).component();
return this._databaseCount;
}
@@ -881,7 +882,7 @@ export class SqlDatabaseTree {
public async initialize(): Promise<void> {
let instanceTableValues: azdata.DeclarativeTableCellValue[][] = [];
this._databaseTableValues = [];
this._dbNames = this._model._databaseAssessment;
this._dbNames = this._model._databasesForAssessment;
const selectedDbs = (this._targetType === MigrationTargetType.SQLVM) ? this._model._vmDbs : this._model._miDbs;
this._serverName = (await this._model.getSourceConnectionProfile()).serverName;
@@ -959,25 +960,16 @@ export class SqlDatabaseTree {
});
}
await this._instanceTable.setDataValues(instanceTableValues);
if (this._model.resumeAssessment && this._model.savedInfo.closedPage >= Page.SKURecommendation && this._targetType === this._model.savedInfo.migrationTargetType) {
await this._databaseTable.setDataValues(this._model.savedInfo.migrationDatabases);
} else {
if (this._model.retryMigration && this._targetType === this._model.savedInfo.migrationTargetType) {
const sourceDatabaseName = this._model.savedInfo.databaseList[0];
const sourceDatabaseIndex = this._dbNames.indexOf(sourceDatabaseName);
this._databaseTableValues[sourceDatabaseIndex][0].value = true;
}
await this._databaseTable.setDataValues(this._databaseTableValues);
await this.updateValuesOnSelection();
}
this._databaseTableValues = selectDatabasesFromList(this._model._databasesForMigration, this._databaseTableValues);
await this._databaseTable.setDataValues(this._databaseTableValues);
await this.updateValuesOnSelection();
}
private async updateValuesOnSelection() {
await this._databaseCount.updateProperties({
'value': constants.DATABASES(this.selectedDbs()?.length, this._model._databaseAssessment?.length)
'value': constants.DATABASES(this.selectedDbs()?.length, this._model._databasesForAssessment?.length)
});
this._model._databaseSelection = <azdata.DeclarativeTableCellValue[][]>this._databaseTable.dataValues;
}
// undo when bug #16445 is fixed