Много разных изменений

This commit is contained in:
Zuev
2026-08-20 00:55:27 +03:00
parent 3599d850f6
commit a1c4ee4298
78 changed files with 4698 additions and 428 deletions

View File

@@ -1,8 +1,17 @@
import { api, getSession } from '../api.js';
import { escapeHtml, hideAlert, showAlert } from '../utils.js';
import { alertAction } from '../dialog.js';
import { AsyncCombobox } from '../async-combobox.js';
const MANAGER_ROLES = new Set(['ADMIN', 'EDUCATION_OFFICE', 'DEPARTMENT']);
export function teacherAbsenceTeacherOptionsUrl({ query = '', selectedId = '', role = '', departmentId = '' } = {}) {
const params = new URLSearchParams({ query, limit: '30' });
if (role === 'DEPARTMENT' && departmentId) params.set('departmentId', departmentId);
if (selectedId) params.set('selectedId', selectedId);
return `/api/users/teachers/options?${params}`;
}
export async function initTeacherAbsences() {
const session = getSession();
const role = session?.role;
@@ -27,6 +36,20 @@ export async function initTeacherAbsences() {
let preferenceItems = [];
let changeItems = [];
new AsyncCombobox(teacherSelect, {
placeholder: 'Найдите преподавателя по ФИО',
optionLabel: teacher => teacher.fullName || teacher.username || `ID ${teacher.id}`,
optionDescription: teacher => [teacher.jobTitle, teacher.departmentName].filter(Boolean).join(' · '),
load: async (query, selectedId) => {
return api.get(teacherAbsenceTeacherOptionsUrl({
query,
selectedId,
role,
departmentId: session?.departmentId
}));
}
});
setDefaultPeriod(startInput, endInput);
form?.addEventListener('submit', createAbsence);
statusFilter?.addEventListener('change', loadAbsences);
@@ -46,21 +69,7 @@ export async function initTeacherAbsences() {
document.getElementById('teacher-change-refresh')?.addEventListener('click', loadChangeReviews);
changeReviewList?.addEventListener('click', handleChangeReview);
await Promise.all([loadTeachers(), loadAbsences(), loadPreferenceMeta(), loadChangeReviews()]);
async function loadTeachers() {
try {
let teachers = await api.get('/api/users/teachers');
if (role === 'DEPARTMENT' && session?.departmentId) {
teachers = teachers.filter(item => String(item.departmentId) === String(session.departmentId));
}
teacherSelect.innerHTML = '<option value="">Выберите преподавателя</option>' + teachers.map(item => `
<option value="${escapeHtml(item.id)}">${escapeHtml(item.fullName || item.username || `ID ${item.id}`)}</option>
`).join('');
} catch (error) {
teacherSelect.innerHTML = `<option value="">${escapeHtml(error.message || 'Не удалось загрузить преподавателей')}</option>`;
}
}
await Promise.all([loadAbsences(), loadPreferenceMeta(), loadChangeReviews()]);
async function loadAbsences() {
registry.innerHTML = '<div class="loading-row">Загрузка...</div>';
@@ -167,7 +176,7 @@ export async function initTeacherAbsences() {
await openWizard(id);
}
} catch (error) {
window.alert(error.message || 'Не удалось выполнить действие');
await alertAction({ title: 'Действие не выполнено', message: error.message || 'Не удалось выполнить действие' });
} finally {
button.disabled = false;
}
@@ -328,7 +337,7 @@ export async function initTeacherAbsences() {
const approved = button.dataset.preferenceReview === 'approve';
const comment = card.querySelector('.teacher-dialogue-comment')?.value.trim() || '';
if (!approved && !comment) {
window.alert('При отклонении укажите комментарий');
await alertAction({ title: 'Нужен комментарий', message: 'При отклонении укажите комментарий.' });
return;
}
button.disabled = true;
@@ -339,7 +348,7 @@ export async function initTeacherAbsences() {
});
await loadPreferenceReviews();
} catch (error) {
window.alert(error.message || 'Не удалось рассмотреть пожелание');
await alertAction({ title: 'Ошибка рассмотрения', message: error.message || 'Не удалось рассмотреть пожелание' });
button.disabled = false;
}
}
@@ -397,7 +406,7 @@ export async function initTeacherAbsences() {
const approved = button.dataset.changeReview === 'approve';
const comment = card.querySelector('.teacher-dialogue-comment')?.value.trim() || '';
if (!approved && !comment) {
window.alert('При отклонении укажите комментарий');
await alertAction({ title: 'Нужен комментарий', message: 'При отклонении укажите комментарий.' });
return;
}
button.disabled = true;
@@ -405,7 +414,7 @@ export async function initTeacherAbsences() {
await api.post(`/api/teacher-change-requests/${button.dataset.id}/review`, { approved, comment });
await Promise.all([loadChangeReviews(), loadAbsences()]);
} catch (error) {
window.alert(error.message || 'Не удалось применить решение');
await alertAction({ title: 'Решение не применено', message: error.message || 'Не удалось применить решение' });
button.disabled = false;
}
}