@@ -244,11 +247,11 @@ function mapStateToProps(state) {
searchQuery: state.get('searchQuery'),
showingDetails: state.get('nodeDetails').size > 0,
showingHelp: state.get('showingHelp'),
- showingTimeTravel: state.get('showingTimeTravel'),
showingTroubleshootingMenu: state.get('showingTroubleshootingMenu'),
showingNetworkSelector: availableNetworksSelector(state).count() > 0,
showingTerminal: state.get('controlPipes').size > 0,
topologyViewMode: state.get('topologyViewMode'),
+ timeTravelSupported: timeTravelSupportedSelector(state),
timeTravelTransitioning: state.get('timeTravelTransitioning'),
urlState: getUrlState(state)
};
diff --git a/client/app/scripts/components/nodes.js b/client/app/scripts/components/nodes.js
index e5933858c..88e9f8db6 100644
--- a/client/app/scripts/components/nodes.js
+++ b/client/app/scripts/components/nodes.js
@@ -86,7 +86,6 @@ function mapStateToProps(state) {
topologyNodeCountZero: isTopologyNodeCountZero(state),
nodesDisplayEmpty: isNodesDisplayEmpty(state),
nodesLoaded: nodesLoadedSelector(state),
- timeTravelTransitioning: state.get('timeTravelTransitioning'),
currentTopology: state.get('currentTopology'),
topologies: state.get('topologies'),
topologiesLoaded: state.get('topologiesLoaded'),
diff --git a/client/app/scripts/components/time-control.js b/client/app/scripts/components/time-control.js
index f835701b8..96a83b653 100644
--- a/client/app/scripts/components/time-control.js
+++ b/client/app/scripts/components/time-control.js
@@ -4,7 +4,8 @@ import classNames from 'classnames';
import { connect } from 'react-redux';
import { trackAnalyticsEvent } from '../utils/tracking-utils';
-import { pauseTimeAtNow, resumeTime, startTimeTravel } from '../actions/app-actions';
+import { pauseTimeAtNow, resumeTime } from '../actions/app-actions';
+import { isPausedSelector, timeTravelSupportedSelector } from '../selectors/time-travel';
const className = isSelected => (
@@ -17,7 +18,6 @@ class TimeControl extends React.Component {
this.handleNowClick = this.handleNowClick.bind(this);
this.handlePauseClick = this.handlePauseClick.bind(this);
- this.handleTravelClick = this.handleTravelClick.bind(this);
this.getTrackingMetadata = this.getTrackingMetadata.bind(this);
}
@@ -50,71 +50,44 @@ class TimeControl extends React.Component {
this.props.pauseTimeAtNow();
}
- handleTravelClick() {
- if (!this.props.showingTimeTravel) {
- trackAnalyticsEvent('scope.time.travel.click', this.getTrackingMetadata({ open: true }));
- this.props.startTimeTravel();
- } else {
- trackAnalyticsEvent('scope.time.travel.click', this.getTrackingMetadata({ open: false }));
- this.props.resumeTime();
- }
- }
-
render() {
- const {
- showingTimeTravel, pausedAt, timeTravelTransitioning, topologiesLoaded,
- hasHistoricReports
- } = this.props;
+ const { isPaused, pausedAt, topologiesLoaded } = this.props;
- const isPausedNow = pausedAt && !showingTimeTravel;
- const isTimeTravelling = showingTimeTravel;
- const isRunningNow = !pausedAt;
-
- if (!topologiesLoaded) return null;
+ // If Time Travel is supported, show an empty placeholder div instead
+ // of this control, since time will be controlled through the timeline.
+ // We return
instead of null so that selector controls would
+ // be aligned the same way between WC Explore and Scope standalone.
+ if (this.props.timeTravelSupported) return
;
return (
-
- {timeTravelTransitioning && }
-
- {isRunningNow && }
+ {!isPaused && }
Live
- {isPausedNow && }
- {isPausedNow ? 'Paused' : 'Pause'}
+ {isPaused && }
+ {isPaused ? 'Paused' : 'Pause'}
- {hasHistoricReports &&
-
- {isTimeTravelling && }
- Time Travel
-
- }
- {(isPausedNow || isTimeTravelling) &&
+ {isPaused &&
Showing state from {moment(pausedAt).fromNow()}
}
- {isRunningNow && timeTravelTransitioning &&
-
Resuming the live state
- }
);
}
@@ -122,12 +95,11 @@ class TimeControl extends React.Component {
function mapStateToProps(state) {
return {
- hasHistoricReports: state.getIn(['capabilities', 'historic_reports']),
+ isPaused: isPausedSelector(state),
+ timeTravelSupported: timeTravelSupportedSelector(state),
topologyViewMode: state.get('topologyViewMode'),
topologiesLoaded: state.get('topologiesLoaded'),
currentTopology: state.get('currentTopology'),
- showingTimeTravel: state.get('showingTimeTravel'),
- timeTravelTransitioning: state.get('timeTravelTransitioning'),
pausedAt: state.get('pausedAt'),
};
}
@@ -137,6 +109,5 @@ export default connect(
{
resumeTime,
pauseTimeAtNow,
- startTimeTravel,
}
)(TimeControl);
diff --git a/client/app/scripts/components/time-travel-wrapper.js b/client/app/scripts/components/time-travel-wrapper.js
index 5795d1dc9..f8c5e687d 100644
--- a/client/app/scripts/components/time-travel-wrapper.js
+++ b/client/app/scripts/components/time-travel-wrapper.js
@@ -1,28 +1,18 @@
import React from 'react';
import moment from 'moment';
-import styled from 'styled-components';
import { connect } from 'react-redux';
import { TimeTravel } from 'weaveworks-ui-components';
import { trackAnalyticsEvent } from '../utils/tracking-utils';
-import { jumpToTime } from '../actions/app-actions';
+import { jumpToTime, resumeTime, pauseTimeAtNow } from '../actions/app-actions';
-const TimeTravelContainer = styled.div`
- transition: all .15s ease-in-out;
- position: relative;
- overflow: hidden;
- height: 0;
-
- ${props => props.visible && `
- height: 105px;
- `}
-`;
-
class TimeTravelWrapper extends React.Component {
constructor(props, context) {
super(props, context);
+ this.handleLiveModeChange = this.handleLiveModeChange.bind(this);
+
this.trackTimestampEdit = this.trackTimestampEdit.bind(this);
this.trackTimelinePanButtonClick = this.trackTimelinePanButtonClick.bind(this);
this.trackTimelineLabelClick = this.trackTimelineLabelClick.bind(this);
@@ -71,20 +61,29 @@ class TimeTravelWrapper extends React.Component {
});
}
+ handleLiveModeChange(showingLive) {
+ if (showingLive) {
+ this.props.resumeTime();
+ } else {
+ this.props.pauseTimeAtNow();
+ }
+ }
+
render() {
return (
-
-
-
+
);
}
}
@@ -102,7 +101,7 @@ function mapStateToProps(state, { params }) {
}
return {
- visible: scopeState.get('showingTimeTravel'),
+ showingLive: !scopeState.get('pausedAt'),
topologyViewMode: scopeState.get('topologyViewMode'),
currentTopology: scopeState.get('currentTopology'),
earliestTimestamp: firstSeenConnectedAt,
@@ -112,5 +111,5 @@ function mapStateToProps(state, { params }) {
export default connect(
mapStateToProps,
- { jumpToTime },
+ { jumpToTime, resumeTime, pauseTimeAtNow },
)(TimeTravelWrapper);
diff --git a/client/app/scripts/constants/styles.js b/client/app/scripts/constants/styles.js
index 54781bacd..7d18ab11d 100644
--- a/client/app/scripts/constants/styles.js
+++ b/client/app/scripts/constants/styles.js
@@ -39,13 +39,13 @@ export const EDGE_WAYPOINTS_CAP = 10;
export const CANVAS_MARGINS = {
[GRAPH_VIEW_MODE]: {
- top: 160, left: 80, right: 80, bottom: 150
+ top: 220, left: 80, right: 80, bottom: 150
},
[TABLE_VIEW_MODE]: {
top: 220, left: 40, right: 40, bottom: 30
},
[RESOURCE_VIEW_MODE]: {
- top: 140, left: 210, right: 40, bottom: 150
+ top: 200, left: 210, right: 40, bottom: 150
},
};
diff --git a/client/app/scripts/reducers/root.js b/client/app/scripts/reducers/root.js
index 8e04ed00d..d9d346506 100644
--- a/client/app/scripts/reducers/root.js
+++ b/client/app/scripts/reducers/root.js
@@ -75,7 +75,6 @@ export const initialState = makeMap({
selectedNetwork: null,
selectedNodeId: null,
showingHelp: false,
- showingTimeTravel: false,
showingTroubleshootingMenu: false,
showingNetworks: false,
timeTravelTransitioning: false,
@@ -369,18 +368,15 @@ export function rootReducer(state = initialState, action) {
case ActionTypes.RESUME_TIME: {
state = state.set('timeTravelTransitioning', true);
- state = state.set('showingTimeTravel', false);
return state.set('pausedAt', null);
}
case ActionTypes.PAUSE_TIME_AT_NOW: {
- state = state.set('showingTimeTravel', false);
state = state.set('timeTravelTransitioning', false);
return state.set('pausedAt', moment().utc().format());
}
case ActionTypes.START_TIME_TRAVEL: {
- state = state.set('showingTimeTravel', true);
state = state.set('timeTravelTransitioning', false);
return state.set('pausedAt', action.timestamp || moment().utc().format());
}
diff --git a/client/app/scripts/selectors/time-travel.js b/client/app/scripts/selectors/time-travel.js
index 40a70772a..c3bfa556a 100644
--- a/client/app/scripts/selectors/time-travel.js
+++ b/client/app/scripts/selectors/time-travel.js
@@ -7,3 +7,5 @@ export const isPausedSelector = createSelector(
],
pausedAt => !!pausedAt
);
+
+export const timeTravelSupportedSelector = state => state.getIn(['capabilities', 'historic_reports']);
diff --git a/client/app/styles/_base.scss b/client/app/styles/_base.scss
index 4addf32c2..94e083cdd 100644
--- a/client/app/styles/_base.scss
+++ b/client/app/styles/_base.scss
@@ -198,7 +198,7 @@ a {
&.time-travel-open {
.details-wrapper {
- margin-top: $timeline-height + 15px;
+ margin-top: $timeline-height + 50px;
}
}
}
@@ -211,6 +211,7 @@ a {
.selectors {
display: flex;
position: relative;
+
> * {
z-index: 20;
flex: 1 1;
@@ -391,6 +392,10 @@ a {
width: 33%;
height: 550px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+
.heading {
font-size: 125%;
}