diff --git a/src/sql/parts/dashboard/widgets/insights/insightsWidget.contribution.ts b/src/sql/parts/dashboard/widgets/insights/insightsWidget.contribution.ts index 474c0f05ca..efe4545caa 100644 --- a/src/sql/parts/dashboard/widgets/insights/insightsWidget.contribution.ts +++ b/src/sql/parts/dashboard/widgets/insights/insightsWidget.contribution.ts @@ -6,7 +6,7 @@ import { join } from 'path'; import { registerDashboardWidget, registerNonCustomDashboardWidget } from 'sql/platform/dashboard/common/widgetRegistry'; import { Extensions as InsightExtensions, IInsightRegistry } from 'sql/platform/dashboard/common/insightRegistry'; -import { IInsightsConfig } from './interfaces'; +import { IInsightsConfig, IInsightTypeContrib } from './interfaces'; import { insightsContribution, insightsSchema } from 'sql/parts/dashboard/widgets/insights/insightsWidgetSchemas'; import { IExtensionPointUser, ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; @@ -14,10 +14,6 @@ import { Registry } from 'vs/platform/registry/common/platform'; const insightRegistry = Registry.as(InsightExtensions.InsightContribution); -interface IInsightTypeContrib { - id: string; - contrib: IInsightsConfig; -} registerDashboardWidget('insights-widget', '', insightsSchema); diff --git a/src/sql/parts/dashboard/widgets/insights/interfaces.ts b/src/sql/parts/dashboard/widgets/insights/interfaces.ts index 2988100a10..2d1ef33e66 100644 --- a/src/sql/parts/dashboard/widgets/insights/interfaces.ts +++ b/src/sql/parts/dashboard/widgets/insights/interfaces.ts @@ -57,4 +57,8 @@ export interface IInsightsConfig { queryFile?: string; details?: IInsightsConfigDetails; autoRefreshInterval?: number; +} +export interface IInsightTypeContrib { + id: string; + contrib: IInsightsConfig; } \ No newline at end of file diff --git a/src/sql/parts/extensions/sqlExtensionsHelper.ts b/src/sql/parts/extensions/sqlExtensionsHelper.ts new file mode 100644 index 0000000000..ce9c913409 --- /dev/null +++ b/src/sql/parts/extensions/sqlExtensionsHelper.ts @@ -0,0 +1,110 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import 'vs/css!vs/workbench/parts/extensions/browser/media/extensionEditor'; + + +import { IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { Color } from 'vs/base/common/color'; +import { append, $, addClass, removeClass, finalHandler, join, toggleClass } from 'vs/base/browser/dom'; +import { IInsightTypeContrib } from 'sql/parts/dashboard/widgets/insights/interfaces'; +import { IDashboardTabContrib } from 'sql/parts/dashboard/common/dashboardTab.contribution'; +import { localize } from 'vs/nls'; + +class ContributionReader { + constructor(private manifest: IExtensionManifest) { } + + public dashboardInsights(): IInsightTypeContrib[] { + let contributes = this.manifest.contributes; + if (contributes) { + let insights: IInsightTypeContrib | IInsightTypeContrib[] = contributes['dashboard.insights']; + if (insights) { + if (!Array.isArray(insights)) { + return [insights]; + } + return insights; + } + } + return undefined; + } + + public dashboardTabs(): IDashboardTabContrib[] { + let contributes = this.manifest.contributes; + if (contributes) { + let tabs: IDashboardTabContrib | IDashboardTabContrib[] = contributes['dashboard.tabs']; + if (tabs) { + if (!Array.isArray(tabs)) { + return [tabs]; + } + return tabs; + } + } + return undefined; + } +} + +export function renderDashboardContributions(container: HTMLElement, manifest: IExtensionManifest, onDetailsToggle: Function): boolean { + let contributionReader = new ContributionReader(manifest); + renderDashboardTabs(onDetailsToggle, contributionReader, container); + renderDashboardInsights(onDetailsToggle, contributionReader, container); + return true; +} + +function renderDashboardTabs(onDetailsToggle: Function, contributionReader: ContributionReader, container: HTMLElement): boolean { + let tabs = contributionReader.dashboardTabs(); + + if (!tabs || !tabs.length) { + return false; + } + + const details = $('details', { open: true, ontoggle: onDetailsToggle }, + $('summary', null, localize('tabs', "Dashboard Tabs ({0})", tabs.length)), + $('table', null, + $('tr', null, + $('th', null, localize('tabId', "Id")), + $('th', null, localize('tabTitle', "Title")), + $('th', null, localize('tabDescription', "Description")) + ), + ...tabs.map(tab => $('tr', null, + $('td', null, $('code', null, tab.id)), + $('td', null, tab.title ? tab.title : tab.id), + $('td', null, tab.description), + )) + ) + ); + + append(container, details); + return true; +} + +function renderDashboardInsights(onDetailsToggle: Function, contributionReader: ContributionReader, container: HTMLElement): boolean { + let insights = contributionReader.dashboardInsights(); + + if (!insights || !insights.length) { + return false; + } + + const details = $('details', { open: true, ontoggle: onDetailsToggle }, + $('summary', null, localize('insights', "Dashboard Insights ({0})", insights.length)), + $('table', null, + $('tr', null, + $('th', null, localize('insightId', "Id")), + $('th', null, localize('name', "Name")), + $('th', null, localize('insight condition', "When")) + ), + ...insights.map(insight => $('tr', null, + $('td', null, $('code', null, insight.id)), + $('td', null, insight.contrib.name ? insight.contrib.name : insight.id), + $('td', null, insight.contrib.when), + )) + ) + ); + + append(container, details); + return true; +} + diff --git a/src/vs/workbench/parts/extensions/browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/browser/extensionEditor.ts index bf4feb8fcb..17410eae79 100644 --- a/src/vs/workbench/parts/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/browser/extensionEditor.ts @@ -54,6 +54,9 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { assign } from 'vs/base/common/objects'; import { INotificationService } from 'vs/platform/notification/common/notification'; +// {{SQL CARBON EDIT}} +import { renderDashboardContributions } from 'sql/parts/extensions/sqlExtensionsHelper'; + /** A context key that is set when an extension editor webview has focus. */ export const KEYBINDING_CONTEXT_EXTENSIONEDITOR_WEBVIEW_FOCUS = new RawContextKey('extensionEditorWebviewFocus', undefined); /** A context key that is set when the find widget find input in extension editor webview is focused. */ @@ -474,7 +477,9 @@ export class ExtensionEditor extends BaseEditor { this.renderJSONValidation(content, manifest, layout), this.renderDebuggers(content, manifest, layout), this.renderViews(content, manifest, layout), - this.renderLocalizations(content, manifest, layout) + this.renderLocalizations(content, manifest, layout), + // {{SQL CARBON EDIT}} + renderDashboardContributions(content, manifest, layout) ]; const isEmpty = !renders.reduce((v, r) => r || v, false); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts index a6dca8ea83..9719200438 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts @@ -59,7 +59,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe private _fileBasedRecommendations: { [id: string]: number; } = Object.create(null); // {{SQL CARBON EDIT}} - private _recommendations: string[] = Object.create(null); + private _recommendations: string[] = []; private _exeBasedRecommendations: { [id: string]: string; } = Object.create(null); private _availableRecommendations: { [pattern: string]: string[] } = Object.create(null); private _allWorkspaceRecommendedExtensions: string[] = [];