From 71d7461eb9394502423562391e1b975cf147e005 Mon Sep 17 00:00:00 2001 From: Bryce Date: Mon, 4 Nov 2024 13:23:37 -0800 Subject: [PATCH] Better experience for adding new journal entry --- src/clj/auto_ap/ssr/components/data_grid.clj | 21 ++--- src/clj/auto_ap/ssr/ledger.clj | 5 +- src/clj/auto_ap/ssr/ledger/common.clj | 4 +- src/clj/auto_ap/ssr/ledger/new.clj | 91 ++++++++++++-------- 4 files changed, 73 insertions(+), 48 deletions(-) diff --git a/src/clj/auto_ap/ssr/components/data_grid.clj b/src/clj/auto_ap/ssr/components/data_grid.clj index 97239a48..400a7929 100644 --- a/src/clj/auto_ap/ssr/components/data_grid.clj +++ b/src/clj/auto_ap/ssr/components/data_grid.clj @@ -135,20 +135,21 @@ (defn new-row- [{:keys [index colspan tr-params row-offset] :as params} & content] (row- (merge {:class "new-row" +"x-on:htmx:after-settle.camel" "let options=$el.parentNode.querySelectorAll('tr'); let target=options[options.length-2]; $nextTick(() => $focus.within(target).first())" + :x-data (hx/json {:newRowIndex index - :offset (or row-offset 0)}) - } + :offset (or row-offset 0)}) } tr-params) (cell- {:colspan colspan :class "bg-gray-100"} [:div.flex.justify-center (a-button- (merge - (dissoc params :index :colspan) - { - "@click.prevent" "$dispatch('newRow', {index: (newRowIndex++)})" - :color :secondary - :hx-trigger "newRow" - :hx-vals (hiccup/raw "js:{index: event.detail.index }") - :hx-target "closest .new-row" - :hx-swap "beforebegin"}) + (dissoc params :index :colspan) + {"@click.prevent" "$dispatch('newRow', {index: (newRowIndex++)})" + :color :secondary + :hx-trigger "newRow" + :hx-vals (hiccup/raw "js:{index: event.detail.index }") + :hx-target "closest .new-row" + :hx-swap "beforebegin" + }) content)]))) diff --git a/src/clj/auto_ap/ssr/ledger.clj b/src/clj/auto_ap/ssr/ledger.clj index 265e3502..f7244110 100644 --- a/src/clj/auto_ap/ssr/ledger.clj +++ b/src/clj/auto_ap/ssr/ledger.clj @@ -22,6 +22,7 @@ [auto-ap.ssr.ledger.cash-flows :as cash-flows] [auto-ap.ssr.ledger.common :refer [bank-account-filter default-read fetch-ids grid-page query-schema]] + [auto-ap.ssr.ledger.common :as ledger.common] [auto-ap.ssr.ledger.investigate :as investigate] [auto-ap.ssr.ledger.new :as new] [auto-ap.ssr.ledger.profit-and-loss :as profit-and-loss] @@ -76,7 +77,7 @@ ;; TODO test as a real user -(def row* (partial helper/row* grid-page)) + (defn delete [{invoice :entity :as request identity :identity}] (exception->notification @@ -103,7 +104,7 @@ (:invoice/expense-accounts invoice))}]] identity) - (html-response (row* (:identity request) (dc/pull (dc/db conn) default-read (:db/id invoice)) + (html-response (ledger.common/row* (:identity request) (dc/pull (dc/db conn) default-read (:db/id invoice)) {:class "live-removed"}) :headers {"hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" (:db/id invoice))})) diff --git a/src/clj/auto_ap/ssr/ledger/common.clj b/src/clj/auto_ap/ssr/ledger/common.clj index 8fccd9e5..1430a9ee 100644 --- a/src/clj/auto_ap/ssr/ledger/common.clj +++ b/src/clj/auto_ap/ssr/ledger/common.clj @@ -527,4 +527,6 @@ :transactions) {:exact-match-id (:db/id (:journal-entry/original-entity i))}) :color :primary - :content (format "Transaction '%s'" (-> i :journal-entry/original-entity :transaction/description-original))}))))}]})) \ No newline at end of file + :content (format "Transaction '%s'" (-> i :journal-entry/original-entity :transaction/description-original))}))))}]})) + +(def row* (partial helper/row* grid-page)) \ No newline at end of file diff --git a/src/clj/auto_ap/ssr/ledger/new.clj b/src/clj/auto_ap/ssr/ledger/new.clj index 5c7bebf1..b089d72f 100644 --- a/src/clj/auto_ap/ssr/ledger/new.clj +++ b/src/clj/auto_ap/ssr/ledger/new.clj @@ -1,6 +1,6 @@ (ns auto-ap.ssr.ledger.new (:require - [auto-ap.datomic :refer [conn pull-attr]] + [auto-ap.datomic :refer [audit-transact conn pull-attr]] [auto-ap.datomic.accounts :as d-accounts] [auto-ap.datomic.accounts :as a] [auto-ap.logging :as alog] @@ -12,6 +12,7 @@ [auto-ap.ssr.components :as com] [auto-ap.ssr.form-cursor :as fc] [auto-ap.ssr.hx :as hx] + [auto-ap.ssr.ledger.common :as ledger.common] [auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]] [auto-ap.ssr.svg :as svg] [auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers check-allowance @@ -20,10 +21,13 @@ wrap-form-4xx-2 wrap-schema-enforce]] [auto-ap.time :as atime] [bidi.bidi :as bidi] + [clj-time.coerce :as coerce] [clojure.string :as str] [datomic.api :as dc] - [iol-ion.query :refer [dollars=]]) - (:import [java.util UUID])) + [iol-ion.query :refer [dollars=]] + [iol-ion.utils :refer [remove-nils]]) + (:import + [java.util UUID])) (def new-ledger-schema [:and @@ -179,26 +183,31 @@ (defn form* [request] (alog/peek :FP (:form-errors request)) (let [client (some-> request :form-params :journal-entry/client) - client-locations (some-> client :client/locations)] + client-locations (some-> client :client/locations) + extant? false] ;;TODO (fc/start-form (:form-params request) (:form-errors request) [:div.flex.gap-4.flex-col {:x-data (hx/json {:clientId (or (:db/id (fc/field-value (:journal-entry/client fc/*current*))) (:db/id (:client request))) - :vendorId (:db/id (fc/field-value (:journal-entry/vendor fc/*current*))) })} + :vendorId (:db/id (fc/field-value (:journal-entry/vendor fc/*current*)))})} (fc/with-field :journal-entry/client - (com/validated-field - {:label "Client" - :errors (fc/field-errors)} - [:div.w-96 - (com/typeahead {:name (fc/field-name) - :error? (fc/error?) - :class "w-96" - :placeholder "Search..." - :url (bidi/path-for ssr-routes/only-routes :company-search) - :value (fc/field-value) - :value-fn :db/id - :content-fn :client/name - :x-model "clientId"})])) + (if (or (:client request) extant?) + (com/hidden {:name (fc/field-name) + :value (:db/id (:client request))}) + [:div.w-96 + (com/validated-field + {:label "Client" + :errors (fc/field-errors)} + [:div.w-96 + (com/typeahead {:name (fc/field-name) + :error? (fc/error?) + :class "w-96" + :placeholder "Search..." + :url (bidi/path-for ssr-routes/only-routes :company-search) + :value (fc/field-value) + :value-fn :db/id + :content-fn :client/name + :x-model "clientId"})])])) (fc/with-field :journal-entry/date (com/validated-field {:label "Date" @@ -265,23 +274,35 @@ [:div (com/button {:color :primary} "Save")])]))) (defn new-submit [request] - @(dc/transact conn - [(-> (:form-params request) - (update :journal-entry/client :db/id) - (update :journal-entry/vendor :db/id) - (update :journal-entry/line-items - (fn [li] - (mapv - #(update % :journal-entry-line/account :db/id) - li))) - (assoc :journal-entry/external-id (str "manual-" (UUID/randomUUID))))]) - - - (html-response - [:div "GOOD"] - :headers (cond-> {"hx-trigger" "modalclose" - #_#_"hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" (:db/id invoice)) - #_#_"hx-reswap" "outerHTML"}))) + (let [id (:db/id (:form-params request)) + entity (cond-> (-> (:form-params request) + (update :journal-entry/date coerce/to-date) + (update :journal-entry/client :db/id) + (update :journal-entry/vendor :db/id) + (update :journal-entry/line-items + (fn [li] + (mapv + #(remove-nils (update % :journal-entry-line/account :db/id)) + li))) + (assoc :journal-entry/external-id (str "manual-" (UUID/randomUUID)))) + (= :post (:request-method request)) (assoc :db/id "new")) + {:keys [tempids]} (audit-transact [[:upsert-entity entity]] + (:identity request)) + updated-entity (dc/pull (dc/db conn) + ledger.common/default-read + (or (get tempids (:db/id entity)) (:db/id entity)))] + + (html-response + (ledger.common/row* identity updated-entity + {:flash? true + :request request}) + :headers (cond-> {"hx-trigger" "modalclose"} + (= :put (:request-method request)) + (assoc "hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" id) + "hx-reswap" "outerHTML") + (= :post (:request-method request)) + (assoc "hx-retarget" "#entity-table tbody" + "hx-reswap" "afterbegin"))))) (def key->handler