|
@@ -131,11 +131,6 @@
|
|
|
(when-not (string/blank? after)
|
|
|
[:span after])]))
|
|
|
|
|
|
-(defn- leave-focus
|
|
|
- []
|
|
|
- (when-let [input (gdom/getElement "search-field")]
|
|
|
- (.blur input)))
|
|
|
-
|
|
|
(defonce search-timeout (atom nil))
|
|
|
|
|
|
(rum/defc search-auto-complete
|
|
@@ -165,14 +160,15 @@
|
|
|
(concat new-page pages files blocks))
|
|
|
result (if (= search-mode :graph)
|
|
|
[{:type :graph-add-filter}]
|
|
|
- result)]
|
|
|
+ result)
|
|
|
+ repo (state/get-current-repo)]
|
|
|
[:div
|
|
|
(ui/auto-complete
|
|
|
result
|
|
|
{:class "search-results"
|
|
|
:on-chosen (fn [{:keys [type data alias]}]
|
|
|
+ (search-handler/add-search-to-recent! repo search-q)
|
|
|
(search-handler/clear-search!)
|
|
|
- (leave-focus)
|
|
|
(case type
|
|
|
:graph-add-filter
|
|
|
(state/add-graph-search-filter! search-q)
|
|
@@ -201,6 +197,7 @@
|
|
|
:query-params {:anchor (str "ls-block-" (:block/uuid data))}}))))
|
|
|
nil))
|
|
|
:on-shift-chosen (fn [{:keys [type data alias]}]
|
|
|
+ (search-handler/add-search-to-recent! repo search-q)
|
|
|
(case type
|
|
|
:page
|
|
|
(let [data (or alias data)
|
|
@@ -266,6 +263,71 @@
|
|
|
(search-handler/clear-search!)))}
|
|
|
(t :more)]])])))
|
|
|
|
|
|
+(rum/defc recent-search-and-pages
|
|
|
+ [in-page-search?]
|
|
|
+ [:div.recent-search
|
|
|
+ [:div.px-4.py-2.text-sm.opacity-70.flex.flex-row.justify-between.align-items
|
|
|
+ [:div "Recent search:"]
|
|
|
+ (ui/tippy {:html [:div.text-sm.font-medium
|
|
|
+ "Shortcut: "
|
|
|
+ [:code (util/->platform-shortcut "Ctrl + Shift + k")]]
|
|
|
+ :interactive true
|
|
|
+ :arrow true}
|
|
|
+ [:div.flex-row.flex.align-items
|
|
|
+ [:div.mr-2 "Search in page:"]
|
|
|
+ [:div {:style {:margin-top 3}}
|
|
|
+ (ui/toggle in-page-search?
|
|
|
+ (fn [_value]
|
|
|
+ (state/set-search-mode! (if in-page-search? :global :page)))
|
|
|
+ true)]])]
|
|
|
+ (let [recent-search (mapv (fn [q] {:type :search :data q}) (db/get-key-value :recent/search))
|
|
|
+ pages (->> (db/get-key-value :recent/pages)
|
|
|
+ (remove nil?)
|
|
|
+ (remove #(= (string/lower-case %) "contents"))
|
|
|
+ (mapv (fn [page] {:type :page :data page})))
|
|
|
+ result (concat (take 5 recent-search) pages)]
|
|
|
+ (ui/auto-complete
|
|
|
+ result
|
|
|
+ {:on-chosen (fn [{:keys [type data]}]
|
|
|
+ (case type
|
|
|
+ :page
|
|
|
+ (route/redirect! {:to :page
|
|
|
+ :path-params {:name data}})
|
|
|
+ :search
|
|
|
+ (let [q data]
|
|
|
+ (fn []
|
|
|
+ (state/set-q! q)
|
|
|
+ (let [search-mode (state/get-search-mode)
|
|
|
+ opts (if (= :page search-mode)
|
|
|
+ (let [current-page (or (state/get-current-page)
|
|
|
+ (date/today))]
|
|
|
+ {:page-db-id (:db/id (db/entity [:block/name (string/lower-case current-page)]))})
|
|
|
+ {})]
|
|
|
+ (if (= :page search-mode)
|
|
|
+ (search-handler/search (state/get-current-repo) q opts)
|
|
|
+ (search-handler/search (state/get-current-repo) q)))))
|
|
|
+
|
|
|
+ nil))
|
|
|
+ :on-shift-chosen (fn [{:keys [type data]}]
|
|
|
+ (case type
|
|
|
+ :page
|
|
|
+ (let [page data]
|
|
|
+ (when-let [page (db/pull [:block/name (string/lower-case page)])]
|
|
|
+ (state/sidebar-add-block!
|
|
|
+ (state/get-current-repo)
|
|
|
+ (:db/id page)
|
|
|
+ :page
|
|
|
+ {:page page})))
|
|
|
+
|
|
|
+ nil))
|
|
|
+ :item-render (fn [{:keys [type data]}]
|
|
|
+ (case type
|
|
|
+ :search [:div.flex-row.flex.search-item.font-medium
|
|
|
+ svg/search
|
|
|
+ [:span.ml-2 data]]
|
|
|
+ :page (search-result-item "Page" data)
|
|
|
+ nil))}))])
|
|
|
+
|
|
|
(rum/defcs search-modal < rum/reactive
|
|
|
(shortcut/disable-all-shortcuts)
|
|
|
(mixins/event-mixin
|
|
@@ -273,8 +335,7 @@
|
|
|
(mixins/hide-when-esc-or-outside
|
|
|
state
|
|
|
:on-hide (fn []
|
|
|
- (search-handler/clear-search!)
|
|
|
- (leave-focus)))))
|
|
|
+ (search-handler/clear-search!)))))
|
|
|
[state]
|
|
|
(let [search-result (state/sub :search/result)
|
|
|
search-q (state/sub :search/q)
|
|
@@ -288,61 +349,48 @@
|
|
|
500
|
|
|
|
|
|
:else
|
|
|
- 300)]
|
|
|
+ 300)
|
|
|
+ in-page-search? (= search-mode :page)]
|
|
|
(rum/with-context [[t] i18n/*tongue-context*]
|
|
|
- (let [input (::input state)]
|
|
|
- [:div.cp__palette.cp__palette-main
|
|
|
+ (let [input (::input state)]
|
|
|
+ [:div.cp__palette.cp__palette-main
|
|
|
|
|
|
- [:div.input-wrap
|
|
|
- [:input.cp__palette-input.w-full
|
|
|
- {:type "text"
|
|
|
- :auto-focus true
|
|
|
- :placeholder (case search-mode
|
|
|
- :graph
|
|
|
- (t :graph-search)
|
|
|
- :page
|
|
|
- (t :page-search)
|
|
|
- (t :search))
|
|
|
- :auto-complete (if (util/chrome?) "chrome-off" "off") ; off not working here
|
|
|
- :default-value ""
|
|
|
- :on-change (fn [e]
|
|
|
- (when @search-timeout
|
|
|
- (js/clearTimeout @search-timeout))
|
|
|
- (let [value (util/evalue e)]
|
|
|
- (if (string/blank? value)
|
|
|
- (search-handler/clear-search! false)
|
|
|
- (let [search-mode (state/get-search-mode)
|
|
|
- opts (if (= :page search-mode)
|
|
|
- (let [current-page (or (state/get-current-page)
|
|
|
- (date/today))]
|
|
|
- {:page-db-id (:db/id (db/entity [:block/name (string/lower-case current-page)]))})
|
|
|
- {})]
|
|
|
- (state/set-q! value)
|
|
|
- (reset! search-timeout
|
|
|
- (js/setTimeout
|
|
|
+ [:div.input-wrap
|
|
|
+ [:input.cp__palette-input.w-full
|
|
|
+ {:type "text"
|
|
|
+ :auto-focus true
|
|
|
+ :placeholder (case search-mode
|
|
|
+ :graph
|
|
|
+ (t :graph-search)
|
|
|
+ :page
|
|
|
+ (t :page-search)
|
|
|
+ (t :search))
|
|
|
+ :auto-complete (if (util/chrome?) "chrome-off" "off") ; off not working here
|
|
|
+ :default-value ""
|
|
|
+ :on-change (fn [e]
|
|
|
+ (when @search-timeout
|
|
|
+ (js/clearTimeout @search-timeout))
|
|
|
+ (let [value (util/evalue e)]
|
|
|
+ (if (string/blank? value)
|
|
|
+ (search-handler/clear-search! false)
|
|
|
+ (let [search-mode (state/get-search-mode)
|
|
|
+ opts (if (= :page search-mode)
|
|
|
+ (let [current-page (or (state/get-current-page)
|
|
|
+ (date/today))]
|
|
|
+ {:page-db-id (:db/id (db/entity [:block/name (string/lower-case current-page)]))})
|
|
|
+ {})]
|
|
|
+ (state/set-q! value)
|
|
|
+ (reset! search-timeout
|
|
|
+ (js/setTimeout
|
|
|
(fn []
|
|
|
(if (= :page search-mode)
|
|
|
(search-handler/search (state/get-current-repo) value opts)
|
|
|
(search-handler/search (state/get-current-repo) value)))
|
|
|
timeout))))))}]]
|
|
|
-
|
|
|
- [:div.search-results-wrap
|
|
|
- (search-auto-complete search-result search-q false)]]))))
|
|
|
-
|
|
|
-(rum/defcs search < rum/reactive
|
|
|
- {:will-unmount (fn [state]
|
|
|
- (search-handler/clear-search!)
|
|
|
- state)}
|
|
|
- [state]
|
|
|
- (rum/with-context [[t] i18n/*tongue-context*]
|
|
|
- [:div#search.flex-1.flex.p-2
|
|
|
- [:div.inner
|
|
|
- [:label.sr-only {:for "search-field"} (t :search)]
|
|
|
- [:div#search-wrapper.relative.w-full.text-gray-400.focus-within:text-gray-600
|
|
|
- [:a.block.cursor
|
|
|
- {:style {:left 6}
|
|
|
- :on-click #(state/pub-event! [:go/search])}
|
|
|
- svg/search]]]]))
|
|
|
+ [:div.search-results-wrap
|
|
|
+ (if (seq search-result)
|
|
|
+ (search-auto-complete search-result search-q false)
|
|
|
+ (recent-search-and-pages in-page-search?))]]))))
|
|
|
|
|
|
(rum/defc more < rum/reactive
|
|
|
[route]
|