-
-
Save nxtk/8e960e0069058b679231296f9c4534c7 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
; This is the next iteration of the CRUD metamodel that powers Hyperfiddle | |
; Just a design sketch, the current metamodel in prod is different | |
; CRUD definition | |
{identity ; Pass through URL params to query | |
[{:dustingetz/event-registration ; virtual attribute identifying a query | |
[:db/id | |
(:dustingetz/email {:hf/a :dustingetz/registrant-edit}) ; hyperlink to detail form | |
:dustingetz/name | |
{:dustingetz/gender | |
[:db/ident]} | |
{:dustingetz/shirt-size | |
[:db/ident]}]}] | |
nil ; no query params | |
[{:dustingetz/genders ; picklist for genders | |
[:db/ident]}] | |
((hf/new) {:hf/tx :dustingetz/register}) ; generate a Datomic tempid and wire up a transaction | |
[:db/id | |
:dustingetz/email | |
:dustingetz/name | |
{:dustingetz/gender | |
[:db/ident | |
{:dustingetz/shirt-sizes ; shirt-size options depend on gender | |
[:db/ident]}]} | |
{:dustingetz/shirt-size | |
[:db/ident]}]} | |
; Queries | |
{:dustingetz/genders | |
[:find (pull ?e [:db/ident]) | |
:where | |
[?e :db/ident ?i] | |
[(namespace ?i) ?ns] | |
[(ground "dustingetz.gender") ?ns]] | |
:dustingetz/shirt-sizes | |
[:in $ ?gender | |
:find (pull ?e [:db/ident]) | |
:where | |
[?e :db/ident ?i] | |
[?e :dustingetz.reg/gender ?gender] | |
[(namespace ?i) ?ns] | |
[(ground "dustingetz.shirt-size") ?ns]] | |
:dustingetz/another-query ; just an example of how server code eval might work | |
(->> (d/q '[:in $ ?e | |
:find ?a ?v ?tx ?x | |
:where | |
[?e ?a ?v ?tx ?x]] | |
(d/history *$*) | |
%) | |
(map #(assoc % 0 (:db/ident (d/entity db (get % 0))))) | |
(group-by #(nth % 2)) | |
(map-values #(sort-by first %)) | |
(sort-by first))} | |
; Validation | |
(s/def :dustingetz/register (s/keys :req [:dustingetz/email | |
:dustingetz/name] | |
:opt [:dustingetz/gender | |
:dustingetz/shirt-size])) | |
; View progressive enhancement | |
(defmethod hyperfiddle.api/render #{:dustingetz/gender} ; custom renderer for ::gender | |
[ctx props] | |
[hfui/select ctx ; present as picklist | |
{:options :dustingetz/genders ; Wire up picklist options to named query | |
:option-label :db/ident}]) ; picklist label | |
(defmethod hyperfiddle.api/render #{:dustingetz/shirt-size} ; custom renderer for ::shirt-size | |
[ctx props] | |
[hfui/select ctx ; second picklist | |
{:options :dustingetz/shirt-sizes | |
:option-label :db/ident}]) | |
; Transactions | |
(defmethod hyperfiddle.api/tx :dustingetz/register [ctx [e a v] props] | |
[[:db/add v :dustingetz/registered-date (js/Date.)]]) | |
; Schema | |
[{:db/ident :dustingetz/name, | |
:db/valueType :db.type/string, | |
:db/cardinality :db.cardinality/one, | |
:db/doc "Registrant's name"} | |
{:db/ident :dustingetz/email, | |
:db/valueType :db.type/string, | |
:db/cardinality :db.cardinality/one, | |
:db/unique :db.unique/identity, | |
:db/doc "Registrant's email"} | |
{:db/ident :dustingetz/gender, | |
:db/valueType :db.type/ref, | |
:db/cardinality :db.cardinality/one, | |
:db/doc "Registrant's gender (for shirt size)"} | |
{:db/ident :dustingetz/shirt-size, | |
:db/valueType :db.type/ref, | |
:db/cardinality :db.cardinality/one, | |
:db/doc "Selected tee-shirt size"}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment