From 130182fb25a65ea4bf6c21140cb66eedcdf6c715 Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Mon, 22 Jun 2026 13:48:49 +0300 Subject: [PATCH 01/16] feat(student): implement StudentService for API integration and update StudentTable to load students dynamically --- .../src/app/core/interfaces/student-elm.ts | 1 + .../app/core/shared/main-panel/main-panel.ts | 5 +- .../app/features/student/student-service.ts | 59 +++++ .../student/student-table/student-table.ts | 212 ++++++++++-------- 4 files changed, 177 insertions(+), 100 deletions(-) create mode 100644 uniplanWeb/src/app/features/student/student-service.ts diff --git a/uniplanWeb/src/app/core/interfaces/student-elm.ts b/uniplanWeb/src/app/core/interfaces/student-elm.ts index f826a9b..71eff05 100644 --- a/uniplanWeb/src/app/core/interfaces/student-elm.ts +++ b/uniplanWeb/src/app/core/interfaces/student-elm.ts @@ -1,4 +1,5 @@ export interface StudentElm { + id: string; position: number; name: string; facultyNumber: string; diff --git a/uniplanWeb/src/app/core/shared/main-panel/main-panel.ts b/uniplanWeb/src/app/core/shared/main-panel/main-panel.ts index d205b1b..389da4f 100644 --- a/uniplanWeb/src/app/core/shared/main-panel/main-panel.ts +++ b/uniplanWeb/src/app/core/shared/main-panel/main-panel.ts @@ -8,8 +8,7 @@ import { MajorTable } from '../../../features/major/major-table/major-table'; import { MajorFilters } from '../../../features/major/major-filters/major-filters'; import { StudentOptions } from '../../../features/student/student-options/student-options'; import { - StudentTable, - ELEMENT_STUDENT_DATA, + StudentTable } from '../../../features/student/student-table/student-table'; import { StudentFilters } from '../../../features/student/student-filters/student-filters'; import { MajorElm } from '../../interfaces/major-elm'; @@ -37,7 +36,7 @@ export class MainPanel { currentView = 'home'; majors: MajorElm[] = []; - students = ELEMENT_STUDENT_DATA; + students = []; searchText = ''; searchFacNum = ''; diff --git a/uniplanWeb/src/app/features/student/student-service.ts b/uniplanWeb/src/app/features/student/student-service.ts new file mode 100644 index 0000000..a13a06f --- /dev/null +++ b/uniplanWeb/src/app/features/student/student-service.ts @@ -0,0 +1,59 @@ +import { inject, Injectable } from '@angular/core'; +import { map, Observable, Subject } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; +import { StudentElm } from '../../core/interfaces/student-elm'; + +@Injectable({ + providedIn: 'root' +}) +export class StudentService { + private apiUrl = 'http://localhost:8080/api/students' + + refreshNeeded = new Subject(); + + private http = inject(HttpClient); + + getStudents(): Observable { + return this.http.get(this.apiUrl).pipe( + map((students) => + students.map((student, index) => ({ + id: student.id, + position: index + 1, + name: student.name, + facultyNumber: student.facultyNumber, + major: student.major, + majorType: student.majorType, + course: student.course, + subtype: student.subtype, + })) + ) + ); + } + createStudent(student: Omit): Observable { + return this.http.post(`${this.apiUrl}`, student).pipe( + map((res) => { + this.refreshNeeded.next(); + return res; + }) + ); + } + + editStudent(id: string, + updatedStudent: Omit): Observable { + return this.http.put(`${this.apiUrl}/${id}`, updatedStudent).pipe( + map((res) => { + this.refreshNeeded.next(); + return res; + }) + ); + } + + deleteStudent(id: string): Observable { + return this.http.delete(`${this.apiUrl}/${id}`).pipe( + map((res) => { + this.refreshNeeded.next(); + return res; + }) + ); + } +} \ No newline at end of file diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.ts b/uniplanWeb/src/app/features/student/student-table/student-table.ts index acffefe..20431bf 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.ts +++ b/uniplanWeb/src/app/features/student/student-table/student-table.ts @@ -4,106 +4,108 @@ import { SimpleChanges, OnChanges, OnInit, - ChangeDetectionStrategy + ChangeDetectionStrategy, + inject } from '@angular/core'; import { StudentElm } from '../../../core/interfaces/student-elm'; import { MatTableModule } from '@angular/material/table'; import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; +import { StudentService } from '../student-service'; -export const ELEMENT_STUDENT_DATA: StudentElm[] = [ - { - position: 1, - name: 'Иван Иванов', - facultyNumber: '123456', - majorType: 'бакалавър', - major: 'Компютърни науки', - course: '3', - subtype: 'редовно', - }, - { - position: 2, - name: 'Мария Петрова', - facultyNumber: '234567', - majorType: 'бакалавър', - major: 'История', - course: '2', - subtype: 'задочно', - }, - { - position: 3, - name: 'Георги Георгиев', - facultyNumber: '345678', - majorType: 'бакалавър', - major: 'Английска филология', - course: '1', - subtype: 'редовно', - }, - { - position: 4, - name: 'Анна Димитрова', - facultyNumber: '456789', - majorType: 'магистър', - major: 'Молекулярна биология', - course: '4', - subtype: 'редовно', - }, - { - position: 5, - name: 'Петър Петров', - facultyNumber: '567890', - majorType: 'магистър', - major: 'Органична химия', - course: '2', - subtype: 'редовно', - }, - { - position: 6, - name: 'Елена Стоянова', - facultyNumber: '678901', - majorType: 'магистър', - major: 'Астрофизика', - course: '3', - subtype: 'задочно', - }, - { - position: 7, - name: 'Димитър Иванов', - facultyNumber: '789012', - majorType: 'бакалавър', - major: 'Начална педагогика', - course: '1', - subtype: 'редовно', - }, - { - position: 8, - name: 'Виктория Николова', - facultyNumber: '890123', - majorType: 'бакалавър', - major: 'Специална педагогика', - course: '4', - subtype: 'редовно', - }, - { - position: 9, - name: 'Красимир Тодоров', - facultyNumber: '901234', - majorType: 'бакалавър', - major: 'Екология', - course: '3', - subtype: 'задочно', - }, - { - position: 10, - name: 'Милена Георгиева', - facultyNumber: '012345', - majorType: 'магистър', - major: 'Прикладна математика', - course: '2', - subtype: 'редовно', - }, -]; +// export const ELEMENT_STUDENT_DATA: StudentElm[] = [ +// { +// position: 1, +// name: 'Иван Иванов', +// facultyNumber: '123456', +// majorType: 'бакалавър', +// major: 'Компютърни науки', +// course: '3', +// subtype: 'редовно', +// }, +// { +// position: 2, +// name: 'Мария Петрова', +// facultyNumber: '234567', +// majorType: 'бакалавър', +// major: 'История', +// course: '2', +// subtype: 'задочно', +// }, +// { +// position: 3, +// name: 'Георги Георгиев', +// facultyNumber: '345678', +// majorType: 'бакалавър', +// major: 'Английска филология', +// course: '1', +// subtype: 'редовно', +// }, +// { +// position: 4, +// name: 'Анна Димитрова', +// facultyNumber: '456789', +// majorType: 'магистър', +// major: 'Молекулярна биология', +// course: '4', +// subtype: 'редовно', +// }, +// { +// position: 5, +// name: 'Петър Петров', +// facultyNumber: '567890', +// majorType: 'магистър', +// major: 'Органична химия', +// course: '2', +// subtype: 'редовно', +// }, +// { +// position: 6, +// name: 'Елена Стоянова', +// facultyNumber: '678901', +// majorType: 'магистър', +// major: 'Астрофизика', +// course: '3', +// subtype: 'задочно', +// }, +// { +// position: 7, +// name: 'Димитър Иванов', +// facultyNumber: '789012', +// majorType: 'бакалавър', +// major: 'Начална педагогика', +// course: '1', +// subtype: 'редовно', +// }, +// { +// position: 8, +// name: 'Виктория Николова', +// facultyNumber: '890123', +// majorType: 'бакалавър', +// major: 'Специална педагогика', +// course: '4', +// subtype: 'редовно', +// }, +// { +// position: 9, +// name: 'Красимир Тодоров', +// facultyNumber: '901234', +// majorType: 'бакалавър', +// major: 'Екология', +// course: '3', +// subtype: 'задочно', +// }, +// { +// position: 10, +// name: 'Милена Георгиева', +// facultyNumber: '012345', +// majorType: 'магистър', +// major: 'Прикладна математика', +// course: '2', +// subtype: 'редовно', +// }, +// ]; @Component({ selector: 'app-student-table', @@ -113,6 +115,7 @@ export const ELEMENT_STUDENT_DATA: StudentElm[] = [ styleUrl: './student-table.scss', }) export class StudentTable implements OnInit, OnChanges { + private studentService = inject(StudentService) //todo @Input() searchText = ''; @Input() searchFacNum = ''; @@ -132,18 +135,33 @@ export class StudentTable implements OnInit, OnChanges { 'actions', ]; - originalData: StudentElm[] = ELEMENT_STUDENT_DATA; - dataSourceFilter: StudentElm[] = ELEMENT_STUDENT_DATA; + originalData: StudentElm[] = []; + dataSourceFilter: StudentElm[] = []; ngOnInit(): void { - this.subtypes = StudentTable.getFilterOptions(this.originalData).subtypes; - this.applyFilters(); + this.loadStudents(); + this.studentService.refreshNeeded.subscribe(() => { + this.loadStudents(); + }); } ngOnChanges(changes: SimpleChanges): void { this.applyFilters(); } + loadStudents(): void { + this.studentService.getStudents().subscribe({ + next: (students) => { + this.originalData = students; + this.subtypes = StudentTable.getFilterOptions(students).subtypes; + this.applyFilters(); + }, + error: () => { + console.error('Failed to load students'); + } + }); + } + applyFilters(): void { const name = this.searchText.toLowerCase(); const major = this.searchMajor.toLowerCase(); From 9348a9f29e596cd14350f79c0e05367f489a98ea Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Mon, 22 Jun 2026 16:06:05 +0300 Subject: [PATCH 02/16] Changes in Student interface --- uniplanWeb/src/app/core/interfaces/student-elm.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/uniplanWeb/src/app/core/interfaces/student-elm.ts b/uniplanWeb/src/app/core/interfaces/student-elm.ts index 71eff05..eaa4a1d 100644 --- a/uniplanWeb/src/app/core/interfaces/student-elm.ts +++ b/uniplanWeb/src/app/core/interfaces/student-elm.ts @@ -3,8 +3,7 @@ export interface StudentElm { position: number; name: string; facultyNumber: string; - major: string; - majorType: string; - course: string; - subtype: 'редовно' | 'задочно'; + majorName: string; + courseType: string; + courseSubtype: 'редовно' | 'задочно'; } From 6155251e50a45cd033f613017a54d17d59c150f5 Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Tue, 23 Jun 2026 09:27:55 +0300 Subject: [PATCH 03/16] feat(student): update StudentElm interface and related components to use majorName, majorType, courseType, and courseSubtype --- .../src/app/core/interfaces/student-elm.ts | 1 + .../app/features/student/student-service.ts | 6 +-- .../student/student-table/student-table.html | 42 +++++++++---------- .../student/student-table/student-table.ts | 18 ++++---- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/uniplanWeb/src/app/core/interfaces/student-elm.ts b/uniplanWeb/src/app/core/interfaces/student-elm.ts index eaa4a1d..eac50c5 100644 --- a/uniplanWeb/src/app/core/interfaces/student-elm.ts +++ b/uniplanWeb/src/app/core/interfaces/student-elm.ts @@ -4,6 +4,7 @@ export interface StudentElm { name: string; facultyNumber: string; majorName: string; + majorType: string; courseType: string; courseSubtype: 'редовно' | 'задочно'; } diff --git a/uniplanWeb/src/app/features/student/student-service.ts b/uniplanWeb/src/app/features/student/student-service.ts index a13a06f..72d9a29 100644 --- a/uniplanWeb/src/app/features/student/student-service.ts +++ b/uniplanWeb/src/app/features/student/student-service.ts @@ -21,10 +21,10 @@ export class StudentService { position: index + 1, name: student.name, facultyNumber: student.facultyNumber, - major: student.major, + majorName: student.majorName, majorType: student.majorType, - course: student.course, - subtype: student.subtype, + courseType: student.courseType, + courseSubtype: student.courseSubtype as 'редовно' | 'задочно', })) ) ); diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.html b/uniplanWeb/src/app/features/student/student-table/student-table.html index 67e9fc1..026a935 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.html +++ b/uniplanWeb/src/app/features/student/student-table/student-table.html @@ -1,6 +1,5 @@
- +
@@ -17,7 +16,7 @@ - + @@ -29,14 +28,14 @@ - - - - @@ -49,8 +48,7 @@
No. Специалност Курс + + Форма на + обучение Форма на - обучение + + Курс
- +
@@ -66,9 +64,9 @@ {{element.facultyNumber}} - + + {{element.majorName}} @@ -76,24 +74,22 @@ {{element.majorType}} - - + + - - + + @@ -102,4 +98,4 @@
{{element.position}} - {{element.major}} - {{element.course}} + {{element.courseSubtype}} - {{element.subtype}} + {{element.courseType}} - -
-
+ \ No newline at end of file diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.ts b/uniplanWeb/src/app/features/student/student-table/student-table.ts index 20431bf..5e3030d 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.ts +++ b/uniplanWeb/src/app/features/student/student-table/student-table.ts @@ -128,10 +128,10 @@ export class StudentTable implements OnInit, OnChanges { 'position', 'name', 'facultyNumber', - 'major', + 'majorName', 'majorType', - 'subtype', - 'course', + 'courseSubtype', + 'courseType', 'actions', ]; @@ -140,9 +140,9 @@ export class StudentTable implements OnInit, OnChanges { ngOnInit(): void { this.loadStudents(); - this.studentService.refreshNeeded.subscribe(() => { - this.loadStudents(); - }); + this.studentService.refreshNeeded.subscribe(() => { + this.loadStudents(); + }); } ngOnChanges(changes: SimpleChanges): void { @@ -169,9 +169,9 @@ export class StudentTable implements OnInit, OnChanges { this.dataSourceFilter = this.originalData.filter((student) => { const matchName = !name || student.name.toLowerCase().includes(name); - const matchMajor = !major || student.major.toLowerCase().includes(major); + const matchMajor = !major || student.majorName.toLowerCase().includes(major); const matchFacNum = !facNum || student.facultyNumber.includes(facNum); - const matchSubtype = !this.subtype || student.subtype === this.subtype; + const matchSubtype = !this.subtype || student.courseSubtype === this.subtype; return matchName && matchMajor && matchFacNum && matchSubtype; }); @@ -179,7 +179,7 @@ export class StudentTable implements OnInit, OnChanges { static getFilterOptions(data: StudentElm[]) { return { - subtypes: [...new Set(data.map((e) => e.subtype))], + subtypes: [...new Set(data.map((e) => e.courseSubtype))], }; } From 55b1c68a9306ae4a36886e9eb5e62446c4ef9043 Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Tue, 23 Jun 2026 14:29:49 +0300 Subject: [PATCH 04/16] feat(student): update StudentElm interface and related components to include courseYear and replace majorType with courseType --- .../src/app/core/interfaces/student-elm.ts | 2 +- .../app/features/student/student-service.ts | 4 +- .../student/student-table/student-table.html | 20 ++-- .../student/student-table/student-table.scss | 31 ++---- .../student/student-table/student-table.ts | 97 +------------------ 5 files changed, 22 insertions(+), 132 deletions(-) diff --git a/uniplanWeb/src/app/core/interfaces/student-elm.ts b/uniplanWeb/src/app/core/interfaces/student-elm.ts index eac50c5..93f09d6 100644 --- a/uniplanWeb/src/app/core/interfaces/student-elm.ts +++ b/uniplanWeb/src/app/core/interfaces/student-elm.ts @@ -4,7 +4,7 @@ export interface StudentElm { name: string; facultyNumber: string; majorName: string; - majorType: string; courseType: string; courseSubtype: 'редовно' | 'задочно'; + courseYear: number; } diff --git a/uniplanWeb/src/app/features/student/student-service.ts b/uniplanWeb/src/app/features/student/student-service.ts index 72d9a29..2ccdf0b 100644 --- a/uniplanWeb/src/app/features/student/student-service.ts +++ b/uniplanWeb/src/app/features/student/student-service.ts @@ -22,9 +22,9 @@ export class StudentService { name: student.name, facultyNumber: student.facultyNumber, majorName: student.majorName, - majorType: student.majorType, courseType: student.courseType, - courseSubtype: student.courseSubtype as 'редовно' | 'задочно', + courseSubtype: student.courseSubtype, + courseYear: student.courseYear, })) ) ); diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.html b/uniplanWeb/src/app/features/student/student-table/student-table.html index 026a935..c1288d5 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.html +++ b/uniplanWeb/src/app/features/student/student-table/student-table.html @@ -22,8 +22,8 @@ - - + + Квалификационна степен @@ -34,8 +34,8 @@ - - Курс + + Курс @@ -69,9 +69,9 @@ {{element.majorName}} - - - {{element.majorType}} + + + {{element.courseType}} @@ -79,9 +79,9 @@ {{element.courseSubtype}} - - - {{element.courseType}} + + + {{element.courseYear}} diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.scss b/uniplanWeb/src/app/features/student/student-table/student-table.scss index 68efa23..06fe230 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.scss +++ b/uniplanWeb/src/app/features/student/student-table/student-table.scss @@ -4,91 +4,74 @@ overflow: hidden; background-color: #fff; } - .table-header { width: 100%; table-layout: fixed; } - .scrollable-body { max-height: 510px; overflow-y: auto; overflow-x: hidden; } - @media (min-width: 900px) { .scrollable-body { max-height: 510px; } } - @media (min-width: 1800px) { .scrollable-body { max-height: 680px; } } - .table-body { width: 100%; table-layout: fixed; border-collapse: collapse; } - .table-body tr:hover td { background-color: #f8f8f8; cursor: pointer; } - th, td { text-align: center; padding: 8px 10px; word-wrap: break-word; } - th { background-color: #f7f7f7 !important; } - td { background-color: #fff; } - .col-position { width: 80px; border-right: 1px solid #e0e0e0; } - .col-name { width: 130px; border-right: 1px solid #e0e0e0; } - .col-fac-number { width: 120px; border-right: 1px solid #e0e0e0; } - -.col-major-type { - width: 140px; - border-right: 1px solid #e0e0e0; -} - .col-major { width: 160px; border-right: 1px solid #e0e0e0; } - -.col-course { - width: 70px; +.col-course-type { + width: 140px; border-right: 1px solid #e0e0e0; } - .col-subtype { width: 100px; border-right: 1px solid #e0e0e0; } - +.col-year { + width: 70px; + border-right: 1px solid #e0e0e0; +} .col-actions { width: 109px; -} +} \ No newline at end of file diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.ts b/uniplanWeb/src/app/features/student/student-table/student-table.ts index 5e3030d..c8a2610 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.ts +++ b/uniplanWeb/src/app/features/student/student-table/student-table.ts @@ -14,99 +14,6 @@ import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; import { StudentService } from '../student-service'; -// export const ELEMENT_STUDENT_DATA: StudentElm[] = [ -// { -// position: 1, -// name: 'Иван Иванов', -// facultyNumber: '123456', -// majorType: 'бакалавър', -// major: 'Компютърни науки', -// course: '3', -// subtype: 'редовно', -// }, -// { -// position: 2, -// name: 'Мария Петрова', -// facultyNumber: '234567', -// majorType: 'бакалавър', -// major: 'История', -// course: '2', -// subtype: 'задочно', -// }, -// { -// position: 3, -// name: 'Георги Георгиев', -// facultyNumber: '345678', -// majorType: 'бакалавър', -// major: 'Английска филология', -// course: '1', -// subtype: 'редовно', -// }, -// { -// position: 4, -// name: 'Анна Димитрова', -// facultyNumber: '456789', -// majorType: 'магистър', -// major: 'Молекулярна биология', -// course: '4', -// subtype: 'редовно', -// }, -// { -// position: 5, -// name: 'Петър Петров', -// facultyNumber: '567890', -// majorType: 'магистър', -// major: 'Органична химия', -// course: '2', -// subtype: 'редовно', -// }, -// { -// position: 6, -// name: 'Елена Стоянова', -// facultyNumber: '678901', -// majorType: 'магистър', -// major: 'Астрофизика', -// course: '3', -// subtype: 'задочно', -// }, -// { -// position: 7, -// name: 'Димитър Иванов', -// facultyNumber: '789012', -// majorType: 'бакалавър', -// major: 'Начална педагогика', -// course: '1', -// subtype: 'редовно', -// }, -// { -// position: 8, -// name: 'Виктория Николова', -// facultyNumber: '890123', -// majorType: 'бакалавър', -// major: 'Специална педагогика', -// course: '4', -// subtype: 'редовно', -// }, -// { -// position: 9, -// name: 'Красимир Тодоров', -// facultyNumber: '901234', -// majorType: 'бакалавър', -// major: 'Екология', -// course: '3', -// subtype: 'задочно', -// }, -// { -// position: 10, -// name: 'Милена Георгиева', -// facultyNumber: '012345', -// majorType: 'магистър', -// major: 'Прикладна математика', -// course: '2', -// subtype: 'редовно', -// }, -// ]; - @Component({ selector: 'app-student-table', imports: [MatTableModule, MatIconModule, MatButtonModule], @@ -129,11 +36,11 @@ export class StudentTable implements OnInit, OnChanges { 'name', 'facultyNumber', 'majorName', - 'majorType', 'courseSubtype', 'courseType', + 'courseYear', 'actions', - ]; +]; originalData: StudentElm[] = []; dataSourceFilter: StudentElm[] = []; From 7a5e3bf5ebbd3299562947386aea0858b76bc174 Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Wed, 24 Jun 2026 10:36:31 +0300 Subject: [PATCH 05/16] feat(course): add CourseElm interface and CourseService for course data retrieval feat(student): integrate MatDialog in StudentTable for dialog management --- .../src/app/core/interfaces/course-elm.ts | 7 +++++++ .../src/app/features/course/course-service.ts | 17 +++++++++++++++++ .../student/student-table/student-table.ts | 2 ++ 3 files changed, 26 insertions(+) create mode 100644 uniplanWeb/src/app/core/interfaces/course-elm.ts create mode 100644 uniplanWeb/src/app/features/course/course-service.ts diff --git a/uniplanWeb/src/app/core/interfaces/course-elm.ts b/uniplanWeb/src/app/core/interfaces/course-elm.ts new file mode 100644 index 0000000..017004f --- /dev/null +++ b/uniplanWeb/src/app/core/interfaces/course-elm.ts @@ -0,0 +1,7 @@ +export interface CourseElm { + id: string; + majorId: string; + courseYear: number; + courseType: string; + courseSubtype: string; +} \ No newline at end of file diff --git a/uniplanWeb/src/app/features/course/course-service.ts b/uniplanWeb/src/app/features/course/course-service.ts new file mode 100644 index 0000000..fd63133 --- /dev/null +++ b/uniplanWeb/src/app/features/course/course-service.ts @@ -0,0 +1,17 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable, inject } from '@angular/core'; +import { Observable } from 'rxjs'; +import { CourseElm } from '../../core/interfaces/course-elm'; +import { environment } from '../../../environments/environments'; + +@Injectable({ + providedIn: 'root' +}) +export class CourseService { + private apiUrl = environment.testUrl.coursesUrl; + private http = inject(HttpClient); + + getCoursesByMajorId(majorId: string): Observable { + return this.http.get(`${this.apiUrl}/major/${majorId}`); + } +} \ No newline at end of file diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.ts b/uniplanWeb/src/app/features/student/student-table/student-table.ts index c8a2610..363c812 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.ts +++ b/uniplanWeb/src/app/features/student/student-table/student-table.ts @@ -13,6 +13,7 @@ import { MatTableModule } from '@angular/material/table'; import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; import { StudentService } from '../student-service'; +import { MatDialog } from '@angular/material/dialog'; @Component({ selector: 'app-student-table', @@ -22,6 +23,7 @@ import { StudentService } from '../student-service'; styleUrl: './student-table.scss', }) export class StudentTable implements OnInit, OnChanges { + private dialog = inject(MatDialog) private studentService = inject(StudentService) //todo @Input() searchText = ''; From ac9ec743a11ec5940c91212155ba87d824acba0d Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Wed, 24 Jun 2026 11:39:01 +0300 Subject: [PATCH 06/16] adding shared warning messages for Add and Edit forms --- uniplanWeb/src/app/features/student/student-warnings.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 uniplanWeb/src/app/features/student/student-warnings.ts diff --git a/uniplanWeb/src/app/features/student/student-warnings.ts b/uniplanWeb/src/app/features/student/student-warnings.ts new file mode 100644 index 0000000..a08f196 --- /dev/null +++ b/uniplanWeb/src/app/features/student/student-warnings.ts @@ -0,0 +1,9 @@ +export const StudentWarnings = { + firstNameMissing: 'Моля въведете първо име на студента.', + lastNameMissing: 'Моля въведете фамилия на студента', + facultyNumberMissing: 'Моля въведете факултетен номер', + majorMissing: 'Моля изберете специалност', + courseSubtypeMissing: 'Моля изберете форма на обучение', + courseTypeMissing: 'Моля изберете квалификационна степен', + courseYearMissing: 'Моля изберете курс', +}; \ No newline at end of file From f1f7a02c38cf18148697889312fc5219896abacb Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Wed, 24 Jun 2026 22:44:06 +0300 Subject: [PATCH 07/16] added majorId to student element interface and refactored getStudents in service --- uniplanWeb/src/app/core/interfaces/student-elm.ts | 1 + uniplanWeb/src/app/features/student/student-service.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/uniplanWeb/src/app/core/interfaces/student-elm.ts b/uniplanWeb/src/app/core/interfaces/student-elm.ts index 93f09d6..8ef90ee 100644 --- a/uniplanWeb/src/app/core/interfaces/student-elm.ts +++ b/uniplanWeb/src/app/core/interfaces/student-elm.ts @@ -3,6 +3,7 @@ export interface StudentElm { position: number; name: string; facultyNumber: string; + majorId: string; majorName: string; courseType: string; courseSubtype: 'редовно' | 'задочно'; diff --git a/uniplanWeb/src/app/features/student/student-service.ts b/uniplanWeb/src/app/features/student/student-service.ts index 2ccdf0b..48fc223 100644 --- a/uniplanWeb/src/app/features/student/student-service.ts +++ b/uniplanWeb/src/app/features/student/student-service.ts @@ -21,6 +21,7 @@ export class StudentService { position: index + 1, name: student.name, facultyNumber: student.facultyNumber, + majorId: student.majorId, majorName: student.majorName, courseType: student.courseType, courseSubtype: student.courseSubtype, From 07200ac44b55af5484e596f42d1afa65f77a35ee Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Thu, 25 Jun 2026 14:17:10 +0300 Subject: [PATCH 08/16] feat(i18n): add Bulgarian and English localization files for student and faculty features refactor(student): remove deprecated student warnings file --- uniplanWeb/public/i18n/bg.json | 69 +++++++++++++++++++ uniplanWeb/public/i18n/en.json | 69 +++++++++++++++++++ .../app/features/student/student-warnings.ts | 9 --- 3 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 uniplanWeb/public/i18n/bg.json create mode 100644 uniplanWeb/public/i18n/en.json delete mode 100644 uniplanWeb/src/app/features/student/student-warnings.ts diff --git a/uniplanWeb/public/i18n/bg.json b/uniplanWeb/public/i18n/bg.json new file mode 100644 index 0000000..856e75a --- /dev/null +++ b/uniplanWeb/public/i18n/bg.json @@ -0,0 +1,69 @@ +{ + "features": { + "name-label": "Име", + "faculty-label": "Факултет", + "actions-label": "Действия", + "type-label": "Тип", + "study-mode-label": "Форма на обучение", + "major-label": "Специалност", + "location-label": "Местоположение" + }, + "faculty": { + "delete-button": "Изтрий", + "edit-button": "Редактирай", + "uni-label": "Университет", + "delete-confirmation": "Сигурни ли сте, че искате да изтриете факултет с име: ", + "add": { + "title": "Добави факултет" + }, + "edit": { + "title": "Редактирай факултет" + } + }, + "major": { + "paid-option": "Платено", + "full-time-option": "Редовно", + "delete-confirmation": "Сигурни ли сте, че искате да изтриете специалност с име: ", + "bachelor-option": "Бакалавър", + "master-option": "Магистър", + "add": { + "title": "Добави специалност" + }, + "edit": { + "title": "Редактирай специалност" + } + }, + "student": { + "faculty-number-label": "Факултетен номер", + "course-label": "Курс", + "qualification-level-label": "Квалификационна степен", + "first-name-label": "Първо име", + "last-name-label": "Фамилия", + "major-label": "Специалност", + "study-mode-label": "Форма на обучение", + "add": { + "title": "Добави студент", + "first-name-warning": "Моля въведете първо име на студента.", + "last-name-warning": "Моля въведете фамилия на студента.", + "faculty-number-warning": "Моля въведете факултетен номер.", + "major-warning": "Моля изберете специалност.", + "study-mode-warning": "Моля изберете форма на обучение.", + "qualification-warning": "Моля изберете квалификационна степен.", + "course-warning": "Моля изберете курс." + } + }, + "settings": { + "title": "Заглавие", + "span": "Смени езика", + "bulgarian": "български", + "english": "английски" + }, + "shared": { + "add-button": "Добави", + "exit-button": "Отмени", + "save-button": "Запази", + "delete-button": "Изтрий", + "option-all": "Всички", + "confirm-delete": "Потвърдете изтриването" + } +} \ No newline at end of file diff --git a/uniplanWeb/public/i18n/en.json b/uniplanWeb/public/i18n/en.json new file mode 100644 index 0000000..a7975f7 --- /dev/null +++ b/uniplanWeb/public/i18n/en.json @@ -0,0 +1,69 @@ +{ + "features": { + "name-label": "Name", + "faculty-label": "Faculty", + "actions-label": "Actions", + "type-label": "Type", + "study-mode-label": "Study mode", + "major-label": "Major", + "location-label": "Location" + }, + "faculty": { + "delete-button": "Delete", + "edit-button": "Edit", + "uni-label": "University", + "delete-confirmation": "Are you sure you want to delete the faculty named: ", + "add": { + "title": "Add faculty" + }, + "edit": { + "title": "Edit faculty" + } + }, + "major": { + "paid-option": "Paid", + "full-time-option": "Full-time", + "delete-confirmation": "Are you sure you want to delete the major named: ", + "bachelor-option": "Bachelor", + "master-option": "Master", + "add": { + "title": "Add major" + }, + "edit": { + "title": "Edit major" + } + }, + "student": { + "faculty-number-label": "Student ID", + "course-label": "Course", + "qualification-level-label": "Qualification level", + "first-name-label": "First name", + "last-name-label": "Last name", + "major-label": "Major", + "study-mode-label": "Study mode", + "add": { + "title": "Add student", + "first-name-warning": "Please enter the student's first name.", + "last-name-warning": "Please enter the student's last name.", + "faculty-number-warning": "Please enter the faculty number.", + "major-warning": "Please select a major.", + "study-mode-warning": "Please select a study mode.", + "qualification-warning": "Please select a qualification level.", + "course-warning": "Please select a course." + } + }, + "settings": { + "title": "Title", + "span": "Change language", + "bulgarian": "Bulgarian", + "english": "English" + }, + "shared": { + "add-button": "Add", + "exit-button": "Cancel", + "save-button": "Save", + "delete-button": "Delete", + "option-all": "All", + "confirm-delete": "Confirm deletion" + } +} \ No newline at end of file diff --git a/uniplanWeb/src/app/features/student/student-warnings.ts b/uniplanWeb/src/app/features/student/student-warnings.ts deleted file mode 100644 index a08f196..0000000 --- a/uniplanWeb/src/app/features/student/student-warnings.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const StudentWarnings = { - firstNameMissing: 'Моля въведете първо име на студента.', - lastNameMissing: 'Моля въведете фамилия на студента', - facultyNumberMissing: 'Моля въведете факултетен номер', - majorMissing: 'Моля изберете специалност', - courseSubtypeMissing: 'Моля изберете форма на обучение', - courseTypeMissing: 'Моля изберете квалификационна степен', - courseYearMissing: 'Моля изберете курс', -}; \ No newline at end of file From 29237f3fa2e55be674cb6aa146f3862bafd3b46a Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Thu, 25 Jun 2026 14:29:58 +0300 Subject: [PATCH 09/16] feat(i18n): restructure student add/edit warnings in Bulgarian and English localization files --- uniplanWeb/public/i18n/bg.json | 24 ++++++++++++++++-------- uniplanWeb/public/i18n/en.json | 24 ++++++++++++++++-------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/uniplanWeb/public/i18n/bg.json b/uniplanWeb/public/i18n/bg.json index 856e75a..e841e71 100644 --- a/uniplanWeb/public/i18n/bg.json +++ b/uniplanWeb/public/i18n/bg.json @@ -42,14 +42,22 @@ "major-label": "Специалност", "study-mode-label": "Форма на обучение", "add": { - "title": "Добави студент", - "first-name-warning": "Моля въведете първо име на студента.", - "last-name-warning": "Моля въведете фамилия на студента.", - "faculty-number-warning": "Моля въведете факултетен номер.", - "major-warning": "Моля изберете специалност.", - "study-mode-warning": "Моля изберете форма на обучение.", - "qualification-warning": "Моля изберете квалификационна степен.", - "course-warning": "Моля изберете курс." + "title": "Добави студент" + }, + "edit": { + "title": "Редактирай студент" + }, + "delete": { + "title": "Изтрий студент" + }, + "warnings": { + "first-name": "Моля въведете първо име на студента.", + "last-name": "Моля въведете фамилия на студента.", + "faculty-number": "Моля въведете факултетен номер.", + "major": "Моля изберете специалност.", + "study-mode": "Моля изберете форма на обучение.", + "qualification": "Моля изберете квалификационна степен.", + "course": "Моля изберете курс." } }, "settings": { diff --git a/uniplanWeb/public/i18n/en.json b/uniplanWeb/public/i18n/en.json index a7975f7..52bd2e1 100644 --- a/uniplanWeb/public/i18n/en.json +++ b/uniplanWeb/public/i18n/en.json @@ -42,14 +42,22 @@ "major-label": "Major", "study-mode-label": "Study mode", "add": { - "title": "Add student", - "first-name-warning": "Please enter the student's first name.", - "last-name-warning": "Please enter the student's last name.", - "faculty-number-warning": "Please enter the faculty number.", - "major-warning": "Please select a major.", - "study-mode-warning": "Please select a study mode.", - "qualification-warning": "Please select a qualification level.", - "course-warning": "Please select a course." + "title": "Add student" + }, + "edit": { + "title": "Edit student" + }, + "delete":{ + "title": "Delete student" + }, + "warnings": { + "first-name": "Please enter the student's first name.", + "last-name": "Please enter the student's last name.", + "faculty-number": "Please enter the faculty number.", + "major": "Please select a major.", + "study-mode": "Please select a study mode.", + "qualification": "Please select a qualification level.", + "course": "Please select a course." } }, "settings": { From bc92eebf4c920d01a9db50f71a3f52dcb3da5ef3 Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Thu, 25 Jun 2026 15:40:16 +0300 Subject: [PATCH 10/16] style(student-table): student-table i18n --- .../student/student-table/student-table.html | 74 +++++-------------- 1 file changed, 17 insertions(+), 57 deletions(-) diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.html b/uniplanWeb/src/app/features/student/student-table/student-table.html index 80bb551..0922817 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.html +++ b/uniplanWeb/src/app/features/student/student-table/student-table.html @@ -1,93 +1,54 @@
- + - - + - - + - - + - - - + + - - - + + - - - - - - + - - + -
No. - No. {{ 'features.name-label' | translate }} - {{ 'features.name-label' | translate }} - {{ 'student.faculty-number-label' | translate }} - {{ 'student.faculty-number-label' | translate }} - {{ 'features.major-label' | translate }} - {{ 'features.major-label' | translate }} - {{'student.qualification-level-label' | translate}} - {{ 'student.qualification-level-label' | translate }} {{ 'student.course-label' | translate }} - {{ 'features.study-mode-label' | translate }} {{ 'features.study-mode-label' | translate }} - Курс - {{ 'student.course-label' | translate }} {{ 'features.actions-label' | translate }} - {{ 'features.actions-label' | translate }}
-
- + - - + - - + - - + - - + - - + - - + - -
- {{element.position}} {{element.position}} - {{element.name}} {{element.name}} - {{element.facultyNumber}} {{element.facultyNumber}} - {{element.majorName}} {{element.majorName}} - {{element.courseType}} {{element.courseType}} - {{element.courseSubtype}} {{element.courseSubtype}} - {{element.courseYear}} {{element.courseYear}}
From c15562c8be3beb922c7adb771579ce75b846e31d Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Fri, 26 Jun 2026 10:29:28 +0300 Subject: [PATCH 11/16] feat(student-table): emit subtypesLoaded event and clean up unused code --- .../app/features/student/student-panel/student-panel.html | 3 ++- .../src/app/features/student/student-panel/student-panel.ts | 6 ++---- .../src/app/features/student/student-table/student-table.ts | 6 +++++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/uniplanWeb/src/app/features/student/student-panel/student-panel.html b/uniplanWeb/src/app/features/student/student-panel/student-panel.html index 7a2811e..a6d22fe 100644 --- a/uniplanWeb/src/app/features/student/student-panel/student-panel.html +++ b/uniplanWeb/src/app/features/student/student-panel/student-panel.html @@ -18,6 +18,7 @@ [searchFacNum]="searchFacNum" [searchMajor]="searchMajor" [subtype]="selectedStudentSubtype" - [subtypes]="studentSubtypes"> + [subtypes]="studentSubtypes" + (subtypesLoaded)="studentSubtypes=$event">
diff --git a/uniplanWeb/src/app/features/student/student-panel/student-panel.ts b/uniplanWeb/src/app/features/student/student-panel/student-panel.ts index 28fd5fe..ec745ef 100644 --- a/uniplanWeb/src/app/features/student/student-panel/student-panel.ts +++ b/uniplanWeb/src/app/features/student/student-panel/student-panel.ts @@ -1,9 +1,8 @@ import { Component, OnInit } from '@angular/core'; -import { StudentElm } from '../../../core/interfaces/student-elm'; import { StudentOptions } from '../student-options/student-options'; import { StudentFilters } from '../student-filters/student-filters'; -import { StudentTable, ELEMENT_STUDENT_DATA } from '../student-table/student-table'; +import { StudentTable } from '../student-table/student-table'; @Component({ selector: 'app-student-panel', @@ -19,7 +18,6 @@ export class StudentPanel implements OnInit { studentSubtypes: string[] = []; ngOnInit(): void { - const students: StudentElm[] = ELEMENT_STUDENT_DATA; - this.studentSubtypes = StudentTable.getFilterOptions(students).subtypes; + } } diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.ts b/uniplanWeb/src/app/features/student/student-table/student-table.ts index 99b0ce9..d232a49 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.ts +++ b/uniplanWeb/src/app/features/student/student-table/student-table.ts @@ -5,7 +5,8 @@ import { OnChanges, OnInit, ChangeDetectionStrategy, - inject + inject, + output } from '@angular/core'; import { StudentElm } from '../../../core/interfaces/student-elm'; import { TranslatePipe } from '@ngx-translate/core'; @@ -34,6 +35,8 @@ export class StudentTable implements OnInit, OnChanges { @Input() subtypes: string[] = []; + subtypesLoaded = output(); + displayedColumns: string[] = [ 'position', 'name', @@ -64,6 +67,7 @@ export class StudentTable implements OnInit, OnChanges { next: (students) => { this.originalData = students; this.subtypes = StudentTable.getFilterOptions(students).subtypes; + this.subtypesLoaded.emit(this.subtypes); this.applyFilters(); }, error: () => { From 001c74b85f5392c96b42b502732ac3efaa559fd3 Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Tue, 30 Jun 2026 14:42:41 +0300 Subject: [PATCH 12/16] refactor: update CourseService to use API_ENDPOINTS for URL management --- uniplanWeb/src/app/features/course/course-service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uniplanWeb/src/app/features/course/course-service.ts b/uniplanWeb/src/app/features/course/course-service.ts index fd63133..0a09773 100644 --- a/uniplanWeb/src/app/features/course/course-service.ts +++ b/uniplanWeb/src/app/features/course/course-service.ts @@ -2,16 +2,16 @@ import { HttpClient } from '@angular/common/http'; import { Injectable, inject } from '@angular/core'; import { Observable } from 'rxjs'; import { CourseElm } from '../../core/interfaces/course-elm'; -import { environment } from '../../../environments/environments'; +import { API_ENDPOINTS } from '../../config/endpoints'; @Injectable({ providedIn: 'root' }) export class CourseService { - private apiUrl = environment.testUrl.coursesUrl; + private apiUrl = API_ENDPOINTS.courses private http = inject(HttpClient); getCoursesByMajorId(majorId: string): Observable { - return this.http.get(`${this.apiUrl}/major/${majorId}`); + return this.http.get(`${API_ENDPOINTS.faculties}/major/${majorId}`); } } \ No newline at end of file From 2b5f90be24251773dc3e0c2d570f32fd9a969e8e Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Tue, 30 Jun 2026 14:46:44 +0300 Subject: [PATCH 13/16] refactor: remove unused apiUrl variable from CourseService --- uniplanWeb/src/app/features/course/course-service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/uniplanWeb/src/app/features/course/course-service.ts b/uniplanWeb/src/app/features/course/course-service.ts index 0a09773..de36473 100644 --- a/uniplanWeb/src/app/features/course/course-service.ts +++ b/uniplanWeb/src/app/features/course/course-service.ts @@ -8,7 +8,6 @@ import { API_ENDPOINTS } from '../../config/endpoints'; providedIn: 'root' }) export class CourseService { - private apiUrl = API_ENDPOINTS.courses private http = inject(HttpClient); getCoursesByMajorId(majorId: string): Observable { From d5d25831e8078f7c9f28b8352ba81e9062c78fdc Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Wed, 1 Jul 2026 09:54:06 +0300 Subject: [PATCH 14/16] refactor: update StudentService to use API_ENDPOINTS for student API URL, fixed wrong URL in CourseService --- uniplanWeb/src/app/config/endpoints.ts | 1 + uniplanWeb/src/app/features/course/course-service.ts | 6 ++++-- uniplanWeb/src/app/features/student/student-service.ts | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/uniplanWeb/src/app/config/endpoints.ts b/uniplanWeb/src/app/config/endpoints.ts index 53a9589..8896ff7 100644 --- a/uniplanWeb/src/app/config/endpoints.ts +++ b/uniplanWeb/src/app/config/endpoints.ts @@ -5,4 +5,5 @@ export const API_ENDPOINTS = { courses: `${environment.baseUrl}/courses`, faculties: `${environment.baseUrl}/faculties`, majors: `${environment.baseUrl}/majors`, + students: `${environment.baseUrl}/students`, }; diff --git a/uniplanWeb/src/app/features/course/course-service.ts b/uniplanWeb/src/app/features/course/course-service.ts index de36473..ddbc487 100644 --- a/uniplanWeb/src/app/features/course/course-service.ts +++ b/uniplanWeb/src/app/features/course/course-service.ts @@ -11,6 +11,8 @@ export class CourseService { private http = inject(HttpClient); getCoursesByMajorId(majorId: string): Observable { - return this.http.get(`${API_ENDPOINTS.faculties}/major/${majorId}`); + return this.http.get(`${API_ENDPOINTS.courses}/major/${majorId}`); } -} \ No newline at end of file +} +//placeholder course service to make student form dropdowns work, +//if there is a merge conflict please provide a getCoursesByMajorId-like method wherever it's needed \ No newline at end of file diff --git a/uniplanWeb/src/app/features/student/student-service.ts b/uniplanWeb/src/app/features/student/student-service.ts index 48fc223..2e1afa9 100644 --- a/uniplanWeb/src/app/features/student/student-service.ts +++ b/uniplanWeb/src/app/features/student/student-service.ts @@ -2,12 +2,13 @@ import { inject, Injectable } from '@angular/core'; import { map, Observable, Subject } from 'rxjs'; import { HttpClient } from '@angular/common/http'; import { StudentElm } from '../../core/interfaces/student-elm'; +import { API_ENDPOINTS } from '../../config/endpoints'; @Injectable({ providedIn: 'root' }) export class StudentService { - private apiUrl = 'http://localhost:8080/api/students' + private apiUrl = API_ENDPOINTS.students; refreshNeeded = new Subject(); From ccc0fe504590d7417754d104941adf95cb9ed230 Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Mon, 6 Jul 2026 10:04:29 +0300 Subject: [PATCH 15/16] update comment --- uniplanWeb/src/app/features/course/course-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uniplanWeb/src/app/features/course/course-service.ts b/uniplanWeb/src/app/features/course/course-service.ts index ddbc487..a35fb88 100644 --- a/uniplanWeb/src/app/features/course/course-service.ts +++ b/uniplanWeb/src/app/features/course/course-service.ts @@ -15,4 +15,4 @@ export class CourseService { } } //placeholder course service to make student form dropdowns work, -//if there is a merge conflict please provide a getCoursesByMajorId-like method wherever it's needed \ No newline at end of file +//when replacing this please provide a getCoursesByMajorId-like method \ No newline at end of file From 5292fbdb7aea624a5d7f504a0d420c32dee69d62 Mon Sep 17 00:00:00 2001 From: constantine0621 Date: Thu, 9 Jul 2026 11:17:51 +0300 Subject: [PATCH 16/16] Refactor StudentElm interface to use CourseSubtype type and update student service methods to return void --- uniplanWeb/src/app/core/interfaces/student-elm.ts | 4 +++- .../src/app/features/course/course-subtype.ts | 6 ++++++ .../src/app/features/student/student-service.ts | 12 ++++++------ .../student/student-table/student-table.ts | 14 ++++++++++---- 4 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 uniplanWeb/src/app/features/course/course-subtype.ts diff --git a/uniplanWeb/src/app/core/interfaces/student-elm.ts b/uniplanWeb/src/app/core/interfaces/student-elm.ts index 8ef90ee..63ad7ba 100644 --- a/uniplanWeb/src/app/core/interfaces/student-elm.ts +++ b/uniplanWeb/src/app/core/interfaces/student-elm.ts @@ -1,3 +1,5 @@ +import { CourseSubtype } from "../../features/course/course-subtype"; + export interface StudentElm { id: string; position: number; @@ -6,6 +8,6 @@ export interface StudentElm { majorId: string; majorName: string; courseType: string; - courseSubtype: 'редовно' | 'задочно'; + courseSubtype: CourseSubtype; courseYear: number; } diff --git a/uniplanWeb/src/app/features/course/course-subtype.ts b/uniplanWeb/src/app/features/course/course-subtype.ts new file mode 100644 index 0000000..01e81a6 --- /dev/null +++ b/uniplanWeb/src/app/features/course/course-subtype.ts @@ -0,0 +1,6 @@ +export const CourseSubtypeLabels = { + FullTime: 'редовно', + PartTime: 'задочно', +} as const; + +export type CourseSubtype = typeof CourseSubtypeLabels[keyof typeof CourseSubtypeLabels]; \ No newline at end of file diff --git a/uniplanWeb/src/app/features/student/student-service.ts b/uniplanWeb/src/app/features/student/student-service.ts index 2e1afa9..d6a451c 100644 --- a/uniplanWeb/src/app/features/student/student-service.ts +++ b/uniplanWeb/src/app/features/student/student-service.ts @@ -31,8 +31,8 @@ export class StudentService { ) ); } - createStudent(student: Omit): Observable { - return this.http.post(`${this.apiUrl}`, student).pipe( + createStudent(student: Omit): Observable { + return this.http.post(`${this.apiUrl}`, student).pipe( map((res) => { this.refreshNeeded.next(); return res; @@ -41,8 +41,8 @@ export class StudentService { } editStudent(id: string, - updatedStudent: Omit): Observable { - return this.http.put(`${this.apiUrl}/${id}`, updatedStudent).pipe( + updatedStudent: Omit): Observable { + return this.http.put(`${this.apiUrl}/${id}`, updatedStudent).pipe( map((res) => { this.refreshNeeded.next(); return res; @@ -50,8 +50,8 @@ export class StudentService { ); } - deleteStudent(id: string): Observable { - return this.http.delete(`${this.apiUrl}/${id}`).pipe( + deleteStudent(id: string): Observable { + return this.http.delete(`${this.apiUrl}/${id}`).pipe( map((res) => { this.refreshNeeded.next(); return res; diff --git a/uniplanWeb/src/app/features/student/student-table/student-table.ts b/uniplanWeb/src/app/features/student/student-table/student-table.ts index d232a49..69158cd 100644 --- a/uniplanWeb/src/app/features/student/student-table/student-table.ts +++ b/uniplanWeb/src/app/features/student/student-table/student-table.ts @@ -6,7 +6,8 @@ import { OnInit, ChangeDetectionStrategy, inject, - output + output, + DestroyRef } from '@angular/core'; import { StudentElm } from '../../../core/interfaces/student-elm'; import { TranslatePipe } from '@ngx-translate/core'; @@ -16,6 +17,7 @@ import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; import { StudentService } from '../student-service'; import { MatDialog } from '@angular/material/dialog'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @Component({ selector: 'app-student-table', @@ -27,7 +29,7 @@ import { MatDialog } from '@angular/material/dialog'; export class StudentTable implements OnInit, OnChanges { private dialog = inject(MatDialog) private studentService = inject(StudentService) - //todo + private destroyRef = inject(DestroyRef); @Input() searchText = ''; @Input() searchFacNum = ''; @Input() searchMajor = ''; @@ -53,7 +55,9 @@ export class StudentTable implements OnInit, OnChanges { ngOnInit(): void { this.loadStudents(); - this.studentService.refreshNeeded.subscribe(() => { + this.studentService.refreshNeeded + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe(() => { this.loadStudents(); }); } @@ -63,7 +67,9 @@ export class StudentTable implements OnInit, OnChanges { } loadStudents(): void { - this.studentService.getStudents().subscribe({ + this.studentService.getStudents() + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe({ next: (students) => { this.originalData = students; this.subtypes = StudentTable.getFilterOptions(students).subtypes;