Release 2.16.2
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile, web, pulse-signage-web) (push) Successful in 1m13s
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile.player, player, pulse-signage-player) (push) Successful in 31s

This commit is contained in:
lzstealth committed 2026-10-21 01:38:22 +01:00
1 parent 8ce8228091
commit 49df51d92f
32 files changed
+390 -172

No files matched your search

+18 -1
View File
@@ -92,6 +92,10 @@
toggleButton.className = toggleButton.className.replace(/btn-(danger|success)/g, willEnable ? 'btn-danger' : 'btn-success');
toggleButton.innerHTML = '<i class="bi ' + (willEnable ? 'bi-pause-fill' : 'bi-play-fill') + ' me-1" aria-hidden="true"></i>' + (willEnable ? 'Disable' : 'Enable');
Array.prototype.forEach.call(document.querySelectorAll('[data-source-toggle-owner="' + form.id + '"]'), function (control) {
control.disabled = !willEnable || control.getAttribute('data-source-item-enabled') === 'false';
});
var message = '';
try {
message = new URL(response.url, window.location.href).searchParams.get('message') || '';
@@ -837,17 +841,30 @@
return;
}
refreshButton.disabled = true;
var refreshTargetSelector = refreshButton.getAttribute('data-manual-refresh-target');
fetch(refreshButton.getAttribute('data-manual-refresh-url'), {
method: 'POST',
credentials: 'same-origin',
headers: { 'X-Requested-With': 'XMLHttpRequest' }
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': refreshTargetSelector ? 'application/json' : 'text/html, application/xhtml+xml'
}
}).then(function (response) {
if (!response.ok) {
throw new Error('Refresh failed');
}
if (refreshTargetSelector) {
return response.json().then(function (payload) {
if (!payload.taskId || !payload.stateUrl) throw new Error('Unable to track refresh task.');
watchRefreshTask(payload.stateUrl, payload.taskId, refreshTargetSelector, refreshSequence);
refreshButton.disabled = false;
showToast(payload.message || 'Refresh queued. Unsaved changes are kept.', 'success');
});
}
window.location.assign(response.url);
}).catch(function () {
refreshButton.disabled = false;
if (refreshTargetSelector) showToast('Unable to refresh API response. Unsaved changes are kept.', 'danger');
});
return;
}
+1 -11
View File
@@ -34,17 +34,7 @@
}
function getApiItems(response, itemsPath) {
var selected = itemsPath ? getPath(response, itemsPath) : response;
if (Array.isArray(selected)) {
return selected;
}
if (Array.isArray(response)) {
return response;
}
if (response && Array.isArray(response.items)) return response.items;
if (response && Array.isArray(response.results)) return response.results;
if (response && Array.isArray(response.data)) return response.data;
return response && typeof response === 'object' ? [response] : [];
return root.placeholderUtils.resolveApiItems(response, itemsPath);
}
function normalizeRows(rows, mapping) {
+1 -24
View File
@@ -51,30 +51,7 @@
var source = getSourceById(sourceId, sources);
var responseJson = source && source.responseJson && typeof source.responseJson === 'object' ? source.responseJson : null;
var itemsPath = getSourceItemsPath(source, itemsPathOverride);
if (itemsPath !== undefined && itemsPath !== null && itemsPath !== '') {
var current = responseJson;
String(itemsPath).split('.').forEach(function (segment) {
if (current === undefined || current === null) {
current = '';
return;
}
current = current[segment];
});
return Array.isArray(current) ? current : [];
}
if (Array.isArray(responseJson)) {
return responseJson;
}
if (responseJson && Array.isArray(responseJson.items)) {
return responseJson.items;
}
if (responseJson && Array.isArray(responseJson.results)) {
return responseJson.results;
}
if (responseJson && Array.isArray(responseJson.data)) {
return responseJson.data;
}
return responseJson ? [responseJson] : [];
return placeholderUtils.resolveApiItems(responseJson, itemsPath);
}
function getItemCount(sourceId, sources, itemsPathOverride) {
+25 -5
View File
@@ -1,7 +1,12 @@
// Shared placeholder parsing and resolution helpers for browser-rendered API content.
(function () {
var root = window;
(function (root, factory) {
if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.placeholderUtils = factory();
}
}(typeof window !== 'undefined' ? window : globalThis, function () {
var transformPattern = /^([a-z_][a-z0-9_]*)\((.*)\)$/i;
var monthNamesShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
@@ -48,6 +53,20 @@
return segments;
}
function resolveApiItems(value, itemsPath) {
var path = String(itemsPath || '').trim().replace(/\[([0-9]+)\]/g, '.$1');
if (path) {
var selected = resolvePath(value, path);
if (Array.isArray(selected)) return selected;
return selected && typeof selected === 'object' ? [selected] : [];
}
if (Array.isArray(value)) return value;
if (value && Array.isArray(value.items)) return value.items;
if (value && Array.isArray(value.results)) return value.results;
if (value && Array.isArray(value.data)) return value.data;
return value && typeof value === 'object' ? [value] : [];
}
function parsePlaceholderExpression(expression) {
var raw = String(expression || '').trim();
var segments = raw ? splitExpressionSegments(raw) : [];
@@ -402,7 +421,7 @@
}
function renderProgressPlaceholder(value, expression) {
var parsed = parsePlaceholderExpression(expression);
var parsed = parsePlaceholderExpression(String(expression || '').replace(/<\/?(?:span|strong|em|b|i|u|s|small|sub|sup|font)\b[^>]*>/gi, ''));
var transform = parsed.transforms.find(function (candidate) {
return candidate && candidate.name === 'progress';
});
@@ -582,8 +601,9 @@
return output;
}
root.placeholderUtils = {
return {
resolvePath: resolvePath,
resolveApiItems: resolveApiItems,
parsePlaceholderExpression: parsePlaceholderExpression,
resolvePlaceholderExpression: resolvePlaceholderExpression,
isImagePlaceholderExpression: isImagePlaceholderExpression,
@@ -593,4 +613,4 @@
formatPlaceholderValue: formatPlaceholderValue,
collectPlaceholderFieldPaths: collectPlaceholderFieldPaths
};
}());
}));
+1 -24
View File
@@ -365,30 +365,7 @@ export function createSlideFormRegionHelpers(options) {
var responseJson = source && source.responseJson && typeof source.responseJson === 'object' ? source.responseJson : null;
var itemsPath = getApiSourceItemsPath(source, itemsPathOverride);
if (itemsPath !== undefined && itemsPath !== null && itemsPath !== '') {
var current = responseJson;
String(itemsPath).split('.').forEach(function (segment) {
if (current === undefined || current === null) {
current = '';
return;
}
current = current[segment];
});
return Array.isArray(current) ? current : [];
}
if (Array.isArray(responseJson)) {
return responseJson;
}
if (responseJson && Array.isArray(responseJson.items)) {
return responseJson.items;
}
if (responseJson && Array.isArray(responseJson.results)) {
return responseJson.results;
}
if (responseJson && Array.isArray(responseJson.data)) {
return responseJson.data;
}
return responseJson ? [responseJson] : [];
return window.placeholderUtils.resolveApiItems(responseJson, itemsPath);
}
function getApiItemCount(sourceId, itemsPathOverride) {