From 30a635702c25d0e9ea4cab361d61face626623c9 Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Tue, 10 Sep 2024 16:04:31 -0400 Subject: [PATCH] fix: validate duplicate object when typed all at once Fixes 2nd buggy case of logseq/db-test#66 where user types "hello #Task" all at once. Previous fix had only handled typing #Task after hello was already in the block --- src/main/frontend/handler/db_based/page.cljs | 39 ++++++++++++++++++++ src/main/frontend/handler/page.cljs | 32 ++-------------- src/test/frontend/test/helper.cljs | 4 +- 3 files changed, 44 insertions(+), 31 deletions(-) create mode 100644 src/main/frontend/handler/db_based/page.cljs diff --git a/src/main/frontend/handler/db_based/page.cljs b/src/main/frontend/handler/db_based/page.cljs new file mode 100644 index 000000000..460992694 --- /dev/null +++ b/src/main/frontend/handler/db_based/page.cljs @@ -0,0 +1,39 @@ +(ns frontend.handler.db-based.page + (:require [logseq.outliner.core :as outliner-core] + [frontend.db :as db] + [frontend.handler.editor :as editor-handler] + [frontend.handler.notification :as notification] + ;; ui-outliner-tx macro relying on this + #_:clj-kondo/ignore + [frontend.state :as state] + [frontend.modules.outliner.ui :as ui-outliner-tx] + [promesa.core :as p])) + +(defn- valid-tag? + "Returns a boolean indicating whether the new tag passes all valid checks. + When returning false, this fn also displays appropriate notifications to the user" + [repo block tag-entity] + (try + (outliner-core/validate-unique-by-name-tag-and-block-type + (db/get-db repo) + (:block/title block) + (update block :block/tags (fnil conj #{}) tag-entity)) + true + (catch :default e + (if (= :notification (:type (ex-data e))) + (let [payload (:payload (ex-data e))] + (notification/show! (:message payload) (:type payload)) + false) + (throw e))))) + +(defn add-tag [repo block-id tag-entity] + (ui-outliner-tx/transact! + {:outliner-op :save-block} + (p/do! + (editor-handler/save-current-block!) + ;; Check after save-current-block to get most up to date block content + (when (valid-tag? repo (db/entity repo [:block/uuid block-id]) tag-entity) + (let [tx-data [[:db/add [:block/uuid block-id] :block/tags (:db/id tag-entity)] + ;; TODO: Move this to outliner.core to consistently add refs for tags + [:db/add [:block/uuid block-id] :block/refs (:db/id tag-entity)]]] + (db/transact! repo tx-data {:outliner-op :save-block})))))) diff --git a/src/main/frontend/handler/page.cljs b/src/main/frontend/handler/page.cljs index 109e8d84a..094af7376 100644 --- a/src/main/frontend/handler/page.cljs +++ b/src/main/frontend/handler/page.cljs @@ -46,7 +46,7 @@ [frontend.handler.property.util :as pu] [datascript.impl.entity :as de] [logseq.db.frontend.class :as db-class] - [logseq.outliner.core :as outliner-core])) + [frontend.handler.db-based.page :as db-page-handler])) (def (editor-handler/get-nearest-page) string/trim)] (if (and add-tag-to-nearest-node? (not (string/blank? nearest-node))) (when-let [e (db/get-page nearest-node)] - (add-tag (state/get-current-repo) e tag-entity)) - (add-tag (state/get-current-repo) edit-block tag-entity)))))))) + (db-page-handler/add-tag (state/get-current-repo) (:block/uuid e) tag-entity)) + (db-page-handler/add-tag (state/get-current-repo) (:block/uuid edit-block) tag-entity)))))))) (when input (.focus input)))))) diff --git a/src/test/frontend/test/helper.cljs b/src/test/frontend/test/helper.cljs index af3bc7fac..b2a9f033c 100644 --- a/src/test/frontend/test/helper.cljs +++ b/src/test/frontend/test/helper.cljs @@ -7,7 +7,7 @@ [logseq.db.sqlite.util :as sqlite-util] [frontend.db :as db] [frontend.handler.editor :as editor-handler] - [frontend.handler.page :as page-handler] + [frontend.handler.db-based.page :as db-page-handler] [datascript.core :as d] [logseq.graph-parser.text :as text] [logseq.db.sqlite.create-graph :as sqlite-create-graph] @@ -236,7 +236,7 @@ This can be called in synchronous contexts as no async fns should be invoked" [repo block-uuid content {:keys [tags]}] (editor-handler/save-block! repo block-uuid content) (doseq [tag tags] - (page-handler/add-tag repo block-uuid (db/get-page tag)))) + (db-page-handler/add-tag repo block-uuid (db/get-page tag)))) (defn create-page! [title & {:as opts}]