open-consul/ui-v2/app/instance-initializers/nspace.js

126 lines
4.5 KiB
JavaScript

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,
};