diff --git a/api/js/etemplate/Et2Date/Et2Date.ts b/api/js/etemplate/Et2Date/Et2Date.ts index ed453cf803..7ccca3e3d2 100644 --- a/api/js/etemplate/Et2Date/Et2Date.ts +++ b/api/js/etemplate/Et2Date/Et2Date.ts @@ -15,7 +15,6 @@ import {dateStyles} from "./DateStyles"; import {Instance} from 'flatpickr/dist/types/instance'; import "flatpickr/dist/plugins/scrollPlugin.js"; import "shortcut-buttons-flatpickr/dist/shortcut-buttons-flatpickr"; -import {holidays} from "./Holidays"; import flatpickr from "flatpickr"; import {egw} from "../../jsapi/egw_global"; import {HTMLElementWithValue} from "@lion/form-core/types/FormControlMixinTypes"; @@ -28,8 +27,6 @@ import shoelace from "../Styles/shoelace"; const textbox = new Et2Textbox(); const button = new Et2ButtonIcon(); -// Request this year's holidays now -holidays(new Date().getFullYear()); // list of existing localizations from node_modules/flatpicker/dist/l10n directory: const l10n = [ @@ -812,15 +809,7 @@ export class Et2Date extends Et2InputWidget(FormControlMixin(LitFlatpickr)) } }.bind(this); - let holiday_list = holidays(f_date.getFullYear()); - if(holiday_list instanceof Promise) - { - holiday_list.then((h) => {set_holiday(h, dayElement);}); - } - else - { - set_holiday(holiday_list, dayElement); - } + egw.holidays(f_date.getFullYear()).then((h) => set_holiday(h, dayElement)); } /** diff --git a/api/js/etemplate/Et2Date/Holidays.ts b/api/js/etemplate/Et2Date/Holidays.ts deleted file mode 100644 index a2f428bae3..0000000000 --- a/api/js/etemplate/Et2Date/Holidays.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Static holiday cache - * access through holidays(year) - */ -import {egw} from "../../jsapi/egw_global"; - -let _holiday_cache = {}; - -/** - * Get a list of holidays for the given year - * - * Returns either a list of holidays indexed by date, in Ymd format: - * {20001225: [{day: 14, month: 2, occurence: 2021, name: "Valentinstag"}]} - * or a promise that resolves with the list. - * - * No need to cache the results, we do it here. - * - * @param year - * @returns Promise<{[key: string]: Array}>|{[key: string]: Array} - */ -export function holidays(year) : Promise<{ [key : string] : Array }> | { [key : string] : Array } -{ - // No country selected causes error, so skip if it's missing - if(!egw || !egw.preference('country', 'common')) - { - return {}; - } - - if(typeof _holiday_cache[year] === 'undefined') - { - // Fetch with json instead of jsonq because there may be more than - // one widget listening for the response by the time it gets back, - // and we can't do that when it's queued. - _holiday_cache[year] = window.fetch( - egw.link('/calendar/holidays.php', {year: year}) - ).then((response) => - { - return _holiday_cache[year] = response.json(); - }); - } - return _holiday_cache[year]; -} diff --git a/api/js/jsapi/egw_calendar.js b/api/js/jsapi/egw_calendar.js index 7f65ac48c7..3e3e0cb858 100644 --- a/api/js/jsapi/egw_calendar.js +++ b/api/js/jsapi/egw_calendar.js @@ -18,10 +18,12 @@ import './egw_core.js'; * @param {string} _app application name object is instanced for * @param {object} _wnd window object is instanced for */ -egw.extend('calendar', egw.MODULE_WND_LOCAL, function(_app, _wnd) +egw.extend('calendar', egw.MODULE_GLOBAL, function (_app, _wnd) { "use strict"; + let _holiday_cache = {}; + /** * transform PHP date/time-format to jQuery date/time-format * @@ -103,7 +105,7 @@ egw.extend('calendar', egw.MODULE_WND_LOCAL, function(_app, _wnd) diff = day === 6 ? 0 : day === 0 ? -1 : -(day + 1); break; case 'Monday': - diff = day === 0 ? -6 : 1-day; + diff = day === 0 ? -6 : 1 - day; break; case 'Sunday': default: @@ -111,6 +113,39 @@ egw.extend('calendar', egw.MODULE_WND_LOCAL, function(_app, _wnd) } d.setUTCDate(d.getUTCDate() + diff); return d; + }, + /** + * Get a list of holidays for the given year + * + * Returns a promise that resolves with a list of holidays indexed by date, in Ymd format: + * {20001225: [{day: 14, month: 2, occurence: 2021, name: "Valentinstag"}]} + * + * No need to cache the results, we do it here. + * + * @param year + * @returns Promise<{[key: string]: Array}> + */ + holidays: function holidays(year) //: Promise<{ [key : string] : Array }> + { + // No country selected causes error, so skip if it's missing + if (!egw || !egw.preference('country', 'common')) + { + return {}; + } + + if (typeof _holiday_cache[year] === 'undefined') + { + // Fetch with json instead of jsonq because there may be more than + // one widget listening for the response by the time it gets back, + // and we can't do that when it's queued. + _holiday_cache[year] = window.fetch( + egw.link('/calendar/holidays.php', {year: year}) + ).then((response) => + { + return _holiday_cache[year] = response.json(); + }); + } + return Promise.resolve(_holiday_cache[year]); } }; }); \ No newline at end of file diff --git a/api/js/jsapi/egw_global.d.ts b/api/js/jsapi/egw_global.d.ts index 010610c03e..502a6a835b 100644 --- a/api/js/jsapi/egw_global.d.ts +++ b/api/js/jsapi/egw_global.d.ts @@ -454,13 +454,27 @@ declare interface IegwGlobal * @return grant object, false if not (yet) loaded and no callback or undefined */ grants(_app : string) /*, _callback, _context)*/ : any; + + /** + * Get a list of holidays for the given year + * + * Returns a promise that resolves with a list of holidays indexed by date, in Ymd format: + * {20001225: [{day: 14, month: 2, occurence: 2021, name: "Valentinstag"}]} + * + * No need to cache the results, we do it here. + * + * @param year + * @returns Promise<{[key: string]: Array}> + */ + holidays(fullYear : number) : Promise<{ [key : string] : Array }>; + /** * Get mime types supported by file editor AND not excluded by user * * @param {string} _mime current mime type * @returns {object|null} returns object of filemanager editor hook */ - file_editor_prefered_mimes(_mime : string) : object|null; + file_editor_prefered_mimes(_mime : string) : object | null; /** * implemented in egw_store.js diff --git a/calendar/js/et2_widget_daycol.ts b/calendar/js/et2_widget_daycol.ts index d7bccf7578..da9d6af42e 100644 --- a/calendar/js/et2_widget_daycol.ts +++ b/calendar/js/et2_widget_daycol.ts @@ -24,7 +24,6 @@ import {et2_no_init} from "../../api/js/etemplate/et2_core_common"; import {egw} from "../../api/js/jsapi/egw_global"; import {egwIsMobile, sprintf} from "../../api/js/egw_action/egw_action_common.js"; import {CalendarApp} from "./app"; -import {holidays} from "../../api/js/etemplate/Et2Date/Holidays"; import {et2_calendar_view} from "./et2_widget_view"; import flatpickr from "flatpickr"; import {formatDate} from "../../api/js/etemplate/Et2Date/Et2Date"; @@ -452,7 +451,7 @@ export class et2_calendar_daycol extends et2_valueWidget implements et2_IDetache ); // Holidays and birthdays - let fetched_holidays = await holidays(this.options.date.substring(0, 4)); + let fetched_holidays = await this.egw().holidays(this.options.date.substring(0, 4)); const holiday_list = []; let holiday_pref = (egw.preference('birthdays_as_events', 'calendar') || []); if(typeof holiday_pref === 'string') @@ -512,12 +511,13 @@ export class et2_calendar_daycol extends et2_valueWidget implements et2_IDetache else { // Show holidays as events on mobile - if(holidays_as_events) + if(holidays_as_events && this.getWidgetById("event_" + escape(fetched_holidays[i].name)) == null) { // Create event var event = et2_createWidget('calendar-event', { id: 'event_' + fetched_holidays[i].name, value: { + row_id: escape(fetched_holidays[i].name), title: fetched_holidays[i].name, whole_day: true, whole_day_on_top: true, diff --git a/calendar/js/et2_widget_planner.ts b/calendar/js/et2_widget_planner.ts index 131de7b271..2b91f56163 100644 --- a/calendar/js/et2_widget_planner.ts +++ b/calendar/js/et2_widget_planner.ts @@ -36,7 +36,6 @@ import {sprintf} from "../../api/js/egw_action/egw_action_common.js"; import {et2_dataview_grid} from "../../api/js/etemplate/et2_dataview_view_grid"; import {et2_selectbox} from "../../api/js/etemplate/et2_widget_selectbox"; import {formatDate, formatTime} from "../../api/js/etemplate/Et2Date/Et2Date"; -import {holidays} from "../../api/js/etemplate/Et2Date/Holidays"; import interact from "@interactjs/interactjs/index"; import type {InteractEvent} from "@interactjs/core/InteractEvent"; @@ -1317,7 +1316,7 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta } // Holidays and birthdays - const fetched = await holidays(date.getUTCFullYear()); + const fetched = await this.egw().holidays(date.getUTCFullYear()); var day_class = ''; // Pass a string rather than the date object, to make sure it doesn't get changed