Browse Source

Merge branch 'master' into feat/capacitor-new

charlie 4 months ago
parent
commit
b6e3e98990
49 changed files with 569 additions and 434 deletions
  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
         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
       - 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
       - 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:
   e2e-test:
     # TODO: Re-enable when ready to enable tests for file graphs
     # TODO: Re-enable when ready to enable tests for file graphs

+ 1 - 0
clj-e2e/deps.edn

@@ -5,6 +5,7 @@
                                     :sha "8571fae7c51400ac61c8b1026cbfba68279bc461"}
                                     :sha "8571fae7c51400ac61c8b1026cbfba68279bc461"}
         ;; io.github.zmedelis/bosquet {:mvn/version "2025.03.28"}
         ;; io.github.zmedelis/bosquet {:mvn/version "2025.03.28"}
         org.clj-commons/claypoole          {:mvn/version "1.2.2"}
         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"}}
         clj-time/clj-time                  {:mvn/version "0.15.2"}}
  :aliases
  :aliases
  {:build {:deps {io.github.clojure/tools.build {:mvn/version "0.10.5"}}
  {: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
   (:require
    [clojure.string :as string]
    [clojure.string :as string]
    [clojure.test :refer [deftest testing is use-fixtures]]
    [clojure.test :refer [deftest testing is use-fixtures]]
+   [jsonista.core :as json]
+   [logseq.e2e.assert :as assert]
    [logseq.e2e.fixtures :as fixtures]
    [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.main :as w]
    [wally.repl :as repl]))
    [wally.repl :as repl]))
 
 
@@ -34,12 +39,79 @@
   (let [tag (name tag)
   (let [tag (name tag)
         ns' (string/split tag #"\.")
         ns' (string/split tag #"\.")
         ns? (and (seq ns') (= (count ns') 2))
         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
 (deftest apis-related-test
   (testing "block related apis"
   (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"}
                              :desc "Exclude built-in pages"}
    :set-diff {:alias :s
    :set-diff {:alias :s
               :desc "Use set to reduce noisy diff caused by ordering"}
               :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]
 (defn -main [args]
   (let [{options :opts args' :args} (cli/parse-args args {:spec spec})
   (let [{options :opts args' :args} (cli/parse-args args {:spec spec})
@@ -31,9 +35,11 @@
             (js/process.exit 1))
             (js/process.exit 1))
         conn (apply sqlite-cli/open-db! (sqlite-cli/->open-db-args graph-dir))
         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))
         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
         prepare-export-to-diff
         (fn [m]
         (fn [m]
           (cond->
           (cond->

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

@@ -19,7 +19,7 @@
   "Options spec"
   "Options spec"
   {:help {:alias :h
   {:help {:alias :h
           :desc "Print help"}
           :desc "Print help"}
-   :include-timestamps? {:alias :t
+   :include-timestamps? {:alias :T
                          :desc "Include timestamps in export"}
                          :desc "Include timestamps in export"}
    :file {:alias :f
    :file {:alias :f
           :desc "Saves edn to file"}
           :desc "Saves edn to file"}
@@ -31,7 +31,11 @@
    :exclude-built-in-pages? {:alias :b
    :exclude-built-in-pages? {:alias :b
                              :desc "Exclude built-in pages"}
                              :desc "Exclude built-in pages"}
    :exclude-files? {:alias :F
    :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]
 (defn -main [args]
   (let [{options :opts args' :args} (cli/parse-args args {:spec spec})
   (let [{options :opts args' :args} (cli/parse-args args {:spec spec})
@@ -41,8 +45,10 @@
                           (cli/format-opts {:spec spec})))
                           (cli/format-opts {:spec spec})))
             (js/process.exit 1))
             (js/process.exit 1))
         conn (apply sqlite-cli/open-db! (sqlite-cli/->open-db-args graph-dir))
         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)
     (if (:file options)
       (do
       (do
         (println "Exported" (count (:properties export-map)) "properties,"
         (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]
   (let [remove-block-temp-f (fn [m]
                               (->> (remove (fn [[k _v]] (= "block.temp" (namespace k))) m)
                               (->> (remove (fn [[k _v]] (= "block.temp" (namespace k))) m)
                                    (into {})))]
                                    (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
 (defn assert-no-entities
   [tx-data]
   [tx-data]
@@ -372,7 +380,7 @@
         parents'))))
         parents'))))
 
 
 (def get-block-children-ids common-initial-data/get-block-children-ids)
 (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
 (defn- get-sorted-page-block-ids
   [db page-id]
   [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))))
       (update block :block/link (fn [link] (d/pull db '[*] (:db/id link))))
       block)))
       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
 (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?]
   [db block-uuid & {:keys [include-collapsed-children?]
                     :or {include-collapsed-children? true}}]
                     :or {include-collapsed-children? true}}]
   (when-let [eid (:db/id (d/entity db [:block/uuid block-uuid]))]
   (when-let [eid (:db/id (d/entity db [:block/uuid block-uuid]))]
@@ -140,7 +100,6 @@
                             (when (or include-collapsed-children?
                             (when (or include-collapsed-children?
                                       (not (:block/collapsed? e))
                                       (not (:block/collapsed? e))
                                       (common-entity-util/page? e))
                                       (common-entity-util/page? e))
-
                               (:block/_parent e)))) eids-to-expand)
                               (:block/_parent e)))) eids-to-expand)
                 uuids-to-add (keep :block/uuid children)]
                 uuids-to-add (keep :block/uuid children)]
             (vswap! seen (partial apply conj) uuids-to-add)
             (vswap! seen (partial apply conj) uuids-to-add)
@@ -148,13 +107,27 @@
       @seen)))
       @seen)))
 
 
 (defn get-block-children
 (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?]}])}
   {:arglists '([db block-uuid & {:keys [include-collapsed-children?]}])}
   [db block-uuid & {:as opts}]
   [db block-uuid & {:as opts}]
   (let [ids (get-block-children-ids db block-uuid opts)]
   (let [ids (get-block-children-ids db block-uuid opts)]
     (when (seq ids)
     (when (seq ids)
       (map (fn [id] (d/entity db [:block/uuid id])) 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
 (defn- with-raw-title
   [m entity]
   [m entity]
   (if-let [raw-title (:block/raw-title 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
    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"
    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?
 ;; TODO: How to detect these idents don't conflict with existing? :db/add?
 (defn- create-all-idents
 (defn- create-all-idents
   [properties classes {:keys [graph-namespace]}]
   [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 {}))
                              (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)
         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 {}))
                           (into {}))
         _ (assert (= (count (set (vals class-idents))) (count classes)) "All class db-idents must be unique")
         _ (assert (= (count (set (vals class-idents))) (count classes)) "All class db-idents must be unique")
         all-idents (merge property-idents class-idents)]
         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)
     ;; (prn :rproperties referenced-properties)
     undefined))
     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 #{})
   (let [pvalue-known-uuids (atom #{})
         _ (walk/postwalk (fn [f]
         _ (walk/postwalk (fn [f]
                            (if (and (map? f) (:build/property-value f) (:block/uuid f))
                            (if (and (map? f) (:build/property-value f) (:block/uuid f))
@@ -806,6 +806,11 @@
                      (mapcat get-pvalue-uuids (vals properties))
                      (mapcat get-pvalue-uuids (vals properties))
                      (mapcat (comp get-pvalue-uuids :page) pages-and-blocks)
                      (mapcat (comp get-pvalue-uuids :page) pages-and-blocks)
                      (mapcat #(sqlite-build/extract-from-blocks (:blocks %) get-pvalue-uuids) 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)]
     (set/difference ref-uuids known-uuids)))
     (set/difference ref-uuids known-uuids)))
 
 
@@ -842,10 +847,10 @@
   "Checks that export map is usable by sqlite.build including checking that
   "Checks that export map is usable by sqlite.build including checking that
    all referenced properties and classes are defined. Checks related to properties and
    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"
    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*)]
   (let [export-map (remove-namespaced-keys export-map*)]
     (when-not (seq (:exclude-namespaces graph-options)) (sqlite-build/validate-options 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-> {}
           undefined (cond-> {}
                       (empty? (:exclude-namespaces graph-options))
                       (empty? (:exclude-namespaces graph-options))
                       (merge (find-undefined-classes-and-properties export-map))
                       (merge (find-undefined-classes-and-properties export-map))
@@ -875,10 +880,10 @@
         export-map (patch-invalid-keywords export-map*)]
         export-map (patch-invalid-keywords export-map*)]
     (if (get-in options [:graph-options :catch-validation-errors?])
     (if (get-in options [:graph-options :catch-validation-errors?])
       (try
       (try
-        (ensure-export-is-valid export-map options)
+        (ensure-export-is-valid db export-map options)
         (catch ExceptionInfo e
         (catch ExceptionInfo e
           (println "Caught error:" 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)))
     (assoc export-map ::export-type export-type)))
 
 
 ;; Import fns
 ;; Import fns

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

@@ -5,7 +5,8 @@
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.sqlite.build :as sqlite-build]
             [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
 (deftest build-tags
   (let [conn (db-test/create-conn)
   (let [conn (db-test/create-conn)
@@ -244,4 +245,15 @@
     (is (= {:block/tags [:user.class/C1]}
     (is (= {:block/tags [:user.class/C1]}
            (-> (db-test/find-block-by-content @conn "u1")
            (-> (db-test/find-block-by-content @conn "u1")
                db-test/readable-properties
                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]]
   (reduce (fn [acc [asset-name asset-uuid]]
             (let [new-title (string/replace acc
             (let [new-title (string/replace acc
                                             (re-pattern (str "!?\\[[^\\]]*?\\]\\([^\\)]*?"
                                             (re-pattern (str "!?\\[[^\\]]*?\\]\\([^\\)]*?"
-                                                             asset-name
+                                                             (common-util/escape-regex-chars asset-name)
                                                              "\\)(\\{[^}]*\\})?"))
                                                              "\\)(\\{[^}]*\\})?"))
                                             (page-ref/->page-ref asset-uuid))]
                                             (page-ref/->page-ref asset-uuid))]
               (when (string/includes? new-title asset-name)
               (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)
     (assert (ds/outliner-txs-state? *txs-state)
             "db should be satisfied outliner-tx-state?")
             "db should be satisfied outliner-tx-state?")
     (let [block-id (:block/uuid this)
     (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])]
           page-tx (let [block (d/entity db [:block/uuid block-id])]
                     (when (:block/pre-block? block)
                     (when (:block/pre-block? block)
                       (when-let [id (:db/id (:block/page block))]
                       (when-let [id (:db/id (:block/page block))]
@@ -870,12 +866,12 @@
                    :block/order block-order}
                    :block/order block-order}
                    (not (ldb/page? block))
                    (not (ldb/page? block))
                    (assoc :block/page target-page))]
                    (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]
                              (keep (fn [id]
-                                     (let [child (d/entity db [:block/uuid id])]
+                                     (let [child (d/entity db id)]
                                        (when-not (ldb/page? child)
                                        (when-not (ldb/page? child)
-                                         {:block/uuid id
+                                         {:block/uuid (:block/uuid child)
                                           :block/page target-page}))) children-ids)))
                                           :block/page target-page}))) children-ids)))
         target-from-property (:logseq.property/created-from-property target-block)
         target-from-property (:logseq.property/created-from-property target-block)
         block-from-property (:logseq.property/created-from-property 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
   parent: IEntityID
   title: string
   title: string
   content?: string // @deprecated. Use :title instead!
   content?: string // @deprecated. Use :title instead!
-  page: IEntityID
+  page: IEntityID // owner page
   createdAt: number
   createdAt: number
   updatedAt: number
   updatedAt: number
+  ident?: string // ident for property block
   properties?: Record<string, any>
   properties?: Record<string, any>
   'collapsed?': boolean
   'collapsed?': boolean
 
 
   // optional fields in dummy page
   // optional fields in dummy page
-  left?: IEntityID
   anchor?: string
   anchor?: string
   body?: any
   body?: any
   children?: Array<BlockEntity | BlockUUIDTuple>
   children?: Array<BlockEntity | BlockUUIDTuple>
@@ -812,7 +812,7 @@ export interface IEditorProxy extends Record<string, any> {
   upsertProperty: (
   upsertProperty: (
     key: string,
     key: string,
     schema?: Partial<{
     schema?: Partial<{
-      type: 'default' | 'map' | 'number' | 'keyword' | 'node' | 'date' | 'checkbox' | string,
+      type: 'default' | 'number' | 'node' | 'date' | 'checkbox' | 'url' | string,
       cardinality: 'many' | 'one',
       cardinality: 'many' | 'one',
       hide: boolean
       hide: boolean
       public: boolean
       public: boolean
@@ -831,7 +831,7 @@ export interface IEditorProxy extends Record<string, any> {
 
 
   removeBlockProperty: (block: BlockIdentity, key: string) => Promise<void>
   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>
   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]
   (:require ["fs" :as fs]
             [babashka.cli :as cli]
             [babashka.cli :as cli]
             [clojure.edn :as edn]
             [clojure.edn :as edn]
+            [clojure.pprint :as pprint]
             [clojure.set :as set]
             [clojure.set :as set]
             [clojure.string :as string]
             [clojure.string :as string]
             [clojure.walk :as w]
             [clojure.walk :as w]
@@ -20,6 +21,7 @@
             [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
+            [logseq.db.sqlite.export :as sqlite-export]
             [logseq.outliner.cli :as outliner-cli]
             [logseq.outliner.cli :as outliner-cli]
             [nbb.classpath :as cp]
             [nbb.classpath :as cp]
             [nbb.core :as nbb]))
             [nbb.core :as nbb]))
@@ -352,51 +354,17 @@
    :config {:alias :c
    :config {:alias :c
             :coerce edn/read-string
             :coerce edn/read-string
             :desc "EDN map to add to config.edn"}
             :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
    :subset {:alias :s
             :desc "Only generate a subset of data for testing purposes"}
             :desc "Only generate a subset of data for testing purposes"}
    :verbose {:alias :v
    :verbose {:alias :v
              :desc "Verbose mode"}})
              :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]
 (defn -main [args]
   (let [[graph-dir] args
   (let [[graph-dir] args
@@ -419,7 +387,7 @@
     (d/transact! conn init-tx)
     (d/transact! conn init-tx)
     (d/transact! conn block-props-tx)
     (d/transact! conn block-props-tx)
     (when (:verbose options) (println "Transacted" (count (d/datoms @conn :eavt)) "datoms"))
     (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 "!"))))
     (println "Created graph" (str db-name "!"))))
 
 
 (when (= nbb/*file* (nbb/invoked-file))
 (when (= nbb/*file* (nbb/invoked-file))

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

@@ -43,8 +43,8 @@
                                            ldb/sort-by-order
                                            ldb/sort-by-order
                                            last)
                                            last)
                            target (or last-child library-page)
                            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)))
                        (set-selected-choices! (conj selected-choices chosen)))
                      (do
                      (do
                        (db/transact! (state/get-current-repo)
                        (db/transact! (state/get-current-repo)

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

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

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

@@ -24,7 +24,7 @@
   entity pull pull-many]
   entity pull pull-many]
 
 
  [frontend.db.model
  [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-parent get-block-parents parents-collapsed?
   get-block-immediate-children get-block-page
   get-block-immediate-children get-block-page
   get-file file-exists?  get-files-full
   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)]
   (when-let [db (conn/get-db repo)]
     (ldb/get-children db block-uuid)))
     (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
 (defn get-block-and-children
   [repo block-uuid & {:as opts}]
   [repo block-uuid & {:as opts}]
   (let [db (conn/get-db repo)]
   (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)
              tag-properties (->> (d/datoms db :avet :logseq.property.class/properties id)
                                  (mapcat (fn [d]
                                  (mapcat (fn [d]
                                            [[:db/retract (:e d) (:a d) (:v 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]
          (concat [new-property]
                  tag-properties
                  tag-properties
+                 other-properties-tx
                  retract-property-attrs
                  retract-property-attrs
                  (mapcat
                  (mapcat
                   (fn [d]
                   (fn [d]

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

@@ -5,42 +5,82 @@
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.frontend.validate :as db-validate]))
             [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!
 (defn- fix-invalid-blocks!
   [conn errors]
   [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
                          (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)
     (when (seq tx-data)
       (ldb/transact! conn tx-data {:fix-db? true}))))
       (ldb/transact! conn tx-data {:fix-db? true}))))
 
 

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

@@ -61,11 +61,17 @@
   [conn]
   [conn]
   (some->> (d/datoms @conn :eavt)
   (some->> (d/datoms @conn :eavt)
            (map (fn [{:keys [e a v t]}]
            (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)
                     (d/datom e a (str "debug " e) t)
+
+                    :else
                     (d/datom e a v t))))))
                     (d/datom e a v t))))))

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

@@ -83,14 +83,6 @@
 (defn get-caller-plugin-id
 (defn get-caller-plugin-id
   [] (gobj/get js/window "$$callerPluginID"))
   [] (gobj/get js/window "$$callerPluginID"))
 
 
-(defn- sanitize-user-property-name
-  [k]
-  (if (string? k)
-    (-> k (string/trim)
-        (string/replace #"^[:_]+" "")
-        (string/lower-case))
-    k))
-
 ;; helpers
 ;; helpers
 (defn ^:export install-plugin-hook
 (defn ^:export install-plugin-hook
   [pid hook ^js opts]
   [pid hook ^js opts]
@@ -723,10 +715,12 @@
                 (db-async/<get-block repo page-uuid)))]
                 (db-async/<get-block repo page-uuid)))]
     block))
     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)
     (when (string/blank? block-uuid-or-page-name)
       (throw (js/Error. "Page title or block UUID shouldn't be empty.")))
       (throw (js/Error. "Page title or block UUID shouldn't be empty.")))
+
     (p/let [block? (util/uuid-string? (str block-uuid-or-page-name))
     (p/let [block? (util/uuid-string? (str block-uuid-or-page-name))
             block (<pull-block (str block-uuid-or-page-name))]
             block (<pull-block (str block-uuid-or-page-name))]
       (if (and block? (not block))
       (if (and block? (not block))
@@ -735,41 +729,45 @@
                 [page-name block-uuid] (if (util/uuid-string? block-uuid-or-page-name)
                 [page-name block-uuid] (if (util/uuid-string? block-uuid-or-page-name)
                                          [nil (uuid block-uuid-or-page-name)]
                                          [nil (uuid block-uuid-or-page-name)]
                                          [block-uuid-or-page-name nil])
                                          [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)
                 insert-at-first-child? (not= block-uuid' block-uuid)
                 [sibling? before?] (if insert-at-first-child?
                 [sibling? before?] (if insert-at-first-child?
                                      [true true]
                                      [true true]
                                      [sibling before])
                                      [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)))))))
           (bean/->js (sdk-utils/normalize-keyword-for-json new-block)))))))
 
 
 (def ^:export insert_batch_block
 (def ^:export insert_batch_block
@@ -883,31 +881,26 @@
           nil)))))
           nil)))))
 
 
 ;; properties (db only)
 ;; 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
 (defn -get-property
   [^js plugin k]
   [^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'
       (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))))
               p (db-utils/pull k)] p))))
 
 
 (defn ^:export get_property
 (defn ^:export get_property
   [k]
   [k]
   (this-as this
   (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
 (defn ^:export upsert_property
   "schema:
   "schema:
-    {:type :default | :keyword | :map | :date | :checkbox
+    {:type :default | :number | :date | :datetime | :checkbox | :url | :node
      :cardinality :many | :one
      :cardinality :many | :one
      :hide? true
      :hide? true
      :view-context :page
      :view-context :page
@@ -916,87 +909,96 @@
   [k ^js schema ^js opts]
   [k ^js schema ^js opts]
   (this-as this
   (this-as this
            (when-let [k' (and (string? k) (keyword k))]
            (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)) {})
                (p/let [opts (or (some-> opts (bean/->clj)) {})
-                       name (or (:name opts) (some-> (str k) (string/trim)))
                        k (if (qualified-keyword? k') k'
                        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)
                        schema (or (some-> schema (bean/->clj)
                                           (update-keys #(if (contains? #{:hide :public} %)
                                           (update-keys #(if (contains? #{:hide :public} %)
                                                           (keyword (str (name %) "?")) %))) {})
                                                           (keyword (str (name %) "?")) %))) {})
                        schema (cond-> schema
                        schema (cond-> schema
                                 (string? (:cardinality schema))
                                 (string? (:cardinality schema))
-                                (update :cardinality keyword)
+                                (-> (assoc :db/cardinality (keyword (:cardinality schema)))
+                                  (dissoc :cardinality))
+
                                 (string? (:type schema))
                                 (string? (:type schema))
                                 (-> (assoc :logseq.property/type (keyword (:type schema)))
                                 (-> (assoc :logseq.property/type (keyword (:type schema)))
                                     (dissoc :type)))
                                     (dissoc :type)))
                        p (db-property-handler/upsert-property! k schema
                        p (db-property-handler/upsert-property! k schema
                                                                (cond-> opts
                                                                (cond-> opts
                                                                  name
                                                                  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)))))))
                  (bean/->js (sdk-utils/normalize-keyword-for-json p)))))))
 
 
 (defn ^:export remove_property
 (defn ^:export remove_property
   [k]
   [k]
   (this-as this
   (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
 ;; block properties
 (defn ^:export upsert_block_property
 (defn ^:export upsert_block_property
-  [block-uuid keyname value]
+  [block-uuid key ^js value]
   (this-as this
   (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
 (defn ^:export remove_block_property
   [block-uuid key]
   [block-uuid key]
   (this-as this
   (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
 (defn ^:export get_block_property
   [block-uuid key]
   [block-uuid key]
   (this-as this
   (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
 (def ^:export get_block_properties
   (fn [block-uuid]
   (fn [block-uuid]

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

@@ -16,124 +16,171 @@
             [frontend.modules.outliner.ui :as ui-outliner-tx]
             [frontend.modules.outliner.ui :as ui-outliner-tx]
             [frontend.state :as state]
             [frontend.state :as state]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
+            [logseq.db.frontend.db-ident :as db-ident]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.sdk.utils :as sdk-utils]
             [logseq.sdk.utils :as sdk-utils]
             [promesa.core :as p]))
             [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
 (defn convert?to-built-in-property-name
   [property-name]
   [property-name]
   (if (and (not (qualified-keyword? property-name))
   (if (and (not (qualified-keyword? property-name))
-           (contains? #{:background-color} property-name))
+        (contains? #{:background-color} property-name))
     (keyword :logseq.property property-name)
     (keyword :logseq.property property-name)
     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
 ;; 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
 ;; 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
 ;; 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
 ;; find a property's ident by looking up the property in the db by its title
 (defn get-db-ident-for-user-property-name
 (defn get-db-ident-for-user-property-name
   "Finds a property :db/ident for a given 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
 (defn into-readable-db-properties
   [properties]
   [properties]
   (some-> 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
 (defn into-properties
   ([block] (into-properties (state/get-current-repo) block))
   ([block] (into-properties (state/get-current-repo) block))
   ([repo block]
   ([repo block]
    (if (some-> repo (config/db-based-graph?))
    (if (some-> repo (config/db-based-graph?))
      (let [props (some->> block
      (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 (update block :block/properties merge props)
            block (apply dissoc (concat [block] (keys props)))]
            block (apply dissoc (concat [block] (keys props)))]
        block)
        block)
      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!
 (defn infer-property-value-type-to-save!
   [ident value]
   [ident value]
-  (let [multi? (coll? value)
+  (let [as-json? (coll? value)
         value-handle
         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 %)))
                             (p/then #(:db/id %)))
-                        id))))
+                          id))))
                 (p/all)
                 (p/all)
                 (p/then (fn [vs] [ident :logseq.property/empty-placeholder vs true])))
                 (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
       (let [type (cond
                    (boolean? value) :checkbox
                    (boolean? value) :checkbox
                    (number? value) :number
                    (number? value) :number
-                   (coll? value) :node
+                   (coll? value) :string
                    :else :default)
                    :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
         (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!
 (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]
            (fn [props]
              (->> 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 []
            (fn []
              (when (seq @*properties-page-refs)
              (when (seq @*properties-page-refs)
                (doseq [[ident refs] @*properties-page-refs]
                (doseq [[ident refs] @*properties-page-refs]
                  (-> (property-handler/remove-block-property! (state/get-current-repo) block-id ident)
                  (-> (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}
                            {:outliner-op :set-block-properties}
                            (doseq [eid refs]
                            (doseq [eid refs]
                              (when (number? eid)
                              (when (number? eid)
                                (property-handler/set-block-property!
                                (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!
 (defn <sync-children-blocks!
   [block]
   [block]
   (when block
   (when block
     (db-async/<get-block (state/get-current-repo)
     (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
 (defn get_block
   [id-or-uuid ^js opts]
   [id-or-uuid ^js opts]
@@ -141,19 +188,19 @@
                      (db-utils/pull id-or-uuid)
                      (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))))]
                      (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)))
     (when (or (true? (some-> opts (.-includePage)))
-              (not (contains? block :block/name)))
+            (not (contains? block :block/name)))
       (when-let [uuid (:block/uuid block)]
       (when-let [uuid (:block/uuid block)]
         (let [{:keys [includeChildren]} (bean/->clj opts)
         (let [{:keys [includeChildren]} (bean/->clj opts)
               repo (state/get-current-repo)
               repo (state/get-current-repo)
               block (if includeChildren
               block (if includeChildren
                       ;; nested children results
                       ;; nested children results
                       (let [blocks (->> (db-model/get-block-and-children repo uuid)
                       (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)))
                         (first (outliner-tree/blocks->vec-tree blocks uuid)))
                       ;; attached shallow children
                       ;; attached shallow children
                       (assoc block :block/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)]
               block (into-properties repo block)]
           (bean/->js (sdk-utils/normalize-keyword-for-json block)))))))
           (bean/->js (sdk-utils/normalize-keyword-for-json block)))))))

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

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

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

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

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

@@ -1,7 +1,6 @@
 {:all-files                                         "Llista d'arxius"
 {:all-files                                         "Llista d'arxius"
  :all-graphs                                        "Llista de grafs"
  :all-graphs                                        "Llista de grafs"
  :all-journals                                      "Llista de diaris"
  :all-journals                                      "Llista de diaris"
- :all-pages                                         "Llista de pàgines"
  :all-whiteboards                                   "Totes les pissarres"
  :all-whiteboards                                   "Totes les pissarres"
  :auto-heading                                      "Encapçalaments automàtics"
  :auto-heading                                      "Encapçalaments automàtics"
  :bold                                              "Negreta"
  :bold                                              "Negreta"
@@ -490,7 +489,6 @@
  :plugin/updating                                   "Actualitzant"
  :plugin/updating                                   "Actualitzant"
  :plugin/up-to-date                                 "Està actualitzat {1}"
  :plugin/up-to-date                                 "Està actualitzat {1}"
  :query/config-property-settings                    "Configuració de propietats per aquesta consulta:"
  :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/block-ref                          "Referència de bloc"
  :right-side-bar/contents                           "Contingut"
  :right-side-bar/contents                           "Contingut"
  :right-side-bar/flashcards                         "Targetes de memorització"
  :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/page-graph                        "Graf stránky"
  :right-side-bar/block-ref                         "Reference bloku"
  :right-side-bar/block-ref                         "Reference bloku"
  :right-side-bar/graph-view                        "Zobrazení grafu"
  :right-side-bar/graph-view                        "Zobrazení grafu"
- :right-side-bar/all-pages                         "Všechny stránky"
  :right-side-bar/whiteboards                       "Tabule"
  :right-side-bar/whiteboards                       "Tabule"
  :right-side-bar/flashcards                        "Kartičky"
  :right-side-bar/flashcards                        "Kartičky"
  :right-side-bar/show-journals                     "Zobrazit deníky"
  :right-side-bar/show-journals                     "Zobrazit deníky"
@@ -424,7 +423,6 @@
  :export-copied-to-clipboard                       "Zkopírováno do schránky!"
  :export-copied-to-clipboard                       "Zkopírováno do schránky!"
  :export-save-to-file                              "Uložit do souboru"
  :export-save-to-file                              "Uložit do souboru"
  :all-graphs                                       "Všechny grafy"
  :all-graphs                                       "Všechny grafy"
- :all-pages                                        "Všechny stránky"
  :all-whiteboards                                  "Všechny tabule"
  :all-whiteboards                                  "Všechny tabule"
  :all-files                                        "Všechny soubory"
  :all-files                                        "Všechny soubory"
  :all-journals                                     "Všechny denníky"
  :all-journals                                     "Všechny denníky"

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

@@ -1,7 +1,6 @@
 {:all-files "Alle Dateien"
 {:all-files "Alle Dateien"
  :all-graphs "Alle Graphen"
  :all-graphs "Alle Graphen"
  :all-journals "Alle Journale"
  :all-journals "Alle Journale"
- :all-pages "Alle Seiten"
  :all-whiteboards "Alle Whiteboards"
  :all-whiteboards "Alle Whiteboards"
  :auto-heading "Automatische Überschrift"
  :auto-heading "Automatische Überschrift"
  :bold "Fett"
  :bold "Fett"
@@ -309,7 +308,6 @@
 
 
  :query/config-property-settings "Einstellungen für diese Query:"
  :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/block-ref "Blockreferenz"
  :right-side-bar/contents "Inhalt"
  :right-side-bar/contents "Inhalt"
  :right-side-bar/flashcards "Karteikarten"
  :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/page-graph "Page graph"
  :right-side-bar/block-ref "Block references"
  :right-side-bar/block-ref "Block references"
  :right-side-bar/graph-view "Graph view"
  :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/whiteboards "Whiteboards"
  :right-side-bar/flashcards "Flashcards"
  :right-side-bar/flashcards "Flashcards"
  :right-side-bar/show-journals "Show Journals"
  :right-side-bar/show-journals "Show Journals"
@@ -456,7 +456,7 @@
  :export-copied-to-clipboard "Copied to clipboard!"
  :export-copied-to-clipboard "Copied to clipboard!"
  :export-save-to-file "Save to file"
  :export-save-to-file "Save to file"
  :all-graphs "All graphs"
  :all-graphs "All graphs"
- :all-pages "All pages"
+ :all-pages "Pages"
   ;; E.g. 1 Page or 2 Pages
   ;; E.g. 1 Page or 2 Pages
  :all-pages/table-title (fn [total] (str total (if (= total 1) " Page" " 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."
  :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-files                                         "Lista de archivos"
  :all-graphs                                        "Lista de grafos"
  :all-graphs                                        "Lista de grafos"
  :all-journals                                      "Lista de diarios"
  :all-journals                                      "Lista de diarios"
- :all-pages                                         "Lista de páginas"
  :all-whiteboards                                   "Todas las pizarras"
  :all-whiteboards                                   "Todas las pizarras"
  :auto-heading                                      "Encabezados automáticos"
  :auto-heading                                      "Encabezados automáticos"
  :bold                                              "Negrita"
  :bold                                              "Negrita"
@@ -489,7 +488,6 @@
  :plugin/updating                                   "Actualizando"
  :plugin/updating                                   "Actualizando"
  :plugin/up-to-date                                 "Está actualizado {1}"
  :plugin/up-to-date                                 "Está actualizado {1}"
  :query/config-property-settings                    "Configuración de propiedades para esta consulta:"
  :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/block-ref                          "Referencia de bloque"
  :right-side-bar/contents                           "Contenido"
  :right-side-bar/contents                           "Contenido"
  :right-side-bar/flashcards                         "Tarjetas de memorización"
  :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/page-graph           "گراف برگه"
  :right-side-bar/block-ref            "ارجاعات بلوک"
  :right-side-bar/block-ref            "ارجاعات بلوک"
  :right-side-bar/graph-view           "نمای گراف"
  :right-side-bar/graph-view           "نمای گراف"
- :right-side-bar/all-pages            "همه برگه‌ها"
  :right-side-bar/whiteboards          "تخته‌سفیدها"
  :right-side-bar/whiteboards          "تخته‌سفیدها"
  :right-side-bar/flashcards           "فلش کارت‌ها"
  :right-side-bar/flashcards           "فلش کارت‌ها"
  :right-side-bar/show-journals        "نمایش روزنگارها"
  :right-side-bar/show-journals        "نمایش روزنگارها"
@@ -289,7 +288,6 @@
  :export-copied-to-clipboard "در بریده‌دان رونوشت شد!"
  :export-copied-to-clipboard "در بریده‌دان رونوشت شد!"
  :export-save-to-file "ذخیره در پرونده"
  :export-save-to-file "ذخیره در پرونده"
  :all-graphs "همهٔ گراف‌ها"
  :all-graphs "همهٔ گراف‌ها"
- :all-pages "همهٔ برگه‌ها"
  :all-whiteboards "همه تخته‌سفیدها"
  :all-whiteboards "همه تخته‌سفیدها"
  :all-files "همهٔ پرونده‌ها"
  :all-files "همهٔ پرونده‌ها"
  :all-journals "همهٔ روزنگارها"
  :all-journals "همهٔ روزنگارها"

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

@@ -26,7 +26,6 @@
     :right-side-bar/contents "Contenus"
     :right-side-bar/contents "Contenus"
     :right-side-bar/block-ref "Référence des blocs"
     :right-side-bar/block-ref "Référence des blocs"
     :right-side-bar/graph-view "Vue graphe"
     :right-side-bar/graph-view "Vue graphe"
-    :right-side-bar/all-pages "Toutes les pages"
     :right-side-bar/flashcards "Cartes-mémoire"
     :right-side-bar/flashcards "Cartes-mémoire"
     :left-side-bar/journals "Journaux"
     :left-side-bar/journals "Journaux"
     :page/make-public "Rendre la page publique"
     :page/make-public "Rendre la page publique"
@@ -57,7 +56,6 @@
     :re-index "Ré-indexer"
     :re-index "Ré-indexer"
     :export-json "Exporter au format JSON"
     :export-json "Exporter au format JSON"
     :graph "Graphe"
     :graph "Graphe"
-    :all-pages "Toutes les pages"
     :all-files "Tous les fichiers"
     :all-files "Tous les fichiers"
     :all-journals "Tous les journaux"
     :all-journals "Tous les journaux"
     :settings "Préférences"
     :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/page-graph "Grafik halaman"
  :right-side-bar/block-ref "Referensi blok"
  :right-side-bar/block-ref "Referensi blok"
  :right-side-bar/graph-view "Tampilan grafik"
  :right-side-bar/graph-view "Tampilan grafik"
- :right-side-bar/all-pages "Semua halaman"
  :right-side-bar/whiteboards "Papan tulis"
  :right-side-bar/whiteboards "Papan tulis"
  :right-side-bar/flashcards "Kartu flash"
  :right-side-bar/flashcards "Kartu flash"
  :right-side-bar/show-journals "Tampilkan Jurnal"
  :right-side-bar/show-journals "Tampilkan Jurnal"
@@ -422,7 +421,6 @@
  :export-copied-to-clipboard "Disalin ke clipboard!"
  :export-copied-to-clipboard "Disalin ke clipboard!"
  :export-save-to-file "Simpan ke berkas"
  :export-save-to-file "Simpan ke berkas"
  :all-graphs "Semua grafik"
  :all-graphs "Semua grafik"
- :all-pages "Semua halaman"
  :all-whiteboards "Semua papan tulis"
  :all-whiteboards "Semua papan tulis"
  :all-files "Semua berkas"
  :all-files "Semua berkas"
  :all-journals "Semua jurnal"
  :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/page-graph "Grafo della pagina"
  :right-side-bar/block-ref "Riferimento al blocco"
  :right-side-bar/block-ref "Riferimento al blocco"
  :right-side-bar/graph-view "Vista del grafo"
  :right-side-bar/graph-view "Vista del grafo"
- :right-side-bar/all-pages "Tutte le pagine"
  :right-side-bar/show-journals "Mostra diari"
  :right-side-bar/show-journals "Mostra diari"
  :left-side-bar/journals "Diario"
  :left-side-bar/journals "Diario"
  :left-side-bar/nav-favorites "Preferiti"
  :left-side-bar/nav-favorites "Preferiti"
@@ -118,7 +117,6 @@
  :export-roam-json "Esporta come Roam JSON"
  :export-roam-json "Esporta come Roam JSON"
  :export-edn "Esporta come EDN"
  :export-edn "Esporta come EDN"
  :all-graphs "Tutti i grafi"
  :all-graphs "Tutti i grafi"
- :all-pages "Tutte le pagine"
  :all-files "Tutti i file"
  :all-files "Tutti i file"
  :all-journals "Tutte le pagine di diario"
  :all-journals "Tutte le pagine di diario"
  :settings "Impostazioni"
  :settings "Impostazioni"

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

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

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

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

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

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

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

@@ -1,7 +1,6 @@
 {:all-files "Alle bestanden"
 {:all-files "Alle bestanden"
  :all-graphs "Alle grafieken"
  :all-graphs "Alle grafieken"
  :all-journals "Alle Journalen"
  :all-journals "Alle Journalen"
- :all-pages "Alle pagina's"
  :bold "Vet"
  :bold "Vet"
  :cancel "Annuleren"
  :cancel "Annuleren"
  :close "Sluiten"
  :close "Sluiten"
@@ -136,7 +135,6 @@
  :plugin/update-available "Update beschikbaar"
  :plugin/update-available "Update beschikbaar"
  :plugin/updating "Bijwerken"
  :plugin/updating "Bijwerken"
 
 
- :right-side-bar/all-pages "Alle pagina's"
  :right-side-bar/block-ref "Blok verwijzingen"
  :right-side-bar/block-ref "Blok verwijzingen"
  :right-side-bar/contents "Inhoud"
  :right-side-bar/contents "Inhoud"
  :right-side-bar/graph-view "Grafiekweergave"
  :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/page-graph "Graf strony"
  :right-side-bar/block-ref "Referencja bloku"
  :right-side-bar/block-ref "Referencja bloku"
  :right-side-bar/graph-view "Widok grafu"
  :right-side-bar/graph-view "Widok grafu"
- :right-side-bar/all-pages "Wszystkie strony"
  :right-side-bar/flashcards "Fiszki"
  :right-side-bar/flashcards "Fiszki"
  :right-side-bar/show-journals "Pokaż dzienniki"
  :right-side-bar/show-journals "Pokaż dzienniki"
  :left-side-bar/journals "Dzienniki"
  :left-side-bar/journals "Dzienniki"
@@ -136,7 +135,6 @@
  :export-roam-json "Eksportuj jako Roam JSON"
  :export-roam-json "Eksportuj jako Roam JSON"
  :export-edn "Eksportuj jako EDN"
  :export-edn "Eksportuj jako EDN"
  :all-graphs "Wszystkie grafy"
  :all-graphs "Wszystkie grafy"
- :all-pages "Wszystkie strony"
  :all-files "Wszystkie pliki"
  :all-files "Wszystkie pliki"
  :all-journals "Wszystkie dzienniki"
  :all-journals "Wszystkie dzienniki"
  :settings "Ustawienia"
  :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/page-graph "Grafo da página"
  :right-side-bar/block-ref "Referências de bloco"
  :right-side-bar/block-ref "Referências de bloco"
  :right-side-bar/graph-view "Visualização de grafo"
  :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/flashcards "Flashcards"
  :right-side-bar/show-journals "Mostrar diários"
  :right-side-bar/show-journals "Mostrar diários"
  :right-side-bar/separator "Manipulador de redimensionamento da barra lateral direita"
  :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-copied-to-clipboard "Copiado para a área de transferência!"
  :export-save-to-file "Salvar em arquivo"
  :export-save-to-file "Salvar em arquivo"
  :all-graphs "Todos os grafos"
  :all-graphs "Todos os grafos"
- :all-pages "Todas as páginas"
  :all-whiteboards "Todos os whiteboards"
  :all-whiteboards "Todos os whiteboards"
  :all-files "Todos os arquivos"
  :all-files "Todos os arquivos"
  :all-journals "Todos os diários"
  :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/page-graph "Grafo da página"
  :right-side-bar/block-ref "Referência de bloco"
  :right-side-bar/block-ref "Referência de bloco"
  :right-side-bar/graph-view "Vista do grafo"
  :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/whiteboards "Quadros brancos"
  :right-side-bar/flashcards "Flashcards"
  :right-side-bar/flashcards "Flashcards"
  :right-side-bar/show-journals "Mostrar págs. diárias"
  :right-side-bar/show-journals "Mostrar págs. diárias"
@@ -175,7 +174,6 @@
  :export-roam-json "Exportar como JSON do Roam"
  :export-roam-json "Exportar como JSON do Roam"
  :export-edn "Exportar como EDN"
  :export-edn "Exportar como EDN"
  :all-graphs "Todos os grafos"
  :all-graphs "Todos os grafos"
- :all-pages "Todas as páginas"
  :all-whiteboards "Todos os quadros brancos"
  :all-whiteboards "Todos os quadros brancos"
  :all-files "Todos os ficheiros"
  :all-files "Todos os ficheiros"
  :all-journals "Todas as págs. diárias"
  :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/page-graph                            "Граф страницы"
  :right-side-bar/block-ref                             "Ссылка на блок"
  :right-side-bar/block-ref                             "Ссылка на блок"
  :right-side-bar/graph-view                            "Визуальный граф"
  :right-side-bar/graph-view                            "Визуальный граф"
- :right-side-bar/all-pages                             "Все страницы"
  :right-side-bar/whiteboards                           "Интерактивные доски"
  :right-side-bar/whiteboards                           "Интерактивные доски"
  :right-side-bar/flashcards                            "Карточки"
  :right-side-bar/flashcards                            "Карточки"
  :right-side-bar/show-journals                         "Показать журналы"
  :right-side-bar/show-journals                         "Показать журналы"
@@ -306,7 +305,6 @@
  :export-roam-json                                     "Экспортировать как Roam JSON"
  :export-roam-json                                     "Экспортировать как Roam JSON"
  :export-edn                                           "Экспортировать как EDN"
  :export-edn                                           "Экспортировать как EDN"
  :all-graphs                                           "Все графы"
  :all-graphs                                           "Все графы"
- :all-pages                                            "Все страницы"
  :all-whiteboards                                      "Все интерактивные доски"
  :all-whiteboards                                      "Все интерактивные доски"
  :all-files                                            "Все файлы"
  :all-files                                            "Все файлы"
  :all-journals                                         "Все журналы"
  :all-journals                                         "Все журналы"

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

@@ -106,7 +106,6 @@
  :right-side-bar/page-graph                        "Graf stránok"
  :right-side-bar/page-graph                        "Graf stránok"
  :right-side-bar/block-ref                         "Referencie bloku"
  :right-side-bar/block-ref                         "Referencie bloku"
  :right-side-bar/graph-view                        "Zobrazenie grafu"
  :right-side-bar/graph-view                        "Zobrazenie grafu"
- :right-side-bar/all-pages                         "Všetky stránky"
  :right-side-bar/whiteboards                       "Tabule"
  :right-side-bar/whiteboards                       "Tabule"
  :right-side-bar/flashcards                        "Kartičky"
  :right-side-bar/flashcards                        "Kartičky"
  :right-side-bar/show-journals                     "Zobraziť denníky"
  :right-side-bar/show-journals                     "Zobraziť denníky"
@@ -425,7 +424,6 @@
  :export-copied-to-clipboard                       "Skopírované do schránky!"
  :export-copied-to-clipboard                       "Skopírované do schránky!"
  :export-save-to-file                              "Uložiť do súboru"
  :export-save-to-file                              "Uložiť do súboru"
  :all-graphs                                       "Všetky grafy"
  :all-graphs                                       "Všetky grafy"
- :all-pages                                        "Všetky stránky"
  :all-whiteboards                                  "Všetky tabule"
  :all-whiteboards                                  "Všetky tabule"
  :all-files                                        "Všetky súbory"
  :all-files                                        "Všetky súbory"
  :all-journals                                     "Všetky denníky"
  :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/page-graph "Sayfa grafı"
  :right-side-bar/block-ref "Blok referansı"
  :right-side-bar/block-ref "Blok referansı"
  :right-side-bar/graph-view "Graf görünümü"
  :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/whiteboards "Beyaz tahtalar"
  :right-side-bar/flashcards "Bilgi kartları"
  :right-side-bar/flashcards "Bilgi kartları"
  :right-side-bar/show-journals "Günlükleri Göster"
  :right-side-bar/show-journals "Günlükleri Göster"
@@ -437,7 +436,6 @@
  :export-copied-to-clipboard "Panoya kopyalandı!"
  :export-copied-to-clipboard "Panoya kopyalandı!"
  :export-save-to-file "Dosyaya kaydet"
  :export-save-to-file "Dosyaya kaydet"
  :all-graphs "Tüm graflar"
  :all-graphs "Tüm graflar"
- :all-pages "Tüm sayfalar"
  :all-whiteboards "Tüm beyaz tahtalar"
  :all-whiteboards "Tüm beyaz tahtalar"
  :all-files "Tüm dosyalar"
  :all-files "Tüm dosyalar"
  :all-journals "Bütün günlükler"
  :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/page-graph "Графік сторінки"
  :right-side-bar/block-ref "Посилання на блоки"
  :right-side-bar/block-ref "Посилання на блоки"
  :right-side-bar/graph-view "Вигляд графіка"
  :right-side-bar/graph-view "Вигляд графіка"
- :right-side-bar/all-pages "Всі сторінки"
  :right-side-bar/whiteboards "Дошки"
  :right-side-bar/whiteboards "Дошки"
  :right-side-bar/flashcards "Флеш-картки"
  :right-side-bar/flashcards "Флеш-картки"
  :right-side-bar/show-journals "Показати журнали"
  :right-side-bar/show-journals "Показати журнали"
@@ -198,7 +197,6 @@
  :export-roam-json "Експортувати як Roam JSON"
  :export-roam-json "Експортувати як Roam JSON"
  :export-edn "Експортувати як EDN"
  :export-edn "Експортувати як EDN"
  :all-graphs "Всі графіки"
  :all-graphs "Всі графіки"
- :all-pages "Всі сторінки"
  :all-whiteboards "Всі дошки"
  :all-whiteboards "Всі дошки"
  :all-files "Всі файли"
  :all-files "Всі файли"
  :all-journals "Всі журнали"
  :all-journals "Всі журнали"

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

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

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

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