mirror of
https://github.com/penpot/penpot.git
synced 2025-06-02 17:21:39 +02:00
🎉 Allow to restore deleted components
This commit is contained in:
parent
ee1058950e
commit
251e7eada2
14 changed files with 209 additions and 34 deletions
|
@ -18,6 +18,7 @@
|
|||
[app.common.types.color :as ctc]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.typography :as ctt]
|
||||
[app.common.uuid :as uuid]
|
||||
|
@ -393,13 +394,50 @@
|
|||
(ptk/reify ::delete-component
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [data (get state :workspace-data)
|
||||
(let [data (get state :workspace-data)
|
||||
components-v2 (features/active-feature? state :components-v2)
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/delete-component id))]
|
||||
(pcb/delete-component id components-v2))]
|
||||
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
|
||||
(defn restore-component
|
||||
"Restore a deleted component, with the given id, on the current file library."
|
||||
[id]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::restore-component
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [data (get state :workspace-data)
|
||||
component (ctf/get-deleted-component data id)
|
||||
page (ctpl/get-page data (:main-instance-page component))
|
||||
|
||||
; Make a new main instance, with the same id of the original
|
||||
[_main-instance shapes]
|
||||
(ctn/make-component-instance page
|
||||
component
|
||||
(:id data)
|
||||
(gpt/point (:main-instance-x component)
|
||||
(:main-instance-y component))
|
||||
{:main-instance? true
|
||||
:force-id (:main-instance-id component)})
|
||||
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/with-page page))
|
||||
|
||||
changes (reduce #(pcb/add-object %1 %2 {:ignore-touched true})
|
||||
changes
|
||||
shapes)
|
||||
|
||||
; restore-component change needs to be done after add main instance
|
||||
; because when undo changes, the orden is inverse
|
||||
changes (pcb/restore-component changes id)]
|
||||
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
|
||||
|
||||
(defn instantiate-component
|
||||
"Create a new shape in the current page, from the component with the given id
|
||||
in the given file library. Then selects the newly created instance."
|
||||
|
|
|
@ -233,7 +233,16 @@
|
|||
(pcb/with-page page)
|
||||
(pcb/with-objects objects)
|
||||
(pcb/with-library-data file)
|
||||
(pcb/set-page-option :guides guides)
|
||||
(pcb/set-page-option :guides guides))
|
||||
|
||||
changes (reduce (fn [changes component-id]
|
||||
;; It's important to delete the component before the main instance, because we
|
||||
;; need to store the instance position if we want to restore it later.
|
||||
(pcb/delete-component changes component-id components-v2))
|
||||
changes
|
||||
components-to-delete)
|
||||
|
||||
changes (-> changes
|
||||
(pcb/remove-objects all-children)
|
||||
(pcb/remove-objects ids)
|
||||
(pcb/remove-objects empty-parents)
|
||||
|
@ -252,12 +261,7 @@
|
|||
(cond-> (seq starting-flows)
|
||||
(pcb/update-page-option :flows (fn [flows]
|
||||
(->> (map :id starting-flows)
|
||||
(reduce ctp/remove-flow flows))))))
|
||||
|
||||
changes (reduce (fn [changes component-id]
|
||||
(pcb/delete-component changes component-id))
|
||||
changes
|
||||
components-to-delete)]
|
||||
(reduce ctp/remove-flow flows))))))]
|
||||
|
||||
(rx/of (dc/detach-comment-thread ids)
|
||||
(dwsl/update-layout-positions all-parents)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
|
@ -18,6 +19,7 @@
|
|||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.shortcuts :as sc]
|
||||
[app.main.features :as features]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
|
@ -373,9 +375,19 @@
|
|||
component-file (-> shapes first :component-file)
|
||||
component-shapes (filter #(contains? % :component-id) shapes)
|
||||
|
||||
components-v2 (features/use-feature :components-v2)
|
||||
|
||||
current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
local-component? (= component-file current-file-id)
|
||||
|
||||
local-library (when local-component?
|
||||
;; Not needed to subscribe to changes because it's not expected
|
||||
;; to change while context menu is open
|
||||
(deref refs/workspace-local-library))
|
||||
|
||||
main-component (when local-component?
|
||||
(ctkl/get-component local-library (:component-id (first shapes))))
|
||||
|
||||
do-add-component #(st/emit! (dwl/add-component))
|
||||
do-detach-component #(st/emit! (dwl/detach-component shape-id))
|
||||
do-detach-component-in-bulk #(st/emit! dwl/detach-selected-components)
|
||||
|
@ -384,6 +396,7 @@
|
|||
do-navigate-component-file #(st/emit! (dwl/nav-to-component-file component-file))
|
||||
do-update-component #(st/emit! (dwl/update-component-sync shape-id component-file))
|
||||
do-update-component-in-bulk #(st/emit! (dwl/update-component-in-bulk component-shapes component-file))
|
||||
do-restore-component #(st/emit! (dwl/restore-component component-id))
|
||||
|
||||
do-update-remote-component
|
||||
#(st/emit! (modal/show
|
||||
|
@ -436,11 +449,14 @@
|
|||
|
||||
|
||||
(if local-component?
|
||||
[:*
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.update-main")
|
||||
:on-click do-update-component}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.show-main")
|
||||
:on-click do-show-component}]]
|
||||
(if (and (nil? main-component) components-v2)
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.restore-main")
|
||||
:on-click do-restore-component}]
|
||||
[:*
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.update-main")
|
||||
:on-click do-update-component}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.show-main")
|
||||
:on-click do-show-component}]])
|
||||
|
||||
[:*
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.go-main")
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.component
|
||||
(:require
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[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]
|
||||
|
@ -34,6 +36,15 @@
|
|||
(:main-instance? values)
|
||||
true)
|
||||
|
||||
local-component? (= library-id current-file-id)
|
||||
local-library (when local-component?
|
||||
;; Not needed to subscribe to changes because it's not expected
|
||||
;; to change while context menu is open
|
||||
(deref refs/workspace-local-library))
|
||||
|
||||
main-component (when local-component?
|
||||
(ctkl/get-component local-library component-id))
|
||||
|
||||
on-menu-click
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
|
@ -54,6 +65,9 @@
|
|||
do-update-component
|
||||
#(st/emit! (dwl/update-component-sync id library-id))
|
||||
|
||||
do-restore-component
|
||||
#(st/emit! (dwl/restore-component component-id))
|
||||
|
||||
do-update-remote-component
|
||||
#(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
|
@ -85,11 +99,13 @@
|
|||
;; app/main/ui/workspace/context_menu.cljs
|
||||
[:& context-menu {:on-close on-menu-close
|
||||
:show (:menu-open @local)
|
||||
:options (if (= library-id current-file-id)
|
||||
[[(tr "workspace.shape.menu.detach-instance") do-detach-component]
|
||||
[(tr "workspace.shape.menu.reset-overrides") do-reset-component]
|
||||
[(tr "workspace.shape.menu.update-main") do-update-component]
|
||||
[(tr "workspace.shape.menu.show-main") do-show-component]]
|
||||
:options (if local-component?
|
||||
(if (and (nil? main-component) components-v2)
|
||||
[[(tr "workspace.shape.menu.restore-main") do-restore-component]]
|
||||
[[(tr "workspace.shape.menu.detach-instance") do-detach-component]
|
||||
[(tr "workspace.shape.menu.reset-overrides") do-reset-component]
|
||||
[(tr "workspace.shape.menu.update-main") do-update-component]
|
||||
[(tr "workspace.shape.menu.show-main") do-show-component]])
|
||||
|
||||
[[(tr "workspace.shape.menu.detach-instance") do-detach-component]
|
||||
[(tr "workspace.shape.menu.reset-overrides") do-reset-component]
|
||||
|
|
|
@ -4303,6 +4303,9 @@ msgstr "Update main components"
|
|||
msgid "workspace.shape.menu.update-main"
|
||||
msgstr "Update main component"
|
||||
|
||||
msgid "workspace.shape.menu.restore-main"
|
||||
msgstr "Restore main component"
|
||||
|
||||
#: src/app/main/ui/workspace/left_toolbar.cljs
|
||||
msgid "workspace.sidebar.history"
|
||||
msgstr "History (%s)"
|
||||
|
|
|
@ -4498,6 +4498,9 @@ msgstr "Actualizar componentes"
|
|||
msgid "workspace.shape.menu.update-main"
|
||||
msgstr "Actualizar componente principal"
|
||||
|
||||
msgid "workspace.shape.menu.restore-main"
|
||||
msgstr "Restaurar componente principal"
|
||||
|
||||
#: src/app/main/ui/workspace/left_toolbar.cljs
|
||||
msgid "workspace.sidebar.history"
|
||||
msgstr "Historial (%s)"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue