доработал отображение учебного графика

This commit is contained in:
Zuev
2026-05-01 14:02:01 +03:00
parent 89c822a073
commit bf02efb8b8
28 changed files with 1644 additions and 1145 deletions

View File

@@ -7,22 +7,15 @@ export async function initDepartmentsData() {
const createDeptForm = document.getElementById('create-department-form');
const createSpecForm = document.getElementById('create-specialty-form');
const createProfileForm = document.getElementById('create-profile-form');
const profileSpecialtySelect = document.getElementById('profile-specialty');
const profilesTbody = document.getElementById('profiles-tbody');
const editDeptForm = document.getElementById('edit-department-form');
const editSpecForm = document.getElementById('edit-specialty-form');
const editProfileForm = document.getElementById('edit-profile-form');
const editDeptModal = document.getElementById('modal-edit-department');
const editSpecModal = document.getElementById('modal-edit-specialty');
const editProfileModal = document.getElementById('modal-edit-profile');
const editDeptClose = document.getElementById('modal-edit-department-close');
const editSpecClose = document.getElementById('modal-edit-specialty-close');
const editProfileClose = document.getElementById('modal-edit-profile-close');
let departments = [];
let specialties = [];
let profiles = [];
async function loadData() {
// Load Departments
@@ -37,11 +30,8 @@ export async function initDepartmentsData() {
try {
specialties = await api.get('/api/specialties');
renderSpecialties();
renderProfileSpecialtySelect();
await loadProfiles();
} catch (e) {
specTbody.innerHTML = '<tr><td colspan="4" class="loading-row">-</td></tr>';
profilesTbody.innerHTML = '<tr><td colspan="4" class="loading-row">-</td></tr>';
}
}
@@ -81,52 +71,6 @@ export async function initDepartmentsData() {
`).join('');
}
function renderProfileSpecialtySelect() {
const current = profileSpecialtySelect.value;
profileSpecialtySelect.innerHTML = '<option value="">Выберите специальность</option>' +
specialties.map(s => `<option value="${s.id}">${escapeHtml(s.specialityCode || s.specialtyCode || s.specialty_code)}${escapeHtml(s.specialityName || s.name)}</option>`).join('');
if (current && specialties.some(s => String(s.id) === String(current))) {
profileSpecialtySelect.value = current;
} else if (specialties.length) {
profileSpecialtySelect.value = String(specialties[0].id);
}
syncSelect(profileSpecialtySelect);
}
async function loadProfiles() {
const specialtyId = profileSpecialtySelect.value;
if (!specialtyId) {
profiles = [];
profilesTbody.innerHTML = '<tr><td colspan="4" class="loading-row">Выберите специальность</td></tr>';
return;
}
profilesTbody.innerHTML = '<tr><td colspan="4" class="loading-row">Загрузка...</td></tr>';
try {
profiles = await api.get(`/api/specialties/${specialtyId}/profiles`);
renderProfiles();
} catch (error) {
profilesTbody.innerHTML = `<tr><td colspan="4" class="loading-row">Ошибка загрузки: ${escapeHtml(error.message)}</td></tr>`;
}
}
function renderProfiles() {
if (!profiles.length) {
profilesTbody.innerHTML = '<tr><td colspan="4" class="loading-row">Профили не созданы</td></tr>';
return;
}
profilesTbody.innerHTML = profiles.map(profile => `
<tr>
<td>${profile.id}</td>
<td>${escapeHtml(profile.name)}</td>
<td>${escapeHtml(profile.description || '-')}</td>
<td>
<button class="btn-edit-classroom btn-edit-profile" data-id="${profile.id}">Изменить</button>
<button class="btn-delete btn-delete-profile" data-id="${profile.id}">Удалить</button>
</td>
</tr>
`).join('');
}
createDeptForm.addEventListener('submit', async (e) => {
e.preventDefault();
hideAlert('create-dept-alert');
@@ -197,59 +141,6 @@ export async function initDepartmentsData() {
}
});
profileSpecialtySelect.addEventListener('change', loadProfiles);
createProfileForm.addEventListener('submit', async (e) => {
e.preventDefault();
hideAlert('create-profile-alert');
const specialtyId = profileSpecialtySelect.value;
const name = document.getElementById('profile-name').value.trim();
const description = document.getElementById('profile-description').value.trim();
if (!specialtyId || !name) {
showAlert('create-profile-alert', 'Выберите специальность и заполните название профиля', 'error');
return;
}
try {
await api.post(`/api/specialties/${specialtyId}/profiles`, { name, description });
showAlert('create-profile-alert', `Профиль "${name}" создан`, 'success');
createProfileForm.reset();
profileSpecialtySelect.value = specialtyId;
syncSelect(profileSpecialtySelect);
await loadProfiles();
} catch (error) {
showAlert('create-profile-alert', error.message || 'Ошибка создания профиля', 'error');
}
});
profilesTbody.addEventListener('click', async (e) => {
const editBtn = e.target.closest('.btn-edit-profile');
const deleteBtn = e.target.closest('.btn-delete-profile');
if (editBtn) {
const profile = profiles.find(item => item.id == editBtn.dataset.id);
if (!profile) return;
document.getElementById('edit-profile-id').value = profile.id;
document.getElementById('edit-profile-name').value = profile.name || '';
document.getElementById('edit-profile-description').value = profile.description || '';
hideAlert('edit-profile-alert');
editProfileModal.classList.add('open');
return;
}
if (deleteBtn) {
if (!confirm('Удалить профиль обучения?')) return;
try {
await api.delete(`/api/specialties/${profileSpecialtySelect.value}/profiles/${deleteBtn.dataset.id}`);
showAlert('create-profile-alert', 'Профиль удалён', 'success');
await loadProfiles();
} catch (error) {
showAlert('create-profile-alert', error.message || 'Ошибка удаления профиля', 'error');
}
}
});
specTbody.addEventListener('click', async (e) => {
const editBtn = e.target.closest('.btn-edit-specialty');
const deleteBtn = e.target.closest('.btn-delete-specialty');
@@ -322,45 +213,14 @@ export async function initDepartmentsData() {
}
});
editProfileForm.addEventListener('submit', async (e) => {
e.preventDefault();
hideAlert('edit-profile-alert');
const specialtyId = profileSpecialtySelect.value;
const id = document.getElementById('edit-profile-id').value;
const name = document.getElementById('edit-profile-name').value.trim();
const description = document.getElementById('edit-profile-description').value.trim();
if (!specialtyId || !id || !name) {
showAlert('edit-profile-alert', 'Заполните название профиля', 'error');
return;
}
try {
await api.put(`/api/specialties/${specialtyId}/profiles/${id}`, { id: Number(id), name, description });
editProfileModal.classList.remove('open');
showAlert('create-profile-alert', `Профиль "${name}" обновлён`, 'success');
await loadProfiles();
} catch (error) {
showAlert('edit-profile-alert', error.message || 'Ошибка обновления профиля', 'error');
}
});
editDeptClose.addEventListener('click', () => editDeptModal.classList.remove('open'));
editSpecClose.addEventListener('click', () => editSpecModal.classList.remove('open'));
editProfileClose.addEventListener('click', () => editProfileModal.classList.remove('open'));
editDeptModal.addEventListener('click', (e) => {
if (e.target === editDeptModal) editDeptModal.classList.remove('open');
});
editSpecModal.addEventListener('click', (e) => {
if (e.target === editSpecModal) editSpecModal.classList.remove('open');
});
editProfileModal.addEventListener('click', (e) => {
if (e.target === editProfileModal) editProfileModal.classList.remove('open');
});
await loadData();
function syncSelect(select) {
select.dispatchEvent(new Event('change', { bubbles: true }));
}
}