mirror of
https://github.com/penpot/penpot.git
synced 2026-09-14 07:59:36 +00:00
♻️ Extract make-delete-asset-group-fn helper for assets panel (#9211)
Reviewer follow-up on PR #9151. The "Delete group" handler was duplicated across the three assets-panel sections (colors, typographies, components), each carrying the same skeleton — filter by group path, build an undo-id, run the deletes inside one transaction, and show the same confirm modal — with only the path predicate and the per-asset delete event differing. Add `app.main.ui.workspace.sidebar.assets.common/make-delete-asset-group-fn` that takes the differing parts as options: - `:assets` collection to filter. - `:on-clear-selection` invoked before the deletes. - `:delete-events` `(fn [matching-assets] => seq-of-events)`. - `:path-filter` predicate (defaults to `str/starts-with?`), overridden to `cpn/inside-path?` for components so nested group paths match the same way the existing ungroup/combine helpers do. The factory returns `(fn [path] …)` so each call site stays a straight `mf/use-fn`. The variant-container dedup in components (one `delete-shapes` per container, not one per sibling variant) moves into that section's `:delete-events` fn and is unchanged in behavior. Cleanup ------- The `:as i18n` alias is no longer needed in any of the three section files (its only use was `i18n/c` for the modal count, which the helper now handles); reduced to `:refer [tr]`. Github #9141 Signed-off-by: FairyPigDev <luislee3108@gmail.com> Co-authored-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
parent
400414776b
commit
ed021711b6
@ -29,7 +29,7 @@
|
|||||||
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
||||||
[app.util.color :as uc]
|
[app.util.color :as uc]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
@ -501,38 +501,12 @@
|
|||||||
file-id))))
|
file-id))))
|
||||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||||
|
|
||||||
;; Issue #9141. Delete every color under a group path in a
|
|
||||||
;; single undo transaction, after user confirmation.
|
|
||||||
on-delete-group
|
on-delete-group
|
||||||
(mf/use-fn
|
(mf/with-memo [colors on-clear-selection]
|
||||||
(mf/deps colors on-clear-selection)
|
(cmm/make-delete-asset-group-fn
|
||||||
(fn [path]
|
{:assets colors
|
||||||
(let [group-colors
|
:on-clear-selection on-clear-selection
|
||||||
(->> colors
|
:delete-events #(map (fn [c] (dwl/delete-color {:id (:id c)})) %)}))
|
||||||
(filter #(str/starts-with? (:path %) path)))
|
|
||||||
|
|
||||||
;; Hoisted so the start/commit pair is bound to the
|
|
||||||
;; same symbol regardless of how `do-delete` is
|
|
||||||
;; invoked by the confirm modal. Review suggestion
|
|
||||||
;; on PR #9151.
|
|
||||||
undo-id (js/Symbol)
|
|
||||||
|
|
||||||
do-delete
|
|
||||||
(fn []
|
|
||||||
(on-clear-selection)
|
|
||||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
|
||||||
(run! st/emit!
|
|
||||||
(map #(dwl/delete-color {:id (:id %)}) group-colors))
|
|
||||||
(st/emit! (dwu/commit-undo-transaction undo-id)))]
|
|
||||||
(when (seq group-colors)
|
|
||||||
(st/emit!
|
|
||||||
(modal/show
|
|
||||||
{:type :confirm
|
|
||||||
:title (tr "modals.delete-asset-group.title")
|
|
||||||
:message (tr "modals.delete-asset-group.message"
|
|
||||||
(i18n/c (count group-colors)))
|
|
||||||
:accept-label (tr "labels.delete")
|
|
||||||
:on-accept do-delete}))))))
|
|
||||||
|
|
||||||
on-asset-click
|
on-asset-click
|
||||||
(mf/use-fn (mf/deps groups on-asset-click) (partial on-asset-click groups))]
|
(mf/use-fn (mf/deps groups on-asset-click) (partial on-asset-click groups))]
|
||||||
|
|||||||
@ -198,6 +198,39 @@
|
|||||||
(run! st/emit!))
|
(run! st/emit!))
|
||||||
(st/emit! (dwu/commit-undo-transaction undo-id))))
|
(st/emit! (dwu/commit-undo-transaction undo-id))))
|
||||||
|
|
||||||
|
(defn make-delete-asset-group-fn
|
||||||
|
"Build an `:on-delete-group` handler that filters `assets` by group
|
||||||
|
path, asks the user to confirm, and on accept emits every event
|
||||||
|
produced by `delete-events` inside one undo transaction.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
- `:assets` collection to filter.
|
||||||
|
- `:on-clear-selection` invoked before the deletes.
|
||||||
|
- `:delete-events` `(fn [matching-assets] => seq-of-events)`.
|
||||||
|
- `:path-filter` `(fn [asset-path group-path] => bool)` deciding
|
||||||
|
which assets fall under the group. Defaults to
|
||||||
|
`str/starts-with?`."
|
||||||
|
[{:keys [assets on-clear-selection delete-events path-filter]
|
||||||
|
:or {path-filter str/starts-with?}}]
|
||||||
|
(fn [path]
|
||||||
|
(let [matching (filter #(path-filter (:path %) path) assets)
|
||||||
|
undo-id (js/Symbol)
|
||||||
|
do-delete
|
||||||
|
(fn []
|
||||||
|
(on-clear-selection)
|
||||||
|
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||||
|
(run! st/emit! (delete-events matching))
|
||||||
|
(st/emit! (dwu/commit-undo-transaction undo-id)))]
|
||||||
|
(when (seq matching)
|
||||||
|
(st/emit!
|
||||||
|
(modal/show
|
||||||
|
{:type :confirm
|
||||||
|
:title (tr "modals.delete-asset-group.title")
|
||||||
|
:message (tr "modals.delete-asset-group.message"
|
||||||
|
(c (count matching)))
|
||||||
|
:accept-label (tr "labels.delete")
|
||||||
|
:on-accept do-delete}))))))
|
||||||
|
|
||||||
(defn on-drop-asset
|
(defn on-drop-asset
|
||||||
[event asset dragging* selected selected-full selected-paths rename]
|
[event asset dragging* selected selected-full selected-paths rename]
|
||||||
(let [create-typed-assets-group (partial create-assets-group rename)]
|
(let [create-typed-assets-group (partial create-assets-group rename)]
|
||||||
|
|||||||
@ -33,7 +33,7 @@
|
|||||||
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.dom.dnd :as dnd]
|
[app.util.dom.dnd :as dnd]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[potok.v2.core :as ptk]
|
[potok.v2.core :as ptk]
|
||||||
@ -496,59 +496,32 @@
|
|||||||
(map #(dwv/rename-comp-or-variant-and-main (:id %) (cmm/ungroup % path)))))
|
(map #(dwv/rename-comp-or-variant-and-main (:id %) (cmm/ungroup % path)))))
|
||||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||||
|
|
||||||
;; Issue #9141. Delete every component under a group path in a
|
|
||||||
;; single undo transaction, after user confirmation. Variants
|
|
||||||
;; are handled via their variant container (matching the
|
|
||||||
;; per-item delete dispatch in file_library.cljs); sibling
|
|
||||||
;; variants sharing a container are deduplicated so we delete
|
|
||||||
;; each container only once.
|
|
||||||
on-delete-group
|
on-delete-group
|
||||||
(mf/use-fn
|
(mf/with-memo [components on-clear-selection]
|
||||||
(mf/deps components on-clear-selection)
|
(cmm/make-delete-asset-group-fn
|
||||||
(fn [path]
|
{:assets components
|
||||||
(let [group-components
|
:on-clear-selection on-clear-selection
|
||||||
(->> components
|
:path-filter cpn/inside-path?
|
||||||
(filter #(cpn/inside-path? (:path %) path)))
|
;; Variants are handled via their variant container
|
||||||
|
;; (matching the per-item delete dispatch in
|
||||||
|
;; file_library.cljs); sibling variants sharing a
|
||||||
|
;; container are deduplicated so we delete each container
|
||||||
|
;; only once.
|
||||||
|
:delete-events
|
||||||
|
(fn [matching]
|
||||||
|
(let [{variants true non-variants false}
|
||||||
|
(group-by (comp boolean ctc/is-variant?) matching)
|
||||||
|
|
||||||
{variants true non-variants false}
|
variant-containers
|
||||||
(group-by (comp boolean ctc/is-variant?) group-components)
|
(->> variants
|
||||||
|
(group-by :variant-id)
|
||||||
;; One delete-shapes per variant container, not per
|
(map (fn [[_ comps]] (first comps))))]
|
||||||
;; sibling variant within that container.
|
(concat
|
||||||
variant-containers
|
(map #(dwsh/delete-shapes (:main-instance-page %)
|
||||||
(->> variants
|
#{(:variant-id %)})
|
||||||
(group-by :variant-id)
|
variant-containers)
|
||||||
(map (fn [[_ comps]] (first comps))))
|
(map #(dwl/delete-component {:id (:id %)})
|
||||||
|
non-variants))))}))
|
||||||
;; Hoisted so the start/commit pair is bound to the
|
|
||||||
;; same symbol regardless of how `do-delete` is
|
|
||||||
;; invoked by the confirm modal. Review suggestion
|
|
||||||
;; on PR #9151.
|
|
||||||
undo-id (js/Symbol)
|
|
||||||
|
|
||||||
do-delete
|
|
||||||
(fn []
|
|
||||||
(on-clear-selection)
|
|
||||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
|
||||||
(run! st/emit!
|
|
||||||
(map (fn [component]
|
|
||||||
(dwsh/delete-shapes (:main-instance-page component)
|
|
||||||
#{(:variant-id component)}))
|
|
||||||
variant-containers))
|
|
||||||
(run! st/emit!
|
|
||||||
(map (fn [component]
|
|
||||||
(dwl/delete-component {:id (:id component)}))
|
|
||||||
non-variants))
|
|
||||||
(st/emit! (dwu/commit-undo-transaction undo-id)))]
|
|
||||||
(when (seq group-components)
|
|
||||||
(st/emit!
|
|
||||||
(modal/show
|
|
||||||
{:type :confirm
|
|
||||||
:title (tr "modals.delete-asset-group.title")
|
|
||||||
:message (tr "modals.delete-asset-group.message"
|
|
||||||
(i18n/c (count group-components)))
|
|
||||||
:accept-label (tr "labels.delete")
|
|
||||||
:on-accept do-delete}))))))
|
|
||||||
|
|
||||||
on-group-combine-variants
|
on-group-combine-variants
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
||||||
[app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry]]
|
[app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry]]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[potok.v2.core :as ptk]
|
[potok.v2.core :as ptk]
|
||||||
@ -354,38 +354,12 @@
|
|||||||
(cmm/ungroup % path)))))
|
(cmm/ungroup % path)))))
|
||||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||||
|
|
||||||
;; Issue #9141. Delete every typography under a group path in a
|
|
||||||
;; single undo transaction, after user confirmation.
|
|
||||||
on-delete-group
|
on-delete-group
|
||||||
(mf/use-fn
|
(mf/with-memo [typographies on-clear-selection]
|
||||||
(mf/deps typographies file-id on-clear-selection)
|
(cmm/make-delete-asset-group-fn
|
||||||
(fn [path]
|
{:assets typographies
|
||||||
(let [group-typographies
|
:on-clear-selection on-clear-selection
|
||||||
(->> typographies
|
:delete-events #(map (fn [t] (dwl/delete-typography (:id t))) %)}))
|
||||||
(filter #(str/starts-with? (:path %) path)))
|
|
||||||
|
|
||||||
;; Hoisted so the start/commit pair is bound to the
|
|
||||||
;; same symbol regardless of how `do-delete` is
|
|
||||||
;; invoked by the confirm modal. Review suggestion
|
|
||||||
;; on PR #9151.
|
|
||||||
undo-id (js/Symbol)
|
|
||||||
|
|
||||||
do-delete
|
|
||||||
(fn []
|
|
||||||
(on-clear-selection)
|
|
||||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
|
||||||
(run! st/emit!
|
|
||||||
(map #(dwl/delete-typography (:id %)) group-typographies))
|
|
||||||
(st/emit! (dwu/commit-undo-transaction undo-id)))]
|
|
||||||
(when (seq group-typographies)
|
|
||||||
(st/emit!
|
|
||||||
(modal/show
|
|
||||||
{:type :confirm
|
|
||||||
:title (tr "modals.delete-asset-group.title")
|
|
||||||
:message (tr "modals.delete-asset-group.message"
|
|
||||||
(i18n/c (count group-typographies)))
|
|
||||||
:accept-label (tr "labels.delete")
|
|
||||||
:on-accept do-delete}))))))
|
|
||||||
|
|
||||||
on-context-menu
|
on-context-menu
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user