import { Location } from "@angular/common"; import { inject, Injectable, OnDestroy } from "@angular/core"; import { MatSnackBar } from "@angular/material/snack-bar"; import { ActivatedRoute } from "@angular/router"; import { BehaviorSubject, Observable, Subscription } from "rxjs"; import { Publication } from "../../core/rest-services/publications/model/publication"; import { PublicationRestService } from "../../core/rest-services/publications/publication.rest-service"; import { copy } from '../../core/utils/ObjectUtils'; import { MatDialog } from "@angular/material/dialog"; import { PictureSelectionDialog } from "./picture-selection-dialog/picture-selection-dialog.component"; const DEFAULT_PUBLICATION: Publication = { id: '', key: '', title: '', text: '', parsedText: '', description: '', creationDate: new Date(), illustrationId: '', categoryId: '', author: { id: '', name: '', image: '' } }; @Injectable() export class PublicationEditionService implements OnDestroy { private readonly activatedRoute = inject(ActivatedRoute); private readonly publicationRestService = inject(PublicationRestService); private readonly location = inject(Location); private readonly snackBar = inject(MatSnackBar); private readonly dialog = inject(MatDialog); private isLoadingSubject = new BehaviorSubject(false); private publicationSubject = new BehaviorSubject(copy(DEFAULT_PUBLICATION)); private subscriptions: Subscription[] = []; ngOnDestroy(): void { this.subscriptions.forEach(subscription => subscription.unsubscribe()); } private get _publication(): Publication { return this.publicationSubject.value; } private _save(publication: Publication): void { this.publicationSubject.next(publication); } get isLoading$(): Observable { return this.isLoadingSubject.asObservable(); } get publication$(): Observable { return this.publicationSubject.asObservable(); } loadPublication(): void { this.isLoadingSubject.next(true); this.activatedRoute.paramMap.subscribe(params => { const publicationId = params.get('publicationId'); if (publicationId == undefined) { this.snackBar.open('A technical error occurred while loading publication data.', 'Close', {duration: 5000}); this.location.back(); } else { this.publicationRestService.getById(publicationId) .then(publication => { this.publicationSubject.next(publication); }) .catch(error => { const errorMessage = 'A technical error occurred while loading publication data.'; this.snackBar.open(errorMessage, 'Close', {duration: 5000}); console.error(errorMessage, error) }) .finally(() => this.isLoadingSubject.next(false)); } }); } editTitle(title: string): void { const publication = this._publication; publication.title = title; this._save(publication); } editDescription(description: string): void { const publication = this._publication; publication.description = description; this._save(publication); } editText(text: string): void { const publication = this._publication; publication.text = text; this._save(publication); } editIllustrationId(pictureId: string): void { const publication = this._publication; publication.illustrationId = pictureId this._save(publication); } displayPictureSectionDialog(): void { const dialogRef = this.dialog.open(PictureSelectionDialog); const afterDialogCloseSubscription = dialogRef.afterClosed() .subscribe(newPictureId => { if (newPictureId) { this.editIllustrationId(newPictureId); } }); this.subscriptions.push(afterDialogCloseSubscription); } }