fix: no default set for the available choices stops selection

fixes https://github.com/logseq/db-test/issues/230
This commit is contained in:
Tienson Qin
2025-03-14 17:23:41 +08:00
parent ad4b1af31e
commit a551370498

View File

@@ -148,34 +148,6 @@
:property-id (:db/id property)}))
property))
(defn upsert-property!
"Updates property if property-id is given. Otherwise creates a property
with the given property-id or :property-name option. When a property is created
it is ensured to have a unique :db/ident"
[conn property-id schema {:keys [property-name] :as opts}]
(let [db @conn
db-ident (or property-id
(try (db-property/create-user-property-ident-from-name property-name)
(catch :default e
(throw (ex-info (str e)
{:type :notification
:payload {:message "Property failed to create. Please try a different property name."
:type :error}})))))]
(assert (qualified-keyword? db-ident))
(if-let [property (and (qualified-keyword? property-id) (d/entity db db-ident))]
(update-property conn db-ident property schema opts)
(let [k-name (or (and property-name (name property-name))
(name property-id))
db-ident' (db-ident/ensure-unique-db-ident @conn db-ident)]
(assert (some? k-name)
(prn "property-id: " property-id ", property-name: " property-name))
(outliner-validate/validate-page-title k-name {:node {:db/ident db-ident'}})
(outliner-validate/validate-page-title-characters k-name {:node {:db/ident db-ident'}})
(ldb/transact! conn
[(sqlite-util/build-new-property db-ident' schema {:title k-name})]
{:outliner-op :new-property})
(d/entity @conn db-ident')))))
(defn- validate-property-value-aux
[schema value {:keys [many?]}]
;; normalize :many values since most components update them as a single value
@@ -288,77 +260,6 @@
:payload {:message "Can't set this block itself as own property value"
:type :error}}))))
(defn set-block-property!
"Updates a block property's value for an existing property-id and block. If
property is a ref type, automatically handles a raw property value i.e. you
can pass \"value\" instead of the property value entity. Also handle db
attributes as properties"
[conn block-eid property-id v]
(throw-error-if-read-only-property property-id)
(let [block-eid (->eid block-eid)
_ (assert (qualified-keyword? property-id) "property-id should be a keyword")
block (d/entity @conn block-eid)
db-attribute? (some? (db-schema/schema property-id))]
(when (= property-id :block/tags)
(outliner-validate/validate-tags-property @conn [block-eid] v))
(when (= property-id :logseq.property/parent)
(outliner-validate/validate-parent-property v [block]))
(cond
db-attribute?
(when-not (and (= property-id :block/alias) (= v (:db/id block))) ; alias can't be itself
(ldb/transact! conn [{:db/id (:db/id block) property-id v}]
{:outliner-op :save-block}))
:else
(let [property (d/entity @conn property-id)
_ (assert (some? property) (str "Property " property-id " doesn't exist yet"))
property-type (get property :logseq.property/type :default)
ref? (db-property-type/all-ref-property-types property-type)
new-value (if ref?
(convert-ref-property-value conn property-id v property-type)
v)
existing-value (get block property-id)]
(throw-error-if-self-value block new-value ref?)
(when-not (= existing-value new-value)
(raw-set-block-property! conn block property property-type new-value))))))
(defn batch-set-property!
"Sets properties for multiple blocks. Automatically handles property value refs.
Does no validation of property values."
[conn block-ids property-id v]
(assert property-id "property-id is nil")
(throw-error-if-read-only-property property-id)
(let [block-eids (map ->eid block-ids)
_ (when (= property-id :block/tags)
(outliner-validate/validate-tags-property @conn block-eids v))
property (d/entity @conn property-id)
_ (when (= (:db/ident property) :logseq.property/parent)
(outliner-validate/validate-parent-property
(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 property :logseq.property/type :default)
_ (assert (some? v) "Can't set a nil property value must be not nil")
ref? (db-property-type/value-ref-property-types property-type)
default-url-not-closed? (and (contains? #{:default :url} property-type)
(not (seq (:property/closed-values property))))
v' (if ref?
(convert-ref-property-value conn property-id v property-type)
v)
txs (doall
(mapcat
(fn [eid]
(if-let [block (d/entity @conn eid)]
(let [v' (if default-url-not-closed?
(let [v (if (number? v) (:block/title (d/entity @conn v)) v)]
(convert-ref-property-value conn property-id v property-type))
v')]
(throw-error-if-self-value block v' ref?)
(build-property-value-tx-data conn block property-id v'))
(js/console.error "Skipping setting a block's property because the block id could not be found:" eid)))
block-eids))]
(when (seq txs)
(ldb/transact! conn txs {:outliner-op :save-block}))))
(defn batch-remove-property!
[conn block-ids property-id]
(throw-error-if-read-only-property property-id)
@@ -391,6 +292,46 @@
(when (seq txs)
(ldb/transact! conn txs {:outliner-op :save-block})))))))
(defn batch-set-property!
"Sets properties for multiple blocks. Automatically handles property value refs.
Does no validation of property values."
[conn block-ids property-id v]
(assert property-id "property-id is nil")
(throw-error-if-read-only-property property-id)
(if (nil? v)
(batch-remove-property! conn block-ids property-id)
(let [block-eids (map ->eid block-ids)
_ (when (= property-id :block/tags)
(outliner-validate/validate-tags-property @conn block-eids v))
property (d/entity @conn property-id)
_ (when (= (:db/ident property) :logseq.property/parent)
(outliner-validate/validate-parent-property
(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 property :logseq.property/type :default)
_ (assert (some? v) "Can't set a nil property value must be not nil")
ref? (db-property-type/value-ref-property-types property-type)
default-url-not-closed? (and (contains? #{:default :url} property-type)
(not (seq (:property/closed-values property))))
v' (if ref?
(convert-ref-property-value conn property-id v property-type)
v)
txs (doall
(mapcat
(fn [eid]
(if-let [block (d/entity @conn eid)]
(let [v' (if default-url-not-closed?
(let [v (if (number? v) (:block/title (d/entity @conn v)) v)]
(convert-ref-property-value conn property-id v property-type))
v')]
(throw-error-if-self-value block v' ref?)
(build-property-value-tx-data conn block property-id v'))
(js/console.error "Skipping setting a block's property because the block id could not be found:" eid)))
block-eids))]
(when (seq txs)
(ldb/transact! conn txs {:outliner-op :save-block})))))
(defn remove-block-property!
[conn eid property-id]
(throw-error-if-read-only-property property-id)
@@ -420,6 +361,69 @@
:else
(batch-remove-property! conn [eid] property-id))))
(defn set-block-property!
"Updates a block property's value for an existing property-id and block. If
property is a ref type, automatically handles a raw property value i.e. you
can pass \"value\" instead of the property value entity. Also handle db
attributes as properties"
[conn block-eid property-id v]
(throw-error-if-read-only-property property-id)
(if (nil? v)
(remove-block-property! conn block-eid property-id)
(let [block-eid (->eid block-eid)
_ (assert (qualified-keyword? property-id) "property-id should be a keyword")
block (d/entity @conn block-eid)
db-attribute? (some? (db-schema/schema property-id))]
(when (= property-id :block/tags)
(outliner-validate/validate-tags-property @conn [block-eid] v))
(when (= property-id :logseq.property/parent)
(outliner-validate/validate-parent-property v [block]))
(cond
db-attribute?
(when-not (and (= property-id :block/alias) (= v (:db/id block))) ; alias can't be itself
(ldb/transact! conn [{:db/id (:db/id block) property-id v}]
{:outliner-op :save-block}))
:else
(let [property (d/entity @conn property-id)
_ (assert (some? property) (str "Property " property-id " doesn't exist yet"))
property-type (get property :logseq.property/type :default)
ref? (db-property-type/all-ref-property-types property-type)
new-value (if ref?
(convert-ref-property-value conn property-id v property-type)
v)
existing-value (get block property-id)]
(throw-error-if-self-value block new-value ref?)
(when-not (= existing-value new-value)
(raw-set-block-property! conn block property property-type new-value)))))))
(defn upsert-property!
"Updates property if property-id is given. Otherwise creates a property
with the given property-id or :property-name option. When a property is created
it is ensured to have a unique :db/ident"
[conn property-id schema {:keys [property-name] :as opts}]
(let [db @conn
db-ident (or property-id
(try (db-property/create-user-property-ident-from-name property-name)
(catch :default e
(throw (ex-info (str e)
{:type :notification
:payload {:message "Property failed to create. Please try a different property name."
:type :error}})))))]
(assert (qualified-keyword? db-ident))
(if-let [property (and (qualified-keyword? property-id) (d/entity db db-ident))]
(update-property conn db-ident property schema opts)
(let [k-name (or (and property-name (name property-name))
(name property-id))
db-ident' (db-ident/ensure-unique-db-ident @conn db-ident)]
(assert (some? k-name)
(prn "property-id: " property-id ", property-name: " property-name))
(outliner-validate/validate-page-title k-name {:node {:db/ident db-ident'}})
(outliner-validate/validate-page-title-characters k-name {:node {:db/ident db-ident'}})
(ldb/transact! conn
[(sqlite-util/build-new-property db-ident' schema {:title k-name})]
{:outliner-op :new-property})
(d/entity @conn db-ident')))))
(defn delete-property-value!
"Delete value if a property has multiple values"
[conn block-eid property-id property-value]