diff --git a/src/app/admin/components/manage-employers/manage-employers.component.html b/src/app/admin/components/manage-employers/manage-employers.component.html index 7bb145742b57644ad94b64bdfae95fac201877fb..c3ad3cb17d0428ac0af7f67754ade3cfc22648c6 100644 --- a/src/app/admin/components/manage-employers/manage-employers.component.html +++ b/src/app/admin/components/manage-employers/manage-employers.component.html @@ -18,7 +18,7 @@ [columnDefs]="unvalidEmployersColumnDefs" [getRowHeight]="getRowHeight" [defaultColDef]="unvalidColDef" - [frameworkComponents]="frameworkComponents" + [components]="components" /> <h3 *ngIf="validatedEmployers" class="title">Employeurs validés ({{ validatedEmployers.length }})</h3> @@ -32,19 +32,22 @@ [columnDefs]="columnDefs" [getRowHeight]="getRowHeight" [defaultColDef]="defaultColDef" - [frameworkComponents]="frameworkComponents" + [components]="components" /> <h3 *ngIf="validatedEmployers" class="title">Créer un nouvel employeur</h3> <form [formGroup]="newEmployerForm" (ngSubmit)="onSubmit()"> - <div class="inline" style="align-items: flex-end"> + <div class="inline"> <app-input size="large" label="Nouvel employeur" [value]="employer.value" (valueChange)="employer.setValue($event)" - /> - <app-button type="submit" variant="secondary" label="Créer" [disabled]="newEmployerForm.invalid" /> + id="newEmployer" + [status]="null" + [externalStatusControl]="true" + ></app-input> + <app-button type="submit" variant="secondary" label="Créer" [disabled]="newEmployerForm.invalid"></app-button> </div> </form> </div> diff --git a/src/app/admin/components/manage-employers/manage-employers.component.scss b/src/app/admin/components/manage-employers/manage-employers.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e48c426ebe04dc4a717537b7e8643cb999157ba0 --- /dev/null +++ b/src/app/admin/components/manage-employers/manage-employers.component.scss @@ -0,0 +1,8 @@ +::ng-deep .ag-popup { + max-height: 100px; + overflow: auto; +} + +.inline { + align-items: flex-end; +} diff --git a/src/app/admin/components/manage-employers/manage-employers.component.ts b/src/app/admin/components/manage-employers/manage-employers.component.ts index 20e79dea0b4867846ba6f47bded3dccdb9680a38..1b5b5170d053fe90b23246a8544413e349e53606 100644 --- a/src/app/admin/components/manage-employers/manage-employers.component.ts +++ b/src/app/admin/components/manage-employers/manage-employers.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; import { ColDef } from 'ag-grid-community'; import { Employer } from '../../../models/employer.model'; import { NotificationService } from '../../../services/notification.service'; @@ -12,7 +12,7 @@ import { ValidateEmployerComponent } from './validate-employer/validate-employer @Component({ selector: 'app-admin-manage-employers', templateUrl: './manage-employers.component.html', - styleUrls: ['../../admin.scss'], + styleUrls: ['../../admin.scss', 'manage-employers.component.scss'], }) export class ManageEmployersComponent { public newEmployerForm = new FormGroup({ @@ -35,7 +35,7 @@ export class ManageEmployersComponent { public columnDefs: ColDef<Employer>[]; public unvalidEmployersColumnDefs: ColDef<Employer>[]; - public frameworkComponents; + public components; public defaultColDef = { editable: true, sortable: true, @@ -120,7 +120,7 @@ export class ManageEmployersComponent { }, }, ]; - this.frameworkComponents = { + this.components = { employerRenderer: EmployerRendererComponent, deleteEmployerComponent: DeleteEmployerComponent, attachedUsersComponent: AttachedUsersComponent, @@ -128,8 +128,8 @@ export class ManageEmployersComponent { }; } - get employer(): AbstractControl<string, string> { - return this.newEmployerForm.get('employer'); + get employer(): FormControl { + return this.newEmployerForm.get('employer') as FormControl; } public onDeleteButtonClick(arg): void { @@ -137,19 +137,18 @@ export class ManageEmployersComponent { } public onSubmit(): void { - if (!this.newEmployerForm.valid) { - return; + if (this.newEmployerForm.valid) { + this.adminService.createEmployer(this.employer.value).subscribe( + () => { + this.findValidatedEmployers(); + this.newEmployerForm.reset(); + this.notificationService.showSuccess('Votre employeur a bien été créé'); + }, + (err) => { + this.notificationService.showError(`${err.error.message}`, 'Une erreur est survenue'); + }, + ); } - this.adminService.createEmployer(this.employer.value).subscribe( - () => { - this.findValidatedEmployers(); - this.newEmployerForm.reset(); - this.notificationService.showSuccess('Votre employeur a bien été créée'); - }, - (err) => { - this.notificationService.showError(`${err.error.message}`, 'Une erreur est survenue'); - }, - ); } public onValidateButtonClick(arg): void { @@ -233,6 +232,21 @@ export class ManageEmployersComponent { employers.sort((a, b) => a.users.length - b.users.length); this.validatedEmployers = employers; this.validatedEmployersName = employers.map((employer) => employer.name); + this.updateUnvalidEmployersColumnDefs(); + }); + } + + updateUnvalidEmployersColumnDefs() { + this.unvalidEmployersColumnDefs = this.unvalidEmployersColumnDefs.map((col) => { + if (col.field === '_id') { + return { + ...col, + cellEditorParams: { + values: this.validatedEmployersName, + }, + }; + } + return col; }); } diff --git a/src/app/admin/components/manage-jobs/manage-jobs.component.html b/src/app/admin/components/manage-jobs/manage-jobs.component.html index 0e4702bf328ac1361357e8ffdb6c0e12602a1083..938a0c117de2c14d29b1d71abc0d30016a9c5592 100644 --- a/src/app/admin/components/manage-jobs/manage-jobs.component.html +++ b/src/app/admin/components/manage-jobs/manage-jobs.component.html @@ -16,7 +16,7 @@ [columnDefs]="unvalidJobsColumnDefs" [getRowHeight]="getUsersRowHeight" [defaultColDef]="unvalidColDef" - [frameworkComponents]="frameworkComponents" + [components]="components" /> <h3 *ngIf="validatedJobs" class="title">Fonctions validées ({{ validatedJobs.length }})</h3> @@ -30,13 +30,21 @@ [columnDefs]="columnDefs" [getRowHeight]="getUsersRowHeight" [defaultColDef]="defaultColDef" - [frameworkComponents]="frameworkComponents" + [components]="components" /> <h3 *ngIf="validatedJobs" class="title">Créer une nouvelle fonction</h3> <form [formGroup]="newJobForm" (ngSubmit)="onSubmit()"> - <div class="inline" style="align-items: flex-end"> - <app-input label="Nouvelle fonction" size="large" [value]="job.value" (valueChange)="job.setValue($event)" /> + <div class="inline"> + <app-input + label="Nouvelle fonction" + size="large" + [value]="job.value" + (valueChange)="job.setValue($event)" + id="newJob" + [status]="null" + [externalStatusControl]="true" + /> <app-button type="submit" variant="secondary" label="Créer" [disabled]="newJobForm.invalid" /> </div> </form> @@ -58,17 +66,20 @@ [columnDefs]="columnDefsJobsGroups" [getRowHeight]="getJobsRowHeight" [defaultColDef]="defaultColDef" - [frameworkComponents]="frameworkComponents" + [components]="components" /> <h3 class="title">Créer un nouveau groupe de fonctions</h3> <form [formGroup]="newJobsGroupForm" (ngSubmit)="onSubmitNewJobsGroup()"> - <div class="inline" style="align-items: flex-end"> + <div class="inline"> <app-input label="Nouveau groupe de fonction" size="large" [value]="jobsGroup.value" (valueChange)="jobsGroup.setValue($event)" + id="newJobsGroup" + [status]="null" + [externalStatusControl]="true" /> <app-button type="submit" variant="secondary" label="Créer" [disabled]="newJobsGroupForm.invalid" /> </div> diff --git a/src/app/admin/components/manage-jobs/manage-jobs.component.ts b/src/app/admin/components/manage-jobs/manage-jobs.component.ts index 821697e2ae4e9eba52cac72b6277e50297069001..b6ef05caa292b14b85ffbcbcbc8de0a5408b0a57 100644 --- a/src/app/admin/components/manage-jobs/manage-jobs.component.ts +++ b/src/app/admin/components/manage-jobs/manage-jobs.component.ts @@ -16,7 +16,7 @@ import { ValidateJobComponent } from './validate-job/validate-job.component'; @Component({ selector: 'app-admin-manage-jobs', templateUrl: './manage-jobs.component.html', - styleUrls: ['../../admin.scss'], + styleUrls: ['../../admin.scss', '../manage-employers/manage-employers.component.scss'], }) export class ManageJobsComponent { public newJobForm = new FormGroup({ @@ -51,7 +51,7 @@ export class ManageJobsComponent { public columnDefs: ColDef<Job>[]; public columnDefsJobsGroups: ColDef<Job>[]; public unvalidJobsColumnDefs: ColDef<Job>[]; - public frameworkComponents; + public components; public defaultColDef: ColDef = { editable: true, sortable: true, @@ -150,7 +150,7 @@ export class ManageJobsComponent { }, }, ]; - this.frameworkComponents = { + this.components = { jobRenderer: JobRendererComponent, jobPersonalOffer: JobPersonalOfferComponent, deleteJobComponent: DeleteJobComponent, @@ -229,20 +229,19 @@ export class ManageJobsComponent { } public onSubmit(): void { - if (!this.newJobForm.valid) { - return; + if (this.newJobForm.valid) { + const name: string = this.newJobForm.value.job; + this.adminService.createJob(name).subscribe( + () => { + this.findValidatedJobs(); + this.newJobForm.reset(); + this.notificationService.showSuccess('Votre fonction a bien été créée'); + }, + (err) => { + this.notificationService.showError(`${err.error.message}`, 'Une erreur est survenue'); + }, + ); } - const name: string = this.newJobForm.value.job; - this.adminService.createJob(name).subscribe( - () => { - this.findValidatedJobs(); - this.newJobForm.reset(); - this.notificationService.showSuccess('Votre fonction a bien été créée'); - }, - (err) => { - this.notificationService.showError(`${err.error.message}`, 'Une erreur est survenue'); - }, - ); } public onValidateButtonClick(arg): void { diff --git a/src/app/annuaire/annuaire-header/annuaire-header.component.html b/src/app/annuaire/annuaire-header/annuaire-header.component.html index 91153afc10ad6fc7f7ffb3971d319fe25648f613..ff353987827c45603b864f59e0aed4267552fc6f 100644 --- a/src/app/annuaire/annuaire-header/annuaire-header.component.html +++ b/src/app/annuaire/annuaire-header/annuaire-header.component.html @@ -14,14 +14,26 @@ [checkedModules]="employerCheckedModules" (selectEvent)="onSelectEmployers($event)" /> + <app-collapsable-filter + [label]="'Territoire'" + [categories]="territoryCategories" + [checkedModules]="territoryCheckedModules" + (selectEvent)="onSelectTerritory($event)" + /> + <app-collapsable-filter + [label]="'Commune'" + [categories]="communeCategories" + [checkedModules]="communeCheckedModules" + (selectEvent)="onSelectCommune($event)" + /> </div> </div> - <div *ngIf="searchService.checkedFilterList.length" class="filterTags isntPhoneContent"> + <div *ngIf="checkedModulesFilter.length" class="filterTags isntPhoneContent"> <div class="title">Filtres :</div> <app-tag-item - *ngFor="let filter of searchService.checkedFilterList" + *ngFor="let filter of checkedModulesFilter" [ariaLabel]="'Supprimer filtre ' + filter" - [label]="filter" + [label]="filter.displayText" [size]="'small'" [color]="'grey'" [iconName]="'cross'" diff --git a/src/app/annuaire/annuaire-header/annuaire-header.component.ts b/src/app/annuaire/annuaire-header/annuaire-header.component.ts index 3df6eea39ef9a7293f2426828db441c7526695dd..cad43d88a10032f4d175efeb08543dc2b60e993b 100644 --- a/src/app/annuaire/annuaire-header/annuaire-header.component.ts +++ b/src/app/annuaire/annuaire-header/annuaire-header.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { forkJoin, lastValueFrom } from 'rxjs'; +import { firstValueFrom, forkJoin, lastValueFrom } from 'rxjs'; import { Category } from '../../structure-list/models/category.model'; import { Module } from '../../structure-list/models/module.model'; import { SearchService } from '../../structure-list/services/search.service'; @@ -12,22 +12,20 @@ import { SearchQuery } from '../models/searchQuery.model'; styleUrls: ['./annuaire-header.component.scss'], }) export class AnnuaireHeaderComponent implements OnInit, OnChanges { - /** Input to reset filters, needed because a reset button is displayed on the result list when it is empty */ @Input() shouldResetFilters = 0; @Output() searchEvent = new EventEmitter<SearchQuery>(); public jobGroupCategories: Category[] = []; public employerCategories: Category[] = []; + public territoryCategories: Category[] = []; + public communeCategories: Category[] = []; public searchInput = ''; - // Checked modules for each filter (used to receive changes from collapsable-filter) + public checkedModulesFilter: Module[] = []; public jobGroupCheckedModules: Module[] = []; public employerCheckedModules: Module[] = []; - - private jobGroups: string[] = []; - private employers: string[] = []; - private jobGroupFilterChecked: string[] = []; - private employerFilterChecked: string[] = []; + public territoryCheckedModules: Module[] = []; + public communeCheckedModules: Module[] = []; constructor( private activatedRoute: ActivatedRoute, @@ -36,12 +34,15 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { ) {} async ngOnInit(): Promise<void> { - this.loadQueryParams(); // Will store the different categories await this.loadFilters(); + this.loadQueryParams(); + if (this.searchService.previousResult$.getValue().docs.length === 0) { this.applyFilter(); + } else { + this.setCheckedModulesFilter(); } } @@ -54,15 +55,27 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { private loadQueryParams(): void { const queryParams = this.activatedRoute.snapshot.queryParams; this.searchInput = queryParams['search'] ?? ''; - this.jobGroupFilterChecked = queryParams['jobs']?.split('|') ?? []; - this.employerFilterChecked = queryParams['employers']?.split('|') ?? []; - this.searchService.checkedFilterList = [...this.jobGroupFilterChecked, ...this.employerFilterChecked]; - this.searchService.annuaireSearchQuery = { - search: this.searchInput, - page: Number(queryParams['page']) || 1, - jobFilters: this.jobGroupFilterChecked, - employerFilters: this.employerFilterChecked, - }; + const jobGroupFilterChecked = queryParams['jobs']?.split('|') ?? []; + const employerFilterChecked = queryParams['employers']?.split('|') ?? []; + const territoryFilterChecked = queryParams['territories']?.split('|') ?? []; + const communeFilterChecked = queryParams['communes']?.split('|') ?? []; + + // We need to map to set the type in module name, as it is done in checkedModules of the collapsable-filter/more-filters component + this.jobGroupCheckedModules = this.jobGroupCategories[0]?.modules + .filter((module) => jobGroupFilterChecked.includes(module.name)) + .map((module) => ({ ...module, displayText: module.name, name: 'jobGroup' })); + + this.employerCheckedModules = this.employerCategories[0]?.modules + .filter((module) => employerFilterChecked.includes(module.name)) + .map((module) => ({ ...module, displayText: module.name, name: 'employer' })); + + this.territoryCheckedModules = this.territoryCategories[0]?.modules + .filter((module) => territoryFilterChecked.includes(module.name)) + .map((module) => ({ ...module, displayText: module.name, name: 'ctm' })); + + this.communeCheckedModules = this.communeCategories[0]?.modules + .filter((module) => communeFilterChecked.includes(module.name)) + .map((module) => ({ ...module, displayText: module.name, name: 'commune' })); } public onSearchSubmitted(value: string): void { @@ -76,13 +89,17 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { if (this.searchInput.trim()) { queryParams.search = this.searchInput.trim(); } - - if (this.jobGroupFilterChecked.length) { - queryParams.jobs = this.jobGroupFilterChecked.join('|'); + if (this.jobGroupCheckedModules.length) { + queryParams.jobs = this.jobGroupCheckedModules.map((module) => module.displayText).join('|'); } - - if (this.employerFilterChecked.length) { - queryParams.employers = this.employerFilterChecked.join('|'); + if (this.employerCheckedModules.length) { + queryParams.employers = this.employerCheckedModules.map((module) => module.displayText).join('|'); + } + if (this.territoryCheckedModules.length) { + queryParams.territories = this.territoryCheckedModules.map((module) => module.displayText).join('|'); + } + if (this.communeCheckedModules.length) { + queryParams.communes = this.communeCheckedModules.map((module) => module.displayText).join('|'); } // Delay to avoid error in console: "NG0100: ExpressionChangedAfterItHasBeenCheckedError" @@ -96,19 +113,25 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { ); } - public applyFilter(page = 1): void { - this.jobGroupCheckedModules = this.jobGroupFilterChecked.map((filter) => { - return new Module(filter, 'jobGroup', filter); - }); - this.employerCheckedModules = this.employerFilterChecked.map((filter) => { - return new Module(filter, 'employer', filter); - }); + private setCheckedModulesFilter(): void { + this.checkedModulesFilter = [ + ...this.jobGroupCheckedModules, + ...this.employerCheckedModules, + ...this.territoryCheckedModules, + ...this.communeCheckedModules, + ]; + } + + private applyFilter(page = 1): void { + this.setCheckedModulesFilter(); this.searchEvent.emit({ search: this.searchInput.trim(), page: page, - jobFilters: this.jobGroupFilterChecked, - employerFilters: this.employerFilterChecked, + jobFilters: this.jobGroupCheckedModules.map((module) => module.id), + employerFilters: this.employerCheckedModules.map((module) => module.id), + territoryFilters: this.territoryCheckedModules.map((module) => module.id), + communeFilters: this.communeCheckedModules.map((module) => module.id), }); this.updateQueryParams(); @@ -122,8 +145,6 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { employers: this.searchService.getEmployers(), }), ); - this.jobGroups = jobGroups; - this.employers = employers; this.jobGroupCategories = [ { id: 'jobGroup', @@ -135,8 +156,8 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { jobGroups.forEach((jobGroup) => { this.jobGroupCategories[0].modules.push({ disabled: false, - name: jobGroup, - id: jobGroup, + name: jobGroup.name, + id: jobGroup._id, }); }); @@ -151,43 +172,86 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { employers.forEach((employer) => { this.employerCategories[0].modules.push({ disabled: false, - name: employer, - id: employer, + name: employer.name, + id: employer._id, }); }); - } - private splitFilters(checkedFilterList: string[]): void { - this.jobGroupFilterChecked = checkedFilterList.filter((filter) => this.jobGroups.includes(filter)); - this.employerFilterChecked = checkedFilterList.filter((filter) => this.employers.includes(filter)); + // Territories + const categories = await firstValueFrom(this.searchService.getCategories()); + const ctmCategory = categories.find((c) => c.id === 'ctm'); + if (ctmCategory) { + this.territoryCategories = [ + { + id: 'ctm', + name: 'ctm', + theme: 'ctm', + modules: ctmCategory.modules.map((module) => ({ + disabled: false, + name: module.name, + id: module.id, + })), + }, + ]; + } + + // Communes + const communes = await lastValueFrom(this.searchService.getCommunesWithUsers()); + this.communeCategories = [ + { + id: 'commune', + name: 'Commune', + theme: 'Communes', + modules: communes.map((commune) => ({ + disabled: false, + name: commune.commune, + id: commune.inseeCode, + })), + }, + ]; } public onSelectJobGroups(jobGroupCheckedModules: Module[]): void { - this.jobGroupFilterChecked = jobGroupCheckedModules.map((module) => module.id); - this.searchService.checkedFilterList = [...this.jobGroupFilterChecked, ...this.employerFilterChecked]; + this.jobGroupCheckedModules = jobGroupCheckedModules; this.applyFilter(); } public onSelectEmployers(employerCheckedModules: Module[]): void { - this.employerFilterChecked = employerCheckedModules.map((module) => module.id); - this.searchService.checkedFilterList = [...this.jobGroupFilterChecked, ...this.employerFilterChecked]; + this.employerCheckedModules = employerCheckedModules; + this.applyFilter(); + } + + public onSelectTerritory(territoryCheckedModules: Module[]): void { + this.territoryCheckedModules = territoryCheckedModules; + this.applyFilter(); + } + + public onSelectCommune(communeCheckedModules: Module[]): void { + this.communeCheckedModules = communeCheckedModules; this.applyFilter(); } public resetFilters(): void { this.searchInput = ''; - this.searchService.checkedFilterList = []; - this.jobGroupFilterChecked = []; - this.employerFilterChecked = []; + this.jobGroupCheckedModules = []; + this.employerCheckedModules = []; + this.territoryCheckedModules = []; + this.communeCheckedModules = []; this.applyFilter(); } - public removeFilter(filter: string): void { - const index = this.searchService.checkedFilterList.findIndex((checkedFilter: string) => checkedFilter === filter); + public removeFilter(module: Module): void { + const index: number = this.checkedModulesFilter.findIndex((m: Module) => m.id === module.id); if (index !== -1) { - this.searchService.checkedFilterList.splice(index, 1); - this.splitFilters(this.searchService.checkedFilterList); - this.updateQueryParams(); + // update global list of checked filters + this.checkedModulesFilter = this.checkedModulesFilter.filter((m: Module) => m.id !== module.id); + // update each select + this.jobGroupCheckedModules = this.checkedModulesFilter.filter((module) => module.name === 'jobGroup'); + this.employerCheckedModules = this.checkedModulesFilter.filter((module) => module.name === 'employer'); + this.territoryCheckedModules = this.checkedModulesFilter.filter((module) => module.name === 'ctm'); + this.communeCheckedModules = this.checkedModulesFilter.filter((module) => module.name === 'commune'); + + // this.updateQueryParams(); this.applyFilter(); } } diff --git a/src/app/annuaire/annuaire.component.ts b/src/app/annuaire/annuaire.component.ts index bf9108a699929afa6e10c63b37ac92ccf7dd40a4..470aa662d12aec279af37243f403d3dd9f44a6ca 100644 --- a/src/app/annuaire/annuaire.component.ts +++ b/src/app/annuaire/annuaire.component.ts @@ -24,16 +24,6 @@ export class AnnuaireComponent implements OnInit { private isAlreadySearching = false; ngOnInit(): void { - this.route.queryParams.subscribe((params) => { - const searchQuery: SearchQuery = { - search: params['search'] || '', - page: Number(params['page']) || 1, - jobFilters: params['jobs'] ? params['jobs'].split('|') : [], - employerFilters: params['employers'] ? params['employers'].split('|') : [], - }; - this.searchUsers(searchQuery); - }); - if (this.userIsLoggedIn()) { this.userList = this.searchService.previousResult$.getValue().docs; this.totalUserResult = this.searchService.previousResult$.getValue().count; @@ -66,7 +56,14 @@ export class AnnuaireComponent implements OnInit { this.loadParams(params); this.isLoading = true; this.searchService - .searchUserRegistry(params.search, params.page, params.jobFilters, params.employerFilters) + .searchUserRegistry( + params.search, + params.page, + params.jobFilters, + params.employerFilters, + params.territoryFilters, + params.communeFilters, + ) .then((res) => { // We only push new users instead of reassigning userList to avoid an unwanted scroll this.userList.push(...res.docs); diff --git a/src/app/annuaire/models/searchQuery.model.ts b/src/app/annuaire/models/searchQuery.model.ts index 61a73194f8e9d52b920163dcedbbd7257ce3ca2b..f7cee1b52b1e2a984481ff4ef5f5041bfa74076c 100644 --- a/src/app/annuaire/models/searchQuery.model.ts +++ b/src/app/annuaire/models/searchQuery.model.ts @@ -5,6 +5,8 @@ export interface SearchQuery { page?: number; jobFilters?: string[]; employerFilters?: string[]; + territoryFilters?: string[]; + communeFilters?: string[]; } export interface SearchResults { count: number; diff --git a/src/app/carto/carto.component.ts b/src/app/carto/carto.component.ts index 9f384e8af08b3b588767308f1377919a753fce2f..8c50ecba492c99308f9161f7ac3430814cb6b919 100644 --- a/src/app/carto/carto.component.ts +++ b/src/app/carto/carto.component.ts @@ -2,6 +2,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Meta } from '@angular/platform-browser'; import { ActivatedRoute } from '@angular/router'; import * as _ from 'lodash'; +import { NeedsTypes } from '../form/orientation-form-view/enums/orientation.enums'; import { GeoJson } from '../map/models/geojson.model'; import { Structure } from '../models/structure.model'; import { ProfileService } from '../profile/services/profile.service'; @@ -22,6 +23,7 @@ export class CartoComponent implements OnInit { @Input() public userLatitude: number = null; @Input() public userLongitude: number = null; @Input() public structuresSelected: Structure[] = []; + @Input() public needType: NeedsTypes = null; @Output() structureSelection = new EventEmitter<any>(); @Output() structureSelectionRDV = new EventEmitter<any>(); @@ -91,10 +93,15 @@ export class CartoComponent implements OnInit { } if (mustLoadStructures) { - // For orientation rdv, structure offers will be ignored: we filter only on personalOffers of the structure with appointment + // For orientation rdv: we filter only on personalOffers of the structure with appointment which allows orientation this.structureService.getStructures(filters, 'search', this.isOrientationRdv).subscribe((structures) => { if (structures) { - if (this.isOrientationRdv) structures = structures.filter((structure) => structure.hasUserWithAppointmentDN); + if (this.isOrientationRdv) { + structures = structures.filter((structure) => structure.hasUserWithAppointmentDN); + } + if (this.needType === NeedsTypes.onlineDemarch) { + structures = structures.filter((structure) => structure.allowOrientation); + } this.updateStructuresDistance(structures, this.userLongitude, this.userLatitude, sortByDistance); } else { this.structures = []; diff --git a/src/app/form/form-view/form-view.component.ts b/src/app/form/form-view/form-view.component.ts index fd4498791e8962cfc95a3f37c1877e68024204cb..b6fd2d625d8f3e34125ea3fbdfd6df2ebaa4eba5 100644 --- a/src/app/form/form-view/form-view.component.ts +++ b/src/app/form/form-view/form-view.component.ts @@ -443,6 +443,10 @@ export class FormViewComponent implements OnInit, AfterViewInit { return { pmrAccess: this.structureForm.get('pmrAccess').value, }; + case structureFormStep.structureAllowOrientation: + return { + allowOrientation: this.structureForm.get('allowOrientation').value, + }; case structureFormStep.structureWebAndSocialNetwork: return { facebook: this.structureForm.get('facebook').value, diff --git a/src/app/form/form-view/form-view.module.ts b/src/app/form/form-view/form-view.module.ts index d74d10215e3edf1f050c771a3429bbf5e470254f..3b653de9e3b6aee2f1b9def2e5d006923861bb8f 100644 --- a/src/app/form/form-view/form-view.module.ts +++ b/src/app/form/form-view/form-view.module.ts @@ -20,6 +20,7 @@ import { ProfileJobSelectionComponent } from './profile-form/profile-job-selecti import { ProfileStructureChoiceComponent } from './profile-form/profile-structure-choice/profile-structure-choice.component'; import { StructureAccessModalityComponent } from './structure-form/structure-access-modality/structure-access-modality.component'; import { StructureAccompanimentChoiceComponent } from './structure-form/structure-accompaniment-choice/structure-accompaniment-choice.component'; +import { StructureAllowOrientationComponent } from './structure-form/structure-allow-orientation/structure-allow-orientation.component'; import { StructureConsentComponent } from './structure-form/structure-consent/structure-consent.component'; import { StructureContactComponent } from './structure-form/structure-contact/structure-contact.component'; import { StructureDescriptionComponent } from './structure-form/structure-description/structure-description.component'; @@ -60,6 +61,7 @@ import { StructureWifiComponent } from './structure-form/structure-wifi/structur StructureDigitalHelpingAccompanimentComponent, StructureTrainingPriceComponent, StructureWifiComponent, + StructureAllowOrientationComponent, StructureEquipmentsComponent, StructureLabelsComponent, StructureDescriptionComponent, diff --git a/src/app/form/form-view/structure-form/structure-allow-orientation/structure-allow-orientation.component.html b/src/app/form/form-view/structure-form/structure-allow-orientation/structure-allow-orientation.component.html new file mode 100644 index 0000000000000000000000000000000000000000..9d0ecc57a4316c30d04afc4e956362eab4590dbb --- /dev/null +++ b/src/app/form/form-view/structure-form/structure-allow-orientation/structure-allow-orientation.component.html @@ -0,0 +1,22 @@ +<form [formGroup]="structureForm"> + <app-go-back *ngIf="isEditMode" (action)="goBack()" /> + <div class="title"> + <h3>Est-il possible d’orienter des bénéficiaires vers cette structure ?</h3> + </div> + <div class="formGroup"> + <app-radio-option + [id]="'yes'" + [label]="'Oui'" + [value]="true" + [selected]="structureForm.get('allowOrientation').value === true" + (click)="onRadioChange('allowOrientation', true)" + /> + <app-radio-option + [id]="'no'" + [label]="'Non'" + [value]="false" + [selected]="structureForm.get('allowOrientation').value === false" + (click)="onRadioChange('allowOrientation', false)" + /> + </div> +</form> diff --git a/src/app/form/form-view/structure-form/structure-allow-orientation/structure-allow-orientation.component.ts b/src/app/form/form-view/structure-form/structure-allow-orientation/structure-allow-orientation.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..19d4b407144d801eca91faf86c77f985a3067db3 --- /dev/null +++ b/src/app/form/form-view/structure-form/structure-allow-orientation/structure-allow-orientation.component.ts @@ -0,0 +1,27 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { UntypedFormGroup } from '@angular/forms'; +import { FormUtils } from 'src/app/utils/formUtils'; + +@Component({ + selector: 'app-structure-allow-orientation', + templateUrl: './structure-allow-orientation.component.html', +}) +export class StructureAllowOrientationComponent implements OnInit { + @Input() structureForm: UntypedFormGroup; + @Input() isEditMode: boolean; + @Output() radioChange = new EventEmitter<any>(); + @Output() validateForm = new EventEmitter<any>(); + + public formUtils = new FormUtils(); + ngOnInit(): void { + this.validateForm.emit(); + } + + public onRadioChange(name: string, value: boolean): void { + this.radioChange.emit({ name, value }); + this.validateForm.emit(); + } + public goBack(): void { + history.back(); + } +} diff --git a/src/app/form/form-view/structure-form/structure-form.component.html b/src/app/form/form-view/structure-form/structure-form.component.html index d426db66719ea1e6ddaee0a18cb48bc2f5c40383..4561235a24aa3bfb2a80914f65a87c04e1751396 100644 --- a/src/app/form/form-view/structure-form/structure-form.component.html +++ b/src/app/form/form-view/structure-form/structure-form.component.html @@ -78,6 +78,14 @@ (radioChange)="onRadioChange($event)" /> </div> +<div *ngIf="currentStep === structureFormStep.structureAllowOrientation"> + <app-structure-allow-orientation + [isEditMode]="isEditMode" + [structureForm]="structureForm" + (validateForm)="setValidationsForm()" + (radioChange)="onRadioChange($event)" + /> +</div> <div *ngIf="currentStep === structureFormStep.structureWebAndSocialNetwork"> <app-structure-web-and-social-network [isEditMode]="isEditMode" diff --git a/src/app/form/form-view/structure-form/structure-form.component.ts b/src/app/form/form-view/structure-form/structure-form.component.ts index 5a6b30b1581d8a04d6e873162381c300ad775ead..b628571628d5b9f842ae245002aa211721dafebd 100644 --- a/src/app/form/form-view/structure-form/structure-form.component.ts +++ b/src/app/form/form-view/structure-form/structure-form.component.ts @@ -123,6 +123,9 @@ export class StructureFormComponent implements OnInit, OnChanges { this.pagesValidation[structureFormStep.structurePmr] = { valid: this.structureForm.get('pmrAccess').valid, }; + this.pagesValidation[structureFormStep.structureAllowOrientation] = { + valid: this.structureForm.get('allowOrientation').valid, + }; this.pagesValidation[structureFormStep.structureWebAndSocialNetwork] = { valid: this.structureForm.get('website').valid && diff --git a/src/app/form/form-view/structure-form/structureFormStep.enum.ts b/src/app/form/form-view/structure-form/structureFormStep.enum.ts index ca7aeca355ccde89dabe9bf2ad5632004e65c2a5..71e9a18f9e20b3176ccd64e0fc313373add81796 100644 --- a/src/app/form/form-view/structure-form/structureFormStep.enum.ts +++ b/src/app/form/form-view/structure-form/structureFormStep.enum.ts @@ -8,6 +8,7 @@ export enum structureFormStep { structureAccessModality, structureHours, structurePmr, + structureAllowOrientation, structureWebAndSocialNetwork, structurePublicTarget, /** Accompagnements adaptés à des publics spécifiques */ diff --git a/src/app/form/orientation-form-view/equipment-access/equipment-access.component.html b/src/app/form/orientation-form-view/equipment-access/equipment-access.component.html index 51673974545d459600608cafa25d292b7b66ec66..f67f34a95cfe251592b356b2d3148cd2a78265b2 100644 --- a/src/app/form/orientation-form-view/equipment-access/equipment-access.component.html +++ b/src/app/form/orientation-form-view/equipment-access/equipment-access.component.html @@ -5,6 +5,7 @@ /> <app-orientation-structure-list *ngIf="genericStep === GenericOrientationSteps.accompanimentTunnel" + [needType]="NeedsTypes.equipmentAccess" [currentStep]="currentStep" [form]="orientationForm" [filters]="filters" diff --git a/src/app/form/orientation-form-view/equipment-access/equipment-access.component.ts b/src/app/form/orientation-form-view/equipment-access/equipment-access.component.ts index f538bbdad1e2daf96065fe102381a4557e704c4d..28ab8646ed6a7e8e762968024d52dbf501b7b579 100644 --- a/src/app/form/orientation-form-view/equipment-access/equipment-access.component.ts +++ b/src/app/form/orientation-form-view/equipment-access/equipment-access.component.ts @@ -3,7 +3,7 @@ import { FormGroup } from '@angular/forms'; import { User } from '../../../models/user.model'; import { Filter } from '../../../structure-list/models/filter.model'; import { OrientationUtils } from '../../../utils/orientationUtils'; -import { CommonSteps, GenericOrientationSteps, StructuresListSteps } from '../enums/orientation.enums'; +import { CommonSteps, GenericOrientationSteps, NeedsTypes, StructuresListSteps } from '../enums/orientation.enums'; import { FiltersForm } from '../interfaces/filtersForm.interface'; import { StructureOrientationForm } from '../interfaces/structureOrientationForm.interface'; import { AllOrientationSteps } from '../types/orientation.types'; @@ -26,6 +26,7 @@ export class EquipmentAccessComponent { // Enums public GenericOrientationSteps = GenericOrientationSteps; + public NeedsTypes = NeedsTypes; public checkValidation(): void { switch (this.genericStep) { diff --git a/src/app/form/orientation-form-view/equipment-buy/equipment-buy.component.html b/src/app/form/orientation-form-view/equipment-buy/equipment-buy.component.html index e5e8a9aaaf812f0688333305bc591cd17d261685..2a55b64493ba1b69008ff59698d89641e4a3af3d 100644 --- a/src/app/form/orientation-form-view/equipment-buy/equipment-buy.component.html +++ b/src/app/form/orientation-form-view/equipment-buy/equipment-buy.component.html @@ -5,8 +5,9 @@ /> <app-orientation-structure-list *ngIf="genericStep === GenericOrientationSteps.accompanimentTunnel" - [form]="orientationForm" + [needType]="NeedsTypes.equipmentBuy" [currentStep]="currentStep" + [form]="orientationForm" [filters]="filters" [profile]="profile" (validatePage)="checkValidation()" diff --git a/src/app/form/orientation-form-view/equipment-buy/equipment-buy.component.ts b/src/app/form/orientation-form-view/equipment-buy/equipment-buy.component.ts index 2e1a7c8ec224284bc750d075543cd4d1e8300fef..ad8230a85742ce7c9fe68ef4a9e2a6f1523d5e79 100644 --- a/src/app/form/orientation-form-view/equipment-buy/equipment-buy.component.ts +++ b/src/app/form/orientation-form-view/equipment-buy/equipment-buy.component.ts @@ -3,7 +3,7 @@ import { FormGroup } from '@angular/forms'; import { User } from '../../../models/user.model'; import { Filter } from '../../../structure-list/models/filter.model'; import { OrientationUtils } from '../../../utils/orientationUtils'; -import { CommonSteps, GenericOrientationSteps, StructuresListSteps } from '../enums/orientation.enums'; +import { CommonSteps, GenericOrientationSteps, NeedsTypes, StructuresListSteps } from '../enums/orientation.enums'; import { FiltersForm } from '../interfaces/filtersForm.interface'; import { StructureOrientationForm } from '../interfaces/structureOrientationForm.interface'; import { AllOrientationSteps } from '../types/orientation.types'; @@ -26,6 +26,7 @@ export class EquipmentBuyComponent { // Enums public GenericOrientationSteps = GenericOrientationSteps; + public NeedsTypes = NeedsTypes; public checkValidation(): void { switch (this.genericStep) { diff --git a/src/app/form/orientation-form-view/online-demarch/appointment/make-appointment/make-appointment.component.ts b/src/app/form/orientation-form-view/online-demarch/appointment/make-appointment/make-appointment.component.ts index 0eeb9ea3fd8b057305befa09860ecccc5217b9a7..819e8a14d5699c612c7c7ba6fd61e2ed2c1b6db3 100644 --- a/src/app/form/orientation-form-view/online-demarch/appointment/make-appointment/make-appointment.component.ts +++ b/src/app/form/orientation-form-view/online-demarch/appointment/make-appointment/make-appointment.component.ts @@ -105,7 +105,7 @@ export class MakeAppointmentComponent implements OnInit { const filteredStructures = []; // for each structure this.structures.forEach((structure) => { - // check each of its personnalOffers + // check each of its personalOffers structure.personalOffers?.forEach((po) => { // if the needs the user selected are all part of the personalOffer, keep the structure for display if ( diff --git a/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.html b/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.html index 06caabc759410b67278da984cc702165682f7194..3e66262ff97543e82115a9453cfc681bb267af24 100644 --- a/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.html +++ b/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.html @@ -22,8 +22,9 @@ <!-- STRUCTURE LIST FORM --> <app-orientation-structure-list *ngIf="accompanimentType === AccompanimentTypes.structuresList" - [form]="form" + [needType]="needType" [currentStep]="currentStep" + [form]="form" [filters]="filters" [profile]="profile" (validatePage)="checkValidation()" @@ -40,7 +41,7 @@ *ngIf="currentStep === OnlineDemarchesAppointmentSteps.pmrAccess" [structureForm]="form" (validateForm)="checkValidation()" - (radioChange)="onRadioChange($event)" + (radioChange)="applyPMRFilter($event)" /> <app-orientation-structure-address *ngIf="currentStep === OnlineDemarchesAppointmentSteps.location" diff --git a/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.ts b/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.ts index f0d87444d436bacb5f182683c59c674eace2bb0a..e068521da56fa19a5a3000b87539ba07d38458aa 100644 --- a/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.ts +++ b/src/app/form/orientation-form-view/online-demarch/onlineDemarch-form.component.ts @@ -155,10 +155,10 @@ export class OnlineDemarchFormComponent implements OnInit { } return false; } - public onRadioChange(event: { name: string; value: boolean }): void { + public applyPMRFilter(event: { name: string; value: boolean }): void { const { name, value } = event; this.form.get(name).setValue(value); - this.orientationUtils.manuallySetOfPmr(this.filters, event); + this.orientationUtils.manuallySetOffPmr(this.filters, event); this.checkValidation(); } public setFailedOrientation(): void { diff --git a/src/app/form/orientation-form-view/orientation-form-view.component.ts b/src/app/form/orientation-form-view/orientation-form-view.component.ts index e9fd1e6c12ebaa3db0285b23fec5d14cc451636b..685d6243561e96c74f6347e9ad66fae7f4444787 100644 --- a/src/app/form/orientation-form-view/orientation-form-view.component.ts +++ b/src/app/form/orientation-form-view/orientation-form-view.component.ts @@ -398,7 +398,9 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked if (this.tunnelingStepIs(AccompanimentTypes.appointment, AppointmentSteps.location)) { const eligibleStructures = ( await lastValueFrom(this.structureService.getStructures(this.filters, 'search', true)) - ).filter((structure) => structure.hasUserWithAppointmentDN); + ) + .filter((structure) => structure.hasUserWithAppointmentDN) + .filter((structure) => structure.allowOrientation); if (eligibleStructures.length === 0) { this.sendOrientationIndicator(this.structureOrientationForm ?? this.onlineDemarcheForm); this.failedOrientation = true; @@ -473,23 +475,17 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked return Math.round((this.currentStep / this.nbSteps) * 100); } private async sendOrientationIndicator(orientationForm: FormGroup): Promise<void> { - let isConnected = false; - let profile: User = null; - if (this.authService.isLoggedIn()) { - isConnected = true; - profile = await this.profilService.getProfile(); - } - + this.profile = await this.profilService.getProfile(); const orientationCompleted: boolean = this.isLastStep; const orientationIndicator: IOrientationIndicator = { origin: { id: undefined, - prescripteur: this.utils.nullifyEmpty(profile?.job?.name), + prescripteur: this.utils.nullifyEmpty(this.profile?.job?.name), adresse: this.utils.nullifyEmpty(orientationForm?.get('address')?.value), }, target: this.utils.nullifyEmpty(this.targetStructures(orientationForm.get('structureChoice'))), type: this.orientationType(this.filters), - connected: isConnected, + connected: true, completed: orientationCompleted, progress: this.getProgress(), }; diff --git a/src/app/form/orientation-form-view/orientation-structure-list/orientation-structure-list.component.html b/src/app/form/orientation-form-view/orientation-structure-list/orientation-structure-list.component.html index 175cb0c0e120f700feea6ce719113a20b0a6de89..98f02e291364fdd54b0c7fd8bcf698746d9c8b31 100644 --- a/src/app/form/orientation-form-view/orientation-structure-list/orientation-structure-list.component.html +++ b/src/app/form/orientation-form-view/orientation-structure-list/orientation-structure-list.component.html @@ -14,6 +14,7 @@ [isOrientationForm]="true" [structuresSelected]="selectedStructures" [filters]="filters" + [needType]="needType" [userLongitude]="form.get('address').value?.coordinates[0]" [userLatitude]="form.get('address').value?.coordinates[1]" (structureSelection)="checkValidation($event)" diff --git a/src/app/form/orientation-form-view/orientation-structure-list/orientation-structure-list.component.ts b/src/app/form/orientation-form-view/orientation-structure-list/orientation-structure-list.component.ts index be95e999d79a990b6448609ab75c81c0e4cf6d4d..ca657fca5504b90098646e89c63fa97cce66da5d 100644 --- a/src/app/form/orientation-form-view/orientation-structure-list/orientation-structure-list.component.ts +++ b/src/app/form/orientation-form-view/orientation-structure-list/orientation-structure-list.component.ts @@ -4,7 +4,7 @@ import { Structure } from '../../../models/structure.model'; import { User } from '../../../models/user.model'; import { Filter } from '../../../structure-list/models/filter.model'; import { OrientationUtils } from '../../../utils/orientationUtils'; -import { AccompanimentTypes, StructuresListSteps } from '../enums/orientation.enums'; +import { AccompanimentTypes, NeedsTypes, StructuresListSteps } from '../enums/orientation.enums'; import { AllOrientationSteps } from '../types/orientation.types'; @Component({ @@ -12,6 +12,7 @@ import { AllOrientationSteps } from '../types/orientation.types'; templateUrl: './orientation-structure-list.component.html', }) export class OrientationStructureListComponent implements OnChanges { + @Input() needType: NeedsTypes; @Input() currentStep: AllOrientationSteps; @Input() profile: User; @Input() form: UntypedFormGroup; @@ -34,7 +35,7 @@ export class OrientationStructureListComponent implements OnChanges { public radioChange(event: { name: string; value: boolean }): void { const { name, value } = event; this.form.get(name).setValue(value); - this.orientationUtils.manuallySetOfPmr(this.filters, event); + this.orientationUtils.manuallySetOffPmr(this.filters, event); this.checkValidation(); } diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html index e7fe355dc55b82a5c867a60b446f0b6ea63ed479..a82a1d628e428ba5fe1c8448a80e84d65cf26ce1 100644 --- a/src/app/header/header.component.html +++ b/src/app/header/header.component.html @@ -90,6 +90,16 @@ > Données </a> + <a + routerLink="/page/ressourcerie" + role="menuitem" + title="Ressourcerie" + [routerLinkActive]="'active'" + i18n + [attr.aria-current]="isActive('/page/ressourcerie')" + > + Ressourcerie + </a> <a *ngIf="isAdmin" routerLink="/admin" @@ -183,6 +193,17 @@ > Données </a> + <a + routerLink="/page/ressourcerie" + role="menuitem" + title="Ressourcerie" + [routerLinkActive]="'active'" + i18n + [attr.aria-current]="isActive('/page/ressourcerie')" + (click)="closeMenu()" + > + Ressourcerie + </a> <a routerLink="/page/qui-sommes-nous" role="menuitem" diff --git a/src/app/models/structure.model.ts b/src/app/models/structure.model.ts index ff79e00fdd4ad009a81d7a5f99bd539ca2a9f34b..b33cb513bf5b314912ed2ada9697d96e6c893774 100644 --- a/src/app/models/structure.model.ts +++ b/src/app/models/structure.model.ts @@ -1,6 +1,5 @@ import { StructureCategoryEnum } from '../shared/enum/structureCategory.enum'; import { StructureCategoryIconEnum } from '../shared/enum/structureCategoryIcon.enum'; -import { Weekday } from '../structure-list/enum/weekday.enum'; import { Module } from '../structure-list/models/module.model'; import { FreeWorkShopIDs, FreeWorkShopLabels } from '../structure/enums/freeWorkshop.enum'; import { Utils } from '../utils/utils'; @@ -8,7 +7,7 @@ import { Address } from './address.model'; import { OpeningDay } from './openingDay.model'; import { PersonalOffer } from './personalOffer.model'; import { StructureType } from './structureType.model'; -import { Day, Week } from './week.model'; +import { Week } from './week.model'; export class Structure { public _id: string = null; @@ -30,6 +29,7 @@ export class Structure { public instagram: string = null; public linkedin: string = null; public pmrAccess: boolean = null; + public allowOrientation: boolean = null; public placeOfReception: boolean = null; public choiceCompletion: boolean = null; public contactPersonFirstName: string = null; @@ -86,27 +86,6 @@ export class Structure { }); } - public getDayhours(day: Weekday): Day { - switch (day) { - case Weekday.monday: - return this.hours.monday; - case Weekday.tuesday: - return this.hours.tuesday; - case Weekday.thursday: - return this.hours.thursday; - case Weekday.wednesday: - return this.hours.wednesday; - case Weekday.friday: - return this.hours.friday; - case Weekday.saturday: - return this.hours.saturday; - case Weekday.sunday: - return this.hours.sunday; - default: - return null; - } - } - /** * Check if a structure has equipments */ @@ -216,7 +195,7 @@ export class Structure { * Check if a structure proposes learning skills for free under condition and if it has these conditions specified */ public hasFreenessCondition(): boolean { - const isUnderCondition = this.categoriesDisplay.freeWorkShop[0].name === FreeWorkShopLabels.underCondition; + const isUnderCondition = this.categoriesDisplay.freeWorkShop[0]?.name === FreeWorkShopLabels.underCondition; const freenessCondition = this.getFreenessCondition(); const freenessConditionExists = !(this.utils.isNullOrEmpty(freenessCondition) || freenessCondition.length === 0); return isUnderCondition && freenessConditionExists; diff --git a/src/app/page/page.component.ts b/src/app/page/page.component.ts index a804752487d05bb3c315589b5f497c0e19c23ea9..4d9a3c9be066d9d16903e936b2f41c8e990417dc 100644 --- a/src/app/page/page.component.ts +++ b/src/app/page/page.component.ts @@ -8,6 +8,7 @@ import { PageService } from './services/page.service'; enum PageEnum { quiSommesNous = 'qui-sommes-nous', accessibilite = 'accessibilite', + ressourcerie = 'ressourcerie', } @Component({ diff --git a/src/app/profile/structure-edition-summary/structure-edition-summary.component.html b/src/app/profile/structure-edition-summary/structure-edition-summary.component.html index d6aa720e3c53bbb57b6eced685968d9920154855..abf583ccf5995dae00ffea1de979e5f858a46574 100644 --- a/src/app/profile/structure-edition-summary/structure-edition-summary.component.html +++ b/src/app/profile/structure-edition-summary/structure-edition-summary.component.html @@ -294,9 +294,9 @@ <app-tag-item *ngIf="offerHolder.user && offerHolder.user.withAppointment" label="Rendez-vous" + iconName="calendar" [size]="'small'" [color]="'blue'" - iconName="calendar" /> </div> </div> @@ -314,7 +314,7 @@ [iconName]="containsDigitalHelp(offerHolder.offers) ? 'edit' : 'plus'" [size]="'small'" (action)="goToEdit(structureFormStep.structureDigitalHelpingAccompaniment, offerHolder)" - ></app-button> + /> <app-icon-button class="hide-on-desktop" [variant]="'secondary'" @@ -325,7 +325,7 @@ : 'Ajouter des aides aux démarches en ligne' " (action)="goToEdit(structureFormStep.structureDigitalHelpingAccompaniment, offerHolder)" - ></app-icon-button> + /> </ng-container> </div> <app-no-information *ngIf="!containsDigitalHelp(offerHolder.offers)" /> @@ -346,7 +346,7 @@ [iconName]="structure.otherDescription ? 'edit' : 'plus'" [size]="'small'" (action)="goToEdit(structureFormStep.structureDigitalHelpingAccompanimentOther, offerHolder)" - ></app-button> + /> <app-icon-button class="hide-on-desktop" [variant]="'secondary'" @@ -357,7 +357,7 @@ : 'Ajouter les autres démarches en ligne' " (action)="goToEdit(structureFormStep.structureDigitalHelpingAccompanimentOther, offerHolder)" - ></app-icon-button> + /> </div> <app-no-information *ngIf="!structure.otherDescription" /> <p *ngIf="structure.otherDescription">{{ structure.otherDescription }}</p> @@ -373,7 +373,7 @@ [iconName]="containsDigitalLearning(offerHolder.offers) ? 'edit' : 'plus'" [size]="'small'" (action)="goToEdit(structureFormStep.structureTrainingType, offerHolder)" - ></app-button> + /> <app-icon-button class="hide-on-desktop" [variant]="'secondary'" @@ -384,7 +384,7 @@ : 'Ajouter les accompagnements aux usages numériques' " (action)="goToEdit(structureFormStep.structureTrainingType, offerHolder)" - ></app-icon-button> + /> </div> <app-no-information *ngIf="!containsDigitalLearning(offerHolder.offers)" /> @@ -449,6 +449,52 @@ </div> </section> + <section class="allowOrientation"> + <div class="sectionHeader"> + <h3 class="uppercase">Orientation de bénéficiaires</h3> + <app-button + class="hide-on-mobile" + [variant]="'secondary'" + [label]="'Modifier'" + [iconName]="'edit'" + [size]="'small'" + (action)="goToEdit(structureFormStep.structureAllowOrientation)" + /> + <app-icon-button + ariaLabel="Modifier les autorisations de visibilité dans l'orientation" + class="hide-on-desktop" + [variant]="'secondary'" + [iconName]="'edit'" + (action)="goToEdit(structureFormStep.structureAllowOrientation)" + /> + </div> + {{ structure.allowOrientation ? 'Oui' : 'Non' }} + </section> + + <section class="wifi"> + <div class="sectionHeader"> + <h3 class="uppercase">Wifi</h3> + <app-button + class="hide-on-mobile" + [variant]="'secondary'" + [label]="'Modifier'" + [iconName]="'edit'" + [size]="'small'" + (action)="goToEdit(structureFormStep.structureWifi)" + /> + <app-icon-button + ariaLabel="Modifier l'accès au wifi" + class="hide-on-desktop" + [variant]="'secondary'" + [iconName]="'edit'" + (action)="goToEdit(structureFormStep.structureWifi)" + /> + </div> + <p> + {{ hasWifi(structure.categories.selfServiceMaterial) ? 'Oui' : 'Non' }} + </p> + </section> + <section class="equipements"> <div class="sectionHeader"> <h3>Matériel en accès libre</h3> diff --git a/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts b/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts index 2bc4dd48145303e60ba14b5302c5bc8b6c56bb99..1a7468287e3c1483578028c3e0cb1eda7aff93e9 100644 --- a/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts +++ b/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts @@ -82,7 +82,7 @@ export class StructureEditionSummaryComponent implements OnInit { const updatedAt = DateTime.fromISO(this.structure.updatedAt); const sixMonthsAgo = DateTime.local().minus({ month: 6 }); if (updatedAt < sixMonthsAgo) this.isUpdateStructure = true; - this.freeWorkShop = this.structure.categoriesDisplay.freeWorkShop[0].displayText; + this.freeWorkShop = this.structure.categoriesDisplay.freeWorkShop[0]?.displayText; this.freenessCondition = this.structure.categories.freenessCondition as unknown as string; this.categories = await this.searchService.getCategories().toPromise(); diff --git a/src/app/structure-list/services/search.service.ts b/src/app/structure-list/services/search.service.ts index c0a3fd49454795b1d61661ebb181b260756502c4..bc002a522a3e550b9657c1fb652d9bb33b38440b 100644 --- a/src/app/structure-list/services/search.service.ts +++ b/src/app/structure-list/services/search.service.ts @@ -11,7 +11,6 @@ import { Module } from '../models/module.model'; }) export class SearchService { public annuaireSearchQuery: SearchQuery; - public checkedFilterList: string[] = []; public previousResult$ = new BehaviorSubject<SearchResults>({ count: 0, docs: [] }); constructor(private http: HttpClient) {} @@ -23,21 +22,25 @@ export class SearchService { return this.http.get('/api/categories').pipe(map((data: any[]) => data.map((item) => new Category(item)))); } public getJobsGroups(): Observable<any> { - return this.http.get('/api/jobs-groups').pipe(map((data: any[]) => data.map((item) => item.name))); + return this.http.get('/api/jobs-groups'); } - public getEmployers(): Observable<string[]> { - return this.http.get('/api/employer').pipe(map((data: any[]) => data.map((item) => item.name))); + public getEmployers(): Observable<any> { + return this.http.get('/api/employer'); } public async searchUserRegistry( searchTerm: string, page: number, jobsGroup?: string[], employers?: string[], + territories?: string[], + communes?: string[], ): Promise<SearchResults> { const users = await lastValueFrom( this.http.post<SearchResults>(`/api/userRegistry/?search=${searchTerm}`, { jobsGroup, employer: employers, + territory: territories, + commune: communes, page, }), ); @@ -49,4 +52,7 @@ export class SearchService { public getIndex(array: Module[], id: string, categ: string): number { return array.findIndex((m: Module) => m.id === id && m.name === categ); } + public getCommunesWithUsers(): Observable<any> { + return this.http.get<any>('/api/userRegistry/communesWithUsers'); + } } diff --git a/src/app/utils/formUtils.ts b/src/app/utils/formUtils.ts index 387d0b801bfbfd927ccc29a16f2148889599ae17..612b39bfddfff0f18f7963d73c09456080f11fac 100644 --- a/src/app/utils/formUtils.ts +++ b/src/app/utils/formUtils.ts @@ -93,6 +93,7 @@ export class FormUtils { linkedin: new UntypedFormControl(structure.linkedin, Validators.pattern(CustomRegExp.LINKEDIN)), hours: new UntypedFormGroup({}), pmrAccess: new UntypedFormControl(structure.pmrAccess, Validators.required), + allowOrientation: new UntypedFormControl(structure.allowOrientation, Validators.required), placeOfReception: new UntypedFormControl(structure.placeOfReception, !isEditMode && Validators.required), choiceCompletion: new UntypedFormControl(structure.choiceCompletion, !isEditMode && Validators.required), exceptionalClosures: new UntypedFormControl(structure.exceptionalClosures), diff --git a/src/app/utils/orientationUtils.ts b/src/app/utils/orientationUtils.ts index f7180922fb7437d84071f22c80aa5bb9a5297bc6..2c04e342742e6b15ac5d278f725f1f806974acf4 100644 --- a/src/app/utils/orientationUtils.ts +++ b/src/app/utils/orientationUtils.ts @@ -234,7 +234,7 @@ export class OrientationUtils { updatePageValid(pagesValidation[step].valid); } - public manuallySetOfPmr(filters: Filter[], event: { name: string; value: boolean }): void { + public manuallySetOffPmr(filters: Filter[], event: { name: string; value: boolean }): void { // Handle special PMR access case if (event.name === 'pmrAccess') { const filterIndex = filters.findIndex((f) => f.name === 'pmrAccess');