makes cloud search possible.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
[auto-ap.ssr.auth :as auth]
|
||||
[auto-ap.ssr.transaction.insights :as insights]
|
||||
[auto-ap.ssr.company.company-1099 :as company-1099]
|
||||
[auto-ap.ssr.search :as search]
|
||||
[auto-ap.ssr.company-dropdown :as company-dropdown]))
|
||||
|
||||
;; from auto-ap.ssr-routes, because they're shared
|
||||
@@ -25,5 +26,6 @@
|
||||
:transaction-insight-table (wrap-client-redirect-unauthenticated (wrap-secure insights/insight-table))
|
||||
:transaction-insight-rows (wrap-client-redirect-unauthenticated (wrap-secure insights/transaction-rows))
|
||||
:transaction-insight-approve (wrap-client-redirect-unauthenticated (wrap-secure insights/approve))
|
||||
:transaction-insight-explain (wrap-client-redirect-unauthenticated (wrap-secure insights/explain))})
|
||||
:transaction-insight-explain (wrap-client-redirect-unauthenticated (wrap-secure insights/explain))
|
||||
:search (wrap-client-redirect-unauthenticated (wrap-secure search/dialog-contents))})
|
||||
|
||||
|
||||
125
src/clj/auto_ap/ssr/search.clj
Normal file
125
src/clj/auto_ap/ssr/search.clj
Normal file
@@ -0,0 +1,125 @@
|
||||
(ns auto-ap.ssr.search
|
||||
(:require
|
||||
[auto-ap.graphql.utils :refer [can-see-client?]]
|
||||
[auto-ap.ssr.utils :refer [html-response]]
|
||||
[auto-ap.time :as atime]
|
||||
[clj-http.client :as client]
|
||||
[clojure.data.json :as json]
|
||||
[clojure.string :as str]
|
||||
[auto-ap.solr :as solr]))
|
||||
|
||||
(defn try-cleanse-date [d]
|
||||
(try
|
||||
(or
|
||||
(some-> (atime/parse-utc d atime/normal-date) (atime/unparse atime/solr-date))
|
||||
(some-> (atime/parse-utc d atime/iso-date) (atime/unparse atime/solr-date))
|
||||
d)
|
||||
(catch Exception _
|
||||
d)))
|
||||
|
||||
(defn try-parse-number [n]
|
||||
(if (re-find #"^[\-]?\d+\.\d+$" n )
|
||||
(str (with-precision 2
|
||||
(some-> n
|
||||
(Double/parseDouble)
|
||||
bigdec
|
||||
(.setScale 2 java.math.RoundingMode/HALF_UP)
|
||||
(double))))
|
||||
n))
|
||||
|
||||
|
||||
(defn q->solr-q [q]
|
||||
(let [matches (re-seq #"(?:\".*?\"|\S)+" q)]
|
||||
(str/join " AND "
|
||||
(->> matches
|
||||
(map (fn [m]
|
||||
(cond (= "payment" m)
|
||||
"type:payment"
|
||||
|
||||
(= "invoice" m)
|
||||
"type:invoice"
|
||||
|
||||
(= "transaction" m)
|
||||
"type:transaction"
|
||||
|
||||
:else
|
||||
(str "_text_:\"" (try-parse-number (try-cleanse-date m)) ""\"))))))))
|
||||
|
||||
|
||||
(defn search-results [q id]
|
||||
(into []
|
||||
(filter (fn [d]
|
||||
(can-see-client? id (first (:client_id d)))))
|
||||
(solr/query (q->solr-q q))))
|
||||
|
||||
|
||||
(defn search-results* [q id]
|
||||
(let [results (search-results q id)]
|
||||
[:div
|
||||
(if (seq results)
|
||||
(for [doc results]
|
||||
[:div.block
|
||||
[:div.card
|
||||
[:div.card-header.has-background-info-light
|
||||
(cond (= "transaction" (:type doc))
|
||||
[:div.card-header-icon.icon-task-list-text-1]
|
||||
|
||||
(= "invoice" (:type doc))
|
||||
[:div.card-header-icon.icon-accounting-invoice-mail]
|
||||
|
||||
(= "payment" (:type doc))
|
||||
[:div.card-header-icon.icon-check-payment-sign])
|
||||
[:div.card-header-title (clojure.string/capitalize (:type doc))
|
||||
" "
|
||||
" "
|
||||
[:span.tags.ml-3
|
||||
[:span.tag.is-warning "client: " (:client_code doc)]
|
||||
[:span.tag.is-info "amount: $" (first (:amount doc))]
|
||||
(when-let [vendor-name (first (:vendor_name doc))]
|
||||
[:span.tag.is-primary "vendor: " vendor-name])]]
|
||||
[:a.card-header-icon.fa.fa-external-link {:href (str "/" (cond (= "invoice"
|
||||
(:type doc))
|
||||
"invoices"
|
||||
|
||||
(= "transaction"
|
||||
(:type doc))
|
||||
"transactions"
|
||||
|
||||
:else
|
||||
"payments") "/?exact-match-id=" (:id doc))
|
||||
:target "_blank"}]
|
||||
]
|
||||
|
||||
|
||||
[:div.card-content
|
||||
[:span
|
||||
|
||||
[:strong (atime/unparse (atime/parse (:date doc) atime/solr-date) atime/normal-date)]
|
||||
": "
|
||||
(str (or (first (:description doc))
|
||||
(first (:number doc))))]]]]
|
||||
)
|
||||
[:div.block "No results found."])]))
|
||||
|
||||
(defn dialog-contents [request]
|
||||
(if-let [q (:q (:params request))]
|
||||
(html-response (search-results* q (:identity request)))
|
||||
(html-response
|
||||
[:div#search {:style {:height "400px" :overflow "auto"}}
|
||||
|
||||
[:div.block
|
||||
[:input#search-input.input {:type "search"
|
||||
:placeholder "5/5/2034 Magheritas"
|
||||
:name "q"
|
||||
:hx-post "/search"
|
||||
:hx-trigger "keyup changed delay:300ms, search"
|
||||
:hx-target "#search-results"
|
||||
:hx-indicator "#search"
|
||||
:value (:q (:params request))
|
||||
:autofocus true}]]
|
||||
[:style
|
||||
".htmx-request #search-results {display: none} .htmx-request .htmx-indicator { display: block !important; }"]
|
||||
[:div#search-results
|
||||
]
|
||||
[:div.loader.is-loading.big.htmx-indicator {:style {:display "none"}}]])))
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
[config.core :refer [env]]
|
||||
[hiccup2.core :as hiccup]))
|
||||
|
||||
(defn html-response [hiccup & {:keys [status] :or {status 200}}]
|
||||
(defn html-response [hiccup & {:keys [status headers] :or {status 200 headers {}}}]
|
||||
{:status status
|
||||
:headers {"Content-Type" "text/html"}
|
||||
:headers (into {"Content-Type" "text/html"}
|
||||
headers)
|
||||
:body (str
|
||||
(hiccup/html
|
||||
{}
|
||||
|
||||
Reference in New Issue
Block a user