mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Tab contribution support both inline container and registered container (#766)
* accept inline nav section contribution * contribution accepted both inline container and registered container * address comments * formatting
This commit is contained in:
@@ -6,12 +6,27 @@ import * as types from 'vs/base/common/types';
|
|||||||
import { generateUuid } from 'vs/base/common/uuid';
|
import { generateUuid } from 'vs/base/common/uuid';
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import { Severity } from 'vs/platform/message/common/message';
|
import { Severity } from 'vs/platform/message/common/message';
|
||||||
|
import { error } from 'sql/base/common/log';
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry';
|
||||||
import { ConnectionManagementInfo } from 'sql/parts/connection/common/connectionManagementInfo';
|
import { ConnectionManagementInfo } from 'sql/parts/connection/common/connectionManagementInfo';
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
|
import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
||||||
|
import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
||||||
|
import { WEBVIEW_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWebviewContainer.contribution';
|
||||||
|
import { NAV_SECTION } from 'sql/parts/dashboard/containers/dashboardNavSection.contribution';
|
||||||
|
import { IDashboardContainerRegistry, Extensions as DashboardContainerExtensions, IDashboardContainer, registerContainerType } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||||
|
import { IDashboardTab } from 'sql/platform/dashboard/common/dashboardRegistry';
|
||||||
|
|
||||||
|
const dashboardcontainerRegistry = Registry.as<IDashboardContainerRegistry>(DashboardContainerExtensions.dashboardContainerContributions);
|
||||||
|
const containerTypes = [
|
||||||
|
WIDGETS_CONTAINER,
|
||||||
|
GRID_CONTAINER,
|
||||||
|
WEBVIEW_CONTAINER,
|
||||||
|
NAV_SECTION
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,4 +187,26 @@ export function filterConfigs<T extends { provider?: string | string[], edition?
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get registered container if it is specified as the key
|
||||||
|
* @param container dashboard container
|
||||||
|
*/
|
||||||
|
export function getDashboardContainer(container: object): object {
|
||||||
|
if (Object.keys(container).length !== 1) {
|
||||||
|
error(nls.localize('moreThanOneDashboardContainersError', 'Exactly 1 dashboard container must be defined per space'));
|
||||||
|
}
|
||||||
|
|
||||||
|
let key = Object.keys(container)[0];
|
||||||
|
let containerTypeFound = containerTypes.find(c => (c === key));
|
||||||
|
if (!containerTypeFound) {
|
||||||
|
let dashboardContainer = dashboardcontainerRegistry.getRegisteredContainer(key);
|
||||||
|
if (!dashboardContainer) {
|
||||||
|
error(nls.localize('unknownDashboardContainerError', 'The specified dashboard container is unknown.'));
|
||||||
|
} else {
|
||||||
|
container = dashboardContainer.container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return container;
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/
|
|||||||
import { AngularEventType } from 'sql/services/angularEventing/angularEventingService';
|
import { AngularEventType } from 'sql/services/angularEventing/angularEventingService';
|
||||||
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||||
import { error } from 'sql/base/common/log';
|
import { error } from 'sql/base/common/log';
|
||||||
import * as widgetHelper from 'sql/parts/dashboard/common/dashboardWidgetHelper';
|
import * as dashboardHelper from 'sql/parts/dashboard/common/dashboardHelper';
|
||||||
import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
||||||
import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
||||||
|
|
||||||
@@ -72,16 +72,16 @@ export abstract class DashboardPage extends Disposable implements OnDestroy {
|
|||||||
|
|
||||||
// a set of config modifiers
|
// a set of config modifiers
|
||||||
private readonly _configModifiers: Array<(item: Array<WidgetConfig>, dashboardServer: DashboardServiceInterface, context: string) => Array<WidgetConfig>> = [
|
private readonly _configModifiers: Array<(item: Array<WidgetConfig>, dashboardServer: DashboardServiceInterface, context: string) => Array<WidgetConfig>> = [
|
||||||
widgetHelper.removeEmpty,
|
dashboardHelper.removeEmpty,
|
||||||
widgetHelper.initExtensionConfigs,
|
dashboardHelper.initExtensionConfigs,
|
||||||
widgetHelper.addProvider,
|
dashboardHelper.addProvider,
|
||||||
widgetHelper.addEdition,
|
dashboardHelper.addEdition,
|
||||||
widgetHelper.addContext,
|
dashboardHelper.addContext,
|
||||||
widgetHelper.filterConfigs
|
dashboardHelper.filterConfigs
|
||||||
];
|
];
|
||||||
|
|
||||||
private readonly _gridModifiers: Array<(item: Array<WidgetConfig>, originalConfig: Array<WidgetConfig>) => Array<WidgetConfig>> = [
|
private readonly _gridModifiers: Array<(item: Array<WidgetConfig>, originalConfig: Array<WidgetConfig>) => Array<WidgetConfig>> = [
|
||||||
widgetHelper.validateGridConfig
|
dashboardHelper.validateGridConfig
|
||||||
];
|
];
|
||||||
|
|
||||||
protected abstract propertiesWidget: WidgetConfig;
|
protected abstract propertiesWidget: WidgetConfig;
|
||||||
@@ -140,7 +140,7 @@ export abstract class DashboardPage extends Disposable implements OnDestroy {
|
|||||||
this.addNewTab(homeTab);
|
this.addNewTab(homeTab);
|
||||||
this._panel.selectTab(homeTab.id);
|
this._panel.selectTab(homeTab.id);
|
||||||
|
|
||||||
let allTabs = widgetHelper.filterConfigs(dashboardRegistry.tabs, this.dashboardService);
|
let allTabs = dashboardHelper.filterConfigs(dashboardRegistry.tabs, this.dashboardService);
|
||||||
|
|
||||||
// Load always show tabs
|
// Load always show tabs
|
||||||
let alwaysShowTabs = allTabs.filter(tab => tab.alwaysShow);
|
let alwaysShowTabs = allTabs.filter(tab => tab.alwaysShow);
|
||||||
@@ -192,14 +192,11 @@ export abstract class DashboardPage extends Disposable implements OnDestroy {
|
|||||||
private loadNewTabs(dashboardTabs: IDashboardTab[]) {
|
private loadNewTabs(dashboardTabs: IDashboardTab[]) {
|
||||||
if (dashboardTabs && dashboardTabs.length > 0) {
|
if (dashboardTabs && dashboardTabs.length > 0) {
|
||||||
let selectedTabs = dashboardTabs.map(v => {
|
let selectedTabs = dashboardTabs.map(v => {
|
||||||
|
let container = dashboardHelper.getDashboardContainer(v.container);
|
||||||
|
let key = Object.keys(container)[0];
|
||||||
|
|
||||||
if (Object.keys(v.container).length !== 1) {
|
|
||||||
error('Exactly 1 content must be defined per space');
|
|
||||||
}
|
|
||||||
|
|
||||||
let key = Object.keys(v.container)[0];
|
|
||||||
if (key === WIDGETS_CONTAINER || key === GRID_CONTAINER) {
|
if (key === WIDGETS_CONTAINER || key === GRID_CONTAINER) {
|
||||||
let configs = <WidgetConfig[]>Object.values(v.container)[0];
|
let configs = <WidgetConfig[]>Object.values(container)[0];
|
||||||
this._configModifiers.forEach(cb => {
|
this._configModifiers.forEach(cb => {
|
||||||
configs = cb.apply(this, [configs, this.dashboardService, this.context]);
|
configs = cb.apply(this, [configs, this.dashboardService, this.context]);
|
||||||
});
|
});
|
||||||
@@ -213,7 +210,7 @@ export abstract class DashboardPage extends Disposable implements OnDestroy {
|
|||||||
return { id: v.id, title: v.title, container: { 'grid-container': configs }, alwaysShow: v.alwaysShow };
|
return { id: v.id, title: v.title, container: { 'grid-container': configs }, alwaysShow: v.alwaysShow };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v;
|
return { id: v.id, title: v.title, container: container, alwaysShow: v.alwaysShow };
|
||||||
}).map(v => {
|
}).map(v => {
|
||||||
let actions = [];
|
let actions = [];
|
||||||
if (!v.alwaysShow) {
|
if (!v.alwaysShow) {
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import { IExtensionPointUser, ExtensionsRegistry } from 'vs/platform/extensions/
|
|||||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
|
|
||||||
import { registerTab, generateTabContentSchemaProperties } from 'sql/platform/dashboard/common/dashboardRegistry';
|
import { registerTab } from 'sql/platform/dashboard/common/dashboardRegistry';
|
||||||
|
import { generateContainerTypeSchemaProperties } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||||
|
|
||||||
export interface IDashboardTabContrib {
|
export interface IDashboardTabContrib {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -64,7 +65,7 @@ const tabSchema: IJSONSchema = {
|
|||||||
container: {
|
container: {
|
||||||
description: localize('sqlops.extension.contributes.dashboard.tab.container', "The container that will be displayed in this tab."),
|
description: localize('sqlops.extension.contributes.dashboard.tab.container', "The container that will be displayed in this tab."),
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: generateTabContentSchemaProperties()
|
properties: generateContainerTypeSchemaProperties()
|
||||||
},
|
},
|
||||||
alwaysShow: {
|
alwaysShow: {
|
||||||
description: localize('sqlops.extension.contributes.dashboard.tab.alwaysShow', "Whether or not this tab should always be shown or only when the user adds it."),
|
description: localize('sqlops.extension.contributes.dashboard.tab.alwaysShow', "Whether or not this tab should always be shown or only when the user adds it."),
|
||||||
|
|||||||
@@ -41,6 +41,15 @@ export interface TabConfig extends IDashboardTab {
|
|||||||
actions?: Array<Action>;
|
actions?: Array<Action>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type IUserFriendlyIcon = string | { light: string; dark: string; };
|
||||||
|
|
||||||
|
export interface NavSectionConfig {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
icon?: IUserFriendlyIcon;
|
||||||
|
container: object;
|
||||||
|
}
|
||||||
|
|
||||||
export interface PinConfig {
|
export interface PinConfig {
|
||||||
tabId: string;
|
tabId: string;
|
||||||
isPinned?: boolean;
|
isPinned?: boolean;
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ export type IUserFriendlyIcon = string | { light: string; dark: string; };
|
|||||||
|
|
||||||
export interface IDashboardContainerContrib {
|
export interface IDashboardContainerContrib {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
|
||||||
icon?: IUserFriendlyIcon;
|
|
||||||
container: object;
|
container: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,33 +23,10 @@ const containerSchema: IJSONSchema = {
|
|||||||
properties: {
|
properties: {
|
||||||
id: {
|
id: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: localize('sqlops.extension.contributes.dashboard.container.id', "Unique identifier for this inner tab. Will be passed to the extension for any requests.")
|
description: localize('sqlops.extension.contributes.dashboard.container.id', "Unique identifier for this container.")
|
||||||
},
|
|
||||||
icon: {
|
|
||||||
description: localize('sqlops.extension.contributes.dashboard.container.icon', '(Optional) Icon which is used to represent this inner tab in the UI. Either a file path or a themable configuration'),
|
|
||||||
anyOf: [{
|
|
||||||
type: 'string'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
light: {
|
|
||||||
description: localize('carbon.extension.contributes.account.icon.light', 'Icon path when a light theme is used'),
|
|
||||||
type: 'string'
|
|
||||||
},
|
|
||||||
dark: {
|
|
||||||
description: localize('carbon.extension.contributes.account.icon.dark', 'Icon path when a dark theme is used'),
|
|
||||||
type: 'string'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: 'string',
|
|
||||||
description: localize('sqlops.extension.contributes.dashboard.container.title', "Title of the inner tab to show the user.")
|
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
description: localize('sqlops.extension.contributes.dashboard.container.container', "The container that will be displayed in this inner tab."),
|
description: localize('sqlops.extension.contributes.dashboard.container.container', "The container that will be displayed in the tab."),
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: generateContainerTypeSchemaProperties()
|
properties: generateContainerTypeSchemaProperties()
|
||||||
}
|
}
|
||||||
@@ -59,7 +34,7 @@ const containerSchema: IJSONSchema = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const containerContributionSchema: IJSONSchema = {
|
const containerContributionSchema: IJSONSchema = {
|
||||||
description: localize('sqlops.extension.contributes.containers', "Contributes a single or multiple inner tabs for users to add to their dashboard."),
|
description: localize('sqlops.extension.contributes.containers', "Contributes a single or multiple dashboard containers for users to add to their dashboard."),
|
||||||
oneOf: [
|
oneOf: [
|
||||||
containerSchema,
|
containerSchema,
|
||||||
{
|
{
|
||||||
@@ -72,30 +47,11 @@ const containerContributionSchema: IJSONSchema = {
|
|||||||
ExtensionsRegistry.registerExtensionPoint<IDashboardContainerContrib | IDashboardContainerContrib[]>('dashboard.containers', [], containerContributionSchema).setHandler(extensions => {
|
ExtensionsRegistry.registerExtensionPoint<IDashboardContainerContrib | IDashboardContainerContrib[]>('dashboard.containers', [], containerContributionSchema).setHandler(extensions => {
|
||||||
|
|
||||||
function handleCommand(dashboardContainer: IDashboardContainerContrib, extension: IExtensionPointUser<any>) {
|
function handleCommand(dashboardContainer: IDashboardContainerContrib, extension: IExtensionPointUser<any>) {
|
||||||
let { title, id, container, icon } = dashboardContainer;
|
let { id, container } = dashboardContainer;
|
||||||
if (!title) {
|
|
||||||
extension.collector.error('No title specified for extension.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!container) {
|
if (!container) {
|
||||||
extension.collector.warn('No container specified to show.');
|
extension.collector.warn('No container specified to show.');
|
||||||
}
|
}
|
||||||
|
registerContainer({ id, container });
|
||||||
let iconClass: string;
|
|
||||||
if (icon) {
|
|
||||||
iconClass = id;
|
|
||||||
if (typeof icon === 'string') {
|
|
||||||
const path = join(extension.description.extensionFolderPath, icon);
|
|
||||||
createCSSRule(`.icon.${iconClass}`, `background-image: url("${URI.file(path).toString()}")`);
|
|
||||||
} else {
|
|
||||||
const light = join(extension.description.extensionFolderPath, icon.light);
|
|
||||||
const dark = join(extension.description.extensionFolderPath, icon.dark);
|
|
||||||
createCSSRule(`.icon.${iconClass}`, `background-image: url("${URI.file(light).toString()}")`);
|
|
||||||
createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: url("${URI.file(dark).toString()}")`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
registerContainer({ title, id, container, hasIcon: !!icon });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let extension of extensions) {
|
for (let extension of extensions) {
|
||||||
|
|||||||
@@ -6,14 +6,15 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
|||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
import { generateDashboardGridLayoutSchema } from 'sql/parts/dashboard/pages/dashboardPageContribution';
|
import { generateDashboardGridLayoutSchema } from 'sql/parts/dashboard/pages/dashboardPageContribution';
|
||||||
import { registerTabContent } from 'sql/platform/dashboard/common/dashboardRegistry';
|
import { registerContainerType, registerNavSectionContainerType } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||||
|
|
||||||
export const GRID_CONTAINER = 'grid-container';
|
export const GRID_CONTAINER = 'grid-container';
|
||||||
|
|
||||||
let gridContainersSchema: IJSONSchema = {
|
let gridContainersSchema: IJSONSchema = {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
description: nls.localize('dashboard.gridtab.content.items', "The list of widgets or webviews that will be displayed in this tab."),
|
description: nls.localize('dashboard.container.gridtab.items', "The list of widgets or webviews that will be displayed in this tab."),
|
||||||
items: generateDashboardGridLayoutSchema(undefined, true)
|
items: generateDashboardGridLayoutSchema(undefined, true)
|
||||||
};
|
};
|
||||||
|
|
||||||
registerTabContent(GRID_CONTAINER, gridContainersSchema);
|
registerContainerType(GRID_CONTAINER, gridContainersSchema);
|
||||||
|
registerNavSectionContainerType(GRID_CONTAINER, gridContainersSchema);
|
||||||
|
|||||||
@@ -8,20 +8,18 @@ import 'vs/css!./dashboardNavSection';
|
|||||||
import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges, AfterContentInit } from '@angular/core';
|
import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges, AfterContentInit } from '@angular/core';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
import { WidgetConfig, TabConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { WidgetConfig, TabConfig, NavSectionConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { PanelComponent, IPanelOptions, NavigationBarLayout } from 'sql/base/browser/ui/panel/panel.component';
|
import { PanelComponent, IPanelOptions, NavigationBarLayout } from 'sql/base/browser/ui/panel/panel.component';
|
||||||
import { IDashboardContainerRegistry, Extensions as InnerTabExtensions, IDashboardContainer } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
|
||||||
import { TabComponent } from 'sql/base/browser/ui/panel/tab.component';
|
import { TabComponent } from 'sql/base/browser/ui/panel/tab.component';
|
||||||
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
import { DashboardTab } from 'sql/parts/dashboard/common/interfaces';
|
||||||
import { error } from 'sql/base/common/log';
|
import { error } from 'sql/base/common/log';
|
||||||
import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
||||||
import * as widgetHelper from 'sql/parts/dashboard/common/dashboardWidgetHelper';
|
import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
||||||
|
import * as dashboardHelper from 'sql/parts/dashboard/common/dashboardHelper';
|
||||||
|
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import Event, { Emitter } from 'vs/base/common/event';
|
import Event, { Emitter } from 'vs/base/common/event';
|
||||||
|
|
||||||
const innerTabRegistry = Registry.as<IDashboardContainerRegistry>(InnerTabExtensions.dashboardContainerContributions);
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'dashboard-nav-section',
|
selector: 'dashboard-nav-section',
|
||||||
providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardNavSection) }],
|
providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardNavSection) }],
|
||||||
@@ -40,16 +38,16 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh
|
|||||||
|
|
||||||
// a set of config modifiers
|
// a set of config modifiers
|
||||||
private readonly _configModifiers: Array<(item: Array<WidgetConfig>, dashboardServer: DashboardServiceInterface, context: string) => Array<WidgetConfig>> = [
|
private readonly _configModifiers: Array<(item: Array<WidgetConfig>, dashboardServer: DashboardServiceInterface, context: string) => Array<WidgetConfig>> = [
|
||||||
widgetHelper.removeEmpty,
|
dashboardHelper.removeEmpty,
|
||||||
widgetHelper.initExtensionConfigs,
|
dashboardHelper.initExtensionConfigs,
|
||||||
widgetHelper.addProvider,
|
dashboardHelper.addProvider,
|
||||||
widgetHelper.addEdition,
|
dashboardHelper.addEdition,
|
||||||
widgetHelper.addContext,
|
dashboardHelper.addContext,
|
||||||
widgetHelper.filterConfigs
|
dashboardHelper.filterConfigs
|
||||||
];
|
];
|
||||||
|
|
||||||
private readonly _gridModifiers: Array<(item: Array<WidgetConfig>, originalConfig: Array<WidgetConfig>) => Array<WidgetConfig>> = [
|
private readonly _gridModifiers: Array<(item: Array<WidgetConfig>, originalConfig: Array<WidgetConfig>) => Array<WidgetConfig>> = [
|
||||||
widgetHelper.validateGridConfig
|
dashboardHelper.validateGridConfig
|
||||||
];
|
];
|
||||||
|
|
||||||
@ViewChildren(DashboardTab) private _tabs: QueryList<DashboardTab>;
|
@ViewChildren(DashboardTab) private _tabs: QueryList<DashboardTab>;
|
||||||
@@ -63,19 +61,10 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh
|
|||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
this.tabs = [];
|
this.tabs = [];
|
||||||
let innerTabIds = [];
|
let navSectionContainers: NavSectionConfig[] = [];
|
||||||
let allPosibleInnerTab = innerTabRegistry.containers;
|
|
||||||
let filteredTabs: IDashboardContainer[] = [];
|
|
||||||
if (this.tab.container) {
|
if (this.tab.container) {
|
||||||
innerTabIds = Object.values(this.tab.container)[0];
|
navSectionContainers = Object.values(this.tab.container)[0];
|
||||||
if (innerTabIds && innerTabIds.length > 0) {
|
this.loadNewTabs(navSectionContainers);
|
||||||
innerTabIds.forEach(tabId => {
|
|
||||||
let tab = allPosibleInnerTab.find(i => i.id === tabId);
|
|
||||||
filteredTabs.push(tab);
|
|
||||||
});
|
|
||||||
this.loadNewTabs(filteredTabs);
|
|
||||||
}
|
|
||||||
this._cd.detectChanges();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,26 +82,29 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh
|
|||||||
this.dispose();
|
this.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadNewTabs(dashboardTabs: IDashboardContainer[]) {
|
private loadNewTabs(dashboardTabs: NavSectionConfig[]) {
|
||||||
if (dashboardTabs && dashboardTabs.length > 0) {
|
if (dashboardTabs && dashboardTabs.length > 0) {
|
||||||
let selectedTabs = dashboardTabs.map(v => {
|
let selectedTabs = dashboardTabs.map(v => {
|
||||||
|
|
||||||
if (Object.keys(v.container).length !== 1) {
|
let container = dashboardHelper.getDashboardContainer(v.container);
|
||||||
error('Exactly 1 content must be defined per space');
|
let key = Object.keys(container)[0];
|
||||||
}
|
|
||||||
|
|
||||||
let key = Object.keys(v.container)[0];
|
if (key === WIDGETS_CONTAINER || key === GRID_CONTAINER) {
|
||||||
if (key === WIDGETS_CONTAINER) {
|
let configs = <WidgetConfig[]>Object.values(container)[0];
|
||||||
let configs = <WidgetConfig[]>Object.values(v.container)[0];
|
|
||||||
this._configModifiers.forEach(cb => {
|
this._configModifiers.forEach(cb => {
|
||||||
configs = cb.apply(this, [configs, this.dashboardService, this.tab.context]);
|
configs = cb.apply(this, [configs, this.dashboardService, this.tab.context]);
|
||||||
});
|
});
|
||||||
this._gridModifiers.forEach(cb => {
|
this._gridModifiers.forEach(cb => {
|
||||||
configs = cb.apply(this, [configs]);
|
configs = cb.apply(this, [configs]);
|
||||||
});
|
});
|
||||||
return { id: v.id, title: v.title, container: { 'widgets-container': configs } };
|
if (key === WIDGETS_CONTAINER) {
|
||||||
|
return { id: v.id, title: v.title, container: { 'widgets-container': configs } };
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return { id: v.id, title: v.title, container: { 'grid-container': configs } };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return { id: v.id, title: v.title, container: v.container };
|
return { id: v.id, title: v.title, container: container };
|
||||||
}).map(v => {
|
}).map(v => {
|
||||||
let config = v as TabConfig;
|
let config = v as TabConfig;
|
||||||
config.context = this.tab.context;
|
config.context = this.tab.context;
|
||||||
|
|||||||
@@ -5,16 +5,52 @@
|
|||||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
import { registerTabContent } from 'sql/platform/dashboard/common/dashboardRegistry';
|
import { registerContainerType, generateNavSectionContainerTypeSchemaProperties } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||||
|
|
||||||
export const NAV_SECTION = 'nav-section';
|
export const NAV_SECTION = 'nav-section';
|
||||||
|
|
||||||
let NavSectionSchema: IJSONSchema = {
|
const navSectionContainerSchema: IJSONSchema = {
|
||||||
type: 'array',
|
type: 'object',
|
||||||
description: nls.localize('dashboard.tab.content.left-nav-bar', "The list of inner tabs IDs that will be displayed in this vertical navigation bar."),
|
properties: {
|
||||||
items: {
|
id: {
|
||||||
type: 'string'
|
type: 'string',
|
||||||
|
description: nls.localize('dashboard.container.left-nav-bar.id', "Unique identifier for this nav section. Will be passed to the extension for any requests.")
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
description: nls.localize('dashboard.container.left-nav-bar.icon', '(Optional) Icon which is used to represent this nav section in the UI. Either a file path or a themeable configuration'),
|
||||||
|
anyOf: [{
|
||||||
|
type: 'string'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
light: {
|
||||||
|
description: nls.localize('dashboard.container.left-nav-bar.icon.light', 'Icon path when a light theme is used'),
|
||||||
|
type: 'string'
|
||||||
|
},
|
||||||
|
dark: {
|
||||||
|
description: nls.localize('dashboard.container.left-nav-bar.icon.dark', 'Icon path when a dark theme is used'),
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: 'string',
|
||||||
|
description: nls.localize('dashboard.container.left-nav-bar.title', "Title of the nav section to show the user.")
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
description: nls.localize('dashboard.container.left-nav-bar.container', "The container that will be displayed in this nav section."),
|
||||||
|
type: 'object',
|
||||||
|
properties: generateNavSectionContainerTypeSchemaProperties()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
registerTabContent(NAV_SECTION, NavSectionSchema);
|
let NavSectionSchema: IJSONSchema = {
|
||||||
|
type: 'array',
|
||||||
|
description: nls.localize('dashboard.container.left-nav-bar', "The list of dashboard containers that will be displayed in this navigation section."),
|
||||||
|
items: navSectionContainerSchema
|
||||||
|
};
|
||||||
|
|
||||||
|
registerContainerType(NAV_SECTION, NavSectionSchema);
|
||||||
@@ -5,16 +5,15 @@
|
|||||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
import { registerTabContent } from 'sql/platform/dashboard/common/dashboardRegistry';
|
import { registerContainerType, registerNavSectionContainerType } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||||
import { registerContainerType } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
|
||||||
|
|
||||||
export const WEBVIEW_CONTAINER = 'webview-container';
|
export const WEBVIEW_CONTAINER = 'webview-container';
|
||||||
|
|
||||||
let webviewSchema: IJSONSchema = {
|
let webviewSchema: IJSONSchema = {
|
||||||
type: 'null',
|
type: 'null',
|
||||||
description: nls.localize('dashboard.tab.widgets', "The list of widgets that will be displayed in this tab."),
|
description: nls.localize('dashboard.container.webview', "The webview that will be displayed in this tab."),
|
||||||
default: null
|
default: null
|
||||||
};
|
};
|
||||||
|
|
||||||
registerTabContent(WEBVIEW_CONTAINER, webviewSchema);
|
registerContainerType(WEBVIEW_CONTAINER, webviewSchema);
|
||||||
registerContainerType(WEBVIEW_CONTAINER, webviewSchema);
|
registerNavSectionContainerType(WEBVIEW_CONTAINER, webviewSchema);
|
||||||
@@ -6,16 +6,15 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
|||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
import { generateDashboardWidgetSchema } from 'sql/parts/dashboard/pages/dashboardPageContribution';
|
import { generateDashboardWidgetSchema } from 'sql/parts/dashboard/pages/dashboardPageContribution';
|
||||||
import { registerTabContent } from 'sql/platform/dashboard/common/dashboardRegistry';
|
import { registerContainerType, registerNavSectionContainerType } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
||||||
import { registerContainerType } from 'sql/platform/dashboard/common/dashboardContainerRegistry';
|
|
||||||
|
|
||||||
export const WIDGETS_CONTAINER = 'widgets-container';
|
export const WIDGETS_CONTAINER = 'widgets-container';
|
||||||
|
|
||||||
let widgetsSchema: IJSONSchema = {
|
let widgetsSchema: IJSONSchema = {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
description: nls.localize('dashboard.tab.content.widgets', "The list of widgets that will be displayed in this tab."),
|
description: nls.localize('dashboard.container.widgets', "The list of widgets that will be displayed in this tab."),
|
||||||
items: generateDashboardWidgetSchema(undefined, true)
|
items: generateDashboardWidgetSchema(undefined, true)
|
||||||
};
|
};
|
||||||
|
|
||||||
registerTabContent(WIDGETS_CONTAINER, widgetsSchema);
|
|
||||||
registerContainerType(WIDGETS_CONTAINER, widgetsSchema);
|
registerContainerType(WIDGETS_CONTAINER, widgetsSchema);
|
||||||
|
registerNavSectionContainerType(WIDGETS_CONTAINER, widgetsSchema);
|
||||||
|
|||||||
@@ -16,34 +16,35 @@ export const Extensions = {
|
|||||||
|
|
||||||
export interface IDashboardContainer {
|
export interface IDashboardContainer {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
|
||||||
hasIcon: boolean;
|
|
||||||
container?: object;
|
container?: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDashboardContainerRegistry {
|
export interface IDashboardContainerRegistry {
|
||||||
registerContainer(tab: IDashboardContainer): void;
|
registerContainer(container: IDashboardContainer): void;
|
||||||
registerContainerType(id: string, schema: IJSONSchema): void;
|
registerContainerType(id: string, schema: IJSONSchema): void;
|
||||||
containers: Array<IDashboardContainer>;
|
registerNavSectionContainerType(id: string, schema: IJSONSchema): void;
|
||||||
|
getRegisteredContainer(id: string): IDashboardContainer;
|
||||||
containerTypeSchemaProperties: IJSONSchemaMap;
|
containerTypeSchemaProperties: IJSONSchemaMap;
|
||||||
|
navSectionContainerTypeSchemaProperties: IJSONSchemaMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DashboardContainerRegistry implements IDashboardContainerRegistry {
|
class DashboardContainerRegistry implements IDashboardContainerRegistry {
|
||||||
private _containers = new Array<IDashboardContainer>();
|
private _containers: { [x: string]: IDashboardContainer } = {};
|
||||||
private _dashboardContainerTypeSchemaProperties: IJSONSchemaMap = {};
|
private _dashboardContainerTypeSchemaProperties: IJSONSchemaMap = {};
|
||||||
|
private _dashboardNavSectionContainerTypeSchemaProperties: IJSONSchemaMap = {};
|
||||||
|
|
||||||
public registerContainer(tab: IDashboardContainer): void {
|
public registerContainer(container: IDashboardContainer): void {
|
||||||
this._containers.push(tab);
|
this._containers[container.id] = container;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get containers(): Array<IDashboardContainer> {
|
public getRegisteredContainer(id: string): IDashboardContainer {
|
||||||
return this._containers;
|
return this._containers[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a dashboard widget
|
* Register a dashboard container
|
||||||
* @param id id of the widget
|
* @param id id of the container
|
||||||
* @param schema config schema of the widget
|
* @param schema config schema of the container
|
||||||
*/
|
*/
|
||||||
public registerContainerType(id: string, schema: IJSONSchema): void {
|
public registerContainerType(id: string, schema: IJSONSchema): void {
|
||||||
this._dashboardContainerTypeSchemaProperties[id] = schema;
|
this._dashboardContainerTypeSchemaProperties[id] = schema;
|
||||||
@@ -52,13 +53,26 @@ class DashboardContainerRegistry implements IDashboardContainerRegistry {
|
|||||||
public get containerTypeSchemaProperties(): IJSONSchemaMap {
|
public get containerTypeSchemaProperties(): IJSONSchemaMap {
|
||||||
return deepClone(this._dashboardContainerTypeSchemaProperties);
|
return deepClone(this._dashboardContainerTypeSchemaProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a dashboard nav section container
|
||||||
|
* @param id id of the container
|
||||||
|
* @param schema config schema of the container
|
||||||
|
*/
|
||||||
|
public registerNavSectionContainerType(id: string, schema: IJSONSchema): void {
|
||||||
|
this._dashboardNavSectionContainerTypeSchemaProperties[id] = schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get navSectionContainerTypeSchemaProperties(): IJSONSchemaMap {
|
||||||
|
return deepClone(this._dashboardNavSectionContainerTypeSchemaProperties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dashboardContainerRegistry = new DashboardContainerRegistry();
|
const dashboardContainerRegistry = new DashboardContainerRegistry();
|
||||||
Registry.add(Extensions.dashboardContainerContributions, dashboardContainerRegistry);
|
Registry.add(Extensions.dashboardContainerContributions, dashboardContainerRegistry);
|
||||||
|
|
||||||
export function registerContainer(innerTab: IDashboardContainer): void {
|
export function registerContainer(container: IDashboardContainer): void {
|
||||||
dashboardContainerRegistry.registerContainer(innerTab);
|
dashboardContainerRegistry.registerContainer(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerContainerType(id: string, schema: IJSONSchema): void {
|
export function registerContainerType(id: string, schema: IJSONSchema): void {
|
||||||
@@ -67,4 +81,12 @@ export function registerContainerType(id: string, schema: IJSONSchema): void {
|
|||||||
|
|
||||||
export function generateContainerTypeSchemaProperties(): IJSONSchemaMap {
|
export function generateContainerTypeSchemaProperties(): IJSONSchemaMap {
|
||||||
return dashboardContainerRegistry.containerTypeSchemaProperties;
|
return dashboardContainerRegistry.containerTypeSchemaProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerNavSectionContainerType(id: string, schema: IJSONSchema): void {
|
||||||
|
dashboardContainerRegistry.registerNavSectionContainerType(id, schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateNavSectionContainerTypeSchemaProperties(): IJSONSchemaMap {
|
||||||
|
return dashboardContainerRegistry.navSectionContainerTypeSchemaProperties;
|
||||||
}
|
}
|
||||||
@@ -34,9 +34,7 @@ export interface IDashboardRegistry {
|
|||||||
registerDashboardProvider(id: string, properties: ProviderProperties): void;
|
registerDashboardProvider(id: string, properties: ProviderProperties): void;
|
||||||
getProperties(id: string): ProviderProperties;
|
getProperties(id: string): ProviderProperties;
|
||||||
registerTab(tab: IDashboardTab): void;
|
registerTab(tab: IDashboardTab): void;
|
||||||
registerTabContent(id: string, schema: IJSONSchema): void;
|
|
||||||
tabs: Array<IDashboardTab>;
|
tabs: Array<IDashboardTab>;
|
||||||
tabContentSchemaProperties: IJSONSchemaMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DashboardRegistry implements IDashboardRegistry {
|
class DashboardRegistry implements IDashboardRegistry {
|
||||||
@@ -77,19 +75,6 @@ class DashboardRegistry implements IDashboardRegistry {
|
|||||||
public get tabs(): Array<IDashboardTab> {
|
public get tabs(): Array<IDashboardTab> {
|
||||||
return this._tabs;
|
return this._tabs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a dashboard widget
|
|
||||||
* @param id id of the widget
|
|
||||||
* @param schema config schema of the widget
|
|
||||||
*/
|
|
||||||
public registerTabContent(id: string, schema: IJSONSchema): void {
|
|
||||||
this._dashboardTabContentSchemaProperties[id] = schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get tabContentSchemaProperties(): IJSONSchemaMap {
|
|
||||||
return deepClone(this._dashboardTabContentSchemaProperties);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const dashboardRegistry = new DashboardRegistry();
|
const dashboardRegistry = new DashboardRegistry();
|
||||||
@@ -99,14 +84,6 @@ export function registerTab(tab: IDashboardTab): void {
|
|||||||
dashboardRegistry.registerTab(tab);
|
dashboardRegistry.registerTab(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerTabContent(id: string, schema: IJSONSchema): void {
|
|
||||||
dashboardRegistry.registerTabContent(id, schema);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generateTabContentSchemaProperties(): IJSONSchemaMap {
|
|
||||||
return dashboardRegistry.tabContentSchemaProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dashboardPropertiesPropertyContrib: IJSONSchema = {
|
const dashboardPropertiesPropertyContrib: IJSONSchema = {
|
||||||
description: nls.localize('dashboard.properties.property', "Defines a property to show on the dashboard"),
|
description: nls.localize('dashboard.properties.property', "Defines a property to show on the dashboard"),
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
|||||||
@@ -160,11 +160,11 @@ import 'sql/parts/dashboard/widgets/tasks/tasksWidget.contribution';
|
|||||||
import 'sql/parts/dashboard/widgets/webview/webviewWidget.contribution';
|
import 'sql/parts/dashboard/widgets/webview/webviewWidget.contribution';
|
||||||
import 'sql/parts/dashboard/dashboardConfig.contribution';
|
import 'sql/parts/dashboard/dashboardConfig.contribution';
|
||||||
/* Containers */
|
/* Containers */
|
||||||
import 'sql/parts/dashboard/containers/dashboardNavSection.contribution';
|
|
||||||
import 'sql/parts/dashboard/containers/dashboardWebviewContainer.contribution';
|
import 'sql/parts/dashboard/containers/dashboardWebviewContainer.contribution';
|
||||||
import 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
import 'sql/parts/dashboard/containers/dashboardGridContainer.contribution';
|
||||||
import 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
import 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution';
|
||||||
import 'sql/parts/dashboard/containers/dashboardContainer.contribution';
|
import 'sql/parts/dashboard/containers/dashboardContainer.contribution';
|
||||||
|
import 'sql/parts/dashboard/containers/dashboardNavSection.contribution';
|
||||||
import 'sql/parts/dashboard/common/dashboardTab.contribution';
|
import 'sql/parts/dashboard/common/dashboardTab.contribution';
|
||||||
/* Tasks */
|
/* Tasks */
|
||||||
import 'sql/workbench/common/actions.contribution';
|
import 'sql/workbench/common/actions.contribution';
|
||||||
|
|||||||
Reference in New Issue
Block a user