115 lines
4.1 KiB
TypeScript
115 lines
4.1 KiB
TypeScript
import { Injectable } from '@angular/core';
|
|
import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http';
|
|
import { Observable, Subject, tap } from 'rxjs';
|
|
|
|
import { environment } from '../../environments/environment';
|
|
|
|
export type NotificationTipo = 'AVencer' | 'Vencido' | 'RenovacaoAutomatica' | string;
|
|
|
|
export type NotificationDto = {
|
|
id: string;
|
|
tipo: NotificationTipo;
|
|
titulo: string;
|
|
mensagem: string;
|
|
data: string;
|
|
referenciaData?: string | null;
|
|
diasParaVencer?: number | null;
|
|
lida: boolean;
|
|
lidaEm?: string | null;
|
|
vigenciaLineId?: string | null;
|
|
cliente?: string | null;
|
|
linha?: string | null;
|
|
usuario?: string | null;
|
|
conta?: string | null;
|
|
planoContrato?: string | null;
|
|
dtEfetivacaoServico?: string | null;
|
|
dtTerminoFidelizacao?: string | null;
|
|
};
|
|
|
|
export type NotificationsEvent =
|
|
| { type: 'read'; ids: string[]; readAtIso: string }
|
|
| { type: 'unread'; ids: string[] }
|
|
| { type: 'readAll'; readAtIso: string }
|
|
| { type: 'unreadAll' }
|
|
| { type: 'reload' };
|
|
|
|
@Injectable({ providedIn: 'root' })
|
|
export class NotificationsService {
|
|
private readonly baseApi: string;
|
|
private readonly eventsSubject = new Subject<NotificationsEvent>();
|
|
readonly events$ = this.eventsSubject.asObservable();
|
|
|
|
constructor(private http: HttpClient) {
|
|
const raw = (environment.apiUrl || '').replace(/\/+$/, '');
|
|
this.baseApi = raw.toLowerCase().endsWith('/api') ? raw : `${raw}/api`;
|
|
}
|
|
|
|
list(): Observable<NotificationDto[]> {
|
|
return this.http.get<NotificationDto[]>(`${this.baseApi}/notifications`);
|
|
}
|
|
|
|
markAsRead(id: string): Observable<void> {
|
|
const readAtIso = new Date().toISOString();
|
|
return this.http.patch<void>(`${this.baseApi}/notifications/${id}/read`, {}).pipe(
|
|
tap(() => this.eventsSubject.next({ type: 'read', ids: [id], readAtIso }))
|
|
);
|
|
}
|
|
|
|
markAsUnread(id: string): Observable<void> {
|
|
return this.http.patch<void>(`${this.baseApi}/notifications/${id}/unread`, {}).pipe(
|
|
tap(() => this.eventsSubject.next({ type: 'unread', ids: [id] }))
|
|
);
|
|
}
|
|
|
|
markAllAsRead(filter?: string, notificationIds?: string[]): Observable<void> {
|
|
let params = new HttpParams();
|
|
if (filter) params = params.set('filter', filter);
|
|
const body = notificationIds && notificationIds.length ? { notificationIds } : {};
|
|
const readAtIso = new Date().toISOString();
|
|
return this.http.patch<void>(`${this.baseApi}/notifications/read-all`, body, { params }).pipe(
|
|
tap(() => {
|
|
if (notificationIds && notificationIds.length) {
|
|
this.eventsSubject.next({ type: 'read', ids: notificationIds, readAtIso });
|
|
return;
|
|
}
|
|
// Se não sabemos o escopo (sem IDs), preferimos sinalizar que "todas" foram lidas.
|
|
// Para casos futuros de filtros sem IDs, o consumer pode optar por recarregar.
|
|
this.eventsSubject.next(filter ? { type: 'reload' } : { type: 'readAll', readAtIso });
|
|
})
|
|
);
|
|
}
|
|
|
|
markAllAsUnread(filter?: string, notificationIds?: string[]): Observable<void> {
|
|
let params = new HttpParams();
|
|
if (filter) params = params.set('filter', filter);
|
|
const body = notificationIds && notificationIds.length ? { notificationIds } : {};
|
|
return this.http.patch<void>(`${this.baseApi}/notifications/unread-all`, body, { params }).pipe(
|
|
tap(() => {
|
|
if (notificationIds && notificationIds.length) {
|
|
this.eventsSubject.next({ type: 'unread', ids: notificationIds });
|
|
return;
|
|
}
|
|
this.eventsSubject.next(filter ? { type: 'reload' } : { type: 'unreadAll' });
|
|
})
|
|
);
|
|
}
|
|
|
|
export(filter?: string, notificationIds?: string[]): Observable<HttpResponse<Blob>> {
|
|
let params = new HttpParams();
|
|
if (filter) params = params.set('filter', filter);
|
|
if (notificationIds && notificationIds.length) {
|
|
return this.http.post(`${this.baseApi}/notifications/export`, { notificationIds }, {
|
|
params,
|
|
observe: 'response',
|
|
responseType: 'blob'
|
|
});
|
|
}
|
|
|
|
return this.http.get(`${this.baseApi}/notifications/export`, {
|
|
params,
|
|
observe: 'response',
|
|
responseType: 'blob'
|
|
});
|
|
}
|
|
}
|