Przeglądaj źródła

fix: clean orphaned pages when saving the editor

Tienson Qin 4 lat temu
rodzic
commit
166ffa3b35

+ 1 - 1
src/main/frontend/components/page.cljs

@@ -846,7 +846,7 @@
             [:a.ml-1.pr-2.opacity-70.hover:opacity-100
              {:on-click (fn [] (state/set-modal!
                                 (batch-delete-dialog
-                                 (model/get-orphaned-pages (state/get-current-repo)) true
+                                 (model/get-orphaned-pages {}) true
                                  #(do
                                     (reset! *checks nil)
                                     (refresh-pages)))))}

+ 30 - 21
src/main/frontend/db/model.cljs

@@ -336,6 +336,13 @@
      (set)
      (set/union #{page-id}))))
 
+(defn get-entities-by-ids
+  ([ids]
+   (get-entities-by-ids (state/get-current-repo) ids))
+  ([repo ids]
+   (when repo
+     (db-utils/pull-many repo '[*] ids))))
+
 (defn get-page-names-by-ids
   ([ids]
    (get-page-names-by-ids (state/get-current-repo) ids))
@@ -1432,32 +1439,34 @@
    (take 200)))
 
 (defn get-orphaned-pages
-  [repo]
-  (let [all-pages (get-pages repo)
+  [{:keys [repo pages empty-ref-f]
+          :or {repo (state/get-current-repo)
+               empty-ref-f (fn [page] (zero? (count (:block/_refs page))))}}]
+  (let [pages (or pages (get-pages repo))
         built-in-pages (set (map string/lower-case default-db/built-in-pages-names))
         orphaned-pages (->>
-                         (map
-                           (fn [page]
-                             (let [name (string/lower-case page)]
-                               (when-let [page (db-utils/entity [:block/name name])]
-                                 (and
-                                   (zero? (count (:block/_refs page)))
-                                   (or
-                                     (page-empty? repo (:db/id page))
-                                     (let [first-child (first (:block/_left page))
-                                           children (:block/_page page)]
-                                       (and
-                                         first-child
-                                         (= 1 (count children))
-                                         (contains? #{"" "-" "*"} (string/trim (:block/content first-child))))))
-                                   (not (contains? built-in-pages name))
-                                   page))))
-                           all-pages)
-                         (remove false?))]
+                        (map
+                          (fn [page]
+                            (let [name (string/lower-case page)]
+                              (when-let [page (db-utils/entity [:block/name name])]
+                                (and
+                                 (empty-ref-f page)
+                                 (or
+                                  (page-empty? repo (:db/id page))
+                                  (let [first-child (first (:block/_left page))
+                                        children (:block/_page page)]
+                                    (and
+                                     first-child
+                                     (= 1 (count children))
+                                     (contains? #{"" "-" "*"} (string/trim (:block/content first-child))))))
+                                 (not (contains? built-in-pages name))
+                                 page))))
+                          pages)
+                        (remove false?))]
     orphaned-pages))
 
 (defn remove-orphaned-pages!
-  ([repo] (remove-orphaned-pages! repo (get-orphaned-pages repo)))
+  ([repo] (remove-orphaned-pages! repo (get-orphaned-pages {})))
   ([repo orphaned-pages]
    (let [transaction (mapv (fn [page] [:db/retractEntity (:db/id page)]) orphaned-pages)]
      (db-utils/transact! transaction))))

+ 0 - 7
src/main/frontend/handler/editor.cljs

@@ -186,13 +186,6 @@
     (doseq [block blocks]
       (gdom-classes/remove block "block-highlight"))))
 
-;; FIXME: children' :block/path-ref-pages
-(defn compute-retract-refs
-  "Computes old references to be retracted."
-  [eid {:block/keys [refs]} old-refs]
-  ;; TODO:
-  )
-
 (defn- get-edit-input-id-with-block-id
   [block-id]
   (when-let [first-block (util/get-first-block-by-id block-id)]

+ 25 - 3
src/main/frontend/modules/outliner/core.cljs

@@ -2,6 +2,7 @@
   (:require [clojure.set :as set]
             [clojure.zip :as zip]
             [frontend.db :as db]
+            [frontend.db.model :as db-model]
             [frontend.db-schema :as db-schema]
             [frontend.db.conn :as conn]
             [frontend.db.outliner :as db-outliner]
@@ -82,6 +83,23 @@
         ]
     block))
 
+(defn- remove-orphaned-page-refs!
+  [db-id txs-state old-refs new-refs]
+  (when (not= old-refs new-refs)
+    (let [new-refs (set (map :block/name new-refs))
+          old-pages (->> (map :db/id old-refs)
+                         (db-model/get-entities-by-ids)
+                         (remove (fn [e] (contains? new-refs (:block/name e))))
+                         (map :block/name))
+          orphaned-pages (db-model/get-orphaned-pages {:pages old-pages
+                                                       :empty-ref-f (fn [page]
+                                                                      (let [refs (:block/_refs page)]
+                                                                        (or (zero? (count refs))
+                                                                            (= #{db-id} (set (map :db/id refs))))))})]
+      (when (seq orphaned-pages)
+        (let [tx (mapv (fn [page] [:db/retractEntity (:db/id page)]) orphaned-pages)]
+          (swap! txs-state (fn [state] (vec (concat state tx)))))))))
+
 ;; -get-id, -get-parent-id, -get-left-id return block-id
 ;; the :block/parent, :block/left should be datascript lookup ref
 
@@ -142,7 +160,10 @@
                 (util/remove-nils))
           m (if (state/enable-block-timestamps?) (block-with-timestamps m) m)
           other-tx (:db/other-tx m)
-          id (:db/id (:data this))]
+          id (:db/id (:data this))
+          block-entity (db/entity id)
+          old-refs (:block/refs block-entity)
+          new-refs (:block/refs m)]
       (when (seq other-tx)
         (swap! txs-state (fn [txs]
                            (vec (concat txs other-tx)))))
@@ -155,13 +176,14 @@
                                            [:db/retract id attribute])
                                       db-schema/retract-attributes)))))
 
-        (when-let [e (:block/page (db/entity id))]
+        (when-let [e (:block/page block-entity)]
           (let [m {:db/id (:db/id e)
                    :block/updated-at (util/time-ms)}
                 m (if (:block/created-at e)
                     m
                     (assoc m :block/created-at (util/time-ms)))]
-            (swap! txs-state conj m))))
+            (swap! txs-state conj m))
+          (remove-orphaned-page-refs! (:db/id block-entity) txs-state old-refs new-refs)))
 
       (swap! txs-state conj (dissoc m :db/other-tx))