mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 02:00:43 +00:00
Upgrade eslint, react and react-motion
* get rid of material-ui * reduced bundle size by 20%
This commit is contained in:
214
client/.eslintrc
214
client/.eslintrc
@@ -1,216 +1,12 @@
|
||||
{
|
||||
"parser": "babel-eslint",
|
||||
"plugins": [
|
||||
"react",
|
||||
"jasmine"
|
||||
],
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"ecmaFeatures": {
|
||||
"arrowFunctions": true,
|
||||
"blockBindings": true,
|
||||
"classes": true,
|
||||
"defaultParams": true,
|
||||
"destructuring": true,
|
||||
"forOf": true,
|
||||
"generators": false,
|
||||
"modules": true,
|
||||
"objectLiteralComputedProperties": true,
|
||||
"objectLiteralDuplicateProperties": false,
|
||||
"objectLiteralShorthandMethods": true,
|
||||
"objectLiteralShorthandProperties": true,
|
||||
"spread": true,
|
||||
"superInFunctions": true,
|
||||
"templateStrings": true,
|
||||
"jsx": true
|
||||
},
|
||||
"extends": "airbnb",
|
||||
"globals": {
|
||||
__WS_URL__: false
|
||||
},
|
||||
"rules": {
|
||||
/**
|
||||
* Strict mode
|
||||
*/
|
||||
// babel inserts "use strict"; for us
|
||||
// http://eslint.org/docs/rules/strict
|
||||
"strict": [2, "never"],
|
||||
|
||||
/**
|
||||
* ES6
|
||||
*/
|
||||
"no-var": 2, // http://eslint.org/docs/rules/no-var
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*/
|
||||
"no-shadow": 2, // http://eslint.org/docs/rules/no-shadow
|
||||
"no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names
|
||||
"no-unused-vars": [2, { // http://eslint.org/docs/rules/no-unused-vars
|
||||
"vars": "local",
|
||||
"args": "after-used"
|
||||
}],
|
||||
"no-use-before-define": 2, // http://eslint.org/docs/rules/no-use-before-define
|
||||
|
||||
/**
|
||||
* Possible errors
|
||||
*/
|
||||
"comma-dangle": [2, "never"], // http://eslint.org/docs/rules/comma-dangle
|
||||
"no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign
|
||||
"no-console": 1, // http://eslint.org/docs/rules/no-console
|
||||
"no-debugger": 1, // http://eslint.org/docs/rules/no-debugger
|
||||
"no-alert": 1, // http://eslint.org/docs/rules/no-alert
|
||||
"no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition
|
||||
"no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys
|
||||
"no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case
|
||||
"no-empty": 2, // http://eslint.org/docs/rules/no-empty
|
||||
"no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign
|
||||
"no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast
|
||||
"no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi
|
||||
"no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign
|
||||
"no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations
|
||||
"no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp
|
||||
"no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace
|
||||
"no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls
|
||||
"no-reserved-keys": 2, // http://eslint.org/docs/rules/no-reserved-keys
|
||||
"no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays
|
||||
"no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable
|
||||
"use-isnan": 2, // http://eslint.org/docs/rules/use-isnan
|
||||
"block-scoped-var": 2, // http://eslint.org/docs/rules/block-scoped-var
|
||||
|
||||
/**
|
||||
* Best practices
|
||||
*/
|
||||
"consistent-return": 2, // http://eslint.org/docs/rules/consistent-return
|
||||
"curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly
|
||||
"default-case": 2, // http://eslint.org/docs/rules/default-case
|
||||
"dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation
|
||||
"allowKeywords": true
|
||||
}],
|
||||
"eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq
|
||||
"guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in
|
||||
"no-caller": 2, // http://eslint.org/docs/rules/no-caller
|
||||
"no-else-return": 2, // http://eslint.org/docs/rules/no-else-return
|
||||
"no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null
|
||||
"no-eval": 2, // http://eslint.org/docs/rules/no-eval
|
||||
"no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native
|
||||
"no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind
|
||||
"no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough
|
||||
"no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal
|
||||
"no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval
|
||||
"no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks
|
||||
"no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func
|
||||
"no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str
|
||||
"no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign
|
||||
"no-new": 2, // http://eslint.org/docs/rules/no-new
|
||||
"no-new-func": 2, // http://eslint.org/docs/rules/no-new-func
|
||||
"no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers
|
||||
"no-octal": 2, // http://eslint.org/docs/rules/no-octal
|
||||
"no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape
|
||||
"no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign
|
||||
"no-proto": 2, // http://eslint.org/docs/rules/no-proto
|
||||
"no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare
|
||||
"no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign
|
||||
"no-script-url": 2, // http://eslint.org/docs/rules/no-script-url
|
||||
"no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare
|
||||
"no-sequences": 2, // http://eslint.org/docs/rules/no-sequences
|
||||
"no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal
|
||||
"no-with": 2, // http://eslint.org/docs/rules/no-with
|
||||
"radix": 2, // http://eslint.org/docs/rules/radix
|
||||
"vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top
|
||||
"wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife
|
||||
"yoda": 2, // http://eslint.org/docs/rules/yoda
|
||||
|
||||
/**
|
||||
* Style
|
||||
*/
|
||||
"indent": [2, 2], // http://eslint.org/docs/rules/
|
||||
"brace-style": [2, // http://eslint.org/docs/rules/brace-style
|
||||
"1tbs", {
|
||||
"allowSingleLine": true
|
||||
}],
|
||||
"quotes": [
|
||||
2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes
|
||||
],
|
||||
"camelcase": [2, { // http://eslint.org/docs/rules/camelcase
|
||||
"properties": "never"
|
||||
}],
|
||||
"comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing
|
||||
"before": false,
|
||||
"after": true
|
||||
}],
|
||||
"comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style
|
||||
"eol-last": 2, // http://eslint.org/docs/rules/eol-last
|
||||
"func-names": 0, // http://eslint.org/docs/rules/func-names
|
||||
"key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing
|
||||
"beforeColon": false,
|
||||
"afterColon": true
|
||||
}],
|
||||
"new-cap": [2, { // http://eslint.org/docs/rules/new-cap
|
||||
"newIsCap": true
|
||||
}],
|
||||
"no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines
|
||||
"max": 2
|
||||
}],
|
||||
"no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary
|
||||
"no-new-object": 2, // http://eslint.org/docs/rules/no-new-object
|
||||
"no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func
|
||||
"no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces
|
||||
"no-wrap-func": 2, // http://eslint.org/docs/rules/no-wrap-func
|
||||
"no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle
|
||||
"one-var": [2, "never"], // http://eslint.org/docs/rules/one-var
|
||||
"padded-blocks": [2, "never"], // http://eslint.org/docs/rules/padded-blocks
|
||||
"semi": [2, "always"], // http://eslint.org/docs/rules/semi
|
||||
"semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing
|
||||
"before": false,
|
||||
"after": true
|
||||
}],
|
||||
"space-after-keywords": 2, // http://eslint.org/docs/rules/space-after-keywords
|
||||
"space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks
|
||||
"space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren
|
||||
"space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops
|
||||
"space-return-throw-case": 2, // http://eslint.org/docs/rules/space-return-throw-case
|
||||
"spaced-line-comment": 2, // http://eslint.org/docs/rules/spaced-line-comment
|
||||
|
||||
/**
|
||||
* JSX style
|
||||
*/
|
||||
"react/display-name": 0,
|
||||
"react/jsx-boolean-value": 2,
|
||||
"react/jsx-quotes": [2, "double"],
|
||||
"react/jsx-no-undef": 2,
|
||||
"react/jsx-sort-props": 0,
|
||||
"react/jsx-sort-prop-types": 0,
|
||||
"react/jsx-uses-react": 2,
|
||||
"react/jsx-uses-vars": 2,
|
||||
"react/no-did-mount-set-state": [2, "allow-in-func"],
|
||||
"react/no-did-update-set-state": 2,
|
||||
"react/no-multi-comp": 2,
|
||||
"react/no-unknown-property": 2,
|
||||
"react/prop-types": 0,
|
||||
"react/react-in-jsx-scope": 2,
|
||||
"react/self-closing-comp": 2,
|
||||
"react/wrap-multilines": 2,
|
||||
"react/sort-comp": [2, {
|
||||
"order": [
|
||||
"displayName",
|
||||
"mixins",
|
||||
"statics",
|
||||
"propTypes",
|
||||
"getDefaultProps",
|
||||
"getInitialState",
|
||||
"componentWillMount",
|
||||
"componentDidMount",
|
||||
"componentWillReceiveProps",
|
||||
"shouldComponentUpdate",
|
||||
"componentWillUpdate",
|
||||
"componentWillUnmount",
|
||||
"/^on.+$/",
|
||||
"/^get.+$/",
|
||||
"/^render.+$/",
|
||||
"render"
|
||||
]
|
||||
}]
|
||||
"comma-dangle": 0,
|
||||
"func-names": 0,
|
||||
"react/sort-comp": 0,
|
||||
"react/prop-types": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ module.exports = {
|
||||
WebapiUtils.doControl(
|
||||
probeId,
|
||||
nodeId,
|
||||
control,
|
||||
control
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
const _ = require('lodash');
|
||||
const d3 = require('d3');
|
||||
const React = require('react');
|
||||
const Spring = require('react-motion').Spring;
|
||||
const Motion = require('react-motion').Motion;
|
||||
const spring = require('react-motion').spring;
|
||||
|
||||
const AppActions = require('../actions/app-actions');
|
||||
|
||||
@@ -15,8 +16,8 @@ const animConfig = [80, 20]; // stiffness, bounce
|
||||
const flattenPoints = function(points) {
|
||||
const flattened = {};
|
||||
points.forEach(function(point, i) {
|
||||
flattened['x' + i] = {val: point.x, config: animConfig};
|
||||
flattened['y' + i] = {val: point.y, config: animConfig};
|
||||
flattened['x' + i] = spring(point.x, animConfig);
|
||||
flattened['y' + i] = spring(point.y, animConfig);
|
||||
});
|
||||
return flattened;
|
||||
};
|
||||
@@ -29,7 +30,7 @@ const extractPoints = function(points) {
|
||||
if (!extracted[index]) {
|
||||
extracted[index] = {};
|
||||
}
|
||||
extracted[index][axis] = value.val;
|
||||
extracted[index][axis] = value;
|
||||
});
|
||||
return extracted;
|
||||
};
|
||||
@@ -66,7 +67,7 @@ const Edge = React.createClass({
|
||||
const classes = classNames.join(' ');
|
||||
|
||||
return (
|
||||
<Spring endValue={points}>
|
||||
<Motion style={points}>
|
||||
{function(interpolated) {
|
||||
const path = line(extractPoints(interpolated));
|
||||
return (
|
||||
@@ -76,7 +77,7 @@ const Edge = React.createClass({
|
||||
</g>
|
||||
);
|
||||
}}
|
||||
</Spring>
|
||||
</Motion>
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const React = require('react');
|
||||
const Spring = require('react-motion').Spring;
|
||||
const Motion = require('react-motion').Motion;
|
||||
const spring = require('react-motion').spring;
|
||||
|
||||
const AppActions = require('../actions/app-actions');
|
||||
const NodeColorMixin = require('../mixins/node-color-mixin');
|
||||
@@ -42,30 +43,30 @@ const Node = React.createClass({
|
||||
const classes = classNames.join(' ');
|
||||
|
||||
return (
|
||||
<Spring endValue={{
|
||||
x: {val: this.props.dx, config: animConfig},
|
||||
y: {val: this.props.dy, config: animConfig},
|
||||
f: {val: scaleFactor, config: animConfig}
|
||||
<Motion style={{
|
||||
x: spring(this.props.dx, animConfig),
|
||||
y: spring(this.props.dy, animConfig),
|
||||
f: spring(scaleFactor, animConfig)
|
||||
}}>
|
||||
{function(interpolated) {
|
||||
const transform = `translate(${interpolated.x.val},${interpolated.y.val})`;
|
||||
const transform = `translate(${interpolated.x},${interpolated.y})`;
|
||||
return (
|
||||
<g className={classes} transform={transform} id={props.id}
|
||||
onClick={onMouseClick} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
|
||||
{props.highlighted && <circle r={scale(0.7 * interpolated.f.val)} className="highlighted"></circle>}
|
||||
<circle r={scale(0.5 * interpolated.f.val)} className="border" stroke={color}></circle>
|
||||
<circle r={scale(0.45 * interpolated.f.val)} className="shadow"></circle>
|
||||
<circle r={Math.max(2, scale(0.125 * interpolated.f.val))} className="node"></circle>
|
||||
<text className="node-label" textAnchor="middle" x="0" y={labelOffsetY + scale(0.5 * interpolated.f.val)}>
|
||||
{props.highlighted && <circle r={scale(0.7 * interpolated.f)} className="highlighted"></circle>}
|
||||
<circle r={scale(0.5 * interpolated.f)} className="border" stroke={color}></circle>
|
||||
<circle r={scale(0.45 * interpolated.f)} className="shadow"></circle>
|
||||
<circle r={Math.max(2, scale(0.125 * interpolated.f))} className="node"></circle>
|
||||
<text className="node-label" textAnchor="middle" x="0" y={labelOffsetY + scale(0.5 * interpolated.f)}>
|
||||
{label}
|
||||
</text>
|
||||
<text className="node-sublabel" textAnchor="middle" x="0" y={subLabelOffsetY + scale(0.5 * interpolated.f.val)}>
|
||||
<text className="node-sublabel" textAnchor="middle" x="0" y={subLabelOffsetY + scale(0.5 * interpolated.f)}>
|
||||
{subLabel}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
}}
|
||||
</Spring>
|
||||
</Motion>
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ const debug = require('debug')('scope:nodes-chart');
|
||||
const React = require('react');
|
||||
const makeMap = require('immutable').Map;
|
||||
const timely = require('timely');
|
||||
const Spring = require('react-motion').Spring;
|
||||
const Motion = require('react-motion').Motion;
|
||||
const spring = require('react-motion').spring;
|
||||
|
||||
const AppActions = require('../actions/app-actions');
|
||||
const AppStore = require('../stores/app-store');
|
||||
@@ -199,7 +200,7 @@ const NodesChart = React.createClass({
|
||||
render: function() {
|
||||
const nodeElements = this.renderGraphNodes(this.state.nodes, this.state.nodeScale);
|
||||
const edgeElements = this.renderGraphEdges(this.state.edges, this.state.nodeScale);
|
||||
let scale = this.state.scale;
|
||||
const scale = this.state.scale;
|
||||
|
||||
// only animate shift behavior, not panning
|
||||
const panTranslate = this.state.panTranslate;
|
||||
@@ -213,15 +214,16 @@ const NodesChart = React.createClass({
|
||||
const svgClassNames = this.state.maxNodesExceeded || nodeElements.size === 0 ? 'hide' : '';
|
||||
const errorEmpty = this.renderEmptyTopologyError(AppStore.isTopologyEmpty());
|
||||
const errorMaxNodesExceeded = this.renderMaxNodesError(this.state.maxNodesExceeded);
|
||||
const motionConfig = [80, 20];
|
||||
|
||||
return (
|
||||
<div className="nodes-chart">
|
||||
{errorEmpty}
|
||||
{errorMaxNodesExceeded}
|
||||
<svg width="100%" height="100%" className={svgClassNames} onClick={this.handleMouseClick}>
|
||||
<Spring endValue={{val: translate, config: [80, 20]}}>
|
||||
<Motion style={{x: spring(translate[0], motionConfig), y: spring(translate[1], motionConfig)}}>
|
||||
{function(interpolated) {
|
||||
let interpolatedTranslate = wasShifted ? interpolated.val : panTranslate;
|
||||
const interpolatedTranslate = wasShifted ? [interpolated.x, interpolated.y] : panTranslate;
|
||||
const transform = 'translate(' + interpolatedTranslate + ')' +
|
||||
' scale(' + scale + ')';
|
||||
return (
|
||||
@@ -235,7 +237,7 @@ const NodesChart = React.createClass({
|
||||
</g>
|
||||
);
|
||||
}}
|
||||
</Spring>
|
||||
</Motion>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
@@ -291,14 +293,14 @@ const NodesChart = React.createClass({
|
||||
centerSelectedNode: function(props, state) {
|
||||
let stateNodes = state.nodes;
|
||||
let stateEdges = state.edges;
|
||||
let selectedLayoutNode = stateNodes.get(props.selectedNodeId);
|
||||
const selectedLayoutNode = stateNodes.get(props.selectedNodeId);
|
||||
|
||||
if (!selectedLayoutNode) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const adjacency = AppStore.getAdjacentNodes(props.selectedNodeId);
|
||||
let adjacentLayoutNodeIds = [];
|
||||
const adjacentLayoutNodeIds = [];
|
||||
|
||||
adjacency.forEach(function(adjacentId) {
|
||||
// filter loopback
|
||||
|
||||
@@ -7,7 +7,7 @@ const NodesError = React.createClass({
|
||||
if (this.props.hidden) {
|
||||
classNames += ' hide';
|
||||
}
|
||||
let iconClassName = 'fa ' + this.props.faIconClass;
|
||||
const iconClassName = 'fa ' + this.props.faIconClass;
|
||||
|
||||
return (
|
||||
<div className={classNames}>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// polyfill
|
||||
Object.assign = require('object-assign');
|
||||
|
||||
const dagre = require('dagre');
|
||||
const debug = require('debug')('scope:nodes-layout');
|
||||
const makeMap = require('immutable').Map;
|
||||
@@ -181,7 +184,7 @@ function hasSameEndpoints(cachedEdge, nodes) {
|
||||
* @return {Object} layout clone
|
||||
*/
|
||||
function cloneLayout(layout, nodes, edges) {
|
||||
const clone = {...layout, nodes, edges};
|
||||
const clone = Object.assign({}, layout, {nodes, edges});
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ describe('NodeDetails', () => {
|
||||
const c = TestUtils.renderIntoDocument(<NodeDetails nodes={nodes} nodeId={nodeId} details={details} />);
|
||||
|
||||
const title = TestUtils.findRenderedDOMComponentWithClass(c, 'node-details-header-label');
|
||||
expect(title.getDOMNode().textContent).toBe('Node 1');
|
||||
expect(title.textContent).toBe('Node 1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const React = require('react');
|
||||
const mui = require('material-ui');
|
||||
|
||||
const Logo = require('./logo');
|
||||
const AppStore = require('../stores/app-store');
|
||||
@@ -13,8 +12,6 @@ const Details = require('./details');
|
||||
const Nodes = require('./nodes');
|
||||
const RouterUtils = require('../utils/router-utils');
|
||||
|
||||
const ThemeManager = new mui.Styles.ThemeManager();
|
||||
|
||||
const ESC_KEY_CODE = 27;
|
||||
|
||||
function getStateFromStores() {
|
||||
@@ -67,12 +64,6 @@ const App = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
getChildContext: function() {
|
||||
return {
|
||||
muiTheme: ThemeManager.getCurrentTheme()
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const showingDetails = this.state.selectedNodeId;
|
||||
const versionString = this.state.version ? 'Version ' + this.state.version : '';
|
||||
@@ -115,9 +106,6 @@ const App = React.createClass({
|
||||
);
|
||||
},
|
||||
|
||||
childContextTypes: {
|
||||
muiTheme: React.PropTypes.object
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = App;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
const React = require('react');
|
||||
const mui = require('material-ui');
|
||||
const Paper = mui.Paper;
|
||||
|
||||
const NodeDetails = require('./node-details');
|
||||
|
||||
@@ -9,9 +7,11 @@ const Details = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<div id="details">
|
||||
<Paper zDepth={3} style={{height: '100%', paddingBottom: 8}}>
|
||||
<div style={{height: '100%', paddingBottom: 8, borderRadius: 2,
|
||||
backgroundColor: '#fff',
|
||||
boxShadow: '0 10px 30px rgba(0, 0, 0, 0.19), 0 6px 10px rgba(0, 0, 0, 0.23)'}}>
|
||||
<NodeDetails {...this.props} />
|
||||
</Paper>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ require('font-awesome-webpack');
|
||||
require('../styles/main.less');
|
||||
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
|
||||
const App = require('./components/app.js');
|
||||
|
||||
React.render(
|
||||
ReactDOM.render(
|
||||
<App/>,
|
||||
document.getElementById('app'));
|
||||
|
||||
@@ -242,186 +242,186 @@ const AppStore = assign({}, EventEmitter.prototype, {
|
||||
AppStore.registeredCallback = function(payload) {
|
||||
switch (payload.type) {
|
||||
|
||||
case ActionTypes.CHANGE_TOPOLOGY_OPTION:
|
||||
if (topologyOptions.getIn([payload.topologyId, payload.option])
|
||||
!== payload.value) {
|
||||
nodes = nodes.clear();
|
||||
}
|
||||
topologyOptions = topologyOptions.setIn(
|
||||
[payload.topologyId, payload.option],
|
||||
payload.value
|
||||
);
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.CLEAR_CONTROL_ERROR:
|
||||
controlError = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.CLICK_CLOSE_DETAILS:
|
||||
selectedNodeId = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.CLICK_NODE:
|
||||
if (payload.nodeId === selectedNodeId) {
|
||||
// clicking same node twice unsets the selection
|
||||
selectedNodeId = null;
|
||||
} else {
|
||||
selectedNodeId = payload.nodeId;
|
||||
}
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.CLICK_TOPOLOGY:
|
||||
selectedNodeId = null;
|
||||
if (payload.topologyId !== currentTopologyId) {
|
||||
setTopology(payload.topologyId);
|
||||
nodes = nodes.clear();
|
||||
}
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.CLOSE_WEBSOCKET:
|
||||
websocketClosed = true;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.DO_CONTROL:
|
||||
controlPending = true;
|
||||
controlError = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.ENTER_EDGE:
|
||||
mouseOverEdgeId = payload.edgeId;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.ENTER_NODE:
|
||||
mouseOverNodeId = payload.nodeId;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.HIT_ESC_KEY:
|
||||
nodeDetails = null;
|
||||
selectedNodeId = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.LEAVE_EDGE:
|
||||
mouseOverEdgeId = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.LEAVE_NODE:
|
||||
mouseOverNodeId = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.OPEN_WEBSOCKET:
|
||||
// flush nodes cache after re-connect
|
||||
case ActionTypes.CHANGE_TOPOLOGY_OPTION:
|
||||
if (topologyOptions.getIn([payload.topologyId, payload.option])
|
||||
!== payload.value) {
|
||||
nodes = nodes.clear();
|
||||
websocketClosed = false;
|
||||
}
|
||||
topologyOptions = topologyOptions.setIn(
|
||||
[payload.topologyId, payload.option],
|
||||
payload.value
|
||||
);
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
case ActionTypes.CLEAR_CONTROL_ERROR:
|
||||
controlError = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.DO_CONTROL_ERROR:
|
||||
controlPending = false;
|
||||
controlError = payload.error;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
case ActionTypes.CLICK_CLOSE_DETAILS:
|
||||
selectedNodeId = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.DO_CONTROL_SUCCESS:
|
||||
controlPending = false;
|
||||
controlError = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
case ActionTypes.CLICK_NODE:
|
||||
if (payload.nodeId === selectedNodeId) {
|
||||
// clicking same node twice unsets the selection
|
||||
selectedNodeId = null;
|
||||
} else {
|
||||
selectedNodeId = payload.nodeId;
|
||||
}
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_ERROR:
|
||||
errorUrl = payload.errorUrl;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
case ActionTypes.CLICK_TOPOLOGY:
|
||||
selectedNodeId = null;
|
||||
if (payload.topologyId !== currentTopologyId) {
|
||||
setTopology(payload.topologyId);
|
||||
nodes = nodes.clear();
|
||||
}
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_NODE_DETAILS:
|
||||
errorUrl = null;
|
||||
nodeDetails = payload.details;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
case ActionTypes.CLOSE_WEBSOCKET:
|
||||
websocketClosed = true;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_NODES_DELTA:
|
||||
const emptyMessage = !payload.delta.add && !payload.delta.remove
|
||||
&& payload.delta.update;
|
||||
case ActionTypes.DO_CONTROL:
|
||||
controlPending = true;
|
||||
controlError = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
if (!emptyMessage) {
|
||||
debug('RECEIVE_NODES_DELTA',
|
||||
'remove', _.size(payload.delta.remove),
|
||||
'update', _.size(payload.delta.update),
|
||||
'add', _.size(payload.delta.add));
|
||||
case ActionTypes.ENTER_EDGE:
|
||||
mouseOverEdgeId = payload.edgeId;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.ENTER_NODE:
|
||||
mouseOverNodeId = payload.nodeId;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.HIT_ESC_KEY:
|
||||
nodeDetails = null;
|
||||
selectedNodeId = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.LEAVE_EDGE:
|
||||
mouseOverEdgeId = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.LEAVE_NODE:
|
||||
mouseOverNodeId = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.OPEN_WEBSOCKET:
|
||||
// flush nodes cache after re-connect
|
||||
nodes = nodes.clear();
|
||||
websocketClosed = false;
|
||||
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.DO_CONTROL_ERROR:
|
||||
controlPending = false;
|
||||
controlError = payload.error;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.DO_CONTROL_SUCCESS:
|
||||
controlPending = false;
|
||||
controlError = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_ERROR:
|
||||
errorUrl = payload.errorUrl;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_NODE_DETAILS:
|
||||
errorUrl = null;
|
||||
nodeDetails = payload.details;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_NODES_DELTA:
|
||||
const emptyMessage = !payload.delta.add && !payload.delta.remove
|
||||
&& payload.delta.update;
|
||||
|
||||
if (!emptyMessage) {
|
||||
debug('RECEIVE_NODES_DELTA',
|
||||
'remove', _.size(payload.delta.remove),
|
||||
'update', _.size(payload.delta.update),
|
||||
'add', _.size(payload.delta.add));
|
||||
}
|
||||
|
||||
errorUrl = null;
|
||||
|
||||
// nodes that no longer exist
|
||||
_.each(payload.delta.remove, function(nodeId) {
|
||||
// in case node disappears before mouseleave event
|
||||
if (mouseOverNodeId === nodeId) {
|
||||
mouseOverNodeId = null;
|
||||
}
|
||||
|
||||
errorUrl = null;
|
||||
|
||||
// nodes that no longer exist
|
||||
_.each(payload.delta.remove, function(nodeId) {
|
||||
// in case node disappears before mouseleave event
|
||||
if (mouseOverNodeId === nodeId) {
|
||||
mouseOverNodeId = null;
|
||||
}
|
||||
if (nodes.has(nodeId) && _.contains(mouseOverEdgeId, nodeId)) {
|
||||
mouseOverEdgeId = null;
|
||||
}
|
||||
nodes = nodes.delete(nodeId);
|
||||
});
|
||||
|
||||
// update existing nodes
|
||||
_.each(payload.delta.update, function(node) {
|
||||
nodes = nodes.set(node.id, nodes.get(node.id).merge(makeNode(node)));
|
||||
});
|
||||
|
||||
// add new nodes
|
||||
_.each(payload.delta.add, function(node) {
|
||||
nodes = nodes.set(node.id, Immutable.fromJS(makeNode(node)));
|
||||
});
|
||||
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_TOPOLOGIES:
|
||||
errorUrl = null;
|
||||
topologies = processTopologies(payload.topologies);
|
||||
setTopology(currentTopologyId);
|
||||
// only set on first load, if options are not already set via route
|
||||
if (!topologiesLoaded && topologyOptions.size === 0) {
|
||||
setDefaultTopologyOptions(topologies);
|
||||
if (nodes.has(nodeId) && _.contains(mouseOverEdgeId, nodeId)) {
|
||||
mouseOverEdgeId = null;
|
||||
}
|
||||
topologiesLoaded = true;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
nodes = nodes.delete(nodeId);
|
||||
});
|
||||
|
||||
case ActionTypes.RECEIVE_API_DETAILS:
|
||||
errorUrl = null;
|
||||
version = payload.version;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
// update existing nodes
|
||||
_.each(payload.delta.update, function(node) {
|
||||
nodes = nodes.set(node.id, nodes.get(node.id).merge(makeNode(node)));
|
||||
});
|
||||
|
||||
case ActionTypes.ROUTE_TOPOLOGY:
|
||||
routeSet = true;
|
||||
if (currentTopologyId !== payload.state.topologyId) {
|
||||
nodes = nodes.clear();
|
||||
}
|
||||
setTopology(payload.state.topologyId);
|
||||
// add new nodes
|
||||
_.each(payload.delta.add, function(node) {
|
||||
nodes = nodes.set(node.id, Immutable.fromJS(makeNode(node)));
|
||||
});
|
||||
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_TOPOLOGIES:
|
||||
errorUrl = null;
|
||||
topologies = processTopologies(payload.topologies);
|
||||
setTopology(currentTopologyId);
|
||||
// only set on first load, if options are not already set via route
|
||||
if (!topologiesLoaded && topologyOptions.size === 0) {
|
||||
setDefaultTopologyOptions(topologies);
|
||||
selectedNodeId = payload.state.selectedNodeId;
|
||||
topologyOptions = Immutable.fromJS(payload.state.topologyOptions)
|
||||
|| topologyOptions;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
}
|
||||
topologiesLoaded = true;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case ActionTypes.RECEIVE_API_DETAILS:
|
||||
errorUrl = null;
|
||||
version = payload.version;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.ROUTE_TOPOLOGY:
|
||||
routeSet = true;
|
||||
if (currentTopologyId !== payload.state.topologyId) {
|
||||
nodes = nodes.clear();
|
||||
}
|
||||
setTopology(payload.state.topologyId);
|
||||
setDefaultTopologyOptions(topologies);
|
||||
selectedNodeId = payload.state.selectedNodeId;
|
||||
topologyOptions = Immutable.fromJS(payload.state.topologyOptions)
|
||||
|| topologyOptions;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,19 +9,22 @@
|
||||
"d3": "~3.5.5",
|
||||
"dagre": "0.7.4",
|
||||
"debug": "~2.2.0",
|
||||
"flux": "2.0.3",
|
||||
"flux": "2.1.1",
|
||||
"font-awesome": "4.3.0",
|
||||
"font-awesome-webpack": "0.0.3",
|
||||
"immutable": "~3.7.4",
|
||||
"keymirror": "0.1.1",
|
||||
"lodash": "~3.9.3",
|
||||
"material-ui": "0.11.0",
|
||||
"materialize-css": "0.96.1",
|
||||
"object-assign": "2.0.0",
|
||||
"page": "1.6.3",
|
||||
"react": "~0.13.3",
|
||||
"react-motion": "0.2.7",
|
||||
"react-tap-event-plugin": "0.1.7",
|
||||
"react": "0.14.2",
|
||||
"react-addons-create-fragment": "0.14.2",
|
||||
"react-addons-pure-render-mixin": "0.14.2",
|
||||
"react-addons-transition-group": "0.14.2",
|
||||
"react-addons-update": "0.14.2",
|
||||
"react-dom": "0.14.2",
|
||||
"react-motion": "0.3.1",
|
||||
"reqwest": "~1.1.5",
|
||||
"timely": "0.1.0"
|
||||
},
|
||||
@@ -32,10 +35,11 @@
|
||||
"babel-jest": "5.3.0",
|
||||
"babel-loader": "5.1.3",
|
||||
"css-loader": "0.14.4",
|
||||
"eslint": "~0.21.2",
|
||||
"eslint-loader": "0.11.2",
|
||||
"eslint": "1.9.0",
|
||||
"eslint-config-airbnb": "1.0.0",
|
||||
"eslint-loader": "1.1.1",
|
||||
"eslint-plugin-jasmine": "1.0.0",
|
||||
"eslint-plugin-react": "2.3.0",
|
||||
"eslint-plugin-react": "3.8.0",
|
||||
"file-loader": "0.8.4",
|
||||
"jest-cli": "~0.4.19",
|
||||
"json-loader": "0.5.2",
|
||||
|
||||
Reference in New Issue
Block a user