UX enhancements on data views

This commit is contained in:
2026-05-26 17:07:18 +02:00
parent 9d783b60a9
commit ea3a423186
8 changed files with 558 additions and 43 deletions

View File

@ -1,5 +1,6 @@
import { apiGet, apiPost } from '../api.js';
import { showToast } from '../app.js';
import { isDevTestClientCode, isDevTestUsername, testDataRowClassForClient } from '../test-data.js';
let coaches = [];
let clients = [];
@ -61,8 +62,9 @@ function renderAssignments() {
<ul class="coach-list" id="coachList">
${coaches.map(c => {
const count = (clientsByCoach[c.coachID] || []).length;
const coachTest = isDevTestUsername(c.username) ? ' row-test-data' : '';
return `
<li class="coach-list-item" data-id="${c.coachID}">
<li class="coach-list-item${coachTest}" data-id="${c.coachID}">
<div class="coach-name">${esc(c.username)}</div>
${c.supervisorUsername
? `<div class="coach-supervisor">${esc(c.supervisorUsername)}</div>`
@ -88,6 +90,11 @@ function renderAssignments() {
).join('')}
</select>
<input type="text" id="clientSearch" placeholder="Search client code..." style="width:160px">
<select id="clientTestFilter">
<option value="">All clients</option>
<option value="test">Test only</option>
<option value="hide-test">Hide test</option>
</select>
</div>
</div>
<div style="display:flex;gap:6px">
@ -95,7 +102,7 @@ function renderAssignments() {
<button class="btn btn-sm" id="clearSelBtn">Clear</button>
</div>
</div>
<div class="table-wrapper" style="max-height:420px;overflow-y:auto">
<div class="table-wrapper" style="max-height:420px">
<table class="data-table">
<thead>
<tr>
@ -141,6 +148,7 @@ function renderAssignments() {
// Wire filters
document.getElementById('filterByCoach').addEventListener('change', renderClientRows);
document.getElementById('clientSearch').addEventListener('input', renderClientRows);
document.getElementById('clientTestFilter').addEventListener('change', renderClientRows);
// Wire select all / clear
document.getElementById('selectAllBtn').addEventListener('click', () => {
@ -166,6 +174,7 @@ function renderClientRows() {
const body = document.getElementById('clientTableBody');
const coachFilter = document.getElementById('filterByCoach').value;
const search = document.getElementById('clientSearch').value.trim().toLowerCase();
const testMode = document.getElementById('clientTestFilter')?.value || '';
let visible = clients;
if (coachFilter === '__unassigned__') {
@ -176,6 +185,11 @@ function renderClientRows() {
if (search) {
visible = visible.filter(c => c.clientCode.toLowerCase().includes(search));
}
if (testMode === 'test') {
visible = visible.filter(c => isDevTestClientCode(c.clientCode));
} else if (testMode === 'hide-test') {
visible = visible.filter(c => !isDevTestClientCode(c.clientCode));
}
if (!visible.length) {
body.innerHTML = `<tr><td colspan="3" style="text-align:center;color:var(--text-secondary);padding:24px">No clients match the current filter</td></tr>`;
@ -184,7 +198,7 @@ function renderClientRows() {
}
body.innerHTML = visible.map(c => `
<tr>
<tr class="${testDataRowClassForClient(c.clientCode).trim()}">
<td><input type="checkbox" class="client-cb" data-code="${esc(c.clientCode)}" value="${esc(c.clientCode)}"></td>
<td><strong>${esc(c.clientCode)}</strong></td>
<td>${c.coachUsername ? esc(c.coachUsername) : '<span style="color:var(--text-secondary);font-style:italic">Unassigned</span>'}</td>