refactor: bind components to api

This commit is contained in:
2024-06-11 00:16:17 +03:00
parent bd03cde151
commit 8a1921b6cb
8 changed files with 294 additions and 246 deletions

View File

@ -6,12 +6,13 @@
</mat-panel-title>
</mat-expansion-panel-header>
<mat-chip-listbox hideSingleSelectionIndicator (change)="chooseFaculty($event)">
@for (faculty of faculties | async; track $index) {
@for (faculty of faculties; track $index) {
<mat-chip-option [value]="faculty.id" color="accent">
{{ faculty.name }}
</mat-chip-option>
} @empty {
<app-loading-indicator [loading]="facultiesLoaded !== null" (retryFunction)="facultiesLoadRetry.emit()"/>
<app-loading-indicator [loading]="facultiesLoaded !== null"
(retryFunction)="loadFaculties()"/>
}
</mat-chip-listbox>
</mat-expansion-panel>
@ -22,14 +23,14 @@
Курс
</mat-panel-title>
</mat-expansion-panel-header>
<mat-chip-listbox hideSingleSelectionIndicator (change)="chooseCourseNumber($event)" [formControl]="chipCourse">
@for (course of courseNumbers | async; track $index) {
<mat-chip-listbox hideSingleSelectionIndicator (change)="chooseCourseNumber($event)" [formControl]="formChipCourse">
@for (course of courseNumbers; track $index) {
<mat-chip-option [value]="course" color="accent">
{{ course }}
</mat-chip-option>
} @empty {
<app-loading-indicator [loading]="groupsLoaded !== null"
(retryFunction)="groupsLoadRetry.emit(this.facultyId!)"/>
(retryFunction)="loadCourseGroup()"/>
}
</mat-chip-listbox>
</mat-expansion-panel>
@ -40,14 +41,14 @@
Группа
</mat-panel-title>
</mat-expansion-panel-header>
<mat-chip-listbox hideSingleSelectionIndicator (change)="chooseGroup($event)" [formControl]="chipGroup">
@for (group of filteredGroups | async; track $index) {
<mat-chip-listbox hideSingleSelectionIndicator (change)="chooseGroup($event)" [formControl]="formChipGroup">
@for (group of filteredGroups; track $index) {
<mat-chip-option [value]="group.id" color="accent">
{{ group.name }}
</mat-chip-option>
} @empty {
<app-loading-indicator [loading]="groupsLoaded !== null"
(retryFunction)="groupsLoadRetry.emit(this.facultyId!)"/>
(retryFunction)="loadCourseGroup()"/>
}
</mat-chip-listbox>
</mat-expansion-panel>

View File

@ -1,12 +1,13 @@
import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core';
import {Component, EventEmitter, Output, ViewChild} from '@angular/core';
import {MatExpansionModule, MatExpansionPanel} from "@angular/material/expansion";
import {MatChipListboxChange, MatChipsModule} from '@angular/material/chips';
import {FormControl, ReactiveFormsModule} from "@angular/forms";
import {AsyncPipe} from "@angular/common";
import {map, Observable, of} from "rxjs";
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";
@Component({
selector: 'app-group',
@ -16,49 +17,98 @@ import {FacultyResponse} from "@api/v1/facultyResponse";
MatChipsModule,
ReactiveFormsModule,
LoadingIndicatorComponent,
AsyncPipe
FormsModule
],
templateUrl: './group.component.html',
styleUrl: './group.component.css'
styleUrl: './group.component.css',
providers: [FacultyService, GroupService]
})
export class GroupComponent {
protected facultyId: number | null = null;
protected courseNumber: number | null = null;
protected filteredGroups: Observable<GroupResponse[]> = of([]);
protected courseNumbers: Observable<number[]> = of([]);
protected groups: Observable<GroupResponse[]> = of([]);
protected filteredGroups: GroupResponse[] = [];
protected courseNumbers: number[] = [];
private groups: GroupResponse[] = [];
protected chipCourse: FormControl = new FormControl();
protected chipGroup: FormControl = new FormControl();
protected formChipCourse: FormControl = new FormControl();
protected formChipGroup: FormControl = new FormControl();
protected faculties: FacultyResponse[] = [];
@ViewChild('courseNumberPanel') courseNumberPanel!: MatExpansionPanel;
@ViewChild('groupPanel') groupPanel!: MatExpansionPanel;
@Input() faculties: Observable<FacultyResponse[]> = of([]);
@Input() facultiesLoaded: boolean | null = false;
@Output() facultiesLoadRetry: EventEmitter<void> = new EventEmitter<void>();
@Input() groupsLoaded: boolean | null = false;
@Output() groupsLoadRetry: EventEmitter<number> = new EventEmitter<number>();
protected facultiesLoaded: boolean | null = false;
protected groupsLoaded: boolean | null = false;
@Input() set setGroups(data: Observable<GroupResponse[]>) {
this.groups = data;
this.courseNumbers = this.groups.pipe(
map(data => data.map(g => g.courseNumber)),
map(courseNumbersArray => courseNumbersArray.filter((value, index, self) => self.indexOf(value) === index)),
map(uniqueCourseNumbers => uniqueCourseNumbers.sort((a, b) => a - b))
);
@Output() eventResult = new EventEmitter<number>();
constructor(private facultyApi: FacultyService, private groupApi: GroupService) {
this.loadFaculties();
}
@Output() groupSelected = new EventEmitter<number>();
@Output() facultySelected = new EventEmitter<number>();
protected loadFaculties() {
this.facultiesLoaded = false;
this.facultyApi.getFaculties()
.pipe(catchError(error => {
this.facultiesLoaded = null;
throw error;
}))
.subscribe(data => {
this.faculties = data;
this.facultiesLoaded = true;
});
}
private filteringCourseNumber() {
this.courseNumbers = Array.from(
new Set(
this.groups
.filter(x => x.facultyId === this.facultyId)
.map(x => x.courseNumber)
)
).sort((a, b) => a - b);
}
private filteringGroup() {
this.filteredGroups = this.groups.filter(x => x.facultyId === this.facultyId && x.courseNumber === this.courseNumber);
}
protected loadCourseGroup() {
if (this.groups.length === 0) {
this.groupsLoaded = false;
this.groupApi.getGroups().pipe(
catchError(error => {
this.groupsLoaded = null;
throw error;
})
).subscribe(data => {
this.groups = data;
if (this.courseNumber === null)
this.filteringCourseNumber();
else
this.filteringGroup();
this.groupsLoaded = true;
});
return
}
if (this.courseNumber === null)
this.filteringCourseNumber();
else
this.filteringGroup();
}
protected chooseFaculty(event: MatChipListboxChange) {
this.courseNumber = null;
this.groups = of([]);
this.chipGroup.reset();
this.chipCourse.reset();
this.groups = [];
this.formChipGroup.reset();
this.formChipCourse.reset();
if (event.value === undefined || event.value === null) {
this.facultyId = null;
@ -67,12 +117,12 @@ export class GroupComponent {
this.facultyId = event.value;
this.courseNumberPanel.open();
this.facultySelected.emit(this.facultyId!);
this.loadCourseGroup();
}
protected chooseCourseNumber(event: MatChipListboxChange) {
this.filteredGroups = of([]);
this.chipGroup.reset();
this.filteredGroups = [];
this.formChipGroup.reset();
if (event.value === undefined || event.value === null) {
this.courseNumber = null;
@ -81,8 +131,7 @@ export class GroupComponent {
this.courseNumber = event.value;
this.groupPanel.open();
this.groups.subscribe(data =>
this.filteredGroups = of(data.filter(g => g.courseNumber === this.courseNumber)));
this.loadCourseGroup();
}
protected chooseGroup(event: MatChipListboxChange) {
@ -90,6 +139,6 @@ export class GroupComponent {
return;
this.groupPanel.close();
this.groupSelected.emit(event.value);
this.eventResult.emit(event.value);
}
}