From b3c4ff4dc0216755813e7c26d0e28b9bb1acd5e4 Mon Sep 17 00:00:00 2001 From: Aitor Date: Fri, 14 Apr 2023 13:04:41 +0200 Subject: [PATCH] :bug: Fix page item context menu --- CHANGES.md | 3 + frontend/src/app/main/data/workspace.cljs | 29 +++++++ frontend/src/app/main/refs.cljs | 4 + .../app/main/ui/workspace/context_menu.cljs | 29 ++++++- .../main/ui/workspace/sidebar/sitemap.cljs | 77 +++++++------------ 5 files changed, 92 insertions(+), 50 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b5a518253..a7c75232d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,9 @@ ### :bug: Bugs fixed - 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 diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 1121279d7..792288feb 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1234,6 +1234,7 @@ (s/def ::point gpt/point?) + (defn show-context-menu [{:keys [position] :as params}] (us/verify ::point position) @@ -1262,10 +1263,20 @@ (rx/of (show-context-menu (-> params (assoc + :kind :shape :disable-booleans? (or no-bool-shapes? not-group-like?) :disable-flatten? no-bool-shapes? :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 (ptk/reify ::hide-context-menu ptk/UpdateEvent @@ -1989,7 +2000,25 @@ (update [_ state] (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 diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 86ca9d33d..4d488a002 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -183,6 +183,10 @@ (def context-menu (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? (l/derived :file-library-listing-thumbs workspace-global)) diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index 215bdeff8..bcd897060 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -575,6 +575,30 @@ :shortcut (sc/get-tooltip :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 [] (let [mdata (mf/deref menu-ref) @@ -602,8 +626,9 @@ :style {:top top :left left} :on-context-menu prevent-default} - (if (contains? mdata :selected) - [:& shape-context-menu {:mdata mdata}] + (case (:kind mdata) + :shape [:& shape-context-menu {:mdata mdata}] + :page [:& page-item-context-menu {:mdata mdata}] [:& viewport-context-menu {:mdata mdata}])]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs index 716218f32..50a98a7a1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs @@ -11,7 +11,6 @@ [app.main.data.workspace :as dw] [app.main.refs :as refs] [app.main.store :as st] - [app.main.ui.components.context-menu :refer [context-menu]] [app.main.ui.context :as ctx] [app.main.ui.hooks :as hooks] [app.main.ui.hooks.resize :refer [use-resize-hook]] @@ -26,29 +25,14 @@ ;; --- Page Item (mf/defc page-item - [{:keys [page index deletable? selected?] :as props}] - (let [local (mf/use-state {}) - input-ref (mf/use-ref) + [{:keys [page index deletable? selected? editing?] :as props}] + (let [input-ref (mf/use-ref) id (:id page) - state (mf/use-state {:menu-open false}) 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))) 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 (mf/use-callback (mf/deps id) @@ -65,8 +49,8 @@ (dom/prevent-default event) (dom/stop-propagation event) (when-not workspace-read-only? - (swap! local assoc :edition true) - (swap! state assoc :menu-open false)))) + (st/emit! (dw/start-rename-page-item id)) + (st/emit! (dw/hide-context-menu))))) on-blur (mf/use-callback @@ -75,7 +59,7 @@ name (str/trim (dom/get-value target))] (when-not (str/empty? name) (st/emit! (dw/rename-page id name))) - (swap! local assoc :edition false)))) + (st/emit! (dw/stop-rename-page-item))))) on-key-down (mf/use-callback @@ -85,7 +69,7 @@ (on-blur event) (kbd/esc? event) - (swap! local assoc :edition false)))) + (st/emit! (dw/stop-rename-page-item))))) on-drop (mf/use-callback @@ -94,10 +78,6 @@ (let [index (if (= :bot side) (inc index) index)] (st/emit! (dw/relocate-page id index))))) - on-duplicate - (fn [_] - (st/emit! (dw/duplicate-page id))) - [dprops dref] (hooks/use-sortable :data-type "penpot/page" @@ -105,7 +85,20 @@ :data {:id id :index index :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/deps selected?) @@ -115,9 +108,9 @@ (dom/scroll-into-view-if-needed! node))))) (mf/use-layout-effect - (mf/deps (:edition @local)) + (mf/deps editing?) (fn [] - (when (:edition @local) + (when editing? (let [edit-input (mf/ref-val input-ref)] (dom/select-text! edit-input)) nil))) @@ -135,7 +128,7 @@ :on-double-click on-double-click :on-context-menu on-context-menu} [:div.page-icon i/file-html] - (if (:edition @local) + (if editing? [:* [:input.element-name {:type "text" :ref input-ref @@ -147,22 +140,7 @@ [:span (:name page)] [:div.page-actions (when (and deletable? (not workspace-read-only?)) - [: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])))}])])) + [:a {:on-click on-delete} i/trash])]])]]])) ;; --- Page Item Wrapper @@ -175,13 +153,14 @@ st/state =)) (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)) page (mf/deref page-ref)] [:& page-item {:page page :index index :deletable? deletable? - :selected? selected?}])) + :selected? selected? + :editing? editing?}])) ;; --- Pages List @@ -189,6 +168,7 @@ [{:keys [file] :as props}] (let [pages (:pages file) deletable? (> (count pages) 1) + editing-page-id (mf/deref refs/editing-page-item) current-page-id (mf/use-ctx ctx/current-page-id)] [:ul.element-list.pages-list [:& hooks/sortable-container {} @@ -198,6 +178,7 @@ :index index :deletable? deletable? :selected? (= page-id current-page-id) + :editing? (= page-id editing-page-id) :key page-id}])]])) ;; --- Sitemap Toolbox