mirror of
https://github.com/logseq/logseq.git
synced 2026-04-29 00:24:51 +00:00
Replace enum type with available choices (#10438)
* Add type schema for enum values * Refactor: closed values instead of enum to limit values There's no need to add the enum type, we just want to limit the values. * feat: :page type supports closed values * fix: can't set property values for text/number types * fix: don't trigger on-chosen when unmounting any select component * fix: can't apply both page classes limitation and closed values * fix: merge conflicts * fix: ui not refresh when changing closed value * fix: can't set icon for closed value
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
[frontend.handler.file-based.property :as file-property-handler]
|
||||
[frontend.handler.file-based.page-property :as file-page-property]
|
||||
[frontend.handler.notification :as notification]
|
||||
[logseq.db.frontend.property.type :as db-property-type]
|
||||
[frontend.config :as config]
|
||||
[frontend.util :as util]
|
||||
[frontend.state :as state]
|
||||
@@ -150,21 +151,20 @@
|
||||
:all-classes all-classes ; block own classes + parent classes
|
||||
:classes-properties all-properties}))
|
||||
|
||||
(defn enum-other-position?
|
||||
(defn closed-value-other-position?
|
||||
[property-id block-properties]
|
||||
(and
|
||||
(some? (get block-properties property-id))
|
||||
(let [schema (:block/schema (db/entity [:block/uuid property-id]))]
|
||||
(and (= :enum (:type schema))
|
||||
(= (:position schema) "block-beginning")))))
|
||||
(= (:position schema) "block-beginning"))))
|
||||
|
||||
(defn get-block-enum-other-position-properties
|
||||
(defn get-block-other-position-properties
|
||||
[eid]
|
||||
(let [block (db/entity eid)
|
||||
own-properties (keys (:block/properties block))]
|
||||
(->> (:classes-properties (get-block-classes-properties eid))
|
||||
(concat own-properties)
|
||||
(filter (fn [id] (enum-other-position? id (:block/properties block))))
|
||||
(filter (fn [id] (closed-value-other-position? id (:block/properties block))))
|
||||
(distinct))))
|
||||
|
||||
(defn block-has-viewable-properties?
|
||||
@@ -240,27 +240,50 @@
|
||||
{:page page-tx
|
||||
:blocks [new-block]}))
|
||||
|
||||
(defn upsert-enum-item
|
||||
[property {:keys [id name icon description]}]
|
||||
(when (= :enum (get-in property [:block/schema :type]))
|
||||
(let [icon-id (pu/get-pid "icon")
|
||||
name (string/trim name)
|
||||
(defn upsert-closed-value
|
||||
"id should be a block UUID or nil"
|
||||
[property {:keys [id value icon description]}]
|
||||
(assert (or (nil? id) (uuid? id)))
|
||||
(when (contains? db-property-type/closed-values-schema-types (get-in property [:block/schema :type] :default))
|
||||
(let [value (if (string? value) (string/trim value) value)
|
||||
property-schema (:block/schema property)
|
||||
enum-values (get-in property-schema [:enum-config :values])
|
||||
block-values (map (fn [id] (db/entity [:block/uuid id])) enum-values)
|
||||
icon (when-not (and (string? icon) (string/blank? icon)) icon)
|
||||
description (string/trim description)
|
||||
description (when-not (string/blank? description) description)]
|
||||
(if (some (fn [b] (and (= name (:block/content b))
|
||||
(not= id (:block/uuid b)))) block-values)
|
||||
(notification/show! "Choice exists already." :warning)
|
||||
(let [block (when id (db/entity [:block/uuid id]))
|
||||
block-id (or id (db/new-block-id))
|
||||
closed-values (:values property-schema)
|
||||
block-values (map (fn [id] (db/entity [:block/uuid id])) closed-values)
|
||||
resolved-value (try
|
||||
(db-property-handler/convert-property-input-string (:type property-schema) value)
|
||||
(catch :default e
|
||||
(js/console.error e)
|
||||
(notification/show! (str e) :error false)
|
||||
nil))
|
||||
block (when id (db/entity [:block/uuid id]))
|
||||
value-block (when (uuid? value) (db/entity [:block/uuid value]))]
|
||||
(cond
|
||||
(nil? resolved-value)
|
||||
nil
|
||||
|
||||
(some (fn [b] (and (= resolved-value (get-in b [:block/metadata :value]))
|
||||
(not= id (:block/uuid b)))) block-values)
|
||||
(do
|
||||
(notification/show! "Choice already exists" :warning)
|
||||
:value-exists)
|
||||
|
||||
(:block/name value-block) ; page
|
||||
(let [new-values (vec (conj closed-values value))]
|
||||
{:block-id value
|
||||
:tx-data [{:db/id (:db/id property)
|
||||
:block/schema (assoc property-schema :values new-values)}]})
|
||||
|
||||
:else
|
||||
(let [block-id (or id (db/new-block-id))
|
||||
icon-id (pu/get-pid "icon")
|
||||
icon (when-not (and (string? icon) (string/blank? icon)) icon)
|
||||
description (string/trim description)
|
||||
description (when-not (string/blank? description) description)
|
||||
tx-data (if block
|
||||
[(let [properties (:block/properties block)
|
||||
schema (:block/schema block)]
|
||||
schema (assoc (:block/schema block)
|
||||
:value resolved-value)]
|
||||
{:block/uuid id
|
||||
:block/content name
|
||||
:block/properties (if icon
|
||||
(assoc properties icon-id icon)
|
||||
(dissoc properties icon-id))
|
||||
@@ -277,12 +300,11 @@
|
||||
page-id [:block/uuid (:block/uuid page)]
|
||||
metadata {:created-from-property (:block/uuid property)}
|
||||
new-block (cond->
|
||||
{:block/type #{"enum value"}
|
||||
{:block/type #{"closed value"}
|
||||
:block/uuid block-id
|
||||
:block/format :markdown
|
||||
:block/content name
|
||||
:block/page page-id
|
||||
:block/metadata metadata
|
||||
:block/schema {:value resolved-value}
|
||||
:block/parent page-id
|
||||
:block/left (or (when page-entity (model/get-block-last-direct-child (db/get-db) (:db/id page-entity)))
|
||||
page-id)}
|
||||
@@ -290,28 +312,28 @@
|
||||
(assoc :block/properties {icon-id icon})
|
||||
|
||||
description
|
||||
(assoc :block/schema {:description description})
|
||||
(update :block/schema assoc :description description)
|
||||
|
||||
true
|
||||
outliner-core/block-with-timestamps)
|
||||
new-values (vec (conj enum-values block-id))]
|
||||
new-values (vec (conj closed-values block-id))]
|
||||
(->> (cons page-tx [new-block
|
||||
{:db/id (:db/id property)
|
||||
:block/schema (assoc property-schema :enum-config {:values new-values})}])
|
||||
:block/schema (assoc property-schema :values new-values)}])
|
||||
(remove nil?))))]
|
||||
{:block-id block-id
|
||||
:tx-data tx-data})))))
|
||||
|
||||
(defn delete-enum-item
|
||||
(defn delete-closed-value
|
||||
[property item]
|
||||
(if (seq (:block/_refs item))
|
||||
(notification/show! "The choice can't be deleted because it's still used." :warning)
|
||||
(let [schema (:block/schema property)
|
||||
tx-data [[:db/retractEntity (:db/id item)]
|
||||
{:db/id (:db/id property)
|
||||
:block/schema (update-in schema [:enum-config :values]
|
||||
(fn [values]
|
||||
(vec (remove #{(:block/uuid item)} values))))}]]
|
||||
:block/schema (update schema :values
|
||||
(fn [values]
|
||||
(vec (remove #{(:block/uuid item)} values))))}]]
|
||||
(db/transact! tx-data))))
|
||||
|
||||
(defn get-property-block-created-block
|
||||
|
||||
Reference in New Issue
Block a user