Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { semesterView, addDays, weekday, weekIndexOf } from "../shared/weeks.js";
|
||||
import { lessonKey, subgroupsOf } from "../shared/lessons.js";
|
||||
import { occurrence, peopleAndRooms, roomsOn } from "./directory.js";
|
||||
import { apiError } from "./errors.js";
|
||||
|
||||
const MAX_DAYS = 62;
|
||||
// A whole semester with its session fits easily; the cap only guards against abuse.
|
||||
@@ -38,22 +39,35 @@ function lessonOut(lesson, group, people, date, status, calendar) {
|
||||
*/
|
||||
export function timetable({ file, schedule, calendar, group, from, days, range, today }) {
|
||||
if (!schedule.groups.includes(group)) {
|
||||
const error = new Error(`В документе нет группы ${group}.`);
|
||||
error.status = 404;
|
||||
throw error;
|
||||
throw apiError(404, "group_not_found", `В документе нет группы ${group}.`);
|
||||
}
|
||||
let count = Math.min(Math.max(Number(days) || 7, 1), MAX_DAYS);
|
||||
const lessons = schedule.lessons.filter((l) => l.groups.includes(group));
|
||||
// A session schedule printed with a date on every day needs no week table: its own dates
|
||||
// say when each lesson takes place, even in a year the table no longer covers.
|
||||
const sessionDates = lessons.every((l) => l.date || l.dates?.length)
|
||||
? lessons.flatMap((l) => (l.date ? [l.date] : l.dates)).sort()
|
||||
: [];
|
||||
const session = sessionDates.length
|
||||
? {
|
||||
id: `session-${sessionDates[0]}`,
|
||||
label: schedule.period || "Сессия",
|
||||
start: sessionDates[0],
|
||||
end: sessionDates.at(-1),
|
||||
}
|
||||
: null;
|
||||
// range=semester: every day of the semester `today` falls in, so a client can keep
|
||||
// the whole term offline. Without a known semester it keeps the plain from/days window.
|
||||
// the whole term offline; a session schedule keeps its own span. Without either it
|
||||
// keeps the plain from/days window.
|
||||
if (range === "semester") {
|
||||
const current = semesterView(calendar, schedule, today || from);
|
||||
if (current) {
|
||||
from = current.semester.start;
|
||||
const span = Math.round((Date.parse(current.semester.end) - Date.parse(from)) / DAY_MS) + 1;
|
||||
count = Math.min(Math.max(span, 1), MAX_SEMESTER_DAYS);
|
||||
const span = current?.semester || session;
|
||||
if (span) {
|
||||
from = span.start;
|
||||
const length = Math.round((Date.parse(span.end) - Date.parse(from)) / DAY_MS) + 1;
|
||||
count = Math.min(Math.max(length, 1), MAX_SEMESTER_DAYS);
|
||||
}
|
||||
}
|
||||
const lessons = schedule.lessons.filter((l) => l.groups.includes(group));
|
||||
const entries = lessons.map((lesson) => ({
|
||||
doc: { id: file.id, schedule },
|
||||
lesson,
|
||||
@@ -66,7 +80,7 @@ export function timetable({ file, schedule, calendar, group, from, days, range,
|
||||
const date = addDays(from, i);
|
||||
const week = view ? view.weeks[weekIndexOf(view, date)] || null : null;
|
||||
const dayLessons = [];
|
||||
if (view)
|
||||
if (view || session)
|
||||
for (const entry of entries) {
|
||||
const status = occurrence(entry, date, calendar, views);
|
||||
if (status === "yes" || status === "maybe")
|
||||
@@ -99,8 +113,8 @@ export function timetable({ file, schedule, calendar, group, from, days, range,
|
||||
modified: file.modified || schedule.source.modified || null,
|
||||
},
|
||||
period: schedule.period,
|
||||
semester: view?.semester || null,
|
||||
note: view
|
||||
semester: view?.semester || session,
|
||||
note: view || session
|
||||
? null
|
||||
: "Семестр этого расписания не найден в таблице недель: даты не рассчитаны, смотрите строки Word (weekly).",
|
||||
subgroups: subgroupsOf(schedule, group),
|
||||
|
||||
Reference in New Issue
Block a user