import Route from '@ember/routing/route'; import { routes } from 'consul-ui/router'; import { env } from 'consul-ui/env'; import flat from 'flat'; const withNspace = function(currentRouteName, requestedRouteName, ...rest) { const isNspaced = currentRouteName.startsWith('nspace.'); if (isNspaced && requestedRouteName.startsWith('dc')) { return [`nspace.${requestedRouteName}`, ...rest]; } return [requestedRouteName, ...rest]; }; const register = function(container, route, path) { route.reopen({ templateName: path .replace('/root-create', '/create') .replace('/create', '/edit') .replace('/folder', '/index'), }); container.register(`route:nspace/${path}`, route); const controller = container.resolveRegistration(`controller:${path}`); if (controller) { container.register(`controller:nspace/${path}`, controller); } }; export function initialize(container) { // patch Route routeName-like methods for navigation to support nspace relative routes Route.reopen( ['transitionTo', 'replaceWith'].reduce(function(prev, item) { prev[item] = function(requestedRouteName, ...rest) { return this._super(...withNspace(this.routeName, requestedRouteName, ...rest)); }; return prev; }, {}) ); // patch Route routeName-like methods for data to support nspace relative routes Route.reopen( ['modelFor', 'paramsFor'].reduce(function(prev, item) { prev[item] = function(requestedRouteName, ...rest) { const isNspaced = this.routeName.startsWith('nspace.'); if (requestedRouteName === 'nspace' && !isNspaced && this.routeName !== 'nspace') { return { nspace: '~', }; } return this._super(...withNspace(this.routeName, requestedRouteName, ...rest)); }; return prev; }, {}) ); // extend router service with a nspace aware router to support nspace relative routes const nspacedRouter = container.resolveRegistration('service:router').extend({ transitionTo: function(requestedRouteName, ...rest) { return this._super(...withNspace(this.currentRoute.name, requestedRouteName, ...rest)); }, replaceWith: function(requestedRouteName, ...rest) { return this._super(...withNspace(this.currentRoute.name, requestedRouteName, ...rest)); }, urlFor: function(requestedRouteName, ...rest) { return this._super(...withNspace(this.currentRoute.name, requestedRouteName, ...rest)); }, }); container.register('service:router', nspacedRouter); if (env('CONSUL_NSPACES_ENABLED')) { // enable the nspace repo ['dc', 'settings', 'dc.intentions.edit', 'dc.intentions.create'].forEach(function(item) { container.inject(`route:${item}`, 'nspacesRepo', 'service:repository/nspace/enabled'); container.inject(`route:nspace.${item}`, 'nspacesRepo', 'service:repository/nspace/enabled'); }); container.inject('route:application', 'nspacesRepo', 'service:repository/nspace/enabled'); const dotRe = /\./g; // register automatic 'index' routes and controllers that start with 'dc' Object.keys(flat(routes)) .filter(function(item) { return item.startsWith('dc'); }) .map(function(item) { return item.replace('._options.path', '').replace(dotRe, '/'); }) .forEach(function(item) { let route = container.resolveRegistration(`route:${item}`); let indexed; // if the route doesn't exist it probably has an index route instead if (!route) { item = `${item}/index`; route = container.resolveRegistration(`route:${item}`); } else { // if the route does exist // then check to see if it also has an index route indexed = `${item}/index`; const index = container.resolveRegistration(`route:${indexed}`); if (typeof index !== 'undefined') { register(container, index, indexed); } } register(container, route, item); }); // tell the view we have nspaces enabled container .lookup('service:dom') .root() .classList.add('has-nspaces'); } // TODO: This needs to live in its own initializer, either: // 1. Make it be about adding classes to the root dom node // 2. Make it be about config and things to do on initialization re: config // If we go with 1 then we need to move both this and the above nspaces class if (env('CONSUL_ACLS_ENABLED')) { container .lookup('service:dom') .root() .classList.add('has-acls'); } } export default { initialize, };