diff --git a/deps/db/.carve/ignore b/deps/db/.carve/ignore index 658b35e76d..953cfea20b 100644 --- a/deps/db/.carve/ignore +++ b/deps/db/.carve/ignore @@ -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 diff --git a/deps/db/src/logseq/db/frontend/malli_schema.cljs b/deps/db/src/logseq/db/frontend/malli_schema.cljs index b00b898a8f..80d647dcbe 100644 --- a/deps/db/src/logseq/db/frontend/malli_schema.cljs +++ b/deps/db/src/logseq/db/frontend/malli_schema.cljs @@ -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 diff --git a/deps/db/src/logseq/db/frontend/property/type.cljs b/deps/db/src/logseq/db/frontend/property/type.cljs index 18163b765c..44490d3905 100644 --- a/deps/db/src/logseq/db/frontend/property/type.cljs +++ b/deps/db/src/logseq/db/frontend/property/type.cljs @@ -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 diff --git a/src/main/frontend/handler/db_based/property.cljs b/src/main/frontend/handler/db_based/property.cljs index 97d4bbbc66..0e912885be 100644 --- a/src/main/frontend/handler/db_based/property.cljs +++ b/src/main/frontend/handler/db_based/property.cljs @@ -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))) diff --git a/src/main/frontend/handler/property.cljs b/src/main/frontend/handler/property.cljs index ebf5cf867c..d3896a0b8f 100644 --- a/src/main/frontend/handler/property.cljs +++ b/src/main/frontend/handler/property.cljs @@ -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 diff --git a/src/main/frontend/ui.cljs b/src/main/frontend/ui.cljs index 6ed9b59354..40520e047d 100644 --- a/src/main/frontend/ui.cljs +++ b/src/main/frontend/ui.cljs @@ -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?