ux(labels): extend display labels to AJAX-sourced modal renders
Closes the Task 3 design-goal gap: two user-facing modals (work-log payroll preview in base.html, split-payslip preview in payroll_dashboard.html) render adjustment types via JS reading AJAX JSON. After Task 3's TYPE_CHOICES rename they were still showing the old long labels because the backend endpoints (work_log_payroll_ajax, preview_payslip) only emitted adj.type (DB value), not the display label. Added a 'type_label' field to the JSON payloads alongside the existing 'type' field. JS at both render sites now reads `adj.type_label || adj.type` — with the fallback so any stale client-side JSON degrades gracefully to the DB value rather than rendering blank. Path A still holds: adj.type in JSON stays the DB value for any identifier purposes; the new type_label is additive. Tests: 69/69. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c1d9014fe1
commit
1cf13048c2
@ -549,7 +549,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
var adjBody = document.createElement('tbody');
|
||||
data.adjustments.forEach(function(adj) {
|
||||
var tr = document.createElement('tr');
|
||||
tr.appendChild(el('td', null, adj.type));
|
||||
// Prefer the short display label from the server; fall back to the
|
||||
// raw DB value if a stale JSON response doesn't include type_label
|
||||
// (graceful degradation — never render a blank cell).
|
||||
tr.appendChild(el('td', null, adj.type_label || adj.type));
|
||||
var wTd = document.createElement('td');
|
||||
wTd.appendChild(link('/workers/' + adj.worker_id + '/', adj.worker_name));
|
||||
tr.appendChild(wTd);
|
||||
|
||||
@ -2395,7 +2395,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
labelWrap.className = 'd-flex justify-content-between flex-grow-1';
|
||||
|
||||
var label = document.createElement('span');
|
||||
label.textContent = adj.type + (adj.project ? ' (' + adj.project + ')' : '');
|
||||
// Prefer the short display label ('Loan' / 'Advance' / 'Advance Repaid')
|
||||
// from the server; fall back to the raw DB value if a stale JSON
|
||||
// response doesn't include type_label (graceful degradation).
|
||||
label.textContent = (adj.type_label || adj.type) + (adj.project ? ' (' + adj.project + ')' : '');
|
||||
if (adj.description) {
|
||||
var descSmall = document.createElement('small');
|
||||
descSmall.className = 'text-muted ms-1';
|
||||
|
||||
@ -1020,8 +1020,11 @@ def work_log_payroll_ajax(request, log_id):
|
||||
} for row in ctx['worker_rows']]
|
||||
|
||||
# Adjustments linked directly to this work_log (Overtime, etc.).
|
||||
# We emit BOTH 'type' (raw DB value — stable identifier for any JS logic)
|
||||
# AND 'type_label' (short display label from get_type_display()) — visible UI.
|
||||
adjustments = [{
|
||||
'type': adj.type,
|
||||
'type_label': adj.get_type_display(),
|
||||
'amount': float(adj.amount),
|
||||
'worker_id': adj.worker.id,
|
||||
'worker_name': adj.worker.name,
|
||||
@ -4236,7 +4239,11 @@ def preview_payslip(request, worker_id):
|
||||
adj_total += float(adj.amount) if adj.type in ADDITIVE_TYPES else -float(adj.amount)
|
||||
adjustments_list.append({
|
||||
'id': adj.id,
|
||||
# 'type' keeps the raw DB value so any JS that uses it as an
|
||||
# identifier keeps working; 'type_label' is the short display
|
||||
# label ('Loan' / 'Advance' / 'Advance Repaid' etc.) for visible UI.
|
||||
'type': adj.type,
|
||||
'type_label': adj.get_type_display(),
|
||||
'amount': float(adj.amount),
|
||||
'sign': sign,
|
||||
'description': adj.description,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user