Edit dossier attributes WIP

This commit is contained in:
Adina Țeudan 2021-07-14 16:32:37 +03:00
parent e3beeae0e3
commit efa4e76f62
48 changed files with 527 additions and 871 deletions

View File

@ -4,7 +4,7 @@ import { AppStateService } from '@state/app-state.service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../services/admin-dialog.service';
import { DossierTemplateControllerService } from '@redaction/red-ui-http'; import { DossierTemplateControllerService } from '@redaction/red-ui-http';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
@Component({ @Component({
selector: 'redaction-dossier-template-actions', selector: 'redaction-dossier-template-actions',
@ -33,22 +33,15 @@ export class DossierTemplateActionsComponent {
} }
openEditDossierTemplateDialog($event: any) { openEditDossierTemplateDialog($event: any) {
this._dialogService.openDialog( this._dialogService.openDialog('addEditDossierTemplate', $event, this.dossierTemplate, () => {
'addEditDossierTemplate', this.loadDossierTemplatesData?.emit();
$event, });
this.dossierTemplate,
() => {
this.loadDossierTemplatesData?.emit();
}
);
} }
openDeleteDossierTemplateDialog($event?: MouseEvent) { openDeleteDossierTemplateDialog($event?: MouseEvent) {
this._dialogService.openDialog('confirm', $event, null, async () => { this._dialogService.openDialog('confirm', $event, null, async () => {
this._loadingService.start(); this._loadingService.start();
await this._dossierTemplateControllerService await this._dossierTemplateControllerService.deleteDossierTemplates([this.dossierTemplateId]).toPromise();
.deleteDossierTemplates([this.dossierTemplateId])
.toPromise();
await this._appStateService.loadAllDossierTemplates(); await this._appStateService.loadAllDossierTemplates();
await this._appStateService.loadDictionaryData(); await this._appStateService.loadDictionaryData();
await this._router.navigate(['main', 'admin']); await this._router.navigate(['main', 'admin']);

View File

@ -5,7 +5,7 @@ import { DictionaryControllerService, TypeValue } from '@redaction/red-ui-http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { NotificationService, NotificationType } from '@services/notification.service'; import { NotificationService, NotificationType } from '@services/notification.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { TypeValueWrapper } from '../../../../models/file/type-value.wrapper'; import { TypeValueWrapper } from '@models/file/type-value.wrapper';
import { humanize } from '../../../../utils/functions'; import { humanize } from '../../../../utils/functions';
@Component({ @Component({
@ -78,11 +78,7 @@ export class AddEditDictionaryDialogComponent {
if (this.dictionary) { if (this.dictionary) {
// edit mode // edit mode
observable = this._dictionaryControllerService.updateType( observable = this._dictionaryControllerService.updateType(typeValue, this._dossierTemplateId, typeValue.type);
typeValue,
this._dossierTemplateId,
typeValue.type
);
} else { } else {
// create mode // create mode
typeValue.dossierTemplateId = this._dossierTemplateId; typeValue.dossierTemplateId = this._dossierTemplateId;
@ -104,11 +100,7 @@ export class AddEditDictionaryDialogComponent {
} }
private _notifyError(message: string) { private _notifyError(message: string) {
this._notificationService.showToastNotification( this._notificationService.showToastNotification(this._translateService.instant(message), null, NotificationType.ERROR);
this._translateService.instant(message),
null,
NotificationType.ERROR
);
} }
private _formToObject(): TypeValue { private _formToObject(): TypeValue {

View File

@ -1,11 +1,11 @@
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { DossierAttributeConfig, DossierAttributesControllerService, FileAttributeConfig } from '@redaction/red-ui-http'; import { DossierAttributeConfig, DossierAttributesControllerService, FileAttributeConfig } from '@redaction/red-ui-http';
import { AppStateService } from '../../../../state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
import { ErrorMessageService } from '../../../../services/error-message.service'; import { ErrorMessageService } from '@services/error-message.service';
import { NotificationService, NotificationType } from '../../../../services/notification.service'; import { NotificationService, NotificationType } from '@services/notification.service';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
@Component({ @Component({

View File

@ -1,8 +1,8 @@
import { Component, EventEmitter, Input, Output } from '@angular/core'; import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { User, UserControllerService } from '@redaction/red-ui-http'; import { User, UserControllerService } from '@redaction/red-ui-http';
import { UserService } from '../../../../../services/user.service'; import { UserService } from '@services/user.service';
import { LoadingService } from '../../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
@Component({ @Component({
selector: 'redaction-reset-password', selector: 'redaction-reset-password',

View File

@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { User, UserControllerService } from '@redaction/red-ui-http'; import { User, UserControllerService } from '@redaction/red-ui-http';
import { AdminDialogService } from '../../../services/admin-dialog.service'; import { AdminDialogService } from '../../../services/admin-dialog.service';
import { LoadingService } from '../../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
@Component({ @Component({
selector: 'redaction-user-details', selector: 'redaction-user-details',
@ -64,10 +64,7 @@ export class UserDetailsComponent implements OnInit {
disabled: disabled:
this.user && this.user &&
Object.keys(this._ROLE_REQUIREMENTS).reduce( Object.keys(this._ROLE_REQUIREMENTS).reduce(
(value, key) => (value, key) => value || (role === this._ROLE_REQUIREMENTS[key] && this.user.roles.indexOf(key) !== -1),
value ||
(role === this._ROLE_REQUIREMENTS[key] &&
this.user.roles.indexOf(key) !== -1),
false false
) )
} }
@ -79,7 +76,10 @@ export class UserDetailsComponent implements OnInit {
firstName: [this.user?.firstName, Validators.required], firstName: [this.user?.firstName, Validators.required],
lastName: [this.user?.lastName, Validators.required], lastName: [this.user?.lastName, Validators.required],
email: [ email: [
{ value: this.user?.email, disabled: !!this.user }, {
value: this.user?.email,
disabled: !!this.user
},
[Validators.required, Validators.email] [Validators.required, Validators.email]
], ],
...rolesControls ...rolesControls

View File

@ -2,7 +2,7 @@ import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { User, UserControllerService } from '@redaction/red-ui-http'; import { User, UserControllerService } from '@redaction/red-ui-http';
import { AppStateService } from '@state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
@Component({ @Component({
selector: 'redaction-confirm-delete-users-dialog', selector: 'redaction-confirm-delete-users-dialog',
@ -45,9 +45,7 @@ export class ConfirmDeleteUsersDialogComponent {
async deleteUser() { async deleteUser() {
if (this.valid) { if (this.valid) {
this._loadingService.start(); this._loadingService.start();
await this._userControllerService await this._userControllerService.deleteUsers(this.users.map(u => u.userId)).toPromise();
.deleteUsers(this.users.map(u => u.userId))
.toPromise();
this.dialogRef.close(true); this.dialogRef.close(true);
} else { } else {
this.showToast = true; this.showToast = true;

View File

@ -1,19 +1,11 @@
import { import { Component, EventEmitter, Injector, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
Component,
EventEmitter,
Injector,
Input,
OnChanges,
Output,
SimpleChanges
} from '@angular/core';
import { Field } from '../file-attributes-csv-import-dialog.component'; import { Field } from '../file-attributes-csv-import-dialog.component';
import { FileAttributeConfig } from '@redaction/red-ui-http'; import { FileAttributeConfig } from '@redaction/red-ui-http';
import { FilterService } from '../../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { SortingService } from '../../../../../services/sorting.service'; import { SortingService } from '../../../../../services/sorting.service';
import { BaseListingComponent } from '../../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
@Component({ @Component({
selector: 'redaction-active-fields-listing', selector: 'redaction-active-fields-listing',
@ -27,11 +19,7 @@ export class ActiveFieldsListingComponent extends BaseListingComponent<Field> im
@Output() setHoveredColumn = new EventEmitter<string>(); @Output() setHoveredColumn = new EventEmitter<string>();
@Output() toggleFieldActive = new EventEmitter<Field>(); @Output() toggleFieldActive = new EventEmitter<Field>();
readonly typeOptions = [ readonly typeOptions = [FileAttributeConfig.TypeEnum.TEXT, FileAttributeConfig.TypeEnum.NUMBER, FileAttributeConfig.TypeEnum.DATE];
FileAttributeConfig.TypeEnum.TEXT,
FileAttributeConfig.TypeEnum.NUMBER,
FileAttributeConfig.TypeEnum.DATE
];
constructor(protected readonly _injector: Injector) { constructor(protected readonly _injector: Injector) {
super(_injector); super(_injector);
@ -47,12 +35,8 @@ export class ActiveFieldsListingComponent extends BaseListingComponent<Field> im
} }
deactivateSelection() { deactivateSelection() {
this.allEntities this.allEntities.filter(field => this.isSelected(field)).forEach(field => (field.primaryAttribute = false));
.filter(field => this.isSelected(field)) this._screenStateService.setEntities([...this.allEntities.filter(field => !this.isSelected(field))]);
.forEach(field => (field.primaryAttribute = false));
this._screenStateService.setEntities([
...this.allEntities.filter(field => !this.isSelected(field))
]);
this.entitiesChange.emit(this.allEntities); this.entitiesChange.emit(this.allEntities);
this._screenStateService.setSelectedEntitiesIds([]); this._screenStateService.setSelectedEntitiesIds([]);
} }

View File

@ -3,20 +3,16 @@ import { AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators } from
import { AppStateService } from '@state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import * as Papa from 'papaparse'; import * as Papa from 'papaparse';
import { import { FileAttributeConfig, FileAttributesConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
FileAttributeConfig,
FileAttributesConfig,
FileAttributesControllerService
} from '@redaction/red-ui-http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators'; import { map, startWith } from 'rxjs/operators';
import { NotificationService, NotificationType } from '@services/notification.service'; import { NotificationService, NotificationType } from '@services/notification.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { SortingService } from '../../../../services/sorting.service'; import { SortingService } from '../../../../services/sorting.service';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
export interface Field { export interface Field {
id?: string; id?: string;
@ -70,10 +66,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
this.dossierTemplateId = data.dossierTemplateId; this.dossierTemplateId = data.dossierTemplateId;
this.baseConfigForm = this._formBuilder.group({ this.baseConfigForm = this._formBuilder.group({
filenameMappingColumnHeaderName: [ filenameMappingColumnHeaderName: ['', [Validators.required, this._autocompleteStringValidator()]],
'',
[Validators.required, this._autocompleteStringValidator()]
],
delimiter: [undefined, Validators.required], delimiter: [undefined, Validators.required],
encoding: ['UTF-8', Validators.required] encoding: ['UTF-8', Validators.required]
}); });
@ -103,16 +96,12 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
this.parseResult.meta.fields = Object.keys(this.parseResult.data[0]); this.parseResult.meta.fields = Object.keys(this.parseResult.data[0]);
} }
this._screenStateService.setEntities( this._screenStateService.setEntities(this.parseResult.meta.fields.map(field => this._buildAttribute(field)));
this.parseResult.meta.fields.map(field => this._buildAttribute(field))
);
this._screenStateService.setDisplayedEntities(this.allEntities); this._screenStateService.setDisplayedEntities(this.allEntities);
this.activeFields = []; this.activeFields = [];
for (const entity of this.allEntities) { for (const entity of this.allEntities) {
const existing = this.data.existingConfiguration.fileAttributeConfigs.find( const existing = this.data.existingConfiguration.fileAttributeConfigs.find(a => a.csvColumnHeader === entity.csvColumn);
a => a.csvColumnHeader === entity.csvColumn
);
if (existing) { if (existing) {
entity.id = existing.id; entity.id = existing.id;
entity.name = existing.label; entity.name = existing.label;
@ -124,34 +113,21 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
} }
} }
this.filteredKeyOptions = this.baseConfigForm this.filteredKeyOptions = this.baseConfigForm.get('filenameMappingColumnHeaderName').valueChanges.pipe(
.get('filenameMappingColumnHeaderName') startWith(this.baseConfigForm.get('filenameMappingColumnHeaderName').value as string),
.valueChanges.pipe( map((value: string) =>
startWith( this.allEntities
this.baseConfigForm.get('filenameMappingColumnHeaderName').value as string .filter(field => field.csvColumn.toLowerCase().indexOf(value.toLowerCase()) !== -1)
), .map(field => field.csvColumn)
map((value: string) => )
this.allEntities );
.filter(
field =>
field.csvColumn.toLowerCase().indexOf(value.toLowerCase()) !==
-1
)
.map(field => field.csvColumn)
)
);
if ( if (
this.data.existingConfiguration && this.data.existingConfiguration &&
this.allEntities.find( this.allEntities.find(entity => entity.csvColumn === this.data.existingConfiguration.filenameMappingColumnHeaderName)
entity =>
entity.csvColumn ===
this.data.existingConfiguration.filenameMappingColumnHeaderName
)
) { ) {
this.baseConfigForm.patchValue({ this.baseConfigForm.patchValue({
filenameMappingColumnHeaderName: filenameMappingColumnHeaderName: this.data.existingConfiguration.filenameMappingColumnHeaderName
this.data.existingConfiguration.filenameMappingColumnHeaderName
}); });
} }
@ -206,9 +182,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
const newPrimary = !!this.activeFields.find(attr => attr.primaryAttribute); const newPrimary = !!this.activeFields.find(attr => attr.primaryAttribute);
if (newPrimary) { if (newPrimary) {
this.data.existingConfiguration.fileAttributeConfigs.forEach( this.data.existingConfiguration.fileAttributeConfigs.forEach(attr => (attr.primaryAttribute = false));
attr => (attr.primaryAttribute = false)
);
} }
const fileAttributes = { const fileAttributes = {
@ -229,9 +203,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
}; };
try { try {
await this._fileAttributesControllerService await this._fileAttributesControllerService.setFileAttributesConfig(fileAttributes, this.dossierTemplateId).toPromise();
.setFileAttributesConfig(fileAttributes, this.dossierTemplateId)
.toPromise();
this._notificationService.showToastNotification( this._notificationService.showToastNotification(
this._translateService.instant('file-attributes-csv-import.save.success', { this._translateService.instant('file-attributes-csv-import.save.success', {
count: this.activeFields.length count: this.activeFields.length
@ -260,9 +232,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
if (!column) { if (!column) {
this.columnSample = []; this.columnSample = [];
} else { } else {
this.columnSample = this.parseResult.data this.columnSample = this.parseResult.data.filter(row => !!row[column]).map(row => row[column]);
.filter(row => !!row[column])
.map(row => row[column]);
} }
}, 0); }, 0);
} }
@ -283,9 +253,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
csvColumn, csvColumn,
name: csvColumn, name: csvColumn,
temporaryName: csvColumn, temporaryName: csvColumn,
type: isNumber type: isNumber ? FileAttributeConfig.TypeEnum.NUMBER : FileAttributeConfig.TypeEnum.TEXT,
? FileAttributeConfig.TypeEnum.NUMBER
: FileAttributeConfig.TypeEnum.TEXT,
readonly: false, readonly: false,
primaryAttribute: false primaryAttribute: false
}; };

View File

@ -4,12 +4,12 @@ import { Colors, DictionaryControllerService } from '@redaction/red-ui-http';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../services/admin-dialog.service';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { ScreenNames, SortingService } from '../../../../services/sorting.service'; import { ScreenNames, SortingService } from '@services/sorting.service';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
@Component({ @Component({
templateUrl: './default-colors-screen.component.html', templateUrl: './default-colors-screen.component.html',
@ -60,9 +60,7 @@ export class DefaultColorsScreenComponent
private async _loadColors() { private async _loadColors() {
this._loadingService.start(); this._loadingService.start();
const data = await this._dictionaryControllerService const data = await this._dictionaryControllerService.getColors(this._appStateService.activeDossierTemplateId).toPromise();
.getColors(this._appStateService.activeDossierTemplateId)
.toPromise();
this._colorsObj = data; this._colorsObj = data;
this._screenStateService.setEntities( this._screenStateService.setEntities(
Object.keys(data).map(key => ({ Object.keys(data).map(key => ({

View File

@ -6,15 +6,15 @@ import { catchError, defaultIfEmpty, tap } from 'rxjs/operators';
import { forkJoin, of } from 'rxjs'; import { forkJoin, of } from 'rxjs';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { TypeValueWrapper } from '@models/file/type-value.wrapper';
import { TypeValueWrapper } from '../../../../models/file/type-value.wrapper';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { ScreenNames, SortingService } from '../../../../services/sorting.service'; import { ScreenNames, SortingService } from '@services/sorting.service';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
import { AdminDialogService } from '../../services/admin-dialog.service';
const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({ const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
value: dict.entries ? dict.entries.length : 0, value: dict.entries ? dict.entries.length : 0,
@ -28,10 +28,7 @@ const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
styleUrls: ['./dictionary-listing-screen.component.scss'], styleUrls: ['./dictionary-listing-screen.component.scss'],
providers: [FilterService, SearchService, ScreenStateService, SortingService] providers: [FilterService, SearchService, ScreenStateService, SortingService]
}) })
export class DictionaryListingScreenComponent export class DictionaryListingScreenComponent extends BaseListingComponent<TypeValueWrapper> implements OnInit {
extends BaseListingComponent<TypeValueWrapper>
implements OnInit
{
chartData: DoughnutChartConfig[] = []; chartData: DoughnutChartConfig[] = [];
constructor( constructor(
@ -56,15 +53,10 @@ export class DictionaryListingScreenComponent
this._loadDictionaryData(); this._loadDictionaryData();
} }
openDeleteDictionariesDialog( openDeleteDictionariesDialog($event?: MouseEvent, types = this._screenStateService.selectedEntitiesIds) {
$event?: MouseEvent,
types = this._screenStateService.selectedEntitiesIds
) {
this._dialogService.openDialog('confirm', $event, null, async () => { this._dialogService.openDialog('confirm', $event, null, async () => {
this._loadingService.start(); this._loadingService.start();
await this._dictionaryControllerService await this._dictionaryControllerService.deleteTypes(types, this._appStateService.activeDossierTemplateId).toPromise();
.deleteTypes(types, this._appStateService.activeDossierTemplateId)
.toPromise();
this._screenStateService.setSelectedEntitiesIds([]); this._screenStateService.setSelectedEntitiesIds([]);
await this._appStateService.loadDictionaryData(); await this._appStateService.loadDictionaryData();
this._loadDictionaryData(false); this._loadDictionaryData(false);
@ -92,8 +84,7 @@ export class DictionaryListingScreenComponent
} }
private _loadDictionaryData(loadEntries = true): void { private _loadDictionaryData(loadEntries = true): void {
const appStateDictionaryData = const appStateDictionaryData = this._appStateService.dictionaryData[this._appStateService.activeDossierTemplateId];
this._appStateService.dictionaryData[this._appStateService.activeDossierTemplateId];
const entities = Object.values(appStateDictionaryData).filter(d => !d.virtual); const entities = Object.values(appStateDictionaryData).filter(d => !d.virtual);
if (!loadEntries) if (!loadEntries)
@ -110,16 +101,14 @@ export class DictionaryListingScreenComponent
if (!loadEntries) return; if (!loadEntries) return;
const dataObs = this.allEntities.map(dict => const dataObs = this.allEntities.map(dict =>
this._dictionaryControllerService this._dictionaryControllerService.getDictionaryForType(this._appStateService.activeDossierTemplateId, dict.type).pipe(
.getDictionaryForType(this._appStateService.activeDossierTemplateId, dict.type) tap(values => (dict.entries = values.entries ?? [])),
.pipe( catchError(() => {
tap(values => (dict.entries = values.entries ?? [])), console.log('error');
catchError(() => { dict.entries = [];
console.log('error'); return of({});
dict.entries = []; })
return of({}); )
})
)
); );
forkJoin(dataObs) forkJoin(dataObs)

View File

@ -9,8 +9,8 @@ import { ComponentHasChanges } from '@guards/can-deactivate.guard';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../services/admin-dialog.service';
import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component'; import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component';
import { DictionarySaveService } from '@shared/services/dictionary-save.service'; import { DictionarySaveService } from '@shared/services/dictionary-save.service';
import { TypeValueWrapper } from '../../../../models/file/type-value.wrapper'; import { TypeValueWrapper } from '@models/file/type-value.wrapper';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
@Component({ @Component({
selector: 'redaction-dictionary-overview-screen', selector: 'redaction-dictionary-overview-screen',
@ -75,9 +75,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
$event?.stopPropagation(); $event?.stopPropagation();
this._dialogService.openDialog('confirm', $event, null, async () => { this._dialogService.openDialog('confirm', $event, null, async () => {
await this._dictionaryControllerService await this._dictionaryControllerService.deleteTypes([this.dictionary.type], this.dictionary.dossierTemplateId).toPromise();
.deleteTypes([this.dictionary.type], this.dictionary.dossierTemplateId)
.toPromise();
await this._appStateService.loadDictionaryData(); await this._appStateService.loadDictionaryData();
await this._router.navigate([ await this._router.navigate([
'/main', '/main',
@ -113,13 +111,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
saveEntries(entries: string[]) { saveEntries(entries: string[]) {
this.processing = true; this.processing = true;
this._dictionarySaveService this._dictionarySaveService
.saveEntries( .saveEntries(entries, this.entries, this.dictionary.dossierTemplateId, this.dictionary.type, null)
entries,
this.entries,
this.dictionary.dossierTemplateId,
this.dictionary.type,
null
)
.subscribe( .subscribe(
() => { () => {
this.processing = false; this.processing = false;
@ -133,19 +125,15 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
private _loadEntries() { private _loadEntries() {
this.processing = true; this.processing = true;
this._dictionaryControllerService this._dictionaryControllerService.getDictionaryForType(this.dictionary.dossierTemplateId, this.dictionary.type).subscribe(
.getDictionaryForType(this.dictionary.dossierTemplateId, this.dictionary.type) data => {
.subscribe( this.processing = false;
data => { this.entries = data.entries.sort((str1, str2) => str1.localeCompare(str2, undefined, { sensitivity: 'accent' }));
this.processing = false; },
this.entries = data.entries.sort((str1, str2) => () => {
str1.localeCompare(str2, undefined, { sensitivity: 'accent' }) this.processing = false;
); this.entries = [];
}, }
() => { );
this.processing = false;
this.entries = [];
}
);
} }
} }

View File

@ -1,14 +1,14 @@
import { Component, Injector, OnInit } from '@angular/core'; import { Component, Injector, OnInit } from '@angular/core';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
import { DossierAttributeConfig, DossierAttributesControllerService } from '@redaction/red-ui-http'; import { DossierAttributeConfig, DossierAttributesControllerService } from '@redaction/red-ui-http';
import { AppStateService } from '../../../../state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../services/admin-dialog.service';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '../../../../services/loading.service';
import { ScreenNames, SortingService } from '../../../../services/sorting.service'; import { ScreenNames, SortingService } from '../../../../services/sorting.service';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
@Component({ @Component({

View File

@ -6,11 +6,11 @@ import { AdminDialogService } from '../../services/admin-dialog.service';
import { DossierTemplateModelWrapper } from '../../../../models/file/dossier-template-model.wrapper'; import { DossierTemplateModelWrapper } from '../../../../models/file/dossier-template-model.wrapper';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '../../../../services/loading.service';
import { DossierTemplateControllerService } from '@redaction/red-ui-http'; import { DossierTemplateControllerService } from '@redaction/red-ui-http';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { ScreenNames, SortingService } from '../../../../services/sorting.service'; import { ScreenNames, SortingService } from '../../../../services/sorting.service';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
@Component({ @Component({
templateUrl: './dossier-templates-listing-screen.component.html', templateUrl: './dossier-templates-listing-screen.component.html',
@ -18,10 +18,7 @@ import { BaseListingComponent } from '../../../shared/base/base-listing.componen
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
providers: [FilterService, SearchService, ScreenStateService, SortingService] providers: [FilterService, SearchService, ScreenStateService, SortingService]
}) })
export class DossierTemplatesListingScreenComponent export class DossierTemplatesListingScreenComponent extends BaseListingComponent<DossierTemplateModelWrapper> implements OnInit {
extends BaseListingComponent<DossierTemplateModelWrapper>
implements OnInit
{
constructor( constructor(
private readonly _dialogService: AdminDialogService, private readonly _dialogService: AdminDialogService,
private readonly _appStateService: AppStateService, private readonly _appStateService: AppStateService,
@ -44,9 +41,7 @@ export class DossierTemplatesListingScreenComponent
openDeleteTemplatesDialog($event?: MouseEvent) { openDeleteTemplatesDialog($event?: MouseEvent) {
return this._dialogService.openDialog('confirm', $event, null, async () => { return this._dialogService.openDialog('confirm', $event, null, async () => {
this._loadingService.start(); this._loadingService.start();
await this._dossierTemplateControllerService await this._dossierTemplateControllerService.deleteDossierTemplates(this._screenStateService.selectedEntitiesIds).toPromise();
.deleteDossierTemplates(this._screenStateService.selectedEntitiesIds)
.toPromise();
this._screenStateService.setSelectedEntitiesIds([]); this._screenStateService.setSelectedEntitiesIds([]);
await this._appStateService.loadAllDossierTemplates(); await this._appStateService.loadAllDossierTemplates();
await this._appStateService.loadDictionaryData(); await this._appStateService.loadDictionaryData();
@ -64,16 +59,11 @@ export class DossierTemplatesListingScreenComponent
} }
openAddDossierTemplateDialog() { openAddDossierTemplateDialog() {
this._dialogService.openDialog( this._dialogService.openDialog('addEditDossierTemplate', null, null, async newDossierTemplate => {
'addEditDossierTemplate', if (newDossierTemplate) {
null, this.loadDossierTemplatesData();
null,
async newDossierTemplate => {
if (newDossierTemplate) {
this.loadDossierTemplatesData();
}
} }
); });
} }
private _loadDossierTemplateStats() { private _loadDossierTemplateStats() {

View File

@ -1,22 +1,15 @@
import { import { ChangeDetectionStrategy, Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
ChangeDetectionStrategy,
Component,
ElementRef,
Injector,
OnInit,
ViewChild
} from '@angular/core';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { FileAttributeConfig, FileAttributesConfig, FileAttributesControllerService } from '@redaction/red-ui-http'; import { FileAttributeConfig, FileAttributesConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
import { AppStateService } from '@state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../services/admin-dialog.service';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '../../../../services/loading.service';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { ScreenNames, SortingService } from '../../../../services/sorting.service'; import { ScreenNames, SortingService } from '../../../../services/sorting.service';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
@Component({ @Component({
templateUrl: './file-attributes-listing-screen.component.html', templateUrl: './file-attributes-listing-screen.component.html',
@ -24,10 +17,7 @@ import { BaseListingComponent } from '../../../shared/base/base-listing.componen
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
providers: [FilterService, SearchService, ScreenStateService, SortingService] providers: [FilterService, SearchService, ScreenStateService, SortingService]
}) })
export class FileAttributesListingScreenComponent export class FileAttributesListingScreenComponent extends BaseListingComponent<FileAttributeConfig> implements OnInit {
extends BaseListingComponent<FileAttributeConfig>
implements OnInit
{
private _existingConfiguration: FileAttributesConfig; private _existingConfiguration: FileAttributesConfig;
@ViewChild('fileInput') private _fileInput: ElementRef; @ViewChild('fileInput') private _fileInput: ElementRef;
@ -75,10 +65,7 @@ export class FileAttributesListingScreenComponent
.toPromise(); .toPromise();
} else { } else {
await this._fileAttributesService await this._fileAttributesService
.deleteFileAttributes( .deleteFileAttributes(this._screenStateService.selectedEntitiesIds, this._appStateService.activeDossierTemplateId)
this._screenStateService.selectedEntitiesIds,
this._appStateService.activeDossierTemplateId
)
.toPromise(); .toPromise();
} }
await this._loadData(); await this._loadData();

View File

@ -1,6 +1,6 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { AppStateService } from '../../../../state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { ReportTemplate, ReportTemplateControllerService } from '@redaction/red-ui-http'; import { ReportTemplate, ReportTemplateControllerService } from '@redaction/red-ui-http';
import { download } from '../../../../utils/file-download-utils'; import { download } from '../../../../utils/file-download-utils';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../services/admin-dialog.service';

View File

@ -5,11 +5,11 @@ import { Dossier, StatusControllerService } from '@redaction/red-ui-http';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '../../../../services/loading.service';
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service'; import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
import * as moment from 'moment'; import * as moment from 'moment';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { ScreenNames, SortingService } from '../../../../services/sorting.service'; import { ScreenNames, SortingService } from '../../../../services/sorting.service';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
import { DossiersService } from '../../../dossier/services/dossiers.service'; import { DossiersService } from '../../../dossier/services/dossiers.service';
@Component({ @Component({

View File

@ -1,11 +1,4 @@
import { import { ChangeDetectionStrategy, Component, Injector, OnInit, QueryList, ViewChildren } from '@angular/core';
ChangeDetectionStrategy,
Component,
Injector,
OnInit,
QueryList,
ViewChildren
} from '@angular/core';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { User, UserControllerService } from '@redaction/red-ui-http'; import { User, UserControllerService } from '@redaction/red-ui-http';
@ -14,12 +7,12 @@ import { TranslateService } from '@ngx-translate/core';
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component'; import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
import { TranslateChartService } from '@services/translate-chart.service'; import { TranslateChartService } from '@services/translate-chart.service';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '../../../../services/loading.service';
import { InitialsAvatarComponent } from '../../../shared/components/initials-avatar/initials-avatar.component'; import { InitialsAvatarComponent } from '@shared/components/initials-avatar/initials-avatar.component';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { SortingService } from '../../../../services/sorting.service'; import { SortingService } from '../../../../services/sorting.service';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@ -86,9 +79,7 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
} }
bulkDelete() { bulkDelete() {
this.openDeleteUsersDialog( this.openDeleteUsersDialog(this._screenStateService.entities.filter(u => this.isSelected(u)));
this._screenStateService.entities.filter(u => this.isSelected(u))
);
} }
trackById(index: number, user: User) { trackById(index: number, user: User) {
@ -96,9 +87,7 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
} }
private async _loadData() { private async _loadData() {
this._screenStateService.setEntities( this._screenStateService.setEntities(await this._userControllerService.getAllUsers().toPromise());
await this._userControllerService.getAllUsers().toPromise()
);
await this.userService.loadAllUsers(); await this.userService.loadAllUsers();
this.filterService.filterEntities(); this.filterService.filterEntities();
this._computeStats(); this._computeStats();
@ -114,38 +103,27 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
label: 'INACTIVE' label: 'INACTIVE'
}, },
{ {
value: this.allEntities.filter( value: this.allEntities.filter(user => user.roles.length === 1 && user.roles[0] === 'RED_USER').length,
user => user.roles.length === 1 && user.roles[0] === 'RED_USER'
).length,
color: 'REGULAR', color: 'REGULAR',
label: 'REGULAR' label: 'REGULAR'
}, },
{ {
value: this.allEntities.filter( value: this.allEntities.filter(user => this.userService.isManager(user) && !this.userService.isAdmin(user)).length,
user => this.userService.isManager(user) && !this.userService.isAdmin(user)
).length,
color: 'MANAGER', color: 'MANAGER',
label: 'RED_MANAGER' label: 'RED_MANAGER'
}, },
{ {
value: this.allEntities.filter( value: this.allEntities.filter(user => this.userService.isManager(user) && this.userService.isAdmin(user)).length,
user => this.userService.isManager(user) && this.userService.isAdmin(user)
).length,
color: 'MANAGER_ADMIN', color: 'MANAGER_ADMIN',
label: 'MANAGER_ADMIN' label: 'MANAGER_ADMIN'
}, },
{ {
value: this.allEntities.filter( value: this.allEntities.filter(user => this.userService.isUserAdmin(user) && !this.userService.isAdmin(user)).length,
user =>
this.userService.isUserAdmin(user) && !this.userService.isAdmin(user)
).length,
color: 'USER_ADMIN', color: 'USER_ADMIN',
label: 'RED_USER_ADMIN' label: 'RED_USER_ADMIN'
}, },
{ {
value: this.allEntities.filter( value: this.allEntities.filter(user => this.userService.isAdmin(user) && !this.userService.isManager(user)).length,
user => this.userService.isAdmin(user) && !this.userService.isManager(user)
).length,
color: 'ADMIN', color: 'ADMIN',
label: 'RED_ADMIN' label: 'RED_ADMIN'
} }

View File

@ -11,7 +11,7 @@ import { AddEditUserDialogComponent } from '../dialogs/add-edit-user-dialog/add-
import { ConfirmDeleteUsersDialogComponent } from '../dialogs/confirm-delete-users-dialog/confirm-delete-users-dialog.component'; import { ConfirmDeleteUsersDialogComponent } from '../dialogs/confirm-delete-users-dialog/confirm-delete-users-dialog.component';
import { FileAttributesCsvImportDialogComponent } from '../dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component'; import { FileAttributesCsvImportDialogComponent } from '../dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component';
import { ComponentType } from '@angular/cdk/portal'; import { ComponentType } from '@angular/cdk/portal';
import { DialogService } from '../../shared/services/dialog.service'; import { DialogService } from '@shared/services/dialog.service';
import { AddEditDossierAttributeDialogComponent } from '../dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component'; import { AddEditDossierAttributeDialogComponent } from '../dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component';
type DialogType = type DialogType =

View File

@ -1,18 +1,15 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core';
import { AppStateService } from '@state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { import { FileManagementControllerService, ReanalysisControllerService } from '@redaction/red-ui-http';
FileManagementControllerService,
ReanalysisControllerService
} from '@redaction/red-ui-http';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { FileStatusWrapper } from '@models/file/file-status.wrapper'; import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { FileActionService } from '../../services/file-action.service'; import { FileActionService } from '../../services/file-action.service';
import { from, Observable } from 'rxjs'; import { from, Observable } from 'rxjs';
import { StatusOverlayService } from '@upload-download/services/status-overlay.service'; import { StatusOverlayService } from '@upload-download/services/status-overlay.service';
import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
import { ConfirmationDialogInput } from '../../../shared/dialogs/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogInput } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
@Component({ @Component({
selector: 'redaction-dossier-overview-bulk-actions', selector: 'redaction-dossier-overview-bulk-actions',
@ -44,10 +41,7 @@ export class DossierOverviewBulkActionsComponent {
get selectedFiles(): FileStatusWrapper[] { get selectedFiles(): FileStatusWrapper[] {
return this.selectedFileIds.map(fileId => return this.selectedFileIds.map(fileId =>
this._appStateService.getFileById( this._appStateService.getFileById(this._appStateService.activeDossier.dossier.dossierId, fileId)
this._appStateService.activeDossier.dossier.dossierId,
fileId
)
); );
} }
@ -69,10 +63,7 @@ export class DossierOverviewBulkActionsComponent {
(acc, file) => acc && (file.isUnderReview || file.isUnassigned), (acc, file) => acc && (file.isUnderReview || file.isUnassigned),
true true
); );
const allFilesAreUnderApproval = selectedFiles.reduce( const allFilesAreUnderApproval = selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true);
(acc, file) => acc && file.isUnderApproval,
true
);
return allFilesAreUnderReviewOrUnassigned || allFilesAreUnderApproval; return allFilesAreUnderReviewOrUnassigned || allFilesAreUnderApproval;
} }
return false; return false;
@ -81,42 +72,27 @@ export class DossierOverviewBulkActionsComponent {
get canAssignToSelf() { get canAssignToSelf() {
return ( return (
this.allSelectedFilesCanBeAssignedIntoSameState && this.allSelectedFilesCanBeAssignedIntoSameState &&
this.selectedFiles.reduce( this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignToSelf(file), true)
(acc, file) => acc && this._permissionsService.canAssignToSelf(file),
true
)
); );
} }
get canAssign() { get canAssign() {
return ( return (
this.allSelectedFilesCanBeAssignedIntoSameState && this.allSelectedFilesCanBeAssignedIntoSameState &&
this.selectedFiles.reduce( this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignUser(file), true)
(acc, file) => acc && this._permissionsService.canAssignUser(file),
true
)
); );
} }
get canDelete() { get canDelete() {
return this.selectedFiles.reduce( return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canDeleteFile(file), true);
(acc, file) => acc && this._permissionsService.canDeleteFile(file),
true
);
} }
get canReanalyse() { get canReanalyse() {
return this.selectedFiles.reduce( return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canReanalyseFile(file), true);
(acc, file) => acc && this._permissionsService.canReanalyseFile(file),
true
);
} }
get canOcr() { get canOcr() {
return this.selectedFiles.reduce( return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canOcrFile(file), true);
(acc, file) => acc && this._permissionsService.canOcrFile(file),
true
);
} }
get fileStatuses() { get fileStatuses() {
@ -125,51 +101,31 @@ export class DossierOverviewBulkActionsComponent {
// Under review // Under review
get canSetToUnderReview() { get canSetToUnderReview() {
return this.selectedFiles.reduce( return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderReview(file), true);
(acc, file) => acc && this._permissionsService.canSetUnderReview(file),
true
);
} }
// Under approval // Under approval
get canSetToUnderApproval() { get canSetToUnderApproval() {
return this.selectedFiles.reduce( return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderApproval(file), true);
(acc, file) => acc && this._permissionsService.canSetUnderApproval(file),
true
);
} }
// Approve // Approve
get isReadyForApproval() { get isReadyForApproval() {
return this.selectedFiles.reduce( return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.isReadyForApproval(file), true);
(acc, file) => acc && this._permissionsService.isReadyForApproval(file),
true
);
} }
get canApprove() { get canApprove() {
return this.selectedFiles.reduce( return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canApprove(file), true);
(acc, file) => acc && this._permissionsService.canApprove(file),
true
);
} }
// Undo approval // Undo approval
get canUndoApproval() { get canUndoApproval() {
return this.selectedFiles.reduce( return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canUndoApproval(file), true);
(acc, file) => acc && this._permissionsService.canUndoApproval(file),
true
);
} }
get assignTooltip() { get assignTooltip() {
const allFilesAreUnderApproval = this.selectedFiles.reduce( const allFilesAreUnderApproval = this.selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true);
(acc, file) => acc && file.isUnderApproval, return allFilesAreUnderApproval ? 'dossier-overview.assign-approver' : 'dossier-overview.assign-reviewer';
true
);
return allFilesAreUnderApproval
? 'dossier-overview.assign-approver'
: 'dossier-overview.assign-reviewer';
} }
delete() { delete() {
@ -212,23 +168,15 @@ export class DossierOverviewBulkActionsComponent {
); );
} else { } else {
this._performBulkAction( this._performBulkAction(
this._fileActionService.setFileUnderApproval( this._fileActionService.setFileUnderApproval(this.selectedFiles, this._appStateService.activeDossier.approverIds[0])
this.selectedFiles,
this._appStateService.activeDossier.approverIds[0]
)
); );
} }
} }
async reanalyse() { async reanalyse() {
const fileIds = this.selectedFiles const fileIds = this.selectedFiles.filter(file => this._permissionsService.fileRequiresReanalysis(file)).map(file => file.fileId);
.filter(file => this._permissionsService.fileRequiresReanalysis(file))
.map(file => file.fileId);
this._performBulkAction( this._performBulkAction(
this._reanalysisControllerService.reanalyzeFilesForDossier( this._reanalysisControllerService.reanalyzeFilesForDossier(fileIds, this._appStateService.activeDossier.dossierId)
fileIds,
this._appStateService.activeDossier.dossierId
)
); );
} }
@ -250,9 +198,7 @@ export class DossierOverviewBulkActionsComponent {
assign() { assign() {
this._loadingService.start(); this._loadingService.start();
const files = this.selectedFileIds.map(fileId => const files = this.selectedFileIds.map(fileId => this._appStateService.getFileById(this._appStateService.activeDossierId, fileId));
this._appStateService.getFileById(this._appStateService.activeDossierId, fileId)
);
const mode = files[0].isUnderApproval ? 'approver' : 'reviewer'; const mode = files[0].isUnderApproval ? 'approver' : 'reviewer';

View File

@ -8,7 +8,7 @@ import { StatusSorter } from '@utils/sorters/status-sorter';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { User } from '@redaction/red-ui-http'; import { User } from '@redaction/red-ui-http';
import { NotificationService } from '@services/notification.service'; import { NotificationService } from '@services/notification.service';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { FileStatusWrapper } from '../../../../models/file/file-status.wrapper'; import { FileStatusWrapper } from '../../../../models/file/file-status.wrapper';
@Component({ @Component({
@ -70,9 +70,7 @@ export class DossierDetailsComponent implements OnInit {
}); });
} }
this.documentsChartData.sort((a, b) => StatusSorter[a.key] - StatusSorter[b.key]); this.documentsChartData.sort((a, b) => StatusSorter[a.key] - StatusSorter[b.key]);
this.documentsChartData = this.translateChartService.translateStatus( this.documentsChartData = this.translateChartService.translateStatus(this.documentsChartData);
this.documentsChartData
);
this._changeDetectorRef.detectChanges(); this._changeDetectorRef.detectChanges();
} }

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component'; import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
import { AppStateService } from '@state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
@Component({ @Component({
selector: 'redaction-dossier-listing-details', selector: 'redaction-dossier-listing-details',
@ -13,8 +13,5 @@ export class DossierListingDetailsComponent<T> {
@Input() dossiersChartData: DoughnutChartConfig[]; @Input() dossiersChartData: DoughnutChartConfig[];
@Input() documentsChartData: DoughnutChartConfig[]; @Input() documentsChartData: DoughnutChartConfig[];
constructor( constructor(readonly appStateService: AppStateService, readonly filterService: FilterService<T>) {}
readonly appStateService: AppStateService,
readonly filterService: FilterService<T>
) {}
} }

View File

@ -4,8 +4,8 @@ import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { AppStateService } from '@state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { FileActionService } from '../../services/file-action.service'; import { FileActionService } from '../../services/file-action.service';
import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { ConfirmationDialogInput } from '../../../shared/dialogs/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogInput } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
import { FileManagementControllerService } from '@redaction/red-ui-http'; import { FileManagementControllerService } from '@redaction/red-ui-http';
@Component({ @Component({
@ -48,9 +48,7 @@ export class FileActionsComponent implements OnInit {
return 'file-preview.toggle-analysis.only-managers'; return 'file-preview.toggle-analysis.only-managers';
} }
return this.fileStatus?.isExcluded return this.fileStatus?.isExcluded ? 'file-preview.toggle-analysis.enable' : 'file-preview.toggle-analysis.disable';
? 'file-preview.toggle-analysis.enable'
: 'file-preview.toggle-analysis.disable';
} }
get canAssignToSelf() { get canAssignToSelf() {
@ -86,9 +84,7 @@ export class FileActionsComponent implements OnInit {
} }
get assignTooltip() { get assignTooltip() {
return this.fileStatus.isUnderApproval return this.fileStatus.isUnderApproval ? 'dossier-overview.assign-approver' : 'dossier-overview.assign-reviewer';
? 'dossier-overview.assign-approver'
: 'dossier-overview.assign-reviewer';
} }
ngOnInit(): void { ngOnInit(): void {
@ -124,9 +120,7 @@ export class FileActionsComponent implements OnInit {
}), }),
async () => { async () => {
this._loadingService.start(); this._loadingService.start();
await this._fileManagementControllerService await this._fileManagementControllerService.deleteFiles([this.fileStatus.fileId], this.fileStatus.dossierId).toPromise();
.deleteFiles([this.fileStatus.fileId], this.fileStatus.dossierId)
.toPromise();
await this.appStateService.reloadActiveDossierFiles(); await this.appStateService.reloadActiveDossierFiles();
this.actionPerformed.emit('delete'); this.actionPerformed.emit('delete');
this._loadingService.stop(); this._loadingService.stop();
@ -162,11 +156,7 @@ export class FileActionsComponent implements OnInit {
setFileUnderApproval($event: MouseEvent) { setFileUnderApproval($event: MouseEvent) {
$event.stopPropagation(); $event.stopPropagation();
if (this.appStateService.activeDossier.approverIds.length > 1) { if (this.appStateService.activeDossier.approverIds.length > 1) {
this._fileActionService.assignDossierApprover( this._fileActionService.assignDossierApprover(this.fileStatus, () => this.actionPerformed.emit('assign-reviewer'), true);
this.fileStatus,
() => this.actionPerformed.emit('assign-reviewer'),
true
);
} else { } else {
this._fileActionService.setFileUnderApproval(this.fileStatus).subscribe(() => { this._fileActionService.setFileUnderApproval(this.fileStatus).subscribe(() => {
this.reloadDossiers('set-under-approval'); this.reloadDossiers('set-under-approval');
@ -206,8 +196,6 @@ export class FileActionsComponent implements OnInit {
async toggleAnalysis() { async toggleAnalysis() {
await this._fileActionService.toggleAnalysis(this.fileStatus).toPromise(); await this._fileActionService.toggleAnalysis(this.fileStatus).toPromise();
await this.appStateService.getFiles(); await this.appStateService.getFiles();
this.actionPerformed.emit( this.actionPerformed.emit(this.fileStatus?.isExcluded ? 'enable-analysis' : 'disable-analysis');
this.fileStatus?.isExcluded ? 'enable-analysis' : 'disable-analysis'
);
} }
} }

View File

@ -19,7 +19,7 @@ import { debounce } from '@utils/debounce';
import { FileDataModel } from '@models/file/file-data.model'; import { FileDataModel } from '@models/file/file-data.model';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model'; import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import { CommentsComponent } from '../comments/comments.component'; import { CommentsComponent } from '../comments/comments.component';
import { PermissionsService } from '../../../../services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { WebViewerInstance } from '@pdftron/webviewer'; import { WebViewerInstance } from '@pdftron/webviewer';

View File

@ -1,10 +1,10 @@
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { PermissionsService } from '../../../../services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { FormBuilder, FormGroup } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { PageRange, ReanalysisControllerService } from '@redaction/red-ui-http'; import { PageRange, ReanalysisControllerService } from '@redaction/red-ui-http';
import { FileDataModel } from '../../../../models/file/file-data.model'; import { FileDataModel } from '@models/file/file-data.model';
import { NotificationService, NotificationType } from '../../../../services/notification.service'; import { NotificationService, NotificationType } from '@services/notification.service';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@Component({ @Component({
@ -34,9 +34,7 @@ export class PageExclusionComponent implements OnChanges {
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
if (changes.fileData) { if (changes.fileData) {
const excludedPages = (this.fileData?.fileStatus?.excludedPages || []).sort( const excludedPages = (this.fileData?.fileStatus?.excludedPages || []).sort((p1, p2) => p1 - p2);
(p1, p2) => p1 - p2
);
this.excludedPagesRanges = excludedPages.reduce((ranges, page) => { this.excludedPagesRanges = excludedPages.reduce((ranges, page) => {
if (!ranges.length) { if (!ranges.length) {
return [{ startPage: page, endPage: page }]; return [{ startPage: page, endPage: page }];

View File

@ -24,12 +24,12 @@ import { AnnotationActionsService } from '../../services/annotation-actions.serv
import { UserPreferenceService } from '@services/user-preference.service'; import { UserPreferenceService } from '@services/user-preference.service';
import { BASE_HREF } from '../../../../tokens'; import { BASE_HREF } from '../../../../tokens';
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service'; import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
import { LoadingService } from '../../../../services/loading.service'; import { LoadingService } from '@services/loading.service';
import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { ConfirmationDialogInput } from '../../../shared/dialogs/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogInput } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
import { loadCompareDocumentWrapper } from '../../utils/compare-mode.utils'; import { loadCompareDocumentWrapper } from '../../utils/compare-mode.utils';
import { PdfViewerUtils } from '../../utils/pdf-viewer.utils'; import { PdfViewerUtils } from '../../utils/pdf-viewer.utils';
import { ViewMode } from '../../../../models/file/view-mode'; import { ViewMode } from '@models/file/view-mode';
import TextTool = Tools.TextTool; import TextTool = Tools.TextTool;
@Component({ @Component({
@ -105,9 +105,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
// viewer init // viewer init
this.instance.setFitMode('FitPage'); this.instance.setFitMode('FitPage');
const instanceDisplayMode = this.instance.docViewer const instanceDisplayMode = this.instance.docViewer.getDisplayModeManager().getDisplayMode();
.getDisplayModeManager()
.getDisplayMode();
instanceDisplayMode.mode = this.viewMode === 'STANDARD' ? 'Single' : 'Facing'; instanceDisplayMode.mode = this.viewMode === 'STANDARD' ? 'Single' : 'Facing';
this.instance.docViewer.getDisplayModeManager().setDisplayMode(instanceDisplayMode); this.instance.docViewer.getDisplayModeManager().setDisplayMode(instanceDisplayMode);
} }
@ -123,15 +121,11 @@ export class PdfViewerComponent implements OnInit, OnChanges {
const pdfData = fileReader.result; const pdfData = fileReader.result;
const PDFNet = this.instance.PDFNet; const PDFNet = this.instance.PDFNet;
await PDFNet.initialize( await PDFNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
environment.licenseKey ? atob(environment.licenseKey) : null
);
const mergedDocument = await PDFNet.PDFDoc.create(); const mergedDocument = await PDFNet.PDFDoc.create();
const compareDocument = await PDFNet.PDFDoc.createFromBuffer(<any>pdfData); const compareDocument = await PDFNet.PDFDoc.createFromBuffer(<any>pdfData);
const currentDocument = await PDFNet.PDFDoc.createFromBuffer( const currentDocument = await PDFNet.PDFDoc.createFromBuffer(await this.fileData.arrayBuffer());
await this.fileData.arrayBuffer()
);
const currentDocumentPageCount = await currentDocument.getPageCount(); const currentDocumentPageCount = await currentDocument.getPageCount();
const compareDocumentPageCount = await compareDocument.getPageCount(); const compareDocumentPageCount = await compareDocument.getPageCount();
@ -186,9 +180,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
this.viewMode = 'STANDARD'; this.viewMode = 'STANDARD';
const PDFNet = this.instance.PDFNet; const PDFNet = this.instance.PDFNet;
await PDFNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null); await PDFNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
const currentDocument = await PDFNet.PDFDoc.createFromBuffer( const currentDocument = await PDFNet.PDFDoc.createFromBuffer(await this.fileData.arrayBuffer());
await this.fileData.arrayBuffer()
);
this.instance.loadDocument(currentDocument, { this.instance.loadDocument(currentDocument, {
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf' filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
}); });
@ -221,16 +213,12 @@ export class PdfViewerComponent implements OnInit, OnChanges {
this._configureTextPopup(); this._configureTextPopup();
this.instance.annotManager.on('annotationSelected', (annotations, action) => { this.instance.annotManager.on('annotationSelected', (annotations, action) => {
this.annotationSelected.emit( this.annotationSelected.emit(this.instance.annotManager.getSelectedAnnotations().map(ann => ann.Id));
this.instance.annotManager.getSelectedAnnotations().map(ann => ann.Id)
);
if (action === 'deselected') { if (action === 'deselected') {
this._toggleRectangleAnnotationAction(true); this._toggleRectangleAnnotationAction(true);
} else { } else {
this._configureAnnotationSpecificActions(annotations); this._configureAnnotationSpecificActions(annotations);
this._toggleRectangleAnnotationAction( this._toggleRectangleAnnotationAction(annotations.length === 1 && annotations[0].ReadOnly);
annotations.length === 1 && annotations[0].ReadOnly
);
} }
}); });
@ -238,10 +226,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
// when a rectangle is drawn, // when a rectangle is drawn,
// it returns one annotation with tool name 'AnnotationCreateRectangle; // it returns one annotation with tool name 'AnnotationCreateRectangle;
// this will auto select rectangle after drawing // this will auto select rectangle after drawing
if ( if (annotations.length === 1 && annotations[0].ToolName === 'AnnotationCreateRectangle') {
annotations.length === 1 &&
annotations[0].ToolName === 'AnnotationCreateRectangle'
) {
this.instance.annotManager.selectAnnotations(annotations); this.instance.annotManager.selectAnnotations(annotations);
} }
}); });
@ -284,9 +269,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
this.instance.iframeWindow.addEventListener('visibilityChanged', (event: any) => { this.instance.iframeWindow.addEventListener('visibilityChanged', (event: any) => {
if (event.detail.element === 'searchPanel') { if (event.detail.element === 'searchPanel') {
const inputElement = this.instance.iframeWindow.document.getElementById( const inputElement = this.instance.iframeWindow.document.getElementById('SearchPanel__input') as HTMLInputElement;
'SearchPanel__input'
) as HTMLInputElement;
setTimeout(() => { setTimeout(() => {
inputElement.value = ''; inputElement.value = '';
}, 0); }, 0);
@ -364,9 +347,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
type: 'actionButton', type: 'actionButton',
element: 'closeCompare', element: 'closeCompare',
dataElement: 'closeCompareButton', dataElement: 'closeCompareButton',
img: this._convertPath( img: this._convertPath('/assets/icons/general/pdftron-action-close-compare.svg'),
'/assets/icons/general/pdftron-action-close-compare.svg'
),
title: 'Leave Compare Mode', title: 'Leave Compare Mode',
onClick: () => { onClick: () => {
this.closeCompareMode(); this.closeCompareMode();
@ -394,9 +375,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
return; return;
} }
const annotationWrappers = viewerAnnotations const annotationWrappers = viewerAnnotations.map(va => this.annotations.find(a => a.id === va.Id)).filter(va => !!va);
.map(va => this.annotations.find(a => a.id === va.Id))
.filter(va => !!va);
this.instance.annotationPopup.update([]); this.instance.annotationPopup.update([]);
if (annotationWrappers.length === 0) { if (annotationWrappers.length === 0) {
@ -405,15 +384,9 @@ export class PdfViewerComponent implements OnInit, OnChanges {
} }
// Add hide action as last item // Add hide action as last item
const allAnnotationsHaveImageAction = annotationWrappers.reduce( const allAnnotationsHaveImageAction = annotationWrappers.reduce((acc, next) => acc && next.isImage, true);
(acc, next) => acc && next.isImage,
true
);
if (allAnnotationsHaveImageAction) { if (allAnnotationsHaveImageAction) {
const allAreVisible = viewerAnnotations.reduce( const allAreVisible = viewerAnnotations.reduce((acc, next) => next.isVisible() && acc, true);
(acc, next) => next.isVisible() && acc,
true
);
this.instance.annotationPopup.add([ this.instance.annotationPopup.add([
{ {
@ -437,10 +410,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
} }
this.instance.annotationPopup.add( this.instance.annotationPopup.add(
this._annotationActionsService.getViewerAvailableActions( this._annotationActionsService.getViewerAvailableActions(annotationWrappers, this.annotationsChanged)
annotationWrappers,
this.annotationsChanged
)
); );
} }
@ -449,17 +419,12 @@ export class PdfViewerComponent implements OnInit, OnChanges {
type: 'actionButton', type: 'actionButton',
dataElement: 'add-rectangle', dataElement: 'add-rectangle',
img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'), img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'),
title: this._translateService.instant( title: this._translateService.instant(this._manualAnnotationService.getTitle('REDACTION')),
this._manualAnnotationService.getTitle('REDACTION')
),
onClick: () => { onClick: () => {
const selectedAnnotations = this.instance.annotManager.getSelectedAnnotations(); const selectedAnnotations = this.instance.annotManager.getSelectedAnnotations();
const activeAnnotation = selectedAnnotations[0]; const activeAnnotation = selectedAnnotations[0];
const activePage = selectedAnnotations[0].getPageNumber(); const activePage = selectedAnnotations[0].getPageNumber();
const quad = this._annotationDrawService.annotationToQuads( const quad = this._annotationDrawService.annotationToQuads(activeAnnotation, this.instance);
activeAnnotation,
this.instance
);
const quadsObject = {}; const quadsObject = {};
quadsObject[activePage] = [quad]; quadsObject[activePage] = [quad];
const mre = this._getManualRedactionEntry(quadsObject, 'Rectangle'); const mre = this._getManualRedactionEntry(quadsObject, 'Rectangle');
@ -469,13 +434,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
this.instance.enableElements(['shapeToolGroupButton', 'rectangleToolDivider']); this.instance.enableElements(['shapeToolGroupButton', 'rectangleToolDivider']);
// dispatch event // dispatch event
this.manualAnnotationRequested.emit( this.manualAnnotationRequested.emit(
new ManualRedactionEntryWrapper( new ManualRedactionEntryWrapper([quad], mre, 'REDACTION', 'RECTANGLE', activeAnnotation.Id)
[quad],
mre,
'REDACTION',
'RECTANGLE',
activeAnnotation.Id
)
); );
} }
}); });
@ -509,19 +468,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
type: 'actionButton', type: 'actionButton',
dataElement: 'add-false-positive', dataElement: 'add-false-positive',
img: this._convertPath('/assets/icons/general/pdftron-action-false-positive.svg'), img: this._convertPath('/assets/icons/general/pdftron-action-false-positive.svg'),
title: this._translateService.instant( title: this._translateService.instant(this._manualAnnotationService.getTitle('FALSE_POSITIVE')),
this._manualAnnotationService.getTitle('FALSE_POSITIVE')
),
onClick: () => { onClick: () => {
const selectedQuads = this.instance.docViewer.getSelectedTextQuads(); const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
const text = this.instance.docViewer.getSelectedText(); const text = this.instance.docViewer.getSelectedText();
const mre = this._getManualRedactionEntry(selectedQuads, text, true); const mre = this._getManualRedactionEntry(selectedQuads, text, true);
this.manualAnnotationRequested.emit( this.manualAnnotationRequested.emit(
new ManualRedactionEntryWrapper( new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'FALSE_POSITIVE')
this.instance.docViewer.getSelectedTextQuads(),
mre,
'FALSE_POSITIVE'
)
); );
} }
}); });
@ -531,19 +484,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
type: 'actionButton', type: 'actionButton',
dataElement: 'add-dictionary', dataElement: 'add-dictionary',
img: this._convertPath('/assets/icons/general/pdftron-action-add-dict.svg'), img: this._convertPath('/assets/icons/general/pdftron-action-add-dict.svg'),
title: this._translateService.instant( title: this._translateService.instant(this._manualAnnotationService.getTitle('DICTIONARY')),
this._manualAnnotationService.getTitle('DICTIONARY')
),
onClick: () => { onClick: () => {
const selectedQuads = this.instance.docViewer.getSelectedTextQuads(); const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
const text = this.instance.docViewer.getSelectedText(); const text = this.instance.docViewer.getSelectedText();
const mre = this._getManualRedactionEntry(selectedQuads, text, true); const mre = this._getManualRedactionEntry(selectedQuads, text, true);
this.manualAnnotationRequested.emit( this.manualAnnotationRequested.emit(
new ManualRedactionEntryWrapper( new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'DICTIONARY')
this.instance.docViewer.getSelectedTextQuads(),
mre,
'DICTIONARY'
)
); );
} }
}); });
@ -552,19 +499,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
type: 'actionButton', type: 'actionButton',
dataElement: 'add-redaction', dataElement: 'add-redaction',
img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'), img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'),
title: this._translateService.instant( title: this._translateService.instant(this._manualAnnotationService.getTitle('REDACTION')),
this._manualAnnotationService.getTitle('REDACTION')
),
onClick: () => { onClick: () => {
const selectedQuads = this.instance.docViewer.getSelectedTextQuads(); const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
const text = this.instance.docViewer.getSelectedText(); const text = this.instance.docViewer.getSelectedText();
const mre = this._getManualRedactionEntry(selectedQuads, text, true); const mre = this._getManualRedactionEntry(selectedQuads, text, true);
this.manualAnnotationRequested.emit( this.manualAnnotationRequested.emit(
new ManualRedactionEntryWrapper( new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'REDACTION')
this.instance.docViewer.getSelectedTextQuads(),
mre,
'REDACTION'
)
); );
} }
}); });
@ -600,22 +541,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
} }
} }
private _getManualRedactionEntry( private _getManualRedactionEntry(quads: any, text: string, convertQuads: boolean = false): ManualRedactionEntry {
quads: any,
text: string,
convertQuads: boolean = false
): ManualRedactionEntry {
text = text.replace(/-\n/gi, ''); text = text.replace(/-\n/gi, '');
const entry: ManualRedactionEntry = { positions: [] }; const entry: ManualRedactionEntry = { positions: [] };
for (const key of Object.keys(quads)) { for (const key of Object.keys(quads)) {
for (const quad of quads[key]) { for (const quad of quads[key]) {
const page = parseInt(key, 10); const page = parseInt(key, 10);
entry.positions.push( entry.positions.push(this.utils.toPosition(page, convertQuads ? this.utils.translateQuads(page, quad) : quad));
this.utils.toPosition(
page,
convertQuads ? this.utils.translateQuads(page, quad) : quad
)
);
} }
} }
entry.value = text; entry.value = text;

View File

@ -4,8 +4,8 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { LegalBasisMappingControllerService } from '@redaction/red-ui-http'; import { LegalBasisMappingControllerService } from '@redaction/red-ui-http';
import { AppStateService } from '../../../../state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { PermissionsService } from '../../../../services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
export interface LegalBasisOption { export interface LegalBasisOption {
label?: string; label?: string;

View File

@ -1,10 +1,10 @@
import { Component, Inject, ViewChild } from '@angular/core'; import { Component, Inject, ViewChild } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { DossierWrapper } from '../../../../state/model/dossier.wrapper'; import { DossierWrapper } from '@state/model/dossier.wrapper';
import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component'; import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component';
import { DictionarySaveService } from '@shared/services/dictionary-save.service'; import { DictionarySaveService } from '@shared/services/dictionary-save.service';
import { AppStateService } from '../../../../state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { PermissionsService } from '../../../../services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
@Component({ @Component({
selector: 'redaction-dossier-dictionary-dialog', selector: 'redaction-dossier-dictionary-dialog',
@ -23,9 +23,7 @@ export class DossierDictionaryDialogComponent {
private readonly _appStateService: AppStateService, private readonly _appStateService: AppStateService,
private readonly _dictionarySaveService: DictionarySaveService private readonly _dictionarySaveService: DictionarySaveService
) { ) {
this.canEdit = this.canEdit = this.permissionsService.isDossierMember(this.dossier) || this.permissionsService.isAdmin();
this.permissionsService.isDossierMember(this.dossier) ||
this.permissionsService.isAdmin();
} }
saveDossierDictionary() { saveDossierDictionary() {
@ -39,10 +37,7 @@ export class DossierDictionaryDialogComponent {
) )
.subscribe(async () => { .subscribe(async () => {
await this._appStateService.reloadActiveDossierFiles(); await this._appStateService.reloadActiveDossierFiles();
this._appStateService.updateDossierDictionary( this._appStateService.updateDossierDictionary(this.dossier.dossierTemplateId, this.dossier.dossierId);
this.dossier.dossierTemplateId,
this.dossier.dossierId
);
this.dialogRef.close(); this.dialogRef.close();
}); });
} }

View File

@ -0,0 +1,21 @@
<form *ngIf="attributesForm" [formGroup]="attributesForm">
<div>
<div class="heading">
{{ 'edit-dossier-dialog.nav-items.custom-dossier-attributes' | translate }}
</div>
<div *ngFor="let attr of customAttributes" class="red-input-group w-300">
<label>{{ attr.label }}</label>
<input [formControlName]="attr.id" [name]="attr.id" type="text" />
</div>
</div>
<div class="separator"></div>
<div>
<div class="heading">
{{ 'edit-dossier-dialog.nav-items.image-attributes' | translate }}
</div>
<div *ngFor="let attr of imageAttributes" class="red-input-group w-300">
<label>{{ attr.label }}</label>
<input [formControlName]="attr.id" [name]="attr.id" type="text" />
</div>
</div>
</form>

View File

@ -0,0 +1,24 @@
@import '../../../../../../assets/styles/red-variables';
:host {
display: flex;
min-height: 100%;
form {
display: flex;
flex: 1;
> div {
flex: 1;
padding: 24px 32px;
}
.separator {
flex: none;
height: 100%;
width: 1px;
padding: 0;
background-color: $separator;
}
}
}

View File

@ -0,0 +1,97 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { DossierWrapper } from '@state/model/dossier.wrapper';
import { AppStateService } from '@state/app-state.service';
import { PermissionsService } from '@services/permissions.service';
import { DossierAttributeConfig, DossierAttributesControllerService } from '@redaction/red-ui-http';
import { LoadingService } from '@services/loading.service';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'redaction-edit-dossier-attributes',
templateUrl: './edit-dossier-attributes.component.html',
styleUrls: ['./edit-dossier-attributes.component.scss']
})
export class EditDossierAttributesComponent implements EditDossierSectionInterface, OnInit {
@Input() dossierWrapper: DossierWrapper;
@Output() updateDossier = new EventEmitter<any>();
customAttributes: (DossierAttributeConfig & { value: any })[] = [];
imageAttributes: (DossierAttributeConfig & { value: any })[] = [];
attributesMapping: (DossierAttributeConfig & { value: any })[] = [];
attributesForm: FormGroup;
constructor(
private readonly _appStateService: AppStateService,
private readonly _permissionsService: PermissionsService,
private readonly _dossierAttributesService: DossierAttributesControllerService,
private readonly _loadingService: LoadingService,
private readonly _formBuilder: FormBuilder
) {}
get changed() {
for (const attr of this.attributesMapping) {
if (this._parseAttrValue(attr.value) !== this._parseAttrValue(this.attributesForm.get(attr.id).value)) {
return true;
}
}
return false;
}
get disabled() {
return !this._permissionsService.isOwner(this.dossierWrapper);
}
async ngOnInit() {
this._loadingService.start();
await this._loadAttributes();
this._initForm();
this._loadingService.stop();
}
async save() {
this._loadingService.start();
const dossierAttributeList = this.attributesMapping.map(attr => ({
dossierAttributeId: attr.id,
value: this.attributesForm.get(attr.id).value
}));
await this._dossierAttributesService.setDossierAttributes({ dossierAttributeList }, this.dossierWrapper.dossierId).toPromise();
await this._loadAttributes();
this._loadingService.stop();
}
updatedDossier($event) {
this.updateDossier.emit($event);
}
revert() {
this._initForm();
}
private _parseAttrValue(value: any) {
return [null, undefined, ''].includes(value) ? undefined : value;
}
private async _loadAttributes() {
const attributes = await this._dossierAttributesService.getDossierAttributes(this.dossierWrapper.dossierId).toPromise();
const attributesConfig = await this._dossierAttributesService
.getDossierAttributesConfig(this.dossierWrapper.dossierTemplateId)
.toPromise();
this.attributesMapping = attributesConfig.dossierAttributeConfigs.map(config => ({
...config,
value: attributes.dossierAttributeList.find(attr => attr.dossierAttributeId === config.id)?.value
}));
this.customAttributes = this.attributesMapping.filter(attr => attr.type !== 'IMAGE');
this.imageAttributes = this.attributesMapping.filter(attr => attr.type === 'IMAGE');
}
private _initForm() {
const controlsConfig = {};
for (const attribute of this.attributesMapping) {
controlsConfig[attribute.id] = attribute.value;
}
this.attributesForm = this._formBuilder.group(controlsConfig);
}
}

View File

@ -1,8 +1,8 @@
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { AppStateService } from '../../../../../state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { DossierWrapper } from '../../../../../state/model/dossier.wrapper'; import { DossierWrapper } from '@state/model/dossier.wrapper';
import { EditDossierSectionInterface } from '../edit-dossier-section.interface'; import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { PermissionsService } from '../../../../../services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component'; import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component';
import { DictionarySaveService } from '@shared/services/dictionary-save.service'; import { DictionarySaveService } from '@shared/services/dictionary-save.service';
@ -23,9 +23,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
private readonly _dictionarySaveService: DictionarySaveService, private readonly _dictionarySaveService: DictionarySaveService,
private readonly _permissionsService: PermissionsService private readonly _permissionsService: PermissionsService
) { ) {
this.canEdit = this.canEdit = this._permissionsService.isDossierMember(this.dossierWrapper) || this._permissionsService.isAdmin();
this._permissionsService.isDossierMember(this.dossierWrapper) ||
this._permissionsService.isAdmin();
} }
get changed() { get changed() {
@ -47,10 +45,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
false false
) )
.subscribe(async () => { .subscribe(async () => {
this._appStateService.updateDossierDictionary( this._appStateService.updateDossierDictionary(this.dossierWrapper.dossierTemplateId, this.dossierWrapper.dossierId);
this.dossierWrapper.dossierTemplateId,
this.dossierWrapper.dossierId
);
this.updateDossier.emit(); this.updateDossier.emit();
}); });
} }

View File

@ -1,8 +1,8 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { DossierTemplateModel } from '@redaction/red-ui-http'; import { DossierTemplateModel } from '@redaction/red-ui-http';
import { FormBuilder, FormGroup } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { AppStateService } from '../../../../../state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { DossierWrapper } from '../../../../../state/model/dossier.wrapper'; import { DossierWrapper } from '@state/model/dossier.wrapper';
import { EditDossierSectionInterface } from '../edit-dossier-section.interface'; import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
@Component({ @Component({
@ -19,10 +19,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
@Input() dossierWrapper: DossierWrapper; @Input() dossierWrapper: DossierWrapper;
@Output() updateDossier = new EventEmitter<any>(); @Output() updateDossier = new EventEmitter<any>();
constructor( constructor(private readonly _appStateService: AppStateService, private readonly _formBuilder: FormBuilder) {}
private readonly _appStateService: AppStateService,
private readonly _formBuilder: FormBuilder
) {}
get reportTypesLength() { get reportTypesLength() {
return this.dossierForm.controls['reportTypes']?.value?.length || 0; return this.dossierForm.controls['reportTypes']?.value?.length || 0;
@ -34,9 +31,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
get changed() { get changed() {
for (const key of Object.keys(this.dossierForm.getRawValue())) { for (const key of Object.keys(this.dossierForm.getRawValue())) {
if ( if (this.dossierWrapper.dossier[key].length !== this.dossierForm.get(key).value.length) {
this.dossierWrapper.dossier[key].length !== this.dossierForm.get(key).value.length
) {
return true; return true;
} }
@ -65,10 +60,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
}, },
{ {
validators: control => validators: control =>
control.value.reportTypes?.length > 0 || control.value.reportTypes?.length > 0 || control.value.downloadFileTypes?.length > 0 ? null : { downloadPackage: true }
control.value.downloadFileTypes?.length > 0
? null
: { downloadPackage: true }
} }
); );
} }

View File

@ -14,23 +14,16 @@
></div> ></div>
</redaction-side-nav> </redaction-side-nav>
<div> <div>
<div class="content"> <div [class.no-padding]="noPaddingTab" class="content">
<div class="heading"> <div *ngIf="showHeading" class="heading">
{{ {{ 'edit-dossier-dialog.nav-items.' + (activeNavItem.title || activeNavItem.key) | translate }}
'edit-dossier-dialog.nav-items.' +
(activeNavItem.title || activeNavItem.key) | translate
}}
<div <div *ngIf="showSubtitle" class="small-label stats-subtitle">
*ngIf="activeNav === 'dossier-dictionary'"
class="small-label stats-subtitle"
>
<div> <div>
<mat-icon svgIcon="red:entries"></mat-icon> <mat-icon svgIcon="red:entries"></mat-icon>
{{ {{
'edit-dossier-dialog.dictionary.entries' 'edit-dossier-dialog.dictionary.entries'
| translate | translate: { length: (dossierWrapper.type?.entries || []).length }
: { length: (dossierWrapper.type?.entries || []).length }
}} }}
</div> </div>
</div> </div>
@ -59,6 +52,12 @@
*ngIf="activeNav === 'members'" *ngIf="activeNav === 'members'"
[dossierWrapper]="dossierWrapper" [dossierWrapper]="dossierWrapper"
></redaction-edit-dossier-team-members> ></redaction-edit-dossier-team-members>
<redaction-edit-dossier-attributes
(updateDossier)="updatedDossier($event)"
*ngIf="activeNav === 'dossier-attributes'"
[dossierWrapper]="dossierWrapper"
></redaction-edit-dossier-attributes>
</div> </div>
<div class="dialog-actions"> <div class="dialog-actions">
@ -71,18 +70,10 @@
{{ 'edit-dossier-dialog.actions.save' | translate }} {{ 'edit-dossier-dialog.actions.save' | translate }}
</button> </button>
<div <div (click)="revert()" class="all-caps-label cancel" translate="edit-dossier-dialog.actions.revert"></div>
(click)="revert()"
class="all-caps-label cancel"
translate="edit-dossier-dialog.actions.revert"
></div>
</div> </div>
</div> </div>
</div> </div>
<redaction-circle-button <redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
class="dialog-close"
icon="red:close"
mat-dialog-close
></redaction-circle-button>
</section> </section>

View File

@ -18,7 +18,11 @@
height: calc(100% - 81px); height: calc(100% - 81px);
box-sizing: border-box; box-sizing: border-box;
.heading { &.no-padding {
padding: 0;
}
::ng-deep .heading {
margin-bottom: 24px; margin-bottom: 24px;
} }
} }

View File

@ -6,12 +6,13 @@ import { DossierWrapper } from '../../../../state/model/dossier.wrapper';
import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component'; import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component';
import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component'; import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component';
import { EditDossierSectionInterface } from './edit-dossier-section.interface'; import { EditDossierSectionInterface } from './edit-dossier-section.interface';
import { NotificationService, NotificationType } from '../../../../services/notification.service'; import { NotificationService, NotificationType } from '@services/notification.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component'; import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component';
import { EditDossierTeamMembersComponent } from './team-members/edit-dossier-team-members.component'; import { EditDossierTeamMembersComponent } from './team-members/edit-dossier-team-members.component';
import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component';
type Section = 'dossier-info' | 'download-package' | 'dossier-dictionary' | 'members'; type Section = 'dossier-info' | 'download-package' | 'dossier-dictionary' | 'members' | 'dossier-attributes';
@Component({ @Component({
templateUrl: './edit-dossier-dialog.component.html', templateUrl: './edit-dossier-dialog.component.html',
@ -22,20 +23,19 @@ export class EditDossierDialogComponent {
{ key: 'dossier-info', title: 'general-info' }, { key: 'dossier-info', title: 'general-info' },
{ key: 'download-package', title: 'choose-download' }, { key: 'download-package', title: 'choose-download' },
{ key: 'dossier-dictionary', title: 'dossier-dictionary' }, { key: 'dossier-dictionary', title: 'dossier-dictionary' },
{ key: 'members', title: 'team-members' } { key: 'members', title: 'team-members' },
{ key: 'dossier-attributes' }
// TODO: // TODO:
// { key: 'dossier-attributes' },
// { key: 'report-attributes' } // { key: 'report-attributes' }
]; ];
activeNav: Section; activeNav: Section;
dossierWrapper: DossierWrapper; dossierWrapper: DossierWrapper;
@ViewChild(EditDossierGeneralInfoComponent) @ViewChild(EditDossierGeneralInfoComponent) generalInfoComponent: EditDossierGeneralInfoComponent;
generalInfoComponent: EditDossierGeneralInfoComponent; @ViewChild(EditDossierDownloadPackageComponent) downloadPackageComponent: EditDossierDownloadPackageComponent;
@ViewChild(EditDossierDownloadPackageComponent)
downloadPackageComponent: EditDossierDownloadPackageComponent;
@ViewChild(EditDossierDictionaryComponent) dictionaryComponent: EditDossierDictionaryComponent; @ViewChild(EditDossierDictionaryComponent) dictionaryComponent: EditDossierDictionaryComponent;
@ViewChild(EditDossierTeamMembersComponent) membersComponent: EditDossierTeamMembersComponent; @ViewChild(EditDossierTeamMembersComponent) membersComponent: EditDossierTeamMembersComponent;
@ViewChild(EditDossierAttributesComponent) attributesComponent: EditDossierAttributesComponent;
constructor( constructor(
private readonly _appStateService: AppStateService, private readonly _appStateService: AppStateService,
@ -64,10 +64,23 @@ export class EditDossierDialogComponent {
'dossier-info': this.generalInfoComponent, 'dossier-info': this.generalInfoComponent,
'download-package': this.downloadPackageComponent, 'download-package': this.downloadPackageComponent,
'dossier-dictionary': this.dictionaryComponent, 'dossier-dictionary': this.dictionaryComponent,
members: this.membersComponent members: this.membersComponent,
'dossier-attributes': this.attributesComponent
}[this.activeNav]; }[this.activeNav];
} }
get noPaddingTab(): boolean {
return ['dossier-attributes'].includes(this.activeNav);
}
get showHeading(): boolean {
return !['dossier-attributes'].includes(this.activeNav);
}
get showSubtitle(): boolean {
return ['dossier-dictionary'].includes(this.activeNav);
}
updatedDossier(updatedDossier: DossierWrapper) { updatedDossier(updatedDossier: DossierWrapper) {
this._notificationService.showToastNotification( this._notificationService.showToastNotification(
this._translateService.instant('edit-dossier-dialog.change-successful'), this._translateService.instant('edit-dossier-dialog.change-successful'),

View File

@ -6,14 +6,11 @@ import * as moment from 'moment';
import { DossierWrapper } from '../../../../../state/model/dossier.wrapper'; import { DossierWrapper } from '../../../../../state/model/dossier.wrapper';
import { EditDossierSectionInterface } from '../edit-dossier-section.interface'; import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service'; import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import { PermissionsService } from '../../../../../services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { MatDialogRef } from '@angular/material/dialog'; import { MatDialogRef } from '@angular/material/dialog';
import { EditDossierDialogComponent } from '../edit-dossier-dialog.component'; import { EditDossierDialogComponent } from '../edit-dossier-dialog.component';
import { import { NotificationService, NotificationType } from '@services/notification.service';
NotificationService,
NotificationType
} from '../../../../../services/notification.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@Component({ @Component({
@ -47,12 +44,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
if (this.hasDueDate !== !!this.dossierWrapper.dueDate) { if (this.hasDueDate !== !!this.dossierWrapper.dueDate) {
return true; return true;
} }
if ( if (this.hasDueDate && !moment(this.dossierWrapper.dueDate).isSame(moment(this.dossierForm.get(key).value))) {
this.hasDueDate &&
!moment(this.dossierWrapper.dueDate).isSame(
moment(this.dossierForm.get(key).value)
)
) {
return true; return true;
} }
} else if (this.dossierWrapper[key] !== this.dossierForm.get(key).value) { } else if (this.dossierWrapper[key] !== this.dossierForm.get(key).value) {

View File

@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core
import { AppStateService } from '../../../../../state/app-state.service'; import { AppStateService } from '../../../../../state/app-state.service';
import { DossierWrapper } from '../../../../../state/model/dossier.wrapper'; import { DossierWrapper } from '../../../../../state/model/dossier.wrapper';
import { EditDossierSectionInterface } from '../edit-dossier-section.interface'; import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { PermissionsService } from '../../../../../services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { TeamMembersManagerComponent } from '../../../components/team-members-manager/team-members-manager.component'; import { TeamMembersManagerComponent } from '../../../components/team-members-manager/team-members-manager.component';
@Component({ @Component({
@ -16,10 +16,7 @@ export class EditDossierTeamMembersComponent implements EditDossierSectionInterf
@ViewChild(TeamMembersManagerComponent) managerComponent: TeamMembersManagerComponent; @ViewChild(TeamMembersManagerComponent) managerComponent: TeamMembersManagerComponent;
constructor( constructor(private readonly _appStateService: AppStateService, private readonly _permissionsService: PermissionsService) {}
private readonly _appStateService: AppStateService,
private readonly _permissionsService: PermissionsService
) {}
get changed() { get changed() {
return this.managerComponent.changed; return this.managerComponent.changed;

View File

@ -10,7 +10,7 @@ import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry
import { ManualAnnotationService } from '../../services/manual-annotation.service'; import { ManualAnnotationService } from '../../services/manual-annotation.service';
import { ManualAnnotationResponse } from '@models/file/manual-annotation-response'; import { ManualAnnotationResponse } from '@models/file/manual-annotation-response';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { TypeValueWrapper } from '../../../../models/file/type-value.wrapper'; import { TypeValueWrapper } from '@models/file/type-value.wrapper';
export interface LegalBasisOption { export interface LegalBasisOption {
label?: string; label?: string;
@ -76,8 +76,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
this.isDocumentAdmin = this._permissionsService.isApprover(); this.isDocumentAdmin = this._permissionsService.isApprover();
this.isFalsePositiveRequest = this.manualRedactionEntryWrapper.type === 'FALSE_POSITIVE'; this.isFalsePositiveRequest = this.manualRedactionEntryWrapper.type === 'FALSE_POSITIVE';
this.isDictionaryRequest = this.isDictionaryRequest = this.manualRedactionEntryWrapper.type === 'DICTIONARY' || this.isFalsePositiveRequest;
this.manualRedactionEntryWrapper.type === 'DICTIONARY' || this.isFalsePositiveRequest;
this.redactionForm = this._formBuilder.group({ this.redactionForm = this._formBuilder.group({
reason: this.isDictionaryRequest ? [null] : [null, Validators.required], reason: this.isDictionaryRequest ? [null] : [null, Validators.required],
@ -87,11 +86,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
comment: this.isDocumentAdmin ? [null] : [null, Validators.required] comment: this.isDocumentAdmin ? [null] : [null, Validators.required]
}); });
for (const key of Object.keys( for (const key of Object.keys(this._appStateService.dictionaryData[this._appStateService.activeDossier.dossierTemplateId])) {
this._appStateService.dictionaryData[
this._appStateService.activeDossier.dossierTemplateId
]
)) {
const dictionaryData = this._appStateService.getDictionaryTypeValue(key); const dictionaryData = this._appStateService.getDictionaryTypeValue(key);
if (!dictionaryData.virtual && dictionaryData.addToDictionaryAction) { if (!dictionaryData.virtual && dictionaryData.addToDictionaryAction) {
this.redactionDictionaries.push(dictionaryData); this.redactionDictionaries.push(dictionaryData);
@ -102,15 +97,10 @@ export class ManualAnnotationDialogComponent implements OnInit {
handleAddRedaction() { handleAddRedaction() {
this._enhanceManualRedaction(this.manualRedactionEntryWrapper.manualRedactionEntry); this._enhanceManualRedaction(this.manualRedactionEntryWrapper.manualRedactionEntry);
this._manualAnnotationService this._manualAnnotationService.addAnnotation(this.manualRedactionEntryWrapper.manualRedactionEntry).subscribe(
.addAnnotation(this.manualRedactionEntryWrapper.manualRedactionEntry) response => this.dialogRef.close(new ManualAnnotationResponse(this.manualRedactionEntryWrapper, response)),
.subscribe( () => this.dialogRef.close()
response => );
this.dialogRef.close(
new ManualAnnotationResponse(this.manualRedactionEntryWrapper, response)
),
() => this.dialogRef.close()
);
} }
private _enhanceManualRedaction(addRedactionRequest: AddRedactionRequest) { private _enhanceManualRedaction(addRedactionRequest: AddRedactionRequest) {

View File

@ -1,8 +1,8 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { PermissionsService } from '../../../../services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AnnotationWrapper } from '../../../../models/file/annotation.wrapper'; import { AnnotationWrapper } from '@models/file/annotation.wrapper';
@Component({ @Component({
selector: 'redaction-recategorize-image-dialog', selector: 'redaction-recategorize-image-dialog',

View File

@ -46,13 +46,10 @@ import { ScrollButtonComponent } from './components/scroll-button/scroll-button.
import { ChangeLegalBasisDialogComponent } from './dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component'; import { ChangeLegalBasisDialogComponent } from './dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component';
import { PageExclusionComponent } from './components/page-exclusion/page-exclusion.component'; import { PageExclusionComponent } from './components/page-exclusion/page-exclusion.component';
import { RecategorizeImageDialogComponent } from './dialogs/recategorize-image-dialog/recategorize-image-dialog.component'; import { RecategorizeImageDialogComponent } from './dialogs/recategorize-image-dialog/recategorize-image-dialog.component';
import { EditDossierAttributesComponent } from './dialogs/edit-dossier-dialog/attributes/edit-dossier-attributes.component';
import { DossiersService } from './services/dossiers.service'; import { DossiersService } from './services/dossiers.service';
const screens = [ const screens = [DossierListingScreenComponent, DossierOverviewScreenComponent, FilePreviewScreenComponent];
DossierListingScreenComponent,
DossierOverviewScreenComponent,
FilePreviewScreenComponent
];
const dialogs = [ const dialogs = [
AddDossierDialogComponent, AddDossierDialogComponent,
@ -87,6 +84,7 @@ const components = [
EditDossierDownloadPackageComponent, EditDossierDownloadPackageComponent,
EditDossierDictionaryComponent, EditDossierDictionaryComponent,
EditDossierTeamMembersComponent, EditDossierTeamMembersComponent,
EditDossierAttributesComponent,
TeamMembersManagerComponent, TeamMembersManagerComponent,
ScrollButtonComponent, ScrollButtonComponent,
PageExclusionComponent, PageExclusionComponent,

View File

@ -23,11 +23,11 @@ import {
dossierTemplateChecker dossierTemplateChecker
} from '@shared/components/filters/popup-filter/utils/filter-utils'; } from '@shared/components/filters/popup-filter/utils/filter-utils';
import { UserPreferenceService } from '../../../../services/user-preference.service'; import { UserPreferenceService } from '../../../../services/user-preference.service';
import { ButtonConfig } from '../../../shared/components/page-header/models/button-config.model'; import { ButtonConfig } from '@shared/components/page-header/models/button-config.model';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
import { ScreenNames, SortingService } from '../../../../services/sorting.service'; import { ScreenNames, SortingService } from '../../../../services/sorting.service';
@Component({ @Component({

View File

@ -1,14 +1,4 @@
import { import { ChangeDetectorRef, Component, ElementRef, HostListener, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
ChangeDetectorRef,
Component,
ElementRef,
HostListener,
Injector,
OnDestroy,
OnInit,
TemplateRef,
ViewChild
} from '@angular/core';
import { NavigationStart, Router } from '@angular/router'; import { NavigationStart, Router } from '@angular/router';
import { NotificationService, NotificationType } from '@services/notification.service'; import { NotificationService, NotificationType } from '@services/notification.service';
import { AppStateService } from '@state/app-state.service'; import { AppStateService } from '@state/app-state.service';
@ -31,19 +21,16 @@ import { convertFiles, handleFileDrop } from '@utils/file-drop-utils';
import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { DossierWrapper } from '@state/model/dossier.wrapper'; import { DossierWrapper } from '@state/model/dossier.wrapper';
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy'; import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
import { import { annotationFilterChecker, keyChecker } from '@shared/components/filters/popup-filter/utils/filter-utils';
annotationFilterChecker,
keyChecker
} from '@shared/components/filters/popup-filter/utils/filter-utils';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model'; import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service'; import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
import { FilterConfig } from '@shared/components/page-header/models/filter-config.model'; import { FilterConfig } from '@shared/components/page-header/models/filter-config.model';
import { ActionConfig } from '@shared/components/page-header/models/action-config.model'; import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
import { FilterService } from '../../../shared/services/filter.service'; import { FilterService } from '@shared/services/filter.service';
import { SearchService } from '../../../shared/services/search.service'; import { SearchService } from '@shared/services/search.service';
import { ScreenStateService } from '../../../shared/services/screen-state.service'; import { ScreenStateService } from '@shared/services/screen-state.service';
import { ScreenNames, SortingService } from '../../../../services/sorting.service'; import { ScreenNames, SortingService } from '../../../../services/sorting.service';
import { BaseListingComponent } from '../../../shared/base/base-listing.component'; import { BaseListingComponent } from '@shared/base/base-listing.component';
@Component({ @Component({
templateUrl: './dossier-overview-screen.component.html', templateUrl: './dossier-overview-screen.component.html',
@ -103,15 +90,11 @@ export class DossierOverviewScreenComponent
} }
get checkedRequiredFilters() { get checkedRequiredFilters() {
return this.filterService return this.filterService.getFilter('quickFilters')?.values.filter(f => f.required && f.checked);
.getFilter('quickFilters')
?.values.filter(f => f.required && f.checked);
} }
get checkedNotRequiredFilters() { get checkedNotRequiredFilters() {
return this.filterService return this.filterService.getFilter('quickFilters')?.values.filter(f => !f.required && f.checked);
.getFilter('quickFilters')
?.values.filter(f => !f.required && f.checked);
} }
isLastOpenedFile(fileStatus: FileStatusWrapper): boolean { isLastOpenedFile(fileStatus: FileStatusWrapper): boolean {
@ -195,11 +178,9 @@ export class DossierOverviewScreenComponent
} }
isProcessing(fileStatusWrapper: FileStatusWrapper) { isProcessing(fileStatusWrapper: FileStatusWrapper) {
return [ return [FileStatus.StatusEnum.REPROCESS, FileStatus.StatusEnum.FULLREPROCESS, FileStatus.StatusEnum.PROCESSING].includes(
FileStatus.StatusEnum.REPROCESS, fileStatusWrapper.status
FileStatus.StatusEnum.FULLREPROCESS, );
FileStatus.StatusEnum.PROCESSING
].includes(fileStatusWrapper.status);
} }
reloadDossiers() { reloadDossiers() {
@ -280,9 +261,7 @@ export class DossierOverviewScreenComponent
} }
recentlyModifiedChecker = (file: FileStatusWrapper) => recentlyModifiedChecker = (file: FileStatusWrapper) =>
moment(file.lastUpdated) moment(file.lastUpdated).add(this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS), 'hours').isAfter(moment());
.add(this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS), 'hours')
.isAfter(moment());
private _loadEntitiesFromState() { private _loadEntitiesFromState() {
if (this.activeDossier) this._screenStateService.setEntities(this.activeDossier.files); if (this.activeDossier) this._screenStateService.setEntities(this.activeDossier.files);
@ -309,8 +288,7 @@ export class DossierOverviewScreenComponent
allDistinctFileStatusWrapper.add(file.status); allDistinctFileStatusWrapper.add(file.status);
allDistinctAddedDates.add(moment(file.added).format('DD/MM/YYYY')); allDistinctAddedDates.add(moment(file.added).format('DD/MM/YYYY'));
if (this.permissionsService.fileRequiresReanalysis(file)) if (this.permissionsService.fileRequiresReanalysis(file)) allDistinctNeedsWork.add('analysis');
allDistinctNeedsWork.add('analysis');
if (file.hintsOnly) allDistinctNeedsWork.add('hint'); if (file.hintsOnly) allDistinctNeedsWork.add('hint');
if (file.hasRedactions) allDistinctNeedsWork.add('redaction'); if (file.hasRedactions) allDistinctNeedsWork.add('redaction');
if (file.hasRequests) allDistinctNeedsWork.add('suggestion'); if (file.hasRequests) allDistinctNeedsWork.add('suggestion');
@ -377,10 +355,7 @@ export class DossierOverviewScreenComponent
checker: (file: FileStatusWrapper) => checker: (file: FileStatusWrapper) =>
this.checkedRequiredFilters.reduce((acc, f) => acc && f.checker(file), true) && this.checkedRequiredFilters.reduce((acc, f) => acc && f.checker(file), true) &&
(this.checkedNotRequiredFilters.length === 0 || (this.checkedNotRequiredFilters.length === 0 ||
this.checkedNotRequiredFilters.reduce( this.checkedNotRequiredFilters.reduce((acc, f) => acc || f.checker(file), false))
(acc, f) => acc || f.checker(file),
false
))
}); });
this._createActionConfigs(); this._createActionConfigs();
@ -389,9 +364,7 @@ export class DossierOverviewScreenComponent
private _createQuickFilters() { private _createQuickFilters() {
let quickFilters = []; let quickFilters = [];
if (this._screenStateService.entities.filter(this.recentlyModifiedChecker).length > 0) { if (this._screenStateService.entities.filter(this.recentlyModifiedChecker).length > 0) {
const recentPeriod = this._appConfigService.getConfig( const recentPeriod = this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS);
AppConfigKey.RECENT_PERIOD_IN_HOURS
);
quickFilters = [ quickFilters = [
{ {
key: 'recent', key: 'recent',
@ -408,9 +381,7 @@ export class DossierOverviewScreenComponent
...quickFilters, ...quickFilters,
{ {
key: 'assigned-to-me', key: 'assigned-to-me',
label: this._translateService.instant( label: this._translateService.instant('dossier-overview.quick-filters.assigned-to-me'),
'dossier-overview.quick-filters.assigned-to-me'
),
checker: (file: FileStatusWrapper) => file.currentReviewer === this.user.id checker: (file: FileStatusWrapper) => file.currentReviewer === this.user.id
}, },
{ {
@ -420,11 +391,8 @@ export class DossierOverviewScreenComponent
}, },
{ {
key: 'assigned-to-others', key: 'assigned-to-others',
label: this._translateService.instant( label: this._translateService.instant('dossier-overview.quick-filters.assigned-to-others'),
'dossier-overview.quick-filters.assigned-to-others' checker: (file: FileStatusWrapper) => !!file.currentReviewer && file.currentReviewer !== this.user.id
),
checker: (file: FileStatusWrapper) =>
!!file.currentReviewer && file.currentReviewer !== this.user.id
} }
]; ];
} }

View File

@ -1,12 +1,4 @@
import { import { ChangeDetectorRef, Component, HostListener, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core';
ChangeDetectorRef,
Component,
HostListener,
NgZone,
OnDestroy,
OnInit,
ViewChild
} from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router'; import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
import { AppStateService } from '@state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { Annotations, WebViewerInstance } from '@pdftron/webviewer'; import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
@ -41,11 +33,8 @@ import { FileWorkloadComponent } from '../../components/file-workload/file-workl
import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy'; import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model'; import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
import { import { handleFilterDelta, processFilters } from '@shared/components/filters/popup-filter/utils/filter-utils';
handleFilterDelta, import { LoadingService } from '@services/loading.service';
processFilters
} from '@shared/components/filters/popup-filter/utils/filter-utils';
import { LoadingService } from '../../../../services/loading.service';
import { stampPDFPage } from '../../../../utils/page-stamper'; import { stampPDFPage } from '../../../../utils/page-stamper';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -117,9 +106,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
} }
get assignTooltip(): string { get assignTooltip(): string {
return this.appStateService.activeFile.isUnderApproval return this.appStateService.activeFile.isUnderApproval ? 'dossier-overview.assign-approver' : this.assignOrChangeReviewerTooltip;
? 'dossier-overview.assign-approver'
: this.assignOrChangeReviewerTooltip;
} }
get annotations(): AnnotationWrapper[] { get annotations(): AnnotationWrapper[] {
@ -139,25 +126,15 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
} }
get canSwitchToRedactedView() { get canSwitchToRedactedView() {
return ( return this.fileData && !this.permissionsService.fileRequiresReanalysis() && !this.fileData.fileStatus.isExcluded;
this.fileData &&
!this.permissionsService.fileRequiresReanalysis() &&
!this.fileData.fileStatus.isExcluded
);
} }
get canSwitchToDeltaView() { get canSwitchToDeltaView() {
return ( return this.fileData?.redactionChangeLog?.redactionLogEntry?.length > 0 && !this.fileData.fileStatus.isExcluded;
this.fileData?.redactionChangeLog?.redactionLogEntry?.length > 0 &&
!this.fileData.fileStatus.isExcluded
);
} }
get canAssign(): boolean { get canAssign(): boolean {
return ( return !this.editingReviewer && (this.permissionsService.canAssignUser() || this.permissionsService.canAssignToSelf());
!this.editingReviewer &&
(this.permissionsService.canAssignUser() || this.permissionsService.canAssignToSelf())
);
} }
get displayData() { get displayData() {
@ -181,9 +158,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
} }
get assignOrChangeReviewerTooltip() { get assignOrChangeReviewerTooltip() {
return this.currentReviewer return this.currentReviewer ? 'file-preview.change-reviewer' : 'file-preview.assign-reviewer';
? 'file-preview.change-reviewer'
: 'file-preview.assign-reviewer';
} }
get currentReviewer(): string { get currentReviewer(): string {
@ -204,9 +179,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
get canAssignReviewer(): boolean { get canAssignReviewer(): boolean {
return ( return (
!this.currentReviewer && !this.currentReviewer && this.permissionsService.canAssignUser() && this.appStateService.activeDossier.hasMoreThanOneReviewer
this.permissionsService.canAssignUser() &&
this.appStateService.activeDossier.hasMoreThanOneReviewer
); );
} }
@ -217,12 +190,8 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
switch (this.viewMode) { switch (this.viewMode) {
case 'STANDARD': { case 'STANDARD': {
this._setAnnotationsColor(redactions, 'annotationColor'); this._setAnnotationsColor(redactions, 'annotationColor');
const standardEntries = annotations.filter( const standardEntries = annotations.filter(a => !a.getCustomData('changeLogRemoved'));
a => !a.getCustomData('changeLogRemoved') const nonStandardEntries = annotations.filter(a => a.getCustomData('changeLogRemoved'));
);
const nonStandardEntries = annotations.filter(a =>
a.getCustomData('changeLogRemoved')
);
this._show(standardEntries); this._show(standardEntries);
this._hide(nonStandardEntries); this._hide(nonStandardEntries);
break; break;
@ -271,9 +240,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
this._updateCanPerformActions(); this._updateCanPerformActions();
try { try {
const key = 'Dossier-Recent-' + this.dossierId; const key = 'Dossier-Recent-' + this.dossierId;
await this._userPreferenceControllerService await this._userPreferenceControllerService.savePreferences([this.fileId], key).toPromise();
.savePreferences([this.fileId], key)
.toPromise();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} }
@ -299,35 +266,22 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
console.error(error); console.error(error);
} }
} }
console.log( console.log('[REDACTION] Delete previous annotations time: ' + (new Date().getTime() - startTime) + 'ms');
'[REDACTION] Delete previous annotations time: ' +
(new Date().getTime() - startTime) +
'ms'
);
const processStartTime = new Date().getTime(); const processStartTime = new Date().getTime();
this.annotationData = this.fileData.getAnnotations( this.annotationData = this.fileData.getAnnotations(
this.appStateService.dictionaryData[ this.appStateService.dictionaryData[this.appStateService.activeDossier.dossierTemplateId],
this.appStateService.activeDossier.dossierTemplateId
],
this.permissionsService.currentUser, this.permissionsService.currentUser,
this.viewMode, this.viewMode,
this.userPreferenceService.areDevFeaturesEnabled this.userPreferenceService.areDevFeaturesEnabled
); );
const annotationFilters = this._annotationProcessingService.getAnnotationFilter( const annotationFilters = this._annotationProcessingService.getAnnotationFilter(this.annotations);
this.annotations
);
this.primaryFilters = processFilters(this.primaryFilters, annotationFilters); this.primaryFilters = processFilters(this.primaryFilters, annotationFilters);
this.secondaryFilters = processFilters( this.secondaryFilters = processFilters(this.secondaryFilters, AnnotationProcessingService.secondaryAnnotationFilters);
this.secondaryFilters,
AnnotationProcessingService.secondaryAnnotationFilters
);
this._workloadComponent?.filtersChanged({ this._workloadComponent?.filtersChanged({
primary: this.primaryFilters, primary: this.primaryFilters,
secondary: this.secondaryFilters secondary: this.secondaryFilters
}); });
console.log( console.log('[REDACTION] Process time: ' + (new Date().getTime() - processStartTime) + 'ms');
'[REDACTION] Process time: ' + (new Date().getTime() - processStartTime) + 'ms'
);
console.log( console.log(
'[REDACTION] Annotation Redraw and filter rebuild time: ' + '[REDACTION] Annotation Redraw and filter rebuild time: ' +
(new Date().getTime() - startTime) + (new Date().getTime() - startTime) +
@ -348,11 +302,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
this._changeDetectorRef.detectChanges(); this._changeDetectorRef.detectChanges();
} }
selectAnnotations( selectAnnotations(annotations?: AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }) {
annotations?:
| AnnotationWrapper[]
| { annotations: AnnotationWrapper[]; multiSelect: boolean }
) {
if (annotations) { if (annotations) {
this.viewerComponent.utils.selectAnnotations(annotations); this.viewerComponent.utils.selectAnnotations(annotations);
} else { } else {
@ -371,24 +321,19 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
openManualAnnotationDialog($event: ManualRedactionEntryWrapper) { openManualAnnotationDialog($event: ManualRedactionEntryWrapper) {
this._ngZone.run(() => { this._ngZone.run(() => {
this.dialogRef = this._dialogService.openManualAnnotationDialog( this.dialogRef = this._dialogService.openManualAnnotationDialog($event, async (response: ManualAnnotationResponse) => {
$event, if (response?.annotationId) {
async (response: ManualAnnotationResponse) => { const annotation = this._instance.annotManager.getAnnotationById(response.manualRedactionEntryWrapper.rectId);
if (response?.annotationId) { this._instance.annotManager.deleteAnnotation(annotation);
const annotation = this._instance.annotManager.getAnnotationById( this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
response.manualRedactionEntryWrapper.rectId const distinctPages = $event.manualRedactionEntry.positions
); .map(p => p.page)
this._instance.annotManager.deleteAnnotation(annotation); .filter((item, pos, self) => self.indexOf(item) === pos);
this.fileData.fileStatus = await this.appStateService.reloadActiveFile(); distinctPages.forEach(page => {
const distinctPages = $event.manualRedactionEntry.positions this._cleanupAndRedrawManualAnnotationsForEntirePage(page);
.map(p => p.page) });
.filter((item, pos, self) => self.indexOf(item) === pos);
distinctPages.forEach(page => {
this._cleanupAndRedrawManualAnnotationsForEntirePage(page);
});
}
} }
); });
}); });
} }
@ -407,10 +352,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
return; return;
} }
if ( if (!ALL_HOTKEY_ARRAY.includes($event.key) || this.dialogRef?.getState() === MatDialogState.OPEN) {
!ALL_HOTKEY_ARRAY.includes($event.key) ||
this.dialogRef?.getState() === MatDialogState.OPEN
) {
return; return;
} }
@ -524,9 +466,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
const reviewerName = this.userService.getNameForId(reviewerId); const reviewerName = this.userService.getNameForId(reviewerId);
const { dossierId, fileId, filename } = this.fileData.fileStatus; const { dossierId, fileId, filename } = this.fileData.fileStatus;
await this._statusControllerService await this._statusControllerService.setFileReviewer(dossierId, fileId, reviewerId).toPromise();
.setFileReviewer(dossierId, fileId, reviewerId)
.toPromise();
const msg = `Successfully assigned ${reviewerName} to file: ${filename}`; const msg = `Successfully assigned ${reviewerName} to file: ${filename}`;
this._notificationService.showToastNotification(msg); this._notificationService.showToastNotification(msg);
@ -549,13 +489,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
downloadOriginalFile() { downloadOriginalFile() {
this._fileManagementControllerService this._fileManagementControllerService
.downloadOriginalFile( .downloadOriginalFile(this.dossierId, this.fileId, true, this.fileData.fileStatus.cacheIdentifier, 'response')
this.dossierId,
this.fileId,
true,
this.fileData.fileStatus.cacheIdentifier,
'response'
)
.subscribe(data => { .subscribe(data => {
download(data, this.fileData.fileStatus.filename); download(data, this.fileData.fileStatus.filename);
}); });
@ -608,17 +542,15 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
this.filesAutoUpdateTimer = timer(0, 5000) this.filesAutoUpdateTimer = timer(0, 5000)
.pipe(tap(async () => await this.appStateService.reloadActiveFile())) .pipe(tap(async () => await this.appStateService.reloadActiveFile()))
.subscribe(); .subscribe();
this.fileReanalysedSubscription = this.appStateService.fileReanalysed.subscribe( this.fileReanalysedSubscription = this.appStateService.fileReanalysed.subscribe(async (fileStatus: FileStatusWrapper) => {
async (fileStatus: FileStatusWrapper) => { if (fileStatus.fileId === this.fileId) {
if (fileStatus.fileId === this.fileId) { await this._loadFileData(!this._reloadFileOnReanalysis);
await this._loadFileData(!this._reloadFileOnReanalysis); this._reloadFileOnReanalysis = false;
this._reloadFileOnReanalysis = false; this.viewReady = true;
this.viewReady = true; this._updateCanPerformActions();
this._updateCanPerformActions(); this._cleanupAndRedrawManualAnnotations();
this._cleanupAndRedrawManualAnnotations();
}
} }
); });
} }
private _unsubscribeFromFileUpdates(): void { private _unsubscribeFromFileUpdates(): void {
@ -663,10 +595,8 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
/* Get the documentElement (<html>) to display the page in fullscreen */ /* Get the documentElement (<html>) to display the page in fullscreen */
private _cleanupAndRedrawManualAnnotations() { private _cleanupAndRedrawManualAnnotations() {
this._fileDownloadService this._fileDownloadService.loadActiveFileRedactionLogPreview().subscribe(redactionLogPreview => {
.loadActiveFileRedactionLogPreview() this.fileData.redactionLog = redactionLogPreview;
.subscribe(redactionLogPreview => {
this.fileData.redactionLog = redactionLogPreview;
this._annotationDrawService.drawAnnotations( this._annotationDrawService.drawAnnotations(
this._instance, this._instance,
this.annotationData.allAnnotations, this.annotationData.allAnnotations,
@ -681,18 +611,14 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
const currentPageAnnotationIds = currentPageAnnotations.map(a => a.id); const currentPageAnnotationIds = currentPageAnnotations.map(a => a.id);
this.fileData.fileStatus = await this.appStateService.reloadActiveFile(); this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
this._fileDownloadService this._fileDownloadService.loadActiveFileRedactionLogPreview().subscribe(redactionLogPreview => {
.loadActiveFileRedactionLogPreview() this.fileData.redactionLog = redactionLogPreview;
.subscribe(redactionLogPreview => {
this.fileData.redactionLog = redactionLogPreview;
this.rebuildFilters(); this.rebuildFilters();
if (this.viewMode === 'STANDARD') { if (this.viewMode === 'STANDARD') {
currentPageAnnotationIds.forEach(id => { currentPageAnnotationIds.forEach(id => {
this._findAndDeleteAnnotation(id); this._findAndDeleteAnnotation(id);
}); });
const newPageAnnotations = this.annotations.filter( const newPageAnnotations = this.annotations.filter(item => item.pageNumber === page);
item => item.pageNumber === page
);
this._handleDeltaAnnotationFilters(currentPageAnnotations, newPageAnnotations); this._handleDeltaAnnotationFilters(currentPageAnnotations, newPageAnnotations);
this._annotationDrawService.drawAnnotations( this._annotationDrawService.drawAnnotations(
this._instance, this._instance,
@ -704,22 +630,16 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
}); });
} }
private _handleDeltaAnnotationFilters( private _handleDeltaAnnotationFilters(currentPageAnnotations: AnnotationWrapper[], newPageAnnotations: AnnotationWrapper[]) {
currentPageAnnotations: AnnotationWrapper[],
newPageAnnotations: AnnotationWrapper[]
) {
const hasAnyFilterSet = const hasAnyFilterSet =
this.primaryFilters.find(f => f.checked || f.indeterminate) || this.primaryFilters.find(f => f.checked || f.indeterminate) || this.secondaryFilters.find(f => f.checked || f.indeterminate);
this.secondaryFilters.find(f => f.checked || f.indeterminate);
if (!hasAnyFilterSet) { if (!hasAnyFilterSet) {
return; return;
} }
const oldPageSpecificFilters = const oldPageSpecificFilters = this._annotationProcessingService.getAnnotationFilter(currentPageAnnotations);
this._annotationProcessingService.getAnnotationFilter(currentPageAnnotations); const newPageSpecificFilters = this._annotationProcessingService.getAnnotationFilter(newPageAnnotations);
const newPageSpecificFilters =
this._annotationProcessingService.getAnnotationFilter(newPageAnnotations);
handleFilterDelta(oldPageSpecificFilters, newPageSpecificFilters, this.primaryFilters); handleFilterDelta(oldPageSpecificFilters, newPageSpecificFilters, this.primaryFilters);
this._workloadComponent.filtersChanged({ this._workloadComponent.filtersChanged({
primary: this.primaryFilters, primary: this.primaryFilters,

View File

@ -17,12 +17,12 @@ import { ManualAnnotationService } from './manual-annotation.service';
import { ManualAnnotationDialogComponent } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component'; import { ManualAnnotationDialogComponent } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component';
import { DossierDictionaryDialogComponent } from '../dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component'; import { DossierDictionaryDialogComponent } from '../dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component';
import { EditDossierDialogComponent } from '../dialogs/edit-dossier-dialog/edit-dossier-dialog.component'; import { EditDossierDialogComponent } from '../dialogs/edit-dossier-dialog/edit-dossier-dialog.component';
import { FileStatusWrapper } from '../../../models/file/file-status.wrapper'; import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { AssignReviewerApproverDialogComponent } from '../dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component'; import { AssignReviewerApproverDialogComponent } from '../dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component';
import { AppConfigService } from '../../app-config/app-config.service'; import { AppConfigService } from '../../app-config/app-config.service';
import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component'; import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component';
import { RecategorizeImageDialogComponent } from '../dialogs/recategorize-image-dialog/recategorize-image-dialog.component'; import { RecategorizeImageDialogComponent } from '../dialogs/recategorize-image-dialog/recategorize-image-dialog.component';
import { DialogService } from '../../shared/services/dialog.service'; import { DialogService } from '@shared/services/dialog.service';
import { ComponentType } from '@angular/cdk/portal'; import { ComponentType } from '@angular/cdk/portal';
const dialogConfig = { const dialogConfig = {
@ -67,10 +67,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
super(_dialog); super(_dialog);
} }
openManualAnnotationDialog( openManualAnnotationDialog($event: ManualRedactionEntryWrapper, cb?: Function): MatDialogRef<ManualAnnotationDialogComponent> {
$event: ManualRedactionEntryWrapper,
cb?: Function
): MatDialogRef<ManualAnnotationDialogComponent> {
const ref = this._dialog.open(ManualAnnotationDialogComponent, { const ref = this._dialog.open(ManualAnnotationDialogComponent, {
...dialogConfig, ...dialogConfig,
autoFocus: true, autoFocus: true,
@ -96,13 +93,11 @@ export class DossiersDialogService extends DialogService<DialogType> {
const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig); const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig);
ref.afterClosed().subscribe(result => { ref.afterClosed().subscribe(result => {
if (result) { if (result) {
this._manualAnnotationService this._manualAnnotationService.approveRequest(annotation.id).subscribe(acceptResult => {
.approveRequest(annotation.id) if (callback) {
.subscribe(acceptResult => { callback(acceptResult);
if (callback) { }
callback(acceptResult); });
}
});
} }
}); });
@ -132,10 +127,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
return ref; return ref;
} }
openForceRedactionDialog( openForceRedactionDialog($event: MouseEvent, cb?: Function): MatDialogRef<ForceRedactionDialogComponent> {
$event: MouseEvent,
cb?: Function
): MatDialogRef<ForceRedactionDialogComponent> {
$event?.stopPropagation(); $event?.stopPropagation();
const ref = this._dialog.open(ForceRedactionDialogComponent, { const ref = this._dialog.open(ForceRedactionDialogComponent, {
...dialogConfig ...dialogConfig
@ -203,11 +195,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
return ref; return ref;
} }
openDeleteDossierDialog( openDeleteDossierDialog($event: MouseEvent, dossier: DossierWrapper, cb?: Function): MatDialogRef<ConfirmationDialogComponent> {
$event: MouseEvent,
dossier: DossierWrapper,
cb?: Function
): MatDialogRef<ConfirmationDialogComponent> {
$event.stopPropagation(); $event.stopPropagation();
const period = this._appConfigService.getConfig('DELETE_RETENTION_HOURS'); const period = this._appConfigService.getConfig('DELETE_RETENTION_HOURS');
const ref = this._dialog.open(ConfirmationDialogComponent, { const ref = this._dialog.open(ConfirmationDialogComponent, {
@ -299,11 +287,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
return ref; return ref;
} }
openRemoveAnnotationModal( openRemoveAnnotationModal($event: MouseEvent, annotation: AnnotationWrapper, callback: () => void) {
$event: MouseEvent,
annotation: AnnotationWrapper,
callback: () => void
) {
$event?.stopPropagation(); $event?.stopPropagation();
const ref = this._dialog.open(ConfirmationDialogComponent, { const ref = this._dialog.open(ConfirmationDialogComponent, {
@ -313,13 +297,11 @@ export class DossiersDialogService extends DialogService<DialogType> {
ref.afterClosed().subscribe(result => { ref.afterClosed().subscribe(result => {
if (result) { if (result) {
this._manualAnnotationService this._manualAnnotationService.removeOrSuggestRemoveAnnotation(annotation).subscribe(() => {
.removeOrSuggestRemoveAnnotation(annotation) if (callback) {
.subscribe(() => { callback();
if (callback) { }
callback(); });
}
});
} }
}); });

View File

@ -1,8 +1,8 @@
import { Annotations, WebViewerInstance } from '@pdftron/webviewer'; import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
import { ViewMode } from '../../../models/file/view-mode'; import { ViewMode } from '@models/file/view-mode';
import { translateQuads } from '../../../utils/pdf-coordinates'; import { translateQuads } from '../../../utils/pdf-coordinates';
import { Rectangle } from '@redaction/red-ui-http'; import { Rectangle } from '@redaction/red-ui-http';
import { AnnotationWrapper } from '../../../models/file/annotation.wrapper'; import { AnnotationWrapper } from '@models/file/annotation.wrapper';
const DISABLED_HOTKEYS = [ const DISABLED_HOTKEYS = [
'CTRL+SHIFT+EQUAL', 'CTRL+SHIFT+EQUAL',
@ -74,9 +74,7 @@ export class PdfViewerUtils {
} }
try { try {
return this.isCompareMode return this.isCompareMode ? Math.ceil(this.instance?.docViewer?.getPageCount() / 2) : this.instance?.docViewer?.getPageCount();
? Math.ceil(this.instance?.docViewer?.getPageCount() / 2)
: this.instance?.docViewer?.getPageCount();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
return null; return null;
@ -93,9 +91,7 @@ export class PdfViewerUtils {
navigateToPage(pageNumber: string | number) { navigateToPage(pageNumber: string | number) {
const parsedNumber = typeof pageNumber === 'string' ? parseInt(pageNumber, 10) : pageNumber; const parsedNumber = typeof pageNumber === 'string' ? parseInt(pageNumber, 10) : pageNumber;
this._navigateToPage( this._navigateToPage(this.paginationOffset === 2 ? parsedNumber * this.paginationOffset - 1 : parsedNumber);
this.paginationOffset === 2 ? parsedNumber * this.paginationOffset - 1 : parsedNumber
);
} }
previousPage() { previousPage() {
@ -106,12 +102,7 @@ export class PdfViewerUtils {
nextPage() { nextPage() {
if (this._currentInternalPage < this._totalInternalPages) { if (this._currentInternalPage < this._totalInternalPages) {
this._navigateToPage( this._navigateToPage(Math.min(this._currentInternalPage + this.paginationOffset, this._totalInternalPages));
Math.min(
this._currentInternalPage + this.paginationOffset,
this._totalInternalPages
)
);
} }
} }
@ -144,9 +135,7 @@ export class PdfViewerUtils {
this.instance.annotManager.deselectAllAnnotations(); this.instance.annotManager.deselectAllAnnotations();
} }
selectAnnotations( selectAnnotations($event: AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }) {
$event: AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }
) {
let annotations: AnnotationWrapper[]; let annotations: AnnotationWrapper[];
let multiSelect: boolean; let multiSelect: boolean;
if ($event instanceof Array) { if ($event instanceof Array) {

View File

@ -14,11 +14,7 @@ export function processFilters(oldFilters: FilterModel[], newFilters: FilterMode
return newFilters; return newFilters;
} }
export function handleFilterDelta( export function handleFilterDelta(oldFilters: FilterModel[], newFilters: FilterModel[], allFilters: FilterModel[]) {
oldFilters: FilterModel[],
newFilters: FilterModel[],
allFilters: FilterModel[]
) {
const newFiltersDelta = {}; const newFiltersDelta = {};
for (const newFilter of newFilters) { for (const newFilter of newFilters) {
const oldFilter = oldFilters.find(f => f.key === newFilter.key); const oldFilter = oldFilters.find(f => f.key === newFilter.key);
@ -87,13 +83,7 @@ export function handleCheckedValue(filter: FilterModel) {
} }
} }
export function checkFilter( export function checkFilter(entity: any, filters: FilterModel[], validate: Function, validateArgs: any = [], matchAll: boolean = false) {
entity: any,
filters: FilterModel[],
validate: Function,
validateArgs: any = [],
matchAll: boolean = false
) {
const hasChecked = filters.find(f => f.checked); const hasChecked = filters.find(f => f.checked);
if (validateArgs) { if (validateArgs) {
@ -121,8 +111,7 @@ export function checkFilter(
return filterMatched; return filterMatched;
} }
export const keyChecker = (key: string) => (entity: any, filter: FilterModel) => export const keyChecker = (key: string) => (entity: any, filter: FilterModel) => entity[key] === filter.key;
entity[key] === filter.key;
export const annotationFilterChecker = ( export const annotationFilterChecker = (
input: FileStatusWrapper | DossierWrapper, input: FileStatusWrapper | DossierWrapper,
@ -158,38 +147,24 @@ export const annotationFilterChecker = (
} }
}; };
export const dossierStatusChecker = (dw: DossierWrapper, filter: FilterModel) => export const dossierStatusChecker = (dw: DossierWrapper, filter: FilterModel) => dw.hasStatus(filter.key);
dw.hasStatus(filter.key);
export const dossierMemberChecker = (dw: DossierWrapper, filter: FilterModel) => export const dossierMemberChecker = (dw: DossierWrapper, filter: FilterModel) => dw.hasMember(filter.key);
dw.hasMember(filter.key);
export const dossierTemplateChecker = (dw: DossierWrapper, filter: FilterModel) => export const dossierTemplateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.dossierTemplateId === filter.key;
dw.dossierTemplateId === filter.key;
export const dueDateChecker = (dw: DossierWrapper, filter: FilterModel) => export const dueDateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.dueDateMatches(filter.key);
dw.dueDateMatches(filter.key);
export const addedDateChecker = (dw: DossierWrapper, filter: FilterModel) => export const addedDateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.addedDateMatches(filter.key);
dw.addedDateMatches(filter.key);
export const dossierApproverChecker = (dw: DossierWrapper, filter: FilterModel) => export const dossierApproverChecker = (dw: DossierWrapper, filter: FilterModel) => dw.approverIds.includes(filter.key);
dw.approverIds.includes(filter.key);
export function getFilteredEntities<T>(entities: T[], filters: FilterWrapper[]) { export function getFilteredEntities<T>(entities: T[], filters: FilterWrapper[]) {
const filteredEntities: T[] = []; const filteredEntities: T[] = [];
for (const entity of entities) { for (const entity of entities) {
let add = true; let add = true;
for (const filter of filters) { for (const filter of filters) {
add = add = add && checkFilter(entity, filter.values, filter.checker, filter.checkerArgs, filter.matchAll);
add &&
checkFilter(
entity,
filter.values,
filter.checker,
filter.checkerArgs,
filter.matchAll
);
} }
if (add) { if (add) {
filteredEntities.push(entity); filteredEntities.push(entity);

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs'; import { Observable, throwError } from 'rxjs';
import { NotificationService, NotificationType } from '../../../services/notification.service'; import { NotificationService, NotificationType } from '@services/notification.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { DictionaryControllerService } from '@redaction/red-ui-http'; import { DictionaryControllerService } from '@redaction/red-ui-http';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
@ -36,20 +36,9 @@ export class DictionarySaveService {
// can add at least 1 - block UI // can add at least 1 - block UI
let obs: Observable<any>; let obs: Observable<any>;
if (entriesToAdd.length > 0) { if (entriesToAdd.length > 0) {
obs = this._dictionaryControllerService.addEntry( obs = this._dictionaryControllerService.addEntry(entriesToAdd, dossierTemplateId, type, dossierId, true);
entriesToAdd,
dossierTemplateId,
type,
dossierId,
true
);
} else { } else {
obs = this._dictionaryControllerService.deleteEntries( obs = this._dictionaryControllerService.deleteEntries(initialEntries, dossierTemplateId, type, dossierId);
initialEntries,
dossierTemplateId,
type,
dossierId
);
} }
return obs.pipe( return obs.pipe(
@ -57,9 +46,7 @@ export class DictionarySaveService {
() => { () => {
if (showToast) { if (showToast) {
this._notificationService.showToastNotification( this._notificationService.showToastNotification(
this._translateService.instant( this._translateService.instant('dictionary-overview.success.generic'),
'dictionary-overview.success.generic'
),
null, null,
NotificationType.SUCCESS NotificationType.SUCCESS
); );

View File

@ -831,7 +831,9 @@
"general-info": "General Information", "general-info": "General Information",
"members": "Members", "members": "Members",
"report-attributes": "Report Attributes", "report-attributes": "Report Attributes",
"team-members": "Team Members" "team-members": "Team Members",
"custom-dossier-attributes": "Custom Dossier Attributes",
"image-attributes": "Image Attributes"
}, },
"unsaved-changes": "You have unsaved changes. Save or revert before changing the tab." "unsaved-changes": "You have unsaved changes. Save or revert before changing the tab."
}, },