uses cursors instead, much clearer experience.

This commit is contained in:
2023-10-20 08:54:00 -07:00
parent ce8fa027b2
commit e3443a3dd8
5 changed files with 161 additions and 119 deletions

View File

@@ -126,5 +126,6 @@ elem.dp = new Datepicker(elem, {format: "mm/dd/yyyy", autohide: true});
countRows = function(id) { countRows = function(id) {
var table = document.querySelector(id); var table = document.querySelector(id);
var rows = table.querySelectorAll("tbody tr"); var rows = table.querySelectorAll("tbody tr");
console.log("ROWS", rows.length);
return rows.length; return rows.length;
} }

View File

@@ -20,6 +20,7 @@
[auto-ap.ssr.components :as com] [auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper] [auto-ap.ssr.grid-page-helper :as helper]
[auto-ap.ssr.hx :as hx] [auto-ap.ssr.hx :as hx]
[auto-ap.ssr.form-cursor :as fc]
[auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]] [auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]]
[auto-ap.ssr.svg :as svg] [auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils [auto-ap.ssr.utils
@@ -58,34 +59,13 @@
;; TODO better generation of names? ;; TODO better generation of names?
(def ^:dynamic *errors*)
(def ^:dynamic *prev-cursor* nil)
(def ^:dynamic *cursor* nil)
(defmacro with-cursor [cursor & rest]
`(binding [*prev-cursor* (or *cursor* ~cursor)]
(binding [*cursor* ~cursor]
~@rest)))
(defn cursor-name []
(apply path->name2 (cursor/path *cursor*)))
(defn cursor-value []
@*cursor*)
(defn cursor-errors []
(:errors (get
(meta @*prev-cursor*)
(last (cursor/path *cursor*)))))
(defn filters [request] (defn filters [request]
[:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" [:form {"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
:admin-transaction-rule-table) :admin-transaction-rule-table)
"hx-target" "#transaction-rule-table" "hx-target" "#transaction-rule-table"
"hx-indicator" "#transaction-rule-table"} "hx-indicator" "#transaction-rule-table"}
[:fieldset.space-y-6 [:fieldset.space-y-6
(com/field {:label "Vendor"} (com/field {:label "Vendor"}
@@ -301,7 +281,7 @@
:when (and account-location (not= account-location location))] :when (and account-location (not= account-location location))]
(field-validation-error (str "must be " account-location) (field-validation-error (str "must be " account-location)
[:transaction-rule/accounts i :transaction-rule-account/location] [:transaction-rule/accounts i :transaction-rule-account/location]
:form entity)) :form form-params))
total (reduce + total (reduce +
0.0 0.0
@@ -309,14 +289,14 @@
(:transaction-rule/accounts entity))) (:transaction-rule/accounts entity)))
_ (when-not (dollars= 1.0 total) _ (when-not (dollars= 1.0 total)
(form-validation-error (format "Expense accounts total (%d%%) must add to 100%%" (int (* 100.0 total))) (form-validation-error (format "Expense accounts total (%d%%) must add to 100%%" (int (* 100.0 total)))
:form entity)) :form form-params))
_ (when (and (:transaction-rule/bank-account entity) _ (when (and (:transaction-rule/bank-account entity)
(not (bank-account-belongs-to-client? (:transaction-rule/bank-account entity) (not (bank-account-belongs-to-client? (:transaction-rule/bank-account entity)
(:transaction-rule/client entity)))) (:transaction-rule/client entity))))
(field-validation-error "does not belong to client" (field-validation-error "does not belong to client"
[:transaction-rule/bank-account] [:transaction-rule/bank-account]
:form entity)) :form form-params))
{:keys [tempids]} (audit-transact [[:upsert-entity entity]] {:keys [tempids]} (audit-transact [[:upsert-entity entity]]
@@ -366,13 +346,12 @@
(defn- transaction-rule-account-row* (defn- transaction-rule-account-row*
[transaction-rule account] [transaction-rule account]
(com/data-grid-row {} (com/data-grid-row {}
(let [account-name (with-cursor (:transaction-rule-account/account account) (let [account-name (fc/field-name (:transaction-rule-account/account account))]
(cursor-name))]
(list (list
(with-cursor (:db/id account) (fc/with-field :db/id
(com/hidden {:name (cursor-name) (com/hidden {:name (fc/field-name)
:value (cursor-value)})) :value (fc/field-value)}))
(with-cursor (:transaction-rule-account/account account) (fc/with-field :transaction-rule-account/account
(com/data-grid-cell {} (com/data-grid-cell {}
[:div {:hx-trigger (hx/trigger-field-change :name "transaction-rule/client" [:div {:hx-trigger (hx/trigger-field-change :name "transaction-rule/client"
:from "#edit-form") :from "#edit-form")
@@ -384,11 +363,15 @@
account-name "value"}) account-name "value"})
:hx-get (str (bidi/path-for ssr-routes/only-routes :admin-transaction-rule-account-typeahead)) :hx-get (str (bidi/path-for ssr-routes/only-routes :admin-transaction-rule-account-typeahead))
:hx-swap "innerHTML"} :hx-swap "innerHTML"}
(account-typeahead* {:value (cursor-value) (account-typeahead* {:value (fc/field-value)
:client-id (:db/id (:transaction-rule/client transaction-rule)) :client-id (:db/id (:transaction-rule/client transaction-rule))
:name (cursor-name)}) :name (fc/field-name)})
(com/errors {:errors (cursor-errors)})])) (println "HERE" (cursor/path fc/*current*))
(with-cursor (:transaction-rule-account/location account) (println "DATA "fc/*form-data*)
(println "ERR" fc/*form-errors*)
(println (fc/field-errors))
(com/errors {:errors (fc/field-errors)})]))
(fc/with-field :transaction-rule-account/location
(com/data-grid-cell {} (com/data-grid-cell {}
[:div [:div {:hx-trigger (hx/triggers [:div [:div {:hx-trigger (hx/triggers
(hx/trigger-field-change :name "transaction-rule/client" (hx/trigger-field-change :name "transaction-rule/client"
@@ -396,36 +379,36 @@
(hx/trigger-field-change :name account-name (hx/trigger-field-change :name account-name
:from "#edit-form")) :from "#edit-form"))
:hx-include "#edit-form" :hx-include "#edit-form"
:hx-vals (hx/vals {:name (cursor-name)}) :hx-vals (hx/vals {:name (fc/field-name)})
:hx-ext "rename-params" :hx-ext "rename-params"
:hx-rename-params-ex (hx/json {"transaction-rule/client" "client-id" :hx-rename-params-ex (hx/json {"transaction-rule/client" "client-id"
account-name "account-id" account-name "account-id"
"name" "name" "name" "name"
(cursor-name) "value"}) (fc/field-name) "value"})
:hx-get (bidi/path-for ssr-routes/only-routes :admin-transaction-rule-location-select) :hx-get (bidi/path-for ssr-routes/only-routes :admin-transaction-rule-location-select)
:hx-swap "innerHTML"} :hx-swap "innerHTML"}
(location-select* {:name (cursor-name) (location-select* {:name (fc/field-name)
:account-location (:account/location (cond->> (:transaction-rule-account/account @account) :account-location (:account/location (cond->> (:transaction-rule-account/account @account)
(nat-int? (:transaction-rule-account/account @account)) (dc/pull (dc/db conn) (nat-int? (:transaction-rule-account/account @account)) (dc/pull (dc/db conn)
'[:account/location]))) '[:account/location])))
:client-locations (:client/locations (:transaction-rule/client transaction-rule)) :client-locations (:client/locations (:transaction-rule/client transaction-rule))
:value (cursor-value)})] :value (fc/field-value)})]
(com/errors {:errors (cursor-errors)})] (com/errors {:errors (fc/field-errors)})]
)) ))
(with-cursor (:transaction-rule-account/percentage account) (fc/with-field :transaction-rule-account/percentage
(com/data-grid-cell (com/money-input {:name (cursor-name) (com/data-grid-cell (com/money-input {:name (fc/field-name)
:class "w-16" :class "w-16"
:value (some-> (cursor-value) :value (some-> (fc/field-value)
(* 100 ) (* 100 )
(long ))}) (long ))})
(com/errors {:errors (cursor-errors)}))))) (com/errors {:errors (fc/field-errors)})))))
(com/data-grid-cell (com/data-grid-cell
(com/a-icon-button (com/a-icon-button
{"_" (hiccup/raw "on click halt the event then transition the closest <tr />'s opacity to 0 then remove closest <tr />") {"_" (hiccup/raw "on click halt the event then transition the closest <tr />'s opacity to 0 then remove closest <tr />")
:href "#"} :href "#"}
svg/x)))) svg/x))))
(defn dialog* [& {:keys [ entity form-params]}] (defn dialog* [& {:keys [ entity form-params form-errors]}]
(com/modal (com/modal
{:modal-class "max-w-4xl"} {:modal-class "max-w-4xl"}
(com/modal-card (com/modal-card
@@ -438,100 +421,102 @@
form-params) form-params)
[:fieldset {:class "hx-disable" :hx-disinherit "hx-target"} [:fieldset {:class "hx-disable" :hx-disinherit "hx-target"}
(with-cursor (cursor/cursor entity) (fc/start-form entity form-errors
[:div.space-y-2 [:div.space-y-2
(when-let [id (:db/id entity)] (when-let [id (:db/id entity)]
(com/hidden {:name "db/id" (com/hidden {:name "db/id"
:value id})) :value id}))
(with-cursor (:transaction-rule/client *cursor*)
(fc/with-field :transaction-rule/client
(com/validated-field (com/validated-field
{:label "Client" {:label "Client"
:errors (cursor-errors)} :errors (fc/field-errors)}
[:div.w-96 [:div.w-96
(com/typeahead {:name (cursor-name) (com/typeahead {:name (fc/field-name)
:class "w-96" :class "w-96"
:placeholder "Search..." :placeholder "Search..."
:url (bidi/path-for ssr-routes/only-routes :company-search) :url (bidi/path-for ssr-routes/only-routes :company-search)
:id (str "form-client-search") :id (str "form-client-search")
:value (cursor-value) :value (fc/field-value)
:value-fn (some-fn :db/id identity) :value-fn (some-fn :db/id identity)
:content-fn (fn [c] (cond->> c :content-fn (fn [c] (cond->> c
(nat-int? c) (dc/pull (dc/db conn) '[:client/name]) (nat-int? c) (dc/pull (dc/db conn) '[:client/name])
true :client/name))})])) true :client/name))})]))
(with-cursor (:transaction-rule/bank-account *cursor*) (fc/with-field :transaction-rule/bank-account
(com/validated-field {:label "Bank Account" (com/validated-field {:label "Bank Account"
:errors (cursor-errors)} :errors (fc/field-errors)}
[:div#bank-account-spot.w-96 {:hx-get (bidi/path-for ssr-routes/only-routes :bank-account-typeahead) [:div#bank-account-spot.w-96 {:hx-get (bidi/path-for ssr-routes/only-routes :bank-account-typeahead)
:hx-trigger (hx/trigger-field-change :name "transaction-rule/client" :hx-trigger (hx/trigger-field-change :name "transaction-rule/client"
:from "#edit-form") :from "#edit-form")
:hx-swap "innerHTML" :hx-swap "innerHTML"
:hx-ext "rename-params" :hx-ext "rename-params"
:hx-include "#edit-form" :hx-include "#edit-form"
:hx-vals (hx/vals {:name (cursor-name)}) :hx-vals (hx/vals {:name (fc/field-name)})
:hx-rename-params-ex (cheshire/generate-string {"transaction-rule/client" "client-id" :hx-rename-params-ex (cheshire/generate-string {"transaction-rule/client" "client-id"
"name" "name"})} "name" "name"})}
(bank-account-typeahead* {:client-id ((some-fn :db/id identity) (:transaction-rule/client entity)) (bank-account-typeahead* {:client-id ((some-fn :db/id identity) (:transaction-rule/client entity))
:name (cursor-name) :name (fc/field-name)
:value (cursor-value)})])) :value (fc/field-value)})]))
(with-cursor (:transaction-rule/description *cursor*) (fc/with-field :transaction-rule/description
(com/validated-field {:label "Description" (com/validated-field {:label "Description"
:errors (cursor-errors)} :errors (fc/field-errors)}
(com/text-input {:name (cursor-name) (com/text-input {:name (fc/field-name)
:placeholder "HOME DEPOT" :placeholder "HOME DEPOT"
:class "w-96" :class "w-96"
:value (cursor-value)}))) :value (fc/field-value)})))
(com/field {:label "Amount"} (com/field {:label "Amount"}
[:div.flex.gap-2 [:div.flex.gap-2
(with-cursor (:transaction-rule/amount-gte *cursor*) (fc/with-field :transaction-rule/amount-gte
[:div.flex.flex-col [:div.flex.flex-col
(com/money-input {:name (cursor-name) (com/money-input {:name (fc/field-name)
:placeholder ">=" :placeholder ">="
:class "w-24" :class "w-24"
:value (cursor-value)}) :value (fc/field-value)})
(com/errors {:errors (cursor-errors)})]) (com/errors {:errors (fc/field-errors)})])
(with-cursor (:transaction-rule/amount-lte *cursor*) (fc/with-field :transaction-rule/amount-lte
[:div.flex.flex-col [:div.flex.flex-col
(com/money-input {:name (cursor-name) (com/money-input {:name (fc/field-name)
:placeholder "<=" :placeholder "<="
:class "w-24" :class "w-24"
:value (cursor-value)}) :value (fc/field-value)})
(com/errors {:errors (cursor-errors)})])]) (com/errors {:errors (fc/field-errors)})])])
(com/field {:label "Day of month"} (com/field {:label "Day of month"}
[:div.flex.gap-2 [:div.flex.gap-2
(with-cursor (:transaction-rule/dom-gte *cursor*) (fc/with-field :transaction-rule/dom-gte
[:div.flex.flex-col [:div.flex.flex-col
(com/int-input {:name (cursor-name) (com/int-input {:name (fc/field-name)
:placeholder ">=" :placeholder ">="
:class "w-24" :class "w-24"
:value (cursor-value)}) :value (fc/field-value)})
(com/errors {:errors (cursor-errors)})]) (com/errors {:errors (fc/field-errors)})])
(with-cursor (:transaction-rule/dom-lte *cursor*) (fc/with-field :transaction-rule/dom-lte
[:div.flex.flex-col [:div.flex.flex-col
(com/int-input {:name (cursor-name) (com/int-input {:name (fc/field-name)
:placeholder ">=" :placeholder ">="
:class "w-24" :class "w-24"
:value (cursor-value)}) :value (fc/field-value)})
(com/errors {:errors (cursor-errors)})])]) (com/errors {:errors (fc/field-errors)})])])
[:h2.text-lg "Outcomes"] [:h2.text-lg "Outcomes"]
(with-cursor (:transaction-rule/vendor *cursor*) (fc/with-field :transaction-rule/vendor
(com/validated-field {:label "Assign Vendor" (com/validated-field {:label "Assign Vendor"
:errors (cursor-errors)} :errors (fc/field-errors)}
[:div.w-96 [:div.w-96
(com/typeahead {:name (cursor-name) (com/typeahead {:name (fc/field-name)
:placeholder "Search..." :placeholder "Search..."
:url (bidi/path-for ssr-routes/only-routes :vendor-search) :url (bidi/path-for ssr-routes/only-routes :vendor-search)
:id (str "form-vendor-search") :id (str "form-vendor-search")
:value (cursor-value) :value (fc/field-value)
:value-fn (some-fn :db/id identity) :value-fn (some-fn :db/id identity)
:content-fn (some-fn :vendor/name #(pull-attr (dc/db conn) :vendor/name %))})])) :content-fn (some-fn :vendor/name #(pull-attr (dc/db conn) :vendor/name %))})]))
(with-cursor (:transaction-rule/accounts *cursor*) (fc/with-field :transaction-rule/accounts
(list (list
(com/data-grid {:headers [(com/data-grid-header {} (com/data-grid {:headers [(com/data-grid-header {}
"Account") "Account")
@@ -539,10 +524,11 @@
(com/data-grid-header {:class "w-16"} "%") (com/data-grid-header {:class "w-16"} "%")
(com/data-grid-header {:class "w-16"})] (com/data-grid-header {:class "w-16"})]
:id "transaction-rule-account-table"} :id "transaction-rule-account-table"}
(for [tra *cursor*] (when @fc/*current*
(with-cursor tra (doall (for [tra fc/*current*]
(transaction-rule-account-row* entity tra)))) (fc/with-cursor tra
(com/errors {:errors (cursor-errors)}))) (transaction-rule-account-row* entity tra))))))
(com/errors {:errors (fc/field-errors)})))
(com/a-button {:hx-get (bidi/path-for ssr-routes/only-routes (com/a-button {:hx-get (bidi/path-for ssr-routes/only-routes
:admin-transaction-rule-new-account) :admin-transaction-rule-new-account)
:hx-include "#edit-form" :hx-include "#edit-form"
@@ -553,36 +539,41 @@
:hx-target "#transaction-rule-account-table tbody" :hx-target "#transaction-rule-account-table tbody"
:hx-swap "beforeend"} :hx-swap "beforeend"}
"New account") "New account")
(with-cursor (:transaction-rule/transaction-approval-status *cursor*) (fc/with-field :transaction-rule/transaction-approval-status
(com/radio {:options (ref->radio-options "transaction-approval-status") (com/validated-field {:label "Approval status"
:value (cursor-value) :errors (fc/field-errors)}
:name (cursor-name)})) (com/radio {:options (ref->radio-options "transaction-approval-status")
:value (fc/field-value)
:name (fc/field-name)})))
[:div#form-errors [:span.error-content [:div#form-errors [:span.error-content
(com/errors {:errors (:errors (meta entity))})]] (com/errors {:errors (:errors fc/*form-errors*)})]]
(com/button {:color :primary :form "edit-form" :type "submit"} (com/button {:color :primary :form "edit-form" :type "submit"}
"Save")])]] "Save")])]]
[:div]))) [:div])))
(defn new-account [{{:keys [client-id index]} :query-params}] (defn new-account [{{:keys [client-id index]} :query-params}]
(let [transaction-rule {:transaction-rule/client (dc/pull (dc/db conn) '[:client/name :client/locations :db/id] (let [index (or index 0) ;; TODO schema decode is not working
transaction-rule {:transaction-rule/client (dc/pull (dc/db conn) '[:client/name :client/locations :db/id]
client-id) client-id)
:transaction-rule/accounts (conj (into [] (repeat (inc index) {} )) :transaction-rule/accounts (conj (into [] (repeat (inc index) {} ))
{:db/id (str (java.util.UUID/randomUUID)) {:db/id (str (java.util.UUID/randomUUID))
:transaction-rule-account/location "Shared"})}] :transaction-rule-account/location "Shared"})}]
(html-response (html-response
(with-cursor (cursor/cursor transaction-rule) (fc/start-form transaction-rule []
(with-cursor (:transaction-rule/accounts *cursor*) (fc/with-cursor (get-in fc/*current* [:transaction-rule/accounts index])
(with-cursor (nth *cursor* index) (transaction-rule-account-row*
(transaction-rule-account-row* ;; TODO store a pointer to the "head " cursor for errors instead of nesting them
;; TODO store a pointer to the "head " cursor for errors instead of nesting them ;; makes it so you don't have to do this
;; makes it so you don't have to do this transaction-rule
transaction-rule fc/*current*))))))
*cursor*
)))))))
;; TODO check to see if it should be called "Shared" or "shared" for the value ;; TODO check to see if it should be called "Shared" or "shared" for the value
;; TODO blank location is being allowed
;; TODO hydrate nested types more easily. make it easy to hydrate so you don't do weird sometimes pulls
;; TODO is it possible to make it easy to get a virtual cursor in the case of adding a new row? setting up
;; fake data doesn't feel right - maybe have a "prelude" that's dynamic
(defn location-select [{{:keys [name account-id client-id value] :as qp} :query-params}] (defn location-select [{{:keys [name account-id client-id value] :as qp} :query-params}]
(html-response (location-select* {:name name (html-response (location-select* {:name name
@@ -613,15 +604,22 @@
(defn transaction-rule-error [request] (defn transaction-rule-error [request]
(let [entity (some-> request :last-form)] (let [entity (some-> request :last-form)]
(html-response (dialog* :entity entity) (html-response (dialog* :entity entity
:form-errors (:form-errors request)
:form-params (if (:db/id entity)
{:hx-put (str (bidi/path-for ssr-routes/only-routes
:admin-transaction-rule-edit-save))}
{:hx-post (str (bidi/path-for ssr-routes/only-routes
:admin-transaction-rule-edit-save))}))
:headers {"hx-retarget" "#edit-form fieldset" :headers {"hx-retarget" "#edit-form fieldset"
"hx-reselect" "#edit-form fieldset"}))) "hx-reselect" "#edit-form fieldset"})))
(defn account-new-dialog [_] (defn transaction-rule-new-dialog [_]
(html-response (dialog* :account nil (html-response (dialog* :entity {}
:form-errors {}
:form-params {:hx-post (str (bidi/path-for ssr-routes/only-routes :form-params {:hx-post (str (bidi/path-for ssr-routes/only-routes
:admin-account-new-save))}) :admin-transaction-rule-edit-save))})
:headers {"hx-trigger" "modalOpening"})) :headers {"hx-trigger" "modalOpening"}))
(def transaction-rule-schema (mc/schema (def transaction-rule-schema (mc/schema
@@ -653,7 +651,8 @@
(wrap-schema-decode :query-schema [:map (wrap-schema-decode :query-schema [:map
[:client-id {:optional true} [:client-id {:optional true}
[:maybe entity-id]] [:maybe entity-id]]
[:index nat-int?]]) [:index {:optional true
:default 0} [nat-int? {:default 0}]]])
wrap-admin wrap-client-redirect-unauthenticated) wrap-admin wrap-client-redirect-unauthenticated)
:admin-transaction-rule-location-select (-> location-select :admin-transaction-rule-location-select (-> location-select
(wrap-schema-decode :query-schema [:map (wrap-schema-decode :query-schema [:map
@@ -675,7 +674,7 @@
(wrap-form-4xx-2 transaction-rule-error)) (wrap-form-4xx-2 transaction-rule-error))
:admin-transaction-rule-edit-dialog (-> transaction-rule-edit-dialog :admin-transaction-rule-edit-dialog (-> transaction-rule-edit-dialog
(wrap-schema-decode :route-schema [:map [:db/id entity-id]])) (wrap-schema-decode :route-schema [:map [:db/id entity-id]]))
:admin-transaction-rule-new-dialog account-new-dialog}) :admin-transaction-rule-new-dialog transaction-rule-new-dialog})
(fn [h] (fn [h]
(-> h (-> h
(wrap-admin) (wrap-admin)

View File

@@ -123,7 +123,9 @@ c.clearChoices();
:key (:error-key params)}))]) :key (:error-key params)}))])
(defn errors- [{:keys [errors]}] (defn errors- [{:keys [errors]}]
[:p.mt-2.text-xs.text-red-600.dark:text-red-500.h-4 (str/join ", " errors)]) [:p.mt-2.text-xs.text-red-600.dark:text-red-500.h-4
(when (sequential? errors)
(str/join ", " (filter string? errors)))])
(defn validated-field- [params & rest] (defn validated-field- [params & rest]
(field- (dissoc params :errors) (field- (dissoc params :errors)

View File

@@ -0,0 +1,38 @@
(ns auto-ap.ssr.form-cursor
(:require [auto-ap.ssr.utils :refer [path->name2]]
[auto-ap.cursor :as cursor]))
(def ^:dynamic *form-data*)
(def ^:dynamic *form-errors*)
(def ^:dynamic *prev-cursor* nil)
(def ^:dynamic *current* nil)
(defmacro start-form [form-data errors & rest]
`(binding [*form-data* ~form-data
*form-errors* (or ~errors {})]
(binding [*current* (cursor/cursor *form-data*)]
~@rest)))
(defmacro with-cursor [cursor & rest]
`(binding [*current* ~cursor]
~@rest))
(defmacro with-field [field & rest]
`(with-cursor (get *current* ~field )
~@rest))
(defn field-name
([] (field-name *current*))
([cursor]
(apply path->name2 (cursor/path cursor))))
(defn field-value []
@*current*)
(defn field-errors
([]
(field-errors *current*))
([cursor]
(get-in *form-errors* (cursor/path cursor))))

View File

@@ -151,8 +151,7 @@
(defn field-validation-error [m path & {:as data}] (defn field-validation-error [m path & {:as data}]
(throw+ (ex-info m (merge data {:type :field-validation (throw+ (ex-info m (merge data {:type :field-validation
:field-validation-errors [{:path path :form-errors (assoc-in {} path [m])}))))
:message [m]}]}))))
(defn form-validation-error [m & {:as data}] (defn form-validation-error [m & {:as data}]
(throw+ (ex-info m (merge data {:type :form-validation (throw+ (ex-info m (merge data {:type :form-validation
@@ -164,7 +163,8 @@
(mt2/key-transformer {:encode keyword->str :decode str->keyword}) (mt2/key-transformer {:encode keyword->str :decode str->keyword})
mt2/string-transformer mt2/string-transformer
mt2/json-transformer mt2/json-transformer
(mt2/transformer {:name :arbitrary}))) (mt2/transformer {:name :arbitrary})
mt2/default-value-transformer))
(defn wrap-schema-decode [handler & {:keys [form-schema query-schema route-schema params-schema]}] (defn wrap-schema-decode [handler & {:keys [form-schema query-schema route-schema params-schema]}]
(fn [{:keys [form-params query-params params] :as request}] (fn [{:keys [form-params query-params params] :as request}]
@@ -290,18 +290,20 @@
(:errors (:explain (:error e))))] (:errors (:explain (:error e))))]
(alog/warn ::form-4xx :errors errors) (alog/warn ::form-4xx :errors errors)
(form-handler (assoc request (form-handler (assoc request
:last-form (assoc-errors-into-meta (:decoded e) errors) :last-form (:decoded e)
:field-validation-errors errors))) :field-validation-errors errors
:form-errors humanized)))
#_(html-response [:span.error-content.text-red-500 (:message &throw-context)] #_(html-response [:span.error-content.text-red-500 (:message &throw-context)]
:status 400)) :status 400))
(catch [:type :field-validation] e (catch [:type :field-validation] e
(form-handler (assoc request (form-handler (assoc request
:last-form (assoc-errors-into-meta (:form e) (:field-validation-errors e)) :last-form (:form e)
:field-validation-errors (:field-validation-errors e)))) :form-errors (:form-errors e))))
(catch [:type :form-validation] e (catch [:type :form-validation] e
(form-handler (assoc request (form-handler (assoc request
:last-form (with-meta (:form e) {:errors (:form-validation-errors e)}) :last-form (:form e)
:form-validation-errors (:form-validation-errors e))))))) :form-validation-errors (:form-validation-errors e)
:form-errors {:errors (:form-validation-errors e)}))))))
(defn apply-middleware-to-all-handlers [key->handler f] (defn apply-middleware-to-all-handlers [key->handler f]