mirror of
https://github.com/penpot/penpot.git
synced 2025-05-24 11:46:14 +02:00
✨ In view mode allow comment/inspect to non-team users (by shared link permissions)
This commit is contained in:
parent
0f04398e61
commit
115314e97c
23 changed files with 254 additions and 132 deletions
|
@ -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)
|
- 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)
|
- 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
|
### :bug: Bugs fixed
|
||||||
### :arrow_up: Deps updates
|
### :arrow_up: Deps updates
|
||||||
|
|
|
@ -228,13 +228,13 @@
|
||||||
:fn (mg/resource "app/migrations/sql/0072-mod-file-object-thumbnail-table.sql")}
|
:fn (mg/resource "app/migrations/sql/0072-mod-file-object-thumbnail-table.sql")}
|
||||||
|
|
||||||
{:name "0073-mod-file-media-object-constraints"
|
{:name "0073-mod-file-media-object-constraints"
|
||||||
:fn (mg/resource "app/migrations/sql/0073-mod-file-media-object-constraints.sql")}
|
: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")}
|
|
||||||
|
|
||||||
{:name "0074-mod-file-library-rel-constraints"
|
{:name "0074-mod-file-library-rel-constraints"
|
||||||
:fn (mg/resource "app/migrations/sql/0074-mod-file-library-rel-constraints.sql")}
|
: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")}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,19 +26,21 @@
|
||||||
|
|
||||||
(s/def ::page-id ::us/uuid)
|
(s/def ::page-id ::us/uuid)
|
||||||
(s/def ::file-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 ::profile-id ::us/uuid)
|
||||||
(s/def ::position ::gpt/point)
|
(s/def ::position ::gpt/point)
|
||||||
(s/def ::content ::us/string)
|
(s/def ::content ::us/string)
|
||||||
|
|
||||||
(s/def ::create-comment-thread
|
(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
|
(sv/defmethod ::create-comment-thread
|
||||||
{::retry/max-retries 3
|
{::retry/max-retries 3
|
||||||
::retry/matches retry/conflict-db-insert?}
|
::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]
|
(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)))
|
(create-comment-thread conn params)))
|
||||||
|
|
||||||
(defn- retrieve-next-seqn
|
(defn- retrieve-next-seqn
|
||||||
|
@ -92,18 +94,20 @@
|
||||||
;; --- Mutation: Update Comment Thread Status
|
;; --- Mutation: Update Comment Thread Status
|
||||||
|
|
||||||
(s/def ::id ::us/uuid)
|
(s/def ::id ::us/uuid)
|
||||||
|
(s/def ::share-id (s/nilable ::us/uuid))
|
||||||
|
|
||||||
(s/def ::update-comment-thread-status
|
(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
|
(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]
|
(db/with-atomic [conn pool]
|
||||||
(let [cthr (db/get-by-id conn :comment-thread id {:for-update true})]
|
(let [cthr (db/get-by-id conn :comment-thread id {:for-update true})]
|
||||||
(when-not cthr
|
(when-not cthr
|
||||||
(ex/raise :type :not-found))
|
(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)))))
|
(upsert-comment-thread-status! conn profile-id (:id cthr)))))
|
||||||
|
|
||||||
(def sql:upsert-comment-thread-status
|
(def sql:upsert-comment-thread-status
|
||||||
|
@ -122,16 +126,17 @@
|
||||||
|
|
||||||
(s/def ::is-resolved ::us/boolean)
|
(s/def ::is-resolved ::us/boolean)
|
||||||
(s/def ::update-comment-thread
|
(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
|
(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]
|
(db/with-atomic [conn pool]
|
||||||
(let [thread (db/get-by-id conn :comment-thread id {:for-update true})]
|
(let [thread (db/get-by-id conn :comment-thread id {:for-update true})]
|
||||||
(when-not thread
|
(when-not thread
|
||||||
(ex/raise :type :not-found))
|
(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
|
(db/update! conn :comment-thread
|
||||||
{:is-resolved is-resolved}
|
{:is-resolved is-resolved}
|
||||||
|
@ -142,10 +147,11 @@
|
||||||
;; --- Mutation: Add Comment
|
;; --- Mutation: Add Comment
|
||||||
|
|
||||||
(s/def ::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
|
(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]
|
(db/with-atomic [conn pool]
|
||||||
(let [thread (-> (db/get-by-id conn :comment-thread thread-id {:for-update true})
|
(let [thread (-> (db/get-by-id conn :comment-thread thread-id {:for-update true})
|
||||||
(comments/decode-row))
|
(comments/decode-row))
|
||||||
|
@ -155,7 +161,7 @@
|
||||||
(when-not thread (ex/raise :type :not-found))
|
(when-not thread (ex/raise :type :not-found))
|
||||||
|
|
||||||
;; Permission Checks
|
;; 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.
|
;; Update the page-name cachedattribute on comment thread table.
|
||||||
(when (not= pname (:page-name thread))
|
(when (not= pname (:page-name thread))
|
||||||
|
@ -199,10 +205,11 @@
|
||||||
;; --- Mutation: Update Comment
|
;; --- Mutation: Update Comment
|
||||||
|
|
||||||
(s/def ::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
|
(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]
|
(db/with-atomic [conn pool]
|
||||||
(let [comment (db/get-by-id conn :comment id {:for-update true})
|
(let [comment (db/get-by-id conn :comment id {:for-update true})
|
||||||
_ (when-not comment (ex/raise :type :not-found))
|
_ (when-not comment (ex/raise :type :not-found))
|
||||||
|
@ -210,7 +217,7 @@
|
||||||
_ (when-not thread (ex/raise :type :not-found))
|
_ (when-not thread (ex/raise :type :not-found))
|
||||||
pname (retrieve-page-name conn thread)]
|
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
|
;; Don't allow edit comments to not owners
|
||||||
(when-not (= (:owner-id thread) profile-id)
|
(when-not (= (:owner-id thread) profile-id)
|
||||||
|
|
|
@ -53,6 +53,16 @@
|
||||||
([perms] (:can-read perms))
|
([perms] (:can-read perms))
|
||||||
([conn & args] (check (apply qfn conn args)))))
|
([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
|
(defn make-check-fn
|
||||||
"Helper that converts a predicate permission function to a check
|
"Helper that converts a predicate permission function to a check
|
||||||
function (function that raises an exception)."
|
function (function that raises an exception)."
|
||||||
|
|
|
@ -25,16 +25,16 @@
|
||||||
|
|
||||||
(s/def ::team-id ::us/uuid)
|
(s/def ::team-id ::us/uuid)
|
||||||
(s/def ::file-id ::us/uuid)
|
(s/def ::file-id ::us/uuid)
|
||||||
|
(s/def ::share-id (s/nilable ::us/uuid))
|
||||||
|
|
||||||
(s/def ::comment-threads
|
(s/def ::comment-threads
|
||||||
(s/and (s/keys :req-un [::profile-id]
|
(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 %))))
|
#(or (:file-id %) (:team-id %))))
|
||||||
|
|
||||||
(sv/defmethod ::comment-threads
|
(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)]
|
(with-open [conn (db/open pool)]
|
||||||
(files/check-read-permissions! conn profile-id file-id)
|
|
||||||
(retrieve-comment-threads conn params)))
|
(retrieve-comment-threads conn params)))
|
||||||
|
|
||||||
(def sql:comment-threads
|
(def sql:comment-threads
|
||||||
|
@ -60,8 +60,8 @@
|
||||||
window w as (partition by c.thread_id order by c.created_at asc)")
|
window w as (partition by c.thread_id order by c.created_at asc)")
|
||||||
|
|
||||||
(defn- retrieve-comment-threads
|
(defn- retrieve-comment-threads
|
||||||
[conn {:keys [profile-id file-id]}]
|
[conn {:keys [profile-id file-id share-id]}]
|
||||||
(files/check-read-permissions! conn profile-id file-id)
|
(files/check-comment-permissions! conn profile-id file-id share-id)
|
||||||
(->> (db/exec! conn [sql:comment-threads profile-id file-id])
|
(->> (db/exec! conn [sql:comment-threads profile-id file-id])
|
||||||
(into [] (map decode-row))))
|
(into [] (map decode-row))))
|
||||||
|
|
||||||
|
@ -116,13 +116,15 @@
|
||||||
;; --- Query: Single Comment Thread
|
;; --- Query: Single Comment Thread
|
||||||
|
|
||||||
(s/def ::id ::us/uuid)
|
(s/def ::id ::us/uuid)
|
||||||
|
(s/def ::share-id (s/nilable ::us/uuid))
|
||||||
(s/def ::comment-thread
|
(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
|
(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)]
|
(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 ")"
|
(let [sql (str "with threads as (" sql:comment-threads ")"
|
||||||
"select * from threads where id = ?")]
|
"select * from threads where id = ?")]
|
||||||
(-> (db/exec-one! conn [sql profile-id file-id id])
|
(-> (db/exec-one! conn [sql profile-id file-id id])
|
||||||
|
@ -133,15 +135,17 @@
|
||||||
(declare retrieve-comments)
|
(declare retrieve-comments)
|
||||||
|
|
||||||
(s/def ::file-id ::us/uuid)
|
(s/def ::file-id ::us/uuid)
|
||||||
|
(s/def ::share-id (s/nilable ::us/uuid))
|
||||||
(s/def ::thread-id ::us/uuid)
|
(s/def ::thread-id ::us/uuid)
|
||||||
(s/def ::comments
|
(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
|
(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)]
|
(with-open [conn (db/open pool)]
|
||||||
(let [thread (db/get-by-id conn :comment-thread thread-id)]
|
(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))))
|
(retrieve-comments conn thread-id))))
|
||||||
|
|
||||||
(def sql:comments
|
(def sql:comments
|
||||||
|
@ -153,3 +157,40 @@
|
||||||
[conn thread-id]
|
[conn thread-id]
|
||||||
(->> (db/exec! conn [sql:comments thread-id])
|
(->> (db/exec! conn [sql:comments thread-id])
|
||||||
(into [] (map decode-row))))
|
(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]))
|
||||||
|
|
|
@ -98,7 +98,9 @@
|
||||||
(some? perms) perms
|
(some? perms) perms
|
||||||
(some? ldata) {:type :share-link
|
(some? ldata) {:type :share-link
|
||||||
:can-read true
|
: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?
|
(def has-edit-permissions?
|
||||||
(perms/make-edition-predicate-fn get-permissions))
|
(perms/make-edition-predicate-fn get-permissions))
|
||||||
|
@ -106,12 +108,26 @@
|
||||||
(def has-read-permissions?
|
(def has-read-permissions?
|
||||||
(perms/make-read-predicate-fn get-permissions))
|
(perms/make-read-predicate-fn get-permissions))
|
||||||
|
|
||||||
|
(def has-comment-permissions?
|
||||||
|
(perms/make-comment-predicate-fn get-permissions))
|
||||||
|
|
||||||
(def check-edition-permissions!
|
(def check-edition-permissions!
|
||||||
(perms/make-check-fn has-edit-permissions?))
|
(perms/make-check-fn has-edit-permissions?))
|
||||||
|
|
||||||
(def check-read-permissions!
|
(def check-read-permissions!
|
||||||
(perms/make-check-fn has-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
|
;; --- Query: Files search
|
||||||
|
|
||||||
;; TODO: this query need to a good refactor
|
;; TODO: this query need to a good refactor
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.db :as db]
|
[app.db :as db]
|
||||||
|
[app.rpc.queries.comments :as comments]
|
||||||
[app.rpc.queries.files :as files]
|
[app.rpc.queries.files :as files]
|
||||||
[app.rpc.queries.share-link :as slnk]
|
[app.rpc.queries.share-link :as slnk]
|
||||||
[app.rpc.queries.teams :as teams]
|
|
||||||
[app.util.services :as sv]
|
[app.util.services :as sv]
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
[promesa.core :as p]))
|
[promesa.core :as p]))
|
||||||
|
@ -23,11 +23,11 @@
|
||||||
(db/get-by-id pool :project id {:columns [:id :name :team-id]}))
|
(db/get-by-id pool :project id {:columns [:id :name :team-id]}))
|
||||||
|
|
||||||
(defn- retrieve-bundle
|
(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)
|
(p/let [file (files/retrieve-file cfg file-id)
|
||||||
project (retrieve-project pool (:project-id file))
|
project (retrieve-project pool (:project-id file))
|
||||||
libs (files/retrieve-file-libraries cfg false file-id)
|
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})
|
links (->> (db/query pool :share-link {:file-id file-id})
|
||||||
(mapv slnk/decode-share-link-row))
|
(mapv slnk/decode-share-link-row))
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
(p/let [slink (slnk/retrieve-share-link pool file-id share-id)
|
(p/let [slink (slnk/retrieve-share-link pool file-id share-id)
|
||||||
perms (files/get-permissions pool profile-id file-id share-id)
|
perms (files/get-permissions pool profile-id file-id share-id)
|
||||||
thumbs (files/retrieve-object-thumbnails cfg file-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 :permissions perms)
|
||||||
(assoc-in [:file :thumbnails] thumbs))]
|
(assoc-in [:file :thumbnails] thumbs))]
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,8 @@
|
||||||
:profile-id (:id prof)
|
:profile-id (:id prof)
|
||||||
:file-id (:id file)
|
:file-id (:id file)
|
||||||
:pages #{(get-in file [:data :pages 0])}
|
:pages #{(get-in file [:data :pages 0])}
|
||||||
:flags #{}}
|
:who-comment "team"
|
||||||
|
:who-inspect "all"}
|
||||||
out (th/mutation! data)]
|
out (th/mutation! data)]
|
||||||
|
|
||||||
;; (th/print-result! out)
|
;; (th/print-result! out)
|
||||||
|
|
|
@ -75,20 +75,23 @@
|
||||||
|
|
||||||
(ptk/reify ::create-comment-thread
|
(ptk/reify ::create-comment-thread
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(->> (rp/mutation :create-comment-thread params)
|
(let [share-id (-> state :viewer-local :share-id)
|
||||||
(rx/mapcat #(rp/query :comment-thread {:file-id (:file-id %) :id (:id %)}))
|
params (assoc params :share-id share-id)]
|
||||||
(rx/map #(partial created %))
|
(->> (rp/mutation :create-comment-thread params)
|
||||||
(rx/catch #(rx/throw {:type :comment-error})))))))
|
(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
|
(defn update-comment-thread-status
|
||||||
[{:keys [id] :as thread}]
|
[{:keys [id] :as thread}]
|
||||||
(us/assert ::comment-thread thread)
|
(us/assert ::comment-thread thread)
|
||||||
(ptk/reify ::update-comment-thread-status
|
(ptk/reify ::update-comment-thread-status
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(let [done #(d/update-in-when % [:comment-threads id] assoc :count-unread-comments 0)]
|
(let [done #(d/update-in-when % [:comment-threads id] assoc :count-unread-comments 0)
|
||||||
(->> (rp/mutation :update-comment-thread-status {:id id})
|
share-id (-> state :viewer-local :share-id)]
|
||||||
|
(->> (rp/mutation :update-comment-thread-status {:id id :share-id share-id})
|
||||||
(rx/map (constantly done))
|
(rx/map (constantly done))
|
||||||
(rx/catch #(rx/throw {:type :comment-error})))))))
|
(rx/catch #(rx/throw {:type :comment-error})))))))
|
||||||
|
|
||||||
|
@ -105,10 +108,11 @@
|
||||||
(d/update-in-when state [:comment-threads id] assoc :is-resolved is-resolved))
|
(d/update-in-when state [:comment-threads id] assoc :is-resolved is-resolved))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(->> (rp/mutation :update-comment-thread {:id id :is-resolved is-resolved})
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(rx/catch #(rx/throw {:type :comment-error}))
|
(->> (rp/mutation :update-comment-thread {:id id :is-resolved is-resolved :share-id share-id})
|
||||||
(rx/ignore)))))
|
(rx/catch #(rx/throw {:type :comment-error}))
|
||||||
|
(rx/ignore))))))
|
||||||
|
|
||||||
|
|
||||||
(defn add-comment
|
(defn add-comment
|
||||||
|
@ -119,12 +123,13 @@
|
||||||
(update-in state [:comments (:id thread)] assoc (:id comment) comment))]
|
(update-in state [:comments (:id thread)] assoc (:id comment) comment))]
|
||||||
(ptk/reify ::create-comment
|
(ptk/reify ::create-comment
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(rx/concat
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(->> (rp/mutation :add-comment {:thread-id (:id thread) :content content})
|
(rx/concat
|
||||||
(rx/map #(partial created %))
|
(->> (rp/mutation :add-comment {:thread-id (:id thread) :content content :share-id share-id})
|
||||||
(rx/catch #(rx/throw {:type :comment-error})))
|
(rx/map #(partial created %))
|
||||||
(rx/of (refresh-comment-thread thread)))))))
|
(rx/catch #(rx/throw {:type :comment-error})))
|
||||||
|
(rx/of (refresh-comment-thread thread))))))))
|
||||||
|
|
||||||
(defn update-comment
|
(defn update-comment
|
||||||
[{:keys [id content thread-id] :as comment}]
|
[{:keys [id content thread-id] :as comment}]
|
||||||
|
@ -135,10 +140,11 @@
|
||||||
(d/update-in-when state [:comments thread-id id] assoc :content content))
|
(d/update-in-when state [:comments thread-id id] assoc :content content))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(->> (rp/mutation :update-comment {:id id :content content})
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(rx/catch #(rx/throw {:type :comment-error}))
|
(->> (rp/mutation :update-comment {:id id :content content :share-id share-id})
|
||||||
(rx/ignore)))))
|
(rx/catch #(rx/throw {:type :comment-error}))
|
||||||
|
(rx/ignore))))))
|
||||||
|
|
||||||
(defn delete-comment-thread
|
(defn delete-comment-thread
|
||||||
[{:keys [id] :as thread}]
|
[{:keys [id] :as thread}]
|
||||||
|
@ -151,10 +157,11 @@
|
||||||
(update :comment-threads dissoc id)))
|
(update :comment-threads dissoc id)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(->> (rp/mutation :delete-comment-thread {:id id})
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(rx/catch #(rx/throw {:type :comment-error}))
|
(->> (rp/mutation :delete-comment-thread {:id id :share-id share-id})
|
||||||
(rx/ignore)))))
|
(rx/catch #(rx/throw {:type :comment-error}))
|
||||||
|
(rx/ignore))))))
|
||||||
|
|
||||||
(defn delete-comment
|
(defn delete-comment
|
||||||
[{:keys [id thread-id] :as comment}]
|
[{:keys [id thread-id] :as comment}]
|
||||||
|
@ -165,10 +172,11 @@
|
||||||
(d/update-in-when state [:comments thread-id] dissoc id))
|
(d/update-in-when state [:comments thread-id] dissoc id))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(->> (rp/mutation :delete-comment {:id id})
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(rx/catch #(rx/throw {:type :comment-error}))
|
(->> (rp/mutation :delete-comment {:id id :share-id share-id})
|
||||||
(rx/ignore)))))
|
(rx/catch #(rx/throw {:type :comment-error}))
|
||||||
|
(rx/ignore))))))
|
||||||
|
|
||||||
(defn refresh-comment-thread
|
(defn refresh-comment-thread
|
||||||
[{:keys [id file-id] :as thread}]
|
[{:keys [id file-id] :as thread}]
|
||||||
|
@ -177,10 +185,11 @@
|
||||||
(assoc-in state [:comment-threads id] thread))]
|
(assoc-in state [:comment-threads id] thread))]
|
||||||
(ptk/reify ::refresh-comment-thread
|
(ptk/reify ::refresh-comment-thread
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(->> (rp/query :comment-thread {:file-id file-id :id id})
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(rx/map #(partial fetched %))
|
(->> (rp/query :comment-thread {:file-id file-id :id id :share-id share-id})
|
||||||
(rx/catch #(rx/throw {:type :comment-error})))))))
|
(rx/map #(partial fetched %))
|
||||||
|
(rx/catch #(rx/throw {:type :comment-error}))))))))
|
||||||
|
|
||||||
(defn retrieve-comment-threads
|
(defn retrieve-comment-threads
|
||||||
[file-id]
|
[file-id]
|
||||||
|
@ -189,10 +198,11 @@
|
||||||
(assoc state :comment-threads (d/index-by :id data)))]
|
(assoc state :comment-threads (d/index-by :id data)))]
|
||||||
(ptk/reify ::retrieve-comment-threads
|
(ptk/reify ::retrieve-comment-threads
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(->> (rp/query :comment-threads {:file-id file-id})
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(rx/map #(partial fetched %))
|
(->> (rp/query :comment-threads {:file-id file-id :share-id share-id})
|
||||||
(rx/catch #(rx/throw {:type :comment-error})))))))
|
(rx/map #(partial fetched %))
|
||||||
|
(rx/catch #(rx/throw {:type :comment-error}))))))))
|
||||||
|
|
||||||
(defn retrieve-comments
|
(defn retrieve-comments
|
||||||
[thread-id]
|
[thread-id]
|
||||||
|
@ -201,10 +211,11 @@
|
||||||
(update state :comments assoc thread-id (d/index-by :id comments)))]
|
(update state :comments assoc thread-id (d/index-by :id comments)))]
|
||||||
(ptk/reify ::retrieve-comments
|
(ptk/reify ::retrieve-comments
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(->> (rp/query :comments {:thread-id thread-id})
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(rx/map #(partial fetched %))
|
(->> (rp/query :comments {:thread-id thread-id :share-id share-id})
|
||||||
(rx/catch #(rx/throw {:type :comment-error})))))))
|
(rx/map #(partial fetched %))
|
||||||
|
(rx/catch #(rx/throw {:type :comment-error}))))))))
|
||||||
|
|
||||||
(defn retrieve-unread-comment-threads
|
(defn retrieve-unread-comment-threads
|
||||||
"A event used mainly in dashboard for retrieve all unread threads of a team."
|
"A event used mainly in dashboard for retrieve all unread threads of a team."
|
||||||
|
|
|
@ -436,7 +436,6 @@
|
||||||
(rx/map (constantly (fetch-profile)))
|
(rx/map (constantly (fetch-profile)))
|
||||||
(rx/catch on-error))))))
|
(rx/catch on-error))))))
|
||||||
|
|
||||||
|
|
||||||
(defn fetch-users
|
(defn fetch-users
|
||||||
[{:keys [team-id] :as params}]
|
[{:keys [team-id] :as params}]
|
||||||
(us/assert ::us/uuid team-id)
|
(us/assert ::us/uuid team-id)
|
||||||
|
@ -450,6 +449,20 @@
|
||||||
(->> (rp/query :team-users {:team-id team-id})
|
(->> (rp/query :team-users {:team-id team-id})
|
||||||
(rx/map #(partial fetched %)))))))
|
(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
|
;; --- EVENT: request-account-deletion
|
||||||
|
|
||||||
(defn request-account-deletion
|
(defn request-account-deletion
|
||||||
|
|
|
@ -33,7 +33,9 @@
|
||||||
:selected #{}
|
:selected #{}
|
||||||
:collapsed #{}
|
:collapsed #{}
|
||||||
:overlays []
|
:overlays []
|
||||||
:hover nil})
|
:hover nil
|
||||||
|
:share-id ""
|
||||||
|
:file-comments-users []})
|
||||||
|
|
||||||
(declare fetch-comment-threads)
|
(declare fetch-comment-threads)
|
||||||
(declare fetch-bundle)
|
(declare fetch-bundle)
|
||||||
|
@ -50,7 +52,7 @@
|
||||||
:opt-un [::share-id ::page-id]))
|
:opt-un [::share-id ::page-id]))
|
||||||
|
|
||||||
(defn initialize
|
(defn initialize
|
||||||
[{:keys [file-id] :as params}]
|
[{:keys [file-id share-id] :as params}]
|
||||||
(us/assert ::initialize-params params)
|
(us/assert ::initialize-params params)
|
||||||
(ptk/reify ::initialize
|
(ptk/reify ::initialize
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
|
@ -61,7 +63,8 @@
|
||||||
(fn [lstate]
|
(fn [lstate]
|
||||||
(if (nil? lstate)
|
(if (nil? lstate)
|
||||||
default-local-state
|
default-local-state
|
||||||
lstate)))))
|
lstate)))
|
||||||
|
(assoc-in [:viewer-local :share-id] share-id)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
|
@ -138,7 +141,7 @@
|
||||||
(rx/of (go-to-frame-auto))))))))
|
(rx/of (go-to-frame-auto))))))))
|
||||||
|
|
||||||
(defn fetch-comment-threads
|
(defn fetch-comment-threads
|
||||||
[{:keys [file-id page-id] :as params}]
|
[{:keys [file-id page-id share-id] :as params}]
|
||||||
(letfn [(fetched [data state]
|
(letfn [(fetched [data state]
|
||||||
(->> data
|
(->> data
|
||||||
(filter #(= page-id (:page-id %)))
|
(filter #(= page-id (:page-id %)))
|
||||||
|
@ -153,7 +156,7 @@
|
||||||
(ptk/reify ::fetch-comment-threads
|
(ptk/reify ::fetch-comment-threads
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(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/map #(partial fetched %))
|
||||||
(rx/catch on-error))))))
|
(rx/catch on-error))))))
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@
|
||||||
(unchecked-set ug/global "name" name)))))
|
(unchecked-set ug/global "name" name)))))
|
||||||
|
|
||||||
(defn- file-initialized
|
(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/reify ::file-initialized
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
@ -156,7 +156,8 @@
|
||||||
;; the version number
|
;; the version number
|
||||||
#_(assoc :version 17)
|
#_(assoc :version 17)
|
||||||
#_(app.common.pages.migrations/migrate-data 19))
|
#_(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
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
|
|
|
@ -258,20 +258,23 @@
|
||||||
[project-id file-id]
|
[project-id file-id]
|
||||||
(ptk/reify ::fetch-bundle
|
(ptk/reify ::fetch-bundle
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(->> (rx/zip (rp/query :file-raw {:id file-id})
|
(let [share-id (-> state :viewer-local :share-id)]
|
||||||
(rp/query :team-users {:file-id file-id})
|
(->> (rx/zip (rp/query :file-raw {:id file-id})
|
||||||
(rp/query :project {:id project-id})
|
(rp/query :team-users {:file-id file-id})
|
||||||
(rp/query :file-libraries {:file-id file-id}))
|
(rp/query :project {:id project-id})
|
||||||
(rx/take 1)
|
(rp/query :file-libraries {:file-id file-id})
|
||||||
(rx/map (fn [[file-raw users project libraries]]
|
(rp/query :file-comments-users {:file-id file-id :share-id share-id}))
|
||||||
{:file-raw file-raw
|
(rx/take 1)
|
||||||
:users users
|
(rx/map (fn [[file-raw users project libraries file-comments-users]]
|
||||||
:project project
|
{:file-raw file-raw
|
||||||
:libraries libraries}))
|
:users users
|
||||||
(rx/mapcat (fn [{:keys [project] :as bundle}]
|
:project project
|
||||||
(rx/of (ptk/data-event ::bundle-fetched bundle)
|
:libraries libraries
|
||||||
(df/load-team-fonts (:team-id project)))))))))
|
: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
|
;; --- Helpers
|
||||||
|
|
|
@ -387,6 +387,9 @@
|
||||||
(def users
|
(def users
|
||||||
(l/derived :users st/state))
|
(l/derived :users st/state))
|
||||||
|
|
||||||
|
(def current-file-comments-users
|
||||||
|
(l/derived :current-file-comments-users st/state))
|
||||||
|
|
||||||
(def viewer-fullscreen?
|
(def viewer-fullscreen?
|
||||||
(l/derived (fn [state]
|
(l/derived (fn [state]
|
||||||
(dm/get-in state [:viewer-local :fullscreen?]))
|
(dm/get-in state [:viewer-local :fullscreen?]))
|
||||||
|
|
|
@ -345,7 +345,6 @@
|
||||||
(mf/defc comment-thread
|
(mf/defc comment-thread
|
||||||
[{:keys [item users on-click] :as props}]
|
[{:keys [item users on-click] :as props}]
|
||||||
(let [owner (get users (:owner-id item))
|
(let [owner (get users (:owner-id item))
|
||||||
|
|
||||||
on-click*
|
on-click*
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps item)
|
(mf/deps item)
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
show-dropdown (mf/use-fn #(reset! show-dropdown? true))
|
show-dropdown (mf/use-fn #(reset! show-dropdown? true))
|
||||||
hide-dropdown (mf/use-fn #(reset! show-dropdown? false))
|
hide-dropdown (mf/use-fn #(reset! show-dropdown? false))
|
||||||
threads-map (mf/deref refs/comment-threads)
|
threads-map (mf/deref refs/comment-threads)
|
||||||
users (mf/deref refs/users)
|
users (mf/deref refs/current-file-comments-users)
|
||||||
|
|
||||||
tgroups (->> (vals threads-map)
|
tgroups (->> (vals threads-map)
|
||||||
(sort-by :modified-at)
|
(sort-by :modified-at)
|
||||||
|
|
|
@ -84,6 +84,5 @@
|
||||||
[]
|
[]
|
||||||
(let [modal (mf/deref modal-ref)]
|
(let [modal (mf/deref modal-ref)]
|
||||||
(when modal
|
(when modal
|
||||||
(.log js/console "modal"(clj->js modal))
|
|
||||||
[:& modal-wrapper {:data modal
|
[:& modal-wrapper {:data modal
|
||||||
:key (:id modal)}])))
|
:key (:id modal)}])))
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
:who-comment who-comment
|
:who-comment who-comment
|
||||||
:who-inspect who-inspect})
|
:who-inspect who-inspect})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(mf/defc share-link-dialog
|
(mf/defc share-link-dialog
|
||||||
{::mf/register modal/components
|
{::mf/register modal/components
|
||||||
::mf/register-as :share-link}
|
::mf/register-as :share-link}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
[app.main.ui.share-link]
|
[app.main.ui.share-link]
|
||||||
[app.main.ui.static :as static]
|
[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.handoff :as handoff]
|
||||||
[app.main.ui.viewer.header :refer [header]]
|
[app.main.ui.viewer.header :refer [header]]
|
||||||
[app.main.ui.viewer.interactions :as interactions]
|
[app.main.ui.viewer.interactions :as interactions]
|
||||||
|
@ -84,7 +84,7 @@
|
||||||
|
|
||||||
(when show-comments-list
|
(when show-comments-list
|
||||||
[:& comments-sidebar {:users users :frame frame :page page}])
|
[:& comments-sidebar {:users users :frame frame :page page}])
|
||||||
|
|
||||||
[:div.viewer-wrapper
|
[:div.viewer-wrapper
|
||||||
{:style {:width (:width wrapper-size)
|
{:style {:width (:width wrapper-size)
|
||||||
:height (:height wrapper-size)}}
|
:height (:height wrapper-size)}}
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
:on-click #(when (:close-click-outside overlay)
|
:on-click #(when (:close-click-outside overlay)
|
||||||
(close-overlay (:frame overlay)))}])
|
(close-overlay (:frame overlay)))}])
|
||||||
[:div.viewport-container.viewer-overlay
|
[:div.viewport-container.viewer-overlay
|
||||||
|
|
||||||
{:id (str "overlay-" (-> overlay :frame :id))
|
{:id (str "overlay-" (-> overlay :frame :id))
|
||||||
:style {:width (:width size-over)
|
:style {:width (:width size-over)
|
||||||
:height (:height size-over)
|
:height (:height size-over)
|
||||||
|
@ -169,6 +169,17 @@
|
||||||
(let [{:keys [page-id section index]} params
|
(let [{:keys [page-id section index]} params
|
||||||
{:keys [file users project permissions]} data
|
{: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)
|
local (mf/deref refs/viewer-local)
|
||||||
|
|
||||||
nav-scroll (:nav-scroll local)
|
nav-scroll (:nav-scroll local)
|
||||||
|
@ -241,6 +252,9 @@
|
||||||
(when (nil? page)
|
(when (nil? page)
|
||||||
(ex/raise :type :not-found))
|
(ex/raise :type :not-found))
|
||||||
|
|
||||||
|
(when (not allowed)
|
||||||
|
(st/emit! (dv/go-to-section :interactions)))
|
||||||
|
|
||||||
;; Set the page title
|
;; Set the page title
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps (:name file))
|
(mf/deps (:name file))
|
||||||
|
@ -394,24 +408,23 @@
|
||||||
:index index
|
:index index
|
||||||
:viewer-pagination viewer-pagination}]
|
:viewer-pagination viewer-pagination}]
|
||||||
|
|
||||||
|
[:& viewer-wrapper
|
||||||
[:& viewer-wrapper
|
{:wrapper-size wrapper-size
|
||||||
{:wrapper-size wrapper-size
|
:scroll scroll
|
||||||
:scroll scroll
|
:orig-frame orig-frame
|
||||||
:orig-frame orig-frame
|
:orig-viewport-ref orig-viewport-ref
|
||||||
:orig-viewport-ref orig-viewport-ref
|
:orig-size orig-size
|
||||||
:orig-size orig-size
|
:page page
|
||||||
:page page
|
:file file
|
||||||
:file file
|
:users users
|
||||||
:users users
|
:current-viewport-ref current-viewport-ref
|
||||||
:current-viewport-ref current-viewport-ref
|
:size size
|
||||||
:size size
|
:frame frame
|
||||||
:frame frame
|
:interactions-mode interactions-mode
|
||||||
:interactions-mode interactions-mode
|
:overlays overlays
|
||||||
:overlays overlays
|
:zoom zoom
|
||||||
:zoom zoom
|
:section section
|
||||||
:section section
|
:index index}]))]]]))
|
||||||
:index index}]))]]]))
|
|
||||||
|
|
||||||
;; --- Component: Viewer Page
|
;; --- Component: Viewer Page
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@
|
||||||
[:div.main-icon
|
[:div.main-icon
|
||||||
[:a {:on-click go-to-dashboard
|
[:a {:on-click go-to-dashboard
|
||||||
;; If the user doesn't have permission we disable the link
|
;; 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}]]
|
[:& 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))}
|
:alt (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))}
|
||||||
i/play]
|
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
|
[:button.mode-zone-button.tooltip.tooltip-bottom
|
||||||
{:on-click #(navigate :comments)
|
{:on-click #(navigate :comments)
|
||||||
:class (dom/classnames :active (= section :comments))
|
:class (dom/classnames :active (= section :comments))
|
||||||
|
@ -208,7 +210,8 @@
|
||||||
|
|
||||||
(when (or (= (:type permissions) :membership)
|
(when (or (= (:type permissions) :membership)
|
||||||
(and (= (:type permissions) :share-link)
|
(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
|
[:button.mode-zone-button.tooltip.tooltip-bottom
|
||||||
{:on-click go-to-handoff
|
{:on-click go-to-handoff
|
||||||
:class (dom/classnames :active (= section :handoff))
|
:class (dom/classnames :active (= section :handoff))
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
[{:keys [users threads page-id]}]
|
[{:keys [users threads page-id]}]
|
||||||
(let [threads-map (mf/deref refs/threads-ref)
|
(let [threads-map (mf/deref refs/threads-ref)
|
||||||
profile (mf/deref refs/profile)
|
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)
|
users (or users users-refs)
|
||||||
local (mf/deref refs/comments-local)
|
local (mf/deref refs/comments-local)
|
||||||
options? (mf/use-state false)
|
options? (mf/use-state false)
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
pos-y (* (- (:y vbox)) zoom)
|
pos-y (* (- (:y vbox)) zoom)
|
||||||
|
|
||||||
profile (mf/deref refs/profile)
|
profile (mf/deref refs/profile)
|
||||||
users (mf/deref refs/users)
|
users (mf/deref refs/current-file-comments-users)
|
||||||
local (mf/deref refs/comments-local)
|
local (mf/deref refs/comments-local)
|
||||||
threads-map (mf/deref refs/threads-ref)
|
threads-map (mf/deref refs/threads-ref)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue