mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-09 17:52:34 -05:00
Dev/brih/feature/switch ads to portal context (#18963)
* Add CodeQL Analysis workflow (#10195) * Add CodeQL Analysis workflow * Fix path * dashboard refactor * update version, readme, minor ui changes * fix merge issue * Revert "Add CodeQL Analysis workflow (#10195)" This reverts commit fe98d586cd75be4758ac544649bb4983accf4acd. * fix context switching issue * fix resource id parsing error and mi api version * mv refresh btn, rm autorefresh, align cards * remove missed autorefresh code * improve error handling and messages * fix typos * remove duplicate/unnecessary _populate* calls * change clear configuration button text * remove confusing watermark text * add stale account handling Co-authored-by: Justin Hutchings <jhutchings1@users.noreply.github.com>
This commit is contained in:
@@ -786,15 +786,27 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
||||
await this.switchNetworkContainerFields(this.migrationStateModel._databaseBackup.networkContainerType);
|
||||
|
||||
const connectionProfile = await this.migrationStateModel.getSourceConnectionProfile();
|
||||
const queryProvider = azdata.dataprotocol.getProvider<azdata.QueryProvider>((await this.migrationStateModel.getSourceConnectionProfile()).providerId, azdata.DataProviderType.QueryProvider);
|
||||
const queryProvider = azdata.dataprotocol.getProvider<azdata.QueryProvider>(
|
||||
(await this.migrationStateModel.getSourceConnectionProfile()).providerId,
|
||||
azdata.DataProviderType.QueryProvider);
|
||||
|
||||
const query = 'select SUSER_NAME()';
|
||||
const results = await queryProvider.runQueryAndReturn(await (azdata.connection.getUriForConnection(this.migrationStateModel.sourceConnectionId)), query);
|
||||
const results = await queryProvider.runQueryAndReturn(
|
||||
await (azdata.connection.getUriForConnection(
|
||||
this.migrationStateModel.sourceConnectionId)), query);
|
||||
|
||||
const username = results.rows[0][0].displayValue;
|
||||
this.migrationStateModel._authenticationType = connectionProfile.authenticationType === 'SqlLogin' ? MigrationSourceAuthenticationType.Sql : connectionProfile.authenticationType === 'Integrated' ? MigrationSourceAuthenticationType.Integrated : undefined!;
|
||||
this.migrationStateModel._authenticationType = connectionProfile.authenticationType === 'SqlLogin'
|
||||
? MigrationSourceAuthenticationType.Sql
|
||||
: connectionProfile.authenticationType === 'Integrated'
|
||||
? MigrationSourceAuthenticationType.Integrated
|
||||
: undefined!;
|
||||
this._sourceHelpText.value = constants.SQL_SOURCE_DETAILS(this.migrationStateModel._authenticationType, connectionProfile.serverName);
|
||||
this._sqlSourceUsernameInput.value = username;
|
||||
this._sqlSourcePassword.value = (await azdata.connection.getCredentials(this.migrationStateModel.sourceConnectionId)).password;
|
||||
this._windowsUserAccountText.value = this.migrationStateModel.savedInfo?.networkShares[0]?.windowsUser;
|
||||
this._windowsUserAccountText.value = this.migrationStateModel.savedInfo?.networkShares
|
||||
? this.migrationStateModel.savedInfo?.networkShares[0]?.windowsUser
|
||||
: '';
|
||||
|
||||
this._networkShareTargetDatabaseNames = [];
|
||||
this._networkShareLocations = [];
|
||||
@@ -809,7 +821,7 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
||||
}
|
||||
|
||||
let originalTargetDatabaseNames = this.migrationStateModel._targetDatabaseNames;
|
||||
let originalNetworkShares = this.migrationStateModel._databaseBackup.networkShares;
|
||||
let originalNetworkShares = this.migrationStateModel._databaseBackup.networkShares || [];
|
||||
let originalBlobs = this.migrationStateModel._databaseBackup.blobs;
|
||||
if (this.migrationStateModel._didUpdateDatabasesForMigration) {
|
||||
this.migrationStateModel._targetDatabaseNames = [];
|
||||
@@ -830,7 +842,10 @@ export class DatabaseBackupPage extends MigrationWizardPage {
|
||||
blob = originalBlobs[dbIndex] ?? blob;
|
||||
} else {
|
||||
// network share values are uniform for all dbs in the same migration, except for networkShareLocation
|
||||
const previouslySelectedNetworkShare = originalNetworkShares[0];
|
||||
const previouslySelectedNetworkShare = originalNetworkShares.length > 0
|
||||
? originalNetworkShares[0]
|
||||
: '';
|
||||
|
||||
if (previouslySelectedNetworkShare) {
|
||||
networkShare = {
|
||||
...previouslySelectedNetworkShare,
|
||||
|
||||
@@ -8,43 +8,16 @@ import * as vscode from 'vscode';
|
||||
import { MigrationWizardPage } from '../models/migrationWizardPage';
|
||||
import { MigrationStateModel, StateChangeEvent } from '../models/stateMachine';
|
||||
import * as constants from '../constants/strings';
|
||||
import { IconPath, IconPathHelper } from '../constants/iconPathHelper';
|
||||
import { debounce } from '../api/utils';
|
||||
import * as styles from '../constants/styles';
|
||||
import { selectDatabasesFromList } from '../constants/helper';
|
||||
|
||||
const styleLeft: azdata.CssStyles = {
|
||||
'border': 'none',
|
||||
'text-align': 'left',
|
||||
'white-space': 'nowrap',
|
||||
'text-overflow': 'ellipsis',
|
||||
'overflow': 'hidden',
|
||||
'box-shadow': '0px -1px 0px 0px rgba(243, 242, 241, 1) inset'
|
||||
};
|
||||
|
||||
const styleCheckBox: azdata.CssStyles = {
|
||||
'border': 'none',
|
||||
'text-align': 'left',
|
||||
'white-space': 'nowrap',
|
||||
'text-overflow': 'ellipsis',
|
||||
'overflow': 'hidden',
|
||||
};
|
||||
|
||||
const styleRight: azdata.CssStyles = {
|
||||
'border': 'none',
|
||||
'text-align': 'right',
|
||||
'white-space': 'nowrap',
|
||||
'text-overflow': 'ellipsis',
|
||||
'overflow': 'hidden',
|
||||
'box-shadow': '0px -1px 0px 0px rgba(243, 242, 241, 1) inset'
|
||||
};
|
||||
import { IconPathHelper } from '../constants/iconPathHelper';
|
||||
|
||||
export class DatabaseSelectorPage extends MigrationWizardPage {
|
||||
private _view!: azdata.ModelView;
|
||||
private _databaseSelectorTable!: azdata.DeclarativeTableComponent;
|
||||
private _databaseSelectorTable!: azdata.TableComponent;
|
||||
private _dbNames!: string[];
|
||||
private _dbCount!: azdata.TextComponent;
|
||||
private _databaseTableValues!: azdata.DeclarativeTableCellValue[][];
|
||||
private _databaseTableValues!: any[];
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
constructor(wizard: azdata.window.Wizard, migrationStateModel: MigrationStateModel) {
|
||||
@@ -115,7 +88,6 @@ export class DatabaseSelectorPage extends MigrationWizardPage {
|
||||
protected async handleStateChange(e: StateChangeEvent): Promise<void> {
|
||||
}
|
||||
|
||||
|
||||
private createSearchComponent(): azdata.DivContainer {
|
||||
let resourceSearchBox = this._view.modelBuilder.inputBox().withProps({
|
||||
stopEnterPropagation: true,
|
||||
@@ -137,74 +109,36 @@ export class DatabaseSelectorPage extends MigrationWizardPage {
|
||||
}
|
||||
|
||||
@debounce(500)
|
||||
private _filterTableList(value: string): void {
|
||||
private async _filterTableList(value: string, selectedList?: string[]): Promise<void> {
|
||||
const selectedRows: number[] = [];
|
||||
const selectedDatabases = selectedList || this.selectedDbs();
|
||||
let tableRows = this._databaseTableValues;
|
||||
if (this._databaseTableValues && value?.length > 0) {
|
||||
const filter: number[] = [];
|
||||
this._databaseTableValues.forEach((row, index) => {
|
||||
// undo when bug #16445 is fixed
|
||||
// const flexContainer: azdata.FlexContainer = row[1]?.value as azdata.FlexContainer;
|
||||
// const textComponent: azdata.TextComponent = flexContainer?.items[1] as azdata.TextComponent;
|
||||
// const cellText = textComponent?.value?.toLowerCase();
|
||||
const text = row[1]?.value as string;
|
||||
const cellText = text?.toLowerCase();
|
||||
const searchText: string = value?.toLowerCase();
|
||||
if (cellText?.includes(searchText)) {
|
||||
filter.push(index);
|
||||
}
|
||||
});
|
||||
|
||||
this._databaseSelectorTable.setFilter(filter);
|
||||
} else {
|
||||
this._databaseSelectorTable.setFilter(undefined);
|
||||
tableRows = this._databaseTableValues
|
||||
.filter(row => {
|
||||
const searchText = value?.toLowerCase();
|
||||
return row[2]?.toLowerCase()?.indexOf(searchText) > -1 // database name
|
||||
|| row[3]?.toLowerCase()?.indexOf(searchText) > -1 // state
|
||||
|| row[4]?.toLowerCase()?.indexOf(searchText) > -1 // size
|
||||
|| row[5]?.toLowerCase()?.indexOf(searchText) > -1; // last backup date
|
||||
});
|
||||
}
|
||||
|
||||
for (let row = 0; row < tableRows.length; row++) {
|
||||
const database: string = tableRows[row][2];
|
||||
if (selectedDatabases.includes(database)) {
|
||||
selectedRows.push(row);
|
||||
}
|
||||
}
|
||||
|
||||
await this._databaseSelectorTable.updateProperty('data', tableRows);
|
||||
this._databaseSelectorTable.selectedRows = selectedRows;
|
||||
await this.updateValuesOnSelection();
|
||||
}
|
||||
|
||||
|
||||
public async createRootContainer(view: azdata.ModelView): Promise<azdata.FlexContainer> {
|
||||
const providerId = (await this.migrationStateModel.getSourceConnectionProfile()).providerId;
|
||||
const metaDataService = azdata.dataprotocol.getProvider<azdata.MetadataProvider>(providerId, azdata.DataProviderType.MetadataProvider);
|
||||
const ownerUri = await azdata.connection.getUriForConnection(this.migrationStateModel.sourceConnectionId);
|
||||
const results = <azdata.DatabaseInfo[]>await metaDataService.getDatabases(ownerUri);
|
||||
const excludeDbs: string[] = [
|
||||
'master',
|
||||
'tempdb',
|
||||
'msdb',
|
||||
'model'
|
||||
];
|
||||
this._dbNames = [];
|
||||
let finalResult = results.filter((db) => !excludeDbs.includes(db.options.name));
|
||||
finalResult.sort((a, b) => a.options.name.localeCompare(b.options.name));
|
||||
this._databaseTableValues = [];
|
||||
for (let index in finalResult) {
|
||||
let selectable = true;
|
||||
if (constants.OFFLINE_CAPS.includes(finalResult[index].options.state)) {
|
||||
selectable = false;
|
||||
}
|
||||
this._databaseTableValues.push([
|
||||
{
|
||||
value: false,
|
||||
style: styleCheckBox,
|
||||
enabled: selectable
|
||||
},
|
||||
{
|
||||
value: this.createIconTextCell(IconPathHelper.sqlDatabaseLogo, finalResult[index].options.name),
|
||||
style: styleLeft
|
||||
},
|
||||
{
|
||||
value: `${finalResult[index].options.state}`,
|
||||
style: styleLeft
|
||||
},
|
||||
{
|
||||
value: `${finalResult[index].options.sizeInMB}`,
|
||||
style: styleRight
|
||||
},
|
||||
{
|
||||
value: `${finalResult[index].options.lastBackup}`,
|
||||
style: styleLeft
|
||||
}
|
||||
]);
|
||||
this._dbNames.push(finalResult[index].options.name);
|
||||
}
|
||||
await this._loadDatabaseList(this.migrationStateModel, this.migrationStateModel._assessedDatabaseList);
|
||||
|
||||
const text = this._view.modelBuilder.text().withProps({
|
||||
value: constants.DATABASE_FOR_ASSESSMENT_DESCRIPTION,
|
||||
@@ -214,70 +148,83 @@ export class DatabaseSelectorPage extends MigrationWizardPage {
|
||||
}).component();
|
||||
|
||||
this._dbCount = this._view.modelBuilder.text().withProps({
|
||||
value: constants.DATABASES_SELECTED(this.selectedDbs.length, this._databaseTableValues.length),
|
||||
value: constants.DATABASES_SELECTED(
|
||||
this.selectedDbs().length,
|
||||
this._databaseTableValues.length),
|
||||
CSSStyles: {
|
||||
...styles.BODY_CSS,
|
||||
'margin-top': '8px'
|
||||
}
|
||||
}).component();
|
||||
|
||||
this._databaseSelectorTable = this._view.modelBuilder.declarativeTable().withProps(
|
||||
{
|
||||
enableRowSelection: true,
|
||||
width: '100%',
|
||||
CSSStyles: {
|
||||
'border': 'none'
|
||||
},
|
||||
const cssClass = 'no-borders';
|
||||
this._databaseSelectorTable = this._view.modelBuilder.table()
|
||||
.withProps({
|
||||
data: [],
|
||||
width: 650,
|
||||
height: '100%',
|
||||
forceFitColumns: azdata.ColumnSizingMode.ForceFit,
|
||||
columns: [
|
||||
{
|
||||
displayName: '',
|
||||
valueType: azdata.DeclarativeDataType.boolean,
|
||||
width: 20,
|
||||
isReadOnly: false,
|
||||
showCheckAll: true,
|
||||
headerCssStyles: styleCheckBox
|
||||
<azdata.CheckboxColumn>{
|
||||
value: '',
|
||||
width: 10,
|
||||
type: azdata.ColumnType.checkBox,
|
||||
action: azdata.ActionOnCellCheckboxCheck.selectRow,
|
||||
resizable: false,
|
||||
cssClass: cssClass,
|
||||
headerCssClass: cssClass,
|
||||
},
|
||||
{
|
||||
displayName: constants.DATABASE,
|
||||
// undo when bug #16445 is fixed
|
||||
// valueType: azdata.DeclarativeDataType.component,
|
||||
valueType: azdata.DeclarativeDataType.string,
|
||||
width: '100%',
|
||||
isReadOnly: true,
|
||||
headerCssStyles: styleLeft
|
||||
value: 'databaseicon',
|
||||
name: '',
|
||||
width: 10,
|
||||
type: azdata.ColumnType.icon,
|
||||
headerCssClass: cssClass,
|
||||
cssClass: cssClass,
|
||||
resizable: false,
|
||||
},
|
||||
{
|
||||
displayName: constants.STATUS,
|
||||
valueType: azdata.DeclarativeDataType.string,
|
||||
width: 100,
|
||||
isReadOnly: true,
|
||||
headerCssStyles: styleLeft
|
||||
name: constants.DATABASE,
|
||||
value: 'database',
|
||||
type: azdata.ColumnType.text,
|
||||
width: 360,
|
||||
cssClass: cssClass,
|
||||
headerCssClass: cssClass,
|
||||
},
|
||||
{
|
||||
displayName: constants.SIZE,
|
||||
valueType: azdata.DeclarativeDataType.string,
|
||||
width: 125,
|
||||
isReadOnly: true,
|
||||
headerCssStyles: styleRight
|
||||
name: constants.STATUS,
|
||||
value: 'status',
|
||||
type: azdata.ColumnType.text,
|
||||
width: 80,
|
||||
cssClass: cssClass,
|
||||
headerCssClass: cssClass,
|
||||
},
|
||||
{
|
||||
displayName: constants.LAST_BACKUP,
|
||||
valueType: azdata.DeclarativeDataType.string,
|
||||
width: 150,
|
||||
isReadOnly: true,
|
||||
headerCssStyles: styleLeft
|
||||
}
|
||||
name: constants.SIZE,
|
||||
value: 'size',
|
||||
type: azdata.ColumnType.text,
|
||||
width: 80,
|
||||
cssClass: cssClass,
|
||||
headerCssClass: cssClass,
|
||||
},
|
||||
{
|
||||
name: constants.LAST_BACKUP,
|
||||
value: 'lastBackup',
|
||||
type: azdata.ColumnType.text,
|
||||
width: 130,
|
||||
cssClass: cssClass,
|
||||
headerCssClass: cssClass,
|
||||
},
|
||||
]
|
||||
}
|
||||
).component();
|
||||
}).component();
|
||||
|
||||
this._databaseTableValues = selectDatabasesFromList(this.migrationStateModel._databasesForAssessment, this._databaseTableValues);
|
||||
await this._databaseSelectorTable.setDataValues(this._databaseTableValues);
|
||||
await this.updateValuesOnSelection();
|
||||
|
||||
this._disposables.push(this._databaseSelectorTable.onDataChanged(async () => {
|
||||
this._disposables.push(this._databaseSelectorTable.onRowSelected(async (e) => {
|
||||
await this.updateValuesOnSelection();
|
||||
}));
|
||||
|
||||
// load unfiltered table list and pre-select list of databases saved in state
|
||||
await this._filterTableList('', this.migrationStateModel._databasesForAssessment);
|
||||
|
||||
const flex = view.modelBuilder.flexContainer().withLayout({
|
||||
flexFlow: 'column',
|
||||
height: '100%',
|
||||
@@ -293,65 +240,60 @@ export class DatabaseSelectorPage extends MigrationWizardPage {
|
||||
return flex;
|
||||
}
|
||||
|
||||
private async _loadDatabaseList(stateMachine: MigrationStateModel, selectedDatabases: string[]): Promise<void> {
|
||||
const providerId = (await stateMachine.getSourceConnectionProfile()).providerId;
|
||||
const metaDataService = azdata.dataprotocol.getProvider<azdata.MetadataProvider>(
|
||||
providerId,
|
||||
azdata.DataProviderType.MetadataProvider);
|
||||
const ownerUri = await azdata.connection.getUriForConnection(
|
||||
stateMachine.sourceConnectionId);
|
||||
const excludeDbs: string[] = [
|
||||
'master',
|
||||
'tempdb',
|
||||
'msdb',
|
||||
'model'
|
||||
];
|
||||
const databaseList = (<azdata.DatabaseInfo[]>await metaDataService
|
||||
.getDatabases(ownerUri))
|
||||
.filter(database => !excludeDbs.includes(database.options.name))
|
||||
|| [];
|
||||
|
||||
databaseList.sort((a, b) => a.options.name.localeCompare(b.options.name));
|
||||
this._dbNames = [];
|
||||
|
||||
this._databaseTableValues = databaseList.map(database => {
|
||||
const databaseName = database.options.name;
|
||||
this._dbNames.push(databaseName);
|
||||
return [
|
||||
selectedDatabases?.indexOf(databaseName) > -1,
|
||||
<azdata.IconColumnCellValue>{
|
||||
icon: IconPathHelper.sqlDatabaseLogo,
|
||||
title: databaseName,
|
||||
},
|
||||
databaseName,
|
||||
database.options.state,
|
||||
database.options.sizeInMB,
|
||||
database.options.lastBackup,
|
||||
];
|
||||
}) || [];
|
||||
}
|
||||
|
||||
public selectedDbs(): string[] {
|
||||
let result: string[] = [];
|
||||
this._databaseSelectorTable?.dataValues?.forEach((arr, index) => {
|
||||
if (arr[0].value === true) {
|
||||
result.push(this._dbNames[index]);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
const rows = this._databaseSelectorTable?.data || [];
|
||||
const databases = this._databaseSelectorTable?.selectedRows || [];
|
||||
return databases
|
||||
.filter(row => row < rows.length)
|
||||
.map(row => rows[row][2])
|
||||
|| [];
|
||||
}
|
||||
|
||||
private async updateValuesOnSelection() {
|
||||
const selectedDatabases = this.selectedDbs() || [];
|
||||
await this._dbCount.updateProperties({
|
||||
'value': constants.DATABASES_SELECTED(this.selectedDbs().length, this._databaseTableValues.length)
|
||||
'value': constants.DATABASES_SELECTED(
|
||||
selectedDatabases.length,
|
||||
this._databaseSelectorTable.data?.length || 0)
|
||||
});
|
||||
this.migrationStateModel._databasesForAssessment = this.selectedDbs();
|
||||
this.migrationStateModel._databasesForAssessment = selectedDatabases;
|
||||
}
|
||||
|
||||
// undo when bug #16445 is fixed
|
||||
private createIconTextCell(icon: IconPath, text: string): string {
|
||||
return text;
|
||||
}
|
||||
// private createIconTextCell(icon: IconPath, text: string): azdata.FlexContainer {
|
||||
// const cellContainer = this._view.modelBuilder.flexContainer().withProps({
|
||||
// CSSStyles: {
|
||||
// 'justify-content': 'left'
|
||||
// }
|
||||
// }).component();
|
||||
|
||||
// const iconComponent = this._view.modelBuilder.image().withProps({
|
||||
// iconPath: icon,
|
||||
// iconWidth: '16px',
|
||||
// iconHeight: '16px',
|
||||
// width: '20px',
|
||||
// height: '20px'
|
||||
// }).component();
|
||||
// cellContainer.addItem(iconComponent, {
|
||||
// flex: '0',
|
||||
// CSSStyles: {
|
||||
// 'width': '32px'
|
||||
// }
|
||||
// });
|
||||
|
||||
// const textComponent = this._view.modelBuilder.text().withProps({
|
||||
// value: text,
|
||||
// title: text,
|
||||
// CSSStyles: {
|
||||
// 'margin': '0px',
|
||||
// 'width': '110px'
|
||||
// }
|
||||
// }).component();
|
||||
|
||||
// cellContainer.addItem(textComponent, {
|
||||
// CSSStyles: {
|
||||
// 'width': 'auto'
|
||||
// }
|
||||
// });
|
||||
|
||||
// return cellContainer;
|
||||
// }
|
||||
// undo when bug #16445 is fixed
|
||||
|
||||
}
|
||||
|
||||
@@ -44,27 +44,21 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
|
||||
protected async registerContent(view: azdata.ModelView): Promise<void> {
|
||||
this._view = view;
|
||||
|
||||
this._statusLoadingComponent = view.modelBuilder.loadingComponent().withItem(this.createDMSDetailsContainer()).component();
|
||||
this._statusLoadingComponent = view.modelBuilder.loadingComponent()
|
||||
.withItem(this.createDMSDetailsContainer())
|
||||
.component();
|
||||
|
||||
this._dmsInfoContainer = this._view.modelBuilder.flexContainer().withItems([
|
||||
this._statusLoadingComponent
|
||||
]).component();
|
||||
this._dmsInfoContainer = this._view.modelBuilder.flexContainer()
|
||||
.withItems([this._statusLoadingComponent])
|
||||
.component();
|
||||
|
||||
const form = view.modelBuilder.formContainer()
|
||||
.withFormItems(
|
||||
[
|
||||
{
|
||||
component: this.migrationServiceDropdownContainer()
|
||||
},
|
||||
{
|
||||
component: this._dmsInfoContainer
|
||||
}
|
||||
]
|
||||
).withProps({
|
||||
CSSStyles: {
|
||||
'padding-top': '0'
|
||||
}
|
||||
}).component();
|
||||
.withFormItems([
|
||||
{ component: this.migrationServiceDropdownContainer() },
|
||||
{ component: this._dmsInfoContainer }
|
||||
])
|
||||
.withProps({ CSSStyles: { 'padding-top': '0' } })
|
||||
.component();
|
||||
|
||||
this._disposables.push(this._view.onClosed(e => {
|
||||
this._disposables.forEach(
|
||||
@@ -419,29 +413,26 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
|
||||
this.migrationStateModel._targetSubscription,
|
||||
this.migrationStateModel._sqlMigrationService.properties.resourceGroup,
|
||||
this.migrationStateModel._sqlMigrationService.location,
|
||||
this.migrationStateModel._sqlMigrationService.name,
|
||||
this.migrationStateModel._sessionId);
|
||||
this.migrationStateModel._sqlMigrationService.name);
|
||||
this.migrationStateModel._sqlMigrationService = migrationService;
|
||||
const migrationServiceMonitoringStatus = await getSqlMigrationServiceMonitoringData(
|
||||
this.migrationStateModel._azureAccount,
|
||||
this.migrationStateModel._targetSubscription,
|
||||
this.migrationStateModel._sqlMigrationService.properties.resourceGroup,
|
||||
this.migrationStateModel._sqlMigrationService.location,
|
||||
this.migrationStateModel._sqlMigrationService!.name,
|
||||
this.migrationStateModel._sessionId);
|
||||
this.migrationStateModel._nodeNames = migrationServiceMonitoringStatus.nodes.map(node => node.nodeName);
|
||||
this.migrationStateModel._sqlMigrationService!.name);
|
||||
this.migrationStateModel._nodeNames = migrationServiceMonitoringStatus.nodes.map(
|
||||
node => node.nodeName);
|
||||
|
||||
const migrationServiceAuthKeys = await getSqlMigrationServiceAuthKeys(
|
||||
this.migrationStateModel._azureAccount,
|
||||
this.migrationStateModel._targetSubscription,
|
||||
this.migrationStateModel._sqlMigrationService.properties.resourceGroup,
|
||||
this.migrationStateModel._sqlMigrationService.location,
|
||||
this.migrationStateModel._sqlMigrationService!.name,
|
||||
this.migrationStateModel._sessionId
|
||||
);
|
||||
this.migrationStateModel._sqlMigrationService!.name);
|
||||
|
||||
this.migrationStateModel._nodeNames = migrationServiceMonitoringStatus.nodes.map((node) => {
|
||||
return node.nodeName;
|
||||
});
|
||||
this.migrationStateModel._nodeNames = migrationServiceMonitoringStatus.nodes.map(
|
||||
node => node.nodeName);
|
||||
|
||||
const state = migrationService.properties.integrationRuntimeState;
|
||||
if (state === 'Online') {
|
||||
@@ -458,25 +449,21 @@ export class IntergrationRuntimePage extends MigrationWizardPage {
|
||||
|
||||
const data = [
|
||||
[
|
||||
{ value: constants.SERVICE_KEY1_LABEL },
|
||||
{ value: migrationServiceAuthKeys.authKey1 },
|
||||
{
|
||||
value: constants.SERVICE_KEY1_LABEL
|
||||
},
|
||||
{
|
||||
value: migrationServiceAuthKeys.authKey1
|
||||
},
|
||||
{
|
||||
value: this._view.modelBuilder.flexContainer().withItems([this._copy1, this._refresh1]).component()
|
||||
value: this._view.modelBuilder.flexContainer()
|
||||
.withItems([this._copy1, this._refresh1])
|
||||
.component()
|
||||
}
|
||||
],
|
||||
[
|
||||
{ value: constants.SERVICE_KEY2_LABEL },
|
||||
{ value: migrationServiceAuthKeys.authKey2 },
|
||||
{
|
||||
value: constants.SERVICE_KEY2_LABEL
|
||||
},
|
||||
{
|
||||
value: migrationServiceAuthKeys.authKey2
|
||||
},
|
||||
{
|
||||
value: this._view.modelBuilder.flexContainer().withItems([this._copy2, this._refresh2]).component()
|
||||
value: this._view.modelBuilder.flexContainer()
|
||||
.withItems([this._copy2, this._refresh2])
|
||||
.component()
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
@@ -186,7 +186,8 @@ export class TargetSelectionPage extends MigrationWizardPage {
|
||||
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) {
|
||||
if (selectedAzureAccount.isStale === false &&
|
||||
this.migrationStateModel._azureAccount.properties.tenants.length > 1) {
|
||||
this.migrationStateModel._accountTenants = selectedAzureAccount.properties.tenants;
|
||||
this._accountTenantDropdown.values = await this.migrationStateModel.getTenantValues();
|
||||
selectDropDownIndex(this._accountTenantDropdown, 0);
|
||||
|
||||
@@ -17,14 +17,17 @@ import { MigrationModePage } from './migrationModePage';
|
||||
import { DatabaseSelectorPage } from './databaseSelectorPage';
|
||||
import { sendSqlMigrationActionEvent, TelemetryAction, TelemetryViews, logError } from '../telemtery';
|
||||
import * as styles from '../constants/styles';
|
||||
import { MigrationLocalStorage, MigrationServiceContext } from '../models/migrationLocalStorage';
|
||||
import { azureResource } from 'azureResource';
|
||||
|
||||
export const WIZARD_INPUT_COMPONENT_WIDTH = '600px';
|
||||
export class WizardController {
|
||||
private _wizardObject!: azdata.window.Wizard;
|
||||
private _model!: MigrationStateModel;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
constructor(private readonly extensionContext: vscode.ExtensionContext, model: MigrationStateModel) {
|
||||
this._model = model;
|
||||
constructor(
|
||||
private readonly extensionContext: vscode.ExtensionContext,
|
||||
private readonly _model: MigrationStateModel,
|
||||
private readonly _onClosedCallback: () => Promise<void>) {
|
||||
}
|
||||
|
||||
public async openWizard(connectionId: string): Promise<void> {
|
||||
@@ -105,13 +108,12 @@ export class WizardController {
|
||||
});
|
||||
|
||||
await Promise.all(wizardSetupPromises);
|
||||
this._model.extensionContext.subscriptions.push(this._wizardObject.onPageChanged(async (pageChangeInfo: azdata.window.WizardPageChangeInfo) => {
|
||||
await pages[0].onPageEnter(pageChangeInfo);
|
||||
}));
|
||||
this._model.extensionContext.subscriptions.push(
|
||||
this._wizardObject.onPageChanged(
|
||||
async (pageChangeInfo: azdata.window.WizardPageChangeInfo) => {
|
||||
await pages[0].onPageEnter(pageChangeInfo);
|
||||
}));
|
||||
|
||||
this._model.extensionContext.subscriptions.push(this._wizardObject.doneButton.onClick(async (e) => {
|
||||
await stateModel.startMigration();
|
||||
}));
|
||||
this._disposables.push(saveAndCloseButton.onClick(async () => {
|
||||
await stateModel.saveInfo(serverName, this._wizardObject.currentPage);
|
||||
await this._wizardObject.close();
|
||||
@@ -134,16 +136,65 @@ export class WizardController {
|
||||
|
||||
this._wizardObject.doneButton.label = loc.START_MIGRATION_TEXT;
|
||||
|
||||
this._disposables.push(this._wizardObject.doneButton.onClick(e => {
|
||||
sendSqlMigrationActionEvent(
|
||||
TelemetryViews.SqlMigrationWizard,
|
||||
TelemetryAction.PageButtonClick,
|
||||
{
|
||||
...this.getTelemetryProps(),
|
||||
'buttonPressed': TelemetryAction.Done,
|
||||
'pageTitle': this._wizardObject.pages[this._wizardObject.currentPage].title
|
||||
}, {});
|
||||
}));
|
||||
this._disposables.push(
|
||||
this._wizardObject.doneButton.onClick(async (e) => {
|
||||
await stateModel.startMigration();
|
||||
await this.updateServiceContext(stateModel);
|
||||
await this._onClosedCallback();
|
||||
|
||||
sendSqlMigrationActionEvent(
|
||||
TelemetryViews.SqlMigrationWizard,
|
||||
TelemetryAction.PageButtonClick,
|
||||
{
|
||||
...this.getTelemetryProps(),
|
||||
'buttonPressed': TelemetryAction.Done,
|
||||
'pageTitle': this._wizardObject.pages[this._wizardObject.currentPage].title
|
||||
}, {});
|
||||
}));
|
||||
}
|
||||
|
||||
private async updateServiceContext(stateModel: MigrationStateModel): Promise<void> {
|
||||
const resourceGroup = this._getResourceGroupByName(
|
||||
stateModel._resourceGroups,
|
||||
stateModel._sqlMigrationService?.properties.resourceGroup);
|
||||
|
||||
const subscription = this._getSubscriptionFromResourceId(
|
||||
stateModel._subscriptions,
|
||||
resourceGroup?.id);
|
||||
|
||||
const location = this._getLocationByValue(
|
||||
stateModel._locations,
|
||||
stateModel._sqlMigrationService?.location);
|
||||
|
||||
return await MigrationLocalStorage.saveMigrationServiceContext(
|
||||
<MigrationServiceContext>{
|
||||
azureAccount: stateModel._azureAccount,
|
||||
tenant: stateModel._azureTenant,
|
||||
subscription: subscription,
|
||||
location: location,
|
||||
resourceGroup: resourceGroup,
|
||||
migrationService: stateModel._sqlMigrationService,
|
||||
});
|
||||
}
|
||||
|
||||
private _getResourceGroupByName(resourceGroups: azureResource.AzureResourceResourceGroup[], displayName?: string): azureResource.AzureResourceResourceGroup | undefined {
|
||||
return resourceGroups.find(rg => rg.name === displayName);
|
||||
}
|
||||
|
||||
private _getLocationByValue(locations: azureResource.AzureLocation[], name?: string): azureResource.AzureLocation | undefined {
|
||||
return locations.find(loc => loc.name === name);
|
||||
}
|
||||
|
||||
private _getSubscriptionFromResourceId(subscriptions: azureResource.AzureResourceSubscription[], resourceId?: string): azureResource.AzureResourceSubscription | undefined {
|
||||
let parts = resourceId?.split('/subscriptions/');
|
||||
if (parts?.length && parts?.length > 1) {
|
||||
parts = parts[1]?.split('/resourcegroups/');
|
||||
if (parts?.length && parts?.length > 0) {
|
||||
const subscriptionId: string = parts[0];
|
||||
return subscriptions.find(sub => sub.id === subscriptionId, 1);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private async sendPageButtonClickEvent(pageChangeInfo: azdata.window.WizardPageChangeInfo) {
|
||||
|
||||
Reference in New Issue
Block a user