From c04a8c2178aaf27b5c68f662cf850329b9131b8f Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Mon, 22 Jun 2026 17:49:51 +0300 Subject: [PATCH] =?UTF-8?q?fix(sidebar):=20=D0=BF=D1=80=D1=8F=D1=82=D0=B0?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BF=D1=83=D1=81=D1=82=D1=8B=D0=B5=20=D0=B3?= =?UTF-8?q?=D1=80=D1=83=D0=BF=D0=BF=D1=8B=20(=D0=B7=D0=B0=D0=B3=D0=BE?= =?UTF-8?q?=D0=BB=D0=BE=D0=B2=D0=BE=D0=BA=20=D0=B1=D0=B5=D0=B7=20=D0=B2?= =?UTF-8?q?=D0=B8=D0=B4=D0=B8=D0=BC=D1=8B=D1=85=20=D0=BF=D1=83=D0=BD=D0=BA?= =?UTF-8?q?=D1=82=D0=BE=D0=B2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Когда все пункты группы сайдбара скрыты (фичи отключены / teacher-only у ученика), оставался висеть пустой заголовок-аккордеон (напр. «Практика и игры»). Добавлена hideEmptySidebarGroups(): по .sb-group проверяет computed-display пунктов .sb-link в теле и прячет группу, если ни одного видимого. Зовётся синхронно из sidebar.js после сборки (по кэш-CSS — без мигания) и в конце hideDisabledFeatures (по свежим данным; re-show при включении). Co-Authored-By: Claude Opus 4.8 (1M context) --- js/api.js | 18 ++++++++++++++++++ js/sidebar.js | 3 +++ 2 files changed, 21 insertions(+) diff --git a/js/api.js b/js/api.js index 09ab2df..261378e 100644 --- a/js/api.js +++ b/js/api.js @@ -887,6 +887,22 @@ try { if (_cachedFeats) _applyFeatureCss(_cachedFeats); } catch { /* нет кэша / приватный режим — просто ждём async */ } +/* Прячет группы сайдбара (.sb-group), у которых не осталось ни одного видимого пункта, + чтобы не висел пустой заголовок-аккордеон (напр. «Практика и игры», когда все + модули отключены). Зовётся после построения сайдбара и после hideDisabledFeatures. */ +function hideEmptySidebarGroups() { + document.querySelectorAll('.sb-group').forEach(g => { + const body = g.querySelector('.sb-group-body'); + if (!body) return; + let anyVisible = false; + body.querySelectorAll('.sb-link').forEach(it => { + const cs = getComputedStyle(it); + if (cs.display !== 'none' && cs.visibility !== 'hidden') anyVisible = true; + }); + g.style.display = anyVisible ? '' : 'none'; + }); +} + /** * Show board sidebar link only for teachers/admins and students in a class. * Call after LS.initPage(). Uses features cache (_no_class flag). @@ -925,6 +941,7 @@ async function hideDisabledFeatures() { document.querySelector('[onclick*="tab-account"]')?.click(); } } + hideEmptySidebarGroups(); // после обновления видимости пунктов — спрятать пустые группы // Exam-prep track links (/exam-prep/): показываем только включённые // (exam_tracks.enabled) и доступные пользователю треки. /api/exam-prep/tracks @@ -1129,6 +1146,7 @@ window.LS = { loadFeatures, clearFeaturesCache, hideDisabledFeatures, + hideEmptySidebarGroups, showBoardIfAllowed, biochemGetElements, biochemGetMolecules, biochemGetMolecule, biochemValidate, biochemAnalyze, biochemGetReactions, biochemGetChallenges, biochemSolveChallenge, diff --git a/js/sidebar.js b/js/sidebar.js index db73073..a8d2154 100644 --- a/js/sidebar.js +++ b/js/sidebar.js @@ -228,6 +228,9 @@ LS.showBoardIfAllowed?.(); LS.hideDisabledFeatures?.(); LS.notif?.init?.(); + // Синхронно по кэш-состоянию (CSS уже инъектнут до сборки) — прячем пустые + // группы сразу, без мигания; hideDisabledFeatures повторит после свежих данных. + LS.hideEmptySidebarGroups?.(); } // Глобальная плавающая кнопка «создать карточку» (на всех страницах с шапкой)