diff --git a/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js b/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js index b4f0976c9..2c1e882b7 100644 --- a/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js +++ b/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js @@ -26,7 +26,7 @@ }, create: { _options: { - template: 'dc/nspaces/edit', + template: '../edit', path: '/create', abilities: ['create nspaces'], }, diff --git a/ui/packages/consul-partitions/vendor/consul-partitions/routes.js b/ui/packages/consul-partitions/vendor/consul-partitions/routes.js index a60c5ba22..dc925e985 100644 --- a/ui/packages/consul-partitions/vendor/consul-partitions/routes.js +++ b/ui/packages/consul-partitions/vendor/consul-partitions/routes.js @@ -26,7 +26,7 @@ }, create: { _options: { - template: 'dc/partitions/edit', + template: '../edit', path: '/create', abilities: ['create partitions'], }, diff --git a/ui/packages/consul-ui/app/router.js b/ui/packages/consul-ui/app/router.js index 1ac7c4da1..fb6691f92 100644 --- a/ui/packages/consul-ui/app/router.js +++ b/ui/packages/consul-ui/app/router.js @@ -62,7 +62,18 @@ export const routes = merge.all( source: 'source', 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: { as: 'filter', @@ -95,7 +106,7 @@ export const routes = merge.all( }, create: { _options: { - template: 'dc/services/show/intentions/edit', + template: '../edit', path: '/create', }, }, @@ -296,7 +307,7 @@ export const routes = merge.all( }, create: { _options: { - template: 'dc/intentions/edit', + template: '../edit', path: '/create', abilities: ['create intentions'], }, @@ -320,7 +331,7 @@ export const routes = merge.all( }, folder: { _options: { - template: 'dc/kv/index', + template: '../index', path: '/*key', }, }, @@ -329,14 +340,14 @@ export const routes = merge.all( }, create: { _options: { - template: 'dc/kv/edit', + template: '../edit', path: '/*key/create', abilities: ['create kvs'], }, }, 'root-create': { _options: { - template: 'dc/kv/edit', + template: '../edit', path: '/create', abilities: ['create kvs'], }, diff --git a/ui/packages/consul-ui/app/routes/dc/services/show/instances.js b/ui/packages/consul-ui/app/routes/dc/services/show/instances.js deleted file mode 100644 index 5c27d6497..000000000 --- a/ui/packages/consul-ui/app/routes/dc/services/show/instances.js +++ /dev/null @@ -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, - }, - }; -} diff --git a/ui/packages/consul-ui/app/routing/route.js b/ui/packages/consul-ui/app/routing/route.js index 0499b849f..c50b975a8 100644 --- a/ui/packages/consul-ui/app/routing/route.js +++ b/ui/packages/consul-ui/app/routing/route.js @@ -1,6 +1,7 @@ import Route from '@ember/routing/route'; import { get, setProperties, action } from '@ember/object'; import { inject as service } from '@ember/service'; +import resolve from 'consul-ui/utils/path/resolve'; import { routes } from 'consul-ui/router'; @@ -16,7 +17,7 @@ export default class BaseRoute extends Route { const template = get(routes, `${this.routeName}._options.template`); if (typeof template !== 'undefined') { - this.templateName = template; + this.templateName = resolve(this.routeName.split('.').join('/'), template); } const queryParams = get(routes, `${this.routeName}._options.queryParams`); @@ -28,25 +29,16 @@ export default class BaseRoute extends Route { redirect(model, transition) { let to = get(routes, `${this.routeName}._options.redirect`); 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? // 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 // you feel like adding a return - this.replaceWith(`${to}`, model); + this.replaceWith( + resolve(this.routeName.split('.').join('/'), to) + .split('/') + .join('.'), + model + ); } } diff --git a/ui/packages/consul-ui/app/utils/path/resolve.js b/ui/packages/consul-ui/app/utils/path/resolve.js new file mode 100644 index 000000000..80fa362a9 --- /dev/null +++ b/ui/packages/consul-ui/app/utils/path/resolve.js @@ -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('/'); +}; diff --git a/ui/packages/consul-ui/docs/significant-patterns.mdx b/ui/packages/consul-ui/docs/significant-patterns.mdx index 657da2d5e..0cd9d4365 100644 --- a/ui/packages/consul-ui/docs/significant-patterns.mdx +++ b/ui/packages/consul-ui/docs/significant-patterns.mdx @@ -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 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 We use a specific BaseRoute as a parent Route for **all** our Routes. This contains project wide diff --git a/ui/packages/consul-ui/tests/unit/utils/path/resolve-test.js b/ui/packages/consul-ui/tests/unit/utils/path/resolve-test.js new file mode 100644 index 000000000..4c77ffc10 --- /dev/null +++ b/ui/packages/consul-ui/tests/unit/utils/path/resolve-test.js @@ -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}` + ); + }); + }); +});