[reagent "0.5.0"]
lein new figwheel hello-world -- --reagent
lein new luminus hello-world +cljs
<div class="well">
Look, I'm in a well!
</div>
(defn well
[message]
[:div.well
message])
(reagent/render
[well "Look, I'm in a well!"]
(.getElementById js/document "well")))
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">Pending</h3>
</div>
<div class="panel-body">
...
</div>
</div>
(defn task-panel
[]
[:div.panel.panel-warning
[:div.panel-heading
[:h3.panel-title "Pending"]]
[:div.panel-body
... ]])
(defn task-panel
"displays tasks in a panel"
[name task-list]
[:div.panel.panel-warning
[:div.panel-heading
[:h3.panel-title name]]
[:div.panel-body
(if (empty? task-list)
[task {:name "No tasks in this state"}]
(for [t task-list]
^{:key (:id t)} [task t]))]])
(defn task
[]
[:div
[page-header "Task Management"]
[:div.panel
(if (empty? task-list)
[ctask/task {:name "No tasks in task queue"}]
(for [t task-list]
^{:key (:id t)} [ctask/task t]))]])
Keyboard, Form, Focus,Mouse
[:form.form-vertical
[:fieldset
[:input#taskName.form-control
{:placeholder "Task Name"
:value (:name @task-data)
:on-change #(println "new name value:" (.-target.value %))}]
[:input#taskDesc.form-control
{:placeholder "Task Description"
:value (:desc @task-data)
:on-change #(println "new desc value:" (.-target.value %))}]
[:a.btn.btn-info.btn-raised
{:on-click
(fn [e]
(println "Add button clicked"))} "Add Task"]]
(defn new-task
[]
(let [task-data (atom {:name nil :desc nil})] ;; local variable for new task form
(fn []
[:form.form-vertical
[:input#taskName.form-control
{:placeholder "Task Name"
:value (:name @task-data)}] ...)
(defn new-task
[]
(let [task-data (atom {:name nil :desc nil})] ;; local variable for new task form
(fn []
[:form.form-vertical
[:input#taskName.form-control
{:placeholder "Task Name"
:value (:name @task-data)}] ...)
(defn new-task
[]
(let [task-data (atom {:name nil :desc nil})] ;; local variable for new task form
(fn []
[:form.form-vertical
...
[:a.btn.btn-info.btn-raised
{:on-click (fn [e] (reset! task-data {:name nil :desc nil}))} "Add Task"]]
...)
Form component
Panel component
(defn new-task
[chan-events]
(let [task-data (atom {:name nil :desc nil})] ;; local variable for new task form
(fn []
[:form.form-vertical
...
[:a.btn.btn-info.btn-raised
{:on-click (fn [e]
(go (async/>! chan-events @task-data))
(reset! task-data {:name nil :desc nil}))} "Add Task"]]
...)
put message
(defn task-panel
[name init-task-list chan-events]
(let [task-list (atom init-task-list)]
(go-loop []
(let [new-task (async/<! chan-events)]
(swap! task-list conj new-task))
(recur))
(fn []
[:div.panel.panel-info)}
[:div.panel-heading
[:h3.panel-title name]]
[:div.panel-body
(if (empty? @task-list)
[task {:name "No tasks in this state"}]
(for [t @task-list]
^{:key (:id t)} [task t]))]])))
take message
Event Queue
(defn initialize-event-que
[]
(let [chan-data (async/chan)
event-que (async/pub chan-data :event-type)]
...))
(defn go-logger
[]
(let [chan-log (async/chan)]
(async/sub event-que :new-ui-task chan-log)
(go-loop []
(let [v (async/<! chan-log)]
(println "new event: " v))
(recur))))
Event Queue
Log Service
(defn task-panel
[name init-task-list event-que event-chan]
(let [task-list (atom init-task-list)
chan-data (async/chan)]
(async/sub event-que :service-task-update chan-data)
(go-loop []
(let [new-task (async/<! chan-data)]
(swap! task-list conj new-task))
(recur))
(fn []
[:div.panel.panel-info)}
[:div.panel-heading {:on-click (fn [e]
(go (async/>! event-chan "click fired")))}
[:h3.panel-title name]]
...)
Action/View
(defroute "/" [] (session/put! :page :home))
(defroute "/task" [] (session/put! :page :task))
(defroute "/about" [] (session/put! :page :about))
...
(defonce appdata
{:navbar
{:brand "Tazki"
:items [
{:name "Dashboard" :page :home :url "#/"}
{:name "Task Que" :page :task :url "#/task"}
{:name "About" :page :about :url "#/about"}]}})
(defn init! []
...
(ev/initialize-event-que)
(utils/mount-component cnavbar/navbar (:navbar appdata) "navbar")
(utils/mount-component page nil "app"))
(defn go-panel-update-mixin
[state ref-list]
(let [xf (filter #(= state (get-in % [:event-data :state]))) ;; transducer
chan-data (async/chan 1 xf)]
(async/sub event-que :service-task-update chan-data)
(go-loop []
(let [new-task (:event-data (async/<! chan-data))]
(swap! ref-list conj new-task)
(recur))))
(defn task-panel
[name state init-task-list]
(let [task-list (atom init-task-list)]
(go-panel-update-mixin state task-list)
(fn []
[:div.panel.panel-info
[:div.panel-heading
[:h3.panel-title name]]
...)
Presentation Resources