From fcf6ebd0e4186739f68226b7792f9e1db9d4e7e0 Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Fri, 10 May 2024 16:40:42 -0400 Subject: [PATCH] fix: page properties for :default, :number and :url Also fix page property example in properties graph and removed unused branches in validation --- .../logseq/db/frontend/property/build.cljs | 9 +- .../src/logseq/db/frontend/property/type.cljs | 15 +-- .../logseq/tasks/db_graph/create_graph.cljs | 106 ++++++++++-------- .../create_graph_with_properties.cljs | 32 +++--- .../frontend/handler/db_based/property.cljs | 2 +- 5 files changed, 89 insertions(+), 75 deletions(-) diff --git a/deps/db/src/logseq/db/frontend/property/build.cljs b/deps/db/src/logseq/db/frontend/property/build.cljs index 8df04a8f92..5b7c4f8908 100644 --- a/deps/db/src/logseq/db/frontend/property/build.cljs +++ b/deps/db/src/logseq/db/frontend/property/build.cljs @@ -68,14 +68,17 @@ closed-value-blocks-tx))] (into [property-tx] hidden-tx))) -(defn property-create-new-block +(defn build-property-value-block [block property value parse-block] (-> {:block/uuid (d/squuid) :block/format :markdown :block/content value - :block/page (:db/id (:block/page block)) + :block/page (if (:block/page block) + (:db/id (:block/page block)) + ;; page block + (:db/id block)) :block/parent (:db/id block) :logseq.property/created-from-property (or (:db/id property) {:db/ident (:db/ident property)})} sqlite-util/block-with-timestamps - parse-block)) + parse-block)) \ No newline at end of file diff --git a/deps/db/src/logseq/db/frontend/property/type.cljs b/deps/db/src/logseq/db/frontend/property/type.cljs index 207166c9f0..9cc41752da 100644 --- a/deps/db/src/logseq/db/frontend/property/type.cljs +++ b/deps/db/src/logseq/db/frontend/property/type.cljs @@ -74,10 +74,8 @@ (defn- url-entity? [db val] - (or - (= val :logseq.property/empty-placeholder) - (when-let [ent (d/entity db val)] - (url? (:block/content ent))))) + (when-let [ent (d/entity db val)] + (url? (:block/content ent)))) (defn- property-value-block? [db s] @@ -104,11 +102,9 @@ (defn- number-entity? [db id] - (or - (= id :logseq.property/empty-placeholder) - (when-let [entity (d/entity db id)] - (number? (some-> (:block/content entity) - parse-double))))) + (when-let [entity (d/entity db id)] + (number? (some-> (:block/content entity) + parse-double)))) (def built-in-validation-schemas "Map of types to malli validation schemas that validate a property value for that type" @@ -120,7 +116,6 @@ string-or-closed-string?] :number [:fn {:error/message "should be a number"} - ;; Also handles entity? so no need to use it number-entity?] :date [:fn {:error/message "should be a journal date"} diff --git a/scripts/src/logseq/tasks/db_graph/create_graph.cljs b/scripts/src/logseq/tasks/db_graph/create_graph.cljs index 8e90fc9cea..a4024ae152 100644 --- a/scripts/src/logseq/tasks/db_graph/create_graph.cljs +++ b/scripts/src/logseq/tasks/db_graph/create_graph.cljs @@ -114,7 +114,7 @@ (defn- create-property-value [block property value] - (db-property-build/property-create-new-block + (db-property-build/build-property-value-block block property ;; FIXME: Remove when fixed in UI @@ -122,8 +122,9 @@ ;; TODO: One day would be nice to parse block for refs #(assoc % :block/order (db-order/gen-key nil)))) -(defn- create-pvalue-entities - "Given a new block and its properties, creates a map of properties which have property values as entities" +(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" [new-block properties properties-config all-idents] (->> properties (map (fn [[k v]] @@ -133,25 +134,30 @@ (create-property-value new-block {:db/ident (get-ident all-idents k)} v))]))) (into {}))) +(defn- property-value-properties + "Converts a property-value-tx map for addition to a block by replacing values with references + to the property value entities" + [pvalue-tx] + (update-vals pvalue-tx + (fn [v] + (if (set? v) + (set (map #(vector :block/uuid (:block/uuid %)) v)) + (vector :block/uuid (:block/uuid v)))))) + (defn- ->block-tx [{:keys [properties] :as m} properties-config uuid-maps all-idents page-id] (let [new-block {:db/id (new-db-id) :block/format :markdown :block/page {:db/id page-id} :block/order (db-order/gen-key nil) :block/parent {:db/id page-id}} - pvalue-ents (create-pvalue-entities new-block properties properties-config all-idents) + pvalue-tx-m (->property-value-tx-m new-block properties properties-config all-idents) block-props (when (seq properties) - (->block-properties (merge properties - (update-vals pvalue-ents - (fn [v] - (if (set? v) - (set (map #(vector :block/uuid (:block/uuid %)) v)) - (vector :block/uuid (:block/uuid v)))))) + (->block-properties (merge properties (property-value-properties pvalue-tx-m)) uuid-maps all-idents))] (cond-> [] ;; Place property values first since they are referenced by block - (seq pvalue-ents) - (into (mapcat #(if (set? %) % [%]) (vals pvalue-ents))) + (seq pvalue-tx-m) + (into (mapcat #(if (set? %) % [%]) (vals pvalue-tx-m))) true (conj (merge (dissoc m :properties) (sqlite-util/block-with-timestamps new-block) @@ -272,6 +278,45 @@ "Class and property db-idents have no overlap") all-idents)) +(defn- build-pages-and-blocks-tx + [pages-and-blocks all-idents uuid-maps {:keys [page-id-fn properties] + :or {page-id-fn :db/id}}] + (vec + (mapcat + (fn [{:keys [page blocks]}] + (let [new-page (merge + {:db/id (or (:db/id page) (new-db-id)) + :block/original-name (or (:block/original-name page) (string/capitalize (:block/name page))) + :block/name (or (:block/name page) (common-util/page-name-sanity-lc (:block/original-name page))) + :block/format :markdown} + (dissoc page :properties :db/id :block/name :block/original-name)) + pvalue-tx-m (->property-value-tx-m new-page (:properties page) properties all-idents)] + (into + ;; page tx + (cond-> [] + (seq pvalue-tx-m) + (into (mapcat #(if (set? %) % [%]) (vals pvalue-tx-m))) + true + (conj + (sqlite-util/block-with-timestamps + (merge + new-page + (when (seq (:properties page)) + (->block-properties (merge (:properties page) (property-value-properties pvalue-tx-m)) + uuid-maps + all-idents)) + (when (seq (:properties page)) + {:block/refs (build-property-refs (:properties page) all-idents) + ;; app doesn't do this yet but it should to link property to page + :block/path-refs (build-property-refs (:properties page) all-idents)}))))) + ;; blocks tx + (reduce (fn [acc m] + (into acc + (->block-tx m properties uuid-maps all-idents (page-id-fn new-page)))) + [] + blocks)))) + pages-and-blocks))) + (defn create-blocks-tx "Given an EDN map for defining pages, blocks and properties, this creates a vector of transactable data for use with d/transact!. The blocks that can be created @@ -311,8 +356,7 @@ supported: :default, :url, :checkbox, :number, :page and :date. :checkbox and :number values are written as booleans and integers/floats. :page references are written as vectors e.g. `[:page \"PAGE NAME\"]`" - [{:keys [pages-and-blocks properties classes graph-namespace page-id-fn] - :or {page-id-fn :db/id} + [{:keys [pages-and-blocks properties classes graph-namespace] :as options}] (let [_ (validate-options options) ;; add uuids before tx for refs in :properties @@ -336,36 +380,8 @@ cs))) m)) properties-tx) - pages-and-blocks-tx - (vec - (mapcat - (fn [{:keys [page blocks]}] - (let [new-page (merge - {:db/id (or (:db/id page) (new-db-id)) - :block/original-name (or (:block/original-name page) (string/capitalize (:block/name page))) - :block/name (or (:block/name page) (common-util/page-name-sanity-lc (:block/original-name page))) - :block/format :markdown} - (dissoc page :properties :db/id :block/name :block/original-name))] - (into - ;; page tx - [(sqlite-util/block-with-timestamps - (merge - new-page - (when (seq (:properties page)) - (->block-properties (:properties page) uuid-maps all-idents)) - (when (seq (:properties page)) - {:block/refs (build-property-refs (:properties page) all-idents) - ;; app doesn't do this yet but it should to link property to page - :block/path-refs (build-property-refs (:properties page) all-idents)})))] - ;; blocks tx - (reduce (fn [acc m] - (into acc - (->block-tx m properties uuid-maps all-idents (page-id-fn new-page)))) - [] - blocks)))) - pages-and-blocks'))] - ;; Properties first b/c they have schema. Then pages b/c they can be referenced by blocks + pages-and-blocks-tx (build-pages-and-blocks-tx pages-and-blocks' all-idents uuid-maps options)] + ;; Properties first b/c they have schema and are referenced by all. Then classes b/c they can be referenced by pages. Then pages (vec (concat properties-tx' classes-tx - (filter :block/name pages-and-blocks-tx) - (remove :block/name pages-and-blocks-tx))))) + pages-and-blocks-tx)))) 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 4814ffb555..96c455c530 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 @@ -102,12 +102,12 @@ {:block/content "number property block" :properties {:number 5}} {:block/content "number-many property block" :properties {:number-many #{5 10}}} ;; {:block/content "number-closed property block" :properties {:number-closed (random-closed-value :number-closed)}} - ;; {:block/content "page property block" :properties {:page [:page "page 1"]}} - ;; {:block/content "page-many property block" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}} + {:block/content "page property block" :properties {:page [:page "page 1"]}} + {:block/content "page-many property block" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}} ;; ;; :page-closed and :date-closed disabled for now since they're not supported ;; #_{:block/content "page-closed property block" :properties {:page-closed (random-closed-value :page-closed)}} - ;; {:block/content "date property block" :properties {:date [:page (date-journal-title today)]}} - #_{:block/content "date-many property block" :properties {:date-many #{[:page (date-journal-title today)] + {:block/content "date property block" :properties {:date [:page (date-journal-title today)]}} + {:block/content "date-many property block" :properties {:date-many #{[:page (date-journal-title today)] [:page (date-journal-title yesterday)]}}} #_{:block/content "date-closed property block" :properties {:date-closed (random-closed-value :date-closed)}}]} #_{:page {:block/original-name "Block Property Queries"} @@ -130,22 +130,22 @@ #_{:block/content (str "{{query (property :date-closed " (page-ref/->page-ref (string/capitalize (get-closed-value :date-closed))) ")}}")}]} ;; Page property pages and queries - ;; {:page {:block/name "default page" :properties {:default "yolo block"}}} - ;; {:page {:block/name "string page" :properties {:string "yolo"}}} - ;; {:page {:block/name "string-many page" :properties {:string-many #{"yee" "haw" "sir"}}}} + ;; {:page {:block/name "default page" :properties {:default "yolo block"}}} + {:page {:block/name "string page" :properties {:string "yolo"}}} + {:page {:block/name "string-many page" :properties {:string-many #{"yee" "haw" "sir"}}}} ;; {:page {:block/name "string-closed page" :properties {:string-closed (random-closed-value :string-closed)}}} - ;; {:page {:block/name "url page" :properties {:url "https://logseq.com"}}} - ;; {:page {:block/name "url-many page" :properties {:url-many #{"https://logseq.com" "https://docs.logseq.com"}}}} + {:page {:block/name "url page" :properties {:url "https://logseq.com"}}} + {:page {:block/name "url-many page" :properties {:url-many #{"https://logseq.com" "https://docs.logseq.com"}}}} ;; {:page {:block/name "url-closed page" :properties {:url-closed (random-closed-value :url-closed)}}} - ;; {:page {:block/name "checkbox page" :properties {:checkbox true}}} - ;; {:page {:block/name "number page" :properties {:number 5}}} - ;; {:page {:block/name "number-many page" :properties {:number-many #{5 10}}}} + {:page {:block/name "checkbox page" :properties {:checkbox true}}} + {:page {:block/name "number page" :properties {:number 5}}} + {:page {:block/name "number-many page" :properties {:number-many #{5 10}}}} ;; {:page {:block/name "number-closed page" :properties {:number-closed (random-closed-value :number-closed)}}} - ;; {:page {:block/name "page page" :properties {:page [:page "page 1"]}}} - ;; {:page {:block/name "page-many page" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}}} + {:page {:block/name "page page" :properties {:page [:page "page 1"]}}} + {:page {:block/name "page-many page" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}}} ;; #_{:page {:block/name "page-closed page" :properties {:page-closed (random-closed-value :page-closed)}}} - ;; {:page {:block/name "date page" :properties {:date [:page (date-journal-title today)]}}} - #_{:page {:block/name "date-many page" :properties {:date-many #{[:page (date-journal-title today)] + {:page {:block/name "date page" :properties {:date [:page (date-journal-title today)]}}} + {:page {:block/name "date-many page" :properties {:date-many #{[:page (date-journal-title today)] [:page (date-journal-title yesterday)]}}}} #_{:page {:block/name "date-closed page" :properties {:date-closed (random-closed-value :date-closed)}}} #_{:page {:block/original-name "Page Property Queries"} diff --git a/src/main/frontend/handler/db_based/property.cljs b/src/main/frontend/handler/db_based/property.cljs index fd2083f65e..462e799c8e 100644 --- a/src/main/frontend/handler/db_based/property.cljs +++ b/src/main/frontend/handler/db_based/property.cljs @@ -432,7 +432,7 @@ [block property value parse-block {:keys [class-schema?]}] (assert (e/entity? property)) (let [repo (state/get-current-repo) - new-value-block (db-property-build/property-create-new-block block property value parse-block) + new-value-block (db-property-build/build-property-value-block block property value parse-block) class? (contains? (:block/type block) "class") property-id (:db/ident property)] (p/let [_ (db/transact! repo [new-value-block] {:outliner-op :insert-blocks})]