Przeglądaj źródła

fix: convert to ref type when updating a property to closed values

Tienson Qin 1 rok temu
rodzic
commit
2195c4b63a

+ 9 - 0
deps/db/src/logseq/db/frontend/property.cljs

@@ -336,3 +336,12 @@
   (let [properties (map :db/ident (:class/schema.properties class-entity))
         ordered (get-in class-entity [:block/schema :properties])]
     (concat ordered (remove (set ordered) properties))))
+
+(defn property-created-block?
+  "`block` has been created in a property and it's not a closed value."
+  [block]
+  (and (map? block)
+       (:logseq.property/created-from-property block)
+       (:block/page block)
+       ;; not closed value
+       (not (some? (get-in block [:block/schema :value])))))

+ 6 - 2
deps/db/src/logseq/db/sqlite/common_db.cljs

@@ -170,8 +170,12 @@
                (when (contains? #{"closed value" "property" "class"} (:v datom))
                  (d/entity db (:e datom)))))
        (mapcat (fn [block]
-                 (cons (d/pull db '[*] (:db/id block))
-                       (property-with-values db block))))))
+                 (concat
+                  (cons (d/pull db '[*] (:db/id block))
+                        (property-with-values db block))
+                  (when (contains? (:block/type block) "closed value")
+                    (let [values (get-in block [:schema :values])]
+                      (d/pull-many db '[*] (map (fn [id] [:block/uuid id]) values)))))))))
 
 (defn get-favorites
   "Favorites page and its blocks"

+ 8 - 4
src/main/frontend/components/property/closed_value.cljs

@@ -115,7 +115,7 @@
         value (db-property/closed-value-name item)
         page? (:block/original-name item)
         date? (= :date (:type (:block/schema property)))
-        property-block? (:logseq.property/created-from-property item)]
+        property-block? (db-property/property-created-block? item)]
     [:div.flex.flex-1.flex-row.items-center.gap-2.justify-between
      {:on-mouse-over #(reset! *hover? true)
       :on-mouse-out #(reset! *hover? false)}
@@ -191,7 +191,7 @@
     (for [value values]
       [:li (if (uuid? value)
              (let [result (db/entity [:block/uuid value])]
-               (if (:logseq.property/created-from-property result)
+               (if (db-property/property-created-block? result)
                  (let [first-child (ldb/get-by-parent-&-left (db/get-db) (:db/id result) (:db/id result))]
                    (:block/content first-child))
                  (:block/original-name result)))
@@ -230,7 +230,12 @@
          :size :sm
          :on-click
          (fn [e]
-           (p/let [values (db-async/<get-block-property-values (state/get-current-repo) (:db/ident property))]
+           (p/let [values (db-async/<get-block-property-values (state/get-current-repo) (:db/ident property))
+                   existing-values (seq (get-in property [:block/schema :values]))
+                   values (if (seq existing-values)
+                            (let [existing-ids (set (map #(:db/id (db/entity [:block/uuid %])) existing-values))]
+                              (remove (fn [[_ id]] (existing-ids id)) values))
+                            values)]
              (shui/popup-show! (.-target e)
                                (fn [{:keys [id]}]
                                  (let [opts {:toggle-fn (fn [] (shui/popup-hide! id))}
@@ -238,7 +243,6 @@
                                                       (map #(:block/uuid (db/entity (second %))) values)
                                                       (map second values))
                                                     (remove string/blank?)
-                                                    (remove (set (get-in property [:block/schema :values])))
                                                     distinct)]
                                    (if (seq values')
                                      (add-existing-values property *property-schema values' opts)

+ 15 - 14
src/main/frontend/components/property/value.cljs

@@ -390,7 +390,7 @@
                     (keep (fn [id]
                             (when-let [block (when id (db/entity [:block/uuid id]))]
                               (let [icon (pu/get-block-property-value block :logseq.property/icon)
-                                    value (if (:logseq.property/created-from-property block)
+                                    value (if (db-property/property-created-block? block)
                                             (let [first-child (ldb/get-by-parent-&-left (db/get-db) (:db/id block) (:db/id block))]
                                               (:block/content first-child))
                                             (db-property/closed-value-name block))]
@@ -415,7 +415,7 @@
             add-property-f #(<add-property! block (:db/ident property) %)
             on-chosen (fn [chosen]
                         (p/do!
-                         (add-property-f (if (map? chosen) (:value chosen) chosen))
+                          (add-property-f (if (map? chosen) (:value chosen) chosen))
                          (when-let [f (:on-chosen select-opts)] (f))))
             selected-choices' (get block (:db/ident property))
             selected-choices (if (coll? selected-choices')
@@ -457,11 +457,11 @@
 
 (rum/defc property-normal-block-value < rum/reactive db-mixins/query
   {:init (fn [state]
-           (let [block-id (:block/uuid (first (:rum/args state)))]
+           (when-let [block-id (:block/uuid (first (:rum/args state)))]
              (db-async/<get-block (state/get-current-repo) block-id :children? true))
            state)}
   [parent block-cp editor-box]
-  (if (state/sub-async-query-loading (:block/uuid parent))
+  (if (and (:block/uuid parent) (state/sub-async-query-loading (:block/uuid parent)))
     [:div.text-sm.opacity-70 "loading"]
     (let [children (model/sort-by-left
                     (:block/_parent (db/entity (:db/id parent)))
@@ -474,7 +474,7 @@
 
 (rum/defc property-template-value < rum/reactive
   {:init (fn [state]
-           (let [block-id (second (:rum/args state))]
+           (when-let [block-id (second (:rum/args state))]
              (db-async/<get-block (state/get-current-repo) block-id :children? false))
            state)}
   [config value opts]
@@ -496,7 +496,7 @@
 (rum/defcs property-block-value < rum/reactive
   (rum/local nil ::template-instance)
   {:init (fn [state]
-           (let [block-id (:block/uuid (first (:rum/args state)))]
+           (when-let [block-id (:block/uuid (first (:rum/args state)))]
              (db-async/<get-block (state/get-current-repo) block-id :children? true))
            state)}
   [state value block property block-cp editor-box opts page-cp editor-id]
@@ -537,7 +537,7 @@
   (when value
     (let [eid (if (de/entity? value) (:db/id value) [:block/uuid value])]
       (when-let [block (db/sub-block (:db/id (db/entity eid)))]
-        (let [property-block? (:logseq.property/created-from-property block)
+        (let [property-block? (db-property/property-created-block? block)
               value' (get-in block [:block/schema :value])
               icon (pu/get-block-property-value block :logseq.property/icon)]
           (cond
@@ -566,8 +566,12 @@
 
 (rum/defc select-item
   [property type value {:keys [page-cp inline-text _icon?] :as opts}]
-  (let [closed-values? (seq (get-in property [:block/schema :values]))]
-    [:div.select-item.w-full
+  (let [closed-values? (seq (get-in property [:block/schema :values]))
+        property-block? (db-property/property-created-block? value)]
+    [:div.select-item
+     (cond-> {}
+       property-block?
+       (assoc :class "w-full"))
      (cond
        (= value :logseq.property/empty-placeholder)
        (property-empty-value)
@@ -590,8 +594,7 @@
 
 (rum/defc single-value-select
   [block property value value-f select-opts {:keys [editing?] :as opts}]
-  (let [[hover? set-hover!] (rum/use-state false)
-        [open? set-open!] (rum/use-state editing?)
+  (let [[open? set-open!] (rum/use-state editing?)
         schema (:block/schema property)
         type (get schema :type :default)
         select-opts' (cond-> (assoc select-opts
@@ -599,10 +602,8 @@
                                     :on-chosen #(set-open! false))
                        (= type :page)
                        (assoc :classes (:classes schema)))
-        property-block? (:logseq.property/created-from-property value)]
+        property-block? (db-property/property-created-block? value)]
     [:div.flex.flex-1.flex-row
-     {:on-mouse-over #(set-hover! true)
-      :on-mouse-out #(set-hover! false)}
      (when property-block?
        [:div.flex.flex-1 (value-f)])
      (shui/dropdown-menu

+ 18 - 12
src/main/frontend/handler/db_based/property.cljs

@@ -110,10 +110,11 @@
       (if (util/uuid-string? v-str) (uuid v-str) v-str))))
 
 (defn- update-datascript-schema
-  [property {:keys [type cardinality]}]
+  [property {:keys [type cardinality values]}]
   (let [ident (:db/ident property)
         cardinality (if (= cardinality :many) :db.cardinality/many :db.cardinality/one)
-        type-data (when (and type (db-property-type/ref-property-types type)) ; type changes
+        type-data (when (and type (or (db-property-type/ref-property-types type)
+                                      (seq values))) ; type changes or closed values
                     {:db/ident ident
                      :db/valueType :db.type/ref
                      :db/cardinality cardinality})]
@@ -165,7 +166,8 @@
                      (merge {:db/ident db-ident} changed-property-attrs)))
               (or (not= (:type schema) (get-in property [:block/schema :type]))
                   (not= (:cardinality schema) (get-in property [:block/schema :cardinality]))
-                  (and (= :default (:type schema)) (not= :db.type/ref (:db/valueType property))))
+                  (and (= :default (:type schema)) (not= :db.type/ref (:db/valueType property)))
+                  (seq (:values schema)))
               (conj (update-datascript-schema property schema)))
             tx-data (concat property-tx-data
                             (when (seq properties)
@@ -705,7 +707,9 @@
       (if (every? uuid? values')
         (p/let [new-value-ids (vec (remove #(nil? (db/entity [:block/uuid %])) values'))]
           (when (seq new-value-ids)
-            (let [property-tx {:db/id (:db/id property)
+            (let [property-tx {:db/ident (:db/ident property)
+                               :db/valueType :db.type/ref
+                               :db/cardinality :db.cardinality/one
                                :block/schema (assoc property-schema :values new-value-ids)}]
               (db/transact! (state/get-current-repo) [property-tx]
                             {:outliner-op :insert-blocks})
@@ -726,7 +730,9 @@
                                  (map #(get-in % [:block/schema :value]) closed-value-blocks)
                                  (map :block/uuid closed-value-blocks))
                 new-value-ids (mapv :block/uuid closed-value-blocks)
-                property-tx {:db/id (:db/id property)
+                property-tx {:db/ident (:db/ident property)
+                             :db/valueType :db.type/ref
+                             :db/cardinality :db.cardinality/one
                              :block/schema (assoc property-schema :values new-value-ids)}
                 property-values (db-async/<get-block-property-values (state/get-current-repo) (:db/ident property))
                 block-values (->> property-values
@@ -735,13 +741,13 @@
                          (when page-tx [page-tx])
                          closed-value-blocks
                          [property-tx]
-                         (mapcat (fn [[id value]]
-                                   [[:db/retract id property-id]
-                                    {:db/id id
-                                     property-id (if (set? value)
-                                                   (set (map value->block-id value))
-                                                   (get value->block-id value))}])
-                                 (filter second block-values)))]
+                         (map (fn [[id value]]
+                                (let [value' (if (set? value)
+                                               (set (map #(vector :block/uuid (value->block-id %)) value))
+                                               [:block/uuid (value->block-id value)])]
+                                  {:db/id id
+                                   property-id value'}))
+                              (filter second block-values)))]
           (db/transact! (state/get-current-repo) tx-data
                         {:outliner-op :insert-blocks})
           new-value-ids)))))