Tables: initial ФИО order, click-to-sort columns, substring search

- identity group detail (and thus every student list) is ordered by full name;
  defense rows on the group page sorted by name + lab number
- tablekit.js: click a header to sort (numeric-aware, ru locale), second click
  flips direction (▲/▼ indicator); search input with data-target filters rows
  by substring live
- tables wired: group matrix (with data-sort on variant cells), defense table
  (data-sort on status/date), students table, lab assignment lists per group,
  groups list and labs list; name/number columns pre-marked ascending
- non-sortable columns marked data-nosort (checkbox/actions)
This commit is contained in:
2026-09-15 22:38:42 +03:00
parent cdf4fb0ee0
commit a4f2c7db90
9 changed files with 128 additions and 32 deletions

View File

@@ -22,9 +22,14 @@
<input type="hidden" name="_csrf" th:value="${csrfToken}">
</form>
</div>
<div class="card card-flush mt-8">
<table>
<thead><tr><th>Название</th><th>Студентов</th><th>Выгрузка</th></tr></thead>
<div class="flex flex-wrap items-center justify-between gap-2 mb-2 mt-8">
<h2 class="section-title m-0">Список групп</h2>
<input class="input input-sm table-search" data-target="groups-table"
placeholder="Поиск по названию…" aria-label="Поиск по группам">
</div>
<div class="card card-flush">
<table id="groups-table" class="tablekit">
<thead><tr><th class="th-sortable is-asc" title="Название — по возрастанию">Название</th><th>Студентов</th><th data-nosort>Выгрузка</th></tr></thead>
<tbody>
<tr th:each="group : ${groups}">
<td><a th:href="@{/admin/groups/{id}(id=${group.id})}" th:text="${group.name}">—</a></td>