diff --git a/apps/red-ui/src/app/components/base-screen/base-screen.component.html b/apps/red-ui/src/app/components/base-screen/base-screen.component.html
index 30abc60e1..bb66bc9f6 100644
--- a/apps/red-ui/src/app/components/base-screen/base-screen.component.html
+++ b/apps/red-ui/src/app/components/base-screen/base-screen.component.html
@@ -3,25 +3,6 @@
-
-
diff --git a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts
index 4f06ac46a..b97584730 100644
--- a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts
+++ b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts
@@ -9,6 +9,7 @@ import { TranslateService } from '@ngx-translate/core';
import { SpotlightSearchAction } from '@components/spotlight-search/spotlight-search-action';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { distinctUntilChanged, filter, map, startWith } from 'rxjs/operators';
+import { DossiersService } from '../../modules/dossier/services/dossiers.service';
interface MenuItem {
readonly name: string;
@@ -54,8 +55,8 @@ export class BaseScreenComponent {
{
text: this._translateService.instant('search.this-dossier'),
icon: 'red:enter',
- hide: (): boolean => !this.appStateService.activeDossier,
- action: (query): void => this._search(query, this.appStateService.activeDossier.id)
+ hide: (): boolean => !this.dossiersService.activeDossier,
+ action: (query): void => this._search(query, this.dossiersService.activeDossierId)
},
{
text: this._translateService.instant('search.entire-platform'),
@@ -74,6 +75,7 @@ export class BaseScreenComponent {
constructor(
readonly appStateService: AppStateService,
+ readonly dossiersService: DossiersService,
readonly userService: UserService,
readonly userPreferenceService: UserPreferenceService,
readonly titleService: Title,
diff --git a/apps/red-ui/src/app/components/notifications/notifications.component.ts b/apps/red-ui/src/app/components/notifications/notifications.component.ts
index 841ea9b8c..66b7a888c 100644
--- a/apps/red-ui/src/app/components/notifications/notifications.component.ts
+++ b/apps/red-ui/src/app/components/notifications/notifications.component.ts
@@ -8,6 +8,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UserService } from '@services/user.service';
import { NotificationType, NotificationTypeEnum } from '@models/notification-types';
import { notificationsTranslations } from '../../translations/notifications-translations';
+import { DossiersService } from '../../modules/dossier/services/dossiers.service';
@Component({
selector: 'redaction-notifications',
@@ -23,6 +24,7 @@ export class NotificationsComponent {
private readonly _userService: UserService,
private readonly _notificationControllerService: NotificationControllerService,
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _datePipe: DatePipe
) {
this._notificationControllerService.getNotifications(false).subscribe((response: NotificationResponse) => {
@@ -96,12 +98,12 @@ export class NotificationsComponent {
}
private _getDossierName(dossierId: string | undefined) {
- const dossier = this._appStateService.getDossierById(dossierId);
+ const dossier = this._dossiersService.find(dossierId);
return dossier?.dossierName || this._translateService.instant(_('dossier'));
}
private _getFileName(dossierId: string | undefined, fileId: string | undefined) {
- const file = this._appStateService.getFileById(dossierId, fileId);
+ const file = this._dossiersService.find(dossierId, fileId);
return file?.filename || this._translateService.instant(_('file'));
}
diff --git a/apps/red-ui/src/app/models/audit-model-wrapper.model.ts b/apps/red-ui/src/app/models/audit-model-wrapper.model.ts
deleted file mode 100644
index e69de29bb..000000000
diff --git a/apps/red-ui/src/app/models/audit.model.ts b/apps/red-ui/src/app/models/audit.model.ts
index d653e3099..76ca7d7ad 100644
--- a/apps/red-ui/src/app/models/audit.model.ts
+++ b/apps/red-ui/src/app/models/audit.model.ts
@@ -7,7 +7,7 @@ export class Audit implements IAudit, IListable {
readonly details?: unknown;
readonly message?: string;
readonly objectId?: string;
- readonly recordDate?: string;
+ readonly recordDate: string;
readonly userId?: string;
constructor(audit: IAudit) {
@@ -20,7 +20,7 @@ export class Audit implements IAudit, IListable {
this.userId = audit.userId;
}
- get id() {
+ get id(): string {
return this.recordDate;
}
diff --git a/apps/red-ui/src/app/models/dictionary.ts b/apps/red-ui/src/app/models/dictionary.ts
index bae65a716..53f4d6350 100644
--- a/apps/red-ui/src/app/models/dictionary.ts
+++ b/apps/red-ui/src/app/models/dictionary.ts
@@ -9,7 +9,7 @@ export class Dictionary implements IDictionary, IListable {
readonly entries?: List;
readonly hexColor?: string;
readonly hint: boolean;
- readonly label?: string;
+ readonly label: string;
readonly rank?: number;
readonly recommendation: boolean;
diff --git a/apps/red-ui/src/app/models/file/file.ts b/apps/red-ui/src/app/models/file/file.ts
index 2f7d82d22..01c718e09 100644
--- a/apps/red-ui/src/app/models/file/file.ts
+++ b/apps/red-ui/src/app/models/file/file.ts
@@ -11,17 +11,17 @@ const processingStatuses: List
= [
] as const;
export class File implements IFile, IListable {
- readonly added: string;
+ readonly added?: string;
readonly allManualRedactionsApplied: boolean;
- readonly analysisDuration: number;
+ readonly analysisDuration?: number;
readonly analysisRequired: boolean;
- readonly approvalDate: string;
- readonly currentReviewer: string;
- readonly dictionaryVersion: number;
- readonly dossierDictionaryVersion: number;
+ readonly approvalDate?: string;
+ readonly currentReviewer?: string;
+ readonly dictionaryVersion?: number;
+ readonly dossierDictionaryVersion?: number;
readonly dossierId: string;
readonly excluded: boolean;
- readonly fileAttributes: FileAttributes;
+ readonly fileAttributes?: FileAttributes;
readonly fileId: string;
readonly filename: string;
readonly hasAnnotationComments: boolean;
@@ -29,22 +29,21 @@ export class File implements IFile, IListable {
readonly hasImages: boolean;
readonly hasRedactions: boolean;
readonly hasUpdates: boolean;
- readonly lastOCRTime: string;
- readonly lastProcessed: string;
- readonly lastReviewer: string;
- readonly lastUpdated: string;
- readonly lastUploaded: string;
- readonly legalBasisVersion: number;
- readonly numberOfAnalyses: number;
- readonly numberOfPages: number;
- readonly rulesVersion: number;
+ readonly lastOCRTime?: string;
+ readonly lastProcessed?: string;
+ readonly lastReviewer?: string;
+ readonly lastUpdated?: string;
+ readonly lastUploaded?: string;
+ readonly legalBasisVersion?: number;
+ readonly numberOfAnalyses?: number;
+ readonly numberOfPages?: number;
+ readonly rulesVersion?: number;
readonly status: FileStatus;
- readonly uploader: string;
- readonly excludedPages: number[];
+ readonly uploader?: string;
+ readonly excludedPages?: number[];
readonly hasSuggestions: boolean;
- readonly dossierTemplateId: string;
- primaryAttribute: string;
+ readonly primaryAttribute: string;
lastOpened: boolean;
readonly statusSort: number;
readonly cacheIdentifier: string;
@@ -62,25 +61,25 @@ export class File implements IFile, IListable {
readonly isWorkable: boolean;
readonly canBeOCRed: boolean;
- constructor(file: IFile, public reviewerName: string, fileAttributesConfig?: FileAttributesConfig) {
+ constructor(file: IFile, readonly reviewerName: string, fileAttributesConfig?: FileAttributesConfig) {
this.added = file.added;
- this.allManualRedactionsApplied = file.allManualRedactionsApplied;
+ this.allManualRedactionsApplied = !!file.allManualRedactionsApplied;
this.analysisDuration = file.analysisDuration;
- this.analysisRequired = file.analysisRequired && !file.excluded;
+ this.analysisRequired = !!file.analysisRequired && !file.excluded;
this.approvalDate = file.approvalDate;
this.currentReviewer = file.currentReviewer;
this.dictionaryVersion = file.dictionaryVersion;
this.dossierDictionaryVersion = file.dossierDictionaryVersion;
this.dossierId = file.dossierId;
- this.excluded = file.excluded;
+ this.excluded = !!file.excluded;
this.fileAttributes = file.fileAttributes;
this.fileId = file.fileId;
this.filename = file.filename;
- this.hasAnnotationComments = file.hasAnnotationComments;
- this.hasHints = file.hasHints;
- this.hasImages = file.hasImages;
- this.hasRedactions = file.hasRedactions;
- this.hasUpdates = file.hasUpdates;
+ this.hasAnnotationComments = !!file.hasAnnotationComments;
+ this.hasHints = !!file.hasHints;
+ this.hasImages = !!file.hasImages;
+ this.hasRedactions = !!file.hasRedactions;
+ this.hasUpdates = !!file.hasUpdates;
this.lastOCRTime = file.lastOCRTime;
this.lastProcessed = file.lastProcessed;
this.lastReviewer = file.lastReviewer;
@@ -94,11 +93,12 @@ export class File implements IFile, IListable {
this.rulesVersion = file.rulesVersion;
this.uploader = file.uploader;
this.excludedPages = file.excludedPages;
- this.hasSuggestions = file.hasSuggestions;
- this.dossierTemplateId = file.dossierTemplateId;
+ this.hasSuggestions = !!file.hasSuggestions;
this.statusSort = StatusSorter[this.status];
- this.cacheIdentifier = btoa(this.lastUploaded + this.lastOCRTime);
+ if (this.lastUpdated && this.lastOCRTime) {
+ this.cacheIdentifier = btoa(this.lastUploaded + this.lastOCRTime);
+ }
this.hintsOnly = this.hasHints && !this.hasRedactions;
this.hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions;
this.isUnassigned = !this.currentReviewer;
diff --git a/apps/red-ui/src/app/models/user.ts b/apps/red-ui/src/app/models/user.ts
index 24bb45dd4..75d775736 100644
--- a/apps/red-ui/src/app/models/user.ts
+++ b/apps/red-ui/src/app/models/user.ts
@@ -5,8 +5,8 @@ import { KeycloakProfile } from 'keycloak-js';
export class User implements IUser, IListable {
readonly email: string;
readonly username: string;
- readonly firstName: string;
- readonly lastName: string;
+ readonly firstName?: string;
+ readonly lastName?: string;
readonly name: string;
readonly searchKey: string;
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-users-dialog/confirm-delete-users-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-users-dialog/confirm-delete-users-dialog.component.ts
index bd63dad28..8f9c5eb26 100644
--- a/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-users-dialog/confirm-delete-users-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-users-dialog/confirm-delete-users-dialog.component.ts
@@ -1,10 +1,10 @@
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UserControllerService } from '@redaction/red-ui-http';
-import { AppStateService } from '@state/app-state.service';
import { LoadingService } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { User } from '@models/user';
+import { DossiersService } from '../../../dossier/services/dossiers.service';
@Component({
selector: 'redaction-confirm-delete-users-dialog',
@@ -20,13 +20,13 @@ export class ConfirmDeleteUsersDialogComponent {
dossiersCount: number;
constructor(
- private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _loadingService: LoadingService,
private readonly _userControllerService: UserControllerService,
readonly dialogRef: MatDialogRef,
@Inject(MAT_DIALOG_DATA) readonly users: User[]
) {
- this.dossiersCount = this._appStateService.allDossiers.filter(dw => {
+ this.dossiersCount = this._dossiersService.all.filter(dw => {
for (const user of this.users) {
if (dw.memberIds.indexOf(user.id) !== -1) {
return true;
diff --git a/apps/red-ui/src/app/modules/dossier/components/document-info/document-info.component.ts b/apps/red-ui/src/app/modules/dossier/components/document-info/document-info.component.ts
index f367b2ae8..0331901d1 100644
--- a/apps/red-ui/src/app/modules/dossier/components/document-info/document-info.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/components/document-info/document-info.component.ts
@@ -5,6 +5,7 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { AutoUnsubscribe } from '@iqser/common-ui';
import { File } from '@models/file/file';
import { FileAttributesService } from '../../services/file-attributes.service';
+import { DossiersService } from '../../services/dossiers.service';
@Component({
selector: 'redaction-document-info',
@@ -13,12 +14,13 @@ import { FileAttributesService } from '../../services/file-attributes.service';
})
export class DocumentInfoComponent extends AutoUnsubscribe implements OnInit {
@Input() file: File;
- @Output() closeDocumentInfoView = new EventEmitter();
+ @Output() readonly closeDocumentInfoView = new EventEmitter();
fileAttributesConfig: FileAttributesConfig;
constructor(
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _fileAttributesService: FileAttributesService,
private readonly _dialogService: DossiersDialogService
) {
@@ -26,7 +28,7 @@ export class DocumentInfoComponent extends AutoUnsubscribe implements OnInit {
}
get dossier() {
- return this._appStateService.getDossierById(this.file.dossierId);
+ return this._dossiersService.find(this.file.dossierId);
}
get dossierTemplateName(): string {
@@ -34,10 +36,10 @@ export class DocumentInfoComponent extends AutoUnsubscribe implements OnInit {
}
ngOnInit(): void {
- this.fileAttributesConfig = this._fileAttributesService.getFileAttributeConfig(this.file.dossierTemplateId);
+ this.fileAttributesConfig = this._fileAttributesService.getFileAttributeConfig(this.dossier.dossierTemplateId);
this.addSubscription = this._appStateService.dossierTemplateChanged$.subscribe(() => {
- this.fileAttributesConfig = this._fileAttributesService.getFileAttributeConfig(this.file.dossierTemplateId);
+ this.fileAttributesConfig = this._fileAttributesService.getFileAttributeConfig(this.dossier.dossierTemplateId);
});
}
diff --git a/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts b/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts
index 7e6cdf763..b99377e82 100644
--- a/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts
@@ -1,9 +1,10 @@
-import {Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges} from '@angular/core';
-import {ViewedPages, ViewedPagesControllerService} from '@redaction/red-ui-http';
-import {AppStateService} from '@state/app-state.service';
-import {PermissionsService} from '@services/permissions.service';
-import {ConfigService} from '@services/config.service';
-import {Subscription} from 'rxjs';
+import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
+import { ViewedPages, ViewedPagesControllerService } from '@redaction/red-ui-http';
+import { AppStateService } from '@state/app-state.service';
+import { PermissionsService } from '@services/permissions.service';
+import { ConfigService } from '@services/config.service';
+import { Subscription } from 'rxjs';
+import { DossiersService } from '../../services/dossiers.service';
@Component({
selector: 'redaction-page-indicator',
@@ -16,7 +17,7 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy {
@Input() viewedPages: ViewedPages;
@Input() activeSelection = false;
- @Output() pageSelected = new EventEmitter();
+ @Output() readonly pageSelected = new EventEmitter();
pageReadTimeout: number = null;
canMarkPagesAsViewed: boolean;
@@ -25,10 +26,10 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy {
constructor(
private readonly _viewedPagesControllerService: ViewedPagesControllerService,
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _configService: ConfigService,
private readonly _permissionService: PermissionsService
- ) {
- }
+ ) {}
get read() {
return this.viewedPages?.pages?.findIndex(p => p.page === this.number) >= 0;
@@ -96,15 +97,15 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy {
private _markPageRead() {
this._viewedPagesControllerService
- .addPage({page: this.number}, this._appStateService.activeDossierId, this._appStateService.activeFileId)
+ .addPage({ page: this.number }, this._dossiersService.activeDossierId, this._appStateService.activeFileId)
.subscribe(() => {
- this.viewedPages?.pages?.push({page: this.number, fileId: this._appStateService.activeFileId});
+ this.viewedPages?.pages?.push({ page: this.number, fileId: this._appStateService.activeFileId });
});
}
private _markPageUnread() {
this._viewedPagesControllerService
- .removePage(this._appStateService.activeDossierId, this._appStateService.activeFileId, this.number)
+ .removePage(this._dossiersService.activeDossierId, this._appStateService.activeFileId, this.number)
.subscribe(() => {
this.viewedPages?.pages?.splice(
this.viewedPages?.pages?.findIndex(p => p.page === this.number),
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 be438a273..fbdeb4479 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,11 +1,11 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { IDossier } from '@redaction/red-ui-http';
-import { AppStateService } from '@state/app-state.service';
+import { DossierRequest, IDossier } from '@redaction/red-ui-http';
import { UserService } from '@services/user.service';
import { Toaster } from '@iqser/common-ui';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Dossier } from '@state/model/dossier';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
+import { DossiersService } from '../../services/dossiers.service';
@Component({
selector: 'redaction-team-members-manager',
@@ -28,7 +28,7 @@ export class TeamMembersManagerComponent implements OnInit {
readonly userService: UserService,
private readonly _toaster: Toaster,
private readonly _formBuilder: FormBuilder,
- private readonly _appStateService: AppStateService
+ private readonly _dossiersService: DossiersService
) {}
get selectedOwnerId(): string {
@@ -52,22 +52,17 @@ export class TeamMembersManagerComponent implements OnInit {
}
async saveMembers() {
- let result;
- try {
- const ownerId = this.selectedOwnerId;
- const memberIds = this.selectedMembersList;
- const approverIds = this.selectedApproversList;
- const dw = {
- ...this.dossier,
- memberIds,
- approverIds,
- ownerId
- };
- result = await this._appStateService.createOrUpdateDossier(dw);
+ const dossier = {
+ ...this.dossier,
+ memberIds: this.selectedMembersList,
+ approverIds: this.selectedApproversList,
+ ownerId: this.selectedOwnerId
+ } as DossierRequest;
+
+ const result = await this._dossiersService.createOrUpdate(dossier).toPromise();
+ if (result) {
this.save.emit(result);
this._updateChanged();
- } catch (error) {
- this._toaster.error(_('error.http.generic'), { params: error });
}
}
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/add-dossier-dialog/add-dossier-dialog.component.html b/apps/red-ui/src/app/modules/dossier/dialogs/add-dossier-dialog/add-dossier-dialog.component.html
index c0c360868..88a3666fd 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/add-dossier-dialog/add-dossier-dialog.component.html
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/add-dossier-dialog/add-dossier-dialog.component.html
@@ -83,7 +83,7 @@
reportTemplate.templateId;
constructor(
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _formBuilder: FormBuilder,
private readonly _reportTemplateController: ReportTemplateControllerService,
readonly dialogRef: MatDialogRef
@@ -45,7 +52,7 @@ export class AddDossierDialogComponent {
validators: control =>
control.value.reportTemplateIds?.length > 0 || control.value.downloadFileTypes?.length > 0
? null
- : {downloadPackage: true}
+ : { downloadPackage: true }
}
);
}
@@ -66,18 +73,12 @@ export class AddDossierDialogComponent {
return this.dossierForm.invalid;
}
- async saveDossier() {
- const savedDossier = await this._appStateService.createOrUpdateDossier(this._formToObject());
- if (savedDossier) {
- this.dialogRef.close({dossier: savedDossier});
- }
- }
+ reportTemplateValueMapper = (reportTemplate: ReportTemplate) => reportTemplate.templateId;
- async saveDossierAndAddMembers() {
- const dossier: DossierRequest = this._formToObject();
- const savedDossier = await this._appStateService.createOrUpdateDossier(dossier);
+ async saveDossier(addMembers = false) {
+ const savedDossier = await this._dossiersService.createOrUpdate(this._formToObject()).toPromise();
if (savedDossier) {
- this.dialogRef.close({addMembers: true, dossier: savedDossier});
+ this.dialogRef.close({ dossier: savedDossier, addMembers });
}
}
@@ -94,7 +95,7 @@ export class AddDossierDialogComponent {
downloadFileTypes: dossierTemplate.downloadFileTypes,
reportTemplateIds: [] // TODO DEFAULT
},
- {emitEvent: false}
+ { emitEvent: false }
);
} else {
this.availableReportTypes = [];
@@ -103,7 +104,7 @@ export class AddDossierDialogComponent {
downloadFileTypes: [],
reportTemplateIds: []
},
- {emitEvent: false}
+ { emitEvent: false }
);
}
}
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 3a49970ba..4f2a2dabb 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
@@ -8,6 +8,7 @@ import { File } from '@models/file/file';
import { Dossier } from '@state/model/dossier';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FilesService } from '../../services/files.service';
+import { DossiersService } from '../../services/dossiers.service';
class DialogData {
mode: 'approver' | 'reviewer';
@@ -29,6 +30,7 @@ export class AssignReviewerApproverDialogComponent {
private readonly _toaster: Toaster,
private readonly _formBuilder: FormBuilder,
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _filesService: FilesService,
private readonly _dialogRef: MatDialogRef,
@Inject(MAT_DIALOG_DATA) readonly data: DialogData
@@ -42,8 +44,8 @@ export class AssignReviewerApproverDialogComponent {
get singleUsersSelectOptions() {
return this.data.mode === 'approver'
- ? this._appStateService.activeDossier.approverIds
- : this._appStateService.activeDossier.memberIds;
+ ? this._dossiersService.activeDossier.approverIds
+ : this._dossiersService.activeDossier.memberIds;
}
get changed(): boolean {
@@ -72,7 +74,7 @@ export class AssignReviewerApproverDialogComponent {
await this._filesService
.setReviewerFor(
this.data.files.map(f => f.fileId),
- this._appStateService.activeDossierId,
+ this._dossiersService.activeDossierId,
selectedUser
)
.toPromise();
@@ -81,7 +83,7 @@ export class AssignReviewerApproverDialogComponent {
.setUnderApprovalFor(
this.data.files.map(f => f.fileId),
selectedUser,
- this._appStateService.activeDossierId
+ this._dossiersService.activeDossierId
)
.toPromise();
}
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts
index 1217bb918..624ebeda2 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts
@@ -6,6 +6,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { LegalBasisMappingControllerService } from '@redaction/red-ui-http';
import { AppStateService } from '@state/app-state.service';
import { PermissionsService } from '@services/permissions.service';
+import { DossiersService } from '../../services/dossiers.service';
export interface LegalBasisOption {
label?: string;
@@ -27,6 +28,7 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
private readonly _translateService: TranslateService,
private readonly _legalBasisMappingControllerService: LegalBasisMappingControllerService,
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _permissionsService: PermissionsService,
private readonly _formBuilder: FormBuilder,
public dialogRef: MatDialogRef,
@@ -45,7 +47,7 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
comment: this.isDocumentAdmin ? [null] : [null, Validators.required]
});
const data = await this._legalBasisMappingControllerService
- .getLegalBasisMapping(this._appStateService.activeDossier.dossierTemplateId)
+ .getLegalBasisMapping(this._dossiersService.activeDossier.dossierTemplateId)
.toPromise();
this.legalOptions = data
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/document-info-dialog/document-info-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/document-info-dialog/document-info-dialog.component.ts
index 9625d86c1..f00ca3baf 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/document-info-dialog/document-info-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/document-info-dialog/document-info-dialog.component.ts
@@ -5,6 +5,7 @@ import { AppStateService } from '@state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Dossier } from '@state/model/dossier';
import { FileAttributesService } from '../../services/file-attributes.service';
+import { DossiersService } from '../../services/dossiers.service';
@Component({
templateUrl: './document-info-dialog.component.html',
@@ -15,17 +16,18 @@ export class DocumentInfoDialogComponent implements OnInit {
file: IFile;
attributes: IFileAttributeConfig[];
- private _dossier: Dossier;
+ private readonly _dossier: Dossier;
constructor(
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _formBuilder: FormBuilder,
private readonly _fileAttributesService: FileAttributesService,
public dialogRef: MatDialogRef,
@Inject(MAT_DIALOG_DATA) public data: IFile
) {
this.file = this.data;
- this._dossier = this._appStateService.getDossierById(this.file.dossierId);
+ this._dossier = this._dossiersService.find(this.file.dossierId);
}
async ngOnInit() {
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts
index 39508e09a..6f43510c1 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts
@@ -1,5 +1,4 @@
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
-import { AppStateService } from '@state/app-state.service';
import { Dossier } from '@state/model/dossier';
import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { PermissionsService } from '@services/permissions.service';
@@ -8,6 +7,7 @@ import { DictionaryService } from '@shared/services/dictionary.service';
import { FormBuilder } from '@angular/forms';
import { CircleButtonTypes, LoadingService } from '@iqser/common-ui';
import { IDictionary } from '@redaction/red-ui-http';
+import { DossiersService } from '../../../services/dossiers.service';
@Component({
selector: 'redaction-edit-dossier-dictionary',
@@ -20,10 +20,10 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
canEdit = false;
readonly circleButtonTypes = CircleButtonTypes;
- @ViewChild(DictionaryManagerComponent, { static: false }) private _dictionaryManager: DictionaryManagerComponent;
+ @ViewChild(DictionaryManagerComponent, { static: false }) private readonly _dictionaryManager: DictionaryManagerComponent;
constructor(
- private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _dictionaryService: DictionaryService,
private readonly _permissionsService: PermissionsService,
private readonly _loadingService: LoadingService,
@@ -42,7 +42,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
async ngOnInit() {
this._loadingService.start();
- await this._appStateService.updateDossierDictionary(this.dossier.dossierTemplateId, this.dossier.id);
+ await this._dossiersService.updateDossierDictionary(this.dossier.dossierTemplateId, this.dossier.id);
this._loadingService.stop();
}
@@ -51,7 +51,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
await this._dictionaryService
.updateType(typeValue, this.dossier.dossierTemplateId, 'dossier_redaction', this.dossier.id)
.toPromise();
- await this._appStateService.updateDossierDictionary(this.dossier.dossierTemplateId, this.dossier.id);
+ await this._dossiersService.updateDossierDictionary(this.dossier.dossierTemplateId, this.dossier.id);
this.updateDossier.emit();
}
@@ -66,7 +66,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
false
)
.toPromise();
- await this._appStateService.updateDossierDictionary(this.dossier.dossierTemplateId, this.dossier.id);
+ await this._dossiersService.updateDossierDictionary(this.dossier.dossierTemplateId, this.dossier.id);
this.updateDossier.emit();
}
diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component.ts
index 7e0f91e9f..b1d2a77ae 100644
--- a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component.ts
@@ -1,10 +1,10 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { DownloadFileType, ReportTemplate, ReportTemplateControllerService } from '@redaction/red-ui-http';
import { FormBuilder, FormGroup } from '@angular/forms';
-import { AppStateService } from '@state/app-state.service';
import { Dossier } from '@state/model/dossier';
import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { downloadTypesTranslations } from '../../../../../translations/download-types-translations';
+import { DossiersService } from '../../../services/dossiers.service';
@Component({
selector: 'redaction-edit-dossier-download-package',
@@ -23,7 +23,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
@Output() readonly updateDossier = new EventEmitter();
constructor(
- private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _reportTemplateController: ReportTemplateControllerService,
private readonly _formBuilder: FormBuilder
) {}
@@ -87,7 +87,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
downloadFileTypes: this.dossierForm.get('downloadFileTypes').value,
reportTemplateIds: this.dossierForm.get('reportTemplateIds').value
};
- await this._appStateService.createOrUpdateDossier(dossier);
+ await this._dossiersService.createOrUpdate(dossier).toPromise();
this.updateDossier.emit();
}
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 8090b67f0..438dce15b 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
@@ -12,6 +12,7 @@ import { EditDossierAttributesComponent } from './attributes/edit-dossier-attrib
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { EditDossierDeletedDocumentsComponent } from './deleted-documents/edit-dossier-deleted-documents.component';
import { AppStateService } from '@state/app-state.service';
+import { DossiersService } from '../../services/dossiers.service';
type Section = 'dossierInfo' | 'downloadPackage' | 'dossierDictionary' | 'members' | 'dossierAttributes' | 'deletedDocuments';
@@ -34,6 +35,7 @@ export class EditDossierDialogComponent {
constructor(
private readonly _toaster: Toaster,
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _changeRef: ChangeDetectorRef,
@Inject(MAT_DIALOG_DATA)
private readonly _data: {
@@ -106,7 +108,7 @@ export class EditDossierDialogComponent {
updatedDossier() {
this._toaster.success(_('edit-dossier-dialog.change-successful'), { params: { dossierName: this.dossier.dossierName } });
- this.dossier = this._appStateService.getDossierById(this.dossier.id);
+ this.dossier = this._dossiersService.find(this.dossier.id);
this._changeRef.detectChanges();
this.afterSave();
}
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 f43064429..03967596f 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
@@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { IDossierTemplate } from '@redaction/red-ui-http';
+import { DossierRequest, IDossierTemplate } from '@redaction/red-ui-http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '@state/app-state.service';
import * as moment from 'moment';
@@ -12,6 +12,7 @@ import { MatDialogRef } from '@angular/material/dialog';
import { EditDossierDialogComponent } from '../edit-dossier-dialog.component';
import { ConfirmationDialogInput, IconButtonTypes, TitleColors, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
+import { DossiersService } from '../../../services/dossiers.service';
@Component({
selector: 'redaction-edit-dossier-general-info',
@@ -31,6 +32,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
constructor(
readonly permissionsService: PermissionsService,
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _formBuilder: FormBuilder,
private readonly _dialogService: DossiersDialogService,
private readonly _router: Router,
@@ -99,8 +101,8 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
watermarkEnabled: this.dossierForm.get('watermarkEnabled').value,
dueDate: this.hasDueDate ? this.dossierForm.get('dueDate').value : undefined,
dossierTemplateId: this.dossierForm.get('dossierTemplateId').value
- };
- await this._appStateService.createOrUpdateDossier(dossier);
+ } as DossierRequest;
+ await this._dossiersService.createOrUpdate(dossier).toPromise();
this.updateDossier.emit();
}
@@ -119,7 +121,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
}
});
this._dialogService.openDialog('confirm', null, data, async () => {
- await this._appStateService.deleteDossier(this.dossier);
+ await this._dossiersService.delete(this.dossier).toPromise();
this._editDossierDialogRef.componentInstance.afterSave();
this._editDossierDialogRef.close();
this._router.navigate(['main', 'dossiers']).then(() => this._notifyDossierDeleted());
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 f89f44a36..6adba14df 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
@@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
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 { Toaster } from '@iqser/common-ui';
@@ -8,6 +7,7 @@ import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
import { ManualAnnotationService } from '../../services/manual-annotation.service';
import { PermissionsService } from '@services/permissions.service';
+import { DossiersService } from '../../services/dossiers.service';
export interface LegalBasisOption {
label?: string;
@@ -26,7 +26,7 @@ export class ForceRedactionDialogComponent implements OnInit {
legalOptions: LegalBasisOption[] = [];
constructor(
- private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _userService: UserService,
private readonly _formBuilder: FormBuilder,
private readonly _notificationService: Toaster,
@@ -39,7 +39,7 @@ export class ForceRedactionDialogComponent implements OnInit {
async ngOnInit() {
this._legalBasisMappingControllerService
- .getLegalBasisMapping(this._appStateService.activeDossier.dossierTemplateId)
+ .getLegalBasisMapping(this._dossiersService.activeDossier.dossierTemplateId)
.subscribe(data => {
data.map(lbm => {
this.legalOptions.push({
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 47ba5c066..6868bc0a6 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
@@ -11,6 +11,7 @@ import { ManualAnnotationService } from '../../services/manual-annotation.servic
import { ManualAnnotationResponse } from '@models/file/manual-annotation-response';
import { PermissionsService } from '@services/permissions.service';
import { TypeValue } from '@models/file/type-value';
+import { DossiersService } from '../../services/dossiers.service';
export interface LegalBasisOption {
label?: string;
@@ -35,6 +36,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
constructor(
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _userService: UserService,
private readonly _formBuilder: FormBuilder,
private readonly _notificationService: Toaster,
@@ -60,7 +62,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
async ngOnInit() {
this._legalBasisMappingControllerService
- .getLegalBasisMapping(this._appStateService.activeDossier.dossierTemplateId)
+ .getLegalBasisMapping(this._dossiersService.activeDossier.dossierTemplateId)
.subscribe(data => {
data.map(lbm => {
this.legalOptions.push({
@@ -86,7 +88,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
comment: this.isDocumentAdmin ? [null] : [null, Validators.required]
});
- for (const key of Object.keys(this._appStateService.dictionaryData[this._appStateService.activeDossier.dossierTemplateId])) {
+ for (const key of Object.keys(this._appStateService.dictionaryData[this._dossiersService.activeDossier.dossierTemplateId])) {
const dictionaryData = this._appStateService.getDictionaryTypeValue(key);
if (!dictionaryData.virtual && dictionaryData.addToDictionaryAction) {
this.redactionDictionaries.push(dictionaryData);
@@ -103,6 +105,14 @@ export class ManualAnnotationDialogComponent implements OnInit {
);
}
+ format(value: string) {
+ return value.replace(
+ // eslint-disable-next-line no-control-regex,max-len
+ /([^\s\d-]{2,})[-\u00AD]\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]/gi,
+ '$1'
+ );
+ }
+
private _enhanceManualRedaction(addRedactionRequest: AddRedactionRequest) {
const legalOption: LegalBasisOption = this.redactionForm.get('reason').value;
addRedactionRequest.type = this.redactionForm.get('dictionary').value;
@@ -118,12 +128,4 @@ export class ManualAnnotationDialogComponent implements OnInit {
const commentValue = this.redactionForm.get('comment').value;
addRedactionRequest.comment = commentValue ? { text: commentValue } : null;
}
-
- format(value: string) {
- return value.replace(
- // eslint-disable-next-line no-control-regex,max-len
- /([^\s\d-]{2,})[-\u00AD]\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]/gi,
- '$1'
- );
- }
}
diff --git a/apps/red-ui/src/app/modules/dossier/dossiers.module.ts b/apps/red-ui/src/app/modules/dossier/dossiers.module.ts
index c4b617945..dffaa52ad 100644
--- a/apps/red-ui/src/app/modules/dossier/dossiers.module.ts
+++ b/apps/red-ui/src/app/modules/dossier/dossiers.module.ts
@@ -80,7 +80,6 @@ const components = [
];
const services = [
- DossiersService,
DossiersDialogService,
AnnotationActionsService,
ManualAnnotationService,
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html
index 8accd8635..6d727f388 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.html
@@ -3,43 +3,43 @@
(action)="delete()"
*ngIf="canDelete"
[tooltip]="'dossier-overview.bulk.delete' | translate"
- icon="red:trash"
[type]="circleButtonTypes.dark"
+ icon="red:trash"
>
-
+
@@ -56,23 +56,23 @@
(action)="setToUnderApproval()"
*ngIf="canUndoApproval"
[tooltip]="'dossier-overview.under-approval' | translate"
- icon="red:undo"
[type]="circleButtonTypes.dark"
+ icon="red:undo"
>
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts
index 701123da9..58d55bdb5 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/bulk-actions/dossier-overview-bulk-actions.component.ts
@@ -1,4 +1,4 @@
-import { Component, EventEmitter, Output } from '@angular/core';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
import { AppStateService } from '../../../../../../state/app-state.service';
import { FileManagementControllerService, ReanalysisControllerService } from '@redaction/red-ui-http';
import { PermissionsService } from '../../../../../../services/permissions.service';
@@ -9,6 +9,7 @@ import { DossiersDialogService } from '../../../../services/dossiers-dialog.serv
import { CircleButtonTypes, ConfirmationDialogInput, EntitiesService, LoadingService } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
+import { Dossier } from '@state/model/dossier';
@Component({
selector: 'redaction-dossier-overview-bulk-actions',
@@ -18,6 +19,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
export class DossierOverviewBulkActionsComponent {
readonly circleButtonTypes = CircleButtonTypes;
+ @Input() dossier: Dossier;
@Output() readonly reload = new EventEmitter();
constructor(
@@ -32,19 +34,12 @@ export class DossierOverviewBulkActionsComponent {
private readonly _entitiesService: EntitiesService
) {}
- get dossier() {
- return this._appStateService?.activeDossier;
- }
-
get selectedFiles(): File[] {
return this._entitiesService.selected;
}
get areAllFilesSelected() {
- return (
- this._appStateService.activeDossier.files.length !== 0 &&
- this.selectedFiles.length === this._appStateService.activeDossier.files.length
- );
+ return this.dossier.files.length !== 0 && this.selectedFiles.length === this.dossier.files.length;
}
get areSomeFilesSelected() {
@@ -133,7 +128,7 @@ export class DossierOverviewBulkActionsComponent {
await this._fileManagementControllerService
.deleteFiles(
this.selectedFiles.map(item => item.fileId),
- this._appStateService.activeDossierId
+ this.dossier.dossierId
)
.toPromise();
await this._appStateService.reloadActiveDossierFiles();
@@ -146,20 +141,16 @@ export class DossierOverviewBulkActionsComponent {
setToUnderApproval() {
// If more than 1 approver - show dialog and ask who to assign
- if (this._appStateService.activeDossier.approverIds.length > 1) {
+ if (this.dossier.approverIds.length > 1) {
this._assignFiles('approver', true);
} else {
- this._performBulkAction(
- this._fileActionService.setFilesUnderApproval(this.selectedFiles, this._appStateService.activeDossier.approverIds[0])
- );
+ this._performBulkAction(this._fileActionService.setFilesUnderApproval(this.selectedFiles, this.dossier.approverIds[0]));
}
}
async reanalyse() {
const fileIds = this.selectedFiles.filter(file => file.analysisRequired).map(file => file.fileId);
- this._performBulkAction(
- this._reanalysisControllerService.reanalyzeFilesForDossier(fileIds, this._appStateService.activeDossier.id)
- );
+ this._performBulkAction(this._reanalysisControllerService.reanalyzeFilesForDossier(fileIds, this.dossier.id));
}
ocr() {
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.html
index e237e4559..5201a21e5 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.html
@@ -1,66 +1,68 @@
-
-
- {{ 'dossier-overview.dossier-details.stats.documents' | translate: { count: activeDossier.files.length } }}
-
-
-
- {{ 'dossier-overview.dossier-details.stats.people' | translate: { count: activeDossier.memberIds.length } }}
-
-
-
- {{
- 'dossier-overview.dossier-details.stats.analysed-pages' | translate: { count: activeDossier.totalNumberOfPages | number }
- }}
-
-
-
-
{{
- 'dossier-overview.dossier-details.stats.created-on'
+
+
+
+ {{ 'dossier-overview.dossier-details.stats.documents' | translate: { count: dossier.files.length } }}
+
+
+
+ {{ 'dossier-overview.dossier-details.stats.people' | translate: { count: dossier.memberIds.length } }}
+
+
+
+ {{
+ 'dossier-overview.dossier-details.stats.analysed-pages' | translate: { count: dossier.totalNumberOfPages | number }
+ }}
+
+
+
+ {{
+ 'dossier-overview.dossier-details.stats.created-on'
+ | translate
+ : {
+ date: dossier.date | date: 'd MMM. yyyy'
+ }
+ }}
+
+
+
+
+ {{
+ 'dossier-overview.dossier-details.stats.due-date'
| translate
: {
- date: activeDossier.date | date: 'd MMM. yyyy'
+ date: dossier.dueDate | date: 'd MMM. yyyy'
}
- }}
-
-
-
-
- {{
- 'dossier-overview.dossier-details.stats.due-date'
- | translate
- : {
- date: activeDossier.dueDate | date: 'd MMM. yyyy'
- }
- }}
-
-
-
- {{ dossierTemplate?.name }}
-
-
-
- {{ 'dossier-overview.dossier-details.dictionary' | translate }}
-
-
-
-
- {{ 'dossier-overview.dossier-details.attributes.expand' | translate: { count: dossierAttributes.length } }}
+ }}
+
+
+
+ {{ dossierTemplate(dossier).name }}
+
+
+
+ {{ 'dossier-overview.dossier-details.dictionary' | translate }}
-
-
-
-
{{ attr.label + ': -' }}
-
{{ attr.label + ': ' + (attr.value | date: 'd MMM. yyyy') }}
-
- {{ attr.label + ': ' + ('dossier-overview.dossier-details.attributes.image-uploaded' | translate) }}
-
{{ attr.label + ': ' + attr.value }}
+
+
+ {{ 'dossier-overview.dossier-details.attributes.expand' | translate: { count: dossierAttributes.length } }}
-
- {{ 'dossier-overview.dossier-details.attributes.show-less' | translate }}
-
+
+
+
+ {{ attr.label + ': -' }}
+ {{ attr.label + ': ' + (attr.value | date: 'd MMM. yyyy') }}
+
+ {{ attr.label + ': ' + ('dossier-overview.dossier-details.attributes.image-uploaded' | translate) }}
+ {{ attr.label + ': ' + attr.value }}
+
+
+
+ {{ 'dossier-overview.dossier-details.attributes.show-less' | translate }}
+
+
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts
index dcfb93f0e..92fd0f559 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts
@@ -4,6 +4,7 @@ import { AppStateService } from '@state/app-state.service';
import { Dossier } from '@state/model/dossier';
import { IDossierTemplate } from '@redaction/red-ui-http';
import { DossiersDialogService } from '../../../../services/dossiers-dialog.service';
+import { DossiersService } from '../../../../services/dossiers.service';
@Component({
selector: 'redaction-dossier-details-stats',
@@ -15,19 +16,19 @@ export class DossierDetailsStatsComponent {
@Input() dossierAttributes: DossierAttributeWithValue[];
@Output() readonly openDossierDictionaryDialog = new EventEmitter();
- constructor(private readonly _appStateService: AppStateService, private readonly _dialogService: DossiersDialogService) {}
+ constructor(
+ private readonly _appStateService: AppStateService,
+ private readonly _dialogService: DossiersDialogService,
+ readonly dossiersService: DossiersService
+ ) {}
- get activeDossier(): Dossier {
- return this._appStateService.activeDossier;
+ dossierTemplate(dossier: Dossier): IDossierTemplate {
+ return this._appStateService.getDossierTemplateById(dossier.dossierTemplateId);
}
- get dossierTemplate(): IDossierTemplate {
- return this._appStateService.getDossierTemplateById(this.activeDossier.dossierTemplateId);
- }
-
- openEditDossierAttributesDialog() {
+ openEditDossierAttributesDialog(dossier: Dossier) {
this._dialogService.openDialog('editDossier', null, {
- dossier: this.activeDossier,
+ dossier,
section: 'dossierAttributes'
});
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.html
index 80255b717..0444ba767 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.html
@@ -1,11 +1,11 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.ts
index c291dce12..c7e90c7fd 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.ts
@@ -8,8 +8,9 @@ import { FilterService, Toaster } from '@iqser/common-ui';
import { DossierAttributeWithValue } from '@models/dossier-attributes.model';
import { fileStatusTranslations } from '../../../../translations/file-status-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
-import { List } from '@redaction/red-ui-http';
+import { DossierRequest } from '@redaction/red-ui-http';
import { User } from '@models/user';
+import { DossiersService } from '../../../../services/dossiers.service';
@Component({
selector: 'redaction-dossier-details',
@@ -32,6 +33,7 @@ export class DossierDetailsComponent implements OnInit {
constructor(
readonly appStateService: AppStateService,
+ readonly dossiersService: DossiersService,
readonly translateChartService: TranslateChartService,
readonly filterService: FilterService,
private readonly _changeDetectorRef: ChangeDetectorRef,
@@ -39,20 +41,12 @@ export class DossierDetailsComponent implements OnInit {
private readonly _toaster: Toaster
) {}
- get memberIds(): List {
- return this.appStateService.activeDossier.memberIds;
- }
-
- get hasFiles(): boolean {
- return this.appStateService.activeDossier.hasFiles;
- }
-
get managers() {
return this._userService.managerUsers;
}
ngOnInit(): void {
- this.owner = this._userService.getRedUserById(this.appStateService.activeDossier.ownerId);
+ this.owner = this._userService.getRedUserById(this.dossiersService.activeDossier.ownerId);
this.calculateChartConfig();
this.appStateService.fileChanged$.subscribe(() => {
this.calculateChartConfig();
@@ -60,11 +54,12 @@ export class DossierDetailsComponent implements OnInit {
}
calculateChartConfig(): void {
- if (!this.appStateService.activeDossier) {
+ const activeDossier = this.dossiersService.activeDossier;
+ if (!activeDossier) {
return;
}
- const groups = groupBy(this.appStateService.activeDossier?.files, 'status');
+ const groups = groupBy(activeDossier?.files, 'status');
this.documentsChartData = [];
for (const status of Object.keys(groups)) {
this.documentsChartData.push({
@@ -81,11 +76,12 @@ export class DossierDetailsComponent implements OnInit {
async assignOwner(user: User | string) {
this.owner = typeof user === 'string' ? this._userService.getRedUserById(user) : user;
- const dw = { ...this.appStateService.activeDossier, id: this.appStateService.activeDossierId, ownerId: this.owner.id };
- await this.appStateService.createOrUpdateDossier(dw);
+ const activeDossier = this.dossiersService.activeDossier;
+ const dossierRequest: DossierRequest = { ...activeDossier, dossierId: activeDossier.dossierId, ownerId: this.owner.id };
+ await this.dossiersService.createOrUpdate(dossierRequest).toPromise();
const ownerName = this._userService.getNameForId(this.owner.id);
- const dossierName = this.appStateService.activeDossier.dossierName;
+ const dossierName = activeDossier.dossierName;
this._toaster.info(_('assignment.owner'), { params: { ownerName, dossierName } });
}
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.ts
index 3507e73cb..a68573855 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.ts
@@ -14,6 +14,4 @@ export class TableItemComponent {
@Input() @Required() statsTemplate!: TemplateRef
;
@Input() @Required() displayedAttributes!: IFileAttributeConfig[];
@Output() readonly calculateData = new EventEmitter();
-
- constructor() {}
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts
index 5c390ea88..748c86a01 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/config.service.ts
@@ -14,6 +14,7 @@ import { annotationFilterChecker, RedactionFilterSorter, StatusSorter } from '@u
import { workloadTranslations } from '../../translations/workload-translations';
import * as moment from 'moment';
import { ConfigService as AppConfigService } from '@services/config.service';
+import { DossiersService } from '../../services/dossiers.service';
@Injectable()
export class ConfigService {
@@ -21,6 +22,7 @@ export class ConfigService {
private readonly _fileActionService: FileActionService,
private readonly _loadingService: LoadingService,
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _permissionsService: PermissionsService,
private readonly _translateService: TranslateService,
private readonly _userService: UserService,
@@ -331,7 +333,7 @@ export class ConfigService {
private _openEditDossierDialog($event: MouseEvent) {
this._dialogService.openDialog('editDossier', $event, {
- dossier: this._appStateService.activeDossier
+ dossier: this._dossiersService.activeDossier
});
}
@@ -345,7 +347,7 @@ export class ConfigService {
};
private _underApprovalFn = (reloadDossiers: () => Promise) => async (file: File) => {
- if (this._appStateService.activeDossier.approverIds.length > 1) {
+ if (this._dossiersService.activeDossier.approverIds.length > 1) {
this._fileActionService.assignFile('approver', null, file, () => this._loadingService.loadWhile(reloadDossiers()), true);
} else {
this._loadingService.start();
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html
index 16e001034..7dc4f46f6 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.html
@@ -7,13 +7,13 @@
>
-
+
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 640c77700..5d119fd53 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
@@ -50,6 +50,7 @@ import { Router } from '@angular/router';
import { FileAttributesService } from '../../../services/file-attributes.service';
import { ConfigService as AppConfigService } from '@services/config.service';
import { ConfigService } from '../config.service';
+import { DossiersService } from '../../../services/dossiers.service';
@Component({
templateUrl: './dossier-overview-screen.component.html',
@@ -60,7 +61,7 @@ export class DossierOverviewScreenComponent extends ListingComponent imple
readonly listingModes = ListingModes;
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser = this._userService.currentUser;
- currentDossier = this._appStateService.activeDossier;
+ currentDossier = this._dossiersService.activeDossier;
readonly tableHeaderLabel = _('dossier-overview.table-header.title');
collapsedDetails = false;
dossierAttributes: DossierAttributeWithValue[] = [];
@@ -83,6 +84,7 @@ export class DossierOverviewScreenComponent extends ListingComponent imple
readonly permissionsService: PermissionsService,
private readonly _loadingService: LoadingService,
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
readonly routerHistoryService: RouterHistoryService,
private readonly _appConfigService: AppConfigService,
private readonly _translateService: TranslateService,
@@ -96,11 +98,6 @@ export class DossierOverviewScreenComponent extends ListingComponent imple
private readonly _configService: ConfigService
) {
super(_injector);
- this._loadEntitiesFromState();
- this.fileAttributeConfigs = this._fileAttributesService.getFileAttributeConfig(
- this.currentDossier.dossierTemplateId
- )?.fileAttributeConfigs;
- this.tableColumnConfigs = this._configService.tableConfig(this.displayedAttributes);
}
get checkedRequiredFilters(): NestedFilter[] {
@@ -133,6 +130,11 @@ export class DossierOverviewScreenComponent extends ListingComponent imple
async ngOnInit(): Promise {
this._loadingService.start();
+ this._loadEntitiesFromState();
+ this.fileAttributeConfigs = this._fileAttributesService.getFileAttributeConfig(
+ this.currentDossier.dossierTemplateId
+ )?.fileAttributeConfigs;
+ this.tableColumnConfigs = this._configService.tableConfig(this.displayedAttributes);
try {
this._fileDropOverlayService.initFileDropHandling();
@@ -197,7 +199,7 @@ export class DossierOverviewScreenComponent extends ListingComponent imple
}
calculateData(): void {
- if (!this._appStateService.activeDossierId) {
+ if (!this._dossiersService.activeDossierId) {
return;
}
@@ -249,9 +251,9 @@ export class DossierOverviewScreenComponent extends ListingComponent imple
moment(file.lastUpdated).add(this._appConfigService.values.RECENT_PERIOD_IN_HOURS, 'hours').isAfter(moment());
private _loadEntitiesFromState() {
- this.currentDossier = this._appStateService.activeDossier;
+ this.currentDossier = this._dossiersService.activeDossier;
if (this.currentDossier) {
- this.entitiesService.setEntities(this.currentDossier.files);
+ this.entitiesService.setEntities([...this.currentDossier.files]);
}
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-actions/dossiers-listing-actions.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-actions/dossiers-listing-actions.component.html
index 7c7b364fe..78eac82af 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-actions/dossiers-listing-actions.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-actions/dossiers-listing-actions.component.html
@@ -4,17 +4,17 @@
(action)="openEditDossierDialog($event, dossier)"
*ngIf="currentUser.isManager"
[tooltip]="'dossier-listing.edit.action' | translate"
- icon="iqser:edit"
[type]="circleButtonTypes.dark"
+ icon="iqser:edit"
>
-
+
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.html
index 48847222d..8bcc76779 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.html
@@ -6,11 +6,11 @@
[subtitle]="'dossier-listing.stats.charts.dossiers' | translate"
>
-
+
-
{{ appStateService.totalAnalysedPages | number }}
+
{{ stats.totalAnalyzedPages | number }}
@@ -18,7 +18,7 @@
-
{{ appStateService.totalPeople }}
+
{{ stats.totalPeople }}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts
index dfaf1c60a..355ad624d 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts
@@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
-import { AppStateService } from '@state/app-state.service';
import { FilterService } from '@iqser/common-ui';
+import { DossiersService } from '../../../../services/dossiers.service';
@Component({
selector: 'redaction-dossiers-listing-details',
@@ -13,5 +13,5 @@ export class DossiersListingDetailsComponent {
@Input() dossiersChartData: DoughnutChartConfig[];
@Input() documentsChartData: DoughnutChartConfig[];
- constructor(readonly appStateService: AppStateService, readonly filterService: FilterService) {}
+ constructor(readonly filterService: FilterService, readonly dossiersService: DossiersService) {}
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/table-item/table-item.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/table-item/table-item.component.ts
index 7c2e63ce1..fad81a746 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/table-item/table-item.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/table-item/table-item.component.ts
@@ -9,7 +9,5 @@ import { Required } from '@iqser/common-ui';
})
export class TableItemComponent {
@Input() @Required() dossier!: Dossier;
- @Output() readonly calculateData = new EventEmitter
();
-
- constructor() {}
+ @Output() readonly calculateData = new EventEmitter();
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.ts
index e35358650..071959d12 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.ts
@@ -11,15 +11,31 @@ import { tap } from 'rxjs/operators';
import { Router } from '@angular/router';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import { groupBy, StatusSorter } from '@utils/index';
-import { DefaultListingServices, ListingComponent, OnAttach, OnDetach, TableComponent } from '@iqser/common-ui';
+import {
+ EntitiesService,
+ FilterService,
+ ListingComponent,
+ OnAttach,
+ OnDetach,
+ SearchService,
+ SortingService,
+ TableComponent
+} from '@iqser/common-ui';
import { fileStatusTranslations } from '../../../translations/file-status-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ConfigService } from '../config.service';
+import { DossiersService } from '../../../services/dossiers.service';
@Component({
templateUrl: './dossiers-listing-screen.component.html',
styleUrls: ['./dossiers-listing-screen.component.scss'],
- providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => DossiersListingScreenComponent) }]
+ providers: [
+ FilterService,
+ SearchService,
+ SortingService,
+ { provide: EntitiesService, useExisting: DossiersService },
+ { provide: ListingComponent, useExisting: forwardRef(() => DossiersListingScreenComponent) }
+ ]
})
export class DossiersListingScreenComponent
extends ListingComponent
@@ -45,13 +61,13 @@ export class DossiersListingScreenComponent
private readonly _userService: UserService,
readonly permissionsService: PermissionsService,
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _dialogService: DossiersDialogService,
private readonly _translateChartService: TranslateChartService,
private readonly _configService: ConfigService
) {
super(_injector);
this._appStateService.reset();
- this._loadEntitiesFromState();
}
private get _activeDossiersCount(): number {
@@ -67,7 +83,6 @@ export class DossiersListingScreenComponent
this.addSubscription = timer(0, 10000).subscribe(async () => {
await this._appStateService.loadAllDossiers();
- this._loadEntitiesFromState();
this.calculateData();
});
@@ -84,7 +99,6 @@ export class DossiersListingScreenComponent
ngOnAttach(): void {
this._appStateService.reset();
- this._loadEntitiesFromState();
this.ngOnInit();
this.ngAfterViewInit();
this._tableComponent.scrollViewport.scrollToIndex(this._lastScrolledIndex, 'smooth');
@@ -113,7 +127,7 @@ export class DossiersListingScreenComponent
{ value: this._activeDossiersCount, color: 'ACTIVE', label: _('active') },
{ value: this._inactiveDossiersCount, color: 'DELETED', label: _('archived') }
];
- const groups = groupBy(this._appStateService.aggregatedFiles, 'status');
+ const groups = groupBy(this._dossiersService.allFiles, 'status');
this.documentsChartData = [];
for (const status of Object.keys(groups)) {
@@ -128,10 +142,6 @@ export class DossiersListingScreenComponent
this.documentsChartData = this._translateChartService.translateStatus(this.documentsChartData);
}
- private _loadEntitiesFromState() {
- this.entitiesService.setEntities(this._appStateService.allDossiers);
- }
-
private _computeAllFilters() {
const filterGroups = this._configService.filterGroups(this.entitiesService.all, this._needsWorkFilterTemplate);
for (const filterGroup of filterGroups) {
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html
index 7fb6b46c0..ef520987f 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html
@@ -29,7 +29,7 @@
-
+
@@ -48,7 +48,7 @@
>
@@ -58,7 +58,7 @@
(cancel)="editingReviewer = false"
(save)="assignReviewer($event)"
*ngIf="editingReviewer"
- [options]="singleUsersSelectOptions"
+ [options]="singleUsersSelectOptions(dossier)"
[value]="currentReviewer"
>
@@ -118,7 +118,7 @@
{
if (!this.appStateService.activeFile.canBeOpened) {
- await this._router.navigate(['/main/dossiers/' + this.dossierId]);
- return;
+ return await this.dossiersService.goToActiveDossier();
}
await this.ngOnInit();
@@ -278,7 +274,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
console.log('[REDACTION] Delete previous annotations time: ' + (new Date().getTime() - startTime) + 'ms');
const processStartTime = new Date().getTime();
const newAnnotationsData = this.fileData.getAnnotations(
- this.appStateService.dictionaryData[this.appStateService.activeDossier.dossierTemplateId],
+ this.appStateService.dictionaryData[this.dossiersService.activeDossier.dossierTemplateId],
this.userService.currentUser,
this.viewMode,
this.userPreferenceService.areDevFeaturesEnabled
@@ -290,7 +286,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this.annotationData = newAnnotationsData;
const annotationFilters = this._annotationProcessingService.getAnnotationFilter(this.annotations);
const primaryFilters = this._filterService.getGroup('primaryFilters')?.filters;
- console.log(annotationFilters);
this._filterService.addFilterGroup({
slug: 'primaryFilters',
filterTemplate: this._filterTemplate,
@@ -302,8 +297,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
filterTemplate: this._filterTemplate,
filters: processFilters(secondaryFilters, AnnotationProcessingService.secondaryAnnotationFilters)
});
- console.log(this.annotations);
- console.log(this.appStateService.activeFile);
console.log('[REDACTION] Process time: ' + (new Date().getTime() - processStartTime) + 'ms');
console.log(
'[REDACTION] Annotation Redraw and filter rebuild time: ' +
@@ -451,8 +444,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
switch (action) {
case 'delete':
- await this._router.navigate([`/main/dossiers/${this.dossierId}`]);
- return;
+ return await this.dossiersService.goToActiveDossier();
case 'enable-analysis':
case 'reanalyse':
@@ -522,7 +514,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
downloadOriginalFile() {
this.addSubscription = this._fileManagementControllerService
- .downloadOriginalFile(this.dossierId, this.fileId, true, this.fileData.file.cacheIdentifier, 'response')
+ .downloadOriginalFile(this.fileData.file.dossierId, this.fileId, true, this.fileData.file.cacheIdentifier, 'response')
.subscribe(data => {
download(data, this.fileData.file.filename);
});
@@ -538,15 +530,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
return false;
}
- //
- async openSSRFilePreview() {
- window.open(`/pdf-preview/${this.dossierId}/${this.fileId}`, '_blank');
- }
-
- async openHTMLDebug() {
- window.open(`/html-debug/${this.dossierId}/${this.fileId}`, '_blank');
- }
-
private _setHiddenPropertyToNewAnnotations(newAnnotations: AnnotationWrapper[], oldAnnotations: AnnotationWrapper[]) {
newAnnotations.map((newAnnotation: AnnotationWrapper) => {
const oldAnnotation = oldAnnotations.find((a: AnnotationWrapper) => a.annotationId === newAnnotation.annotationId);
@@ -619,7 +602,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
if (fileData.file.isError) {
- await this._router.navigate(['/main/dossiers/' + this.dossierId]);
+ await this.dossiersService.goToActiveDossier();
}
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts
index 1005f3eef..716563712 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts
@@ -13,11 +13,11 @@ import { List, MatchedDocument, SearchControllerService, SearchResult } from '@r
import { BehaviorSubject, Observable } from 'rxjs';
import { debounceTime, map, skip, switchMap, tap } from 'rxjs/operators';
import { ActivatedRoute, Router } from '@angular/router';
-import { AppStateService } from '@state/app-state.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { fileStatusTranslations } from '../../translations/file-status-translations';
import { TranslateService } from '@ngx-translate/core';
import { RouterHistoryService } from '@services/router-history.service';
+import { DossiersService } from '../../services/dossiers.service';
interface ListItem extends IListable {
readonly dossierId: string;
@@ -65,19 +65,20 @@ export class SearchScreenComponent extends ListingComponent implements
protected readonly _injector: Injector,
private readonly _activatedRoute: ActivatedRoute,
private readonly _loadingService: LoadingService,
- private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
readonly routerHistoryService: RouterHistoryService,
private readonly _translateService: TranslateService,
private readonly _searchControllerService: SearchControllerService
) {
super(_injector);
+ this.searchService.skip = true;
this.filterService.addFilterGroup({
slug: 'dossiers',
label: this._translateService.instant('search-screen.filters.by-dossier'),
filterceptionPlaceholder: this._translateService.instant('search-screen.filters.search-placeholder'),
icon: 'red:folder',
- filters: this._appStateService.allDossiers.map(
+ filters: this._dossiersService.all.map(
dossier =>
new NestedFilter({
id: dossier.id,
@@ -135,7 +136,7 @@ export class SearchScreenComponent extends ListingComponent implements
}
private _toListItem({ dossierId, fileId, unmatchedTerms, highlights }: MatchedDocument): ListItem {
- const file = this._appStateService.getFileById(dossierId, fileId);
+ const file = this._dossiersService.find(dossierId, fileId);
if (!file) {
return undefined;
}
@@ -147,7 +148,7 @@ export class SearchScreenComponent extends ListingComponent implements
highlights,
status: file.status,
numberOfPages: file.numberOfPages,
- dossierName: this._appStateService.getDossierById(dossierId).dossierName,
+ dossierName: this._dossiersService.find(dossierId).dossierName,
filename: file.filename,
searchKey: file.filename,
routerLink: `/main/dossiers/${dossierId}/file/${fileId}`
diff --git a/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts b/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts
index 471f2f1cb..8ed474bf6 100644
--- a/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/services/annotation-draw.service.ts
@@ -5,12 +5,14 @@ import { hexToRgb } from '@utils/functions';
import { AppStateService } from '@state/app-state.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { UserPreferenceService } from '@services/user-preference.service';
+import { DossiersService } from './dossiers.service';
import Annotation = Core.Annotations.Annotation;
@Injectable()
export class AnnotationDrawService {
constructor(
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _redactionLogControllerService: RedactionLogControllerService,
private readonly _userPreferenceService: UserPreferenceService
) {}
@@ -28,7 +30,7 @@ export class AnnotationDrawService {
if (this._userPreferenceService.areDevFeaturesEnabled) {
this._redactionLogControllerService
- .getSectionGrid(this._appStateService.activeDossierId, this._appStateService.activeFileId)
+ .getSectionGrid(this._dossiersService.activeDossierId, this._appStateService.activeFileId)
.subscribe(sectionGrid => {
this.drawSections(activeViewer, sectionGrid);
});
diff --git a/apps/red-ui/src/app/modules/dossier/services/dossiers.service.ts b/apps/red-ui/src/app/modules/dossier/services/dossiers.service.ts
index 46a87f29b..90654ad04 100644
--- a/apps/red-ui/src/app/modules/dossier/services/dossiers.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/services/dossiers.service.ts
@@ -1,12 +1,15 @@
import { Injectable, Injector } from '@angular/core';
-import { IDossier } from '@redaction/red-ui-http';
-import { EntitiesService, List, QueryParam } from '@iqser/common-ui';
+import { DossierRequest, IDossier } from '@redaction/red-ui-http';
+import { EntitiesService, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
import { Dossier } from '@state/model/dossier';
-import { filter, map } from 'rxjs/operators';
+import { catchError, filter, map, tap } from 'rxjs/operators';
import { TEMPORARY_INJECTOR } from './injector';
-import { BehaviorSubject, Observable } from 'rxjs';
+import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
import { ActivationEnd, Router } from '@angular/router';
import { BaseScreenComponent } from '@components/base-screen/base-screen.component';
+import { File } from '@models/file/file';
+import { DictionaryService } from '@shared/services/dictionary.service';
+import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
export interface IDossiersStats {
totalPeople: number;
@@ -14,63 +17,139 @@ export interface IDossiersStats {
}
const getRelatedEvents = filter(event => event instanceof ActivationEnd && event.snapshot.component !== BaseScreenComponent);
+const DOSSIER_EXISTS_MSG = _('add-dossier-dialog.errors.dossier-already-exists');
+const GENERIC_MGS = _('add-dossier-dialog.errors.generic');
@Injectable({
providedIn: 'root'
})
export class DossiersService extends EntitiesService {
readonly stats$ = this.all$.pipe(map(entities => this._computeStats(entities)));
- readonly activeDossierId$: Observable;
- readonly activeDossier$: Observable;
- private readonly _activeDossierId$ = new BehaviorSubject(null);
+ readonly activeDossier$: Observable;
+ readonly dossierChanged$ = new Subject();
+ private readonly _activeDossier$ = new BehaviorSubject(undefined);
- constructor(protected readonly _injector: Injector, private readonly _router: Router) {
+ constructor(
+ protected readonly _injector: Injector,
+ private readonly _router: Router,
+ private readonly _dictionaryService: DictionaryService,
+ private readonly _toaster: Toaster
+ ) {
super(TEMPORARY_INJECTOR(_injector), 'dossier');
- this.activeDossierId$ = this._activeDossierId$.asObservable();
- this.activeDossier$ = this.activeDossierId$.pipe(map(id => this.all.find(dossier => dossier.id === id)));
+ this.activeDossier$ = this._activeDossier$.asObservable();
_router.events.pipe(getRelatedEvents).subscribe((event: ActivationEnd) => {
const dossierId = event.snapshot.paramMap.get('dossierId');
- const sameIdAsCurrentActive = dossierId === this._activeDossierId$.getValue();
+ const sameIdAsCurrentActive = dossierId === this._activeDossier$.getValue()?.dossierId;
if (sameIdAsCurrentActive) {
return;
}
if (dossierId === null || dossierId === undefined) {
- return this._activeDossierId$.next(null);
+ return this._activeDossier$.next(undefined);
}
- // const notFound = !this.all.some(dossier => dossier.id === dossierId);
- // if (notFound) {
- // return this._router.navigate(['/main/dossiers']).then();
- // }
+ if (!this.has(dossierId)) {
+ this._activeDossier$.next(undefined);
+ return this._router.navigate(['/main/dossiers']).then();
+ }
- this._activeDossierId$.next(dossierId);
+ this._activeDossier$.next(this.find(dossierId));
+ this.updateDossierDictionary(this.activeDossier.dossierTemplateId, dossierId).then();
});
}
+ get allFiles(): File[] {
+ return this.all.reduce((acc: File[], { files }) => [...acc, ...files], []);
+ }
+
+ get activeDossier(): Dossier | undefined {
+ return this._activeDossier$.value;
+ }
+
+ get activeDossierId(): string | undefined {
+ return this._activeDossier$.value?.dossierId;
+ }
+
+ goToActiveDossier(): Promise {
+ return this._router.navigate([this.activeDossier?.routerLink]).then();
+ }
+
+ find(dossierId: string): Dossier | undefined;
+ find(dossierId: string, fileId: string): File | undefined;
+ find(dossierId: string, fileId?: string): Dossier | File | undefined {
+ const dossier = this.all.find(item => item.dossierId === dossierId);
+ return fileId ? dossier?.files.find(file => file.fileId === fileId) : dossier;
+ }
+
+ replace(newDossier: Dossier) {
+ const dossiers = this.all.filter(dossier => dossier.dossierId !== newDossier.dossierId);
+ dossiers.push(newDossier);
+ this.setEntities(dossiers);
+ this.dossierChanged$.next(newDossier);
+ if (newDossier.dossierId === this.activeDossierId) {
+ this._activeDossier$.next(newDossier);
+ }
+ }
+
+ has(dossierId: string): boolean {
+ return this.all.some(dossier => dossier.dossierId === dossierId);
+ }
+
+ async updateDossierDictionary(dossierTemplateId: string, dossierId: string) {
+ // dossier exists, load its dictionary
+ const dossier = this.find(dossierId);
+ try {
+ dossier.type = await this._dictionaryService.getFor(dossierTemplateId, 'dossier_redaction', dossierId).toPromise();
+ } catch (e) {
+ dossier.type = null;
+ }
+ }
+
get(): Observable;
get(dossierId: string): Observable;
get(dossierId?: string): Observable {
return dossierId ? super._getOne([dossierId]) : super.getAll();
}
- createOrUpdate(dossier: IDossier): Promise {
- return this._post(dossier).toPromise();
+ @Validate()
+ createOrUpdate(@RequiredParam() dossier: DossierRequest): Observable {
+ return this._post(dossier).pipe(
+ map(updatedDossier => new Dossier(updatedDossier, this.find(updatedDossier.dossierId)?.files ?? [])),
+ tap(newDossier => this.replace(newDossier)),
+ catchError(error => {
+ this._toaster.error(error.status === 409 ? DOSSIER_EXISTS_MSG : GENERIC_MGS);
+ return of(undefined);
+ })
+ );
}
getDeleted(): Promise {
return this.getAll('deleted-dossiers').toPromise();
}
- restore(dossierIds: List): Promise {
+ delete(dossier: Dossier): Observable {
+ const updateDossiers = () => {
+ console.log(this.all.filter(d => d.dossierId !== dossier.dossierId));
+ this.setEntities(this.all.filter(d => d.dossierId !== dossier.dossierId));
+ };
+ const showToast = () => {
+ this._toaster.error(_('dossier-listing.delete.delete-failed'), { params: dossier });
+ return of({});
+ };
+ return super.delete(dossier.dossierId).pipe(tap(updateDossiers), catchError(showToast));
+ }
+
+ @Validate()
+ restore(@RequiredParam() dossierIds: List): Promise {
return this._post(dossierIds, 'deleted-dossiers/restore').toPromise();
}
- hardDelete(dossierIds: List): Promise {
+ @Validate()
+ hardDelete(@RequiredParam() dossierIds: List): Promise {
const body = dossierIds.map(id => ({ key: 'dossierId', value: id }));
- return this.delete(body, 'deleted-dossiers/hard-delete', body).toPromise();
+ return super.delete(body, 'deleted-dossiers/hard-delete', body).toPromise();
}
private _computeStats(entities: List): IDossiersStats {
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 f38d0bdc5..862212d1f 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
@@ -10,6 +10,7 @@ import { PermissionsService } from '@services/permissions.service';
import { AnnotationActionMode } from '../models/annotation-action-mode.model';
import { annotationActionsTranslations } from '../translations/annotation-actions-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
+import { DossiersService } from './dossiers.service';
@Injectable()
export class ManualAnnotationService {
@@ -19,6 +20,7 @@ export class ManualAnnotationService {
constructor(
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _userService: UserService,
private readonly _translateService: TranslateService,
private readonly _toaster: Toaster,
@@ -46,13 +48,13 @@ export class ManualAnnotationService {
const obs = !secondParam
? this._manualRedactionControllerService[this.CONFIG[mode]](
body,
- this._appStateService.activeDossierId,
+ this._dossiersService.activeDossierId,
this._appStateService.activeFileId
)
: this._manualRedactionControllerService[this.CONFIG[mode]](
body,
secondParam,
- this._appStateService.activeDossierId,
+ this._dossiersService.activeDossierId,
this._appStateService.activeFileId
);
@@ -74,7 +76,7 @@ export class ManualAnnotationService {
return this._manualRedactionControllerService.addComment(
{ text: comment },
annotationId,
- this._appStateService.activeDossierId,
+ this._dossiersService.activeDossierId,
this._appStateService.activeFileId
);
}
@@ -84,7 +86,7 @@ export class ManualAnnotationService {
return this._manualRedactionControllerService.undoComment(
annotationId,
commentId,
- this._appStateService.activeDossierId,
+ this._dossiersService.activeDossierId,
this._appStateService.activeFileId
);
}
diff --git a/apps/red-ui/src/app/modules/dossier/services/pdf-viewer-data.service.ts b/apps/red-ui/src/app/modules/dossier/services/pdf-viewer-data.service.ts
index 5744621d9..4db531619 100644
--- a/apps/red-ui/src/app/modules/dossier/services/pdf-viewer-data.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/services/pdf-viewer-data.service.ts
@@ -11,11 +11,13 @@ import { FileDataModel } from '@models/file/file-data.model';
import { AppStateService } from '@state/app-state.service';
import { PermissionsService } from '@services/permissions.service';
import { File } from '@models/file/file';
+import { DossiersService } from './dossiers.service';
@Injectable()
export class PdfViewerDataService {
constructor(
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _permissionsService: PermissionsService,
private readonly _man: ManualRedactionControllerService,
private readonly _fileManagementControllerService: FileManagementControllerService,
@@ -25,7 +27,7 @@ export class PdfViewerDataService {
loadActiveFileRedactionLog() {
return this._redactionLogControllerService
- .getRedactionLog(this._appStateService.activeDossierId, this._appStateService.activeFileId)
+ .getRedactionLog(this._dossiersService.activeDossierId, this._appStateService.activeFileId)
.pipe(
tap(
redactionLog => redactionLog.redactionLogEntry.sort((a, b) => a.positions[0].page - b.positions[0].page),
@@ -47,7 +49,7 @@ export class PdfViewerDataService {
getViewedPagesForActiveFile() {
if (this._permissionsService.canMarkPagesAsViewed()) {
return this._viewedPagesControllerService
- .getViewedPages(this._appStateService.activeDossierId, this._appStateService.activeFileId)
+ .getViewedPages(this._dossiersService.activeDossierId, this._appStateService.activeFileId)
.pipe(catchError(() => of({ pages: [] })));
}
return of({ pages: [] });
diff --git a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html
index 71850629a..867b9f857 100644
--- a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html
+++ b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html
@@ -47,8 +47,8 @@
{
+ this.addSubscription = this.dossiersService.dossierChanged$.subscribe(() => {
this._setup();
});
}
@@ -172,7 +174,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
setFileUnderApproval($event: MouseEvent) {
$event.stopPropagation();
- if (this.appStateService.activeDossier.approverIds.length > 1) {
+ if (this.dossiersService.activeDossier.approverIds.length > 1) {
this._fileActionService.assignFile('approver', $event, this.file, () => this.reloadDossiers('assign-reviewer'), true);
} else {
this.addSubscription = this._fileActionService.setFilesUnderApproval([this.file]).subscribe(() => {
diff --git a/apps/red-ui/src/app/modules/dossier/shared/services/file-action.service.ts b/apps/red-ui/src/app/modules/dossier/shared/services/file-action.service.ts
index 84d7e70b5..ebcd2346d 100644
--- a/apps/red-ui/src/app/modules/dossier/shared/services/file-action.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/shared/services/file-action.service.ts
@@ -8,6 +8,7 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FilesService } from '../../services/files.service';
import { ConfirmationDialogInput } from '@iqser/common-ui';
+import { DossiersService } from '../../services/dossiers.service';
@Injectable()
export class FileActionService {
@@ -17,11 +18,12 @@ export class FileActionService {
private readonly _userService: UserService,
private readonly _fileService: FilesService,
private readonly _reanalysisControllerService: ReanalysisControllerService,
- private readonly _appStateService: AppStateService
+ private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService
) {}
reanalyseFile(file = this._appStateService.activeFile) {
- return this._reanalysisControllerService.reanalyzeFile(this._appStateService.activeDossier.id, file.fileId, true);
+ return this._reanalysisControllerService.reanalyzeFile(this._dossiersService.activeDossier.id, file.fileId, true);
}
toggleAnalysis(file = this._appStateService.activeFile) {
@@ -51,34 +53,34 @@ export class FileActionService {
setFilesUnderApproval(files: File[], approverId?: string) {
if (!approverId) {
- approverId = this._appStateService.activeDossier.approverIds[0];
+ approverId = this._dossiersService.activeDossier.approverIds[0];
}
return this._fileService.setUnderApprovalFor(
files.map(f => f.fileId),
approverId,
- this._appStateService.activeDossierId
+ this._dossiersService.activeDossierId
);
}
setFilesApproved(files: File[]) {
return this._fileService.setApprovedFor(
files.map(f => f.fileId),
- this._appStateService.activeDossierId
+ this._dossiersService.activeDossierId
);
}
setFilesUnderReview(files: File[]) {
return this._fileService.setUnderReviewFor(
files.map(f => f.fileId),
- this._appStateService.activeDossierId
+ this._dossiersService.activeDossierId
);
}
ocrFiles(files: File[]) {
return this._reanalysisControllerService.ocrFiles(
files.map(f => f.fileId),
- this._appStateService.activeDossierId
+ this._dossiersService.activeDossierId
);
}
@@ -101,7 +103,7 @@ export class FileActionService {
await this._fileService
.setReviewerFor(
files.map(f => f.fileId),
- this._appStateService.activeDossierId,
+ this._dossiersService.activeDossierId,
this._userService.currentUser.id
)
.toPromise();
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 1d41ba93f..f822b1573 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
@@ -3,8 +3,7 @@ import { PermissionsService } from '@services/permissions.service';
import { Dossier } from '../../../../../state/model/dossier';
import { File } from '@models/file/file';
import { FileDownloadService } from '@upload-download/services/file-download.service';
-import { Toaster } from '@iqser/common-ui';
-import { AutoUnsubscribe, CircleButtonType, CircleButtonTypes } from '@iqser/common-ui';
+import { AutoUnsubscribe, CircleButtonType, CircleButtonTypes, List, Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@@ -18,7 +17,7 @@ export type MenuState = 'OPEN' | 'CLOSED';
})
export class FileDownloadBtnComponent extends AutoUnsubscribe implements OnDestroy {
@Input() dossier: Dossier;
- @Input() file: File | File[];
+ @Input() files: List;
@Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above';
@Input() type: CircleButtonType = CircleButtonTypes.default;
@Input() tooltipClass: string;
@@ -34,11 +33,7 @@ export class FileDownloadBtnComponent extends AutoUnsubscribe implements OnDestr
}
get canDownloadFiles() {
- if (!Array.isArray(this.file)) {
- return this._permissionsService.canDownloadFiles(this.file);
- }
-
- return this.file.length > 0 && this.file.reduce((acc, file) => acc && this._permissionsService.canDownloadFiles(file), true);
+ return this.files.length > 0 && this.files.reduce((acc, file) => acc && this._permissionsService.canDownloadFiles(file), true);
}
get tooltip() {
@@ -50,7 +45,7 @@ export class FileDownloadBtnComponent extends AutoUnsubscribe implements OnDestr
downloadFiles($event: MouseEvent) {
$event.stopPropagation();
this.addSubscription = this._fileDownloadService
- .downloadFiles(Array.isArray(this.file) ? this.file : [this.file], this.dossier)
+ .downloadFiles(this.files, this.dossier)
.subscribe(() => this._toaster.info(_('download-status.queued')));
}
}
diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html
index f5c16d073..5b097423b 100644
--- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html
+++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html
@@ -33,7 +33,7 @@
{{ selectDossier.dossierName | translate }}
-
+
{{ dossier.dossierName }}
diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts
index 33bfc20ed..270dd1efe 100644
--- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts
+++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts
@@ -1,11 +1,11 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
-import { AppStateService } from '@state/app-state.service';
import { Debounce, IconButtonTypes, List } from '@iqser/common-ui';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { Dossier } from '@state/model/dossier';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DictionaryService } from '@shared/services/dictionary.service';
+import { DossiersService } from '../../../dossier/services/dossiers.service';
import ICodeEditor = monaco.editor.ICodeEditor;
import IDiffEditor = monaco.editor.IDiffEditor;
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
@@ -44,7 +44,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
private _decorations: string[] = [];
private _searchDecorations: string[] = [];
- constructor(private readonly _dictionaryService: DictionaryService, private readonly _appStateService: AppStateService) {}
+ constructor(private readonly _dictionaryService: DictionaryService, readonly dossiersService: DossiersService) {}
private _dossier: Dossier = this.selectDossier as Dossier;
@@ -72,10 +72,6 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
});
}
- get dossiers() {
- return this._appStateService.allDossiers;
- }
-
get editorValue(): string {
return this.currentEntries.join('\n');
}
diff --git a/apps/red-ui/src/app/modules/shared/components/type-filter/type-filter.component.ts b/apps/red-ui/src/app/modules/shared/components/type-filter/type-filter.component.ts
index 39c71c592..9d2866f9d 100644
--- a/apps/red-ui/src/app/modules/shared/components/type-filter/type-filter.component.ts
+++ b/apps/red-ui/src/app/modules/shared/components/type-filter/type-filter.component.ts
@@ -1,5 +1,5 @@
import { Component, Input, OnInit } from '@angular/core';
-import { AppStateService } from '../../../../state/app-state.service';
+import { AppStateService } from '@state/app-state.service';
import { INestedFilter } from '@iqser/common-ui';
@Component({
diff --git a/apps/red-ui/src/app/modules/upload-download/file-drop/file-drop.component.ts b/apps/red-ui/src/app/modules/upload-download/file-drop/file-drop.component.ts
index 991a2ee75..4e8c11a71 100644
--- a/apps/red-ui/src/app/modules/upload-download/file-drop/file-drop.component.ts
+++ b/apps/red-ui/src/app/modules/upload-download/file-drop/file-drop.component.ts
@@ -4,7 +4,7 @@ import { FileUploadModel } from '../model/file-upload.model';
import { OverlayRef } from '@angular/cdk/overlay';
import { StatusOverlayService } from '../services/status-overlay.service';
import { handleFileDrop } from '@utils/file-drop-utils';
-import { AppStateService } from '@state/app-state.service';
+import { DossiersService } from '../../dossier/services/dossiers.service';
@Component({
selector: 'redaction-file-drop',
@@ -15,7 +15,7 @@ export class FileDropComponent {
constructor(
private readonly _dialogRef: OverlayRef,
private readonly _fileUploadService: FileUploadService,
- private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _statusOverlayService: StatusOverlayService
) {}
@@ -33,7 +33,7 @@ export class FileDropComponent {
@HostListener('drop', ['$event'])
onDrop(event: DragEvent) {
- handleFileDrop(event, this._appStateService.activeDossier, this.uploadFiles.bind(this));
+ handleFileDrop(event, this._dossiersService.activeDossier, this.uploadFiles.bind(this));
}
@HostListener('dragover', ['$event'])
diff --git a/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts b/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts
index 74230877b..45741d33c 100644
--- a/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts
+++ b/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts
@@ -10,6 +10,7 @@ import { DownloadStatusWrapper } from '../model/download-status.wrapper';
import { AppStateService } from '@state/app-state.service';
import { KeycloakService } from 'keycloak-angular';
import { UserService } from '@services/user.service';
+import { List } from '@iqser/common-ui';
@Injectable()
export class FileDownloadService {
@@ -34,7 +35,7 @@ export class FileDownloadService {
});
}
- downloadFiles(files: File[], dossier: Dossier): Observable
{
+ downloadFiles(files: List, dossier: Dossier): Observable {
return this._downloadControllerService
.prepareDownload({
fileIds: files.map(f => f.fileId),
diff --git a/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts b/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts
index 2384b562a..f6133266f 100644
--- a/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts
+++ b/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts
@@ -10,6 +10,7 @@ import { toNumber } from '@utils/functions';
import { UploadControllerService } from '@redaction/red-ui-http';
import { isCsv } from '@utils/file-drop-utils';
import { ErrorMessageService } from '@iqser/common-ui';
+import { DossiersService } from '../../dossier/services/dossiers.service';
export interface ActiveUpload {
subscription: Subscription;
@@ -28,6 +29,7 @@ export class FileUploadService {
constructor(
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _applicationRef: ApplicationRef,
private readonly _translateService: TranslateService,
private readonly _configService: ConfigService,
@@ -57,7 +59,7 @@ export class FileUploadService {
async uploadFiles(files: FileUploadModel[]): Promise {
const maxSizeMB = this._configService.values.MAX_FILE_SIZE_MB;
const maxSizeBytes = toNumber(maxSizeMB) * 1024 * 1024;
- const dossierFiles = this._appStateService.activeDossier.files;
+ const dossierFiles = this._dossiersService.activeDossier.files;
let option: 'overwrite' | 'skip';
for (let idx = 0; idx < files.length; ++idx) {
const file = files[idx];
diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts
index 02a6d9658..acc7f9323 100644
--- a/apps/red-ui/src/app/services/permissions.service.ts
+++ b/apps/red-ui/src/app/services/permissions.service.ts
@@ -4,26 +4,31 @@ import { UserService } from './user.service';
import { File } from '@models/file/file';
import { Comment } from '@redaction/red-ui-http';
import { Dossier } from '@state/model/dossier';
+import { DossiersService } from '../modules/dossier/services/dossiers.service';
@Injectable({
providedIn: 'root'
})
export class PermissionsService {
- constructor(private readonly _appStateService: AppStateService, private readonly _userService: UserService) {}
+ constructor(
+ private readonly _appStateService: AppStateService,
+ private readonly _userService: UserService,
+ private readonly _dossiersService: DossiersService
+ ) {}
private get _activeFile(): File | undefined {
return this._appStateService.activeFile;
}
private get _activeDossier(): Dossier | undefined {
- return this._appStateService.activeDossier;
+ return this._dossiersService.activeDossier;
}
isReviewerOrApprover(file?: File): boolean {
return this.isFileReviewer(file) || this.isApprover();
}
- displayReanalyseBtn(dossier = this._activeDossier): boolean {
+ displayReanalyseBtn(dossier: Dossier): boolean {
return this.isApprover(dossier) && dossier.files.filter(file => file.analysisRequired).length > 0;
}
@@ -46,7 +51,7 @@ export class PermissionsService {
canAssignToSelf(file = this._activeFile): boolean {
const precondition = this.isDossierMember() && !file.isProcessing && !file.isError && !file.isApproved;
- const isTheOnlyReviewer = !this._appStateService.activeDossier?.hasReviewers;
+ const isTheOnlyReviewer = !this._activeDossier?.hasReviewers;
if (precondition) {
if (
@@ -85,7 +90,7 @@ export class PermissionsService {
return file?.isUnderReview && this.isReviewerOrApprover(file);
}
- isOwner(dossier = this._activeDossier, user = this._userService.currentUser): boolean {
+ isOwner(dossier: Dossier, user = this._userService.currentUser): boolean {
return dossier?.ownerId === user.id;
}
@@ -113,8 +118,8 @@ export class PermissionsService {
return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file?.status) && this.isFileReviewer(file);
}
- canDownloadFiles(file = this._activeFile): boolean {
- const dossier = this._appStateService.getDossierById(file?.dossierId);
+ canDownloadFiles(file: File): boolean {
+ const dossier = this._dossiersService.find(file?.dossierId);
if (!dossier) {
return false;
}
diff --git a/apps/red-ui/src/app/state/app-state.guard.ts b/apps/red-ui/src/app/state/app-state.guard.ts
index 39c225494..113c461c2 100644
--- a/apps/red-ui/src/app/state/app-state.guard.ts
+++ b/apps/red-ui/src/app/state/app-state.guard.ts
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
import { AppStateService } from './app-state.service';
import { UserService } from '@services/user.service';
+import { DossiersService } from '../modules/dossier/services/dossiers.service';
@Injectable({
providedIn: 'root'
@@ -9,6 +10,7 @@ import { UserService } from '@services/user.service';
export class AppStateGuard implements CanActivate {
constructor(
private readonly _appStateService: AppStateService,
+ private readonly _dossiersService: DossiersService,
private readonly _userService: UserService,
private readonly _router: Router
) {}
@@ -30,12 +32,12 @@ export class AppStateGuard implements CanActivate {
const { dossierId, fileId, dossierTemplateId, type } = route.params;
- if (dossierId && !this._appStateService.getDossierById(dossierId)) {
+ if (dossierId && !this._dossiersService.find(dossierId)) {
await this._router.navigate(['main', 'dossiers']);
return false;
}
- if (fileId && !this._appStateService.getFileById(dossierId, fileId)) {
+ if (fileId && !this._dossiersService.find(dossierId, fileId)) {
await this._router.navigate(['main', 'dossiers', dossierId]);
return false;
}
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 c0eeee9c7..19509cec4 100644
--- a/apps/red-ui/src/app/state/app-state.service.ts
+++ b/apps/red-ui/src/app/state/app-state.service.ts
@@ -1,18 +1,17 @@
import { Injectable } from '@angular/core';
-import { Colors, IDossier, IFile, ReanalysisControllerService } from '@redaction/red-ui-http';
+import { Colors, IFile, ReanalysisControllerService } from '@redaction/red-ui-http';
import { Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
-import { Event, NavigationEnd, ResolveStart, Router } from '@angular/router';
+import { Event, ResolveStart, Router } from '@angular/router';
import { UserService } from '@services/user.service';
import { forkJoin, Observable, of, Subject } from 'rxjs';
-import { catchError, map, tap } from 'rxjs/operators';
+import { catchError, filter, first, map, tap } from 'rxjs/operators';
import { FALLBACK_COLOR, hexToRgb } from '@utils/functions';
import { File } from '@models/file/file';
import { Dossier } from './model/dossier';
import { TypeValue } from '@models/file/type-value';
import { DossierTemplate } from '@models/file/dossier-template';
import { DossiersService } from '../modules/dossier/services/dossiers.service';
-import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UserPreferenceService } from '@services/user-preference.service';
import { FilesService } from '../modules/dossier/services/files.service';
import { DictionaryService } from '@shared/services/dictionary.service';
@@ -20,14 +19,10 @@ import { DossierTemplatesService } from '../modules/dossier/services/dossier-tem
import { FileAttributesService } from '../modules/dossier/services/file-attributes.service';
export interface AppState {
- dossiers: Dossier[];
dossierTemplates: DossierTemplate[];
- activeDossierId: string;
- activeFileId: string;
- activeDossierTemplateId: string;
- activeDictionaryType: string;
- totalAnalysedPages?: number;
- totalPeople?: number;
+ activeFileId?: string;
+ activeDossierTemplateId?: string;
+ activeDictionaryType?: string;
}
@Injectable({
@@ -36,7 +31,6 @@ export interface AppState {
export class AppStateService {
readonly fileChanged$ = new Subject();
readonly fileReanalysed$ = new Subject();
- readonly dossierChanged$ = new Subject();
readonly dossierTemplateChanged$ = new Subject();
private _appState: AppState;
@@ -55,45 +49,37 @@ export class AppStateService {
private readonly _userPreferenceService: UserPreferenceService
) {
this._appState = {
- dossiers: [],
- dossierTemplates: [],
- activeDossierId: null,
- activeFileId: null,
- activeDossierTemplateId: null,
- activeDictionaryType: null
+ dossierTemplates: []
};
- _router.events.subscribe((event: Event) => {
+ _router.events.subscribe(async (event: Event) => {
if (AppStateService._isFileOverviewRoute(event)) {
const url = (event as ResolveStart).url.replace('/main/dossiers/', '');
const [dossierId, , fileId] = url.split(/[/?]/);
- return this.activateFile(dossierId, fileId);
- }
- if (AppStateService._isDossierOverviewRoute(event)) {
- const dossierId = (event as ResolveStart).url.replace('/main/dossiers/', '');
- return this.activateDossier(dossierId);
- }
- if (AppStateService._isRandomRoute(event)) {
- this._appState.activeDossierId = null;
+ await _dossiersService.activeDossier$
+ .pipe(
+ filter(dossier => !!dossier),
+ first()
+ )
+ .toPromise();
+ return await this.activateFile(dossierId, fileId);
}
+
+ this._appState.activeFileId = undefined;
});
}
- private _dictionaryData: { [key: string]: { [key: string]: TypeValue } } = null;
+ private _dictionaryData?: { [key: string]: { [key: string]: TypeValue } };
- get dictionaryData(): { [key: string]: { [key: string]: TypeValue } } {
+ get dictionaryData(): { [key: string]: { [key: string]: TypeValue } } | undefined {
return this._dictionaryData;
}
- get aggregatedFiles(): File[] {
- return this.allDossiers.reduce((acc, { files }) => [...acc, ...files], []);
- }
-
- get activeDossierTemplateId(): string {
+ get activeDossierTemplateId(): string | undefined {
return this._appState.activeDossierTemplateId;
}
- get activeDossierTemplate(): DossierTemplate {
+ get activeDossierTemplate(): DossierTemplate | undefined {
return this.getDossierTemplateById(this.activeDossierTemplateId);
}
@@ -101,95 +87,65 @@ export class AppStateService {
return this._appState.dossierTemplates;
}
- get activeDictionaryType(): string {
+ get activeDictionaryType(): string | undefined {
return this._appState.activeDictionaryType;
}
- get activeDictionary(): TypeValue {
- return this.activeDossierTemplateId && this.dictionaryData[this.activeDossierTemplateId]
+ get activeDictionary(): TypeValue | undefined {
+ return this.activeDossierTemplateId &&
+ this.activeDictionaryType &&
+ this.dictionaryData &&
+ this.dictionaryData[this.activeDossierTemplateId]
? this.dictionaryData[this.activeDossierTemplateId][this.activeDictionaryType]
- : null;
- }
-
- get activeDossierId(): string {
- return this._appState.activeDossierId;
- }
-
- get activeDossier(): Dossier | undefined {
- return this.allDossiers.find(p => p.id === this.activeDossierId);
- }
-
- get allDossiers(): Dossier[] {
- return this._appState.dossiers;
- }
-
- get hasDossiers() {
- return this.allDossiers?.length > 0;
+ : undefined;
}
get activeFile(): File | undefined {
- return this.activeDossier?.files.find(f => f.fileId === this.activeFileId);
+ return this._dossiersService.activeDossier?.files.find(f => f.fileId === this.activeFileId);
}
- get activeFileId(): string {
+ get activeFileId(): string | undefined {
return this._appState.activeFileId;
}
- get totalAnalysedPages(): number {
- return this._appState.totalAnalysedPages;
- }
-
- get totalPeople(): number {
- return this._appState.totalPeople;
- }
-
private static _isFileOverviewRoute(event: Event) {
return event instanceof ResolveStart && event.url.includes('/main/dossiers/') && event.url.includes('/file/');
}
- private static _isDossierOverviewRoute(event: Event) {
- return (
- event instanceof ResolveStart &&
- event.url.includes('/main/dossiers/') &&
- !event.url.includes('/file/') &&
- !event.url.includes('/search')
- );
- }
-
- private static _isRandomRoute(event: Event) {
- return event instanceof NavigationEnd && !event.url.includes('/main/dossiers/') && !event.url.includes('/file/');
- }
-
async reloadActiveDossierFilesIfNecessary() {
- if (this.activeDossier?.hasPendingOrProcessing) {
+ if (this._dossiersService.activeDossier?.hasPendingOrProcessing) {
await this.reloadActiveDossierFiles();
}
}
- getDictionaryColor(type?: string, dossierTemplateId = this.activeDossier?.dossierTemplateId) {
+ getDictionaryColor(type?: string, dossierTemplateId = this._dossiersService.activeDossier?.dossierTemplateId) {
if (!dossierTemplateId) {
dossierTemplateId = this.dossierTemplates[0]?.dossierTemplateId;
}
- if (!dossierTemplateId) {
+
+ if (!dossierTemplateId || !this._dictionaryData) {
return '#cccccc';
}
- const color = this._dictionaryData[dossierTemplateId][type]?.hexColor;
+
+ let color;
+ if (type) {
+ color = this._dictionaryData[dossierTemplateId][type]?.hexColor;
+ }
return color ?? this._dictionaryData[dossierTemplateId]['default'].hexColor;
}
- getDossierTemplateById(id: string): DossierTemplate {
+ getDossierTemplateById(id?: string): DossierTemplate | undefined {
+ if (!id) {
+ return undefined;
+ }
return this.dossierTemplates.find(rs => rs.dossierTemplateId === id);
}
- getDictionaryTypeValue(key: string, dossierTemplateId?: string): TypeValue {
- if (!dossierTemplateId && this.activeDossier) {
- dossierTemplateId = this.activeDossier.dossierTemplateId;
- }
-
+ getDictionaryTypeValue(key: string, dossierTemplateId = this._dossiersService.activeDossier.dossierTemplateId): TypeValue | undefined {
if (!dossierTemplateId) {
dossierTemplateId = this.dossierTemplates.length > 0 ? this.dossierTemplates[0].dossierTemplateId : undefined;
}
- if (!dossierTemplateId) {
+ if (!dossierTemplateId || !this._dictionaryData) {
return undefined;
}
@@ -197,49 +153,43 @@ export class AppStateService {
return data ? data : this._dictionaryData[dossierTemplateId]['default'];
}
- getDossierById(id: string) {
- return this.allDossiers.find(dossier => dossier.id === id);
- }
-
- getFileById(dossierId: string, fileId: string) {
- return this.getDossierById(dossierId)?.files.find(file => file.fileId === fileId);
- }
-
- async loadAllDossiers(emitEvents: boolean = true) {
+ async loadAllDossiers(emitEvents = true) {
const dossiers = await this._dossiersService.get().toPromise();
if (!dossiers) {
return;
}
- const mappedDossiers = dossiers.map(p => new Dossier(p, this._getExistingFiles(p.dossierId)));
+ const getFiles = (dossierId: string) => this._dossiersService.find(dossierId)?.files ?? [];
+ const mappedDossiers = dossiers.map(p => new Dossier(p, getFiles(p.dossierId)));
const fileData = await this._filesService.getFor(mappedDossiers.map(p => p.id)).toPromise();
for (const dossierId of Object.keys(fileData)) {
const dossier = mappedDossiers.find(p => p.id === dossierId);
- this._processFiles(dossier, fileData[dossierId], emitEvents);
+ if (dossier) {
+ this._processFiles(dossier, fileData[dossierId], emitEvents);
+ }
}
-
- this._appState.dossiers = mappedDossiers;
- this._computeStats();
}
async reloadActiveFile() {
- if (!this.activeFile) {
+ const activeDossier = this._dossiersService.activeDossier;
+
+ if (!this.activeFile || !activeDossier) {
return null;
}
const oldProcessedDate = this.activeFile.lastProcessed;
- const dossierTemplateId = this.activeFile.dossierTemplateId;
- const iFile = await this._filesService.get(this.activeDossierId, this.activeFileId).toPromise();
- iFile.dossierTemplateId = dossierTemplateId;
+ const iFile = await this._filesService.get(activeDossier.dossierId, this.activeFileId).toPromise();
const activeFile = new File(
iFile,
this._userService.getNameForId(iFile.currentReviewer),
- this._fileAttributesService.getFileAttributeConfig(iFile.dossierTemplateId)
+ this._fileAttributesService.getFileAttributeConfig(activeDossier.dossierTemplateId)
);
- this.activeDossier.files = this.activeDossier?.files.map(file => (file.fileId === activeFile.fileId ? activeFile : file));
+ const files = activeDossier.files.filter(file => file.fileId !== activeFile.fileId);
+ files.push(activeFile);
+ const newDossier = new Dossier(activeDossier, files);
+ this._dossiersService.replace(newDossier);
- this._computeStats();
if (activeFile.lastProcessed !== oldProcessedDate) {
this.fileReanalysed$.next(activeFile);
}
@@ -247,48 +197,25 @@ export class AppStateService {
return activeFile;
}
- async getFiles(dossier: Dossier = this.activeDossier, emitEvents = true) {
+ async getFiles(dossier = this._dossiersService.activeDossier, emitEvents = true) {
const files = await this._filesService.getFor(dossier.id).toPromise();
return this._processFiles(dossier, files, emitEvents);
}
- async reanalyzeDossier({ id }: Dossier = this.activeDossier) {
+ async reanalyzeDossier({ id } = this._dossiersService.activeDossier) {
await this._reanalysisControllerService.reanalyzeDossier(id, true).toPromise();
}
- async activateDossier(dossierId: string) {
- this._appState.activeFileId = null;
- this._appState.activeDossierId = dossierId;
- if (!this.activeDossier) {
- this._appState.activeDossierId = null;
- await this._router.navigate(['/main/dossiers']);
- return;
- }
-
- this.updateDossierDictionary(this.activeDossier.dossierTemplateId, dossierId);
- }
-
- async updateDossierDictionary(dossierTemplateId: string, dossierId: string) {
- // dossier exists, load its dictionary
- const dossier = this.getDossierById(dossierId);
- try {
- dossier.type = await this._dictionaryService.getFor(dossierTemplateId, 'dossier_redaction', dossierId).toPromise();
- } catch (e) {
- dossier.type = null;
- }
- }
-
async activateFile(dossierId: string, fileId: string) {
- if (this.activeDossierId === dossierId && this.activeFileId === fileId) {
+ if (this._dossiersService.activeDossierId === dossierId && this.activeFileId === fileId) {
return;
}
- await this.activateDossier(dossierId);
- if (this.activeDossier) {
+ if (this._dossiersService.activeDossier) {
this._appState.activeFileId = fileId;
if (!this.activeFile) {
this._appState.activeFileId = null;
- await this._router.navigate(['/main/dossiers/' + dossierId]);
+ await this._dossiersService.goToActiveDossier();
}
}
await this._updateLastActiveFileForDossier(dossierId, fileId);
@@ -316,47 +243,12 @@ export class AppStateService {
reset() {
this._appState.activeFileId = null;
- this._appState.activeDossierId = null;
this._appState.activeDossierTemplateId = null;
this._appState.activeDictionaryType = null;
}
- deleteDossier(dossier: Dossier) {
- return this._dossiersService
- .delete(dossier.id)
- .toPromise()
- .then(
- () => {
- const index = this.allDossiers.findIndex(p => p.id === dossier.id);
- this._appState.dossiers.splice(index, 1);
- },
- () => this._toaster.error(_('dossier-listing.delete.delete-failed'), { params: dossier })
- );
- }
-
- async createOrUpdateDossier(dossier: IDossier) {
- try {
- const updatedDossier = await this._dossiersService.createOrUpdate(dossier);
- let foundDossier = this.allDossiers.find(p => p.id === updatedDossier.dossierId);
- if (foundDossier) {
- this._appState.dossiers.splice(this._appState.dossiers.indexOf(foundDossier), 1);
- foundDossier = new Dossier(updatedDossier, foundDossier.files);
- } else {
- foundDossier = new Dossier(updatedDossier, []);
- }
-
- this._appState.dossiers.push(foundDossier);
- this.dossierChanged$.next(foundDossier);
- return foundDossier;
- } catch (error) {
- this._toaster.error(
- error.status === 409 ? _('add-dossier-dialog.errors.dossier-already-exists') : _('add-dossier-dialog.errors.generic')
- );
- }
- }
-
async reloadActiveDossierFiles() {
- if (this.activeDossierId) {
+ if (this._dossiersService.activeDossierId) {
await this.getFiles();
}
}
@@ -391,7 +283,7 @@ export class AppStateService {
}
async loadAllDossiersIfNecessary() {
- if (!this.allDossiers.length) {
+ if (!this._dossiersService.all.length) {
await this.loadAllDossiers();
}
}
@@ -407,7 +299,7 @@ export class AppStateService {
async loadDictionaryData(): Promise {
const observables = [];
for (const dossierTemplate of this.dossierTemplates) {
- observables.push(this._getDictionaryDataForDossierTemplateObservables(dossierTemplate.dossierTemplateId));
+ observables.push(this._getDictionaryDataForDossierTemplate$(dossierTemplate.dossierTemplateId));
}
const result = await forkJoin(observables).toPromise();
@@ -420,7 +312,7 @@ export class AppStateService {
}
async refreshDossierTemplateDictionaryData(dossierTemplateId: string) {
- this._dictionaryData[dossierTemplateId] = await this._getDictionaryDataForDossierTemplateObservables(dossierTemplateId).toPromise();
+ this._dictionaryData[dossierTemplateId] = await this._getDictionaryDataForDossierTemplate$(dossierTemplateId).toPromise();
}
loadColors(dossierTemplateId: string) {
@@ -442,7 +334,7 @@ export class AppStateService {
);
}
- private _getDictionaryDataForDossierTemplateObservables(dossierTemplateId: string): Observable<{ [key: string]: any }> {
+ private _getDictionaryDataForDossierTemplate$(dossierTemplateId: string): Observable<{ [key: string]: any }> {
const dictionaryData: { [key: string]: any } = {};
const typeObs = this._dictionaryService.getAllTypes(dossierTemplateId).pipe(
@@ -650,96 +542,50 @@ export class AppStateService {
})
);
- console.log(dictionaryData);
-
return forkJoin([typeObs, colorsObs]).pipe(map(() => dictionaryData));
}
private async _updateLastActiveFileForDossier(dossierId: string, fileId: string) {
- this.activeDossier.files.forEach(f => {
+ this._dossiersService.activeDossier.files.forEach(f => {
f.lastOpened = f.fileId === fileId;
});
await this._userPreferenceService.saveLastOpenedFileForDossier(dossierId, fileId);
}
- private _getExistingFiles(dossierId: string): File[] {
- const dossier = this.allDossiers.find(p => p.id === dossierId);
- return dossier?.files ?? [];
- }
-
private _processFiles(dossier: Dossier, iFiles: IFile[], emitEvents = true) {
const oldFiles = [...dossier.files];
+ const fileAttributes = this._fileAttributesService.getFileAttributeConfig(dossier.dossierTemplateId);
+ const newFiles = iFiles.map(iFile => new File(iFile, this._userService.getNameForId(iFile.currentReviewer), fileAttributes));
- const fileChangedEvent: File[] = [];
- const fileReanalysedEvent: File[] = [];
+ const lastOpenedFileId = this._userPreferenceService.getLastOpenedFileForDossier(dossier.id);
+ newFiles.forEach(file => (file.lastOpened = file.fileId === lastOpenedFileId));
- for (const iFile of iFiles) {
+ for (const newFile of newFiles) {
let found = false;
- iFile.dossierTemplateId = dossier.dossierTemplateId;
for (const oldFile of oldFiles) {
- if (oldFile.fileId === iFile.fileId) {
+ if (oldFile.fileId === newFile.fileId) {
// emit when analysis count changed
- const file = new File(
- iFile,
- this._userService.getNameForId(iFile.currentReviewer),
- this._fileAttributesService.getFileAttributeConfig(iFile.dossierTemplateId)
- );
- file.lastOpened = file.fileId === this._userPreferenceService.getLastOpenedFileForDossier(dossier.id);
- if (JSON.stringify(oldFile) !== JSON.stringify(file)) {
- fileChangedEvent.push(file);
+ if (JSON.stringify(oldFile) !== JSON.stringify(newFile) && emitEvents) {
+ this.fileChanged$.next(newFile);
}
- if (oldFile.lastProcessed !== iFile.lastProcessed) {
- fileReanalysedEvent.push(file);
+ if (oldFile.lastProcessed !== newFile.lastProcessed && emitEvents) {
+ this.fileReanalysed$.next(newFile);
}
found = true;
break;
}
}
// emit for new file
- if (!found) {
- const file = new File(
- iFile,
- this._userService.getNameForId(iFile.currentReviewer),
- this._fileAttributesService.getFileAttributeConfig(iFile.dossierTemplateId)
- );
- fileChangedEvent.push(file);
+ if (!found && emitEvents) {
+ this.fileChanged$.next(newFile);
}
}
- dossier.files = iFiles.map(
- iFile =>
- new File(
- iFile,
- this._userService.getNameForId(iFile.currentReviewer),
- this._fileAttributesService.getFileAttributeConfig(iFile.dossierTemplateId)
- )
- );
- this._computeStats();
+ const newDossier = new Dossier(dossier, newFiles);
+ this._dossiersService.replace(newDossier);
- if (emitEvents) {
- fileReanalysedEvent.forEach(file => this.fileReanalysed$.next(file));
- fileChangedEvent.forEach(file => this.fileChanged$.next(file));
- }
-
- const lastOpenedFileId = this._userPreferenceService.getLastOpenedFileForDossier(dossier.id);
-
- dossier.files.forEach(file => (file.lastOpened = file.fileId === lastOpenedFileId));
-
- return iFiles;
- }
-
- private _computeStats() {
- let totalAnalysedPages = 0;
- const totalPeople = new Set();
-
- this.allDossiers.forEach(d => {
- d.memberIds?.forEach(m => totalPeople.add(m));
- totalAnalysedPages += d.totalNumberOfPages;
- });
-
- this._appState.totalPeople = totalPeople.size;
- this._appState.totalAnalysedPages = totalAnalysedPages;
+ return newFiles;
}
}
diff --git a/apps/red-ui/src/app/state/model/dossier-attribute-config.ts b/apps/red-ui/src/app/state/model/dossier-attribute-config.ts
index 28da877ca..087c3081b 100644
--- a/apps/red-ui/src/app/state/model/dossier-attribute-config.ts
+++ b/apps/red-ui/src/app/state/model/dossier-attribute-config.ts
@@ -4,9 +4,10 @@ import { IListable } from '@iqser/common-ui';
export class DossierAttributeConfig implements IDossierAttributeConfig, IListable {
readonly id: string;
readonly editable: boolean;
- readonly label?: string;
+ readonly label: string;
readonly placeholder?: string;
readonly type?: DossierAttributeConfigType;
+ readonly dossierTemplateId: string;
constructor(dossierAttributeConfig: IDossierAttributeConfig) {
this.id = dossierAttributeConfig.id;
@@ -14,6 +15,7 @@ export class DossierAttributeConfig implements IDossierAttributeConfig, IListabl
this.label = dossierAttributeConfig.label;
this.placeholder = dossierAttributeConfig.placeholder;
this.type = dossierAttributeConfig.type;
+ this.dossierTemplateId = dossierAttributeConfig.dossierTemplateId;
}
get searchKey(): string {
diff --git a/apps/red-ui/src/app/state/model/dossier.ts b/apps/red-ui/src/app/state/model/dossier.ts
index 6e2ec7389..34acc5b0b 100644
--- a/apps/red-ui/src/app/state/model/dossier.ts
+++ b/apps/red-ui/src/app/state/model/dossier.ts
@@ -4,38 +4,37 @@ import { IListable } from '@iqser/common-ui';
export class Dossier implements IDossier, IListable {
readonly dossierId: string;
- readonly ownerId: string;
- readonly memberIds: List;
- readonly approverIds: List;
- readonly reportTemplateIds: List;
readonly dossierTemplateId: string;
+ readonly ownerId: string;
+ readonly memberIds?: List;
+ readonly approverIds?: List;
+ readonly reportTemplateIds?: List;
readonly dossierName: string;
- readonly date: string;
- readonly description: string;
- readonly downloadFileTypes: List;
- readonly dueDate: string;
- readonly hardDeletedTime: string;
- readonly reportTypes: List;
- readonly softDeletedTime: string;
- readonly status: DossierStatus;
+ readonly date?: string;
+ readonly dueDate?: string;
+ readonly description?: string;
+ readonly downloadFileTypes?: List;
+ readonly hardDeletedTime?: string;
+ readonly reportTypes?: List;
+ readonly softDeletedTime?: string;
+ readonly status?: DossierStatus;
readonly watermarkEnabled: boolean;
readonly hasReviewers: boolean;
- reanalysisRequired = this._files.some(file => file.analysisRequired);
- hasFiles = this._files.length > 0;
- filesLength = this._files.length;
+ readonly reanalysisRequired = this.files.some(file => file.analysisRequired);
+ readonly hasFiles = this.files.length > 0;
+ readonly filesLength = this.files.length;
- totalNumberOfPages?: number;
- hintsOnly?: boolean;
- hasRedactions?: boolean;
- hasSuggestions?: boolean;
- hasNone?: boolean;
- hasPendingOrProcessing?: boolean;
+ readonly totalNumberOfPages: number;
+ readonly hintsOnly: boolean;
+ readonly hasRedactions: boolean;
+ readonly hasSuggestions: boolean;
+ readonly hasNone: boolean;
+ readonly hasPendingOrProcessing: boolean;
- allFilesApproved?: boolean;
type?: IDictionary;
- constructor(dossier: IDossier, private _files: File[] = []) {
+ constructor(dossier: IDossier, readonly files: List = []) {
this.dossierId = dossier.dossierId;
this.approverIds = dossier.approverIds;
this.date = dossier.date;
@@ -51,10 +50,29 @@ export class Dossier implements IDossier, IListable {
this.reportTypes = dossier.reportTypes;
this.softDeletedTime = dossier.softDeletedTime;
this.status = dossier.status;
- this.watermarkEnabled = dossier.watermarkEnabled;
- this.hasReviewers = this.memberIds.length > 1;
+ this.watermarkEnabled = !!dossier.watermarkEnabled;
+ this.hasReviewers = !!this.memberIds && this.memberIds.length > 1;
- this._recomputeFileStatus();
+ let hintsOnly = false;
+ let hasRedactions = false;
+ let hasSuggestions = false;
+ let totalNumberOfPages = 0;
+ let hasPendingOrProcessing = false;
+
+ this.files.forEach(f => {
+ hintsOnly = hintsOnly || f.hintsOnly;
+ hasRedactions = hasRedactions || f.hasRedactions;
+ hasSuggestions = hasSuggestions || f.hasSuggestions;
+ totalNumberOfPages += f.numberOfPages ?? 0;
+ hasPendingOrProcessing = hasPendingOrProcessing || f.isPending || f.isProcessing;
+ });
+
+ this.hintsOnly = hintsOnly;
+ this.hasRedactions = hasRedactions;
+ this.hasSuggestions = hasSuggestions;
+ this.totalNumberOfPages = totalNumberOfPages;
+ this.hasPendingOrProcessing = hasPendingOrProcessing;
+ this.hasNone = !this.hasSuggestions && !this.hasRedactions && !this.hintsOnly;
}
get id(): string {
@@ -69,42 +87,11 @@ export class Dossier implements IDossier, IListable {
return this.dossierName;
}
- get files(): File[] {
- return this._files;
- }
-
- set files(files: File[]) {
- this._files = files ? files : [];
- this._recomputeFileStatus();
- }
-
hasStatus(status: string): boolean {
- return !!this._files.find(f => f.status === status);
+ return !!this.files.find(f => f.status === status);
}
hasMember(memberId: string): boolean {
- return this.memberIds.indexOf(memberId) >= 0;
- }
-
- private _recomputeFileStatus() {
- this.hintsOnly = false;
- this.hasRedactions = false;
- this.hasSuggestions = false;
- this.hasNone = false;
- this.allFilesApproved = true;
- this.totalNumberOfPages = 0;
- this.hasPendingOrProcessing = false;
- this._files.forEach(f => {
- this.hintsOnly = this.hintsOnly || f.hintsOnly;
- this.hasRedactions = this.hasRedactions || f.hasRedactions;
- this.hasSuggestions = this.hasSuggestions || f.hasSuggestions;
- this.allFilesApproved = this.allFilesApproved && f.isApproved;
- this.totalNumberOfPages += f.numberOfPages;
- this.hasPendingOrProcessing = this.hasPendingOrProcessing || f.isPending || f.isProcessing;
- });
- this.hasNone = !this.hasSuggestions && !this.hasRedactions && !this.hintsOnly;
- this.hasFiles = this._files.length > 0;
- this.filesLength = this._files.length;
- this.reanalysisRequired = this._files.some(file => file.analysisRequired);
+ return !!this.memberIds && this.memberIds.indexOf(memberId) >= 0;
}
}
diff --git a/apps/red-ui/src/app/state/model/dossier.wrapper.ts b/apps/red-ui/src/app/state/model/dossier.wrapper.ts
deleted file mode 100644
index e69de29bb..000000000
diff --git a/apps/red-ui/src/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts
index 76285fc64..28d8757e9 100644
--- a/apps/red-ui/src/app/utils/functions.ts
+++ b/apps/red-ui/src/app/utils/functions.ts
@@ -1,8 +1,9 @@
import * as moment from 'moment';
+import { List } from '@iqser/common-ui';
export const FALLBACK_COLOR = '#CCCCCC';
-export function groupBy(xs: any[], key: string) {
+export function groupBy(xs: List, key: string) {
return xs.reduce((rv, x) => {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
diff --git a/libs/red-ui-http/src/lib/model/audit.ts b/libs/red-ui-http/src/lib/model/audit.ts
index 940f7eb76..2a94b2242 100644
--- a/libs/red-ui-http/src/lib/model/audit.ts
+++ b/libs/red-ui-http/src/lib/model/audit.ts
@@ -15,7 +15,7 @@ export interface IAudit {
readonly details?: unknown;
readonly message?: string;
readonly objectId?: string;
- readonly recordDate?: string;
+ readonly recordDate: string;
readonly recordId?: number;
readonly userId?: string;
}
diff --git a/libs/red-ui-http/src/lib/model/dictionary.ts b/libs/red-ui-http/src/lib/model/dictionary.ts
index 5bfd45658..0754fb732 100644
--- a/libs/red-ui-http/src/lib/model/dictionary.ts
+++ b/libs/red-ui-http/src/lib/model/dictionary.ts
@@ -47,7 +47,7 @@ export interface IDictionary {
/**
* Label of the type
*/
- readonly label?: string;
+ readonly label: string;
/**
* The rank of this dictionary, higher rank means higher importance.
*/
diff --git a/libs/red-ui-http/src/lib/model/dossier.ts b/libs/red-ui-http/src/lib/model/dossier.ts
index f87e6224b..0e48a239c 100644
--- a/libs/red-ui-http/src/lib/model/dossier.ts
+++ b/libs/red-ui-http/src/lib/model/dossier.ts
@@ -12,17 +12,17 @@
import { List } from '../red-types';
export interface IDossier {
+ readonly dossierId: string;
+ readonly dossierName: string;
+ readonly dossierTemplateId: string;
readonly approverIds?: List;
readonly date?: string;
readonly description?: string;
- readonly dossierId?: string;
- readonly dossierName?: string;
- readonly dossierTemplateId?: string;
readonly downloadFileTypes?: List;
readonly dueDate?: string;
readonly hardDeletedTime?: string;
readonly memberIds?: List;
- readonly ownerId?: string;
+ readonly ownerId: string;
readonly reportTemplateIds?: List;
readonly reportTypes?: List;
readonly softDeletedTime?: string;
diff --git a/libs/red-ui-http/src/lib/model/dossierAttributeConfig.ts b/libs/red-ui-http/src/lib/model/dossierAttributeConfig.ts
index ba1173cad..d41f90b65 100644
--- a/libs/red-ui-http/src/lib/model/dossierAttributeConfig.ts
+++ b/libs/red-ui-http/src/lib/model/dossierAttributeConfig.ts
@@ -13,9 +13,9 @@
export interface IDossierAttributeConfig {
readonly id: string;
readonly editable?: boolean;
- readonly label?: string;
+ readonly label: string;
readonly placeholder?: string;
- readonly dossierTemplateId?: string;
+ readonly dossierTemplateId: string;
readonly type?: DossierAttributeConfigType;
}
diff --git a/libs/red-ui-http/src/lib/model/file.ts b/libs/red-ui-http/src/lib/model/file.ts
index 1d5212519..05093c593 100644
--- a/libs/red-ui-http/src/lib/model/file.ts
+++ b/libs/red-ui-http/src/lib/model/file.ts
@@ -9,7 +9,7 @@
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
-import { FileAttributes } from './fileAttributes';
+import { FileAttributes } from "./fileAttributes";
/**
* Object containing information on a specific file.
@@ -50,11 +50,7 @@ export interface IFile {
/**
* The ID of the dossier the file belongs to.
*/
- readonly dossierId?: string;
- /**
- * The dossierTemplateId for this file.
- */
- dossierTemplateId?: string;
+ readonly dossierId: string;
/**
* Shows if the file was excluded from analysis.
*/
@@ -67,11 +63,11 @@ export interface IFile {
/**
* The ID of the file.
*/
- readonly fileId?: string;
+ readonly fileId: string;
/**
* The file's name.
*/
- readonly filename?: string;
+ readonly filename: string;
/**
* Shows if this file has comments on annotations.
*/
@@ -147,7 +143,7 @@ export interface IFile {
/**
* The status of the file with regard to its analysis an review processes.
*/
- readonly status?: FileStatus;
+ readonly status: FileStatus;
/**
* The ID of the user who uploaded the file.
*/
diff --git a/libs/red-ui-http/src/lib/model/user.ts b/libs/red-ui-http/src/lib/model/user.ts
index 12c831294..c51160c70 100644
--- a/libs/red-ui-http/src/lib/model/user.ts
+++ b/libs/red-ui-http/src/lib/model/user.ts
@@ -17,7 +17,7 @@ export interface IUser {
/**
* Email of user.
*/
- readonly email?: string;
+ readonly email: string;
/**
* First name of user.
*/