import { CommonModule } from '@angular/common'; import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, } from '@angular/core'; import { NgbModule, NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { AngularSvgIconModule } from 'angular-svg-icon'; import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, } from '@angular/forms'; import { Subject, takeUntil } from 'rxjs'; // models import { SortColumn } from '../ca-sort-dropdown/models'; // enums import { eSharedString, eStringPlaceholder } from '../../enums'; import { eFleetFilterItemType } from './enums'; // interfaces import { IFleetFilterData, IFleetFilterItemEmit, IFleetFilterTrailer, IFleetFilterTruck, } from './interfaces'; import { ICaInput } from '../ca-input/config'; // components import { CaAppTooltipV2Component } from '../ca-app-tooltip-v2/ca-app-tooltip-v2.component'; import { CaInputComponent } from '../ca-input/ca-input.component'; import { CaCustomCardComponent } from '../ca-custom-card/ca-custom-card.component'; import { CaSortDropdownComponent } from '../ca-sort-dropdown/ca-sort-dropdown.component'; // constants import { FleetFilterConstants } from './utils/constants'; // svg routes import { FleetFilterSvgRoutes } from './utils/svg-routes'; // pipes import { RemoveSvgExtensionPipe } from './utils/pipes'; // helpers import { FleetFilterHelper } from './utils/helpers'; @Component({ selector: 'app-ca-fleet-filter', templateUrl: './ca-fleet-filter.component.html', styleUrl: './ca-fleet-filter.component.scss', imports: [ // modules CommonModule, AngularSvgIconModule, NgbModule, ReactiveFormsModule, // components CaAppTooltipV2Component, CaInputComponent, CaCustomCardComponent, CaSortDropdownComponent, // pipes RemoveSvgExtensionPipe, ], }) export class CaFleetFilterComponent implements OnInit, OnDestroy { @Input() set fleetFilterData(value: IFleetFilterData) { this.trucks = value.trucks; this.trailers = value.trailers; this.filteredTrucks = value.trucks; this.filteredTrailers = value.trailers; this.truckCount = value.truckCount; this.trailerCount = value.trailerCount; } @Output() onItemClick: EventEmitter = new EventEmitter(); private destroy$ = new Subject(); private activeSortName: string = eSharedString.UNIT_NO; private activeSortDirection: string = eSharedString.ASC; public truckCount: number = 0; public trailerCount: number = 0; public trucks: IFleetFilterTruck[] = []; public trailers: IFleetFilterTrailer[] = []; public filteredTrucks: IFleetFilterTruck[] = []; public filteredTrailers: IFleetFilterTrailer[] = []; public fleetFilterPopover: NgbPopover | null = null; public searchForm!: UntypedFormGroup; public isTruckCardOpen: boolean = true; public isTrailerCardOpen: boolean = true; public isSearchActive: boolean = false; public sortColumns!: SortColumn[]; // svg routes public dropdownMenuSvgRoutes = FleetFilterSvgRoutes; // enums public eSharedString = eSharedString; public eFleetFilterItemType = eFleetFilterItemType; public searchInputConfig: ICaInput = FleetFilterConstants.SEARCH_INPUT_CONFIG; constructor(private formBuilder: UntypedFormBuilder) {} ngOnInit(): void { this.createFormAndSort(); this.watchSearchFormValueChanges(); } private createFormAndSort(): void { this.searchForm = this.formBuilder.group({ search: null, }); this.sortColumns = FleetFilterConstants.SORT_COLUMNS; } private watchSearchFormValueChanges(): void { this.searchForm.valueChanges .pipe(takeUntil(this.destroy$)) .subscribe((changes) => { const inputValue = changes.search?.toLowerCase() || eStringPlaceholder.EMPTY; if (!inputValue) { this.filteredTrucks = this.trucks; this.filteredTrailers = this.trailers; this.isSearchActive = false; return; } this.filteredTrucks = this.trucks.filter((truck) => truck.truckNumber?.toLowerCase().includes(inputValue) ); this.filteredTrailers = this.trailers.filter((trailer) => trailer.trailerNumber?.toLowerCase().includes(inputValue) ); this.isSearchActive = true; this.filteredTrucks = FleetFilterHelper.sortFleetItems( this.filteredTrucks, this.activeSortName, this.activeSortDirection ); this.filteredTrailers = FleetFilterHelper.sortFleetItems( this.filteredTrailers, this.activeSortName, this.activeSortDirection ); }); } public onFleetFilterOpenCloseClick(fleetFilterPopover: NgbPopover): void { if (fleetFilterPopover.isOpen()) { fleetFilterPopover.close(); this.fleetFilterPopover = null; } else { this.fleetFilterPopover?.close(); this.fleetFilterPopover = fleetFilterPopover; this.fleetFilterPopover.open(); } } public clearInput(event: boolean): void { this.filteredTrucks = this.trucks; this.filteredTrailers = this.trailers; this.isSearchActive = false; this.filteredTrucks = FleetFilterHelper.sortFleetItems( this.filteredTrucks, this.activeSortName, this.activeSortDirection ); this.filteredTrailers = FleetFilterHelper.sortFleetItems( this.filteredTrailers, this.activeSortName, this.activeSortDirection ); } public handleSortClick(event: { column: SortColumn; sortName: string; direction: string; }): void { const { direction, column } = event; this.activeSortName = column.sortName; this.activeSortDirection = direction; this.filteredTrucks = FleetFilterHelper.sortFleetItems( this.filteredTrucks, this.activeSortName, this.activeSortDirection ); this.filteredTrailers = FleetFilterHelper.sortFleetItems( this.filteredTrailers, this.activeSortName, this.activeSortDirection ); } public onOpenCard(isOpen: boolean, type: eSharedString): void { if (type === eSharedString.TRUCK) this.isTruckCardOpen = isOpen; else this.isTrailerCardOpen = isOpen; } public onItemClickEmit( itemId: number | undefined, type: eFleetFilterItemType ): void { if (itemId) { const emitData = { itemId, type, }; this.onItemClick.emit(emitData); } } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } }