{% load i18n %} /* exported showAlertOrCache, showCachedAlerts, startNotificationWatcher, stopNotificationWatcher, openNotificationPanel, closeNotificationPanel, */ /* * Add a cached alert message to sesion storage */ function addCachedAlert(message, options={}) { var alerts = sessionStorage.getItem('inventree-alerts'); if (alerts) { alerts = JSON.parse(alerts); } else { alerts = []; } alerts.push({ message: message, style: options.style || 'success', icon: options.icon, }); sessionStorage.setItem('inventree-alerts', JSON.stringify(alerts)); } /* * Remove all cached alert messages */ function clearCachedAlerts() { sessionStorage.removeItem('inventree-alerts'); } /* * Display an alert, or cache to display on reload */ function showAlertOrCache(message, cache, options={}) { if (cache) { addCachedAlert(message, options); } else { showMessage(message, options); } } /* * Display cached alert messages when loading a page */ function showCachedAlerts() { var alerts = JSON.parse(sessionStorage.getItem('inventree-alerts')) || []; alerts.forEach(function(alert) { showMessage( alert.message, { style: alert.style || 'success', icon: alert.icon, } ); }); clearCachedAlerts(); } /* * Display an alert message at the top of the screen. * The message will contain a "close" button, * and also dismiss automatically after a certain amount of time. * * arguments: * - message: Text / HTML content to display * * options: * - style: alert style e.g. 'success' / 'warning' * - timeout: Time (in milliseconds) after which the message will be dismissed */ function showMessage(message, options={}) { var style = options.style || 'info'; var timeout = options.timeout || 5000; var target = options.target || $('#alerts'); var details = ''; if (options.details) { details = `

${options.details}

`; } // Hacky function to get the next available ID var id = 1; while ($(`#alert-${id}`).exists()) { id++; } var icon = ''; if (options.icon) { icon = ``; } // Construct the alert var html = ` `; target.append(html); // Remove the alert automatically after a specified period of time $(`#alert-${id}`).delay(timeout).slideUp(200, function() { $(this).alert(close); }); } var notificationWatcher = null; // reference for the notificationWatcher /** * start the regular notification checks **/ function startNotificationWatcher() { notificationCheck(force=true); notificationWatcher = setInterval(notificationCheck, 1000); } /** * stop the regular notification checks **/ function stopNotificationWatcher() { clearInterval(notificationWatcher); } var notificationUpdateTic = 0; /** * The notification checker is initiated when the document is loaded. It checks if there are unread notifications * if unread messages exist the notification indicator is updated * * options: * - force: set true to force an update now (if you got in focus for example) **/ function notificationCheck(force = false) { notificationUpdateTic = notificationUpdateTic + 1; // refresh if forced or // if in focus and was not refreshed in the last 5 seconds if (force || (document.hasFocus() && notificationUpdateTic >= 5)) { notificationUpdateTic = 0; inventreeGet( '/api/notifications/', { read: false, }, { success: function(response) { updateNotificationIndicator(response.length); }, error: function(xhr) { console.warn('Could not access server: /api/notifications'); } } ); } } /** * handles read / unread buttons and UI rebuilding * * arguments: * - btn: element that got clicked / fired the event -> must contain pk and target as attributes * * options: * - panel_caller: this button was clicked in the notification panel **/ function updateNotificationReadState(btn, panel_caller=false) { var url = `/api/notifications/${btn.attr('pk')}/${btn.attr('target')}/`; inventreePut(url, {}, { method: 'POST', success: function() { // update the notification tables if they were declared if (window.updateNotifications) { window.updateNotifications(); } // update current notification count var count = parseInt($('#notification-counter').html()); if (btn.attr('target') == 'read') { count = count - 1; } else { count = count + 1; } // update notification indicator now updateNotificationIndicator(count); // remove notification if called from notification panel if (panel_caller) { btn.parent().parent().remove(); } } }); }; /** * Returns the html for a read / unread button * * arguments: * - pk: primary key of the notification * - state: current state of the notification (read / unread) -> just pass what you were handed by the api * - small: should the button be small **/ function getReadEditButton(pk, state, small=false) { if (state) { var bReadText = '{% trans "Mark as unread" %}'; var bReadIcon = 'fas fa-bookmark icon-red'; var bReadTarget = 'unread'; } else { var bReadText = '{% trans "Mark as read" %}'; var bReadIcon = 'far fa-bookmark icon-green'; var bReadTarget = 'read'; } var style = (small) ? 'btn-sm ' : ''; return ``; } /** * fills the notification panel when opened **/ function openNotificationPanel() { var html = ''; var center_ref = '#notification-center'; inventreeGet( '/api/notifications/', { read: false, ordering: '-creation', }, { success: function(response) { if (response.length == 0) { html = `

{% trans "No unread notifications" %}

`; } else { // build up items response.forEach(function(item, index) { html += '
  • '; html += `
    `; html += `${item.name}`; html += getReadEditButton(item.pk, item.read, true); html += `
    `; if (item.target) { var link_text = `${item.target.name}`; if (item.target.link) { link_text = `${link_text}`; } html += link_text; } html += '
    '; html += `${item.age_human}`; html += '
  • '; }); // package up html = ``; } // set html $(center_ref).html(html); } } ); $(center_ref).on('click', '.notification-read', function() { updateNotificationReadState($(this), true); }); } /** * clears the notification panel when closed **/ function closeNotificationPanel() { $('#notification-center').html(`

    {% trans "Notifications will load here" %}

    `); } /** * updates the notification counter **/ function updateNotificationIndicator(count) { // reset update Ticker -> safe some API bandwidth notificationUpdateTic = 0; if (count == 0) { $('#notification-alert').addClass('d-none'); } else { $('#notification-alert').removeClass('d-none'); } $('#notification-counter').html(count); }