Skip to content

Commit 3d32d32

Browse files
committed
feat: add formations labels and services to affiner ma recherche
1 parent a313c49 commit 3d32d32

16 files changed

+386
-110
lines changed

src/features/cartographie/components/affiner-recherche-form/affiner-recherche-form.component.html

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,10 @@
2222
<input
2323
class="form-check-input"
2424
type="checkbox"
25-
name="service"
25+
name="fiche_acces_libre"
2626
role="switch"
27-
formControlName="service"
28-
(change)="setFilterToQueryString('service')" />
29-
Prise en main de Mon espace Santé
30-
</label>
31-
</div>
32-
</li>
33-
<li class="list-group-item bg-transparent">
34-
<div class="form-check form-switch my-2">
35-
<label class="form-check-label">
36-
<input
37-
class="form-check-input"
38-
type="checkbox"
39-
name="accessibilite"
40-
role="switch"
41-
formControlName="accessibilite"
42-
(change)="setFilterToQueryString('accessibilite')" />
27+
formControlName="fiche_acces_libre"
28+
(change)="setFilterToQueryString('fiche_acces_libre')" />
4329
Accessibilité renseignée
4430
</label>
4531
</div>
@@ -67,7 +53,7 @@
6753
type="checkbox"
6854
name="frais_a_charge"
6955
role="switch"
70-
value="Gratuit : Je peux accéder gratuitement au lieu et à ses services"
56+
value="Gratuit"
7157
appCheckboxArray
7258
formControlName="frais_a_charge"
7359
(change)="setFilterToQueryString('frais_a_charge')" />
@@ -77,9 +63,11 @@
7763
</li>
7864
</ul>
7965
</fieldset>
80-
<ng-container *ngIf="labelNationauxFrom(lieuxMediationNumeriques) as labelNationaux">
66+
<ng-container *ngIf="dispositifProgrammesNationauxFrom(lieuxMediationNumeriques) as labelNationaux">
8167
<fieldset *ngIf="labelNationaux.length > 1">
82-
<legend class="text-uppercase p-2 pt-4 border-bottom bg-white text-muted h6 fw-bold">Labels nationaux</legend>
68+
<legend class="text-uppercase p-2 pt-4 border-bottom bg-white text-muted h6 fw-bold">
69+
Dispositifs et programmes nationaux
70+
</legend>
8371
<ul class="list-group list-group-flush fw-bold">
8472
<li *ngFor="let labelNational of labelNationaux" class="list-group-item bg-transparent">
8573
<div class="form-check form-switch my-2">
@@ -100,6 +88,54 @@
10088
</ul>
10189
</fieldset>
10290
</ng-container>
91+
<ng-container *ngIf="formationsLabelsFrom(lieuxMediationNumeriques) as formationLabels">
92+
<fieldset *ngIf="formationLabels.length > 1">
93+
<legend class="text-uppercase p-2 pt-4 border-bottom bg-white text-muted h6 fw-bold">
94+
Labels, certifications et formations
95+
</legend>
96+
<ul class="list-group list-group-flush fw-bold">
97+
<li *ngFor="let formationLabel of formationLabels" class="list-group-item bg-transparent">
98+
<div class="form-check form-switch my-2">
99+
<label class="form-check-label">
100+
<input
101+
class="form-check-input"
102+
name="formations_labels"
103+
type="checkbox"
104+
role="switch"
105+
[value]="formationLabel"
106+
appCheckboxArray
107+
formControlName="formations_labels"
108+
(change)="setFilterToQueryString('formations_labels')" />
109+
{{ labelMap.get(formationLabel) ?? formationLabel }}
110+
</label>
111+
</div>
112+
</li>
113+
</ul>
114+
</fieldset>
115+
</ng-container>
116+
<ng-container *ngIf="servicesFrom(lieuxMediationNumeriques) as services">
117+
<fieldset *ngIf="services.length > 1">
118+
<legend class="text-uppercase p-2 pt-4 border-bottom bg-white text-muted h6 fw-bold">Services</legend>
119+
<ul class="list-group list-group-flush fw-bold">
120+
<li *ngFor="let service of services" class="list-group-item bg-transparent">
121+
<div class="form-check form-switch my-2">
122+
<label class="form-check-label">
123+
<input
124+
class="form-check-input"
125+
name="service"
126+
type="checkbox"
127+
role="switch"
128+
[value]="service"
129+
appCheckboxArray
130+
formControlName="service"
131+
(change)="setFilterToQueryString('service')" />
132+
{{ labelMap.get(service) ?? service }}
133+
</label>
134+
</div>
135+
</li>
136+
</ul>
137+
</fieldset>
138+
</ng-container>
103139
<ng-container *ngIf="strategiesTerritorialesFrom(lieuxMediationNumeriques) as strategiesTerritoriales">
104140
<fieldset *ngIf="strategiesTerritoriales.length > 0">
105141
<legend class="text-uppercase p-2 pt-4 border-bottom bg-white text-muted h6 fw-bold">Territoires Prioritaires</legend>

src/features/cartographie/components/affiner-recherche-form/affiner-recherche-form.component.ts

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,65 @@
11
import { ChangeDetectionStrategy, Component, Input, Optional } from '@angular/core';
22
import { FormControl, FormGroup } from '@angular/forms';
33
import { ActivatedRoute, Router } from '@angular/router';
4-
import { DispositifProgrammeNational, Frais, Service } from '@gouvfr-anct/lieux-de-mediation-numerique';
4+
import { DispositifProgrammeNational, FormationLabel, Frais, Service } from '@gouvfr-anct/lieux-de-mediation-numerique';
55
import {
66
FilterFormPresentation,
77
LieuMediationNumeriquePresentation,
88
OpeningHours,
99
toFilterFormPresentationFromQuery
1010
} from '../../../core/presenters';
11-
import { dispositifProgrammesNationauxFrom, strategiesTerritorialesFrom } from './affiner-recherche-form.presenter';
11+
import {
12+
dispositifProgrammesNationauxFrom,
13+
formationsLabelsFrom,
14+
servicesFrom,
15+
strategiesTerritorialesFrom
16+
} from './affiner-recherche-form.presenter';
1217
import { MatomoTracker } from 'ngx-matomo';
1318

1419
type AffinerRechercheFields = {
1520
prise_rdv: FormControl<boolean>;
16-
accessibilite: FormControl<boolean>;
21+
fiche_acces_libre: FormControl<boolean>;
1722
horaires_ouverture: FormControl<OpeningHours[] | false>;
1823
frais_a_charge: FormControl<Frais[]>;
1924
dispositif_programmes_nationaux: FormControl<DispositifProgrammeNational[]>;
25+
formations_labels: FormControl<FormationLabel[]>;
2026
autres_formations_labels: FormControl<string[]>;
21-
service: FormControl<Service | undefined>;
27+
service: FormControl<Service[]>;
2228
};
2329

2430
type AffinerRechercheValues = {
2531
prise_rdv: boolean;
26-
accessibilite: boolean;
32+
fiche_acces_libre: boolean;
2733
horaires_ouverture: OpeningHours[] | false;
2834
frais_a_charge: Frais[];
2935
dispositif_programmes_nationaux: DispositifProgrammeNational[];
36+
formations_labels: FormationLabel[];
3037
autres_formations_labels: string[];
31-
service: Service | undefined;
38+
service: Service[];
3239
};
3340

3441
const AFFINER_RECHERCHE_FORM = (
3542
filterFormPresentation: FilterFormPresentation
3643
): FormGroup<Record<keyof AffinerRechercheValues, FormControl>> =>
3744
new FormGroup<Record<keyof AffinerRechercheValues, FormControl>>({
3845
prise_rdv: new FormControl<AffinerRechercheValues['prise_rdv']>(filterFormPresentation.prise_rdv ?? false),
39-
accessibilite: new FormControl<AffinerRechercheValues['accessibilite']>(filterFormPresentation.fiche_acces_libre ?? false),
46+
fiche_acces_libre: new FormControl<AffinerRechercheValues['fiche_acces_libre']>(
47+
filterFormPresentation.fiche_acces_libre ?? false
48+
),
4049
horaires_ouverture: new FormControl<AffinerRechercheValues['horaires_ouverture']>(
4150
filterFormPresentation.horaires_ouverture ?? false
4251
),
4352
frais_a_charge: new FormControl<AffinerRechercheValues['frais_a_charge']>(filterFormPresentation.frais_a_charge ?? []),
4453
dispositif_programmes_nationaux: new FormControl<AffinerRechercheValues['dispositif_programmes_nationaux']>(
4554
filterFormPresentation.dispositif_programmes_nationaux ?? []
4655
),
56+
formations_labels: new FormControl<AffinerRechercheValues['formations_labels']>(
57+
filterFormPresentation.formations_labels ?? []
58+
),
4759
autres_formations_labels: new FormControl<AffinerRechercheValues['autres_formations_labels']>(
4860
filterFormPresentation.autres_formations_labels ?? []
4961
),
50-
service: new FormControl<AffinerRechercheValues['service']>(filterFormPresentation.service)
62+
service: new FormControl<AffinerRechercheValues['service']>(filterFormPresentation.service ?? [])
5163
});
5264

5365
@Component({
@@ -61,7 +73,12 @@ export class AffinerRechercheFormComponent {
6173
public labelMap: Map<string, string> = new Map<string, string>([
6274
[DispositifProgrammeNational.ConseillersNumeriques, DispositifProgrammeNational.ConseillersNumeriques],
6375
['QPV', 'QPV (quartier prioritaire de la ville)'],
64-
['ZRR', 'ZRR (zones de revitalisation rurale)']
76+
['ZRR', 'ZRR (zones de revitalisation rurale)'],
77+
[Service.AideAuxDemarchesAdministratives, 'Démarches administratives'],
78+
[Service.MaitriseDesOutilsNumeriquesDuQuotidien, 'Outils numériques du quotidien'],
79+
[Service.InsertionProfessionnelleViaLeNumerique, 'Insertion professionnelle'],
80+
[Service.ParentaliteEtEducationAvecLeNumerique, 'Parentalité et éducation'],
81+
[Service.MaterielInformatiqueAPrixSolidaire, 'Acquisition de matériel']
6582
]);
6683

6784
public constructor(
@@ -74,15 +91,20 @@ export class AffinerRechercheFormComponent {
7491
toFilterFormPresentationFromQuery(this.route.snapshot.queryParams)
7592
);
7693

77-
public strategiesTerritorialesFrom = strategiesTerritorialesFrom;
94+
public readonly strategiesTerritorialesFrom = strategiesTerritorialesFrom;
95+
96+
public readonly dispositifProgrammesNationauxFrom = dispositifProgrammesNationauxFrom;
97+
98+
public readonly formationsLabelsFrom = formationsLabelsFrom;
7899

79-
public labelNationauxFrom = dispositifProgrammesNationauxFrom;
100+
public readonly servicesFrom = servicesFrom;
80101

81102
public setFilterToQueryString(field: string): void {
82103
this._matomoTracker?.trackEvent('Cartographie', 'Affiner recherche', field);
83104
this.router.navigate([], {
84105
queryParams: {
85106
...this.route.snapshot.queryParams,
107+
[field]: this.affinerRechercheForm.get(field)?.value,
86108
...(field === 'horaires_ouverture' && this.affinerRechercheForm.get(field)?.value
87109
? { horaires_ouverture: JSON.stringify([{ day: 'now' }]) }
88110
: {})

src/features/cartographie/components/affiner-recherche-form/affiner-recherche-form.presenter.spec.ts

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1-
import { DispositifProgrammeNational } from '@gouvfr-anct/lieux-de-mediation-numerique';
2-
import { autresFormationsLabelsFrom, dispositifProgrammesNationauxFrom } from './affiner-recherche-form.presenter';
1+
import { DispositifProgrammeNational, FormationLabel, Service } from '@gouvfr-anct/lieux-de-mediation-numerique';
2+
import {
3+
autresFormationsLabelsFrom,
4+
dispositifProgrammesNationauxFrom,
5+
formationsLabelsFrom,
6+
servicesFrom
7+
} from './affiner-recherche-form.presenter';
38
import { LieuMediationNumeriquePresentation } from '../../../core/presenters';
49

510
describe('affiner recherche form presenter', (): void => {
6-
it('should not get any label national from lieux mediation numerique', (): void => {
11+
it('should not get any dispositif programme national from lieux mediation numerique', (): void => {
712
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [];
813

914
const labelNationaux: DispositifProgrammeNational[] = dispositifProgrammesNationauxFrom(LieuxMediationNumerique);
1015

1116
expect(labelNationaux).toStrictEqual([]);
1217
});
1318

14-
it('should get CnFS label national from lieux mediation numerique', (): void => {
19+
it('should get CnFS dispositif programme national from lieux mediation numerique', (): void => {
1520
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [
1621
{
1722
dispositif_programmes_nationaux: [DispositifProgrammeNational.ConseillersNumeriques]
@@ -23,7 +28,7 @@ describe('affiner recherche form presenter', (): void => {
2328
expect(labelNationaux).toStrictEqual([DispositifProgrammeNational.ConseillersNumeriques]);
2429
});
2530

26-
it('should not get duplicated label national from lieux mediation numerique', (): void => {
31+
it('should not get duplicated dispositif programme national from lieux mediation numerique', (): void => {
2732
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [
2833
{
2934
dispositif_programmes_nationaux: [
@@ -38,6 +43,38 @@ describe('affiner recherche form presenter', (): void => {
3843
expect(labelNationaux).toStrictEqual([DispositifProgrammeNational.ConseillersNumeriques]);
3944
});
4045

46+
it('should not get any formation label from lieux mediation numerique', (): void => {
47+
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [];
48+
49+
const formationsLabels: FormationLabel[] = formationsLabelsFrom(LieuxMediationNumerique);
50+
51+
expect(formationsLabels).toStrictEqual([]);
52+
});
53+
54+
it('should get fabriques de territoire formation label from lieux mediation numerique', (): void => {
55+
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [
56+
{
57+
formations_labels: [FormationLabel.FabriquesDeTerritoire]
58+
} as LieuMediationNumeriquePresentation
59+
];
60+
61+
const formationsLabels: FormationLabel[] = formationsLabelsFrom(LieuxMediationNumerique);
62+
63+
expect(formationsLabels).toStrictEqual([FormationLabel.FabriquesDeTerritoire]);
64+
});
65+
66+
it('should not get duplicated formation label from lieux mediation numerique', (): void => {
67+
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [
68+
{
69+
formations_labels: [FormationLabel.FabriquesDeTerritoire, FormationLabel.FabriquesDeTerritoire]
70+
} as LieuMediationNumeriquePresentation
71+
];
72+
73+
const formationsLabels: FormationLabel[] = formationsLabelsFrom(LieuxMediationNumerique);
74+
75+
expect(formationsLabels).toStrictEqual([FormationLabel.FabriquesDeTerritoire]);
76+
});
77+
4178
it('should not get any label autre from lieux mediation numerique', (): void => {
4279
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [];
4380

@@ -69,4 +106,36 @@ describe('affiner recherche form presenter', (): void => {
69106

70107
expect(labelsAutres).toStrictEqual(['Hinaura']);
71108
});
109+
110+
it('should not get any service from lieux mediation numerique', (): void => {
111+
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [];
112+
113+
const services: Service[] = servicesFrom(LieuxMediationNumerique);
114+
115+
expect(services).toStrictEqual([]);
116+
});
117+
118+
it('should get loisirs et création numérique service from lieux mediation numerique', (): void => {
119+
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [
120+
{
121+
services: [Service.LoisirsEtCreationsNumeriques]
122+
} as LieuMediationNumeriquePresentation
123+
];
124+
125+
const services: Service[] = servicesFrom(LieuxMediationNumerique);
126+
127+
expect(services).toStrictEqual([Service.LoisirsEtCreationsNumeriques]);
128+
});
129+
130+
it('should not get services from lieux mediation numerique', (): void => {
131+
const LieuxMediationNumerique: LieuMediationNumeriquePresentation[] = [
132+
{
133+
services: [Service.LoisirsEtCreationsNumeriques, Service.LoisirsEtCreationsNumeriques]
134+
} as LieuMediationNumeriquePresentation
135+
];
136+
137+
const services: Service[] = servicesFrom(LieuxMediationNumerique);
138+
139+
expect(services).toStrictEqual([Service.LoisirsEtCreationsNumeriques]);
140+
});
72141
});

src/features/cartographie/components/affiner-recherche-form/affiner-recherche-form.presenter.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,34 @@
1-
import { DispositifProgrammeNational } from '@gouvfr-anct/lieux-de-mediation-numerique';
1+
import { DispositifProgrammeNational, FormationLabel, Service } from '@gouvfr-anct/lieux-de-mediation-numerique';
22
import { LieuMediationNumeriquePresentation } from '../../../core/presenters';
33

44
const toDispositifProgrammesNationaux = (
55
lieuMediationNumerique: LieuMediationNumeriquePresentation
66
): DispositifProgrammeNational[] => lieuMediationNumerique.dispositif_programmes_nationaux ?? [];
77

8+
const toFormationsLabels = (lieuMediationNumerique: LieuMediationNumeriquePresentation): FormationLabel[] =>
9+
lieuMediationNumerique.formations_labels ?? [];
10+
811
const toAutresFormationsLabels = (lieuMediationNumerique: LieuMediationNumeriquePresentation): string[] =>
912
lieuMediationNumerique.autres_formations_labels ?? [];
1013

14+
const toServices = (lieuMediationNumerique: LieuMediationNumeriquePresentation): Service[] =>
15+
lieuMediationNumerique.services ?? [];
16+
1117
const deduplicate = <T>(duplicates: T[]): T[] => Array.from(new Set(duplicates));
1218

1319
export const dispositifProgrammesNationauxFrom = (
1420
LieuxMediationNumerique: LieuMediationNumeriquePresentation[]
1521
): DispositifProgrammeNational[] => deduplicate(LieuxMediationNumerique.flatMap(toDispositifProgrammesNationaux));
1622

23+
export const formationsLabelsFrom = (LieuxMediationNumerique: LieuMediationNumeriquePresentation[]): FormationLabel[] =>
24+
deduplicate(LieuxMediationNumerique.flatMap(toFormationsLabels));
25+
1726
export const autresFormationsLabelsFrom = (LieuxMediationNumerique: LieuMediationNumeriquePresentation[]): string[] =>
1827
deduplicate(LieuxMediationNumerique.flatMap(toAutresFormationsLabels));
1928

29+
export const servicesFrom = (LieuxMediationNumerique: LieuMediationNumeriquePresentation[]): Service[] =>
30+
deduplicate(LieuxMediationNumerique.flatMap(toServices));
31+
2032
export const strategiesTerritorialesFrom = (LieuxMediationNumerique: LieuMediationNumeriquePresentation[]): string[] =>
2133
autresFormationsLabelsFrom(LieuxMediationNumerique).filter(
2234
(autreLabel: string) => autreLabel === 'QPV' || autreLabel === 'ZRR'

src/features/core/presenters/filter/filter.presenter.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ describe('démarrer page prensenter', (): void => {
3030

3131
it('should indicates that there is an active filter when service is defined', (): void => {
3232
const filterFormPresentation: FilterFormPresentation = {
33-
service: Service.MaitriseDesOutilsNumeriquesDuQuotidien
33+
service: [Service.MaitriseDesOutilsNumeriquesDuQuotidien]
3434
};
3535

3636
const activeFilter: boolean = hasActiveFilter(filterFormPresentation);

0 commit comments

Comments
 (0)