diff --git a/frontend/src/app/components/publication-edition/publication-edition.component.html b/frontend/src/app/components/publication-edition/publication-edition.component.html
index e4e2e01..d14b795 100644
--- a/frontend/src/app/components/publication-edition/publication-edition.component.html
+++ b/frontend/src/app/components/publication-edition/publication-edition.component.html
@@ -16,15 +16,22 @@
Description
+
+ Category
+
+ @for (category of categories$ | async; track category) {
+
+ {{ category.name }}
+
+ }
+
+
- @if (publication.illustrationId.length) {
-

- } @else {
-

- }
-
+
diff --git a/frontend/src/app/components/publication-edition/publication-edition.component.ts b/frontend/src/app/components/publication-edition/publication-edition.component.ts
index af690d4..53b8518 100644
--- a/frontend/src/app/components/publication-edition/publication-edition.component.ts
+++ b/frontend/src/app/components/publication-edition/publication-edition.component.ts
@@ -1,5 +1,5 @@
import { CommonModule, Location } from "@angular/common";
-import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, Output } from "@angular/core";
+import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, OnInit, Output } from "@angular/core";
import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms";
import { MatDialogModule } from "@angular/material/dialog";
import { MatIconModule } from "@angular/material/icon";
@@ -7,11 +7,14 @@ import { MatInputModule } from "@angular/material/input";
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
import { MatTabsModule } from "@angular/material/tabs";
import { MatTooltipModule } from "@angular/material/tooltip";
-import { map, Observable, of, Subscription } from "rxjs";
+import { filter, map, Observable, of, Subscription } from "rxjs";
import { Publication } from "../../core/rest-services/publications/model/publication";
import { PictureSelectionDialog } from "./picture-selection-dialog/picture-selection-dialog.component";
import { SubmitButtonComponent } from "../submit-button/submit-button.component";
import { PublicationEditionService } from "./publication-edition.service";
+import { MatSelectModule } from "@angular/material/select";
+import { CategoryService } from "../../core/service/category.service";
+import { Category } from "../../core/rest-services/category/model/category";
@Component({
selector: 'app-publication-edition',
@@ -24,6 +27,7 @@ import { PublicationEditionService } from "./publication-edition.service";
MatIconModule,
MatInputModule,
MatProgressSpinnerModule,
+ MatSelectModule,
MatTabsModule,
MatTooltipModule,
PictureSelectionDialog,
@@ -42,6 +46,7 @@ export class PublicationEditionComponent implements OnChanges, OnDestroy {
@Output()
publicationSave = new EventEmitter();
+ private readonly categoryService = inject(CategoryService);
private readonly formBuilder = inject(FormBuilder);
private readonly location = inject(Location);
private readonly publicationEditionService = inject(PublicationEditionService);
@@ -64,6 +69,30 @@ export class PublicationEditionComponent implements OnChanges, OnDestroy {
return this.publicationEditionService.isPreviewing$;
}
+ get categories$(): Observable {
+ return this.categoryService.categories$
+ .pipe(
+ map(categories =>
+ categories.filter(category => category.subCategories.length == 0)
+ .sort(this.byNameAscComparator())
+ )
+ );
+ }
+
+ private byNameAscComparator(): (categoryA: Category, categoryB: Category) => number {
+ return (categoryA, categoryB) => this.compareStrings(categoryA.name, categoryB.name);
+ }
+
+ private compareStrings(stringA: string, stringB: string): number {
+ if (stringA < stringB) {
+ return -1;
+ }
+ if (stringA > stringB) {
+ return 1;
+ }
+ return 0;
+ }
+
ngOnChanges(): void {
this.ngOnDestroy();
@@ -93,6 +122,12 @@ export class PublicationEditionComponent implements OnChanges, OnDestroy {
this.subscriptions.push(fieldSubscription);
});
+ const categoryIdChangeSubscription = this.publicationEditionForm.controls['categoryId'].valueChanges
+ .subscribe(newCategoryId => {
+ this.publicationEditionService.editCategoryId(newCategoryId);
+ });
+ this.subscriptions.push(categoryIdChangeSubscription);
+
const publicationSubscription = this.publicationEditionService.state$.subscribe(state => {
this.publicationInEdition = state.publication;
this.publicationEditionForm.controls['title'].setValue(this.publication.title, { emitEvent: false });
diff --git a/frontend/src/app/components/publication-edition/publication-edition.service.ts b/frontend/src/app/components/publication-edition/publication-edition.service.ts
index a1a9e80..1a144a7 100644
--- a/frontend/src/app/components/publication-edition/publication-edition.service.ts
+++ b/frontend/src/app/components/publication-edition/publication-edition.service.ts
@@ -139,6 +139,12 @@ export class PublicationEditionService implements OnDestroy {
this._save(state);
}
+ editCategoryId(categoryId: string): void {
+ const state = this._state;
+ state.publication.categoryId = categoryId;
+ this._save(state);
+ }
+
editText(text: string): void {
const state = this._state;
state.publication.text = text;
diff --git a/frontend/src/app/components/side-menu/side-menu.component.scss b/frontend/src/app/components/side-menu/side-menu.component.scss
index a2c1026..30a1a05 100644
--- a/frontend/src/app/components/side-menu/side-menu.component.scss
+++ b/frontend/src/app/components/side-menu/side-menu.component.scss
@@ -12,7 +12,7 @@
bottom: 0;
transition: left .2s ease-in-out;
width: $categoriesMenuWidth;
- z-index: 2;
+ z-index: 3;
padding: 1em 0;
&.displayed {
@@ -77,6 +77,7 @@
height: 100%;
background-color: #000;
opacity: .2;
+ z-index: 2;
&.displayed {
display: block;