Maddy/properties widget for endpoints (#5654)

* changes to resue properties widget for endpoints

* comments added

* added loader

* changes to address the review comments: code clean up and constants

* dark theme style fox and misc

* added varibale for display aligment

* renamed hyperlink to isHyperlink

* added endpoints as a modelview to be used on dashboard

* added padding to fix the overlap issues.

* removed the propertieswidget changes

* formatting fixes for hygiene errors

* renamed endpoints to bdc-endpoints

* chnages to address the comments

* added null check
This commit is contained in:
Maddy
2019-05-29 17:30:11 -07:00
committed by GitHub
parent 6d56701b5b
commit 75ce8d6c20
7 changed files with 111 additions and 8 deletions

View File

@@ -400,16 +400,26 @@
"name": "%title.tasks%",
"row": 0,
"col": 0,
"colspan": 2,
"colspan": 1,
"widget": {
"tasks-widget": [
"mssqlCluster.task.newNotebook",
"mssqlCluster.task.openNotebook",
"mssqlCluster.livy.task.submitSparkJob",
"mssqlCluster.livy.task.openSparkHistory",
"mssqlCluster.livy.task.openYarnHistory"
"mssqlCluster.livy.task.submitSparkJob"
]
}
},
{
"name": "%title.endpoints%",
"row": 0,
"col": 2,
"rowspan": 1.5,
"colspan": 2,
"widget": {
"modelview": {
"id": "bdc-endpoints"
}
}
}
]
}

View File

@@ -29,6 +29,8 @@
"title.searchServers": "Search: Servers",
"title.clearSearchServerResult": "Search: Clear Search Server Results",
"title.endpoints": "Service Endpoints",
"mssql.configuration.title": "MSSQL configuration",
"mssql.query.displayBitAsNumber": "Should BIT columns be displayed as numbers (1 or 0)? If false, BIT columns will be displayed as 'true' or 'false'",
"mssql.format.alignColumnDefinitionsInColumns": "Should column definitions be aligned?",

View File

@@ -134,6 +134,59 @@ export async function activate(context: vscode.ExtensionContext): Promise<MssqlE
context.subscriptions.push(new DeleteFilesCommand(prompter, appContext));
context.subscriptions.push({ dispose: () => languageClient.stop() });
azdata.ui.registerModelViewProvider('bdc-endpoints', async (view) => {
const endpointsArray: Array<Utils.IEndpoint> = Object.assign([], view.serverInfo.options['clusterEndpoints']);
if (endpointsArray.length > 0) {
const managementProxyEp = endpointsArray.find(e => e.serviceName === 'management-proxy');
if (managementProxyEp) {
endpointsArray.push(getCustomEndpoint(managementProxyEp, 'Grafana Dashboard', '/grafana'));
endpointsArray.push(getCustomEndpoint(managementProxyEp, 'Kibana Dashboard', '/kibana'));
}
const gatewayEp = endpointsArray.find(e => e.serviceName === 'gateway');
if (gatewayEp) {
endpointsArray.push(getCustomEndpoint(gatewayEp, 'Spark History', '/gateway/default/sparkhistory'));
endpointsArray.push(getCustomEndpoint(gatewayEp, 'Yarn History', '/gateway/default/yarn'));
}
const container = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column', width: '100%', height: '100%', alignItems: 'left' }).component();
endpointsArray.forEach(endpointInfo => {
const endPointRow = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'row' }).component();
const nameCell = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: endpointInfo.serviceName }).component();
endPointRow.addItem(nameCell, { CSSStyles: { 'width': '30%', 'font-weight': '600' } });
if (endpointInfo.isHyperlink) {
const linkCell = view.modelBuilder.hyperlink().withProperties<azdata.HyperlinkComponentProperties>({ label: endpointInfo.hyperlink, url: endpointInfo.hyperlink, position: '' }).component();
endPointRow.addItem(linkCell, { CSSStyles: { 'width': '70%', 'color': 'blue', 'text-decoration': 'underline', 'padding-top': '10px' } });
}
else {
const endpointCell = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: endpointInfo.ipAddress + ':' + endpointInfo.port }).component();
endPointRow.addItem(endpointCell, { CSSStyles: { 'width': '70%' } });
}
container.addItem(endPointRow, { CSSStyles: { 'padding-left': '10px', 'border-top': 'solid 1px #ccc', 'box-sizing': 'border-box' } });
});
const endpointsContainer = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column', width: '100%', height: '100%', alignItems: 'left' }).component();
endpointsContainer.addItem(container, { CSSStyles: { 'padding-top': '25px' } });
await view.initializeModel(endpointsContainer);
}
});
function getCustomEndpoint(parentEndpoint: Utils.IEndpoint, serviceName: string, serviceUrl?: string): Utils.IEndpoint {
if (parentEndpoint) {
let endpoint: Utils.IEndpoint = {
serviceName: serviceName,
ipAddress: parentEndpoint.ipAddress,
port: parentEndpoint.port,
isHyperlink: serviceUrl ? true : false,
hyperlink: 'https://' + parentEndpoint.ipAddress + ':' + parentEndpoint.port + serviceUrl
};
return endpoint;
}
return null;
}
let api: MssqlExtensionApi = {
getMssqlObjectExplorerBrowser(): MssqlObjectExplorerBrowser {
return {

View File

@@ -213,7 +213,9 @@ export async function getClusterEndpoint(profileId: string, serviceName: string)
let clusterEndpoint: IEndpoint = {
serviceName: endpoints[index].serviceName,
ipAddress: endpoints[index].ipAddress,
port: endpoints[index].port
port: endpoints[index].port,
isHyperlink: false,
hyperlink: null
};
return clusterEndpoint;
}
@@ -222,6 +224,8 @@ export interface IEndpoint {
serviceName: string;
ipAddress: string;
port: number;
isHyperlink: boolean;
hyperlink: string;
}
export function isValidNumber(maybeNumber: any) {

View File

@@ -20,6 +20,9 @@
<webview-content *ngIf="isWebview(row,col)" [webviewId]="getWebviewId(row,col)">
</webview-content>
<modelview-content *ngIf="isModelView(row,col)" [modelViewId]="getModelViewId(row,col)">
</modelview-content>
</td>
</ng-container>
</ng-container>

View File

@@ -32,6 +32,13 @@ export interface GridWebviewConfig extends GridCellConfig {
id?: string;
};
}
export interface GridModelViewConfig extends GridCellConfig {
widget: {
modelview: {
id?: string;
}
};
}
@Component({
selector: 'dashboard-grid-container',
@@ -78,6 +85,17 @@ export class DashboardGridContainer extends DashboardTab implements OnDestroy {
return undefined;
}
protected getModelViewContent(row: number, col: number): GridModelViewConfig {
const content = this.getContent(row, col);
if (content) {
const modelviewConfig = <GridModelViewConfig>content;
if (modelviewConfig && modelviewConfig.widget.modelview) {
return modelviewConfig;
}
}
return undefined;
}
protected isWidget(row: number, col: number): boolean {
const widgetConfig = this.getWidgetContent(row, col);
@@ -97,6 +115,18 @@ export class DashboardGridContainer extends DashboardTab implements OnDestroy {
return undefined;
}
protected isModelView(row: number, col: number): boolean {
const modelView = this.getModelViewContent(row, col);
return modelView !== undefined;
}
protected getModelViewId(row: number, col: number): string {
const widgetConfig = this.getModelViewContent(row, col);
if (widgetConfig && widgetConfig.widget.modelview) {
return widgetConfig.widget.modelview.id;
}
return undefined;
}
protected getColspan(row: number, col: number): string {
const content = this.getContent(row, col);
let colspan: string = '1';

View File

@@ -99,9 +99,6 @@ const widgetComponents = [
/* Insights */
const insightComponents = Registry.as<IInsightRegistry>(Extensions.InsightContribution).getAllCtors();
/* Model-backed components */
const extensionComponents = Registry.as<IComponentRegistry>(ComponentExtensions.ComponentContribution).getAllCtors();
// Setup routes for various child components
const appRoutes: Routes = [
{ path: 'database-dashboard', component: DatabaseDashboardPage },
@@ -116,6 +113,10 @@ const appRoutes: Routes = [
// Connection Dashboard main angular module
export const DashboardModule = (params, selector: string, instantiationService: IInstantiationService): any => {
/* Model-backed components */
const extensionComponents = Registry.as<IComponentRegistry>(ComponentExtensions.ComponentContribution).getAllCtors();
@NgModule({
declarations: [
...baseComponents,