import {Component, EventEmitter, HostListener, Input, Output, ViewChild} from '@angular/core'; import {MatMenu, MatMenuTrigger} from "@angular/material/menu"; import {MatCheckbox} from "@angular/material/checkbox"; import {BehaviorSubject} from "rxjs"; import {MatButton, MatIconButton} from "@angular/material/button"; import {MatFormField, MatSuffix} from "@angular/material/form-field"; import {MatIcon} from "@angular/material/icon"; import {FormsModule} from "@angular/forms"; import {MatListOption, MatSelectionList} from "@angular/material/list"; import {ScrollingModule} from "@angular/cdk/scrolling"; import {ScrollingModule as ExperimentalScrollingModule} from '@angular/cdk-experimental/scrolling'; import {MatDivider} from "@angular/material/divider"; import {MatInput} from "@angular/material/input"; import {LoadingIndicatorComponent} from "@component/common/loading-indicator/loading-indicator.component"; export interface SelectData { id: number, name: string, selected: boolean } @Component({ selector: 'app-other', standalone: true, imports: [ MatMenuTrigger, MatButton, MatMenu, MatFormField, MatIcon, FormsModule, MatCheckbox, MatSelectionList, MatListOption, MatDivider, MatIconButton, MatInput, MatSuffix, ScrollingModule, ExperimentalScrollingModule, LoadingIndicatorComponent ], templateUrl: './other.component.html', styleUrl: './other.component.css' }) export class OtherComponent { private _searchQuery: string = ''; protected filteredData: BehaviorSubject = new BehaviorSubject([]); protected data: SelectData[] = []; @Input() idButton!: string; @Input() textButton!: string; @ViewChild('menuTrigger') menuTrigger!: MatMenuTrigger; @ViewChild('chooseCheckbox') chooseCheckbox!: MatCheckbox; @Input() dataLoaded: boolean | null = false; @Output() retryLoadData: EventEmitter = new EventEmitter(); get selectedIds(): number[] { return this.data.filter(x => x.selected).map(x => x.id); } set Data(data: SelectData[]) { this.data = data; this.data.forEach(x => x.selected = false); this.filteredData.next(this.data); } protected get searchQuery(): string { return this._searchQuery; } private updateCheckBox() { this.chooseCheckbox.checked = this.data.every(x => x.selected); this.chooseCheckbox.indeterminate = this.data.some(x => x.selected) && !this.chooseCheckbox.checked; } protected set searchQuery(value: string) { this._searchQuery = value; this.updateFilteredData(); } protected updateFilteredData(): void { this.filteredData.next(this.data.filter(x => x.name.toLowerCase().includes(this.searchQuery.toLowerCase()) )); } protected clearSearchQuery(): void { this.searchQuery = ''; } protected clearAll(): void { this.data.forEach(x => x.selected = false); if (this.searchQuery !== '') { const updatedData = this.filteredData.value.map(x => { return {...x, selected: false}; }); this.filteredData.next(updatedData); } else this.updateFilteredData(); this.updateCheckBox(); } protected checkData() { const check: boolean = this.filteredData.value.some(x => !x.selected) && !this.filteredData.value.every(x => x.selected); const updatedData = this.filteredData.value.map(data => { this.data.find(x => x.id === data.id)!.selected = check; return {...data, selected: check}; }); this.filteredData.next(updatedData); this.updateCheckBox(); } protected checkboxStateChange(item: number) { const data = this.data.find(x => x.id === item)!; data.selected = !data.selected; const updatedData = this.filteredData.value; updatedData.find(x => x.id === item)!.selected = data.selected; this.filteredData.next(updatedData); this.updateCheckBox(); } @HostListener('document:click', ['$event']) private onClick(event: MouseEvent): void { if (this.menuTrigger && this.menuTrigger.menuOpen && (event.target as HTMLElement).closest('.mat-menu-content') === null && !this.isInsideMenuButton(event.target as HTMLElement, this.idButton)) { this.menuTrigger.closeMenu(); } } private isInsideMenuButton(target: HTMLElement, id: string): boolean { let parentElement: HTMLElement | null = target.parentElement; return (parentElement !== null && parentElement.id === id); } }