ux(admin): sticky table headers + collapsible nav + унификация лейблов
3 победы из аудита админ-панели за один заход:
1) STICKY TABLE HEADERS
admin.html:142 — добавлен position:sticky; top:0; z-index:5; на <th>
Заголовки колонок теперь остаются видны при scroll длинных таблиц
(Users, Sessions, Shop, Gam — 100+ строк). Background фон поменян
на opaque #E5EAF7 чтобы строки скроллились чисто за header'ом.
Стоимость: 1 CSS-правило. Эффект: пользователи не теряют контекст
столбцов при просмотре длинного списка.
2) COLLAPSIBLE NAV GROUPS
admin.html:875+ — 4 группы (Аналитика, Контент, Пользователи,
Система) вместо плоского списка 21 кнопки с просто визуальными
сепараторами. Каждая группа сворачивается кликом по заголовку.
Состояние per-группа в localStorage (ls_adm_g_<slug>).
Группа «Система» (только админ) теперь объединяет shop, gam, sims,
games, audit, errors, health — раньше они шли вперемешку с
teacher-видимыми табами (sublog, topics, broadcast). Переместил
sublog/broadcast в группу «Пользователи», topics в «Контент» —
логичнее по смыслу.
Паттерн один-в-один как у sidebar.js (где мы это сделали ранее).
3) УНИФИКАЦИЯ ЛЕЙБЛОВ
Правило: «+ Добавить» для атомов (вопрос, тема, опция, товар),
«+ Создать» для составных объектов (тест, задание, курс).
Изменения:
- admin.html:1431 — «Создать» → «Добавить» (форма темы — атом)
- admin.html:1195 — «Новый товар» → «Добавить товар»
- admin.js:415 — q-modal title «Новый вопрос» → «Добавить вопрос»
- admin.js:2239 — shop-form-title «Новый товар» → «Добавить товар»
Теперь кнопка в toolbar и заголовок модалки/формы согласованы.
Остались крупные пункты из аудита (на отдельный заход):
- Q-modal wizard (split на 2 шага) — 🔴 высокий приоритет
- Pagination в больших таблицах — 🟡
- Standardized error/loading states — 🔵
This commit is contained in:
@@ -12,9 +12,24 @@
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.style.display = '';
|
||||
});
|
||||
document.getElementById('admin-nav-system-sep').style.display = '';
|
||||
document.getElementById('admin-nav-system-label').style.display = '';
|
||||
const sysGroup = document.getElementById('admin-nav-system-group');
|
||||
if (sysGroup) sysGroup.style.display = '';
|
||||
}
|
||||
|
||||
/* Collapsible nav groups — state persisted in localStorage */
|
||||
window.toggleAdminGroup = function (slug) {
|
||||
const g = document.querySelector(`.admin-nav-group[data-ng="${slug}"]`);
|
||||
if (!g) return;
|
||||
const collapsed = g.classList.toggle('collapsed');
|
||||
try { localStorage.setItem('ls_adm_g_' + slug, collapsed ? '1' : '0'); } catch {}
|
||||
};
|
||||
// Restore collapsed state on page load
|
||||
document.querySelectorAll('.admin-nav-group').forEach(g => {
|
||||
const slug = g.dataset.ng;
|
||||
try {
|
||||
if (localStorage.getItem('ls_adm_g_' + slug) === '1') g.classList.add('collapsed');
|
||||
} catch {}
|
||||
});
|
||||
LS.showBoardIfAllowed();
|
||||
LS.hideDisabledFeatures?.();
|
||||
LS.notif?.init();
|
||||
@@ -412,7 +427,7 @@
|
||||
/* ─── Modal ─── */
|
||||
function openQModal(q = null) {
|
||||
editingQId = q ? q.id : null;
|
||||
document.getElementById('q-modal-title').textContent = q ? `Редактировать вопрос #${q.id}` : 'Новый вопрос';
|
||||
document.getElementById('q-modal-title').textContent = q ? `Редактировать вопрос #${q.id}` : 'Добавить вопрос';
|
||||
const textEl = document.getElementById('qf-text');
|
||||
textEl.value = q?.text || '';
|
||||
updateCharCounter(textEl, 'qf-text-cnt', 500);
|
||||
@@ -2236,7 +2251,7 @@
|
||||
|
||||
function shopAdminCreateItem() {
|
||||
_shopEditId = null;
|
||||
document.getElementById('shop-form-title').textContent = 'Новый товар';
|
||||
document.getElementById('shop-form-title').textContent = 'Добавить товар';
|
||||
document.getElementById('shop-f-name').value = '';
|
||||
document.getElementById('shop-f-type').value = 'frame';
|
||||
document.getElementById('shop-f-price').value = '100';
|
||||
|
||||
Reference in New Issue
Block a user