feat: update language support and enhance API functionality
- Changed the default language in `index.html` from Russian to English, updating the title and button aria-labels for improved accessibility. - Refactored the `buildFetchOptions` function in `api.js` to include an optional external abort signal, enhancing request management. - Updated `fetchDuties` and `fetchCalendarEvents` to support request cancellation using the new abort signal, improving error handling. - Added unit tests for the API functions to ensure proper functionality, including handling of 403 errors and request cancellations. - Enhanced CSS styles for duty markers to improve visual consistency. - Removed unused code and improved the overall structure of the JavaScript files for better maintainability.
This commit is contained in:
@@ -29,6 +29,9 @@ export function calendarEventsByDate(events) {
|
||||
return byDate;
|
||||
}
|
||||
|
||||
/** Max days to iterate per duty; prevents infinite loop on corrupted API data (end_at < start_at). */
|
||||
const MAX_DAYS_PER_DUTY = 366;
|
||||
|
||||
/**
|
||||
* Group duties by local date (start_at/end_at are UTC).
|
||||
* @param {object[]} duties - Duties with start_at, end_at
|
||||
@@ -39,14 +42,17 @@ export function dutiesByDate(duties) {
|
||||
duties.forEach((d) => {
|
||||
const start = new Date(d.start_at);
|
||||
const end = new Date(d.end_at);
|
||||
if (end < start) return;
|
||||
const endLocal = localDateString(end);
|
||||
let t = new Date(start);
|
||||
while (true) {
|
||||
const key = localDateString(t);
|
||||
let cursor = new Date(start);
|
||||
let iterations = 0;
|
||||
while (iterations <= MAX_DAYS_PER_DUTY) {
|
||||
const key = localDateString(cursor);
|
||||
if (!byDate[key]) byDate[key] = [];
|
||||
byDate[key].push(d);
|
||||
if (key === endLocal) break;
|
||||
t.setDate(t.getDate() + 1);
|
||||
cursor.setDate(cursor.getDate() + 1);
|
||||
iterations++;
|
||||
}
|
||||
});
|
||||
return byDate;
|
||||
@@ -104,14 +110,8 @@ export function renderCalendar(
|
||||
start_at: x.start_at,
|
||||
end_at: x.end_at
|
||||
}));
|
||||
cell.setAttribute(
|
||||
"data-day-duties",
|
||||
JSON.stringify(dayPayload).replace(/"/g, """)
|
||||
);
|
||||
cell.setAttribute(
|
||||
"data-day-events",
|
||||
JSON.stringify(eventSummaries).replace(/"/g, """)
|
||||
);
|
||||
cell.setAttribute("data-day-duties", JSON.stringify(dayPayload));
|
||||
cell.setAttribute("data-day-events", JSON.stringify(eventSummaries));
|
||||
}
|
||||
|
||||
const ariaParts = [];
|
||||
|
||||
Reference in New Issue
Block a user