import { CommonModule } from '@angular/common'; import { HttpClientModule } from '@angular/common/http'; import { Component, EventEmitter, Input, Output } from '@angular/core'; import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; // third-pary modules import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { AngularSvgIconModule } from 'angular-svg-icon'; // components import { CaProfileImageComponent } from '../ca-profile-image/ca-profile-image.component'; import { CaAppTooltipV2Component } from '../ca-app-tooltip-v2/ca-app-tooltip-v2.component'; import { CaAutoclosePopoverComponent } from '../ca-autoclose-popover/ca-autoclose-popover.component'; // pipes import { CaSvgPipe, DateFromStringPipe, NameInitialsPipe, SafeHtmlPipe, } from '../../pipes'; import { CaIsCurrentUserPipe, CaSortCommentsPipe, CaHighlightCommentPipe, CaHighlightSingleStringPipe, } from './pipes'; // enums import { eAnimationState, eSharedString, eDateTimeFormats, eGeneralActions, eColor, ePosition, eStringPlaceholder, } from '../../enums'; // models import { IComment } from './models'; import { ICompanyUser, IUser } from '../../interfaces'; // assets import { toggleUpDownAnimation } from '../../utils/animations'; // helpers import { UserHelper } from '../../utils/helpers'; // svg route import { SharedSvgRoutes } from '../../utils/svg-routes'; @Component({ selector: 'ca-comments', templateUrl: './ca-comments.component.html', styleUrl: './ca-comments.component.scss', animations: [toggleUpDownAnimation], imports: [ CommonModule, FormsModule, ReactiveFormsModule, HttpClientModule, // Components CaProfileImageComponent, CaAutoclosePopoverComponent, CaAppTooltipV2Component, // Third-party modules AngularSvgIconModule, NgbModule, // Pipes DateFromStringPipe, NameInitialsPipe, CaSvgPipe, CaIsCurrentUserPipe, CaSortCommentsPipe, CaHighlightCommentPipe, CaHighlightSingleStringPipe, SafeHtmlPipe, ] }) export class CaCommentsComponent { @Input() isDarkmode: boolean = false; @Input() isSearchDisplayed: boolean = true; @Input() isDriverTab: boolean = false; @Input() isModal: boolean = false; @Input() commentCount: number = 0; @Input() set comments(value: IComment[]) { this._comments = [...value]; } @Input() set currentUser(value: IUser) { this._currentUser = value ?? UserHelper.getUserFromLocalStorage(); } @Input() set hasNewComment(value: boolean) { if (value) this.onAddNewComment(); } @Output() onCommentDelete: EventEmitter = new EventEmitter(); @Output() onCommentAdded: EventEmitter = new EventEmitter(); @Output() onCommentEdited: EventEmitter = new EventEmitter(); @Output() onCommentCancel = new EventEmitter(); @Output() onCommentSearchCancel = new EventEmitter(); public _comments!: IComment[]; public _currentUser!: IUser; // enums public eSharedString = eSharedString; public eAnimationState = eAnimationState; public eDateTimeFormats = eDateTimeFormats; public eGeneralActions = eGeneralActions; public eColor = eColor; public ePosition = ePosition; public eStringPlaceholder = eStringPlaceholder; public sortDirection: eSharedString.ASC | eSharedString.DSC = eSharedString.DSC; public commentExpanded!: IComment | null; public commentAddOrEdit!: IComment | null; public commentAction: eGeneralActions.ADD | eGeneralActions.EDIT | null = null; // form public commentContentFormControl = new FormControl(); public searchCommentFormControl = new FormControl(); // svg routes public sharedSvgRoutes = SharedSvgRoutes; constructor() {} public onToggleSort(): void { switch (this.sortDirection) { case eSharedString.ASC: this.sortDirection = eSharedString.DSC; break; case eSharedString.DSC: this.sortDirection = eSharedString.ASC; break; default: this.sortDirection = eSharedString.DSC; return; } } public onDeleteComment(comment: IComment): void { this.onCommentDelete.emit(comment.id); } public onExpandComment(comment: IComment): void { if (this.commentExpanded?.id === comment?.id) { this.commentExpanded = null; return; } this.commentExpanded = comment; } public onAddNewComment(): void { const hasNewComment: boolean = this._comments.some( (comment: IComment) => comment.isNew ); if (hasNewComment) return; const companyUser: ICompanyUser = { id: this._currentUser?.companyUserId!, fullName: `${this._currentUser?.firstName} ${this._currentUser?.lastName}`, avatarFile: { fileId: this._currentUser?.avatarFile?.fileId ?? 0, fileName: this._currentUser?.avatarFile?.fileName || `${this._currentUser?.firstName} ${this._currentUser?.lastName}`, url: this._currentUser?.avatarFile?.url ?? eStringPlaceholder?.EMPTY, }, }; const newComment: IComment = { id: this._comments?.length + 1, commentContent: eStringPlaceholder.EMPTY, companyUser, isDriver: this.isDriverTab, isEdited: false, isNew: true, createdAt: new Date().toISOString(), }; this.commentAddOrEdit = { ...newComment }; this._comments = [{ ...newComment }, ...this._comments]; this.commentAction = eGeneralActions.ADD; } public onEditComment(comment: IComment): void { this.commentAddOrEdit = { ...comment }; this.commentContentFormControl.patchValue( this.commentAddOrEdit.commentContent ); this.commentAction = eGeneralActions.EDIT; } public clearCommentAddOrEdit(): void { this.commentAddOrEdit = null; if (this.commentAction === eGeneralActions.ADD) { this._comments = [...this._comments.slice(1)]; this.onCommentCancel.emit(); } } public onClearSearch(event: Event): void { this.searchCommentFormControl.reset(); this.onCommentSearchCancel.emit(); } public confirmComment(comment: IComment): void { switch (this.commentAction) { case eGeneralActions.EDIT: const commentFound: IComment | undefined = this._comments.find( (item: IComment) => comment.id === item.id ); if (!commentFound) break; const updatedComment: IComment = { ...comment, commentContent: this.commentContentFormControl.value ?? commentFound.commentContent, isNew: false, }; this.onCommentEdited.emit(updatedComment); break; case eGeneralActions.ADD: if (!this.commentContentFormControl.value) break; const newComment: IComment = { ...comment, commentContent: this.commentContentFormControl.value, isNew: true, }; this.onCommentAdded.emit(newComment); break; default: this.commentAction = null; break; } this.clearCommentAddOrEdit(); this.commentContentFormControl.reset(); } }