Enhance worker list display with site, grade, and FTE information; add non-working days summary rendering
This commit is contained in:
@@ -4,9 +4,23 @@
|
||||
<ul>
|
||||
{% for w in rota.workers.all %}
|
||||
<li>
|
||||
<a href="{% url 'rota:worker_detail' w.id %}">{{ w.name }}</a>
|
||||
<button class="button is-small is-light ml-2" hx-get="{% url 'rota:worker_edit' rota.id w.id %}" hx-target="#modal" hx-swap="innerHTML">Edit</button>
|
||||
<button class="button is-small is-danger ml-2" hx-get="{% url 'rota:worker_delete' rota.id w.id %}" hx-target="#modal" hx-swap="innerHTML">Delete</button>
|
||||
<div style="display:flex; align-items:center; justify-content:space-between; gap:0.75rem;">
|
||||
<div style="display:flex; align-items:center; gap:0.5rem;">
|
||||
<a href="{% url 'rota:worker_detail' w.id %}">{{ w.name }}</a>
|
||||
<small style="color:#666">— {{ w.site }}{% if w.grade %} · grade {{ w.grade }}{% endif %} · FTE {{ w.fte }}</small>
|
||||
{# show non-working days stored in options.nwds if present; render JSON safely and let JS format it #}
|
||||
{% if w.options.nwds %}
|
||||
<span id="nwds-summary-{{ w.id }}" class="nwds-summary" data-nwds-id="nwds-data-{{ w.id }}" style="margin-left:0.5rem;color:#666"></span>
|
||||
{% with script_id='nwds-data-'|add:w.id %}
|
||||
{{ w.options.nwds|default:"[]"|json_script:script_id }}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div style="flex:0 0 auto;">
|
||||
<button class="button is-small is-light ml-2" hx-get="{% url 'rota:worker_edit' rota.id w.id %}" hx-target="#modal" hx-swap="innerHTML">Edit</button>
|
||||
<button class="button is-small is-danger ml-2" hx-get="{% url 'rota:worker_delete' rota.id w.id %}" hx-target="#modal" hx-swap="innerHTML">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{% empty %}
|
||||
<li>No workers assigned</li>
|
||||
@@ -14,3 +28,69 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Render NWDS summaries: find script tags with id starting 'nwds-data-' and populate the
|
||||
// corresponding summary span. Clicking a day label toggles display of date details.
|
||||
(function(){
|
||||
const DAYS = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'];
|
||||
function dayLabelFromItem(item){
|
||||
if(item === null || item === undefined) return '(any)';
|
||||
if(typeof item === 'number') return DAYS[item] || String(item);
|
||||
if(typeof item === 'string'){
|
||||
const n = parseInt(item,10);
|
||||
if(!Number.isNaN(n)) return DAYS[n] || item;
|
||||
// normalise to first 3 letters
|
||||
return item.trim().slice(0,3);
|
||||
}
|
||||
if(typeof item === 'object'){
|
||||
if(item.day !== undefined){
|
||||
if(typeof item.day === 'number') return DAYS[item.day] || String(item.day);
|
||||
return String(item.day).slice(0,3);
|
||||
}
|
||||
}
|
||||
return String(item);
|
||||
}
|
||||
|
||||
document.querySelectorAll('.nwds-summary').forEach(function(target){
|
||||
try{
|
||||
let arr = [];
|
||||
const dataAttr = target.getAttribute('data-nwds');
|
||||
if(dataAttr){
|
||||
try{ arr = JSON.parse(dataAttr); }catch(e){ arr = []; }
|
||||
} else {
|
||||
const scriptId = target.getAttribute('data-nwds-id');
|
||||
if(scriptId){
|
||||
let script = document.getElementById(scriptId);
|
||||
// Some template/tooling may emit the JSON <script> without an id (observed in output).
|
||||
// Fallback: look for the next sibling <script type="application/json"> after the span.
|
||||
if(!script){
|
||||
let sib = target.nextElementSibling;
|
||||
while(sib){
|
||||
if(sib.tagName === 'SCRIPT' && (sib.type === 'application/json' || sib.getAttribute('type') === 'application/json')){ script = sib; break; }
|
||||
sib = sib.nextElementSibling;
|
||||
}
|
||||
}
|
||||
if(script){
|
||||
try{ arr = JSON.parse(script.textContent || script.innerText || '[]'); }catch(e){ arr = []; }
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!Array.isArray(arr) || arr.length===0){ target.textContent = ''; return; }
|
||||
arr.forEach(function(item, idx){
|
||||
const a = document.createElement('a');
|
||||
a.href = '#'; a.className = 'nwds-day'; a.style.marginLeft = (idx? '0.4rem':'0'); a.style.color = '#666'; a.textContent = dayLabelFromItem(item);
|
||||
const details = document.createElement('span'); details.className='nwds-dates'; details.style.display='none'; details.style.marginLeft='0.25rem'; details.style.color='#444';
|
||||
if(item && typeof item === 'object'){
|
||||
const sd = item.start_date || item.from || '';
|
||||
const ed = item.end_date || item.to || '';
|
||||
if(sd || ed){ details.textContent = (sd||'') + (sd && ed ? ' → ' : '') + (ed||''); }
|
||||
}
|
||||
a.addEventListener('click', function(ev){ ev.preventDefault(); if(details.textContent){ details.style.display = details.style.display === 'none' ? 'inline' : 'none'; } });
|
||||
target.appendChild(a);
|
||||
target.appendChild(details);
|
||||
});
|
||||
}catch(e){ console.error('nwds render failed', e); }
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user