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 = new MatTableDataSource([]); 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); 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; }