progress on pay button.
This commit is contained in:
@@ -98,7 +98,8 @@
|
|||||||
(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 font-medium border border-gray-300 dark:border-gray-700")))
|
(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 font-medium border border-gray-300 dark:border-gray-700")))
|
||||||
[:div.htmx-indicator.flex.items-center
|
[:div.htmx-indicator.flex.items-center
|
||||||
(svg/spinner {:class "inline w-4 h-4 text-white"})
|
(svg/spinner {:class "inline w-4 h-4 text-white"})
|
||||||
[:div.ml-3 "Loading..."]]
|
(when (not (:minimal-loading? params))
|
||||||
|
[:div.ml-3 "Loading..."])]
|
||||||
(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 a-button- [params & children]
|
(defn a-button- [params & children]
|
||||||
|
|||||||
@@ -215,13 +215,14 @@
|
|||||||
identity
|
identity
|
||||||
request)
|
request)
|
||||||
:headers {"hx-push-url" (str "?" (url/map->query
|
:headers {"hx-push-url" (str "?" (url/map->query
|
||||||
(if (:query-schema grid-spec)
|
(dissoc (if (:query-schema grid-spec)
|
||||||
(update (filter-vals #(not (nil? %))
|
(update (filter-vals #(not (nil? %))
|
||||||
(m/encode (:query-schema grid-spec)
|
(m/encode (:query-schema grid-spec)
|
||||||
(:query-params request)
|
(:query-params request)
|
||||||
main-transformer))
|
main-transformer))
|
||||||
"sort" sort->query)
|
"sort" sort->query)
|
||||||
(unparse-query-params (:parsed-query-params request)))))}
|
(unparse-query-params (:parsed-query-params request)))
|
||||||
|
"selected" "all-selected")))} ;; TODO seems hacky to special case selected and all-selected here
|
||||||
:oob (when-let [oob-render (:oob-render grid-spec)]
|
:oob (when-let [oob-render (:oob-render grid-spec)]
|
||||||
(oob-render request)))))
|
(oob-render request)))))
|
||||||
(wrap-trim-client-ids)
|
(wrap-trim-client-ids)
|
||||||
@@ -242,7 +243,11 @@
|
|||||||
:client (:client request)
|
:client (:client request)
|
||||||
:identity (:identity request)}
|
:identity (:identity request)}
|
||||||
(apply com/breadcrumbs {} (:breadcrumbs grid-spec))
|
(apply com/breadcrumbs {} (:breadcrumbs grid-spec))
|
||||||
[:div {:x-data (hx/json {:selected [] :all_selected false})}
|
[:div {:x-data (hx/json {:selected [] :all_selected false})
|
||||||
|
"x-bind:hx-vals" "JSON.stringify({selected: $data.selected, 'all-selected': $data.all_selected})"
|
||||||
|
:x-init "$watch('selected', s=> $dispatch('selectedChanged', {selected: s, all_selected: all_selected}) );
|
||||||
|
$watch('all_selected', a=>$dispatch('selectedChanged', {selected: selected, all_selected: a}))"}
|
||||||
|
|
||||||
(table* grid-spec
|
(table* grid-spec
|
||||||
identity
|
identity
|
||||||
request)])
|
request)])
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
[:div {:id "exact-match-id-tag"}]))
|
[:div {:id "exact-match-id-tag"}]))
|
||||||
|
|
||||||
(defn filters [request]
|
(defn filters [request]
|
||||||
[:form#payment-filters {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
|
[:form#invoice-filters {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms"
|
||||||
"hx-get" (bidi/path-for ssr-routes/only-routes
|
"hx-get" (bidi/path-for ssr-routes/only-routes
|
||||||
::route/table)
|
::route/table)
|
||||||
"hx-target" "#entity-table"
|
"hx-target" "#entity-table"
|
||||||
@@ -264,11 +264,10 @@
|
|||||||
[:start {:optional true :default 0} [:maybe :int]]
|
[:start {:optional true :default 0} [:maybe :int]]
|
||||||
[:amount-gte {:optional true} [:maybe :double]]
|
[:amount-gte {:optional true} [:maybe :double]]
|
||||||
[:amount-lte {:optional true} [:maybe :double]]
|
[:amount-lte {:optional true} [:maybe :double]]
|
||||||
[:payment-type {:optional true} [:maybe (ref->enum-schema "payment-type")]]
|
|
||||||
[:vendor {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :vendor/name]}]]]
|
[:vendor {:optional true :default nil} [:maybe [:entity-map {:pull [:db/id :vendor/name]}]]]
|
||||||
[:check-number {:optional true} [:maybe [:string {:decode/string strip}]]]
|
[:check-number {:optional true} [:maybe [:string {:decode/string strip}]]]
|
||||||
[:invoice-number {:optional true} [:maybe [:string {:decode/string strip}]]]
|
[:invoice-number {:optional true} [:maybe [:string {:decode/string strip}]]]
|
||||||
[:status {:optional true} [:maybe (ref->enum-schema "payment-status")]]
|
[:status {:optional true} [:maybe (ref->enum-schema "invoice-status")]]
|
||||||
[:exact-match-id {:optional true} [:maybe entity-id]]
|
[:exact-match-id {:optional true} [:maybe entity-id]]
|
||||||
[:all-selected {:optional true :default nil} [:maybe :boolean]]
|
[:all-selected {:optional true :default nil} [:maybe :boolean]]
|
||||||
[:selected {:optional true :default nil} [:maybe [:vector {:coerce? true}
|
[:selected {:optional true :default nil} [:maybe [:vector {:coerce? true}
|
||||||
@@ -283,6 +282,75 @@
|
|||||||
{:start " "}
|
{:start " "}
|
||||||
main-transformer))
|
main-transformer))
|
||||||
|
|
||||||
|
(defn selected->ids [request params]
|
||||||
|
(let [all-selected (:all-selected params)
|
||||||
|
selected (:selected params)
|
||||||
|
ids (cond
|
||||||
|
all-selected
|
||||||
|
(:ids (fetch-ids (dc/db conn) (-> request
|
||||||
|
(assoc :query-params params)
|
||||||
|
(assoc-in [:query-params :start] 0)
|
||||||
|
(assoc-in [:query-params :per-page] 250))))
|
||||||
|
|
||||||
|
|
||||||
|
:else
|
||||||
|
selected)]
|
||||||
|
ids))
|
||||||
|
|
||||||
|
(defn pay-button* [params]
|
||||||
|
(let [ids (:ids params)
|
||||||
|
selected-client-count (if (seq ids)
|
||||||
|
(ffirst
|
||||||
|
(dc/q '[:find (count ?c)
|
||||||
|
:in $ [?i ...]
|
||||||
|
:where [?i :invoice/client ?c]]
|
||||||
|
(dc/db conn)
|
||||||
|
ids))
|
||||||
|
|
||||||
|
0)]
|
||||||
|
|
||||||
|
[:div {:hx-target "this"
|
||||||
|
:x-data (hx/json {:popper nil
|
||||||
|
:hovering false})
|
||||||
|
"x-init" "popper = Popper.createPopper($refs.button, $refs.tooltip, {placement: 'bottom', strategy: 'fixed', modifiers: [{name: 'preventOverflow'}, {name: 'offset', options: {offset: [0, 10]}}]});"}
|
||||||
|
(com/button {:color :primary
|
||||||
|
:disabled (or (= (count (:ids params)) 0)
|
||||||
|
(not= 1 selected-client-count))
|
||||||
|
"x-bind:hx-vals" "JSON.stringify({selected: $data.selected, 'all-selected': $data.all_selected})"
|
||||||
|
"hx-include" "#invoice-filters"
|
||||||
|
:hx-get (bidi/path-for ssr-routes/only-routes ::route/pay-button)
|
||||||
|
:hx-swap "outerHTML"
|
||||||
|
:hx-trigger "selectedChanged from:body, htmx:afterSwap from:#entity-table"
|
||||||
|
"@mouseover" "hovering=true; $nextTick(() => popper.update())"
|
||||||
|
"@mouseout" "hovering=false;"
|
||||||
|
:x-ref "button"
|
||||||
|
:minimal-loading? true
|
||||||
|
:class "relative"}
|
||||||
|
(if (> (count (:ids params)) 0)
|
||||||
|
|
||||||
|
(str "Pay " (count (:ids params)) " invoices")
|
||||||
|
"Pay")
|
||||||
|
(when (or (= 0 (count ids))
|
||||||
|
(> selected-client-count 1))
|
||||||
|
(com/badge {} "!")))
|
||||||
|
[:div (hx/alpine-appear {:x-ref "tooltip"
|
||||||
|
|
||||||
|
:x-show "hovering"
|
||||||
|
:class "bg-gray-100 dark:bg-gray-600 rounded-lg shadow-2xl w-max z-50 p-4"})
|
||||||
|
(cond
|
||||||
|
(= 0 (count ids))
|
||||||
|
[:div "Please select some invoices to pay"]
|
||||||
|
(> selected-client-count 1)
|
||||||
|
[:div "Can only pay for one client at a time"]
|
||||||
|
:else
|
||||||
|
[:div "Click to choose a bank account"])]]))
|
||||||
|
|
||||||
|
|
||||||
|
(defn pay-button [request]
|
||||||
|
(html-response
|
||||||
|
(pay-button* {:ids (selected->ids request
|
||||||
|
(:query-params request))})))
|
||||||
|
|
||||||
;; TODO fix parsing of query params
|
;; TODO fix parsing of query params
|
||||||
(def grid-page
|
(def grid-page
|
||||||
(helper/build {:id "entity-table"
|
(helper/build {:id "entity-table"
|
||||||
@@ -298,12 +366,15 @@
|
|||||||
:parse-query-params (fn [p]
|
:parse-query-params (fn [p]
|
||||||
(mc/decode query-schema p main-transformer))
|
(mc/decode query-schema p main-transformer))
|
||||||
:action-buttons (fn [request]
|
:action-buttons (fn [request]
|
||||||
[(when (can? (:identity request) {:subject :payment :activity :bulk-delete})
|
[(when (can? (:identity request) {:subject :invoice :activity :bulk-delete})
|
||||||
(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes ::route/bulk-delete))
|
(com/button {:hx-get (str (bidi/path-for ssr-routes/only-routes ::route/bulk-delete))
|
||||||
"x-bind:hx-vals" "JSON.stringify({selected: $data.selected, 'all-selected': $data.all_selected})"
|
"x-bind:hx-vals" "JSON.stringify({selected: $data.selected, 'all-selected': $data.all_selected})"
|
||||||
"hx-include" "#payment-filters"
|
"hx-include" "#invoice-filters"
|
||||||
:color :red}
|
:color :red}
|
||||||
"Void selected"))])
|
"Void selected"))
|
||||||
|
(when (can? (:identity request) {:subject :invoice :activity :pay})
|
||||||
|
(pay-button* {:ids (selected->ids request
|
||||||
|
(:query-params request))}))])
|
||||||
:row-buttons (fn [_ entity]
|
:row-buttons (fn [_ entity]
|
||||||
[(when (= :invoice-status/unpaid (:invoice/status entity))
|
[(when (= :invoice-status/unpaid (:invoice/status entity))
|
||||||
(com/icon-button {:hx-delete (bidi/path-for ssr-routes/only-routes
|
(com/icon-button {:hx-delete (bidi/path-for ssr-routes/only-routes
|
||||||
@@ -470,7 +541,7 @@
|
|||||||
(assoc "hx-retarget" ".modal-stack")
|
(assoc "hx-retarget" ".modal-stack")
|
||||||
(assoc "hx-reswap" "beforeend")))))
|
(assoc "hx-reswap" "beforeend")))))
|
||||||
|
|
||||||
(defn void-payments-internal [all-ids id]
|
(defn void-invoices-internal [all-ids id]
|
||||||
(let [all-ids (->> all-ids
|
(let [all-ids (->> all-ids
|
||||||
(dc/q '[:find (pull ?i [:db/id :invoice/date {:invoice/expense-accounts [:db/id]}])
|
(dc/q '[:find (pull ?i [:db/id :invoice/date {:invoice/expense-accounts [:db/id]}])
|
||||||
:in $ [?i ...]
|
:in $ [?i ...]
|
||||||
@@ -512,21 +583,12 @@
|
|||||||
id)
|
id)
|
||||||
(count all-ids)))
|
(count all-ids)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn bulk-delete-dialog-confirm [request]
|
(defn bulk-delete-dialog-confirm [request]
|
||||||
(alog/peek (:form-params request))
|
(alog/peek (:form-params request))
|
||||||
(let [all-selected (:all-selected (:form-params request))
|
(let [ids (selected->ids request (:form-params request))
|
||||||
selected (:selected (:form-params request))
|
updated-count (void-invoices-internal ids (:identity request))]
|
||||||
ids (cond
|
|
||||||
all-selected
|
|
||||||
(:ids (fetch-ids (dc/db conn) (-> request
|
|
||||||
(assoc :query-params (:form-params request))
|
|
||||||
(assoc-in [:query-params :start] 0)
|
|
||||||
(assoc-in [:query-params :per-page] 250))))
|
|
||||||
|
|
||||||
|
|
||||||
:else
|
|
||||||
selected)
|
|
||||||
updated-count (void-payments-internal ids (:identity request))]
|
|
||||||
|
|
||||||
(html-response [:div]
|
(html-response [:div]
|
||||||
:headers {"hx-trigger" (hx/json {:modalclose ""
|
:headers {"hx-trigger" (hx/json {:modalclose ""
|
||||||
@@ -539,6 +601,8 @@
|
|||||||
(def key->handler
|
(def key->handler
|
||||||
(apply-middleware-to-all-handlers
|
(apply-middleware-to-all-handlers
|
||||||
{::route/page (helper/page-route grid-page)
|
{::route/page (helper/page-route grid-page)
|
||||||
|
::route/pay-button (-> pay-button
|
||||||
|
(wrap-schema-enforce :query-schema query-schema))
|
||||||
::route/delete (-> delete
|
::route/delete (-> delete
|
||||||
(wrap-entity [:route-params :db/id] default-read)
|
(wrap-entity [:route-params :db/id] default-read)
|
||||||
(wrap-schema-enforce :route-params [:map [:db/id entity-id]]))
|
(wrap-schema-enforce :route-params [:map [:db/id entity-id]]))
|
||||||
|
|||||||
@@ -259,12 +259,15 @@
|
|||||||
(mt2/transformer {:decoders {:vector {:compile (fn [schema _]
|
(mt2/transformer {:decoders {:vector {:compile (fn [schema _]
|
||||||
(when (:coerce? (m/properties schema))
|
(when (:coerce? (m/properties schema))
|
||||||
(fn [data]
|
(fn [data]
|
||||||
(cond (sequential? data)
|
(cond
|
||||||
data
|
(vector? data)
|
||||||
(nil? data)
|
data
|
||||||
nil
|
(sequential? data)
|
||||||
:else
|
data
|
||||||
[data]))))}}}))
|
(nil? data)
|
||||||
|
nil
|
||||||
|
:else
|
||||||
|
[data]))))}}}))
|
||||||
|
|
||||||
(defn wrap-merge-prior-hx [handler]
|
(defn wrap-merge-prior-hx [handler]
|
||||||
;; TODO this should just be automatic
|
;; TODO this should just be automatic
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
(ns auto-ap.routes.invoice)
|
(ns auto-ap.routes.invoice)
|
||||||
(def routes {"" {:get ::page}
|
(def routes {"" {:get ::page}
|
||||||
|
"/pay-button" ::pay-button
|
||||||
"/bulk-delete" {:get ::bulk-delete
|
"/bulk-delete" {:get ::bulk-delete
|
||||||
:delete ::bulk-delete-confirm}
|
:delete ::bulk-delete-confirm}
|
||||||
["/" [#"\d+" :db/id]] {:delete ::delete}
|
["/" [#"\d+" :db/id]] {:delete ::delete}
|
||||||
|
|||||||
Reference in New Issue
Block a user