Skip to content

Instantly share code, notes, and snippets.

@trikitrok
Created March 16, 2018 06:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trikitrok/a6647dd274e5df3bae2e46ac38a53c50 to your computer and use it in GitHub Desktop.
Save trikitrok/a6647dd274e5df3bae2e46ac38a53c50 to your computer and use it in GitHub Desktop.
(ns horizon.controls.widgets.tree.hierarchy
(:require
[cljs.core.async :refer [>!]]
[clojure.string :as string]
[horizon.common.logging :as log]
[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.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
[cljs.core.async.macros :refer [go]]
[horizon.common.macros :refer [defhandler]]))
(defhandler expand-node [e channel expanded node-id expanded?]
(if expanded?
(go (>! channel {:type :expand-node :value (disj expanded node-id)}))
(go (>! channel {:type :expand-node :value (conj expanded node-id)}))))
(defhandler select-node [e channel value]
(go (>! channel {:type :select-nodes :value value})))
(defhandler select-alert [e channel value]
(go (>! channel {:type :select-alert :value value})))
(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?)}
[:button.mdl-button.mdl-js-button.mdl-js-ripple-effect.mdl-button--icon
(if expanded?
[:i.fa.fa-minus]
[:i.fa.fa-plus])]]
[:div.dummy-expander])
[:div.alert-icon
(when (some? icon-type)
[:button.mdl-button.mdl-js-button.mdl-js-ripple-effect.mdl-button--icon
{:title title
:on-click #(select-alert % branch-channel node-alerts)}
[: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
#(tree.hierarchy-helpers/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
#(tree.hierarchy-helpers/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