diff --git a/uniplanWeb/public/i18n/bg.json b/uniplanWeb/public/i18n/bg.json index 7ac66ea..40af598 100644 --- a/uniplanWeb/public/i18n/bg.json +++ b/uniplanWeb/public/i18n/bg.json @@ -14,6 +14,7 @@ "room": { "room-number": "Номер на стая", "no-rooms": "Няма записани стаи", + "category-label":"Тип на стая/Капацитет", "add": { "title": "Добави стая", "failed": "Неуспешно добавяне на стаята." diff --git a/uniplanWeb/public/i18n/en.json b/uniplanWeb/public/i18n/en.json index c44c379..19e8cec 100644 --- a/uniplanWeb/public/i18n/en.json +++ b/uniplanWeb/public/i18n/en.json @@ -14,6 +14,7 @@ "room": { "room-number": "Room number", "no-rooms": "No rooms", + "category-label": "Room Type/Capacity", "add": { "title": "Add room", "failed": "Failed to add room." diff --git a/uniplanWeb/src/app/config/endpoints.ts b/uniplanWeb/src/app/config/endpoints.ts index 0d9f0d0..29b08af 100644 --- a/uniplanWeb/src/app/config/endpoints.ts +++ b/uniplanWeb/src/app/config/endpoints.ts @@ -5,5 +5,6 @@ export const API_ENDPOINTS = { courses: `${environment.baseUrl}/courses`, faculties: `${environment.baseUrl}/faculties`, majors: `${environment.baseUrl}/majors`, + categories: `${environment.baseUrl}/categories`, rooms: `${environment.baseUrl}/rooms`, }; diff --git a/uniplanWeb/src/app/core/interfaces/category.ts b/uniplanWeb/src/app/core/interfaces/category.ts new file mode 100644 index 0000000..c1b25eb --- /dev/null +++ b/uniplanWeb/src/app/core/interfaces/category.ts @@ -0,0 +1,6 @@ +export interface Category { + id: string; + roomType: string; + capacity: number; + position: number; +} \ No newline at end of file diff --git a/uniplanWeb/src/app/core/interfaces/room-elm.ts b/uniplanWeb/src/app/core/interfaces/room-elm.ts deleted file mode 100644 index 655e906..0000000 --- a/uniplanWeb/src/app/core/interfaces/room-elm.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface RoomElm { - id: string; - facultyId: string; - roomNumber: string; -} diff --git a/uniplanWeb/src/app/core/interfaces/room-view-model.ts b/uniplanWeb/src/app/core/interfaces/room-view-model.ts deleted file mode 100644 index 9acc24d..0000000 --- a/uniplanWeb/src/app/core/interfaces/room-view-model.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RoomElm } from "./room-elm"; - -export interface RoomViewModel extends RoomElm { - position: number; -} \ No newline at end of file diff --git a/uniplanWeb/src/app/core/interfaces/room.ts b/uniplanWeb/src/app/core/interfaces/room.ts new file mode 100644 index 0000000..adfa581 --- /dev/null +++ b/uniplanWeb/src/app/core/interfaces/room.ts @@ -0,0 +1,7 @@ +export interface Room { + id: string; + facultyId: string; + roomNumber: string; + categoryId: string; + position: number; +} diff --git a/uniplanWeb/src/app/core/shared/navmenu-component/navmenu-component.ts b/uniplanWeb/src/app/core/shared/navmenu-component/navmenu-component.ts index ea4aa6b..6b1eada 100644 --- a/uniplanWeb/src/app/core/shared/navmenu-component/navmenu-component.ts +++ b/uniplanWeb/src/app/core/shared/navmenu-component/navmenu-component.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { RouterLink, RouterLinkActive } from '@angular/router'; import { TranslatePipe } from '@ngx-translate/core'; -import { LoginAuthService } from '../../../services/login-auth-service'; +import { LoginAuthService } from '../../../services/login/login-auth-service'; @Component({ selector: 'app-navmenu-component', diff --git a/uniplanWeb/src/app/core/shared/pipes/category/category-display-pipe.spec.ts b/uniplanWeb/src/app/core/shared/pipes/category/category-display-pipe.spec.ts new file mode 100644 index 0000000..26c897d --- /dev/null +++ b/uniplanWeb/src/app/core/shared/pipes/category/category-display-pipe.spec.ts @@ -0,0 +1,8 @@ +import { CategoryDisplayPipe } from "./category-display-pipe"; + +describe('CategoryDisplayPipe', () => { + it('create an instance', () => { + const pipe = new CategoryDisplayPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/uniplanWeb/src/app/core/shared/pipes/category/category-display-pipe.ts b/uniplanWeb/src/app/core/shared/pipes/category/category-display-pipe.ts new file mode 100644 index 0000000..31f7977 --- /dev/null +++ b/uniplanWeb/src/app/core/shared/pipes/category/category-display-pipe.ts @@ -0,0 +1,13 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'categoryDisplayPipe', +}) + +export class CategoryDisplayPipe implements PipeTransform { + + transform(id: string, categoryMap: Map): string { + return categoryMap.get(id) || '—'; + } + +} diff --git a/uniplanWeb/src/app/core/shared/pipes/faculty-name-pipe.spec.ts b/uniplanWeb/src/app/core/shared/pipes/faculty/faculty-name-pipe.spec.ts similarity index 73% rename from uniplanWeb/src/app/core/shared/pipes/faculty-name-pipe.spec.ts rename to uniplanWeb/src/app/core/shared/pipes/faculty/faculty-name-pipe.spec.ts index bd0e57e..7d273cf 100644 --- a/uniplanWeb/src/app/core/shared/pipes/faculty-name-pipe.spec.ts +++ b/uniplanWeb/src/app/core/shared/pipes/faculty/faculty-name-pipe.spec.ts @@ -1,4 +1,4 @@ -import { FacultyNamePipe } from './faculty-name-pipe'; +import { FacultyNamePipe } from "./faculty-name-pipe"; describe('FacultyNamePipe', () => { it('create an instance', () => { diff --git a/uniplanWeb/src/app/core/shared/pipes/faculty-name-pipe.ts b/uniplanWeb/src/app/core/shared/pipes/faculty/faculty-name-pipe.ts similarity index 100% rename from uniplanWeb/src/app/core/shared/pipes/faculty-name-pipe.ts rename to uniplanWeb/src/app/core/shared/pipes/faculty/faculty-name-pipe.ts diff --git a/uniplanWeb/src/app/features/room/room-service.ts b/uniplanWeb/src/app/features/room/room-service.ts index 217367e..077a9d3 100644 --- a/uniplanWeb/src/app/features/room/room-service.ts +++ b/uniplanWeb/src/app/features/room/room-service.ts @@ -1,8 +1,7 @@ import { Injectable, inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { map, Observable, shareReplay } from 'rxjs'; -import { RoomViewModel } from '../../core/interfaces/room-view-model'; -import { RoomElm } from '../../core/interfaces/room-elm'; +import { Room } from '../../core/interfaces/room'; import { Subject } from 'rxjs'; import { API_ENDPOINTS } from '../../config/endpoints'; @@ -15,14 +14,15 @@ export class RoomService { private http = inject(HttpClient); - getRooms(): Observable { - return this.http.get(API_ENDPOINTS.rooms).pipe( + getRooms(): Observable { + return this.http.get(API_ENDPOINTS.rooms).pipe( map(rooms => rooms ?? []), map(rooms => rooms.map((room, index) => ({ id: room.id, facultyId: room.facultyId, roomNumber: room.roomNumber, + categoryId: room.categoryId, position: index + 1, })) ), @@ -33,8 +33,8 @@ export class RoomService { createRoom(room: { roomNumber: string; facultyId: string; - }): Observable { - return this.http.post(`${(API_ENDPOINTS.rooms)}`, room).pipe( + }): Observable { + return this.http.post(`${(API_ENDPOINTS.rooms)}`, room).pipe( map((res) => { this.refreshNeeded.next(); return res; diff --git a/uniplanWeb/src/app/features/room/room-table/room-table.html b/uniplanWeb/src/app/features/room/room-table/room-table.html index 3747b80..d160e78 100644 --- a/uniplanWeb/src/app/features/room/room-table/room-table.html +++ b/uniplanWeb/src/app/features/room/room-table/room-table.html @@ -12,6 +12,12 @@ {{ 'room.room-number' | translate }} + + + {{ 'room.category-label' | translate }} + + + {{ 'features.actions-label' | translate }} @@ -35,13 +41,19 @@ - {{ element.facultyId | facultyNamePipe: facultyMap() }} + {{ element.facultyId | facultyNamePipe: facultyMap }} - - {{ element.roomNumber }} + {{ element.roomNumber }} + + + + + + {{ element.categoryId | categoryDisplayPipe: categoryMap }} + diff --git a/uniplanWeb/src/app/features/room/room-table/room-table.scss b/uniplanWeb/src/app/features/room/room-table/room-table.scss index 3c2519f..bef3d54 100644 --- a/uniplanWeb/src/app/features/room/room-table/room-table.scss +++ b/uniplanWeb/src/app/features/room/room-table/room-table.scss @@ -8,11 +8,12 @@ .table-header { width: 100%; table-layout: fixed; + padding-right: 14px; } .scrollable-body { max-height: 510px; - overflow-y: auto; + overflow-y: scroll; overflow-x: hidden; } @@ -55,20 +56,25 @@ td { } .col-position { - width: 100px; + width: 10%; border-right: 1px solid #e0e0e0; } .col-name { - width: 200px; + width: 25%; border-right: 1px solid #e0e0e0; } .col-room-number { - width: 260px; + width: 20%; + border-right: 1px solid #e0e0e0; +} + +.col-category { + width: 30%; border-right: 1px solid #e0e0e0; } .col-actions { - width: 150px; + width: 15%; } \ No newline at end of file diff --git a/uniplanWeb/src/app/features/room/room-table/room-table.ts b/uniplanWeb/src/app/features/room/room-table/room-table.ts index 4c018f5..2c5cc68 100644 --- a/uniplanWeb/src/app/features/room/room-table/room-table.ts +++ b/uniplanWeb/src/app/features/room/room-table/room-table.ts @@ -1,4 +1,4 @@ -import { Component, inject, ChangeDetectionStrategy, DestroyRef, OnInit, signal } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy, DestroyRef, OnInit } from '@angular/core'; import { RoomService } from '../room-service'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; @@ -8,9 +8,10 @@ import { TranslatePipe } from '@ngx-translate/core'; import { CommonModule } from '@angular/common'; import { FacultyService } from '../../faculty/faculty-service'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { FacultyNamePipe } from '../../../core/shared/pipes/faculty-name-pipe'; +import { FacultyNamePipe } from '../../../core/shared/pipes/faculty/faculty-name-pipe'; +import { CategoryDisplayPipe } from '../../../core/shared/pipes/category/category-display-pipe'; +import { CategoryService } from '../../../services/category/category-service'; import { startWith, switchMap } from 'rxjs'; - @Component({ selector: 'app-room-table', templateUrl: './room-table.html', @@ -23,25 +24,30 @@ import { startWith, switchMap } from 'rxjs'; MatDialogModule, TranslatePipe, CommonModule, - FacultyNamePipe + FacultyNamePipe, + CategoryDisplayPipe ], }) export class RoomTable implements OnInit { roomService = inject(RoomService); facultyService = inject(FacultyService); - facultyMap = signal>(new Map()); + categoryService = inject(CategoryService) + facultyMap = new Map(); + categoryMap = new Map(); private destroyRef = inject(DestroyRef); displayedColumns: string[] = [ 'position', 'facultyId', 'roomNumber', + 'categoryId', 'actions', ]; ngOnInit(): void { this.loadFaculties(); + this.loadCategories(); } data$ = this.roomService.refreshNeeded.pipe( @@ -53,7 +59,17 @@ export class RoomTable implements OnInit { this.facultyService.getFaculties() .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((faculties) => { - this.facultyMap.set(new Map(faculties.map((f) => [f.id, f.facultyName]))); + this.facultyMap = new Map(faculties.map((f) => [f.id, f.facultyName])); + }); + } + + loadCategories(): void { + this.categoryService.getCategories() + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((categories) => { + this.categoryMap = new Map( + categories.map((c) => [c.id, `${c.roomType} (${c.capacity})`]) + ); }); } } diff --git a/uniplanWeb/src/app/services/category/category-service.spec.ts b/uniplanWeb/src/app/services/category/category-service.spec.ts new file mode 100644 index 0000000..240b9ee --- /dev/null +++ b/uniplanWeb/src/app/services/category/category-service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { CategoryService } from './category-service'; + +describe('CategoryService', () => { + let service: CategoryService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(CategoryService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/uniplanWeb/src/app/services/category/category-service.ts b/uniplanWeb/src/app/services/category/category-service.ts new file mode 100644 index 0000000..f243b7d --- /dev/null +++ b/uniplanWeb/src/app/services/category/category-service.ts @@ -0,0 +1,26 @@ +import { Injectable, inject } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable,map } from 'rxjs'; +import { Category } from '../../core/interfaces/category'; +import { API_ENDPOINTS } from '../../config/endpoints'; + +@Injectable({ + providedIn: 'root' +}) + +export class CategoryService { + http = inject(HttpClient); + + getCategories(): Observable { + return this.http.get(API_ENDPOINTS.categories).pipe( + map((categories) => + categories.map((category, index) => ({ + id: category.id, + roomType: category.roomType, + capacity: category.capacity, + position: index + 1, + })) + ) + ); + } +} diff --git a/uniplanWeb/src/app/services/login-auth-service.spec.ts b/uniplanWeb/src/app/services/login/login-auth-service.spec.ts similarity index 87% rename from uniplanWeb/src/app/services/login-auth-service.spec.ts rename to uniplanWeb/src/app/services/login/login-auth-service.spec.ts index 66e46d1..5bc3bbf 100644 --- a/uniplanWeb/src/app/services/login-auth-service.spec.ts +++ b/uniplanWeb/src/app/services/login/login-auth-service.spec.ts @@ -1,7 +1,7 @@ import { TestBed } from '@angular/core/testing'; import { translateTestingProviders } from '@testing/translate-testing'; -import { LoginAuthService } from '../services/login-auth-service'; +import { LoginAuthService } from './login-auth-service'; describe('LoginAuthService', () => { let service: LoginAuthService; diff --git a/uniplanWeb/src/app/services/login-auth-service.ts b/uniplanWeb/src/app/services/login/login-auth-service.ts similarity index 100% rename from uniplanWeb/src/app/services/login-auth-service.ts rename to uniplanWeb/src/app/services/login/login-auth-service.ts