From 59c7df7ef3868ad6f818b24dceec31e895f00ab0 Mon Sep 17 00:00:00 2001 From: Josha von Gizycki Date: Tue, 11 Sep 2018 16:14:31 +0200 Subject: [PATCH] attribute updates, some styling, forms fixing --- resources/app/stylesheets/app.less | 9 +++ src/wanijo/attribute/domain.clj | 42 +++++++++++--- src/wanijo/attribute/routes.clj | 27 +++++++-- src/wanijo/framework/form.clj | 88 ++++++++++++++---------------- src/wanijo/schema/view.clj | 13 +++-- 5 files changed, 115 insertions(+), 64 deletions(-) diff --git a/resources/app/stylesheets/app.less b/resources/app/stylesheets/app.less index d053c9a..f05fa81 100644 --- a/resources/app/stylesheets/app.less +++ b/resources/app/stylesheets/app.less @@ -66,6 +66,15 @@ h2 { .schema-title__name { font-weight: normal; } + + .schema-attributes { + list-style-type: none; + padding: 0; + + li { + margin-bottom: 3rem; + } + } } aside { diff --git a/src/wanijo/attribute/domain.clj b/src/wanijo/attribute/domain.clj index c609159..53fb2e7 100644 --- a/src/wanijo/attribute/domain.clj +++ b/src/wanijo/attribute/domain.clj @@ -11,8 +11,7 @@ #(some (partial = %) ["date" "file", "string" "text"]))) (spec/def ::required - (spec/or :bool-val boolean? - :nil nil?)) + #(some (partial = %) ["on" nil 0 1 "0" "1"])) (neo4j/defquery findy-by-schema @@ -37,13 +36,38 @@ CREATE (a)-[:of]->(s) SET a.type = {type} SET a.name = {name} - SET a.uuid = {attribute_uuid}") + SET a.uuid = {attribute_uuid} + SET a.required = {required}") -(defn create-new! [name type schema-uuid user-uuid] +(defn create-new! [attr schema-uuid user-uuid] (neo4j/exec-query! create-new - {:user_uuid user-uuid - :schema_uuid schema-uuid - :attribute_uuid (neo4j/uuid) - :type type - :name name})) + (-> attr + (assoc + :user_uuid user-uuid + :schema_uuid schema-uuid + :attribute_uuid (neo4j/uuid)) + (update :required #(if (some? %) 1 0))))) + +(neo4j/defquery edit + "MATCH (a:attribute) + WHERE a.uuid = {uuid} + SET a.type = {type} + SET a.name = {name} + SET a.required = {required}") + +(defn edit! [attr] + (neo4j/exec-query! + edit + (update attr + :required #(if (some? %) 1 0)))) + +(neo4j/defquery delete-by-uuid + "MATCH (a:attribute)-[c]-() + WHERE a.uuid = {uuid} + DELETE c, a") + +(defn delete-by-uuid! [uuid] + (neo4j/exec-query! + delete-by-uuid + {:uuid uuid})) diff --git a/src/wanijo/attribute/routes.clj b/src/wanijo/attribute/routes.clj index cbb0375..fcf2414 100644 --- a/src/wanijo/attribute/routes.clj +++ b/src/wanijo/attribute/routes.clj @@ -1,5 +1,5 @@ (ns wanijo.attribute.routes - (:require [compojure.core :refer [defroutes GET POST]] + (:require [compojure.core :refer [defroutes GET POST DELETE]] [ring.util.response :as resp] [wanijo.framework.form :as form] [wanijo.framework.routing :refer [register! path]] @@ -12,8 +12,7 @@ (if (form/valid? view-schema/attr-form req) (do (domain/create-new! - (get-in req [:params :name]) - (get-in req [:params :type]) + (:params req) schema-uuid (get-in req [:session :uuid])) (resp/redirect (path :schema-show {:uuid schema-uuid}))) @@ -22,7 +21,27 @@ (domain/find-by-schema! schema-uuid) req)))) +(defn edit! [schema-uuid req] + (if (form/valid? view-schema/attr-form req) + (do + (domain/edit! (:params req)) + (resp/redirect (path :schema-show {:uuid schema-uuid}))) + (view-schema/show-schema! + (domain-schema/find-by-uuid! schema-uuid) + (domain/find-by-schema! schema-uuid) + req))) + +(defn delete! [uuid req] + (domain/delete-by-uuid! uuid) + (resp/redirect (path :schema-show {:uuid (get-in req [:params :schema])}))) + (defroutes routes (POST (register! :attribute-new "/attribute/new") [] - new!)) + new!) + (POST (register! :attribute-edit "/attribute/edit/:schema") + [schema :as req] + (edit! schema req)) + (DELETE (register! :attribute-delete "/attribute/:uuid/delete") + [uuid :as req] + (delete! uuid req))) diff --git a/src/wanijo/framework/form.clj b/src/wanijo/framework/form.clj index 897e407..f680a58 100644 --- a/src/wanijo/framework/form.clj +++ b/src/wanijo/framework/form.clj @@ -39,9 +39,7 @@ (spec/explain-data spec-key field-value))))) (defn field-valid?[value spec-key req] - (or (or (and (contains? req :form-params) - (empty? (:form-params req))) - (empty? req)) + (or (empty? (:form-params req)) (spec/valid? spec-key value))) (defn field @@ -109,38 +107,40 @@ true (:params req))) -(defn render-input [id {:keys [label required spec]} values] - (let [value (id values)] - (list (when-not (field-valid? value spec values) - (spec-to-errmsg label spec value)) - (hform/label id label) - (hform/text-field {:required (when required "required")} - id - value)))) +(defn render-input [id {:keys [label required spec]} value req-value validate?] + (list + (when (and validate? (not (spec/valid? spec req-value))) + (spec-to-errmsg label spec req-value)) + (hform/label id label) + (hform/text-field {:required (when required "required")} + id + (if validate? req-value value)))) -(defn render-checkbox [id {:keys [label spec]} values] - (let [value (id values)] - (list - (when-not (field-valid? value spec values) - (spec-to-errmsg label spec value)) - (hform/label id label) - (hform/check-box id (some? value) value)))) +(defn render-checkbox [id {:keys [label spec]} value req-value validate?] + (list + (when (and validate? (not (spec/valid? spec req-value))) + (spec-to-errmsg label spec value)) + (hform/label id label) + (hform/check-box id + (and (some? value) (not= 0 value)) + (if validate? req-value value)))) -(defn render-textarea [id {:keys [label spec]} values] - (let [value (id values)] - (list - (when-not (field-valid? value spec values) - (spec-to-errmsg label spec value)) - (hform/label id label) - (hform/text-area id value)))) +(defn render-textarea [id {:keys [label spec]} value req-value validate?] + (list + (when (and validate? (not (spec/valid? spec req-value))) + (spec-to-errmsg label spec value)) + (hform/label id label) + (hform/text-area id + (if validate? req-value value)))) -(defn render-select [id {:keys [label spec options]} values] - (let [value (id values)] - (list - (when-not (field-valid? value spec values) - (spec-to-errmsg label spec value)) - (hform/label id label) - (hform/drop-down id options value)))) +(defn render-select [id {:keys [label spec options]} value req-value validate?] + (list + (when (and validate? (not (spec/valid? spec req-value))) + (spec-to-errmsg label spec value)) + (hform/label id label) + (hform/drop-down id + options + (if validate? req-value value)))) (def render-mapping {:input render-input @@ -148,29 +148,25 @@ :textarea render-textarea :select render-select}) -(defn cleaned-values - "Removes keys from value map that are not configured in the form" - [form-def values] - (reduce-kv - (fn [agg value-key value] - (if (contains? (:fields form-def) value-key) - (assoc agg value-key value) - agg)) - {} - values)) - -(defn render-form [form-def values] +(defn render-form [form-def values req] {:pre [(spec/valid? ::form form-def)]} - (let [cleaned-values (cleaned-values form-def values)] + (let [form-hash (str (hash [form-def values])) + submitted-hash (get-in req [:params :__form-hash]) + validate? (= form-hash submitted-hash)] (conj (map (fn [[field-id field-def]] (let [{:keys [options widget]} field-def + value (field-id values) + req-value (get-in req [:params field-id]) widget (cond (some? widget) widget (some? options) :select :else :input) widget-renderer (widget render-mapping)] (widget-renderer field-id field-def - cleaned-values))) + value + req-value + validate?))) (:fields form-def)) + (hform/hidden-field "__form-hash" form-hash) (anti-forgery-field)))) diff --git a/src/wanijo/schema/view.clj b/src/wanijo/schema/view.clj index 454b9e9..981c5ec 100644 --- a/src/wanijo/schema/view.clj +++ b/src/wanijo/schema/view.clj @@ -64,17 +64,20 @@ [:span.schema-title__name (:name schema)]] (hform/form-to [:post "/schema/edit"]) [:h2 "Attributes"] - [:ul + [:ul.schema-attributes (for [attr attrs] [:li - (hform/form-to [:post ""] - (form/render-form attr-form attr) + (hform/form-to [:post (path :attribute-edit {:schema (:uuid schema)})] + (form/render-form attr-form attr req) + (hform/hidden-field "uuid" (:uuid attr)) (hform/submit-button "Save")) - (hform/form-to [:delete ""] + (hform/form-to [:delete (path :attribute-delete attr)] + (anti-forgery-field) + (hform/hidden-field "schema" (:uuid schema)) (hform/submit-button "Delete!"))])] [:h3 "New attribute"] (hform/form-to [:post (path :attribute-new)] - (form/render-form attr-form (:params req)) + (form/render-form attr-form {} req) (hform/hidden-field "schema" (:uuid schema)) (hform/submit-button "Save")) [:h2 "Actions"]