mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Made ExplorerToolbar connected and refactored away responsabilities from Explore
This commit is contained in:
parent
21df0c90a9
commit
1e6d50df7a
@ -9,7 +9,6 @@ import { AutoSizer } from 'react-virtualized';
|
|||||||
import store from 'app/core/store';
|
import store from 'app/core/store';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { DataSourceSelectItem } from '@grafana/ui/src/types';
|
|
||||||
import { Alert } from './Error';
|
import { Alert } from './Error';
|
||||||
import ErrorBoundary from './ErrorBoundary';
|
import ErrorBoundary from './ErrorBoundary';
|
||||||
import GraphContainer from './GraphContainer';
|
import GraphContainer from './GraphContainer';
|
||||||
@ -20,18 +19,13 @@ import TimePicker, { parseTime } from './TimePicker';
|
|||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {
|
import {
|
||||||
changeDatasource,
|
|
||||||
changeSize,
|
changeSize,
|
||||||
changeTime,
|
changeTime,
|
||||||
clearQueries,
|
|
||||||
initializeExplore,
|
initializeExplore,
|
||||||
modifyQueries,
|
modifyQueries,
|
||||||
runQueries,
|
|
||||||
scanStart,
|
scanStart,
|
||||||
scanStop,
|
scanStop,
|
||||||
setQueries,
|
setQueries,
|
||||||
splitClose,
|
|
||||||
splitOpen,
|
|
||||||
} from './state/actions';
|
} from './state/actions';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
@ -44,24 +38,19 @@ import { ExploreToolbar } from './ExploreToolbar';
|
|||||||
|
|
||||||
interface ExploreProps {
|
interface ExploreProps {
|
||||||
StartPage?: any;
|
StartPage?: any;
|
||||||
changeDatasource: typeof changeDatasource;
|
|
||||||
changeSize: typeof changeSize;
|
changeSize: typeof changeSize;
|
||||||
changeTime: typeof changeTime;
|
changeTime: typeof changeTime;
|
||||||
clearQueries: typeof clearQueries;
|
|
||||||
datasourceError: string;
|
datasourceError: string;
|
||||||
datasourceInstance: any;
|
datasourceInstance: any;
|
||||||
datasourceLoading: boolean | null;
|
datasourceLoading: boolean | null;
|
||||||
datasourceMissing: boolean;
|
datasourceMissing: boolean;
|
||||||
exploreDatasources: DataSourceSelectItem[];
|
|
||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
initialDatasource?: string;
|
initialDatasource?: string;
|
||||||
initialQueries: DataQuery[];
|
initialQueries: DataQuery[];
|
||||||
initializeExplore: typeof initializeExplore;
|
initializeExplore: typeof initializeExplore;
|
||||||
initialized: boolean;
|
initialized: boolean;
|
||||||
loading: boolean;
|
|
||||||
modifyQueries: typeof modifyQueries;
|
modifyQueries: typeof modifyQueries;
|
||||||
range: RawTimeRange;
|
range: RawTimeRange;
|
||||||
runQueries: typeof runQueries;
|
|
||||||
scanner?: RangeScanner;
|
scanner?: RangeScanner;
|
||||||
scanning?: boolean;
|
scanning?: boolean;
|
||||||
scanRange?: RawTimeRange;
|
scanRange?: RawTimeRange;
|
||||||
@ -69,8 +58,6 @@ interface ExploreProps {
|
|||||||
scanStop: typeof scanStop;
|
scanStop: typeof scanStop;
|
||||||
setQueries: typeof setQueries;
|
setQueries: typeof setQueries;
|
||||||
split: boolean;
|
split: boolean;
|
||||||
splitClose: typeof splitClose;
|
|
||||||
splitOpen: typeof splitOpen;
|
|
||||||
showingStartPage?: boolean;
|
showingStartPage?: boolean;
|
||||||
supportsGraph: boolean | null;
|
supportsGraph: boolean | null;
|
||||||
supportsLogs: boolean | null;
|
supportsLogs: boolean | null;
|
||||||
@ -145,10 +132,6 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
this.el = el;
|
this.el = el;
|
||||||
};
|
};
|
||||||
|
|
||||||
onChangeDatasource = async option => {
|
|
||||||
this.props.changeDatasource(this.props.exploreId, option.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
onChangeTime = (range: TimeRange, changedByScanner?: boolean) => {
|
onChangeTime = (range: TimeRange, changedByScanner?: boolean) => {
|
||||||
if (this.props.scanning && !changedByScanner) {
|
if (this.props.scanning && !changedByScanner) {
|
||||||
this.onStopScanning();
|
this.onStopScanning();
|
||||||
@ -156,23 +139,11 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
this.props.changeTime(this.props.exploreId, range);
|
this.props.changeTime(this.props.exploreId, range);
|
||||||
};
|
};
|
||||||
|
|
||||||
onClickClear = () => {
|
|
||||||
this.props.clearQueries(this.props.exploreId);
|
|
||||||
};
|
|
||||||
|
|
||||||
onClickCloseSplit = () => {
|
|
||||||
this.props.splitClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use this in help pages to set page to a single query
|
// Use this in help pages to set page to a single query
|
||||||
onClickExample = (query: DataQuery) => {
|
onClickExample = (query: DataQuery) => {
|
||||||
this.props.setQueries(this.props.exploreId, [query]);
|
this.props.setQueries(this.props.exploreId, [query]);
|
||||||
};
|
};
|
||||||
|
|
||||||
onClickSplit = () => {
|
|
||||||
this.props.splitOpen();
|
|
||||||
};
|
|
||||||
|
|
||||||
onClickLabel = (key: string, value: string) => {
|
onClickLabel = (key: string, value: string) => {
|
||||||
this.onModifyQueries({ type: 'ADD_FILTER', key, value });
|
this.onModifyQueries({ type: 'ADD_FILTER', key, value });
|
||||||
};
|
};
|
||||||
@ -204,10 +175,6 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
this.props.scanStop(this.props.exploreId);
|
this.props.scanStop(this.props.exploreId);
|
||||||
};
|
};
|
||||||
|
|
||||||
onSubmit = () => {
|
|
||||||
this.props.runQueries(this.props.exploreId);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
StartPage,
|
StartPage,
|
||||||
@ -215,11 +182,8 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
datasourceError,
|
datasourceError,
|
||||||
datasourceLoading,
|
datasourceLoading,
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
exploreDatasources,
|
|
||||||
exploreId,
|
exploreId,
|
||||||
loading,
|
|
||||||
initialQueries,
|
initialQueries,
|
||||||
range,
|
|
||||||
showingStartPage,
|
showingStartPage,
|
||||||
split,
|
split,
|
||||||
supportsGraph,
|
supportsGraph,
|
||||||
@ -227,30 +191,10 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
supportsTable,
|
supportsTable,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const exploreClass = split ? 'explore explore-split' : 'explore';
|
const exploreClass = split ? 'explore explore-split' : 'explore';
|
||||||
const selectedDatasource = datasourceInstance
|
|
||||||
? exploreDatasources.find(d => d.name === datasourceInstance.name)
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const timepicker = <TimePicker ref={this.timepickerRef} range={range} onChangeTime={this.onChangeTime} />;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={exploreClass} ref={this.getRef}>
|
<div className={exploreClass} ref={this.getRef}>
|
||||||
<ExploreToolbar
|
<ExploreToolbar exploreId={exploreId} timepickerRef={this.timepickerRef} onChangeTime={this.onChangeTime} />
|
||||||
datasourceMissing={datasourceMissing}
|
|
||||||
exploreDatasources={exploreDatasources}
|
|
||||||
exploreId={exploreId}
|
|
||||||
loading={loading}
|
|
||||||
range={range}
|
|
||||||
selectedDatasource={selectedDatasource}
|
|
||||||
splitted={split}
|
|
||||||
timepicker={timepicker}
|
|
||||||
onChangeDatasource={this.onChangeDatasource}
|
|
||||||
onClearAll={this.onClickClear}
|
|
||||||
onCloseSplit={this.onClickCloseSplit}
|
|
||||||
onChangeTime={this.onChangeTime}
|
|
||||||
onRunQuery={this.onSubmit}
|
|
||||||
onSplit={this.onClickSplit}
|
|
||||||
/>
|
|
||||||
{datasourceLoading ? <div className="explore-container">Loading datasource...</div> : null}
|
{datasourceLoading ? <div className="explore-container">Loading datasource...</div> : null}
|
||||||
{datasourceMissing ? (
|
{datasourceMissing ? (
|
||||||
<div className="explore-container">Please add a datasource that supports Explore (e.g., Prometheus).</div>
|
<div className="explore-container">Please add a datasource that supports Explore (e.g., Prometheus).</div>
|
||||||
@ -307,30 +251,24 @@ function mapStateToProps(state: StoreState, { exploreId }) {
|
|||||||
datasourceInstance,
|
datasourceInstance,
|
||||||
datasourceLoading,
|
datasourceLoading,
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
exploreDatasources,
|
|
||||||
initialDatasource,
|
initialDatasource,
|
||||||
initialQueries,
|
initialQueries,
|
||||||
initialized,
|
initialized,
|
||||||
queryTransactions,
|
|
||||||
range,
|
range,
|
||||||
showingStartPage,
|
showingStartPage,
|
||||||
supportsGraph,
|
supportsGraph,
|
||||||
supportsLogs,
|
supportsLogs,
|
||||||
supportsTable,
|
supportsTable,
|
||||||
} = item;
|
} = item;
|
||||||
const loading = queryTransactions.some(qt => !qt.done);
|
|
||||||
return {
|
return {
|
||||||
StartPage,
|
StartPage,
|
||||||
datasourceError,
|
datasourceError,
|
||||||
datasourceInstance,
|
datasourceInstance,
|
||||||
datasourceLoading,
|
datasourceLoading,
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
exploreDatasources,
|
|
||||||
initialDatasource,
|
initialDatasource,
|
||||||
initialQueries,
|
initialQueries,
|
||||||
initialized,
|
initialized,
|
||||||
loading,
|
|
||||||
queryTransactions,
|
|
||||||
range,
|
range,
|
||||||
showingStartPage,
|
showingStartPage,
|
||||||
split,
|
split,
|
||||||
@ -341,18 +279,13 @@ function mapStateToProps(state: StoreState, { exploreId }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
changeDatasource,
|
|
||||||
changeSize,
|
changeSize,
|
||||||
changeTime,
|
changeTime,
|
||||||
clearQueries,
|
|
||||||
initializeExplore,
|
initializeExplore,
|
||||||
modifyQueries,
|
modifyQueries,
|
||||||
runQueries,
|
|
||||||
scanStart,
|
scanStart,
|
||||||
scanStop,
|
scanStop,
|
||||||
setQueries,
|
setQueries,
|
||||||
splitClose,
|
|
||||||
splitOpen,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(Explore));
|
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(Explore));
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { hot } from 'react-hot-loader';
|
||||||
|
|
||||||
import { ExploreId } from 'app/types/explore';
|
import { ExploreId } from 'app/types/explore';
|
||||||
import { DataSourceSelectItem, RawTimeRange, TimeRange } from '@grafana/ui';
|
import { DataSourceSelectItem, RawTimeRange, TimeRange } from '@grafana/ui';
|
||||||
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
|
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
|
||||||
|
import { StoreState } from 'app/types/store';
|
||||||
|
import { changeDatasource, clearQueries, splitClose, runQueries, splitOpen } from './state/actions';
|
||||||
|
import TimePicker from './TimePicker';
|
||||||
|
|
||||||
const createResponsiveButton = (options: {
|
const createResponsiveButton = (options: {
|
||||||
splitted: boolean;
|
splitted: boolean;
|
||||||
@ -20,37 +26,58 @@ const createResponsiveButton = (options: {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Props {
|
interface OwnProps {
|
||||||
|
exploreId: ExploreId;
|
||||||
|
timepickerRef: React.RefObject<TimePicker>;
|
||||||
|
onChangeTime: (range: TimeRange, changedByScanner?: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StateProps {
|
||||||
datasourceMissing: boolean;
|
datasourceMissing: boolean;
|
||||||
exploreDatasources: DataSourceSelectItem[];
|
exploreDatasources: DataSourceSelectItem[];
|
||||||
exploreId: ExploreId;
|
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
range: RawTimeRange;
|
range: RawTimeRange;
|
||||||
selectedDatasource: DataSourceSelectItem;
|
selectedDatasource: DataSourceSelectItem;
|
||||||
splitted: boolean;
|
splitted: boolean;
|
||||||
timepicker: JSX.Element;
|
|
||||||
onChangeDatasource: (option) => void;
|
|
||||||
onClearAll: () => void;
|
|
||||||
onCloseSplit: () => void;
|
|
||||||
onChangeTime: (range: TimeRange, changedByScanner?: boolean) => void;
|
|
||||||
onRunQuery: () => void;
|
|
||||||
onSplit: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ExploreToolbar extends PureComponent<Props, {}> {
|
interface DispatchProps {
|
||||||
|
changeDatasource: typeof changeDatasource;
|
||||||
|
clearAll: typeof clearQueries;
|
||||||
|
runQuery: typeof runQueries;
|
||||||
|
closeSplit: typeof splitClose;
|
||||||
|
split: typeof splitOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = StateProps & DispatchProps & OwnProps;
|
||||||
|
|
||||||
|
export class UnConnectedExploreToolbar extends PureComponent<Props, {}> {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onChangeDatasource = async option => {
|
||||||
|
this.props.changeDatasource(this.props.exploreId, option.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
onClearAll = () => {
|
||||||
|
this.props.clearAll(this.props.exploreId);
|
||||||
|
};
|
||||||
|
|
||||||
|
onRunQuery = () => {
|
||||||
|
this.props.runQuery(this.props.exploreId);
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
exploreDatasources,
|
exploreDatasources,
|
||||||
exploreId,
|
exploreId,
|
||||||
loading,
|
loading,
|
||||||
|
range,
|
||||||
selectedDatasource,
|
selectedDatasource,
|
||||||
splitted,
|
splitted,
|
||||||
timepicker,
|
timepickerRef,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -67,7 +94,7 @@ export class ExploreToolbar extends PureComponent<Props, {}> {
|
|||||||
</div>
|
</div>
|
||||||
<div className="toolbar-header-close">
|
<div className="toolbar-header-close">
|
||||||
{exploreId === 'right' && (
|
{exploreId === 'right' && (
|
||||||
<a onClick={this.props.onCloseSplit}>
|
<a onClick={this.props.closeSplit}>
|
||||||
<i className="fa fa-window-close fa-fw" />
|
<i className="fa fa-window-close fa-fw" />
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
@ -80,7 +107,7 @@ export class ExploreToolbar extends PureComponent<Props, {}> {
|
|||||||
<div className="toolbar-content-item">
|
<div className="toolbar-content-item">
|
||||||
<div className="datasource-picker">
|
<div className="datasource-picker">
|
||||||
<DataSourcePicker
|
<DataSourcePicker
|
||||||
onChange={this.props.onChangeDatasource}
|
onChange={this.onChangeDatasource}
|
||||||
datasources={exploreDatasources}
|
datasources={exploreDatasources}
|
||||||
current={selectedDatasource}
|
current={selectedDatasource}
|
||||||
/>
|
/>
|
||||||
@ -92,14 +119,16 @@ export class ExploreToolbar extends PureComponent<Props, {}> {
|
|||||||
{createResponsiveButton({
|
{createResponsiveButton({
|
||||||
splitted,
|
splitted,
|
||||||
title: 'Split',
|
title: 'Split',
|
||||||
onClick: this.props.onSplit,
|
onClick: this.props.split,
|
||||||
iconClassName: 'fa fa-fw fa-columns',
|
iconClassName: 'fa fa-fw fa-columns',
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="toolbar-content-item timepicker">{timepicker}</div>
|
<div className="toolbar-content-item timepicker">
|
||||||
|
<TimePicker ref={timepickerRef} range={range} onChangeTime={this.props.onChangeTime} />
|
||||||
|
</div>
|
||||||
<div className="toolbar-content-item">
|
<div className="toolbar-content-item">
|
||||||
<button className="btn navbar-button navbar-button--no-icon" onClick={this.props.onClearAll}>
|
<button className="btn navbar-button navbar-button--no-icon" onClick={this.onClearAll}>
|
||||||
Clear All
|
Clear All
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -107,7 +136,7 @@ export class ExploreToolbar extends PureComponent<Props, {}> {
|
|||||||
{createResponsiveButton({
|
{createResponsiveButton({
|
||||||
splitted,
|
splitted,
|
||||||
title: 'Run Query',
|
title: 'Run Query',
|
||||||
onClick: this.props.onRunQuery,
|
onClick: this.onRunQuery,
|
||||||
buttonClassName: 'navbar-button--primary',
|
buttonClassName: 'navbar-button--primary',
|
||||||
iconClassName: loading ? 'fa fa-spinner fa-fw fa-spin run-icon' : 'fa fa-level-down fa-fw run-icon',
|
iconClassName: loading ? 'fa fa-spinner fa-fw fa-spin run-icon' : 'fa fa-level-down fa-fw run-icon',
|
||||||
})}
|
})}
|
||||||
@ -118,3 +147,32 @@ export class ExploreToolbar extends PureComponent<Props, {}> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state: StoreState, { exploreId }: OwnProps): StateProps => {
|
||||||
|
const splitted = state.explore.split;
|
||||||
|
const exploreItem = state.explore[exploreId];
|
||||||
|
const { datasourceInstance, datasourceMissing, exploreDatasources, queryTransactions, range } = exploreItem;
|
||||||
|
const selectedDatasource = datasourceInstance
|
||||||
|
? exploreDatasources.find(datasource => datasource.name === datasourceInstance.name)
|
||||||
|
: undefined;
|
||||||
|
const loading = queryTransactions.some(qt => !qt.done);
|
||||||
|
|
||||||
|
return {
|
||||||
|
datasourceMissing,
|
||||||
|
exploreDatasources,
|
||||||
|
loading,
|
||||||
|
range,
|
||||||
|
selectedDatasource,
|
||||||
|
splitted,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps: DispatchProps = {
|
||||||
|
changeDatasource,
|
||||||
|
clearAll: clearQueries,
|
||||||
|
runQuery: runQueries,
|
||||||
|
closeSplit: splitClose,
|
||||||
|
split: splitOpen,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ExploreToolbar = hot(module)(connect(mapStateToProps, mapDispatchToProps)(UnConnectedExploreToolbar));
|
||||||
|
Loading…
Reference in New Issue
Block a user