diff --git a/deps/db/src/logseq/db/frontend/property.cljs b/deps/db/src/logseq/db/frontend/property.cljs index 38634e9bac..2b4353352a 100644 --- a/deps/db/src/logseq/db/frontend/property.cljs +++ b/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 diff --git a/deps/db/src/logseq/db/frontend/property/type.cljs b/deps/db/src/logseq/db/frontend/property/type.cljs index 3d891d4dee..98cdb601a4 100644 --- a/deps/db/src/logseq/db/frontend/property/type.cljs +++ b/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 ;; ========== diff --git a/deps/db/src/logseq/db/frontend/schema.cljs b/deps/db/src/logseq/db/frontend/schema.cljs index aead2c4cc4..133f9e19a4 100644 --- a/deps/db/src/logseq/db/frontend/schema.cljs +++ b/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} diff --git a/deps/graph-parser/src/logseq/graph_parser/exporter.cljs b/deps/graph-parser/src/logseq/graph_parser/exporter.cljs index 6e81c5cd5d..9536e03436 100644 --- a/deps/graph-parser/src/logseq/graph_parser/exporter.cljs +++ b/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 diff --git a/scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs b/scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs index 5ed6da981a..1c941f1bc9 100644 --- a/scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs +++ b/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 %} diff --git a/scripts/src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs b/scripts/src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs index c6f1646925..dec6974024 100644 --- a/scripts/src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs +++ b/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 diff --git a/src/main/frontend/components/property.cljs b/src/main/frontend/components/property.cljs index 5708cc8e59..06f088140a 100644 --- a/src/main/frontend/components/property.cljs +++ b/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}))) diff --git a/src/main/frontend/components/property/closed_value.cljs b/src/main/frontend/components/property/closed_value.cljs index 02c9dce618..c9f8b978f5 100644 --- a/src/main/frontend/components/property/closed_value.cljs +++ b/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 diff --git a/src/main/frontend/components/property/value.cljs b/src/main/frontend/components/property/value.cljs index cc8521ef2d..812271e719 100644 --- a/src/main/frontend/components/property/value.cljs +++ b/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))) +(defn- get-node-icon + [node] + (cond + (db/page? node) + "page" + (seq (:block/tags node)) + "topology-star" + :else + "block")) -(rum/defc select-page < rum/reactive db-mixins/query +(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)) - (> (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)) diff --git a/src/main/frontend/worker/search.cljs b/src/main/frontend/worker/search.cljs index eda0cafb09..451c17a340 100644 --- a/src/main/frontend/worker/search.cljs +++ b/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) diff --git a/src/main/logseq/api/block.cljs b/src/main/logseq/api/block.cljs index 9bc3e5f2f8..40f3a7fe78 100644 --- a/src/main/logseq/api/block.cljs +++ b/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