Further BDC Dashboard Updates (#6926)

* BDC Dashboard updates

* Add service health status view details

* Add sanity check to endpoint fixing logic for SQL dashboard as well
This commit is contained in:
Charles Gagnon
2019-08-23 17:46:26 -07:00
committed by GitHub
parent 5513f0badd
commit 023d06d114
6 changed files with 68 additions and 17 deletions

View File

@@ -42,6 +42,10 @@
{ {
"command": "bigDataClusters.command.refreshController", "command": "bigDataClusters.command.refreshController",
"when": "false" "when": "false"
},
{
"command": "bigDataClusters.command.manageController",
"when": "false"
} }
], ],
"view/title": [ "view/title": [
@@ -53,14 +57,19 @@
], ],
"view/item/context": [ "view/item/context": [
{ {
"command": "bigDataClusters.command.deleteController", "command": "bigDataClusters.command.manageController",
"when": "viewItem == bigDataClusters.itemType.controllerNode", "when": "viewItem == bigDataClusters.itemType.controllerNode",
"group": "navigation@1" "group": "navigation@1"
}, },
{ {
"command": "bigDataClusters.command.refreshController", "command": "bigDataClusters.command.refreshController",
"when": "viewItem == bigDataClusters.itemType.controllerNode", "when": "viewItem == bigDataClusters.itemType.controllerNode",
"group": "navigation@1" "group": "navigation@2"
},
{
"command": "bigDataClusters.command.deleteController",
"when": "viewItem == bigDataClusters.itemType.controllerNode",
"group": "navigation@3"
} }
] ]
}, },
@@ -96,6 +105,10 @@
"light": "resources/light/refresh.svg", "light": "resources/light/refresh.svg",
"dark": "resources/dark/refresh_inverse.svg" "dark": "resources/dark/refresh_inverse.svg"
} }
},
{
"command": "bigDataClusters.command.manageController",
"title": "%command.manageController.title%"
} }
] ]
}, },

View File

@@ -75,7 +75,7 @@ export class BdcDashboard {
}).component(); }).component();
openTroubleshootNotebookButton.onDidClick(() => { openTroubleshootNotebookButton.onDidClick(() => {
vscode.commands.executeCommand('mssqlCluster.task.openNotebook'); vscode.commands.executeCommand('books.sqlserver2019');
}); });
const toolbarContainer = modelView.modelBuilder.toolbarContainer() const toolbarContainer = modelView.modelBuilder.toolbarContainer()
@@ -131,6 +131,9 @@ export class BdcDashboard {
}); });
this.navContainer.addItem(overviewNavItem, { flex: '0 0 auto' }); this.navContainer.addItem(overviewNavItem, { 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' } });
await modelView.initializeModel(rootContainer); await modelView.initializeModel(rootContainer);
this.initialized = true; this.initialized = true;

View File

@@ -8,7 +8,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { getBdcStatus, getEndPoints } from '../controller/clusterControllerApi'; import { getBdcStatus, getEndPoints } from '../controller/clusterControllerApi';
import { EndpointModel, BdcStatusModel } from '../controller/apiGenerated'; import { EndpointModel, BdcStatusModel } from '../controller/apiGenerated';
import { showErrorMessage } from '../utils'; import { showErrorMessage, Endpoint } from '../utils';
export class BdcDashboardModel { export class BdcDashboardModel {
@@ -50,9 +50,27 @@ export class BdcDashboardModel {
}), }),
getEndPoints(this.url, this.username, this.password, true).then(response => { getEndPoints(this.url, this.username, this.password, true).then(response => {
this._endpoints = response.endPoints || []; this._endpoints = response.endPoints || [];
fixEndpoints(this._endpoints);
this._endpointsLastUpdated = new Date(); this._endpointsLastUpdated = new Date();
this._onDidUpdateEndpoints.fire(this.serviceEndpoints); this._onDidUpdateEndpoints.fire(this.serviceEndpoints);
}) })
]).catch(error => showErrorMessage(error)); ]).catch(error => showErrorMessage(error));
} }
} }
/**
* Applies fixes to the endpoints received so they are displayed correctly
* @param endpoints The endpoints received to modify
*/
function fixEndpoints(endpoints: EndpointModel[]) {
endpoints.forEach(e => {
if (e.name === Endpoint.metricsui && e.endpoint && e.endpoint.indexOf('/d/wZx3OUdmz') === -1) {
// Update to have correct URL
e.endpoint += '/d/wZx3OUdmz';
}
if (e.name === Endpoint.logsui && e.endpoint && e.endpoint.indexOf('/app/kibana#/discover') === -1) {
// Update to have correct URL
e.endpoint += '/app/kibana#/discover';
}
});
}

View File

@@ -6,6 +6,7 @@
'use strict'; 'use strict';
import * as azdata from 'azdata'; import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
import { BdcDashboardModel } from './bdcDashboardModel'; import { BdcDashboardModel } from './bdcDashboardModel';
import { IconPathHelper } from '../constants'; import { IconPathHelper } from '../constants';
@@ -66,7 +67,7 @@ export class BdcDashboardOverviewPage {
// Cluster Name // Cluster Name
const clusterNameLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.clusterName', "Cluster Name :") }).component(); const clusterNameLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.clusterName', "Cluster Name :") }).component();
const clusterNameValue = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: this.model.clusterName }).component(); const clusterNameValue = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: this.model.clusterName }).component();
row1.addItem(clusterNameLabel, { CSSStyles: { 'width': '100px', 'min-width': '100px', 'user-select': 'text' } }); row1.addItem(clusterNameLabel, { CSSStyles: { 'width': '100px', 'min-width': '100px', 'user-select': 'none', 'font-weight': 'bold' } });
row1.addItem(clusterNameValue, { CSSStyles: { 'user-select': 'text' } }); row1.addItem(clusterNameValue, { CSSStyles: { 'user-select': 'text' } });
rootContainer.addItem(row1, { CSSStyles: { 'padding-left': '10px', 'border-top': 'solid 1px #ccc', 'box-sizing': 'border-box', 'user-select': 'text' } }); rootContainer.addItem(row1, { CSSStyles: { 'padding-left': '10px', 'border-top': 'solid 1px #ccc', 'box-sizing': 'border-box', 'user-select': 'text' } });
@@ -76,17 +77,17 @@ export class BdcDashboardOverviewPage {
// Cluster State // Cluster State
const clusterStateLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.clusterState', "Cluster State :") }).component(); const clusterStateLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.clusterState', "Cluster State :") }).component();
const clusterStateValue = view.modelBuilder.text().component(); const clusterStateValue = view.modelBuilder.text().withProperties({ CSSStyles: { 'user-select': 'text' } }).component();
this.clusterStateLoadingComponent = view.modelBuilder.loadingComponent().withItem(clusterStateValue).component(); this.clusterStateLoadingComponent = view.modelBuilder.loadingComponent().withItem(clusterStateValue).component();
row2.addItem(clusterStateLabel, { CSSStyles: { 'width': '125px', 'min-width': '125px', 'user-select': 'text' } }); row2.addItem(clusterStateLabel, { CSSStyles: { 'width': '125px', 'min-width': '125px', 'user-select': 'none', 'font-weight': 'bold' } });
row2.addItem(this.clusterStateLoadingComponent, { CSSStyles: { 'width': '125px', 'min-width': '125px', 'user-select': 'text' } }); row2.addItem(this.clusterStateLoadingComponent, { CSSStyles: { 'width': '125px', 'min-width': '125px', 'user-select': 'none' } });
// Health Status // Health Status
const healthStatusLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.healthStatus', "Health Status :") }).component(); const healthStatusLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.healthStatus', "Health Status :") }).component();
const healthStatusValue = view.modelBuilder.text().component(); const healthStatusValue = view.modelBuilder.text().withProperties({ CSSStyles: { 'user-select': 'text' } }).component();
this.clusterHealthStatusLoadingComponent = view.modelBuilder.loadingComponent().withItem(healthStatusValue).component(); this.clusterHealthStatusLoadingComponent = view.modelBuilder.loadingComponent().withItem(healthStatusValue).component();
row2.addItem(healthStatusLabel, { CSSStyles: { 'width': '125px', 'min-width': '125px', 'user-select': 'text' } }); row2.addItem(healthStatusLabel, { CSSStyles: { 'width': '125px', 'min-width': '125px', 'user-select': 'none', 'font-weight': 'bold' } });
row2.addItem(this.clusterHealthStatusLoadingComponent, { CSSStyles: { 'width': '125px', 'min-width': '125px', 'user-select': 'text' } }); row2.addItem(this.clusterHealthStatusLoadingComponent, { CSSStyles: { 'width': '125px', 'min-width': '125px', 'user-select': 'none' } });
rootContainer.addItem(row2, { CSSStyles: { 'padding-left': '10px', 'border-bottom': 'solid 1px #ccc', 'box-sizing': 'border-box', 'user-select': 'text' } }); rootContainer.addItem(row2, { CSSStyles: { 'padding-left': '10px', 'border-bottom': 'solid 1px #ccc', 'box-sizing': 'border-box', 'user-select': 'text' } });
@@ -228,6 +229,14 @@ function createServiceStatusRow(modelBuilder: azdata.ModelBuilder, container: az
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(); 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 } }); serviceStatusRow.addItem(healthStatusCell, { CSSStyles: { 'width': overviewHealthStatusCellWidth, 'min-width': overviewHealthStatusCellWidth } });
if (serviceStatus.healthStatus !== 'healthy' && serviceStatus.details && serviceStatus.details.length > 0) {
const viewDetailsButton = modelBuilder.button().withProperties<azdata.ButtonProperties>({ 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' } }); 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' } });
} }
@@ -237,25 +246,25 @@ function createServiceEndpointRow(modelBuilder: azdata.ModelBuilder, container:
endPointRow.addItem(nameCell, { CSSStyles: { 'width': serviceEndpointRowServiceNameCellWidth, 'min-width': serviceEndpointRowServiceNameCellWidth, 'user-select': 'text', 'text-align': 'center' } }); endPointRow.addItem(nameCell, { CSSStyles: { 'width': serviceEndpointRowServiceNameCellWidth, 'min-width': serviceEndpointRowServiceNameCellWidth, 'user-select': 'text', 'text-align': 'center' } });
if (isHyperlink) { if (isHyperlink) {
const endpointCell = modelBuilder.hyperlink() const endpointCell = modelBuilder.hyperlink()
.withProperties({ label: endpoint.endpoint, url: endpoint.endpoint, CSSStyles: { 'height': '15px' } }) .withProperties({ label: endpoint.endpoint, url: endpoint.endpoint, CSSStyles: { 'height': '15px', 'padding-left': '10px' } })
.component(); .component();
endPointRow.addItem(endpointCell, { CSSStyles: { 'width': serviceEndpointRowEndpointCellWidth, 'min-width': serviceEndpointRowEndpointCellWidth, 'color': '#0078d4', 'text-decoration': 'underline', 'overflow': 'hidden' } }); endPointRow.addItem(endpointCell, { CSSStyles: { 'width': serviceEndpointRowEndpointCellWidth, 'min-width': serviceEndpointRowEndpointCellWidth, 'color': '#0078d4', 'text-decoration': 'underline', 'overflow': 'hidden' } });
} }
else { else {
const endpointCell = modelBuilder.text() const endpointCell = modelBuilder.text()
.withProperties({ value: endpoint.endpoint, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text' } }) .withProperties({ value: endpoint.endpoint, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text', 'padding-left': '10px' } })
.component(); .component();
endPointRow.addItem(endpointCell, { CSSStyles: { 'width': serviceEndpointRowEndpointCellWidth, 'min-width': serviceEndpointRowEndpointCellWidth, 'overflow': 'hidden' } }); endPointRow.addItem(endpointCell, { CSSStyles: { 'width': serviceEndpointRowEndpointCellWidth, 'min-width': serviceEndpointRowEndpointCellWidth, 'overflow': 'hidden' } });
} }
const copyValueCell = modelBuilder.button().component(); const copyValueCell = modelBuilder.button().component();
copyValueCell.iconPath = IconPathHelper.copy; copyValueCell.iconPath = IconPathHelper.copy;
copyValueCell.onDidClick(() => { copyValueCell.onDidClick(() => {
// vscode.env.clipboard.writeText(hyperlink); vscode.env.clipboard.writeText(endpoint.endpoint);
}); });
copyValueCell.title = localize('bdc.dashboard.copyTitle', "Copy"); copyValueCell.title = localize('bdc.dashboard.copyTitle', "Copy");
copyValueCell.iconHeight = '14px'; copyValueCell.iconHeight = '14px';
copyValueCell.iconWidth = '14px'; copyValueCell.iconWidth = '14px';
endPointRow.addItem(copyValueCell, { CSSStyles: { 'width': '50px', 'min-width': '50px', 'padding-left': '10px', 'margin-block-start': '0px', 'margin-block-end': '0px' } }); endPointRow.addItem(copyValueCell, { CSSStyles: { 'width': '14px', 'min-width': '14px', 'padding-left': '10px', 'margin-block-start': '0px', 'margin-block-end': '0px' } });
container.addItem(endPointRow, { CSSStyles: { 'padding-left': '10px', 'border-top': 'solid 1px #ccc', 'border-bottom': isLastRow ? 'solid 1px #ccc' : '', 'box-sizing': 'border-box', 'user-select': 'text' } }); container.addItem(endPointRow, { CSSStyles: { 'padding-left': '10px', 'border-top': 'solid 1px #ccc', 'border-bottom': isLastRow ? 'solid 1px #ccc' : '', 'box-sizing': 'border-box', 'user-select': 'text' } });
} }

View File

@@ -5,6 +5,7 @@
'use strict'; 'use strict';
import * as azdata from 'azdata'; import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
import { BdcDashboardModel } from './bdcDashboardModel'; import { BdcDashboardModel } from './bdcDashboardModel';
import { BdcStatusModel, InstanceStatusModel } from '../controller/apiGenerated'; import { BdcStatusModel, InstanceStatusModel } from '../controller/apiGenerated';
@@ -180,6 +181,13 @@ function createInstanceHealthStatusRow(modelBuilder: azdata.ModelBuilder, instan
const healthStatusCell = modelBuilder.text().withProperties({ value: getHealthStatusDisplayText(instanceStatus.healthStatus), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text' } }).component(); const healthStatusCell = modelBuilder.text().withProperties({ value: getHealthStatusDisplayText(instanceStatus.healthStatus), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '0px', 'user-select': 'text' } }).component();
instanceHealthStatusRow.addItem(healthStatusCell, { CSSStyles: { 'width': healthAndStatusHealthColumnWidth, 'min-width': healthAndStatusHealthColumnWidth } }); instanceHealthStatusRow.addItem(healthStatusCell, { CSSStyles: { 'width': healthAndStatusHealthColumnWidth, 'min-width': healthAndStatusHealthColumnWidth } });
if (instanceStatus.healthStatus !== 'healthy' && instanceStatus.details && instanceStatus.details.length > 0) {
const viewDetailsButton = modelBuilder.button().withProperties<azdata.ButtonProperties>({ label: localize('bdc.dashboard.viewDetails', "View Details") }).component();
viewDetailsButton.onDidClick(() => {
vscode.window.showErrorMessage(instanceStatus.details);
});
instanceHealthStatusRow.addItem(viewDetailsButton, { flex: '0 0 auto' });
}
return instanceHealthStatusRow; return instanceHealthStatusRow;
} }

View File

@@ -27,12 +27,12 @@ export function registerServiceEndpoints(context: vscode.ExtensionContext): void
if (endpointsArray.length > 0) { if (endpointsArray.length > 0) {
const grafanaEp = endpointsArray.find(e => e.serviceName === grafanaEndpointName); const grafanaEp = endpointsArray.find(e => e.serviceName === grafanaEndpointName);
if (grafanaEp) { if (grafanaEp && grafanaEp.endpoint && grafanaEp.endpoint.indexOf('/d/wZx3OUdmz') === -1) {
// Update to have correct URL // Update to have correct URL
grafanaEp.endpoint += '/d/wZx3OUdmz'; grafanaEp.endpoint += '/d/wZx3OUdmz';
} }
const kibanaEp = endpointsArray.find(e => e.serviceName === logsuiEndpointName); const kibanaEp = endpointsArray.find(e => e.serviceName === logsuiEndpointName);
if (kibanaEp) { if (kibanaEp && kibanaEp.endpoint && kibanaEp.endpoint.indexOf('/app/kibana#/discover') === -1) {
// Update to have correct URL // Update to have correct URL
kibanaEp.endpoint += '/app/kibana#/discover'; kibanaEp.endpoint += '/app/kibana#/discover';
} }