Release v2.2.0
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
// Background tasks settings page renderer.
|
||||
|
||||
const { renderView } = require('../../view');
|
||||
const { hasAnyPermission } = require('../../../rbac');
|
||||
const { buildPagination, buildQueryString } = require('../../lib/pagination');
|
||||
const { parsePageNumber, normalizeSortDirection, sortRows, createSearchMatcher } = require('../../lib/list-query');
|
||||
|
||||
const TASKS_PER_PAGE = 10;
|
||||
const TASKS_PER_PAGE = 25;
|
||||
const QUEUE_PAGE_URL = '/settings/tasks-background';
|
||||
const SCHEDULED_PAGE_URL = '/settings/tasks-scheduled';
|
||||
|
||||
@@ -91,7 +93,7 @@ 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() || 'started';
|
||||
const sort = String(data && data.sort || '').trim() || 'queued';
|
||||
const direction = normalizeSortDirection(data && data.direction || 'desc');
|
||||
const queryState = {
|
||||
page: parsePageNumber(data && data.page),
|
||||
@@ -188,6 +190,7 @@ function buildQueuePageViewModel(data, message, currentUser) {
|
||||
return renderView('settings/tasks-background/index', {
|
||||
title: 'Background tasks',
|
||||
active: 'background-tasks',
|
||||
bodyClass: 'background-tasks-page',
|
||||
message: message,
|
||||
currentUser: currentUser || null,
|
||||
scripts: ['js/settings/background-tasks.js'],
|
||||
@@ -211,7 +214,7 @@ function buildScheduledPageViewModel(data, message, currentUser) {
|
||||
const summary = (data && data.summary) || { counts: {}, total: 0, activeCount: 0, scheduledCount: 0 };
|
||||
const canManage = hasAnyPermission(currentUser, ['scheduled-tasks.allow']);
|
||||
const search = String(data && data.search || '').trim();
|
||||
const sort = String(data && data.sort || '').trim();
|
||||
const sort = String(data && data.sort || '').trim() || 'task';
|
||||
const direction = normalizeSortDirection(data && data.direction);
|
||||
const filteredRecurringTasks = recurringTasks.filter(function (task) {
|
||||
return taskMatchesSearch(search, [
|
||||
@@ -249,7 +252,7 @@ function buildScheduledPageViewModel(data, message, currentUser) {
|
||||
return String(value || '').trim();
|
||||
}).join(' ');
|
||||
}
|
||||
return task && task.nextRunAt;
|
||||
return task && task.title;
|
||||
}, direction);
|
||||
|
||||
return renderView('settings/tasks-scheduled/index', {
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
// Settings route registration for the background tasks page.
|
||||
|
||||
const { hasAnyPermission } = require('../../../rbac');
|
||||
|
||||
function requireSettingsAccess() {
|
||||
function redirectToLogin(res, setAuthMessageCookie) {
|
||||
if (typeof setAuthMessageCookie === 'function') {
|
||||
setAuthMessageCookie(res, 'Please sign in to continue.');
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
function requireSettingsAccess(setAuthMessageCookie) {
|
||||
return function (req, res, next) {
|
||||
if (!req.currentUser) {
|
||||
return res.redirect('/login?message=' + encodeURIComponent('Please sign in to continue.'));
|
||||
return redirectToLogin(res, setAuthMessageCookie);
|
||||
}
|
||||
|
||||
if (hasAnyPermission(req.currentUser, ['background-tasks.read', 'background-tasks.allow'])) {
|
||||
@@ -17,10 +28,10 @@ function requireSettingsAccess() {
|
||||
};
|
||||
}
|
||||
|
||||
function requireScheduledSettingsAccess() {
|
||||
function requireScheduledSettingsAccess(setAuthMessageCookie) {
|
||||
return function (req, res, next) {
|
||||
if (!req.currentUser) {
|
||||
return res.redirect('/login?message=' + encodeURIComponent('Please sign in to continue.'));
|
||||
return redirectToLogin(res, setAuthMessageCookie);
|
||||
}
|
||||
|
||||
if (hasAnyPermission(req.currentUser, ['scheduled-tasks.read', 'scheduled-tasks.allow'])) {
|
||||
@@ -34,32 +45,41 @@ function requireScheduledSettingsAccess() {
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function registerAdminSettingsRoutes(app, deps) {
|
||||
module.exports = function registerSettingsRoutes(app, deps) {
|
||||
const pages = deps.pages;
|
||||
const backgroundTaskQueue = deps.backgroundTaskQueue;
|
||||
const setAuthMessageCookie = deps.setAuthMessageCookie;
|
||||
|
||||
if (!pages || !backgroundTaskQueue) {
|
||||
throw new Error('registerAdminSettingsRoutes requires pages and backgroundTaskQueue.');
|
||||
throw new Error('registerSettingsRoutes requires pages and backgroundTaskQueue.');
|
||||
}
|
||||
|
||||
app.get('/settings/tasks-background', requireSettingsAccess(), function (req, res) {
|
||||
const tasks = backgroundTaskQueue.listTasks();
|
||||
const recurringTasks = backgroundTaskQueue.listRecurringTasks();
|
||||
const summary = backgroundTaskQueue.getSummary();
|
||||
res.send(pages.renderBackgroundTasksPage({ tasks: tasks, recurringTasks: recurringTasks, summary: summary, page: req.query.page, recurringPage: req.query.recurringPage, search: req.query.search, sort: req.query.sort, direction: req.query.direction }, req.query.message ? String(req.query.message) : '', req.currentUser));
|
||||
app.get('/settings/tasks-background', requireSettingsAccess(setAuthMessageCookie), async function (req, res, next) {
|
||||
try {
|
||||
const tasks = await backgroundTaskQueue.listTasks();
|
||||
const recurringTasks = await backgroundTaskQueue.listRecurringTasks();
|
||||
const summary = await backgroundTaskQueue.getSummary();
|
||||
res.send(pages.renderBackgroundTasksPage({ tasks: tasks, recurringTasks: recurringTasks, summary: summary, page: req.query.page, recurringPage: req.query.recurringPage, search: req.query.search, sort: req.query.sort, direction: req.query.direction }, req.query.message ? String(req.query.message) : '', req.currentUser));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/settings/tasks-scheduled', requireScheduledSettingsAccess(), function (req, res) {
|
||||
const tasks = backgroundTaskQueue.listTasks();
|
||||
const recurringTasks = backgroundTaskQueue.listRecurringTasks();
|
||||
const summary = backgroundTaskQueue.getSummary();
|
||||
res.send(pages.renderBackgroundTasksScheduledPage({ tasks: tasks, recurringTasks: recurringTasks, summary: summary, page: req.query.page, recurringPage: req.query.recurringPage, search: req.query.search, sort: req.query.sort, direction: req.query.direction }, req.query.message ? String(req.query.message) : '', req.currentUser));
|
||||
app.get('/settings/tasks-scheduled', requireScheduledSettingsAccess(setAuthMessageCookie), async function (req, res, next) {
|
||||
try {
|
||||
const tasks = await backgroundTaskQueue.listTasks();
|
||||
const recurringTasks = await backgroundTaskQueue.listRecurringTasks();
|
||||
const summary = await backgroundTaskQueue.getSummary();
|
||||
res.send(pages.renderBackgroundTasksScheduledPage({ tasks: tasks, recurringTasks: recurringTasks, summary: summary, page: req.query.page, recurringPage: req.query.recurringPage, search: req.query.search, sort: req.query.sort, direction: req.query.direction }, req.query.message ? String(req.query.message) : '', req.currentUser));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
function requireSettingsManageAccess() {
|
||||
return function (req, res, next) {
|
||||
if (!req.currentUser) {
|
||||
return res.redirect('/login?message=' + encodeURIComponent('Please sign in to continue.'));
|
||||
return redirectToLogin(res, setAuthMessageCookie);
|
||||
}
|
||||
|
||||
if (hasAnyPermission(req.currentUser, ['background-tasks.allow'])) {
|
||||
@@ -75,7 +95,7 @@ module.exports = function registerAdminSettingsRoutes(app, deps) {
|
||||
|
||||
function requireRecurringTaskAccess(req, res, next) {
|
||||
if (!req.currentUser) {
|
||||
return res.redirect('/login?message=' + encodeURIComponent('Please sign in to continue.'));
|
||||
return redirectToLogin(res, setAuthMessageCookie);
|
||||
}
|
||||
|
||||
if (!hasAnyPermission(req.currentUser, ['scheduled-tasks.allow'])) {
|
||||
@@ -88,23 +108,39 @@ module.exports = function registerAdminSettingsRoutes(app, deps) {
|
||||
return next();
|
||||
}
|
||||
|
||||
app.post('/settings/tasks-background/clear-finished', requireSettingsManageAccess(), function (req, res) {
|
||||
const removedCount = backgroundTaskQueue.clearFinishedTasks();
|
||||
res.redirect('/settings/tasks-background?message=' + encodeURIComponent(removedCount ? 'Cleared ' + removedCount + ' finished task' + (removedCount === 1 ? '' : 's') + '.' : 'No finished tasks to clear.'));
|
||||
app.post('/settings/tasks-background/clear-finished', requireSettingsManageAccess(), async function (req, res, next) {
|
||||
try {
|
||||
const removedCount = await backgroundTaskQueue.clearFinishedTasks();
|
||||
res.redirect('/settings/tasks-background?message=' + encodeURIComponent(removedCount ? 'Cleared ' + removedCount + ' finished task' + (removedCount === 1 ? '' : 's') + '.' : 'No finished tasks to clear.'));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/settings/tasks-background/:id/cancel', requireSettingsManageAccess(), function (req, res) {
|
||||
const canceled = backgroundTaskQueue.cancelTask(Number(req.params.id));
|
||||
res.redirect('/settings/tasks-background?message=' + encodeURIComponent(canceled ? 'Task canceled.' : 'Unable to cancel that task.'));
|
||||
app.post('/settings/tasks-background/:id/cancel', requireSettingsManageAccess(), async function (req, res, next) {
|
||||
try {
|
||||
const canceled = await backgroundTaskQueue.cancelTask(Number(req.params.id));
|
||||
res.redirect('/settings/tasks-background?message=' + encodeURIComponent(canceled ? 'Task canceled.' : 'Unable to cancel that task.'));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/settings/tasks-background/:id/retry', requireSettingsManageAccess(), function (req, res) {
|
||||
const retriedTask = backgroundTaskQueue.retryTask(Number(req.params.id));
|
||||
res.redirect('/settings/tasks-background?message=' + encodeURIComponent(retriedTask ? 'Task requeued.' : 'Unable to retry that task.'));
|
||||
app.post('/settings/tasks-background/:id/retry', requireSettingsManageAccess(), async function (req, res, next) {
|
||||
try {
|
||||
const retriedTask = await backgroundTaskQueue.retryTask(Number(req.params.id));
|
||||
res.redirect('/settings/tasks-background?message=' + encodeURIComponent(retriedTask ? 'Task requeued.' : 'Unable to retry that task.'));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/settings/tasks-scheduled/recurring/:key/run', requireRecurringTaskAccess, function (req, res) {
|
||||
const ran = backgroundTaskQueue.runRecurringTask(String(req.params.key || '').trim());
|
||||
res.redirect('/settings/tasks-scheduled?message=' + encodeURIComponent(ran ? 'Scheduled refresh run queued.' : 'Unable to run that scheduled refresh.'));
|
||||
app.post('/settings/tasks-scheduled/recurring/:key/run', requireRecurringTaskAccess, async function (req, res, next) {
|
||||
try {
|
||||
const ran = await backgroundTaskQueue.runRecurringTask(String(req.params.key || '').trim());
|
||||
res.redirect('/settings/tasks-scheduled?message=' + encodeURIComponent(ran ? 'Scheduled refresh run queued.' : 'Unable to run that scheduled refresh.'));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
// Settings route registration for managed fonts.
|
||||
|
||||
const fs = require('fs');
|
||||
const { hasAnyPermission } = require('../../../rbac');
|
||||
const fontLibrary = require('../../lib/media/font-library');
|
||||
|
||||
function normalizeFontFamilyName(value) {
|
||||
return String(value || '').replace(/\s+/g, ' ').trim().toLowerCase();
|
||||
}
|
||||
|
||||
async function fetchUsedFontFamilies(pool, fonts) {
|
||||
const usedFamilies = new Set();
|
||||
|
||||
for (let i = 0; i < (Array.isArray(fonts) ? fonts.length : 0); i += 1) {
|
||||
const family = normalizeFontFamilyName(fonts[i] && (fonts[i].family || fonts[i].name));
|
||||
if (!family) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const [rows] = await pool.query(
|
||||
'SELECT COUNT(*) AS match_count FROM c_slides WHERE LOCATE(LOWER(?), LOWER(COALESCE(content_json, ""))) > 0',
|
||||
[family]
|
||||
);
|
||||
if (Number(rows && rows[0] && rows[0].match_count) > 0) {
|
||||
usedFamilies.add(family);
|
||||
}
|
||||
}
|
||||
|
||||
return usedFamilies;
|
||||
}
|
||||
|
||||
async function isFontUsed(pool, family) {
|
||||
const normalizedFamily = normalizeFontFamilyName(family);
|
||||
if (!normalizedFamily) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const [rows] = await pool.query(
|
||||
'SELECT COUNT(*) AS match_count FROM c_slides WHERE LOCATE(LOWER(?), LOWER(COALESCE(content_json, ""))) > 0',
|
||||
[normalizedFamily]
|
||||
);
|
||||
|
||||
return Number(rows && rows[0] && rows[0].match_count) > 0;
|
||||
}
|
||||
|
||||
function redirectToLogin(res, setAuthMessageCookie) {
|
||||
if (typeof setAuthMessageCookie === 'function') {
|
||||
setAuthMessageCookie(res, 'Please sign in to continue.');
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
function requireFontsAccess(setAuthMessageCookie) {
|
||||
return function (req, res, next) {
|
||||
if (!req.currentUser) {
|
||||
return redirectToLogin(res, setAuthMessageCookie);
|
||||
}
|
||||
|
||||
if (hasAnyPermission(req.currentUser, ['fonts.read', 'fonts.create', 'fonts.delete'])) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const error = new Error('You do not have permission to access this area.');
|
||||
error.statusCode = 403;
|
||||
error.expose = true;
|
||||
next(error);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function registerFontRoutes(app, deps) {
|
||||
const pool = deps.pool;
|
||||
const pages = deps.pages;
|
||||
const upload = deps.upload;
|
||||
const uploadDir = deps.uploadDir;
|
||||
const backgroundTaskQueue = deps.backgroundTaskQueue;
|
||||
const setAuthMessageCookie = deps.setAuthMessageCookie;
|
||||
|
||||
if (!pool || !pages || !upload || !uploadDir) {
|
||||
throw new Error('registerFontRoutes requires pool, pages, upload, and uploadDir.');
|
||||
}
|
||||
|
||||
app.get('/settings/fonts', requireFontsAccess(setAuthMessageCookie), async function (req, res, next) {
|
||||
try {
|
||||
const library = fontLibrary.loadFontLibrary(uploadDir);
|
||||
const usedFamilies = await fetchUsedFontFamilies(pool, library.fonts);
|
||||
const fonts = library.fonts.map(function (font) {
|
||||
const family = normalizeFontFamilyName(font.family || font.name);
|
||||
return Object.assign({}, font, {
|
||||
inUse: usedFamilies.has(family)
|
||||
});
|
||||
});
|
||||
res.send(pages.renderFontsPage({
|
||||
fonts: fonts,
|
||||
stylesheetHref: library.stylesheetHref
|
||||
}, req.query.message ? String(req.query.message) : '', req.currentUser));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/settings/fonts', requireFontsAccess(setAuthMessageCookie), upload.single('font_file'), async function (req, res, next) {
|
||||
try {
|
||||
if (!req.file) {
|
||||
return res.status(400).send('No font file was uploaded.');
|
||||
}
|
||||
|
||||
const result = await fontLibrary.addFontFile(uploadDir, req.file, String(req.body && req.body.font_family || '').trim());
|
||||
if (backgroundTaskQueue && typeof backgroundTaskQueue.enqueueTask === 'function') {
|
||||
await backgroundTaskQueue.enqueueTask({
|
||||
key: `font-sync:${result && result.font && result.font.id ? result.font.id : Date.now()}`,
|
||||
title: 'Font sync',
|
||||
category: 'fonts',
|
||||
taskType: 'font-sync',
|
||||
payload: {
|
||||
uploadDir: uploadDir,
|
||||
operations: fontLibrary.collectFontLibrarySyncOperations(uploadDir)
|
||||
},
|
||||
persist: true
|
||||
});
|
||||
}
|
||||
|
||||
res.redirect('/settings/fonts?message=' + encodeURIComponent('Font uploaded.'));
|
||||
} catch (error) {
|
||||
if (req.file && req.file.path) {
|
||||
try {
|
||||
await fs.promises.unlink(req.file.path);
|
||||
} catch (_cleanupError) {}
|
||||
}
|
||||
|
||||
if (error && /already exists/i.test(String(error.message || ''))) {
|
||||
const library = fontLibrary.loadFontLibrary(uploadDir);
|
||||
const usedFamilies = await fetchUsedFontFamilies(pool, library.fonts);
|
||||
const fonts = library.fonts.map(function (font) {
|
||||
const family = normalizeFontFamilyName(font.family || font.name);
|
||||
return Object.assign({}, font, {
|
||||
inUse: usedFamilies.has(family)
|
||||
});
|
||||
});
|
||||
|
||||
return res.status(400).send(pages.renderFontsPage({
|
||||
fonts: fonts,
|
||||
stylesheetHref: library.stylesheetHref
|
||||
}, String(error.message || 'Font already exists.'), req.currentUser));
|
||||
}
|
||||
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/settings/fonts/:id/toggle', requireFontsAccess(setAuthMessageCookie), async function (req, res, next) {
|
||||
try {
|
||||
const enabled = String(req.body && req.body.enabled || '').trim() !== '0';
|
||||
const updated = await fontLibrary.setFontEnabled(uploadDir, String(req.params.id || '').trim(), enabled);
|
||||
if (!updated) {
|
||||
return res.redirect('/settings/fonts?message=' + encodeURIComponent('That font was not found.'));
|
||||
}
|
||||
|
||||
if (backgroundTaskQueue && typeof backgroundTaskQueue.enqueueTask === 'function') {
|
||||
await backgroundTaskQueue.enqueueTask({
|
||||
key: `font-sync:toggle:${updated && updated.id ? updated.id : Date.now()}`,
|
||||
title: 'Font sync',
|
||||
category: 'fonts',
|
||||
taskType: 'font-sync',
|
||||
payload: {
|
||||
uploadDir: uploadDir,
|
||||
operations: fontLibrary.collectFontLibrarySyncOperations(uploadDir)
|
||||
},
|
||||
persist: true
|
||||
});
|
||||
}
|
||||
|
||||
res.redirect('/settings/fonts?message=' + encodeURIComponent(enabled ? 'Font enabled.' : 'Font disabled.'));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/settings/fonts/:id/delete', requireFontsAccess(setAuthMessageCookie), async function (req, res, next) {
|
||||
try {
|
||||
const fontId = String(req.params.id || '').trim();
|
||||
const currentFont = fontLibrary.loadFontLibrary(uploadDir).fonts.find(function (font) {
|
||||
return String(font.id || font.fileName || '').trim() === fontId || String(font.fileName || '').trim() === fontId;
|
||||
});
|
||||
const family = currentFont ? String(currentFont.family || currentFont.name || '').trim() : '';
|
||||
if (family && await isFontUsed(pool, family)) {
|
||||
return res.redirect('/settings/fonts?message=' + encodeURIComponent('That font is still used by one or more slides.'));
|
||||
}
|
||||
|
||||
const removed = await fontLibrary.deleteFontFile(uploadDir, fontId);
|
||||
if (!removed) {
|
||||
return res.redirect('/settings/fonts?message=' + encodeURIComponent('That font was not found.'));
|
||||
}
|
||||
|
||||
if (backgroundTaskQueue && typeof backgroundTaskQueue.enqueueTask === 'function') {
|
||||
await backgroundTaskQueue.enqueueTask({
|
||||
key: `font-sync:delete:${removed && removed.id ? removed.id : Date.now()}`,
|
||||
title: 'Font sync',
|
||||
category: 'fonts',
|
||||
taskType: 'font-sync',
|
||||
payload: {
|
||||
uploadDir: uploadDir,
|
||||
operations: [
|
||||
removed.fileName ? { type: 'delete', uploadPath: '/media/fonts/' + removed.fileName } : null
|
||||
].concat(fontLibrary.collectFontLibrarySyncOperations(uploadDir)).filter(Boolean)
|
||||
},
|
||||
persist: true
|
||||
});
|
||||
}
|
||||
|
||||
res.redirect('/settings/fonts?message=' + encodeURIComponent('Font removed.'));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
// Managed fonts settings page renderer.
|
||||
|
||||
const { renderView } = require('../../../view');
|
||||
|
||||
module.exports = function renderFontsPage(data, message, currentUser) {
|
||||
return renderView('settings/fonts/list', {
|
||||
title: 'Fonts',
|
||||
active: 'fonts',
|
||||
message: message,
|
||||
currentUser: currentUser || null,
|
||||
fonts: data.fonts || [],
|
||||
stylesheetHref: data.stylesheetHref || ''
|
||||
});
|
||||
};
|
||||
@@ -1,3 +1,5 @@
|
||||
// RBAC role add page renderer.
|
||||
|
||||
const { renderView } = require('../../../view');
|
||||
|
||||
module.exports = function renderRbacAddPage(message, currentUser, formValues, permissionGroups, messageVariant) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// RBAC role edit page renderer.
|
||||
|
||||
const { renderView } = require('../../../view');
|
||||
|
||||
module.exports = function renderRbacEditPage(role, message, currentUser, permissionGroups, users, pagination) {
|
||||
@@ -7,6 +9,7 @@ module.exports = function renderRbacEditPage(role, message, currentUser, permiss
|
||||
message: message,
|
||||
currentUser: currentUser || null,
|
||||
role: role,
|
||||
inUse: Boolean(role && role.inUse),
|
||||
permissionGroups: permissionGroups || [],
|
||||
users: users || [],
|
||||
pagination: pagination || null,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// RBAC role-and-permission list page renderer.
|
||||
|
||||
const { renderView } = require('../../../view');
|
||||
|
||||
module.exports = function renderRbacPage(data, message, currentUser) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// User add page renderer.
|
||||
|
||||
const { renderView } = require('../../../view');
|
||||
|
||||
module.exports = function renderUsersAddPage(message, currentUser, roles, formValues, messageVariant) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// User edit page renderer.
|
||||
|
||||
const { renderView } = require('../../../view');
|
||||
|
||||
module.exports = function renderUsersEditPage(user, message, currentUser, roles) {
|
||||
@@ -7,6 +9,7 @@ module.exports = function renderUsersEditPage(user, message, currentUser, roles)
|
||||
message: message,
|
||||
currentUser: currentUser || null,
|
||||
user: user,
|
||||
inUse: Boolean(user && user.inUse),
|
||||
roles: roles || []
|
||||
});
|
||||
};
|
||||
@@ -1,3 +1,5 @@
|
||||
// User list page renderer.
|
||||
|
||||
const { renderView } = require('../../../view');
|
||||
|
||||
module.exports = function renderUsersPage(data, message, currentUser) {
|
||||
|
||||
Reference in New Issue
Block a user