import { Component, computed, inject, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import Keycloak from 'keycloak-js'; import { KEYCLOAK_EVENT_SIGNAL } from 'keycloak-angular'; import { MODERATORE_ROLE, extractRealmRoles } from '../../core/auth/roles'; import { Attivita, Paragrafo } from '../../core/models/attivita.model'; import { AttivitaService } from '../../core/services/attivita'; import { formatData, parseMarkdown, statoStyle } from '../../core/utils/stato-style'; @Component({ selector: 'app-detail', imports: [], templateUrl: './detail.html', styleUrl: './detail.css', }) export class Detail { private readonly route = inject(ActivatedRoute); private readonly attivitaService = inject(AttivitaService); private readonly keycloak = inject(Keycloak); private readonly keycloakEvent = inject(KEYCLOAK_EVENT_SIGNAL); readonly attivita = signal(null); readonly caricamento = signal(true); readonly testoCommento = signal(''); readonly azioneInCorso = signal(false); readonly dataModificaFmt = computed(() => formatData(this.attivita()?.dataModifica)); readonly statoTextColor = computed(() => statoStyle(this.attivita()?.stato.id ?? 'BO').color); readonly brancaNomi = computed(() => (this.attivita()?.brancaList ?? []).map((b) => b.nome).join(', ')); readonly paragrafiOrdinati = computed(() => [...(this.attivita()?.paragrafoList ?? [])].sort((a, b) => a.ordine - b.ordine) ); readonly isModeratore = computed(() => { this.keycloakEvent(); return extractRealmRoles(this.keycloak.tokenParsed).includes(MODERATORE_ROLE); }); readonly puoModerare = computed( () => this.isModeratore() && this.attivita()?.stato.id === 'IA', ); readonly puoCancellareNote = computed( () => this.isModeratore() && this.attivita()?.stato.id === 'PU', ); constructor() { this.caricaAttivita(); } private caricaAttivita(): void { const idAttivita = Number(this.route.snapshot.paramMap.get('idAttivita')); this.caricamento.set(true); this.attivitaService.getOne(idAttivita).subscribe({ next: (attivita) => { this.attivita.set(attivita); this.caricamento.set(false); }, error: () => this.caricamento.set(false), }); } isTitolo(paragrafo: Paragrafo): boolean { return paragrafo.tipo.id === 'TITOLO'; } tokens(paragrafo: Paragrafo) { return parseMarkdown(paragrafo.corpo); } formatNotaData(data: string): string { return formatData(data); } approva(): void { const attivita = this.attivita(); if (!attivita?.id || this.azioneInCorso()) return; this.azioneInCorso.set(true); this.attivitaService.approva(attivita.id).subscribe({ next: () => { this.azioneInCorso.set(false); this.caricaAttivita(); }, error: () => this.azioneInCorso.set(false), }); } commenta(): void { const attivita = this.attivita(); const testo = this.testoCommento().trim(); if (!attivita?.id || !testo || this.azioneInCorso()) return; this.azioneInCorso.set(true); this.attivitaService.commenta(attivita.id, testo).subscribe({ next: () => { this.azioneInCorso.set(false); this.testoCommento.set(''); this.caricaAttivita(); }, error: () => this.azioneInCorso.set(false), }); } eliminaNota(idNota: number): void { this.attivitaService.eliminaNota(idNota).subscribe(() => this.caricaAttivita()); } }