From d6f612356788d34cc04c24ffec80974e4d50db72 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Fri, 21 Jul 2023 15:38:45 +0300 Subject: [PATCH] DM-337 - WIP on Add/Remove annotations dialog in DocuMine --- .../add-annotation-dialog.component.html | 56 +++++++++ .../add-annotation-dialog.component.scss | 0 .../add-annotation-dialog.component.ts | 116 ++++++++++++++++++ .../remove-annotation-dialog.component.html | 34 +++++ .../remove-annotation-dialog.component.scss | 0 .../remove-annotation-dialog.component.ts | 99 +++++++++++++++ .../remove-annotation-options.ts | 7 ++ .../redact-text-dialog.component.ts | 4 +- .../remove-redaction-dialog.component.ts | 3 +- .../file-preview-screen.component.ts | 46 ++++--- .../file-preview/file-preview.module.ts | 4 + .../services/pdf-proxy.service.ts | 21 ++-- .../entity-services/dictionary.service.ts | 10 +- .../remove-annotation-translations.ts | 22 ++++ apps/red-ui/src/assets/config/config.json | 6 +- apps/red-ui/src/assets/i18n/redact/de.json | 43 +++++++ apps/red-ui/src/assets/i18n/redact/en.json | 43 +++++++ apps/red-ui/src/assets/i18n/scm/de.json | 43 +++++++ apps/red-ui/src/assets/i18n/scm/en.json | 43 +++++++ 19 files changed, 564 insertions(+), 36 deletions(-) create mode 100644 apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.html create mode 100644 apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.scss create mode 100644 apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.ts create mode 100644 apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.html create mode 100644 apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.scss create mode 100644 apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts create mode 100644 apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-options.ts create mode 100644 apps/red-ui/src/app/translations/remove-annotation-translations.ts diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.html new file mode 100644 index 000000000..e08222606 --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.html @@ -0,0 +1,56 @@ +
+
+
+ +
+
+ + {{ form.get('selectedText').value }} +
+ +
+ + + + + {{ displayedDictionaryLabel }} + + {{ dictionary.label }} + + + +
+ +
+ + +
+
+ +
+ + + +
+
+
+ + +
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.scss b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.ts new file mode 100644 index 000000000..1d840f854 --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component.ts @@ -0,0 +1,116 @@ +import { Component, OnInit } from '@angular/core'; +import { IconButtonTypes, IqserPermissionsService } from '@iqser/common-ui'; +import { Dictionary, Dossier, File, IAddRedactionRequest, IManualRedactionEntry, SuperTypes } from '@red/domain'; +import { FormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Roles } from '@users/roles'; +import { JustificationsService } from '@services/entity-services/justifications.service'; +import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; +import { DictionaryService } from '@services/entity-services/dictionary.service'; + +import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; +import { IqserDialogComponent } from '@iqser/common-ui'; + +export interface AddAnnotationData { + manualRedactionEntryWrapper: ManualRedactionEntryWrapper; + dossierId: string; + file: File; +} + +interface DialogResult { + redaction: IManualRedactionEntry; + dictionary: Dictionary; + applyToAllDossiers: boolean | null; +} + +@Component({ + templateUrl: './add-annotation-dialog.component.html', + styleUrls: ['./add-annotation-dialog.component.scss'], +}) +export class AddAnnotationDialogComponent + extends IqserDialogComponent + implements OnInit +{ + readonly iconButtonTypes = IconButtonTypes; + dictionaries: Dictionary[] = []; + form!: UntypedFormGroup; + + #manualRedactionTypeExists = true; + readonly #dossier: Dossier; + readonly #isRss = this._iqserPermissionsService.has(Roles.getRss); + readonly hint: boolean; + + constructor( + private readonly _justificationsService: JustificationsService, + private readonly _activeDossiersService: ActiveDossiersService, + private readonly _dictionaryService: DictionaryService, + private readonly _iqserPermissionsService: IqserPermissionsService, + private readonly _formBuilder: FormBuilder, + ) { + super(); + this.#dossier = _activeDossiersService.find(this.data.dossierId); + this.#manualRedactionTypeExists = this._dictionaryService.hasManualType(this.#dossier.dossierTemplateId); + + this.form = this.#getForm(); + } + + get displayedDictionaryLabel() { + const dictType = this.form.get('dictionary').value; + if (dictType) { + return this.dictionaries.find(d => d.type === dictType)?.label ?? null; + } + return null; + } + + get disabled() { + return !this.#isRss || !this.form.get('dictionary').value; + } + + async ngOnInit(): Promise { + this.dictionaries = this._dictionaryService.getRedactionTypes(this.#dossier.dossierTemplateId); + this.#formatSelectedTextValue(); + } + + save(): void { + this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry); + const redaction = this.data.manualRedactionEntryWrapper.manualRedactionEntry; + this.dialogRef.close({ + redaction, + dictionary: this.dictionaries.find(d => d.type === this.form.get('dictionary').value), + }); + } + + #getForm(): UntypedFormGroup { + return this._formBuilder.group({ + selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value, + reason: [null], + comment: [null], + dictionary: [this.#manualRedactionTypeExists ? SuperTypes.ManualRedaction : null], + classification: ['non-readable content'], + section: [null], + }); + } + + #formatSelectedTextValue(): void { + this.data.manualRedactionEntryWrapper.manualRedactionEntry.value = + this.data.manualRedactionEntryWrapper.manualRedactionEntry.value.replace( + // eslint-disable-next-line no-control-regex,max-len + /([^\s\d-]{2,})[-\u00AD]\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]/gi, + '$1', + ); + } + + #enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) { + addRedactionRequest.type = this.form.get('dictionary').value; + + const selectedType = this.dictionaries.find(d => d.type === addRedactionRequest.type); + addRedactionRequest.addToDictionary = !!selectedType?.hasDictionary; + + if (!addRedactionRequest.reason) { + addRedactionRequest.reason = 'Dictionary Request'; + } + const commentValue = this.form.get('comment').value; + addRedactionRequest.comment = commentValue ? { text: commentValue } : null; + addRedactionRequest.section = this.form.get('section').value; + addRedactionRequest.value = this.form.get('selectedText').value; + } +} diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.html new file mode 100644 index 000000000..30b92426c --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.html @@ -0,0 +1,34 @@ +
+
+
+ +
+ + +
+ + +
+
+ +
+ + + +
+
+
+ + +
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.scss b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts new file mode 100644 index 000000000..70f757ecc --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts @@ -0,0 +1,99 @@ +import { Component } from '@angular/core'; +import { DetailsRadioOption, IconButtonTypes } from '@iqser/common-ui'; +import { FormBuilder, UntypedFormGroup } from '@angular/forms'; +import { AnnotationWrapper } from '@models/file/annotation.wrapper'; +import { Dossier } from '@red/domain'; +import { IqserDialogComponent } from '@iqser/common-ui'; +import { PermissionsService } from '@services/permissions.service'; +import { RemoveAnnotationOption, RemoveAnnotationOptions } from './remove-annotation-options'; +import { removeAnnotationTranslations } from '@translations/remove-annotation-translations'; + +const PIN_ICON = 'red:push-pin'; +const FOLDER_ICON = 'red:folder'; +const REMOVE_FROM_DICT_ICON = 'red:remove-from-dict'; + +export interface RemoveAnnotationPermissions { + canRemoveOnlyHere: boolean; + canRemoveFromDictionary: boolean; + canMarkAsFalsePositive: boolean; +} + +export interface RemoveAnnotationData { + annotation: AnnotationWrapper; + dossier: Dossier; + falsePositiveContext: string; + permissions: RemoveAnnotationPermissions; + applyToAllDossiers: boolean; +} + +export interface RemoveAnnotationResult { + comment: string; + option: DetailsRadioOption; +} + +@Component({ + templateUrl: './remove-annotation-dialog.component.html', + styleUrls: ['./remove-annotation-dialog.component.scss'], +}) +export class RemoveAnnotationDialogComponent extends IqserDialogComponent< + RemoveAnnotationDialogComponent, + RemoveAnnotationData, + RemoveAnnotationResult +> { + readonly iconButtonTypes = IconButtonTypes; + readonly options: DetailsRadioOption[]; + + form!: UntypedFormGroup; + + readonly #annotation: AnnotationWrapper; + readonly #permissions: RemoveAnnotationPermissions; + readonly #translations = removeAnnotationTranslations; + + constructor(private readonly _formBuilder: FormBuilder, private readonly _permissionsService: PermissionsService) { + super(); + this.#annotation = this.data.annotation; + this.#permissions = this.data.permissions; + this.options = this.#options(); + this.form = this.#getForm(); + } + + save(): void { + this.dialogRef.close(this.form.getRawValue()); + } + + #getForm(): UntypedFormGroup { + return this._formBuilder.group({ + comment: [null], + option: [this.options[0]], + }); + } + + #options() { + const options: DetailsRadioOption[] = []; + if (this.#permissions.canRemoveOnlyHere) { + options.push({ + label: this.#translations.ONLY_HERE.label, + description: this.#translations.ONLY_HERE.description, + icon: PIN_ICON, + value: RemoveAnnotationOptions.ONLY_HERE, + }); + } + if (this.#permissions.canRemoveFromDictionary) { + options.push({ + label: this.#translations.IN_DOSSIER.label, + description: this.#translations.IN_DOSSIER.description, + icon: FOLDER_ICON, + value: RemoveAnnotationOptions.IN_DOSSIER, + }); + } + if (this.#permissions.canMarkAsFalsePositive) { + options.push({ + label: this.#translations.FALSE_POSITIVE.label, + description: this.#translations.FALSE_POSITIVE.description, + icon: REMOVE_FROM_DICT_ICON, + value: RemoveAnnotationOptions.FALSE_POSITIVE, + }); + } + return options; + } +} diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-options.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-options.ts new file mode 100644 index 000000000..01da1c682 --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-options.ts @@ -0,0 +1,7 @@ +export const RemoveAnnotationOptions = { + ONLY_HERE: 'ONLY_HERE', + IN_DOSSIER: 'IN_DOSSIER', + FALSE_POSITIVE: 'FALSE_POSITIVE', +} as const; + +export type RemoveAnnotationOption = keyof typeof RemoveAnnotationOptions; diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts index fdb1e990a..e97829dc1 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts @@ -14,12 +14,12 @@ import { redactTextTranslations } from '@translations/redact-text-translations'; import { RedactTextOption, RedactTextOptions } from './redact-text-options'; import { tap } from 'rxjs/operators'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { IqserDialogComponent } from '../../../../../../../../libs/common-ui/src/lib/dialog/iqser-dialog-component.directive'; +import { IqserDialogComponent } from '@iqser/common-ui'; const PIN_ICON = 'red:push-pin'; const FOLDER_ICON = 'red:folder'; -interface RedactTextData { +export interface RedactTextData { manualRedactionEntryWrapper: ManualRedactionEntryWrapper; dossierId: string; file: File; diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index 4c133e169..7a7bbf2f2 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -5,11 +5,10 @@ import { FormBuilder, UntypedFormGroup } from '@angular/forms'; import { removeRedactionTranslations } from '@translations/remove-redaction-translations'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { Dossier } from '@red/domain'; -import { IqserDialogComponent } from '../../../../../../../../libs/common-ui/src/lib/dialog/iqser-dialog-component.directive'; +import { IqserDialogComponent } from '@iqser/common-ui'; import { PermissionsService } from '@services/permissions.service'; import { tap } from 'rxjs/operators'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { RedactTextOption } from '../redact-text-dialog/redact-text-options'; const PIN_ICON = 'red:push-pin'; const FOLDER_ICON = 'red:folder'; 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 64844499f..28d035905 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 @@ -19,6 +19,7 @@ import { ConfirmOptions, CustomError, ErrorService, + getConfig, HelpModeService, IConfirmationDialogData, IqserDialog, @@ -66,11 +67,12 @@ import { ConfigService } from '@services/config.service'; import { ReadableRedactionsService } from '../pdf-viewer/services/readable-redactions.service'; import { Roles } from '@users/roles'; import { SuggestionsService } from './services/suggestions.service'; -import { RedactTextDialogComponent } from './dialogs/redact-text-dialog/redact-text-dialog.component'; +import { RedactTextData, RedactTextDialogComponent } from './dialogs/redact-text-dialog/redact-text-dialog.component'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; import { copyLocalStorageFiltersValues, FilterService, NestedFilter, processFilters } from '@iqser/common-ui/lib/filtering'; import { AutoUnsubscribe, Bind, bool, Debounce, List, OnAttach, OnDetach } from '@iqser/common-ui/lib/utils'; import { TenantsService } from '@iqser/common-ui/lib/tenants'; +import { AddAnnotationDialogComponent } from './dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component'; const textActions = [TextPopups.REDACT_TEXT, TextPopups.ADD_HINT, TextPopups.ADD_FALSE_POSITIVE]; @@ -95,6 +97,7 @@ export class FilePreviewScreenComponent readonly fileId = this.state.fileId; readonly dossierId = this.state.dossierId; readonly lastAssignee = computed(() => this.getLastAssignee()); + readonly #isDocumine; width: number; constructor( @@ -169,6 +172,7 @@ export class FilePreviewScreenComponent this._stampService.stampPDF().then(); } }); + this.#isDocumine = getConfig().IS_DOCUMINE; } get changed() { @@ -365,20 +369,12 @@ export class FilePreviewScreenComponent async openRedactTextDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) { const file = this.state.file(); - const dossierTemplate = this._dossierTemplatesService.find(this.state.dossierTemplateId); - const isApprover = this.permissionsService.isApprover(this.state.dossier()); - const applyDictionaryUpdatesToAllDossiersByDefault = dossierTemplate.applyDictionaryUpdatesToAllDossiersByDefault; const hint = manualRedactionEntryWrapper.type === ManualRedactionEntryTypes.HINT; - const ref = this._iqserDialog.openDefault(RedactTextDialogComponent, { - data: { - manualRedactionEntryWrapper, - dossierId: this.dossierId, - file, - applyToAllDossiers: isApprover ? applyDictionaryUpdatesToAllDossiersByDefault : false, - isApprover, - hint, - }, - }); + + const data = this.#getRedactTextDialogData(manualRedactionEntryWrapper, file, hint); + const ref = this.#isDocumine + ? this._iqserDialog.openDefault(AddAnnotationDialogComponent, { data }) + : this._iqserDialog.openDefault(RedactTextDialogComponent, { data: data as RedactTextData }); const result = await ref.result(); if (!result) { @@ -397,6 +393,28 @@ export class FilePreviewScreenComponent return firstValueFrom(addAndReload$.pipe(catchError(() => of(undefined)))); } + #getRedactTextDialogData(manualRedactionEntryWrapper: ManualRedactionEntryWrapper, file: File, hint: boolean) { + const dossierTemplate = this._dossierTemplatesService.find(this.state.dossierTemplateId); + + const data = { + manualRedactionEntryWrapper, + dossierId: this.dossierId, + file, + }; + if (this.#isDocumine) { + return data; + } + + const isApprover = this.permissionsService.isApprover(this.state.dossier()); + const applyDictionaryUpdatesToAllDossiersByDefault = dossierTemplate.applyDictionaryUpdatesToAllDossiersByDefault; + return { + ...data, + applyToAllDossiers: isApprover ? applyDictionaryUpdatesToAllDossiersByDefault : false, + isApprover, + hint, + }; + } + toggleFullScreen() { this.fullScreen = !this.fullScreen; if (this.fullScreen) { 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 82cbd9fb1..f00380451 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 @@ -66,6 +66,8 @@ import { IqserUsersModule } from '@iqser/common-ui/lib/users'; import { IqserFiltersModule } from '@iqser/common-ui/lib/filtering'; import { StatusBarComponent } from '@iqser/common-ui/lib/shared'; import { TenantPipe } from '@iqser/common-ui/lib/tenants'; +import { AddAnnotationDialogComponent } from './dialogs/docu-mine/add-annotation-dialog/add-annotation-dialog.component'; +import { RemoveAnnotationDialogComponent } from './dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component'; const routes: IqserRoutes = [ { @@ -89,6 +91,8 @@ const dialogs = [ RssDialogComponent, RedactTextDialogComponent, RemoveRedactionDialogComponent, + AddAnnotationDialogComponent, + RemoveAnnotationDialogComponent, ]; const components = [ diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts index 2d15c7a65..76cf1f29d 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts @@ -9,7 +9,7 @@ import { } from '@models/file/manual-redaction-entry.wrapper'; import { AnnotationDrawService } from '../../pdf-viewer/services/annotation-draw.service'; import { UserPreferenceService } from '@users/user-preference.service'; -import { IqserPermissionsService } from '@iqser/common-ui'; +import { getConfig, IqserPermissionsService } from '@iqser/common-ui'; import { toPosition } from '../utils/pdf-calculation.utils'; import { MultiSelectService } from './multi-select.service'; import { FilePreviewStateService } from './file-preview-state.service'; @@ -50,6 +50,7 @@ export class PdfProxyService { readonly #addRedactionIcon = this._iqserPermissionsService.has(Roles.getRss) ? this._convertPath('/assets/icons/general/pdftron-action-add-annotation.svg') : this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'); + readonly #isDocumine; readonly #addHintIcon = this._convertPath('/assets/icons/general/pdftron-action-add-hint.svg'); readonly annotationSelected$ = this.#annotationSelected$; readonly manualAnnotationRequested$ = new Subject(); @@ -113,6 +114,7 @@ export class PdfProxyService { this._viewerHeaderService.disable([HeaderElements.TOGGLE_READABLE_REDACTIONS]); } }); + this.#isDocumine = getConfig().IS_DOCUMINE; } get #annotationSelected$() { @@ -186,13 +188,16 @@ export class PdfProxyService { title: this.#getTitle(ManualRedactionEntryTypes.REDACT), onClick: () => this._ngZone.run(() => this.#redactText(ManualRedactionEntryTypes.REDACT)), }); - popups.push({ - type: 'actionButton', - dataElement: TextPopups.ADD_HINT, - img: this.#addHintIcon, - title: this.#getTitle(ManualRedactionEntryTypes.HINT), - onClick: () => this._ngZone.run(() => this.#redactText(ManualRedactionEntryTypes.HINT)), - }); + + if (!this.#isDocumine) { + popups.push({ + type: 'actionButton', + dataElement: TextPopups.ADD_HINT, + img: this.#addHintIcon, + title: this.#getTitle(ManualRedactionEntryTypes.HINT), + onClick: () => this._ngZone.run(() => this.#redactText(ManualRedactionEntryTypes.HINT)), + }); + } } this._pdf.configureTextPopups(popups); diff --git a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts index 6402c0485..1e5b8dcc5 100644 --- a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { firstValueFrom, forkJoin, Observable, of, throwError } from 'rxjs'; +import { firstValueFrom, forkJoin, Observable, throwError } from 'rxjs'; import { EntitiesService, QueryParam, Toaster } from '@iqser/common-ui'; import { Dictionary, DictionaryEntryType, DictionaryEntryTypes, IDictionary, IUpdateDictionary, SuperTypes } from '@red/domain'; import { catchError, map, switchMap, tap } from 'rxjs/operators'; @@ -177,9 +177,7 @@ export class DictionaryService extends EntitiesService } }); - possibleDictionaries.sort((a, b) => a.label.localeCompare(b.label)); - - return possibleDictionaries; + return possibleDictionaries.sort((a, b) => a.label.localeCompare(b.label)); } getRedactionTypes(dossierTemplateId: string): Dictionary[] { @@ -191,9 +189,7 @@ export class DictionaryService extends EntitiesService } } - possibleDictionaries.sort((a, b) => a.label.localeCompare(b.label)); - - return possibleDictionaries; + return possibleDictionaries.sort((a, b) => a.label.localeCompare(b.label)); } async getDictionariesOptions(dossierTemplateId: string, dossierId: string): Promise { diff --git a/apps/red-ui/src/app/translations/remove-annotation-translations.ts b/apps/red-ui/src/app/translations/remove-annotation-translations.ts new file mode 100644 index 000000000..b186ef467 --- /dev/null +++ b/apps/red-ui/src/app/translations/remove-annotation-translations.ts @@ -0,0 +1,22 @@ +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { RemoveAnnotationOption } from '../modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-options'; + +interface Option { + label: string; + description: string; +} + +export const removeAnnotationTranslations: { [key in RemoveAnnotationOption]: Option } = { + ONLY_HERE: { + label: _('remove-annotation.dialog.content.options.only-here.label'), + description: _('remove-annotation.dialog.content.options.only-here.description'), + }, + IN_DOSSIER: { + label: _('remove-annotation.dialog.content.options.in-dossier.label'), + description: _('remove-annotation.dialog.content.options.in-dossier.description'), + }, + FALSE_POSITIVE: { + label: _('remove-annotation.dialog.content.options.false-positive.label'), + description: _('remove-annotation.dialog.content.options.false-positive.description'), + }, +}; diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index f96939231..772d6e339 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -1,9 +1,9 @@ { "ADMIN_CONTACT_NAME": null, "ADMIN_CONTACT_URL": null, - "API_URL": "https://dan.iqser.cloud", + "API_URL": "https://dev-04.iqser.cloud", "APP_NAME": "RedactManager very very very very long", - "IS_DOCUMINE": false, + "IS_DOCUMINE": true, "AUTO_READ_TIME": 3, "BACKEND_APP_VERSION": "4.4.40", "EULA_URL": "EULA_URL", @@ -12,7 +12,7 @@ "MAX_RETRIES_ON_SERVER_ERROR": 3, "OAUTH_CLIENT_ID": "redaction", "OAUTH_IDP_HINT": null, - "OAUTH_URL": "https://dan.iqser.cloud/auth", + "OAUTH_URL": "https://dev-04.iqser.cloud/auth", "RECENT_PERIOD_IN_HOURS": 24, "SELECTION_MODE": "structural", "MANUAL_BASE_URL": "https://docs.redactmanager.com/preview", diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 7c8549c24..d52bf2b30 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -11,6 +11,22 @@ "all": "Alle", "none": "Keine" }, + "add-annotation": { + "dialog": { + "actions": { + "cancel": "", + "save": "" + }, + "content": { + "comment": "", + "comment-placeholder": "", + "selected-text": "", + "type": "", + "type-placeholder": "" + }, + "title": "" + } + }, "add-dossier-dialog": { "actions": { "save": "Speichern", @@ -1951,6 +1967,33 @@ }, "redaction-abbreviation": "R", "references": "", + "remove-annotation": { + "dialog": { + "actions": { + "cancel": "", + "save": "" + }, + "content": { + "comment": "", + "comment-placeholder": "", + "options": { + "false-positive": { + "description": "", + "label": "" + }, + "in-dossier": { + "description": "", + "label": "" + }, + "only-here": { + "description": "", + "label": "" + } + } + }, + "title": "" + } + }, "remove-redaction": { "dialog": { "actions": { diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 5ad6ae7d5..1b22cc672 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -11,6 +11,22 @@ "all": "All", "none": "None" }, + "add-annotation": { + "dialog": { + "actions": { + "cancel": "Cancel", + "save": "Save" + }, + "content": { + "comment": "Comment", + "comment-placeholder": "Add remarks or mentions...", + "selected-text": "Selected text:", + "type": "Type", + "type-placeholder": "Select type ..." + }, + "title": "Add annotation" + } + }, "add-dossier-dialog": { "actions": { "save": "Save", @@ -1951,6 +1967,33 @@ }, "redaction-abbreviation": "R", "references": "{count} {count, plural, one{reference} other{references}}", + "remove-annotation": { + "dialog": { + "actions": { + "cancel": "", + "save": "" + }, + "content": { + "comment": "", + "comment-placeholder": "", + "options": { + "false-positive": { + "description": "", + "label": "" + }, + "in-dossier": { + "description": "", + "label": "" + }, + "only-here": { + "description": "", + "label": "" + } + } + }, + "title": "" + } + }, "remove-redaction": { "dialog": { "actions": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 26c56448b..452dcf579 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -11,6 +11,22 @@ "all": "Alle", "none": "Keine" }, + "add-annotation": { + "dialog": { + "actions": { + "cancel": "", + "save": "" + }, + "content": { + "comment": "", + "comment-placeholder": "", + "selected-text": "", + "type": "", + "type-placeholder": "" + }, + "title": "" + } + }, "add-dossier-dialog": { "actions": { "save": "Speichern", @@ -1951,6 +1967,33 @@ }, "redaction-abbreviation": "C", "references": "", + "remove-annotation": { + "dialog": { + "actions": { + "cancel": "", + "save": "" + }, + "content": { + "comment": "", + "comment-placeholder": "", + "options": { + "false-positive": { + "description": "", + "label": "" + }, + "in-dossier": { + "description": "", + "label": "" + }, + "only-here": { + "description": "", + "label": "" + } + } + }, + "title": "" + } + }, "remove-redaction": { "dialog": { "actions": { diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index f382a2b4e..76cbfd99b 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -11,6 +11,22 @@ "all": "All", "none": "None" }, + "add-annotation": { + "dialog": { + "actions": { + "cancel": "Cancel", + "save": "Save" + }, + "content": { + "comment": "Comment", + "comment-placeholder": "Add remarks or mentions...", + "selected-text": "Selected text:", + "type": "Type", + "type-placeholder": "Select type ..." + }, + "title": "Add annotation" + } + }, "add-dossier-dialog": { "actions": { "save": "Save", @@ -1951,6 +1967,33 @@ }, "redaction-abbreviation": "A", "references": "{count} {count, plural, one{reference} other{references}}", + "remove-annotation": { + "dialog": { + "actions": { + "cancel": "", + "save": "" + }, + "content": { + "comment": "", + "comment-placeholder": "", + "options": { + "false-positive": { + "description": "", + "label": "" + }, + "in-dossier": { + "description": "", + "label": "" + }, + "only-here": { + "description": "", + "label": "" + } + } + }, + "title": "" + } + }, "remove-redaction": { "dialog": { "actions": {