From af3d368453c4b84b39d6f59b04754531389e956c Mon Sep 17 00:00:00 2001 From: Matthew Huebert Date: Mon, 15 Jan 2024 18:08:11 +0100 Subject: [PATCH] fix prose editing --- src/sb/app/account/ui.cljc | 5 +++-- src/sb/app/board/data.cljc | 12 ++++++------ src/sb/app/board/ui.cljc | 3 +-- src/sb/app/chat/data.cljc | 7 +++---- src/sb/app/chat/ui.cljc | 5 +++-- src/sb/app/field/data.cljc | 2 +- src/sb/app/field/ui.cljc | 29 ++++++++++++++--------------- src/sb/app/membership/data.cljc | 16 ++++------------ src/sb/app/membership/ui.cljc | 4 ++-- src/sb/app/views/header.cljc | 1 - src/sb/authorize.cljc | 32 ++++++++++++++++++++++---------- src/sb/server/core.clj | 9 ++++++--- 12 files changed, 65 insertions(+), 60 deletions(-) diff --git a/src/sb/app/account/ui.cljc b/src/sb/app/account/ui.cljc index 3ec9da6a..b5ae0d41 100644 --- a/src/sb/app/account/ui.cljc +++ b/src/sb/app/account/ui.cljc @@ -14,7 +14,8 @@ [sb.routing :as routing] [sb.util :as u] [yawn.hooks :as h] - [yawn.view :as v])) + [yawn.view :as v] + [sb.authorize :as az])) (defn account:sign-in-with-google [] (v/x @@ -103,7 +104,7 @@ (u/for! [org org :let [projects-by-board (into {} (keep (fn [board] - (when-let [projects (->> (member.data/membership account-id board) + (when-let [projects (->> (az/membership account-id board) :membership/_member (into [] (comp (map :membership/entity) diff --git a/src/sb/app/board/data.cljc b/src/sb/app/board/data.cljc index e40adffa..f7e73225 100644 --- a/src/sb/app/board/data.cljc +++ b/src/sb/app/board/data.cljc @@ -1,15 +1,15 @@ (ns sb.app.board.data (:require [re-db.api :as db] - [sb.app.field.data :as field.data] [sb.app.entity.data :as entity.data] + [sb.app.field.data :as field.data] + [sb.app.field.data :as field.data] [sb.app.membership.data :as member.data] [sb.authorize :as az] [sb.query :as q] [sb.schema :as sch :refer [? s-]] [sb.server.datalevin :as dl] - [sb.validate :as validate] [sb.util :as u] - [sb.app.field.data :as field.data])) + [sb.validate :as validate])) (sch/register! {:board/project-numbers? {s- :boolean @@ -104,7 +104,7 @@ (q/defquery show {:prepare [(az/with-roles :board-id) (member.data/assert-can-view :board-id)]} - [{:keys [board-id membership/roles]}] + [{:as params :keys [board-id membership/roles]}] (u/timed `show (if-let [board (db/pull `[~@entity.data/listing-fields ~@entity.data/site-fields @@ -139,7 +139,7 @@ (q/defquery members {:prepare [(az/with-roles :board-id) (member.data/assert-can-view :board-id)]} - [{:keys [board-id membership/roles]}] + [{:keys [board-id]}] (u/timed `members (->> (db/entity board-id) :membership/_entity (remove (some-fn :entity/deleted-at :entity/archived?)) @@ -158,7 +158,7 @@ (q/defquery drafts {:prepare az/with-account-id} [{:keys [account-id board-id]}] - (->> (member.data/membership account-id board-id) + (->> (az/membership account-id board-id) :membership/_member (filter :entity/draft?) (map #(db/pull project-fields (:membership/entity %))))) diff --git a/src/sb/app/board/ui.cljc b/src/sb/app/board/ui.cljc index fceded64..59b4be2d 100644 --- a/src/sb/app/board/ui.cljc +++ b/src/sb/app/board/ui.cljc @@ -150,8 +150,7 @@ (map (partial member.ui/card {:entity/member-tags (:entity/member-tags board) :entity/member-fields (filter :field/show-on-card? (:entity/member-fields board))}))) - (data/members {:board-id board-id})) - ]]]])) + (data/members {:board-id board-id}))]]]])) (comment [:ul ;; i18n stuff diff --git a/src/sb/app/chat/data.cljc b/src/sb/app/chat/data.cljc index dfab638b..0ac825dc 100644 --- a/src/sb/app/chat/data.cljc +++ b/src/sb/app/chat/data.cljc @@ -1,7 +1,6 @@ (ns sb.app.chat.data (:require [clojure.string :as str] [re-db.api :as db] - [sb.app.membership.data :as m.data] [sb.authorize :as az] [sb.query :as q] [sb.schema :as sch :refer [s-]] @@ -120,7 +119,7 @@ (do (when-not (contains? (into #{} (map :db/id) (:chat/participants chat)) - (:db/id (m.data/membership account-id (:chat/entity chat)))) + (:db/id (az/membership account-id (:chat/entity chat)))) (az/unauthorized! "You are not a participant in this chat.")) chat))) @@ -148,7 +147,7 @@ (last (:chat/messages e))))))))) (defn read? [{:keys [account-id]} {:chat/keys [entity last-message messages read-last]}] - (let [membership-id (:entity/id (m.data/membership account-id entity)) + (let [membership-id (:entity/id (az/membership account-id entity)) last-message-id (:entity/id (or last-message (last messages)))] (or (= (get read-last membership-id) last-message-id) (= membership-id (:entity/id (:entity/created-by last-message)))))) @@ -170,7 +169,7 @@ [{:as params :keys [account-id chat-id message-id]}] (let [chat (dl/entity chat-id) _ (ensure-participant! account-id chat) - membership (m.data/membership account-id (:chat/entity chat))] + membership (az/membership account-id (:chat/entity chat))] (db/transact! [[:db/add chat-id :chat/read-last (merge (:chat/read-last chat) {(:entity/id membership) (sch/unwrap-id message-id)})]])) diff --git a/src/sb/app/chat/ui.cljc b/src/sb/app/chat/ui.cljc index 591bfbae..aae8e1e3 100644 --- a/src/sb/app/chat/ui.cljc +++ b/src/sb/app/chat/ui.cljc @@ -7,6 +7,7 @@ [sb.app.membership.data :as member.data] [sb.app.views.radix :as radix] [sb.app.views.ui :as ui] + [sb.authorize :as az] [sb.i18n :refer [t]] [sb.icons :as icons] [sb.routing :as routing] @@ -39,7 +40,7 @@ (:account/display-name account)]))])) (defn other-participant [account-id chat] - (let [membership-id (:db/id (member.data/membership account-id (:chat/entity chat)))] + (let [membership-id (:db/id (az/membership account-id (:chat/entity chat)))] (u/find-first (:chat/participants chat) #(not= membership-id (:db/id %))))) @@ -105,7 +106,7 @@ !response (h/use-state nil) !scrollable-window (h/use-ref) message (u/guard @!message (complement str/blank?)) - params (assoc params :membership-id (member.data/membership-id account-id (:chat/entity chat))) + params (assoc params :membership-id (az/membership-id account-id (:chat/entity chat))) keydown-handler (fn [e] (when ((ui/keydown-handler {:Enter diff --git a/src/sb/app/field/data.cljc b/src/sb/app/field/data.cljc index ddc023e3..987acc27 100644 --- a/src/sb/app/field/data.cljc +++ b/src/sb/app/field/data.cljc @@ -246,7 +246,7 @@ (defmethod entry-value :field.type/prose [entry] (when-let [value (u/guard (:prose/string entry) (complement str/blank?))] {:prose/string value - :prose/format (:prose/format entry)})) + :prose/format (or (:prose/format entry) :prose.format/markdown)})) (q/defx save-entry! [{:keys [account-id]} parent-id field-id entry] (let [field (db/entity (sch/wrap-id field-id)) diff --git a/src/sb/app/field/ui.cljc b/src/sb/app/field/ui.cljc index cc078847..e4fb198c 100644 --- a/src/sb/app/field/ui.cljc +++ b/src/sb/app/field/ui.cljc @@ -8,6 +8,7 @@ [sb.app.asset.data :as asset.data] [sb.app.asset.ui :as asset.ui] [sb.app.entity.data :as entity.data] + [sb.app.field.data :as field.data] [sb.app.field.data :as data] [sb.app.form.ui :as form.ui] [sb.app.views.radix :as radix] @@ -662,7 +663,6 @@ (str "no match" field))) (defn make-entries-?field [init {:keys [entity/fields]}] - (prn fields) (let [init (for [field fields] (merge #:field-entry{:field field} (get init (:field/id field))))] (io/form @@ -677,21 +677,10 @@ :prose/string prose/?string} :init init) (into {} - (map (fn [{:as entry :keys [field-entry/field]}] - [(:field/id field) (dissoc entry :field-entry/field)]))) + (map (juxt (comp :field/id :field-entry/field) + field.data/entry-value))) u/prune)))) -(ui/defview entries-field - {:make-?field make-entries-?field} - [{:syms [?entries]} - {:as props - :keys [field/can-edit?]}] - - (doall (for [?entry (seq ?entries) - :when (or can-edit? - (data/entry-value @?entry))] - (show-entry-field ?entry props)))) - (ui/defview tags-field {:make-?field (fn [init _props] (io/field :many {:tag/id ?id} @@ -763,4 +752,14 @@ (some-> (get field-entries (:field/id field)) (assoc :field-entry/field field)))) member-fields))] - (map show-entry:card entries))) \ No newline at end of file + (map show-entry:card entries))) + +(ui/defview entries-field + {:make-?field make-entries-?field} + [{:syms [?entries]} + {:as props + :keys [field/can-edit?]}] + (doall (for [?entry (seq ?entries) + :when (or can-edit? + (data/entry-value @?entry))] + (show-entry-field ?entry props)))) \ No newline at end of file diff --git a/src/sb/app/membership/data.cljc b/src/sb/app/membership/data.cljc index 354f91d8..1cedd5cb 100644 --- a/src/sb/app/membership/data.cljc +++ b/src/sb/app/membership/data.cljc @@ -20,9 +20,7 @@ :role/admin :role/editor :role/member]} - :membership/roles (merge sch/keyword - sch/many - {s- [:set :membership/role]}) + :membership/roles {s- [:set :membership/role]} :membership/entity (sch/ref :one) :membership/member (sch/ref :one) @@ -76,25 +74,19 @@ (dissoc (q/pull `[~@entity.data/listing-fields :entity/tags :entity/field-entries - {:membership/entity [:entity/id - :entity/kind + {:membership/entity [~@entity.data/id-fields :entity/member-tags :entity/member-fields]} {:membership/member [~@entity.data/listing-fields :account/display-name]}] (:membership-id params)))) -(defn membership-id [member-id entity-id] - [:entity/id (sch/composite-uuid :membership member-id entity-id)]) - -(def membership (comp db/entity membership-id)) - #?(:clj (defn ensure-membership! [account entity] (let [entity (dl/entity entity)] (case (:entity/kind entity) :project (ensure-membership! account (:entity/parent entity)) - (when-not (dl/resolve-id (membership-id account entity)) + (when-not (dl/resolve-id (az/membership-id account entity)) (throw (ex-info "Not a member" {:status 403}))))))) (defn active-member? [member] @@ -106,7 +98,7 @@ (let [kind (:entity/kind entity)] (case kind (:board :org) (or (:entity/public? entity) - (active-member? (membership account-id entity))) + (active-member? (az/membership account-id entity))) :project (can-view? account-id (:entity/parent entity)) :membership (let [member (:membership/member entity)] (case (:entity/kind member) diff --git a/src/sb/app/membership/ui.cljc b/src/sb/app/membership/ui.cljc index ef988d89..31e3c5f4 100644 --- a/src/sb/app/membership/ui.cljc +++ b/src/sb/app/membership/ui.cljc @@ -9,7 +9,8 @@ [sb.authorize :as az] [sb.color :as color] [sb.icons :as icons] - [sb.routing :as routing])) + [sb.routing :as routing] + [sb.schema :as sch])) (ui/defview show {:route "/m/:membership-id" @@ -84,5 +85,4 @@ (filter (comp (into #{} (map :tag/id) tags) :tag/id)) (map show-tag)) [:div.flex.flex-wrap.gap-1 (map show-tag custom-tags)]] - ;; show card entries on hover? [:div.text-gray-500.contents (field.ui/show-entries member-fields field-entries)]]]])) diff --git a/src/sb/app/views/header.cljc b/src/sb/app/views/header.cljc index 30f8ea6d..9dad6d88 100644 --- a/src/sb/app/views/header.cljc +++ b/src/sb/app/views/header.cljc @@ -116,7 +116,6 @@ (ui/defview entity [{:as entity :keys [entity/title - membership/roles image/avatar]} children] (let [path (routing/entity-path entity 'ui/show)] [:div.header diff --git a/src/sb/authorize.cljc b/src/sb/authorize.cljc index 54a5b379..47918f34 100644 --- a/src/sb/authorize.cljc +++ b/src/sb/authorize.cljc @@ -1,11 +1,14 @@ (ns sb.authorize - (:require [clojure.set :as set] - [re-db.api :as db] + (:require [re-db.api :as db] [sb.server.datalevin :as dl] - [sb.schema :as sch] - [sb.util :as u]) + [sb.schema :as sch]) #?(:clj (:import [re_db.read Entity]))) +(defn membership-id [member-id entity-id] + [:entity/id (sch/composite-uuid :membership member-id entity-id)]) + +(def membership (comp db/entity membership-id)) + (defn editor-role? [roles] (or (:role/self roles) (:role/project-admin roles) @@ -39,12 +42,18 @@ x (db/entity (dl/resolve-id x)))) +(defn membership-account [membership] + (let [member (:membership/member membership)] + (if (= :account (:entity/kind member)) + member + (:membership/member membership)))) + (defn get-roles [account-id entity] (or (case (:entity/kind entity) - :account (when (sch/id= account-id (:entity/id entity)) #{:role/self}) - :membership (when (sch/id= account-id (-> entity :membership/member :entity/id)) #{:role/self}) + :account (when (sch/id= account-id entity) #{:role/self}) + :membership (when (sch/id= account-id (membership-account entity)) #{:role/self}) (:membership/roles #?(:cljs entity - :clj (db/entity (dl/entid [:membership/entity+member [(:db/id entity) (dl/resolve-id account-id)]]))))) + :clj (membership account-id entity)))) #{})) (defn scoped-roles [account-id {:as entity :keys [entity/kind]}] @@ -71,9 +80,12 @@ (all-roles account-id entity-id) (db/touch (db/entity entity-id)))) +(defn with-roles* [entity-key req params] + (if-let [account-id (-> req :account :entity/id)] + (assoc params :membership/roles (all-roles account-id (get-entity (entity-key params)))) + params)) + #?(:clj (defn with-roles [entity-key] (fn [req params] - (if-let [account-id (some-> (-> req :account :entity/id) sch/wrap-id)] - (assoc params :membership/roles (get-roles account-id (get-entity (entity-key params)))) - params)))) \ No newline at end of file + (#'with-roles* entity-key req params)))) \ No newline at end of file diff --git a/src/sb/server/core.clj b/src/sb/server/core.clj index e271aa79..96b5d8b5 100644 --- a/src/sb/server/core.clj +++ b/src/sb/server/core.clj @@ -34,7 +34,7 @@ [sb.i18n :as i18n] [sb.log] [sb.routing :as routing] - [sb.app] ;; includes all endpoints + [sb.app] ;; includes all endpoints [sb.server.account :as accounts] [sb.server.env :as env] [sb.server.html :as server.html] @@ -126,12 +126,13 @@ (defn prepare! [fs req params] (cond (nil? fs) params (sequential? fs) (reduce (fn [params f] - (f req params)) params fs) + (or (f req params) + params)) params fs) :else (fs req params))) (defn authorize! [f req params] - (let [m (meta f) + (let [m (meta f) authorized? (or (:endpoint/public? m) (:account req))] (when-not authorized? @@ -255,6 +256,8 @@ (sch/install-malli-schemas!) (db/merge-schema! @sch/!schema) (routing/init-endpoints! (routing/endpoints)) + #_(doseq [channel (keys @re-db.sync/!watches)] + (re-db.sync/unwatch-all channel)) (stop-server!) (reset! the-server (httpkit/run-server (fn [req] (@app-handler req)) {:port port