/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as azdata from 'azdata'; import { MigrationWizardPage } from '../models/migrationWizardPage'; 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'; interface GenericValue extends azdata.CategoryValue { value: T; } type AccountValue = GenericValue; type SubscriptionValue = GenericValue; type ProductValue = GenericValue; export class SubscriptionSelectionPage extends MigrationWizardPage { private disposables: Disposable[] = []; // For future reference: DO NOT EXPOSE WIZARD DIRECTLY THROUGH HERE. constructor(wizard: azdata.window.Wizard, migrationStateModel: MigrationStateModel) { super(wizard, azdata.window.createWizardPage(SUBSCRIPTION_SELECTION_PAGE_TITLE), migrationStateModel); } protected async registerContent(view: azdata.ModelView): Promise { await this.initialState(view); } private accountDropDown?: azdata.FormComponent; private subscriptionDropDown?: azdata.FormComponent; private productDropDown?: azdata.FormComponent; private async initialState(view: azdata.ModelView) { this.accountDropDown = this.createAccountDropDown(view); this.subscriptionDropDown = this.createSubscriptionDropDown(view); this.productDropDown = this.createProdcutDropDown(view); const form = view.modelBuilder.formContainer().withFormItems( [ this.accountDropDown, this.subscriptionDropDown, this.productDropDown ] ); await view.initializeModel(form.component()); } private createAccountDropDown(view: azdata.ModelView): azdata.FormComponent { const dropDown = view.modelBuilder.dropDown().withProperties({ values: [], }); this.disposables.push(dropDown.component().onValueChanged(() => { this.accountValueChanged().catch(console.error); })); return { component: dropDown.component(), title: SUBSCRIPTION_SELECTION_AZURE_ACCOUNT_TITLE }; } private createSubscriptionDropDown(view: azdata.ModelView): azdata.FormComponent { const dropDown = view.modelBuilder.dropDown().withProperties({ values: [], }); this.disposables.push(dropDown.component().onValueChanged(() => { this.subscriptionValueChanged().catch(console.error); })); return { component: dropDown.component(), title: SUBSCRIPTION_SELECTION_AZURE_SUBSCRIPTION_TITLE }; } private createProdcutDropDown(view: azdata.ModelView): azdata.FormComponent { const dropDown = view.modelBuilder.dropDown().withProperties({ values: [], }); return { component: dropDown.component(), title: SUBSCRIPTION_SELECTION_AZURE_PRODUCT_TITLE }; } private async accountValueChanged(): Promise { const account = this.getPickedAccount(); if (account) { const subscriptions = await getSubscriptions(account); await this.populateSubscriptionValues(subscriptions); } } private async subscriptionValueChanged(): Promise { const account = this.getPickedAccount(); const subscription = this.getPickedSubscription(); const results = await getAvailableManagedInstanceProducts(account!, subscription!); await getAvailableSqlServers(account!, subscription!); this.populateProductValues(results); } private getPickedAccount(): azdata.Account | undefined { const accountValue: AccountValue | undefined = this.accountDropDown?.component.value as AccountValue; return accountValue?.value; } private getPickedSubscription(): Subscription | undefined { const accountValue: SubscriptionValue | undefined = this.subscriptionDropDown?.component.value as SubscriptionValue; return accountValue?.value; } private async populateAccountValues(): Promise { let accounts = await azdata.accounts.getAllAccounts(); accounts = accounts.filter(a => a.key.providerId.startsWith('azure') && !a.isStale); const values: AccountValue[] = accounts.map(a => { return { displayName: a.displayInfo.displayName, name: a.key.accountId, value: a }; }); this.accountDropDown!.component.values = values; await this.accountValueChanged(); } private async populateSubscriptionValues(subscriptions: Subscription[]): Promise { const values: SubscriptionValue[] = subscriptions.map(sub => { return { displayName: sub.name, name: sub.id, value: sub }; }); this.subscriptionDropDown!.component.values = values; await this.subscriptionValueChanged(); } private async populateProductValues(products: AzureProduct[]) { const values: ProductValue[] = products.map(prod => { return { displayName: prod.name, name: prod.id, value: prod }; }); this.productDropDown!.component.values = values; } public async onPageEnter(): Promise { this.disposables.push(this.migrationStateModel.stateChangeEvent(async (e) => this.onStateChangeEvent(e))); await this.populateAccountValues(); } public async onPageLeave(): Promise { this.disposables.forEach(d => d.dispose()); } protected async handleStateChange(e: StateChangeEvent): Promise { } }