feat(permissions): A1 — зависимости между правами (requires) + план переработки
registry: поле requires (questions.delete→manage, templates.public→manage, courses.interactive→manage, simulations.quiz→access), проброшено в byRole. auth.requirePermission: вынесен isEnabled(); право = own AND все requires (дочернее не работает без родителя). /me и /users/🆔 effective с учётом requires + requires в ответе. UI permissions.js: каскад — дочернее с невыполненной зависимостью неактивно (тумблер заблокирован + «Требует: …»). Тест зависимости. План: plans/permissions-rework/PLAN.md. Backend 216 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,20 +21,30 @@
|
||||
['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; });
|
||||
container.innerHTML = defs.map(def => {
|
||||
const enabled = permissions[role]?.[def.key] ?? def.default;
|
||||
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
|
||||
? `<span class="perm-modified-dot" title="Отличается от значения по умолчанию"></span>`
|
||||
: '';
|
||||
const reqNote = reqs.length
|
||||
? `<div class="perm-desc" style="margin-top:3px;color:${blocked ? 'var(--danger,#dc2626)' : 'var(--muted)'}">${blocked ? 'Требует: ' + unmet.map(r => esc(labelOf[r] || r)).join(', ') : 'Зависит от: ' + reqs.map(r => esc(labelOf[r] || r)).join(', ')}</div>`
|
||||
: '';
|
||||
return `
|
||||
<div class="perm-card${enabled ? ' enabled' : ''}" id="perm-card-${role}-${def.key.replace('.','_')}">
|
||||
<div class="perm-card${effective ? ' enabled' : ''}" id="perm-card-${role}-${def.key.replace('.','_')}" style="${blocked ? 'opacity:.65' : ''}">
|
||||
<div class="perm-info">
|
||||
<div class="perm-label">${esc(def.label)}${modDot}</div>
|
||||
<div class="perm-desc">${esc(def.desc)}</div>
|
||||
${reqNote}
|
||||
</div>
|
||||
<label class="perm-toggle" title="${enabled ? 'Выключить' : 'Включить'}">
|
||||
<input type="checkbox" ${enabled ? 'checked' : ''}
|
||||
<label class="perm-toggle" title="${blocked ? 'Сначала включите зависимость' : (enabled ? 'Выключить' : 'Включить')}">
|
||||
<input type="checkbox" ${enabled ? 'checked' : ''} ${blocked ? 'disabled' : ''}
|
||||
onchange="togglePermission('${esc(role)}','${esc(def.key)}',this.checked,this)">
|
||||
<span class="perm-track"></span>
|
||||
<span class="perm-thumb"></span>
|
||||
|
||||
Reference in New Issue
Block a user