import {Component, EventEmitter, Output, 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, TabSelectData, TabSelectType, TabStorageService} from "@service/tab-storage.service"; @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; @Output() eventResult = new EventEmitter(); constructor(private facultyApi: FacultyService, private groupApi: GroupService, private tabStorage: TabStorageService) { } existParams(data: TabSelectData): boolean { return data.selected['group'] !== undefined || data.selected['course'] !== undefined || data.selected['faculty'] !== undefined; } protected loadFaculties() { this.facultyApi.getFaculties() .pipe(catchError(error => { this.facultyIndicator.loading = false; throw error; })) .subscribe(data => { this.faculties = data; let selected = TabStorageService.selected?.selected['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); } } }); } 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['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); } } let selectedGroupStorage = TabStorageService.selected?.selected['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); } } }); 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) { this.courseNumber = null; this.groups = []; this.formChipGroup.reset(); this.formChipCourse.reset(); if (index === undefined) { this.facultyId = null; return; } this.tabStorage.select(new TabSelect(index, this.faculties!.find(x => x.id === index)?.name ?? ''), TabSelectType.group, 'faculty'); this.facultyId = index; this.courseNumberPanel.open(); this.loadCourseGroup(); } protected onCourseSelected(course: number) { this.filteredGroupsBehaviour = []; this.filteredGroupsMagistracy = []; this.filteredGroupsSpecialist = []; this.formChipGroup.reset(); if (course === undefined) { this.courseNumber = null; return; } this.tabStorage.select(new TabSelect(course, course.toString()), TabSelectType.group, 'course'); this.courseNumber = course; this.groupPanel.open(); this.loadCourseGroup(); } protected onGroupSelected(index: number) { if (index === undefined) return; this.tabStorage.select(new TabSelect(index, this.groups!.find(x => x.id == index)?.name ?? ''), TabSelectType.group, 'group'); this.groupPanel.close(); this.eventResult.emit(index); } public load() { if (this.faculties === null) this.loadFaculties(); } }