diff --git a/resources/public/js/alpine-vals.js b/resources/public/js/alpine-vals.js index ec898f40..a23d1c7a 100644 --- a/resources/public/js/alpine-vals.js +++ b/resources/public/js/alpine-vals.js @@ -68,3 +68,4 @@ Alpine.directive('hx-header', (el, { value, expression }, { evaluateLater, effec } })) }) + diff --git a/src/clj/auto_ap/intuit/core.clj b/src/clj/auto_ap/intuit/core.clj index aaff8fdc..ed69df79 100644 --- a/src/clj/auto_ap/intuit/core.clj +++ b/src/clj/auto_ap/intuit/core.clj @@ -53,6 +53,7 @@ :bucket-name "data.prod.app.integreatconsult.com" :key "intuit/refresh-token"))))) + #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defn init-tokens [access refresh] (set-access-token access) diff --git a/src/clj/auto_ap/ssr/admin/excel_invoice.clj b/src/clj/auto_ap/ssr/admin/excel_invoice.clj index 1149bf44..2b0435c0 100644 --- a/src/clj/auto_ap/ssr/admin/excel_invoice.clj +++ b/src/clj/auto_ap/ssr/admin/excel_invoice.clj @@ -1,33 +1,30 @@ (ns auto-ap.ssr.admin.excel-invoice - (:require - [auto-ap.datomic :refer [audit-transact remove-nils conn]] - [auto-ap.datomic.accounts :as a] - [auto-ap.datomic.invoices :as d-invoices] - [auto-ap.import.manual.common :as c] - [auto-ap.logging :as alog] - [auto-ap.routes.admin.excel-invoices :as route] - [auto-ap.routes.utils + (:require [auto-ap.datomic :refer [audit-transact conn remove-nils]] + [auto-ap.datomic.accounts :as a] + [auto-ap.datomic.invoices :as d-invoices] + [auto-ap.import.manual.common :as c] + [auto-ap.logging :as alog] + [auto-ap.routes.admin.excel-invoices :as route] + [auto-ap.routes.utils :refer [wrap-admin wrap-client-redirect-unauthenticated]] - [auto-ap.ssr-routes :as ssr-routes] - [auto-ap.ssr.components :as com] - [auto-ap.ssr.components.inputs :as inputs] - [auto-ap.ssr.form-cursor :as fc] - [auto-ap.ssr.hiccup-helper :as hh] - [auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]] - [auto-ap.ssr.ui :refer [base-page]] - [auto-ap.ssr.utils - :refer [apply-middleware-to-all-handlers - html-response - wrap-form-4xx-2 + [auto-ap.ssr-routes :as ssr-routes] + [auto-ap.ssr.components :as com] + [auto-ap.ssr.components.inputs :as inputs] + [auto-ap.ssr.form-cursor :as fc] + [auto-ap.ssr.hiccup-helper :as hh] + [auto-ap.ssr.hx :as hx] + [auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]] + [auto-ap.ssr.ui :refer [base-page]] + [auto-ap.ssr.utils + :refer [apply-middleware-to-all-handlers html-response wrap-form-4xx-2 wrap-schema-enforce]] - [auto-ap.utils :refer [by]] - [bidi.bidi :as bidi] - [clj-time.coerce :as coerce] - [clojure.string :as str] - [datomic.api :as dc] - [digest] - [hiccup2.core :as hiccup] - [auto-ap.ssr.hx :as hx])) + [auto-ap.utils :refer [by]] + [bidi.bidi :as bidi] + [clj-time.coerce :as coerce] + [clojure.string :as str] + [datomic.api :as dc] + [digest] + [hiccup2.core :as hiccup :refer [raw]])) (defn validate-invoice [invoice] (when-not (:invoice/client invoice) @@ -268,9 +265,6 @@ (form* {:form-params form-params :form-errors form-errors} [:div.flex.space-x-4 - {:x-init (when (seq (:vendors-not-found result)) - "popper = Popper.createPopper($refs.pill, $refs.tooltip, {placement: 'bottom', strategy: 'fixed', modifiers: {name: 'offset', options: {offset: [0, 10]}}});") - :x-data (hx/json {:show false})} (com/pill {:color :primary} (format "%d imported" (:imported result))) (com/pill {:color :secondary} @@ -280,10 +274,11 @@ (com/pill {:color :yellow "@mouseover" "show=true" "@mouseout" "show=false" - :x-ref "pill"} + "x-tooltip" "{content: ()=>$refs.tooltip.innerHTML , + allowHTML: true}" } (format "%d vendors not found" (count (:vendors-not-found result)))) - [:div {:x-ref "tooltip" :x-show "show" :class "bg-gray-100 dark:bg-gray-600 rounded-lg shadow-2xl w-max z-50 ring-1 p-4"} + [:template {:x-ref "tooltip"} [:ul (for [n (take 5 (:vendors-not-found result))] [:li n])]]))] diff --git a/src/clj/auto_ap/ssr/company/plaid.clj b/src/clj/auto_ap/ssr/company/plaid.clj index 811a93a0..a8b6a954 100644 --- a/src/clj/auto_ap/ssr/company/plaid.clj +++ b/src/clj/auto_ap/ssr/company/plaid.clj @@ -185,12 +185,10 @@ first :bank-account/integration-status)] [:div - (when bad-integration - { :x-data "popper()" }) - [:div.cursor-pointer (com/pill {:color (if bad-integration - :red - :primary) - :x-ref "source"} + + [:div.cursor-pointer (com/pill (cond-> {:color :primary} + bad-integration (assoc :color :red + :x-tooltip "{content: ()=>$refs.tooltip.innerHTML, theme: 'light', allowHTML: true}")) [:div.inline-flex.gap-2 (or @@ -204,10 +202,9 @@ (when bad-integration - (com/tooltip {:x-bind "tooltip" - :x-ref "tooltip"} - [:div.text-red-700 - (:integration-status/message bad-integration)]))])] + [:template {:x-ref "tooltip"} + [:div.text-red-700 + (:integration-status/message bad-integration)]])])] [:div.grid.grid-cols-2.gap-1.auto-cols-min.grid-flow-row.shrink [:div "Attempted: "] [:div (atime/unparse-local (coerce/to-date-time (:integration-status/last-attempt e)) atime/normal-date)] [:div "Last Updated: "] [:div (atime/unparse-local (coerce/to-date-time (:integration-status/last-updated e)) atime/normal-date)]]]))} diff --git a/src/clj/auto_ap/ssr/company/reports/reconciliation.clj b/src/clj/auto_ap/ssr/company/reports/reconciliation.clj index c832b03b..b1e5d059 100644 --- a/src/clj/auto_ap/ssr/company/reports/reconciliation.clj +++ b/src/clj/auto_ap/ssr/company/reports/reconciliation.clj @@ -52,19 +52,12 @@ (:requires-feedback-count row)) (com/data-grid-cell {:class class} (when (> (count (:missing-transactions row)) 0) - [:div { :x-data (hx/json {:popper nil - :hovering false}) - "x-init" "popper = Popper.createPopper($refs.hover_target, $refs.tooltip, {placement: 'bottom', strategy:'fixed', modifiers: [{name: 'preventOverflow'}, {name: 'offset', options: {offset: [0, 10]}}]});"} - (com/button {"x-ref" "hover_target" - "@click.prevent" "hovering=!hovering; $nextTick(() => popper.update())"} + [:div + (com/button { :x-tooltip.on.click "{content: ()=>$refs.tooltip.innerHTML, theme: 'light', allowHTML: true}" } [:div.flex.gap-2.items-center (count (:missing-transactions row)) - [:div.w-4.h-4 svg/question] - - ]) - [: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"}) + [:div.w-4.h-4 svg/question]]) + [:template {:x-ref "tooltip"} (com/data-grid {:headers [(com/data-grid-header {} "Date") (com/data-grid-header {} "Amount")]} (for [r (:missing-transactions row)] @@ -72,7 +65,7 @@ (com/data-grid-cell {} (atime/unparse-local (coerce/to-date-time (:transaction/date r)) atime/normal-date)) (com/data-grid-cell {} - (format "$%,.2f" (:transaction/amount r)))))) ] ]))))))]) + (format "$%,.2f" (:transaction/amount r))))))]]))))))]) (defn reconciliation-card* [{:keys [request report]}] diff --git a/src/clj/auto_ap/ssr/components/link_dropdown.clj b/src/clj/auto_ap/ssr/components/link_dropdown.clj index 91dc5acb..cd824a3b 100644 --- a/src/clj/auto_ap/ssr/components/link_dropdown.clj +++ b/src/clj/auto_ap/ssr/components/link_dropdown.clj @@ -5,20 +5,19 @@ (defn link-dropdown [links] (when (> (count links) 0) - [:div {:x-data (hx/json {:popper nil - :show false}) - "@click.outside" "show=false" + [:div - :x-init "popper = Popper.createPopper($refs.link, $refs.tooltip, {placement: 'bottom', strategy: 'fixed'})"} - - (com/a-icon-button {:x-ref "link" "@click.prevent" "show=!show; $nextTick(() => popper.update());" :class "relative"} + (com/a-icon-button {:class "relative" + "@click.prevent" "$tooltip($refs.tooltip, {content: ()=>$refs.tooltip.innerHTML, theme: 'light', allowHTML: true, interactive:true})" + } svg/paperclip (com/badge {:color "blue"} (count links))) - [:div.divide-y.divide-gray-200.bg-white.rounded-lg.shadow.z-50 (hx/alpine-appear {:x-ref "tooltip" :x-show "show" :data-key "show"}) - [:div {:class "p-3 overflow-y-auto text-sm text-gray-700 dark:text-gray-200"} - [:div.flex.flex-col.gap-y-2 {:class "max-w-[24em]"} - (for [l links] - [:div.flex-initial - [:a {:href (:link l) :target "_blank"} - (com/pill {:color (or (:color l) :primary) :class "truncate block shrink grow-0"} - (:content l))]])]]]])) \ No newline at end of file + [:template {:x-ref "tooltip"} + [:div.divide-y.divide-gray-200 + [:div {:class "p-2 overflow-y-auto text-sm text-gray-700 dark:text-gray-200"} + [:div.flex.flex-col.gap-y-2 {:class "max-w-[24em]"} + (for [l links] + [:div.flex-initial + [:a {:href (:link l) :target "_blank"} + (com/pill {:color (or (:color l) :primary) :class "truncate block shrink grow-0"} + (:content l))]])]]]]])) \ No newline at end of file diff --git a/src/clj/auto_ap/ssr/invoices.clj b/src/clj/auto_ap/ssr/invoices.clj index 8871fe17..b4d88ebf 100644 --- a/src/clj/auto_ap/ssr/invoices.clj +++ b/src/clj/auto_ap/ssr/invoices.clj @@ -382,8 +382,8 @@ :hx-get (bidi/path-for ssr-routes/only-routes ::route/pay-wizard) :hx-trigger "click from:#pay-button" - :x-data "popper()" - } + :x-tooltip "{allowHTML: true, content: () => $refs.template.innerHTML, appendTo: $root}" + } (com/button {:color :primary :id "pay-button" :disabled (or (= (count (:ids params)) 0) @@ -406,21 +406,21 @@ (when (or (= 0 (count ids)) (> selected-client-count 1)) (com/badge {} "!"))) - (com/tooltip {:x-bind "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."] + [:template {:x-ref "template"} + (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] @@ -817,9 +817,7 @@ (defn bank-account-card-base [{:keys [bg-color text-color icon bank-account can-handwrite? credit-only?]}] [:div {:class "w-[30em]"} (com/card {:class "w-full"} - [:div.flex.items-stretch {:x-data (hx/json {:chosen false - :popper nil}) - "x-init" "popper = Popper.createPopper($refs.button, $refs.tooltip, {placement: 'bottom', strategy: 'fixed', modifiers: [{name: 'preventOverflow'}, {name: 'offset', options: {offset: [0, 10]}}]});"} + [:div.flex.items-stretch {} (com/hidden {:name "item" :value (:db/id bank-account)}) [:div.grow-0.flex.flex-col.justify-center @@ -832,7 +830,7 @@ [:div.flex.flex-col.grow.m-2 [:div.font-medium.text-gray-700 (:bank-account/name bank-account)] [:div.font-light.text-gray-600 (:bank-account/bank-name bank-account)]] - [:div.grow-0.m-2.self-center + [:div.grow-0.m-2.self-center {:x-data (hx/json {})} (if credit-only? (com/button {:color :primary :minimal-loading? true @@ -843,52 +841,52 @@ :to (mm/encode-step-key :payment-details)})} "Credit") (com/button {:x-ref "button" - "@click.prevent.capture" "chosen=true; $nextTick(() => popper.update())"} + "@click.prevent.capture" "$tooltip($refs.tooltip.innerHTML, {allowHTML: true, onMount(i) {htmx.process(i.popper)}, interactive:true, theme:\"light\", timeout:5000})" } "Pay")) - [:div.flex.flex-col.gap-2 (hx/alpine-appear {:x-show "chosen" :x-ref "tooltip" - :data-key "vis" - :class "bg-gray-100 dark:bg-gray-600 rounded-lg shadow-2xl w-max z-50 p-4" - "@click.outside" "chosen=false"}) - (when (= :bank-account-type/check - (:bank-account/type bank-account)) - (com/button {:color :primary - :minimal-loading? true - :hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account) - "step-params[method]" "print-check"}) - :hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate) - {:from (mm/encode-step-key :choose-method) - :to (mm/encode-step-key :payment-details)})} - "Print check")) - (when (= :bank-account-type/cash - (:bank-account/type bank-account)) - (com/button {:minimal-loading? true - :hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account) - "step-params[method]" "cash"}) - :hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate) - {:from (mm/encode-step-key :choose-method) - :to (mm/encode-step-key :payment-details)})} - "With cash")) - (when (not= :bank-account-type/cash - (:bank-account/type bank-account)) - (com/button {:color (when (= :bank-account-type/credit - (:bank-account/type bank-account)) - :primary) - :minimal-loading? true - :hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account) - "step-params[method]" "debit"}) - :hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate) - {:from (mm/encode-step-key :choose-method) - :to (mm/encode-step-key :payment-details)})} - "Debit")) - (when (and (= :bank-account-type/check (:bank-account/type bank-account)) - can-handwrite?) - (com/button {:minimal-loading? true - :hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account) - "step-params[method]" "handwrite-check"}) - :hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate) - {:from (mm/encode-step-key :choose-method) - :to (mm/encode-step-key :payment-details)})} - "Handwrite check"))]]])]) + [:template { :x-ref "tooltip"} + [:div.flex.flex-col.gap-2 { + :data-key "vis" + :class "p-4 w-max" } + (when (= :bank-account-type/check + (:bank-account/type bank-account)) + (com/button {:color :primary + :minimal-loading? true + :hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account) + "step-params[method]" "print-check"}) + :hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate) + {:from (mm/encode-step-key :choose-method) + :to (mm/encode-step-key :payment-details)})} + "Print check")) + (when (= :bank-account-type/cash + (:bank-account/type bank-account)) + (com/button {:minimal-loading? true + :hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account) + "step-params[method]" "cash"}) + :hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate) + {:from (mm/encode-step-key :choose-method) + :to (mm/encode-step-key :payment-details)})} + "With cash")) + (when (not= :bank-account-type/cash + (:bank-account/type bank-account)) + (com/button {:color (when (= :bank-account-type/credit + (:bank-account/type bank-account)) + :primary) + :minimal-loading? true + :hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account) + "step-params[method]" "debit"}) + :hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate) + {:from (mm/encode-step-key :choose-method) + :to (mm/encode-step-key :payment-details)})} + "Debit")) + (when (and (= :bank-account-type/check (:bank-account/type bank-account)) + can-handwrite?) + (com/button {:minimal-loading? true + :hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account) + "step-params[method]" "handwrite-check"}) + :hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate) + {:from (mm/encode-step-key :choose-method) + :to (mm/encode-step-key :payment-details)})} + "Handwrite check"))]]]])]) (defmulti bank-account-card (fn [ba _ _] (:bank-account/type ba))) diff --git a/src/clj/auto_ap/ssr/ledger.clj b/src/clj/auto_ap/ssr/ledger.clj index 16de6b96..89568011 100644 --- a/src/clj/auto_ap/ssr/ledger.clj +++ b/src/clj/auto_ap/ssr/ledger.clj @@ -213,12 +213,10 @@ [:div.p-2 (cond (seq (fc/field-errors)) [:div - { :x-data "popper()"} + { :x-tooltip (hx/json (pr-str (fc/field-errors)))} [:div.w-8.h-8.bg-red-50.rounded-full.p-2.text-red-300.flex.items-start { :x-ref "source"} - svg/alert] - (com/tooltip {:x-bind "tooltip"} - [:span (pr-str (fc/field-errors))])] + svg/alert] ] :else nil) ]))))} diff --git a/src/clj/auto_ap/ssr/ledger/common.clj b/src/clj/auto_ap/ssr/ledger/common.clj index 663042b0..f83ccb13 100644 --- a/src/clj/auto_ap/ssr/ledger/common.clj +++ b/src/clj/auto_ap/ssr/ledger/common.clj @@ -358,14 +358,12 @@ (list (if account-name - [:div {:x-data "popper()"} + [:div { :x-tooltip (hx/json (str "Running Balance: " (some->> (:journal-entry-line/running-balance jel) + (format "$%,.2f"))))} [:div.text-left.underline.cursor-pointer {:x-ref "source"} (:journal-entry-line/location jel) ": " (or (:account/numeric-code account) (:bank-account/numeric-code account)) - " - " account-name] - (com/tooltip {:x-bind "tooltip" :class "absolute"} - "Running Balance: " (some->> (:journal-entry-line/running-balance jel) - (format "$%,.2f")))] + " - " account-name] ] [:div.text-left (com/pill {:color :yellow} "Unassigned")]) [:div.text-right.text-underline (format "$%,.2f" (key jel))])) diff --git a/src/clj/auto_ap/ssr/ui.clj b/src/clj/auto_ap/ssr/ui.clj index f27ea6d7..87fd0740 100644 --- a/src/clj/auto_ap/ssr/ui.clj +++ b/src/clj/auto_ap/ssr/ui.clj @@ -32,6 +32,9 @@ [:script {:src "https://unpkg.com/hyperscript.org@0.9.7/dist/_hyperscript.min.js"}] [:script {:src "https://unpkg.com/@popperjs/core@2.11.8/dist/umd/popper.min.js"}] [:script {:src "https://cdn.plaid.com/link/v2/stable/link-initialize.js"}] + [:script { :src "https://cdn.jsdelivr.net/npm/@ryangjchandler/alpine-tooltip@1.x.x/dist/cdn.min.js" :defer true}] + [:link {:rel "stylesheet" :href "https://unpkg.com/tippy.js@6/dist/tippy.css"}] + [:link {:rel "stylesheet" :href "https://unpkg.com/tippy.js@6/themes/light.css"}] (if (= "dev" (:dd-env env)) [:script {:src "https://unpkg.com/htmx.org@1.9.6/dist/htmx.js" :crossorigin= "anonymous"}]