mirror of
https://github.com/penpot/penpot.git
synced 2025-05-29 00:26:19 +02:00
✨ Restore a deleted variant
This commit is contained in:
parent
7eab6a2f1d
commit
219ddfabaf
7 changed files with 86 additions and 28 deletions
|
@ -423,6 +423,8 @@
|
||||||
(not inside-component?)
|
(not inside-component?)
|
||||||
(assoc :component-root true))
|
(assoc :component-root true))
|
||||||
|
|
||||||
|
restoring-into-parent (get objects (:parent-id first-shape))
|
||||||
|
|
||||||
changes (-> changes
|
changes (-> changes
|
||||||
(pcb/with-page page)
|
(pcb/with-page page)
|
||||||
(pcb/with-objects (:objects page))
|
(pcb/with-objects (:objects page))
|
||||||
|
@ -433,12 +435,15 @@
|
||||||
changes
|
changes
|
||||||
(rest moved-shapes))
|
(rest moved-shapes))
|
||||||
changes (cond-> changes
|
changes (cond-> changes
|
||||||
;; Remove variant info when restoring into a parent that is not a variant-container
|
;; Transform variant info into name when restoring into a parent that is not a variant-container
|
||||||
(and is-variant? parent (not (ctk/is-variant-container? parent)))
|
(and is-variant? parent (not (ctk/is-variant-container? parent)))
|
||||||
(clvp/generate-make-shapes-no-variant [first-shape])
|
(clvp/generate-make-shapes-no-variant [first-shape])
|
||||||
|
;; Remove variant info when restoring into a variant-container that doesn't exists anymore
|
||||||
|
(and is-variant? (nil? restoring-into-parent))
|
||||||
|
(clvp/generate-delete-variant-info first-shape)
|
||||||
;; Add variant info and rename when restoring into a variant-container
|
;; Add variant info and rename when restoring into a variant-container
|
||||||
(ctk/is-variant-container? parent)
|
(ctk/is-variant-container? restoring-into-parent)
|
||||||
(clvp/generate-make-shapes-variant [first-shape] parent))]
|
(clvp/generate-make-shapes-variant [first-shape] restoring-into-parent))]
|
||||||
{:changes (pcb/restore-component changes component-id (:id page) minusdelta)
|
{:changes (pcb/restore-component changes component-id (:id page) minusdelta)
|
||||||
:shape (first moved-shapes)})))
|
:shape (first moved-shapes)})))
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,16 @@
|
||||||
related-components)]
|
related-components)]
|
||||||
changes))
|
changes))
|
||||||
|
|
||||||
|
|
||||||
|
(defn generate-delete-variant-info
|
||||||
|
[changes shape]
|
||||||
|
(-> changes
|
||||||
|
(pcb/update-component (:component-id shape)
|
||||||
|
#(dissoc % :variant-id :variant-properties)
|
||||||
|
{:apply-changes-local-library? true})
|
||||||
|
(pcb/update-shapes [(:id shape)]
|
||||||
|
#(dissoc % :variant-id :variant-name))))
|
||||||
|
|
||||||
(defn- generate-make-shape-no-variant
|
(defn- generate-make-shape-no-variant
|
||||||
[changes shape]
|
[changes shape]
|
||||||
(let [new-name (ctv/variant-name-to-name shape)
|
(let [new-name (ctv/variant-name-to-name shape)
|
||||||
|
@ -112,9 +122,10 @@
|
||||||
(reduce generate-make-shape-no-variant changes shapes))
|
(reduce generate-make-shape-no-variant changes shapes))
|
||||||
|
|
||||||
|
|
||||||
(defn- generate-new-properties-from-variant
|
(defn- create-new-properties-from-variant
|
||||||
[shape min-props data container-name base-properties]
|
[shape min-props data container-name base-properties]
|
||||||
(let [component (ctcl/get-component data (:component-id shape) true)
|
(let [component (ctcl/get-component data (:component-id shape) true)
|
||||||
|
|
||||||
add-name? (not= (:name component) container-name)
|
add-name? (not= (:name component) container-name)
|
||||||
props (ctv/merge-properties base-properties
|
props (ctv/merge-properties base-properties
|
||||||
(:variant-properties component))
|
(:variant-properties component))
|
||||||
|
@ -127,7 +138,7 @@
|
||||||
(ctv/add-new-prop props (:name component))
|
(ctv/add-new-prop props (:name component))
|
||||||
props)))
|
props)))
|
||||||
|
|
||||||
(defn- generate-new-properties-from-non-variant
|
(defn- create-new-properties-from-non-variant
|
||||||
[shape min-props container-name base-properties]
|
[shape min-props container-name base-properties]
|
||||||
(let [;; Remove container name from shape name if present
|
(let [;; Remove container name from shape name if present
|
||||||
shape-name (ctv/remove-prefix (:name shape) container-name)]
|
shape-name (ctv/remove-prefix (:name shape) container-name)]
|
||||||
|
@ -155,14 +166,14 @@
|
||||||
[cpath cname] (cfh/parse-path-name (:name variant-container))
|
[cpath cname] (cfh/parse-path-name (:name variant-container))
|
||||||
container-name (:name variant-container)
|
container-name (:name variant-container)
|
||||||
|
|
||||||
generate-new-properties
|
create-new-properties
|
||||||
(fn [shape min-props]
|
(fn [shape min-props]
|
||||||
(if (ctk/is-variant? shape)
|
(if (ctk/is-variant? shape)
|
||||||
(generate-new-properties-from-variant shape min-props data container-name base-props)
|
(create-new-properties-from-variant shape min-props data container-name base-props)
|
||||||
(generate-new-properties-from-non-variant shape min-props container-name base-props)))
|
(create-new-properties-from-non-variant shape min-props container-name base-props)))
|
||||||
|
|
||||||
total-props (reduce (fn [m shape]
|
total-props (reduce (fn [m shape]
|
||||||
(max m (count (generate-new-properties shape num-base-props))))
|
(max m (count (create-new-properties shape num-base-props))))
|
||||||
0
|
0
|
||||||
shapes)
|
shapes)
|
||||||
|
|
||||||
|
@ -180,19 +191,21 @@
|
||||||
:name (:name variant-container)))]
|
:name (:name variant-container)))]
|
||||||
(reduce
|
(reduce
|
||||||
(fn [changes shape]
|
(fn [changes shape]
|
||||||
(if (or (zero? num-base-props)
|
(let [component (ctcl/get-component data (:component-id shape) true)]
|
||||||
(= variant-id (:variant-id shape)))
|
(if (or (zero? num-base-props) ;; do nothing if there are no base props
|
||||||
changes ;; do nothing more if we aren't changing the parent or there are no base props
|
(and (= variant-id (:variant-id shape)) ;; or we are only moving the shape inside its parent (it is
|
||||||
(let [props (generate-new-properties shape total-props)
|
(not (:deleted component)))) ;; the same parent and the component isn't deleted)
|
||||||
variant-name (ctv/properties-to-name props)]
|
changes
|
||||||
(-> (pcb/update-component changes
|
(let [props (create-new-properties shape total-props)
|
||||||
(:component-id shape)
|
variant-name (ctv/properties-to-name props)]
|
||||||
#(assoc % :variant-id variant-id
|
(-> (pcb/update-component changes
|
||||||
:variant-properties props
|
(:component-id shape)
|
||||||
:name cname
|
#(assoc % :variant-id variant-id
|
||||||
:path cpath)
|
:variant-properties props
|
||||||
{:apply-changes-local-library? true})
|
:name cname
|
||||||
(pcb/update-shapes [(:id shape)]
|
:path cpath)
|
||||||
#(assoc % :variant-name variant-name))))))
|
{:apply-changes-local-library? true})
|
||||||
|
(pcb/update-shapes [(:id shape)]
|
||||||
|
#(assoc % :variant-name variant-name)))))))
|
||||||
changes
|
changes
|
||||||
shapes)))
|
shapes)))
|
||||||
|
|
|
@ -287,7 +287,7 @@
|
||||||
|
|
||||||
(defn get-component-root
|
(defn get-component-root
|
||||||
[component]
|
[component]
|
||||||
(if (true? (:main-instance-id component))
|
(if (some? (:main-instance-id component))
|
||||||
(get-in component [:objects (:main-instance-id component)])
|
(get-in component [:objects (:main-instance-id component)])
|
||||||
(get-in component [:objects (:id component)])))
|
(get-in component [:objects (:id component)])))
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
(ns app.main.ui.workspace.sidebar.assets.common
|
(ns app.main.ui.workspace.sidebar.assets.common
|
||||||
(:require-macros [app.main.style :as stl])
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.common.thumbnails :as thc]
|
[app.common.thumbnails :as thc]
|
||||||
|
@ -384,6 +385,24 @@
|
||||||
|
|
||||||
same-variant? (ctv/same-variant? shapes)
|
same-variant? (ctv/same-variant? shapes)
|
||||||
|
|
||||||
|
is-restorable-variant?
|
||||||
|
;; A shape is a restorable variant if its component is deleted, is a variant,
|
||||||
|
;; and the variant-container in which it will be restored still exists
|
||||||
|
(fn [shape]
|
||||||
|
(let [component (find-component shape true)
|
||||||
|
main (ctk/get-component-root component)
|
||||||
|
objects (dm/get-in libraries [(:component-file shape)
|
||||||
|
:data
|
||||||
|
:pages-index
|
||||||
|
(:main-instance-page component)
|
||||||
|
:objects])
|
||||||
|
|
||||||
|
parent (get objects (:parent-id main))]
|
||||||
|
(and (:deleted component) (ctk/is-variant? component) parent)))
|
||||||
|
|
||||||
|
restorable-variants? (and variants?
|
||||||
|
(every? is-restorable-variant? restorable-copies))
|
||||||
|
|
||||||
do-detach-component
|
do-detach-component
|
||||||
#(st/emit! (dwl/detach-components (map :id copies)))
|
#(st/emit! (dwl/detach-components (map :id copies)))
|
||||||
|
|
||||||
|
@ -464,7 +483,10 @@
|
||||||
{:title (tr "workspace.shape.menu.reset-overrides")
|
{:title (tr "workspace.shape.menu.reset-overrides")
|
||||||
:action do-reset-component})
|
:action do-reset-component})
|
||||||
(when (seq restorable-copies)
|
(when (seq restorable-copies)
|
||||||
{:title (tr "workspace.shape.menu.restore-main")
|
{:title
|
||||||
|
(if restorable-variants?
|
||||||
|
(tr "workspace.shape.menu.restore-variant")
|
||||||
|
(tr "workspace.shape.menu.restore-main"))
|
||||||
:action do-restore-component})
|
:action do-restore-component})
|
||||||
(when can-show-component?
|
(when can-show-component?
|
||||||
{:title (tr "workspace.shape.menu.show-main")
|
{:title (tr "workspace.shape.menu.show-main")
|
||||||
|
|
|
@ -756,7 +756,9 @@
|
||||||
|
|
||||||
(when (and can-swap? (not multi))
|
(when (and can-swap? (not multi))
|
||||||
[:div {:class (stl/css :component-parent-name)}
|
[:div {:class (stl/css :component-parent-name)}
|
||||||
(cfh/merge-path-item-with-dot path (:name component))])]]
|
(if (:deleted component)
|
||||||
|
(tr "workspace.options.component.unlinked")
|
||||||
|
(cfh/merge-path-item-with-dot path (:name component)))])]]
|
||||||
|
|
||||||
(when show-menu?
|
(when show-menu?
|
||||||
[:div {:class (stl/css :component-actions)}
|
[:div {:class (stl/css :component-actions)}
|
||||||
|
@ -776,7 +778,11 @@
|
||||||
(when (and (not swap-opened?) (not multi))
|
(when (and (not swap-opened?) (not multi))
|
||||||
[:& component-annotation {:id id :shape shape :component component :rerender-fn rerender-fn}])
|
[:& component-annotation {:id id :shape shape :component component :rerender-fn rerender-fn}])
|
||||||
|
|
||||||
(when (and is-variant? (not main-instance?) (not swap-opened?) (not multi))
|
(when (and is-variant?
|
||||||
|
(not main-instance?)
|
||||||
|
(not (:deleted component))
|
||||||
|
(not swap-opened?)
|
||||||
|
(not multi))
|
||||||
[:> component-variant* {:component component
|
[:> component-variant* {:component component
|
||||||
:shape shape
|
:shape shape
|
||||||
:data data}])
|
:data data}])
|
||||||
|
|
|
@ -5177,6 +5177,9 @@ msgstr "Annotation"
|
||||||
msgid "workspace.options.component.copy"
|
msgid "workspace.options.component.copy"
|
||||||
msgstr "Copy"
|
msgstr "Copy"
|
||||||
|
|
||||||
|
msgid "workspace.options.component.unlinked"
|
||||||
|
msgstr "Unlinked"
|
||||||
|
|
||||||
#: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:180
|
#: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:180
|
||||||
msgid "workspace.options.component.create-annotation"
|
msgid "workspace.options.component.create-annotation"
|
||||||
msgstr "Create an annotation"
|
msgstr "Create an annotation"
|
||||||
|
@ -6626,6 +6629,9 @@ msgstr "Reset overrides"
|
||||||
msgid "workspace.shape.menu.restore-main"
|
msgid "workspace.shape.menu.restore-main"
|
||||||
msgstr "Restore main component"
|
msgstr "Restore main component"
|
||||||
|
|
||||||
|
msgid "workspace.shape.menu.restore-variant"
|
||||||
|
msgstr "Restore variant"
|
||||||
|
|
||||||
#: src/app/main/ui/workspace/context_menu.cljs:247
|
#: src/app/main/ui/workspace/context_menu.cljs:247
|
||||||
msgid "workspace.shape.menu.select-layer"
|
msgid "workspace.shape.menu.select-layer"
|
||||||
msgstr "Select layer"
|
msgstr "Select layer"
|
||||||
|
|
|
@ -5203,6 +5203,9 @@ msgstr "Nota"
|
||||||
msgid "workspace.options.component.copy"
|
msgid "workspace.options.component.copy"
|
||||||
msgstr "Copia"
|
msgstr "Copia"
|
||||||
|
|
||||||
|
msgid "workspace.options.component.unlinked"
|
||||||
|
msgstr "Desvinculado"
|
||||||
|
|
||||||
#: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:180
|
#: src/app/main/ui/workspace/sidebar/options/menus/component.cljs:180
|
||||||
msgid "workspace.options.component.create-annotation"
|
msgid "workspace.options.component.create-annotation"
|
||||||
msgstr "Crear una nota"
|
msgstr "Crear una nota"
|
||||||
|
@ -6656,6 +6659,9 @@ msgstr "Deshacer modificaciones"
|
||||||
msgid "workspace.shape.menu.restore-main"
|
msgid "workspace.shape.menu.restore-main"
|
||||||
msgstr "Restaurar componente principal"
|
msgstr "Restaurar componente principal"
|
||||||
|
|
||||||
|
msgid "workspace.shape.menu.restore-variant"
|
||||||
|
msgstr "Restaurar variante"
|
||||||
|
|
||||||
#: src/app/main/ui/workspace/context_menu.cljs:247
|
#: src/app/main/ui/workspace/context_menu.cljs:247
|
||||||
msgid "workspace.shape.menu.select-layer"
|
msgid "workspace.shape.menu.select-layer"
|
||||||
msgstr "Seleccionar capa"
|
msgstr "Seleccionar capa"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue