Skip to content

Commit

Permalink
[FEATURE] Ajouter le filtre pour trier les participations par badge n…
Browse files Browse the repository at this point in the history
…on obtenu. (PIX-16351)

 #11488
  • Loading branch information
pix-service-auto-merge authored Feb 25, 2025
2 parents df760b5 + 22d1163 commit 313ce74
Show file tree
Hide file tree
Showing 14 changed files with 443 additions and 353 deletions.
10 changes: 0 additions & 10 deletions api/src/prescription/campaign/domain/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,8 @@ class CampaignParticipationDoesNotBelongToUser extends DomainError {
}
}

class AssessmentParticipationResultFilterError extends DomainError {
constructor() {
super(
'Filtering on both acquired and unacquired using the same badge id is impossible',
'ASSESSMENT_PARTICIPATION_RESULT_FILTER_ERROR',
);
}
}

export {
ArchivedCampaignError,
AssessmentParticipationResultFilterError,
CampaignCodeFormatError,
CampaignParticipationDoesNotBelongToUser,
CampaignUniqueCodeError,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import { AssessmentParticipationResultFilterError } from '../errors.js';

async function findAssessmentParticipationResultList({
const findAssessmentParticipationResultList = async ({
campaignId,
filters,
page,
campaignAssessmentParticipationResultListRepository,
}) {
if (filters?.badges?.some((id) => filters?.unacquiredBadges?.includes(id))) {
throw new AssessmentParticipationResultFilterError();
}
return campaignAssessmentParticipationResultListRepository.findPaginatedByCampaignId({ campaignId, filters, page });
}
}) => campaignAssessmentParticipationResultListRepository.findPaginatedByCampaignId({ campaignId, filters, page });

export { findAssessmentParticipationResultList };
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('Integration | UseCase | find-assessment-participation-result-list', fu
organizationId,
userId,
});

campaignId = databaseBuilder.factory.buildCampaign({ organizationId }).id;
databaseBuilder.factory.buildCampaignSkill({ campaignId, skillId: skill.id });

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AssessmentParticipationResultFilterError } from '../../../../../../src/prescription/campaign/domain/errors.js';
import { findAssessmentParticipationResultList } from '../../../../../../src/prescription/campaign/domain/usecases/find-assessment-participation-result-list.js';
import { catchErr, expect, sinon } from '../../../../../test-helper.js';
import { expect, sinon } from '../../../../../test-helper.js';

describe('Unit | UseCase | find-assessment-participation-result-list', function () {
it('return the assessmentParticipationResultMinimal list', async function () {
Expand All @@ -21,18 +20,4 @@ describe('Unit | UseCase | find-assessment-participation-result-list', function
expect(findPaginatedByCampaignId).to.have.been.calledWithExactly({ page, campaignId, filters });
expect(results).to.equal(participations);
});

it('throw when filter contain the same id on both badge and unacquiredBadge filters', async function () {
const campaignId = 1;
const filters = { unacquiredBadges: [1, 3], badges: [1, 2] };
const page = Symbol('page');

const error = await catchErr(findAssessmentParticipationResultList)({
campaignId,
filters,
page,
});

expect(error).instanceOf(AssessmentParticipationResultFilterError);
});
});
25 changes: 25 additions & 0 deletions orga/app/components/campaign/filter/participation-filters.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export default class ParticipationFilters extends Component {
(!this.displayGroupsFilter || this.args.selectedGroups.length === 0) &&
(!this.displayStagesFilter || this.args.selectedStages.length === 0) &&
(!this.displayBadgesFilter || this.args.selectedBadges.length === 0) &&
(!this.displayBadgesFilter || this.args.selectedUnacquiredBadges.length === 0) &&
(!this.displayCertificabilityFilter || !this.args.selectedCertificability)
);
}
Expand Down Expand Up @@ -159,6 +160,18 @@ export default class ParticipationFilters extends Component {
});
}

@action
onSelectUnacquiredBadge(unacquiredBadges) {
this.args.onFilter('unacquiredBadges', unacquiredBadges);

this.metrics.add({
event: 'custom-event',
'pix-event-category': 'Campagnes',
'pix-event-action': 'Filtrer les participations',
'pix-event-name': 'Utilisation du filtre "Thématiques non obtenues"',
});
}

@action
onSelectDivision(divisions) {
this.args.onFilter('divisions', divisions);
Expand Down Expand Up @@ -243,6 +256,18 @@ export default class ParticipationFilters extends Component {
<:label>{{t "pages.campaign-results.filters.type.badges"}}</:label>
<:default as |badge|>{{badge.label}}</:default>
</PixMultiSelect>

<PixMultiSelect
@placeholder={{t "pages.campaign-results.filters.type.unacquired-badges"}}
@screenReaderOnly={{true}}
@onChange={{this.onSelectUnacquiredBadge}}
@values={{@selectedUnacquiredBadges}}
@options={{this.badgeOptions}}
@className="participant-filter-banner__badges"
>
<:label>{{t "pages.campaign-results.filters.type.unacquired-badges"}}</:label>
<:default as |badge|>{{badge.label}}</:default>
</PixMultiSelect>
{{/if}}
{{#if this.displayCertificabilityFilter}}
<PixSelect
Expand Down
1 change: 1 addition & 0 deletions orga/app/components/campaign/results/assessment-list.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import EvolutionHeader from './evolution-header';
@selectedDivisions={{@selectedDivisions}}
@selectedGroups={{@selectedGroups}}
@selectedBadges={{@selectedBadges}}
@selectedUnacquiredBadges={{@selectedUnacquiredBadges}}
@selectedStages={{@selectedStages}}
@searchFilter={{@searchFilter}}
@rowCount={{@participations.meta.rowCount}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default class AssessmentResultsController extends Controller {
@tracked divisions = [];
@tracked groups = [];
@tracked badges = [];
@tracked unacquiredBadges = [];
@tracked stages = [];
@tracked search = null;

Expand Down Expand Up @@ -42,7 +43,10 @@ export default class AssessmentResultsController extends Controller {
this.pageNumber = null;
this.divisions = [];
this.groups = [];

this.badges = [];
this.unacquiredBadges = [];

this.stages = [];
this.search = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export default class AssessmentResultsRoute extends Route {
badges: {
refreshModel: true,
},
unacquiredBadges: {
refreshModel: true,
},
stages: {
refreshModel: true,
},
Expand Down Expand Up @@ -55,6 +58,7 @@ export default class AssessmentResultsRoute extends Route {
divisions: params.divisions,
groups: params.groups,
badges: params.badges,
unacquiredBadges: params.unacquiredBadges,
stages: params.stages,
search: params.search,
},
Expand All @@ -70,6 +74,7 @@ export default class AssessmentResultsRoute extends Route {
controller.groups = [];
controller.badges = [];
controller.stages = [];
controller.unacquiredBadges = [];
controller.search = null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
@selectedDivisions={{this.divisions}}
@selectedGroups={{this.groups}}
@selectedBadges={{this.badges}}
@selectedUnacquiredBadges={{this.unacquiredBadges}}
@selectedStages={{this.stages}}
@searchFilter={{this.search}}
@onClickParticipant={{this.goToAssessmentPage}}
Expand Down
Loading

0 comments on commit 313ce74

Please sign in to comment.