diff options
Diffstat (limited to 'resources/assets/javascripts/lib/holiday.ts')
| -rw-r--r-- | resources/assets/javascripts/lib/holiday.ts | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/resources/assets/javascripts/lib/holiday.ts b/resources/assets/javascripts/lib/holiday.ts new file mode 100644 index 0000000..2363eb1 --- /dev/null +++ b/resources/assets/javascripts/lib/holiday.ts @@ -0,0 +1,254 @@ +import {jsonapi} from "./jsonapi"; +import {datetime} from "./datetime"; + +/** + * The Holiday class represents a holiday in Stud.IP + */ +class Holiday +{ + /** + * The day of the holiday. + */ + day: Date; + + /** + * The name of the holiday. + */ + name: string; + + /** + * Whether the holiday is an official holiday (true) or not (false). + * The latter means that it can be part of a vacation period. + */ + official: boolean; + + constructor(day: Date, name: string, official: boolean = true) { + this.day = day; + this.name = name; + this.official = official; + } +} + + +/** + * The HolidayCache class handles retrieving and caching holidays and vacations. + */ +class HolidayCache +{ + holiday_cache: Map<number, Array<Holiday>>; + vacation_cache: Map<number, Array<Holiday>>; + + /** + * The constructor has code to load cached holidays and vacations from the session storage. + */ + constructor() { + //Attempt to restore the cache from the session: + const holiday_cache_str = sessionStorage.getItem('fullcalendar_holidays'); + this.holiday_cache = new Map<number, Array<Holiday>>(); + if (holiday_cache_str != null) { + for (const [year, raw_array] of Object.entries(JSON.parse(holiday_cache_str))) { + const holidays: Array<Holiday> = []; + if (Array.isArray(raw_array)) { + for (const raw_holiday of raw_array) { + holidays.push( + new Holiday(new Date(raw_holiday.day), raw_holiday.name, raw_holiday.official) + ); + } + this.holiday_cache.set(parseInt(year), holidays); + } + } + } + + const vacation_cache_str = sessionStorage.getItem('fullcalendar_vacations'); + this.vacation_cache = new Map<number, Array<Holiday>>(); + if (vacation_cache_str != null) { + for (const [year, raw_array] of Object.entries(JSON.parse(vacation_cache_str))) { + const vacations: Array<Holiday> = []; + if (Array.isArray(raw_array)) { + for (const raw_vacation of raw_array) { + vacations.push( + new Holiday(new Date(raw_vacation.day), raw_vacation.name, raw_vacation.official) + ); + } + this.vacation_cache.set(parseInt(year), vacations); + } + } + } + } + + /** + * Loads the holidays of a year and stores them in the cache. + * + * @param year The year for which to load holidays. + */ + loadHolidays(year: number) : void { + const existing_cache = this.holiday_cache.get(year); + if (existing_cache) { + return; + } + + jsonapi.withPromises().GET('holidays', { + data: { 'filter[year]': year } + }).then(response => { + if (!response) { + return; + } + const events: Array<Holiday> = []; + for (const [date, data] of Object.entries(response)) { + const day = new Date(date); + events.push(new Holiday(day, data.holiday, data.mandatory)); + } + + this.holiday_cache.set(year, events); + //Update the session storage item: + sessionStorage.setItem('fullcalendar_holidays', JSON.stringify(Object.fromEntries(this.holiday_cache))); + }); + } + + /** + * Loads the vacation days of a year and stores them in the cache. + * + * @param year The year for which to load vacations. + */ + loadVacations(year: number): void { + const existing_cache = this.vacation_cache.get(year); + if (existing_cache) { + return; + } + jsonapi.withPromises().get('vacations', { + data: {'filter[year]': year} + }).then(response => { + if (!response) { + return; + } + const events: Array<Holiday> = []; + for (const vacation_data of Object.values(response)) { + for (let i = parseInt(vacation_data.start); i < parseInt(vacation_data.end); i += 86400) { + const day = new Date(i * 1000); + events.push(new Holiday(day, vacation_data.name, false)); + } + } + + this.vacation_cache.set(year, events); + //Update the session storage item: + sessionStorage.setItem('fullcalendar_vacations', JSON.stringify(Object.fromEntries(this.vacation_cache))); + }); + } + + /** + * Returns a vacation day from the cache. + * + * @param date The day of the vacation. + * + * @returns Holiday|null If a vacation exists on the specified day, a Holiday object + * for it is returned. Otherwise, null is returned. + */ + getVacation(date: Date) : Holiday|null { + const year_vacation_cache = this.vacation_cache.get(date.getFullYear()); + if (!year_vacation_cache) { + return null; + } + for (const vacation of year_vacation_cache) { + if (datetime.getISODate(date) === datetime.getISODate(vacation.day)) { + //A vacation day has been found. + return vacation; + } + } + return null; + } + + /** + * Checks if there is a vacation day on the specified date. + * + * @param date The date to check. + * + * @returns boolean True, if the specified day is a vacation day. + * Otherwise, false is returned. + */ + isVacation(date: Date) { + return this.getVacation(date) !== null; + } + + /** + * Returns the name of the vacation day on the specified date. + * + * @param date The date for which to get the vacation name. + * + * @returns string The name of the vacation, if any. + * If there is no vacation day on the specified date, the string is empty. + */ + getVacationName(date: Date) { + const vacation = this.getVacation(date); + if (vacation) { + return vacation.name; + } + return ''; + } + + /** + * Returns a holiday / vacation day from the cache. + * + * @param date The date of the holiday. + * + * @param regard_vacations Whether to regard vacations in addition to holidays (true) + * or to just regard holidays (false). Defaults to false. + * + * @returns Holiday|null If a holiday can be found, it is returned. Otherwise, + * null is returned. + */ + getHoliday(date: Date, regard_vacations: boolean = false): Holiday|null { + //Check if an entry for the date exists in the holiday or the vacation list: + const year_holiday_cache = this.holiday_cache.get(date.getFullYear()); + if (!year_holiday_cache) { + return null; + } + for (const holiday of year_holiday_cache) { + if (datetime.getISODate(date) === datetime.getISODate(holiday.day)) { + //A holiday has been found. + return holiday; + } + } + if (regard_vacations) { + return this.getVacation(date); + } + return null; + } + + /** + * Checks if there is a holiday on the specified date. + * + * @param date The date to check. + * + * @param regard_vacations Whether to regard vacations in addition to holidays (true) + * or to just regard holidays (false). Defaults to false. + * + * @returns boolean True, if the specified day is a holiday / vacation day. + * Otherwise, false is returned. + */ + isHoliday(date: Date, regard_vacations: boolean = false) : boolean { + return this.getHoliday(date, regard_vacations) !== null; + } + + /** + * Returns the name of the holiday on the specified date. + * + * @param date The date for which to get the holiday name. + * + * @param regard_vacations Whether to regard vacations in addition to holidays (true) + * or to just regard holidays (false). Defaults to false. + * + * @returns string The name of the holiday / vacation, if any. + * If there is no holiday on the specified date, the string is empty. + */ + getHolidayName(date: Date, regard_vacations: boolean = false) : string { + const holiday = this.getHoliday(date, regard_vacations); + if (holiday) { + return holiday.name; + } + return ''; + } +} + + +export {Holiday, HolidayCache}; +export const holiday_cache: HolidayCache = new HolidayCache(); |
