Vai al contenuto

FAQ

La pagina FAQ (/dashboard/faq) espone articoli di aiuto pubblicati dal CMS interno, organizzati per Topic/Categoria con ricerca full-text. Executive ed Executive Support possono inoltre creare, modificare ed eliminare gli articoli direttamente dalla pagina.

Esperienza utente

Cosa si può fare

  • Sfogliare gli articoli in vista Indice, a scelta come lista o come griglia di card (toggle persistito in localStorage)
  • Filtrare per Topic tramite chip a selezione singola (una sola chip attiva alla volta, chip "Tutte" per rimuovere il filtro)
  • Cercare per titolo, descrizione o categoria (debounce 300ms); ricerca e filtro Topic si combinano in AND
  • Aprire il dettaglio di un articolo cliccandolo: titolo, data di creazione/aggiornamento, badge categoria, corpo HTML sanificato
  • Creare, modificare ed eliminare articoli (solo utenti con i permessi adeguati, vedi sotto)

Indice → Dettaglio

A differenza di altre pagine dell'app, la FAQ non ha una route per-articolo: l'indice e il dettaglio sono due stati (view: 'index' | 'detail') dello stesso componente, senza cambio di URL.

Editing

Visibile solo a chi ha i permessi di scrittura (vedi Chi può accedere):

  • Nuova FAQ — bottone in toolbar sopra l'indice, apre il form in modalità creazione
  • Modifica — bottone nel dettaglio, attiva il form inline sullo stesso articolo
  • Elimina — bottone nel dettaglio, richiede conferma in un dialog prima di procedere

Campi del form:

Campo Componente Note
Topic app-select-button Obbligatorio. Cambiandolo, la Categoria si resetta se non più valida per il nuovo Topic
Categoria app-select-button Obbligatorio. Opzioni filtrate sul Topic selezionato (category.idTopic)
Domanda app-input-text Obbligatorio
Risposta app-rich-text-editor Obbligatorio. Formattazione limitata a grassetto, corsivo, elenco puntato, link
Stato app-select-button (Bozza / Pubblicata) Obbligatorio. Default Bozza per una nuova FAQ — l'indice di sola lettura mostra solo gli articoli Pubblicati

Validazione con Reactive Forms (Validators.required), errori mostrati solo dopo il primo tentativo di submit (hasSubmitted).

Fuori scope in questa iterazione (decisione esplicita): nessun riordino drag-and-drop degli articoli (il backend non espone un campo position né un endpoint di ordinamento per /contents, a differenza di /home-contents che ce l'ha); nessun tag libero multiplo (il modello reale usa la gerarchia Topic → Categoria, non un campo tag).

Chi può accedere

  • Lettura: tutti gli utenti autorizzati. Vengono mostrati solo contenuti con stato Pubblicata.
  • Scrittura (creazione/modifica/eliminazione): utenti la cui policy include contents.create / contents.update / contents.delete rispettivamente — enforcement reale lato backend (GET /v1/auth/policies), tipicamente assegnata a Executive ed Executive Support. Il markup usa la direttiva *appPolicy esistente (non isExecutive()/RoleEnum come altre pagine); vedi Accesso e ruoli per il quadro generale dei due sistemi di permessi.

Dettaglio tecnico

API

Operazione Servizio Endpoint / Lambda
Lista contenuti FaqService.getContents() GET /v1/contents (lambda cms)
Crea contenuto FaqService.createContent() POST /v1/contents
Aggiorna contenuto FaqService.updateContent() PUT /v1/contents/:id
Elimina contenuto FaqService.deleteContent() DELETE /v1/contents/:id
Lista topic TopicService.getTopics() GET /v1/topics
Lista categorie CategoryService.getCategories() GET /v1/categories

Filtraggio per stato pubblicato e per Topic/ricerca è lato client.

Cascata Topic → Categoria

flowchart LR
  A[Utente seleziona Topic] --> B[categoriesForSelectedTopic\ncomputed su idTopic]
  B --> C{Categoria corrente\nancora valida?}
  C -->|Sì| D[Nessuna azione]
  C -->|No| E[Reset campo Categoria]

Sanitizzazione HTML

Il corpo degli articoli (in lettura) passa per DomSanitizer.sanitize(SecurityContext.HTML, ...) prima del render. In editing, app-rich-text-editor produce HTML compatibile con lo stesso campo description.

Ricerca

searchSubject con debounceTime e distinctUntilChanged alimenta il computed filteredContents, combinato con il filtro Topic (activeTopicId).

File principali

File Ruolo
src/pages/faq/faq.component.ts UI indice/dettaglio, ricerca, filtro Topic, form di editing
src/services/faq.service.ts CRUD /v1/contents
src/services/topic.service.ts Lettura /v1/topics
src/services/category.service.ts Lettura /v1/categories
src/models/content.ts Content, Topic, Category, CreateContentPayload, UpdateContentPayload
src/lib/rich-text-editor/ Componente Design System per il corpo della FAQ (wrappa primeng/editor/Quill)