Make Explore plugin exports explicit

pull/13844/head
David Kaltschmidt 7 years ago
parent d0776937b5
commit cf19ecc8f5
  1. 1
      public/app/core/utils/explore.test.ts
  2. 53
      public/app/features/explore/Explore.tsx
  3. 10
      public/app/features/explore/QueryField.tsx
  4. 14
      public/app/features/explore/QueryRows.tsx
  5. 7
      public/app/features/plugins/datasource_srv.ts
  6. 7
      public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
  7. 8
      public/app/plugins/datasource/prometheus/module.ts
  8. 6
      public/app/types/datasources.ts
  9. 2
      public/app/types/explore.ts
  10. 9
      public/app/types/plugins.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,

@ -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>

@ -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

@ -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)}

@ -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);
})

@ -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': {

@ -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,
};

@ -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 {

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

@ -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 {

Loading…
Cancel
Save