Files
pulse-signage/src/web/routes/signage/clients/routes.js
T
2026-07-26 20:26:01 +01:00

70 lines
3.0 KiB
JavaScript

module.exports = function registerClientsRoutes(app, deps) {
const pool = deps.pool;
const common = deps.common;
const pages = deps.pages;
const buildDashboardState = deps.buildDashboardState;
const { buildPagination } = require('../../../lib/pagination');
const { sortRows, createSearchMatcher } = require('../../../lib/list-query');
const requirePermission = deps.requirePermission;
const LIST_PAGE_SIZE = 10;
function sortClients(clients, sortKey, sortDirection) {
const normalizedSortKey = String(sortKey || '').trim();
const normalizedDirection = String(sortDirection || '').trim().toLowerCase() === 'desc' ? 'desc' : 'asc';
const accessors = {
client: function (client) { return String(client && (client.client_name || client.name || client.clientId) || '').trim(); },
screen: function (client) { return String(client && (client.screen_name || client.screen_slug) || '').trim(); },
slide: function (client) { return String(client && client.currentSlideTitle || '').trim(); },
ip: function (client) { return String(client && client.clientIp || '').trim(); },
viewport: function (client) {
const viewport = client && client.viewport;
if (!viewport || !viewport.width || !viewport.height) {
return '';
}
return `${Number(viewport.width) || 0}x${Number(viewport.height) || 0}`;
},
connected: function (client) { return String(client && (client.connectedAt || client.lastSeenAt) || '').trim(); }
};
if (!accessors[normalizedSortKey]) {
return Array.isArray(clients) ? clients.slice() : [];
}
return sortRows(clients, function (client) {
return accessors[normalizedSortKey](client);
}, normalizedDirection);
}
app.get('/clients', requirePermission('clients.read'), async function (req, res, next) {
try {
const data = await buildDashboardState(pool);
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 matchesSearch = createSearchMatcher(search, [
'name',
'client_name',
'clientId',
'deviceId',
'slug',
'screen_slug',
'ipAddress',
'status'
]);
const filteredClients = (data.clients || []).filter(matchesSearch);
const sortedClients = sortClients(filteredClients, sort, direction);
const startIndex = (page - 1) * LIST_PAGE_SIZE;
const clients = sortedClients.slice(startIndex, startIndex + LIST_PAGE_SIZE);
res.send(pages.renderConnectedClientsPage({
clients: clients,
pagination: buildPagination(sortedClients.length, page, 'page', { search: search, sort: sort, direction: direction }, LIST_PAGE_SIZE, 'clients', 'Client pages')
}, req.query.message ? String(req.query.message) : '', req.currentUser));
} catch (error) {
next(error);
}
});
};