Fix categories loading in side menu component.
This commit is contained in:
@@ -18,6 +18,6 @@ public interface CategoryRepository extends JpaRepository<CategoryEntity, UUID>
|
|||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
boolean existsAnyAssociatedPublication(@Param("categoryId") UUID categoryId);
|
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<CategoryEntity> findAll();
|
List<CategoryEntity> findAll();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
<div class="category {{category.isOpenned ? 'openned' : ''}}" *ngFor="let category of categories$ | async">
|
@for(category of categories$ | async; track category) {
|
||||||
|
<div class="category {{category.isOpenned ? 'openned' : ''}}">
|
||||||
<div id="category-{{category.id}}" class="category-header" (click)="setOpenned(category)">
|
<div id="category-{{category.id}}" class="category-header" (click)="setOpenned(category)">
|
||||||
{{category.name}}
|
{{category.name}}
|
||||||
<mat-icon>chevron_right</mat-icon>
|
<mat-icon>chevron_right</mat-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-category-container {{category.isOpenned ? 'displayed' : ''}}">
|
<div class="sub-category-container {{category.isOpenned ? 'displayed' : ''}}">
|
||||||
<a [routerLink]="['/']" class="sub-category" *ngFor="let subCategory of category.subCategories">
|
@for(subCategory of category.subCategories; track subCategory) {
|
||||||
|
<a [routerLink]="['/categories/' + subCategory.id]" class="sub-category">
|
||||||
{{subCategory.name}}
|
{{subCategory.name}}
|
||||||
</a>
|
</a>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { CommonModule } from "@angular/common";
|
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 { MatIconModule } from "@angular/material/icon";
|
||||||
import { DisplayableCategory, SideMenuService } from "../side-menu.service";
|
import { DisplayableCategory, SideMenuService } from "../side-menu.service";
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
@@ -12,9 +12,13 @@ import { RouterModule } from "@angular/router";
|
|||||||
templateUrl: './categories-menu.component.html',
|
templateUrl: './categories-menu.component.html',
|
||||||
styleUrl: './categories-menu.component.scss'
|
styleUrl: './categories-menu.component.scss'
|
||||||
})
|
})
|
||||||
export class CategoriesMenuComponent {
|
export class CategoriesMenuComponent implements OnInit {
|
||||||
private sideMenuService = inject(SideMenuService);
|
private sideMenuService = inject(SideMenuService);
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.sideMenuService.loadCategories();
|
||||||
|
}
|
||||||
|
|
||||||
get categories$(): Observable<DisplayableCategory[]> {
|
get categories$(): Observable<DisplayableCategory[]> {
|
||||||
return this.sideMenuService.categories$;
|
return this.sideMenuService.categories$;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {Component} from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import {MatIconModule} from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import {CategoriesMenuComponent} from './categories-menu/categories-menu.component';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import {MatTooltipModule} from '@angular/material/tooltip';
|
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { CategoriesMenuComponent } from './categories-menu/categories-menu.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-side-menu',
|
selector: 'app-side-menu',
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { Injectable, OnDestroy, inject } from '@angular/core';
|
|||||||
import { CategoryService } from '../../core/service/category.service';
|
import { CategoryService } from '../../core/service/category.service';
|
||||||
import { BehaviorSubject, Observable, Subscription, map } from 'rxjs';
|
import { BehaviorSubject, Observable, Subscription, map } from 'rxjs';
|
||||||
import { Category } from '../../core/rest-services/category/model/category';
|
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 {
|
export interface DisplayableCategory {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -19,26 +21,28 @@ export interface DisplayableSubCategory {
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class SideMenuService implements OnDestroy {
|
export class SideMenuService implements OnDestroy {
|
||||||
private categoryService = inject(CategoryService);
|
private categoryRestService = inject(CategoryRestService);
|
||||||
|
private snackBar = inject(MatSnackBar);
|
||||||
private categoriesSubject = new BehaviorSubject<DisplayableCategory[]>([]);
|
private categoriesSubject = new BehaviorSubject<DisplayableCategory[]>([]);
|
||||||
private categoriesSubscription: Subscription | undefined;
|
private isLoadingSubject = new BehaviorSubject<boolean>(false);
|
||||||
|
private isLoadedSubject = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.categoriesSubscription = this.categoryService.categories$
|
// this.categoriesSubscription = this.categoryService.categories$
|
||||||
.pipe(
|
// .pipe(
|
||||||
map(categories =>
|
// map(categories =>
|
||||||
categories
|
// categories
|
||||||
.filter(category => category.subCategories?.length)
|
// .filter(category => category.subCategories?.length)
|
||||||
.map(category =>
|
// .map(category =>
|
||||||
this.mapToDisplayableCategory(category)
|
// this.mapToDisplayableCategory(category)
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
.subscribe(categories => this.categoriesSubject.next(categories));
|
// .subscribe(categories => this.categoriesSubject.next(categories));
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.categoriesSubscription?.unsubscribe();
|
// this.categoriesSubscription?.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
private mapToDisplayableCategory(category: Category): DisplayableCategory {
|
private mapToDisplayableCategory(category: Category): DisplayableCategory {
|
||||||
@@ -57,10 +61,6 @@ export class SideMenuService implements OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get categories$(): Observable<DisplayableCategory[]> {
|
|
||||||
return this.categoriesSubject.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
private get categories(): DisplayableCategory[] {
|
private get categories(): DisplayableCategory[] {
|
||||||
return this.categoriesSubject.value;
|
return this.categoriesSubject.value;
|
||||||
}
|
}
|
||||||
@@ -69,6 +69,36 @@ export class SideMenuService implements OnDestroy {
|
|||||||
this.categoriesSubject.next(categories);
|
this.categoriesSubject.next(categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get categories$(): Observable<DisplayableCategory[]> {
|
||||||
|
return this.categoriesSubject.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
get isLoading$(): Observable<boolean> {
|
||||||
|
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 {
|
setOpenned(category: DisplayableCategory): void {
|
||||||
const categories = this.categories;
|
const categories = this.categories;
|
||||||
const matchingCategory = categories.find(categoryTemp => categoryTemp.id === category.id);
|
const matchingCategory = categories.find(categoryTemp => categoryTemp.id === category.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user