Toast Service
Il servizio TessToastService fornisce un'interfaccia unificata per mostrare notifiche toast attraverso diversi UI Kit (PrimeNG, Bootstrap, Material).
Panoramica
TessToastService è UI-agnostic e utilizza il pattern Adapter per delegare l'implementazione al UI Kit configurato nell'applicazione.
Caratteristiche
- ✅ UI-agnostic: Funziona con PrimeNG, Bootstrap, Material
- ✅ Type-safe: Supporto TypeScript completo
- ✅ Auto-dismiss: Chiusura automatica configurabile
- ✅ Severità multiple: Success, Info, Warning, Error
- ✅ Posizionamento: Top, Bottom, Left, Right, Center
- ✅ Sticky messages: Toast persistenti che richiedono chiusura manuale
Installazione
import { provideTessUiLibrary } from '@tess-ui-library/core';
export const appConfig: ApplicationConfig = {
providers: [
provideTessUiLibrary({
uiKit: 'primeng', // o 'bootstrap', 'material'
}),
],
};
Uso Base
Importa il Servizio
import { Component, inject } from '@angular/core';
import { TessToastService } from '@tess-ui-library/core';
@Component({
selector: 'app-example',
standalone: true,
template: `
<button (click)="showSuccess()">Mostra Successo</button>
`,
})
export class ExampleComponent {
private toastService = inject(TessToastService);
showSuccess() {
this.toastService.success('Operazione completata con successo!');
}
}
API
Metodi di Severità
success(message: string, title?: string, options?: ToastOptions): void
Mostra un toast di successo.
this.toastService.success('Utente salvato con successo!', 'Successo');
info(message: string, title?: string, options?: ToastOptions): void
Mostra un toast informativo.
this.toastService.info('Hai 3 nuove notifiche', 'Informazione');
warn(message: string, title?: string, options?: ToastOptions): void
Mostra un toast di warning.
this.toastService.warn('Connessione instabile', 'Attenzione');
error(message: string, title?: string, options?: ToastOptions): void
Mostra un toast di errore.
this.toastService.error('Impossibile salvare i dati', 'Errore');
Metodo Generico
show(message: ToastMessage): void
Mostra un toast con configurazione completa.
this.toastService.show({
severity: 'success',
summary: 'Operazione Completata',
detail: 'I tuoi dati sono stati salvati correttamente',
life: 5000,
sticky: false,
closable: true,
});
ToastMessage Interface
interface ToastMessage {
severity: 'success' | 'info' | 'warn' | 'error';
summary?: string; // Titolo del toast
detail: string; // Messaggio del toast
life?: number; // Durata in ms (default: 3000)
sticky?: boolean; // Se true, richiede chiusura manuale
closable?: boolean; // Mostra pulsante chiusura (default: true)
key?: string; // Identificatore per toast multipli
data?: any; // Dati custom
icon?: string; // Icona personalizzata
styleClass?: string; // CSS class personalizzata
}
ToastOptions Interface
interface ToastOptions {
life?: number; // Durata in ms
sticky?: boolean; // Toast persistente
closable?: boolean; // Mostra pulsante chiusura
key?: string; // Key per posizionamento
}
Gestione Toast
clear(key?: string): void
Rimuove tutti i toast o solo quelli con una specifica key.
// Rimuovi tutti i toast
this.toastService.clear();
// Rimuovi solo toast con key specifica
this.toastService.clear('notifications');
Esempi
Toast di Successo Base
saveUser() {
this.userService.save(this.user).subscribe({
next: () => {
this.toastService.success(
'Utente salvato con successo!',
'Operazione Completata'
);
},
error: (error) => {
this.toastService.error(
'Impossibile salvare l\'utente',
'Errore'
);
}
});
}
Toast con Durata Personalizzata
this.toastService.success(
'File caricato correttamente',
'Upload Completato',
{ life: 5000 } // 5 secondi
);
Toast Sticky (Persistente)
this.toastService.show({
severity: 'warn',
summary: 'Aggiornamento Disponibile',
detail: 'È disponibile una nuova versione dell\'applicazione. Ricarica la pagina per aggiornarla.',
sticky: true,
closable: true,
});
Toast Senza Chiusura Manuale
this.toastService.show({
severity: 'info',
summary: 'Caricamento',
detail: 'Elaborazione in corso...',
closable: false,
life: 10000,
});
Toast Multipli con Key
// Toast per notifiche generali
this.toastService.show({
key: 'main',
severity: 'success',
summary: 'Successo',
detail: 'Operazione completata',
});
// Toast per notifiche secondarie (posizione diversa)
this.toastService.show({
key: 'secondary',
severity: 'info',
summary: 'Info',
detail: 'Nuova notifica',
});
// Rimuovi solo toast main
this.toastService.clear('main');
Toast con Dettagli Errore
deleteUser(userId: string) {
this.userService.delete(userId).subscribe({
next: () => {
this.toastService.success('Utente eliminato', 'Successo');
},
error: (error) => {
this.toastService.show({
severity: 'error',
summary: 'Errore Eliminazione',
detail: error.message || 'Si è verificato un errore imprevisto',
life: 7000,
closable: true,
});
}
});
}
Toast di Conferma con Azione
undoDelete() {
this.toastService.show({
severity: 'success',
summary: 'Elemento Eliminato',
detail: 'L\'elemento è stato eliminato. Clicca qui per annullare.',
sticky: true,
data: { action: 'undo', itemId: this.deletedItemId },
});
}
// Nel componente toast-container (custom)
onToastClick(message: ToastMessage) {
if (message.data?.action === 'undo') {
this.restoreItem(message.data.itemId);
this.toastService.clear();
}
}
Toast per Operazioni Lunghe
async processLargeFile() {
// Mostra toast di inizio
this.toastService.info(
'Elaborazione del file in corso...',
'Attendere',
{ closable: false, life: 0 }
);
try {
await this.fileService.process(this.file);
// Rimuovi toast di loading
this.toastService.clear();
// Mostra toast di successo
this.toastService.success(
'File elaborato con successo!',
'Completato'
);
} catch (error) {
this.toastService.clear();
this.toastService.error(
'Errore durante l\'elaborazione del file',
'Errore'
);
}
}
Toast con HTTP Interceptor
import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { TessToastService } from '@tess-ui-library/core';
import { catchError } from 'rxjs/operators';
export const errorInterceptor: HttpInterceptorFn = (req, next) => {
const toastService = inject(TessToastService);
return next(req).pipe(
catchError((error) => {
// Mostra toast per errori HTTP
if (error.status >= 500) {
toastService.error(
'Si è verificato un errore del server',
'Errore Server'
);
} else if (error.status === 401) {
toastService.warn(
'Sessione scaduta. Effettua nuovamente l\'accesso.',
'Autenticazione Richiesta'
);
} else if (error.status === 403) {
toastService.warn(
'Non hai i permessi per eseguire questa operazione',
'Accesso Negato'
);
}
throw error;
})
);
};
Posizionamento (UI Kit Specifico)
PrimeNG
Con PrimeNG, usa il componente p-toast nel tuo template principale:
<!-- app.component.html -->
<p-toast key="main"></p-toast>
<p-toast key="secondary" position="bottom-right"></p-toast>
<router-outlet></router-outlet>
Posizioni disponibili:
top-lefttop-centertop-rightbottom-leftbottom-centerbottom-right
Bootstrap
Con Bootstrap, aggiungi il container nel template principale:
<!-- app.component.html -->
<ngb-toast-container class="toast-container position-fixed top-0 end-0 p-3"></ngb-toast-container>
<router-outlet></router-outlet>
Material
Con Material, usa MatSnackBar che è già configurato:
// Nessun template aggiuntivo necessario
Configurazione Globale
Configura il comportamento di default dei toast:
// app.config.ts
import { provideTessUiLibrary, TOAST_CONFIG } from '@tess-ui-library/core';
export const appConfig: ApplicationConfig = {
providers: [
provideTessUiLibrary({ uiKit: 'primeng' }),
{
provide: TOAST_CONFIG,
useValue: {
life: 4000, // Durata default 4 secondi
sticky: false, // Non sticky per default
closable: true, // Sempre chiudibile
position: 'top-right', // Posizione default
},
},
],
};
Best Practices
- Usa severità appropriate: Success per azioni completate, error per errori, warn per avvisi, info per notifiche
- Messaggi chiari e concisi: Evita messaggi lunghi, usa il detail per informazioni aggiuntive
- Durata appropriata:
- Success/Info: 3-4 secondi
- Warning: 5-7 secondi
- Error: 7-10 secondi o sticky
- Evita toast multipli: Usa
clear()prima di mostrare un nuovo toast importante - Sticky solo quando necessario: Usa sticky solo per messaggi che richiedono azione o conferma
- Accessibilità: I toast devono essere leggibili da screen reader (già implementato)
- Non abusare: Usa i toast per feedback immediato, non per conversazioni complesse