-
-
Save devn/6b6254013728fe2b952d71f83ed782ce 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
(defn ^:private item-offset-for-rule | |
[rule y] | |
(when (isa? (:type rule) ::rule/rule-group) | |
(let [rule-element (.getElementById js/document (:id rule)) | |
li-elements (-> (.-children rule-element) | |
(aget 1) | |
(.-children)) | |
num-li-elements (.-length li-elements)] | |
(loop [index 0] | |
(if (< index num-li-elements) | |
(let [li-element (aget li-elements index) | |
rect (.getBoundingClientRect li-element) | |
top (.-top rect) | |
height (.-height rect) | |
cut-off (+ top | |
(/ height | |
2))] | |
(if (< y cut-off) | |
index | |
(recur (inc index)))) | |
index))))) | |
(defn rule-component [rule db] | |
(let [hover? (reagent/atom false) | |
drop-target (reagent/cursor db [:drop-target]) | |
dragged-rule (reagent/cursor db [:dragged-rule]) | |
active-drop-target? (reagent.atom/make-reaction | |
#(= rule @drop-target)) | |
dragged? (reagent.atom/make-reaction | |
#(= rule @dragged-rule)) | |
eligible-drag-target? (reagent.atom/make-reaction | |
#(when @dragged-rule | |
(rule/accepts? rule @dragged-rule))) | |
when-drop-target (fn [f] | |
(fn [e] | |
(when @eligible-drag-target? | |
(.stopPropagation e) | |
(f e)))) | |
on-this-target (fn [f] | |
(fn [e] | |
(when (= (:id rule) | |
(.-id (.-target e))) | |
(.stopPropagation e) | |
(f e)))) | |
disabled? (reagent.atom/make-reaction | |
#(rule/disabled? rule db))] | |
(fn rule-component* [rule db] | |
[:li | |
{:class [:card | |
(:type rule) | |
(when @disabled? | |
:disabled) | |
(when @hover? | |
:hover) | |
(when @active-drop-target? | |
:active-drop-target) | |
(when @dragged? | |
:dragged)] | |
:draggable (not @disabled?) | |
:on-drag-start (on-this-target | |
(fn [e] | |
(let [[effect rule] (rule/drag-effect-and-rule rule)] | |
(set! (.-effectAllowed (.-dataTransfer e)) | |
effect) | |
(reset! dragged-rule rule) | |
(reset! hover? false)))) | |
:on-drag-end (on-this-target | |
#(swap! db dissoc :dragged-rule :drop-target)) | |
:on-drag-enter (when-drop-target | |
(fn [_] | |
(swap! db assoc :drop-target rule))) | |
:on-drag-leave (when-drop-target | |
(fn [e] | |
(let [entering (.-relatedTarget e)] | |
(when (or (nil? entering) | |
(= (.-parentNode (.-target e)) | |
entering)) | |
(swap! db dissoc :drop-target))))) | |
:on-drop (when-drop-target | |
(fn [e] | |
(let [offset (item-offset-for-rule rule (.-clientY e))] | |
(when (model/unassigned? db @dragged-rule) | |
(println "Removing" (:name @dragged-rule) "from available") | |
(println "Dragged rule:" (pr-str @dragged-rule)) | |
(println "Number of availabe before:" (count (:available @db))) | |
(let [sorted-names (fn [db] (into (sorted-set) | |
(map :name (:available @db)))) | |
sorted-names-before (sorted-names db) | |
_ (println sorted-names-before) | |
_ (reagent/rswap! db update :available disj @dragged-rule) | |
_ (println "Number of available after:" (count (:available @db))) | |
sorted-names-after (sorted-names db) | |
_ (println sorted-names-after)] | |
(println "Difference old and new available items:" | |
(clojure.set/difference sorted-names-before sorted-names-after))))))) | |
:on-drag-over (when-drop-target | |
(fn [e] | |
(println "dragging" | |
(:name @dragged-rule) | |
"over" | |
(:name rule)) | |
(let [data (.-dataTransfer e) | |
effect (.-effectAllowed data)] | |
(set! (.-dropEffect data) effect)) | |
(.preventDefault e))) | |
:on-mouse-over (on-this-target #(reset! hover? true)) | |
:on-mouse-out (on-this-target #(reset! hover? false)) | |
:id (:id rule) | |
:key (:id rule) | |
:title (rule/hover-text rule db)} | |
[:span (:name rule)] | |
(when (isa? (:type rule) ::rule/rule-group) | |
(into [:ul] | |
(map (fn [r] [rule-component r db])) | |
(:children rule)))]))) | |
(defn ^:private available-items-list | |
[db] | |
[:section | |
[:header [:h2.h4 "Available Items"]] | |
(let [{:keys [available]} @db] | |
(if (empty? available) | |
[:p "No available items"] | |
(into [:ul.card-list] | |
(map (fn [r] [rule-component r db])) | |
available)))]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment