mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 14:14:55 +00:00
fix: remove inline page tags when saving or inserting blocks
Page tags here means db-class/page-classes.
This commit is contained in:
37
deps/outliner/src/logseq/outliner/core.cljs
vendored
37
deps/outliner/src/logseq/outliner/core.cljs
vendored
@@ -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)
|
||||
|
||||
@@ -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]}]
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user