Release 1.5.3

This commit is contained in:
2026-07-25 15:11:41 +01:00
parent 9ee938fd2f
commit 0e89892c94
89 changed files with 7660 additions and 542 deletions
+5 -2
View File
@@ -6,7 +6,9 @@ module.exports = function renderCanvasSizesPage(data, message, currentUser) {
name: size.name,
width: size.width,
height: size.height,
templateCount: (data.templates || []).filter((template) => Number(template.canvas_size_id) === Number(size.id)).length
templateCount: size.template_count !== undefined
? Number(size.template_count) || 0
: (data.templates || []).filter((template) => Number(template.canvas_size_id) === Number(size.id)).length
}));
return renderView('canvas-sizes/list', {
@@ -14,6 +16,7 @@ module.exports = function renderCanvasSizesPage(data, message, currentUser) {
active: 'canvas-sizes',
message: message,
currentUser: currentUser || null,
canvasSizes: canvasSizes
canvasSizes: canvasSizes,
pagination: data.pagination || null
});
};
@@ -2,12 +2,19 @@ module.exports = function registerCanvasSizeRoutes(app, deps) {
const pages = deps.pages;
const common = deps.common;
const pool = deps.pool;
const { buildPagination } = require('../../../lib/pagination');
const requirePermission = deps.requirePermission;
const LIST_PAGE_SIZE = 10;
app.get('/canvas-sizes', requirePermission('canvas-sizes.read'), async function (req, res, next) {
try {
const data = await common.fetchCanvasSizesData(pool);
res.send(pages.renderCanvasSizesPage(data, req.query.message ? String(req.query.message) : '', req.currentUser));
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
const data = await common.fetchCanvasSizesPage(pool, page, LIST_PAGE_SIZE);
res.send(pages.renderCanvasSizesPage({
canvasSizes: data.canvasSizes || [],
pagination: buildPagination(data.totalItems, data.currentPage, 'page', {}, LIST_PAGE_SIZE, 'canvas sizes', 'Canvas size pages')
}, req.query.message ? String(req.query.message) : '', req.currentUser));
} catch (error) {
next(error);
}
+2 -1
View File
@@ -7,6 +7,7 @@ module.exports = function renderConnectedClientsPage(data, message, currentUser)
message: message,
currentUser: currentUser || null,
scripts: ['js/dashboard/dashboard-page.js'],
clients: data.clients || []
clients: data.clients || [],
pagination: data.pagination || null
});
};
+11 -1
View File
@@ -2,12 +2,22 @@ module.exports = function registerClientsRoutes(app, deps) {
const pool = deps.pool;
const pages = deps.pages;
const buildDashboardState = deps.buildDashboardState;
const { buildPagination } = require('../../../lib/pagination');
const requirePermission = deps.requirePermission;
const LIST_PAGE_SIZE = 10;
app.get('/clients', requirePermission('clients.read'), async function (req, res, next) {
try {
const data = await buildDashboardState(pool);
res.send(pages.renderConnectedClientsPage(data, req.query.message ? String(req.query.message) : '', req.currentUser));
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
const totalItems = Array.isArray(data.clients) ? data.clients.length : 0;
const startIndex = (page - 1) * LIST_PAGE_SIZE;
const clients = (data.clients || []).slice(startIndex, startIndex + LIST_PAGE_SIZE);
res.send(pages.renderConnectedClientsPage({
clients: clients,
pagination: buildPagination(totalItems, page, 'page', {}, LIST_PAGE_SIZE, 'clients', 'Client pages')
}, req.query.message ? String(req.query.message) : '', req.currentUser));
} catch (error) {
next(error);
}
+2 -1
View File
@@ -5,7 +5,8 @@ module.exports = function renderPlaylistFormPage(message, currentUser) {
title: 'Create playlist',
active: 'playlists',
playlist: {
fade_between_slides: false
fade_between_slides: false,
skip_unavailable_rtmp: false
},
message: message,
currentUser: currentUser || null
+2 -1
View File
@@ -102,6 +102,7 @@ module.exports = function renderPlaylistEditPage(playlist, data, message, curren
currentUser: currentUser || null,
playlist: playlist,
playlistFadeBetweenSlides: Boolean(playlist.fade_between_slides),
playlistSkipUnavailableRtmp: Boolean(playlist.skip_unavailable_rtmp),
playlistSlides: playlistSlides,
slides: data.slides || [],
hasSlides: (data.slides || []).length > 0,
@@ -110,6 +111,6 @@ module.exports = function renderPlaylistEditPage(playlist, data, message, curren
selectableSlides: selectableSlides,
playlistCanvasSignature: playlistCanvasSignature,
playlistCanvasMismatch: playlistCanvasMismatch,
scripts: ['js/vendor/sortable.min.js', 'js/playlists/playlist-schedule.js']
scripts: ['js/lib/modal.js', 'js/vendor/sortable.min.js', 'js/playlists/playlist-schedule.js']
});
};
+5 -3
View File
@@ -1,9 +1,10 @@
const { renderView } = require('../../../view');
module.exports = function renderPlaylistsPage(data, message, currentUser) {
const playlistSlides = data.playlistSlides || [];
const playlists = (data.playlists || []).map((playlist) => {
const slideCount = playlistSlides.filter((item) => item.playlist_id === playlist.id).length;
const slideCount = playlist.slide_count !== undefined
? Number(playlist.slide_count) || 0
: (data.playlistSlides || []).filter((item) => item.playlist_id === playlist.id).length;
return Object.assign({}, playlist, {
slideCount: slideCount,
slideCountIsOne: slideCount === 1
@@ -15,7 +16,8 @@ module.exports = function renderPlaylistsPage(data, message, currentUser) {
active: 'playlists',
message: message,
currentUser: currentUser || null,
playlists: playlists
playlists: playlists,
pagination: data.pagination || null
});
};
+10 -2
View File
@@ -2,8 +2,11 @@ module.exports = function registerPlaylistsRoutes(app, deps) {
const pool = deps.pool;
const common = deps.common;
const pages = deps.pages;
const { buildPagination } = require('../../../lib/pagination');
const requirePermission = deps.requirePermission;
const LIST_PAGE_SIZE = 10;
function requireQueryPermission(readPermissionKey, editPermissionKey) {
return function (req, res, next) {
const permissionKey = req.query && req.query.edit ? editPermissionKey : readPermissionKey;
@@ -13,15 +16,20 @@ module.exports = function registerPlaylistsRoutes(app, deps) {
app.get('/playlists', requireQueryPermission('playlists.read', 'playlists.update'), async function (req, res, next) {
try {
const data = await common.fetchAdminData(pool);
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
if (req.query.edit) {
const data = await common.fetchAdminData(pool);
const playlist = await common.fetchPlaylistById(pool, Number(req.query.edit));
if (!playlist) {
return res.status(404).send('Playlist not found');
}
return res.send(pages.renderPlaylistEditPage(playlist, data, req.query.message ? String(req.query.message) : '', req.currentUser));
}
res.send(pages.renderPlaylistsPage(data, req.query.message ? String(req.query.message) : '', req.currentUser));
const data = await common.fetchPlaylistsPage(pool, page, LIST_PAGE_SIZE);
res.send(pages.renderPlaylistsPage({
playlists: data.playlists || [],
pagination: buildPagination(data.totalItems, data.currentPage, 'page', {}, LIST_PAGE_SIZE, 'playlists', 'Playlist pages')
}, req.query.message ? String(req.query.message) : '', req.currentUser));
} catch (error) {
next(error);
}
@@ -74,6 +74,6 @@ module.exports = function renderPlaylistSlideConfigPage(playlist, playlistSlide,
...day,
checked: selectedDays.has(day.value)
})),
scripts: ['js/playlists/playlist-schedule.js']
scripts: ['js/lib/modal.js', 'js/playlists/playlist-schedule.js']
});
};
+2 -1
View File
@@ -6,7 +6,8 @@ module.exports = function renderScreensPage(data, message, currentUser) {
active: 'screens',
message: message,
currentUser: currentUser || null,
screens: data.screens || []
screens: data.screens || [],
pagination: data.pagination || null
});
};
+10 -2
View File
@@ -3,8 +3,11 @@ module.exports = function registerScreensRoutes(app, deps) {
const common = deps.common;
const pages = deps.pages;
const buildDashboardState = deps.buildDashboardState;
const { buildPagination } = require('../../../lib/pagination');
const requirePermission = deps.requirePermission;
const LIST_PAGE_SIZE = 10;
function requireQueryPermission(readPermissionKey, editPermissionKey) {
return function (req, res, next) {
const permissionKey = req.query && req.query.edit ? editPermissionKey : readPermissionKey;
@@ -14,8 +17,8 @@ module.exports = function registerScreensRoutes(app, deps) {
app.get('/screens', requireQueryPermission('screens.read', 'screens.update'), async function (req, res, next) {
try {
const data = await buildDashboardState(pool);
if (req.query.edit) {
const data = await buildDashboardState(pool);
const screen = await common.fetchScreenById(pool, Number(req.query.edit));
if (!screen) {
return res.status(404).send('Screen not found');
@@ -23,7 +26,12 @@ module.exports = function registerScreensRoutes(app, deps) {
const editData = await common.fetchScreenEditData(pool);
return res.send(pages.renderScreenEditPage(screen, editData, req.query.message ? String(req.query.message) : '', req.currentUser));
}
res.send(pages.renderScreensPage(data, req.query.message ? String(req.query.message) : '', req.currentUser));
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
const data = await common.fetchScreensPage(pool, page, LIST_PAGE_SIZE);
res.send(pages.renderScreensPage({
screens: data.screens || [],
pagination: buildPagination(data.totalItems, data.currentPage, 'page', {}, LIST_PAGE_SIZE, 'screens', 'Screen pages')
}, req.query.message ? String(req.query.message) : '', req.currentUser));
} catch (error) {
next(error);
}
+2 -1
View File
@@ -6,7 +6,8 @@ module.exports = function renderSlidesPage(data, message, currentUser) {
active: 'slides',
message: message,
currentUser: currentUser || null,
slides: data.slides || []
slides: data.slides || [],
pagination: data.pagination || null
});
};
+9 -2
View File
@@ -2,12 +2,19 @@ module.exports = function registerSlidesRoutes(app, deps) {
const pages = deps.pages;
const common = deps.common;
const pool = deps.pool;
const { buildPagination } = require('../../../lib/pagination');
const requirePermission = deps.requirePermission;
const LIST_PAGE_SIZE = 10;
app.get('/slides', requirePermission('slides.read'), async function (req, res, next) {
try {
const data = await common.fetchAdminData(pool);
res.send(pages.renderSlidesPage(data, req.query.message ? String(req.query.message) : '', req.currentUser));
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
const data = await common.fetchSlidesPage(pool, page, LIST_PAGE_SIZE);
res.send(pages.renderSlidesPage({
slides: data.slides || [],
pagination: buildPagination(data.totalItems, data.currentPage, 'page', {}, LIST_PAGE_SIZE, 'slides', 'Slide pages')
}, req.query.message ? String(req.query.message) : '', req.currentUser));
} catch (error) {
next(error);
}
+1 -1
View File
@@ -50,6 +50,6 @@ module.exports = function renderTemplateFormPage(template, mode, message, canvas
currentUser: currentUser || null,
template: current,
canvasSizes: canvasSizes || [],
scripts: ['js/templates/template-designer-utils.js', 'js/templates/template-designer.js']
scripts: ['js/lib/modal.js', 'js/templates/template-designer-utils.js', 'js/templates/template-designer.js']
});
};
+5 -2
View File
@@ -6,7 +6,9 @@ module.exports = function renderTemplatesPage(data, message, currentUser) {
name: template.name,
canvas_size_width: template.canvas_size_width,
canvas_size_height: template.canvas_size_height,
regionCount: (data.templateRegions || []).filter((region) => region.template_id === template.id).length
regionCount: template.region_count !== undefined
? Number(template.region_count) || 0
: (data.templateRegions || []).filter((region) => region.template_id === template.id).length
}));
return renderView('templates/list', {
@@ -14,6 +16,7 @@ module.exports = function renderTemplatesPage(data, message, currentUser) {
active: 'templates',
message: message,
currentUser: currentUser || null,
templates: templates
templates: templates,
pagination: data.pagination || null
});
};
+9 -2
View File
@@ -2,12 +2,19 @@ module.exports = function registerTemplatesRoutes(app, deps) {
const pages = deps.pages;
const common = deps.common;
const pool = deps.pool;
const { buildPagination } = require('../../../lib/pagination');
const requirePermission = deps.requirePermission;
const LIST_PAGE_SIZE = 10;
app.get('/templates', requirePermission('templates.read'), async function (req, res, next) {
try {
const data = await common.fetchTemplatesData(pool);
res.send(pages.renderTemplatesPage(data, req.query.message ? String(req.query.message) : '', req.currentUser));
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
const data = await common.fetchTemplatesPage(pool, page, LIST_PAGE_SIZE);
res.send(pages.renderTemplatesPage({
templates: data.templates || [],
pagination: buildPagination(data.totalItems, data.currentPage, 'page', {}, LIST_PAGE_SIZE, 'templates', 'Template pages')
}, req.query.message ? String(req.query.message) : '', req.currentUser));
} catch (error) {
next(error);
}