feat: support exact client code match in dropdown search
When typing in the company dropdown search, check for an exact match on client code via Datomic before falling back to Solr name search. This allows users to quickly find clients by typing their code (e.g. NGRV).
This commit is contained in:
@@ -21,25 +21,25 @@
|
|||||||
[:li
|
[:li
|
||||||
[:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"}
|
[:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"}
|
||||||
(if group
|
(if group
|
||||||
[:a {:href "#" :class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
|
[:a {:href "#" :class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
|
||||||
|
|
||||||
:hx-put (bidi/path-for ssr-routes/only-routes
|
:hx-put (bidi/path-for ssr-routes/only-routes
|
||||||
:active-client
|
:active-client
|
||||||
:request-method :put)
|
:request-method :put)
|
||||||
:hx-target "#company-dropdown"
|
:hx-target "#company-dropdown"
|
||||||
:hx-headers (hx/json {"x-clients" (pr-str [:group group])})
|
:hx-headers (hx/json {"x-clients" (pr-str [:group group])})
|
||||||
"@click" (format "globalClientSelection={group: %s}" (hx/json group))
|
"@click" (format "globalClientSelection={group: %s}" (hx/json group))
|
||||||
:hx-swap "outerHTML"
|
:hx-swap "outerHTML"
|
||||||
:hx-trigger "click"}
|
:hx-trigger "click"}
|
||||||
name]
|
name]
|
||||||
[:a {:href "#" :class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
|
[:a {:href "#" :class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
|
||||||
:hx-put (bidi/path-for ssr-routes/only-routes
|
:hx-put (bidi/path-for ssr-routes/only-routes
|
||||||
:active-client
|
:active-client
|
||||||
:request-method :put)
|
:request-method :put)
|
||||||
:hx-target "#company-dropdown"
|
:hx-target "#company-dropdown"
|
||||||
:hx-headers (format "{\"x-clients\": \"[%d]\"}" id)
|
:hx-headers (format "{\"x-clients\": \"[%d]\"}" id)
|
||||||
"@click" (format "globalClientSelection={selected: [%d]}" id)
|
"@click" (format "globalClientSelection={selected: [%d]}" id)
|
||||||
:hx-swap "outerHTML"
|
:hx-swap "outerHTML"
|
||||||
:hx-trigger "click"}
|
:hx-trigger "click"}
|
||||||
name])]])])
|
name])]])])
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
cleansed-search-query (str "name:(" query ")")
|
cleansed-search-query (str "name:(" query ")")
|
||||||
exec-search (fn []
|
exec-search (fn []
|
||||||
(for [n (pull-many (dc/db conn) [:client/name :db/id]
|
(for [n (pull-many (dc/db conn) [:client/name :db/id]
|
||||||
(for [{:keys [id name]} (solr/query solr/impl "clients" {"query" cleansed-search-query
|
(for [{:keys [id name]} (solr/query solr/impl "clients" {"query" cleansed-search-query
|
||||||
"fields" "id, name"})
|
"fields" "id, name"})
|
||||||
:let [client-id (Long/parseLong id)]
|
:let [client-id (Long/parseLong id)]
|
||||||
:when (can-see-client? identity client-id)]
|
:when (can-see-client? identity client-id)]
|
||||||
@@ -61,15 +61,17 @@
|
|||||||
:name (str "All clients matching " (subs query 2))}]
|
:name (str "All clients matching " (subs query 2))}]
|
||||||
|
|
||||||
raw-query
|
raw-query
|
||||||
(let [code-matches (for [n (pull-many (dc/db conn) [:client/name :db/id]
|
(let [exact-code-matches (for [n (pull-many (dc/db conn) [:client/name :db/id]
|
||||||
(for [{:keys [id name]} (solr/query solr/impl "clients" {"query" (format "code:\"%s\"" raw-query)
|
(for [client-id (map first (dc/q '[:find ?e
|
||||||
"fields" "id, name"})
|
:in $ ?code
|
||||||
:let [client-id (Long/parseLong id)]
|
:where [?e :client/code ?code]]
|
||||||
:when (can-see-client? identity client-id)]
|
(dc/db conn)
|
||||||
client-id))]
|
query))
|
||||||
{:id (:db/id n)
|
:when (can-see-client? identity client-id)]
|
||||||
:name (:client/name n)})]
|
client-id))]
|
||||||
(or (seq code-matches) (exec-search)))
|
{:id (:db/id n)
|
||||||
|
:name (:client/name n)})]
|
||||||
|
(or (seq exact-code-matches) (exec-search)))
|
||||||
|
|
||||||
cleansed-query
|
cleansed-query
|
||||||
(exec-search))))
|
(exec-search))))
|
||||||
@@ -93,7 +95,7 @@
|
|||||||
[:div
|
[:div
|
||||||
[:button#company-dropdown-button {:class "text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
[:button#company-dropdown-button {:class "text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||||
"x-tooltip.on.click" "{content: ()=>$refs.tooltip.innerHTML, theme: 'light', onMount(i) { htmx.process(i.popper); }, allowHTML: true, interactive:true}"
|
"x-tooltip.on.click" "{content: ()=>$refs.tooltip.innerHTML, theme: 'light', onMount(i) { htmx.process(i.popper); }, allowHTML: true, interactive:true}"
|
||||||
:type "button"}
|
:type "button"}
|
||||||
(cond
|
(cond
|
||||||
(= :mine client-selection)
|
(= :mine client-selection)
|
||||||
"My Companies"
|
"My Companies"
|
||||||
@@ -119,43 +121,43 @@
|
|||||||
svg/search]]
|
svg/search]]
|
||||||
[:input#company-search {:placeholder "Company name"
|
[:input#company-search {:placeholder "Company name"
|
||||||
:x-ref "company"
|
:x-ref "company"
|
||||||
:name "search-text"
|
:name "search-text"
|
||||||
:class "block w-full p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
:class "block w-full p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||||
:autoFocus true
|
:autoFocus true
|
||||||
:tab-index -1
|
:tab-index -1
|
||||||
:hx-trigger "keyup changed delay:500ms, search"
|
:hx-trigger "keyup changed delay:500ms, search"
|
||||||
:hx-get (bidi/path-for ssr-routes/only-routes
|
:hx-get (bidi/path-for ssr-routes/only-routes
|
||||||
:company-dropdown-search-results)
|
:company-dropdown-search-results)
|
||||||
:hx-target "#company-search-results"
|
:hx-target "#company-search-results"
|
||||||
:hx-swap "innerHTML"}]]
|
:hx-swap "innerHTML"}]]
|
||||||
[:input#company-search-value {:type "hidden"
|
[:input#company-search-value {:type "hidden"
|
||||||
:name "x-clients"}]]
|
:name "x-clients"}]]
|
||||||
[:div.divide-y.divide-gray-100
|
[:div.divide-y.divide-gray-100
|
||||||
[:div#company-search-results {:class "h-48 px-3 pb-3 overflow-y-auto text-sm text-gray-700 dark:text-gray-200"}]
|
[:div#company-search-results {:class "h-48 px-3 pb-3 overflow-y-auto text-sm text-gray-700 dark:text-gray-200"}]
|
||||||
(when (= "admin" (:user/role identity))
|
(when (= "admin" (:user/role identity))
|
||||||
[:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"}
|
[:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"}
|
||||||
|
|
||||||
[:button {:class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
|
[:button {:class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
|
||||||
:hx-put (bidi/path-for ssr-routes/only-routes
|
:hx-put (bidi/path-for ssr-routes/only-routes
|
||||||
:active-client
|
:active-client
|
||||||
:request-method :put)
|
:request-method :put)
|
||||||
:hx-target "#company-dropdown"
|
:hx-target "#company-dropdown"
|
||||||
|
|
||||||
"@click" "globalClientSelection=\"mine\""
|
"@click" "globalClientSelection=\"mine\""
|
||||||
:hx-headers "{\"x-clients\": \":mine\"}"
|
:hx-headers "{\"x-clients\": \":mine\"}"
|
||||||
:hx-swap "outerHTML"
|
:hx-swap "outerHTML"
|
||||||
:hx-trigger "click"}
|
:hx-trigger "click"}
|
||||||
"Mine"]])
|
"Mine"]])
|
||||||
[:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"}
|
[:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"}
|
||||||
|
|
||||||
[:button {:class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
|
[:button {:class "w-full py-2 ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300"
|
||||||
:hx-put (bidi/path-for ssr-routes/only-routes
|
:hx-put (bidi/path-for ssr-routes/only-routes
|
||||||
:active-client
|
:active-client
|
||||||
:request-method :put)
|
:request-method :put)
|
||||||
:hx-target "#company-dropdown"
|
:hx-target "#company-dropdown"
|
||||||
"@click" "globalClientSelection=\"all\""
|
"@click" "globalClientSelection=\"all\""
|
||||||
:hx-headers "{\"x-clients\": \":all\"}"
|
:hx-headers "{\"x-clients\": \":all\"}"
|
||||||
:hx-swap "outerHTML"
|
:hx-swap "outerHTML"
|
||||||
:hx-trigger "click"}
|
:hx-trigger "click"}
|
||||||
"All"]]]]]
|
"All"]]]]]
|
||||||
[:script {:lang "text/javascript"}
|
[:script {:lang "text/javascript"}
|
||||||
@@ -188,7 +190,7 @@ function initCompanyDropdown() {
|
|||||||
(defn active-client [{:keys [identity params] :as request}]
|
(defn active-client [{:keys [identity params] :as request}]
|
||||||
(assoc
|
(assoc
|
||||||
(html-response
|
(html-response
|
||||||
(dropdown {:client-selection (:client-selection request)
|
(dropdown {:client-selection (:client-selection request)
|
||||||
:clients (:clients request)
|
:clients (:clients request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
:identity identity}))
|
:identity identity}))
|
||||||
|
|||||||
Reference in New Issue
Block a user