import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { ParticipantStatus } from '@dafa-enums/participant-status.enum'; import { SortOrder } from '@dafa-enums/sort-order.enum'; import { environment } from '@dafa-environment'; import { mapParticipantApiResponseToParticipant, Participant, ParticipantApiResponse, ParticipantsApiResponse, } from '@dafa-models/participant.model'; import { Sort } from '@dafa-models/sort.model'; import { sort } from '@dafa-utils/sort.util'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; function filterParticipants(participants: Participant[], searchFilter: string): Participant[] { return participants.filter(participant => { const searchValueExistsInName = participant.fullName.toLowerCase().includes(searchFilter.toLowerCase()); const searchValueExistsInErrandNumber = participant.errandNumber.toString().includes(searchFilter); return searchValueExistsInName || searchValueExistsInErrandNumber; }); } const API_HEADERS = { headers: environment.api.headers }; @Injectable({ providedIn: 'root', }) export class ParticipantsService { private _apiUrl = `${environment.api.url}/participants`; private _allParticipants$: Observable = this.httpClient .get(this._apiUrl) .pipe(map(response => response.data.map(participant => mapParticipantApiResponseToParticipant(participant)))); private _activeParticipantsSortBy$ = new BehaviorSubject | null>({ key: 'handleBefore', order: SortOrder.ASC, }); public activeParticipantsSortBy$: Observable< Sort > = this._activeParticipantsSortBy$.asObservable(); private _followUpParticipantsSortBy$ = new BehaviorSubject | null>({ key: 'handleBefore', order: SortOrder.ASC, }); public followUpParticipantsSortBy$: Observable< Sort > = this._followUpParticipantsSortBy$.asObservable(); private _searchFilter$ = new BehaviorSubject(''); public searchFilter$: Observable = this._searchFilter$.asObservable(); public filteredParticipants$: Observable = combineLatest([ this._allParticipants$, this._searchFilter$, ]).pipe(map(([participants, searchFilter]) => filterParticipants(participants, searchFilter))); public activeParticipants$: Observable = combineLatest([ this.filteredParticipants$, this._activeParticipantsSortBy$, ]).pipe( map(([participants, sortBy]) => { const activeParticipants = participants.filter(participant => participant.status === ParticipantStatus.ACTIVE); return sortBy ? sort(activeParticipants, sortBy) : activeParticipants; }) ); public followUpParticipants$: Observable = combineLatest([ this.filteredParticipants$, this._followUpParticipantsSortBy$, ]).pipe( map(([participants, sortBy]) => { const followUpParticipants = participants.filter( participant => participant.status === ParticipantStatus.FOLLOW_UP ); return sortBy ? sort(followUpParticipants, sortBy) : followUpParticipants; }) ); public fetchDetailedParticipantData$(id: string): Observable { return this.httpClient .get(`${this._apiUrl}/${id}`, { ...API_HEADERS }) .pipe(map(result => mapParticipantApiResponseToParticipant(result.data))); } public setSearchFilter(value: string) { this._searchFilter$.next(value); } public setActiveParticipantsSortKey(key: keyof Participant) { const currentSortBy = this._activeParticipantsSortBy$.getValue(); let order = currentSortBy.order; if (currentSortBy?.key === key) { order = order === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; } this._activeParticipantsSortBy$.next({ key, order }); } public setFollowUpParticipantsSortKey(key: keyof Participant) { const currentSortBy = this._followUpParticipantsSortBy$.getValue(); let order = currentSortBy.order; if (currentSortBy?.key === key) { order = order === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; } this._followUpParticipantsSortBy$.next({ key, order }); } constructor(private httpClient: HttpClient) {} }