fix: batch-set-property working with property value refs

Fixed batch-setting background-color. With this fix was then able
to migrate order-list-type to use :default. Also cleaned up
outdated assumptions in batch fn
experiment/tanstack-table
Gabriel Horner 2024-05-15 17:37:57 -04:00
parent e50d3eff21
commit 8921767b69
3 changed files with 41 additions and 58 deletions

View File

@ -79,7 +79,7 @@
:logseq.property/hl-color {:schema {:type :default
:hide? true}}
:logseq.property/order-list-type {:name :logseq.order-list-type
:schema {:type :string
:schema {:type :default
:hide? true}}
:logseq.property.tldraw/page {:name :logseq.tldraw.page
:schema {:type :map

View File

@ -464,10 +464,13 @@
rest))))
(defn- blocks-with-ordered-list-props
[repo conn blocks target-block sibling?]
(let [db @conn
target-block (if sibling? target-block (when target-block (ldb/get-down target-block)))
list-type-fn (fn [block] (db-property-util/get-block-property-value repo db block :logseq.property/order-list-type))
[repo blocks target-block sibling?]
(let [target-block (if sibling? target-block (when target-block (ldb/get-down target-block)))
list-type-fn (fn [block]
(if (sqlite-util/db-based-graph? repo)
;; Get raw id since insert-blocks doesn't auto-handle raw property values
(:db/id (:logseq.property/order-list-type block))
(get (:block/properties block) (db-property-util/get-pid repo :logseq.property/order-list-type))))
db-based? (sqlite-util/db-based-graph? repo)]
(if-let [list-type (and target-block (list-type-fn target-block))]
(mapv
@ -644,7 +647,7 @@
(string/blank? (:block/content target-block))
(> (count blocks) 1)))
blocks' (let [blocks' (blocks-with-level blocks)]
(cond->> (blocks-with-ordered-list-props repo conn blocks' target-block sibling?)
(cond->> (blocks-with-ordered-list-props repo blocks' target-block sibling?)
update-timestamps?
(mapv (fn [b] (block-with-timestamps (dissoc b :block/created-at :block/updated-at))))
true

View File

@ -46,30 +46,12 @@
(fn property-value-schema [property-val]
(db-malli-schema/validate-property-value db schema-fn [property property-val] {:new-closed-value? new-closed-value?}))]))
(defn- fail-parse-long
[v-str]
(let [result (parse-long v-str)]
(or result
(throw (js/Error. (str "Can't convert \"" v-str "\" to a number"))))))
(defn- fail-parse-double
[v-str]
(let [result (parse-double v-str)]
(or result
(throw (js/Error. (str "Can't convert \"" v-str "\" to a number"))))))
(defn- infer-schema-from-input-string
[v-str]
(try
(cond
(fail-parse-long v-str) :number
(fail-parse-double v-str) :number
(common-util/url? v-str) :url
(contains? #{"true" "false"} (string/lower-case v-str)) :checkbox
:else :default)
(catch :default _e
:default)))
(defn ^:api convert-property-input-string
[schema-type v-str]
(if (and (= :number schema-type) (string? v-str))
@ -207,8 +189,7 @@
(throw (ex-info "Schema validation failed"
{:type :notification
:payload {:message msg'
:type :warning}}))
(prn :error :msg msg' :property k-name :v new-value))
:type :warning}})))
(let [status? (= :logseq.task/status (:db/ident property))
tx-data (build-property-value-tx-data block property-id new-value status?)]
(d/transact! conn tx-data {:outliner-op :save-block})))))
@ -246,6 +227,13 @@
property-id
raw-value)))
(defn- find-or-create-property-value
"Find or create a property value. Only to be used with properties that have ref types"
[conn property-id v]
(or (get-property-value-eid @conn property-id (str v))
(let [v-uuid (create-property-text-block! conn nil property-id (str v) {})]
(:db/id (d/entity @conn [:block/uuid v-uuid])))))
(defn set-block-property!
"Updates a block property's value for an existing property-id and block.
Property value is sanitized and if property is a ref type, automatically
@ -257,7 +245,7 @@
_ (assert (qualified-keyword? property-id) "property-id should be a keyword")
block (d/entity @conn block-eid)
property (d/entity @conn property-id)
_ (assert (some? property) (str "Property " property-id " doesn't exists yet"))
_ (assert (some? property) (str "Property " property-id " doesn't exist yet"))
property-type (get-in property [:block/schema :type] :default)
v' (or (resolve-tag! conn v) v)
db-attribute? (contains? db-property/db-attribute-properties property-id)
@ -274,12 +262,10 @@
(or (and (= property-type :number) (= property-id (:db/ident (:logseq.property/created-from-property (d/entity db v')))))
(not= property-type :number)))
v'
;; Get or create a property value by its raw value
(or (get-property-value-eid db property-id (str v'))
(let [v-uuid (create-property-text-block! conn nil (:db/id property) (str v') {})]
(:db/id (d/entity @conn [:block/uuid v-uuid])))))
(find-or-create-property-value conn property-id v'))
:else
v')
;; don't modify maps
new-value (if (or (sequential? new-value*) (set? new-value*))
(if (= :coll property-type)
(vec (remove string/blank? new-value*))
@ -290,35 +276,29 @@
(raw-set-block-property! conn block property property-type new-value))))))
(defn batch-set-property!
"Notice that this works only for properties with cardinality equals to `one`."
"Sets properties for multiple blocks. Automatically handles property value refs.
Does no validation of property values.
NOTE: This fn only works for properties with cardinality equal to `one`."
[conn block-ids property-id v]
(assert property-id "property-id is nil")
(let [block-eids (map ->eid block-ids)
property (d/entity @conn property-id)]
(when property
(let [type (:type (:block/schema property))
infer-schema (when-not type (infer-schema-from-input-string v))
property-type (or type infer-schema :default)
many? (db-property/many? property)
property (d/entity @conn property-id)
_ (assert (some? property) (str "Property " property-id " doesn't exist yet"))
_ (assert (not (db-property/many? property)) "Property must be cardinality :one in batch-set-property!")
property-type (get-in property [:block/schema :type] :default)
_ (assert v "Can't set a nil property value must be not nil")
v' (if (db-property-type/value-ref-property-types property-type)
(find-or-create-property-value conn property-id v)
v)
status? (= :logseq.task/status (:db/ident property))
txs (->>
(mapcat
txs (mapcat
(fn [eid]
(when-let [block (d/entity @conn eid)]
(when (and (some? v) (not many?))
(when-let [v* (try
(convert-property-input-string property-type v)
(catch :default e
(throw (ex-info "Property converted failed"
{:type :notification
:payload {:message (str e)
:type :error}}))
nil))]
(build-property-value-tx-data block property-id v* status?)))))
block-eids)
(remove nil?))]
(if-let [block (d/entity @conn eid)]
(build-property-value-tx-data block property-id v' status?)
(js/console.error "Skipping setting a block's property because the block id could not be found:" eid)))
block-eids)]
(when (seq txs)
(d/transact! conn txs {:outliner-op :save-block}))))))
(d/transact! conn txs {:outliner-op :save-block}))))
(defn batch-remove-property!
[conn block-ids property-id]