refactor(ssr): de-fake simple-mode account cursor via explicit render (heuristic 1)
simple-mode-fields* rendered its single account row by rebinding the form cursor to a synthetic MapCursor rooted at accounts[0] (faking a deep starting position). Replace that with explicit-data rendering: account-field-name builds the exact field names the cursor would produce at [:step-params :transaction/accounts 0 field] (via path->name2), and account-field-errors reads errors from the same path -- no re-rooted cursor. This is the render-fn rewrite the earlier with-field-default shortcut couldn't be (that mutated the cursor and broke the simple-mode swap). Scorecard: faked cursor roots 2 -> 0 (both heuristic-1 items now clear for this modal). Parity held: swap spec 6/6 (its vendor tests run in simple mode), Shared Location save green, full suite 31 pass / no regression.
This commit is contained in:
@@ -183,10 +183,32 @@
|
||||
(:account/name (d-accounts/clientize (dc/pull (dc/db conn) d-accounts/default-read value)
|
||||
client-id)))})])
|
||||
|
||||
(defn- account-field-name
|
||||
"Explicit form-field name for account row `index`, field `field` -- the same string
|
||||
the form cursor produces at path [:step-params :transaction/accounts index field]
|
||||
(via path->name2), without faking a deep cursor to get there."
|
||||
[index field]
|
||||
(str "step-params[transaction/accounts][" index "]["
|
||||
(if (keyword? field)
|
||||
(str (when (namespace field) (str (namespace field) "/")) (name field))
|
||||
field)
|
||||
"]"))
|
||||
|
||||
(defn- account-field-errors
|
||||
"Errors for account row `index`, field `field`, read straight from the form errors
|
||||
at the same path the cursor would walk -- avoids re-rooting a cursor to look them up."
|
||||
[index field]
|
||||
(when (bound? #'fc/*form-errors*)
|
||||
(get-in fc/*form-errors* [:step-params :transaction/accounts index field])))
|
||||
|
||||
(defn simple-mode-fields*
|
||||
"Renders the simple-mode account + location row and the toggle-to-advanced link.
|
||||
Must be called within a fc/start-form + fc/with-field :step-params context.
|
||||
Caller must establish Alpine x-data with simpleAccountId in scope."
|
||||
Caller must establish Alpine x-data with simpleAccountId in scope.
|
||||
|
||||
The single account row is rendered from explicit data with explicit field names
|
||||
(account-field-name 0 ...) rather than faking a synthetic MapCursor rooted at
|
||||
accounts[0] -- the row always lives at index 0 in simple mode."
|
||||
[request]
|
||||
(let [snapshot (-> request :multi-form-state :snapshot)
|
||||
step-params (-> request :multi-form-state :step-params)
|
||||
@@ -204,50 +226,41 @@
|
||||
(:transaction/amount snapshot)
|
||||
0.0))]
|
||||
[:div
|
||||
(fc/with-field :transaction/accounts
|
||||
(fc/with-cursor (let [cur fc/*current*]
|
||||
(if (sequential? @cur)
|
||||
(nth cur 0 nil)
|
||||
(auto_ap.cursor.MapCursor. {} (cursor/state cur) (conj (cursor/path cur) 0))))
|
||||
[:span
|
||||
(fc/with-field :db/id
|
||||
(com/hidden {:name (fc/field-name)
|
||||
:value row-id}))
|
||||
[:div.flex.gap-2.mt-2
|
||||
(fc/with-field :transaction-account/account
|
||||
(com/validated-field
|
||||
{:label "Account"
|
||||
:errors (fc/field-errors)}
|
||||
[:div.w-72
|
||||
(account-typeahead* {:value account-val
|
||||
:client-id client-id
|
||||
:name (fc/field-name)
|
||||
:x-model "simpleAccountId"})]))
|
||||
(fc/with-field :transaction-account/location
|
||||
;; Selecting the account only affects the valid Location options, so the
|
||||
;; change swaps just this cell -- nothing else needs to re-render.
|
||||
[:div {:id "simple-account-location"}
|
||||
(com/validated-field
|
||||
{:label "Location"
|
||||
:errors (fc/field-errors)
|
||||
:x-hx-val:account-id "simpleAccountId"
|
||||
:hx-vals (hx/json (cond-> {:name (fc/field-name)}
|
||||
client-id (assoc :client-id client-id)))
|
||||
:x-dispatch:changed "simpleAccountId"
|
||||
:hx-trigger "changed"
|
||||
:hx-post (bidi/path-for ssr-routes/only-routes ::route/edit-form-changed)
|
||||
:hx-target "#simple-account-location"
|
||||
:hx-select "#simple-account-location"
|
||||
:hx-swap "outerHTML"
|
||||
:hx-include "closest form"}
|
||||
(location-select*
|
||||
{:name (fc/field-name)
|
||||
:account-location (:account/location account-id)
|
||||
:client-locations (pull-attr (dc/db conn) :client/locations client-id)
|
||||
:value location-val}))])
|
||||
(fc/with-field :transaction-account/amount
|
||||
(com/hidden {:name (fc/field-name)
|
||||
:value total}))]]))
|
||||
[:span
|
||||
(com/hidden {:name (account-field-name 0 :db/id)
|
||||
:value row-id})
|
||||
[:div.flex.gap-2.mt-2
|
||||
(com/validated-field
|
||||
{:label "Account"
|
||||
:errors (account-field-errors 0 :transaction-account/account)}
|
||||
[:div.w-72
|
||||
(account-typeahead* {:value account-val
|
||||
:client-id client-id
|
||||
:name (account-field-name 0 :transaction-account/account)
|
||||
:x-model "simpleAccountId"})])
|
||||
;; Selecting the account only affects the valid Location options, so the
|
||||
;; change swaps just this cell -- nothing else needs to re-render.
|
||||
[:div {:id "simple-account-location"}
|
||||
(com/validated-field
|
||||
{:label "Location"
|
||||
:errors (account-field-errors 0 :transaction-account/location)
|
||||
:x-hx-val:account-id "simpleAccountId"
|
||||
:hx-vals (hx/json (cond-> {:name (account-field-name 0 :transaction-account/location)}
|
||||
client-id (assoc :client-id client-id)))
|
||||
:x-dispatch:changed "simpleAccountId"
|
||||
:hx-trigger "changed"
|
||||
:hx-post (bidi/path-for ssr-routes/only-routes ::route/edit-form-changed)
|
||||
:hx-target "#simple-account-location"
|
||||
:hx-select "#simple-account-location"
|
||||
:hx-swap "outerHTML"
|
||||
:hx-include "closest form"}
|
||||
(location-select*
|
||||
{:name (account-field-name 0 :transaction-account/location)
|
||||
:account-location (:account/location account-id)
|
||||
:client-locations (pull-attr (dc/db conn) :client/locations client-id)
|
||||
:value location-val}))]
|
||||
(com/hidden {:name (account-field-name 0 :transaction-account/amount)
|
||||
:value total})]]
|
||||
[:div.mt-1
|
||||
[:a.text-sm.text-blue-600.hover:underline.cursor-pointer
|
||||
{:hx-post (bidi/path-for ssr-routes/only-routes ::route/edit-wizard-toggle-mode)
|
||||
|
||||
Reference in New Issue
Block a user