diff --git a/mon-pix/app/components/download-session-results.gjs b/mon-pix/app/components/download-session-results.gjs
new file mode 100644
index 00000000000..ac81fa4b264
--- /dev/null
+++ b/mon-pix/app/components/download-session-results.gjs
@@ -0,0 +1,56 @@
+import PixBackgroundHeader from '@1024pix/pix-ui/components/pix-background-header';
+import PixBlock from '@1024pix/pix-ui/components/pix-block';
+import PixButton from '@1024pix/pix-ui/components/pix-button';
+import PixMessage from '@1024pix/pix-ui/components/pix-message';
+import { action } from '@ember/object';
+import { service } from '@ember/service';
+import Component from '@glimmer/component';
+import { tracked } from '@glimmer/tracking';
+import { t } from 'ember-intl';
+import ENV from 'mon-pix/config/environment';
+import PixWindow from 'mon-pix/utils/pix-window';
+
+export default class DownloadSessionResults extends Component {
+ @tracked showErrorMessage = false;
+ @service requestManager;
+
+ @action
+ async downloadSessionResults(event) {
+ event.preventDefault();
+ this.showErrorMessage = false;
+
+ try {
+ const token = decodeURIComponent(PixWindow.getLocationHash().slice(1));
+ await this.requestManager.request({
+ url: `${ENV.APP.API_HOST}/api/sessions/download-all-results`,
+ method: 'POST',
+ body: JSON.stringify({ token }),
+ });
+ } catch {
+ this.showErrorMessage = true;
+ }
+ }
+
+
+
+
+
+
+
+
+}
diff --git a/mon-pix/app/router.js b/mon-pix/app/router.js
index 5e665cd6294..253693e1a9b 100644
--- a/mon-pix/app/router.js
+++ b/mon-pix/app/router.js
@@ -141,6 +141,8 @@ Router.map(function () {
this.route('companion', { path: '/verification-extension-certification' });
+ this.route('download-session-results', { path: '/resultats-session' });
+
// XXX: this route is used for any request that did not match any of the previous routes. SHOULD ALWAYS BE THE LAST ONE
this.route('not-found', { path: '/*path' });
});
diff --git a/mon-pix/app/routes/download-session-results.js b/mon-pix/app/routes/download-session-results.js
new file mode 100644
index 00000000000..adb1021d6eb
--- /dev/null
+++ b/mon-pix/app/routes/download-session-results.js
@@ -0,0 +1,3 @@
+import Route from '@ember/routing/route';
+
+export default class DownloadSessionResults extends Route {}
diff --git a/mon-pix/app/styles/app.scss b/mon-pix/app/styles/app.scss
index 9a88fc1295b..18d7fb61c6e 100644
--- a/mon-pix/app/styles/app.scss
+++ b/mon-pix/app/styles/app.scss
@@ -187,3 +187,4 @@ of an adaptative/mobile-first approach — refactoring is welcome here */
@import 'pages/language';
@import 'pages/existing-campagne';
@import 'pages/certification-instructions';
+@import 'pages/download-session-results';
diff --git a/mon-pix/app/styles/pages/_download-session-results.scss b/mon-pix/app/styles/pages/_download-session-results.scss
new file mode 100644
index 00000000000..85c51ed04da
--- /dev/null
+++ b/mon-pix/app/styles/pages/_download-session-results.scss
@@ -0,0 +1,29 @@
+.download-session-results {
+ max-width: max-content;
+ margin: 0 auto 32px;
+ padding: 48px 24px;
+
+ @include device-is('tablet') {
+ padding: 48px 60px;
+ }
+
+ &__form {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ .form__title {
+ @extend %pix-title-m;
+
+ margin-bottom: var(--pix-spacing-4x);
+ }
+
+ .form__actions {
+ margin-top: var(--pix-spacing-6x);
+ }
+
+ .form__error {
+ margin-top: var(--pix-spacing-4x);
+ }
+ }
+}
diff --git a/mon-pix/app/templates/download-session-results.hbs b/mon-pix/app/templates/download-session-results.hbs
new file mode 100644
index 00000000000..67e9d1580fe
--- /dev/null
+++ b/mon-pix/app/templates/download-session-results.hbs
@@ -0,0 +1,11 @@
+{{page-title (t "pages.download-session-results.title")}}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mon-pix/tests/integration/components/download-session-results-test.gjs b/mon-pix/tests/integration/components/download-session-results-test.gjs
new file mode 100644
index 00000000000..0d2e309e54b
--- /dev/null
+++ b/mon-pix/tests/integration/components/download-session-results-test.gjs
@@ -0,0 +1,69 @@
+import { render } from '@1024pix/ember-testing-library';
+import { click } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+import { t } from 'ember-intl/test-support';
+import DownloadSessionResults from 'mon-pix/components/download-session-results';
+import ENV from 'mon-pix/config/environment';
+import PixWindow from 'mon-pix/utils/pix-window';
+import { module, test } from 'qunit';
+import sinon from 'sinon';
+
+import setupIntlRenderingTest from '../../helpers/setup-intl-rendering';
+
+module('Integration | Component | download-session-results', function (hooks) {
+ setupIntlRenderingTest(hooks);
+
+ let requestManagerService;
+
+ hooks.beforeEach(function () {
+ requestManagerService = this.owner.lookup('service:requestManager');
+ sinon.stub(requestManagerService, 'request');
+ });
+
+ hooks.afterEach(function () {
+ sinon.restore();
+ });
+
+ test('should display component', async function (assert) {
+ // given
+ // when
+ const screen = await render();
+
+ // then
+ assert.dom(screen.getByRole('heading', { name: t('pages.download-session-results.title'), level: 1 })).exists();
+ assert.dom(screen.getByRole('button', { name: t('pages.download-session-results.button.label') })).exists();
+ });
+
+ test('should display the expiration error message', async function (assert) {
+ // given
+ requestManagerService.request.rejects({ status: 500 });
+
+ // when
+ const screen = await render(hbs``);
+ const downloadButton = screen.getByRole('button', { name: t('pages.download-session-results.button.label') });
+ await click(downloadButton);
+
+ // then
+ assert.dom(screen.getByText(t('pages.download-session-results.errors.expiration'))).exists();
+ });
+
+ test('should trigger the download', async function (assert) {
+ // given
+ requestManagerService.request.resolves({ status: 200 });
+ const tokenHash = 'mytoken';
+ sinon.stub(PixWindow, 'getLocationHash').returns(`#${tokenHash}`);
+
+ // when
+ const screen = await render(hbs``);
+ const downloadButton = screen.getByRole('button', { name: t('pages.download-session-results.button.label') });
+ await click(downloadButton);
+
+ // then
+ sinon.assert.calledWithExactly(requestManagerService.request, {
+ url: `${ENV.APP.API_HOST}/api/sessions/download-all-results`,
+ method: 'POST',
+ body: `{"token":"${tokenHash}"}`,
+ });
+ assert.ok(true);
+ });
+});
diff --git a/mon-pix/translations/en.json b/mon-pix/translations/en.json
index 925995d2798..08ae24720c9 100644
--- a/mon-pix/translations/en.json
+++ b/mon-pix/translations/en.json
@@ -226,7 +226,7 @@
},
"errors": {
"invalid-locale-format": "Provided locale \"{invalidLocale}\" has an invalid format.",
- "invalid-or-already-used-email" : "Invalid or already used e-mail address",
+ "invalid-or-already-used-email": "Invalid or already used e-mail address",
"locale-not-supported": "Provided locale \"{localeNotSupported}\" isn't currently supported."
},
"fields": {
@@ -366,7 +366,7 @@
"new-email": ",if not, enter a new one."
},
"empty-email": "The e-mail address field is mandatory.",
- "invalid-or-already-used-email" : "Invalid or already used e-mail address",
+ "invalid-or-already-used-email": "Invalid or already used e-mail address",
"new-backup-email": "Please enter a valid e-mail address to recover your account",
"new-email-already-exist": "This e-mail address is already in use",
"wrong-email-format": "Your e-mail address is invalid."
@@ -1261,6 +1261,15 @@
},
"title": "Homepage"
},
+ "download-session-results": {
+ "button": {
+ "label": "Download results"
+ },
+ "errors": {
+ "expiration": "The session results download link has expired."
+ },
+ "title": "Download session results"
+ },
"error": {
"content-text": "'
'Please refresh the page or return to homepage.'
'You can also contact us via ''the help centre form''specifying the error code below in the description.'
'Please excuse any inconvenience caused.'
'The Pix team.'
'",
"first-title": "Oops, an error occurred!"
@@ -2100,7 +2109,7 @@
"errors": {
"empty-password": "Your password can't be empty.",
"invalid-email": "Your email address is invalid.",
- "invalid-or-already-used-email" : "Invalid or already used e-mail address",
+ "invalid-or-already-used-email": "Invalid or already used e-mail address",
"invalid-password": "There was an error in the password entered.",
"new-email-already-exist": "This email address is already in use."
},
diff --git a/mon-pix/translations/fr.json b/mon-pix/translations/fr.json
index 613a5dc9d3b..9cec9a09c24 100644
--- a/mon-pix/translations/fr.json
+++ b/mon-pix/translations/fr.json
@@ -226,7 +226,7 @@
},
"errors": {
"invalid-locale-format": "Votre locale \"{invalidLocale}\" n'est pas dans le bon format.",
- "invalid-or-already-used-email" : "Adresse e-mail invalide ou déjà utilisée",
+ "invalid-or-already-used-email": "Adresse e-mail invalide ou déjà utilisée",
"locale-not-supported": "Votre locale \"{localeNotSupported}\" n'est actuellement pas supportée."
},
"fields": {
@@ -366,7 +366,7 @@
"new-email": ", sinon saisissez une nouvelle."
},
"empty-email": "Le champ adresse e-mail est obligatoire.",
- "invalid-or-already-used-email" : "Adresse e-mail invalide ou déjà utilisée",
+ "invalid-or-already-used-email": "Adresse e-mail invalide ou déjà utilisée",
"new-backup-email": "Veuillez saisir un e-mail valide pour récupérer votre compte",
"new-email-already-exist": "Cette adresse e-mail est déjà utilisée",
"wrong-email-format": "Votre adresse e-mail n’est pas valide."
@@ -1262,6 +1262,15 @@
},
"title": "Accueil"
},
+ "download-session-results": {
+ "button": {
+ "label": "Télécharger les résultats"
+ },
+ "errors": {
+ "expiration": "Le lien de téléchargement des résultats de session a expiré."
+ },
+ "title": "Télécharger les résultats de session"
+ },
"error": {
"content-text": "''Nous vous invitons à recharger cette page ou revenir à la page d’accueil.'
'Vous pouvez aussi nous contacter via ''le formulaire du centre d'aide'' en nous précisant le code d’erreur ci-dessous dans la description.'
'Nous vous prions de nous excuser pour la gêne occasionnée.'
'L’équipe Pix.'
'",
"first-title": "Oups, une erreur est survenue !"
@@ -2101,7 +2110,7 @@
"errors": {
"empty-password": "Votre mot de passe ne peut pas être vide.",
"invalid-email": "Votre adresse e-mail n’est pas valide.",
- "invalid-or-already-used-email" : "Adresse e-mail invalide ou déjà utilisée",
+ "invalid-or-already-used-email": "Adresse e-mail invalide ou déjà utilisée",
"invalid-password": "Le mot de passe que vous avez saisi est invalide.",
"new-email-already-exist": "Cette adresse e-mail est déjà utilisée."
},