Created
February 23, 2016 19:58
-
-
Save andreloureiro/dc73873f7eb753cd5d39 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 mimas.core | |
| (:require [om.next :as om :refer-macros [defui]] | |
| [om.dom :as dom] | |
| [goog.dom :as gdom])) | |
| (enable-console-print!) | |
| (println "mimas") | |
| ;; --- Utils --- | |
| (defn str->edn [s] | |
| (cljs.reader/read-string s)) | |
| ;; --- Parser --- | |
| (defmulti readf om/dispatch) | |
| (defmethod readf :task/list | |
| [{:keys [state query]} k _] | |
| {:value (om/db->tree query (get @state k) @state)}) | |
| (defmethod readf :project/list | |
| [{:keys [state query parser]} k _] | |
| (let [projects (om/db->tree query (get @state k) @state) | |
| tasks (om/db->tree [:id :title :project] (get @state :task/list) @state) | |
| projects-with-tasks (mapv (fn [project] (assoc project :tasks (filterv #(= (:project %) [:project/by-id (:id project)]) tasks))) projects)] | |
| {:value projects-with-tasks})) | |
| (defmulti mutatef om/dispatch) | |
| (defmethod mutatef 'task/create | |
| [{:keys [state ref]} _ {:keys [task]}] | |
| (let [ref [:task/by-id (:id task)]] | |
| {:action #(swap! state (fn [st] | |
| (-> st | |
| (update :task/list conj ref) | |
| (assoc-in ref task))))})) | |
| (def parser (om/parser {:read readf :mutate mutatef})) | |
| ;; --- Reconciler --- | |
| (def state {:project/list [{:id 0 :title "Project#1"} | |
| {:id 1 :title "Project#2"}] | |
| :task/list [{:id 0 :title "Task#1" :project [:project/by-id 1]} | |
| {:id 1 :title "Task#2" :project [:project/by-id 0]}]}) | |
| (def reconciler (om/reconciler {:state state | |
| :parser parser})) | |
| ;; --- Components --- | |
| (defui TaskInput | |
| Object | |
| (initLocalState [_] | |
| {:title nil | |
| :project nil}) | |
| (render [this] | |
| (let [{:keys [create-task projects] :as computed} (om/get-computed this) | |
| {:keys [title project]} (om/get-state this)] | |
| (dom/div nil | |
| (dom/input #js {:type "text" | |
| :value title | |
| :onChange #(om/update-state! this assoc :title (.. % -target -value)) | |
| :placeholder "task..."}) | |
| (dom/select #js {:value project | |
| :onChange #(om/update-state! this assoc :project (str->edn (.. % -target -value)))} | |
| (map #(dom/option #js {:value `[:project/by-id ~(:id %)]} (:title %)) projects)) | |
| (dom/button #js {:onClick #(create-task title project)} "create"))))) | |
| (def task-input (om/factory TaskInput)) | |
| (defui Project | |
| static om/Ident | |
| (ident [_ {:keys [id]}] | |
| `[:project/by-id ~id]) | |
| static om/IQuery | |
| (query [_] | |
| [:id :title])) | |
| (defn render-project [{:keys [title tasks]}] | |
| (dom/li nil title | |
| (dom/ul nil | |
| (map (fn [task] (dom/li nil (:title task))) tasks)))) | |
| (defui ProjectList | |
| Object | |
| (render [this] | |
| (let [projects (om/props this)] | |
| (dom/ul nil | |
| (map render-project projects))))) | |
| (def project-list (om/factory ProjectList)) | |
| (defui Task | |
| static om/Ident | |
| (ident [_ {:keys [id]}] | |
| `[:task/by-id ~id]) | |
| static om/IQuery | |
| (query [_] | |
| [:id :title {:project [:id :title]}]) | |
| Object | |
| (render [this] | |
| (let [{:keys [id title project] :as task} (om/props this)] | |
| (dom/li nil (str title " - " (:title project)))))) | |
| (def task (om/factory Task {:key-fn :id})) | |
| (defn task-list [list] | |
| (dom/ul nil (map task list))) | |
| (defui ^:once Mimas | |
| static om/IQuery | |
| (query [this] | |
| `[{:task/list ~(om/get-query Task)} | |
| {:project/list ~(om/get-query Project)}]) | |
| Object | |
| (create-task [this title project] | |
| (let [task {:id (rand-int 100) :title title :project project}] | |
| (om/transact! this `[(task/create {:task ~task}) :task/list]))) | |
| (render [this] | |
| (let [{:keys [task/list] :as props} (om/props this)] | |
| (dom/div nil | |
| (task-input (om/computed props {:projects (:project/list props) :create-task #(.create-task this %1 %2)})) | |
| (dom/p nil "tasks") | |
| (task-list list) | |
| (dom/p nil "projects") | |
| (project-list (:project/list props)))))) | |
| (om/add-root! | |
| reconciler | |
| Mimas | |
| (gdom/getElement "app")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment