other pages

This commit is contained in:
Bryce
2023-05-18 22:14:23 -07:00
parent 33fc70295b
commit 33cae26cc1
9 changed files with 349 additions and 222 deletions

View File

@@ -579,12 +579,14 @@
(defn add-sorter-fields [q sort-map args]
(reduce
(fn [q {:keys [sort-key]}]
(fn [q {:keys [sort-key] :as z}]
(prn z)
(println (class sort-key))
(merge-query q
{:query {:find [(symbol (str "?sort-" sort-key))]
:where (sort-map
sort-key
(println "Warning, trying to sort by unsupported field" sort-key))}}))
(println "Warning, trying to sort by unsupported field" sort-key, "sort map" (pr-str sort-map)))}}))
q
(:sort args)))

View File

@@ -59,6 +59,7 @@
(map :db/id (:report/client r))))))))
(defn get-graphql [args]
(clojure.pprint/pprint args)
(let [db (dc/db conn)
{ids-to-retrieve :ids matching-count :count} (raw-graphql-ids db args)]

View File

@@ -3,120 +3,81 @@
[amazonica.aws.s3 :as s3]
[auto-ap.datomic :refer [conn]]
[auto-ap.datomic.reports :as r]
[auto-ap.graphql.utils :refer [assert-admin is-admin?]]
[auto-ap.graphql.utils :refer [assert-can-see-client is-admin?]]
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper]
[auto-ap.ssr.svg :as svg]
[auto-ap.ssr.ui :refer [base-page]]
[auto-ap.ssr.utils :refer [html-response]]
[auto-ap.time :as atime]
[bidi.bidi :as bidi]
[config.core :refer [env]]
[datomic.api :as dc]
[hiccup2.core :as hiccup]))
[datomic.api :as dc]))
(defn row* [{:keys [flash? report identity delete-after-settle?]}]
(com/data-grid-row
{:class (when flash?
"live-added")
"_" (hiccup/raw (when delete-after-settle?" on htmx:afterSettle wait 400ms then remove me"))}
(com/data-grid-cell
{}
(:report/name report))
(com/data-grid-cell
{}
(when (:report/creator report)
(com/pill {:color :primary }
(:report/creator report))))
(com/data-grid-cell
{}
(atime/unparse-local (:report/created report)
atime/normal-date))
(com/data-grid-right-stack-cell
{}
(com/a-icon-button {:href (:report/url report)}
svg/download)
(when (is-admin? identity)
[:form
[:input {:type :hidden :name "id" :value (:db/id report)}]
(com/icon-button {:hx-delete (str (bidi/path-for ssr-routes/only-routes
:company-reports-delete
:request-method :delete))
:hx-target "closest tr"}
svg/trash)]))))
(def grid-page {:id "report-table"
:nav (com/company-aside-nav)
:id-fn :db/id
:fetch-page (fn [user args]
(r/get-graphql (into args {:id user})))
:breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes
:company)}
"My Company"]
(defn table* [{:keys [client start per-page identity session flash-id]}]
(let [start (or start 0)
per-page (or per-page 30)
[reports total] (r/get-graphql {:id identity
:start start
:per-page per-page
:client-id (:db/id client)
:sort nil})]
(com/data-grid-card {:id "report-table"
:title "Reports"
:entity-name "reports"
:route :company-reports-table
:start start
:per-page per-page
:total total
:action-buttons [(com/button {:color :primary}
(com/button-icon {} svg/refresh)
"Add new product")
(com/button {:color :secondary}
(com/button-icon {} svg/refresh)
"Update stocks 1/250")
(com/icon-button {}
svg/upload)]
:rows (for [report reports]
(row* {:report report
:flash? (= flash-id
(:db/id report))
:identity identity}))
:headers [(com/data-grid-header {} "Name")
(com/data-grid-header {:class "hidden md:table-cell"} "Created by")
(com/data-grid-header {:class "hidden md:table-cell"} "Created")
(com/data-grid-header {})]})))
[:a {:href (bidi/path-for ssr-routes/only-routes
:company-reports)}
"Reports"]]
:title "Reports"
:entity-name "Reports"
:route :company-reports-table
:action-buttons (fn [user]
nil)
:row-buttons (fn [user e]
(com/a-icon-button {:href (:report/url e)}
svg/download)[
(when (is-admin? user)
(com/icon-button {:hx-delete (str (bidi/path-for ssr-routes/only-routes
:company-reports-delete
:request-method :delete))
:hx-target "closest tr"}
svg/trash))])
:headers [{:key "name"
:name "Name"
:sort-key "name"
:render :report/name}
{:key "created-by"
:name "Created by"
:sort-key "creator"
:render (fn [report]
(when (:report/creator report)
(com/pill {:color :primary }
(:report/creator report))))}
{:key "created"
:name "Created"
:sort-key "created"
:render #(atime/unparse-local (:report/created %)
atime/normal-date)}]})
(defn delete-report [{:keys [query-params hx-query-params form-params identity session] :as request}]
(def row* (partial helper/row* grid-page))
(def table* (partial helper/table* grid-page))
(def table (partial helper/table grid-page))
(def page (partial helper/page grid-page))
(defn delete-report [{:keys [form-params identity]}]
(let [[id-to-delete key] (first (dc/q '[:find ?i ?k
:in $ ?i
:where [?i :report/key ?k]]
(dc/db conn)
(some-> (get form-params "id") not-empty Long/parseLong)))
report (dc/pull (dc/db conn) r/default-read id-to-delete)]
(assert-can-see-client identity (:report/client report))
(when id-to-delete
(s3/delete-object :bucket-name (:data-bucket env)
:key key)
@(dc/transact conn [[:db/retractEntity id-to-delete]]))
(html-response
(row* {:report report
:flash? true
:identity identity
(row* identity
report
{:flash? true
:delete-after-settle? true}))))
(defn reports-table [{:keys [query-params hx-query-params identity session] :as request}]
(html-response (table* {:client (:client (:session request))
:start (some-> (or (get query-params "start") (get hx-query-params "start")) not-empty (Long/parseLong ))
:per-page (some-> (or (get query-params "per-page") (get hx-query-params "per-page")) not-empty (Long/parseLong ))
:identity identity
:session session})
:headers {"hx-push-url" (str "?start=" (get (:query-params request) "start"))}))
(defn page [{:keys [query-params hx-query-params identity session] :as request}]
(base-page
request
(com/page {:nav (com/company-aside-nav)
:active-client (:client (:session request))
:identity (:identity request)}
(com/breadcrumbs {}
[:a {:href (bidi/path-for ssr-routes/only-routes
:company)} "My Company"]
[:a {:href {:href (bidi/path-for ssr-routes/only-routes
:company-reports)}} "Reports"])
(table* {:client (:client (:session request))
:start (some-> (or (get query-params "start") (get hx-query-params "start")) not-empty (Long/parseLong ))
:per-page (some-> (or (get query-params "per-page") (get hx-query-params "per-page")) not-empty (Long/parseLong ))
:identity identity
:session session}))
nil))

View File

@@ -7,6 +7,7 @@
[auto-ap.ssr.components :as com]
[auto-ap.ssr.svg :as svg]
[auto-ap.ssr.ui :refer [base-page]]
[auto-ap.ssr.grid-page-helper :as helper]
[auto-ap.ssr.utils :refer [html-response]]
[auto-ap.time :as atime]
[auto-ap.yodlee.core2 :as yodlee]
@@ -15,89 +16,6 @@
[datomic.api :as dc]
[hiccup2.core :as hiccup]))
(defn row* [{:keys [flash? yodlee-provider-account identity delete-after-settle?]}]
(com/data-grid-row
{:class (when flash?
"live-added")
"_" (hiccup/raw (when delete-after-settle?" on htmx:afterSettle wait 400ms then remove me"))}
(com/data-grid-cell
{}
(:yodlee-provider-account/id yodlee-provider-account))
(com/data-grid-cell
{}
(when-let [status (:yodlee-provider-account/status yodlee-provider-account)]
(com/pill {:color (if (not= status "SUCCESS")
:yellow
:primary) }
status)))
(com/data-grid-cell
{}
(when-let [status (:yodlee-provider-account/detailed-status yodlee-provider-account)]
status)
)
(com/data-grid-cell
{}
(atime/unparse-local (:yodlee-provider-account/last-updated yodlee-provider-account)
atime/normal-date))
(com/data-grid-cell
{}
[:ul
(for [a (:yodlee-provider-account/accounts yodlee-provider-account)]
[:li (:yodlee-account/name a) " - " (:yodlee-account/number a) #_[:div.tag (->$ (:available-balance a))]])])
(com/data-grid-right-stack-cell
{}
(when (is-admin? identity)
[:form
[:input {:type :hidden :name "id" :value (:db/id yodlee-provider-account)}]
(com/icon-button {:hx-put (bidi/path-for ssr-routes/only-routes
:company-yodlee-provider-account-refresh)
:hx-target "closest tr"}
svg/refresh)])
#_(when (is-admin? identity)
[:form
[:input {:type :hidden :name "id" :value (:db/id report)}]
(com/icon-button {:hx-delete (str (bidi/path-for ssr-routes/only-routes
:company-reports-delete
:request-method :delete))
:hx-target "closest tr"}
svg/trash)]))))
(defn table* [{:keys [identity start per-page client flash-id]}]
(let [start (or start 0)
per-page (or per-page 30)
[yodlee-provider-accounts total] (yodlee2/get-graphql {:id identity
:start start
:per-page per-page
:client-id (:db/id client)
:sort nil})]
[:div
(com/data-grid-card {:id "yodlee-table"
:title "Yodlee Accounts"
:entity-name "Yodlee accounts"
:route :company-yodlee-table
:start start
:per-page per-page
:total total
:action-buttons [(com/button {:color :primary
:on-click "openFastlink()"
:hx-get (bidi/path-for ssr-routes/only-routes
:company-yodlee-fastlink-dialog)
:hx-target "#modal-holder"}
(com/button-icon {} svg/refresh)
"Link new account")]
:rows (for [yodlee-provider-account yodlee-provider-accounts]
(row* {:yodlee-provider-account yodlee-provider-account
:flash? (= flash-id
(:db/id yodlee-provider-account))
:identity identity}))
:headers [(com/data-grid-header {} "Provider Account")
(com/data-grid-header {} "Status")
(com/data-grid-header {} "Detailed Status")
(com/data-grid-header {} "Last Updated")
(com/data-grid-header {:class "hidden md:table-cell"} "Accounts")
(com/data-grid-header {})]})]))
(def default-read '[:db/id
:yodlee-provider-account/last-updated
:yodlee-provider-account/status
@@ -106,14 +24,7 @@
{:yodlee-provider-account/accounts [:yodlee-account/name :yodlee-account/number]
:yodlee-provider-account/client [:client/code]}])
(defn refresh-provider-account [{:keys [form-params identity]}]
(let [provider-account (dc/pull (dc/db conn) default-read (some-> (get form-params "id") not-empty Long/parseLong))]
(yodlee/refresh-provider-account (:client/code (:yodlee-provider-account/client provider-account))
(:yodlee-provider-account/id provider-account))
(html-response
(row* {:yodlee-provider-account provider-account
:flash? true
:identity identity}))))
(defn fastlink-dialog [{:keys [session]}]
(html-response
@@ -136,33 +47,77 @@ fastlink.open({fastLinkURL: '%s',
]
[:div]))))
(def grid-page {:id "yodlee-table"
:nav (com/company-aside-nav)
:id-fn :db/id
:fetch-page (fn [user args]
(yodlee2/get-graphql (assoc args :id user)))
:breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes
:company)}
"My Company"]
(defn table [{:keys [query-params hx-query-params identity session] :as request}]
(html-response (table* {:client (:client (:session request))
:start (some-> (or (get query-params "start") (get hx-query-params "start")) not-empty (Long/parseLong ))
:per-page (some-> (or (get query-params "per-page") (get hx-query-params "per-page")) not-empty (Long/parseLong ))
:identity identity
:session session})
:headers {"hx-push-url" (str "?start=" (get (:query-params request) "start"))}))
[:a {:href (bidi/path-for ssr-routes/only-routes
:company-yodlee)}
"Yodlee"]]
:title "Yodlee Accounts"
:entity-name "Yodlee accounts"
:route :company-yodlee-table
:action-buttons (fn [user]
[(com/button {:color :primary
:on-click "openFastlink()"
:hx-get (bidi/path-for ssr-routes/only-routes
:company-yodlee-fastlink-dialog)
:hx-target "#modal-holder"}
(com/button-icon {} svg/refresh)
"Link new account")])
:row-buttons (fn [user e]
[(when (is-admin? user)
(com/icon-button {:hx-put (bidi/path-for ssr-routes/only-routes
:company-yodlee-provider-account-refresh)
:hx-target "closest tr"}
svg/refresh))])
:headers [{:key "provider-account"
:name "Provider Account"
:sort-key "provider-account"
:render :yodlee-provider-account/id}
{:key "status"
:name "Status"
:sort-key "status"
:render #(when-let [status (:yodlee-provider-account/status %)]
(com/pill {:color (if (not= status "SUCCESS")
:yellow
:primary) }
status))}
{:key "detailed-status"
:name "Detailed Status"
:sort-key "detailed-status"
:render #(when-let [status (:yodlee-provider-account/detailed-status %)]
status)}
(defn page [{:keys [identity matched-route query-params :hx-query-params session] :as request}]
(base-page
request
(com/page {:nav (com/company-aside-nav)
:active-client (:client (:session request))
:identity (:identity request)}
(com/breadcrumbs {}
[:a {:href (bidi/path-for ssr-routes/only-routes
:company)}
"My Company"]
{:key "last-updated"
:name "Last Updated"
:sort-key "last-updated"
:render #(atime/unparse-local (:yodlee-provider-account/last-updated %)
atime/normal-date)}
{:key "accounts"
:name "Accounts"
:show-starting "md"
:render (fn [e]
[:ul
(for [a (:yodlee-provider-account/accounts e)]
[:li (:yodlee-account/name a) " - " (:yodlee-account/number a)])])}]})
[:a {:href (bidi/path-for ssr-routes/only-routes
:company-yodlee)}
"Yodlee"]
)
(table* {:client (:client session)
:start (some-> (or (get query-params "start") (get hx-query-params "start")) not-empty (Long/parseLong ))
:per-page (some-> (or (get query-params "per-page") (get hx-query-params "per-page")) not-empty (Long/parseLong ))
:identity identity
:session session}))
nil))
(def page (partial helper/page grid-page))
(def table (partial helper/table grid-page))
;; TODO delete-after-settle
(defn refresh-provider-account [{:keys [form-params identity]}]
(let [provider-account (dc/pull (dc/db conn) default-read (some-> (get form-params "id") not-empty Long/parseLong))]
(yodlee/refresh-provider-account (:client/code (:yodlee-provider-account/client provider-account))
(:yodlee-provider-account/id provider-account))
(html-response
(helper/row*
grid-page
identity
provider-account
{:flash? true}))))

View File

@@ -37,6 +37,7 @@
(def data-grid data-grid/data-grid-)
(def data-grid-header data-grid/header-)
(def data-grid-sort-header data-grid/sort-header-)
(def data-grid-row data-grid/row-)
(def data-grid-cell data-grid/cell-)
(def data-grid-right-stack-cell data-grid/right-stack-cell-)

View File

@@ -3,11 +3,20 @@
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components.card :refer [content-card-]]
[auto-ap.ssr.components.paginator :refer [paginator-]]
[bidi.bidi :as bidi]))
[bidi.bidi :as bidi]
[hiccup2.core :as hiccup]))
(defn header- [params & rest]
(into [:th.px-4.py-3 {:scope "col" :class (:class params)} ] rest))
(into [:th.px-4.py-3 {:scope "col" :class (:class params)
"_" (hiccup/raw (when (:sort-key params ) (format "on click trigger sorted(key:\"%s\")", (:sort-key params))))}]
(if (:sort-key params)
[(into [:a {:href "#"} ] rest)]
rest)))
(defn sort-header- [params & rest]
[:th.px-4.py-3 {:scope "col" :class (:class params)
"_" (hiccup/raw (format "on click trigger sorted(key:\"%s\")", (:sort-key params)))}
(into [:a {:href "#"} ] rest)])
(defn row- [params & rest]
(into [:tr (update params
@@ -27,9 +36,9 @@
[:input {:id "checkbox-all", :type "checkbox", :class "w-4 h-4 bg-gray-100 border-gray-300 rounded text-primary-600 focus:ring-primary-500 dark:focus:ring-primary-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"}]
[:label {:for "checkbox-all", :class "sr-only"} "checkbox"]]])
(defn data-grid- [{:keys [headers]} & rest]
(defn data-grid- [{:keys [headers thead-params]} & rest]
[:table {:class "w-full text-sm text-left text-gray-500 dark:text-gray-400"}
[:thead {:class "text-xs text-gray-800 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"}
[:thead (assoc thead-params :class "text-xs text-gray-800 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400")
(into
[:tr]
headers)]
@@ -40,9 +49,10 @@
(defn data-grid-card- [{:keys [id
route
title
entity-name
action-buttons
total
subtitle
thead-params
start
per-page
flash-id
@@ -61,13 +71,14 @@
[:h1.text-2xl.mb-3.font-bold title]
[:div {:class "flex items-center flex-1 space-x-4"}
[:h5
[:span (format "Total %s:" entity-name)]
[:span {:class "dark:text-white pl-4"} total]]]]
(when subtitle
[:span subtitle])]]]
(into [:div {:class "flex flex-col flex-shrink-0 space-y-3 md:flex-row md:items-center lg:justify-end md:space-y-0 md:space-x-3"}
]
action-buttons)]
[:div {:class "overflow-x-auto"}
(data-grid- {:headers headers
:thead-params thead-params
}
rows

View File

@@ -33,7 +33,7 @@
:company-yodlee-fastlink-dialog (wrap-client-redirect-unauthenticated (wrap-secure company-yodlee/fastlink-dialog))
:company-yodlee-provider-account-refresh (wrap-client-redirect-unauthenticated (wrap-admin company-yodlee/refresh-provider-account))
:company-reports (wrap-client-redirect-unauthenticated (wrap-secure company-reports/page))
:company-reports-table (wrap-client-redirect-unauthenticated (wrap-secure company-reports/reports-table))
:company-reports-table (wrap-client-redirect-unauthenticated (wrap-secure company-reports/table))
:company-reports-delete (wrap-client-redirect-unauthenticated (wrap-admin company-reports/delete-report))
:transaction-insights (wrap-client-redirect-unauthenticated (wrap-secure insights/page))
:transaction-insight-table (wrap-client-redirect-unauthenticated (wrap-secure insights/insight-table))

View File

@@ -0,0 +1,182 @@
(ns auto-ap.ssr.grid-page-helper
(:require
[auto-ap.ssr.components :as com]
[auto-ap.ssr.ui :refer [base-page]]
[auto-ap.ssr.utils :refer [html-response]]
[hiccup2.core :as hiccup]
[bidi.bidi :as bidi]
[auto-ap.ssr-routes :as ssr-routes]
[cemerick.url :as url]
[clojure.string :as str]
[auto-ap.ssr.svg :as svg]))
(defn row* [gridspec user entity {:keys [flash? delete-after-settle?] :as options}]
(let [cells (mapv (fn [header]
(com/data-grid-cell {}
((:render header) entity)))
(:headers gridspec))
cells (conj cells (com/data-grid-right-stack-cell {}
(into [:form
[:input {:type :hidden :name "id" :value ((:id-fn gridspec) entity)}]]
((:row-buttons gridspec) user entity))))]
(apply com/data-grid-row
{:class (when flash?
"live-added")
"_" (hiccup/raw (when delete-after-settle?
" on htmx:afterSettle wait 400ms then remove me"))
}
cells)))
(defn sort-icon [sort key]
(->> sort
(filter (comp #(= key %) :sort-key))
first
:sort-icon))
(defn sort-by-list [sort]
(if (seq sort)
(into
[:div.flex.gap-2.items-center
"sorted by"
]
(for [{:keys [name sort-icon ]} sort]
[:div.py-1.px-3.text-sm.rounded.bg-gray-100.dark:bg-gray-600.flex.items-center.gap-2.relative name [:div.h-4.w-4.mr-3 sort-icon]
[:div {:class "absolute inline-flex items-center justify-center w-6 h-6 text-xs font-bold text-white hover:scale-110 transition-all duration-300 bg-gray-400 border-2 border-white rounded-full -top-2 -right-2 dark:border-gray-900"}
[:div.h-4.w-4 svg/x]
]]
))
"default sort"))
(defn table* [grid-spec user {:keys [start per-page client flash-id sort]}]
(let [start (or start 0)
per-page (or per-page 30)
[entities total] ((:fetch-page grid-spec)
user
{:start start
:per-page per-page
:client-id (:db/id client)
:sort sort})]
(com/data-grid-card {:id (:id grid-spec)
:title (:title grid-spec)
:route (:route grid-spec)
:start start
:per-page per-page
:total total
:subtitle [:div.flex.items-center.gap-2
[:span (format "Total %s: %d, " (:entity-name grid-spec) total)]
(sort-by-list sort)]
:action-buttons ((:action-buttons grid-spec) user)
:rows (for [entity entities]
(row* grid-spec user entity {:flash? (= flash-id ((:id-fn grid-spec) entity))}))
:thead-params {:hx-get (bidi/path-for ssr-routes/only-routes
(:route grid-spec))
:hx-target (str "#" (:id grid-spec))
:hx-trigger "sorted once"
:hx-vals "js:{\"toggle-sort\": event.detail.key || \"\"}"}
:headers
(conj
(mapv
(fn [h]
(if (:sort-key h)
(com/data-grid-sort-header {:class (if-let [show-starting (:show-starting h)]
(format "hidden %s:table-cell" show-starting)
(:class h))
:sort-key (:sort-key h)}
[:div.flex.gap-4.items-center
(:name h)
[:div.h-6.w-6.text-gray-400.dark:text-gray-500 (sort-icon sort (:sort-key h))]])
(com/data-grid-header {:class (if-let [show-starting (:show-starting h)]
(format "hidden %s:table-cell" show-starting)
(:class h))
:sort-key (:sort-key h)}
(:name h))
))
(:headers grid-spec))
(com/data-grid-header {}))})))
(defn parse-sort [grid-spec q]
(if (not-empty q)
(into []
(map (fn [k]
(let [[k v] (str/split k #":")]
{:sort-key (str k)
:asc (boolean (= "asc" v))
:name (:name (first (filter #(= (str k) (:sort-key %)) (:headers grid-spec))))
:sort-icon (if (= (boolean (= "asc" v)) true)
svg/sort-down
svg/sort-up)}))
(str/split q #",")))
[]))
(defn toggle-sort [grid-spec q k]
(if ((set (map :sort-key q)) k)
(mapv
(fn [s]
(if (= (:sort-key s)
k)
(-> s
(update :asc
#(boolean (not %)))
(update :sort-icon (fn [x]
(if (= x svg/sort-down)
svg/sort-up
svg/sort-down))))
s))
q)
(conj q {:sort-key k
:asc true
:name (:name (first (filter #(= (str k) (:sort-key %)) (:headers grid-spec))))
:sort-icon svg/sort-down})))
(defn sort->query [s]
(str/join "," (map (fn [k] (format "%s:%s" (:sort-key k) (if (= true (:asc k))
"asc"
"desc")))
s)))
(defn params->query-string [q]
(-> q
(dissoc :client :session)
(update :sort sort->query)
(url/map->query)))
(defn extract-params [grid-spec {:keys [query-params hx-query-params identity session] :as request}]
(let [{hx-start "start" hx-per-page "per-page" hx-sort "sort" } hx-query-params
{q-start "start" q-per-page "per-page" q-sort "sort" q-toggle-sort "toggle-sort"} query-params]
(cond-> {}
hx-start (assoc :start (some-> hx-start not-empty (Long/parseLong )))
q-start (assoc :start (some-> q-start not-empty (Long/parseLong )))
hx-per-page (assoc :per-page (some-> hx-per-page not-empty (Long/parseLong )))
q-per-page (assoc :per-page (some-> q-per-page not-empty (Long/parseLong )))
hx-sort (assoc :sort (parse-sort grid-spec hx-sort))
q-sort (assoc :sort (parse-sort grid-spec q-sort))
(not-empty q-toggle-sort) (update :sort #(toggle-sort grid-spec % q-toggle-sort) )
(:session request) (assoc :session (:session request))
(:client (:session request)) (assoc :client (:client (:session request))))))
(defn table [grid-spec {:keys [query-params hx-query-params identity session] :as request}]
(let [params (extract-params grid-spec request)
query-string (params->query-string params)]
(html-response (table*
grid-spec
identity
params
)
:headers {"hx-push-url" (str "?" query-string)})))
(defn page [grid-spec {:keys [identity] :as request}]
(base-page
request
(com/page {:nav (:nav grid-spec)
:active-client (:client (:session request))
:identity (:identity request)}
(apply com/breadcrumbs {} (:breadcrumbs grid-spec))
(table* grid-spec
identity
(extract-params grid-spec request)))
nil))

View File

@@ -293,3 +293,17 @@
[:svg {:xmlns "http://www.w3.org/2000/svg", :viewbox "0 0 24 24"}
[:circle {:cx "12", :cy "12", :r "11.5", :fill "#FFF", :stroke-linecap "round", :stroke-linejoin "round"}]
[:path {:d "M24,12A12,12,0,1,0,12,24,12,12,0,0,0,24,12Zm-7.29,3.28a1,1,0,0,1,0,1.41,1,1,0,0,1-1.42,0l-3.11-3.11a.26.26,0,0,0-.35,0L8.72,16.69a1,1,0,0,1-1.41-1.41l3.11-3.11a.26.26,0,0,0,0-.35L7.31,8.71a1,1,0,0,1,0-1.42,1,1,0,0,1,1.41,0l3.11,3.11a.24.24,0,0,0,.35,0l3.11-3.11a1,1,0,1,1,1.42,1.42L13.6,11.82a.24.24,0,0,0,0,.35Z", :fill "currentColor"}]])
(def sort-down
[:svg {:id "Regular", :xmlns "http://www.w3.org/2000/svg", :viewbox "0 0 24 24"}
[:defs]
[:title "arrow-thick-down-4"]
[:rect {:y "0.75", :rx "3", :stroke "currentColor", :transform "translate(0 24) rotate(-90)", :fill "none", :stroke-linejoin "round", :width "22.5", :stroke-linecap "round", :stroke-width "1.5px", :x "0.75", :ry "3", :height "22.5"}]
[:path {:d "M9.75,6v7.5L6.53,10.28a.75.75,0,0,0-1.28.531v2.068a1.5,1.5,0,0,0,.439,1.06L11.47,19.72a.749.749,0,0,0,1.06,0l5.781-5.781a1.5,1.5,0,0,0,.439-1.06V10.811a.75.75,0,0,0-1.28-.531L14.25,13.5V6a.75.75,0,0,0-.75-.75h-3A.75.75,0,0,0,9.75,6Z", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round", :stroke-width "1.5px"}]])
(def sort-up
[:svg {:id "Regular", :xmlns "http://www.w3.org/2000/svg", :viewbox "0 0 24 24"}
[:defs]
[:title "arrow-thick-up-4"]
[:rect {:y "0.75", :rx "3", :stroke "currentColor", :transform "translate(24 0) rotate(90)", :fill "none", :stroke-linejoin "round", :width "22.5", :stroke-linecap "round", :stroke-width "1.5px", :x "0.75", :ry "3", :height "22.5"}]
[:path {:d "M14.25,18V10.5l3.22,3.22a.75.75,0,0,0,1.28-.531V11.121a1.5,1.5,0,0,0-.439-1.06L12.53,4.28a.749.749,0,0,0-1.06,0L5.689,10.061a1.5,1.5,0,0,0-.439,1.06v2.068a.75.75,0,0,0,1.28.531L9.75,10.5V18a.75.75,0,0,0,.75.75h3A.75.75,0,0,0,14.25,18Z", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round", :stroke-width "1.5px"}]])