Skip to content

Commit d6290b6

Browse files
committed
datascript 🤗
1 parent 50b8750 commit d6290b6

File tree

7 files changed

+119
-40
lines changed

7 files changed

+119
-40
lines changed

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ pom.xml.asc
1414
.cpcache/
1515
node_modules/
1616
.shadow-cljs/
17+
18+
/public/js/*

‎public/index.html

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css">
6+
<link rel="stylesheet" type="text/css" href="style.css">
7+
</head>
8+
<body>
9+
<div id="app"></div>
10+
<script src="js/main.js"></script>
11+
</body>
12+
</html>

‎resources/public/index.html

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4+
<meta charset="UTF-8">
5+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css">
46
<link rel="stylesheet" type="text/css" href="style.css">
57
</head>
68
<body>

‎src/cljc/reitit_db_fun/validations.cljc

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
[malli.error :as me]))
44

55
(def Article [:map
6-
[:title [:string {:min 2}]]
7-
[:body [:string {:min 5}]]
8-
[:author-id :int]])
6+
[:article/title [:string {:min 2}]]
7+
[:article/body [:string {:min 5}]]
8+
[:article/author-id :int]])
99

1010
(comment
1111
(m/validate Article

‎src/cljs/reitit_db_fun/db.cljs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(ns reitit-db-fun.db
2+
(:require [datascript.core :as ds]))
3+
4+
(def schema {})
5+
6+
(def initial-data
7+
[{:db/id -1
8+
:author/name "Lew Tolstoj"}
9+
{:db/id -2
10+
:author/name "Henryk Sienkiewicz"}])
11+
12+
(defonce conn (let [conn (ds/create-conn schema)]
13+
(ds/transact! conn initial-data)
14+
conn))

‎src/cljs/reitit_db_fun/main.cljs

+84-37
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,29 @@
44
[malli.core :as m]
55
[malli.error :as me]
66
[ajax.core :refer [GET POST]]
7-
[reitit-db-fun.validations :as v]))
7+
[reitit-db-fun.validations :as v]
88

9-
(defonce app-state (atom {:articles [{:title "Tytul artykulu"
10-
:body "Ciekawa tresc artykulu"
11-
:author-id 1}]}))
9+
[reitit-db-fun.db :refer [conn]]
10+
[datascript.core :as ds]))
11+
12+
(defn entities-for-attr [db attribute]
13+
(->> (ds/datoms db :aevt attribute)
14+
(map :e)
15+
(ds/pull-many db [:*])))
16+
17+
18+
(defn all-articles [db]
19+
(->> (ds/datoms db :aevt :article/title)
20+
(map :e)
21+
(ds/pull-many db [:*])))
1222

1323

1424
(rum/defc title < rum/static
1525
[text]
16-
[:h1 text])
26+
[:h1.title text])
1727

1828
(rum/defc input < rum/static
19-
[{:keys [type name label message value on-change read-only]
29+
[{:keys [type name label message value on-change read-only options]
2030
:or {read-only false}}]
2131
(let [inputs
2232
{:text
@@ -40,67 +50,95 @@
4050
:value value
4151
:on-change on-change
4252
:read-only read-only}]]
53+
[:p.help.is-danger message]]
54+
55+
:select
56+
[:.field
57+
[:label.label label]
58+
[:.control
59+
[:.select {:name name
60+
:read-only read-only
61+
:on-change on-change}
62+
(into [:select]
63+
(for [[value text] options] [:option {:value value} text]))]]
4364
[:p.help.is-danger message]]}]
4465
(get inputs type)))
4566

46-
(rum/defc articles < rum/static
47-
[articles]
67+
(rum/defc articles
68+
[db]
4869
(into [:div]
49-
(for [article articles]
70+
(for [article (all-articles db)]
5071
[:<>
51-
(input {:type :text :value (:title article) :read-only true})
52-
(input {:type :text-area :value (:body article) :read-only true})])))
53-
54-
55-
(defn save-article! [article]
56-
(swap! app-state update :articles conj article))
57-
72+
(input {:type :text :value (:article/title article) :read-only true})
73+
(input {:type :text-area :value (:article/body article) :read-only true})
74+
(input {:type :text :value (->> (:article/author-id article)
75+
(ds/datoms db :eavt)
76+
first
77+
:v) :read-only true})])))
78+
79+
(defn save-article!
80+
"TODO na razie zapisuje lokalnie w bazie. Docelowo w backendzie."
81+
[article]
82+
(println "saving:" article)
83+
(ds/transact! conn [(merge article {:db/id -1})]))
5884

5985
;; dodać lokalny stan z {} i walidować
6086
(rum/defcs article-form < (rum/local
61-
{:form-data {:title "" :body ""}
87+
{:form-data {:article/title ""
88+
:article/body ""
89+
:article/author-id nil}
6290
:messages {}}
6391
::article-form)
64-
[state]
65-
(let [local-state (::article-form state)
66-
{:keys [form-data messages]} @local-state
67-
{:keys [title body]} form-data]
92+
[state authors]
93+
(let [#_ "TODO dodać reaktywną listę autorów.. hmmm"
94+
#_ " w sumie to bez sensu trochÄ™...."
95+
96+
local-state (::article-form state)
97+
{:keys [form-data messages]} @local-state]
6898
[:div
69-
(input {:name :title :type :text :label "Tytuł" :value title
70-
:message (get messages :title "")
99+
(input {:name :title :type :text :label "Tytuł" :value (:article/title form-data)
100+
:message (get messages :article/title "")
71101
:on-change (fn [e]
72-
(swap! local-state assoc-in [:form-data :title]
102+
(swap! local-state assoc-in [:form-data :article/title]
73103
(-> e .-target .-value)))})
74-
(input {:name :body :type :text-area :label "Treść" :value body
75-
:message (get messages :body "")
104+
(input {:name :body :type :text-area :label "Treść" :value (:article/body form-data)
105+
:message (get messages :article/body "")
76106
:on-change (fn [e]
77-
(swap! local-state assoc-in [:form-data :body]
107+
(swap! local-state assoc-in [:form-data :article/body]
78108
(-> e .-target .-value)))})
109+
(input {:name :author-id :type :select :label "Autor" :options authors
110+
:message (get messages :article/author-id "")
111+
:on-change (fn [e]
112+
(swap! local-state assoc-in [:form-data :article/author-id]
113+
(-> e .-target .-value js/parseInt)))})
79114
[:button.button.is-primary
80115
{:on-click
81116
(fn [_]
82-
(if (m/validate v/Article {:title title :body body})
117+
(if (m/validate v/Article form-data)
83118
(do
84119
(swap! local-state assoc :messages {})
85-
(save-article! {:title title :body body})
86-
(prn "call to backend" {:title title :body body}))
120+
(save-article! form-data))
87121
(let [errors (-> v/Article
88-
(m/explain {:title title :body body})
122+
(m/explain form-data)
89123
(me/humanize))]
124+
(js/console.log (pr-str errors))
90125
(swap! local-state assoc :messages {})
91126
(doseq [[k v] errors]
92127
(swap! local-state assoc-in [:messages k] v)))))}
93128
"Zapisz"]]))
94129

95-
(rum/defc app []
96-
[:.container
97-
(title "Artukuły")
98-
(articles (:articles @app-state))
99-
(article-form)])
130+
(rum/defc app < rum/reactive
131+
[conn]
132+
(let [db (rum/react conn)]
133+
[:.container
134+
(article-form (mapv (juxt :db/id :author/name) (entities-for-attr db :author/name)))
135+
(title "Artukuły")
136+
(articles db)
137+
]))
100138

101139

102140
(defn ^:dev/after-load init []
103-
(rum/mount (app) (js/document.getElementById "app")))
141+
(rum/mount (app conn) (js/document.getElementById "app")))
104142

105143
(comment
106144

@@ -112,5 +150,14 @@
112150
(assoc ::m/missing-key
113151
{:error/message "Pole wymagane"}))}))
114152

153+
(save-article! {:article/title "title2" :article/body "body2"
154+
:article/author-id "test"})
155+
156+
(all-articles @conn)
157+
(entities-for-attr @conn :article/title)
158+
(entities-for-attr @conn :author/name)
159+
115160

161+
(mapv (juxt :db/id :author/name) (entities-for-attr @conn :author/name))
162+
(ds/db conn)
116163
)

‎src/cljs/reitit_db_fun/util.cljs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(ns reitit-db-fun.util
2+
(:require [datascript.core :as ds]))

0 commit comments

Comments
 (0)