import {Component, EventEmitter, ViewChild} from '@angular/core'; import {MatExpansionModule, MatExpansionPanel} from "@angular/material/expansion"; import {MatChipListbox, MatChipsModule} from '@angular/material/chips'; import {FormControl, FormsModule, ReactiveFormsModule} from "@angular/forms"; import {catchError} from "rxjs"; import {LoadingIndicatorComponent} from "@component/common/loading-indicator/loading-indicator.component"; import {GroupResponse} from "@api/v1/groupResponse"; import {FacultyResponse} from "@api/v1/facultyResponse"; import {FacultyService} from "@api/v1/faculty.service"; import {GroupService} from "@api/v1/group.service"; import {IScheduleTab} from "@component/schedule/tabs/ischedule-tab"; import {TabSelect, TabStorageService} from "@service/tab-storage.service"; enum Enclosure { faculty, course, group } @Component({ selector: 'app-group', standalone: true, imports: [ MatExpansionModule, MatChipsModule, ReactiveFormsModule, LoadingIndicatorComponent, FormsModule ], templateUrl: './group.component.html', styleUrl: './group.component.css', providers: [FacultyService, GroupService] }) export class GroupComponent implements IScheduleTab { protected faculties: FacultyResponse[] | null = null; protected courseNumbers: number[] | null = null; private groups: GroupResponse[] | null = null; protected filteredGroupsBehaviour: GroupResponse[] | null = null; protected filteredGroupsMagistracy: GroupResponse[] | null = null; protected filteredGroupsSpecialist: GroupResponse[] | null = null; protected facultyId: number | null = null; protected courseNumber: number | null = null; protected formChipCourse: FormControl = new FormControl(); protected formChipGroup: FormControl = new FormControl(); @ViewChild('courseNumberPanel') courseNumberPanel!: MatExpansionPanel; @ViewChild('groupPanel') groupPanel!: MatExpansionPanel; @ViewChild('facultyChip') facultyChip!: MatChipListbox; @ViewChild('courseChip') courseChip!: MatChipListbox; @ViewChild('groupChip') groupChip!: MatChipListbox; @ViewChild('facultyIndicator') facultyIndicator!: LoadingIndicatorComponent; @ViewChild('courseIndicator') courseIndicator!: LoadingIndicatorComponent; @ViewChild('groupIndicator') groupIndicator!: LoadingIndicatorComponent; private resetCourse() { this.courseNumber = null; this.groups = []; this.formChipCourse.reset(); this.courseChip.value = undefined; } private resetGroup() { this.filteredGroupsBehaviour = []; this.filteredGroupsMagistracy = []; this.filteredGroupsSpecialist = []; this.formChipGroup.reset(); this.groupChip.value = undefined; } public eventResult = new EventEmitter(); public selectChangeEvent = new EventEmitter(); constructor(private facultyApi: FacultyService, private groupApi: GroupService) { } private getSelectedTabs(): TabSelect[] { const faculty = this.facultyChip.value; const course = this.courseChip.value; const group = this.groupChip.value; const result: TabSelect[] = []; if (faculty) result.push(new TabSelect(faculty, this.faculties!.find(x => x.id === faculty)?.name ?? '')); if (course) result.push(new TabSelect(course, course.toString())); if (group) result.push(new TabSelect(group, this.groups!.find(x => x.id == group)?.name ?? '')); return result; } public getEnclosureList(): string[] { return Object.keys(Enclosure).filter((item) => { return isNaN(Number(item)); }); } protected loadFaculties() { this.facultyApi.getFaculties() .pipe(catchError(error => { this.facultyIndicator.loading = false; throw error; })) .subscribe(data => { this.faculties = data; let selected = TabStorageService.selected?.selected[this.getEnclosureList()[Enclosure.faculty]]; if (selected) { let selectedFaculty = data.find(x => x.id === selected.index); if (selectedFaculty === undefined || selectedFaculty.name !== selected.name) selectedFaculty = data.find(x => x.name === selected.name); if (selectedFaculty !== undefined) { TabStorageService.trySelectChip(selectedFaculty.id, this.facultyChip); this.onFacultySelected(selectedFaculty.id, true); } } }); } protected loadCourseGroup() { if (this.facultyId === null) return; if (this.groups === null || this.groups.length === 0 || this.groups[0].facultyId !== this.facultyId) { this.groupApi.getByFaculty(this.facultyId) .pipe(catchError(error => { this.groupIndicator.loading = false; this.courseIndicator.loading = false; throw error; })) .subscribe(data => { this.groups = data; this.courseNumbers = Array.from( new Set( this.groups! .map(x => x.courseNumber) .sort((a, b) => a - b)) ); let selected = TabStorageService.selected?.selected[this.getEnclosureList()[Enclosure.course]]; if (selected) { let selectedCourse = this.courseNumbers.find(x => x === selected.index); if (selectedCourse === undefined) selectedCourse = this.courseNumbers.find(x => x.toString() === selected.name); if (selectedCourse !== undefined) { TabStorageService.trySelectChip(selectedCourse, this.courseChip); this.onCourseSelected(selectedCourse, true); } } let selectedGroupStorage = TabStorageService.selected?.selected[this.getEnclosureList()[Enclosure.group]]; if (selectedGroupStorage) { let selectedGroup = data.find(x => x.id === selectedGroupStorage.index); if (selectedGroup === undefined || selectedGroup.name !== selectedGroupStorage.name) selectedGroup = data.find(x => x.name === selectedGroupStorage.name); if (selectedGroup !== undefined) { TabStorageService.trySelectChip(selectedGroup.id, this.groupChip); this.onGroupSelected(selectedGroup.id, true); } } }); return; } if (this.courseNumber !== null) { const groupByCourse = this.groups!.filter(x => x.courseNumber === this.courseNumber); groupByCourse.forEach(x => { if (x.name[2].toUpperCase() === 'Б') this.filteredGroupsBehaviour?.push(x); else if (x.name[2].toUpperCase() === 'С') this.filteredGroupsSpecialist?.push(x); else this.filteredGroupsMagistracy?.push(x); }); } } protected onFacultySelected(index: number, loadMode: boolean = false) { this.resetCourse(); this.resetGroup(); if (index === undefined) { this.facultyId = null; return; } if (loadMode) this.facultyChip.value = index; else this.selectChangeEvent.emit(this.getSelectedTabs()); this.facultyId = index; this.courseNumberPanel.open(); this.loadCourseGroup(); } protected onCourseSelected(course: number, loadMode: boolean = false) { this.resetGroup(); if (course === undefined) { this.courseNumber = null; return; } if (loadMode) this.courseChip.value = course; else this.selectChangeEvent.emit(this.getSelectedTabs()); this.courseNumber = course; this.groupPanel.open(); this.loadCourseGroup(); } protected onGroupSelected(index: number, loadMode: boolean = false) { if (index === undefined) return; if (loadMode) this.groupChip.value = index; this.selectChangeEvent.emit(this.getSelectedTabs()); this.groupPanel.close(); this.eventResult.emit(index); } public load() { if (this.faculties === null) this.loadFaculties(); } }