mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Migration extensions - UI fixes and vBump (#15199)
* Fixing Migration Cutover Dialog Adding support for target file share Fixing request body Correcting localized strings * Redesigned IR page Adding additional details in migration status dialog * vbump * Fixed the perpetual loading * Fixed duration logic * Adding icon for migration extension * Adding helper commenst to util function localizing some strings logging console errors * enabling cutover buttons for ignored files
This commit is contained in:
@@ -32,6 +32,7 @@ export class MigrationCutoverDialog {
|
||||
private _targetVersion!: azdata.TextComponent;
|
||||
private _migrationStatus!: azdata.TextComponent;
|
||||
private _fullBackupFile!: azdata.TextComponent;
|
||||
private _backupLocation!: azdata.TextComponent;
|
||||
private _lastAppliedLSN!: azdata.TextComponent;
|
||||
private _lastAppliedBackupFile!: azdata.TextComponent;
|
||||
private _lastAppliedBackupTakenOn!: azdata.TextComponent;
|
||||
@@ -44,7 +45,7 @@ export class MigrationCutoverDialog {
|
||||
|
||||
constructor(migration: MigrationContext) {
|
||||
this._model = new MigrationCutoverDialogModel(migration);
|
||||
this._dialogObject = azdata.window.createModelViewDialog(loc.MIGRATION_CUTOVER, 'MigrationCutoverDialog', 1000);
|
||||
this._dialogObject = azdata.window.createModelViewDialog('', 'MigrationCutoverDialog', 1000);
|
||||
}
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
@@ -65,17 +66,17 @@ export class MigrationCutoverDialog {
|
||||
|
||||
flexServer.addItem(sourceDatabase.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '150px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
flexServer.addItem(sourceDetails.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '150px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
flexServer.addItem(sourceVersion.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '150px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -93,26 +94,28 @@ export class MigrationCutoverDialog {
|
||||
|
||||
flexTarget.addItem(targetDatabase.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '230px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
flexTarget.addItem(targetServer.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '230px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
flexTarget.addItem(targetVersion.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '230px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
|
||||
const migrationStatus = this.createInfoField(loc.MIGRATION_STATUS, '');
|
||||
const fullBackupFileOn = this.createInfoField(loc.FULL_BACKUP_FILES, '');
|
||||
const backupLocation = this.createInfoField(loc.BACKUP_LOCATION, '');
|
||||
|
||||
|
||||
this._migrationStatus = migrationStatus.text;
|
||||
this._fullBackupFile = fullBackupFileOn.text;
|
||||
this._backupLocation = backupLocation.text;
|
||||
|
||||
const flexStatus = view.modelBuilder.flexContainer().withLayout({
|
||||
flexFlow: 'column'
|
||||
@@ -120,12 +123,17 @@ export class MigrationCutoverDialog {
|
||||
|
||||
flexStatus.addItem(migrationStatus.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '180px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
flexStatus.addItem(fullBackupFileOn.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '180px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
flexStatus.addItem(backupLocation.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -133,6 +141,7 @@ export class MigrationCutoverDialog {
|
||||
const lastAppliedBackup = this.createInfoField(loc.LAST_APPLIED_BACKUP_FILES, '');
|
||||
const lastAppliedBackupOn = this.createInfoField(loc.LAST_APPLIED_BACKUP_FILES_TAKEN_ON, '');
|
||||
|
||||
|
||||
this._lastAppliedLSN = lastSSN.text;
|
||||
this._lastAppliedBackupFile = lastAppliedBackup.text;
|
||||
this._lastAppliedBackupTakenOn = lastAppliedBackupOn.text;
|
||||
@@ -142,22 +151,22 @@ export class MigrationCutoverDialog {
|
||||
}).component();
|
||||
flexFile.addItem(lastSSN.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '230px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
flexFile.addItem(lastAppliedBackup.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '230px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
flexFile.addItem(lastAppliedBackupOn.flexContainer, {
|
||||
CSSStyles: {
|
||||
'width': '230px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
const flexInfo = view.modelBuilder.flexContainer().withProps({
|
||||
CSSStyles: {
|
||||
'width': '700px'
|
||||
'width': '800px',
|
||||
}
|
||||
}).component();
|
||||
|
||||
@@ -165,7 +174,7 @@ export class MigrationCutoverDialog {
|
||||
flex: '0',
|
||||
CSSStyles: {
|
||||
'flex': '0',
|
||||
'width': '150px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -173,7 +182,7 @@ export class MigrationCutoverDialog {
|
||||
flex: '0',
|
||||
CSSStyles: {
|
||||
'flex': '0',
|
||||
'width': '230px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -181,7 +190,7 @@ export class MigrationCutoverDialog {
|
||||
flex: '0',
|
||||
CSSStyles: {
|
||||
'flex': '0',
|
||||
'width': '180px'
|
||||
'width': '200px'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -240,11 +249,17 @@ export class MigrationCutoverDialog {
|
||||
const formBuilder = view.modelBuilder.formContainer().withFormItems(
|
||||
[
|
||||
{
|
||||
component: await this.migrationContainerHeader()
|
||||
component: this.migrationContainerHeader()
|
||||
},
|
||||
{
|
||||
component: this._view.modelBuilder.separator().withProps({ width: '800px' }).component()
|
||||
},
|
||||
{
|
||||
component: flexInfo
|
||||
},
|
||||
{
|
||||
component: this._view.modelBuilder.separator().withProps({ width: '800px' }).component()
|
||||
},
|
||||
{
|
||||
component: this._fileCount
|
||||
},
|
||||
@@ -267,30 +282,59 @@ export class MigrationCutoverDialog {
|
||||
|
||||
|
||||
private migrationContainerHeader(): azdata.FlexContainer {
|
||||
const header = this._view.modelBuilder.flexContainer().withLayout({
|
||||
const sqlDatbaseLogo = this._view.modelBuilder.image().withProps({
|
||||
iconPath: IconPathHelper.sqlDatabaseLogo,
|
||||
iconHeight: '32px',
|
||||
iconWidth: '32px',
|
||||
width: '32px',
|
||||
height: '32px'
|
||||
}).component();
|
||||
|
||||
this._databaseTitleName = this._view.modelBuilder.text().withProps({
|
||||
CSSStyles: {
|
||||
'font-size': 'large',
|
||||
'width': '400px'
|
||||
'font-size': '16px',
|
||||
'font-weight': 'bold',
|
||||
'margin': '0px'
|
||||
},
|
||||
value: this._model._migration.migrationContext.name
|
||||
value: this._model._migration.migrationContext.properties.sourceDatabaseName
|
||||
}).component();
|
||||
|
||||
header.addItem(this._databaseTitleName, {
|
||||
flex: '0',
|
||||
const databaseSubTitle = this._view.modelBuilder.text().withProps({
|
||||
CSSStyles: {
|
||||
'width': '500px'
|
||||
'font-size': '10px',
|
||||
'margin': '5px 0px'
|
||||
},
|
||||
value: loc.DATABASE
|
||||
}).component();
|
||||
|
||||
const titleContainer = this._view.modelBuilder.flexContainer().withItems([
|
||||
this._databaseTitleName,
|
||||
databaseSubTitle
|
||||
]).withLayout({
|
||||
'flexFlow': 'column'
|
||||
}).component();
|
||||
|
||||
|
||||
const titleLogoContainer = this._view.modelBuilder.flexContainer().component();
|
||||
|
||||
titleLogoContainer.addItem(sqlDatbaseLogo, {
|
||||
flex: '0'
|
||||
});
|
||||
titleLogoContainer.addItem(titleContainer, {
|
||||
CSSStyles: {
|
||||
'margin-left': '5px'
|
||||
}
|
||||
});
|
||||
|
||||
const headerActions = this._view.modelBuilder.flexContainer().withLayout({
|
||||
}).component();
|
||||
|
||||
this._cutoverButton = this._view.modelBuilder.button().withProps({
|
||||
iconPath: IconPathHelper.cutover,
|
||||
iconHeight: '14px',
|
||||
iconWidth: '12px',
|
||||
label: 'Start Cutover',
|
||||
height: '55px',
|
||||
height: '20px',
|
||||
width: '100px',
|
||||
enabled: false
|
||||
}).component();
|
||||
@@ -307,11 +351,8 @@ export class MigrationCutoverDialog {
|
||||
}
|
||||
});
|
||||
|
||||
header.addItem(this._cutoverButton, {
|
||||
flex: '0',
|
||||
CSSStyles: {
|
||||
'width': '100px'
|
||||
}
|
||||
headerActions.addItem(this._cutoverButton, {
|
||||
flex: '0'
|
||||
});
|
||||
|
||||
this._cancelButton = this._view.modelBuilder.button().withProps({
|
||||
@@ -319,19 +360,16 @@ export class MigrationCutoverDialog {
|
||||
iconHeight: '16px',
|
||||
iconWidth: '16px',
|
||||
label: loc.CANCEL_MIGRATION,
|
||||
height: '55px',
|
||||
width: '130px'
|
||||
height: '20px',
|
||||
width: '120px'
|
||||
}).component();
|
||||
|
||||
this._cancelButton.onDidClick((e) => {
|
||||
this.cancelMigration();
|
||||
});
|
||||
|
||||
header.addItem(this._cancelButton, {
|
||||
flex: '0',
|
||||
CSSStyles: {
|
||||
'width': '130px'
|
||||
}
|
||||
headerActions.addItem(this._cancelButton, {
|
||||
flex: '0'
|
||||
});
|
||||
|
||||
|
||||
@@ -340,19 +378,16 @@ export class MigrationCutoverDialog {
|
||||
iconHeight: '16px',
|
||||
iconWidth: '16px',
|
||||
label: 'Refresh',
|
||||
height: '55px',
|
||||
width: '100px'
|
||||
height: '20px',
|
||||
width: '65px'
|
||||
}).component();
|
||||
|
||||
this._refreshButton.onDidClick((e) => {
|
||||
this.refreshStatus();
|
||||
});
|
||||
|
||||
header.addItem(this._refreshButton, {
|
||||
headerActions.addItem(this._refreshButton, {
|
||||
flex: '0',
|
||||
CSSStyles: {
|
||||
'width': '100px'
|
||||
}
|
||||
});
|
||||
|
||||
this._copyDatabaseMigrationDetails = this._view.modelBuilder.button().withProps({
|
||||
@@ -360,8 +395,8 @@ export class MigrationCutoverDialog {
|
||||
iconHeight: '16px',
|
||||
iconWidth: '16px',
|
||||
label: loc.COPY_MIGRATION_DETAILS,
|
||||
height: '55px',
|
||||
width: '100px'
|
||||
height: '20px',
|
||||
width: '150px'
|
||||
}).component();
|
||||
|
||||
this._copyDatabaseMigrationDetails.onDidClick(async (e) => {
|
||||
@@ -378,22 +413,34 @@ export class MigrationCutoverDialog {
|
||||
vscode.window.showInformationMessage(loc.DETAILS_COPIED);
|
||||
});
|
||||
|
||||
header.addItem(this._copyDatabaseMigrationDetails, {
|
||||
headerActions.addItem(this._copyDatabaseMigrationDetails, {
|
||||
flex: '0',
|
||||
CSSStyles: {
|
||||
'width': '100px'
|
||||
'margin-left': '5px'
|
||||
}
|
||||
});
|
||||
|
||||
this._refreshLoader = this._view.modelBuilder.loadingComponent().withProps({
|
||||
loading: false,
|
||||
height: '55px'
|
||||
height: '15px'
|
||||
}).component();
|
||||
|
||||
header.addItem(this._refreshLoader, {
|
||||
headerActions.addItem(this._refreshLoader, {
|
||||
flex: '0',
|
||||
CSSStyles: {
|
||||
'margin-top': '15px'
|
||||
'margin-left': '16px'
|
||||
}
|
||||
});
|
||||
|
||||
const header = this._view.modelBuilder.flexContainer().withItems([
|
||||
titleLogoContainer
|
||||
]).withLayout({
|
||||
flexFlow: 'column'
|
||||
}).component();
|
||||
|
||||
header.addItem(headerActions, {
|
||||
'CSSStyles': {
|
||||
'margin-top': '16px'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -461,19 +508,19 @@ export class MigrationCutoverDialog {
|
||||
|
||||
this._sourceDatabase.value = sourceDatabaseName;
|
||||
this._serverName.value = sqlServerName;
|
||||
this._serverVersion.value = `${sqlServerVersion}
|
||||
${sqlServerInfo.serverVersion}`;
|
||||
this._serverVersion.value = `${sqlServerVersion} ${sqlServerInfo.serverVersion}`;
|
||||
|
||||
this._targetDatabase.value = targetDatabaseName;
|
||||
this._targetServer.value = targetServerName;
|
||||
this._targetVersion.value = targetServerVersion;
|
||||
|
||||
this._migrationStatus.value = migrationStatusTextValue;
|
||||
this._fullBackupFile.value = fullBackupFileName!;
|
||||
this._migrationStatus.value = migrationStatusTextValue ?? '---';
|
||||
this._fullBackupFile.value = fullBackupFileName! ?? '-';
|
||||
this._backupLocation.value = this._model._migration.migrationContext.properties.backupConfiguration?.sourceLocation?.fileShare?.path! ?? '-';
|
||||
|
||||
this._lastAppliedLSN.value = lastAppliedSSN!;
|
||||
this._lastAppliedBackupFile.value = this._model.migrationStatus.properties.migrationStatusDetails?.lastRestoredFilename;
|
||||
this._lastAppliedBackupTakenOn.value = lastAppliedBackupFileTakenOn! ? new Date(lastAppliedBackupFileTakenOn).toLocaleString() : '';
|
||||
this._lastAppliedLSN.value = lastAppliedSSN! ?? '-';
|
||||
this._lastAppliedBackupFile.value = this._model.migrationStatus.properties.migrationStatusDetails?.lastRestoredFilename ?? '-';
|
||||
this._lastAppliedBackupTakenOn.value = lastAppliedBackupFileTakenOn! ? new Date(lastAppliedBackupFileTakenOn).toLocaleString() : '-';
|
||||
|
||||
this._fileCount.value = loc.ACTIVE_BACKUP_FILES_ITEMS(tableData.length);
|
||||
|
||||
@@ -495,7 +542,7 @@ export class MigrationCutoverDialog {
|
||||
}
|
||||
|
||||
if (migrationStatusTextValue === MigrationStatus.InProgress) {
|
||||
const fileNotRestored = await tableData.some(file => file.status !== 'Restored');
|
||||
const fileNotRestored = await tableData.some(file => file.status !== 'Restored' && file.status !== 'Ignored');
|
||||
this._cutoverButton.enabled = !fileNotRestored;
|
||||
this._cancelButton.enabled = true;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user