import {Component, EventEmitter, Output, ViewChild} from '@angular/core'; import {HttpClientModule} from "@angular/common/http"; import {OtherComponent} from "@component/schedule/tabs/other/other.component"; import {MatTab, MatTabChangeEvent, MatTabGroup} from "@angular/material/tabs"; import {catchError, map, Observable, of, switchMap, tap} from "rxjs"; import {ReactiveFormsModule} from "@angular/forms"; import {AsyncPipe, NgIf} from "@angular/common"; import {MatButton} from "@angular/material/button"; import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component"; import {ProfessorResponse} from "@api/v1/professorResponse"; import {FacultyResponse} from "@api/v1/facultyResponse"; import {GroupResponse} from "@api/v1/groupResponse"; import {CampusBasicInfoResponse} from "@api/v1/campusBasicInfoResponse"; import {LectureHallResponse} from "@api/v1/lectureHallResponse"; import {DisciplineService} from "@api/v1/discipline.service"; import {GroupComponent} from "@component/schedule/tabs/group/group.component"; import {ProfessorComponent} from "@component/schedule/tabs/professor/professor.component"; import {LectureHallComponent} from "@component/schedule/tabs/lecture-hall/lecture-hall.component"; import {FacultyService} from "@api/v1/faculty.service"; import {GroupService} from "@api/v1/group.service"; import {ProfessorService} from "@api/v1/professor.service"; import {CampusService} from "@api/v1/campus.service"; import {LectureHallService} from "@api/v1/lectureHall.service"; @Component({ selector: 'app-tabs', standalone: true, imports: [ HttpClientModule, OtherComponent, MatTabGroup, MatTab, ReactiveFormsModule, AsyncPipe, NgIf, MatButton, DataSpinnerComponent, GroupComponent, ProfessorComponent, LectureHallComponent ], templateUrl: './tabs.component.html', styleUrl: './tabs.component.css', providers: [FacultyService, GroupService, ProfessorService, CampusService, LectureHallService, DisciplineService ] }) export class TabsComponent { protected professorsData: ProfessorResponse[] = []; protected faculties: Observable = of([]); protected groups: Observable = of([]); private groupsData: Observable = of([]); protected campuses: Observable = of([]); protected lectureHalls: Observable = of([]); private lectureHallsData: Observable = of([]); // States protected facultiesLoaded: boolean | null = false; protected groupLoaded: boolean | null = false; protected campusesLoaded: boolean | null = false; protected lectureHallsLoaded: boolean | null = false; protected disciplinesLoaded: boolean | null = false; protected professorsLoaded: boolean | null = false; @Output() groupSelected: EventEmitter = new EventEmitter(); @Output() lectureHallSelected: EventEmitter = new EventEmitter(); @Output() professorSelected: EventEmitter = new EventEmitter(); constructor( private facultyApi: FacultyService, private groupApi: GroupService, private professorApi: ProfessorService, private campusApi: CampusService, private lectureHallApi: LectureHallService, private disciplineApi: DisciplineService) { this.facultyLoad().then(); } protected async chooseTabs(event: MatTabChangeEvent) { switch (event.index) { case 0: await this.facultyLoad(); break; case 1: this.professorsLoad(); break; case 2: await this.campusLoad(); break; case 3: await this.extensionLoad(); break; } } protected async facultyLoad() { if (this.facultiesLoaded === null) this.facultiesLoaded = false; if (this.facultiesLoaded) return; this.faculties = this.facultyApi.getFaculties().pipe( tap(() => { this.facultiesLoaded = true; }), catchError((error) => { this.facultiesLoaded = null; throw error; }) ); } protected groupLoad(id: number) { if (this.groupLoaded === null) this.groupLoaded = false; if (this.groupLoaded) this.groups = this.groupsData.pipe(map(data => data.filter(x => x.facultyId === id))); else this.groups = this.groupApi.getByFaculty(id).pipe( tap(() => { this.groupLoaded = false; }), catchError((error) => { this.groupLoaded = null; throw error; }) ); } protected professorsLoad() { if (this.professorsLoaded === null) this.professorsLoaded = false; if (this.professorsLoaded) return; this.professorApi.getProfessors().pipe( catchError((error) => { this.professorsLoaded = null; throw error; }) ).subscribe(data => { this.professorsData = data; this.professorEx.Data = data.map(x => ({ id: x.id, name: x.altName ? x.altName : x.name, selected: false })); }); } protected async campusLoad() { if (this.campusesLoaded === null) this.campusesLoaded = false; if (this.campusesLoaded) return; this.campuses = this.campusApi.getCampus().pipe( tap(() => { this.campusesLoaded = true; }), catchError((error) => { this.campusesLoaded = null; throw error; }) ); } protected lectureHallLoad(id: number) { if (this.lectureHallsLoaded === null) this.lectureHallsLoaded = false; if (this.lectureHallsLoaded) this.lectureHalls = this.lectureHallsData.pipe(map(data => data.filter(x => x.campusId === id))); else this.lectureHalls = this.lectureHallApi.getByCampus(id).pipe( tap(() => { this.lectureHallsLoaded = false; }), catchError((error) => { this.lectureHallsLoaded = null; throw error; }) ); } protected async loadLectureHalls() { if (!this.campusesLoaded) await this.campusLoad(); if (!this.lectureHallsLoaded) { this.lectureHallsData = this.lectureHallApi.getLectureHalls(); this.lectureHallsData.pipe( switchMap(lectureHalls => this.campuses.pipe( map(campuses => { return lectureHalls.map(x => { const campus = campuses.find(c => c.id === x.campusId); const codeName = campus ? campus.codeName : ''; return { id: x.id, name: `${x.name} (${codeName})`, selected: false }; }); }) )), ).subscribe(data => { this.lectureHallEx.Data = data; this.lectureHallsLoaded = true; this.campusesLoaded = true; }); } } protected async loadDisciplines() { if (!this.disciplinesLoaded) { this.disciplineApi.getDisciplines().pipe( catchError((error) => { this.disciplinesLoaded = null; throw error; })).subscribe(data => { this.disciplineEx.Data = data.map(x => ({ id: x.id, name: x.name, selected: false })); this.disciplinesLoaded = true; }); } } protected async loadGroups() { if (!this.facultiesLoaded) await this.facultyLoad(); if (!this.groupLoaded) { this.groupsData = this.groupApi.getGroups(); this.groupsData.pipe( switchMap(groups => this.faculties.pipe( map(campuses => { return groups.map(x => { const faculties = campuses.find(c => c.id === x.facultyId); const name = faculties ? faculties.name : ''; return { id: x.id, name: `${x.name} (${name})`, selected: false }; }); }) )) ).subscribe(data => { this.groupEx.Data = data; this.groupLoaded = true; }); } } protected async extensionLoad() { // Lecture Hall await this.loadLectureHalls(); // Disciplines await this.loadDisciplines(); // Groups await this.loadGroups(); // Professors if (this.professorsData.length === 0) this.professorsLoad(); } @ViewChild('discipline') disciplineEx!: OtherComponent; @ViewChild('lecture') lectureHallEx!: OtherComponent; @ViewChild('group') groupEx!: OtherComponent; @ViewChild('professor') professorEx!: OtherComponent; }