From 7f4d8ad22bfb9b6b3fd04289602bb4f64cc4f19b Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Thu, 6 Nov 2025 12:20:37 +0800 Subject: [PATCH] add tag-add-property && tag-remove-property --- src/main/logseq/api.cljs | 2 + src/main/logseq/api/db_based.cljs | 139 ++++++++++++++---------------- 2 files changed, 68 insertions(+), 73 deletions(-) diff --git a/src/main/logseq/api.cljs b/src/main/logseq/api.cljs index 31cb1fda7c..6afebe2b3e 100644 --- a/src/main/logseq/api.cljs +++ b/src/main/logseq/api.cljs @@ -203,6 +203,8 @@ (def ^:export create_tag db-based-api/create-tag) (def ^:export add_block_tag db-based-api/add-block-tag) (def ^:export remove_block_tag db-based-api/remove-block-tag) +(def ^:export tag-add-property db-based-api/tag-add-property) +(def ^:export tag-remove-property db-based-api/tag-remove-property) ;; Internal db-based CLI APIs (def ^:export list_tags cli-based-api/list-tags) diff --git a/src/main/logseq/api/db_based.cljs b/src/main/logseq/api/db_based.cljs index 88829606ef..e6c0e6eac2 100644 --- a/src/main/logseq/api/db_based.cljs +++ b/src/main/logseq/api/db_based.cljs @@ -5,17 +5,15 @@ [clojure.string :as string] [clojure.walk :as walk] [datascript.core :as d] - [frontend.components.property.value :as pv] [frontend.db :as db] + [frontend.db.async :as db-async] [frontend.db.model :as db-model] [frontend.handler.common.page :as page-common-handler] - [logseq.db.frontend.property :as db-property] + [frontend.handler.db-based.page :as db-page-handler] [frontend.handler.db-based.property :as db-property-handler] [frontend.handler.editor :as editor-handler] [frontend.handler.page :as page-handler] [frontend.modules.layout.core] - [frontend.handler.db-based.page :as db-page-handler] - [frontend.db.async :as db-async] [frontend.state :as state] [frontend.util :as util] [logseq.api.block :as api-block] @@ -60,12 +58,12 @@ blocks (:blocks result)] (when (seq blocks) (p/doseq [block blocks] - (let [id (:block/uuid block) - b (db/entity [:block/uuid id]) - properties (when uuid->properties (uuid->properties id))] - (when (seq properties) - (api-block/db-based-save-block-properties! b properties {:plugin this - :schema schema}))))) + (let [id (:block/uuid block) + b (db/entity [:block/uuid id]) + properties (when uuid->properties (uuid->properties id))] + (when (seq properties) + (api-block/db-based-save-block-properties! b properties {:plugin this + :schema schema}))))) (let [blocks' (map (fn [b] (db/entity [:block/uuid (:block/uuid b)])) blocks)] (sdk-utils/result->js blocks'))))) @@ -95,10 +93,10 @@ (defn get-property [k] (this-as this - (p/let [prop (-get-property this k) - prop' (some-> prop - (assoc :type (:logseq.property/type prop)))] - (sdk-utils/result->js prop')))) + (p/let [prop (-get-property this k) + prop' (some-> prop + (assoc :type (:logseq.property/type prop)))] + (sdk-utils/result->js prop')))) (defn ->cardinality [input] @@ -117,6 +115,32 @@ (when-not (contains? valid-types type) (throw (ex-info (str "Invalid type, type should be one of: " valid-types) {:type type}))))) +(defn- upsert-property-aux + [this k schema opts] + (p/let [k' (api-block/sanitize-user-property-name k) + property-ident (api-block/get-db-ident-from-property-name k' this) + property (db/entity property-ident)] + (if property + property + (p/let [_ (api-block/ensure-property-upsert-control this property-ident k') + schema (or (some-> schema bean/->clj + (update-keys #(if (contains? #{:hide :public} %) + (keyword (str (name %) "?")) %))) + {}) + _ (when (:type schema) + (schema-type-check! (keyword (:type schema)))) + schema (cond-> schema + (string? (:cardinality schema)) + (-> (assoc :db/cardinality (->cardinality (:cardinality schema))) + (dissoc :cardinality)) + + (string? (:type schema)) + (-> (assoc :logseq.property/type (keyword (:type schema))) + (dissoc :type))) + p (db-property-handler/upsert-property! property-ident schema + (assoc opts :property-name k'))] + (db/entity (:db/id p)))))) + (defn upsert-property "schema: {:type :default | :number | :date | :datetime | :checkbox | :url | :node | :json | :string @@ -128,37 +152,20 @@ [k ^js schema ^js opts] (this-as this - (when-not (string/blank? k) - (p/let [opts (or (some-> opts bean/->clj) {}) - k' (api-block/sanitize-user-property-name k) - property-ident (api-block/get-db-ident-from-property-name k' this) - _ (api-block/ensure-property-upsert-control this property-ident k') - schema (or (some-> schema (bean/->clj) - (update-keys #(if (contains? #{:hide :public} %) - (keyword (str (name %) "?")) %))) {}) - _ (when (:type schema) - (schema-type-check! (keyword (:type schema)))) - schema (cond-> schema - (string? (:cardinality schema)) - (-> (assoc :db/cardinality (->cardinality (:cardinality schema))) - (dissoc :cardinality)) - - (string? (:type schema)) - (-> (assoc :logseq.property/type (keyword (:type schema))) - (dissoc :type))) - p (db-property-handler/upsert-property! property-ident schema - (assoc opts :property-name k')) - p (db/entity (:db/id p))] - (sdk-utils/result->js p))))) + (when-not (string/blank? k) + (p/let [opts' (or (some-> opts bean/->clj) {}) + schema' (or (some-> schema bean/->clj) {}) + property (upsert-property-aux this k schema' opts')] + (sdk-utils/result->js property))))) (defn remove-property [k] (this-as this - (p/let [property (-get-property this k)] - (when-let [uuid (and (api-block/plugin-property-key? (:db/ident property)) - (:block/uuid property))] - (page-common-handler/js tag)))) -(defn add-tag-class-property [tag-id property-id-or-name & {:keys [schema]}] - (p/let [repo (state/get-current-repo) - tag-entity (db-async/ tag-entity (ldb/class?)) - _ (when-not class-tag? (throw (ex-info (str tag-id " should be class tag") {:value tag-entity}))) - property (db-async/ property (ldb/property?)) - property-title (or (:block/title property) property-id-or-name)] - (p/let [property' - (if property? - (do - (when (and (not (ldb/public-built-in-property? property)) - (ldb/built-in? property)) - (throw (ex-info "This is a private built-in property that can't be used." {:value property}))) - property) - ;; new property entered or converting page to property - (if (db-property/valid-property-name? property-title) - (p/let [type (or (:type schema) :default) - schema (assoc schema :logseq.property/type type) - opts (cond-> {:property-name property-title} - (and (not property?) (ldb/internal-page? property)) - (assoc :properties {:db/id (:db/id property)})) - result (db-property-handler/upsert-property! nil schema opts) - property (db/entity (:db/id result)) - _ (when class-tag? - (pv/js property') - ))) +(defn tag-add-property [tag-id property-id-or-name] + (p/let [tag (db/get-page tag-id) + property (db/get-page property-id-or-name)] + (when-not (ldb/class? tag) (throw (ex-info "Not a valid tag" {:tag tag-id}))) + (when-not (ldb/property? property) (throw (ex-info "Not a valid property" {:property property-id-or-name}))) + (when (and (not (ldb/public-built-in-property? property)) + (ldb/built-in? property)) + (throw (ex-info "This is a private built-in property that can't be used." {:value property}))) + (p/do! + (db-property-handler/class-add-property! (:db/id tag) (:db/ident property)) + (sdk-utils/result->js (db/get-page tag-id))))) -(defn remove-tag-class-property [tag-id property-id-or-name] - (throw (ex-info "TODO: implement remove-tag-class-property" {tag-id property-id-or-name}))) +(defn tag-remove-property [tag-id property-id-or-name] + (p/let [tag (db/get-page tag-id) + property (db/get-page property-id-or-name)] + (when-not (ldb/class? tag) (throw (ex-info "Not a valid tag" {:tag tag-id}))) + (when-not (ldb/property? property) (throw (ex-info "Not a valid property" {:property property-id-or-name}))) + (p/do! + (db-property-handler/class-remove-property! (:db/id tag) (:db/ident property)) + (sdk-utils/result->js (db/get-page tag-id))))) (defn add-block-tag [id-or-name tag-id] (p/let [repo (state/get-current-repo)