поправил вид сетки и прочие баги
This commit is contained in:
@@ -21,11 +21,15 @@ export async function initDepartmentWorkspace() {
|
||||
const commentsSubjectInput = document.getElementById('department-comment-subject-id');
|
||||
const commentsTextInput = document.getElementById('department-comment-text');
|
||||
const commentsCloseButton = document.getElementById('department-comments-close');
|
||||
let lastTeachers = null;
|
||||
let lastWorkload = null;
|
||||
let teachersErrorMessage = '';
|
||||
let workloadErrorMessage = '';
|
||||
|
||||
setDefaultDates(startInput, endInput);
|
||||
refreshButton?.addEventListener('click', loadWorkspace);
|
||||
departmentSelect?.addEventListener('change', loadWorkspace);
|
||||
startInput?.addEventListener('change', loadWorkload);
|
||||
startInput?.addEventListener('change', handleStartDateChange);
|
||||
endInput?.addEventListener('change', loadWorkload);
|
||||
importForm?.addEventListener('submit', importSubjects);
|
||||
commentsForm?.addEventListener('submit', saveComment);
|
||||
@@ -53,6 +57,11 @@ export async function initDepartmentWorkspace() {
|
||||
|
||||
async function loadWorkspace() {
|
||||
hideAlert('department-workspace-alert');
|
||||
lastTeachers = null;
|
||||
lastWorkload = null;
|
||||
teachersErrorMessage = '';
|
||||
workloadErrorMessage = '';
|
||||
renderTeachers();
|
||||
await Promise.all([loadSubjects(), loadTeachers(), loadWorkload()]);
|
||||
}
|
||||
|
||||
@@ -172,25 +181,28 @@ export async function initDepartmentWorkspace() {
|
||||
}
|
||||
|
||||
async function loadTeachers() {
|
||||
const container = document.getElementById('department-teachers-list');
|
||||
container.textContent = 'Загрузка...';
|
||||
lastTeachers = null;
|
||||
teachersErrorMessage = '';
|
||||
renderTeachers();
|
||||
try {
|
||||
const teachers = await api.get(`/api/department/teachers?departmentId=${encodeURIComponent(selectedDepartmentId() || '')}`);
|
||||
container.innerHTML = teachers.length
|
||||
? teachers.map(teacher => `
|
||||
<article class="metric-card">
|
||||
<strong>${escapeHtml(teacher.fullName || teacher.username || '-')}</strong>
|
||||
<span>${escapeHtml(teacher.jobTitle || 'Должность не указана')}</span>
|
||||
</article>
|
||||
`).join('')
|
||||
: '<div class="loading-row">Преподаватели не найдены</div>';
|
||||
lastTeachers = Array.isArray(teachers) ? teachers : [];
|
||||
renderTeachers();
|
||||
} catch (error) {
|
||||
container.innerHTML = `<div class="loading-row">${escapeHtml(error.message || 'Ошибка загрузки преподавателей')}</div>`;
|
||||
lastTeachers = [];
|
||||
teachersErrorMessage = error.message || 'Ошибка загрузки преподавателей';
|
||||
renderTeachers();
|
||||
}
|
||||
}
|
||||
|
||||
async function loadWorkload() {
|
||||
const container = document.getElementById('department-workload-list');
|
||||
if (!startInput.value || !endInput.value) {
|
||||
lastWorkload = [];
|
||||
workloadErrorMessage = 'Выберите начало и окончание периода';
|
||||
renderTeachers();
|
||||
return;
|
||||
}
|
||||
|
||||
const params = new URLSearchParams({
|
||||
startDate: startInput.value,
|
||||
endDate: endInput.value
|
||||
@@ -198,23 +210,84 @@ export async function initDepartmentWorkspace() {
|
||||
if (selectedDepartmentId()) {
|
||||
params.set('departmentId', selectedDepartmentId());
|
||||
}
|
||||
container.textContent = 'Загрузка...';
|
||||
lastWorkload = null;
|
||||
workloadErrorMessage = '';
|
||||
renderTeachers();
|
||||
try {
|
||||
const workload = await api.get(`/api/workload/teachers?${params}`);
|
||||
container.innerHTML = workload.length
|
||||
? workload.map(item => `
|
||||
<article class="metric-card">
|
||||
<strong>${escapeHtml(item.name || '-')}</strong>
|
||||
<span>${escapeHtml(String(item.academicHours ?? 0))} ак. ч.</span>
|
||||
<small>${escapeHtml(String(item.lessonCount ?? 0))} занятий</small>
|
||||
</article>
|
||||
`).join('')
|
||||
: '<div class="loading-row">Нагрузка не найдена</div>';
|
||||
lastWorkload = Array.isArray(workload) ? workload : [];
|
||||
renderTeachers();
|
||||
} catch (error) {
|
||||
container.innerHTML = `<div class="loading-row">${escapeHtml(error.message || 'Ошибка расчёта нагрузки')}</div>`;
|
||||
lastWorkload = [];
|
||||
workloadErrorMessage = error.message || 'Ошибка расчёта нагрузки';
|
||||
renderTeachers();
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStartDateChange() {
|
||||
if (startInput.value && endInput.value && startInput.value > endInput.value) {
|
||||
endInput.value = '';
|
||||
}
|
||||
await loadWorkload();
|
||||
}
|
||||
|
||||
function renderTeachers() {
|
||||
const container = document.getElementById('department-teachers-list');
|
||||
if (!container) return;
|
||||
|
||||
if (lastTeachers === null || lastWorkload === null) {
|
||||
container.textContent = 'Загрузка...';
|
||||
return;
|
||||
}
|
||||
|
||||
const teachers = Array.isArray(lastTeachers) ? lastTeachers : [];
|
||||
const workload = Array.isArray(lastWorkload) ? lastWorkload : [];
|
||||
const workloadByTeacher = new Map();
|
||||
const usedWorkloadKeys = new Set();
|
||||
|
||||
workload
|
||||
.filter(item => item && (item.id || item.name))
|
||||
.forEach(item => {
|
||||
workloadKeys(item).forEach(key => {
|
||||
if (!workloadByTeacher.has(key)) {
|
||||
workloadByTeacher.set(key, item);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const rows = teachers.map(teacher => {
|
||||
const workloadItem = workloadKeys(teacher)
|
||||
.map(key => workloadByTeacher.get(key))
|
||||
.find(Boolean);
|
||||
if (workloadItem) {
|
||||
workloadKeys(workloadItem).forEach(key => usedWorkloadKeys.add(key));
|
||||
}
|
||||
return renderTeacherMetric({
|
||||
name: teacher.fullName || teacher.username || '-',
|
||||
meta: teacher.jobTitle || 'Должность не указана',
|
||||
workload: workloadItem
|
||||
}, workloadErrorMessage);
|
||||
});
|
||||
|
||||
workload
|
||||
.filter(item => item && (item.id || item.name))
|
||||
.filter(item => workloadKeys(item).every(key => !usedWorkloadKeys.has(key)))
|
||||
.forEach(item => {
|
||||
rows.push(renderTeacherMetric({
|
||||
name: item.name || '-',
|
||||
meta: 'Есть занятия в расписании кафедры',
|
||||
workload: item
|
||||
}, workloadErrorMessage));
|
||||
});
|
||||
|
||||
if (rows.length) {
|
||||
container.innerHTML = rows.join('');
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = `<div class="loading-row">${escapeHtml(teachersErrorMessage || 'Преподаватели не найдены')}</div>`;
|
||||
}
|
||||
|
||||
function selectedDepartmentId() {
|
||||
return role === ROLE_DEPARTMENT ? userDepartmentId : departmentSelect.value;
|
||||
}
|
||||
@@ -261,3 +334,36 @@ function subjectCountLabel(count) {
|
||||
if ([2, 3, 4].includes(count % 10)) return `${count} дисциплины`;
|
||||
return `${count} дисциплин`;
|
||||
}
|
||||
|
||||
function renderTeacherMetric(item, workloadErrorMessage) {
|
||||
return `
|
||||
<article class="metric-card">
|
||||
<strong>${escapeHtml(item.name || '-')}</strong>
|
||||
<span>${escapeHtml(item.meta || 'Должность не указана')}</span>
|
||||
<small>${escapeHtml(workloadLabel(item.workload, workloadErrorMessage))}</small>
|
||||
</article>
|
||||
`;
|
||||
}
|
||||
|
||||
function workloadLabel(item, workloadErrorMessage) {
|
||||
if (workloadErrorMessage) {
|
||||
return workloadErrorMessage;
|
||||
}
|
||||
if (!item) {
|
||||
return '0 ак. ч., 0 занятий за период';
|
||||
}
|
||||
const hours = String(item.academicHours ?? 0);
|
||||
const lessons = String(item.lessonCount ?? 0);
|
||||
return `${hours} ак. ч., ${lessons} занятий за период`;
|
||||
}
|
||||
|
||||
function workloadKeys(item) {
|
||||
return [
|
||||
item.id == null ? null : `id:${item.id}`,
|
||||
normalizeTeacherName(item.fullName || item.name || item.username)
|
||||
].filter(Boolean);
|
||||
}
|
||||
|
||||
function normalizeTeacherName(value) {
|
||||
return value ? `name:${String(value).trim().toLowerCase()}` : null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user