110 lines
3.4 KiB
TypeScript
110 lines
3.4 KiB
TypeScript
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<Attivita | null>(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());
|
|
}
|
|
}
|