mirror of
https://github.com/logseq/logseq.git
synced 2026-05-24 04:34:14 +00:00
enhance(cli): show command displays public built-in props
Adds support for show to display several public built-in props that weren't visible for. Confirmed this works for scheduled, deadline, priority, description and user* properties
This commit is contained in:
7
deps/db/src/logseq/db/frontend/property.cljs
vendored
7
deps/db/src/logseq/db/frontend/property.cljs
vendored
@@ -26,7 +26,7 @@
|
||||
* :cardinality - property cardinality. Default to one/single cardinality if not set
|
||||
* :hide? - Boolean which hides property when set on a block or exported e.g. slides
|
||||
* :public? - Boolean which allows property to be used by user: add and remove property to blocks/pages
|
||||
and queryable via property and has-property rules
|
||||
and queryable via property and has-property rules. When it's not set, it's the same as false
|
||||
* :view-context - Keyword to indicate which view contexts a property can be
|
||||
seen in when :public? is set. Valid values are :page, :block and :never. Property can
|
||||
be viewed in any context if not set
|
||||
@@ -662,6 +662,11 @@
|
||||
:public? false
|
||||
:hide? true}})))
|
||||
|
||||
(def public-built-in-properties
|
||||
(->> built-in-properties
|
||||
(keep (fn [[k v]] (when (get-in v [:schema :public?]) k)))
|
||||
set))
|
||||
|
||||
(def db-attribute-properties
|
||||
"Internal properties that are also db schema attributes"
|
||||
#{:block/alias :block/tags :block/parent
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
[logseq.cli.style :as style]
|
||||
[logseq.cli.transport :as transport]
|
||||
[logseq.common.util :as common-util]
|
||||
[promesa.core :as p]))
|
||||
[promesa.core :as p]
|
||||
[clojure.set :as set]
|
||||
[logseq.db.frontend.property :as db-property]))
|
||||
|
||||
(def ^:private show-spec
|
||||
{:id {:desc "Block db/id or EDN vector of ids"}
|
||||
@@ -154,12 +156,21 @@
|
||||
(when (seq labels)
|
||||
(string/join " " (map #(style/bold (str "#" %)) labels)))))
|
||||
|
||||
(def ^:private user-property-namespace "user.property")
|
||||
(def ^:private displayable-built-in-properties
|
||||
"Built-in properties that are displayed alongside user properties."
|
||||
(set/difference db-property/public-built-in-properties
|
||||
;; Exclude built-in properties handled elsewhere in this command
|
||||
#{:block/tags :logseq.property/status}))
|
||||
|
||||
(defn- user-property-key?
|
||||
[k]
|
||||
(and (qualified-keyword? k)
|
||||
(= user-property-namespace (namespace k))))
|
||||
(= db-property/default-user-namespace (namespace k))))
|
||||
|
||||
(defn- displayable-property-key?
|
||||
[k]
|
||||
(or (user-property-key? k)
|
||||
(contains? displayable-built-in-properties k)))
|
||||
|
||||
(defn- nonblank-string
|
||||
[value]
|
||||
@@ -223,7 +234,7 @@
|
||||
([node] (node-user-property-entries node nil))
|
||||
([node labels]
|
||||
(->> node
|
||||
(filter (fn [[k _]] (user-property-key? k)))
|
||||
(filter (fn [[k _]] (displayable-property-key? k)))
|
||||
(map (fn [[k v]] [k (normalize-property-values v labels)]))
|
||||
(remove (fn [[_ values]] (empty? values)))
|
||||
vec)))
|
||||
@@ -488,7 +499,7 @@
|
||||
[{:keys [root linked-references]}]
|
||||
(letfn [(collect-node [node]
|
||||
(let [node-keys (->> (keys node)
|
||||
(filter user-property-key?))]
|
||||
(filter displayable-property-key?))]
|
||||
(reduce (fn [acc child]
|
||||
(into acc (collect-node child)))
|
||||
(set node-keys)
|
||||
@@ -542,7 +553,7 @@
|
||||
:else acc))
|
||||
(collect-node [acc node]
|
||||
(let [acc (reduce (fn [acc [k v]]
|
||||
(if (user-property-key? k)
|
||||
(if (displayable-property-key? k)
|
||||
(collect-value acc v)
|
||||
acc))
|
||||
acc
|
||||
@@ -633,12 +644,21 @@
|
||||
[(namespace ?a) ?ns]
|
||||
[(= "user.property" ?ns)]
|
||||
[(get-else $ ?e :logseq.property/type :default) ?type]]
|
||||
built-in-query '[:find ?a ?type
|
||||
:in $ [?a ...]
|
||||
:where
|
||||
[?e :db/ident ?a]
|
||||
[(get-else $ ?e :logseq.property/type :default) ?type]]
|
||||
props-query '[:find ?b ?a ?v
|
||||
:in $ [?b ...] [?a ...]
|
||||
:where
|
||||
[?b ?a ?v]]
|
||||
ids (vec block-ids)]
|
||||
(p/let [ident-type-pairs (transport/invoke config :thread-api/q false [repo [idents-query]])
|
||||
ids (vec block-ids)
|
||||
built-in-idents (vec displayable-built-in-properties)]
|
||||
(p/let [user-pairs (transport/invoke config :thread-api/q false [repo [idents-query]])
|
||||
built-in-pairs (transport/invoke config :thread-api/q false
|
||||
[repo [built-in-query built-in-idents]])
|
||||
ident-type-pairs (into (vec user-pairs) built-in-pairs)
|
||||
datetime-idents (set (keep (fn [[a type]] (when (= :datetime type) a)) ident-type-pairs))
|
||||
property-idents (vec (map first ident-type-pairs))]
|
||||
(if (seq property-idents)
|
||||
|
||||
@@ -101,12 +101,14 @@
|
||||
(let [call-idx (swap! call-count inc)]
|
||||
(p/resolved
|
||||
(case call-idx
|
||||
;; First call: idents-query returns property idents with types
|
||||
;; First call: user idents-query returns property idents with types
|
||||
1 [[:user.property/title :default]
|
||||
[:user.property/due :datetime]
|
||||
[:user.property/count :number]]
|
||||
;; Second call: props-query returns raw values
|
||||
2 [[10 :user.property/title "hello"]
|
||||
;; Second call: built-in idents-query returns built-in property types
|
||||
2 []
|
||||
;; Third call: props-query returns raw values
|
||||
3 [[10 :user.property/title "hello"]
|
||||
[10 :user.property/due 1774267200000]
|
||||
[10 :user.property/count 42]]
|
||||
[]))))]
|
||||
@@ -123,6 +125,37 @@
|
||||
(p/catch (fn [e] (is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest test-fetch-user-properties-includes-built-in-datetime
|
||||
(let [fetch #'show-command/fetch-user-properties
|
||||
call-count (atom 0)
|
||||
mock-invoke (fn [_ _method _ _args]
|
||||
(let [call-idx (swap! call-count inc)]
|
||||
(p/resolved
|
||||
(case call-idx
|
||||
;; First call: user idents-query
|
||||
1 [[:user.property/status :default]]
|
||||
;; Second call: built-in idents-query returns deadline and scheduled
|
||||
2 [[:logseq.property/deadline :datetime]
|
||||
[:logseq.property/scheduled :datetime]]
|
||||
;; Third call: props-query returns raw values
|
||||
3 [[10 :user.property/status "todo"]
|
||||
[10 :logseq.property/deadline 1774267200000]
|
||||
[10 :logseq.property/scheduled 1774180800000]]
|
||||
[]))))]
|
||||
(async done
|
||||
(-> (p/with-redefs [transport/invoke mock-invoke]
|
||||
(p/let [result (fetch {} "demo" [10])]
|
||||
(testing "built-in deadline is converted to ISO string"
|
||||
(is (string? (get-in result [10 :logseq.property/deadline])))
|
||||
(is (string/includes? (get-in result [10 :logseq.property/deadline]) "2026")))
|
||||
(testing "built-in scheduled is converted to ISO string"
|
||||
(is (string? (get-in result [10 :logseq.property/scheduled])))
|
||||
(is (string/includes? (get-in result [10 :logseq.property/scheduled]) "2026")))
|
||||
(testing "user property is unaffected"
|
||||
(is (= "todo" (get-in result [10 :user.property/status]))))))
|
||||
(p/catch (fn [e] (is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(defn- call-private
|
||||
[sym & args]
|
||||
(when-let [v (get (ns-interns 'logseq.cli.command.show) sym)]
|
||||
|
||||
Reference in New Issue
Block a user