ui: Runtime Injectable Components (#11969)

- Simplifies how we 'import' our configuration files a little in order to make them more grokable.
- Starts to exclude files based on explicit configuration rather than convention.
- Adds the first instance of us being able to select an implementation (of multiple) of a component at runtime.
This commit is contained in:
John Cowen 2022-01-19 10:14:59 +00:00 committed by GitHub
parent e77becb59e
commit 1eb93726a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 588 additions and 546 deletions

View File

@ -9,10 +9,7 @@
},
},
}))(
(json, data = document.currentScript.dataset) => {
const appNameJS = data.appName.split('-')
.map((item, i) => i ? `${item.substr(0, 1).toUpperCase()}${item.substr(1)}` : item)
.join('');
data[`${appNameJS}Routes`] = JSON.stringify(json);
(json, data = (typeof document !== 'undefined' ? document.currentScript.dataset : module.exports)) => {
data[`routes`] = JSON.stringify(json);
}
);

View File

@ -0,0 +1,7 @@
(services => services({
}))(
(json, data = (typeof document !== 'undefined' ? document.currentScript.dataset : module.exports)) => {
data[`services`] = JSON.stringify(json);
}
);

View File

@ -34,10 +34,7 @@
},
},
}))(
(json, data = document.currentScript.dataset) => {
const appNameJS = data.appName.split('-')
.map((item, i) => i ? `${item.substr(0, 1).toUpperCase()}${item.substr(1)}` : item)
.join('');
data[`${appNameJS}Routes`] = JSON.stringify(json);
(json, data = (typeof document !== 'undefined' ? document.currentScript.dataset : module.exports)) => {
data[`routes`] = JSON.stringify(json);
}
);

View File

@ -0,0 +1,7 @@
(services => services({
}))(
(json, data = (typeof document !== 'undefined' ? document.currentScript.dataset : module.exports)) => {
data[`services`] = JSON.stringify(json);
}
);

View File

@ -1,4 +1,3 @@
{{#if (can "use partitions")}}
{{#let
(or @partition 'default')
as |partition|}}
@ -62,5 +61,3 @@ as |partition|}}
</li>
{{/if}}
{{/let}}
{{/if}}

View File

@ -34,10 +34,7 @@
},
},
}))(
(json, data = document.currentScript.dataset) => {
const appNameJS = data.appName.split('-')
.map((item, i) => i ? `${item.substr(0, 1).toUpperCase()}${item.substr(1)}` : item)
.join('');
data[`${appNameJS}Routes`] = JSON.stringify(json);
(json, data = (typeof document !== 'undefined' ? document.currentScript.dataset : module.exports)) => {
data[`routes`] = JSON.stringify(json);
}
);

View File

@ -0,0 +1,9 @@
(services => services({
"component:consul/partition/selector": {
"class": "consul-ui/components/consul/partition/selector"
}
}))(
(json, data = (typeof document !== 'undefined' ? document.currentScript.dataset : module.exports)) => {
data[`services`] = JSON.stringify(json);
}
);

View File

@ -3,38 +3,33 @@ import require from 'require';
import merge from 'deepmerge';
const doc = document;
const appName = 'consul-ui';
const appNameJS = appName
.split('-')
.map((item, i) => (i ? `${item.substr(0, 1).toUpperCase()}${item.substr(1)}` : item))
.join('');
export const services = merge.all(
[].concat(
...[...doc.querySelectorAll(`script[data-${appName}-services]`)].map($item =>
JSON.parse($item.dataset[`${appNameJS}Services`])
)
[...doc.querySelectorAll(`script[data-services]`)].map($item =>
JSON.parse($item.dataset[`services`])
)
);
const inject = function(container, obj) {
// inject all the things
Object.entries(obj).forEach(([key, value]) => {
switch(true) {
case (typeof value.class === 'string'):
if(require.has(value.class)) {
container.register(key.replace('auth-provider:', 'torii-provider:'), require(value.class).default);
switch (true) {
case typeof value.class === 'string':
if (require.has(value.class)) {
container.register(
key.replace('auth-provider:', 'torii-provider:'),
require(value.class).default
);
} else {
throw new Error(`Unable to locate '${value.class}'`);
}
break;
break;
}
});
}
};
export default {
name: 'container',
initialize(application) {
inject(application, services);
const container = application.lookup('service:container');

View File

@ -8,443 +8,9 @@ import walk, { dump } from 'consul-ui/utils/routing/walk';
const doc = document;
const appName = config.modulePrefix;
const appNameJS = appName
.split('-')
.map((item, i) => (i ? `${item.substr(0, 1).toUpperCase()}${item.substr(1)}` : item))
.join('');
export const routes = merge.all(
[
{
// Our parent datacenter resource sets the namespace
// for the entire application
dc: {
_options: {
path: '/:dc',
},
index: {
_options: {
path: '/',
redirect: '../services',
},
},
// Services represent a consul service
services: {
_options: { path: '/services' },
index: {
_options: {
path: '/',
queryParams: {
sortBy: 'sort',
status: 'status',
source: 'source',
kind: 'kind',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Tags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
// Show an individual service
show: {
_options: { path: '/:name' },
instances: {
_options: {
path: '/instances',
queryParams: {
sortBy: 'sort',
status: 'status',
source: 'source',
searchproperty: {
as: 'searchproperty',
empty: [
[
'Name',
'Node',
'Tags',
'ID',
'Address',
'Port',
'Service.Meta',
'Node.Meta',
],
],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
intentions: {
_options: { path: '/intentions' },
index: {
_options: {
path: '',
queryParams: {
sortBy: 'sort',
access: 'access',
searchproperty: {
as: 'searchproperty',
empty: [['SourceName', 'DestinationName']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
edit: {
_options: { path: '/:intention_id' },
},
create: {
_options: {
template: '../edit',
path: '/create',
},
},
},
topology: {
_options: { path: '/topology' },
},
services: {
_options: {
path: '/services',
queryParams: {
sortBy: 'sort',
instance: 'instance',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Tags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
upstreams: {
_options: {
path: '/upstreams',
queryParams: {
sortBy: 'sort',
instance: 'instance',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Tags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
routing: {
_options: { path: '/routing' },
},
tags: {
_options: { path: '/tags' },
},
},
instance: {
_options: {
path: '/:name/instances/:node/:id',
redirect: './healthchecks',
},
healthchecks: {
_options: {
path: '/health-checks',
queryParams: {
sortBy: 'sort',
status: 'status',
check: 'check',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Node', 'CheckID', 'Notes', 'Output', 'ServiceTags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
upstreams: {
_options: {
path: '/upstreams',
queryParams: {
sortBy: 'sort',
search: {
as: 'filter',
replace: true,
},
searchproperty: {
as: 'searchproperty',
empty: [['DestinationName', 'LocalBindAddress', 'LocalBindPort']],
},
},
},
},
exposedpaths: {
_options: { path: '/exposed-paths' },
},
addresses: {
_options: { path: '/addresses' },
},
metadata: {
_options: { path: '/metadata' },
},
},
notfound: {
_options: { path: '/:name/:node/:id' },
},
},
// Nodes represent a consul node
nodes: {
_options: { path: '/nodes' },
index: {
_options: {
path: '',
queryParams: {
sortBy: 'sort',
status: 'status',
searchproperty: {
as: 'searchproperty',
empty: [['Node', 'Address', 'Meta']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
// Show an individual node
show: {
_options: { path: '/:name' },
healthchecks: {
_options: {
path: '/health-checks',
queryParams: {
sortBy: 'sort',
status: 'status',
kind: 'kind',
check: 'check',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Service', 'CheckID', 'Notes', 'Output', 'ServiceTags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
services: {
_options: {
path: '/service-instances',
queryParams: {
sortBy: 'sort',
status: 'status',
source: 'source',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Tags', 'ID', 'Address', 'Port', 'Service.Meta']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
rtt: {
_options: { path: '/round-trip-time' },
},
sessions: {
_options: { path: '/lock-sessions' },
},
metadata: {
_options: { path: '/metadata' },
},
},
},
// Intentions represent a consul intention
intentions: {
_options: { path: '/intentions' },
index: {
_options: {
path: '/',
queryParams: {
sortBy: 'sort',
access: 'access',
searchproperty: {
as: 'searchproperty',
empty: [['SourceName', 'DestinationName']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
edit: {
_options: {
path: '/:intention_id',
abilities: ['read intentions'],
},
},
create: {
_options: {
template: '../edit',
path: '/create',
abilities: ['create intentions'],
},
},
},
// Key/Value
kv: {
_options: { path: '/kv' },
index: {
_options: {
path: '/',
queryParams: {
sortBy: 'sort',
kind: 'kind',
search: {
as: 'filter',
replace: true,
},
},
},
},
folder: {
_options: {
template: '../index',
path: '/*key',
},
},
edit: {
_options: { path: '/*key/edit' },
},
create: {
_options: {
template: '../edit',
path: '/*key/create',
abilities: ['create kvs'],
},
},
'root-create': {
_options: {
template: '../edit',
path: '/create',
abilities: ['create kvs'],
},
},
},
// ACLs
acls: {
_options: {
path: '/acls',
abilities: ['access acls'],
},
policies: {
_options: {
path: '/policies',
abilities: ['read policies'],
},
edit: {
_options: { path: '/:id' },
},
create: {
_options: {
path: '/create',
abilities: ['create policies'],
},
},
},
roles: {
_options: {
path: '/roles',
abilities: ['read roles'],
},
edit: {
_options: { path: '/:id' },
},
create: {
_options: {
path: '/create',
abilities: ['create roles'],
},
},
},
tokens: {
_options: {
path: '/tokens',
abilities: ['access acls'],
},
edit: {
_options: { path: '/:id' },
},
create: {
_options: {
path: '/create',
abilities: ['create tokens'],
},
},
},
'auth-methods': {
_options: {
path: '/auth-methods',
abilities: ['read auth-methods'],
},
show: {
_options: { path: '/:id' },
'auth-method': {
_options: { path: '/auth-method' },
},
'binding-rules': {
_options: { path: '/binding-rules' },
},
'nspace-rules': {
_options: { path: '/nspace-rules' },
},
},
},
},
'routing-config': {
_options: { path: '/routing-config/:name' },
},
},
// Shows a datacenter picker. If you only have one
// it just redirects you through.
index: {
_options: { path: '/' },
},
// The settings page is global.
settings: {
_options: { path: '/setting' },
},
notfound: {
_options: { path: '/*notfound' },
},
},
].concat(
...[...doc.querySelectorAll(`script[data-${appName}-routes]`)].map($item =>
JSON.parse($item.dataset[`${appNameJS}Routes`])
)
)
[...doc.querySelectorAll(`script[data-routes]`)].map($item => JSON.parse($item.dataset[`routes`]))
);
runInDebug(() => {
@ -497,6 +63,12 @@ runInDebug(() => {
};
});
// Consul UIs routes are kept in individual configuration files Please see for
// example /ui/pacakges/consul-ui/vendor/routes.js Routing for additional
// applications/features are kept in the corresponding configuration files for
// the application/feature and optional merged at runtime depending on a
// Consul backend feature flag. Please see for example
// /ui/packages/consul-nspaces/vendor/route.js
export default class Router extends EmberRouter {
location = env('locationType');
rootURL = env('rootURL');

View File

@ -27,6 +27,7 @@ module.exports = function(defaults, $ = process.env) {
let excludeFiles = [];
const apps = [
'consul-ui',
'consul-acls',
'consul-partitions',
'consul-nspaces'
@ -55,6 +56,7 @@ module.exports = function(defaults, $ = process.env) {
])
}
if(['test', 'production'].includes(env)) {
// exclude our debug initializer, route and template
excludeFiles = excludeFiles.concat([
@ -66,6 +68,30 @@ module.exports = function(defaults, $ = process.env) {
'templates/debug.hbs',
'components/debug/**/*.*'
])
// inspect *-debug configuration files for files to exclude
excludeFiles = apps.reduce(
(prev, item) => {
return ['services', 'routes'].reduce(
(prev, type) => {
const path = `${item.path}/vendor/${item.name}/${type}-debug.js`;
if(exists(path)) {
return Object.entries(JSON.parse(require(path)[type])).reduce(
(prev, [key, definition]) => {
if(typeof definition.class !== 'undefined') {
return prev.concat(`${definition.class.replace(`${item.name}/`, '')}.js`);
}
return prev;
},
prev
);
}
return prev;
},
prev
)
},
excludeFiles
);
// exclude any debug like addons from production or test environments
addons.blacklist = [
// exclude docfy
@ -88,18 +114,24 @@ module.exports = function(defaults, $ = process.env) {
}
//
trees.app = mergeTrees([
new Funnel('app', { exclude: excludeFiles })
].concat(
apps.filter(item => exists(`${item.path}/app`)).map(item => new Funnel(`${item.path}/app`, {exclude: excludeFiles}))
), {
overwrite: true
});
trees.vendor = mergeTrees([
new Funnel('vendor'),
].concat(
apps.map(item => new Funnel(`${item.path}/vendor`))
));
(
function(apps) {
trees.app = mergeTrees([
new Funnel('app', { exclude: excludeFiles })
].concat(
apps.filter(item => exists(`${item.path}/app`)).map(item => new Funnel(`${item.path}/app`, {exclude: excludeFiles}))
), {
overwrite: true
});
trees.vendor = mergeTrees([
new Funnel('vendor'),
].concat(
apps.map(item => new Funnel(`${item.path}/vendor`))
));
}
// consul-ui will eventually be a separate app just like the others
// at which point we can remove this filter/extra scope
)(apps.filter(item => item.name !== 'consul-ui'));
//
const app = new EmberApp(
@ -147,20 +179,31 @@ module.exports = function(defaults, $ = process.env) {
},
}
);
const build = function(path, options) {
const {root, ...rest} = options;
if(exists(`${root}/${path}`)) {
app.import(path, rest);
}
};
apps.forEach(item => {
app.import(`vendor/${item.name}/routes.js`, {
build(`vendor/${item.name}/routes.js`, {
root: item.path,
outputFile: `assets/${item.name}/routes.js`,
});
});
[
'consul-ui/services'
].concat(devlike ? [
'consul-ui/services-debug',
'consul-ui/routes-debug'
] : []).forEach(item => {
app.import(`vendor/${item}.js`, {
outputFile: `assets/${item}.js`,
build(`vendor/${item.name}/services.js`, {
root: item.path,
outputFile: `assets/${item.name}/services.js`,
});
if(devlike) {
build(`vendor/${item.name}/routes-debug.js`, {
root: item.path,
outputFile: `assets/${item.name}/routes-debug.js`,
});
build(`vendor/${item.name}/services-debug.js`, {
root: item.path,
outputFile: `assets/${item.name}/services-debug.js`,
});
}
});
// Use `app.import` to add additional libraries to the generated
// output files.

View File

@ -42,12 +42,13 @@ ${environment === 'production' ? `{{jsonEncode .}}` : JSON.stringify(config.oper
"codemirror/mode/xml/xml.js": "${rootURL}assets/codemirror/mode/xml/xml.js"
}
</script>
<script data-app-name="${appName}" data-${appName}-services src="${rootURL}assets/consul-ui/services.js"></script>
<script src="${rootURL}assets/consul-ui/services.js"></script>
<script src="${rootURL}assets/consul-ui/routes.js"></script>
${
environment === 'development' || environment === 'staging'
? `
<script data-app-name="${appName}" data-${appName}-services src="${rootURL}assets/consul-ui/services-debug.js"></script>
<script data-app-name="${appName}" data-${appName}-routing src="${rootURL}assets/consul-ui/routes-debug.js"></script>
<script src="${rootURL}assets/consul-ui/services-debug.js"></script>
<script src="${rootURL}assets/consul-ui/routes-debug.js"></script>
`
: ``
}
@ -55,13 +56,14 @@ ${
environment === 'production'
? `
{{if .ACLsEnabled}}
<script data-app-name="${appName}" data-${appName}-routing src="${rootURL}assets/consul-acls/routes.js"></script>
<script src="${rootURL}assets/consul-acls/routes.js"></script>
{{end}}
{{if .PartitionsEnabled}}
<script data-app-name="${appName}" data-${appName}-routing src="${rootURL}assets/consul-partitions/routes.js"></script>
<script src="${rootURL}assets/consul-partitions/services.js"></script>
<script src="${rootURL}assets/consul-partitions/routes.js"></script>
{{end}}
{{if .NamespacesEnabled}}
<script data-app-name="${appName}" data-${appName}-routing src="${rootURL}assets/consul-nspaces/routes.js"></script>
<script src="${rootURL}assets/consul-nspaces/routes.js"></script>
{{end}}
`
: `
@ -72,7 +74,8 @@ ${
if(get(key) || (key === 'CONSUL_NSPACES_ENABLE' && ${
env('CONSUL_NSPACES_ENABLED') === '1' ? `true` : `false`
})) {
document.write(\`\\x3Cscript data-app-name="${appName}" data-${appName}-routing src="${rootURL}assets/\${value}/routes.js">\\x3C/script>\`);
document.write(\`\\x3Cscript src="${rootURL}assets/\${value}/services.js">\\x3C/script>\`);
document.write(\`\\x3Cscript src="${rootURL}assets/\${value}/routes.js">\\x3C/script>\`);
}
});
}

View File

@ -1,19 +1,20 @@
(routes => routes({
['oauth-provider-debug']: {
_options: {
path: '/oauth-provider-debug',
queryParams: {
redirect_uri: 'redirect_uri',
response_type: 'response_type',
scope: 'scope',
(routes =>
routes({
['oauth-provider-debug']: {
_options: {
path: '/oauth-provider-debug',
queryParams: {
redirect_uri: 'redirect_uri',
response_type: 'response_type',
scope: 'scope',
},
},
}
},
}))(
(json, data = document.currentScript.dataset) => {
const appNameJS = data.appName.split('-')
.map((item, i) => i ? `${item.substr(0, 1).toUpperCase()}${item.substr(1)}` : item)
.join('');
data[`${appNameJS}Routes`] = JSON.stringify(json);
},
}))(
(
json,
data = typeof document !== 'undefined' ? document.currentScript.dataset : module.exports
) => {
data[`routes`] = JSON.stringify(json);
}
);

View File

@ -0,0 +1,412 @@
(routes =>
routes({
dc: {
_options: {
path: '/:dc',
},
index: {
_options: {
path: '/',
redirect: '../services',
},
},
services: {
_options: { path: '/services' },
index: {
_options: {
path: '/',
queryParams: {
sortBy: 'sort',
status: 'status',
source: 'source',
kind: 'kind',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Tags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
show: {
_options: { path: '/:name' },
instances: {
_options: {
path: '/instances',
queryParams: {
sortBy: 'sort',
status: 'status',
source: 'source',
searchproperty: {
as: 'searchproperty',
empty: [
['Name', 'Node', 'Tags', 'ID', 'Address', 'Port', 'Service.Meta', 'Node.Meta'],
],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
intentions: {
_options: { path: '/intentions' },
index: {
_options: {
path: '',
queryParams: {
sortBy: 'sort',
access: 'access',
searchproperty: {
as: 'searchproperty',
empty: [['SourceName', 'DestinationName']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
edit: {
_options: { path: '/:intention_id' },
},
create: {
_options: {
template: '../edit',
path: '/create',
},
},
},
topology: {
_options: { path: '/topology' },
},
services: {
_options: {
path: '/services',
queryParams: {
sortBy: 'sort',
instance: 'instance',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Tags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
upstreams: {
_options: {
path: '/upstreams',
queryParams: {
sortBy: 'sort',
instance: 'instance',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Tags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
routing: {
_options: { path: '/routing' },
},
tags: {
_options: { path: '/tags' },
},
},
instance: {
_options: {
path: '/:name/instances/:node/:id',
redirect: './healthchecks',
},
healthchecks: {
_options: {
path: '/health-checks',
queryParams: {
sortBy: 'sort',
status: 'status',
check: 'check',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Node', 'CheckID', 'Notes', 'Output', 'ServiceTags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
upstreams: {
_options: {
path: '/upstreams',
queryParams: {
sortBy: 'sort',
search: {
as: 'filter',
replace: true,
},
searchproperty: {
as: 'searchproperty',
empty: [['DestinationName', 'LocalBindAddress', 'LocalBindPort']],
},
},
},
},
exposedpaths: {
_options: { path: '/exposed-paths' },
},
addresses: {
_options: { path: '/addresses' },
},
metadata: {
_options: { path: '/metadata' },
},
},
notfound: {
_options: { path: '/:name/:node/:id' },
},
},
nodes: {
_options: { path: '/nodes' },
index: {
_options: {
path: '',
queryParams: {
sortBy: 'sort',
status: 'status',
searchproperty: {
as: 'searchproperty',
empty: [['Node', 'Address', 'Meta']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
show: {
_options: { path: '/:name' },
healthchecks: {
_options: {
path: '/health-checks',
queryParams: {
sortBy: 'sort',
status: 'status',
kind: 'kind',
check: 'check',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Service', 'CheckID', 'Notes', 'Output', 'ServiceTags']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
services: {
_options: {
path: '/service-instances',
queryParams: {
sortBy: 'sort',
status: 'status',
source: 'source',
searchproperty: {
as: 'searchproperty',
empty: [['Name', 'Tags', 'ID', 'Address', 'Port', 'Service.Meta']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
rtt: {
_options: { path: '/round-trip-time' },
},
sessions: {
_options: { path: '/lock-sessions' },
},
metadata: {
_options: { path: '/metadata' },
},
},
},
intentions: {
_options: { path: '/intentions' },
index: {
_options: {
path: '/',
queryParams: {
sortBy: 'sort',
access: 'access',
searchproperty: {
as: 'searchproperty',
empty: [['SourceName', 'DestinationName']],
},
search: {
as: 'filter',
replace: true,
},
},
},
},
edit: {
_options: {
path: '/:intention_id',
abilities: ['read intentions'],
},
},
create: {
_options: {
template: '../edit',
path: '/create',
abilities: ['create intentions'],
},
},
},
kv: {
_options: { path: '/kv' },
index: {
_options: {
path: '/',
queryParams: {
sortBy: 'sort',
kind: 'kind',
search: {
as: 'filter',
replace: true,
},
},
},
},
folder: {
_options: {
template: '../index',
path: '/*key',
},
},
edit: {
_options: { path: '/*key/edit' },
},
create: {
_options: {
template: '../edit',
path: '/*key/create',
abilities: ['create kvs'],
},
},
'root-create': {
_options: {
template: '../edit',
path: '/create',
abilities: ['create kvs'],
},
},
},
acls: {
_options: {
path: '/acls',
abilities: ['access acls'],
},
policies: {
_options: {
path: '/policies',
abilities: ['read policies'],
},
edit: {
_options: { path: '/:id' },
},
create: {
_options: {
path: '/create',
abilities: ['create policies'],
},
},
},
roles: {
_options: {
path: '/roles',
abilities: ['read roles'],
},
edit: {
_options: { path: '/:id' },
},
create: {
_options: {
path: '/create',
abilities: ['create roles'],
},
},
},
tokens: {
_options: {
path: '/tokens',
abilities: ['access acls'],
},
edit: {
_options: { path: '/:id' },
},
create: {
_options: {
path: '/create',
abilities: ['create tokens'],
},
},
},
'auth-methods': {
_options: {
path: '/auth-methods',
abilities: ['read auth-methods'],
},
show: {
_options: { path: '/:id' },
'auth-method': {
_options: { path: '/auth-method' },
},
'binding-rules': {
_options: { path: '/binding-rules' },
},
'nspace-rules': {
_options: { path: '/nspace-rules' },
},
},
},
},
'routing-config': {
_options: { path: '/routing-config/:name' },
},
},
index: {
_options: { path: '/' },
},
settings: {
_options: { path: '/setting' },
},
notfound: {
_options: { path: '/*notfound' },
},
}))(
(
json,
data = typeof document !== 'undefined' ? document.currentScript.dataset : module.exports
) => {
data[`routes`] = JSON.stringify(json);
}
);

View File

@ -1,15 +1,16 @@
(services => services({
"route:application": {
"class": "consul-ui/routing/application-debug"
},
"service:intl": {
"class": "consul-ui/services/i18n-debug"
}
}))(
(json, data = document.currentScript.dataset) => {
const appNameJS = data.appName.split('-')
.map((item, i) => i ? `${item.substr(0, 1).toUpperCase()}${item.substr(1)}` : item)
.join('');
data[`${appNameJS}Services`] = JSON.stringify(json);
(services =>
services({
'route:application': {
class: 'consul-ui/routing/application-debug',
},
'service:intl': {
class: 'consul-ui/services/i18n-debug',
},
}))(
(
json,
data = typeof document !== 'undefined' ? document.currentScript.dataset : module.exports
) => {
data[`services`] = JSON.stringify(json);
}
);

View File

@ -1,21 +1,25 @@
(services => services({
"route:basic": {
"class": "consul-ui/routing/route"
},
"service:intl": {
"class": "consul-ui/services/i18n"
},
"service:state": {
"class": "consul-ui/services/state-with-charts"
},
"auth-provider:oidc-with-url": {
"class": "consul-ui/services/auth-providers/oauth2-code-with-url-provider"
}
}))(
(json, data = document.currentScript.dataset) => {
const appNameJS = data.appName.split('-')
.map((item, i) => i ? `${item.substr(0, 1).toUpperCase()}${item.substr(1)}` : item)
.join('');
data[`${appNameJS}Services`] = JSON.stringify(json);
(services =>
services({
'route:basic': {
class: 'consul-ui/routing/route',
},
'service:intl': {
class: 'consul-ui/services/i18n',
},
'service:state': {
class: 'consul-ui/services/state-with-charts',
},
'auth-provider:oidc-with-url': {
class: 'consul-ui/services/auth-providers/oauth2-code-with-url-provider',
},
'component:consul/partition/selector': {
class: '@glimmer/component',
},
}))(
(
json,
data = typeof document !== 'undefined' ? document.currentScript.dataset : module.exports
) => {
data[`services`] = JSON.stringify(json);
}
);