Skip to content

Commit

Permalink
feat(orga): create statistics component
Browse files Browse the repository at this point in the history
Co-authored-by: Vincent Hardouin <[email protected]>
  • Loading branch information
Alexandre-Monney and VincentHardouin committed Dec 10, 2024
1 parent 7d07a52 commit 73ffb1e
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 0 deletions.
47 changes: 47 additions & 0 deletions orga/app/components/statistics/index.gjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { t } from 'ember-intl';

import Header from '../table/header';
import CoverRateGauge from './cover-rate-gauge';
import TagLevel from './tag-level';

const analysisByTubes = (model) => {
return model.data.sort(
(a, b) => a.competence_code.localeCompare(b.competence_code) || a.sujet.localeCompare(b.sujet),
);
};

<template>
<div class="statistics-page-header">
<h1 class="page-title">{{t "pages.statistics.title"}}</h1>
</div>

<section class="statistics">
<table class="panel">
<caption class="screen-reader-only">{{t "pages.statistics.table.caption"}}</caption>
<thead>
<tr>
<Header @size="wide" scope="col">{{t "pages.statistics.table.headers.skills"}}</Header>
<Header @size="medium" scope="col">{{t "pages.statistics.table.headers.topics"}}</Header>
<Header @size="medium" @align="center" scope="col">{{t "pages.statistics.table.headers.cover-rate"}}</Header>
<Header @align="center" @size="medium" scope="col">{{t
"pages.statistics.table.headers.reached-level"
}}</Header>
</tr>
</thead>
<tbody>
{{#each (analysisByTubes @model) as |line|}}
<tr>
<td>{{line.competence_code}} {{line.competence}}</td>
<td>{{line.sujet}}</td>
<td>
<CoverRateGauge @userLevel={{line.niveau_par_user}} @tubeLevel={{line.niveau_par_sujet}} />
</td>
<td class="table__column--center">
<TagLevel @level={{line.niveau_par_user}} />
</td>
</tr>
{{/each}}
</tbody>
</table>
</section>
</template>
1 change: 1 addition & 0 deletions orga/app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
@import 'components/sup-organization-participant/replace-students-modal';
@import 'components/import-banner';
@import 'components/import-information-banner';
@import 'components/statistics';
@import 'components/statistics/cover-rate-gauge';

// pages
Expand Down
17 changes: 17 additions & 0 deletions orga/app/styles/components/statistics.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.statistics-page-header {
display: flex;
gap: var(--pix-spacing-2x);
align-items: baseline;

&__date {
@extend %pix-body-xs;
}
}

.statistics {
tbody > tr {
&:nth-child(odd) {
background-color: var(--pix-neutral-20);
}
}
}
3 changes: 3 additions & 0 deletions orga/app/templates/authenticated/statistics.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{page-title (t "pages.statistics.title")}}

<Statistics @model={{this.model}} />
14 changes: 14 additions & 0 deletions orga/mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,20 @@ function routes() {

this.get('/organizations/:id/participants', findFilteredPaginatedOrganizationParticipants);

this.get('/organizations/:id/organization-learners-level-by-tubes', (schema) => {
return schema.analysisByTubes.create({
data: [
{
competence_code: '2.1',
competence: 'Interagir',
sujet: 'Gérer ses contacts',
niveau_par_user: '1.30',
niveau_par_sujet: '1.50',
},
],
});
});

this.get('/organization-learners/:id', (schema, request) => {
const participantId = request.params.id;

Expand Down
44 changes: 44 additions & 0 deletions orga/tests/acceptance/statistics-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { visit } from '@1024pix/ember-testing-library';
import { currentURL } from '@ember/test-helpers';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { t } from 'ember-intl/test-support';
import { setupApplicationTest } from 'ember-qunit';
import { module, test } from 'qunit';

import authenticateSession from '../helpers/authenticate-session';
import setupIntl from '../helpers/setup-intl';
import { createPrescriberForOrganization } from '../helpers/test-init';

module('Acceptance | Statistics', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
setupIntl(hooks);

module('When prescriber is not logged in', function () {
test('it should not be accessible by an unauthenticated prescriber', async function (assert) {
// when
await visit('/statistiques');

// then
assert.deepEqual(currentURL(), '/connexion');
});
});

module('When prescriber is logged in and has cover rate feature', function () {
test('user should access to page', async function (assert) {
// given
const user = createPrescriberForOrganization({ lang: 'fr', pixOrgaTermsOfServiceAccepted: true }, {}, 'ADMIN', {
COVER_RATE: true,
});
await authenticateSession(user.id);

// when
const screen = await visit('/statistiques');

// then
assert.ok(screen.getByRole('heading', { level: 1, name: t('pages.statistics.title') }));
assert.ok(screen.getByRole('table'));
assert.ok(screen.getAllByRole('cell'));
});
});
});
62 changes: 62 additions & 0 deletions orga/tests/integration/components/statistics/index-test.gjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { render } from '@1024pix/ember-testing-library';
import { t } from 'ember-intl/test-support';
import Statistics from 'pix-orga/components/statistics/index';
import { module, test } from 'qunit';

import setupIntlRenderingTest from '../../../helpers/setup-intl-rendering';

module('Integration | Component | Statistics | Index', function (hooks) {
setupIntlRenderingTest(hooks);

test('it should display title', async function (assert) {
//given
const model = {
data: [],
};

//when
const screen = await render(<template><Statistics @model={{model}} /></template>);

//then
assert.ok(screen.getByRole('heading', { name: t('pages.statistics.title'), level: 1 }));
});

test('it should display table headers', async function (assert) {
//given
const model = {
data: [],
};

//when
const screen = await render(<template><Statistics @model={{model}} /></template>);

//then
assert.ok(screen.getByRole('columnheader', { name: t('pages.statistics.table.headers.skills') }));
assert.ok(screen.getByRole('columnheader', { name: t('pages.statistics.table.headers.topics') }));
assert.ok(screen.getByRole('columnheader', { name: t('pages.statistics.table.headers.reached-level') }));
assert.ok(screen.getByRole('columnheader', { name: t('pages.statistics.table.headers.cover-rate') }));
});

test('it should display rows data', async function (assert) {
//given
const model = {
data: [
{
competence_code: '2.1',
competence: 'Interagir',
sujet: 'Gérer ses contacts',
niveau_par_user: '1.30',
niveau_par_sujet: '1.50',
},
],
};

//when
const screen = await render(<template><Statistics @model={{model}} /></template>);

//then
assert.ok(screen.getByRole('cell', { name: '2.1 Interagir' }));
assert.ok(screen.getByRole('cell', { name: 'Gérer ses contacts' }));
assert.ok(screen.getByRole('cell', { name: t('pages.statistics.level.novice') }));
});
});
10 changes: 10 additions & 0 deletions orga/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,7 @@
}
},
"statistics": {
"title": "Statistics",
"gauge": {
"label": "On the topic, your participants achieved a level of {userLevel} out of a maximum reachable level of {tubeLevel}."
},
Expand All @@ -1470,6 +1471,15 @@
"expert": "expert",
"independent": "independent",
"novice": "novice"
},
"table": {
"caption": "This table displays the analysis of all participants' results by topic. For each line, it shows the skill, the topic, the coverage rate and the level achieved.",
"headers": {
"cover-rate": "Cover rate",
"reached-level": "Reached level",
"skills": "Skills",
"topics": "Topics"
}
}
},
"sup-organization-participant-activity": {
Expand Down
10 changes: 10 additions & 0 deletions orga/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,7 @@
}
},
"statistics": {
"title": "Statistiques",
"gauge": {
"label": "Sur le sujet vos participants ont obtenu un niveau de {userLevel} sur un niveau maximum atteignable de {tubeLevel}."
},
Expand All @@ -1476,6 +1477,15 @@
"expert": "expert",
"independent": "indépendant",
"novice": "novice"
},
"table": {
"caption": "Ce tableau affiche l'analyse des résultats de tous les participants par sujets. Il indique pour chaque ligne la compétence, le sujet, le taux de couverture ainsi que le niveau atteint",
"headers": {
"cover-rate": "Taux de couverture",
"reached-level": "Niveau atteint",
"skills": "Compétences",
"topics": "Sujets"
}
}
},
"sup-organization-participant-activity": {
Expand Down
10 changes: 10 additions & 0 deletions orga/translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,7 @@
"title": "{count, plural, =0 {Studenten} =1 {Studenten ({count})} other {studenten ({count})}}"
},
"statistics": {
"title": "Statistieken",
"gauge": {
"label": "Je deelnemers behaalden een {userLevel} op een maximaal haalbaar niveau van {tubeLevel}."
},
Expand All @@ -1470,6 +1471,15 @@
"expert": "expert",
"independent": "onafhankelijk",
"novice": "beginnende"
},
"table": {
"caption": "Deze tabel toont de resultaten van alle deelnemers per onderwerp. Voor elke regel wordt de vaardigheid, het onderwerp, het dekkingspercentage en het behaalde niveau aangegeven.",
"headers": {
"cover-rate": "Dekkingspercentage",
"reached-level": "Bereikt niveau",
"skills": "Vaardigheden",
"topics": "Onderwerpen"
}
}
},
"sup-organization-participant-activity": {
Expand Down

0 comments on commit 73ffb1e

Please sign in to comment.