Last active
April 26, 2018 18:31
-
-
Save trikitrok/03ed9b48d3e9f4942a60a5810347793e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns horizon.controls.widgets.tree.hierarchy | |
(:require | |
[horizon.common.utils.coeffects.extraction :as coeffects.extraction] | |
[horizon.common.utils.coeffects.factories :as coeffects] | |
[horizon.common.utils.effects.processing :as effects.processing] | |
[horizon.common.utils.keys-pressed :as kp] | |
[horizon.controls.utils.css-transitions-group :as css-transitions-group :include-macros true] | |
[horizon.controls.utils.icons :as icons] | |
[horizon.controls.utils.reactive :as utils.reactive] | |
[horizon.controls.widgets.mdl :as mdl] | |
[horizon.controls.widgets.tree.hierarchy-helpers :as tree.hierarchy-helpers] | |
[om.core :as om :include-macros true] | |
[om.dom :include-macros true] | |
[sablono.core :refer-macros [html]]) | |
(:require-macros | |
[horizon.common.macros :refer [defhandler]])) | |
(defhandler expand-node [e channel expanded-nodes-ids node-id expanded?] | |
(effects.processing/process-all! | |
(tree.hierarchy-helpers/expand-nodes-effects | |
channel expanded? expanded-nodes-ids node-id))) | |
(defhandler select-node [e channel value] | |
(effects.processing/process-all! | |
(tree.hierarchy-helpers/select-node-effects channel value))) | |
(defhandler select-alert [e channel value] | |
(effects.processing/process-all! | |
(tree.hierarchy-helpers/select-alert-effects channel value))) | |
(defn handle-branch-channel-messages [tree-channel msg] | |
(effects.processing/process-all! | |
(tree.hierarchy-helpers/branch-channel-messages-effects | |
tree-channel msg))) | |
(defn- get-expanded-nodes-from-dom [] | |
(let [expanded-html-nodes (vec (array-seq (js->clj (.getElementsByClassName js/document "device-name"))))] | |
(mapv #(hash-map :id (.-id (.-dataset %)) :name (.-name (.-dataset %))) expanded-html-nodes))) | |
(defn- extracting-data [owner] | |
(coeffects.extraction/extract-all! | |
[(coeffects/om-state owner [:shift-selection :selected :pressed-keys]) | |
(coeffects/arbitrary-fn :expanded-nodes get-expanded-nodes-from-dom)])) | |
(defn- handle-tree-channel-messages [owner channel msg] | |
(effects.processing/process-all! | |
(tree.hierarchy-helpers/tree-channel-messages-effects owner | |
channel | |
msg | |
#(extracting-data owner)))) | |
(defn- info-view [{:keys [level expanded info-data num-children selected]} owner branch-channel] | |
(reify | |
om/IRender | |
(render [_] | |
(let [{node-id :NodeId icon-type :IconType severity :Severity node-name :NodeName title | |
:Title node-alerts :Alerts} info-data | |
expanded? (contains? expanded node-id) | |
icon (icons/build-icon-class icon-type) | |
icon-color (icons/build-icon-color severity) | |
node-class (tree.hierarchy-helpers/select-node-classes selected node-id level num-children)] | |
(html | |
[:div | |
(if (zero? num-children) | |
{:class node-class | |
:on-click #(select-node % branch-channel {:id node-id | |
:name node-name})} | |
{:class node-class}) | |
(if (pos? num-children) | |
[:div.expander | |
{:on-click #(expand-node % branch-channel expanded node-id expanded?)} | |
(mdl/button | |
{:icon (if expanded? | |
[:i.fa.fa-minus] | |
[:i.fa.fa-plus])})] | |
[:div.dummy-expander]) | |
[:div.alert-icon | |
(when (some? icon-type) | |
(mdl/button | |
{:title title | |
:on-click #(select-alert % branch-channel node-alerts) | |
:icon [:i {:class icon :style {:color icon-color}}]}))] | |
[:div.device-name | |
{:data-id node-id | |
:data-name node-name} | |
node-name]]))))) | |
(defn- branch-view | |
[{node-id :NodeId nodes :Nodes :as data} owner {:keys [level tree-channel]}] | |
(reify | |
om/IInitState | |
(init-state [_] | |
{:expanded false | |
:selected false | |
:branch-channel (utils.reactive/build-channel-loop | |
#(handle-branch-channel-messages tree-channel %))}) | |
om/IRenderState | |
(render-state [_ {:keys [expanded branch-channel selected]}] | |
(html | |
[:div.branch-container | |
(let [num-branches (count nodes)] | |
(list | |
(om/build info-view | |
{:expanded expanded | |
:level level | |
:info-data data | |
:selected selected | |
:num-children num-branches} | |
{:opts branch-channel}) | |
(css-transitions-group/with-transition | |
:rim-list | |
(when (and (pos? num-branches) | |
(contains? expanded node-id)) | |
(om/build-all branch-view | |
nodes | |
{:opts {:level (inc level) | |
:tree-channel tree-channel} | |
:state {:selected selected | |
:expanded expanded}})))))])))) | |
(defn- set-state-pressed-keys [owner keys] | |
(om/set-state! owner :pressed-keys (set keys))) | |
(defn main-view [{:keys [values expanded selected view]} owner channel] | |
(reify | |
om/IInitState | |
(init-state [_] | |
{:shift-selection nil | |
:pressed-keys #{} | |
:selected selected | |
:tree-channel (utils.reactive/build-channel-loop | |
#(handle-tree-channel-messages owner channel %))}) | |
om/IDidMount | |
(did-mount [_] | |
(kp/listen-to-pressed-keys | |
#{:control :shift} | |
#(set-state-pressed-keys owner %) | |
:tree-view-listen-pressed-keys)) | |
om/IWillUnmount | |
(will-unmount [_] | |
(kp/unlisten-to-pressed-keys :tree-view-listen-pressed-keys)) | |
om/IRenderState | |
(render-state [_ {:keys [tree-channel selected]}] | |
(html | |
[:div.tree-hierarchy-container | |
(om/build branch-view | |
values | |
{:opts {:level 0 | |
:tree-channel tree-channel | |
:view view} | |
:state {:selected selected | |
:expanded expanded}})])))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment