From 631f481de5fb9ab7286ecde2f7bfb851a68e524b Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Thu, 7 Mar 2024 16:18:54 -0500 Subject: [PATCH] enhance: mark built-in closed values and disallow their deletion. Also fix a bug where used/undeleted closed values could still be deleted because ui state was incorrectly updated. Part of LOG-3048 --- deps/db/src/logseq/db/frontend/default.cljs | 11 +++++++++-- .../src/logseq/db/frontend/property/util.cljs | 5 +++++ deps/db/src/logseq/db/sqlite/create_graph.cljs | 11 +++-------- .../components/property/closed_value.cljs | 6 +++--- .../frontend/handler/db_based/property.cljs | 18 ++++++++++++++---- .../db_based/property_closed_value_test.cljs | 2 +- 6 files changed, 35 insertions(+), 18 deletions(-) diff --git a/deps/db/src/logseq/db/frontend/default.cljs b/deps/db/src/logseq/db/frontend/default.cljs index 03553c754..bff3abce6 100644 --- a/deps/db/src/logseq/db/frontend/default.cljs +++ b/deps/db/src/logseq/db/frontend/default.cljs @@ -1,7 +1,8 @@ (ns logseq.db.frontend.default - "Provides fns for seeding default data in a logseq db" + "Provides vars and fns for dealing with default/built-in? data" (:require [clojure.string :as string] - [clojure.set :as set])) + [clojure.set :as set] + [datascript.core :as d])) (defonce built-in-markers ["NOW" "LATER" "DOING" "DONE" "CANCELED" "CANCELLED" "IN-PROGRESS" "TODO" "WAIT" "WAITING"]) @@ -24,3 +25,9 @@ (def built-in-pages (mapv page-title->block built-in-pages-names)) + +(defn mark-block-as-built-in + "Marks built-in blocks as built-in? including pages, classes, properties and closed values" + [db block] + (let [built-in-property-id (:block/uuid (d/entity db :built-in?))] + (update block :block/properties assoc built-in-property-id true))) diff --git a/deps/db/src/logseq/db/frontend/property/util.cljs b/deps/db/src/logseq/db/frontend/property/util.cljs index 798c2660d..9d917b447 100644 --- a/deps/db/src/logseq/db/frontend/property/util.cljs +++ b/deps/db/src/logseq/db/frontend/property/util.cljs @@ -2,6 +2,7 @@ "Util fns for building core property concepts" (:require [logseq.db.sqlite.util :as sqlite-util] [logseq.common.util :as common-util] + [logseq.db.frontend.default :as default-db] [datascript.core :as d])) (defonce hidden-page-name-prefix "$$$") @@ -27,6 +28,10 @@ icon (assoc :block/properties {icon-id icon}) + ;; For now, only closed values with :db/ident are built-in? + (and db-ident (keyword? db-ident)) + ((fn [b] (default-db/mark-block-as-built-in db b))) + description (update :block/schema assoc :description description) diff --git a/deps/db/src/logseq/db/sqlite/create_graph.cljs b/deps/db/src/logseq/db/sqlite/create_graph.cljs index 7dc572803..e462c3c47 100644 --- a/deps/db/src/logseq/db/sqlite/create_graph.cljs +++ b/deps/db/src/logseq/db/sqlite/create_graph.cljs @@ -10,11 +10,6 @@ [logseq.db :as ldb] [logseq.db.frontend.default :as default-db])) -(defn- mark-block-as-built-in - [db block] - (let [built-in-property-id (:block/uuid (d/entity db :built-in?))] - (update block :block/properties assoc built-in-property-id true))) - (defn- build-initial-properties [db] (let [;; Some uuids need to be pre-defined since they are referenced by other properties @@ -45,7 +40,7 @@ schema (get default-property-uuids k-keyword id) {:db-ident db-ident})])] - (update blocks 0 #(mark-block-as-built-in db %)))) + (update blocks 0 #(default-db/mark-block-as-built-in db %)))) built-in-properties))) (defn build-db-initial-data @@ -70,7 +65,7 @@ :file/content "" :file/last-modified-at (js/Date.)}] default-pages (->> (ldb/build-pages-tx (map default-db/page-title->block ["Contents"])) - (map #(mark-block-as-built-in db %))) + (map #(default-db/mark-block-as-built-in db %))) default-properties (build-initial-properties db) name->properties (zipmap (map :block/name default-properties) @@ -78,7 +73,7 @@ default-classes (map (fn [[k-keyword {:keys [schema original-name]}]] (let [k-name (name k-keyword)] - (mark-block-as-built-in + (default-db/mark-block-as-built-in db (sqlite-util/build-new-class (let [properties (mapv diff --git a/src/main/frontend/components/property/closed_value.cljs b/src/main/frontend/components/property/closed_value.cljs index 25f378203..82c0dc416 100644 --- a/src/main/frontend/components/property/closed_value.cljs +++ b/src/main/frontend/components/property/closed_value.cljs @@ -153,9 +153,9 @@ (assoc opts :delete-choice (fn [] - (p/do! - (db-property-handler/delete-closed-value! property block) - (swap! *property-schema update :values (fn [vs] (vec (remove #(= uuid %) vs)))))) + (p/let [success? (db-property-handler/delete-closed-value! (db/get-db) property block)] + (when success? + (swap! *property-schema update :values (fn [vs] (vec (remove #(= uuid %) vs))))))) :update-icon (fn [icon] (property-handler/set-block-property! (state/get-current-repo) (:block/uuid block) :icon icon))) diff --git a/src/main/frontend/handler/db_based/property.cljs b/src/main/frontend/handler/db_based/property.cljs index c71b536d6..a3ee4f1d4 100644 --- a/src/main/frontend/handler/db_based/property.cljs +++ b/src/main/frontend/handler/db_based/property.cljs @@ -801,9 +801,18 @@ new-value-ids))) (defn delete-closed-value! - [property value-block] - (if (seq (:block/_refs value-block)) - (notification/show! "The choice can't be deleted because it's still used." :warning) + "Returns true when deleted or if not deleted displays warning and returns false" + [db property value-block] + (cond + (ldb/built-in? db value-block) + (do (notification/show! "The choice can't be deleted because it's built-in." :warning) + false) + + (seq (:block/_refs value-block)) + (do (notification/show! "The choice can't be deleted because it's still used." :warning) + false) + + :else (let [property (db/entity (:db/id property)) schema (:block/schema property) tx-data [[:db/retractEntity (:db/id value-block)] @@ -813,7 +822,8 @@ (vec (remove #{(:block/uuid value-block)} values))))}]] (p/do! (db/transact! tx-data) - (re-init-commands! property))))) + (re-init-commands! property) + true)))) (defn get-property-block-created-block "Get the root block and property that created this property block." diff --git a/src/test/frontend/handler/db_based/property_closed_value_test.cljs b/src/test/frontend/handler/db_based/property_closed_value_test.cljs index ce481ba70..a7c085085 100644 --- a/src/test/frontend/handler/db_based/property_closed_value_test.cljs +++ b/src/test/frontend/handler/db_based/property_closed_value_test.cljs @@ -82,6 +82,6 @@ (is (contains? (:block/type b) "closed value"))))) (testing "Delete closed value" - (db-property-handler/delete-closed-value! property (db/entity [:block/uuid block-id])) + (db-property-handler/delete-closed-value! (db/get-db) property (db/entity [:block/uuid block-id])) (is (nil? (db/entity [:block/uuid block-id]))) (is (= 2 (count (:values (:block/schema (db/entity [:block/name k])))))))))))))