merge: объединить изменения команды в Redesign
This commit is contained in:
43
frontend/admin/js/schedule-period.js
Normal file
43
frontend/admin/js/schedule-period.js
Normal file
@@ -0,0 +1,43 @@
|
||||
export function preferredScheduleSemester(semesters, date) {
|
||||
const items = (semesters || [])
|
||||
.filter(semester => semester?.startDate && semester?.endDate);
|
||||
const current = items.find(semester =>
|
||||
semester.startDate <= date && semester.endDate >= date
|
||||
);
|
||||
if (current) return current;
|
||||
|
||||
const upcoming = items
|
||||
.filter(semester => semester.startDate > date)
|
||||
.sort((first, second) => first.startDate.localeCompare(second.startDate));
|
||||
if (upcoming.length) return upcoming[0];
|
||||
|
||||
return items
|
||||
.filter(semester => semester.endDate < date)
|
||||
.sort((first, second) => second.endDate.localeCompare(first.endDate))[0] || null;
|
||||
}
|
||||
|
||||
export function defaultSchedulePeriod(semesters, date, durationDays = 14) {
|
||||
const semester = preferredScheduleSemester(semesters, date);
|
||||
const startDate = semester && (date < semester.startDate || date > semester.endDate)
|
||||
? semester.startDate
|
||||
: date;
|
||||
const calculatedEnd = addIsoDays(startDate, Math.max(1, durationDays) - 1);
|
||||
return {
|
||||
semester,
|
||||
startDate,
|
||||
endDate: semester && calculatedEnd > semester.endDate
|
||||
? semester.endDate
|
||||
: calculatedEnd
|
||||
};
|
||||
}
|
||||
|
||||
function addIsoDays(value, days) {
|
||||
const [year, month, day] = String(value).split('-').map(Number);
|
||||
const date = new Date(year, month - 1, day);
|
||||
date.setDate(date.getDate() + days);
|
||||
return [
|
||||
date.getFullYear(),
|
||||
String(date.getMonth() + 1).padStart(2, '0'),
|
||||
String(date.getDate()).padStart(2, '0')
|
||||
].join('-');
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { api, getSession } from '../api.js';
|
||||
import { escapeHtml, formatLocalDate, showAlert, hideAlert } from '../utils.js';
|
||||
import { defaultSchedulePeriod } from '../schedule-period.js';
|
||||
|
||||
const ROLE_DEPARTMENT = 'DEPARTMENT';
|
||||
|
||||
@@ -72,6 +73,7 @@ export async function initDepartmentWorkspace() {
|
||||
departmentField.hidden = true;
|
||||
departmentSelect.value = userDepartmentId || '';
|
||||
}
|
||||
await selectDefaultWorkloadPeriod(startInput, endInput);
|
||||
await loadAllTeachers();
|
||||
renderImportRows([{ code: '', name: '' }]);
|
||||
await loadWorkspace();
|
||||
@@ -475,6 +477,20 @@ export async function initDepartmentWorkspace() {
|
||||
}
|
||||
}
|
||||
|
||||
async function selectDefaultWorkloadPeriod(startInput, endInput) {
|
||||
try {
|
||||
const semesters = await api.get('/api/schedule/semesters');
|
||||
const period = defaultSchedulePeriod(
|
||||
semesters,
|
||||
formatLocalDate(new Date())
|
||||
);
|
||||
startInput.value = period.startDate;
|
||||
endInput.value = period.endDate;
|
||||
} catch (_error) {
|
||||
// Текущий диапазон остаётся безопасным fallback, если справочник семестров недоступен.
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDepartments(role, userDepartmentId) {
|
||||
const departments = await api.get('/api/departments');
|
||||
fillSelect('department-workspace-department', departments, item => item.id, item => item.departmentName, 'Выберите кафедру');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { api, getSession } from '../api.js';
|
||||
import { escapeHtml, showAlert, hideAlert } from '../utils.js';
|
||||
import { preferredScheduleSemester } from '../schedule-period.js';
|
||||
import { canEditScheduleOverrides, createScheduleOverridePanel } from './schedule-override-panel.js';
|
||||
|
||||
const ROLE_DEPARTMENT = 'DEPARTMENT';
|
||||
@@ -321,17 +322,7 @@ export async function initScheduleView() {
|
||||
|
||||
function buildSectionContext(target) {
|
||||
const selectedGroupId = target === TARGET_GROUPS ? normalizeId(valueOf('schedule-view-group')) : '';
|
||||
const selectedDepartmentId = role === ROLE_DEPARTMENT
|
||||
? userDepartmentId
|
||||
: (target === TARGET_DEPARTMENTS ? normalizeId(valueOf('schedule-view-department')) : '');
|
||||
const allowedGroupIds = new Set();
|
||||
if (selectedGroupId) {
|
||||
allowedGroupIds.add(selectedGroupId);
|
||||
} else if (selectedDepartmentId) {
|
||||
state.dictionaries.groups
|
||||
.filter(group => String(group.departmentId) === String(selectedDepartmentId))
|
||||
.forEach(group => allowedGroupIds.add(String(group.id)));
|
||||
}
|
||||
const allowedGroupIds = allowedGroupIdsForScheduleTarget(target, selectedGroupId);
|
||||
return {
|
||||
selectedGroupId,
|
||||
selectedGroupName: selectedGroupId ? groupNameById(selectedGroupId) : '',
|
||||
@@ -905,8 +896,11 @@ export async function initScheduleView() {
|
||||
|
||||
function selectCurrentSemester() {
|
||||
if (!semesterSelect) return;
|
||||
const defaultSemester = findDefaultSemester(state.dictionaries.semesters, dateInput.value);
|
||||
semesterSelect.value = defaultSemester ? String(defaultSemester.id) : '';
|
||||
const preferredSemester = preferredScheduleSemester(
|
||||
state.dictionaries.semesters,
|
||||
dateInput.value
|
||||
);
|
||||
semesterSelect.value = preferredSemester ? String(preferredSemester.id) : '';
|
||||
synchronizeDateWithSemester();
|
||||
updatePeriodLabel();
|
||||
}
|
||||
@@ -1064,6 +1058,12 @@ function buildScheduleSections(lessons, splitType, context) {
|
||||
.sort((a, b) => naturalCompare(a.title, b.title));
|
||||
}
|
||||
|
||||
export function allowedGroupIdsForScheduleTarget(target, selectedGroupId) {
|
||||
return target === TARGET_GROUPS && selectedGroupId
|
||||
? new Set([String(selectedGroupId)])
|
||||
: new Set();
|
||||
}
|
||||
|
||||
function splitEntitiesForLesson(lesson, splitType, context) {
|
||||
if (splitType === TARGET_TEACHERS) {
|
||||
return [singleEntity('teacher', lesson.teacherId, lesson.teacherName, 'Преподаватель не указан')];
|
||||
@@ -1211,11 +1211,6 @@ export function findSemesterForDate(semesters, date) {
|
||||
return (semesters || []).find(semester => dateWithinSemester(date, semester)) || null;
|
||||
}
|
||||
|
||||
export function findDefaultSemester(semesters, date) {
|
||||
const availableSemesters = semesters || [];
|
||||
return findSemesterForDate(availableSemesters, date) || availableSemesters[0] || null;
|
||||
}
|
||||
|
||||
export function scheduleRangeForSemester(selectedDate, semester) {
|
||||
if (semester?.startDate && semester?.endDate) {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user