191 lines
7.5 KiB
TypeScript
191 lines
7.5 KiB
TypeScript
import { CommonModule, Location } from "@angular/common";
|
|
import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, 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";
|
|
import { MatInputModule } from "@angular/material/input";
|
|
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
|
import { MatSelectModule } from "@angular/material/select";
|
|
import { MatTabsModule } from "@angular/material/tabs";
|
|
import { MatTooltipModule } from "@angular/material/tooltip";
|
|
import { map, Observable, of, Subscription } from "rxjs";
|
|
import { Category } from "../../core/rest-services/category/model/category";
|
|
import { Publication } from "../../core/rest-services/publications/model/publication";
|
|
import { CategoryService } from "../../core/service/category.service";
|
|
import { SubmitButtonComponent } from "../submit-button/submit-button.component";
|
|
import { PictureSelectionDialog } from "./picture-selection-dialog/picture-selection-dialog.component";
|
|
import { PublicationEditionService } from "./publication-edition.service";
|
|
|
|
@Component({
|
|
selector: 'app-publication-edition',
|
|
standalone: true,
|
|
templateUrl: './publication-edition.component.html',
|
|
styleUrl: './publication-edition.component.scss',
|
|
imports: [
|
|
CommonModule,
|
|
MatDialogModule,
|
|
MatIconModule,
|
|
MatInputModule,
|
|
MatProgressSpinnerModule,
|
|
MatSelectModule,
|
|
MatTabsModule,
|
|
MatTooltipModule,
|
|
PictureSelectionDialog,
|
|
ReactiveFormsModule,
|
|
SubmitButtonComponent
|
|
],
|
|
providers: [PublicationEditionService]
|
|
})
|
|
export class PublicationEditionComponent implements OnChanges, OnDestroy {
|
|
@Input()
|
|
publication!: Publication;
|
|
@Input()
|
|
title!: string;
|
|
@Input()
|
|
isSaving$: Observable<boolean> = of(false);
|
|
@Output()
|
|
publicationSave = new EventEmitter<Publication>();
|
|
|
|
publicationInEdition!: Publication;
|
|
private readonly categoryService = inject(CategoryService);
|
|
private readonly formBuilder = inject(FormBuilder);
|
|
private readonly location = inject(Location);
|
|
private readonly publicationEditionService = inject(PublicationEditionService);
|
|
private subscriptions: Subscription[] = [];
|
|
|
|
publicationEditionForm: FormGroup = this.formBuilder.group({
|
|
title: new FormControl<string | undefined>('', [Validators.required]),
|
|
description: new FormControl<string | undefined>('', [Validators.required]),
|
|
text: new FormControl<string | undefined>('', [Validators.required]),
|
|
illustrationId: new FormControl<string | undefined>('', [Validators.required]),
|
|
categoryId: new FormControl<string | undefined>('', [Validators.required])
|
|
});
|
|
|
|
get isLoading$(): Observable<boolean> {
|
|
return this.publicationEditionService.isLoading$;
|
|
}
|
|
|
|
get isPreviewing$(): Observable<boolean> {
|
|
return this.publicationEditionService.isPreviewing$;
|
|
}
|
|
|
|
get categories$(): Observable<Category[]> {
|
|
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();
|
|
|
|
this.publicationInEdition = this.publication;
|
|
this.publicationEditionService.init(this.publicationInEdition);
|
|
|
|
['title', 'description', 'text'].forEach(fieldName => {
|
|
const fieldSubscription = this.publicationEditionForm.controls[fieldName].valueChanges
|
|
.pipe(
|
|
map(value => value?.length ? value as string : '')
|
|
)
|
|
.subscribe(fieldValue => {
|
|
switch (fieldName) {
|
|
case 'title':
|
|
this.publicationEditionService.editTitle(fieldValue);
|
|
break;
|
|
case 'description':
|
|
this.publicationEditionService.editDescription(fieldValue);
|
|
break;
|
|
case 'text':
|
|
this.publicationEditionService.editText(fieldValue);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
});
|
|
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 => {
|
|
console.log(state.publication.parsedText.substring(0, 15));
|
|
this.publicationInEdition = state.publication;
|
|
this.publicationEditionForm.controls['title'].setValue(this.publicationInEdition.title, { emitEvent: false });
|
|
this.publicationEditionForm.controls['description'].setValue(this.publicationInEdition.description, { emitEvent: false });
|
|
this.publicationEditionForm.controls['text'].setValue(this.publicationInEdition.text, { emitEvent: false });
|
|
this.publicationEditionForm.controls['illustrationId'].setValue(this.publicationInEdition.illustrationId, { emitEvent: false });
|
|
this.publicationEditionForm.controls['categoryId'].setValue(this.publicationInEdition.categoryId, { emitEvent: false });
|
|
});
|
|
this.subscriptions.push(publicationSubscription);
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.subscriptions.forEach(subscription => subscription?.unsubscribe());
|
|
}
|
|
|
|
goPreviousLocation(): void {
|
|
this.location.back();
|
|
}
|
|
|
|
insertTitle(titleNumber: number): void {
|
|
this.publicationEditionService.insertTitle(titleNumber);
|
|
}
|
|
|
|
selectAPicture(): void {
|
|
this.publicationEditionService.selectAPicture();
|
|
}
|
|
|
|
insertLink(): void {
|
|
this.publicationEditionService.insertLink();
|
|
}
|
|
|
|
displayCodeBlockDialog(): void {
|
|
this.publicationEditionService.displayCodeBlockDialog();
|
|
}
|
|
|
|
save(): void {
|
|
this.publicationSave.emit(this.publicationInEdition);
|
|
}
|
|
|
|
displayPictureSectionDialog(): void {
|
|
this.publicationEditionService.displayPictureSectionDialog();
|
|
}
|
|
|
|
updateCursorPosition(event: KeyboardEvent | MouseEvent): void {
|
|
if (event.target) {
|
|
const textarea = event.target as HTMLTextAreaElement;
|
|
|
|
const positionStart = textarea.selectionStart;
|
|
const positionEnd = textarea.selectionEnd;
|
|
|
|
this.publicationEditionService.editCursorPosition(positionStart, positionEnd);
|
|
}
|
|
}
|
|
|
|
onTabChange(tabSelectedIndex: number): void {
|
|
if (tabSelectedIndex === 1) {
|
|
this.publicationEditionService.loadPreview();
|
|
}
|
|
}
|
|
} |