diff --git a/deps/db/src/logseq/db.cljs b/deps/db/src/logseq/db.cljs index 221d8db386..f10e31f5c9 100644 --- a/deps/db/src/logseq/db.cljs +++ b/deps/db/src/logseq/db.cljs @@ -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)))) diff --git a/src/main/frontend/components/block.css b/src/main/frontend/components/block.css index 1823974d74..660dad3b94 100644 --- a/src/main/frontend/components/block.css +++ b/src/main/frontend/components/block.css @@ -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 { diff --git a/src/main/frontend/components/property.cljs b/src/main/frontend/components/property.cljs index a5ee6025f6..97eb74c242 100644 --- a/src/main/frontend/components/property.cljs +++ b/src/main/frontend/components/property.cljs @@ -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?)