import {inject, Injectable, Signal, signal} from '@angular/core'; import {MatSnackBar} from '@angular/material/snack-bar'; import {CategoryRestService} from '../../core/rest-services/category/category.rest-service'; import {Category} from '../../core/rest-services/category/model/category'; export interface DisplayableCategory { id: string; name: string; subCategories: DisplayableSubCategory[]; isOpenned: boolean; } export interface DisplayableSubCategory { id: string; name: string; } @Injectable({ providedIn: 'root' }) export class SideMenuService { readonly #categoryRestService = inject(CategoryRestService); readonly #snackBar = inject(MatSnackBar); #categories = signal([]); #isLoading = signal(false); isLoaded = signal(false); #mapToDisplayableCategory(category: Category): DisplayableCategory { return { id: category.id, name: category.name, subCategories: category.subCategories.map(subCategory => this.#mapToDisplayableSubCategory(subCategory)), isOpenned: false }; } #mapToDisplayableSubCategory(subCategory: Category): DisplayableSubCategory { return { id: subCategory.id, name: subCategory.name } } get categories(): Signal { return this.#categories.asReadonly(); } get isLoading(): Signal { return this.#isLoading.asReadonly(); } loadCategories(): void { this.#isLoading.set(true); this.isLoaded.set(false); this.#categoryRestService.getCategories() .then(categories => { const displayableCategories = categories .filter(category => category.subCategories?.length) .map(category => this.#mapToDisplayableCategory(category)); this.#categories.set(displayableCategories); }) .catch(error => { const errorMessage = $localize`An error occured while loading categories.`; console.error(errorMessage, error); this.#snackBar.open(errorMessage, $localize`Close`, {duration: 5000}); }) .finally(() => { this.#isLoading.set(false); this.isLoaded.set(true); }); } setOpened(category: DisplayableCategory): void { const categories = this.#categories(); const matchingCategory = categories.find(categoryTemp => categoryTemp.id === category.id); if (matchingCategory) { const actualOpennedCategory = categories.find(category => category.isOpenned); if (actualOpennedCategory && actualOpennedCategory.id === matchingCategory.id) { matchingCategory.isOpenned = false; } else { categories.forEach(categoryTemp => categoryTemp.isOpenned = false); matchingCategory.isOpenned = true; } this.#categories.set(categories); } } }