mirror of
https://github.com/penpot/penpot.git
synced 2025-05-18 01:56:11 +02:00
Merge pull request #3145 from penpot/azazeln28-fix-page-context-menu
🐛 Fix page item context menu
This commit is contained in:
commit
dde7063da0
5 changed files with 92 additions and 50 deletions
|
@ -5,6 +5,9 @@
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
- Fix problem with rulers not placing correctly [Taiga #5093](https://tree.taiga.io/project/penpot/issue/5093)
|
- Fix problem with rulers not placing correctly [Taiga #5093](https://tree.taiga.io/project/penpot/issue/5093)
|
||||||
|
- Fix page context menu [Taiga #5145](https://tree.taiga.io/project/penpot/issue/5145)
|
||||||
|
|
||||||
|
### :arrow_up: Deps updates
|
||||||
|
|
||||||
## 1.18.2
|
## 1.18.2
|
||||||
|
|
||||||
|
|
|
@ -1234,6 +1234,7 @@
|
||||||
|
|
||||||
(s/def ::point gpt/point?)
|
(s/def ::point gpt/point?)
|
||||||
|
|
||||||
|
|
||||||
(defn show-context-menu
|
(defn show-context-menu
|
||||||
[{:keys [position] :as params}]
|
[{:keys [position] :as params}]
|
||||||
(us/verify ::point position)
|
(us/verify ::point position)
|
||||||
|
@ -1262,10 +1263,20 @@
|
||||||
(rx/of (show-context-menu
|
(rx/of (show-context-menu
|
||||||
(-> params
|
(-> params
|
||||||
(assoc
|
(assoc
|
||||||
|
:kind :shape
|
||||||
:disable-booleans? (or no-bool-shapes? not-group-like?)
|
:disable-booleans? (or no-bool-shapes? not-group-like?)
|
||||||
:disable-flatten? no-bool-shapes?
|
:disable-flatten? no-bool-shapes?
|
||||||
:selected (conj selected (:id shape)))))))))))
|
:selected (conj selected (:id shape)))))))))))
|
||||||
|
|
||||||
|
(defn show-page-item-context-menu
|
||||||
|
[{:keys [position page] :as params}]
|
||||||
|
(us/verify ::point position)
|
||||||
|
(ptk/reify ::show-page-item-context-menu
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ _ _]
|
||||||
|
(rx/of (show-context-menu
|
||||||
|
(-> params (assoc :kind :page :selected (:id page))))))))
|
||||||
|
|
||||||
(def hide-context-menu
|
(def hide-context-menu
|
||||||
(ptk/reify ::hide-context-menu
|
(ptk/reify ::hide-context-menu
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
|
@ -1989,7 +2000,25 @@
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc-in state [:workspace-local :inspect-expanded] expanded?))))
|
(assoc-in state [:workspace-local :inspect-expanded] expanded?))))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Sitemap
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn start-rename-page-item
|
||||||
|
[id]
|
||||||
|
(ptk/reify ::start-rename-page-item
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(assoc-in state [:workspace-local :page-item] id))))
|
||||||
|
|
||||||
|
(defn stop-rename-page-item
|
||||||
|
[]
|
||||||
|
(ptk/reify ::stop-rename-page-item
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(let [local (-> (:workspace-local state)
|
||||||
|
(dissoc :page-item))]
|
||||||
|
(assoc state :workspace-local local)))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; File Library persistent settings
|
;; File Library persistent settings
|
||||||
|
|
|
@ -183,6 +183,10 @@
|
||||||
(def context-menu
|
(def context-menu
|
||||||
(l/derived :context-menu workspace-local))
|
(l/derived :context-menu workspace-local))
|
||||||
|
|
||||||
|
;; page item that it is being edited
|
||||||
|
(def editing-page-item
|
||||||
|
(l/derived :page-item workspace-local))
|
||||||
|
|
||||||
(def file-library-listing-thumbs?
|
(def file-library-listing-thumbs?
|
||||||
(l/derived :file-library-listing-thumbs workspace-global))
|
(l/derived :file-library-listing-thumbs workspace-global))
|
||||||
|
|
||||||
|
|
|
@ -575,6 +575,30 @@
|
||||||
:shortcut (sc/get-tooltip :toggle-focus-mode)
|
:shortcut (sc/get-tooltip :toggle-focus-mode)
|
||||||
:on-click do-toggle-focus-mode}])]))
|
:on-click do-toggle-focus-mode}])]))
|
||||||
|
|
||||||
|
(mf/defc page-item-context-menu
|
||||||
|
[{:keys [mdata] :as props}]
|
||||||
|
(let [page (:page mdata)
|
||||||
|
deletable? (:deletable? mdata)
|
||||||
|
id (:id page)
|
||||||
|
delete-fn #(st/emit! (dw/delete-page id))
|
||||||
|
do-delete #(st/emit! (modal/show
|
||||||
|
{:type :confirm
|
||||||
|
:title (tr "modals.delete-page.title")
|
||||||
|
:message (tr "modals.delete-page.body")
|
||||||
|
:on-accept delete-fn}))
|
||||||
|
do-duplicate #(st/emit! (dw/duplicate-page id))
|
||||||
|
do-rename #(st/emit! (dw/start-rename-page-item id))]
|
||||||
|
|
||||||
|
[:*
|
||||||
|
(when deletable?
|
||||||
|
[:& menu-entry {:title (tr "workspace.assets.delete")
|
||||||
|
:on-click do-delete}])
|
||||||
|
|
||||||
|
[:& menu-entry {:title (tr "workspace.assets.rename")
|
||||||
|
:on-click do-rename}]
|
||||||
|
[:& menu-entry {:title (tr "workspace.assets.duplicate")
|
||||||
|
:on-click do-duplicate}]]))
|
||||||
|
|
||||||
(mf/defc context-menu
|
(mf/defc context-menu
|
||||||
[]
|
[]
|
||||||
(let [mdata (mf/deref menu-ref)
|
(let [mdata (mf/deref menu-ref)
|
||||||
|
@ -602,8 +626,9 @@
|
||||||
:style {:top top :left left}
|
:style {:top top :left left}
|
||||||
:on-context-menu prevent-default}
|
:on-context-menu prevent-default}
|
||||||
|
|
||||||
(if (contains? mdata :selected)
|
(case (:kind mdata)
|
||||||
[:& shape-context-menu {:mdata mdata}]
|
:shape [:& shape-context-menu {:mdata mdata}]
|
||||||
|
:page [:& page-item-context-menu {:mdata mdata}]
|
||||||
[:& viewport-context-menu {:mdata mdata}])]]))
|
[:& viewport-context-menu {:mdata mdata}])]]))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.context-menu :refer [context-menu]]
|
|
||||||
[app.main.ui.context :as ctx]
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.hooks :as hooks]
|
[app.main.ui.hooks :as hooks]
|
||||||
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
||||||
|
@ -26,29 +25,14 @@
|
||||||
;; --- Page Item
|
;; --- Page Item
|
||||||
|
|
||||||
(mf/defc page-item
|
(mf/defc page-item
|
||||||
[{:keys [page index deletable? selected?] :as props}]
|
[{:keys [page index deletable? selected? editing?] :as props}]
|
||||||
(let [local (mf/use-state {})
|
(let [input-ref (mf/use-ref)
|
||||||
input-ref (mf/use-ref)
|
|
||||||
id (:id page)
|
id (:id page)
|
||||||
state (mf/use-state {:menu-open false})
|
|
||||||
|
|
||||||
delete-fn (mf/use-callback (mf/deps id) #(st/emit! (dw/delete-page id)))
|
delete-fn (mf/use-callback (mf/deps id) #(st/emit! (dw/delete-page id)))
|
||||||
navigate-fn (mf/use-callback (mf/deps id) #(st/emit! :interrupt (dw/go-to-page id)))
|
navigate-fn (mf/use-callback (mf/deps id) #(st/emit! :interrupt (dw/go-to-page id)))
|
||||||
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
|
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||||
|
|
||||||
on-context-menu
|
|
||||||
(mf/use-callback
|
|
||||||
(mf/deps id workspace-read-only?)
|
|
||||||
(fn [event]
|
|
||||||
(dom/prevent-default event)
|
|
||||||
(dom/stop-propagation event)
|
|
||||||
(when-not workspace-read-only?
|
|
||||||
(let [pos (dom/get-client-position event)]
|
|
||||||
(swap! state assoc
|
|
||||||
:menu-open true
|
|
||||||
:top (:y pos)
|
|
||||||
:left (:x pos))))))
|
|
||||||
|
|
||||||
on-delete
|
on-delete
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps id)
|
(mf/deps id)
|
||||||
|
@ -65,8 +49,8 @@
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(when-not workspace-read-only?
|
(when-not workspace-read-only?
|
||||||
(swap! local assoc :edition true)
|
(st/emit! (dw/start-rename-page-item id))
|
||||||
(swap! state assoc :menu-open false))))
|
(st/emit! (dw/hide-context-menu)))))
|
||||||
|
|
||||||
on-blur
|
on-blur
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
@ -75,7 +59,7 @@
|
||||||
name (str/trim (dom/get-value target))]
|
name (str/trim (dom/get-value target))]
|
||||||
(when-not (str/empty? name)
|
(when-not (str/empty? name)
|
||||||
(st/emit! (dw/rename-page id name)))
|
(st/emit! (dw/rename-page id name)))
|
||||||
(swap! local assoc :edition false))))
|
(st/emit! (dw/stop-rename-page-item)))))
|
||||||
|
|
||||||
on-key-down
|
on-key-down
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
@ -85,7 +69,7 @@
|
||||||
(on-blur event)
|
(on-blur event)
|
||||||
|
|
||||||
(kbd/esc? event)
|
(kbd/esc? event)
|
||||||
(swap! local assoc :edition false))))
|
(st/emit! (dw/stop-rename-page-item)))))
|
||||||
|
|
||||||
on-drop
|
on-drop
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
@ -94,10 +78,6 @@
|
||||||
(let [index (if (= :bot side) (inc index) index)]
|
(let [index (if (= :bot side) (inc index) index)]
|
||||||
(st/emit! (dw/relocate-page id index)))))
|
(st/emit! (dw/relocate-page id index)))))
|
||||||
|
|
||||||
on-duplicate
|
|
||||||
(fn [_]
|
|
||||||
(st/emit! (dw/duplicate-page id)))
|
|
||||||
|
|
||||||
[dprops dref]
|
[dprops dref]
|
||||||
(hooks/use-sortable
|
(hooks/use-sortable
|
||||||
:data-type "penpot/page"
|
:data-type "penpot/page"
|
||||||
|
@ -105,7 +85,20 @@
|
||||||
:data {:id id
|
:data {:id id
|
||||||
:index index
|
:index index
|
||||||
:name (:name page)}
|
:name (:name page)}
|
||||||
:draggable? (not workspace-read-only?))]
|
:draggable? (not workspace-read-only?))
|
||||||
|
|
||||||
|
on-context-menu
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps id workspace-read-only?)
|
||||||
|
(fn [event]
|
||||||
|
(dom/prevent-default event)
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(when-not workspace-read-only?
|
||||||
|
(let [position (dom/get-client-position event)]
|
||||||
|
(st/emit! (dw/show-page-item-context-menu
|
||||||
|
{:position position
|
||||||
|
:page page
|
||||||
|
:deletable? deletable?}))))))]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps selected?)
|
(mf/deps selected?)
|
||||||
|
@ -115,9 +108,9 @@
|
||||||
(dom/scroll-into-view-if-needed! node)))))
|
(dom/scroll-into-view-if-needed! node)))))
|
||||||
|
|
||||||
(mf/use-layout-effect
|
(mf/use-layout-effect
|
||||||
(mf/deps (:edition @local))
|
(mf/deps editing?)
|
||||||
(fn []
|
(fn []
|
||||||
(when (:edition @local)
|
(when editing?
|
||||||
(let [edit-input (mf/ref-val input-ref)]
|
(let [edit-input (mf/ref-val input-ref)]
|
||||||
(dom/select-text! edit-input))
|
(dom/select-text! edit-input))
|
||||||
nil)))
|
nil)))
|
||||||
|
@ -135,7 +128,7 @@
|
||||||
:on-double-click on-double-click
|
:on-double-click on-double-click
|
||||||
:on-context-menu on-context-menu}
|
:on-context-menu on-context-menu}
|
||||||
[:div.page-icon i/file-html]
|
[:div.page-icon i/file-html]
|
||||||
(if (:edition @local)
|
(if editing?
|
||||||
[:*
|
[:*
|
||||||
[:input.element-name {:type "text"
|
[:input.element-name {:type "text"
|
||||||
:ref input-ref
|
:ref input-ref
|
||||||
|
@ -147,22 +140,7 @@
|
||||||
[:span (:name page)]
|
[:span (:name page)]
|
||||||
[:div.page-actions
|
[:div.page-actions
|
||||||
(when (and deletable? (not workspace-read-only?))
|
(when (and deletable? (not workspace-read-only?))
|
||||||
[:a {:on-click on-delete} i/trash])]])]]
|
[:a {:on-click on-delete} i/trash])]])]]]))
|
||||||
|
|
||||||
(when-not workspace-read-only?
|
|
||||||
[:& context-menu
|
|
||||||
{:selectable false
|
|
||||||
:show (:menu-open @state)
|
|
||||||
:on-close #(swap! state assoc :menu-open false)
|
|
||||||
:top (:top @state)
|
|
||||||
:left (:left @state)
|
|
||||||
:options (cond-> []
|
|
||||||
deletable?
|
|
||||||
(conj [(tr "workspace.assets.delete") on-delete])
|
|
||||||
|
|
||||||
:always
|
|
||||||
(-> (conj [(tr "workspace.assets.rename") on-double-click])
|
|
||||||
(conj [(tr "workspace.assets.duplicate") on-duplicate])))}])]))
|
|
||||||
|
|
||||||
|
|
||||||
;; --- Page Item Wrapper
|
;; --- Page Item Wrapper
|
||||||
|
@ -175,13 +153,14 @@
|
||||||
st/state =))
|
st/state =))
|
||||||
|
|
||||||
(mf/defc page-item-wrapper
|
(mf/defc page-item-wrapper
|
||||||
[{:keys [page-id index deletable? selected?] :as props}]
|
[{:keys [page-id index deletable? selected? editing?] :as props}]
|
||||||
(let [page-ref (mf/use-memo (mf/deps page-id) #(make-page-ref page-id))
|
(let [page-ref (mf/use-memo (mf/deps page-id) #(make-page-ref page-id))
|
||||||
page (mf/deref page-ref)]
|
page (mf/deref page-ref)]
|
||||||
[:& page-item {:page page
|
[:& page-item {:page page
|
||||||
:index index
|
:index index
|
||||||
:deletable? deletable?
|
:deletable? deletable?
|
||||||
:selected? selected?}]))
|
:selected? selected?
|
||||||
|
:editing? editing?}]))
|
||||||
|
|
||||||
;; --- Pages List
|
;; --- Pages List
|
||||||
|
|
||||||
|
@ -189,6 +168,7 @@
|
||||||
[{:keys [file] :as props}]
|
[{:keys [file] :as props}]
|
||||||
(let [pages (:pages file)
|
(let [pages (:pages file)
|
||||||
deletable? (> (count pages) 1)
|
deletable? (> (count pages) 1)
|
||||||
|
editing-page-id (mf/deref refs/editing-page-item)
|
||||||
current-page-id (mf/use-ctx ctx/current-page-id)]
|
current-page-id (mf/use-ctx ctx/current-page-id)]
|
||||||
[:ul.element-list.pages-list
|
[:ul.element-list.pages-list
|
||||||
[:& hooks/sortable-container {}
|
[:& hooks/sortable-container {}
|
||||||
|
@ -198,6 +178,7 @@
|
||||||
:index index
|
:index index
|
||||||
:deletable? deletable?
|
:deletable? deletable?
|
||||||
:selected? (= page-id current-page-id)
|
:selected? (= page-id current-page-id)
|
||||||
|
:editing? (= page-id editing-page-id)
|
||||||
:key page-id}])]]))
|
:key page-id}])]]))
|
||||||
|
|
||||||
;; --- Sitemap Toolbox
|
;; --- Sitemap Toolbox
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue