diff --git a/src/main/frontend/components/cmdk/cmdk.css b/src/main/frontend/components/cmdk/cmdk.css index 6d66092c52..860a890f25 100644 --- a/src/main/frontend/components/cmdk/cmdk.css +++ b/src/main/frontend/components/cmdk/cmdk.css @@ -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))); +} diff --git a/src/main/frontend/components/cmdk/core.cljs b/src/main/frontend/components/cmdk/core.cljs index 09296da73c..786c581883 100644 --- a/src/main/frontend/components/cmdk/core.cljs +++ b/src/main/frontend/components/cmdk/core.cljs @@ -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}))) diff --git a/src/main/frontend/components/cmdk/list_item.cljs b/src/main/frontend/components/cmdk/list_item.cljs index 43d42a6ef1..2c35867bbd 100644 --- a/src/main/frontend/components/cmdk/list_item.cljs +++ b/src/main/frontend/components/cmdk/list_item.cljs @@ -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) diff --git a/src/test/frontend/components/cmdk/list_item_test.cljs b/src/test/frontend/components/cmdk/list_item_test.cljs new file mode 100644 index 0000000000..0a7d5c74a8 --- /dev/null +++ b/src/test/frontend/components/cmdk/list_item_test.cljs @@ -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)))))