mirror of
https://github.com/penpot/penpot.git
synced 2025-06-07 12:41:41 +02:00
✨ Duplicate pages
This commit is contained in:
parent
c775f5aba0
commit
dd283381a1
3 changed files with 92 additions and 25 deletions
|
@ -214,4 +214,17 @@ $width-settings-bar: 16rem;
|
||||||
|
|
||||||
.element-list.pages-list {
|
.element-list.pages-list {
|
||||||
max-height: 10rem;
|
max-height: 10rem;
|
||||||
|
|
||||||
|
.context-menu {
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-items {
|
||||||
|
border: none;
|
||||||
|
margin: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-action {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,6 +268,24 @@
|
||||||
:id id}]
|
:id id}]
|
||||||
(rx/of (dwc/commit-changes [rchange] [uchange] {:commit-local? true}))))))
|
(rx/of (dwc/commit-changes [rchange] [uchange] {:commit-local? true}))))))
|
||||||
|
|
||||||
|
(defn duplicate-page [page-id]
|
||||||
|
(ptk/reify ::duplicate-page
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [this state stream]
|
||||||
|
(let [id (uuid/next)
|
||||||
|
pages (get-in state [:workspace-data :pages-index])
|
||||||
|
unames (dwc/retrieve-used-names pages)
|
||||||
|
page (get-in state [:workspace-data :pages-index page-id])
|
||||||
|
name (dwc/generate-unique-name unames (:name page))
|
||||||
|
|
||||||
|
page (-> page (assoc :name name :id id))
|
||||||
|
|
||||||
|
rchange {:type :add-page
|
||||||
|
:page page}
|
||||||
|
uchange {:type :del-page
|
||||||
|
:id id}]
|
||||||
|
(rx/of (dwc/commit-changes [rchange] [uchange] {:commit-local? true}))))))
|
||||||
|
|
||||||
(s/def ::rename-page
|
(s/def ::rename-page
|
||||||
(s/keys :req-un [::id ::name]))
|
(s/keys :req-un [::id ::name]))
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.sidebar.sitemap
|
(ns app.main.ui.workspace.sidebar.sitemap
|
||||||
(:require
|
(:require
|
||||||
|
[app.main.ui.components.context-menu :refer [context-menu]]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
|
@ -33,9 +34,23 @@
|
||||||
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! (dw/go-to-page id)))
|
navigate-fn (mf/use-callback (mf/deps id) #(st/emit! (dw/go-to-page id)))
|
||||||
|
|
||||||
|
on-context-menu
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps id)
|
||||||
|
(fn [event]
|
||||||
|
(dom/prevent-default event)
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(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)
|
||||||
|
@ -50,7 +65,8 @@
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(swap! local assoc :edition true)))
|
(swap! local assoc :edition true)
|
||||||
|
(swap! state assoc :menu-open false)))
|
||||||
|
|
||||||
on-blur
|
on-blur
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
@ -77,6 +93,10 @@
|
||||||
(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 [event]
|
||||||
|
(st/emit! (dw/duplicate-page id)))
|
||||||
|
|
||||||
[dprops dref]
|
[dprops dref]
|
||||||
(hooks/use-sortable
|
(hooks/use-sortable
|
||||||
:data-type "app/page"
|
:data-type "app/page"
|
||||||
|
@ -93,30 +113,46 @@
|
||||||
(dom/select-text! edit-input))
|
(dom/select-text! edit-input))
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
[:li {:class (dom/classnames
|
[:*
|
||||||
:selected selected?
|
[:li {:class (dom/classnames
|
||||||
:dnd-over-top (= (:over dprops) :top)
|
:selected selected?
|
||||||
:dnd-over-bot (= (:over dprops) :bot))
|
:dnd-over-top (= (:over dprops) :top)
|
||||||
:ref dref}
|
:dnd-over-bot (= (:over dprops) :bot))
|
||||||
[:div.element-list-body
|
:ref dref}
|
||||||
{:class (dom/classnames
|
[:div.element-list-body
|
||||||
:selected selected?)
|
{:class (dom/classnames
|
||||||
:on-click navigate-fn
|
:selected selected?)
|
||||||
:on-double-click on-double-click}
|
:on-click navigate-fn
|
||||||
[:div.page-icon i/file-html]
|
:on-double-click on-double-click
|
||||||
(if (:edition @local)
|
:on-context-menu on-context-menu}
|
||||||
[:*
|
[:div.page-icon i/file-html]
|
||||||
[:input.element-name {:type "text"
|
(if (:edition @local)
|
||||||
:ref input-ref
|
[:*
|
||||||
:on-blur on-blur
|
[:input.element-name {:type "text"
|
||||||
:on-key-down on-key-down
|
:ref input-ref
|
||||||
:auto-focus true
|
:on-blur on-blur
|
||||||
:default-value (:name page "")}]]
|
:on-key-down on-key-down
|
||||||
[:*
|
:auto-focus true
|
||||||
[:span (:name page)]
|
:default-value (:name page "")}]]
|
||||||
[:div.page-actions
|
[:*
|
||||||
(when deletable?
|
[:span (:name page)]
|
||||||
[:a {:on-click on-delete} i/trash])]])]]))
|
[:div.page-actions
|
||||||
|
(when deletable?
|
||||||
|
[:a {:on-click on-delete} i/trash])]])]]
|
||||||
|
|
||||||
|
[:& 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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue