diff --git a/src/sql/parts/connection/common/constants.ts b/src/sql/parts/connection/common/constants.ts index 5d1f84e35d..4fbe1531a7 100644 --- a/src/sql/parts/connection/common/constants.ts +++ b/src/sql/parts/connection/common/constants.ts @@ -21,6 +21,8 @@ export const capabilitiesOptions = 'OPTIONS_METADATA'; export const configMaxRecentConnections = 'maxRecentConnections'; export const mssqlProviderName = 'MSSQL'; +export const anyProviderName = '*'; +export const connectionProviderContextKey = 'connectionProvider'; export const applicationName = 'sqlops'; diff --git a/src/sql/parts/dashboard/common/dashboardHelper.ts b/src/sql/parts/dashboard/common/dashboardHelper.ts index 62cd1e1720..a5a29bf366 100644 --- a/src/sql/parts/dashboard/common/dashboardHelper.ts +++ b/src/sql/parts/dashboard/common/dashboardHelper.ts @@ -19,9 +19,9 @@ import { WEBVIEW_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWebvi import { MODELVIEW_CONTAINER } from 'sql/parts/dashboard/containers/dashboardModelViewContainer.contribution'; import { CONTROLHOST_CONTAINER } from 'sql/parts/dashboard/containers/dashboardControlHostContainer.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'; +import { IDashboardContainerRegistry, Extensions as DashboardContainerExtensions } from 'sql/platform/dashboard/common/dashboardContainerRegistry'; import { SingleConnectionManagementService } from 'sql/services/common/commonServiceInterface.service'; +import * as Constants from 'sql/parts/connection/common/constants'; const dashboardcontainerRegistry = Registry.as(DashboardContainerExtensions.dashboardContainerContributions); const containerTypes = [ @@ -166,9 +166,11 @@ export function addContext(config: WidgetConfig[], collection: any, context: str * Returns a filtered version of the widgets passed based on edition and provider * @param config widgets to filter */ -export function filterConfigs(config: T[], collection: K): Array { +export function filterConfigs(config: T[], collection: K): Array { return config.filter((item) => { - if (!item.when) { + if (!hasCompatibleProvider(item.provider, collection.contextKeyService)) { + return false; + } else if (!item.when) { return true; } else { return collection.contextKeyService.contextMatchesRules(ContextKeyExpr.deserialize(item.when)); @@ -176,6 +178,21 @@ export function filterConfigs(Constants.connectionProviderContextKey); + if (connectionProvider) { + let providers = (provider instanceof Array) ? provider : [provider]; + let matchingProvider = providers.find((p) => p === connectionProvider || p === Constants.anyProviderName); + isCompatible = (matchingProvider !== undefined); + } // Else there's no connection context so skip the check + return isCompatible; +} + /** * Get registered container if it is specified as the key * @param container dashboard container diff --git a/src/sql/parts/dashboard/common/dashboardPage.component.ts b/src/sql/parts/dashboard/common/dashboardPage.component.ts index 3498e3f0d7..dece1f01f5 100644 --- a/src/sql/parts/dashboard/common/dashboardPage.component.ts +++ b/src/sql/parts/dashboard/common/dashboardPage.component.ts @@ -17,11 +17,12 @@ import { IDashboardRegistry, Extensions as DashboardExtensions, IDashboardTab } import { PinUnpinTabAction, AddFeatureTabAction } from './actions'; import { TabComponent, TabChild } from 'sql/base/browser/ui/panel/tab.component'; import { AngularEventType, IAngularEventingService } from 'sql/services/angularEventing/angularEventingService'; -import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; +import { DashboardTab, IConfigModifierCollection } from 'sql/parts/dashboard/common/interfaces'; import * as dashboardHelper from 'sql/parts/dashboard/common/dashboardHelper'; import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution'; import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution'; import { AngularDisposable } from 'sql/base/common/lifecycle'; +import * as Constants from 'sql/parts/connection/common/constants'; import { Registry } from 'vs/platform/registry/common/platform'; import * as types from 'vs/base/common/types'; @@ -38,16 +39,11 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; const dashboardRegistry = Registry.as(DashboardExtensions.DashboardContributions); -interface IConfigModifierCollection { - connectionManagementService: SingleConnectionManagementService; - contextKeyService: IContextKeyService; -} - @Component({ selector: 'dashboard-page', templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/common/dashboardPage.component.html')) }) -export abstract class DashboardPage extends AngularDisposable { +export abstract class DashboardPage extends AngularDisposable implements IConfigModifierCollection { protected tabs: Array = []; @@ -140,6 +136,7 @@ export abstract class DashboardPage extends AngularDisposable { // Create home tab let homeTab: TabConfig = { id: 'homeTab', + provider: Constants.anyProviderName, publisher: undefined, title: this.homeTabTitle, container: { 'widgets-container': homeWidgets }, @@ -218,7 +215,7 @@ export abstract class DashboardPage extends AngularDisposable { if (key === WIDGETS_CONTAINER || key === GRID_CONTAINER) { let configs = Object.values(containerResult.container)[0]; this._configModifiers.forEach(cb => { - configs = cb.apply(this, [configs, this.dashboardService, this.context]); + configs = cb.apply(this, [configs, this, this.context]); }); this._gridModifiers.forEach(cb => { configs = cb.apply(this, [configs]); diff --git a/src/sql/parts/dashboard/common/dashboardTab.contribution.ts b/src/sql/parts/dashboard/common/dashboardTab.contribution.ts index e353612411..64ef8d2102 100644 --- a/src/sql/parts/dashboard/common/dashboardTab.contribution.ts +++ b/src/sql/parts/dashboard/common/dashboardTab.contribution.ts @@ -7,6 +7,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { localize } from 'vs/nls'; import * as types from 'vs/base/common/types'; +import * as Constants from 'sql/parts/connection/common/constants'; import { registerTab } from 'sql/platform/dashboard/common/dashboardRegistry'; import { generateContainerTypeSchemaProperties } from 'sql/platform/dashboard/common/dashboardContainerRegistry'; import { NAV_SECTION, validateNavSectionContributionAndRegisterIcon } from 'sql/parts/dashboard/containers/dashboardNavSection.contribution'; @@ -17,6 +18,7 @@ export interface IDashboardTabContrib { id: string; title: string; container: object; + provider: string | string[]; when?: string; description?: string; alwaysShow?: boolean; @@ -41,6 +43,11 @@ const tabSchema: IJSONSchema = { description: localize('sqlops.extension.contributes.tab.when', 'Condition which must be true to show this item'), type: 'string' }, + provider: { + description: localize('sqlops.extension.contributes.tab.provider', 'Defines the connection types this tab is compatible with. Defaults to "MSSQL" if not set'), + type: ['string', 'array'] + + }, container: { description: localize('sqlops.extension.contributes.dashboard.tab.container', "The container that will be displayed in this tab."), type: 'object', @@ -67,7 +74,7 @@ const tabContributionSchema: IJSONSchema = { ExtensionsRegistry.registerExtensionPoint('dashboard.tabs', [], tabContributionSchema).setHandler(extensions => { function handleCommand(tab: IDashboardTabContrib, extension: IExtensionPointUser) { - let { description, container, title, when, id, alwaysShow } = tab; + let { description, container, provider, title, when, id, alwaysShow } = tab; // If always show is not specified, set it to true by default. if (!types.isBoolean(alwaysShow)) { @@ -88,6 +95,11 @@ ExtensionsRegistry.registerExtensionPoint DashboardNavSection) }], templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/containers/dashboardNavSection.component.html')) }) -export class DashboardNavSection extends DashboardTab implements OnDestroy, OnChanges, AfterContentInit { +export class DashboardNavSection extends DashboardTab implements OnDestroy, OnChanges, AfterContentInit, IConfigModifierCollection { @Input() private tab: TabConfig; protected tabs: Array = []; private _onResize = new Emitter(); @@ -38,7 +37,7 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh }; // a set of config modifiers - private readonly _configModifiers: Array<(item: Array, dashboardServer: DashboardServiceInterface, context: string) => Array> = [ + private readonly _configModifiers: Array<(item: Array, collection: IConfigModifierCollection, context: string) => Array> = [ dashboardHelper.removeEmpty, dashboardHelper.initExtensionConfigs, dashboardHelper.addProvider, @@ -103,7 +102,7 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh if (key === WIDGETS_CONTAINER || key === GRID_CONTAINER) { let configs = Object.values(containerResult.container)[0]; this._configModifiers.forEach(cb => { - configs = cb.apply(this, [configs, this.dashboardService, this.tab.context]); + configs = cb.apply(this, [configs, this, this.tab.context]); }); this._gridModifiers.forEach(cb => { configs = cb.apply(this, [configs]); @@ -169,4 +168,12 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh }); } } + + public get connectionManagementService(): SingleConnectionManagementService { + return this.dashboardService.connectionManagementService; + } + + public get contextKeyService(): IContextKeyService { + return this.dashboardService.scopedContextKeyService; + } } diff --git a/src/sql/platform/dashboard/common/dashboardRegistry.ts b/src/sql/platform/dashboard/common/dashboardRegistry.ts index 65b54f801e..84b6f75762 100644 --- a/src/sql/platform/dashboard/common/dashboardRegistry.ts +++ b/src/sql/platform/dashboard/common/dashboardRegistry.ts @@ -7,7 +7,6 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions as ConfigurationExtension } from 'vs/platform/configuration/common/configurationRegistry'; import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import * as nls from 'vs/nls'; -import { deepClone } from 'vs/base/common/objects'; import { IExtensionPointUser, ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { ProviderProperties } from 'sql/parts/dashboard/widgets/properties/propertiesWidget.component'; @@ -22,6 +21,7 @@ export const Extensions = { export interface IDashboardTab { id: string; title: string; + provider: string | string[]; publisher: string; description?: string; container?: object;