-
+
{{ entry.key }}
@@ -65,12 +67,14 @@
[label]="'rss-dialog.actions.export-json' | translate"
[submit]="true"
[type]="iconButtonTypes.primary"
+ [attr.help-mode-key]="'scm_export_DIALOG'"
>
@@ -73,6 +75,7 @@
[tooltip]="'common.close' | translate"
class="ml-8"
icon="iqser:close"
+ [attr.help-mode-key]="'editor_close'"
>
diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts
index 7b93ef488..cf56904e0 100644
--- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts
+++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts
@@ -338,6 +338,7 @@ export class FilePreviewScreenComponent
document.documentElement.addEventListener('fullscreenchange', this.fullscreenListener);
this.#openRssDialogIfDefault();
+ this._viewerHeaderService.resetLayers();
}
ngAfterViewInit() {
diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview.module.ts b/apps/red-ui/src/app/modules/file-preview/file-preview.module.ts
index 2dd50f057..d5201841e 100644
--- a/apps/red-ui/src/app/modules/file-preview/file-preview.module.ts
+++ b/apps/red-ui/src/app/modules/file-preview/file-preview.module.ts
@@ -71,6 +71,7 @@ import { DocumentUnloadedGuard } from './services/document-unloaded.guard';
import { FilePreviewDialogService } from './services/file-preview-dialog.service';
import { ManualRedactionService } from './services/manual-redaction.service';
import { TablesService } from './services/tables.service';
+import { ReplaceNbspPipe } from '@common-ui/pipes/replace-nbsp.pipe';
const routes: IqserRoutes = [
{
@@ -154,6 +155,7 @@ const components = [
IqserDenyDirective,
TenantPipe,
LogPipe,
+ ReplaceNbspPipe,
],
providers: [FilePreviewDialogService, ManualRedactionService, DocumentUnloadedGuard, TablesService],
})
diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts
index 8579ae9eb..b7cb9210f 100644
--- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts
+++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts
@@ -113,10 +113,10 @@ export class AnnotationActionsService {
}));
requests.push(this._manualRedactionService.changeLegalBasis(changeLegalBasisBody, dossierId, fileId));
}
- if (result.type !== annotations[0].type || this.#isDocumine) {
- const recategorizeBody: List
= annotations.map(({ id }) => ({
- annotationId: id,
- type: result.type,
+ if (this.#isDocumine) {
+ const recategorizeBody: List = annotations.map(annotation => ({
+ annotationId: annotation.id,
+ type: result.type ?? annotation.type,
}));
requests.push(this._manualRedactionService.recategorizeRedactions(recategorizeBody, dossierId, fileId));
}
@@ -134,7 +134,7 @@ export class AnnotationActionsService {
await this.#processObsAndEmit(zip(requests).pipe(log()));
}
- async removeRedaction(redaction: AnnotationWrapper, permissions: AnnotationPermissions) {
+ async removeRedaction(redactions: AnnotationWrapper[], permissions: AnnotationPermissions) {
const removePermissions: RemoveRedactionPermissions = {
canRemoveOnlyHere: permissions.canRemoveOnlyHere,
canRemoveFromDictionary: permissions.canRemoveFromDictionary,
@@ -144,9 +144,9 @@ export class AnnotationActionsService {
const isApprover = this._permissionsService.isApprover(this._state.dossier());
const data = {
- redaction,
+ redactions,
dossier: this._state.dossier(),
- falsePositiveContext: this.#getFalsePositiveText(redaction),
+ falsePositiveContext: redactions.map(r => this.#getFalsePositiveText(r)),
permissions: removePermissions,
applyToAllDossiers: isApprover ? dossierTemplate.applyDictionaryUpdatesToAllDossiersByDefault : false,
isApprover,
@@ -162,9 +162,9 @@ export class AnnotationActionsService {
result.option.value === RemoveRedactionOptions.FALSE_POSITIVE ||
result.option.value === RemoveRedactionOptions.DO_NOT_RECOMMEND
) {
- this.#setAsFalsePositive(redaction, result);
+ this.#setAsFalsePositive(redactions, result);
} else {
- this.#removeRedaction(redaction, result);
+ this.#removeRedaction(redactions, result);
}
}
@@ -393,8 +393,8 @@ export class AnnotationActionsService {
return words;
}
- #setAsFalsePositive(redaction: AnnotationWrapper, dialogResult: RemoveRedactionResult) {
- const request = {
+ #setAsFalsePositive(redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult) {
+ const requests = redactions.map(redaction => ({
sourceId: redaction.id,
value: this.#getFalsePositiveText(redaction),
type: redaction.type,
@@ -406,24 +406,24 @@ export class AnnotationActionsService {
? DictionaryEntryTypes.FALSE_RECOMMENDATION
: DictionaryEntryTypes.FALSE_POSITIVE,
comment: dialogResult.comment ? { text: dialogResult.comment } : null,
- };
+ }));
const { dossierId, fileId } = this._state;
- this.#processObsAndEmit(this._manualRedactionService.addAnnotation([request], dossierId, fileId)).then();
+ this.#processObsAndEmit(this._manualRedactionService.addAnnotation(requests, dossierId, fileId)).then();
}
- #removeRedaction(redaction: AnnotationWrapper, dialogResult: RemoveRedactionResult) {
+ #removeRedaction(redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult) {
const removeFromDictionary = dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER;
- const body = {
+ const body = redactions.map(redaction => ({
annotationId: redaction.id,
comment: dialogResult.comment,
removeFromDictionary,
removeFromAllDossiers: !!dialogResult.option.extraOption?.checked || !!dialogResult.applyToAllDossiers,
- };
+ }));
+ // todo: might not be correct, probably shouldn't get to this point if they are not all the same
+ const isHint = redactions.every(r => r.isHint);
const { dossierId, fileId } = this._state;
- this.#processObsAndEmit(
- this._manualRedactionService.removeRedaction([body], dossierId, fileId, removeFromDictionary, redaction.isHint),
- ).then();
+ this.#processObsAndEmit(this._manualRedactionService.removeRedaction(body, dossierId, fileId, removeFromDictionary, isHint)).then();
}
#getRemoveRedactionDialog(data: RemoveRedactionData) {
diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts
index 520e9eb3a..e365144d7 100644
--- a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts
+++ b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts
@@ -1,7 +1,7 @@
import { effect, Injectable, Signal, signal } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
-import { EntitiesService, Toaster } from '@iqser/common-ui';
+import { EntitiesService, getConfig, Toaster } from '@iqser/common-ui';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import {
ChangeType,
@@ -50,6 +50,7 @@ export class FileDataService extends EntitiesService>;
readonly annotations: Signal;
readonly annotations$: Observable;
+ readonly #isDocumine = getConfig().IS_DOCUMINE;
constructor(
private readonly _state: FilePreviewStateService,
@@ -220,6 +221,7 @@ export class FileDataService extends EntitiesService 1 ? permissions.canEditAnnotations : canEditRedactions;
+ if (canEdit) {
const editButton = this.#getButton('edit', _('annotation-actions.edit-redaction.label'), () =>
this.#annotationActionsService.editRedaction(annotations),
);
@@ -83,7 +84,7 @@ export class PdfAnnotationActionsService {
if (permissions.canRemoveRedaction) {
const removeRedactionButton = this.#getButton('trash', _('annotation-actions.remove-annotation.remove-redaction'), () =>
- this.#annotationActionsService.removeRedaction(annotations[0], permissions),
+ this.#annotationActionsService.removeRedaction(annotations, permissions),
);
availableActions.push(removeRedactionButton);
}
diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts
index cf41c03c1..9befd59e2 100644
--- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts
+++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts
@@ -149,15 +149,16 @@ export const getRemoveRedactionOptions = (
isDocumine: boolean = false,
): DetailsRadioOption[] => {
const translations = isDocumine ? removeAnnotationTranslations : removeRedactionTranslations;
- const { permissions, redaction, applyToAllDossiers, isApprover, falsePositiveContext } = data;
+ const { permissions, redactions, applyToAllDossiers, isApprover, falsePositiveContext } = data;
+ const isBulk = redactions.length > 1;
const options: DetailsRadioOption[] = [];
if (permissions.canRemoveOnlyHere) {
options.push({
label: translations.ONLY_HERE.label,
- description: translations.ONLY_HERE.description,
+ description: isBulk ? translations.ONLY_HERE.descriptionBulk : translations.ONLY_HERE.description,
descriptionParams: {
- value: redaction.value,
+ value: redactions[0].value,
},
icon: PIN_ICON,
value: RemoveRedactionOptions.ONLY_HERE,
@@ -165,9 +166,9 @@ export const getRemoveRedactionOptions = (
}
if (permissions.canRemoveFromDictionary) {
options.push({
- label: translations.IN_DOSSIER.label,
- description: translations.IN_DOSSIER.description,
- descriptionParams: { value: redaction.value, type: redaction.type },
+ label: isBulk ? translations.IN_DOSSIER.labelBulk : translations.IN_DOSSIER.label,
+ description: isBulk ? translations.IN_DOSSIER.descriptionBulk : translations.IN_DOSSIER.description,
+ descriptionParams: { value: redactions[0].value, type: redactions[0].type },
icon: FOLDER_ICON,
value: RemoveRedactionOptions.IN_DOSSIER,
extraOption: !isDocumine
@@ -180,11 +181,15 @@ export const getRemoveRedactionOptions = (
});
}
if (permissions.canMarkAsFalsePositive) {
- if (data.redaction.isRecommendation) {
+ if (data.redactions[0].isRecommendation) {
options.push({
label: translations.DO_NOT_RECOMMEND.label,
- description: translations.DO_NOT_RECOMMEND.description,
- descriptionParams: { value: redaction.value, type: redaction.type, context: falsePositiveContext },
+ description: isBulk ? translations.DO_NOT_RECOMMEND.descriptionBulk : translations.DO_NOT_RECOMMEND.description,
+ descriptionParams: {
+ value: redactions[0].value,
+ type: redactions[0].type,
+ context: falsePositiveContext[0],
+ },
icon: FOLDER_ICON,
value: RemoveRedactionOptions.DO_NOT_RECOMMEND,
extraOption: !isDocumine
@@ -198,8 +203,12 @@ export const getRemoveRedactionOptions = (
} else {
options.push({
label: translations.FALSE_POSITIVE.label,
- description: translations.FALSE_POSITIVE.description,
- descriptionParams: { value: redaction.value, type: redaction.type, context: falsePositiveContext },
+ description: isBulk ? translations.FALSE_POSITIVE.descriptionBulk : translations.FALSE_POSITIVE.description,
+ descriptionParams: {
+ value: redactions[0].value,
+ type: redactions[0].type,
+ context: falsePositiveContext[0],
+ },
icon: REMOVE_FROM_DICT_ICON,
value: RemoveRedactionOptions.FALSE_POSITIVE,
extraOption: !isDocumine
diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts
index 11d89beee..000c448dc 100644
--- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts
+++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts
@@ -71,9 +71,9 @@ export interface RemoveRedactionPermissions {
}
export interface RemoveRedactionData {
- redaction: AnnotationWrapper;
+ redactions: AnnotationWrapper[];
dossier: Dossier;
- falsePositiveContext: string;
+ falsePositiveContext: string[];
permissions: RemoveRedactionPermissions;
applyToAllDossiers: boolean;
isApprover: boolean;
diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/layers.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/layers.service.ts
index 18e2f0019..98ec02af1 100644
--- a/apps/red-ui/src/app/modules/pdf-viewer/services/layers.service.ts
+++ b/apps/red-ui/src/app/modules/pdf-viewer/services/layers.service.ts
@@ -33,6 +33,11 @@ export class LayersService {
return tooltipsDisabled ? this.#enableIcon : this.#disableIcon;
}
+ resetLayers() {
+ this._active = false;
+ this.#updateButton();
+ }
+
async toggleLayers(): Promise {
const layers = await this._documentViewer.document.getLayersArray();
layers.forEach(layer => {
@@ -45,6 +50,10 @@ export class LayersService {
this._documentViewer.refreshAndUpdateView();
this._active = !this._active;
+ this.#updateButton();
+ }
+
+ #updateButton() {
this._pdf.instance.UI.updateElement(HeaderElements.TOGGLE_LAYERS, {
title: this.toggleLayersBtnTitle,
img: this.toggleLayersBtnIcon,
diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts
index 53d356531..967a125c3 100644
--- a/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts
+++ b/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts
@@ -1,11 +1,11 @@
import { inject, Injectable, NgZone } from '@angular/core';
-import { getConfig, IqserPermissionsService, isIqserDevMode } from '@iqser/common-ui';
+import { getConfig, HelpModeService, IqserPermissionsService, isIqserDevMode } from '@iqser/common-ui';
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
import { TranslateService } from '@ngx-translate/core';
import { IHeaderElement, RotationTypes } from '@red/domain';
import { FilesMapService } from '@services/files/files-map.service';
import { Roles } from '@users/roles';
-import { fromEvent, Observable, Subject } from 'rxjs';
+import { fromEvent, merge, Observable, Subject } from 'rxjs';
import { filter, map, tap } from 'rxjs/operators';
import { HeaderElements, HeaderElementType } from '../../file-preview/utils/constants';
import { ROTATION_ACTION_BUTTONS, ROTATION_BUTTONS, ViewerEvents } from '../utils/constants';
@@ -56,6 +56,7 @@ export class ViewerHeaderService {
private readonly _layersService: LayersService,
private readonly _readableRedactionsService: ReadableRedactionsService,
private readonly _ngZone: NgZone,
+ private readonly _helpModeService: HelpModeService,
) {
this.events$ = this.#events$.asObservable();
}
@@ -224,9 +225,9 @@ export class ViewerHeaderService {
}
get #toggleLoadAnnotations$() {
- return this.expandedPanelEvent$.pipe(
- tap(isVisible =>
- isVisible ? this.enable([HeaderElements.LOAD_ALL_ANNOTATIONS]) : this.disable([HeaderElements.LOAD_ALL_ANNOTATIONS]),
+ return merge(this.expandedPanelEvent$, this._helpModeService.isHelpModeActive$).pipe(
+ tap(enable =>
+ enable ? this.enable([HeaderElements.LOAD_ALL_ANNOTATIONS]) : this.disable([HeaderElements.LOAD_ALL_ANNOTATIONS]),
),
);
}
@@ -376,4 +377,8 @@ export class ViewerHeaderService {
this.disable(ROTATION_ACTION_BUTTONS);
}
}
+
+ resetLayers() {
+ this._layersService.resetLayers();
+ }
}
diff --git a/apps/red-ui/src/app/modules/shared-dossiers/components/dossiers-listing-actions/dossiers-listing-actions.component.html b/apps/red-ui/src/app/modules/shared-dossiers/components/dossiers-listing-actions/dossiers-listing-actions.component.html
index 7ca821014..47276c23b 100644
--- a/apps/red-ui/src/app/modules/shared-dossiers/components/dossiers-listing-actions/dossiers-listing-actions.component.html
+++ b/apps/red-ui/src/app/modules/shared-dossiers/components/dossiers-listing-actions/dossiers-listing-actions.component.html
@@ -2,7 +2,7 @@
-
+
diff --git a/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts
index 9ddd0cbd2..435ad2955 100644
--- a/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts
+++ b/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts
@@ -41,7 +41,7 @@ export class FileActionsComponent implements OnChanges {
@Input({ required: true }) type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow';
@Input() maxWidth: number;
@Input() minWidth: number;
- @Input() fileActionsHelpModeKey: 'document_features_in_dossier' | 'editor_document_features' = 'document_features_in_dossier';
+ @Input() helpModeKeyPrefix: 'dossier' | 'editor' = 'dossier';
readonly currentUser = getCurrentUser
();
toggleTooltip?: string;
assignTooltip?: string;
@@ -112,6 +112,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: _('dossier-overview.delete.action'),
icon: 'iqser:trash',
show: this.showDelete,
+ helpModeKey: 'delete_file',
},
{
id: 'assign-btn',
@@ -120,6 +121,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: this.assignTooltip,
icon: 'red:assign',
show: this.showAssign,
+ helpModeKey: 'assign_user',
},
{
id: 'assign-to-me-btn',
@@ -128,6 +130,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: _('dossier-overview.assign-me'),
icon: 'red:assign-me',
show: this.showAssignToSelf,
+ helpModeKey: 'assign_user',
},
{
id: 'open-import-redactions-dialog-btn',
@@ -145,6 +148,7 @@ export class FileActionsComponent implements OnChanges {
tooltipClass: 'small',
show: this._permissionsService.canDownloadRedactedFile() && !!this.file.lastProcessed,
disabled: this.file.processingStatus === ProcessingFileStatuses.ERROR,
+ helpModeKey: 'download',
},
{
id: 'toggle-document-info-btn',
@@ -154,6 +158,7 @@ export class FileActionsComponent implements OnChanges {
ariaExpanded: toObservable(this._documentInfoService?.shown, { injector: this._injector }),
icon: 'red:status-info',
show: !!this._documentInfoService,
+ helpModeKey: 'document_info',
},
{
id: 'toggle-exclude-pages-btn',
@@ -172,6 +177,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: _('dossier-overview.back-to-new'),
icon: 'red:undo',
show: this.showSetToNew,
+ helpModeKey: 'change_status',
},
{
id: 'set-file-under-approval-btn',
@@ -180,6 +186,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: _('dossier-overview.under-approval'),
icon: 'red:ready-for-approval',
show: this.showUnderApproval,
+ helpModeKey: 'change_status',
},
{
id: 'set-file-under-review-btn',
@@ -188,6 +195,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: _('dossier-overview.under-review'),
icon: 'red:undo',
show: this.showUnderReview,
+ helpModeKey: 'change_status',
},
{
id: 'set-file-approved-btn',
@@ -197,6 +205,7 @@ export class FileActionsComponent implements OnChanges {
icon: 'red:approved',
disabled: !this.file.canBeApproved,
show: this.showApprove,
+ helpModeKey: 'change_status',
},
{
id: 'toggle-automatic-analysis-btn',
@@ -205,6 +214,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: _('dossier-overview.stop-auto-analysis'),
icon: 'red:disable-analysis',
show: this.canDisableAutoAnalysis,
+ helpModeKey: 'stop_analysis',
},
{
id: 'reanalyse-file-preview-btn',
@@ -215,6 +225,7 @@ export class FileActionsComponent implements OnChanges {
icon: 'iqser:refresh',
show: this.showReanalyseFilePreview,
disabled: this.file.isProcessing,
+ helpModeKey: 'stop_analysis',
},
{
id: 'toggle-automatic-analysis-btn',
@@ -224,6 +235,7 @@ export class FileActionsComponent implements OnChanges {
buttonType: this.isFilePreview ? CircleButtonTypes.warn : CircleButtonTypes.default,
icon: 'red:enable-analysis',
show: this.canEnableAutoAnalysis,
+ helpModeKey: 'stop_analysis',
},
{
id: 'set-under-approval-btn',
@@ -232,6 +244,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: _('dossier-overview.under-approval'),
icon: 'red:undo',
show: this.showUndoApproval,
+ helpModeKey: 'change_status',
},
{
id: 'ocr-file-btn',
@@ -248,6 +261,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: _('dossier-overview.reanalyse.action'),
icon: 'iqser:refresh',
show: this.showReanalyseDossierOverview,
+ helpModeKey: 'stop_analysis',
},
{
id: 'toggle-analysis-btn',
@@ -258,6 +272,7 @@ export class FileActionsComponent implements OnChanges {
class: { 'mr-24': this.isDossierOverviewList },
checked: !this.file.excluded,
show: this.showToggleAnalysis,
+ helpModeKey: 'disable_extraction',
},
];
diff --git a/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.html b/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.html
index 47b264762..e261eb0a3 100644
--- a/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.html
+++ b/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.html
@@ -2,7 +2,7 @@