diff --git a/src/main/frontend/handler/block.cljs b/src/main/frontend/handler/block.cljs index 31ab472974..6954781e6b 100644 --- a/src/main/frontend/handler/block.cljs +++ b/src/main/frontend/handler/block.cljs @@ -1,5 +1,6 @@ (ns ^:no-doc frontend.handler.block (:require [clojure.string :as string] + [datascript.core :as d] [datascript.impl.entity :as de] [dommy.core :as dom] [frontend.config :as config] @@ -77,6 +78,21 @@ (or "") (subs 0 pos)))) +(defn- class-title-conflicts? + [class-entity] + (let [class-title (:block/title class-entity) + class-id (:db/id class-entity)] + (when-let [db (and class-title (db/get-db))] + (boolean + (d/q '[:find ?other . + :in $ ?class-title ?class-id + :where + [?other :block/title ?class-title] + [?other :block/tags :logseq.class/Tag] + [(not= ?other ?class-id)] + (not [?other :logseq.property/deleted-at])] + db class-title class-id))))) + (defn mark-last-input-time! [repo] (when repo @@ -104,18 +120,25 @@ (let [block-e (cond (de/entity? block) block + + (number? (:db/id block)) + (or (db/entity (:db/id block)) block) + (uuid? (:block/uuid block)) (db/entity [:block/uuid (:block/uuid block)]) + :else block) - class? (ldb/class? block) + class? (ldb/class? block-e) tags (when (and with-tags? (not class?)) (remove (fn [t] (or (some-> (:block/raw-title block-e) (ldb/inline-tag? t)) (ldb/private-tags (:db/ident t)))) (map (fn [tag] (if (number? tag) (db/entity tag) tag)) (:block/tags block)))) base-title (if class? - (ldb/get-class-title-with-extends block) + (if (class-title-conflicts? block-e) + (ldb/get-class-title-with-extends block-e) + (:block/title block-e)) (:block/title block)) trunc-title (if (and truncate? base-title (> (count base-title) 256)) (subs base-title 0 256) diff --git a/src/test/frontend/handler/block_test.cljs b/src/test/frontend/handler/block_test.cljs index b344491fce..97fb180944 100644 --- a/src/test/frontend/handler/block_test.cljs +++ b/src/test/frontend/handler/block_test.cljs @@ -1,7 +1,10 @@ (ns frontend.handler.block-test (:require [cljs.test :refer [deftest is testing]] [clojure.string :as string] - [frontend.handler.block :as block-handler])) + [datascript.core :as d] + [frontend.db :as db] + [frontend.handler.block :as block-handler] + [logseq.db.test.helper :as db-test])) (deftest block-unique-title-no-truncate-when-disabled (testing "disable truncate for cmdk path" @@ -21,3 +24,42 @@ (is (string/starts-with? result base-title)) (is (string/ends-with? result "#example")) (is (> (count result) 256))))) + +(deftest block-unique-title-hides-class-parent-when-title-is-unique + (let [conn (db-test/create-conn-with-blocks + {:classes {:Project {:block/title "Project"} + :Milestone {:block/title "Milestone" + :build/class-extends [:Project]}}}) + milestone (d/entity @conn :user.class/Milestone)] + (with-redefs [db/get-db (fn [] @conn)] + (is (= "Milestone" (block-handler/block-unique-title milestone)))))) + +(deftest block-unique-title-shows-class-parent-when-title-conflicts + (let [conn (db-test/create-conn-with-blocks + {:classes {:Project {:block/title "Project"} + :Area {:block/title "Area"} + :user.class/Milestone {:block/title "Milestone" + :build/class-extends [:Project]} + :other.class/Milestone {:block/title "Milestone" + :build/class-extends [:Area]}}}) + project-milestone (d/entity @conn :user.class/Milestone) + area-milestone (d/entity @conn :other.class/Milestone)] + (with-redefs [db/get-db (fn [] @conn)] + (is (= "Project/Milestone" (block-handler/block-unique-title project-milestone))) + (is (= "Area/Milestone" (block-handler/block-unique-title area-milestone)))))) + +(deftest block-unique-title-resolves-plain-class-map-before-title-formatting + (let [conn (db-test/create-conn-with-blocks + {:classes {:Project {:block/title "Project"} + :Area {:block/title "Area"} + :user.class/Milestone {:block/title "Milestone" + :build/class-extends [:Project]} + :other.class/Milestone {:block/title "Milestone" + :build/class-extends [:Area]}}}) + project-milestone (d/entity @conn :user.class/Milestone) + plain-class-map {:db/id (:db/id project-milestone) + :block/title (:block/title project-milestone) + :block/tags [(d/entid @conn :logseq.class/Tag)]}] + (with-redefs [db/get-db (fn [] @conn) + db/entity (fn [eid] (d/entity @conn eid))] + (is (= "Project/Milestone" (block-handler/block-unique-title plain-class-map))))))