diff options
author | Koren Lev <korenlev@gmail.com> | 2017-07-27 16:42:15 +0300 |
---|---|---|
committer | Koren Lev <korenlev@gmail.com> | 2017-07-27 16:42:15 +0300 |
commit | b88c78e3cf2bef22aa2f1c4d0bf305e303bc15f0 (patch) | |
tree | ffa30a6e1511d72562d8772b8700cda52b2752a1 /ui/imports/ui/reducers | |
parent | b70483739d1f6f4f0d31987ed2e4d1e30d71d579 (diff) |
adding calipso ui
Change-Id: Ifa6f63daebb07f45580f747341960e898fdb00c4
Signed-off-by: Koren Lev <korenlev@gmail.com>
Diffstat (limited to 'ui/imports/ui/reducers')
-rw-r--r-- | ui/imports/ui/reducers/environment-panel.reducer.js | 194 | ||||
-rw-r--r-- | ui/imports/ui/reducers/graph-tooltip-window.reducer.js | 48 | ||||
-rw-r--r-- | ui/imports/ui/reducers/i18n.reducer.js | 180 | ||||
-rw-r--r-- | ui/imports/ui/reducers/index.js | 33 | ||||
-rw-r--r-- | ui/imports/ui/reducers/main-app.reducer.js | 28 | ||||
-rw-r--r-- | ui/imports/ui/reducers/navigation.js | 99 | ||||
-rw-r--r-- | ui/imports/ui/reducers/search-interested-parties.js | 76 | ||||
-rw-r--r-- | ui/imports/ui/reducers/tree-node.reducer.js | 232 | ||||
-rw-r--r-- | ui/imports/ui/reducers/vedge-info-window.reducer.js | 50 |
9 files changed, 940 insertions, 0 deletions
diff --git a/ui/imports/ui/reducers/environment-panel.reducer.js b/ui/imports/ui/reducers/environment-panel.reducer.js new file mode 100644 index 0000000..bac0e72 --- /dev/null +++ b/ui/imports/ui/reducers/environment-panel.reducer.js @@ -0,0 +1,194 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import * as R from 'ramda'; + +import * as actions from '/imports/ui/actions/environment-panel.actions'; +import { reducer as treeNode } from './tree-node.reducer'; +import { + updateTreeNodeInfo, + addUpdateChildrenTreeNode, + resetTreeNodeChildren, + startOpenTreeNode, + endOpenTreeNode, + startCloseTreeNode, + endCloseTreeNode, + setChildDetectedTreeNode, + setPositionReportIsNeededAsOn, + reportNodePositionRetrieved, + setScrollToNodeIsNeededAsOn, + reportScrollToNodePerformed, + resetNeedChildDetection, +} + from '/imports/ui/actions/tree-node.actions'; + +const defaultState = { + _id: null, + envName: null, + isLoaded: false, + treeNode: treeNode(), + selectedNode: { + _id: null, + type: null + }, + showType: 'dashboard' +}; + +let newState; + +export function reducer(state = defaultState, action) { + switch (action.type) { + case actions.SET_ENV_NAME: + return R.assoc('envName', action.payload.envName, state); + + case actions.UPDATE_ENV_TREE_NODE: + return R.assoc('treeNode', + treeNode(state.treeNode, + updateTreeNodeInfo(action.payload.nodeInfo, 0)), + state); + + case actions.ADD_UPDATE_CHILDREN_ENV_TREE_NODE: + return R.assoc('treeNode', + treeNode(state.treeNode, + addUpdateChildrenTreeNode(action.payload.nodePath, action.payload.childrenInfo, 0)), + state); + + case actions.RESET_ENV_TREE_NODE_CHILDREN: + return R.assoc('treeNode', + treeNode(state.treeNode, resetTreeNodeChildren(action.payload.nodePath)), + state + ); + + case actions.START_OPEN_ENV_TREE_NODE: + return R.assoc('treeNode', + treeNode(state.treeNode, startOpenTreeNode(action.payload.nodePath)), + state + ); + + case actions.END_OPEN_ENV_TREE_NODE: + return R.assoc('treeNode', + treeNode(state.treeNode, endOpenTreeNode(action.payload.nodePath)), + state + ); + + case actions.START_CLOSE_ENV_TREE_NODE: + return R.assoc('treeNode', + treeNode(state.treeNode, startCloseTreeNode(action.payload.nodePath)), + state + ); + + case actions.END_CLOSE_ENV_TREE_NODE: + return R.assoc('treeNode', + treeNode(state.treeNode, endCloseTreeNode(action.payload.nodePath)), + state + ); + + case actions.SET_ENV_CHILD_DETECTED_TREE_NODE: + return R.assoc('treeNode', + treeNode(state.treeNode, setChildDetectedTreeNode(action.payload.nodePath)), + state + ); + + case actions.SET_ENV_SELECTED_NODE: + if (R.pathEq(['selectedNode', '_id'], action.payload.nodeId, state) && + R.pathEq(['selectedNode', 'type'], action.payload.nodeType) + ) { + return state; + } + + return R.merge(state, { + selectedNode: { + _id: action.payload.nodeId, + type: action.payload.nodeType + } + }); + + case actions.SET_ENV_SELECTED_NODE_INFO: + newState = R.merge(state, { + selectedNode: R.merge(state.selectedNode, { + type: action.payload.nodeInfo.type, + clique: action.payload.nodeInfo.clique, + id_path: action.payload.nodeInfo.id_path + }) + }); + + if (! R.isNil(action.payload.nodeInfo.clique)) { + newState = R.assoc('showType', 'graph', newState); + } + + return newState; + + case actions.SET_ENV_SELECTED_NODE_AS_ENV: + return R.merge(state, { + selectedNode: { + _id: state._id, + type: 'environment' + } + }); + + case actions.SET_ENV_ENV_ID: + return R.assoc('_id', action.payload._id, state); + + case actions.SET_ENV_AS_LOADED: + return R.assoc('isLoaded', true, state); + + case actions.SET_ENV_AS_NOT_LOADED: + return R.assoc('isLoaded', false, state); + + case actions.SET_SHOW_DASHBOARD: + return R.assoc('showType', 'dashboard', state); + + case actions.SET_SHOW_GRAPH: + return R.assoc('showType', 'graph', state); + + case actions.TOGGLE_ENV_SHOW: + return R.pipe( + R.ifElse(R.equals('dashboard'), + R.always('graph'), + R.always('dashboard')), + R.assoc('showType', R.__, state) + )(state.showType); + + case actions.SET_ENV_POSITION_REPORT_IS_NEEDED_AS_ON: + return R.assoc('treeNode', + treeNode(state.treeNode, setPositionReportIsNeededAsOn(action.payload.nodePath)), + state + ); + + case actions.REPORT_ENV_NODE_POSITION_RETRIEVED: + return R.assoc('treeNode', + treeNode(state.treeNode, reportNodePositionRetrieved( + action.payload.nodePath, action.payload.rect)), + state + ); + + case actions.SET_ENV_SCROLL_TO_NODE_IS_NEEDED_AS_ON: + return R.assoc('treeNode', + treeNode(state.treeNode, setScrollToNodeIsNeededAsOn( + action.payload.nodePath)), + state + ); + + case actions.REPORT_ENV_SCROLL_TO_NODE_PERFORMED: + return R.assoc('treeNode', + treeNode(state.treeNode, reportScrollToNodePerformed( + action.payload.nodePath)), + state + ); + + case actions.RESET_ENV_NEED_CHILD_DETECTION: + return R.assoc('treeNode', + treeNode(state.treeNode, resetNeedChildDetection( + action.payload.nodePath)), + state + ); + + default: + return state; + } +} diff --git a/ui/imports/ui/reducers/graph-tooltip-window.reducer.js b/ui/imports/ui/reducers/graph-tooltip-window.reducer.js new file mode 100644 index 0000000..67f96f1 --- /dev/null +++ b/ui/imports/ui/reducers/graph-tooltip-window.reducer.js @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import * as R from 'ramda'; + +import * as actions from '/imports/ui/actions/graph-tooltip-window.actions'; + +const defaultState = { + label: '', + title: '', + left: 0, + top: 0, + show: false +}; + +export function reducer(state = defaultState, action) { + let attrsStr; + switch (action.type) { + case actions.ACTIVATE_GRAPH_TOOLTIP_WINDOW: + attrsStr = JSON.stringify(action.payload.attributes, null, 4) + .toString() + .replace(/\,/g,'<BR>') + .replace(/\[/g,'') + .replace(/\]/g,'') + .replace(/\{/g,'') + .replace(/\}/g,'') + .replace(/"/g,''); + + return R.merge(state, { + label: action.payload.label, + title: attrsStr, + left: action.payload.left, + top: action.payload.top - 28, + show: true + }); + + case actions.CLOSE_GRAPH_TOOLTIP_WINDOW: + return R.assoc('show', false, state); + + default: + return state; + } +} diff --git a/ui/imports/ui/reducers/i18n.reducer.js b/ui/imports/ui/reducers/i18n.reducer.js new file mode 100644 index 0000000..8771aad --- /dev/null +++ b/ui/imports/ui/reducers/i18n.reducer.js @@ -0,0 +1,180 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +//import * as R from 'ramda'; + +const defaultState = { + apis: { + + }, + collections: { + environments: { + fields: { + eventBasedScan: { + header: 'Event based scan', + desc: 'Update the inventory in real-time whenever a user makes a change to the OpenStack environment' + } + } + } + }, + components: { + environment: { + noGraphForLeafMsg: 'No clique for this focal_point', + briefInfos: { + lastScanning: { + header: 'Last scanning' + }, + vConnectorsNum: { + header: 'Number of vConnectors' + }, + hostsNum: { + header: 'Number of hosts' + }, + vServicesNum: { + header: 'Number of vServices' + }, + instancesNum: { + header: 'Number of instances' + } + }, + listInfoBoxes: { + regions: { + header: 'Regions' + }, + projects: { + header: 'Projects' + } + } + }, + projectDashboard: { + infoBoxes: { + networks: { + header: 'Number of networks' + }, + ports: { + header: 'Number of ports' + } + } + }, + + regionDashboard: { + infoBoxes: { + instances: { + header: 'Number of instances' + }, + vServices: { + header: 'Number of vServices' + }, + hosts: { + header: 'Number of hosts' + }, + vConnectors: { + header: 'Number of vConnectors' + } + }, + listInfoBoxes: { + availabilityZones: { + header: 'Availability zones' + }, + aggregates: { + header: 'Aggregates' + } + } + }, + + zoneDashboard: { + infoBoxes: { + instances: { + header: 'Number of instances' + }, + vServices: { + header: 'Number of vServices' + }, + hosts: { + header: 'Number of hosts' + }, + vConnectors: { + header: 'Number of vConnectors' + }, + vEdges: { + header: 'Number of vEdges' + } + }, + listInfoBoxes: { + hosts: { + header: 'Hosts' + }, + } + }, + + aggregateDashboard: { + infoBoxes: { + instances: { + header: 'Number of instances' + }, + vServices: { + header: 'Number of vServices' + }, + hosts: { + header: 'Number of hosts' + }, + vConnectors: { + header: 'Number of vConnectors' + }, + vEdges: { + header: 'Number of vEdges' + } + }, + listInfoBoxes: { + hosts: { + header: 'Hosts' + }, + } + }, + + hostDashboard: { + infoBoxes: { + instances: { + header: 'Number of instances' + }, + vServices: { + header: 'Number of vServices' + }, + vConnectors: { + header: 'Number of vConnectors' + }, + networkAgents: { + header: 'Number of agents' + }, + pnics: { + header: 'Number of pnics' + }, + vEdges: { + header: 'Number of vEdges' + }, + ports: { + header: 'Number of ports' + } + }, + }, + + generalFolderNodeDashboard: { + mainCubic: { + header: 'Number of children' + } + } + } +}; + +export function reducer(state = defaultState, action) { + switch (action.type) { + + default: + return state; + } +} diff --git a/ui/imports/ui/reducers/index.js b/ui/imports/ui/reducers/index.js new file mode 100644 index 0000000..6ee909d --- /dev/null +++ b/ui/imports/ui/reducers/index.js @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import { combineReducers } from 'redux'; + +import { navigation } from './navigation'; +import { searchInterestedParties } from './search-interested-parties'; +import { reducer as environmentPanel } from './environment-panel.reducer'; +import { reducer as i18n } from './i18n.reducer'; +import { reducer as graphTooltipWindow } from './graph-tooltip-window.reducer'; +import { reducer as vedgeInfoWindow } from './vedge-info-window.reducer'; +import { reducer as mainApp } from './main-app.reducer'; + +const calipsoApp = combineReducers({ + api: combineReducers({ + navigation, + searchInterestedParties, + i18n + }), + components: combineReducers({ + mainApp: mainApp, + environmentPanel, + graphTooltipWindow, + vedgeInfoWindow + }) +}); + +export default calipsoApp; diff --git a/ui/imports/ui/reducers/main-app.reducer.js b/ui/imports/ui/reducers/main-app.reducer.js new file mode 100644 index 0000000..abc4574 --- /dev/null +++ b/ui/imports/ui/reducers/main-app.reducer.js @@ -0,0 +1,28 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import * as R from 'ramda'; + +import * as actions from '/imports/ui/actions/main-app.actions'; + +const defaultState = { + selectedEnvironment: {}, +}; + +export function reducer(state = defaultState, action) { + switch (action.type) { + case actions.SET_MAIN_APP_SELECTED_ENVIRONMENT: + return R.assoc('selectedEnvironment', { + _id: action.payload._id, + name: action.payload.name + }, state); + + default: + return state; + } +} diff --git a/ui/imports/ui/reducers/navigation.js b/ui/imports/ui/reducers/navigation.js new file mode 100644 index 0000000..de78ee5 --- /dev/null +++ b/ui/imports/ui/reducers/navigation.js @@ -0,0 +1,99 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import * as R from 'ramda'; + +import * as actions from '/imports/ui/actions/navigation'; + +const defaultState = { current: [], lastActionable: [] }; + +function reducer(state = defaultState, action) { + let lastActionable = null; + + switch (action.type) { + case actions.SET_CURRENT_NODE: + lastActionable = isActionable(action.payload.nodeChain) ? action.payload.nodeChain : + state.lastActionable; + + return R.merge(state, { + current: action.payload.nodeChain, + lastActionable: lastActionable + }); + + case actions.SET_CURRENT_NODE_FROM_TREE_CONTROL: + lastActionable = isActionable(action.payload.nodeChain) ? action.payload.nodeChain : + state.lastActionable; + + if (contains(action.payload.nodeChain, state.current)) { + let equalLastIndex = findEqualLastIndex(action.payload.nodeChain, state.current); + return R.merge(state, { + current: R.slice(0, equalLastIndex, action.payload.nodeChain), + lastActionable: lastActionable + }); + } else { + return R.merge(state, { + current: action.payload.nodeChain, + lastActionable: lastActionable + }); + } + + default: + return state; + } +} + +function contains(subArray, array) { + let equalLastIndex = findEqualLastIndex(subArray, array); + + if (subArray.length <= array.length && + equalLastIndex >= 0 && + subArray.length === equalLastIndex + 1) { + + return true; + } + + return false; +} + +function findEqualLastIndex (arrayA, arrayB) { + let indexResult = -1; + + for (let i = 0; (i < arrayA.length) && (i < arrayB.length); i++) { + if (equalsNodes(arrayA[i], arrayB[i])) { + indexResult = i; + } else { + break; + } + } + + return indexResult; +} + +function equalsNodes(nodeA, nodeB) { + if (nodeA.fullIdPath !== nodeB.fullIdPath) { return false; } + if (nodeA.fullNamePath !== nodeB.fullNamePath) { return false; } + + return true; +} + +function isActionable(nodeChain) { + let last = R.last(nodeChain); + + if (R.isNil(last)) { return false; } + if (R.isNil(last.item)) { return false; } + + if (! R.isNil(last.item.clique)) { return true; } + + if (last.item.id === 'aggregate-WebEx-RTP-SSD-Aggregate-node-24') { + return true; + } + + return false; +} + +export const navigation = reducer; diff --git a/ui/imports/ui/reducers/search-interested-parties.js b/ui/imports/ui/reducers/search-interested-parties.js new file mode 100644 index 0000000..26220c2 --- /dev/null +++ b/ui/imports/ui/reducers/search-interested-parties.js @@ -0,0 +1,76 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import * as R from 'ramda'; + +import * as actions from '/imports/ui/actions/search-interested-parties'; + +const defaultState = { + listeners: [], + searchTerm: null, + searchAutoCompleteTerm: null, + searchAutoCompleteFutureId: null +}; + +function reducer(state = defaultState, action) { + let newListeners; + + switch (action.type) { + case actions.ADD_SEARCH_INTERESTED_PARTY: + newListeners = R.unionWith( + R.eqBy(R.prop('action')), + state.listeners, + [{ action: action.payload.listener }]); + return R.assoc('listeners', newListeners, state); + + case actions.REMOVE_SEARCH_INTERESTED_PARTY: + newListeners = R.differenceWith( + R.eqBy(R.prop('action')), + state.listeners, + [{ action:action.payload.listener }]); + return R.assoc('listeners', newListeners, state); + + case actions.SET_SEARCH_TERM: + asyncCall(() => { + notifyListeners(action.payload.searchTerm, state.listeners); + }); + return R.assoc('searchTerm', action.payload.searchTerm, state); + + case actions.SET_SEARCH_AUTO_COMPLETE_TERM: + return R.assoc('searchAutoCompleteTerm', action.payload.searchTerm, state); + + case actions.RESET_SEARCH_AUTO_COMPLETE_FUTURE: + if (! R.isNil(state.searchAutoCompleteFutureId)) { + clearTimeout(state.searchAutoCompleteFutureId); + } + return R.assoc('searchAutoCompleteFutureId', null, state); + + case actions.SET_SEARCH_AUTO_COMPLETE_FUTURE: + if (! R.isNil(state.searchAutoCompleteFutureId)) { + clearTimeout(state.searchAutoCompleteFutureId); + } + return R.assoc('searchAutoCompleteFutureId', action.payload.futureId, state); + + default: + return state; + } +} + +function asyncCall(fnObject) { + setTimeout(() => { + fnObject.call(null); + }, 0); +} + +function notifyListeners(searchTerm, listeners) { + R.forEach((listenerItem) => { + listenerItem.action.call(null, searchTerm); + }, listeners); +} + +export const searchInterestedParties = reducer; diff --git a/ui/imports/ui/reducers/tree-node.reducer.js b/ui/imports/ui/reducers/tree-node.reducer.js new file mode 100644 index 0000000..0a6ec73 --- /dev/null +++ b/ui/imports/ui/reducers/tree-node.reducer.js @@ -0,0 +1,232 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +//import { Mongo } from 'meteor/mongo'; +import * as R from 'ramda'; + +import * as actions from '/imports/ui/actions/tree-node.actions'; + +const defaultState = { + _id: null, + nodeInfo: {}, + openState: 'closed', // opened, start_close, closed, start_open + children: [], + childDetected: false, + needChildDetection: true, + linkDetected: false, + level: 1, + positionNeeded: false, + position: null, + scrollToNodeIsNeeded: false +}; + +export function reducer(state = defaultState, action) { + let nodeId; + let rest; + //let child; + //let index; + + if (R.isNil(action)) { return defaultState; } + + switch (action.type) { + + case actions.UPDATE_TREE_NODE_INFO: + return R.merge(state, { + _id: action.payload.nodeInfo._id._str, + nodeInfo: action.payload.nodeInfo, + openState: 'closed', + children: [], + childDetected: false, + needChildDetection: true, + linkDetected: R.propEq('type', 'host_ref', action.payload.nodeInfo), + level: action.payload.level, + }); + + case actions.ADD_UPDATE_CHILDREN_TREE_NODE: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + let actionChildren = R.map((childInfo) => { + let existingChild = R.find( + R.pathEq(['nodeInfo', '_id', '_str'], childInfo._id._str), state.children); + + return reducer(existingChild, + actions.updateTreeNodeInfo(childInfo, action.payload.level + 1)); + }, action.payload.childrenInfo); + + let allChildren = R.unionWith(R.eqBy(R.path(['nodeInfo', '_id', '_str'])), + actionChildren, state.children); + + /* + R.forEach((actionChild) => { + let index = R.findIndex(R.pathEq(['nodeInfo', '_id', '_str'], actionChild._id._str),state.children); + if (index < 0) { + state.children.push(actionChild); + } else { + state.children[index] = actionChild; + } + }, actionChildren); + let allChildren = state.children; + */ + + return R.merge(state, { + children: allChildren, + childDetected: R.length(allChildren) > 0 + }); + + /* + state.childDetected = R.length(allChildren) > 0; + return state; + */ + } + + return reduceActionOnChild(state, + actions.addUpdateChildrenTreeNode( + rest, action.payload.childrenInfo, action.payload.level + 1), + nodeId); + + case actions.RESET_TREE_NODE_CHILDREN: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.merge(state, { + children: [], + childDetected: false, + needChildDetection: true, + }); + } + + return reduceActionOnChild(state, actions.resetTreeNodeChildren(rest), nodeId); + + case actions.START_OPEN_TREE_NODE: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.assoc('openState', 'start_open', state); + } + + return reduceActionOnChild(state, actions.startOpenTreeNode(rest), nodeId); + + case actions.END_OPEN_TREE_NODE: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.assoc('openState', 'opened', state); + } + + return reduceActionOnChild(state, actions.endOpenTreeNode(rest), nodeId); + + case actions.START_CLOSE_TREE_NODE: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.assoc('openState', 'start_close', state); + } + + return reduceActionOnChild(state, actions.startCloseTreeNode(rest), nodeId); + + case actions.END_CLOSE_TREE_NODE: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.assoc('openState', 'closed', state); + } + + return reduceActionOnChild(state, actions.endCloseTreeNode(rest), nodeId); + + case actions.SET_CHILD_DETECTED_TREE_NODE: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.assoc('childDetected', true, state); + } + + return reduceActionOnChild(state, actions.setChildDetectedTreeNode(rest), nodeId); + + case actions.SET_POSITION_REPORT_IS_NEEDED_AS_ON: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.assoc('positionNeeded', true, state); + } + + return reduceActionOnChild(state, actions.setPositionReportIsNeededAsOn(rest), nodeId); + + case actions.REPORT_NODE_POSITION_RETRIEVED: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.merge(state, { + position: { + top: action.payload.rect.top, + bottom: action.payload.rect.bottom, + height: action.payload.rect.height, + }, + positionNeeded: false + }); + } + + return reduceActionOnChild(state, + actions.reportNodePositionRetrieved(rest, action.payload.rect), nodeId); + + case actions.SET_SCROLL_TO_NODE_IS_NEEDED_AS_ON: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.assoc('scrollToNodeIsNeeded', true, state); + } + + return reduceActionOnChild(state, actions.setScrollToNodeIsNeededAsOn(rest), nodeId); + + case actions.REPORT_SCROLL_TO_NODE_PERFORMED: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.assoc('scrollToNodeIsNeeded', false, state); + } + + return reduceActionOnChild(state, actions.reportScrollToNodePerformed(rest), nodeId); + + case actions.RESET_NEED_CHILD_DETECTION: + nodeId = R.head(action.payload.nodePath); + rest = R.tail(action.payload.nodePath); + + if (R.isNil(nodeId)) { + return R.assoc('needChildDetection', false, state); + } + + return reduceActionOnChild(state, actions.resetNeedChildDetection(rest), nodeId); + + + default: + return state; + } +} + +function reduceActionOnChild(state, action, nodeId) { + let index = R.findIndex(R.pathEq(['nodeInfo', '_id', '_str'], nodeId), state.children); + if (index < 0) throw 'error in reduce action on child'; + let child = state.children[index]; + + return R.assoc('children', + R.update(index, + reducer(child, action), + state.children), + state); +} diff --git a/ui/imports/ui/reducers/vedge-info-window.reducer.js b/ui/imports/ui/reducers/vedge-info-window.reducer.js new file mode 100644 index 0000000..d1be629 --- /dev/null +++ b/ui/imports/ui/reducers/vedge-info-window.reducer.js @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import * as R from 'ramda'; + +import * as actions from '/imports/ui/actions/vedge-info-window.actions'; + +const defaultState = { + node: null, + left: 0, + top: 0, + show: false +}; + +export function reducer(state = defaultState, action) { + let newState; + + switch (action.type) { + case actions.ACTIVATE_VEDGE_INFO_WINDOW: + newState = R.merge(state, { + node: R.pick([ + '_id', + 'id', + 'id_path', + 'name', + 'name_path', + 'environment' + ], action.payload.node), + left: action.payload.left, + top: action.payload.top - 28, + show: true + }); + return newState; + + case actions.CLOSE_VEDGE_INFO_WINDOW: + return R.merge(state, { + show: false, + top: 0, + left: 0 + }); + + default: + return state; + } +} |