Report Templates are now used for download package, old enums have been removed

This commit is contained in:
Timo 2021-07-22 15:04:00 +03:00
parent cf583dde4d
commit ea753f02d6
21 changed files with 209 additions and 279 deletions

View File

@ -38,8 +38,8 @@ export class DossierTemplateModelWrapper {
return this.dossierTemplateModel.name;
}
get reportTypes() {
return this.dossierTemplateModel.reportTypes;
get reportTemplateIds() {
return this.dossierTemplateModel.reportTemplateIds;
}
get validFrom() {

View File

@ -36,7 +36,7 @@ export class AdminSideNavComponent {
{ screen: 'watermark' },
{ screen: 'file-attributes' },
{ screen: 'dossier-attributes' },
{ screen: 'reports', onlyDevMode: true }
{ screen: 'reports' }
]
};

View File

@ -1,10 +1,8 @@
<section class="dialog">
<div class="dialog-header heading-l">
{{
(dossierTemplate
? 'add-edit-dossier-template.title.edit'
: 'add-edit-dossier-template.title.new'
) | translate: { name: dossierTemplate?.name }
(dossierTemplate ? 'add-edit-dossier-template.title.edit' : 'add-edit-dossier-template.title.new')
| translate: { name: dossierTemplate?.name }
}}
</div>
@ -15,9 +13,7 @@
<input
formControlName="name"
name="name"
placeholder="{{
'add-edit-dossier-template.form.name-placeholder' | translate
}}"
placeholder="{{ 'add-edit-dossier-template.form.name-placeholder' | translate }}"
type="text"
/>
</div>
@ -27,9 +23,7 @@
<textarea
formControlName="description"
name="description"
placeholder="{{
'add-edit-dossier-template.form.description-placeholder' | translate
}}"
placeholder="{{ 'add-edit-dossier-template.form.description-placeholder' | translate }}"
rows="4"
type="text"
></textarea>
@ -46,12 +40,7 @@
{{ 'add-edit-dossier-template.form.valid-from' | translate }}
</mat-checkbox>
<mat-checkbox
(change)="hasValidTo = !hasValidTo"
[checked]="hasValidTo"
class="filter-menu-checkbox"
color="primary"
>
<mat-checkbox (change)="hasValidTo = !hasValidTo" [checked]="hasValidTo" class="filter-menu-checkbox" color="primary">
{{ 'add-edit-dossier-template.form.valid-to' | translate }}
</mat-checkbox>
</div>
@ -59,11 +48,7 @@
<div>
<div class="red-input-group datepicker-wrapper">
<ng-container *ngIf="hasValidFrom">
<input
[matDatepicker]="fromPicker"
formControlName="validFrom"
placeholder="dd/mm/yy"
/>
<input [matDatepicker]="fromPicker" formControlName="validFrom" placeholder="dd/mm/yy" />
<mat-datepicker-toggle [for]="fromPicker" matSuffix>
<mat-icon matDatepickerToggleIcon svgIcon="red:calendar"></mat-icon>
</mat-datepicker-toggle>
@ -73,11 +58,7 @@
<div class="red-input-group datepicker-wrapper">
<ng-container *ngIf="hasValidTo">
<input
[matDatepicker]="toPicker"
formControlName="validTo"
placeholder="dd/mm/yy"
/>
<input [matDatepicker]="toPicker" formControlName="validTo" placeholder="dd/mm/yy" />
<mat-datepicker-toggle [for]="toPicker" matSuffix>
<mat-icon matDatepickerToggleIcon svgIcon="red:calendar"></mat-icon>
</mat-datepicker-toggle>
@ -89,27 +70,29 @@
<p class="download-includes">{{ 'download-includes' | translate }}</p>
<div class="d-flex">
<!-- only in edit mode-->
<redaction-select
*ngIf="dossierTemplate?.dossierTemplateId"
[label]="
'report-type.label'
| translate
: {
length: this.dossierTemplateForm.controls['reportTypes'].value
.length
length: dossierTemplateForm.controls['reportTemplateIds'].value.length
}
"
[options]="reportTypesEnum"
[optionTemplate]="reportTemplateOptionTemplate"
[options]="availableReportTypes"
[valueMapper]="reportTemplateValueMapper"
[translatePrefix]="'report-type.'"
class="mr-16"
formControlName="reportTypes"
formControlName="reportTemplateIds"
></redaction-select>
<redaction-select
[label]="
'download-type.label'
| translate
: {
length: this.dossierTemplateForm.controls['downloadFileTypes']
.value.length
length: dossierTemplateForm.controls['downloadFileTypes'].value.length
}
"
[options]="downloadTypesEnum"
@ -120,20 +103,15 @@
</div>
<div class="dialog-actions">
<button
[disabled]="dossierTemplateForm.invalid || !changed"
color="primary"
mat-flat-button
type="submit"
>
<button [disabled]="dossierTemplateForm.invalid || !changed" color="primary" mat-flat-button type="submit">
{{ 'add-edit-dossier-template.save' | translate }}
</button>
</div>
</form>
<redaction-circle-button
class="dialog-close"
icon="red:close"
mat-dialog-close
></redaction-circle-button>
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
</section>
<ng-template #reportTemplateOptionTemplate let-option="option">
{{ option.fileName }}
</ng-template>

View File

@ -1,10 +1,15 @@
import { Component, Inject } from '@angular/core';
import { Component, Inject, OnInit } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import * as moment from 'moment';
import { Moment } from 'moment';
import { DossierTemplateControllerService, DossierTemplateModel } from '@redaction/red-ui-http';
import {
DossierTemplateControllerService,
DossierTemplateModel,
ReportTemplate,
ReportTemplateControllerService
} from '@redaction/red-ui-http';
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
@Component({
@ -12,20 +17,23 @@ import { applyIntervalConstraints } from '@utils/date-inputs-utils';
templateUrl: './add-edit-dossier-template-dialog.component.html',
styleUrls: ['./add-edit-dossier-template-dialog.component.scss']
})
export class AddEditDossierTemplateDialogComponent {
export class AddEditDossierTemplateDialogComponent implements OnInit {
dossierTemplateForm: FormGroup;
hasValidFrom: boolean;
hasValidTo: boolean;
downloadTypesEnum = ['ORIGINAL', 'PREVIEW', 'REDACTED'];
reportTypesEnum = Object.values(DossierTemplateModel.ReportTypesEnum);
availableReportTypes = [];
private _previousValidFrom: Moment;
private _previousValidTo: Moment;
reportTemplateValueMapper = (reportTemplate: ReportTemplate) => reportTemplate.templateId;
constructor(
private readonly _appStateService: AppStateService,
private readonly _formBuilder: FormBuilder,
private readonly _dossierTemplateController: DossierTemplateControllerService,
private readonly _reportTemplateController: ReportTemplateControllerService,
public dialogRef: MatDialogRef<AddEditDossierTemplateDialogComponent>,
@Inject(MAT_DIALOG_DATA) public dossierTemplate: DossierTemplateModel
) {
@ -40,21 +48,8 @@ export class AddEditDossierTemplateDialogComponent {
this.dossierTemplate?.validTo ? moment(this.dossierTemplate?.validTo) : null,
this._requiredIfValidator(() => this.hasValidTo)
],
downloadFileTypes: [
this.dossierTemplate
? this.dossierTemplate.downloadFileTypes
: ['PREVIEW', 'REDACTED']
],
reportTypes: [
this.dossierTemplate
? this.dossierTemplate.reportTypes
: [
'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE',
'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE',
'EXCEL_MULTI_FILE'
],
Validators.required
]
downloadFileTypes: [this.dossierTemplate?.downloadFileTypes || ['PREVIEW', 'REDACTED']],
reportTemplateIds: [this.dossierTemplate?.reportTemplateIds || [], Validators.required]
});
this.hasValidFrom = !!this.dossierTemplate?.validFrom;
this.hasValidTo = !!this.dossierTemplate?.validTo;
@ -67,6 +62,11 @@ export class AddEditDossierTemplateDialogComponent {
});
}
async ngOnInit() {
this.availableReportTypes =
(await this._reportTemplateController.getAvailableReportTemplates(this.dossierTemplate?.dossierTemplateId).toPromise()) || [];
}
get changed(): boolean {
if (!this.dossierTemplate) return true;
@ -77,9 +77,7 @@ export class AddEditDossierTemplateDialogComponent {
}
if (
this.hasValidFrom &&
!moment(this.dossierTemplate.validFrom).isSame(
moment(this.dossierTemplateForm.get('validFrom').value)
)
!moment(this.dossierTemplate.validFrom).isSame(moment(this.dossierTemplateForm.get('validFrom').value))
) {
return true;
}
@ -89,9 +87,7 @@ export class AddEditDossierTemplateDialogComponent {
}
if (
this.hasValidTo &&
!moment(this.dossierTemplate.validTo).isSame(
moment(this.dossierTemplateForm.get('validTo').value)
)
!moment(this.dossierTemplate.validTo).isSame(moment(this.dossierTemplateForm.get('validTo').value))
) {
return true;
}
@ -110,9 +106,7 @@ export class AddEditDossierTemplateDialogComponent {
validFrom: this.hasValidFrom ? this.dossierTemplateForm.get('validFrom').value : null,
validTo: this.hasValidTo ? this.dossierTemplateForm.get('validTo').value : null
};
await this._dossierTemplateController
.createOrUpdateDossierTemplate(dossierTemplate)
.toPromise();
await this._dossierTemplateController.createOrUpdateDossierTemplate(dossierTemplate).toPromise();
await this._appStateService.loadAllDossierTemplates();
await this._appStateService.loadDictionaryData();
this.dialogRef.close(dossierTemplate);

View File

@ -16,18 +16,10 @@
<div class="red-input-group required w-400">
<mat-form-field floatLabel="always">
<mat-label>{{ 'add-dossier-dialog.form.template' | translate }}</mat-label>
<mat-select
(valueChange)="dossierTemplateChanged($event)"
formControlName="dossierTemplateId"
style="width: 100%"
>
<mat-select (valueChange)="dossierTemplateChanged($event)" formControlName="dossierTemplateId" style="width: 100%">
<mat-option
*ngFor="let dossierTemplate of dossierTemplates"
[matTooltip]="
dossierTemplate.description
? dossierTemplate.description
: dossierTemplate.name
"
[matTooltip]="dossierTemplate.description ? dossierTemplate.description : dossierTemplate.name"
[value]="dossierTemplate.dossierTemplateId"
matTooltipPosition="after"
>
@ -54,21 +46,12 @@
</mat-checkbox>
<div class="due-date">
<mat-checkbox
(change)="hasDueDate = !hasDueDate"
[checked]="hasDueDate"
class="filter-menu-checkbox"
color="primary"
>
<mat-checkbox (change)="hasDueDate = !hasDueDate" [checked]="hasDueDate" class="filter-menu-checkbox" color="primary">
{{ 'add-dossier-dialog.form.due-date' | translate }}
</mat-checkbox>
<div *ngIf="hasDueDate" class="red-input-group datepicker-wrapper">
<input
[matDatepicker]="picker"
formControlName="dueDate"
placeholder="dd/mm/yy"
/>
<input [matDatepicker]="picker" formControlName="dueDate" placeholder="dd/mm/yy" />
<mat-datepicker-toggle [for]="picker" matSuffix>
<mat-icon matDatepickerToggleIcon svgIcon="red:calendar"></mat-icon>
</mat-datepicker-toggle>
@ -79,11 +62,13 @@
<p class="download-includes">{{ 'download-includes' | translate }}</p>
<div class="d-flex">
<redaction-select
[label]="'report-type.label' | translate: { length: reportTypesLength }"
[options]="reportTypesEnum"
[label]="'report-type.label' | translate: { length: reportTemplateIdsLength }"
[options]="availableReportTypes"
[optionTemplate]="reportTemplateOptionTemplate"
[valueMapper]="reportTemplateValueMapper"
[translatePrefix]="'report-type.'"
class="mr-16"
formControlName="reportTypes"
formControlName="reportTemplateIds"
></redaction-select>
<redaction-select
[label]="'download-type.label' | translate: { length: downloadFileTypesLength }"
@ -109,9 +94,9 @@
</div>
</form>
<redaction-circle-button
class="dialog-close"
icon="red:close"
mat-dialog-close
></redaction-circle-button>
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
</section>
<ng-template #reportTemplateOptionTemplate let-option="option">
{{ option.fileName }}
</ng-template>

View File

@ -1,6 +1,6 @@
import { Component } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { Dossier, DossierTemplateModel } from '@redaction/red-ui-http';
import { Dossier, DossierTemplateModel, ReportTemplate, ReportTemplateControllerService } from '@redaction/red-ui-http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '@state/app-state.service';
import * as moment from 'moment';
@ -14,12 +14,14 @@ export class AddDossierDialogComponent {
dossierForm: FormGroup;
hasDueDate = false;
downloadTypesEnum = ['ORIGINAL', 'PREVIEW', 'REDACTED'];
reportTypesEnum = Object.values(DossierTemplateModel.ReportTypesEnum);
dossierTemplates: DossierTemplateModel[];
availableReportTypes = [];
reportTemplateValueMapper = (reportTemplate: ReportTemplate) => reportTemplate.templateId;
constructor(
private readonly _appStateService: AppStateService,
private readonly _formBuilder: FormBuilder,
private readonly _reportTemplateController: ReportTemplateControllerService,
public dialogRef: MatDialogRef<AddDossierDialogComponent>
) {
this._filterInvalidDossierTemplates();
@ -28,20 +30,22 @@ export class AddDossierDialogComponent {
dossierName: [null, Validators.required],
dossierTemplateId: [null, Validators.required],
downloadFileTypes: [null],
reportTypes: [null],
reportTemplateIds: [null],
description: [null],
dueDate: [null],
watermarkEnabled: [true]
},
{
validators: control =>
control.value.reportTypes?.length > 0 || control.value.downloadFileTypes?.length > 0 ? null : { downloadPackage: true }
control.value.reportTemplateIds?.length > 0 || control.value.downloadFileTypes?.length > 0
? null
: { downloadPackage: true }
}
);
}
get reportTypesLength() {
return this.dossierForm.controls['reportTypes']?.value?.length || 0;
get reportTemplateIdsLength() {
return this.dossierForm.controls['reportTemplateIds']?.value?.length || 0;
}
get downloadFileTypesLength() {
@ -78,15 +82,27 @@ export class AddDossierDialogComponent {
}
}
dossierTemplateChanged(dossierTemplateId) {
async dossierTemplateChanged(dossierTemplateId) {
// get current selected dossierTemplate
const dossierTemplate = this.dossierTemplates.find(r => r.dossierTemplateId === dossierTemplateId);
if (dossierTemplate) {
this.availableReportTypes =
(await this._reportTemplateController.getAvailableReportTemplates(dossierTemplate.dossierTemplateId).toPromise()) || [];
// update dropdown values
this.dossierForm.patchValue(
{
downloadFileTypes: dossierTemplate.downloadFileTypes,
reportTypes: dossierTemplate.reportTypes
reportTemplateIds: dossierTemplate.reportTemplateIds
},
{ emitEvent: false }
);
} else {
this.availableReportTypes = [];
this.dossierForm.patchValue(
{
downloadFileTypes: [],
reportTemplateIds: []
},
{ emitEvent: false }
);
@ -108,7 +124,9 @@ export class AddDossierDialogComponent {
dueDate: this.hasDueDate ? this.dossierForm.get('dueDate').value : undefined,
dossierTemplateId: this.dossierForm.get('dossierTemplateId').value,
downloadFileTypes: this.dossierForm.get('downloadFileTypes').value,
reportTypes: this.dossierForm.get('reportTypes').value,
reportTemplateIds: this.dossierForm.get('reportTemplateIds').value,
// TODO REMOVE THIS
reportTypes: [],
watermarkEnabled: this.dossierForm.get('watermarkEnabled').value
};
}

View File

@ -1,10 +1,12 @@
<form [formGroup]="dossierForm">
<form [formGroup]="dossierForm" *ngIf="dossierForm">
<redaction-select
[label]="'report-type.label' | translate: { length: reportTypesLength }"
[options]="reportTypesEnum"
[options]="availableReportTypes"
[valueMapper]="reportTemplateValueMapper"
[optionTemplate]="reportTemplateOptionTemplate"
[translatePrefix]="'report-type.'"
class="mr-16"
formControlName="reportTypes"
formControlName="reportTemplateIds"
></redaction-select>
<redaction-select
[label]="'download-type.label' | translate: { length: downloadFileTypesLength }"
@ -13,3 +15,7 @@
formControlName="downloadFileTypes"
></redaction-select>
</form>
<ng-template #reportTemplateOptionTemplate let-option="option">
{{ option.fileName }}
</ng-template>

View File

@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { DossierTemplateModel } from '@redaction/red-ui-http';
import { DossierTemplateModel, ReportTemplate, ReportTemplateControllerService } from '@redaction/red-ui-http';
import { FormBuilder, FormGroup } from '@angular/forms';
import { AppStateService } from '@state/app-state.service';
import { DossierWrapper } from '@state/model/dossier.wrapper';
@ -13,16 +13,22 @@ import { EditDossierSectionInterface } from '../edit-dossier-section.interface';
export class EditDossierDownloadPackageComponent implements OnInit, EditDossierSectionInterface {
dossierForm: FormGroup;
downloadTypesEnum = ['ORIGINAL', 'PREVIEW', 'REDACTED'];
reportTypesEnum = Object.values(DossierTemplateModel.ReportTypesEnum);
dossierTemplates: DossierTemplateModel[];
availableReportTypes = [];
@Input() dossierWrapper: DossierWrapper;
@Output() updateDossier = new EventEmitter<any>();
constructor(private readonly _appStateService: AppStateService, private readonly _formBuilder: FormBuilder) {}
reportTemplateValueMapper = (reportTemplate: ReportTemplate) => reportTemplate.templateId;
constructor(
private readonly _appStateService: AppStateService,
private readonly _reportTemplateController: ReportTemplateControllerService,
private readonly _formBuilder: FormBuilder
) {}
get reportTypesLength() {
return this.dossierForm.controls['reportTypes']?.value?.length || 0;
return this.dossierForm.controls['reportTemplateIds']?.value?.length || 0;
}
get downloadFileTypesLength() {
@ -52,15 +58,20 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
return this.dossierForm.invalid;
}
ngOnInit() {
async ngOnInit() {
this.availableReportTypes =
(await this._reportTemplateController.getAvailableReportTemplates(this.dossierWrapper.dossierTemplateId).toPromise()) || [];
this.dossierForm = this._formBuilder.group(
{
reportTypes: [this.dossierWrapper.dossier.reportTypes],
reportTemplateIds: [this.dossierWrapper.dossier.reportTemplateIds],
downloadFileTypes: [this.dossierWrapper.dossier.downloadFileTypes]
},
{
validators: control =>
control.value.reportTypes?.length > 0 || control.value.downloadFileTypes?.length > 0 ? null : { downloadPackage: true }
control.value.reportTemplateIds?.length > 0 || control.value.downloadFileTypes?.length > 0
? null
: { downloadPackage: true }
}
);
}
@ -69,7 +80,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
const dossier = {
...this.dossierWrapper.dossier,
downloadFileTypes: this.dossierForm.get('downloadFileTypes').value,
reportTypes: this.dossierForm.get('reportTypes').value
reportTemplateIds: this.dossierForm.get('reportTemplateIds').value
};
const updatedDossier = await this._appStateService.createOrUpdateDossier(dossier);
this.updateDossier.emit(updatedDossier);
@ -78,7 +89,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
revert() {
this.dossierForm.reset({
downloadFileTypes: this.dossierWrapper.dossier.downloadFileTypes,
reportTypes: this.dossierWrapper.dossier.reportTypes
reportTemplateIds: this.dossierWrapper.dossier.reportTemplateIds
});
}
}

View File

@ -20,7 +20,6 @@ import { Toaster } from '../../../../../services/toaster.service';
export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSectionInterface {
dossierForm: FormGroup;
hasDueDate: boolean;
readonly reportTypesEnum = Object.values(DossierTemplateModel.ReportTypesEnum);
dossierTemplates: DossierTemplateModel[];
@Input() dossierWrapper: DossierWrapper;

View File

@ -24,7 +24,8 @@ export class FileActionService {
}
return this._reanalysisControllerService.reanalyzeFile(
this._appStateService.activeDossier.dossier.dossierId,
fileStatusWrapper.fileId
fileStatusWrapper.fileId,
true
);
}
@ -47,11 +48,7 @@ export class FileActionService {
}
}
assignDossierApprover(
file?: FileStatusWrapper,
callback?: Function,
ignoreDialogChanges = false
) {
assignDossierApprover(file?: FileStatusWrapper, callback?: Function, ignoreDialogChanges = false) {
this._dialogService.openAssignFileToUserDialog(
file ? [file] : [this._appStateService.activeFile],
'approver',
@ -65,11 +62,7 @@ export class FileActionService {
);
}
assignDossierReviewer(
file?: FileStatusWrapper,
callback?: Function,
ignoreDialogChanges = false
) {
assignDossierReviewer(file?: FileStatusWrapper, callback?: Function, ignoreDialogChanges = false) {
this._dialogService.openAssignFileToUserDialog(
file ? [file] : [this._appStateService.activeFile],
'reviewer',
@ -88,10 +81,7 @@ export class FileActionService {
fileStatus = [fileStatus];
}
const atLeastOneFileHasReviewer = fileStatus.reduce(
(acc, fs) => acc || !!fs.currentReviewer,
false
);
const atLeastOneFileHasReviewer = fileStatus.reduce((acc, fs) => acc || !!fs.currentReviewer, false);
if (atLeastOneFileHasReviewer) {
this._dialogService.openAssignFileToMeDialog(async () => {
await this._assignReviewerToCurrentUser(fileStatus, callback);
@ -148,22 +138,15 @@ export class FileActionService {
}
private _openAssignReviewerDialog(file?: FileStatusWrapper, callback?: Function) {
this._dialogService.openAssignFileToUserDialog(
file ? [file] : [this._appStateService.activeFile],
'reviewer',
async () => {
await this._appStateService.reloadActiveDossierFiles();
if (callback) {
callback();
}
this._dialogService.openAssignFileToUserDialog(file ? [file] : [this._appStateService.activeFile], 'reviewer', async () => {
await this._appStateService.reloadActiveDossierFiles();
if (callback) {
callback();
}
);
});
}
private async _assignReviewerToCurrentUser(
fileStatus: FileStatusWrapper | FileStatusWrapper[],
callback?: Function
) {
private async _assignReviewerToCurrentUser(fileStatus: FileStatusWrapper | FileStatusWrapper[], callback?: Function) {
if (!isArray(fileStatus)) {
fileStatus = [fileStatus];
}

View File

@ -1,16 +1,8 @@
<div class="label-header">
<div class="all-caps-label">{{ label }}</div>
<div class="actions">
<div
(click)="selectAll($event)"
class="all-caps-label primary pointer"
translate="actions.all"
></div>
<div
(click)="deselectAll($event)"
class="all-caps-label primary pointer"
translate="actions.none"
></div>
<div (click)="selectAll($event)" class="all-caps-label primary pointer" translate="actions.all"></div>
<div (click)="deselectAll($event)" class="all-caps-label primary pointer" translate="actions.none"></div>
</div>
</div>
@ -18,9 +10,17 @@
<mat-chip
#chip="matChip"
(click)="toggleSelection(chip)"
(selectionChange)="selectChange($event)"
*ngFor="let option of options"
[value]="option"
[value]="valueMapper(option)"
>
{{ translatePrefix + option | translate }}
<ng-container
[ngTemplateOutlet]="optionTemplate ?? defaultOptionTemplate"
[ngTemplateOutletContext]="{ option: option }"
></ng-container>
</mat-chip>
</mat-chip-list>
<ng-template #defaultOptionTemplate let-option="option">
{{ translatePrefix + option | translate }}
</ng-template>

View File

@ -1,7 +1,6 @@
import { AfterViewInit, ChangeDetectorRef, Component, Input, ViewChild } from '@angular/core';
import { AfterViewInit, ChangeDetectorRef, Component, Input, TemplateRef, ViewChild } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { MatChip, MatChipList } from '@angular/material/chips';
import { map } from 'rxjs/operators';
import { MatChip, MatChipList, MatChipSelectionChange } from '@angular/material/chips';
@Component({
selector: 'redaction-select',
@ -16,32 +15,40 @@ import { map } from 'rxjs/operators';
]
})
export class SelectComponent implements AfterViewInit, ControlValueAccessor {
@Input() optionTemplate: TemplateRef<any>;
@Input() label: string;
@Input() options: string[];
@Input() options: any[];
@Input() translatePrefix = '';
@Input() disabled = false;
@Input() multiple = true;
@ViewChild(MatChipList) chipList: MatChipList;
private _value: string[] = [];
private _onChange: (value: string[]) => void;
private _value: any[] = [];
private _onChange: (value: any[]) => void;
@Input() valueMapper: (option: any) => any = option => option;
constructor(private readonly _changeDetector: ChangeDetectorRef) {}
ngAfterViewInit(): void {
this._selectChips(this._value);
this.chipList.chipSelectionChanges.pipe(map(event => event.source)).subscribe(chip => {
setTimeout(() => {
this._selectChips(this._value);
this._changeDetector.detectChanges();
});
}
selectChange($event: MatChipSelectionChange) {
const chip = $event.source;
if ($event.isUserInput) {
if (chip.selected) {
this._value = [...this._value, chip.value];
} else {
this._value = this._value.filter(o => o !== chip.value);
}
this._propagateChange(this._value);
});
this._changeDetector.detectChanges();
this._propagateChange([...new Set(this._value)]);
}
}
registerOnChange(fn: any): void {
@ -51,9 +58,12 @@ export class SelectComponent implements AfterViewInit, ControlValueAccessor {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
registerOnTouched(fn: any): void {}
writeValue(value: string[]): void {
if (this.chipList && value) this._selectChips(value);
else if (value) this._value = value;
writeValue(value: any[]): void {
if (this.chipList && value) {
this._selectChips(value);
} else if (value) {
this._value = value;
}
}
setDisabledState?(isDisabled: boolean): void {
@ -61,28 +71,34 @@ export class SelectComponent implements AfterViewInit, ControlValueAccessor {
}
toggleSelection(chip: MatChip): void {
if (!this.disabled) chip.toggleSelected();
if (!this.disabled) chip.toggleSelected(true);
}
selectAll($event) {
$event.stopPropagation();
this.chipList.chips.forEach(chip => chip.select());
this.chipList.chips.forEach(chip => {
if (!chip.selected) {
chip.toggleSelected(true);
}
});
}
deselectAll($event) {
$event.stopPropagation();
this.chipList.chips.forEach(chip => chip.deselect());
deselectAll($event?) {
$event?.stopPropagation();
this.chipList.chips.forEach(chip => {
if (chip.selected) {
chip.toggleSelected(true);
}
});
}
private _selectChips(value: string[]): void {
this.chipList.chips.forEach(chip => chip.deselect());
private _selectChips(value: any[]): void {
this.deselectAll();
const chipsToSelect = this.chipList.chips.filter(c => value.includes(c.value));
chipsToSelect.forEach(chip => chip.select());
chipsToSelect.forEach(chip => chip.toggleSelected(true));
}
private _propagateChange(value: string[]): void {
private _propagateChange(value: any[]): void {
if (this._onChange) this._onChange(value);
}
}

View File

@ -15,7 +15,6 @@ export class LoadingService {
}
start(): void {
console.log('start');
this._loadingEvent.next(true);
this._loadingStarted = new Date().getTime();
}

View File

@ -13,7 +13,9 @@ export interface SortingOption {
column: string;
}
@Injectable()
@Injectable({
providedIn: 'root'
})
export class SortingService {
private _sortingOption: SortingOption;

View File

@ -15,7 +15,7 @@ import { Event, NavigationEnd, ResolveStart, Router } from '@angular/router';
import { UserService } from '@services/user.service';
import { forkJoin, Observable, of } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { humanize } from '@utils/functions';
import { FALLBACK_COLOR, hexToRgb, humanize } from '@utils/functions';
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
import { DossierWrapper } from './model/dossier.wrapper';
import { TypeValueWrapper } from '@models/file/type-value.wrapper';
@ -258,7 +258,7 @@ export class AppStateService {
}
async reanalyzeDossier({ dossierId }: DossierWrapper = this.activeDossier) {
await this._reanalysisControllerService.reanalyzeDossier(dossierId).toPromise();
await this._reanalysisControllerService.reanalyzeDossier(dossierId, true).toPromise();
}
activateDossier(dossierId: string): void {
@ -403,6 +403,18 @@ export class AppStateService {
const colorsObs = this._dictionaryControllerService.getColors(dossierTemplateId).pipe(
tap(colors => {
for (const key of Object.keys(colors)) {
const color = colors[key];
try {
const rgbValue = hexToRgb(color);
if (!rgbValue) {
colors[key] = FALLBACK_COLOR;
}
} catch (e) {
colors[key] = FALLBACK_COLOR;
}
}
// declined
dictionaryData['declined-suggestion'] = new TypeValueWrapper(
{

View File

@ -1,3 +1,5 @@
export const FALLBACK_COLOR = '#CCCCCC';
export function groupBy(xs: any[], key: string) {
return xs.reduce((rv, x) => {
(rv[x[key]] = rv[x[key]] || []).push(x);

View File

@ -1,6 +1,6 @@
{
"OAUTH_URL": "https://dev-06.iqser.cloud/auth/realms/redaction",
"API_URL": "https://dev-06.iqser.cloud/redaction-gateway-v1",
"OAUTH_URL": "https://red-staging.iqser.cloud/auth/realms/redaction",
"API_URL": "https://red-staging.iqser.cloud/redaction-gateway-v1",
"OAUTH_CLIENT_ID": "redaction",
"BACKEND_APP_VERSION": "4.4.40",
"FRONTEND_APP_VERSION": "1.1",

View File

@ -23,19 +23,14 @@ export interface Dossier {
memberIds?: Array<string>;
ownerId?: string;
reportTemplateIds?: Array<string>;
reportTypes?: Array<Dossier.ReportTypesEnum>;
reportTypes?: Array<string>;
softDeletedTime?: string;
status?: Dossier.StatusEnum;
watermarkEnabled?: boolean;
}
export namespace Dossier {
export type DownloadFileTypesEnum =
| 'ANNOTATED'
| 'FLATTEN'
| 'ORIGINAL'
| 'PREVIEW'
| 'REDACTED';
export type DownloadFileTypesEnum = 'ANNOTATED' | 'FLATTEN' | 'ORIGINAL' | 'PREVIEW' | 'REDACTED';
export const DownloadFileTypesEnum = {
ANNOTATED: 'ANNOTATED' as DownloadFileTypesEnum,
FLATTEN: 'FLATTEN' as DownloadFileTypesEnum,
@ -43,20 +38,6 @@ export namespace Dossier {
PREVIEW: 'PREVIEW' as DownloadFileTypesEnum,
REDACTED: 'REDACTED' as DownloadFileTypesEnum
};
export type ReportTypesEnum =
| 'EXCEL_MULTI_FILE'
| 'EXCEL_SINGLE_FILE'
| 'WORD_SINGLE_FILE'
| 'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE'
| 'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE';
export const ReportTypesEnum = {
EXCELMULTIFILE: 'EXCEL_MULTI_FILE' as ReportTypesEnum,
EXCELSINGLEFILE: 'EXCEL_SINGLE_FILE' as ReportTypesEnum,
WORDSINGLEFILE: 'WORD_SINGLE_FILE' as ReportTypesEnum,
WORDSINGLEFILEAPPENDIXA1TEMPLATE:
'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE' as ReportTypesEnum,
WORDSINGLEFILEAPPENDIXA2TEMPLATE: 'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE' as ReportTypesEnum
};
export type StatusEnum = 'ACTIVE' | 'DELETED';
export const StatusEnum = {
ACTIVE: 'ACTIVE' as StatusEnum,

View File

@ -57,7 +57,7 @@ export interface DossierRequest {
/**
* Report File Types for this dossiers submission package.
*/
reportTypes?: Array<DossierRequest.ReportTypesEnum>;
reportTypes?: Array<string>;
/**
* Whether a watermark will be applied to the redacted files or not.
*/
@ -65,12 +65,7 @@ export interface DossierRequest {
}
export namespace DossierRequest {
export type DownloadFileTypesEnum =
| 'ANNOTATED'
| 'FLATTEN'
| 'ORIGINAL'
| 'PREVIEW'
| 'REDACTED';
export type DownloadFileTypesEnum = 'ANNOTATED' | 'FLATTEN' | 'ORIGINAL' | 'PREVIEW' | 'REDACTED';
export const DownloadFileTypesEnum = {
ANNOTATED: 'ANNOTATED' as DownloadFileTypesEnum,
FLATTEN: 'FLATTEN' as DownloadFileTypesEnum,
@ -78,18 +73,4 @@ export namespace DossierRequest {
PREVIEW: 'PREVIEW' as DownloadFileTypesEnum,
REDACTED: 'REDACTED' as DownloadFileTypesEnum
};
export type ReportTypesEnum =
| 'EXCEL_MULTI_FILE'
| 'EXCEL_SINGLE_FILE'
| 'WORD_SINGLE_FILE'
| 'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE'
| 'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE';
export const ReportTypesEnum = {
EXCELMULTIFILE: 'EXCEL_MULTI_FILE' as ReportTypesEnum,
EXCELSINGLEFILE: 'EXCEL_SINGLE_FILE' as ReportTypesEnum,
WORDSINGLEFILE: 'WORD_SINGLE_FILE' as ReportTypesEnum,
WORDSINGLEFILEAPPENDIXA1TEMPLATE:
'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE' as ReportTypesEnum,
WORDSINGLEFILEAPPENDIXA2TEMPLATE: 'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE' as ReportTypesEnum
};
}

View File

@ -46,7 +46,7 @@ export interface DossierTemplateModel {
/**
* Report File Types for this dossierTemplate's dossiers submission package.
*/
reportTypes?: Array<DossierTemplateModel.ReportTypesEnum>;
reportTemplateIds?: string[];
/**
* Validity of start this dossierTemplate.
*/
@ -58,12 +58,7 @@ export interface DossierTemplateModel {
}
export namespace DossierTemplateModel {
export type DownloadFileTypesEnum =
| 'ANNOTATED'
| 'FLATTEN'
| 'ORIGINAL'
| 'PREVIEW'
| 'REDACTED';
export type DownloadFileTypesEnum = 'ANNOTATED' | 'FLATTEN' | 'ORIGINAL' | 'PREVIEW' | 'REDACTED';
export const DownloadFileTypesEnum = {
ANNOTATED: 'ANNOTATED' as DownloadFileTypesEnum,
FLATTEN: 'FLATTEN' as DownloadFileTypesEnum,
@ -71,16 +66,4 @@ export namespace DossierTemplateModel {
PREVIEW: 'PREVIEW' as DownloadFileTypesEnum,
REDACTED: 'REDACTED' as DownloadFileTypesEnum
};
export type ReportTypesEnum =
| 'EXCEL_MULTI_FILE'
| 'EXCEL_SINGLE_FILE'
| 'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE'
| 'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE';
export const ReportTypesEnum = {
EXCELMULTIFILE: 'EXCEL_MULTI_FILE' as ReportTypesEnum,
EXCELSINGLEFILE: 'EXCEL_SINGLE_FILE' as ReportTypesEnum,
WORDSINGLEFILEAPPENDIXA1TEMPLATE:
'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE' as ReportTypesEnum,
WORDSINGLEFILEAPPENDIXA2TEMPLATE: 'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE' as ReportTypesEnum
};
}

View File

@ -14,16 +14,10 @@ export interface DownloadDetails {
downloadFileTypes?: Array<DownloadDetails.DownloadFileTypesEnum>;
fileIds?: Array<string>;
reportTemplateIds?: Array<string>;
reportTypes?: Array<DownloadDetails.ReportTypesEnum>;
}
export namespace DownloadDetails {
export type DownloadFileTypesEnum =
| 'ANNOTATED'
| 'FLATTEN'
| 'ORIGINAL'
| 'PREVIEW'
| 'REDACTED';
export type DownloadFileTypesEnum = 'ANNOTATED' | 'FLATTEN' | 'ORIGINAL' | 'PREVIEW' | 'REDACTED';
export const DownloadFileTypesEnum = {
ANNOTATED: 'ANNOTATED' as DownloadFileTypesEnum,
FLATTEN: 'FLATTEN' as DownloadFileTypesEnum,
@ -31,18 +25,4 @@ export namespace DownloadDetails {
PREVIEW: 'PREVIEW' as DownloadFileTypesEnum,
REDACTED: 'REDACTED' as DownloadFileTypesEnum
};
export type ReportTypesEnum =
| 'EXCEL_MULTI_FILE'
| 'EXCEL_SINGLE_FILE'
| 'WORD_SINGLE_FILE'
| 'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE'
| 'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE';
export const ReportTypesEnum = {
EXCELMULTIFILE: 'EXCEL_MULTI_FILE' as ReportTypesEnum,
EXCELSINGLEFILE: 'EXCEL_SINGLE_FILE' as ReportTypesEnum,
WORDSINGLEFILE: 'WORD_SINGLE_FILE' as ReportTypesEnum,
WORDSINGLEFILEAPPENDIXA1TEMPLATE:
'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE' as ReportTypesEnum,
WORDSINGLEFILEAPPENDIXA2TEMPLATE: 'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE' as ReportTypesEnum
};
}