mirror of https://github.com/logseq/logseq
Merge branch 'feat/db' into refactor/boolean-not-ref-type
commit
a85fcdb842
|
@ -264,8 +264,7 @@
|
||||||
|
|
||||||
(def property-common-schema-attrs
|
(def property-common-schema-attrs
|
||||||
"Property :schema attributes common to all properties"
|
"Property :schema attributes common to all properties"
|
||||||
[[:hide? {:optional true} :boolean]
|
[[:hide? {:optional true} :boolean]])
|
||||||
[:description {:optional true} :string]])
|
|
||||||
|
|
||||||
(def internal-property
|
(def internal-property
|
||||||
(vec
|
(vec
|
||||||
|
@ -371,10 +370,7 @@
|
||||||
[:db/ident {:optional true} logseq-property-ident]
|
[:db/ident {:optional true} logseq-property-ident]
|
||||||
[:block/title {:optional true} :string]
|
[:block/title {:optional true} :string]
|
||||||
[:property.value/content {:optional true} [:or :string :double]]
|
[:property.value/content {:optional true} [:or :string :double]]
|
||||||
[:block/closed-value-property {:optional true} [:set :int]]
|
[:block/closed-value-property {:optional true} [:set :int]] ]
|
||||||
[:block/schema {:optional true}
|
|
||||||
[:map
|
|
||||||
[:description {:optional true} :string]]]]
|
|
||||||
(remove #(#{:block/title} (first %)) block-attrs)
|
(remove #(#{:block/title} (first %)) block-attrs)
|
||||||
page-or-block-attrs)))
|
page-or-block-attrs)))
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,10 @@
|
||||||
:hide? true
|
:hide? true
|
||||||
:view-context :page
|
:view-context :page
|
||||||
:public? true}}
|
:public? true}}
|
||||||
|
:logseq.property/description {:schema
|
||||||
|
{:type :default
|
||||||
|
:public? true}}
|
||||||
|
|
||||||
:logseq.property.table/sorting {:schema
|
:logseq.property.table/sorting {:schema
|
||||||
{:type :coll
|
{:type :coll
|
||||||
:hide? true
|
:hide? true
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
(defn build-closed-value-block
|
(defn build-closed-value-block
|
||||||
"Builds a closed value block to be transacted"
|
"Builds a closed value block to be transacted"
|
||||||
[block-uuid block-value property {:keys [db-ident icon description]}]
|
[block-uuid block-value property {:keys [db-ident icon]}]
|
||||||
(assert block-uuid (uuid? block-uuid))
|
(assert block-uuid (uuid? block-uuid))
|
||||||
(cond->
|
(cond->
|
||||||
(closed-value-new-block block-uuid block-value property)
|
(closed-value-new-block block-uuid block-value property)
|
||||||
|
@ -31,9 +31,6 @@
|
||||||
icon
|
icon
|
||||||
(assoc :logseq.property/icon icon)
|
(assoc :logseq.property/icon icon)
|
||||||
|
|
||||||
description
|
|
||||||
(update :block/schema assoc :description description)
|
|
||||||
|
|
||||||
true
|
true
|
||||||
sqlite-util/block-with-timestamps))
|
sqlite-util/block-with-timestamps))
|
||||||
|
|
||||||
|
@ -46,13 +43,13 @@
|
||||||
:ref-type? true})
|
:ref-type? true})
|
||||||
property-attributes)]
|
property-attributes)]
|
||||||
(into [property-tx]
|
(into [property-tx]
|
||||||
(map (fn [{:keys [db-ident value icon description uuid]}]
|
(map (fn [{:keys [db-ident value icon uuid]}]
|
||||||
(cond->
|
(cond->
|
||||||
(build-closed-value-block
|
(build-closed-value-block
|
||||||
uuid
|
uuid
|
||||||
value
|
value
|
||||||
property
|
property
|
||||||
{:db-ident db-ident :icon icon :description description})
|
{:db-ident db-ident :icon icon})
|
||||||
true
|
true
|
||||||
(assoc :block/order (db-order/gen-key))))
|
(assoc :block/order (db-order/gen-key))))
|
||||||
(:closed-values property)))))
|
(:closed-values property)))))
|
||||||
|
|
|
@ -82,34 +82,32 @@
|
||||||
(defn- property-with-values
|
(defn- property-with-values
|
||||||
[db block]
|
[db block]
|
||||||
(when (entity-plus/db-based-graph? db)
|
(when (entity-plus/db-based-graph? db)
|
||||||
(let [block (d/entity db (:db/id block))
|
(let [block (d/entity db (:db/id block))]
|
||||||
block-properties (when (seq (:block/properties block))
|
(->> (:block/properties block)
|
||||||
(mapcat
|
vals
|
||||||
(fn [[_property-id property-values]]
|
(mapcat
|
||||||
(let [values (if (and (coll? property-values)
|
(fn [property-values]
|
||||||
(map? (first property-values)))
|
(let [values (->>
|
||||||
property-values
|
(if (and (coll? property-values)
|
||||||
#{property-values})
|
(map? (first property-values)))
|
||||||
value-ids (when (every? map? values)
|
property-values
|
||||||
(->> (map :db/id values)
|
#{property-values})
|
||||||
(filter (fn [id] (or (int? id) (keyword? id))))))
|
(remove sqlite-util/page?))
|
||||||
value-blocks (->>
|
value-ids (when (every? map? values)
|
||||||
(when (seq value-ids)
|
(->> (map :db/id values)
|
||||||
(map
|
(filter (fn [id] (or (int? id) (keyword? id))))))
|
||||||
(fn [id] (d/pull db '[*] id))
|
value-blocks (->>
|
||||||
value-ids))
|
(when (seq value-ids)
|
||||||
;; FIXME: why d/pull returns {:db/id db-ident} instead of {:db/id number-eid}?
|
(map
|
||||||
(map (fn [block]
|
(fn [id] (d/pull db '[*] id))
|
||||||
(let [from-property-id (get-in block [:logseq.property/created-from-property :db/id])]
|
value-ids))
|
||||||
(if (keyword? from-property-id)
|
;; FIXME: why d/pull returns {:db/id db-ident} instead of {:db/id number-eid}?
|
||||||
(assoc-in block [:logseq.property/created-from-property :db/id] (:db/id (d/entity db from-property-id)))
|
(keep (fn [block]
|
||||||
block)))))
|
(let [from-property-id (get-in block [:logseq.property/created-from-property :db/id])]
|
||||||
page (when (seq values)
|
(if (keyword? from-property-id)
|
||||||
(when-let [page-id (:db/id (:block/page (d/entity db (:db/id (first values)))))]
|
(assoc-in block [:logseq.property/created-from-property :db/id] (:db/id (d/entity db from-property-id)))
|
||||||
(d/pull db '[*] page-id)))]
|
block)))))]
|
||||||
(remove nil? (concat [page] value-blocks))))
|
value-blocks)))))))
|
||||||
(:block/properties block)))]
|
|
||||||
block-properties)))
|
|
||||||
|
|
||||||
(defn get-block-children-ids
|
(defn get-block-children-ids
|
||||||
"Returns children UUIDs"
|
"Returns children UUIDs"
|
||||||
|
|
|
@ -397,32 +397,24 @@
|
||||||
(seq properties))))
|
(seq properties))))
|
||||||
|
|
||||||
(defn- build-closed-value-tx
|
(defn- build-closed-value-tx
|
||||||
[db property resolved-value {:keys [id icon description]
|
[db property resolved-value {:keys [id icon]}]
|
||||||
:or {description ""}}]
|
|
||||||
(let [block (when id (d/entity db [:block/uuid id]))
|
(let [block (when id (d/entity db [:block/uuid id]))
|
||||||
block-id (or id (ldb/new-block-id))
|
block-id (or id (ldb/new-block-id))
|
||||||
icon (when-not (and (string? icon) (string/blank? icon)) icon)
|
icon (when-not (and (string? icon) (string/blank? icon)) icon)
|
||||||
description (string/trim description)
|
|
||||||
description (when-not (string/blank? description) description)
|
|
||||||
tx-data (if block
|
tx-data (if block
|
||||||
[(let [schema (:block/schema block)]
|
[(cond->
|
||||||
(cond->
|
(outliner-core/block-with-updated-at
|
||||||
(outliner-core/block-with-updated-at
|
(merge
|
||||||
(merge
|
{:block/uuid id
|
||||||
{:block/uuid id
|
:block/closed-value-property (:db/id property)}
|
||||||
:block/closed-value-property (:db/id property)
|
(if (db-property-type/original-value-ref-property-types (get-in property [:block/schema :type]))
|
||||||
:block/schema (if description
|
{:property.value/content resolved-value}
|
||||||
(assoc schema :description description)
|
{:block/title resolved-value})))
|
||||||
(dissoc schema :description))}
|
icon
|
||||||
(if (db-property-type/original-value-ref-property-types (get-in property [:block/schema :type]))
|
(assoc :logseq.property/icon icon))]
|
||||||
{:property.value/content resolved-value}
|
|
||||||
{:block/title resolved-value})))
|
|
||||||
icon
|
|
||||||
(assoc :logseq.property/icon icon)))]
|
|
||||||
(let [max-order (:block/order (last (:property/closed-values property)))
|
(let [max-order (:block/order (last (:property/closed-values property)))
|
||||||
new-block (-> (db-property-build/build-closed-value-block block-id resolved-value
|
new-block (-> (db-property-build/build-closed-value-block block-id resolved-value
|
||||||
property {:icon icon
|
property {:icon icon})
|
||||||
:description description})
|
|
||||||
(assoc :block/order (db-order/gen-key max-order nil)))]
|
(assoc :block/order (db-order/gen-key max-order nil)))]
|
||||||
[new-block
|
[new-block
|
||||||
(outliner-core/block-with-updated-at
|
(outliner-core/block-with-updated-at
|
||||||
|
@ -434,7 +426,7 @@
|
||||||
|
|
||||||
(defn upsert-closed-value!
|
(defn upsert-closed-value!
|
||||||
"id should be a block UUID or nil"
|
"id should be a block UUID or nil"
|
||||||
[conn property-id {:keys [id value] :as opts}]
|
[conn property-id {:keys [id value description] :as opts}]
|
||||||
(assert (or (nil? id) (uuid? id)))
|
(assert (or (nil? id) (uuid? id)))
|
||||||
(let [db @conn
|
(let [db @conn
|
||||||
property (d/entity db property-id)
|
property (d/entity db property-id)
|
||||||
|
@ -472,9 +464,20 @@
|
||||||
nil
|
nil
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(ldb/transact! conn
|
(let [tx-data (build-closed-value-tx @conn property resolved-value opts)]
|
||||||
(build-closed-value-tx @conn property resolved-value opts)
|
(ldb/transact! conn tx-data {:outliner-op :save-block})
|
||||||
{:outliner-op :save-block}))))))
|
|
||||||
|
(when (seq description)
|
||||||
|
(if-let [desc-ent (and id (:logseq.property/description (d/entity db [:block/uuid id])))]
|
||||||
|
(ldb/transact! conn
|
||||||
|
[(outliner-core/block-with-updated-at {:db/id (:db/id desc-ent)
|
||||||
|
:block/title description})]
|
||||||
|
{:outliner-op :save-block})
|
||||||
|
(set-block-property! conn
|
||||||
|
;; new closed value is first in tx-data
|
||||||
|
[:block/uuid (or id (:block/uuid (first tx-data)))]
|
||||||
|
:logseq.property/description
|
||||||
|
description)))))))))
|
||||||
|
|
||||||
(defn add-existing-values-to-closed-values!
|
(defn add-existing-values-to-closed-values!
|
||||||
"Adds existing values as closed values and returns their new block uuids"
|
"Adds existing values as closed values and returns their new block uuids"
|
||||||
|
|
|
@ -255,7 +255,7 @@
|
||||||
:description "choice 4"})
|
:description "choice 4"})
|
||||||
updated-b (d/entity @conn [:block/uuid (:block/uuid b)])]
|
updated-b (d/entity @conn [:block/uuid (:block/uuid b)])]
|
||||||
(is (= 4 (db-property/closed-value-content updated-b)))
|
(is (= 4 (db-property/closed-value-content updated-b)))
|
||||||
(is (= "choice 4" (:description (:block/schema updated-b))))))))
|
(is (= "choice 4" (db-property/property-value-content (:logseq.property/description updated-b))))))))
|
||||||
|
|
||||||
(deftest delete-closed-value!
|
(deftest delete-closed-value!
|
||||||
(let [closed-value-uuid (random-uuid)
|
(let [closed-value-uuid (random-uuid)
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
(cond-> {:block/title class-name
|
(cond-> {:block/title class-name
|
||||||
:build/properties (cond-> {:url url}
|
:build/properties (cond-> {:url url}
|
||||||
(class-m "rdfs:comment")
|
(class-m "rdfs:comment")
|
||||||
(assoc :description (get-comment-string (class-m "rdfs:comment") renamed-pages)))}
|
(assoc :logseq.property/description (get-comment-string (class-m "rdfs:comment") renamed-pages)))}
|
||||||
parent-class'
|
parent-class'
|
||||||
(assoc :build/class-parent (keyword (strip-schema-prefix parent-class')))
|
(assoc :build/class-parent (keyword (strip-schema-prefix parent-class')))
|
||||||
(seq properties)
|
(seq properties)
|
||||||
|
@ -117,12 +117,12 @@
|
||||||
schema (cond-> {:type schema-type}
|
schema (cond-> {:type schema-type}
|
||||||
;; This cardinality rule should be adjusted as we use schema.org more
|
;; This cardinality rule should be adjusted as we use schema.org more
|
||||||
(= schema-type :node)
|
(= schema-type :node)
|
||||||
(assoc :cardinality :many)
|
(assoc :cardinality :many))]
|
||||||
(property-m "rdfs:comment")
|
|
||||||
(assoc :description (get-comment-string (property-m "rdfs:comment") renamed-pages)))]
|
|
||||||
{(keyword (strip-schema-prefix (property-m "@id")))
|
{(keyword (strip-schema-prefix (property-m "@id")))
|
||||||
(cond-> {:block/schema schema
|
(cond-> {:block/schema schema
|
||||||
:build/properties {:url url}}
|
:build/properties (cond-> {:url url}
|
||||||
|
(property-m "rdfs:comment")
|
||||||
|
(assoc :logseq.property/description (get-comment-string (property-m "rdfs:comment") renamed-pages)))}
|
||||||
(= schema-type :node)
|
(= schema-type :node)
|
||||||
(assoc :build/schema-classes (mapv (comp keyword strip-schema-prefix) range-includes)))}))
|
(assoc :build/schema-classes (mapv (comp keyword strip-schema-prefix) range-includes)))}))
|
||||||
|
|
||||||
|
@ -256,8 +256,13 @@
|
||||||
(get-schema-type (get-range-includes property-m) class-map)))
|
(get-schema-type (get-range-includes property-m) class-map)))
|
||||||
frequencies)
|
frequencies)
|
||||||
"\n"))
|
"\n"))
|
||||||
(apply merge
|
(assoc
|
||||||
(mapv #(->property-page % class-map options) select-properties)))
|
(apply merge
|
||||||
|
(mapv #(->property-page % class-map options) select-properties))
|
||||||
|
;; Have to update schema for now as validation doesn't take into account existing properties
|
||||||
|
:logseq.property/description {:block/schema {:public? true :type :default}
|
||||||
|
:build/properties {:url "https://schema.org/description"
|
||||||
|
:logseq.property/description "A description of the item."}}))
|
||||||
|
|
||||||
(defn- get-all-classes-and-properties
|
(defn- get-all-classes-and-properties
|
||||||
"Get all classes and properties from raw json file"
|
"Get all classes and properties from raw json file"
|
||||||
|
@ -267,7 +272,8 @@
|
||||||
(if (string? type') [type'] type')))
|
(if (string? type') [type'] type')))
|
||||||
"rdfs:Class")
|
"rdfs:Class")
|
||||||
schema-data)
|
schema-data)
|
||||||
all-properties* (get-all-properties schema-data options)
|
;; Use built-in description
|
||||||
|
all-properties* (remove #(= "schema:description" (% "@id")) (get-all-properties schema-data options))
|
||||||
property-tuples (map #(vector (% "@id") :property) all-properties*)
|
property-tuples (map #(vector (% "@id") :property) all-properties*)
|
||||||
class-tuples (map #(vector (% "@id") :class) all-classes*)
|
class-tuples (map #(vector (% "@id") :class) all-classes*)
|
||||||
page-tuples (map #(vector (str "schema:" %) :node) existing-pages)
|
page-tuples (map #(vector (str "schema:" %) :node) existing-pages)
|
||||||
|
@ -276,6 +282,7 @@
|
||||||
renamed-properties (detect-property-conflicts-and-get-renamed-properties
|
renamed-properties (detect-property-conflicts-and-get-renamed-properties
|
||||||
property-tuples page-tuples options)
|
property-tuples page-tuples options)
|
||||||
renamed-pages (merge renamed-classes renamed-properties)
|
renamed-pages (merge renamed-classes renamed-properties)
|
||||||
|
;; Note: schema:description refs don't get renamed but they aren't used
|
||||||
;; Updates keys like @id, @subClassOf
|
;; Updates keys like @id, @subClassOf
|
||||||
rename-page-ids (fn [m]
|
rename-page-ids (fn [m]
|
||||||
(w/postwalk (fn [x]
|
(w/postwalk (fn [x]
|
||||||
|
|
|
@ -238,6 +238,7 @@
|
||||||
db-mixins/query
|
db-mixins/query
|
||||||
(rum/local nil ::property-name)
|
(rum/local nil ::property-name)
|
||||||
(rum/local nil ::property-schema)
|
(rum/local nil ::property-schema)
|
||||||
|
(rum/local nil ::property-description)
|
||||||
{:init (fn [state]
|
{:init (fn [state]
|
||||||
(let [*values (atom :loading)]
|
(let [*values (atom :loading)]
|
||||||
(p/let [result (db-async/<get-block-property-values (state/get-current-repo)
|
(p/let [result (db-async/<get-block-property-values (state/get-current-repo)
|
||||||
|
@ -248,6 +249,7 @@
|
||||||
(let [[property _opts] (:rum/args state)]
|
(let [[property _opts] (:rum/args state)]
|
||||||
(reset! (::property-name state) (:block/title property))
|
(reset! (::property-name state) (:block/title property))
|
||||||
(reset! (::property-schema state) (:block/schema property))
|
(reset! (::property-schema state) (:block/schema property))
|
||||||
|
(reset! (::property-description state) (db-property/property-value-content (:logseq.property/description property)))
|
||||||
(state/set-state! :editor/property-configure? true)
|
(state/set-state! :editor/property-configure? true)
|
||||||
state))
|
state))
|
||||||
:will-unmount (fn [state]
|
:will-unmount (fn [state]
|
||||||
|
@ -260,6 +262,7 @@
|
||||||
(when-not (= :loading values)
|
(when-not (= :loading values)
|
||||||
(let [*property-name (::property-name state)
|
(let [*property-name (::property-name state)
|
||||||
*property-schema (::property-schema state)
|
*property-schema (::property-schema state)
|
||||||
|
*property-description (::property-description state)
|
||||||
property (db/sub-block (:db/id property))
|
property (db/sub-block (:db/id property))
|
||||||
built-in? (ldb/built-in? property)
|
built-in? (ldb/built-in? property)
|
||||||
disabled? (or built-in? config/publishing?)
|
disabled? (or built-in? config/publishing?)
|
||||||
|
@ -391,15 +394,24 @@
|
||||||
(swap! *property-schema assoc :hide? (not hide?))
|
(swap! *property-schema assoc :hide? (not hide?))
|
||||||
(save-property-fn))})])
|
(save-property-fn))})])
|
||||||
|
|
||||||
(let [description (or (:description @*property-schema) "")]
|
(let [description (or @*property-description "")]
|
||||||
[:div.grid.grid-cols-5.gap-1.items-start.leading-8
|
[:div.grid.grid-cols-5.gap-1.items-start.leading-8
|
||||||
[:label.col-span-2 "Description:"]
|
[:label.col-span-2 "Description:"]
|
||||||
[:div.col-span-3
|
[:div.col-span-3
|
||||||
[:div.mt-1
|
[:div.mt-1
|
||||||
(shui/textarea
|
(shui/textarea
|
||||||
{:on-change (fn [e]
|
{:on-change (fn [e]
|
||||||
(swap! *property-schema assoc :description (util/evalue e)))
|
(reset! *property-description (util/evalue e)))
|
||||||
:on-blur save-property-fn
|
:on-blur (fn []
|
||||||
|
(if-let [ent (:logseq.property/description property)]
|
||||||
|
(db/transact! (state/get-current-repo)
|
||||||
|
[(outliner-core/block-with-updated-at
|
||||||
|
{:db/id (:db/id ent) :block/title @*property-description})]
|
||||||
|
{:outliner-op :save-block})
|
||||||
|
(db-property-handler/set-block-property!
|
||||||
|
(:db/id property)
|
||||||
|
:logseq.property/description
|
||||||
|
@*property-description)))
|
||||||
:disabled disabled?
|
:disabled disabled?
|
||||||
:default-value description})]]])]]))))
|
:default-value description})]]])]]))))
|
||||||
|
|
||||||
|
@ -716,7 +728,7 @@
|
||||||
[:div.flex.flex-1
|
[:div.flex.flex-1
|
||||||
(if (and (:class-schema? opts) (:page-configure? opts))
|
(if (and (:class-schema? opts) (:page-configure? opts))
|
||||||
[:div.property-description.text-sm.opacity-70
|
[:div.property-description.text-sm.opacity-70
|
||||||
(inline-text {} :markdown (get-in property [:block/schema :description]))]
|
(inline-text {} :markdown (db-property/property-value-content (:logseq.property/description property)))]
|
||||||
[:div.property-value.flex.flex-1
|
[:div.property-value.flex.flex-1
|
||||||
(pv/property-value block property v opts)])]]]))))
|
(pv/property-value block property v opts)])]]]))))
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
(let [block (second (:rum/args state))
|
(let [block (second (:rum/args state))
|
||||||
value (or (str (db-property/closed-value-content block)) "")
|
value (or (str (db-property/closed-value-content block)) "")
|
||||||
icon (:logseq.property/icon block)
|
icon (:logseq.property/icon block)
|
||||||
description (or (get-in block [:block/schema :description]) "")]
|
description (or (db-property/property-value-content (:logseq.property/description block)) "")]
|
||||||
(assoc state
|
(assoc state
|
||||||
::value (atom value)
|
::value (atom value)
|
||||||
::icon (atom icon)
|
::icon (atom icon)
|
||||||
|
|
Loading…
Reference in New Issue