171 lines
7.7 KiB
Clojure
171 lines
7.7 KiB
Clojure
(ns auto-ap.ssr.company-dropdown
|
|
(:require [auto-ap.datomic :refer [conn pull-attr pull-many]]
|
|
[auto-ap.graphql.utils :refer [cleanse-query]]
|
|
[auto-ap.solr :as solr]
|
|
[auto-ap.ssr-routes :as ssr-routes]
|
|
[auto-ap.ssr.hx :as hx]
|
|
[auto-ap.ssr.svg :as svg]
|
|
[auto-ap.ssr.utils :refer [html-response]]
|
|
[bidi.bidi :as bidi]
|
|
[clojure.string :as str]
|
|
[datomic.api :as dc]
|
|
[hiccup2.core :as hiccup]
|
|
[iol-ion.query :refer [can-see-client?]]))
|
|
|
|
(defn dropdown-search-results* [{:keys [options]}]
|
|
[:ul
|
|
(for [{:keys [id name group]} options]
|
|
[: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"
|
|
|
|
: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])})
|
|
: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"
|
|
:hx-headers (format "{\"x-clients\": \"[%d]\"}" id)
|
|
:hx-swap "outerHTML"
|
|
:hx-trigger "click"}
|
|
name])]])])
|
|
|
|
|
|
|
|
|
|
(defn get-clients [identity query]
|
|
(if (str/starts-with? query "g:")
|
|
(let [search-query (str "groups:(" (subs query 2) ")")]
|
|
[{:group (subs query 2)
|
|
:name (str "All clients matching " (subs query 2))}])
|
|
(if-let [query (not-empty (cleanse-query query))]
|
|
(let [search-query (str "name:(" query ")")]
|
|
|
|
(for [n (pull-many (dc/db conn) [:client/name :db/id]
|
|
(for [{:keys [id name]} (solr/query solr/impl "clients" {"query" search-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)}))
|
|
[])))
|
|
|
|
(defn dropdown-search-results [{:keys [identity] :as request}]
|
|
(html-response
|
|
(dropdown-search-results* {:options (get-clients identity (get (:query-params request) "search-text"))})))
|
|
|
|
(defn dropdown [{:keys [client-selection client identity clients]}]
|
|
[:div#company-dropdown
|
|
[:script
|
|
(hiccup/raw
|
|
"localStorage.setItem(\"last-client-id\", \"" (:db/id client) "\")" "\n"
|
|
"localStorage.setItem(\"last-selected-clients\", " (pr-str (pr-str client-selection)) ")")]
|
|
[: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"
|
|
:type "button"}
|
|
(cond
|
|
(= :mine client-selection)
|
|
"My Companies"
|
|
(= :all client-selection)
|
|
"All Companies"
|
|
|
|
(and client
|
|
(= 1 (count clients)))
|
|
( :client/name client)
|
|
|
|
:else
|
|
(str (count clients) " Companies"))
|
|
[:div.w-4.h-4.ml-2
|
|
svg/drop-down]]
|
|
[:div#company-dropdown-list.hidden {"_" (hiccup/raw "init call initCompanyDropdown()")}
|
|
[:div {:class "z-10 bg-white rounded-lg shadow w-64 dark:bg-gray-700 slide-up duration-500 transition-all"}
|
|
[:div {:class "p-3"}
|
|
[:label {:for "input-group-search", :class "sr-only"} "Search"]
|
|
[:div {:class "relative"}
|
|
[:div {:class "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none"}
|
|
[:div.w-5.h-5.text-gray-500.dark:text-gray-400
|
|
svg/search]]
|
|
[:input#company-search {:placeholder "Company name"
|
|
: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"
|
|
:hx-headers "{\"x-clients\": \":mine\"}"
|
|
: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"
|
|
:hx-headers "{\"x-clients\": \":all\"}"
|
|
:hx-swap "outerHTML"
|
|
:hx-trigger "click"}
|
|
"All"]]]]]
|
|
[:script {:lang "text/javascript"}
|
|
(hiccup/raw
|
|
"
|
|
function initCompanyDropdown() {
|
|
var $dropdownTargetEl = document.getElementById('company-dropdown-list');
|
|
|
|
// set the element that trigger the dropdown menu on click
|
|
var $dropdownTriggerEl = document.getElementById('company-dropdown-button');
|
|
|
|
var dropdownOptions = {
|
|
placement: 'bottom',
|
|
triggerType: 'click',
|
|
offsetSkidding: 0,
|
|
offsetDistance: 10,
|
|
delay: 300,
|
|
onHide: () => {
|
|
},
|
|
onShow: () => {
|
|
document.getElementById('company-search').focus()
|
|
},
|
|
onToggle: () => {
|
|
}
|
|
};
|
|
var companyDrowdown = new Dropdown($dropdownTargetEl, $dropdownTriggerEl, dropdownOptions);
|
|
}
|
|
")]]])
|
|
|
|
(defn active-client [{:keys [identity params] :as request}]
|
|
(assoc
|
|
(html-response
|
|
(dropdown {:client-selection (:client-selection (:session request))
|
|
:clients (:clients request)
|
|
:client (:client request)
|
|
:identity identity}))
|
|
:headers
|
|
{"hx-trigger" "clientSelected"}))
|
|
|