Refactor: Plugin exports & data source / panel types (#16364)

* wip: began work off removing meta and pluginExports from DataSourceApi interface

* WIP: changing how plugins are exports and loaded

* Down the refactoring rabit hole that keeps expanding

* TestData now returns DataSourcePlugin

* Refactoring: fixed app config page loading, type renamings and more typings

* Refactor: Correct casing on DatasourceStatus => DataSourceStatus
This commit is contained in:
Torkel Ödegaard
2019-04-04 18:30:15 +02:00
committed by GitHub
parent e04990752c
commit 47e51cb6b3
31 changed files with 411 additions and 251 deletions

View File

@@ -1,7 +1,159 @@
import { ComponentClass } from 'react';
import { TimeRange, RawTimeRange } from './time';
import { PluginMeta } from './plugin';
import { TableData, TimeSeries, SeriesData } from './data';
export class DataSourcePlugin<TQuery extends DataQuery = DataQuery> {
DataSourceClass: DataSourceConstructor<TQuery>;
components: DataSourcePluginComponents<TQuery>;
constructor(DataSourceClass: DataSourceConstructor<TQuery>) {
this.DataSourceClass = DataSourceClass;
this.components = {};
}
setConfigCtrl(ConfigCtrl: any) {
this.components.ConfigCtrl = ConfigCtrl;
return this;
}
setQueryCtrl(QueryCtrl: any) {
this.components.QueryCtrl = QueryCtrl;
return this;
}
setAnnotationQueryCtrl(AnnotationsQueryCtrl: any) {
this.components.AnnotationsQueryCtrl = AnnotationsQueryCtrl;
return this;
}
setQueryEditor(QueryEditor: ComponentClass<QueryEditorProps<DataSourceApi, TQuery>>) {
this.components.QueryEditor = QueryEditor;
return this;
}
setExploreQueryField(ExploreQueryField: ComponentClass<ExploreQueryFieldProps<DataSourceApi, TQuery>>) {
this.components.ExploreQueryField = ExploreQueryField;
return this;
}
setExploreStartPage(ExploreStartPage: ComponentClass<ExploreStartPageProps>) {
this.components.ExploreStartPage = ExploreStartPage;
return this;
}
setVariableQueryEditor(VariableQueryEditor: any) {
this.components.VariableQueryEditor = VariableQueryEditor;
return this;
}
setComponentsFromLegacyExports(exports: any) {
this.components.ConfigCtrl = exports.ConfigCtrl;
this.components.QueryCtrl = exports.QueryCtrl;
this.components.AnnotationsQueryCtrl = exports.AnnotationsQueryCtrl;
this.components.ExploreQueryField = exports.ExploreQueryField;
this.components.ExploreStartPage = exports.ExploreStartPage;
this.components.QueryEditor = exports.QueryEditor;
}
}
export interface DataSourcePluginComponents<TQuery extends DataQuery = DataQuery> {
QueryCtrl?: any;
ConfigCtrl?: any;
AnnotationsQueryCtrl?: any;
VariableQueryEditor?: any;
QueryEditor?: ComponentClass<QueryEditorProps<DataSourceApi, TQuery>>;
ExploreQueryField?: ComponentClass<ExploreQueryFieldProps<DataSourceApi, TQuery>>;
ExploreStartPage?: ComponentClass<ExploreStartPageProps>;
}
interface DataSourceConstructor<TQuery extends DataQuery = DataQuery> {
new (instanceSettings: DataSourceInstanceSettings, ...args: any[]): DataSourceApi<TQuery>;
}
/**
* The main data source abstraction interface, represents an instance of a data source
*/
export interface DataSourceApi<TQuery extends DataQuery = DataQuery> {
/**
* min interval range
*/
interval?: string;
/**
* Imports queries from a different datasource
*/
importQueries?(queries: TQuery[], originMeta: PluginMeta): Promise<TQuery[]>;
/**
* Initializes a datasource after instantiation
*/
init?: () => void;
/**
* Main metrics / data query action
*/
query(options: DataQueryOptions<TQuery>): Promise<DataQueryResponse>;
/**
* Test & verify datasource settings & connection details
*/
testDatasource(): Promise<any>;
/**
* Get hints for query improvements
*/
getQueryHints?(query: TQuery, results: any[], ...rest: any): QueryHint[];
/**
* Set after constructor is called by Grafana
*/
name?: string;
/**
* 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;
meta?: PluginMeta;
}
export interface ExploreDataSourceApi<TQuery extends DataQuery = DataQuery> extends DataSourceApi {
modifyQuery?(query: TQuery, action: QueryFixAction): TQuery;
getHighlighterExpression?(query: TQuery): string;
languageProvider?: any;
}
export interface QueryEditorProps<DSType extends DataSourceApi, TQuery extends DataQuery> {
datasource: DSType;
query: TQuery;
onRunQuery: () => void;
onChange: (value: TQuery) => void;
queryResponse?: SeriesData[];
queryError?: DataQueryError;
}
export enum DataSourceStatus {
Connected,
Disconnected,
}
export interface ExploreQueryFieldProps<DSType extends DataSourceApi, TQuery extends DataQuery> {
datasource: DSType;
datasourceStatus: DataSourceStatus;
query: TQuery;
error?: string | JSX.Element;
hint?: QueryHint;
history: any[];
onExecuteQuery?: () => void;
onQueryChange?: (value: TQuery) => void;
onExecuteHint?: (action: QueryFixAction) => void;
}
export interface ExploreStartPageProps {
onClickExample: (query: DataQuery) => void;
}
/**
* Starting in v6.2 SeriesData can represent both TimeSeries and TableData
*/
@@ -89,6 +241,9 @@ export interface QueryHint {
fix?: QueryFix;
}
/**
* Data Source instance edit model
*/
export interface DataSourceSettings {
id: number;
orgId: number;
@@ -109,6 +264,29 @@ export interface DataSourceSettings {
withCredentials: boolean;
}
/**
* Frontend settings model that is passed to Datasource constructor. This differs a bit from the model above
* as this data model is available to every user who has access to a data source (Viewers+).
*/
export interface DataSourceInstanceSettings {
type: string;
name: string;
meta: PluginMeta;
url?: string;
jsonData: { [str: string]: any };
username?: string;
password?: string; // when access is direct, for some legacy datasources
/**
* This is the full Authorization header if basic auth is ennabled.
* Only available here when access is Browser (direct), when acess is Server (proxy)
* The basic auth header, username & password is never exposted to browser/Frontend
* so this will be emtpy then.
*/
basicAuth?: string;
withCredentials?: boolean;
}
export interface DataSourceSelectItem {
name: string;
value: string | null;

View File

@@ -83,6 +83,16 @@ export class ReactPanelPlugin<TOptions = any> {
}
}
export class AngularPanelPlugin {
components: {
PanelCtrl: any;
};
constructor(PanelCtrl: any) {
this.components = { PanelCtrl: PanelCtrl };
}
}
export interface PanelSize {
width: number;
height: number;

View File

@@ -1,110 +1,10 @@
import { ComponentClass } from 'react';
import { ReactPanelPlugin } from './panel';
import {
DataQueryOptions,
DataQuery,
DataQueryResponse,
QueryHint,
QueryFixAction,
DataQueryError,
} from './datasource';
import { SeriesData } from './data';
export interface DataSourceApi<TQuery extends DataQuery = DataQuery> {
/**
* min interval range
*/
interval?: string;
/**
* Imports queries from a different datasource
*/
importQueries?(queries: TQuery[], originMeta: PluginMeta): Promise<TQuery[]>;
/**
* Initializes a datasource after instantiation
*/
init?: () => void;
/**
* Main metrics / data query action
*/
query(options: DataQueryOptions<TQuery>): Promise<DataQueryResponse>;
/**
* Test & verify datasource settings & connection details
*/
testDatasource(): Promise<any>;
/**
* Get hints for query improvements
*/
getQueryHints?(query: TQuery, results: any[], ...rest: any): QueryHint[];
/**
* Set after constructor is called by Grafana
*/
name?: string;
meta?: PluginMeta;
pluginExports?: PluginExports;
}
export interface ExploreDataSourceApi<TQuery extends DataQuery = DataQuery> extends DataSourceApi {
modifyQuery?(query: TQuery, action: QueryFixAction): TQuery;
getHighlighterExpression?(query: TQuery): string;
languageProvider?: any;
}
export interface QueryEditorProps<DSType extends DataSourceApi, TQuery extends DataQuery> {
datasource: DSType;
query: TQuery;
onRunQuery: () => void;
onChange: (value: TQuery) => void;
queryResponse?: SeriesData[];
queryError?: DataQueryError;
}
export enum DatasourceStatus {
Connected,
Disconnected,
}
export interface ExploreQueryFieldProps<DSType extends DataSourceApi, TQuery extends DataQuery> {
datasource: DSType;
datasourceStatus: DatasourceStatus;
query: TQuery;
error?: string | JSX.Element;
hint?: QueryHint;
history: any[];
onExecuteQuery?: () => void;
onQueryChange?: (value: TQuery) => void;
onExecuteHint?: (action: QueryFixAction) => void;
}
export interface ExploreStartPageProps {
onClickExample: (query: DataQuery) => void;
}
export interface PluginExports {
Datasource?: DataSourceApi;
QueryCtrl?: any;
QueryEditor?: ComponentClass<QueryEditorProps<DataSourceApi, DataQuery>>;
ConfigCtrl?: any;
AnnotationsQueryCtrl?: any;
VariableQueryEditor?: any;
ExploreQueryField?: ComponentClass<ExploreQueryFieldProps<DataSourceApi, DataQuery>>;
ExploreStartPage?: ComponentClass<ExploreStartPageProps>;
// Panel plugin
PanelCtrl?: any;
reactPanel?: ReactPanelPlugin;
}
export interface PluginMeta {
id: string;
name: string;
info: PluginMetaInfo;
includes: PluginInclude[];
module: string;
baseUrl: string;
// Datasource-specific
builtIn?: boolean;
@@ -150,3 +50,18 @@ export interface PluginMetaInfo {
updated: string;
version: string;
}
export class AppPlugin {
components: {
ConfigCtrl?: any;
};
pages: { [str: string]: any };
constructor(ConfigCtrl: any) {
this.components = {
ConfigCtrl: ConfigCtrl,
};
this.pages = {};
}
}