UX enhancements on data views
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import { apiGet, apiPost, apiDelete } from '../api.js';
|
||||
import { getRole, getUser, showToast } from '../app.js';
|
||||
import { isDevTestUsername, testDataRowClassForUser } from '../test-data.js';
|
||||
|
||||
// Roles an admin can create; supervisors can only create coaches
|
||||
const CREATEABLE_ROLES = {
|
||||
@ -10,6 +11,8 @@ const CREATEABLE_ROLES = {
|
||||
let usersList = [];
|
||||
let supervisorsList = [];
|
||||
let callerRole = '';
|
||||
let filterSearch = '';
|
||||
let filterTestData = '';
|
||||
|
||||
export async function usersPage() {
|
||||
callerRole = getRole();
|
||||
@ -86,8 +89,19 @@ function renderUsers() {
|
||||
{ label: 'Coaches', key: 'coach' },
|
||||
];
|
||||
|
||||
container.innerHTML = groups.map(group => {
|
||||
const users = byRole[group.key] || [];
|
||||
container.innerHTML = `
|
||||
<div class="card" style="margin-bottom:16px">
|
||||
<div class="filter-bar">
|
||||
<input type="search" id="userListSearch" class="filter-search" placeholder="Search username…" value="${esc(filterSearch)}">
|
||||
<select id="userTestFilter">
|
||||
<option value="">All users</option>
|
||||
<option value="test" ${filterTestData === 'test' ? 'selected' : ''}>Test data only (dev_*)</option>
|
||||
<option value="hide-test" ${filterTestData === 'hide-test' ? 'selected' : ''}>Hide test data</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
` + groups.map(group => {
|
||||
const users = filterUsers(byRole[group.key] || []);
|
||||
if (!users.length) return '';
|
||||
return `
|
||||
<div class="card" style="margin-bottom:16px">
|
||||
@ -111,11 +125,34 @@ function renderUsers() {
|
||||
</div>`;
|
||||
}).join('');
|
||||
|
||||
document.getElementById('userListSearch')?.addEventListener('input', (e) => {
|
||||
filterSearch = e.target.value.trim();
|
||||
renderUsers();
|
||||
});
|
||||
document.getElementById('userTestFilter')?.addEventListener('change', (e) => {
|
||||
filterTestData = e.target.value;
|
||||
renderUsers();
|
||||
});
|
||||
|
||||
container.querySelectorAll('.delete-user-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => deleteUser(btn.dataset.id, btn.dataset.name));
|
||||
});
|
||||
}
|
||||
|
||||
function filterUsers(users) {
|
||||
let list = users;
|
||||
if (filterSearch) {
|
||||
const q = filterSearch.toLowerCase();
|
||||
list = list.filter(u => (u.username || '').toLowerCase().includes(q));
|
||||
}
|
||||
if (filterTestData === 'test') {
|
||||
list = list.filter(u => isDevTestUsername(u.username));
|
||||
} else if (filterTestData === 'hide-test') {
|
||||
list = list.filter(u => !isDevTestUsername(u.username));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
function userRowHTML(u, myUsername) {
|
||||
const isSelf = u.username === myUsername;
|
||||
const detail = u.role === 'coach'
|
||||
@ -134,7 +171,7 @@ function userRowHTML(u, myUsername) {
|
||||
);
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<tr class="${testDataRowClassForUser(u.username).trim()}">
|
||||
<td>
|
||||
<strong>${esc(u.username)}</strong>
|
||||
${isSelf ? '<span class="badge badge-you">You</span>' : ''}
|
||||
|
||||
Reference in New Issue
Block a user