Merge branch 'master' into VM/RED-6012

This commit is contained in:
Valentin Mihai 2023-05-03 22:53:27 +03:00
commit e22d598cef
28 changed files with 208 additions and 143 deletions

View File

@ -134,6 +134,10 @@ export class AnnotationWrapper implements IListable, Record<string, unknown> {
return this.type?.toLowerCase() === 'false_positive' && !!FalsePositiveSuperTypes[this.superType];
}
get isSuggestionAddToFalsePositive() {
return this.typeLabel === annotationTypesTranslations[SuggestionAddFalsePositive];
}
get isDeclinedSuggestion() {
return this.superType === SuperTypes.DeclinedSuggestion;
}

View File

@ -1,4 +1,4 @@
<div [translateParams]="{ userName: user | name }" [translate]="'reset-password-dialog.header'" class="dialog-header heading-l"></div>
<div [innerHTML]="'reset-password-dialog.header' | translate : { userName: user | name }" class="dialog-header heading-l"></div>
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">

View File

@ -1,5 +1,5 @@
<section class="dialog">
<div class="dialog-header heading-l" translate="smtp-auth-config.title"></div>
<div class="dialog-header heading-l" [translate]="'smtp-auth-config.title'"></div>
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">

View File

@ -1,5 +1,5 @@
<section class="dialog">
<div class="dialog-header heading-l" translate="upload-dictionary-dialog.title"></div>
<div class="dialog-header heading-l" [translate]="'upload-dictionary-dialog.title'"></div>
<div class="dialog-content">
<p translate="upload-dictionary-dialog.question"></p>

View File

@ -1,10 +1,8 @@
<section class="dialog">
<div
[translateParams]="{
type: data.justification ? 'edit' : 'create',
name: data.justification?.name
}"
[translate]="'add-edit-justification.title'"
[innerHTML]="
'add-edit-justification.title' | translate : { type: data.justification ? 'edit' : 'create', name: data.justification?.name }
"
class="dialog-header heading-l"
></div>

View File

@ -1,4 +1,4 @@
import { Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
import { ChangeDetectorRef, Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
import WebViewer, { WebViewerInstance } from '@pdftron/webviewer';
import { HttpClient } from '@angular/common/http';
import { FormBuilder, FormGroup } from '@angular/forms';
@ -85,7 +85,8 @@ export class WatermarkScreenComponent implements OnInit {
];
readonly orientationOptions = ['DIAGONAL', 'HORIZONTAL', 'VERTICAL'];
instance: WebViewerInstance;
readonly loaded$ = new BehaviorSubject(false);
readonly #loaded$ = new BehaviorSubject(false);
readonly loaded$ = this.#loaded$.asObservable().pipe(tap(() => setTimeout(() => this._changeDetectorRef.detectChanges())));
@ViewChild('viewer', { static: true }) private readonly _viewer: ElementRef<HTMLDivElement>;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly #watermarkId = Number(getParam(WATERMARK_ID));
@ -109,6 +110,7 @@ export class WatermarkScreenComponent implements OnInit {
private readonly _watermarkService: WatermarkService,
private readonly _userPreferenceService: UserPreferenceService,
private readonly _router: Router,
private readonly _changeDetectorRef: ChangeDetectorRef,
watermarksMapService: WatermarksMapService,
) {
const watermark$ = watermarksMapService.watch$(this.#dossierTemplateId, this.#watermarkId);
@ -248,9 +250,9 @@ export class WatermarkScreenComponent implements OnInit {
this.instance.UI.setTheme(this._userPreferenceService.getTheme());
this.instance.Core.documentViewer.addEventListener('documentLoaded', async () => {
this.loaded$.next(true);
this._loadingService.stop();
await this.#drawWatermark();
this.#loaded$.next(true);
this._loadingService.stop();
});
if (environment.production) {

View File

@ -1,20 +1,28 @@
<div class="file-attribute">
<span *ngIf="!isDate; else date" class="clamp-3"> {{ fileAttributeValue || '-' }}</span>
<ng-template #date>
<span class="clamp-3"> {{ fileAttributeValue ? (fileAttributeValue | date : 'd MMM yyyy') : '-' }}</span>
</ng-template>
<div class="value">
<span *ngIf="!isDate; else date" class="clamp-3"> {{ fileAttributeValue || '-' }}</span>
<ng-template #date>
<span class="clamp-3"> {{ fileAttributeValue ? (fileAttributeValue | date : 'd MMM yyyy') : '-' }}</span>
</ng-template>
</div>
<ng-container *ngIf="((fileAttributesService.isEditingFileAttribute$ | async) === false || isInEditMode) && !file.isProcessing">
<div *ngIf="!isInEditMode; else input" class="action-buttons edit-button">
<iqser-circle-button
(action)="editFileAttribute()"
*ngIf="permissionsService.canEditFileAttributes(file, dossier)"
[disabled]="!fileAttribute.editable"
[icon]="'iqser:edit'"
[tooltip]="'file-attribute.actions.edit' | translate"
[attr.help-mode-key]="'edit-file-attributes'"
id="edit-attribute-button"
></iqser-circle-button>
<ng-container
*ngIf="
((fileAttributesService.isEditingFileAttribute$ | async) === false || isInEditMode) &&
!file.isInitialProcessing &&
permissionsService.canEditFileAttributes(file, dossier)
"
>
<div
*ngIf="!isInEditMode; else input"
class="action-buttons edit-button"
[class.help-mode-button]="helpModeService.isHelpModeActive$ | async"
(click)="editFileAttribute($event)"
[attr.help-mode-key]="'edit-file-attributes'"
>
<div class="edit-icon">
<mat-icon [svgIcon]="'iqser:edit'"></mat-icon>
</div>
</div>
<ng-template #input>

View File

@ -4,29 +4,32 @@
display: flex;
align-items: center;
.edit-button {
position: absolute;
height: 100%;
right: 10%;
width: 90%;
background: linear-gradient(to left, var(--iqser-side-nav) 20%, rgba(244, 245, 247, 0) 60%);
.value {
z-index: 1;
}
iqser-circle-button {
position: absolute;
top: 50%;
left: 80%;
transform: translate(-50%, -50%);
}
.edit-icon {
display: none;
}
.help-mode-button {
background-color: var(--iqser-grey-6);
width: 90%;
height: 50%;
border-radius: 4px;
position: absolute;
margin-left: -10px;
}
.edit-input {
cursor: default;
display: flex;
z-index: 1;
border: solid var(--iqser-grey-4);
z-index: 2;
border: solid var(--iqser-grey-6);
border-radius: 10px;
background: var(--iqser-background);
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
margin-left: -10px;
form {
margin: 5px;
@ -43,3 +46,34 @@
}
}
}
.file-attribute:hover {
.edit-button {
background-color: var(--iqser-grey-6);
width: 100%;
height: 50%;
border-radius: 4px;
position: absolute;
margin-left: -10px;
}
.edit-icon {
z-index: 1;
background: white;
width: 23px;
height: 23px;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
right: 0;
border-radius: 50%;
margin-top: -8px;
margin-right: -8px;
mat-icon {
width: 13px;
height: 13px;
}
}
}

View File

@ -1,6 +1,6 @@
import { Component, HostListener, Input, OnDestroy, OnInit } from '@angular/core';
import { Dossier, File, FileAttributeConfigTypes, IFileAttributeConfig } from '@red/domain';
import { BaseFormComponent, ListingService, Toaster } from '@iqser/common-ui';
import { BaseFormComponent, HelpModeService, ListingService, Toaster } from '@iqser/common-ui';
import { PermissionsService } from '@services/permissions.service';
import { FormBuilder, UntypedFormGroup } from '@angular/forms';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
@ -33,6 +33,7 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr
readonly permissionsService: PermissionsService,
private readonly _listingService: ListingService<File>,
readonly fileAttributesService: FileAttributesService,
readonly helpModeService: HelpModeService,
) {
super();
const sub = router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => this.close());
@ -57,7 +58,8 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr
this.#subscriptions.unsubscribe();
}
async editFileAttribute(): Promise<void> {
async editFileAttribute($event: MouseEvent): Promise<void> {
$event.stopPropagation();
this.#toggleEdit();
}

View File

@ -375,7 +375,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
if (this._viewModeService.isRedacted) {
annotations = annotations.filter(a => !bool(a.isChangeLogRemoved));
annotations = this._suggestionsService.convertWorkloadRemoveSuggestionsToRedactions(annotations);
annotations = this._suggestionsService.filterWorkloadSuggestionsInPreview(annotations);
}
this.displayedAnnotations = this._annotationProcessingService.filterAndGroupAnnotations(annotations, primary, secondary);

View File

@ -1,10 +1,10 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-header heading-l" translate="change-legal-basis-dialog.header"></div>
<div class="dialog-header heading-l" [translate]="'change-legal-basis-dialog.header'"></div>
<div class="dialog-content">
<div class="iqser-input-group required w-400">
<label translate="change-legal-basis-dialog.content.reason"></label>
<label [translate]="'change-legal-basis-dialog.content.reason'"></label>
<mat-form-field>
<mat-select
[placeholder]="'change-legal-basis-dialog.content.reason-placeholder' | translate"
@ -19,22 +19,22 @@
</div>
<div class="iqser-input-group w-400">
<label translate="change-legal-basis-dialog.content.legalBasis"></label>
<label [translate]="'change-legal-basis-dialog.content.legalBasis'"></label>
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
</div>
<div class="iqser-input-group w-400">
<label translate="change-legal-basis-dialog.content.section"></label>
<label [translate]="'change-legal-basis-dialog.content.section'"></label>
<input formControlName="section" name="section" type="text" />
</div>
<div *ngIf="this.allRectangles" class="iqser-input-group w-400">
<label translate="change-legal-basis-dialog.content.classification"></label>
<label [translate]="'change-legal-basis-dialog.content.classification'"></label>
<input formControlName="classification" name="classification" type="text" />
</div>
<div class="iqser-input-group w-300">
<label translate="change-legal-basis-dialog.content.comment"></label>
<label [translate]="'change-legal-basis-dialog.content.comment'"></label>
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
</div>
</div>

View File

@ -1,5 +1,5 @@
<section *ngIf="!!form" class="dialog">
<div class="dialog-header heading-l" translate="document-info.title"></div>
<div class="dialog-header heading-l" [translate]="'document-info.title'"></div>
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">

View File

@ -1,6 +1,6 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-header heading-l" translate="false-positive-dialog.header"></div>
<div class="dialog-header heading-l" [translate]="'false-positive-dialog.header'"></div>
<div class="dialog-content">
<ul>
@ -10,7 +10,7 @@
></li>
</ul>
<div class="iqser-input-group w-300">
<label translate="false-positive-dialog.content.comment"></label>
<label [translate]="'false-positive-dialog.content.comment'"></label>
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
</div>
</div>

View File

@ -1,11 +1,11 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="form">
<div *ngIf="!isHintDialog" class="dialog-header heading-l" translate="manual-annotation.dialog.header.force-redaction"></div>
<div *ngIf="isHintDialog" class="dialog-header heading-l" translate="manual-annotation.dialog.header.force-hint"></div>
<div *ngIf="!isHintDialog" class="dialog-header heading-l" [translate]="'manual-annotation.dialog.header.force-redaction'"></div>
<div *ngIf="isHintDialog" class="dialog-header heading-l" [translate]="'manual-annotation.dialog.header.force-hint'"></div>
<div class="dialog-content">
<div *ngIf="!isHintDialog" class="iqser-input-group required w-400">
<label translate="manual-annotation.dialog.content.reason"></label>
<label [translate]="'manual-annotation.dialog.content.reason'"></label>
<mat-form-field>
<mat-select
[placeholder]="'manual-annotation.dialog.content.reason-placeholder' | translate"
@ -20,12 +20,12 @@
</div>
<div *ngIf="!isHintDialog" class="iqser-input-group w-400">
<label translate="manual-annotation.dialog.content.legalBasis"></label>
<label [translate]="'manual-annotation.dialog.content.legalBasis'"></label>
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
</div>
<div class="iqser-input-group w-300">
<label translate="manual-annotation.dialog.content.comment"></label>
<label [translate]="'manual-annotation.dialog.content.comment'"></label>
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4"></textarea>
</div>
</div>

View File

@ -1,8 +1,8 @@
<section class="dialog">
<div class="dialog-header heading-l" translate="import-redactions-dialog.title"></div>
<div class="dialog-header heading-l" [translate]="'import-redactions-dialog.title'"></div>
<div class="dialog-content">
<div class="mb-24" translate="import-redactions-dialog.details"></div>
<div class="mb-24" [translate]="'import-redactions-dialog.details'"></div>
<iqser-upload-file (fileChanged)="fileChanged($event)"></iqser-upload-file>
<div class="only-for-pages">
@ -29,7 +29,7 @@
[type]="iconButtonTypes.primary"
></iqser-icon-button>
<div class="all-caps-label cancel" mat-dialog-close translate="import-redactions-dialog.actions.cancel"></div>
<div class="all-caps-label cancel" mat-dialog-close [translate]="'import-redactions-dialog.actions.cancel'"></div>
</div>
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>

View File

@ -4,7 +4,7 @@
<div class="dialog-content">
<div *ngIf="!isRectangle" class="iqser-input-group w-450">
<label translate="manual-annotation.dialog.content.text"></label>
<label [translate]="'manual-annotation.dialog.content.text'"></label>
<div *ngIf="!isEditingSelectedText" class="flex-align-items-center">
{{ form.get('selectedText').value }}
<iqser-circle-button
@ -28,15 +28,15 @@
</div>
<div *ngIf="isRectangle" class="iqser-input-group">
<label translate="manual-annotation.dialog.content.rectangle"></label>
<label [translate]="'manual-annotation.dialog.content.rectangle'"></label>
</div>
<div
*ngIf="!isFalsePositiveRequest && (isDictionaryRequest || !manualRedactionTypeExists)"
class="iqser-input-group required w-450"
>
<label *ngIf="isDictionaryRequest" translate="manual-annotation.dialog.content.dictionary"></label>
<label *ngIf="!isDictionaryRequest" translate="manual-annotation.dialog.content.type"></label>
<label *ngIf="isDictionaryRequest" [translate]="'manual-annotation.dialog.content.dictionary'"></label>
<label *ngIf="!isDictionaryRequest" [translate]="'manual-annotation.dialog.content.type'"></label>
<mat-form-field>
<mat-select formControlName="dictionary">
@ -54,7 +54,7 @@
</div>
<div *deny="roles.getRss; if: !isDictionaryRequest" class="iqser-input-group required w-450">
<label translate="manual-annotation.dialog.content.reason"></label>
<label [translate]="'manual-annotation.dialog.content.reason'"></label>
<mat-form-field>
<mat-select
[placeholder]="'manual-annotation.dialog.content.reason-placeholder' | translate"
@ -74,22 +74,22 @@
</div>
<div *deny="roles.getRss; if: !isDictionaryRequest" class="iqser-input-group w-450">
<label translate="manual-annotation.dialog.content.legalBasis"></label>
<label [translate]="'manual-annotation.dialog.content.legalBasis'"></label>
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
</div>
<div *ngIf="isRectangle" class="iqser-input-group w-450">
<label translate="manual-annotation.dialog.content.section"></label>
<label [translate]="'manual-annotation.dialog.content.section'"></label>
<input formControlName="section" name="section" type="text" />
</div>
<div *ngIf="isRectangle" class="iqser-input-group w-450">
<label translate="manual-annotation.dialog.content.classification"></label>
<label [translate]="'manual-annotation.dialog.content.classification'"></label>
<input formControlName="classification" name="classification" type="text" />
</div>
<div class="iqser-input-group w-450">
<label translate="manual-annotation.dialog.content.comment"></label>
<label [translate]="'manual-annotation.dialog.content.comment'"></label>
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
</div>

View File

@ -1,10 +1,10 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-header heading-l" translate="recategorize-image-dialog.header"></div>
<div class="dialog-header heading-l" [translate]="'recategorize-image-dialog.header'"></div>
<div class="dialog-content">
<div class="iqser-input-group required w-400">
<label translate="recategorize-image-dialog.content.type"></label>
<label [translate]="'recategorize-image-dialog.content.type'"></label>
<mat-form-field>
<mat-select
[placeholder]="'recategorize-image-dialog.content.type-placeholder' | translate"
@ -19,7 +19,7 @@
</div>
<div class="iqser-input-group w-300">
<label translate="recategorize-image-dialog.content.comment"></label>
<label [translate]="'recategorize-image-dialog.content.comment'"></label>
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
</div>
</div>
@ -32,7 +32,7 @@
[type]="iconButtonTypes.primary"
></iqser-icon-button>
<div class="all-caps-label cancel" mat-dialog-close translate="recategorize-image-dialog.actions.cancel"></div>
<div class="all-caps-label cancel" mat-dialog-close [translate]="'recategorize-image-dialog.actions.cancel'"></div>
</div>
</form>

View File

@ -1,21 +1,23 @@
<section class="dialog">
<div class="dialog-header heading-l">
{{
<div
class="dialog-header heading-l"
[innerHTML]="
(data.removeFromDictionary
? 'remove-annotations-dialog.remove-from-dictionary.title'
: 'remove-annotations-dialog.remove-only-here.title'
) | translate : { hint: data.hint }
}}
</div>
"
></div>
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">
{{
<div
class="dialog-content"
[innerHTML]="
(data.removeFromDictionary
? 'remove-annotations-dialog.remove-from-dictionary.question'
: 'remove-annotations-dialog.remove-only-here.question'
) | translate : { hint: data.hint }
}}
"
>
<div *ngIf="data.removeFromDictionary" class="content-wrapper">
<table class="default-table">
<thead>
@ -40,7 +42,7 @@
</ul>
<div class="iqser-input-group w-300">
<label translate="manual-annotation.dialog.content.comment"></label>
<label [translate]="'manual-annotation.dialog.content.comment'"></label>
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
</div>
</div>
@ -53,7 +55,7 @@
[type]="iconButtonTypes.primary"
></iqser-icon-button>
<div class="all-caps-label cancel" mat-dialog-close translate="remove-annotations-dialog.cancel"></div>
<div class="all-caps-label cancel" mat-dialog-close [translate]="'remove-annotations-dialog.cancel'"></div>
</div>
</form>

View File

@ -1,10 +1,10 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-header heading-l" translate="resize-annotation-dialog.header"></div>
<div class="dialog-header heading-l" [translate]="'resize-annotation-dialog.header'"></div>
<div class="dialog-content">
<div class="iqser-input-group w-300">
<label translate="resize-annotation-dialog.content.comment"></label>
<label [translate]="'resize-annotation-dialog.content.comment'"></label>
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
</div>
@ -26,7 +26,7 @@
[type]="iconButtonTypes.primary"
></iqser-icon-button>
<div class="all-caps-label cancel" mat-dialog-close translate="resize-annotation-dialog.actions.cancel"></div>
<div class="all-caps-label cancel" mat-dialog-close [translate]="'resize-annotation-dialog.actions.cancel'"></div>
</div>
</form>

View File

@ -1,5 +1,5 @@
<section class="dialog">
<div class="dialog-header heading-l" translate="rss-dialog.title"></div>
<div class="dialog-header heading-l" [translate]="'rss-dialog.title'"></div>
<hr />
<div class="dialog-content">
@ -79,7 +79,7 @@
label="Export All"
></iqser-icon-button>
<div class="all-caps-label cancel" mat-dialog-close translate="rss-dialog.actions.close"></div>
<div class="all-caps-label cancel" mat-dialog-close [translate]="'rss-dialog.actions.close'"></div>
</div>
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>

View File

@ -215,7 +215,8 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
}
return filtered;
}, []);
this._suggestionsService.removedRedactions = await this.#buildAnnotations(redactionLogCopy, file);
const annotations = await this.#buildAnnotations(redactionLogCopy, file);
this._suggestionsService.removedRedactions = annotations.filter(a => !a.isSkipped);
}
}

View File

@ -24,39 +24,43 @@ export class SuggestionsService {
}
hideSuggestionsInPreview(annotations: Annotation[]): void {
if (!this._userPreferenceService.getDisplaySuggestionsInPreview()) {
const suggestions = annotations.filter(a => bool(a.getCustomData('suggestion')));
this._annotationManager.hide(suggestions);
this.#convertSuggestionsToRedactions(suggestions);
if (this._readableRedactionsService.active) {
if (this._userPreferenceService.getDisplaySuggestionsInPreview()) {
const suggestionsRemove = annotations.filter(a => bool(a.getCustomData('suggestionRemove')));
this._annotationManager.hide(suggestionsRemove);
return;
}
}
const suggestionsToHide = annotations.filter(
a => bool(a.getCustomData('suggestionAdd')) && !bool(a.getCustomData('suggestionAddToFalsePositive')),
);
annotations.forEach(a => {
if (bool(a.getCustomData('suggestionRemove'))) {
const foundRedaction = this.#removedRedactions.find(r => r.id === a.Id);
if (!foundRedaction) {
suggestionsToHide.push(a);
}
}
});
this._annotationManager.hide(suggestionsToHide);
}
convertWorkloadRemoveSuggestionsToRedactions(annotations: AnnotationWrapper[]): AnnotationWrapper[] {
if (!this._userPreferenceService.getDisplaySuggestionsInPreview()) {
annotations = annotations.filter(a => !a.isSuggestion);
annotations = [...annotations, ...this.#removedRedactions];
filterWorkloadSuggestionsInPreview(annotations: AnnotationWrapper[]): AnnotationWrapper[] {
if (this._readableRedactionsService.active) {
if (this._userPreferenceService.getDisplaySuggestionsInPreview()) {
return annotations.filter(a => !a.isSuggestionRemove);
}
}
annotations = annotations.filter(a => !a.isSuggestionAdd || a.isSuggestionAddToFalsePositive);
for (let i = annotations.length - 1; i >= 0; i--) {
const foundRemovedRedaction = this.#removedRedactions.find(r => r.id === annotations[i].id);
if (foundRemovedRedaction) {
annotations[i] = foundRemovedRedaction;
} else if (annotations[i].isSuggestionRemove) {
annotations.splice(i, 1);
}
}
return annotations;
}
#convertSuggestionsToRedactions(suggestions: Annotation[]): void {
suggestions = this.#filterSuggestions(suggestions);
suggestions.forEach(s => s.setCustomData('suggestion', 'false'));
this._readableRedactionsService.setAnnotationsColor(suggestions, 'redactionColor');
this._readableRedactionsService.setAnnotationsOpacity(suggestions);
this._annotationManager.show(suggestions);
}
#filterSuggestions(suggestions: Annotation[]): Annotation[] {
const filteredSuggestions = [];
this.#removedRedactions.forEach(r => {
const found = suggestions.find(s => s.Id === r.annotationId);
if (found) {
filteredSuggestions.push(found);
}
});
return filteredSuggestions;
}
}

View File

@ -156,6 +156,8 @@ export class AnnotationDrawService {
annotation.setCustomData('redact-manager', 'true');
annotation.setCustomData('redaction', String(annotationWrapper.previewAnnotation));
annotation.setCustomData('suggestion', String(annotationWrapper.isSuggestion));
annotation.setCustomData('suggestionAdd', String(annotationWrapper.isSuggestionAdd));
annotation.setCustomData('suggestionAddToFalsePositive', String(annotationWrapper.isSuggestionAddToFalsePositive));
annotation.setCustomData('suggestionRemove', String(annotationWrapper.isSuggestionRemove));
annotation.setCustomData('skipped', String(annotationWrapper.isSkipped));
annotation.setCustomData('changeLog', String(annotationWrapper.isChangeLogEntry));

View File

@ -52,27 +52,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
{ label: _('search-screen.cols.pages'), width: 'auto' },
];
readonly searchResults$ = combineLatest([this._queryChanged, this._filtersChanged$]).pipe(
tap(() => this._loadingService.start()),
tap(([query, [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]]) =>
this._updateNavigation(query, dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive),
),
switchMap(([query, [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]]) =>
this._platformSearchService.search({
query,
dossierIds,
dossierTemplateIds,
workflowStatus,
assignee,
includeDeletedDossiers: false,
includeArchivedDossiers: !onlyActive,
}),
),
map(searchResult => this._toMatchedDocuments(searchResult)),
map(docs => this._toListItems(docs)),
tap(result => this.entitiesService.setEntities(result)),
tap(() => this._loadingService.stop()),
);
readonly searchResults$ = new Observable<ISearchListItem[]>();
readonly dossierTemplates$ = this._dossierTemplateService.loadAll().pipe(tap(templates => this._addTemplateFilter(templates)));
@ -90,6 +70,30 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
private readonly _userService: UserService,
) {
super();
if (!Object.keys(this._activatedRoute.snapshot.queryParams).length) {
this._router.navigate(['main']).then();
}
this.searchResults$ = combineLatest([this._queryChanged$, this._filtersChanged$]).pipe(
tap(() => this._loadingService.start()),
tap(([query, [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]]) =>
this._updateNavigation(query, dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive),
),
switchMap(([query, [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]]) =>
this._platformSearchService.search({
query,
dossierIds,
dossierTemplateIds,
workflowStatus,
assignee,
includeDeletedDossiers: false,
includeArchivedDossiers: !onlyActive,
}),
),
map(searchResult => this._toMatchedDocuments(searchResult)),
map(docs => this._toListItems(docs)),
tap(result => this.entitiesService.setEntities(result)),
tap(() => this._loadingService.stop()),
);
this.searchService.skip = true;
this.sortingService.setSortingOption({ column: 'searchKey', order: SortingOrders.desc });
this._initFilters();
@ -119,7 +123,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
return this._activatedRoute.snapshot.queryParamMap.get('query');
}
private get _queryChanged(): Observable<string> {
private get _queryChanged$(): Observable<string> {
return this.searchService.valueChanges$.pipe(
startWith(this._routeQuery),
tap(query => (this.searchService.searchValue = query)),

View File

@ -1,5 +1,5 @@
<section class="dialog">
<div [translateParams]="{ type: mode }" [translate]="'assign-owner.dialog.title'" class="dialog-header heading-l"></div>
<div [innerHTML]="'assign-owner.dialog.title' | translate : { type: mode }" class="dialog-header heading-l"></div>
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">

View File

@ -355,6 +355,10 @@
"elementKey": "dictionary_entity",
"documentKey": "dictionary_entity"
},
{
"elementKey": "recommendation",
"documentKey": "recommendation"
},
{
"elementKey": "false_recommendations_entity",
"documentKey": "false_recommendations_entity"

View File

@ -1,6 +1,6 @@
{
"name": "redaction",
"version": "4.72.0",
"version": "4.78.0",
"private": true,
"license": "MIT",
"scripts": {

Binary file not shown.