Co-authored-by: Siyang Yao <siyao@microsoft.com>
This commit is contained in:
Siyang Yao
2023-10-11 14:53:49 -07:00
committed by GitHub
parent 52bbb60def
commit eb3598f1a7
7 changed files with 85 additions and 11 deletions

View File

@@ -1169,3 +1169,9 @@ export async function clearDropDown(dropDown: DropDownComponent): Promise<void>
await dropDown.updateProperty('value', undefined);
await dropDown.updateProperty('values', []);
}
export async function clearDropDownWithLoading(dropDown: DropDownComponent): Promise<void> {
dropDown.loading = true;
await dropDown.updateProperty('value', undefined);
await dropDown.updateProperty('values', []);
}

View File

@@ -547,7 +547,7 @@ export function ACCOUNT_CREDENTIALS_REFRESH(accountName: string): string {
"{0} (requires credentials refresh)",
accountName);
}
export const SELECT_SERVICE_PLACEHOLDER = localize('sql.migration.select.service.select.migration.target', "Select a target server.");
export const SELECT_SERVICE_PLACEHOLDER = localize('sql.migration.select.service.select.migration.target', "Select a target server");
// database backup page
export const DATA_SOURCE_CONFIGURATION_PAGE_TITLE = localize('sql.migration.data.source.configuration.page.title', "Data source configuration");

View File

@@ -75,7 +75,8 @@ export class RestartMigrationDialog {
// Integration Runtime
sqlMigrationService: serviceContext.migrationService,
serviceSubscription: null,
serviceResourceGroup: null
serviceResourceGroup: null,
xEventsFilesFolderPath: null
};
const getStorageAccountResourceGroup = (storageAccountResourceId: string): azureResource.AzureResourceResourceGroup => {

View File

@@ -153,6 +153,7 @@ export interface SavedInfo {
serviceSubscription: azurecore.azureResource.AzureResourceSubscription | null;
serviceResourceGroup: azurecore.azureResource.AzureResourceResourceGroup | null;
serverAssessment: ServerAssessment | null;
xEventsFilesFolderPath: string | null;
skuRecommendation: SkuRecommendationSavedInfo | null;
}
@@ -1257,6 +1258,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
targetDatabaseNames: [],
sqlMigrationService: undefined,
serverAssessment: null,
xEventsFilesFolderPath: null,
skuRecommendation: null,
serviceResourceGroup: null,
serviceSubscription: null,
@@ -1288,6 +1290,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
saveInfo.migrationTargetType = this._targetType;
saveInfo.databaseList = this._databasesForMigration;
saveInfo.serverAssessment = this._assessmentResults;
saveInfo.xEventsFilesFolderPath = this._xEventsFilesFolderPath;
if (this._skuRecommendationPerformanceDataSource) {
const skuRecommendation: SkuRecommendationSavedInfo = {
@@ -1304,6 +1307,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
case Page.DatabaseSelector:
saveInfo.databaseAssessment = this._databasesForAssessment;
saveInfo.xEventsFilesFolderPath = this._xEventsFilesFolderPath;
await this.extensionContext.globalState.update(`${this.mementoString}.${serverName}`, saveInfo);
}
}
@@ -1350,6 +1354,9 @@ export class MigrationStateModel implements Model, vscode.Disposable {
this._sqlMigrationServiceSubscription = this.savedInfo.serviceSubscription || undefined!;
this._sqlMigrationServiceResourceGroup = this.savedInfo.serviceResourceGroup || undefined!;
this._assessedDatabaseList = this.savedInfo.databaseAssessment ?? [];
this._databasesForAssessment = this.savedInfo.databaseAssessment ?? [];
this._xEventsFilesFolderPath = this.savedInfo.xEventsFilesFolderPath ?? '';
const savedAssessmentResults = this.savedInfo.serverAssessment;
if (savedAssessmentResults) {
this._assessmentResults = savedAssessmentResults;

View File

@@ -18,11 +18,12 @@ export class DatabaseSelectorPage extends MigrationWizardPage {
private _databaseSelectorTable!: azdata.TableComponent;
private _xEventsGroup!: azdata.GroupContainer;
private _xEventsFolderPickerInput!: azdata.InputBoxComponent;
private _xEventsFilesFolderPath!: string;
private _xEventsFilesFolderPath: string = '';
private _dbNames!: string[];
private _dbCount!: azdata.TextComponent;
private _databaseTableValues!: any[];
private _disposables: vscode.Disposable[] = [];
private _enableNavigationValidation: boolean = true;
private readonly TABLE_WIDTH = 650;
@@ -57,6 +58,12 @@ export class DatabaseSelectorPage extends MigrationWizardPage {
if (pageChangeInfo.newPage < pageChangeInfo.lastPage) {
return true;
}
if (!this._enableNavigationValidation) {
this._enableNavigationValidation = true;
return true;
}
if (this.selectedDbs().length === 0) {
this.wizard.message = {
text: constants.SELECT_DATABASE_TO_CONTINUE,
@@ -67,6 +74,14 @@ export class DatabaseSelectorPage extends MigrationWizardPage {
return true;
});
if (this.migrationStateModel.resumeAssessment) {
// if start a new session, it won't trigger navigation validator until clicking 'Next'.
// It works as expected if no target or databases are selected, it should show errors and block to next page.
// However, if resume the previously saved session, wizard.setCurrentPage will trigger wizard navigation validator without clicking 'Next'.
// At this moment, all components are not initialized yet. Therefore, _databaseSelectorTable is undefined, so selectedDbs().length is always 0.
this._enableNavigationValidation = false;
}
this._xEventsFilesFolderPath = this.migrationStateModel._xEventsFilesFolderPath;
}

View File

@@ -654,6 +654,10 @@ export class SKURecommendationPage extends MigrationWizardPage {
public async refreshCardText(showLoadingIcon: boolean = true): Promise<void> {
this._rbgLoader.loading = showLoadingIcon && true;
if (!this._rbg.selectedCardId) {
this._rbg.selectedCardId = MigrationTargetType.SQLMI;
}
switch (this._rbg.selectedCardId) {
case MigrationTargetType.SQLMI:
this.migrationStateModel._databasesForMigration = this.migrationStateModel._miDbs;

View File

@@ -89,7 +89,7 @@ export class TargetSelectionPage extends MigrationWizardPage {
{ component: this._pageDescription },
{ component: this.createAzureAccountsDropdown() },
{ component: this.createAzureTenantContainer() },
{ component: this.createTargetDropdownContainer() },
{ component: await this.createTargetDropdownContainer() },
{ component: this._certMigrationRequiredInfoBox }
]).withProps({
CSSStyles: { 'padding-top': '0' }
@@ -271,6 +271,10 @@ export class TargetSelectionPage extends MigrationWizardPage {
await this._targetPasswordInputBox.updateProperties({ required: isSqlDbTarget });
await utils.updateControlDisplay(this._resourceAuthenticationContainer, isSqlDbTarget);
if (!this._migrationTargetPlatform) {
this._migrationTargetPlatform = this.migrationStateModel._targetType;
}
if (this._migrationTargetPlatform !== this.migrationStateModel._targetType) {
// if the user had previously selected values on this page, then went back to change the migration target platform
// and came back, forcibly reload the location/resource group/resource values since they will now be different
@@ -287,14 +291,19 @@ export class TargetSelectionPage extends MigrationWizardPage {
await utils.clearDropDown(this._azureAccountsDropdown);
await utils.clearDropDown(this._accountTenantDropdown);
await utils.clearDropDown(this._azureSubscriptionDropdown);
await utils.clearDropDown(this._azureLocationDropdown);
await utils.clearDropDown(this._azureResourceGroupDropdown);
await utils.clearDropDown(this._azureResourceDropdown);
await utils.clearDropDownWithLoading(this._azureSubscriptionDropdown);
await utils.clearDropDownWithLoading(this._azureLocationDropdown);
await utils.clearDropDownWithLoading(this._azureResourceGroupDropdown);
await utils.clearDropDownWithLoading(this._azureResourceDropdown);
}
await utils.updateControlDisplay(this._certMigrationRequiredInfoBox, this.migrationStateModel.tdeMigrationConfig.shouldAdsMigrateCertificates());
await this.populateAzureAccountsDropdown();
await this.populateTenantsDropdown();
await this.populateSubscriptionDropdown();
await this.populateLocationDropdown();
await this.populateResourceGroupDropdown();
await this.populateResourceInstanceDropdown();
}
public async onPageLeave(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise<void> {
@@ -403,7 +412,7 @@ export class TargetSelectionPage extends MigrationWizardPage {
return this._accountTenantFlexContainer;
}
private createTargetDropdownContainer(): azdata.FlexContainer {
private async createTargetDropdownContainer(): Promise<azdata.FlexContainer> {
const subscriptionDropdownLabel = this._view.modelBuilder.text()
.withProps({
value: constants.SUBSCRIPTION,
@@ -474,6 +483,11 @@ export class TargetSelectionPage extends MigrationWizardPage {
this._resourceSelectionContainer = this._createResourceDropdowns();
this._resourceAuthenticationContainer = this._createResourceAuthenticationContainer();
const isSqlDbTarget = this.migrationStateModel._targetType === MigrationTargetType.SQLDB;
await this._targetUserNameInputBox.updateProperties({ required: isSqlDbTarget });
await this._targetPasswordInputBox.updateProperties({ required: isSqlDbTarget });
await utils.updateControlDisplay(this._resourceAuthenticationContainer, isSqlDbTarget);
return this._view.modelBuilder.flexContainer()
.withItems([
subscriptionDropdownLabel,
@@ -700,9 +714,13 @@ export class TargetSelectionPage extends MigrationWizardPage {
await this.populateResourceInstanceDropdown();
}));
const resourceDropDownValue = this.migrationStateModel._targetType === MigrationTargetType.SQLMI
? constants.AZURE_SQL_DATABASE_MANAGED_INSTANCE
: this.migrationStateModel._targetType === MigrationTargetType.SQLDB ? constants.AZURE_SQL_DATABASE : constants.AZURE_SQL_DATABASE_VIRTUAL_MACHINE;
this._azureResourceDropdownLabel = this._view.modelBuilder.text()
.withProps({
value: constants.AZURE_SQL_DATABASE_MANAGED_INSTANCE,
value: resourceDropDownValue,
description: constants.TARGET_RESOURCE_INFO,
width: WIZARD_INPUT_COMPONENT_WIDTH,
requiredIndicator: true,
@@ -710,7 +728,7 @@ export class TargetSelectionPage extends MigrationWizardPage {
}).component();
this._azureResourceDropdown = this._view.modelBuilder.dropDown()
.withProps({
ariaLabel: constants.AZURE_SQL_DATABASE_MANAGED_INSTANCE,
ariaLabel: resourceDropDownValue,
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
required: true,
@@ -910,6 +928,10 @@ export class TargetSelectionPage extends MigrationWizardPage {
this._azureAccountsDropdown,
accountId,
false);
const selectedAccount = this.migrationStateModel._azureAccounts?.find(account => account.displayInfo.displayName === (<azdata.CategoryValue>this._azureAccountsDropdown.value)?.displayName);
this.migrationStateModel._azureAccount = (selectedAccount)
? utils.deepClone(selectedAccount)!
: undefined!;
} finally {
this._azureAccountsDropdown.loading = false;
}
@@ -933,6 +955,10 @@ export class TargetSelectionPage extends MigrationWizardPage {
tenantId,
true);
}
const selectedTenant = this.migrationStateModel._accountTenants?.find(tenant => tenant.displayName === (<azdata.CategoryValue>this._accountTenantDropdown.value)?.displayName);
this.migrationStateModel._azureTenant = selectedTenant
? utils.deepClone(selectedTenant)
: undefined!;
await this._azureAccountsDropdown.validate();
} finally {
this._accountTenantDropdown.loading = false;
@@ -960,6 +986,12 @@ export class TargetSelectionPage extends MigrationWizardPage {
this._azureSubscriptionDropdown,
subscriptionId,
false);
const selectedSubscription = this.migrationStateModel._subscriptions?.find(
subscription => `${subscription.name} - ${subscription.id}` === (<azdata.CategoryValue>this._azureSubscriptionDropdown.value)?.displayName);
this.migrationStateModel._targetSubscription = (selectedSubscription)
? utils.deepClone(selectedSubscription)!
: undefined!;
this.migrationStateModel.refreshDatabaseBackupPage = true;
} catch (e) {
console.log(e);
} finally {
@@ -1009,6 +1041,10 @@ export class TargetSelectionPage extends MigrationWizardPage {
this._azureLocationDropdown,
location,
true);
const selectedLocation = this.migrationStateModel._locations?.find(location => location.displayName === (<azdata.CategoryValue>this._azureLocationDropdown.value)?.displayName);
this.migrationStateModel._location = (selectedLocation)
? utils.deepClone(selectedLocation)!
: undefined!;
} catch (e) {
console.log(e);
} finally {
@@ -1047,6 +1083,11 @@ export class TargetSelectionPage extends MigrationWizardPage {
this._azureResourceGroupDropdown,
resourceGroupId,
false);
const selectedResourceGroup = this.migrationStateModel._resourceGroups?.find(rg => rg.name === (<azdata.CategoryValue>this._azureResourceGroupDropdown.value)?.displayName);
this.migrationStateModel._resourceGroup = (selectedResourceGroup)
? utils.deepClone(selectedResourceGroup)!
: undefined!;
} catch (e) {
console.log(e);
} finally {