Renaming controller to migration service and other bug fixes/ validations. (#14751)

* - Added coming soon message for learn more.
- Potential fix for learn more message

* Renaming of controller to sqlMigrationService

* Surfacing some errors
-Azure account is stale error
-Migration Service creation error.

* Adding refresh azure token validation.

* Fixing some errors pointed during PR
-Fixing property names
-Fixing count

* Fixing migration status
- Adding special error handling for resource not found error
- Deleting unfound migrations from local cache
- Using prefetched migration status for view all

Misc fixes:
- Using SQL server version name instead of number
- Fixing Icons on sku recommendation page
- Fixing table column width in cutover dialog
- Adding spinner button to refresh.

* Fixing all strings in migration service page and dialog

* fixed a string error in create service dialog
This commit is contained in:
Aasim Khan
2021-03-17 14:55:24 -07:00
committed by GitHub
parent 5917f869ef
commit c7cca7e9f0
16 changed files with 558 additions and 418 deletions

View File

@@ -8,7 +8,6 @@ import * as vscode from 'vscode';
import { MigrationContext, MigrationLocalStorage } from '../models/migrationLocalStorage';
import * as loc from '../constants/strings';
import { IconPath, IconPathHelper } from '../constants/iconPathHelper';
import { getDatabaseMigration } from '../api/azure';
import { MigrationStatusDialog } from '../dialog/migrationStatus/migrationStatusDialog';
import { MigrationCategory } from '../dialog/migrationStatus/migrationStatusDialogModel';
@@ -22,12 +21,25 @@ interface IActionMetadata {
const maxWidth = 800;
interface StatusCard {
container: azdata.DivContainer;
count: azdata.TextComponent
}
export class DashboardWidget {
private _migrationStatusCardsContainer!: azdata.FlexContainer;
private _migrationStatusCardLoadingContainer!: azdata.LoadingComponent;
private _view!: azdata.ModelView;
private _inProgressMigrationButton!: StatusCard;
private _successfulMigrationButton!: StatusCard;
private _notStartedMigrationCard!: StatusCard;
private _migrationStatus!: MigrationContext[];
private _viewAllMigrationsButton!: azdata.ButtonComponent;
constructor() {
}
@@ -143,6 +155,10 @@ export class DashboardWidget {
}
}).component();
preRequisiteLearnMoreLink.onDidClick((value) => {
vscode.window.showInformationMessage(loc.COMING_SOON);
});
const preReqContainer = view.modelBuilder.flexContainer().withItems([
preRequisiteListTitle,
preRequisiteListElement
@@ -197,101 +213,51 @@ export class DashboardWidget {
}
private async refreshMigrations(): Promise<void> {
this._viewAllMigrationsButton.enabled = false;
this._migrationStatusCardLoadingContainer.loading = true;
this._migrationStatusCardsContainer.clearItems();
try {
const migrationStatus = await this.getMigrations();
this._migrationStatus = await this.getMigrations();
const inProgressMigrations = migrationStatus.filter((value) => {
const inProgressMigrations = this._migrationStatus.filter((value) => {
const status = value.migrationContext.properties.migrationStatus;
return status === 'InProgress' || status === 'Creating' || status === 'Completing';
});
const inProgressMigrationButton = this.createStatusCard(
IconPathHelper.inProgressMigration,
loc.MIGRATION_IN_PROGRESS,
loc.LOG_SHIPPING_IN_PROGRESS,
inProgressMigrations.length
);
inProgressMigrationButton.onDidClick((e) => {
const dialog = new MigrationStatusDialog(migrationStatus, MigrationCategory.ONGOING);
dialog.initialize();
});
this._migrationStatusCardsContainer.addItem(inProgressMigrationButton);
const successfulMigration = migrationStatus.filter((value) => {
this._inProgressMigrationButton.count.value = inProgressMigrations.length.toString();
const successfulMigration = this._migrationStatus.filter((value) => {
const status = value.migrationContext.properties.migrationStatus;
return status === 'Succeeded';
});
const successfulMigrationButton = this.createStatusCard(
IconPathHelper.completedMigration,
loc.MIGRATION_COMPLETED,
loc.SUCCESSFULLY_MIGRATED_TO_AZURE_SQL,
successfulMigration.length
);
successfulMigrationButton.onDidClick((e) => {
const dialog = new MigrationStatusDialog(migrationStatus, MigrationCategory.SUCCEEDED);
dialog.initialize();
});
this._migrationStatusCardsContainer.addItem(
successfulMigrationButton
);
this._successfulMigrationButton.count.value = successfulMigration.length.toString();
const currentConnection = (await azdata.connection.getCurrentConnection());
const localMigrations = MigrationLocalStorage.getMigrationsBySourceConnections(currentConnection);
const migrationDatabases = new Set(
localMigrations.filter((value) => {
}).map((value) => {
this._migrationStatus.map((value) => {
return value.migrationContext.properties.sourceDatabaseName;
}));
const serverDatabases = await azdata.connection.listDatabases(currentConnection.connectionId);
const notStartedMigrationCard = this.createStatusCard(
IconPathHelper.notStartedMigration,
loc.MIGRATION_NOT_STARTED,
loc.CHOOSE_TO_MIGRATE_TO_AZURE_SQL,
serverDatabases.length - migrationDatabases.size
);
notStartedMigrationCard.onDidClick((e) => {
vscode.window.showInformationMessage('Feature coming soon');
});
this._migrationStatusCardsContainer.addItem(
notStartedMigrationCard
);
this._notStartedMigrationCard.count.value = (serverDatabases.length - migrationDatabases.size).toString();
} catch (error) {
console.log(error);
} finally {
this._migrationStatusCardLoadingContainer.loading = false;
this._viewAllMigrationsButton.enabled = true;
}
}
private async getMigrations(): Promise<MigrationContext[]> {
const currentConnection = (await azdata.connection.getCurrentConnection());
const localMigrations = MigrationLocalStorage.getMigrationsBySourceConnections(currentConnection);
for (let i = 0; i < localMigrations.length; i++) {
const localMigration = localMigrations[i];
try {
localMigration.migrationContext = await getDatabaseMigration(
localMigration.azureAccount,
localMigration.subscription,
localMigration.targetManagedInstance.location,
localMigration.migrationContext.id
);
} catch (e) {
console.log(e);
}
localMigration.sourceConnectionProfile = currentConnection;
}
return localMigrations;
return await MigrationLocalStorage.getMigrationsBySourceConnections(currentConnection, true);
}
private createStatusCard(
cardIconPath: IconPath,
cardTitle: string,
cardDescription: string,
count: number
): azdata.DivContainer {
cardDescription: string
): StatusCard {
const cardTitleText = this._view.modelBuilder.text().withProps({ value: cardTitle }).withProps({
CSSStyles: {
@@ -312,7 +278,7 @@ export class DashboardWidget {
}
}).component();
const cardCount = this._view.modelBuilder.text().withProps({
value: count.toString(),
value: '0',
CSSStyles: {
'font-size': '28px',
'line-height': '36px',
@@ -367,7 +333,10 @@ export class DashboardWidget {
ariaLabel: 'show status',
clickable: true
}).component();
return compositeButton;
return {
container: compositeButton,
count: cardCount
};
}
private async createFooter(view: azdata.ModelView): Promise<azdata.Component> {
@@ -412,7 +381,7 @@ export class DashboardWidget {
}
}).component();
const viewAllButton = view.modelBuilder.hyperlink().withProps({
this._viewAllMigrationsButton = view.modelBuilder.hyperlink().withProps({
label: loc.VIEW_ALL,
url: '',
CSSStyles: {
@@ -420,8 +389,8 @@ export class DashboardWidget {
}
}).component();
viewAllButton.onDidClick(async (e) => {
new MigrationStatusDialog(await this.getMigrations(), MigrationCategory.ALL).initialize();
this._viewAllMigrationsButton.onDidClick(async (e) => {
new MigrationStatusDialog(this._migrationStatus ? this._migrationStatus : await this.getMigrations(), MigrationCategory.ALL).initialize();
});
const refreshButton = view.modelBuilder.hyperlink().withProps({
@@ -433,15 +402,17 @@ export class DashboardWidget {
}
}).component();
refreshButton.onDidClick((e) => {
this.refreshMigrations();
refreshButton.onDidClick(async (e) => {
refreshButton.enabled = false;
await this.refreshMigrations();
refreshButton.enabled = true;
});
const buttonContainer = view.modelBuilder.flexContainer().withLayout({
justifyContent: 'flex-end',
}).component();
buttonContainer.addItem(viewAllButton, {
buttonContainer.addItem(this._viewAllMigrationsButton, {
flex: 'auto',
CSSStyles: {
'border-right': '1px solid ',
@@ -466,9 +437,46 @@ export class DashboardWidget {
flexFlow: 'row'
}).component();
this._migrationStatusCardsContainer = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
this._inProgressMigrationButton = this.createStatusCard(
IconPathHelper.inProgressMigration,
loc.MIGRATION_IN_PROGRESS,
loc.LOG_SHIPPING_IN_PROGRESS
);
this._inProgressMigrationButton.container.onDidClick((e) => {
const dialog = new MigrationStatusDialog(this._migrationStatus, MigrationCategory.ONGOING);
dialog.initialize();
});
this._migrationStatusCardsContainer.addItem(
this._inProgressMigrationButton.container
);
this._successfulMigrationButton = this.createStatusCard(
IconPathHelper.completedMigration,
loc.MIGRATION_COMPLETED,
loc.SUCCESSFULLY_MIGRATED_TO_AZURE_SQL
);
this._successfulMigrationButton.container.onDidClick((e) => {
const dialog = new MigrationStatusDialog(this._migrationStatus, MigrationCategory.SUCCEEDED);
dialog.initialize();
});
this._migrationStatusCardsContainer.addItem(
this._successfulMigrationButton.container
);
this._notStartedMigrationCard = this.createStatusCard(
IconPathHelper.notStartedMigration,
loc.MIGRATION_NOT_STARTED,
loc.CHOOSE_TO_MIGRATE_TO_AZURE_SQL
);
this._notStartedMigrationCard.container.onDidClick((e) => {
vscode.window.showInformationMessage('Feature coming soon');
});
this._migrationStatusCardsContainer.addItem(
this._notStartedMigrationCard.container
);
this._migrationStatusCardLoadingContainer = view.modelBuilder.loadingComponent().withItem(this._migrationStatusCardsContainer).component();
statusContainer.addItem(