Files
MireaFrontend/src/components/schedule/table/table.component.ts

130 lines
4.4 KiB
TypeScript

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 {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
import {ScheduleResponse} from "@api/v1/scheduleResponse";
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 {
@Input() currentWeek!: number;
@Input() startWeek!: Date;
@Input() isLoad: boolean = false;
private isDisciplineWithWeeks: boolean = false;
protected tableDataSource: MatTableDataSource<TableData> = new MatTableDataSource<TableData>([]);
private backupDisciplines: string[] = [];
protected daysOfWeek: string[] = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'];
protected displayedColumns: string[] = ['pairNumber'];
protected dataSource: ScheduleResponse[] = [];
@Input() set disciplineWithWeeks(value: boolean) {
this.isDisciplineWithWeeks = value;
this.convertData();
}
@Input() set data(schedule: ScheduleResponse[]) {
this.dataSource = schedule;
this.convertData();
}
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 pairNumber: number = 1; pairNumber <= 7; pairNumber++) {
let convertedData: TableData = {
pairNumber: pairNumber,
data: {}
};
for (let dayOfWeek: number = 1; dayOfWeek < 7; dayOfWeek++) {
let filteredData = this.dataSource.filter(x =>
x.pairNumber === pairNumber &&
x.dayOfWeek === dayOfWeek &&
x.isEven === (this.currentWeek % 2 === 0)
);
if (!this.isDisciplineWithWeeks)
filteredData = filteredData.filter(x =>
x.isExcludedWeeks == undefined ||
x.weeks == undefined ||
x.weeks.length == 0 ||
(x.isExcludedWeeks && !x.weeks.includes(this.currentWeek)) ||
(!x.isExcludedWeeks && x.weeks.includes(this.currentWeek))
);
const groupedData = filteredData.reduce((acc, item) => {
const key = `${item.typeOfOccupations.join(', ')}-${item.lectureHalls}-${item.campus}-${item.discipline}-${item.professors.join(', ')}-${item.isExcludedWeeks}-${item.weeks?.join(', ') || ''}`;
if (!acc[key])
acc[key] = {...item, groups: [item.group]};
else
acc[key].groups.push(item.group);
return acc;
}, {} as { [key: string]: ScheduleResponse & { groups: string[] } });
convertedData.data[dayOfWeek.toString()] = Object.values(groupedData).map(item => {
item.group = item.groups.join(', ');
if (this.isDisciplineWithWeeks && item.weeks !== undefined && item.weeks.length > 0 && item.isExcludedWeeks !== undefined) {
if (this.backupDisciplines[item.disciplineId])
item.discipline = this.backupDisciplines[item.disciplineId];
else
this.backupDisciplines[item.disciplineId] = item.discipline;
item.discipline = `${item.isExcludedWeeks ? 'кр.' : ''} ${item.weeks.sort((x, y) => x - y).join(', ')} н. ${item.discipline}`;
} else if (this.backupDisciplines[item.disciplineId])
item.discipline = this.backupDisciplines[item.disciplineId];
return item;
});
}
tableData.push(convertedData);
}
this.tableDataSource = new MatTableDataSource<TableData>(tableData);
this.isLoad = false;
}
protected checkAvailableData(data: any[] | any): boolean {
return data && data.length !== 0 && (!Array.isArray(data) || data.every(x => x !== null));
}
protected readonly addDays = addDays;
}