diff --git a/deps/outliner/src/logseq/outliner/core.cljs b/deps/outliner/src/logseq/outliner/core.cljs index 96633f4f48..863e8c374d 100644 --- a/deps/outliner/src/logseq/outliner/core.cljs +++ b/deps/outliner/src/logseq/outliner/core.cljs @@ -327,11 +327,6 @@ (:block/title m*) (not= (:block/title m*) (:block/title block-entity))) (outliner-validate/validate-block-title db (:block/title m*) block-entity)) - _ (when (and db-based? (seq (:block/tags m*))) - ;; Add built-in? b/c it's not available here - (doseq [tag (map #(assoc % :logseq.property/built-in? - (contains? sqlite-create-graph/built-in-pages-names (:block/title %))) (:block/tags m*))] - (outliner-validate/validate-built-in-pages tag {:message "Built-in page can't be a tag"}))) m (cond-> m* db-based? (dissoc :block/format :block/pre-block? :block/priority :block/marker :block/properties-order))] diff --git a/deps/outliner/src/logseq/outliner/validate.cljs b/deps/outliner/src/logseq/outliner/validate.cljs index 183868b6d3..63886bca29 100644 --- a/deps/outliner/src/logseq/outliner/validate.cljs +++ b/deps/outliner/src/logseq/outliner/validate.cljs @@ -39,15 +39,6 @@ (def ^:api uneditable-page? ldb/built-in?) -(defn ^:api validate-built-in-pages - "Validates built-in pages shouldn't be modified" - [entity & {:keys [message]}] - (when (uneditable-page? entity) - (throw (ex-info "Rename built-in pages" - {:type :notification - :payload {:message (or message "Built-in pages can't be edited") - :type :warning}})))) - (defn- find-other-ids-with-title-and-tags "Query that finds other ids given the id to ignore, title to look up and tags to consider" [entity] @@ -138,7 +129,6 @@ (defn validate-block-title "Validates a block title when it has changed for a entity-util/page? or tagged node" [db new-title existing-block-entity] - (validate-built-in-pages existing-block-entity) (validate-unique-by-name-and-tags db new-title existing-block-entity) (validate-disallow-page-with-journal-name new-title existing-block-entity)) diff --git a/src/main/frontend/components/editor.cljs b/src/main/frontend/components/editor.cljs index 22e68411e8..8467c4f325 100644 --- a/src/main/frontend/components/editor.cljs +++ b/src/main/frontend/components/editor.cljs @@ -161,11 +161,13 @@ result (if db-tag? (let [classes (editor-handler/get-matched-classes q)] (if (and (ldb/internal-page? block) - (= (:block/title block) q)) - (cons {:block/title (util/format "Convert \"%s\" to tag" q) + (= (:block/title block) q) + (not (ldb/built-in? block))) + (cons {:block/title q :db/id (:db/id block) :block/uuid (:block/uuid block) - :convert-page-to-tag? true} classes) + :convert-page-to-tag? true + :friendly-title (util/format "Convert \"%s\" to tag" q)} classes) classes)) (editor-handler/> add-created-by-tx-data (nil? created-by-ent) (cons created-by-block)))))) +(defn- revert-disallowed-changes + [{:keys [tx-meta tx-data db-before db-after]}] + (when-not (rtc-tx-or-download-graph? tx-meta) + (let [built-in-page? (fn [id] + (let [block (d/entity db-after id)] + (and (contains? sqlite-create-graph/built-in-pages-names + (:block/title block)) + (ldb/built-in? block)))) + tx-data' (mapcat + (fn [[e a v _t added]] + (when added + (cond + ;; using built-in pages as tags + (and (= a :block/tags) (built-in-page? v)) + [[:db/retract v :db/ident] + [:db/retract v :logseq.property.class/extends] + [:db/retract v :block/tags :logseq.class/Tag] + [:db/add v :block/tags :logseq.class/Page] + [:db/retract e a v]] + + ;; built-in block protected properties updated + (and (contains? #{:db/ident :block/title :block/name :logseq.property/type + :logseq.property/built-in? :logseq.property.class/extends} a) + (some? (d/entity db-before e)) + (let [block (d/entity db-after e)] + (and (ldb/built-in? block) + (not= (get block a) (get (d/entity db-before e) a))))) + (if-some [prev-v (get (d/entity db-before e) a)] + [[:db/add e a prev-v]] + [[:db/retract e a v]]) + + :else + nil))) + tx-data)] + (when (seq tx-data') + (prn :debug ::revert-built-in-block-updates :tx-data (distinct tx-data'))) + (distinct tx-data')))) + (defn- compute-extra-tx-data [repo tx-report] (let [{:keys [db-before db-after tx-data tx-meta]} tx-report db db-after + revert-tx-data (revert-disallowed-changes tx-report) fix-page-tags-tx-data (fix-page-tags 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) @@ -337,7 +378,8 @@ insert-templates-tx (when-not (rtc-tx-or-download-graph? tx-meta) (insert-tag-templates repo tx-report)) created-by-tx (add-created-by-ref-hook db-before db-after tx-data tx-meta)] - (concat toggle-page-and-block-tx-data + (concat revert-tx-data + toggle-page-and-block-tx-data display-blocks-tx-data commands-tx insert-templates-tx diff --git a/src/test/frontend/worker/pipeline_test.cljs b/src/test/frontend/worker/pipeline_test.cljs index 76456d8d04..e20b1b52f9 100644 --- a/src/test/frontend/worker/pipeline_test.cljs +++ b/src/test/frontend/worker/pipeline_test.cljs @@ -1,6 +1,10 @@ (ns frontend.worker.pipeline-test (:require [cljs.test :refer [deftest is testing]] - [frontend.worker.pipeline :as worker-pipeline])) + [datascript.core :as d] + [frontend.test.helper :as test-helper] + [frontend.worker.pipeline :as worker-pipeline] + [logseq.db :as ldb] + [logseq.db.test.helper :as db-test])) (deftest remove-conflict-datoms-test (testing "remove-conflict-datoms (1)" @@ -36,3 +40,40 @@ [177 :block/refs 136 536871082 true] [177 :block/refs 21 536871082 true]]) (set (#'worker-pipeline/remove-conflict-datoms datoms))))))) + +(deftest test-built-in-page-updates-that-should-be-reverted + (let [graph test-helper/test-db-name-db-version + conn (db-test/create-conn-with-blocks + [{:page {:block/title "page1"} + :blocks [{:block/title "b1"}]}]) + library (ldb/get-built-in-page @conn "Library")] + + (ldb/register-transact-pipeline-fn! + (fn [tx-report] + (worker-pipeline/transact-pipeline graph tx-report))) + + (testing "Using built-in pages as tags" + (let [page-1 (ldb/get-page @conn "page1") + b1 (first (:block/_page page-1))] + (ldb/transact! conn [{:db/id (:db/id b1) + :block/title "b1 #Library" + :block/tags [library]}]) + + (is (not (ldb/class? library))) + (is (empty? (:block/tags (d/entity @conn (:db/id b1))))))) + + (testing "Updating protected properties for built-in nodes" + (ldb/transact! conn [{:db/id (:db/id library) + :block/title "newlibrary" + :db/ident :test/ident}]) + (let [library (ldb/get-built-in-page @conn "Library")] + (is (nil? (:db/ident library))) + (is (= "Library" (:block/title library)))) + + (let [task (d/entity @conn :logseq.class/Task)] + (ldb/transact! conn [{:db/id (:db/id task) + :db/ident :logseq.class/task-new-ident + :block/title "task"}]) + (let [task (d/entity @conn (:db/id task))] + (is (= :logseq.class/Task (:db/ident task))) + (is (= "Task" (:block/title task))))))))