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/components/environment/environment.js | |
parent | b70483739d1f6f4f0d31987ed2e4d1e30d71d579 (diff) |
adding calipso ui
Change-Id: Ifa6f63daebb07f45580f747341960e898fdb00c4
Signed-off-by: Koren Lev <korenlev@gmail.com>
Diffstat (limited to 'ui/imports/ui/components/environment/environment.js')
-rw-r--r-- | ui/imports/ui/components/environment/environment.js | 570 |
1 files changed, 570 insertions, 0 deletions
diff --git a/ui/imports/ui/components/environment/environment.js b/ui/imports/ui/components/environment/environment.js new file mode 100644 index 0000000..6dc4a82 --- /dev/null +++ b/ui/imports/ui/components/environment/environment.js @@ -0,0 +1,570 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// 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 / +///////////////////////////////////////////////////////////////////////////////////////// +/* + * Tempalte Component: Environment + */ + +/* + * Lifecycles methods + */ + +import { Template } from 'meteor/templating'; +import { ReactiveDict } from 'meteor/reactive-dict'; +import { ReactiveVar } from 'meteor/reactive-var'; +import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +import * as R from 'ramda'; +import { EJSON } from 'meteor/ejson'; +import factory from 'reactive-redux'; +import { _idFieldDef } from '/imports/lib/simple-schema-utils'; +//import { idToStr } from '/imports/lib/utilities'; + +import { Environments } from '/imports/api/environments/environments'; +import { Inventory } from '/imports/api/inventories/inventories'; +//import { Messages } from '/imports/api/messages/messages'; + +import { store } from '/imports/ui/store/store'; +//import { setCurrentNode } from '/imports/ui/actions/navigation'; +import { + setEnvEnvId, + setEnvName, + updateEnvTreeNode, + startOpenEnvTreeNode, + setEnvSelectedNodeInfo, + setEnvAsLoaded, + setEnvAsNotLoaded, + setEnvSelectedNodeAsEnv, + toggleEnvShow, + endOpenEnvTreeNode, + reportEnvNodePositionRetrieved, + setEnvScrollToNodeIsNeededAsOn, + reportEnvScrollToNodePerformed, + resetEnvNeedChildDetection, + setShowDashboard, +// setShowGraph, +} from '/imports/ui/actions/environment-panel.actions'; +import { setMainAppSelectedEnvironment } from '/imports/ui/actions/main-app.actions'; +import { closeVedgeInfoWindow } from '/imports/ui/actions/vedge-info-window.actions'; +import { setEnvSelectedNode } + from '/imports/ui/actions/environment-panel.actions'; + +import '/imports/ui/components/accordion-nav-menu/accordion-nav-menu'; +import '/imports/ui/components/graph-tooltip-window/graph-tooltip-window'; +import '/imports/ui/components/vedge-info-window/vedge-info-window'; +import '/imports/ui/components/env-delete-modal/env-delete-modal'; +import '/imports/ui/components/environment-dashboard/environment-dashboard'; +import '/imports/ui/components/general-folder-node-dashboard/general-folder-node-dashboard'; +import '/imports/ui/components/general-node-dashboard/general-node-dashboard'; +import '/imports/ui/components/network-graph-manager/network-graph-manager'; + +import './environment.html'; + +let maxOpenTreeNodeTrialCount = 3; + +/* +var nodeTypesForSelection = [ + 'project', + 'availability_zone', + 'host', + 'environment', + 'aggregate', + 'host', + 'region', + 'instance', + 'network' +]; +*/ + +/* + * Lifecycles + */ + +Template.Environment.onCreated(function () { + var instance = this; + + // reactive state + instance.state = new ReactiveDict(); + instance.state.setDefault({ + graphTooltipWindow: { label: '', title: '', left: 0, top: 0, show: false }, + vedgeInfoWindow: { node: null, left: 0, top: 0, show: false }, + dashboardName: 'environment', + }); + instance.currentData = new ReactiveVar(null, EJSON.equals); + instance.onNodeOpeningDone = _.debounce(() => { + scrollTreeToLastOpenedChild(instance); + }, 400); + + createAttachedFns(instance); + + const envIdSelector = (state) => (state.components.environmentPanel._id); + instance.rdxEnvId = factory(envIdSelector, store); + + const mainNodeSelector = (state) => (state.components.environmentPanel.treeNode); + instance.rdxMainNode = factory(mainNodeSelector, store); + + const selectedNodeIdSelector = + (state) => (state.components.environmentPanel.selectedNode._id); + instance.rdxSelectedNodeId = factory(selectedNodeIdSelector, store); + + const selectedNodeTypeSelector = + (state) => (state.components.environmentPanel.selectedNode.type); + instance.rdxSelectedNodeType = factory(selectedNodeTypeSelector, store); + + const envNameSelector = (state) => (state.components.environmentPanel.envName); + instance.rdxEnvName = factory(envNameSelector, store); + + const isLoadedSelector = (state) => (state.components.environmentPanel.isLoaded); + instance.rdxIsLoaded = factory(isLoadedSelector, store); + + const showTypeSelector = (state) => (state.components.environmentPanel.showType); + instance.rdxShowType = factory(showTypeSelector, store); + + const selectedNodeCliqueSelector = + (state) => (state.components.environmentPanel.selectedNode.clique); + instance.rdxSelectedNodeClique = factory(selectedNodeCliqueSelector, store); + + const selectedNodeIdPathSelector = + (state) => (state.components.environmentPanel.selectedNode.id_path); + instance.rdxSelectedNodeIdPath = factory(selectedNodeIdPathSelector, store); + + const i18nSelector = (state) => (state.api.i18n); + instance.rdxI18n = factory(i18nSelector, store); + + instance.autorun((function(_this) { + return function(_computation) { + return _this.currentData.set(Template.currentData()); + }; + })(instance)); + + let lastData = null; + + // Autorun component input + instance.autorun(function () { + let data = instance.currentData.get(); + + if (R.equals(data, lastData)) { return; } + lastData = data; + + new SimpleSchema({ + _id: _idFieldDef, + selectedNodeId: R.assoc('optional', true, _idFieldDef), + }).validate(data); + + store.dispatch(setEnvEnvId(data._id)); + if (R.isNil(data.selectedNodeId)) { + store.dispatch(setEnvSelectedNodeAsEnv()); + } else { + store.dispatch(setEnvSelectedNode(data.selectedNodeId)); + } + }); + + // Autorun object id + instance.autorun(function () { + let _id = instance.rdxEnvId.get(); + store.dispatch(setEnvAsNotLoaded()); + + instance.subscribe('environments?_id', _id); + Environments.find({ _id: _id }).forEach((env) => { + store.dispatch(setEnvName(env.name)); + store.dispatch(updateEnvTreeNode(env)); + store.dispatch(setEnvAsLoaded()); + store.dispatch(startOpenEnvTreeNode([])); + store.dispatch(setMainAppSelectedEnvironment(env._id)); + store.dispatch(setShowDashboard()); + }); + }); + + // Autorun selected node + instance.autorun(function () { + let selectedNodeId = instance.rdxSelectedNodeId.get(); + //let selectedNodeType = instance.rdxSelectedNodeType.get(); + + if (R.isNil(selectedNodeId)) { return; } + //if (selectedNodeType === 'environment') { return; } + + instance.subscribe('inventory?_id', selectedNodeId); + Inventory.find({ _id: selectedNodeId }).forEach((selectedNode) => { + store.dispatch(setEnvSelectedNodeInfo(selectedNode)); + + Meteor.apply('expandNodePath', + [ selectedNode._id ], + { wait: false }, + function (err, res) { + if (err) { + console.error(err); + return; + } + + if (R.isNil(res)) { return; } + + let idList = R.map(R.path(['_id', '_str']), res); + openTreeNode([R.head(idList)], R.tail(idList), 0); + }); + }); + }); + + ///////////////// + + instance.storeUnsubscribe = store.subscribe(() => { + let state = store.getState(); + + let graphTooltipWindow = state.components.graphTooltipWindow; + instance.state.set('graphTooltipWindow', graphTooltipWindow); + + let vedgeInfoWindow = state.components.vedgeInfoWindow; + instance.state.set('vedgeInfoWindow', vedgeInfoWindow); + + }); + + /* + (() => { + if (R.isNil(controller.params.query.selectedNodeId) && + R.isNil(selectedNodeId)) { + return; + } + + let srlSelectedNodeId = idToStr(selectedNodeId); + if (R.equals(controller.params.query.selectedNodeId, srlSelectedNodeId)) { + return; + } + + setTimeout(() => { + Router.go('environment', + { _id: controller.params._id }, + { query: { selectedNodeId: srlSelectedNodeId } }); + }, 1); + + })(); + */ + +}); + +Template.Environment.onDestroyed(function () { + let instance = this; + instance.storeUnsubscribe(); + instance.rdxMainNode.cancel(); + instance.rdxEnvId.cancel(); + instance.rdxSelectedNodeId.cancel(); + instance.rdxEnvName.cancel(); + instance.rdxIsLoaded.cancel(); + instance.rdxShowType.cancel(); + instance.rdxSelectedNodeIdPath.cancel(); +}); + +Template.Environment.rendered = function(){ +}; + +/* + * Helpers + */ + +Template.Environment.helpers({ + isLoaded: function () { + let instance = Template.instance(); + return instance.rdxIsLoaded.get(); + }, + + envName: function(){ + let instance = Template.instance(); + return instance.rdxEnvName.get(); + }, + + mainNode: function () { + let instance = Template.instance(); + return instance.rdxMainNode.get(); + }, + + selectedNodeType: function () { + let instance = Template.instance(); + return instance.rdxSelectedNodeType.get(); + }, + + getState: function (key) { + let instance = Template.instance(); + return instance.state.get(key); + }, + + argsNavMenu: function (envName, mainNode) { + let instance = Template.instance(); + return { + envName: envName, + mainNode: mainNode, + onOpeningDone: instance._fns.onOpeningDone, + onNodeSelected: instance._fns.onNodeSelected, + onToggleGraphReq: function () { + store.dispatch(toggleEnvShow()); + }, + onResetSelectedNodeReq: function () { + store.dispatch(setEnvSelectedNodeAsEnv()); + }, + onPositionRetrieved: instance._fns.onPositionRetrieved, + onScrollToNodePerformed: instance._fns.onScrollToNodePerformed, + onOpenLinkReq: instance._fns.onOpenLinkReq, + onResetNeedChildDetection: instance._fns.onResetNeedChildDetection, + }; + }, + + graphTooltipWindow: function () { + let instance = Template.instance(); + let graphTooltipWindow = instance.state.get('graphTooltipWindow'); + + return graphTooltipWindow; + }, + + vedgeInfoWindow: function () { + let instance = Template.instance(); + let vedgeInfoWindow = instance.state.get('vedgeInfoWindow'); + + return vedgeInfoWindow; + }, + + argsGraphTooltipWindow: function (graphTooltipWindow) { + return { + label: R.path(['label'], graphTooltipWindow), + title: R.path(['title'], graphTooltipWindow), + left: R.path(['left'], graphTooltipWindow), + top: R.path(['top'], graphTooltipWindow), + show: R.path(['show'], graphTooltipWindow) + }; + }, + + argsVedgeInfoWindow: function (vedgeInfoWindow) { + return { + environment: R.path(['node', 'environment'], vedgeInfoWindow), + object_id: R.path(['node', 'id'], vedgeInfoWindow), + name: R.path(['node', 'name'], vedgeInfoWindow), + left: R.path(['left'], vedgeInfoWindow), + top: R.path(['top'], vedgeInfoWindow), + show: R.path(['show'], vedgeInfoWindow), + onCloseRequested: function () { + store.dispatch(closeVedgeInfoWindow()); + } + }; + }, + + argsD3Graph: function () { + let instance = Template.instance(); + let idPath = instance.rdxSelectedNodeIdPath.get(); + + return { + id_path: idPath + }; + }, + + argsNetworkGraphManager: function () { + let instance = Template.instance(); + let idPath = instance.rdxSelectedNodeIdPath.get(); + + return { + id_path: idPath + }; + }, + + showVedgeInfoWindow: function () { + let instance = Template.instance(); + let node = instance.state.get('vedgeInfoWindow').node; + return ! R.isNil(node); + }, + + isSelectedNodeAGraph: function () { + let instance = Template.instance(); + let nodeClique = instance.rdxSelectedNodeClique.get(); + + return !R.isNil(nodeClique); + }, + + dashboardTemplate: function () { + let instance = Template.instance(); + let selectedNodeType = instance.rdxSelectedNodeType.get(); + let dashTemplate = 'EnvironmentDashboard'; + + switch (selectedNodeType) { + case 'project': + dashTemplate = 'ProjectDashboard'; + break; + + case 'region': + dashTemplate = 'RegionDashboard'; + break; + + case 'aggregate': + dashTemplate = 'AggregateDashboard'; + break; + + case 'host': + dashTemplate = 'HostDashboard'; + break; + + case 'availability_zone': + dashTemplate = 'ZoneDashboard'; + break; + + case 'environment': + dashTemplate = 'EnvironmentDashboard'; + break; + + case 'vservice_routers_folder': + case 'vnics_folder': + case 'regions_folder': + case 'vedges_folder': + case 'network_agents_folder': + case 'network_services_folder': + case 'availability_zones_folder': + case 'pnics_folder': + case 'networks_folder': + case 'vconnectors_folder': + case 'projects_folder': + case 'aggregates_folder': + case 'vservices_folder': + case 'vservice_dhcps_folder': + case 'ports_folder': + case 'instances_folder': + dashTemplate = 'GeneralFolderNodeDashboard'; + break; + + default: + dashTemplate = 'GeneralNodeDashboard'; + } + + return dashTemplate; + }, + + rdxSelectedNodeId: function () { + let instance = Template.instance(); + return instance.rdxSelectedNodeId.get(); + }, + + argsDashboard: function (nodeId) { + //let instance = Template.instance(); + + return { + _id: nodeId, + onNodeSelected: function (selectedNodeId) { + store.dispatch(setEnvSelectedNode(selectedNodeId, null)); + } + }; + }, + + argsBreadCrumb: function (selectedNodeId) { + return { + nodeId: selectedNodeId, + onNodeSelected: function (node) { + store.dispatch(setEnvSelectedNode(node._id, null)); + } + }; + }, + + getShow: function (qShowType) { + let instance = Template.instance(); + let showType = instance.rdxShowType.get(); + + return R.equals(showType, qShowType); + }, + + i18n: function () { + let instance = Template.instance(); + return instance.rdxI18n.get(); + + }, +}); // end: helpers + + +Template.Environment.events({ +}); + +function openTreeNode(path, rest, trialCount) { + if (trialCount > maxOpenTreeNodeTrialCount) { + return; + } + + let tree = store.getState().components.environmentPanel + .treeNode; + + let node = getNodeInTree(path, tree); + if (R.isNil(node)) { + setTimeout(() => { + openTreeNode(path, rest, trialCount + 1); + }, 800); + return; + } + + if (node.openState === 'closed') { + store.dispatch(startOpenEnvTreeNode(path)); + setTimeout(() => { + openTreeNode(path, rest, trialCount + 1); + }, 200); + return; + } + + if (R.length(rest) === 0) { return; } + + let newPath = R.append(R.head(rest), path); + let newRest = R.drop(1, rest); + openTreeNode(newPath, newRest, 0); +} + +function getNodeInTree(path, tree) { + if (R.length(path) === 0) { return tree; } + + let first = R.head(path); + let rest = R.tail(path); + let child = R.find(R.pathEq(['nodeInfo', '_id', '_str'], first), + tree.children); + + if (R.isNil(child)) { return null; } + + return getNodeInTree(rest, child); +} + +function createAttachedFns(instance) { + instance._fns = { + onOpeningDone: (nodePath, _nodeInfo) => { + store.dispatch(endOpenEnvTreeNode(R.tail(nodePath))); + instance.lastOpenedNodePath = nodePath; + instance.onNodeOpeningDone(); + }, + + onNodeSelected: (nodeInfo) => { + //if (R.contains(nodeInfo.type, nodeTypesForSelection)) { + store.dispatch(setEnvSelectedNode(nodeInfo._id, null)); + //} + }, + + onPositionRetrieved: (nodePath, rect) => { + store.dispatch( + reportEnvNodePositionRetrieved(R.tail(nodePath), rect)); + }, + + onScrollToNodePerformed: (nodePath) => { + store.dispatch(reportEnvScrollToNodePerformed(R.tail(nodePath))); + }, + + onOpenLinkReq: (envName, nodeName) => { + Meteor.apply('inventoryFindNode?type&env&name', [ + 'host', envName, nodeName + ], { + wait: false + }, function (err, res) { + if (err) { + console.log('error in inventoryFindNode', err); + return; + } + + store.dispatch(setEnvSelectedNode(res.node._id, null)); + }); + }, + + onResetNeedChildDetection: (nodePath) => { + store.dispatch(resetEnvNeedChildDetection(R.tail(nodePath))); + } + }; +} + +function scrollTreeToLastOpenedChild(instance) { + store.dispatch(setEnvScrollToNodeIsNeededAsOn(R.tail(instance.lastOpenedNodePath))); +} |