Convert observables to signals.
This commit is contained in:
+17
-17
@@ -1,18 +1,18 @@
|
||||
@for(category of categories$ | async; track category) {
|
||||
<div class="category {{category.isOpenned ? 'openned' : ''}}">
|
||||
<div id="category-{{category.id}}" class="category-header" (click)="setOpenned(category)">
|
||||
{{category.name}}
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
</div>
|
||||
<div class="sub-category-container {{category.isOpenned ? 'displayed' : ''}}">
|
||||
@for(subCategory of category.subCategories; track subCategory) {
|
||||
<a [routerLink]="['/publications']"
|
||||
[queryParams]="{'category-id': subCategory.id}"
|
||||
(click)="categoryClicked.emit()"
|
||||
class="sub-category">
|
||||
{{subCategory.name}}
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
@for (category of categories$ | async; track category) {
|
||||
<div class="category {{category.isOpenned ? 'openned' : ''}}">
|
||||
<div id="category-{{category.id}}" class="category-header" (click)="setOpenned(category)">
|
||||
{{ category.name }}
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
</div>
|
||||
}
|
||||
<div class="sub-category-container {{category.isOpenned ? 'displayed' : ''}}">
|
||||
@for (subCategory of category.subCategories; track subCategory) {
|
||||
<a [routerLink]="['/publications']"
|
||||
[queryParams]="{'category-id': subCategory.id}"
|
||||
(click)="categoryClicked.emit()"
|
||||
class="sub-category">
|
||||
{{ subCategory.name }}
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
+49
-49
@@ -1,57 +1,57 @@
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.category {
|
||||
.category {
|
||||
transition: background-color .2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: #5c6bc0;
|
||||
}
|
||||
|
||||
.category-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: .5em 1em;
|
||||
|
||||
mat-icon {
|
||||
transition: transform .2s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
&.openned {
|
||||
.category-header {
|
||||
mat-icon {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
.sub-category-container {
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-category-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
max-height: 0;
|
||||
transition: max-height .2s ease-in-out;
|
||||
background-color: #303f9f;
|
||||
|
||||
.sub-category {
|
||||
padding: .5em 1em .5em 2em;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: background-color .2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: #5c6bc0;
|
||||
}
|
||||
|
||||
.category-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: .5em 1em;
|
||||
|
||||
mat-icon {
|
||||
transition: transform .2s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
&.openned {
|
||||
.category-header {
|
||||
mat-icon {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
.sub-category-container {
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-category-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
max-height: 0;
|
||||
transition: max-height .2s ease-in-out;
|
||||
background-color: #303f9f;
|
||||
|
||||
.sub-category {
|
||||
padding: .5em 1em .5em 2em;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: background-color .2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
background-color: #5c6bc0;
|
||||
}
|
||||
}
|
||||
background-color: #5c6bc0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
-18
@@ -1,19 +1,19 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, EventEmitter, inject, OnInit, Output } from "@angular/core";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
import { DisplayableCategory, SideMenuService } from "../side-menu.service";
|
||||
import { Observable } from "rxjs";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {Component, EventEmitter, inject, OnInit, Output} from "@angular/core";
|
||||
import {MatIconModule} from "@angular/material/icon";
|
||||
import {DisplayableCategory, SideMenuService} from "../side-menu.service";
|
||||
import {Observable} from "rxjs";
|
||||
import {RouterModule} from "@angular/router";
|
||||
|
||||
@Component({
|
||||
selector: 'app-categories-menu',
|
||||
templateUrl: './categories-menu.component.html',
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
MatIconModule
|
||||
],
|
||||
styleUrl: './categories-menu.component.scss'
|
||||
selector: 'app-categories-menu',
|
||||
templateUrl: './categories-menu.component.html',
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
MatIconModule
|
||||
],
|
||||
styleUrl: './categories-menu.component.scss'
|
||||
})
|
||||
export class CategoriesMenuComponent implements OnInit {
|
||||
private sideMenuService = inject(SideMenuService);
|
||||
@@ -37,10 +37,10 @@ export class CategoriesMenuComponent implements OnInit {
|
||||
} else {
|
||||
const categoriesDivs = document.getElementsByClassName('category-header');
|
||||
Array.from(categoriesDivs)
|
||||
.map(category => category as HTMLElement)
|
||||
.map(category => category as HTMLElement)
|
||||
.forEach(categoryDiv => this.closeAccordion(categoryDiv));
|
||||
|
||||
const categoryDiv = document.getElementById(`category-${category.id}`);
|
||||
|
||||
const categoryDiv = document.getElementById(`category-${category.id}`);
|
||||
if (categoryDiv) {
|
||||
this.openAccordion(categoryDiv);
|
||||
}
|
||||
@@ -58,4 +58,4 @@ export class CategoriesMenuComponent implements OnInit {
|
||||
const divContent = categoryDiv?.nextElementSibling as HTMLElement;
|
||||
divContent.style.maxHeight = `${divContent.scrollHeight}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<div class="menu {{ isOpened ? 'displayed' : '' }}">
|
||||
<h1>
|
||||
<a [routerLink]="['/home']">
|
||||
<img src="assets/images/codiki.png" alt="logo"/>
|
||||
Codiki
|
||||
</a>
|
||||
<button type="button"
|
||||
(click)="close()"
|
||||
class="cod-button icon"
|
||||
matTooltip="Close the menu"
|
||||
matRipple
|
||||
i18n-matTooltip>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</h1>
|
||||
<h2 i18n>Categories</h2>
|
||||
<app-categories-menu (categoryClicked)="close()"></app-categories-menu>
|
||||
<div class="menu {{ isOpened() ? 'displayed' : '' }}">
|
||||
<h1>
|
||||
<a [routerLink]="['/home']">
|
||||
<img src="assets/images/codiki.png" alt="logo"/>
|
||||
Codiki
|
||||
</a>
|
||||
<button type="button"
|
||||
(click)="close()"
|
||||
class="cod-button icon"
|
||||
matTooltip="Close the menu"
|
||||
matRipple
|
||||
i18n-matTooltip>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</h1>
|
||||
<h2 i18n>Categories</h2>
|
||||
<app-categories-menu (categoryClicked)="close()"></app-categories-menu>
|
||||
</div>
|
||||
<div class="overlay {{ isOpened ? 'displayed' : ''}}" (click)="close()"></div>
|
||||
<div class="overlay {{ isOpened() ? 'displayed' : ''}}" (click)="close()"></div>
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
:host {
|
||||
.menu {
|
||||
.menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #3f51b5;
|
||||
color: white;
|
||||
|
||||
$categoriesMenuWidth: 20em;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: -$categoriesMenuWidth - 1em - 1;
|
||||
bottom: 0;
|
||||
transition: left .2s ease-in-out;
|
||||
width: $categoriesMenuWidth;
|
||||
z-index: 3;
|
||||
padding: 1em 0;
|
||||
|
||||
&.displayed {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 1em;
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #3f51b5;
|
||||
flex-direction: row;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
gap: .5em;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
|
||||
$categoriesMenuWidth: 20em;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: -$categoriesMenuWidth - 1em - 1;
|
||||
bottom: 0;
|
||||
transition: left .2s ease-in-out;
|
||||
width: $categoriesMenuWidth;
|
||||
z-index: 3;
|
||||
padding: 1em 0;
|
||||
|
||||
&.displayed {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 1em;
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
gap: .5em;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
|
||||
img {
|
||||
$imageSize: 1.2em;
|
||||
width: $imageSize;
|
||||
height: $imageSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding: 0 1em;
|
||||
img {
|
||||
$imageSize: 1.2em;
|
||||
width: $imageSize;
|
||||
height: $imageSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
opacity: .2;
|
||||
z-index: 2;
|
||||
|
||||
&.displayed {
|
||||
display: block;
|
||||
}
|
||||
h2 {
|
||||
padding: 0 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
opacity: .2;
|
||||
z-index: 2;
|
||||
|
||||
&.displayed {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import {Component, signal} 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';
|
||||
import { MatRippleModule } from '@angular/material/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';
|
||||
import {MatRippleModule} from '@angular/material/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-side-menu',
|
||||
templateUrl: './side-menu.component.html',
|
||||
styleUrl: './side-menu.component.scss',
|
||||
imports: [
|
||||
CategoriesMenuComponent,
|
||||
MatIconModule,
|
||||
MatRippleModule,
|
||||
MatTooltipModule,
|
||||
RouterModule
|
||||
]
|
||||
selector: 'app-side-menu',
|
||||
templateUrl: './side-menu.component.html',
|
||||
styleUrl: './side-menu.component.scss',
|
||||
imports: [
|
||||
CategoriesMenuComponent,
|
||||
MatIconModule,
|
||||
MatRippleModule,
|
||||
MatTooltipModule,
|
||||
RouterModule
|
||||
]
|
||||
})
|
||||
export class SideMenuComponent {
|
||||
isOpened = signal(false);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { CategoryRestService } from '../../core/rest-services/category/category.rest-service';
|
||||
import { Category } from '../../core/rest-services/category/model/category';
|
||||
import {inject, Injectable} from '@angular/core';
|
||||
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||
import {BehaviorSubject, Observable} from 'rxjs';
|
||||
import {CategoryRestService} from '../../core/rest-services/category/category.rest-service';
|
||||
import {Category} from '../../core/rest-services/category/model/category';
|
||||
|
||||
export interface DisplayableCategory {
|
||||
id: string;
|
||||
@@ -53,7 +53,7 @@ export class SideMenuService {
|
||||
get categories$(): Observable<DisplayableCategory[]> {
|
||||
return this.categoriesSubject.asObservable();
|
||||
}
|
||||
|
||||
|
||||
get isLoading$(): Observable<boolean> {
|
||||
return this.isLoadingSubject.asObservable();
|
||||
}
|
||||
@@ -72,7 +72,7 @@ export class SideMenuService {
|
||||
.catch(error => {
|
||||
const errorMessage = $localize`An error occured while loading categories.`;
|
||||
console.error(errorMessage, error);
|
||||
this.snackBar.open(errorMessage, $localize`Close`, { duration: 5000 });
|
||||
this.snackBar.open(errorMessage, $localize`Close`, {duration: 5000});
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoadingSubject.next(false);
|
||||
|
||||
Reference in New Issue
Block a user