0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-26 14:41:36 -05:00

In view mode allow comment/inspect to non-team users (by shared link permissions)

This commit is contained in:
Pablo Alba 2022-06-22 18:16:34 +02:00
parent 0f04398e61
commit 115314e97c
23 changed files with 254 additions and 132 deletions

View file

@ -6,6 +6,7 @@
- Allow for nested and rotated boards inside other boards and groups [Taiga #2874](https://tree.taiga.io/project/penpot/us/2874?milestone=319982)
- View mode improvements to enable access and use in different conditions [Taiga #3023](https://tree.taiga.io/project/penpot/us/3023)
- Improved share link options. Now you can allow non-team members to comment and/or inspect [Taiga #3056] (https://tree.taiga.io/project/penpot/us/3056)
### :bug: Bugs fixed
### :arrow_up: Deps updates

View file

@ -228,13 +228,13 @@
:fn (mg/resource "app/migrations/sql/0072-mod-file-object-thumbnail-table.sql")}
{:name "0073-mod-file-media-object-constraints"
:fn (mg/resource "app/migrations/sql/0073-mod-file-media-object-constraints.sql")}
{:name "0073-mod-share-link-table"
:fn (mg/resource "app/migrations/sql/0073-mod-share-link-table.sql")}
:fn (mg/resource "app/migrations/sql/0073-mod-file-media-object-constraints.sql")}
{:name "0074-mod-file-library-rel-constraints"
:fn (mg/resource "app/migrations/sql/0074-mod-file-library-rel-constraints.sql")}
{:name "0075-mod-share-link-table"
:fn (mg/resource "app/migrations/sql/0075-mod-share-link-table.sql")}
])

View file

@ -26,19 +26,21 @@
(s/def ::page-id ::us/uuid)
(s/def ::file-id ::us/uuid)
(s/def ::share-id (s/nilable ::us/uuid))
(s/def ::profile-id ::us/uuid)
(s/def ::position ::gpt/point)
(s/def ::content ::us/string)
(s/def ::create-comment-thread
(s/keys :req-un [::profile-id ::file-id ::position ::content ::page-id]))
(s/keys :req-un [::profile-id ::file-id ::position ::content ::page-id]
:opt-un [::share-id]))
(sv/defmethod ::create-comment-thread
{::retry/max-retries 3
::retry/matches retry/conflict-db-insert?}
[{:keys [pool] :as cfg} {:keys [profile-id file-id] :as params}]
[{:keys [pool] :as cfg} {:keys [profile-id file-id share-id] :as params}]
(db/with-atomic [conn pool]
(files/check-read-permissions! conn profile-id file-id)
(files/check-comment-permissions! conn profile-id file-id share-id)
(create-comment-thread conn params)))
(defn- retrieve-next-seqn
@ -92,18 +94,20 @@
;; --- Mutation: Update Comment Thread Status
(s/def ::id ::us/uuid)
(s/def ::share-id (s/nilable ::us/uuid))
(s/def ::update-comment-thread-status
(s/keys :req-un [::profile-id ::id]))
(s/keys :req-un [::profile-id ::id]
:opt-un [::share-id]))
(sv/defmethod ::update-comment-thread-status
[{:keys [pool] :as cfg} {:keys [profile-id id] :as params}]
[{:keys [pool] :as cfg} {:keys [profile-id id share-id] :as params}]
(db/with-atomic [conn pool]
(let [cthr (db/get-by-id conn :comment-thread id {:for-update true})]
(when-not cthr
(ex/raise :type :not-found))
(files/check-read-permissions! conn profile-id (:file-id cthr))
(files/check-comment-permissions! conn profile-id (:file-id cthr) share-id)
(upsert-comment-thread-status! conn profile-id (:id cthr)))))
(def sql:upsert-comment-thread-status
@ -122,16 +126,17 @@
(s/def ::is-resolved ::us/boolean)
(s/def ::update-comment-thread
(s/keys :req-un [::profile-id ::id ::is-resolved]))
(s/keys :req-un [::profile-id ::id ::is-resolved]
:opt-un [::share-id]))
(sv/defmethod ::update-comment-thread
[{:keys [pool] :as cfg} {:keys [profile-id id is-resolved] :as params}]
[{:keys [pool] :as cfg} {:keys [profile-id id is-resolved share-id] :as params}]
(db/with-atomic [conn pool]
(let [thread (db/get-by-id conn :comment-thread id {:for-update true})]
(when-not thread
(ex/raise :type :not-found))
(files/check-read-permissions! conn profile-id (:file-id thread))
(files/check-comment-permissions! conn profile-id (:file-id thread) share-id)
(db/update! conn :comment-thread
{:is-resolved is-resolved}
@ -142,10 +147,11 @@
;; --- Mutation: Add Comment
(s/def ::add-comment
(s/keys :req-un [::profile-id ::thread-id ::content]))
(s/keys :req-un [::profile-id ::thread-id ::content]
:opt-un [::share-id]))
(sv/defmethod ::add-comment
[{:keys [pool] :as cfg} {:keys [profile-id thread-id content] :as params}]
[{:keys [pool] :as cfg} {:keys [profile-id thread-id content share-id] :as params}]
(db/with-atomic [conn pool]
(let [thread (-> (db/get-by-id conn :comment-thread thread-id {:for-update true})
(comments/decode-row))
@ -155,7 +161,7 @@
(when-not thread (ex/raise :type :not-found))
;; Permission Checks
(files/check-read-permissions! conn profile-id (:file-id thread))
(files/check-comment-permissions! conn profile-id (:file-id thread) share-id)
;; Update the page-name cachedattribute on comment thread table.
(when (not= pname (:page-name thread))
@ -199,10 +205,11 @@
;; --- Mutation: Update Comment
(s/def ::update-comment
(s/keys :req-un [::profile-id ::id ::content]))
(s/keys :req-un [::profile-id ::id ::content]
:opt-un [::share-id]))
(sv/defmethod ::update-comment
[{:keys [pool] :as cfg} {:keys [profile-id id content] :as params}]
[{:keys [pool] :as cfg} {:keys [profile-id id content share-id] :as params}]
(db/with-atomic [conn pool]
(let [comment (db/get-by-id conn :comment id {:for-update true})
_ (when-not comment (ex/raise :type :not-found))
@ -210,7 +217,7 @@
_ (when-not thread (ex/raise :type :not-found))
pname (retrieve-page-name conn thread)]
(files/check-read-permissions! conn profile-id (:file-id thread))
(files/check-comment-permissions! conn profile-id (:file-id thread) share-id)
;; Don't allow edit comments to not owners
(when-not (= (:owner-id thread) profile-id)

View file

@ -53,6 +53,16 @@
([perms] (:can-read perms))
([conn & args] (check (apply qfn conn args)))))
(defn make-comment-predicate-fn
"A simple factory for comment permission predicate functions."
[qfn]
(us/assert fn? qfn)
(fn check
([perms]
(and (:is-logged perms) (= (:who-comment perms) "all")))
([conn & args]
(check (apply qfn conn args)))))
(defn make-check-fn
"Helper that converts a predicate permission function to a check
function (function that raises an exception)."

View file

@ -25,16 +25,16 @@
(s/def ::team-id ::us/uuid)
(s/def ::file-id ::us/uuid)
(s/def ::share-id (s/nilable ::us/uuid))
(s/def ::comment-threads
(s/and (s/keys :req-un [::profile-id]
:opt-un [::file-id ::team-id])
:opt-un [::file-id ::share-id ::team-id])
#(or (:file-id %) (:team-id %))))
(sv/defmethod ::comment-threads
[{:keys [pool] :as cfg} {:keys [profile-id file-id] :as params}]
[{:keys [pool] :as cfg} params]
(with-open [conn (db/open pool)]
(files/check-read-permissions! conn profile-id file-id)
(retrieve-comment-threads conn params)))
(def sql:comment-threads
@ -60,8 +60,8 @@
window w as (partition by c.thread_id order by c.created_at asc)")
(defn- retrieve-comment-threads
[conn {:keys [profile-id file-id]}]
(files/check-read-permissions! conn profile-id file-id)
[conn {:keys [profile-id file-id share-id]}]
(files/check-comment-permissions! conn profile-id file-id share-id)
(->> (db/exec! conn [sql:comment-threads profile-id file-id])
(into [] (map decode-row))))
@ -116,13 +116,15 @@
;; --- Query: Single Comment Thread
(s/def ::id ::us/uuid)
(s/def ::share-id (s/nilable ::us/uuid))
(s/def ::comment-thread
(s/keys :req-un [::profile-id ::file-id ::id]))
(s/keys :req-un [::profile-id ::file-id ::id]
:opt-un [::share-id]))
(sv/defmethod ::comment-thread
[{:keys [pool] :as cfg} {:keys [profile-id file-id id] :as params}]
[{:keys [pool] :as cfg} {:keys [profile-id file-id id share-id] :as params}]
(with-open [conn (db/open pool)]
(files/check-read-permissions! conn profile-id file-id)
(files/check-comment-permissions! conn profile-id file-id share-id)
(let [sql (str "with threads as (" sql:comment-threads ")"
"select * from threads where id = ?")]
(-> (db/exec-one! conn [sql profile-id file-id id])
@ -133,15 +135,17 @@
(declare retrieve-comments)
(s/def ::file-id ::us/uuid)
(s/def ::share-id (s/nilable ::us/uuid))
(s/def ::thread-id ::us/uuid)
(s/def ::comments
(s/keys :req-un [::profile-id ::thread-id]))
(s/keys :req-un [::profile-id ::thread-id]
:opt-un [::share-id]))
(sv/defmethod ::comments
[{:keys [pool] :as cfg} {:keys [profile-id thread-id] :as params}]
[{:keys [pool] :as cfg} {:keys [profile-id thread-id share-id] :as params}]
(with-open [conn (db/open pool)]
(let [thread (db/get-by-id conn :comment-thread thread-id)]
(files/check-read-permissions! conn profile-id (:file-id thread))
(files/check-comment-permissions! conn profile-id (:file-id thread) share-id)
(retrieve-comments conn thread-id))))
(def sql:comments
@ -153,3 +157,40 @@
[conn thread-id]
(->> (db/exec! conn [sql:comments thread-id])
(into [] (map decode-row))))
;; file-comments-users
(declare retrieve-file-comments-users)
(s/def ::file-id ::us/uuid)
(s/def ::share-id (s/nilable ::us/uuid))
(s/def ::file-comments-users
(s/keys :req-un [::profile-id ::file-id]
:opt-un [::share-id]))
(sv/defmethod ::file-comments-users
[{:keys [pool] :as cfg} {:keys [profile-id file-id share-id]}]
(with-open [conn (db/open pool)]
(files/check-comment-permissions! conn profile-id file-id share-id)
(retrieve-file-comments-users conn file-id profile-id)))
(def sql:file-comment-users
"select p.id,
p.email,
p.fullname as name,
p.fullname as fullname,
p.photo_id,
p.is_active
from profile p
where p.id in
(select owner_id from comment
where thread_id in
(select id from comment_thread
where file_id=?))
or p.id=?
") ;; all the users that had comment the file, plus the current user
(defn retrieve-file-comments-users
[conn file-id profile-id]
(db/exec! conn [sql:file-comment-users file-id profile-id]))

View file

@ -98,7 +98,9 @@
(some? perms) perms
(some? ldata) {:type :share-link
:can-read true
:flags (:flags ldata)}))))
:is-logged (some? profile-id)
:who-comment (:who-comment ldata)
:who-inspect (:who-inspect ldata)}))))
(def has-edit-permissions?
(perms/make-edition-predicate-fn get-permissions))
@ -106,12 +108,26 @@
(def has-read-permissions?
(perms/make-read-predicate-fn get-permissions))
(def has-comment-permissions?
(perms/make-comment-predicate-fn get-permissions))
(def check-edition-permissions!
(perms/make-check-fn has-edit-permissions?))
(def check-read-permissions!
(perms/make-check-fn has-read-permissions?))
;; A user has comment permissions if she has read permissions, or comment permissions
(defn check-comment-permissions!
[conn profile-id file-id share-id]
(let [can-read (has-read-permissions? conn profile-id file-id)
can-comment (has-comment-permissions? conn profile-id file-id share-id)
]
(when-not (or can-read can-comment)
(ex/raise :type :not-found
:code :object-not-found
:hint "not found"))))
;; --- Query: Files search
;; TODO: this query need to a good refactor

View file

@ -9,9 +9,9 @@
[app.common.exceptions :as ex]
[app.common.spec :as us]
[app.db :as db]
[app.rpc.queries.comments :as comments]
[app.rpc.queries.files :as files]
[app.rpc.queries.share-link :as slnk]
[app.rpc.queries.teams :as teams]
[app.rpc.queries.share-link :as slnk]
[app.util.services :as sv]
[clojure.spec.alpha :as s]
[promesa.core :as p]))
@ -23,11 +23,11 @@
(db/get-by-id pool :project id {:columns [:id :name :team-id]}))
(defn- retrieve-bundle
[{:keys [pool] :as cfg} file-id]
[{:keys [pool] :as cfg} file-id profile-id]
(p/let [file (files/retrieve-file cfg file-id)
project (retrieve-project pool (:project-id file))
libs (files/retrieve-file-libraries cfg false file-id)
users (teams/retrieve-users pool (:team-id project))
users (comments/retrieve-file-comments-users pool file-id profile-id)
links (->> (db/query pool :share-link {:file-id file-id})
(mapv slnk/decode-share-link-row))
@ -54,7 +54,7 @@
(p/let [slink (slnk/retrieve-share-link pool file-id share-id)
perms (files/get-permissions pool profile-id file-id share-id)
thumbs (files/retrieve-object-thumbnails cfg file-id)
bundle (p/-> (retrieve-bundle cfg file-id)
bundle (p/-> (retrieve-bundle cfg file-id profile-id)
(assoc :permissions perms)
(assoc-in [:file :thumbnails] thumbs))]

View file

@ -49,7 +49,8 @@
:profile-id (:id prof)
:file-id (:id file)
:pages #{(get-in file [:data :pages 0])}
:flags #{}}
:who-comment "team"
:who-inspect "all"}
out (th/mutation! data)]
;; (th/print-result! out)

View file

@ -75,20 +75,23 @@
(ptk/reify ::create-comment-thread
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/mutation :create-comment-thread params)
(rx/mapcat #(rp/query :comment-thread {:file-id (:file-id %) :id (:id %)}))
(rx/map #(partial created %))
(rx/catch #(rx/throw {:type :comment-error})))))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)
params (assoc params :share-id share-id)]
(->> (rp/mutation :create-comment-thread params)
(rx/mapcat #(rp/query :comment-thread {:file-id (:file-id %) :id (:id %) :share-id share-id}))
(rx/map #(partial created %))
(rx/catch #(rx/throw {:type :comment-error}))))))))
(defn update-comment-thread-status
[{:keys [id] :as thread}]
(us/assert ::comment-thread thread)
(ptk/reify ::update-comment-thread-status
ptk/WatchEvent
(watch [_ _ _]
(let [done #(d/update-in-when % [:comment-threads id] assoc :count-unread-comments 0)]
(->> (rp/mutation :update-comment-thread-status {:id id})
(watch [_ state _]
(let [done #(d/update-in-when % [:comment-threads id] assoc :count-unread-comments 0)
share-id (-> state :viewer-local :share-id)]
(->> (rp/mutation :update-comment-thread-status {:id id :share-id share-id})
(rx/map (constantly done))
(rx/catch #(rx/throw {:type :comment-error})))))))
@ -105,10 +108,11 @@
(d/update-in-when state [:comment-threads id] assoc :is-resolved is-resolved))
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/mutation :update-comment-thread {:id id :is-resolved is-resolved})
(rx/catch #(rx/throw {:type :comment-error}))
(rx/ignore)))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rp/mutation :update-comment-thread {:id id :is-resolved is-resolved :share-id share-id})
(rx/catch #(rx/throw {:type :comment-error}))
(rx/ignore))))))
(defn add-comment
@ -119,12 +123,13 @@
(update-in state [:comments (:id thread)] assoc (:id comment) comment))]
(ptk/reify ::create-comment
ptk/WatchEvent
(watch [_ _ _]
(rx/concat
(->> (rp/mutation :add-comment {:thread-id (:id thread) :content content})
(rx/map #(partial created %))
(rx/catch #(rx/throw {:type :comment-error})))
(rx/of (refresh-comment-thread thread)))))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(rx/concat
(->> (rp/mutation :add-comment {:thread-id (:id thread) :content content :share-id share-id})
(rx/map #(partial created %))
(rx/catch #(rx/throw {:type :comment-error})))
(rx/of (refresh-comment-thread thread))))))))
(defn update-comment
[{:keys [id content thread-id] :as comment}]
@ -135,10 +140,11 @@
(d/update-in-when state [:comments thread-id id] assoc :content content))
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/mutation :update-comment {:id id :content content})
(rx/catch #(rx/throw {:type :comment-error}))
(rx/ignore)))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rp/mutation :update-comment {:id id :content content :share-id share-id})
(rx/catch #(rx/throw {:type :comment-error}))
(rx/ignore))))))
(defn delete-comment-thread
[{:keys [id] :as thread}]
@ -151,10 +157,11 @@
(update :comment-threads dissoc id)))
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/mutation :delete-comment-thread {:id id})
(rx/catch #(rx/throw {:type :comment-error}))
(rx/ignore)))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rp/mutation :delete-comment-thread {:id id :share-id share-id})
(rx/catch #(rx/throw {:type :comment-error}))
(rx/ignore))))))
(defn delete-comment
[{:keys [id thread-id] :as comment}]
@ -165,10 +172,11 @@
(d/update-in-when state [:comments thread-id] dissoc id))
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/mutation :delete-comment {:id id})
(rx/catch #(rx/throw {:type :comment-error}))
(rx/ignore)))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rp/mutation :delete-comment {:id id :share-id share-id})
(rx/catch #(rx/throw {:type :comment-error}))
(rx/ignore))))))
(defn refresh-comment-thread
[{:keys [id file-id] :as thread}]
@ -177,10 +185,11 @@
(assoc-in state [:comment-threads id] thread))]
(ptk/reify ::refresh-comment-thread
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/query :comment-thread {:file-id file-id :id id})
(rx/map #(partial fetched %))
(rx/catch #(rx/throw {:type :comment-error})))))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rp/query :comment-thread {:file-id file-id :id id :share-id share-id})
(rx/map #(partial fetched %))
(rx/catch #(rx/throw {:type :comment-error}))))))))
(defn retrieve-comment-threads
[file-id]
@ -189,10 +198,11 @@
(assoc state :comment-threads (d/index-by :id data)))]
(ptk/reify ::retrieve-comment-threads
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/query :comment-threads {:file-id file-id})
(rx/map #(partial fetched %))
(rx/catch #(rx/throw {:type :comment-error})))))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rp/query :comment-threads {:file-id file-id :share-id share-id})
(rx/map #(partial fetched %))
(rx/catch #(rx/throw {:type :comment-error}))))))))
(defn retrieve-comments
[thread-id]
@ -201,10 +211,11 @@
(update state :comments assoc thread-id (d/index-by :id comments)))]
(ptk/reify ::retrieve-comments
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/query :comments {:thread-id thread-id})
(rx/map #(partial fetched %))
(rx/catch #(rx/throw {:type :comment-error})))))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rp/query :comments {:thread-id thread-id :share-id share-id})
(rx/map #(partial fetched %))
(rx/catch #(rx/throw {:type :comment-error}))))))))
(defn retrieve-unread-comment-threads
"A event used mainly in dashboard for retrieve all unread threads of a team."

View file

@ -436,7 +436,6 @@
(rx/map (constantly (fetch-profile)))
(rx/catch on-error))))))
(defn fetch-users
[{:keys [team-id] :as params}]
(us/assert ::us/uuid team-id)
@ -450,6 +449,20 @@
(->> (rp/query :team-users {:team-id team-id})
(rx/map #(partial fetched %)))))))
(defn fetch-file-comments-users
[{:keys [team-id] :as params}]
(us/assert ::us/uuid team-id)
(letfn [(fetched [users state]
(->> users
(d/index-by :id)
(assoc state :file-comments-users)))]
(ptk/reify ::fetch-team-users
ptk/WatchEvent
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rp/query :file-comments-users {:team-id team-id :share-id share-id})
(rx/map #(partial fetched %))))))))
;; --- EVENT: request-account-deletion
(defn request-account-deletion

View file

@ -33,7 +33,9 @@
:selected #{}
:collapsed #{}
:overlays []
:hover nil})
:hover nil
:share-id ""
:file-comments-users []})
(declare fetch-comment-threads)
(declare fetch-bundle)
@ -50,7 +52,7 @@
:opt-un [::share-id ::page-id]))
(defn initialize
[{:keys [file-id] :as params}]
[{:keys [file-id share-id] :as params}]
(us/assert ::initialize-params params)
(ptk/reify ::initialize
ptk/UpdateEvent
@ -61,7 +63,8 @@
(fn [lstate]
(if (nil? lstate)
default-local-state
lstate)))))
lstate)))
(assoc-in [:viewer-local :share-id] share-id)))
ptk/WatchEvent
(watch [_ _ _]
@ -138,7 +141,7 @@
(rx/of (go-to-frame-auto))))))))
(defn fetch-comment-threads
[{:keys [file-id page-id] :as params}]
[{:keys [file-id page-id share-id] :as params}]
(letfn [(fetched [data state]
(->> data
(filter #(= page-id (:page-id %)))
@ -153,7 +156,7 @@
(ptk/reify ::fetch-comment-threads
ptk/WatchEvent
(watch [_ _ _]
(->> (rp/query :comment-threads {:file-id file-id})
(->> (rp/query :comment-threads {:file-id file-id :share-id share-id})
(rx/map #(partial fetched %))
(rx/catch on-error))))))

View file

@ -140,7 +140,7 @@
(unchecked-set ug/global "name" name)))))
(defn- file-initialized
[{:keys [file users project libraries] :as bundle}]
[{:keys [file users project libraries file-comments-users] :as bundle}]
(ptk/reify ::file-initialized
ptk/UpdateEvent
(update [_ state]
@ -156,7 +156,8 @@
;; the version number
#_(assoc :version 17)
#_(app.common.pages.migrations/migrate-data 19))
:workspace-libraries (d/index-by :id libraries)))
:workspace-libraries (d/index-by :id libraries)
:current-file-comments-users (d/index-by :id file-comments-users)))
ptk/WatchEvent
(watch [_ _ _]

View file

@ -258,20 +258,23 @@
[project-id file-id]
(ptk/reify ::fetch-bundle
ptk/WatchEvent
(watch [_ _ _]
(->> (rx/zip (rp/query :file-raw {:id file-id})
(rp/query :team-users {:file-id file-id})
(rp/query :project {:id project-id})
(rp/query :file-libraries {:file-id file-id}))
(rx/take 1)
(rx/map (fn [[file-raw users project libraries]]
{:file-raw file-raw
:users users
:project project
:libraries libraries}))
(rx/mapcat (fn [{:keys [project] :as bundle}]
(rx/of (ptk/data-event ::bundle-fetched bundle)
(df/load-team-fonts (:team-id project)))))))))
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rx/zip (rp/query :file-raw {:id file-id})
(rp/query :team-users {:file-id file-id})
(rp/query :project {:id project-id})
(rp/query :file-libraries {:file-id file-id})
(rp/query :file-comments-users {:file-id file-id :share-id share-id}))
(rx/take 1)
(rx/map (fn [[file-raw users project libraries file-comments-users]]
{:file-raw file-raw
:users users
:project project
:libraries libraries
:file-comments-users file-comments-users}))
(rx/mapcat (fn [{:keys [project] :as bundle}]
(rx/of (ptk/data-event ::bundle-fetched bundle)
(df/load-team-fonts (:team-id project))))))))))
;; --- Helpers

View file

@ -387,6 +387,9 @@
(def users
(l/derived :users st/state))
(def current-file-comments-users
(l/derived :current-file-comments-users st/state))
(def viewer-fullscreen?
(l/derived (fn [state]
(dm/get-in state [:viewer-local :fullscreen?]))

View file

@ -345,7 +345,6 @@
(mf/defc comment-thread
[{:keys [item users on-click] :as props}]
(let [owner (get users (:owner-id item))
on-click*
(mf/use-callback
(mf/deps item)

View file

@ -31,7 +31,7 @@
show-dropdown (mf/use-fn #(reset! show-dropdown? true))
hide-dropdown (mf/use-fn #(reset! show-dropdown? false))
threads-map (mf/deref refs/comment-threads)
users (mf/deref refs/users)
users (mf/deref refs/current-file-comments-users)
tgroups (->> (vals threads-map)
(sort-by :modified-at)

View file

@ -84,6 +84,5 @@
[]
(let [modal (mf/deref modal-ref)]
(when modal
(.log js/console "modal"(clj->js modal))
[:& modal-wrapper {:data modal
:key (:id modal)}])))

View file

@ -30,8 +30,6 @@
:who-comment who-comment
:who-inspect who-inspect})
(mf/defc share-link-dialog
{::mf/register modal/components
::mf/register-as :share-link}

View file

@ -25,7 +25,7 @@
[app.main.ui.icons :as i]
[app.main.ui.share-link]
[app.main.ui.static :as static]
[app.main.ui.viewer.comments :refer [comments-layer comments-sidebar]]
[app.main.ui.viewer.comments :refer [comments-layer comments-sidebar]]
[app.main.ui.viewer.handoff :as handoff]
[app.main.ui.viewer.header :refer [header]]
[app.main.ui.viewer.interactions :as interactions]
@ -84,7 +84,7 @@
(when show-comments-list
[:& comments-sidebar {:users users :frame frame :page page}])
[:div.viewer-wrapper
{:style {:width (:width wrapper-size)
:height (:height wrapper-size)}}
@ -140,7 +140,7 @@
:on-click #(when (:close-click-outside overlay)
(close-overlay (:frame overlay)))}])
[:div.viewport-container.viewer-overlay
{:id (str "overlay-" (-> overlay :frame :id))
:style {:width (:width size-over)
:height (:height size-over)
@ -169,6 +169,17 @@
(let [{:keys [page-id section index]} params
{:keys [file users project permissions]} data
allowed (or
(= section :interactions)
(and (= section :comments)
(or (:can-edit permissions)
(and (true? (:is-logged permissions))
(= (:who-comment permissions) "all"))))
(and (= section :handoff)
(or (:can-edit permissions)
(and (true? (:is-logged permissions))
(= (:who-inspect permissions) "all")))))
local (mf/deref refs/viewer-local)
nav-scroll (:nav-scroll local)
@ -241,6 +252,9 @@
(when (nil? page)
(ex/raise :type :not-found))
(when (not allowed)
(st/emit! (dv/go-to-section :interactions)))
;; Set the page title
(mf/use-effect
(mf/deps (:name file))
@ -394,24 +408,23 @@
:index index
:viewer-pagination viewer-pagination}]
[:& viewer-wrapper
{:wrapper-size wrapper-size
:scroll scroll
:orig-frame orig-frame
:orig-viewport-ref orig-viewport-ref
:orig-size orig-size
:page page
:file file
:users users
:current-viewport-ref current-viewport-ref
:size size
:frame frame
:interactions-mode interactions-mode
:overlays overlays
:zoom zoom
:section section
:index index}]))]]]))
[:& viewer-wrapper
{:wrapper-size wrapper-size
:scroll scroll
:orig-frame orig-frame
:orig-viewport-ref orig-viewport-ref
:orig-size orig-size
:page page
:file file
:users users
:current-viewport-ref current-viewport-ref
:size size
:frame frame
:interactions-mode interactions-mode
:overlays overlays
:zoom zoom
:section section
:index index}]))]]]))
;; --- Component: Viewer Page

View file

@ -188,7 +188,7 @@
[:div.main-icon
[:a {:on-click go-to-dashboard
;; If the user doesn't have permission we disable the link
:style {:pointer-events (when-not permissions "none")}} i/logo-icon]]
:style {:pointer-events (when-not (:can-edit permissions) "none")}} i/logo-icon]]
[:& header-sitemap {:project project :file file :page page :frame frame :index index}]]
@ -199,7 +199,9 @@
:alt (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))}
i/play]
(when (:can-edit permissions)
(when (or (:can-edit permissions)
(and (true? (:is-logged permissions))
(= (:who-comment permissions) "all")))
[:button.mode-zone-button.tooltip.tooltip-bottom
{:on-click #(navigate :comments)
:class (dom/classnames :active (= section :comments))
@ -208,7 +210,8 @@
(when (or (= (:type permissions) :membership)
(and (= (:type permissions) :share-link)
(contains? (:flags permissions) :section-handoff)))
(true? (:is-logged permissions))
(= (:who-inspect permissions) "all")))
[:button.mode-zone-button.tooltip.tooltip-bottom
{:on-click go-to-handoff
:class (dom/classnames :active (= section :handoff))

View file

@ -60,7 +60,7 @@
[{:keys [users threads page-id]}]
(let [threads-map (mf/deref refs/threads-ref)
profile (mf/deref refs/profile)
users-refs (mf/deref refs/users)
users-refs (mf/deref refs/current-file-comments-users)
users (or users users-refs)
local (mf/deref refs/comments-local)
options? (mf/use-state false)

View file

@ -20,7 +20,7 @@
pos-y (* (- (:y vbox)) zoom)
profile (mf/deref refs/profile)
users (mf/deref refs/users)
users (mf/deref refs/current-file-comments-users)
local (mf/deref refs/comments-local)
threads-map (mf/deref refs/threads-ref)