mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Target Page Changes (#14421)
* target page changes * remove SourceConfigurationPage * fix build errors * fixed build errors * passing selected Dbs on to migration state model * code cleanup * fix build errors
This commit is contained in:
@@ -6,10 +6,15 @@
|
|||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { MigrationStateModel } from '../../models/stateMachine';
|
import { MigrationStateModel } from '../../models/stateMachine';
|
||||||
import { SqlDatabaseTree } from './sqlDatabasesTree';
|
import { SqlDatabaseTree } from './sqlDatabasesTree';
|
||||||
import { SqlAssessmentResultList } from './sqlAssessmentResultsList';
|
import { SqlMigrationImpactedObjectInfo } from '../../../../mssql/src/mssql';
|
||||||
import { SqlAssessmentResult } from './sqlAssessmentResult';
|
|
||||||
|
|
||||||
|
|
||||||
|
export type Issues = {
|
||||||
|
description: string,
|
||||||
|
recommendation: string,
|
||||||
|
moreInfo: string,
|
||||||
|
impactedObjects: SqlMigrationImpactedObjectInfo[],
|
||||||
|
rowNumber: number
|
||||||
|
};
|
||||||
export class AssessmentResultsDialog {
|
export class AssessmentResultsDialog {
|
||||||
|
|
||||||
private static readonly OkButtonText: string = 'OK';
|
private static readonly OkButtonText: string = 'OK';
|
||||||
@@ -17,33 +22,40 @@ export class AssessmentResultsDialog {
|
|||||||
|
|
||||||
private _isOpen: boolean = false;
|
private _isOpen: boolean = false;
|
||||||
private dialog: azdata.window.Dialog | undefined;
|
private dialog: azdata.window.Dialog | undefined;
|
||||||
|
private _model: MigrationStateModel;
|
||||||
|
|
||||||
// Dialog Name for Telemetry
|
// Dialog Name for Telemetry
|
||||||
public dialogName: string | undefined;
|
public dialogName: string | undefined;
|
||||||
|
|
||||||
private _tree: SqlDatabaseTree;
|
private _tree: SqlDatabaseTree;
|
||||||
private _list: SqlAssessmentResultList;
|
|
||||||
private _result: SqlAssessmentResult;
|
|
||||||
|
|
||||||
constructor(public ownerUri: string, public model: MigrationStateModel, public title: string) {
|
constructor(public ownerUri: string, public model: MigrationStateModel, public title: string) {
|
||||||
this._tree = new SqlDatabaseTree();
|
this._model = model;
|
||||||
this._list = new SqlAssessmentResultList();
|
let assessmentData = this.parseData(this._model);
|
||||||
this._result = new SqlAssessmentResult();
|
this._tree = new SqlDatabaseTree(assessmentData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async initializeDialog(dialog: azdata.window.Dialog): Promise<void> {
|
private async initializeDialog(dialog: azdata.window.Dialog): Promise<void> {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
dialog.registerContent(async (view) => {
|
dialog.registerContent(async (view) => {
|
||||||
try {
|
try {
|
||||||
|
// const resultComponent = await this._tree.createComponentResult(view);
|
||||||
const treeComponent = await this._tree.createComponent(view);
|
const treeComponent = await this._tree.createComponent(view);
|
||||||
const separator1 = view.modelBuilder.separator().component();
|
|
||||||
const listComponent = await this._list.createComponent(view);
|
|
||||||
const separator2 = view.modelBuilder.separator().component();
|
|
||||||
const resultComponent = await this._result.createComponent(view);
|
|
||||||
|
|
||||||
const flex = view.modelBuilder.flexContainer().withItems([treeComponent, separator1, listComponent, separator2, resultComponent]);
|
const flex = view.modelBuilder.flexContainer().withLayout({
|
||||||
|
flexFlow: 'row',
|
||||||
|
height: '100%',
|
||||||
|
width: '100%'
|
||||||
|
}).withProps({
|
||||||
|
CSSStyles: {
|
||||||
|
'margin-top': '10px'
|
||||||
|
}
|
||||||
|
}).component();
|
||||||
|
flex.addItem(treeComponent, { flex: '0 0 auto' });
|
||||||
|
// flex.addItem(resultComponent, { flex: '1 1 auto' });
|
||||||
|
|
||||||
view.initializeModel(flex.component());
|
view.initializeModel(flex);
|
||||||
resolve();
|
resolve();
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
reject(ex);
|
reject(ex);
|
||||||
@@ -72,7 +84,48 @@ export class AssessmentResultsDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private parseData(model: MigrationStateModel): Map<string, Issues[]> {
|
||||||
|
// if there are multiple issues for the same DB, need to consolidate
|
||||||
|
// map DB name -> Assessment result items (issues)
|
||||||
|
// map assessment result items to description, recommendation, more info & impacted objects
|
||||||
|
|
||||||
|
let dbMap = new Map<string, Issues[]>();
|
||||||
|
|
||||||
|
model.assessmentResults?.forEach((element) => {
|
||||||
|
let issues: Issues;
|
||||||
|
issues = {
|
||||||
|
description: element.description,
|
||||||
|
recommendation: element.message,
|
||||||
|
moreInfo: element.helpLink,
|
||||||
|
impactedObjects: element.impactedObjects,
|
||||||
|
rowNumber: 0
|
||||||
|
};
|
||||||
|
if (element.targetName.includes(':')) {
|
||||||
|
let spliceIndex = element.targetName.indexOf(':');
|
||||||
|
let dbName = element.targetName.slice(spliceIndex + 1);
|
||||||
|
let dbIssues = dbMap.get(element.targetName);
|
||||||
|
if (dbIssues) {
|
||||||
|
dbMap.set(dbName, dbIssues.concat([issues]));
|
||||||
|
} else {
|
||||||
|
dbMap.set(dbName, [issues]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let dbIssues = dbMap.get(element.targetName);
|
||||||
|
if (dbIssues) {
|
||||||
|
dbMap.set(element.targetName, dbIssues.concat([issues]));
|
||||||
|
} else {
|
||||||
|
dbMap.set(element.targetName, [issues]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return dbMap;
|
||||||
|
}
|
||||||
|
|
||||||
protected async execute() {
|
protected async execute() {
|
||||||
|
// this.model._migrationDbs = this._tree.selectedDbs();
|
||||||
this._isOpen = false;
|
this._isOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,17 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import { AssessmentDialogComponent } from './model/assessmentDialogComponent';
|
import { AssessmentDialogComponent } from './model/assessmentDialogComponent';
|
||||||
|
import { Issues } from './assessmentResultsDialog';
|
||||||
|
|
||||||
export class SqlDatabaseTree extends AssessmentDialogComponent {
|
export class SqlDatabaseTree extends AssessmentDialogComponent {
|
||||||
|
|
||||||
|
// private _assessmentData: Map<string, Issues[]>;
|
||||||
|
|
||||||
|
constructor(assessmentData: Map<string, Issues[]>) {
|
||||||
|
super();
|
||||||
|
// this._assessmentData = assessmentData;
|
||||||
|
}
|
||||||
|
|
||||||
async createComponent(view: azdata.ModelView): Promise<azdata.Component> {
|
async createComponent(view: azdata.ModelView): Promise<azdata.Component> {
|
||||||
|
|
||||||
return view.modelBuilder.divContainer().withItems([
|
return view.modelBuilder.divContainer().withItems([
|
||||||
@@ -89,4 +98,5 @@ export class SqlDatabaseTree extends AssessmentDialogComponent {
|
|||||||
|
|
||||||
return table.component();
|
return table.component();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
export type MigrationProductType = 'AzureSQLMI' | 'AzureSQLVM' | 'AzureSQL';
|
export type MigrationProductType = 'AzureSQLMI' | 'AzureSQLVM';
|
||||||
export interface MigrationProduct {
|
export interface MigrationProduct {
|
||||||
readonly type: MigrationProductType;
|
readonly type: MigrationProductType;
|
||||||
}
|
}
|
||||||
@@ -53,9 +53,5 @@ export const ProductLookupTable: { [key in MigrationProductType]: Product } = {
|
|||||||
'AzureSQLVM': {
|
'AzureSQLVM': {
|
||||||
type: 'AzureSQLVM',
|
type: 'AzureSQLVM',
|
||||||
name: localize('sql.migration.products.azuresqlvm.name', 'Azure SQL Virtual Machine (Customer managed)'),
|
name: localize('sql.migration.products.azuresqlvm.name', 'Azure SQL Virtual Machine (Customer managed)'),
|
||||||
},
|
|
||||||
'AzureSQL': {
|
|
||||||
type: 'AzureSQL',
|
|
||||||
name: localize('sql.migration.products.azuresql.name', 'Azure SQL'),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
|
|||||||
public _targetManagedInstance!: SqlManagedInstance;
|
public _targetManagedInstance!: SqlManagedInstance;
|
||||||
|
|
||||||
public _databaseBackup!: DatabaseBackupModel;
|
public _databaseBackup!: DatabaseBackupModel;
|
||||||
|
public _migrationDbs!: string[];
|
||||||
public _storageAccounts!: StorageAccount[];
|
public _storageAccounts!: StorageAccount[];
|
||||||
public _fileShares!: azureResource.FileShare[];
|
public _fileShares!: azureResource.FileShare[];
|
||||||
public _blobContainers!: azureResource.BlobContainer[];
|
public _blobContainers!: azureResource.BlobContainer[];
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const SKU_RECOMMENDATION_ALL_SUCCESSFUL = (databaseCount: number): string
|
|||||||
export const SKU_RECOMMENDATION_SOME_SUCCESSFUL = (migratableCount: number, databaseCount: number): string => {
|
export const SKU_RECOMMENDATION_SOME_SUCCESSFUL = (migratableCount: number, databaseCount: number): string => {
|
||||||
return localize('sql.migration.wizard.sku.some', "Based on the results of our source configuration scans, {0} out of {1} of your databases can be migrated to Azure SQL.", migratableCount, databaseCount);
|
return localize('sql.migration.wizard.sku.some', "Based on the results of our source configuration scans, {0} out of {1} of your databases can be migrated to Azure SQL.", migratableCount, databaseCount);
|
||||||
};
|
};
|
||||||
export const SKU_RECOMMENDATION_CHOOSE_A_TARGET = localize('sql.migration.wizard.sku.choose_a_target', "Choose a target");
|
export const SKU_RECOMMENDATION_CHOOSE_A_TARGET = localize('sql.migration.wizard.sku.choose_a_target', "Choose a target Azure SQL");
|
||||||
|
|
||||||
export const SKU_RECOMMENDATION_NONE_SUCCESSFUL = localize('sql.migration.sku.none', "Based on the results of our source configuration scans, none of your databases can be migrated to Azure SQL.");
|
export const SKU_RECOMMENDATION_NONE_SUCCESSFUL = localize('sql.migration.sku.none', "Based on the results of our source configuration scans, none of your databases can be migrated to Azure SQL.");
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ export const SUBSCRIPTION_SELECTION_AZURE_ACCOUNT_TITLE = localize('sql.migratio
|
|||||||
export const SUBSCRIPTION_SELECTION_AZURE_SUBSCRIPTION_TITLE = localize('sql.migration.wizard.subscription.azure.subscription.title', "Azure Subscription");
|
export const SUBSCRIPTION_SELECTION_AZURE_SUBSCRIPTION_TITLE = localize('sql.migration.wizard.subscription.azure.subscription.title', "Azure Subscription");
|
||||||
export const SUBSCRIPTION_SELECTION_AZURE_PRODUCT_TITLE = localize('sql.migration.wizard.subscription.azure.product.title', "Azure Product");
|
export const SUBSCRIPTION_SELECTION_AZURE_PRODUCT_TITLE = localize('sql.migration.wizard.subscription.azure.product.title', "Azure Product");
|
||||||
|
|
||||||
export const CONGRATULATIONS = localize('sql.migration.generic.congratulations', "Congratulations");
|
export const CONGRATULATIONS = localize('sql.migration.generic.congratulations', "Congratulations!");
|
||||||
|
|
||||||
|
|
||||||
// Accounts page
|
// Accounts page
|
||||||
|
|||||||
@@ -8,62 +8,92 @@ import * as path from 'path';
|
|||||||
import { MigrationWizardPage } from '../models/migrationWizardPage';
|
import { MigrationWizardPage } from '../models/migrationWizardPage';
|
||||||
import { MigrationStateModel, StateChangeEvent } from '../models/stateMachine';
|
import { MigrationStateModel, StateChangeEvent } from '../models/stateMachine';
|
||||||
import { Product, ProductLookupTable } from '../models/product';
|
import { Product, ProductLookupTable } from '../models/product';
|
||||||
import { SKU_RECOMMENDATION_PAGE_TITLE, SKU_RECOMMENDATION_CHOOSE_A_TARGET } from '../models/strings';
|
|
||||||
import { Disposable } from 'vscode';
|
import { Disposable } from 'vscode';
|
||||||
import { AssessmentResultsDialog } from '../dialog/assessmentResults/assessmentResultsDialog';
|
import { AssessmentResultsDialog } from '../dialog/assessmentResults/assessmentResultsDialog';
|
||||||
|
import { getAvailableManagedInstanceProducts, getSubscriptions, SqlManagedInstance, Subscription } from '../api/azure';
|
||||||
|
import * as constants from '../models/strings';
|
||||||
|
import { azureResource } from 'azureResource';
|
||||||
|
|
||||||
|
// import { SqlMigrationService } from '../../../../extensions/mssql/src/sqlMigration/sqlMigrationService';
|
||||||
|
|
||||||
export class SKURecommendationPage extends MigrationWizardPage {
|
export class SKURecommendationPage extends MigrationWizardPage {
|
||||||
// For future reference: DO NOT EXPOSE WIZARD DIRECTLY THROUGH HERE.
|
// For future reference: DO NOT EXPOSE WIZARD DIRECTLY THROUGH HERE.
|
||||||
constructor(wizard: azdata.window.Wizard, migrationStateModel: MigrationStateModel) {
|
constructor(wizard: azdata.window.Wizard, migrationStateModel: MigrationStateModel) {
|
||||||
super(wizard, azdata.window.createWizardPage(SKU_RECOMMENDATION_PAGE_TITLE), migrationStateModel);
|
super(wizard, azdata.window.createWizardPage(constants.SKU_RECOMMENDATION_PAGE_TITLE), migrationStateModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async registerContent(view: azdata.ModelView) {
|
protected async registerContent(view: azdata.ModelView) {
|
||||||
await this.initialState(view);
|
await this.initialState(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private igComponent: azdata.FormComponent<azdata.TextComponent> | undefined;
|
private _igComponent: azdata.FormComponent<azdata.TextComponent> | undefined;
|
||||||
private detailsComponent: azdata.FormComponent<azdata.TextComponent> | undefined;
|
private _detailsComponent: azdata.FormComponent<azdata.TextComponent> | undefined;
|
||||||
private chooseTargetComponent: azdata.FormComponent<azdata.DivContainer> | undefined;
|
private _chooseTargetComponent: azdata.FormComponent<azdata.DivContainer> | undefined;
|
||||||
private view: azdata.ModelView | undefined;
|
private _azureSubscriptionText: azdata.FormComponent<azdata.TextComponent> | undefined;
|
||||||
|
private _managedInstanceSubscriptionDropdown!: azdata.DropDownComponent;
|
||||||
|
private _managedInstanceDropdown!: azdata.DropDownComponent;
|
||||||
|
private _subscriptionDropdownValues: azdata.CategoryValue[] = [];
|
||||||
|
private _subscriptionMap: Map<string, Subscription> = new Map();
|
||||||
|
private _view: azdata.ModelView | undefined;
|
||||||
|
|
||||||
private async initialState(view: azdata.ModelView) {
|
private async initialState(view: azdata.ModelView) {
|
||||||
this.igComponent = this.createStatusComponent(view); // The first component giving basic information
|
this._igComponent = this.createStatusComponent(view); // The first component giving basic information
|
||||||
this.detailsComponent = this.createDetailsComponent(view); // The details of what can be moved
|
this._detailsComponent = this.createDetailsComponent(view); // The details of what can be moved
|
||||||
this.chooseTargetComponent = this.createChooseTargetComponent(view);
|
this._chooseTargetComponent = this.createChooseTargetComponent(view);
|
||||||
|
this._azureSubscriptionText = this.createAzureSubscriptionText(view);
|
||||||
|
|
||||||
|
const managedInstanceSubscriptionDropdownLabel = view.modelBuilder.text().withProps({
|
||||||
|
value: constants.SUBSCRIPTION
|
||||||
|
}).component();
|
||||||
|
this._managedInstanceSubscriptionDropdown = view.modelBuilder.dropDown().component();
|
||||||
|
this._managedInstanceSubscriptionDropdown.onValueChanged((e) => {
|
||||||
|
this.populateManagedInstanceDropdown();
|
||||||
|
});
|
||||||
|
const managedInstanceDropdownLabel = view.modelBuilder.text().withProps({
|
||||||
|
value: constants.MANAGED_INSTANCE
|
||||||
|
}).component();
|
||||||
|
this._managedInstanceDropdown = view.modelBuilder.dropDown().component();
|
||||||
|
|
||||||
const assessmentLink = view.modelBuilder.hyperlink()
|
const targetContainer = view.modelBuilder.flexContainer().withItems(
|
||||||
.withProperties<azdata.HyperlinkComponentProperties>({
|
[
|
||||||
label: 'View Assessment Results',
|
managedInstanceSubscriptionDropdownLabel,
|
||||||
url: ''
|
this._managedInstanceSubscriptionDropdown,
|
||||||
}).component();
|
managedInstanceDropdownLabel,
|
||||||
assessmentLink.onDidClick(async () => {
|
this._managedInstanceDropdown
|
||||||
let dialog = new AssessmentResultsDialog('ownerUri', this.migrationStateModel, 'Assessment Dialog');
|
]
|
||||||
await dialog.openDialog();
|
).withLayout({
|
||||||
|
flexFlow: 'column'
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
let connectionUri: string = await azdata.connection.getUriForConnection(this.migrationStateModel.sourceConnectionId);
|
||||||
|
this.migrationStateModel.migrationService.getAssessments(connectionUri).then(results => {
|
||||||
|
if (results) {
|
||||||
|
this.migrationStateModel.assessmentResults = results.items;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const assessmentFormLink = {
|
this._view = view;
|
||||||
title: '',
|
const formContainer = view.modelBuilder.formContainer().withFormItems(
|
||||||
component: assessmentLink,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.view = view;
|
|
||||||
const form = view.modelBuilder.formContainer().withFormItems(
|
|
||||||
[
|
[
|
||||||
this.igComponent,
|
this._igComponent,
|
||||||
this.detailsComponent,
|
this._detailsComponent,
|
||||||
this.chooseTargetComponent,
|
this._chooseTargetComponent,
|
||||||
assessmentFormLink
|
this._azureSubscriptionText,
|
||||||
|
{
|
||||||
|
component: targetContainer
|
||||||
|
},
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
await view.initializeModel(form.component());
|
await view.initializeModel(formContainer.component());
|
||||||
}
|
}
|
||||||
|
|
||||||
private createStatusComponent(view: azdata.ModelView): azdata.FormComponent<azdata.TextComponent> {
|
private createStatusComponent(view: azdata.ModelView): azdata.FormComponent<azdata.TextComponent> {
|
||||||
const component = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({
|
const component = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({
|
||||||
value: '',
|
value: '',
|
||||||
|
CSSStyles: {
|
||||||
|
'font-size': '18px'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -87,27 +117,34 @@ export class SKURecommendationPage extends MigrationWizardPage {
|
|||||||
const component = view.modelBuilder.divContainer();
|
const component = view.modelBuilder.divContainer();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: SKU_RECOMMENDATION_CHOOSE_A_TARGET,
|
title: constants.SKU_RECOMMENDATION_CHOOSE_A_TARGET,
|
||||||
component: component.component()
|
component: component.component()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructDetails(): void {
|
private constructDetails(): void {
|
||||||
this.chooseTargetComponent?.component.clearItems();
|
this._chooseTargetComponent?.component.clearItems();
|
||||||
|
|
||||||
this.igComponent!.component.value = 'Test';
|
if (this.migrationStateModel.assessmentResults) {
|
||||||
this.detailsComponent!.component.value = 'Test';
|
|
||||||
|
}
|
||||||
|
this._igComponent!.component.value = constants.CONGRATULATIONS;
|
||||||
|
// either: SKU_RECOMMENDATION_ALL_SUCCESSFUL or SKU_RECOMMENDATION_SOME_SUCCESSFUL or SKU_RECOMMENDATION_NONE_SUCCESSFUL
|
||||||
|
this._detailsComponent!.component.value = constants.SKU_RECOMMENDATION_SOME_SUCCESSFUL(1, 1);
|
||||||
this.constructTargets();
|
this.constructTargets();
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructTargets(): void {
|
private constructTargets(): void {
|
||||||
const products: Product[] = Object.values(ProductLookupTable);
|
const products: Product[] = Object.values(ProductLookupTable);
|
||||||
|
|
||||||
const rbg = this.view!.modelBuilder.radioCardGroup();
|
const rbg = this._view!.modelBuilder.radioCardGroup().withProperties<azdata.RadioCardGroupComponentProperties>({
|
||||||
rbg.component().cards = [];
|
cards: [],
|
||||||
rbg.component().orientation = azdata.Orientation.Vertical;
|
cardWidth: '600px',
|
||||||
rbg.component().iconHeight = '30px';
|
cardHeight: '60px',
|
||||||
rbg.component().iconWidth = '30px';
|
orientation: azdata.Orientation.Vertical,
|
||||||
|
iconHeight: '30px',
|
||||||
|
iconWidth: '30px'
|
||||||
|
});
|
||||||
|
|
||||||
products.forEach((product) => {
|
products.forEach((product) => {
|
||||||
const imagePath = path.resolve(this.migrationStateModel.getExtensionPath(), 'media', product.icon ?? 'ads.svg');
|
const imagePath = path.resolve(this.migrationStateModel.getExtensionPath(), 'media', product.icon ?? 'ads.svg');
|
||||||
@@ -144,12 +181,104 @@ export class SKURecommendationPage extends MigrationWizardPage {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chooseTargetComponent?.component.addItem(rbg.component());
|
rbg.component().onLinkClick(async (value) => {
|
||||||
|
|
||||||
|
//check which card is being selected, and open correct dialog based on link
|
||||||
|
console.log(value);
|
||||||
|
let dialog = new AssessmentResultsDialog('ownerUri', this.migrationStateModel, 'Assessment Dialog');
|
||||||
|
await dialog.openDialog();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._chooseTargetComponent?.component.addItem(rbg.component());
|
||||||
|
}
|
||||||
|
|
||||||
|
private createAzureSubscriptionText(view: azdata.ModelView): azdata.FormComponent<azdata.TextComponent> {
|
||||||
|
const component = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({
|
||||||
|
value: 'Select an Azure subscription and an Azure SQL Managed Instance for your target.', //TODO: Localize
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: '',
|
||||||
|
component: component.component(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async populateSubscriptionDropdown(): Promise<void> {
|
||||||
|
this._managedInstanceSubscriptionDropdown.loading = true;
|
||||||
|
this._managedInstanceDropdown.loading = true;
|
||||||
|
let subscriptions: azureResource.AzureResourceSubscription[] = [];
|
||||||
|
try {
|
||||||
|
subscriptions = await getSubscriptions(this.migrationStateModel._azureAccount);
|
||||||
|
subscriptions.forEach((subscription) => {
|
||||||
|
this._subscriptionMap.set(subscription.id, subscription);
|
||||||
|
this._subscriptionDropdownValues.push({
|
||||||
|
name: subscription.id,
|
||||||
|
displayName: subscription.name + ' - ' + subscription.id,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!this._subscriptionDropdownValues || this._subscriptionDropdownValues.length === 0) {
|
||||||
|
this._subscriptionDropdownValues = [
|
||||||
|
{
|
||||||
|
displayName: constants.NO_SUBSCRIPTIONS_FOUND,
|
||||||
|
name: ''
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
this._managedInstanceSubscriptionDropdown.values = this._subscriptionDropdownValues;
|
||||||
|
} catch (error) {
|
||||||
|
this.setEmptyDropdownPlaceHolder(this._managedInstanceSubscriptionDropdown, constants.NO_SUBSCRIPTIONS_FOUND);
|
||||||
|
this._managedInstanceDropdown.loading = false;
|
||||||
|
}
|
||||||
|
this.populateManagedInstanceDropdown();
|
||||||
|
this._managedInstanceSubscriptionDropdown.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async populateManagedInstanceDropdown(): Promise<void> {
|
||||||
|
this._managedInstanceDropdown.loading = true;
|
||||||
|
let mis: SqlManagedInstance[] = [];
|
||||||
|
let miValues: azdata.CategoryValue[] = [];
|
||||||
|
try {
|
||||||
|
const subscriptionId = (<azdata.CategoryValue>this._managedInstanceSubscriptionDropdown.value).name;
|
||||||
|
|
||||||
|
mis = await getAvailableManagedInstanceProducts(this.migrationStateModel._azureAccount, this._subscriptionMap.get(subscriptionId)!);
|
||||||
|
mis.forEach((mi) => {
|
||||||
|
miValues.push({
|
||||||
|
name: mi.name,
|
||||||
|
displayName: mi.name
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!miValues || miValues.length === 0) {
|
||||||
|
miValues = [
|
||||||
|
{
|
||||||
|
displayName: constants.NO_MANAGED_INSTANCE_FOUND,
|
||||||
|
name: ''
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
this._managedInstanceDropdown.values = miValues;
|
||||||
|
} catch (error) {
|
||||||
|
this.setEmptyDropdownPlaceHolder(this._managedInstanceDropdown, constants.NO_MANAGED_INSTANCE_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._managedInstanceDropdown.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private setEmptyDropdownPlaceHolder(dropDown: azdata.DropDownComponent, placeholder: string): void {
|
||||||
|
dropDown.values = [{
|
||||||
|
displayName: placeholder,
|
||||||
|
name: ''
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
private eventListener: Disposable | undefined;
|
private eventListener: Disposable | undefined;
|
||||||
public async onPageEnter(): Promise<void> {
|
public async onPageEnter(): Promise<void> {
|
||||||
this.eventListener = this.migrationStateModel.stateChangeEvent(async (e) => this.onStateChangeEvent(e));
|
this.eventListener = this.migrationStateModel.stateChangeEvent(async (e) => this.onStateChangeEvent(e));
|
||||||
|
this.populateSubscriptionDropdown();
|
||||||
this.constructDetails();
|
this.constructDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import * as azdata from 'azdata';
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as mssql from '../../../mssql';
|
import * as mssql from '../../../mssql';
|
||||||
import { MigrationStateModel } from '../models/stateMachine';
|
import { MigrationStateModel } from '../models/stateMachine';
|
||||||
// import { SourceConfigurationPage } from './sourceConfigurationPage';
|
|
||||||
import { WIZARD_TITLE } from '../models/strings';
|
import { WIZARD_TITLE } from '../models/strings';
|
||||||
import { MigrationWizardPage } from '../models/migrationWizardPage';
|
import { MigrationWizardPage } from '../models/migrationWizardPage';
|
||||||
import { SKURecommendationPage } from './skuRecommendationPage';
|
import { SKURecommendationPage } from './skuRecommendationPage';
|
||||||
@@ -14,7 +13,6 @@ import { SKURecommendationPage } from './skuRecommendationPage';
|
|||||||
import { DatabaseBackupPage } from './databaseBackupPage';
|
import { DatabaseBackupPage } from './databaseBackupPage';
|
||||||
import { AccountsSelectionPage } from './accountsSelectionPage';
|
import { AccountsSelectionPage } from './accountsSelectionPage';
|
||||||
import { IntergrationRuntimePage } from './integrationRuntimePage';
|
import { IntergrationRuntimePage } from './integrationRuntimePage';
|
||||||
import { TempTargetSelectionPage } from './tempTargetSelectionPage';
|
|
||||||
import { SummaryPage } from './summaryPage';
|
import { SummaryPage } from './summaryPage';
|
||||||
|
|
||||||
export const WIZARD_INPUT_COMPONENT_WIDTH = '400px';
|
export const WIZARD_INPUT_COMPONENT_WIDTH = '400px';
|
||||||
@@ -36,11 +34,9 @@ export class WizardController {
|
|||||||
const wizard = azdata.window.createWizard(WIZARD_TITLE, 'wide');
|
const wizard = azdata.window.createWizard(WIZARD_TITLE, 'wide');
|
||||||
wizard.generateScriptButton.enabled = false;
|
wizard.generateScriptButton.enabled = false;
|
||||||
wizard.generateScriptButton.hidden = true;
|
wizard.generateScriptButton.hidden = true;
|
||||||
// const sourceConfigurationPage = new SourceConfigurationPage(wizard, stateModel);
|
|
||||||
const skuRecommendationPage = new SKURecommendationPage(wizard, stateModel);
|
const skuRecommendationPage = new SKURecommendationPage(wizard, stateModel);
|
||||||
// const subscriptionSelectionPage = new SubscriptionSelectionPage(wizard, stateModel);
|
// const subscriptionSelectionPage = new SubscriptionSelectionPage(wizard, stateModel);
|
||||||
const azureAccountsPage = new AccountsSelectionPage(wizard, stateModel);
|
const azureAccountsPage = new AccountsSelectionPage(wizard, stateModel);
|
||||||
const tempTargetSelectionPage = new TempTargetSelectionPage(wizard, stateModel);
|
|
||||||
const databaseBackupPage = new DatabaseBackupPage(wizard, stateModel);
|
const databaseBackupPage = new DatabaseBackupPage(wizard, stateModel);
|
||||||
const integrationRuntimePage = new IntergrationRuntimePage(wizard, stateModel);
|
const integrationRuntimePage = new IntergrationRuntimePage(wizard, stateModel);
|
||||||
const summaryPage = new SummaryPage(wizard, stateModel);
|
const summaryPage = new SummaryPage(wizard, stateModel);
|
||||||
@@ -48,8 +44,6 @@ export class WizardController {
|
|||||||
const pages: MigrationWizardPage[] = [
|
const pages: MigrationWizardPage[] = [
|
||||||
// subscriptionSelectionPage,
|
// subscriptionSelectionPage,
|
||||||
azureAccountsPage,
|
azureAccountsPage,
|
||||||
tempTargetSelectionPage,
|
|
||||||
// sourceConfigurationPage,
|
|
||||||
skuRecommendationPage,
|
skuRecommendationPage,
|
||||||
databaseBackupPage,
|
databaseBackupPage,
|
||||||
integrationRuntimePage,
|
integrationRuntimePage,
|
||||||
|
|||||||
Reference in New Issue
Block a user