import { Component, Input, OnInit, OnDestroy, ElementRef, Output, EventEmitter, OnChanges } from '@angular/core'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-custom-header', templateUrl: 'custom-header.component.html', styleUrls: ['custom-header.component.scss'] }) export class CustomHeaderComponent implements OnInit, OnChanges, OnDestroy { @Input() columns: any; @Input() columnIndex: number; @Input() mappedColumn: any; @Input() header: string; @Input() forceDropdownUpdate: number; @Output() headerChanged = new EventEmitter(); currentSelection: string = this.clearSelection(); showSelection: boolean = false; customInput: string; mappedColumnIsRequired: boolean; mappedColumnType: string; mappedColumnId: number; subscriptions: Array = []; mappedColumnAriaLabel: string = ""; constructor(private _elementRef: ElementRef) {} ngOnInit(): void { if (this.mappedColumn) { this.updateMapping(this.mappedColumn, false); } else { this.mapCurrentHeader(); } this.customInput = this.header ? this.header : ''; } ngOnChanges(): void { this.clearSelection(); } ngOnDestroy(): void { this.subscriptions.forEach((sub: Subscription) => sub.unsubscribe()); } /** * Toggle the showing of the selection drop down menu. */ toggleSelection(): void { this.showSelection = !this.showSelection; } /** * Close the selection drop down menu when the document is clicked. * @param event Click event from document. */ closeSelection(event: Event): void { if (!this._elementRef.nativeElement.contains(event.target)) this.showSelection = false; } /** * Clears the mapping of a particular field */ clearMapping(): void { this.toggleSelection(); this.clearSelection(); const mappedColumnItem = { clear: true, col: this.columnIndex }; this.customHeaderChange(mappedColumnItem); this.headerChanged.emit(mappedColumnItem); } /** * Set the mapping of a field to the clicked selection or entered custom field. * @param mappedColumn is an Object containing currently select column information. * @param toggle conditional boolean to toggle drop down selection. */ updateMapping(mappedColumn: any, toggle: boolean = true): void { this.currentSelection = mappedColumn.name; this.mappedColumnIsRequired = mappedColumn.required ? true : false; this.mappedColumnType = mappedColumn.type; this.mappedColumnId = mappedColumn.colId ? mappedColumn.colId : 0; this.mappedColumnAriaLabel = `Column ${this.columnIndex + 1} will be mapped to ${this.currentSelection}` if (toggle) this.toggleSelection(); this.mapCurrentHeader(); } /** * Triggered by clearMapping and sets field to default. */ clearSelection(): string { this.mappedColumnIsRequired = false; this.mappedColumnAriaLabel = `Please define mapping for Column ${this.columnIndex + 1}` return (this.currentSelection = '- -'); } /** * Triggered by updateMapping then maps current field and sends it to the mappingView for processing. */ mapCurrentHeader(): void { const mappedColumn = { name: this.currentSelection, custom: this.header, col: this.columnIndex, colId: this.mappedColumnId, required: this.mappedColumnIsRequired, type: this.mappedColumnType }; this.customHeaderChange(mappedColumn); this.headerChanged.emit(mappedColumn); } /** * Triggered by the user entering a custom field name and clicking map. * @param columnIndex column number. */ mapCustomField(columnIndex: number, customInput: string): void { let mappedColumn: any; if (customInput.length > 0) { mappedColumn = { col: columnIndex, name: customInput, required: false, type: 'Custom' }; this.currentSelection = customInput; this.updateMapping(mappedColumn); } } /** * Triggers mapCustomField when user hits return. * @param event Keyup event from custom column field. * @param columnIndex Column number. */ keyUpOnCustom(event: KeyboardEvent, columnIndex: number, customInput: string): void { if (event.key === 'Enter') this.mapCustomField(columnIndex, customInput); } customHeaderChange(item): void { if (item.type !== 'Custom' && this.currentSelection === item.name && item.col !== this.columnIndex) this.currentSelection = this.clearSelection(); } }