From e336db74eb8df2a21b4ca2b37f387bb282615d03 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 4 Jul 2023 10:07:26 +0800 Subject: [PATCH] fix: add-property should replace existing property if it exists --- src/main/frontend/components/editor.cljs | 7 +- src/main/frontend/components/property.cljs | 70 +++++++++++++------ .../frontend/handler/editor/lifecycle.cljs | 7 +- src/main/frontend/handler/property.cljs | 16 ++++- 4 files changed, 72 insertions(+), 28 deletions(-) diff --git a/src/main/frontend/components/editor.cljs b/src/main/frontend/components/editor.cljs index e5d2ed0b11..d85c4e32ab 100644 --- a/src/main/frontend/components/editor.cljs +++ b/src/main/frontend/components/editor.cljs @@ -646,7 +646,7 @@ (mixins/event-mixin setup-key-listener!) (shortcut/mixin :shortcut.handler/block-editing-only) lifecycle/lifecycle - [state {:keys [format block parent-block]} id _config] + [state {:keys [format block parent-block]} id config] (let [content (state/sub-edit-content id) heading-class (get-editor-style-class block content format) opts (cond-> @@ -660,7 +660,10 @@ :auto-focus false :class heading-class} (some? parent-block) - (assoc :parentblockid (str (:block/uuid parent-block))))] + (assoc :parentblockid (str (:block/uuid parent-block))) + + true + (merge (:editor-opts config)))] [:div.editor-inner {:class (if block "block-editor" "non-block-editor")} (ui/ls-textarea opts) diff --git a/src/main/frontend/components/property.cljs b/src/main/frontend/components/property.cljs index a3c2b9c513..a242542f2e 100644 --- a/src/main/frontend/components/property.cljs +++ b/src/main/frontend/components/property.cljs @@ -90,7 +90,8 @@ [*property-key *property-value] (when *property-key (reset! *property-key nil)) (when *property-value (reset! *property-value nil)) - (property-handler/set-editing-new-property! nil)) + (property-handler/set-editing-new-property! nil) + (state/clear-edit!)) (defn- add-property! [block *property-key *property-value] @@ -134,7 +135,8 @@ editor-box editor-args new-item?]}] (let [multiple-values? (= :many (:cardinality (:block/schema property))) - editing? (state/sub [:editor/editing? editor-id])] + editing? (state/sub [:editor/editing? editor-id]) + repo (state/get-current-repo)] (when (or (not new-item?) editing?) (case (:type (:block/schema property)) :date @@ -143,18 +145,39 @@ :checkbox (ui/checkbox {:checked value :on-change (fn [_e] - (let [repo (state/get-current-repo)] - (property-handler/add-property! repo block - (:block/name property) - (boolean (not value))) - (exit-edit-property nil nil)))}) + (property-handler/add-property! repo block + (:block/original-name property) + (boolean (not value))) + (exit-edit-property nil nil))}) ;; :others (if editing? [:div.flex.flex-1 (cond-> {} multiple-values? (assoc :class "property-value-content")) - (editor-box editor-args editor-id {})] + (let [config (if multiple-values? + {:editor-opts + {:on-key-down + (fn [e] + (let [enter? (= (util/ekey e) "Enter")] + (when (contains? #{"Enter" "Escape"} (util/ekey e)) + (util/stop e) + (property-handler/add-property! repo block + (:block/original-name property) + (state/get-edit-content) + :old-value value) + (exit-edit-property nil nil) + + (when enter? + (let [values-count (-> (:block/properties (db/entity (:db/id block))) + (get (:block/uuid property)) + (count)) + editor-id (str "ls-property-" (:db/id property) "-" (:block/uuid property) values-count)] + (set-editing! property editor-id nil ""))))))}} + {})] + (editor-box editor-args editor-id (cond-> config + multiple-values? + (assoc :property-value value))))] [:div.flex.flex-1 (cond-> {:id (or dom-id (random-uuid)) @@ -277,15 +300,18 @@ (rum/defcs multiple-value-item < (rum/local false ::show-close?) [state entity property item {:keys [dom-id editor-id - page-cp inline-text] + page-cp inline-text + new-item?] :as opts}] (let [*show-close? (::show-close? state) object? (= :object (:type (:block/schema property))) - block (when object? (db/pull [:block/uuid item]))] + block (when object? (db/pull [:block/uuid item])) + editing? (state/sub [:editor/editing? editor-id])] [:div.flex.flex-1.flex-row {:on-mouse-over #(reset! *show-close? true) :on-mouse-out #(reset! *show-close? false)} (property-scalar-value entity property item opts) - (when @*show-close? + (when (and (or (not new-item?) editing?) + @*show-close?) [:a.close.fade-in {:title "Delete this value" :on-mouse-down @@ -305,7 +331,6 @@ (get (:block/properties block) k)) dom-id (str "ls-property-" k) editor-id (str "ls-property-" (:db/id property) "-" k) - schema (:block/schema property) multiple-values? (= :many (:cardinality schema)) type (:type schema) @@ -317,21 +342,22 @@ (let [v' (if (coll? v) v (when v [v])) v' (if (seq v') v' [""]) v' (conj v' ::new-value-placeholder) ; new one - editor-id' (str editor-id (count v')) - ] + editor-id' (str editor-id (count v'))] [:div.flex.flex-1.flex-col [:div.flex.flex-1.flex-col (for [[idx item] (medley/indexed v')] (let [dom-id' (str dom-id "-" idx) editor-id' (str editor-id idx)] - (multiple-value-item block property item - {:dom-id dom-id' - :editor-id editor-id' - :editor-box editor-box - :editor-args editor-args - :page-cp page-cp - :inline-text inline-text - :new-item? (= item ::new-value-placeholder)}))) + (rum/with-key + (multiple-value-item block property item + {:dom-id dom-id' + :editor-id editor-id' + :editor-box editor-box + :editor-args editor-args + :page-cp page-cp + :inline-text inline-text + :new-item? (= item ::new-value-placeholder)}) + dom-id'))) (let [fv (first v')] (when (and fv diff --git a/src/main/frontend/handler/editor/lifecycle.cljs b/src/main/frontend/handler/editor/lifecycle.cljs index a39074f4ab..73964588b2 100644 --- a/src/main/frontend/handler/editor/lifecycle.cljs +++ b/src/main/frontend/handler/editor/lifecycle.cljs @@ -48,12 +48,15 @@ ;; Don't trigger auto-save if the latest op is undo or redo (not (contains? #{:undo :redo} (state/get-editor-latest-op)))) (if property? + ;; click outside property value to save it (let [parent-block (when-let [id (d/attr node "parentblockid")] (when (util/uuid-string? id) (db/entity [:block/uuid (uuid id)]))) - property (:block/name block)] + property (:block/name block) + old-value (:property-value (last (state/get-editor-args)))] (when (and parent-block property) - (property-handler/add-property! repo parent-block property value))) + (property-handler/add-property! repo parent-block property value + :old-value old-value))) (editor-handler/save-block! (get-state) value)))) state) diff --git a/src/main/frontend/handler/property.cljs b/src/main/frontend/handler/property.cljs index 64416b1193..1a485db1f0 100644 --- a/src/main/frontend/handler/property.cljs +++ b/src/main/frontend/handler/property.cljs @@ -94,7 +94,7 @@ v-str))) (defn add-property! - [repo block k-name v] + [repo block k-name v & {:keys [old-value]}] (let [property (db/pull repo '[*] [:block/name (gp-util/page-name-sanity-lc k-name)]) v (if property v (or v ""))] (when (some? v) @@ -139,7 +139,19 @@ v' (if (= property-type :default) (if (seq refs) refs v*) v*) - new-value (if multiple-values? (vec (distinct (conj value v'))) v') + new-value (cond + (and multiple-values? old-value + (not= old-value :frontend.components.property/new-value-placeholder)) + (let [v (mapv (fn [x] (if (= x old-value) v' x)) value)] + (if (contains? (set v) v') + v + (conj v v'))) + + multiple-values? + (vec (distinct (conj value v'))) + + :else + v') block-properties (assoc properties property-uuid new-value) block-properties-text-values (if (and (not multiple-values?) (= property-type :default))