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 bd15772d8..fb790d059 100644 --- a/apps/red-ui/src/app/components/notifications/notifications.component.html +++ b/apps/red-ui/src/app/components/notifications/notifications.component.html @@ -1,10 +1,17 @@ + +
{{ group.dateString }}
diff --git a/apps/red-ui/src/app/components/notifications/notifications.component.scss b/apps/red-ui/src/app/components/notifications/notifications.component.scss index 9b9bf34d1..22cac0d80 100644 --- a/apps/red-ui/src/app/components/notifications/notifications.component.scss +++ b/apps/red-ui/src/app/components/notifications/notifications.component.scss @@ -9,6 +9,7 @@ .notifications-menu { min-width: 400px !important; + max-width: 413px !important; padding: 0 8px 16px; margin-right: 8px; max-height: calc(100vh - 200px); 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 b790e6380..0b8d4b06e 100644 --- a/apps/red-ui/src/app/components/notifications/notifications.component.ts +++ b/apps/red-ui/src/app/components/notifications/notifications.component.ts @@ -1,25 +1,13 @@ import { Component } from '@angular/core'; import * as moment from 'moment'; import { TranslateService } from '@ngx-translate/core'; -import { NotificationControllerService, Notification, NotificationResponse } from '@redaction/red-ui-http'; +import { Notification, NotificationControllerService, NotificationResponse } from '@redaction/red-ui-http'; import { DatePipe } from '@shared/pipes/date.pipe'; import { AppStateService } from '@state/app-state.service'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { UserService } from '@services/user.service'; - -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' -} +import { NotificationType, NotificationTypeEnum } from '@models/notification-types'; +import { notificationsTranslations } from '../../translations/notifications-translations'; @Component({ selector: 'redaction-notifications', @@ -53,37 +41,22 @@ export class NotificationsComponent { } 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.DOCUMENT_APPROVED: - return this._translate(notification, _('notification.document-approved')); - case NotificationType.UNASSIGNED_FROM_FILE: - return this._translate(notification, _('notification.unassigned-from-file')); - case NotificationType.DOSSIER_OWNER_SET: - return this._translate(notification, _('notification.dossier-owner-set')); - case NotificationType.DOSSIER_OWNER_REMOVED: - return this._translate(notification, _('notification.dossier-owner-removed')); - case NotificationType.DOSSIER_OWNER_DELETED: - return this._translate(notification, _('notification.dossier-owner-deleted')); - case NotificationType.USER_BECOMES_DOSSIER_MEMBER: - return this._translate(notification, _('notification.user-becomes-dossier-member')); - case NotificationType.USER_REMOVED_AS_DOSSIER_MEMBER: - return this._translate(notification, _('notification.user-removed-as-dossier-member')); - case NotificationType.USER_PROMOTED_TO_APPROVER: - return this._translate(notification, _('notification.user-promoted-to-approver')); - case NotificationType.USER_DEGRADED_TO_REVIEWER: - return this._translate(notification, _('notification.user-denoted-to-reviewer')); + return this._translate(notification, notificationsTranslations[notification.notificationType]); + } - default: - return ''; + async markRead(notification: Notification, $event, isRead: boolean = true) { + $event.stopPropagation(); + const ids = [notification.notificationId]; + await this._notificationControllerService.toggleNotificationRead(ids, isRead).toPromise(); + if (isRead) { + notification.readDate = moment().format('YYYY-MM-DDTHH:mm:ss Z'); + } else { + notification.readDate = null; } } private _isSupportedType(notification: Notification) { - return Object.values(NotificationType).includes(notification.notificationType); + return Object.values(NotificationTypeEnum).includes(notification.notificationType); } private _getDossierHref(dossierId: string) { @@ -120,17 +93,6 @@ export class NotificationsComponent { this.groupedNotifications = this.groupedNotifications.reverse(); } - async markRead(notification: Notification, $event, isRead: boolean = true) { - $event.stopPropagation(); - const ids = [notification.notificationId]; - await this._notificationControllerService.toggleNotificationRead(ids, isRead).toPromise(); - if (isRead) { - notification.readDate = moment().format('YYYY-MM-DDTHH:mm:ss Z'); - } else { - notification.readDate = null; - } - } - private _getDossierName(dossierId: string | undefined) { const dossier = this._appStateService.getDossierById(dossierId); return dossier?.dossierName || this._translateService.instant(_('dossier')); diff --git a/apps/red-ui/src/app/models/notification-types.ts b/apps/red-ui/src/app/models/notification-types.ts new file mode 100644 index 000000000..87f258972 --- /dev/null +++ b/apps/red-ui/src/app/models/notification-types.ts @@ -0,0 +1,15 @@ +export enum NotificationTypeEnum { + 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' +} + +export type NotificationType = NotificationTypeEnum; diff --git a/apps/red-ui/src/app/modules/shared/components/empty-state/empty-state.component.html b/apps/red-ui/src/app/modules/shared/components/empty-state/empty-state.component.html index 37b31da41..cc9bca594 100644 --- a/apps/red-ui/src/app/modules/shared/components/empty-state/empty-state.component.html +++ b/apps/red-ui/src/app/modules/shared/components/empty-state/empty-state.component.html @@ -6,7 +6,7 @@ }" class="empty-state" > - +
diff --git a/apps/red-ui/src/app/translations/notifications-translations.ts b/apps/red-ui/src/app/translations/notifications-translations.ts new file mode 100644 index 000000000..a78779bb6 --- /dev/null +++ b/apps/red-ui/src/app/translations/notifications-translations.ts @@ -0,0 +1,16 @@ +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { NotificationType, NotificationTypeEnum } from '@models/notification-types'; + +export const notificationsTranslations: { [key in NotificationType]: string } = { + [NotificationTypeEnum.ASSIGN_APPROVER]: _('notification.assign-approver'), + [NotificationTypeEnum.ASSIGN_REVIEWER]: _('notification.assign-reviewer'), + [NotificationTypeEnum.DOCUMENT_APPROVED]: _('notification.document-approved'), + [NotificationTypeEnum.DOSSIER_OWNER_DELETED]: _('notification.dossier-owner-deleted'), + [NotificationTypeEnum.DOSSIER_OWNER_REMOVED]: _('notification.dossier-owner-removed'), + [NotificationTypeEnum.DOSSIER_OWNER_SET]: _('notification.dossier-owner-set'), + [NotificationTypeEnum.UNASSIGNED_FROM_FILE]: _('notification.unassigned-from-file'), + [NotificationTypeEnum.USER_BECOMES_DOSSIER_MEMBER]: _('notification.user-becomes-dossier-member'), + [NotificationTypeEnum.USER_DEGRADED_TO_REVIEWER]: _('notification.user-demoted-to-reviewer'), + [NotificationTypeEnum.USER_PROMOTED_TO_APPROVER]: _('notification.user-promoted-to-approver'), + [NotificationTypeEnum.USER_REMOVED_AS_DOSSIER_MEMBER]: _('notification.user-removed-as-dossier-member') +} as const; diff --git a/apps/red-ui/src/assets/i18n/de.json b/apps/red-ui/src/assets/i18n/de.json index 0028d47d0..6bc4c7da7 100644 --- a/apps/red-ui/src/assets/i18n/de.json +++ b/apps/red-ui/src/assets/i18n/de.json @@ -1097,11 +1097,7 @@ } }, "notifications": { - "mark-read": "als gelesen markieren", - "mark-unread": "als ungelesen markieren", - "today": "Heute", - "tomorrow": "Morgen", - "yesterday": "Gestern" + "mark-as": "als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" }, "overwrite-files-dialog": { "options": { diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 6be48809b..318b5c45b 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -339,9 +339,6 @@ "title": "Confirm Action" } }, - "unknown": "Unknown", - "dossier": "Dossier", - "file": "File", "configurations": "Configurations", "confirm-delete-file-attribute": { "cancel": "Keep {type, select, single{Attribute} bulk{Attributes} other{}}", @@ -362,13 +359,6 @@ "warning": "Warning: this cannot be undone!" }, "confirmation-dialog": { - "upload-report-template": { - "question": "Please choose if {fileName} is a single or multi-file report template", - "title": "Report Template Upload", - "deny-text": "Cancel Upload", - "confirmation-text": "Upload as single-file report", - "alternate-confirmation-text": "Upload as multi-file report" - }, "assign-file-to-me": { "question": "This document is currently reviewed by someone else. Do you want to become the reviewer and assign yourself to this document?", "title": "Re-assign reviewer" @@ -393,6 +383,13 @@ "deny-text": "Keep {filesCount, plural, one{Document} other{Documents}}", "question": "Are you sure you want to delete {filesCount, plural, one{this document} other{these documents}}?", "title": "Delete {filesCount, plural, one{{fileName}} other{Selected Documents}}" + }, + "upload-report-template": { + "alternate-confirmation-text": "Upload as multi-file report", + "confirmation-text": "Upload as single-file report", + "deny-text": "Cancel Upload", + "question": "Please choose if {fileName} is a single or multi-file report template", + "title": "Report Template Upload" } }, "content": "Reason", @@ -523,6 +520,7 @@ "save": "Save Document Info", "title": "Introduce File Attributes" }, + "dossier": "Dossier", "dossier-attribute-types": { "date": "Date", "image": "Image", @@ -849,6 +847,7 @@ "unsaved-changes": "You have unsaved changes. Save or revert before changing the tab." }, "exact-date": "{day} {month} {year} at {hour}:{minute}", + "file": "File", "file-attribute-types": { "date": "Date", "number": "Number", @@ -1041,11 +1040,11 @@ "filters": { "assigned-people": "Assignee(s)", "dossier-templates": "Dossier Templates", + "empty": "Empty", "filter-by": "Filter:", "needs-work": "Workload", "people": "Dossier Member(s)", - "status": "Status", - "empty": "Empty" + "status": "Status" }, "general-config-screen": { "actions": { @@ -1186,22 +1185,19 @@ "notification": { "assign-approver": "You have been assigned as approver for {fileName} in the {dossierName}!", "assign-reviewer": "You have been assigned as reviewer for {fileName} in the {dossierName}!", - "unassigned-from-file": "You have been unassigned from {fileName} in the {dossierName}!", "document-approved": " {fileName} has been approved!", - "dossier-owner-set": " {dossierName} owner changed to {user}!", - "dossier-owner-removed": "{dossierName} owner removed!", "dossier-owner-deleted": "{dossierName} owner removed!", + "dossier-owner-removed": "{dossierName} owner removed!", + "dossier-owner-set": " {dossierName} owner changed to {user}!", + "unassigned-from-file": "You have been unassigned from {fileName} in the {dossierName}!", "user-becomes-dossier-member": "{user} joined dossier: {dossierName}!", - "user-removed-as-dossier-member": "{user} removed as a member of: {dossierName} !", + "user-demoted-to-reviewer": "{user} demoted to reviewer in dossier: {dossierName}!", "user-promoted-to-approver": "{user} promoted to approver in dossier: {dossierName}!", - "user-denoted-to-reviewer": "{user} denoted to reviewer in dossier: {dossierName}!" + "user-removed-as-dossier-member": "{user} removed as a member of: {dossierName} !" }, "notifications": { - "mark-read": "Mark as read", - "mark-unread": "Mark as unread", - "today": "Today", - "tomorrow": "Tomorrow", - "yesterday": "Yesterday" + "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}", + "no-data": "You have no notifications." }, "overwrite-files-dialog": { "options": { @@ -1260,7 +1256,6 @@ }, "reports": "Reports", "reports-screen": { - "multi-file-report": "(Multi-file)", "description": "A short text explaining how to create report documents. It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.", "descriptions": { "dossier-attributes": "This placeholder gets replaced with the value of the dossier attribute {attribute}.", @@ -1290,6 +1285,7 @@ "document-setup-description": "A short text explaining what placeholders are and how to use them in your report template. It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.", "document-setup-heading": "Document Setup", "invalid-upload": "Invalid format selected for Upload! Supported formats are XLSX and DOCX", + "multi-file-report": "(Multi-file)", "report-documents": "Report Documents", "table-header": { "description": "Description", @@ -1416,6 +1412,7 @@ } }, "type": "Type", + "unknown": "Unknown", "upload-status": { "dialog": { "actions": { diff --git a/apps/red-ui/src/assets/styles/red-menu.scss b/apps/red-ui/src/assets/styles/red-menu.scss index 65b94e05f..567c4b3b8 100644 --- a/apps/red-ui/src/assets/styles/red-menu.scss +++ b/apps/red-ui/src/assets/styles/red-menu.scss @@ -1,4 +1,5 @@ @import 'variables'; +@import 'red-mixins'; .mat-menu-panel { border-radius: 8px !important; @@ -6,6 +7,7 @@ max-width: none !important; min-width: 180px !important; margin-top: 10px; + @include scroll-bar; .mat-menu-content:not(:empty) { padding-top: 8px; diff --git a/apps/red-ui/src/assets/styles/red-select.scss b/apps/red-ui/src/assets/styles/red-select.scss index 1a9c3b0ac..2efdd6510 100644 --- a/apps/red-ui/src/assets/styles/red-select.scss +++ b/apps/red-ui/src/assets/styles/red-select.scss @@ -1,14 +1,19 @@ @import 'variables'; +@import 'red-mixins'; -.mat-select-panel .mat-option { - &:hover:not(.mat-option-disabled), - &:focus:not(.mat-option-disabled) { - background-color: $grey-6; - } +.mat-select-panel { + @include scroll-bar; - &.mat-selected:not(.mat-option-multiple) { - background-color: rgba($primary, 0.2); - color: $accent; + .mat-option { + &:hover:not(.mat-option-disabled), + &:focus:not(.mat-option-disabled) { + background-color: $grey-6; + } + + &.mat-selected:not(.mat-option-multiple) { + background-color: rgba($primary, 0.2); + color: $accent; + } } }