mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 14:14:55 +00:00
fix: revert disallowed built-in block updates
1. built-in pages (non-classes) shouldn't be used as tags 2. some protected properties for built-in nodes shouldn't be updated, e.g. db/ident, block/title, block/name, logseq.property/type
This commit is contained in:
5
deps/outliner/src/logseq/outliner/core.cljs
vendored
5
deps/outliner/src/logseq/outliner/core.cljs
vendored
@@ -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))]
|
||||
|
||||
10
deps/outliner/src/logseq/outliner/validate.cljs
vendored
10
deps/outliner/src/logseq/outliner/validate.cljs
vendored
@@ -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))
|
||||
|
||||
|
||||
@@ -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/<get-matched-blocks q {:nlp-pages? true
|
||||
:page-only? (not db-based?)}))]
|
||||
@@ -203,7 +205,7 @@
|
||||
(let [block' (if-let [id (:block/uuid block)]
|
||||
(if-let [e (db/entity [:block/uuid id])]
|
||||
(assoc e
|
||||
:block/title (or (:block/title e) (:block/title block))
|
||||
:block/title (or (:friendly-title block) (:block/title e) (:block/title block))
|
||||
:alias (:alias block))
|
||||
block)
|
||||
block)]
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
(:block/parent page-entity)
|
||||
(notification/show! "Namespaced pages can't be tags" :error false)
|
||||
(outliner-validate/uneditable-page? page-entity)
|
||||
(notification/show! "Built-in pages can't be edited" :error)
|
||||
(notification/show! "Built-in pages can't be used as tags" :error)
|
||||
:else
|
||||
(let [txs [(db-class/build-new-class (db/get-db)
|
||||
{:db/id (:db/id page-entity)
|
||||
@@ -65,7 +65,7 @@
|
||||
(cond (db/page-exists? (:block/title entity) #{:logseq.class/Page})
|
||||
(notification/show! (str "A page with the name \"" (:block/title entity) "\" already exists.") :warning false)
|
||||
(outliner-validate/uneditable-page? entity)
|
||||
(notification/show! "Built-in tags can't be edited" :error)
|
||||
(notification/show! "Built-in tags can't be converted to pages" :error)
|
||||
:else
|
||||
(if (seq (:logseq.property.class/_extends entity))
|
||||
(notification/show! "This tag cannot be converted because it has tag children. All tag children must be removed or converted before converting this tag." :error false)
|
||||
|
||||
@@ -3630,13 +3630,10 @@
|
||||
(save-current-block!) ;; Save the input contents before collapsing
|
||||
(ui-outliner-tx/transact! ;; Save the new collapsed state as an undo transaction (if it changed)
|
||||
{:outliner-op :collapse-expand-blocks}
|
||||
(doseq [block-id block-ids]
|
||||
(when-let [block (db/entity [:block/uuid block-id])]
|
||||
(let [current-value (boolean (:block/collapsed? block))]
|
||||
(when-not (= current-value value)
|
||||
(let [block {:block/uuid block-id
|
||||
:block/collapsed? value}]
|
||||
(outliner-save-block! block {:outliner-op :collapse-expand-blocks})))))))
|
||||
(let [tx-data (map (fn [block-id]
|
||||
{:block/uuid block-id
|
||||
:block/collapsed? value}) block-ids)]
|
||||
(outliner-op/transact! tx-data {})))
|
||||
(doseq [block-id block-ids]
|
||||
(state/set-collapsed-block! block-id value)))))
|
||||
|
||||
|
||||
@@ -510,8 +510,6 @@
|
||||
|
||||
r (d/transact! conn data' {:fix-db? true
|
||||
:db-migrate? true})]
|
||||
(when (seq (:tx-data r))
|
||||
(prn :debug :ensure-built-in-data-exists? :tx-data (:tx-data r)))
|
||||
(assoc r :migrate-updates
|
||||
;; fake it as a normal :fix type migration
|
||||
{:fix (constantly :ensure-built-in-data-exists!)})))
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
[logseq.db.common.order :as db-order]
|
||||
[logseq.db.common.sqlite :as common-sqlite]
|
||||
[logseq.db.frontend.class :as db-class]
|
||||
[logseq.db.sqlite.create-graph :as sqlite-create-graph]
|
||||
[logseq.db.sqlite.export :as sqlite-export]
|
||||
[logseq.graph-parser.exporter :as gp-exporter]
|
||||
[logseq.outliner.core :as outliner-core]
|
||||
@@ -86,6 +87,7 @@
|
||||
(:block/uuid e)))))))]
|
||||
blocks))))]
|
||||
(when (seq template-blocks)
|
||||
;; FIXME: outliner core apis shouldn't use `repo`
|
||||
(let [result (outliner-core/insert-blocks
|
||||
repo db template-blocks object
|
||||
{:sibling? false
|
||||
@@ -323,10 +325,49 @@
|
||||
(cond->> 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
|
||||
|
||||
@@ -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))))))))
|
||||
|
||||
Reference in New Issue
Block a user