Edit dossier attributes WIP
This commit is contained in:
parent
e3beeae0e3
commit
efa4e76f62
@ -4,7 +4,7 @@ import { AppStateService } from '@state/app-state.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { DossierTemplateControllerService } from '@redaction/red-ui-http';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossier-template-actions',
|
||||
@ -33,22 +33,15 @@ export class DossierTemplateActionsComponent {
|
||||
}
|
||||
|
||||
openEditDossierTemplateDialog($event: any) {
|
||||
this._dialogService.openDialog(
|
||||
'addEditDossierTemplate',
|
||||
$event,
|
||||
this.dossierTemplate,
|
||||
() => {
|
||||
this.loadDossierTemplatesData?.emit();
|
||||
}
|
||||
);
|
||||
this._dialogService.openDialog('addEditDossierTemplate', $event, this.dossierTemplate, () => {
|
||||
this.loadDossierTemplatesData?.emit();
|
||||
});
|
||||
}
|
||||
|
||||
openDeleteDossierTemplateDialog($event?: MouseEvent) {
|
||||
this._dialogService.openDialog('confirm', $event, null, async () => {
|
||||
this._loadingService.start();
|
||||
await this._dossierTemplateControllerService
|
||||
.deleteDossierTemplates([this.dossierTemplateId])
|
||||
.toPromise();
|
||||
await this._dossierTemplateControllerService.deleteDossierTemplates([this.dossierTemplateId]).toPromise();
|
||||
await this._appStateService.loadAllDossierTemplates();
|
||||
await this._appStateService.loadDictionaryData();
|
||||
await this._router.navigate(['main', 'admin']);
|
||||
|
||||
@ -5,7 +5,7 @@ import { DictionaryControllerService, TypeValue } from '@redaction/red-ui-http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { NotificationService, NotificationType } from '@services/notification.service';
|
||||
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';
|
||||
|
||||
@Component({
|
||||
@ -78,11 +78,7 @@ export class AddEditDictionaryDialogComponent {
|
||||
|
||||
if (this.dictionary) {
|
||||
// edit mode
|
||||
observable = this._dictionaryControllerService.updateType(
|
||||
typeValue,
|
||||
this._dossierTemplateId,
|
||||
typeValue.type
|
||||
);
|
||||
observable = this._dictionaryControllerService.updateType(typeValue, this._dossierTemplateId, typeValue.type);
|
||||
} else {
|
||||
// create mode
|
||||
typeValue.dossierTemplateId = this._dossierTemplateId;
|
||||
@ -104,11 +100,7 @@ export class AddEditDictionaryDialogComponent {
|
||||
}
|
||||
|
||||
private _notifyError(message: string) {
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant(message),
|
||||
null,
|
||||
NotificationType.ERROR
|
||||
);
|
||||
this._notificationService.showToastNotification(this._translateService.instant(message), null, NotificationType.ERROR);
|
||||
}
|
||||
|
||||
private _formToObject(): TypeValue {
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
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 { LoadingService } from '../../../../services/loading.service';
|
||||
import { ErrorMessageService } from '../../../../services/error-message.service';
|
||||
import { NotificationService, NotificationType } from '../../../../services/notification.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { ErrorMessageService } from '@services/error-message.service';
|
||||
import { NotificationService, NotificationType } from '@services/notification.service';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { UserService } from '../../../../../services/user.service';
|
||||
import { LoadingService } from '../../../../../services/loading.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-reset-password',
|
||||
|
||||
@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||
import { LoadingService } from '../../../../../services/loading.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-user-details',
|
||||
@ -64,10 +64,7 @@ export class UserDetailsComponent implements OnInit {
|
||||
disabled:
|
||||
this.user &&
|
||||
Object.keys(this._ROLE_REQUIREMENTS).reduce(
|
||||
(value, key) =>
|
||||
value ||
|
||||
(role === this._ROLE_REQUIREMENTS[key] &&
|
||||
this.user.roles.indexOf(key) !== -1),
|
||||
(value, key) => value || (role === this._ROLE_REQUIREMENTS[key] && this.user.roles.indexOf(key) !== -1),
|
||||
false
|
||||
)
|
||||
}
|
||||
@ -79,7 +76,10 @@ export class UserDetailsComponent implements OnInit {
|
||||
firstName: [this.user?.firstName, Validators.required],
|
||||
lastName: [this.user?.lastName, Validators.required],
|
||||
email: [
|
||||
{ value: this.user?.email, disabled: !!this.user },
|
||||
{
|
||||
value: this.user?.email,
|
||||
disabled: !!this.user
|
||||
},
|
||||
[Validators.required, Validators.email]
|
||||
],
|
||||
...rolesControls
|
||||
|
||||
@ -2,7 +2,7 @@ import { Component, Inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-confirm-delete-users-dialog',
|
||||
@ -45,9 +45,7 @@ export class ConfirmDeleteUsersDialogComponent {
|
||||
async deleteUser() {
|
||||
if (this.valid) {
|
||||
this._loadingService.start();
|
||||
await this._userControllerService
|
||||
.deleteUsers(this.users.map(u => u.userId))
|
||||
.toPromise();
|
||||
await this._userControllerService.deleteUsers(this.users.map(u => u.userId)).toPromise();
|
||||
this.dialogRef.close(true);
|
||||
} else {
|
||||
this.showToast = true;
|
||||
|
||||
@ -1,19 +1,11 @@
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Injector,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output,
|
||||
SimpleChanges
|
||||
} from '@angular/core';
|
||||
import { Component, EventEmitter, Injector, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { Field } from '../file-attributes-csv-import-dialog.component';
|
||||
import { FileAttributeConfig } from '@redaction/red-ui-http';
|
||||
import { FilterService } from '../../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../../shared/services/screen-state.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { SortingService } from '../../../../../services/sorting.service';
|
||||
import { BaseListingComponent } from '../../../../shared/base/base-listing.component';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-active-fields-listing',
|
||||
@ -27,11 +19,7 @@ export class ActiveFieldsListingComponent extends BaseListingComponent<Field> im
|
||||
@Output() setHoveredColumn = new EventEmitter<string>();
|
||||
@Output() toggleFieldActive = new EventEmitter<Field>();
|
||||
|
||||
readonly typeOptions = [
|
||||
FileAttributeConfig.TypeEnum.TEXT,
|
||||
FileAttributeConfig.TypeEnum.NUMBER,
|
||||
FileAttributeConfig.TypeEnum.DATE
|
||||
];
|
||||
readonly typeOptions = [FileAttributeConfig.TypeEnum.TEXT, FileAttributeConfig.TypeEnum.NUMBER, FileAttributeConfig.TypeEnum.DATE];
|
||||
|
||||
constructor(protected readonly _injector: Injector) {
|
||||
super(_injector);
|
||||
@ -47,12 +35,8 @@ export class ActiveFieldsListingComponent extends BaseListingComponent<Field> im
|
||||
}
|
||||
|
||||
deactivateSelection() {
|
||||
this.allEntities
|
||||
.filter(field => this.isSelected(field))
|
||||
.forEach(field => (field.primaryAttribute = false));
|
||||
this._screenStateService.setEntities([
|
||||
...this.allEntities.filter(field => !this.isSelected(field))
|
||||
]);
|
||||
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._screenStateService.setSelectedEntitiesIds([]);
|
||||
}
|
||||
|
||||
@ -3,20 +3,16 @@ import { AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators } from
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import * as Papa from 'papaparse';
|
||||
import {
|
||||
FileAttributeConfig,
|
||||
FileAttributesConfig,
|
||||
FileAttributesControllerService
|
||||
} from '@redaction/red-ui-http';
|
||||
import { FileAttributeConfig, FileAttributesConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { NotificationService, NotificationType } from '@services/notification.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.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 {
|
||||
id?: string;
|
||||
@ -70,10 +66,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
this.dossierTemplateId = data.dossierTemplateId;
|
||||
|
||||
this.baseConfigForm = this._formBuilder.group({
|
||||
filenameMappingColumnHeaderName: [
|
||||
'',
|
||||
[Validators.required, this._autocompleteStringValidator()]
|
||||
],
|
||||
filenameMappingColumnHeaderName: ['', [Validators.required, this._autocompleteStringValidator()]],
|
||||
delimiter: [undefined, 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._screenStateService.setEntities(
|
||||
this.parseResult.meta.fields.map(field => this._buildAttribute(field))
|
||||
);
|
||||
this._screenStateService.setEntities(this.parseResult.meta.fields.map(field => this._buildAttribute(field)));
|
||||
this._screenStateService.setDisplayedEntities(this.allEntities);
|
||||
this.activeFields = [];
|
||||
|
||||
for (const entity of this.allEntities) {
|
||||
const existing = this.data.existingConfiguration.fileAttributeConfigs.find(
|
||||
a => a.csvColumnHeader === entity.csvColumn
|
||||
);
|
||||
const existing = this.data.existingConfiguration.fileAttributeConfigs.find(a => a.csvColumnHeader === entity.csvColumn);
|
||||
if (existing) {
|
||||
entity.id = existing.id;
|
||||
entity.name = existing.label;
|
||||
@ -124,34 +113,21 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
}
|
||||
}
|
||||
|
||||
this.filteredKeyOptions = this.baseConfigForm
|
||||
.get('filenameMappingColumnHeaderName')
|
||||
.valueChanges.pipe(
|
||||
startWith(
|
||||
this.baseConfigForm.get('filenameMappingColumnHeaderName').value as string
|
||||
),
|
||||
map((value: string) =>
|
||||
this.allEntities
|
||||
.filter(
|
||||
field =>
|
||||
field.csvColumn.toLowerCase().indexOf(value.toLowerCase()) !==
|
||||
-1
|
||||
)
|
||||
.map(field => field.csvColumn)
|
||||
)
|
||||
);
|
||||
this.filteredKeyOptions = this.baseConfigForm.get('filenameMappingColumnHeaderName').valueChanges.pipe(
|
||||
startWith(this.baseConfigForm.get('filenameMappingColumnHeaderName').value as string),
|
||||
map((value: string) =>
|
||||
this.allEntities
|
||||
.filter(field => field.csvColumn.toLowerCase().indexOf(value.toLowerCase()) !== -1)
|
||||
.map(field => field.csvColumn)
|
||||
)
|
||||
);
|
||||
|
||||
if (
|
||||
this.data.existingConfiguration &&
|
||||
this.allEntities.find(
|
||||
entity =>
|
||||
entity.csvColumn ===
|
||||
this.data.existingConfiguration.filenameMappingColumnHeaderName
|
||||
)
|
||||
this.allEntities.find(entity => entity.csvColumn === this.data.existingConfiguration.filenameMappingColumnHeaderName)
|
||||
) {
|
||||
this.baseConfigForm.patchValue({
|
||||
filenameMappingColumnHeaderName:
|
||||
this.data.existingConfiguration.filenameMappingColumnHeaderName
|
||||
filenameMappingColumnHeaderName: this.data.existingConfiguration.filenameMappingColumnHeaderName
|
||||
});
|
||||
}
|
||||
|
||||
@ -206,9 +182,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
const newPrimary = !!this.activeFields.find(attr => attr.primaryAttribute);
|
||||
|
||||
if (newPrimary) {
|
||||
this.data.existingConfiguration.fileAttributeConfigs.forEach(
|
||||
attr => (attr.primaryAttribute = false)
|
||||
);
|
||||
this.data.existingConfiguration.fileAttributeConfigs.forEach(attr => (attr.primaryAttribute = false));
|
||||
}
|
||||
|
||||
const fileAttributes = {
|
||||
@ -229,9 +203,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
};
|
||||
|
||||
try {
|
||||
await this._fileAttributesControllerService
|
||||
.setFileAttributesConfig(fileAttributes, this.dossierTemplateId)
|
||||
.toPromise();
|
||||
await this._fileAttributesControllerService.setFileAttributesConfig(fileAttributes, this.dossierTemplateId).toPromise();
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant('file-attributes-csv-import.save.success', {
|
||||
count: this.activeFields.length
|
||||
@ -260,9 +232,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
if (!column) {
|
||||
this.columnSample = [];
|
||||
} else {
|
||||
this.columnSample = this.parseResult.data
|
||||
.filter(row => !!row[column])
|
||||
.map(row => row[column]);
|
||||
this.columnSample = this.parseResult.data.filter(row => !!row[column]).map(row => row[column]);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
@ -283,9 +253,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
csvColumn,
|
||||
name: csvColumn,
|
||||
temporaryName: csvColumn,
|
||||
type: isNumber
|
||||
? FileAttributeConfig.TypeEnum.NUMBER
|
||||
: FileAttributeConfig.TypeEnum.TEXT,
|
||||
type: isNumber ? FileAttributeConfig.TypeEnum.NUMBER : FileAttributeConfig.TypeEnum.TEXT,
|
||||
readonly: false,
|
||||
primaryAttribute: false
|
||||
};
|
||||
|
||||
@ -4,12 +4,12 @@ import { Colors, DictionaryControllerService } from '@redaction/red-ui-http';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { ScreenNames, SortingService } from '../../../../services/sorting.service';
|
||||
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { ScreenNames, SortingService } from '@services/sorting.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
|
||||
@Component({
|
||||
templateUrl: './default-colors-screen.component.html',
|
||||
@ -60,9 +60,7 @@ export class DefaultColorsScreenComponent
|
||||
|
||||
private async _loadColors() {
|
||||
this._loadingService.start();
|
||||
const data = await this._dictionaryControllerService
|
||||
.getColors(this._appStateService.activeDossierTemplateId)
|
||||
.toPromise();
|
||||
const data = await this._dictionaryControllerService.getColors(this._appStateService.activeDossierTemplateId).toPromise();
|
||||
this._colorsObj = data;
|
||||
this._screenStateService.setEntities(
|
||||
Object.keys(data).map(key => ({
|
||||
|
||||
@ -6,15 +6,15 @@ import { catchError, defaultIfEmpty, tap } from 'rxjs/operators';
|
||||
import { forkJoin, of } from 'rxjs';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
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 { LoadingService } from '../../../../services/loading.service';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { ScreenNames, SortingService } from '../../../../services/sorting.service';
|
||||
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { ScreenNames, SortingService } from '@services/sorting.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
|
||||
value: dict.entries ? dict.entries.length : 0,
|
||||
@ -28,10 +28,7 @@ const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
|
||||
styleUrls: ['./dictionary-listing-screen.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
})
|
||||
export class DictionaryListingScreenComponent
|
||||
extends BaseListingComponent<TypeValueWrapper>
|
||||
implements OnInit
|
||||
{
|
||||
export class DictionaryListingScreenComponent extends BaseListingComponent<TypeValueWrapper> implements OnInit {
|
||||
chartData: DoughnutChartConfig[] = [];
|
||||
|
||||
constructor(
|
||||
@ -56,15 +53,10 @@ export class DictionaryListingScreenComponent
|
||||
this._loadDictionaryData();
|
||||
}
|
||||
|
||||
openDeleteDictionariesDialog(
|
||||
$event?: MouseEvent,
|
||||
types = this._screenStateService.selectedEntitiesIds
|
||||
) {
|
||||
openDeleteDictionariesDialog($event?: MouseEvent, types = this._screenStateService.selectedEntitiesIds) {
|
||||
this._dialogService.openDialog('confirm', $event, null, async () => {
|
||||
this._loadingService.start();
|
||||
await this._dictionaryControllerService
|
||||
.deleteTypes(types, this._appStateService.activeDossierTemplateId)
|
||||
.toPromise();
|
||||
await this._dictionaryControllerService.deleteTypes(types, this._appStateService.activeDossierTemplateId).toPromise();
|
||||
this._screenStateService.setSelectedEntitiesIds([]);
|
||||
await this._appStateService.loadDictionaryData();
|
||||
this._loadDictionaryData(false);
|
||||
@ -92,8 +84,7 @@ export class DictionaryListingScreenComponent
|
||||
}
|
||||
|
||||
private _loadDictionaryData(loadEntries = true): void {
|
||||
const appStateDictionaryData =
|
||||
this._appStateService.dictionaryData[this._appStateService.activeDossierTemplateId];
|
||||
const appStateDictionaryData = this._appStateService.dictionaryData[this._appStateService.activeDossierTemplateId];
|
||||
const entities = Object.values(appStateDictionaryData).filter(d => !d.virtual);
|
||||
|
||||
if (!loadEntries)
|
||||
@ -110,16 +101,14 @@ export class DictionaryListingScreenComponent
|
||||
if (!loadEntries) return;
|
||||
|
||||
const dataObs = this.allEntities.map(dict =>
|
||||
this._dictionaryControllerService
|
||||
.getDictionaryForType(this._appStateService.activeDossierTemplateId, dict.type)
|
||||
.pipe(
|
||||
tap(values => (dict.entries = values.entries ?? [])),
|
||||
catchError(() => {
|
||||
console.log('error');
|
||||
dict.entries = [];
|
||||
return of({});
|
||||
})
|
||||
)
|
||||
this._dictionaryControllerService.getDictionaryForType(this._appStateService.activeDossierTemplateId, dict.type).pipe(
|
||||
tap(values => (dict.entries = values.entries ?? [])),
|
||||
catchError(() => {
|
||||
console.log('error');
|
||||
dict.entries = [];
|
||||
return of({});
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
forkJoin(dataObs)
|
||||
|
||||
@ -9,8 +9,8 @@ import { ComponentHasChanges } from '@guards/can-deactivate.guard';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component';
|
||||
import { DictionarySaveService } from '@shared/services/dictionary-save.service';
|
||||
import { TypeValueWrapper } from '../../../../models/file/type-value.wrapper';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { TypeValueWrapper } from '@models/file/type-value.wrapper';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dictionary-overview-screen',
|
||||
@ -75,9 +75,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
|
||||
$event?.stopPropagation();
|
||||
|
||||
this._dialogService.openDialog('confirm', $event, null, async () => {
|
||||
await this._dictionaryControllerService
|
||||
.deleteTypes([this.dictionary.type], this.dictionary.dossierTemplateId)
|
||||
.toPromise();
|
||||
await this._dictionaryControllerService.deleteTypes([this.dictionary.type], this.dictionary.dossierTemplateId).toPromise();
|
||||
await this._appStateService.loadDictionaryData();
|
||||
await this._router.navigate([
|
||||
'/main',
|
||||
@ -113,13 +111,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
|
||||
saveEntries(entries: string[]) {
|
||||
this.processing = true;
|
||||
this._dictionarySaveService
|
||||
.saveEntries(
|
||||
entries,
|
||||
this.entries,
|
||||
this.dictionary.dossierTemplateId,
|
||||
this.dictionary.type,
|
||||
null
|
||||
)
|
||||
.saveEntries(entries, this.entries, this.dictionary.dossierTemplateId, this.dictionary.type, null)
|
||||
.subscribe(
|
||||
() => {
|
||||
this.processing = false;
|
||||
@ -133,19 +125,15 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple
|
||||
|
||||
private _loadEntries() {
|
||||
this.processing = true;
|
||||
this._dictionaryControllerService
|
||||
.getDictionaryForType(this.dictionary.dossierTemplateId, this.dictionary.type)
|
||||
.subscribe(
|
||||
data => {
|
||||
this.processing = false;
|
||||
this.entries = data.entries.sort((str1, str2) =>
|
||||
str1.localeCompare(str2, undefined, { sensitivity: 'accent' })
|
||||
);
|
||||
},
|
||||
() => {
|
||||
this.processing = false;
|
||||
this.entries = [];
|
||||
}
|
||||
);
|
||||
this._dictionaryControllerService.getDictionaryForType(this.dictionary.dossierTemplateId, this.dictionary.type).subscribe(
|
||||
data => {
|
||||
this.processing = false;
|
||||
this.entries = data.entries.sort((str1, str2) => str1.localeCompare(str2, undefined, { sensitivity: 'accent' }));
|
||||
},
|
||||
() => {
|
||||
this.processing = false;
|
||||
this.entries = [];
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
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 { AppStateService } from '../../../../state/app-state.service';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { ScreenNames, SortingService } from '../../../../services/sorting.service';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -6,11 +6,11 @@ import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { DossierTemplateModelWrapper } from '../../../../models/file/dossier-template-model.wrapper';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { DossierTemplateControllerService } from '@redaction/red-ui-http';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.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({
|
||||
templateUrl: './dossier-templates-listing-screen.component.html',
|
||||
@ -18,10 +18,7 @@ import { BaseListingComponent } from '../../../shared/base/base-listing.componen
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
})
|
||||
export class DossierTemplatesListingScreenComponent
|
||||
extends BaseListingComponent<DossierTemplateModelWrapper>
|
||||
implements OnInit
|
||||
{
|
||||
export class DossierTemplatesListingScreenComponent extends BaseListingComponent<DossierTemplateModelWrapper> implements OnInit {
|
||||
constructor(
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
@ -44,9 +41,7 @@ export class DossierTemplatesListingScreenComponent
|
||||
openDeleteTemplatesDialog($event?: MouseEvent) {
|
||||
return this._dialogService.openDialog('confirm', $event, null, async () => {
|
||||
this._loadingService.start();
|
||||
await this._dossierTemplateControllerService
|
||||
.deleteDossierTemplates(this._screenStateService.selectedEntitiesIds)
|
||||
.toPromise();
|
||||
await this._dossierTemplateControllerService.deleteDossierTemplates(this._screenStateService.selectedEntitiesIds).toPromise();
|
||||
this._screenStateService.setSelectedEntitiesIds([]);
|
||||
await this._appStateService.loadAllDossierTemplates();
|
||||
await this._appStateService.loadDictionaryData();
|
||||
@ -64,16 +59,11 @@ export class DossierTemplatesListingScreenComponent
|
||||
}
|
||||
|
||||
openAddDossierTemplateDialog() {
|
||||
this._dialogService.openDialog(
|
||||
'addEditDossierTemplate',
|
||||
null,
|
||||
null,
|
||||
async newDossierTemplate => {
|
||||
if (newDossierTemplate) {
|
||||
this.loadDossierTemplatesData();
|
||||
}
|
||||
this._dialogService.openDialog('addEditDossierTemplate', null, null, async newDossierTemplate => {
|
||||
if (newDossierTemplate) {
|
||||
this.loadDossierTemplatesData();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private _loadDossierTemplateStats() {
|
||||
|
||||
@ -1,22 +1,15 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
ElementRef,
|
||||
Injector,
|
||||
OnInit,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { FileAttributeConfig, FileAttributesConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.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({
|
||||
templateUrl: './file-attributes-listing-screen.component.html',
|
||||
@ -24,10 +17,7 @@ import { BaseListingComponent } from '../../../shared/base/base-listing.componen
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
})
|
||||
export class FileAttributesListingScreenComponent
|
||||
extends BaseListingComponent<FileAttributeConfig>
|
||||
implements OnInit
|
||||
{
|
||||
export class FileAttributesListingScreenComponent extends BaseListingComponent<FileAttributeConfig> implements OnInit {
|
||||
private _existingConfiguration: FileAttributesConfig;
|
||||
@ViewChild('fileInput') private _fileInput: ElementRef;
|
||||
|
||||
@ -75,10 +65,7 @@ export class FileAttributesListingScreenComponent
|
||||
.toPromise();
|
||||
} else {
|
||||
await this._fileAttributesService
|
||||
.deleteFileAttributes(
|
||||
this._screenStateService.selectedEntitiesIds,
|
||||
this._appStateService.activeDossierTemplateId
|
||||
)
|
||||
.deleteFileAttributes(this._screenStateService.selectedEntitiesIds, this._appStateService.activeDossierTemplateId)
|
||||
.toPromise();
|
||||
}
|
||||
await this._loadData();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||
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 { download } from '../../../../utils/file-download-utils';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
@ -5,11 +5,11 @@ import { Dossier, StatusControllerService } from '@redaction/red-ui-http';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
|
||||
import * as moment from 'moment';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.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';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -1,11 +1,4 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
Injector,
|
||||
OnInit,
|
||||
QueryList,
|
||||
ViewChildren
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, Injector, OnInit, QueryList, ViewChildren } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
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 { TranslateChartService } from '@services/translate-chart.service';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { InitialsAvatarComponent } from '../../../shared/components/initials-avatar/initials-avatar.component';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { InitialsAvatarComponent } from '@shared/components/initials-avatar/initials-avatar.component';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.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 { map } from 'rxjs/operators';
|
||||
|
||||
@ -86,9 +79,7 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
|
||||
}
|
||||
|
||||
bulkDelete() {
|
||||
this.openDeleteUsersDialog(
|
||||
this._screenStateService.entities.filter(u => this.isSelected(u))
|
||||
);
|
||||
this.openDeleteUsersDialog(this._screenStateService.entities.filter(u => this.isSelected(u)));
|
||||
}
|
||||
|
||||
trackById(index: number, user: User) {
|
||||
@ -96,9 +87,7 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
|
||||
}
|
||||
|
||||
private async _loadData() {
|
||||
this._screenStateService.setEntities(
|
||||
await this._userControllerService.getAllUsers().toPromise()
|
||||
);
|
||||
this._screenStateService.setEntities(await this._userControllerService.getAllUsers().toPromise());
|
||||
await this.userService.loadAllUsers();
|
||||
this.filterService.filterEntities();
|
||||
this._computeStats();
|
||||
@ -114,38 +103,27 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
|
||||
label: 'INACTIVE'
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(
|
||||
user => user.roles.length === 1 && user.roles[0] === 'RED_USER'
|
||||
).length,
|
||||
value: this.allEntities.filter(user => user.roles.length === 1 && user.roles[0] === 'RED_USER').length,
|
||||
color: 'REGULAR',
|
||||
label: 'REGULAR'
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(
|
||||
user => this.userService.isManager(user) && !this.userService.isAdmin(user)
|
||||
).length,
|
||||
value: this.allEntities.filter(user => this.userService.isManager(user) && !this.userService.isAdmin(user)).length,
|
||||
color: 'MANAGER',
|
||||
label: 'RED_MANAGER'
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(
|
||||
user => this.userService.isManager(user) && this.userService.isAdmin(user)
|
||||
).length,
|
||||
value: this.allEntities.filter(user => this.userService.isManager(user) && this.userService.isAdmin(user)).length,
|
||||
color: 'MANAGER_ADMIN',
|
||||
label: 'MANAGER_ADMIN'
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(
|
||||
user =>
|
||||
this.userService.isUserAdmin(user) && !this.userService.isAdmin(user)
|
||||
).length,
|
||||
value: this.allEntities.filter(user => this.userService.isUserAdmin(user) && !this.userService.isAdmin(user)).length,
|
||||
color: 'USER_ADMIN',
|
||||
label: 'RED_USER_ADMIN'
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(
|
||||
user => this.userService.isAdmin(user) && !this.userService.isManager(user)
|
||||
).length,
|
||||
value: this.allEntities.filter(user => this.userService.isAdmin(user) && !this.userService.isManager(user)).length,
|
||||
color: 'ADMIN',
|
||||
label: 'RED_ADMIN'
|
||||
}
|
||||
|
||||
@ -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 { FileAttributesCsvImportDialogComponent } from '../dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component';
|
||||
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';
|
||||
|
||||
type DialogType =
|
||||
|
||||
@ -1,18 +1,15 @@
|
||||
import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import {
|
||||
FileManagementControllerService,
|
||||
ReanalysisControllerService
|
||||
} from '@redaction/red-ui-http';
|
||||
import { FileManagementControllerService, ReanalysisControllerService } from '@redaction/red-ui-http';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { FileActionService } from '../../services/file-action.service';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { StatusOverlayService } from '@upload-download/services/status-overlay.service';
|
||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { ConfirmationDialogInput } from '../../../shared/dialogs/confirmation-dialog/confirmation-dialog.component';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { ConfirmationDialogInput } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossier-overview-bulk-actions',
|
||||
@ -44,10 +41,7 @@ export class DossierOverviewBulkActionsComponent {
|
||||
|
||||
get selectedFiles(): FileStatusWrapper[] {
|
||||
return this.selectedFileIds.map(fileId =>
|
||||
this._appStateService.getFileById(
|
||||
this._appStateService.activeDossier.dossier.dossierId,
|
||||
fileId
|
||||
)
|
||||
this._appStateService.getFileById(this._appStateService.activeDossier.dossier.dossierId, fileId)
|
||||
);
|
||||
}
|
||||
|
||||
@ -69,10 +63,7 @@ export class DossierOverviewBulkActionsComponent {
|
||||
(acc, file) => acc && (file.isUnderReview || file.isUnassigned),
|
||||
true
|
||||
);
|
||||
const allFilesAreUnderApproval = selectedFiles.reduce(
|
||||
(acc, file) => acc && file.isUnderApproval,
|
||||
true
|
||||
);
|
||||
const allFilesAreUnderApproval = selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true);
|
||||
return allFilesAreUnderReviewOrUnassigned || allFilesAreUnderApproval;
|
||||
}
|
||||
return false;
|
||||
@ -81,42 +72,27 @@ export class DossierOverviewBulkActionsComponent {
|
||||
get canAssignToSelf() {
|
||||
return (
|
||||
this.allSelectedFilesCanBeAssignedIntoSameState &&
|
||||
this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canAssignToSelf(file),
|
||||
true
|
||||
)
|
||||
this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignToSelf(file), true)
|
||||
);
|
||||
}
|
||||
|
||||
get canAssign() {
|
||||
return (
|
||||
this.allSelectedFilesCanBeAssignedIntoSameState &&
|
||||
this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canAssignUser(file),
|
||||
true
|
||||
)
|
||||
this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignUser(file), true)
|
||||
);
|
||||
}
|
||||
|
||||
get canDelete() {
|
||||
return this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canDeleteFile(file),
|
||||
true
|
||||
);
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canDeleteFile(file), true);
|
||||
}
|
||||
|
||||
get canReanalyse() {
|
||||
return this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canReanalyseFile(file),
|
||||
true
|
||||
);
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canReanalyseFile(file), true);
|
||||
}
|
||||
|
||||
get canOcr() {
|
||||
return this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canOcrFile(file),
|
||||
true
|
||||
);
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canOcrFile(file), true);
|
||||
}
|
||||
|
||||
get fileStatuses() {
|
||||
@ -125,51 +101,31 @@ export class DossierOverviewBulkActionsComponent {
|
||||
|
||||
// Under review
|
||||
get canSetToUnderReview() {
|
||||
return this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canSetUnderReview(file),
|
||||
true
|
||||
);
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderReview(file), true);
|
||||
}
|
||||
|
||||
// Under approval
|
||||
get canSetToUnderApproval() {
|
||||
return this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canSetUnderApproval(file),
|
||||
true
|
||||
);
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderApproval(file), true);
|
||||
}
|
||||
|
||||
// Approve
|
||||
get isReadyForApproval() {
|
||||
return this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.isReadyForApproval(file),
|
||||
true
|
||||
);
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.isReadyForApproval(file), true);
|
||||
}
|
||||
|
||||
get canApprove() {
|
||||
return this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canApprove(file),
|
||||
true
|
||||
);
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canApprove(file), true);
|
||||
}
|
||||
|
||||
// Undo approval
|
||||
get canUndoApproval() {
|
||||
return this.selectedFiles.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canUndoApproval(file),
|
||||
true
|
||||
);
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canUndoApproval(file), true);
|
||||
}
|
||||
|
||||
get assignTooltip() {
|
||||
const allFilesAreUnderApproval = this.selectedFiles.reduce(
|
||||
(acc, file) => acc && file.isUnderApproval,
|
||||
true
|
||||
);
|
||||
return allFilesAreUnderApproval
|
||||
? 'dossier-overview.assign-approver'
|
||||
: 'dossier-overview.assign-reviewer';
|
||||
const allFilesAreUnderApproval = this.selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true);
|
||||
return allFilesAreUnderApproval ? 'dossier-overview.assign-approver' : 'dossier-overview.assign-reviewer';
|
||||
}
|
||||
|
||||
delete() {
|
||||
@ -212,23 +168,15 @@ export class DossierOverviewBulkActionsComponent {
|
||||
);
|
||||
} else {
|
||||
this._performBulkAction(
|
||||
this._fileActionService.setFileUnderApproval(
|
||||
this.selectedFiles,
|
||||
this._appStateService.activeDossier.approverIds[0]
|
||||
)
|
||||
this._fileActionService.setFileUnderApproval(this.selectedFiles, this._appStateService.activeDossier.approverIds[0])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async reanalyse() {
|
||||
const fileIds = this.selectedFiles
|
||||
.filter(file => this._permissionsService.fileRequiresReanalysis(file))
|
||||
.map(file => file.fileId);
|
||||
const fileIds = this.selectedFiles.filter(file => this._permissionsService.fileRequiresReanalysis(file)).map(file => file.fileId);
|
||||
this._performBulkAction(
|
||||
this._reanalysisControllerService.reanalyzeFilesForDossier(
|
||||
fileIds,
|
||||
this._appStateService.activeDossier.dossierId
|
||||
)
|
||||
this._reanalysisControllerService.reanalyzeFilesForDossier(fileIds, this._appStateService.activeDossier.dossierId)
|
||||
);
|
||||
}
|
||||
|
||||
@ -250,9 +198,7 @@ export class DossierOverviewBulkActionsComponent {
|
||||
|
||||
assign() {
|
||||
this._loadingService.start();
|
||||
const files = this.selectedFileIds.map(fileId =>
|
||||
this._appStateService.getFileById(this._appStateService.activeDossierId, fileId)
|
||||
);
|
||||
const files = this.selectedFileIds.map(fileId => this._appStateService.getFileById(this._appStateService.activeDossierId, fileId));
|
||||
|
||||
const mode = files[0].isUnderApproval ? 'approver' : 'reviewer';
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import { StatusSorter } from '@utils/sorters/status-sorter';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { User } from '@redaction/red-ui-http';
|
||||
import { NotificationService } from '@services/notification.service';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { FileStatusWrapper } from '../../../../models/file/file-status.wrapper';
|
||||
|
||||
@Component({
|
||||
@ -70,9 +70,7 @@ export class DossierDetailsComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
this.documentsChartData.sort((a, b) => StatusSorter[a.key] - StatusSorter[b.key]);
|
||||
this.documentsChartData = this.translateChartService.translateStatus(
|
||||
this.documentsChartData
|
||||
);
|
||||
this.documentsChartData = this.translateChartService.translateStatus(this.documentsChartData);
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossier-listing-details',
|
||||
@ -13,8 +13,5 @@ export class DossierListingDetailsComponent<T> {
|
||||
@Input() dossiersChartData: DoughnutChartConfig[];
|
||||
@Input() documentsChartData: DoughnutChartConfig[];
|
||||
|
||||
constructor(
|
||||
readonly appStateService: AppStateService,
|
||||
readonly filterService: FilterService<T>
|
||||
) {}
|
||||
constructor(readonly appStateService: AppStateService, readonly filterService: FilterService<T>) {}
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@ import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { FileActionService } from '../../services/file-action.service';
|
||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
import { ConfirmationDialogInput } from '../../../shared/dialogs/confirmation-dialog/confirmation-dialog.component';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { ConfirmationDialogInput } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { FileManagementControllerService } from '@redaction/red-ui-http';
|
||||
|
||||
@Component({
|
||||
@ -48,9 +48,7 @@ export class FileActionsComponent implements OnInit {
|
||||
return 'file-preview.toggle-analysis.only-managers';
|
||||
}
|
||||
|
||||
return this.fileStatus?.isExcluded
|
||||
? 'file-preview.toggle-analysis.enable'
|
||||
: 'file-preview.toggle-analysis.disable';
|
||||
return this.fileStatus?.isExcluded ? 'file-preview.toggle-analysis.enable' : 'file-preview.toggle-analysis.disable';
|
||||
}
|
||||
|
||||
get canAssignToSelf() {
|
||||
@ -86,9 +84,7 @@ export class FileActionsComponent implements OnInit {
|
||||
}
|
||||
|
||||
get assignTooltip() {
|
||||
return this.fileStatus.isUnderApproval
|
||||
? 'dossier-overview.assign-approver'
|
||||
: 'dossier-overview.assign-reviewer';
|
||||
return this.fileStatus.isUnderApproval ? 'dossier-overview.assign-approver' : 'dossier-overview.assign-reviewer';
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@ -124,9 +120,7 @@ export class FileActionsComponent implements OnInit {
|
||||
}),
|
||||
async () => {
|
||||
this._loadingService.start();
|
||||
await this._fileManagementControllerService
|
||||
.deleteFiles([this.fileStatus.fileId], this.fileStatus.dossierId)
|
||||
.toPromise();
|
||||
await this._fileManagementControllerService.deleteFiles([this.fileStatus.fileId], this.fileStatus.dossierId).toPromise();
|
||||
await this.appStateService.reloadActiveDossierFiles();
|
||||
this.actionPerformed.emit('delete');
|
||||
this._loadingService.stop();
|
||||
@ -162,11 +156,7 @@ export class FileActionsComponent implements OnInit {
|
||||
setFileUnderApproval($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
if (this.appStateService.activeDossier.approverIds.length > 1) {
|
||||
this._fileActionService.assignDossierApprover(
|
||||
this.fileStatus,
|
||||
() => this.actionPerformed.emit('assign-reviewer'),
|
||||
true
|
||||
);
|
||||
this._fileActionService.assignDossierApprover(this.fileStatus, () => this.actionPerformed.emit('assign-reviewer'), true);
|
||||
} else {
|
||||
this._fileActionService.setFileUnderApproval(this.fileStatus).subscribe(() => {
|
||||
this.reloadDossiers('set-under-approval');
|
||||
@ -206,8 +196,6 @@ export class FileActionsComponent implements OnInit {
|
||||
async toggleAnalysis() {
|
||||
await this._fileActionService.toggleAnalysis(this.fileStatus).toPromise();
|
||||
await this.appStateService.getFiles();
|
||||
this.actionPerformed.emit(
|
||||
this.fileStatus?.isExcluded ? 'enable-analysis' : 'disable-analysis'
|
||||
);
|
||||
this.actionPerformed.emit(this.fileStatus?.isExcluded ? 'enable-analysis' : 'disable-analysis');
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ import { debounce } from '@utils/debounce';
|
||||
import { FileDataModel } from '@models/file/file-data.model';
|
||||
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
|
||||
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 { WebViewerInstance } from '@pdftron/webviewer';
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
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 { PageRange, ReanalysisControllerService } from '@redaction/red-ui-http';
|
||||
import { FileDataModel } from '../../../../models/file/file-data.model';
|
||||
import { NotificationService, NotificationType } from '../../../../services/notification.service';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { FileDataModel } from '@models/file/file-data.model';
|
||||
import { NotificationService, NotificationType } from '@services/notification.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
@ -34,9 +34,7 @@ export class PageExclusionComponent implements OnChanges {
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes.fileData) {
|
||||
const excludedPages = (this.fileData?.fileStatus?.excludedPages || []).sort(
|
||||
(p1, p2) => p1 - p2
|
||||
);
|
||||
const excludedPages = (this.fileData?.fileStatus?.excludedPages || []).sort((p1, p2) => p1 - p2);
|
||||
this.excludedPagesRanges = excludedPages.reduce((ranges, page) => {
|
||||
if (!ranges.length) {
|
||||
return [{ startPage: page, endPage: page }];
|
||||
|
||||
@ -24,12 +24,12 @@ import { AnnotationActionsService } from '../../services/annotation-actions.serv
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { BASE_HREF } from '../../../../tokens';
|
||||
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 { 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 { PdfViewerUtils } from '../../utils/pdf-viewer.utils';
|
||||
import { ViewMode } from '../../../../models/file/view-mode';
|
||||
import { ViewMode } from '@models/file/view-mode';
|
||||
import TextTool = Tools.TextTool;
|
||||
|
||||
@Component({
|
||||
@ -105,9 +105,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
// viewer init
|
||||
this.instance.setFitMode('FitPage');
|
||||
|
||||
const instanceDisplayMode = this.instance.docViewer
|
||||
.getDisplayModeManager()
|
||||
.getDisplayMode();
|
||||
const instanceDisplayMode = this.instance.docViewer.getDisplayModeManager().getDisplayMode();
|
||||
instanceDisplayMode.mode = this.viewMode === 'STANDARD' ? 'Single' : 'Facing';
|
||||
this.instance.docViewer.getDisplayModeManager().setDisplayMode(instanceDisplayMode);
|
||||
}
|
||||
@ -123,15 +121,11 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
const pdfData = fileReader.result;
|
||||
|
||||
const PDFNet = this.instance.PDFNet;
|
||||
await PDFNet.initialize(
|
||||
environment.licenseKey ? atob(environment.licenseKey) : null
|
||||
);
|
||||
await PDFNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
||||
|
||||
const mergedDocument = await PDFNet.PDFDoc.create();
|
||||
const compareDocument = await PDFNet.PDFDoc.createFromBuffer(<any>pdfData);
|
||||
const currentDocument = await PDFNet.PDFDoc.createFromBuffer(
|
||||
await this.fileData.arrayBuffer()
|
||||
);
|
||||
const currentDocument = await PDFNet.PDFDoc.createFromBuffer(await this.fileData.arrayBuffer());
|
||||
|
||||
const currentDocumentPageCount = await currentDocument.getPageCount();
|
||||
const compareDocumentPageCount = await compareDocument.getPageCount();
|
||||
@ -186,9 +180,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
this.viewMode = 'STANDARD';
|
||||
const PDFNet = this.instance.PDFNet;
|
||||
await PDFNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
||||
const currentDocument = await PDFNet.PDFDoc.createFromBuffer(
|
||||
await this.fileData.arrayBuffer()
|
||||
);
|
||||
const currentDocument = await PDFNet.PDFDoc.createFromBuffer(await this.fileData.arrayBuffer());
|
||||
this.instance.loadDocument(currentDocument, {
|
||||
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
|
||||
});
|
||||
@ -221,16 +213,12 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
this._configureTextPopup();
|
||||
|
||||
this.instance.annotManager.on('annotationSelected', (annotations, action) => {
|
||||
this.annotationSelected.emit(
|
||||
this.instance.annotManager.getSelectedAnnotations().map(ann => ann.Id)
|
||||
);
|
||||
this.annotationSelected.emit(this.instance.annotManager.getSelectedAnnotations().map(ann => ann.Id));
|
||||
if (action === 'deselected') {
|
||||
this._toggleRectangleAnnotationAction(true);
|
||||
} else {
|
||||
this._configureAnnotationSpecificActions(annotations);
|
||||
this._toggleRectangleAnnotationAction(
|
||||
annotations.length === 1 && annotations[0].ReadOnly
|
||||
);
|
||||
this._toggleRectangleAnnotationAction(annotations.length === 1 && annotations[0].ReadOnly);
|
||||
}
|
||||
});
|
||||
|
||||
@ -238,10 +226,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
// when a rectangle is drawn,
|
||||
// it returns one annotation with tool name 'AnnotationCreateRectangle;
|
||||
// this will auto select rectangle after drawing
|
||||
if (
|
||||
annotations.length === 1 &&
|
||||
annotations[0].ToolName === 'AnnotationCreateRectangle'
|
||||
) {
|
||||
if (annotations.length === 1 && annotations[0].ToolName === 'AnnotationCreateRectangle') {
|
||||
this.instance.annotManager.selectAnnotations(annotations);
|
||||
}
|
||||
});
|
||||
@ -284,9 +269,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
|
||||
this.instance.iframeWindow.addEventListener('visibilityChanged', (event: any) => {
|
||||
if (event.detail.element === 'searchPanel') {
|
||||
const inputElement = this.instance.iframeWindow.document.getElementById(
|
||||
'SearchPanel__input'
|
||||
) as HTMLInputElement;
|
||||
const inputElement = this.instance.iframeWindow.document.getElementById('SearchPanel__input') as HTMLInputElement;
|
||||
setTimeout(() => {
|
||||
inputElement.value = '';
|
||||
}, 0);
|
||||
@ -364,9 +347,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
type: 'actionButton',
|
||||
element: 'closeCompare',
|
||||
dataElement: 'closeCompareButton',
|
||||
img: this._convertPath(
|
||||
'/assets/icons/general/pdftron-action-close-compare.svg'
|
||||
),
|
||||
img: this._convertPath('/assets/icons/general/pdftron-action-close-compare.svg'),
|
||||
title: 'Leave Compare Mode',
|
||||
onClick: () => {
|
||||
this.closeCompareMode();
|
||||
@ -394,9 +375,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
return;
|
||||
}
|
||||
|
||||
const annotationWrappers = viewerAnnotations
|
||||
.map(va => this.annotations.find(a => a.id === va.Id))
|
||||
.filter(va => !!va);
|
||||
const annotationWrappers = viewerAnnotations.map(va => this.annotations.find(a => a.id === va.Id)).filter(va => !!va);
|
||||
this.instance.annotationPopup.update([]);
|
||||
|
||||
if (annotationWrappers.length === 0) {
|
||||
@ -405,15 +384,9 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
// Add hide action as last item
|
||||
const allAnnotationsHaveImageAction = annotationWrappers.reduce(
|
||||
(acc, next) => acc && next.isImage,
|
||||
true
|
||||
);
|
||||
const allAnnotationsHaveImageAction = annotationWrappers.reduce((acc, next) => acc && next.isImage, true);
|
||||
if (allAnnotationsHaveImageAction) {
|
||||
const allAreVisible = viewerAnnotations.reduce(
|
||||
(acc, next) => next.isVisible() && acc,
|
||||
true
|
||||
);
|
||||
const allAreVisible = viewerAnnotations.reduce((acc, next) => next.isVisible() && acc, true);
|
||||
|
||||
this.instance.annotationPopup.add([
|
||||
{
|
||||
@ -437,10 +410,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
this.instance.annotationPopup.add(
|
||||
this._annotationActionsService.getViewerAvailableActions(
|
||||
annotationWrappers,
|
||||
this.annotationsChanged
|
||||
)
|
||||
this._annotationActionsService.getViewerAvailableActions(annotationWrappers, this.annotationsChanged)
|
||||
);
|
||||
}
|
||||
|
||||
@ -449,17 +419,12 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
type: 'actionButton',
|
||||
dataElement: 'add-rectangle',
|
||||
img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'),
|
||||
title: this._translateService.instant(
|
||||
this._manualAnnotationService.getTitle('REDACTION')
|
||||
),
|
||||
title: this._translateService.instant(this._manualAnnotationService.getTitle('REDACTION')),
|
||||
onClick: () => {
|
||||
const selectedAnnotations = this.instance.annotManager.getSelectedAnnotations();
|
||||
const activeAnnotation = selectedAnnotations[0];
|
||||
const activePage = selectedAnnotations[0].getPageNumber();
|
||||
const quad = this._annotationDrawService.annotationToQuads(
|
||||
activeAnnotation,
|
||||
this.instance
|
||||
);
|
||||
const quad = this._annotationDrawService.annotationToQuads(activeAnnotation, this.instance);
|
||||
const quadsObject = {};
|
||||
quadsObject[activePage] = [quad];
|
||||
const mre = this._getManualRedactionEntry(quadsObject, 'Rectangle');
|
||||
@ -469,13 +434,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
this.instance.enableElements(['shapeToolGroupButton', 'rectangleToolDivider']);
|
||||
// dispatch event
|
||||
this.manualAnnotationRequested.emit(
|
||||
new ManualRedactionEntryWrapper(
|
||||
[quad],
|
||||
mre,
|
||||
'REDACTION',
|
||||
'RECTANGLE',
|
||||
activeAnnotation.Id
|
||||
)
|
||||
new ManualRedactionEntryWrapper([quad], mre, 'REDACTION', 'RECTANGLE', activeAnnotation.Id)
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -509,19 +468,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
type: 'actionButton',
|
||||
dataElement: 'add-false-positive',
|
||||
img: this._convertPath('/assets/icons/general/pdftron-action-false-positive.svg'),
|
||||
title: this._translateService.instant(
|
||||
this._manualAnnotationService.getTitle('FALSE_POSITIVE')
|
||||
),
|
||||
title: this._translateService.instant(this._manualAnnotationService.getTitle('FALSE_POSITIVE')),
|
||||
onClick: () => {
|
||||
const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
|
||||
const text = this.instance.docViewer.getSelectedText();
|
||||
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
||||
this.manualAnnotationRequested.emit(
|
||||
new ManualRedactionEntryWrapper(
|
||||
this.instance.docViewer.getSelectedTextQuads(),
|
||||
mre,
|
||||
'FALSE_POSITIVE'
|
||||
)
|
||||
new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'FALSE_POSITIVE')
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -531,19 +484,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
type: 'actionButton',
|
||||
dataElement: 'add-dictionary',
|
||||
img: this._convertPath('/assets/icons/general/pdftron-action-add-dict.svg'),
|
||||
title: this._translateService.instant(
|
||||
this._manualAnnotationService.getTitle('DICTIONARY')
|
||||
),
|
||||
title: this._translateService.instant(this._manualAnnotationService.getTitle('DICTIONARY')),
|
||||
onClick: () => {
|
||||
const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
|
||||
const text = this.instance.docViewer.getSelectedText();
|
||||
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
||||
this.manualAnnotationRequested.emit(
|
||||
new ManualRedactionEntryWrapper(
|
||||
this.instance.docViewer.getSelectedTextQuads(),
|
||||
mre,
|
||||
'DICTIONARY'
|
||||
)
|
||||
new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'DICTIONARY')
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -552,19 +499,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
type: 'actionButton',
|
||||
dataElement: 'add-redaction',
|
||||
img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'),
|
||||
title: this._translateService.instant(
|
||||
this._manualAnnotationService.getTitle('REDACTION')
|
||||
),
|
||||
title: this._translateService.instant(this._manualAnnotationService.getTitle('REDACTION')),
|
||||
onClick: () => {
|
||||
const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
|
||||
const text = this.instance.docViewer.getSelectedText();
|
||||
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
||||
this.manualAnnotationRequested.emit(
|
||||
new ManualRedactionEntryWrapper(
|
||||
this.instance.docViewer.getSelectedTextQuads(),
|
||||
mre,
|
||||
'REDACTION'
|
||||
)
|
||||
new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'REDACTION')
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -600,22 +541,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
private _getManualRedactionEntry(
|
||||
quads: any,
|
||||
text: string,
|
||||
convertQuads: boolean = false
|
||||
): ManualRedactionEntry {
|
||||
private _getManualRedactionEntry(quads: any, text: string, convertQuads: boolean = false): ManualRedactionEntry {
|
||||
text = text.replace(/-\n/gi, '');
|
||||
const entry: ManualRedactionEntry = { positions: [] };
|
||||
for (const key of Object.keys(quads)) {
|
||||
for (const quad of quads[key]) {
|
||||
const page = parseInt(key, 10);
|
||||
entry.positions.push(
|
||||
this.utils.toPosition(
|
||||
page,
|
||||
convertQuads ? this.utils.translateQuads(page, quad) : quad
|
||||
)
|
||||
);
|
||||
entry.positions.push(this.utils.toPosition(page, convertQuads ? this.utils.translateQuads(page, quad) : quad));
|
||||
}
|
||||
}
|
||||
entry.value = text;
|
||||
|
||||
@ -4,8 +4,8 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { LegalBasisMappingControllerService } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '../../../../state/app-state.service';
|
||||
import { PermissionsService } from '../../../../services/permissions.service';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
|
||||
export interface LegalBasisOption {
|
||||
label?: string;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { Component, Inject, ViewChild } from '@angular/core';
|
||||
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 { DictionarySaveService } from '@shared/services/dictionary-save.service';
|
||||
import { AppStateService } from '../../../../state/app-state.service';
|
||||
import { PermissionsService } from '../../../../services/permissions.service';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossier-dictionary-dialog',
|
||||
@ -23,9 +23,7 @@ export class DossierDictionaryDialogComponent {
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _dictionarySaveService: DictionarySaveService
|
||||
) {
|
||||
this.canEdit =
|
||||
this.permissionsService.isDossierMember(this.dossier) ||
|
||||
this.permissionsService.isAdmin();
|
||||
this.canEdit = this.permissionsService.isDossierMember(this.dossier) || this.permissionsService.isAdmin();
|
||||
}
|
||||
|
||||
saveDossierDictionary() {
|
||||
@ -39,10 +37,7 @@ export class DossierDictionaryDialogComponent {
|
||||
)
|
||||
.subscribe(async () => {
|
||||
await this._appStateService.reloadActiveDossierFiles();
|
||||
this._appStateService.updateDossierDictionary(
|
||||
this.dossier.dossierTemplateId,
|
||||
this.dossier.dossierId
|
||||
);
|
||||
this._appStateService.updateDossierDictionary(this.dossier.dossierTemplateId, this.dossier.dossierId);
|
||||
this.dialogRef.close();
|
||||
});
|
||||
}
|
||||
|
||||
@ -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>
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { AppStateService } from '../../../../../state/app-state.service';
|
||||
import { DossierWrapper } from '../../../../../state/model/dossier.wrapper';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
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 { DictionarySaveService } from '@shared/services/dictionary-save.service';
|
||||
|
||||
@ -23,9 +23,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
|
||||
private readonly _dictionarySaveService: DictionarySaveService,
|
||||
private readonly _permissionsService: PermissionsService
|
||||
) {
|
||||
this.canEdit =
|
||||
this._permissionsService.isDossierMember(this.dossierWrapper) ||
|
||||
this._permissionsService.isAdmin();
|
||||
this.canEdit = this._permissionsService.isDossierMember(this.dossierWrapper) || this._permissionsService.isAdmin();
|
||||
}
|
||||
|
||||
get changed() {
|
||||
@ -47,10 +45,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
|
||||
false
|
||||
)
|
||||
.subscribe(async () => {
|
||||
this._appStateService.updateDossierDictionary(
|
||||
this.dossierWrapper.dossierTemplateId,
|
||||
this.dossierWrapper.dossierId
|
||||
);
|
||||
this._appStateService.updateDossierDictionary(this.dossierWrapper.dossierTemplateId, this.dossierWrapper.dossierId);
|
||||
this.updateDossier.emit();
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { DossierTemplateModel } from '@redaction/red-ui-http';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { AppStateService } from '../../../../../state/app-state.service';
|
||||
import { DossierWrapper } from '../../../../../state/model/dossier.wrapper';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
|
||||
|
||||
@Component({
|
||||
@ -19,10 +19,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
||||
@Input() dossierWrapper: DossierWrapper;
|
||||
@Output() updateDossier = new EventEmitter<any>();
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _formBuilder: FormBuilder
|
||||
) {}
|
||||
constructor(private readonly _appStateService: AppStateService, private readonly _formBuilder: FormBuilder) {}
|
||||
|
||||
get reportTypesLength() {
|
||||
return this.dossierForm.controls['reportTypes']?.value?.length || 0;
|
||||
@ -34,9 +31,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
||||
|
||||
get changed() {
|
||||
for (const key of Object.keys(this.dossierForm.getRawValue())) {
|
||||
if (
|
||||
this.dossierWrapper.dossier[key].length !== this.dossierForm.get(key).value.length
|
||||
) {
|
||||
if (this.dossierWrapper.dossier[key].length !== this.dossierForm.get(key).value.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -65,10 +60,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
||||
},
|
||||
{
|
||||
validators: control =>
|
||||
control.value.reportTypes?.length > 0 ||
|
||||
control.value.downloadFileTypes?.length > 0
|
||||
? null
|
||||
: { downloadPackage: true }
|
||||
control.value.reportTypes?.length > 0 || control.value.downloadFileTypes?.length > 0 ? null : { downloadPackage: true }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -14,23 +14,16 @@
|
||||
></div>
|
||||
</redaction-side-nav>
|
||||
<div>
|
||||
<div class="content">
|
||||
<div class="heading">
|
||||
{{
|
||||
'edit-dossier-dialog.nav-items.' +
|
||||
(activeNavItem.title || activeNavItem.key) | translate
|
||||
}}
|
||||
<div [class.no-padding]="noPaddingTab" class="content">
|
||||
<div *ngIf="showHeading" class="heading">
|
||||
{{ 'edit-dossier-dialog.nav-items.' + (activeNavItem.title || activeNavItem.key) | translate }}
|
||||
|
||||
<div
|
||||
*ngIf="activeNav === 'dossier-dictionary'"
|
||||
class="small-label stats-subtitle"
|
||||
>
|
||||
<div *ngIf="showSubtitle" class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:entries"></mat-icon>
|
||||
{{
|
||||
'edit-dossier-dialog.dictionary.entries'
|
||||
| translate
|
||||
: { length: (dossierWrapper.type?.entries || []).length }
|
||||
| translate: { length: (dossierWrapper.type?.entries || []).length }
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
@ -59,6 +52,12 @@
|
||||
*ngIf="activeNav === 'members'"
|
||||
[dossierWrapper]="dossierWrapper"
|
||||
></redaction-edit-dossier-team-members>
|
||||
|
||||
<redaction-edit-dossier-attributes
|
||||
(updateDossier)="updatedDossier($event)"
|
||||
*ngIf="activeNav === 'dossier-attributes'"
|
||||
[dossierWrapper]="dossierWrapper"
|
||||
></redaction-edit-dossier-attributes>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
@ -71,18 +70,10 @@
|
||||
{{ 'edit-dossier-dialog.actions.save' | translate }}
|
||||
</button>
|
||||
|
||||
<div
|
||||
(click)="revert()"
|
||||
class="all-caps-label cancel"
|
||||
translate="edit-dossier-dialog.actions.revert"
|
||||
></div>
|
||||
<div (click)="revert()" class="all-caps-label cancel" translate="edit-dossier-dialog.actions.revert"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
height: calc(100% - 81px);
|
||||
box-sizing: border-box;
|
||||
|
||||
.heading {
|
||||
&.no-padding {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::ng-deep .heading {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,12 +6,13 @@ import { DossierWrapper } from '../../../../state/model/dossier.wrapper';
|
||||
import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component';
|
||||
import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component';
|
||||
import { EditDossierSectionInterface } from './edit-dossier-section.interface';
|
||||
import { NotificationService, NotificationType } from '../../../../services/notification.service';
|
||||
import { NotificationService, NotificationType } from '@services/notification.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component';
|
||||
import { EditDossierTeamMembersComponent } from './team-members/edit-dossier-team-members.component';
|
||||
import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component';
|
||||
|
||||
type Section = 'dossier-info' | 'download-package' | 'dossier-dictionary' | 'members';
|
||||
type Section = 'dossier-info' | 'download-package' | 'dossier-dictionary' | 'members' | 'dossier-attributes';
|
||||
|
||||
@Component({
|
||||
templateUrl: './edit-dossier-dialog.component.html',
|
||||
@ -22,20 +23,19 @@ export class EditDossierDialogComponent {
|
||||
{ key: 'dossier-info', title: 'general-info' },
|
||||
{ key: 'download-package', title: 'choose-download' },
|
||||
{ key: 'dossier-dictionary', title: 'dossier-dictionary' },
|
||||
{ key: 'members', title: 'team-members' }
|
||||
{ key: 'members', title: 'team-members' },
|
||||
{ key: 'dossier-attributes' }
|
||||
// TODO:
|
||||
// { key: 'dossier-attributes' },
|
||||
// { key: 'report-attributes' }
|
||||
];
|
||||
activeNav: Section;
|
||||
dossierWrapper: DossierWrapper;
|
||||
|
||||
@ViewChild(EditDossierGeneralInfoComponent)
|
||||
generalInfoComponent: EditDossierGeneralInfoComponent;
|
||||
@ViewChild(EditDossierDownloadPackageComponent)
|
||||
downloadPackageComponent: EditDossierDownloadPackageComponent;
|
||||
@ViewChild(EditDossierGeneralInfoComponent) generalInfoComponent: EditDossierGeneralInfoComponent;
|
||||
@ViewChild(EditDossierDownloadPackageComponent) downloadPackageComponent: EditDossierDownloadPackageComponent;
|
||||
@ViewChild(EditDossierDictionaryComponent) dictionaryComponent: EditDossierDictionaryComponent;
|
||||
@ViewChild(EditDossierTeamMembersComponent) membersComponent: EditDossierTeamMembersComponent;
|
||||
@ViewChild(EditDossierAttributesComponent) attributesComponent: EditDossierAttributesComponent;
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
@ -64,10 +64,23 @@ export class EditDossierDialogComponent {
|
||||
'dossier-info': this.generalInfoComponent,
|
||||
'download-package': this.downloadPackageComponent,
|
||||
'dossier-dictionary': this.dictionaryComponent,
|
||||
members: this.membersComponent
|
||||
members: this.membersComponent,
|
||||
'dossier-attributes': this.attributesComponent
|
||||
}[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) {
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant('edit-dossier-dialog.change-successful'),
|
||||
|
||||
@ -6,14 +6,11 @@ import * as moment from 'moment';
|
||||
import { DossierWrapper } from '../../../../../state/model/dossier.wrapper';
|
||||
import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
|
||||
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 { MatDialogRef } from '@angular/material/dialog';
|
||||
import { EditDossierDialogComponent } from '../edit-dossier-dialog.component';
|
||||
import {
|
||||
NotificationService,
|
||||
NotificationType
|
||||
} from '../../../../../services/notification.service';
|
||||
import { NotificationService, NotificationType } from '@services/notification.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
@ -47,12 +44,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
if (this.hasDueDate !== !!this.dossierWrapper.dueDate) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
this.hasDueDate &&
|
||||
!moment(this.dossierWrapper.dueDate).isSame(
|
||||
moment(this.dossierForm.get(key).value)
|
||||
)
|
||||
) {
|
||||
if (this.hasDueDate && !moment(this.dossierWrapper.dueDate).isSame(moment(this.dossierForm.get(key).value))) {
|
||||
return true;
|
||||
}
|
||||
} else if (this.dossierWrapper[key] !== this.dossierForm.get(key).value) {
|
||||
|
||||
@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core
|
||||
import { AppStateService } from '../../../../../state/app-state.service';
|
||||
import { DossierWrapper } from '../../../../../state/model/dossier.wrapper';
|
||||
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';
|
||||
|
||||
@Component({
|
||||
@ -16,10 +16,7 @@ export class EditDossierTeamMembersComponent implements EditDossierSectionInterf
|
||||
|
||||
@ViewChild(TeamMembersManagerComponent) managerComponent: TeamMembersManagerComponent;
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _permissionsService: PermissionsService
|
||||
) {}
|
||||
constructor(private readonly _appStateService: AppStateService, private readonly _permissionsService: PermissionsService) {}
|
||||
|
||||
get changed() {
|
||||
return this.managerComponent.changed;
|
||||
|
||||
@ -10,7 +10,7 @@ import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry
|
||||
import { ManualAnnotationService } from '../../services/manual-annotation.service';
|
||||
import { ManualAnnotationResponse } from '@models/file/manual-annotation-response';
|
||||
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 {
|
||||
label?: string;
|
||||
@ -76,8 +76,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
|
||||
this.isDocumentAdmin = this._permissionsService.isApprover();
|
||||
|
||||
this.isFalsePositiveRequest = this.manualRedactionEntryWrapper.type === 'FALSE_POSITIVE';
|
||||
this.isDictionaryRequest =
|
||||
this.manualRedactionEntryWrapper.type === 'DICTIONARY' || this.isFalsePositiveRequest;
|
||||
this.isDictionaryRequest = this.manualRedactionEntryWrapper.type === 'DICTIONARY' || this.isFalsePositiveRequest;
|
||||
|
||||
this.redactionForm = this._formBuilder.group({
|
||||
reason: this.isDictionaryRequest ? [null] : [null, Validators.required],
|
||||
@ -87,11 +86,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
|
||||
comment: this.isDocumentAdmin ? [null] : [null, Validators.required]
|
||||
});
|
||||
|
||||
for (const key of Object.keys(
|
||||
this._appStateService.dictionaryData[
|
||||
this._appStateService.activeDossier.dossierTemplateId
|
||||
]
|
||||
)) {
|
||||
for (const key of Object.keys(this._appStateService.dictionaryData[this._appStateService.activeDossier.dossierTemplateId])) {
|
||||
const dictionaryData = this._appStateService.getDictionaryTypeValue(key);
|
||||
if (!dictionaryData.virtual && dictionaryData.addToDictionaryAction) {
|
||||
this.redactionDictionaries.push(dictionaryData);
|
||||
@ -102,15 +97,10 @@ export class ManualAnnotationDialogComponent implements OnInit {
|
||||
|
||||
handleAddRedaction() {
|
||||
this._enhanceManualRedaction(this.manualRedactionEntryWrapper.manualRedactionEntry);
|
||||
this._manualAnnotationService
|
||||
.addAnnotation(this.manualRedactionEntryWrapper.manualRedactionEntry)
|
||||
.subscribe(
|
||||
response =>
|
||||
this.dialogRef.close(
|
||||
new ManualAnnotationResponse(this.manualRedactionEntryWrapper, response)
|
||||
),
|
||||
() => this.dialogRef.close()
|
||||
);
|
||||
this._manualAnnotationService.addAnnotation(this.manualRedactionEntryWrapper.manualRedactionEntry).subscribe(
|
||||
response => this.dialogRef.close(new ManualAnnotationResponse(this.manualRedactionEntryWrapper, response)),
|
||||
() => this.dialogRef.close()
|
||||
);
|
||||
}
|
||||
|
||||
private _enhanceManualRedaction(addRedactionRequest: AddRedactionRequest) {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
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 { AnnotationWrapper } from '../../../../models/file/annotation.wrapper';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-recategorize-image-dialog',
|
||||
|
||||
@ -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 { PageExclusionComponent } from './components/page-exclusion/page-exclusion.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';
|
||||
|
||||
const screens = [
|
||||
DossierListingScreenComponent,
|
||||
DossierOverviewScreenComponent,
|
||||
FilePreviewScreenComponent
|
||||
];
|
||||
const screens = [DossierListingScreenComponent, DossierOverviewScreenComponent, FilePreviewScreenComponent];
|
||||
|
||||
const dialogs = [
|
||||
AddDossierDialogComponent,
|
||||
@ -87,6 +84,7 @@ const components = [
|
||||
EditDossierDownloadPackageComponent,
|
||||
EditDossierDictionaryComponent,
|
||||
EditDossierTeamMembersComponent,
|
||||
EditDossierAttributesComponent,
|
||||
TeamMembersManagerComponent,
|
||||
ScrollButtonComponent,
|
||||
PageExclusionComponent,
|
||||
|
||||
@ -23,11 +23,11 @@ import {
|
||||
dossierTemplateChecker
|
||||
} from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||
import { UserPreferenceService } from '../../../../services/user-preference.service';
|
||||
import { ButtonConfig } from '../../../shared/components/page-header/models/button-config.model';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
|
||||
import { ButtonConfig } from '@shared/components/page-header/models/button-config.model';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { ScreenNames, SortingService } from '../../../../services/sorting.service';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -1,14 +1,4 @@
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
Injector,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
TemplateRef,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, ElementRef, HostListener, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { NavigationStart, Router } from '@angular/router';
|
||||
import { NotificationService, NotificationType } from '@services/notification.service';
|
||||
import { 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 { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import {
|
||||
annotationFilterChecker,
|
||||
keyChecker
|
||||
} from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||
import { annotationFilterChecker, keyChecker } from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
|
||||
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
|
||||
import { FilterConfig } from '@shared/components/page-header/models/filter-config.model';
|
||||
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { FilterService } from '@shared/services/filter.service';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.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({
|
||||
templateUrl: './dossier-overview-screen.component.html',
|
||||
@ -103,15 +90,11 @@ export class DossierOverviewScreenComponent
|
||||
}
|
||||
|
||||
get checkedRequiredFilters() {
|
||||
return this.filterService
|
||||
.getFilter('quickFilters')
|
||||
?.values.filter(f => f.required && f.checked);
|
||||
return this.filterService.getFilter('quickFilters')?.values.filter(f => f.required && f.checked);
|
||||
}
|
||||
|
||||
get checkedNotRequiredFilters() {
|
||||
return this.filterService
|
||||
.getFilter('quickFilters')
|
||||
?.values.filter(f => !f.required && f.checked);
|
||||
return this.filterService.getFilter('quickFilters')?.values.filter(f => !f.required && f.checked);
|
||||
}
|
||||
|
||||
isLastOpenedFile(fileStatus: FileStatusWrapper): boolean {
|
||||
@ -195,11 +178,9 @@ export class DossierOverviewScreenComponent
|
||||
}
|
||||
|
||||
isProcessing(fileStatusWrapper: FileStatusWrapper) {
|
||||
return [
|
||||
FileStatus.StatusEnum.REPROCESS,
|
||||
FileStatus.StatusEnum.FULLREPROCESS,
|
||||
FileStatus.StatusEnum.PROCESSING
|
||||
].includes(fileStatusWrapper.status);
|
||||
return [FileStatus.StatusEnum.REPROCESS, FileStatus.StatusEnum.FULLREPROCESS, FileStatus.StatusEnum.PROCESSING].includes(
|
||||
fileStatusWrapper.status
|
||||
);
|
||||
}
|
||||
|
||||
reloadDossiers() {
|
||||
@ -280,9 +261,7 @@ export class DossierOverviewScreenComponent
|
||||
}
|
||||
|
||||
recentlyModifiedChecker = (file: FileStatusWrapper) =>
|
||||
moment(file.lastUpdated)
|
||||
.add(this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS), 'hours')
|
||||
.isAfter(moment());
|
||||
moment(file.lastUpdated).add(this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS), 'hours').isAfter(moment());
|
||||
|
||||
private _loadEntitiesFromState() {
|
||||
if (this.activeDossier) this._screenStateService.setEntities(this.activeDossier.files);
|
||||
@ -309,8 +288,7 @@ export class DossierOverviewScreenComponent
|
||||
allDistinctFileStatusWrapper.add(file.status);
|
||||
allDistinctAddedDates.add(moment(file.added).format('DD/MM/YYYY'));
|
||||
|
||||
if (this.permissionsService.fileRequiresReanalysis(file))
|
||||
allDistinctNeedsWork.add('analysis');
|
||||
if (this.permissionsService.fileRequiresReanalysis(file)) allDistinctNeedsWork.add('analysis');
|
||||
if (file.hintsOnly) allDistinctNeedsWork.add('hint');
|
||||
if (file.hasRedactions) allDistinctNeedsWork.add('redaction');
|
||||
if (file.hasRequests) allDistinctNeedsWork.add('suggestion');
|
||||
@ -377,10 +355,7 @@ export class DossierOverviewScreenComponent
|
||||
checker: (file: FileStatusWrapper) =>
|
||||
this.checkedRequiredFilters.reduce((acc, f) => acc && f.checker(file), true) &&
|
||||
(this.checkedNotRequiredFilters.length === 0 ||
|
||||
this.checkedNotRequiredFilters.reduce(
|
||||
(acc, f) => acc || f.checker(file),
|
||||
false
|
||||
))
|
||||
this.checkedNotRequiredFilters.reduce((acc, f) => acc || f.checker(file), false))
|
||||
});
|
||||
|
||||
this._createActionConfigs();
|
||||
@ -389,9 +364,7 @@ export class DossierOverviewScreenComponent
|
||||
private _createQuickFilters() {
|
||||
let quickFilters = [];
|
||||
if (this._screenStateService.entities.filter(this.recentlyModifiedChecker).length > 0) {
|
||||
const recentPeriod = this._appConfigService.getConfig(
|
||||
AppConfigKey.RECENT_PERIOD_IN_HOURS
|
||||
);
|
||||
const recentPeriod = this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS);
|
||||
quickFilters = [
|
||||
{
|
||||
key: 'recent',
|
||||
@ -408,9 +381,7 @@ export class DossierOverviewScreenComponent
|
||||
...quickFilters,
|
||||
{
|
||||
key: 'assigned-to-me',
|
||||
label: this._translateService.instant(
|
||||
'dossier-overview.quick-filters.assigned-to-me'
|
||||
),
|
||||
label: this._translateService.instant('dossier-overview.quick-filters.assigned-to-me'),
|
||||
checker: (file: FileStatusWrapper) => file.currentReviewer === this.user.id
|
||||
},
|
||||
{
|
||||
@ -420,11 +391,8 @@ export class DossierOverviewScreenComponent
|
||||
},
|
||||
{
|
||||
key: 'assigned-to-others',
|
||||
label: this._translateService.instant(
|
||||
'dossier-overview.quick-filters.assigned-to-others'
|
||||
),
|
||||
checker: (file: FileStatusWrapper) =>
|
||||
!!file.currentReviewer && file.currentReviewer !== this.user.id
|
||||
label: this._translateService.instant('dossier-overview.quick-filters.assigned-to-others'),
|
||||
checker: (file: FileStatusWrapper) => !!file.currentReviewer && file.currentReviewer !== this.user.id
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
HostListener,
|
||||
NgZone,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, HostListener, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
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 { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
|
||||
import {
|
||||
handleFilterDelta,
|
||||
processFilters
|
||||
} from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { handleFilterDelta, processFilters } from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { stampPDFPage } from '../../../../utils/page-stamper';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@ -117,9 +106,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
}
|
||||
|
||||
get assignTooltip(): string {
|
||||
return this.appStateService.activeFile.isUnderApproval
|
||||
? 'dossier-overview.assign-approver'
|
||||
: this.assignOrChangeReviewerTooltip;
|
||||
return this.appStateService.activeFile.isUnderApproval ? 'dossier-overview.assign-approver' : this.assignOrChangeReviewerTooltip;
|
||||
}
|
||||
|
||||
get annotations(): AnnotationWrapper[] {
|
||||
@ -139,25 +126,15 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
}
|
||||
|
||||
get canSwitchToRedactedView() {
|
||||
return (
|
||||
this.fileData &&
|
||||
!this.permissionsService.fileRequiresReanalysis() &&
|
||||
!this.fileData.fileStatus.isExcluded
|
||||
);
|
||||
return this.fileData && !this.permissionsService.fileRequiresReanalysis() && !this.fileData.fileStatus.isExcluded;
|
||||
}
|
||||
|
||||
get canSwitchToDeltaView() {
|
||||
return (
|
||||
this.fileData?.redactionChangeLog?.redactionLogEntry?.length > 0 &&
|
||||
!this.fileData.fileStatus.isExcluded
|
||||
);
|
||||
return this.fileData?.redactionChangeLog?.redactionLogEntry?.length > 0 && !this.fileData.fileStatus.isExcluded;
|
||||
}
|
||||
|
||||
get canAssign(): boolean {
|
||||
return (
|
||||
!this.editingReviewer &&
|
||||
(this.permissionsService.canAssignUser() || this.permissionsService.canAssignToSelf())
|
||||
);
|
||||
return !this.editingReviewer && (this.permissionsService.canAssignUser() || this.permissionsService.canAssignToSelf());
|
||||
}
|
||||
|
||||
get displayData() {
|
||||
@ -181,9 +158,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
}
|
||||
|
||||
get assignOrChangeReviewerTooltip() {
|
||||
return this.currentReviewer
|
||||
? 'file-preview.change-reviewer'
|
||||
: 'file-preview.assign-reviewer';
|
||||
return this.currentReviewer ? 'file-preview.change-reviewer' : 'file-preview.assign-reviewer';
|
||||
}
|
||||
|
||||
get currentReviewer(): string {
|
||||
@ -204,9 +179,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
|
||||
get canAssignReviewer(): boolean {
|
||||
return (
|
||||
!this.currentReviewer &&
|
||||
this.permissionsService.canAssignUser() &&
|
||||
this.appStateService.activeDossier.hasMoreThanOneReviewer
|
||||
!this.currentReviewer && this.permissionsService.canAssignUser() && this.appStateService.activeDossier.hasMoreThanOneReviewer
|
||||
);
|
||||
}
|
||||
|
||||
@ -217,12 +190,8 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
switch (this.viewMode) {
|
||||
case 'STANDARD': {
|
||||
this._setAnnotationsColor(redactions, 'annotationColor');
|
||||
const standardEntries = annotations.filter(
|
||||
a => !a.getCustomData('changeLogRemoved')
|
||||
);
|
||||
const nonStandardEntries = annotations.filter(a =>
|
||||
a.getCustomData('changeLogRemoved')
|
||||
);
|
||||
const standardEntries = annotations.filter(a => !a.getCustomData('changeLogRemoved'));
|
||||
const nonStandardEntries = annotations.filter(a => a.getCustomData('changeLogRemoved'));
|
||||
this._show(standardEntries);
|
||||
this._hide(nonStandardEntries);
|
||||
break;
|
||||
@ -271,9 +240,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
this._updateCanPerformActions();
|
||||
try {
|
||||
const key = 'Dossier-Recent-' + this.dossierId;
|
||||
await this._userPreferenceControllerService
|
||||
.savePreferences([this.fileId], key)
|
||||
.toPromise();
|
||||
await this._userPreferenceControllerService.savePreferences([this.fileId], key).toPromise();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
@ -299,35 +266,22 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
console.log(
|
||||
'[REDACTION] Delete previous annotations time: ' +
|
||||
(new Date().getTime() - startTime) +
|
||||
'ms'
|
||||
);
|
||||
console.log('[REDACTION] Delete previous annotations time: ' + (new Date().getTime() - startTime) + 'ms');
|
||||
const processStartTime = new Date().getTime();
|
||||
this.annotationData = this.fileData.getAnnotations(
|
||||
this.appStateService.dictionaryData[
|
||||
this.appStateService.activeDossier.dossierTemplateId
|
||||
],
|
||||
this.appStateService.dictionaryData[this.appStateService.activeDossier.dossierTemplateId],
|
||||
this.permissionsService.currentUser,
|
||||
this.viewMode,
|
||||
this.userPreferenceService.areDevFeaturesEnabled
|
||||
);
|
||||
const annotationFilters = this._annotationProcessingService.getAnnotationFilter(
|
||||
this.annotations
|
||||
);
|
||||
const annotationFilters = this._annotationProcessingService.getAnnotationFilter(this.annotations);
|
||||
this.primaryFilters = processFilters(this.primaryFilters, annotationFilters);
|
||||
this.secondaryFilters = processFilters(
|
||||
this.secondaryFilters,
|
||||
AnnotationProcessingService.secondaryAnnotationFilters
|
||||
);
|
||||
this.secondaryFilters = processFilters(this.secondaryFilters, AnnotationProcessingService.secondaryAnnotationFilters);
|
||||
this._workloadComponent?.filtersChanged({
|
||||
primary: this.primaryFilters,
|
||||
secondary: this.secondaryFilters
|
||||
});
|
||||
console.log(
|
||||
'[REDACTION] Process time: ' + (new Date().getTime() - processStartTime) + 'ms'
|
||||
);
|
||||
console.log('[REDACTION] Process time: ' + (new Date().getTime() - processStartTime) + 'ms');
|
||||
console.log(
|
||||
'[REDACTION] Annotation Redraw and filter rebuild time: ' +
|
||||
(new Date().getTime() - startTime) +
|
||||
@ -348,11 +302,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
selectAnnotations(
|
||||
annotations?:
|
||||
| AnnotationWrapper[]
|
||||
| { annotations: AnnotationWrapper[]; multiSelect: boolean }
|
||||
) {
|
||||
selectAnnotations(annotations?: AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }) {
|
||||
if (annotations) {
|
||||
this.viewerComponent.utils.selectAnnotations(annotations);
|
||||
} else {
|
||||
@ -371,24 +321,19 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
|
||||
openManualAnnotationDialog($event: ManualRedactionEntryWrapper) {
|
||||
this._ngZone.run(() => {
|
||||
this.dialogRef = this._dialogService.openManualAnnotationDialog(
|
||||
$event,
|
||||
async (response: ManualAnnotationResponse) => {
|
||||
if (response?.annotationId) {
|
||||
const annotation = this._instance.annotManager.getAnnotationById(
|
||||
response.manualRedactionEntryWrapper.rectId
|
||||
);
|
||||
this._instance.annotManager.deleteAnnotation(annotation);
|
||||
this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
|
||||
const distinctPages = $event.manualRedactionEntry.positions
|
||||
.map(p => p.page)
|
||||
.filter((item, pos, self) => self.indexOf(item) === pos);
|
||||
distinctPages.forEach(page => {
|
||||
this._cleanupAndRedrawManualAnnotationsForEntirePage(page);
|
||||
});
|
||||
}
|
||||
this.dialogRef = this._dialogService.openManualAnnotationDialog($event, async (response: ManualAnnotationResponse) => {
|
||||
if (response?.annotationId) {
|
||||
const annotation = this._instance.annotManager.getAnnotationById(response.manualRedactionEntryWrapper.rectId);
|
||||
this._instance.annotManager.deleteAnnotation(annotation);
|
||||
this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
|
||||
const distinctPages = $event.manualRedactionEntry.positions
|
||||
.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;
|
||||
}
|
||||
|
||||
if (
|
||||
!ALL_HOTKEY_ARRAY.includes($event.key) ||
|
||||
this.dialogRef?.getState() === MatDialogState.OPEN
|
||||
) {
|
||||
if (!ALL_HOTKEY_ARRAY.includes($event.key) || this.dialogRef?.getState() === MatDialogState.OPEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -524,9 +466,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
const reviewerName = this.userService.getNameForId(reviewerId);
|
||||
|
||||
const { dossierId, fileId, filename } = this.fileData.fileStatus;
|
||||
await this._statusControllerService
|
||||
.setFileReviewer(dossierId, fileId, reviewerId)
|
||||
.toPromise();
|
||||
await this._statusControllerService.setFileReviewer(dossierId, fileId, reviewerId).toPromise();
|
||||
|
||||
const msg = `Successfully assigned ${reviewerName} to file: ${filename}`;
|
||||
this._notificationService.showToastNotification(msg);
|
||||
@ -549,13 +489,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
|
||||
downloadOriginalFile() {
|
||||
this._fileManagementControllerService
|
||||
.downloadOriginalFile(
|
||||
this.dossierId,
|
||||
this.fileId,
|
||||
true,
|
||||
this.fileData.fileStatus.cacheIdentifier,
|
||||
'response'
|
||||
)
|
||||
.downloadOriginalFile(this.dossierId, this.fileId, true, this.fileData.fileStatus.cacheIdentifier, 'response')
|
||||
.subscribe(data => {
|
||||
download(data, this.fileData.fileStatus.filename);
|
||||
});
|
||||
@ -608,17 +542,15 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
this.filesAutoUpdateTimer = timer(0, 5000)
|
||||
.pipe(tap(async () => await this.appStateService.reloadActiveFile()))
|
||||
.subscribe();
|
||||
this.fileReanalysedSubscription = this.appStateService.fileReanalysed.subscribe(
|
||||
async (fileStatus: FileStatusWrapper) => {
|
||||
if (fileStatus.fileId === this.fileId) {
|
||||
await this._loadFileData(!this._reloadFileOnReanalysis);
|
||||
this._reloadFileOnReanalysis = false;
|
||||
this.viewReady = true;
|
||||
this._updateCanPerformActions();
|
||||
this._cleanupAndRedrawManualAnnotations();
|
||||
}
|
||||
this.fileReanalysedSubscription = this.appStateService.fileReanalysed.subscribe(async (fileStatus: FileStatusWrapper) => {
|
||||
if (fileStatus.fileId === this.fileId) {
|
||||
await this._loadFileData(!this._reloadFileOnReanalysis);
|
||||
this._reloadFileOnReanalysis = false;
|
||||
this.viewReady = true;
|
||||
this._updateCanPerformActions();
|
||||
this._cleanupAndRedrawManualAnnotations();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private _unsubscribeFromFileUpdates(): void {
|
||||
@ -663,10 +595,8 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
/* Get the documentElement (<html>) to display the page in fullscreen */
|
||||
|
||||
private _cleanupAndRedrawManualAnnotations() {
|
||||
this._fileDownloadService
|
||||
.loadActiveFileRedactionLogPreview()
|
||||
.subscribe(redactionLogPreview => {
|
||||
this.fileData.redactionLog = redactionLogPreview;
|
||||
this._fileDownloadService.loadActiveFileRedactionLogPreview().subscribe(redactionLogPreview => {
|
||||
this.fileData.redactionLog = redactionLogPreview;
|
||||
this._annotationDrawService.drawAnnotations(
|
||||
this._instance,
|
||||
this.annotationData.allAnnotations,
|
||||
@ -681,18 +611,14 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
const currentPageAnnotationIds = currentPageAnnotations.map(a => a.id);
|
||||
this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
|
||||
|
||||
this._fileDownloadService
|
||||
.loadActiveFileRedactionLogPreview()
|
||||
.subscribe(redactionLogPreview => {
|
||||
this.fileData.redactionLog = redactionLogPreview;
|
||||
this._fileDownloadService.loadActiveFileRedactionLogPreview().subscribe(redactionLogPreview => {
|
||||
this.fileData.redactionLog = redactionLogPreview;
|
||||
this.rebuildFilters();
|
||||
if (this.viewMode === 'STANDARD') {
|
||||
currentPageAnnotationIds.forEach(id => {
|
||||
this._findAndDeleteAnnotation(id);
|
||||
});
|
||||
const newPageAnnotations = this.annotations.filter(
|
||||
item => item.pageNumber === page
|
||||
);
|
||||
const newPageAnnotations = this.annotations.filter(item => item.pageNumber === page);
|
||||
this._handleDeltaAnnotationFilters(currentPageAnnotations, newPageAnnotations);
|
||||
this._annotationDrawService.drawAnnotations(
|
||||
this._instance,
|
||||
@ -704,22 +630,16 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy, OnAttach,
|
||||
});
|
||||
}
|
||||
|
||||
private _handleDeltaAnnotationFilters(
|
||||
currentPageAnnotations: AnnotationWrapper[],
|
||||
newPageAnnotations: AnnotationWrapper[]
|
||||
) {
|
||||
private _handleDeltaAnnotationFilters(currentPageAnnotations: AnnotationWrapper[], newPageAnnotations: AnnotationWrapper[]) {
|
||||
const hasAnyFilterSet =
|
||||
this.primaryFilters.find(f => f.checked || f.indeterminate) ||
|
||||
this.secondaryFilters.find(f => f.checked || f.indeterminate);
|
||||
this.primaryFilters.find(f => f.checked || f.indeterminate) || this.secondaryFilters.find(f => f.checked || f.indeterminate);
|
||||
|
||||
if (!hasAnyFilterSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldPageSpecificFilters =
|
||||
this._annotationProcessingService.getAnnotationFilter(currentPageAnnotations);
|
||||
const newPageSpecificFilters =
|
||||
this._annotationProcessingService.getAnnotationFilter(newPageAnnotations);
|
||||
const oldPageSpecificFilters = this._annotationProcessingService.getAnnotationFilter(currentPageAnnotations);
|
||||
const newPageSpecificFilters = this._annotationProcessingService.getAnnotationFilter(newPageAnnotations);
|
||||
handleFilterDelta(oldPageSpecificFilters, newPageSpecificFilters, this.primaryFilters);
|
||||
this._workloadComponent.filtersChanged({
|
||||
primary: this.primaryFilters,
|
||||
|
||||
@ -17,12 +17,12 @@ import { ManualAnnotationService } from './manual-annotation.service';
|
||||
import { ManualAnnotationDialogComponent } from '../dialogs/manual-redaction-dialog/manual-annotation-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 { 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 { AppConfigService } from '../../app-config/app-config.service';
|
||||
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 { DialogService } from '../../shared/services/dialog.service';
|
||||
import { DialogService } from '@shared/services/dialog.service';
|
||||
import { ComponentType } from '@angular/cdk/portal';
|
||||
|
||||
const dialogConfig = {
|
||||
@ -67,10 +67,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
|
||||
super(_dialog);
|
||||
}
|
||||
|
||||
openManualAnnotationDialog(
|
||||
$event: ManualRedactionEntryWrapper,
|
||||
cb?: Function
|
||||
): MatDialogRef<ManualAnnotationDialogComponent> {
|
||||
openManualAnnotationDialog($event: ManualRedactionEntryWrapper, cb?: Function): MatDialogRef<ManualAnnotationDialogComponent> {
|
||||
const ref = this._dialog.open(ManualAnnotationDialogComponent, {
|
||||
...dialogConfig,
|
||||
autoFocus: true,
|
||||
@ -96,13 +93,11 @@ export class DossiersDialogService extends DialogService<DialogType> {
|
||||
const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig);
|
||||
ref.afterClosed().subscribe(result => {
|
||||
if (result) {
|
||||
this._manualAnnotationService
|
||||
.approveRequest(annotation.id)
|
||||
.subscribe(acceptResult => {
|
||||
if (callback) {
|
||||
callback(acceptResult);
|
||||
}
|
||||
});
|
||||
this._manualAnnotationService.approveRequest(annotation.id).subscribe(acceptResult => {
|
||||
if (callback) {
|
||||
callback(acceptResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -132,10 +127,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
|
||||
return ref;
|
||||
}
|
||||
|
||||
openForceRedactionDialog(
|
||||
$event: MouseEvent,
|
||||
cb?: Function
|
||||
): MatDialogRef<ForceRedactionDialogComponent> {
|
||||
openForceRedactionDialog($event: MouseEvent, cb?: Function): MatDialogRef<ForceRedactionDialogComponent> {
|
||||
$event?.stopPropagation();
|
||||
const ref = this._dialog.open(ForceRedactionDialogComponent, {
|
||||
...dialogConfig
|
||||
@ -203,11 +195,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
|
||||
return ref;
|
||||
}
|
||||
|
||||
openDeleteDossierDialog(
|
||||
$event: MouseEvent,
|
||||
dossier: DossierWrapper,
|
||||
cb?: Function
|
||||
): MatDialogRef<ConfirmationDialogComponent> {
|
||||
openDeleteDossierDialog($event: MouseEvent, dossier: DossierWrapper, cb?: Function): MatDialogRef<ConfirmationDialogComponent> {
|
||||
$event.stopPropagation();
|
||||
const period = this._appConfigService.getConfig('DELETE_RETENTION_HOURS');
|
||||
const ref = this._dialog.open(ConfirmationDialogComponent, {
|
||||
@ -299,11 +287,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
|
||||
return ref;
|
||||
}
|
||||
|
||||
openRemoveAnnotationModal(
|
||||
$event: MouseEvent,
|
||||
annotation: AnnotationWrapper,
|
||||
callback: () => void
|
||||
) {
|
||||
openRemoveAnnotationModal($event: MouseEvent, annotation: AnnotationWrapper, callback: () => void) {
|
||||
$event?.stopPropagation();
|
||||
|
||||
const ref = this._dialog.open(ConfirmationDialogComponent, {
|
||||
@ -313,13 +297,11 @@ export class DossiersDialogService extends DialogService<DialogType> {
|
||||
|
||||
ref.afterClosed().subscribe(result => {
|
||||
if (result) {
|
||||
this._manualAnnotationService
|
||||
.removeOrSuggestRemoveAnnotation(annotation)
|
||||
.subscribe(() => {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
this._manualAnnotationService.removeOrSuggestRemoveAnnotation(annotation).subscribe(() => {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
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 { Rectangle } from '@redaction/red-ui-http';
|
||||
import { AnnotationWrapper } from '../../../models/file/annotation.wrapper';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
|
||||
const DISABLED_HOTKEYS = [
|
||||
'CTRL+SHIFT+EQUAL',
|
||||
@ -74,9 +74,7 @@ export class PdfViewerUtils {
|
||||
}
|
||||
|
||||
try {
|
||||
return this.isCompareMode
|
||||
? Math.ceil(this.instance?.docViewer?.getPageCount() / 2)
|
||||
: this.instance?.docViewer?.getPageCount();
|
||||
return this.isCompareMode ? Math.ceil(this.instance?.docViewer?.getPageCount() / 2) : this.instance?.docViewer?.getPageCount();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return null;
|
||||
@ -93,9 +91,7 @@ export class PdfViewerUtils {
|
||||
|
||||
navigateToPage(pageNumber: string | number) {
|
||||
const parsedNumber = typeof pageNumber === 'string' ? parseInt(pageNumber, 10) : pageNumber;
|
||||
this._navigateToPage(
|
||||
this.paginationOffset === 2 ? parsedNumber * this.paginationOffset - 1 : parsedNumber
|
||||
);
|
||||
this._navigateToPage(this.paginationOffset === 2 ? parsedNumber * this.paginationOffset - 1 : parsedNumber);
|
||||
}
|
||||
|
||||
previousPage() {
|
||||
@ -106,12 +102,7 @@ export class PdfViewerUtils {
|
||||
|
||||
nextPage() {
|
||||
if (this._currentInternalPage < this._totalInternalPages) {
|
||||
this._navigateToPage(
|
||||
Math.min(
|
||||
this._currentInternalPage + this.paginationOffset,
|
||||
this._totalInternalPages
|
||||
)
|
||||
);
|
||||
this._navigateToPage(Math.min(this._currentInternalPage + this.paginationOffset, this._totalInternalPages));
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,9 +135,7 @@ export class PdfViewerUtils {
|
||||
this.instance.annotManager.deselectAllAnnotations();
|
||||
}
|
||||
|
||||
selectAnnotations(
|
||||
$event: AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }
|
||||
) {
|
||||
selectAnnotations($event: AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }) {
|
||||
let annotations: AnnotationWrapper[];
|
||||
let multiSelect: boolean;
|
||||
if ($event instanceof Array) {
|
||||
|
||||
@ -14,11 +14,7 @@ export function processFilters(oldFilters: FilterModel[], newFilters: FilterMode
|
||||
return newFilters;
|
||||
}
|
||||
|
||||
export function handleFilterDelta(
|
||||
oldFilters: FilterModel[],
|
||||
newFilters: FilterModel[],
|
||||
allFilters: FilterModel[]
|
||||
) {
|
||||
export function handleFilterDelta(oldFilters: FilterModel[], newFilters: FilterModel[], allFilters: FilterModel[]) {
|
||||
const newFiltersDelta = {};
|
||||
for (const newFilter of newFilters) {
|
||||
const oldFilter = oldFilters.find(f => f.key === newFilter.key);
|
||||
@ -87,13 +83,7 @@ export function handleCheckedValue(filter: FilterModel) {
|
||||
}
|
||||
}
|
||||
|
||||
export function checkFilter(
|
||||
entity: any,
|
||||
filters: FilterModel[],
|
||||
validate: Function,
|
||||
validateArgs: any = [],
|
||||
matchAll: boolean = false
|
||||
) {
|
||||
export function checkFilter(entity: any, filters: FilterModel[], validate: Function, validateArgs: any = [], matchAll: boolean = false) {
|
||||
const hasChecked = filters.find(f => f.checked);
|
||||
|
||||
if (validateArgs) {
|
||||
@ -121,8 +111,7 @@ export function checkFilter(
|
||||
return filterMatched;
|
||||
}
|
||||
|
||||
export const keyChecker = (key: string) => (entity: any, filter: FilterModel) =>
|
||||
entity[key] === filter.key;
|
||||
export const keyChecker = (key: string) => (entity: any, filter: FilterModel) => entity[key] === filter.key;
|
||||
|
||||
export const annotationFilterChecker = (
|
||||
input: FileStatusWrapper | DossierWrapper,
|
||||
@ -158,38 +147,24 @@ export const annotationFilterChecker = (
|
||||
}
|
||||
};
|
||||
|
||||
export const dossierStatusChecker = (dw: DossierWrapper, filter: FilterModel) =>
|
||||
dw.hasStatus(filter.key);
|
||||
export const dossierStatusChecker = (dw: DossierWrapper, filter: FilterModel) => dw.hasStatus(filter.key);
|
||||
|
||||
export const dossierMemberChecker = (dw: DossierWrapper, filter: FilterModel) =>
|
||||
dw.hasMember(filter.key);
|
||||
export const dossierMemberChecker = (dw: DossierWrapper, filter: FilterModel) => dw.hasMember(filter.key);
|
||||
|
||||
export const dossierTemplateChecker = (dw: DossierWrapper, filter: FilterModel) =>
|
||||
dw.dossierTemplateId === filter.key;
|
||||
export const dossierTemplateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.dossierTemplateId === filter.key;
|
||||
|
||||
export const dueDateChecker = (dw: DossierWrapper, filter: FilterModel) =>
|
||||
dw.dueDateMatches(filter.key);
|
||||
export const dueDateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.dueDateMatches(filter.key);
|
||||
|
||||
export const addedDateChecker = (dw: DossierWrapper, filter: FilterModel) =>
|
||||
dw.addedDateMatches(filter.key);
|
||||
export const addedDateChecker = (dw: DossierWrapper, filter: FilterModel) => dw.addedDateMatches(filter.key);
|
||||
|
||||
export const dossierApproverChecker = (dw: DossierWrapper, filter: FilterModel) =>
|
||||
dw.approverIds.includes(filter.key);
|
||||
export const dossierApproverChecker = (dw: DossierWrapper, filter: FilterModel) => dw.approverIds.includes(filter.key);
|
||||
|
||||
export function getFilteredEntities<T>(entities: T[], filters: FilterWrapper[]) {
|
||||
const filteredEntities: T[] = [];
|
||||
for (const entity of entities) {
|
||||
let add = true;
|
||||
for (const filter of filters) {
|
||||
add =
|
||||
add &&
|
||||
checkFilter(
|
||||
entity,
|
||||
filter.values,
|
||||
filter.checker,
|
||||
filter.checkerArgs,
|
||||
filter.matchAll
|
||||
);
|
||||
add = add && checkFilter(entity, filter.values, filter.checker, filter.checkerArgs, filter.matchAll);
|
||||
}
|
||||
if (add) {
|
||||
filteredEntities.push(entity);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
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 { DictionaryControllerService } from '@redaction/red-ui-http';
|
||||
import { tap } from 'rxjs/operators';
|
||||
@ -36,20 +36,9 @@ export class DictionarySaveService {
|
||||
// can add at least 1 - block UI
|
||||
let obs: Observable<any>;
|
||||
if (entriesToAdd.length > 0) {
|
||||
obs = this._dictionaryControllerService.addEntry(
|
||||
entriesToAdd,
|
||||
dossierTemplateId,
|
||||
type,
|
||||
dossierId,
|
||||
true
|
||||
);
|
||||
obs = this._dictionaryControllerService.addEntry(entriesToAdd, dossierTemplateId, type, dossierId, true);
|
||||
} else {
|
||||
obs = this._dictionaryControllerService.deleteEntries(
|
||||
initialEntries,
|
||||
dossierTemplateId,
|
||||
type,
|
||||
dossierId
|
||||
);
|
||||
obs = this._dictionaryControllerService.deleteEntries(initialEntries, dossierTemplateId, type, dossierId);
|
||||
}
|
||||
|
||||
return obs.pipe(
|
||||
@ -57,9 +46,7 @@ export class DictionarySaveService {
|
||||
() => {
|
||||
if (showToast) {
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant(
|
||||
'dictionary-overview.success.generic'
|
||||
),
|
||||
this._translateService.instant('dictionary-overview.success.generic'),
|
||||
null,
|
||||
NotificationType.SUCCESS
|
||||
);
|
||||
|
||||
@ -831,7 +831,9 @@
|
||||
"general-info": "General Information",
|
||||
"members": "Members",
|
||||
"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."
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user