Alignment of interfaces and components

This commit is contained in:
Hugo Häggmark
2019-02-01 11:55:01 +01:00
parent 43f8098981
commit acea1d7f00
6 changed files with 77 additions and 66 deletions

View File

@@ -41,6 +41,12 @@ export interface DataSourceApi<TQuery extends DataQuery = DataQuery> {
pluginExports?: PluginExports; pluginExports?: PluginExports;
} }
export interface ExploreDataSourceApi<TQuery extends DataQuery = DataQuery> extends DataSourceApi {
modifyQuery?(query: TQuery, action: any): TQuery;
getHighlighterExpression?(query: TQuery): string;
languageProvider?: any;
}
export interface QueryEditorProps<DSType extends DataSourceApi, TQuery extends DataQuery> { export interface QueryEditorProps<DSType extends DataSourceApi, TQuery extends DataQuery> {
datasource: DSType; datasource: DSType;
query: TQuery; query: TQuery;
@@ -48,6 +54,16 @@ export interface QueryEditorProps<DSType extends DataSourceApi, TQuery extends D
onChange: (value: TQuery) => void; onChange: (value: TQuery) => void;
} }
export interface ExploreQueryFieldProps<DSType extends DataSourceApi, TQuery extends DataQuery> {
datasource: DSType;
initialQuery: TQuery;
error?: string | JSX.Element;
hint?: QueryHint;
history: any[];
onExecuteQuery?: () => void;
onQueryChange?: (value: TQuery) => void;
}
export interface PluginExports { export interface PluginExports {
Datasource?: DataSourceApi; Datasource?: DataSourceApi;
QueryCtrl?: any; QueryCtrl?: any;
@@ -55,7 +71,7 @@ export interface PluginExports {
ConfigCtrl?: any; ConfigCtrl?: any;
AnnotationsQueryCtrl?: any; AnnotationsQueryCtrl?: any;
VariableQueryEditor?: any; VariableQueryEditor?: any;
ExploreQueryField?: any; ExploreQueryField?: ComponentClass<ExploreQueryFieldProps<DataSourceApi, DataQuery>>;
ExploreStartPage?: any; ExploreStartPage?: any;
// Panel plugin // Panel plugin

View File

@@ -33,10 +33,9 @@ export interface QueryFieldProps {
cleanText?: (text: string) => string; cleanText?: (text: string) => string;
disabled?: boolean; disabled?: boolean;
initialQuery: string | null; initialQuery: string | null;
onBlur?: () => void; onExecuteQuery?: () => void;
onFocus?: () => void; onQueryChange?: (value: string) => void;
onTypeahead?: (typeahead: TypeaheadInput) => TypeaheadOutput; onTypeahead?: (typeahead: TypeaheadInput) => TypeaheadOutput;
onValueChanged?: (value: string) => void;
onWillApplySuggestion?: (suggestion: string, state: QueryFieldState) => string; onWillApplySuggestion?: (suggestion: string, state: QueryFieldState) => string;
placeholder?: string; placeholder?: string;
portalOrigin?: string; portalOrigin?: string;
@@ -145,7 +144,7 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
if (documentChanged) { if (documentChanged) {
const textChanged = Plain.serialize(prevValue) !== Plain.serialize(value); const textChanged = Plain.serialize(prevValue) !== Plain.serialize(value);
if (textChanged && invokeParentOnValueChanged) { if (textChanged && invokeParentOnValueChanged) {
this.handleChangeValue(); this.executeOnQueryChangeAndExecuteQueries();
} }
} }
}); });
@@ -159,11 +158,15 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
} }
}; };
handleChangeValue = () => { executeOnQueryChangeAndExecuteQueries = () => {
// Send text change to parent // Send text change to parent
const { onValueChanged } = this.props; const { onQueryChange, onExecuteQuery } = this.props;
if (onValueChanged) { if (onQueryChange) {
onValueChanged(Plain.serialize(this.state.value)); onQueryChange(Plain.serialize(this.state.value));
}
if (onExecuteQuery) {
onExecuteQuery();
} }
}; };
@@ -311,7 +314,7 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
return true; return true;
} else { } else {
this.handleChangeValue(); this.executeOnQueryChangeAndExecuteQueries();
return undefined; return undefined;
} }
@@ -379,23 +382,16 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
}; };
handleBlur = () => { handleBlur = () => {
const { onBlur } = this.props;
// If we dont wait here, menu clicks wont work because the menu // If we dont wait here, menu clicks wont work because the menu
// will be gone. // will be gone.
this.resetTimer = setTimeout(this.resetTypeahead, 100); this.resetTimer = setTimeout(this.resetTypeahead, 100);
// Disrupting placeholder entry wipes all remaining placeholders needing input // Disrupting placeholder entry wipes all remaining placeholders needing input
this.placeholdersBuffer.clearPlaceholders(); this.placeholdersBuffer.clearPlaceholders();
if (onBlur) {
onBlur(); this.executeOnQueryChangeAndExecuteQueries();
}
}; };
handleFocus = () => { handleFocus = () => {};
const { onFocus } = this.props;
if (onFocus) {
onFocus();
}
};
onClickMenu = (item: CompletionItem) => { onClickMenu = (item: CompletionItem) => {
// Manually triggering change // Manually triggering change

View File

@@ -20,7 +20,7 @@ import {
// Types // Types
import { StoreState } from 'app/types'; import { StoreState } from 'app/types';
import { RawTimeRange, DataQuery, QueryHint } from '@grafana/ui'; import { RawTimeRange, DataQuery, ExploreDataSourceApi, QueryHint } from '@grafana/ui';
import { QueryTransaction, HistoryItem, ExploreItemState, ExploreId } from 'app/types/explore'; import { QueryTransaction, HistoryItem, ExploreItemState, ExploreId } from 'app/types/explore';
import { Emitter } from 'app/core/utils/emitter'; import { Emitter } from 'app/core/utils/emitter';
@@ -37,7 +37,7 @@ interface QueryRowProps {
changeQuery: typeof changeQuery; changeQuery: typeof changeQuery;
className?: string; className?: string;
exploreId: ExploreId; exploreId: ExploreId;
datasourceInstance: any; datasourceInstance: ExploreDataSourceApi;
highlightLogsExpression: typeof highlightLogsExpression; highlightLogsExpression: typeof highlightLogsExpression;
history: HistoryItem[]; history: HistoryItem[];
index: number; index: number;
@@ -115,13 +115,15 @@ export class QueryRow extends PureComponent<QueryRowProps> {
{QueryField ? ( {QueryField ? (
<QueryField <QueryField
datasource={datasourceInstance} datasource={datasourceInstance}
initialQuery={initialQuery}
onExecuteQuery={this.onExecuteQuery}
onQueryChange={this.onChangeQuery}
error={queryError} error={queryError}
hint={hint} hint={hint}
initialQuery={initialQuery}
history={history} history={history}
onClickHintFix={this.onClickHintFix} // onClickHintFix={this.onClickHintFix}
onPressEnter={this.onExecuteQuery} // onPressEnter={this.onExecuteQuery}
onQueryChange={this.onChangeQuery} // onQueryChange={this.onChangeQuery}
/> />
) : ( ) : (
<QueryEditor <QueryEditor

View File

@@ -12,12 +12,12 @@ import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explor
import { getNextCharacter, getPreviousCousin } from 'app/features/explore/utils/dom'; import { getNextCharacter, getPreviousCousin } from 'app/features/explore/utils/dom';
import BracesPlugin from 'app/features/explore/slate-plugins/braces'; import BracesPlugin from 'app/features/explore/slate-plugins/braces';
import RunnerPlugin from 'app/features/explore/slate-plugins/runner'; import RunnerPlugin from 'app/features/explore/slate-plugins/runner';
import LokiDatasource from '../datasource';
// Types // Types
import { LokiQuery } from '../types'; import { LokiQuery } from '../types';
import { TypeaheadOutput } from 'app/types/explore'; import { TypeaheadOutput, HistoryItem } from 'app/types/explore';
import { makePromiseCancelable, CancelablePromise } from 'app/core/utils/CancelablePromise'; import { makePromiseCancelable, CancelablePromise } from 'app/core/utils/CancelablePromise';
import { ExploreDataSourceApi, ExploreQueryFieldProps } from '@grafana/ui';
const PRISM_SYNTAX = 'promql'; const PRISM_SYNTAX = 'promql';
@@ -65,15 +65,8 @@ interface CascaderOption {
disabled?: boolean; disabled?: boolean;
} }
interface LokiQueryFieldProps { interface LokiQueryFieldProps extends ExploreQueryFieldProps<ExploreDataSourceApi, LokiQuery> {
datasource: LokiDatasource; history: HistoryItem[];
error?: string | JSX.Element;
hint?: any;
history?: any[];
initialQuery?: LokiQuery;
onClickHintFix?: (action: any) => void;
onPressEnter?: () => void;
onQueryChange?: (value: LokiQuery, override?: boolean) => void;
} }
interface LokiQueryFieldState { interface LokiQueryFieldState {
@@ -98,14 +91,14 @@ export class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, Lok
this.plugins = [ this.plugins = [
BracesPlugin(), BracesPlugin(),
RunnerPlugin({ handler: props.onPressEnter }), RunnerPlugin({ handler: props.onExecuteQuery }),
PluginPrism({ PluginPrism({
onlyIn: node => node.type === 'code_block', onlyIn: node => node.type === 'code_block',
getSyntax: node => 'promql', getSyntax: node => 'promql',
}), }),
]; ];
this.pluginsSearch = [RunnerPlugin({ handler: props.onPressEnter })]; this.pluginsSearch = [RunnerPlugin({ handler: props.onExecuteQuery })];
this.state = { this.state = {
logLabelOptions: [], logLabelOptions: [],
@@ -169,21 +162,25 @@ export class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, Lok
onChangeQuery = (value: string, override?: boolean) => { onChangeQuery = (value: string, override?: boolean) => {
// Send text change to parent // Send text change to parent
const { initialQuery, onQueryChange } = this.props; const { initialQuery, onQueryChange, onExecuteQuery } = this.props;
if (onQueryChange) { if (onQueryChange) {
const query = { const query = {
...initialQuery, ...initialQuery,
expr: value, expr: value,
}; };
onQueryChange(query, override); onQueryChange(query);
if (override && onExecuteQuery) {
onExecuteQuery();
}
} }
}; };
onClickHintFix = () => { onClickHintFix = () => {
const { hint, onClickHintFix } = this.props; // const { hint, onClickHintFix } = this.props;
if (onClickHintFix && hint && hint.fix) { // if (onClickHintFix && hint && hint.fix) {
onClickHintFix(hint.fix.action); // onClickHintFix(hint.fix.action);
} // }
}; };
onUpdateLanguage = () => { onUpdateLanguage = () => {
@@ -243,7 +240,8 @@ export class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, Lok
initialQuery={initialQuery.expr} initialQuery={initialQuery.expr}
onTypeahead={this.onTypeahead} onTypeahead={this.onTypeahead}
onWillApplySuggestion={willApplySuggestion} onWillApplySuggestion={willApplySuggestion}
onValueChanged={this.onChangeQuery} onQueryChange={this.onChangeQuery}
onExecuteQuery={this.props.onExecuteQuery}
placeholder="Enter a Loki query" placeholder="Enter a Loki query"
portalOrigin="loki" portalOrigin="loki"
syntaxLoaded={syntaxLoaded} syntaxLoaded={syntaxLoaded}

View File

@@ -4,7 +4,7 @@ import Cascader from 'rc-cascader';
import PluginPrism from 'slate-prism'; import PluginPrism from 'slate-prism';
import Prism from 'prismjs'; import Prism from 'prismjs';
import { TypeaheadOutput } from 'app/types/explore'; import { TypeaheadOutput, HistoryItem } from 'app/types/explore';
// dom also includes Element polyfills // dom also includes Element polyfills
import { getNextCharacter, getPreviousCousin } from 'app/features/explore/utils/dom'; import { getNextCharacter, getPreviousCousin } from 'app/features/explore/utils/dom';
@@ -13,6 +13,7 @@ import RunnerPlugin from 'app/features/explore/slate-plugins/runner';
import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField'; import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField';
import { PromQuery } from '../types'; import { PromQuery } from '../types';
import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise'; import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
import { ExploreDataSourceApi, ExploreQueryFieldProps } from '@grafana/ui';
const HISTOGRAM_GROUP = '__histograms__'; const HISTOGRAM_GROUP = '__histograms__';
const METRIC_MARK = 'metric'; const METRIC_MARK = 'metric';
@@ -86,15 +87,8 @@ interface CascaderOption {
disabled?: boolean; disabled?: boolean;
} }
interface PromQueryFieldProps { interface PromQueryFieldProps extends ExploreQueryFieldProps<ExploreDataSourceApi, PromQuery> {
datasource: any; history: HistoryItem[];
error?: string | JSX.Element;
initialQuery: PromQuery;
hint?: any;
history?: any[];
onClickHintFix?: (action: any) => void;
onPressEnter?: () => void;
onQueryChange?: (value: PromQuery, override?: boolean) => void;
} }
interface PromQueryFieldState { interface PromQueryFieldState {
@@ -116,7 +110,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
this.plugins = [ this.plugins = [
BracesPlugin(), BracesPlugin(),
RunnerPlugin({ handler: props.onPressEnter }), RunnerPlugin({ handler: props.onExecuteQuery }),
PluginPrism({ PluginPrism({
onlyIn: node => node.type === 'code_block', onlyIn: node => node.type === 'code_block',
getSyntax: node => 'promql', getSyntax: node => 'promql',
@@ -174,21 +168,25 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
onChangeQuery = (value: string, override?: boolean) => { onChangeQuery = (value: string, override?: boolean) => {
// Send text change to parent // Send text change to parent
const { initialQuery, onQueryChange } = this.props; const { initialQuery, onQueryChange, onExecuteQuery } = this.props;
if (onQueryChange) { if (onQueryChange) {
const query: PromQuery = { const query: PromQuery = {
...initialQuery, ...initialQuery,
expr: value, expr: value,
}; };
onQueryChange(query, override); onQueryChange(query);
if (override && onExecuteQuery) {
onExecuteQuery();
}
} }
}; };
onClickHintFix = () => { onClickHintFix = () => {
const { hint, onClickHintFix } = this.props; // const { hint, onClickHintFix } = this.props;
if (onClickHintFix && hint && hint.fix) { // if (onClickHintFix && hint && hint.fix) {
onClickHintFix(hint.fix.action); // onClickHintFix(hint.fix.action);
} // }
}; };
onUpdateLanguage = () => { onUpdateLanguage = () => {
@@ -264,7 +262,8 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
initialQuery={initialQuery.expr} initialQuery={initialQuery.expr}
onTypeahead={this.onTypeahead} onTypeahead={this.onTypeahead}
onWillApplySuggestion={willApplySuggestion} onWillApplySuggestion={willApplySuggestion}
onValueChanged={this.onChangeQuery} onQueryChange={this.onChangeQuery}
onExecuteQuery={this.props.onExecuteQuery}
placeholder="Enter a PromQL query" placeholder="Enter a PromQL query"
portalOrigin="prometheus" portalOrigin="prometheus"
syntaxLoaded={syntaxLoaded} syntaxLoaded={syntaxLoaded}

View File

@@ -1,6 +1,6 @@
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import thunk from 'redux-thunk'; import thunk from 'redux-thunk';
// import { createLogger } from 'redux-logger'; import { createLogger } from 'redux-logger';
import sharedReducers from 'app/core/reducers'; import sharedReducers from 'app/core/reducers';
import alertingReducers from 'app/features/alerting/state/reducers'; import alertingReducers from 'app/features/alerting/state/reducers';
import teamsReducers from 'app/features/teams/state/reducers'; import teamsReducers from 'app/features/teams/state/reducers';
@@ -39,7 +39,7 @@ export function configureStore() {
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
// DEV builds we had the logger middleware // DEV builds we had the logger middleware
setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk)))); setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk, createLogger()))));
} else { } else {
setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk)))); setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk))));
} }