diff --git a/extensions/sql-migration/images/sqlDatabase.svg b/extensions/sql-migration/images/sqlDatabase.svg
new file mode 100644
index 0000000000..01110e8f28
--- /dev/null
+++ b/extensions/sql-migration/images/sqlDatabase.svg
@@ -0,0 +1,23 @@
+
diff --git a/extensions/sql-migration/images/sqlDatabaseWarning.svg b/extensions/sql-migration/images/sqlDatabaseWarning.svg
new file mode 100644
index 0000000000..e30729f414
--- /dev/null
+++ b/extensions/sql-migration/images/sqlDatabaseWarning.svg
@@ -0,0 +1,26 @@
+
diff --git a/extensions/sql-migration/images/sqlServer.svg b/extensions/sql-migration/images/sqlServer.svg
new file mode 100644
index 0000000000..192ca0d058
--- /dev/null
+++ b/extensions/sql-migration/images/sqlServer.svg
@@ -0,0 +1,19 @@
+
diff --git a/extensions/sql-migration/src/constants/iconPathHelper.ts b/extensions/sql-migration/src/constants/iconPathHelper.ts
index 418db19689..2dfb61f865 100644
--- a/extensions/sql-migration/src/constants/iconPathHelper.ts
+++ b/extensions/sql-migration/src/constants/iconPathHelper.ts
@@ -24,6 +24,9 @@ export class IconPathHelper {
public static notStartedMigration: IconPath;
public static sqlVmLogo: IconPath;
public static sqlMiLogo: IconPath;
+ public static sqlServerLogo: IconPath;
+ public static sqlDatabaseLogo: IconPath;
+ public static sqlDatabaseWarningLogo: IconPath;
public static setExtensionContext(context: vscode.ExtensionContext) {
IconPathHelper.copy = {
@@ -78,5 +81,17 @@ export class IconPathHelper {
light: context.asAbsolutePath('images/sqlVM.svg'),
dark: context.asAbsolutePath('images/sqlVM.svg')
};
+ IconPathHelper.sqlServerLogo = {
+ light: context.asAbsolutePath('images/sqlServer.svg'),
+ dark: context.asAbsolutePath('images/sqlServer.svg')
+ };
+ IconPathHelper.sqlDatabaseLogo = {
+ light: context.asAbsolutePath('images/sqlDatabase.svg'),
+ dark: context.asAbsolutePath('images/sqlDatabase.svg')
+ };
+ IconPathHelper.sqlDatabaseWarningLogo = {
+ light: context.asAbsolutePath('images/sqlDatabaseWarning.svg'),
+ dark: context.asAbsolutePath('images/sqlDatabaseWarning.svg')
+ };
}
}
diff --git a/extensions/sql-migration/src/constants/strings.ts b/extensions/sql-migration/src/constants/strings.ts
index 1692dd2a09..7f8b3a4a21 100644
--- a/extensions/sql-migration/src/constants/strings.ts
+++ b/extensions/sql-migration/src/constants/strings.ts
@@ -274,6 +274,28 @@ export function ENTER_YOUR_SQL_CREDS(sqlServerName: string) {
return localize('sql.migration.enter.your.sql.creds', "Enter the credentials for source SQL server instance ‘{0}’", sqlServerName);
}
export const USERNAME = localize('sql.migration.username', "Username");
+
+//Assessment Dialog
+export const DATABASES = localize('sql.migration.databases', "Databases");
+export const ISSUES = localize('sql.migration.issues', "Issues");
+export const SEARCH = localize('sql.migration.search', "Search");
+export const INSTANCE = localize('sql.migration.instance', "Instance");
+export const WARNINGS = localize('sql.migration.warnings', "Warnings");
+export const IMPACTED_OBJECTS = localize('sql.migration.impacted.objects', "Impacted Objects");
+export const OBJECT_DETAILS = localize('sql.migration.object.details', "Object details");
+export const TYPES_LABEL = localize('sql.migration.type.label', "Type:");
+export const NAMES_LABEL = localize('sql.migration.name.label', "Names:");
+export const DESCRIPTION = localize('sql.migration.description', "Description");
+export const RECOMMENDATION = localize('sql.migration.recommendation', "Recommendation");
+export const MORE_INFO = localize('sql.migration.more.info', "More Info");
+export const TARGET_PLATFORM = localize('sql.migration.target.platform', "Target Platform");
+export const WARNINGS_DETAILS = localize('sql.migration.warnings.details', "Warnings Details");
+export function IMPACT_OBJECT_TYPE(objectType: string): string {
+ return localize('sql.migration.impact.object.type', "Type: {0}", objectType);
+}
+export function IMPACT_OBJECT_NAME(objectName: string): string {
+ return localize('sql.migration.impact.object.name', "Name: {0}", objectName);
+}
export const AUTHENTICATION_TYPE = localize('sql.migration.authentication.type', "Authentication Type");
export const SQL_LOGIN = localize('sql.migration.sql.login', "SQL Login");
export const WINDOWS_AUTHENTICATION = localize('sql.migration.windows.auth', "Windows Authentication");
diff --git a/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts b/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts
index 7b9e16ec66..9ce8100f57 100644
--- a/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts
+++ b/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts
@@ -4,29 +4,47 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import { SqlMigrationAssessmentResultItem, SqlMigrationImpactedObjectInfo } from '../../../../mssql/src/mssql';
+import { IconPath, IconPathHelper } from '../../constants/iconPathHelper';
import { MigrationStateModel, MigrationTargetType } from '../../models/stateMachine';
+import * as constants from '../../constants/strings';
const styleLeft: azdata.CssStyles = {
'border': 'none',
'text-align': 'left',
'white-space': 'nowrap',
'text-overflow': 'ellipsis',
- 'overflow': 'hidden'
+ 'overflow': 'hidden',
};
const styleRight: azdata.CssStyles = {
'border': 'none',
'text-align': 'right',
'white-space': 'nowrap',
'text-overflow': 'ellipsis',
- 'overflow': 'hidden'
+ 'overflow': 'hidden',
+};
+
+const headerLeft: azdata.CssStyles = {
+ 'border': 'none',
+ 'text-align': 'left',
+ 'white-space': 'nowrap',
+ 'text-overflow': 'ellipsis',
+ 'overflow': 'hidden',
+ 'border-bottom': '1px solid'
+};
+const headerRight: azdata.CssStyles = {
+ 'border': 'none',
+ 'text-align': 'right',
+ 'white-space': 'nowrap',
+ 'text-overflow': 'ellipsis',
+ 'overflow': 'hidden',
+ 'border-bottom': '1px solid'
};
export class SqlDatabaseTree {
-
+ private _view!: azdata.ModelView;
private _instanceTable!: azdata.DeclarativeTableComponent;
private _databaseTable!: azdata.DeclarativeTableComponent;
private _assessmentResultsTable!: azdata.DeclarativeTableComponent;
-
private _impactedObjectsTable!: azdata.DeclarativeTableComponent;
private _recommendation!: azdata.TextComponent;
@@ -44,6 +62,9 @@ export class SqlDatabaseTree {
private _selectedIssue!: SqlMigrationAssessmentResultItem;
private _selectedObject!: SqlMigrationImpactedObjectInfo;
+ private _serverName!: string;
+ private _dbNames!: string[];
+
constructor(
private _model: MigrationStateModel,
private _targetType: MigrationTargetType
@@ -51,6 +72,7 @@ export class SqlDatabaseTree {
}
async createComponent(view: azdata.ModelView, dbs: string[]): Promise {
+ this._view = view;
const component = view.modelBuilder.flexContainer().withLayout({
height: '100%',
flexFlow: 'column'
@@ -60,14 +82,15 @@ export class SqlDatabaseTree {
},
}).component();
- component.addItem(this.createSearchComponent(view), { flex: '0 0 auto' });
- component.addItem(this.createInstanceComponent(view), { flex: '0 0 auto' });
- component.addItem(this.createDatabaseComponent(view, dbs), { flex: '1 1 auto', CSSStyles: { 'overflow-y': 'auto' } });
+ component.addItem(this.createSearchComponent(), { flex: '0 0 auto' });
+ component.addItem(this.createInstanceComponent(), { flex: '0 0 auto' });
+ component.addItem(this.createDatabaseComponent(dbs), { flex: '1 1 auto', CSSStyles: { 'overflow-y': 'auto' } });
return component;
}
- private createDatabaseComponent(view: azdata.ModelView, dbs: string[]): azdata.DivContainer {
- this._databaseTable = view.modelBuilder.declarativeTable().withProps(
+ private createDatabaseComponent(dbs: string[]): azdata.DivContainer {
+
+ this._databaseTable = this._view.modelBuilder.declarativeTable().withProps(
{
enableRowSelection: true,
width: 200,
@@ -81,22 +104,21 @@ export class SqlDatabaseTree {
width: 20,
isReadOnly: false,
showCheckAll: true,
- headerCssStyles: styleLeft,
- ariaLabel: 'Database Migration Check' // TODO localize
+ headerCssStyles: headerLeft,
},
{
- displayName: 'Databases', // TODO localize
- valueType: azdata.DeclarativeDataType.string,
+ displayName: constants.DATABASES,
+ valueType: azdata.DeclarativeDataType.component,
width: 100,
isReadOnly: true,
- headerCssStyles: styleLeft
+ headerCssStyles: headerLeft
},
{
- displayName: 'Issues', // Incidents
+ displayName: constants.ISSUES,
valueType: azdata.DeclarativeDataType.string,
width: 30,
isReadOnly: true,
- headerCssStyles: styleRight,
+ headerCssStyles: headerRight,
}
]
}
@@ -106,76 +128,69 @@ export class SqlDatabaseTree {
this._databaseTable.focus();
this._activeIssues = this._model._assessmentResults?.databaseAssessments[row].issues;
this._selectedIssue = this._model._assessmentResults?.databaseAssessments[row].issues[0];
- this._dbName.value = this._databaseTable.dataValues![row][1].value;
+ this._dbName.value = this._dbNames[row];
this.refreshResults();
});
- const tableContainer = view.modelBuilder.divContainer().withItems([this._databaseTable]).withProps({
+ const tableContainer = this._view.modelBuilder.divContainer().withItems([this._databaseTable]).withProps({
CSSStyles: {
'width': '200px',
- 'margin-left': '15px',
- 'margin-right': '5px',
- 'margin-bottom': '10px'
+ 'margin': '0px 8px 0px 34px'
}
}).component();
return tableContainer;
}
- private createSearchComponent(view: azdata.ModelView): azdata.DivContainer {
- let resourceSearchBox = view.modelBuilder.inputBox().withProperties({
- placeHolder: 'Search',
+ private createSearchComponent(): azdata.DivContainer {
+ let resourceSearchBox = this._view.modelBuilder.inputBox().withProps({
+ placeHolder: constants.SEARCH,
+ width: 200
}).component();
- const searchContainer = view.modelBuilder.divContainer().withItems([resourceSearchBox]).withProps({
+ const searchContainer = this._view.modelBuilder.divContainer().withItems([resourceSearchBox]).withProps({
CSSStyles: {
'width': '200px',
- 'margin-left': '15px',
- 'margin-right': '5px',
- 'margin-bottom': '10px'
+ 'margin': '32px 8px 0px 34px'
}
}).component();
return searchContainer;
}
- private createInstanceComponent(view: azdata.ModelView): azdata.DivContainer {
- this._instanceTable = view.modelBuilder.declarativeTable().withProps(
+ private createInstanceComponent(): azdata.DivContainer {
+ this._instanceTable = this._view.modelBuilder.declarativeTable().withProps(
{
enableRowSelection: true,
width: 200,
columns: [
{
- displayName: 'Instance',
- valueType: azdata.DeclarativeDataType.string,
+ displayName: constants.INSTANCE,
+ valueType: azdata.DeclarativeDataType.component,
width: 150,
isReadOnly: true,
- headerCssStyles: styleLeft,
- ariaLabel: 'Database Migration Check' // TODO localize
+ headerCssStyles: headerLeft
},
{
- displayName: 'Warnings', // TODO localize
+ displayName: constants.WARNINGS,
valueType: azdata.DeclarativeDataType.string,
width: 50,
isReadOnly: true,
- headerCssStyles: styleRight
+ headerCssStyles: headerRight
}
],
-
}).component();
- const instanceContainer = view.modelBuilder.divContainer().withItems([this._instanceTable]).withProps({
+ const instanceContainer = this._view.modelBuilder.divContainer().withItems([this._instanceTable]).withProps({
CSSStyles: {
'width': '200px',
- 'margin-left': '15px',
- 'margin-right': '5px',
- 'margin-bottom': '10px'
+ 'margin': '19px 8px 0px 34px'
}
}).component();
this._instanceTable.onRowSelected((e) => {
this._activeIssues = this._model._assessmentResults?.issues;
this._selectedIssue = this._model._assessmentResults?.issues[0];
- this._dbName.value = this._instanceTable.dataValues![0][0].value;
+ this._dbName.value = this._serverName;
this.refreshResults();
});
@@ -183,17 +198,16 @@ export class SqlDatabaseTree {
}
async createComponentResult(view: azdata.ModelView): Promise {
+ this._view = view;
+ const topContainer = this.createTopContainer();
+ const bottomContainer = this.createBottomContainer();
- const topContainer = this.createTopContainer(view);
- const bottomContainer = this.createBottomContainer(view);
-
- const container = view.modelBuilder.flexContainer().withLayout({
+ const container = this._view.modelBuilder.flexContainer().withLayout({
flexFlow: 'column',
height: '100%'
}).withProps({
CSSStyles: {
- 'margin-left': '10px',
- 'margin-right': '15px',
+ 'margin': '32px 0px 0px 18px',
'overflow-y': 'hidden'
}
}).component();
@@ -205,25 +219,42 @@ export class SqlDatabaseTree {
}
- private createTopContainer(view: azdata.ModelView): azdata.FlexContainer {
- const title = this.createTitleComponent(view);
- const impact = this.createPlatformComponent(view);
- const recommendation = this.createRecommendationComponent(view);
- const assessmentResults = this.createAssessmentResultsTitle(view);
+ private createTopContainer(): azdata.FlexContainer {
+ const title = this.createTitleComponent();
+ const impact = this.createPlatformComponent();
+ const recommendation = this.createRecommendationComponent();
+ const assessmentResultsTitle = this.createAssessmentResultsTitle();
+ const assessmentDetailsTitle = this.createAssessmentDetailsTitle();
- const container = view.modelBuilder.flexContainer().withItems([title, impact, recommendation, assessmentResults]).withLayout({
+ const titleContainer = this._view.modelBuilder.flexContainer().withItems([
+ ]).withProps({
+ CSSStyles: {
+ 'border-bottom': 'solid 1px',
+ 'width': '800px'
+ }
+ }).component();
+
+ titleContainer.addItem(assessmentResultsTitle, {
+ flex: '0 0 auto'
+ });
+
+ titleContainer.addItem(assessmentDetailsTitle, {
+ flex: '0 0 auto'
+ });
+
+ const container = this._view.modelBuilder.flexContainer().withItems([title, impact, recommendation, titleContainer]).withLayout({
flexFlow: 'column'
}).component();
return container;
}
- private createBottomContainer(view: azdata.ModelView): azdata.FlexContainer {
+ private createBottomContainer(): azdata.FlexContainer {
- const impactedObjects = this.createImpactedObjectsTable(view);
- const rightContainer = this.createAssessmentContainer(view);
+ const impactedObjects = this.createImpactedObjectsTable();
+ const rightContainer = this.createAssessmentContainer();
- const container = view.modelBuilder.flexContainer().withLayout({
+ const container = this._view.modelBuilder.flexContainer().withLayout({
flexFlow: 'row',
height: '100%'
}).withProps({
@@ -237,189 +268,196 @@ export class SqlDatabaseTree {
return container;
}
- private createAssessmentContainer(view: azdata.ModelView): azdata.FlexContainer {
- const title = this.createAssessmentTitle(view);
+ private createAssessmentContainer(): azdata.FlexContainer {
+ const title = this.createAssessmentTitle();
- const bottomContainer = this.createDescriptionContainer(view);
+ const bottomContainer = this.createDescriptionContainer();
- const container = view.modelBuilder.flexContainer().withItems([title, bottomContainer]).withLayout({
+ const container = this._view.modelBuilder.flexContainer().withItems([title, bottomContainer]).withLayout({
flexFlow: 'column'
}).withProps({
CSSStyles: {
- 'margin-left': '10px'
+ 'margin-left': '24px'
}
}).component();
return container;
}
- private createDescriptionContainer(view: azdata.ModelView): azdata.FlexContainer {
- const description = this.createDescription(view);
- const impactedObjects = this.createImpactedObjectsDescription(view);
+ private createDescriptionContainer(): azdata.FlexContainer {
+ const description = this.createDescription();
+ const impactedObjects = this.createImpactedObjectsDescription();
- const container = view.modelBuilder.flexContainer().withLayout({
+ const container = this._view.modelBuilder.flexContainer().withLayout({
flexFlow: 'row'
}).withProps({
CSSStyles: {
'height': '100%'
}
}).component();
- container.addItem(description, { flex: '1 1 auto', CSSStyles: { 'width': '50%', 'margin-right': '10px' } });
- container.addItem(impactedObjects, { flex: '1 1 auto', CSSStyles: { 'width': '50%', 'margin-left': '10px' } });
+ container.addItem(description, { flex: '0 0 auto', CSSStyles: { 'width': '200px', 'margin-right': '35px' } });
+ container.addItem(impactedObjects, { flex: '0 0 auto', CSSStyles: { 'width': '280px' } });
return container;
}
- private createImpactedObjectsDescription(view: azdata.ModelView): azdata.FlexContainer {
- const impactedObjectsTitle = view.modelBuilder.text().withProperties({
- value: 'Impacted Objects',
+ private createImpactedObjectsDescription(): azdata.FlexContainer {
+ const impactedObjectsTitle = this._view.modelBuilder.text().withProps({
+ value: constants.IMPACTED_OBJECTS,
CSSStyles: {
- 'font-size': '14px'
+ 'font-size': '14px',
+ 'width': '280px',
+ 'margin': '10px 0px 0px 0px'
}
}).component();
- const headerStyle: azdata.CssStyles = {
- 'border': 'none',
- 'text-align': 'left'
- };
const rowStyle: azdata.CssStyles = {
'border': 'none',
- 'text-align': 'left'
+ 'text-align': 'left',
+ 'border-bottom': '1px solid'
};
- this._impactedObjectsTable = view.modelBuilder.declarativeTable().withProps(
+ this._impactedObjectsTable = this._view.modelBuilder.declarativeTable().withProps(
{
enableRowSelection: true,
width: '100%',
columns: [
{
- displayName: 'Type', // TODO localize
+ displayName: constants.TYPE,
valueType: azdata.DeclarativeDataType.string,
- width: '100%',
+ width: '120px',
isReadOnly: true,
- headerCssStyles: headerStyle,
+ headerCssStyles: headerLeft,
rowCssStyles: rowStyle
},
{
- displayName: 'Name', // TODO localize
+ displayName: constants.NAME,
valueType: azdata.DeclarativeDataType.string,
- width: '100%',
+ width: '130px',
isReadOnly: true,
- headerCssStyles: headerStyle,
+ headerCssStyles: headerLeft,
rowCssStyles: rowStyle
},
],
dataValues: [
[
{
- value: 'Agent Job'
+ value: ''
},
{
- value: 'Process Monthly Usage'
+ value: ''
}
]
- ]
+ ],
+ CSSStyles: {
+ 'margin-top': '12px'
+ }
}
).component();
-
this._impactedObjectsTable.onRowSelected(({ row }) => {
this._selectedObject = this._impactedObjects[row];
this.refreshImpactedObject();
});
-
-
-
- const objectDetailsTitle = view.modelBuilder.text().withProperties({
- value: 'Object details',
+ const objectDetailsTitle = this._view.modelBuilder.text().withProps({
+ value: constants.OBJECT_DETAILS,
CSSStyles: {
- 'margin-top': '10px',
- 'font-size': '14px',
- 'margin-block-start': '0px',
- 'margin-block-end': '0px'
+ 'font-size': '13px',
+ 'line-size': '18px',
+ 'margin': '12px 0px 0px 0px'
}
}).component();
- this._objectDetailsType = view.modelBuilder.text().withProperties({
- value: 'Type:',
+ this._objectDetailsType = this._view.modelBuilder.text().withProps({
+ value: constants.TYPES_LABEL,
CSSStyles: {
- 'font-size': '14px',
- 'margin-block-start': '0px',
- 'margin-block-end': '0px'
+ 'font-size': '13px',
+ 'line-size': '18px',
+ 'margin': '5px 0px 0px 0px'
}
}).component();
- this._objectDetailsName = view.modelBuilder.text().withProperties({
- value: 'Name:',
+ this._objectDetailsName = this._view.modelBuilder.text().withProps({
+ value: constants.NAMES_LABEL,
CSSStyles: {
- 'font-size': '14px',
- 'margin-block-start': '0px',
- 'margin-block-end': '0px'
+ 'font-size': '13px',
+ 'line-size': '18px',
+ 'margin': '5px 0px 0px 0px'
}
}).component();
- this._objectDetailsSample = view.modelBuilder.text().withProperties({
- value: 'Sample',
+ this._objectDetailsSample = this._view.modelBuilder.text().withProps({
+ value: '',
CSSStyles: {
- 'font-size': '14px',
- 'margin-block-start': '0px',
- 'margin-block-end': '0px'
+ 'font-size': '13px',
+ 'line-size': '18px',
+ 'margin': '5px 0px 0px 0px'
}
}).component();
- const container = view.modelBuilder.flexContainer().withItems([impactedObjectsTitle, this._impactedObjectsTable, objectDetailsTitle, this._objectDetailsType, this._objectDetailsName, this._objectDetailsSample]).withLayout({
+ const container = this._view.modelBuilder.flexContainer().withItems([impactedObjectsTitle, this._impactedObjectsTable, objectDetailsTitle, this._objectDetailsType, this._objectDetailsName, this._objectDetailsSample]).withLayout({
flexFlow: 'column'
}).component();
return container;
}
- private createDescription(view: azdata.ModelView): azdata.FlexContainer {
- const descriptionTitle = view.modelBuilder.text().withProperties({
- value: 'Description',
+ private createDescription(): azdata.FlexContainer {
+ const descriptionTitle = this._view.modelBuilder.text().withProps({
+ value: constants.DESCRIPTION,
CSSStyles: {
'font-size': '14px',
- 'margin-block-start': '0px',
- 'margin-block-end': '0px'
+ 'width': '200px',
+ 'margin': '10px 35px 0px 0px'
}
}).component();
- this._descriptionText = view.modelBuilder.text().withProperties({
- value: 'It is a job step that runs a PowerShell scripts.',
- CSSStyles: {
- 'font-size': '12px'
- }
- }).component();
-
- const recommendationTitle = view.modelBuilder.text().withProperties({
- value: 'Recommendation',
- CSSStyles: {
- 'font-size': '14px',
- 'margin-block-start': '0px',
- 'margin-block-end': '0px'
- }
- }).component();
- this._recommendationText = view.modelBuilder.text().withProperties({
- value: '',
+ this._descriptionText = this._view.modelBuilder.text().withProps({
CSSStyles: {
'font-size': '12px',
- 'width': '250px'
+ 'width': '200px',
+ 'margin': '3px 35px 0px 0px'
}
}).component();
- const moreInfo = view.modelBuilder.text().withProperties({
- value: 'More Info',
+
+ const recommendationTitle = this._view.modelBuilder.text().withProps({
+ value: constants.RECOMMENDATION,
CSSStyles: {
'font-size': '14px',
- 'margin-block-start': '0px',
- 'margin-block-end': '0px'
+ 'width': '200px',
+ 'margin': '12px 35px 0px 0px'
}
}).component();
- this._moreInfo = view.modelBuilder.hyperlink().component();
+ this._recommendationText = this._view.modelBuilder.text().withProps({
+ CSSStyles: {
+ 'font-size': '12px',
+ 'width': '200px',
+ 'margin': '3px 35px 0px 0px'
+ }
+ }).component();
+ const moreInfo = this._view.modelBuilder.text().withProps({
+ value: constants.MORE_INFO,
+ CSSStyles: {
+ 'font-size': '14px',
+ 'width': '200px',
+ 'margin': '15px 35px 0px 0px'
+ }
+ }).component();
+ this._moreInfo = this._view.modelBuilder.hyperlink().withProps({
+ label: '',
+ url: '',
+ CSSStyles: {
+ 'font-size': '12px',
+ 'width': '200px',
+ 'margin': '3px 35px 0px 0px'
+ },
+ showLinkIcon: true
+ }).component();
- const container = view.modelBuilder.flexContainer().withItems([descriptionTitle, this._descriptionText, recommendationTitle, this._recommendationText, moreInfo, this._moreInfo]).withLayout({
+ const container = this._view.modelBuilder.flexContainer().withItems([descriptionTitle, this._descriptionText, recommendationTitle, this._recommendationText, moreInfo, this._moreInfo]).withLayout({
flexFlow: 'column'
}).component();
@@ -427,13 +465,15 @@ export class SqlDatabaseTree {
}
- private createAssessmentTitle(view: azdata.ModelView): azdata.TextComponent {
- this._assessmentTitle = view.modelBuilder.text().withProperties({
+ private createAssessmentTitle(): azdata.TextComponent {
+ this._assessmentTitle = this._view.modelBuilder.text().withProps({
value: '',
CSSStyles: {
- 'font-size': '15px',
- 'line-size': '19px',
- 'padding-bottom': '15px',
+ 'font-size': '13px',
+ 'line-size': '18px',
+ 'height': '48px',
+ 'width': '540px',
+ 'font-weight': '600',
'border-bottom': 'solid 1px'
}
}).component();
@@ -441,57 +481,67 @@ export class SqlDatabaseTree {
return this._assessmentTitle;
}
- private createTitleComponent(view: azdata.ModelView): azdata.TextComponent {
- const title = view.modelBuilder.text().withProperties({
- value: 'Target Platform',
+ private createTitleComponent(): azdata.TextComponent {
+ const title = this._view.modelBuilder.text().withProps({
+ value: constants.TARGET_PLATFORM,
CSSStyles: {
'font-size': '13px',
'line-size': '19px',
- 'margin-block-start': '0px',
- 'margin-block-end': '2px'
+ 'margin': '0px 0px 0px 0px'
}
});
return title.component();
}
- private createPlatformComponent(view: azdata.ModelView): azdata.TextComponent {
- const impact = view.modelBuilder.text().withProperties({
- title: 'Platform', // TODO localize
- value: (this._targetType === MigrationTargetType.SQLVM) ? 'Azure SQL Virtual Machine' : 'Azure SQL Managed Instance',
+ private createPlatformComponent(): azdata.TextComponent {
+ const impact = this._view.modelBuilder.text().withProps({
+ value: (this._targetType === MigrationTargetType.SQLVM) ? constants.SUMMARY_VM_TYPE : constants.SUMMARY_MI_TYPE,
CSSStyles: {
'font-size': '18px',
- 'margin-block-start': '0px',
- 'margin-block-end': '0px'
+ 'margin': '0px 0px 0px 0px'
}
});
return impact.component();
}
- private createRecommendationComponent(view: azdata.ModelView): azdata.TextComponent {
- this._dbName = view.modelBuilder.text().withProperties({
- title: 'Recommendation', // TODO localize
- value: 'SQL Server 1',
+ private createRecommendationComponent(): azdata.TextComponent {
+ this._dbName = this._view.modelBuilder.text().withProps({
CSSStyles: {
- 'font-size': '14px',
- 'font-weight': 'bold'
+ 'font-size': '13px',
+ 'font-weight': 'bold',
+ 'margin': '10px 0px 0px 0px'
}
}).component();
return this._dbName;
}
- private createAssessmentResultsTitle(view: azdata.ModelView): azdata.TextComponent {
- this._recommendation = view.modelBuilder.text().withProperties({
- title: 'Recommendation', // TODO localize
- value: 'Warnings',
+ private createAssessmentResultsTitle(): azdata.TextComponent {
+ this._recommendation = this._view.modelBuilder.text().withProps({
+ value: constants.WARNINGS,
CSSStyles: {
- 'font-size': '14px',
- 'font-weight': 'bold',
- 'border-bottom': 'solid 1px',
- 'margin-block-start': '0px',
- 'margin-block-end': '0px'
+ 'font-size': '13px',
+ 'line-height': '18px',
+ 'width': '200px',
+ 'font-weight': '600',
+ 'margin': '8px 35px 5px 0px'
+ }
+ }).component();
+
+ return this._recommendation;
+ }
+
+ private createAssessmentDetailsTitle(): azdata.TextComponent {
+ this._recommendation = this._view.modelBuilder.text().withProps({
+ value: constants.WARNINGS_DETAILS,
+ CSSStyles: {
+ 'font-size': '13px',
+ 'line-height': '18px',
+ 'width': '200px',
+ 'font-weight': '600',
+ 'margin': '8px 0px 5px 0px'
}
}).component();
@@ -499,7 +549,7 @@ export class SqlDatabaseTree {
}
- private createImpactedObjectsTable(view: azdata.ModelView): azdata.DeclarativeTableComponent {
+ private createImpactedObjectsTable(): azdata.DeclarativeTableComponent {
const headerStyle: azdata.CssStyles = {
'border': 'none',
@@ -511,10 +561,11 @@ export class SqlDatabaseTree {
'white-space': 'nowrap',
'text-overflow': 'ellipsis',
'width': '200px',
- 'overflow': 'hidden'
+ 'overflow': 'hidden',
+ 'border-bottom': '1px solid'
};
- this._assessmentResultsTable = view.modelBuilder.declarativeTable().withProps(
+ this._assessmentResultsTable = this._view.modelBuilder.declarativeTable().withProps(
{
enableRowSelection: true,
width: '200px',
@@ -523,25 +574,13 @@ export class SqlDatabaseTree {
},
columns: [
{
- displayName: '', // TODO localize
+ displayName: '',
valueType: azdata.DeclarativeDataType.string,
width: '100%',
isReadOnly: true,
headerCssStyles: headerStyle,
rowCssStyles: rowStyle
}
- ],
- dataValues: [
- [
- {
- value: 'DB1 Assessment results'
- }
- ],
- [
- {
- value: 'DB2 Assessment results'
- }
- ]
]
}
).component();
@@ -587,7 +626,7 @@ export class SqlDatabaseTree {
this._moreInfo.url = this._selectedIssue.helpLink;
this._moreInfo.label = this._selectedIssue.helpLink;
this._impactedObjects = this._selectedIssue.impactedObjects;
- this._recommendationText.value = this._selectedIssue.message; // Expose correct property for recommendation.
+ this._recommendationText.value = this._selectedIssue.message; //TODO: Expose correct property for recommendation.
this._impactedObjectsTable.dataValues = this._selectedIssue.impactedObjects.map((object) => {
return [
{
@@ -613,8 +652,8 @@ export class SqlDatabaseTree {
public refreshImpactedObject(): void {
if (this._selectedObject) {
- this._objectDetailsType.value = `Type: ${this._selectedObject.objectType!}`;
- this._objectDetailsName.value = `Name: ${this._selectedObject.name}`;
+ this._objectDetailsType.value = constants.IMPACT_OBJECT_TYPE(this._selectedObject.objectType!);
+ this._objectDetailsName.value = constants.IMPACT_OBJECT_NAME(this._selectedObject.name);
this._objectDetailsSample.value = this._selectedObject.impactDetail;
} else {
this._objectDetailsType.value = ``;
@@ -628,15 +667,15 @@ export class SqlDatabaseTree {
let instanceTableValues: azdata.DeclarativeTableCellValue[][] = [];
let databaseTableValues: azdata.DeclarativeTableCellValue[][] = [];
const excludedDatabases = ['master', 'msdb', 'tempdb', 'model'];
- const dbList = (await azdata.connection.listDatabases(this._model.sourceConnectionId)).filter(db => !excludedDatabases.includes(db));
+ this._dbNames = (await azdata.connection.listDatabases(this._model.sourceConnectionId)).filter(db => !excludedDatabases.includes(db));
const selectedDbs = (this._targetType === MigrationTargetType.SQLVM) ? this._model._vmDbs : this._model._miDbs;
- const serverName = (await this._model.getSourceConnectionProfile()).serverName;
+ this._serverName = (await this._model.getSourceConnectionProfile()).serverName;
if (this._targetType === MigrationTargetType.SQLVM || !this._model._assessmentResults) {
instanceTableValues = [
[
{
- value: serverName,
+ value: this.createIconTextCell(IconPathHelper.sqlServerLogo, this._serverName),
style: styleLeft
},
{
@@ -645,7 +684,7 @@ export class SqlDatabaseTree {
}
]
];
- dbList.forEach((db) => {
+ this._dbNames.forEach((db) => {
databaseTableValues.push(
[
{
@@ -653,7 +692,7 @@ export class SqlDatabaseTree {
style: styleLeft
},
{
- value: db,
+ value: this.createIconTextCell(IconPathHelper.sqlDatabaseLogo, db),
style: styleLeft
},
{
@@ -667,7 +706,7 @@ export class SqlDatabaseTree {
instanceTableValues = [
[
{
- value: serverName,
+ value: this.createIconTextCell(IconPathHelper.sqlServerLogo, this._serverName),
style: styleLeft
},
{
@@ -684,7 +723,7 @@ export class SqlDatabaseTree {
style: styleLeft
},
{
- value: db.name,
+ value: this.createIconTextCell((db.issues.length === 0) ? IconPathHelper.sqlDatabaseLogo : IconPathHelper.sqlDatabaseWarningLogo, db.name),
style: styleLeft
},
{
@@ -695,11 +734,49 @@ export class SqlDatabaseTree {
);
});
}
- this._dbName.value = serverName;
- this._activeIssues = this._model._assessmentResults.issues;
- this._selectedIssue = this._model._assessmentResults?.issues[0];
- this.refreshResults();
+ this._dbName.value = this._serverName;
this._instanceTable.dataValues = instanceTableValues;
this._databaseTable.dataValues = databaseTableValues;
+ if (this._targetType === MigrationTargetType.SQLMI) {
+ this._activeIssues = this._model._assessmentResults.issues;
+ this._selectedIssue = this._model._assessmentResults?.issues[0];
+ this.refreshResults();
+ }
+ }
+
+ private createIconTextCell(icon: IconPath, text: string): azdata.FlexContainer {
+
+ const iconComponent = this._view.modelBuilder.image().withProps({
+ iconPath: icon,
+ iconWidth: '16px',
+ iconHeight: '16px',
+ width: '20px',
+ height: '20px'
+ }).component();
+ const textComponent = this._view.modelBuilder.text().withProps({
+ value: text,
+ CSSStyles: {
+ 'margin': '0px'
+ }
+ }).component();
+
+ const cellContainer = this._view.modelBuilder.flexContainer().withProps({
+ CSSStyles: {
+ 'justify-content': 'left'
+ }
+ }).component();
+ cellContainer.addItem(iconComponent, {
+ flex: '0',
+ CSSStyles: {
+ 'width': '32px'
+ }
+ });
+ cellContainer.addItem(textComponent, {
+ CSSStyles: {
+ 'width': 'auto'
+ }
+ });
+
+ return cellContainer;
}
}