From ed95b5900331953c14fadf9dd371815203a0645d Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 24 May 2021 17:25:28 +0200 Subject: [PATCH] :bug: Fix issue when group creation leaves an empty group --- CHANGES.md | 1 + frontend/src/app/main/data/workspace.cljs | 29 +++--- .../src/app/main/data/workspace/groups.cljs | 97 ++++++++++++++++--- .../data/workspace/libraries_helpers.cljs | 2 +- 4 files changed, 100 insertions(+), 29 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6df4e555c..504a776e6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -33,6 +33,7 @@ - Fix problem with imported SVG on editing paths [#971](https://github.com/penpot/penpot/issues/971) - Fix problem with color picker positioning - Fix order on color palette [#961](https://github.com/penpot/penpot/issues/961) +- Fix issue when group creation leaves an empty group [#1724](https://tree.taiga.io/project/penpot/issue/1724) ### :arrow_up: Deps updates diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 1d42177dc..5b70d9ce9 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -991,19 +991,22 @@ [[] [] []] ids) - [rchanges uchanges] (relocate-shapes-changes objects - parents - parent-id - page-id - to-index - ids - groups-to-delete - groups-to-unmask - shapes-to-detach - shapes-to-reroot - shapes-to-deroot)] + [rchanges uchanges] + (relocate-shapes-changes objects + parents + parent-id + page-id + to-index + ids + groups-to-delete + groups-to-unmask + shapes-to-detach + shapes-to-reroot + shapes-to-deroot) + + ] (rx/of (dch/commit-changes {:redo-changes rchanges - :undo-chanes uchanges + :undo-changes uchanges :origin it}) (dwc/expand-collapse parent-id)))))) @@ -1058,7 +1061,7 @@ :id id :index cidx}] (rx/of (dch/commit-changes {:redo-changes [rchg] - :undo-chanes [uchg] + :undo-changes [uchg] :origin it})))))) ;; --- Shape / Selection Alignment and Distribution diff --git a/frontend/src/app/main/data/workspace/groups.cljs b/frontend/src/app/main/data/workspace/groups.cljs index 356be5153..849fdde94 100644 --- a/frontend/src/app/main/data/workspace/groups.cljs +++ b/frontend/src/app/main/data/workspace/groups.cljs @@ -32,31 +32,97 @@ (gsh/setup selrect) (assoc :shapes (mapv :id shapes))))) +(defn get-empty-groups + "Retrieve emtpy groups after group creation" + [objects parent-id shapes] + (let [ids (cp/clean-loops objects (into #{} (map :id) shapes)) + parents (->> ids + (reduce #(conj %1 (cp/get-parent %2 objects)) + #{}))] + (loop [current-id (first parents) + to-check (rest parents) + removed-id? ids + result #{}] + + (if-not current-id + ;; Base case, no next element + result + + (let [group (get objects current-id)] + (if (and (not= :frame (:type group)) + (not= current-id parent-id) + (empty? (remove removed-id? (:shapes group)))) + + ;; Adds group to the remove and check its parent + (let [to-check (d/concat [] to-check [(cp/get-parent current-id objects)]) ] + (recur (first to-check) + (rest to-check) + (conj removed-id? current-id) + (conj result current-id))) + + ;; otherwise recur + (recur (first to-check) + (rest to-check) + removed-id? + result))))))) + (defn prepare-create-group - [page-id shapes prefix keep-name] + [objects page-id shapes prefix keep-name] (let [group (make-group shapes prefix keep-name) + frame-id (:frame-id (first shapes)) + parent-id (:parent-id (first shapes)) rchanges [{:type :add-obj :id (:id group) :page-id page-id - :frame-id (:frame-id (first shapes)) - :parent-id (:parent-id (first shapes)) + :frame-id frame-id + :parent-id parent-id :obj group :index (::index (first shapes))} + {:type :mov-objects :page-id page-id :parent-id (:id group) :shapes (mapv :id shapes)}] - uchanges (conj - (mapv (fn [obj] {:type :mov-objects - :page-id page-id - :parent-id (:parent-id obj) - :index (::index obj) - :shapes [(:id obj)]}) - shapes) - {:type :del-obj - :id (:id group) - :page-id page-id})] + uchanges (-> (mapv + (fn [obj] + {:type :mov-objects + :page-id page-id + :parent-id (:parent-id obj) + :index (::index obj) + :shapes [(:id obj)]}) shapes) + (conj + {:type :del-obj + :id (:id group) + :page-id page-id})) + + ids-to-delete (get-empty-groups objects parent-id shapes) + + delete-group + (fn [changes id] + (-> changes + (conj {:type :del-obj + :id id + :page-id page-id}))) + + add-deleted-group + (fn [changes id] + (let [obj (-> (get objects id) + (d/without-keys [:shapes]))] + + (d/concat [{:type :add-obj + :id id + :page-id page-id + :frame-id (:frame-id obj) + :parent-id (:parent-id obj) + :obj obj + :index (::index obj)}] changes))) + + rchanges (->> ids-to-delete + (reduce delete-group rchanges)) + + uchanges (->> ids-to-delete + (reduce add-deleted-group uchanges))] [group rchanges uchanges])) (defn prepare-remove-group @@ -107,7 +173,8 @@ selected (cp/clean-loops objects selected) shapes (shapes-for-grouping objects selected)] (when-not (empty? shapes) - (let [[group rchanges uchanges] (prepare-create-group page-id shapes "Group-" false)] + (let [[group rchanges uchanges] + (prepare-create-group objects page-id shapes "Group-" false)] (rx/of (dch/commit-changes {:redo-changes rchanges :undo-changes uchanges :origin it}) @@ -146,7 +213,7 @@ (if (and (= (count shapes) 1) (= (:type (first shapes)) :group)) [(first shapes) [] []] - (prepare-create-group page-id shapes "Group-" true)) + (prepare-create-group objects page-id shapes "Group-" true)) rchanges (d/concat rchanges [{:type :mod-obj diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index 01d8a61a8..c59050916 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -131,7 +131,7 @@ (if (and (= (count shapes) 1) (= (:type (first shapes)) :group)) [(first shapes) [] []] - (dwg/prepare-create-group page-id shapes "Component-" true)) + (dwg/prepare-create-group objects page-id shapes "Component-" true)) [new-shape new-shapes updated-shapes] (make-component-shape group objects file-id)