diff --git a/src/app/annuaire/annuaire-header/annuaire-header.component.html b/src/app/annuaire/annuaire-header/annuaire-header.component.html index 338a3ba202feb8f08724f80afff8e145f06694c9..dda02e28cc70e77c8904a9bd2abc3e9a31cc35f9 100644 --- a/src/app/annuaire/annuaire-header/annuaire-header.component.html +++ b/src/app/annuaire/annuaire-header/annuaire-header.component.html @@ -1,6 +1,6 @@ <div class="searchContainer"> <div class="searchBarAndFilters"> - <app-search-bar [(value)]="searchInput" (searchSubmitted)="applyFilter()" /> + <app-search-bar [(value)]="searchInput" (searchSubmitted)="onSearchSubmitted($event)" /> <div class="filters isntPhoneContent" (appClickOutside)="closeModal()"> <app-collapsable-filter [label]="'Fonction'" diff --git a/src/app/annuaire/annuaire-header/annuaire-header.component.ts b/src/app/annuaire/annuaire-header/annuaire-header.component.ts index 1c60be68d4ce40f7de590bd98b5d507f453f6c36..2d18ac5300f2e04a12eec21a00f9900ef5f5ef1f 100644 --- a/src/app/annuaire/annuaire-header/annuaire-header.component.ts +++ b/src/app/annuaire/annuaire-header/annuaire-header.component.ts @@ -12,10 +12,8 @@ import { SearchQuery } from '../models/searchQuery.model'; }) export class AnnuaireHeaderComponent implements OnInit, OnChanges { @Input() shouldResetFilters = 0; - @Input() shouldShowNextPage = 0; @Output() searchEvent = new EventEmitter<SearchQuery>(); - public addStructureFormModal = false; public modalTypeOpened: TypeModal; public employersFiltersActive = false; public jobsFiltersActive = false; @@ -29,51 +27,80 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { constructor( private activatedRoute: ActivatedRoute, - private route: ActivatedRoute, private router: Router, public searchService: SearchService, ) {} async ngOnInit(): Promise<void> { + this.loadQueryParams(); // Will store the different categories await this.loadFilters(); - const queryString = this.activatedRoute.snapshot.queryParamMap.get('search'); - // Use existing query if back to the page or init the query - if (!this.searchService.annuaireSearchQuery) { - this.searchService.annuaireSearchQuery = { search: '', page: 1, jobFilters: [], employerFilters: [] }; - } - if (queryString) { - this.searchService.annuaireSearchQuery.search = queryString; + + if (this.searchService.previousResult$.getValue().docs.length === 0) { + this.applyFilter(); } - this.splitFilters(this.searchService.checkedFilterList); + } - this.searchInput = this.searchService.annuaireSearchQuery.search || ''; + ngOnChanges(changes: SimpleChanges): void { + if (changes.shouldResetFilters?.currentValue !== 0) { + this.resetFilters(); + } + } - // Prevent re-fetching if previous data - if (this.searchService.previousResult$.getValue().docs.length !== 0) return; - this.searchEvent.emit({ + private loadQueryParams(): void { + const queryParams = this.activatedRoute.snapshot.queryParams; + this.searchInput = queryParams['search'] ?? ''; + this.jobFilterChecked = queryParams['jobs']?.split('|') ?? []; + this.employerFilterChecked = queryParams['employers']?.split('|') ?? []; + this.searchService.checkedFilterList = [...this.jobFilterChecked, ...this.employerFilterChecked]; + this.searchService.annuaireSearchQuery = { search: this.searchInput, + page: Number(queryParams['page']) || 1, jobFilters: this.jobFilterChecked, employerFilters: this.employerFilterChecked, - }); + }; } - ngOnChanges(changes: SimpleChanges): void { - if (changes.shouldResetFilters && changes.shouldResetFilters.currentValue !== 0) { - this.resetFilters(); + public onSearchSubmitted(value: string): void { + this.searchInput = value; + this.applyFilter(); + } + + private updateQueryParams(): void { + const queryParams: Record<string, string> = {}; + + if (this.searchInput.trim()) { + queryParams.search = this.searchInput.trim(); } - if ( - changes.shouldShowNextPage && - !changes.shouldShowNextPage.firstChange && - changes.shouldShowNextPage.currentValue > 1 - ) { - this.searchEvent.emit({ - search: this.searchInput, - page: changes.shouldShowNextPage.currentValue, - jobFilters: this.jobFilterChecked, - employerFilters: this.employerFilterChecked, - }); + + if (this.jobFilterChecked.length) { + queryParams.jobs = this.jobFilterChecked.join('|'); + } + + if (this.employerFilterChecked.length) { + queryParams.employers = this.employerFilterChecked.join('|'); } + + // Delay to avoid error in console: "NG0100: ExpressionChangedAfterItHasBeenCheckedError" + setTimeout( + () => + this.router.navigate([], { + relativeTo: this.activatedRoute, + queryParams: queryParams, + }), + 1, + ); + } + + public applyFilter(page = 1): void { + this.searchEvent.emit({ + search: this.searchInput.trim(), + page: page, + jobFilters: this.jobFilterChecked, + employerFilters: this.employerFilterChecked, + }); + + this.updateQueryParams(); } /** Get the categories for each modal type */ @@ -89,30 +116,6 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { this.countCheckedFilters(); } - /** Sends an array containing all filters */ - public applyFilter(): void { - this.shouldResetFilters = 0; - // Add search input filter - if (this.searchInput) { - this.router.navigate(['/annuaire'], { - relativeTo: this.route, - queryParams: { search: this.searchInput }, - queryParamsHandling: 'merge', - }); - } else { - this.router.navigate(['/annuaire'], { - relativeTo: this.route, - }); - } - this.splitFilters(this.searchService.checkedFilterList); - this.searchEvent.emit({ - search: this.searchInput, - page: 1, - jobFilters: this.jobFilterChecked, - employerFilters: this.employerFilterChecked, - }); - } - private splitFilters(checkedFilterList: string[]): void { this.employerFilterChecked = checkedFilterList.filter((filter) => this.employerTypes.includes(filter)); this.jobFilterChecked = checkedFilterList.filter((filter) => this.jobTypes.includes(filter)); @@ -120,6 +123,7 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { public fetchResults(checkedFilters: string[]): void { this.searchService.checkedFilterList = checkedFilters; + this.splitFilters(checkedFilters); this.closeModal(); this.applyFilter(); } @@ -137,12 +141,7 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { /** Open the modal and display the list according to the right filter button */ public openModal(modalType: TypeModal): void { - // if modal already opened, reset type - if (this.modalTypeOpened === modalType) { - this.closeModal(); - } else if (this.modalTypeOpened !== modalType) { - this.modalTypeOpened = modalType; - } + this.modalTypeOpened = this.modalTypeOpened === modalType ? undefined : modalType; } public closeModal(): void { @@ -165,21 +164,26 @@ export class AnnuaireHeaderComponent implements OnInit, OnChanges { this.jobsFiltersActive = false; this.employerFilterChecked = []; this.jobFilterChecked = []; - this.searchEvent.emit({ search: '', page: 1, jobFilters: [], employerFilters: [] }); + // Delay to avoid error in console: "NG0100: ExpressionChangedAfterItHasBeenCheckedError" - setTimeout(() => this.router.navigate(['/annuaire']), 1); + setTimeout( + () => + this.router.navigate([], { + relativeTo: this.activatedRoute, + queryParams: {}, + }), + 1, + ); } public removeFilter(filter: string): void { const index = this.searchService.checkedFilterList.findIndex((checkedFilter: string) => checkedFilter === filter); - this.searchService.checkedFilterList.splice(index, 1); - this.splitFilters(this.searchService.checkedFilterList); - this.countCheckedFilters(); - this.searchEvent.emit({ - search: this.searchInput, - page: 1, - jobFilters: this.jobFilterChecked, - employerFilters: this.employerFilterChecked, - }); + if (index !== -1) { + this.searchService.checkedFilterList.splice(index, 1); + this.splitFilters(this.searchService.checkedFilterList); + this.countCheckedFilters(); + this.updateQueryParams(); + this.applyFilter(); + } } } diff --git a/src/app/annuaire/annuaire.component.html b/src/app/annuaire/annuaire.component.html index 99b9180941e7d5fe5308ac32723f172c7744093a..7bd222a5fca31e6def4e2298049e1603ed8d6ea4 100644 --- a/src/app/annuaire/annuaire.component.html +++ b/src/app/annuaire/annuaire.component.html @@ -4,7 +4,6 @@ <app-annuaire-header class="hide-on-print" [shouldResetFilters]="resetFilters" - [shouldShowNextPage]="searchService.annuaireSearchQuery?.page" (searchEvent)="searchUsers($event)" /> <app-result-list diff --git a/src/app/annuaire/annuaire.component.ts b/src/app/annuaire/annuaire.component.ts index 799bfee957c8560d052ca34ce78617f3522bd656..bf9108a699929afa6e10c63b37ac92ccf7dd40a4 100644 --- a/src/app/annuaire/annuaire.component.ts +++ b/src/app/annuaire/annuaire.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { UserAnnuary } from '../models/user.model'; import { AuthService } from '../services/auth.service'; import { SearchService } from '../structure-list/services/search.service'; @@ -13,7 +14,9 @@ export class AnnuaireComponent implements OnInit { constructor( public searchService: SearchService, private authService: AuthService, + private route: ActivatedRoute, ) {} + public userList: UserAnnuary[] = []; public totalUserResult: number; public resetFilters = 0; @@ -21,6 +24,16 @@ 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; @@ -68,7 +81,11 @@ export class AnnuaireComponent implements OnInit { public shouldResetFilters(): void { this.resetFilters++; } + public showMore(): void { - this.searchService.annuaireSearchQuery.page++; + if (this.searchService.annuaireSearchQuery) { + this.searchService.annuaireSearchQuery.page++; + this.searchUsers(this.searchService.annuaireSearchQuery); + } } } diff --git a/src/app/annuaire/result-list/result-list.component.ts b/src/app/annuaire/result-list/result-list.component.ts index fd7d3f431d93adacaea82105eeb93b48899bc4a4..6ce3348b9ee2a8a8d4229cdb6500c373bc0d2bc0 100644 --- a/src/app/annuaire/result-list/result-list.component.ts +++ b/src/app/annuaire/result-list/result-list.component.ts @@ -53,12 +53,15 @@ export class ResultListComponent implements OnChanges, AfterViewInit { }, 0); } } + public goLogin(): void { this.router.navigate(['/connexion'], { queryParams: { returnUrl: '/annuaire' } }); } + public goRegister(): void { this.router.navigateByUrl('/formulaire/compte'); } + public resetFilters(): void { this.resetEvent.emit(); }