diff --git a/CHANGES.md b/CHANGES.md index 11b308b336..3fccd4f985 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ ### :sparkles: New features & Enhancements +- Add "Delete group" option to the assets panel context menu for components, colors and typographies (by @FairyPigDev) [Github #9141](https://github.com/penpot/penpot/issues/9141) - Add `Alt+click` on a layer's disclosure arrow to recursively expand the entire subtree rooted at that layer in the Layers sidebar; symmetric with the existing `Shift+click` collapse-all gesture, and removes the O(siblings × depth) click cost of unfolding a deep subtree one level at a time [Github #7736](https://github.com/penpot/penpot/issues/7736) - Show alpha percentage next to library color values to distinguish colors that differ only in opacity (by @rockchris099) [Github #6328](https://github.com/penpot/penpot/issues/6328) - Add "Clear artboard guides" option to right-click context menu for frames (by @eureka0928) [Github #6987](https://github.com/penpot/penpot/issues/6987) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs index c0395cf4f4..83df80b9db 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs @@ -280,7 +280,7 @@ (mf/defc colors-group [{:keys [file-id prefix groups open-groups force-open? local? selected multi-colors? multi-assets? on-asset-click on-assets-delete - on-clear-selection on-group on-rename-group on-ungroup colors + on-clear-selection on-group on-rename-group on-ungroup on-delete-group colors selected-full]}] (let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that false @@ -325,7 +325,8 @@ :path prefix :is-group-open group-open? :on-rename on-rename-group - :on-ungroup on-ungroup}] + :on-ungroup on-ungroup + :on-delete-group on-delete-group}] (when group-open? [:* (let [colors (get groups "" [])] @@ -378,6 +379,7 @@ :on-group on-group :on-rename-group on-rename-group :on-ungroup on-ungroup + :on-delete-group on-delete-group :colors colors :selected-full selected-full}]))])])) @@ -499,6 +501,39 @@ file-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 + (mf/use-fn + (mf/deps colors on-clear-selection) + (fn [path] + (let [group-colors + (->> colors + (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 (mf/use-fn (mf/deps groups on-asset-click) (partial on-asset-click groups))] @@ -533,5 +568,6 @@ :on-group on-group :on-rename-group on-rename-group :on-ungroup on-ungroup + :on-delete-group on-delete-group :colors colors :selected-full selected-full}]]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs index 077742d71d..2d9d1b72e7 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs @@ -17,6 +17,7 @@ [app.main.data.workspace :as dw] [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.media :as dwm] + [app.main.data.workspace.shapes :as dwsh] [app.main.data.workspace.undo :as dwu] [app.main.data.workspace.variants :as dwv] [app.main.refs :as refs] @@ -191,7 +192,7 @@ (mf/defc components-group* [{:keys [file-id prefix groups open-groups is-force-open renaming is-listing-thumbs selected on-asset-click - on-drag-start do-rename cancel-rename on-rename-group on-group on-ungroup on-context-menu + on-drag-start do-rename cancel-rename on-rename-group on-group on-ungroup on-delete-group on-context-menu selected-full is-local count-variants on-group-combine-variants]}] (let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that @@ -246,6 +247,7 @@ :is-can-combine can-combine? :on-rename on-rename-group :on-ungroup on-ungroup + :on-delete-group on-delete-group :on-group-combine-variants on-group-combine-variants}] (when group-open? @@ -303,6 +305,7 @@ :cancel-rename cancel-rename :on-rename-group on-rename-group :on-ungroup on-ungroup + :on-delete-group on-delete-group :on-context-menu on-context-menu :on-group-combine-variants on-group-combine-variants :selected-full selected-full @@ -493,6 +496,60 @@ (map #(dwv/rename-comp-or-variant-and-main (:id %) (cmm/ungroup % path))))) (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 + (mf/use-fn + (mf/deps components on-clear-selection) + (fn [path] + (let [group-components + (->> components + (filter #(cpn/inside-path? (:path %) path))) + + {variants true non-variants false} + (group-by (comp boolean ctc/is-variant?) group-components) + + ;; One delete-shapes per variant container, not per + ;; sibling variant within that container. + variant-containers + (->> variants + (group-by :variant-id) + (map (fn [[_ comps]] (first comps)))) + + ;; 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 (mf/use-fn (mf/deps components on-clear-selection) @@ -602,6 +659,7 @@ :on-rename-group on-rename-group :on-group on-group :on-ungroup on-ungroup + :on-delete-group on-delete-group :on-group-combine-variants on-group-combine-variants :on-context-menu on-context-menu :selected-full selected-full diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs index 4a781fa48a..c7e72c871b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs @@ -23,7 +23,7 @@ [rumext.v2 :as mf])) (mf/defc asset-group-title* - [{:keys [file-id section path is-group-open on-rename on-ungroup on-group-combine-variants is-can-combine on-add]}] + [{:keys [file-id section path is-group-open on-rename on-ungroup on-delete-group on-group-combine-variants is-can-combine on-add]}] (when-not (empty? path) (let [[other-path last-path truncated] (cpn/compact-path path 35 true) menu-state (mf/use-state cmm/initial-context-menu-state) @@ -69,6 +69,12 @@ {:name (tr "workspace.assets.ungroup") :id "assets-ungroup-group" :handler #(on-ungroup path)}] + on-delete-group + (conj + {:name (tr "workspace.assets.delete-group") + :id "assets-delete-group" + :handler #(on-delete-group path)}) + is-can-combine (conj {:name (tr "workspace.shape.menu.combine-as-variants") diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs index 082fecb996..cf95f8b477 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs @@ -134,7 +134,7 @@ {::mf/wrap-props false} [{:keys [file-id prefix groups open-groups force-open? file local? selected local-data editing-id renaming-id on-asset-click handle-change on-rename-group - on-ungroup on-context-menu selected-full is-read-only]}] + on-ungroup on-delete-group on-context-menu selected-full is-read-only]}] (let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that false (get open-groups prefix true)) @@ -185,6 +185,7 @@ :is-group-open group-open? :on-rename on-rename-group :on-ungroup on-ungroup + :on-delete-group on-delete-group :on-add (when (and local? (not is-read-only)) add-typography-to-group)}] @@ -238,6 +239,7 @@ :handle-change handle-change :on-rename-group on-rename-group :on-ungroup on-ungroup + :on-delete-group on-delete-group :on-context-menu on-context-menu :selected-full selected-full :is-read-only is-read-only}]))])])) @@ -352,6 +354,39 @@ (cmm/ungroup % path))))) (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 + (mf/use-fn + (mf/deps typographies file-id on-clear-selection) + (fn [path] + (let [group-typographies + (->> typographies + (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 (mf/use-fn (mf/deps selected on-clear-selection read-only?) @@ -441,6 +476,7 @@ :handle-change handle-change :on-rename-group on-rename-group :on-ungroup on-ungroup + :on-delete-group on-delete-group :on-context-menu on-context-menu :selected-full selected-full :is-read-only read-only?}] diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 4b774cd775..f2c15954b7 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -3561,6 +3561,16 @@ msgstr "Are you sure you want to delete this page?" msgid "modals.delete-page.title" msgstr "Delete page" +#: src/app/main/ui/workspace/sidebar/assets/components.cljs, src/app/main/ui/workspace/sidebar/assets/colors.cljs, src/app/main/ui/workspace/sidebar/assets/typographies.cljs +msgid "modals.delete-asset-group.title" +msgstr "Delete group" + +#: src/app/main/ui/workspace/sidebar/assets/components.cljs, src/app/main/ui/workspace/sidebar/assets/colors.cljs, src/app/main/ui/workspace/sidebar/assets/typographies.cljs +msgid "modals.delete-asset-group.message" +msgid_plural "modals.delete-asset-group.message" +msgstr[0] "Are you sure you want to delete this asset?" +msgstr[1] "Are you sure you want to delete these %s assets?" + #: src/app/main/ui/dashboard/project_menu.cljs:73 msgid "modals.delete-project-confirm.accept" msgstr "Delete project" @@ -5733,6 +5743,10 @@ msgstr "Text Transform" msgid "workspace.assets.ungroup" msgstr "Ungroup" +#: src/app/main/ui/workspace/sidebar/assets/groups.cljs +msgid "workspace.assets.delete-group" +msgstr "Delete group" + #: src/app/main/ui/workspace/colorpicker.cljs:428, src/app/main/ui/workspace/colorpicker.cljs:441 msgid "workspace.colorpicker.color-tokens" msgstr "Color tokens"