import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, } from '@angular/core'; import { Subject } from 'rxjs'; // modules import { AngularSvgIconModule } from 'angular-svg-icon'; import { CommonModule } from '@angular/common'; import { NgbModule, NgbPopover } from '@ng-bootstrap/ng-bootstrap'; // moment import moment from 'moment'; // animations import { noteLongAnimation, pickupAnimation } from '../../animations/animation'; //pipe import { SafeHtmlPipe } from '../../pipes/safe-html.pipe'; //models import { NoteActiveOptions } from '../../models/note-active-options.model'; import { PlaceholderDirective } from '../../directives/placeholder-directive'; //helper import { CopyPasteHelper } from '../ca-note/utils/helper/copy-paste.helper'; //components import { CaNoteContainerComponent } from '../ca-note-container/ca-note-container.component'; import { CaAppTooltipV2Component } from '../ca-app-tooltip-v2/ca-app-tooltip-v2.component'; import { CaSpinnerComponent } from '../ca-spinner/ca-spinner.component'; //svg-routess import { NoteSvgRoutes } from '../ca-note/utils/svg-routes/note-svg-routes'; @Component({ selector: 'app-ca-note', templateUrl: './ca-note.component.html', styleUrls: ['./ca-note.component.scss'], encapsulation: ViewEncapsulation.None, imports: [ // Module CommonModule, NgbModule, AngularSvgIconModule, //Components CaNoteContainerComponent, CaAppTooltipV2Component, CaSpinnerComponent, //Directives PlaceholderDirective, // Pipe SafeHtmlPipe, ], animations: [pickupAnimation, noteLongAnimation] }) export class CaNoteComponent { @Output() saveNoteValue = new EventEmitter(); @Input() isParking: boolean = false; @Input() dispatchIndex: number = -1; @Input() type!: string; @Input() parentWidth!: string; @Input() isDispatch: boolean = false; @Input() set noteWidth(value: number) { this._noteWidth = value; } @Input() set isOpenAll(value: boolean) { this.isAllOpen = value; if (this.isDispatch) { this.closeNote(true); this.setNoteParentWidth(); } } @ViewChild('main_editor') public main_editor!: ElementRef; @ViewChild('note_popover') public note_popover!: ElementRef; @ViewChild('noteContainer') public noteContainer!: CaNoteContainerComponent; public placeholder = 'Write Something...'; public _note!: string; public _noteWidth: number = 250; public _parentWidth: number = 250; public isAllOpen!: boolean; public noteIcon: string = this._note !== '' ? NoteSvgRoutes.noteRoute : NoteSvgRoutes.noteFilledRoute; //note container public isShowColorPattern!: boolean; public buttonsExpanded = false; public activeOptions!: NoteActiveOptions; public selectedPaternColor: string = '#6C6C6C'; //properties and values public isExpanded: boolean = false; public isNoteOpened: boolean = false; public value: string = ''; private lastTypeTime!: number; public isleavedOpened!: boolean; public selectionTaken!: Selection; public range!: Range; public isFocused: boolean = false; private isPreventedClosing: boolean = false; //saving public isSavingNote: boolean = false; public savedValue: string = ''; private destroy$ = new Subject(); constructor( private ref: ChangeDetectorRef, private elRef: ElementRef ) {} ngAfterViewInit(): void { this.value = this._note; } public checkFocus(event: Event): void { event.stopPropagation(); event.preventDefault(); this.isFocused = true; this.isleavedOpened = true; this.isExpanded = true; setTimeout(() => { this.buttonsExpanded = true; this.checkActiveItems(); }, 150); } public toggleNote(data: string, t2: NgbPopover): void { this.isPreventedClosing = true; setTimeout(() => { this.isPreventedClosing = false; }, 200); if (t2?.isOpen()) { if (this.isOpenAll) { this.isleavedOpened = true; } else if (!this.isExpanded) { this.isleavedOpened = false; this.checkActiveItems(); this.isExpanded = true; this.buttonsExpanded = true; setTimeout(() => { t2.open(); }, 1); } else { this.isExpanded = false; this.buttonsExpanded = false; this.isleavedOpened = false; this.isNoteOpened = false; this._note = this.value; t2.close(); } this.isShowColorPattern = false; } else { if (!data || data == '' || this.isOpenAll) { this.buttonsExpanded = true; this.isExpanded = true; } this.isleavedOpened = true; setTimeout(() => { this.isNoteOpened = true; }, 1); t2.open(); } } public prepareForTextRange(): void { this.isFocused = false; this.selectionTaken = window.getSelection()!; if (this.selectionTaken.rangeCount && this.selectionTaken.getRangeAt) { this.range = this.selectionTaken.getRangeAt(0); this.selectionTaken.removeAllRanges(); this.selectionTaken.addRange(this.range); } } public preventMouseDown(ev: Event): void { ev.stopPropagation(); ev.preventDefault(); } public valueChange(event: Event | string, deleteAll?: boolean): void { if (event) { const target = (event as Event).target as HTMLElement; this.value = target.innerHTML; } else { this.value = event; } this.checkActiveItems(); this.lastTypeTime = moment().unix(); this.checkNoteImage(this.value); } public saveNote(autoSave?: boolean, deleteAll?: boolean): void { setTimeout(() => { if (!autoSave && this.isOpenAll) { this.closeNote(); } }, 200); if (this.value == '
') { this.value = this.value.replace('
', ''); } this.savedValue = this.value; if (deleteAll) this.closeNote(); } private closeNote(dontTransfer?: boolean): void { this.isNoteOpened = false; this.isleavedOpened = false; this.isShowColorPattern = false; this.isExpanded = false; this.buttonsExpanded = false; this._note = this.value; if (!dontTransfer) this.transferNoteData(); } public popoverClosed(): void { if (!this.isPreventedClosing) { this.closeNote(); } this.isPreventedClosing = false; } public onPaste(event: ClipboardEvent): void { CopyPasteHelper.onPaste(event); } private transferNoteData(): void { if (this.dispatchIndex === -1) this.saveNoteValue.emit(this.value); else this.saveNoteValue.emit({ note: this.value, dispatchIndex: this.dispatchIndex, }); } private checkNoteImage(note: string): void { if (note && note != '') { this.noteIcon = this.getSvgPath('noteFilledRoute'); } else { this.noteIcon = this.getSvgPath('noteRoute'); } } public getSvgPath(propertyName: keyof typeof NoteSvgRoutes): string { return NoteSvgRoutes[propertyName] as string; } private checkActiveItems(): void { if (this.noteContainer && this.noteContainer?.checkActiveItems) { this.noteContainer?.checkActiveItems(); } } private setNoteParentWidth(): void { if (this.parentWidth && this.isAllOpen) { setTimeout(() => { const parentWidth = this.elRef.nativeElement .closest(this.parentWidth) .getBoundingClientRect(); this._parentWidth = this.isDispatch ? parentWidth.width - 2 : parentWidth.width; this.ref.detectChanges(); }, 1000); } } ngOnDestroy(): void { this.isleavedOpened = false; this.isShowColorPattern = false; this.destroy$.next(); this.destroy$.complete(); } }