diff --git a/src/components/schedule-tabs/schedule-tabs-other/schedule-tabs-other.component.css b/src/components/schedule-tabs/schedule-tabs-other/schedule-tabs-other.component.css new file mode 100644 index 0000000..136c15d --- /dev/null +++ b/src/components/schedule-tabs/schedule-tabs-other/schedule-tabs-other.component.css @@ -0,0 +1,13 @@ +.header-menu { + position: sticky; + top: 0; + background-color: var(--mat-menu-container-color); + z-index: 1; + padding-top: 5px; +} + +.button-group { + display: flex; + justify-content: space-between; + align-items: center; +} diff --git a/src/components/schedule-tabs/schedule-tabs-other/schedule-tabs-other.component.html b/src/components/schedule-tabs/schedule-tabs-other/schedule-tabs-other.component.html new file mode 100644 index 0000000..a6e5bfc --- /dev/null +++ b/src/components/schedule-tabs/schedule-tabs-other/schedule-tabs-other.component.html @@ -0,0 +1,42 @@ + + + + +
+
+ + + + + +
+ + +
+
+
+ @if (data.length === 0) { + + } @else { + + @if (filteredData.value.length !== 0) { + +
+ +
{{ item.name }}
+
+ +
+
+ } @else { +
+ Нет подходящих элементов +
+ } +
+ } +
+
diff --git a/src/components/schedule-tabs/schedule-tabs-other/schedule-tabs-other.component.ts b/src/components/schedule-tabs/schedule-tabs-other/schedule-tabs-other.component.ts new file mode 100644 index 0000000..bc98aa5 --- /dev/null +++ b/src/components/schedule-tabs/schedule-tabs-other/schedule-tabs-other.component.ts @@ -0,0 +1,139 @@ +import {Component, HostListener, Input, 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 {DataSpinnerComponent} from "@component/data-spinner/data-spinner.component"; +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"; + +export interface SelectData { + id: number, + name: string, + selected: boolean +} + +@Component({ + selector: 'app-schedule-tabs-other', + standalone: true, + imports: [ + MatMenuTrigger, + MatButton, + MatMenu, + MatFormField, + MatIcon, + FormsModule, + MatCheckbox, + DataSpinnerComponent, + MatSelectionList, + MatListOption, + MatDivider, + MatIconButton, + MatInput, + MatSuffix, + ScrollingModule, + ExperimentalScrollingModule + ], + templateUrl: './schedule-tabs-other.component.html', + styleUrl: './schedule-tabs-other.component.css' +}) +export class ScheduleTabsOtherComponent { + private _searchQuery: string = ''; + protected filteredData: BehaviorSubject = new BehaviorSubject([]); + protected data: SelectData[] = []; + + @Input() idButton!: string; + @Input() buttonText!: string; + @ViewChild('menuTrigger') menuTrigger!: MatMenuTrigger; + @ViewChild('chooseCheckbox') chooseCheckbox!: MatCheckbox; + + 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 clearSearch(): 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 selectData() { + 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); + console.log(this.filteredData.value); + this.updateCheckBox(); + } + + selectChange(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); + } +}