feat(admin): sortable columns for active users table
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions

All 6 columns clickable: # and numeric columns default desc,
name defaults asc, last login sorts by date value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-03-18 08:58:02 +01:00
parent 96232200f9
commit 17d640a375

View File

@ -355,26 +355,26 @@
<h2>Najbardziej aktywni uzytkownicy</h2>
{% if active_users %}
<div class="table-scroll">
<table class="data-table">
<table class="data-table" id="active-users-table">
<thead>
<tr>
<th>#</th>
<th>Uzytkownik</th>
<th>Sesje</th>
<th>Laczny czas (min)</th>
<th>Odslony</th>
<th>Ostatnie logowanie</th>
<th class="sortable" data-col="0" data-type="number">#</th>
<th class="sortable" data-col="1" data-type="string">ytkownik</th>
<th class="sortable sort-desc" data-col="2" data-type="number">Sesje</th>
<th class="sortable" data-col="3" data-type="number">Łączny czas (min)</th>
<th class="sortable" data-col="4" data-type="number">Odsłony</th>
<th class="sortable" data-col="5" data-type="date">Ostatnie logowanie</th>
</tr>
</thead>
<tbody>
{% for u in active_users %}
<tr>
<td>{{ loop.index }}</td>
<td class="num">{{ loop.index }}</td>
<td>{{ u.name }}</td>
<td class="num">{{ u.session_count }}</td>
<td class="num">{{ u.total_time_min }}</td>
<td class="num">{{ u.total_pages }}</td>
<td>{{ u.last_login.strftime('%d.%m.%Y %H:%M') if u.last_login else '-' }}</td>
<td data-sort-value="{{ u.last_login.strftime('%Y%m%d%H%M') if u.last_login else '0' }}">{{ u.last_login.strftime('%d.%m.%Y %H:%M') if u.last_login else '-' }}</td>
</tr>
{% endfor %}
</tbody>
@ -510,4 +510,42 @@
});
});
})();
/* --- Active users table: sorting --- */
(function() {
var table = document.getElementById('active-users-table');
if (!table) return;
var tbody = table.querySelector('tbody');
var rows = Array.from(tbody.querySelectorAll('tr'));
table.querySelectorAll('th.sortable').forEach(function(th) {
th.addEventListener('click', function() {
var col = parseInt(th.dataset.col);
var type = th.dataset.type;
var isDesc = th.classList.contains('sort-desc');
var dir = isDesc ? 1 : -1;
table.querySelectorAll('th.sortable').forEach(function(h) {
h.classList.remove('sort-asc', 'sort-desc');
});
th.classList.add(isDesc ? 'sort-asc' : 'sort-desc');
rows.sort(function(a, b) {
var aCell = a.cells[col], bCell = b.cells[col];
if (type === 'date') {
var av = aCell.dataset.sortValue || '0';
var bv = bCell.dataset.sortValue || '0';
return av < bv ? dir : av > bv ? -dir : 0;
} else if (type === 'number') {
return (parseFloat(aCell.textContent) - parseFloat(bCell.textContent)) * dir;
} else {
var av = aCell.textContent.trim().toLowerCase();
var bv = bCell.textContent.trim().toLowerCase();
return av < bv ? dir : av > bv ? -dir : 0;
}
});
rows.forEach(function(r) { tbody.appendChild(r); });
});
});
})();
{% endblock %}