浏览代码

refactor: replace both :page and :object types with :node

Tienson Qin 1 年之前
父节点
当前提交
3bc1a673cb

+ 5 - 5
deps/db/src/logseq/db/frontend/property.cljs

@@ -28,18 +28,18 @@
   (ordered-map
    :block/alias           {:title "Alias"
                            :attribute :block/alias
-                           :schema {:type :page
+                           :schema {:type :node
                                     :cardinality :many
                                     :view-context :page
                                     :public? true}}
    :block/tags           {:title "Tags"
                           :attribute :block/tags
-                          :schema {:type :page
+                          :schema {:type :node
                                    :cardinality :many
                                    :public? true
                                    :classes #{:logseq.class/Root}}}
    :logseq.property/page-tags {:title "pageTags"
-                               :schema {:type :page
+                               :schema {:type :node
                                         :public? true
                                         :view-context :page
                                         :cardinality :many}}
@@ -82,10 +82,10 @@
                                      :schema {:type :default
                                               :hide? true}}
    :logseq.property.linked-references/includes {:schema {; could be :entity to support blocks(objects) in the future
-                                                         :type :page
+                                                         :type :node
                                                          :cardinality :many
                                                          :hide? true}}
-   :logseq.property.linked-references/excludes {:schema {:type :page
+   :logseq.property.linked-references/excludes {:schema {:type :node
                                                          :cardinality :many
                                                          :hide? true}}
    :logseq.property.tldraw/page {:name :logseq.tldraw.page

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

@@ -16,7 +16,7 @@
 
 (def user-built-in-property-types
   "Valid property types for users in order they appear in the UI"
-  [:default :number :date :checkbox :url :page :object])
+  [:default :number :date :checkbox :url :node])
 
 (def closed-value-property-types
   "Valid property :type for closed values"
@@ -24,7 +24,7 @@
 
 (def position-property-types
   "Valid property :type for position"
-  #{:default :number :date :checkbox :url :page :object})
+  #{:default :number :date :checkbox :url :node})
 
 (assert (set/subset? closed-value-property-types (set user-built-in-property-types))
         "All closed value types are valid property types")
@@ -45,7 +45,7 @@
   "User facing ref types. Property values that users see are stored in either
   :property.value/content, :block/title.
   :block/title is for all the page related types"
-  (into #{:page :date :object} value-ref-property-types))
+  (into #{:date :node} value-ref-property-types))
 
 (assert (set/subset? ref-property-types
                      (set user-built-in-property-types))
@@ -60,8 +60,7 @@
                :number #{:cardinality}
                :date #{:cardinality}
                :url #{:cardinality}
-               :page #{:cardinality :classes}
-               :object #{:cardinality :classes}
+               :node #{:cardinality :classes}
                :checkbox #{}}))
 
 (assert (= (set user-built-in-property-types) (set (keys user-built-in-allowed-schema-attributes)))
@@ -117,15 +116,11 @@
     (when-let [ent (d/entity db s)]
       (string? (:block/title ent)))))
 
-(defn- page?
+(defn- node-entity?
   [db val]
   (when-let [ent (d/entity db val)]
-    (some? (:block/title ent))))
-
-(defn- object-entity?
-  [db val]
-  (when-let [ent (d/entity db val)]
-    (seq (:block/tags ent))))
+    ;; (seq (:block/tags ent))
+    (some? ent)))
 
 (defn- date?
   [db val]
@@ -149,12 +144,9 @@
    :url      [:fn
               {:error/message "should be a URL"}
               url-entity?]
-   :page     [:fn
-              {:error/message "should be a page"}
-              page?]
-   :object   [:fn
-              {:error/message "should be a page/block with tags"}
-              object-entity?]
+   :node   [:fn
+            {:error/message "should be a page/block with tags"}
+            node-entity?]
 
    ;; Internal usage
    ;; ==============
@@ -173,7 +165,7 @@
 
 (def property-types-with-db
   "Property types whose validation fn requires a datascript db"
-  #{:default :checkbox :url :number :date :page :object :entity})
+  #{:default :checkbox :url :number :date :node :entity})
 
 ;; Helper fns
 ;; ==========

+ 1 - 1
deps/db/src/logseq/db/frontend/schema.cljs

@@ -2,7 +2,7 @@
   "Main datascript schemas for the Logseq app"
   (:require [clojure.set :as set]))
 
-(def version 7)
+(def version 8)
 ;; 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}

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

@@ -278,7 +278,7 @@
     (when-not (get @property-schemas prop)
       (create-property-ident db all-idents prop)
       (let [schema (cond-> {:type prop-type}
-                     (#{:page :date} 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))]
@@ -359,13 +359,13 @@
       (or (get properties-text-values prop) (str val))
 
       ;; treat it the same as a :page
-      (= {:from :page :to :date} type-change)
+      (= {:from :node :to :date} type-change)
       (update-page-or-date-values page-names-to-uuids val)
 
       ;; Change to :page as dates can be pages but pages can't be dates
-      (= {:from :date :to :page} type-change)
+      (= {:from :date :to :node} type-change)
       (do
-        (swap! property-schemas assoc-in [prop :type] :page)
+        (swap! property-schemas assoc-in [prop :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

+ 11 - 11
scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs

@@ -100,8 +100,8 @@
           {:block/title "number property block" :build/properties {:number 5}}
           {:block/title "number-many property block" :build/properties {:number-many #{5 10}}}
           {:block/title "number-closed property block" :build/properties {:number-closed (random-closed-value :number-closed)}}
-          {:block/title "object property block" :build/properties {:object [:block/uuid object-uuid]}}
-          {:block/title "object-many property block" :build/properties {:object-many #{[:block/uuid object-uuid] [:page "Page object"]}}}
+          {:block/title "object property block" :build/properties {:node [:block/uuid object-uuid]}}
+          {:block/title "object-many property block" :build/properties {:node-many #{[:block/uuid object-uuid] [:page "Page object"]}}}
           {:block/title "page property block" :build/properties {:page [:page "Page 1"]}}
           {:block/title "page-many property block" :build/properties {:page-many #{[:page "Page 1"] [:page "Page 2"]}}}
           ;;  ;; :page-closed and :date-closed disabled for now since they're not supported
@@ -122,8 +122,8 @@
           {:block/title "{{query (property :number 5)}}"}
           {:block/title "{{query (property :number-many 10)}}"}
           {:block/title (str "{{query (property :number-closed " (pr-str (get-closed-value :number-closed)) ")}}")}
-          {:block/title "{{query (property :object \"block object\")}}"}
-          {:block/title "{{query (property :object-many [[Page object]])}}"}
+          {:block/title "{{query (property :node \"block object\")}}"}
+          {:block/title "{{query (property :node-many [[Page object]])}}"}
           {:block/title "{{query (property :page [[Page 1]])}}"}
           {:block/title "{{query (property :page-many [[Page 2]])}}"}
           #_{:block/title (str "{{query (property :page-closed " (page-ref/->page-ref (string/capitalize (get-closed-value :page-closed))) ")}}")}
@@ -142,8 +142,8 @@
         {:page {:block/title "number page" :build/properties {:number 5}}}
         {:page {:block/title "number-many page" :build/properties {:number-many #{5 10}}}}
         {:page {:block/title "number-closed page" :build/properties {:number-closed (random-closed-value :number-closed)}}}
-        {:page {:block/title "object page" :build/properties {:object [:block/uuid object-uuid]}}}
-        {:page {:block/title "object-many page" :build/properties {:object-many #{[:block/uuid object-uuid] [:page "Page object"]}}}}
+        {:page {:block/title "object page" :build/properties {:node [:block/uuid object-uuid]}}}
+        {:page {:block/title "object-many page" :build/properties {:node-many #{[:block/uuid object-uuid] [:page "Page object"]}}}}
         {:page {:block/title "page page" :build/properties {:page [:page "Page 1"]}}}
         {:page {:block/title "page-many page" :build/properties {:page-many #{[:page "Page 1"] [:page "Page 2"]}}}}
       ;;  #_{:page {:block/title "page-closed page" :build/properties {:page-closed (random-closed-value :page-closed)}}}
@@ -163,8 +163,8 @@
           {:block/title "{{query (page-property :number 5)}}"}
           {:block/title "{{query (page-property :number-many 10)}}"}
           {:block/title (str "{{query (page-property :number-closed " (pr-str (get-closed-value :number-closed)) ")}}")}
-          {:block/title "{{query (page-property :object \"block object\")}}"}
-          {:block/title "{{query (page-property :object-many [[Page object]])}}"}
+          {:block/title "{{query (page-property :node \"block object\")}}"}
+          {:block/title "{{query (page-property :node-many [[Page object]])}}"}
           {:block/title "{{query (page-property :page [[Page 1]])}}"}
           {:block/title "{{query (page-property :page-many [[Page 2]])}}"}
           #_{:block/title (str "{{query (page-property :page-closed " (page-ref/->page-ref (string/capitalize (get-closed-value :page-closed))) ")}}")}
@@ -176,14 +176,14 @@
 
      ;; Properties
      :properties
-     (->> [:default :url :checkbox :number :page :date :object]
+     (->> [:default :url :checkbox :number :page :date :node]
           (mapcat #(cond-> [[% (cond-> {:block/schema {:type %}}
-                                 (= :object %)
+                                 (= :node %)
                                  (assoc :build/schema-classes [:TestClass]))]]
                      (db-property-type/property-type-allows-schema-attribute? % :cardinality)
                      (conj [(keyword (str (name %) "-many"))
                             (cond-> {:block/schema {:type % :cardinality :many}}
-                                 (= :object %)
+                                 (= :node %)
                                  (assoc :build/schema-classes [:TestClass]))])))
           (into (mapv #(vector (keyword (str (name %) "-closed"))
                                {:block/schema {:type %}

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

@@ -6,10 +6,10 @@
      * Some classes are renamed due to naming conflicts
    * All properties with their property type, url, description
      * Property type is determined by looking for the first range value that is
-       a subclass of https://schema.org/DataType and then falling back to :page.
+       a subclass of https://schema.org/DataType and then falling back to :node.
      * 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 :page properties are given a :cardinality :many"
+     * schema.org assumes no cardinality. For now, only :node properties are given a :cardinality :many"
   (:require [logseq.outliner.cli :as outliner-cli]
             [logseq.common.util :as common-util]
             [logseq.db.frontend.property :as db-property]
@@ -95,7 +95,7 @@
 
 (defn- get-schema-type [range-includes class-map]
   (some #(or (schema->logseq-data-types %)
-             (when (class-map %) :page))
+             (when (class-map %) :node))
         range-includes))
 
 (defn- ->property-page [property-m class-map {:keys [verbose renamed-pages renamed-properties]}]
@@ -106,25 +106,25 @@
             (println "Picked property type:"
                      {:property (property-m "@id") :type schema-type :range-includes (vec range-includes)}))
         _ (assert schema-type (str "No schema found for property " (property-m "@id")))
-        _ (when (= schema-type :page)
+        _ (when (= schema-type :node)
             (when-let [datatype-classes (not-empty (set/intersection (set range-includes)
                                                                      (set (keys schema->logseq-data-types))))]
               (throw (ex-info (str "property " (pr-str (property-m "@id"))
-                                   " with type :page has DataType class values which aren't supported: " datatype-classes) {}))))
+                                   " with type :node has DataType class values which aren't supported: " datatype-classes) {}))))
 
         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 :page)
+                 (= schema-type :node)
                  (assoc :cardinality :many)
                  (property-m "rdfs:comment")
                  (assoc :description (get-comment-string (property-m "rdfs:comment") renamed-pages)))]
     {(keyword (strip-schema-prefix (property-m "@id")))
      (cond-> {:block/schema schema
               :build/properties {:url url}}
-       (= schema-type :page)
+       (= schema-type :node)
        (assoc :build/schema-classes (mapv (comp keyword strip-schema-prefix) range-includes)))}))
 
 (defn- get-class-to-properties
@@ -269,7 +269,7 @@
         all-properties* (get-all-properties schema-data options)
         property-tuples (map #(vector (% "@id") :property) all-properties*)
         class-tuples (map #(vector (% "@id") :class) all-classes*)
-        page-tuples (map #(vector (str "schema:" %) :page) existing-pages)
+        page-tuples (map #(vector (str "schema:" %) :node) existing-pages)
         renamed-classes (detect-id-conflicts-and-get-renamed-classes
                          property-tuples class-tuples page-tuples options)
         renamed-properties (detect-property-conflicts-and-get-renamed-properties

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

@@ -196,7 +196,7 @@
                 (when *property (reset! *property property))
                 (p/do!
                  (when *show-new-property-config? (reset! *show-new-property-config? false))
-                 (when (= (:type schema) :object) (reset! *show-class-select? true))
+                 (when (= (:type schema) :node) (reset! *show-class-select? true))
                  (components-pu/update-property! property property-name schema)
                  (cond
                    (and *show-class-select? @*show-class-select?)
@@ -321,7 +321,7 @@
             (case (:type @*property-schema)
               ;; Question: 1. should we still support classes for `page` type?
               ;;           2. flexible query instead of classes? e.g. find all papers are related to either Clojure or OCaml `(and (tag :paper) (or (tag :clojure) (tag :ocaml)))`
-              :object
+              :node
               (when (empty? (:property/closed-values property))
                 [:div.grid.grid-cols-5.gap-1.items-center.leading-8
                  [:label.col-span-2 "Specify classes:"]
@@ -445,7 +445,7 @@
                  :checkbox "checkbox"
                  :url "link"
                  :page "page"
-                 :object "topology-star"
+                 :node "topology-star"
                  "letter-t"))]
     (ui/icon icon {:class "opacity-50"
                    :size 15})))

+ 1 - 1
src/main/frontend/components/property/closed_value.cljs

@@ -102,7 +102,7 @@
                              :title "Delete this icon"}
           (ui/icon "X")])]]
      ;; Disable description for types that can't edit them
-     (when-not (#{:page :date} property-type)
+     (when-not (#{:node :date} property-type)
        [:div.grid.grid-cols-5.gap-1.items-start.leading-8
         [:label.col-span-2 "Description:"]
         [:div.col-span-3

+ 67 - 34
src/main/frontend/components/property/value.cljs

@@ -25,7 +25,9 @@
             [datascript.impl.entity :as de]
             [frontend.handler.property.util :as pu]
             [logseq.db.frontend.property.type :as db-property-type]
-            [dommy.core :as d]))
+            [dommy.core :as d]
+            [frontend.search :as search]
+            [goog.functions :refer [debounce]]))
 
 (rum/defc property-empty-btn-value
   [& {:as opts}]
@@ -57,7 +59,7 @@
 
 (defn- select-type?
   [property type]
-  (or (contains? #{:page :object :number :url :date} type)
+  (or (contains? #{:node :number :url :date} type)
       ;; closed values
       (seq (:property/closed-values property))))
 
@@ -306,16 +308,21 @@
     ;          {:id value :value label}) items') nil opts)
     ))
 
-(defn- get-title
-  [e]
-  (or (:block/title e)
-      (:block/title e)))
-
-(rum/defc select-page < rum/reactive db-mixins/query
+(defn- get-node-icon
+  [node]
+  (cond
+    (db/page? node)
+    "page"
+    (seq (:block/tags node))
+    "topology-star"
+    :else
+    "block"))
+
+(rum/defc select-node < rum/reactive db-mixins/query
   [property
-   {:keys [block multiple-choices? dropdown? input-opts] :as opts}]
+   {:keys [block multiple-choices? dropdown? input-opts on-input] :as opts}
+   *result]
   (let [repo (state/get-current-repo)
-        object? (= :object (get-in property [:block/schema :type]))
         classes (:property/schema.classes property)
         tags? (= :block/tags (:db/ident property))
         alias? (= :block/alias (:db/ident property))
@@ -325,7 +332,7 @@
                              (if (every? de/entity? v)
                                (map :db/id v)
                                [(:db/id v)])))
-        objects-or-pages
+        nodes
         (->>
          (cond
            (seq classes)
@@ -337,15 +344,30 @@
             classes)
 
            :else
-           (->> (model/get-all-pages repo)
-                (remove (fn [page]
-                          (or (ldb/built-in? page)
+           (let [result (rum/react *result)]
+             (if (empty? result)
+               (let [v (get block (:db/ident property))]
+                 (if (every? de/entity? v) v [v]))
+               (remove (fn [node]
+                         (or (= (:db/id block) (:db/id node))
                               ;; A page's alias can't be itself
-                              (and alias? (= (or (:db/id (:block/page block))
-                                                 (:db/id block))
-                                             (:db/id page)))))))))
-        options (map (fn [object] {:label (get-title object)
-                                   :value (:db/id object)}) objects-or-pages)
+                             (and alias? (= (or (:db/id (:block/page block))
+                                                (:db/id block))
+                                            (:db/id node)))))
+                       result)))))
+        options (map (fn [node]
+                       (let [id (or (:value node) (:db/id node))
+                             label (if (integer? id)
+                                     (let [title (subs (:block/title node) 0 256)
+                                           node (or (db/entity id) node)
+                                           icon (get-node-icon node)]
+                                       [:div.flex.flex-row.items-center.gap-1
+                                        (ui/icon icon {:size 14})
+                                        [:div title]])
+                                     (or (:label node) (:block/title node)))]
+                         (assoc node
+                                :label label
+                                :value id))) nodes)
         classes' (remove (fn [class] (= :logseq.class/Root (:db/ident class))) classes)
         opts' (cond->
                (merge
@@ -360,18 +382,20 @@
                                               alias?
                                               "Set alias"
                                               multiple-choices?
-                                              (str "Choose " (if object? "objects" "pages"))
+                                              "Choose nodes"
                                               :else
-                                              (str "Choose " (if object? "object" "page")))
+                                              "Choose node")
                  :show-new-when-not-exact-match? true
                  :extract-chosen-fn :value
                  :extract-fn :label
-
                  :input-opts input-opts
+                 :on-input (debounce on-input 50)
                  :on-chosen (fn [chosen selected?]
                               (p/let [id (if (integer? chosen) chosen
                                              (when-not (string/blank? (string/trim chosen))
-                                               (<create-page-if-not-exists! property classes' chosen)))]
+                                               (<create-page-if-not-exists! property classes' chosen)))
+                                      _ (when (and (integer? id) (not (ldb/page? (db/entity id))))
+                                          (db-async/<get-block repo id))]
                                 (if id
                                   (add-or-remove-property-value block property id selected? {})
                                   (log/error :msg "No :db/id found or created for chosen" :chosen chosen))))})
@@ -393,10 +417,12 @@
                                    results))))]
     (select-aux block property opts')))
 
-(defn property-value-select-page
-  [block property opts
+(rum/defcs property-value-select-node <
+  (rum/local nil ::result)
+  [state block property opts
    {:keys [*show-new-property-config?]}]
-  (let [input-opts (fn [_]
+  (let [*result (::result state)
+        input-opts (fn [_]
                      {:on-click (fn []
                                   (when *show-new-property-config?
                                     (reset! *show-new-property-config? false)))
@@ -406,10 +432,17 @@
                           "Escape"
                           (when-let [f (:on-chosen opts)] (f))
                           nil))})
+
         opts' (assoc opts
                      :block block
-                     :input-opts input-opts)]
-    (select-page property opts')))
+                     :input-opts input-opts
+                     :on-input (fn [v]
+                                 (if (string/blank? v)
+                                   (reset! *result nil)
+                                   (p/let [result (search/block-search (state/get-current-repo) v {:enable-snippet? false
+                                                                                                   :built-in? false})]
+                                     (reset! *result result)))))]
+    (select-node property opts' *result)))
 
 (rum/defcs select < rum/reactive db-mixins/query
   {:init (fn [state]
@@ -587,7 +620,7 @@
        (= value :logseq.property/empty-placeholder)
        (property-empty-btn-value)
 
-       (ldb/page? value)
+       (or (ldb/page? value) (seq (:block/tags value)))
        (when value
          (rum/with-key
            (page-cp {:disable-preview? true
@@ -596,7 +629,7 @@
                      :meta-click? other-position?} value)
            (:db/id value)))
 
-       (= type :object)
+       (= type :node)
        (when-let [reference (state/get-component :block/reference)]
          (reference {} (:block/uuid value)))
 
@@ -631,8 +664,8 @@
                              (:number :url :default)
                              (select block property select-opts' opts)
 
-                             (:object :page :date)
-                             (property-value-select-page block property select-opts' opts))])
+                             (:node :date)
+                             (property-value-select-node block property select-opts' opts))])
           trigger-id (str "trigger-" (:container-id opts) "-" (:db/id block) "-" (:db/id property))
           show! (fn [e]
                   (let [target (.-target e)]
@@ -748,8 +781,8 @@
                                                select-opts
                                                {:dropdown? false})]
                         [:div.property-select
-                         (if (contains? #{:page :object} type)
-                           (property-value-select-page block property
+                         (if (= :node type)
+                           (property-value-select-node block property
                                                        select-opts
                                                        opts)
                            (select block property select-opts opts))]))]

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

@@ -517,7 +517,7 @@
     (concat
      [:is :is-not]
      (case (get-in property [:block/schema :type])
-       (:default :url :page :object)
+       (:default :url :node)
        [:text-contains :text-not-contains]
        :date
        [:date-before :date-after]

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

@@ -29,6 +29,16 @@
                          [:db/add (:e d) :block/title (:block/original-name e)]])))) datoms)]
     tx-data))
 
+(defn- replace-object-and-page-type-with-node
+  [conn _search-db]
+  (->> (ldb/get-all-properties @conn)
+       (filter (fn [p]
+                 (contains? #{:object :page} (:type (:block/schema p)))))
+       (map
+        (fn [p]
+          {:db/id (:db/id p)
+           :block/schema (assoc (:block/schema p) :type :node)}))))
+
 (def schema-version->updates
   [[3 {:properties [:logseq.property/table-sorting :logseq.property/table-filters
                     :logseq.property/table-hidden-columns :logseq.property/table-ordered-columns]
@@ -42,7 +52,8 @@
    [5 {:properties [:logseq.property/view-for]
        :classes    []}]
    [6 {:properties [:logseq.property.asset/remote-metadata]}]
-   [7 {:fix replace-original-name-content-with-title}]])
+   [7 {:fix replace-original-name-content-with-title}]
+   [8 {:fix replace-object-and-page-type-with-node}]])
 
 (let [max-schema-version (apply max (map first schema-version->updates))]
   (assert (<= db-schema/version max-schema-version))

+ 2 - 1
src/main/frontend/worker/search.cljs

@@ -295,7 +295,8 @@ DROP TRIGGER IF EXISTS blocks_au;
                                       block-id (uuid id)]
                                   (when-let [block (d/entity @conn [:block/uuid block-id])]
                                     (when-not (and (not built-in?) (ldb/built-in? block))
-                                      {:block/uuid block-id
+                                      {:db/id (:db/id block)
+                                       :block/uuid block-id
                                        :block/title (or snippet title)
                                        :block/page (if (common-util/uuid-string? page)
                                                      (uuid page)

+ 1 - 1
src/main/logseq/api/block.cljs

@@ -52,7 +52,7 @@
       (let [type (cond
                    (boolean? value) :checkbox
                    (number? value) :number
-                   (coll? value) :page
+                   (coll? value) :node
                    :else :default)
             schema {:type type :cardinality (if multi? :many :one)}]
         (p/chain