@@ -100,9 +75,7 @@
@@ -139,6 +112,4 @@
-
+
diff --git a/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.ts
index 0ebbfb000..a5ac0a556 100644
--- a/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.ts
+++ b/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.ts
@@ -1,17 +1,17 @@
-import { Component } from '@angular/core';
+import { Component, OnDestroy } from '@angular/core';
import { DigitalSignature, DigitalSignatureControllerService } from '@redaction/red-ui-http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
-import { NotificationService, NotificationType } from '@services/notification.service';
-import { TranslateService } from '@ngx-translate/core';
+import { Toaster } from '../../../../services/toaster.service';
import { PermissionsService } from '@services/permissions.service';
import { lastIndexOfEnd } from '@utils/functions';
+import { AutoUnsubscribeComponent } from '../../../shared/base/auto-unsubscribe.component';
@Component({
selector: 'redaction-digital-signature-screen',
templateUrl: './digital-signature-screen.component.html',
styleUrls: ['./digital-signature-screen.component.scss']
})
-export class DigitalSignatureScreenComponent {
+export class DigitalSignatureScreenComponent extends AutoUnsubscribeComponent implements OnDestroy {
digitalSignature: DigitalSignature;
digitalSignatureForm: FormGroup;
@@ -20,11 +20,11 @@ export class DigitalSignatureScreenComponent {
constructor(
private readonly _digitalSignatureControllerService: DigitalSignatureControllerService,
- private readonly _notificationService: NotificationService,
+ private readonly _toaster: Toaster,
private readonly _formBuilder: FormBuilder,
- private readonly _translateService: TranslateService,
readonly permissionsService: PermissionsService
) {
+ super();
this.loadDigitalSignatureAndInitializeForm();
}
@@ -43,50 +43,28 @@ export class DigitalSignatureScreenComponent {
? this._digitalSignatureControllerService.updateDigitalSignature(digitalSignature)
: this._digitalSignatureControllerService.saveDigitalSignature(digitalSignature);
- observable.subscribe(
+ this.addSubscription = observable.subscribe(
() => {
this.loadDigitalSignatureAndInitializeForm();
- this._notificationService.showToastNotification(
- this._translateService.instant('digital-signature-screen.action.save-success'),
- null,
- NotificationType.SUCCESS
- );
+ this._toaster.success('digital-signature-screen.action.save-success');
},
error => {
if (error.status === 400) {
- this._notificationService.showToastNotification(
- this._translateService.instant('digital-signature-screen.action.certificate-not-valid-error'),
- null,
- NotificationType.ERROR
- );
+ this._toaster.error('digital-signature-screen.action.certificate-not-valid-error');
} else {
- this._notificationService.showToastNotification(
- this._translateService.instant('digital-signature-screen.action.save-error'),
- null,
- NotificationType.ERROR
- );
+ this._toaster.error('digital-signature-screen.action.save-error');
}
}
);
}
removeDigitalSignature() {
- this._digitalSignatureControllerService.deleteDigitalSignature().subscribe(
+ this.addSubscription = this._digitalSignatureControllerService.deleteDigitalSignature().subscribe(
() => {
this.loadDigitalSignatureAndInitializeForm();
- this._notificationService.showToastNotification(
- this._translateService.instant('digital-signature-screen.action.delete-success'),
- null,
- NotificationType.SUCCESS
- );
+ this._toaster.success('digital-signature-screen.action.delete-success');
},
- () => {
- this._notificationService.showToastNotification(
- this._translateService.instant('digital-signature-screen.action.delete-error'),
- null,
- NotificationType.ERROR
- );
- }
+ () => this._toaster.error('digital-signature-screen.action.delete-error')
);
}
@@ -105,7 +83,7 @@ export class DigitalSignatureScreenComponent {
loadDigitalSignatureAndInitializeForm() {
this.viewReady = false;
- this._digitalSignatureControllerService
+ this.addSubscription = this._digitalSignatureControllerService
.getDigitalSignature()
.subscribe(
digitalSignature => {
@@ -123,8 +101,6 @@ export class DigitalSignatureScreenComponent {
});
}
- formChanged() {}
-
private _initForm() {
this.digitalSignatureForm = this._formBuilder.group({
certificateName: [this.digitalSignature.certificateName, Validators.required],
diff --git a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts
index 8f266eebd..d8a6552a7 100644
--- a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts
+++ b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts
@@ -1,7 +1,7 @@
-import { Component, ElementRef, ViewChild } from '@angular/core';
+import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { RulesControllerService } from '@redaction/red-ui-http';
-import { NotificationService, NotificationType } from '@services/notification.service';
+import { Toaster } from '../../../../services/toaster.service';
import { TranslateService } from '@ngx-translate/core';
import { saveAs } from 'file-saver';
import { ComponentHasChanges } from '@guards/can-deactivate.guard';
@@ -17,7 +17,7 @@ import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorCon
templateUrl: './rules-screen.component.html',
styleUrls: ['./rules-screen.component.scss']
})
-export class RulesScreenComponent extends ComponentHasChanges {
+export class RulesScreenComponent extends ComponentHasChanges implements OnInit {
editorOptions: IStandaloneEditorConstructionOptions = {
theme: 'vs',
language: 'java',
@@ -39,13 +39,16 @@ export class RulesScreenComponent extends ComponentHasChanges {
readonly permissionsService: PermissionsService,
private readonly _rulesControllerService: RulesControllerService,
private readonly _appStateService: AppStateService,
- private readonly _notificationService: NotificationService,
+ private readonly _toaster: Toaster,
protected readonly _translateService: TranslateService,
private readonly _activatedRoute: ActivatedRoute
) {
super(_translateService);
- this._appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
- this._initialize();
+ _appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
+ }
+
+ async ngOnInit() {
+ await this._initialize();
}
get hasChanges(): boolean {
@@ -83,27 +86,20 @@ export class RulesScreenComponent extends ComponentHasChanges {
async save(): Promise
{
this.processing = true;
- this._rulesControllerService
+ await this._rulesControllerService
.uploadRules({
rules: this._codeEditor.getModel().getValue(),
dossierTemplateId: this._appStateService.activeDossierTemplateId
})
- .subscribe(
- () => {
- this._initialize();
- this._notificationService.showToastNotification(
- this._translateService.instant('rules-screen.success.generic'),
- null,
- NotificationType.SUCCESS
- );
+ .toPromise()
+ .then(
+ async () => {
+ await this._initialize();
+ this._toaster.success('rules-screen.success.generic');
},
() => {
this.processing = false;
- this._notificationService.showToastNotification(
- this._translateService.instant('rules-screen.error.generic'),
- null,
- NotificationType.ERROR
- );
+ this._toaster.error('rules-screen.error.generic');
}
);
}
@@ -148,13 +144,16 @@ export class RulesScreenComponent extends ComponentHasChanges {
} as IModelDeltaDecoration;
}
- private _initialize() {
- this._rulesControllerService.downloadRules(this._appStateService.activeDossierTemplateId).subscribe(
- rules => {
- this.currentLines = this.initialLines = rules.rules.split('\n');
- this.revert();
- },
- () => (this.processing = false)
- );
+ private async _initialize() {
+ await this._rulesControllerService
+ .downloadRules(this._appStateService.activeDossierTemplateId)
+ .toPromise()
+ .then(
+ rules => {
+ this.currentLines = this.initialLines = rules.rules.split('\n');
+ this.revert();
+ },
+ () => (this.processing = false)
+ );
}
}
diff --git a/apps/red-ui/src/app/modules/admin/screens/smtp-config/smtp-config-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/smtp-config/smtp-config-screen.component.ts
index b36206694..33cef2580 100644
--- a/apps/red-ui/src/app/modules/admin/screens/smtp-config/smtp-config-screen.component.ts
+++ b/apps/red-ui/src/app/modules/admin/screens/smtp-config/smtp-config-screen.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnDestroy, OnInit } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AdminDialogService } from '../../services/admin-dialog.service';
@@ -8,15 +8,15 @@ import {
SmtpConfigurationControllerService,
SMTPConfigurationModel
} from '@redaction/red-ui-http';
-import { NotificationService, NotificationType } from '@services/notification.service';
-import { TranslateService } from '@ngx-translate/core';
+import { Toaster } from '../../../../services/toaster.service';
+import { AutoUnsubscribeComponent } from '../../../shared/base/auto-unsubscribe.component';
@Component({
selector: 'redaction-smtp-config-screen',
templateUrl: './smtp-config-screen.component.html',
styleUrls: ['./smtp-config-screen.component.scss']
})
-export class SmtpConfigScreenComponent implements OnInit {
+export class SmtpConfigScreenComponent extends AutoUnsubscribeComponent implements OnInit, OnDestroy {
viewReady = false;
configForm: FormGroup;
generalSettings: GeneralConfigurationModel = {
@@ -31,11 +31,11 @@ export class SmtpConfigScreenComponent implements OnInit {
private readonly _smtpConfigService: SmtpConfigurationControllerService,
private readonly _formBuilder: FormBuilder,
private readonly _dialogService: AdminDialogService,
- private readonly _notificationService: NotificationService,
- private readonly _translateService: TranslateService,
+ private readonly _toaster: Toaster,
private readonly _generalSettingsControllerService: GeneralSettingsControllerService
) {
- this.configForm = this._formBuilder.group({
+ super();
+ this.configForm = _formBuilder.group({
host: [undefined, Validators.required],
port: [25],
from: [undefined, [Validators.required, Validators.email]],
@@ -50,7 +50,7 @@ export class SmtpConfigScreenComponent implements OnInit {
password: [undefined]
});
- this.configForm.controls.auth.valueChanges.subscribe(auth => {
+ this.addSubscription = this.configForm.controls.auth.valueChanges.subscribe(auth => {
if (auth) {
this.openAuthConfigDialog();
}
@@ -110,17 +110,9 @@ export class SmtpConfigScreenComponent implements OnInit {
this.viewReady = false;
try {
await this._smtpConfigService.testSMTPConfiguration(this.configForm.getRawValue()).toPromise();
- this._notificationService.showToastNotification(
- this._translateService.instant('smtp-config-screen.test.success'),
- undefined,
- NotificationType.SUCCESS
- );
+ this._toaster.success('smtp-config-screen.test.success');
} catch (e) {
- this._notificationService.showToastNotification(
- this._translateService.instant('smtp-config-screen.test.error'),
- undefined,
- NotificationType.ERROR
- );
+ this._toaster.error('smtp-config-screen.test.error');
} finally {
this.viewReady = true;
}
diff --git a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts
index 3bc64a4da..627166a6e 100644
--- a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts
+++ b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts
@@ -7,8 +7,7 @@ import { HttpClient } from '@angular/common/http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { debounce } from '@utils/debounce';
import { WatermarkControllerService, WatermarkModelRes } from '@redaction/red-ui-http';
-import { NotificationService, NotificationType } from '@services/notification.service';
-import { TranslateService } from '@ngx-translate/core';
+import { Toaster } from '../../../../services/toaster.service';
import { ActivatedRoute } from '@angular/router';
import { BASE_HREF } from '../../../../tokens';
import { stampPDFPage } from '../../../../utils/page-stamper';
@@ -39,15 +38,14 @@ export class WatermarkScreenComponent implements OnInit {
readonly permissionsService: PermissionsService,
readonly appStateService: AppStateService,
@Inject(BASE_HREF) private readonly _baseHref: string,
- private readonly _translateService: TranslateService,
private readonly _watermarkControllerService: WatermarkControllerService,
- private readonly _notificationService: NotificationService,
+ private readonly _toaster: Toaster,
private readonly _http: HttpClient,
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _formBuilder: FormBuilder,
private readonly _activatedRoute: ActivatedRoute
) {
- this.appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
+ appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
this._initForm();
}
@@ -81,24 +79,12 @@ export class WatermarkScreenComponent implements OnInit {
? this._watermarkControllerService.saveWatermark(watermark, this.appStateService.activeDossierTemplateId)
: this._watermarkControllerService.deleteWatermark(this.appStateService.activeDossierTemplateId);
- observable.subscribe(
+ observable.toPromise().then(
() => {
this._loadWatermark();
- this._notificationService.showToastNotification(
- this._translateService.instant(
- watermark.text ? 'watermark-screen.action.change-success' : 'watermark-screen.action.delete-success'
- ),
- null,
- NotificationType.SUCCESS
- );
+ this._toaster.success(watermark.text ? 'watermark-screen.action.change-success' : 'watermark-screen.action.delete-success');
},
- () => {
- this._notificationService.showToastNotification(
- this._translateService.instant('watermark-screen.action.error'),
- null,
- NotificationType.ERROR
- );
- }
+ () => this._toaster.error('watermark-screen.action.error')
);
}
@@ -188,11 +174,41 @@ export class WatermarkScreenComponent implements OnInit {
private _initForm() {
this.configForm = this._formBuilder.group({
text: [{ value: null, disabled: !this.permissionsService.isAdmin() }],
- hexColor: [{ value: null, disabled: !this.permissionsService.isAdmin() }, Validators.required],
- opacity: [{ value: null, disabled: !this.permissionsService.isAdmin() }, Validators.required],
- fontSize: [{ value: null, disabled: !this.permissionsService.isAdmin() }, Validators.required],
- fontType: [{ value: null, disabled: !this.permissionsService.isAdmin() }, Validators.required],
- orientation: [{ value: null, disabled: !this.permissionsService.isAdmin() }, Validators.required]
+ hexColor: [
+ {
+ value: null,
+ disabled: !this.permissionsService.isAdmin()
+ },
+ Validators.required
+ ],
+ opacity: [
+ {
+ value: null,
+ disabled: !this.permissionsService.isAdmin()
+ },
+ Validators.required
+ ],
+ fontSize: [
+ {
+ value: null,
+ disabled: !this.permissionsService.isAdmin()
+ },
+ Validators.required
+ ],
+ fontType: [
+ {
+ value: null,
+ disabled: !this.permissionsService.isAdmin()
+ },
+ Validators.required
+ ],
+ orientation: [
+ {
+ value: null,
+ disabled: !this.permissionsService.isAdmin()
+ },
+ Validators.required
+ ]
});
}
}
diff --git a/apps/red-ui/src/app/modules/dossier/components/dossier-details/dossier-details.component.ts b/apps/red-ui/src/app/modules/dossier/components/dossier-details/dossier-details.component.ts
index 39de289e9..f212e5115 100644
--- a/apps/red-ui/src/app/modules/dossier/components/dossier-details/dossier-details.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/components/dossier-details/dossier-details.component.ts
@@ -7,9 +7,9 @@ import { TranslateChartService } from '@services/translate-chart.service';
import { StatusSorter } from '@utils/sorters/status-sorter';
import { UserService } from '@services/user.service';
import { User } from '@redaction/red-ui-http';
-import { NotificationService } from '@services/notification.service';
-import { FilterService } from '@shared/services/filter.service';
-import { FileStatusWrapper } from '@models/file/file-status.wrapper';
+import { Toaster } from '../../../../services/toaster.service';
+import { FilterService } from '../../../shared/services/filter.service';
+import { FileStatusWrapper } from '../../../../models/file/file-status.wrapper';
import { DossierAttributeWithValue } from '@models/dossier-attributes.model';
@Component({
@@ -34,7 +34,7 @@ export class DossierDetailsComponent implements OnInit {
readonly filterService: FilterService,
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _userService: UserService,
- private readonly _notificationService: NotificationService
+ private readonly _toaster: Toaster
) {}
get memberIds(): string[] {
@@ -86,6 +86,6 @@ export class DossierDetailsComponent implements OnInit {
const ownerName = this._userService.getNameForId(this.owner.userId);
const dossierName = this.appStateService.activeDossier.name;
const msg = 'Successfully assigned ' + ownerName + ' to dossier: ' + dossierName;
- this._notificationService.showToastNotification(msg);
+ this._toaster.info(msg);
}
}
diff --git a/apps/red-ui/src/app/modules/dossier/components/page-exclusion/page-exclusion.component.ts b/apps/red-ui/src/app/modules/dossier/components/page-exclusion/page-exclusion.component.ts
index 7245e5ccc..0dd8eb2bb 100644
--- a/apps/red-ui/src/app/modules/dossier/components/page-exclusion/page-exclusion.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/components/page-exclusion/page-exclusion.component.ts
@@ -2,9 +2,9 @@ import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from
import { PermissionsService } from '@services/permissions.service';
import { FormBuilder, FormGroup } from '@angular/forms';
import { PageRange, ReanalysisControllerService } from '@redaction/red-ui-http';
-import { FileDataModel } from '@models/file/file-data.model';
-import { NotificationService, NotificationType } from '@services/notification.service';
-import { LoadingService } from '@services/loading.service';
+import { FileDataModel } from '../../../../models/file/file-data.model';
+import { Toaster } from '../../../../services/toaster.service';
+import { LoadingService } from '../../../../services/loading.service';
import { TranslateService } from '@ngx-translate/core';
@Component({
@@ -23,9 +23,8 @@ export class PageExclusionComponent implements OnChanges {
readonly permissionsService: PermissionsService,
private readonly _formBuilder: FormBuilder,
private readonly _reanalysisControllerService: ReanalysisControllerService,
- private readonly _notificationService: NotificationService,
- private readonly _loadingService: LoadingService,
- private readonly _translateService: TranslateService
+ private readonly _toaster: Toaster,
+ private readonly _loadingService: LoadingService
) {
this.excludePagesForm = this._formBuilder.group({
value: ['']
@@ -80,11 +79,7 @@ export class PageExclusionComponent implements OnChanges {
this.excludePagesForm.reset();
this.actionPerformed.emit('exclude-pages');
} catch (e) {
- this._notificationService.showToastNotification(
- this._translateService.instant('file-preview.tabs.exclude-pages.error'),
- null,
- NotificationType.ERROR
- );
+ this._toaster.error('file-preview.tabs.exclude-pages.error');
this._loadingService.stop();
}
}
diff --git a/apps/red-ui/src/app/modules/dossier/components/team-members-manager/team-members-manager.component.ts b/apps/red-ui/src/app/modules/dossier/components/team-members-manager/team-members-manager.component.ts
index 85e32b0d4..665fa19c8 100644
--- a/apps/red-ui/src/app/modules/dossier/components/team-members-manager/team-members-manager.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/components/team-members-manager/team-members-manager.component.ts
@@ -1,8 +1,8 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { Dossier, DossierControllerService, StatusControllerService } from '@redaction/red-ui-http';
+import { Dossier } from '@redaction/red-ui-http';
import { AppStateService } from '@state/app-state.service';
import { UserService } from '@services/user.service';
-import { NotificationService, NotificationType } from '@services/notification.service';
+import { Toaster } from '../../../../services/toaster.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { DossierWrapper } from '@state/model/dossier.wrapper';
@@ -21,10 +21,8 @@ export class TeamMembersManagerComponent implements OnInit {
constructor(
readonly userService: UserService,
- private readonly _dossierControllerService: DossierControllerService,
- private readonly _notificationService: NotificationService,
+ private readonly _toaster: Toaster,
private readonly _formBuilder: FormBuilder,
- private readonly _statusControllerService: StatusControllerService,
private readonly _appStateService: AppStateService
) {}
@@ -91,11 +89,7 @@ export class TeamMembersManagerComponent implements OnInit {
result = await this._appStateService.createOrUpdateDossier(dw.dossier);
this.save.emit(result);
} catch (error) {
- this._notificationService.showToastNotification(
- 'Failed: ' + error.error ? error.error.message : error,
- null,
- NotificationType.ERROR
- );
+ this._toaster.error('Failed: ' + error.error ? error.error.message : error);
}
}
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component.ts
index 0c7390409..b82a86f1d 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component.ts
@@ -1,9 +1,9 @@
import { Component, Inject } from '@angular/core';
-import { DossierControllerService, StatusControllerService } from '@redaction/red-ui-http';
+import { StatusControllerService } from '@redaction/red-ui-http';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AppStateService } from '@state/app-state.service';
import { UserService } from '@services/user.service';
-import { NotificationService, NotificationType } from '@services/notification.service';
+import { Toaster } from '../../../../services/toaster.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { DossierWrapper } from '@state/model/dossier.wrapper';
@@ -16,7 +16,6 @@ class DialogData {
}
@Component({
- selector: 'redaction-dossier-details-dialog',
templateUrl: './assign-reviewer-approver-dialog.component.html',
styleUrls: ['./assign-reviewer-approver-dialog.component.scss']
})
@@ -26,13 +25,12 @@ export class AssignReviewerApproverDialogComponent {
constructor(
readonly userService: UserService,
- private readonly _dossierControllerService: DossierControllerService,
- private readonly _notificationService: NotificationService,
+ private readonly _toaster: Toaster,
private readonly _formBuilder: FormBuilder,
private readonly _statusControllerService: StatusControllerService,
private readonly _appStateService: AppStateService,
- public dialogRef: MatDialogRef,
- @Inject(MAT_DIALOG_DATA) public data: DialogData
+ private readonly _dialogRef: MatDialogRef,
+ @Inject(MAT_DIALOG_DATA) readonly data: DialogData
) {
this._loadData();
}
@@ -52,10 +50,8 @@ export class AssignReviewerApproverDialogComponent {
return true;
}
- const reviewerId = this.selectedSingleUser;
-
for (const file of this.data.files) {
- if (file.currentReviewer !== reviewerId) {
+ if (file.currentReviewer !== this.selectedSingleUser) {
return true;
}
}
@@ -94,14 +90,10 @@ export class AssignReviewerApproverDialogComponent {
file.reviewerName = this.userService.getNameForId(selectedUser);
}
} catch (error) {
- this._notificationService.showToastNotification(
- 'Failed: ' + error.error ? error.error.message : error,
- null,
- NotificationType.ERROR
- );
+ this._toaster.error('Failed: ' + error.error ? error.error.message : error);
}
- this.dialogRef.close();
+ this._dialogRef.close();
}
private _loadData() {
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts
index 99c5b12d9..7e08320d3 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts
@@ -1,13 +1,10 @@
import { ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core';
-import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
-import { FormBuilder } from '@angular/forms';
-import { AppStateService } from '@state/app-state.service';
+import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { DossierWrapper } from '../../../../state/model/dossier.wrapper';
import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component';
import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component';
import { EditDossierSectionInterface } from './edit-dossier-section.interface';
-import { NotificationService, NotificationType } from '@services/notification.service';
-import { TranslateService } from '@ngx-translate/core';
+import { Toaster } from '../../../../services/toaster.service';
import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component';
import { EditDossierTeamMembersComponent } from './team-members/edit-dossier-team-members.component';
import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component';
@@ -38,12 +35,8 @@ export class EditDossierDialogComponent {
@ViewChild(EditDossierAttributesComponent) attributesComponent: EditDossierAttributesComponent;
constructor(
- private readonly _appStateService: AppStateService,
- private readonly _formBuilder: FormBuilder,
- private readonly _notificationService: NotificationService,
- private readonly _translateService: TranslateService,
+ private readonly _toaster: Toaster,
private readonly _changeRef: ChangeDetectorRef,
- private readonly _dialogRef: MatDialogRef,
@Inject(MAT_DIALOG_DATA)
private readonly _data: {
dossierWrapper: DossierWrapper;
@@ -82,11 +75,7 @@ export class EditDossierDialogComponent {
}
updatedDossier(updatedDossier: DossierWrapper) {
- this._notificationService.showToastNotification(
- this._translateService.instant('edit-dossier-dialog.change-successful'),
- null,
- NotificationType.SUCCESS
- );
+ this._toaster.success('edit-dossier-dialog.change-successful');
if (updatedDossier) {
this.dossierWrapper = updatedDossier;
@@ -111,11 +100,7 @@ export class EditDossierDialogComponent {
changeTab(key: Section) {
if (this.activeComponent.changed) {
- this._notificationService.showToastNotification(
- this._translateService.instant('edit-dossier-dialog.unsaved-changes'),
- null,
- NotificationType.ERROR
- );
+ this._toaster.error('edit-dossier-dialog.unsaved-changes');
return;
}
this.activeNav = key;
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts
index 3fd26d42d..dc52079f7 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts
@@ -10,8 +10,7 @@ import { PermissionsService } from '@services/permissions.service';
import { Router } from '@angular/router';
import { MatDialogRef } from '@angular/material/dialog';
import { EditDossierDialogComponent } from '../edit-dossier-dialog.component';
-import { NotificationService, NotificationType } from '../../../../../services/notification.service';
-import { TranslateService } from '@ngx-translate/core';
+import { Toaster } from '../../../../../services/toaster.service';
@Component({
selector: 'redaction-edit-dossier-general-info',
@@ -34,8 +33,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
private readonly _dialogService: DossiersDialogService,
private readonly _router: Router,
private readonly _editDossierDialogRef: MatDialogRef,
- private readonly _notificationService: NotificationService,
- private readonly _translateService: TranslateService
+ private readonly _toaster: Toaster
) {}
get changed() {
@@ -113,11 +111,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
}
private _notifyDossierDeleted() {
- this._notificationService.showToastNotification(
- this._translateService.instant('edit-dossier-dialog.delete-successful'),
- null,
- NotificationType.SUCCESS
- );
+ this._toaster.success('edit-dossier-dialog.delete-successful');
}
private _filterInvalidDossierTemplates() {
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/force-redaction-dialog/force-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/force-redaction-dialog/force-redaction-dialog.component.ts
index 8b905a9a1..c3de99226 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/force-redaction-dialog/force-redaction-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/force-redaction-dialog/force-redaction-dialog.component.ts
@@ -3,7 +3,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '@state/app-state.service';
import { MatDialogRef } from '@angular/material/dialog';
import { ForceRedactionRequest, LegalBasisMappingControllerService } from '@redaction/red-ui-http';
-import { NotificationService } from '@services/notification.service';
+import { Toaster } from '../../../../services/toaster.service';
import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
import { ManualAnnotationService } from '../../services/manual-annotation.service';
@@ -29,7 +29,7 @@ export class ForceRedactionDialogComponent implements OnInit {
private readonly _appStateService: AppStateService,
private readonly _userService: UserService,
private readonly _formBuilder: FormBuilder,
- private readonly _notificationService: NotificationService,
+ private readonly _notificationService: Toaster,
private readonly _translateService: TranslateService,
private readonly _legalBasisMappingControllerService: LegalBasisMappingControllerService,
private readonly _manualAnnotationService: ManualAnnotationService,
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts
index 85fe5c5e1..b5c5d24df 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts
@@ -3,7 +3,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '@state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AddRedactionRequest, LegalBasisMappingControllerService } from '@redaction/red-ui-http';
-import { NotificationService } from '@services/notification.service';
+import { Toaster } from '../../../../services/toaster.service';
import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
@@ -37,7 +37,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
private readonly _appStateService: AppStateService,
private readonly _userService: UserService,
private readonly _formBuilder: FormBuilder,
- private readonly _notificationService: NotificationService,
+ private readonly _notificationService: Toaster,
private readonly _translateService: TranslateService,
private readonly _legalBasisMappingControllerService: LegalBasisMappingControllerService,
private readonly _manualAnnotationService: ManualAnnotationService,
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts
index 88c1161d3..33068bc48 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts
@@ -1,6 +1,6 @@
import { ChangeDetectorRef, Component, ElementRef, HostListener, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { NavigationStart, Router } from '@angular/router';
-import { NotificationService, NotificationType } from '@services/notification.service';
+import { Toaster } from '../../../../services/toaster.service';
import { AppStateService } from '@state/app-state.service';
import { FileDropOverlayService } from '@upload-download/services/file-drop-overlay.service';
import { FileUploadModel } from '@upload-download/model/file-upload.model';
@@ -59,7 +59,7 @@ export class DossierOverviewScreenComponent
constructor(
readonly permissionsService: PermissionsService,
private readonly _userService: UserService,
- private readonly _notificationService: NotificationService,
+ private readonly _toaster: Toaster,
private readonly _dialogService: DossiersDialogService,
private readonly _fileUploadService: FileUploadService,
private readonly _statusOverlayService: StatusOverlayService,
@@ -149,19 +149,9 @@ export class DossierOverviewScreenComponent
.reanalyzeDossier()
.then(() => {
this.reloadDossiers();
- this._notificationService.showToastNotification(
- this._translateService.instant('dossier-overview.reanalyse-dossier.success'),
- null,
- NotificationType.SUCCESS
- );
+ this._toaster.success('dossier-overview.reanalyse-dossier.success');
})
- .catch(() => {
- this._notificationService.showToastNotification(
- this._translateService.instant('dossier-overview.reanalyse-dossier.error'),
- null,
- NotificationType.ERROR
- );
- });
+ .catch(() => this._toaster.error('dossier-overview.reanalyse-dossier.error'));
}
reloadDossiers() {
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts
index 15c433e57..bb0d1f886 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts
@@ -12,8 +12,7 @@ import { AnnotationData, FileDataModel } from '@models/file/file-data.model';
import { FileActionService } from '../../services/file-action.service';
import { AnnotationDrawService } from '../../services/annotation-draw.service';
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
-import { tap } from 'rxjs/operators';
-import { NotificationService } from '@services/notification.service';
+import { Toaster } from '../../../../services/toaster.service';
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { PermissionsService } from '@services/permissions.service';
import { Subscription, timer } from 'rxjs';
@@ -37,6 +36,7 @@ import { handleFilterDelta, processFilters } from '@shared/components/filters/po
import { LoadingService } from '../../../../services/loading.service';
import { stampPDFPage } from '../../../../utils/page-stamper';
import { TranslateService } from '@ngx-translate/core';
+import { AutoUnsubscribeComponent } from '../../../shared/base/auto-unsubscribe.component';
const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
@@ -45,7 +45,7 @@ const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
templateUrl: './file-preview-screen.component.html',
styleUrls: ['./file-preview-screen.component.scss']
})
-export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach, OnDetach {
+export class FilePreviewScreenComponent extends AutoUnsubscribeComponent implements OnInit, OnDestroy, OnAttach, OnDetach {
dialogRef: MatDialogRef;
viewMode: ViewMode = 'STANDARD';
fullScreen = false;
@@ -59,7 +59,6 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
secondaryFilters: FilterModel[];
canPerformAnnotationActions: boolean;
filesAutoUpdateTimer: Subscription;
- fileReanalysedSubscription: Subscription;
hideSkipped = false;
displayPDFViewer = false;
viewDocumentInfo = false;
@@ -81,7 +80,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
private readonly _activatedRoute: ActivatedRoute,
private readonly _dialogService: DossiersDialogService,
private readonly _router: Router,
- private readonly _notificationService: NotificationService,
+ private readonly _toaster: Toaster,
private readonly _annotationProcessingService: AnnotationProcessingService,
private readonly _annotationDrawService: AnnotationDrawService,
private readonly _fileActionService: FileActionService,
@@ -92,6 +91,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
private readonly _loadingService: LoadingService,
private readonly _translateService: TranslateService
) {
+ super();
document.documentElement.addEventListener('fullscreenchange', () => {
if (!document.fullscreenElement) {
this.fullScreen = false;
@@ -221,7 +221,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
ngOnDetach() {
this.displayPDFViewer = false;
this.viewReady = false;
- this._unsubscribeFromFileUpdates();
+ super.ngOnDestroy();
}
async ngOnAttach(previousRoute: ActivatedRouteSnapshot) {
@@ -249,10 +249,6 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
this.viewReady = true;
}
- ngOnDestroy(): void {
- this._unsubscribeFromFileUpdates();
- }
-
rebuildFilters(deletePreviousAnnotations: boolean = false) {
const startTime = new Date().getTime();
if (deletePreviousAnnotations) {
@@ -469,7 +465,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
await this._statusControllerService.setFileReviewer(dossierId, fileId, reviewerId).toPromise();
const msg = `Successfully assigned ${reviewerName} to file: ${filename}`;
- this._notificationService.showToastNotification(msg);
+ this._toaster.info(msg);
await this.appStateService.reloadActiveFile();
this._updateCanPerformActions();
this.editingReviewer = false;
@@ -488,7 +484,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
}
downloadOriginalFile() {
- this._fileManagementControllerService
+ this.addSubscription = this._fileManagementControllerService
.downloadOriginalFile(this.dossierId, this.fileId, true, this.fileData.fileStatus.cacheIdentifier, 'response')
.subscribe(data => {
download(data, this.fileData.fileStatus.filename);
@@ -539,10 +535,8 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
}
private _subscribeToFileUpdates(): void {
- this.filesAutoUpdateTimer = timer(0, 5000)
- .pipe(tap(async () => await this.appStateService.reloadActiveFile()))
- .subscribe();
- this.fileReanalysedSubscription = this.appStateService.fileReanalysed.subscribe(async (fileStatus: FileStatusWrapper) => {
+ this.addSubscription = timer(0, 5000).subscribe(async () => await this.appStateService.reloadActiveFile());
+ this.addSubscription = this.appStateService.fileReanalysed.subscribe(async (fileStatus: FileStatusWrapper) => {
if (fileStatus.fileId === this.fileId) {
await this._loadFileData(!this._reloadFileOnReanalysis);
this._reloadFileOnReanalysis = false;
@@ -553,11 +547,6 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
});
}
- private _unsubscribeFromFileUpdates(): void {
- this.filesAutoUpdateTimer.unsubscribe();
- this.fileReanalysedSubscription.unsubscribe();
- }
-
private _updateCanPerformActions() {
this.canPerformAnnotationActions =
this.permissionsService.canPerformAnnotationActions() &&
diff --git a/apps/red-ui/src/app/modules/dossier/services/manual-annotation.service.ts b/apps/red-ui/src/app/modules/dossier/services/manual-annotation.service.ts
index 055e3670d..102baff26 100644
--- a/apps/red-ui/src/app/modules/dossier/services/manual-annotation.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/services/manual-annotation.service.ts
@@ -7,7 +7,7 @@ import {
ManualRedactionControllerService
} from '@redaction/red-ui-http';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
-import { NotificationService, NotificationType } from '@services/notification.service';
+import { Toaster } from '../../../services/toaster.service';
import { TranslateService } from '@ngx-translate/core';
import { tap } from 'rxjs/operators';
import { UserService } from '@services/user.service';
@@ -38,7 +38,7 @@ export class ManualAnnotationService {
private readonly _appStateService: AppStateService,
private readonly _userService: UserService,
private readonly _translateService: TranslateService,
- private readonly _notificationService: NotificationService,
+ private readonly _toaster: Toaster,
private readonly _manualRedactionControllerService: ManualRedactionControllerService,
private readonly _dictionaryControllerService: DictionaryControllerService,
private readonly _permissionsService: PermissionsService
@@ -76,8 +76,12 @@ export class ManualAnnotationService {
return obs.pipe(
tap(
- () => this._notify(this._getMessage(mode)),
- error => this._notify(this._getMessage(mode, modifyDictionary, true), NotificationType.ERROR, error)
+ () => this._toaster.success(this._getMessage(mode), { positionClass: 'toast-file-preview' }),
+ error =>
+ this._toaster.error(this._getMessage(mode, modifyDictionary, true), {
+ params: error,
+ positionClass: 'toast-file-preview'
+ })
)
);
}
@@ -223,13 +227,6 @@ export class ManualAnnotationService {
}
}
- private _notify(key: string, type: NotificationType = NotificationType.SUCCESS, data?: any) {
- this._notificationService.showToastNotification(this._translateService.instant(key, data), null, type, {
- positionClass: 'toast-file-preview',
- actions: []
- });
- }
-
private _getMessage(mode: Mode, modifyDictionary?: boolean, error: boolean = false) {
return (
'annotation-actions.message.' +
diff --git a/apps/red-ui/src/app/modules/shared/base/auto-unsubscribe.component.ts b/apps/red-ui/src/app/modules/shared/base/auto-unsubscribe.component.ts
index 680769e31..761726bf7 100644
--- a/apps/red-ui/src/app/modules/shared/base/auto-unsubscribe.component.ts
+++ b/apps/red-ui/src/app/modules/shared/base/auto-unsubscribe.component.ts
@@ -3,8 +3,6 @@ import { Subscription } from 'rxjs';
/**
* Inherit this class when you need to subscribe to observables in your components
- *
- * @remarks You must explicitly call super.ngOnDestroy in you component to unsubscribe
*/
@Component({ template: '' })
export abstract class AutoUnsubscribeComponent implements OnDestroy {
@@ -21,7 +19,8 @@ export abstract class AutoUnsubscribeComponent implements OnDestroy {
/**
* This method unsubscribes active subscriptions
- * Explicitly call this method in your component's ngOnDestroy
+ * If you implement OnDestroy in a component that inherits AutoUnsubscribeComponent,
+ * then you must explicitly call super.ngOnDestroy()
*/
ngOnDestroy(): void {
this._subscriptions.unsubscribe();
diff --git a/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts b/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts
index 7ba2a27aa..201189b97 100644
--- a/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts
+++ b/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts
@@ -5,7 +5,6 @@ import { FilterService } from '../services/filter.service';
import { SearchService } from '../services/search.service';
import { ScreenStateService } from '../services/screen-state.service';
import { Observable } from 'rxjs';
-import { FilterModel } from '../components/filters/popup-filter/model/filter.model';
import { AutoUnsubscribeComponent } from './auto-unsubscribe.component';
@Component({ template: '' })
diff --git a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts
index 3233c7e4e..0ec7be010 100644
--- a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts
+++ b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts
@@ -1,11 +1,11 @@
-import { ChangeDetectionStrategy, Component, Inject, Input } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Inject, Input, OnDestroy } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { DossierWrapper } from '@state/model/dossier.wrapper';
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { FileDownloadService } from '@upload-download/services/file-download.service';
-import { NotificationService } from '@services/notification.service';
-import { TranslateService } from '@ngx-translate/core';
+import { Toaster } from '@services/toaster.service';
import { BASE_HREF } from '../../../../../tokens';
+import { AutoUnsubscribeComponent } from '@shared/base/auto-unsubscribe.component';
export type MenuState = 'OPEN' | 'CLOSED';
@@ -15,7 +15,7 @@ export type MenuState = 'OPEN' | 'CLOSED';
styleUrls: ['./file-download-btn.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
-export class FileDownloadBtnComponent {
+export class FileDownloadBtnComponent extends AutoUnsubscribeComponent implements OnDestroy {
@Input() dossier: DossierWrapper;
@Input() file: FileStatusWrapper | FileStatusWrapper[];
@Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above';
@@ -27,9 +27,10 @@ export class FileDownloadBtnComponent {
@Inject(BASE_HREF) private readonly _baseHref: string,
private readonly _permissionsService: PermissionsService,
private readonly _fileDownloadService: FileDownloadService,
- private readonly _translateService: TranslateService,
- private readonly _notificationService: NotificationService
- ) {}
+ private readonly _toaster: Toaster
+ ) {
+ super();
+ }
get canDownloadFiles() {
if (!Array.isArray(this.file)) {
@@ -41,12 +42,10 @@ export class FileDownloadBtnComponent {
downloadFiles($event: MouseEvent) {
$event.stopPropagation();
- this._fileDownloadService.downloadFiles(Array.isArray(this.file) ? this.file : [this.file], this.dossier).subscribe(() => {
- this._notificationService.showToastNotification(
- this._translateService.instant('download-status.queued', {
- baseUrl: this._baseHref
- })
- );
- });
+ this.addSubscription = this._fileDownloadService
+ .downloadFiles(Array.isArray(this.file) ? this.file : [this.file], this.dossier)
+ .subscribe(() => {
+ this._toaster.info('download-status.queued', { params: { baseUrl: this._baseHref } });
+ });
}
}
diff --git a/apps/red-ui/src/app/modules/shared/services/dictionary-save.service.ts b/apps/red-ui/src/app/modules/shared/services/dictionary-save.service.ts
index 4f6886952..5bce425e3 100644
--- a/apps/red-ui/src/app/modules/shared/services/dictionary-save.service.ts
+++ b/apps/red-ui/src/app/modules/shared/services/dictionary-save.service.ts
@@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
-import { NotificationService, NotificationType } from '@services/notification.service';
-import { TranslateService } from '@ngx-translate/core';
+import { Toaster } from '../../../services/toaster.service';
import { DictionaryControllerService } from '@redaction/red-ui-http';
import { tap } from 'rxjs/operators';
@@ -11,11 +10,7 @@ const MIN_WORD_LENGTH = 2;
providedIn: 'root'
})
export class DictionarySaveService {
- constructor(
- private readonly _notificationService: NotificationService,
- private readonly _translateService: TranslateService,
- private readonly _dictionaryControllerService: DictionaryControllerService
- ) {}
+ constructor(private readonly _toaster: Toaster, private readonly _dictionaryControllerService: DictionaryControllerService) {}
saveEntries(
entries: string[],
@@ -44,29 +39,13 @@ export class DictionarySaveService {
return obs.pipe(
tap(
() => {
- if (showToast) {
- this._notificationService.showToastNotification(
- this._translateService.instant('dictionary-overview.success.generic'),
- null,
- NotificationType.SUCCESS
- );
- }
+ if (showToast) this._toaster.success('dictionary-overview.success.generic');
},
- () => {
- this._notificationService.showToastNotification(
- this._translateService.instant('dictionary-overview.error.generic'),
- null,
- NotificationType.ERROR
- );
- }
+ () => this._toaster.error('dictionary-overview.error.generic')
)
);
} else {
- this._notificationService.showToastNotification(
- this._translateService.instant('dictionary-overview.error.entries-too-short'),
- null,
- NotificationType.ERROR
- );
+ this._toaster.error('dictionary-overview.error.entries-too-short');
return throwError('Entries too short');
}
diff --git a/apps/red-ui/src/app/services/error-message.service.ts b/apps/red-ui/src/app/services/error-message.service.ts
index d8d311fb1..68fd90874 100644
--- a/apps/red-ui/src/app/services/error-message.service.ts
+++ b/apps/red-ui/src/app/services/error-message.service.ts
@@ -8,11 +8,11 @@ import { HttpErrorResponse } from '@angular/common/http';
export class ErrorMessageService {
constructor(private readonly _translateService: TranslateService) {}
- _parseErrorResponse(err: HttpErrorResponse) {
+ _parseErrorResponse(err: HttpErrorResponse): string {
return err?.error?.message?.includes('message') ? ` ${err.error.message.match('"message":"(.*?)\\"')[1]}` : '';
}
- getMessage(err: HttpErrorResponse, defaultMessage: string) {
- return this._translateService.instant(defaultMessage) + this._parseErrorResponse(err);
+ getMessage(error: HttpErrorResponse, defaultMessage: string): string {
+ return this._translateService.instant(defaultMessage) + this._parseErrorResponse(error);
}
}
diff --git a/apps/red-ui/src/app/services/notification.service.ts b/apps/red-ui/src/app/services/notification.service.ts
deleted file mode 100644
index 9431503f7..000000000
--- a/apps/red-ui/src/app/services/notification.service.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Injectable } from '@angular/core';
-import { ActiveToast, ToastrService } from 'ngx-toastr';
-import { IndividualConfig } from 'ngx-toastr/toastr/toastr-config';
-import { NavigationStart, Router } from '@angular/router';
-
-export enum NotificationType {
- SUCCESS = 'SUCCESS',
- WARNING = 'WARNING',
- ERROR = 'ERROR',
- INFO = 'INFO'
-}
-
-export class ToastAction {
- title: string;
- action?: () => any;
-}
-
-@Injectable({
- providedIn: 'root'
-})
-export class NotificationService {
- constructor(private readonly _toastr: ToastrService, private readonly _router: Router) {
- _router.events.subscribe(event => {
- if (event instanceof NavigationStart) {
- this._toastr.clear();
- }
- });
- }
-
- showToastNotification(
- message: string,
- title?: string,
- notificationType = NotificationType.INFO,
- options?: Partial & { actions?: ToastAction[] }
- ): ActiveToast {
- switch (notificationType) {
- case NotificationType.ERROR:
- return this._toastr.error(message, title, options);
- case NotificationType.SUCCESS:
- return this._toastr.success(message, title, options);
- case NotificationType.WARNING:
- return this._toastr.warning(message, title, options);
- case NotificationType.INFO:
- return this._toastr.info(message, title, options);
- }
- }
-}
diff --git a/apps/red-ui/src/app/services/toaster.service.ts b/apps/red-ui/src/app/services/toaster.service.ts
new file mode 100644
index 000000000..c24fe23d0
--- /dev/null
+++ b/apps/red-ui/src/app/services/toaster.service.ts
@@ -0,0 +1,82 @@
+import { Injectable } from '@angular/core';
+import { ActiveToast, ToastrService } from 'ngx-toastr';
+import { IndividualConfig } from 'ngx-toastr/toastr/toastr-config';
+import { NavigationStart, Router } from '@angular/router';
+import { TranslateService } from '@ngx-translate/core';
+import { HttpErrorResponse } from '@angular/common/http';
+import { ErrorMessageService } from '@services/error-message.service';
+import { filter } from 'rxjs/operators';
+
+export enum NotificationType {
+ SUCCESS = 'SUCCESS',
+ WARNING = 'WARNING',
+ INFO = 'INFO'
+}
+
+export interface ToasterOptions extends IndividualConfig {
+ title?: string;
+ /**
+ * These params are used as interpolateParams for translate service
+ */
+ params?: object;
+ actions?: { title?: string; action: () => void }[];
+}
+
+export interface ErrorToasterOptions extends ToasterOptions {
+ /**
+ * Pass an http error that will be processed by error message service and shown in toast
+ */
+ error?: HttpErrorResponse;
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class Toaster {
+ constructor(
+ private readonly _toastr: ToastrService,
+ private readonly _router: Router,
+ private readonly _translateService: TranslateService,
+ private readonly _errorMessageService: ErrorMessageService
+ ) {
+ _router.events.pipe(filter(event => event instanceof NavigationStart)).subscribe(() => {
+ _toastr.clear();
+ });
+ }
+
+ error(message: string, options?: Partial) {
+ if (options?.error) message = this._errorMessageService.getMessage(options.error, message);
+ else message = this._translateService.instant(message, options?.params);
+
+ return this._toastr.error(message, options?.title, options);
+ }
+
+ info(message: string, options?: Partial) {
+ return this._showToastNotification(message, NotificationType.INFO, options);
+ }
+
+ success(message: string, options?: Partial) {
+ return this._showToastNotification(message, NotificationType.SUCCESS, options);
+ }
+
+ warning(message: string, options?: Partial) {
+ return this._showToastNotification(message, NotificationType.WARNING, options);
+ }
+
+ private _showToastNotification(
+ message: string,
+ notificationType = NotificationType.INFO,
+ options?: Partial
+ ): ActiveToast {
+ message = this._translateService.instant(message, options?.params);
+
+ switch (notificationType) {
+ case NotificationType.SUCCESS:
+ return this._toastr.success(message, options?.title, options);
+ case NotificationType.WARNING:
+ return this._toastr.warning(message, options?.title, options);
+ case NotificationType.INFO:
+ return this._toastr.info(message, options?.title, options);
+ }
+ }
+}
diff --git a/apps/red-ui/src/app/state/app-state.service.ts b/apps/red-ui/src/app/state/app-state.service.ts
index 8acaa3a7b..ce9146e7d 100644
--- a/apps/red-ui/src/app/state/app-state.service.ts
+++ b/apps/red-ui/src/app/state/app-state.service.ts
@@ -9,7 +9,7 @@ import {
ReanalysisControllerService,
StatusControllerService
} from '@redaction/red-ui-http';
-import { NotificationService, NotificationType } from '@services/notification.service';
+import { Toaster } from '../services/toaster.service';
import { TranslateService } from '@ngx-translate/core';
import { Event, NavigationEnd, ResolveStart, Router } from '@angular/router';
import { UserService } from '@services/user.service';
@@ -47,7 +47,7 @@ export class AppStateService {
private readonly _router: Router,
private readonly _userService: UserService,
private readonly _dossiersService: DossiersService,
- private readonly _notificationService: NotificationService,
+ private readonly _toaster: Toaster,
private readonly _reanalysisControllerService: ReanalysisControllerService,
private readonly _translateService: TranslateService,
private readonly _dictionaryControllerService: DictionaryControllerService,
@@ -239,7 +239,7 @@ export class AppStateService {
this.activeDossierTemplateId,
this._appState.fileAttributesConfig[this.activeDossierTemplateId]
);
- this.activeDossier.files = this.activeDossier.files.map(file =>
+ this.activeDossier.files = this.activeDossier?.files.map(file =>
file.fileId === activeFileWrapper.fileId ? activeFileWrapper : file
);
@@ -330,13 +330,7 @@ export class AppStateService {
const index = this.allDossiers.findIndex(p => p.dossierId === dossier.dossierId);
this._appState.dossiers.splice(index, 1);
},
- () => {
- this._notificationService.showToastNotification(
- this._translateService.instant('dossiers.delete.delete-failed', dossier),
- null,
- NotificationType.ERROR
- );
- }
+ () => this._toaster.error('dossiers.delete.delete-failed', { params: dossier })
);
}
@@ -353,12 +347,8 @@ export class AppStateService {
this._appState.dossiers = [...this._appState.dossiers];
return foundDossier;
} catch (error) {
- this._notificationService.showToastNotification(
- this._translateService.instant(
- error.status === 409 ? 'add-dossier-dialog.errors.dossier-already-exists' : 'add-dossier-dialog.errors.generic'
- ),
- null,
- NotificationType.ERROR
+ this._toaster.error(
+ error.status === 409 ? 'add-dossier-dialog.errors.dossier-already-exists' : 'add-dossier-dialog.errors.generic'
);
}
}