diff --git a/addons/core/addon/helpers/route-action.js b/addons/core/addon/helpers/route-action.js
deleted file mode 100644
index e69a376cc..000000000
--- a/addons/core/addon/helpers/route-action.js
+++ /dev/null
@@ -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 };
- }
-}
diff --git a/addons/core/app/helpers/route-action.js b/addons/core/app/helpers/route-action.js
deleted file mode 100644
index eaa68564a..000000000
--- a/addons/core/app/helpers/route-action.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Copyright (c) HashiCorp, Inc.
- * SPDX-License-Identifier: BUSL-1.1
- */
-
-export { default } from 'core/helpers/route-action';
diff --git a/ui/admin/.template-lintrc.js b/ui/admin/.template-lintrc.js
index 05e4ca99d..71a2c0c5f 100644
--- a/ui/admin/.template-lintrc.js
+++ b/ui/admin/.template-lintrc.js
@@ -18,7 +18,6 @@ module.exports = {
'is-loading',
],
},
- 'no-route-action': false,
},
overrides: [
{
diff --git a/ui/admin/app/controllers/scopes/scope/groups/group/add-members.js b/ui/admin/app/controllers/scopes/scope/groups/group/add-members.js
index 6db68d193..4e1621695 100644
--- a/ui/admin/app/controllers/scopes/scope/groups/group/add-members.js
+++ b/ui/admin/app/controllers/scopes/scope/groups/group/add-members.js
@@ -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');
+ }
}
diff --git a/ui/admin/app/controllers/scopes/scope/roles/role/add-principals.js b/ui/admin/app/controllers/scopes/scope/roles/role/add-principals.js
index 9d710c839..83635e5fd 100644
--- a/ui/admin/app/controllers/scopes/scope/roles/role/add-principals.js
+++ b/ui/admin/app/controllers/scopes/scope/roles/role/add-principals.js
@@ -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');
+ }
}
diff --git a/ui/admin/app/controllers/scopes/scope/workers/index.js b/ui/admin/app/controllers/scopes/scope/workers/index.js
index 0619700d8..23219bb41 100644
--- a/ui/admin/app/controllers/scopes/scope/workers/index.js
+++ b/ui/admin/app/controllers/scopes/scope/workers/index.js
@@ -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');
+ }
}
diff --git a/ui/admin/app/routes/scopes/scope/workers.js b/ui/admin/app/routes/scopes/scope/workers.js
index 6c96955b1..dd6c25ae5 100644
--- a/ui/admin/app/routes/scopes/scope/workers.js
+++ b/ui/admin/app/routes/scopes/scope/workers.js
@@ -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);
- }
}
diff --git a/ui/admin/app/routes/scopes/scope/workers/index.js b/ui/admin/app/routes/scopes/scope/workers/index.js
index b1cb00cc9..3a253cf5f 100644
--- a/ui/admin/app/routes/scopes/scope/workers/index.js
+++ b/ui/admin/app/routes/scopes/scope/workers/index.js
@@ -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);
diff --git a/ui/admin/app/templates/scopes/scope/groups/group/add-members.hbs b/ui/admin/app/templates/scopes/scope/groups/group/add-members.hbs
index 6cbf9e82f..7d89f7b42 100644
--- a/ui/admin/app/templates/scopes/scope/groups/group/add-members.hbs
+++ b/ui/admin/app/templates/scopes/scope/groups/group/add-members.hbs
@@ -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|
>
{{t 'actions.clear-all-filters'}}
{{/if}}
diff --git a/ui/admin/app/templates/scopes/scope/roles/role/add-principals.hbs b/ui/admin/app/templates/scopes/scope/roles/role/add-principals.hbs
index fba47331e..3a4447a27 100644
--- a/ui/admin/app/templates/scopes/scope/roles/role/add-principals.hbs
+++ b/ui/admin/app/templates/scopes/scope/roles/role/add-principals.hbs
@@ -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|
>
{{t 'actions.clear-all-filters'}}
{{/if}}
diff --git a/ui/admin/app/templates/scopes/scope/workers/index.hbs b/ui/admin/app/templates/scopes/scope/workers/index.hbs
index 0fc830bf8..bf0879ce9 100644
--- a/ui/admin/app/templates/scopes/scope/workers/index.hbs
+++ b/ui/admin/app/templates/scopes/scope/workers/index.hbs
@@ -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|
>
@@ -78,7 +78,7 @@
{{t 'actions.clear-all-filters'}}
{{/if}}
@@ -86,7 +86,7 @@
-
+
diff --git a/ui/admin/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js b/ui/admin/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js
index ce58b1a34..c621b608f 100644
--- a/ui/admin/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js
+++ b/ui/admin/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js
@@ -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, []);
+ });
},
);
diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js
index bfd6f25ab..eba139e05 100644
--- a/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js
+++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js
@@ -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, []);
+ });
},
);
diff --git a/ui/admin/tests/unit/controllers/scopes/scope/workers/index-test.js b/ui/admin/tests/unit/controllers/scopes/scope/workers/index-test.js
index 4466e12c1..c80f0a8e4 100644
--- a/ui/admin/tests/unit/controllers/scopes/scope/workers/index-test.js
+++ b/ui/admin/tests/unit/controllers/scopes/scope/workers/index-test.js
@@ -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, []);
+ });
});