Kaynağa Gözat

Merge branch 'master' into feat/capacitor-new

charlie 4 ay önce
ebeveyn
işleme
b6e3e98990
49 değiştirilmiş dosya ile 569 ekleme ve 434 silme
  1. 2 2
      .github/workflows/build.yml
  2. 1 0
      clj-e2e/deps.edn
  3. 78 6
      clj-e2e/test/logseq/e2e/plugins_basic_test.clj
  4. 11 5
      deps/db/script/diff_graphs.cljs
  5. 10 4
      deps/db/script/export_graph.cljs
  6. 18 10
      deps/db/src/logseq/db.cljs
  7. 16 43
      deps/db/src/logseq/db/common/initial_data.cljs
  8. 26 22
      deps/db/src/logseq/db/frontend/db_ident.cljc
  9. 28 12
      deps/db/src/logseq/db/sqlite/build.cljs
  10. 10 5
      deps/db/src/logseq/db/sqlite/export.cljs
  11. 14 2
      deps/db/test/logseq/db/sqlite/build_test.cljs
  12. 1 1
      deps/graph-parser/src/logseq/graph_parser/exporter.cljs
  13. 6 10
      deps/outliner/src/logseq/outliner/core.cljs
  14. 16 0
      deps/outliner/test/logseq/outliner/core_test.cljs
  15. 4 4
      libs/src/LSPlugin.ts
  16. 9 41
      scripts/src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs
  17. 2 2
      src/main/frontend/components/library.cljs
  18. 1 1
      src/main/frontend/components/views.cljs
  19. 1 1
      src/main/frontend/db.cljs
  20. 0 9
      src/main/frontend/db/model.cljs
  21. 9 1
      src/main/frontend/worker/db/migrate.cljs
  22. 72 32
      src/main/frontend/worker/db/validate.cljs
  23. 12 6
      src/main/frontend/worker/export.cljs
  24. 108 106
      src/main/logseq/api.cljs
  25. 111 64
      src/main/logseq/api/block.cljs
  26. 1 0
      src/main/logseq/sdk/utils.cljs
  27. 0 1
      src/resources/dicts/af.edn
  28. 0 2
      src/resources/dicts/ca.edn
  29. 0 2
      src/resources/dicts/cs.edn
  30. 0 2
      src/resources/dicts/de.edn
  31. 2 2
      src/resources/dicts/en.edn
  32. 0 2
      src/resources/dicts/es.edn
  33. 0 2
      src/resources/dicts/fa.edn
  34. 0 2
      src/resources/dicts/fr.edn
  35. 0 2
      src/resources/dicts/id.edn
  36. 0 2
      src/resources/dicts/it.edn
  37. 0 2
      src/resources/dicts/ja.edn
  38. 0 2
      src/resources/dicts/ko.edn
  39. 0 2
      src/resources/dicts/nb-no.edn
  40. 0 2
      src/resources/dicts/nl.edn
  41. 0 2
      src/resources/dicts/pl.edn
  42. 0 2
      src/resources/dicts/pt-br.edn
  43. 0 2
      src/resources/dicts/pt-pt.edn
  44. 0 2
      src/resources/dicts/ru.edn
  45. 0 2
      src/resources/dicts/sk.edn
  46. 0 2
      src/resources/dicts/tr.edn
  47. 0 2
      src/resources/dicts/uk.edn
  48. 0 2
      src/resources/dicts/zh-cn.edn
  49. 0 2
      src/resources/dicts/zh-hant.edn

+ 2 - 2
.github/workflows/build.yml

@@ -178,10 +178,10 @@ jobs:
         run: cd deps/db && yarn nbb-logseq script/validate_db.cljs ../../scripts/properties-graph ../../scripts/schema-graph --closed-maps --group-errors
 
       - name: Export a created DB graph
-        run: cd deps/db && yarn nbb-logseq script/export_graph.cljs ../../scripts/properties-graph -f properties.edn -t
+        run: cd deps/db && yarn nbb-logseq script/export_graph.cljs ../../scripts/properties-graph -f properties.edn -T
 
       - name: Create graph from the export and diff the two graphs
-        run: cd deps/db && yarn nbb-logseq -cp src:../outliner/src:script script/create_graph.cljs ./properties-graph2 properties.edn -iv && yarn nbb-logseq script/diff_graphs.cljs ../../scripts/properties-graph ./properties-graph2 -t
+        run: cd deps/db && yarn nbb-logseq -cp src:../outliner/src:script script/create_graph.cljs ./properties-graph2 properties.edn -iv && yarn nbb-logseq script/diff_graphs.cljs ../../scripts/properties-graph ./properties-graph2 -T
 
   e2e-test:
     # TODO: Re-enable when ready to enable tests for file graphs

+ 1 - 0
clj-e2e/deps.edn

@@ -5,6 +5,7 @@
                                     :sha "8571fae7c51400ac61c8b1026cbfba68279bc461"}
         ;; io.github.zmedelis/bosquet {:mvn/version "2025.03.28"}
         org.clj-commons/claypoole          {:mvn/version "1.2.2"}
+        metosin/jsonista                   {:mvn/version "0.3.13"}
         clj-time/clj-time                  {:mvn/version "0.15.2"}}
  :aliases
  {:build {:deps {io.github.clojure/tools.build {:mvn/version "0.10.5"}}

+ 78 - 6
clj-e2e/test/logseq/e2e/plugins_basic_test.clj

@@ -2,7 +2,12 @@
   (:require
    [clojure.string :as string]
    [clojure.test :refer [deftest testing is use-fixtures]]
+   [jsonista.core :as json]
+   [logseq.e2e.assert :as assert]
    [logseq.e2e.fixtures :as fixtures]
+   [logseq.e2e.keyboard :as k]
+   [logseq.e2e.page :as page]
+   [logseq.e2e.util :as util]
    [wally.main :as w]
    [wally.repl :as repl]))
 
@@ -34,12 +39,79 @@
   (let [tag (name tag)
         ns' (string/split tag #"\.")
         ns? (and (seq ns') (= (count ns') 2))
-        ns1 (string/lower-case (if ns? (str "sdk." (first ns')) "api"))
-        name1 (if ns? (to-snake-case (last ns')) tag)]
-    (w/eval-js
-      (format "args => { const o=logseq.%1$s; return o['%2$s']?.apply(null, args || []); }" ns1 name1)
-      (vec args))))
+        inbuilt? (contains? #{"app" "editor"} (first ns'))
+        ns1 (string/lower-case (if (and ns? (not inbuilt?))
+                                 (str "sdk." (first ns')) "api"))
+        name1 (if ns? (to-snake-case (last ns')) tag)
+        estr (format "s => { const args = JSON.parse(s);const o=logseq.%1$s; return o['%2$s']?.apply(null, args || []); }" ns1 name1)]
+    (let [args (json/write-value-as-string (vec args))]
+      ;(prn "Debug: eval-js #" estr args)
+      (w/eval-js estr args))))
+
+(defn- assert-api-ls-block!
+  ([ret] (assert-api-ls-block! ret 1))
+  ([ret-or-uuid count]
+   (let [uuid' (or (get ret-or-uuid "uuid") ret-or-uuid)]
+     (is (string? uuid'))
+     (assert/assert-have-count (str "#ls-block-" uuid') count)
+     uuid')))
 
 (deftest apis-related-test
   (testing "block related apis"
-    (ls-api-call! :ui.showMsg "hello world" "error")))
+    (page/new-page "test-block-apis")
+    (ls-api-call! :ui.showMsg "hello world" "info")
+    (let [ret (ls-api-call! :editor.appendBlockInPage "test-block-apis" "append-block-in-page-0")
+          uuid' (assert-api-ls-block! ret)]
+      (-> (ls-api-call! :editor.insertBlock uuid' "insert-0")
+        (assert-api-ls-block!))
+      (ls-api-call! :editor.updateBlock uuid' "append-but-updated-0")
+      (k/esc)
+      (w/wait-for ".block-title-wrap:text('append-but-updated-0')")
+      (ls-api-call! :editor.removeBlock uuid')
+      (assert-api-ls-block! uuid' 0)))
+
+  (testing "block properties related apis"
+    (page/new-page "test-block-properties-apis")
+    (let [ret (ls-api-call! :editor.appendBlockInPage "test-block-properties-apis" "block-in-page-0" {:properties {:p1 1}})
+          uuid' (assert-api-ls-block! ret)
+          prop1 (ls-api-call! :editor.getBlockProperty uuid' "p1")
+          props1 (ls-api-call! :editor.getBlockProperties uuid' "p1")]
+      (w/wait-for ".property-k:text('p1')")
+      (is (= 1 (get prop1 "value")))
+      (is (= (get prop1 "ident") ":plugin.property._api/p1"))
+      (is (= 1 (get props1 ":plugin.property._api/p1")))
+      (ls-api-call! :editor.upsertBlockProperty uuid' "p2" "p2")
+      (ls-api-call! :editor.upsertBlockProperty uuid' "p3" true)
+      (ls-api-call! :editor.upsertBlockProperty uuid' "p4" {:a 1, :b [2, 3]})
+      (let [prop2 (ls-api-call! :editor.getBlockProperty uuid' "p2")
+            prop3 (ls-api-call! :editor.getBlockProperty uuid' "p3")
+            prop4 (ls-api-call! :editor.getBlockProperty uuid' "p4")]
+        (w/wait-for ".property-k:text('p2')")
+        (is (= "p2" (get prop2 "value")))
+        (is (true? prop3))
+        (is (= prop4 {"a" 1, "b" [2 3]})))
+      (ls-api-call! :editor.removeBlockProperty uuid' "p4")
+      ;; wait for react re-render
+      (util/wait-timeout 16)
+      (is (nil? (w/find-one-by-text ".property-k" "p4")))
+      (ls-api-call! :editor.upsertBlockProperty uuid' "p3" false)
+      (ls-api-call! :editor.upsertBlockProperty uuid' "p2" "p2-updated")
+      (w/wait-for ".block-title-wrap:text('p2-updated')")
+      (let [props (ls-api-call! :editor.getBlockProperties uuid')]
+        (is (= (get props ":plugin.property._api/p3") false))
+        (is (= (get props ":plugin.property._api/p2") "p2-updated")))))
+
+  (testing "properties management related apis"
+    (let [_ (ls-api-call! :editor.upsertProperty "o1")
+          _ (ls-api-call! :editor.upsertProperty "o2" {:type "number"})
+          _ (ls-api-call! :editor.upsertProperty "user.property/o3" {:type "node"})
+          prop1 (ls-api-call! :editor.getProperty "o1")
+          prop2 (ls-api-call! :editor.getProperty "o2")
+          prop3 (ls-api-call! :editor.getProperty "user.property/o3")]
+      (is (= (get prop1 "ident") ":plugin.property._api/o1"))
+      (is (= (get prop1 "type") "default"))
+      (is (= (get prop2 "type") "number"))
+      (is (= (get prop3 "ident") ":user.property/o3"))
+      (is (= (get prop3 "type") "node"))
+      (ls-api-call! :editor.removeProperty "o2")
+      (is (nil? (w/find-one-by-text ".property-k" "o2"))))))

+ 11 - 5
deps/db/script/diff_graphs.cljs

@@ -19,8 +19,12 @@
                              :desc "Exclude built-in pages"}
    :set-diff {:alias :s
               :desc "Use set to reduce noisy diff caused by ordering"}
-   :include-timestamps? {:alias :t
-                         :desc "Include timestamps in export"}})
+   :include-timestamps? {:alias :T
+                         :desc "Include timestamps in export"}
+   :export-type {:alias :t
+                 :coerce :keyword
+                 :desc "Export type"
+                 :default :graph}})
 
 (defn -main [args]
   (let [{options :opts args' :args} (cli/parse-args args {:spec spec})
@@ -31,9 +35,11 @@
             (js/process.exit 1))
         conn (apply sqlite-cli/open-db! (sqlite-cli/->open-db-args graph-dir))
         conn2 (apply sqlite-cli/open-db! (sqlite-cli/->open-db-args graph-dir2))
-        export-options (select-keys options [:include-timestamps? :exclude-namespaces :exclude-built-in-pages?])
-        export-map (sqlite-export/build-export @conn {:export-type :graph :graph-options export-options})
-        export-map2 (sqlite-export/build-export @conn2 {:export-type :graph :graph-options export-options})
+        export-args (cond-> {:export-type (:export-type options)}
+                      (= :graph (:export-type options))
+                      (assoc :graph-options (select-keys options [:include-timestamps? :exclude-namespaces :exclude-built-in-pages?])))
+        export-map (sqlite-export/build-export @conn export-args)
+        export-map2 (sqlite-export/build-export @conn2 export-args)
         prepare-export-to-diff
         (fn [m]
           (cond->

+ 10 - 4
deps/db/script/export_graph.cljs

@@ -19,7 +19,7 @@
   "Options spec"
   {:help {:alias :h
           :desc "Print help"}
-   :include-timestamps? {:alias :t
+   :include-timestamps? {:alias :T
                          :desc "Include timestamps in export"}
    :file {:alias :f
           :desc "Saves edn to file"}
@@ -31,7 +31,11 @@
    :exclude-built-in-pages? {:alias :b
                              :desc "Exclude built-in pages"}
    :exclude-files? {:alias :F
-                    :desc "Exclude :file/path files"}})
+                    :desc "Exclude :file/path files"}
+   :export-type {:alias :t
+                 :coerce :keyword
+                 :desc "Export type"
+                 :default :graph}})
 
 (defn -main [args]
   (let [{options :opts args' :args} (cli/parse-args args {:spec spec})
@@ -41,8 +45,10 @@
                           (cli/format-opts {:spec spec})))
             (js/process.exit 1))
         conn (apply sqlite-cli/open-db! (sqlite-cli/->open-db-args graph-dir))
-        export-options (dissoc options :file)
-        export-map (sqlite-export/build-export @conn {:export-type :graph :graph-options export-options})]
+        export-map (sqlite-export/build-export @conn
+                                               (cond-> {:export-type (:export-type options)}
+                                                 (= :graph (:export-type options))
+                                                 (assoc :graph-options (dissoc options :file :export-type))))]
     (if (:file options)
       (do
         (println "Exported" (count (:properties export-map)) "properties,"

+ 18 - 10
deps/db/src/logseq/db.cljs

@@ -41,15 +41,23 @@
   (let [remove-block-temp-f (fn [m]
                               (->> (remove (fn [[k _v]] (= "block.temp" (namespace k))) m)
                                    (into {})))]
-    (map (fn [m]
-           (if (map? m)
-             (cond->
-              (remove-block-temp-f m)
-               (and (seq (:block/refs m))
-                    (every? map? (:block/refs m)))
-               (update :block/refs (fn [refs] (map remove-block-temp-f refs))))
-             m))
-         tx-data)))
+    (keep (fn [data]
+            (cond
+              (map? data)
+              (cond->
+               (remove-block-temp-f data)
+                (and (seq (:block/refs data))
+                     (every? map? (:block/refs data)))
+                (update :block/refs (fn [refs] (map remove-block-temp-f refs))))
+              (and (vector? data)
+                   (contains? #{:db/add :db/retract} (first data))
+                   (> (count data) 2)
+                   (keyword? (nth data 2))
+                   (= "block.temp" (namespace (nth data 2))))
+              nil
+              :else
+              data))
+          tx-data)))
 
 (defn assert-no-entities
   [tx-data]
@@ -372,7 +380,7 @@
         parents'))))
 
 (def get-block-children-ids common-initial-data/get-block-children-ids)
-(def get-block-children common-initial-data/get-block-children)
+(def get-block-full-children-ids common-initial-data/get-block-full-children-ids)
 
 (defn- get-sorted-page-block-ids
   [db page-id]

+ 16 - 43
deps/db/src/logseq/db/common/initial_data.cljs

@@ -86,48 +86,8 @@
       (update block :block/link (fn [link] (d/pull db '[*] (:db/id link))))
       block)))
 
-(comment
-  (defn- property-without-db-attrs
-    [property]
-    (dissoc property :db/index :db/valueType :db/cardinality))
-
-  (defn- property-with-values
-    [db block properties]
-    (when (entity-plus/db-based-graph? db)
-      (let [block (d/entity db (:db/id block))
-            property-vals (if properties
-                            (map block properties)
-                            (vals (:block/properties block)))]
-        (->> property-vals
-             (mapcat
-              (fn [property-values]
-                (let [values (->>
-                              (if (and (coll? property-values)
-                                       (map? (first property-values)))
-                                property-values
-                                #{property-values}))
-                      value-ids (when (every? map? values)
-                                  (->> (map :db/id values)
-                                       (filter (fn [id] (or (int? id) (keyword? id))))))
-                      value-blocks (->>
-                                    (when (seq value-ids)
-                                      (map
-                                       (fn [id] (d/pull db '[:db/id :block/uuid
-                                                             :block/name :block/title
-                                                             :logseq.property/value
-                                                             :block/tags :block/page
-                                                             :logseq.property/created-from-property] id))
-                                       value-ids))
-                                  ;; FIXME: why d/pull returns {:db/id db-ident} instead of {:db/id number-eid}?
-                                    (keep (fn [block]
-                                            (let [from-property-id (get-in block [:logseq.property/created-from-property :db/id])]
-                                              (if (keyword? from-property-id)
-                                                (assoc-in block [:logseq.property/created-from-property :db/id] (:db/id (d/entity db from-property-id)))
-                                                block)))))]
-                  value-blocks))))))))
-
 (defn get-block-children-ids
-  "Returns children UUIDs"
+  "Returns children UUIDs, notice the result doesn't include property value children ids."
   [db block-uuid & {:keys [include-collapsed-children?]
                     :or {include-collapsed-children? true}}]
   (when-let [eid (:db/id (d/entity db [:block/uuid block-uuid]))]
@@ -140,7 +100,6 @@
                             (when (or include-collapsed-children?
                                       (not (:block/collapsed? e))
                                       (common-entity-util/page? e))
-
                               (:block/_parent e)))) eids-to-expand)
                 uuids-to-add (keep :block/uuid children)]
             (vswap! seen (partial apply conj) uuids-to-add)
@@ -148,13 +107,27 @@
       @seen)))
 
 (defn get-block-children
-  "Including nested children."
+  "Including nested children, notice the result doesn't include property values."
   {:arglists '([db block-uuid & {:keys [include-collapsed-children?]}])}
   [db block-uuid & {:as opts}]
   (let [ids (get-block-children-ids db block-uuid opts)]
     (when (seq ids)
       (map (fn [id] (d/entity db [:block/uuid id])) ids))))
 
+(defn get-block-full-children-ids
+  "Including nested, collapsed and property value children."
+  {:arglists '([db block-uuid])}
+  [db block-uuid]
+  (d/q
+   '[:find [?c ...]
+     :in $ ?id %
+     :where
+     [?p :block/uuid ?id]
+     (parent ?p ?c)]
+   db
+   block-uuid
+   (:parent rules/rules)))
+
 (defn- with-raw-title
   [m entity]
   (if-let [raw-title (:block/raw-title entity)]

+ 26 - 22
deps/db/src/logseq/db/frontend/db_ident.cljc

@@ -63,25 +63,29 @@
 
    NOTE: Only use this when creating a db-ident for a new class/property. Using
    this in read-only contexts like querying can result in db-ident conflicts"
-  [user-namespace name-string]
-  {:pre [(or (keyword? user-namespace) (string? user-namespace)) (string? name-string)]}
-  (assert (not (re-find #"^(logseq|block)(\.|$)" (name user-namespace)))
-          "New ident is not allowed to use an internal namespace")
-  (if #?(:org.babashka/nbb true
-         :cljs (and (exists? js/process) (or js/process.env.REPEATABLE_IDENTS js/process.env.DB_GRAPH))
-         :default false)
-    ;; Used for contexts where we want repeatable idents e.g. tests and CLIs
-    (keyword user-namespace
-             (->> (string/replace-first name-string #"^(\d)" "NUM-$1")
-                  ;; '-' must go last in char class
-                  (filter #(re-find #"[0-9a-zA-Z*+!_'?<>=-]{1}" %))
-                  (apply str)))
-    (keyword user-namespace
-             (str
-              (->> (string/replace-first name-string #"^(\d)" "NUM-$1")
-                   ;; '-' must go last in char class
-                   (filter #(re-find #"[0-9a-zA-Z*+!_'?<>=-]{1}" %))
-                   (apply str))
-              "-"
-              (rand-nth non-int-char-range)
-              (nano-id 7)))))
+  ([user-namespace name-string]
+   (create-db-ident-from-name user-namespace name-string true))
+  ([user-namespace name-string random-suffix?]
+   {:pre [(or (keyword? user-namespace) (string? user-namespace)) (string? name-string) (boolean? random-suffix?)]}
+   (assert (not (re-find #"^(logseq|block)(\.|$)" (name user-namespace)))
+     "New ident is not allowed to use an internal namespace")
+   (if #?(:org.babashka/nbb true
+          :cljs             (or (false? random-suffix?)
+                              (and (exists? js/process)
+                                (or js/process.env.REPEATABLE_IDENTS js/process.env.DB_GRAPH)))
+          :default          false)
+     ;; Used for contexts where we want repeatable idents e.g. tests and CLIs
+     (keyword user-namespace
+       (->> (string/replace-first name-string #"^(\d)" "NUM-$1")
+         ;; '-' must go last in char class
+         (filter #(re-find #"[0-9a-zA-Z*+!_'?<>=-]{1}" %))
+         (apply str)))
+     (keyword user-namespace
+       (str
+         (->> (string/replace-first name-string #"^(\d)" "NUM-$1")
+           ;; '-' must go last in char class
+           (filter #(re-find #"[0-9a-zA-Z*+!_'?<>=-]{1}" %))
+           (apply str))
+         "-"
+         (rand-nth non-int-char-range)
+         (nano-id 7))))))

+ 28 - 12
deps/db/src/logseq/db/sqlite/build.cljs

@@ -394,20 +394,36 @@
 ;; TODO: How to detect these idents don't conflict with existing? :db/add?
 (defn- create-all-idents
   [properties classes {:keys [graph-namespace]}]
-  (let [property-idents (->> (keys properties)
-                             (map #(vector %
-                                           (if graph-namespace
-                                             (db-ident/create-db-ident-from-name (str (name graph-namespace) ".property")
-                                                                                 (name %))
-                                             (db-property/create-user-property-ident-from-name (name %)))))
+  (let [create-property-ident (if graph-namespace
+                                (fn create-property-ident [kw]
+                                  (db-ident/create-db-ident-from-name (str (name graph-namespace) ".property")
+                                                                      (name kw)))
+                                (fn create-property-ident [kw]
+                                  (if (qualified-keyword? kw)
+                                    (do
+                                      (assert (db-property/user-property-namespace? (namespace kw))
+                                              "Property ident must have valid namespace")
+                                      (db-ident/create-db-ident-from-name (namespace kw) (name kw)))
+                                    (db-property/create-user-property-ident-from-name (name kw)))))
+        property-idents (->> (keys properties)
+                             (map #(vector % (create-property-ident %)))
                              (into {}))
-        _ (assert (= (count (set (vals property-idents))) (count properties)) "All property db-idents must be unique")
+        _ (assert (= (count (set (vals property-idents))) (count properties))
+                  (str "All property db-idents must be unique but the following are duplicates: "
+                       (->> property-idents vals frequencies (keep (fn [[k v]] (when (> v 1) k))))))
+        create-class-ident (if graph-namespace
+                             (fn create-class-ident [kw]
+                               (db-ident/create-db-ident-from-name (str (name graph-namespace) ".class")
+                                                                   (name kw)))
+                             (fn create-class-ident [kw]
+                               (if (qualified-keyword? kw)
+                                 (do
+                                   (assert (db-class/user-class-namespace? (namespace kw))
+                                           "Class ident must have valid namespace")
+                                   (db-ident/create-db-ident-from-name (namespace kw) (name kw)))
+                                 (db-class/create-user-class-ident-from-name nil (name kw)))))
         class-idents (->> (keys classes)
-                          (map #(vector %
-                                        (if graph-namespace
-                                          (db-ident/create-db-ident-from-name (str (name graph-namespace) ".class")
-                                                                              (name %))
-                                          (db-class/create-user-class-ident-from-name nil (name %)))))
+                          (map #(vector % (create-class-ident %)))
                           (into {}))
         _ (assert (= (count (set (vals class-idents))) (count classes)) "All class db-idents must be unique")
         all-idents (merge property-idents class-idents)]

+ 10 - 5
deps/db/src/logseq/db/sqlite/export.cljs

@@ -781,7 +781,7 @@
     ;; (prn :rproperties referenced-properties)
     undefined))
 
-(defn- find-undefined-uuids [{:keys [classes properties pages-and-blocks]}]
+(defn- find-undefined-uuids [db {:keys [classes properties pages-and-blocks]}]
   (let [pvalue-known-uuids (atom #{})
         _ (walk/postwalk (fn [f]
                            (if (and (map? f) (:build/property-value f) (:block/uuid f))
@@ -806,6 +806,11 @@
                      (mapcat get-pvalue-uuids (vals properties))
                      (mapcat (comp get-pvalue-uuids :page) pages-and-blocks)
                      (mapcat #(sqlite-build/extract-from-blocks (:blocks %) get-pvalue-uuids) pages-and-blocks))
+             (remove (fn [id]
+                       (let [eid (when id [:block/uuid id])]
+                         (some->> eid
+                                  (d/entity db)
+                                  :logseq.property/created-from-property))))
              set)]
     (set/difference ref-uuids known-uuids)))
 
@@ -842,10 +847,10 @@
   "Checks that export map is usable by sqlite.build including checking that
    all referenced properties and classes are defined. Checks related to properties and
    classes are disabled when :exclude-namespaces is set because those checks can't be done"
-  [export-map* {:keys [graph-options]}]
+  [db export-map* {:keys [graph-options]}]
   (let [export-map (remove-namespaced-keys export-map*)]
     (when-not (seq (:exclude-namespaces graph-options)) (sqlite-build/validate-options export-map))
-    (let [undefined-uuids (find-undefined-uuids export-map)
+    (let [undefined-uuids (find-undefined-uuids db export-map)
           undefined (cond-> {}
                       (empty? (:exclude-namespaces graph-options))
                       (merge (find-undefined-classes-and-properties export-map))
@@ -875,10 +880,10 @@
         export-map (patch-invalid-keywords export-map*)]
     (if (get-in options [:graph-options :catch-validation-errors?])
       (try
-        (ensure-export-is-valid export-map options)
+        (ensure-export-is-valid db export-map options)
         (catch ExceptionInfo e
           (println "Caught error:" e)))
-      (ensure-export-is-valid export-map options))
+      (ensure-export-is-valid db export-map options))
     (assoc export-map ::export-type export-type)))
 
 ;; Import fns

+ 14 - 2
deps/db/test/logseq/db/sqlite/build_test.cljs

@@ -5,7 +5,8 @@
             [logseq.db :as ldb]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.sqlite.build :as sqlite-build]
-            [logseq.db.test.helper :as db-test]))
+            [logseq.db.test.helper :as db-test]
+            [logseq.db.frontend.entity-util :as entity-util]))
 
 (deftest build-tags
   (let [conn (db-test/create-conn)
@@ -244,4 +245,15 @@
     (is (= {:block/tags [:user.class/C1]}
            (-> (db-test/find-block-by-content @conn "u1")
                db-test/readable-properties
-               (dissoc :logseq.property/created-from-property))))))
+               (dissoc :logseq.property/created-from-property))))))
+
+(deftest build-ontology-with-multiple-namespaces
+  (let [conn (db-test/create-conn-with-blocks
+              {:properties {:user.property/p1 {:logseq.property/type :default}
+                            :other.property/p1 {:logseq.property/type :default}}
+               :classes {:user.class/C1 {}
+                         :other.class/C1 {}}})]
+    (is (entity-util/property? (d/entity @conn :user.property/p1)))
+    (is (entity-util/property? (d/entity @conn :other.property/p1)))
+    (is (entity-util/class? (d/entity @conn :user.class/C1)))
+    (is (entity-util/class? (d/entity @conn :other.class/C1)))))

+ 1 - 1
deps/graph-parser/src/logseq/graph_parser/exporter.cljs

@@ -993,7 +993,7 @@
   (reduce (fn [acc [asset-name asset-uuid]]
             (let [new-title (string/replace acc
                                             (re-pattern (str "!?\\[[^\\]]*?\\]\\([^\\)]*?"
-                                                             asset-name
+                                                             (common-util/escape-regex-chars asset-name)
                                                              "\\)(\\{[^}]*\\})?"))
                                             (page-ref/->page-ref asset-uuid))]
               (when (string/includes? new-title asset-name)

+ 6 - 10
deps/outliner/src/logseq/outliner/core.cljs

@@ -348,12 +348,8 @@
     (assert (ds/outliner-txs-state? *txs-state)
             "db should be satisfied outliner-tx-state?")
     (let [block-id (:block/uuid this)
-          ids (->>
-               (let [children (ldb/get-block-children db block-id)
-                     children-ids (map :block/uuid children)]
-                 (conj children-ids block-id))
-               (remove nil?))
-          txs (map (fn [id] [:db.fn/retractEntity [:block/uuid id]]) ids)
+          ids (cons (:db/id this) (ldb/get-block-full-children-ids db block-id))
+          txs (map (fn [id] [:db.fn/retractEntity id]) ids)
           page-tx (let [block (d/entity db [:block/uuid block-id])]
                     (when (:block/pre-block? block)
                       (when-let [id (:db/id (:block/page block))]
@@ -870,12 +866,12 @@
                    :block/order block-order}
                    (not (ldb/page? block))
                    (assoc :block/page target-page))]
-        children-page-tx (when not-same-page?
-                           (let [children-ids (ldb/get-block-children-ids db (:block/uuid block))]
+        children-page-tx (when (and not-same-page? (not (ldb/page? block)))
+                           (let [children-ids (ldb/get-block-full-children-ids db (:block/uuid block))]
                              (keep (fn [id]
-                                     (let [child (d/entity db [:block/uuid id])]
+                                     (let [child (d/entity db id)]
                                        (when-not (ldb/page? child)
-                                         {:block/uuid id
+                                         {:block/uuid (:block/uuid child)
                                           :block/page target-page}))) children-ids)))
         target-from-property (:logseq.property/created-from-property target-block)
         block-from-property (:logseq.property/created-from-property block)

+ 16 - 0
deps/outliner/test/logseq/outliner/core_test.cljs

@@ -0,0 +1,16 @@
+(ns logseq.outliner.core-test
+  (:require [cljs.test :refer [deftest is testing]]
+            [logseq.db.test.helper :as db-test]
+            [logseq.outliner.core :as outliner-core]))
+
+(deftest test-delete-block-with-default-property
+  (testing "Delete block with default property"
+    (let [conn (db-test/create-conn-with-blocks
+                [{:page {:block/title "page1"}
+                  :blocks [{:block/title "b1" :build/properties {:default "test block"}}]}])
+          property-value (:user.property/default (db-test/find-block-by-content @conn "b1"))
+          _ (assert (:db/id property-value))
+          block (db-test/find-block-by-content @conn "b1")]
+      (outliner-core/delete-blocks! nil conn nil [block] {})
+      (is (nil? (db-test/find-block-by-content @conn "b1")))
+      (is (nil? (db-test/find-block-by-content @conn "test block"))))))

+ 4 - 4
libs/src/LSPlugin.ts

@@ -191,14 +191,14 @@ export interface BlockEntity {
   parent: IEntityID
   title: string
   content?: string // @deprecated. Use :title instead!
-  page: IEntityID
+  page: IEntityID // owner page
   createdAt: number
   updatedAt: number
+  ident?: string // ident for property block
   properties?: Record<string, any>
   'collapsed?': boolean
 
   // optional fields in dummy page
-  left?: IEntityID
   anchor?: string
   body?: any
   children?: Array<BlockEntity | BlockUUIDTuple>
@@ -812,7 +812,7 @@ export interface IEditorProxy extends Record<string, any> {
   upsertProperty: (
     key: string,
     schema?: Partial<{
-      type: 'default' | 'map' | 'number' | 'keyword' | 'node' | 'date' | 'checkbox' | string,
+      type: 'default' | 'number' | 'node' | 'date' | 'checkbox' | 'url' | string,
       cardinality: 'many' | 'one',
       hide: boolean
       public: boolean
@@ -831,7 +831,7 @@ export interface IEditorProxy extends Record<string, any> {
 
   removeBlockProperty: (block: BlockIdentity, key: string) => Promise<void>
 
-  getBlockProperty: (block: BlockIdentity, key: string) => Promise<BlockEntity | string | null>
+  getBlockProperty: (block: BlockIdentity, key: string) => Promise<BlockEntity | unknown>
 
   getBlockProperties: (block: BlockIdentity) => Promise<Record<string, any> | null>
 

+ 9 - 41
scripts/src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs

@@ -13,6 +13,7 @@
   (:require ["fs" :as fs]
             [babashka.cli :as cli]
             [clojure.edn :as edn]
+            [clojure.pprint :as pprint]
             [clojure.set :as set]
             [clojure.string :as string]
             [clojure.walk :as w]
@@ -20,6 +21,7 @@
             [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.property :as db-property]
+            [logseq.db.sqlite.export :as sqlite-export]
             [logseq.outliner.cli :as outliner-cli]
             [nbb.classpath :as cp]
             [nbb.core :as nbb]))
@@ -352,51 +354,17 @@
    :config {:alias :c
             :coerce edn/read-string
             :desc "EDN map to add to config.edn"}
-   :debug {:alias :d
-           :desc "Prints additional debug info and a schema.edn for debugging"}
+   :export {:alias :e
+            :desc "Exports graph to schema.edn"}
    :subset {:alias :s
             :desc "Only generate a subset of data for testing purposes"}
    :verbose {:alias :v
              :desc "Verbose mode"}})
 
-(defn- write-debug-file [db]
-  (let [ents (remove #(db-malli-schema/internal-ident? (:db/ident %))
-                     (d/q '[:find [(pull ?b [*
-                                             {:logseq.property.class/properties [:block/title]}
-                                             {:logseq.property/classes [:block/title]}
-                                             {:logseq.property.class/extends [:block/title]}
-                                             {:block/tags [:block/title]}
-                                             {:block/refs [:block/title]}]) ...]
-                            :in $
-                            :where [?b :db/ident ?ident]]
-                          db))
-        top-level-properties [:logseq.property/type :logseq.property.class/properties :logseq.property/classes
-                              :logseq.property.class/extends :block/tags]
-        debug-attributes (into [:block/name :block/title :db/cardinality :db/ident :block/refs]
-                               top-level-properties)]
-    (fs/writeFileSync "schema-org.edn"
-                      (pr-str
-                       (->> ents
-                            (map (fn [m]
-                                   (let [props (apply dissoc (db-property/properties m) top-level-properties)]
-                                     (cond-> (select-keys m debug-attributes)
-                                       (seq props)
-                                       (assoc :block/properties (-> (update-keys props name)
-                                                                    (update-vals (fn [v]
-                                                                                   (if (:db/id v)
-                                                                                     (db-property/property-value-content (d/entity db (:db/id v)))
-                                                                                     v)))))
-                                       (seq (:logseq.property.class/properties m))
-                                       (update :logseq.property.class/properties #(set (map :block/title %)))
-                                       (some? (:logseq.property.class/extends m))
-                                       (update :logseq.property.class/extends :block/title)
-                                       (seq (:logseq.property/classes m))
-                                       (update :logseq.property/classes #(set (map :block/title %)))
-                                       (seq (:block/tags m))
-                                       (update :block/tags #(set (map :block/title %)))
-                                       (seq (:block/refs m))
-                                       (update :block/refs #(set (map :block/title %)))))))
-                            set)))))
+(defn- write-export-file [db]
+  (let [export-map (sqlite-export/build-export db {:export-type :graph-ontology})]
+    (fs/writeFileSync "schema.edn"
+                      (with-out-str (pprint/pprint export-map)))))
 
 (defn -main [args]
   (let [[graph-dir] args
@@ -419,7 +387,7 @@
     (d/transact! conn init-tx)
     (d/transact! conn block-props-tx)
     (when (:verbose options) (println "Transacted" (count (d/datoms @conn :eavt)) "datoms"))
-    (when (:debug options) (write-debug-file @conn))
+    (when (:export options) (write-export-file @conn))
     (println "Created graph" (str db-name "!"))))
 
 (when (= nbb/*file* (nbb/invoked-file))

+ 2 - 2
src/main/frontend/components/library.cljs

@@ -43,8 +43,8 @@
                                            ldb/sort-by-order
                                            last)
                            target (or last-child library-page)
-                           sibling? (some? last-child)]
-                       (editor-handler/move-blocks! [{:db/id chosen}] target sibling?)
+                           chosen-block (db/entity chosen)]
+                       (editor-handler/move-blocks! [chosen-block] target (if last-child true false))
                        (set-selected-choices! (conj selected-choices chosen)))
                      (do
                        (db/transact! (state/get-current-repo)

+ 1 - 1
src/main/frontend/components/views.cljs

@@ -1740,7 +1740,7 @@
                            :property-objects
                            "All"
                            :all-pages
-                           "All pages"
+                           "All"
                            ""))
             view-block-id (common-uuid/gen-uuid :view-block-uuid (str (:block/uuid view-parent) view-feature-type))
             result (editor-handler/api-insert-new-block! view-title

+ 1 - 1
src/main/frontend/db.cljs

@@ -24,7 +24,7 @@
   entity pull pull-many]
 
  [frontend.db.model
-  delete-files get-block-and-children get-block-by-uuid get-block-children sort-by-order
+  delete-files get-block-and-children get-block-by-uuid sort-by-order
   get-block-parent get-block-parents parents-collapsed?
   get-block-immediate-children get-block-page
   get-file file-exists?  get-files-full

+ 0 - 9
src/main/frontend/db/model.cljs

@@ -314,15 +314,6 @@ independent of format as format specific heading characters are stripped"
   (when-let [db (conn/get-db repo)]
     (ldb/get-children db block-uuid)))
 
-(defn get-block-children
-  "Including nested children."
-  [repo block-uuid]
-  (when-let [db (conn/get-db repo)]
-    (let [ids (ldb/get-block-children-ids db block-uuid)]
-      (when (seq ids)
-        (let [ids' (map (fn [id] [:block/uuid id]) ids)]
-          (db-utils/pull-many repo '[*] ids'))))))
-
 (defn get-block-and-children
   [repo block-uuid & {:as opts}]
   (let [db (conn/get-db repo)]

+ 9 - 1
src/main/frontend/worker/db/migrate.cljs

@@ -239,9 +239,17 @@
              tag-properties (->> (d/datoms db :avet :logseq.property.class/properties id)
                                  (mapcat (fn [d]
                                            [[:db/retract (:e d) (:a d) (:v d)]
-                                            [:db/add (:e d) (:a d) [:block/uuid (:block/uuid new-property)]]])))]
+                                            [:db/add (:e d) (:a d) [:block/uuid (:block/uuid new-property)]]])))
+             other-properties-tx (mapcat
+                                  (fn [ident]
+                                    (->> (d/datoms db :avet ident id)
+                                         (mapcat (fn [d]
+                                                   [[:db/retract (:e d) (:a d) (:v d)]
+                                                    [:db/add (:e d) (:a d) [:block/uuid (:block/uuid new-property)]]]))))
+                                  [:logseq.property.view/group-by-property :logseq.property.table/pinned-columns])]
          (concat [new-property]
                  tag-properties
+                 other-properties-tx
                  retract-property-attrs
                  (mapcat
                   (fn [d]

+ 72 - 32
src/main/frontend/worker/db/validate.cljs

@@ -5,42 +5,82 @@
             [logseq.db :as ldb]
             [logseq.db.frontend.validate :as db-validate]))
 
+(defn- get-property-by-title
+  [db title]
+  (when title
+    (some->> (first (ldb/page-exists? db title [:logseq.class/Property]))
+             (d/entity db))))
+
 (defn- fix-invalid-blocks!
   [conn errors]
-  (let [tx-data (mapcat
-                 (fn [{:keys [entity dispatch-key]}]
-                   (let [entity (d/entity @conn (:db/id entity))]
-                     (cond
-                       (and (= dispatch-key :block) (nil? (:block/title entity)))
-                       [[:db/retractEntity (:db/id entity)]]
-
-                       (and (= dispatch-key :block) (nil? (:block/page entity)))
-                       (let [latest-journal-id (:db/id (first (ldb/get-latest-journals @conn)))
-                             page-id (:db/id (:block/page (:block/parent entity)))]
+  (let [db @conn
+        fix-tx-data (mapcat
+                     (fn [{:keys [entity dispatch-key]}]
+                       (let [entity (d/entity db (:db/id entity))]
                          (cond
-                           page-id
-                           [[:db/add (:db/id entity) :block/page page-id]]
-                           latest-journal-id
-                           [[:db/add (:db/id entity) :block/page latest-journal-id]
-                            [:db/add (:db/id entity) :block/parent latest-journal-id]]
-                           :else
-                           (js/console.error (str "Don't know where to put the block " (:db/id entity)))))
+                           (and (= dispatch-key :block) (nil? (:block/title entity)))
+                           [[:db/retractEntity (:db/id entity)]]
 
-                       (:block.temp/fully-loaded? entity)
-                       [[:db/retract (:db/id entity) :block.temp/fully-loaded?]]
-                       (and (:block/page entity) (not (:block/parent entity)))
-                       [[:db/add (:db/id entity) :block/parent (:db/id (:block/page entity))]]
-                       (and (not (:block/page entity)) (not (:block/parent entity)) (not (:block/name entity)))
-                       [[:db/retractEntity (:db/id entity)]]
-                       (and (= dispatch-key :property-value-block) (:block/title entity))
-                       [[:db/retract (:db/id entity) :block/title]]
-                       (and (ldb/class? entity) (not (:logseq.property.class/extends entity)))
-                       [[:db/add (:db/id entity) :logseq.property.class/extends :logseq.class/Root]]
-                       (and (or (ldb/class? entity) (ldb/property? entity)) (ldb/internal-page? entity))
-                       [[:db/retract (:db/id entity) :block/tags :logseq.class/Page]]
-                       :else
-                       nil)))
-                 errors)]
+                           (and (= dispatch-key :block) (nil? (:block/page entity)))
+                           (let [latest-journal-id (:db/id (first (ldb/get-latest-journals db)))
+                                 page-id (:db/id (:block/page (:block/parent entity)))]
+                             (cond
+                               page-id
+                               [[:db/add (:db/id entity) :block/page page-id]]
+                               latest-journal-id
+                               [[:db/add (:db/id entity) :block/page latest-journal-id]
+                                [:db/add (:db/id entity) :block/parent latest-journal-id]]
+                               :else
+                               (js/console.error (str "Don't know where to put the block " (:db/id entity)))))
+
+                           (and (= dispatch-key :block)
+                                (some (fn [k] (= "user.class" (namespace k))) (keys (:logseq.property.table/sized-columns entity))))
+                           (let [new-value (->> (keep (fn [[k v]]
+                                                        (if (= "user.class" (namespace k))
+                                                          (when-let [property (get-property-by-title db (:block/title (d/entity db k)))]
+                                                            [(:db/ident property) v])
+                                                          [k v]))
+                                                      (:logseq.property.table/sized-columns entity))
+                                                (into {}))]
+                             [[:db/add (:db/id entity) :logseq.property.table/sized-columns new-value]])
+
+                           (:block.temp/fully-loaded? entity)
+                           [[:db/retract (:db/id entity) :block.temp/fully-loaded?]]
+                           (and (:block/page entity) (not (:block/parent entity)))
+                           [[:db/add (:db/id entity) :block/parent (:db/id (:block/page entity))]]
+                           (and (not (:block/page entity)) (not (:block/parent entity)) (not (:block/name entity)))
+                           [[:db/retractEntity (:db/id entity)]]
+                           (and (= dispatch-key :property-value-block) (:block/title entity))
+                           [[:db/retract (:db/id entity) :block/title]]
+                           (and (ldb/class? entity) (not (:logseq.property.class/extends entity)))
+                           [[:db/add (:db/id entity) :logseq.property.class/extends :logseq.class/Root]]
+                           (and (or (ldb/class? entity) (ldb/property? entity)) (ldb/internal-page? entity))
+                           [[:db/retract (:db/id entity) :block/tags :logseq.class/Page]]
+                           :else
+                           nil)))
+                     errors)
+        class-as-properties (concat
+                             (mapcat
+                              (fn [ident]
+                                (->> (d/datoms db :avet ident)
+                                     (mapcat (fn [d]
+                                               (let [entity (d/entity db (:v d))]
+                                                 (when (ldb/class? entity)
+                                                   (if-let [property (get-property-by-title db (:block/title entity))]
+                                                     [[:db/retract (:e d) (:a d) (:v d)]
+                                                      [:db/add (:e d) (:a d) (:db/id property)]]
+                                                     [[:db/retract (:e d) (:a d) (:v d)]])))))))
+                              [:logseq.property.view/group-by-property :logseq.property.table/pinned-columns])
+                             (->> (d/datoms db :eavt)
+                                  (filter (fn [d] (= (namespace (:a d)) "user.class")))
+                                  (mapcat (fn [d]
+                                            (let [class-title (:block/title (d/entity db (:a d)))
+                                                  property (get-property-by-title db class-title)]
+                                              (if property
+                                                [[:db/retract (:e d) (:a d) (:v d)]
+                                                 [:db/add (:e d) (:db/ident property) (:v d)]]
+                                                [[:db/retract (:e d) (:a d) (:v d)]]))))))
+        tx-data (concat fix-tx-data class-as-properties)]
     (when (seq tx-data)
       (ldb/transact! conn tx-data {:fix-db? true}))))
 

+ 12 - 6
src/main/frontend/worker/export.cljs

@@ -61,11 +61,17 @@
   [conn]
   (some->> (d/datoms @conn :eavt)
            (map (fn [{:keys [e a v t]}]
-                  (if (and (contains? #{:block/title :block/name} a)
-                           (let [entity (d/entity @conn e)]
-                             (and (not (:db/ident entity))
-                                  (not (ldb/journal? entity))
-                                  (not (:logseq.property/built-in? entity))
-                                  (not (= :logseq.property/query (:db/ident (:logseq.property/created-from-property entity)))))))
+                  (cond
+                    (= :url (:logseq.property/type (d/entity @conn a)))
+                    (d/datom e a "https://logseq.com" t)
+
+                    (and (contains? #{:block/title :block/name} a)
+                         (let [entity (d/entity @conn e)]
+                           (and (not (:db/ident entity))
+                                (not (ldb/journal? entity))
+                                (not (:logseq.property/built-in? entity))
+                                (not (= :logseq.property/query (:db/ident (:logseq.property/created-from-property entity)))))))
                     (d/datom e a (str "debug " e) t)
+
+                    :else
                     (d/datom e a v t))))))

+ 108 - 106
src/main/logseq/api.cljs

@@ -83,14 +83,6 @@
 (defn get-caller-plugin-id
   [] (gobj/get js/window "$$callerPluginID"))
 
-(defn- sanitize-user-property-name
-  [k]
-  (if (string? k)
-    (-> k (string/trim)
-        (string/replace #"^[:_]+" "")
-        (string/lower-case))
-    k))
-
 ;; helpers
 (defn ^:export install-plugin-hook
   [pid hook ^js opts]
@@ -723,10 +715,12 @@
                 (db-async/<get-block repo page-uuid)))]
     block))
 
-(def ^:export insert_block
-  (fn [block-uuid-or-page-name content ^js opts]
+(defn ^:export insert_block
+  [block-uuid-or-page-name content ^js opts]
+  (this-as this
     (when (string/blank? block-uuid-or-page-name)
       (throw (js/Error. "Page title or block UUID shouldn't be empty.")))
+
     (p/let [block? (util/uuid-string? (str block-uuid-or-page-name))
             block (<pull-block (str block-uuid-or-page-name))]
       (if (and block? (not block))
@@ -735,41 +729,45 @@
                 [page-name block-uuid] (if (util/uuid-string? block-uuid-or-page-name)
                                          [nil (uuid block-uuid-or-page-name)]
                                          [block-uuid-or-page-name nil])
-                page-name              (when page-name (util/page-name-sanity-lc page-name))
-                _                      (when (and page-name
-                                                  (nil? (ldb/get-page (db/get-db) page-name)))
-                                         (page-handler/<create! block-uuid-or-page-name {}))
-                custom-uuid            (or customUUID (:id properties))
-                custom-uuid            (when custom-uuid (sdk-utils/uuid-or-throw-error custom-uuid))
-                edit-block?            (if (nil? focus) true focus)
-                _                      (when (and custom-uuid (db-model/query-block-by-uuid custom-uuid))
-                                         (throw (js/Error.
-                                                 (util/format "Custom block UUID already exists (%s)." custom-uuid))))
-                block-uuid'            (if (and (not sibling) before block-uuid)
-                                         (let [block       (db/entity [:block/uuid block-uuid])
-                                               first-child (ldb/get-first-child (db/get-db) (:db/id block))]
-                                           (if first-child
-                                             (:block/uuid first-child)
-                                             block-uuid))
-                                         block-uuid)
+                page-name (when page-name (util/page-name-sanity-lc page-name))
+                _ (when (and page-name
+                          (nil? (ldb/get-page (db/get-db) page-name)))
+                    (page-handler/<create! block-uuid-or-page-name {}))
+                custom-uuid (or customUUID (:id properties))
+                custom-uuid (when custom-uuid (sdk-utils/uuid-or-throw-error custom-uuid))
+                edit-block? (if (nil? focus) true focus)
+                _ (when (and custom-uuid (db-model/query-block-by-uuid custom-uuid))
+                    (throw (js/Error.
+                             (util/format "Custom block UUID already exists (%s)." custom-uuid))))
+                block-uuid' (if (and (not sibling) before block-uuid)
+                              (let [block (db/entity [:block/uuid block-uuid])
+                                    first-child (ldb/get-first-child (db/get-db) (:db/id block))]
+                                (if first-child
+                                  (:block/uuid first-child)
+                                  block-uuid))
+                              block-uuid)
                 insert-at-first-child? (not= block-uuid' block-uuid)
                 [sibling? before?] (if insert-at-first-child?
                                      [true true]
                                      [sibling before])
-                before?                (if (and (false? sibling?) before? (not insert-at-first-child?))
-                                         false
-                                         before?)
-                new-block              (editor-handler/api-insert-new-block!
-                                        content
-                                        {:block-uuid  block-uuid'
-                                         :sibling?    sibling?
-                                         :before?     before?
-                                         :edit-block? edit-block?
-                                         :page        page-name
-                                         :custom-uuid custom-uuid
-                                         :ordered-list? (if (boolean? autoOrderedList) autoOrderedList false)
-                                         :properties  (merge properties
-                                                             (when custom-uuid {:id custom-uuid}))})]
+                db-base? (db-graph?)
+                before? (if (and (false? sibling?) before? (not insert-at-first-child?))
+                          false
+                          before?)
+                new-block (editor-handler/api-insert-new-block!
+                            content
+                            {:block-uuid block-uuid'
+                             :sibling? sibling?
+                             :before? before?
+                             :edit-block? edit-block?
+                             :page page-name
+                             :custom-uuid custom-uuid
+                             :ordered-list? (if (boolean? autoOrderedList) autoOrderedList false)
+                             :properties (when (not db-base?)
+                                           (merge properties
+                                             (when custom-uuid {:id custom-uuid})))})
+                _ (when (and db-base? (some? properties))
+                    (api-block/save-db-based-block-properties! new-block properties this))]
           (bean/->js (sdk-utils/normalize-keyword-for-json new-block)))))))
 
 (def ^:export insert_batch_block
@@ -883,31 +881,26 @@
           nil)))))
 
 ;; properties (db only)
-(defn -resolve-property-prefix-for-db
-  [^js plugin]
-  (when (some-> js/window.LSPlugin (.-PluginLocal) (instance? plugin))
-    (some-> (.-id plugin) (sanitize-user-property-name) (str "."))))
-
 (defn -get-property
   [^js plugin k]
-  (when-let [k' (and (string? k) (some-> k (sanitize-user-property-name) (keyword)))]
-    (let [prefix (-resolve-property-prefix-for-db plugin)]
+  (when-let [k' (and (string? k) (some-> k (api-block/sanitize-user-property-name) (keyword)))]
+    (let [prefix (api-block/resolve-property-prefix-for-db plugin)]
       (p/let [k (if (qualified-keyword? k') k'
-                    (api-block/get-db-ident-for-user-property-name (str prefix k)))
+                    (api-block/get-db-ident-for-user-property-name k prefix))
               p (db-utils/pull k)] p))))
 
 (defn ^:export get_property
   [k]
   (this-as this
-           (p/let [prop (-get-property this k)]
-             (-> prop
-                 (assoc :type (:logseq.property/type prop))
-                 (sdk-utils/normalize-keyword-for-json)
-                 (bean/->js)))))
+    (p/let [prop (-get-property this k)]
+      (some-> prop
+        (assoc :type (:logseq.property/type prop))
+        (sdk-utils/normalize-keyword-for-json)
+        (bean/->js)))))
 
 (defn ^:export upsert_property
   "schema:
-    {:type :default | :keyword | :map | :date | :checkbox
+    {:type :default | :number | :date | :datetime | :checkbox | :url | :node
      :cardinality :many | :one
      :hide? true
      :view-context :page
@@ -916,87 +909,96 @@
   [k ^js schema ^js opts]
   (this-as this
            (when-let [k' (and (string? k) (keyword k))]
-             (let [prefix (when (some-> js/window.LSPlugin (.-PluginLocal) (instance? this))
-                            (str (.-id this) "."))]
+             (let [prefix (api-block/resolve-property-prefix-for-db this)]
                (p/let [opts (or (some-> opts (bean/->clj)) {})
-                       name (or (:name opts) (some-> (str k) (string/trim)))
                        k (if (qualified-keyword? k') k'
-                             (api-block/get-db-ident-for-user-property-name (str prefix k)))
+                             (api-block/get-db-ident-for-user-property-name k prefix))
+                       name (or (:name opts) (some-> k (name)))
                        schema (or (some-> schema (bean/->clj)
                                           (update-keys #(if (contains? #{:hide :public} %)
                                                           (keyword (str (name %) "?")) %))) {})
                        schema (cond-> schema
                                 (string? (:cardinality schema))
-                                (update :cardinality keyword)
+                                (-> (assoc :db/cardinality (keyword (:cardinality schema)))
+                                  (dissoc :cardinality))
+
                                 (string? (:type schema))
                                 (-> (assoc :logseq.property/type (keyword (:type schema)))
                                     (dissoc :type)))
                        p (db-property-handler/upsert-property! k schema
                                                                (cond-> opts
                                                                  name
-                                                                 (assoc :property-name name)))]
+                                                                 (assoc :property-name name)))
+                       p (db-utils/pull (:db/id p))]
                  (bean/->js (sdk-utils/normalize-keyword-for-json p)))))))
 
 (defn ^:export remove_property
   [k]
   (this-as this
-           (p/let [prop (-get-property this k)]
-             (when-let [uuid (:block/uuid prop)]
-               (page-common-handler/<delete! uuid nil nil)))))
+    (p/let [prop (-get-property this k)]
+      (when-let [uuid (and (api-block/plugin-property-key? (:db/ident prop))
+                        (:block/uuid prop))]
+        (page-common-handler/<delete! uuid nil nil)))))
 
 ;; block properties
 (defn ^:export upsert_block_property
-  [block-uuid keyname value]
+  [block-uuid key ^js value]
   (this-as this
-           (p/let [keyname (sanitize-user-property-name keyname)
-                   block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
-                   repo (state/get-current-repo)
-                   _ (db-async/<get-block repo block-uuid :children? false)
-                   db? (config/db-based-graph? repo)
-                   key (-> (if (keyword? key) (name keyname) keyname) (util/safe-lower-case))
-                   key (if db?
-                         (api-block/get-db-ident-for-user-property-name
-                          (str (-resolve-property-prefix-for-db this) key))
-                         key)
-                   _ (when (and db? (not (db-utils/entity key)))
-                       (db-property-handler/upsert-property! key {} {:property-name keyname}))]
-             (property-handler/set-block-property! repo block-uuid key value))))
+    (p/let [keyname (api-block/sanitize-user-property-name key)
+            block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
+            repo (state/get-current-repo)
+            block (db-async/<get-block repo block-uuid :children? false)
+            db-base? (db-graph?)
+            key' (-> (if (keyword? keyname) (name keyname) keyname) (util/trim-safe))
+            value (bean/->clj value)]
+      (when block
+        (if db-base?
+          (p/do!
+            (api-block/save-db-based-block-properties! block {key' value} this))
+          (property-handler/set-block-property! repo block-uuid key' value))))))
 
 (defn ^:export remove_block_property
   [block-uuid key]
   (this-as this
-           (p/let [key (sanitize-user-property-name key)
-                   block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
-                   _ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)
-                   db? (config/db-based-graph? (state/get-current-repo))
-                   key-ns? (and (keyword? key) (namespace key))
-                   key (if key-ns? key (-> (if (keyword? key) (name key) key) (util/safe-lower-case)))
-                   key (if (and db? (not key-ns?))
-                         (api-block/get-db-ident-for-user-property-name
-                          (str (-resolve-property-prefix-for-db this) key))
-                         key)]
-             (property-handler/remove-block-property!
-              (state/get-current-repo)
-              block-uuid key))))
+    (p/let [key (api-block/sanitize-user-property-name key)
+            block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
+            _ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)
+            db? (config/db-based-graph? (state/get-current-repo))
+            key-ns? (and (keyword? key) (namespace key))
+            key (if key-ns? key (-> (if (keyword? key) (name key) key) (util/safe-lower-case)))
+            key (if (and db? (not key-ns?))
+                  (api-block/get-db-ident-for-user-property-name
+                    key (api-block/resolve-property-prefix-for-db this))
+                  key)]
+      (property-handler/remove-block-property!
+        (state/get-current-repo)
+        block-uuid key))))
 
 (defn ^:export get_block_property
   [block-uuid key]
   (this-as this
-           (p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
-                   _ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)]
-             (when-let [properties (some-> block-uuid (db-model/get-block-by-uuid) (:block/properties))]
-               (when (seq properties)
-                 (let [key (sanitize-user-property-name key)
-                       property-name (-> (if (keyword? key) (name key) key) (util/safe-lower-case))
-                       property-value (or (get properties key)
-                                          (get properties (keyword property-name))
-                                          (get properties
-                                               (api-block/get-db-ident-for-user-property-name
-                                                (str (-resolve-property-prefix-for-db this) property-name))))
-                       property-value (if-let [property-id (:db/id property-value)]
-                                        (db/pull property-id) property-value)
-                       ret (sdk-utils/normalize-keyword-for-json property-value)]
-                   (bean/->js ret)))))))
+    (p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
+            _ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)]
+      (when-let [properties (some-> block-uuid (db-model/get-block-by-uuid) (:block/properties))]
+        (when (seq properties)
+          (let [key (api-block/sanitize-user-property-name key)
+                property-name (-> (if (keyword? key) (name key) key) (util/safe-lower-case))
+                ident (api-block/get-db-ident-for-user-property-name
+                        property-name (api-block/resolve-property-prefix-for-db this))
+                property-value (or (get properties key)
+                                 (get properties (keyword property-name))
+                                 (get properties ident))
+                property-value (if-let [property-id (:db/id property-value)]
+                                 (db/pull property-id) property-value)
+                property-value (cond-> property-value
+                                 (map? property-value)
+                                 (assoc
+                                   :value (or (:logseq.property/value property-value)
+                                            (:block/title property-value))
+                                   :ident ident))
+                parsed-value (api-block/parse-property-json-value-if-need ident property-value)]
+            (or parsed-value
+              (bean/->js (sdk-utils/normalize-keyword-for-json property-value)))))))))
 
 (def ^:export get_block_properties
   (fn [block-uuid]

+ 111 - 64
src/main/logseq/api/block.cljs

@@ -16,124 +16,171 @@
             [frontend.modules.outliner.ui :as ui-outliner-tx]
             [frontend.state :as state]
             [logseq.db :as ldb]
+            [logseq.db.frontend.db-ident :as db-ident]
             [logseq.db.frontend.property :as db-property]
             [logseq.sdk.utils :as sdk-utils]
             [promesa.core :as p]))
 
-(defn- encode-user-property-name
-  [k]
-  (if (string? k)
-    (-> k (string/trim)
-        (string/replace "/" "")
-        (string/replace " " ""))
-    k))
-
 (defn convert?to-built-in-property-name
   [property-name]
   (if (and (not (qualified-keyword? property-name))
-           (contains? #{:background-color} property-name))
+        (contains? #{:background-color} property-name))
     (keyword :logseq.property property-name)
     property-name))
 
+(defn sanitize-user-property-name
+  [k]
+  (if (string? k)
+    (-> k (string/trim)
+      (string/replace " " "")
+      (string/replace #"^[:_\s]+" "")
+      (string/lower-case))
+    k))
+
+(defn resolve-property-prefix-for-db
+  [^js plugin]
+  (->> (when (some-> js/window.LSPlugin (.-PluginLocal))
+         (or (some->> plugin (.-id) (sanitize-user-property-name) (str "."))
+           "._api"))
+    (str "plugin.property")))
+
 ;; FIXME: This ns should not be creating idents. This allows for ident conflicts
 ;; and assumes that names directly map to idents which is incorrect and breaks for multiple
 ;; cases e.g. a property that has been renamed or sanitized. Instead it should
 ;; find a property's ident by looking up the property in the db by its title
 (defn get-db-ident-for-user-property-name
   "Finds a property :db/ident for a given property name"
-  [property-name]
-  (let [property-name' (if (string? property-name)
-                         (keyword property-name) property-name)
-        property-name' (convert?to-built-in-property-name property-name')]
-    (if (qualified-keyword? property-name')
-      property-name'
-      (keyword "plugin.property" (encode-user-property-name property-name)))))
+  ([property-name] (get-db-ident-for-user-property-name property-name "user.property"))
+  ([property-name prefix]
+   (let [property-name' (if (string? property-name)
+                          (keyword property-name) property-name)
+         property-name' (convert?to-built-in-property-name property-name')]
+     (if (qualified-keyword? property-name') property-name'
+       (db-ident/create-db-ident-from-name prefix (name property-name) false)))))
+
+(defn plugin-property-key?
+  [ident]
+  (some-> ident (str)
+    (string/starts-with? ":plugin.property.")))
 
 (defn into-readable-db-properties
   [properties]
   (some-> properties
-          (db-pu/readable-properties
-           {:original-key? true :key-fn str})))
+    (db-pu/readable-properties
+      {:original-key? true :key-fn str})))
 
 (defn into-properties
   ([block] (into-properties (state/get-current-repo) block))
   ([repo block]
    (if (some-> repo (config/db-based-graph?))
      (let [props (some->> block
-                          (filter (fn [[k _]] (db-property/property? k)))
-                          (into {})
-                          (into-readable-db-properties))
+                   (filter (fn [[k _]] (db-property/property? k)))
+                   (into {})
+                   (into-readable-db-properties))
            block (update block :block/properties merge props)
            block (apply dissoc (concat [block] (keys props)))]
        block)
      block)))
 
+(defn parse-property-json-value-if-need
+  [ident property-value]
+  (when-let [prop (and (string? property-value)
+                    (plugin-property-key? ident)
+                    (some-> ident (db-utils/entity)))]
+    (if (= (:logseq.property/type prop) :string)
+      (try
+        (js/JSON.parse property-value)
+        (catch js/Error _e
+          property-value))
+      property-value)))
+
 (defn infer-property-value-type-to-save!
   [ident value]
-  (let [multi? (coll? value)
+  (let [as-json? (coll? value)
         value-handle
-        (fn []
-          (if multi?
-            (-> (for [v value]
-                  (when-let [page (some-> v (str) (string/trim))]
-                    (let [id (:db/id (ldb/get-case-page (conn/get-db) page))]
-                      (if (nil? id)
-                        (-> (page-handler/<create! page {:redirect? false})
+        (fn [type multi?]
+          (let [as-json? (or (= type :string) as-json?)]
+            (if multi?
+              (-> (for [v value]
+                    (when-let [page (some-> v (str) (string/trim))]
+                      (let [id (:db/id (ldb/get-case-page (conn/get-db) page))]
+                        (if (nil? id)
+                          (-> (page-handler/<create! page {:redirect? false})
                             (p/then #(:db/id %)))
-                        id))))
+                          id))))
                 (p/all)
                 (p/then (fn [vs] [ident :logseq.property/empty-placeholder vs true])))
-            [ident value nil false]))]
-    (if (not (db-utils/entity ident))
+              (let [value (if as-json? (js/JSON.stringify (bean/->js value)) value)]
+                [ident value nil false]))))
+        ent (db-utils/entity ident)]
+    (if (not ent)
       (let [type (cond
                    (boolean? value) :checkbox
                    (number? value) :number
-                   (coll? value) :node
+                   (coll? value) :string
                    :else :default)
-            schema {:type type :cardinality (if multi? :many :one)}]
+            schema {:logseq.property/type type
+                    :db/cardinality :one}]
+        (p/chain
+          (db-property-handler/upsert-property! ident schema {})
+          (fn [] (value-handle type false))))
+      (let [value-multi? (vector? value)
+            ident (:db/ident ent)
+            ent-type (:logseq.property/type ent)
+            ent-type-str? (= ent-type :string)
+            ent-multi? (= (:db/cardinality ent) :db.cardinality/many)
+            cardinality-want-illegal-changed? (and (not value-multi?) ent-multi?)]
+        (when cardinality-want-illegal-changed?
+          (throw (js/Error. "Multiple property type can not be changed.")))
         (p/chain
-         (db-property-handler/upsert-property! ident schema {})
-         value-handle))
-      (value-handle))))
+          (db-property-handler/upsert-property! ident
+            {:logseq.property/type ent-type
+             :db/cardinality (if (and (not ent-type-str?) value-multi?) :many :one)}
+            {})
+          #(value-handle ent-type ent-multi?))))))
 
 (defn save-db-based-block-properties!
-  [block properties]
-  (when-let [block-id (and (seq properties) (:db/id block))]
-    (let [properties (update-keys properties
-                                  (fn [k] (get-db-ident-for-user-property-name k)))
-          *properties-page-refs (volatile! {})]
-      (-> (for [ident (keys properties)]
-            (p/let [ret (infer-property-value-type-to-save! ident (get properties ident))] ret))
-          (p/all)
-          (p/chain
+  ([block properties] (save-db-based-block-properties! block properties nil))
+  ([block properties ^js plugin]
+   (when-let [block-id (and (seq properties) (:db/id block))]
+     (let [properties (update-keys properties
+                        (fn [k]
+                          (let [prefix (resolve-property-prefix-for-db plugin)]
+                            (get-db-ident-for-user-property-name k prefix))))
+           *properties-page-refs (volatile! {})]
+       (-> (for [ident (keys properties)]
+             (p/let [ret (infer-property-value-type-to-save! ident (get properties ident))]
+               ret))
+         (p/all)
+         (p/chain
            (fn [props]
              (->> props
-                  (reduce (fn [a [k v vs multi?]]
-                            (if multi?
-                              (do (vswap! *properties-page-refs assoc k vs) a)
-                              (assoc a k v))) {})
-                  (db-property-handler/set-block-properties! block-id)))
-          ;; handle page refs
+               (reduce (fn [a [k v vs multi?]]
+                         (if multi?
+                           (do (vswap! *properties-page-refs assoc k vs) a)
+                           (assoc a k v))) {})
+               (db-property-handler/set-block-properties! block-id)))
+           ;; handle page refs
            (fn []
              (when (seq @*properties-page-refs)
                (doseq [[ident refs] @*properties-page-refs]
                  (-> (property-handler/remove-block-property! (state/get-current-repo) block-id ident)
-                     (p/then
-                      (fn []
-                        (if (seq refs)
-                          (ui-outliner-tx/transact!
+                   (p/then
+                     (fn []
+                       (if (seq refs)
+                         (ui-outliner-tx/transact!
                            {:outliner-op :set-block-properties}
                            (doseq [eid refs]
                              (when (number? eid)
                                (property-handler/set-block-property!
-                                (state/get-current-repo) block-id ident eid))))
-                          (db-property-handler/set-block-property! block-id ident :logseq.property/empty-placeholder)))))))))))))
+                                 (state/get-current-repo) block-id ident eid))))
+                         (db-property-handler/set-block-property! block-id ident :logseq.property/empty-placeholder))))))))))))))
 
 (defn <sync-children-blocks!
   [block]
   (when block
     (db-async/<get-block (state/get-current-repo)
-                         (:block/uuid (:block/parent block)) {:children? true})))
+      (:block/uuid (:block/parent block)) {:children? true})))
 
 (defn get_block
   [id-or-uuid ^js opts]
@@ -141,19 +188,19 @@
                      (db-utils/pull id-or-uuid)
                      (and id-or-uuid (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error id-or-uuid))))]
     (when (or (true? (some-> opts (.-includePage)))
-              (not (contains? block :block/name)))
+            (not (contains? block :block/name)))
       (when-let [uuid (:block/uuid block)]
         (let [{:keys [includeChildren]} (bean/->clj opts)
               repo (state/get-current-repo)
               block (if includeChildren
                       ;; nested children results
                       (let [blocks (->> (db-model/get-block-and-children repo uuid)
-                                        (map (fn [b]
-                                               (dissoc (db-utils/pull (:db/id b)) :block.temp/load-status))))]
+                                     (map (fn [b]
+                                            (dissoc (db-utils/pull (:db/id b)) :block.temp/load-status))))]
                         (first (outliner-tree/blocks->vec-tree blocks uuid)))
                       ;; attached shallow children
                       (assoc block :block/children
-                             (map #(list :uuid (:block/uuid %))
-                                  (db/get-block-immediate-children repo uuid))))
+                        (map #(list :uuid (:block/uuid %))
+                          (db/get-block-immediate-children repo uuid))))
               block (into-properties repo block)]
           (bean/->js (sdk-utils/normalize-keyword-for-json block)))))))

+ 1 - 0
src/main/logseq/sdk/utils.cljs

@@ -38,6 +38,7 @@
                 camel-case?
                 (csk/->camelCase)))
 
+            (de/entity? a) (:db/id a)
             (uuid? a) (str a)
 
             ;; @FIXME compatible layer for classic APIs

+ 0 - 1
src/resources/dicts/af.edn

@@ -43,7 +43,6 @@
  :re-index "Herindekseer"
  :export-json "Uitvoer as JSON"
  :graph "Grafiek"
- :all-pages "Alle blaaie"
  :all-files "Alle lêers"
  :settings "Verstellings"
  :import "Invoer"

+ 0 - 2
src/resources/dicts/ca.edn

@@ -1,7 +1,6 @@
 {:all-files                                         "Llista d'arxius"
  :all-graphs                                        "Llista de grafs"
  :all-journals                                      "Llista de diaris"
- :all-pages                                         "Llista de pàgines"
  :all-whiteboards                                   "Totes les pissarres"
  :auto-heading                                      "Encapçalaments automàtics"
  :bold                                              "Negreta"
@@ -490,7 +489,6 @@
  :plugin/updating                                   "Actualitzant"
  :plugin/up-to-date                                 "Està actualitzat {1}"
  :query/config-property-settings                    "Configuració de propietats per aquesta consulta:"
- :right-side-bar/all-pages                          "Llista de pàgines"
  :right-side-bar/block-ref                          "Referència de bloc"
  :right-side-bar/contents                           "Contingut"
  :right-side-bar/flashcards                         "Targetes de memorització"

+ 0 - 2
src/resources/dicts/cs.edn

@@ -106,7 +106,6 @@
  :right-side-bar/page-graph                        "Graf stránky"
  :right-side-bar/block-ref                         "Reference bloku"
  :right-side-bar/graph-view                        "Zobrazení grafu"
- :right-side-bar/all-pages                         "Všechny stránky"
  :right-side-bar/whiteboards                       "Tabule"
  :right-side-bar/flashcards                        "Kartičky"
  :right-side-bar/show-journals                     "Zobrazit deníky"
@@ -424,7 +423,6 @@
  :export-copied-to-clipboard                       "Zkopírováno do schránky!"
  :export-save-to-file                              "Uložit do souboru"
  :all-graphs                                       "Všechny grafy"
- :all-pages                                        "Všechny stránky"
  :all-whiteboards                                  "Všechny tabule"
  :all-files                                        "Všechny soubory"
  :all-journals                                     "Všechny denníky"

+ 0 - 2
src/resources/dicts/de.edn

@@ -1,7 +1,6 @@
 {:all-files "Alle Dateien"
  :all-graphs "Alle Graphen"
  :all-journals "Alle Journale"
- :all-pages "Alle Seiten"
  :all-whiteboards "Alle Whiteboards"
  :auto-heading "Automatische Überschrift"
  :bold "Fett"
@@ -309,7 +308,6 @@
 
  :query/config-property-settings "Einstellungen für diese Query:"
 
- :right-side-bar/all-pages "Alle Seiten"
  :right-side-bar/block-ref "Blockreferenz"
  :right-side-bar/contents "Inhalt"
  :right-side-bar/flashcards "Karteikarten"

+ 2 - 2
src/resources/dicts/en.edn

@@ -111,7 +111,7 @@
  :right-side-bar/page-graph "Page graph"
  :right-side-bar/block-ref "Block references"
  :right-side-bar/graph-view "Graph view"
- :right-side-bar/all-pages "All pages"
+ :right-side-bar/all-pages "Pages"
  :right-side-bar/whiteboards "Whiteboards"
  :right-side-bar/flashcards "Flashcards"
  :right-side-bar/show-journals "Show Journals"
@@ -456,7 +456,7 @@
  :export-copied-to-clipboard "Copied to clipboard!"
  :export-save-to-file "Save to file"
  :all-graphs "All graphs"
- :all-pages "All pages"
+ :all-pages "Pages"
   ;; E.g. 1 Page or 2 Pages
  :all-pages/table-title (fn [total] (str total (if (= total 1) " Page" " Pages")))
  :all-pages/failed-to-delete-pages "These pages had their content deleted but were unable to be deleted: {1}. See javascript console for more details."

+ 0 - 2
src/resources/dicts/es.edn

@@ -1,7 +1,6 @@
 {:all-files                                         "Lista de archivos"
  :all-graphs                                        "Lista de grafos"
  :all-journals                                      "Lista de diarios"
- :all-pages                                         "Lista de páginas"
  :all-whiteboards                                   "Todas las pizarras"
  :auto-heading                                      "Encabezados automáticos"
  :bold                                              "Negrita"
@@ -489,7 +488,6 @@
  :plugin/updating                                   "Actualizando"
  :plugin/up-to-date                                 "Está actualizado {1}"
  :query/config-property-settings                    "Configuración de propiedades para esta consulta:"
- :right-side-bar/all-pages                          "Lista de páginas"
  :right-side-bar/block-ref                          "Referencia de bloque"
  :right-side-bar/contents                           "Contenido"
  :right-side-bar/flashcards                         "Tarjetas de memorización"

+ 0 - 2
src/resources/dicts/fa.edn

@@ -82,7 +82,6 @@
  :right-side-bar/page-graph           "گراف برگه"
  :right-side-bar/block-ref            "ارجاعات بلوک"
  :right-side-bar/graph-view           "نمای گراف"
- :right-side-bar/all-pages            "همه برگه‌ها"
  :right-side-bar/whiteboards          "تخته‌سفیدها"
  :right-side-bar/flashcards           "فلش کارت‌ها"
  :right-side-bar/show-journals        "نمایش روزنگارها"
@@ -289,7 +288,6 @@
  :export-copied-to-clipboard "در بریده‌دان رونوشت شد!"
  :export-save-to-file "ذخیره در پرونده"
  :all-graphs "همهٔ گراف‌ها"
- :all-pages "همهٔ برگه‌ها"
  :all-whiteboards "همه تخته‌سفیدها"
  :all-files "همهٔ پرونده‌ها"
  :all-journals "همهٔ روزنگارها"

+ 0 - 2
src/resources/dicts/fr.edn

@@ -26,7 +26,6 @@
     :right-side-bar/contents "Contenus"
     :right-side-bar/block-ref "Référence des blocs"
     :right-side-bar/graph-view "Vue graphe"
-    :right-side-bar/all-pages "Toutes les pages"
     :right-side-bar/flashcards "Cartes-mémoire"
     :left-side-bar/journals "Journaux"
     :page/make-public "Rendre la page publique"
@@ -57,7 +56,6 @@
     :re-index "Ré-indexer"
     :export-json "Exporter au format JSON"
     :graph "Graphe"
-    :all-pages "Toutes les pages"
     :all-files "Tous les fichiers"
     :all-journals "Tous les journaux"
     :settings "Préférences"

+ 0 - 2
src/resources/dicts/id.edn

@@ -101,7 +101,6 @@
  :right-side-bar/page-graph "Grafik halaman"
  :right-side-bar/block-ref "Referensi blok"
  :right-side-bar/graph-view "Tampilan grafik"
- :right-side-bar/all-pages "Semua halaman"
  :right-side-bar/whiteboards "Papan tulis"
  :right-side-bar/flashcards "Kartu flash"
  :right-side-bar/show-journals "Tampilkan Jurnal"
@@ -422,7 +421,6 @@
  :export-copied-to-clipboard "Disalin ke clipboard!"
  :export-save-to-file "Simpan ke berkas"
  :all-graphs "Semua grafik"
- :all-pages "Semua halaman"
  :all-whiteboards "Semua papan tulis"
  :all-files "Semua berkas"
  :all-journals "Semua jurnal"

+ 0 - 2
src/resources/dicts/it.edn

@@ -28,7 +28,6 @@
  :right-side-bar/page-graph "Grafo della pagina"
  :right-side-bar/block-ref "Riferimento al blocco"
  :right-side-bar/graph-view "Vista del grafo"
- :right-side-bar/all-pages "Tutte le pagine"
  :right-side-bar/show-journals "Mostra diari"
  :left-side-bar/journals "Diario"
  :left-side-bar/nav-favorites "Preferiti"
@@ -118,7 +117,6 @@
  :export-roam-json "Esporta come Roam JSON"
  :export-edn "Esporta come EDN"
  :all-graphs "Tutti i grafi"
- :all-pages "Tutte le pagine"
  :all-files "Tutti i file"
  :all-journals "Tutte le pagine di diario"
  :settings "Impostazioni"

+ 0 - 2
src/resources/dicts/ja.edn

@@ -110,7 +110,6 @@
  :right-side-bar/page-graph "ページグラフ"
  :right-side-bar/block-ref "ブロック参照"
  :right-side-bar/graph-view "グラフビュー"
- :right-side-bar/all-pages "全ページ"
  :right-side-bar/whiteboards "ホワイトボード"
  :right-side-bar/flashcards "フラッシュカード"
  :right-side-bar/show-journals "日誌を表示"
@@ -441,7 +440,6 @@
  :export-copied-to-clipboard "クリップボードにコピーしました"
  :export-save-to-file "ファイルに保存"
  :all-graphs "全グラフ"
- :all-pages "全ページ"
  :all-whiteboards "全てのホワイトボード"
  :all-files "全ファイル"
  :all-journals "全日誌"

+ 0 - 2
src/resources/dicts/ko.edn

@@ -29,7 +29,6 @@
  :right-side-bar/page-graph "페이지 그래프"
  :right-side-bar/block-ref "블록 참조"
  :right-side-bar/graph-view "그래프 뷰"
- :right-side-bar/all-pages "모든 페이지"
  :right-side-bar/flashcards "플래시 카드"
  :left-side-bar/journals "일지"
  :left-side-bar/nav-favorites "즐겨찾기"
@@ -124,7 +123,6 @@
  :export-roam-json "Roam JSON으로 내보내기"
  :export-edn "EDN으로 내보내기"
  :all-graphs "모든 그래프"
- :all-pages "모든 페이지"
  :all-files "모든 파일"
  :all-journals "모든 일지"
  :settings "설정"

+ 0 - 2
src/resources/dicts/nb-no.edn

@@ -31,7 +31,6 @@
  :right-side-bar/page-graph "Sidegraf"
  :right-side-bar/block-ref "Blokkreferanse"
  :right-side-bar/graph-view "Grafvisning"
- :right-side-bar/all-pages "Alle sider"
  :right-side-bar/separator "Høyre sidestolpe størrelsesendring"
  :right-side-bar/show-journals "Vis dagbøker"
  :left-side-bar/journals "Dagbøker"
@@ -117,7 +116,6 @@
  :export-roam-json "Eksporter som Roam JSON"
  :export-edn "Eksporter som EDN"
  :all-graphs "Alle grafer"
- :all-pages "Alle sider"
  :all-files "Alle filer"
  :all-journals "Alle dagbøker"
  :settings "Innstillinger"

+ 0 - 2
src/resources/dicts/nl.edn

@@ -1,7 +1,6 @@
 {:all-files "Alle bestanden"
  :all-graphs "Alle grafieken"
  :all-journals "Alle Journalen"
- :all-pages "Alle pagina's"
  :bold "Vet"
  :cancel "Annuleren"
  :close "Sluiten"
@@ -136,7 +135,6 @@
  :plugin/update-available "Update beschikbaar"
  :plugin/updating "Bijwerken"
 
- :right-side-bar/all-pages "Alle pagina's"
  :right-side-bar/block-ref "Blok verwijzingen"
  :right-side-bar/contents "Inhoud"
  :right-side-bar/graph-view "Grafiekweergave"

+ 0 - 2
src/resources/dicts/pl.edn

@@ -30,7 +30,6 @@
  :right-side-bar/page-graph "Graf strony"
  :right-side-bar/block-ref "Referencja bloku"
  :right-side-bar/graph-view "Widok grafu"
- :right-side-bar/all-pages "Wszystkie strony"
  :right-side-bar/flashcards "Fiszki"
  :right-side-bar/show-journals "Pokaż dzienniki"
  :left-side-bar/journals "Dzienniki"
@@ -136,7 +135,6 @@
  :export-roam-json "Eksportuj jako Roam JSON"
  :export-edn "Eksportuj jako EDN"
  :all-graphs "Wszystkie grafy"
- :all-pages "Wszystkie strony"
  :all-files "Wszystkie pliki"
  :all-journals "Wszystkie dzienniki"
  :settings "Ustawienia"

+ 0 - 2
src/resources/dicts/pt-br.edn

@@ -107,7 +107,6 @@
  :right-side-bar/page-graph "Grafo da página"
  :right-side-bar/block-ref "Referências de bloco"
  :right-side-bar/graph-view "Visualização de grafo"
- :right-side-bar/all-pages "Todas as páginas"
  :right-side-bar/flashcards "Flashcards"
  :right-side-bar/show-journals "Mostrar diários"
  :right-side-bar/separator "Manipulador de redimensionamento da barra lateral direita"
@@ -425,7 +424,6 @@
  :export-copied-to-clipboard "Copiado para a área de transferência!"
  :export-save-to-file "Salvar em arquivo"
  :all-graphs "Todos os grafos"
- :all-pages "Todas as páginas"
  :all-whiteboards "Todos os whiteboards"
  :all-files "Todos os arquivos"
  :all-journals "Todos os diários"

+ 0 - 2
src/resources/dicts/pt-pt.edn

@@ -42,7 +42,6 @@
  :right-side-bar/page-graph "Grafo da página"
  :right-side-bar/block-ref "Referência de bloco"
  :right-side-bar/graph-view "Vista do grafo"
- :right-side-bar/all-pages "Todas as páginas"
  :right-side-bar/whiteboards "Quadros brancos"
  :right-side-bar/flashcards "Flashcards"
  :right-side-bar/show-journals "Mostrar págs. diárias"
@@ -175,7 +174,6 @@
  :export-roam-json "Exportar como JSON do Roam"
  :export-edn "Exportar como EDN"
  :all-graphs "Todos os grafos"
- :all-pages "Todas as páginas"
  :all-whiteboards "Todos os quadros brancos"
  :all-files "Todos os ficheiros"
  :all-journals "Todas as págs. diárias"

+ 0 - 2
src/resources/dicts/ru.edn

@@ -48,7 +48,6 @@
  :right-side-bar/page-graph                            "Граф страницы"
  :right-side-bar/block-ref                             "Ссылка на блок"
  :right-side-bar/graph-view                            "Визуальный граф"
- :right-side-bar/all-pages                             "Все страницы"
  :right-side-bar/whiteboards                           "Интерактивные доски"
  :right-side-bar/flashcards                            "Карточки"
  :right-side-bar/show-journals                         "Показать журналы"
@@ -306,7 +305,6 @@
  :export-roam-json                                     "Экспортировать как Roam JSON"
  :export-edn                                           "Экспортировать как EDN"
  :all-graphs                                           "Все графы"
- :all-pages                                            "Все страницы"
  :all-whiteboards                                      "Все интерактивные доски"
  :all-files                                            "Все файлы"
  :all-journals                                         "Все журналы"

+ 0 - 2
src/resources/dicts/sk.edn

@@ -106,7 +106,6 @@
  :right-side-bar/page-graph                        "Graf stránok"
  :right-side-bar/block-ref                         "Referencie bloku"
  :right-side-bar/graph-view                        "Zobrazenie grafu"
- :right-side-bar/all-pages                         "Všetky stránky"
  :right-side-bar/whiteboards                       "Tabule"
  :right-side-bar/flashcards                        "Kartičky"
  :right-side-bar/show-journals                     "Zobraziť denníky"
@@ -425,7 +424,6 @@
  :export-copied-to-clipboard                       "Skopírované do schránky!"
  :export-save-to-file                              "Uložiť do súboru"
  :all-graphs                                       "Všetky grafy"
- :all-pages                                        "Všetky stránky"
  :all-whiteboards                                  "Všetky tabule"
  :all-files                                        "Všetky súbory"
  :all-journals                                     "Všetky denníky"

+ 0 - 2
src/resources/dicts/tr.edn

@@ -110,7 +110,6 @@
  :right-side-bar/page-graph "Sayfa grafı"
  :right-side-bar/block-ref "Blok referansı"
  :right-side-bar/graph-view "Graf görünümü"
- :right-side-bar/all-pages "Bütün sayfalar"
  :right-side-bar/whiteboards "Beyaz tahtalar"
  :right-side-bar/flashcards "Bilgi kartları"
  :right-side-bar/show-journals "Günlükleri Göster"
@@ -437,7 +436,6 @@
  :export-copied-to-clipboard "Panoya kopyalandı!"
  :export-save-to-file "Dosyaya kaydet"
  :all-graphs "Tüm graflar"
- :all-pages "Tüm sayfalar"
  :all-whiteboards "Tüm beyaz tahtalar"
  :all-files "Tüm dosyalar"
  :all-journals "Bütün günlükler"

+ 0 - 2
src/resources/dicts/uk.edn

@@ -43,7 +43,6 @@
  :right-side-bar/page-graph "Графік сторінки"
  :right-side-bar/block-ref "Посилання на блоки"
  :right-side-bar/graph-view "Вигляд графіка"
- :right-side-bar/all-pages "Всі сторінки"
  :right-side-bar/whiteboards "Дошки"
  :right-side-bar/flashcards "Флеш-картки"
  :right-side-bar/show-journals "Показати журнали"
@@ -198,7 +197,6 @@
  :export-roam-json "Експортувати як Roam JSON"
  :export-edn "Експортувати як EDN"
  :all-graphs "Всі графіки"
- :all-pages "Всі сторінки"
  :all-whiteboards "Всі дошки"
  :all-files "Всі файли"
  :all-journals "Всі журнали"

+ 0 - 2
src/resources/dicts/zh-cn.edn

@@ -99,7 +99,6 @@
  :right-side-bar/page-graph "页面图谱"
  :right-side-bar/block-ref "块引用"
  :right-side-bar/graph-view "图谱视角"
- :right-side-bar/all-pages "全部页面"
  :right-side-bar/flashcards "记忆卡片"
  :right-side-bar/separator "调整右侧边栏大小"
  :right-side-bar/whiteboards "白板"
@@ -216,7 +215,6 @@
  :all-journals "日记"
  :export "导出"
  :all-graphs "所有图谱"
- :all-pages "所有页面"
  :all-files "所有文件"
  :settings "设置"
  :settings-of-plugins "插件设置"

+ 0 - 2
src/resources/dicts/zh-hant.edn

@@ -43,7 +43,6 @@
  :right-side-bar/page-graph "頁面圖表"
  :right-side-bar/block-ref "區塊引用"
  :right-side-bar/graph-view "圖表顯示"
- :right-side-bar/all-pages "所有頁面"
  :right-side-bar/whiteboards "白板"
  :right-side-bar/flashcards "卡片"
  :right-side-bar/show-journals "顯示日記頁面"
@@ -179,7 +178,6 @@
  :export-roam-json "以 Roam JSON 格式匯出"
  :export-edn "以 EDN 格式匯出"
  :all-graphs "所有圖表"
- :all-pages "所有分頁"
  :all-whiteboards "所有白板"
  :all-files "所有資料"
  :all-journals "所有日記"