Compare commits
8 Commits
49179d2a8a
...
b341d66f08
Author | SHA1 | Date | |
---|---|---|---|
b341d66f08 | |||
79393a39c3 | |||
60218a73f2 | |||
42e454c4d6 | |||
c6059a7a60 | |||
6a3a6a8d47 | |||
1fa1e864da | |||
fc828f3008 |
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"version": "1.0.0-b3",
|
||||
"version": "1.0.0-b4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "frontend",
|
||||
"version": "1.0.0-b3",
|
||||
"version": "1.0.0-b4",
|
||||
"dependencies": {
|
||||
"@angular/animations": "^18.2.1",
|
||||
"@angular/cdk": "~18.2.1",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"version": "1.0.0-b3",
|
||||
"version": "1.0.0-b4",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
|
@ -1,3 +1,4 @@
|
||||
<mat-toolbar style="justify-content: space-between;">
|
||||
<a href="/" style="color: inherit;">Winsomnia</a>
|
||||
<a href="/admin" style="color: inherit; font-size: 14px" *appHasRole="AuthRoles.Admin">Админ панель</a>
|
||||
</mat-toolbar>
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
import {MatToolbar} from "@angular/material/toolbar";
|
||||
import {MatAnchor, MatButton} from "@angular/material/button";
|
||||
import {HasRoleDirective} from "@/directives/has-role.directive";
|
||||
import {AuthRoles} from "@model/AuthRoles";
|
||||
|
||||
@Component({
|
||||
selector: 'app-header',
|
||||
@ -8,11 +10,13 @@ import {MatAnchor, MatButton} from "@angular/material/button";
|
||||
imports: [
|
||||
MatToolbar,
|
||||
MatButton,
|
||||
MatAnchor
|
||||
MatAnchor,
|
||||
HasRoleDirective
|
||||
],
|
||||
templateUrl: './header.component.html',
|
||||
styleUrl: './header.component.css'
|
||||
})
|
||||
export class HeaderComponent {
|
||||
|
||||
protected readonly AuthRoles = AuthRoles;
|
||||
}
|
||||
|
@ -1,81 +0,0 @@
|
||||
import {MatChipListbox} from "@angular/material/chips";
|
||||
|
||||
export class TabSelect {
|
||||
public index: number;
|
||||
public name: string;
|
||||
|
||||
constructor(index: number, name: string) {
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
export enum TabSelectType {
|
||||
group,
|
||||
professor,
|
||||
lecture,
|
||||
other
|
||||
}
|
||||
|
||||
export interface TabSelectData {
|
||||
selected: TabSelect[] | null;
|
||||
type: TabSelectType;
|
||||
}
|
||||
|
||||
export class TabStorageComponent {
|
||||
private static dataName = 'tabSelectedData';
|
||||
|
||||
public static trySelectChip(index: number, chip: MatChipListbox, tryCount: number = 0) {
|
||||
setTimeout(() => {
|
||||
if (chip?._chips !== undefined && chip._chips.length !== 0) {
|
||||
let selected = chip._chips.find(x => x.value == index.toString());
|
||||
if (selected !== undefined) {
|
||||
selected.select();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (tryCount >= 10)
|
||||
return;
|
||||
|
||||
this.trySelectChip(index, chip, ++tryCount);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
public static select(selected: TabSelect, type: TabSelectType, index: number) {
|
||||
let selectedData = this.selected;
|
||||
|
||||
if (selectedData === null)
|
||||
selectedData = {} as TabSelectData;
|
||||
|
||||
if (selectedData.type !== type || selectedData.selected === null || selectedData.selected.length === 0) {
|
||||
if (index !== 0)
|
||||
return;
|
||||
else
|
||||
selectedData.selected = [selected];
|
||||
} else {
|
||||
if (selectedData.selected.length < index)
|
||||
return;
|
||||
|
||||
if (selectedData.selected.length - 1 === index)
|
||||
selectedData.selected[index] = selected;
|
||||
else if (selectedData.selected.length > index + 1)
|
||||
selectedData.selected = selectedData.selected.slice(0, index + 1);
|
||||
else
|
||||
selectedData.selected.push(selected);
|
||||
}
|
||||
|
||||
selectedData.type = type;
|
||||
|
||||
localStorage.setItem(this.dataName, JSON.stringify(selectedData));
|
||||
}
|
||||
|
||||
public static get selected(): TabSelectData | null {
|
||||
let data = localStorage.getItem(this.dataName);
|
||||
|
||||
if (data === null)
|
||||
return null;
|
||||
|
||||
return JSON.parse(data) as TabSelectData;
|
||||
}
|
||||
}
|
@ -31,7 +31,9 @@ interface Dictionary {
|
||||
})
|
||||
|
||||
export class TableComponent implements OnChanges {
|
||||
private isDisciplineWithWeeks: boolean = false;
|
||||
protected tableDataSource: MatTableDataSource<TableData> = new MatTableDataSource<TableData>([]);
|
||||
private backupDisciplines: string[] = [];
|
||||
protected daysOfWeek: string[] = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'];
|
||||
protected displayedColumns: string[] = ['pairNumber'];
|
||||
protected dataSource: ScheduleResponse[] = [];
|
||||
@ -41,6 +43,11 @@ export class TableComponent implements OnChanges {
|
||||
@Input() startWeek!: Date;
|
||||
@Input() isLoad: boolean = false;
|
||||
|
||||
@Input() set disciplineWithWeeks(value: boolean) {
|
||||
this.isDisciplineWithWeeks = value;
|
||||
this.convertData();
|
||||
}
|
||||
|
||||
@Input() set data(schedule: ScheduleResponse[]) {
|
||||
this.dataSource = schedule;
|
||||
this.convertData();
|
||||
@ -68,14 +75,35 @@ export class TableComponent implements OnChanges {
|
||||
};
|
||||
|
||||
for (let k: number = 1; k < 7; k++) {
|
||||
convertedData.data[k.toString()] = this.dataSource.filter(x =>
|
||||
let filteredData = this.dataSource.filter(x =>
|
||||
x.pairNumber === i &&
|
||||
x.dayOfWeek === k &&
|
||||
x.isEven === (this.currentWeek % 2 === 0) &&
|
||||
(
|
||||
(x.isExcludedWeeks && (!x.weeks || !x.weeks.includes(this.currentWeek))) ||
|
||||
(!x.isExcludedWeeks && (!x.weeks || x.weeks.includes(this.currentWeek)))
|
||||
));
|
||||
x.isEven === (this.currentWeek % 2 === 0)
|
||||
);
|
||||
|
||||
if (!this.isDisciplineWithWeeks)
|
||||
filteredData = filteredData.filter(x =>
|
||||
x.isExcludedWeeks == undefined ||
|
||||
x.weeks == undefined ||
|
||||
(x.isExcludedWeeks && (!x.weeks.includes(this.currentWeek))) ||
|
||||
(!x.isExcludedWeeks && (x.weeks.includes(this.currentWeek)))
|
||||
);
|
||||
|
||||
filteredData.forEach(x => {
|
||||
if (this.isDisciplineWithWeeks) {
|
||||
if (x.isExcludedWeeks != undefined && x.weeks != undefined) {
|
||||
if (this.backupDisciplines[x.disciplineId])
|
||||
x.discipline = this.backupDisciplines[x.disciplineId];
|
||||
else
|
||||
this.backupDisciplines[x.disciplineId] = x.discipline;
|
||||
|
||||
x.discipline = `${(x.isExcludedWeeks ? 'кр.' : 'н.')} ${x.weeks.join(', ')} ${x.discipline}`;
|
||||
}
|
||||
} else if (this.backupDisciplines[x.disciplineId])
|
||||
x.discipline = this.backupDisciplines[x.disciplineId];
|
||||
});
|
||||
|
||||
convertedData.data[k.toString()] = filteredData;
|
||||
}
|
||||
|
||||
tableData.push(convertedData);
|
||||
|
@ -9,11 +9,7 @@ import {FacultyResponse} from "@api/v1/facultyResponse";
|
||||
import {FacultyService} from "@api/v1/faculty.service";
|
||||
import {GroupService} from "@api/v1/group.service";
|
||||
import {IScheduleTab} from "@component/schedule/tabs/ischedule-tab";
|
||||
import {
|
||||
TabSelect,
|
||||
TabSelectType,
|
||||
TabStorageComponent
|
||||
} from "@component/common/tab-storage/tab-storage.component";
|
||||
import {TabSelect, TabSelectData, TabSelectType, TabStorageService} from "@service/tab-storage.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-group',
|
||||
@ -49,20 +45,17 @@ export class GroupComponent implements IScheduleTab {
|
||||
@ViewChild('courseChip') courseChip!: MatChipListbox;
|
||||
@ViewChild('groupChip') groupChip!: MatChipListbox;
|
||||
|
||||
private readonly selected: TabSelect[] | null = null;
|
||||
|
||||
@ViewChild('facultyIndicator') facultyIndicator!: LoadingIndicatorComponent;
|
||||
@ViewChild('courseIndicator') courseIndicator!: LoadingIndicatorComponent;
|
||||
@ViewChild('groupIndicator') groupIndicator!: LoadingIndicatorComponent;
|
||||
|
||||
@Output() eventResult = new EventEmitter<number>();
|
||||
|
||||
constructor(private facultyApi: FacultyService, private groupApi: GroupService) {
|
||||
let selectedData = TabStorageComponent.selected;
|
||||
if (selectedData !== null && selectedData.selected !== null) {
|
||||
if (selectedData.type === TabSelectType.group)
|
||||
this.selected = selectedData.selected;
|
||||
constructor(private facultyApi: FacultyService, private groupApi: GroupService, private tabStorage: TabStorageService) {
|
||||
}
|
||||
|
||||
existParams(data: TabSelectData): boolean {
|
||||
return data.selected['group'] !== undefined || data.selected['course'] !== undefined || data.selected['faculty'] !== undefined;
|
||||
}
|
||||
|
||||
protected loadFaculties() {
|
||||
@ -73,14 +66,16 @@ export class GroupComponent implements IScheduleTab {
|
||||
}))
|
||||
.subscribe(data => {
|
||||
this.faculties = data;
|
||||
if (this.selected !== null && this.selected.length >= 1) {
|
||||
let selectedFaculty = data.find(x => x.id === this.selected![0].index);
|
||||
|
||||
if (selectedFaculty === undefined || selectedFaculty.name !== this.selected[0].name)
|
||||
selectedFaculty = data.find(x => x.name === this.selected![0].name);
|
||||
let selected = TabStorageService.selected?.selected['faculty'];
|
||||
if (selected) {
|
||||
let selectedFaculty = data.find(x => x.id === selected.index);
|
||||
|
||||
if (selectedFaculty === undefined || selectedFaculty.name !== selected.name)
|
||||
selectedFaculty = data.find(x => x.name === selected.name);
|
||||
|
||||
if (selectedFaculty !== undefined) {
|
||||
TabStorageComponent.trySelectChip(selectedFaculty.id, this.facultyChip);
|
||||
TabStorageService.trySelectChip(selectedFaculty.id, this.facultyChip);
|
||||
this.onFacultySelected(selectedFaculty.id);
|
||||
}
|
||||
}
|
||||
@ -107,23 +102,28 @@ export class GroupComponent implements IScheduleTab {
|
||||
.sort((a, b) => a - b))
|
||||
);
|
||||
|
||||
if (this.selected !== null && this.selected.length >= 2) {
|
||||
let selectedCourse = this.courseNumbers.find(x => x === this.selected![1].index);
|
||||
let selected = TabStorageService.selected?.selected['course'];
|
||||
if (selected) {
|
||||
let selectedCourse = this.courseNumbers.find(x => x === selected.index);
|
||||
|
||||
if (selectedCourse === undefined)
|
||||
selectedCourse = this.courseNumbers.find(x => x.toString() === selected.name);
|
||||
|
||||
if (selectedCourse !== undefined) {
|
||||
TabStorageComponent.trySelectChip(selectedCourse, this.courseChip);
|
||||
TabStorageService.trySelectChip(selectedCourse, this.courseChip);
|
||||
this.onCourseSelected(selectedCourse);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.selected !== null && this.selected.length >= 3) {
|
||||
let selectedGroup = data.find(x => x.id === this.selected![2].index);
|
||||
let selectedGroupStorage = TabStorageService.selected?.selected['group'];
|
||||
if (selectedGroupStorage) {
|
||||
let selectedGroup = data.find(x => x.id === selectedGroupStorage.index);
|
||||
|
||||
if (selectedGroup === undefined || selectedGroup.name !== this.selected[2].name)
|
||||
selectedGroup = data.find(x => x.name === this.selected![2].name);
|
||||
if (selectedGroup === undefined || selectedGroup.name !== selectedGroupStorage.name)
|
||||
selectedGroup = data.find(x => x.name === selectedGroupStorage.name);
|
||||
|
||||
if (selectedGroup !== undefined) {
|
||||
TabStorageComponent.trySelectChip(selectedGroup.id, this.groupChip);
|
||||
TabStorageService.trySelectChip(selectedGroup.id, this.groupChip);
|
||||
this.onGroupSelected(selectedGroup.id);
|
||||
}
|
||||
}
|
||||
@ -147,7 +147,7 @@ export class GroupComponent implements IScheduleTab {
|
||||
return;
|
||||
}
|
||||
|
||||
TabStorageComponent.select(new TabSelect(index, this.faculties!.find(x => x.id === index)?.name ?? ''), TabSelectType.group, 0);
|
||||
this.tabStorage.select(new TabSelect(index, this.faculties!.find(x => x.id === index)?.name ?? ''), TabSelectType.group, 'faculty');
|
||||
|
||||
this.facultyId = index;
|
||||
this.courseNumberPanel.open();
|
||||
@ -164,7 +164,7 @@ export class GroupComponent implements IScheduleTab {
|
||||
return;
|
||||
}
|
||||
|
||||
TabStorageComponent.select(new TabSelect(course, course.toString()), TabSelectType.group, 1);
|
||||
this.tabStorage.select(new TabSelect(course, course.toString()), TabSelectType.group, 'course');
|
||||
|
||||
this.courseNumber = course;
|
||||
this.groupPanel.open();
|
||||
@ -175,7 +175,7 @@ export class GroupComponent implements IScheduleTab {
|
||||
if (index === undefined)
|
||||
return;
|
||||
|
||||
TabStorageComponent.select(new TabSelect(index, this.groups!.find(x => x.id == index)?.name ?? ''), TabSelectType.group, 2);
|
||||
this.tabStorage.select(new TabSelect(index, this.groups!.find(x => x.id == index)?.name ?? ''), TabSelectType.group, 'group');
|
||||
|
||||
this.groupPanel.close();
|
||||
this.eventResult.emit(index);
|
||||
|
@ -1,6 +1,8 @@
|
||||
import {EventEmitter} from "@angular/core";
|
||||
import {TabSelectData} from "@service/tab-storage.service";
|
||||
|
||||
export interface IScheduleTab {
|
||||
load(): void;
|
||||
eventResult: EventEmitter<number>;
|
||||
existParams(data: TabSelectData): boolean;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import {LectureHallResponse} from "@api/v1/lectureHallResponse";
|
||||
import {CampusService} from "@api/v1/campus.service";
|
||||
import {LectureHallService} from "@api/v1/lectureHall.service";
|
||||
import {IScheduleTab} from "@component/schedule/tabs/ischedule-tab";
|
||||
import {TabSelect, TabSelectType, TabStorageComponent} from "@component/common/tab-storage/tab-storage.component";
|
||||
import {TabSelect, TabSelectData, TabSelectType, TabStorageService} from "@service/tab-storage.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-lecture-hall',
|
||||
@ -45,14 +45,12 @@ export class LectureHallComponent implements IScheduleTab {
|
||||
@ViewChild('lectureChip') lectureChip!: MatChipListbox;
|
||||
|
||||
private lectureHalls: LectureHallResponse[] | null = null;
|
||||
private readonly selected: TabSelect[] | null = null;
|
||||
|
||||
constructor(private campusApi: CampusService, private lectureHallApi: LectureHallService) {
|
||||
let selectedData = TabStorageComponent.selected;
|
||||
if (selectedData !== null && selectedData.selected !== null) {
|
||||
if (selectedData.type === TabSelectType.lecture)
|
||||
this.selected = selectedData.selected;
|
||||
constructor(private campusApi: CampusService, private lectureHallApi: LectureHallService, private tabStorage: TabStorageService) {
|
||||
}
|
||||
|
||||
existParams(data: TabSelectData): boolean {
|
||||
return data.selected['campus'] !== undefined || data.selected['lecture'] !== undefined;
|
||||
}
|
||||
|
||||
protected loadCampuses() {
|
||||
@ -64,14 +62,15 @@ export class LectureHallComponent implements IScheduleTab {
|
||||
.subscribe(data => {
|
||||
this.campuses = data;
|
||||
|
||||
if (this.selected !== null && this.selected.length >= 1) {
|
||||
let selectedCampus = data.find(x => x.id === this.selected![0].index);
|
||||
let selected = TabStorageService.selected?.selected['campus'];
|
||||
if (selected) {
|
||||
let selectedCampus = data.find(x => x.id === selected.index);
|
||||
|
||||
if (selectedCampus === undefined || selectedCampus.codeName !== this.selected![0].name)
|
||||
selectedCampus = data.find(x => x.codeName === this.selected![0].name);
|
||||
if (selectedCampus === undefined || selectedCampus.codeName !== selected.name)
|
||||
selectedCampus = data.find(x => x.codeName === selected.name);
|
||||
|
||||
if (selectedCampus !== undefined) {
|
||||
TabStorageComponent.trySelectChip(selectedCampus.id, this.campusChip);
|
||||
TabStorageService.trySelectChip(selectedCampus.id, this.campusChip);
|
||||
this.onCampusSelected(selectedCampus.id);
|
||||
}
|
||||
}
|
||||
@ -85,7 +84,7 @@ export class LectureHallComponent implements IScheduleTab {
|
||||
protected onCampusSelected(index: number) {
|
||||
this.formLectureHalls.reset();
|
||||
|
||||
TabStorageComponent.select(new TabSelect(index, this.campuses!.find(x => x.id === index)?.codeName ?? ''), TabSelectType.lecture, 0);
|
||||
this.tabStorage.select(new TabSelect(index, this.campuses!.find(x => x.id === index)?.codeName ?? ''), TabSelectType.lecture, 'campus');
|
||||
|
||||
if (index === undefined) {
|
||||
this.campusId = null;
|
||||
@ -111,14 +110,16 @@ export class LectureHallComponent implements IScheduleTab {
|
||||
.subscribe(data => {
|
||||
this.lectureHalls = data;
|
||||
this.filteringLectureHalls();
|
||||
if (this.selected !== null && this.selected.length >= 2) {
|
||||
let selectedLecture = data.find(x => x.id === this.selected![1].index);
|
||||
|
||||
if (selectedLecture === undefined || selectedLecture.name !== this.selected![1].name)
|
||||
selectedLecture = data.find(x => x.name === this.selected![1].name);
|
||||
let selected = TabStorageService.selected?.selected['lecture'];
|
||||
if (selected) {
|
||||
let selectedLecture = data.find(x => x.id === selected.index);
|
||||
|
||||
if (selectedLecture === undefined || selectedLecture.name !== selected.name)
|
||||
selectedLecture = data.find(x => x.name === selected.name);
|
||||
|
||||
if (selectedLecture !== undefined) {
|
||||
TabStorageComponent.trySelectChip(selectedLecture.id, this.lectureChip);
|
||||
TabStorageService.trySelectChip(selectedLecture.id, this.lectureChip);
|
||||
this.onLectureHallSelected(selectedLecture.id);
|
||||
}
|
||||
}
|
||||
@ -129,7 +130,7 @@ export class LectureHallComponent implements IScheduleTab {
|
||||
if (index === undefined)
|
||||
return;
|
||||
|
||||
TabStorageComponent.select(new TabSelect(index, this.lectureHallsFiltered!.find(x => x.id === index)?.name ?? ''), TabSelectType.lecture, 1);
|
||||
this.tabStorage.select(new TabSelect(index, this.lectureHallsFiltered!.find(x => x.id === index)?.name ?? ''), TabSelectType.lecture, 'lecture');
|
||||
|
||||
this.lecturePanel.close();
|
||||
this.eventResult.emit(index);
|
||||
|
@ -8,7 +8,7 @@ import {LoadingIndicatorComponent} from "@component/common/loading-indicator/loa
|
||||
import {ProfessorResponse} from "@api/v1/professorResponse";
|
||||
import {ProfessorService} from "@api/v1/professor.service";
|
||||
import {IScheduleTab} from "@component/schedule/tabs/ischedule-tab";
|
||||
import {TabSelect, TabSelectType, TabStorageComponent} from "@component/common/tab-storage/tab-storage.component";
|
||||
import {TabSelect, TabSelectData, TabSelectType, TabStorageService} from "@service/tab-storage.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-professor',
|
||||
@ -30,18 +30,16 @@ export class ProfessorComponent implements OnInit, IScheduleTab {
|
||||
protected filteredProfessors!: Observable<ProfessorResponse[]>;
|
||||
|
||||
protected professors: ProfessorResponse[] | null = null;
|
||||
private readonly selected: TabSelect[] | null = null;
|
||||
|
||||
@ViewChild('professorIndicator') professorIndicator!: LoadingIndicatorComponent;
|
||||
|
||||
@Output() eventResult = new EventEmitter<number>();
|
||||
|
||||
constructor(private api: ProfessorService) {
|
||||
let selectedData = TabStorageComponent.selected;
|
||||
if (selectedData !== null && selectedData.selected !== null) {
|
||||
if (selectedData.type === TabSelectType.professor)
|
||||
this.selected = selectedData.selected;
|
||||
constructor(private api: ProfessorService, private tabStorage: TabStorageService) {
|
||||
}
|
||||
|
||||
existParams(data: TabSelectData): boolean {
|
||||
return data.selected['professor'] !== undefined;
|
||||
}
|
||||
|
||||
protected loadProfessors() {
|
||||
@ -54,11 +52,12 @@ export class ProfessorComponent implements OnInit, IScheduleTab {
|
||||
.subscribe(data => {
|
||||
this.professors = data;
|
||||
|
||||
if (this.selected !== null && this.selected.length >= 1) {
|
||||
let selectedProfessor = data.find(x => x.id === this.selected![0].index);
|
||||
let selected = TabStorageService.selected?.selected['professor'];
|
||||
if (selected) {
|
||||
let selectedProfessor = data.find(x => x.id === selected.index);
|
||||
|
||||
if (selectedProfessor === undefined || selectedProfessor.name !== this.selected[0].name)
|
||||
selectedProfessor = data.find(x => x.name === this.selected![0].name);
|
||||
if (selectedProfessor === undefined || selectedProfessor.name !== selected.name)
|
||||
selectedProfessor = data.find(x => x.name === selected.name);
|
||||
|
||||
if (selectedProfessor !== undefined)
|
||||
this.onOptionSelected(selectedProfessor.id);
|
||||
@ -96,7 +95,7 @@ export class ProfessorComponent implements OnInit, IScheduleTab {
|
||||
this.professorControl.setValue(selectedOption.name);
|
||||
this.eventResult.emit(selectedOption.id);
|
||||
|
||||
TabStorageComponent.select(new TabSelect(selectedOption.id, selectedOption.name), TabSelectType.professor, 0);
|
||||
this.tabStorage.select(new TabSelect(selectedOption.id, selectedOption.name), TabSelectType.professor, 'professor');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
.padding-content div {
|
||||
padding: 30px 15px;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.margin-other-button {
|
||||
|
@ -17,7 +17,7 @@ import {GroupService} from "@api/v1/group.service";
|
||||
import {ProfessorService} from "@api/v1/professor.service";
|
||||
import {AuthRoles} from "@model/AuthRoles";
|
||||
import {HasRoleDirective} from "@/directives/has-role.directive";
|
||||
import {TabStorageComponent} from "@component/common/tab-storage/tab-storage.component";
|
||||
import {TabStorageService} from "@service/tab-storage.service";
|
||||
|
||||
export enum TabsSelect {
|
||||
Group,
|
||||
@ -44,7 +44,7 @@ export enum TabsSelect {
|
||||
],
|
||||
templateUrl: './tabs.component.html',
|
||||
styleUrl: './tabs.component.css',
|
||||
providers: [ScheduleService, DisciplineService, LectureHallService, GroupService, ProfessorService]
|
||||
providers: [ScheduleService, DisciplineService, LectureHallService, GroupService, ProfessorService, TabStorageService]
|
||||
})
|
||||
|
||||
export class TabsComponent implements AfterViewInit {
|
||||
@ -58,13 +58,25 @@ export class TabsComponent implements AfterViewInit {
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
let selected = TabStorageComponent.selected;
|
||||
let selected = TabStorageService.selected;
|
||||
|
||||
let index = 0;
|
||||
if (selected !== null)
|
||||
index = selected.type;
|
||||
|
||||
this.chooseTabs(index).then();
|
||||
if (selected !== null) {
|
||||
if (selected.type === null) {
|
||||
if (this.groupTab.existParams(selected))
|
||||
index = 0;
|
||||
else if (this.professorTab.existParams(selected))
|
||||
index = 1;
|
||||
else if (this.lectureHallTab.existParams(selected))
|
||||
index = 2;
|
||||
} else
|
||||
index = selected.type;
|
||||
}
|
||||
|
||||
if (index === null || index === 0)
|
||||
this.chooseTabs(0).then();
|
||||
else
|
||||
this.tabs.selectedIndex = index;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,12 @@
|
||||
.schedule {
|
||||
padding: 50px 15%;
|
||||
min-height: 60vh;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.schedule mat-sidenav-content {
|
||||
overflow: inherit;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 599px) {
|
||||
|
@ -1,6 +1,18 @@
|
||||
<mat-sidenav-container class="schedule">
|
||||
<mat-sidenav-content>
|
||||
<app-tabs (eventResult)="result($event)"/>
|
||||
</mat-sidenav-content>
|
||||
|
||||
<mat-sidenav-content>
|
||||
<app-table-header [startWeek]="startWeek" [currentWeek]="currentWeek" (weekEvent)="handleWeekEvent($event)"
|
||||
#tableHeader/>
|
||||
<app-table [currentWeek]="currentWeek" [startWeek]="startWeek" [data]="data" [isLoad]="isLoadTable"/>
|
||||
</mat-sidenav-content>
|
||||
|
||||
<mat-sidenav-content>
|
||||
<app-table [currentWeek]="currentWeek" [startWeek]="startWeek" [data]="data" [isLoad]="isLoadTable" [disciplineWithWeeks]="disciplineWithWeeks"/>
|
||||
</mat-sidenav-content>
|
||||
|
||||
<mat-sidenav-content>
|
||||
<mat-checkbox (change)="changeDisciplineWeeksView($event.checked)" [checked]="disciplineWithWeeks">Показать недели в дисциплине</mat-checkbox>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Component, LOCALE_ID, ViewChild} from '@angular/core';
|
||||
import {Component, LOCALE_ID, OnInit, ViewChild} from '@angular/core';
|
||||
import {TableComponent} from "@component/schedule/table/table.component";
|
||||
import {MatFormField, MatInput} from "@angular/material/input";
|
||||
import {MatButton} from "@angular/material/button";
|
||||
@ -6,12 +6,15 @@ import {FormsModule} from "@angular/forms";
|
||||
import {AdditionalText, TableHeaderComponent} from "@component/schedule/table-header/table-header.component";
|
||||
import {addDays, weekInYear} from "@progress/kendo-date-math";
|
||||
import {MatCard} from "@angular/material/card";
|
||||
import {MatSidenavContainer} from "@angular/material/sidenav";
|
||||
import {MatSidenavModule} from "@angular/material/sidenav";
|
||||
import {TabsComponent, TabsSelect} from "@component/schedule/tabs/tabs.component";
|
||||
import {catchError, Observable} from "rxjs";
|
||||
import {ScheduleService} from "@api/v1/schedule.service";
|
||||
import {ScheduleResponse} from "@api/v1/scheduleResponse";
|
||||
import {PeriodTimes} from "@model/pairPeriodTime";
|
||||
import {MatCheckbox} from "@angular/material/checkbox";
|
||||
import {ActivatedRoute} from "@angular/router";
|
||||
import {TabStorageService} from "@service/tab-storage.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-schedule',
|
||||
@ -24,8 +27,9 @@ import {PeriodTimes} from "@model/pairPeriodTime";
|
||||
FormsModule,
|
||||
TableHeaderComponent,
|
||||
MatCard,
|
||||
MatSidenavContainer,
|
||||
TabsComponent
|
||||
MatSidenavModule,
|
||||
TabsComponent,
|
||||
MatCheckbox
|
||||
],
|
||||
templateUrl: './schedule.component.html',
|
||||
styleUrl: './schedule.component.css',
|
||||
@ -35,19 +39,29 @@ import {PeriodTimes} from "@model/pairPeriodTime";
|
||||
]
|
||||
})
|
||||
|
||||
export class ScheduleComponent {
|
||||
protected startWeek!: Date;
|
||||
export class ScheduleComponent implements OnInit {
|
||||
protected startWeek: Date;
|
||||
protected data: ScheduleResponse[] = [];
|
||||
protected startTerm: Date;
|
||||
protected isLoadTable: boolean = false;
|
||||
protected pairPeriods: PeriodTimes = {};
|
||||
protected disciplineWithWeeks: boolean = false;
|
||||
|
||||
@ViewChild('tableHeader') childComponent!: TableHeaderComponent;
|
||||
|
||||
constructor(api: ScheduleService) {
|
||||
constructor(api: ScheduleService, route: ActivatedRoute) {
|
||||
route.queryParams.subscribe(params => {
|
||||
TabStorageService.selectDataFromQuery(params);
|
||||
});
|
||||
|
||||
this.startTerm = new Date(1, 1, 1);
|
||||
this.startWeek = new Date(1, 1, 1);
|
||||
|
||||
let disciplineWithWeeksStorage = localStorage.getItem('disciplineWithWeeks');
|
||||
|
||||
if (disciplineWithWeeksStorage)
|
||||
this.disciplineWithWeeks = disciplineWithWeeksStorage.toLowerCase() === 'true';
|
||||
|
||||
api.pairPeriod().subscribe(date => {
|
||||
this.pairPeriods = date;
|
||||
});
|
||||
@ -57,6 +71,9 @@ export class ScheduleComponent {
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
protected result(data: [TabsSelect, number, Observable<ScheduleResponse[]>]) {
|
||||
this.isLoadTable = true;
|
||||
data[2]
|
||||
@ -120,4 +137,9 @@ export class ScheduleComponent {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected changeDisciplineWeeksView(checked: boolean) {
|
||||
localStorage.setItem('disciplineWithWeeks', checked.toString());
|
||||
this.disciplineWithWeeks = checked;
|
||||
}
|
||||
}
|
||||
|
113
src/services/tab-storage.service.ts
Normal file
113
src/services/tab-storage.service.ts
Normal file
@ -0,0 +1,113 @@
|
||||
import {MatChipListbox} from "@angular/material/chips";
|
||||
import {Injectable} from "@angular/core";
|
||||
import {Params, Router} from "@angular/router";
|
||||
import {Location} from '@angular/common';
|
||||
|
||||
export class TabSelect {
|
||||
public index: number;
|
||||
public name: string;
|
||||
|
||||
constructor(index: number, name: string) {
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
export enum TabSelectType {
|
||||
group,
|
||||
professor,
|
||||
lecture,
|
||||
other
|
||||
}
|
||||
|
||||
export interface TabSelectData {
|
||||
selected: { [key: string]: TabSelect };
|
||||
type: TabSelectType | null;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class TabStorageService {
|
||||
private static dataName = 'tabSelectedData';
|
||||
|
||||
constructor(private router: Router, private location: Location) {
|
||||
}
|
||||
|
||||
public static trySelectChip(index: number, chip: MatChipListbox, tryCount: number = 0) {
|
||||
setTimeout(() => {
|
||||
if (chip?._chips !== undefined && chip._chips.length !== 0) {
|
||||
let selected = chip._chips.find(x => x.value == index.toString());
|
||||
if (selected !== undefined) {
|
||||
selected.select();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (tryCount < 10)
|
||||
this.trySelectChip(index, chip, ++tryCount);
|
||||
else
|
||||
return;
|
||||
|
||||
}, 100);
|
||||
}
|
||||
|
||||
private resetIfNeed(type: TabSelectType) {
|
||||
let selectedData = TabStorageService.selected;
|
||||
|
||||
if (selectedData === null || selectedData?.type === null)
|
||||
return;
|
||||
|
||||
if (selectedData.type !== type) {
|
||||
localStorage.removeItem(TabStorageService.dataName);
|
||||
const currentUrl = this.router.url.split('?')[0];
|
||||
this.location.replaceState(currentUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public select(selected: TabSelect, type: TabSelectType, navigateName: string) {
|
||||
this.resetIfNeed(type);
|
||||
let selectedData = TabStorageService.selected;
|
||||
|
||||
if (selectedData === null || !selectedData.selected)
|
||||
selectedData = {selected: {}} as TabSelectData;
|
||||
|
||||
selectedData.selected[navigateName] = selected;
|
||||
selectedData.type = type;
|
||||
|
||||
localStorage.setItem(TabStorageService.dataName, JSON.stringify(selectedData));
|
||||
|
||||
const currentUrl = this.router.url.split('?')[0];
|
||||
|
||||
const queryParam = new URLSearchParams();
|
||||
for (let select in selectedData.selected)
|
||||
queryParam.set(select, selectedData.selected[select].name);
|
||||
|
||||
this.location.replaceState(currentUrl, queryParam.toString());
|
||||
}
|
||||
|
||||
public static selectDataFromQuery(query: Params) {
|
||||
if (Object.keys(query).length === 0)
|
||||
return;
|
||||
|
||||
let selectedData = {selected: {}} as TabSelectData;
|
||||
selectedData.type = null;
|
||||
|
||||
for (let select in query) {
|
||||
selectedData.selected[select] = {} as TabSelect;
|
||||
selectedData.selected[select].name = query[select];
|
||||
selectedData.selected[select].index = -1;
|
||||
}
|
||||
|
||||
localStorage.setItem(TabStorageService.dataName, JSON.stringify(selectedData));
|
||||
}
|
||||
|
||||
public static get selected(): TabSelectData | null {
|
||||
let data = localStorage.getItem(this.dataName);
|
||||
|
||||
if (data === null)
|
||||
return null;
|
||||
|
||||
return JSON.parse(data) as TabSelectData;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user