UNPKG

we-plugin-menu

Version:
367 lines (331 loc) 9.86 kB
/** * We.js menu plugin main file */ const sync = require('./lib/sync.js'); module.exports = function loadPlugin(projectPath, Plugin) { const plugin = new Plugin(__dirname); // set plugin configs plugin.setConfigs({ menu: { linkSortAttrs: ['weight', 'id', 'depth', 'parent'], adminMenu(req) { return { class: 'nav', permission: 'access_admin', links: [ { id: 'adminMenu', text: '<i class="fa fa-bars"></i> '+req.__('menu.find'), href: '/admin/menu', class: null, weight: 2, name: 'admin.menu.find' }, { id: 'adminUser', text: '<i class="fa fa-users"></i> '+req.__('users.link'), href: '/admin/user', class: null, weight: 3, name: 'admin.user.find' }, { id: 'adminPermissions', text: '<i class="fa fa-unlock-alt"></i> '+req.__('permission.link'), href: '/admin/permission', class: null, weight: 5 }, { id: 'adminUrlAlias', text: '<i class="fa fa-random"></i> '+req.__('urlAlias.find'), href: '/admin/urlAlias', class: null, weight: 7 } ] }; }, authenticatedUserMenu(req) { return { links: [{ id: 'user', href: '/user/' + req.user.id, text: req.user.displayName || '#'+req.user.id, class: null, weight: 3 }, { id: 'userProfileView', href: '/user/' + req.user.id, text: '<i class="glyphicon glyphicon-user"></i> '+ req.__('user.profile.view'), class: null, weight: 3, parent: 'user' }, { id: 'userProfileEdit', href: '/user/' + req.user.id + '/edit', text: '<i class="glyphicon glyphicon-pencil"></i> '+ req.__('user.profile.edit'), class: null, weight: 5, parent: 'user' }, { id: 'userProfileEditPrivacity', href: '/user/' + req.user.id + '/edit/privacity', text: '<i class="glyphicon glyphicon-alert"></i> '+ req.__('Privacity'), class: null, weight: 5, parent: 'user' }, { id: 'userChangePassword', href: '/auth/change-password', text: '<i class="glyphicon glyphicon-lock text-warning"></i> '+ req.__('auth.change-password'), class: null, weight: 7, parent: 'user', dividerAfter: true }, { id: 'logout', href: '/auth/logout', text: '<i class="glyphicon glyphicon-log-out text-danger"></i> '+ req.__('Logout'), class: null, weight: 9, parent: 'user', dividerAfter: true } ] }; }, unAuthenticatedUserMenu(req) { const links = []; if (req.we.config.auth.allowLogin) { links.push({ id: 'login', href: '/login', text: req.__('Login'), class: 'login-link', weight: 3 }); } if (req.we.config.auth.allowRegister) { links.push({ id: 'register', href: '/signup', text: req.__('Register'), class: 'register-link', weight: 5 }); } return { class: 'nav navbar-nav navbar-right', links: links }; } }, }); // menu resource: plugin.setResource({ name: 'menu' }); // menu link resource: plugin.setResource({ name: 'link' }); plugin.setRoutes({ 'post /admin/menu/:menuId([0-9]+)/sort-links': { controller : 'menu', action : 'sortLinks', model : 'menu', permission : 'update_menu', responseType : 'json' } }); /** * Default publish update that will be overriden in sync */ plugin.publishUpdate = function(cb) { cb(); }; /** * Default reload cached menus that will be overriden in sync */ plugin.reloadAllCachedMenus = function(cb) { cb(); }; /** * Preload menus selected with systemSettings configuration * * @param {Object} req Express.js request * @param {Object} res Express.js response * @param {Function} next Callback */ plugin.preloadMenus = function preloadMenus(req, res, next) { const ss = req.we.systemSettings; const l = res.locals; Object.defineProperty(l, 'menuMain', { get: function getMenu() { return plugin.getMenuWithID(ss.menuMainId); } }); Object.defineProperty(l, 'menuSecondary', { get: function getMenu() { return plugin.getMenuWithID(ss.menuSecondaryId); } }); Object.defineProperty(l, 'menuFooter', { get: function getMenu() { return plugin.getMenuWithID(ss.menuFooterId); } }); Object.defineProperty(l, 'menuSocial', { get: function getMenu() { return plugin.getMenuWithID(ss.menuSocialId); } }); Object.defineProperty(l, 'menuAuthenticated', { get: function getMenu() { return plugin.getMenuWithID(ss.menuAuthenticatedId); } }); next(); }; plugin.getMenuWithID = function getMenuWithID(id) { if (!id) return null; for (let name in plugin.we.menu) { if (plugin.we.menu[name].id == id) { return plugin.we.menu[name]; } } return null; }; // set menu class after load menu plugin.events.on('we:after:load:plugins', function (we) { we.class.Menu = require('./lib/Menu'); we.menu = {}; we.events.emit('we-plugin-menu:after:set:menu:class', we); }); plugin.events.on('we:after:load:express', (we)=> { if (we.plugins['we-plugin-db-system-settings']) { we.express.use(plugin.preloadMenus); } }); plugin.hooks.on('we:router:request:after:load:context', function (data, done) { const res = data.res, req = data.req; // set user menu if (req.isAuthenticated()) { res.locals.userMenu = new req.we.class.Menu( req.we.config.menu.authenticatedUserMenu(req) ); } else { res.locals.userMenu = new req.we.class.Menu( req.we.config.menu.unAuthenticatedUserMenu(req) ); } if (res.locals.isAdmin) { // set admin menu res.locals.adminMenu = new req.we.class.Menu( req.we.config.menu.adminMenu(req) ); } if (res.locals.user) { res.locals.currentUserMenu = new req.we.class.Menu({ class: 'nav nav-stacked nav-pills', permission: 'find_user', links: [ { id: 'view', text: '<i class="fa fa-eye"></i> '+req.__('menu.user.view'), href: res.locals.user.getUrlPathAlias(), class: null, weight: 2, name: 'menu.user.view' } ] }); if (req.we.acl && req.we.acl.canStatic('update_user', req.userRoleNames)) { res.locals.currentUserMenu.addLink({ id: 'edit', text: '<i class="fa fa-edit"></i> '+req.__('menu.user.edit'), href: '/user/'+res.locals.user.id+'/edit', class: null, weight: 4, name: 'menu.user.edit' }); } } req.we.hooks.trigger('we-plugin-menu:after:set:core:menus', data, done); }); plugin.hooks.on('we:after:routes:bind', function (we, done) { // skip menu cache if views plugin dont are instaled: if (!we.plugins['we-plugin-view']) return done(); we.db.models.menu.addHook('afterCreate', 'addToMenuCache', function (r) { we.menu[r.name] = r; }); we.db.models.menu.addHook('afterUpdate', 'updateMenuCache', function (r) { we.menu[r.name] = r; }); we.db.models.menu.addHook('afterDestroy', 'removeFromMenuCache', function (r) { delete we.menu[r.name]; }); we.db.models.link.addHook('afterCreate', 'addToMenuCache', function (r) { return new Promise( (resolve, reject)=> { // update the menu after create link we.db.models.menu .findOne({ where: { id: r.menuId }, include: [{ all: true }] }) .then( (r)=> { we.menu[r.name] = r; resolve(); }) .catch(reject); }); }); we.db.models.link.addHook('afterUpdate', 'updateLinkInMenuCache', function (r) { return new Promise( (resolve, reject)=> { // update the menu link after update link // TODO change to only update this link inside the menu we.db.models.menu .findOne({ where: { id: r.menuId }, include: [{ all: true }] }) .then( (r)=> { we.menu[r.name] = r; resolve(); }) .catch(reject); }); }); we.db.models.link.addHook('afterDestroy', 'removeFromMenuCache', function (r) { return new Promise( (resolve, reject)=> { // update the menu after delete link we.db.models.menu .findOne({ where: { id: r.menuId }, include: [{ all: true }] }) .then( (r)=> { we.menu[r.name] = r; resolve(); }) .catch(reject); }); }); plugin.reloadAllCachedMenus(done); }); plugin.events.on('we:after:init:sysPubsub', ()=> { sync.init(plugin); }); return plugin; };