Browse Source

Merge pull request #11673 from logseq/refactor/block-schema

refactor: replace :block/schema with corresponding properties
Gabriel Horner 11 months ago
parent
commit
a1f29cc05a
84 changed files with 1039 additions and 1003 deletions
  1. 1 1
      deps/common/src/logseq/common/util/date_time.cljs
  2. 8 6
      deps/db/script/create_graph/inferred.edn
  3. 3 3
      deps/db/src/logseq/db/frontend/entity_plus.cljc
  4. 6 5
      deps/db/src/logseq/db/frontend/entity_util.cljs
  5. 28 47
      deps/db/src/logseq/db/frontend/malli_schema.cljs
  6. 68 81
      deps/db/src/logseq/db/frontend/property.cljs
  7. 27 4
      deps/db/src/logseq/db/frontend/property/build.cljs
  8. 10 10
      deps/db/src/logseq/db/frontend/property/type.cljs
  9. 15 16
      deps/db/src/logseq/db/frontend/rules.cljc
  10. 2 7
      deps/db/src/logseq/db/frontend/schema.cljs
  11. 26 27
      deps/db/src/logseq/db/sqlite/build.cljs
  12. 55 35
      deps/db/src/logseq/db/sqlite/create_graph.cljs
  13. 21 22
      deps/db/src/logseq/db/sqlite/util.cljs
  14. 9 7
      deps/db/test/logseq/db/frontend/rules_test.cljs
  15. 22 12
      deps/db/test/logseq/db/sqlite/create_graph_test.cljs
  16. 5 5
      deps/db/test/logseq/db_test.cljs
  17. 3 3
      deps/graph-parser/script/db_import.cljs
  18. 18 17
      deps/graph-parser/src/logseq/graph_parser/exporter.cljs
  19. 15 15
      deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs
  20. 5 5
      deps/outliner/src/logseq/outliner/pipeline.cljs
  21. 43 38
      deps/outliner/src/logseq/outliner/property.cljs
  22. 8 8
      deps/outliner/test/logseq/outliner/pipeline_test.cljs
  23. 31 21
      deps/outliner/test/logseq/outliner/property_test.cljs
  24. 3 3
      deps/outliner/test/logseq/outliner/validate_test.cljs
  25. 21 15
      scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs
  26. 32 32
      scripts/src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs
  27. 1 1
      scripts/src/logseq/tasks/dev/db_and_file_graphs.clj
  28. 4 4
      src/main/frontend/components/all_pages.cljs
  29. 15 17
      src/main/frontend/components/assets.cljs
  30. 1 1
      src/main/frontend/components/block.cljs
  31. 14 14
      src/main/frontend/components/bug_report.cljs
  32. 4 4
      src/main/frontend/components/cmdk/core.cljs
  33. 5 5
      src/main/frontend/components/dnd.cljs
  34. 3 3
      src/main/frontend/components/editor.cljs
  35. 4 4
      src/main/frontend/components/file_based/block.cljs
  36. 11 11
      src/main/frontend/components/file_sync.cljs
  37. 7 7
      src/main/frontend/components/git.cljs
  38. 6 6
      src/main/frontend/components/handbooks.cljs
  39. 3 3
      src/main/frontend/components/header.cljs
  40. 2 2
      src/main/frontend/components/imports.cljs
  41. 2 2
      src/main/frontend/components/objects.cljs
  42. 3 3
      src/main/frontend/components/page.cljs
  43. 13 14
      src/main/frontend/components/plugins.cljs
  44. 2 2
      src/main/frontend/components/plugins_settings.cljs
  45. 21 18
      src/main/frontend/components/property.cljs
  46. 27 25
      src/main/frontend/components/property/config.cljs
  47. 0 12
      src/main/frontend/components/property/util.cljs
  48. 30 35
      src/main/frontend/components/property/value.cljs
  49. 4 4
      src/main/frontend/components/query.cljs
  50. 14 14
      src/main/frontend/components/query/builder.cljs
  51. 2 2
      src/main/frontend/components/right_sidebar.cljs
  52. 7 7
      src/main/frontend/components/server.cljs
  53. 2 2
      src/main/frontend/components/settings.cljs
  54. 2 2
      src/main/frontend/components/theme.cljs
  55. 56 56
      src/main/frontend/components/user/login.cljs
  56. 15 22
      src/main/frontend/components/views.cljs
  57. 1 1
      src/main/frontend/db/async.cljs
  58. 9 9
      src/main/frontend/db/query_dsl.cljs
  59. 4 4
      src/main/frontend/extensions/pdf/windows.cljs
  60. 11 11
      src/main/frontend/extensions/slide.cljs
  61. 16 16
      src/main/frontend/extensions/tldraw.cljs
  62. 2 2
      src/main/frontend/extensions/zotero.cljs
  63. 21 21
      src/main/frontend/handler/common/plugin.cljs
  64. 1 1
      src/main/frontend/handler/db_based/recent.cljs
  65. 2 2
      src/main/frontend/handler/editor.cljs
  66. 21 21
      src/main/frontend/handler/import.cljs
  67. 14 14
      src/main/frontend/handler/plugin.cljs
  68. 22 22
      src/main/frontend/mobile/graph_picker.cljs
  69. 2 2
      src/main/frontend/rum.cljs
  70. 7 7
      src/main/frontend/ui.cljs
  71. 4 4
      src/main/frontend/worker/commands.cljs
  72. 58 8
      src/main/frontend/worker/db/migrate.cljs
  73. 2 2
      src/main/frontend/worker/rtc/db_listener.cljs
  74. 3 4
      src/main/frontend/worker/rtc/remote_update.cljs
  75. 2 2
      src/main/frontend/worker/rtc/ws.cljs
  76. 7 38
      src/main/frontend/worker/search.cljs
  77. 37 37
      src/main/logseq/api.cljs
  78. 0 0
      src/rtc_e2e_test/example.cljs
  79. 8 8
      src/test/frontend/db/db_based_model_test.cljs
  80. 11 11
      src/test/frontend/db/query_dsl_test.cljs
  81. 4 4
      src/test/frontend/worker/handler/page/db_based/page_test.cljs
  82. 1 1
      src/test/frontend/worker/rtc/client_test.cljs
  83. 2 2
      src/test/frontend/worker/rtc/db_listener_test.cljs
  84. 2 2
      src/test/frontend/worker/rtc/rtc_fns_test.cljs

+ 1 - 1
deps/common/src/logseq/common/util/date_time.cljs

@@ -1,8 +1,8 @@
 (ns logseq.common.util.date-time
   "cljs-time util fns for deps"
   (:require [cljs-time.coerce :as tc]
-            [cljs-time.format :as tf]
             [cljs-time.core :as t]
+            [cljs-time.format :as tf]
             [clojure.string :as string]
             [logseq.common.util :as common-util]))
 

+ 8 - 6
deps/db/script/create_graph/inferred.edn

@@ -7,13 +7,15 @@
 ;; or
 ;; - DB 3 #Meeting #Tienson
 {:auto-create-ontology? true
- :classes {:Movie {:build/schema-properties [:actor :comment]}
-           :Meeting {:build/schema-properties [:attendee :duration]}}
+ :classes {:Movie {:build/class-properties [:actor :comment]}
+           :Meeting {:build/class-properties [:attendee :duration]}}
  :properties
- {:actor {:block/schema {:type :node :cardinality :many}
-          :build/schema-classes [:Person]}
-  :attendee {:block/schema {:type :node :cardinality :many}
-             :build/schema-classes [:Person]}}
+ {:actor {:logseq.property/type :node
+          :db/cardinality :many
+          :build/property-classes [:Person]}
+  :attendee {:logseq.property/type :node
+             :db/cardinality :many
+             :build/property-classes [:Person]}}
  :pages-and-blocks
  [{:page {:block/title "Matt-Damon" :build/tags [:Person]}}
   {:page {:block/title "Ben-Affleck" :build/tags [:Person]}}

+ 3 - 3
deps/db/src/logseq/db/frontend/entity_plus.cljc

@@ -31,7 +31,7 @@
   "These db-ident entities are immutable,
   it means `(db/entity :block/title)` always return same result"
   #{:block/link :block/updated-at :block/refs :block/closed-value-property
-    :block/created-at :block/collapsed? :block/schema :block/tags :block/title
+    :block/created-at :block/collapsed? :block/tags :block/title
     :block/path-refs :block/parent :block/order :block/page
 
     :logseq.property/created-from-property
@@ -114,8 +114,8 @@
        ;; property default value
        (when (qualified-keyword? k)
          (when-let [property (entity-memoized db k)]
-           (let [schema (lookup-entity property :block/schema nil)]
-             (if (= :checkbox (:type schema))
+           (let [property-type (lookup-entity property :logseq.property/type nil)]
+             (if (= :checkbox property-type)
                (lookup-entity property :logseq.property/scalar-default-value nil)
                (lookup-entity property :logseq.property/default-value nil)))))))))
 

+ 6 - 5
deps/db/src/logseq/db/frontend/entity_util.cljs

@@ -73,11 +73,12 @@
 
 (defn hidden?
   [page]
-  (when page
-    (if (string? page)
-      (string/starts-with? page "$$$")
-      (when (or (map? page) (de/entity? page))
-        (false? (get-in page [:block/schema :public?]))))))
+  (boolean
+   (when page
+     (if (string? page)
+       (string/starts-with? page "$$$")
+       (when (or (map? page) (de/entity? page))
+         (:logseq.property/hide? page))))))
 
 (defn object?
   [node]

+ 28 - 47
deps/db/src/logseq/db/frontend/malli_schema.cljs

@@ -84,14 +84,14 @@
   expected to be a coll if the property has a :many cardinality. validate-fn is
   a fn that is called directly on each value to return a truthy value.
   validate-fn varies by property type"
-  [db validate-fn [{:block/keys [schema] :as property} property-val] & {:keys [new-closed-value?]}]
+  [db validate-fn [property property-val] & {:keys [new-closed-value?]}]
   ;; For debugging
   ;; (when (not (internal-ident? (:db/ident property))) (prn :validate-val (dissoc property :property/closed-values) property-val))
-  (let [validate-fn' (if (db-property-type/property-types-with-db (:type schema))
+  (let [validate-fn' (if (db-property-type/property-types-with-db (:logseq.property/type property))
                        (fn [value]
                          (validate-fn db value {:new-closed-value? new-closed-value?}))
                        validate-fn)
-        validate-fn'' (if (and (db-property-type/closed-value-property-types (:type schema))
+        validate-fn'' (if (and (db-property-type/closed-value-property-types (:logseq.property/type property))
                                ;; new closed values aren't associated with the property yet
                                (not new-closed-value?)
                                (seq (:property/closed-values property)))
@@ -111,8 +111,9 @@
    of validate-property-value"
   (set/union
    (set (get-in db-class/built-in-classes [:logseq.class/Asset :schema :required-properties]))
-   #{:logseq.property/created-from-property :logseq.property.history/scalar-value
-     :logseq.property.history/block :logseq.property.history/property :logseq.property.history/ref-value}))
+   #{:logseq.property/created-from-property :logseq.property/value
+     :logseq.property.history/scalar-value :logseq.property.history/block
+     :logseq.property.history/property :logseq.property.history/ref-value}))
 
 (defn- property-entity->map
   "Provide the minimal number of property attributes to validate the property
@@ -121,9 +122,7 @@
   [property]
   ;; use explicit call to be nbb compatible
   (let [closed-values (entity-plus/lookup-kv-then-entity property :property/closed-values)]
-    (cond-> (assoc (select-keys property [:db/ident :db/valueType :db/cardinality])
-                   :block/schema
-                   (select-keys (:block/schema property) [:type]))
+    (cond-> (select-keys property [:db/ident :db/valueType :db/cardinality :logseq.property/type])
       (seq closed-values)
       (assoc :property/closed-values closed-values))))
 
@@ -132,7 +131,9 @@
   [db ents]
   ;; required-properties allows schemas like property-value-block to require
   ;; properties in their schema that they depend on
-  (let [exceptions-to-block-properties (conj required-properties :block/tags)
+  (let [exceptions-to-block-properties (-> required-properties
+                                           (into db-property/schema-properties)
+                                           (conj :block/tags))
         page-class-id (:db/id (d/entity db :logseq.class/Page))
         all-page-class-ids (set (map #(:db/id (d/entity db %)) db-class/page-classes))]
     (mapv
@@ -213,7 +214,7 @@
 (def property-tuple
   "A tuple of a property map and a property value"
   (into
-   [:multi {:dispatch #(-> % first :block/schema :type)}]
+   [:multi {:dispatch #(-> % first :logseq.property/type)}]
    (map (fn [[prop-type value-schema]]
           [prop-type
            (let [schema-fn (if (vector? value-schema) (last value-schema) value-schema)]
@@ -269,7 +270,7 @@
    [:db/valueType {:optional true} [:enum :db.type/ref]]
    [:db/cardinality {:optional true} [:enum :db.cardinality/many :db.cardinality/one]]
    [:block/order {:optional true} block-order]
-   [:property/schema.classes {:optional true} [:set :int]]])
+   [:logseq.property/classes {:optional true} [:set :int]]])
 
 (def normal-page
   (vec
@@ -290,49 +291,31 @@
 
 (def property-common-schema-attrs
   "Property :schema attributes common to all properties"
-  [[:hide? {:optional true} :boolean]
-   [:position {:optional true} [:enum :properties :block-left :block-right :block-below]]])
+  [[:logseq.property/hide? {:optional true} :boolean]
+   [:logseq.property/public? {:optional true} :boolean]
+   [:logseq.property/ui-position {:optional true} [:enum :properties :block-left :block-right :block-below]]])
 
 (def internal-property
   (vec
    (concat
     [:map
      [:db/ident internal-property-ident]
-     [:block/schema
-      (vec
-       (concat
-        [:map
-         [:type (apply vector :enum (into db-property-type/internal-built-in-property-types
-                                          db-property-type/user-built-in-property-types))]
-         [:public? {:optional true} :boolean]
-         [:view-context {:optional true} [:enum :page :block :class :property :never]]
-         [:shortcut {:optional true} :string]]
-        property-common-schema-attrs))]]
+     [:logseq.property/type (apply vector :enum (into db-property-type/internal-built-in-property-types
+                                                      db-property-type/user-built-in-property-types))]
+     [:logseq.property/view-context {:optional true} [:enum :page :block :class :property :never]]]
+    property-common-schema-attrs
     property-attrs
     page-attrs
     page-or-block-attrs)))
 
-(def user-property-schema
-  (into
-   [:multi {:dispatch :type}]
-   (map
-    (fn [prop-type]
-      [prop-type
-       (vec
-        (concat
-         [:map
-          ;; Once a schema is defined it must have :type as this is an irreversible decision
-          [:type :keyword]]
-         property-common-schema-attrs))])
-    db-property-type/user-built-in-property-types)))
-
 (def user-property
   (vec
    (concat
     [:map
      ;; class-ident allows for a class to be used as a property
      [:db/ident [:or user-property-ident class-ident]]
-     [:block/schema user-property-schema]]
+     [:logseq.property/type (apply vector :enum db-property-type/user-built-in-property-types)]]
+    property-common-schema-attrs
     property-attrs
     page-attrs
     page-or-block-attrs)))
@@ -350,9 +333,7 @@
     [:map
      ;; pages from :default property uses this but closed-value pages don't
      [:block/order {:optional true} block-order]
-     [:block/schema
-      [:map
-       [:public? {:optional true} :boolean]]]]
+     [:logseq.property/hide? [:enum true]]]
     page-attrs
     page-or-block-attrs)))
 
@@ -384,7 +365,7 @@
   (vec
    (concat
     [:map]
-    [[:property.value/content [:or :string :double :boolean]]
+    [[:logseq.property/value [:or :string :double :boolean]]
      [:logseq.property/created-from-property :int]]
     (remove #(#{:block/title :logseq.property/created-from-property} (first %)) block-attrs)
     page-or-block-attrs)))
@@ -416,7 +397,7 @@
     [;; for built-in properties
      [:db/ident {:optional true} logseq-property-ident]
      [:block/title {:optional true} :string]
-     [:property.value/content {:optional true} [:or :string :double]]
+     [:logseq.property/value {:optional true} [:or :string :double]]
      [:logseq.property/created-from-property :int]
      [:block/closed-value-property {:optional true} [:set :int]]]
     (remove #(#{:block/title :logseq.property/created-from-property} (first %)) block-attrs)
@@ -425,10 +406,10 @@
 (def closed-value-block
   "A closed value for a property with closed/allowed values"
   [:and closed-value-block*
-   [:fn {:error/message ":block/title or :property.value/content required"
-         :error/path [:property.value/content]}
+   [:fn {:error/message ":block/title or :logseq.property/value required"
+         :error/path [:logseq.property/value]}
     (fn [m]
-      (or (:block/title m) (:property.value/content m)))]])
+      (or (:block/title m) (:logseq.property/value m)))]])
 
 (def normal-block
   "A block with content and no special type or tag behavior"
@@ -506,7 +487,7 @@
                        :closed-value-block
 
                        (and (:logseq.property/created-from-property d)
-                            (:property.value/content d))
+                            (:logseq.property/value d))
                        :property-value-block
 
                        (:block/uuid d)

+ 68 - 81
deps/db/src/logseq/db/frontend/property.cljs

@@ -5,32 +5,8 @@
             [datascript.core :as d]
             [flatland.ordered.map :refer [ordered-map]]
             [logseq.common.defkeywords :refer [defkeywords]]
-            [logseq.common.util :as common-util]
             [logseq.common.uuid :as common-uuid]
-            [logseq.db.frontend.db-ident :as db-ident]
-            [logseq.db.frontend.order :as db-order]
-            [logseq.db.frontend.property.type :as db-property-type]))
-
-(defn build-property-value-block
-  "Builds a property value entity given a block map/entity, a property entity or
-  ident and its property value"
-  [block property value]
-  (let [block-id (or (:db/id block) (:db/ident block))]
-    (-> (merge
-         {:block/uuid (d/squuid)
-          :block/page (if (:block/page block)
-                        (:db/id (:block/page block))
-                        ;; page block
-                        block-id)
-          :block/parent block-id
-          :logseq.property/created-from-property (if (= (:db/ident property) :logseq.property/default-value)
-                                                   block-id
-                                                   (or (:db/id property) {:db/ident (:db/ident property)}))
-          :block/order (db-order/gen-key)}
-         (if (db-property-type/property-value-content? (get-in block [:block/schema :type]) property)
-           {:property.value/content value}
-           {:block/title value}))
-        common-util/block-with-timestamps)))
+            [logseq.db.frontend.db-ident :as db-ident]))
 
 ;; Main property vars
 ;; ==================
@@ -38,6 +14,7 @@
 (def ^:large-vars/data-var built-in-properties*
   "Map of built in properties for db graphs with their :db/ident as keys.
    Each property has a config map with the following keys:
+   TODO: Move some of these keys to :properties since :schema is a deprecated concept
    * :schema - Property's schema. Required key. Has the following common keys:
      * :type - Property type
      * :cardinality - property cardinality. Default to one/single cardinality if not set
@@ -59,13 +36,40 @@
   (apply
    ordered-map
    (defkeywords
-     :block/alias           {:title "Alias"
-                             :attribute :block/alias
-                             :schema {:type :page
-                                      :cardinality :many
-                                      :view-context :page
-                                      :public? true}
-                             :queryable? true}
+     :logseq.property/type {:title "Property type"
+                            :schema {:type :keyword
+                                     :hide? true}}
+     :logseq.property/hide? {:title "Hide this property"
+                             :schema {:type :checkbox
+                                      :hide? true}}
+     :logseq.property/public? {:title "Property public?"
+                               :schema {:type :checkbox
+                                        :hide? true}}
+     :logseq.property/view-context {:title "Property view context"
+                                    :schema {:type :keyword
+                                             :hide? true}}
+     :logseq.property/ui-position {:title "Property position"
+                                   :schema {:type :keyword
+                                            :hide? true}}
+     :logseq.property/classes
+     {:title "Property classes"
+      :schema {:type :entity
+               :cardinality :many
+               :public? false
+               :hide? true}}
+     :logseq.property/value
+     {:title "Property value"
+      :schema {:type :any
+               :public? false
+               :hide? true}}
+
+     :block/alias          {:title "Alias"
+                            :attribute :block/alias
+                            :schema {:type :page
+                                     :cardinality :many
+                                     :view-context :page
+                                     :public? true}
+                            :queryable? true}
      :block/tags           {:title "Tags"
                             :attribute :block/tags
                             :schema {:type :class
@@ -73,16 +77,6 @@
                                      :public? true
                                      :classes #{:logseq.class/Root}}
                             :queryable? true}
-     :logseq.property.attribute/kv-value {:title "KV value"
-                                          :attribute :kv/value
-                                          :schema {:type :any
-                                                   :public? false
-                                                   :hide? true}}
-     :block/schema         {:title "Node schema"
-                            :attribute :block/schema
-                            :schema {:type :map
-                                     :public? false
-                                     :hide? true}}
      :block/parent         {:title "Node parent"
                             :attribute :block/parent
                             :schema {:type :entity
@@ -140,20 +134,6 @@
                             :schema {:type :datetime
                                      :public? false
                                      :hide? true}}
-     :logseq.property.attribute/property-schema-classes
-     {:title "Property classes"
-      :attribute :property/schema.classes
-      :schema {:type :entity
-               :cardinality :many
-               :public? false
-               :hide? true}}
-     :logseq.property.attribute/property-value-content
-     {:title "Property value"
-      :attribute :property.value/content
-      :schema {:type :any
-               :public? false
-               :hide? true}}
-
      :logseq.property.node/display-type {:title "Node Display Type"
                                          :schema {:type :keyword
                                                   :public? false
@@ -280,20 +260,6 @@
                                             {:type :string
                                              :public? false}}
 
-   ;; TODO: should we replace block/journal-day with those separate props?
-   ;; :logseq.property.journal/year {:title "Journal year"
-   ;;                                :schema
-   ;;                                {:type :raw-number
-   ;;                                 :public? false}}
-   ;; :logseq.property.journal/month {:title "Journal month"
-   ;;                                 :schema
-   ;;                                 {:type :raw-number
-   ;;                                  :public? false}}
-   ;; :logseq.property.journal/day {:title "Journal day"
-   ;;                               :schema
-   ;;                               {:type :raw-number
-   ;;                                :public? false}}
-
      :logseq.property/choice-checkbox-state
      {:title "Choice checkbox state"
       :schema {:type :checkbox
@@ -311,7 +277,7 @@
       :schema
       {:type :default
        :public? true
-       :position :block-left}
+       :ui-position :block-left}
       :closed-values
       (mapv (fn [[db-ident value icon]]
               {:db-ident db-ident
@@ -329,7 +295,7 @@
       :schema
       {:type :default
        :public? true
-       :position :block-left}
+       :ui-position :block-left}
       :closed-values
       (mapv (fn [[db-ident value icon checkbox-state]]
               {:db-ident db-ident
@@ -352,7 +318,7 @@
      {:title "Deadline"
       :schema {:type :datetime
                :public? true
-               :position :block-below}
+               :ui-position :block-below}
       :properties {:logseq.property/hide-empty-value true
                    :logseq.property/description "Use it to finish something at a specific date(time)."}
       :queryable? true}
@@ -360,7 +326,7 @@
      {:title "Scheduled"
       :schema {:type :datetime
                :public? true
-               :position :block-below}
+               :ui-position :block-below}
       :properties {:logseq.property/hide-empty-value true
                    :logseq.property/description "Use it to plan something to start at a specific date(time)."}
       :queryable? true}
@@ -585,15 +551,14 @@
 
 (def db-attribute-properties
   "Internal properties that are also db schema attributes"
-  #{:block/alias :block/tags :block/schema :block/parent
+  #{:block/alias :block/tags :block/parent
     :block/order :block/collapsed? :block/page
     :block/refs :block/path-refs :block/link
     :block/title :block/closed-value-property
-    :block/created-at :block/updated-at
-    :logseq.property.attribute/kv-value :logseq.property.attribute/property-schema-classes :logseq.property.attribute/property-value-content})
+    :block/created-at :block/updated-at})
 
 (assert (= db-attribute-properties
-           (set (keep (fn [[k {:keys [attribute]}]] (when attribute k))
+           (set (keep (fn [[_k {:keys [attribute]}]] (when attribute attribute))
                       built-in-properties)))
         "All db attribute properties are configured in built-in-properties")
 
@@ -611,6 +576,24 @@
   "Property values that shouldn't be updated"
   #{:logseq.property/built-in?})
 
+(def schema-properties-map
+  "Maps schema unqualified keywords to their qualified keywords.
+   The qualified keywords are all properties except for :db/cardinality
+   which is a datascript attribute"
+  {:cardinality :db/cardinality
+   :type :logseq.property/type
+   :hide? :logseq.property/hide?
+   :public? :logseq.property/public?
+   :ui-position :logseq.property/ui-position
+   :view-context :logseq.property/view-context
+   :classes :logseq.property/classes})
+
+(def schema-properties
+  "Properties that used to be in block/schema. Schema originally referred to just type and cardinality
+   but expanded to include a property's core configuration because it was easy to add to the schema map.
+   We should move some of these out since they are just like any other properties e.g. :view-context"
+  (set (vals schema-properties-map)))
+
 (def logseq-property-namespaces
   #{"logseq.property" "logseq.property.tldraw" "logseq.property.pdf" "logseq.property.fsrs" "logseq.task"
     "logseq.property.linked-references" "logseq.property.asset" "logseq.property.table" "logseq.property.node"
@@ -673,14 +656,14 @@
   "Gets content/value of a given closed value ent/map. Works for all closed value types"
   [ent]
   (or (:block/title ent)
-      (:property.value/content ent)))
+      (:logseq.property/value ent)))
 
 (defn property-value-content
   "Given an entity, gets the content for the property value of a ref type
   property i.e. what the user sees. For page types the content is the page name"
   [ent]
   (or (:block/title ent)
-      (:property.value/content ent)))
+      (:logseq.property/value ent)))
 
 (defn ref->property-value-content
   "Given a ref from a pulled query e.g. `{:db/id X}`, gets a readable name for
@@ -747,4 +730,8 @@
   "Indicates whether built-in property can be seen and edited by users"
   [entity]
   ;; No need to do :built-in? check yet since user properties can't set this
-  (get-in entity [:block/schema :public?]))
+  (:logseq.property/public? entity))
+
+(defn get-property-schema
+  [property-m]
+  (select-keys property-m schema-properties))

+ 27 - 4
deps/db/src/logseq/db/frontend/property/build.cljs

@@ -1,6 +1,8 @@
 (ns logseq.db.frontend.property.build
   "Builds core property concepts"
-  (:require [logseq.db.frontend.order :as db-order]
+  (:require [datascript.core :as d]
+            [logseq.common.util :as common-util]
+            [logseq.db.frontend.order :as db-order]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property.type :as db-property-type]
             [logseq.db.sqlite.util :as sqlite-util]))
@@ -16,7 +18,7 @@
                                                      property-id)
             :block/parent property-id}
            (if (db-property-type/property-value-content? block-type property)
-             {:property.value/content value}
+             {:logseq.property/value value}
              {:block/title value}))))
 
 (defn build-closed-value-block
@@ -54,7 +56,8 @@
   "Builds all the tx needed for property with closed values including
    the hidden page and closed value blocks as needed"
   [db-ident prop-name property {:keys [property-attributes properties]}]
-  (let [property-schema (:block/schema property)
+  (let [property-schema (or (:schema property)
+                            (db-property/get-property-schema property))
         property-tx (merge (sqlite-util/build-new-property db-ident property-schema {:title prop-name
                                                                                      :ref-type? true
                                                                                      :properties properties})
@@ -62,7 +65,27 @@
     (into [property-tx]
           (closed-values->blocks property))))
 
-(def build-property-value-block db-property/build-property-value-block)
+(defn- build-property-value-block
+  "Builds a property value entity given a block map/entity, a property entity or
+  ident and its property value"
+  [block property value]
+  (let [block-id (or (:db/id block) (:db/ident block))]
+    (-> (merge
+         {:block/uuid (d/squuid)
+          :block/page (if (:block/page block)
+                        (:db/id (:block/page block))
+                        ;; page block
+                        block-id)
+          :block/parent block-id
+          :logseq.property/created-from-property (if (= (:db/ident property) :logseq.property/default-value)
+                                                   block-id
+                                                   (or (:db/id property) {:db/ident (:db/ident property)}))
+          :block/order (db-order/gen-key)}
+         (if (db-property-type/property-value-content? (:logseq.property/type property) property)
+           {:logseq.property/value value}
+           {:block/title value}))
+        common-util/block-with-timestamps)))
+
 
 (defn build-property-values-tx-m
   "Builds a map of property names to their property value blocks to be

+ 10 - 10
deps/db/src/logseq/db/frontend/property/type.cljs

@@ -1,11 +1,11 @@
 (ns logseq.db.frontend.property.type
   "Provides property types and related helper fns e.g. property value validation
   fns and their allowed schema attributes"
-  (:require [datascript.core :as d]
-            [clojure.set :as set]
+  (:require [clojure.set :as set]
+            [clojure.string :as string]
+            [datascript.core :as d]
             [logseq.common.util.macro :as macro-util]
-            [logseq.db.frontend.entity-util :as entity-util]
-            [clojure.string :as string]))
+            [logseq.db.frontend.entity-util :as entity-util]))
 
 ;; Config vars
 ;; ===========
@@ -44,18 +44,18 @@
 
 (def original-value-ref-property-types
   "Property value ref types where the refed entity stores its value in
-  :property.value/content e.g. :number is stored as a number. new value-ref-property-types
+  :logseq.property/value e.g. :number is stored as a number. new value-ref-property-types
   should default to this as it allows for more querying power"
   #{:number})
 
 (def value-ref-property-types
   "Property value ref types where the refed entities either store their value in
-  :property.value/content or :block/title (for :default)"
+  :logseq.property/value or :block/title (for :default)"
   (into #{:default :url} original-value-ref-property-types))
 
 (def user-ref-property-types
   "User ref types. Property values that users see are stored in either
-  :property.value/content or :block/title. :block/title is for all the page related types"
+  :logseq.property/value or :block/title. :block/title is for all the page related types"
   (into #{:date :node} value-ref-property-types))
 
 (assert (set/subset? user-ref-property-types
@@ -120,7 +120,7 @@
   (if new-closed-value?
     (number? id-or-value)
     (when-let [entity (d/entity db id-or-value)]
-      (number? (:property.value/content entity)))))
+      (number? (:logseq.property/value entity)))))
 
 (defn- text-entity?
   [db s {:keys [new-closed-value?]}]
@@ -206,9 +206,9 @@
     :else :default))
 
 (defn property-value-content?
-  "Whether property value should be stored in :property.value/content"
+  "Whether property value should be stored in :logseq.property/value"
   [block-type property]
   (or
-   (original-value-ref-property-types (get-in property [:block/schema :type]))
+   (original-value-ref-property-types (:logseq.property/type property))
    (and (= (:db/ident property) :logseq.property/default-value)
         (original-value-ref-property-types block-type))))

+ 15 - 16
deps/db/src/logseq/db/frontend/rules.cljc

@@ -178,7 +178,7 @@
        [?prop-e :db/valueType :db.type/ref]
        [?b ?prop ?pv]
        (or [?pv :block/title ?val]
-           [?pv :property.value/content ?val])]]
+           [?pv :logseq.property/value ?val])]]
 
     :property-missing-value
     '[(property-missing-value ?b ?prop-e ?default-p ?default-v)
@@ -202,7 +202,7 @@
       (property-missing-value ?b ?prop-e ?default-p ?default-v)
       (or
        [?default-v :block/title ?val]
-       [?default-v :property.value/content ?val])]
+       [?default-v :logseq.property/value ?val])]
 
     :property-value
     '[[(property-value ?b ?prop-e ?val)
@@ -241,9 +241,9 @@
       [?prop-e :db/ident ?prop]
       [?prop-e :block/tags :logseq.class/Property]
       (has-property-or-default-value? ?b ?prop)
-      [?prop-e :block/schema ?prop-schema]
-      [(get ?prop-schema :public? true) ?public]
-      [(= true ?public)]]
+      (or
+       [(missing? $ ?prop-e :logseq.property/public?)]
+       [?prop-e :logseq.property/public? true])]
 
     ;; Same as has-simple-query-property except it returns public and private properties like :block/title
     :has-private-simple-query-property
@@ -258,18 +258,18 @@
       [?b ?prop _]
       [?prop-e :db/ident ?prop]
       [?prop-e :block/tags :logseq.class/Property]
-      [?prop-e :block/schema ?prop-schema]
-      [(get ?prop-schema :public? true) ?public]
-      [(= true ?public)]]
+      (or
+       [(missing? $ ?prop-e :logseq.property/public?)]
+       [?prop-e :logseq.property/public? true])]
 
     ;; Checks if a property has a value for any features that are not simple queries
     :property
     '[(property ?b ?prop ?val)
       [?prop-e :db/ident ?prop]
       [?prop-e :block/tags :logseq.class/Property]
-      [?prop-e :block/schema ?prop-schema]
-      [(get ?prop-schema :public? true) ?public]
-      [(= true ?public)]
+      (or
+       [(missing? $ ?prop-e :logseq.property/public?)]
+       [?prop-e :logseq.property/public? true])
       [?b ?prop ?pv]
       (or
        ;; non-ref value
@@ -280,17 +280,16 @@
        (and
         [?prop-e :db/valueType :db.type/ref]
         (or [?pv :block/title ?val]
-            [?pv :property.value/content ?val])))]
+            [?pv :logseq.property/value ?val])))]
 
     ;; Checks if a property has a value for simple queries. Supports default values
     :simple-query-property
     '[(simple-query-property ?b ?prop ?val)
       [?prop-e :db/ident ?prop]
       [?prop-e :block/tags :logseq.class/Property]
-      [?prop-e :block/schema ?prop-schema]
-      [(get ?prop-schema :public? true) ?public]
-      [(get ?prop-schema :type) ?type]
-      [(= true ?public)]
+      (or
+       [(missing? $ ?prop-e :logseq.property/public?)]
+       [?prop-e :logseq.property/public? true])
       (property-value ?b ?prop-e ?val)]
 
     ;; Same as property except it returns public and private properties like :block/title

+ 2 - 7
deps/db/src/logseq/db/frontend/schema.cljs

@@ -2,13 +2,12 @@
   "Main datascript schemas for the Logseq app"
   (:require [clojure.set :as set]))
 
-(def version 60)
+(def version 62)
 
 ;; A page is a special block, a page can corresponds to multiple files with the same ":block/name".
 (def ^:large-vars/data-var schema
   {:db/ident        {:db/unique :db.unique/identity}
    :kv/value       {}
-
    :recent/pages {}
 
    ;; :block/type is a string type of the current block
@@ -16,7 +15,6 @@
    ;; "property" for property blocks
    ;; "class" for structured page
    :block/type {:db/index true}
-   :block/schema {}
    :block/uuid {:db/unique :db.unique/identity}
    :block/parent {:db/valueType :db.type/ref
                   :db/index true}
@@ -116,10 +114,7 @@
    {:block/name {:db/index true}        ; remove db/unique for :block/name
     ;; closed value
     :block/closed-value-property {:db/valueType :db.type/ref
-                                  :db/cardinality :db.cardinality/many}
-    :property/schema.classes {:db/valueType :db.type/ref
-                              :db/cardinality :db.cardinality/many}
-    :property.value/content {}}))
+                                  :db/cardinality :db.cardinality/many}}))
 
 (def retract-attributes
   #{:block/refs

+ 26 - 27
deps/db/src/logseq/db/sqlite/build.cljs

@@ -88,18 +88,19 @@
                           ;; closed values are referenced by their :db/ident so no need to create values
                           (not (get-in db-property/built-in-properties [k :closed-values])))
                    (let [property-map {:db/ident k
-                                       :block/schema {:type built-in-type}}]
+                                       :logseq.property/type built-in-type}]
                      [property-map v])
                    (when-let [built-in-type' (get (:build/properties-ref-types new-block) built-in-type)]
                      (let [property-map {:db/ident k
-                                         :block/schema {:type built-in-type'}}]
+                                         :logseq.property/type built-in-type'}]
                        [property-map v])))
-                 (when (and (db-property-type/value-ref-property-types (get-in properties-config [k :block/schema :type]))
+                 (when (and (db-property-type/value-ref-property-types (get-in properties-config [k :logseq.property/type]))
                             ;; TODO: Support translate-property-value without this hack
                             (not (vector? v)))
-                   (let [property-map {:db/ident (get-ident all-idents k)
+                   (let [prop-type (get-in properties-config [k :logseq.property/type])
+                         property-map {:db/ident (get-ident all-idents k)
                                        :original-property-id k
-                                       :block/schema {:type (get-in properties-config [k :block/schema :type])}}]
+                                       :logseq.property/type prop-type}]
                      [property-map v])))))
        (db-property-build/build-property-values-tx-m new-block)))
 
@@ -143,7 +144,7 @@
 
 (defn- build-property-tx
   [properties page-uuids all-idents property-db-ids
-   [prop-name {:build/keys [schema-classes] :as prop-m}]]
+   [prop-name {:build/keys [property-classes] :as prop-m}]]
   (let [[new-block & additional-tx]
         (if-let [closed-values (seq (map #(merge {:uuid (random-uuid)} %) (:build/closed-values prop-m)))]
           (let [db-ident (get-ident all-idents prop-name)]
@@ -156,7 +157,7 @@
                                  (throw (ex-info "No :db/id for property" {:property prop-name})))}
                      (select-keys prop-m [:build/properties-ref-types]))}))
           [(merge (sqlite-util/build-new-property (get-ident all-idents prop-name)
-                                                  (:block/schema prop-m)
+                                                  (db-property/get-property-schema prop-m)
                                                   {:block-uuid (:block/uuid prop-m)
                                                    :title (:block/title prop-m)})
                   {:db/id (or (property-db-ids prop-name)
@@ -173,10 +174,10 @@
         new-block
         (when-let [props (not-empty (:build/properties prop-m))]
           (->block-properties (merge props (db-property-build/build-properties-with-ref-values pvalue-tx-m)) page-uuids all-idents))
-        (when (seq schema-classes)
-          {:property/schema.classes
+        (when (seq property-classes)
+          {:logseq.property/classes
            (mapv #(hash-map :db/ident (get-ident all-idents %))
-                 schema-classes)})))
+                 property-classes)})))
       true
       (into additional-tx))))
 
@@ -195,7 +196,7 @@
                           (into {}))
         classes-tx (vec
                     (mapcat
-                     (fn [[class-name {:build/keys [class-parent schema-properties] :as class-m}]]
+                     (fn [[class-name {:build/keys [class-parent class-properties] :as class-m}]]
                        (let [db-ident (get-ident all-idents class-name)
                              new-block
                              (sqlite-util/build-new-class
@@ -214,17 +215,17 @@
                            (conj
                             (merge
                              new-block
-                             (dissoc class-m :build/properties :build/class-parent :build/schema-properties)
+                             (dissoc class-m :build/properties :build/class-parent :build/class-properties)
                              (when-let [props (not-empty (:build/properties class-m))]
                                (->block-properties (merge props (db-property-build/build-properties-with-ref-values pvalue-tx-m)) uuid-maps all-idents))
                              (when class-parent
                                {:logseq.property/parent
                                 (or (class-db-ids class-parent)
                                     (throw (ex-info (str "No :db/id for " class-parent) {})))})
-                             (when schema-properties
+                             (when class-properties
                                {:logseq.property.class/properties
                                 (mapv #(hash-map :db/ident (get-ident all-idents %))
-                                      schema-properties)}))))))
+                                      class-properties)}))))))
                      classes))]
     classes-tx))
 
@@ -257,8 +258,6 @@
   [:map-of
    Property
    [:map
-    [:block/schema [:map
-                    [:type :keyword]]]
     [:build/properties {:optional true} User-properties]
     [:build/properties-ref-types {:optional true}
      [:map-of :keyword :keyword]]
@@ -268,7 +267,7 @@
                [:value [:or :string :double]]
                [:uuid {:optional true} :uuid]
                [:icon {:optional true} :map]]]]
-    [:build/schema-classes {:optional true} [:vector Class]]]])
+    [:build/property-classes {:optional true} [:vector Class]]]])
 
 (def Classes
   [:map-of
@@ -276,7 +275,7 @@
    [:map
     [:build/properties {:optional true} User-properties]
     [:build/class-parent {:optional true} Class]
-    [:build/schema-properties {:optional true} [:vector Property]]]])
+    [:build/class-properties {:optional true} [:vector Property]]]])
 
 (def Options
   [:map
@@ -290,7 +289,7 @@
 
 (defn- get-used-properties-from-options
   "Extracts all used properties as a map of properties to their property values. Looks at properties
-   from :build/properties and :build/schema-properties. Properties from :block/schema-properties have
+   from :build/properties and :build/class-properties. Properties from :build/class-properties have
    a ::no-value value"
   [{:keys [pages-and-blocks properties classes]}]
   (let [page-block-properties (->> pages-and-blocks
@@ -300,7 +299,7 @@
         property-properties (->> (vals properties)
                                  (mapcat #(into [] (:build/properties %))))
         class-properties (->> (vals classes)
-                              (mapcat #(concat (map (fn [p] [p ::no-value]) (:build/schema-properties %))
+                              (mapcat #(concat (map (fn [p] [p ::no-value]) (:build/class-properties %))
                                                (into [] (:build/properties %))))
                               set)
         props-to-values (->> (set/union class-properties page-block-properties property-properties)
@@ -502,9 +501,9 @@
                       :node
                       (db-property-type/infer-property-type-from-value prop-value'))
                     :default)]
-    (cond-> {:block/schema {:type prop-type}}
+    (cond-> {:logseq.property/type prop-type}
       (coll? prop-value)
-      (assoc-in [:block/schema :cardinality] :many))))
+      (assoc :db/cardinality :many))))
 
 (defn- auto-create-ontology
   "Auto creates properties and classes from uses of options.  Creates properties
@@ -541,8 +540,8 @@
         class-ident->id (->> classes-tx (map (juxt :db/ident :db/id)) (into {}))
         ;; Replace idents with db-ids to avoid any upsert issues
         properties-tx' (mapv (fn [m]
-                               (if (:property/schema.classes m)
-                                 (update m :property/schema.classes
+                               (if (:logseq.property/classes m)
+                                 (update m :logseq.property/classes
                                          (fn [cs]
                                            (mapv #(or (some->> (:db/ident %) class-ident->id (hash-map :db/id))
                                                       (throw (ex-info (str "No :db/id found for :db/ident " (pr-str (:db/ident %))) {})))
@@ -580,11 +579,11 @@
           Allows for outlines to be expressed to whatever depth
        * :build/properties - Defines properties on a block
    * :properties - This is a map to configure properties where the keys are property name keywords
-     and the values are maps of datascript attributes e.g. `{:block/schema {:type :checkbox}}`.
+     and the values are maps of datascript attributes e.g. `{:logseq.property/type :checkbox}`.
      Additional keys available:
      * :build/properties - Define properties on a property page.
      * :build/closed-values - Define closed values with a vec of maps. A map contains keys :uuid, :value and :icon.
-     * :build/schema-classes - Vec of class name keywords. Defines a property's range classes
+     * :build/property-classes - Vec of class name keywords. Defines a property's range classes
      * :build/properties-ref-types - Map of internal ref types to public ref types that are valid only for this property.
        Useful when remapping value ref types e.g. for :logseq.property/default-value
    * :classes - This is a map to configure classes where the keys are class name keywords
@@ -592,7 +591,7 @@
      Additional keys available:
      * :build/properties - Define properties on a class page
      * :build/class-parent - Add a class parent by its keyword name
-     * :build/schema-properties - Vec of property name keywords. Defines properties that a class gives to its objects
+     * :build/class-properties - Vec of property name keywords. Defines properties that a class gives to its objects
   * :graph-namespace - namespace to use for db-ident creation. Useful when importing an ontology
   * :auto-create-ontology? - When set to true, creates properties and classes from their use.
     See auto-create-ontology for more details

+ 55 - 35
deps/db/src/logseq/db/sqlite/create_graph.cljs

@@ -7,17 +7,27 @@
             [logseq.common.uuid :as common-uuid]
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.entity-util :as entity-util]
+            [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.order :as db-order]
             [logseq.db.frontend.property :as db-property]
-            [logseq.db.frontend.property.type :as db-property-type]
             [logseq.db.frontend.property.build :as db-property-build]
+            [logseq.db.frontend.property.type :as db-property-type]
             [logseq.db.frontend.schema :as db-schema]
-            [logseq.db.sqlite.util :as sqlite-util]
-            [logseq.db.frontend.malli-schema :as db-malli-schema]))
+            [logseq.db.sqlite.util :as sqlite-util]))
 
 (defn- mark-block-as-built-in [block]
   (assoc block :logseq.property/built-in? true))
 
+(defn- schema->qualified-property-keyword
+  [prop-schema]
+  (reduce-kv
+   (fn [r k v]
+     (if-let [new-k (and (simple-keyword? k) (db-property/schema-properties-map k))]
+       (assoc r new-k v)
+       (assoc r k v)))
+   {}
+   prop-schema))
+
 (defn- ->property-value-tx-m
   "Given a new block and its properties, creates a map of properties which have values of property value tx.
    This map is used for both creating the new property values and then adding them to a block"
@@ -29,28 +39,31 @@
                           ;; closed values are referenced by their :db/ident so no need to create values
                           (not (get-in db-property/built-in-properties [k :closed-values])))
                    (let [property-map {:db/ident k
-                                       :block/schema {:type built-in-type}}]
+                                       :logseq.property/type built-in-type}]
                      [property-map v])
                    (when-let [built-in-type' (get (:build/properties-ref-types new-block) built-in-type)]
                      (let [property-map {:db/ident k
-                                         :block/schema {:type built-in-type'}}]
+                                         :logseq.property/type built-in-type'}]
                        [property-map v]))))))
        (db-property-build/build-property-values-tx-m new-block)))
 
-(defn build-initial-properties*
+(defn build-properties
+  "Given a properties map in the format of db-property/built-in-properties, builds their properties tx"
   [built-in-properties]
   (mapcat
-   (fn [[db-ident {:keys [schema title closed-values properties] :as m}]]
-     (let [prop-name (or title (name (:name m)))
+   (fn [[db-ident {:keys [attribute schema title closed-values properties] :as m}]]
+     (let [db-ident (or attribute db-ident)
+           prop-name (or title (name (:name m)))
+           schema' (schema->qualified-property-keyword schema)
            [property & others] (if closed-values
                                  (db-property-build/build-closed-values
                                   db-ident
                                   prop-name
-                                  {:db/ident db-ident :block/schema schema :closed-values closed-values}
+                                  {:db/ident db-ident :schema schema' :closed-values closed-values}
                                   {})
                                  [(sqlite-util/build-new-property
                                    db-ident
-                                   schema
+                                   schema'
                                    {:title prop-name})])
            pvalue-tx-m (->property-value-tx-m
                         (merge property
@@ -78,35 +91,40 @@
                      properties
                      (db-property-build/build-properties-with-ref-values pvalue-tx-m))))]
        tx))
-   (dissoc built-in-properties :logseq.property/built-in?)))
+   built-in-properties))
+
+(defn- build-bootstrap-property
+  [db-ident]
+  (sqlite-util/build-new-property
+   db-ident
+   (schema->qualified-property-keyword (get-in db-property/built-in-properties [db-ident :schema]))
+   {:title (get-in db-property/built-in-properties [db-ident :title])}))
 
 (defn- build-initial-properties
   "Builds initial properties and their closed values and marks them
   as built-in?. Returns their tx data as well as data needed for subsequent build steps"
   []
-  (let [built-in-property-schema (get-in db-property/built-in-properties [:logseq.property/built-in? :schema])
-        built-in-property (sqlite-util/build-new-property
-                           :logseq.property/built-in?
-                           built-in-property-schema
-                           {:title (name :logseq.property/built-in?)})
-        mark-block-as-built-in' (fn [block]
-                                  (mark-block-as-built-in {:block/uuid (:block/uuid block)}))
-        properties (build-initial-properties* db-property/built-in-properties)
-        ;; Tx order matters. built-in-property must come first as all properties depend on it.
-        tx (concat [built-in-property]
-                   properties
-                   ;; Adding built-ins must come after initial properties
-                   [(mark-block-as-built-in' built-in-property)]
-                   (map mark-block-as-built-in' properties)
-                   (keep #(when (entity-util/closed-value? %)
-                            (mark-block-as-built-in' %))
-                         properties))]
+  ;; bootstrap-idents must either be necessary to define a property or be used on every property
+  (let [bootstrap-idents #{:logseq.property/type :logseq.property/hide? :logseq.property/built-in?}
+        bootstrap-properties (map build-bootstrap-property bootstrap-idents)
+        ;; First tx bootstrap properties so they can take affect. Then tx the bootstrap properties on themselves
+        bootstrap-properties-tx (into (mapv #(apply dissoc % bootstrap-idents) bootstrap-properties)
+                                      (mapv #(select-keys % (into [:block/uuid] bootstrap-idents))
+                                            bootstrap-properties))
+        properties-tx (build-properties (apply dissoc db-property/built-in-properties bootstrap-idents))
+        mark-block-as-built-in' (fn [b] (mark-block-as-built-in {:block/uuid (:block/uuid b)}))
+        ;; Tx order matters
+        tx (concat bootstrap-properties-tx
+                   properties-tx
+                   ;; Adding built-ins must come after its properties are defined
+                   (map mark-block-as-built-in' bootstrap-properties)
+                   (map mark-block-as-built-in' properties-tx))]
     (doseq [m tx]
       (when-let [block-uuid (and (:db/ident m) (:block/uuid m))]
         (assert (string/starts-with? (str block-uuid) "00000002") m)))
 
     {:tx tx
-     :properties (filter entity-util/property? properties)}))
+     :properties (filter entity-util/property? properties-tx)}))
 
 (def built-in-pages-names
   #{"Contents"})
@@ -128,7 +146,7 @@
      (let [title' (or title (name db-ident))]
        (mark-block-as-built-in
         (sqlite-util/build-new-class
-         (let [schema-properties (mapv
+         (let [class-properties (mapv
                                   (fn [db-ident]
                                     (let [property (get db-ident->properties db-ident)]
                                       (assert property (str "Built-in property " db-ident " is not defined yet"))
@@ -139,8 +157,8 @@
              :block/name (common-util/page-name-sanity-lc title')
              :db/ident db-ident
              :block/uuid (common-uuid/gen-uuid :db-ident-block-uuid db-ident)}
-             (seq schema-properties)
-             (assoc :logseq.property.class/properties schema-properties)
+             (seq class-properties)
+             (assoc :logseq.property.class/properties class-properties)
              (seq properties)
              (merge properties)))))))
    built-in-classes))
@@ -158,7 +176,7 @@
        :block/name common-config/views-page-name
        :block/title common-config/views-page-name
        :block/tags [:logseq.class/Page]
-       :block/schema {:public? false}
+       :logseq.property/hide? true
        :logseq.property/built-in? true})
      (sqlite-util/block-with-timestamps
       {:block/uuid (common-uuid/gen-uuid)
@@ -176,7 +194,7 @@
      :block/name common-config/favorites-page-name
      :block/title common-config/favorites-page-name
      :block/tags [:logseq.class/Page]
-     :block/schema {:public? false}
+     :logseq.property/hide? true
      :logseq.property/built-in? true})])
 
 (defn build-db-initial-data
@@ -222,7 +240,9 @@
         classes-tx (concat (map #(dissoc % :db/ident) bootstrap-classes)
                            (remove bootstrap-class? default-classes))
         ;; Order of tx is critical. bootstrap-class-ids bootstraps properties-tx and classes-tx
-        tx (vec (concat bootstrap-class-ids initial-data properties-tx classes-tx
+        ;; bootstrap-class-ids coming first is useful as Root, Tag and Property have stable :db/id's of 1, 2 and 3
+        tx (vec (concat bootstrap-class-ids
+                        initial-data properties-tx classes-tx
                         initial-files default-pages hidden-pages))]
     (validate-tx-for-duplicate-idents tx)
     tx))

+ 21 - 22
deps/db/src/logseq/db/sqlite/util.cljs

@@ -78,27 +78,26 @@
                      db-ident
                      (db-property/create-user-property-ident-from-name (name db-ident)))
          prop-name (or title (name db-ident'))
-         classes (:classes prop-schema)
-         prop-schema (assoc prop-schema :type (get prop-schema :type :default))]
-     (block-with-timestamps
-      (cond->
-       {:db/ident db-ident'
-        :block/tags #{:logseq.class/Property}
-        :block/schema (merge {:type :default} (dissoc prop-schema :classes :cardinality))
-        :block/name (common-util/page-name-sanity-lc (name prop-name))
-        :block/uuid (or block-uuid (common-uuid/gen-uuid :db-ident-block-uuid db-ident'))
-        :block/title (name prop-name)
-        :db/index true
-        :db/cardinality (if (= :many (:cardinality prop-schema))
-                          :db.cardinality/many
-                          :db.cardinality/one)
-        :block/order (db-order/gen-key)}
-        (seq classes)
-        (assoc :property/schema.classes classes)
-        (or ref-type? (contains? db-property-type/all-ref-property-types (:type prop-schema)))
-        (assoc :db/valueType :db.type/ref)
-        (seq properties)
-        (merge properties))))))
+         prop-type (get prop-schema :logseq.property/type :default)]
+     (merge
+      (dissoc prop-schema :db/cardinality)
+      (block-with-timestamps
+       (cond->
+        {:db/ident db-ident'
+         :block/tags #{:logseq.class/Property}
+         :logseq.property/type prop-type
+         :block/name (common-util/page-name-sanity-lc (name prop-name))
+         :block/uuid (or block-uuid (common-uuid/gen-uuid :db-ident-block-uuid db-ident'))
+         :block/title (name prop-name)
+         :db/index true
+         :db/cardinality (if (= :many (:db/cardinality prop-schema))
+                           :db.cardinality/many
+                           :db.cardinality/one)
+         :block/order (db-order/gen-key)}
+         (or ref-type? (contains? db-property-type/all-ref-property-types prop-type))
+         (assoc :db/valueType :db.type/ref)
+         (seq properties)
+         (merge properties)))))))
 
 (defn build-new-class
   "Build a standard new class so that it is consistent across contexts"
@@ -122,7 +121,7 @@
 
 (defn kv
   "Creates a key-value pair tx with the key and value respectively stored under
-  :db/ident and :kv/value.  The key must be under the namespace :logseq.kv"
+  :db/ident and :kv/value. The key must be under the namespace :logseq.kv"
   [k value]
   {:pre [(= "logseq.kv" (namespace k))]}
   {:db/ident k

+ 9 - 7
deps/db/test/logseq/db/frontend/rules_test.cljs

@@ -28,8 +28,8 @@
 
 (deftest has-property-rule
   (let [conn (db-test/create-conn-with-blocks
-              {:properties {:foo {:block/schema {:type :default}}
-                            :foo2 {:block/schema {:type :default}}}
+              {:properties {:foo {:logseq.property/type :default}
+                            :foo2 {:logseq.property/type :default}}
                :pages-and-blocks
                [{:page {:block/title "Page1"
                         :build/properties {:foo "bar"}}}]})]
@@ -44,7 +44,7 @@
                               @conn)
                 (map (comp :block/title first))))
         "has-property returns no result when block doesn't have property")
-    (is (= [:user.property/foo :block/tags]
+    (is (= [:block/tags :user.property/foo]
            (q-with-rules '[:find [?p ...]
                            :where (has-property ?b ?p) [?b :block/title "Page1"]]
                          @conn))
@@ -52,10 +52,12 @@
 
 (deftest property-rule
   (let [conn (db-test/create-conn-with-blocks
-              {:properties {:foo {:block/schema {:type :default}}
-                            :foo2 {:block/schema {:type :default}}
-                            :number-many {:block/schema {:type :number :cardinality :many}}
-                            :page-many {:block/schema {:type :node :cardinality :many}}}
+              {:properties {:foo {:logseq.property/type :default}
+                            :foo2 {:logseq.property/type :default}
+                            :number-many {:logseq.property/type :number
+                                          :db/cardinality :many}
+                            :page-many {:logseq.property/type :node
+                                        :db/cardinality :many}}
                :pages-and-blocks
                [{:page {:block/title "Page1"
                         :build/properties {:foo "bar" :number-many #{5 10} :page-many #{[:page "Page A"]}}}}

+ 22 - 12
deps/db/test/logseq/db/sqlite/create_graph_test.cljs

@@ -1,16 +1,16 @@
 (ns logseq.db.sqlite.create-graph-test
   (:require [cljs.test :refer [deftest is testing]]
-            [clojure.string :as string]
             [clojure.set :as set]
+            [clojure.string :as string]
             [datascript.core :as d]
+            [logseq.db :as ldb]
+            [logseq.db.frontend.class :as db-class]
+            [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.schema :as db-schema]
-            [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.frontend.validate :as db-validate]
-            [logseq.db.frontend.property :as db-property]
             [logseq.db.sqlite.build :as sqlite-build]
-            [logseq.db :as ldb]
-            [logseq.db.test.helper :as db-test]
-            [logseq.db.frontend.class :as db-class]))
+            [logseq.db.sqlite.create-graph :as sqlite-create-graph]
+            [logseq.db.test.helper :as db-test]))
 
 (deftest new-graph-db-idents
   (testing "a new graph follows :db/ident conventions for"
@@ -29,7 +29,7 @@
         (is (= []
                (->> (remove db-property/db-attribute-properties default-idents)
                     (keep namespace)
-                    (remove #(string/starts-with? % "logseq."))))
+                    (remove #(string/starts-with? % "logseq"))))
             "All default :db/ident namespaces start with logseq."))
 
       (testing "closed values"
@@ -76,8 +76,9 @@
 
 (deftest new-graph-initializes-default-classes-correctly
   (let [conn (db-test/create-conn)]
-    (is (= (count db-class/built-in-classes) (count (d/datoms @conn :avet :block/tags :logseq.class/Tag)))
-        "Number of built-in classes equals number of ents with :logseq.class/Tag")
+    (is (= (set (keys db-class/built-in-classes))
+           (set (map #(:db/ident (d/entity @conn (:e %))) (d/datoms @conn :avet :block/tags :logseq.class/Tag))))
+        "All built-in classes are indexed by :block/tags with :logseq.class/Tag")
 
     (is (= (count (dissoc db-class/built-in-classes :logseq.class/Root))
            (count (->> (d/datoms @conn :avet :block/tags :logseq.class/Tag)
@@ -88,8 +89,17 @@
 
 (deftest new-graph-initializes-default-properties-correctly
   (let [conn (db-test/create-conn)]
-    (is (= (count db-property/built-in-properties) (count (d/datoms @conn :avet :block/tags :logseq.class/Property)))
-        "Number of built-in properties equals number of ents with :logseq.class/Property")
+    (is (= (set (keys db-property/built-in-properties))
+           (set (map #(:db/ident (d/entity @conn (:e %))) (d/datoms @conn :avet :block/tags :logseq.class/Property))))
+        "All built-in properties are indexed by :block/tags with :logseq.class/Property")
+    (is (= (set (keys db-property/built-in-properties))
+           (set (map #(:db/ident (d/entity @conn (:e %))) (d/datoms @conn :avet :logseq.property/type))))
+        "All built-in properties have and are indexed by :logseq.property/type")
+    (is (= #{}
+           (set/difference
+            (set (keys db-property/built-in-properties))
+            (set (map #(:db/ident (d/entity @conn (:e %))) (d/datoms @conn :avet :logseq.property/built-in?)))))
+        "All built-in properties have and are indexed by :logseq.property/built-in?")
 
     ;; testing :properties config
     (testing "A built-in property that has"
@@ -131,7 +141,7 @@
     (testing ":url property"
       (sqlite-build/create-blocks
        conn
-       {:properties {:url {:block/schema {:type :url}}}
+       {:properties {:url {:logseq.property/type :url}}
         :pages-and-blocks
         [{:page {:block/title "page1"}
           :blocks [{:block/title "b1" :build/properties {:url "https://logseq.com"}}

+ 5 - 5
deps/db/test/logseq/db_test.cljs

@@ -1,8 +1,8 @@
 (ns logseq.db-test
   (:require [cljs.test :refer [deftest is]]
-            [logseq.db.frontend.schema :as db-schema]
             [datascript.core :as d]
             [logseq.db :as ldb]
+            [logseq.db.frontend.schema :as db-schema]
             [logseq.db.test.helper :as db-test]))
 
 ;;; datoms
@@ -55,8 +55,8 @@
 (deftest get-case-page
   (let [conn (db-test/create-conn-with-blocks
               {:properties
-               {:foo {:block/schema {:type :default}}
-                :Foo {:block/schema {:type :default}}}
+               {:foo {:logseq.property/type :default}
+                :Foo {:logseq.property/type :default}}
                :classes {:movie {} :Movie {}}})]
     ;; Case sensitive properties
     (is (= "foo" (:block/title (ldb/get-case-page @conn "foo"))))
@@ -68,8 +68,8 @@
 (deftest page-exists
   (let [conn (db-test/create-conn-with-blocks
               {:properties
-               {:foo {:block/schema {:type :default}}
-                :Foo {:block/schema {:type :default}}}
+               {:foo {:logseq.property/type :default}
+                :Foo {:logseq.property/type :default}}
                :classes {:movie {} :Movie {}}})]
     (is (= ["foo"]
            (map #(:block/title (d/entity @conn %)) (ldb/page-exists? @conn "foo" #{:logseq.class/Property})))

+ 3 - 3
deps/graph-parser/script/db_import.cljs

@@ -6,6 +6,7 @@
             ["fs/promises" :as fsp]
             ["os" :as os]
             ["path" :as node-path]
+            #_:clj-kondo/ignore
             [babashka.cli :as cli]
             [cljs.pprint :as pprint]
             [clojure.set :as set]
@@ -13,7 +14,6 @@
             [datascript.core :as d]
             [logseq.common.graph :as common-graph]
             [logseq.graph-parser.exporter :as gp-exporter]
-            #_:clj-kondo/ignore
             [logseq.outliner.cli :as outliner-cli]
             [nbb.classpath :as cp]
             [nbb.core :as nbb]
@@ -112,8 +112,8 @@
         files' (mapv #(hash-map :path %)
                      (into [file] (map resolve-path files)))]
     (p/with-redefs [d/transact! dev-transact!]
-     (p/let [_ (gp-exporter/export-doc-files conn files' <read-file doc-options)]
-       {:import-state (:import-state doc-options)}))))
+      (p/let [_ (gp-exporter/export-doc-files conn files' <read-file doc-options)]
+        {:import-state (:import-state doc-options)}))))
 
 (def spec
   "Options spec"

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

@@ -370,7 +370,7 @@
 
 (defn- infer-property-schema-and-get-property-change
   "Infers a property's schema from the given _user_ property value and adds new ones to
-  the property-schemas atom. If a property's :type changes, returns a map of
+  the property-schemas atom. If a property's :logseq.property/type changes, returns a map of
   the schema attribute changed and how it changed e.g. `{:type {:from :default :to :url}}`"
   [db prop-val prop prop-val-text refs {:keys [property-schemas all-idents]} macros]
   ;; Explicitly fail an unexpected case rather than cause silent downstream failures
@@ -390,15 +390,15 @@
                         :else
                         (db-property-type/infer-property-type-from-value
                          (macro-util/expand-value-if-macro prop-val macros)))
-        prev-type (get-in @property-schemas [prop :type])]
+        prev-type (get-in @property-schemas [prop :logseq.property/type])]
     ;; Create new property
     (when-not (get @property-schemas prop)
       (create-property-ident db all-idents prop)
-      (let [schema (cond-> {:type prop-type}
+      (let [schema (cond-> {:logseq.property/type prop-type}
                      (#{:node :date} prop-type)
                      ;; Assume :many for now as detecting that detecting property values across files are consistent
                      ;; isn't possible yet
-                     (assoc :cardinality :many))]
+                     (assoc :db/cardinality :many))]
         (swap! property-schemas assoc prop schema)))
     (when (and prev-type (not= prev-type prop-type))
       {:type {:from prev-type :to prop-type}})))
@@ -555,7 +555,7 @@
       ;; Change to :node as dates can be pages but pages can't be dates
       (= {:from :date :to :node} type-change)
       (do
-        (swap! property-schemas assoc-in [prop :type] :node)
+        (swap! property-schemas assoc-in [prop :logseq.property/type] :node)
         (update-page-or-date-values page-names-to-uuids val))
 
       ;; Unlike the other property changes, this one changes all the previous values of a property
@@ -568,9 +568,9 @@
           (swap! ignored-properties conj {:property prop :value val :schema (get property-changes prop)})
           nil)
         (do
-          (swap! upstream-properties assoc prop {:schema {:type :default}
+          (swap! upstream-properties assoc prop {:schema {:logseq.property/type :default}
                                                  :from-type (:from type-change)})
-          (swap! property-schemas assoc prop {:type :default})
+          (swap! property-schemas assoc prop {:logseq.property/type :default})
           (get properties-text-values prop)))
 
       :else
@@ -590,7 +590,7 @@
                    [prop val'])
                  [prop
                   (if (set? val)
-                    (if (= :default (:type (get @property-schemas prop)))
+                    (if (= :default (:logseq.property/type (get @property-schemas prop)))
                       (get properties-text-values prop)
                       (update-page-or-date-values page-names-to-uuids val))
                     val)])))
@@ -607,12 +607,13 @@
                             ;; closed values are referenced by their :db/ident so no need to create values
                             (not (get-in db-property/built-in-properties [k :closed-values])))
                    (let [property-map {:db/ident k
-                                       :block/schema {:type built-in-type}}]
+                                       :logseq.property/type built-in-type}]
                      [property-map v]))
-                 (when (db-property-type/value-ref-property-types (:type (get-schema-fn k)))
-                   (let [property-map {:db/ident (get-ident all-idents k)
-                                       :original-property-id k
-                                       :block/schema (get-schema-fn k)}]
+                 (when (db-property-type/value-ref-property-types (:logseq.property/type (get-schema-fn k)))
+                   (let [property-map (merge
+                                       {:db/ident (get-ident all-idents k)
+                                        :original-property-id k}
+                                       (get-schema-fn k))]
                      [property-map v])))))
        (db-property-build/build-property-values-tx-m new-block)))
 
@@ -1093,9 +1094,9 @@
            (fn [[prop {:keys [schema from-type]}]]
              (let [prop-ident (get-ident all-idents prop)
                    upstream-tx
-                   (when (= :default (:type schema))
+                   (when (= :default (:logseq.property/type schema))
                      (build-upstream-properties-tx-for-default db prop prop-ident from-type block-properties-text-values))
-                   property-pages-tx [{:db/ident prop-ident :block/schema schema}]]
+                   property-pages-tx [(merge {:db/ident prop-ident} schema)]]
                ;; If we handle cardinality changes we would need to return these separately
                ;; as property-pages would need to be transacted separately
                (concat property-pages-tx upstream-tx)))
@@ -1113,7 +1114,7 @@
    :ignored-properties (atom [])
    ;; Vec of maps with keys :path and :reason
    :ignored-files (atom [])
-   ;; Map of property names (keyword) and their current schemas (map).
+   ;; Map of property names (keyword) and their current schemas (map of qualified properties).
    ;; Used for adding schemas to properties and detecting changes across a property's usage
    :property-schemas (atom {})
    ;; Map of property or class names (keyword) to db-ident keywords
@@ -1167,7 +1168,7 @@
                                                               (get-property-schema @(:property-schemas import-state) kw-name)
                                                               {:title (name kw-name)})]
                  (assert existing-page-uuid)
-                 (merge (select-keys new-prop [:block/tags :block/schema :db/ident :db/index :db/cardinality :db/valueType])
+                 (merge (select-keys new-prop [:block/tags :db/ident :logseq.property/type :db/index :db/cardinality :db/valueType])
                         {:block/uuid existing-page-uuid})))
              (set/intersection new-properties (set (map keyword (keys existing-pages)))))
         ;; Could do this only for existing pages but the added complexity isn't worth reducing the tx noise

+ 15 - 15
deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs

@@ -230,24 +230,24 @@
                   (remove #(db-malli-schema/internal-ident? (:db/ident %)))
                   count))
           "Correct number of user properties")
-      (is (= #{{:db/ident :user.property/prop-bool :block/schema {:type :checkbox}}
-               {:db/ident :user.property/prop-string :block/schema {:type :default}}
-               {:db/ident :user.property/prop-num :block/schema {:type :number}}
-               {:db/ident :user.property/sameas :block/schema {:type :url}}
-               {:db/ident :user.property/rangeincludes :block/schema {:type :node}}
-               {:db/ident :user.property/startedat :block/schema {:type :date}}}
+      (is (= #{{:db/ident :user.property/prop-bool :logseq.property/type :checkbox}
+               {:db/ident :user.property/prop-string :logseq.property/type :default}
+               {:db/ident :user.property/prop-num :logseq.property/type :number}
+               {:db/ident :user.property/sameas :logseq.property/type :url}
+               {:db/ident :user.property/rangeincludes :logseq.property/type :node}
+               {:db/ident :user.property/startedat :logseq.property/type :date}}
              (->> @conn
-                  (d/q '[:find [(pull ?b [:db/ident :block/schema]) ...]
+                  (d/q '[:find [(pull ?b [:db/ident :logseq.property/type]) ...]
                          :where [?b :block/tags :logseq.class/Property]])
                   (filter #(contains? #{:prop-bool :prop-string :prop-num :rangeincludes :sameas :startedat}
                                       (keyword (name (:db/ident %)))))
                   set))
           "Main property types have correct inferred :type")
       (is (= :default
-             (get-in (d/entity @conn :user.property/description) [:block/schema :type]))
+             (:logseq.property/type (d/entity @conn :user.property/description)))
           "Property value consisting of text and refs is inferred as :default")
       (is (= :url
-             (get-in (d/entity @conn :user.property/url) [:block/schema :type]))
+             (:logseq.property/type (d/entity @conn :user.property/url)))
           "Property value with a macro correctly inferred as :url")
 
       (is (= {:user.property/prop-bool true
@@ -429,14 +429,14 @@
 
     (testing "property :type changes"
       (is (= :node
-             (get-in (d/entity @conn :user.property/finishedat) [:block/schema :type]))
+             (:logseq.property/type (d/entity @conn :user.property/finishedat)))
           ":date property to :node value changes to :node")
       (is (= :node
-             (get-in (d/entity @conn :user.property/participants) [:block/schema :type]))
+             (:logseq.property/type (d/entity @conn :user.property/participants)))
           ":node property to :date value remains :node")
 
       (is (= :default
-             (get-in (d/entity @conn :user.property/description) [:block/schema :type]))
+             (:logseq.property/type (d/entity @conn :user.property/description)))
           ":default property to :node (or any non :default value) remains :default")
       (is (= "[[Jakob]]"
              (:user.property/description (readable-properties @conn (db-test/find-block-by-content @conn #":default to :node"))))
@@ -444,14 +444,14 @@
 
       (testing "with changes to upstream/existing property value"
         (is (= :default
-               (get-in (d/entity @conn :user.property/duration) [:block/schema :type]))
+               (:logseq.property/type (d/entity @conn :user.property/duration)))
             ":number property to :default value changes to :default")
         (is (= "20"
                (:user.property/duration (readable-properties @conn (db-test/find-block-by-content @conn "existing :number to :default"))))
             "existing :number property value correctly saved as :default")
 
-        (is (= {:block/schema {:type :default} :db/cardinality :db.cardinality/many}
-               (select-keys (d/entity @conn :user.property/people) [:block/schema :db/cardinality]))
+        (is (= {:logseq.property/type :default :db/cardinality :db.cardinality/many}
+               (select-keys (d/entity @conn :user.property/people) [:logseq.property/type :db/cardinality]))
             ":node property to :default value changes to :default and keeps existing cardinality")
         (is (= #{"[[Jakob]] [[Gabriel]]"}
                (:user.property/people (readable-properties @conn (db-test/find-block-by-content @conn ":node people"))))

+ 5 - 5
deps/outliner/src/logseq/outliner/pipeline.cljs

@@ -3,12 +3,12 @@
   (:require [clojure.set :as set]
             [datascript.core :as d]
             [datascript.impl.entity :as de]
+            [logseq.common.util.date-time :as date-time-util]
             [logseq.db :as ldb]
             [logseq.db.frontend.content :as db-content]
             [logseq.db.frontend.entity-plus :as entity-plus]
             [logseq.db.frontend.property :as db-property]
-            [logseq.outliner.datascript-report :as ds-report]
-            [logseq.common.util.date-time :as date-time-util]))
+            [logseq.outliner.datascript-report :as ds-report]))
 
 (defn filter-deleted-blocks
   [datoms]
@@ -25,7 +25,7 @@
                             (keep (fn [id]
                                     (when-let [entity (d/entity db-after [:block/uuid id])]
                                       (let [from-property (:logseq.property/created-from-property entity)
-                                            default? (= :default (get-in from-property [:block/schema :type]))
+                                            default? (= :default (:logseq.property/type from-property))
                                             page? (ldb/page? entity)]
                                         (when-not (or page? (and from-property (not default?)))
                                           [(:db/id entity)
@@ -68,7 +68,7 @@
   (let [*computed-ids (atom #{})
         blocks (remove (fn [block]
                          (let [from-property (:logseq.property/created-from-property block)
-                               default? (= :default (get-in from-property [:block/schema :type]))]
+                               default? (= :default (:logseq.property/type from-property))]
                            (and from-property (not default?))))
                        blocks*)]
     (->>
@@ -181,7 +181,7 @@
                                              (map :db/id v)
 
                                              :else
-                                             (let [datetime? (= :datetime (get-in (d/entity db property) [:block/schema :type]))]
+                                             (let [datetime? (= :datetime (:logseq.property/type (d/entity db property)))]
                                                (cond
                                                  (and datetime? (coll? v))
                                                  (keep #(get-journal-day-from-long db %) v)

+ 43 - 38
deps/outliner/src/logseq/outliner/property.cljs

@@ -74,7 +74,7 @@
 
 (defn ^:api convert-property-input-string
   [block-type property v-str]
-  (let [schema-type (get-in property [:block/schema :type])]
+  (let [schema-type (:logseq.property/type property)]
     (if (and (or (= :number schema-type)
                  (and (= (:db/ident property) :logseq.property/default-value)
                       (= :number block-type)))
@@ -83,19 +83,23 @@
       v-str)))
 
 (defn- update-datascript-schema
-  [property {type' :type :keys [cardinality]}]
-  (let [ident (:db/ident property)
+  "Updates property type and cardinality"
+  [property schema]
+  (let [new-type (:logseq.property/type schema)
+        cardinality (:db/cardinality schema)
+        ident (:db/ident property)
         cardinality (if (= cardinality :many) :db.cardinality/many :db.cardinality/one)
-        old-type (get-in property [:block/schema :type])
+        old-type (:logseq.property/type property)
         old-ref-type? (db-property-type/user-ref-property-types old-type)
-        ref-type? (db-property-type/user-ref-property-types type')]
-    [(cond->
-      {:db/ident ident
-       :db/cardinality cardinality}
-       ref-type?
-       (assoc :db/valueType :db.type/ref))
-     (when (and old-ref-type? (not ref-type?))
-       [:db/retract (:db/id property) :db/valueType])]))
+        ref-type? (db-property-type/user-ref-property-types new-type)]
+    (cond-> [(cond->
+              (outliner-core/block-with-updated-at
+               {:db/ident ident
+                :db/cardinality cardinality})
+               ref-type?
+               (assoc :db/valueType :db.type/ref))]
+      (and new-type old-ref-type? (not ref-type?))
+      (conj [:db/retract (:db/id property) :db/valueType]))))
 
 (defn- update-property
   [conn db-ident property schema {:keys [property-name properties]}]
@@ -106,9 +110,11 @@
 
   (let [changed-property-attrs
         ;; Only update property if something has changed as we are updating a timestamp
-        (cond-> {}
-          (not= schema (:block/schema property))
-          (assoc :block/schema schema)
+        (cond-> (->> (dissoc schema :db/cardinality)
+                     (keep (fn [[k v]]
+                             (when-not (= (get property k) v)
+                               [k v])))
+                     (into {}))
           (and (some? property-name) (not= property-name (:block/title property)))
           (assoc :block/title property-name
                  :block/name (common-util/page-name-sanity-lc property-name)))
@@ -117,18 +123,19 @@
           (seq changed-property-attrs)
           (conj (outliner-core/block-with-updated-at
                  (merge {:db/ident db-ident}
-                        (common-util/dissoc-in changed-property-attrs [:block/schema :cardinality]))))
-          (or (not= (:type schema) (get-in property [:block/schema :type]))
-              (and (:cardinality schema) (not= (:cardinality schema) (keyword (name (:db/cardinality property)))))
-              (and (= :default (:type schema)) (not= :db.type/ref (:db/valueType property)))
-              (seq (:property/closed-values property)))
+                        changed-property-attrs)))
+          (and (seq schema)
+               (or (not= (:logseq.property/type schema) (:logseq.property/type property))
+                   (and (:db/cardinality schema) (not= (:db/cardinality schema) (keyword (name (:db/cardinality property)))))
+                   (and (= :default (:logseq.property/type schema)) (not= :db.type/ref (:db/valueType property)))
+                   (seq (:property/closed-values property))))
           (concat (update-datascript-schema property schema)))
         tx-data (concat property-tx-data
                         (when (seq properties)
                           (mapcat
                            (fn [[property-id v]]
                              (build-property-value-tx-data conn property property-id v)) properties)))
-        many->one? (and (db-property/many? property) (= :one (:cardinality schema)))]
+        many->one? (and (db-property/many? property) (= :one (:db/cardinality schema)))]
     (when (and many->one? (seq (d/datoms @conn :avet db-ident)))
       (throw (ex-info "Disallowed many to one conversion"
                       {:type :notification
@@ -177,7 +184,7 @@
 
 (defn validate-property-value
   [db property value]
-  (let [property-type (get-in property [:block/schema :type])
+  (let [property-type (:logseq.property/type property)
         many? (= :db.cardinality/many (:db/cardinality property))
         schema (get-property-value-schema db property-type property)]
     (validate-property-value-aux schema value {:many? many?})))
@@ -212,7 +219,7 @@
   (let [property (d/entity @conn property-id)
         block (when block-id (d/entity @conn block-id))
         _ (assert (some? property) (str "Property " property-id " doesn't exist yet"))
-        value' (convert-property-input-string (get-in block [:block/schema :type])
+        value' (convert-property-input-string (:logseq.property/type block)
                                               property value)
         new-value-block (cond-> (db-property-build/build-property-value-block (or block property) property value')
                           new-block-id
@@ -221,7 +228,7 @@
     (let [property-id (:db/ident property)]
       (when (and property-id block)
         (when-let [block-id (:db/id (d/entity @conn [:block/uuid (:block/uuid new-value-block)]))]
-          (raw-set-block-property! conn block property (get-in property [:block/schema :type]) block-id)))
+          (raw-set-block-property! conn block property (:logseq.property/type property) block-id)))
       (:block/uuid new-value-block))))
 
 (defn- get-property-value-eid
@@ -232,7 +239,7 @@
           :where
           [?b ?property-id ?v]
           (or [?v :block/title ?raw-value]
-              [?v :property.value/content ?raw-value])]
+              [?v :logseq.property/value ?raw-value])]
         db
         property-id
         raw-value)))
@@ -242,7 +249,7 @@
   [conn property-id v]
   (let [property (d/entity @conn property-id)
         closed-values? (seq (:property/closed-values property))
-        default-type? (= :default (get-in property [:block/schema :type]))]
+        default-type? (= :default (:logseq.property/type property))]
     (cond
       closed-values?
       (get-property-value-eid @conn property-id v)
@@ -295,7 +302,7 @@
       :else
       (let [property (d/entity @conn property-id)
             _ (assert (some? property) (str "Property " property-id " doesn't exist yet"))
-            property-type (get-in property [:block/schema :type] :default)
+            property-type (get property :logseq.property/type :default)
             new-value (if (db-property-type/all-ref-property-types property-type)
                         (convert-ref-property-value conn property-id v property-type)
                         v)
@@ -318,7 +325,7 @@
              (if (number? v) (d/entity @conn v) v)
              (map #(d/entity @conn %) block-eids)))
         _ (assert (some? property) (str "Property " property-id " doesn't exist yet"))
-        property-type (get-in property [:block/schema :type] :default)
+        property-type (get property :logseq.property/type :default)
         _ (assert (some? v) "Can't set a nil property value must be not nil")
         v' (if (db-property-type/value-ref-property-types property-type)
              (convert-ref-property-value conn property-id v property-type)
@@ -461,20 +468,19 @@
 (defn- property-with-position?
   [db property-id block position]
   (when-let [property (entity-plus/entity-memoized db property-id)]
-    (let [schema (:block/schema property)]
+    (let [property-position (:logseq.property/ui-position property)]
       (and
-       (= (:position schema) position)
+       (= property-position position)
        (not (and (:logseq.property/hide-empty-value property)
                  (nil? (get block property-id))))
-       (not (get-in property [:block/schema :hide?]))
+       (not (:logseq.property/hide? property))
        (not (and
-             (= (:position schema) :block-below)
+             (= property-position :block-below)
              (nil? (get block property-id))))))))
 
 (defn property-with-other-position?
   [property]
-  (let [schema (:block/schema property)]
-    (not (contains? #{:properties nil} (:position schema)))))
+  (not (contains? #{:properties nil} (:logseq.property/ui-position property))))
 
 (defn get-block-positioned-properties
   [db eid position]
@@ -500,8 +506,8 @@
                      (merge
                       {:block/uuid id
                        :block/closed-value-property (:db/id property)}
-                      (if (db-property-type/property-value-content? (get-in block [:block/schema :type]) property)
-                        {:property.value/content resolved-value}
+                      (if (db-property-type/property-value-content? (:logseq.property/type block) property)
+                        {:logseq.property/value resolved-value}
                         {:block/title resolved-value})))
                      icon
                      (assoc :logseq.property/icon icon))]
@@ -523,8 +529,7 @@
   (assert (or (nil? id) (uuid? id)))
   (let [db @conn
         property (d/entity db property-id)
-        property-schema (:block/schema property)
-        property-type (get property-schema :type :default)]
+        property-type (:logseq.property/type property)]
     (when (contains? db-property-type/closed-value-property-types property-type)
       (let [value' (if (string? value) (string/trim value) value)
             resolved-value (convert-property-input-string nil property value')

+ 8 - 8
deps/outliner/test/logseq/outliner/pipeline_test.cljs

@@ -1,15 +1,15 @@
 (ns logseq.outliner.pipeline-test
   (:require [cljs.test :refer [deftest is testing]]
-            [logseq.db.frontend.schema :as db-schema]
+            [clojure.set :as set]
+            [clojure.string :as string]
             [datascript.core :as d]
-            [logseq.db.sqlite.create-graph :as sqlite-create-graph]
+            [logseq.common.util.page-ref :as page-ref]
+            [logseq.db.frontend.schema :as db-schema]
             [logseq.db.sqlite.build :as sqlite-build]
-            [logseq.outliner.db-pipeline :as db-pipeline]
-            [logseq.outliner.pipeline :as outliner-pipeline]
-            [clojure.string :as string]
+            [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.test.helper :as db-test]
-            [logseq.common.util.page-ref :as page-ref]
-            [clojure.set :as set]))
+            [logseq.outliner.db-pipeline :as db-pipeline]
+            [logseq.outliner.pipeline :as outliner-pipeline]))
 
 (defn- get-blocks [db]
   (->> (d/q '[:find (pull ?b [* {:block/path-refs [:block/name :db/id]}])
@@ -51,7 +51,7 @@
                               ;; Only keep enough of content to uniquely identify block
                               (map #(hash-map :block/title (re-find #"\w+" (:block/title %))
                                               :path-ref-names (set (map :block/name (:block/path-refs %))))))
-          page-tag-refs #{"tags" "page"}]
+          page-tag-refs #{"page" "tags"}]
       (is (= [{:block/title "parent"
                :path-ref-names (set/union page-tag-refs #{"page1" "bar"})}
               {:block/title "child"

+ 31 - 21
deps/outliner/test/logseq/outliner/property_test.cljs

@@ -1,32 +1,42 @@
 (ns logseq.outliner.property-test
   (:require [cljs.test :refer [deftest is testing are]]
             [datascript.core :as d]
-            [logseq.outliner.property :as outliner-property]
+            [logseq.db :as ldb]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.test.helper :as db-test]
-            [logseq.db :as ldb]))
+            [logseq.outliner.property :as outliner-property]))
 
 (deftest upsert-property!
   (testing "Creates a property"
     (let [conn (db-test/create-conn-with-blocks [])
-          _ (outliner-property/upsert-property! conn nil {:type :number} {:property-name "num"})]
-      (is (= {:type :number}
-             (:block/schema (d/entity @conn :user.property/num)))
+          _ (outliner-property/upsert-property! conn nil {:logseq.property/type :number} {:property-name "num"})]
+      (is (= :number
+             (:logseq.property/type (d/entity @conn :user.property/num)))
           "Creates property with property-name")))
 
   (testing "Updates a property"
-    (let [conn (db-test/create-conn-with-blocks {:properties {:num {:block/schema {:type :number}}}})
-          _ (outliner-property/upsert-property! conn :user.property/num {:type :default :cardinality :many} {})]
-      (is (db-property/many? (d/entity @conn :user.property/num)))))
+    (let [conn (db-test/create-conn-with-blocks {:properties {:num {:logseq.property/type :number}}})
+          old-updated-at (:block/updated-at (d/entity @conn :user.property/num))]
+
+      (testing "and change its cardinality"
+        (outliner-property/upsert-property! conn :user.property/num {:db/cardinality :many} {})
+        (is (db-property/many? (d/entity @conn :user.property/num)))
+        (is (> (:block/updated-at (d/entity @conn :user.property/num))
+               old-updated-at)))
+
+      (testing "and change its type from a ref to a non-ref type"
+        (outliner-property/upsert-property! conn :user.property/num {:logseq.property/type :checkbox} {})
+        (is (= :checkbox (:logseq.property/type (d/entity @conn :user.property/num))))
+        (is (= nil (:db/valueType (d/entity @conn :user.property/num)))))))
 
   (testing "Multiple properties that generate the same initial :db/ident"
     (let [conn (db-test/create-conn-with-blocks [])]
-      (outliner-property/upsert-property! conn nil {:type :default} {:property-name "p1"})
+      (outliner-property/upsert-property! conn nil {:logseq.property/type :default} {:property-name "p1"})
       (outliner-property/upsert-property! conn nil {} {:property-name "p1"})
       (outliner-property/upsert-property! conn nil {} {:property-name "p1"})
 
-      (is (= {:block/name "p1" :block/title "p1" :block/schema {:type :default}}
-             (select-keys (d/entity @conn :user.property/p1) [:block/name :block/title :block/schema]))
+      (is (= {:block/name "p1" :block/title "p1" :logseq.property/type :default}
+             (select-keys (d/entity @conn :user.property/p1) [:block/name :block/title :logseq.property/type]))
           "Existing db/ident does not get modified")
       (is (= "p1"
              (:block/title (d/entity @conn :user.property/p1-1)))
@@ -40,7 +50,7 @@
     (let [test-uuid (random-uuid)]
       (are [x y]
            (= (let [[schema-type value] x]
-                (outliner-property/convert-property-input-string nil {:block/schema {:type schema-type}} value)) y)
+                (outliner-property/convert-property-input-string nil {:logseq.property/type schema-type} value)) y)
         [:number "1"] 1
         [:number "1.2"] 1.2
         [:url test-uuid] test-uuid
@@ -210,7 +220,7 @@
 (deftest upsert-closed-value!
   (let [conn (db-test/create-conn-with-blocks
               {:properties {:num {:build/closed-values [{:uuid (random-uuid) :value 2}]
-                                  :block/schema {:type :number}}}})]
+                                  :logseq.property/type :number}}})]
 
     (testing "Add non-number choice shouldn't work"
       (is
@@ -228,13 +238,13 @@
 
     (testing "Add choice successfully"
       (let [_ (outliner-property/upsert-closed-value! conn :user.property/num {:value 3})
-            b (first (d/q '[:find [(pull ?b [*]) ...] :where [?b :property.value/content 3]] @conn))]
+            b (first (d/q '[:find [(pull ?b [*]) ...] :where [?b :logseq.property/value 3]] @conn))]
         (is (ldb/closed-value? (d/entity @conn (:db/id b))))
         (is (= [2 3]
                (map db-property/closed-value-content (:block/_closed-value-property (d/entity @conn :user.property/num)))))))
 
     (testing "Update choice successfully"
-      (let [b (first (d/q '[:find [(pull ?b [*]) ...] :where [?b :property.value/content 2]] @conn))
+      (let [b (first (d/q '[:find [(pull ?b [*]) ...] :where [?b :logseq.property/value 2]] @conn))
             _ (outliner-property/upsert-closed-value! conn :user.property/num {:id (:block/uuid b)
                                                                                :value 4
                                                                                :description "choice 4"})
@@ -248,7 +258,7 @@
         conn (db-test/create-conn-with-blocks
               {:properties {:default {:build/closed-values [{:uuid closed-value-uuid :value "foo"}
                                                             {:uuid used-closed-value-uuid :value "bar"}]
-                                      :block/schema {:type :default}}}
+                                      :logseq.property/type :default}}
                :pages-and-blocks
                [{:page {:block/title "page1"}
                  :blocks [{:block/title "b1" :user.property/default [:block/uuid used-closed-value-uuid]}]}]})
@@ -260,8 +270,8 @@
 (deftest class-add-property!
   (let [conn (db-test/create-conn-with-blocks
               {:classes {:c1 {}}
-               :properties {:p1 {:block/schema {:type :default}}
-                            :p2 {:block/schema {:type :default}}}})
+               :properties {:p1 {:logseq.property/type :default}
+                            :p2 {:logseq.property/type :default}}})
         _ (outliner-property/class-add-property! conn :user.class/c1 :user.property/p1)
         _ (outliner-property/class-add-property! conn :user.class/c1 :user.property/p2)]
     (is (= [:user.property/p1 :user.property/p2]
@@ -269,15 +279,15 @@
 
 (deftest class-remove-property!
   (let [conn (db-test/create-conn-with-blocks
-              {:classes {:c1 {:build/schema-properties [:p1 :p2]}}})
+              {:classes {:c1 {:build/class-properties [:p1 :p2]}}})
         _ (outliner-property/class-remove-property! conn :user.class/c1 :user.property/p1)]
     (is (= [:user.property/p2]
            (map :db/ident (:logseq.property.class/properties (d/entity @conn :user.class/c1)))))))
 
 (deftest get-block-classes-properties
   (let [conn (db-test/create-conn-with-blocks
-              {:classes {:c1 {:build/schema-properties [:p1]}
-                         :c2 {:build/schema-properties [:p2 :p3]}}
+              {:classes {:c1 {:build/class-properties [:p1]}
+                         :c2 {:build/class-properties [:p2 :p3]}}
                :pages-and-blocks
                [{:page {:block/title "p1"}
                  :blocks [{:block/title "o1"

+ 3 - 3
deps/outliner/test/logseq/outliner/validate_test.cljs

@@ -7,8 +7,8 @@
 
 (deftest validate-block-title-unique-for-properties
   (let [conn (db-test/create-conn-with-blocks
-              {:properties {:color {:block/schema {:type :default}}
-                            :color2 {:block/schema {:type :default}}}})]
+              {:properties {:color {:logseq.property/type :default}
+                            :color2 {:logseq.property/type :default}}})]
 
     (is (nil?
          (outliner-validate/validate-unique-by-name-tag-and-block-type
@@ -67,7 +67,7 @@
 
 (deftest validate-parent-property
   (let [conn (db-test/create-conn-with-blocks
-              {:properties {:prop1 {:block/schema {:type :default}}}
+              {:properties {:prop1 {:logseq.property/type :default}}
                :classes {:Class1 {} :Class2 {}}
                :pages-and-blocks
                [{:page {:block/title "page1"}}

+ 21 - 15
scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs

@@ -2,18 +2,20 @@
   "Script that generates all the permutations of property types and cardinality.
    Also creates a page of queries that exercises most properties
    NOTE: This script is also used in CI to confirm graph creation works"
-  (:require [logseq.outliner.cli :as outliner-cli]
-            [logseq.common.util.date-time :as date-time-util]
-            [logseq.common.util :as common-util]
-            [logseq.common.util.page-ref :as page-ref]
-            [logseq.db.frontend.property.type :as db-property-type]
-            [clojure.string :as string]
+  (:require ["fs-extra$default" :as fse]
+            ["fs" :as fs]
+            ["os" :as os]
+            ["path" :as node-path]
+            [babashka.cli :as cli]
             [clojure.edn :as edn]
             [clojure.set :as set]
+            [clojure.string :as string]
             [datascript.core :as d]
-            ["path" :as node-path]
-            ["os" :as os]
-            [babashka.cli :as cli]
+            [logseq.common.util :as common-util]
+            [logseq.common.util.date-time :as date-time-util]
+            [logseq.common.util.page-ref :as page-ref]
+            [logseq.db.frontend.property.type :as db-property-type]
+            [logseq.outliner.cli :as outliner-cli]
             [nbb.classpath :as cp]
             [nbb.core :as nbb]))
 
@@ -168,16 +170,17 @@
      :properties
      (->> db-property-type/user-built-in-property-types
           (mapcat #(cond-> (if (= :node %)
-                             [[% {:block/schema {:type %} :build/schema-classes [:TestClass]}]
-                              [:node-without-classes {:block/schema {:type %}}]]
-                             [[% {:block/schema {:type %}}]])
+                             [[% {:logseq.property/type % :build/property-classes [:TestClass]}]
+                              [:node-without-classes {:logseq.property/type %}]]
+                             [[% {:logseq.property/type %}]])
                      (contains? db-property-type/cardinality-property-types %)
                      (conj [(keyword (str (name %) "-many"))
-                            (cond-> {:block/schema {:type % :cardinality :many}}
+                            (cond-> {:logseq.property/type %
+                                     :db/cardinality :many}
                               (= :node %)
-                              (assoc :build/schema-classes [:TestClass]))])))
+                              (assoc :build/property-classes [:TestClass]))])))
           (into (mapv #(vector (keyword (str (name %) "-closed"))
-                               {:block/schema {:type %}
+                               {:logseq.property/type %
                                 :build/closed-values (closed-values-config (keyword (str (name %) "-closed")))})
                       [:default :url :number]))
           (into {}))}))
@@ -200,6 +203,9 @@
         [dir db-name] (if (string/includes? graph-dir "/")
                         ((juxt node-path/dirname node-path/basename) graph-dir)
                         [(node-path/join (os/homedir) "logseq" "graphs") graph-dir])
+        db-path (node-path/join dir db-name "db.sqlite")
+        _ (when (fs/existsSync db-path)
+            (fse/removeSync db-path))
         conn (outliner-cli/init-conn dir db-name {:additional-config (:config options)
                                                   :classpath (cp/get-classpath)})
         {:keys [init-tx block-props-tx]} (outliner-cli/build-blocks-tx (create-init-data))

+ 32 - 32
scripts/src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs

@@ -10,20 +10,20 @@
      * Some properties are skipped because they are superseded/deprecated or because they have a property
        type logseq doesnt' support yet
      * schema.org assumes no cardinality. For now, only :node properties are given a :cardinality :many"
-  (:require [logseq.outliner.cli :as outliner-cli]
-            [logseq.db.frontend.property :as db-property]
-            [clojure.string :as string]
-            [clojure.edn :as edn]
-            [datascript.core :as d]
-            ["path" :as node-path]
+  (:require ["fs" :as fs]
             ["os" :as os]
-            ["fs" :as fs]
-            [nbb.classpath :as cp]
-            [nbb.core :as nbb]
+            ["path" :as node-path]
+            [babashka.cli :as cli]
+            [clojure.edn :as edn]
             [clojure.set :as set]
+            [clojure.string :as string]
             [clojure.walk :as w]
-            [babashka.cli :as cli]
-            [logseq.db.frontend.malli-schema :as db-malli-schema]))
+            [datascript.core :as d]
+            [logseq.db.frontend.malli-schema :as db-malli-schema]
+            [logseq.db.frontend.property :as db-property]
+            [logseq.outliner.cli :as outliner-cli]
+            [nbb.classpath :as cp]
+            [nbb.core :as nbb]))
 
 (defn- get-comment-string
   [rdfs-comment renamed-pages]
@@ -69,7 +69,7 @@
       parent-class'
       (assoc :build/class-parent (keyword (strip-schema-prefix parent-class')))
       (seq properties)
-      (assoc :build/schema-properties (mapv (comp keyword strip-schema-prefix) properties)))))
+      (assoc :build/class-properties (mapv (comp keyword strip-schema-prefix) properties)))))
 
 (def schema->logseq-data-types
   "Schema datatypes, https://schema.org/DataType, mapped to their Logseq equivalents"
@@ -113,18 +113,17 @@
 
         inverted-renamed-properties (set/map-invert renamed-properties)
         class-name (strip-schema-prefix (property-m "@id"))
-        url (str "https://schema.org/" (get inverted-renamed-properties class-name class-name))
-        schema (cond-> {:type schema-type}
-                 ;; This cardinality rule should be adjusted as we use schema.org more
-                 (= schema-type :node)
-                 (assoc :cardinality :many))]
+        url (str "https://schema.org/" (get inverted-renamed-properties class-name class-name))]
     {(keyword (strip-schema-prefix (property-m "@id")))
-     (cond-> {:block/schema schema
+     (cond-> {:logseq.property/type schema-type
               :build/properties (cond-> {:url url}
                                   (property-m "rdfs:comment")
                                   (assoc :logseq.property/description (get-comment-string (property-m "rdfs:comment") renamed-pages)))}
+       ;; This cardinality rule should be adjusted as we use schema.org more
+       (= schema-type :node)
+       (assoc :db/cardinality :many)
        (= schema-type :node)
-       (assoc :build/schema-classes (mapv (comp keyword strip-schema-prefix) range-includes)))}))
+       (assoc :build/property-classes (mapv (comp keyword strip-schema-prefix) range-includes)))}))
 
 (defn- get-class-to-properties
   "Given a vec of class ids and a vec of properties map to process, return a map of
@@ -260,7 +259,8 @@
    (apply merge
           (mapv #(->property-page % class-map options) select-properties))
    ;; Have to update schema for now as validation doesn't take into account existing properties
-   :logseq.property/description {:block/schema {:public? true :type :default}
+   :logseq.property/description {:logseq.property/public? true
+                                 :logseq.property/type :default
                                  :build/properties {:url "https://schema.org/description"
                                                     :logseq.property/description "A description of the item."}}))
 
@@ -334,8 +334,8 @@
           (let [select-class-ids' (->> select-class-ids (map (comp keyword strip-schema-prefix)) set)]
             (-> properties
                 (update-vals (fn [m]
-                               (if (:build/schema-classes m)
-                                 (update m :build/schema-classes
+                               (if (:build/property-classes m)
+                                 (update m :build/property-classes
                                          (fn [cs] (vec (set (filter #(contains? select-class-ids' %) cs)))))
                                  m)))))
           properties)
@@ -364,25 +364,25 @@
   (let [ents (remove #(db-malli-schema/internal-ident? (:db/ident %))
                      (d/q '[:find [(pull ?b [*
                                              {:logseq.property.class/properties [:block/title]}
-                                             {:property/schema.classes [:block/title]}
+                                             {:logseq.property/classes [:block/title]}
                                              {:logseq.property/parent [:block/title]}
                                              {:block/tags [:block/title]}
                                              {:block/refs [:block/title]}]) ...]
                             :in $
                             :where [?b :db/ident ?ident]]
-                          db))]
+                          db))
+        top-level-properties [:logseq.property/type :logseq.property.class/properties :logseq.property/classes
+                              :logseq.property/parent :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 (->> (db-property/properties m)
-                                                    (into {}))]
-                                     (cond-> (select-keys m [:block/name :block/tags :block/title :block/schema :db/ident
-                                                             :logseq.property.class/properties :logseq.property/parent
-                                                             :db/cardinality :property/schema.classes :block/refs])
+                                   (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)
-                                                                    (dissoc "tags")
                                                                     (update-vals (fn [v]
                                                                                    (if (:db/id v)
                                                                                      (db-property/property-value-content (d/entity db (:db/id v)))
@@ -391,8 +391,8 @@
                                        (update :logseq.property.class/properties #(set (map :block/title %)))
                                        (some? (:logseq.property/parent m))
                                        (update :logseq.property/parent :block/title)
-                                       (seq (:property/schema.classes m))
-                                       (update :property/schema.classes #(set (map :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))

+ 1 - 1
scripts/src/logseq/tasks/dev/db_and_file_graphs.clj

@@ -126,7 +126,7 @@
   []
   (let [db-concepts
         ;; from logseq.db.frontend.schema
-        ["closed-value" "class/properties" "schema.classes" "property/parent"
+        ["closed-value" "class/properties" "classes" "property/parent"
          "logseq.property" "logseq.class"]
         res (apply shell {:out :string :continue true}
                    "git grep -E" (str "(" (string/join "|" db-concepts) ")")

+ 4 - 4
src/main/frontend/components/all_pages.cljs

@@ -3,17 +3,17 @@
   (:require [frontend.components.block :as component-block]
             [frontend.components.page :as component-page]
             [frontend.components.views :as views]
+            [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.db :as db]
             [frontend.handler.page :as page-handler]
+            [frontend.hooks :as hooks]
             [frontend.state :as state]
+            [frontend.ui :as ui]
             [logseq.db :as ldb]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
-            [rum.core :as rum]
-            [frontend.ui :as ui]
-            [frontend.config :as config]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (defn- columns
   []

+ 15 - 17
src/main/frontend/components/assets.cljs

@@ -2,20 +2,20 @@
   (:require
    [clojure.set :refer [difference]]
    [clojure.string :as string]
-   [logseq.shui.ui :as shui]
-   [rum.core :as rum]
-   [frontend.state :as state]
-   [frontend.context.i18n :refer [t]]
-   [frontend.util :as util]
    [electron.ipc :as ipc]
-   [promesa.core :as p]
-   [medley.core :as medley]
-   [frontend.ui :as ui]
-   [frontend.config :as config]
    [frontend.components.select :as cp-select]
-   [frontend.handler.notification :as notification]
+   [frontend.config :as config]
+   [frontend.context.i18n :refer [t]]
    [frontend.handler.assets :as assets-handler]
-   [frontend.hooks :as hooks]))
+   [frontend.handler.notification :as notification]
+   [frontend.hooks :as hooks]
+   [frontend.state :as state]
+   [frontend.ui :as ui]
+   [frontend.util :as util]
+   [logseq.shui.ui :as shui]
+   [medley.core :as medley]
+   [promesa.core :as p]
+   [rum.core :as rum]))
 
 (defn -get-all-formats
   []
@@ -81,7 +81,7 @@
                        (set-val! (util/trim-safe (.. e -target -value))))
         :on-key-up   (fn [^js e]
                        (when (and (= 13 (.-which e))
-                                (not (string/blank? val)))
+                                  (not (string/blank? val)))
                          (on-submit)))}]]
 
      [:div.pt-6.flex.justify-end
@@ -98,7 +98,7 @@
 
 (rum/defcs ^:large-vars/data-var alias-directories
   < rum/reactive
-    (rum/local nil ::ext-editing-dir)
+  (rum/local nil ::ext-editing-dir)
   [_state]
   (let [*ext-editing-dir (::ext-editing-dir _state)
         directories      (into [] (state/sub :assets/alias-dirs))
@@ -186,9 +186,7 @@
               (ui/icon "plus") "Acceptable file extensions"])]
 
           [:span.ctrls.flex.space-x-3.text-xs.opacity-30.hover:opacity-100.whitespace-nowrap.hidden.mt-1
-           [:a {:on-click #(rm-dir dir)} (ui/icon "trash-x")]]]
-
-         ])]
+           [:a {:on-click #(rm-dir dir)} (ui/icon "trash-x")]]]])]
 
      [:p.pt-2
       (ui/button
@@ -201,7 +199,7 @@
 
 (rum/defcs settings-content
   < rum/reactive
-    (rum/local (state/sub :assets/alias-enabled?) ::alias-enabled?)
+  (rum/local (state/sub :assets/alias-enabled?) ::alias-enabled?)
   [_state]
 
   (let [*pre-alias-enabled?    (::alias-enabled? _state)

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

@@ -2353,7 +2353,7 @@
       [:span.w-full
        (text-block-title config block)
        (when-let [property (:logseq.property/created-from-property block)]
-         (when-let [message (when (= :url (get-in property [:block/schema :type]))
+         (when-let [message (when (= :url (:logseq.property/type property))
                               (first (outliner-property/validate-property-value (db/get-db) property (:db/id block))))]
            (ui/tooltip
             (shui/button

+ 14 - 14
src/main/frontend/components/bug_report.cljs

@@ -1,13 +1,13 @@
 (ns frontend.components.bug-report
-  (:require [rum.core :as rum]
-            [frontend.ui :as ui]
+  (:require [clojure.string :as string]
             [frontend.components.header :as header]
+            [frontend.context.i18n :refer [t]]
+            [frontend.handler.notification :as notification]
+            [frontend.hooks :as hooks]
+            [frontend.ui :as ui]
             [frontend.util :as util]
             [reitit.frontend.easy :as rfe]
-            [clojure.string :as string]
-            [frontend.handler.notification :as notification]
-            [frontend.context.i18n :refer [t]]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (defn parse-clipboard-data-transfer
   "parse dataTransfer
@@ -94,11 +94,11 @@
 
 (rum/defc report-item-button
   [title description icon-name {:keys [on-click]}]
-   [:a.cp__bug-report-item-button.flex.items-center.px-4.py-2.my-2.rounded-lg {:on-click on-click}
-    [(ui/icon icon-name)
-     [:div.flex.flex-col.ml-2
-      [:div title]
-      [:div.opacity-60 description]]]])
+  [:a.cp__bug-report-item-button.flex.items-center.px-4.py-2.my-2.rounded-lg {:on-click on-click}
+   [(ui/icon icon-name)
+    [:div.flex.flex-col.ml-2
+     [:div title]
+     [:div.opacity-60 description]]]])
 
 (rum/defc bug-report
   []
@@ -112,9 +112,9 @@
     [:h1.text-2xl (t :bug-report/section-clipboard-title)]
     [:div.opacity-60 (t :bug-report/section-clipboard-desc)]
     (report-item-button (t :bug-report/section-clipboard-btn-title)
-                 (t :bug-report/section-clipboard-btn-desc)
-                 "clipboard"
-                 {:on-click #(util/open-url (rfe/href :bug-report-tools {:tool "clipboard-data-inspector"}))})
+                        (t :bug-report/section-clipboard-btn-desc)
+                        "clipboard"
+                        {:on-click #(util/open-url (rfe/href :bug-report-tools {:tool "clipboard-data-inspector"}))})
     [:div.py-2] ;; divider
     [:div.flex.flex-col
      [:h1.text-2xl (t :bug-report/section-issues-title)]

+ 4 - 4
src/main/frontend/components/cmdk/core.cljs

@@ -685,7 +685,7 @@
               page' (db/entity repo [:block/uuid (:block/uuid page)])
               link (if (config/db-based-graph? repo)
                      (some (fn [[k v]]
-                             (when (= :url (get-in (db/entity repo k) [:block/schema :type]))
+                             (when (= :url (:logseq.property/type (db/entity repo k)))
                                (:block/title v)))
                            (:block/properties page'))
                      (some #(re-find editor-handler/url-regex (val %)) (:block/properties page')))]
@@ -792,9 +792,9 @@
     ;; if not then clear that puppy out!
     ;; This was moved to a functional component
     (hooks/use-effect! (fn []
-                       (when (and highlighted-item (= -1 (.indexOf all-items (dissoc highlighted-item :mouse-enter-triggered-highlight))))
-                         (reset! (::highlighted-item state) nil)))
-                     [all-items])
+                         (when (and highlighted-item (= -1 (.indexOf all-items (dissoc highlighted-item :mouse-enter-triggered-highlight))))
+                           (reset! (::highlighted-item state) nil)))
+                       [all-items])
     (hooks/use-effect! (fn [] (load-results :default state)) [])
     [:div {:class "bg-gray-02 border-b border-1 border-gray-07"}
      [:input.cp__cmdk-search-input

+ 5 - 5
src/main/frontend/components/dnd.cljs

@@ -1,12 +1,12 @@
 (ns frontend.components.dnd
-  (:require [rum.core :as rum]
-            [cljs-bean.core :as bean]
+  (:require ["@dnd-kit/core" :refer [DndContext closestCenter MouseSensor useSensor useSensors]]
             ["@dnd-kit/sortable" :refer [useSortable arrayMove SortableContext verticalListSortingStrategy horizontalListSortingStrategy] :as sortable]
             ["@dnd-kit/utilities" :refer [CSS]]
-            ["@dnd-kit/core" :refer [DndContext closestCenter MouseSensor useSensor useSensors]]
+            [cljs-bean.core :as bean]
+            [frontend.hooks :as hooks]
             [frontend.rum :as r]
             [frontend.state :as state]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (def dnd-context (r/adapt-class DndContext))
 (def sortable-context (r/adapt-class SortableContext))
@@ -88,7 +88,7 @@
                                {:key id :id id})]
                      (cond
                        sort-by-inner-element?
-                       [:div (:content item)]
+                       [:div {:key id} (:content item)]
 
                        (:disabled? item)
                        (rum/with-key (non-sortable-item prop (:content item)) id)

+ 3 - 3
src/main/frontend/components/editor.cljs

@@ -344,9 +344,9 @@
   [id q]
   (let [[matched-templates set-matched-templates!] (rum/use-state nil)]
     (hooks/use-effect! (fn []
-                       (p/let [result (editor-handler/<get-matched-templates q)]
-                         (set-matched-templates! result)))
-                     [q])
+                         (p/let [result (editor-handler/<get-matched-templates q)]
+                           (set-matched-templates! result)))
+                       [q])
     (ui/auto-complete
      matched-templates
      {:on-chosen   (editor-handler/template-on-chosen-handler id)

+ 4 - 4
src/main/frontend/components/file_based/block.cljs

@@ -4,15 +4,15 @@
             [frontend.components.file-based.datetime :as datetime-comp]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.file-based.repeated :as repeated]
+            [frontend.hooks :as hooks]
+            [frontend.state :as state]
             [frontend.ui :as ui]
-            [logseq.shui.ui :as shui]
             [frontend.util :as util]
             [frontend.util.file-based.clock :as clock]
             [frontend.util.file-based.drawer :as drawer]
-            [frontend.state :as state]
+            [logseq.shui.ui :as shui]
             [reitit.frontend.easy :as rfe]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (defn marker-switch
   [{:block/keys [marker] :as block}]

+ 11 - 11
src/main/frontend/components/file_sync.cljs

@@ -1,7 +1,8 @@
 (ns frontend.components.file-sync
-  (:require [cljs.core.async :as async]
+  (:require [cljs-time.coerce :as tc]
+            [cljs-time.core :as t]
+            [cljs.core.async :as async]
             [cljs.core.async.interop :refer [p->c]]
-            [frontend.util.persist-var :as persist-var]
             [clojure.string :as string]
             [electron.ipc :as ipc]
             [frontend.components.lazy-editor :as lazy-editor]
@@ -12,27 +13,26 @@
             [frontend.db.model :as db-model]
             [frontend.fs :as fs]
             [frontend.fs.sync :as fs-sync]
+            [frontend.handler.file-based.nfs :as nfs-handler]
             [frontend.handler.file-sync :refer [*beta-unavailable?] :as file-sync-handler]
             [frontend.handler.notification :as notification]
+            [frontend.handler.page :as page-handler]
             [frontend.handler.repo :as repo-handler]
             [frontend.handler.user :as user-handler]
-            [frontend.handler.page :as page-handler]
-            [frontend.handler.file-based.nfs :as nfs-handler]
+            [frontend.hooks :as hooks]
             [frontend.mobile.util :as mobile-util]
             [frontend.state :as state]
+            [frontend.storage :as storage]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [frontend.util.fs :as fs-util]
-            [frontend.storage :as storage]
+            [frontend.util.persist-var :as persist-var]
+            [goog.functions :refer [debounce]]
+            [logseq.common.util :as common-util]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
             [reitit.frontend.easy :as rfe]
-            [rum.core :as rum]
-            [cljs-time.core :as t]
-            [cljs-time.coerce :as tc]
-            [goog.functions :refer [debounce]]
-            [logseq.common.util :as common-util]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (declare maybe-onboarding-show)
 (declare open-icloud-graph-clone-picker)

+ 7 - 7
src/main/frontend/components/git.cljs

@@ -1,13 +1,13 @@
 (ns frontend.components.git
-  (:require [rum.core :as rum]
-            [frontend.ui :as ui]
-            [promesa.core :as p]
-            [frontend.util :as util]
-            [clojure.string :as string]
-            [frontend.handler.shell :as shell]
+  (:require [clojure.string :as string]
             [frontend.handler.file :as file]
+            [frontend.handler.shell :as shell]
+            [frontend.hooks :as hooks]
             [frontend.state :as state]
-            [frontend.hooks :as hooks]))
+            [frontend.ui :as ui]
+            [frontend.util :as util]
+            [promesa.core :as p]
+            [rum.core :as rum]))
 
 (rum/defcs set-git-username-and-email <
   (rum/local "" ::username)

+ 6 - 6
src/main/frontend/components/handbooks.cljs

@@ -1,10 +1,10 @@
 (ns frontend.components.handbooks
-  (:require [rum.core :as rum]
-            [frontend.state :as state]
-            [frontend.modules.layout.core :as layout]
-            ;[shadow.lazy :as lazy]
-            [frontend.extensions.handbooks.core :as handbooks]
-            [frontend.hooks :as hooks]))
+  (:require ;[shadow.lazy :as lazy]
+   [frontend.extensions.handbooks.core :as handbooks]
+   [frontend.hooks :as hooks]
+   [frontend.modules.layout.core :as layout]
+   [frontend.state :as state]
+   [rum.core :as rum]))
 
 #_:clj-kondo/ignore
 ;(def lazy-handbooks (lazy/loadable frontend.extensions.handbooks.core/content))

+ 3 - 3
src/main/frontend/components/header.cljs

@@ -4,6 +4,7 @@
             [cljs-time.core :as t]
             [clojure.string :as string]
             [dommy.core :as d]
+            [frontend.common.missionary :as c.m]
             [frontend.components.export :as export]
             [frontend.components.file-sync :as fs-sync]
             [frontend.components.page-menu :as page-menu]
@@ -22,20 +23,19 @@
             [frontend.handler.plugin :as plugin-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.user :as user-handler]
+            [frontend.hooks :as hooks]
             [frontend.mobile.util :as mobile-util]
             [frontend.state :as state]
             [frontend.storage :as storage]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [frontend.version :refer [version]]
-            [frontend.common.missionary :as c.m]
             [logseq.db :as ldb]
             [logseq.shui.ui :as shui]
             [logseq.shui.util :as shui-util]
             [missionary.core :as m]
             [reitit.frontend.easy :as rfe]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (rum/defc home-button
   < {:key-fn #(identity "home-button")}

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

@@ -16,6 +16,7 @@
             [frontend.handler.repo :as repo-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
+            [frontend.hooks :as hooks]
             [frontend.persist-db.browser :as db-browser]
             [frontend.state :as state]
             [frontend.ui :as ui]
@@ -31,8 +32,7 @@
             [logseq.shui.form.core :as form-core]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 ;; Can't name this component as `frontend.components.import` since shadow-cljs
 ;; will complain about it.

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

@@ -9,6 +9,7 @@
             [frontend.db.model :as db-model]
             [frontend.db.react :as react]
             [frontend.handler.editor :as editor-handler]
+            [frontend.hooks :as hooks]
             [frontend.mixins :as mixins]
             [frontend.modules.outliner.op :as outliner-op]
             [frontend.modules.outliner.ui :as ui-outliner-tx]
@@ -20,8 +21,7 @@
             [logseq.outliner.property :as outliner-property]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (defn- get-class-objects
   [class]

+ 3 - 3
src/main/frontend/components/page.cljs

@@ -33,6 +33,7 @@
             [frontend.handler.notification :as notification]
             [frontend.handler.page :as page-handler]
             [frontend.handler.route :as route-handler]
+            [frontend.hooks :as hooks]
             [frontend.mixins :as mixins]
             [frontend.mobile.util :as mobile-util]
             [frontend.rum :as frontend-rum]
@@ -48,8 +49,7 @@
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
             [reitit.frontend.easy :as rfe]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (defn- get-page-name
   [state]
@@ -143,7 +143,7 @@
       ;; mounted
       ;(hooks/use-effect! #(focus!) [])
       (hooks/use-effect! #(if selected? (focus!)
-                            (some-> (rum/deref *el-ref) (.blur))) [selected?])
+                              (some-> (rum/deref *el-ref) (.blur))) [selected?])
 
       (shui/trigger-as
        :div.ls-dummy-block.ls-block

+ 13 - 14
src/main/frontend/components/plugins.cljs

@@ -12,6 +12,7 @@
             [frontend.handler.plugin :as plugin-handler]
             [frontend.handler.plugin-config :as plugin-config-handler]
             [frontend.handler.ui :as ui-handler]
+            [frontend.hooks :as hooks]
             [frontend.mixins :as mixins]
             [frontend.rum :as rum-utils]
             [frontend.search :as search]
@@ -21,8 +22,7 @@
             [frontend.util :as util]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (declare open-waiting-updates-modal!)
 (defonce PER-PAGE-SIZE 15)
@@ -486,11 +486,11 @@
         handle-submit! (fn []
                          (set-pending? true)
                          (-> (plugin-handler/load-plugin-from-web-url! url)
-                           (p/then #(do (notification/show! "New plugin registered!" :success)
-                                      (shui/dialog-close!)))
-                           (p/catch #(notification/show! (str %) :error))
-                           (p/finally
-                             #(set-pending? false))))]
+                             (p/then #(do (notification/show! "New plugin registered!" :success)
+                                          (shui/dialog-close!)))
+                             (p/catch #(notification/show! (str %) :error))
+                             (p/finally
+                               #(set-pending? false))))]
 
     [:div.px-4.pt-4.pb-2.rounded-md.flex.flex-col.gap-2
      [:div.flex.flex-col.gap-3
@@ -502,12 +502,11 @@
        (shui/tabler-icon "info-circle" {:size 13})
        [:span "URLs support both GitHub repositories and local development servers.
       (For examples: https://github.com/xyhp915/logseq-journals-calendar,
-      http://localhost:8080/<plugin-dir-root>)"]]
-      ]
+      http://localhost:8080/<plugin-dir-root>)"]]]
      [:div.flex.justify-end
       (shui/button {:disabled (or pending? (string/blank? url))
                     :on-click handle-submit!}
-        (if pending? (ui/loading) "Install"))]]))
+                   (if pending? (ui/loading) "Install"))]]))
 
 (rum/defc install-from-github-release-container
   []
@@ -1412,10 +1411,10 @@
                            ;; interval 12 hours
                           (> (- (js/Date.now) last-updates) (* 60 60 12 1000))))
              (let [update-timer (js/setTimeout
-                                  (fn []
-                                    (plugin-handler/auto-check-enabled-for-updates!)
-                                    (storage/set :lsp-last-auto-updates (js/Date.now)))
-                                  (if (util/electron?) 3000 (* 60 1000) ))]
+                                 (fn []
+                                   (plugin-handler/auto-check-enabled-for-updates!)
+                                   (storage/set :lsp-last-auto-updates (js/Date.now)))
+                                 (if (util/electron?) 3000 (* 60 1000)))]
                #(js/clearTimeout update-timer))))))
      [online?])
 

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

@@ -3,12 +3,12 @@
             [frontend.components.lazy-editor :as lazy-editor]
             [frontend.handler.notification :as notification]
             [frontend.handler.plugin :as plugin-handler]
+            [frontend.hooks :as hooks]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [goog.functions :refer [debounce]]
             [logseq.shui.ui :as shui]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (defn- dom-purify
   [html opts]

+ 21 - 18
src/main/frontend/components/property.cljs

@@ -5,7 +5,6 @@
             [frontend.components.dnd :as dnd]
             [frontend.components.icon :as icon-component]
             [frontend.components.property.config :as property-config]
-            [frontend.components.property.util :as components-pu]
             [frontend.components.property.value :as pv]
             [frontend.components.select :as select]
             [frontend.components.svg :as svg]
@@ -73,7 +72,8 @@
                           default-open? class-schema?]
                    :as opts}]
   (let [property-name (or (and *property-name @*property-name) (:block/title property))
-        property-schema (or (and *property-schema @*property-schema) (:block/schema property))
+        property-schema (or (and *property-schema @*property-schema)
+                            (select-keys property [:logseq.property/type]))
         schema-types (->> (concat db-property-type/user-built-in-property-types
                                   (when built-in?
                                     db-property-type/internal-built-in-property-types))
@@ -88,7 +88,7 @@
         :on-value-change
         (fn [v]
           (let [type (keyword (string/lower-case v))
-                update-schema-fn #(assoc % :type type)]
+                update-schema-fn #(assoc % :logseq.property/type type)]
             (when *property-schema
               (swap! *property-schema update-schema-fn))
             (let [schema (or (and *property-schema @*property-schema)
@@ -102,8 +102,12 @@
                 (p/do!
                  (when *show-new-property-config?
                    (reset! *show-new-property-config? false))
-                 (when (= (:type schema) :node) (reset! *show-class-select? true))
-                 (components-pu/update-property! property property-name schema)
+                 (when (= (:logseq.property/type schema) :node) (reset! *show-class-select? true))
+                 (db-property-handler/upsert-property!
+                  (:db/ident property)
+                  schema
+                  {})
+
                  (cond
                    (and *show-class-select? @*show-class-select?)
                    nil
@@ -124,8 +128,8 @@
                    (pv/<create-new-block! block property "")))))))}
 
         ;; only set when in property configure modal
-        (and *property-name (:type property-schema))
-        (assoc :default-value (name (:type property-schema))))
+        (and *property-name (:logseq.property/type property-schema))
+        (assoc :default-value (name (:logseq.property/type property-schema))))
       (shui/select-trigger
        {:class "!px-2 !py-0 !h-8"}
        (shui/select-value
@@ -133,7 +137,7 @@
       (shui/select-content
        (shui/select-group
         (for [{:keys [label value disabled]} schema-types]
-          (shui/select-item {:value value :disabled disabled} label)))))
+          (shui/select-item {:key label :value value :disabled disabled} label)))))
      (when show-type-change-hints?
        (ui/tippy {:html        "Changing the property type clears some property configurations."
                   :class       "tippy-hover ml-2"
@@ -183,7 +187,7 @@
 
 (rum/defc property-icon
   [property property-type]
-  (let [type (or (get-in property [:block/schema :type] property-type) :default)
+  (let [type (or (:logseq.property/type property) property-type :default)
         ident (:db/ident property)
         icon (cond
                (= ident :block/tags)
@@ -213,7 +217,7 @@
       (reset! *property property)
       (when property
         (let [add-class-property? (and (ldb/class? block) class-schema?)
-              type (get-in property [:block/schema :type])]
+              type (:logseq.property/type property)]
           (cond
             add-class-property?
             (p/do!
@@ -286,9 +290,8 @@
                            {:on-chosen
                             (fn [_e icon]
                               (if icon
-                                (db-property-handler/upsert-property! (:db/ident property)
-                                                                      (:block/schema property)
-                                                                      {:properties {:logseq.property/icon icon}})
+                                (db-property-handler/set-block-property! (:db/id property)
+                                                                         :logseq.property/icon icon)
                                 (db-property-handler/remove-block-property! (:db/id property)
                                                                             (pu/get-pid :logseq.property/icon)))
                               (shui/popup-hide! id))
@@ -360,7 +363,7 @@
                         (empty? types)
                         #{:block}))
         exclude-properties (fn [m]
-                             (let [view-context (get-in m [:block/schema :view-context] :all)]
+                             (let [view-context (get m :logseq.property/view-context :all)]
                                (or (contains? #{:logseq.property/query} (:db/ident m))
                                    (and (not page?) (contains? #{:block/alias} (:db/ident m)))
                                    ;; Filters out properties from being in wrong :view-context and :never view-contexts
@@ -373,7 +376,7 @@
      (if property-key
        [:div.ls-property-add.gap-1.flex.flex-1.flex-row.items-center
         [:div.flex.flex-row.items-center.property-key.gap-1
-         (when-not (:db/id property) (property-icon property (:type @*property-schema)))
+         (when-not (:db/id property) (property-icon property (:logseq.property/type @*property-schema)))
          (if (:db/id property)                              ; property exists already
            (property-key-cp block property opts)
            [:div property-key])]
@@ -446,7 +449,7 @@
   [block k v {:keys [inline-text page-cp sortable-opts] :as opts}]
   (when (keyword? k)
     (when-let [property (db/sub-block (:db/id (db/entity k)))]
-      (let [type (get-in property [:block/schema :type] :default)
+      (let [type (get property :logseq.property/type :default)
             closed-values? (seq (:property/closed-values property))
             block? (and v
                         (not closed-values?)
@@ -625,7 +628,7 @@
                                     state-hide-empty-properties?
                                     (nil? (get block property-id))
                                     :else
-                                    (boolean (:hide? (:block/schema property))))))
+                                    (boolean (:logseq.property/hide? property)))))
         property-hide-f (cond
                           config/publishing?
                           ;; Publishing is read only so hide all blank properties as they
@@ -636,7 +639,7 @@
                           state-hide-empty-properties?
                           (fn [[property-id property-value]]
                             ;; User's selection takes precedence over config
-                            (if (contains? (:block/schema (db/entity property-id)) :hide?)
+                            (if (:logseq.property/hide? (db/entity property-id))
                               (hide-with-property-id property-id)
                               (nil? property-value)))
                           :else

+ 27 - 25
src/main/frontend/components/property/config.cljs

@@ -15,6 +15,7 @@
             [frontend.handler.db-based.property :as db-property-handler]
             [frontend.handler.property :as property-handler]
             [frontend.handler.route :as route-handler]
+            [frontend.hooks :as hooks]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
@@ -27,8 +28,7 @@
             [logseq.shui.popup.core :as shui-popup]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (defn- re-init-commands!
   "Update commands after task status and priority's closed values has been changed"
@@ -90,7 +90,7 @@
          (some-> (rum/deref *ref)
                  (.click))))
      [default-open?])
-    (let [schema-classes (:property/schema.classes property)]
+    (let [schema-classes (:logseq.property/classes property)]
       [:div.flex.flex-1.col-span-3
        (let [content-fn
              (fn [{:keys [id]}]
@@ -129,7 +129,7 @@
                                           (toggle-fn)
                                           (p/let [result (<create-class-if-not-exists! value)
                                                   value' (or result value)
-                                                  tx-data [[(if select? :db/add :db/retract) (:db/id property) :property/schema.classes [:block/uuid value']]]
+                                                  tx-data [[(if select? :db/add :db/retract) (:db/id property) :logseq.property/classes [:block/uuid value']]]
                                                   _ (db/transact! (state/get-current-repo) tx-data {:outliner-op :update-property})]
                                             (when-not multiple-choices? (toggle-fn)))))}]
 
@@ -190,7 +190,7 @@
                                   (set-saving! true)
                                   (-> [(db-property-handler/upsert-property!
                                         (:db/ident property)
-                                        (:block/schema property)
+                                        {}
                                         {:property-name title
                                          :properties {:logseq.property/icon (:icon form-data)}})
                                        (when (not= description (:description (rum/deref *form-data)))
@@ -340,7 +340,7 @@
         (shui/tabler-icon "dots" {:size 16})))
       (shui/dropdown-menu-content
        ;; default choice
-       (let [property-type (get-in property [:block/schema :type])
+       (let [property-type (:logseq.property/type property)
              property (db/sub-block (:db/id property))
              default-type? (contains? #{:default :number} property-type)
              default-value (when default-type? (:logseq.property/default-value property))
@@ -443,7 +443,7 @@
                           (shui/popup-show! (.-target e)
                                             (fn [{:keys [id]}]
                                               (let [opts {:toggle-fn (fn [] (shui/popup-hide! id))}
-                                                    values' (->> (if (contains? db-property-type/all-ref-property-types (get-in property [:block/schema :type]))
+                                                    values' (->> (if (contains? db-property-type/all-ref-property-types (:logseq.property/type property))
                                                                    (->> values
                                                                         (map db/entity)
                                                                         (remove (fn [e]
@@ -467,7 +467,8 @@
                       (shui/select-value {:placeholder "Select a choice"}))
                      (shui/select-content
                       (map (fn [choice]
-                             (shui/select-item {:value (:db/id choice)} (:block/title choice))) choices))))
+                             (shui/select-item {:key (str (:db/id choice))
+                                                :value (:db/id choice)} (:block/title choice))) choices))))
         checked-choice (some (fn [choice] (when (true? (:logseq.property/choice-checkbox-state choice)) choice)) choices)
         unchecked-choice (some (fn [choice] (when (false? (:logseq.property/choice-checkbox-state choice)) choice)) choices)]
     [:div.flex.flex-col.gap-4.text-sm.p-2
@@ -503,13 +504,13 @@
    :block-below {:icon :layout-align-top :title "Below the block"}})
 
 (rum/defc ui-position-sub-pane
-  [property {:keys [id set-sub-open! _position]}]
+  [property {:keys [id set-sub-open! _ui-position]}]
   (let [handle-select! (fn [^js e]
                          (when-let [v (some-> (.-target e) (.-dataset) (.-value))]
-                           (db-property-handler/upsert-property!
-                            (:db/ident property)
-                            (assoc (:block/schema property) :position (keyword v))
-                            {:property-name (:block/title property)})
+                           (db-property-handler/set-block-property!
+                            (:db/id property)
+                            :logseq.property/ui-position
+                            (keyword v))
                            (set-sub-open! false)
                            (restore-root-highlight-item! id)))
         item-props {:on-select handle-select!}]
@@ -554,7 +555,7 @@
                            (p/do!
                             (db-property-handler/upsert-property!
                              (:db/ident property)
-                             (assoc (:block/schema property) :type (keyword v))
+                             {:logseq.property/type (keyword v)}
                              {})
                             (set-sub-open! false)
                             (restore-root-highlight-item! id))))
@@ -573,7 +574,7 @@
 
 (rum/defc default-value-subitem
   [property]
-  (let [property-type (get-in property [:block/schema :type])
+  (let [property-type (:logseq.property/type property)
         option (if (= :checkbox property-type)
                  (let [default-value (:logseq.property/scalar-default-value property)]
                    {:icon :settings-2
@@ -592,8 +593,7 @@
   "property: block entity"
   [property owner-block values {:keys [class-schema? debug?]}]
   (let [title (:block/title property)
-        property-schema (:block/schema property)
-        property-type (get property-schema :type)
+        property-type (:logseq.property/type property)
         property-type-label' (some-> property-type (property-type-label))
         enable-closed-values? (contains? db-property-type/closed-value-property-types
                                          (or property-type :default))
@@ -660,7 +660,8 @@
                                     :on-toggle-checked-change
                                     (fn []
                                       (let [update-cardinality-fn #(db-property-handler/upsert-property! (:db/ident property)
-                                                                                                         (assoc property-schema :cardinality (if many? :one :many)) {})]
+                                                                                                         {:db/cardinality (if many? :one :many)}
+                                                                                                         {})]
                                       ;; Only show dialog for existing values as it can be reversed for unused properties
                                         (if (and (seq values) (not many?))
                                           (-> (shui/dialog-confirm!
@@ -669,24 +670,25 @@
                                           (update-cardinality-fn))))})))
 
      (when (not= :logseq.property/enable-history? (:db/ident property))
-       (let [property-type (get-in property [:block/schema :type])
+       (let [property-type (:logseq.property/type property)
              group' (->> [(when (and (not (contains? #{:logseq.property/parent :logseq.property.class/properties} (:db/ident property)))
                                      (contains? #{:default :number :date :checkbox :node} property-type)
                                      (not
                                       (and (= :default property-type)
                                            (empty? (:property/closed-values property))
-                                           (contains? #{nil :properties} (:position property-schema)))))
-                            (let [position (:position property-schema)]
+                                           (contains? #{nil :properties} (:logseq.property/ui-position property)))))
+                            (let [position (:logseq.property/ui-position property)]
                               (dropdown-editor-menuitem {:icon :float-left :title "UI position" :desc (some->> position (get position-labels) (:title))
                                                          :item-props {:class "ui__position-trigger-item"}
                                                          :disabled? config/publishing?
-                                                         :submenu-content (fn [ops] (ui-position-sub-pane property (assoc ops :position position)))})))
+                                                         :submenu-content (fn [ops] (ui-position-sub-pane property (assoc ops :ui-position position)))})))
 
                           (when (not (contains? #{:logseq.property/parent :logseq.property.class/properties} (:db/ident property)))
-                            (dropdown-editor-menuitem {:icon :eye-off :title "Hide by default" :toggle-checked? (boolean (:hide? property-schema))
+                            (dropdown-editor-menuitem {:icon :eye-off :title "Hide by default" :toggle-checked? (boolean (:logseq.property/hide? property))
                                                        :disabled? config/publishing?
-                                                       :on-toggle-checked-change #(db-property-handler/upsert-property! (:db/ident property)
-                                                                                                                        (assoc property-schema :hide? %) {})}))
+                                                       :on-toggle-checked-change #(db-property-handler/set-block-property! (:db/id property)
+                                                                                                                           :logseq.property/hide?
+                                                                                                                           %)}))
                           (when (not (contains? #{:logseq.property/parent :logseq.property.class/properties} (:db/ident property)))
                             (dropdown-editor-menuitem {:icon :eye-off :title "Hide empty value" :toggle-checked? (boolean (:logseq.property/hide-empty-value property))
                                                        :disabled? config/publishing?

+ 0 - 12
src/main/frontend/components/property/util.cljs

@@ -1,12 +0,0 @@
-(ns frontend.components.property.util
-  "Property component utils"
-  (:require [frontend.handler.db-based.property :as db-property-handler]))
-
-(defn update-property!
-  [property property-name property-schema]
-  (when (or (not= (:block/title property) property-name)
-            (not= (:block/schema property) property-schema))
-    (db-property-handler/upsert-property!
-     (:db/ident property)
-     property-schema
-     {:property-name property-name})))

+ 30 - 35
src/main/frontend/components/property/value.cljs

@@ -22,6 +22,7 @@
             [frontend.handler.property :as property-handler]
             [frontend.handler.property.util :as pu]
             [frontend.handler.route :as route-handler]
+            [frontend.hooks :as hooks]
             [frontend.modules.outliner.ui :as ui-outliner-tx]
             [frontend.search :as search]
             [frontend.state :as state]
@@ -37,8 +38,7 @@
             [logseq.outliner.property :as outliner-property]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (rum/defc property-empty-btn-value
   [property & opts]
@@ -112,17 +112,17 @@
       ;; closed values
       (seq (:property/closed-values property))
       (and (= (:db/ident property) :logseq.property/default-value)
-           (= (get-in block [:block/schema :type]) :number))))
+           (= (:logseq.property/type block) :number))))
 
 (defn <create-new-block!
   [block property value & {:keys [edit-block?]
                            :or {edit-block? true}}]
-  (when-not (or (get-in property [:block/schema :hide?])
+  (when-not (or (:logseq.property/hide? property)
                 (= (:db/ident property) :logseq.property/default-value))
     (ui/hide-popups-until-preview-popup!)
     (shui/dialog-close!))
   (p/let [block
-          (if (and (contains? #{:default :url} (get-in property [:block/schema :type]))
+          (if (and (contains? #{:default :url} (:logseq.property/type property))
                    (not (db-property/many? property)))
             (p/let [existing-value (get block (:db/ident property))
                     default-value (:logseq.property/default-value property)
@@ -169,9 +169,8 @@
                   :db/valueType :db.type/ref
                   :db/index true
                   :block/tags :logseq.class/Property
-                  :block/schema (assoc (:block/schema property)
-                                       :type :node)
-                  :property/schema.classes (:db/id property)}]
+                  :logseq.property/type :node
+                  :logseq.property/classes (:db/id property)}]
                 {:outliner-op :save-block}))
 
 (defn <add-property!
@@ -184,7 +183,7 @@
          class? (ldb/class? block)
          property (db/entity property-id)
          many? (db-property/many? property)
-         checkbox? (= :checkbox (get-in property [:block/schema :type]))
+         checkbox? (= :checkbox (:logseq.property/type property))
          blocks (get-operating-blocks block)]
      (assert (qualified-keyword? property-id) "property to add must be a keyword")
      (p/do!
@@ -194,7 +193,7 @@
            (<set-class-as-property! repo property))
          (db-property-handler/class-add-property! (:db/id block) property-id))
         (let [block-ids (map :block/uuid blocks)]
-          (if (and (db-property-type/all-ref-property-types (get-in property [:block/schema :type]))
+          (if (and (db-property-type/all-ref-property-types (:logseq.property/type property))
                    (string? property-value))
             (p/let [new-block (<create-new-block! block (db/entity property-id) property-value {:edit-block? false})]
               (when (seq (remove #{(:db/id block)} (map :db/id block)))
@@ -255,7 +254,7 @@
                                                                                                   :logseq.task/scheduled-on-property)))))]
        (if (#{:logseq.task/deadline :logseq.task/scheduled} (:db/ident property))
          [:div "Repeat task"]
-         [:div "Repeat " (if (= :date (get-in property [:block/schema :type])) "date" "datetime")])]]
+         [:div "Repeat " (if (= :date (:logseq.property/type property)) "date" "datetime")])]]
      [:div.flex.flex-row.gap-2
       [:div.flex.text-muted-foreground.mr-4
        "Every"]
@@ -295,7 +294,8 @@
           (shui/select-value {:placeholder "Select a property"}))
          (shui/select-content
           (map (fn [choice]
-                 (shui/select-item {:value (:db/id choice)} (:block/title choice))) properties)))
+                 (shui/select-item {:key (str (:db/id choice))
+                                    :value (:db/id choice)} (:block/title choice))) properties)))
         [:div.flex.flex-row.gap-1
          [:div.text-muted-foreground
           "is:"]
@@ -496,7 +496,7 @@
   [block property value opts]
   (let [multiple-values? (db-property/many? property)
         repo (state/get-current-repo)
-        datetime? (= :datetime (get-in property [:block/schema :type]))]
+        datetime? (= :datetime (:logseq.property/type property))]
     (date-picker value
                  (merge opts
                         {:block block
@@ -615,7 +615,7 @@
    result]
   (let [[refresh-count set-refresh-count!] (rum/use-state 0)
         repo (state/get-current-repo)
-        classes (:property/schema.classes property)
+        classes (:logseq.property/classes property)
         tags? (= :block/tags (:db/ident property))
         alias? (= :block/alias (:db/ident property))
         tags-or-alias? (or tags? alias?)
@@ -655,7 +655,7 @@
             distinct)
 
            :else
-           (let [property-type (get-in property [:block/schema :type])]
+           (let [property-type (:logseq.property/type property)]
              (if (empty? result)
                (let [v (get block (:db/ident property))]
                  (remove #(= :logseq.property/empty-placeholder (:db/ident %))
@@ -675,7 +675,7 @@
         options (map (fn [node]
                        (let [id (or (:value node) (:db/id node))
                              [header label] (if (integer? id)
-                                              (let [node-title (if (seq (:property/schema.classes property))
+                                              (let [node-title (if (seq (:logseq.property/classes property))
                                                                  (:block/title node)
                                                                  (block-handler/block-unique-title node))
                                                     title (subs node-title 0 256)
@@ -686,7 +686,7 @@
                                                                [:div.text-xs.opacity-70
                                                                 (breadcrumb {:search? true} (state/get-current-repo) (:block/uuid block) {})]))
                                                     label [:div.flex.flex-row.items-center.gap-1
-                                                           (when-not (:property/schema.classes property)
+                                                           (when-not (:logseq.property/classes property)
                                                              (ui/icon icon {:size 14}))
                                                            [:div title]]]
                                                 [header label])
@@ -781,7 +781,7 @@
                                                                                                    :built-in? false})]
                                      (set-result! result)))))
         repo (state/get-current-repo)
-        classes (:property/schema.classes property)
+        classes (:logseq.property/classes property)
         non-root-classes (remove (fn [c] (= (:db/ident c) :logseq.class/Root)) classes)
         parent-property? (= (:db/ident property) :logseq.property/parent)]
     (when (and (not parent-property?) (seq non-root-classes))
@@ -817,14 +817,13 @@
         values (rum/react *values)
         block (db/sub-block (:db/id block))]
     (when-not (= :loading values)
-      (let [schema (:block/schema property)
-            type (:type schema)
+      (let [type (:logseq.property/type property)
             closed-values? (seq (:property/closed-values property))
             ref-type? (db-property-type/all-ref-property-types type)
             items (if closed-values?
                     (let [date? (and
                                  (= (:db/ident property) :logseq.task/recur-unit)
-                                 (= :date (get-in (:property opts) [:block/schema :type])))
+                                 (= :date (:logseq.property/type (:property opts))))
                           values (cond->> (:property/closed-values property)
                                    date?
                                    (remove (fn [b] (contains? #{:logseq.task/recur-unit.minute :logseq.task/recur-unit.hour} (:db/ident b)))))]
@@ -1031,8 +1030,7 @@
        (when (:editing? opts)
          (.click (rum/deref *el))))
      [(:editing? opts)])
-    (let [schema (:block/schema property)
-          type (get schema :type :default)
+    (let [type (:logseq.property/type property)
           select-opts' (assoc select-opts :multiple-choices? false)
           popup-content (fn content-fn [_]
                           [:div.property-select
@@ -1071,11 +1069,10 @@
 (defn- property-value-inner
   [block property value {:keys [inline-text page-cp
                                 dom-id row?]}]
-  (let [schema (:block/schema property)
-        multiple-values? (db-property/many? property)
+  (let [multiple-values? (db-property/many? property)
         class (str (when-not row? "flex flex-1 ")
                    (when multiple-values? "property-value-content"))
-        type (:type schema)
+        type (:logseq.property/type property)
         text-ref-type? (db-property-type/text-ref-property-types type)]
     [:div.cursor-text
      {:id (or dom-id (random-uuid))
@@ -1102,8 +1099,7 @@
   [state block property value* {:keys [container-id editing? on-chosen]
                                 :as opts}]
   (let [property (model/sub-block (:db/id property))
-        schema (:block/schema property)
-        type (get schema :type :default)
+        type (:logseq.property/type property)
         editing? (or editing?
                      (and (state/sub-editing? [container-id (:block/uuid block)])
                           (= (:db/id property) (:db/id (:property (state/get-editor-action-data))))))
@@ -1163,8 +1159,8 @@
            (property-value-inner block property value opts)])))))
 
 (rum/defc multiple-values-inner
-  [block property v {:keys [on-chosen editing?] :as opts} schema]
-  (let [type (get schema :type :default)
+  [block property v {:keys [on-chosen editing?] :as opts}]
+  (let [type (:logseq.property/type property)
         date? (= type :date)
         *el (rum/use-ref nil)
         items (cond->> (if (de/entity? v) #{v} v)
@@ -1219,12 +1215,12 @@
                (property-empty-text-value property opts))))]))))
 
 (rum/defc multiple-values < rum/reactive db-mixins/query
-  [block property opts schema]
+  [block property opts]
   (let [block (db/sub-block (:db/id block))
         value (get block (:db/ident property))
         value' (if (coll? value) value
                    (when (some? value) #{value}))]
-    (multiple-values-inner block property value' opts schema)))
+    (multiple-values-inner block property value' opts)))
 
 (rum/defcs property-value < rum/reactive db-mixins/query
   [state block property {:keys [show-tooltip?]
@@ -1242,8 +1238,7 @@
                       :properties-cp :properties-cp})
          dom-id (str "ls-property-" (:db/id block) "-" (:db/id property))
          editor-id (str dom-id "-editor")
-         schema (:block/schema property)
-         type (some-> schema (get :type :default))
+         type (:logseq.property/type property)
          multiple-values? (db-property/many? property)
          v (get block (:db/ident property))
          v (cond
@@ -1271,7 +1266,7 @@
                      (property-normal-block-value block property v)
 
                      multiple-values?
-                     (multiple-values block property opts schema)
+                     (multiple-values block property opts)
 
                      :else
                      (let [parent? (= property-ident :logseq.property/parent)

+ 4 - 4
src/main/frontend/components/query.cljs

@@ -1,22 +1,22 @@
 (ns frontend.components.query
   (:require [clojure.string :as string]
-            [frontend.components.file-based.query-table :as query-table]
             [frontend.components.file-based.query :as file-query]
+            [frontend.components.file-based.query-table :as query-table]
             [frontend.components.query.result :as query-result]
             [frontend.components.query.view :as query-view]
+            [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.db :as db]
             [frontend.db-mixins :as db-mixins]
             [frontend.extensions.sci :as sci]
             [frontend.handler.editor :as editor-handler]
+            [frontend.hooks :as hooks]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [lambdaisland.glogi :as log]
-            [rum.core :as rum]
-            [frontend.config :as config]
             [logseq.db :as ldb]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (defn- built-in-custom-query?
   [title]

+ 14 - 14
src/main/frontend/components/query/builder.cljs

@@ -1,31 +1,31 @@
 (ns frontend.components.query.builder
   "DSL query builder."
-  (:require [frontend.date :as date]
-            [frontend.ui :as ui]
+  (:require [clojure.string :as string]
+            [frontend.components.select :as component-select]
+            [frontend.config :as config]
+            [frontend.date :as date]
             [frontend.db :as db]
+            [frontend.db-mixins :as db-mixins]
             [frontend.db.async :as db-async]
             [frontend.db.model :as db-model]
             [frontend.db.query-dsl :as query-dsl]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.query.builder :as query-builder]
-            [frontend.components.select :as component-select]
+            [frontend.hooks :as hooks]
+            [frontend.mixins :as mixins]
             [frontend.state :as state]
+            [frontend.ui :as ui]
             [frontend.util :as util]
-            [logseq.shui.ui :as shui]
-            [frontend.mixins :as mixins]
-            [logseq.graph-parser.db :as gp-db]
-            [rum.core :as rum]
-            [clojure.string :as string]
             [logseq.common.util :as common-util]
             [logseq.common.util.page-ref :as page-ref]
-            [promesa.core :as p]
-            [frontend.config :as config]
+            [logseq.db :as ldb]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property.type :as db-property-type]
             [logseq.db.sqlite.util :as sqlite-util]
-            [frontend.db-mixins :as db-mixins]
-            [logseq.db :as ldb]
-            [frontend.hooks :as hooks]))
+            [logseq.graph-parser.db :as gp-db]
+            [logseq.shui.ui :as shui]
+            [promesa.core :as p]
+            [rum.core :as rum]))
 
 (rum/defc page-block-selector
   [*find]
@@ -204,7 +204,7 @@
 (rum/defc property-value-select
   [repo *property *private-property? *find *tree opts loc]
   (let [db-graph? (sqlite-util/db-based-graph? repo)
-        property-type (when db-graph? (get-in (db/entity repo @*property) [:block/schema :type]))
+        property-type (when db-graph? (:logseq.property/type (db/entity repo @*property)))
         ref-property? (and db-graph? (contains? db-property-type/all-ref-property-types property-type))
         [values set-values!] (rum/use-state nil)]
     (hooks/use-effect!

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

@@ -16,6 +16,7 @@
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
+            [frontend.hooks :as hooks]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
@@ -23,8 +24,7 @@
             [logseq.shui.ui :as shui]
             [medley.core :as medley]
             [reitit.frontend.easy :as rfe]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (rum/defc toggle
   []

+ 7 - 7
src/main/frontend/components/server.cljs

@@ -1,16 +1,16 @@
 (ns frontend.components.server
   (:require
    [clojure.string :as string]
-   [logseq.shui.ui :as shui]
-   [rum.core :as rum]
    [electron.ipc :as ipc]
-   [medley.core :as medley]
-   [promesa.core :as p]
-   [frontend.state :as state]
-   [frontend.util :as util]
    [frontend.handler.notification :as notification]
+   [frontend.hooks :as hooks]
+   [frontend.state :as state]
    [frontend.ui :as ui]
-   [frontend.hooks :as hooks]))
+   [frontend.util :as util]
+   [logseq.shui.ui :as shui]
+   [medley.core :as medley]
+   [promesa.core :as p]
+   [rum.core :as rum]))
 
 (rum/defcs panel-of-tokens
   < rum/reactive

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

@@ -21,6 +21,7 @@
             [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.user :as user-handler]
+            [frontend.hooks :as hooks]
             [frontend.mobile.util :as mobile-util]
             [frontend.modules.instrumentation.core :as instrument]
             [frontend.modules.shortcut.data-helper :as shortcut-helper]
@@ -36,8 +37,7 @@
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
             [reitit.frontend.easy :as rfe]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (defn toggle
   [label-for name state on-toggle & [detail-text]]

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

@@ -8,14 +8,14 @@
             [frontend.handler.plugin-config :as plugin-config-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
+            [frontend.hooks :as hooks]
             [frontend.rum :refer [use-mounted]]
             [frontend.state :as state]
             [frontend.storage :as storage]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [logseq.shui.ui :as shui]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (rum/defc scrollbar-measure
   []

+ 56 - 56
src/main/frontend/components/user/login.cljs

@@ -1,17 +1,17 @@
 (ns frontend.components.user.login
-  (:require [clojure.string :as string]
-            [logseq.shui.ui :as shui]
-            [rum.core :as rum]
+  (:require [cljs-bean.core :as bean]
+            [clojure.string :as string]
             [dommy.core :refer-macros [sel]]
-            [frontend.rum :refer [adapt-class]]
-            [frontend.modules.shortcut.core :as shortcut]
-            [frontend.handler.user :as user]
-            [frontend.handler.route :as route-handler]
-            [cljs-bean.core :as bean]
+            [frontend.config :as config]
             [frontend.handler.notification :as notification]
+            [frontend.handler.route :as route-handler]
+            [frontend.handler.user :as user]
+            [frontend.hooks :as hooks]
+            [frontend.modules.shortcut.core :as shortcut]
+            [frontend.rum :refer [adapt-class]]
             [frontend.state :as state]
-            [frontend.config :as config]
-            [frontend.hooks :as hooks]))
+            [logseq.shui.ui :as shui]
+            [rum.core :as rum]))
 
 (declare setupAuthConfigure! LSAuthenticator)
 
@@ -30,11 +30,11 @@
 
   (.setLanguage js/LSAmplify.I18n (or (:preferred-language @state/state) "en"))
   (setupAuthConfigure!
-    #js {:region              config/REGION,
-         :userPoolId          config/USER-POOL-ID,
-         :userPoolWebClientId config/COGNITO-CLIENT-ID,
-         :identityPoolId      config/IDENTITY-POOL-ID,
-         :oauthDomain         config/OAUTH-DOMAIN}))
+   #js {:region              config/REGION,
+        :userPoolId          config/USER-POOL-ID,
+        :userPoolWebClientId config/COGNITO-CLIENT-ID,
+        :identityPoolId      config/IDENTITY-POOL-ID,
+        :oauthDomain         config/OAUTH-DOMAIN}))
 
 (rum/defc user-pane
   [_sign-out! user]
@@ -42,14 +42,14 @@
         username (:username user)]
 
     (hooks/use-effect!
-      (fn []
-        (when session
-          (user/login-callback session)
-          (notification/show! (str "Hi, " username " :)") :success)
-          (shui/dialog-close!)
-          (when (= :user-login (state/get-current-route))
-            (route-handler/redirect! {:to :home}))))
-      [])
+     (fn []
+       (when session
+         (user/login-callback session)
+         (notification/show! (str "Hi, " username " :)") :success)
+         (shui/dialog-close!)
+         (when (= :user-login (state/get-current-route))
+           (route-handler/redirect! {:to :home}))))
+     [])
 
     nil))
 
@@ -60,40 +60,40 @@
         *ref-el (rum/use-ref nil)]
 
     (hooks/use-effect!
-      (fn [] (setup-configure!)
-        (set-ready? true)
-        (js/setTimeout
-          (fn []
-            (when-let [^js el (some-> (rum/deref *ref-el) (.querySelector ".amplify-tabs"))]
-              (let [btn1 (.querySelector el "button")]
-                (.addEventListener el "pointerdown"
-                  (fn [^js e]
-                    (if (= (.-target e) btn1)
-                      (set-tab! :login)
-                      (set-tab! :create-account)))))))))
-      [])
+     (fn [] (setup-configure!)
+       (set-ready? true)
+       (js/setTimeout
+        (fn []
+          (when-let [^js el (some-> (rum/deref *ref-el) (.querySelector ".amplify-tabs"))]
+            (let [btn1 (.querySelector el "button")]
+              (.addEventListener el "pointerdown"
+                                 (fn [^js e]
+                                   (if (= (.-target e) btn1)
+                                     (set-tab! :login)
+                                     (set-tab! :create-account)))))))))
+     [])
 
     (hooks/use-effect!
-      (fn []
-        (when-let [^js el (rum/deref *ref-el)]
-          (js/setTimeout
-            #(some-> (.querySelector el (str "input[name=" (if (= tab :login) "username" "email") "]"))
-               (.focus)) 100)))
-      [tab])
+     (fn []
+       (when-let [^js el (rum/deref *ref-el)]
+         (js/setTimeout
+          #(some-> (.querySelector el (str "input[name=" (if (= tab :login) "username" "email") "]"))
+                   (.focus)) 100)))
+     [tab])
 
     [:div.cp__user-login
      {:ref *ref-el}
      (when ready?
        (LSAuthenticator
-         {:termsLink "https://blog.logseq.com/terms/"}
-         (fn [^js op]
-           (let [sign-out!'      (.-signOut op)
-                 ^js user-proxy (.-user op)
-                 ^js user       (try (js/JSON.parse (js/JSON.stringify user-proxy))
-                                     (catch js/Error e
-                                       (js/console.error "Error: Amplify user payload:" e)))
-                 user'          (bean/->clj user)]
-             (user-pane sign-out!' user')))))]))
+        {:termsLink "https://blog.logseq.com/terms/"}
+        (fn [^js op]
+          (let [sign-out!'      (.-signOut op)
+                ^js user-proxy (.-user op)
+                ^js user       (try (js/JSON.parse (js/JSON.stringify user-proxy))
+                                    (catch js/Error e
+                                      (js/console.error "Error: Amplify user payload:" e)))
+                user'          (bean/->clj user)]
+            (user-pane sign-out!' user')))))]))
 
 (rum/defcs modal-inner <
   shortcut/disable-all-shortcuts
@@ -107,9 +107,9 @@
 (defn open-login-modal!
   []
   (shui/dialog-open!
-    (fn [_close] (modal-inner))
-    {:label "user-login"
-     :content-props {:onPointerDownOutside #(let [inputs (sel "form[data-amplify-form] input:not([type=checkbox])")
-                                                  inputs (some->> inputs (map (fn [^js e] (.-value e))) (remove string/blank?))]
-                                              (when (seq inputs)
-                                                (.preventDefault %)))}}))
+   (fn [_close] (modal-inner))
+   {:label "user-login"
+    :content-props {:onPointerDownOutside #(let [inputs (sel "form[data-amplify-form] input:not([type=checkbox])")
+                                                 inputs (some->> inputs (map (fn [^js e] (.-value e))) (remove string/blank?))]
+                                             (when (seq inputs)
+                                               (.preventDefault %)))}}))

+ 15 - 22
src/main/frontend/components/views.cljs

@@ -6,29 +6,29 @@
             [clojure.set :as set]
             [clojure.string :as string]
             [datascript.impl.entity :as de]
+            [dommy.core :as dom]
             [frontend.components.dnd :as dnd]
             [frontend.components.property.value :as pv]
             [frontend.components.select :as select]
+            [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.date :as date]
             [frontend.db :as db]
+            [frontend.db-mixins :as db-mixins]
             [frontend.handler.property :as property-handler]
             [frontend.handler.ui :as ui-handler]
+            [frontend.hooks :as hooks]
+            [frontend.mixins :as mixins]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [goog.dom :as gdom]
-            [dommy.core :as dom]
+            [logseq.db :as ldb]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property.type :as db-property-type]
-            [logseq.shui.ui :as shui]
-            [rum.core :as rum]
-            [frontend.mixins :as mixins]
             [logseq.shui.table.core :as table-core]
-            [logseq.db :as ldb]
-            [frontend.config :as config]
-            [frontend.db-mixins :as db-mixins]
-            [frontend.hooks :as hooks]))
+            [logseq.shui.ui :as shui]
+            [rum.core :as rum]))
 
 (defn- get-latest-entity
   [e]
@@ -119,7 +119,7 @@
 
 (defn- get-property-value-for-search
   [block property]
-  (let [type (get-in property [:block/schema :type])
+  (let [type (:logseq.property/type property)
         many? (= :db.cardinality/many (get property :db/cardinality))
         number-type? (= :number type)
         v (get block (:db/ident property))
@@ -194,7 +194,7 @@
                                           :logseq.property/created-from-property}
                                         ident)
                              (and with-object-name? (= :block/title ident))
-                             (contains? #{:map :entity} (get-in property [:block/schema :type])))
+                             (contains? #{:map :entity} (:logseq.property/type property)))
                  (let [property (if (de/entity? property)
                                   property
                                   (or (merge (db/entity ident) property) property)) ; otherwise, :cell/:header/etc. will be removed
@@ -537,13 +537,6 @@
         :on-click #(set-show-input! true)}
        (ui/icon "search")))))
 
-(comment
-  (defn- property-ref-type?
-    [property]
-    (let [schema (:block/schema property)
-          type (:type schema)]
-      (db-property-type/all-ref-property-types type))))
-
 (defn- get-property-values
   [rows property]
   (let [property-ident (:db/ident property)
@@ -562,7 +555,7 @@
 (defn datetime-property?
   [property]
   (or
-   (= :datetime (get-in property [:block/schema :type]))
+   (= :datetime (:logseq.property/type property))
    (contains? #{:block/created-at :block/updated-at} (:db/ident property))))
 
 (def timestamp-options
@@ -615,7 +608,7 @@
                                    property (db/entity id)
                                    internal-property {:db/ident (:id column)
                                                       :block/title (:name column)
-                                                      :block/schema {:type (:type column)}}]
+                                                      :logseq.property/type (:type column)}]
                                (if (or property
                                        (= :db.cardinality/many (:db/cardinality (get schema id)))
                                        (not= (:type column) :string))
@@ -638,7 +631,7 @@
                                       (let [filters' (conj filters [(:db/ident property) :after value])]
                                         (set-filters! filters')))})
                  property
-                 (if (= :checkbox (get-in property [:block/schema :type]))
+                 (if (= :checkbox (:logseq.property/type property))
                    (let [items [{:value true :label "true"}
                                 {:value false :label "false"}]]
                      (merge option
@@ -701,7 +694,7 @@
     [:before :after]
     (concat
      [:is :is-not]
-     (case (get-in property [:block/schema :type])
+     (case (:logseq.property/type property)
        (:default :url :node)
        [:text-contains :text-not-contains]
        (:date)
@@ -794,7 +787,7 @@
 
 (rum/defc filter-value-select < rum/static
   [{:keys [data-fns] :as table} property value operator idx]
-  (let [type (get-in property [:block/schema :type])
+  (let [type (:logseq.property/type property)
         items (cond
                 (contains? #{:before :after} operator)
                 timestamp-options

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

@@ -120,7 +120,7 @@
                          [?b ?property-id ?vid]
                          [(not= ?vid :logseq.property/empty-placeholder)]
                          (or
-                          [?vid :property.value/content ?value]
+                          [?vid :logseq.property/value ?value]
                           [?vid :block/title ?value])]
                        property-id
                        value)]

+ 9 - 9
src/main/frontend/db/query_dsl.cljs

@@ -6,20 +6,20 @@
             [clojure.set :as set]
             [clojure.string :as string]
             [clojure.walk :as walk]
+            [frontend.config :as config]
             [frontend.date :as date]
-            [frontend.db.utils :as db-utils]
             [frontend.db.model :as model]
             [frontend.db.query-react :as query-react]
-            [logseq.db.frontend.rules :as rules]
+            [frontend.db.utils :as db-utils]
+            [frontend.state :as state]
             [frontend.template :as template]
-            [logseq.graph-parser.text :as text]
+            [frontend.util :as util]
+            [frontend.util.text :as text-util]
+            [logseq.common.util :as common-util]
             [logseq.common.util.date-time :as date-time-util]
             [logseq.common.util.page-ref :as page-ref]
-            [logseq.common.util :as common-util]
-            [frontend.util.text :as text-util]
-            [frontend.util :as util]
-            [frontend.config :as config]
-            [frontend.state :as state]))
+            [logseq.db.frontend.rules :as rules]
+            [logseq.graph-parser.text :as text]))
 
 ;; Query fields:
 
@@ -303,7 +303,7 @@
             (subs v' 1)
             (or (page-ref/get-page-name v') v'))
           ;; Convert number pages to string
-          (and (double? v) (= :node (get-in (db-utils/entity k) [:block/schema :type])))
+          (and (double? v) (= :node (:logseq.property/type (db-utils/entity k))))
           (str v)
           :else
           v')))

+ 4 - 4
src/main/frontend/extensions/pdf/windows.cljs

@@ -1,8 +1,8 @@
 (ns frontend.extensions.pdf.windows
-  (:require [frontend.state :as state]
-            [rum.core :as rum]
-            [cljs-bean.core :as bean]
-            [frontend.storage :as storage]))
+  (:require [cljs-bean.core :as bean]
+            [frontend.state :as state]
+            [frontend.storage :as storage]
+            [rum.core :as rum]))
 
 (def *active-win (atom nil))
 (def *exit-pending? (atom false))

+ 11 - 11
src/main/frontend/extensions/slide.cljs

@@ -1,20 +1,20 @@
 (ns frontend.extensions.slide
-  (:require [rum.core :as rum]
-            [cljs-bean.core :as bean]
-            [frontend.loader :as loader]
-            [frontend.ui :as ui]
-            [frontend.context.i18n :refer [t]]
-            [frontend.config :as config]
-            [frontend.components.block :as block]
+  (:require [cljs-bean.core :as bean]
             [clojure.string :as string]
-            [frontend.db-mixins :as db-mixins]
+            [frontend.components.block :as block]
+            [frontend.config :as config]
+            [frontend.context.i18n :refer [t]]
             [frontend.db :as db]
+            [frontend.db-mixins :as db-mixins]
+            [frontend.db.conn :as conn]
+            [frontend.handler.db-based.property.util :as db-pu]
+            [frontend.loader :as loader]
             [frontend.modules.outliner.tree :as outliner-tree]
             [frontend.state :as state]
-            [frontend.handler.db-based.property.util :as db-pu]
+            [frontend.ui :as ui]
             [logseq.db :as ldb]
             [logseq.db.frontend.property :as db-property]
-            [frontend.db.conn :as conn]))
+            [rum.core :as rum]))
 
 (defn loaded? []
   js/window.Reveal)
@@ -28,7 +28,7 @@
                        (->> properties
                             (keep (fn [[k v]]
                                     ;; Don't inject hidden props like created-from-property
-                                    (when-not (:hide? (:block/schema (db/entity repo k)))
+                                    (when-not (:logseq.property/hide? (db/entity repo k))
                                       [k
                                        (if (:db/id v)
                                          ;; Can't use db-property-util/lookup b/c vals aren't entities

+ 16 - 16
src/main/frontend/extensions/tldraw.cljs

@@ -1,36 +1,36 @@
 (ns frontend.extensions.tldraw
   "Adapters related to tldraw"
   (:require ["/frontend/tldraw-logseq" :as TldrawLogseq]
+            [cljs-bean.core :as bean]
             [frontend.components.block :as block]
             [frontend.components.export :as export]
             [frontend.components.page :as page]
+            [frontend.components.whiteboard :as whiteboard]
             [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
-            [frontend.db.model :as model]
             [frontend.db :as db]
+            [frontend.db.async :as db-async]
+            [frontend.db.model :as model]
             [frontend.extensions.pdf.assets :as pdf-assets]
+            [frontend.handler.assets :as assets-handler]
             [frontend.handler.editor :as editor-handler]
+            [frontend.handler.history :as history]
+            [frontend.handler.notification :as notification]
             [frontend.handler.page :as page-handler]
-            [frontend.handler.assets :as assets-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.whiteboard :as whiteboard-handler]
-            [frontend.handler.history :as history]
-            [frontend.handler.notification :as notification]
+            [frontend.hooks :as hooks]
             [frontend.rum :as r]
             [frontend.search :as search]
             [frontend.state :as state]
+            [frontend.ui :as ui]
             [frontend.util :as util]
+            [frontend.util.text :as text-util]
             [goog.object :as gobj]
-            [promesa.core :as p]
-            [rum.core :as rum]
-            [frontend.ui :as ui]
-            [frontend.components.whiteboard :as whiteboard]
-            [cljs-bean.core :as bean]
-            [frontend.db.async :as db-async]
             [logseq.common.util :as common-util]
             [logseq.shui.ui :as shui]
-            [frontend.util.text :as text-util]
-            [frontend.hooks :as hooks]))
+            [promesa.core :as p]
+            [rum.core :as rum]))
 
 (def tldraw (r/adapt-class (gobj/get TldrawLogseq "App")))
 
@@ -260,8 +260,8 @@
   (let [page-uuid (str page-uuid)
         [loaded-app set-loaded-app] (rum/use-state nil)]
     (hooks/use-effect! (fn []
-                       (when (and loaded-app block-id)
-                         (state/focus-whiteboard-shape loaded-app block-id))
-                       #())
-                     [block-id loaded-app])
+                         (when (and loaded-app block-id)
+                           (state/focus-whiteboard-shape loaded-app block-id))
+                         #())
+                       [block-id loaded-app])
     (tldraw-app-inner page-uuid block-id loaded-app set-loaded-app)))

+ 2 - 2
src/main/frontend/extensions/zotero.cljs

@@ -9,14 +9,14 @@
             [frontend.extensions.zotero.setting :as setting]
             [frontend.handler.notification :as notification]
             [frontend.handler.route :as route-handler]
+            [frontend.hooks :as hooks]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [goog.dom :as gdom]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]
-            [rum.core :as rum]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (def term-chan (chan))
 (def debounce-chan-mult (a/mult (api/debounce term-chan 500)))

+ 21 - 21
src/main/frontend/handler/common/plugin.cljs

@@ -40,28 +40,28 @@
   (js/console.log "debug:plugin:" (if only-check "Checking" "Installing") " #" repo)
   (let [version (if (not only-check) (:latest-version manifest) version)]
     (-> (fetch-web-plugin-entry-info repo (if only-check "" version))
-      (p/then (fn [web-pkg]
-                (let [web-pkg (merge web-pkg (dissoc manifest :stat :version :only-check))
-                      latest-version (:version web-pkg)
-                      valid-latest-version (when only-check
-                                             (let [coerced-current-version (.coerce util/sem-ver version)
-                                                   coerced-latest-version (.coerce util/sem-ver latest-version)]
-                                               (if (and coerced-current-version
-                                                     coerced-latest-version
-                                                     (util/sem-ver.lt coerced-current-version coerced-latest-version))
-                                                 latest-version
-                                                 (throw (js/Error. :no-new-version)))))]
-                  (emit-lsp-updates!
-                    {:status :completed
+        (p/then (fn [web-pkg]
+                  (let [web-pkg (merge web-pkg (dissoc manifest :stat :version :only-check))
+                        latest-version (:version web-pkg)
+                        valid-latest-version (when only-check
+                                               (let [coerced-current-version (.coerce util/sem-ver version)
+                                                     coerced-latest-version (.coerce util/sem-ver latest-version)]
+                                                 (if (and coerced-current-version
+                                                          coerced-latest-version
+                                                          (util/sem-ver.lt coerced-current-version coerced-latest-version))
+                                                   latest-version
+                                                   (throw (js/Error. :no-new-version)))))]
+                    (emit-lsp-updates!
+                     {:status :completed
+                      :only-check only-check
+                      :payload (if only-check
+                                 (assoc manifest :latest-version valid-latest-version :latest-notes (some-> web-pkg :_objectExtra :releaseNotes))
+                                 (assoc manifest :dst repo :version latest-version :web-pkg web-pkg))}))))
+        (p/catch (fn [^js e]
+                   (emit-lsp-updates!
+                    {:status :error
                      :only-check only-check
-                     :payload (if only-check
-                                (assoc manifest :latest-version valid-latest-version :latest-notes (some-> web-pkg :_objectExtra :releaseNotes))
-                                (assoc manifest :dst repo :version latest-version :web-pkg web-pkg))}))))
-      (p/catch (fn [^js e]
-                 (emit-lsp-updates!
-                   {:status :error
-                    :only-check only-check
-                    :payload (assoc manifest :error-code (.-message e))}))))))
+                     :payload (assoc manifest :error-code (.-message e))}))))))
 
 (defn install-marketplace-plugin!
   "Installs plugin given plugin map with id"

+ 1 - 1
src/main/frontend/handler/db_based/recent.cljs

@@ -26,4 +26,4 @@
        (remove ldb/hidden?)
        (remove (fn [e]
                  (and (ldb/property? e)
-                      (true? (get-in e [:block/schema :hide?])))))))
+                      (true? (:logseq.property/hide? e)))))))

+ 2 - 2
src/main/frontend/handler/editor.cljs

@@ -2737,7 +2737,7 @@
         (cursor/move-cursor-to-start input)
 
         (and property? right? (cursor/end? input)
-             (or (not= (get-in block [:block/schema :type]) :default)
+             (or (not= (:logseq.property/type block) :default)
                  (seq (:property/closed-values block))))
         (let [pair (util/rec-get-node input "property-pair")
               jtrigger (when pair (dom/sel1 pair ".property-value-container .jtrigger"))]
@@ -3471,7 +3471,7 @@
                         (concat class-properties)
                         (remove (fn [e] (db-property/db-attribute-properties (:db/ident e))))
                         (remove outliner-property/property-with-other-position?)
-                        (remove (fn [e] (:hide? (:block/schema e))))
+                        (remove (fn [e] (:logseq.property/hide? e)))
                         (remove nil?))]
     (or (seq properties)
         (ldb/class-instance? (entity-plus/entity-memoized db :logseq.class/Query) block))))

+ 21 - 21
src/main/frontend/handler/import.cljs

@@ -1,34 +1,34 @@
 (ns frontend.handler.import
   "Fns related to import from external services"
-  (:require [clojure.edn :as edn]
+  (:require [cljs.core.async.interop :refer [p->c]]
+            [clojure.core.async :as async]
+            [clojure.edn :as edn]
+            [clojure.string :as string]
             [clojure.walk :as walk]
-            [frontend.external :as external]
-            [frontend.handler.file :as file-handler]
-            [frontend.handler.repo :as repo-handler]
-            [frontend.handler.file-based.repo :as file-repo-handler]
-            [frontend.state :as state]
-            [frontend.date :as date]
             [frontend.config :as config]
-            [clojure.string :as string]
+            [frontend.date :as date]
             [frontend.db :as db]
-            [frontend.format.mldoc :as mldoc]
+            [frontend.db.async :as db-async]
+            [frontend.external :as external]
             [frontend.format.block :as block]
-            [logseq.graph-parser.mldoc :as gp-mldoc]
-            [logseq.common.util :as common-util]
-            [logseq.graph-parser.whiteboard :as gp-whiteboard]
-            [logseq.common.util.date-time :as date-time-util]
-            [frontend.handler.page :as page-handler]
+            [frontend.format.mldoc :as mldoc]
             [frontend.handler.editor :as editor]
+            [frontend.handler.file :as file-handler]
+            [frontend.handler.file-based.repo :as file-repo-handler]
             [frontend.handler.notification :as notification]
-            [frontend.util :as util]
-            [clojure.core.async :as async]
-            [cljs.core.async.interop :refer [p->c]]
-            [medley.core :as medley]
+            [frontend.handler.page :as page-handler]
+            [frontend.handler.repo :as repo-handler]
             [frontend.persist-db :as persist-db]
-            [promesa.core :as p]
-            [frontend.db.async :as db-async]
+            [frontend.state :as state]
+            [frontend.util :as util]
+            [logseq.common.util :as common-util]
+            [logseq.common.util.date-time :as date-time-util]
+            [logseq.db :as ldb]
             [logseq.db.sqlite.util :as sqlite-util]
-            [logseq.db :as ldb]))
+            [logseq.graph-parser.mldoc :as gp-mldoc]
+            [logseq.graph-parser.whiteboard :as gp-whiteboard]
+            [medley.core :as medley]
+            [promesa.core :as p]))
 
 (defn index-files!
   "Create file structure, then parse into DB (client only)"

+ 14 - 14
src/main/frontend/handler/plugin.cljs

@@ -781,16 +781,16 @@
                           (some-> (re-find #"github.com/([^/]+/[^/]+)" url) (last)))
             package-url (if github?
                           (some-> github-repo
-                             (plugin-common-handler/get-web-plugin-checker-url!))
+                                  (plugin-common-handler/get-web-plugin-checker-url!))
                           (str url "/package.json"))
             ^js res (js/window.fetch (str package-url "?v=" (js/Date.now)))
             package (if (and (.-ok res)
-                          (= (.-status res) 200))
+                             (= (.-status res) 200))
                       (-> (.json res)
-                        (p/then bean/->clj))
+                          (p/then bean/->clj))
                       (throw (js/Error. (.text res))))
             logseq (or (:logseq package)
-                     (throw (js/Error. "Illegal logseq package")))]
+                       (throw (js/Error. "Illegal logseq package")))]
       (let [id (if github?
                  (some-> github-repo (string/replace "/" "_"))
                  (or (:id logseq) (:name package)))
@@ -798,16 +798,16 @@
             theme? (some? (or (:theme logseq) (:themes logseq)))]
 
         (plugin-common-handler/emit-lsp-updates!
-          {:status :completed
-           :only-check false
-           :payload {:id id
-                     :repo repo
-                     :dst repo
-                     :theme theme?
-                     :web-pkg (cond-> package
-
-                                (not github?)
-                                (assoc :installedFromUserWebUrl url))}}))
+         {:status :completed
+          :only-check false
+          :payload {:id id
+                    :repo repo
+                    :dst repo
+                    :theme theme?
+                    :web-pkg (cond-> package
+
+                               (not github?)
+                               (assoc :installedFromUserWebUrl url))}}))
       url)))
 
 ;; components

+ 22 - 22
src/main/frontend/mobile/graph_picker.cljs

@@ -1,21 +1,21 @@
 (ns frontend.mobile.graph-picker
   (:require
    [clojure.string :as string]
-   [logseq.shui.ui :as shui]
-   [rum.core :as rum]
-   [frontend.ui :as ui]
-   [frontend.handler.notification :as notification]
+   [frontend.components.svg :as svg]
+   [frontend.fs :as fs]
    [frontend.handler.file-based.nfs :as nfs-handler]
+   [frontend.handler.notification :as notification]
    [frontend.handler.page :as page-handler]
-   [frontend.util :as util]
+   [frontend.hooks :as hooks]
+   [frontend.mobile.util :as mobile-util]
    [frontend.modules.shortcut.core :as shortcut]
    [frontend.state :as state]
-   [frontend.mobile.util :as mobile-util]
-   [frontend.fs :as fs]
-   [frontend.components.svg :as svg]
-   [promesa.core :as p]
+   [frontend.ui :as ui]
+   [frontend.util :as util]
    [logseq.common.path :as path]
-   [frontend.hooks :as hooks]))
+   [logseq.shui.ui :as shui]
+   [promesa.core :as p]
+   [rum.core :as rum]))
 
 (defn validate-graph-dirname
   [root dirname]
@@ -24,14 +24,14 @@
 (rum/defc toggle-item
   [{:keys [on? title on-toggle]}]
   (ui/button
-    [:span.flex.items-center.justify-between.w-full.py-1
-     [:strong title]
-     (ui/toggle on? (fn []) true)]
-    :class (str "toggle-item " (when on? "is-on"))
-    :intent "logseq"
-    :on-pointer-down #(util/stop %)
-    :on-click #(when (fn? on-toggle)
-                 (on-toggle (not on?)))))
+   [:span.flex.items-center.justify-between.w-full.py-1
+    [:strong title]
+    (ui/toggle on? (fn []) true)]
+   :class (str "toggle-item " (when on? "is-on"))
+   :intent "logseq"
+   :on-pointer-down #(util/stop %)
+   :on-click #(when (fn? on-toggle)
+                (on-toggle (not on?)))))
 
 (rum/defc ^:large-vars/cleanup-todo graph-picker-cp
   [{:keys [onboarding-and-home? logged? native-icloud?] :as opts}]
@@ -120,10 +120,10 @@
          :on-click (fn []
                      (shui/dialog-close!)
                      (page-handler/ls-dir-files! shortcut/refresh!
-                       {:dir (when native-ios?
-                               (or
-                                 (state/get-icloud-container-root-url)
-                                 (state/get-local-container-root-url)))})))]
+                                                 {:dir (when native-ios?
+                                                         (or
+                                                          (state/get-icloud-container-root-url)
+                                                          (state/get-local-container-root-url)))})))]
 
        ;; step 1
        :new-graph

+ 2 - 2
src/main/frontend/rum.cljs

@@ -5,8 +5,8 @@
             [clojure.string :as string]
             [clojure.walk :as w]
             [daiquiri.interpreter :as interpreter]
-            [rum.core :refer [use-state] :as rum]
-            [frontend.hooks :as hooks]))
+            [frontend.hooks :as hooks]
+            [rum.core :refer [use-state] :as rum]))
 
 ;; copy from https://github.com/priornix/antizer/blob/35ba264cf48b84e6597743e28b3570d8aa473e74/src/antizer/core.cljs
 

+ 7 - 7
src/main/frontend/ui.cljs

@@ -1,22 +1,24 @@
 (ns frontend.ui
   "Main ns for reusable components"
-  (:require ["@logseq/react-tweet-embed" :as react-tweet-embed]
+  (:require ["@emoji-mart/data" :as emoji-data]
+            ["@logseq/react-tweet-embed" :as react-tweet-embed]
+            ["emoji-mart" :as emoji-mart]
             ["react-intersection-observer" :as react-intersection-observer]
             ["react-textarea-autosize" :as TextareaAutosize]
             ["react-tippy" :as react-tippy]
             ["react-transition-group" :refer [CSSTransition TransitionGroup]]
             ["react-virtuoso" :refer [Virtuoso VirtuosoGrid]]
-            ["@emoji-mart/data" :as emoji-data]
-            ["emoji-mart" :as emoji-mart]
             [cljs-bean.core :as bean]
             [clojure.string :as string]
             [electron.ipc :as ipc]
             [frontend.components.svg :as svg]
             [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
+            [frontend.date :as date]
             [frontend.db-mixins :as db-mixins]
             [frontend.handler.notification :as notification]
             [frontend.handler.plugin :as plugin-handler]
+            [frontend.hooks :as hooks]
             [frontend.mixins :as mixins]
             [frontend.mobile.util :as mobile-util]
             [frontend.modules.shortcut.config :as shortcut-config]
@@ -32,12 +34,10 @@
             [lambdaisland.glogi :as log]
             [logseq.shui.icon.v2 :as shui.icon.v2]
             [logseq.shui.popup.core :as shui-popup]
+            [logseq.shui.ui :as shui]
             [medley.core :as medley]
             [promesa.core :as p]
-            [rum.core :as rum]
-            [logseq.shui.ui :as shui]
-            [frontend.date :as date]
-            [frontend.hooks :as hooks]))
+            [rum.core :as rum]))
 
 (declare icon)
 

+ 4 - 4
src/main/frontend/worker/commands.cljs

@@ -43,7 +43,7 @@
     (or
      (let [p (:logseq.task/recur-status-property entity)
            choices (:property/closed-values p)
-           checkbox? (= :checkbox (get-in p [:block/schema :type]))]
+           checkbox? (= :checkbox (:logseq.property/type p))]
        (if checkbox?
          true
          (some (fn [choice]
@@ -54,7 +54,7 @@
     (or
      (let [p (:logseq.task/recur-status-property entity)
            choices (:property/closed-values p)
-           checkbox? (= :checkbox (get-in p [:block/schema :type]))]
+           checkbox? (= :checkbox (:logseq.property/type p))]
        (if checkbox?
          false
          (some (fn [choice]
@@ -71,7 +71,7 @@
         value' (get-value entity property value)]
     (when-let [property-entity (d/entity db property')]
       (let [value-matches? (fn [datom-value]
-                             (let [ref? (contains? db-property-type/all-ref-property-types (:type (:block/schema property-entity)))
+                             (let [ref? (contains? db-property-type/all-ref-property-types (:logseq.property/type property-entity))
                                    db-value (cond
                                               ;; entity-conditions
                                               (nil? datom-value)
@@ -155,7 +155,7 @@
         frequency (db-property/property-value-content (:logseq.task/recur-frequency entity))
         unit (:logseq.task/recur-unit entity)
         property (d/entity db property-ident)
-        date? (= :date (get-in property [:block/schema :type]))
+        date? (= :date (:logseq.property/type property))
         current-value (cond->
                        (get entity property-ident)
                         date?

+ 58 - 8
src/main/frontend/worker/db/migrate.cljs

@@ -363,7 +363,7 @@
                              (true? (:db/index property)))
                 (let [fix-tx-data (->>
                                    (select-keys db-property/built-in-properties [:logseq.property.node/display-type])
-                                   (sqlite-create-graph/build-initial-properties*)
+                                   (sqlite-create-graph/build-properties)
                                    (map (fn [m]
                                           (assoc m :db/id (:db/id property)))))]
                   (d/transact! conn fix-tx-data)))
@@ -534,6 +534,52 @@
                           [:db/retract e :logseq.user/avatar]])
                  db-ids))))))
 
+(defn- schema->qualified-property-keyword
+  [prop-schema]
+  (reduce-kv
+   (fn [r k v]
+     (if (qualified-keyword? k)
+       (assoc r k v)
+       (cond
+         (= k :cardinality)
+         (assoc r :db/cardinality v)
+         (= k :classes)
+         (assoc r :logseq.property/classes v)
+         (= k :position)
+         (assoc r :logseq.property/ui-position v)
+         :else
+         (assoc r (keyword "logseq.property" k) v))))
+   {}
+   prop-schema))
+
+(defn- remove-block-schema
+  [conn _search-db]
+  (let [db @conn
+        schema (:schema db)]
+    (when (ldb/db-based-graph? db)
+      (let [db-ids (d/q '[:find [?b ...]
+                          :where
+                          [?b :block/schema]]
+                        db)
+            tx-data (mapcat (fn [eid]
+                              (let [entity (d/entity db eid)
+                                    schema (:block/schema entity)
+                                    schema-properties (schema->qualified-property-keyword schema)
+                                    hidden-page? (contains? #{common-config/favorites-page-name common-config/views-page-name}
+                                                            (:block/title entity))
+                                    m (assoc schema-properties :db/id eid)
+                                    m' (if hidden-page?
+                                         (-> m (assoc :logseq.property/hide? true) (dissoc :logseq.property/public?))
+                                         m)]
+                                (concat
+                                 [m'
+                                  [:db/retract eid :block/schema]])))
+                            db-ids)
+            tx-data' (concat tx-data [[:db/retractEntity :block/schema]])]
+        (d/transact! conn tx-data' {:db-migrate? true})))
+    (d/reset-schema! conn (dissoc schema :block/schema))
+    []))
+
 (def schema-version->updates
   "A vec of tuples defining datascript migrations. Each tuple consists of the
    schema version integer and a migration map. A migration map can have keys of :properties, :classes
@@ -608,7 +654,7 @@
                      :block/refs :block/path-refs :block/link
                      :block/title :block/closed-value-property
                      :block/created-at :block/updated-at
-                     :logseq.property.attribute/property-schema-classes :logseq.property.attribute/property-value-content]}]
+                     :logseq.property.attribute/property-classes :logseq.property.attribute/property-value-content]}]
    [47 {:fix replace-hidden-type-with-schema}]
    [48 {:properties [:logseq.property/default-value :logseq.property/scalar-default-value]}]
    [49 {:fix replace-special-id-ref-with-id-ref}]
@@ -626,7 +672,11 @@
                      :logseq.property.history/ref-value :logseq.property.history/scalar-value]}]
    [58 {:fix remove-duplicated-contents-page}]
    [59 {:properties [:logseq.property/created-by]}]
-   [60 {:fix (rename-properties {:logseq.property/public :logseq.property/publishing-public?})}]])
+   [60 {:fix (rename-properties {:logseq.property/public :logseq.property/publishing-public?})}]
+   [61 {:properties [:logseq.property/type :logseq.property/hide? :logseq.property/public? :logseq.property/view-context :logseq.property/ui-position]
+        :fix (rename-properties {:property/schema.classes :logseq.property/classes
+                                 :property.value/content :logseq.property/value})}]
+   [62 {:fix remove-block-schema}]])
 
 (let [max-schema-version (apply max (map first schema-version->updates))]
   (assert (<= db-schema/version max-schema-version))
@@ -698,7 +748,7 @@
                                       (when (d/entity db k)
                                         (assert (str "DB migration: property already exists " k)))))
                             (into {})
-                            sqlite-create-graph/build-initial-properties*
+                            sqlite-create-graph/build-properties
                             (map (fn [b] (assoc b :logseq.property/built-in? true))))
         classes' (->> (concat [:logseq.class/Property :logseq.class/Tag :logseq.class/Page :logseq.class/Journal :logseq.class/Whiteboard] classes)
                       distinct)
@@ -860,10 +910,10 @@
                                 [[:db/add eid :block/tags :logseq.class/Property]
                                  [:db/retract eid :block/tags :logseq.class/Page]]
 
-                                (when-let [schema (:block/schema entity)]
-                                  (or (:cardinality schema) (:classes schema)))
-                                (let [schema (:block/schema entity)]
-                                  [[:db/add eid :block/schema (dissoc schema :cardinality :classes)]])
+                                ;; (when-let [schema (:block/schema entity)]
+                                ;;   (or (:cardinality schema) (:classes schema)))
+                                ;; (let [schema (:block/schema entity)]
+                                ;;   [[:db/add eid :block/schema (dissoc schema :cardinality :classes)]])
 
                                 (and (:logseq.property.asset/type entity)
                                      (or (nil? (:logseq.property.asset/checksum entity))

+ 2 - 2
src/main/frontend/worker/rtc/db_listener.cljs

@@ -22,8 +22,8 @@
 
 (def ^:private watched-attrs
   #{:block/title :block/created-at :block/updated-at :block/alias
-    :block/tags :block/schema :block/link :block/journal-day
-    :property/schema.classes :property.value/content
+    :block/tags :block/link :block/journal-day
+    :logseq.property/classes :logseq.property/value
     :db/index :db/valueType :db/cardinality})
 
 (def ^:private watched-attr-ns

+ 3 - 4
src/main/frontend/worker/rtc/remote_update.cljs

@@ -4,7 +4,6 @@
             [clojure.set :as set]
             [clojure.string :as string]
             [datascript.core :as d]
-            [logseq.common.defkeywords :refer [defkeywords]]
             [frontend.worker.handler.page :as worker-page]
             [frontend.worker.rtc.asset :as r.asset]
             [frontend.worker.rtc.client-op :as client-op]
@@ -14,6 +13,7 @@
             [frontend.worker.state :as worker-state]
             [frontend.worker.util :as worker-util]
             [logseq.clj-fractional-indexing :as index]
+            [logseq.common.defkeywords :refer [defkeywords]]
             [logseq.common.util :as common-util]
             [logseq.db :as ldb]
             [logseq.db.frontend.property :as db-property]
@@ -367,12 +367,11 @@ so need to pull earlier remote-data from websocket."})
     :block/updated-at
     :block/created-at
     :block/alias
-    :block/schema
     :block/tags
     :block/link
     :block/journal-day
-    :property/schema.classes
-    :property.value/content})
+    :logseq.property/classes
+    :logseq.property/value})
 
 (def ^:private watched-attr-ns
   (conj db-property/logseq-property-namespaces "logseq.class"))

+ 2 - 2
src/main/frontend/worker/rtc/ws.cljs

@@ -3,9 +3,9 @@
   based on
   https://github.com/ReilySiegel/missionary-websocket/blob/master/src/com/reilysiegel/missionary/websocket.cljs"
   (:require [cljs-http-missionary.client :as http]
-            [frontend.worker.rtc.malli-schema :as rtc-schema]
-            [frontend.worker.rtc.exception :as r.ex]
             [frontend.common.missionary :as c.m]
+            [frontend.worker.rtc.exception :as r.ex]
+            [frontend.worker.rtc.malli-schema :as rtc-schema]
             [missionary.core :as m]))
 
 (defn- get-state

+ 7 - 38
src/main/frontend/worker/search.cljs

@@ -1,16 +1,16 @@
 (ns frontend.worker.search
   "Full-text and fuzzy search"
-  (:require [clojure.string :as string]
+  (:require ["fuse.js" :as fuse]
             [cljs-bean.core :as bean]
-            ["fuse.js" :as fuse]
-            [goog.object :as gobj]
+            [clojure.set :as set]
+            [clojure.string :as string]
             [datascript.core :as d]
             [frontend.common.search-fuzzy :as fuzzy]
-            [logseq.db.sqlite.util :as sqlite-util]
+            [goog.object :as gobj]
             [logseq.common.util :as common-util]
-            [logseq.db :as ldb]
-            [clojure.set :as set]
             [logseq.common.util.namespace :as ns-util]
+            [logseq.db :as ldb]
+            [logseq.db.sqlite.util :as sqlite-util]
             [logseq.graph-parser.text :as text]))
 
 ;; TODO: use sqlite for fuzzy search
@@ -332,37 +332,6 @@ DROP TRIGGER IF EXISTS blocks_au;
   (drop-tables-and-triggers! db)
   (create-tables-and-triggers! db))
 
-(comment
-  (defn- get-db-properties-str
-    "Similar to db-pu/readable-properties but with a focus on making property values searchable"
-    [db properties]
-    (->> properties
-         (keep
-          (fn [[k v]]
-            (let [property (d/entity db k)
-                  values
-                  (->> (if (set? v) v #{v})
-                       (map (fn [val]
-                              (if (= :db.type/ref (:db/valueType property))
-                                (let [e (d/entity db (:db/id val))
-                                      value (or
-                                           ;; closed value
-                                             (property-value-when-closed e)
-                                           ;; :page or :date properties
-                                             (:block/title e)
-                                             ;; first child
-                                             (let [parent-id (:db/id e)]
-                                               (:block/title (ldb/get-first-child db parent-id))))]
-                                  value)
-                                val)))
-                       (remove string/blank?))
-                  hide? (get-in property [:block/schema :hide?])]
-              (when (and (not hide?) (seq values))
-                (str (:block/title property)
-                     ": "
-                     (string/join "; " values))))))
-         (string/join ", "))))
-
 (defn get-all-block-contents
   [db]
   (when db
@@ -406,7 +375,7 @@ DROP TRIGGER IF EXISTS blocks_au;
         datoms (filter
                 (fn [datom]
                   ;; Capture any direct change on page display title, page ref or block content
-                  (contains? #{:block/uuid :block/name :block/title :block/properties :block/schema} (:a datom)))
+                  (contains? #{:block/uuid :block/name :block/title :block/properties} (:a datom)))
                 data)]
     (when (seq datoms)
       (get-blocks-from-datoms-impl repo tx-report datoms))))

+ 37 - 37
src/main/logseq/api.cljs

@@ -41,12 +41,13 @@
             [frontend.util :as util]
             [frontend.util.cursor :as cursor]
             [frontend.version :as fv]
+            [goog.date :as gdate]
             [goog.dom :as gdom]
             [goog.object :as gobj]
-            [goog.date :as gdate]
             [lambdaisland.glogi :as log]
             [logseq.api.block :as api-block]
             [logseq.common.util :as common-util]
+            [logseq.common.util.date-time :as date-time-util]
             [logseq.db :as ldb]
             [logseq.db.frontend.property.util :as db-property-util]
             [logseq.outliner.core :as outliner-core]
@@ -56,7 +57,6 @@
             [logseq.sdk.git]
             [logseq.sdk.ui :as sdk-ui]
             [logseq.sdk.utils :as sdk-utils]
-            [logseq.common.util.date-time :as date-time-util]
             [promesa.core :as p]
             [reitit.frontend.easy :as rfe]))
 
@@ -130,9 +130,9 @@
   ;; get app base info
   []
   (-> (sdk-utils/normalize-keyword-for-json
-        {:version fv/version
-         :supportDb true})
-    (bean/->js)))
+       {:version fv/version
+        :supportDb true})
+      (bean/->js)))
 
 (def ^:export get_user_configs
   (fn []
@@ -541,7 +541,7 @@
           query (bean/->clj query)]
       (if page?
         (-> (:name params)
-          (route-handler/redirect-to-page! {:anchor (:anchor query) :push true}))
+            (route-handler/redirect-to-page! {:anchor (:anchor query) :push true}))
         (rfe/push-state k params query)))))
 
 (def ^:export replace_state
@@ -627,29 +627,29 @@
 (defn ^:export get_page
   [id-or-page-name]
   (p/let [page (db-async/<pull (state/get-current-repo)
-                 (cond
-                   (number? id-or-page-name)
-                   id-or-page-name
-                   (util/uuid-string? id-or-page-name)
-                   [:block/uuid (uuid id-or-page-name)]
-                   :else
-                   [:block/name (util/page-name-sanity-lc id-or-page-name)]))]
+                               (cond
+                                 (number? id-or-page-name)
+                                 id-or-page-name
+                                 (util/uuid-string? id-or-page-name)
+                                 [:block/uuid (uuid id-or-page-name)]
+                                 :else
+                                 [:block/name (util/page-name-sanity-lc id-or-page-name)]))]
     (when-let [page (and (:block/name page)
-                      (some->> page (api-block/into-properties (state/get-current-repo))))]
+                         (some->> page (api-block/into-properties (state/get-current-repo))))]
       (bean/->js (sdk-utils/normalize-keyword-for-json page)))))
 
 (defn ^:export get_all_pages
   []
   (let [db (conn/get-db (state/get-current-repo))]
     (some->
-      (->>
-        (d/datoms db :avet :block/name)
-        (map #(db-utils/pull (:e %)))
-        (remove ldb/hidden?)
-        (remove (fn [page]
-                  (common-util/uuid-string? (:block/name page)))))
-      (sdk-utils/normalize-keyword-for-json)
-      (bean/->js))))
+     (->>
+      (d/datoms db :avet :block/name)
+      (map #(db-utils/pull (:e %)))
+      (remove ldb/hidden?)
+      (remove (fn [page]
+                (common-util/uuid-string? (:block/name page)))))
+     (sdk-utils/normalize-keyword-for-json)
+     (bean/->js))))
 
 (defn ^:export create_page
   [name ^js properties ^js opts]
@@ -659,29 +659,29 @@
     (p/let [page (<pull-block name)
             new-page (when-not page
                        (page-handler/<create!
-                         name
-                         (cond->
-                           {:redirect? (if (boolean? redirect) redirect true)
-                            :journal? journal
-                            :create-first-block? (if (boolean? createFirstBlock) createFirstBlock true)
-                            :format format}
-
-                           (not db-base?)
-                           (assoc :properties properties))))
+                        name
+                        (cond->
+                         {:redirect? (if (boolean? redirect) redirect true)
+                          :journal? journal
+                          :create-first-block? (if (boolean? createFirstBlock) createFirstBlock true)
+                          :format format}
+
+                          (not db-base?)
+                          (assoc :properties properties))))
             _ (when (and db-base? (seq properties))
                 (api-block/save-db-based-block-properties! new-page properties))]
       (some-> (or page new-page)
-        :db/id
-        (db-utils/pull)
-        (sdk-utils/normalize-keyword-for-json)
-        (bean/->js)))))
+              :db/id
+              (db-utils/pull)
+              (sdk-utils/normalize-keyword-for-json)
+              (bean/->js)))))
 
 (defn ^:export create_journal_page
   [^js date]
   (let [date (js/Date. date)]
     (when-let [datestr (and (not (js/isNaN (.getTime date)))
-                          (-> (gdate/Date. date)
-                            (date-time-util/format "yyyy-MM-dd")))]
+                            (-> (gdate/Date. date)
+                                (date-time-util/format "yyyy-MM-dd")))]
       (create_page datestr nil #js {:journal true :redirect false}))))
 
 (defn ^:export delete_page

File diff suppressed because it is too large
+ 0 - 0
src/rtc_e2e_test/example.cljs


+ 8 - 8
src/test/frontend/db/db_based_model_test.cljs

@@ -1,13 +1,13 @@
 (ns frontend.db.db-based-model-test
   (:require [cljs.test :refer [use-fixtures deftest is testing]]
-            [frontend.db.model :as model]
+            [datascript.core :as d]
             [frontend.db :as db]
+            [frontend.db.conn :as conn]
+            [frontend.db.model :as model]
             [frontend.test.helper :as test-helper]
-            [datascript.core :as d]
-            [logseq.db.frontend.class :as db-class]
             [logseq.db :as ldb]
-            [logseq.db.test.helper :as db-test]
-            [frontend.db.conn :as conn]))
+            [logseq.db.frontend.class :as db-class]
+            [logseq.db.test.helper :as db-test]))
 
 (def repo test-helper/test-db-name-db-version)
 
@@ -56,10 +56,10 @@
 
 (deftest get-classes-with-property-test
   (let [conn (db-test/create-conn-with-blocks
-              {:properties {:prop1 {:block/schema {:type :default}}}
+              {:properties {:prop1 {:logseq.property/type :default}}
                :classes
-               {:Class1 {:build/schema-properties [:prop1]}
-                :Class2 {:build/schema-properties [:prop1]}}})
+               {:Class1 {:build/class-properties [:prop1]}
+                :Class2 {:build/class-properties [:prop1]}}})
         property (d/entity @conn :user.property/prop1)
         classes (with-redefs [conn/get-db (constantly @conn)]
                   (model/get-classes-with-property (:db/ident property)))]

+ 11 - 11
src/test/frontend/db/query_dsl_test.cljs

@@ -183,7 +183,7 @@ prop-d:: [[nada]]"}])
   (deftest db-only-block-property-queries
     (load-test-files-for-db-graph
      {:properties
-      {:zzz {:block/schema {:type :default}
+      {:zzz {:logseq.property/type :default
              :block/title "zzz name!"}}
       :pages-and-blocks
       [{:page {:block/title "page1"}
@@ -208,11 +208,11 @@ prop-d:: [[nada]]"}])
   (deftest property-default-type-default-value-queries
     (load-test-files-for-db-graph
      {:properties
-      {:default {:block/schema {:type :default}
+      {:default {:logseq.property/type :default
                  :build/properties
                  {:logseq.property/default-value "foo"}
                  :build/properties-ref-types {:entity :number}}}
-      :classes {:Class1 {:build/schema-properties [:default]}}
+      :classes {:Class1 {:build/class-properties [:default]}}
       :pages-and-blocks
       [{:page {:block/title "page1"}
         :blocks [{:block/title "b1"
@@ -222,8 +222,8 @@ prop-d:: [[nada]]"}])
                  {:block/title "b3"
                   :build/tags [:Class1]}]}]})
 
-    (is (= ["b3" "b2" "b1"]
-           (map :block/title (dsl-query "(property :user.property/default)")))
+    (is (= (set ["b3" "b2" "b1"])
+           (set (map :block/title (dsl-query "(property :user.property/default)"))))
         "Blocks with any :default property or tagged with a tag that has that default-value property")
     (is (= ["b1" "b3"]
            (map :block/title (dsl-query "(property :user.property/default \"foo\")")))
@@ -235,10 +235,10 @@ prop-d:: [[nada]]"}])
   (deftest property-checkbox-type-default-value-queries
     (load-test-files-for-db-graph
      {:properties
-      {:checkbox {:block/schema {:type :checkbox}
+      {:checkbox {:logseq.property/type :checkbox
                   :build/properties
                   {:logseq.property/scalar-default-value true}}}
-      :classes {:Class1 {:build/schema-properties [:checkbox]}}
+      :classes {:Class1 {:build/class-properties [:checkbox]}}
       :pages-and-blocks
       [{:page {:block/title "page1"}
         :blocks [{:block/title "b1"
@@ -248,8 +248,8 @@ prop-d:: [[nada]]"}])
                  {:block/title "b3"
                   :build/tags [:Class1]}]}]})
 
-    (is (= ["b3" "b2" "b1"]
-           (map :block/title (dsl-query "(property :user.property/checkbox)")))
+    (is (= (set ["b3" "b2" "b1"])
+           (set (map :block/title (dsl-query "(property :user.property/checkbox)"))))
         "Blocks with any :checkbox property or tagged with a tag that has that default-value property")
     (is (= ["b1" "b3"]
            (map :block/title (dsl-query "(property :user.property/checkbox true)")))
@@ -261,14 +261,14 @@ prop-d:: [[nada]]"}])
   (deftest closed-property-default-value-queries
     (load-test-files-for-db-graph
      {:properties
-      {:status {:block/schema {:type :default}
+      {:status {:logseq.property/type :default
                 :build/closed-values
                 [{:value "Todo" :uuid (random-uuid)}
                  {:value "Doing" :uuid (random-uuid)}]
                 :build/properties
                 {:logseq.property/default-value "Todo"}
                 :build/properties-ref-types {:entity :number}}}
-      :classes {:Mytask {:build/schema-properties [:status]}
+      :classes {:Mytask {:build/class-properties [:status]}
                 :Bug {:build/class-parent :Mytask}}
       :pages-and-blocks
       [{:page {:block/title "page1"}

+ 4 - 4
src/test/frontend/worker/handler/page/db_based/page_test.cljs

@@ -1,9 +1,9 @@
 (ns frontend.worker.handler.page.db-based.page-test
   (:require [cljs.test :refer [deftest is testing]]
             [datascript.core :as d]
-            [logseq.db.test.helper :as db-test]
+            [frontend.worker.handler.page.db-based.page :as worker-db-page]
             [logseq.db :as ldb]
-            [frontend.worker.handler.page.db-based.page :as worker-db-page]))
+            [logseq.db.test.helper :as db-test]))
 
 (deftest create-class
   (let [conn (db-test/create-conn)
@@ -18,7 +18,7 @@
 
 (deftest create-namespace-pages
   (let [conn (db-test/create-conn-with-blocks
-              {:properties {:property1 {:block/schema {:type :default}}}
+              {:properties {:property1 {:logseq.property/type :default}}
                :classes {:class1 {}}
                :pages-and-blocks [{:page {:block/title "page1"}}]})]
 
@@ -97,4 +97,4 @@
            (->> (d/entity @conn [:block/uuid page-uuid])
                 :block/tags
                 (map #(:db/ident (d/entity @conn (:db/id %))))))
-        "New journal only has Journal tag")))
+        "New journal only has Journal tag")))

+ 1 - 1
src/test/frontend/worker/rtc/client_test.cljs

@@ -45,7 +45,7 @@
                                    :db/valueType :db.type/ref
                                    :block/updated-at 1716880036491
                                    :block/created-at 1716880036491
-                                   :block/schema {:type :number}
+                                   :logseq.property/type :number
                                    :db/cardinality :db.cardinality/one
                                    :db/ident :user.property/xxx,
                                    :block/type "property",

+ 2 - 2
src/test/frontend/worker/rtc/db_listener_test.cljs

@@ -49,7 +49,7 @@
                    [:db/add 1000000 :db/valueType :db.type/ref]
                    [:db/add 1000000 :block/updated-at 1716882111476]
                    [:db/add 1000000 :block/created-at 1716882111476]
-                   [:db/add 1000000 :block/schema {:type :number}]
+                   [:db/add 1000000 :logseq.property/type :number]
                    [:db/add 1000000 :db/cardinality :db.cardinality/one]
                    [:db/add 1000000 :db/ident :user.property/qqq]
                    [:db/add 1000000 :block/tags :logseq.class/Property]
@@ -68,10 +68,10 @@
             [:update {:block-uuid #uuid "66558abf-6512-469d-9e83-8f1ba0be9305"
                       :av-coll
                       [[:db/index "[\"~#'\",true]"]
+                       [:logseq.property/type "[\"~#'\",\"~:number\"]"]
                        [:db/valueType "[\"~#'\",\"~:db.type/ref\"]"]
                        [:block/updated-at "[\"~#'\",1716882111476]"]
                        [:block/created-at "[\"~#'\",1716882111476]"]
-                       [:block/schema "[\"^ \",\"~:type\",\"~:number\"]"]
                        [:block/tags #uuid "00000002-1038-7670-4800-000000000000"]
                        [:block/title "[\"~#'\",\"qqq\"]"]
                        [:db/cardinality "[\"~#'\",\"~:db.cardinality/one\"]"]

+ 2 - 2
src/test/frontend/worker/rtc/rtc_fns_test.cljs

@@ -4,14 +4,14 @@
             [frontend.db.conn :as conn]
             [frontend.state :as state]
             [frontend.test.helper :as test-helper]
+            [frontend.worker.fixtures :as worker-fixtures]
             [frontend.worker.rtc.malli-schema :as rtc-schema]
             [frontend.worker.rtc.remote-update :as r.remote]
             [frontend.worker.state :as worker-state]
             [logseq.common.config :as common-config]
             [logseq.db :as ldb]
             [logseq.outliner.core :as outliner-core]
-            [logseq.outliner.transaction :as outliner-tx]
-            [frontend.worker.fixtures :as worker-fixtures]))
+            [logseq.outliner.transaction :as outliner-tx]))
 
 (use-fixtures :each
   test-helper/db-based-start-and-destroy-db

Some files were not shown because too many files changed in this diff