import { Component } from '@angular/core'; import { DatePipe } from '@shared/pipes/date.pipe'; import { NotificationsService } from '@services/notifications.service'; import { Notification } from '@red/domain'; import { distinctUntilChanged, map } from 'rxjs/operators'; import { Observable } from 'rxjs'; import { isToday, shareLast, trackByFactory } from '@iqser/common-ui'; import dayjs, { Dayjs } from 'dayjs'; import { TranslateService } from '@ngx-translate/core'; interface NotificationsGroup { date: string; notifications: Notification[]; } export function isOlderThan(date: string | Date | Dayjs, years: number) { return dayjs(date).year() <= dayjs(Date.now()).subtract(years, 'year').year(); } function chronologically(first: string, second: string) { return dayjs(first).isAfter(second) ? -1 : 1; } @Component({ selector: 'redaction-notifications', templateUrl: './notifications.component.html', styleUrls: ['./notifications.component.scss'], }) export class NotificationsComponent { readonly hasUnreadNotifications$: Observable; readonly groupedNotifications$: Observable; readonly trackBy = trackByFactory(); constructor( private readonly _notificationsService: NotificationsService, private readonly _datePipe: DatePipe, private readonly _translateService: TranslateService, ) { this.groupedNotifications$ = this._notificationsService.all$.pipe(map(notifications => this.#groupNotifications(notifications))); this.hasUnreadNotifications$ = this.#hasUnreadNotifications$; } get #hasUnreadNotifications$(): Observable { return this._notificationsService.all$.pipe( map(notifications => notifications.filter(n => !n.readDate).length > 0), distinctUntilChanged(), shareLast(), ); } async markRead(notifications: Notification[] = this._notificationsService.all, isRead = true): Promise { if (!notifications.find(notification => !!notification.readDate !== isRead)) { // If no notification changes status after the request, abort return; } const notificationsIds = notifications.map(n => n.id); await this._notificationsService.toggleNotificationRead(notificationsIds, isRead); } #groupNotifications(notifications: Notification[]): NotificationsGroup[] { const todayTranslation = this._translateService.instant('today'); const groupedMap = notifications.groupBy(n => { if (isOlderThan(n.creationDate, 2)) { return dayjs(n.creationDate).year().toString(); } else if (isOlderThan(n.creationDate, 1)) { return dayjs(n.creationDate).format('YYYY-MM'); } return n.creationDate.split('T')[0]; }); const sortedGroups = [...groupedMap.entries()].sort(([aDate], [bDate]) => chronologically(aDate, bDate)); return sortedGroups.map(([date, _notifications]) => ({ date: isToday(date) ? todayTranslation : this._datePipe.transform(date, 'sophisticatedDate'), notifications: [..._notifications].sort((a, b) => chronologically(a.creationDate, b.creationDate)), })); } }