import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, } from '@angular/core'; import { CommonModule } from '@angular/common'; import { AngularSvgIconModule } from 'angular-svg-icon'; import { HttpClientModule } from '@angular/common/http'; import { debounceTime, Subject, takeUntil } from 'rxjs'; import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, } from '@angular/forms'; // models import { ActivityLogItem } from './models'; // enums import { ActivityLogUtils } from './enums'; import { RightSidePanelCurrentTab } from '../ca-right-side-panel/enums'; import { eStringPlaceholder } from '../../enums'; // pipes import { ActionLogNameTransformPipe, ActivityLogDateTransformPipe, CompanyUserNameTransformPipe, TabTitleTransformPipe, } from './utils/pipes'; import { CaSvgPipe } from '../../pipes'; // components import { CaProfileImageComponent } from '../ca-profile-image/ca-profile-image.component'; import { CaInputComponent } from '../ca-input/ca-input.component'; // configs import { ICaInput } from '../ca-input/config'; import { ActivityLogSearchFilterConfig } from './config'; @Component({ selector: 'app-ca-activity-log-list', templateUrl: './ca-activity-log-list.component.html', styleUrls: ['./ca-activity-log-list.component.scss'], imports: [ CommonModule, AngularSvgIconModule, HttpClientModule, ReactiveFormsModule, // components CaProfileImageComponent, CaInputComponent, // pipes ActionLogNameTransformPipe, ActivityLogDateTransformPipe, CaSvgPipe, TabTitleTransformPipe, CompanyUserNameTransformPipe, ] }) export class CaActivityLogListComponent implements OnInit, OnDestroy { public RightSidePanelCurrentTab = RightSidePanelCurrentTab; public activityLogSearchConfig!: ICaInput; public searchForm!: UntypedFormGroup; public searchButtonSvg!: string; public showSearch: boolean = false; public hoveredItemId: number = 0; public hoveredUserName?: string; public focusedItemId: number = 0; public _selectedTab!: RightSidePanelCurrentTab; private destroy$ = new Subject(); public _activityLogList!: ActivityLogItem[]; @Input() set activityLogList(value: ActivityLogItem[]) { this.filterActivityLogListDate(value); } @Input() set selectedTab(value: RightSidePanelCurrentTab) { this._selectedTab = value; this.focusedItemId = 0; } @Output() searchText: EventEmitter = new EventEmitter(); @Output() resetFilters: EventEmitter = new EventEmitter(); constructor( private formBuilder: UntypedFormBuilder, private cdr: ChangeDetectorRef ) {} ngOnInit(): void { this.createForm(); this.setActivityLogSearch(); } private createForm(): void { this.searchForm = this.formBuilder.group({ search: null, }); this.watchSearchFormValueChanges(); } private filterActivityLogListDate( activityLogList: ActivityLogItem[] ): void { activityLogList.forEach((item: ActivityLogItem, index, array) => { const currentDate = item.createdAt ? new Date(item.createdAt).toDateString() : ActivityLogUtils.NONE; const previousItem = array[index - 1]; const previousDate = index && previousItem?.createdAt ? new Date(previousItem.createdAt).toDateString() : ActivityLogUtils.NONE; item.isFirstInDay = currentDate !== previousDate; if (typeof item.description === ActivityLogUtils.STRING) item.description = JSON.parse(item.description as string); }); this._activityLogList = activityLogList; this.cdr.detectChanges(); } private setActivityLogSearch(): void { this.activityLogSearchConfig = ActivityLogSearchFilterConfig.getActivityLogSearch(); this.searchButtonSvg = ActivityLogSearchFilterConfig.getSearchButtonSvg(); } public openSearchInput(): void { this.showSearch = true; } public hoverItem(activityLogItem: ActivityLogItem): void { this.hoveredItemId = activityLogItem.id; this.setHoveredUserName(activityLogItem.companyUser.fullName); } public leaveItem(): void { this.hoveredItemId = 0; } private setHoveredUserName(fullName: string): void { const [name, surname] = fullName.split(eStringPlaceholder.WHITESPACE); this.hoveredUserName = `${name[0]}. ${surname}`; } public activityLogItemFocus(activityLogItemId: number): void { if (this.focusedItemId === activityLogItemId) this.focusedItemId = 0; else this.focusedItemId = activityLogItemId; } private watchSearchFormValueChanges(): void { this.searchForm.valueChanges .pipe(takeUntil(this.destroy$), debounceTime(500)) .subscribe((changes) => { const inputValue: string = changes.search?.toLowerCase() || ''; this.searchText.emit(inputValue); }); } public resetFiltersClick(): void { this.resetFilters.emit(true); } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } }