mirror of
https://github.com/logseq/logseq.git
synced 2026-05-29 15:09:41 +00:00
feat: add current page badge functionality
This commit is contained in:
@@ -8,3 +8,11 @@
|
||||
.ls-dialog-cmdk {
|
||||
@apply p-0 w-auto !max-w-fit overflow-hidden;
|
||||
}
|
||||
|
||||
.cp__cmdk-current-page-badge {
|
||||
@apply inline-flex items-center rounded-full border text-xs font-medium leading-none;
|
||||
padding: 2px 8px;
|
||||
color: var(--lx-gray-11, var(--ls-secondary-text-color, rgba(0, 0, 0, 0.7)));
|
||||
background: var(--lx-gray-04, var(--ls-tertiary-background-color, rgba(0, 0, 0, 0.08)));
|
||||
border-color: var(--lx-gray-06, var(--ls-border-color, rgba(0, 0, 0, 0.12)));
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@
|
||||
new-result)))]))
|
||||
|
||||
(defn page-item
|
||||
[repo page input]
|
||||
[repo page current-page input]
|
||||
(let [entity (-> (or (db/entity [:block/uuid (:block/uuid page)]) page)
|
||||
(update :block/tags (fn [tags]
|
||||
(map (fn [tag]
|
||||
@@ -286,6 +286,12 @@
|
||||
tag)) tags))))
|
||||
source-page (or (model/get-alias-source-page repo (:db/id entity))
|
||||
(:alias page))
|
||||
current-page-id (:block/uuid current-page)
|
||||
result-page-id (or (:block/uuid source-page)
|
||||
(:block/uuid entity)
|
||||
(:block/uuid page))
|
||||
current-page? (and current-page-id
|
||||
(= current-page-id result-page-id))
|
||||
icon (icon-component/get-node-icon-cp entity {:ignore-current-icon? true})
|
||||
title (block-handler/block-unique-title entity
|
||||
:alias (:block/title source-page)
|
||||
@@ -300,6 +306,8 @@
|
||||
(block/breadcrumb {:disable-preview? true
|
||||
:search? true} repo (:block/uuid page)
|
||||
{:disabled? true}))
|
||||
:result-type :page
|
||||
:current-page? current-page?
|
||||
:alias (:alias page)
|
||||
:source-block (or source-page page))))
|
||||
|
||||
@@ -314,6 +322,7 @@
|
||||
:header (block/breadcrumb {:disable-preview? true
|
||||
:search? true} repo id
|
||||
{:disabled? true})
|
||||
:result-type :block
|
||||
:current-page? (when-let [page-id (:block/page block)]
|
||||
(= page-id (:block/uuid current-page)))
|
||||
:source-block block}))
|
||||
@@ -335,7 +344,7 @@
|
||||
blocks (remove nil? blocks)
|
||||
items (keep (fn [block]
|
||||
(if (:page? block)
|
||||
(page-item repo block @!input)
|
||||
(page-item repo block current-page @!input)
|
||||
(block-item repo block current-page @!input))) blocks)]
|
||||
(if (= group :current-page)
|
||||
(let [items-on-current-page (filter :current-page? items)]
|
||||
@@ -346,6 +355,8 @@
|
||||
(let [!input (::input state)
|
||||
!results (::results state)
|
||||
repo (state/get-current-repo)
|
||||
current-page (when-let [id (page-util/get-current-page-id)]
|
||||
(db/entity id))
|
||||
opts (cmdk-state/cmdk-block-search-options
|
||||
{:filter-group :code
|
||||
:dev? config/dev?})]
|
||||
@@ -353,7 +364,7 @@
|
||||
(p/let [blocks (search/block-search repo @!input opts)
|
||||
blocks (remove nil? blocks)
|
||||
items (map (fn [block]
|
||||
(block-item repo block nil @!input))
|
||||
(block-item repo block current-page @!input))
|
||||
blocks)]
|
||||
(swap! !results update group merge {:status :success :items items}))))
|
||||
|
||||
@@ -428,6 +439,7 @@
|
||||
:icon-theme :gray
|
||||
:text (highlight-content-query (:block/title block) @!input)
|
||||
:header (block/breadcrumb {:search? true} repo id {:disabled? true})
|
||||
:result-type (if (:page? block) :page :block)
|
||||
:current-page? true
|
||||
:source-block block})) blocks)]
|
||||
(swap! !results update :current-page merge {:status :success :items items})))
|
||||
|
||||
@@ -50,13 +50,31 @@
|
||||
segs))
|
||||
[:span normal-text])))))
|
||||
|
||||
(def current-page-badge-label "Current Page")
|
||||
|
||||
(defn current-page-badge-placement
|
||||
[{:keys [current-page? result-type]}]
|
||||
(when current-page?
|
||||
(case result-type
|
||||
:page {:text-badge current-page-badge-label}
|
||||
:block {:header-badge current-page-badge-label}
|
||||
nil)))
|
||||
|
||||
(defn current-page-badge-node
|
||||
[label]
|
||||
(when-not (string/blank? label)
|
||||
[:span.cp__cmdk-current-page-badge label]))
|
||||
|
||||
(rum/defc root [{:keys [icon icon-theme query text info shortcut value-label value
|
||||
title highlighted on-highlight on-highlight-dep header on-click
|
||||
hoverable compact rounded on-mouse-enter component-opts source-block] :as _props
|
||||
hoverable compact rounded on-mouse-enter component-opts source-block] :as props
|
||||
:or {hoverable true rounded true}}
|
||||
{:keys [app-config]}]
|
||||
(let [ref (hooks/create-ref)
|
||||
highlight-query (partial highlight-query* app-config query)
|
||||
badge-placement (current-page-badge-placement props)
|
||||
text-badge (current-page-badge-node (:text-badge badge-placement))
|
||||
header-badge (current-page-badge-node (:header-badge badge-placement))
|
||||
[hover? set-hover?] (rum/use-state false)
|
||||
mouse-highlighted? (and highlighted hoverable hover?)
|
||||
keyboard-highlighted? (and highlighted (not mouse-highlighted?))
|
||||
@@ -99,9 +117,10 @@
|
||||
component-opts)
|
||||
;; header
|
||||
(when header
|
||||
[:div.text-xs.pl-8.font-light {:class "-mt-1"
|
||||
[:div.text-xs.pl-8.font-light.flex.items-center.gap-2.flex-wrap {:class "-mt-1"
|
||||
:style {:color "var(--lx-gray-11)"}}
|
||||
(highlight-query header)])
|
||||
(highlight-query header)
|
||||
header-badge])
|
||||
;; main row
|
||||
[:div.flex.items-start.gap-3
|
||||
[:div.w-5.h-5.rounded.flex.items-center.justify-center
|
||||
@@ -119,10 +138,11 @@
|
||||
[:div.flex.flex-1.flex-col
|
||||
(when title
|
||||
[:div.text-sm.pb-2.font-bold.text-gray-11 (highlight-query title)])
|
||||
[:div {:class "text-sm font-medium text-gray-12"}
|
||||
[:div {:class "text-sm font-medium text-gray-12 flex items-center gap-2 flex-wrap"}
|
||||
(block-handler/block-title-with-icon source-block
|
||||
(highlight-query text)
|
||||
icon-component/icon)
|
||||
text-badge
|
||||
(when info
|
||||
[:span.text-xs.text-gray-11 " — " (highlight-query info)])]]
|
||||
(when (or value-label value)
|
||||
|
||||
33
src/test/frontend/components/cmdk/list_item_test.cljs
Normal file
33
src/test/frontend/components/cmdk/list_item_test.cljs
Normal file
@@ -0,0 +1,33 @@
|
||||
(ns frontend.components.cmdk.list-item-test
|
||||
(:require [cljs.test :refer [deftest is testing]]
|
||||
[frontend.components.cmdk.list-item :as list-item]))
|
||||
|
||||
(deftest current-page-badge-placement-test
|
||||
(testing "page result in current page gets text badge"
|
||||
(is (= {:text-badge "Current Page"}
|
||||
(list-item/current-page-badge-placement
|
||||
{:current-page? true
|
||||
:result-type :page}))))
|
||||
(testing "block result in current page gets header badge"
|
||||
(is (= {:header-badge "Current Page"}
|
||||
(list-item/current-page-badge-placement
|
||||
{:current-page? true
|
||||
:result-type :block}))))
|
||||
(testing "non current-page results do not get badge"
|
||||
(is (nil? (list-item/current-page-badge-placement
|
||||
{:current-page? false
|
||||
:result-type :page})))
|
||||
(is (nil? (list-item/current-page-badge-placement
|
||||
{:current-page? false
|
||||
:result-type :block})))
|
||||
(is (nil? (list-item/current-page-badge-placement
|
||||
{:current-page? true
|
||||
:result-type :unknown})))))
|
||||
|
||||
(deftest current-page-badge-node-test
|
||||
(testing "badge node renders expected class and label"
|
||||
(is (= [:span.cp__cmdk-current-page-badge "Current Page"]
|
||||
(list-item/current-page-badge-node "Current Page"))))
|
||||
(testing "blank labels do not render badge node"
|
||||
(is (nil? (list-item/current-page-badge-node "")))
|
||||
(is (nil? (list-item/current-page-badge-node nil)))))
|
||||
Reference in New Issue
Block a user