Surfacing migration errors in dashboard (#14956)

* vbumping migration

* Adding 2 new icons cancel and warning

* Fixed help link display text in assessments

* Adding summary page redesign and resource name validations

* Made headings bold

* Fixed sku recommendation page styling
Added check item for assessment

* Validating account dropdown after token refresh

* Renamed cutover to mode

* cutover to mode renaming changes.

* Converting to details api for more warnings

* Added target database name and fixed cancel icon

* Surfacing warning info in dashboard.

* Consolidated fetch migrations logic
Localilzed some strings
Surface migration errors in dashboard and status page
Table redesign in status dialog
Fixed a major bug that happens when multiple dashboards are opened due to class variable sharing

* removing console count

* Fixing regex for SQL MI database names

* Allowing spaces in regex
This commit is contained in:
Aasim Khan
2021-04-02 18:49:34 -07:00
committed by GitHub
parent fde5caa9a4
commit 684dfc9760
19 changed files with 433 additions and 151 deletions

View File

@@ -6,11 +6,10 @@
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { IconPathHelper } from '../../constants/iconPathHelper';
import { MigrationContext } from '../../models/migrationLocalStorage';
import { MigrationContext, MigrationLocalStorage } from '../../models/migrationLocalStorage';
import { MigrationCutoverDialog } from '../migrationCutover/migrationCutoverDialog';
import { MigrationCategory, MigrationStatusDialogModel } from './migrationStatusDialogModel';
import * as loc from '../../constants/strings';
import { getDatabaseMigration } from '../../api/azure';
export class MigrationStatusDialog {
private _model: MigrationStatusDialogModel;
private _dialogObject!: azdata.window.Dialog;
@@ -81,7 +80,7 @@ export class MigrationStatusDialog {
dark: IconPathHelper.refresh.dark
},
iconHeight: '16px',
iconWidth: '16px',
iconWidth: '20px',
height: '30px',
label: 'Refresh',
}).component();
@@ -90,7 +89,11 @@ export class MigrationStatusDialog {
this.refreshTable();
});
const flexContainer = this._view.modelBuilder.flexContainer().component();
const flexContainer = this._view.modelBuilder.flexContainer().withProps({
CSSStyles: {
'justify-content': 'left'
}
}).component();
flexContainer.addItem(this._searchBox, {
flex: '0'
@@ -109,7 +112,10 @@ export class MigrationStatusDialog {
}).component();
flexContainer.addItem(this._refreshLoader, {
flex: '0'
flex: '0 0 auto',
CSSStyles: {
'margin-left': '20px'
}
});
return flexContainer;
@@ -128,7 +134,7 @@ export class MigrationStatusDialog {
return new Date(m1.migrationContext.properties.startedOn) > new Date(m2.migrationContext.properties.startedOn) ? -1 : 1;
});
migrations.forEach((migration) => {
migrations.forEach((migration, index) => {
const migrationRow: azdata.DeclarativeTableCellValue[] = [];
const databaseHyperLink = this._view.modelBuilder.hyperlink().withProps({
@@ -142,10 +148,6 @@ export class MigrationStatusDialog {
value: databaseHyperLink,
});
migrationRow.push({
value: migration.migrationContext.properties.migrationStatus ? migration.migrationContext.properties.migrationStatus : migration.migrationContext.properties.provisioningState
});
const targetMigrationIcon = this._view.modelBuilder.image().withProps({
iconPath: (migration.targetManagedInstance.type === 'microsoft.sql/managedinstances') ? IconPathHelper.sqlMiLogo : IconPathHelper.sqlVmLogo,
iconWidth: '16px',
@@ -163,7 +165,7 @@ export class MigrationStatusDialog {
const sqlMigrationContainer = this._view.modelBuilder.flexContainer().withProps({
CSSStyles: {
'justify-content': 'center'
'justify-content': 'left'
}
}).component();
sqlMigrationContainer.addItem(targetMigrationIcon, {
@@ -186,6 +188,27 @@ export class MigrationStatusDialog {
value: loc.ONLINE
});
let migrationStatus = migration.migrationContext.properties.migrationStatus ? migration.migrationContext.properties.migrationStatus : migration.migrationContext.properties.provisioningState;
let warningCount = 0;
if (migration.asyncOperationResult?.error?.message) {
warningCount++;
}
if (migration.migrationContext.properties.migrationFailureError?.message) {
warningCount++;
}
if (migration.migrationContext.properties.migrationStatusDetails?.fileUploadBlockingErrors) {
warningCount += migration.migrationContext.properties.migrationStatusDetails?.fileUploadBlockingErrors.length;
}
if (migration.migrationContext.properties.migrationStatusDetails?.restoreBlockingReason) {
warningCount++;
}
migrationRow.push({
value: loc.STATUS_WARNING_COUNT(migrationStatus, warningCount)
});
migrationRow.push({
value: (migration.migrationContext.properties.startedOn) ? new Date(migration.migrationContext.properties.startedOn).toLocaleString() : '---'
});
@@ -202,21 +225,28 @@ export class MigrationStatusDialog {
}
}
private refreshTable(): void {
private async refreshTable(): Promise<void> {
this._refreshLoader.loading = true;
this._model._migrations.forEach(async (migration) => {
migration.migrationContext = await getDatabaseMigration(
migration.azureAccount,
migration.subscription,
migration.targetManagedInstance.location,
migration.migrationContext.id
);
});
const currentConnection = await azdata.connection.getCurrentConnection();
this._model._migrations = await MigrationLocalStorage.getMigrationsBySourceConnections(currentConnection, true);
this.populateMigrationTable();
this._refreshLoader.loading = false;
}
private createStatusTable(): azdata.DeclarativeTableComponent {
const rowCssStyle: azdata.CssStyles = {
'border': 'none',
'text-align': 'left',
'border-bottom': '1px solid'
};
const headerCssStyles: azdata.CssStyles = {
'border': 'none',
'text-align': 'left',
'border-bottom': '1px solid',
'font-weight': 'bold'
};
this._statusTable = this._view.modelBuilder.declarativeTable().withProps({
columns: [
{
@@ -224,54 +254,48 @@ export class MigrationStatusDialog {
valueType: azdata.DeclarativeDataType.component,
width: '100px',
isReadOnly: true,
rowCssStyles: {
'text-align': 'center'
}
},
{
displayName: loc.MIGRATION_STATUS,
valueType: azdata.DeclarativeDataType.string,
width: '150px',
isReadOnly: true,
rowCssStyles: {
'text-align': 'center'
}
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles
},
{
displayName: loc.TARGET_AZURE_SQL_INSTANCE_NAME,
valueType: azdata.DeclarativeDataType.component,
width: '300px',
width: '170px',
isReadOnly: true,
rowCssStyles: {
'text-align': 'center'
}
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles
},
{
displayName: loc.MIGRATION_MODE,
valueType: azdata.DeclarativeDataType.string,
width: '100px',
isReadOnly: true,
rowCssStyles: {
'text-align': 'center'
}
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles
},
{
displayName: loc.MIGRATION_STATUS,
valueType: azdata.DeclarativeDataType.string,
width: '150px',
isReadOnly: true,
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles
},
{
displayName: loc.START_TIME,
valueType: azdata.DeclarativeDataType.string,
width: '150px',
width: '120px',
isReadOnly: true,
rowCssStyles: {
'text-align': 'center'
}
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles
},
{
displayName: loc.FINISH_TIME,
valueType: azdata.DeclarativeDataType.string,
width: '150px',
width: '120px',
isReadOnly: true,
rowCssStyles: {
'text-align': 'center'
}
rowCssStyles: rowCssStyle,
headerCssStyles: headerCssStyles
}
]
}).component();