From 5b2aba561cd21239460beb7d20e8e6ed247ad2d2 Mon Sep 17 00:00:00 2001 From: Bryce Date: Sat, 23 May 2026 13:24:40 -0700 Subject: [PATCH] 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). --- src/clj/auto_ap/ssr/company_dropdown.clj | 96 ++++++++++++------------ 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/src/clj/auto_ap/ssr/company_dropdown.clj b/src/clj/auto_ap/ssr/company_dropdown.clj index e4f0ba4e..26e193df 100644 --- a/src/clj/auto_ap/ssr/company_dropdown.clj +++ b/src/clj/auto_ap/ssr/company_dropdown.clj @@ -21,25 +21,25 @@ [:li [:div {:class "flex items-center pl-2 rounded hover:bg-green-100 dark:hover:bg-green-600"} (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 - :active-client - :request-method :put) - :hx-target "#company-dropdown" + :hx-put (bidi/path-for ssr-routes/only-routes + :active-client + :request-method :put) + :hx-target "#company-dropdown" :hx-headers (hx/json {"x-clients" (pr-str [:group group])}) "@click" (format "globalClientSelection={group: %s}" (hx/json group)) - :hx-swap "outerHTML" + :hx-swap "outerHTML" :hx-trigger "click"} name] - [: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 - :active-client - :request-method :put) - :hx-target "#company-dropdown" + [: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 + :active-client + :request-method :put) + :hx-target "#company-dropdown" :hx-headers (format "{\"x-clients\": \"[%d]\"}" id) "@click" (format "globalClientSelection={selected: [%d]}" id) - :hx-swap "outerHTML" + :hx-swap "outerHTML" :hx-trigger "click"} name])]])]) @@ -49,7 +49,7 @@ cleansed-search-query (str "name:(" query ")") exec-search (fn [] (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"}) :let [client-id (Long/parseLong id)] :when (can-see-client? identity client-id)] @@ -61,15 +61,17 @@ :name (str "All clients matching " (subs query 2))}] raw-query - (let [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) - "fields" "id, name"}) - :let [client-id (Long/parseLong id)] - :when (can-see-client? identity client-id)] - client-id))] - {:id (:db/id n) - :name (:client/name n)})] - (or (seq code-matches) (exec-search))) + (let [exact-code-matches (for [n (pull-many (dc/db conn) [:client/name :db/id] + (for [client-id (map first (dc/q '[:find ?e + :in $ ?code + :where [?e :client/code ?code]] + (dc/db conn) + query)) + :when (can-see-client? identity client-id)] + client-id))] + {:id (:db/id n) + :name (:client/name n)})] + (or (seq exact-code-matches) (exec-search))) cleansed-query (exec-search)))) @@ -93,7 +95,7 @@ [: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" "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 (= :mine client-selection) "My Companies" @@ -119,43 +121,43 @@ svg/search]] [:input#company-search {:placeholder "Company name" :x-ref "company" - :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" - :autoFocus true - :tab-index -1 - :hx-trigger "keyup changed delay:500ms, search" - :hx-get (bidi/path-for ssr-routes/only-routes - :company-dropdown-search-results) - :hx-target "#company-search-results" - :hx-swap "innerHTML"}]] - [:input#company-search-value {:type "hidden" - :name "x-clients"}]] + :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" + :autoFocus true + :tab-index -1 + :hx-trigger "keyup changed delay:500ms, search" + :hx-get (bidi/path-for ssr-routes/only-routes + :company-dropdown-search-results) + :hx-target "#company-search-results" + :hx-swap "innerHTML"}]] + [:input#company-search-value {:type "hidden" + :name "x-clients"}]] [: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"}] (when (= "admin" (:user/role identity)) [: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" - :hx-put (bidi/path-for ssr-routes/only-routes - :active-client - :request-method :put) - :hx-target "#company-dropdown" + [: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 + :active-client + :request-method :put) + :hx-target "#company-dropdown" "@click" "globalClientSelection=\"mine\"" :hx-headers "{\"x-clients\": \":mine\"}" - :hx-swap "outerHTML" + :hx-swap "outerHTML" :hx-trigger "click"} "Mine"]]) [: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" - :hx-put (bidi/path-for ssr-routes/only-routes - :active-client - :request-method :put) - :hx-target "#company-dropdown" + [: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 + :active-client + :request-method :put) + :hx-target "#company-dropdown" "@click" "globalClientSelection=\"all\"" :hx-headers "{\"x-clients\": \":all\"}" - :hx-swap "outerHTML" + :hx-swap "outerHTML" :hx-trigger "click"} "All"]]]]] [:script {:lang "text/javascript"} @@ -188,7 +190,7 @@ function initCompanyDropdown() { (defn active-client [{:keys [identity params] :as request}] (assoc (html-response - (dropdown {:client-selection (:client-selection request) + (dropdown {:client-selection (:client-selection request) :clients (:clients request) :client (:client request) :identity identity}))