feat: 🎸 add initial add-principals flow

This commit is contained in:
Randall Morey committed 2020-08-31 15:52:50 -04:00
1 parent 67de48a137
commit 7fecae2796
7 files changed
+194 -1

No files matched your search

@@ -0,0 +1,66 @@
{{#if this.hasAvailablePrincipals}}
<Rose::Form
class="full-width"
@onSubmit={{fn this.submit @submit}}
@cancel={{@cancel}}
@disabled={{@model.isSaving}}
@error={{@model.errors.base}}
as |form|
>
<form.actions
@submitText={{t "actions.add-principals"}}
@cancelText={{t "actions.cancel"}} />
<Rose::Table as |table|>
<table.header as |header|>
<header.row as |row|>
<row.headerCell>{{t 'form.label.id'}}</row.headerCell>
<row.headerCell>{{t 'form.label.name'}}</row.headerCell>
<row.headerCell>{{t 'form.label.type'}}</row.headerCell>
</header.row>
</table.header>
<table.body as |body|>
{{#each @groups as |group|}}
<body.row as |row|>
<row.cell>
<form.checkbox
@label={{group.id}}
@description={{group.description}}
onChange={{fn this.togglePrincipal group}} />
</row.cell>
<row.cell>{{group.name}}</row.cell>
<row.cell>
<Rose::Badge>{{t "resources.group"}}</Rose::Badge>
</row.cell>
</body.row>
{{/each}}
{{#each @users as |user|}}
<body.row as |row|>
<row.cell>
<form.checkbox
@label={{user.id}}
@description={{user.description}}
onChange={{fn this.togglePrincipal user}} />
</row.cell>
<row.cell>{{user.name}}</row.cell>
<row.cell>
<Rose::Badge>{{t "resources.user"}}</Rose::Badge>
</row.cell>
</body.row>
{{/each}}
</table.body>
</Rose::Table>
</Rose::Form>
{{/if}}
{{#unless this.hasAvailablePrincipals}}
<Rose::Layout::Centered>
<Rose::Message @title={{t "titles.no-principals"}} as |message|>
<message.description>
{{t "descriptions.no-principals"}}
</message.description>
</Rose::Message>
</Rose::Layout::Centered>
{{/unless}}
@@ -0,0 +1,38 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { A } from '@ember/array';
export default class FormRoleAddPrincipalsComponent extends Component {
// =properties
/**
* Array of selected principal IDs.
* @type {EmberArray}
*/
selectedPrincipalIDs = A();
/**
* True if there are users or groups not yet added to this role.
* TODO: this must be computed on users, groups, and role principals.
* @type {boolean}
*/
hasAvailablePrincipals = true;
// =actions
@action
togglePrincipal(principal) {
if (!this.selectedPrincipalIDs.includes(principal.id)) {
this.selectedPrincipalIDs.addObject(principal.id);
} else {
this.selectedPrincipalIDs.removeObject(principal.id);
}
}
@action
submit(fn) {
fn(this.selectedPrincipalIDs);
}
}
@@ -1,9 +1,37 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { hash } from 'rsvp';
export default class ScopesScopeRolesRoleAddPrincipalsRoute extends Route {
// =services
@service intl;
@service notify;
// =methods
/**
* Emtpy out any previously loaded users and groups
* (collectively, principals).
*/
beforeModel() {
this.store.unloadAll('user');
this.store.unloadAll('group');
}
model() {
const role = this.modelFor('scopes.scope.roles.role');
const { scopeID } = role;
const options = { adapterOptions: { scopeID } };
return hash({
role,
users: this.store.findAll('user', options),
groups: this.store.findAll('group', options)
});
}
/**
* Empties the actions and navigation outlets and renders a custom header.
* @override
@@ -26,4 +54,30 @@ export default class ScopesScopeRolesRoleAddPrincipalsRoute extends Route {
outlet: 'navigation'
});
}
/**
* Saves principal IDs into the role via the API.
* @param {RoleModel} role
* @param {[string]} principalIDs
*/
@action
async addPrincipals(role, principalIDs) {
try {
await role.addPrincipals(principalIDs);
this.replaceWith('scopes.scope.roles.role.principals');
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 role principals as if nothing ever happened.
*/
@action
cancel() {
this.replaceWith('scopes.scope.roles.role.principals');
}
}
@@ -1,3 +1,9 @@
{{title (t "actions.add-principals")}}
{{outlet}}
<Form::Role::AddPrincipals
@model={{@model.role}}
@users={{@model.users}}
@groups={{@model.groups}}
@submit={{route-action "addPrincipals" @model.role}}
@cancel={{route-action "cancel"}}
/>
@@ -12,5 +12,6 @@ export default Factory.extend({
created_time: () => date.recent(),
updated_time: () => date.recent(),
disabled: () => random.boolean(),
version: () => random.number(),
});
+16
View File
@@ -237,4 +237,20 @@ module('Acceptance | roles', function (hooks) {
test('new grants can be added and saved or canceled', async function (assert) {
assert.expect(0);
});
test('viewing role principals', async function (assert) {
assert.expect(0);
});
test('can delete a principal', async function(assert) {
assert.expect(0);
});
test('select and save principals to add', async function (assert) {
assert.expect(0);
});
test('select and cancel principals to add', async function (assert) {
assert.expect(0);
});
});
@@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
// import { render } from '@ember/test-helpers';
// import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | form/role/add-principals', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
assert.expect(0);
});
});