diff --git a/src/sql/azdata.proposed.d.ts b/src/sql/azdata.proposed.d.ts index 523914da52..f1ccaa4003 100644 --- a/src/sql/azdata.proposed.d.ts +++ b/src/sql/azdata.proposed.d.ts @@ -6,6 +6,7 @@ // This is the place for API experiments and proposal. import * as vscode from 'vscode'; +import { DataProvider } from 'azdata'; declare module 'azdata' { /** @@ -95,6 +96,61 @@ declare module 'azdata' { export namespace dataprotocol { export function registerSerializationProvider(provider: SerializationProvider): vscode.Disposable; export function registerSqlAssessmentServicesProvider(provider: SqlAssessmentServicesProvider): vscode.Disposable; + /** + * Registers a DataGridProvider which is used to provide lists of items to a data grid + * @param provider The provider implementation + */ + export function registerDataGridProvider(provider: DataGridProvider): vscode.Disposable; + } + + export enum DataProviderType { + DataGridProvider = 'DataGridProvider' + } + + /** + * A column in a data grid + */ + export interface DataGridColumn { + /** + * The text to display on the column heading. + **/ + name: string; + /** + * The property name in the DataGridItem + **/ + field: string; + /** + * A unique identifier for the column within the grid. + */ + id: string; + } + + /** + * An item for displaying in a data grid + */ + export interface DataGridItem { + /** + * A unique identifier for this item + */ + id: string; + /** + * The other properties that will be displayed in the grid + */ + [key: string]: string; + } + + /** + * A data provider that provides lists of resource items for a data grid + */ + export interface DataGridProvider extends DataProvider { + /** + * Gets the list of data grid items for this provider + */ + getDataGridItems(): Thenable; + /** + * Gets the list of data grid columns for this provider + */ + getDataGridColumns(): Thenable; } export interface HyperlinkComponent { @@ -532,5 +588,4 @@ declare module 'azdata' { */ delete?: boolean; } - } diff --git a/src/sql/platform/telemetry/common/telemetryKeys.ts b/src/sql/platform/telemetry/common/telemetryKeys.ts index 66a36fba8a..3c93dcf45f 100644 --- a/src/sql/platform/telemetry/common/telemetryKeys.ts +++ b/src/sql/platform/telemetry/common/telemetryKeys.ts @@ -25,6 +25,8 @@ export const CancelQuery = 'CancelQuery'; export const NewQuery = 'NewQuery'; export const FirewallRuleRequested = 'FirewallRuleCreated'; export const DashboardNavigated = 'DashboardNavigated'; +export const GetDataGridItems = 'GetDataGridItems'; +export const GetDataGridColumns = 'GetDataGridColumns'; // Telemetry Properties diff --git a/src/sql/workbench/api/browser/mainThreadDataProtocol.ts b/src/sql/workbench/api/browser/mainThreadDataProtocol.ts index ab23e9b849..5b66692142 100644 --- a/src/sql/workbench/api/browser/mainThreadDataProtocol.ts +++ b/src/sql/workbench/api/browser/mainThreadDataProtocol.ts @@ -28,6 +28,7 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { assign } from 'vs/base/common/objects'; import { serializableToMap } from 'sql/base/common/map'; import { IAssessmentService } from 'sql/workbench/services/assessment/common/interfaces'; +import { IDataGridProviderService } from 'sql/workbench/services/dataGridProvider/common/dataGridProviderService'; /** * Main thread class for handling data protocol management registration. @@ -55,7 +56,8 @@ export class MainThreadDataProtocol extends Disposable implements MainThreadData @IProfilerService private _profilerService: IProfilerService, @ISerializationService private _serializationService: ISerializationService, @IFileBrowserService private _fileBrowserService: IFileBrowserService, - @IAssessmentService private _assessmentService: IAssessmentService + @IAssessmentService private _assessmentService: IAssessmentService, + @IDataGridProviderService private _dataGridProviderService: IDataGridProviderService ) { super(); if (extHostContext) { @@ -466,6 +468,20 @@ export class MainThreadDataProtocol extends Disposable implements MainThreadData return undefined; } + + public $registerDataGridProvider(providerId: string, handle: number): void { + const self = this; + this._dataGridProviderService.registerProvider(providerId, { + providerId: providerId, + getDataGridItems(): Thenable { + return self._proxy.$getDataGridItems(handle); + }, + getDataGridColumns(): Thenable { + return self._proxy.$getDataGridColumns(handle); + } + }); + } + public $registerCapabilitiesServiceProvider(providerId: string, handle: number): Promise { const self = this; this._capabilitiesService.registerProvider({ diff --git a/src/sql/workbench/api/common/extHostDataProtocol.ts b/src/sql/workbench/api/common/extHostDataProtocol.ts index cb70e90037..602a60c443 100644 --- a/src/sql/workbench/api/common/extHostDataProtocol.ts +++ b/src/sql/workbench/api/common/extHostDataProtocol.ts @@ -173,6 +173,11 @@ export class ExtHostDataProtocol extends ExtHostDataProtocolShape { this._proxy.$registerSqlAssessmentServicesProvider(provider.providerId, provider.handle); return rt; } + $registerDataGridProvider(provider: azdata.DataGridProvider): vscode.Disposable { + let rt = this.registerProvider(provider, DataProviderType.DataGridProvider); + this._proxy.$registerDataGridProvider(provider.providerId, provider.handle); + return rt; + } $registerCapabilitiesServiceProvider(provider: azdata.CapabilitiesProvider): vscode.Disposable { let rt = this.registerProvider(provider, DataProviderType.CapabilitiesProvider); this._proxy.$registerCapabilitiesServiceProvider(provider.providerId, provider.handle); @@ -856,4 +861,12 @@ export class ExtHostDataProtocol extends ExtHostDataProtocolShape { public $generateAssessmentScript(handle: number, items: azdata.SqlAssessmentResultItem[]): Thenable { return this._resolveProvider(handle).generateAssessmentScript(items); } + + public $getDataGridItems(handle: number): Thenable { + return this._resolveProvider(handle).getDataGridItems(); + } + + public $getDataGridColumns(handle: number): Thenable { + return this._resolveProvider(handle).getDataGridColumns(); + } } diff --git a/src/sql/workbench/api/common/sqlExtHost.api.impl.ts b/src/sql/workbench/api/common/sqlExtHost.api.impl.ts index f462e69e95..2d0059e9be 100644 --- a/src/sql/workbench/api/common/sqlExtHost.api.impl.ts +++ b/src/sql/workbench/api/common/sqlExtHost.api.impl.ts @@ -373,6 +373,10 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp return extHostDataProvider.$registerSqlAssessmentServiceProvider(provider); }; + let registerDataGridProvider = (provider: azdata.DataGridProvider): vscode.Disposable => { + return extHostDataProvider.$registerDataGridProvider(provider); + }; + // namespace: dataprotocol const dataprotocol: typeof azdata.dataprotocol = { registerBackupProvider, @@ -392,6 +396,7 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp registerCapabilitiesServiceProvider, registerSerializationProvider, registerSqlAssessmentServicesProvider, + registerDataGridProvider, onDidChangeLanguageFlavor(listener: (e: azdata.DidChangeLanguageFlavorParams) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { return extHostDataProvider.onDidChangeLanguageFlavor(listener, thisArgs, disposables); }, diff --git a/src/sql/workbench/api/common/sqlExtHost.protocol.ts b/src/sql/workbench/api/common/sqlExtHost.protocol.ts index f955a55345..8fa8e63875 100644 --- a/src/sql/workbench/api/common/sqlExtHost.protocol.ts +++ b/src/sql/workbench/api/common/sqlExtHost.protocol.ts @@ -509,6 +509,16 @@ export abstract class ExtHostDataProtocolShape { * Generate an assessment script based on recent results */ $generateAssessmentScript(handle: number, items: azdata.SqlAssessmentResultItem[]): Thenable { throw ni(); } + + /** + * Gets the list of items for a data grid + */ + $getDataGridItems(handle: number): Thenable { throw ni(); } + + /** + * Gets the list of columns for a data grid + */ + $getDataGridColumns(handle: number): Thenable { throw ni(); } } /** @@ -573,6 +583,7 @@ export interface MainThreadDataProtocolShape extends IDisposable { $registerAgentServicesProvider(providerId: string, handle: number): Promise; $registerSerializationProvider(providerId: string, handle: number): Promise; $registerSqlAssessmentServicesProvider(providerId: string, handle: number): Promise; + $registerDataGridProvider(providerId: string, handle: number): void; $unregisterProvider(handle: number): Promise; $onConnectionComplete(handle: number, connectionInfoSummary: azdata.ConnectionInfoSummary): void; $onIntelliSenseCacheComplete(handle: number, connectionUri: string): void; diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts index 7c97e44036..8b677ca6af 100644 --- a/src/sql/workbench/api/common/sqlExtHostTypes.ts +++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts @@ -354,7 +354,8 @@ export enum DataProviderType { ObjectExplorerNodeProvider = 'ObjectExplorerNodeProvider', SerializationProvider = 'SerializationProvider', IconProvider = 'IconProvider', - SqlAssessmentServicesProvider = 'SqlAssessmentServicesProvider' + SqlAssessmentServicesProvider = 'SqlAssessmentServicesProvider', + DataGridProvider = 'DataGridProvider' } export enum DeclarativeDataType { diff --git a/src/sql/workbench/services/dataGridProvider/browser/dataGridProviderService.ts b/src/sql/workbench/services/dataGridProvider/browser/dataGridProviderService.ts new file mode 100644 index 0000000000..2bce918735 --- /dev/null +++ b/src/sql/workbench/services/dataGridProvider/browser/dataGridProviderService.ts @@ -0,0 +1,58 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as azdata from 'azdata'; +import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry'; +import { IDataGridProviderService } from 'sql/workbench/services/dataGridProvider/common/dataGridProviderService'; +import { invalidProvider } from 'sql/base/common/errors'; +import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; + +export class DataGridProviderService implements IDataGridProviderService { + + public _serviceBrand: undefined; + private _providers = new Map(); + + constructor( + @IAdsTelemetryService private _telemetryService: IAdsTelemetryService + ) { } + + /** + * Register a data grid provider + */ + public registerProvider(providerId: string, provider: azdata.DataGridProvider): void { + if (this._providers.has(providerId)) { + throw new Error(`A DataGridProvider with id "${providerId}" is already registered`); + } + this._providers.set(providerId, provider); + } + + public unregisterProvider(providerId: string): void { + this._providers.delete(providerId); + } + + public async getDataGridItems(providerId: string): Promise { + const provider = this._providers.get(providerId); + if (provider) { + this._telemetryService.createActionEvent(TelemetryKeys.TelemetryView.Shell, TelemetryKeys.GetDataGridItems) + .withAdditionalProperties({ + provider: providerId + }).send(); + return provider.getDataGridItems(); + } + throw invalidProvider(providerId); + } + + public async getDataGridColumns(providerId: string): Promise { + const provider = this._providers.get(providerId); + if (provider) { + this._telemetryService.createActionEvent(TelemetryKeys.TelemetryView.Shell, TelemetryKeys.GetDataGridColumns) + .withAdditionalProperties({ + provider: providerId + }).send(); + return provider.getDataGridColumns(); + } + throw invalidProvider(providerId); + } +} diff --git a/src/sql/workbench/services/dataGridProvider/common/dataGridProviderService.ts b/src/sql/workbench/services/dataGridProvider/common/dataGridProviderService.ts new file mode 100644 index 0000000000..f129b02260 --- /dev/null +++ b/src/sql/workbench/services/dataGridProvider/common/dataGridProviderService.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as azdata from 'azdata'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const SERVICE_ID = 'dataGridProviderService'; +export const IDataGridProviderService = createDecorator(SERVICE_ID); + +export interface IDataGridProviderService { + _serviceBrand: undefined; + + /** + * Register a data grid provider + */ + registerProvider(providerId: string, provider: azdata.DataGridProvider): void; + + /** + * Unregister a resource data provider + */ + unregisterProvider(providerId: string): void; + + /** + * Gets a list of data grid items from the specified provider + */ + getDataGridItems(providerId: string): Promise; + + /** + * Gets a list of data grid columns from the specified provider + */ + getDataGridColumns(providerId: string): Promise; +} diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index cf65b3bd69..7195d3ff05 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -198,6 +198,8 @@ import { INotebookService } from 'sql/workbench/services/notebook/browser/notebo import { IScriptingService, ScriptingService } from 'sql/platform/scripting/common/scriptingService'; import { IAssessmentService } from 'sql/workbench/services/assessment/common/interfaces'; import { AssessmentService } from 'sql/workbench/services/assessment/common/assessmentService'; +import { DataGridProviderService } from 'sql/workbench/services/dataGridProvider/browser/dataGridProviderService'; +import { IDataGridProviderService } from 'sql/workbench/services/dataGridProvider/common/dataGridProviderService'; registerSingleton(IDashboardService, DashboardService); registerSingleton(IDashboardViewService, DashboardViewService); @@ -236,6 +238,7 @@ registerSingleton(IAdsTelemetryService, AdsTelemetryService); registerSingleton(IObjectExplorerService, ObjectExplorerService); registerSingleton(IOEShimService, OEShimService); registerSingleton(IAssessmentService, AssessmentService); +registerSingleton(IDataGridProviderService, DataGridProviderService); //#endregion