fix: multiple fixes for property validation

- couldn't use :default block property values
- couldn't add new closed number value
- couldn't select existing :page or :date closed values
- editor/CLI validation wasn't working - see failing db-graph-test job
- update schema for closed-value
Part of LOG-2871. Also fixed typo in ui.cljs
pull/10507/head
Gabriel Horner 2023-11-15 14:51:30 -05:00
parent 443eb3f2b8
commit b359694c4b
6 changed files with 35 additions and 19 deletions

View File

@ -6,5 +6,7 @@ logseq.db.frontend.rules/query-dsl-rules
logseq.db.frontend.rules/db-query-dsl-rules
;; API
logseq.db.frontend.rules/extract-rules
;; API
logseq.db.frontend.property.type/type-or-closed-value?
;; Internal API
logseq.db.frontend.rules/rules

View File

@ -128,7 +128,7 @@
(def property-schema-attrs
[[:hide? {:optional true} :boolean]
[:description {:optional true} :string]
;; For any types except for :checkbox :default :template :enum
;; For any types except for :checkbox :default :template
[:cardinality {:optional true} [:enum :one :many]]
;; For closed values
[:values {:optional true} [:vector :uuid]]
@ -232,8 +232,8 @@
[:block/page :int]]
page-or-block-attrs)))
(def enum-block
"An enum value for enum property"
(def closed-value-block
"A closed value for a property with closed/allowed values"
(vec
(concat
[:map]
@ -245,7 +245,7 @@
[:block/metadata
[:map
[:created-from-property :uuid]]]]
(remove #(#{:block/metadata :block/content} (first %)) block-attrs)
(remove #(#{:block/metadata :block/content :block/left} (first %)) block-attrs)
page-or-block-attrs)))
(def normal-block
@ -261,7 +261,7 @@
[:or
normal-block
object-block
enum-block
closed-value-block
whiteboard-block])
;; TODO: invalid macros should not generate unknown

View File

@ -43,7 +43,8 @@
(and (uuid? id)
(some? (d/entity db [:block/uuid id]))))
(defn- exist-closed-value?
(defn- existing-closed-value-valid?
"Validates that the given existing closed value is valid"
[db property type-validate-fn value]
(boolean
(when-let [e (and (uuid? value)
@ -51,8 +52,10 @@
(let [values (get-in property [:block/schema :values])]
(and
(contains? (set values) value)
(contains? (:block/type e) "closed value")
(type-validate-fn (:value (:block/schema e))))))))
(if (contains? (:block/type e) "closed value")
(type-validate-fn (:value (:block/schema e)))
;; page uuids aren't closed value types
(type-validate-fn value)))))))
(defn type-or-closed-value?
"The `value` could be either a closed value (when `property` has pre-defined values) or it can be validated by `type-validate-fn`.
@ -62,26 +65,28 @@
(fn [db property value new-closed-value?]
(if (and (seq (get-in property [:block/schema :values]))
(not new-closed-value?))
(exist-closed-value? db property type-validate-fn value)
(existing-closed-value-valid? db property type-validate-fn value)
(type-validate-fn value))))
(def builtin-schema-types
{:default [:fn
{:error/message "should be a text"}
(type-or-closed-value? string?)] ; refs/tags will not be extracted
;; uuid check needed for property block values
(some-fn string? uuid?)] ; refs/tags will not be extracted
:number [:fn
{:error/message "should be a number"}
(type-or-closed-value? number?)]
;; TODO: Remove uuid? for :number and :url when type-or-closed-value? is used in this ns
(some-fn number? uuid?)]
:date [:fn
{:error/message "should be a journal date"}
(type-or-closed-value? logseq-page?)]
logseq-page?]
:checkbox boolean?
:url [:fn
{:error/message "should be a URL"}
(type-or-closed-value? url?)]
(some-fn url? uuid?)]
:page [:fn
{:error/message "should be a page"}
(type-or-closed-value? logseq-page?)]
logseq-page?]
:template [:fn
{:error/message "should has #template"}
logseq-template?]
@ -94,7 +99,7 @@
(def property-types-with-db
"Property types whose validation fn requires a datascript db"
#{:default :number :date :url :page :template})
#{:date :page :template})
(assert (= (set (keys builtin-schema-types))
(into internal-builtin-schema-types

View File

@ -25,9 +25,17 @@
:or {new-closed-value? false}}]
(into {}
(map (fn [[property-type property-val-schema]]
(if (db-property-type/property-types-with-db property-type)
(cond
(db-property-type/closed-values-schema-types property-type)
(let [[_ schema-opts schema-fn] property-val-schema
schema-fn' (if (db-property-type/property-types-with-db property-type) #(schema-fn (db/get-db) %) schema-fn)]
[property-type [:fn
schema-opts
#((db-property-type/type-or-closed-value? schema-fn') (db/get-db) property % new-closed-value?)]])
(db-property-type/property-types-with-db property-type)
(let [[_ schema-opts schema-fn] property-val-schema]
[property-type [:fn schema-opts #(schema-fn (db/get-db) property % new-closed-value?)]])
[property-type [:fn schema-opts #(schema-fn (db/get-db) %)]])
:else
[property-type property-val-schema]))
db-property-type/builtin-schema-types)))

View File

@ -260,7 +260,7 @@
value-block (when (uuid? value) (db/entity [:block/uuid value]))
validate-message (db-property-handler/validate-property-value
(get (db-property-handler/builtin-schema-types property {:new-closed-value? true}) property-type)
value)]
resolved-value)]
(cond
(nil? resolved-value)
nil
@ -310,6 +310,7 @@
metadata {:created-from-property (:block/uuid property)}
new-block (cond->
{:block/type #{"closed value"}
:block/format :markdown
:block/uuid block-id
:block/page page-id
:block/metadata metadata

View File

@ -1038,7 +1038,7 @@
:icon-props icon-props
:button-props (merge
(dissoc option
:background :href :class :intent :small? :large? :icon :icon-props :disabled? button-props)
:background :href :class :intent :small? :large? :icon :icon-props :disabled? :button-props)
button-props)
:class (if (= intent "border-link") (str class " border") class)
:muted disabled?