92 lines
3.7 KiB
JavaScript
92 lines
3.7 KiB
JavaScript
// Connected client route registration and dashboard wiring.
|
|
|
|
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 { compareSortValues, createSearchMatcher, getComparableSortValue } = require('../../../lib/list-query');
|
|
const requirePermission = deps.requirePermission;
|
|
|
|
const LIST_PAGE_SIZE = 25;
|
|
|
|
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(); }
|
|
};
|
|
|
|
function compareValues(leftValue, rightValue) {
|
|
return compareSortValues(getComparableSortValue(leftValue), getComparableSortValue(rightValue));
|
|
}
|
|
|
|
const sortKeys = accessors[normalizedSortKey]
|
|
? [normalizedSortKey]
|
|
: ['client'];
|
|
|
|
if (sortKeys[0] === 'client') {
|
|
sortKeys.push('ip');
|
|
} else if (sortKeys[0] === 'ip') {
|
|
sortKeys.push('client');
|
|
}
|
|
|
|
return (Array.isArray(clients) ? clients.slice() : []).sort(function (leftClient, rightClient) {
|
|
for (let index = 0; index < sortKeys.length; index += 1) {
|
|
const sortKeyName = sortKeys[index];
|
|
const comparison = compareValues(accessors[sortKeyName](leftClient), accessors[sortKeyName](rightClient));
|
|
|
|
if (comparison !== 0) {
|
|
return index === 0 && normalizedDirection === 'desc' ? comparison * -1 : comparison;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
});
|
|
}
|
|
|
|
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({
|
|
screens: data.screens || [],
|
|
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);
|
|
}
|
|
});
|
|
};
|
|
|