Release 1.5.16
This commit is contained in:
@@ -135,6 +135,11 @@ module.exports = function registerAdminContentRoutes(app, deps) {
|
||||
return Array.from(usage);
|
||||
}
|
||||
|
||||
async function fetchSlidesByTemplateId(templateId) {
|
||||
const [slides] = await pool.query('SELECT id, thumbnail_path FROM slides WHERE template_id = ? ORDER BY id ASC', [templateId]);
|
||||
return slides;
|
||||
}
|
||||
|
||||
function getRemovedTemplateRegionKeys(existingRegions, nextRegions) {
|
||||
const nextKeys = new Set((Array.isArray(nextRegions) ? nextRegions : []).map((region) => String(region && region.region_key || '').trim()).filter(Boolean));
|
||||
return (Array.isArray(existingRegions) ? existingRegions : [])
|
||||
@@ -171,6 +176,23 @@ module.exports = function registerAdminContentRoutes(app, deps) {
|
||||
});
|
||||
}
|
||||
|
||||
function queueTemplateSlideThumbnailRefresh(templateId) {
|
||||
if (!backgroundTaskQueue || typeof backgroundTaskQueue.enqueueTask !== 'function') {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
return backgroundTaskQueue.enqueueTask({
|
||||
key: 'template-slide-thumbnail:' + Number(templateId),
|
||||
title: 'Refresh slide thumbnails',
|
||||
category: 'slides',
|
||||
taskType: 'template-slide-thumbnail-refresh',
|
||||
payload: {
|
||||
templateId: Number(templateId)
|
||||
},
|
||||
persist: true
|
||||
});
|
||||
}
|
||||
|
||||
async function canvasSizeExists(width, height, ignoreId) {
|
||||
const params = [width, height];
|
||||
let query = 'SELECT COUNT(*) AS count FROM canvas_sizes WHERE width = ? AND height = ?';
|
||||
@@ -524,6 +546,12 @@ module.exports = function registerAdminContentRoutes(app, deps) {
|
||||
previousUploadRefs: existingUploadRefs,
|
||||
nextUploadRefs: nextUploadRefs
|
||||
});
|
||||
const templateSlides = await fetchSlidesByTemplateId(template.id);
|
||||
if (templateSlides.length > 0) {
|
||||
queueTemplateSlideThumbnailRefresh(template.id).catch(function (error) {
|
||||
console.warn('Unable to queue template slide thumbnail refresh:', error);
|
||||
});
|
||||
}
|
||||
await notifyPlayerScreens(affectedScreens, 'refresh');
|
||||
redirectAfterSave(req, res, '/templates/' + template.id + '/edit', {
|
||||
closeUrl: '/templates',
|
||||
|
||||
@@ -147,7 +147,6 @@ module.exports = function registerAdminRbacRoutes(app, deps) {
|
||||
const permissionRows = await rbacData.fetchPermissions(pool);
|
||||
const selectedPermissionKeys = await rbacData.fetchRolePermissionKeys(pool, role.id);
|
||||
const selectedUserIds = await rbacData.fetchRoleUserIds(pool, role.id);
|
||||
const users = await rbacData.fetchUsersWithRoles(pool);
|
||||
return {
|
||||
role: Object.assign({}, role, {
|
||||
permissionKeys: selectedPermissionKeys,
|
||||
@@ -155,7 +154,7 @@ module.exports = function registerAdminRbacRoutes(app, deps) {
|
||||
userCount: Number(role.user_count) || 0
|
||||
}),
|
||||
permissionGroups: buildPermissionGroups(mapPermissionsForView(permissionRows, selectedPermissionKeys)),
|
||||
users: mapUsersForView(users, selectedUserIds)
|
||||
selectedUserIds: selectedUserIds
|
||||
};
|
||||
}
|
||||
|
||||
@@ -251,14 +250,17 @@ module.exports = function registerAdminRbacRoutes(app, deps) {
|
||||
return res.status(404).send('Role not found.');
|
||||
}
|
||||
|
||||
const page = Math.max(1, Math.floor(Number(req.query.page) || 1));
|
||||
const search = common.getSearchQuery(req);
|
||||
const sort = common.getSortQuery(req);
|
||||
const direction = common.getSortDirectionQuery(req);
|
||||
const currentUserId = req.currentUser ? Number(req.currentUser.id) : null;
|
||||
const users = Array.isArray(viewModel.users)
|
||||
? viewModel.users.filter(function (user) {
|
||||
return Number(user && user.id) !== currentUserId;
|
||||
})
|
||||
: [];
|
||||
const data = await rbacData.fetchUsersWithRolesPage(pool, page, LIST_PAGE_SIZE, search, sort, direction, {
|
||||
excludeUserId: currentUserId
|
||||
});
|
||||
const users = mapUsersForView(data.users, viewModel.selectedUserIds);
|
||||
|
||||
res.send(pages.renderRbacEditPage(viewModel.role, req.query.message ? String(req.query.message) : '', req.currentUser, viewModel.permissionGroups, users));
|
||||
res.send(pages.renderRbacEditPage(viewModel.role, req.query.message ? String(req.query.message) : '', req.currentUser, viewModel.permissionGroups, users, buildPagination(data.totalItems, data.currentPage, 'page', { search: search, sort: sort, direction: direction }, LIST_PAGE_SIZE, 'users', 'User pages')));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
|
||||
@@ -91,8 +91,8 @@ function buildQueuePageViewModel(data, message, currentUser) {
|
||||
const tasks = (data && data.tasks) || [];
|
||||
const summary = (data && data.summary) || { counts: {}, total: 0, activeCount: 0 };
|
||||
const canManage = hasAnyPermission(currentUser, ['background-tasks.allow']);
|
||||
const sort = String(data && data.sort || '').trim();
|
||||
const direction = normalizeSortDirection(data && data.direction);
|
||||
const sort = String(data && data.sort || '').trim() || 'started';
|
||||
const direction = normalizeSortDirection(data && data.direction || 'desc');
|
||||
const queryState = {
|
||||
page: parsePageNumber(data && data.page),
|
||||
sourceType: '',
|
||||
@@ -130,7 +130,7 @@ function buildQueuePageViewModel(data, message, currentUser) {
|
||||
return task && task.createdAt;
|
||||
}
|
||||
if (sort === 'started') {
|
||||
return task && task.startedAt;
|
||||
return task && (task.startedAt || '0001-01-01T00:00:00.000Z');
|
||||
}
|
||||
if (sort === 'finished') {
|
||||
return task && task.finishedAt;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { renderView } = require('../../../view');
|
||||
|
||||
module.exports = function renderRbacEditPage(role, message, currentUser, permissionGroups, users) {
|
||||
module.exports = function renderRbacEditPage(role, message, currentUser, permissionGroups, users, pagination) {
|
||||
return renderView('settings/rbac/edit', {
|
||||
title: 'Edit role',
|
||||
active: 'rbac',
|
||||
@@ -9,6 +9,8 @@ module.exports = function renderRbacEditPage(role, message, currentUser, permiss
|
||||
role: role,
|
||||
permissionGroups: permissionGroups || [],
|
||||
users: users || [],
|
||||
pagination: pagination || null,
|
||||
roleEditBasePath: '/rbac/' + Number(role && role.id) + '/edit',
|
||||
scripts: ['js/rbac-permissions.js']
|
||||
});
|
||||
};
|
||||
@@ -36,6 +36,27 @@ function formatDays(daysJson) {
|
||||
return days.map((day) => dayNames[Number(day)] || '').filter(Boolean).join(', ');
|
||||
}
|
||||
|
||||
function normalizeScheduleDaysJson(daysJson) {
|
||||
if (Array.isArray(daysJson)) {
|
||||
return JSON.stringify(daysJson.map((day) => Number(day)).filter((day) => Number.isInteger(day) && day >= 0 && day <= 6));
|
||||
}
|
||||
|
||||
if (!daysJson) {
|
||||
return '[]';
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(daysJson);
|
||||
if (Array.isArray(parsed)) {
|
||||
return JSON.stringify(parsed.map((day) => Number(day)).filter((day) => Number.isInteger(day) && day >= 0 && day <= 6));
|
||||
}
|
||||
} catch (_error) {
|
||||
return JSON.stringify(String(daysJson).split(',').map((day) => Number(day)).filter((day) => Number.isInteger(day) && day >= 0 && day <= 6));
|
||||
}
|
||||
|
||||
return '[]';
|
||||
}
|
||||
|
||||
function scheduleSummary(item) {
|
||||
const mode = String(item.schedule_mode || 'always');
|
||||
if (mode === 'dates') {
|
||||
@@ -160,6 +181,7 @@ module.exports = function renderPlaylistEditPage(playlist, data, message, curren
|
||||
videoDurationSeconds: getVideoDurationSeconds(item),
|
||||
useVideoDuration: Boolean(item.use_video_duration),
|
||||
durationSeconds: getVideoDurationValue(item),
|
||||
schedule_days_json: normalizeScheduleDaysJson(item.schedule_days_json),
|
||||
scheduleSummary: scheduleSummary(item)
|
||||
}));
|
||||
const assignedSlideIds = new Set(playlistSlides.map((item) => item.slide_id));
|
||||
|
||||
Reference in New Issue
Block a user