Skip to content

Commit

Permalink
Fix grouping bar for topologies that don't support grouping
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
davkal authored and Tom Wilkie committed May 22, 2015
1 parent 65cfe63 commit 0ff6334
Show file tree
Hide file tree
Showing 20 changed files with 260 additions and 233 deletions.
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ client/dist/scripts/bundle.js: client/app/scripts/*
mkdir -p client/dist
docker run -ti -v $(shell pwd)/client/app:/home/weave/app \
-v $(shell pwd)/client/dist:/home/weave/dist \
$(SCOPE_UI_BUILD_IMAGE)
$(SCOPE_UI_BUILD_IMAGE) gulp build

client-test: client/test/*
docker run -ti -v $(shell pwd)/client/app:/home/weave/app \
-v $(shell pwd)/client/test:/home/weave/test \
$(SCOPE_UI_BUILD_IMAGE) npm test

$(SCOPE_UI_BUILD_EXPORT): client/Dockerfile client/gulpfile.js client/package.json
docker build -t $(SCOPE_UI_BUILD_IMAGE) client
Expand Down
1 change: 1 addition & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ test:
- cd $SRCDIR; make static
- cd $SRCDIR; make
- cd $SRCDIR; ./bin/test
- cd $SRCDIR; make client-test
post:
- goveralls -repotoken $COVERALLS_REPO_TOKEN -coverprofile=$SRCDIR/profile.cov -service=circleci || true
- cd $SRCDIR; cp coverage.html $CIRCLE_ARTIFACTS
Expand Down
10 changes: 4 additions & 6 deletions client/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ FROM mhart/alpine-node

WORKDIR /home/weave

# jest-cli requires python, make and g++
RUN apk --update add python make g++

# build tool
RUN npm install -g gulp

Expand All @@ -11,9 +14,4 @@ RUN npm install

ADD gulpfile.js /home/weave/

# run container via
#
# `docker run -v $GOPATH/src/github.com/weaveworks/scope/client:/app weaveworks/scope-build`
#
# after the container is run, bundled app should be in ./dist/ dir
CMD gulp build
# For instructions on running this container, consult the toplevel Makefile
35 changes: 28 additions & 7 deletions client/app/scripts/actions/app-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module.exports = {
grouping: grouping
});
RouterUtils.updateRoute();
WebapiUtils.getNodesDelta(AppStore.getUrlForTopology(AppStore.getCurrentTopology()));
WebapiUtils.getNodesDelta(AppStore.getCurrentTopologyUrl());
},

clickNode: function(nodeId) {
Expand All @@ -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) {
Expand All @@ -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() {
Expand All @@ -43,29 +50,43 @@ 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,
details: details
});
},

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) {
AppDispatcher.dispatch({
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());
}
};

Expand Down
25 changes: 0 additions & 25 deletions client/app/scripts/actions/topology-actions.js

This file was deleted.

13 changes: 5 additions & 8 deletions client/app/scripts/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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()
}
}
Expand All @@ -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);

Expand All @@ -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>

Expand Down
1 change: 0 additions & 1 deletion client/app/scripts/components/details.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({

Expand Down
34 changes: 27 additions & 7 deletions client/app/scripts/components/groupings.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -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>
Expand Down
12 changes: 6 additions & 6 deletions client/app/scripts/components/topologies.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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>
);
Expand Down
65 changes: 65 additions & 0 deletions client/app/scripts/stores/__tests__/app-store-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
jest.dontMock('../app-store');
jest.dontMock('../../constants/action-types');

describe('AppStore', function() {

var ActionTypes = require('../../constants/action-types');
var AppStore, AppDispatcher, callback;

// 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');
AppDispatcher = require('../../dispatcher/app-dispatcher');
callback = AppDispatcher.register.mock.calls[0][0];
});

// topology tests

it('init with no topologies', function() {
expect(AppDispatcher.register.mock.calls.length).toBe(1);
var topos = AppStore.getTopologies();
expect(topos.length).toBe(0);
expect(AppStore.getCurrentTopology()).toBeUndefined();
});

it('get current topology', function() {
callback(ClickTopologyAction);
callback(ReceiveTopologiesAction);

expect(AppStore.getTopologies().length).toBe(1);
expect(AppStore.getCurrentTopology().name).toBe('Topo1');
expect(AppStore.getCurrentTopologyUrl()).toBe('/topo1');
});

it('get grouped topology', function() {
callback(ClickTopologyAction);
callback(ReceiveTopologiesAction);
callback(ClickGroupingAction);

expect(AppStore.getTopologies().length).toBe(1);
expect(AppStore.getCurrentTopology().name).toBe('Topo1');
expect(AppStore.getCurrentTopologyUrl()).toBe('/topo1grouped');
});


});

0 comments on commit 0ff6334

Please sign in to comment.