Files
pulse-signage/src/web/public/js/settings/background-tasks.js
T
2026-07-25 18:24:12 +01:00

247 lines
7.0 KiB
JavaScript

(function () {
var REFRESH_INTERVAL_MS = 10000;
var pathname = window.location.pathname.replace(/\/$/, '');
var stateNode = document.getElementById('background-tasks-state');
var currentVersion = stateNode ? String(stateNode.getAttribute('data-state-version') || '') : '';
if (pathname !== '/settings/background-tasks') {
return;
}
function getPageUrl(href) {
try {
return new URL(href, window.location.href);
} catch (_error) {
return null;
}
}
function updateLocalDateTimes(root) {
if (typeof window.initLocalDateTimes === 'function') {
window.initLocalDateTimes(root || document);
}
}
function replaceSectionFromDocument(sectionName, responseDocument) {
var currentCard = document.querySelector('[data-pagination-card="' + sectionName + '"]');
var nextCard = responseDocument.querySelector('[data-pagination-card="' + sectionName + '"]');
if (!currentCard || !nextCard) {
return false;
}
currentCard.outerHTML = nextCard.outerHTML;
updateLocalDateTimes(document.querySelector('[data-pagination-card="' + sectionName + '"]'));
return true;
}
function replaceSummaryFromDocument(responseDocument) {
var currentSummary = document.getElementById('background-tasks-summary');
var nextSummary = responseDocument.getElementById('background-tasks-summary');
if (!currentSummary || !nextSummary) {
return false;
}
currentSummary.outerHTML = nextSummary.outerHTML;
return true;
}
function replaceFiltersFromDocument(responseDocument) {
var currentFilters = document.getElementById('background-tasks-filters');
var nextFilters = responseDocument.getElementById('background-tasks-filters');
if (!currentFilters || !nextFilters) {
return false;
}
currentFilters.outerHTML = nextFilters.outerHTML;
return true;
}
function replaceStateFromDocument(responseDocument) {
var currentState = document.getElementById('background-tasks-state');
var nextState = responseDocument.getElementById('background-tasks-state');
if (!currentState || !nextState) {
return false;
}
currentState.outerHTML = nextState.outerHTML;
stateNode = document.getElementById('background-tasks-state');
currentVersion = stateNode ? String(stateNode.getAttribute('data-state-version') || '') : currentVersion;
return true;
}
function applyPageResponse(responseDocument, sectionNames) {
var updated = false;
if (replaceStateFromDocument(responseDocument)) {
updated = true;
}
if (replaceSummaryFromDocument(responseDocument)) {
updated = true;
}
if (replaceFiltersFromDocument(responseDocument)) {
updated = true;
}
sectionNames.forEach(function (sectionName) {
if (replaceSectionFromDocument(sectionName, responseDocument)) {
updated = true;
}
});
return updated;
}
function loadPage(nextUrl, options) {
var url = getPageUrl(nextUrl);
var sectionNames = options && options.sectionNames ? options.sectionNames : [];
var replaceHistory = Boolean(options && options.replaceHistory);
if (!url) {
return;
}
fetch(url.toString(), {
method: 'GET',
headers: {
'Accept': 'text/html, application/xhtml+xml',
'X-Requested-With': 'XMLHttpRequest'
},
credentials: 'same-origin',
cache: 'no-store'
}).then(function (response) {
if (!response.ok) {
throw new Error('Unable to load background tasks page.');
}
return response.text();
}).then(function (text) {
var responseDocument = new DOMParser().parseFromString(text || '', 'text/html');
if (!applyPageResponse(responseDocument, sectionNames.length ? sectionNames : ['tasks', 'recurring'])) {
return;
}
if (replaceHistory) {
window.history.replaceState({}, document.title, url.pathname + url.search + url.hash);
} else {
window.history.pushState({}, document.title, url.pathname + url.search + url.hash);
}
}).catch(function (_error) {
window.location.assign(url.pathname + url.search + url.hash);
});
}
function stripMessageParameter() {
try {
var url = new URL(window.location.href);
if (!url.searchParams.has('message')) {
return;
}
url.searchParams.delete('message');
window.history.replaceState({}, document.title, url.pathname + (url.search ? url.search : '') + url.hash);
} catch (_error) {
// Ignore URL cleanup failures.
}
}
function findPaginationLink(target) {
if (!target || !target.closest) {
return null;
}
var link = target.closest('.pagination .page-link');
if (!link) {
return null;
}
var href = String(link.getAttribute('href') || '').trim();
if (!href || href === '#') {
return null;
}
var card = link.closest('[data-pagination-card]');
if (!card) {
return null;
}
return {
href: href,
sectionName: String(card.getAttribute('data-pagination-card') || '').trim()
};
}
function initPaginationNavigation() {
document.addEventListener('click', function (event) {
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
return;
}
var paginationLink = findPaginationLink(event.target);
if (paginationLink && paginationLink.sectionName) {
var currentUrl = getPageUrl(window.location.href);
var nextUrl = getPageUrl(paginationLink.href);
if (!currentUrl || !nextUrl) {
return;
}
if (currentUrl.pathname === nextUrl.pathname && currentUrl.search === nextUrl.search && currentUrl.hash === nextUrl.hash) {
event.preventDefault();
return;
}
event.preventDefault();
loadPage(nextUrl.toString(), { sectionNames: [paginationLink.sectionName] });
return;
}
}, true);
window.addEventListener('popstate', function () {
loadPage(window.location.href, { replaceHistory: true });
});
}
function refreshPage() {
if (document.visibilityState !== 'visible') {
return;
}
fetch('/settings/background-tasks/state', {
method: 'GET',
headers: {
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
credentials: 'same-origin',
cache: 'no-store'
}).then(function (response) {
if (!response.ok) {
return null;
}
return response.json();
}).then(function (payload) {
if (!payload || !payload.version) {
return;
}
var nextVersion = String(payload.version || '');
if (!currentVersion) {
currentVersion = nextVersion;
return;
}
if (nextVersion !== currentVersion) {
window.location.reload();
}
}).catch(function (_error) {
// Ignore refresh probe errors and try again on the next interval.
});
}
stripMessageParameter();
initPaginationNavigation();
window.setInterval(refreshPage, REFRESH_INTERVAL_MS);
}());