Add styling to selected tabs in BDC Dashboard (#6978)

* Change cursor over tabs to be hand (pointer)

* Change hyperlink color

* Hook up CSSStyles to be updated from extension side and make BDC dashboard tabs change style when selected

* Remove unused file

* Add back in call to updateStyles

* Fix typos
This commit is contained in:
Charles Gagnon
2019-08-27 14:14:46 -07:00
committed by GitHub
parent 1e217094a7
commit a27b759b10
7 changed files with 84 additions and 33 deletions

View File

@@ -12,12 +12,17 @@ import { BdcDashboardModel } from './bdcDashboardModel';
import { IconPathHelper } from '../constants';
import { BdcServiceStatusPage } from './bdcServiceStatusPage';
import { BdcDashboardOverviewPage } from './bdcDashboardOverviewPage';
import { EndpointModel, BdcStatusModel, ServiceStatusModel } from '../controller/apiGenerated';
import { BdcStatusModel, ServiceStatusModel } from '../controller/apiGenerated';
import { getHealthStatusDot, getServiceNameDisplayText } from '../utils';
const localize = nls.loadMessageBundle();
const navWidth = '175px';
const navWidth = '200px';
const selectedTabCss = { 'font-weight': 'bold' };
const unselectedTabCss = { 'font-weight': '' };
type NavTab = { div: azdata.DivContainer, dot: azdata.TextComponent, text: azdata.TextComponent };
export class BdcDashboard {
@@ -29,6 +34,8 @@ export class BdcDashboard {
private modelView: azdata.ModelView;
private mainAreaContainer: azdata.FlexContainer;
private navContainer: azdata.FlexContainer;
private currentTab: NavTab;
private currentPage: azdata.FlexContainer;
constructor(private title: string, private model: BdcDashboardModel) {
@@ -117,18 +124,26 @@ export class BdcDashboard {
this.mainAreaContainer.addItem(this.navContainer, { flex: `0 0 ${navWidth}`, CSSStyles: { 'padding-left': '10px', 'border-right': 'solid 1px #ccc' } });
// Overview nav item - this will be the initial page
const overviewNavItem = modelView.modelBuilder.divContainer().withLayout({ width: navWidth, height: '30px' }).component();
overviewNavItem.addItem(modelView.modelBuilder.text().withProperties({ value: localize('bdc.dashboard.overviewNavTitle', 'Big data cluster overview') }).component(), { CSSStyles: { 'user-select': 'text' } });
const overviewNavItemDiv = modelView.modelBuilder.divContainer().withLayout({ width: navWidth, height: '30px' }).withProperties({ CSSStyles: { 'cursor': 'pointer' } }).component();
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);
this.currentPage = overviewPage;
this.currentTab = { div: overviewNavItemDiv, dot: undefined, text: overviewNavItemText };
this.mainAreaContainer.addItem(overviewPage, { flex: '0 0 100%' });
overviewNavItem.onDidClick(() => {
overviewNavItemDiv.onDidClick(() => {
if (this.currentTab) {
this.currentTab.text.updateCssStyles(unselectedTabCss);
}
this.mainAreaContainer.removeItem(this.currentPage);
this.mainAreaContainer.addItem(overviewPage, { flex: '0 0 100%' });
this.currentPage = overviewPage;
this.currentTab = { div: overviewNavItemDiv, dot: undefined, text: overviewNavItemText };
this.currentTab.text.updateCssStyles(selectedTabCss);
});
this.navContainer.addItem(overviewNavItem, { flex: '0 0 auto' });
this.navContainer.addItem(overviewNavItemDiv, { flex: '0 0 auto' });
const clusterDetailsHeader = modelView.modelBuilder.text().withProperties({ value: localize('bdc.dashboard.clusterDetails', 'Cluster Details'), CSSStyles: { 'margin-block-end': '0px' } }).component();
this.navContainer.addItem(clusterDetailsHeader, { CSSStyles: { 'user-select': 'none', 'font-weight': 'bold', 'border-bottom': 'solid 1px #ccc', 'margin-bottom': '10px' } });
@@ -159,23 +174,30 @@ export class BdcDashboard {
services.forEach(s => {
const navItem = createServiceNavTab(this.modelView.modelBuilder, s);
const serviceStatusPage = new BdcServiceStatusPage(s.serviceName, this.model, this.modelView).container;
navItem.onDidClick(() => {
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.navContainer.addItem(navItem, { flex: '0 0 auto' });
this.navContainer.addItem(navItem.div, { flex: '0 0 auto' });
});
this.serviceTabsCreated = true;
}
}
}
function createServiceNavTab(modelBuilder: azdata.ModelBuilder, serviceStatus: ServiceStatusModel): azdata.DivContainer {
const div = modelBuilder.divContainer().withLayout({ width: navWidth, height: '30px' }).component();
function createServiceNavTab(modelBuilder: azdata.ModelBuilder, serviceStatus: ServiceStatusModel): NavTab {
const div = modelBuilder.divContainer().withLayout({ width: navWidth, height: '30px' }).withProperties({ CSSStyles: { 'cursor': 'pointer' } }).component();
const innerContainer = modelBuilder.flexContainer().withLayout({ width: navWidth, height: '30px', flexFlow: 'row' }).component();
innerContainer.addItem(modelBuilder.text().withProperties({ value: getHealthStatusDot(serviceStatus.healthStatus), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'none', 'color': 'red', 'font-size': '40px', 'width': '20px' } }).component(), { flex: '0 0 auto' });
innerContainer.addItem(modelBuilder.text().withProperties({ value: getServiceNameDisplayText(serviceStatus.serviceName), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text' } }).component(), { flex: '0 0 auto' });
const dot = modelBuilder.text().withProperties({ value: getHealthStatusDot(serviceStatus.healthStatus), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'none', 'color': 'red', 'font-size': '40px', 'width': '20px' } }).component();
innerContainer.addItem(dot, { flex: '0 0 auto' });
const text = modelBuilder.text().withProperties({ value: getServiceNameDisplayText(serviceStatus.serviceName), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'none' } }).component();
innerContainer.addItem(text, { flex: '0 0 auto' });
div.addItem(innerContainer);
return div;
return { div: div, dot: dot, text: text };
}

View File

@@ -200,9 +200,9 @@ function createMetricsAndLogsRow(modelBuilder: azdata.ModelBuilder, instanceStat
const metricsAndLogsRow = modelBuilder.flexContainer().withLayout({ flexFlow: 'row', alignItems: 'center', height: '30px' }).component();
const nameCell = modelBuilder.text().withProperties({ value: instanceStatus.instanceName, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px' } }).component();
metricsAndLogsRow.addItem(nameCell, { CSSStyles: { 'width': '100px', 'min-width': '100px', 'user-select': 'text', 'margin-block-start': '0px', 'margin-block-end': '0px' } });
const metricsCell = modelBuilder.hyperlink().withProperties({ label: localize('bdc.dashboard.viewHyperlink', "View"), url: instanceStatus.dashboards.nodeMetricsUrl, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text' } }).component();
const metricsCell = modelBuilder.hyperlink().withProperties({ label: localize('bdc.dashboard.viewHyperlink', "View"), url: instanceStatus.dashboards.nodeMetricsUrl, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text', 'color': '#0078d4', 'text-decoration': 'underline' } }).component();
metricsAndLogsRow.addItem(metricsCell, { CSSStyles: { 'width': '75px', 'min-width': '75px' } });
const logsCell = modelBuilder.hyperlink().withProperties({ label: localize('bdc.dashboard.viewHyperlink', "View"), url: instanceStatus.dashboards.logsUrl, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text' } }).component();
const logsCell = modelBuilder.hyperlink().withProperties({ label: localize('bdc.dashboard.viewHyperlink', "View"), url: instanceStatus.dashboards.logsUrl, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text', 'color': '#0078d4', 'text-decoration': 'underline' } }).component();
metricsAndLogsRow.addItem(logsCell, { CSSStyles: { 'width': '75px', 'min-width': '75px' } });
return metricsAndLogsRow;

View File

@@ -10,11 +10,15 @@ import { BdcDashboardResourceStatusPage } from './bdcDashboardResourceStatusPage
import { BdcDashboardModel } from './bdcDashboardModel';
import { getHealthStatusDot } from '../utils';
const selectedTabCss = { 'font-weight': 'bold' };
const unselectedTabCss = { 'font-weight': '' };
export class BdcServiceStatusPage {
private initialized: boolean = false;
private resourceTabsCreated: boolean = false;
private currentTabText: azdata.TextComponent;
private currentTabPage: azdata.FlexContainer;
private rootContainer: azdata.FlexContainer;
private resourceHeader: azdata.FlexContainer;
@@ -78,13 +82,20 @@ export class BdcServiceStatusPage {
resources.forEach(resource => {
const resourceHeaderTab = createResourceHeaderTab(this.modelView.modelBuilder, resource);
const resourceStatusPage: azdata.FlexContainer = new BdcDashboardResourceStatusPage(this.model, this.modelView, this.serviceName, resource.resourceName).container;
resourceHeaderTab.onDidClick(() => {
resourceHeaderTab.div.onDidClick(() => {
if (this.currentTabText) {
this.currentTabText.updateCssStyles(unselectedTabCss);
}
this.changeSelectedTabPage(resourceStatusPage);
this.currentTabText = resourceHeaderTab.text;
this.currentTabText.updateCssStyles(selectedTabCss);
});
if (!this.currentTabPage) {
this.changeSelectedTabPage(resourceStatusPage);
this.currentTabText = resourceHeaderTab.text;
this.currentTabText.updateCssStyles(selectedTabCss);
}
this.resourceHeader.addItem(resourceHeaderTab, { flex: '0 0 auto', CSSStyles: { 'border-bottom': 'solid #ccc' } });
this.resourceHeader.addItem(resourceHeaderTab.div, { flex: '0 0 auto', CSSStyles: { 'border-bottom': 'solid #ccc' } });
});
this.resourceTabsCreated = true;
}
@@ -96,12 +107,12 @@ export class BdcServiceStatusPage {
* @param modelBuilder The ModelBuilder used to construct the object
* @param title The text to display in the tab
*/
function createResourceHeaderTab(modelBuilder: azdata.ModelBuilder, resourceStatus: ResourceStatusModel): azdata.DivContainer {
const resourceHeaderTab = modelBuilder.divContainer().withLayout({ width: '100px', height: '25px' }).component();
function createResourceHeaderTab(modelBuilder: azdata.ModelBuilder, resourceStatus: ResourceStatusModel): { div: azdata.DivContainer, text: azdata.TextComponent } {
const resourceHeaderTab = modelBuilder.divContainer().withLayout({ width: '100px', height: '25px' }).withProperties({ CSSStyles: { 'cursor': 'pointer' } }).component();
const innerContainer = modelBuilder.flexContainer().withLayout({ width: '100px', height: '25px', flexFlow: 'row' }).component();
innerContainer.addItem(modelBuilder.text().withProperties({ value: getHealthStatusDot(resourceStatus.healthStatus), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'none', 'color': 'red', 'font-size': '40px', 'width': '20px', 'text-align': 'right' } }).component(), { flex: '0 0 auto' });
const resourceHeaderLabel = modelBuilder.text().withProperties({ value: resourceStatus.resourceName, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'text-align': 'left' } }).component();
innerContainer.addItem(resourceHeaderLabel);
resourceHeaderTab.addItem(innerContainer);
return resourceHeaderTab;
return { div: resourceHeaderTab, text: resourceHeaderLabel };
}