diff --git a/client/app/scripts/actions/app-actions.js b/client/app/scripts/actions/app-actions.js index badb484d1..ae25c8770 100644 --- a/client/app/scripts/actions/app-actions.js +++ b/client/app/scripts/actions/app-actions.js @@ -174,13 +174,14 @@ export function blurSearch() { return { type: ActionTypes.BLUR_SEARCH }; } -export function changeTopologyOption(option, value, topologyId) { +export function changeTopologyOption(option, value, topologyId, addOrRemove) { return (dispatch, getState) => { dispatch({ type: ActionTypes.CHANGE_TOPOLOGY_OPTION, topologyId, option, - value + value, + addOrRemove }); updateRoute(getState); // update all request workers with new options diff --git a/client/app/scripts/components/topology-options.js b/client/app/scripts/components/topology-options.js index f6cd8724e..c4276c28e 100644 --- a/client/app/scripts/components/topology-options.js +++ b/client/app/scripts/components/topology-options.js @@ -18,13 +18,9 @@ class TopologyOptions extends React.Component { const selectedOption = options.find(o => o.get('id') === optionId); if (selectedOption.get('selectType') === 'union') { - if (activeOptions.get(selectedOption.get('id')).includes(value)) { - // Option already exists; user is de-selecting - console.log('TODO! removeOption action'); - } else { - // Option does not exist; user is enabling. - console.log('TODO! addOption action'); - } + const isSelectedAlready = activeOptions.get(selectedOption.get('id')).includes(value); + const addOrRemove = isSelectedAlready ? 'remove' : 'add'; + this.props.changeTopologyOption(optionId, value, topologyId, addOrRemove); } else { this.props.changeTopologyOption(optionId, value, topologyId); } diff --git a/client/app/scripts/reducers/__tests__/root-test.js b/client/app/scripts/reducers/__tests__/root-test.js index 7d5e9e002..ec7993be7 100644 --- a/client/app/scripts/reducers/__tests__/root-test.js +++ b/client/app/scripts/reducers/__tests__/root-test.js @@ -368,22 +368,32 @@ describe('RootReducer', () => { it('adds/removes a topology option', () => { const addAction = { - type: ActionTypes.ADD_TOPOLOGY_OPTION, + type: ActionTypes.CHANGE_TOPOLOGY_OPTION, topologyId: 'services', option: 'namespace', - value: 'scope' + value: 'scope', + addOrRemove: 'add' }; const removeAction = { - type: ActionTypes.REMOVE_TOPOLOGY_OPTION, + type: ActionTypes.CHANGE_TOPOLOGY_OPTION, topologyId: 'services', option: 'namespace', - value: 'scope' + value: 'scope', + addOrRemove: 'remove' }; let nextState = initialState; nextState = reducer(nextState, { type: ActionTypes.RECEIVE_TOPOLOGIES, topologies}); nextState = reducer(nextState, { type: ActionTypes.CLICK_TOPOLOGY, topologyId: 'services' }); - nextState = reducer(nextState, addAction); + expect(activeTopologyOptionsSelector(nextState).toJS()).toEqual({ + namespace: ['default', 'scope'], + pseudo: ['hide'] + }); + nextState = reducer(nextState, removeAction); + expect(activeTopologyOptionsSelector(nextState).toJS()).toEqual({ + namespace: ['default'], + pseudo: ['hide'] + }); }); it('sets topology options from route', () => { diff --git a/client/app/scripts/reducers/root.js b/client/app/scripts/reducers/root.js index 536d5a3f2..3e673e837 100644 --- a/client/app/scripts/reducers/root.js +++ b/client/app/scripts/reducers/root.js @@ -1,6 +1,6 @@ /* eslint-disable import/no-webpack-loader-syntax, import/no-unresolved */ import debug from 'debug'; -import { size, each, includes } from 'lodash'; +import { size, each, includes, isEqual } from 'lodash'; import { fromJS, is as isDeepEqual, List as makeList, Map as makeMap, OrderedMap as makeOrderedMap, Set as makeSet } from 'immutable'; @@ -194,15 +194,21 @@ export function rootReducer(state = initialState, action) { // set option on parent topology const topology = findTopologyById(state.get('topologies'), action.topologyId); if (topology) { + let values = [action.value]; const topologyId = topology.get('parentId') || topology.get('id'); + const optionKey = ['topologyOptions', topologyId, action.option]; const currentOption = state.getIn(['topologyOptions', topologyId, action.option]); - if (currentOption !== action.value) { + + if (!isEqual(currentOption, action.value)) { state = clearNodes(state); } - state = state.setIn( - ['topologyOptions', topologyId, action.option], - [action.value] - ); + + if (action.addOrRemove === 'add') { + values = state.getIn(optionKey).concat(values); + } else if (action.addOrRemove === 'remove') { + values = state.getIn(optionKey).filter(o => !values.includes(o)); + } + state = state.setIn(optionKey, values); } return state; }