Redesign #13

Merged
Zuev merged 15 commits from Redesign into main 2026-06-25 16:43:55 +00:00
5 changed files with 62 additions and 7 deletions
Showing only changes of commit 6a03931190 - Show all commits

View File

@@ -166,6 +166,7 @@ public class AcademicCalendarController {
}
try {
replaceCalendarSubjects(calendar, rows == null ? List.of() : rows);
scheduleGeneratorService.clearCache();
return ResponseEntity.ok(calendarSubjectRepository.findByCalendarIdWithSubject(id).stream()
.map(this::toCalendarSubjectDto)
.toList());
@@ -284,6 +285,7 @@ public class AcademicCalendarController {
}
calendarSubjectRepository.deleteByAcademicCalendar_Id(calendar.getId());
calendarSubjectRepository.flush();
List<AcademicCalendarSubject> entities = rows.stream()
.map(row -> {
AcademicCalendarSubject calendarSubject = new AcademicCalendarSubject();

View File

@@ -435,7 +435,7 @@ GET /api/schedule?groupId=1&startDate=2026-04-27&endDate=2026-05-03
]
```
`semesterNumber` — номер учебного семестра внутри графика: для 4 курсов доступны значения `1..8`. API принимает только существующие неархивные дисциплины из `/api/subjects`, не допускает дубли одной дисциплины в одном семестре и возвращает сохранённые записи с `subjectName`, `subjectCode` и `departmentId`.
`semesterNumber` — номер учебного семестра внутри графика: для 4 курсов доступны значения `1..8`. API принимает только существующие неархивные дисциплины из `/api/subjects`, не допускает дубли одной дисциплины в одном семестре и возвращает сохранённые записи с `subjectName`, `subjectCode` и `departmentId`. `PUT /subjects` выполняет атомарную полную замену списка: перед вставкой нового набора старые привязки этого графика удаляются и синхронизируются с БД.
### `POST /api/admin/schedule-rules`

View File

@@ -139,7 +139,7 @@ frontend/
### Особенности админских вкладок
- Вкладка `groups` загружает кафедры, специальности, профили, учебные годы и календарные графики. Список групп открывается через `/api/groups?includeArchived=true`, поэтому в таблице видны активные, будущие, завершившие обучение и архивные группы со статусом. Группа создаётся через `/api/groups` с `specialtyId` и `specialtyProfileId`, блок подгрупп использует `/api/subgroups` и `/api/groups/{id}/subgroups`, а блок назначений использует `/api/groups/{id}/calendar-assignments`. После назначения графика в таблице назначений сразу выводятся дисциплины графика, сгруппированные по номерам семестров. В селекты подгрупп и назначений попадают только группы с `active=true`.
- Вкладка `groups` загружает кафедры, специальности, профили, учебные годы и календарные графики. Список групп открывается через `/api/groups?includeArchived=true`, поэтому в таблице видны активные, будущие, завершившие обучение и архивные группы со статусом. Группа создаётся через `/api/groups` с `specialtyId` и `specialtyProfileId`, а модалка редактирования использует широкую сетку полей без внутреннего пустого скролла. Блок подгрупп использует `/api/subgroups` и `/api/groups/{id}/subgroups`, а блок назначений использует `/api/groups/{id}/calendar-assignments`. После назначения графика в таблице назначений сразу выводятся дисциплины графика, сгруппированные по номерам семестров. В селекты подгрупп и назначений попадают только группы с `active=true`.
- Вкладка `teacher-requests` показывает pending-заявки кафедр на создание преподавателей. Администратор может скорректировать кафедру, логин, ФИО и должность, задать пароль минимум 8 символов, затем одобрить заявку через `/api/teacher-requests/{id}/approve` или отклонить её через `/api/teacher-requests/{id}/reject`. Для роли `ADMIN` счётчик pending-заявок выводится в пункте меню «Заявки» и рядом с заголовком страницы, чтобы очередь была видна без открытия вкладки.
- Вкладка `department-workspace` в блоке преподавателей объединяет данные `/api/department/teachers` и `/api/workload/teachers`: каждый преподаватель показывается одной карточкой с должностью и нагрузкой за выбранный период, преподаватели без занятий получают нулевую нагрузку, а преподаватели из расписания добавляются без дублей. Если дата начала периода выбрана позже даты окончания, поле окончания очищается, а расчёт нагрузки ждёт корректный период.
- Вкладка `department-workspace` позволяет кафедре добавить существующего активного преподавателя на свою кафедру через `/api/department/teachers/{teacherId}/assignments`, отправить заявку на нового преподавателя через `/api/department/teacher-requests` и видеть статусы собственных заявок в таблице.

View File

@@ -74,6 +74,59 @@
color: var(--error);
}
#modal-edit-group .edit-group-modal {
width: min(980px, calc(100vw - 2rem));
max-height: none;
overflow: visible;
}
#modal-edit-group #edit-group-form {
display: grid;
gap: 1rem;
margin-top: 1rem;
}
#modal-edit-group .edit-group-form-row {
display: grid;
gap: 1rem;
align-items: end;
}
#modal-edit-group .edit-group-form-row-main {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
#modal-edit-group .edit-group-form-row-details {
grid-template-columns: repeat(5, minmax(0, 1fr));
}
#modal-edit-group .form-group {
min-width: 0;
}
#modal-edit-group .edit-group-submit {
display: flex;
align-items: flex-end;
}
#modal-edit-group .edit-group-submit .btn {
width: 100%;
}
@media (max-width: 980px) {
#modal-edit-group .edit-group-form-row-main,
#modal-edit-group .edit-group-form-row-details {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 560px) {
#modal-edit-group .edit-group-form-row-main,
#modal-edit-group .edit-group-form-row-details {
grid-template-columns: 1fr;
}
}
#schedule-conflict-modal {
padding: 0.35rem;
overflow-x: hidden;

View File

@@ -98,12 +98,12 @@
<!-- Модальное окно редактирования группы -->
<div class="modal-overlay" id="modal-edit-group">
<div class="modal-content card">
<div class="modal-content card edit-group-modal">
<h2>Редактировать группу</h2>
<button class="modal-close" id="modal-edit-group-close">&times;</button>
<form id="edit-group-form">
<input type="hidden" id="edit-group-id">
<div class="form-row" style="margin-top: 1rem;">
<div class="form-row edit-group-form-row edit-group-form-row-main">
<div class="form-group">
<label for="edit-group-name">Название группы</label>
<input type="text" id="edit-group-name" required>
@@ -119,7 +119,7 @@
</select>
</div>
</div>
<div class="form-row" style="margin-top: 1rem;">
<div class="form-row edit-group-form-row edit-group-form-row-details">
<div class="form-group">
<label for="edit-group-department">Кафедра</label>
<select id="edit-group-department">
@@ -142,8 +142,8 @@
<option value="">Выберите специальность</option>
</select>
</div>
<div class="form-group" style="display: flex; align-items: flex-end;">
<button type="submit" class="btn btn-md btn-primary" style="width: 100%;">Сохранить</button>
<div class="form-group edit-group-submit">
<button type="submit" class="btn btn-md btn-primary">Сохранить</button>
</div>
</div>
<div class="form-alert" id="edit-group-alert" role="alert"></div>