Merge branch 'master' into VM/TestsIds
This commit is contained in:
commit
bbdff8e525
@ -13,11 +13,11 @@
|
||||
<div *ngFor="let group of groups; let first = first">
|
||||
<div class="all-caps-label flex-align-items-center">
|
||||
<div>{{ group.date }}</div>
|
||||
<div *ngIf="(hasUnreadNotifications$ | async) && first" class="view-all" (click)="markRead($event)">View all</div>
|
||||
<div (click)="markRead($event)" *ngIf="(hasUnreadNotifications$ | async) && first" class="view-all">View all</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
(click)="markRead($event, [notification.id])"
|
||||
(click)="markRead($event, [notification], true)"
|
||||
*ngFor="let notification of group.notifications | sortBy: 'desc':'creationDate'"
|
||||
[class.unread]="!notification.readDate"
|
||||
class="notification"
|
||||
@ -29,7 +29,7 @@
|
||||
<div class="small-label mt-2">{{ notification.time }}</div>
|
||||
</div>
|
||||
<div
|
||||
(click)="markRead($event, [notification.id], !notification.readDate)"
|
||||
(click)="markRead($event, [notification], !notification.readDate)"
|
||||
class="dot"
|
||||
matTooltip="{{ 'notifications.mark-as' | translate: { type: notification.readDate ? 'unread' : 'read' } }}"
|
||||
matTooltipPosition="before"
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
position: relative;
|
||||
line-height: 18px;
|
||||
align-items: flex-start;
|
||||
cursor: default;
|
||||
|
||||
.notification-content {
|
||||
margin-top: 4px;
|
||||
@ -50,6 +51,7 @@
|
||||
background-color: variables.$grey-4;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
@ -1,16 +1,13 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DatePipe } from '@shared/pipes/date.pipe';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||
import { NotificationsService } from '@services/notifications.service';
|
||||
import { Notification } from '@red/domain';
|
||||
import { distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';
|
||||
import { BehaviorSubject, firstValueFrom, Observable, timer } from 'rxjs';
|
||||
import { AutoUnsubscribe, List, shareLast } from '@iqser/common-ui';
|
||||
import { CHANGED_CHECK_INTERVAL } from '@utils/constants';
|
||||
|
||||
const INCLUDE_SEEN = false;
|
||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||
import { firstValueFrom, Observable } from 'rxjs';
|
||||
import { shareLast } from '@iqser/common-ui';
|
||||
|
||||
interface NotificationsGroup {
|
||||
date: string;
|
||||
@ -23,11 +20,9 @@ interface NotificationsGroup {
|
||||
styleUrls: ['./notifications.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class NotificationsComponent extends AutoUnsubscribe implements OnInit {
|
||||
notifications$: Observable<Notification[]>;
|
||||
hasUnreadNotifications$: Observable<boolean>;
|
||||
groupedNotifications$: Observable<NotificationsGroup[]>;
|
||||
private _notifications$ = new BehaviorSubject<Notification[]>([]);
|
||||
export class NotificationsComponent {
|
||||
readonly hasUnreadNotifications$: Observable<boolean>;
|
||||
readonly groupedNotifications$: Observable<NotificationsGroup[]>;
|
||||
|
||||
constructor(
|
||||
private readonly _translateService: TranslateService,
|
||||
@ -36,40 +31,30 @@ export class NotificationsComponent extends AutoUnsubscribe implements OnInit {
|
||||
private readonly _activeDossiersService: ActiveDossiersService,
|
||||
private readonly _datePipe: DatePipe,
|
||||
) {
|
||||
super();
|
||||
this.notifications$ = this._notifications$.asObservable().pipe(shareLast());
|
||||
this.groupedNotifications$ = this.notifications$.pipe(map(notifications => this._groupNotifications(notifications)));
|
||||
this.groupedNotifications$ = this._notificationsService.all$.pipe(map(notifications => this._groupNotifications(notifications)));
|
||||
this.hasUnreadNotifications$ = this._hasUnreadNotifications$;
|
||||
}
|
||||
|
||||
private get _hasUnreadNotifications$(): Observable<boolean> {
|
||||
return this.notifications$.pipe(
|
||||
return this._notificationsService.all$.pipe(
|
||||
map(notifications => notifications.filter(n => !n.readDate).length > 0),
|
||||
distinctUntilChanged(),
|
||||
shareLast(),
|
||||
);
|
||||
}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
await this._loadData();
|
||||
|
||||
this.addSubscription = timer(CHANGED_CHECK_INTERVAL, CHANGED_CHECK_INTERVAL)
|
||||
.pipe(
|
||||
switchMap(() => this._notificationsService.getNotificationsIfChanged(INCLUDE_SEEN)),
|
||||
tap(notifications => this._notifications$.next(notifications)),
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
async markRead($event, notifications: List<string> = this._notifications$.getValue().map(n => n.id), isRead = true): Promise<void> {
|
||||
async markRead($event, notifications: Notification[] = this._notificationsService.all, isRead = true): Promise<void> {
|
||||
$event.stopPropagation();
|
||||
await firstValueFrom(this._notificationsService.toggleNotificationRead(notifications, isRead));
|
||||
await this._loadData();
|
||||
}
|
||||
|
||||
private async _loadData(): Promise<void> {
|
||||
const notifications = await firstValueFrom(this._notificationsService.getNotifications(INCLUDE_SEEN));
|
||||
this._notifications$.next(notifications);
|
||||
if (!notifications.find(notification => !!notification.readDate !== isRead)) {
|
||||
// If no notification changes status after the request, abort
|
||||
return;
|
||||
}
|
||||
await firstValueFrom(
|
||||
this._notificationsService.toggleNotificationRead(
|
||||
notifications.map(n => n.id),
|
||||
isRead,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private _groupNotifications(notifications: Notification[]): NotificationsGroup[] {
|
||||
|
||||
@ -22,7 +22,7 @@ export class AccountSideNavComponent {
|
||||
},
|
||||
{
|
||||
screen: 'notifications',
|
||||
label: _('notifications'),
|
||||
label: _('notifications.label'),
|
||||
hideIf: !this._userService.currentUser.isUser,
|
||||
},
|
||||
];
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { lastIndexOfEnd } from '@utils/functions';
|
||||
import { AutoUnsubscribe, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { RouterHistoryService } from '@services/router-history.service';
|
||||
import { DigitalSignatureService } from '../../services/digital-signature.service';
|
||||
import { IDigitalSignature, IDigitalSignatureRequest } from '@red/domain';
|
||||
import { IDigitalSignature } from '@red/domain';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { HttpStatusCode } from '@angular/common/http';
|
||||
|
||||
@Component({
|
||||
@ -14,7 +15,7 @@ import { HttpStatusCode } from '@angular/common/http';
|
||||
templateUrl: './digital-signature-screen.component.html',
|
||||
styleUrls: ['./digital-signature-screen.component.scss'],
|
||||
})
|
||||
export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements OnDestroy {
|
||||
export class DigitalSignatureScreenComponent implements OnInit {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
|
||||
@ -30,16 +31,18 @@ export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements
|
||||
private readonly _loadingService: LoadingService,
|
||||
readonly routerHistoryService: RouterHistoryService,
|
||||
private readonly _digitalSignatureService: DigitalSignatureService,
|
||||
) {
|
||||
super();
|
||||
this.loadDigitalSignatureAndInitializeForm();
|
||||
}
|
||||
) {}
|
||||
|
||||
get hasDigitalSignatureSet() {
|
||||
return this.digitalSignatureExists || !!this.form.get('base64EncodedPrivateKey').value;
|
||||
}
|
||||
|
||||
saveDigitalSignature() {
|
||||
async ngOnInit(): Promise<void> {
|
||||
await this.loadDigitalSignatureAndInitializeForm();
|
||||
}
|
||||
|
||||
async saveDigitalSignature(): Promise<void> {
|
||||
this._loadingService.start();
|
||||
const formValue = this.form.getRawValue();
|
||||
const digitalSignature: IDigitalSignature = {
|
||||
...formValue,
|
||||
@ -51,29 +54,32 @@ export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements
|
||||
? this._digitalSignatureService.update(digitalSignature)
|
||||
: this._digitalSignatureService.save(digitalSignature);
|
||||
|
||||
this.addSubscription = observable.subscribe({
|
||||
next: () => {
|
||||
this.loadDigitalSignatureAndInitializeForm();
|
||||
this._toaster.success(_('digital-signature-screen.action.save-success'));
|
||||
},
|
||||
error: error => {
|
||||
if (error.status === HttpStatusCode.BadRequest) {
|
||||
this._toaster.error(_('digital-signature-screen.action.certificate-not-valid-error'));
|
||||
} else {
|
||||
this._toaster.error(_('digital-signature-screen.action.save-error'));
|
||||
}
|
||||
},
|
||||
});
|
||||
try {
|
||||
await firstValueFrom(observable);
|
||||
await this.loadDigitalSignatureAndInitializeForm();
|
||||
this._toaster.success(_('digital-signature-screen.action.save-success'));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
if (error.status === HttpStatusCode.BadRequest) {
|
||||
this._toaster.error(_('digital-signature-screen.action.certificate-not-valid-error'));
|
||||
} else {
|
||||
this._toaster.error(_('digital-signature-screen.action.save-error'));
|
||||
}
|
||||
}
|
||||
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
removeDigitalSignature() {
|
||||
this.addSubscription = this._digitalSignatureService.delete().subscribe(
|
||||
() => {
|
||||
this.loadDigitalSignatureAndInitializeForm();
|
||||
this._toaster.success(_('digital-signature-screen.action.delete-success'));
|
||||
},
|
||||
() => this._toaster.error(_('digital-signature-screen.action.delete-error')),
|
||||
);
|
||||
async removeDigitalSignature(): Promise<void> {
|
||||
this._loadingService.start();
|
||||
try {
|
||||
await firstValueFrom(this._digitalSignatureService.delete());
|
||||
await this.loadDigitalSignatureAndInitializeForm();
|
||||
this._toaster.success(_('digital-signature-screen.action.delete-success'));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
this._toaster.error(_('digital-signature-screen.action.delete-error'));
|
||||
}
|
||||
}
|
||||
|
||||
fileChanged(event, input: HTMLInputElement) {
|
||||
@ -89,24 +95,19 @@ export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements
|
||||
fileReader.readAsDataURL(file as Blob);
|
||||
}
|
||||
|
||||
loadDigitalSignatureAndInitializeForm() {
|
||||
async loadDigitalSignatureAndInitializeForm(): Promise<void> {
|
||||
this._loadingService.start();
|
||||
this._digitalSignatureService
|
||||
.getSignature()
|
||||
.subscribe({
|
||||
next: digitalSignature => {
|
||||
this.digitalSignatureExists = true;
|
||||
this.digitalSignature = digitalSignature;
|
||||
},
|
||||
error: () => {
|
||||
this.digitalSignatureExists = false;
|
||||
this.digitalSignature = {};
|
||||
},
|
||||
})
|
||||
.add(() => {
|
||||
this.form = this._getForm();
|
||||
this._loadingService.stop();
|
||||
});
|
||||
try {
|
||||
const digitalSignature = await firstValueFrom(this._digitalSignatureService.getSignature());
|
||||
this.digitalSignatureExists = true;
|
||||
this.digitalSignature = digitalSignature;
|
||||
} catch (error) {
|
||||
this.digitalSignatureExists = false;
|
||||
this.digitalSignature = {};
|
||||
}
|
||||
|
||||
this.form = this._getForm();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
private _getForm(): FormGroup {
|
||||
|
||||
@ -1,56 +1,65 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { GenericService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { Inject, Injectable, Injector } from '@angular/core';
|
||||
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { EMPTY, iif, Observable } from 'rxjs';
|
||||
import { INotification, Notification, NotificationTypes } from '@red/domain';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { EMPTY, iif, Observable, of, timer } from 'rxjs';
|
||||
import { Dossier, INotification, Notification, NotificationTypes } from '@red/domain';
|
||||
import { map, switchMap, tap } from 'rxjs/operators';
|
||||
import { notificationsTranslations } from '../translations/notifications-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { ActiveDossiersService } from './dossiers/active-dossiers.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
import dayjs from 'dayjs';
|
||||
import { CHANGED_CHECK_INTERVAL } from '@utils/constants';
|
||||
import { BASE_HREF } from '../tokens';
|
||||
import { ArchivedDossiersService } from '@services/dossiers/archived-dossiers.service';
|
||||
|
||||
const INCLUDE_SEEN = false;
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class NotificationsService extends GenericService<Notification> {
|
||||
export class NotificationsService extends EntitiesService<Notification, INotification> {
|
||||
constructor(
|
||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _activeDossiersService: ActiveDossiersService,
|
||||
private readonly _archivedDossiersService: ArchivedDossiersService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
) {
|
||||
super(_injector, 'notification');
|
||||
super(_injector, Notification, 'notification');
|
||||
|
||||
timer(0, CHANGED_CHECK_INTERVAL)
|
||||
.pipe(
|
||||
switchMap(() => (this._activeDossiersService.all.length ? of(null) : this._activeDossiersService.loadAll())),
|
||||
switchMap(() => (this._archivedDossiersService.all.length ? of(null) : this._archivedDossiersService.loadAll())),
|
||||
switchMap(() => this.#loadNotificationsIfChanged()),
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
@Validate()
|
||||
getNotifications(@RequiredParam() includeSeen: boolean): Observable<Notification[]> {
|
||||
let queryParam: QueryParam;
|
||||
if (includeSeen !== undefined && includeSeen !== null) {
|
||||
queryParam = { key: 'includeSeen', value: includeSeen };
|
||||
}
|
||||
|
||||
return this.getAll<{ notifications: Notification[] }>(this._defaultModelPath, [queryParam]).pipe(
|
||||
map(response => response.notifications.filter(n => n.notificationType in NotificationTypes)),
|
||||
mapEach(notification => this._new(notification)),
|
||||
);
|
||||
}
|
||||
|
||||
@Validate()
|
||||
getNotificationsIfChanged(@RequiredParam() includeSeen: boolean): Observable<Notification[]> {
|
||||
return this.hasChanges$().pipe(switchMap(changed => iif(() => changed, this.getNotifications(includeSeen), EMPTY)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
toggleNotificationRead(@RequiredParam() body: List, @RequiredParam() setRead: boolean) {
|
||||
toggleNotificationRead(@RequiredParam() body: List, @RequiredParam() setRead: boolean): Observable<unknown> {
|
||||
let queryParam: QueryParam;
|
||||
if (setRead !== undefined && setRead !== null) {
|
||||
queryParam = { key: 'setRead', value: setRead };
|
||||
}
|
||||
|
||||
return this._post(body, `${this._defaultModelPath}/toggle-read`, [queryParam]);
|
||||
return this._post(body, `${this._defaultModelPath}/toggle-read`, [queryParam]).pipe(switchMap(() => this.#loadAll()));
|
||||
}
|
||||
|
||||
#loadAll(includeSeen = INCLUDE_SEEN): Observable<Notification[]> {
|
||||
const queryParam: QueryParam = { key: 'includeSeen', value: includeSeen };
|
||||
|
||||
return this.getAll<{ notifications: Notification[] }>(this._defaultModelPath, [queryParam]).pipe(
|
||||
map(response => response.notifications.filter(n => n.notificationType in NotificationTypes)),
|
||||
mapEach(notification => this._new(notification)),
|
||||
tap(notifications => this.setEntities(notifications)),
|
||||
);
|
||||
}
|
||||
|
||||
#loadNotificationsIfChanged(): Observable<Notification[]> {
|
||||
return this.hasChanges$().pipe(switchMap(changed => iif(() => changed, this.#loadAll(), EMPTY)));
|
||||
}
|
||||
|
||||
private _new(notification: INotification) {
|
||||
@ -66,25 +75,27 @@ export class NotificationsService extends GenericService<Notification> {
|
||||
private _translate(notification: INotification, translation: string): string {
|
||||
const fileId = notification.target.fileId;
|
||||
const dossierId = notification.target.dossierId;
|
||||
const dossier = this._activeDossiersService.find(dossierId);
|
||||
const dossier = this._activeDossiersService.find(dossierId) || this._archivedDossiersService.find(dossierId);
|
||||
const fileName = notification.target.fileName;
|
||||
|
||||
return this._translateService.instant(translation, {
|
||||
fileHref: this._getFileHref(dossierId, fileId),
|
||||
dossierHref: this._getDossierHref(dossierId),
|
||||
dossierName: notification.target?.dossierName || dossier?.dossierName || this._translateService.instant(_('dossier')),
|
||||
fileHref: this._getFileHref(dossier, fileId),
|
||||
dossierHref: this._getDossierHref(dossier),
|
||||
dossierName:
|
||||
notification.target?.dossierName ||
|
||||
dossier?.dossierName ||
|
||||
this._translateService.instant(_('notifications.deleted-dossier')),
|
||||
fileName: fileName || this._translateService.instant(_('file')),
|
||||
user: this._getUsername(notification.userId),
|
||||
});
|
||||
}
|
||||
|
||||
private _getFileHref(dossierId: string, fileId: string): string {
|
||||
const dossierHref = this._getDossierHref(dossierId);
|
||||
return `${dossierHref}/file/${fileId}`;
|
||||
private _getFileHref(dossier: Dossier, fileId: string): string {
|
||||
return dossier ? `${this._getDossierHref(dossier)}/file/${fileId}` : null;
|
||||
}
|
||||
|
||||
private _getDossierHref(dossierId: string): string {
|
||||
return `/ui/main/dossiers/${dossierId}`;
|
||||
private _getDossierHref(dossier: Dossier): string {
|
||||
return dossier ? `${this._baseHref}${dossier.routerLink}` : null;
|
||||
}
|
||||
|
||||
private _getUsername(userId: string | undefined) {
|
||||
|
||||
@ -665,7 +665,6 @@
|
||||
"save": "Dokumenteninformation speichern",
|
||||
"title": "Datei-Attribute anlegen"
|
||||
},
|
||||
"dossier": "Dossier",
|
||||
"dossier-attribute-types": {
|
||||
"date": "Datum",
|
||||
"image": "Bild",
|
||||
@ -1530,21 +1529,20 @@
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"assign-approver": "Sie wurden dem Dokument <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> im Dossier <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a><b> als Genehmiger zugewiesen!",
|
||||
"assign-reviewer": "Sie wurden dem Dokument <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> im Dossier <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a><b> als Reviewer zugewiesen!",
|
||||
"document-approved": "<b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> wurde genehmigt!",
|
||||
"assign-approver": "Sie wurden dem Dokument <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}<b> als Genehmiger zugewiesen!",
|
||||
"assign-reviewer": "Sie wurden dem Dokument <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}<b> als Reviewer zugewiesen!",
|
||||
"document-approved": "<b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> wurde genehmigt!",
|
||||
"dossier-deleted": "Dossier: <b>{dossierName}</b> wurde gelöscht!",
|
||||
"dossier-owner-removed": "Der Dossier-Owner von <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> wurde entfernt!",
|
||||
"dossier-owner-set": "Eigentümer von <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> geändert zu <b>{user}</b>!",
|
||||
"dossier-owner-removed": "Der Dossier-Owner von <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> wurde entfernt!",
|
||||
"dossier-owner-set": "Eigentümer von <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> geändert zu <b>{user}</b>!",
|
||||
"download-ready": "Ihr <b><a href='/ui/main/downloads', target=\"_blank\">Download</a></b> ist fertig!",
|
||||
"no-data": "Du hast aktuell keine Benachrichtigungen",
|
||||
"unassigned-from-file": "Sie wurden vom Dokument <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> im Dossier <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a><b> entfernt!",
|
||||
"user-becomes-dossier-member": "<b>{user}</b> ist jetzt Mitglied des Dossiers <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!",
|
||||
"user-demoted-to-reviewer": "<b>{user}</b> wurde im Dossier <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> auf die Reviewer-Berechtigung heruntergestuft!",
|
||||
"user-promoted-to-approver": "<b>{user}</b> wurde im Dossier <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> zum Genehmiger ernannt!",
|
||||
"user-removed-as-dossier-member": "<b>{user}</b> wurde als Mitglied von: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> entfernt!"
|
||||
"unassigned-from-file": "Sie wurden vom Dokument <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}<b> entfernt!",
|
||||
"user-becomes-dossier-member": "<b>{user}</b> ist jetzt Mitglied des Dossiers <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"user-demoted-to-reviewer": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> auf die Reviewer-Berechtigung heruntergestuft!",
|
||||
"user-promoted-to-approver": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> zum Genehmiger ernannt!",
|
||||
"user-removed-as-dossier-member": "<b>{user}</b> wurde als Mitglied von: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> entfernt!"
|
||||
},
|
||||
"notifications": "Benachrichtigungen",
|
||||
"notifications-screen": {
|
||||
"category": {
|
||||
"email-notifications": "E-Mail Benachrichtigungen",
|
||||
@ -1583,6 +1581,11 @@
|
||||
},
|
||||
"title": "Benachrichtigungseinstellungen"
|
||||
},
|
||||
"notifications": {
|
||||
"deleted-dossier": "",
|
||||
"label": "Benachrichtigungen",
|
||||
"mark-as": ""
|
||||
},
|
||||
"ocr": {
|
||||
"confirmation-dialog": {
|
||||
"cancel": "",
|
||||
|
||||
@ -665,7 +665,6 @@
|
||||
"save": "Save Document Info",
|
||||
"title": "Introduce File Attributes"
|
||||
},
|
||||
"dossier": "Dossier",
|
||||
"dossier-attribute-types": {
|
||||
"date": "Date",
|
||||
"image": "Image",
|
||||
@ -1530,21 +1529,20 @@
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"assign-approver": "You have been assigned as approver for <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> in dossier: <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 dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a><b>!",
|
||||
"document-approved": " <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> has been approved!",
|
||||
"assign-approver": "You have been assigned as approver for <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"assign-reviewer": "You have been assigned as reviewer for <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"document-approved": " <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> has been approved!",
|
||||
"dossier-deleted": "Dossier: <b>{dossierName}</b> has been deleted!",
|
||||
"dossier-owner-removed": "You have been removed as dossier owner from <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!",
|
||||
"dossier-owner-set": "You are now the dossier owner of <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!",
|
||||
"dossier-owner-removed": "You have been removed as dossier owner from <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"dossier-owner-set": "You are now the dossier owner of <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"download-ready": "Your <b><a href='/ui/main/downloads', target=\"_blank\">download</a></b> is ready!",
|
||||
"no-data": "You currently have no notifications",
|
||||
"unassigned-from-file": "You have been unassigned from <b><a href=\"{fileHref}\" target=\"_blank\">{fileName}</a></b> in dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a><b>!",
|
||||
"user-becomes-dossier-member": "You have been added to dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!",
|
||||
"user-demoted-to-reviewer": "You have been demoted to reviewer in dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!",
|
||||
"user-promoted-to-approver": "You have been promoted to approver in dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b>!",
|
||||
"user-removed-as-dossier-member": "You have been removed as a member from dossier: <b><a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a></b> !"
|
||||
"unassigned-from-file": "You have been unassigned from <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>!",
|
||||
"user-becomes-dossier-member": "You have been added to dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"user-demoted-to-reviewer": "You have been demoted to reviewer in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"user-promoted-to-approver": "You have been promoted to approver in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"user-removed-as-dossier-member": "You have been removed as a member from dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!"
|
||||
},
|
||||
"notifications": "Notifications",
|
||||
"notifications-screen": {
|
||||
"category": {
|
||||
"email-notifications": "Email Notifications",
|
||||
@ -1583,6 +1581,11 @@
|
||||
},
|
||||
"title": "Notifications Preferences"
|
||||
},
|
||||
"notifications": {
|
||||
"deleted-dossier": "Deleted Dossier",
|
||||
"label": "Notifications",
|
||||
"mark-as": "Mark as {type, select, read{read} unread{unread} other{}}"
|
||||
},
|
||||
"ocr": {
|
||||
"confirmation-dialog": {
|
||||
"cancel": "Cancel",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "redaction",
|
||||
"version": "3.376.0",
|
||||
"version": "3.377.0",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user