ux enhancements

This commit is contained in:
Tienson Qin
2026-01-04 17:40:14 +08:00
parent b5f8ed266a
commit ce3f0a6d94
3 changed files with 75 additions and 60 deletions

View File

@@ -705,48 +705,49 @@
(and (or (db-property/user-property-namespace? attr-ns)
(db-property/plugin-property? attr))
(when-let [property (d/entity db attr)]
(and
(seq (:logseq.property/classes property))
(= :db.type/ref (:db/valueType property))))))))
(= :db.type/ref (:db/valueType property)))))))
(defn get-bidirectional-properties
"Given a target entity id, returns a seq of maps with:
* :title - pluralized class title
* :entities - page entities that reference the target via ref properties"
[db target-id]
(when (and db target-id)
(let [target (d/entity db target-id)]
(when target
(let [add-entity
(fn [acc class-ent entity]
(if-let [title (pluralize-class-title (:block/title class-ent))]
(update acc title (fnil conj #{}) entity)
acc))]
(->> (d/q '[:find ?e ?a
:in $ ?v
:where [?e ?a ?v]]
db
target-id)
(keep (fn [[e a]]
(when (bidirectional-property-attr? db a)
(when-let [entity (d/entity db e)]
(when (and (not= (:db/id entity) target-id)
(not (entity-util/class? entity))
(not (entity-util/property? entity)))
(let [classes (->> (:block/tags entity)
(filter entity-util/class?))]
(when (seq classes)
(map (fn [class-ent]
[class-ent entity])
classes))))))))
(mapcat identity)
(reduce (fn [acc [class-ent entity]]
(add-entity acc class-ent entity))
{})
(map (fn [[title entities]]
{:title title
:entities (->> entities
(sort-by (comp string/lower-case :block/title))
vec)}))
(sort-by (comp string/lower-case :title))
vec))))))
(when (and db target-id (d/entity db target-id))
(let [add-entity
(fn [acc class-id entity]
(if class-id
(update acc class-id (fnil conj #{}) entity)
acc))]
(->> (d/q '[:find ?e ?a
:in $ ?v
:where
[?e ?a ?v]
[?ea :db/ident ?a]
[?ea :logseq.property/classes]]
db
target-id)
(keep (fn [[e a]]
(when (bidirectional-property-attr? db a)
(when-let [entity (d/entity db e)]
(when (and (not= (:db/id entity) target-id)
(not (entity-util/class? entity))
(not (entity-util/property? entity)))
(let [classes (filter entity-util/class? (:block/tags entity))]
(when (seq classes)
(map (fn [class-ent]
[(:db/id class-ent) entity])
classes))))))))
(mapcat identity)
(reduce (fn [acc [class-ent entity]]
(add-entity acc class-ent entity))
{})
(map (fn [[class-id entities]]
(let [class (d/entity db class-id)
title (pluralize-class-title (:block/title class))]
{:title title
:class class
:entities (->> entities
(sort-by :block/created-at)
vec)})))
(sort-by (comp :block/created-at :class))
vec))))

View File

@@ -1131,6 +1131,10 @@ html.is-mac {
.block-tags {
margin-top: 17px;
}
.ls-properties-area .block-tags {
margin-top: 0;
}
}
.ls-page-title .ls-properties-area {

View File

@@ -341,36 +341,46 @@
(:block/title property)]
(property-key-title block property class-schema?))]))
(rum/defc bidirectional-page-link
[page]
(let [title (ldb/get-title-with-parents page)]
[:a.page-ref
{:on-click (fn [e]
(util/stop e)
(route-handler/redirect-to-page! (:block/uuid page)))}
title]))
(defn- bidirectional-property-icon-cp
[property]
(if-let [icon (:logseq.property/icon property)]
(icon-component/icon icon {:size 15 :color? true})
(ui/icon "letter-b" {:class "opacity-50" :size 15})))
(rum/defcs bidirectional-values-cp < rum/static
{:init (fn [state]
(assoc state ::container-id (state/get-next-container-id)))}
[state entities]
(let [blocks-container (state/get-component :block/blocks-container)
container-id (::container-id state)
config {:id (str "bidirectional-" container-id)
:container-id container-id
:editor-box (state/get-component :editor/box)
:view? true}]
(if (and blocks-container (seq entities))
[:div.property-block-container.content.w-full
(blocks-container config entities)]
[:span.opacity-60 "Empty"])))
(rum/defc bidirectional-properties-section < rum/static
[bidirectional-properties]
(when (seq bidirectional-properties)
(for [{:keys [title entities]} bidirectional-properties]
(for [{:keys [class title entities]} bidirectional-properties]
[:div.property-pair.items-start {:key (str "bidirectional-" title)}
[:div.property-key
[:div.property-key-inner
[:div.property-k.flex.select-none.w-full title]]]
[:div.property-icon
(bidirectional-property-icon-cp class)]
(if class
[:a.property-k.flex.select-none.w-full.jtrigger
{:on-click (fn [e]
(util/stop e)
(route-handler/redirect-to-page! (:block/uuid class)))}
title]
[:div.property-k.flex.select-none.w-full title])]]
[:div.ls-block.property-value-container.flex.flex-row.gap-1.items-start
[:div.property-value.flex.flex-1
[:div.multi-values.flex.flex-1.flex-row.items-center.flex-wrap.gap-1
(let [items (map (fn [entity]
(rum/with-key
(bidirectional-page-link entity)
(str "bi-property-" title "-" (:db/id entity))))
entities)]
(if (seq items)
[:div.flex.flex-col
(for [item items]
item)]
[:span.opacity-60 "Empty"]))]]]])))
(bidirectional-values-cp entities)]]])))
(rum/defcs ^:large-vars/cleanup-todo property-input < rum/reactive
(rum/local false ::show-new-property-config?)