From e96b1796b331c3d52daee3788870b55829c38513 Mon Sep 17 00:00:00 2001 From: Charles Gagnon Date: Tue, 27 Aug 2019 17:45:38 -0700 Subject: [PATCH] Make service names clickable tab links (#6987) * Make sql master link clickable that opens connection * Improve comments and fix break * Show error message if failed to connect and clear username * Make service names clickable tab links * Remove key handler event again --- .../src/bigDataCluster/dialog/bdcDashboard.ts | 33 +++++++++---- .../dialog/bdcDashboardOverviewPage.ts | 46 ++++++++++--------- 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboard.ts b/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboard.ts index 9744d5351d..e1d6b3e020 100644 --- a/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboard.ts +++ b/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboard.ts @@ -38,6 +38,8 @@ export class BdcDashboard { private currentTab: NavTab; private currentPage: azdata.FlexContainer; + private serviceTabPageMapping: { [key: string]: { navTab: NavTab, servicePage: azdata.FlexContainer } } = {}; + constructor(private title: string, private model: BdcDashboardModel) { this.model.onDidUpdateBdcStatus(bdcStatus => this.handleBdcStatusUpdate(bdcStatus)); } @@ -128,7 +130,7 @@ export class BdcDashboard { const overviewNavItemText = modelView.modelBuilder.text().withProperties({ value: localize('bdc.dashboard.overviewNavTitle', 'Big data cluster overview') }).component(); overviewNavItemText.updateCssStyles(selectedTabCss); overviewNavItemDiv.addItem(overviewNavItemText, { CSSStyles: { 'user-select': 'text' } }); - const overviewPage = new BdcDashboardOverviewPage(this.model).create(modelView); + const overviewPage = new BdcDashboardOverviewPage(this, this.model).create(modelView); this.currentPage = overviewPage; this.currentTab = { div: overviewNavItemDiv, dot: undefined, text: overviewNavItemText }; this.mainAreaContainer.addItem(overviewPage, { flex: '0 0 100%' }); @@ -165,6 +167,25 @@ export class BdcDashboard { this.createServiceNavTabs(bdcStatus.services); } + /** + * Switches the current navigation tab to the one corresponding to the specified service + * @param serviceName The name of the service to switch to the tab of + */ + public switchToServiceTab(serviceName: string): void { + const tabPageMapping = this.serviceTabPageMapping[serviceName]; + if (!tabPageMapping) { + return; + } + if (this.currentTab) { + this.currentTab.text.updateCssStyles(unselectedTabCss); + } + this.mainAreaContainer.removeItem(this.currentPage); + this.mainAreaContainer.addItem(tabPageMapping.servicePage); + this.currentPage = tabPageMapping.servicePage; + this.currentTab = tabPageMapping.navTab; + this.currentTab.text.updateCssStyles(selectedTabCss); + } + /** * Helper to create the navigation tabs for the services once the status has been loaded */ @@ -174,15 +195,9 @@ export class BdcDashboard { services.forEach(s => { const navItem = createServiceNavTab(this.modelView.modelBuilder, s); const serviceStatusPage = new BdcServiceStatusPage(s.serviceName, this.model, this.modelView).container; + this.serviceTabPageMapping[s.serviceName] = { navTab: navItem, servicePage: serviceStatusPage }; navItem.div.onDidClick(() => { - if (this.currentTab) { - this.currentTab.text.updateCssStyles(unselectedTabCss); - } - this.mainAreaContainer.removeItem(this.currentPage); - this.mainAreaContainer.addItem(serviceStatusPage); - this.currentPage = serviceStatusPage; - this.currentTab = navItem; - this.currentTab.text.updateCssStyles(selectedTabCss); + this.switchToServiceTab(s.serviceName); }); this.navContainer.addItem(navItem.div, { flex: '0 0 auto' }); }); diff --git a/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardOverviewPage.ts b/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardOverviewPage.ts index 3469ed7737..17e661ac81 100644 --- a/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardOverviewPage.ts +++ b/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardOverviewPage.ts @@ -12,6 +12,7 @@ import { BdcDashboardModel } from './bdcDashboardModel'; import { IconPathHelper } from '../constants'; import { getStateDisplayText, getHealthStatusDisplayText, getEndpointDisplayText, getHealthStatusIcon, getServiceNameDisplayText, Endpoint } from '../utils'; import { EndpointModel, ServiceStatusModel, BdcStatusModel } from '../controller/apiGenerated'; +import { BdcDashboard } from './bdcDashboard'; const localize = nls.loadMessageBundle(); @@ -38,7 +39,7 @@ export class BdcDashboardOverviewPage { private endpointsRowContainer: azdata.FlexContainer; - constructor(private model: BdcDashboardModel) { + constructor(private dashboard: BdcDashboard, private model: BdcDashboardModel) { this.model.onDidUpdateEndpoints(endpoints => this.handleEndpointsUpdate(endpoints)); this.model.onDidUpdateBdcStatus(bdcStatus => this.handleBdcStatusUpdate(bdcStatus)); } @@ -201,7 +202,7 @@ export class BdcDashboardOverviewPage { if (bdcStatus.services) { this.serviceStatusRowContainer.clearItems(); bdcStatus.services.forEach((s, i) => { - createServiceStatusRow(this.modelBuilder, this.serviceStatusRowContainer, s, i === bdcStatus.services.length - 1); + this.createServiceStatusRow(this.serviceStatusRowContainer, s, i === bdcStatus.services.length - 1); }); } } @@ -216,28 +217,31 @@ export class BdcDashboardOverviewPage { createServiceEndpointRow(this.modelBuilder, this.endpointsRowContainer, e, this.model, hyperlinkedEndpoints.some(he => he === e.name), i === endpoints.length - 1); }); } -} -function createServiceStatusRow(modelBuilder: azdata.ModelBuilder, container: azdata.FlexContainer, serviceStatus: ServiceStatusModel, isLastRow: boolean): void { - const serviceStatusRow = modelBuilder.flexContainer().withLayout({ flexFlow: 'row', alignItems: 'center', height: '30px' }).component(); - const statusIconCell = modelBuilder.text().withProperties({ value: getHealthStatusIcon(serviceStatus.healthStatus), CSSStyles: { 'user-select': 'none' } }).component(); - serviceStatusRow.addItem(statusIconCell, { CSSStyles: { 'width': overviewIconColumnWidth, 'min-width': overviewIconColumnWidth } }); - const nameCell = modelBuilder.text().withProperties({ value: getServiceNameDisplayText(serviceStatus.serviceName), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px' } }).component(); - serviceStatusRow.addItem(nameCell, { CSSStyles: { 'width': overviewServiceNameCellWidth, 'min-width': overviewServiceNameCellWidth, 'user-select': 'text', 'margin-block-start': '0px', 'margin-block-end': '0px' } }); - const stateCell = modelBuilder.text().withProperties({ value: getStateDisplayText(serviceStatus.state), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text', 'text-align': 'center' } }).component(); - serviceStatusRow.addItem(stateCell, { CSSStyles: { 'width': overviewStateCellWidth, 'min-width': overviewStateCellWidth } }); - const healthStatusCell = modelBuilder.text().withProperties({ value: getHealthStatusDisplayText(serviceStatus.healthStatus), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text', 'text-align': 'center' } }).component(); - serviceStatusRow.addItem(healthStatusCell, { CSSStyles: { 'width': overviewHealthStatusCellWidth, 'min-width': overviewHealthStatusCellWidth } }); - - if (serviceStatus.healthStatus !== 'healthy' && serviceStatus.details && serviceStatus.details.length > 0) { - const viewDetailsButton = modelBuilder.button().withProperties({ label: localize('bdc.dashboard.viewDetails', "View Details") }).component(); - viewDetailsButton.onDidClick(() => { - vscode.window.showErrorMessage(serviceStatus.details); + private createServiceStatusRow(container: azdata.FlexContainer, serviceStatus: ServiceStatusModel, isLastRow: boolean): void { + const serviceStatusRow = this.modelBuilder.flexContainer().withLayout({ flexFlow: 'row', alignItems: 'center', height: '30px' }).component(); + const statusIconCell = this.modelBuilder.text().withProperties({ value: getHealthStatusIcon(serviceStatus.healthStatus), CSSStyles: { 'user-select': 'none' } }).component(); + serviceStatusRow.addItem(statusIconCell, { CSSStyles: { 'width': overviewIconColumnWidth, 'min-width': overviewIconColumnWidth } }); + const nameCell = this.modelBuilder.text().withProperties({ value: getServiceNameDisplayText(serviceStatus.serviceName), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'color': '#0078d4', 'text-decoration': 'underline', 'cursor': 'pointer' } }).component(); + nameCell.onDidClick(() => { + this.dashboard.switchToServiceTab(serviceStatus.serviceName); }); - serviceStatusRow.addItem(viewDetailsButton, { flex: '0 0 auto' }); - } + serviceStatusRow.addItem(nameCell, { CSSStyles: { 'width': overviewServiceNameCellWidth, 'min-width': overviewServiceNameCellWidth, 'user-select': 'text', 'margin-block-start': '0px', 'margin-block-end': '0px' } }); + const stateCell = this.modelBuilder.text().withProperties({ value: getStateDisplayText(serviceStatus.state), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text', 'text-align': 'center' } }).component(); + serviceStatusRow.addItem(stateCell, { CSSStyles: { 'width': overviewStateCellWidth, 'min-width': overviewStateCellWidth } }); + const healthStatusCell = this.modelBuilder.text().withProperties({ value: getHealthStatusDisplayText(serviceStatus.healthStatus), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text', 'text-align': 'center' } }).component(); + serviceStatusRow.addItem(healthStatusCell, { CSSStyles: { 'width': overviewHealthStatusCellWidth, 'min-width': overviewHealthStatusCellWidth } }); - container.addItem(serviceStatusRow, { CSSStyles: { 'padding-left': '10px', 'border-top': 'solid 1px #ccc', 'border-bottom': isLastRow ? 'solid 1px #ccc' : '', 'box-sizing': 'border-box', 'user-select': 'text' } }); + if (serviceStatus.healthStatus !== 'healthy' && serviceStatus.details && serviceStatus.details.length > 0) { + const viewDetailsButton = this.modelBuilder.button().withProperties({ label: localize('bdc.dashboard.viewDetails', "View Details") }).component(); + viewDetailsButton.onDidClick(() => { + vscode.window.showErrorMessage(serviceStatus.details); + }); + serviceStatusRow.addItem(viewDetailsButton, { flex: '0 0 auto' }); + } + + container.addItem(serviceStatusRow, { CSSStyles: { 'padding-left': '10px', 'border-top': 'solid 1px #ccc', 'border-bottom': isLastRow ? 'solid 1px #ccc' : '', 'box-sizing': 'border-box', 'user-select': 'text' } }); + } } function createServiceEndpointRow(modelBuilder: azdata.ModelBuilder, container: azdata.FlexContainer, endpoint: EndpointModel, bdcModel: BdcDashboardModel, isHyperlink: boolean, isLastRow: boolean): void {