mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Make Explore plugin exports explicit
This commit is contained in:
@@ -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);
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user