gets transaction insights kind of working
This commit is contained in:
1871
data/inference-outcome.csv
Normal file
1871
data/inference-outcome.csv
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,11 +16,22 @@
|
|||||||
(into [:div.htmx-indicator-hidden.inline-flex.gap-2.items-center.justify-center ] children)])
|
(into [:div.htmx-indicator-hidden.inline-flex.gap-2.items-center.justify-center ] children)])
|
||||||
|
|
||||||
(defn icon-button- [params & children]
|
(defn icon-button- [params & children]
|
||||||
(into
|
(into
|
||||||
[:button (update params :class str " inline-flex items-center justify-center bg-white dark:bg-gray-600 items-center p-3 text-sm font-medium border border-gray-300 dark:border-gray-700 text-center text-gray-500 hover:text-gray-800 rounded-lg dark:text-gray-400 dark:hover:text-gray-100")
|
[:button
|
||||||
[:div.htmx-indicator.flex.items-center
|
|
||||||
(svg/spinner {:class "inline w-4 h-4 text-white"})]
|
(update params :class
|
||||||
[:div.htmx-indicator-hidden.inline-flex.gap-2.items-center.justify-center (into [:div.h-4.w-4] children)]]))
|
#(cond-> %
|
||||||
|
true (str " inline-flex items-center justify-center items-center p-3 text-sm font-medium border border-gray-300 dark:border-gray-700 text-center rounded-lg ")
|
||||||
|
(= :secondary (:color params)) (str " bg-blue-500 hover:bg-blue-600 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700")
|
||||||
|
(= :primary (:color params)) (str " bg-green-500 hover:bg-green-600 focus:ring-green-300 dark:bg-green-600 dark:hover:bg-green-700 ")
|
||||||
|
(= :primary-light (:color params)) (str " bg-green-200 hover:bg-green-300 focus:ring-green-200 dark:bg-green-700 dark:hover:bg-green-600 text-gray-800 dark:text-gray-200")
|
||||||
|
(= :secondary-light (:color params)) (str " bg-blue-200 hover:bg-blue-300 focus:ring-blue-200 dark:bg-blue-700 dark:hover:bg-blue-600 text-gray-800 dark:text-gray-200")
|
||||||
|
(= :danger-light (:color params)) (str " bg-red-200 hover:bg-red-300 focus:ring-red-200 dark:bg-red-700 dark:hover:bg-red-600 text-gray-800 dark:text-gray-200")
|
||||||
|
(nil? (:color params))
|
||||||
|
(str " bg-white dark:bg-gray-600 border-gray-300 dark:border-gray-700 text-gray-500 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-100")))
|
||||||
|
[:div.htmx-indicator.flex.items-center
|
||||||
|
(svg/spinner {:class "inline w-4 h-4 text-white"})]
|
||||||
|
[:div.htmx-indicator-hidden.inline-flex.gap-2.items-center.justify-center (into [:div.h-4.w-4] children)]]))
|
||||||
|
|
||||||
(defn a-icon-button- [params & children]
|
(defn a-icon-button- [params & children]
|
||||||
(into
|
(into
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
(defn header- [params & rest]
|
(defn header- [params & rest]
|
||||||
(into [:th.px-4.py-3 {:scope "col" :class (:class params)
|
(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))))}]
|
"_" (hiccup/raw (when (:sort-key params ) (format "on click trigger sorted(key:\"%s\")", (:sort-key params))))
|
||||||
|
:style (:style params)}]
|
||||||
(if (:sort-key params)
|
(if (:sort-key params)
|
||||||
[(into [:a {:href "#"} ] rest)]
|
[(into [:a {:href "#"} ] rest)]
|
||||||
rest)))
|
rest)))
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
:class str " border-b dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700")] rest))
|
:class str " border-b dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700")] rest))
|
||||||
|
|
||||||
(defn cell- [params & rest]
|
(defn cell- [params & rest]
|
||||||
(into [:td.px-4.py-2 {:class (:class params)}] rest))
|
(into [:td.px-4.py-2 params ] rest))
|
||||||
|
|
||||||
(defn right-stack-cell- [params & rest]
|
(defn right-stack-cell- [params & rest]
|
||||||
(cell- params (into [:div.flex.flex-row-reverse.items-center.justify-between
|
(cell- params (into [:div.flex.flex-row-reverse.items-center.justify-between
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ curModal.hide();
|
|||||||
]])
|
]])
|
||||||
|
|
||||||
(defn modal-card- [params header content footer]
|
(defn modal-card- [params header content footer]
|
||||||
[:div#modal-card
|
[:div#modal-card params
|
||||||
[:div {:class "relative bg-white rounded-lg shadow dark:bg-gray-700 dark:text-white fade-in slide-up duration-300 transition-all modal-content"}
|
[:div {:class "relative bg-white rounded-lg shadow dark:bg-gray-700 dark:text-white fade-in slide-up duration-300 transition-all modal-content"}
|
||||||
[:div {:class "flex items-start justify-between p-4 border-b rounded-t dark:border-gray-600"} header]
|
[:div {:class "flex items-start justify-between p-4 border-b rounded-t dark:border-gray-600"} header]
|
||||||
[:div {:class "p-6 space-y-6"}
|
[:div {:class "p-6 space-y-6"}
|
||||||
|
|||||||
@@ -419,3 +419,15 @@
|
|||||||
[:path {:d "M22.629,4.572A6.22,6.22,0,0,1,23,6.5v16a1,1,0,0,1-1,1H2a1,1,0,0,1-1-1V6.5a6.22,6.22,0,0,1,.371-1.928L2.629,1.428A1.6,1.6,0,0,1,4,.5H20a1.6,1.6,0,0,1,1.371.928Z", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round"}]
|
[:path {:d "M22.629,4.572A6.22,6.22,0,0,1,23,6.5v16a1,1,0,0,1-1,1H2a1,1,0,0,1-1-1V6.5a6.22,6.22,0,0,1,.371-1.928L2.629,1.428A1.6,1.6,0,0,1,4,.5H20a1.6,1.6,0,0,1,1.371.928Z", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round"}]
|
||||||
[:line {:x1 "12", :y1 "6", :x2 "12", :y2 "0.5", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round"}]
|
[:line {:x1 "12", :y1 "6", :x2 "12", :y2 "0.5", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round"}]
|
||||||
[:line {:x1 "1.034", :y1 "6", :x2 "22.966", :y2 "6", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round"}]])
|
[:line {:x1 "1.034", :y1 "6", :x2 "22.966", :y2 "6", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round"}]])
|
||||||
|
|
||||||
|
(def thumbs-up
|
||||||
|
[:svg {:xmlns "http://www.w3.org/2000/svg", :viewbox "0 0 24 24"}
|
||||||
|
[:defs]
|
||||||
|
[:title "like"]
|
||||||
|
[:path {:d "M19.5,16.065h0a1.5,1.5,0,0,1,0,3h-1a1.5,1.5,0,0,1,0,3H12c-4,0-3-2-11-2v-9H4a7.949,7.949,0,0,0,7.5-8c0-1.581,3-1.781,3,1.219a31.593,31.593,0,0,1-1,5.781h8a1.5,1.5,0,0,1,0,3h-1a1.5,1.5,0,0,1,0,3h-1", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round"}]])
|
||||||
|
|
||||||
|
(def thumbs-down
|
||||||
|
[:svg {:xmlns "http://www.w3.org/2000/svg", :viewbox "0 0 24 24"}
|
||||||
|
[:defs]
|
||||||
|
[:title "dislike"]
|
||||||
|
[:path {:d "M4.5,8h0a1.5,1.5,0,0,1,0-3h1a1.5,1.5,0,0,1,0-3H12c4,0,3,1.87,11,1.87V13H20a7.811,7.811,0,0,0-7.5,7.856c0,1.582-3,1.813-3-1.187A29.774,29.774,0,0,1,10.5,14h-8a1.5,1.5,0,0,1,0-3h1a1.5,1.5,0,0,1,0-3h1", :fill "none", :stroke "currentColor", :stroke-linecap "round", :stroke-linejoin "round"}]])
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
(ns auto-ap.ssr.transaction.insights
|
(ns auto-ap.ssr.transaction.insights
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.datomic :refer [conn visible-clients]]
|
[auto-ap.datomic :refer [conn visible-clients]]
|
||||||
[auto-ap.shared-views.company.sidebar :refer [company-side-bar]]
|
|
||||||
[auto-ap.ssr-routes :as ssr-routes]
|
[auto-ap.ssr-routes :as ssr-routes]
|
||||||
[auto-ap.ssr.ui :refer [base-page]]
|
[auto-ap.ssr.ui :refer [base-page]]
|
||||||
[auto-ap.ssr.utils :refer [html-response]]
|
[auto-ap.ssr.utils :refer [html-response]]
|
||||||
@@ -10,7 +9,9 @@
|
|||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[datomic.api :as dc]
|
[datomic.api :as dc]
|
||||||
[hiccup2.core :as hiccup]
|
[hiccup2.core :as hiccup]
|
||||||
[clj-time.core :as time]))
|
[auto-ap.ssr.components :as com]
|
||||||
|
[auto-ap.client-routes :as client-routes]
|
||||||
|
[auto-ap.ssr.svg :as svg]))
|
||||||
|
|
||||||
(def pull-expr [:transaction/description-original
|
(def pull-expr [:transaction/description-original
|
||||||
:db/id
|
:db/id
|
||||||
@@ -25,77 +26,84 @@
|
|||||||
|
|
||||||
(defn transaction-recommendations [identity selected-client & {:keys [after]}]
|
(defn transaction-recommendations [identity selected-client & {:keys [after]}]
|
||||||
(let [visible-clients (visible-clients identity)]
|
(let [visible-clients (visible-clients identity)]
|
||||||
(->>
|
(->>
|
||||||
(dc/q '[:find (pull ?t pull-expr)
|
(dc/qseq {:query '[:find (pull ?t pull-expr)
|
||||||
:in $ [?c ...] pull-expr
|
:in $ [?c ...] pull-expr
|
||||||
:where [?t :transaction/recommended-account]
|
:where [?t :transaction/recommended-account]
|
||||||
[?t :transaction/client ?c]
|
[?t :transaction/client ?c]
|
||||||
[?t :transaction/approval-status :transaction-approval-status/unapproved]
|
[?t :transaction/approval-status :transaction-approval-status/unapproved]
|
||||||
(not [?t :transaction/vendor])]
|
(not [?t :transaction/vendor])]
|
||||||
(dc/db conn)
|
:args [(dc/db conn)
|
||||||
(if selected-client
|
(if selected-client
|
||||||
[selected-client]
|
[selected-client]
|
||||||
visible-clients)
|
visible-clients)
|
||||||
pull-expr)
|
pull-expr]})
|
||||||
(map first)
|
(map first)
|
||||||
(sort-by :transaction/date)
|
(sort-by :transaction/date)
|
||||||
(reverse)
|
(reverse)
|
||||||
(drop-while (fn [x]
|
(drop-while (fn [x]
|
||||||
(if after
|
(if after
|
||||||
(not= (Long/parseLong after) (:db/id x))
|
(not= (Long/parseLong after) (:db/id x))
|
||||||
false)))
|
false)))
|
||||||
(#(if after
|
(#(if after
|
||||||
(drop 1 %)
|
(drop 1 %)
|
||||||
%))
|
%))
|
||||||
(take 10)
|
(take 10)
|
||||||
(into []))))
|
(into []))))
|
||||||
|
|
||||||
|
|
||||||
(defn transaction-row [r & {:keys [hide-actions? class last?]}]
|
(defn transaction-row [r & {:keys [hide-actions? class last?]}]
|
||||||
[:tr (cond-> {:class class}
|
(com/data-grid-row
|
||||||
last? (assoc :hx-get (bidi/path-for ssr-routes/only-routes
|
(cond-> {:class class}
|
||||||
:transaction-insight-rows
|
last? (assoc :hx-get (bidi/path-for ssr-routes/only-routes
|
||||||
:after (:db/id r))
|
:transaction-insight-rows
|
||||||
:hx-trigger "intersect once"
|
:after (:db/id r))
|
||||||
:hx-indicator "#insight-table"
|
:hx-trigger "intersect once"
|
||||||
:hx-swap "afterend"))
|
:hx-indicator "#insight-table"
|
||||||
[:td {:style {:width "8em"}}(:client/code (:transaction/client r))]
|
:hx-swap "afterend"))
|
||||||
[:td {:style {:width "10em"}} (:bank-account/code (:transaction/bank-account r))]
|
(com/data-grid-cell {} (:client/code (:transaction/client r)))
|
||||||
[:td {:style {:width "12em"}} (some-> (:transaction/date r) coerce/to-date-time (atime/unparse-local atime/normal-date))]
|
(com/data-grid-cell {} (:bank-account/code (:transaction/bank-account r)))
|
||||||
[:td {:style {:width "30em" :max-width "30em"}} (str (:transaction/description-original r))]
|
(com/data-grid-cell {} (some-> (:transaction/date r) coerce/to-date-time (atime/unparse-local atime/normal-date)))
|
||||||
[:td {:style {:width "10em"}}
|
|
||||||
(if (> (:transaction/amount r) 0.0 )
|
|
||||||
[:div.tag.is-success.is-light (str "$" (Math/round (:transaction/amount r)))]
|
|
||||||
[:div.tag.is-danger.is-light (str "$" (Math/round (:transaction/amount r)))])]
|
|
||||||
[:td {:style {:width "12em"}}
|
|
||||||
[:div [:div.tag (:vendor/name (:transaction/recommended-vendor r))]]
|
|
||||||
[:div [:div.tag (str (:account/numeric-code (:transaction/recommended-account r)) " - " (:account/name (:transaction/recommended-account r)))]]
|
|
||||||
[:div [:div.tag
|
|
||||||
{:class (cond
|
|
||||||
(> (:transaction/account-confidence r) 0.90)
|
|
||||||
"is-success is-light"
|
|
||||||
(> (:transaction/account-confidence r) 0.80)
|
|
||||||
"is-info is-light"
|
|
||||||
|
|
||||||
:else
|
(com/data-grid-cell {} (str (:transaction/description-original r)))
|
||||||
"is-warning is-light")}
|
(com/data-grid-cell {}
|
||||||
(str "%" (Math/round (* 100.0 (:transaction/account-confidence r))))]]]
|
(if (> (:transaction/amount r) 0.0)
|
||||||
[:td
|
[:div.tag.is-success.is-light (str "$" (Math/round (:transaction/amount r)))]
|
||||||
(when-not hide-actions?
|
[:div.tag.is-danger.is-light (str "$" (Math/round (:transaction/amount r)))]))
|
||||||
[:div.buttons
|
(com/data-grid-cell {:style {:width "12em"}}
|
||||||
[:button.button {:hx-post (bidi/path-for ssr-routes/only-routes
|
[:div.flex.gap-2.flex-wrap {:style {:width "12em"}}
|
||||||
:transaction-insight-approve
|
(com/pill {:color :primary} (:vendor/name (:transaction/recommended-vendor r)))
|
||||||
:transaction-id (:db/id r))
|
(com/pill {:color :secondary} (str (:account/numeric-code (:transaction/recommended-account r)) " - " (:account/name (:transaction/recommended-account r))))
|
||||||
:hx-target "closest tr"}
|
(com/pill {:class (cond
|
||||||
[:i.fa.fa-thumbs-up ]]
|
(> (:transaction/account-confidence r) 0.90)
|
||||||
[:button.button
|
"is-success is-light"
|
||||||
[:i.fa.fa-thumbs-down ]]
|
(> (:transaction/account-confidence r) 0.80)
|
||||||
[:a.button {:hx-get (bidi/path-for ssr-routes/only-routes
|
"is-info is-light"
|
||||||
:transaction-insight-explain
|
|
||||||
:transaction-id (:db/id r))
|
:else
|
||||||
:hx-target "#modal-holder"
|
"is-warning is-light")} (str "%" (Math/round (* 100.0 (:transaction/account-confidence r)))))])
|
||||||
:hx-swap "beforeend"}
|
(com/data-grid-right-stack-cell {}
|
||||||
[:i.fa.fa-question ]]])]])
|
(when-not hide-actions?
|
||||||
|
[:form.flex.gap-2
|
||||||
|
[:input {:type :hidden :name "id" :value (:db/id r)}]
|
||||||
|
(com/icon-button {:hx-post (bidi/path-for ssr-routes/only-routes
|
||||||
|
:transaction-insight-approve
|
||||||
|
:transaction-id (:db/id r))
|
||||||
|
:hx-target "closest tr"
|
||||||
|
:color :primary-light}
|
||||||
|
svg/thumbs-up)
|
||||||
|
(com/icon-button {:hx-delete (bidi/path-for ssr-routes/only-routes
|
||||||
|
:transaction-insight-approve
|
||||||
|
:transaction-id (:db/id r))
|
||||||
|
:hx-swap "closest tr"
|
||||||
|
:color :danger-light}
|
||||||
|
svg/thumbs-down)
|
||||||
|
(com/icon-button {:hx-get (bidi/path-for ssr-routes/only-routes
|
||||||
|
:transaction-insight-explain
|
||||||
|
:transaction-id (:db/id r))
|
||||||
|
:hx-target "#modal-holder"
|
||||||
|
:hx-swap "outerHTML"}
|
||||||
|
svg/question)]))))
|
||||||
|
|
||||||
(defn approve [{:keys [identity session] {:keys [transaction-id]} :route-params}]
|
(defn approve [{:keys [identity session] {:keys [transaction-id]} :route-params}]
|
||||||
(html-response (transaction-row
|
(html-response (transaction-row
|
||||||
@@ -108,15 +116,15 @@
|
|||||||
|
|
||||||
(defn explain [{:keys [identity session] {:keys [transaction-id]} :route-params}]
|
(defn explain [{:keys [identity session] {:keys [transaction-id]} :route-params}]
|
||||||
(let [r (dc/pull (dc/db conn)
|
(let [r (dc/pull (dc/db conn)
|
||||||
pull-expr
|
pull-expr
|
||||||
(Long/parseLong transaction-id))
|
(Long/parseLong transaction-id))
|
||||||
similar (->> (dc/q '[:find ?date ?do ?amt
|
similar (->> (dc/q '[:find ?date ?do ?amt
|
||||||
:in $ ?tr
|
:in $ ?tr
|
||||||
:where
|
:where
|
||||||
[(iol-ion.query/recent-date 180) ?start-date]
|
[(iol-ion.query/recent-date 180) ?start-date]
|
||||||
[?tr :transaction/client ?c]
|
[?tr :transaction/client ?c]
|
||||||
[?tr :transaction/recommended-account ?a ]
|
[?tr :transaction/recommended-account ?a]
|
||||||
[?tr :transaction/recommended-vendor ?v ]
|
[?tr :transaction/recommended-vendor ?v]
|
||||||
[?t2 :transaction/client ?c]
|
[?t2 :transaction/client ?c]
|
||||||
[?t2 :transaction/date ?date]
|
[?t2 :transaction/date ?date]
|
||||||
[(>= ?date ?start-date)]
|
[(>= ?date ?start-date)]
|
||||||
@@ -130,38 +138,31 @@
|
|||||||
(take 5)
|
(take 5)
|
||||||
sort
|
sort
|
||||||
reverse)]
|
reverse)]
|
||||||
(html-response [:div.modal.is-active.wide
|
(html-response
|
||||||
[:div.modal-background {"_" (hiccup/raw "on click remove <#modal-holder div/>")}]
|
(com/modal {}
|
||||||
[:div.modal-card
|
(com/modal-card {:style {:width "900px"}}
|
||||||
[:div.modal-card-head
|
[:div.flex [:div.p-2 "Similar Transactions"]]
|
||||||
[:h1.title "Similar transactions"]
|
[:table.w-full
|
||||||
[:div.tags
|
[:thead
|
||||||
[:div.tag.is-large.is-info.is-light (:vendor/name (:transaction/recommended-vendor r))]
|
[:tr
|
||||||
[:div.tag.is-large.is-info.is-light (str (:account/numeric-code (:transaction/recommended-account r)) " - " (:account/name (:transaction/recommended-account r)))]]]
|
[:td "Date"]
|
||||||
[:div.modal-card-body
|
[:td "Description"]
|
||||||
[:table.table
|
[:td "Amount"]]]
|
||||||
[:thead
|
[:tbody
|
||||||
[:tr
|
[:tr
|
||||||
[:td "Date"]
|
[:th.text-left (some-> r :transaction/date coerce/to-date-time (atime/unparse-local atime/normal-date))]
|
||||||
[:td "Description"]
|
[:th.text-left (-> r :transaction/description-original)]
|
||||||
[:td "Amount"]]]
|
[:th.text-left (if (> (-> r :transaction/amount) 0.0)
|
||||||
[:tbody
|
[:div.tag.is-success.is-light (str "$" (Math/round (:transaction/amount r)))]
|
||||||
[:tr
|
[:div.tag.is-danger.is-light (str "$" (Math/round (:transaction/amount r)))])]]
|
||||||
[:th (some-> r :transaction/date coerce/to-date-time (atime/unparse-local atime/normal-date))]
|
(for [[date description amt] similar]
|
||||||
[:th (-> r :transaction/description-original)]
|
[:tr
|
||||||
[:th (if (> (-> r :transaction/amount) 0.0 )
|
[:td (some-> date coerce/to-date-time (atime/unparse-local atime/normal-date))]
|
||||||
[:div.tag.is-success.is-light (str "$" (Math/round (:transaction/amount r)))]
|
[:td description]
|
||||||
[:div.tag.is-danger.is-light (str "$" (Math/round (:transaction/amount r)))])]]
|
[:td (if (> amt 0.0)
|
||||||
(for [[date description amt] similar]
|
[:div.tag.is-success.is-light (str "$" (Math/round amt))]
|
||||||
[:tr
|
[:div.tag.is-danger.is-light (str "$" (Math/round amt))])]])]]
|
||||||
[:td (some-> date coerce/to-date-time (atime/unparse-local atime/normal-date))]
|
[:div])))))
|
||||||
[:td description]
|
|
||||||
[:td (if (> amt 0.0 )
|
|
||||||
[:div.tag.is-success.is-light (str "$" (Math/round amt))]
|
|
||||||
[:div.tag.is-danger.is-light (str "$" (Math/round amt))])]])]]
|
|
||||||
|
|
||||||
]]
|
|
||||||
[:button.modal-close.is-large {"_" (hiccup/raw "on click remove <#modal-holder div/>")}]])))
|
|
||||||
|
|
||||||
(defn transaction-rows* [{:keys [selected-client identity after]}]
|
(defn transaction-rows* [{:keys [selected-client identity after]}]
|
||||||
(let [recommendations (transaction-recommendations identity selected-client :after after)]
|
(let [recommendations (transaction-recommendations identity selected-client :after after)]
|
||||||
@@ -178,28 +179,23 @@
|
|||||||
:after (:after route-params)})))
|
:after (:after route-params)})))
|
||||||
|
|
||||||
(defn insight-table* [{:keys [selected-client identity]}]
|
(defn insight-table* [{:keys [selected-client identity]}]
|
||||||
[:div#insight-table {:hx-get (bidi/path-for ssr-routes/only-routes
|
(let [recommendations (transaction-recommendations identity selected-client)]
|
||||||
:transaction-insight-table
|
(com/data-grid-card {:id "insight-table"
|
||||||
:request-method :get)
|
:title "Transaction Insights"
|
||||||
:hx-trigger "clientSelected from:body"
|
:route :transaction-insight-table
|
||||||
:hx-swap "outerHTML swap:100ms"}
|
:paginate? false
|
||||||
|
:total (count recommendations)
|
||||||
[:table.table
|
:action-buttons nil
|
||||||
[:thead
|
:rows (for [r recommendations
|
||||||
[:tr
|
:let [last? (= r (last recommendations))]]
|
||||||
[:td "Client"]
|
(transaction-row r :last? last?))
|
||||||
[:td "Account"]
|
:headers [(com/data-grid-header {} "Client")
|
||||||
[:td "Date"]
|
(com/data-grid-header {} "Account")
|
||||||
[:td "Description"]
|
(com/data-grid-header {} "Date")
|
||||||
[:td "Amount"]
|
(com/data-grid-header {} "Description")
|
||||||
[:td "Vendor / Account"]
|
(com/data-grid-header {} "Amount")
|
||||||
[:td "action"]]]
|
(com/data-grid-header {:style {:width "4em"}} "Vendor / Account")
|
||||||
[:tbody
|
(com/data-grid-header {})]})))
|
||||||
(transaction-rows* {:selected-client selected-client
|
|
||||||
:identity identity})]]
|
|
||||||
[:div.container.htmx-indicator
|
|
||||||
[:div.column.is-4.is-offset-4.has-text-centered
|
|
||||||
[:div.loader.is-loading.is-active.big.is-centered]]]])
|
|
||||||
|
|
||||||
(defn insight-table [{:keys [session identity]}]
|
(defn insight-table [{:keys [session identity]}]
|
||||||
(html-response (insight-table* {:selected-client
|
(html-response (insight-table* {:selected-client
|
||||||
@@ -208,10 +204,24 @@
|
|||||||
|
|
||||||
(defn page [{:keys [identity matched-route session] :as request}]
|
(defn page [{:keys [identity matched-route session] :as request}]
|
||||||
(base-page
|
(base-page
|
||||||
request
|
request
|
||||||
[:div
|
(com/page {:nav (com/admin-aside-nav)
|
||||||
[:h1.title "Transaction Insights"]
|
:active-client (:client (:session request))
|
||||||
(insight-table* {:selected-client
|
:identity (:identity request)
|
||||||
(-> session :client :db/id)
|
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
||||||
:identity identity})]
|
:admin-history)
|
||||||
"Transaction Insights"))
|
:hx-trigger "clientSelected from:body"
|
||||||
|
:hx-select "#app-contents"
|
||||||
|
:hx-swap "outerHTML swap:300ms"}}
|
||||||
|
(com/breadcrumbs {}
|
||||||
|
[:a {:href (bidi/path-for client-routes/routes
|
||||||
|
:transactions)}
|
||||||
|
"Transactions"]
|
||||||
|
[:a {:href (bidi/path-for ssr-routes/only-routes
|
||||||
|
:transaction-insights)}
|
||||||
|
"Insights"])
|
||||||
|
(insight-table* {:selected-client
|
||||||
|
(-> session :client :db/id)
|
||||||
|
:identity identity}))
|
||||||
|
|
||||||
|
"Transaction Insights"))
|
||||||
|
|||||||
Reference in New Issue
Block a user