Move the remaining static markup out of the bulk-code form view-model and into
the templates, leaving form-ctx as plain data (plus a urls map and two button
contexts). The form/vendor hx-wiring, the status <option> list, the per-row
transition / location-swap / remove wiring, and the field names are now literal
in the templates, built from the row index and the shared urls.
- form.html: form attrs literal; ids render name="ids[N]" via forloop.counter0.
- body.html: vendor-changed wiring literal; status is an inline <select> with
literal options (selected via {% if status.value = ... %}); field wrappers use
{% if has_error %}has-error.
- account-row.html: the <tr> transitions, db/id hidden, location-cell swap and
remove <a> are literal with {{ row.index }} / {{ urls.changed }}; only the
Alpine x-data, errors, and the typeahead/location/money control contexts are
passed as data.
- form-ctx / account-row-vm reduced to data; drop the now-unused
sc/validated-field-classes.
Tradeoff: the status <select> and the remove <a> inline the shared base classes
(those partials can't take literal option labels / per-row wiring), so those two
class strings are duplicated in the bulk-code templates.
Verified: moved wiring correct by targeted checks (ids[N], form/vendor hx-*,
account-row-N, location swap + remove with index, status selected, no unrendered
tags); full browser flow green -- open (3 ids), vendor auto-populate, status
set+persist, add/remove row, submit "Transactions Coded", no JS errors. Shared
component class-sets unchanged (this commit only touches bulk-code).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
3.2 KiB
HTML
35 lines
3.2 KiB
HTML
{# One expense-account row from a loop-bound `row` view-model. All structure, wiring, and
|
|
field names are literal here, built from `row.index` + the shared `urls`; only data (the
|
|
Alpine x-data, db/id, errors, and the typeahead / location / money control contexts)
|
|
comes from the view-model. The location cell (#account-location-N) swaps just itself on
|
|
account change; the remove button swaps the whole #bulk-code-form. #}
|
|
<tr class="account-row border-b dark:border-gray-600 group hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
id="account-row-{{ row.index }}" x-data="{{ row.x_data }}" x-ref="p" x-show="show"
|
|
x-init="$nextTick(() => show=true)"
|
|
x-transition:enter="transition-opacity duration-500" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100"
|
|
x-transition:leave="transition duration-500" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0">
|
|
<input type="hidden" name="accounts[{{ row.index }}][db/id]"{% if row.db_id_value %} value="{{ row.db_id_value }}"{% endif %}>
|
|
<td class="px-4 py-2">
|
|
<div class="group {% if row.account_has_error %}has-error {% endif %}">
|
|
<div class="flex flex-col">{% with width="" x_data=row.account.x_data x_model=row.account.x_model key=row.account.key disabled=row.account.disabled a_xinit=row.account.a_xinit placeholder=row.account.placeholder hidden_attrs=row.account.hidden_attrs %}{% include "templates/components/typeahead.html" %}{% endwith %}</div>
|
|
<p class="mt-2 text-xs text-red-600 dark:text-red-500 h-4">{{ row.account_error }}</p>
|
|
</div>
|
|
</td>
|
|
<td class="px-4 py-2" id="account-location-{{ row.index }}">
|
|
<div class="group {% if row.location_has_error %}has-error {% endif %}"
|
|
hx-post="{{ urls.changed }}" hx-target="#account-location-{{ row.index }}" hx-select="#account-location-{{ row.index }}"
|
|
hx-vals='{"name":"accounts[{{ row.index }}][location]"{% if client_id %},"client-id":{{ client_id }}{% endif %}}'
|
|
x-hx-val:account-id="accountId" x-dispatch:changed="accountId" hx-trigger="changed" hx-swap="outerHTML" hx-include="closest form">
|
|
{% with name=row.location.name variant="w-full" options=row.location.options %}{% include "templates/components/location-select.html" %}{% endwith %}
|
|
<p class="mt-2 text-xs text-red-600 dark:text-red-500 h-4">{{ row.location_error }}</p>
|
|
</div>
|
|
</td>
|
|
<td class="px-4 py-2">
|
|
<div class="group {% if row.pct_has_error %}has-error {% endif %}">
|
|
{% with variant=row.pct.variant attrs=row.pct.attrs %}{% include "templates/components/money-input.html" %}{% endwith %}
|
|
<p class="mt-2 text-xs text-red-600 dark:text-red-500 h-4">{{ row.pct_error }}</p>
|
|
</div>
|
|
</td>
|
|
<td class="px-4 py-2 align-top"><a href="" class="account-remove-action p-3 inline-flex items-center justify-center bg-white dark:bg-gray-600 items-center text-sm font-medium border border-gray-300 dark:border-gray-700 text-center text-gray-500 hover:text-gray-800 rounded-lg dark:text-gray-400 dark:hover:text-gray-100" hx-post="{{ urls.changed }}" hx-vals='{"op":"remove-account","row-index":{{ row.index }}}' hx-target="#bulk-code-form" hx-select="#bulk-code-form" hx-swap="outerHTML" hx-include="closest form"><div class="h-4 w-4">{% include "templates/components/svg-x.html" %}</div></a></td>
|
|
</tr>
|