diff --git a/admin/app/components/organizations/invitations.gjs b/admin/app/components/organizations/invitations.gjs
index 7ee5c105181..16ceead34b2 100644
--- a/admin/app/components/organizations/invitations.gjs
+++ b/admin/app/components/organizations/invitations.gjs
@@ -3,9 +3,11 @@ import { fn } from '@ember/helper';
import { service } from '@ember/service';
import Component from '@glimmer/component';
import dayjsFormat from 'ember-dayjs/helpers/dayjs-format';
+import { t } from 'ember-intl';
export default class OrganizationInvitations extends Component {
@service accessControl;
+ @service intl;
get sortedInvitations() {
return this.args.invitations.sortBy('updatedAt').reverse();
@@ -38,16 +40,25 @@ export default class OrganizationInvitations extends Component {
{{dayjsFormat invitation.updatedAt "DD/MM/YYYY [-] HH:mm"}} |
{{#if this.accessControl.hasAccessToOrganizationActionsScope}}
-
- Annuler l’invitation
-
+
|
{{/if}}
diff --git a/admin/app/controllers/authenticated/organizations/get/invitations.js b/admin/app/controllers/authenticated/organizations/get/invitations.js
index f09ce3684c7..ceaeb8494f0 100644
--- a/admin/app/controllers/authenticated/organizations/get/invitations.js
+++ b/admin/app/controllers/authenticated/organizations/get/invitations.js
@@ -14,6 +14,7 @@ export default class InvitationsController extends Controller {
@service store;
@service accessControl;
@service errorResponseHandler;
+ @service intl;
CUSTOM_ERROR_MESSAGES = {
DEFAULT: 'Une erreur s’est produite, veuillez réessayer.',
@@ -47,6 +48,27 @@ export default class InvitationsController extends Controller {
this.isLoading = false;
}
+ @action
+ async sendNewInvitation(organizationInvitation) {
+ this.isLoading = true;
+ try {
+ await this.store.queryRecord('organization-invitation', {
+ email: organizationInvitation.email,
+ lang: organizationInvitation.lang,
+ role: organizationInvitation.role,
+ organizationId: this.model.organization.id,
+ });
+ this.pixToast.sendSuccessNotification({
+ message: this.intl.t('common.invitations.send-new-confirm', {
+ invitationEmail: organizationInvitation.email,
+ }),
+ });
+ } catch (error) {
+ this.errorResponseHandler.notify(error, this.CUSTOM_ERROR_MESSAGES);
+ }
+ this.isLoading = false;
+ }
+
_isEmailToInviteValid(email) {
if (!email) {
this.userEmailToInviteError = 'Ce champ est requis.';
diff --git a/admin/app/styles/components/organization-invitations.scss b/admin/app/styles/components/organization-invitations.scss
index 77a1ab11b7b..b94c680f807 100644
--- a/admin/app/styles/components/organization-invitations.scss
+++ b/admin/app/styles/components/organization-invitations.scss
@@ -12,7 +12,14 @@
text-align: center;
}
- &-actions__button {
+ &__actions-buttons {
+ display: flex;
+ flex-direction: column;
+
+ button {
+ width: 13rem;
+ margin: 0.2rem;
+ }
svg {
margin-right: 6px;
diff --git a/admin/app/templates/authenticated/organizations/get/invitations.hbs b/admin/app/templates/authenticated/organizations/get/invitations.hbs
index 9a8b16d8a67..6767067425c 100644
--- a/admin/app/templates/authenticated/organizations/get/invitations.hbs
+++ b/admin/app/templates/authenticated/organizations/get/invitations.hbs
@@ -9,5 +9,6 @@
{{/if}}
\ No newline at end of file
diff --git a/admin/tests/integration/components/organizations/invitations-test.gjs b/admin/tests/integration/components/organizations/invitations-test.gjs
index 047c8a04008..39403f9c008 100644
--- a/admin/tests/integration/components/organizations/invitations-test.gjs
+++ b/admin/tests/integration/components/organizations/invitations-test.gjs
@@ -2,6 +2,7 @@ import { render } from '@1024pix/ember-testing-library';
import Service from '@ember/service';
import { click } from '@ember/test-helpers';
import dayjs from 'dayjs';
+import { setupIntl } from 'ember-intl/test-support';
import { setupRenderingTest } from 'ember-qunit';
import Invitations from 'pix-admin/components/organizations/invitations';
import { module, test } from 'qunit';
@@ -9,6 +10,7 @@ import sinon from 'sinon';
module('Integration | Component | organization-invitations', function (hooks) {
setupRenderingTest(hooks);
+ setupIntl(hooks, 'fr');
module('when the admin member have access to organization scope', function (hooks) {
hooks.beforeEach(function () {
@@ -40,6 +42,7 @@ module('Integration | Component | organization-invitations', function (hooks) {
{
email: 'riri@example.net',
role: 'ADMIN',
+ lang: 'fr',
roleInFrench: 'Administrateur',
updatedAt: dayjs('2019-10-08T10:50:00Z').utcOffset(2),
},
@@ -47,11 +50,13 @@ module('Integration | Component | organization-invitations', function (hooks) {
email: 'fifi@example.net',
role: 'MEMBER',
roleInFrench: 'Membre',
+ lang: 'en',
updatedAt: dayjs('2019-10-08T10:50:00Z').utcOffset(2),
},
{
email: 'loulou@example.net',
role: null,
+ lang: 'nl',
roleInFrench: '-',
updatedAt: dayjs('2019-10-08T10:50:00Z').utcOffset(2),
},
diff --git a/admin/tests/unit/controllers/authenticated/organizations/get/invitations-test.js b/admin/tests/unit/controllers/authenticated/organizations/get/invitations-test.js
index a693319d0c4..bebeaf5e482 100644
--- a/admin/tests/unit/controllers/authenticated/organizations/get/invitations-test.js
+++ b/admin/tests/unit/controllers/authenticated/organizations/get/invitations-test.js
@@ -96,4 +96,48 @@ module('Unit | Controller | authenticated/organizations/get/invitations', functi
assert.ok(notifyStub.calledWithExactly(anError, customErrors));
});
});
+
+ module('#sendNewInvitation', function () {
+ test('sends a new invitation', function (assert) {
+ // given
+ const queryRecordStub = sinon.stub();
+ store.queryRecord = queryRecordStub;
+ controller.model = { organization: { id: 1 } };
+ const organizationInvitation = { email: 'test@example.net', lang: 'en', role: 'MEMBER' };
+
+ // when
+ controller.sendNewInvitation(organizationInvitation);
+
+ // then
+ assert.ok(
+ queryRecordStub.calledWith('organization-invitation', {
+ ...organizationInvitation,
+ organizationId: 1,
+ }),
+ );
+ });
+
+ test('When an error occurs, it should send a notification error', async function (assert) {
+ // given
+ const controller = this.owner.lookup('controller:authenticated/organizations/get/invitations');
+ const store = this.owner.lookup('service:store');
+ const anError = Symbol('an error');
+ store.queryRecord = sinon.stub().rejects(anError);
+ const notifyStub = sinon.stub();
+ class ErrorResponseHandler extends Service {
+ notify = notifyStub;
+ }
+ this.owner.register('service:error-response-handler', ErrorResponseHandler);
+ const customErrors = Symbol('custom errors');
+ controller.CUSTOM_ERROR_MESSAGES = customErrors;
+ controller.model = { organization: { id: 1 } };
+ const organizationInvitation = { email: 'test@example.net', lang: 'en', role: 'MEMBER' };
+
+ // when
+ await controller.sendNewInvitation(organizationInvitation);
+
+ // then
+ assert.ok(notifyStub.calledWithExactly(anError, customErrors));
+ });
+ });
});
diff --git a/admin/translations/en.json b/admin/translations/en.json
index 0ef9e7921f2..daf8f7a209c 100644
--- a/admin/translations/en.json
+++ b/admin/translations/en.json
@@ -55,6 +55,11 @@
"mandatory": "Champ obligatoire",
"mandatory-fields": "The fields marked ''*'' are required"
},
+ "invitations": {
+ "send-new": "Resend the invitation",
+ "send-new-confirm": "An email has been sent to {invitationEmail}",
+ "send-new-label": "Resend the invitation to {invitationEmail}"
+ },
"notifications": {
"close-button": {
"extra-information": "Close notification"
diff --git a/admin/translations/fr.json b/admin/translations/fr.json
index 45d7fc901c2..0d50062fc33 100644
--- a/admin/translations/fr.json
+++ b/admin/translations/fr.json
@@ -55,6 +55,11 @@
"mandatory": "Champ obligatoire",
"mandatory-fields": "Les champs marqués de ''*'' sont obligatoires"
},
+ "invitations": {
+ "send-new": "Renvoyer l'invitation",
+ "send-new-confirm": "Un email a bien été renvoyé à {invitationEmail}",
+ "send-new-label": "Renvoyer l'invitation à {invitationEmail}"
+ },
"notifications": {
"close-button": {
"extra-information": "Fermer la notification"