Merge branch 'RED-2067'

This commit is contained in:
Adina Țeudan 2021-08-23 18:13:55 +02:00
commit 5c500e321a
10 changed files with 92 additions and 91 deletions

View File

@ -1,10 +1,17 @@
<iqser-circle-button [matMenuTriggerFor]="overlay" [showDot]="hasUnreadNotifications" icon="red:notification"></iqser-circle-button>
<mat-menu #overlay="matMenu" backdropClass="notifications-backdrop" class="notifications-menu" xPosition="before">
<redaction-empty-state
*ngIf="!groupedNotifications.length"
[horizontalPadding]="40"
[text]="'notifications.no-data' | translate"
[verticalPadding]="0"
></redaction-empty-state>
<div *ngFor="let group of groupedNotifications">
<div class="all-caps-label">{{ group.dateString }}</div>
<div
*ngFor="let notification of group.notifications | sortBy: 'desc':'creationDate'"
(click)="markRead(notification, $event)"
*ngFor="let notification of group.notifications | sortBy: 'desc':'creationDate'"
[class.unread]="!notification.readDate"
class="notification"
mat-menu-item
@ -16,7 +23,7 @@
</div>
<div
(click)="markRead(notification, $event, !notification.readDate)"
[matTooltip]="(notification.readDate ? 'notifications.mark-unread' : 'notifications.mark-read') | translate"
[matTooltip]="'notifications.mark-as' | translate: { type: notification.readDate ? 'unread' : 'read' }"
class="dot"
matTooltipPosition="before"
></div>

View File

@ -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);

View File

@ -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(<any>NotificationType).includes(notification.notificationType);
return Object.values(NotificationTypeEnum).includes(<NotificationType>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'));

View File

@ -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;

View File

@ -6,7 +6,7 @@
}"
class="empty-state"
>
<mat-icon [svgIcon]="icon"></mat-icon>
<mat-icon *ngIf="icon" [svgIcon]="icon"></mat-icon>
<div class="ng-content-wrapper heading-l">
<ng-content></ng-content>
</div>

View File

@ -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;

View File

@ -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": {

View File

@ -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 <b>{fileName}</b> 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 <b>{fileName}</b> 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 <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> in the <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a><b>!",
"assign-reviewer": "You have been assigned as reviewer for <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> in the <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a><b>!",
"unassigned-from-file": "You have been unassigned from <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> in the <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a><b>!",
"document-approved": " <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> has been approved!",
"dossier-owner-set": " <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> owner changed to <b>{user}</b>!",
"dossier-owner-removed": "<b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> owner removed!",
"dossier-owner-deleted": "<b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> owner removed!",
"dossier-owner-removed": "<b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> owner removed!",
"dossier-owner-set": " <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> owner changed to <b>{user}</b>!",
"unassigned-from-file": "You have been unassigned from <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> in the <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a><b>!",
"user-becomes-dossier-member": "<b>{user}</b> joined dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!",
"user-removed-as-dossier-member": "<b>{user}</b> removed as a member of: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> !",
"user-demoted-to-reviewer": "<b>{user}</b> demoted to reviewer in dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!",
"user-promoted-to-approver": "<b>{user}</b> promoted to approver in dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!",
"user-denoted-to-reviewer": "<b>{user}</b> denoted to reviewer in dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!"
"user-removed-as-dossier-member": "<b>{user}</b> removed as a member of: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> !"
},
"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 <code>{attribute}</code>.",
@ -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": {

View File

@ -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;

View File

@ -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;
}
}
}