refactor: 💡 remove route-action usage in admin ui (#2534)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12945
This commit is contained in:
1 parent
e842eb001d
commit
01a2d8e9a6
14 files changed
+261
-101
No files matched your search
@@ -1,69 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import Helper from '@ember/component/helper';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { join } from '@ember/runloop';
|
||||
import { runInDebug, assert } from '@ember/debug';
|
||||
import { A } from '@ember/array';
|
||||
|
||||
/**
|
||||
* This helper is a modern update on ember-route-action-helper, which is
|
||||
* now unmaintained.
|
||||
*
|
||||
* See https://github.com/DockYard/ember-route-action-helper
|
||||
*/
|
||||
export default class RouteActionHelper extends Helper {
|
||||
// =services
|
||||
|
||||
@service router;
|
||||
|
||||
// =attributes
|
||||
|
||||
get routes() {
|
||||
const { currentInfos, mapBy } = this.currentInfos;
|
||||
return A(currentInfos).mapBy(mapBy).reverse();
|
||||
}
|
||||
|
||||
get currentInfos() {
|
||||
// eslint-disable-next-line ember/no-private-routing-service
|
||||
const routerLib = this.router._router._routerMicrolib;
|
||||
return {
|
||||
currentInfos:
|
||||
routerLib.currentRouteInfos || routerLib.currentHandlerInfos,
|
||||
mapBy: (routerLib.currentRouteInfos && 'route') || 'handler',
|
||||
};
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
compute([actionName, ...outerArgs]) {
|
||||
const { action, handler } = this.getRouteWithAction(actionName);
|
||||
|
||||
runInDebug(() => {
|
||||
assert(
|
||||
`
|
||||
[boundary-core-helper-route-action]
|
||||
Unable to find action ${actionName}
|
||||
`,
|
||||
handler,
|
||||
);
|
||||
});
|
||||
|
||||
return (...innerArgs) =>
|
||||
join(handler, action, ...outerArgs.concat(innerArgs));
|
||||
}
|
||||
|
||||
getRouteWithAction(actionName) {
|
||||
let action;
|
||||
const handler = A(this.routes).find((route) => {
|
||||
const actions = route.actions || route._actions;
|
||||
action = actions[actionName];
|
||||
return typeof action === 'function';
|
||||
});
|
||||
|
||||
return { action, handler };
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export { default } from 'core/helpers/route-action';
|
||||
@@ -18,7 +18,6 @@ module.exports = {
|
||||
'is-loading',
|
||||
],
|
||||
},
|
||||
'no-route-action': false,
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
|
||||
@@ -57,4 +57,22 @@ export default class ScopesScopeGroupsGroupAddMembersController extends Controll
|
||||
async cancel() {
|
||||
await this.router.replaceWith('scopes.scope.groups.group.members');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls filterBy action located in the route.
|
||||
* @param {string} field
|
||||
* @param {[ScopeModel]} value
|
||||
*/
|
||||
@action
|
||||
callFilterBy(field, value) {
|
||||
this.send('filterBy', field, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls clearAllFilters action located in the route.
|
||||
*/
|
||||
@action
|
||||
callClearAllFilters() {
|
||||
this.send('clearAllFilters');
|
||||
}
|
||||
}
|
||||
@@ -56,4 +56,22 @@ export default class ScopesScopeRolesRoleAddPrincipalsController extends Control
|
||||
cancel() {
|
||||
this.router.replaceWith('scopes.scope.roles.role.principals');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls filterBy action located in the route.
|
||||
* @param {string} field
|
||||
* @param {[ScopeModel]} value
|
||||
*/
|
||||
@action
|
||||
callFilterBy(field, value) {
|
||||
this.send('filterBy', field, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls clearAllFilters action located in the route.
|
||||
*/
|
||||
@action
|
||||
callClearAllFilters() {
|
||||
this.send('clearAllFilters');
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,15 @@ export default class ScopesScopeWorkersIndexController extends Controller {
|
||||
return `${tag.key} = ${tag.value}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine equality between two tags based on both key and value.
|
||||
* @param {object} firstTag
|
||||
* @param {object} secondTag
|
||||
*/
|
||||
isEqual(firstTag, secondTag) {
|
||||
return firstTag.key === secondTag.key && firstTag.value === secondTag.value;
|
||||
}
|
||||
|
||||
// =actions
|
||||
|
||||
/**
|
||||
@@ -96,4 +105,30 @@ export default class ScopesScopeWorkersIndexController extends Controller {
|
||||
await this.router.replaceWith('scopes.scope.workers');
|
||||
await this.router.refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls filterBy action located in the route.
|
||||
* @param {string} field
|
||||
* @param {[object]} value
|
||||
*/
|
||||
@action
|
||||
callFilterBy(field, value) {
|
||||
this.send('filterBy', field, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls clearAllFilters action located in the route.
|
||||
*/
|
||||
@action
|
||||
callClearAllFilters() {
|
||||
this.send('clearAllFilters');
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes worker data.
|
||||
*/
|
||||
@action
|
||||
refresh() {
|
||||
this.router.refresh('scopes.scope.workers');
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
|
||||
export default class ScopesScopeWorkersRoute extends Route {
|
||||
// =services
|
||||
@@ -35,12 +34,4 @@ export default class ScopesScopeWorkersRoute extends Route {
|
||||
return this.store.query('worker', { scope_id });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes worker data.
|
||||
*/
|
||||
@action
|
||||
refresh() {
|
||||
return super.refresh(...arguments);
|
||||
}
|
||||
}
|
||||
@@ -98,11 +98,6 @@ export default class ScopesScopeWorkersIndexRoute extends Route {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
@action
|
||||
isEqual(firstTag, secondTag) {
|
||||
return firstTag.key === secondTag.key && firstTag.value === secondTag.value;
|
||||
}
|
||||
|
||||
setupController(controller) {
|
||||
const scope = this.modelFor('scopes.scope');
|
||||
super.setupController(...arguments);
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
@name={{filter.name}}
|
||||
@items={{this.flatSortedScopes}}
|
||||
@selectedItems={{filter.selectedValue}}
|
||||
@onChange={{route-action 'filterBy' filter.name}}
|
||||
@onChange={{fn this.callFilterBy filter.name}}
|
||||
as |group|
|
||||
>
|
||||
<li
|
||||
@@ -72,7 +72,7 @@
|
||||
<Rose::Button
|
||||
@style='inline-link-action'
|
||||
@iconLeft='flight-icons/svg/x-16'
|
||||
{{on 'click' (route-action 'clearAllFilters')}}
|
||||
{{on 'click' this.callClearAllFilters}}
|
||||
>{{t 'actions.clear-all-filters'}}
|
||||
</Rose::Button>
|
||||
{{/if}}
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
@name={{filter.name}}
|
||||
@items={{this.flatSortedScopes}}
|
||||
@selectedItems={{filter.selectedValue}}
|
||||
@onChange={{route-action 'filterBy' filter.name}}
|
||||
@onChange={{fn this.callFilterBy filter.name}}
|
||||
as |group|
|
||||
>
|
||||
<li
|
||||
@@ -72,7 +72,7 @@
|
||||
<Rose::Button
|
||||
@style='inline-link-action'
|
||||
@iconLeft='flight-icons/svg/x-16'
|
||||
{{on 'click' (route-action 'clearAllFilters')}}
|
||||
{{on 'click' this.callClearAllFilters}}
|
||||
>{{t 'actions.clear-all-filters'}}
|
||||
</Rose::Button>
|
||||
{{/if}}
|
||||
|
||||
@@ -55,8 +55,8 @@
|
||||
@name={{key}}
|
||||
@items={{tags}}
|
||||
@selectedItems={{filter.selectedValue}}
|
||||
@onChange={{route-action 'filterBy' filter.name}}
|
||||
@itemEqualityFunc={{route-action 'isEqual'}}
|
||||
@onChange={{fn this.callFilterBy filter.name}}
|
||||
@itemEqualityFunc={{this.isEqual}}
|
||||
as |group|
|
||||
>
|
||||
<dropdown.item class='indent-label-1'>
|
||||
@@ -78,7 +78,7 @@
|
||||
<Rose::Button
|
||||
@style='inline-link-action'
|
||||
@iconLeft='flight-icons/svg/x-16'
|
||||
{{on 'click' (route-action 'clearAllFilters')}}
|
||||
{{on 'click' this.callClearAllFilters}}
|
||||
>{{t 'actions.clear-all-filters'}}
|
||||
</Rose::Button>
|
||||
{{/if}}
|
||||
@@ -86,7 +86,7 @@
|
||||
</toolbar.primary>
|
||||
|
||||
<toolbar.secondary>
|
||||
<ToolbarRefresher @onClick={{route-action 'refresh'}} />
|
||||
<ToolbarRefresher @onClick={{this.refresh}} />
|
||||
</toolbar.secondary>
|
||||
|
||||
</Rose::Toolbar>
|
||||
|
||||
@@ -4,18 +4,111 @@
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'admin/tests/helpers';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import { visit } from '@ember/test-helpers';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
|
||||
module(
|
||||
'Unit | Controller | scopes/scope/groups/group/add-members',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let controller = this.owner.lookup(
|
||||
let store;
|
||||
let controller;
|
||||
|
||||
const instances = {
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
},
|
||||
group: null,
|
||||
user: null,
|
||||
};
|
||||
|
||||
const urls = {
|
||||
globalScope: null,
|
||||
addMembers: null,
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
authenticateSession({});
|
||||
store = this.owner.lookup('service:store');
|
||||
controller = this.owner.lookup(
|
||||
'controller:scopes/scope/groups/group/add-members',
|
||||
);
|
||||
|
||||
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
||||
instances.scopes.org = this.server.create('scope', {
|
||||
type: 'org',
|
||||
scope: { id: 'global', type: 'global' },
|
||||
});
|
||||
instances.group = this.server.create('group', {
|
||||
scope: instances.scopes.global,
|
||||
});
|
||||
instances.user = this.server.create('user', {
|
||||
scope: instances.scopes.global,
|
||||
});
|
||||
|
||||
urls.globalScope = `/scopes/global`;
|
||||
urls.addMembers = `${urls.globalScope}/groups/${instances.group.id}/add-members`;
|
||||
});
|
||||
|
||||
test('it exists', function (assert) {
|
||||
assert.ok(controller);
|
||||
});
|
||||
|
||||
test('flatSortedScopes returns array of sorted scopes', async function (assert) {
|
||||
const globalScope = await store.findRecord(
|
||||
'scope',
|
||||
instances.scopes.global.id,
|
||||
);
|
||||
const orgScope = await store.findRecord('scope', instances.scopes.org.id);
|
||||
await visit(urls.addMembers);
|
||||
|
||||
assert.deepEqual(controller.flatSortedScopes, [globalScope, orgScope]);
|
||||
});
|
||||
|
||||
test('addMembers action adds users to specified model', async function (assert) {
|
||||
await visit(urls.addMembers);
|
||||
const group = await store.findRecord('group', instances.group.id);
|
||||
const user = await store.findRecord('user', instances.user.id);
|
||||
|
||||
assert.deepEqual(group.members, []);
|
||||
|
||||
await controller.addMembers(group, [instances.user.id]);
|
||||
|
||||
assert.deepEqual(group.members, [user]);
|
||||
});
|
||||
|
||||
test('callFilterBy action adds expected property values to route', async function (assert) {
|
||||
const route = this.owner.lookup(
|
||||
'route:scopes/scope/groups/group/add-members',
|
||||
);
|
||||
await visit(urls.addMembers);
|
||||
const scope = await store.findRecord('scope', instances.scopes.global.id);
|
||||
|
||||
assert.notOk(route.scope);
|
||||
|
||||
controller.callFilterBy('scope', [scope]);
|
||||
|
||||
assert.deepEqual(route.scope, [scope]);
|
||||
});
|
||||
|
||||
test('callClearAllFilters action removes all filter values from route', async function (assert) {
|
||||
const route = this.owner.lookup(
|
||||
'route:scopes/scope/groups/group/add-members',
|
||||
);
|
||||
await visit(urls.addMembers);
|
||||
const scope = await store.findRecord('scope', instances.scopes.global.id);
|
||||
route.scope = [scope];
|
||||
|
||||
assert.deepEqual(route.scope, [scope]);
|
||||
|
||||
controller.callClearAllFilters();
|
||||
|
||||
assert.deepEqual(route.scope, []);
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -21,6 +21,8 @@ module(
|
||||
const instances = {
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
project: null,
|
||||
},
|
||||
role: null,
|
||||
user: null,
|
||||
@@ -39,6 +41,14 @@ module(
|
||||
);
|
||||
|
||||
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
||||
instances.scopes.org = this.server.create('scope', {
|
||||
type: 'org',
|
||||
scope: { id: 'global', type: 'global' },
|
||||
});
|
||||
instances.scopes.project = this.server.create('scope', {
|
||||
type: 'project',
|
||||
scope: { id: instances.scopes.org.id, type: 'org' },
|
||||
});
|
||||
instances.role = this.server.create('role', {
|
||||
scopeId: 'global',
|
||||
});
|
||||
@@ -54,6 +64,25 @@ module(
|
||||
assert.ok(controller);
|
||||
});
|
||||
|
||||
test('flatSortedScopes returns array of sorted scopes', async function (assert) {
|
||||
const globalScope = await store.findRecord(
|
||||
'scope',
|
||||
instances.scopes.global.id,
|
||||
);
|
||||
const orgScope = await store.findRecord('scope', instances.scopes.org.id);
|
||||
const projectScope = await store.findRecord(
|
||||
'scope',
|
||||
instances.scopes.project.id,
|
||||
);
|
||||
await visit(urls.addPrincipals);
|
||||
|
||||
assert.deepEqual(controller.flatSortedScopes, [
|
||||
globalScope,
|
||||
orgScope,
|
||||
projectScope,
|
||||
]);
|
||||
});
|
||||
|
||||
test('addPrincipals action adds principals to specified model', async function (assert) {
|
||||
await visit(urls.addPrincipals);
|
||||
const role = await store.findRecord('role', instances.role.id);
|
||||
@@ -70,5 +99,34 @@ module(
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('callFilterBy action adds expected property values to route', async function (assert) {
|
||||
const route = this.owner.lookup(
|
||||
'route:scopes/scope/roles/role/add-principals',
|
||||
);
|
||||
await visit(urls.addPrincipals);
|
||||
const scope = await store.findRecord('scope', instances.scopes.global.id);
|
||||
|
||||
assert.notOk(route.scope);
|
||||
|
||||
controller.callFilterBy('scope', [scope]);
|
||||
|
||||
assert.deepEqual(route.scope, [scope]);
|
||||
});
|
||||
|
||||
test('callClearAllFilters action removes all filter values from route', async function (assert) {
|
||||
const route = this.owner.lookup(
|
||||
'route:scopes/scope/roles/role/add-principals',
|
||||
);
|
||||
await visit(urls.addPrincipals);
|
||||
const scope = await store.findRecord('scope', instances.scopes.global.id);
|
||||
route.scope = [scope];
|
||||
|
||||
assert.deepEqual(route.scope, [scope]);
|
||||
|
||||
controller.callClearAllFilters();
|
||||
|
||||
assert.deepEqual(route.scope, []);
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -39,6 +39,7 @@ module('Unit | Controller | scopes/scope/workers/index', function (hooks) {
|
||||
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
||||
instances.worker = this.server.create('worker', {
|
||||
scope: instances.scopes.global,
|
||||
config_tags: { type: ['dev'] },
|
||||
});
|
||||
|
||||
urls.globalScope = `/scopes/global`;
|
||||
@@ -81,4 +82,31 @@ module('Unit | Controller | scopes/scope/workers/index', function (hooks) {
|
||||
|
||||
assert.strictEqual(getWorkerCount(), workerCount - 1);
|
||||
});
|
||||
|
||||
test('callFilterBy action adds expected property values to route', async function (assert) {
|
||||
const route = this.owner.lookup('route:scopes/scope/workers/index');
|
||||
await visit(urls.workers);
|
||||
const tag = { key: 'type', value: 'dev', type: 'config' };
|
||||
|
||||
assert.notOk(route.tags);
|
||||
|
||||
controller.callFilterBy('tags', [tag]);
|
||||
|
||||
assert.deepEqual(route.tags, [tag]);
|
||||
});
|
||||
|
||||
test('callClearAllFilters action removes all filter values from route', async function (assert) {
|
||||
const route = this.owner.lookup('route:scopes/scope/workers/index');
|
||||
await visit(urls.workers);
|
||||
const tag = { key: 'type', value: 'dev', type: 'config' };
|
||||
controller.callFilterBy('tags', [tag]);
|
||||
|
||||
assert.deepEqual(route.tags, [
|
||||
{ key: 'type', value: 'dev', type: 'config' },
|
||||
]);
|
||||
|
||||
controller.callClearAllFilters();
|
||||
|
||||
assert.deepEqual(route.tags, []);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user