From d9b856bd4312f263e8b23b677287f6e90ad8a7a1 Mon Sep 17 00:00:00 2001 From: Florian THIERRY Date: Thu, 29 Aug 2024 11:09:39 +0200 Subject: [PATCH] Fix categories loading in side menu component. --- .../repository/CategoryRepository.java | 2 +- .../categories-menu.component.html | 24 ++++--- .../categories-menu.component.ts | 8 ++- .../side-menu/side-menu.component.ts | 8 +-- .../components/side-menu/side-menu.service.ts | 66 ++++++++++++++----- .../src/app/core/service/category.service.ts | 4 +- 6 files changed, 75 insertions(+), 37 deletions(-) diff --git a/backend/codiki-infrastructure/src/main/java/org/codiki/infrastructure/category/repository/CategoryRepository.java b/backend/codiki-infrastructure/src/main/java/org/codiki/infrastructure/category/repository/CategoryRepository.java index bd152b0..ea081ef 100644 --- a/backend/codiki-infrastructure/src/main/java/org/codiki/infrastructure/category/repository/CategoryRepository.java +++ b/backend/codiki-infrastructure/src/main/java/org/codiki/infrastructure/category/repository/CategoryRepository.java @@ -18,6 +18,6 @@ public interface CategoryRepository extends JpaRepository """, nativeQuery = true) boolean existsAnyAssociatedPublication(@Param("categoryId") UUID categoryId); - @Query("SELECT c FROM CategoryEntity c JOIN FETCH c.subCategories") + @Query("SELECT c FROM CategoryEntity c LEFT JOIN FETCH c.subCategories") List findAll(); } diff --git a/frontend/src/app/components/side-menu/categories-menu/categories-menu.component.html b/frontend/src/app/components/side-menu/categories-menu/categories-menu.component.html index d32e9b0..e32d421 100644 --- a/frontend/src/app/components/side-menu/categories-menu/categories-menu.component.html +++ b/frontend/src/app/components/side-menu/categories-menu/categories-menu.component.html @@ -1,11 +1,15 @@ -
-
- {{category.name}} - chevron_right +@for(category of categories$ | async; track category) { +
+
+ {{category.name}} + chevron_right +
+
+ @for(subCategory of category.subCategories; track subCategory) { + + {{subCategory.name}} + + } +
- -
\ No newline at end of file +} \ No newline at end of file diff --git a/frontend/src/app/components/side-menu/categories-menu/categories-menu.component.ts b/frontend/src/app/components/side-menu/categories-menu/categories-menu.component.ts index 618543d..6a6c408 100644 --- a/frontend/src/app/components/side-menu/categories-menu/categories-menu.component.ts +++ b/frontend/src/app/components/side-menu/categories-menu/categories-menu.component.ts @@ -1,5 +1,5 @@ import { CommonModule } from "@angular/common"; -import { Component, inject } from "@angular/core"; +import { Component, inject, OnInit } from "@angular/core"; import { MatIconModule } from "@angular/material/icon"; import { DisplayableCategory, SideMenuService } from "../side-menu.service"; import { Observable } from "rxjs"; @@ -12,9 +12,13 @@ import { RouterModule } from "@angular/router"; templateUrl: './categories-menu.component.html', styleUrl: './categories-menu.component.scss' }) -export class CategoriesMenuComponent { +export class CategoriesMenuComponent implements OnInit { private sideMenuService = inject(SideMenuService); + ngOnInit(): void { + this.sideMenuService.loadCategories(); + } + get categories$(): Observable { return this.sideMenuService.categories$; } diff --git a/frontend/src/app/components/side-menu/side-menu.component.ts b/frontend/src/app/components/side-menu/side-menu.component.ts index 68fa2cd..b9133ac 100644 --- a/frontend/src/app/components/side-menu/side-menu.component.ts +++ b/frontend/src/app/components/side-menu/side-menu.component.ts @@ -1,8 +1,8 @@ -import {Component} from '@angular/core'; -import {MatIconModule} from '@angular/material/icon'; -import {CategoriesMenuComponent} from './categories-menu/categories-menu.component'; -import {MatTooltipModule} from '@angular/material/tooltip'; +import { Component } from '@angular/core'; +import { MatIconModule } from '@angular/material/icon'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { RouterModule } from '@angular/router'; +import { CategoriesMenuComponent } from './categories-menu/categories-menu.component'; @Component({ selector: 'app-side-menu', diff --git a/frontend/src/app/components/side-menu/side-menu.service.ts b/frontend/src/app/components/side-menu/side-menu.service.ts index bf4ce5b..10f60af 100644 --- a/frontend/src/app/components/side-menu/side-menu.service.ts +++ b/frontend/src/app/components/side-menu/side-menu.service.ts @@ -2,6 +2,8 @@ import { Injectable, OnDestroy, inject } from '@angular/core'; import { CategoryService } from '../../core/service/category.service'; import { BehaviorSubject, Observable, Subscription, map } from 'rxjs'; import { Category } from '../../core/rest-services/category/model/category'; +import { CategoryRestService } from '../../core/rest-services/category/category.rest-service'; +import { MatSnackBar } from '@angular/material/snack-bar'; export interface DisplayableCategory { id: string; @@ -19,26 +21,28 @@ export interface DisplayableSubCategory { providedIn: 'root' }) export class SideMenuService implements OnDestroy { - private categoryService = inject(CategoryService); + private categoryRestService = inject(CategoryRestService); + private snackBar = inject(MatSnackBar); private categoriesSubject = new BehaviorSubject([]); - private categoriesSubscription: Subscription | undefined; + private isLoadingSubject = new BehaviorSubject(false); + private isLoadedSubject = new BehaviorSubject(false); constructor() { - this.categoriesSubscription = this.categoryService.categories$ - .pipe( - map(categories => - categories - .filter(category => category.subCategories?.length) - .map(category => - this.mapToDisplayableCategory(category) - ) - ) - ) - .subscribe(categories => this.categoriesSubject.next(categories)); + // this.categoriesSubscription = this.categoryService.categories$ + // .pipe( + // map(categories => + // categories + // .filter(category => category.subCategories?.length) + // .map(category => + // this.mapToDisplayableCategory(category) + // ) + // ) + // ) + // .subscribe(categories => this.categoriesSubject.next(categories)); } ngOnDestroy(): void { - this.categoriesSubscription?.unsubscribe(); + // this.categoriesSubscription?.unsubscribe(); } private mapToDisplayableCategory(category: Category): DisplayableCategory { @@ -57,10 +61,6 @@ export class SideMenuService implements OnDestroy { } } - get categories$(): Observable { - return this.categoriesSubject.asObservable(); - } - private get categories(): DisplayableCategory[] { return this.categoriesSubject.value; } @@ -69,6 +69,36 @@ export class SideMenuService implements OnDestroy { this.categoriesSubject.next(categories); } + get categories$(): Observable { + return this.categoriesSubject.asObservable(); + } + + get isLoading$(): Observable { + return this.isLoadingSubject.asObservable(); + } + + loadCategories(): void { + this.isLoadingSubject.next(true); + this.isLoadedSubject.next(false); + + this.categoryRestService.getCategories() + .then(categories => { + const displayableCategories = categories + .filter(category => category.subCategories?.length) + .map(category => this.mapToDisplayableCategory(category)); + this.categoriesSubject.next(displayableCategories); + }) + .catch(error => { + const errorMessage = "An error occured while loading categories."; + console.error(errorMessage, error); + this.snackBar.open(errorMessage, 'Close', { duration: 5000 }); + }) + .finally(() => { + this.isLoadingSubject.next(false); + this.isLoadedSubject.next(true); + }); + } + setOpenned(category: DisplayableCategory): void { const categories = this.categories; const matchingCategory = categories.find(categoryTemp => categoryTemp.id === category.id); diff --git a/frontend/src/app/core/service/category.service.ts b/frontend/src/app/core/service/category.service.ts index 1ba3429..3593dca 100644 --- a/frontend/src/app/core/service/category.service.ts +++ b/frontend/src/app/core/service/category.service.ts @@ -17,8 +17,8 @@ export class CategoryService { get categories$(): Observable { if (!this.categories?.length) { this.categoryRestService.getCategories() - .then(categories => this.categoriesSubject.next(categories)) - .catch(error => console.error('An error occured while loading categories.', error)); + .then(categories => this.categoriesSubject.next(categories)) + .catch(error => console.error('An error occured while loading categories.', error)); } return this.categoriesSubject.asObservable(); }