diff --git a/deps/db/src/logseq/db/frontend/property.cljs b/deps/db/src/logseq/db/frontend/property.cljs index a1c660d101..b8ac3358ae 100644 --- a/deps/db/src/logseq/db/frontend/property.cljs +++ b/deps/db/src/logseq/db/frontend/property.cljs @@ -290,6 +290,12 @@ :schema {:type :checkbox :hide? true} :queryable? false} + :logseq.property/checkbox-display-properties + {:title "Properties displayed as checkbox" + :schema {:type :property + :cardinality :many + :hide? true} + :queryable? false} ;; Task props :logseq.task/priority {:title "Priority" diff --git a/deps/outliner/src/logseq/outliner/property.cljs b/deps/outliner/src/logseq/outliner/property.cljs index d594f06682..9fc533e84d 100644 --- a/deps/outliner/src/logseq/outliner/property.cljs +++ b/deps/outliner/src/logseq/outliner/property.cljs @@ -420,6 +420,17 @@ (common-util/distinct-by :db/id) (ldb/sort-by-order)))) +(defn ^:api get-block-classes + [db eid] + (let [block (d/entity db eid) + classes (->> (:block/tags block) + (sort-by :block/name) + (filter ldb/class?)) + class-parents (get-classes-parents classes)] + (->> (concat classes class-parents) + (filter (fn [class] + (seq (:logseq.property.class/properties class))))))) + (defn ^:api get-block-classes-properties [db eid] (let [block (d/entity db eid) diff --git a/src/main/frontend/components/property/config.cljs b/src/main/frontend/components/property/config.cljs index c2114f7490..9fc4b2c0c7 100644 --- a/src/main/frontend/components/property/config.cljs +++ b/src/main/frontend/components/property/config.cljs @@ -637,11 +637,26 @@ (when enable-closed-values? (let [values (:property/closed-values property)] (when (>= (count values) 2) - (when-not owner-block - (dropdown-editor-menuitem {:icon :list :title "Display as checkbox" - :desc "Configure" - :submenu-content (fn [] - (checkbox-state-mapping values))}))))) + (if owner-block + (let [checked? (contains? + (set (map :db/id (:logseq.property/checkbox-display-properties owner-block))) + (:db/id property))] + (dropdown-editor-menuitem + {:icon :checkbox :title "Display as checkbox" + :desc (shui/switch + {:id "display as checkbox" :size "sm" + :checked checked? + :on-click util/stop-propagation + :on-checked-change + (fn [value] + (if value + (db-property-handler/set-block-property! (:db/id owner-block) :logseq.property/checkbox-display-properties (:db/id property)) + (db-property-handler/delete-property-value! (:db/id owner-block) :logseq.property/checkbox-display-properties (:db/id property))))})})) + (dropdown-editor-menuitem + {:icon :settings :title "Display as checkbox" + :desc "Configure" + :submenu-content (fn [] + (checkbox-state-mapping values))}))))) (when (and (contains? db-property-type/cardinality-property-types property-type) (not disabled?)) (let [many? (db-property/many? property)] @@ -735,6 +750,7 @@ (assoc state ::values *values)))} [state property* owner-block opts] (let [property (db/sub-block (:db/id property*)) + owner-block (when (:db/id owner-block) (db/sub-block (:db/id owner-block))) values (rum/react (::values state))] (when-not (= :loading values) (dropdown-editor-impl property owner-block values opts)))) diff --git a/src/main/frontend/components/property/value.cljs b/src/main/frontend/components/property/value.cljs index cae4a6bb85..fa89099d07 100644 --- a/src/main/frontend/components/property/value.cljs +++ b/src/main/frontend/components/property/value.cljs @@ -35,7 +35,8 @@ [logseq.shui.ui :as shui] [promesa.core :as p] [rum.core :as rum] - [clojure.set :as set])) + [clojure.set :as set] + [logseq.outliner.property :as outliner-property])) (rum/defc property-empty-btn-value [property & opts] @@ -1040,10 +1041,28 @@ (icon-row block editing?) (if (and select-type?' (not (and (not closed-values?) (= type :date)))) - (single-value-select block property value - (fn [] (select-item property type value opts)) - select-opts - (assoc opts :editing? editing?)) + (let [classes (outliner-property/get-block-classes (db/get-db) (:db/id block)) + display-as-checkbox? (and (some + (fn [block] + (-> (set (map :db/id (:logseq.property/checkbox-display-properties block))) + (contains? (:db/id property)))) + (conj classes block)) + (seq (:property/closed-values property)) + (boolean? (:logseq.property/choice-checkbox-state value*)))] + (if display-as-checkbox? + (let [checked? (:logseq.property/choice-checkbox-state value*)] + (shui/checkbox {:checked checked? + :class "mt-1" + :on-checked-change (fn [value] + (let [choices (:property/closed-values property) + choice (some (fn [choice] (when (= value (:logseq.property/choice-checkbox-state choice)) + choice)) choices)] + (when choice + (db-property-handler/set-block-property! (:db/id block) (:db/ident property) (:db/id choice)))))})) + (single-value-select block property value + (fn [] (select-item property type value opts)) + select-opts + (assoc opts :editing? editing?)))) (case type (:date :datetime) (property-value-date-picker block property value (merge opts {:editing? editing?})) diff --git a/src/main/frontend/worker/db/migrate.cljs b/src/main/frontend/worker/db/migrate.cljs index 5695e5c050..48bda396ca 100644 --- a/src/main/frontend/worker/db/migrate.cljs +++ b/src/main/frontend/worker/db/migrate.cljs @@ -536,7 +536,7 @@ [52 {:fix replace-block-type-with-tags}] [53 {:properties [:logseq.task/scheduled :logseq.task/recur-frequency :logseq.task/recur-unit :logseq.task/repeated?] :fix add-scheduled-to-task}] - [54 {:properties [:logseq.property/choice-checkbox-state]}]]) + [54 {:properties [:logseq.property/choice-checkbox-state :logseq.property/checkbox-display-properties]}]]) (let [max-schema-version (apply max (map first schema-version->updates))] (assert (<= db-schema/version max-schema-version))