Skip to content

Instantly share code, notes, and snippets.

@IwanKaramazow
Created January 6, 2016 22:07
Show Gist options
  • Save IwanKaramazow/cf8c48de8b5e719db671 to your computer and use it in GitHub Desktop.
Save IwanKaramazow/cf8c48de8b5e719db671 to your computer and use it in GitHub Desktop.
Experimentation with Om Next
(ns om-tutorial.core
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [goog.dom :as gdom]
[cljs.core.async :as async :refer [<! >! put! chan]]
[clojure.string :as string]
[om.next :as om :refer-macros [defui]]
[om.dom :as dom]
[datascript.core :as d]
[cognitect.transit :as t])
(:import [goog Uri]
[goog.net Jsonp]))
(enable-console-print!)
(def base-url
"http://www.gavertrimmers.be/beta/th")
(def r (t/reader :json))
(def w (t/writer :json))
(defn jsonp
([uri] (jsonp (chan) uri))
([c uri]
(let [gjsonp (Jsonp. (Uri. uri))]
(.send gjsonp nil #(put! c (t/read r (.stringify js/JSON %)) )))
c))
(def init-data {})
(defmulti read om/dispatch)
(defn get-results [st key]
(into [] (map #(get-in st % )) (get st key)))
(defmethod read :th/results
[{:keys [query state] :as all} k p]
(let [st @state]
(println query)
(println (into [] (map #(name %) query)))
(println k)
(println p)
{:remote true
;:value (get-results st k)
:value (om/db->tree (into [] (map #(name %) query)) (get st k) st)
}))
(defmethod read :search/results
[{:keys [state ast] :as env} k {:keys [query]}]
(let [st @state]
(if (contains? st k)
{:value (get st k)}
{:remote true})))
(defn get-years [state key]
(let [st @state]
(into [] (map #(get-in st %)) (get st key))))
(defmethod read :th/years
[{:keys [query state] :as env} key params]
(let [st @state]
(if (empty? (get st :th/years))
{:remote true}
{:value (get-years state key)})
))
(defmethod read :year/current
[{:keys [query state] :as env } key _]
(let [st @state]
(if (empty? (get st :year/current))
{:value (get-in st (last (get st :th/years)))}
{:value (get-in st (get st :year/current))}
)
))
;{:remote true
; :value (om/db->tree ["jaar"] (get st key) st)}))
;{:value (om/db->tree query (get st k) st)}))
;(defmethod read :default
; [{:keys [state] :as env} key params]
; (let [st @state]
; (println "reading the default state?")
; (if-let [[_ value] (find st key)]
; {:value value}
; {:value :not-found})))
(defmulti mutate om/dispatch)
(defmethod mutate 'year/select
[{:keys [state]} key {:keys [year]}]
{:value {:keys [:year/current [:jaar]]}
:action
(fn []
(swap! state assoc :year/current [:year/by-year year]))})
;; Components
(defui Year
static om/Ident
(ident [this {:strs [jaar]}]
[:year/by-year jaar])
static om/IQuery
(query [this]
[:jaar])
Object
(render [this]
(let [{:strs [jaar]} (om/props this)]
(dom/li #js {
:onClick
(fn [e]
(om/update-query!
(om/class->any reconciler RootView)
(fn [{:keys [query params] :as q}]
(update-in q [:params :selected] (fn [n] jaar))))
(om/transact! this `[(year/select {:year ~jaar}) :year/current ]))
} jaar ))))
(def year (om/factory Year))
(defui YearListView
Object
(render [this]
(let [list (om/props this)]
(apply dom/ul nil
(map year list)))))
(def year-list-view (om/factory YearListView))
(defui YearTitle
static om/Ident
(ident [this {:strs [jaar]}]
[:year/by-year jaar])
static om/IQuery
(query [this]
[:jaar])
Object
(render [this]
(let [{:strs [jaar]} (om/props this)]
(dom/h1 nil (str "Laatste editie: " jaar)))))
(def yearTitle (om/factory YearTitle))
(defn result-list [results]
(dom/ul #js {:key "result-list"}
(map #(dom/li nil %) results)))
(defui PersonThResult
static om/Ident
(ident [this {:strs [id]}]
[:results/by-id id])
static om/IQuery
(query [_]
[:plaats :categorie :tijd :naam :voornaam :tijd])
Object
(render [this]
(let [{:strs [plaats naam categorie voornaam tijd]} (om/props this) ]
(println (om/props this))
(dom/tr nil
(dom/td nil plaats)
(dom/td nil (str voornaam " " naam))
(dom/td nil categorie)
(dom/td nil tijd)))))
(def result (om/factory PersonThResult))
(defui ThResultTableView
Object
(render [this]
(let [list (om/props this)]
(dom/table nil
(dom/thead nil
(dom/tr nil
(dom/th nil "Nr.")
(dom/th nil "Naam.")
(dom/th nil "Categorie.")
(dom/th nil "Tijd.")))
(dom/tbody nil
(map result list))))))
(def thResultTableView (om/factory ThResultTableView))
(defui RootView
static om/IQueryParams
(params [this]
{:year (om/get-query Year)
:yearTitle (om/get-query YearTitle)
:person (om/get-query PersonThResult)
:selected 2015})
static om/IQuery
(query [this]
'[{:th/years ?year} ({:th/results ?person} {:year ?selected}) {:year/current ?yearTitle}])
Object
(render [this]
(let [{:keys [th/years year/current th/results]} (om/props this)]
(dom/div nil
(yearTitle current)
(year-list-view years)
(thResultTableView results)))))
;; yea yea, I know.. backend has a php 5.3 Rest API...
(defn send-post [uri]
(fn [{:keys [remote] :as all} cb]
(doseq [element remote]
(if (not (= cljs.core/List (type element)))
(let [key (keys element)]
(cond
(= key '(:th/years)) (let [gjsonp (Jsonp. (Uri. (str uri "/years")))]
(.send gjsonp nil #(cb {:th/years (t/read r (.stringify js/JSON %)) })))
(= key '(:year/current)) (let [gjsonp (Jsonp. (Uri. (str uri "/latest-year")))]
(.send gjsonp nil #(cb {:year/current (t/read r (.stringify js/JSON %)) })))
)
)
(let [[_ {:keys [year]}] element
gjsonp (Jsonp. (Uri. (str uri "/results?year=" year)))]
(.send gjsonp nil #(cb {:th/results (t/read r (.stringify js/JSON %))})))
))))
(def reconciler
(om/reconciler
{:state init-data
:parser (om/parser {:read read :mutate mutate})
:send (send-post base-url)
}))
(om/add-root! reconciler RootView (gdom/getElement "app"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment