From cc30b94d2478534e149283bc4a11ffd6484997a8 Mon Sep 17 00:00:00 2001 From: Josha von Gizycki Date: Mon, 26 Aug 2019 14:49:35 +0200 Subject: [PATCH 1/5] cleanup --- src/wanijo/schema/routes.clj | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/wanijo/schema/routes.clj b/src/wanijo/schema/routes.clj index 99480f2..e1dcb65 100644 --- a/src/wanijo/schema/routes.clj +++ b/src/wanijo/schema/routes.clj @@ -2,7 +2,6 @@ (:require [compojure.core :refer [defroutes GET POST DELETE] :as comp] [ring.util.response :as resp] [formulare.core :as form] - [wanijo.infrastructure.view :as view] [wanijo.infrastructure.routing :refer [register! path]] [wanijo.user.db :as domain-user] [wanijo.schema @@ -21,7 +20,7 @@ (resp/redirect (path :schema-overview))) (schema-view/overview! req))) -(defn delete-schema! [uuid session] +(defn delete-schema! [uuid] (domain/delete! uuid) (resp/redirect (path :schema-overview))) @@ -73,8 +72,8 @@ (POST (register! :schema-assign-schemas "/schema/assign/schemas") [] assign-schemas!) (DELETE (register! :schema-delete "/schema/:uuid") - [uuid :as req] - (delete-schema! uuid (:session req)))) + [uuid] + (delete-schema! uuid))) (defroutes read-routes (GET (register! :schema-show "/schema/:uuid") From b1d7c31a839e006cc8a83939b067bb5cdbc02be7 Mon Sep 17 00:00:00 2001 From: Josha von Gizycki Date: Mon, 26 Aug 2019 14:57:19 +0200 Subject: [PATCH 2/5] some logic into schema/domain --- src/wanijo/schema/db.clj | 109 +++++++++++++++-------------------- src/wanijo/schema/domain.clj | 20 +++++++ 2 files changed, 68 insertions(+), 61 deletions(-) create mode 100644 src/wanijo/schema/domain.clj diff --git a/src/wanijo/schema/db.clj b/src/wanijo/schema/db.clj index 9bd2cad..e97a847 100644 --- a/src/wanijo/schema/db.clj +++ b/src/wanijo/schema/db.clj @@ -1,18 +1,6 @@ (ns wanijo.schema.db - (:require [clojure.spec.alpha :as spec] - [wanijo.specs :as specs] - [wanijo.infrastructure.neo4j :as neo4j])) - -(spec/def ::name - (spec/and ::specs/name (complement empty?))) -(spec/def ::assigned-to - (spec/or :public empty? - :assigned (spec/coll-of ::neo4j/uuid) - :assigned-single ::neo4j/uuid)) -(spec/def ::schema - (spec/keys ::req-un [::name - ::specs/created-at - ::neo4j/uuid])) + (:require [wanijo.infrastructure.neo4j :as neo4j] + [wanijo.schema.domain :as domain])) (neo4j/defquery all-created-by "MATCH (s:schema)-[:created_by]->(u:user) @@ -22,8 +10,8 @@ (defn all-created-by! [user-uuid] (map :s (neo4j/exec-query! - all-created-by - {:uuid user-uuid}))) + all-created-by + {:uuid user-uuid}))) (neo4j/defquery all "MATCH (s:schema) @@ -43,14 +31,14 @@ RETURN s") (defn create-new! [schema-name user-uuid] (->> - (neo4j/exec-query! - create-new - {:u_uuid user-uuid - :name schema-name - :s_uuid (neo4j/uuid) - :created_at (neo4j/now-str)}) - first - :uuid)) + (neo4j/exec-query! + create-new + {:u_uuid user-uuid} + :name schema-name + :s_uuid (neo4j/uuid) + :created_at (neo4j/now-str)) + first + :uuid)) (neo4j/defquery find-by-uuid "MATCH (s:schema) @@ -58,11 +46,11 @@ RETURN s") (defn find-by-uuid! [uuid] (->> - (neo4j/exec-query! - find-by-uuid - {:uuid uuid}) - first - :s)) + (neo4j/exec-query! + find-by-uuid + {:uuid uuid}) + first + :s)) (neo4j/defquery schema-creator "MATCH (s:schema)-->(u:user) @@ -70,11 +58,11 @@ RETURN u.uuid as uuid") (defn find-schema-creator! [uuid] (->> - (neo4j/exec-query! - schema-creator - {:uuid uuid}) - first - :uuid)) + (neo4j/exec-query! + schema-creator + {:uuid uuid}) + first + :uuid)) (neo4j/defquery schema-permissions "MATCH (s:schema {uuid:{schema_uuid}}) @@ -86,13 +74,12 @@ -[:permission {type:{type}}]- (s)) AS is_public") (defn has-user-permission? [perm-type schema-uuid user-uuid] - (let [permissions (first (neo4j/exec-query! schema-permissions - {:schema_uuid schema-uuid - :user_uuid user-uuid - :type perm-type})) - public? (:is_public permissions) - user? (:user_has_permission permissions)] - (or public? user?))) + (let [perms (first + (neo4j/exec-query! schema-permissions + {:schema_uuid schema-uuid + :user_uuid user-uuid + :type perm-type}))] + (domain/has-user-permission? perms))) (defn has-user-write-permissions? [schema-uuid user-uuid] (has-user-permission? "write" schema-uuid user-uuid)) (defn has-user-read-permissions? [schema-uuid user-uuid] @@ -120,8 +107,8 @@ DELETE c, s") (defn delete! [uuid] (neo4j/exec-query! - delete - {:uuid uuid})) + delete + {:uuid uuid})) (neo4j/defquery edit "MATCH (s:schema) @@ -129,8 +116,8 @@ SET s.name = {name}") (defn edit! [schema] (neo4j/exec-query! - edit - schema)) + edit + schema)) (neo4j/defquery assigned-users "MATCH (s:schema)-[p:permission]-(u:user) @@ -139,8 +126,8 @@ ORDER BY u.ident") (defn assigned-users! [uuid] (neo4j/exec-query! - assigned-users - {:uuid uuid})) + assigned-users + {:uuid uuid})) (neo4j/defquery assigned-schemas "MATCH (s1:schema)-[p:permission]-(s2:schema) @@ -149,8 +136,8 @@ ORDER BY s2.name") (defn assigned-schemas! [uuid] (neo4j/exec-query! - assigned-schemas - {:uuid uuid})) + assigned-schemas + {:uuid uuid})) (defn find-with-assigned-entities! [uuid] (let [users (reduce #(case (-> %2 :p :type) @@ -160,7 +147,7 @@ {:write [] :read []} (assigned-users! uuid)) - schemas (map #(-> % :s2 :uuid) (assigned-schemas! uuid))] + schemas (map #(-> % :s2 :uuid) (assigned-schemas! uuid))] (assoc (find-by-uuid! uuid) :assigned-read-users (:read users) :assigned-write-users (:write users) @@ -178,13 +165,13 @@ CREATE (s)<-[:permission{type:{permtype}}]-(u)") (defn assign-users! [uuid users permission] (neo4j/exec-queries! - [remove-assignments - {:uuid uuid - :permtype permission}] - [create-assignments - {:uuid uuid - :users users - :permtype permission}])) + [remove-assignments + {:uuid uuid + :permtype permission}] + [create-assignments + {:uuid uuid + :users users + :permtype permission}])) (neo4j/defquery remove-schema-assignments "MATCH (s1:schema)-[p:permission]-(s2:schema) @@ -197,10 +184,10 @@ CREATE (s1)-[:permission]->(s2)") (defn assign-schemas! [uuid schemas] (neo4j/exec-queries! - [remove-schema-assignments - {:uuid uuid}] - [create-schema-assignments - {:uuid uuid :schemas schemas}])) + [remove-schema-assignments + {:uuid uuid}] + [create-schema-assignments + {:uuid uuid :schemas schemas}])) (neo4j/defquery find-by-instance "MATCH (i:instance {uuid:{uuid}})-[:of]->(s:schema) diff --git a/src/wanijo/schema/domain.clj b/src/wanijo/schema/domain.clj new file mode 100644 index 0000000..b7dee76 --- /dev/null +++ b/src/wanijo/schema/domain.clj @@ -0,0 +1,20 @@ +(ns wanijo.schema.domain + (:require [clojure.spec.alpha :as spec] + [wanijo.specs :as specs] + [wanijo.infrastructure.neo4j :as neo4j])) + +(spec/def ::name + (spec/and ::specs/name (complement empty?))) +(spec/def ::assigned-to + (spec/or :public empty? + :assigned (spec/coll-of ::neo4j/uuid) + :assigned-single ::neo4j/uuid)) +(spec/def ::schema + (spec/keys ::req-un [::name + ::specs/created-at + ::neo4j/uuid])) + +(defn has-user-permission? + [{public? :is_public + user-permission :user_has_permission}] + (or public? user-permission)) From 8a9c2a7a5b2884fe6820df7da6de114f38c8e8d4 Mon Sep 17 00:00:00 2001 From: Josha von Gizycki Date: Mon, 26 Aug 2019 14:59:42 +0200 Subject: [PATCH 3/5] remove unused function --- src/wanijo/schema/db.clj | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/wanijo/schema/db.clj b/src/wanijo/schema/db.clj index e97a847..fc9894d 100644 --- a/src/wanijo/schema/db.clj +++ b/src/wanijo/schema/db.clj @@ -33,10 +33,10 @@ (->> (neo4j/exec-query! create-new - {:u_uuid user-uuid} - :name schema-name - :s_uuid (neo4j/uuid) - :created_at (neo4j/now-str)) + {:u_uuid user-uuid + :name schema-name + :s_uuid (neo4j/uuid) + :created_at (neo4j/now-str)}) first :uuid)) @@ -52,18 +52,6 @@ first :s)) -(neo4j/defquery schema-creator - "MATCH (s:schema)-->(u:user) - WHERE s.uuid = {uuid} - RETURN u.uuid as uuid") -(defn find-schema-creator! [uuid] - (->> - (neo4j/exec-query! - schema-creator - {:uuid uuid}) - first - :uuid)) - (neo4j/defquery schema-permissions "MATCH (s:schema {uuid:{schema_uuid}}) RETURN From 6d256c6d37cb739002a1a4768d30951fe5a7c796 Mon Sep 17 00:00:00 2001 From: Josha von Gizycki Date: Mon, 26 Aug 2019 15:51:28 +0200 Subject: [PATCH 4/5] rework views in instance domain --- src/wanijo/instance/db.clj | 24 +- src/wanijo/instance/domain.clj | 10 +- src/wanijo/instance/routes.clj | 88 +++---- src/wanijo/instance/view.clj | 263 -------------------- src/wanijo/instance/view/edit.clj | 75 ++++++ src/wanijo/instance/view/instances.clj | 36 +++ src/wanijo/instance/view/link_selection.clj | 21 ++ src/wanijo/instance/view/show.clj | 126 ++++++++++ src/wanijo/instance/view/starred.clj | 27 ++ src/wanijo/instance/view/view.clj | 6 + 10 files changed, 362 insertions(+), 314 deletions(-) delete mode 100644 src/wanijo/instance/view.clj create mode 100644 src/wanijo/instance/view/edit.clj create mode 100644 src/wanijo/instance/view/instances.clj create mode 100644 src/wanijo/instance/view/link_selection.clj create mode 100644 src/wanijo/instance/view/show.clj create mode 100644 src/wanijo/instance/view/starred.clj create mode 100644 src/wanijo/instance/view/view.clj diff --git a/src/wanijo/instance/db.clj b/src/wanijo/instance/db.clj index 327ad45..6dba364 100644 --- a/src/wanijo/instance/db.clj +++ b/src/wanijo/instance/db.clj @@ -9,16 +9,28 @@ WHERE s.uuid = {uuid} OPTIONAL MATCH (i)-[:tagged_with]->(t:tag) - RETURN i, t") + OPTIONAL MATCH + (i)<-[:of]-(p:property), + (p)-[:of]->(a:attribute) + RETURN i, t, p, a") +(defn flatten-grouped-rows [instance grouped-rows] + {:post [(spec/assert ::domain-instance/instance-with-tags-and-props %)]} + (assoc instance + :tags (->> grouped-rows + (map :t) + (filter some?) + distinct) + :properties (->> grouped-rows + (filter #(some? (:p %))) + (map #(assoc (:p %) + :attribute (:a %))) + distinct))) (defn find-by-schema! [schema-uuid] - {:post [(spec/assert ::domain-instance/instances-with-tags %)]} + {:post [(spec/assert ::domain-instance/instances-with-tags-and-props %)]} (->> (neo4j/exec-query! findy-by-schema {:uuid schema-uuid}) (group-by :i) - (map #(assoc (key %) - :tags (->> (val %) - (map :t) - (filter some?)))) + (map #(flatten-grouped-rows (key %) (val %))) (sort-by :name))) (neo4j/defquery create-instance diff --git a/src/wanijo/instance/domain.clj b/src/wanijo/instance/domain.clj index d0a0fbe..b3cf7e9 100644 --- a/src/wanijo/instance/domain.clj +++ b/src/wanijo/instance/domain.clj @@ -24,9 +24,15 @@ (spec/def ::contains-schema (spec/keys :req-un [::db-schema/schema])) -(spec/def ::instances-with-tags +(spec/def ::instances-with-tags-and-props (spec/coll-of (spec/merge ::instance - (spec/keys :req-un [::tags])))) + (spec/keys :req-un [::tags + ::properties])))) + +(spec/def ::instance-with-tags-and-props + (spec/merge ::instance + (spec/keys :req-un [::tags + ::properties]))) (spec/def ::instance-with-schema (spec/merge ::instance ::contains-schema)) diff --git a/src/wanijo/instance/routes.clj b/src/wanijo/instance/routes.clj index feabe2b..ce47b09 100644 --- a/src/wanijo/instance/routes.clj +++ b/src/wanijo/instance/routes.clj @@ -3,22 +3,24 @@ GET POST DELETE]] [ring.util.response :as resp] [formulare.core :as form] - [wanijo.instance - [view :as view] - [db :as domain] - [forms :as forms-inst]] - [wanijo.schema - [db :as domain-schema] - [middleware :as middleware-schema]] + [wanijo.instance.view.edit :refer [edit]] + [wanijo.instance.view.instances :refer [instances]] + [wanijo.instance.view.show :refer [show]] + [wanijo.instance.view.link-selection :refer [link-selection]] + [wanijo.instance.view.starred :refer [starred]] + [wanijo.instance.db :as domain] + [wanijo.instance.forms :as forms-inst] + [wanijo.schema.db :as domain-schema] + [wanijo.schema.middleware :as middleware-schema] [wanijo.link.db :as domain-link] [wanijo.infrastructure.routing :refer [register! path]] [wanijo.attribute.db :as db-attr])) (defn list! [schema-uuid req] - (view/list! (domain-schema/find-by-uuid! schema-uuid) - (domain/find-by-schema! schema-uuid) - (forms-inst/with-attributes (db-attr/required! schema-uuid)) - req)) + (instances (domain-schema/find-by-uuid! schema-uuid) + (domain/find-by-schema! schema-uuid) + (forms-inst/with-attributes (db-attr/required! schema-uuid)) + req)) (defn new! [req] (let [schema-uuid (get-in req [:params :schema-uuid]) @@ -46,9 +48,9 @@ :starred (domain/is-starred! uuid user-uuid))] - (view/show! instance - (domain-schema/accessible-schemas! user-uuid) - req))) + (show instance + (domain-schema/accessible-schemas! user-uuid) + req))) (defn form! [attrs] (forms-inst/with-attributes attrs)) @@ -57,11 +59,11 @@ (let [instance (instance! uuid) attrs (db-attr/find-by-instance! uuid) user-uuid (get-in req [:session :uuid])] - (view/edit! instance - (form! attrs) - (forms-inst/instance->form-data instance) - (domain-schema/accessible-schemas! user-uuid) - req))) + (edit instance + (form! attrs) + (forms-inst/instance->form-data instance) + (domain-schema/accessible-schemas! user-uuid) + req))) (defn edit! [uuid req] (let [attrs (db-attr/find-by-instance! uuid) @@ -74,7 +76,7 @@ (resp/redirect (path :instance-show instance))) (show! uuid req)))) -(defn delete! [uuid req] +(defn delete! [uuid] (let [schema (domain-schema/find-by-instance! uuid)] (domain/delete! uuid) (resp/redirect (path :instance-list @@ -82,13 +84,13 @@ (defn link-form! [schema-uuid] (forms-inst/link-form - (domain/find-by-schema! schema-uuid))) + (domain/find-by-schema! schema-uuid))) (defn link-selection! [uuid schema-uuid req] - (view/link-selection (instance! uuid) - (domain-schema/find-by-uuid! schema-uuid) - (link-form! schema-uuid) - req)) + (link-selection (instance! uuid) + (domain-schema/find-by-uuid! schema-uuid) + (link-form! schema-uuid) + req)) (defn create-link! [uuid schema-uuid req] (let [form (link-form! schema-uuid)] @@ -101,7 +103,7 @@ (resp/redirect (path :instance-edit-form {:uuid uuid}))) (link-selection! uuid schema-uuid req)))) -(defn delete-link! [uuid link-uuid req] +(defn delete-link! [uuid link-uuid] (domain-link/delete! link-uuid) (resp/redirect (path :instance-edit-form {:uuid uuid}))) @@ -116,19 +118,19 @@ (resp/redirect (path :instance-show {:uuid uuid}))) (defn list-starred! [req] - (view/list-starred - (domain/starred-by-user! (-> req :session :uuid)) - req)) + (starred + (domain/starred-by-user! (-> req :session :uuid)) + req)) (defroutes routes (wrap-routes - (GET (register! :instance-list "/instance/list/:schema-uuid") - [schema-uuid :as req] - (list! schema-uuid req)) - (middleware-schema/wrap-allowed-to-read - #(get-in % [:params :schema-uuid]))) + (GET (register! :instance-list "/instance/list/:schema-uuid") + [schema-uuid :as req] + (list! schema-uuid req)) + (middleware-schema/wrap-allowed-to-read + #(get-in % [:params :schema-uuid]))) (POST (register! :instance-new "/instance/new") [] - new!) + new!) (GET (register! :instance-show "/instance/:uuid") [uuid :as req] (show! uuid req)) @@ -137,10 +139,10 @@ (edit-form! uuid req)) (POST (register! :instance-edit "/instance/:uuid") [uuid :as req] - (edit! uuid req)) + (edit! uuid req)) (DELETE (register! :instance-delete "/instance/:uuid") - [uuid :as req] - (delete! uuid req)) + [uuid] + (delete! uuid)) (GET (register! :instance-link-selection "/instance/:uuid/link/:schema-uuid") [uuid schema-uuid :as req] @@ -148,19 +150,19 @@ (POST (register! :instance-link-create "/instance/:uuid/link/:schema-uuid") [uuid schema-uuid :as req] - (create-link! uuid schema-uuid req)) + (create-link! uuid schema-uuid req)) (DELETE (register! :instance-link-delete "/instance/:uuid/link/:link-uuid") - [uuid link-uuid :as req] - (delete-link! uuid link-uuid req)) + [uuid link-uuid] + (delete-link! uuid link-uuid)) (POST (register! :instance-mark-starred "/instance/:uuid/starred") [uuid :as req] - (mark-starred! uuid req)) + (mark-starred! uuid req)) (DELETE (register! :instance-remove-starred "/instance/:uuid/starred") [uuid :as req] - (remove-starred! uuid req)) + (remove-starred! uuid req)) (GET (register! :instance-list-starred "/instance/starred/list") [:as req] (list-starred! req))) diff --git a/src/wanijo/instance/view.clj b/src/wanijo/instance/view.clj deleted file mode 100644 index 7a59d8d..0000000 --- a/src/wanijo/instance/view.clj +++ /dev/null @@ -1,263 +0,0 @@ -(ns wanijo.instance.view - (:require [hiccup - [form :as hform] - [core :refer [h]]] - [ring.util.anti-forgery :refer [anti-forgery-field]] - [markdown.core :as md] - [formulare.core :as form] - [wanijo.tag.view :as view-tag] - [wanijo.visualisation.viz :as viz] - [wanijo.infrastructure - [view :as view] - [routing :refer [path]] - [time :refer [prettify-dt]]])) - -(defn tags-for-search [{tags :tags}] - [:span.tags-for-search - (reduce #(str %1 ":" (:name %2)) "" tags)]) - -(defn list! [schema instances new-form req] - (view/layout! - :request req - :content - [[:h1 "All Instances of schema " - [:span.schema-title__name (h (:name schema))]] - [:h1 "New Instance"] - (hform/form-to [:post (path :instance-new)] - (form/render-widgets new-form {} req) - (hform/hidden-field "schema-uuid" - (:uuid schema)) - (hform/submit-button "Create!")) - [:table - [:thead - [:tr - [:th "Name"] - [:th "Updated"] - [:th "Created"]]] - [:tbody - (for [instance instances] - [:tr - [:td - [:a {:href (path :instance-show instance)} - (h (:name instance))] - (tags-for-search instance)] - [:td (prettify-dt (:updated_at instance))] - [:td (prettify-dt (:created_at instance))]])]]])) - -(defn list-starred [instances req] - (view/layout! - :request req - :content - [[:h1 "Starred instances"] - [:table - [:thead - [:tr - [:th "Name"] - [:th "Starred"] - [:th "Updated"] - [:th "Created"]]] - [:tbody - (for [instance instances] - [:tr - [:td - [:a {:href (path :instance-show instance)} - (h (:name instance))]] - [:td (prettify-dt (:starred_at instance))] - [:td (prettify-dt (:updated_at instance))] - [:td (prettify-dt (:created_at instance))]])]]])) - -(defn show! [instance schemas req] - (view/layout! - :request req - :content - [[:h1 - (if (:starred instance) - (hform/form-to {:class "inline"} - [:delete (path :instance-mark-starred instance)] - (anti-forgery-field) - (hform/submit-button "★")) - (hform/form-to {:class "inline"} - [:post (path :instance-mark-starred instance)] - (anti-forgery-field) - (hform/submit-button "☆"))) - " " - (h (-> instance :schema :name)) - " " - [:small (h (:name instance))]] - [:p [:small - [:a {:href (path :instance-list - {:schema-uuid (-> instance :schema :uuid)})} - "Back to List"] - " | " - [:a {:href (path :instance-edit-form instance)} - "Edit Instance"] - " | " - [:a {:href (path :vis-explore {:instance-uuid (:uuid instance)})} - "Explore from here"]]] - (when (seq (:tags instance)) - [:section.tags - (view-tag/tag-list (:tags instance))]) - (when (seq (:properties instance)) - [:section.properties - [:h2 "Properties"] - (for [prop (:properties instance) - :let [attr (:attribute prop) - type (:type attr) - render-fn (case type - "date" #(str (prettify-dt %)) - "markdown" md/md-to-html-string - #(str "

" % "

"))]] - (list [:h3 (h (:name attr))] - [:div {:class (str "instance-content " - "attr-type-" type)} - (render-fn (:value prop))]))]) - (when (or (seq (:links-out instance)) - (seq (:links-in instance))) - [:section.visualisation - [:h2 "Visualisation"] - [:p (viz/single-instance instance)]]) - (when (seq (:links-out instance)) - [:section.links-out - [:h2 "Outgoing Links"] - [:table - [:thead - [:tr - [:th "Name"] - [:th "Instance"] - [:th "Schema"] - [:th "Created"]]] - [:tbody - (for [{:keys [link target schema] :as row} (:links-out instance) - :let [name (:name link) - empty (empty? name) - name (if empty [:i "empty"] (h name))]] - [:tr - [:td - name - (tags-for-search row)] - [:td [:a {:href (path :instance-show target)} - (h (:name target))]] - [:td [:a {:href (path :instance-list - {:schema-uuid (:uuid schema)})} - (h (:name schema))]] - [:td (prettify-dt (:created_at link))]])]]]) - (when (seq (:links-in instance)) - [:section.links-in - [:h2 "Incoming Links"] - [:table - [:thead - [:tr - [:th "Name"] - [:th "Instance"] - [:th "Schema"] - [:th "Created"]]] - [:tbody - (for [{:keys [link source schema] :as row} (:links-in instance) - :let [name (:name link) - empty (empty? name) - name (if empty [:i "empty"] (h name))]] - [:tr - [:td - name - (tags-for-search row)] - [:td [:a {:href (path :instance-show source)} - (h (:name source))]] - [:td [:a {:href (path :instance-list - {:schema-uuid (:uuid schema)})} - (h (:name schema))]] - [:td (prettify-dt (:created_at link))]])]]]) - [:section.quick-edits - [:h2 "Quick edits"] - [:section.link-instance - [:h3 "Link Instance with Instance of Schema..."] - [:ul - (for [schema schemas] - [:li - [:a {:href (path :instance-link-selection - {:uuid (:uuid instance) - :schema-uuid (:uuid schema)})} - (h (:name schema))]])]] - [:section.tag-instance - [:h3 "Add or create Tags"] - (view-tag/new-tag-form instance)]]])) - -(defn edit! [instance form form-data schemas req] - (view/layout! - :request req - :content - [[:h1 - (h (-> instance :schema :name)) - " " - [:small (h (:name instance))]] - [:p [:small - [:a {:href (path :instance-list - {:schema-uuid (-> instance :schema :uuid)})} - "Back to List"] - " | " - [:a {:href (path :instance-show instance)} - "Back to Instance"]]] - [:section.edit-instance - [:h2 "Edit Instance"] - (hform/form-to [:post (path :instance-edit instance)] - (form/render-widgets form form-data req) - (hform/submit-button "Edit!")) - (hform/form-to [:delete (path :instance-delete instance)] - (anti-forgery-field) - (view/delete-btn))] - (when (seq (:links-out instance)) - [:section.links-out - [:h2 "Outgoing Links"] - [:table - [:thead - [:tr - [:th "Name"] - [:th "Instance"] - [:th "Schema"] - [:th "Created"] - [:th]]] - [:tbody - (for [{:keys [link target schema]} (:links-out instance) - :let [name (:name link) - empty (empty? name) - name (if empty [:i "empty"] (h name))]] - [:tr - [:td name] - [:td [:a {:href (path :instance-show target)} - (h (:name target))]] - [:td [:a {:href (path :instance-list - {:schema-uuid (:uuid schema)})} - (h (:name schema))]] - [:td (prettify-dt (:created_at link))] - [:td (hform/form-to [:delete (path :instance-link-delete - {:uuid (:uuid instance) - :link-uuid (:uuid link)})] - (anti-forgery-field) - (view/delete-btn))]])]]]) - (when (seq (:tags instance)) - [:section.tags - [:h2 "Tags"] - (view-tag/tag-table instance)]) - [:section.link-instance - [:h2 "Link Instance with Instance of Schema..."] - [:ul - (for [schema schemas] - [:li - [:a {:href (path :instance-link-selection - {:uuid (:uuid instance) - :schema-uuid (:uuid schema)})} - (h (:name schema))]])]]])) - -(defn link-selection [instance schema form req] - (view/layout! - :request req - :content - [[:h1 - [:small "Link " (-> instance :schema :name) " "] - (h (:name instance)) - [:small " with "] - (h (:name schema))] - (hform/form-to [:post (path :instance-link-create - {:uuid (:uuid instance) - :schema-uuid (:uuid schema)})] - (form/render-widgets form nil req) - (hform/submit-button "Link!"))])) diff --git a/src/wanijo/instance/view/edit.clj b/src/wanijo/instance/view/edit.clj new file mode 100644 index 0000000..4405d27 --- /dev/null +++ b/src/wanijo/instance/view/edit.clj @@ -0,0 +1,75 @@ +(ns wanijo.instance.view.edit + (:require [hiccup.form :as hform] + [hiccup.core :refer [h]] + [ring.util.anti-forgery :refer [anti-forgery-field]] + [wanijo.infrastructure.view :as view] + [wanijo.infrastructure.routing :refer [path]] + [wanijo.infrastructure.time :refer [prettify-dt]] + [wanijo.tag.view :as view-tag] + [formulare.core :as form])) + +(defn edit [instance form form-data schemas req] + (view/layout! + :request req + :content + [[:h1 + (h (-> instance :schema :name)) + " " + [:small (h (:name instance))]] + [:p [:small + [:a {:href (path :instance-list + {:schema-uuid (-> instance :schema :uuid)})} + "Back to List"] + " | " + [:a {:href (path :instance-show instance)} + "Back to Instance"]]] + [:section.edit-instance + [:h2 "Edit Instance"] + (hform/form-to [:post (path :instance-edit instance)] + (form/render-widgets form form-data req) + (hform/submit-button "Edit!")) + (hform/form-to [:delete (path :instance-delete instance)] + (anti-forgery-field) + (view/delete-btn))] + (when (seq (:links-out instance)) + [:section.links-out + [:h2 "Outgoing Links"] + [:table + [:thead + [:tr + [:th "Name"] + [:th "Instance"] + [:th "Schema"] + [:th "Created"] + [:th]]] + [:tbody + (for [{:keys [link target schema]} (:links-out instance) + :let [name (:name link) + empty (empty? name) + name (if empty [:i "empty"] (h name))]] + [:tr + [:td name] + [:td [:a {:href (path :instance-show target)} + (h (:name target))]] + [:td [:a {:href (path :instance-list + {:schema-uuid (:uuid schema)})} + (h (:name schema))]] + [:td (prettify-dt (:created_at link))] + [:td (hform/form-to [:delete (path :instance-link-delete + {:uuid (:uuid instance) + :link-uuid (:uuid link)})] + (anti-forgery-field) + (view/delete-btn))]])]]]) + (when (seq (:tags instance)) + [:section.tags + [:h2 "Tags"] + (view-tag/tag-table instance)]) + [:section.link-instance + [:h2 "Link Instance with Instance of Schema..."] + [:ul + (for [schema schemas] + [:li + [:a {:href (path :instance-link-selection + {:uuid (:uuid instance) + :schema-uuid (:uuid schema)})} + (h (:name schema))]])]]])) diff --git a/src/wanijo/instance/view/instances.clj b/src/wanijo/instance/view/instances.clj new file mode 100644 index 0000000..70e7063 --- /dev/null +++ b/src/wanijo/instance/view/instances.clj @@ -0,0 +1,36 @@ +(ns wanijo.instance.view.instances + (:require [hiccup.form :as hform] + [hiccup.core :refer [h]] + [formulare.core :as form] + [wanijo.instance.view.view :as view-instance] + [wanijo.infrastructure.view :as view] + [wanijo.infrastructure.routing :refer [path]] + [wanijo.infrastructure.time :refer [prettify-dt]])) + +(defn instances [schema instances new-form req] + (view/layout! + :request req + :content + [[:h1 "All Instances of schema " + [:span.schema-title__name (h (:name schema))]] + [:h1 "New Instance"] + (hform/form-to [:post (path :instance-new)] + (form/render-widgets new-form {} req) + (hform/hidden-field "schema-uuid" + (:uuid schema)) + (hform/submit-button "Create!")) + [:table + [:thead + [:tr + [:th "Name"] + [:th "Updated"] + [:th "Created"]]] + [:tbody + (for [instance instances] + [:tr + [:td + [:a {:href (path :instance-show instance)} + (h (:name instance))] + (view-instance/tags-for-search instance)] + [:td (prettify-dt (:updated_at instance))] + [:td (prettify-dt (:created_at instance))]])]]])) diff --git a/src/wanijo/instance/view/link_selection.clj b/src/wanijo/instance/view/link_selection.clj new file mode 100644 index 0000000..ccdf25f --- /dev/null +++ b/src/wanijo/instance/view/link_selection.clj @@ -0,0 +1,21 @@ +(ns wanijo.instance.view.link-selection + (:require [hiccup.form :as hform] + [hiccup.core :refer [h]] + [wanijo.infrastructure.view :as view] + [wanijo.infrastructure.routing :refer [path]] + [formulare.core :as form])) + +(defn link-selection [instance schema form req] + (view/layout! + :request req + :content + [[:h1 + [:small "Link " (-> instance :schema :name) " "] + (h (:name instance)) + [:small " with "] + (h (:name schema))] + (hform/form-to [:post (path :instance-link-create + {:uuid (:uuid instance) + :schema-uuid (:uuid schema)})] + (form/render-widgets form nil req) + (hform/submit-button "Link!"))])) diff --git a/src/wanijo/instance/view/show.clj b/src/wanijo/instance/view/show.clj new file mode 100644 index 0000000..2f4a29a --- /dev/null +++ b/src/wanijo/instance/view/show.clj @@ -0,0 +1,126 @@ +(ns wanijo.instance.view.show + (:require [hiccup.form :as hform] + [hiccup.core :refer [h]] + [ring.util.anti-forgery :refer [anti-forgery-field]] + [wanijo.infrastructure.view :as view] + [wanijo.infrastructure.routing :refer [path]] + [wanijo.infrastructure.time :refer [prettify-dt]] + [wanijo.instance.view.view :as view-instance] + [wanijo.tag.view :as view-tag] + [markdown.core :as md] + [wanijo.visualisation.viz :as viz])) + +(defn show [instance schemas req] + (view/layout! + :request req + :content + [[:h1 + (if (:starred instance) + (hform/form-to {:class "inline"} + [:delete (path :instance-mark-starred instance)] + (anti-forgery-field) + (hform/submit-button "★")) + (hform/form-to {:class "inline"} + [:post (path :instance-mark-starred instance)] + (anti-forgery-field) + (hform/submit-button "☆"))) + " " + (h (-> instance :schema :name)) + " " + [:small (h (:name instance))]] + [:p [:small + [:a {:href (path :instance-list + {:schema-uuid (-> instance :schema :uuid)})} + "Back to List"] + " | " + [:a {:href (path :instance-edit-form instance)} + "Edit Instance"] + " | " + [:a {:href (path :vis-explore {:instance-uuid (:uuid instance)})} + "Explore from here"]]] + (when (seq (:tags instance)) + [:section.tags + (view-tag/tag-list (:tags instance))]) + (when (seq (:properties instance)) + [:section.properties + [:h2 "Properties"] + (for [prop (:properties instance) + :let [attr (:attribute prop) + type (:type attr) + render-fn (case type + "date" #(str (prettify-dt %)) + "markdown" md/md-to-html-string + #(str "

" % "

"))]] + (list [:h3 (h (:name attr))] + [:div {:class (str "instance-content " + "attr-type-" type)} + (render-fn (:value prop))]))]) + (when (or (seq (:links-out instance)) + (seq (:links-in instance))) + [:section.visualisation + [:h2 "Visualisation"] + [:p (viz/single-instance instance)]]) + (when (seq (:links-out instance)) + [:section.links-out + [:h2 "Outgoing Links"] + [:table + [:thead + [:tr + [:th "Name"] + [:th "Instance"] + [:th "Schema"] + [:th "Created"]]] + [:tbody + (for [{:keys [link target schema] :as row} (:links-out instance) + :let [name (:name link) + empty (empty? name) + name (if empty [:i "empty"] (h name))]] + [:tr + [:td + name + (view-instance/tags-for-search row)] + [:td [:a {:href (path :instance-show target)} + (h (:name target))]] + [:td [:a {:href (path :instance-list + {:schema-uuid (:uuid schema)})} + (h (:name schema))]] + [:td (prettify-dt (:created_at link))]])]]]) + (when (seq (:links-in instance)) + [:section.links-in + [:h2 "Incoming Links"] + [:table + [:thead + [:tr + [:th "Name"] + [:th "Instance"] + [:th "Schema"] + [:th "Created"]]] + [:tbody + (for [{:keys [link source schema] :as row} (:links-in instance) + :let [name (:name link) + empty (empty? name) + name (if empty [:i "empty"] (h name))]] + [:tr + [:td + name + (view-instance/tags-for-search row)] + [:td [:a {:href (path :instance-show source)} + (h (:name source))]] + [:td [:a {:href (path :instance-list + {:schema-uuid (:uuid schema)})} + (h (:name schema))]] + [:td (prettify-dt (:created_at link))]])]]]) + [:section.quick-edits + [:h2 "Quick edits"] + [:section.link-instance + [:h3 "Link Instance with Instance of Schema..."] + [:ul + (for [schema schemas] + [:li + [:a {:href (path :instance-link-selection + {:uuid (:uuid instance) + :schema-uuid (:uuid schema)})} + (h (:name schema))]])]] + [:section.tag-instance + [:h3 "Add or create Tags"] + (view-tag/new-tag-form instance)]]])) diff --git a/src/wanijo/instance/view/starred.clj b/src/wanijo/instance/view/starred.clj new file mode 100644 index 0000000..cedc18c --- /dev/null +++ b/src/wanijo/instance/view/starred.clj @@ -0,0 +1,27 @@ +(ns wanijo.instance.view.starred + (:require [hiccup.core :refer [h]] + [wanijo.infrastructure.view :as view] + [wanijo.infrastructure.routing :refer [path]] + [wanijo.infrastructure.time :refer [prettify-dt]])) + +(defn starred [instances req] + (view/layout! + :request req + :content + [[:h1 "Starred instances"] + [:table + [:thead + [:tr + [:th "Name"] + [:th "Starred"] + [:th "Updated"] + [:th "Created"]]] + [:tbody + (for [instance instances] + [:tr + [:td + [:a {:href (path :instance-show instance)} + (h (:name instance))]] + [:td (prettify-dt (:starred_at instance))] + [:td (prettify-dt (:updated_at instance))] + [:td (prettify-dt (:created_at instance))]])]]])) diff --git a/src/wanijo/instance/view/view.clj b/src/wanijo/instance/view/view.clj new file mode 100644 index 0000000..7be7615 --- /dev/null +++ b/src/wanijo/instance/view/view.clj @@ -0,0 +1,6 @@ +(ns wanijo.instance.view.view + (:require [hiccup.core :refer [h]])) + +(defn tags-for-search [{tags :tags}] + [:span.tags-for-search + (reduce #(str %1 ":" (h (:name %2))) "" tags)]) From 53bca6a69828bab1bd28dd991418ee4236ea08e3 Mon Sep 17 00:00:00 2001 From: Josha von Gizycki Date: Mon, 26 Aug 2019 16:04:41 +0200 Subject: [PATCH 5/5] show required attributes in instance list --- src/wanijo/instance/domain.clj | 7 ++----- src/wanijo/instance/view/instances.clj | 10 ++++++++++ src/wanijo/schema/db.clj | 23 +++++++++++++++-------- src/wanijo/schema/domain.clj | 7 +++++++ 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/wanijo/instance/domain.clj b/src/wanijo/instance/domain.clj index b3cf7e9..65641c9 100644 --- a/src/wanijo/instance/domain.clj +++ b/src/wanijo/instance/domain.clj @@ -24,15 +24,12 @@ (spec/def ::contains-schema (spec/keys :req-un [::db-schema/schema])) -(spec/def ::instances-with-tags-and-props - (spec/coll-of (spec/merge ::instance - (spec/keys :req-un [::tags - ::properties])))) - (spec/def ::instance-with-tags-and-props (spec/merge ::instance (spec/keys :req-un [::tags ::properties]))) +(spec/def ::instances-with-tags-and-props + (spec/coll-of ::instance-with-tags-and-props)) (spec/def ::instance-with-schema (spec/merge ::instance ::contains-schema)) diff --git a/src/wanijo/instance/view/instances.clj b/src/wanijo/instance/view/instances.clj index 70e7063..c8e4fda 100644 --- a/src/wanijo/instance/view/instances.clj +++ b/src/wanijo/instance/view/instances.clj @@ -23,6 +23,8 @@ [:thead [:tr [:th "Name"] + (map (fn [attr] [:th (h (:name attr))]) + (:req-attrs schema)) [:th "Updated"] [:th "Created"]]] [:tbody @@ -32,5 +34,13 @@ [:a {:href (path :instance-show instance)} (h (:name instance))] (view-instance/tags-for-search instance)] + (map (fn [attr] + [:td (->> (:properties instance) + (filter #(= (:uuid attr) + (-> % :attribute :uuid))) + first + :value + h)]) + (:req-attrs schema)) [:td (prettify-dt (:updated_at instance))] [:td (prettify-dt (:created_at instance))]])]]])) diff --git a/src/wanijo/schema/db.clj b/src/wanijo/schema/db.clj index fc9894d..e8c4ca0 100644 --- a/src/wanijo/schema/db.clj +++ b/src/wanijo/schema/db.clj @@ -1,6 +1,7 @@ (ns wanijo.schema.db (:require [wanijo.infrastructure.neo4j :as neo4j] - [wanijo.schema.domain :as domain])) + [wanijo.schema.domain :as domain] + [clojure.spec.alpha :as spec])) (neo4j/defquery all-created-by "MATCH (s:schema)-[:created_by]->(u:user) @@ -43,14 +44,20 @@ (neo4j/defquery find-by-uuid "MATCH (s:schema) WHERE s.uuid = {uuid} - RETURN s") + OPTIONAL MATCH + (s)<-[:of]-(a:attribute) + WHERE a.required = 1 + RETURN s, a + ORDER BY a.name") (defn find-by-uuid! [uuid] - (->> - (neo4j/exec-query! - find-by-uuid - {:uuid uuid}) - first - :s)) + {:post [(spec/assert ::domain/schema-with-req-attrs %)]} + (let [result (neo4j/exec-query! + find-by-uuid + {:uuid uuid}) + schema (:s (first result))] + (when schema + (assoc schema + :req-attrs (map :a result))))) (neo4j/defquery schema-permissions "MATCH (s:schema {uuid:{schema_uuid}}) diff --git a/src/wanijo/schema/domain.clj b/src/wanijo/schema/domain.clj index b7dee76..64d2f8c 100644 --- a/src/wanijo/schema/domain.clj +++ b/src/wanijo/schema/domain.clj @@ -1,6 +1,7 @@ (ns wanijo.schema.domain (:require [clojure.spec.alpha :as spec] [wanijo.specs :as specs] + [wanijo.attribute.domain :as domain-attr] [wanijo.infrastructure.neo4j :as neo4j])) (spec/def ::name @@ -18,3 +19,9 @@ [{public? :is_public user-permission :user_has_permission}] (or public? user-permission)) + +(spec/def ::req-attrs + (spec/coll-of ::domain-attr/attribute)) +(spec/def ::schema-with-req-attrs + (spec/merge ::schema + :req-un [::req-attrs]))