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
pull/11102/head
Gabriel Horner 2024-03-07 16:18:54 -05:00
parent a61e0d8e0e
commit 631f481de5
6 changed files with 35 additions and 18 deletions

View File

@ -1,7 +1,8 @@
(ns logseq.db.frontend.default (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] (:require [clojure.string :as string]
[clojure.set :as set])) [clojure.set :as set]
[datascript.core :as d]))
(defonce built-in-markers (defonce built-in-markers
["NOW" "LATER" "DOING" "DONE" "CANCELED" "CANCELLED" "IN-PROGRESS" "TODO" "WAIT" "WAITING"]) ["NOW" "LATER" "DOING" "DONE" "CANCELED" "CANCELLED" "IN-PROGRESS" "TODO" "WAIT" "WAITING"])
@ -24,3 +25,9 @@
(def built-in-pages (def built-in-pages
(mapv page-title->block built-in-pages-names)) (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)))

View File

@ -2,6 +2,7 @@
"Util fns for building core property concepts" "Util fns for building core property concepts"
(:require [logseq.db.sqlite.util :as sqlite-util] (:require [logseq.db.sqlite.util :as sqlite-util]
[logseq.common.util :as common-util] [logseq.common.util :as common-util]
[logseq.db.frontend.default :as default-db]
[datascript.core :as d])) [datascript.core :as d]))
(defonce hidden-page-name-prefix "$$$") (defonce hidden-page-name-prefix "$$$")
@ -27,6 +28,10 @@
icon icon
(assoc :block/properties {icon-id 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 description
(update :block/schema assoc :description description) (update :block/schema assoc :description description)

View File

@ -10,11 +10,6 @@
[logseq.db :as ldb] [logseq.db :as ldb]
[logseq.db.frontend.default :as default-db])) [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 (defn- build-initial-properties
[db] [db]
(let [;; Some uuids need to be pre-defined since they are referenced by other properties (let [;; Some uuids need to be pre-defined since they are referenced by other properties
@ -45,7 +40,7 @@
schema schema
(get default-property-uuids k-keyword id) (get default-property-uuids k-keyword id)
{:db-ident db-ident})])] {: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))) built-in-properties)))
(defn build-db-initial-data (defn build-db-initial-data
@ -70,7 +65,7 @@
:file/content "" :file/content ""
:file/last-modified-at (js/Date.)}] :file/last-modified-at (js/Date.)}]
default-pages (->> (ldb/build-pages-tx (map default-db/page-title->block ["Contents"])) 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) default-properties (build-initial-properties db)
name->properties (zipmap name->properties (zipmap
(map :block/name default-properties) (map :block/name default-properties)
@ -78,7 +73,7 @@
default-classes (map default-classes (map
(fn [[k-keyword {:keys [schema original-name]}]] (fn [[k-keyword {:keys [schema original-name]}]]
(let [k-name (name k-keyword)] (let [k-name (name k-keyword)]
(mark-block-as-built-in (default-db/mark-block-as-built-in
db db
(sqlite-util/build-new-class (sqlite-util/build-new-class
(let [properties (mapv (let [properties (mapv

View File

@ -153,9 +153,9 @@
(assoc opts (assoc opts
:delete-choice :delete-choice
(fn [] (fn []
(p/do! (p/let [success? (db-property-handler/delete-closed-value! (db/get-db) property block)]
(db-property-handler/delete-closed-value! property block) (when success?
(swap! *property-schema update :values (fn [vs] (vec (remove #(= uuid %) vs)))))) (swap! *property-schema update :values (fn [vs] (vec (remove #(= uuid %) vs)))))))
:update-icon :update-icon
(fn [icon] (fn [icon]
(property-handler/set-block-property! (state/get-current-repo) (:block/uuid block) :icon icon))) (property-handler/set-block-property! (state/get-current-repo) (:block/uuid block) :icon icon)))

View File

@ -801,9 +801,18 @@
new-value-ids))) new-value-ids)))
(defn delete-closed-value! (defn delete-closed-value!
[property value-block] "Returns true when deleted or if not deleted displays warning and returns false"
(if (seq (:block/_refs value-block)) [db property value-block]
(notification/show! "The choice can't be deleted because it's still used." :warning) (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)) (let [property (db/entity (:db/id property))
schema (:block/schema property) schema (:block/schema property)
tx-data [[:db/retractEntity (:db/id value-block)] tx-data [[:db/retractEntity (:db/id value-block)]
@ -813,7 +822,8 @@
(vec (remove #{(:block/uuid value-block)} values))))}]] (vec (remove #{(:block/uuid value-block)} values))))}]]
(p/do! (p/do!
(db/transact! tx-data) (db/transact! tx-data)
(re-init-commands! property))))) (re-init-commands! property)
true))))
(defn get-property-block-created-block (defn get-property-block-created-block
"Get the root block and property that created this property block." "Get the root block and property that created this property block."

View File

@ -82,6 +82,6 @@
(is (contains? (:block/type b) "closed value"))))) (is (contains? (:block/type b) "closed value")))))
(testing "Delete 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 (nil? (db/entity [:block/uuid block-id])))
(is (= 2 (count (:values (:block/schema (db/entity [:block/name k]))))))))))))) (is (= 2 (count (:values (:block/schema (db/entity [:block/name k])))))))))))))