diff --git a/client/app/scripts/actions/app-actions.js b/client/app/scripts/actions/app-actions.js index 514190450..881544da4 100644 --- a/client/app/scripts/actions/app-actions.js +++ b/client/app/scripts/actions/app-actions.js @@ -339,15 +339,14 @@ export function clickNode(nodeId, label, origin, topologyId = null) { export function pauseTimeAtNow() { return (dispatch, getState) => { - const getScopeState = () => getState().scope || getState(); dispatch({ type: ActionTypes.PAUSE_TIME_AT_NOW }); - updateRoute(getScopeState); - if (!getScopeState().get('nodesLoaded')) { - getNodes(getScopeState, dispatch); - if (isResourceViewModeSelector(getScopeState())) { - getResourceViewNodesSnapshot(getScopeState(), dispatch); + updateRoute(getState); + if (!getState().get('nodesLoaded')) { + getNodes(getState, dispatch); + if (isResourceViewModeSelector(getState())) { + getResourceViewNodesSnapshot(getState(), dispatch); } } }; @@ -578,17 +577,16 @@ export function receiveNodesDelta(delta) { export function resumeTime() { return (dispatch, getState) => { - const getScopeState = () => getState().scope || getState(); - if (isPausedSelector(getScopeState())) { + if (isPausedSelector(getState())) { dispatch({ type: ActionTypes.RESUME_TIME }); - updateRoute(getScopeState); + updateRoute(getState); // After unpausing, all of the following calls will re-activate polling. - getTopologies(getScopeState, dispatch); - getNodes(getScopeState, dispatch, true); - if (isResourceViewModeSelector(getScopeState())) { - getResourceViewNodesSnapshot(getScopeState(), dispatch); + getTopologies(getState, dispatch); + getNodes(getState, dispatch, true); + if (isResourceViewModeSelector(getState())) { + getResourceViewNodesSnapshot(getState(), dispatch); } } }; @@ -622,16 +620,15 @@ export function receiveNodes(nodes) { export function jumpToTime(timestamp) { return (dispatch, getState) => { - const getScopeState = () => getState().scope || getState(); dispatch({ type: ActionTypes.JUMP_TO_TIME, timestamp, }); - updateRoute(getScopeState); - getNodes(getScopeState, dispatch); - getTopologies(getScopeState, dispatch); - if (isResourceViewModeSelector(getScopeState())) { - getResourceViewNodesSnapshot(getScopeState(), dispatch); + updateRoute(getState); + getNodes(getState, dispatch); + getTopologies(getState, dispatch); + if (isResourceViewModeSelector(getState())) { + getResourceViewNodesSnapshot(getState(), dispatch); } }; } @@ -870,12 +867,6 @@ export function getImagesForService(orgId, serviceId) { }; } -export function getFluxHistory(...params) { - return (dispatch, getState, { actions }) => ( - dispatch(actions.getFluxHistory(...params)) - ); -} - export function setMonitorState(monitor) { return { type: ActionTypes.MONITOR_STATE, diff --git a/client/app/scripts/components/app.js b/client/app/scripts/components/app.js index 60a645a6b..e3c0ccf64 100644 --- a/client/app/scripts/components/app.js +++ b/client/app/scripts/components/app.js @@ -1,5 +1,6 @@ import debug from 'debug'; import React from 'react'; +import PropTypes from 'prop-types'; import classNames from 'classnames'; import { connect } from 'react-redux'; import { debounce } from 'lodash'; @@ -11,7 +12,6 @@ import Logo from './logo'; import Footer from './footer'; import Sidebar from './sidebar'; import HelpPanel from './help-panel'; -import CloudFeature from './cloud-feature'; import TroubleshootingMenu from './troubleshooting-menu'; import Search from './search'; import Status from './status'; @@ -59,7 +59,6 @@ import { const keyPressLog = debug('scope:app-key-press'); - class App extends React.Component { constructor(props, context) { super(props, context); @@ -205,11 +204,7 @@ class App extends React.Component { {showingDetails &&
}
- {timeTravelSupported && ( - - - - )} + {timeTravelSupported && this.props.renderTimeTravel()}
@@ -266,8 +261,14 @@ function mapStateToProps(state) { }; } +App.propTypes = { + renderTimeTravel: PropTypes.func, + monitor: PropTypes.bool, +}; + App.defaultProps = { - monitor: false + renderTimeTravel: () => , + monitor: false, }; export default connect(mapStateToProps)(App); diff --git a/client/app/scripts/components/time-travel-wrapper.js b/client/app/scripts/components/time-travel-wrapper.js index 44737d837..bacc058e5 100644 --- a/client/app/scripts/components/time-travel-wrapper.js +++ b/client/app/scripts/components/time-travel-wrapper.js @@ -1,72 +1,10 @@ import React from 'react'; -import moment from 'moment'; import { connect } from 'react-redux'; import { TimeTravel } from 'weaveworks-ui-components'; -import { get, orderBy, debounce } from 'lodash'; -import { trackAnalyticsEvent } from '../utils/tracking-utils'; -import { jumpToTime, resumeTime, pauseTimeAtNow, getFluxHistory } from '../actions/app-actions'; - -// Load deployments in timeline only on zoom levels up to this range. -const MAX_DEPLOYMENTS_RANGE_SECS = moment.duration(2, 'weeks').asSeconds(); - -// Reused from Service UI. -const FLUX_ALL_SERVICES = ''; +import { jumpToTime, resumeTime, pauseTimeAtNow } from '../actions/app-actions'; class TimeTravelWrapper extends React.Component { - constructor(props) { - super(props); - - this.state = { - isLoadingDeployments: false, - visibleRangeStartAtSec: null, - visibleRangeEndAtSec: null, - }; - - this.debouncedUpdateVisibleRange = debounce(this.updateVisibleRange, 500); - } - - trackTimestampEdit = () => { - trackAnalyticsEvent('scope.time.timestamp.edit', { - layout: this.props.topologyViewMode, - topologyId: this.props.currentTopology.get('id'), - parentTopologyId: this.props.currentTopology.get('parentId'), - }); - } - - trackTimelinePanButtonClick = () => { - trackAnalyticsEvent('scope.time.timeline.pan.button.click', { - layout: this.props.topologyViewMode, - topologyId: this.props.currentTopology.get('id'), - parentTopologyId: this.props.currentTopology.get('parentId'), - }); - } - - trackTimelineLabelClick = () => { - trackAnalyticsEvent('scope.time.timeline.label.click', { - layout: this.props.topologyViewMode, - topologyId: this.props.currentTopology.get('id'), - parentTopologyId: this.props.currentTopology.get('parentId'), - }); - } - - trackTimelinePan = () => { - trackAnalyticsEvent('scope.time.timeline.pan', { - layout: this.props.topologyViewMode, - topologyId: this.props.currentTopology.get('id'), - parentTopologyId: this.props.currentTopology.get('parentId'), - }); - } - - trackTimelineZoom = (zoomedPeriod) => { - trackAnalyticsEvent('scope.time.timeline.zoom', { - layout: this.props.topologyViewMode, - topologyId: this.props.currentTopology.get('id'), - parentTopologyId: this.props.currentTopology.get('parentId'), - zoomedPeriod, - }); - } - handleLiveModeChange = (showingLive) => { if (showingLive) { this.props.resumeTime(); @@ -75,96 +13,29 @@ class TimeTravelWrapper extends React.Component { } } - - updateVisibleRange = ({ startAt, endAt }) => { - const { orgId } = this.props.params; - - const visibleRangeEndAtSec = moment(endAt).unix(); - const visibleRangeStartAtSec = moment(startAt).unix(); - this.setState({ visibleRangeStartAtSec, visibleRangeEndAtSec }); - - // Load deployment annotations only if not zoomed out too much. - // See https://github.com/weaveworks/service-ui/issues/1858. - const visibleRangeSec = visibleRangeEndAtSec - visibleRangeStartAtSec; - if (visibleRangeSec < MAX_DEPLOYMENTS_RANGE_SECS) { - this.setState({ isLoadingDeployments: true }); - this.props - .getFluxHistory(orgId, FLUX_ALL_SERVICES, null, endAt, true, startAt) - .then(() => { - this.setState({ isLoadingDeployments: false }); - }); - } - } - render() { - const { - visibleRangeStartAtSec, - visibleRangeEndAtSec, - } = this.state; - - // Don't pass any deployments that are outside of the timeline visible range. - const visibleDeployments = this.props.deployments.filter((deployment) => { - const deploymentAtSec = moment(deployment.Stamp).unix(); - return ( - visibleRangeStartAtSec <= deploymentAtSec && - deploymentAtSec <= visibleRangeEndAtSec - ); - }); - return ( -
- -
+ ); } } -function mapStateToProps(state, { params }) { - const orgId = params && params.orgId; - let firstSeenConnectedAt; - - // If we're in the Weave Cloud context, use firstSeeConnectedAt as the earliest timestamp. - if (state.root && state.root.instances) { - const serviceInstance = state.root.instances[orgId]; - if (serviceInstance && serviceInstance.firstSeenConnectedAt) { - firstSeenConnectedAt = moment(serviceInstance.firstSeenConnectedAt).utc().format(); - } - } - - const unsortedDeployments = get( - state, - ['root', 'fluxInstanceHistory', orgId, FLUX_ALL_SERVICES], - [] - ); - +function mapStateToProps(state) { return { - showingLive: !state.scope.get('pausedAt'), - topologyViewMode: state.scope.get('topologyViewMode'), - currentTopology: state.scope.get('currentTopology'), - deployments: orderBy(unsortedDeployments, ['Stamp'], ['desc']), - earliestTimestamp: firstSeenConnectedAt, - timestamp: state.scope.get('pausedAt'), + showingLive: !state.get('pausedAt'), + timestamp: state.get('pausedAt'), }; } export default connect( mapStateToProps, { - jumpToTime, resumeTime, pauseTimeAtNow, getFluxHistory + jumpToTime, resumeTime, pauseTimeAtNow }, )(TimeTravelWrapper);