mirror of
https://github.com/penpot/penpot.git
synced 2025-05-18 17:56:11 +02:00
♻️ Add minor refactor to shared-link dialog component
Fixes the issue of creating incorrect link when only non-current pages are selected on the shared link permissions
This commit is contained in:
parent
8d6d589a0c
commit
c16de52b49
2 changed files with 104 additions and 99 deletions
|
@ -41,7 +41,8 @@
|
||||||
- Fix select all checkbox on shared link config [Taiga #5566](https://tree.taiga.io/project/penpot/issue/5566)
|
- Fix select all checkbox on shared link config [Taiga #5566](https://tree.taiga.io/project/penpot/issue/5566)
|
||||||
- Fix validation on full name input on account creation [Taiga #5516](https://tree.taiga.io/project/penpot/issue/5516)
|
- Fix validation on full name input on account creation [Taiga #5516](https://tree.taiga.io/project/penpot/issue/5516)
|
||||||
- Fix validation on team name input [Taiga #5510](https://tree.taiga.io/project/penpot/issue/5510)
|
- Fix validation on team name input [Taiga #5510](https://tree.taiga.io/project/penpot/issue/5510)
|
||||||
|
- Fix incorrect uri generation issues on share-link modal [Taiga #5564](https://tree.taiga.io/project/penpot/issue/5564)
|
||||||
|
- Fix cache issues with share-links [Taiga #5559](https://tree.taiga.io/project/penpot/issue/5559)
|
||||||
|
|
||||||
### :arrow_up: Deps updates
|
### :arrow_up: Deps updates
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,12 @@
|
||||||
(ns app.main.ui.viewer.share-link
|
(ns app.main.ui.viewer.share-link
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.logging :as log]
|
[app.common.logging :as log]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
[app.main.data.common :as dc]
|
[app.main.data.common :as dc]
|
||||||
[app.main.data.events :as ev]
|
[app.main.data.events :as ev]
|
||||||
[app.main.data.messages :as dm]
|
[app.main.data.messages :as msg]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -25,52 +26,72 @@
|
||||||
|
|
||||||
(log/set-level! :warn)
|
(log/set-level! :warn)
|
||||||
|
|
||||||
(defn prepare-params
|
(defn- prepare-params
|
||||||
[{:keys [pages who-comment who-inspect]}]
|
[{:keys [pages who-comment who-inspect]}]
|
||||||
|
|
||||||
{:pages pages
|
{:pages pages
|
||||||
: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
|
||||||
|
::mf/wrap-props false}
|
||||||
[{:keys [file page]}]
|
[{:keys [file page]}]
|
||||||
(let [current-page page
|
(let [current-page page
|
||||||
|
current-page-id (:id page)
|
||||||
slinks (mf/deref refs/share-links)
|
slinks (mf/deref refs/share-links)
|
||||||
router (mf/deref refs/router)
|
router (mf/deref refs/router)
|
||||||
route (mf/deref refs/route)
|
route (mf/deref refs/route)
|
||||||
zoom-type (mf/deref refs/viewer-zoom-type)
|
zoom-type (mf/deref refs/viewer-zoom-type)
|
||||||
|
page-ids (dm/get-in file [:data :pages])
|
||||||
|
|
||||||
link (mf/use-state nil)
|
perms-visible* (mf/use-state false)
|
||||||
confirm (mf/use-state false)
|
perms-visible? (deref perms-visible*)
|
||||||
open-ops (mf/use-state false)
|
|
||||||
|
|
||||||
opts* (mf/use-state
|
confirm* (mf/use-state false)
|
||||||
|
confirm? (deref confirm*)
|
||||||
|
|
||||||
|
options* (mf/use-state
|
||||||
{:pages-mode "current"
|
{:pages-mode "current"
|
||||||
:all-pages false
|
:all-pages false
|
||||||
:pages #{(:id page)}
|
:pages #{(:id page)}
|
||||||
:who-comment "team"
|
:who-comment "team"
|
||||||
:who-inspect "team"})
|
:who-inspect "team"})
|
||||||
|
options (deref options*)
|
||||||
|
|
||||||
opts (deref opts*)
|
current-link
|
||||||
|
(mf/with-memo [slinks options page-ids]
|
||||||
|
(let [{:keys [pages who-comment who-inspect] :as params} (prepare-params options)
|
||||||
|
slink (d/seek #(and (= (:who-inspect %) who-inspect)
|
||||||
|
(= (:who-comment %) who-comment)
|
||||||
|
(= (:pages %) pages))
|
||||||
|
slinks)]
|
||||||
|
(when slink
|
||||||
|
(let [pparams (:path-params route)
|
||||||
|
page-id (d/seek #(contains? (:pages slink) %) page-ids)
|
||||||
|
qparams (-> (:query-params route)
|
||||||
|
(assoc :share-id (:id slink))
|
||||||
|
(assoc :page-id page-id)
|
||||||
|
(assoc :index "0"))
|
||||||
|
qparams (if (nil? zoom-type)
|
||||||
|
(dissoc qparams :zoom)
|
||||||
|
(assoc qparams :zoom zoom-type))
|
||||||
|
|
||||||
selected-pages (:pages opts)
|
href (rt/resolve router :viewer pparams qparams)]
|
||||||
file-pages (->> (get-in file [:data :pages])
|
(dm/str (assoc cf/public-uri :fragment href))))))
|
||||||
(map #(get-in file [:data :pages-index %])))
|
|
||||||
|
|
||||||
close
|
on-close
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(st/emit! (modal/hide))
|
(st/emit! (modal/hide))
|
||||||
(modal/disallow-click-outside!))
|
(modal/disallow-click-outside!))
|
||||||
|
|
||||||
toggle-all
|
on-toggle-all
|
||||||
(fn []
|
(fn [_event]
|
||||||
(reset! confirm false)
|
(reset! confirm* false)
|
||||||
(swap! opts*
|
(swap! options*
|
||||||
(fn [state]
|
(fn [state]
|
||||||
(if (= true (:all-pages state))
|
(if (true? (:all-pages state))
|
||||||
(-> state
|
(-> state
|
||||||
(assoc :all-pages false)
|
(assoc :all-pages false)
|
||||||
(assoc :pages #{(:id page)}))
|
(assoc :pages #{(:id page)}))
|
||||||
|
@ -78,30 +99,29 @@
|
||||||
(assoc :all-pages true)
|
(assoc :all-pages true)
|
||||||
(assoc :pages (into #{} (get-in file [:data :pages]))))))))
|
(assoc :pages (into #{} (get-in file [:data :pages]))))))))
|
||||||
|
|
||||||
mark-checked-page
|
on-mark-checked-page
|
||||||
(mf/use-fn
|
(fn [event]
|
||||||
(mf/deps selected-pages)
|
(let [target (dom/get-target event)
|
||||||
(fn [event id]
|
checked? (dom/checked? target)
|
||||||
(let [target (dom/get-target event)
|
page-id (parse-uuid (dom/get-data target "page-id"))
|
||||||
not-checked? (.-checked ^js target)
|
dif-pages? (not= page-id (first (:pages options)))
|
||||||
dif-pages? (not= id (first selected-pages))
|
no-one-page (< 1 (count (:pages options)))
|
||||||
no-one-page (< 1 (count selected-pages))
|
should-change? (or ^boolean no-one-page
|
||||||
should-change (or no-one-page dif-pages?)]
|
^boolean dif-pages?)]
|
||||||
(when should-change
|
(when ^boolean should-change?
|
||||||
(reset! confirm false)
|
(reset! confirm* false)
|
||||||
(swap! opts*
|
(swap! options*
|
||||||
(fn [state]
|
(fn [{:keys [pages] :as state}]
|
||||||
(let [actual-pages (:pages state)
|
(let [pages (if checked?
|
||||||
updated-pages (if not-checked?
|
(conj pages page-id)
|
||||||
(conj actual-pages id)
|
(disj pages page-id))]
|
||||||
(disj actual-pages id))]
|
|
||||||
(-> state
|
(-> state
|
||||||
(assoc :pages updated-pages)
|
(assoc :pages pages)
|
||||||
(assoc :all-pages (= (count updated-pages) (count file-pages)))))))))))
|
(assoc :all-pages (= (count pages) (count page-ids))))))))))
|
||||||
|
|
||||||
create-link
|
create-link
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [params (prepare-params opts)
|
(let [params (prepare-params options)
|
||||||
params (assoc params :file-id (:id file))]
|
params (assoc params :file-id (:id file))]
|
||||||
(st/emit! (dc/create-share-link params)
|
(st/emit! (dc/create-share-link params)
|
||||||
(ptk/event ::ev/event {::ev/name "create-shared-link"
|
(ptk/event ::ev/event {::ev/name "create-shared-link"
|
||||||
|
@ -111,53 +131,35 @@
|
||||||
|
|
||||||
copy-link
|
copy-link
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(wapi/write-to-clipboard @link)
|
(wapi/write-to-clipboard current-link)
|
||||||
(st/emit! (dm/show {:type :info
|
(st/emit! (msg/show {:type :info
|
||||||
:content (tr "common.share-link.link-copied-success")
|
:content (tr "common.share-link.link-copied-success")
|
||||||
:timeout 1000})))
|
:timeout 1000})))
|
||||||
|
|
||||||
try-delete-link
|
try-delete-link
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(reset! confirm true))
|
(reset! confirm* true))
|
||||||
|
|
||||||
delete-link
|
delete-link
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [params (prepare-params opts)
|
(let [params (prepare-params options)
|
||||||
slink (d/seek #(= (:flags %) (:flags params)) slinks)]
|
slink (d/seek #(= (:flags %) (:flags params)) slinks)]
|
||||||
(reset! confirm false)
|
(reset! confirm* false)
|
||||||
(st/emit! (dc/delete-share-link slink))))
|
(st/emit! (dc/delete-share-link slink))))
|
||||||
|
|
||||||
manage-open-ops
|
toggle-perms-visibility
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(swap! open-ops not))
|
(swap! perms-visible* not))
|
||||||
|
|
||||||
on-who-change
|
on-who-change
|
||||||
(fn [type event]
|
(fn [type event]
|
||||||
(let [target (dom/get-target event)
|
(let [target (dom/get-target event)
|
||||||
value (dom/get-value target)
|
value (dom/get-value target)
|
||||||
value (keyword value)]
|
value (keyword value)]
|
||||||
(reset! confirm false)
|
(reset! confirm* false)
|
||||||
(if (= type :comment)
|
(if (= type :comment)
|
||||||
(swap! opts* assoc :who-comment (d/name value))
|
(swap! options* assoc :who-comment (d/name value))
|
||||||
(swap! opts* assoc :who-inspect (d/name value)))))]
|
(swap! options* assoc :who-inspect (d/name value)))))]
|
||||||
|
|
||||||
(mf/use-effect
|
|
||||||
(mf/deps file slinks opts)
|
|
||||||
(fn []
|
|
||||||
(let [{:keys [pages who-comment who-inspect] :as params} (prepare-params opts)
|
|
||||||
slink (d/seek #(and (= (:who-inspect %) who-inspect) (= (:who-comment %) who-comment) (= (:pages %) pages)) slinks)
|
|
||||||
href (when slink
|
|
||||||
(let [pparams (:path-params route)
|
|
||||||
qparams (-> (:query-params route)
|
|
||||||
(assoc :share-id (:id slink))
|
|
||||||
(assoc :index "0"))
|
|
||||||
qparams (if (nil? zoom-type)
|
|
||||||
(dissoc qparams :zoom)
|
|
||||||
(assoc qparams :zoom zoom-type))
|
|
||||||
|
|
||||||
href (rt/resolve router :viewer pparams qparams)]
|
|
||||||
(assoc cf/public-uri :fragment href)))]
|
|
||||||
(reset! link (some-> href str)))))
|
|
||||||
|
|
||||||
[:div.modal-overlay.transparent.share-modal
|
[:div.modal-overlay.transparent.share-modal
|
||||||
[:div.modal-container.share-link-dialog
|
[:div.modal-container.share-link-dialog
|
||||||
|
@ -165,37 +167,38 @@
|
||||||
[:div.title
|
[:div.title
|
||||||
[:h2 (tr "common.share-link.title")]
|
[:h2 (tr "common.share-link.title")]
|
||||||
[:div.modal-close-button
|
[:div.modal-close-button
|
||||||
{:on-click close
|
{:on-click on-close
|
||||||
:title (tr "labels.close")}
|
:title (tr "labels.close")}
|
||||||
i/close]]]
|
i/close]]]
|
||||||
[:div.modal-content
|
[:div.modal-content
|
||||||
[:div.share-link-section
|
[:div.share-link-section
|
||||||
(when (and (not @confirm) (some? @link))
|
(when (and (not confirm?) (some? current-link))
|
||||||
[:div.custom-input.with-icon
|
[:div.custom-input.with-icon
|
||||||
[:input {:type "text"
|
[:input {:type "text"
|
||||||
:value (or @link "")
|
:value (or current-link "")
|
||||||
:placeholder (tr "common.share-link.placeholder")
|
:placeholder (tr "common.share-link.placeholder")
|
||||||
:read-only true}]
|
:read-only true}]
|
||||||
[:div.help-icon {:title (tr "viewer.header.share.copy-link")
|
[:div.help-icon {:title (tr "viewer.header.share.copy-link")
|
||||||
:on-click copy-link}
|
:on-click copy-link}
|
||||||
i/copy]])
|
i/copy]])
|
||||||
[:div.hint-wrapper
|
[:div.hint-wrapper
|
||||||
(when (not @confirm) [:div.hint (tr "common.share-link.permissions-hint")])
|
(when (not ^boolean confirm?)
|
||||||
|
[:div.hint (tr "common.share-link.permissions-hint")])
|
||||||
(cond
|
(cond
|
||||||
(true? @confirm)
|
(true? confirm?)
|
||||||
[:div.confirm-dialog
|
[:div.confirm-dialog
|
||||||
[:div.description (tr "common.share-link.confirm-deletion-link-description")]
|
[:div.description (tr "common.share-link.confirm-deletion-link-description")]
|
||||||
[:div.actions
|
[:div.actions
|
||||||
[:input.btn-secondary
|
[:input.btn-secondary
|
||||||
{:type "button"
|
{:type "button"
|
||||||
:on-click #(reset! confirm false)
|
:on-click #(reset! confirm* false)
|
||||||
:value (tr "labels.cancel")}]
|
:value (tr "labels.cancel")}]
|
||||||
[:input.btn-warning
|
[:input.btn-warning
|
||||||
{:type "button"
|
{:type "button"
|
||||||
:on-click delete-link
|
:on-click delete-link
|
||||||
:value (tr "common.share-link.destroy-link")}]]]
|
:value (tr "common.share-link.destroy-link")}]]]
|
||||||
|
|
||||||
(some? @link)
|
(some? current-link)
|
||||||
[:input.btn-secondary
|
[:input.btn-secondary
|
||||||
{:type "button"
|
{:type "button"
|
||||||
:class "primary"
|
:class "primary"
|
||||||
|
@ -210,16 +213,15 @@
|
||||||
:value (tr "common.share-link.get-link")}])]]]
|
:value (tr "common.share-link.get-link")}])]]]
|
||||||
[:div.modal-content.ops-section
|
[:div.modal-content.ops-section
|
||||||
[:div.manage-permissions
|
[:div.manage-permissions
|
||||||
{:on-click manage-open-ops}
|
{:on-click toggle-perms-visibility}
|
||||||
[:span.icon i/picker-hsv]
|
[:span.icon i/picker-hsv]
|
||||||
[:div.title (tr "common.share-link.manage-ops")]]
|
[:div.title (tr "common.share-link.manage-ops")]]
|
||||||
(when @open-ops
|
(when ^boolean perms-visible?
|
||||||
[:*
|
[:*
|
||||||
(let [all-selected? (:all-pages opts)
|
(let [all-selected? (:all-pages options)
|
||||||
pages (->> (get-in file [:data :pages])
|
pages (->> (get-in file [:data :pages])
|
||||||
(map #(get-in file [:data :pages-index %])))
|
(map #(get-in file [:data :pages-index %])))
|
||||||
selected selected-pages]
|
selected (:pages options)]
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
[:div.view-mode
|
[:div.view-mode
|
||||||
[:div.subtitle
|
[:div.subtitle
|
||||||
|
@ -229,10 +231,11 @@
|
||||||
(if (= 1 (count pages))
|
(if (= 1 (count pages))
|
||||||
[:div.input-checkbox.check-primary
|
[:div.input-checkbox.check-primary
|
||||||
[:input {:type "checkbox"
|
[:input {:type "checkbox"
|
||||||
:id (str "page-" (:id current-page))
|
:id (dm/str "page-" current-page-id)
|
||||||
:on-change #(mark-checked-page % (:id current-page))
|
:data-page-id (dm/str current-page-id)
|
||||||
|
:on-change on-mark-checked-page
|
||||||
:checked true}]
|
:checked true}]
|
||||||
[:label {:for (str "page-" (:id current-page))} (:name current-page)]
|
[:label {:for (str "page-" current-page-id)} (:name current-page)]
|
||||||
[:span (str " " (tr "common.share-link.current-tag"))]]
|
[:span (str " " (tr "common.share-link.current-tag"))]]
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
|
@ -242,29 +245,30 @@
|
||||||
:id "view-all"
|
:id "view-all"
|
||||||
:checked all-selected?
|
:checked all-selected?
|
||||||
:name "pages-mode"
|
:name "pages-mode"
|
||||||
:on-change toggle-all}]
|
:on-change on-toggle-all}]
|
||||||
[:label {:for "view-all"} (tr "common.share-link.view-all")]]
|
[:label {:for "view-all"} (tr "common.share-link.view-all")]]
|
||||||
[:span.count-pages (tr "common.share-link.page-shared" (i18n/c (count selected)))]]
|
[:span.count-pages (tr "common.share-link.page-shared" (i18n/c (count selected)))]]
|
||||||
|
|
||||||
[:ul.pages-selection
|
[:ul.pages-selection
|
||||||
(for [page pages]
|
(for [{:keys [id name]} pages]
|
||||||
[:li.input-checkbox.check-primary {:key (str (:id page))}
|
[:li.input-checkbox.check-primary {:key (dm/str id)}
|
||||||
[:input {:type "checkbox"
|
[:input {:type "checkbox"
|
||||||
:id (str "page-" (:id page))
|
:id (dm/str "page-" id)
|
||||||
:on-change #(mark-checked-page % (:id page))
|
:data-page-id (dm/str id)
|
||||||
:checked (contains? selected (:id page))}]
|
:on-change on-mark-checked-page
|
||||||
(if (= (:id current-page) (:id page))
|
:checked (contains? selected id)}]
|
||||||
|
(if (= current-page-id id)
|
||||||
[:*
|
[:*
|
||||||
[:label {:for (str "page-" (:id page))} (:name page)]
|
[:label {:for (dm/str "page-" id)} name]
|
||||||
[:span.current-tag (str " " (tr "common.share-link.current-tag"))]]
|
[:span.current-tag (dm/str " " (tr "common.share-link.current-tag"))]]
|
||||||
[:label {:for (str "page-" (:id page))} (:name page)])])]])]]])
|
[:label {:for (dm/str "page-" id)} name])])]])]]])
|
||||||
[:div.access-mode
|
[:div.access-mode
|
||||||
[:div.subtitle
|
[:div.subtitle
|
||||||
[:span.icon i/chat]
|
[:span.icon i/chat]
|
||||||
(tr "common.share-link.permissions-can-comment")]
|
(tr "common.share-link.permissions-can-comment")]
|
||||||
[:div.items
|
[:div.items
|
||||||
[:select.input-select {:on-change (partial on-who-change :comment)
|
[:select.input-select {:on-change (partial on-who-change :comment)
|
||||||
:value (:who-comment opts)}
|
:value (:who-comment options)}
|
||||||
[:option {:value "team"} (tr "common.share-link.team-members")]
|
[:option {:value "team"} (tr "common.share-link.team-members")]
|
||||||
[:option {:value "all"} (tr "common.share-link.all-users")]]]]
|
[:option {:value "all"} (tr "common.share-link.all-users")]]]]
|
||||||
[:div.inspect-mode
|
[:div.inspect-mode
|
||||||
|
@ -273,7 +277,7 @@
|
||||||
(tr "common.share-link.permissions-can-inspect")]
|
(tr "common.share-link.permissions-can-inspect")]
|
||||||
[:div.items
|
[:div.items
|
||||||
[:select.input-select {:on-change (partial on-who-change :inspect)
|
[:select.input-select {:on-change (partial on-who-change :inspect)
|
||||||
:value (:who-inspect opts)}
|
:value (:who-inspect options)}
|
||||||
[:option {:value "team"} (tr "common.share-link.team-members")]
|
[:option {:value "team"} (tr "common.share-link.team-members")]
|
||||||
[:option {:value "all"} (tr "common.share-link.all-users")]]]]])]]]))
|
[:option {:value "all"} (tr "common.share-link.all-users")]]]]])]]]))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue