diff --git a/ui/src/shared/components/EmptyRefreshingView.tsx b/ui/src/shared/components/EmptyRefreshingView.tsx index 28dd73e330..078a1c7890 100644 --- a/ui/src/shared/components/EmptyRefreshingView.tsx +++ b/ui/src/shared/components/EmptyRefreshingView.tsx @@ -1,17 +1,32 @@ +// Libraries import React, {PureComponent} from 'react' + +// Components import EmptyGraphMessage from 'src/shared/components/EmptyGraphMessage' + +// Constants +import {emptyGraphCopy} from 'src/shared/copy/cell' + +// Types import {RemoteDataState, FluxTable} from 'src/types' +import {DashboardQuery} from 'src/types/v2' interface Props { error: Error isInitialFetch: boolean loading: RemoteDataState tables: FluxTable[] + queries: DashboardQuery[] } export default class EmptyRefreshingView extends PureComponent { public render() { - const {error, isInitialFetch, loading, tables} = this.props + const {error, isInitialFetch, loading, tables, queries} = this.props + + if (!queries.length) { + return + } + if (error) { return } diff --git a/ui/src/shared/components/RefreshingView.tsx b/ui/src/shared/components/RefreshingView.tsx index be35f55806..c4ef678abd 100644 --- a/ui/src/shared/components/RefreshingView.tsx +++ b/ui/src/shared/components/RefreshingView.tsx @@ -5,13 +5,9 @@ import _ from 'lodash' // Components import TimeSeries from 'src/shared/components/TimeSeries' -import EmptyGraphMessage from 'src/shared/components/EmptyGraphMessage' import EmptyRefreshingView from 'src/shared/components/EmptyRefreshingView' import RefreshingViewSwitcher from 'src/shared/components/RefreshingViewSwitcher' -// Constants -import {emptyGraphCopy} from 'src/shared/copy/cell' - // Utils import {getActiveSource} from 'src/sources/selectors' @@ -55,10 +51,6 @@ class RefreshingView extends PureComponent { manualRefresh, } = this.props - if (!properties.queries.length) { - return - } - return ( { tables={tables} loading={loading} isInitialFetch={isInitialFetch} + queries={this.queries} > void + onZoom?: (range: TimeRange) => void properties: RefreshingViewProperties } export default class RefreshingViewSwitcher extends PureComponent { + public static defaultProps: Partial = { + onZoom: () => {}, + } + public render() { const {properties, loading, viewID, tables, onZoom, timeRange} = this.props diff --git a/ui/src/shared/components/TimeMachine.tsx b/ui/src/shared/components/TimeMachine.tsx index c44db59586..663dff0fb8 100644 --- a/ui/src/shared/components/TimeMachine.tsx +++ b/ui/src/shared/components/TimeMachine.tsx @@ -1,56 +1,93 @@ // Libraries import React, {PureComponent} from 'react' +import {connect} from 'react-redux' +import {get} from 'lodash' // Components import TimeMachineControls from 'src/shared/components/TimeMachineControls' import Threesizer from 'src/shared/components/threesizer/Threesizer' import TimeMachineBottom from 'src/shared/components/TimeMachineBottom' import TimeMachineVis from 'src/shared/components/TimeMachineVis' +import TimeSeries from 'src/shared/components/TimeSeries' + +// Utils +import {getActiveSource} from 'src/sources/selectors' // Constants import {HANDLE_HORIZONTAL} from 'src/shared/constants' // Types import {TimeMachineTab} from 'src/types/v2/timeMachine' +import {AppState, DashboardQuery} from 'src/types/v2' -interface Props { +interface StateProps { + queryLink: string + queries: DashboardQuery[] +} + +interface OwnProps { activeTab: TimeMachineTab } +type Props = OwnProps & StateProps + class TimeMachine extends PureComponent { public render() { - const {activeTab} = this.props - - const divisions = [ - { - name: '', - handleDisplay: 'none', - headerButtons: [], - menuOptions: [], - render: () => , - headerOrientation: HANDLE_HORIZONTAL, - size: 0.33, - }, - { - name: '', - handlePixels: 8, - headerButtons: [], - menuOptions: [], - render: () => , - headerOrientation: HANDLE_HORIZONTAL, - size: 0.67, - }, - ] + const {activeTab, queryLink, queries} = this.props return (
- -
- -
+ + {queriesState => { + const divisions = [ + { + name: '', + handleDisplay: 'none', + headerButtons: [], + menuOptions: [], + render: () => , + headerOrientation: HANDLE_HORIZONTAL, + size: 0.33, + }, + { + name: '', + handlePixels: 8, + headerButtons: [], + menuOptions: [], + render: () => , + headerOrientation: HANDLE_HORIZONTAL, + size: 0.67, + }, + ] + + return ( + <> + +
+ +
+ + ) + }} +
) } } -export default TimeMachine +const mstp = (state: AppState) => { + const {activeTimeMachineID, timeMachines} = state.timeMachines + const timeMachine = timeMachines[activeTimeMachineID] + const queries = get(timeMachine, 'view.properties.queries', []) + const queryLink = getActiveSource(state).links.query + + return {queryLink, queries} +} + +export default connect( + mstp, + null +)(TimeMachine) diff --git a/ui/src/shared/components/TimeMachineVis.tsx b/ui/src/shared/components/TimeMachineVis.tsx index 77a5ee0294..b5ce1f61b6 100644 --- a/ui/src/shared/components/TimeMachineVis.tsx +++ b/ui/src/shared/components/TimeMachineVis.tsx @@ -1,46 +1,59 @@ // Libraries import React, {SFC} from 'react' import {connect} from 'react-redux' +import {get} from 'lodash' // Components -import ViewComponent from 'src/shared/components/cells/View' +import EmptyRefreshingView from 'src/shared/components/EmptyRefreshingView' +import RefreshingViewSwitcher from 'src/shared/components/RefreshingViewSwitcher' // Actions import {setType} from 'src/shared/actions/v2/timeMachines' // Types -import {AppState} from 'src/types/v2' -import {View, NewView, TimeRange} from 'src/types/v2' +import {View, NewView, TimeRange, DashboardQuery, AppState} from 'src/types/v2' +import {RefreshingViewProperties} from 'src/types/v2/dashboards' +import {QueriesState} from 'src/shared/components/TimeSeries' interface StateProps { view: View | NewView timeRange: TimeRange + queries: DashboardQuery[] } interface DispatchProps { onUpdateType: typeof setType } -interface OwnProps {} +interface OwnProps { + queriesState: QueriesState +} type Props = StateProps & DispatchProps & OwnProps const TimeMachineVis: SFC = props => { - const {view, timeRange} = props - const noop = () => {} + const {view, timeRange, queries} = props + const {tables, loading, error, isInitialFetch} = props.queriesState return (
- + + +
@@ -50,10 +63,12 @@ const TimeMachineVis: SFC = props => { const mstp = (state: AppState) => { const {activeTimeMachineID, timeMachines} = state.timeMachines const timeMachine = timeMachines[activeTimeMachineID] + const queries = get(timeMachine, 'view.properties.queries', []) return { view: timeMachine.view, timeRange: timeMachine.timeRange, + queries, } } diff --git a/ui/src/shared/components/TimeSeries.tsx b/ui/src/shared/components/TimeSeries.tsx index 18a0c11c3d..d43393d263 100644 --- a/ui/src/shared/components/TimeSeries.tsx +++ b/ui/src/shared/components/TimeSeries.tsx @@ -16,7 +16,7 @@ import {restartable, CancellationError} from 'src/utils/restartable' export const DEFAULT_TIME_SERIES = [{response: {results: []}}] -interface RenderProps { +export interface QueriesState { tables: FluxTable[] loading: RemoteDataState error: Error | null @@ -27,7 +27,7 @@ interface Props { link: string queries: DashboardQuery[] inView?: boolean - children: (r: RenderProps) => JSX.Element + children: (r: QueriesState) => JSX.Element } interface State { @@ -37,24 +37,22 @@ interface State { fetchCount: number } +const defaultState = (): State => ({ + loading: RemoteDataState.NotStarted, + tables: [], + fetchCount: 0, + error: null, +}) + class TimeSeries extends Component { public static defaultProps = { inView: true, } + public state: State = defaultState() + private executeQueries = restartable(executeQueries) - constructor(props: Props) { - super(props) - - this.state = { - loading: RemoteDataState.NotStarted, - tables: [], - fetchCount: 0, - error: null, - } - } - public async componentDidMount() { this.reload() @@ -89,6 +87,12 @@ class TimeSeries extends Component { return } + if (!queries.length) { + this.setState(defaultState()) + + return + } + this.setState({ loading: RemoteDataState.Loading, fetchCount: this.state.fetchCount + 1,