diff --git a/packages/grafana-ui/src/types/datasource.ts b/packages/grafana-ui/src/types/datasource.ts index f9a2d39dd1f..5448121a8d2 100644 --- a/packages/grafana-ui/src/types/datasource.ts +++ b/packages/grafana-ui/src/types/datasource.ts @@ -1,4 +1,4 @@ -import { ComponentClass } from 'react'; +import { ComponentType, ComponentClass } from 'react'; import { TimeRange } from './time'; import { PluginMeta, GrafanaPlugin } from './plugin'; import { TableData, TimeSeries, SeriesData, LoadingState } from './data'; @@ -11,19 +11,20 @@ export interface DataSourcePluginOptionsEditorProps { } export class DataSourcePlugin< + DSType extends DataSourceApi, TQuery extends DataQuery = DataQuery, TOptions extends DataSourceJsonData = DataSourceJsonData > extends GrafanaPlugin { - DataSourceClass: DataSourceConstructor; - components: DataSourcePluginComponents; + DataSourceClass: DataSourceConstructor; + components: DataSourcePluginComponents; - constructor(DataSourceClass: DataSourceConstructor) { + constructor(DataSourceClass: DataSourceConstructor) { super(); this.DataSourceClass = DataSourceClass; this.components = {}; } - setConfigEditor(editor: React.ComponentType>>) { + setConfigEditor(editor: ComponentType>>) { this.components.ConfigEditor = editor; return this; } @@ -38,12 +39,12 @@ export class DataSourcePlugin< return this; } - setQueryEditor(QueryEditor: ComponentClass>) { + setQueryEditor(QueryEditor: ComponentType>) { this.components.QueryEditor = QueryEditor; return this; } - setExploreQueryField(ExploreQueryField: ComponentClass>) { + setExploreQueryField(ExploreQueryField: ComponentClass>) { this.components.ExploreQueryField = ExploreQueryField; return this; } @@ -91,23 +92,26 @@ interface PluginMetaQueryOptions { } export interface DataSourcePluginComponents< + DSType extends DataSourceApi, TQuery extends DataQuery = DataQuery, TOptions extends DataSourceJsonData = DataSourceJsonData > { QueryCtrl?: any; AnnotationsQueryCtrl?: any; VariableQueryEditor?: any; - QueryEditor?: ComponentClass>; - ExploreQueryField?: ComponentClass>; + QueryEditor?: ComponentType>; + ExploreQueryField?: ComponentClass>; ExploreStartPage?: ComponentClass; - ConfigEditor?: React.ComponentType>>; + ConfigEditor?: ComponentType>>; } +// Only exported for tests export interface DataSourceConstructor< + DSType extends DataSourceApi, TQuery extends DataQuery = DataQuery, TOptions extends DataSourceJsonData = DataSourceJsonData > { - new (instanceSettings: DataSourceInstanceSettings, ...args: any[]): DataSourceApi; + new (instanceSettings: DataSourceInstanceSettings, ...args: any[]): DSType; } /** @@ -166,7 +170,7 @@ export interface DataSourceApi< * Set after constructor call, as the data source instance is the most common thing to pass around * we attach the components to this instance for easy access */ - components?: DataSourcePluginComponents; + components?: DataSourcePluginComponents, TQuery, TOptions>; /** * static information about the datasource @@ -174,13 +178,20 @@ export interface DataSourceApi< meta?: DataSourcePluginMeta; } -export interface ExploreDataSourceApi extends DataSourceApi { +export interface ExploreDataSourceApi< + TQuery extends DataQuery = DataQuery, + TOptions extends DataSourceJsonData = DataSourceJsonData +> extends DataSourceApi { modifyQuery?(query: TQuery, action: QueryFixAction): TQuery; getHighlighterExpression?(query: TQuery): string; languageProvider?: any; } -export interface QueryEditorProps { +export interface QueryEditorProps< + DSType extends DataSourceApi, + TQuery extends DataQuery = DataQuery, + TOptions extends DataSourceJsonData = DataSourceJsonData +> { datasource: DSType; query: TQuery; onRunQuery: () => void; @@ -194,7 +205,11 @@ export enum DataSourceStatus { Disconnected, } -export interface ExploreQueryFieldProps { +export interface ExploreQueryFieldProps< + DSType extends DataSourceApi, + TQuery extends DataQuery = DataQuery, + TOptions extends DataSourceJsonData = DataSourceJsonData +> { datasource: DSType; datasourceStatus: DataSourceStatus; query: TQuery; diff --git a/public/app/features/datasources/settings/DataSourceSettingsPage.tsx b/public/app/features/datasources/settings/DataSourceSettingsPage.tsx index a4c8e60a99b..e02684d57fc 100644 --- a/public/app/features/datasources/settings/DataSourceSettingsPage.tsx +++ b/public/app/features/datasources/settings/DataSourceSettingsPage.tsx @@ -5,7 +5,7 @@ import { connect } from 'react-redux'; // Components import Page from 'app/core/components/Page/Page'; -import PluginSettings from './PluginSettings'; +import { PluginSettings, GenericDataSourcePlugin } from './PluginSettings'; import BasicSettings from './BasicSettings'; import ButtonRow from './ButtonRow'; @@ -22,7 +22,7 @@ import { getRouteParamsId } from 'app/core/selectors/location'; // Types import { StoreState } from 'app/types/'; -import { NavModel, DataSourceSettings, DataSourcePlugin, DataSourcePluginMeta } from '@grafana/ui'; +import { NavModel, DataSourceSettings, DataSourcePluginMeta } from '@grafana/ui'; import { getDataSourceLoadingNav } from '../state/navModel'; import PluginStateinfo from 'app/features/plugins/PluginStateInfo'; import { importDataSourcePlugin } from 'app/features/plugins/plugin_loader'; @@ -37,12 +37,12 @@ export interface Props { setDataSourceName: typeof setDataSourceName; updateDataSource: typeof updateDataSource; setIsDefault: typeof setIsDefault; - plugin?: DataSourcePlugin; + plugin?: GenericDataSourcePlugin; } interface State { dataSource: DataSourceSettings; - plugin: DataSourcePlugin; + plugin: GenericDataSourcePlugin; isTesting?: boolean; testingMessage?: string; testingStatus?: string; @@ -60,7 +60,7 @@ export class DataSourceSettingsPage extends PureComponent { async loadPlugin(pluginId?: string) { const { dataSourceMeta } = this.props; - let importedPlugin: DataSourcePlugin; + let importedPlugin: GenericDataSourcePlugin; try { importedPlugin = await importDataSourcePlugin(dataSourceMeta); diff --git a/public/app/features/datasources/settings/PluginSettings.tsx b/public/app/features/datasources/settings/PluginSettings.tsx index 5b5efe95d56..94c054d56ee 100644 --- a/public/app/features/datasources/settings/PluginSettings.tsx +++ b/public/app/features/datasources/settings/PluginSettings.tsx @@ -1,10 +1,19 @@ import React, { PureComponent } from 'react'; import _ from 'lodash'; -import { DataSourceSettings, DataSourcePlugin, DataSourcePluginMeta } from '@grafana/ui'; +import { + DataSourceSettings, + DataSourcePlugin, + DataSourcePluginMeta, + DataSourceApi, + DataQuery, + DataSourceJsonData, +} from '@grafana/ui'; import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; +export type GenericDataSourcePlugin = DataSourcePlugin>; + export interface Props { - plugin: DataSourcePlugin; + plugin: GenericDataSourcePlugin; dataSource: DataSourceSettings; dataSourceMeta: DataSourcePluginMeta; onModelChange: (dataSource: DataSourceSettings) => void; diff --git a/public/app/plugins/datasource/input/InputQueryEditor.tsx b/public/app/plugins/datasource/input/InputQueryEditor.tsx index 1bbfb76f50b..68e1cb5516e 100644 --- a/public/app/plugins/datasource/input/InputQueryEditor.tsx +++ b/public/app/plugins/datasource/input/InputQueryEditor.tsx @@ -3,11 +3,11 @@ import React, { PureComponent } from 'react'; // Types import { InputDatasource } from './InputDatasource'; -import { InputQuery } from './types'; +import { InputQuery, InputOptions } from './types'; import { FormLabel, Select, QueryEditorProps, SelectOptionItem, SeriesData, TableInputCSV, toCSV } from '@grafana/ui'; -type Props = QueryEditorProps; +type Props = QueryEditorProps; const options = [ { value: 'panel', label: 'Panel', description: 'Save data in the panel configuration.' }, diff --git a/public/app/plugins/datasource/input/module.ts b/public/app/plugins/datasource/input/module.ts index 8aef9d9f53c..ef41af9ce0c 100644 --- a/public/app/plugins/datasource/input/module.ts +++ b/public/app/plugins/datasource/input/module.ts @@ -6,6 +6,6 @@ import { InputQueryEditor } from './InputQueryEditor'; import { InputConfigEditor } from './InputConfigEditor'; import { InputOptions, InputQuery } from './types'; -export const plugin = new DataSourcePlugin(InputDatasource) +export const plugin = new DataSourcePlugin(InputDatasource) .setConfigEditor(InputConfigEditor) .setQueryEditor(InputQueryEditor); diff --git a/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx b/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx index 6662e385e4a..547ecb90b95 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx @@ -66,7 +66,7 @@ export interface CascaderOption { disabled?: boolean; } -export interface LokiQueryFieldFormProps extends ExploreQueryFieldProps { +export interface LokiQueryFieldFormProps extends ExploreQueryFieldProps, LokiQuery> { history: HistoryItem[]; syntax: any; logLabelOptions: any[]; diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx index f34e8a54ecd..f8b2e79c60a 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx @@ -102,7 +102,7 @@ interface CascaderOption { disabled?: boolean; } -interface PromQueryFieldProps extends ExploreQueryFieldProps { +interface PromQueryFieldProps extends ExploreQueryFieldProps, PromQuery> { history: HistoryItem[]; }