ux(labels): close remaining Adjustments-tab display gaps

Final whole-impl review on bce2619 caught two user-facing surfaces
still showing DB values instead of display labels:

1. By-Type group headers - _group_adjustments() used adj.type as
   both the visible label AND the CSS data-type attribute. Split
   into group.label (short display, for visible text) and
   group.type_key (raw DB value, for the [data-type="X"] CSS
   border-left selector).

2. Type filter popover checkboxes - adj_type_choices was a flat
   list of DB values, so checkbox labels read "New Loan" /
   "Advance Payment" / "Advance Repayment". Replaced with
   PayrollAdjustment.TYPE_CHOICES (already a (db_value,
   display_label) tuple list), and updated the template loop to
   unpack both - label in <span>, DB value in the input value=.

Both surfaces now show Loan / Advance / Advance Repaid while
preserving the canonical DB values for CSS selectors + filter
form submissions.

Tests: 69/69.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Konrad du Plessis 2026-04-24 10:29:25 +02:00
parent bce2619a71
commit f159a9f6f2
2 changed files with 22 additions and 11 deletions

View File

@ -585,12 +585,12 @@
<input type="search" class="form-control form-control-sm mb-2"
placeholder="Search types..." data-popover-search>
<div class="adj-checkbox-list" data-popover-list>
{% for t in adj_type_choices %}
{% for value, label in adj_type_choices %}
<label class="d-flex align-items-center gap-2 py-1 adj-cb-row">
<input type="checkbox" class="form-check-input adj-filter-cb"
data-adj-filter="type" value="{{ t }}"
{% if t in adj_filter_values.type %}checked{% endif %}>
<span class="adj-cb-label">{{ t }}</span>
data-adj-filter="type" value="{{ value }}"
{% if value in adj_filter_values.type %}checked{% endif %}>
<span class="adj-cb-label">{{ label }}</span>
</label>
{% endfor %}
</div>
@ -915,7 +915,7 @@
{% for group in adj_groups %}
<tbody>
<tr class="adj-group-header"
{% if adj_filter_values.group_by == 'type' %}data-type="{{ group.label }}"{% endif %}
{% if adj_filter_values.group_by == 'type' %}data-type="{{ group.type_key|default:group.label }}"{% endif %}
data-bs-toggle="collapse"
data-bs-target="#adj-group-{{ group.slug }}"
aria-expanded="true" aria-controls="adj-group-{{ group.slug }}">

View File

@ -2565,10 +2565,17 @@ def _group_adjustments(adjustments, group_by):
groups = []
for key, rows in buckets.items():
if group_by == 'type':
label = key
# Visible header text uses the short display label (e.g. "Loan",
# "Advance", "Advance Repaid") from the model's TYPE_CHOICES.
label = rows[0].get_type_display()
# type_key holds the raw DB value so the template can emit it as
# data-type="..." for the [data-type="X"] CSS border-left accent
# selectors that still key on the canonical DB value.
type_key = key
slug = key.lower().replace(' ', '-')
else: # worker
label = rows[0].worker.name
type_key = None
slug = f'worker-{key}'
net_sum = sum(
(r.amount if r.type in ADDITIVE_TYPES else -r.amount)
@ -2576,6 +2583,7 @@ def _group_adjustments(adjustments, group_by):
)
groups.append({
'label': label,
'type_key': type_key,
'slug': slug,
'rows': rows,
'count': len(rows),
@ -3232,11 +3240,14 @@ def payroll_dashboard(request):
'order': sort_order,
'group_by': group_by,
},
# Flat list of type labels for the Adjustments tab filter dropdown.
# Stored under a separate key so we don't clobber the existing
# 'adjustment_types' context var (which is TYPE_CHOICES tuples
# used by the Add/Edit adjustment modals).
'adj_type_choices': list(ADDITIVE_TYPES) + list(DEDUCTIVE_TYPES),
# (db_value, display_label) pairs for the Type filter popover on the
# Adjustments tab. Uses TYPE_CHOICES directly so the checkbox labels
# show the short display labels (Loan / Advance / Advance Repaid)
# while checkbox values stay on the DB value (which the view filters
# by). Stored under a separate key so we don't clobber the existing
# 'adjustment_types' context var (also TYPE_CHOICES tuples, used by
# the Add/Edit adjustment modals).
'adj_type_choices': PayrollAdjustment.TYPE_CHOICES,
# PERF: reuse `all_workers`/`all_teams` (already cached above for
# the Add-Adjustment modal) — same row-set, same ordering, so no
# need to re-query the database for the filter popovers.