Add prune-unrelated-items debug utility (#10687)

This commit is contained in:
Pablo Alba 2026-07-21 12:31:23 +02:00 committed by GitHub
parent 6c5d01283a
commit 0ff73ae711
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 117 additions and 0 deletions

View File

@ -1651,3 +1651,6 @@
(dm/export dwpg/duplicate-page)
(dm/export dwpg/rename-page)
(dm/export dwpg/delete-page)
;; Shapes
(dm/export dwsh/delete-shapes)

View File

@ -9,12 +9,16 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.exceptions :as ex]
[app.common.files.helpers :as cfh]
[app.common.files.repair :as cfr]
[app.common.files.validate :as cfv]
[app.common.json :as json]
[app.common.logging :as l]
[app.common.pprint :as pp]
[app.common.transit :as t]
[app.common.types.component :as ctk]
[app.common.types.components-list :as ctkl]
[app.common.types.container :as ctn]
[app.common.types.file :as ctf]
[app.common.uuid :as uuid]
[app.main.data.changes :as dwc]
@ -28,6 +32,7 @@
[app.main.data.workspace.path.shortcuts]
[app.main.data.workspace.selection :as dws]
[app.main.data.workspace.shortcuts]
[app.main.data.workspace.undo :as dwu]
[app.main.errors :as errors]
[app.main.repo :as rp]
[app.main.store :as st]
@ -528,3 +533,112 @@
[o]
(app.common.pprint/pprint o {:level 100 :length 100}))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRUNE UNRELATED ITEMS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- get-related-ids
"Given a `context` map (:pindex, :fdata) and a `[page-id id]` pair, returns
the set of `[page-id id]` pairs directly related to it, NOT recursively:
- its children (including itself)
- its ancestors
- the main instance `[page-id id]` of its component, if it's inside a
component copy of a component defined in the current file (libraries
are ignored)
Ids are only unique within a page, so every id is always tracked together
with the page it belongs to."
[{:keys [pindex fdata]} [page-id id]]
(let [page-objects (-> (get pindex page-id) :objects)
shape (get page-objects id)]
(if (nil? shape)
#{}
(let [related (-> #{}
(into (map (partial vector page-id) (cfh/get-parent-ids page-objects id)))
(into (map (partial vector page-id) (cfh/get-children-ids-with-self page-objects id))))
head (when (ctk/in-component-copy? shape)
(ctn/get-head-shape page-objects shape))
component (when (and (some? head) (= (:component-file head) (:id fdata)))
(ctkl/get-component fdata (:component-id head)))]
(cond-> related
(some? component)
(conj [(:main-instance-page component) (:main-instance-id component)]))))))
(defn ^:export prune-unrelated-items
"This function is DESTRUCTIVE. It deletes from the current file all the pages and layers unrelated to the selection.
It is used to isolate bugs"
[]
(let [state @st/state
current-pid (:current-page-id state)
selected (get-selected state)
fdata (dsh/lookup-file-data state)
pindex (:pages-index fdata)
context {:pindex pindex
:fdata fdata}
related
(loop [related (into #{} (map (partial vector current-pid)) selected)]
(let [expanded (->> related
(reduce (fn [acc pair] (into acc (get-related-ids context pair)))
related)
(remove (fn [[_ id]] (= id uuid/zero)))
set)]
(if (= expanded related)
related
(recur expanded))))
related-by-page
(reduce (fn [acc [page-id id]] (update acc page-id (fnil conj #{}) id))
{}
related)
unrelated-pages
(->> (:pages fdata)
(remove (fn [page-id] (seq (get related-by-page page-id))))
vec)
unrelated-items-by-page
(->> (:pages fdata)
(remove (set unrelated-pages))
(map (fn [page-id]
(let [page-related (get related-by-page page-id #{})
ids (->> (get pindex page-id)
:objects
keys
(remove #{uuid/zero})
(remove page-related)
set)]
[page-id ids])))
(filter (fn [[_ ids]] (seq ids)))
vec)
items-to-delete
(reduce + (map (comp count second) unrelated-items-by-page))]
(js/console.log (str "Pages to delete: " (count unrelated-pages)
", items to delete: " items-to-delete))
(.table js/console
(->> unrelated-items-by-page
(mapcat (fn [[page-id ids]]
(let [objects (-> (get pindex page-id) :objects)]
(map (fn [id]
{:page-id (str page-id)
:id (str id)
:name (:name (get objects id))})
ids))))
(clj->js)))
(when (and (or (seq unrelated-pages) (pos? items-to-delete))
(js/confirm (str "Delete " (count unrelated-pages) " unrelated page(s) and "
items-to-delete " unrelated item(s)?")))
(let [undo-id (js/Symbol)]
(apply st/emit!
(concat
[(dwu/start-undo-transaction undo-id)]
(map dw/delete-page unrelated-pages)
(map (fn [[page-id ids]]
(dw/delete-shapes page-id ids))
unrelated-items-by-page)
[(dwu/commit-undo-transaction undo-id)]))))
nil))