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.deleterispettivamente — enforcement reale lato backend (GET /v1/auth/policies), tipicamente assegnata a Executive ed Executive Support. Il markup usa la direttiva*appPolicyesistente (nonisExecutive()/RoleEnumcome 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) |