import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, Output, Renderer2, ViewChild, AfterViewInit, } from '@angular/core'; import { CommonModule } from '@angular/common'; import { AngularSvgIconModule } from 'angular-svg-icon'; import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, } from '@angular/forms'; // Components import { CaSortDropdownComponent } from '../ca-sort-dropdown/ca-sort-dropdown.component'; import { InputComponent, CaiInputConfig } from 'carriera-intern-components'; // Interfaces import { SortColumn } from '../ca-sort-dropdown/models/sort-column.model'; // Svg routes import { SharedSvgRoutes } from '../../utils/svg-routes/shared-svg.routes'; // Constants import { MapListConstants } from './utils/constants'; // Enums import { eGeneralActions, eStringPlaceholder } from '../../enums'; @Component({ selector: 'app-ca-map-list', imports: [ // Modules CommonModule, AngularSvgIconModule, ReactiveFormsModule, // Components CaSortDropdownComponent, InputComponent, ], templateUrl: './ca-map-list.component.html', styleUrl: './ca-map-list.component.scss', }) export class CaMapListComponent implements AfterViewInit { @ViewChild('mapListContainer', { static: false }) mapListContainerRef!: ElementRef; @ViewChild('mapList', { static: false }) mapListRef!: ElementRef; @ViewChild('mapListBody', { static: false }) mapListBodyRef!: ElementRef; @Input() sortColumns: SortColumn[] = []; @Input() activeSortColumn: SortColumn | null = null; @Input() set mapListData(values: T) { setTimeout(() => this.checkResizeButton(), 0); } @Output() onSearchEvent: EventEmitter = new EventEmitter(); @Output() onCloseSearchEvent: EventEmitter = new EventEmitter(); @Output() onSortEvent: EventEmitter<{ column: SortColumn; sortName: string; }> = new EventEmitter(); @Output() onMapListScrollEvent: EventEmitter = new EventEmitter(); private fullContentHeight: number = 0; public isHoveredList: boolean = false; public isExpandButtonShown: boolean = false; public isMapListExpanded: boolean = true; public previousScrollTime: number = 0; public searchForm!: UntypedFormGroup; public searchInputConfig: CaiInputConfig = MapListConstants.SEARCH_INPUT_CONFIG; public eGeneralActions = eGeneralActions; public svgRoutes = SharedSvgRoutes; constructor( private cdRef: ChangeDetectorRef, private renderer: Renderer2, private formBuilder: UntypedFormBuilder ) {} ngOnInit(): void { this.createSearchForm(); } ngAfterViewInit(): void { this.checkResizeButton(); } private createSearchForm(): void { this.searchForm = this.formBuilder.group({ [eGeneralActions.SEARCH_LOWERCASE]: null, }); } public onHoverList(isHovered: boolean) { this.isHoveredList = isHovered; } public onCloseSearch(): void { this.onCloseSearchEvent.emit(); } public onSearch(searchText: string | number | null): void { this.onSearchEvent.emit(searchText); } public onSortChange(event: { column: SortColumn; sortName: string }): void { this.onSortEvent.emit(event); } public mapListScroll(event: Event): void { const element = event.target as HTMLElement; const now = Date.now(); if ( Math.abs( element.scrollHeight - element.scrollTop - element.clientHeight ) <= 3 && now - this.previousScrollTime >= 200 ) { this.previousScrollTime = now; this.onMapListScrollEvent.emit(); } } public resizeMapList(): void { const mapListBody = this.mapListBodyRef?.nativeElement; const container = this.mapListContainerRef?.nativeElement; if (!mapListBody || !container) return; const halfHeight = container.clientHeight / 2 - 12; const currentHeight = getComputedStyle(mapListBody).height; this.renderer.setStyle(mapListBody, 'height', currentHeight); requestAnimationFrame(() => { const newHeight = this.isMapListExpanded ? `${halfHeight}px` : `${this.fullContentHeight}px`; this.renderer.setStyle(mapListBody, 'height', newHeight); this.isMapListExpanded = !this.isMapListExpanded; this.cdRef.detectChanges(); }); } public checkResizeButton(): void { const container = this.mapListContainerRef?.nativeElement; const body = this.mapListBodyRef?.nativeElement; if (!container || !body) return; this.fullContentHeight = body.scrollHeight; const halfHeight = container.clientHeight / 2 - 12; if (this.fullContentHeight > halfHeight + 1) { this.isExpandButtonShown = true; if (!this.isMapListExpanded) { this.renderer.setStyle(body, 'height', `${halfHeight}px`); } } else { this.isExpandButtonShown = false; this.renderer.removeStyle(body, 'height'); } this.cdRef.detectChanges(); } public clearSearch(): void { this.searchForm .get(eGeneralActions.SEARCH_LOWERCASE) ?.patchValue(eStringPlaceholder.EMPTY); this.onSearch(eStringPlaceholder.EMPTY); } }