import {CommonModule, Location} from "@angular/common"; import {Component, effect, inject, input, output, signal} from "@angular/core"; import {FormGroup, ReactiveFormsModule} 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} from "rxjs"; import {Category} from "../../core/rest-services/category/model/category"; import {DEFAULT_PUBLICATION, Publication} from "../../core/rest-services/publications/model/publication"; import {CategoryService} from "../../core/service/category.service"; import {SubmitButtonComponent} from "../submit-button/submit-button.component"; import {PublicationEditionService} from "./publication-edition.service"; import {MatRippleModule} from "@angular/material/core"; @Component({ selector: 'app-publication-edition', templateUrl: './publication-edition.component.html', styleUrl: './publication-edition.component.scss', imports: [ CommonModule, MatDialogModule, MatIconModule, MatInputModule, MatRippleModule, MatProgressSpinnerModule, MatSelectModule, MatTabsModule, MatTooltipModule, ReactiveFormsModule, SubmitButtonComponent ], providers: [PublicationEditionService] }) export class PublicationEditionComponent { readonly #categoryService = inject(CategoryService); readonly #location = inject(Location); readonly #publicationEditionService = inject(PublicationEditionService); publication = input.required(); title = input.required(); isSaving = input.required(); publicationSave = output(); isLoading = this.#publicationEditionService.isLoading; isPreviewing = this.#publicationEditionService.isPreviewing; publicationInEdition = signal(DEFAULT_PUBLICATION); constructor() { effect(() => { let publication = this.publication(); const publicationInEdition = this.publicationInEdition(); if (!publicationInEdition || publicationInEdition !== publication) { this.publicationInEdition.set(publication); this.#publicationEditionService.init(publication); } }); } get publicationEditionForm(): FormGroup { return this.#publicationEditionService.publicationEditionForm; } 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; } 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(); } 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); } } save(): void { this.publicationSave.emit(this.#publicationEditionService.editedPublication); } onTabChange(tabSelectedIndex: number): void { if (tabSelectedIndex === 1) { this.#publicationEditionService.loadPreview(); } } }