Lab page: per-variant create/edit modals, rendered conditions, inline lab edit; student page: compact code field, big score, defense wording, header highlight; toasts tinted; p margin

This commit is contained in:
2026-10-02 20:08:26 +03:00
parent 7b1e6043c2
commit 5ced01f70d
13 changed files with 304 additions and 214 deletions

View File

@@ -363,7 +363,7 @@ function applyDefenseToCell(s) {
: (s.code ? 'код ' + s.code : 'ожидает')));
}
if (s.status === 'ready') {
btn.title = 'Защита завершена: ' + (s.readyReason === 'timeout' ? 'время вышло' : 'студент нажал «Готов»');
btn.title = 'Защита: ' + defenseReasonText(s.readyReason);
if (label) label.textContent = 'готова';
}
}
@@ -388,7 +388,7 @@ function syncDefenseStatuses(sessions, initial) {
var who = (btn && btn.getAttribute('data-student-name')) || 'студент';
var lab = (btn && btn.getAttribute('data-lab-name')) || 'лабораторная';
var reason = s.readyReason === 'timeout' ? 'время вышло' : 'нажал «Готов»';
showToast(who + ' — ' + lab + ': завершил защиту (' + reason + ').');
showToast(who + ' — ' + lab + ': ' + reason + '.');
}
// Обновляем открытый диалог, если он про эту сессию.
@@ -440,9 +440,8 @@ function startDefenseWatch() {
/* ---------- Индивидуальное задание (защита) ---------- */
function defenseReasonText(reason) {
if (reason === 'timeout') return 'время вышло';
if (reason === 'button') return 'студент нажал «Готов»';
return '';
if (reason === 'timeout') return 'Вышло время';
return 'Готов к сдаче';
}
function defenseStatusText(status, code, seconds, reason) {
@@ -453,8 +452,7 @@ function defenseStatusText(status, code, seconds, reason) {
}
if (status === 'started') return 'Студент выполняет работу, осталось ' + fmtSeconds(seconds) + '.';
if (status === 'ready') {
var why = defenseReasonText(reason);
return 'Студент готов к сдаче' + (why ? ' (' + why + ')' : '') + '. Можно начать заново для дополнительного задания.';
return defenseReasonText(reason) + '. Можно начать заново для дополнительного задания.';
}
return '';
}

View File

@@ -0,0 +1,22 @@
/* Страница лабораторной: переключение просмотра/редактирования параметров. */
(function () {
function setMode(editing) {
var view = document.getElementById('lab-description-view');
var form = document.getElementById('lab-edit-form');
if (!view || !form) return;
view.hidden = editing;
form.hidden = !editing;
if (editing) {
var t = form.querySelector('input[name="title"]');
if (t) t.focus();
}
}
document.addEventListener('click', function (e) {
var a = e.target.closest('[data-action]');
if (!a) return;
var kind = a.getAttribute('data-action');
if (kind === 'lab-edit') setMode(true);
if (kind === 'lab-edit-cancel') setMode(false);
});
})();

View File

@@ -84,10 +84,17 @@
/* Активный пункт меню */
function initNavActive() {
var path = window.location.pathname;
document.querySelectorAll('#top-nav .nav-link').forEach(function (a) {
var links = [].slice.call(document.querySelectorAll('#top-nav .nav-link'));
var best = null;
var bestLen = -1;
links.forEach(function (a) {
var href = a.getAttribute('href') || '';
if (path === href || (href !== '/' && path.indexOf(href + '/') === 0)) a.classList.add('active');
if (href === '/') return;
if (path === href || path.indexOf(href + '/') === 0) {
if (href.length > bestLen) { best = a; bestLen = href.length; }
}
});
if (best) best.classList.add('active');
}
/* Серверные уведомления: автоскрытие и кнопка закрытия */

View File

@@ -29,6 +29,12 @@ document.querySelectorAll('.defense-timer').forEach(function (el) {
if (left > 0) {
render(left);
startTick();
markDefense(true);
}
function markDefense(active) {
var name = document.querySelector('.nav-user');
if (name) name.classList.toggle('defense-active', active);
}
if (labId) {
@@ -39,9 +45,11 @@ document.querySelectorAll('.defense-timer').forEach(function (el) {
if (!res || !res.ok) return;
// У сессии закончилось время.
if (res.status !== 'started') {
markDefense(false);
finish();
return;
}
markDefense(true);
var server = parseInt(res.secondsLeft || '0', 10);
if (server <= 0) { finish(); return; }
// Подстраиваем локальный отсчёт под серверное время.