Dev/brih/task/make dropdowns searchable (#15615)

* make dropdown controls editable, searchable

* updte method name and return type

* update error message, and dropdown index selection logic

* address review feedback
This commit is contained in:
brian-harris
2021-06-07 17:55:08 -07:00
committed by GitHub
parent f7dc9ec2be
commit d8b693341e
8 changed files with 171 additions and 84 deletions

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { CategoryValue, DropDownComponent } from 'azdata';
import { DAYS, HRS, MINUTE, SEC } from '../constants/strings';
import { AdsMigrationStatus } from '../dialog/migrationStatus/migrationStatusDialogModel';
import { MigrationContext } from '../models/migrationLocalStorage';
@@ -120,3 +121,16 @@ export function filterMigrations(databaseMigrations: MigrationContext[], statusF
}
return filteredMigration;
}
export function selectDropDownIndex(dropDown: DropDownComponent, index: number): void {
if (index >= 0 && dropDown.values && index <= dropDown.values.length - 1) {
const value = dropDown.values[index];
dropDown.value = value as CategoryValue;
}
}
export function findDropDownItemIndex(dropDown: DropDownComponent, value: string): number {
return dropDown.values &&
dropDown.values.findIndex((v: any) => ((v as CategoryValue)?.displayName?.toLowerCase() === value?.toLowerCase())) ||
-1;
}

View File

@@ -12,6 +12,7 @@ import * as os from 'os';
import { azureResource } from 'azureResource';
import { IntergrationRuntimePage } from '../../wizard/integrationRuntimePage';
import { IconPathHelper } from '../../constants/iconPathHelper';
import { selectDropDownIndex } from '../../api/utils';
export class CreateSqlMigrationServiceDialog {
@@ -174,7 +175,9 @@ export class CreateSqlMigrationServiceDialog {
}).component();
this.migrationServiceResourceGroupDropdown = this._view.modelBuilder.dropDown().withProps({
required: true
required: true,
editable: true,
fireOnTextChange: true,
}).component();
const migrationServiceNameLabel = this._view.modelBuilder.text().withProps({
@@ -252,7 +255,7 @@ export class CreateSqlMigrationServiceDialog {
private async populateSubscriptions(): Promise<void> {
this.migrationServiceResourceGroupDropdown.loading = true;
this.migrationServiceSubscription.value = this.migrationStateModel._targetSubscription.name;
this.populateResourceGroups();
await this.populateResourceGroups();
}
private async populateResourceGroups(): Promise<void> {
@@ -276,6 +279,7 @@ export class CreateSqlMigrationServiceDialog {
];
}
this.migrationServiceResourceGroupDropdown.values = resourceGroupDropdownValues;
selectDropDownIndex(this.migrationServiceResourceGroupDropdown, 0);
this.migrationServiceResourceGroupDropdown.loading = false;
}

View File

@@ -724,8 +724,9 @@ export class MigrationStateModel implements Model, vscode.Disposable {
vscode.window.showInformationMessage(localize("sql.migration.starting.migration.message", 'Starting migration for database {0} to {1} - {2}', this._migrationDbs[i], this._targetServerInstance.name, this._targetDatabaseNames[i]));
}
} catch (e) {
vscode.window.showErrorMessage(
localize('sql.migration.starting.migration.error', "An error occurred while starting the migration: '{0}'", e.message));
console.log(e);
vscode.window.showInformationMessage(e);
}
vscode.commands.executeCommand('sqlmigration.refreshMigrationTiles');

View File

@@ -9,7 +9,7 @@ import { MigrationWizardPage } from '../models/migrationWizardPage';
import { MigrationStateModel, StateChangeEvent } from '../models/stateMachine';
import * as constants from '../constants/strings';
import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController';
import { deepClone } from '../api/utils';
import { deepClone, findDropDownItemIndex, selectDropDownIndex } from '../api/utils';
export class AccountsSelectionPage extends MigrationWizardPage {
private _azureAccountsDropdown!: azdata.DropDownComponent;
@@ -45,7 +45,9 @@ export class AccountsSelectionPage extends MigrationWizardPage {
this._azureAccountsDropdown = view.modelBuilder.dropDown()
.withProps({
width: WIZARD_INPUT_COMPONENT_WIDTH
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
})
.withValidation((c) => {
if (c.value) {
@@ -71,13 +73,15 @@ export class AccountsSelectionPage extends MigrationWizardPage {
}).component();
this._azureAccountsDropdown.onValueChanged(async (value) => {
if (value.selected) {
const selectedAzureAccount = this.migrationStateModel.getAccount(value.index);
const selectedIndex = findDropDownItemIndex(this._azureAccountsDropdown, value);
if (selectedIndex > -1) {
const selectedAzureAccount = this.migrationStateModel.getAccount(selectedIndex);
// Making a clone of the account object to preserve the original tenants
this.migrationStateModel._azureAccount = deepClone(selectedAzureAccount);
if (this.migrationStateModel._azureAccount.properties.tenants.length > 1) {
this.migrationStateModel._accountTenants = selectedAzureAccount.properties.tenants;
this._accountTenantDropdown.values = await this.migrationStateModel.getTenantValues();
selectDropDownIndex(this._accountTenantDropdown, 0);
this._accountTenantFlexContainer.updateCssStyles({
'display': 'inline'
});
@@ -89,7 +93,7 @@ export class AccountsSelectionPage extends MigrationWizardPage {
this.migrationStateModel._subscriptions = undefined!;
this.migrationStateModel._targetSubscription = undefined!;
this.migrationStateModel._databaseBackup.subscription = undefined!;
this._azureAccountsDropdown.validate();
await this._azureAccountsDropdown.validate();
}
});
@@ -140,7 +144,9 @@ export class AccountsSelectionPage extends MigrationWizardPage {
}).component();
this._accountTenantDropdown = view.modelBuilder.dropDown().withProps({
width: WIZARD_INPUT_COMPONENT_WIDTH
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
}).component();
this._accountTenantDropdown.onValueChanged(value => {
@@ -148,8 +154,9 @@ export class AccountsSelectionPage extends MigrationWizardPage {
* Replacing all the tenants in azure account with the tenant user has selected.
* All azure requests will only run on this tenant from now on
*/
if (value.selected) {
this.migrationStateModel._azureAccount.properties.tenants = [this.migrationStateModel.getTenant(value.index)];
const selectedIndex = findDropDownItemIndex(this._accountTenantDropdown, value);
if (selectedIndex > -1) {
this.migrationStateModel._azureAccount.properties.tenants = [this.migrationStateModel.getTenant(selectedIndex)];
this.migrationStateModel._subscriptions = undefined!;
this.migrationStateModel._targetSubscription = undefined!;
this.migrationStateModel._databaseBackup.subscription = undefined!;
@@ -184,6 +191,8 @@ export class AccountsSelectionPage extends MigrationWizardPage {
} finally {
this._azureAccountsDropdown.loading = false;
}
selectDropDownIndex(this._azureAccountsDropdown, 0);
}
public async onPageEnter(): Promise<void> {

View File

@@ -11,6 +11,8 @@ import { Blob, MigrationSourceAuthenticationType, MigrationStateModel, Migration
import * as constants from '../constants/strings';
import { IconPathHelper } from '../constants/iconPathHelper';
import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController';
import { findDropDownItemIndex, selectDropDownIndex } from '../api/utils';
export class DatabaseBackupPage extends MigrationWizardPage {
private _view!: azdata.ModelView;
@@ -392,6 +394,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
private createTargetDatabaseContainer(): azdata.FlexContainer {
const WIZARD_INPUT_COMPONENT_WIDTH = '200px';
const headerCssStyles: azdata.CssStyles = {
'border': 'none',
'font-size': '13px',
@@ -433,7 +436,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles,
isReadOnly: true,
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH
},
{
displayName: constants.TARGET_DATABASE_NAME,
@@ -441,7 +444,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles,
isReadOnly: true,
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH
},
{
displayName: constants.RESOURCE_GROUP,
@@ -449,7 +452,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles,
isReadOnly: true,
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH
},
{
displayName: constants.STORAGE_ACCOUNT,
@@ -457,7 +460,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles,
isReadOnly: true,
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH
},
{
displayName: constants.BLOB_CONTAINER,
@@ -465,7 +468,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles,
isReadOnly: true,
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH
}
]
}).component();
@@ -551,12 +554,15 @@ export class DatabaseBackupPage extends MigrationWizardPage {
}
}).component();
this._networkShareStorageAccountResourceGroupDropdown = this._view.modelBuilder.dropDown().withProps({
width: WIZARD_INPUT_COMPONENT_WIDTH
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
}).component();
this._networkShareStorageAccountResourceGroupDropdown.onValueChanged(e => {
if (e.selected) {
this.migrationStateModel._databaseBackup.networkShare.resourceGroup = this.migrationStateModel.getAzureResourceGroup(e.index);
this.loadNetworkShareStorageDropdown();
this._networkShareStorageAccountResourceGroupDropdown.onValueChanged(async (value) => {
const selectedIndex = findDropDownItemIndex(this._networkShareStorageAccountResourceGroupDropdown, value);
if (selectedIndex > -1) {
this.migrationStateModel._databaseBackup.networkShare.resourceGroup = this.migrationStateModel.getAzureResourceGroup(selectedIndex);
await this.loadNetworkShareStorageDropdown();
}
});
@@ -572,11 +578,14 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._networkShareContainerStorageAccountDropdown = this._view.modelBuilder.dropDown()
.withProps({
required: true,
width: WIZARD_INPUT_COMPONENT_WIDTH
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
}).component();
this._networkShareContainerStorageAccountDropdown.onValueChanged((value) => {
if (value.selected) {
this.migrationStateModel._databaseBackup.networkShare.storageAccount = this.migrationStateModel.getStorageAccount(value.index);
const selectedIndex = findDropDownItemIndex(this._networkShareContainerStorageAccountDropdown, value);
if (selectedIndex > -1) {
this.migrationStateModel._databaseBackup.networkShare.storageAccount = this.migrationStateModel.getStorageAccount(selectedIndex);
}
});
@@ -587,8 +596,8 @@ export class DatabaseBackupPage extends MigrationWizardPage {
height: 25
}).component();
this._networkShareContainerStorageAccountRefreshButton.onDidClick((e) => {
this.loadNetworkShareStorageDropdown();
this._networkShareContainerStorageAccountRefreshButton.onDidClick(async (value) => {
await this.loadNetworkShareStorageDropdown();
});
const storageAccountContainer = this._view.modelBuilder.flexContainer().component();
@@ -628,6 +637,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
public async onPageEnter(): Promise<void> {
if (this.migrationStateModel.refreshDatabaseBackupPage) {
const WIZARD_INPUT_COMPONENT_WIDTH = '200px';
const connectionProfile = await this.migrationStateModel.getSourceConnectionProfile();
const queryProvider = azdata.dataprotocol.getProvider<azdata.QueryProvider>((await this.migrationStateModel.getSourceConnectionProfile()).providerId, azdata.DataProviderType.QueryProvider);
const query = 'select SUSER_NAME()';
@@ -656,7 +666,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
const targetDatabaseInput = this._view.modelBuilder.inputBox().withProps({
required: true,
value: db,
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH
}).withValidation(c => {
if (this._networkShareTargetDatabaseNames.filter(t => t.value === c.value).length > 1) { //Making sure no databases have duplicate values.
c.validationErrorMessage = constants.DUPLICATE_NAME_ERROR;
@@ -680,7 +690,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
const blobtargetDatabaseInput = this._view.modelBuilder.inputBox().withProps({
required: true,
value: db,
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH
}).withValidation(c => {
if (this._blobContainerTargetDatabaseNames.filter(t => t.value === c.value).length > 1) { //Making sure no databases have duplicate values.
c.validationErrorMessage = constants.DUPLICATE_NAME_ERROR;
@@ -702,24 +712,31 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._blobContainerTargetDatabaseNames.push(blobtargetDatabaseInput);
const blobContainerResourceDropdown = this._view.modelBuilder.dropDown().withProps({
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
}).component();
blobContainerResourceDropdown.onValueChanged(e => {
if (e.selected && e.selected !== constants.RESOURCE_GROUP_NOT_FOUND) {
this.migrationStateModel._databaseBackup.blobs[index].resourceGroup = this.migrationStateModel.getAzureResourceGroup(e.index);
blobContainerResourceDropdown.onValueChanged(async (value) => {
const selectedIndex = findDropDownItemIndex(blobContainerResourceDropdown, value);
if (selectedIndex > -1 && value !== constants.RESOURCE_GROUP_NOT_FOUND) {
this.migrationStateModel._databaseBackup.blobs[index].resourceGroup = this.migrationStateModel.getAzureResourceGroup(selectedIndex);
}
this.loadblobStorageDropdown(index);
await this.loadblobStorageDropdown(index);
});
this._blobContainerResourceGroupDropdowns.push(blobContainerResourceDropdown);
const blobContainerStorageAccountDropdown = this._view.modelBuilder.dropDown()
.withProps({
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
}).component();
blobContainerStorageAccountDropdown.onValueChanged(async (value) => {
if (value.selected && value.selected !== constants.NO_STORAGE_ACCOUNT_FOUND) {
this.migrationStateModel._databaseBackup.blobs[index].storageAccount = this.migrationStateModel.getStorageAccount(value.index);
const selectedIndex = findDropDownItemIndex(blobContainerStorageAccountDropdown, value);
if (selectedIndex > -1 && value !== constants.NO_STORAGE_ACCOUNT_FOUND) {
this.migrationStateModel._databaseBackup.blobs[index].storageAccount = this.migrationStateModel.getStorageAccount(selectedIndex);
}
await this.loadBlobContainerDropdown(index);
});
@@ -727,11 +744,14 @@ export class DatabaseBackupPage extends MigrationWizardPage {
const blobContainerDropdown = this._view.modelBuilder.dropDown()
.withProps({
width: '200px'
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
}).component();
blobContainerDropdown.onValueChanged(async (value) => {
if (value.selected && value.selected !== constants.NO_BLOBCONTAINERS_FOUND) {
this.migrationStateModel._databaseBackup.blobs[index].blobContainer = this.migrationStateModel.getBlobContainer(value.index);
blobContainerDropdown.onValueChanged(value => {
const selectedIndex = findDropDownItemIndex(blobContainerStorageAccountDropdown, value);
if (selectedIndex > -1 && value !== constants.NO_BLOBCONTAINERS_FOUND) {
this.migrationStateModel._databaseBackup.blobs[index].blobContainer = this.migrationStateModel.getBlobContainer(selectedIndex);
}
});
this._blobContainerDropdowns.push(blobContainerDropdown);
@@ -953,11 +973,12 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._networkShareStorageAccountResourceGroupDropdown.loading = true;
try {
this._networkShareStorageAccountResourceGroupDropdown.values = await this.migrationStateModel.getAzureResourceGroupDropdownValues(this.migrationStateModel._databaseBackup.subscription);
selectDropDownIndex(this._networkShareStorageAccountResourceGroupDropdown, 0);
} catch (error) {
console.log(error);
} finally {
this._networkShareStorageAccountResourceGroupDropdown.loading = false;
this.loadNetworkShareStorageDropdown();
await this.loadNetworkShareStorageDropdown();
}
}
@@ -965,6 +986,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._networkShareContainerStorageAccountDropdown.loading = true;
try {
this._networkShareContainerStorageAccountDropdown.values = await this.migrationStateModel.getStorageAccountValues(this.migrationStateModel._databaseBackup.subscription, this.migrationStateModel._databaseBackup.networkShare.resourceGroup);
selectDropDownIndex(this._networkShareContainerStorageAccountDropdown, 0);
} catch (error) {
console.log(error);
} finally {
@@ -976,7 +998,10 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._blobContainerResourceGroupDropdowns.forEach(v => v.loading = true);
try {
const resourceGroupValues = await this.migrationStateModel.getAzureResourceGroupDropdownValues(this.migrationStateModel._databaseBackup.subscription);
this._blobContainerResourceGroupDropdowns.forEach(v => v.values = resourceGroupValues);
this._blobContainerResourceGroupDropdowns.forEach(dropDown => {
dropDown.values = resourceGroupValues;
selectDropDownIndex(dropDown, 0);
});
} catch (error) {
console.log(error);
} finally {
@@ -988,6 +1013,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
this._blobContainerStorageAccountDropdowns[index].loading = true;
try {
this._blobContainerStorageAccountDropdowns[index].values = await this.migrationStateModel.getStorageAccountValues(this.migrationStateModel._databaseBackup.subscription, this.migrationStateModel._databaseBackup.blobs[index].resourceGroup);
selectDropDownIndex(this._blobContainerStorageAccountDropdowns[index], 0);
} catch (error) {
console.log(error);
} finally {
@@ -1000,6 +1026,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
try {
const blobContainerValues = await this.migrationStateModel.getBlobContainerValues(this.migrationStateModel._databaseBackup.subscription, this.migrationStateModel._databaseBackup.blobs[index].storageAccount);
this._blobContainerDropdowns[index].values = blobContainerValues;
selectDropDownIndex(this._blobContainerDropdowns[index], 0);
} catch (error) {
console.log(error);
} finally {

View File

@@ -12,6 +12,7 @@ import * as constants from '../constants/strings';
import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController';
import { getLocationDisplayName, getSqlMigrationService, getSqlMigrationServiceAuthKeys, getSqlMigrationServiceMonitoringData, SqlManagedInstance, SqlMigrationService } from '../api/azure';
import { IconPathHelper } from '../constants/iconPathHelper';
import { findDropDownItemIndex } from '../api/utils';
export class IntergrationRuntimePage extends MigrationWizardPage {
@@ -174,12 +175,14 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
}).component();
this._resourceGroupDropdown = this._view.modelBuilder.dropDown().withProps({
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true
editable: true,
fireOnTextChange: true,
}).component();
this._resourceGroupDropdown.onValueChanged(async (value) => {
if (value) {
this.populateDms(value);
const selectedIndex = findDropDownItemIndex(this._resourceGroupDropdown, value);
if (selectedIndex > -1) {
await this.populateDms(value);
}
});
@@ -193,7 +196,8 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
this._dmsDropdown = this._view.modelBuilder.dropDown().withProps({
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true
editable: true,
fireOnTextChange: true,
}).component();
this._dmsDropdown.onValueChanged(async (value) => {
@@ -201,9 +205,11 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
this.wizard.message = {
text: ''
};
const selectedIndex = (<azdata.CategoryValue[]>this._dmsDropdown.values)?.findIndex((v) => v.displayName === value);
this.migrationStateModel._sqlMigrationService = this.migrationStateModel.getMigrationService(selectedIndex);
this.loadMigrationServiceStatus();
const selectedIndex = findDropDownItemIndex(this._dmsDropdown, value);
if (selectedIndex > -1) {
this.migrationStateModel._sqlMigrationService = this.migrationStateModel.getMigrationService(selectedIndex);
await this.loadMigrationServiceStatus();
}
}
});
@@ -395,10 +401,11 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
let index = 0;
if (resourceGroupName) {
index = (<azdata.CategoryValue[]>this._resourceGroupDropdown.values).findIndex(v => v.displayName.toLowerCase() === resourceGroupName.toLowerCase());
index = findDropDownItemIndex(this._resourceGroupDropdown, resourceGroupName);
}
if ((<azdata.CategoryValue>this._resourceGroupDropdown.value)?.displayName.toLowerCase() === (<azdata.CategoryValue>this._resourceGroupDropdown.values[index])?.displayName.toLowerCase()) {
this.populateDms((<azdata.CategoryValue>this._resourceGroupDropdown.value)?.displayName);
await this.populateDms((<azdata.CategoryValue>this._resourceGroupDropdown.value)?.displayName);
} else {
this._resourceGroupDropdown.value = this._resourceGroupDropdown.values[index];
}
@@ -407,7 +414,6 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
} finally {
this._resourceGroupDropdown.loading = false;
}
}
public async populateDms(resourceGroupName: string): Promise<void> {
@@ -419,9 +425,9 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
this._dmsDropdown.values = await this.migrationStateModel.getSqlMigrationServiceValues(this.migrationStateModel._targetSubscription, <SqlManagedInstance>this.migrationStateModel._targetServerInstance, resourceGroupName);
let index = -1;
if (this.migrationStateModel._sqlMigrationService) {
index = (<azdata.CategoryValue[]>this._dmsDropdown.values).findIndex(v => v.displayName.toLowerCase() === this.migrationStateModel._sqlMigrationService.name.toLowerCase());
index = findDropDownItemIndex(this._dmsDropdown, this.migrationStateModel._sqlMigrationService.name);
}
if (index !== -1) {
if (index > -1) {
this._dmsDropdown.value = this._dmsDropdown.values[index];
} else {
this._dmsDropdown.value = this._dmsDropdown.values[0];

View File

@@ -12,6 +12,7 @@ import * as vscode from 'vscode';
import { EOL } from 'os';
import { IconPath, IconPathHelper } from '../constants/iconPathHelper';
import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController';
import { findDropDownItemIndex, selectDropDownIndex } from '../api/utils';
export interface Product {
type: MigrationTargetType;
@@ -291,15 +292,16 @@ export class SKURecommendationPage extends MigrationWizardPage {
}).component();
this._managedInstanceSubscriptionDropdown = this._view.modelBuilder.dropDown().withProps({
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true
editable: true,
fireOnTextChange: true,
}).component();
this._managedInstanceSubscriptionDropdown.onValueChanged((e) => {
if (e) {
const selectedIndex = (<azdata.CategoryValue[]>this._managedInstanceSubscriptionDropdown.values)?.findIndex(v => v.displayName === e);
this._managedInstanceSubscriptionDropdown.onValueChanged(async (value) => {
const selectedIndex = findDropDownItemIndex(this._managedInstanceSubscriptionDropdown, value);
if (selectedIndex > -1) {
this.migrationStateModel._targetSubscription = this.migrationStateModel.getSubscription(selectedIndex);
this.migrationStateModel._targetServerInstance = undefined!;
this.migrationStateModel._sqlMigrationService = undefined!;
this.populateLocationAndResourceGroupDropdown();
await this.populateLocationAndResourceGroupDropdown();
}
});
@@ -312,12 +314,15 @@ export class SKURecommendationPage extends MigrationWizardPage {
}
}).component();
this._azureLocationDropdown = this._view.modelBuilder.dropDown().withProps({
width: WIZARD_INPUT_COMPONENT_WIDTH
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
}).component();
this._azureLocationDropdown.onValueChanged((e) => {
if (e.selected) {
this.migrationStateModel._location = this.migrationStateModel.getLocation(e.index);
this.populateResourceInstanceDropdown();
this._azureLocationDropdown.onValueChanged(async (value) => {
const selectedIndex = findDropDownItemIndex(this._azureLocationDropdown, value);
if (selectedIndex > -1) {
this.migrationStateModel._location = this.migrationStateModel.getLocation(selectedIndex);
await this.populateResourceInstanceDropdown();
}
});
@@ -330,12 +335,15 @@ export class SKURecommendationPage extends MigrationWizardPage {
}
}).component();
this._azureResourceGroupDropdown = this._view.modelBuilder.dropDown().withProps({
width: WIZARD_INPUT_COMPONENT_WIDTH
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
}).component();
this._azureResourceGroupDropdown.onValueChanged((e) => {
if (e.selected) {
this.migrationStateModel._resourceGroup = this.migrationStateModel.getAzureResourceGroup(e.index);
this.populateResourceInstanceDropdown();
this._azureResourceGroupDropdown.onValueChanged(async (value) => {
const selectedIndex = findDropDownItemIndex(this._azureResourceGroupDropdown, value);
if (selectedIndex > -1) {
this.migrationStateModel._resourceGroup = this.migrationStateModel.getAzureResourceGroup(selectedIndex);
await this.populateResourceInstanceDropdown();
}
});
this._resourceDropdownLabel = this._view.modelBuilder.text().withProps({
@@ -348,17 +356,20 @@ export class SKURecommendationPage extends MigrationWizardPage {
}).component();
this._resourceDropdown = this._view.modelBuilder.dropDown().withProps({
width: WIZARD_INPUT_COMPONENT_WIDTH
width: WIZARD_INPUT_COMPONENT_WIDTH,
editable: true,
fireOnTextChange: true,
}).component();
this._resourceDropdown.onValueChanged((e) => {
if (e?.selected &&
e.selected !== constants.NO_MANAGED_INSTANCE_FOUND &&
e.selected !== constants.NO_VIRTUAL_MACHINE_FOUND) {
this._resourceDropdown.onValueChanged(value => {
const selectedIndex = findDropDownItemIndex(this._resourceDropdown, value);
if (selectedIndex > -1 &&
value !== constants.NO_MANAGED_INSTANCE_FOUND &&
value !== constants.NO_VIRTUAL_MACHINE_FOUND) {
this.migrationStateModel._sqlMigrationServices = undefined!;
if (this._rbg.selectedCardId === MigrationTargetType.SQLVM) {
this.migrationStateModel._targetServerInstance = this.migrationStateModel.getVirtualMachine(e.index);
this.migrationStateModel._targetServerInstance = this.migrationStateModel.getVirtualMachine(selectedIndex);
} else {
this.migrationStateModel._targetServerInstance = this.migrationStateModel.getManagedInstance(e.index);
this.migrationStateModel._targetServerInstance = this.migrationStateModel.getManagedInstance(selectedIndex);
}
}
});
@@ -425,11 +436,12 @@ export class SKURecommendationPage extends MigrationWizardPage {
this._resourceDropdown.loading = true;
try {
this._managedInstanceSubscriptionDropdown.values = await this.migrationStateModel.getSubscriptionsDropdownValues();
this._managedInstanceSubscriptionDropdown.value = this._managedInstanceSubscriptionDropdown.values[0];
selectDropDownIndex(this._managedInstanceSubscriptionDropdown, 0);
} catch (e) {
console.log(e);
} finally {
this._managedInstanceSubscriptionDropdown.loading = false;
this._resourceDropdown.loading = false;
}
}
}
@@ -439,7 +451,9 @@ export class SKURecommendationPage extends MigrationWizardPage {
this._azureLocationDropdown.loading = true;
try {
this._azureResourceGroupDropdown.values = await this.migrationStateModel.getAzureResourceGroupDropdownValues(this.migrationStateModel._targetSubscription);
selectDropDownIndex(this._azureResourceGroupDropdown, 0);
this._azureLocationDropdown.values = await this.migrationStateModel.getAzureLocationDropdownValues(this.migrationStateModel._targetSubscription);
selectDropDownIndex(this._azureLocationDropdown, 0);
} catch (e) {
console.log(e);
} finally {
@@ -449,8 +463,8 @@ export class SKURecommendationPage extends MigrationWizardPage {
}
private async populateResourceInstanceDropdown(): Promise<void> {
this._resourceDropdown.loading = true;
try {
this._resourceDropdown.loading = true;
if (this._rbg.selectedCardId === MigrationTargetType.SQLVM) {
this._resourceDropdownLabel.value = constants.AZURE_SQL_DATABASE_VIRTUAL_MACHINE;
this._resourceDropdown.values = await this.migrationStateModel.getSqlVirtualMachineValues(this.migrationStateModel._targetSubscription, this.migrationStateModel._location, this.migrationStateModel._resourceGroup);
@@ -459,6 +473,8 @@ export class SKURecommendationPage extends MigrationWizardPage {
this._resourceDropdownLabel.value = constants.AZURE_SQL_DATABASE_MANAGED_INSTANCE;
this._resourceDropdown.values = await this.migrationStateModel.getManagedInstanceValues(this.migrationStateModel._targetSubscription, this.migrationStateModel._location, this.migrationStateModel._resourceGroup);
}
selectDropDownIndex(this._resourceDropdown, 0);
} catch (e) {
console.log(e);
} finally {

View File

@@ -9,6 +9,7 @@ import { MigrationStateModel, StateChangeEvent } from '../models/stateMachine';
import { SUBSCRIPTION_SELECTION_PAGE_TITLE, SUBSCRIPTION_SELECTION_AZURE_ACCOUNT_TITLE, SUBSCRIPTION_SELECTION_AZURE_PRODUCT_TITLE, SUBSCRIPTION_SELECTION_AZURE_SUBSCRIPTION_TITLE } from '../constants/strings';
import { Disposable } from 'vscode';
import { getSubscriptions, Subscription, getAvailableManagedInstanceProducts, AzureProduct, getAvailableSqlServers } from '../api/azure';
import { selectDropDownIndex } from '../api/utils';
interface GenericValue<T> extends azdata.CategoryValue {
value: T;
@@ -37,7 +38,7 @@ export class SubscriptionSelectionPage extends MigrationWizardPage {
private async initialState(view: azdata.ModelView) {
this.accountDropDown = this.createAccountDropDown(view);
this.subscriptionDropDown = this.createSubscriptionDropDown(view);
this.productDropDown = this.createProdcutDropDown(view);
this.productDropDown = this.createProductDropDown(view);
const form = view.modelBuilder.formContainer().withFormItems(
[
@@ -53,10 +54,12 @@ export class SubscriptionSelectionPage extends MigrationWizardPage {
private createAccountDropDown(view: azdata.ModelView): azdata.FormComponent<azdata.DropDownComponent> {
const dropDown = view.modelBuilder.dropDown().withProperties<azdata.DropDownProperties>({
values: [],
editable: true,
fireOnTextChange: true,
});
this.disposables.push(dropDown.component().onValueChanged(() => {
this.accountValueChanged().catch(console.error);
this.disposables.push(dropDown.component().onValueChanged(async () => {
await this.accountValueChanged().catch(console.error);
}));
return {
@@ -68,10 +71,12 @@ export class SubscriptionSelectionPage extends MigrationWizardPage {
private createSubscriptionDropDown(view: azdata.ModelView): azdata.FormComponent<azdata.DropDownComponent> {
const dropDown = view.modelBuilder.dropDown().withProperties<azdata.DropDownProperties>({
values: [],
editable: true,
fireOnTextChange: true,
});
this.disposables.push(dropDown.component().onValueChanged(() => {
this.subscriptionValueChanged().catch(console.error);
this.disposables.push(dropDown.component().onValueChanged(async () => {
await this.subscriptionValueChanged().catch(console.error);
}));
return {
@@ -80,9 +85,11 @@ export class SubscriptionSelectionPage extends MigrationWizardPage {
};
}
private createProdcutDropDown(view: azdata.ModelView): azdata.FormComponent<azdata.DropDownComponent> {
private createProductDropDown(view: azdata.ModelView): azdata.FormComponent<azdata.DropDownComponent> {
const dropDown = view.modelBuilder.dropDown().withProperties<azdata.DropDownProperties>({
values: [],
editable: true,
fireOnTextChange: true,
});
return {
@@ -132,6 +139,7 @@ export class SubscriptionSelectionPage extends MigrationWizardPage {
});
this.accountDropDown!.component.values = values;
selectDropDownIndex(this.accountDropDown!.component, 0);
await this.accountValueChanged();
}
@@ -145,6 +153,7 @@ export class SubscriptionSelectionPage extends MigrationWizardPage {
});
this.subscriptionDropDown!.component.values = values;
selectDropDownIndex(this.subscriptionDropDown!.component, 0);
await this.subscriptionValueChanged();
}
@@ -158,6 +167,7 @@ export class SubscriptionSelectionPage extends MigrationWizardPage {
});
this.productDropDown!.component.values = values;
selectDropDownIndex(this.productDropDown!.component, 0);
}
public async onPageEnter(): Promise<void> {