diff --git a/client/.babelrc b/client/.babelrc
index 9d92eb7b8..02eef7181 100644
--- a/client/.babelrc
+++ b/client/.babelrc
@@ -1,6 +1,7 @@
{
"plugins": [
"lodash",
+ "transform-class-properties",
["transform-object-rest-spread", { "useBuiltIns": true }]
],
"presets": ["env", "react"]
diff --git a/client/app/scripts/components/node-details/node-details-table-row.js b/client/app/scripts/components/node-details/node-details-table-row.js
index ed157ab3f..428681465 100644
--- a/client/app/scripts/components/node-details/node-details-table-row.js
+++ b/client/app/scripts/components/node-details/node-details-table-row.js
@@ -114,46 +114,44 @@ export default class NodeDetailsTableRow extends React.Component {
// is most likely a details panel popping open.
//
this.state = { focused: false };
- this.mouseDragOrigin = [0, 0];
-
- this.onMouseDown = this.onMouseDown.bind(this);
- this.onMouseUp = this.onMouseUp.bind(this);
- this.onMouseEnter = this.onMouseEnter.bind(this);
- this.onMouseLeave = this.onMouseLeave.bind(this);
+ this.mouseDrag = {};
}
- onMouseEnter() {
+ onMouseEnter = () => {
this.setState({ focused: true });
if (this.props.onMouseEnter) {
this.props.onMouseEnter(this.props.index, this.props.node);
}
}
- onMouseLeave() {
+ onMouseLeave = () => {
this.setState({ focused: false });
if (this.props.onMouseLeave) {
this.props.onMouseLeave();
}
}
- onMouseDown(ev) {
- const { pageX, pageY } = ev;
- this.mouseDragOrigin = [pageX, pageY];
+ onMouseDown = (ev) => {
+ this.mouseDrag = {
+ originX: ev.pageX,
+ originY: ev.pageY,
+ };
}
- onMouseUp(ev) {
- const [originX, originY] = this.mouseDragOrigin;
- const { pageX, pageY } = ev;
+ onClick = (ev) => {
const thresholdPx = 2;
+ const { pageX, pageY } = ev;
+ const { originX, originY } = this.mouseDrag;
const movedTheMouseTooMuch = (
Math.abs(originX - pageX) > thresholdPx ||
Math.abs(originY - pageY) > thresholdPx
);
- if (movedTheMouseTooMuch) {
+ if (movedTheMouseTooMuch && originX && originY) {
return;
}
this.props.onClick(ev, this.props.node);
+ this.mouseDrag = {};
}
render() {
@@ -171,8 +169,8 @@ export default class NodeDetailsTableRow extends React.Component {
return (
diff --git a/client/app/scripts/components/topologies.js b/client/app/scripts/components/topologies.js
index d75439db8..7fa49eb13 100644
--- a/client/app/scripts/components/topologies.js
+++ b/client/app/scripts/components/topologies.js
@@ -39,7 +39,7 @@ class Topologies extends React.Component {
const isActive = subTopology === this.props.currentTopology;
const searchMatchCount = this.props.searchMatchCountByTopology.get(topologyId) || 0;
const title = basicTopologyInfo(subTopology, searchMatchCount);
- const className = classnames('topologies-sub-item', {
+ const className = classnames(`topologies-sub-item topologies-item-${topologyId}`, {
// Don't show matches in the resource view as searching is not supported there yet.
'topologies-sub-item-matched': !this.props.isResourceViewMode && searchMatchCount,
'topologies-sub-item-active': isActive,
@@ -60,14 +60,14 @@ class Topologies extends React.Component {
}
renderTopology(topology) {
+ const topologyId = topology.get('id');
const isActive = topology === this.props.currentTopology;
const searchMatchCount = this.props.searchMatchCountByTopology.get(topology.get('id')) || 0;
- const className = classnames('topologies-item-main', {
+ const className = classnames(`topologies-item-main topologies-item-${topologyId}`, {
// Don't show matches in the resource view as searching is not supported there yet.
'topologies-item-main-matched': !this.props.isResourceViewMode && searchMatchCount,
'topologies-item-main-active': isActive,
});
- const topologyId = topology.get('id');
const title = basicTopologyInfo(topology, searchMatchCount);
return (
diff --git a/client/app/scripts/components/view-mode-button.js b/client/app/scripts/components/view-mode-button.js
new file mode 100644
index 000000000..ce18bedfa
--- /dev/null
+++ b/client/app/scripts/components/view-mode-button.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import classNames from 'classnames';
+
+import { trackAnalyticsEvent } from '../utils/tracking-utils';
+
+
+class ViewModeButton extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.handleClick = this.handleClick.bind(this);
+ }
+
+ handleClick() {
+ trackAnalyticsEvent('scope.layout.selector.click', {
+ layout: this.props.viewMode,
+ topologyId: this.props.currentTopology.get('id'),
+ parentTopologyId: this.props.currentTopology.get('parentId'),
+ });
+ this.props.onClick();
+ }
+
+ render() {
+ const { label, viewMode, disabled } = this.props;
+
+ const isSelected = (this.props.topologyViewMode === viewMode);
+ const className = classNames(`view-mode-selector-action view-${label}-action`, {
+ 'view-mode-selector-action-selected': isSelected,
+ });
+
+ return (
+
+
+ {label}
+
+ );
+ }
+}
+
+function mapStateToProps(state) {
+ return {
+ topologyViewMode: state.get('topologyViewMode'),
+ currentTopology: state.get('currentTopology'),
+ };
+}
+
+export default connect(mapStateToProps)(ViewModeButton);
diff --git a/client/app/scripts/components/view-mode-selector.js b/client/app/scripts/components/view-mode-selector.js
index b2a2b75ce..8c5cf9173 100644
--- a/client/app/scripts/components/view-mode-selector.js
+++ b/client/app/scripts/components/view-mode-selector.js
@@ -1,9 +1,8 @@
import React from 'react';
import { connect } from 'react-redux';
-import classNames from 'classnames';
+import ViewModeButton from './view-mode-button';
import MetricSelector from './metric-selector';
-import { trackAnalyticsEvent } from '../utils/tracking-utils';
import { setGraphView, setTableView, setResourceView } from '../actions/app-actions';
import { availableMetricsSelector } from '../selectors/node-metric';
import {
@@ -24,44 +23,29 @@ class ViewModeSelector extends React.Component {
}
}
- renderItem(icons, label, viewMode, setViewModeAction, isEnabled = true) {
- const isSelected = (this.props.topologyViewMode === viewMode);
- const className = classNames('view-mode-selector-action', {
- 'view-mode-selector-action-selected': isSelected,
- });
- const onClick = () => {
- trackAnalyticsEvent('scope.layout.selector.click', {
- layout: viewMode,
- topologyId: this.props.currentTopology.get('id'),
- parentTopologyId: this.props.currentTopology.get('parentId'),
- });
- setViewModeAction();
- };
-
- return (
-
-
- {label}
-
- );
- }
-
render() {
- const { hasResourceView } = this.props;
-
return (
- {this.renderItem('fa fa-share-alt', 'Graph', GRAPH_VIEW_MODE, this.props.setGraphView)}
- {this.renderItem('fa fa-table', 'Table', TABLE_VIEW_MODE, this.props.setTableView)}
- {this.renderItem(
-'fa fa-bar-chart', 'Resources', RESOURCE_VIEW_MODE,
- this.props.setResourceView, hasResourceView
-)}
+
+
+
diff --git a/client/app/styles/_base.scss b/client/app/styles/_base.scss
index 6352e295e..d00c82dab 100644
--- a/client/app/styles/_base.scss
+++ b/client/app/styles/_base.scss
@@ -371,10 +371,10 @@ a {
.nodes-chart-overlay {
pointer-events: none;
- opacity: 0;
+ opacity: $node-elements-in-background-opacity;
- &.active {
- opacity: $node-elements-in-background-opacity;
+ &:not(.active) {
+ display: none;
}
}
diff --git a/client/package.json b/client/package.json
index e22620aae..126183f5f 100644
--- a/client/package.json
+++ b/client/package.json
@@ -54,6 +54,7 @@
"babel-eslint": "8.0.1",
"babel-jest": "21.2.0",
"babel-loader": "6.4.1",
+ "babel-plugin-transform-class-properties": "6.24.1",
"babel-plugin-transform-object-rest-spread": "6.26.0",
"babel-preset-env": "1.6.1",
"babel-preset-react": "6.24.1",
diff --git a/client/yarn.lock b/client/yarn.lock
index 9aee46b7c..5d35f4f22 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -604,6 +604,10 @@ babel-plugin-syntax-async-functions@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
+babel-plugin-syntax-class-properties@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
+
babel-plugin-syntax-exponentiation-operator@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
@@ -632,6 +636,15 @@ babel-plugin-transform-async-to-generator@^6.22.0:
babel-plugin-syntax-async-functions "^6.8.0"
babel-runtime "^6.22.0"
+babel-plugin-transform-class-properties@6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac"
+ dependencies:
+ babel-helper-function-name "^6.24.1"
+ babel-plugin-syntax-class-properties "^6.8.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
babel-plugin-transform-es2015-arrow-functions@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"