fix: remove inline page tags when saving or inserting blocks

Page tags here means db-class/page-classes.
This commit is contained in:
Tienson Qin
2025-08-27 13:47:27 +08:00
parent cf47d75077
commit 61b862d88a
3 changed files with 115 additions and 9 deletions

View File

@@ -10,6 +10,7 @@
[logseq.common.util.page-ref :as page-ref]
[logseq.common.uuid :as common-uuid]
[logseq.db :as ldb]
[logseq.db.common.entity-plus :as entity-plus]
[logseq.db.common.order :as db-order]
[logseq.db.file-based.schema :as file-schema]
[logseq.db.frontend.class :as db-class]
@@ -27,6 +28,8 @@
[malli.core :as m]
[malli.util :as mu]))
;; TODO: remove `repo` usage, use db to check `entity-plus/db-based-graph?`
(def ^:private block-map
(mu/optional-keys
[:map
@@ -234,14 +237,38 @@
[:db/retract eid :block/tags :logseq.class/Page]])))
tags))
(defn- remove-inline-page-classes
[db {:block/keys [tags] :as block}]
(let [page-class? (fn [t] (and (map? t) (contains? db-class/page-classes
(or (:db/ident t)
(when-let [id (:block/uuid t)]
(:db/ident (d/entity db [:block/uuid id])))))))
page-classes (filter page-class? tags)]
(-> block
(update :block/tags
(fn [tags] (->> (remove page-class? tags)
(remove nil?))))
(update :block/refs
(fn [refs] (->> (remove page-class? refs)
(remove nil?))))
(update :block/title (fn [title]
(reduce
(fn [title page-class]
(-> (string/replace title (str "#" (page-ref/->page-ref (:block/uuid page-class))) "")
string/trim))
title
page-classes))))))
(extend-type Entity
otree/INode
(-save [this *txs-state db repo _date-formatter {:keys [retract-attributes? retract-attributes outliner-op]
:or {retract-attributes? true}}]
(assert (ds/outliner-txs-state? *txs-state)
"db should be satisfied outliner-tx-state?")
(let [data this
db-based? (sqlite-util/db-based-graph? repo)
(let [db-based? (sqlite-util/db-based-graph? repo)
data (cond->> this
db-based?
(remove-inline-page-classes db))
data' (cond->
(if (de/entity? data)
(assoc (.-kv ^js data) :db/id (:db/id data))
@@ -536,12 +563,14 @@
(defn- build-insert-blocks-tx
[db target-block blocks uuids get-new-id {:keys [sibling? outliner-op replace-empty-target? insert-template? keep-block-order?]}]
(let [block-ids (set (map :block/uuid blocks))
(let [db-based? (entity-plus/db-based-graph? db)
block-ids (set (map :block/uuid blocks))
target-page (get-target-block-page target-block sibling?)
orders (get-block-orders blocks target-block sibling? keep-block-order?)]
(map-indexed (fn [idx {:block/keys [parent] :as block}]
(when-let [uuid' (get uuids (:block/uuid block))]
(let [top-level? (= (:block/level block) 1)
(let [block (if db-based? (remove-inline-page-classes db block) block)
top-level? (= (:block/level block) 1)
parent (compute-block-parent block parent target-block top-level? sibling? get-new-id outliner-op replace-empty-target? idx)
order (nth orders idx)

View File

@@ -152,7 +152,8 @@
(:added datom)
(= (:v datom) (:db/id tag)))
(let [t (d/entity db-after (:e datom))]
(when (not (:db/ident t)) ; new tag without db/ident
(when (and (not (ldb/inline-tag? (:block/raw-title t) tag))
(not (:db/ident t))) ; new tag without db/ident
(let [eid (:db/id t)]
[[:db/add eid :db/ident (db-class/create-user-class-ident-from-name db-after (:block/title t))]
[:db/add eid :logseq.property.class/extends :logseq.class/Root]
@@ -176,6 +177,39 @@
tx-data)
(apply concat)))))
(defn- remove-inline-page-class-from-title
"Remove inline page tag from title"
[block page-tag]
(-> (string/replace (:block/raw-title block) (str "#" (page-ref/->page-ref (:block/uuid page-tag))) "")
string/trim))
(defn- fix-inline-built-in-page-classes
[{:keys [db-after tx-data tx-meta]}]
(when-not (:rtc-op? tx-meta)
(let [classes (->> (remove #{:logseq.class/Page} db-class/page-classes)
(map #(d/entity db-after %)))
class-ids (set (map :db/id classes))]
(->>
(keep
(fn [datom]
(when (and (= :block/tags (:a datom))
(:added datom)
(contains? class-ids (:v datom)))
(let [id (:e datom)
entity (d/entity db-after id)
title (or (:block/raw-title entity) (:block/title entity))
page-tag (d/entity db-after (:v datom))]
(when (and title
(string/includes? title "#[[")
(ldb/inline-tag? title page-tag))
(let [title (remove-inline-page-class-from-title entity page-tag)]
[{:db/id id
:block/title title}
[:db/retract id :block/tags (:v datom)]
[:db/retract id :block/tags :logseq.class/Page]])))))
tx-data)
(apply concat)))))
(defn- toggle-page-and-block
[conn {:keys [db-before db-after tx-data tx-meta]}]
(when-not (:rtc-op? tx-meta)
@@ -206,8 +240,7 @@
(let [block (d/entity db-after (:e datom))
block-parent (:block/parent block)
;; remove inline #Page from title
page-title (-> (string/replace (:block/raw-title block) (str "#" (page-ref/->page-ref (:block/uuid page-tag))) "")
string/trim)
page-title (remove-inline-page-class-from-title block page-tag)
->page-tx (concat
[{:db/id id
:block/name (common-util/page-name-sanity-lc page-title)
@@ -335,7 +368,9 @@
[repo conn tx-report]
(let [{:keys [db-before db-after tx-data tx-meta]} tx-report
fix-page-tags-tx-data (fix-page-tags tx-report)
toggle-page-and-block-tx-data (toggle-page-and-block conn tx-report)
fix-inline-page-tx-data (fix-inline-built-in-page-classes tx-report)
toggle-page-and-block-tx-data (when (empty? fix-inline-page-tx-data)
(toggle-page-and-block conn tx-report))
display-blocks-tx-data (add-missing-properties-to-typed-display-blocks db-after tx-data)
commands-tx (when-not (or (:undo? tx-meta) (:redo? tx-meta) (:rtc-tx? tx-meta))
(commands/run-commands conn tx-report))
@@ -347,7 +382,8 @@
commands-tx
insert-templates-tx
created-by-tx
fix-page-tags-tx-data)))
fix-page-tags-tx-data
fix-inline-page-tx-data)))
(defn- undo-tx-data-if-disallowed!
[conn {:keys [tx-data]}]

View File

@@ -12,7 +12,9 @@
[frontend.test.fixtures :as fixtures]
[frontend.test.helper :as test-helper :refer [load-test-files]]
[frontend.worker.db-listener :as worker-db-listener]
[logseq.common.util :as common-util]
[logseq.db :as ldb]
[logseq.db.frontend.class :as db-class]
[logseq.db.test.helper :as db-test]
[logseq.graph-parser.block :as gp-block]
[logseq.outliner.core :as outliner-core]
@@ -537,6 +539,45 @@
(is (= [:logseq.class/Tag] (map :db/ident (:block/tags audio-tag)))
"#audio has wrong tags")))
(deftest do-not-save-inline-page-tag-when-save-block
(testing "Inline page class shouldn't be saved when save block"
(let [conn (db-test/create-conn-with-blocks
[{:page {:block/title "page1"} :blocks [{:block/title "test"}]}])
block (db-test/find-block-by-content @conn "test")
block' (d/entity @conn (:db/id block))]
(doseq [class-ident db-class/page-classes]
(let [class (d/entity @conn class-ident)]
(outliner-core/save-block! "logseq_db_test" conn
"MMM do, yyyy"
{:block/uuid (:block/uuid block)
:block/tags [(select-keys class [:block/name :block/title :block/uuid :db/ident])],
:block/title (common-util/format "test #[[%s]]" (str (:block/uuid class))),
:db/id (:db/id block)})
(is (= "test" (:block/title block')))
(is (empty? (:block/tags block'))))))))
(deftest do-not-save-inline-page-tag-when-insert-blocks
(testing "Inline page class shouldn't be saved when insert blocks"
(let [conn (db-test/create-conn-with-blocks
[{:page {:block/title "page1"} :blocks [{:block/title "test"}]}])
block (db-test/find-block-by-content @conn "test")]
(doseq [class-ident db-class/page-classes]
(let [class (d/entity @conn class-ident)
new-block-id (random-uuid)
_ (outliner-tx/transact!
(transact-opts)
(outliner-core/insert-blocks! "logseq_db_test" conn
[{:block/uuid new-block-id
:block/tags [(select-keys class [:block/name :block/title :block/uuid :db/ident])],
:block/title (common-util/format "test #[[%s]]" (str (:block/uuid class))),
:block/page (:db/id (:block/page block))}]
block
{:sibling? false
:keep-uuid? true}))
block' (d/entity @conn [:block/uuid new-block-id])]
(is (= "test" (:block/title block')))
(is (empty? (:block/tags block'))))))))
(deftest save-test
(load-test-files [{:file/path "pages/page1.md"
:file/content "alias:: foo, bar