Skip to content

Commit

Permalink
Merge pull request #1167 from weaveworks/immutablejs-topology
Browse files Browse the repository at this point in the history
Make app-store's topologies object immutable
  • Loading branch information
davkal committed Mar 15, 2016
2 parents 77417ad + 3f8a26d commit a9d53bc
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 105 deletions.
2 changes: 1 addition & 1 deletion client/app/scripts/charts/__tests__/node-layout-test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
jest.dontMock('../nodes-layout');
jest.dontMock('../topology-utils');
jest.dontMock('../../utils/topology-utils');
jest.dontMock('../../constants/naming'); // edge naming: 'source-target'

import { fromJS, Map } from 'immutable';
Expand Down
2 changes: 1 addition & 1 deletion client/app/scripts/charts/nodes-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import debug from 'debug';
import { Map as makeMap, Set as ImmSet } from 'immutable';

import { EDGE_ID_SEPARATOR } from '../constants/naming';
import { updateNodeDegrees } from './topology-utils';
import { updateNodeDegrees } from '../utils/topology-utils';

const log = debug('scope:nodes-layout');

Expand Down
10 changes: 0 additions & 10 deletions client/app/scripts/charts/topology-utils.js

This file was deleted.

8 changes: 4 additions & 4 deletions client/app/scripts/components/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export default class Status extends React.Component {
classNames += ' status-loading';
showWarningIcon = true;
} else if (this.props.topology) {
const stats = this.props.topology.stats;
text = `${stats.node_count} nodes`;
if (stats.filtered_nodes) {
text = `${text} (${stats.filtered_nodes} filtered)`;
const stats = this.props.topology.get('stats');
text = `${stats.get('node_count')} nodes`;
if (stats.get('filtered_nodes')) {
text = `${text} (${stats.get('filtered_nodes')} filtered)`;
}
classNames += ' status-stats';
showWarningIcon = false;
Expand Down
30 changes: 13 additions & 17 deletions client/app/scripts/components/topologies.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import _ from 'lodash';

import { clickTopology } from '../actions/app-actions';

export default class Topologies extends React.Component {

constructor(props, context) {
super(props, context);
this.onTopologyClick = this.onTopologyClick.bind(this);
Expand All @@ -16,56 +16,52 @@ export default class Topologies extends React.Component {
}

renderSubTopology(subTopology) {
const isActive = subTopology.name === this.props.currentTopology.name;
const topologyId = subTopology.id;
const isActive = subTopology === this.props.currentTopology;
const topologyId = subTopology.get('id');
const title = this.renderTitle(subTopology);
const className = isActive ? 'topologies-sub-item topologies-sub-item-active' : 'topologies-sub-item';

return (
<div className={className} title={title} key={topologyId} rel={topologyId}
onClick={this.onTopologyClick}>
<div className="topologies-sub-item-label">
{subTopology.name}
{subTopology.get('name')}
</div>
</div>
);
}

renderTitle(topology) {
return ['Nodes: ' + topology.stats.node_count,
'Connections: ' + topology.stats.node_count].join('\n');
return ['Nodes: ' + topology.getIn(['stats', 'node_count']),
'Connections: ' + topology.getIn(['stats', 'node_count'])].join('\n');
}

renderTopology(topology) {
const isActive = topology.name === this.props.currentTopology.name;
const isActive = topology === this.props.currentTopology;
const className = isActive ? 'topologies-item-main topologies-item-main-active' : 'topologies-item-main';
const topologyId = topology.id;
const topologyId = topology.get('id');
const title = this.renderTitle(topology);

return (
<div className="topologies-item" key={topologyId}>
<div className={className} title={title} rel={topologyId} onClick={this.onTopologyClick}>
<div className="topologies-item-label">
{topology.name}
{topology.get('name')}
</div>
</div>
<div className="topologies-sub">
{topology.sub_topologies && topology.sub_topologies.map(this.renderSubTopology)}
{topology.has('sub_topologies') && topology.get('sub_topologies').map(this.renderSubTopology)}
</div>
</div>
);
}

render() {
const topologies = _.sortBy(this.props.topologies, function(topology) {
return topology.rank;
});

return (
<div className="topologies">
{this.props.currentTopology && topologies.map(function(topology) {
return this.renderTopology(topology);
}, this)}
{this.props.currentTopology && this.props.topologies.map(
topology => this.renderTopology(topology)
)}
</div>
);
}
Expand Down
30 changes: 12 additions & 18 deletions client/app/scripts/components/topology-options.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import _ from 'lodash';

import TopologyOptionAction from './topology-option-action';

Expand All @@ -21,26 +20,26 @@ export default class TopologyOptions extends React.Component {
const actions = [];
const activeOptions = this.props.activeOptions;
const topologyId = this.props.topologyId;
const option = items[0].option;
const option = items.first().get('option');

// find active option value
if (activeOptions && activeOptions.has(option)) {
activeValue = activeOptions.get(option);
} else {
// get default value
items.forEach(function(item) {
if (item.default) {
activeValue = item.value;
if (item.get('default')) {
activeValue = item.get('value');
}
});
}

// render active option as text, add other options as actions
items.forEach(function(item) {
if (item.value === activeValue) {
activeText = item.display;
if (item.get('value') === activeValue) {
activeText = item.get('display');
} else {
actions.push(this.renderAction(item.value, item.option, topologyId));
actions.push(this.renderAction(item.get('value'), item.get('option'), topologyId));
}
}, this);

Expand All @@ -55,20 +54,15 @@ export default class TopologyOptions extends React.Component {
}

render() {
const options = _.sortBy(
_.map(this.props.options, function(items, optionId) {
_.each(items, function(item) {
item.option = optionId;
});
items.option = optionId;
return items;
}),
'option'
);
const options = this.props.options.map((items, optionId) => {
let itemsMap = items.map(item => item.set('option', optionId));
itemsMap = itemsMap.set('option', optionId);
return itemsMap;
});

return (
<div className="topology-options">
{options.map(function(items) {
{options.toIndexedSeq().map(function(items) {
return this.renderOption(items);
}, this)}
</div>
Expand Down
19 changes: 10 additions & 9 deletions client/app/scripts/stores/__tests__/app-store-test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
jest.dontMock('../../utils/topology-utils');
jest.dontMock('../../constants/action-types');
jest.dontMock('../app-store');

Expand Down Expand Up @@ -160,28 +161,28 @@ describe('AppStore', function() {

it('init with no topologies', function() {
const topos = AppStore.getTopologies();
expect(topos.length).toBe(0);
expect(topos.size).toBe(0);
expect(AppStore.getCurrentTopology()).toBeUndefined();
});

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

expect(AppStore.getTopologies().length).toBe(2);
expect(AppStore.getCurrentTopology().name).toBe('Topo1');
expect(AppStore.getTopologies().size).toBe(2);
expect(AppStore.getCurrentTopology().get('name')).toBe('Topo1');
expect(AppStore.getCurrentTopologyUrl()).toBe('/topo1');
expect(AppStore.getCurrentTopologyOptions().option1).toBeDefined();
expect(AppStore.getCurrentTopologyOptions().get('option1')).toBeDefined();
});

it('get sub-topology', function() {
registeredCallback(ReceiveTopologiesAction);
registeredCallback(ClickSubTopologyAction);

expect(AppStore.getTopologies().length).toBe(2);
expect(AppStore.getCurrentTopology().name).toBe('topo 1 grouped');
expect(AppStore.getTopologies().size).toBe(2);
expect(AppStore.getCurrentTopology().get('name')).toBe('topo 1 grouped');
expect(AppStore.getCurrentTopologyUrl()).toBe('/topo1-grouped');
expect(AppStore.getCurrentTopologyOptions()).toBeUndefined();
expect(AppStore.getCurrentTopologyOptions().size).toBe(0);
});

// topology options
Expand Down Expand Up @@ -402,7 +403,7 @@ describe('AppStore', function() {
it('selectes relatives topology while keeping node selected', function() {
registeredCallback(ClickTopologyAction);
registeredCallback(ReceiveTopologiesAction);
expect(AppStore.getCurrentTopology().name).toBe('Topo1');
expect(AppStore.getCurrentTopology().get('name')).toBe('Topo1');

registeredCallback(ClickNodeAction);
expect(AppStore.getSelectedNodeId()).toBe('n1');
Expand All @@ -422,6 +423,6 @@ describe('AppStore', function() {
expect(AppStore.getSelectedNodeId()).toBe('rel1');
expect(AppStore.getNodeDetails().keySeq().last()).toEqual('rel1');
expect(AppStore.getNodeDetails().size).toEqual(1);
expect(AppStore.getCurrentTopology().name).toBe('Topo2');
expect(AppStore.getCurrentTopology().get('name')).toBe('Topo2');
});
});
Loading

0 comments on commit a9d53bc

Please sign in to comment.