feat(perm-ui): P0 usability improvements (search, default-dot, confirm-critical, wording)

- registry.js: добавлен флаг requireConfirmOff для 7 критичных прав (questions.manage, classes.manage, library.upload, courses.manage, sessions.reset, theory.access, simulations.access); byRole() теперь возвращает это поле
- admin.html: subtitle в модале прав — «учителя» → «пользователя»; tooltip на кнопке «Сбросить всё по умолчанию»; поле поиска над сеткой прав; CSS .perm-modified-dot (amber, 8px)
- admin.js: badge «Инд.» → «Индивидуально» (font-size 11px); renderPermissions() рисует .perm-modified-dot когда значение отличается от registry default; togglePermission() показывает LS.confirm перед выключением критичных прав; window.filterPermissions() скрывает карточки и role-блоки по поисковому запросу

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-05-17 14:43:49 +03:00
parent 19c16bdfe8
commit 7eea33a135
3 changed files with 57 additions and 5 deletions
+8 -1
View File
@@ -31,6 +31,7 @@ const PERMISSIONS = {
role: 'teacher', roles: ['teacher'], default: 0,
label: 'Управление вопросами',
desc: 'Создавать, редактировать и копировать вопросы в банке',
requireConfirmOff: true,
},
'questions.delete': {
role: 'teacher', roles: ['teacher'], default: 0,
@@ -46,6 +47,7 @@ const PERMISSIONS = {
role: 'teacher', roles: ['teacher'], default: 1,
label: 'Сброс попыток',
desc: 'Сбрасывать прохождение теста ученика в своём классе',
requireConfirmOff: true,
},
'results.export': {
role: 'teacher', roles: ['teacher'], default: 1,
@@ -56,11 +58,13 @@ const PERMISSIONS = {
role: 'teacher', roles: ['teacher'], default: 1,
label: 'Управление классами',
desc: 'Создавать, редактировать и удалять свои классы',
requireConfirmOff: true,
},
'library.upload': {
role: 'teacher', roles: ['teacher'], default: 1,
label: 'Загрузка файлов',
desc: 'Загружать файлы в библиотеку',
requireConfirmOff: true,
},
'library.folders': {
role: 'teacher', roles: ['teacher'], default: 1,
@@ -91,6 +95,7 @@ const PERMISSIONS = {
role: 'teacher', roles: ['teacher'], default: 1,
label: 'Управление курсами',
desc: 'Создавать и редактировать теоретические курсы и уроки',
requireConfirmOff: true,
},
'courses.interactive': {
role: 'teacher', roles: ['teacher'], default: 1,
@@ -138,11 +143,13 @@ const PERMISSIONS = {
role: 'student', roles: ['student', 'free_student'], default: 1,
label: 'Доступ к теории',
desc: 'Просматривать теоретические курсы и уроки',
requireConfirmOff: true,
},
'simulations.access': {
role: 'student', roles: ['student', 'free_student'], default: 1,
label: 'Доступ к симуляциям',
desc: 'Открывать лабораторию с физическими, химическими и биологическими симуляциями',
requireConfirmOff: true,
},
'simulations.quiz': {
role: 'student', roles: ['student', 'free_student'], default: 1,
@@ -171,7 +178,7 @@ function listKeys() {
function byRole(role) {
return Object.entries(PERMISSIONS)
.filter(([, v]) => v.role === role)
.map(([key, v]) => ({ key, role: v.role, default: v.default, label: v.label, desc: v.desc }));
.map(([key, v]) => ({ key, role: v.role, default: v.default, label: v.label, desc: v.desc, requireConfirmOff: !!v.requireConfirmOff }));
}
/**