diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index dbab0865a..80efd31cc 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -36,6 +36,7 @@ import { SpotlightSearchComponent } from '@components/spotlight-search/spotlight import { PruningTranslationLoader } from '@utils/pruning-translation-loader'; import { HelpModeComponent } from '@components/help-mode/help-mode.component'; import { HelpModeDialogComponent } from '@components/help-mode-dialog/help-mode-dialog.component'; +import { DatePipe } from '@shared/pipes/date.pipe'; export function httpLoaderFactory(httpClient: HttpClient) { return new PruningTranslationLoader(httpClient, '/assets/i18n/', '.json'); @@ -134,7 +135,8 @@ const components = [ { provide: MissingTranslationHandler, useClass: REDMissingTranslationHandler - } + }, + DatePipe ], bootstrap: [AppComponent] }) diff --git a/apps/red-ui/src/app/components/notifications/notifications.component.html b/apps/red-ui/src/app/components/notifications/notifications.component.html index df9e2a4ce..8f99a4db8 100644 --- a/apps/red-ui/src/app/components/notifications/notifications.component.html +++ b/apps/red-ui/src/app/components/notifications/notifications.component.html @@ -1,21 +1,21 @@ - + -
-
{{ day(group) }}
+
+
{{ group.dateString }}
-
-
{{ eventTime(notification.eventTime) }}
+
+
{{ getTime(notification.creationDate) }}
diff --git a/apps/red-ui/src/app/components/notifications/notifications.component.ts b/apps/red-ui/src/app/components/notifications/notifications.component.ts index 54ee4bd54..072cfee94 100644 --- a/apps/red-ui/src/app/components/notifications/notifications.component.ts +++ b/apps/red-ui/src/app/components/notifications/notifications.component.ts @@ -1,26 +1,22 @@ import { Component } from '@angular/core'; import * as moment from 'moment'; import { TranslateService } from '@ngx-translate/core'; -import { NotificationControllerService } from '@redaction/red-ui-http'; +import { NotificationControllerService, Notification, NotificationResponse } from '@redaction/red-ui-http'; +import { DatePipe } from '@shared/pipes/date.pipe'; -interface Notification { - message: string; - eventTime: number; - read: boolean; +enum NotificationType { + ASSIGN_REVIEWER = 'ASSIGN_REVIEWER', + ASSIGN_APPROVER = 'ASSIGN_APPROVER', + UNASSIGNED_FROM_FILE = 'UNASSIGNED_FROM_FILE', + DOCUMENT_APPROVED = 'DOCUMENT_APPROVED', + DOSSIER_OWNER_SET = 'DOSSIER_OWNER_SET', + DOSSIER_OWNER_REMOVED = 'DOSSIER_OWNER_REMOVED', + USER_BECOMES_DOSSIER_MEMBER = 'USER_BECOMES_DOSSIER_MEMBER', + USER_REMOVED_AS_DOSSIER_MEMBER = 'USER_REMOVED_AS_DOSSIER_MEMBER', + USER_PROMOTED_TO_APPROVER = 'USER_PROMOTED_TO_APPROVER', + USER_DEGRADED_TO_REVIEWER = 'USER_DEGRADED_TO_REVIEWER', + DOSSIER_OWNER_DELETED = 'DOSSIER_OWNER_DELETED' } - -// Current Notification Types: -// ASSIGN_REVIEWER, -// ASSIGN_APPROVER, -// UNASSIGNED_FROM_FILE, -// DOCUMENT_APPROVED, -// DOSSIER_OWNER_SET, -// DOSSIER_OWNER_REMOVED, -// USER_BECOMES_DOSSIER_MEMBER, -// USER_REMOVED_AS_DOSSIER_MEMBER, -// USER_PROMOTED_TO_APPROVER, -// USER_DEGRADED_TO_REVIEWER, -// DOSSIER_OWNER_DELETED // For each you have a different set of target Ids - I.E. a projectId, fileId or userId of the user who did the action // we need to create some templated i18n message which also include links // to the file or project that was affected ( see mock notifications ) @@ -31,67 +27,79 @@ interface Notification { styleUrls: ['./notifications.component.scss'] }) export class NotificationsComponent { - notifications: Notification[] = [ - { - message: 'This is a notification with longer text wrapping on multiple lines', - eventTime: 1607340971000, - read: false - }, - { message: 'This is a link', eventTime: 1607254981000, read: true }, - { message: 'This is a notification 1', eventTime: 1607254571000, read: false }, - { message: 'Notification', eventTime: 1607385727000, read: true }, - { message: 'Another notification', eventTime: 1606829412000, read: false } - ]; + notifications: Notification[]; groupedNotifications: { dateString: string; notifications: Notification[] }[] = []; - constructor(private _translateService: TranslateService, private _notificationControllerService: NotificationControllerService) { - this._groupNotifications(); - // TODO group notifications by date using same date-format as comments in workload - // - // this._notificationControllerService.getNotifications(false).subscribe(response => { - // console.log(response); - // }); - } - - get hasUnread() { - return this.notifications.filter(notification => !notification.read).length > 0; - } - - day(group: { dateString: string; notifications: Notification[] }): string { - moment.locale(this._translateService.currentLang); - return moment(group.notifications[0].eventTime).calendar({ - sameDay: `[${this._translateService.instant('notifications.today')}]`, - lastDay: `[${this._translateService.instant('notifications.yesterday')}]`, - nextDay: `[${this._translateService.instant('notifications.tomorrow')}]`, - nextWeek: 'D MMMM', - lastWeek: 'D MMMM', - sameElse: 'D MMMM' + constructor( + private _translateService: TranslateService, + private _notificationControllerService: NotificationControllerService, + private readonly _datePipe: DatePipe + ) { + this._notificationControllerService.getNotifications(false).subscribe((response: NotificationResponse) => { + this.notifications = response.notifications; + console.log(this.notifications); + console.log(JSON.stringify(this.notifications)); + this._groupNotifications(this.notifications); }); } - eventTime(eventTime: number): string { + getTime(date: string): string { moment.locale(this._translateService.currentLang); - if (moment().isSame(eventTime, 'day')) { - return moment(eventTime).fromNow(); - } else { - return moment(eventTime).format('hh:mm A'); + return moment(date).format('hh:mm A'); + } + + getNotificationMessage(notification: Notification) { + switch (notification.notificationType) { + case NotificationType.ASSIGN_REVIEWER: + return this._translate(notification, 'notification.assign-reviewer'); + case NotificationType.ASSIGN_APPROVER: + return this._translate(notification, 'notification.assign-approver'); + case NotificationType.UNASSIGNED_FROM_FILE: + return this._translate(notification, 'notification.unassigned-from-file'); + default: + return ''; } } toggleRead(notification: Notification, $event) { + console.log('notification: ', notification); $event.stopPropagation(); - notification.read = !notification.read; + notification.readDate = !notification.readDate ? moment().format('YYYY-MM-DDTHH:mm:ss Z') : null; + const ids = [notification.notificationId]; + const isRead = !!notification.readDate; + this._notificationControllerService.toggleNotificationRead(ids, isRead).subscribe(response => { + console.log('response: ', response); + }); } - private _groupNotifications() { + private _getDossierHref(dossierId: string) { + return `main/dossiers/${dossierId}`; + } + + private _getFileHref(dossierId: string, fileId: string) { + const dossierUrl = this._getDossierHref(dossierId); + return `${dossierUrl}/file/${fileId}`; + } + + private _translate(notification: Notification, translation: string) { + const fileId = notification.target.fileId; + const dossierId = notification.target.dossierId; + return this._translateService.instant(translation, { + fileHref: this._getFileHref(dossierId, fileId), + dossierHref: this._getDossierHref(dossierId) + }); + } + + private _groupNotifications(notifications: Notification[]) { const res = {}; - for (const notification of this.notifications) { - const date = moment(notification.eventTime).format('YYYY-MM-DD'); + for (const notification of notifications) { + const date = this._datePipe.transform(notification.creationDate, 'sophisticatedDate'); if (!res[date]) res[date] = []; res[date].push(notification); } for (const key of Object.keys(res)) { this.groupedNotifications.push({ dateString: key, notifications: res[key] }); } + this.groupedNotifications = this.groupedNotifications.reverse(); } } diff --git a/apps/red-ui/src/app/modules/dossier/components/comments/comments.component.html b/apps/red-ui/src/app/modules/dossier/components/comments/comments.component.html index c5d74ae01..2746e1b0e 100644 --- a/apps/red-ui/src/app/modules/dossier/components/comments/comments.component.html +++ b/apps/red-ui/src/app/modules/dossier/components/comments/comments.component.html @@ -2,7 +2,7 @@
{{ getOwnerName(comment) }} - {{ comment.date | date: 'commentDate' }} + {{ comment.date | date: 'sophisticatedDate' }}
file in the dossier!", + "assign-reviewer": "You have been assigned as reviewer for file in the dossier!", + "unassigned-from-file": "You have been unassigned from file in the dossier!" + }, "notifications": { "mark-read": "Mark as read", "mark-unread": "Mark as unread", diff --git a/libs/red-ui-http/src/lib/model/models.ts b/libs/red-ui-http/src/lib/model/models.ts index 8e42e0fcf..5600d88f2 100644 --- a/libs/red-ui-http/src/lib/model/models.ts +++ b/libs/red-ui-http/src/lib/model/models.ts @@ -80,3 +80,5 @@ export * from './searchRequest'; export * from './searchResult'; export * from './matchedDocument'; export * from './placeholdersResponse'; +export * from './notification'; +export * from './notificationResponse'; diff --git a/libs/red-ui-http/src/lib/model/notification.ts b/libs/red-ui-http/src/lib/model/notification.ts index 0da921221..db999aeb3 100644 --- a/libs/red-ui-http/src/lib/model/notification.ts +++ b/libs/red-ui-http/src/lib/model/notification.ts @@ -18,6 +18,6 @@ export interface Notification { readDate?: string; seenDate?: string; softDeleted?: string; - target?: string; + target?: any; userId?: string; }