refactor: folders and components
This commit is contained in:
parent
77845d3a99
commit
afc01c1409
@ -1,6 +1,6 @@
|
|||||||
import {Component} from "@angular/core";
|
import {Component} from "@angular/core";
|
||||||
import {MatList, MatListItem} from "@angular/material/list";
|
import {MatList, MatListItem} from "@angular/material/list";
|
||||||
import {version} from "@/../package.json";
|
import {version} from "../../../../package.json";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-footer',
|
selector: 'app-footer',
|
@ -1,5 +1,5 @@
|
|||||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||||
import {DataSpinnerComponent} from "@component/data-spinner/data-spinner.component";
|
import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
|
||||||
import {MatIcon} from "@angular/material/icon";
|
import {MatIcon} from "@angular/material/icon";
|
||||||
import {MatButton, MatFabButton} from "@angular/material/button";
|
import {MatButton, MatFabButton} from "@angular/material/button";
|
||||||
|
|
54
src/components/schedule/table/table.component.css
Normal file
54
src/components/schedule/table/table.component.css
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
.schedule-table {
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule-table td, .schedule-table th {
|
||||||
|
border-right: 1px solid;
|
||||||
|
border-right-color: var(--mat-table-row-item-outline-color, rgba(0, 0, 0, 0.12));
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule-table tr:nth-child(even) {
|
||||||
|
background-color: color-mix(in srgb, var(--mat-table-background-color), white 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule-table th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-element div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pair-cell {
|
||||||
|
text-align: center;
|
||||||
|
width: 0;
|
||||||
|
min-width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-icon {
|
||||||
|
transform: scale(0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-section {
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 80vh;
|
||||||
|
position: relative
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1001;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
116
src/components/schedule/table/table.component.html
Normal file
116
src/components/schedule/table/table.component.html
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<section class="mat-elevation-z8 table-section" tabindex="0">
|
||||||
|
@if (dataSource.length === 0 || isLoad) {
|
||||||
|
<div class="overlay">
|
||||||
|
@if (isLoad) {
|
||||||
|
<app-data-spinner/>
|
||||||
|
} @else {
|
||||||
|
<p class="mat-h2">Нет данных.</p>
|
||||||
|
<p class="mat-body-2">Выберите необходимое расписание сверху</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<table mat-table [dataSource]="tableDataSource" class="schedule-table size-icon">
|
||||||
|
<!-- Pair Number -->
|
||||||
|
<ng-container matColumnDef="pairNumber" sticky>
|
||||||
|
<th mat-header-cell *matHeaderCellDef style="width: 0; min-width: fit-content;">
|
||||||
|
Пара
|
||||||
|
<!-- Even Or Odd -->
|
||||||
|
<hr/>
|
||||||
|
@if (currentWeek % 2 === 0) {
|
||||||
|
Четная
|
||||||
|
} @else {
|
||||||
|
Нечетная
|
||||||
|
}
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<td mat-cell *matCellDef="let element" class="pair-cell" sticky>
|
||||||
|
{{ element["pairNumber"] }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Day of Week -->
|
||||||
|
@for (day of daysOfWeek; track $index) {
|
||||||
|
<ng-container [matColumnDef]="day">
|
||||||
|
<!-- Day of Week Name -->
|
||||||
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
|
<span class="mat-body-1">
|
||||||
|
{{ day }}
|
||||||
|
</span>
|
||||||
|
<br/>
|
||||||
|
<span class="mat-caption">
|
||||||
|
{{ addDays(startWeek, daysOfWeek.indexOf(day)) | date:"shortDate" }}
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<!-- Info About Pairs -->
|
||||||
|
<td mat-cell *matCellDef="let element" class="table-element">
|
||||||
|
@for (elementData of element.data[daysOfWeek.indexOf(day) + 1]; track $index) {
|
||||||
|
<!-- Discipline -->
|
||||||
|
<div class="mat-body-1">{{ elementData["discipline"] }}</div>
|
||||||
|
<!-- Type of Occupation -->
|
||||||
|
<div class="mat-body">({{ elementData["typeOfOccupation"] }})</div>
|
||||||
|
|
||||||
|
<!-- Professors -->
|
||||||
|
@if (checkAvailableData(elementData["professors"])) {
|
||||||
|
<div class="mat-body">
|
||||||
|
<i>
|
||||||
|
<mat-icon fontIcon="person"/>
|
||||||
|
</i>
|
||||||
|
@for (professor of elementData["professors"]; track $index) {
|
||||||
|
@if ($index !== 0) {
|
||||||
|
<br/>
|
||||||
|
}
|
||||||
|
{{ professor }}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<!-- Address (Lecture Hall & Campus) -->
|
||||||
|
@if (checkAvailableData(elementData["lectureHalls"]) && checkAvailableData(elementData["campus"])) {
|
||||||
|
<div class="mat-body">
|
||||||
|
<i>
|
||||||
|
<mat-icon fontIcon="location_on"/>
|
||||||
|
</i>
|
||||||
|
@for (lectureHall of elementData["lectureHalls"]; track $index) {
|
||||||
|
@if ($index !== 0) {
|
||||||
|
<br/>
|
||||||
|
}
|
||||||
|
@if (lectureHall) {
|
||||||
|
{{ lectureHall }}
|
||||||
|
} @else {
|
||||||
|
N/A
|
||||||
|
}
|
||||||
|
/
|
||||||
|
@if (elementData["campus"][$index]) {
|
||||||
|
{{ elementData["campus"][$index] }}
|
||||||
|
} @else {
|
||||||
|
N/A
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<!-- Group -->
|
||||||
|
@if (!isOneGroup) {
|
||||||
|
<div class="mat-body">
|
||||||
|
<i>
|
||||||
|
<mat-icon fontIcon="group"/>
|
||||||
|
</i>
|
||||||
|
{{ elementData["group"] }}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if ($index + 1 !== element.data[daysOfWeek.indexOf(day) + 1].length) {
|
||||||
|
<hr style="margin: 10px 0;"/>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
}
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
|
</table>
|
||||||
|
</section>
|
89
src/components/schedule/table/table.component.ts
Normal file
89
src/components/schedule/table/table.component.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import {Component, Input, OnChanges} from '@angular/core';
|
||||||
|
import {MatTableDataSource, MatTableModule} from "@angular/material/table";
|
||||||
|
import {MatIcon} from "@angular/material/icon";
|
||||||
|
import {DatePipe} from "@angular/common";
|
||||||
|
import {addDays} from "@progress/kendo-date-math";
|
||||||
|
import {MatDivider} from "@angular/material/divider";
|
||||||
|
import {Schedule} from "@page/schedule/schedule.component";
|
||||||
|
import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
|
||||||
|
|
||||||
|
interface TableData {
|
||||||
|
pairNumber: number;
|
||||||
|
data: Dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Dictionary {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-table',
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
MatTableModule,
|
||||||
|
MatIcon,
|
||||||
|
DatePipe,
|
||||||
|
MatDivider,
|
||||||
|
DataSpinnerComponent
|
||||||
|
],
|
||||||
|
templateUrl: './table.component.html',
|
||||||
|
styleUrl: './table.component.css',
|
||||||
|
})
|
||||||
|
|
||||||
|
export class TableComponent implements OnChanges {
|
||||||
|
protected tableDataSource: MatTableDataSource<TableData> = new MatTableDataSource<TableData>([]);
|
||||||
|
protected daysOfWeek: string[] = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'];
|
||||||
|
protected displayedColumns: string[] = ['pairNumber'];
|
||||||
|
protected dataSource: Schedule[] = [];
|
||||||
|
protected isOneGroup: boolean = false;
|
||||||
|
|
||||||
|
@Input() currentWeek!: number;
|
||||||
|
@Input() startWeek!: Date;
|
||||||
|
@Input() isLoad: boolean = false;
|
||||||
|
|
||||||
|
@Input() set data(schedule: Schedule[]) {
|
||||||
|
this.dataSource = schedule;
|
||||||
|
this.convertData();
|
||||||
|
this.isOneGroup = schedule.every((item, _, array) => item.group === array[0].group);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: any) {
|
||||||
|
if (changes.startWeek && !changes.startWeek.firstChange) {
|
||||||
|
this.convertData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.displayedColumns = this.displayedColumns.concat(this.daysOfWeek);
|
||||||
|
}
|
||||||
|
|
||||||
|
private convertData() {
|
||||||
|
this.isLoad = true;
|
||||||
|
let tableData: TableData[] = [];
|
||||||
|
|
||||||
|
for (let i: number = 1; i <= 7; i++) {
|
||||||
|
let convertedData: TableData = {
|
||||||
|
pairNumber: i,
|
||||||
|
data: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let k: number = 1; k < 7; k++) {
|
||||||
|
convertedData.data[k.toString()] = this.dataSource.filter(x =>
|
||||||
|
x.pairNumber === i
|
||||||
|
&& x.dayOfWeek === k
|
||||||
|
&& x.isEven === (this.currentWeek % 2 === 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
tableData.push(convertedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tableDataSource = new MatTableDataSource<TableData>(tableData);
|
||||||
|
this.isLoad = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected checkAvailableData(data: any[]): boolean {
|
||||||
|
return data && data.length !== 0 && data.every(x => x !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected readonly addDays = addDays;
|
||||||
|
}
|
@ -6,10 +6,10 @@ import {AsyncPipe} from "@angular/common";
|
|||||||
import {map, Observable, of} from "rxjs";
|
import {map, Observable, of} from "rxjs";
|
||||||
import {FacultyResponse} from "@model/facultyResponse";
|
import {FacultyResponse} from "@model/facultyResponse";
|
||||||
import {GroupResponse} from "@model/groupResponse";
|
import {GroupResponse} from "@model/groupResponse";
|
||||||
import {LoadingIndicatorComponent} from "@component/loading-indicator/loading-indicator.component";
|
import {LoadingIndicatorComponent} from "@component/common/loading-indicator/loading-indicator.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-schedule-tabs-group',
|
selector: 'app-group',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
MatExpansionModule,
|
MatExpansionModule,
|
||||||
@ -18,11 +18,11 @@ import {LoadingIndicatorComponent} from "@component/loading-indicator/loading-in
|
|||||||
LoadingIndicatorComponent,
|
LoadingIndicatorComponent,
|
||||||
AsyncPipe
|
AsyncPipe
|
||||||
],
|
],
|
||||||
templateUrl: './schedule-tabs-group.component.html',
|
templateUrl: './group.component.html',
|
||||||
styleUrl: './schedule-tabs-group.component.css'
|
styleUrl: './group.component.css'
|
||||||
})
|
})
|
||||||
|
|
||||||
export class ScheduleTabsGroupComponent {
|
export class GroupComponent {
|
||||||
protected facultyId: number | null = null;
|
protected facultyId: number | null = null;
|
||||||
protected courseNumber: number | null = null;
|
protected courseNumber: number | null = null;
|
||||||
|
|
@ -6,10 +6,10 @@ import {Observable, of} from "rxjs";
|
|||||||
import {CampusBasicInfoResponse} from "@model/campusBasicInfoResponse";
|
import {CampusBasicInfoResponse} from "@model/campusBasicInfoResponse";
|
||||||
import {FormControl, ReactiveFormsModule} from "@angular/forms";
|
import {FormControl, ReactiveFormsModule} from "@angular/forms";
|
||||||
import {LectureHallResponse} from "@model/lectureHallResponse";
|
import {LectureHallResponse} from "@model/lectureHallResponse";
|
||||||
import {LoadingIndicatorComponent} from "@component/loading-indicator/loading-indicator.component";
|
import {LoadingIndicatorComponent} from "@component/common/loading-indicator/loading-indicator.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-schedule-tabs-lecture-hall',
|
selector: 'app-lecture-hall',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
@ -19,10 +19,10 @@ import {LoadingIndicatorComponent} from "@component/loading-indicator/loading-in
|
|||||||
MatAccordion,
|
MatAccordion,
|
||||||
LoadingIndicatorComponent
|
LoadingIndicatorComponent
|
||||||
],
|
],
|
||||||
templateUrl: './schedule-tabs-lecture-hall.component.html',
|
templateUrl: './lecture-hall.component.html',
|
||||||
styleUrl: './schedule-tabs-lecture-hall.component.css'
|
styleUrl: './lecture-hall.component.css'
|
||||||
})
|
})
|
||||||
export class ScheduleTabsLectureHallComponent {
|
export class LectureHallComponent {
|
||||||
protected campusId: number | null = null;
|
protected campusId: number | null = null;
|
||||||
protected chipLecture: FormControl = new FormControl();
|
protected chipLecture: FormControl = new FormControl();
|
||||||
|
|
@ -11,7 +11,7 @@ import {ScrollingModule} from "@angular/cdk/scrolling";
|
|||||||
import {ScrollingModule as ExperimentalScrollingModule} from '@angular/cdk-experimental/scrolling';
|
import {ScrollingModule as ExperimentalScrollingModule} from '@angular/cdk-experimental/scrolling';
|
||||||
import {MatDivider} from "@angular/material/divider";
|
import {MatDivider} from "@angular/material/divider";
|
||||||
import {MatInput} from "@angular/material/input";
|
import {MatInput} from "@angular/material/input";
|
||||||
import {LoadingIndicatorComponent} from "@component/loading-indicator/loading-indicator.component";
|
import {LoadingIndicatorComponent} from "@component/common/loading-indicator/loading-indicator.component";
|
||||||
|
|
||||||
export interface SelectData {
|
export interface SelectData {
|
||||||
id: number,
|
id: number,
|
||||||
@ -20,7 +20,7 @@ export interface SelectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-schedule-tabs-other',
|
selector: 'app-other',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
MatMenuTrigger,
|
MatMenuTrigger,
|
||||||
@ -40,10 +40,10 @@ export interface SelectData {
|
|||||||
ExperimentalScrollingModule,
|
ExperimentalScrollingModule,
|
||||||
LoadingIndicatorComponent
|
LoadingIndicatorComponent
|
||||||
],
|
],
|
||||||
templateUrl: './schedule-tabs-other.component.html',
|
templateUrl: './other.component.html',
|
||||||
styleUrl: './schedule-tabs-other.component.css'
|
styleUrl: './other.component.css'
|
||||||
})
|
})
|
||||||
export class ScheduleTabsOtherComponent {
|
export class OtherComponent {
|
||||||
private _searchQuery: string = '';
|
private _searchQuery: string = '';
|
||||||
protected filteredData: BehaviorSubject<SelectData[]> = new BehaviorSubject<SelectData[]>([]);
|
protected filteredData: BehaviorSubject<SelectData[]> = new BehaviorSubject<SelectData[]>([]);
|
||||||
protected data: SelectData[] = [];
|
protected data: SelectData[] = [];
|
@ -5,10 +5,10 @@ import {MatAutocompleteModule, MatAutocompleteSelectedEvent} from "@angular/mate
|
|||||||
import {AsyncPipe} from "@angular/common";
|
import {AsyncPipe} from "@angular/common";
|
||||||
import {map, Observable, startWith} from "rxjs";
|
import {map, Observable, startWith} from "rxjs";
|
||||||
import {ProfessorResponse} from "@model/professorResponse";
|
import {ProfessorResponse} from "@model/professorResponse";
|
||||||
import {LoadingIndicatorComponent} from "@component/loading-indicator/loading-indicator.component";
|
import {LoadingIndicatorComponent} from "@component/common/loading-indicator/loading-indicator.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-schedule-tabs-professor',
|
selector: 'app-professor',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
MatAutocompleteModule,
|
MatAutocompleteModule,
|
||||||
@ -18,10 +18,10 @@ import {LoadingIndicatorComponent} from "@component/loading-indicator/loading-in
|
|||||||
MatInput,
|
MatInput,
|
||||||
LoadingIndicatorComponent
|
LoadingIndicatorComponent
|
||||||
],
|
],
|
||||||
templateUrl: './schedule-tabs-professor.component.html',
|
templateUrl: './professor.component.html',
|
||||||
styleUrl: './schedule-tabs-professor.component.css'
|
styleUrl: './professor.component.css'
|
||||||
})
|
})
|
||||||
export class ScheduleTabsProfessorComponent implements OnInit {
|
export class ProfessorComponent implements OnInit {
|
||||||
protected professorControl = new FormControl();
|
protected professorControl = new FormControl();
|
||||||
protected filteredProfessors!: Observable<ProfessorResponse[]>;
|
protected filteredProfessors!: Observable<ProfessorResponse[]>;
|
||||||
|
|
14
src/components/schedule/tabs/tabs.component.css
Normal file
14
src/components/schedule/tabs/tabs.component.css
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.padding-content div {
|
||||||
|
padding: 30px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-other-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: space-around;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-other-button app-schedule-tabs-other {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
36
src/components/schedule/tabs/tabs.component.html
Normal file
36
src/components/schedule/tabs/tabs.component.html
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<mat-tab-group dynamicHeight mat-stretch-tabs="false" mat-align-tabs="start" color="accent" class="padding-content"
|
||||||
|
(selectedTabChange)="chooseTabs($event)">
|
||||||
|
<mat-tab label="Группа">
|
||||||
|
<div>
|
||||||
|
<app-group (groupSelected)="groupSelected.emit($event)" (facultySelected)="groupLoad($event)"
|
||||||
|
[setGroups]="groups" [faculties]="faculties" [facultiesLoaded]="facultiesLoaded"
|
||||||
|
[groupsLoaded]="groupLoaded" (groupsLoadRetry)="groupLoad($event)"
|
||||||
|
(facultiesLoadRetry)="facultyLoad()"/>
|
||||||
|
</div>
|
||||||
|
</mat-tab>
|
||||||
|
<mat-tab label="Преподаватель">
|
||||||
|
<div>
|
||||||
|
<app-professor (professorSelected)="professorSelected.emit($event)" [professors]="professorsData" [professorsLoaded]="professorsLoaded" (professorsLoadRetry)="professorsLoad()"/>
|
||||||
|
</div>
|
||||||
|
</mat-tab>
|
||||||
|
<mat-tab label="Кабинет">
|
||||||
|
<div>
|
||||||
|
<app-lecture-hall (lectureHallSelected)="lectureHallSelected.emit($event)" [campuses]="campuses"
|
||||||
|
(campusSelected)="lectureHallLoad($event)" [lectureHalls]="lectureHalls"
|
||||||
|
[campusesLoaded]="campusesLoaded" [lectureHallsLoaded]="lectureHallsLoaded"
|
||||||
|
(campusesLoadRetry)="campusLoad()"
|
||||||
|
(lectureHallsLoadRetry)="lectureHallLoad($event)"/>
|
||||||
|
</div>
|
||||||
|
</mat-tab>
|
||||||
|
<mat-tab label="Другое">
|
||||||
|
<div class="margin-other-button">
|
||||||
|
<app-other idButton="disciplines-button" textButton="Дисциплины" #discipline [dataLoaded]="disciplinesLoaded" (retryLoadData)="loadDisciplines()"/>
|
||||||
|
<app-other idButton="lecture-button" textButton="Кабинеты" #lecture [dataLoaded]="campusesLoaded && lectureHallsLoaded" (retryLoadData)="loadLectureHalls()"/>
|
||||||
|
<app-other idButton="group-button" textButton="Группы" #group [dataLoaded]="facultiesLoaded && groupLoaded" (retryLoadData)="loadGroups()"/>
|
||||||
|
<app-other idButton="professor-button" textButton="Профессоры" #professor [dataLoaded]="professorsLoaded" (retryLoadData)="professorsLoad()"/>
|
||||||
|
<section>
|
||||||
|
<button mat-flat-button (click)="onClickNagmi()">Отфильтровать</button>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</mat-tab>
|
||||||
|
</mat-tab-group>
|
277
src/components/schedule/tabs/tabs.component.ts
Normal file
277
src/components/schedule/tabs/tabs.component.ts
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
import {Component, EventEmitter, Output, ViewChild} from '@angular/core';
|
||||||
|
import {HttpClientModule} from "@angular/common/http";
|
||||||
|
import {ApiService} from '@service/api.service';
|
||||||
|
import {OtherComponent} from "@component/schedule/tabs/other/other.component";
|
||||||
|
import {MatTab, MatTabChangeEvent, MatTabGroup} from "@angular/material/tabs";
|
||||||
|
import {
|
||||||
|
ProfessorComponent
|
||||||
|
} from "@component/schedule/tabs/professor/professor.component";
|
||||||
|
import {GroupComponent} from "@component/schedule/tabs/group/group.component";
|
||||||
|
import {
|
||||||
|
LectureHallComponent
|
||||||
|
} from "@component/schedule/tabs/lecture-hall/lecture-hall.component";
|
||||||
|
import {ProfessorResponse} from "@model/professorResponse";
|
||||||
|
import {catchError, map, Observable, of, switchMap, tap} from "rxjs";
|
||||||
|
import {GroupResponse} from "@model/groupResponse";
|
||||||
|
import {FacultyResponse} from "@model/facultyResponse";
|
||||||
|
import {CampusBasicInfoResponse} from "@model/campusBasicInfoResponse";
|
||||||
|
import {LectureHallResponse} from "@model/lectureHallResponse";
|
||||||
|
import {ReactiveFormsModule} from "@angular/forms";
|
||||||
|
import {AsyncPipe, NgIf} from "@angular/common";
|
||||||
|
import {DisciplineResponse} from "@model/disciplineResponse";
|
||||||
|
import {MatButton} from "@angular/material/button";
|
||||||
|
import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-tabs',
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
HttpClientModule,
|
||||||
|
OtherComponent,
|
||||||
|
MatTabGroup,
|
||||||
|
MatTab,
|
||||||
|
ProfessorComponent,
|
||||||
|
GroupComponent,
|
||||||
|
LectureHallComponent,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
AsyncPipe,
|
||||||
|
NgIf,
|
||||||
|
MatButton,
|
||||||
|
DataSpinnerComponent
|
||||||
|
],
|
||||||
|
templateUrl: './tabs.component.html',
|
||||||
|
styleUrl: './tabs.component.css'
|
||||||
|
})
|
||||||
|
|
||||||
|
export class TabsComponent {
|
||||||
|
protected professorsData: ProfessorResponse[] = [];
|
||||||
|
|
||||||
|
protected faculties: Observable<FacultyResponse[]> = of([]);
|
||||||
|
protected groups: Observable<GroupResponse[]> = of([]);
|
||||||
|
private groupsData: Observable<GroupResponse[]> = of([]);
|
||||||
|
|
||||||
|
protected campuses: Observable<CampusBasicInfoResponse[]> = of([]);
|
||||||
|
protected lectureHalls: Observable<LectureHallResponse[]> = of([]);
|
||||||
|
private lectureHallsData: Observable<LectureHallResponse[]> = 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<number> = new EventEmitter<number>();
|
||||||
|
@Output() lectureHallSelected: EventEmitter<number> = new EventEmitter<number>();
|
||||||
|
@Output() professorSelected: EventEmitter<number> = new EventEmitter<number>();
|
||||||
|
|
||||||
|
constructor(private api: ApiService) {
|
||||||
|
this.facultyLoad().then();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async chooseTabs(event: MatTabChangeEvent) {
|
||||||
|
console.log(event);
|
||||||
|
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.api.get<FacultyResponse[]>("Faculty/Get").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.api.get<GroupResponse[]>("Group/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.api.get<ProfessorResponse[]>("Professor/Get").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.api.get<CampusBasicInfoResponse[]>("Campus/Get").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.api.get<LectureHallResponse[]>("LectureHall/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.api.get<LectureHallResponse[]>("LectureHall/Get");
|
||||||
|
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.api.get<DisciplineResponse[]>("Discipline/Get").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.api.get<GroupResponse[]>("Group/Get");
|
||||||
|
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;
|
||||||
|
|
||||||
|
onClickNagmi() {
|
||||||
|
console.log('huy = ' + this.disciplineEx.selectedIds);
|
||||||
|
console.log('huy2 = ' + this.lectureHallEx.selectedIds);
|
||||||
|
console.log('huy3 = ' + this.groupEx.selectedIds);
|
||||||
|
console.log('huy3 = ' + this.professorEx.selectedIds);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user