Skip to content

[TECH] Utiliser le PixTable dans tout PixOrga (PIX-15793) #11509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ee5f5ed
tech(orga): use new PixTable on campaign list
xav-car Feb 25, 2025
4c35a7a
feat(orga): use PixTable on Participant List
xav-car Feb 27, 2025
ffdf0d8
feat(orga): use PixTable on competences
xav-car Feb 27, 2025
7cafae9
feat(orga): add PixTable on anaylis assessment page
xav-car Feb 28, 2025
de1b4d1
feat(orga): use PixTable on profile collection result
xav-car Feb 28, 2025
39d0b9b
feat(orga): add PixTable on anaylis assessment page
xav-car Feb 28, 2025
3ae3490
move unavquired badge style somewhere for now
xav-car Feb 28, 2025
3487258
feat(orga): use pix table on organization participant (generic)
xav-car Feb 28, 2025
b2eef80
feat(orga): use PixTable on team page
xav-car Feb 28, 2025
9d36092
feat(orga): use PixTable on places
xav-car Feb 28, 2025
9fd5a65
feat(orga): use PixTable on participant assessment result page
xav-car Feb 28, 2025
b57f480
feat(orga): use PixTable on participant profile result
xav-car Feb 28, 2025
d703131
feat(orga): use PixTable on organization learner participation list
xav-car Feb 28, 2025
6a39070
feat(orga): use PixTable on mission list
xav-car Feb 28, 2025
df1eabd
feat(orga): use PixTable on mission activity page
xav-car Feb 28, 2025
ce9052c
feat(orga): use PixTable on statistics page
xav-car Feb 28, 2025
004b42e
feat(orga): use PixTable on mission result table components
xav-car Feb 28, 2025
19f655f
feat(orga): use PixTable on Sco participant list
xav-car Mar 3, 2025
38e51e6
feat(orga): use PixTable on sup page
xav-car Mar 3, 2025
9c797e5
fix(e2e): stop using aria label on table row
xav-car Mar 3, 2025
68da2c9
fix(orga): use PageTitle on sup header action
xav-car Mar 4, 2025
52f50af
fix(orga): remove row title from translation
xav-car Mar 4, 2025
1622ae3
fix(orga): align number column
xav-car Mar 5, 2025
c1009a6
fix(orga): correct semantic on table. avoid display div inside tr
xav-car Mar 5, 2025
0b363ad
remove unecessary css style
xav-car Mar 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions high-level-tests/e2e/cypress/support/step_definitions/campaign.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ When(

When(`j'ouvre le sujet {string}`, (tubeName) => {
cy.contains(tubeName)
.closest('[aria-label="Sujet"]')
.closest('tr')
.within(() => {
cy.get("button").click();
});
Expand All @@ -35,11 +35,13 @@ When(
);

Then(`je vois {int} campagne\(s\)`, (campaignsCount) => {
cy.get('table tbody tr').should("have.lengthOf", campaignsCount);
cy.findAllByRole('row').should("have.lengthOf", campaignsCount + 1);
});

Then(`je vois {int} tutoriel\(s\)`, (tutorialsCount) => {
cy.get('[aria-label="Tutoriel"]').should("have.lengthOf", tutorialsCount);
cy.findByRole('table', { name: "Tableau des sujets à travailler, certains présentent des colonnes supplémentaires indiquant le nombre de tutoriels existant en lien avec le sujet et un accès à ces tutoriels" }).within(() => {
cy.findAllByRole('listitem').should("have.lengthOf", tutorialsCount);
});
});

When(`je recherche une campagne avec le nom {string}`, (campaignSearchName) => {
Expand All @@ -51,25 +53,31 @@ Then(`je vois le détail de la campagne {string}`, (campaignName) => {
});

Then(`je vois {int} participants`, (numberOfParticipants) => {
cy.get('[aria-label="Participant"]').should(
"have.lengthOf",
numberOfParticipants,
);
cy.findByRole('table', {name: "Liste des participants"}).within(() => {
cy.findAllByRole('row').should(
"have.lengthOf",
numberOfParticipants + 1,
);
})
});

Then(`je vois {int} profils`, (numberOfProfiles) => {
cy.get('[aria-label="Profil"]').should("have.lengthOf", numberOfProfiles);
if(numberOfProfiles === 0) {
cy.contains('Aucun participant pour l’instant ! Envoyez-leur le lien suivant pour rejoindre votre campagne.');
} else {
cy.findAllByRole('row').should("have.lengthOf", numberOfProfiles + 1);
}
});

When(
`je vois {int} résultats par compétence`,
(numberOfResultsByCompetence) => {
if (numberOfResultsByCompetence === 0) {
cy.get(".table__empty").should("contain", "En attente de résultat");
cy.findByText("En attente de résultats");
} else {
cy.get('[aria-label="Compétence"]').should(
cy.findAllByRole('row').should(
"have.lengthOf",
numberOfResultsByCompetence,
numberOfResultsByCompetence + 1,
);
}
},
Expand Down Expand Up @@ -118,14 +126,16 @@ Then(`je vois que j'ai envoyé les résultats`, () => {
});

Then(`je vois {int} sujets`, (tubeCount) => {
cy.get('[aria-label="Sujet"]').should("have.lengthOf", tubeCount);
cy.findByRole('table', { name: "Tableau des sujets à travailler, certains présentent des colonnes supplémentaires indiquant le nombre de tutoriels existant en lien avec le sujet et un accès à ces tutoriels"}).within(() => {
cy.findAllByRole('row').should("have.lengthOf", tubeCount + 1);
});
});

Then(
`je vois que le sujet {string} est {string}`,
(tubeName, recommendationLevel) => {
cy.contains(tubeName)
.closest('[aria-label="Sujet"]')
.closest('tr')
.get(`[aria-label="${recommendationLevel}"]`);
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ Then(`je suis redirigé vers la page pour rejoindre l'organisation`, () => {

Then(`je vois {int} invitation\(s\) en attente`, (numberOfInvitations) => {
cy.contains(`Invitations (${numberOfInvitations})`).click();
cy.get('[aria-label="Invitation en attente"]').should(
cy.findAllByRole('row').should(
"have.lengthOf",
numberOfInvitations
numberOfInvitations + 1
);
});

Then(`je vois {int} membre\(s\)`, (numberOfMembers) => {
cy.contains(`Membres (${numberOfMembers})`).click();
cy.get('[aria-label="Membre"]').should("have.lengthOf", numberOfMembers);
cy.findAllByRole('row').should("have.lengthOf", numberOfMembers + 1);
});

When(`j'invite {string} à rejoindre l'organisation`, (emailAddresses) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { When, Then } = require("@badeball/cypress-cucumber-preprocessor");

When(`je veux gérer le compte d'un élève`, () => {
cy.get('[aria-label="Afficher les actions"]').click();
cy.findByRole('button', {name : "Afficher les actions"}).click();
cy.contains("Gérer le compte").click();
});

Expand All @@ -23,9 +23,9 @@ Then("je vois le mot de passe généré", () => {
});

Then("je vois {int} élève(s)", (studentsCount) => {
cy.get('[aria-label="Élève"]').should("have.lengthOf", studentsCount);
cy.findAllByRole('row').should("have.lengthOf", studentsCount + 1);
});

Then("je vois {int} étudiant(s)", (studentsCount) => {
cy.get('[aria-label="Étudiant"]').should("have.lengthOf", studentsCount);
cy.findAllByRole('row').should("have.lengthOf", studentsCount + 1);
});
227 changes: 111 additions & 116 deletions orga/app/components/campaign/activity/participants-list.gjs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import PixIconButton from '@1024pix/pix-ui/components/pix-icon-button';
import PixPagination from '@1024pix/pix-ui/components/pix-pagination';
import PixTable from '@1024pix/pix-ui/components/pix-table';
import PixTableColumn from '@1024pix/pix-ui/components/pix-table-column';
import { array, fn } from '@ember/helper';
import { on } from '@ember/modifier';
import { action } from '@ember/object';
import { LinkTo } from '@ember/routing';
import { service } from '@ember/service';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { t } from 'ember-intl';

import TableHeader from '../../table/header';
import ParticipationStatus from '../../ui/participation-status';
import ParticipationFilters from '../filter/participation-filters';
import DeleteParticipationModal from './delete-participation-modal';
Expand Down Expand Up @@ -66,119 +66,114 @@ export default class ParticipantsList extends Component {
@onResetFilter={{@onResetFilter}}
/>

<section ...attributes>
<div class="panel">
<table class="table content-text content-text--small">
<colgroup class="table__column">
<col class="table__column--wide" />
<col class="table__column--wide" />
{{#if @campaign.externalIdLabel}}
<col class="table__column--medium" />
{{/if}}
<col class="table__column--wide" />
{{#if @showParticipationCount}}
<col class="table__column--wide" />
{{/if}}
{{#if this.canDeleteParticipation}}
<col class="table__column--small table__column--right hide-on-mobile" />
{{/if}}
</colgroup>
<thead>
<tr>
<TableHeader>{{t "pages.campaign-activity.table.column.last-name"}}</TableHeader>
<TableHeader>{{t "pages.campaign-activity.table.column.first-name"}}</TableHeader>
{{#if @campaign.externalIdLabel}}
<TableHeader>{{@campaign.externalIdLabel}}</TableHeader>
{{/if}}
<TableHeader>{{t "pages.campaign-activity.table.column.status"}}</TableHeader>
{{#if @showParticipationCount}}
<TableHeader @size="wide">
{{t "pages.campaign-activity.table.column.participationCount"}}
</TableHeader>
{{/if}}
{{#if this.canDeleteParticipation}}
<TableHeader class="hide-on-mobile">
<span class="screen-reader-only">
{{t "pages.campaign-activity.table.column.delete"}}
</span>
</TableHeader>
{{/if}}
</tr>
</thead>

{{#if @participations}}
<tbody>
{{#each @participations as |participation|}}
<tr
aria-label={{t "pages.campaign-activity.table.row-title"}}
{{on "click" (fn @onClickParticipant @campaign.id participation.lastCampaignParticipationId)}}
class="tr--clickable"
>
<td>
<LinkTo
@route={{if
@campaign.isTypeAssessment
"authenticated.campaigns.participant-assessment"
"authenticated.campaigns.participant-profile"
}}
@models={{array @campaign.id participation.lastCampaignParticipationId}}
>
<span
aria-label="{{t
'pages.campaign-activity.table.see-results'
firstName=participation.firstName
lastName=participation.lastName
}}"
>
{{participation.lastName}}</span>
</LinkTo>
</td>
<td>{{participation.firstName}}</td>
{{#if @campaign.externalIdLabel}}
<td class="table__column table__column--break-word">{{participation.participantExternalId}}</td>
{{/if}}
<td>
<ParticipationStatus @status={{participation.status}} @campaignType={{@campaign.type}} />
</td>
{{#if @showParticipationCount}}
<td>
{{participation.participationCount}}
</td>
{{/if}}
{{#if this.canDeleteParticipation}}
<td class="hide-on-mobile">
<PixIconButton
@ariaLabel={{t "pages.campaign-activity.table.delete-button-label"}}
@withBackground={{true}}
@iconName="delete"
@triggerAction={{fn this.openModal participation}}
@size="small"
class="campaign-activity-table-actions__button campaign-activity-table-actions__button--delete"
/>
</td>
{{/if}}
</tr>
{{/each}}
</tbody>
{{/if}}
</table>

{{#unless @participations}}
<p class="table__empty content-text">{{t "pages.campaign-activity.table.empty"}}</p>
{{/unless}}
</div>

{{#if @participations}}
<PixPagination @pagination={{@participations.meta}} @locale={{this.getCurrentLocale}} />
{{/if}}

<DeleteParticipationModal
@participation={{this.participationToDelete}}
@campaign={{@campaign}}
@deleteCampaignParticipation={{this.deleteCampaignParticipation}}
@closeModal={{this.closeModal}}
@isModalOpen={{this.isModalOpen}}
/>
</section>
<PixTable
@variant="orga"
@caption={{t "pages.campaign-activity.table.title"}}
@data={{@participations}}
class="table"
@onRowClick={{@onClickParticipant}}
>
<:columns as |participation context|>
<PixTableColumn @context={{context}}>
<:header>
{{t "pages.campaign-activity.table.column.last-name"}}
</:header>
<:cell>
<LinkTo
@route={{if
@campaign.isTypeAssessment
"authenticated.campaigns.participant-assessment"
"authenticated.campaigns.participant-profile"
}}
@models={{array @campaign.id participation.lastCampaignParticipationId}}
>
<span
aria-label={{t
"pages.campaign-activity.table.see-results"
firstName=participation.firstName
lastName=participation.lastName
}}
>
{{participation.lastName}}</span>
</LinkTo>
</:cell>
</PixTableColumn>

<PixTableColumn @context={{context}}>
<:header>
{{t "pages.campaign-activity.table.column.first-name"}}
</:header>
<:cell>
{{participation.firstName}}
</:cell>
</PixTableColumn>

{{#if @campaign.externalIdLabel}}
<PixTableColumn @context={{context}}>
<:header>
{{@campaign.externalIdLabel}}
</:header>
<:cell>
{{participation.participantExternalId}}
</:cell>
</PixTableColumn>
{{/if}}

<PixTableColumn @context={{context}}>
<:header>
{{t "pages.campaign-activity.table.column.status"}}
</:header>
<:cell>
<ParticipationStatus @status={{participation.status}} @campaignType={{@campaign.type}} />
</:cell>
</PixTableColumn>

{{#if @showParticipationCount}}
<PixTableColumn @context={{context}} @type="number">
<:header>
{{t "pages.campaign-activity.table.column.participationCount"}}
</:header>
<:cell>
{{participation.participationCount}}
</:cell>
</PixTableColumn>
{{/if}}

{{#if this.canDeleteParticipation}}
<PixTableColumn @context={{context}}>
<:header>
{{t "pages.campaign-activity.table.column.delete"}}
</:header>
<:cell>
<PixIconButton
@ariaLabel={{t "pages.campaign-activity.table.delete-button-label"}}
@withBackground={{true}}
@iconName="delete"
@triggerAction={{fn this.openModal participation}}
@size="small"
class="campaign-activity-table-actions__button campaign-activity-table-actions__button--delete"
/>
</:cell>
</PixTableColumn>
{{/if}}

</:columns>
</PixTable>

{{#unless @participations}}
<p class="table__empty content-text">{{t "pages.campaign-activity.table.empty"}}</p>
{{/unless}}

{{#if @participations}}
<PixPagination @pagination={{@participations.meta}} @locale={{this.getCurrentLocale}} />
{{/if}}

<DeleteParticipationModal
@participation={{this.participationToDelete}}
@campaign={{@campaign}}
@deleteCampaignParticipation={{this.deleteCampaignParticipation}}
@closeModal={{this.closeModal}}
@isModalOpen={{this.isModalOpen}}
/>
</template>
}
Loading