Adds float visibility
This commit is contained in:
1
resources/.~lock.sample-ledger.csv#
Normal file
1
resources/.~lock.sample-ledger.csv#
Normal file
@@ -0,0 +1 @@
|
||||
,noti,pop-os,24.08.2024 23:11,file:///home/noti/.config/libreoffice/4;
|
||||
@@ -42,4 +42,27 @@ Alpine.directive('hx-header', (el, { value, expression }, { evaluateLater, effec
|
||||
cleanup(onDestroy);
|
||||
}
|
||||
);
|
||||
Alpine.directive('popper', (el, { value, expression }, { evaluateLater, effect, cleanup, evaluate, Alpine}) => {
|
||||
let dependent_properties = evaluate(expression)
|
||||
let tooltip = evaluate(dependent_properties['tooltip'])
|
||||
let source = evaluate(dependent_properties['source'])
|
||||
|
||||
let popper = Popper.createPopper(source, tooltip, {placement: 'bottom', strategy: 'fixed', modifiers: [{name: 'preventOverflow'}, {name: 'offset', options: {offset: [0, 10]}}]});;
|
||||
let d=Alpine.reactive({show: false});
|
||||
tooltip.classList.add('opacity-0', 'transition-opacity')
|
||||
|
||||
let show = () => d.show = true;
|
||||
let hide = () => d.show = false;
|
||||
source.addEventListener('mouseover', show)
|
||||
source.addEventListener('mouseout', hide)
|
||||
effect(() => {
|
||||
if (d.show) {
|
||||
tooltip.classList.remove('opacity-0')
|
||||
} else {
|
||||
tooltip.classList.add('opacity-0')
|
||||
}
|
||||
|
||||
})
|
||||
cleanup(() => {popper.destroy(); source.removeEventListener('mouseover', show); source.removeEventListener('mouseout', hide) })
|
||||
})
|
||||
})
|
||||
File diff suppressed because one or more lines are too long
@@ -30,6 +30,7 @@
|
||||
(def modal-header-attachment dialog/modal-header-attachment-)
|
||||
(def modal-body dialog/modal-body-)
|
||||
(def modal-footer dialog/modal-footer-)
|
||||
(def tooltip buttons/tooltip-)
|
||||
|
||||
(def text-input inputs/text-input-)
|
||||
(def text-area inputs/text-area-)
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"sales"
|
||||
(#{::payment-routes/all-page ::payment-routes/pending-page ::payment-routes/cleared-page ::payment-routes/voided-page} (:matched-route request))
|
||||
"payments"
|
||||
(#{::ledger-routes/all-page ::ledger-routes/external-page} (:matched-route request))
|
||||
(#{::ledger-routes/all-page ::ledger-routes/external-page ::ledger-routes/external-import-page} (:matched-route request))
|
||||
"ledger"
|
||||
:else
|
||||
nil)]
|
||||
|
||||
@@ -232,3 +232,8 @@
|
||||
(if (seq children)
|
||||
children
|
||||
"Save")))
|
||||
|
||||
(defn tooltip- [{:as params} & children]
|
||||
[:div (assoc params
|
||||
:class "bg-gray-100 dark:bg-gray-600 rounded-lg shadow-2xl w-max z-50 p-4 opacity-0")
|
||||
[:span children]])
|
||||
|
||||
@@ -382,9 +382,7 @@
|
||||
:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
::route/pay-wizard)
|
||||
:hx-trigger "click from:#pay-button"
|
||||
: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]}}]});"}
|
||||
:x-popper (hx/json {:source "$refs.button", :tooltip "$refs.tooltip"}) }
|
||||
(com/button {:color :primary
|
||||
:id "pay-button"
|
||||
:disabled (or (= (count (:ids params)) 0)
|
||||
@@ -395,8 +393,6 @@
|
||||
: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"}
|
||||
@@ -409,24 +405,21 @@
|
||||
(when (or (= 0 (count ids))
|
||||
(> selected-client-count 1))
|
||||
(com/badge {} "!")))
|
||||
[:div (hx/alpine-appear {:x-ref "tooltip"
|
||||
(com/tooltip {:x-ref "tooltip" }
|
||||
(cond
|
||||
(not all-credits-or-debits)
|
||||
[:div "All vendor totals must be either positive or negative."]
|
||||
(and (= 0 (count ids))
|
||||
(not= (count (:ids params))
|
||||
0))
|
||||
[:div "No " [:span.font-bold "payable"] " invoices selected."]
|
||||
|
||||
:x-show "hovering"
|
||||
:class "bg-gray-100 dark:bg-gray-600 rounded-lg shadow-2xl w-max z-50 p-4"})
|
||||
(cond
|
||||
(not all-credits-or-debits)
|
||||
[:div "All vendor totals must be either positive or negative."]
|
||||
(and (= 0 (count ids))
|
||||
(not= (count (:ids params))
|
||||
0))
|
||||
[:div "No " [:span.font-bold "payable"] " invoices selected."]
|
||||
|
||||
(= 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"])]]))
|
||||
(= 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]
|
||||
|
||||
@@ -680,20 +680,19 @@
|
||||
:name (fc/field-name)
|
||||
:class "w-24"}))))
|
||||
(com/data-grid-cell {:class "align-top"}
|
||||
[:div.p-2 {:x-data (hx/json {:popper nil
|
||||
:hover false})
|
||||
:x-init "popper = Popper.createPopper($refs.button, $refs.tooltip, {placement: 'bottom', strategy: 'fixed', modifiers: [{name: 'preventOverflow'}, {name: 'offset', options: {offset: [0, 10]}}]});"}
|
||||
[:div.p-2
|
||||
(cond (seq (fc/field-errors))
|
||||
[:div.w-8.h-8.bg-red-50.rounded-full.p-2.text-red-300.flex.items-start
|
||||
{"@mouseover" "hover=true; $nextTick(() => popper.update()); console.log('hi')"
|
||||
"@mouseout" "hover=false"
|
||||
:x-ref "button"}
|
||||
svg/alert]
|
||||
[:div
|
||||
{ :x-popper (hx/json {:source "$refs.button"
|
||||
:tooltip "$refs.tooltip"})}
|
||||
[:div.w-8.h-8.bg-red-50.rounded-full.p-2.text-red-300.flex.items-start
|
||||
{ :x-ref "button"}
|
||||
svg/alert]
|
||||
(com/tooltip {:x-ref "tooltip"}
|
||||
[:span (pr-str (fc/field-errors))])]
|
||||
:else
|
||||
nil)
|
||||
[:div (hx/alpine-appear {:x-ref "tooltip" :x-show "hover"
|
||||
:class "bg-gray-100 dark:bg-gray-600 rounded-lg shadow-2xl w-max z-50 p-4"})
|
||||
[:span (pr-str (fc/field-errors))]]]))))}
|
||||
]))))}
|
||||
|
||||
[:div.flex.m-4.flex-row-reverse
|
||||
(com/button {:color :primary} "Import")])])))])
|
||||
|
||||
@@ -243,12 +243,51 @@
|
||||
(map first))]
|
||||
refunds))
|
||||
|
||||
(defn sum-visible-pending [ids]
|
||||
(->>
|
||||
(dc/q {:find ['?id '?o]
|
||||
:in ['$ '[?id ...]]
|
||||
:where ['[?id :payment/amount ?o]
|
||||
'[?id :payment/status :payment-status/pending]]}
|
||||
(dc/db conn)
|
||||
ids)
|
||||
(map last)
|
||||
(reduce
|
||||
+
|
||||
0.0)))
|
||||
|
||||
(defn sum-client-pending [clients]
|
||||
(->>
|
||||
(dc/q {:find '[?e ?a]
|
||||
:in '[$ [?clients ?start ?end]]
|
||||
:where '[[(iol-ion.query/scan-payments $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]
|
||||
[?e :payment/status :payment-status/pending]
|
||||
[?e :payment/amount ?a]]}
|
||||
(dc/db conn)
|
||||
[clients
|
||||
nil
|
||||
nil])
|
||||
|
||||
(map last)
|
||||
(reduce
|
||||
+
|
||||
0.0)))
|
||||
|
||||
(defn fetch-page [request]
|
||||
(let [db (dc/db conn)
|
||||
{ids-to-retrieve :ids matching-count :count} (fetch-ids db request)]
|
||||
{ids-to-retrieve :ids matching-count :count
|
||||
all-ids :all-ids} (fetch-ids db request)]
|
||||
|
||||
|
||||
[(->> (hydrate-results ids-to-retrieve db request))
|
||||
matching-count]))
|
||||
matching-count
|
||||
(sum-visible-pending all-ids)
|
||||
(sum-client-pending (extract-client-ids (:clients request)
|
||||
(:client request)
|
||||
(:client-id (:query-params request))
|
||||
(when (:client-code (:query-params request))
|
||||
[:client/code (:client-code (:query-params request))])))
|
||||
]))
|
||||
|
||||
(def query-schema (mc/schema
|
||||
[:maybe [:map {:date-range [:date-range :start-date :end-date]}
|
||||
@@ -291,12 +330,17 @@
|
||||
:parse-query-params (fn [p]
|
||||
(mc/decode query-schema p main-transformer))
|
||||
:action-buttons (fn [request]
|
||||
[(when (can? (:identity request) {:subject :payment :activity :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})"
|
||||
"hx-include" "#payment-filters"
|
||||
:color :red}
|
||||
"Void selected"))])
|
||||
(let [[_ _ visible-in-float total-in-float ] (:page-results request)]
|
||||
[(com/pill {:color :primary} " Visible in float "
|
||||
(format "$%,.2f" visible-in-float))
|
||||
(com/pill {:color :secondary} " Total in float "
|
||||
(format "$%,.2f" total-in-float))
|
||||
(when (can? (:identity request) {:subject :payment :activity :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})"
|
||||
"hx-include" "#payment-filters"
|
||||
:color :red}
|
||||
"Void selected"))]))
|
||||
:row-buttons (fn [_ entity]
|
||||
[(when (not= :payment-status/voided (:payment/status entity))
|
||||
(com/icon-button {:hx-delete (bidi/path-for ssr-routes/only-routes
|
||||
@@ -306,6 +350,13 @@
|
||||
svg/trash))])
|
||||
:breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes ::route/page)}
|
||||
"Payments"]]
|
||||
:break-table (fn [request entity]
|
||||
(cond
|
||||
(= (-> request :query-params :sort first :name) "Vendor")
|
||||
(-> entity :payment/vendor :vendor/name)
|
||||
|
||||
|
||||
:else nil))
|
||||
:title (fn [r]
|
||||
(str
|
||||
(some-> r :rout-params :status name str/capitalize (str " "))
|
||||
@@ -344,7 +395,7 @@
|
||||
(condp = status
|
||||
:payment-status/cleared
|
||||
(com/pill {:color :primary} "cleared")
|
||||
|
||||
|
||||
:payment-status/pending
|
||||
(com/pill {:color :secondary} "pending")
|
||||
:payment-status/voided
|
||||
@@ -368,10 +419,10 @@
|
||||
(map :invoice-payment/invoice)
|
||||
(filter identity)
|
||||
(map (fn [invoice]
|
||||
{:link (hu/url (bidi/path-for ssr-routes/only-routes
|
||||
::invoice-route/all-page)
|
||||
{:exact-match-id (:db/id invoice)})
|
||||
:content (str "Inv. " (:invoice/invoice-number invoice))})))
|
||||
{:link (hu/url (bidi/path-for ssr-routes/only-routes
|
||||
::invoice-route/all-page)
|
||||
{:exact-match-id (:db/id invoice)})
|
||||
:content (str "Inv. " (:invoice/invoice-number invoice))})))
|
||||
(some-> p :transaction/_payment ((fn [t]
|
||||
[{:link (hu/url (bidi/path-for client-routes/routes
|
||||
:transactions)
|
||||
|
||||
Reference in New Issue
Block a user