refactor: folders and components
This commit is contained in:
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;
|
||||
}
|
Reference in New Issue
Block a user