Преглед изворни кода

Make Explore plugin exports explicit

David Kaltschmidt пре 7 година
родитељ
комит
cf19ecc8f5

+ 0 - 1
public/app/core/utils/explore.test.ts

@@ -2,7 +2,6 @@ import { DEFAULT_RANGE, serializeStateToUrlParam, parseUrlState } from './explor
 import { ExploreState } from 'app/types/explore';
 
 const DEFAULT_EXPLORE_STATE: ExploreState = {
-  customComponents: {},
   datasource: null,
   datasourceError: null,
   datasourceLoading: null,

+ 22 - 31
public/app/features/explore/Explore.tsx

@@ -17,13 +17,14 @@ import IndicatorsContainer from 'app/core/components/Picker/IndicatorsContainer'
 import NoOptionsMessage from 'app/core/components/Picker/NoOptionsMessage';
 import TableModel, { mergeTablesIntoModel } from 'app/core/table_model';
 
-import DefaultQueryRows from './QueryRows';
-import DefaultGraph from './Graph';
-import DefaultLogs from './Logs';
-import DefaultTable from './Table';
+import QueryRows from './QueryRows';
+import Graph from './Graph';
+import Logs from './Logs';
+import Table from './Table';
 import ErrorBoundary from './ErrorBoundary';
 import TimePicker from './TimePicker';
 import { ensureQueries, generateQueryKey, hasQuery } from './utils/query';
+import { DataSource } from 'app/types/datasources';
 
 const MAX_HISTORY_ITEMS = 100;
 
@@ -96,7 +97,6 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
       initialQueries = ensureQueries(queries);
       const initialRange = range || { ...DEFAULT_RANGE };
       this.state = {
-        customComponents: {},
         datasource: null,
         datasourceError: null,
         datasourceLoading: null,
@@ -149,7 +149,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
     }
   }
 
-  async setDatasource(datasource) {
+  async setDatasource(datasource: DataSource) {
     const supportsGraph = datasource.meta.metrics;
     const supportsLogs = datasource.meta.logs;
     const supportsTable = datasource.meta.metrics;
@@ -177,13 +177,12 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
       query: this.queryExpressions[i],
     }));
 
-    const customComponents = {
-      ...datasource.exploreComponents,
-    };
+    // Custom components
+    const StartPage = datasource.pluginExports.ExploreStartPage;
 
     this.setState(
       {
-        customComponents,
+        StartPage,
         datasource,
         datasourceError,
         history,
@@ -398,9 +397,9 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
               q.query = this.queryExpressions[i];
               return i === index
                 ? {
-                  key: generateQueryKey(index),
-                  query: datasource.modifyQuery(q.query, action),
-                }
+                    key: generateQueryKey(index),
+                    query: datasource.modifyQuery(q.query, action),
+                  }
                 : q;
             });
             nextQueryTransactions = queryTransactions
@@ -734,7 +733,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
   render() {
     const { position, split } = this.props;
     const {
-      customComponents,
+      StartPage,
       datasource,
       datasourceError,
       datasourceLoading,
@@ -774,14 +773,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
       queryTransactions.filter(qt => qt.resultType === 'Logs' && qt.done && qt.result).map(qt => qt.result)
     );
     const loading = queryTransactions.some(qt => !qt.done);
-    const showStartPages = queryTransactions.length === 0 && customComponents.StartPage;
-
-    // Custom components
-    const Graph = customComponents.Graph || DefaultGraph;
-    const Logs = customComponents.Logs || DefaultLogs;
-    const QueryRows = customComponents.QueryRows || DefaultQueryRows;
-    const StartPage = customComponents.StartPage;
-    const Table = customComponents.Table || DefaultTable;
+    const showStartPages = StartPage && queryTransactions.length === 0;
 
     return (
       <div className={exploreClass} ref={this.getRef}>
@@ -794,12 +786,12 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
               </a>
             </div>
           ) : (
-              <div className="navbar-buttons explore-first-button">
-                <button className="btn navbar-button" onClick={this.onClickCloseSplit}>
-                  Close Split
+            <div className="navbar-buttons explore-first-button">
+              <button className="btn navbar-button" onClick={this.onClickCloseSplit}>
+                Close Split
               </button>
-              </div>
-            )}
+            </div>
+          )}
           {!datasourceMissing ? (
             <div className="navbar-buttons">
               <Select
@@ -858,7 +850,6 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
         {datasource && !datasourceError ? (
           <div className="explore-container">
             <QueryRows
-              customComponents={customComponents}
               datasource={datasource}
               history={history}
               queries={queries}
@@ -879,17 +870,17 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
                       {supportsGraph ? (
                         <button className={`btn toggle-btn ${graphButtonActive}`} onClick={this.onClickGraphButton}>
                           Graph
-                      </button>
+                        </button>
                       ) : null}
                       {supportsTable ? (
                         <button className={`btn toggle-btn ${tableButtonActive}`} onClick={this.onClickTableButton}>
                           Table
-                      </button>
+                        </button>
                       ) : null}
                       {supportsLogs ? (
                         <button className={`btn toggle-btn ${logsButtonActive}`} onClick={this.onClickLogsButton}>
                           Logs
-                      </button>
+                        </button>
                       ) : null}
                     </div>
 

+ 5 - 5
public/app/features/explore/QueryField.tsx

@@ -27,7 +27,7 @@ function hasSuggestions(suggestions: CompletionItemGroup[]): boolean {
   return suggestions && suggestions.length > 0;
 }
 
-interface TypeaheadFieldProps {
+interface QueryFieldProps {
   additionalPlugins?: any[];
   cleanText?: (text: string) => string;
   initialValue: string | null;
@@ -35,14 +35,14 @@ interface TypeaheadFieldProps {
   onFocus?: () => void;
   onTypeahead?: (typeahead: TypeaheadInput) => TypeaheadOutput;
   onValueChanged?: (value: Value) => void;
-  onWillApplySuggestion?: (suggestion: string, state: TypeaheadFieldState) => string;
+  onWillApplySuggestion?: (suggestion: string, state: QueryFieldState) => string;
   placeholder?: string;
   portalOrigin?: string;
   syntax?: string;
   syntaxLoaded?: boolean;
 }
 
-export interface TypeaheadFieldState {
+export interface QueryFieldState {
   suggestions: CompletionItemGroup[];
   typeaheadContext: string | null;
   typeaheadIndex: number;
@@ -60,7 +60,7 @@ export interface TypeaheadInput {
   wrapperNode: Element;
 }
 
-class QueryField extends React.PureComponent<TypeaheadFieldProps, TypeaheadFieldState> {
+export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldState> {
   menuEl: HTMLElement | null;
   placeholdersBuffer: PlaceholdersBuffer;
   plugins: any[];
@@ -102,7 +102,7 @@ class QueryField extends React.PureComponent<TypeaheadFieldProps, TypeaheadField
     }
   }
 
-  componentWillReceiveProps(nextProps: TypeaheadFieldProps) {
+  componentWillReceiveProps(nextProps: QueryFieldProps) {
     if (nextProps.syntaxLoaded && !this.props.syntaxLoaded) {
       // Need a bogus edit to re-render the editor after syntax has fully loaded
       const change = this.state.value

+ 6 - 8
public/app/features/explore/QueryRows.tsx

@@ -4,6 +4,7 @@ import { QueryTransaction, HistoryItem, Query, QueryHint } from 'app/types/explo
 
 import DefaultQueryField from './QueryField';
 import QueryTransactionStatus from './QueryTransactionStatus';
+import { DataSource } from 'app/types';
 
 function getFirstHintFromTransactions(transactions: QueryTransaction[]): QueryHint {
   const transaction = transactions.find(qt => qt.hints && qt.hints.length > 0);
@@ -23,8 +24,7 @@ interface QueryRowEventHandlers {
 
 interface QueryRowCommonProps {
   className?: string;
-  customComponents: any;
-  datasource: any;
+  datasource: DataSource;
   history: HistoryItem[];
   // Temporarily
   supportsLogs?: boolean;
@@ -37,7 +37,7 @@ type QueryRowProps = QueryRowCommonProps &
     query: string;
   };
 
-class DefaultQueryRow extends PureComponent<QueryRowProps> {
+class QueryRow extends PureComponent<QueryRowProps> {
   onChangeQuery = (value, override?: boolean) => {
     const { index, onChangeQuery } = this.props;
     if (onChangeQuery) {
@@ -78,11 +78,11 @@ class DefaultQueryRow extends PureComponent<QueryRowProps> {
   };
 
   render() {
-    const { customComponents, datasource, history, query, supportsLogs, transactions } = this.props;
+    const { datasource, history, query, supportsLogs, transactions } = this.props;
     const transactionWithError = transactions.find(t => t.error !== undefined);
     const hint = getFirstHintFromTransactions(transactions);
     const queryError = transactionWithError ? transactionWithError.error : null;
-    const QueryField = customComponents.QueryField || DefaultQueryField;
+    const QueryField = datasource.pluginExports.ExploreQueryField || DefaultQueryField;
     return (
       <div className="query-row">
         <div className="query-row-status">
@@ -124,14 +124,12 @@ type QueryRowsProps = QueryRowCommonProps &
 
 export default class QueryRows extends PureComponent<QueryRowsProps> {
   render() {
-    const { className = '', customComponents, queries, transactions, ...handlers } = this.props;
-    const QueryRow = customComponents.QueryRow || DefaultQueryRow;
+    const { className = '', queries, transactions, ...handlers } = this.props;
     return (
       <div className={className}>
         {queries.map((q, index) => (
           <QueryRow
             key={q.key}
-            customComponents={customComponents}
             index={index}
             query={q.query}
             transactions={transactions.filter(t => t.rowIndex === index)}

+ 4 - 3
public/app/features/plugins/datasource_srv.ts

@@ -8,9 +8,10 @@ import { importPluginModule } from './plugin_loader';
 
 // Types
 import { DataSourceApi } from 'app/types/series';
+import { DataSource } from 'app/types';
 
 export class DatasourceSrv {
-  datasources: any;
+  datasources: { [name: string]: DataSource };
 
   /** @ngInject */
   constructor(private $q, private $injector, private $rootScope, private templateSrv) {
@@ -61,10 +62,10 @@ export class DatasourceSrv {
           throw new Error('Plugin module is missing Datasource constructor');
         }
 
-        const instance = this.$injector.instantiate(plugin.Datasource, { instanceSettings: dsConfig });
+        const instance: DataSource = this.$injector.instantiate(plugin.Datasource, { instanceSettings: dsConfig });
         instance.meta = pluginDef;
         instance.name = name;
-        instance.exploreComponents = plugin.ExploreComponents;
+        instance.pluginExports = plugin;
         this.datasources[name] = instance;
         deferred.resolve(instance);
       })

+ 2 - 5
public/app/plugins/datasource/prometheus/components/PromQueryField.tsx

@@ -10,7 +10,7 @@ import { TypeaheadOutput } from 'app/types/explore';
 import { getNextCharacter, getPreviousCousin } from 'app/features/explore/utils/dom';
 import BracesPlugin from 'app/features/explore/slate-plugins/braces';
 import RunnerPlugin from 'app/features/explore/slate-plugins/runner';
-import TypeaheadField, { TypeaheadInput, TypeaheadFieldState } from 'app/features/explore/QueryField';
+import TypeaheadField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField';
 
 const HISTOGRAM_GROUP = '__histograms__';
 const METRIC_MARK = 'metric';
@@ -50,10 +50,7 @@ export function groupMetricsByPrefix(metrics: string[], delimiter = '_'): Cascad
   return [...options, ...metricsOptions];
 }
 
-export function willApplySuggestion(
-  suggestion: string,
-  { typeaheadContext, typeaheadText }: TypeaheadFieldState
-): string {
+export function willApplySuggestion(suggestion: string, { typeaheadContext, typeaheadText }: QueryFieldState): string {
   // Modify suggestion based on context
   switch (typeaheadContext) {
     case 'context-labels': {

+ 2 - 6
public/app/plugins/datasource/prometheus/module.ts

@@ -9,15 +9,11 @@ class PrometheusAnnotationsQueryCtrl {
   static templateUrl = 'partials/annotations.editor.html';
 }
 
-const ExploreComponents = {
-  QueryField: PromQueryField,
-  StartPage: PrometheusStartPage,
-};
-
 export {
   PrometheusDatasource as Datasource,
   PrometheusQueryCtrl as QueryCtrl,
   PrometheusConfigCtrl as ConfigCtrl,
   PrometheusAnnotationsQueryCtrl as AnnotationsQueryCtrl,
-  ExploreComponents,
+  PromQueryField as ExploreQueryField,
+  PrometheusStartPage as ExploreStartPage,
 };

+ 5 - 1
public/app/types/datasources.ts

@@ -1,5 +1,5 @@
 import { LayoutMode } from '../core/components/LayoutSelector/LayoutSelector';
-import { Plugin } from './plugins';
+import { Plugin, PluginExports, PluginMeta } from './plugins';
 
 export interface DataSource {
   id: number;
@@ -16,6 +16,10 @@ export interface DataSource {
   isDefault: boolean;
   jsonData: { authType: string; defaultRegion: string };
   readOnly: boolean;
+  meta?: PluginMeta;
+  pluginExports?: PluginExports;
+  init?: () => void;
+  testDatasource?: () => Promise<any>;
 }
 
 export interface DataSourcesState {

+ 1 - 1
public/app/types/explore.ts

@@ -146,7 +146,7 @@ export interface TextMatch {
 }
 
 export interface ExploreState {
-  customComponents: any;
+  StartPage?: any;
   datasource: any;
   datasourceError: any;
   datasourceLoading: boolean | null;

+ 8 - 1
public/app/types/plugins.ts

@@ -6,7 +6,8 @@ export interface PluginExports {
   ConfigCtrl?: any;
   AnnotationsQueryCtrl?: any;
   PanelOptions?: any;
-  ExploreComponents?: any;
+  ExploreQueryField?: any;
+  ExploreStartPage?: any;
 }
 
 export interface PanelPlugin {
@@ -26,6 +27,12 @@ export interface PluginMeta {
   name: string;
   info: PluginMetaInfo;
   includes: PluginInclude[];
+
+  // Datasource-specific
+  metrics?: boolean;
+  logs?: boolean;
+  explore?: boolean;
+  annotations?: boolean;
 }
 
 export interface PluginInclude {