Vai al contenuto

Progetti — Dettaglio

La pagina Dettaglio progetto (/dashboard/projects/:id) espone metadati, stato del progetto, membri e storico modifiche di un progetto.

Esperienza utente

Sezioni

Sezione Contenuto
Header Nome, stato, azioni (menu contestuale)
Informazioni Dati anagrafici progetto
Stato del progetto Collaborazione, tipo cliente e campi di classificazione
Membri Persone assegnate con ruolo e date
Storico Log delle modifiche al progetto

Cosa si può fare

  • Consultare tutte le sezioni (qualsiasi utente autorizzato può aprire la route)
  • Modificare informazioni, stato del progetto e membri: chi ha canManageProjects()
  • Aggiungere/rimuovere membri con tracciamento nello storico
  • Eliminare il progetto (con conferma): stesso permesso di gestione

Stato del progetto — campi

Card ProjectCollaborationComponent (titolo UI: Stato del progetto). In sola lettura per tutti; in modifica con lo stesso bottone se canManageProjects().

Campo Valori UI Note
Tipo di collaborazione da catalogo collaboration types Editabile
Tipo cliente Bronze / Silver / Gold Editabile
Business Alto / Medio / Basso API: HIGH / MEDIUM / LOW
People Alto / Medio / Basso (o -) Solo lettura — calcolato dal backend
Type PO / PM Editabile
Team Seniority Alto / Medio / Basso Editabile
Livello Supporto PO Alto / Medio / Basso Editabile
Interazione PO Alto / Medio / Basso Editabile
Operatività SM Sì / No Editabile (smOperativity boolean)

Il tag rosa «Completa le informazioni» resta legato solo a tipo collaborazione e tipo cliente mancanti (non ai nuovi campi).

Chi può accedere

  • Lettura: tutti gli utenti in dashboard
  • Scrittura (edit card, membri, delete): PoliciesService.canManageProjects() (projects.create | update | delete)

Vedi Accesso e ruoli.

Dettaglio tecnico

Resolver e primo caricamento

La route projects/:id è protetta da projectDetailResolver, che esegue GET /projects/:id prima dell'attivazione del componente:

flowchart TD
  RES[projectDetailResolver\nGET /projects/:id] -->|successo| D[ProjectDetailComponent\n+ BreadcrumbComponent\nlegge data.project]
  RES -->|errore| E[Toast + Redirect /dashboard/projects]
  • ProjectDetailComponent legge il dato iniziale da route.snapshot.data['project']: nessuna GET duplicata al primo rendering.
  • BreadcrumbComponent legge data.project.name iniettato dal resolver: nessuna chiamata HTTP separata per il nome.
  • Le mutazioni successive (update campi, membri, delete) continuano ad eseguire le proprie chiamate HTTP per aggiornare lo stato locale.

Il resolver è prodotto dalla factory condivisa createDetailResolver (src/utils/resolver-factory.ts), che gestisce in modo uniforme: estrazione id da paramMap, redirect con toast in caso di errore, e take(1) per completare l'observable.

Permessi senza route guard

A differenza del dettaglio team, non esiste un canActivate sulla route :id. Il controllo avviene in UI via PoliciesService:

havePermissionOnProject = computed(() => this.policiesService.canManageProjects());

Pulsanti di modifica, dialog e voci di menu sono disabilitati o nascosti senza le write policies progetto.

Campo people (auto-calcolo backend)

Il frontend non invia people in create/update. Il backend lo ricalcola su ogni create/update a partire dai membri in persons, escludendo Product Owner e Scrum Master se presenti nella lista:

Membri team (senza PO/SM) people
0 null
1–3 LOW
4–7 MEDIUM
8+ HIGH

In UI il valore è formattato con formatProjectLevel() (Alto / Medio / Basso / -). Dopo add/remove membri o cambio PO/SM, il dettaglio si aggiorna dal response API.

Update stato del progetto

project-detail gestisce un unico updateCollaborationForm e un PUT via ProjectService.updateProject con payload parziale (UpdateProjectPayload). I campi livello/type/smOperativity possono essere azzerati a null; collaborazione e tipo cliente seguono il comportamento preesistente (non clear-to-null dal form).

Storico membri e actionEnum

Le modifiche ai membri generano voci nello storico con actionEnum (aggiunta, rimozione, aggiornamento). Il componente calcola il diff tra stato precedente e nuovo payload prima di inviare l'update a ProjectService.

Dialog e conferme

Azione Componente
Aggiorna progetto ProjectUpdateDialogComponent
Aggiungi membro ProjectAddMemberComponent
Elimina progetto CommonConfirmDialogComponent

Come per i team, il query param from supporta breadcrumb di ritorno verso il dettaglio utente o altre origini (UserDetailNavigationState).

File principali

File Ruolo
src/pages/project-detail/project-detail.component.ts Orchestrazione, form stato progetto, permessi UI
src/components/project-detail/project-collaboration/ Card Stato del progetto
src/components/project-detail/ Sezioni, dialog, storico
src/services/project.service.ts API lifecycle progetto
src/models/project.ts ProjectLevel, ProjectType, payload create/update
src/utils/project.ts formatProjectLevel, formatSmOperativity
src/resolvers/project-detail.resolver.ts Pre-fetch GET /projects/:id prima dell'attivazione
src/utils/resolver-factory.ts Factory condivisa per resolver di dettaglio