diff --git a/resources/app/stylesheets/app.less b/resources/app/stylesheets/app.less index 5fd66d0..05821b6 100644 --- a/resources/app/stylesheets/app.less +++ b/resources/app/stylesheets/app.less @@ -11,6 +11,7 @@ body { font-family: sans-serif; + margin: 0; } a:link, @@ -52,8 +53,7 @@ h2 { "nav main sidebar" "footer footer footer"; margin: auto; - min-width: 900px; - width: 80%; + max-width: 1500px; nav { grid-area: nav; diff --git a/src/wanijo/framework/form.clj b/src/wanijo/framework/form.clj index 65aadfd..23405df 100644 --- a/src/wanijo/framework/form.clj +++ b/src/wanijo/framework/form.clj @@ -1,16 +1,19 @@ (ns wanijo.framework.form (:require [clojure.spec.alpha :as spec] [hiccup.form :as hform] + [hiccup.core :as hcore] [wanijo.framework.view :as view] - [ring.util.anti-forgery :refer [anti-forgery-field]])) + [ring.util.anti-forgery :refer [anti-forgery-field]] + [wanijo.framework.common :refer [in?]])) (spec/def ::label string?) (spec/def ::required boolean?) (spec/def ::spec keyword?) (spec/def ::options - (spec/coll-of (spec/tuple string? string?))) + (spec/or :empty empty? + :options (spec/coll-of (spec/tuple string? string?)))) (spec/def ::widget - #(some (partial = %) [:input :select :checkbox :textarea])) + #(in? [:input :select :checkbox :textarea :mselect] %)) (spec/def ::field (spec/keys :req-un [::label ::required @@ -18,11 +21,7 @@ :opt-un [::options ::widget])) (spec/def ::fields - (spec/and map? - (fn [map] - (every? #(spec/valid? ::field (val %)) map)) - (fn [map] - (every? #(keyword? (key %)) map)))) + (spec/map-of keyword? ::field)) (spec/def ::form (spec/keys :req-un [::fields])) @@ -111,14 +110,31 @@ options (if validate? req-value value)))) +(defn render-multiselect [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) + (hcore/html + [:select {:multiple "multiple" + :size 5 + :name (name id) + :id (name id)} + (for [option options] + [:option {:value (second option) + :selected (in? (if validate? req-value value) + (second option))} + (first option)])]))) + (def render-mapping {:input render-input :checkbox render-checkbox :textarea render-textarea - :select render-select}) + :select render-select + :mselect render-multiselect}) (defn render-widgets [form-def values req] - {:pre [(spec/valid? ::form form-def)]} + {:pre [(spec/assert ::form form-def)]} (let [form-hash (str (hash [form-def values])) submitted-hash (get-in req [:params :__form-hash]) validate? (= form-hash submitted-hash)] diff --git a/src/wanijo/schema/domain.clj b/src/wanijo/schema/domain.clj index 4ce2835..bcaf82a 100644 --- a/src/wanijo/schema/domain.clj +++ b/src/wanijo/schema/domain.clj @@ -8,6 +8,9 @@ (spec/def ::created-at (spec/and string? ::neo4j/date-str)) +(spec/def ::assigned-to + (complement empty?)) + (neo4j/defquery all-created-by "MATCH (s:schema)-->(u:user) @@ -110,3 +113,16 @@ (neo4j/exec-query! edit schema)) + +(neo4j/defquery + assigned-users + "MATCH (s:schema)-[:assigned_to]-(u:user) + WHERE s.uuid = {uuid} + RETURN u + ORDER BY u.ident") + +(defn assigned-users! [uuid] + (map :u + (neo4j/exec-query! + assigned-users + {:uuid uuid}))) diff --git a/src/wanijo/schema/routes.clj b/src/wanijo/schema/routes.clj index 89d18ed..3bc58f7 100644 --- a/src/wanijo/schema/routes.clj +++ b/src/wanijo/schema/routes.clj @@ -5,6 +5,7 @@ [wanijo.framework.form :as form] [wanijo.framework.routing :refer [register! path]] [wanijo.schema.domain :as domain] + [wanijo.user.domain :as domain-user] [wanijo.schema.view :as view-schema] [wanijo.attribute.domain :as domain-attr])) @@ -35,22 +36,36 @@ (resp/redirect (path :schema-overview))) {:status 403})) +(defn view! [uuid req] + (view-schema/show-schema! + (assoc (domain/find-by-uuid! uuid) + :assigned (map :uuid (domain/assigned-users! uuid))) + (domain-attr/find-by-schema! uuid) + (assoc-in view-schema/access-form + [:fields :assigned :options] + (map #(vector (:ident %) (:uuid %)) + (domain-user/all!))) + req)) + +(defn assign! [req] + (println (:params req))) + (defroutes routes (GET (register! :schema-overview "/schema") [] view-schema/overview!) (GET (register! :schema-show "/schema/:uuid") [uuid :as req] - (view-schema/show-schema! - (domain/find-by-uuid! uuid) - (domain-attr/find-by-schema! uuid) - req)) + (view! uuid req)) (POST (register! :schema-new "/schema/new") [] new!) (POST (register! :schema-edit "/schema/edit") [] edit!) + (POST (register! :schema-assign "/schema/assign") + [] + assign!) (DELETE (register! :schema-delete "/schema/:uuid") [uuid :as req] (delete-schema! uuid (:session req)))) diff --git a/src/wanijo/schema/view.clj b/src/wanijo/schema/view.clj index e552733..b5ae050 100644 --- a/src/wanijo/schema/view.clj +++ b/src/wanijo/schema/view.clj @@ -10,8 +10,8 @@ (def form {:fields {:name {:label "Name" - :required true - :spec ::domain/name}}}) + :required true + :spec ::domain/name}}}) (def attr-form {:fields {:name {:label "Name" @@ -29,6 +29,12 @@ :spec ::attr-domain/required :widget :checkbox}}}) +(def access-form + {:fields {:assigned {:label "Users" + :required false + :spec :a + :widget :mselect}}}) + (defn overview! [req] (let [session (:session req) uuid (:uuid session) @@ -55,7 +61,8 @@ (form/render-widgets form {} req) (hform/submit-button "Create"))]))) -(defn show-schema! [schema attrs req] +(defn show-schema! [schema attrs access-form req] + (println access-form) (view/layout! :session (:session req) :content @@ -65,7 +72,12 @@ (hform/form-to [:post (path :schema-edit)] (form/render-widgets form schema req) (hform/hidden-field "uuid" (:uuid schema)) - (hform/submit-button "Save")) + (hform/submit-button "Edit")) + [:h2 "Assign to users"] + (hform/form-to [:post (path :schema-assign)] + (form/render-widgets access-form schema req) + (hform/hidden-field "uuid" (:uuid schema)) + (hform/submit-button "Assign")) [:h2 "Attributes"] [:ul.schema-attributes (for [attr attrs] @@ -83,7 +95,7 @@ (hform/form-to [:post (path :attribute-new)] (form/render-widgets attr-form {} req) (hform/hidden-field "schema" (:uuid schema)) - (hform/submit-button "Save")) + (hform/submit-button "Create")) [:h2 "Actions"] (hform/form-to {:class "inline"} [:delete (path :schema-delete schema)] diff --git a/src/wanijo/user/domain.clj b/src/wanijo/user/domain.clj index 44753f1..dac4ef9 100644 --- a/src/wanijo/user/domain.clj +++ b/src/wanijo/user/domain.clj @@ -23,3 +23,15 @@ {:ident ident}) first :n)) + +(neo4j/defquery + all + "MATCH (u:user) + RETURN u + ORDER BY u.ident") + +(defn all! [] + (map :u + (neo4j/exec-query! + all + {})))