Commit 1e6d50df by Hugo Häggmark

Made ExplorerToolbar connected and refactored away responsabilities from Explore

parent 21df0c90
......@@ -9,7 +9,6 @@ import { AutoSizer } from 'react-virtualized';
import store from 'app/core/store';
// Components
import { DataSourceSelectItem } from '@grafana/ui/src/types';
import { Alert } from './Error';
import ErrorBoundary from './ErrorBoundary';
import GraphContainer from './GraphContainer';
......@@ -20,18 +19,13 @@ import TimePicker, { parseTime } from './TimePicker';
// Actions
import {
changeDatasource,
changeSize,
changeTime,
clearQueries,
initializeExplore,
modifyQueries,
runQueries,
scanStart,
scanStop,
setQueries,
splitClose,
splitOpen,
} from './state/actions';
// Types
......@@ -44,24 +38,19 @@ import { ExploreToolbar } from './ExploreToolbar';
interface ExploreProps {
StartPage?: any;
changeDatasource: typeof changeDatasource;
changeSize: typeof changeSize;
changeTime: typeof changeTime;
clearQueries: typeof clearQueries;
datasourceError: string;
datasourceInstance: any;
datasourceLoading: boolean | null;
datasourceMissing: boolean;
exploreDatasources: DataSourceSelectItem[];
exploreId: ExploreId;
initialDatasource?: string;
initialQueries: DataQuery[];
initializeExplore: typeof initializeExplore;
initialized: boolean;
loading: boolean;
modifyQueries: typeof modifyQueries;
range: RawTimeRange;
runQueries: typeof runQueries;
scanner?: RangeScanner;
scanning?: boolean;
scanRange?: RawTimeRange;
......@@ -69,8 +58,6 @@ interface ExploreProps {
scanStop: typeof scanStop;
setQueries: typeof setQueries;
split: boolean;
splitClose: typeof splitClose;
splitOpen: typeof splitOpen;
showingStartPage?: boolean;
supportsGraph: boolean | null;
supportsLogs: boolean | null;
......@@ -145,10 +132,6 @@ export class Explore extends React.PureComponent<ExploreProps> {
this.el = el;
};
onChangeDatasource = async option => {
this.props.changeDatasource(this.props.exploreId, option.value);
};
onChangeTime = (range: TimeRange, changedByScanner?: boolean) => {
if (this.props.scanning && !changedByScanner) {
this.onStopScanning();
......@@ -156,23 +139,11 @@ export class Explore extends React.PureComponent<ExploreProps> {
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
onClickExample = (query: DataQuery) => {
this.props.setQueries(this.props.exploreId, [query]);
};
onClickSplit = () => {
this.props.splitOpen();
};
onClickLabel = (key: string, value: string) => {
this.onModifyQueries({ type: 'ADD_FILTER', key, value });
};
......@@ -204,10 +175,6 @@ export class Explore extends React.PureComponent<ExploreProps> {
this.props.scanStop(this.props.exploreId);
};
onSubmit = () => {
this.props.runQueries(this.props.exploreId);
};
render() {
const {
StartPage,
......@@ -215,11 +182,8 @@ export class Explore extends React.PureComponent<ExploreProps> {
datasourceError,
datasourceLoading,
datasourceMissing,
exploreDatasources,
exploreId,
loading,
initialQueries,
range,
showingStartPage,
split,
supportsGraph,
......@@ -227,30 +191,10 @@ export class Explore extends React.PureComponent<ExploreProps> {
supportsTable,
} = this.props;
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 (
<div className={exploreClass} ref={this.getRef}>
<ExploreToolbar
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}
/>
<ExploreToolbar exploreId={exploreId} timepickerRef={this.timepickerRef} onChangeTime={this.onChangeTime} />
{datasourceLoading ? <div className="explore-container">Loading datasource...</div> : null}
{datasourceMissing ? (
<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,
datasourceLoading,
datasourceMissing,
exploreDatasources,
initialDatasource,
initialQueries,
initialized,
queryTransactions,
range,
showingStartPage,
supportsGraph,
supportsLogs,
supportsTable,
} = item;
const loading = queryTransactions.some(qt => !qt.done);
return {
StartPage,
datasourceError,
datasourceInstance,
datasourceLoading,
datasourceMissing,
exploreDatasources,
initialDatasource,
initialQueries,
initialized,
loading,
queryTransactions,
range,
showingStartPage,
split,
......@@ -341,18 +279,13 @@ function mapStateToProps(state: StoreState, { exploreId }) {
}
const mapDispatchToProps = {
changeDatasource,
changeSize,
changeTime,
clearQueries,
initializeExplore,
modifyQueries,
runQueries,
scanStart,
scanStop,
setQueries,
splitClose,
splitOpen,
};
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(Explore));
import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import { hot } from 'react-hot-loader';
import { ExploreId } from 'app/types/explore';
import { DataSourceSelectItem, RawTimeRange, TimeRange } from '@grafana/ui';
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: {
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;
exploreDatasources: DataSourceSelectItem[];
exploreId: ExploreId;
loading: boolean;
range: RawTimeRange;
selectedDatasource: DataSourceSelectItem;
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) {
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() {
const {
datasourceMissing,
exploreDatasources,
exploreId,
loading,
range,
selectedDatasource,
splitted,
timepicker,
timepickerRef,
} = this.props;
return (
......@@ -67,7 +94,7 @@ export class ExploreToolbar extends PureComponent<Props, {}> {
</div>
<div className="toolbar-header-close">
{exploreId === 'right' && (
<a onClick={this.props.onCloseSplit}>
<a onClick={this.props.closeSplit}>
<i className="fa fa-window-close fa-fw" />
</a>
)}
......@@ -80,7 +107,7 @@ export class ExploreToolbar extends PureComponent<Props, {}> {
<div className="toolbar-content-item">
<div className="datasource-picker">
<DataSourcePicker
onChange={this.props.onChangeDatasource}
onChange={this.onChangeDatasource}
datasources={exploreDatasources}
current={selectedDatasource}
/>
......@@ -92,14 +119,16 @@ export class ExploreToolbar extends PureComponent<Props, {}> {
{createResponsiveButton({
splitted,
title: 'Split',
onClick: this.props.onSplit,
onClick: this.props.split,
iconClassName: 'fa fa-fw fa-columns',
})}
</div>
) : 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">
<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
</button>
</div>
......@@ -107,7 +136,7 @@ export class ExploreToolbar extends PureComponent<Props, {}> {
{createResponsiveButton({
splitted,
title: 'Run Query',
onClick: this.props.onRunQuery,
onClick: this.onRunQuery,
buttonClassName: 'navbar-button--primary',
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));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment