Merge branch 'master' into VM/NotificationsPreferences

This commit is contained in:
Valentin 2021-11-01 14:57:03 +02:00
commit ffd75f5f6f
244 changed files with 925 additions and 1660 deletions

View File

@ -11,7 +11,6 @@
{
"enforceBuildableLibDependency": true,
"allow": [
"@redaction/red-ui-http",
"@redaction/red-cache",
"@services/**",
"@components/**",

View File

@ -210,41 +210,6 @@
"outputs": ["coverage/apps/red-ui"]
}
}
},
"red-ui-http": {
"projectType": "library",
"root": "libs/red-ui-http",
"sourceRoot": "libs/red-ui-http/src",
"prefix": "redaction",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:ng-packagr",
"options": {
"tsConfig": "libs/red-ui-http/tsconfig.lib.json",
"project": "libs/red-ui-http/ng-package.json"
}
},
"lint": {
"builder": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": ["libs/red-ui-http/src/**/*.ts", "libs/red-ui-http/src/**/*.html"]
},
"outputs": ["{options.outputFile}"]
},
"test": {
"builder": "@nrwl/jest:jest",
"options": {
"jestConfig": "libs/red-ui-http/jest.config.js",
"passWithNoTests": true
},
"outputs": ["coverage/libs/red-ui-http"]
}
},
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
}
}
}
}

View File

@ -1,6 +1,6 @@
import { Component, forwardRef, Injector } from '@angular/core';
import { FileDownloadService } from '@upload-download/services/file-download.service';
import { DownloadStatus } from '@upload-download/model/download-status';
import { DownloadStatus } from '@red/domain';
import {
CircleButtonTypes,
DefaultListingServicesTmp,

View File

@ -10,10 +10,14 @@
[verticalPadding]="0"
></iqser-empty-state>
<div *ngFor="let group of groups">
<div class="all-caps-label">{{ group.date }}</div>
<div *ngFor="let group of groups; let first = first">
<div class="all-caps-label flex-align-items-center">
<div>{{ group.date }}</div>
<div *ngIf="(hasUnreadNotifications$ | async) && first" class="view-all" (click)="markRead($event)">View all</div>
</div>
<div
(click)="markRead(notification, $event)"
(click)="markRead($event, [notification.id])"
*ngFor="let notification of group.notifications | sortBy: 'desc':'creationDate'"
[class.unread]="!notification.readDate"
class="notification"
@ -25,7 +29,7 @@
<div class="small-label mt-2">{{ notification.time }}</div>
</div>
<div
(click)="markRead(notification, $event, !notification.readDate)"
(click)="markRead($event, [notification.id], !notification.readDate)"
class="dot"
matTooltip="{{ 'notifications.mark-as' | translate: { type: notification.readDate ? 'unread' : 'read' } }}"
matTooltipPosition="before"

View File

@ -15,7 +15,15 @@
max-height: calc(100vh - 200px);
.all-caps-label {
margin: 16px 0 6px 8px;
justify-content: space-between;
margin: 16px 8px 6px;
.view-all {
cursor: pointer;
&:hover {
color: var(--iqser-primary);
}
}
}
.mat-menu-item.notification {

View File

@ -6,8 +6,9 @@ import { UserService } from '@services/user.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { NotificationsService } from '@services/notifications.service';
import { Notification } from '@red/domain';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { distinctUntilChanged, map, shareReplay } from 'rxjs/operators';
import { BehaviorSubject, Observable } from 'rxjs';
import { List } from '@iqser/common-ui';
interface NotificationsGroup {
date: string;
@ -39,6 +40,7 @@ export class NotificationsComponent implements OnInit {
this.hasUnreadNotifications$ = this.notifications$.pipe(
map(notifications => notifications.filter(n => !n.readDate).length > 0),
distinctUntilChanged(),
shareReplay(1),
);
}
@ -46,9 +48,9 @@ export class NotificationsComponent implements OnInit {
await this._loadData();
}
async markRead(notification: Notification, $event, isRead = true): Promise<void> {
async markRead($event, notifications: List<string> = this._notifications$.getValue().map(n => n.id), isRead = true): Promise<void> {
$event.stopPropagation();
await this._notificationsService.toggleNotificationRead([notification.id], isRead).toPromise();
await this._notificationsService.toggleNotificationRead(notifications, isRead).toPromise();
await this._loadData();
}

View File

@ -1,7 +1,7 @@
import { Comment, Point, Rectangle } from '@redaction/red-ui-http';
import { RedactionLogEntryWrapper } from './redaction-log-entry.wrapper';
import { annotationTypesTranslations } from '../../translations/annotation-types-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { IComment, IPoint, IRectangle } from '@red/domain';
export type AnnotationSuperType =
| 'add-dictionary'
@ -29,8 +29,8 @@ export class AnnotationWrapper {
typeValue: string;
recategorizationType: string;
color: string;
comments: Comment[] = [];
firstTopLeftPoint: Point;
comments: IComment[] = [];
firstTopLeftPoint: IPoint;
annotationId: string;
shortContent: string;
content: string;
@ -41,7 +41,7 @@ export class AnnotationWrapper {
redaction: boolean;
status: string;
dictionaryOperation: boolean;
positions: Rectangle[];
positions: IRectangle[];
recommendationType: string;
legalBasisValue: string;
legalBasisChangeValue?: string;

View File

@ -1,10 +1,7 @@
import { RedactionLog, RedactionLogEntry } from '@redaction/red-ui-http';
import { File } from './file';
import { Dictionary, File, IRedactionLog, IRedactionLogEntry, IViewedPage, User, ViewMode } from '@red/domain';
import { AnnotationWrapper } from './annotation.wrapper';
import { RedactionLogEntryWrapper } from './redaction-log-entry.wrapper';
import { ViewMode } from './view-mode';
import * as moment from 'moment';
import { Dictionary, IViewedPage, User } from '@red/domain';
export class AnnotationData {
visibleAnnotations: AnnotationWrapper[];
@ -16,7 +13,7 @@ export class FileDataModel {
hasChangeLog: boolean;
constructor(public file: File, public fileData: Blob, public redactionLog: RedactionLog, public viewedPages?: IViewedPage[]) {}
constructor(public file: File, public fileData: Blob, public redactionLog: IRedactionLog, public viewedPages?: IViewedPage[]) {}
getAnnotations(
dictionaryData: { [p: string]: Dictionary },
@ -103,7 +100,7 @@ export class FileDataModel {
return result;
}
private _isChangeLogEntry(redactionLogEntry: RedactionLogEntry, wrapper: RedactionLogEntryWrapper) {
private _isChangeLogEntry(redactionLogEntry: IRedactionLogEntry, wrapper: RedactionLogEntryWrapper) {
if (this.file.numberOfAnalyses > 1) {
redactionLogEntry.changes.sort((a, b) => moment(a.dateTime).valueOf() - moment(b.dateTime).valueOf());

View File

@ -1,6 +0,0 @@
export enum FileType {
ORIGINAL = 'ORIGINAL',
ANNOTATED = 'ANNOTATED',
REDACTED = 'REDACTED',
FLAT_REDACTED = 'FLAT_REDACTED',
}

View File

@ -1,11 +1,11 @@
import { ManualRedactionEntryWrapper } from './manual-redaction-entry.wrapper';
import { ManualAddResponse } from '@redaction/red-ui-http';
import { IManualAddResponse } from '@red/domain';
export class ManualAnnotationResponse {
annotationId;
commentId;
constructor(public manualRedactionEntryWrapper: ManualRedactionEntryWrapper, public manualAddResponse: ManualAddResponse) {
constructor(public manualRedactionEntryWrapper: ManualRedactionEntryWrapper, public manualAddResponse: IManualAddResponse) {
this.annotationId = manualAddResponse?.annotationId ? manualAddResponse.annotationId : new Date().getTime();
this.commentId = manualAddResponse?.commentId ? manualAddResponse.commentId : new Date().getTime();
}

View File

@ -1,9 +1,9 @@
import { ManualRedactionEntry } from '@redaction/red-ui-http';
import { IManualRedactionEntry } from '@red/domain';
export class ManualRedactionEntryWrapper {
constructor(
readonly quads: any,
readonly manualRedactionEntry: ManualRedactionEntry,
readonly manualRedactionEntry: IManualRedactionEntry,
readonly type: 'DICTIONARY' | 'REDACTION' | 'FALSE_POSITIVE',
readonly annotationType: 'TEXT' | 'RECTANGLE' = 'TEXT',
readonly rectId?: string,

View File

@ -1,7 +1,7 @@
import { Change, Comment, ILegalBasis, Rectangle } from '@redaction/red-ui-http';
import { IChange, IComment, ILegalBasis, IRectangle } from '@red/domain';
export interface RedactionLogEntryWrapper {
changes?: Array<Change>;
changes?: Array<IChange>;
dossierDictionaryEntry?: boolean;
endOffset?: number;
excluded?: boolean;
@ -19,7 +19,7 @@ export interface RedactionLogEntryWrapper {
manual?: boolean;
manualRedactionType?: 'ADD' | 'REMOVE' | 'UNDO' | 'LEGAL_BASIS_CHANGE' | 'FORCE_REDACT' | 'RECATEGORIZE';
matchedRule?: number;
positions?: Array<Rectangle>;
positions?: Array<IRectangle>;
reason?: string;
redacted?: boolean;
section?: string;
@ -29,7 +29,7 @@ export interface RedactionLogEntryWrapper {
textBefore?: string;
value?: string;
image?: boolean;
legalBasisList?: Array<ILegalBasis>;
legalBasisList?: ILegalBasis[];
recommendation?: boolean;
recommendationAnnotationId?: string;
@ -37,7 +37,7 @@ export interface RedactionLogEntryWrapper {
hidden?: boolean;
userId?: string;
comments?: Comment[];
comments?: IComment[];
isChangeLogEntry?: boolean;
changeLogType?: 'ADDED' | 'REMOVED' | 'CHANGED';

View File

@ -3,7 +3,7 @@
{{ dialogHeader }}
</div>
<form (submit)="saveDictionary()" [formGroup]="dictionaryForm">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">
<div class="iqser-input-group mb-14">
<label translate="add-edit-dictionary.form.technical-name"></label>
@ -47,10 +47,10 @@
type="text"
/>
<div
(colorPickerChange)="dictionaryForm.get('hexColor').setValue($event)"
[colorPicker]="dictionaryForm.get('hexColor').value"
(colorPickerChange)="form.get('hexColor').setValue($event)"
[colorPicker]="form.get('hexColor').value"
[cpOutputFormat]="'hex'"
[style.background]="dictionaryForm.get('hexColor').value"
[style.background]="form.get('hexColor').value"
class="input-icon"
>
<mat-icon *ngIf="hasColor" svgIcon="red:color-picker"></mat-icon>
@ -95,7 +95,7 @@
</div>
<div class="dialog-actions">
<button [disabled]="dictionaryForm.invalid || !changed" color="primary" mat-flat-button type="submit">
<button [disabled]="form.invalid || !changed" color="primary" mat-flat-button type="submit">
{{ 'add-edit-dictionary.save' | translate }}
</button>
</div>

View File

@ -2,7 +2,7 @@ import { Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Observable } from 'rxjs';
import { Toaster } from '@iqser/common-ui';
import { BaseDialogComponent, Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { AppStateService } from '@state/app-state.service';
@ -15,8 +15,8 @@ import { Dictionary, IDictionary } from '@red/domain';
templateUrl: './add-edit-dictionary-dialog.component.html',
styleUrls: ['./add-edit-dictionary-dialog.component.scss'],
})
export class AddEditDictionaryDialogComponent {
dictionaryForm: FormGroup;
export class AddEditDictionaryDialogComponent extends BaseDialogComponent {
form: FormGroup;
readonly dictionary: Dictionary;
technicalName = '';
private readonly _dossierTemplateId: string;
@ -31,9 +31,10 @@ export class AddEditDictionaryDialogComponent {
@Inject(MAT_DIALOG_DATA)
private readonly _data: { dictionary: Dictionary; dossierTemplateId: string },
) {
super();
this.dictionary = _data.dictionary;
this._dossierTemplateId = _data.dossierTemplateId;
this.dictionaryForm = _formBuilder.group({
this.form = _formBuilder.group({
label: [this.dictionary?.label, [Validators.required, Validators.minLength(3)]],
description: [this.dictionary?.description],
rank: [this.dictionary?.rank, Validators.required],
@ -42,7 +43,7 @@ export class AddEditDictionaryDialogComponent {
addToDictionaryAction: [!!this.dictionary?.addToDictionaryAction],
caseSensitive: [this.dictCaseSensitive],
});
this.dictionaryForm.get('label').valueChanges.subscribe(() => {
this.form.get('label').valueChanges.subscribe(() => {
this._updateTechnicalName();
});
}
@ -55,7 +56,7 @@ export class AddEditDictionaryDialogComponent {
}
get hasColor(): boolean {
const hexColorValue = this.dictionaryForm.get('hexColor').value;
const hexColorValue = this.form.get('hexColor').value;
return !hexColorValue || hexColorValue?.length === 0;
}
@ -68,12 +69,12 @@ export class AddEditDictionaryDialogComponent {
return true;
}
for (const key of Object.keys(this.dictionaryForm.getRawValue())) {
for (const key of Object.keys(this.form.getRawValue())) {
if (key === 'caseSensitive') {
if (this.dictCaseSensitive !== this.dictionaryForm.get(key).value) {
if (this.dictCaseSensitive !== this.form.get(key).value) {
return true;
}
} else if (this.dictionary[key] !== this.dictionaryForm.get(key).value) {
} else if (this.dictionary[key] !== this.form.get(key).value) {
return true;
}
}
@ -81,7 +82,7 @@ export class AddEditDictionaryDialogComponent {
return false;
}
saveDictionary(): void {
save(): void {
const dictionary = this._formToObject();
let observable: Observable<unknown>;
@ -108,7 +109,7 @@ export class AddEditDictionaryDialogComponent {
}
private _updateTechnicalName() {
const displayName = this.dictionaryForm.get('label').value.trim();
const displayName = this.form.get('label').value.trim();
const existingTechnicalNames = Object.keys(this._appStateService.dictionaryData[this._dossierTemplateId]);
const baseTechnicalName: string = toKebabCase(displayName);
let technicalName = baseTechnicalName;
@ -122,13 +123,13 @@ export class AddEditDictionaryDialogComponent {
private _formToObject(): IDictionary {
return {
type: this.dictionary?.type || this.technicalName,
label: this.dictionaryForm.get('label').value,
caseInsensitive: !this.dictionaryForm.get('caseSensitive').value,
description: this.dictionaryForm.get('description').value,
hexColor: this.dictionaryForm.get('hexColor').value,
hint: this.dictionaryForm.get('hint').value,
rank: this.dictionaryForm.get('rank').value,
addToDictionaryAction: this.dictionaryForm.get('addToDictionaryAction').value,
label: this.form.get('label').value,
caseInsensitive: !this.form.get('caseSensitive').value,
description: this.form.get('description').value,
hexColor: this.form.get('hexColor').value,
hint: this.form.get('hint').value,
rank: this.form.get('rank').value,
addToDictionaryAction: this.form.get('addToDictionaryAction').value,
dossierTemplateId: this._dossierTemplateId,
};
}

View File

@ -8,7 +8,7 @@
class="dialog-header heading-l"
></div>
<form (submit)="saveFileAttribute()" [formGroup]="dossierAttributeForm">
<form (submit)="saveDossierAttribute()" [formGroup]="dossierAttributeForm">
<div class="dialog-content">
<div class="iqser-input-group required w-300">
<label translate="add-edit-dossier-attribute.form.label"></label>

View File

@ -1,13 +1,12 @@
import { Component, Inject, OnDestroy } from '@angular/core';
import { Component, HostListener, Inject, OnDestroy } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { FileAttributeConfigTypes } from '@redaction/red-ui-http';
import { DossierAttributeConfigTypes, FileAttributeConfigTypes, IDossierAttributeConfig } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AutoUnsubscribe, LoadingService, Toaster } from '@iqser/common-ui';
import { AutoUnsubscribe, IqserEventTarget, LoadingService, Toaster } from '@iqser/common-ui';
import { HttpErrorResponse } from '@angular/common/http';
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
import { dossierAttributeTypesTranslations } from '../../translations/dossier-attribute-types-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DossierAttributeConfigTypes, IDossierAttributeConfig } from '@red/domain';
@Component({
templateUrl: './add-edit-dossier-attribute-dialog.component.html',
@ -57,7 +56,7 @@ export class AddEditDossierAttributeDialogComponent extends AutoUnsubscribe impl
return false;
}
saveFileAttribute() {
saveDossierAttribute() {
this._loadingService.start();
const attribute: IDossierAttributeConfig = {
@ -76,4 +75,12 @@ export class AddEditDossierAttributeDialogComponent extends AutoUnsubscribe impl
},
);
}
@HostListener('window:keydown.Enter', ['$event'])
onEnter(event: KeyboardEvent): void {
const node = (event.target as IqserEventTarget).localName;
if (this.dossierAttributeForm.valid && this.changed && node !== 'textarea') {
this.saveDossierAttribute();
}
}
}

View File

@ -8,7 +8,7 @@
class="dialog-header heading-l"
></div>
<form (submit)="saveDossierTemplate()" [formGroup]="dossierTemplateForm">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">
<div class="iqser-input-group required w-300">
<label translate="add-edit-dossier-template.form.name"></label>
@ -77,7 +77,7 @@
'download-type.label'
| translate
: {
length: dossierTemplateForm.controls['downloadFileTypes'].value.length
length: form.controls['downloadFileTypes'].value.length
}
"
[options]="downloadTypes"
@ -87,7 +87,7 @@
</div>
<div class="dialog-actions">
<button [disabled]="dossierTemplateForm.invalid || !changed" color="primary" mat-flat-button type="submit">
<button [disabled]="form.invalid || !changed" color="primary" mat-flat-button type="submit">
{{ 'add-edit-dossier-template.save' | translate }}
</button>
</div>

View File

@ -7,7 +7,7 @@ import { Moment } from 'moment';
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
import { downloadTypesTranslations } from '../../../../translations/download-types-translations';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { CONFLICT_ERROR_CODE, Toaster } from '@iqser/common-ui';
import { BaseDialogComponent, CONFLICT_ERROR_CODE, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DownloadFileType, IDossierTemplate } from '@red/domain';
@ -15,8 +15,8 @@ import { DownloadFileType, IDossierTemplate } from '@red/domain';
templateUrl: './add-edit-dossier-template-dialog.component.html',
styleUrls: ['./add-edit-dossier-template-dialog.component.scss'],
})
export class AddEditDossierTemplateDialogComponent {
dossierTemplateForm: FormGroup;
export class AddEditDossierTemplateDialogComponent extends BaseDialogComponent {
form: FormGroup;
hasValidFrom: boolean;
hasValidTo: boolean;
downloadTypesEnum: DownloadFileType[] = ['ORIGINAL', 'PREVIEW', 'REDACTED'];
@ -36,7 +36,8 @@ export class AddEditDossierTemplateDialogComponent {
public dialogRef: MatDialogRef<AddEditDossierTemplateDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly dossierTemplate: IDossierTemplate,
) {
this.dossierTemplateForm = this._formBuilder.group({
super();
this.form = this._formBuilder.group({
name: [this.dossierTemplate?.name, Validators.required],
description: [this.dossierTemplate?.description],
validFrom: [
@ -52,10 +53,10 @@ export class AddEditDossierTemplateDialogComponent {
this.hasValidFrom = !!this.dossierTemplate?.validFrom;
this.hasValidTo = !!this.dossierTemplate?.validTo;
this._previousValidFrom = this.dossierTemplateForm.get('validFrom').value;
this._previousValidTo = this.dossierTemplateForm.get('validTo').value;
this._previousValidFrom = this.form.get('validFrom').value;
this._previousValidTo = this.form.get('validTo').value;
this.dossierTemplateForm.valueChanges.subscribe(value => {
this.form.valueChanges.subscribe(value => {
this._applyValidityIntervalConstraints(value);
});
}
@ -65,8 +66,8 @@ export class AddEditDossierTemplateDialogComponent {
return true;
}
for (const key of Object.keys(this.dossierTemplateForm.getRawValue())) {
const formValue = this.dossierTemplateForm.get(key).value;
for (const key of Object.keys(this.form.getRawValue())) {
const formValue = this.form.get(key).value;
const objectValue = this.dossierTemplate[key];
if (key === 'validFrom') {
if (this.hasValidFrom !== !!objectValue || (this.hasValidFrom && !moment(objectValue).isSame(moment(formValue)))) {
@ -93,13 +94,13 @@ export class AddEditDossierTemplateDialogComponent {
return false;
}
async saveDossierTemplate() {
async save() {
try {
const dossierTemplate = {
dossierTemplateId: this.dossierTemplate?.dossierTemplateId,
...this.dossierTemplateForm.getRawValue(),
validFrom: this.hasValidFrom ? this.dossierTemplateForm.get('validFrom').value : null,
validTo: this.hasValidTo ? this.dossierTemplateForm.get('validTo').value : null,
...this.form.getRawValue(),
validFrom: this.hasValidFrom ? this.form.get('validFrom').value : null,
validTo: this.hasValidTo ? this.form.get('validTo').value : null,
};
await this._dossierTemplatesService.createOrUpdate(dossierTemplate).toPromise();
await this._dossierTemplatesService.loadAll().toPromise();
@ -115,21 +116,12 @@ export class AddEditDossierTemplateDialogComponent {
}
private _applyValidityIntervalConstraints(value): boolean {
if (
applyIntervalConstraints(
value,
this._previousValidFrom,
this._previousValidTo,
this.dossierTemplateForm,
'validFrom',
'validTo',
)
) {
if (applyIntervalConstraints(value, this._previousValidFrom, this._previousValidTo, this.form, 'validFrom', 'validTo')) {
return true;
}
this._previousValidFrom = this.dossierTemplateForm.get('validFrom').value;
this._previousValidTo = this.dossierTemplateForm.get('validTo').value;
this._previousValidFrom = this.form.get('validFrom').value;
this._previousValidTo = this.form.get('validTo').value;
return false;
}

View File

@ -8,7 +8,7 @@
class="dialog-header heading-l"
></div>
<form (submit)="saveFileAttribute()" [formGroup]="fileAttributeForm">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">
<div class="iqser-input-group required w-300">
<label translate="add-edit-file-attribute.form.name"></label>
@ -66,7 +66,7 @@
</div>
</div>
<div class="dialog-actions">
<button [disabled]="fileAttributeForm.invalid || !changed" color="primary" mat-flat-button type="submit">
<button [disabled]="form.invalid || !changed" color="primary" mat-flat-button type="submit">
{{ 'add-edit-file-attribute.save' | translate }}
</button>
</div>

View File

@ -1,17 +1,18 @@
import { Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '@state/app-state.service';
import { FileAttributeConfigTypes, IFileAttributeConfig } from '@redaction/red-ui-http';
import { FileAttributeConfigTypes, IFileAttributeConfig } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { fileAttributeTypesTranslations } from '../../translations/file-attribute-types-translations';
import { BaseDialogComponent } from '@iqser/common-ui';
@Component({
selector: 'redaction-add-edit-file-attribute-dialog',
templateUrl: './add-edit-file-attribute-dialog.component.html',
styleUrls: ['./add-edit-file-attribute-dialog.component.scss'],
})
export class AddEditFileAttributeDialogComponent {
fileAttributeForm: FormGroup;
export class AddEditFileAttributeDialogComponent extends BaseDialogComponent {
form: FormGroup;
fileAttribute: IFileAttributeConfig;
dossierTemplateId: string;
readonly typeOptions = Object.keys(FileAttributeConfigTypes);
@ -24,10 +25,11 @@ export class AddEditFileAttributeDialogComponent {
@Inject(MAT_DIALOG_DATA)
public data: { fileAttribute: IFileAttributeConfig; dossierTemplateId: string },
) {
super();
this.fileAttribute = data.fileAttribute;
this.dossierTemplateId = data.dossierTemplateId;
this.fileAttributeForm = this._formBuilder.group({
this.form = this._formBuilder.group({
label: [this.fileAttribute?.label, Validators.required],
csvColumnHeader: [this.fileAttribute?.csvColumnHeader, Validators.required],
type: [this.fileAttribute?.type || FileAttributeConfigTypes.TEXT, Validators.required],
@ -43,12 +45,12 @@ export class AddEditFileAttributeDialogComponent {
return true;
}
for (const key of Object.keys(this.fileAttributeForm.getRawValue())) {
for (const key of Object.keys(this.form.getRawValue())) {
if (key === 'readonly') {
if (this.fileAttribute.editable === this.fileAttributeForm.get(key).value) {
if (this.fileAttribute.editable === this.form.get(key).value) {
return true;
}
} else if (this.fileAttribute[key] !== this.fileAttributeForm.get(key).value) {
} else if (this.fileAttribute[key] !== this.form.get(key).value) {
return true;
}
}
@ -56,11 +58,11 @@ export class AddEditFileAttributeDialogComponent {
return false;
}
saveFileAttribute() {
save() {
const fileAttribute: IFileAttributeConfig = {
id: this.fileAttribute?.id,
editable: !this.fileAttributeForm.get('readonly').value,
...this.fileAttributeForm.getRawValue(),
editable: !this.form.get('readonly').value,
...this.form.getRawValue(),
};
this.dialogRef.close(fileAttribute);
}

View File

@ -1,5 +1,5 @@
import { Component, Inject } from '@angular/core';
import { IFileAttributeConfig } from '@redaction/red-ui-http';
import { IFileAttributeConfig } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';

View File

@ -1,7 +1,7 @@
<section class="dialog">
<div [translate]="translations[colorKey]" class="dialog-header heading-l"></div>
<form (submit)="saveColors()" [formGroup]="colorForm">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">
<div class="iqser-input-group required">
<label translate="edit-color-dialog.form.color"></label>
@ -13,14 +13,14 @@
type="text"
/>
<div
(colorPickerChange)="colorForm.get('color').setValue($event)"
[colorPicker]="colorForm.get('color').value"
(colorPickerChange)="form.get('color').setValue($event)"
[colorPicker]="form.get('color').value"
[cpOutputFormat]="'hex'"
[style.background]="colorForm.get('color').value"
[style.background]="form.get('color').value"
class="input-icon"
>
<mat-icon
*ngIf="!colorForm.get('color').value || colorForm.get('color').value?.length === 0"
*ngIf="!form.get('color').value || form.get('color').value?.length === 0"
svgIcon="red:color-picker"
></mat-icon>
</div>
@ -28,7 +28,7 @@
</div>
<div class="dialog-actions">
<button [disabled]="colorForm.invalid || !changed" color="primary" mat-flat-button type="submit">
<button [disabled]="form.invalid || !changed" color="primary" mat-flat-button type="submit">
{{ 'edit-color-dialog.save' | translate }}
</button>
</div>

View File

@ -1,10 +1,9 @@
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Colors } from '@redaction/red-ui-http';
import { Toaster } from '@iqser/common-ui';
import { DefaultColorType, IColors } from '@red/domain';
import { BaseDialogComponent, Toaster } from '@iqser/common-ui';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { DefaultColorType } from '@models/default-color-key.model';
import { defaultColorsTranslations } from '../../translations/default-colors-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DictionaryService } from '@shared/services/dictionary.service';
@ -14,10 +13,10 @@ import { DictionaryService } from '@shared/services/dictionary.service';
templateUrl: './edit-color-dialog.component.html',
styleUrls: ['./edit-color-dialog.component.scss'],
})
export class EditColorDialogComponent {
readonly colors: Colors;
export class EditColorDialogComponent extends BaseDialogComponent {
readonly colors: IColors;
readonly colorKey: DefaultColorType;
colorForm: FormGroup;
form: FormGroup;
translations = defaultColorsTranslations;
private readonly _initialColor: string;
private readonly _dossierTemplateId: string;
@ -29,26 +28,27 @@ export class EditColorDialogComponent {
private readonly _translateService: TranslateService,
private readonly _dialogRef: MatDialogRef<EditColorDialogComponent>,
@Inject(MAT_DIALOG_DATA)
private readonly _data: { colors: Colors; colorKey: DefaultColorType; dossierTemplateId: string },
private readonly _data: { colors: IColors; colorKey: DefaultColorType; dossierTemplateId: string },
) {
super();
this.colors = _data.colors;
this.colorKey = _data.colorKey;
this._dossierTemplateId = _data.dossierTemplateId;
this._initialColor = _data.colors[this.colorKey];
this.colorForm = this._formBuilder.group({
this.form = this._formBuilder.group({
color: [this.colors[this.colorKey], [Validators.required, Validators.minLength(7)]],
});
}
get changed(): boolean {
return this.colorForm.get('color').value !== this._initialColor;
return this.form.get('color').value !== this._initialColor;
}
async saveColors() {
async save() {
const colors = {
...this.colors,
[this.colorKey]: this.colorForm.get('color').value,
[this.colorKey]: this.form.get('color').value,
};
try {

View File

@ -1,9 +1,9 @@
import { Component, EventEmitter, forwardRef, Injector, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { Field } from '../file-attributes-csv-import-dialog.component';
import { FileAttributeConfigTypes } from '@redaction/red-ui-http';
import { CircleButtonTypes, DefaultListingServices, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
import { fileAttributeTypesTranslations } from '../../../translations/file-attribute-types-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FileAttributeConfigTypes } from '@red/domain';
@Component({
selector: 'redaction-active-fields-listing',

View File

@ -2,12 +2,11 @@ import { Component, Inject, Injector } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import * as Papa from 'papaparse';
import { FileAttributeConfigType, FileAttributeConfigTypes, FileAttributesConfig } from '@redaction/red-ui-http';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { DefaultListingServices, IListable, ListingComponent, TableColumnConfig, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FileAttributeConfig } from '@models/file/file-attribute-config';
import { FileAttributeConfig, FileAttributeConfigType, FileAttributeConfigTypes, IFileAttributesConfig } from '@red/domain';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
export interface Field extends IListable {
@ -48,7 +47,7 @@ export class FileAttributesCsvImportDialogComponent extends ListingComponent<Fie
readonly data: {
readonly csv: File;
readonly dossierTemplateId: string;
readonly existingConfiguration: FileAttributesConfig;
readonly existingConfiguration: IFileAttributesConfig;
},
) {
super(_injector);

View File

@ -2,7 +2,7 @@ import { Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UserService } from '@services/user.service';
import { SMTPConfiguration } from '@redaction/red-ui-http';
import { ISmtpConfiguration } from '@red/domain';
@Component({
selector: 'redaction-smtp-auth-dialog',
@ -16,7 +16,7 @@ export class SmtpAuthDialogComponent {
private readonly _formBuilder: FormBuilder,
private readonly _userService: UserService,
public dialogRef: MatDialogRef<SmtpAuthDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: SMTPConfiguration,
@Inject(MAT_DIALOG_DATA) public data: ISmtpConfiguration,
) {
this.authForm = this._formBuilder.group({
user: [data?.user || this._userService.currentUser.email, [Validators.required]],

View File

@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnInit } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { Colors } from '@redaction/red-ui-http';
import { DefaultColorType, IColors } from '@red/domain';
import { ActivatedRoute } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service';
import {
@ -11,7 +11,6 @@ import {
LoadingService,
TableColumnConfig,
} from '@iqser/common-ui';
import { DefaultColorType } from '@models/default-color-key.model';
import { defaultColorsTranslations } from '../../translations/default-colors-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UserService } from '@services/user.service';
@ -38,7 +37,7 @@ export class DefaultColorsScreenComponent extends ListingComponent<ListItem> imp
{ label: _('default-colors-screen.table-col-names.key'), sortByKey: 'searchKey', width: '2fr' },
{ label: _('default-colors-screen.table-col-names.color'), class: 'flex-center' },
];
private _colorsObj: Colors;
private _colorsObj: IColors;
constructor(
protected readonly _injector: Injector,

View File

@ -1,5 +1,4 @@
import { Component, OnDestroy } from '@angular/core';
import { DigitalSignature } from '@redaction/red-ui-http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { lastIndexOfEnd } from '@utils/functions';
import { AutoUnsubscribe, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
@ -7,6 +6,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UserService } from '@services/user.service';
import { RouterHistoryService } from '@services/router-history.service';
import { DigitalSignatureService } from '../../services/digital-signature.service';
import { IDigitalSignature } from '@red/domain';
@Component({
selector: 'redaction-digital-signature-screen',
@ -17,7 +17,7 @@ export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements
readonly iconButtonTypes = IconButtonTypes;
readonly currentUser = this._userService.currentUser;
digitalSignature: DigitalSignature;
digitalSignature: IDigitalSignature;
digitalSignatureForm: FormGroup;
digitalSignatureExists = false;

View File

@ -1,5 +1,4 @@
import { ChangeDetectionStrategy, Component, ElementRef, forwardRef, Injector, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { FileAttributesConfig, IFileAttributeConfig } from '@redaction/red-ui-http';
import { AppStateService } from '@state/app-state.service';
import { ActivatedRoute } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service';
@ -14,7 +13,7 @@ import {
import { fileAttributeTypesTranslations } from '../../translations/file-attribute-types-translations';
import { UserService } from '@services/user.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FileAttributeConfig } from '@models/file/file-attribute-config';
import { FileAttributeConfig, IFileAttributeConfig, IFileAttributesConfig } from '@red/domain';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
@ -47,7 +46,7 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
rightIconTooltip: _('file-attributes-listing.table-col-names.primary-info-tooltip'),
},
];
private _existingConfiguration: FileAttributesConfig;
private _existingConfiguration: IFileAttributesConfig;
@ViewChild('fileInput') private _fileInput: ElementRef;
constructor(

View File

@ -1,7 +1,7 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { GeneralConfigurationModel, SMTPConfiguration } from '@redaction/red-ui-http';
import { IGeneralConfiguration, ISmtpConfiguration } from '@red/domain';
import { ConfigService } from '@services/config.service';
import { AutoUnsubscribe, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -21,8 +21,8 @@ export class GeneralConfigScreenComponent extends AutoUnsubscribe implements OnI
readonly configForm: FormGroup;
readonly smtpForm: FormGroup;
private _initialGeneralConfiguration: GeneralConfigurationModel;
private _initialSMTPConfiguration: SMTPConfiguration;
private _initialGeneralConfiguration: IGeneralConfiguration;
private _initialSMTPConfiguration: ISmtpConfiguration;
constructor(
private readonly _toaster: Toaster,

View File

@ -8,7 +8,7 @@
class="dialog-header heading-l"
></div>
<form (submit)="save()" [formGroup]="justificationForm">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">
<div class="iqser-input-group required w-400">
<label translate="add-edit-justification.form.name"></label>
@ -43,7 +43,7 @@
</div>
</div>
<div class="dialog-actions">
<button [disabled]="justificationForm.invalid || !changed" color="primary" mat-flat-button type="submit">
<button [disabled]="form.invalid || !changed" color="primary" mat-flat-button type="submit">
{{ 'add-edit-justification.actions.save' | translate }}
</button>

View File

@ -1,10 +1,10 @@
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Justification } from '@models/justification.model';
import { Justification } from '@red/domain';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { LoadingService } from '@iqser/common-ui';
import { BaseDialogComponent, LoadingService } from '@iqser/common-ui';
@Component({
selector: 'redaction-add-edit-justification-dialog',
@ -12,8 +12,8 @@ import { LoadingService } from '@iqser/common-ui';
styleUrls: ['./add-edit-justification-dialog.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddEditJustificationDialogComponent {
justificationForm: FormGroup;
export class AddEditJustificationDialogComponent extends BaseDialogComponent {
form: FormGroup;
constructor(
private readonly _formBuilder: FormBuilder,
@ -23,7 +23,8 @@ export class AddEditJustificationDialogComponent {
public dialogRef: MatDialogRef<AddEditJustificationDialogComponent>,
@Inject(MAT_DIALOG_DATA) public justification: Justification,
) {
this.justificationForm = this._formBuilder.group({
super();
this.form = this._formBuilder.group({
name: [{ value: this.justification?.name, disabled: !!this.justification }, Validators.required],
reason: [this.justification?.reason, Validators.required],
description: [this.justification?.description, Validators.required],
@ -33,10 +34,7 @@ export class AddEditJustificationDialogComponent {
get changed(): boolean {
return (
!this.justification ||
Object.keys(this.justificationForm.getRawValue()).reduce(
(prev, key) => prev || this.justification[key] !== this.justificationForm.get(key).value,
false,
)
Object.keys(this.form.getRawValue()).reduce((prev, key) => prev || this.justification[key] !== this.form.get(key).value, false)
);
}
@ -44,7 +42,7 @@ export class AddEditJustificationDialogComponent {
const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId;
this._loadingService.start();
await this._justificationService.createOrUpdate(this.justificationForm.getRawValue(), dossierTemplateId).toPromise();
await this._justificationService.createOrUpdate(this.form.getRawValue(), dossierTemplateId).toPromise();
await this._justificationService.loadAll(dossierTemplateId).toPromise();
this._loadingService.stop();
this.dialogRef.close(true);

View File

@ -12,7 +12,7 @@ import { AddEditJustificationDialogComponent } from './add-edit-justification-di
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { Justification } from '@models/justification.model';
import { Justification } from '@red/domain';
type DialogType = 'confirm' | 'addEditJustification';

View File

@ -9,7 +9,7 @@ import {
LoadingService,
TableColumnConfig,
} from '@iqser/common-ui';
import { Justification } from '@models/justification.model';
import { Justification } from '@red/domain';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { JustificationsDialogService } from '../justifications-dialog.service';

View File

@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { Justification } from '@models/justification.model';
import { Justification } from '@red/domain';
import { CircleButtonTypes, ListingService, LoadingService } from '@iqser/common-ui';
import { JustificationsDialogService } from '../justifications-dialog.service';
import { UserService } from '@services/user.service';

View File

@ -1,5 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { LicenseReport } from '@redaction/red-ui-http';
import { ConfigService } from '@services/config.service';
import * as moment from 'moment';
import { TranslateService } from '@ngx-translate/core';
@ -8,6 +7,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UserService } from '@services/user.service';
import { RouterHistoryService } from '@services/router-history.service';
import { LicenseReportService } from '../../services/licence-report.service';
import { ILicenseReport } from '@red/domain';
@Component({
selector: 'redaction-license-information-screen',
@ -24,9 +24,9 @@ export class LicenseInformationScreenComponent implements OnInit {
},
];
currentInfo: LicenseReport = {};
totalInfo: LicenseReport = {};
unlicensedInfo: LicenseReport = {};
currentInfo: ILicenseReport = {};
totalInfo: ILicenseReport = {};
unlicensedInfo: ILicenseReport = {};
totalLicensedNumberOfPages = 0;
analysisPercentageOfLicense = 100;
barChart: any[];

View File

@ -1,7 +1,7 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AppStateService } from '@state/app-state.service';
import { PlaceholdersResponse, ReportTemplate } from '@redaction/red-ui-http';
import { IPlaceholdersResponse, IReportTemplate } from '@red/domain';
import { download } from '@utils/file-download-utils';
import { ConfirmationDialogInput, LoadingService, Toaster } from '@iqser/common-ui';
import { PermissionsService } from '@services/permissions.service';
@ -31,7 +31,7 @@ const placeholderTypes: PlaceholderType[] = ['generalPlaceholders', 'fileAttribu
})
export class ReportsScreenComponent implements OnInit {
placeholders: Placeholder[];
availableTemplates: ReportTemplate[];
availableTemplates: IReportTemplate[];
@ViewChild('fileInput') private _fileInput: ElementRef;
@ -57,7 +57,7 @@ export class ReportsScreenComponent implements OnInit {
this._loadingService.loadWhile(this._uploadTemplate($event));
}
async download(template: ReportTemplate) {
async download(template: IReportTemplate) {
this._loadingService.start();
try {
const data = await this._reportTemplateService
@ -71,7 +71,7 @@ export class ReportsScreenComponent implements OnInit {
}
}
deleteTemplate(template: ReportTemplate) {
deleteTemplate(template: IReportTemplate) {
this._dialogService.openDialog('confirm', null, null, () => {
this._loadingService.loadWhile(this._deleteTemplate(template));
});
@ -120,7 +120,7 @@ export class ReportsScreenComponent implements OnInit {
this._fileInput.nativeElement.value = null;
}
private async _deleteTemplate(template: ReportTemplate) {
private async _deleteTemplate(template: IReportTemplate) {
await this._reportTemplateService.delete(template.dossierTemplateId, template.templateId).toPromise();
await this._loadReportTemplates();
}
@ -132,7 +132,7 @@ export class ReportsScreenComponent implements OnInit {
}
private async _loadPlaceholders() {
const placeholdersResponse: PlaceholdersResponse = await this._reportTemplateService
const placeholdersResponse: IPlaceholdersResponse = await this._reportTemplateService
.getAvailablePlaceholders(this._dossierTemplatesService.activeDossierTemplateId)
.toPromise();
this.placeholders = placeholderTypes.flatMap(type =>

View File

@ -5,7 +5,7 @@ import { environment } from '@environments/environment';
import { HttpClient } from '@angular/common/http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Debounce, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { IWatermark, WatermarkOrientation, WatermarkOrientations } from '@redaction/red-ui-http';
import { IWatermark, WatermarkOrientation, WatermarkOrientations } from '@red/domain';
import { ActivatedRoute } from '@angular/router';
import { BASE_HREF } from '../../../../tokens';
import { stampPDFPage } from '@utils/page-stamper';

View File

@ -1,8 +1,7 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
import { CategoryModel } from '@redaction/red-ui-http';
import { IAudit, IAuditResponse, IAuditSearchRequest, ICategory } from '@red/domain';
import { Observable } from 'rxjs';
import { IAudit, IAuditResponse, IAuditSearchRequest } from '@red/domain';
@Injectable()
export class AuditService extends GenericService<IAudit> {
@ -10,8 +9,8 @@ export class AuditService extends GenericService<IAudit> {
super(_injector, 'audit');
}
getCategories(): Observable<CategoryModel[]> {
return super.getAll<CategoryModel[]>(`${this._defaultModelPath}/categories`);
getCategories(): Observable<ICategory[]> {
return super.getAll<ICategory[]>(`${this._defaultModelPath}/categories`);
}
@Validate()

View File

@ -1,21 +1,21 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
import { DigitalSignature, DigitalSignatureViewModel } from '@redaction/red-ui-http';
import { Observable } from 'rxjs';
import { IDigitalSignature, IDigitalSignatureRequest } from '@red/domain';
@Injectable()
export class DigitalSignatureService extends GenericService<DigitalSignatureViewModel> {
export class DigitalSignatureService extends GenericService<IDigitalSignatureRequest> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'digital-signature');
}
@Validate()
update(@RequiredParam() body: DigitalSignatureViewModel): Observable<unknown> {
update(@RequiredParam() body: IDigitalSignatureRequest): Observable<unknown> {
return this._put(body);
}
@Validate()
save(@RequiredParam() body: DigitalSignature): Observable<DigitalSignatureViewModel> {
save(@RequiredParam() body: IDigitalSignature): Observable<IDigitalSignatureRequest> {
return this._post(body);
}
@ -23,7 +23,7 @@ export class DigitalSignatureService extends GenericService<DigitalSignatureView
return super.delete({});
}
getSignature(): Observable<DigitalSignatureViewModel> {
getSignature(): Observable<IDigitalSignatureRequest> {
return super.getAll();
}
}

View File

@ -1,15 +1,15 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
import { LicenseReport, LicenseReportRequest } from '@redaction/red-ui-http';
import { ILicenseReport, ILicenseReportRequest } from '@red/domain';
@Injectable()
export class LicenseReportService extends GenericService<LicenseReport> {
export class LicenseReportService extends GenericService<ILicenseReport> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'report');
}
@Validate()
licenseReport(@RequiredParam() body: LicenseReportRequest, limit?: number, offset?: number) {
licenseReport(@RequiredParam() body: ILicenseReportRequest, limit?: number, offset?: number) {
const queryParams: QueryParam[] = [];
if (limit) {
queryParams.push({ key: 'limit', value: limit });

View File

@ -1,9 +1,9 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
import { Rules } from '@redaction/red-ui-http';
import { IRules } from '@red/domain';
@Injectable()
export class RulesService extends GenericService<Rules> {
export class RulesService extends GenericService<IRules> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'rules');
}
@ -14,7 +14,7 @@ export class RulesService extends GenericService<Rules> {
}
@Validate()
uploadRules(@RequiredParam() body: Rules) {
uploadRules(@RequiredParam() body: IRules) {
return this._post<unknown>(body);
}
}

View File

@ -1,6 +1,6 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
import { SMTPConfiguration } from '@redaction/red-ui-http';
import { ISmtpConfiguration } from '@red/domain';
@Injectable()
export class SmtpConfigService extends GenericService<unknown> {
@ -9,12 +9,12 @@ export class SmtpConfigService extends GenericService<unknown> {
}
@Validate()
updateSMTPConfiguration(@RequiredParam() body: SMTPConfiguration) {
updateSMTPConfiguration(@RequiredParam() body: ISmtpConfiguration) {
return this._post(body, `${this._defaultModelPath}/smtp`);
}
@Validate()
testSMTPConfiguration(@RequiredParam() body: SMTPConfiguration) {
testSMTPConfiguration(@RequiredParam() body: ISmtpConfiguration) {
return this._post(body, `${this._defaultModelPath}/smtp/test`);
}

View File

@ -1,6 +1,6 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
import { IWatermark } from '@redaction/red-ui-http';
import { IWatermark } from '@red/domain';
@Injectable()
export class WatermarkService extends GenericService<IWatermark> {

View File

@ -1,5 +1,5 @@
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DefaultColorType } from '@models/default-color-key.model';
import { DefaultColorType } from '@red/domain';
export const defaultColorsTranslations: { [key in DefaultColorType]: string } = {
analysisColor: _('default-colors-screen.types.analysisColor'),

View File

@ -1,5 +1,5 @@
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FileAttributeConfigType } from '@redaction/red-ui-http';
import { FileAttributeConfigType } from '@red/domain';
export const fileAttributeTypesTranslations: { [key in FileAttributeConfigType]: string } = {
TEXT: _('file-attribute-types.text'),

View File

@ -1,4 +1,4 @@
<div *ngFor="let comment of annotation.comments" class="comment">
<div *ngFor="let comment of annotation.comments; trackBy: trackBy" class="comment">
<div class="comment-details-wrapper">
<div [matTooltipPosition]="'above'" [matTooltip]="comment.date | date: 'exactDate'" class="small-label">
<strong> {{ comment.user | name }} </strong>

View File

@ -1,10 +1,10 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, Input, ViewChild } from '@angular/core';
import { Comment } from '@redaction/red-ui-http';
import { IComment } from '@red/domain';
import { ManualAnnotationService } from '../../services/manual-annotation.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service';
import { InputWithActionComponent } from '@iqser/common-ui';
import { InputWithActionComponent, trackBy } from '@iqser/common-ui';
@Component({
selector: 'redaction-comments',
@ -14,6 +14,7 @@ import { InputWithActionComponent } from '@iqser/common-ui';
})
export class CommentsComponent {
@Input() annotation: AnnotationWrapper;
readonly trackBy = trackBy();
@HostBinding('class.hidden') private _hidden = true;
@ViewChild(InputWithActionComponent) private readonly _input: InputWithActionComponent;
@ -31,10 +32,10 @@ export class CommentsComponent {
this._manualAnnotationService
.addComment(value, this.annotation.id)
.toPromise()
.then(commentResponse => {
.then(commentId => {
this.annotation.comments.push({
text: value,
id: parseInt(commentResponse.commentId, 10),
id: commentId,
user: this._userService.currentUser.id,
});
this._input.reset();
@ -47,9 +48,9 @@ export class CommentsComponent {
this._hidden = !this._hidden;
}
deleteComment(comment: Comment): void {
deleteComment(comment: IComment): void {
this._manualAnnotationService
.deleteComment(`${comment.id}`, this.annotation.id)
.deleteComment(comment.id, this.annotation.id)
.toPromise()
.then(() => {
this.annotation.comments.splice(this.annotation.comments.indexOf(comment), 1);

View File

@ -1,9 +1,8 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FileAttributesConfig } from '@redaction/red-ui-http';
import { File, IFileAttributesConfig } from '@red/domain';
import { AppStateService } from '@state/app-state.service';
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { AutoUnsubscribe } from '@iqser/common-ui';
import { File } from '@models/file/file';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
@ -17,7 +16,7 @@ export class DocumentInfoComponent extends AutoUnsubscribe implements OnInit {
@Input() file: File;
@Output() readonly closeDocumentInfoView = new EventEmitter();
fileAttributesConfig: FileAttributesConfig;
fileAttributesConfig: IFileAttributesConfig;
constructor(
private readonly _appStateService: AppStateService,

View File

@ -2,9 +2,8 @@ import { Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@a
import { PermissionsService } from '@services/permissions.service';
import { InputWithActionComponent, LoadingService, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { File } from '@models/file/file';
import { File, IPageRange } from '@red/domain';
import { ReanalysisService } from '@services/reanalysis.service';
import { IPageRange } from '@red/domain';
@Component({
selector: 'redaction-page-exclusion',

View File

@ -47,7 +47,10 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy {
ngOnInit(): void {
this._subscription = this._appStateService.fileChanged$.subscribe(() => {
this.canMarkPagesAsViewed = this._permissionService.canMarkPagesAsViewed();
if (this.canMarkPagesAsViewed !== this._permissionService.canMarkPagesAsViewed()) {
this.canMarkPagesAsViewed = this._permissionService.canMarkPagesAsViewed();
this._handlePageRead();
}
});
}

View File

@ -11,13 +11,12 @@ import {
SimpleChanges,
ViewChild,
} from '@angular/core';
import { ManualRedactionEntry } from '@redaction/red-ui-http';
import { File, IManualRedactionEntry, ViewMode } from '@red/domain';
import WebViewer, { Core, WebViewerInstance } from '@pdftron/webviewer';
import { TranslateService } from '@ngx-translate/core';
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { ManualAnnotationService } from '../../services/manual-annotation.service';
import { File } from '@models/file/file';
import { environment } from '@environments/environment';
import { AnnotationDrawService } from '../../services/annotation-draw.service';
import { AnnotationActionsService } from '../../services/annotation-actions.service';
@ -28,7 +27,6 @@ import { ConfirmationDialogInput, LoadingService } from '@iqser/common-ui';
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { loadCompareDocumentWrapper } from '../../utils/compare-mode.utils';
import { PdfViewerUtils } from '../../utils/pdf-viewer.utils';
import { ViewMode } from '@models/file/view-mode';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ActivatedRoute } from '@angular/router';
import Tools = Core.Tools;
@ -556,8 +554,8 @@ export class PdfViewerComponent implements OnInit, OnChanges {
}
}
private _getManualRedactionEntry(quads: any, text: string, convertQuads: boolean = false): ManualRedactionEntry {
const entry: ManualRedactionEntry = { positions: [] };
private _getManualRedactionEntry(quads: any, text: string, convertQuads: boolean = false): IManualRedactionEntry {
const entry: IManualRedactionEntry = { positions: [] };
for (const key of Object.keys(quads)) {
for (const quad of quads[key]) {
const page = parseInt(key, 10);

View File

@ -1,6 +1,6 @@
import { Component } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { ReportTemplate } from '@redaction/red-ui-http';
import { DownloadFileType, IDossierRequest, IDossierTemplate, IReportTemplate } from '@red/domain';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import * as moment from 'moment';
import { downloadTypesTranslations } from '../../../../translations/download-types-translations';
@ -8,7 +8,6 @@ import { IconButtonTypes } from '@iqser/common-ui';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { ReportTemplateService } from '@services/report-template.service';
import { DownloadFileType, IDossierRequest, IDossierTemplate } from '@red/domain';
@Component({
templateUrl: './add-dossier-dialog.component.html',
@ -69,7 +68,7 @@ export class AddDossierDialogComponent {
return this.dossierForm.invalid;
}
reportTemplateValueMapper = (reportTemplate: ReportTemplate) => reportTemplate.templateId;
reportTemplateValueMapper = (reportTemplate: IReportTemplate) => reportTemplate.templateId;
async saveDossier(addMembers = false) {
const savedDossier = await this._dossiersService.createOrUpdate(this._formToObject()).toPromise();

View File

@ -4,8 +4,7 @@ import { AppStateService } from '@state/app-state.service';
import { UserService } from '@services/user.service';
import { Toaster } from '@iqser/common-ui';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { File } from '@models/file/file';
import { Dossier } from '@red/domain';
import { Dossier, File } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FilesService } from '@services/entity-services/files.service';
import { DossiersService } from '@services/entity-services/dossiers.service';

View File

@ -1,9 +1,8 @@
import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { IFile, IFileAttributeConfig } from '@redaction/red-ui-http';
import { Dossier, IFile, IFileAttributeConfig } from '@red/domain';
import { AppStateService } from '@state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Dossier } from '@red/domain';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { DossiersService } from '@services/entity-services/dossiers.service';

View File

@ -1,6 +1,6 @@
import { Component, EventEmitter, forwardRef, Injector, Input, OnInit, Output } from '@angular/core';
import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { Dossier } from '@red/domain';
import { Dossier, IFile } from '@red/domain';
import {
CircleButtonTypes,
ConfirmationDialogInput,
@ -12,7 +12,6 @@ import {
TableColumnConfig,
TitleColors,
} from '@iqser/common-ui';
import { IFile } from '@redaction/red-ui-http';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import * as moment from 'moment';
import { ConfigService } from '@services/config.service';

View File

@ -1,7 +1,6 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ReportTemplate } from '@redaction/red-ui-http';
import { Dossier, DownloadFileType, IReportTemplate } from '@red/domain';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Dossier, DownloadFileType } from '@red/domain';
import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { downloadTypesTranslations } from '../../../../../translations/download-types-translations';
import { DossiersService } from '@services/entity-services/dossiers.service';
@ -18,7 +17,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
key: type,
label: downloadTypesTranslations[type],
}));
availableReportTypes: ReportTemplate[] = [];
availableReportTypes: IReportTemplate[] = [];
@Input() dossier: Dossier;
@Output() readonly updateDossier = new EventEmitter();
@ -62,7 +61,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
return this.dossierForm?.invalid;
}
reportTemplateValueMapper = (reportTemplate: ReportTemplate) => reportTemplate.templateId;
reportTemplateValueMapper = (reportTemplate: IReportTemplate) => reportTemplate.templateId;
async ngOnInit() {
this.availableReportTypes =

View File

@ -1,7 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialogRef } from '@angular/material/dialog';
import { ForceRedactionRequest } from '@redaction/red-ui-http';
import { Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
@ -9,6 +8,7 @@ import { ManualAnnotationService } from '../../services/manual-annotation.servic
import { PermissionsService } from '@services/permissions.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { ILegalBasisChangeRequest } from '@red/domain';
export interface LegalBasisOption {
label?: string;
@ -63,8 +63,8 @@ export class ForceRedactionDialogComponent implements OnInit {
this.dialogRef.close(this._createForceRedactionRequest());
}
private _createForceRedactionRequest(): ForceRedactionRequest {
const request: ForceRedactionRequest = {};
private _createForceRedactionRequest(): ILegalBasisChangeRequest {
const request: ILegalBasisChangeRequest = {};
const legalOption: LegalBasisOption = this.redactionForm.get('reason').value;

View File

@ -2,7 +2,6 @@ import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '@state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AddRedactionRequest } from '@redaction/red-ui-http';
import { Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
@ -12,7 +11,7 @@ import { ManualAnnotationResponse } from '@models/file/manual-annotation-respons
import { PermissionsService } from '@services/permissions.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { Dictionary } from '@red/domain';
import { Dictionary, IAddRedactionRequest } from '@red/domain';
export interface LegalBasisOption {
label?: string;
@ -112,7 +111,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
);
}
private _enhanceManualRedaction(addRedactionRequest: AddRedactionRequest) {
private _enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) {
const legalOption: LegalBasisOption = this.redactionForm.get('reason').value;
addRedactionRequest.type = this.redactionForm.get('dictionary').value;
if (legalOption) {

View File

@ -1,14 +1,13 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { PermissionsService } from '@services/permissions.service';
import { File } from '@models/file/file';
import { Dossier, File } from '@red/domain';
import { FileActionService } from '../../../../shared/services/file-action.service';
import { Observable } from 'rxjs';
import { DossiersDialogService } from '../../../../services/dossiers-dialog.service';
import { CircleButtonTypes, ConfirmationDialogInput, ListingService, LoadingService } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Dossier } from '@red/domain';
import { LongPressEvent } from '@shared/directives/long-press.directive';
import { UserPreferenceService } from '@services/user-preference.service';
import { FileManagementService } from '../../../../shared/services/file-management.service';

View File

@ -1,13 +1,13 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { groupBy, StatusSorter } from '@utils/index';
import { groupBy } from '@utils/index';
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
import { TranslateChartService } from '@services/translate-chart.service';
import { UserService } from '@services/user.service';
import { FilterService, Toaster } from '@iqser/common-ui';
import { fileStatusTranslations } from '../../../../translations/file-status-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DossierAttributeWithValue, IDossierRequest, User } from '@red/domain';
import { DossierAttributeWithValue, IDossierRequest, StatusSorter, User } from '@red/domain';
import { DossiersService } from '@services/entity-services/dossiers.service';
@Component({
@ -61,7 +61,7 @@ export class DossierDetailsComponent implements OnInit {
label: fileStatusTranslations[status],
key: status,
}));
documentsChartData.sort(StatusSorter.byStatus);
documentsChartData.sort((a, b) => StatusSorter.byStatus(a.key, b.key));
documentsChartData = this.translateChartService.translateStatus(documentsChartData);
this.documentsChartData = documentsChartData;
this._changeDetectorRef.detectChanges();

View File

@ -1,7 +1,6 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, TemplateRef } from '@angular/core';
import { File } from '@models/file/file';
import { File, IFileAttributeConfig } from '@red/domain';
import { Required } from '@iqser/common-ui';
import { IFileAttributeConfig } from '@redaction/red-ui-http';
@Component({
selector: 'redaction-table-item',

View File

@ -10,9 +10,8 @@ import {
TableColumnConfig,
WorkflowConfig,
} from '@iqser/common-ui';
import { File } from '@models/file/file';
import { File, FileStatus, FileStatuses, IFileAttributeConfig, StatusSorter } from '@red/domain';
import { fileStatusTranslations } from '../../translations/file-status-translations';
import { FileStatus, FileStatuses, IFileAttributeConfig } from '@redaction/red-ui-http';
import { FileActionService } from '../../shared/services/file-action.service';
import { AppStateService } from '@state/app-state.service';
import { PermissionsService } from '@services/permissions.service';
@ -20,7 +19,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { annotationFilterChecker, RedactionFilterSorter, StatusSorter } from '@utils/index';
import { annotationFilterChecker, RedactionFilterSorter } from '@utils/index';
import { workloadTranslations } from '../../translations/workload-translations';
import * as moment from 'moment';
import { ConfigService as AppConfigService } from '@services/config.service';

View File

@ -11,7 +11,7 @@ import {
TemplateRef,
ViewChild,
} from '@angular/core';
import { FileStatus, IFileAttributeConfig } from '@redaction/red-ui-http';
import { Dossier, DossierAttributeWithValue, File, FileStatus, IFileAttributeConfig } from '@red/domain';
import { AppStateService } from '@state/app-state.service';
import { FileDropOverlayService } from '@upload-download/services/file-drop-overlay.service';
import { FileUploadModel } from '@upload-download/model/file-upload.model';
@ -20,7 +20,6 @@ import { StatusOverlayService } from '@upload-download/services/status-overlay.s
import { TranslateService } from '@ngx-translate/core';
import * as moment from 'moment';
import { DossierDetailsComponent } from '../components/dossier-details/dossier-details.component';
import { File } from '@models/file/file';
import { UserService } from '@services/user.service';
import { timer } from 'rxjs';
import { take, tap } from 'rxjs/operators';
@ -45,7 +44,6 @@ import { DossierAttributesService } from '@shared/services/controller-wrappers/d
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { PermissionsService } from '@services/permissions.service';
import { RouterHistoryService } from '@services/router-history.service';
import { Dossier, DossierAttributeWithValue } from '@red/domain';
import { Router } from '@angular/router';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { ConfigService as AppConfigService } from '@services/config.service';

View File

@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { StatusSorter } from '@utils/sorters/status-sorter';
import { StatusSorter } from '../../../../../../../../../../libs/red-domain/src/lib/shared/sorters/status-sorter';
import { CircleButtonTypes, StatusBarConfig } from '@iqser/common-ui';
import { UserService } from '@services/user.service';
import { AppStateService } from '@state/app-state.service';

View File

@ -1,6 +1,6 @@
import { Injectable, TemplateRef } from '@angular/core';
import { ButtonConfig, IFilterGroup, keyChecker, NestedFilter, TableColumnConfig } from '@iqser/common-ui';
import { Dossier, User } from '@red/domain';
import { Dossier, StatusSorter, User } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { TranslateService } from '@ngx-translate/core';
import { UserPreferenceService } from '@services/user-preference.service';
@ -12,7 +12,6 @@ import {
dossierStatusChecker,
dossierTemplateChecker,
RedactionFilterSorter,
StatusSorter,
} from '@utils/index';
import { workloadTranslations } from '../../translations/workload-translations';
import { AppStateService } from '@state/app-state.service';

View File

@ -10,7 +10,7 @@ import {
ViewChild,
} from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { Dossier, DossierStatuses } from '@red/domain';
import { Dossier, DossierStatuses, StatusSorter } from '@red/domain';
import { UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service';
import { TranslateChartService } from '@services/translate-chart.service';
@ -19,7 +19,7 @@ import { timer } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Router } from '@angular/router';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import { groupBy, StatusSorter } from '@utils/index';
import { groupBy } from '@utils/index';
import { DefaultListingServicesTmp, EntitiesService, ListingComponent, OnAttach, OnDetach, TableComponent } from '@iqser/common-ui';
import { fileStatusTranslations } from '../../../translations/file-status-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -137,7 +137,7 @@ export class DossiersListingScreenComponent
key: status,
});
}
this.documentsChartData.sort(StatusSorter.byStatus);
this.documentsChartData.sort((a, b) => StatusSorter.byStatus(a.key, b.key));
this.documentsChartData = this._translateChartService.translateStatus(this.documentsChartData);
}

View File

@ -24,15 +24,13 @@ import { AnnotationData, FileDataModel } from '@models/file/file-data.model';
import { FileActionService } from '../../shared/services/file-action.service';
import { AnnotationDrawService } from '../../services/annotation-draw.service';
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
import { File } from '@models/file/file';
import { Dossier, File, FileStatus, User, ViewMode } from '@red/domain';
import { PermissionsService } from '@services/permissions.service';
import { timer } from 'rxjs';
import { UserPreferenceService } from '@services/user-preference.service';
import { UserService } from '@services/user.service';
import { FileStatus } from '@redaction/red-ui-http';
import { PdfViewerDataService } from '../../services/pdf-viewer-data.service';
import { download } from '@utils/file-download-utils';
import { ViewMode } from '@models/file/view-mode';
import { FileWorkloadComponent } from '../../components/file-workload/file-workload.component';
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { clearStamps, stampPDFPage } from '@utils/page-stamper';
@ -41,7 +39,6 @@ import { fileStatusTranslations } from '../../translations/file-status-translati
import { handleFilterDelta } from '@utils/filter-utils';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FileActionsComponent } from '../../shared/components/file-actions/file-actions.component';
import { Dossier, User } from '@red/domain';
import { FilesService } from '@services/entity-services/files.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { FileManagementService } from '../../shared/services/file-management.service';

View File

@ -4,13 +4,13 @@ import { ManualAnnotationService } from './manual-annotation.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Observable } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';
import { AddRedactionRequest, ForceRedactionRequest } from '@redaction/red-ui-http';
import { getFirstRelevantTextPart } from '@utils/functions';
import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { DossiersDialogService } from './dossiers-dialog.service';
import { BASE_HREF } from '../../../tokens';
import { UserService } from '@services/user.service';
import { Core } from '@pdftron/webviewer';
import { IAddRedactionRequest, ILegalBasisChangeRequest } from '@red/domain';
import Annotation = Core.Annotations.Annotation;
@Injectable()
@ -44,7 +44,7 @@ export class AnnotationActionsService {
}
forceRedaction($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
this._dialogService.openDialog('forceRedaction', $event, null, (request: ForceRedactionRequest) => {
this._dialogService.openDialog('forceRedaction', $event, null, (request: ILegalBasisChangeRequest) => {
annotations.forEach(annotation => {
this._processObsAndEmit(
this._manualAnnotationService.force({
@ -323,7 +323,7 @@ export class AnnotationActionsService {
) {
$event?.stopPropagation();
const falsePositiveRequest: AddRedactionRequest = {};
const falsePositiveRequest: IAddRedactionRequest = {};
falsePositiveRequest.reason = annotation.id;
falsePositiveRequest.value = text;
falsePositiveRequest.type = 'false_positive';

View File

@ -1,13 +1,14 @@
import { Injectable } from '@angular/core';
import { Core, WebViewerInstance } from '@pdftron/webviewer';
import { Rectangle, SectionGrid, SectionRectangle } from '@redaction/red-ui-http';
import { hexToRgb } from '@utils/functions';
import { AppStateService } from '@state/app-state.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { UserPreferenceService } from '@services/user-preference.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { RedactionLogService } from './redaction-log.service';
import { environment } from '../../../../environments/environment';
import { environment } from '@environments/environment';
import { IRectangle, ISectionGrid, ISectionRectangle } from '@red/domain';
import Annotation = Core.Annotations.Annotation;
@Injectable()
@ -39,28 +40,6 @@ export class AnnotationDrawService {
);
}
private async _drawAnnotations(
activeViewer: WebViewerInstance,
annotationWrappers: AnnotationWrapper[],
hideSkipped = false,
compareMode = false,
) {
const annotations = annotationWrappers.map(annotation =>
this._computeAnnotation(activeViewer, annotation, hideSkipped, compareMode),
);
const annotationManager = activeViewer.Core.annotationManager;
annotationManager.addAnnotations(annotations, { imported: true });
await annotationManager.drawAnnotationsFromList(annotations);
if (this._userPreferenceService.areDevFeaturesEnabled) {
const sectionsGrid = await this._redactionLogService
.getSectionGrid(this._dossiersService.activeDossierId, this._appStateService.activeFileId)
.toPromise()
.catch(() => ({ rectanglesPerPage: {} }));
await this._drawSections(activeViewer, sectionsGrid);
}
}
getColor(activeViewer: WebViewerInstance, superType: string, dictionary?: string) {
let color;
switch (superType) {
@ -96,10 +75,32 @@ export class AnnotationDrawService {
return new activeViewer.Core.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
}
private async _drawSections(activeViewer: WebViewerInstance, sectionGrid: SectionGrid) {
private async _drawAnnotations(
activeViewer: WebViewerInstance,
annotationWrappers: AnnotationWrapper[],
hideSkipped = false,
compareMode = false,
) {
const annotations = annotationWrappers.map(annotation =>
this._computeAnnotation(activeViewer, annotation, hideSkipped, compareMode),
);
const annotationManager = activeViewer.Core.annotationManager;
annotationManager.addAnnotations(annotations, { imported: true });
await annotationManager.drawAnnotationsFromList(annotations);
if (this._userPreferenceService.areDevFeaturesEnabled) {
const sectionsGrid = await this._redactionLogService
.getSectionGrid(this._dossiersService.activeDossierId, this._appStateService.activeFileId)
.toPromise()
.catch(() => ({ rectanglesPerPage: {} }));
await this._drawSections(activeViewer, sectionsGrid);
}
}
private async _drawSections(activeViewer: WebViewerInstance, sectionGrid: ISectionGrid) {
const sections = [];
for (const page of Object.keys(sectionGrid.rectanglesPerPage)) {
const sectionRectangles: SectionRectangle[] = sectionGrid.rectanglesPerPage[page];
const sectionRectangles = sectionGrid.rectanglesPerPage[page];
sectionRectangles.forEach(sectionRectangle => {
sections.push(this._computeSection(activeViewer, parseInt(page, 10), sectionRectangle));
// sectionRectangle.tableCells?.forEach(cell =>{
@ -112,10 +113,10 @@ export class AnnotationDrawService {
await annotationManager.drawAnnotationsFromList(sections);
}
private _computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: SectionRectangle) {
private _computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: ISectionRectangle) {
const rectangleAnnot = new activeViewer.Core.Annotations.RectangleAnnotation();
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
const rectangle = {
const rectangle: IRectangle = {
topLeft: sectionRectangle.topLeft,
page: pageNumber,
height: sectionRectangle.height,
@ -168,12 +169,12 @@ export class AnnotationDrawService {
return highlight;
}
private _rectanglesToQuads(positions: Rectangle[], activeViewer: WebViewerInstance, pageNumber: number): any[] {
private _rectanglesToQuads(positions: IRectangle[], activeViewer: WebViewerInstance, pageNumber: number): any[] {
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
return positions.map(p => this._rectangleToQuad(p, activeViewer, pageHeight));
}
private _rectangleToQuad(rectangle: Rectangle, activeViewer: WebViewerInstance, pageHeight: number): any {
private _rectangleToQuad(rectangle: IRectangle, activeViewer: WebViewerInstance, pageHeight: number): any {
const x1 = rectangle.topLeft.x;
const y1 = pageHeight - (rectangle.topLeft.y + rectangle.height);

View File

@ -1,19 +1,17 @@
import { Injectable, Injector } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import {
AddRedactionRequest,
ApproveRequest,
CommentResponse,
ForceRedactionRequest,
ImageRecategorizationRequest,
LegalBasisChangeRequest,
ManualAddResponse,
RemoveRedactionRequest,
} from '@redaction/red-ui-http';
IAddRedactionRequest,
IApproveRequest,
IImageRecategorizationRequest,
ILegalBasisChangeRequest,
IManualAddResponse,
IRemoveRedactionRequest,
} from '@red/domain';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { CONFLICT_ERROR_CODE, ErrorMessageService, GenericService, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { tap } from 'rxjs/operators';
import { map, tap } from 'rxjs/operators';
import { UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service';
import { AnnotationActionMode } from '../models/annotation-action-mode.model';
@ -23,7 +21,7 @@ import { DossiersService } from '@services/entity-services/dossiers.service';
import { HttpErrorResponse } from '@angular/common/http';
@Injectable()
export class ManualAnnotationService extends GenericService<ManualAddResponse> {
export class ManualAnnotationService extends GenericService<IManualAddResponse> {
CONFIG: {
[key in AnnotationActionMode]: string;
};
@ -87,7 +85,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
fileId = this._appStateService.activeFileId,
) {
const url = `${this._defaultModelPath}/comment/add/${dossierId}/${fileId}/${annotationId}`;
return this._post<CommentResponse>({ text: comment }, url);
return this._post<{ commentId: string }>({ text: comment }, url).pipe(map(res => res.commentId));
}
@Validate()
@ -102,7 +100,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
}
addRecommendation(annotation: AnnotationWrapper) {
const manualRedactionEntry: AddRedactionRequest = {};
const manualRedactionEntry: IAddRedactionRequest = {};
manualRedactionEntry.addToDictionary = true;
// set the ID as reason, so we can hide the suggestion
manualRedactionEntry.reason = annotation.id;
@ -132,7 +130,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
// this wraps
// /manualRedaction/redaction/add
// /manualRedaction/request/add
addAnnotation(manualRedactionEntry: AddRedactionRequest) {
addAnnotation(manualRedactionEntry: IAddRedactionRequest) {
const mode: AnnotationActionMode = this._permissionsService.isApprover() ? 'add' : 'suggest';
return this._makeRequest(mode, manualRedactionEntry, null, manualRedactionEntry.addToDictionary);
}
@ -140,7 +138,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
// this wraps
// /manualRedaction/redaction/force
// /manualRedaction/request/force
force(request: ForceRedactionRequest) {
force(request: ILegalBasisChangeRequest) {
const mode: AnnotationActionMode = this._permissionsService.isApprover() ? 'force-redaction' : 'request-force-redaction';
return this._makeRequest(mode, request);
}
@ -222,14 +220,14 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
}
@Validate()
addRedaction(@RequiredParam() body: AddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
addRedaction(@RequiredParam() body: IAddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
const url = `${this._defaultModelPath}/redaction/add/${dossierId}/${fileId}`;
return this._post(body, url);
}
@Validate()
recategorizeImage(
@RequiredParam() body: ImageRecategorizationRequest,
@RequiredParam() body: IImageRecategorizationRequest,
@RequiredParam() dossierId: string,
@RequiredParam() fileId: string,
) {
@ -239,7 +237,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
@Validate()
requestImageRecategorization(
@RequiredParam() body: ImageRecategorizationRequest,
@RequiredParam() body: IImageRecategorizationRequest,
@RequiredParam() dossierId: string,
@RequiredParam() fileId: string,
) {
@ -248,14 +246,14 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
}
@Validate()
legalBasisChange(@RequiredParam() body: LegalBasisChangeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
legalBasisChange(@RequiredParam() body: ILegalBasisChangeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
const url = `${this._defaultModelPath}/redaction/legalBasisChange/${dossierId}/${fileId}`;
return this._post(body, url);
}
@Validate()
requestLegalBasisChange(
@RequiredParam() body: LegalBasisChangeRequest,
@RequiredParam() body: ILegalBasisChangeRequest,
@RequiredParam() dossierId: string,
@RequiredParam() fileId: string,
) {
@ -265,7 +263,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
@Validate()
requestRemoveRedaction(
@RequiredParam() body: RemoveRedactionRequest,
@RequiredParam() body: IRemoveRedactionRequest,
@RequiredParam() dossierId: string,
@RequiredParam() fileId: string,
) {
@ -275,7 +273,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
@Validate()
approveRequest(
@RequiredParam() body: ApproveRequest,
@RequiredParam() body: IApproveRequest,
@RequiredParam() annotationId: string,
@RequiredParam() dossierId: string,
@RequiredParam() fileId: string,
@ -297,26 +295,26 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
}
@Validate()
removeRedaction(@RequiredParam() body: RemoveRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
removeRedaction(@RequiredParam() body: IRemoveRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
const url = `${this._defaultModelPath}/redaction/remove/${dossierId}/${fileId}`;
return this._post(body, url);
}
@Validate()
requestAddRedaction(@RequiredParam() body: AddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
requestAddRedaction(@RequiredParam() body: IAddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
const url = `${this._defaultModelPath}/request/add/${dossierId}/${fileId}`;
return this._post(body, url);
}
@Validate()
forceRedaction(@RequiredParam() body: ForceRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
forceRedaction(@RequiredParam() body: ILegalBasisChangeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
const url = `${this._defaultModelPath}/redaction/force/${dossierId}/${fileId}`;
return this._post(body, url);
}
@Validate()
requestForceRedaction(
@RequiredParam() body: ForceRedactionRequest,
@RequiredParam() body: ILegalBasisChangeRequest,
@RequiredParam() dossierId: string,
@RequiredParam() fileId: string,
) {

View File

@ -4,7 +4,7 @@ import { catchError, map, tap } from 'rxjs/operators';
import { FileDataModel } from '@models/file/file-data.model';
import { AppStateService } from '@state/app-state.service';
import { PermissionsService } from '@services/permissions.service';
import { File } from '@models/file/file';
import { File } from '@red/domain';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { FileManagementService } from '../shared/services/file-management.service';
import { RedactionLogService } from './redaction-log.service';
@ -23,16 +23,14 @@ export class PdfViewerDataService {
loadActiveFileRedactionLog() {
return this._redactionLogService.getRedactionLog(this._dossiersService.activeDossierId, this._appStateService.activeFileId).pipe(
tap(
redactionLog => redactionLog.redactionLogEntry.sort((a, b) => a.positions[0].page - b.positions[0].page),
catchError(() => of({})),
),
tap(redactionLog => redactionLog.redactionLogEntry.sort((a, b) => a.positions[0].page - b.positions[0].page)),
catchError(() => of({})),
);
}
loadActiveFileData(): Observable<FileDataModel> {
const file$ = this.downloadOriginalFile(this._appStateService.activeFile);
const reactionLog$ = this.loadActiveFileRedactionLog().pipe(catchError(() => of({})));
const reactionLog$ = this.loadActiveFileRedactionLog();
const viewedPages$ = this.getViewedPagesForActiveFile();
return forkJoin([file$, reactionLog$, viewedPages$]).pipe(

View File

@ -1,6 +1,6 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
import { RedactionLog, SectionGrid } from '@redaction/red-ui-http';
import { IRedactionLog, ISectionGrid } from '@red/domain';
@Injectable({
providedIn: 'root',
@ -17,11 +17,11 @@ export class RedactionLogService extends GenericService<unknown> {
queryParams.push({ key: 'withManualRedactions', value: withManualRedactions });
}
return this._getOne<RedactionLog>([dossierId, fileId], 'redactionLog', queryParams);
return this._getOne<IRedactionLog>([dossierId, fileId], 'redactionLog', queryParams);
}
@Validate()
getSectionGrid(@RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
return this._getOne<SectionGrid>([dossierId, fileId], 'sectionGrid');
return this._getOne<ISectionGrid>([dossierId, fileId], 'sectionGrid');
}
}

View File

@ -1,6 +1,6 @@
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { File } from '@models/file/file';
import { File, FileStatus } from '@red/domain';
import { AppStateService } from '@state/app-state.service';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import {
@ -13,7 +13,6 @@ import {
StatusBarConfig,
Toaster,
} from '@iqser/common-ui';
import { FileStatus } from '@redaction/red-ui-http';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UserService } from '@services/user.service';
import { filter } from 'rxjs/operators';

View File

@ -1,7 +1,6 @@
import { Component, Input } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { File } from '@models/file/file';
import { Dossier } from '@red/domain';
import { Dossier, File } from '@red/domain';
@Component({
selector: 'redaction-needs-work-badge',

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { UserService } from '@services/user.service';
import { File } from '@models/file/file';
import { File } from '@red/domain';
import { PermissionsService } from '@services/permissions.service';
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';

View File

@ -1,7 +1,8 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
import { map } from 'rxjs/operators';
import { catchError, map } from 'rxjs/operators';
import { IViewedPage, IViewedPagesRequest } from '@red/domain';
import { of } from 'rxjs';
@Injectable({
providedIn: 'root',
@ -23,6 +24,9 @@ export class ViewedPagesService extends GenericService<unknown> {
@Validate()
getViewedPages(@RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
return this._getOne<{ pages?: IViewedPage[] }>([dossierId, fileId]).pipe(map(res => res.pages));
return this._getOne<{ pages?: IViewedPage[] }>([dossierId, fileId]).pipe(
map(res => res.pages),
catchError(() => of([])),
);
}
}

View File

@ -1,5 +1,5 @@
import { FileStatus } from '@redaction/red-ui-http';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FileStatus } from '@red/domain';
export const fileStatusTranslations: { [key in FileStatus]: string } = {
APPROVED: _('file-status.approved'),

View File

@ -1,6 +1,5 @@
import { ViewMode } from '@models/file/view-mode';
import { IRectangle, ViewMode } from '@red/domain';
import { translateQuads } from '@utils/pdf-coordinates';
import { Rectangle } from '@redaction/red-ui-http';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Core, WebViewerInstance } from '@pdftron/webviewer';
import Annotation = Core.Annotations.Annotation;
@ -121,7 +120,7 @@ export class PdfViewerUtils {
return translateQuads(page, rotation, quads);
}
toPosition(page: number, selectedQuad: { x1: number; x2: number; x3: number; x4: number; y4: number; y2: number }): Rectangle {
toPosition(page: number, selectedQuad: { x1: number; x2: number; x3: number; x4: number; y4: number; y2: number }): IRectangle {
const pageHeight = this._documentViewer.getPageHeight(page);
const height = selectedQuad.y2 - selectedQuad.y4;
return {

View File

@ -1,7 +1,6 @@
import { ChangeDetectionStrategy, Component, Input, OnDestroy } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { Dossier } from '@red/domain';
import { File } from '@models/file/file';
import { Dossier, File } from '@red/domain';
import { FileDownloadService } from '@upload-download/services/file-download.service';
import { AutoUnsubscribe, CircleButtonType, CircleButtonTypes, List, Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';

View File

@ -1,10 +1,9 @@
import { Injectable, Injector } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { EntitiesService, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
import { Colors, UpdateDictionary } from '@redaction/red-ui-http';
import { Dictionary, IColors, IDictionary, IUpdateDictionary } from '@red/domain';
import { tap } from 'rxjs/operators';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Dictionary, IDictionary } from '@red/domain';
const MIN_WORD_LENGTH = 2;
@ -49,7 +48,7 @@ export class DictionaryService extends EntitiesService<Dictionary, IDictionary>
*/
@Validate()
getColors(@RequiredParam() dossierTemplateId: string) {
return this._getOne<Colors>([dossierTemplateId], 'color');
return this._getOne<IColors>([dossierTemplateId], 'color');
}
/**
@ -57,7 +56,7 @@ export class DictionaryService extends EntitiesService<Dictionary, IDictionary>
*/
@Validate()
updateDictionary(
@RequiredParam() body: UpdateDictionary,
@RequiredParam() body: IUpdateDictionary,
@RequiredParam() dossierTemplateId: string,
@RequiredParam() type: string,
dossierId?: string,
@ -71,7 +70,7 @@ export class DictionaryService extends EntitiesService<Dictionary, IDictionary>
* Set system colors for redaction
*/
@Validate()
setColors(@RequiredParam() body: Colors, @RequiredParam() dossierTemplateId: string) {
setColors(@RequiredParam() body: IColors, @RequiredParam() dossierTemplateId: string) {
return this._post(body, `color/${dossierTemplateId}`);
}

View File

@ -1,15 +1,15 @@
import { Injectable, Injector } from '@angular/core';
import {
DownloadResponse,
DownloadStatusResponse,
DownloadStatus,
IDownloadResponse,
IDownloadStatus,
PrepareDownloadRequest,
RemoveDownloadRequest,
} from '@redaction/red-ui-http';
IDownloadStatusResponse,
IPrepareDownloadRequest,
IRemoveDownloadRequest,
} from '@red/domain';
import { interval, Observable } from 'rxjs';
import { ConfigService } from '@services/config.service';
import { map, mergeMap, tap } from 'rxjs/operators';
import { DownloadStatus } from '../model/download-status';
import { KeycloakService } from 'keycloak-angular';
import { UserService } from '@services/user.service';
import { EntitiesService, List, RequiredParam, Validate } from '@iqser/common-ui';
@ -48,7 +48,7 @@ export class FileDownloadService extends EntitiesService<DownloadStatus, IDownlo
}
getStatuses(): Observable<IDownloadStatus[]> {
return super._getOne<DownloadStatusResponse>(['status']).pipe(map(res => res.downloadStatus));
return super._getOne<IDownloadStatusResponse>(['status']).pipe(map(res => res.downloadStatus));
}
async performDownload(status: DownloadStatus) {
@ -66,12 +66,12 @@ export class FileDownloadService extends EntitiesService<DownloadStatus, IDownlo
}
@Validate()
prepareDownload(@RequiredParam() body: PrepareDownloadRequest): Observable<DownloadResponse> {
prepareDownload(@RequiredParam() body: IPrepareDownloadRequest): Observable<IDownloadResponse> {
return this._post(body, `${this._defaultModelPath}/prepare`);
}
@Validate()
delete(@RequiredParam() body: RemoveDownloadRequest): Observable<unknown> {
delete(@RequiredParam() body: IRemoveDownloadRequest): Observable<unknown> {
return super._post(body, `${this._defaultModelPath}/delete`);
}
}

View File

@ -6,7 +6,7 @@ import { interval, Subscription } from 'rxjs';
import { ConfigService } from '@services/config.service';
import { TranslateService } from '@ngx-translate/core';
import { UploadDownloadDialogService } from './upload-download-dialog.service';
import { FileUploadResult } from '@redaction/red-ui-http';
import { IFileUploadResult } from '@red/domain';
import { isCsv } from '@utils/file-drop-utils';
import { ErrorMessageService, GenericService, HeadersConfiguration, RequiredParam, Validate } from '@iqser/common-ui';
import { DossiersService } from '@services/entity-services/dossiers.service';
@ -17,7 +17,7 @@ export interface ActiveUpload {
}
@Injectable()
export class FileUploadService extends GenericService<FileUploadResult> {
export class FileUploadService extends GenericService<IFileUploadResult> {
static readonly MAX_PARALLEL_UPLOADS = 5;
files: FileUploadModel[] = [];
groupedFiles: { [key: string]: FileUploadModel[] } = {};
@ -130,7 +130,7 @@ export class FileUploadService extends GenericService<FileUploadResult> {
const headers = HeadersConfiguration.getHeaders({ contentType: false }).append('ngsw-bypass', 'true');
return this._http.post<FileUploadResult>(`/${this._defaultModelPath}/${dossierId}`, formParams, {
return this._http.post<IFileUploadResult>(`/${this._defaultModelPath}/${dossierId}`, formParams, {
headers,
observe: 'events',
reportProgress: true,

View File

@ -1,10 +1,9 @@
import { Injectable, Injector } from '@angular/core';
import { EntitiesService, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
import { Dossier, IDossier, IDossierRequest } from '@red/domain';
import { Dossier, File, IDossier, IDossierRequest } from '@red/domain';
import { catchError, map, tap } from 'rxjs/operators';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { ActivationEnd, Router } from '@angular/router';
import { File } from '@models/file/file';
import { DictionaryService } from '@shared/services/dictionary.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { currentComponentRoute } from '@utils/functions';

View File

@ -1,11 +1,10 @@
import { EntitiesService, List, RequiredParam, Validate } from '@iqser/common-ui';
import { FileAttributes, FileAttributesConfig, IFileAttributeConfig } from '@redaction/red-ui-http';
import { Injectable, Injector } from '@angular/core';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { FileAttributeConfig } from '@models/file/file-attribute-config';
import { FileAttributeConfig, FileAttributes, IFileAttributeConfig, IFileAttributesConfig } from '@red/domain';
type FileAttributesConfigMap = Readonly<Record<string, FileAttributesConfig>>;
type FileAttributesConfigMap = Readonly<Record<string, IFileAttributesConfig>>;
@Injectable({
providedIn: 'root',
@ -25,12 +24,12 @@ export class FileAttributesService extends EntitiesService<FileAttributeConfig,
* Get the file attributes that can be used at importing csv.
*/
@Validate()
getFileAttributesConfig(@RequiredParam() dossierTemplateId: string, fetch = true): Observable<FileAttributesConfig> {
getFileAttributesConfig(@RequiredParam() dossierTemplateId: string, fetch = true): Observable<IFileAttributesConfig> {
if (!fetch) {
return this._fileAttributesConfig$.pipe(map(entities => entities[dossierTemplateId]));
}
const request$ = this._getOne<FileAttributesConfig>(['config', dossierTemplateId]);
const request$ = this._getOne<IFileAttributesConfig>(['config', dossierTemplateId]);
return request$.pipe(
tap(entities =>
this._fileAttributesConfig$.next({
@ -42,7 +41,7 @@ export class FileAttributesService extends EntitiesService<FileAttributeConfig,
);
}
getFileAttributeConfig(dossierTemplateId: string): FileAttributesConfig | undefined {
getFileAttributeConfig(dossierTemplateId: string): IFileAttributesConfig | undefined {
return this._fileAttributesConfig$.value[dossierTemplateId];
}
@ -59,7 +58,7 @@ export class FileAttributesService extends EntitiesService<FileAttributeConfig,
* Set file attributes base configuration and a list of file attributes,
*/
@Validate()
setFileAttributeConfig(@RequiredParam() body: FileAttributesConfig, @RequiredParam() dossierTemplateId: string) {
setFileAttributeConfig(@RequiredParam() body: IFileAttributesConfig, @RequiredParam() dossierTemplateId: string) {
const url = `${this._defaultModelPath}/config/baseConfig/${dossierTemplateId}`;
return this._put<unknown>(body, url);
}

View File

@ -1,7 +1,6 @@
import { Injectable, Injector } from '@angular/core';
import { EntitiesService, List, RequiredParam, Validate } from '@iqser/common-ui';
import { IFile } from '@redaction/red-ui-http';
import { File } from '@models/file/file';
import { File, IFile } from '@red/domain';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { UserService } from '../user.service';

View File

@ -1,7 +1,6 @@
import { Injectable, Injector } from '@angular/core';
import { EntitiesService, RequiredParam, Validate } from '@iqser/common-ui';
import { ILegalBasis } from '@redaction/red-ui-http';
import { Justification } from '@models/justification.model';
import { ILegalBasis, Justification } from '@red/domain';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

View File

@ -1,11 +1,11 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
import { GeneralConfigurationModel } from '@redaction/red-ui-http';
import { IGeneralConfiguration } from '@red/domain';
@Injectable({
providedIn: 'root',
})
export class GeneralSettingsService extends GenericService<GeneralConfigurationModel> {
export class GeneralSettingsService extends GenericService<IGeneralConfiguration> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'configuration');
}
@ -15,7 +15,7 @@ export class GeneralSettingsService extends GenericService<GeneralConfigurationM
}
@Validate()
updateGeneralConfigurations(@RequiredParam() body: GeneralConfigurationModel) {
updateGeneralConfigurations(@RequiredParam() body: IGeneralConfiguration) {
return this._post<unknown>(body, `${this._defaultModelPath}/general`);
}
}

View File

@ -1,9 +1,7 @@
import { Injectable } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { UserService } from './user.service';
import { File } from '@models/file/file';
import { Comment } from '@redaction/red-ui-http';
import { Dossier } from '@red/domain';
import { Dossier, File, IComment } from '@red/domain';
import { DossiersService } from './entity-services/dossiers.service';
@Injectable({
@ -147,7 +145,7 @@ export class PermissionsService {
return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file.status) && (this.isFileReviewer(file) || this.isApprover());
}
canDeleteComment(comment: Comment, file = this._activeFile) {
canDeleteComment(comment: IComment, file = this._activeFile) {
return (comment.user === this._userService.currentUser.id || this.isApprover()) && !file.isApproved;
}
}

View File

@ -1,6 +1,6 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, HeadersConfiguration, RequiredParam, Validate } from '@iqser/common-ui';
import { PlaceholdersResponse, ReportTemplate } from '@redaction/red-ui-http';
import { IPlaceholdersResponse, IReportTemplate } from '@red/domain';
import { Observable } from 'rxjs';
import { HttpResponse } from '@angular/common/http';
@ -35,12 +35,12 @@ export class ReportTemplateService extends GenericService<unknown> {
@Validate()
getAvailableReportTemplates(@RequiredParam() dossierTemplateId: string) {
return this.getAll<ReportTemplate[]>(`${this._defaultModelPath}/${dossierTemplateId}`);
return this.getAll<IReportTemplate[]>(`${this._defaultModelPath}/${dossierTemplateId}`);
}
@Validate()
getAvailablePlaceholders(@RequiredParam() dossierTemplateId: string) {
return this._getOne<PlaceholdersResponse>([dossierTemplateId], 'placeholders');
return this._getOne<IPlaceholdersResponse>([dossierTemplateId], 'placeholders');
}
downloadReportTemplate(dossierTemplateId: string, templateId: string, observe: 'response'): Observable<HttpResponse<Blob>>;

View File

@ -1,11 +1,10 @@
import { Inject, Injectable, Injector } from '@angular/core';
import { KeycloakService } from 'keycloak-angular';
import jwt_decode from 'jwt-decode';
import { CreateUserRequest, ResetPasswordRequest } from '@redaction/red-ui-http';
import { ICreateUserRequest, IMyProfileUpdateRequest, IProfileUpdateRequest, IResetPasswordRequest, IUser, User } from '@red/domain';
import { wipeCaches } from '@redaction/red-cache';
import { BASE_HREF } from '../tokens';
import { BehaviorSubject, Observable } from 'rxjs';
import { IMyProfileUpdateRequest, IProfileUpdateRequest, IUser, User } from '@red/domain';
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
import { tap } from 'rxjs/operators';
@ -96,12 +95,12 @@ export class UserService extends EntitiesService<User, IUser> {
}
@Validate()
resetPassword(@RequiredParam() body: ResetPasswordRequest, @RequiredParam() userId: string) {
resetPassword(@RequiredParam() body: IResetPasswordRequest, @RequiredParam() userId: string) {
return this._post<unknown>(body, `${this._defaultModelPath}/${userId}/reset-password`);
}
@Validate()
create(@RequiredParam() body: CreateUserRequest) {
create(@RequiredParam() body: ICreateUserRequest) {
return this._post(body);
}

View File

@ -1,12 +1,10 @@
import { Injectable } from '@angular/core';
import { Colors, IFile } from '@redaction/red-ui-http';
import { Dictionary, Dossier, DossierTemplate, File, IColors, IDossier, IFile } from '@red/domain';
import { ActivationEnd, Router } from '@angular/router';
import { UserService } from '@services/user.service';
import { forkJoin, Observable, of, Subject } from 'rxjs';
import { catchError, filter, first, map, tap } from 'rxjs/operators';
import { currentComponentRoute, FALLBACK_COLOR, hexToRgb } from '@utils/functions';
import { File } from '@models/file/file';
import { Dictionary, Dossier, DossierTemplate, IDossier } from '@red/domain';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { UserPreferenceService } from '@services/user-preference.service';
import { FilesService } from '@services/entity-services/files.service';
@ -275,7 +273,7 @@ export class AppStateService {
requestRemove: FALLBACK_COLOR,
updatedColor: FALLBACK_COLOR,
dossierTemplateId: dossierTemplateId,
} as Colors),
} as IColors),
),
);
}

View File

@ -1,5 +1,4 @@
import { File } from '@models/file/file';
import { Dossier, User, UserType } from '@red/domain';
import { Dossier, File, User, UserType } from '@red/domain';
import { handleCheckedValue, INestedFilter } from '@iqser/common-ui';
export function handleFilterDelta(oldFilters: INestedFilter[], newFilters: INestedFilter[], allFilters: INestedFilter[]) {

View File

@ -1,5 +1,4 @@
export * from './sorters/redaction-filter-sorter';
export * from './sorters/status-sorter';
export * from './sorters/super-type-sorter';
export * from './api-path-interceptor';

View File

@ -1,23 +0,0 @@
type StatusSorterItem = { key?: string } | string;
export const StatusSorter = {
ERROR: 0,
UNPROCESSED: 1,
REPROCESS: 5,
PROCESSING: 5,
OCR_PROCESSING: 7,
UNASSIGNED: 10,
UNDER_REVIEW: 15,
UNDER_APPROVAL: 20,
APPROVED: 25,
byStatus: (a: StatusSorterItem, b: StatusSorterItem): number => {
if (typeof a !== typeof b) {
return;
}
const x = typeof a === 'string' ? a : a.key;
const y = typeof b === 'string' ? b : b.key;
return StatusSorter[x] - StatusSorter[y];
},
};

View File

@ -1,3 +1,3 @@
import { FileStatus } from '@redaction/red-ui-http';
import { DossierStatus, FileStatus } from '@red/domain';
export type Color = FileStatus | DossierStatus.StatusEnum;
export type Color = FileStatus | DossierStatus | string;

View File

@ -3,7 +3,8 @@ server {
listen 8080;
proxy_hide_header WWW-Authenticate;
port_in_redirect off;
server_tokens off;
root /usr/share/nginx/html;
# SSL stuff for cloudflare proxy-ing - ignores SSL certificate and uses SNI
proxy_ssl_verify off;
@ -15,9 +16,8 @@ server {
}
location /ui/ {
alias /usr/share/nginx/html/ui/;
proxy_hide_header WWW-Authenticate;
try_files $uri$args $uri$args/ $uri $uri/ /index.html =404;
try_files $uri$args $uri$args/ $uri $uri/ /ui/index.html =404;
}
client_max_body_size 0;
@ -31,3 +31,4 @@ server {
gzip_types application/javascript text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
}

@ -1 +1 @@
Subproject commit defdc2af4e226ca8bb17df6c4d1cdd85130cfce5
Subproject commit 1df1b1ab899e21093eb07c444acf90def933cb02

View File

@ -1,6 +1,6 @@
export * from './lib/dossiers';
export * from './lib/search';
export * from './lib/shared/types';
export * from './lib/shared';
export * from './lib/dossier-attributes';
export * from './lib/users';
export * from './lib/pages';
@ -8,3 +8,12 @@ export * from './lib/audit';
export * from './lib/notifications';
export * from './lib/dossier-templates';
export * from './lib/dictionaries';
export * from './lib/redaction-log';
export * from './lib/geometry';
export * from './lib/file-attributes';
export * from './lib/files';
export * from './lib/downloads';
export * from './lib/reports';
export * from './lib/configuration';
export * from './lib/signature';
export * from './lib/legal-basis';

View File

@ -1,5 +1,5 @@
import { IListable } from '@iqser/common-ui';
import { IAudit } from './audit.interface';
import { IAudit } from './audit';
export class Audit implements IAudit, IListable {
readonly recordId: string;

Some files were not shown because too many files have changed in this diff Show More