diff --git a/orga/app/components/banner/certification.gjs b/orga/app/components/banner/certification.gjs
new file mode 100644
index 00000000000..65128b2e884
--- /dev/null
+++ b/orga/app/components/banner/certification.gjs
@@ -0,0 +1,35 @@
+import PixBanner from '@1024pix/pix-ui/components/pix-banner';
+import { service } from '@ember/service';
+import Component from '@glimmer/component';
+import { t } from 'ember-intl';
+import ENV from 'pix-orga/config/environment';
+
+export default class InformationBanner extends Component {
+ @service currentUser;
+ @service router;
+ @service dayjs;
+
+ get displayCertificationBanner() {
+ const timeToDisplay = ENV.APP.CERTIFICATION_BANNER_DISPLAY_DATES.split(' ');
+ const actualMonth = this.dayjs.self().format('MM');
+ return this.currentUser.isSCOManagingStudents && timeToDisplay.includes(actualMonth);
+ }
+
+ get year() {
+ return this.dayjs.self().format('YYYY');
+ }
+
+
+ {{#if this.displayCertificationBanner}}
+
+ {{t
+ "banners.certification.message"
+ documentationLink="https://cloud.pix.fr/s/DEarDXyxFxM78ps"
+ linkClasses="link link--banner link--bold link--underlined"
+ htmlSafe=true
+ year=this.year
+ }}
+
+ {{/if}}
+
+}
diff --git a/orga/app/components/banner/information.gjs b/orga/app/components/banner/information.gjs
deleted file mode 100644
index 8cb019d5180..00000000000
--- a/orga/app/components/banner/information.gjs
+++ /dev/null
@@ -1,64 +0,0 @@
-import PixBanner from '@1024pix/pix-ui/components/pix-banner';
-import { service } from '@ember/service';
-import Component from '@glimmer/component';
-import { t } from 'ember-intl';
-import ENV from 'pix-orga/config/environment';
-
-export default class InformationBanner extends Component {
- @service currentUser;
- @service router;
- @service dayjs;
-
- get _isOnCertificationsPage() {
- return this.router.currentRouteName === 'authenticated.certifications';
- }
-
- get displayNewYearOrganizationLearnersImportBanner() {
- return (
- !this.currentUser.prescriber.areNewYearOrganizationLearnersImported &&
- this.currentUser.isSCOManagingStudents &&
- !this._isOnCertificationsPage
- );
- }
-
- get displayCertificationBanner() {
- const timeToDisplay = ENV.APP.CERTIFICATION_BANNER_DISPLAY_DATES.split(' ');
- const actualMonth = this.dayjs.self().format('MM');
- return this.currentUser.isSCOManagingStudents && timeToDisplay.includes(actualMonth);
- }
-
- get year() {
- return this.dayjs.self().format('YYYY');
- }
-
-
- {{#if this.displayNewYearOrganizationLearnersImportBanner}}
-
- {{else if this.displayCertificationBanner}}
-
- {{/if}}
-
-}
-
-const NewYearBanner =
-
- {{t
- "banners.import.message"
- documentationLink="https://view.genial.ly/62cd67b161c1e3001759e818?idSlide=e11f61b2-3047-4be3-9a4d-dd9e7cc698ba"
- linkClasses="link link--banner link--bold link--underlined"
- htmlSafe=true
- }}
-
-;
-
-const CertificationBanner =
-
- {{t
- "banners.certification.message"
- documentationLink="https://cloud.pix.fr/s/DEarDXyxFxM78ps"
- linkClasses="link link--banner link--bold link--underlined"
- htmlSafe=true
- year=@year
- }}
-
-;
diff --git a/orga/app/components/banner/sco-communication.gjs b/orga/app/components/banner/sco-communication.gjs
new file mode 100644
index 00000000000..6389b8b3d43
--- /dev/null
+++ b/orga/app/components/banner/sco-communication.gjs
@@ -0,0 +1,46 @@
+import PixBanner from '@1024pix/pix-ui/components/pix-banner';
+import { LinkTo } from '@ember/routing';
+import { service } from '@ember/service';
+import Component from '@glimmer/component';
+import { t } from 'ember-intl';
+
+export default class ScommunicationBanner extends Component {
+ @service currentUser;
+ @service router;
+
+ get shouldDisplayBanner() {
+ return (
+ [
+ 'authenticated.campaigns.list.my-campaigns',
+ 'authenticated.campaigns.list.all-campaigns',
+ 'authenticated.team.list.members',
+ 'authenticated.sco-organization-participants.list',
+ ].includes(this.router.currentRouteName) && this.currentUser.isSCOManagingStudents
+ );
+ }
+ get importParticipantUrl() {
+ return this.router.urlFor('authenticated.import-organization-participants');
+ }
+
+
+ {{#if this.shouldDisplayBanner}}
+
+ {{t "banners.import.message"}}
+
+ -
+ {{t "banners.import.step1a" htmlSafe=true}}
+
+ {{t "banners.import.step1b"}}
+
+ {{t "banners.import.step1c"}}
+
+ - {{t "banners.import.step2" htmlSafe=true}}
+ - {{t "banners.import.step3" htmlSafe=true}}
+
+
+ {{/if}}
+
+}
diff --git a/orga/app/components/banner/top-banners.gjs b/orga/app/components/banner/top-banners.gjs
index 26fb573e313..28dad869cb0 100644
--- a/orga/app/components/banner/top-banners.gjs
+++ b/orga/app/components/banner/top-banners.gjs
@@ -1,10 +1,12 @@
-import Information from './information';
+import Certification from './certification';
import LanguageAvailability from './language-availability';
+import Scommunication from './sco-communication';
import Survey from './survey';
-
+
+
diff --git a/orga/app/styles/components/banner/index.scss b/orga/app/styles/components/banner/index.scss
index 1b1d2384412..c201340eed6 100644
--- a/orga/app/styles/components/banner/index.scss
+++ b/orga/app/styles/components/banner/index.scss
@@ -1 +1,2 @@
@import 'top-banners';
+@import 'sco-communication'
diff --git a/orga/app/styles/components/banner/sco-communication.scss b/orga/app/styles/components/banner/sco-communication.scss
new file mode 100644
index 00000000000..6e035188f17
--- /dev/null
+++ b/orga/app/styles/components/banner/sco-communication.scss
@@ -0,0 +1,4 @@
+.banner-list {
+ margin-left: var(--pix-spacing-4x);
+ list-style: decimal
+}
diff --git a/orga/tests/integration/components/banner/certification-test.gjs b/orga/tests/integration/components/banner/certification-test.gjs
new file mode 100644
index 00000000000..a7c1770f31e
--- /dev/null
+++ b/orga/tests/integration/components/banner/certification-test.gjs
@@ -0,0 +1,70 @@
+import { render } from '@1024pix/ember-testing-library';
+import Service from '@ember/service';
+import Certification from 'pix-orga/components/banner/certification';
+import { module, test } from 'qunit';
+import sinon from 'sinon';
+
+import setupIntlRenderingTest from '../../../helpers/setup-intl-rendering';
+
+module('Integration | Component | Banner::Certification', function (hooks) {
+ setupIntlRenderingTest(hooks);
+
+ module('When it is certification period', function (hooks) {
+ let dayjs;
+
+ hooks.beforeEach(function () {
+ dayjs = this.owner.lookup('service:dayjs');
+ sinon.stub(dayjs.self.prototype, 'format').withArgs('MM').returns('04').withArgs('YYYY').returns('2001');
+ });
+
+ hooks.afterEach(function () {
+ sinon.restore();
+ });
+
+ module('when prescriber’s organization is of type SCO that manages students', function () {
+ class CurrentUserStub extends Service {
+ organization = { isSco: true };
+ isSCOManagingStudents = true;
+ }
+ test('should render the current year', async function (assert) {
+ // given
+ this.owner.register('service:current-user', CurrentUserStub);
+
+ // when
+ const screen = await render();
+
+ // then
+ assert.ok(screen.getByText(/2001/));
+ });
+ test('should render the info link for finalize certification session', async function (assert) {
+ // given
+ this.owner.register('service:current-user', CurrentUserStub);
+
+ // when
+ const screen = await render();
+
+ const link = screen.getByRole('link', { name: 'finaliser les sessions dans Pix Certif' });
+
+ // then
+ assert.strictEqual(link.href, 'https://cloud.pix.fr/s/DEarDXyxFxM78ps');
+ });
+ });
+
+ module('when prescriber’s organization is not of type SCO that manages students', function () {
+ test('should not render the banner regardless of the period', async function (assert) {
+ // given
+ class CurrentUserStub extends Service {
+ organization = { isSco: false };
+ isSCOManagingStudents = false;
+ }
+ this.owner.register('service:current-user', CurrentUserStub);
+
+ // when
+ await render();
+
+ // then
+ assert.dom('.pix-banner').doesNotExist();
+ });
+ });
+ });
+});
diff --git a/orga/tests/integration/components/banner/information_test.gjs b/orga/tests/integration/components/banner/information_test.gjs
deleted file mode 100644
index 4879c1dcc94..00000000000
--- a/orga/tests/integration/components/banner/information_test.gjs
+++ /dev/null
@@ -1,152 +0,0 @@
-import { render } from '@1024pix/ember-testing-library';
-import Service from '@ember/service';
-import Information from 'pix-orga/components/banner/information';
-import { module, test } from 'qunit';
-import sinon from 'sinon';
-
-import setupIntlRenderingTest from '../../../helpers/setup-intl-rendering';
-
-module('Integration | Component | Banner::Information', function (hooks) {
- setupIntlRenderingTest(hooks);
-
- module('Import Banner', function () {
- module('when prescriber’s organization is of type SCO that manages students', function () {
- module('when prescriber has not imported student yet', function () {
- class CurrentUserStub extends Service {
- prescriber = { areNewYearOrganizationLearnersImported: false };
- organization = { isSco: true };
- isSCOManagingStudents = true;
- }
-
- test('should render the more info link', async function (assert) {
- // given
- this.owner.register('service:current-user', CurrentUserStub);
-
- // when
- const screen = await render();
-
- // then
- const link = screen.getByRole('link', { name: 'Plus d’info' });
-
- assert.strictEqual(
- link.href,
- 'https://view.genial.ly/62cd67b161c1e3001759e818?idSlide=e11f61b2-3047-4be3-9a4d-dd9e7cc698ba',
- );
- });
-
- test('should render the import link banner', async function (assert) {
- // given
- this.owner.register('service:current-user', CurrentUserStub);
-
- // when
- const screen = await render();
-
- // then
- const link = screen.getByRole('link', { name: 'importer' });
-
- assert.dom(link).exists();
- });
- });
- });
-
- module('when prescriber has already imported students', function () {
- test('should not display import informations', async function (assert) {
- // given
- class CurrentUserStub extends Service {
- prescriber = { areNewYearOrganizationLearnersImported: true };
- organization = { isSco: true };
- isSCOManagingStudents = true;
- }
- this.owner.register('service:current-user', CurrentUserStub);
-
- // when
- const screen = await render();
-
- const link = screen.queryByRole('link', { name: 'importer' });
- // then
- assert.notOk(link);
- });
- });
-
- module('when prescriber’s organization is not of type SCO that manages students', function () {
- test('should not render the banner regardless of whether students have been imported or not', async function (assert) {
- // given
- class CurrentUserStub extends Service {
- prescriber = { areNewYearOrganizationLearnersImported: false };
- organization = { isSco: false };
- isSCOManagingStudents = false;
- }
- this.owner.register('service:current-user', CurrentUserStub);
-
- // when
- await render();
-
- // then
- assert.dom('.pix-banner').doesNotExist();
- });
- });
- });
-
- module('Certification Banner', function () {
- module('When it is certification period', function (hooks) {
- let dayjs;
-
- hooks.beforeEach(function () {
- dayjs = this.owner.lookup('service:dayjs');
- sinon.stub(dayjs.self.prototype, 'format').withArgs('MM').returns('04').withArgs('YYYY').returns('2001');
- });
-
- hooks.afterEach(function () {
- sinon.restore();
- });
-
- module('when prescriber’s organization is of type SCO that manages students', function () {
- class CurrentUserStub extends Service {
- prescriber = { areNewYearOrganizationLearnersImported: true };
- organization = { isSco: true };
- isSCOManagingStudents = true;
- }
- test('should render the current year', async function (assert) {
- // given
- this.owner.register('service:current-user', CurrentUserStub);
-
- // when
- const screen = await render();
-
- // then
- assert.ok(screen.getByText(/2001/));
- });
- test('should render the info link for finalize certification session', async function (assert) {
- // given
- this.owner.register('service:current-user', CurrentUserStub);
-
- // when
- const screen = await render();
-
- const link = screen.getByRole('link', { name: 'finaliser les sessions dans Pix Certif' });
-
- // then
- assert.strictEqual(link.href, 'https://cloud.pix.fr/s/DEarDXyxFxM78ps');
- });
- });
-
- module('when prescriber’s organization is not of type SCO that manages students', function () {
- test('should not render the banner regardless of the period', async function (assert) {
- // given
- class CurrentUserStub extends Service {
- prescriber = { areNewYearOrganizationLearnersImported: false };
- organization = { isSco: false };
- isSCOManagingStudents = false;
- }
- this.owner.register('service:current-user', CurrentUserStub);
-
- // when
- await render();
-
- // then
- assert.dom('.pix-banner').doesNotExist();
- });
- });
- });
- });
-});
diff --git a/orga/tests/integration/components/banner/sco-communication-test.gjs b/orga/tests/integration/components/banner/sco-communication-test.gjs
new file mode 100644
index 00000000000..8a69442b446
--- /dev/null
+++ b/orga/tests/integration/components/banner/sco-communication-test.gjs
@@ -0,0 +1,109 @@
+import { render } from '@1024pix/ember-testing-library';
+import Service from '@ember/service';
+import Scommunication from 'pix-orga/components/banner/sco-communication';
+import { module, test } from 'qunit';
+
+import setupIntlRenderingTest from '../../../helpers/setup-intl-rendering';
+
+module('Integration | Component | Banner::Sco-communication', function (hooks) {
+ setupIntlRenderingTest(hooks);
+
+ module('Import Banner', function () {
+ module('when prescriber’s organization is of type SCO that manages students', function () {
+ [
+ 'authenticated.campaigns.list.my-campaigns',
+ 'authenticated.campaigns.list.all-campaigns',
+ 'authenticated.team.list.members',
+ 'authenticated.sco-organization-participants.list',
+ ].forEach((route) => {
+ module(`when prescriber is on route ${route}`, function () {
+ class CurrentUserStub extends Service {
+ organization = { isSco: true };
+ isSCOManagingStudents = true;
+ }
+
+ class Router extends Service {
+ currentRouteName = route;
+ }
+
+ test('should render the banner', async function (assert) {
+ // given
+ this.owner.register('service:current-user', CurrentUserStub);
+ this.owner.register('service:router', Router);
+ // when
+ const screen = await render();
+
+ // then
+ assert.ok(screen.getByRole('alert'));
+
+ const downloadLink = screen.getByRole('link', { name: 'télécharger les résultats' });
+ assert.strictEqual(downloadLink.href, 'https://cloud.pix.fr/s/WjTnkSbFs9TDcSC');
+
+ const importLink = screen.queryByRole('link', { name: 'importer' });
+ assert.ok(importLink.href.endsWith('/import-participants'));
+
+ const createCampaignLink = screen.queryByRole('link', { name: 'Créer les campagnes' });
+ assert.strictEqual(createCampaignLink.href, 'https://cloud.pix.fr/s/RaPpKjFHNX2kSR4');
+
+ const certifLink = screen.queryByRole('link', { name: 'Certifier les apprenants' });
+ assert.strictEqual(certifLink.href, 'https://cloud.pix.fr/s/2q4c4QT9jGbGbEq');
+ });
+ });
+ });
+ module('when prescriber is on route certification', function () {
+ class CurrentUserStub extends Service {
+ organization = { isSco: true };
+ isSCOManagingStudents = true;
+ }
+
+ class Router extends Service {
+ currentRouteName = 'authenticated.certifications';
+ }
+
+ test('should not display alert', async function (assert) {
+ // given
+ this.owner.register('service:current-user', CurrentUserStub);
+ this.owner.register('service:router', Router);
+
+ // when
+ const screen = await render();
+ const alert = screen.queryByRole('alert');
+
+ // then
+ assert.notOk(alert);
+ });
+ });
+ });
+
+ module('when prescriber’s organization is not of type SCO that manages students', function () {
+ [
+ 'authenticated.campaigns.list.my-campaigns',
+ 'authenticated.campaigns.list.all-campaigns',
+ 'authenticated.team.list.members',
+ 'authenticated.sco-organization-participants.list',
+ ].forEach((route) => {
+ test(`should not render the banner even if current route is ${route}`, async function (assert) {
+ // given
+ class CurrentUserStub extends Service {
+ organization = { isSco: false };
+ isSCOManagingStudents = false;
+ }
+ class Router extends Service {
+ currentRouteName = route;
+ }
+
+ this.owner.register('service:current-user', CurrentUserStub);
+ this.owner.register('service:router', Router);
+
+ // when
+ const screen = await render();
+
+ // then
+ const alert = screen.queryByRole('alert');
+ // then
+ assert.notOk(alert);
+ });
+ });
+ });
+ });
+});
diff --git a/orga/translations/en.json b/orga/translations/en.json
index 5fd9a1f938d..d1bea2fbc14 100644
--- a/orga/translations/en.json
+++ b/orga/translations/en.json
@@ -66,7 +66,12 @@
"message": "''Certifications :'' n’oubliez pas de '<'a href={documentationLink} class=\"{linkClasses}\" target=\"_blank\" rel=\"noopener noreferrer\"'>'finaliser les sessions dans Pix Certif'' puis de télécharger les attestations ici via l'onglet “Certifications” avant la rentrée {year}."
},
"import": {
- "message": "The administrator can download certification results and '<'a href=\"/import-participants\" class=\"{linkClasses}\"'>'import'' the students database to create back-to-school campaigns by year level. '<'a href={documentationLink} class=\"{linkClasses}\" target=\"_blank\" rel=\"noopener noreferrer\"'>'Learn more''"
+ "message": "The main stages of the school year :",
+ "step1a": " Setting up : '<'a href='https://cloud.pix.fr/s/WjTnkSbFs9TDcSC' title='Downloading results how-to' class='link link--banner link--bold link--underlined' '>'downloading certification results'' and",
+ "step1b": "importing",
+ "step1c": "the student database (admin)",
+ "step2": "'<'a href='https://cloud.pix.fr/s/RaPpKjFHNX2kSR4' title='Back-to-school how-to' class='link link--banner link--bold link--underlined' '>'Create campaigns'' (back-to-school, 6th grade, thematic, subject-based, targeted courses, etc.).",
+ "step3": "'<'a href='https://cloud.pix.fr/s/2q4c4QT9jGbGbEq' title='Preparing and organising student certification how-to' class='link link--banner link--bold link--underlined' '>'Certify learners''."
},
"language-availability": {
"message": "Your language is not yet available on Pix Orga. For your convenience, the application will be presented in English. The entire Pix team is working to add your language."
@@ -1136,7 +1141,7 @@
"table": {
"title": "Seats purchase history",
"caption": "Table listing your organisation's seat purchases. For each purchase, it shows: the number of tickets, the activation date, the expiry date and the status (active, coming soon or expired). It is ordered according to the status of the purchases and their expiry date.",
- "empty-state":"No seats yet!",
+ "empty-state": "No seats yet!",
"headers": {
"activationDate": "Activation date",
"count": "Seats count",
diff --git a/orga/translations/fr.json b/orga/translations/fr.json
index c8b8615a93f..f7d2cf9cb7d 100644
--- a/orga/translations/fr.json
+++ b/orga/translations/fr.json
@@ -66,7 +66,12 @@
"message": "''Certifications :'' n’oubliez pas de '<'a href={documentationLink} class=\"{linkClasses}\" target=\"_blank\" rel=\"noopener noreferrer\"'>'finaliser les sessions dans Pix Certif'' puis de télécharger les attestations ici via l'onglet “Certifications” avant la rentrée {year}."
},
"import": {
- "message": "L'administrateur peut télécharger les résultats de certification et '<'a href=\"/import-participants\" class=\"{linkClasses}\"'>'importer'' la base élèves, afin de créer les campagnes de rentrée par niveau. '<'a href={documentationLink} class=\"{linkClasses}\" target=\"_blank\" rel=\"noopener noreferrer\"'>'Plus d’info''"
+ "message": "Les grandes étapes de l’année dans l’enseignement scolaire :",
+ "step1a": "Mettre en place : '<'a href='https://cloud.pix.fr/s/WjTnkSbFs9TDcSC' title='Guide télécharger les résultats' class='link link--banner link--bold link--underlined' '>'télécharger les résultats'' de certification et",
+ "step1b": "importer",
+ "step1c": "la base élèves (admin)",
+ "step2": "'<'a href='https://cloud.pix.fr/s/RaPpKjFHNX2kSR4' title='Guide Lancer les parcours de rentrée' class='link link--banner link--bold link--underlined' '>'Créer les campagnes'' (parcours rentrée, 6e, thématiques, disciplinaires, ciblés…).",
+ "step3": "'<'a href='https://cloud.pix.fr/s/2q4c4QT9jGbGbEq' title='Guide Préparer et organiser la certification des élèves' class='link link--banner link--bold link--underlined' '>'Certifier les apprenants''."
},
"language-availability": {
"message": "Votre langue n'est pas encore disponible sur Pix Orga. Pour votre confort, l'application sera présentée en anglais. Toute l'équipe de Pix travaille à l'ajout de votre langue."
@@ -1144,7 +1149,7 @@
"table": {
"title": "Historique d'achat de places",
"caption": "Tableau listant les achats de places de votre organisation. Pour chaque achat, il indique : le nombre de places, la date d’activation, la date d’expiration ainsi que le statut (actif, à venir ou expiré). Il est ordonné selon le statut des achats et leur date d’expiration.",
- "empty-state":"Aucune place pour le moment !",
+ "empty-state": "Aucune place pour le moment !",
"headers": {
"activation-date": "Date d'activation",
"count": "Nombre de places",