diff --git a/extensions/sql-migration/src/constants/strings.ts b/extensions/sql-migration/src/constants/strings.ts index bb7135ed89..74aa76a1ac 100644 --- a/extensions/sql-migration/src/constants/strings.ts +++ b/extensions/sql-migration/src/constants/strings.ts @@ -25,7 +25,7 @@ export const CONTINUE_MIGRATION = localize('sql.migration.resume.contine', "Cont export const ASSESSMENT_BLOCKING_ISSUE_TITLE = localize('sql.migration.assessments.blocking.issue', 'This is a blocking issue that will prevent the database migration from succeeding.'); export const ASSESSMENT_IN_PROGRESS = localize('sql.migration.assessment.in.progress', "Assessment in progress"); export function ASSESSMENT_IN_PROGRESS_CONTENT(dbName: string) { - return localize('sql.migration.assessment.in.progress.content', "We are assessing the databases in your SQL server instance {0} to identify the right Azure SQL target.\n\nThis may take some time.", dbName); + return localize('sql.migration.assessment.in.progress.content', "We are assessing the databases in your SQL Server instance {0} to identify the right Azure SQL target.\n\nThis may take some time.", dbName); } export const SKU_RECOMMENDATION_PAGE_TITLE = localize('sql.migration.wizard.sku.title', "Azure SQL target"); @@ -43,7 +43,7 @@ export const SKU_RECOMMENDATION_RESOURCE_GROUP_INFO = localize('sql.migration.sk export const SKU_RECOMMENDATION_RESOURCE_INFO = localize('sql.migration.sku.resource', "Your Azure SQL target resource name"); export const SKU_RECOMMENDATION_MI_CARD_TEXT = localize('sql.migration.sku.mi.card.title', "Azure SQL Managed Instance (PaaS)"); export const SKU_RECOMMENDATION_VM_CARD_TEXT = localize('sql.migration.sku.vm.card.title', "SQL Server on Azure Virtual Machine (IaaS)"); -export const SELECT_AZURE_MI = localize('sql.migration.select.azure.mi', "Select your target Azure subscription and your target Azure SQL Managed Instance"); +export const SELECT_AZURE_MI = localize('sql.migration.select.azure.mi', "Select your target Azure subscription and your target Azure SQL Managed Instance."); export const SELECT_AZURE_VM = localize('sql.migration.select.azure.vm', "Select your target Azure Subscription and your target SQL Server on Azure Virtual Machine for your target."); export const SKU_RECOMMENDATION_VIEW_ASSESSMENT_MI = localize('sql.migration.sku.recommendation.view.assessment.mi', "To migrate to Azure SQL Managed Instance (PaaS), view assessment results and select one or more databases."); export const SKU_RECOMMENDATION_VIEW_ASSESSMENT_VM = localize('sql.migration.sku.recommendation.view.assessment.vm', "To migrate to SQL Server on Azure Virtual Machine (IaaS), view assessment results and select one or more databases."); @@ -106,7 +106,7 @@ export function DATABASE_ALREADY_EXISTS_MI(dbName: string, targetName: string): export const DATABASE_BACKUP_BLOB_STORAGE_HEADER_TEXT = localize('sql.migration.blob.storage.header.text', "Azure Storage Blob Container details"); export const DATABASE_BACKUP_BLOB_STORAGE_HELP_TEXT = localize('sql.migration.blob.storage.help.text', "Provide the Azure Storage Blob Container that contains the backups."); export const DATABASE_BACKUP_BLOB_STORAGE_TABLE_HELP_TEXT = localize('sql.migration.blob.storage.table.help', "Enter target database name and select resource group, storage account and container for the selected source databases."); -export const DATABASE_BACKUP_BLOB_STORAGE_SUBSCRIPTION_LABEL = localize('sql.migration.blob.storage.subscription.label', "Select the subscription that contains the storage account."); +export const DATABASE_BACKUP_BLOB_STORAGE_SUBSCRIPTION_LABEL = localize('sql.migration.blob.storage.subscription.label', "Subscription"); export const DATABASE_BACKUP_MIGRATION_MODE_LABEL = localize('sql.migration.database.migration.mode.label', "Migration mode"); export const DATABASE_BACKUP_MIGRATION_MODE_DESCRIPTION = localize('sql.migration.database.migration.mode.description', "To migrate to the Azure SQL target, choose a migration mode based on your downtime requirements."); export const DATABASE_BACKUP_MIGRATION_MODE_ONLINE_LABEL = localize('sql.migration.database.migration.mode.online.label', "Online migration"); diff --git a/extensions/sql-migration/src/constants/styles.ts b/extensions/sql-migration/src/constants/styles.ts new file mode 100644 index 0000000000..e84cabe446 --- /dev/null +++ b/extensions/sql-migration/src/constants/styles.ts @@ -0,0 +1,71 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export const DASHBOARD_TITLE_CSS = { + 'font-size': '36px', + 'line-height': '48px', + 'margin': '16px 0 8px 0', +}; + +export const PAGE_TITLE_CSS = { + 'font-size': '18px', + 'line-height': '24px', + 'font-weight': '600', + 'margin': '0 0 4px 0', +}; + +export const PAGE_SUBTITLE_CSS = { + 'font-size': '15px', + 'line-height': '19px', + 'margin': '0 0 12px 0', +}; + +export const SECTION_HEADER_CSS = { + 'font-size': '14px', + 'line-height': '20px', + 'font-weight': '600', + 'margin': '4px 0', +}; + +export const BODY_CSS = { + 'font-size': '13px', + 'line-height': '18px', + 'margin': '4px 0', +}; + +export const LABEL_CSS = { + ...BODY_CSS, + 'margin': '0 0 4px 0', + 'font-weight': '600', +}; + +export const LIGHT_LABEL_CSS = { + ...BODY_CSS, + 'font-weight': '350', +}; + +export const NOTE_CSS = { + 'font-size': '12px', + 'line-height': '16px', + 'margin': '0', + 'font-weight': '350', +}; + +export const BOLD_NOTE_CSS = { + ...NOTE_CSS, + 'font-weight': '600', +}; + +export const SMALL_NOTE_CSS = { + 'font-size': '10px', + 'line-height': '14px', + 'margin': '0', +}; + +export const BIG_NUMBER_CSS = { + 'font-size': '28px', + 'line-height': '36px', + 'margin': '0', +}; diff --git a/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts b/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts index ad8b14d658..a5e780ce70 100644 --- a/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts +++ b/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts @@ -11,6 +11,7 @@ import { IconPath, IconPathHelper } from '../constants/iconPathHelper'; import { MigrationStatusDialog } from '../dialog/migrationStatus/migrationStatusDialog'; import { AdsMigrationStatus } from '../dialog/migrationStatus/migrationStatusDialogModel'; import { filterMigrations, SupportedAutoRefreshIntervals } from '../api/utils'; +import * as styles from '../constants/styles'; interface IActionMetadata { title?: string, @@ -82,7 +83,8 @@ export class DashboardWidget { linear-gradient(0deg, rgba(0, 0, 0, 0.05) 0%, rgba(0, 0, 0, 0) 100%) `, 'background-repeat': 'no-repeat', - 'background-position': '91.06% 100%' + 'background-position': '91.06% 100%', + 'margin-bottom': '20px' } }); @@ -90,12 +92,12 @@ export class DashboardWidget { header.addItem(tasksContainer, { CSSStyles: { 'width': `${maxWidth}px`, - 'height': '150px', + 'margin': '24px' } }); container.addItem(await this.createFooter(view), { CSSStyles: { - 'margin-top': '20px' + 'margin': '0 24px' } }); this._disposables.push(this._view.onClosed(e => { @@ -110,6 +112,8 @@ export class DashboardWidget { } private createHeader(view: azdata.ModelView): azdata.FlexContainer { + this.setAutoRefresh(refreshFrequency); + const header = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column', width: maxWidth, @@ -118,28 +122,20 @@ export class DashboardWidget { value: loc.DASHBOARD_TITLE, width: '750px', CSSStyles: { - 'font-size': '36px', - 'margin-bottom': '5px', + ...styles.DASHBOARD_TITLE_CSS } }).component(); - this.setAutoRefresh(refreshFrequency); - - const container = view.modelBuilder.flexContainer().withItems([ - titleComponent, - ]).component(); - - const descComponent = view.modelBuilder.text().withProps({ + const descriptionComponent = view.modelBuilder.text().withProps({ value: loc.DASHBOARD_DESCRIPTION, CSSStyles: { - 'font-size': '12px', - 'margin-top': '10px', + ...styles.NOTE_CSS } }).component(); - header.addItems([container, descComponent], { + header.addItems([titleComponent, descriptionComponent], { CSSStyles: { 'width': `${maxWidth}px`, - 'padding-left': '20px' + 'padding-left': '24px' } }); return header; @@ -149,7 +145,6 @@ export class DashboardWidget { const tasksContainer = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'row', width: '100%', - height: '50px', }).component(); const migrateButtonMetadata: IActionMetadata = { @@ -162,9 +157,8 @@ export class DashboardWidget { const preRequisiteListTitle = view.modelBuilder.text().withProps({ value: loc.PRE_REQ_TITLE, CSSStyles: { - 'font-size': '14px', - 'padding-left': '15px', - 'margin-bottom': '-5px' + ...styles.BODY_CSS, + 'margin': '0px', } }).component(); @@ -177,9 +171,9 @@ export class DashboardWidget { loc.PRE_REQ_3 ], CSSStyles: { - 'padding-left': '30px', - 'margin-bottom': '5px', - 'margin-top': '10px' + ...styles.SMALL_NOTE_CSS, + 'padding-left': '12px', + 'margin': '-0.5em 0px', } }).component(); @@ -187,36 +181,22 @@ export class DashboardWidget { label: loc.LEARN_MORE, ariaLabel: loc.LEARN_MORE_ABOUT_PRE_REQS, url: 'https://aka.ms/azuresqlmigrationextension', - CSSStyles: { - 'padding-left': '10px' - } }).component(); const preReqContainer = view.modelBuilder.flexContainer().withItems([ preRequisiteListTitle, - preRequisiteListElement + preRequisiteListElement, + preRequisiteLearnMoreLink ]).withLayout({ flexFlow: 'column' }).component(); - preReqContainer.addItem(preRequisiteLearnMoreLink, { - CSSStyles: { - 'padding-left': '10px' - } - }); - - tasksContainer.addItem(migrateButton, { - CSSStyles: { - 'margin-top': '20px', - 'padding': '10px' - } - }); + tasksContainer.addItem(migrateButton, {}); tasksContainer.addItems([preReqContainer], { CSSStyles: { - 'padding': '10px' + 'margin-left': '20px' } }); - return tasksContainer; } @@ -333,198 +313,112 @@ export class DashboardWidget { private createStatusCard( cardIconPath: IconPath, cardTitle: string, + hasSubtext: boolean = false ): StatusCard { + const buttonWidth = '400px'; + const buttonHeight = hasSubtext ? '70px' : '50px'; + const statusCard = this._view.modelBuilder.flexContainer() + .withProps({ + CSSStyles: { + 'width': buttonWidth, + 'height': buttonHeight, + 'align-items': 'center', + } + }).component(); - const cardTitleText = this._view.modelBuilder.text().withProps({ value: cardTitle }).withProps({ - CSSStyles: { - 'height': '23px', - 'margin-top': '15px', - 'margin-bottom': '0px', - 'width': '300px', - 'font-size': '14px', - 'font-weight': 'bold' - } - }).component(); - - const cardCount = this._view.modelBuilder.text().withProps({ - value: '0', - CSSStyles: { - 'font-size': '28px', - 'line-height': '36px', - 'margin-top': '4px' - } - }).component(); - - const flex = this._view.modelBuilder.flexContainer().withProps({ - CSSStyles: { - 'width': '400px', - 'height': '50px' - } - }).component(); - - const img = this._view.modelBuilder.image().withProps({ + const statusIcon = this._view.modelBuilder.image().withProps({ iconPath: cardIconPath!.light, iconHeight: 24, iconWidth: 24, - width: 64, - height: 30, + height: 32, CSSStyles: { - 'margin-top': '10px' + 'margin': '0 8px' } }).component(); - flex.addItem(img, { - flex: '0' - }); - flex.addItem(cardTitleText, { - flex: '0', - CSSStyles: { - 'width': '300px' - } - }); - flex.addItem(cardCount, { - flex: '0' - }); - - const compositeButton = this._view.modelBuilder.divContainer().withItems([flex]).withProps({ - ariaRole: 'button', - ariaLabel: loc.SHOW_STATUS, - clickable: true, - CSSStyles: { - 'width': '400px', - 'border': '1px solid', - 'margin-top': '10px', - 'height': '50px', - 'display': 'flex', - 'flex-direction': 'column', - 'justify-content': 'flex-start', - 'border-radius': '4px', - 'transition': 'all .5s ease', - } - }).component(); - return { - container: compositeButton, - count: cardCount - }; - } - - private createStatusWithSubtextCard( - cardIconPath: IconPath, - cardTitle: string, - cardDescription: string - ): StatusCard { - - const cardTitleText = this._view.modelBuilder.text().withProps({ value: cardTitle }).withProps({ - CSSStyles: { - 'height': '23px', - 'margin-top': '15px', - 'margin-bottom': '0px', - 'width': '300px', - 'font-size': '14px', - } - }).component(); - - const cardDescriptionWarning = this._view.modelBuilder.image().withProps({ - iconPath: IconPathHelper.warning, - iconWidth: 12, - iconHeight: 12, - width: 12, - height: 17 - }).component(); - - const cardDescriptionText = this._view.modelBuilder.text().withProps({ value: cardDescription }).withProps({ - CSSStyles: { - 'height': '13px', - 'margin-top': '0px', - 'margin-bottom': '0px', - 'width': '250px', - 'font-height': '13px', - 'margin': '0 0 0 4px' - } - }).component(); - - const subTextContainer = this._view.modelBuilder.flexContainer().withProps({ - CSSStyles: { - 'justify-content': 'left', - } - }).component(); - - subTextContainer.addItem(cardDescriptionWarning, { - flex: '0 0 auto' - }); - - subTextContainer.addItem(cardDescriptionText, { - flex: '0 0 auto' - }); - - const cardCount = this._view.modelBuilder.text().withProps({ - value: '0', - CSSStyles: { - 'font-size': '28px', - 'line-height': '28px', - 'margin-top': '15px' - } - }).component(); - - const flexContainer = this._view.modelBuilder.flexContainer().withItems([ - cardTitleText, - subTextContainer - ]).withLayout({ + const textContainer = this._view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' - }).withProps({ + }).component(); + + const cardTitleText = this._view.modelBuilder.text().withProps({ value: cardTitle }).withProps({ CSSStyles: { - 'width': '300px', + ...styles.SECTION_HEADER_CSS, + 'width': '240px' + } + }).component(); + textContainer.addItem(cardTitleText); + + const cardCount = this._view.modelBuilder.text().withProps({ + value: '0', + CSSStyles: { + ...styles.BIG_NUMBER_CSS, + 'margin': '0 0 0 8px', + 'text-align': 'center', } }).component(); - const flex = this._view.modelBuilder.flexContainer().withProps({ - CSSStyles: { - 'width': '400px', - 'height': '70px', - } - }).component(); + let warningContainer; + let warningText; + if (hasSubtext) { + const warningIcon = this._view.modelBuilder.image().withProps({ + iconPath: IconPathHelper.warning, + iconWidth: 12, + iconHeight: 12, + width: 12, + height: 18 + }).component(); - const img = this._view.modelBuilder.image().withProps({ - iconPath: cardIconPath!.light, - iconHeight: 24, - iconWidth: 24, - width: 64, - height: 30, - CSSStyles: { - 'margin-top': '20px' - } - }).component(); + const warningDescription = ''; + warningText = this._view.modelBuilder.text().withProps({ value: warningDescription }).withProps({ + CSSStyles: { + ...styles.BODY_CSS, + 'padding-left': '8px', + } + }).component(); - flex.addItem(img, { - flex: '0' - }); - flex.addItem(flexContainer, { - flex: '0', - CSSStyles: { - 'width': '300px' - } - }); - flex.addItem(cardCount, { - flex: '0' - }); + warningContainer = this._view.modelBuilder.flexContainer().withItems([ + warningIcon, + warningText + ], { + flex: '0 0 auto' + }).withProps({ + CSSStyles: { + 'align-items': 'center' + } + }).component(); - const compositeButton = this._view.modelBuilder.divContainer().withItems([flex]).withProps({ - ariaRole: 'button', - ariaLabel: 'show status', - clickable: true, - CSSStyles: { - 'width': '400px', - 'height': '70px', - 'margin-top': '10px', - 'border': '1px solid' - } - }).component(); + textContainer.addItem(warningContainer); + } + + statusCard.addItems([ + statusIcon, + textContainer, + cardCount, + ]); + + const compositeButton = this._view.modelBuilder.divContainer() + .withItems([statusCard]) + .withProps({ + ariaRole: 'button', + ariaLabel: loc.SHOW_STATUS, + clickable: true, + CSSStyles: { + 'height': buttonHeight, + 'margin-bottom': '16px', + 'border': '1px solid', + 'display': 'flex', + 'flex-direction': 'column', + 'justify-content': 'flex-start', + 'border-radius': '4px', + 'transition': 'all .5s ease', + } + }).component(); return { container: compositeButton, count: cardCount, - textContainer: flexContainer, - warningContainer: subTextContainer, - warningText: cardDescriptionText + textContainer: textContainer, + warningContainer: warningContainer, + warningText: warningText }; } @@ -532,7 +426,6 @@ export class DashboardWidget { const footerContainer = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'row', width: maxWidth, - height: '500px', justifyContent: 'flex-start' }).component(); const statusContainer = await this.createMigrationStatusContainer(view); @@ -540,7 +433,7 @@ export class DashboardWidget { footerContainer.addItem(statusContainer); footerContainer.addItem(videoLinksContainer, { CSSStyles: { - 'padding-left': '10px', + 'padding-left': '8px', } }); @@ -556,17 +449,14 @@ export class DashboardWidget { }).withProps({ CSSStyles: { 'border': '1px solid rgba(0, 0, 0, 0.1)', - 'padding': '15px' + 'padding': '16px' } }).component(); const statusContainerTitle = view.modelBuilder.text().withProps({ value: loc.DATABASE_MIGRATION_STATUS, CSSStyles: { - 'font-size': '18px', - 'font-weight': 'bold', - 'margin': '0px', - 'width': '290px' + ...styles.SECTION_HEADER_CSS } }).component(); @@ -574,7 +464,7 @@ export class DashboardWidget { label: loc.VIEW_ALL, url: '', CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); @@ -588,8 +478,8 @@ export class DashboardWidget { url: '', ariaRole: 'button', CSSStyles: { + ...styles.BODY_CSS, 'text-align': 'right', - 'font-size': '13px' } }).component(); @@ -604,18 +494,15 @@ export class DashboardWidget { }).component(); buttonContainer.addItem(this._viewAllMigrationsButton, { - flex: 'auto', CSSStyles: { - 'border-right': '1px solid ', - 'width': '40px', + 'padding-right': '8px', + 'border-right': '1px solid', } }); buttonContainer.addItem(refreshButton, { - flex: 'auto', CSSStyles: { - 'margin-left': '5px', - 'width': '25px' + 'padding-left': '8px', } }); @@ -638,11 +525,9 @@ export class DashboardWidget { width: 198, height: 34, CSSStyles: { - 'font-family': 'Segoe UI', - 'font-size': '12px', + ...styles.NOTE_CSS, 'margin': 'auto', 'text-align': 'center', - 'line-height': '16px', 'display': 'none' } }).component(); @@ -684,7 +569,8 @@ export class DashboardWidget { buttonContainer ] ).withLayout({ - flexFlow: 'row' + flexFlow: 'row', + alignItems: 'center' }).component(); this._migrationStatusCardsContainer = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component(); @@ -718,10 +604,10 @@ export class DashboardWidget { this._inProgressMigrationButton.container ); - this._inProgressWarningMigrationButton = this.createStatusWithSubtextCard( + this._inProgressWarningMigrationButton = this.createStatusCard( IconPathHelper.inProgressMigration, loc.MIGRATION_IN_PROGRESS, - '' + true ); this._disposables.push(this._inProgressWarningMigrationButton.container.onDidClick(async (e) => { const dialog = new MigrationStatusDialog(await this.getCurrentMigrations(), AdsMigrationStatus.ONGOING); @@ -782,11 +668,7 @@ export class DashboardWidget { statusContainer.addItem( header, { CSSStyles: { - 'padding': '0px', - 'padding-right': '5px', - 'padding-top': '10px', - 'height': '10px', - 'margin': '0px' + 'margin-bottom': '16px' } } ); @@ -794,13 +676,7 @@ export class DashboardWidget { statusContainer.addItem(addAccountImage, {}); statusContainer.addItem(addAccountText, {}); statusContainer.addItem(addAccountButton, {}); - - statusContainer.addItem(this._migrationStatusCardLoadingContainer, { - CSSStyles: { - 'margin-top': '30px' - } - }); - + statusContainer.addItem(this._migrationStatusCardLoadingContainer, {}); return statusContainer; } @@ -813,25 +689,19 @@ export class DashboardWidget { }).withProps({ CSSStyles: { 'border': '1px solid rgba(0, 0, 0, 0.1)', - 'padding': '15px' + 'padding': '16px' } }).component(); const titleComponent = view.modelBuilder.text().withProps({ value: loc.HELP_TITLE, CSSStyles: { - 'font-size': '18px', - 'font-weight': 'bold', - 'margin': '0px' + ...styles.SECTION_HEADER_CSS } }).component(); linksContainer.addItems([titleComponent], { CSSStyles: { - 'padding': '0px', - 'padding-right': '5px', - 'padding-top': '10px', - 'height': '10px', - 'margin': '0px' + 'margin-bottom': '16px' } }); @@ -841,22 +711,17 @@ export class DashboardWidget { link: 'https://docs.microsoft.com/azure/azure-sql/migration-guides/managed-instance/sql-server-to-sql-managed-instance-assessment-rules' }]; - const styles = { - 'margin-top': '10px', - 'padding': '10px 10px 10px 0' - }; linksContainer.addItems(links.map(l => this.createLink(view, l)), { - CSSStyles: styles + CSSStyles: { + 'margin-bottom': '8px' + } }); - const videosContainer = this.createVideoLinkContainers(view, [ - ]); - const viewPanelStyle = { - 'padding': '10px 5px 10px 10px', - 'margin-top': '-15px' - }; + const videosContainer = this.createVideoLinkContainers(view, []); linksContainer.addItem(videosContainer, { - CSSStyles: viewPanelStyle + CSSStyles: { + 'margin-bottom': '8px' + } }); return linksContainer; @@ -864,47 +729,39 @@ export class DashboardWidget { private createLink(view: azdata.ModelView, linkMetaData: IActionMetadata): azdata.Component { const maxWidth = 400; - const labelsContainer = view.modelBuilder.flexContainer().withLayout({ - flexFlow: 'column', - width: maxWidth, - justifyContent: 'flex-start' + const labelsContainer = view.modelBuilder.flexContainer().withProps({ + CSSStyles: { + 'flex-direction': 'column', + 'width': `${maxWidth}px`, + 'justify-content': 'flex-start' + } + }).component(); + const linkContainer = view.modelBuilder.flexContainer().withProps({ + CSSStyles: { + 'flex-direction': 'row', + 'width': `${maxWidth + 10}px`, + 'justify-content': 'flex-start', + 'margin-bottom': '4px' + } + }).component(); const descriptionComponent = view.modelBuilder.text().withProps({ value: linkMetaData.description, width: maxWidth, CSSStyles: { - 'font-size': '12px', - 'line-height': '16px', - 'margin': '0px' + ...styles.NOTE_CSS } }).component(); - const linkContainer = view.modelBuilder.flexContainer().withLayout({ - flexFlow: 'row', - width: maxWidth + 10, - justifyContent: 'flex-start' - }).component(); const linkComponent = view.modelBuilder.hyperlink().withProps({ label: linkMetaData.title!, url: linkMetaData.link!, showLinkIcon: true, CSSStyles: { - 'font-size': '14px', - 'margin': '0px' + ...styles.BODY_CSS } }).component(); - linkContainer.addItem(linkComponent, { - CSSStyles: { - 'font-size': '14px', - 'line-height': '18px', - 'padding': '0 5px 0 0', - } - }); - labelsContainer.addItems([linkContainer, descriptionComponent], { - CSSStyles: { - 'padding': '5px 0 0 0', - } - }); - + linkContainer.addItem(linkComponent); + labelsContainer.addItems([linkContainer, descriptionComponent]); return labelsContainer; } @@ -938,8 +795,7 @@ export class DashboardWidget { width: maxWidth, height: '50px', CSSStyles: { - 'font-size': '13px', - 'margin': '0px' + ...styles.BODY_CSS } }).component(); this._disposables.push(video1Container.onDidClick(async () => { diff --git a/extensions/sql-migration/src/dialog/assessmentResults/savedAssessmentDialog.ts b/extensions/sql-migration/src/dialog/assessmentResults/savedAssessmentDialog.ts index a5662532c3..ed3939dfce 100644 --- a/extensions/sql-migration/src/dialog/assessmentResults/savedAssessmentDialog.ts +++ b/extensions/sql-migration/src/dialog/assessmentResults/savedAssessmentDialog.ts @@ -8,6 +8,7 @@ import * as vscode from 'vscode'; import * as constants from '../../constants/strings'; import { MigrationStateModel } from '../../models/stateMachine'; import { WizardController } from '../../wizard/wizardController'; +import * as styles from '../../constants/styles'; export class SavedAssessmentDialog { @@ -89,11 +90,10 @@ export class SavedAssessmentDialog { public initializePageContent(view: azdata.ModelView): azdata.FlexContainer { const buttonGroup = 'resumeMigration'; - const text = view.modelBuilder.text().withProps({ + const pageTitle = view.modelBuilder.text().withProps({ CSSStyles: { - 'font-size': '18px', - 'font-weight': 'bold', - 'margin': '100px 8px 0px 36px' + ...styles.PAGE_TITLE_CSS, + 'margin-bottom': '12px' }, value: constants.RESUME_TITLE }).component(); @@ -102,8 +102,8 @@ export class SavedAssessmentDialog { label: constants.START_MIGRATION, name: buttonGroup, CSSStyles: { - 'font-size': '14px', - 'margin': '40px 8px 0px 36px' + ...styles.BODY_CSS, + 'margin-bottom': '8px' }, checked: true }).component(); @@ -117,8 +117,7 @@ export class SavedAssessmentDialog { label: constants.CONTINUE_MIGRATION, name: buttonGroup, CSSStyles: { - 'font-size': '14px', - 'margin': '10px 8px 0px 36px' + ...styles.BODY_CSS, }, checked: false }).component(); @@ -129,12 +128,17 @@ export class SavedAssessmentDialog { } }); - const flex = view.modelBuilder.flexContainer().withLayout({ - flexFlow: 'column', - height: '100%', - width: '100%' - }).component(); - flex.addItem(text, { flex: '0 0 auto' }); + const flex = view.modelBuilder.flexContainer() + .withLayout({ + flexFlow: 'column', + height: '100%', + width: '100%', + }).withProps({ + CSSStyles: { + 'margin': '20px 15px', + } + }).component(); + flex.addItem(pageTitle, { flex: '0 0 auto' }); flex.addItem(radioStart, { flex: '0 0 auto' }); flex.addItem(radioContinue, { flex: '0 0 auto' }); diff --git a/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts b/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts index aae284db25..a98b2848f8 100644 --- a/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts +++ b/extensions/sql-migration/src/dialog/assessmentResults/sqlDatabasesTree.ts @@ -9,6 +9,7 @@ import { MigrationStateModel, MigrationTargetType } from '../../models/stateMach import * as constants from '../../constants/strings'; import { debounce } from '../../api/utils'; import { IconPath, IconPathHelper } from '../../constants/iconPathHelper'; +import * as styles from '../../constants/styles'; const styleLeft: azdata.CssStyles = { 'border': 'none', @@ -135,8 +136,7 @@ export class SqlDatabaseTree { private createDatabaseCount(): azdata.TextComponent { this._databaseCount = this._view.modelBuilder.text().withProps({ CSSStyles: { - 'font-size': '11px', - 'font-weight': 'bold', + ...styles.BOLD_NOTE_CSS, 'margin': '0px 15px 0px 15px' }, value: constants.DATABASES(0, this._model._databaseAssessment.length) @@ -392,20 +392,14 @@ export class SqlDatabaseTree { message = this._view.modelBuilder.text().withProps({ value: constants.NO_ISSUES_FOUND_VM, CSSStyles: { - 'font-size': '14px', - 'width': '100%', - 'margin': '0', - 'text-align': 'left' + ...styles.BODY_CSS } }).component(); } else { message = this._view.modelBuilder.text().withProps({ value: constants.NO_ISSUES_FOUND_MI, CSSStyles: { - 'font-size': '14px', - 'width': '100%', - 'margin': '0', - 'text-align': 'left' + ...styles.BODY_CSS } }).component(); } @@ -413,8 +407,7 @@ export class SqlDatabaseTree { this._noIssuesContainer = this._view.modelBuilder.flexContainer().withItems([message]).withProps({ CSSStyles: { - 'margin-left': '24px', - 'margin-top': '20px', + 'margin-top': '8px', 'display': 'none' } }).component(); @@ -426,7 +419,7 @@ export class SqlDatabaseTree { const message = this._view.modelBuilder.text().withProps({ value: constants.SELECT_DB_PROMPT, CSSStyles: { - 'font-size': '14px', + ...styles.BODY_CSS, 'width': '400px', 'margin': '10px 0px 0px 0px', 'text-align': 'left' @@ -479,10 +472,9 @@ export class SqlDatabaseTree { const impactedObjectsTitle = this._view.modelBuilder.text().withProps({ value: constants.IMPACTED_OBJECTS, CSSStyles: { - 'font-size': '13px', + ...styles.LIGHT_LABEL_CSS, 'width': '280px', 'margin': '10px 0px 0px 0px', - 'font-weight': 'bold' } }).component(); @@ -539,17 +531,13 @@ export class SqlDatabaseTree { const objectDetailsTitle = this._view.modelBuilder.text().withProps({ value: constants.OBJECT_DETAILS, CSSStyles: { - 'font-size': '13px', - 'line-size': '18px', + ...styles.LIGHT_LABEL_CSS, 'margin': '12px 0px 0px 0px', - 'font-weight': 'bold' } }).component(); const objectDescriptionStyle = { - 'font-size': '12px', - 'line-size': '18px', + ...styles.BODY_CSS, 'margin': '5px 0px 0px 0px', - 'text-align': 'justify', 'word-wrap': 'break-word' }; this._objectDetailsType = this._view.modelBuilder.text().withProps({ @@ -575,22 +563,19 @@ export class SqlDatabaseTree { } private createDescription(): azdata.FlexContainer { - const labelStyle = { - 'font-size': '13px', + const LABEL_CSS = { + ...styles.LIGHT_LABEL_CSS, 'width': '200px', - 'font-weight': 'bold', - 'margin': '10px 35px 0px 0px' + 'margin': '12px 0 0' }; const textStyle = { - 'font-size': '12px', + ...styles.BODY_CSS, 'width': '200px', - 'margin': '3px 35px 0px 0px', - 'text-align': 'justify', 'word-wrap': 'break-word' }; const descriptionTitle = this._view.modelBuilder.text().withProps({ value: constants.DESCRIPTION, - CSSStyles: labelStyle + CSSStyles: LABEL_CSS }).component(); this._descriptionText = this._view.modelBuilder.text().withProps({ CSSStyles: textStyle @@ -598,14 +583,14 @@ export class SqlDatabaseTree { const recommendationTitle = this._view.modelBuilder.text().withProps({ value: constants.RECOMMENDATION, - CSSStyles: labelStyle + CSSStyles: LABEL_CSS }).component(); this._recommendationText = this._view.modelBuilder.text().withProps({ CSSStyles: textStyle }).component(); const moreInfo = this._view.modelBuilder.text().withProps({ value: constants.MORE_INFO, - CSSStyles: labelStyle + CSSStyles: LABEL_CSS }).component(); this._moreInfo = this._view.modelBuilder.hyperlink().withProps({ label: '', @@ -626,11 +611,10 @@ export class SqlDatabaseTree { this._assessmentTitle = this._view.modelBuilder.text().withProps({ value: '', CSSStyles: { - 'font-size': '13px', - 'line-size': '18px', + ...styles.LABEL_CSS, + 'margin-top': '12px', 'height': '48px', 'width': '540px', - 'font-weight': '600', 'border-bottom': 'solid 1px' } }).component(); @@ -642,9 +626,8 @@ export class SqlDatabaseTree { const title = this._view.modelBuilder.text().withProps({ value: constants.TARGET_PLATFORM, CSSStyles: { - 'font-size': '13px', - 'line-size': '19px', - 'margin': '0px 0px 0px 0px' + ...styles.BODY_CSS, + 'margin': '0 0 4px 0' } }); @@ -655,8 +638,7 @@ export class SqlDatabaseTree { 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': '0px 0px 0px 0px' + ...styles.PAGE_SUBTITLE_CSS } }); @@ -666,9 +648,9 @@ export class SqlDatabaseTree { private createRecommendationComponent(): azdata.TextComponent { this._dbName = this._view.modelBuilder.text().withProps({ CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', - 'margin': '10px 0px 0px 0px' + ...styles.LABEL_CSS, + 'margin-bottom': '8px', + 'font-weight': '700' } }).component(); @@ -679,11 +661,9 @@ export class SqlDatabaseTree { this._recommendationTitle = this._view.modelBuilder.text().withProps({ value: constants.WARNINGS, CSSStyles: { - 'font-size': '13px', - 'line-height': '18px', - 'width': '200px', - 'font-weight': '600', - 'margin': '8px 35px 5px 0px' + ...styles.LABEL_CSS, + 'margin': '0 8px 4px 0', + 'width': '220px', } }).component(); @@ -694,11 +674,9 @@ export class SqlDatabaseTree { this._recommendation = this._view.modelBuilder.text().withProps({ value: constants.WARNINGS_DETAILS, CSSStyles: { - 'font-size': '13px', - 'line-height': '18px', + ...styles.LABEL_CSS, + 'margin': '0 0 4px 24px', 'width': '200px', - 'font-weight': '600', - 'margin': '8px 0px 5px 0px' } }).component(); diff --git a/extensions/sql-migration/src/dialog/createResourceGroup/createResourceGroupDialog.ts b/extensions/sql-migration/src/dialog/createResourceGroup/createResourceGroupDialog.ts index 0ae2da4c9c..fe62e3b6fc 100644 --- a/extensions/sql-migration/src/dialog/createResourceGroup/createResourceGroupDialog.ts +++ b/extensions/sql-migration/src/dialog/createResourceGroup/createResourceGroupDialog.ts @@ -9,6 +9,7 @@ import { azureResource } from 'azureResource'; import { EventEmitter } from 'events'; import { createResourceGroup } from '../../api/azure'; import * as constants from '../../constants/strings'; +import * as styles from '../../constants/styles'; export class CreateResourceGroupDialog { private _dialogObject!: azdata.window.Dialog; @@ -42,15 +43,14 @@ export class CreateResourceGroupDialog { const resourceGroupDescription = view.modelBuilder.text().withProps({ value: constants.RESOURCE_GROUP_DESCRIPTION, CSSStyles: { - 'font-size': '13px', - 'margin-bottom': '10px' + ...styles.BODY_CSS, + 'margin-bottom': '8px' } }).component(); const nameLabel = view.modelBuilder.text().withProps({ value: constants.NAME, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); diff --git a/extensions/sql-migration/src/dialog/createSqlMigrationService/createSqlMigrationServiceDialog.ts b/extensions/sql-migration/src/dialog/createSqlMigrationService/createSqlMigrationServiceDialog.ts index d98f11a04a..f1195c240e 100644 --- a/extensions/sql-migration/src/dialog/createSqlMigrationService/createSqlMigrationServiceDialog.ts +++ b/extensions/sql-migration/src/dialog/createSqlMigrationService/createSqlMigrationServiceDialog.ts @@ -12,8 +12,10 @@ import * as os from 'os'; import { azureResource } from 'azureResource'; import { IconPathHelper } from '../../constants/iconPathHelper'; import { CreateResourceGroupDialog } from '../createResourceGroup/createResourceGroupDialog'; +import { createAuthenticationKeyTable } from '../../wizard/integrationRuntimePage'; import * as EventEmitter from 'events'; import { clearDialogMessage } from '../../api/utils'; +import * as styles from '../../constants/styles'; export class CreateSqlMigrationServiceDialog { @@ -208,7 +210,7 @@ export class CreateSqlMigrationServiceDialog { const dialogDescription = this._view.modelBuilder.text().withProps({ value: constants.MIGRATION_SERVICE_DIALOG_DESCRIPTION, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); @@ -216,16 +218,14 @@ export class CreateSqlMigrationServiceDialog { value: constants.SUBSCRIPTION, description: constants.MIGRATION_SERVICE_SUBSCRIPTION_INFO, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); this.migrationServiceSubscription = this._view.modelBuilder.text().withProps({ enabled: false, CSSStyles: { - 'font-size': '13px', - 'margin': '0px' + 'margin': '-1em 0 0' } }).component(); @@ -234,8 +234,7 @@ export class CreateSqlMigrationServiceDialog { description: constants.MIGRATION_SERVICE_RESOURCE_GROUP_INFO, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); @@ -244,6 +243,9 @@ export class CreateSqlMigrationServiceDialog { required: true, editable: true, fireOnTextChange: true, + CSSStyles: { + 'margin-top': '-1em' + } }).component(); const migrationServiceNameLabel = this._view.modelBuilder.text().withProps({ @@ -251,14 +253,16 @@ export class CreateSqlMigrationServiceDialog { description: constants.MIGRATION_SERVICE_NAME_INFO, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); this._createResourceGroupLink = this._view.modelBuilder.hyperlink().withProps({ label: constants.CREATE_NEW, - url: '' + url: '', + CSSStyles: { + ...styles.BODY_CSS + } }).component(); this._disposables.push(this._createResourceGroupLink.onDidClick(async e => { @@ -279,31 +283,33 @@ export class CreateSqlMigrationServiceDialog { } })); - this.migrationServiceNameText = this._view.modelBuilder.inputBox().component(); + this.migrationServiceNameText = this._view.modelBuilder.inputBox().withProps({ + CSSStyles: { + 'margin-top': '-1em' + } + }).component(); const locationDropdownLabel = this._view.modelBuilder.text().withProps({ value: constants.LOCATION, description: constants.MIGRATION_SERVICE_LOCATION_INFO, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); this.migrationServiceLocation = this._view.modelBuilder.text().withProps({ + enabled: false, value: await this._model.getLocationDisplayName(this._model._targetServerInstance.location), CSSStyles: { - 'font-size': '13px', - 'margin': '0px' + 'margin': '-1em 0 0' } }).component(); - const targetlabel = this._view.modelBuilder.text().withProps({ + const targetLabel = this._view.modelBuilder.text().withProps({ value: constants.TARGET, description: constants.MIGRATION_SERVICE_TARGET_INFO, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); @@ -311,8 +317,9 @@ export class CreateSqlMigrationServiceDialog { enabled: false, value: constants.AZURE_SQL, CSSStyles: { - 'font-size': '13px', - 'margin': '0px' + 'margin-top': '-1em', + // 'font-size': '13px', + // 'margin': '0px' } }).component(); @@ -327,7 +334,7 @@ export class CreateSqlMigrationServiceDialog { this._createResourceGroupLink, migrationServiceNameLabel, this.migrationServiceNameText, - targetlabel, + targetLabel, targetText ]).withLayout({ flexFlow: 'column' @@ -379,29 +386,28 @@ export class CreateSqlMigrationServiceDialog { const setupIRHeadingText = this._view.modelBuilder.text().withProps({ value: constants.SERVICE_CONTAINER_HEADING, CSSStyles: { - 'font-weight': 'bold', - 'font-size': '13px' + ...styles.LABEL_CSS } }).component(); const setupIRdescription1 = this._view.modelBuilder.text().withProps({ value: constants.SERVICE_CONTAINER_DESCRIPTION1, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); const setupIRdescription2 = this._view.modelBuilder.text().withProps({ value: constants.SERVICE_CONTAINER_DESCRIPTION2, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); const irSetupStep1Text = this._view.modelBuilder.text().withProps({ value: constants.SERVICE_STEP1, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS }, links: [ { @@ -414,7 +420,7 @@ export class CreateSqlMigrationServiceDialog { const irSetupStep2Text = this._view.modelBuilder.text().withProps({ value: constants.SERVICE_STEP2, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); @@ -423,7 +429,7 @@ export class CreateSqlMigrationServiceDialog { CSSStyles: { 'margin-top': '10px', 'margin-bottom': '10px', - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); @@ -431,7 +437,7 @@ export class CreateSqlMigrationServiceDialog { text: '', style: 'error', CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); @@ -442,55 +448,11 @@ export class CreateSqlMigrationServiceDialog { this._refreshLoadingComponent = this._view.modelBuilder.loadingComponent().withProps({ loading: false, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); - - this.migrationServiceAuthKeyTable = this._view.modelBuilder.declarativeTable().withProps({ - ariaLabel: constants.DATABASE_MIGRATION_SERVICE_AUTHENTICATION_KEYS, - columns: [ - { - displayName: constants.NAME, - valueType: azdata.DeclarativeDataType.string, - width: '50px', - isReadOnly: true, - rowCssStyles: { - 'font-size': '13px' - }, - headerCssStyles: { - 'font-size': '13px' - } - }, - { - displayName: constants.AUTH_KEY_COLUMN_HEADER, - valueType: azdata.DeclarativeDataType.string, - width: '500px', - isReadOnly: true, - rowCssStyles: { - 'font-size': '13px' - }, - headerCssStyles: { - 'font-size': '13px' - } - }, - { - displayName: '', - valueType: azdata.DeclarativeDataType.component, - width: '30px', - isReadOnly: true, - rowCssStyles: { - 'font-size': '13px' - }, - headerCssStyles: { - 'font-size': '13px' - } - } - ], - CSSStyles: { - 'margin-top': '5px' - } - }).component(); + this.migrationServiceAuthKeyTable = createAuthenticationKeyTable(this._view); this._setupContainer = this._view.modelBuilder.flexContainer().withItems( [ @@ -551,7 +513,7 @@ export class CreateSqlMigrationServiceDialog { text: constants.SERVICE_READY(this._createdMigrationService!.name, this.irNodes.join(', ')), style: 'success', CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }); this._dialogObject.okButton.enabled = true; @@ -561,7 +523,7 @@ export class CreateSqlMigrationServiceDialog { text: constants.SERVICE_NOT_READY(this._createdMigrationService!.name), style: 'warning', CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }); this._dialogObject.okButton.enabled = false; diff --git a/extensions/sql-migration/src/dialog/migrationCutover/confirmCutoverDialog.ts b/extensions/sql-migration/src/dialog/migrationCutover/confirmCutoverDialog.ts index 3daec4cb3d..a11a8c0c92 100644 --- a/extensions/sql-migration/src/dialog/migrationCutover/confirmCutoverDialog.ts +++ b/extensions/sql-migration/src/dialog/migrationCutover/confirmCutoverDialog.ts @@ -10,7 +10,7 @@ import * as constants from '../../constants/strings'; import { SqlManagedInstance } from '../../api/azure'; import { IconPathHelper } from '../../constants/iconPathHelper'; import { convertByteSizeToReadableUnit, get12HourTime } from '../../api/utils'; - +import * as styles from '../../constants/styles'; export class ConfirmCutoverDialog { private _dialogObject!: azdata.window.Dialog; private _view!: azdata.ModelView; @@ -29,17 +29,15 @@ export class ConfirmCutoverDialog { const completeCutoverText = view.modelBuilder.text().withProps({ value: constants.COMPLETE_CUTOVER, CSSStyles: { - 'font-size': '20px', - 'font-weight': 'bold', - 'margin-bottom': '0px' + ...styles.PAGE_TITLE_CSS } }).component(); const sourceDatabaseText = view.modelBuilder.text().withProps({ value: this.migrationCutoverModel._migration.migrationContext.properties.sourceDatabaseName, CSSStyles: { - 'font-size': '10px', - 'margin': '5px 0px 10px 0px' + ...styles.SMALL_NOTE_CSS, + 'margin': '4px 0px 8px' } }).component(); @@ -48,24 +46,25 @@ export class ConfirmCutoverDialog { const helpMainText = this._view.modelBuilder.text().withProps({ value: constants.CUTOVER_HELP_MAIN, CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS } }).component(); const helpStepsText = this._view.modelBuilder.text().withProps({ value: this.migrationCutoverModel.confirmCutoverStepsString(), CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS, + 'padding': '8px' } }).component(); - const fileContainer = this.migrationCutoverModel.isBlobMigration() ? this.createBlobFileContainer() : this.createNewtorkShareFileContainer(); + const fileContainer = this.migrationCutoverModel.isBlobMigration() ? this.createBlobFileContainer() : this.createNetworkShareFileContainer(); const confirmCheckbox = this._view.modelBuilder.checkBox().withProps({ CSSStyles: { - 'font-size': '13px', - 'margin-bottom': '8px' + ...styles.BODY_CSS, + 'margin-bottom': '12px' }, label: constants.CONFIRM_CUTOVER_CHECKBOX, }).component(); @@ -78,7 +77,7 @@ export class ConfirmCutoverDialog { text: constants.COMPLETING_CUTOVER_WARNING, style: 'warning', CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS } }).component(); @@ -89,11 +88,11 @@ export class ConfirmCutoverDialog { infoDisplay = 'inline'; } - const businessCriticalinfoBox = this._view.modelBuilder.infoBox().withProps({ + const businessCriticalInfoBox = this._view.modelBuilder.infoBox().withProps({ text: constants.BUSINESS_CRITICAL_INFO, style: 'information', CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS, 'display': infoDisplay } }).component(); @@ -109,7 +108,7 @@ export class ConfirmCutoverDialog { fileContainer, confirmCheckbox, cutoverWarning, - businessCriticalinfoBox + businessCriticalInfoBox ]).component(); @@ -144,15 +143,17 @@ export class ConfirmCutoverDialog { } private createBlobFileContainer(): azdata.FlexContainer { - const container = this._view.modelBuilder.flexContainer().component(); + const container = this._view.modelBuilder.flexContainer().withProps({ + CSSStyles: { + 'margin': '8px 0' + } + }).component(); const containerHeading = this._view.modelBuilder.text().withProps({ value: constants.PENDING_BACKUPS(this.migrationCutoverModel.getPendingLogBackupsCount() ?? 0), width: 250, CSSStyles: { - 'font-size': '13px', - 'line-height': '18px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); @@ -163,9 +164,6 @@ export class ConfirmCutoverDialog { width: 70, height: 20, label: constants.REFRESH, - CSSStyles: { - 'margin-top': '13px' - } }).component(); @@ -195,8 +193,8 @@ export class ConfirmCutoverDialog { const refreshLoader = this._view.modelBuilder.loadingComponent().withProps({ loading: false, CSSStyles: { - 'margin-top': '8px', - 'margin-left': '5px' + 'margin-top': '-4px', + 'margin-left': '8px' } }).component(); @@ -206,7 +204,7 @@ export class ConfirmCutoverDialog { return container; } - private createNewtorkShareFileContainer(): azdata.FlexContainer { + private createNetworkShareFileContainer(): azdata.FlexContainer { const container = this._view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component(); @@ -224,10 +222,8 @@ export class ConfirmCutoverDialog { iconWidth: 8, iconPath: IconPathHelper.expandButtonClosed, CSSStyles: { - 'font-size': '13px', - 'line-height': '18px', - 'font-weight': 'bold', - 'margin': '16px 10px 0px 0px' + ...styles.LABEL_CSS, + 'margin': '16px 8px 0px 0px' } }).component(); @@ -304,7 +300,7 @@ export class ConfirmCutoverDialog { const lastScanCompleted = this._view.modelBuilder.text().withProps({ value: constants.LAST_SCAN_COMPLETED(get12HourTime(new Date())), CSSStyles: { - 'font-size': '12px', + ...styles.NOTE_CSS } }).component(); @@ -340,10 +336,10 @@ export class ConfirmCutoverDialog { return container; } - private refreshFileTable(filetable: azdata.TableComponent) { - const pendingFiles = this.migrationCutoverModel.getPendingfiles(); + private refreshFileTable(fileTable: azdata.TableComponent) { + const pendingFiles = this.migrationCutoverModel.getPendingFiles(); if (pendingFiles.length > 0) { - filetable.data = pendingFiles.map(f => { + fileTable.data = pendingFiles.map(f => { return [ f.fileName, f.status, @@ -351,7 +347,7 @@ export class ConfirmCutoverDialog { ]; }); } else { - filetable.data = [ + fileTable.data = [ [constants.NO_PENDING_BACKUPS] ]; } diff --git a/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialog.ts b/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialog.ts index 3d73aec3f4..3048a3e7c0 100644 --- a/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialog.ts +++ b/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialog.ts @@ -12,6 +12,7 @@ import * as loc from '../../constants/strings'; import { convertByteSizeToReadableUnit, convertIsoTimeToLocalTime, getSqlServerName, getMigrationStatusImage, SupportedAutoRefreshIntervals, clearDialogMessage, displayDialogErrorMessage } from '../../api/utils'; import { EOL } from 'os'; import { ConfirmCutoverDialog } from './confirmCutoverDialog'; +import * as styles from '../../constants/styles'; const refreshFrequency: SupportedAutoRefreshIntervals = 30000; const statusImageSize: number = 14; @@ -66,8 +67,7 @@ export class MigrationCutoverDialog { this._fileCount = view.modelBuilder.text().withProps({ width: '500px', CSSStyles: { - 'font-size': '14px', - 'font-weight': 'bold' + ...styles.BODY_CSS } }).component(); @@ -160,6 +160,7 @@ export class MigrationCutoverDialog { width: '1100px', height: '300px', CSSStyles: { + ...styles.BODY_CSS, 'display': 'none', 'padding-left': '0px' } @@ -179,9 +180,9 @@ export class MigrationCutoverDialog { const _emptyTableText = view.modelBuilder.text().withProps({ value: loc.EMPTY_TABLE_TEXT, CSSStyles: { + ...styles.NOTE_CSS, + 'margin-top': '8px', 'text-align': 'center', - 'font-size': 'large', - 'font-weight': 'bold', 'width': '300px' } }).component(); @@ -249,9 +250,7 @@ export class MigrationCutoverDialog { this._databaseTitleName = this._view.modelBuilder.text().withProps({ CSSStyles: { - 'font-size': '16px', - 'font-weight': 'bold', - 'margin': '0px' + ...styles.PAGE_TITLE_CSS }, width: 950, value: this._model._migration.migrationContext.properties.sourceDatabaseName @@ -259,8 +258,7 @@ export class MigrationCutoverDialog { const databaseSubTitle = this._view.modelBuilder.text().withProps({ CSSStyles: { - 'font-size': '10px', - 'margin': '5px 0px' + ...styles.NOTE_CSS }, width: 950, value: loc.DATABASE @@ -306,7 +304,7 @@ export class MigrationCutoverDialog { width: '150px', enabled: false, CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS, 'display': this._isOnlineMigration() ? 'inline' : 'none' } }).component(); @@ -335,7 +333,7 @@ export class MigrationCutoverDialog { width: '150px', enabled: false, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS, } }).component(); @@ -364,7 +362,7 @@ export class MigrationCutoverDialog { height: '20px', width: '100px', CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS, } }).component(); @@ -383,7 +381,7 @@ export class MigrationCutoverDialog { height: '20px', width: '200px', CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS, } }).component(); @@ -408,7 +406,10 @@ export class MigrationCutoverDialog { iconHeight: '16px', iconWidth: '16px', height: '20px', - width: '140px', + width: '180px', + CSSStyles: { + ...styles.BODY_CSS, + } }).component(); this._newSupportRequest.onDidClick(async (e) => { @@ -668,6 +669,7 @@ export class MigrationCutoverDialog { if (this._shouldDisplayBackupFileTable()) { await this._fileCount.updateCssStyles({ + ...styles.SECTION_HEADER_CSS, display: 'inline' }); await this._fileTable.updateCssStyles({ @@ -745,9 +747,8 @@ export class MigrationCutoverDialog { const labelComponent = this._view.modelBuilder.text().withProps({ value: label, CSSStyles: { - 'font-weight': 'bold', + ...styles.LIGHT_LABEL_CSS, 'margin-bottom': '0', - 'font-size': '12px' } }).component(); flexContainer.addItem(labelComponent); @@ -755,12 +756,11 @@ export class MigrationCutoverDialog { const textComponent = this._view.modelBuilder.text().withProps({ value: value, CSSStyles: { - 'margin-top': '5px', - 'margin-bottom': '0', + ...styles.BODY_CSS, + 'margin': '4px 0 12px', 'width': '100%', 'overflow': 'hidden', - 'text-overflow': 'ellipses', - 'font-size': '12px' + 'text-overflow': 'ellipses' } }).component(); diff --git a/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialogModel.ts b/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialogModel.ts index 98cb0c9e06..9aeb414f00 100644 --- a/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialogModel.ts +++ b/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialogModel.ts @@ -140,7 +140,7 @@ export class MigrationCutoverDialogModel { return this.migrationStatus.properties.migrationStatusDetails?.pendingLogBackupsCount; } - public getPendingfiles(): BackupFileInfo[] { + public getPendingFiles(): BackupFileInfo[] { const files: BackupFileInfo[] = []; this.migrationStatus.properties.migrationStatusDetails?.activeBackupSets?.forEach(abs => { abs.listOfBackupFiles.forEach(f => { diff --git a/extensions/sql-migration/src/dialog/sqlMigrationService/sqlMigrationServiceDetailsDialog.ts b/extensions/sql-migration/src/dialog/sqlMigrationService/sqlMigrationServiceDetailsDialog.ts index 4a06acf152..463dc65bd9 100644 --- a/extensions/sql-migration/src/dialog/sqlMigrationService/sqlMigrationServiceDetailsDialog.ts +++ b/extensions/sql-migration/src/dialog/sqlMigrationService/sqlMigrationServiceDetailsDialog.ts @@ -9,6 +9,7 @@ import { getSqlMigrationServiceAuthKeys, getSqlMigrationServiceMonitoringData, r import { IconPathHelper } from '../../constants/iconPathHelper'; import * as constants from '../../constants/strings'; import { MigrationContext } from '../../models/migrationLocalStorage'; +import * as styles from '../../constants/styles'; const CONTROL_MARGIN = '10px'; const COLUMN_WIDTH = '50px'; @@ -16,13 +17,8 @@ const STRETCH_WIDTH = '100%'; const LABEL_MARGIN = '0 10px 0 10px'; const VALUE_MARGIN = '0 10px 10px 10px'; const INFO_VALUE_MARGIN = '0 10px 0 0'; -const NO_MARGIN = '0'; const ICON_SIZE = '28px'; const IMAGE_SIZE = '21px'; -const TITLE_FONT_SIZE = '14px'; -const DESCRIPTION_FONT_SIZE = '10px'; -const FONT_SIZE = '13px'; -const FONT_WEIGHT_BOLD = 'bold'; const AUTH_KEY1 = 'authKey1'; const AUTH_KEY2 = 'authKey2'; @@ -126,9 +122,7 @@ export class SqlMigrationServiceDetailsDialog { .withProps({ value: migrationContext.controller.name, CSSStyles: { - 'font-size': TITLE_FONT_SIZE, - 'font-weight': FONT_WEIGHT_BOLD, - 'margin': NO_MARGIN, + ...styles.SECTION_HEADER_CSS } }) .component(), @@ -137,8 +131,7 @@ export class SqlMigrationServiceDetailsDialog { .withProps({ value: constants.SQL_MIGRATION_SERVICE_DETAILS_SUB_TITLE, CSSStyles: { - 'font-size': DESCRIPTION_FONT_SIZE, - 'margin': NO_MARGIN, + ...styles.SMALL_NOTE_CSS } }) .component(), @@ -165,7 +158,7 @@ export class SqlMigrationServiceDetailsDialog { description: description, title: value, CSSStyles: { - 'font-size': FONT_SIZE, + ...styles.BODY_CSS, 'margin': margin, } }) @@ -195,10 +188,11 @@ export class SqlMigrationServiceDetailsDialog { valueType: valueType, width: width, isReadOnly: true, - rowCssStyles: { 'font-size': FONT_SIZE }, + rowCssStyles: { + ...styles.BODY_CSS + }, headerCssStyles: { - 'font-size': FONT_SIZE, - 'font-weight': 'normal', + ...styles.BODY_CSS }, }; } diff --git a/extensions/sql-migration/src/dialog/targetDatabaseSummary/targetDatabaseSummaryDialog.ts b/extensions/sql-migration/src/dialog/targetDatabaseSummary/targetDatabaseSummaryDialog.ts index 1a245e5784..0c6df16ada 100644 --- a/extensions/sql-migration/src/dialog/targetDatabaseSummary/targetDatabaseSummaryDialog.ts +++ b/extensions/sql-migration/src/dialog/targetDatabaseSummary/targetDatabaseSummaryDialog.ts @@ -6,6 +6,7 @@ import * as azdata from 'azdata'; import { MigrationMode, MigrationStateModel, NetworkContainerType } from '../../models/stateMachine'; import * as constants from '../../constants/strings'; +import * as styles from '../../constants/styles'; export class TargetDatabaseSummaryDialog { private _dialogObject!: azdata.window.Dialog; @@ -36,7 +37,7 @@ export class TargetDatabaseSummaryDialog { const databaseCount = this._view.modelBuilder.text().withProps({ value: constants.COUNT_DATABASES(this._model._migrationDbs.length), CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS, 'margin-bottom': '20px' } }).component(); diff --git a/extensions/sql-migration/src/wizard/accountsSelectionPage.ts b/extensions/sql-migration/src/wizard/accountsSelectionPage.ts index 7682b85f42..6bd4a92e7f 100644 --- a/extensions/sql-migration/src/wizard/accountsSelectionPage.ts +++ b/extensions/sql-migration/src/wizard/accountsSelectionPage.ts @@ -11,6 +11,7 @@ import * as constants from '../constants/strings'; import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController'; import { deepClone, findDropDownItemIndex, selectDropDownIndex } from '../api/utils'; import { getSubscriptions } from '../api/azure'; +import * as styles from '../constants/styles'; export class AccountsSelectionPage extends MigrationWizardPage { private _azureAccountsDropdown!: azdata.DropDownComponent; @@ -20,19 +21,34 @@ export class AccountsSelectionPage extends MigrationWizardPage { constructor(wizard: azdata.window.Wizard, migrationStateModel: MigrationStateModel) { super(wizard, azdata.window.createWizardPage(constants.ACCOUNTS_SELECTION_PAGE_TITLE), migrationStateModel); - this.wizardPage.description = constants.ACCOUNTS_SELECTION_PAGE_DESCRIPTION; } protected async registerContent(view: azdata.ModelView): Promise { + const pageDescription = { + title: '', + component: view.modelBuilder.text().withProps({ + value: constants.ACCOUNTS_SELECTION_PAGE_DESCRIPTION, + CSSStyles: { + ...styles.BODY_CSS, + 'margin': '0', + } + }).component() + }; + this.wizard.customButtons[0].enabled = true; const form = view.modelBuilder.formContainer() .withFormItems( [ + pageDescription, await this.createAzureAccountsDropdown(view), await this.createAzureTenantContainer(view), ] - ); - await view.initializeModel(form.component()); + ).withProps({ + CSSStyles: { + 'padding-top': '0' + } + }).component(); + await view.initializeModel(form); await this.populateAzureAccountsDropdown(); this._disposables.push(view.onClosed(e => this._disposables.forEach( @@ -44,8 +60,7 @@ export class AccountsSelectionPage extends MigrationWizardPage { const azureAccountLabel = view.modelBuilder.text().withProps({ value: constants.ACCOUNTS_SELECTION_PAGE_TITLE, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); @@ -117,7 +132,7 @@ export class AccountsSelectionPage extends MigrationWizardPage { label: constants.ACCOUNT_LINK_BUTTON_LABEL, url: '', CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS } }) .component(); @@ -153,8 +168,7 @@ export class AccountsSelectionPage extends MigrationWizardPage { const azureTenantDropdownLabel = view.modelBuilder.text().withProps({ value: constants.AZURE_TENANT, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); diff --git a/extensions/sql-migration/src/wizard/databaseBackupPage.ts b/extensions/sql-migration/src/wizard/databaseBackupPage.ts index cd8ce70c30..c4270619a6 100644 --- a/extensions/sql-migration/src/wizard/databaseBackupPage.ts +++ b/extensions/sql-migration/src/wizard/databaseBackupPage.ts @@ -13,6 +13,7 @@ import * as constants from '../constants/strings'; import { IconPathHelper } from '../constants/iconPathHelper'; import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController'; import { findDropDownItemIndex, selectDropDownIndex } from '../api/utils'; +import * as styles from '../constants/styles'; const WIZARD_TABLE_COLUMN_WIDTH = '200px'; const WIZARD_TABLE_COLUMN_WIDTH_SMALL = '170px'; @@ -34,7 +35,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { private _networkSharePath!: azdata.InputBoxComponent; private _sourceHelpText!: azdata.TextComponent; private _sqlSourceUsernameInput!: azdata.InputBoxComponent; - private _sqlSourcepassword!: azdata.InputBoxComponent; + private _sqlSourcePassword!: azdata.InputBoxComponent; private _blobContainer!: azdata.FlexContainer; private _blobContainerSubscription!: azdata.TextComponent; @@ -52,7 +53,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { private _networkShareContainerStorageAccountRefreshButton!: azdata.ButtonComponent; private _targetDatabaseContainer!: azdata.FlexContainer; - private _newtworkShareTargetDatabaseNamesTable!: azdata.DeclarativeTableComponent; + private _networkShareTargetDatabaseNamesTable!: azdata.DeclarativeTableComponent; private _blobContainerTargetDatabaseNamesTable!: azdata.DeclarativeTableComponent; private _networkTableContainer!: azdata.FlexContainer; private _blobTableContainer!: azdata.FlexContainer; @@ -97,14 +98,18 @@ export class DatabaseBackupPage extends MigrationWizardPage { component: this._networkShareStorageAccountDetails } ] - ); + ).withProps({ + CSSStyles: { + 'padding-top': '0' + } + }).component(); this._disposables.push(this._view.onClosed(e => { this._disposables.forEach( d => { try { d.dispose(); } catch { } }); })); - await view.initializeModel(form.component()); + await view.initializeModel(form); } private createBackupLocationComponent(): azdata.FlexContainer { @@ -113,7 +118,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { const selectLocationText = this._view.modelBuilder.text().withProps({ value: constants.DATABASE_BACKUP_PAGE_DESCRIPTION, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); @@ -122,7 +127,8 @@ export class DatabaseBackupPage extends MigrationWizardPage { name: buttonGroup, label: constants.DATABASE_BACKUP_NC_NETWORK_SHARE_RADIO_LABEL, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS, + 'margin': '0' } }).component(); @@ -137,7 +143,8 @@ export class DatabaseBackupPage extends MigrationWizardPage { name: buttonGroup, label: constants.DATABASE_BACKUP_NC_BLOB_STORAGE_RADIO_LABEL, CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS, + 'margin': '0' } }).component(); @@ -179,15 +186,15 @@ export class DatabaseBackupPage extends MigrationWizardPage { value: constants.SOURCE_CREDENTIALS, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '14px', - 'font-weight': 'bold' + ...styles.SECTION_HEADER_CSS, + 'margin-top': '4px' } }).component(); this._sourceHelpText = this._view.modelBuilder.text().withProps({ width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS } }).component(); @@ -196,14 +203,16 @@ export class DatabaseBackupPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); this._sqlSourceUsernameInput = this._view.modelBuilder.inputBox().withProps({ required: true, enabled: false, width: WIZARD_INPUT_COMPONENT_WIDTH, + CSSStyles: { + 'margin-top': '-1em' + }, }).component(); this._disposables.push(this._sqlSourceUsernameInput.onTextChanged(value => { this.migrationStateModel._sqlServerUsername = value; @@ -214,16 +223,18 @@ export class DatabaseBackupPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); - this._sqlSourcepassword = this._view.modelBuilder.inputBox().withProps({ + this._sqlSourcePassword = this._view.modelBuilder.inputBox().withProps({ required: true, inputType: 'password', - width: WIZARD_INPUT_COMPONENT_WIDTH + width: WIZARD_INPUT_COMPONENT_WIDTH, + CSSStyles: { + 'margin-top': '-1em' + }, }).component(); - this._disposables.push(this._sqlSourcepassword.onTextChanged(value => { + this._disposables.push(this._sqlSourcePassword.onTextChanged(value => { this.migrationStateModel._sqlServerPassword = value; })); @@ -232,8 +243,8 @@ export class DatabaseBackupPage extends MigrationWizardPage { value: constants.DATABASE_BACKUP_NETWORK_SHARE_HEADER_TEXT, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '14px', - 'font-weight': 'bold' + ...styles.SECTION_HEADER_CSS, + 'margin-top': '24px' } }).component(); @@ -241,7 +252,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { value: constants.DATABASE_BACKUP_NC_NETWORK_SHARE_HELP_TEXT, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS } }).component(); @@ -251,8 +262,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); this._networkSharePath = this._view.modelBuilder.inputBox().withProps({ @@ -260,8 +270,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { validationErrorMessage: constants.INVALID_NETWORK_SHARE_LOCATION, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + 'margin-top': '-1em' } }).withValidation((component) => { if (this.migrationStateModel._databaseBackup.networkContainerType === NetworkContainerType.NETWORK_SHARE) { @@ -283,8 +292,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { style: 'information', width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', - 'margin-top': '10px' + ...styles.BODY_CSS } }).component(); @@ -295,8 +303,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); this._windowsUserAccountText = this._view.modelBuilder.inputBox() @@ -304,7 +311,11 @@ export class DatabaseBackupPage extends MigrationWizardPage { placeHolder: constants.WINDOWS_USER_ACCOUNT, required: true, validationErrorMessage: constants.INVALID_USER_ACCOUNT, - width: WIZARD_INPUT_COMPONENT_WIDTH + width: WIZARD_INPUT_COMPONENT_WIDTH, + CSSStyles: { + ...styles.BODY_CSS, + 'margin-top': '-1em' + } }) .withValidation((component) => { if (this.migrationStateModel._databaseBackup.networkContainerType === NetworkContainerType.NETWORK_SHARE) { @@ -326,8 +337,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS, } }).component(); this._passwordText = this._view.modelBuilder.inputBox() @@ -335,7 +345,11 @@ export class DatabaseBackupPage extends MigrationWizardPage { placeHolder: constants.DATABASE_BACKUP_NETWORK_SHARE_PASSWORD_PLACEHOLDER, inputType: 'password', required: true, - width: WIZARD_INPUT_COMPONENT_WIDTH + width: WIZARD_INPUT_COMPONENT_WIDTH, + CSSStyles: { + ...styles.BODY_CSS, + 'margin-top': '-1em' + } }).component(); this._disposables.push(this._passwordText.onTextChanged((value) => { this.migrationStateModel._databaseBackup.networkShare.password = value; @@ -348,7 +362,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { usernameLabel, this._sqlSourceUsernameInput, sqlPasswordLabel, - this._sqlSourcepassword, + this._sqlSourcePassword, networkShareHeading, networkShareHelpText, networkLocationInputBoxLabel, @@ -373,8 +387,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { value: constants.DATABASE_BACKUP_BLOB_STORAGE_HEADER_TEXT, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '14px', - 'font-weight': 'bold' + ...styles.SECTION_HEADER_CSS } }).component(); @@ -382,7 +395,8 @@ export class DatabaseBackupPage extends MigrationWizardPage { value: constants.DATABASE_BACKUP_BLOB_STORAGE_HELP_TEXT, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS, + 'margin-bottom': '12px' } }).component(); @@ -390,16 +404,15 @@ export class DatabaseBackupPage extends MigrationWizardPage { .withProps({ value: constants.DATABASE_BACKUP_BLOB_STORAGE_SUBSCRIPTION_LABEL, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); this._blobContainerSubscription = this._view.modelBuilder.text() .withProps({ enabled: false, CSSStyles: { - 'font-size': '13px', - 'margin': '0px' + ...styles.BODY_CSS, + 'margin': '0 0 12px 0' } }).component(); @@ -407,16 +420,15 @@ export class DatabaseBackupPage extends MigrationWizardPage { .withProps({ value: constants.LOCATION, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); this._blobContainerLocation = this._view.modelBuilder.text() .withProps({ enabled: false, CSSStyles: { - 'font-size': '13px', - 'margin': '0px 0px' + ...styles.BODY_CSS, + 'margin': '0px' } }).component(); @@ -442,14 +454,14 @@ export class DatabaseBackupPage extends MigrationWizardPage { private createTargetDatabaseContainer(): azdata.FlexContainer { const headerCssStyles: azdata.CssStyles = { + ...styles.LABEL_CSS, 'border': 'none', - 'font-size': '13px', - 'font-weight': 'bold', 'text-align': 'left', 'box-shadow': 'inset 0px -1px 0px #F3F2F1', }; const rowCssStyle: azdata.CssStyles = { + ...styles.BODY_CSS, 'border': 'none', 'font-size': '13px', 'box-shadow': 'inset 0px -1px 0px #F3F2F1', @@ -459,8 +471,8 @@ export class DatabaseBackupPage extends MigrationWizardPage { .withProps({ value: constants.DATABASE_BACKUP_NETWORK_SHARE_TABLE_HELP_TEXT, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.SECTION_HEADER_CSS, + 'margin-top': '8px' } }).component(); @@ -468,12 +480,11 @@ export class DatabaseBackupPage extends MigrationWizardPage { .withProps({ value: constants.DATABASE_BACKUP_BLOB_STORAGE_TABLE_HELP_TEXT, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.SECTION_HEADER_CSS } }).component(); - this._newtworkShareTargetDatabaseNamesTable = this._view.modelBuilder.declarativeTable().withProps({ + this._networkShareTargetDatabaseNamesTable = this._view.modelBuilder.declarativeTable().withProps({ columns: [ { displayName: constants.SOURCE_DATABASE, @@ -550,14 +561,14 @@ export class DatabaseBackupPage extends MigrationWizardPage { this._networkTableContainer = this._view.modelBuilder.flexContainer().withItems([ networkShareTableText, - this._newtworkShareTargetDatabaseNamesTable + this._networkShareTargetDatabaseNamesTable ]).component(); const allFieldsRequiredLabel = this._view.modelBuilder.text() .withProps({ value: constants.ALL_FIELDS_REQUIRED, CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS } }).component(); @@ -584,8 +595,8 @@ export class DatabaseBackupPage extends MigrationWizardPage { value: constants.DATABASE_BACKUP_NETWORK_SHARE_AZURE_ACCOUNT_HEADER, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '14px', - 'font-weight': 'bold' + ...styles.SECTION_HEADER_CSS, + 'margin-top': '12px' } }).component(); @@ -594,7 +605,8 @@ export class DatabaseBackupPage extends MigrationWizardPage { value: constants.DATABASE_BACKUP_NETWORK_SHARE_AZURE_ACCOUNT_HELP, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS, + 'margin-bottom': '12px' } }).component(); @@ -602,10 +614,10 @@ export class DatabaseBackupPage extends MigrationWizardPage { .withProps({ value: constants.SUBSCRIPTION, width: WIZARD_INPUT_COMPONENT_WIDTH, - requiredIndicator: true, + // requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS, + 'margin': '0' } }).component(); this._networkShareContainerSubscription = this._view.modelBuilder.text() @@ -613,8 +625,8 @@ export class DatabaseBackupPage extends MigrationWizardPage { enabled: false, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', - 'margin': '0px 0px' + // ...styles.BODY_CSS, + // 'margin-top': '-1em' } }).component(); @@ -622,10 +634,10 @@ export class DatabaseBackupPage extends MigrationWizardPage { .withProps({ value: constants.LOCATION, width: WIZARD_INPUT_COMPONENT_WIDTH, - requiredIndicator: true, + // requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS, + 'margin': '12px 0 0' } }).component(); this._networkShareContainerLocation = this._view.modelBuilder.text() @@ -633,8 +645,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { enabled: false, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', - 'margin': '0px 0px' + 'margin': '0' } }).component(); @@ -644,8 +655,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); this._networkShareStorageAccountResourceGroupDropdown = this._view.modelBuilder.dropDown() @@ -655,6 +665,9 @@ export class DatabaseBackupPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, editable: true, fireOnTextChange: true, + CSSStyles: { + 'margin-top': '-1em' + }, }).component(); this._disposables.push(this._networkShareStorageAccountResourceGroupDropdown.onValueChanged(async (value) => { const selectedIndex = findDropDownItemIndex(this._networkShareStorageAccountResourceGroupDropdown, value); @@ -670,8 +683,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS } }).component(); this._networkShareContainerStorageAccountDropdown = this._view.modelBuilder.dropDown() @@ -701,7 +713,12 @@ export class DatabaseBackupPage extends MigrationWizardPage { await this.loadNetworkShareStorageDropdown(); })); - const storageAccountContainer = this._view.modelBuilder.flexContainer().component(); + const storageAccountContainer = this._view.modelBuilder.flexContainer() + .withProps({ + CSSStyles: { + 'margin-top': '-1em' + } + }).component(); storageAccountContainer.addItem(this._networkShareContainerStorageAccountDropdown, { flex: '0 0 auto' @@ -762,7 +779,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { 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._sqlSourcePassword.value = (await azdata.connection.getCredentials(this.migrationStateModel.sourceConnectionId)).password; this._networkShareTargetDatabaseNames = []; this._blobContainerTargetDatabaseNames = []; @@ -805,7 +822,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { })); this._networkShareTargetDatabaseNames.push(targetDatabaseInput); - const blobtargetDatabaseInput = this._view.modelBuilder.inputBox().withProps({ + const blobTargetDatabaseInput = this._view.modelBuilder.inputBox().withProps({ required: true, value: db, }).withValidation(c => { @@ -823,10 +840,10 @@ export class DatabaseBackupPage extends MigrationWizardPage { } return true; }).component(); - this._disposables.push(blobtargetDatabaseInput.onTextChanged((value) => { + this._disposables.push(blobTargetDatabaseInput.onTextChanged((value) => { this.migrationStateModel._targetDatabaseNames[index] = value.trim(); })); - this._blobContainerTargetDatabaseNames.push(blobtargetDatabaseInput); + this._blobContainerTargetDatabaseNames.push(blobTargetDatabaseInput); const blobContainerResourceDropdown = this._view.modelBuilder.dropDown().withProps({ ariaLabel: constants.BLOB_CONTAINER_RESOURCE_GROUP, @@ -920,7 +937,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { }); data.push(targetRow); }); - this._newtworkShareTargetDatabaseNamesTable.dataValues = data; + this._networkShareTargetDatabaseNamesTable.dataValues = data; data = []; @@ -1093,7 +1110,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { await this._sqlSourceUsernameInput.updateProperties({ required: containerType === NetworkContainerType.NETWORK_SHARE }); - await this._sqlSourcepassword.updateProperties({ + await this._sqlSourcePassword.updateProperties({ required: containerType === NetworkContainerType.NETWORK_SHARE }); await this.validateFields(); @@ -1102,7 +1119,7 @@ export class DatabaseBackupPage extends MigrationWizardPage { private async validateFields(): Promise { await this._sqlSourceUsernameInput.validate(); - await this._sqlSourcepassword.validate(); + await this._sqlSourcePassword.validate(); await this._networkSharePath.validate(); await this._windowsUserAccountText.validate(); await this._passwordText.validate(); diff --git a/extensions/sql-migration/src/wizard/databaseSelectorPage.ts b/extensions/sql-migration/src/wizard/databaseSelectorPage.ts index 1da7b8bb1d..b3f4b2f355 100644 --- a/extensions/sql-migration/src/wizard/databaseSelectorPage.ts +++ b/extensions/sql-migration/src/wizard/databaseSelectorPage.ts @@ -10,6 +10,7 @@ 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'; const styleLeft: azdata.CssStyles = { 'border': 'none', @@ -124,7 +125,7 @@ export class DatabaseSelectorPage extends MigrationWizardPage { const searchContainer = this._view.modelBuilder.divContainer().withItems([resourceSearchBox]).withProps({ CSSStyles: { 'width': '200px', - 'margin': '10px 8px 0px 0px' + 'margin-top': '8px' } }).component(); @@ -204,27 +205,23 @@ export class DatabaseSelectorPage extends MigrationWizardPage { const title = this._view.modelBuilder.text().withProps({ value: constants.DATABASE_FOR_MIGRATION, CSSStyles: { - 'font-size': '28px', - 'line-size': '19px', - 'margin': '16px 0px 20px 0px' + ...styles.PAGE_TITLE_CSS, + 'margin-bottom': '8px' } }).component(); const text = this._view.modelBuilder.text().withProps({ value: constants.DATABASE_MIGRATE_TEXT, CSSStyles: { - 'font-size': '13px', - 'line-size': '19px', - 'margin': '10px 0px 0px 0px' + ...styles.BODY_CSS } }).component(); this._dbCount = this._view.modelBuilder.text().withProps({ value: constants.DATABASES_SELECTED(this.selectedDbs.length, this._databaseTableValues.length), CSSStyles: { - 'font-size': '13px', - 'line-size': '19px', - 'margin': '10px 0px 0px 0px' + ...styles.BODY_CSS, + 'margin-top': '8px' } }).component(); @@ -295,7 +292,7 @@ export class DatabaseSelectorPage extends MigrationWizardPage { height: '100%', }).withProps({ CSSStyles: { - 'margin': '0px 28px 0px 28px' + 'margin': '0px 28px 0px 28px' } }).component(); flex.addItem(title, { flex: '0 0 auto' }); diff --git a/extensions/sql-migration/src/wizard/integrationRuntimePage.ts b/extensions/sql-migration/src/wizard/integrationRuntimePage.ts index 980f5615f3..b9abdc435f 100644 --- a/extensions/sql-migration/src/wizard/integrationRuntimePage.ts +++ b/extensions/sql-migration/src/wizard/integrationRuntimePage.ts @@ -13,11 +13,11 @@ import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController'; import { getLocationDisplayName, getSqlMigrationService, getSqlMigrationServiceAuthKeys, getSqlMigrationServiceMonitoringData, SqlManagedInstance } from '../api/azure'; import { IconPathHelper } from '../constants/iconPathHelper'; import { findDropDownItemIndex } from '../api/utils'; +import * as styles from '../constants/styles'; export class IntergrationRuntimePage extends MigrationWizardPage { private _view!: azdata.ModelView; - private _form!: azdata.FormBuilder; private _statusLoadingComponent!: azdata.LoadingComponent; private _subscription!: azdata.TextComponent; private _location!: azdata.TextComponent; @@ -43,23 +43,6 @@ export class IntergrationRuntimePage extends MigrationWizardPage { protected async registerContent(view: azdata.ModelView): Promise { this._view = view; - const createNewMigrationService = view.modelBuilder.hyperlink().withProps({ - label: constants.CREATE_NEW, - url: '', - CSSStyles: { - 'font-size': '13px' - } - }).component(); - - this._disposables.push(createNewMigrationService.onDidClick(async (e) => { - const dialog = new CreateSqlMigrationServiceDialog(); - const createdDmsResult = await dialog.createNewDms(this.migrationStateModel, (this._resourceGroupDropdown.value).displayName); - this.migrationStateModel._sqlMigrationServiceResourceGroup = createdDmsResult.resourceGroup; - this.migrationStateModel._sqlMigrationService = createdDmsResult.service; - await this.loadResourceGroupDropdown(); - await this.populateDms(createdDmsResult.resourceGroup); - })); - this._statusLoadingComponent = view.modelBuilder.loadingComponent().withItem(this.createDMSDetailsContainer()).component(); this._dmsInfoContainer = this._view.modelBuilder.flexContainer().withItems([ @@ -69,36 +52,36 @@ export class IntergrationRuntimePage extends MigrationWizardPage { text: constants.DMS_PORTAL_INFO, style: 'information', CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS }, width: WIZARD_INPUT_COMPONENT_WIDTH }).component(); - this._form = view.modelBuilder.formContainer() + const form = view.modelBuilder.formContainer() .withFormItems( [ { component: this.migrationServiceDropdownContainer() }, - { - component: createNewMigrationService - }, { component: dmsPortalInfo }, { component: this._dmsInfoContainer } - ] - ); + ).withProps({ + CSSStyles: { + 'padding-top': '0' + } + }).component(); this._disposables.push(this._view.onClosed(e => { this._disposables.forEach( d => { try { d.dispose(); } catch { } }); })); - await view.initializeModel(this._form.component()); + await view.initializeModel(form); } public async onPageEnter(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise { @@ -151,41 +134,37 @@ export class IntergrationRuntimePage extends MigrationWizardPage { value: constants.IR_PAGE_DESCRIPTION, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS, + 'margin-bottom': '16px' } }).component(); const subscriptionLabel = this._view.modelBuilder.text().withProps({ value: constants.SUBSCRIPTION, - requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); this._subscription = this._view.modelBuilder.text().withProps({ enabled: false, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', - 'margin': '0px 0px' + 'margin': '0' } }).component(); const locationLabel = this._view.modelBuilder.text().withProps({ value: constants.LOCATION, - requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS, + 'margin-top': '1em' } }).component(); this._location = this._view.modelBuilder.text().withProps({ enabled: false, width: WIZARD_INPUT_COMPONENT_WIDTH, CSSStyles: { - 'font-size': '13px', - 'margin': '0px 0px' + 'margin': '0' } }).component(); @@ -193,8 +172,7 @@ export class IntergrationRuntimePage extends MigrationWizardPage { value: constants.RESOURCE_GROUP, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); this._resourceGroupDropdown = this._view.modelBuilder.dropDown().withProps({ @@ -204,6 +182,9 @@ export class IntergrationRuntimePage extends MigrationWizardPage { editable: true, required: true, fireOnTextChange: true, + CSSStyles: { + 'margin-top': '-1em' + } }).component(); this._disposables.push(this._resourceGroupDropdown.onValueChanged(async (value) => { const selectedIndex = findDropDownItemIndex(this._resourceGroupDropdown, value); @@ -213,12 +194,11 @@ export class IntergrationRuntimePage extends MigrationWizardPage { } })); - const migrationServcieDropdownLabel = this._view.modelBuilder.text().withProps({ + const migrationServiceDropdownLabel = this._view.modelBuilder.text().withProps({ value: constants.IR_PAGE_TITLE, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); this._dmsDropdown = this._view.modelBuilder.dropDown().withProps({ @@ -228,6 +208,9 @@ export class IntergrationRuntimePage extends MigrationWizardPage { editable: true, required: true, fireOnTextChange: true, + CSSStyles: { + 'margin-top': '-1em' + } }).component(); this._disposables.push(this._dmsDropdown.onValueChanged(async (value) => { if (value && value !== constants.SQL_MIGRATION_SERVICE_NOT_FOUND_ERROR) { @@ -246,6 +229,23 @@ export class IntergrationRuntimePage extends MigrationWizardPage { } })); + const createNewMigrationService = this._view.modelBuilder.hyperlink().withProps({ + label: constants.CREATE_NEW, + url: '', + CSSStyles: { + ...styles.BODY_CSS + } + }).component(); + + this._disposables.push(createNewMigrationService.onDidClick(async (e) => { + const dialog = new CreateSqlMigrationServiceDialog(); + const createdDmsResult = await dialog.createNewDms(this.migrationStateModel, (this._resourceGroupDropdown.value).displayName); + this.migrationStateModel._sqlMigrationServiceResourceGroup = createdDmsResult.resourceGroup; + this.migrationStateModel._sqlMigrationService = createdDmsResult.service; + await this.loadResourceGroupDropdown(); + await this.populateDms(createdDmsResult.resourceGroup); + })); + const flexContainer = this._view.modelBuilder.flexContainer().withItems([ descriptionText, subscriptionLabel, @@ -254,8 +254,9 @@ export class IntergrationRuntimePage extends MigrationWizardPage { this._location, resourceGroupLabel, this._resourceGroupDropdown, - migrationServcieDropdownLabel, - this._dmsDropdown + migrationServiceDropdownLabel, + this._dmsDropdown, + createNewMigrationService ]).withLayout({ flexFlow: 'column' }).component(); @@ -270,10 +271,8 @@ export class IntergrationRuntimePage extends MigrationWizardPage { const connectionStatusLabel = this._view.modelBuilder.text().withProps({ value: constants.SERVICE_CONNECTION_STATUS, CSSStyles: { - 'font-weight': 'bold', - 'font-size': '13px', - 'width': '130px', - 'margin': '0' + ...styles.LABEL_CSS, + 'width': '130px' } }).component(); @@ -295,16 +294,10 @@ export class IntergrationRuntimePage extends MigrationWizardPage { } })); - const connectionLabelContainer = this._view.modelBuilder.flexContainer().withProps({ - CSSStyles: { - 'margin-bottom': '13px' - } - }).component(); - + const connectionLabelContainer = this._view.modelBuilder.flexContainer().component(); connectionLabelContainer.addItem(connectionStatusLabel, { flex: '0' }); - connectionLabelContainer.addItem(this._refreshButton, { flex: '0', CSSStyles: { 'margin-right': '10px' } @@ -319,15 +312,14 @@ export class IntergrationRuntimePage extends MigrationWizardPage { style: 'error', text: '', CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); const authenticationKeysLabel = this._view.modelBuilder.text().withProps({ value: constants.AUTHENTICATION_KEYS, CSSStyles: { - 'font-weight': 'bold', - 'font-size': '13px' + ...styles.LABEL_CSS } }).component(); @@ -364,52 +356,8 @@ export class IntergrationRuntimePage extends MigrationWizardPage { iconPath: IconPathHelper.refresh, ariaLabel: constants.REFRESH_KEY2, }).component(); - this._authKeyTable = this._view.modelBuilder.declarativeTable().withProps({ - ariaLabel: constants.DATABASE_MIGRATION_SERVICE_AUTHENTICATION_KEYS, - columns: [ - { - displayName: constants.NAME, - valueType: azdata.DeclarativeDataType.string, - width: '50px', - isReadOnly: true, - rowCssStyles: { - 'font-size': '13px' - }, - headerCssStyles: { - 'font-size': '13px' - } - }, - { - displayName: constants.AUTH_KEY_COLUMN_HEADER, - valueType: azdata.DeclarativeDataType.string, - width: '500px', - isReadOnly: true, - rowCssStyles: { - 'font-size': '13px', - }, - headerCssStyles: { - 'font-size': '13px' - } - }, - { - displayName: '', - valueType: azdata.DeclarativeDataType.component, - width: '30px', - isReadOnly: true, - rowCssStyles: { - 'font-size': '13px' - }, - headerCssStyles: { - 'font-size': '13px' - } - } - ], - CSSStyles: { - 'margin-top': '5px', - 'width': WIZARD_INPUT_COMPONENT_WIDTH - } - }).component(); + this._authKeyTable = createAuthenticationKeyTable(this._view); statusContainer.addItems([ this._dmsStatusInfoBox, @@ -543,3 +491,55 @@ export class IntergrationRuntimePage extends MigrationWizardPage { } } } + +export function createAuthenticationKeyTable(view: azdata.ModelView,): azdata.DeclarativeTableComponent { + const authKeyTable = view.modelBuilder.declarativeTable().withProps({ + ariaLabel: constants.DATABASE_MIGRATION_SERVICE_AUTHENTICATION_KEYS, + columns: [ + { + displayName: constants.NAME, + valueType: azdata.DeclarativeDataType.string, + width: '50px', + isReadOnly: true, + rowCssStyles: { + ...styles.BODY_CSS + }, + headerCssStyles: { + ...styles.BODY_CSS, + 'font-weight': '600' + } + }, + { + displayName: constants.AUTH_KEY_COLUMN_HEADER, + valueType: azdata.DeclarativeDataType.string, + width: '500px', + isReadOnly: true, + rowCssStyles: { + ...styles.BODY_CSS, + + }, + headerCssStyles: { + ...styles.BODY_CSS, + 'font-weight': '600' + } + }, + { + displayName: '', + valueType: azdata.DeclarativeDataType.component, + width: '30px', + isReadOnly: true, + rowCssStyles: { + ...styles.BODY_CSS + }, + headerCssStyles: { + ...styles.BODY_CSS + } + } + ], + CSSStyles: { + 'margin-top': '5px', + 'width': WIZARD_INPUT_COMPONENT_WIDTH + } + }).component(); + return authKeyTable; +} diff --git a/extensions/sql-migration/src/wizard/migrationModePage.ts b/extensions/sql-migration/src/wizard/migrationModePage.ts index e87617d15c..0d46126476 100644 --- a/extensions/sql-migration/src/wizard/migrationModePage.ts +++ b/extensions/sql-migration/src/wizard/migrationModePage.ts @@ -8,6 +8,7 @@ import * as vscode from 'vscode'; import { MigrationWizardPage } from '../models/migrationWizardPage'; import { MigrationMode, MigrationStateModel, StateChangeEvent } from '../models/stateMachine'; import * as constants from '../constants/strings'; +import * as styles from '../constants/styles'; export class MigrationModePage extends MigrationWizardPage { private _view!: azdata.ModelView; @@ -16,23 +17,39 @@ export class MigrationModePage extends MigrationWizardPage { constructor(wizard: azdata.window.Wizard, migrationStateModel: MigrationStateModel) { super(wizard, azdata.window.createWizardPage(constants.DATABASE_BACKUP_MIGRATION_MODE_LABEL, 'MigrationModePage'), migrationStateModel); - this.wizardPage.description = constants.DATABASE_BACKUP_MIGRATION_MODE_DESCRIPTION; } protected async registerContent(view: azdata.ModelView): Promise { this._view = view; + + const pageDescription = { + title: '', + component: view.modelBuilder.text().withProps({ + value: constants.DATABASE_BACKUP_MIGRATION_MODE_DESCRIPTION, + CSSStyles: { + ...styles.BODY_CSS, + 'margin': '0' + } + }).component() + }; + const form = view.modelBuilder.formContainer() .withFormItems( [ + pageDescription, this.migrationModeContainer(), ] - ); + ).withProps({ + CSSStyles: { + 'padding-top': '0' + } + }).component(); this._disposables.push(this._view.onClosed(e => { this._disposables.forEach( d => { try { d.dispose(); } catch { } }); })); - await view.initializeModel(form.component()); + await view.initializeModel(form); } public async onPageEnter(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise { @@ -60,8 +77,7 @@ export class MigrationModePage extends MigrationWizardPage { label: constants.DATABASE_BACKUP_MIGRATION_MODE_ONLINE_LABEL, name: buttonGroup, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS, }, checked: true }).component(); @@ -69,8 +85,8 @@ export class MigrationModePage extends MigrationWizardPage { const onlineDescription = this._view.modelBuilder.text().withProps({ value: constants.DATABASE_BACKUP_MIGRATION_MODE_ONLINE_DESCRIPTION, CSSStyles: { - 'font-size': '13px', - 'margin': '0 0 10px 20px' + ...styles.NOTE_CSS, + 'margin-left': '20px' } }).component(); @@ -84,16 +100,16 @@ export class MigrationModePage extends MigrationWizardPage { label: constants.DATABASE_BACKUP_MIGRATION_MODE_OFFLINE_LABEL, name: buttonGroup, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold' + ...styles.LABEL_CSS, + 'margin-top': '12px' }, }).component(); const offlineDescription = this._view.modelBuilder.text().withProps({ value: constants.DATABASE_BACKUP_MIGRATION_MODE_OFFLINE_DESCRIPTION, CSSStyles: { - 'font-size': '13px', - 'margin': '0 0 10px 20px' + ...styles.NOTE_CSS, + 'margin-left': '20px' } }).component(); diff --git a/extensions/sql-migration/src/wizard/skuRecommendationPage.ts b/extensions/sql-migration/src/wizard/skuRecommendationPage.ts index a01e88b677..f995820351 100644 --- a/extensions/sql-migration/src/wizard/skuRecommendationPage.ts +++ b/extensions/sql-migration/src/wizard/skuRecommendationPage.ts @@ -13,6 +13,7 @@ import { EOL } from 'os'; import { IconPath, IconPathHelper } from '../constants/iconPathHelper'; import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController'; import { findDropDownItemIndex, selectDropDownIndex } from '../api/utils'; +import * as styles from '../constants/styles'; export interface Product { type: MigrationTargetType; @@ -73,10 +74,14 @@ export class SKURecommendationPage extends MigrationWizardPage { iconPath: IconPathHelper.completedMigration, iconHeight: 17, iconWidth: 17, - width: 17, + width: 20, height: 20 }).component(); - const igContainer = this._view.modelBuilder.flexContainer().component(); + const igContainer = this._view.modelBuilder.flexContainer().withProps({ + CSSStyles: { + 'align-items': 'center' + } + }).component(); igContainer.addItem(this._assessmentStatusIcon, { flex: '0 0 auto' }); @@ -89,32 +94,31 @@ export class SKURecommendationPage extends MigrationWizardPage { const refreshAssessmentButton = this._view.modelBuilder.button().withProps({ iconPath: IconPathHelper.refresh, label: constants.REFRESH_ASSESSMENT_BUTTON_LABEL, - width: 130 + width: 160, + height: 24, + CSSStyles: { + ...styles.BODY_CSS, + 'margin': '12px 0 4px 0' + } }).component(); this._disposables.push(refreshAssessmentButton.onDidClick(async () => { await this.constructDetails(); })); - const chooseYourTargetText = this._view.modelBuilder.text().withProps({ - value: constants.SKU_RECOMMENDATION_CHOOSE_A_TARGET, - CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', - 'margin-top': '16px' - } - }).component(); - const statusContainer = this._view.modelBuilder.flexContainer().withLayout({ - flexFlow: 'column' + flexFlow: 'column', }).withItems( [ igContainer, this._detailsComponent, refreshAssessmentButton, - chooseYourTargetText ] - ).component(); + ).withProps({ + CSSStyles: { + 'margin': '0' + } + }).component(); this._chooseTargetComponent = await this.createChooseTargetComponent(view); this.assessmentGroupContainer = await this.createViewAssessmentsContainer(); this._targetContainer = this.createTargetDropdownContainer(); @@ -136,7 +140,8 @@ export class SKURecommendationPage extends MigrationWizardPage { ] ).withProps({ CSSStyles: { - display: 'none' + 'display': 'none', + 'padding-top': '0', } }); @@ -170,10 +175,8 @@ export class SKURecommendationPage extends MigrationWizardPage { private createStatusComponent(view: azdata.ModelView): azdata.TextComponent { const component = view.modelBuilder.text().withProps({ CSSStyles: { - 'font-size': '14px', - 'margin': '0 0 0 8px', - 'line-height': '20px', - 'font-weight': 'bold' + ...styles.SECTION_HEADER_CSS, + 'margin-left': '8px' } }).component(); return component; @@ -182,7 +185,7 @@ export class SKURecommendationPage extends MigrationWizardPage { private createDetailsComponent(view: azdata.ModelView): azdata.TextComponent { const component = view.modelBuilder.text().withProps({ CSSStyles: { - 'font-size': '13px' + ...styles.BODY_CSS } }).component(); return component; @@ -190,6 +193,14 @@ export class SKURecommendationPage extends MigrationWizardPage { private async createChooseTargetComponent(view: azdata.ModelView): Promise { + const chooseYourTargetText = this._view.modelBuilder.text().withProps({ + value: constants.SKU_RECOMMENDATION_CHOOSE_A_TARGET, + CSSStyles: { + ...styles.SECTION_HEADER_CSS, + 'margin': '0' + } + }).component(); + this._rbg = this._view!.modelBuilder.radioCardGroup().withProps({ cards: [], iconHeight: '35px', @@ -198,12 +209,12 @@ export class SKURecommendationPage extends MigrationWizardPage { cardHeight: '130px', iconPosition: 'left', CSSStyles: { - 'margin-top': '0px' + 'margin-top': '0px', + 'margin-left': '-15px', } }).component(); this._supportedProducts.forEach((product) => { - this._rbg.cards.push({ id: product.type, icon: product.icon, @@ -211,14 +222,13 @@ export class SKURecommendationPage extends MigrationWizardPage { { textValue: product.name, textStyles: { - 'font-size': '14px', - 'font-weight': 'bold' + ...styles.SECTION_HEADER_CSS } }, { textValue: '', textStyles: { - 'font-size': '13px', + ...styles.BODY_CSS } } ] @@ -238,6 +248,7 @@ export class SKURecommendationPage extends MigrationWizardPage { const component = view.modelBuilder.divContainer().withItems( [ + chooseYourTargetText, this._rbgLoader ] ).component(); @@ -248,15 +259,17 @@ export class SKURecommendationPage extends MigrationWizardPage { this._viewAssessmentsHelperText = this._view.modelBuilder.text().withProps({ value: constants.SKU_RECOMMENDATION_VIEW_ASSESSMENT_MI, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.SECTION_HEADER_CSS }, width: WIZARD_INPUT_COMPONENT_WIDTH }).component(); const button = this._view.modelBuilder.button().withProps({ label: constants.VIEW_SELECT_BUTTON_LABEL, - width: 100 + width: 100, + CSSStyles: { + 'margin': '12px 0' + } }).component(); let serverName = ''; @@ -281,7 +294,7 @@ export class SKURecommendationPage extends MigrationWizardPage { this._databaseSelectedHelperText = this._view.modelBuilder.text().withProps({ CSSStyles: { - 'font-size': '13px', + ...styles.BODY_CSS, } }).component(); @@ -298,8 +311,7 @@ export class SKURecommendationPage extends MigrationWizardPage { private createTargetDropdownContainer(): azdata.FlexContainer { this._azureSubscriptionText = this._view.modelBuilder.text().withProps({ CSSStyles: { - 'font-size': '13px', - 'line-height': '18px' + ...styles.SECTION_HEADER_CSS } }).component(); @@ -309,8 +321,7 @@ export class SKURecommendationPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS, } }).component(); this._managedInstanceSubscriptionDropdown = this._view.modelBuilder.dropDown().withProps({ @@ -319,6 +330,9 @@ export class SKURecommendationPage extends MigrationWizardPage { editable: true, required: true, fireOnTextChange: true, + CSSStyles: { + 'margin-top': '-1em' + }, }).component(); this._disposables.push(this._managedInstanceSubscriptionDropdown.onValueChanged(async (value) => { const selectedIndex = findDropDownItemIndex(this._managedInstanceSubscriptionDropdown, value); @@ -336,8 +350,7 @@ export class SKURecommendationPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); this._azureLocationDropdown = this._view.modelBuilder.dropDown().withProps({ @@ -346,6 +359,9 @@ export class SKURecommendationPage extends MigrationWizardPage { editable: true, required: true, fireOnTextChange: true, + CSSStyles: { + 'margin-top': '-1em' + }, }).component(); this._disposables.push(this._azureLocationDropdown.onValueChanged(async (value) => { const selectedIndex = findDropDownItemIndex(this._azureLocationDropdown, value); @@ -361,8 +377,7 @@ export class SKURecommendationPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); this._azureResourceGroupDropdown = this._view.modelBuilder.dropDown().withProps({ @@ -371,6 +386,9 @@ export class SKURecommendationPage extends MigrationWizardPage { editable: true, required: true, fireOnTextChange: true, + CSSStyles: { + 'margin-top': '-1em' + }, }).component(); this._disposables.push(this._azureResourceGroupDropdown.onValueChanged(async (value) => { const selectedIndex = findDropDownItemIndex(this._azureResourceGroupDropdown, value); @@ -386,8 +404,7 @@ export class SKURecommendationPage extends MigrationWizardPage { width: WIZARD_INPUT_COMPONENT_WIDTH, requiredIndicator: true, CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS } }).component(); this._resourceDropdown = this._view.modelBuilder.dropDown().withProps({ @@ -396,6 +413,9 @@ export class SKURecommendationPage extends MigrationWizardPage { editable: true, required: true, fireOnTextChange: true, + CSSStyles: { + 'margin-top': '-1em' + }, }).component(); this._disposables.push(this._resourceDropdown.onValueChanged(value => { const selectedIndex = findDropDownItemIndex(this._resourceDropdown, value); @@ -732,24 +752,20 @@ errorId: ${e.errorId} private createAssessmentProgress(): azdata.FlexContainer { - this._assessmentLoader = this._view.modelBuilder.loadingComponent().withProps({ - CSSStyles: { - 'margin-top': '15px' - } - }).component(); + this._assessmentLoader = this._view.modelBuilder.loadingComponent().component(); this._assessmentProgress = this._view.modelBuilder.text().withProps({ value: constants.ASSESSMENT_IN_PROGRESS, CSSStyles: { - 'font-size': '18px', - 'line-height': '24px', + ...styles.PAGE_TITLE_CSS, 'margin-right': '20px' } }).component(); this._progressContainer = this._view.modelBuilder.flexContainer().withLayout({ height: '100%', - flexFlow: 'row' + flexFlow: 'row', + alignItems: 'center' }).component(); this._progressContainer.addItem(this._assessmentProgress, { flex: '0 0 auto' }); @@ -761,9 +777,8 @@ errorId: ${e.errorId} this._assessmentInfo = this._view.modelBuilder.text().withProps({ value: constants.ASSESSMENT_IN_PROGRESS_CONTENT((await this.migrationStateModel.getSourceConnectionProfile()).serverName), CSSStyles: { - 'font-size': '13px', - 'line-height': '18px', - 'font-weight': '600', + ...styles.BODY_CSS, + 'width': '660px' } }).component(); return this._assessmentInfo; diff --git a/extensions/sql-migration/src/wizard/summaryPage.ts b/extensions/sql-migration/src/wizard/summaryPage.ts index 33899c3671..d5f2aebd96 100644 --- a/extensions/sql-migration/src/wizard/summaryPage.ts +++ b/extensions/sql-migration/src/wizard/summaryPage.ts @@ -11,6 +11,7 @@ import * as constants from '../constants/strings'; import { createHeadingTextComponent, createInformationRow, createLabelTextComponent } from './wizardController'; import { getResourceGroupFromId } from '../api/azure'; import { TargetDatabaseSummaryDialog } from '../dialog/targetDatabaseSummary/targetDatabaseSummaryDialog'; +import * as styles from '../constants/styles'; export class SummaryPage extends MigrationWizardPage { private _view!: azdata.ModelView; @@ -49,10 +50,9 @@ export class SummaryPage extends MigrationWizardPage { url: '', label: this.migrationStateModel._migrationDbs.length.toString(), CSSStyles: { + ...styles.BODY_CSS, 'margin': '0px', 'width': '300px', - 'font-size': '13px', - 'line-height': '24px' } }).component(); @@ -70,10 +70,8 @@ export class SummaryPage extends MigrationWizardPage { [ createLabelTextComponent(this._view, constants.SUMMARY_DATABASE_COUNT_LABEL, { - 'margin': '0px', + ...styles.BODY_CSS, 'width': '300px', - 'font-size': '13px', - 'line-height': '24px' } ), targetDatabaseHyperlink @@ -87,7 +85,7 @@ export class SummaryPage extends MigrationWizardPage { this._flexContainer.addItems( [ - await createHeadingTextComponent(this._view, constants.ACCOUNTS_SELECTION_PAGE_TITLE), + await createHeadingTextComponent(this._view, constants.ACCOUNTS_SELECTION_PAGE_TITLE, true), createInformationRow(this._view, constants.ACCOUNTS_SELECTION_PAGE_TITLE, this.migrationStateModel._azureAccount.displayInfo.displayName), await createHeadingTextComponent(this._view, constants.SOURCE_DATABASES), diff --git a/extensions/sql-migration/src/wizard/wizardController.ts b/extensions/sql-migration/src/wizard/wizardController.ts index d60fe3176b..0e9325f2dc 100644 --- a/extensions/sql-migration/src/wizard/wizardController.ts +++ b/extensions/sql-migration/src/wizard/wizardController.ts @@ -16,6 +16,7 @@ import { SummaryPage } from './summaryPage'; import { MigrationModePage } from './migrationModePage'; import { DatabaseSelectorPage } from './databaseSelectorPage'; import { sendSqlMigrationActionEvent, TelemetryAction, TelemetryViews } from '../telemtery'; +import * as styles from '../constants/styles'; export const WIZARD_INPUT_COMPONENT_WIDTH = '600px'; export class WizardController { @@ -157,44 +158,36 @@ export function createInformationRow(view: azdata.ModelView, label: string, valu [ createLabelTextComponent(view, label, { - 'margin': '0px', + ...styles.BODY_CSS, + 'margin': '4px 0px', 'width': '300px', - 'font-size': '13px', - 'line-height': '24px' } ), - createTextCompononent(view, value, + createTextComponent(view, value, { - 'margin': '0px', + ...styles.BODY_CSS, + 'margin': '4px 0px', 'width': '300px', - 'font-size': '13px', - 'line-height': '24px' } ) - ], - { - CSSStyles: { - 'margin-right': '5px' - } - }) - .component(); + ]).component(); } -export async function createHeadingTextComponent(view: azdata.ModelView, value: string): Promise { - const component = createTextCompononent(view, value); +export async function createHeadingTextComponent(view: azdata.ModelView, value: string, firstElement: boolean = false): Promise { + const component = createTextComponent(view, value); await component.updateCssStyles({ - 'font-size': '13px', - 'font-weight': 'bold', + ...styles.LABEL_CSS, + 'margin-top': firstElement ? '0' : '24px' }); return component; } export function createLabelTextComponent(view: azdata.ModelView, value: string, styles: { [key: string]: string; } = { 'width': '300px' }): azdata.TextComponent { - const component = createTextCompononent(view, value, styles); + const component = createTextComponent(view, value, styles); return component; } -export function createTextCompononent(view: azdata.ModelView, value: string, styles: { [key: string]: string; } = { 'width': '300px' }): azdata.TextComponent { +export function createTextComponent(view: azdata.ModelView, value: string, styles: { [key: string]: string; } = { 'width': '300px' }): azdata.TextComponent { return view.modelBuilder.text().withProps({ value: value, CSSStyles: styles