diff --git a/frontend/js/admin/sections/access.js b/frontend/js/admin/sections/access.js index 2e1c955..98d65ce 100644 --- a/frontend/js/admin/sections/access.js +++ b/frontend/js/admin/sections/access.js @@ -42,6 +42,8 @@ const bucket = (type) => BUCKET[type] || (type + 's'); const keyName = (type) => KEYNAME[type] || 'id'; const itemsOf = (type) => (_catalog && _catalog[bucket(type)]) || []; + const subjOf = (it) => it.subject || it.subject_slug || ''; // нормализация поля предмета + const subjLabel = (s) => SUBJ_LABEL[s] || s || 'Прочее'; function contentTitle(type, ref) { const it = itemsOf(type).find(x => x[keyName(type)] === ref); return it ? it.title : ref; @@ -346,10 +348,17 @@ function renderClassDetail(right) { let html = `
Класс «${esc(_selClass.name)}»
-
+
`; + const subjects = [...new Set(CONTENT_TYPES.flatMap(t => itemsOf(t).map(subjOf)).filter(Boolean))].sort(); + if (subjects.length) { + html += `
+ Открыть по предмету: + ${subjects.map(s => ``).join('')} +
`; + } CONTENT_TYPES.forEach(type => { const items = itemsOf(type); html += `
${TYPE_LABEL[type]}
`; @@ -376,6 +385,18 @@ } catch (e) { LS.toast('Ошибка: ' + e.message, 'error'); selClass(_selClass.id); } } + /* открыть классу весь контент одного предмета (любого типа) */ + async function classSubjectBulk(subj) { + const items = CONTENT_TYPES.flatMap(t => itemsOf(t).filter(it => subjOf(it) === subj).map(it => [t, it[keyName(t)]])); + if (!items.length) return; + try { + await Promise.all(items.map(([t, ref]) => LS.accessSetRule(t, ref, 'class', _selClass.id, 1))); + items.forEach(([t, ref]) => { const set = _classOpen[bucket(t)]; if (set && !set.has(ref)) { set.add(ref); bumpSummary(t, ref, +1); } }); + renderRight(); + LS.toast(`Открыт весь контент по предмету «${subjLabel(subj)}»`, 'success'); + } catch (e) { LS.toast('Ошибка: ' + e.message, 'error'); selClass(_selClass.id); } + } + async function classBulk(allow) { if (!allow && !confirm(`Закрыть весь контент у класса «${_selClass.name}»?`)) return; const all = CONTENT_TYPES.flatMap(t => itemsOf(t).map(it => [t, it[keyName(t)]])); @@ -510,6 +531,7 @@ window.accSelClass = selClass; window.accClassToggle = classToggle; window.accClassBulk = classBulk; + window.accClassSubj = classSubjectBulk; window.accMx = mxToggle; window.accMxSearch = mxSearch; window.accMxRowBulk = mxRowBulk;