/** * Main Javascript file * * @author Giancarlo Voci * @date 27/06/2018 * @time 17:42 */ import $ from '../../shared/jquery.js'; import './common'; import { AjaxReq } from './OMGUtils'; const CUSTOM_NOTIFICATION_CODE = 0x4000; const FOCUS_INTERVAL_MS = 1000; const NOTIFICATION_REFRESH_INTERVAL_MS = 3000; const DELETE_ALL_NOTIFICATION_LINK = '#'; /** * Adds a notification item to the notification menu. * * @param {{caption: string, code: number, count: number, link: string|null, timestamp: string}} notification Notification data. * @returns {JQuery} Notification menu item. * @sideEffects Registers a click handler. */ function createNotificationItem(notification) { return $('', { class: 'dropdown-item', href: '#' }) .text(`[${notification.timestamp}] ${notification.caption}`) .append($('', { class: 'ms-1 badge bg-danger', text: notification.count })) .on('click', event => { event.preventDefault(); deleteNotification(notification.link, notification.code); }); } /** * Renders the notifications visible to the user. * * @param {Array} notifications Notifications returned by the API. * @returns {void} * @sideEffects Updates the notification menu. */ function renderNotifications(notifications) { const visibleNotifications = notifications.filter( notification => notification.code <= CUSTOM_NOTIFICATION_CODE, ); const notificationArea = $('#notification_area').empty(); if (visibleNotifications.length === 0) { $('#notification_area_button').addClass('disabled'); $('#sysmsgnum').empty(); return; } visibleNotifications.forEach(notification => notificationArea.append(createNotificationItem(notification))); notificationArea.append( $('', { id: 'notification_area_deleteall', class: 'dropdown-item text-center', href: '#', text: 'Cancella tutto' }) .on('click', event => { event.preventDefault(); deleteNotification(DELETE_ALL_NOTIFICATION_LINK, 0); }), ); $('#notification_area_button').removeClass('disabled'); $('#sysmsgnum').text(visibleNotifications.length); } /** * Retrieves and renders the current system notifications. * * @returns {void} * @sideEffects Performs a network request and updates the notification menu. */ function refreshNotificationArea() { AjaxReq(`${BASEURL}/api.system.getserverstatus`, { method: 'GET' }).fetchPromise() .then(data => renderNotifications(data.notify)) .catch(error => console.error('Unable to refresh system notifications.', error)); } /** * Deletes one notification and optionally follows its link. * * @param {string|null} link Link associated with the notification. * @param {number} code Notification code. * @returns {void} * @sideEffects Performs a network request and may navigate the browser. */ function deleteNotification(link, code) { fetch(`${BASEURL}/api.system.removenotification/${code}`, { method: 'POST' }) .then(response => { if (!response.ok) { return Promise.reject(response); } if (link && link !== DELETE_ALL_NOTIFICATION_LINK) { window.location.href = `${BASEURL}${link}`; } }) .catch(error => { console.error('Unable to delete the notification.', { code, error }); alert('NotificationDelete error'); }); } /** * Enables confirmation prompts for elements that require explicit user approval. * * @returns {void} * @sideEffects Registers click handlers. */ function setupConfirmationDialog() { $('.requestconfirm').on('click', function (event) { if (!confirm($(this).data('confirmtext'))) { event.preventDefault(); } }); } /** * Keeps elements marked with forcefocus focused. * * @returns {void} * @sideEffects Starts an interval timer. */ function startFocusEnforcement() { setInterval(() => $('[forcefocus]').focus(), FOCUS_INTERVAL_MS); } /** * Initializes frontend interactions after the document is ready. * * @returns {void} * @sideEffects Registers UI handlers and starts polling timers. */ function initializeFrontend() { setupConfirmationDialog(); refreshNotificationArea(); startFocusEnforcement(); $('body').on('submit', 'form', function () { $('body').focus(); $('form input,form select').prop('readonly', true); this.submit(); return false; }); setInterval(refreshNotificationArea, NOTIFICATION_REFRESH_INTERVAL_MS); window.NotificationDelete = deleteNotification; } document.addEventListener('DOMContentLoaded', initializeFrontend);