'use strict';
/* admin → permissions section (role-based teacher/student permissions) */
(function () {
'use strict';
let inited = false;
let _permData = null;
async function load() {
try {
_permData = await LS.getPermissions();
renderPermissions();
} catch(e) {
document.getElementById('perm-teacher').innerHTML =
`
Ошибка загрузки: ${esc(e.message)}
`;
}
}
function permCard(role, def, en, labelOf) {
const enabled = en[def.key];
const reqs = def.requires || [];
const unmet = reqs.filter(r => !en[r]);
const blocked = unmet.length > 0; // зависимость не выполнена → право неактивно
const effective = enabled && !blocked;
const isModified = (enabled ? 1 : 0) !== def.default;
const modDot = isModified
? ``
: '';
const reqNote = reqs.length
? `${blocked ? 'Требует: ' + unmet.map(r => esc(labelOf[r] || r)).join(', ') : 'Зависит от: ' + reqs.map(r => esc(labelOf[r] || r)).join(', ')}
`
: '';
return `
${esc(def.label)}${modDot}
${esc(def.desc)}
${reqNote}
`;
}
function renderPermissions() {
if (!_permData) return;
const { permissions, definitions } = _permData;
['teacher', 'student'].forEach(role => {
const container = document.getElementById('perm-' + role);
const defs = definitions.filter(d => d.role === role);
const en = {}, labelOf = {};
defs.forEach(d => { en[d.key] = permissions[role]?.[d.key] ?? d.default; labelOf[d.key] = d.label; });
// группировка по def.group (порядок групп — по первому появлению)
const order = [], byGroup = {};
defs.forEach(d => { const g = d.group || 'Прочее'; if (!byGroup[g]) { byGroup[g] = []; order.push(g); } byGroup[g].push(d); });
const grpBtn = (g, on) => ``;
container.style.display = 'block'; // секции групп блоками (контейнер сам — .perm-grid)
container.innerHTML = order.map(g => `
${esc(g)}
${grpBtn(g, true)}${grpBtn(g, false)}
${byGroup[g].map(def => permCard(role, def, en, labelOf)).join('')}
`).join('');
});
}
async function togglePermGroup(role, group, enable) {
const defs = (_permData.definitions || []).filter(d => d.role === role && (d.group || 'Прочее') === group);
if (!defs.length) return;
if (!enable && defs.some(d => d.requireConfirmOff)) {
const roleLabel = role === 'teacher' ? 'Учитель' : 'Ученик';
const ok = await LS.confirm(
`Выключить все права группы «${group}» для роли «${roleLabel}»? Затронет всех пользователей роли.`,
{ title: 'Подтвердите выключение группы', confirmText: 'Выключить все' }
);
if (!ok) return;
}
try {
await Promise.all(defs.map(d => LS.setPermission(role, d.key, enable)));
if (!_permData.permissions[role]) _permData.permissions[role] = {};
defs.forEach(d => { _permData.permissions[role][d.key] = enable; });
renderPermissions();
LS.toast(enable ? `Группа «${group}» включена` : `Группа «${group}» выключена`, 'success');
} catch (e) { LS.toast('Ошибка: ' + e.message, 'error'); load(); }
}
async function togglePermission(role, key, enabled, checkbox) {
if (!enabled) {
const def = (_permData.definitions || []).find(d => d.role === role && d.key === key);
if (def && def.requireConfirmOff) {
const roleLabel = role === 'teacher' ? 'Учитель' : 'Ученик';
const ok = await LS.confirm(
`Выключение «${def.label}» затронет всех пользователей роли «${roleLabel}». Они потеряют доступ. Продолжить?`,
{ title: 'Подтвердите выключение права', confirmText: 'Выключить' }
);
if (!ok) { checkbox.checked = true; return; }
}
}
checkbox.disabled = true;
try {
await LS.setPermission(role, key, enabled);
if (!_permData.permissions[role]) _permData.permissions[role] = {};
_permData.permissions[role][key] = enabled;
const safeKey = key.replace('.', '_');
const card = document.getElementById(`perm-card-${role}-${safeKey}`);
if (card) card.classList.toggle('enabled', enabled);
// Re-render to refresh the modified-dot indicator across all cards.
renderPermissions();
LS.toast(enabled ? 'Право включено' : 'Право отключено', 'success');
} catch(e) {
checkbox.checked = !enabled;
LS.toast('Ошибка: ' + e.message, 'error');
} finally {
checkbox.disabled = false;
}
}
function filterPermissions(query) {
const q = (query || '').trim().toLowerCase();
['teacher', 'student'].forEach(role => {
const block = document.querySelector(`#perm-${role}`)?.closest('.perm-role-block');
const cards = document.querySelectorAll(`#perm-${role} .perm-card`);
let visibleCount = 0;
cards.forEach(card => {
const label = (card.querySelector('.perm-label')?.textContent || '').toLowerCase();
const desc = (card.querySelector('.perm-desc')?.textContent || '').toLowerCase();
const show = !q || label.includes(q) || desc.includes(q);
card.style.display = show ? '' : 'none';
if (show) visibleCount++;
});
if (block) block.style.display = visibleCount === 0 ? 'none' : '';
});
}
async function loadPermLog() {
const box = document.getElementById('perm-log');
if (!box) return;
box.innerHTML = 'Загрузка…
';
try {
const log = await LS.permissionsLog();
box.innerHTML = log.length
? log.map(e => `${esc(e.actor)} ${esc(e.text)} · ${esc((e.at || '').replace('T', ' ').slice(0, 16))}
`).join('')
: 'Изменений пока нет.
';
} catch (e) {
box.innerHTML = `Ошибка: ${esc(e.message)}
`;
}
}
window.togglePermission = togglePermission;
window.togglePermGroup = togglePermGroup;
window.filterPermissions = filterPermissions;
window.loadPermLog = loadPermLog;
window.AdminSections = window.AdminSections || {};
window.AdminSections.permissions = {
init: async () => { if (inited) return; inited = true; await load(); },
reload: load,
};
})();