import { Component, OnInit, Input, Output, EventEmitter, HostListener, ElementRef } from '@angular/core'; import { every, forEach } from 'lodash'; import { HierarchicalSelectValue } from '../../../utils'; @Component({ selector: 'esp-hierarchical-dropdown', templateUrl: './hierarchical-dropdown.component.html', styleUrls: ['./hierarchical-dropdown.component.scss'], }) export class HierarchicalDropdownComponent implements OnInit { @Input() hierarchicalSelectOptions: HierarchicalSelectValue; @Input() selectAllLabel: string; @Input() dropdownName: string; @Input() disabled: boolean; @Input() showBorder: boolean; @Input() branchNode: boolean; @Input() childNode: boolean; @Output() selectChange: EventEmitter = new EventEmitter(); updatedFilter = null; dropdownLabel: string; showOptions = false; constructor(private eRef: ElementRef) {} @HostListener('document:click', ['$event']) onMenuDeselect(event) { if (!this.eRef.nativeElement.contains(event.target) && this.showOptions) { this.updatedFilter = { name: this.dropdownName ? this.dropdownName : 'selectedOption', hierarchicalSelectOptions: this.hierarchicalSelectOptions, }; this.showOptions = false; if (this.updatedFilter) { this.selectChange.emit(this.updatedFilter); } } } ngOnInit(): void { if(!this.childNode) this.dropdownLabel = this.getDropdownLabel(this.hierarchicalSelectOptions, this.selectAllLabel, false); } changeFilter($event, index): void { $event.stopPropagation(); const wasSelected = this.hierarchicalSelectOptions.children[index].selected; this.hierarchicalSelectOptions.children[index].selected = !this.hierarchicalSelectOptions.children[index].selected; if (!this.hierarchicalSelectOptions.children[index].selected) { this.hierarchicalSelectOptions.selected = false; } this.selectOrUnselectChildren(this.hierarchicalSelectOptions.children[index].children, wasSelected); if (every(this.hierarchicalSelectOptions.children, ['selected', true])) { this.hierarchicalSelectOptions.selected = true; } if(!this.childNode) this.dropdownLabel = this.getDropdownLabel(this.hierarchicalSelectOptions, this.selectAllLabel, false); this.updatedFilter = { name: this.dropdownName ? this.dropdownName : 'selectedOption', hierarchicalSelectOptions: this.hierarchicalSelectOptions, }; if(this.childNode){ this.selectChange.emit(this.updatedFilter); } } selectOrUnselectChildren(children, wasSelected) { forEach(children, child => { child.selected = !wasSelected; if (child.children && child.children.length > 0) { this.selectOrUnselectChildren(child.children, wasSelected); } }); } hierarchicalDropdownSelected(event?): void { this.updatedFilter = { name: this.dropdownName ? this.dropdownName : 'selectedOption', hierarchicalSelectOptions: this.hierarchicalSelectOptions, }; if(!this.childNode) this.dropdownLabel = this.getDropdownLabel(this.hierarchicalSelectOptions, this.selectAllLabel, false); } getDropdownLabel(hierarchicalSelectOptions, selectAllLabel, recursion): string { let dropdownLabel = ''; if(hierarchicalSelectOptions?.children.length){ let isAllchildrenSelected = every(hierarchicalSelectOptions?.children, ['selected', true]); let allSelectedValue = selectAllLabel ? selectAllLabel : 'All selected'; if (isAllchildrenSelected && !recursion) { return allSelectedValue; } else if (hierarchicalSelectOptions.children.some(opt => !opt.selected)) { if(!recursion && hierarchicalSelectOptions.children.every(opt => opt.children && opt.children.length && opt.children.every( option => ((option.children && option.children.length === 0) || !option.children) && !option.selected) && !opt.selected)){ return 'None'; } else { forEach(hierarchicalSelectOptions.children, option => { if (option.selected) { dropdownLabel = dropdownLabel ? dropdownLabel + ', ' : dropdownLabel; dropdownLabel = dropdownLabel + (option.label ? option.label : option.value); dropdownLabel = dropdownLabel.replace('\n',''); } else { let label = this.getDropdownLabel(option, option.label ? option.label : option.value, true); label = label.replace('\n',''); dropdownLabel = dropdownLabel && label ? dropdownLabel + ', ' + label : dropdownLabel + label; } }); return dropdownLabel; } } } else { return dropdownLabel; } } toggleDropdown(): void { this.showOptions = !this.showOptions; } }