mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
@@ -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', []);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user