diff --git a/ui/core/app/controllers/scopes/scope/groups/group/add-members.js b/ui/core/app/controllers/scopes/scope/groups/group/add-members.js new file mode 100644 index 000000000..7a94c1034 --- /dev/null +++ b/ui/core/app/controllers/scopes/scope/groups/group/add-members.js @@ -0,0 +1,20 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeGroupsGroupAddMembersController extends Controller { + + // =services + + @service intl; + + // =attributes + + /** + * Translated new group breadcrumb + * @type {string} + */ + get breadCrumb() { + return this.intl.t('actions.add-members'); + } + +} diff --git a/ui/core/app/router.js b/ui/core/app/router.js index 6800b5103..a8699d517 100644 --- a/ui/core/app/router.js +++ b/ui/core/app/router.js @@ -56,6 +56,7 @@ Router.map(function () { this.route('groups', function () { this.route('group', { path: ':group_id' }, function () { this.route('members'); + this.route('add-members'); }); this.route('new'); }); diff --git a/ui/core/app/routes/scopes/scope/groups/group.js b/ui/core/app/routes/scopes/scope/groups/group.js index 6231ab13f..bd638b343 100644 --- a/ui/core/app/routes/scopes/scope/groups/group.js +++ b/ui/core/app/routes/scopes/scope/groups/group.js @@ -1,6 +1,7 @@ import Route from '@ember/routing/route'; export default class ScopesScopeGroupsGroupRoute extends Route { + // =methods /** @@ -9,10 +10,33 @@ export default class ScopesScopeGroupsGroupRoute extends Route { * @param {string} params.group_id * @return {groupModel} */ - async model({ group_id }) { + model({ group_id }) { const { id: scopeID } = this.modelFor('scopes.scope'); return this.store.findRecord('group', group_id, { adapterOptions: { scopeID }, }); } + + /** + * Renders the route-set specific page sections + * @override + */ + renderTemplate() { + super.renderTemplate(...arguments); + + this.render('scopes/scope/groups/group/-header', { + into: 'scopes/scope/groups/group', + outlet: 'header' + }); + + this.render('scopes/scope/groups/group/-actions', { + into: 'scopes/scope/groups/group', + outlet: 'actions' + }); + + this.render('scopes/scope/groups/group/-navigation', { + into: 'scopes/scope/groups/group', + outlet: 'navigation' + }); + } } diff --git a/ui/core/app/routes/scopes/scope/groups/group/add-members.js b/ui/core/app/routes/scopes/scope/groups/group/add-members.js new file mode 100644 index 000000000..7ad1a8280 --- /dev/null +++ b/ui/core/app/routes/scopes/scope/groups/group/add-members.js @@ -0,0 +1,72 @@ +import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; +import { action } from '@ember/object'; + +export default class ScopesScopeGroupsGroupAddMembersRoute extends Route { + + // =services + + @service intl; + @service notify; + + // =methods + + /** + * Emtpy out any previously loaded users. + */ + beforeModel() { + this.store.unloadAll('user'); + } + + /** + * Renders the route-set specific page sections + * @override + */ + renderTemplate() { + super.renderTemplate(...arguments); + + this.render('scopes/scope/groups/group/add-members/-header', { + into: 'scopes/scope/groups/group', + outlet: 'header' + }); + + this.render('-empty', { + into: 'scopes/scope/groups/group', + outlet: 'actions' + }); + + this.render('-empty', { + into: 'scopes/scope/groups/group', + outlet: 'navigation' + }); + } + + // =actions + + /** + * Adds members to the group and saves, replaces with the members index + * route, and notifies the user of success or error. + * @param {GroupModel} group + * @param {[string]} userIDs + */ + @action + async addMembers(group, userIDs) { + try { + await group.addMembers(userIDs); + await this.replaceWith('scopes.scope.groups.group.members'); + this.notify.success(this.intl.t('notify.save-success')); + } catch (error) { + // TODO: replace with translated strings + this.notify.error(error.message, { closeAfter: null }); + } + } + + /** + * Redirect to group members as if nothing ever happened. + */ + @action + cancel() { + this.replaceWith('scopes.scope.groups.group.members'); + } + +} diff --git a/ui/core/app/templates/scopes/scope/groups/group.hbs b/ui/core/app/templates/scopes/scope/groups/group.hbs index bb0ba8b8a..2a878ff51 100644 --- a/ui/core/app/templates/scopes/scope/groups/group.hbs +++ b/ui/core/app/templates/scopes/scope/groups/group.hbs @@ -7,30 +7,15 @@ -

{{t "resources.group"}}

+ {{outlet "header"}}
- - - {{t 'titles.details'}} - - - {{t 'titles.members'}} - - + {{outlet "navigation"}} - - - {{t 'actions.delete-group'}} - - + {{outlet "actions"}} diff --git a/ui/core/app/templates/scopes/scope/groups/group/-actions.hbs b/ui/core/app/templates/scopes/scope/groups/group/-actions.hbs new file mode 100644 index 000000000..1ebd9d2c6 --- /dev/null +++ b/ui/core/app/templates/scopes/scope/groups/group/-actions.hbs @@ -0,0 +1,12 @@ + + + {{t "actions.add-members"}} + + + {{t 'actions.delete-group'}} + + diff --git a/ui/core/app/templates/scopes/scope/groups/group/-header.hbs b/ui/core/app/templates/scopes/scope/groups/group/-header.hbs new file mode 100644 index 000000000..6631940a3 --- /dev/null +++ b/ui/core/app/templates/scopes/scope/groups/group/-header.hbs @@ -0,0 +1 @@ +

{{t "resources.group"}}

diff --git a/ui/core/app/templates/scopes/scope/groups/group/-navigation.hbs b/ui/core/app/templates/scopes/scope/groups/group/-navigation.hbs new file mode 100644 index 000000000..6dc45b637 --- /dev/null +++ b/ui/core/app/templates/scopes/scope/groups/group/-navigation.hbs @@ -0,0 +1,8 @@ + + + {{t 'titles.details'}} + + + {{t 'titles.members'}} + + diff --git a/ui/core/app/templates/scopes/scope/groups/group/add-members.hbs b/ui/core/app/templates/scopes/scope/groups/group/add-members.hbs new file mode 100644 index 000000000..d8ca3dcef --- /dev/null +++ b/ui/core/app/templates/scopes/scope/groups/group/add-members.hbs @@ -0,0 +1,3 @@ +{{title (t "actions.add-members")}} + +{{outlet}} diff --git a/ui/core/app/templates/scopes/scope/groups/group/add-members/-header.hbs b/ui/core/app/templates/scopes/scope/groups/group/add-members/-header.hbs new file mode 100644 index 000000000..48dca079b --- /dev/null +++ b/ui/core/app/templates/scopes/scope/groups/group/add-members/-header.hbs @@ -0,0 +1 @@ +

{{t "actions.add-members"}}

diff --git a/ui/core/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js b/ui/core/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js new file mode 100644 index 000000000..17daef1db --- /dev/null +++ b/ui/core/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | scopes/scope/groups/group/add-members', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let controller = this.owner.lookup('controller:scopes/scope/groups/group/add-members'); + assert.ok(controller); + }); +}); diff --git a/ui/core/tests/unit/routes/scopes/scope/groups/group/add-members-test.js b/ui/core/tests/unit/routes/scopes/scope/groups/group/add-members-test.js new file mode 100644 index 000000000..8500b2957 --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/groups/group/add-members-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/groups/group/add-members', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/groups/group/add-members'); + assert.ok(route); + }); +}); diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index d33ec0514..c5b005d53 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -23,6 +23,7 @@ actions: add-host-set: Create Host Set add-host: Create Host add-host-sets: Add Host Sets + add-members: Add Members auth: titles: no-scopes: No Scopes Available