mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 17:51:21 +00:00
Fix grouping bar for topologies that don't support grouping
- fixes #61 - dont clear nodes cache if topo is the same - combined stores that were interdependent - dont show topology grouping menu if unsupported - also harmonized some variable names - removed old grouping switcher - moved topo actions to app actions, removed search - get correct topology url - first JS test using Jest - make tests run on circle using the build container. - replaced jest test runner with karma/jasmine - Use debian for UI build and test container. - updated karma-browserify
This commit is contained in:
committed by
Tom Wilkie
parent
8dae139bdf
commit
66d66a4d01
@@ -15,7 +15,7 @@ module.exports = {
|
||||
grouping: grouping
|
||||
});
|
||||
RouterUtils.updateRoute();
|
||||
WebapiUtils.getNodesDelta(AppStore.getUrlForTopology(AppStore.getCurrentTopology()));
|
||||
WebapiUtils.getNodesDelta(AppStore.getCurrentTopologyUrl());
|
||||
},
|
||||
|
||||
clickNode: function(nodeId) {
|
||||
@@ -24,7 +24,7 @@ module.exports = {
|
||||
nodeId: nodeId
|
||||
});
|
||||
RouterUtils.updateRoute();
|
||||
WebapiUtils.getNodeDetails(AppStore.getUrlForTopology(AppStore.getCurrentTopology()), AppStore.getSelectedNodeId());
|
||||
WebapiUtils.getNodeDetails(AppStore.getCurrentTopologyUrl(), AppStore.getSelectedNodeId());
|
||||
},
|
||||
|
||||
clickTopology: function(topologyId) {
|
||||
@@ -33,7 +33,14 @@ module.exports = {
|
||||
topologyId: topologyId
|
||||
});
|
||||
RouterUtils.updateRoute();
|
||||
WebapiUtils.getNodesDelta(AppStore.getUrlForTopology(AppStore.getCurrentTopology()));
|
||||
WebapiUtils.getNodesDelta(AppStore.getCurrentTopologyUrl());
|
||||
},
|
||||
|
||||
enterNode: function(nodeId) {
|
||||
AppDispatcher.dispatch({
|
||||
type: ActionTypes.ENTER_NODE,
|
||||
nodeId: nodeId
|
||||
});
|
||||
},
|
||||
|
||||
hitEsc: function() {
|
||||
@@ -43,6 +50,13 @@ module.exports = {
|
||||
RouterUtils.updateRoute();
|
||||
},
|
||||
|
||||
leaveNode: function(nodeId) {
|
||||
AppDispatcher.dispatch({
|
||||
type: ActionTypes.LEAVE_NODE,
|
||||
nodeId: nodeId
|
||||
});
|
||||
},
|
||||
|
||||
receiveNodeDetails: function(details) {
|
||||
AppDispatcher.dispatch({
|
||||
type: ActionTypes.RECEIVE_NODE_DETAILS,
|
||||
@@ -50,13 +64,20 @@ module.exports = {
|
||||
});
|
||||
},
|
||||
|
||||
receiveNodesDelta: function(delta) {
|
||||
AppDispatcher.dispatch({
|
||||
type: ActionTypes.RECEIVE_NODES_DELTA,
|
||||
delta: delta
|
||||
});
|
||||
},
|
||||
|
||||
receiveTopologies: function(topologies) {
|
||||
AppDispatcher.dispatch({
|
||||
type: ActionTypes.RECEIVE_TOPOLOGIES,
|
||||
topologies: topologies
|
||||
});
|
||||
WebapiUtils.getNodesDelta(AppStore.getUrlForTopology(AppStore.getCurrentTopology()));
|
||||
WebapiUtils.getNodeDetails(AppStore.getUrlForTopology(AppStore.getCurrentTopology()), AppStore.getSelectedNodeId());
|
||||
WebapiUtils.getNodesDelta(AppStore.getCurrentTopologyUrl());
|
||||
WebapiUtils.getNodeDetails(AppStore.getCurrentTopologyUrl(), AppStore.getSelectedNodeId());
|
||||
},
|
||||
|
||||
route: function(state) {
|
||||
@@ -64,8 +85,8 @@ module.exports = {
|
||||
state: state,
|
||||
type: ActionTypes.ROUTE_TOPOLOGY
|
||||
});
|
||||
WebapiUtils.getNodesDelta(AppStore.getUrlForTopology(AppStore.getCurrentTopology()));
|
||||
WebapiUtils.getNodeDetails(AppStore.getUrlForTopology(AppStore.getCurrentTopology()), AppStore.getSelectedNodeId());
|
||||
WebapiUtils.getNodesDelta(AppStore.getCurrentTopologyUrl());
|
||||
WebapiUtils.getNodeDetails(AppStore.getCurrentTopologyUrl(), AppStore.getSelectedNodeId());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
var AppDispatcher = require('../dispatcher/app-dispatcher');
|
||||
var ActionTypes = require('../constants/action-types');
|
||||
|
||||
module.exports = {
|
||||
enterNode: function(nodeId) {
|
||||
AppDispatcher.dispatch({
|
||||
type: ActionTypes.ENTER_NODE,
|
||||
nodeId: nodeId
|
||||
});
|
||||
},
|
||||
|
||||
leaveNode: function(nodeId) {
|
||||
AppDispatcher.dispatch({
|
||||
type: ActionTypes.LEAVE_NODE,
|
||||
nodeId: nodeId
|
||||
});
|
||||
},
|
||||
|
||||
receiveNodesDelta: function(delta) {
|
||||
AppDispatcher.dispatch({
|
||||
type: ActionTypes.RECEIVE_NODES_DELTA,
|
||||
delta: delta
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -8,7 +8,6 @@ var AppStore = require('../stores/app-store');
|
||||
var Groupings = require('./groupings.js');
|
||||
var Status = require('./status.js');
|
||||
var Topologies = require('./topologies.js');
|
||||
var TopologyStore = require('../stores/topology-store');
|
||||
var WebapiUtils = require('../utils/web-api-utils');
|
||||
var AppActions = require('../actions/app-actions');
|
||||
var Details = require('./details');
|
||||
@@ -20,12 +19,12 @@ var ESC_KEY_CODE = 27;
|
||||
|
||||
function getStateFromStores() {
|
||||
return {
|
||||
activeTopology: AppStore.getCurrentTopology(),
|
||||
currentTopology: AppStore.getCurrentTopology(),
|
||||
connectionState: AppStore.getConnectionState(),
|
||||
currentGrouping: AppStore.getCurrentGrouping(),
|
||||
selectedNodeId: AppStore.getSelectedNodeId(),
|
||||
nodeDetails: AppStore.getNodeDetails(),
|
||||
nodes: TopologyStore.getNodes(),
|
||||
nodes: AppStore.getNodes(),
|
||||
topologies: AppStore.getTopologies()
|
||||
}
|
||||
}
|
||||
@@ -38,7 +37,6 @@ var App = React.createClass({
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
TopologyStore.on(TopologyStore.CHANGE_EVENT, this.onChange);
|
||||
AppStore.on(AppStore.CHANGE_EVENT, this.onChange);
|
||||
window.addEventListener('keyup', this.onKeyPress);
|
||||
|
||||
@@ -63,13 +61,12 @@ var App = React.createClass({
|
||||
<div>
|
||||
{showingDetails && <Details nodes={this.state.nodes}
|
||||
nodeId={this.state.selectedNodeId}
|
||||
details={this.state.nodeDetails}
|
||||
topology={this.state.activeTopology} /> }
|
||||
details={this.state.nodeDetails} /> }
|
||||
|
||||
<div className="header">
|
||||
<Logo />
|
||||
<Topologies topologies={this.state.topologies} active={this.state.activeTopology} />
|
||||
<Groupings active={this.state.currentGrouping} />
|
||||
<Topologies topologies={this.state.topologies} currentTopology={this.state.currentTopology} />
|
||||
<Groupings active={this.state.currentGrouping} currentTopology={this.state.currentTopology} />
|
||||
<Status connectionState={this.state.connectionState} />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ var IconButton = mui.IconButton;
|
||||
|
||||
var AppActions = require('../actions/app-actions');
|
||||
var NodeDetails = require('./node-details');
|
||||
var WebapiUtils = require('../utils/web-api-utils');
|
||||
|
||||
var Details = React.createClass({
|
||||
|
||||
|
||||
@@ -8,10 +8,12 @@ var AppStore = require('../stores/app-store');
|
||||
|
||||
var GROUPINGS = [{
|
||||
id: 'none',
|
||||
iconClass: 'fa fa-th'
|
||||
iconClass: 'fa fa-th',
|
||||
needsTopology: false
|
||||
}, {
|
||||
id: 'grouped',
|
||||
iconClass: 'fa fa-th-large'
|
||||
iconClass: 'fa fa-th-large',
|
||||
needsTopology: 'grouped_url'
|
||||
}];
|
||||
|
||||
var Groupings = React.createClass({
|
||||
@@ -21,22 +23,40 @@ var Groupings = React.createClass({
|
||||
AppActions.clickGrouping(ev.currentTarget.getAttribute('rel'));
|
||||
},
|
||||
|
||||
renderGrouping: function(grouping, active) {
|
||||
var className = grouping.id === active ? "groupings-item groupings-item-active" : "groupings-item";
|
||||
isGroupingSupportedByTopology: function(topology, grouping) {
|
||||
return !grouping.needsTopology || topology && topology[grouping.needsTopology];
|
||||
},
|
||||
|
||||
getGroupingsSupportedByTopology: function(topology) {
|
||||
return _.filter(GROUPINGS, _.partial(this.isGroupingSupportedByTopology, topology));
|
||||
},
|
||||
|
||||
renderGrouping: function(grouping, activeGroupingId) {
|
||||
var className = "groupings-item",
|
||||
isSupportedByTopology = this.isGroupingSupportedByTopology(this.props.currentTopology, grouping);
|
||||
|
||||
if (grouping.id === activeGroupingId) {
|
||||
className += " groupings-item-active";
|
||||
} else if (!isSupportedByTopology) {
|
||||
className += " groupings-item-disabled";
|
||||
} else {
|
||||
className += " groupings-item-default";
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={className} key={grouping.id} rel={grouping.id} onClick={this.onGroupingClick}>
|
||||
<div className={className} key={grouping.id} rel={grouping.id} onClick={isSupportedByTopology && this.onGroupingClick}>
|
||||
<span className={grouping.iconClass} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var activeGrouping = this.props.active;
|
||||
var activeGrouping = this.props.active,
|
||||
isGroupingSupported = _.size(this.getGroupingsSupportedByTopology(this.props.currentTopology)) > 1;
|
||||
|
||||
return (
|
||||
<div className="groupings">
|
||||
{GROUPINGS.map(function(grouping) {
|
||||
{isGroupingSupported && GROUPINGS.map(function(grouping) {
|
||||
return this.renderGrouping(grouping, activeGrouping);
|
||||
}, this)}
|
||||
</div>
|
||||
|
||||
@@ -14,8 +14,9 @@ var Topologies = React.createClass({
|
||||
},
|
||||
|
||||
renderTopology: function(topology, active) {
|
||||
var className = AppStore.isUrlForTopology(topology.url, active) ? "topologies-item topologies-item-active" : "topologies-item",
|
||||
topologyId = AppStore.getTopologyForUrl(topology.url),
|
||||
var isActive = topology.name === this.props.currentTopology.name,
|
||||
className = isActive ? "topologies-item topologies-item-active" : "topologies-item",
|
||||
topologyId = AppStore.getTopologyIdForUrl(topology.url),
|
||||
title = ['Topology: ' + topology.name,
|
||||
'Nodes: ' + topology.stats.node_count,
|
||||
'Connections: ' + topology.stats.node_count].join('\n');
|
||||
@@ -32,15 +33,14 @@ var Topologies = React.createClass({
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var activeTopologyId = this.props.active,
|
||||
topologies = _.sortBy(this.props.topologies, function(topology) {
|
||||
var topologies = _.sortBy(this.props.topologies, function(topology) {
|
||||
return topology.name;
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="topologies">
|
||||
{topologies.map(function(topology) {
|
||||
return this.renderTopology(topology, activeTopologyId);
|
||||
{this.props.currentTopology && topologies.map(function(topology) {
|
||||
return this.renderTopology(topology);
|
||||
}, this)}
|
||||
</div>
|
||||
);
|
||||
|
||||
61
client/app/scripts/stores/__tests__/app-store-test.js
Normal file
61
client/app/scripts/stores/__tests__/app-store-test.js
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
describe('AppStore', function() {
|
||||
|
||||
var ActionTypes = require('../../constants/action-types');
|
||||
var AppStore, registeredCallback;
|
||||
|
||||
// actions
|
||||
|
||||
var ClickTopologyAction = {
|
||||
type: ActionTypes.CLICK_TOPOLOGY,
|
||||
topologyId: 'topo1'
|
||||
};
|
||||
|
||||
var ClickGroupingAction = {
|
||||
type: ActionTypes.CLICK_GROUPING,
|
||||
grouping: 'grouped'
|
||||
};
|
||||
|
||||
var ReceiveTopologiesAction = {
|
||||
type: ActionTypes.RECEIVE_TOPOLOGIES,
|
||||
topologies: [{
|
||||
url: '/topo1',
|
||||
grouped_url: '/topo1grouped',
|
||||
name: 'Topo1'
|
||||
}]
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
AppStore = require('../app-store');
|
||||
registeredCallback = AppStore.registeredCallback;
|
||||
});
|
||||
|
||||
// topology tests
|
||||
|
||||
it('init with no topologies', function() {
|
||||
var topos = AppStore.getTopologies();
|
||||
expect(topos.length).toBe(0);
|
||||
expect(AppStore.getCurrentTopology()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('get current topology', function() {
|
||||
registeredCallback(ClickTopologyAction);
|
||||
registeredCallback(ReceiveTopologiesAction);
|
||||
|
||||
expect(AppStore.getTopologies().length).toBe(1);
|
||||
expect(AppStore.getCurrentTopology().name).toBe('Topo1');
|
||||
expect(AppStore.getCurrentTopologyUrl()).toBe('/topo1');
|
||||
});
|
||||
|
||||
it('get grouped topology', function() {
|
||||
registeredCallback(ClickTopologyAction);
|
||||
registeredCallback(ReceiveTopologiesAction);
|
||||
registeredCallback(ClickGroupingAction);
|
||||
|
||||
expect(AppStore.getTopologies().length).toBe(1);
|
||||
expect(AppStore.getCurrentTopology().name).toBe('Topo1');
|
||||
expect(AppStore.getCurrentTopologyUrl()).toBe('/topo1grouped');
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
@@ -5,15 +5,15 @@ var assign = require('object-assign');
|
||||
|
||||
var AppDispatcher = require('../dispatcher/app-dispatcher');
|
||||
var ActionTypes = require('../constants/action-types');
|
||||
var TopologyStore = require('./topology-store');
|
||||
// var topologies = require('../constants/topologies');
|
||||
|
||||
|
||||
// Initial values
|
||||
|
||||
var connectionState = 'disconnected';
|
||||
var currentGrouping = 'none';
|
||||
var currentTopology = 'applications';
|
||||
var currentTopologyId = 'applications';
|
||||
var mouseOverNode = null;
|
||||
var nodes = {};
|
||||
var nodeDetails = null;
|
||||
var selectedNodeId = null;
|
||||
var topologies = [];
|
||||
@@ -26,8 +26,8 @@ var AppStore = assign({}, EventEmitter.prototype, {
|
||||
|
||||
getAppState: function() {
|
||||
return {
|
||||
currentTopology: this.getCurrentTopology(),
|
||||
currentGrouping: this.getCurrentGrouping(),
|
||||
topologyId: currentTopologyId,
|
||||
grouping: this.getCurrentGrouping(),
|
||||
selectedNodeId: this.getSelectedNodeId()
|
||||
};
|
||||
},
|
||||
@@ -37,7 +37,17 @@ var AppStore = assign({}, EventEmitter.prototype, {
|
||||
},
|
||||
|
||||
getCurrentTopology: function() {
|
||||
return currentTopology;
|
||||
return _.find(topologies, function(topology) {
|
||||
return isUrlForTopologyId(topology.url, currentTopologyId);
|
||||
});
|
||||
},
|
||||
|
||||
getCurrentTopologyUrl: function() {
|
||||
var topology = this.getCurrentTopology();
|
||||
|
||||
if (topology) {
|
||||
return topology.grouped_url && currentGrouping == 'grouped' ? topology.grouped_url : topology.url;
|
||||
}
|
||||
},
|
||||
|
||||
getCurrentGrouping: function() {
|
||||
@@ -48,6 +58,10 @@ var AppStore = assign({}, EventEmitter.prototype, {
|
||||
return nodeDetails;
|
||||
},
|
||||
|
||||
getNodes: function() {
|
||||
return nodes;
|
||||
},
|
||||
|
||||
getSelectedNodeId: function() {
|
||||
return selectedNodeId;
|
||||
},
|
||||
@@ -56,40 +70,35 @@ var AppStore = assign({}, EventEmitter.prototype, {
|
||||
return topologies;
|
||||
},
|
||||
|
||||
getTopologyForUrl: function(url) {
|
||||
getTopologyIdForUrl: function(url) {
|
||||
return url.split('/').pop();
|
||||
},
|
||||
|
||||
getUrlForTopology: function(topologyId) {
|
||||
var topology = _.find(topologies, function(topology) {
|
||||
return this.isUrlForTopology(topology.url, topologyId);
|
||||
}, this);
|
||||
|
||||
if (topology) {
|
||||
return topology.grouped_url && currentGrouping == 'grouped' ? topology.grouped_url : topology.url;
|
||||
}
|
||||
},
|
||||
|
||||
isUrlForTopology: function(url, topologyId) {
|
||||
return _.endsWith(url, topologyId);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Helpers
|
||||
|
||||
function isUrlForTopologyId(url, topologyId) {
|
||||
return _.endsWith(url, topologyId);
|
||||
}
|
||||
|
||||
|
||||
// Store Dispatch Hooks
|
||||
|
||||
AppStore.dispatchToken = AppDispatcher.register(function(payload) {
|
||||
AppStore.registeredCallback = function(payload) {
|
||||
switch (payload.type) {
|
||||
|
||||
case ActionTypes.CLICK_CLOSE_DETAILS:
|
||||
selectedNodeId = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.CLICK_GROUPING:
|
||||
currentGrouping = payload.grouping;
|
||||
AppDispatcher.waitFor([TopologyStore.dispatchToken]);
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
if (payload.grouping !== currentGrouping) {
|
||||
currentGrouping = payload.grouping;
|
||||
nodes = {};
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
}
|
||||
break;
|
||||
|
||||
case ActionTypes.CLICK_NODE:
|
||||
@@ -98,8 +107,15 @@ AppStore.dispatchToken = AppDispatcher.register(function(payload) {
|
||||
break;
|
||||
|
||||
case ActionTypes.CLICK_TOPOLOGY:
|
||||
currentTopology = payload.topologyId;
|
||||
AppDispatcher.waitFor([TopologyStore.dispatchToken]);
|
||||
if (payload.topologyId !== currentTopologyId) {
|
||||
currentTopologyId = payload.topologyId;
|
||||
nodes = {};
|
||||
}
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.ENTER_NODE:
|
||||
mouseOverNode = payload.nodeId;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
@@ -109,14 +125,43 @@ AppStore.dispatchToken = AppDispatcher.register(function(payload) {
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.LEAVE_NODE:
|
||||
mouseOverNode = null;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_NODE_DETAILS:
|
||||
nodeDetails = payload.details;
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_NODES_DELTA:
|
||||
console.log('RECEIVE_NODES_DELTA',
|
||||
'remove', _.size(payload.delta.remove),
|
||||
'update', _.size(payload.delta.update),
|
||||
'add', _.size(payload.delta.add));
|
||||
|
||||
connectionState = "connected";
|
||||
AppDispatcher.waitFor([TopologyStore.dispatchToken]);
|
||||
|
||||
// nodes that no longer exist
|
||||
_.each(payload.delta.remove, function(nodeId) {
|
||||
// in case node disappears before mouseleave event
|
||||
if (mouseOverNode === nodeId) {
|
||||
mouseOverNode = null;
|
||||
}
|
||||
delete nodes[nodeId];
|
||||
});
|
||||
|
||||
// update existing nodes
|
||||
_.each(payload.delta.update, function(node) {
|
||||
nodes[node.id] = node;
|
||||
});
|
||||
|
||||
// add new nodes
|
||||
_.each(payload.delta.add, function(node) {
|
||||
nodes[node.id] = node;
|
||||
});
|
||||
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
@@ -126,10 +171,10 @@ AppStore.dispatchToken = AppDispatcher.register(function(payload) {
|
||||
break;
|
||||
|
||||
case ActionTypes.ROUTE_TOPOLOGY:
|
||||
currentTopology = payload.state.currentTopology;
|
||||
currentGrouping = payload.state.currentGrouping;
|
||||
nodes = {};
|
||||
currentTopologyId = payload.state.topologyId;
|
||||
currentGrouping = payload.state.grouping;
|
||||
selectedNodeId = payload.state.selectedNodeId;
|
||||
AppDispatcher.waitFor([TopologyStore.dispatchToken]);
|
||||
AppStore.emit(AppStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
@@ -137,6 +182,8 @@ AppStore.dispatchToken = AppDispatcher.register(function(payload) {
|
||||
break;
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
AppStore.dispatchToken = AppDispatcher.register(AppStore.registeredCallback);
|
||||
|
||||
module.exports = AppStore;
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var _ = require('lodash');
|
||||
var assign = require('object-assign');
|
||||
|
||||
var AppDispatcher = require('../dispatcher/app-dispatcher');
|
||||
var ActionTypes = require('../constants/action-types');
|
||||
|
||||
|
||||
|
||||
// Initial values
|
||||
|
||||
var nodes = {};
|
||||
var mouseOverNode = null;
|
||||
|
||||
// Store API
|
||||
|
||||
var TopologyStore = assign({}, EventEmitter.prototype, {
|
||||
|
||||
CHANGE_EVENT: 'change',
|
||||
|
||||
getNodes: function() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Store Dispatch Hooks
|
||||
|
||||
TopologyStore.dispatchToken = AppDispatcher.register(function(payload) {
|
||||
switch (payload.type) {
|
||||
case ActionTypes.CLICK_GROUPING:
|
||||
nodes = {};
|
||||
TopologyStore.emit(TopologyStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.CLICK_TOPOLOGY:
|
||||
nodes = {};
|
||||
TopologyStore.emit(TopologyStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.ENTER_NODE:
|
||||
mouseOverNode = payload.nodeId;
|
||||
TopologyStore.emit(TopologyStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.LEAVE_NODE:
|
||||
mouseOverNode = null;
|
||||
TopologyStore.emit(TopologyStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_NODES_DELTA:
|
||||
// nodes that no longer exist
|
||||
_.each(payload.delta.remove, function(nodeId) {
|
||||
// in case node disappears before mouseleave event
|
||||
if (mouseOverNode === nodeId) {
|
||||
mouseOverNode = null;
|
||||
}
|
||||
delete nodes[nodeId];
|
||||
});
|
||||
|
||||
// update existing nodes
|
||||
_.each(payload.delta.update, function(node) {
|
||||
nodes[node.id] = node;
|
||||
});
|
||||
|
||||
// add new nodes
|
||||
_.each(payload.delta.add, function(node) {
|
||||
nodes[node.id] = node;
|
||||
});
|
||||
|
||||
TopologyStore.emit(TopologyStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
case ActionTypes.ROUTE_TOPOLOGY:
|
||||
nodes = {};
|
||||
TopologyStore.emit(TopologyStore.CHANGE_EVENT);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = TopologyStore;
|
||||
@@ -1,8 +1,6 @@
|
||||
var reqwest = require('reqwest');
|
||||
|
||||
var TopologyActions = require('../actions/topology-actions');
|
||||
var AppActions = require('../actions/app-actions');
|
||||
var AppStore = require('../stores/app-store');
|
||||
|
||||
var WS_URL = window.WS_URL || 'ws://' + location.host;
|
||||
|
||||
@@ -33,7 +31,7 @@ function createWebsocket(topologyUrl) {
|
||||
socket.onmessage = function(event) {
|
||||
var msg = JSON.parse(event.data);
|
||||
if (msg.add || msg.remove || msg.update) {
|
||||
TopologyActions.receiveNodesDelta(msg);
|
||||
AppActions.receiveNodesDelta(msg);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -48,9 +46,9 @@ function getTopologies() {
|
||||
});
|
||||
}
|
||||
|
||||
function getNodeDetails(topology, nodeId) {
|
||||
if (nodeId) {
|
||||
var url = [AppStore.getUrlForTopology(topology), nodeId].join('/');
|
||||
function getNodeDetails(topologyUrl, nodeId) {
|
||||
if (topologyUrl && nodeId) {
|
||||
var url = [topologyUrl, nodeId].join('/');
|
||||
reqwest(url, function(res) {
|
||||
AppActions.receiveNodeDetails(res.node);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user