import { api } from '../api.js'; import { escapeHtml, showAlert, hideAlert } from '../utils.js'; import { fetchEducationForms } from './edu-forms.js'; export async function initGroups() { const groupsTbody = document.getElementById('groups-tbody'); const createGroupForm = document.getElementById('create-group-form'); const newGroupEfSelect = document.getElementById('new-group-ef'); const newGroupDepartmentSelect = document.getElementById('new-group-department'); const newGroupSpecialitySelect = document.getElementById('new-group-speciality-code'); const filterEfSelect = document.getElementById('filter-ef'); let allGroups = []; let educationForms = []; let departments = []; let specialties = []; async function loadInitialData() { try { [educationForms, departments, specialties] = await Promise.all([ fetchEducationForms(), api.get('/api/departments'), api.get('/api/specialties') ]); populateEfSelects(educationForms); populateDepartmentSelect(departments); populateSpecialitySelect(specialties); await loadGroups(); } catch (e) { groupsTbody.innerHTML = 'Ошибка загрузки данных'; } } async function loadGroups() { try { allGroups = await api.get('/api/groups'); applyGroupFilter(); } catch (e) { groupsTbody.innerHTML = 'Ошибка загрузки'; } } function applyGroupFilter() { const filterId = filterEfSelect.value; const filtered = filterId ? allGroups.filter(g => g.educationFormId == filterId) : allGroups; renderGroups(filtered); } filterEfSelect.addEventListener('change', applyGroupFilter); function populateEfSelects(forms) { // Group creation select const currentVal = newGroupEfSelect.value; newGroupEfSelect.innerHTML = forms.map(ef => `` ).join(''); if (currentVal && forms.find(f => f.id == currentVal)) { newGroupEfSelect.value = currentVal; } syncSelects(newGroupEfSelect); // Filter select const currentFilter = filterEfSelect.value; filterEfSelect.innerHTML = '' + forms.map(ef => `` ).join(''); if (currentFilter) filterEfSelect.value = currentFilter; syncSelects(filterEfSelect); } function populateDepartmentSelect(items) { const currentVal = newGroupDepartmentSelect.value; if (!items || !items.length) { newGroupDepartmentSelect.innerHTML = ''; return; } newGroupDepartmentSelect.innerHTML = '' + items.map(department => { const name = department.departmentName || department.name || 'Без названия'; const code = department.departmentCode || department.code || department.id; return ``; }).join(''); if (currentVal && items.find(department => department.id == currentVal)) { newGroupDepartmentSelect.value = currentVal; } syncSelects(newGroupDepartmentSelect); } function populateSpecialitySelect(items) { const currentVal = newGroupSpecialitySelect.value; if (!items || !items.length) { newGroupSpecialitySelect.innerHTML = ''; return; } newGroupSpecialitySelect.innerHTML = '' + items.map(speciality => { const name = speciality.specialityName || speciality.name || 'Без названия'; const code = speciality.specialityCode || speciality.specialtyCode || speciality.specialty_code || speciality.id; return ``; }).join(''); if (currentVal && items.find(speciality => speciality.id == currentVal)) { newGroupSpecialitySelect.value = currentVal; } syncSelects(newGroupSpecialitySelect); } function departmentLabel(departmentId) { const department = departments.find(item => item.id == departmentId); if (!department) return departmentId || '-'; return department.departmentName || department.name || departmentId; } function specialityLabel(specialityId) { const speciality = specialties.find(item => item.id == specialityId); if (!speciality) return specialityId || '-'; const code = speciality.specialityCode || speciality.specialtyCode || speciality.specialty_code || speciality.id; const name = speciality.specialityName || speciality.name || ''; return name ? `${code} — ${name}` : code; } function renderGroups(groups) { if (!groups || !groups.length) { groupsTbody.innerHTML = 'Нет групп'; return; } groupsTbody.innerHTML = groups.map(g => ` ${g.id} ${escapeHtml(g.name)} ${escapeHtml(g.groupSize)} ${escapeHtml(g.educationFormName)} ${escapeHtml(departmentLabel(g.departmentId))} ${g.course || '-'} ${escapeHtml(specialityLabel(g.specialityCode))} `).join(''); } createGroupForm.addEventListener('submit', async (e) => { e.preventDefault(); hideAlert('create-group-alert'); const name = document.getElementById('new-group-name').value.trim(); const groupSize = document.getElementById('new-group-size').value; const educationFormId = newGroupEfSelect.value; const departmentId = newGroupDepartmentSelect.value; const yearStartStudy = document.getElementById('new-group-yearStartStudy').value; const specialityCode = newGroupSpecialitySelect.value; if (!name) { showAlert('create-group-alert', 'Введите название группы', 'error'); return; } if (!groupSize) { showAlert('create-group-alert', 'Введите размер группы', 'error'); return; } if (!educationFormId) { showAlert('create-group-alert', 'Выберите форму обучения', 'error'); return; } if (!departmentId) { showAlert('create-group-alert', 'Выберите кафедру', 'error'); return; } if (!yearStartStudy) { showAlert('create-group-alert', 'Введите год начала обучения', 'error'); return; } if (!specialityCode) { showAlert('create-group-alert', 'Выберите специальность', 'error'); return; } try { const data = await api.post('/api/groups', { name, groupSize: Number(groupSize), educationFormId: Number(educationFormId), departmentId: Number(departmentId), yearStartStudy: Number(yearStartStudy), specialityCode: Number(specialityCode) }); showAlert('create-group-alert', `Группа "${escapeHtml(data.name || name)}" создана`, 'success'); createGroupForm.reset(); syncSelects(newGroupEfSelect, newGroupDepartmentSelect, newGroupSpecialitySelect); loadGroups(); } catch (e) { showAlert('create-group-alert', e.message || 'Ошибка создания', 'error'); } }); groupsTbody.addEventListener('click', async (e) => { const btn = e.target.closest('.btn-delete'); if (!btn) return; if (!confirm('Удалить группу?')) return; try { await api.delete('/api/groups/' + btn.dataset.id); loadGroups(); } catch (e) { alert(e.message || 'Ошибка удаления'); } }); await loadInitialData(); function syncSelects(...selects) { selects.filter(Boolean).forEach(select => { select.dispatchEvent(new Event('change', { bubbles: true })); }); } }