ui: Allow templateName paths to be relative (#11955)

This commit is contained in:
John Cowen 2022-01-12 09:27:00 +00:00 committed by GitHub
parent ac72b1b9f0
commit fe105d1ba7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 118 additions and 41 deletions

View File

@ -26,7 +26,7 @@
}, },
create: { create: {
_options: { _options: {
template: 'dc/nspaces/edit', template: '../edit',
path: '/create', path: '/create',
abilities: ['create nspaces'], abilities: ['create nspaces'],
}, },

View File

@ -26,7 +26,7 @@
}, },
create: { create: {
_options: { _options: {
template: 'dc/partitions/edit', template: '../edit',
path: '/create', path: '/create',
abilities: ['create partitions'], abilities: ['create partitions'],
}, },

View File

@ -62,7 +62,18 @@ export const routes = merge.all(
source: 'source', source: 'source',
searchproperty: { searchproperty: {
as: 'searchproperty', as: 'searchproperty',
empty: [['Name', 'Node', 'Tags', 'ID', 'Address', 'Port', 'Service.Meta', 'Node.Meta']], empty: [
[
'Name',
'Node',
'Tags',
'ID',
'Address',
'Port',
'Service.Meta',
'Node.Meta',
],
],
}, },
search: { search: {
as: 'filter', as: 'filter',
@ -95,7 +106,7 @@ export const routes = merge.all(
}, },
create: { create: {
_options: { _options: {
template: 'dc/services/show/intentions/edit', template: '../edit',
path: '/create', path: '/create',
}, },
}, },
@ -296,7 +307,7 @@ export const routes = merge.all(
}, },
create: { create: {
_options: { _options: {
template: 'dc/intentions/edit', template: '../edit',
path: '/create', path: '/create',
abilities: ['create intentions'], abilities: ['create intentions'],
}, },
@ -320,7 +331,7 @@ export const routes = merge.all(
}, },
folder: { folder: {
_options: { _options: {
template: 'dc/kv/index', template: '../index',
path: '/*key', path: '/*key',
}, },
}, },
@ -329,14 +340,14 @@ export const routes = merge.all(
}, },
create: { create: {
_options: { _options: {
template: 'dc/kv/edit', template: '../edit',
path: '/*key/create', path: '/*key/create',
abilities: ['create kvs'], abilities: ['create kvs'],
}, },
}, },
'root-create': { 'root-create': {
_options: { _options: {
template: 'dc/kv/edit', template: '../edit',
path: '/create', path: '/create',
abilities: ['create kvs'], abilities: ['create kvs'],
}, },

View File

@ -1,17 +0,0 @@
import Route from 'consul-ui/routing/route';
export default class InstancesRoute extends Route {
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,
},
};
}

View File

@ -1,6 +1,7 @@
import Route from '@ember/routing/route'; import Route from '@ember/routing/route';
import { get, setProperties, action } from '@ember/object'; import { get, setProperties, action } from '@ember/object';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import resolve from 'consul-ui/utils/path/resolve';
import { routes } from 'consul-ui/router'; import { routes } from 'consul-ui/router';
@ -16,7 +17,7 @@ export default class BaseRoute extends Route {
const template = get(routes, `${this.routeName}._options.template`); const template = get(routes, `${this.routeName}._options.template`);
if (typeof template !== 'undefined') { if (typeof template !== 'undefined') {
this.templateName = template; this.templateName = resolve(this.routeName.split('.').join('/'), template);
} }
const queryParams = get(routes, `${this.routeName}._options.queryParams`); const queryParams = get(routes, `${this.routeName}._options.queryParams`);
@ -28,25 +29,16 @@ export default class BaseRoute extends Route {
redirect(model, transition) { redirect(model, transition) {
let to = get(routes, `${this.routeName}._options.redirect`); let to = get(routes, `${this.routeName}._options.redirect`);
if (typeof to !== 'undefined') { if (typeof to !== 'undefined') {
// simple path resolve
to = to
.split('/')
.reduce((prev, item, i, items) => {
if (item !== '.') {
if (item === '..') {
prev.pop();
} else if (item !== '' || i === items.length - 1) {
prev.push(item);
}
}
return prev;
}, this.routeName.split('.'))
.join('.');
// TODO: Does this need to return? // TODO: Does this need to return?
// Almost remember things getting strange if you returned from here // Almost remember things getting strange if you returned from here
// which is why I didn't do it originally so be sure to look properly if // which is why I didn't do it originally so be sure to look properly if
// you feel like adding a return // you feel like adding a return
this.replaceWith(`${to}`, model); this.replaceWith(
resolve(this.routeName.split('.').join('/'), to)
.split('/')
.join('.'),
model
);
} }
} }

View File

@ -0,0 +1,25 @@
/**
* basic path.resolve like function for resolving ember Route-type paths
* importantly your from should look ember-y route-like (i.e. with no prefix /)
* and your to should begin with either ./ or ../
* if to begins with a / then ../ and ./ in the to are not currently
* resolved
*/
export default (from, to) => {
if (to.indexOf('/') === 0) {
return to;
}
return to
.split('/')
.reduce((prev, item, i, items) => {
if (item !== '.') {
if (item === '..') {
prev.pop();
} else if (item !== '' || i === items.length - 1) {
prev.push(item);
}
}
return prev;
}, from.split('/'))
.join('/');
};

View File

@ -12,6 +12,11 @@ DSL. The format is closely modeled on Ember's DSL and if you need to generate
Ember's DSL from this for some reason you can use one of our Debug Utilities Ember's DSL from this for some reason you can use one of our Debug Utilities
to do this. to do this.
All Route based configuration including paths, queryParams, simple redirects
and non-default templateNames are configured in this configuration format.
Please note redirects and template names use relative slash separated paths to
avoid copypasta and for future potential reuse purposes.
### Routes ### Routes
We use a specific BaseRoute as a parent Route for **all** our Routes. This contains project wide We use a specific BaseRoute as a parent Route for **all** our Routes. This contains project wide

View File

@ -0,0 +1,61 @@
import resolve from 'consul-ui/utils/path/resolve';
import { module, test } from 'qunit';
module('Unit | Utility | path/resolve', function() {
test('it resolves paths', function(assert) {
[
{
from: 'dc/intentions/create',
to: '../edit',
expected: 'dc/intentions/edit',
},
{
from: 'dc/intentions/create',
to: '../../edit',
expected: 'dc/edit',
},
{
from: 'dc/intentions/create',
to: './edit',
expected: 'dc/intentions/create/edit',
},
{
from: 'dc/intentions/create',
to: '././edit',
expected: 'dc/intentions/create/edit',
},
{
from: 'dc/intentions/create',
to: './deep/edit',
expected: 'dc/intentions/create/deep/edit',
},
{
from: 'dc/intentions/create',
to: '../deep/edit',
expected: 'dc/intentions/deep/edit',
},
{
from: 'dc/intentions/create',
to: '.././edit',
expected: 'dc/intentions/edit',
},
{
from: 'dc/intentions/create',
to: '../deep/./edit',
expected: 'dc/intentions/deep/edit',
},
{
from: 'dc/intentions/create',
to: '/deep/edit',
expected: '/deep/edit',
},
].forEach(item => {
const actual = resolve(item.from, item.to);
assert.equal(
actual,
item.expected,
`Expected '${item.from}' < '${item.to}' to equal ${item.expected}`
);
});
});
});