You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.7 KiB
JavaScript

'use strict';
const validator = require('validator');
const winston = require('winston');
const plugins = require('../plugins');
const db = require('../database');
const pubsub = require('../pubsub');
const admin = module.exports;
let cache = null;
pubsub.on('admin:navigation:save', () => {
cache = null;
});
admin.save = async function (data) {
const order = Object.keys(data);
const bulkSet = [];
data.forEach((item, index) => {
item.order = order[index];
if (item.hasOwnProperty('groups')) {
item.groups = JSON.stringify(item.groups);
}
bulkSet.push([`navigation:enabled:${item.order}`, item]);
});
cache = null;
pubsub.publish('admin:navigation:save');
const ids = await db.getSortedSetRange('navigation:enabled', 0, -1);
await db.deleteAll(ids.map(id => `navigation:enabled:${id}`));
await db.setObjectBulk(bulkSet);
await db.delete('navigation:enabled');
await db.sortedSetAdd('navigation:enabled', order, order);
};
admin.getAdmin = async function () {
const [enabled, available] = await Promise.all([
admin.get(),
getAvailable(),
]);
return { enabled: enabled, available: available };
};
const fieldsToEscape = ['iconClass', 'class', 'route', 'id', 'text', 'textClass', 'title'];
admin.escapeFields = navItems => toggleEscape(navItems, true);
admin.unescapeFields = navItems => toggleEscape(navItems, false);
function toggleEscape(navItems, flag) {
navItems.forEach((item) => {
if (item) {
fieldsToEscape.forEach((field) => {
if (item.hasOwnProperty(field)) {
item[field] = validator[flag ? 'escape' : 'unescape'](String(item[field]));
}
});
}
});
}
admin.get = async function () {
if (cache) {
return cache.map(item => ({ ...item }));
}
const ids = await db.getSortedSetRange('navigation:enabled', 0, -1);
const data = await db.getObjects(ids.map(id => `navigation:enabled:${id}`));
cache = data.filter(Boolean).map((item) => {
if (item.hasOwnProperty('groups')) {
try {
item.groups = JSON.parse(item.groups);
} catch (err) {
winston.error(err.stack);
item.groups = [];
}
}
item.groups = item.groups || [];
if (item.groups && !Array.isArray(item.groups)) {
item.groups = [item.groups];
}
return item;
});
admin.escapeFields(cache);
return cache.map(item => ({ ...item }));
};
async function getAvailable() {
const core = require('../../install/data/navigation.json').map((item) => {
item.core = true;
item.id = item.id || '';
return item;
});
const navItems = await plugins.hooks.fire('filter:navigation.available', core);
navItems.forEach((item) => {
if (item && !item.hasOwnProperty('enabled')) {
item.enabled = true;
}
});
return navItems;
}
require('../promisify')(admin);