diff --git a/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js b/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js index b4f0976c96..2c1e882b7b 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 a60c5ba22f..dc925e9856 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 1ac7c4da16..fb6691f921 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 5c27d6497c..0000000000 --- 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 0499b849f3..c50b975a85 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 0000000000..80fa362a92 --- /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 657da2d5ee..0cd9d43655 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 0000000000..4c77ffc10d --- /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}` + ); + }); + }); +});