diff --git a/apps/red-ui/src/app/modules/account/account.module.ts b/apps/red-ui/src/app/modules/account/account.module.ts index fac249986..20f4f6bf0 100644 --- a/apps/red-ui/src/app/modules/account/account.module.ts +++ b/apps/red-ui/src/app/modules/account/account.module.ts @@ -9,9 +9,10 @@ import { TranslateModule } from '@ngx-translate/core'; import { IconButtonComponent, IqserAllowDirective, IqserHelpModeModule } from '@iqser/common-ui'; import { PreferencesComponent } from './screens/preferences/preferences.component'; import { SideNavComponent } from '@iqser/common-ui/lib/shared'; +import { DialogDefaultsComponent } from './screens/preferences/dialog-defaults/dialog-defaults.component'; @NgModule({ - declarations: [AccountSideNavComponent, BaseAccountScreenComponent, PreferencesComponent], + declarations: [AccountSideNavComponent, BaseAccountScreenComponent, PreferencesComponent, DialogDefaultsComponent], imports: [ CommonModule, SharedModule, diff --git a/apps/red-ui/src/app/modules/account/screens/preferences/dialog-defaults/dialog-defaults.component.html b/apps/red-ui/src/app/modules/account/screens/preferences/dialog-defaults/dialog-defaults.component.html new file mode 100644 index 000000000..67efc5106 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/screens/preferences/dialog-defaults/dialog-defaults.component.html @@ -0,0 +1,77 @@ +
+
+

{{ 'dialog-defaults-form.title' | translate }}

+

{{ 'dialog-defaults-form.redaction.title' | translate }}

+
+ + + + {{ + option.label | translate + }} + + + {{ + 'dialog-defaults-form.extra-option-label' | translate + }} +
+
+ + + + {{ + option.label | translate + }} + + + {{ + 'dialog-defaults-form.extra-option-label' | translate + }} +
+

{{ 'dialog-defaults-form.recommendation.title' | translate }}

+
+ + + + {{ + option.label | translate + }} + + + {{ + 'dialog-defaults-form.extra-option-label' | translate + }} +
+

{{ 'dialog-defaults-form.hint.title' | translate }}

+
+ + + + {{ option.label | translate }} + + + {{ + 'dialog-defaults-form.extra-option-label' | translate + }} +
+
+ + + + {{ option.label | translate }} + + + {{ + 'dialog-defaults-form.extra-option-label' | translate + }} +
+
+
+ +
+
diff --git a/apps/red-ui/src/app/modules/account/screens/preferences/dialog-defaults/dialog-defaults.component.scss b/apps/red-ui/src/app/modules/account/screens/preferences/dialog-defaults/dialog-defaults.component.scss new file mode 100644 index 000000000..8b82b1023 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/screens/preferences/dialog-defaults/dialog-defaults.component.scss @@ -0,0 +1,3 @@ +mat-checkbox { + margin: 8px 0 0 8px; +} diff --git a/apps/red-ui/src/app/modules/account/screens/preferences/dialog-defaults/dialog-defaults.component.ts b/apps/red-ui/src/app/modules/account/screens/preferences/dialog-defaults/dialog-defaults.component.ts new file mode 100644 index 000000000..0039b8f8a --- /dev/null +++ b/apps/red-ui/src/app/modules/account/screens/preferences/dialog-defaults/dialog-defaults.component.ts @@ -0,0 +1,172 @@ +import { ChangeDetectorRef, Component, inject } from '@angular/core'; +import { BaseFormComponent } from '@common-ui/form'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { + RedactOrHintOption, + RedactOrHintOptions, + RemoveRedactionOption, + RemoveRedactionOptions, +} from '../../../../file-preview/utils/dialog-options'; +import { PreferencesKeys, UserPreferenceService } from '@users/user-preference.service'; +import { AsControl } from '@common-ui/utils'; +import { + hintAddOptions, + recommendationRemoveOptions, + redactionAddOptions, + redactionRemoveOptions, + removeOptions, + SystemDefaultType, +} from '../../../utils/dialog-defaults'; + +interface DefaultOptionsForm { + addRedaction: RedactOrHintOption | SystemDefaultType; + addHint: RedactOrHintOption | SystemDefaultType; + removeRedaction: RemoveRedactionOption | SystemDefaultType; + removeRecommendation: RemoveRedactionOption | SystemDefaultType; + removeHint: RemoveRedactionOption | SystemDefaultType; + addRedactionApplyToAll: boolean; + removeRedactionApplyToAll: boolean; + removeRecommendationApplyToAll: boolean; + addHintApplyToAll: boolean; + removeHintApplyToAll: boolean; +} + +@Component({ + selector: 'redaction-dialog-defaults', + templateUrl: './dialog-defaults.component.html', + styleUrl: './dialog-defaults.component.scss', +}) +export class DialogDefaultsComponent extends BaseFormComponent { + readonly #formBuilder = inject(FormBuilder); + readonly #userPreferences = inject(UserPreferenceService); + readonly #changeDetectorRef = inject(ChangeDetectorRef); + form: FormGroup> = this.#formBuilder.group({ + addRedaction: this.#userPreferences.getAddRedactionDefaultOption(), + addHint: this.#userPreferences.getAddHintDefaultOption(), + removeRedaction: this.#userPreferences.getRemoveRedactionDefaultOption(), + removeRecommendation: this.#userPreferences.getRemoveRecommendationDefaultOption(), + removeHint: this.#userPreferences.getRemoveHintDefaultOption(), + addRedactionApplyToAll: this.#userPreferences.getBool(PreferencesKeys.addRedactionDefaultExtraOption), + removeRedactionApplyToAll: this.#userPreferences.getBool(PreferencesKeys.removeRedactionDefaultExtraOption), + removeRecommendationApplyToAll: this.#userPreferences.getBool(PreferencesKeys.removeRecommendationDefaultExtraOption), + addHintApplyToAll: this.#userPreferences.getBool(PreferencesKeys.addHintDefaultExtraOption), + removeHintApplyToAll: this.#userPreferences.getBool(PreferencesKeys.removeHintDefaultExtraOption), + }); + initialFormValue = this.form.getRawValue(); + + readonly redactionAddOptions = redactionAddOptions; + readonly hintAddOptions = hintAddOptions; + readonly removeOptions = removeOptions; + readonly redactionRemoveOptions = redactionRemoveOptions; + readonly recommendationRemoveOptions = recommendationRemoveOptions; + + get displayExtraOptionAddRedaction() { + return RedactOrHintOptions.IN_DOSSIER === this.form.controls.addRedaction.value; + } + + get displayExtraOptionAddHint() { + return RedactOrHintOptions.IN_DOSSIER === this.form.controls.addHint.value; + } + + get displayExtraOptionRemoveRedaction() { + return ( + [RemoveRedactionOptions.IN_DOSSIER, RemoveRedactionOptions.FALSE_POSITIVE] as Partial< + RemoveRedactionOption | SystemDefaultType + >[] + ).includes(this.form.controls.removeRedaction.value); + } + + get displayExtraOptionRemoveHint() { + return RemoveRedactionOptions.IN_DOSSIER === this.form.controls.removeHint.value; + } + + get displayExtraOptionRemoveRecommendation() { + return RemoveRedactionOptions.DO_NOT_RECOMMEND === this.form.controls.removeRecommendation.value; + } + + constructor() { + super(); + } + + async save(): Promise { + const formValue = this.form.value; + + if (this.initialFormValue.addRedaction !== this.form.controls.addRedaction.value) { + await this.#userPreferences.saveAddRedactionDefaultOption(this.form.controls.addRedaction.value); + } + if (this.initialFormValue.addHint !== this.form.controls.addHint.value) { + await this.#userPreferences.saveAddHintDefaultOption(this.form.controls.addHint.value); + } + if (this.initialFormValue.removeRedaction !== this.form.controls.removeRedaction.value) { + await this.#userPreferences.saveRemoveRedactionDefaultOption(this.form.controls.removeRedaction.value); + } + if (this.initialFormValue.removeRecommendation !== this.form.controls.removeRecommendation.value) { + await this.#userPreferences.saveRemoveRecommendationDefaultOption(this.form.controls.removeRecommendation.value); + } + if (this.initialFormValue.removeHint !== this.form.controls.removeHint.value) { + await this.#userPreferences.saveRemoveHintDefaultOption(this.form.controls.removeHint.value); + } + + if (this.displayExtraOptionAddRedaction) { + if (this.initialFormValue.addRedactionApplyToAll !== this.form.controls.addRedactionApplyToAll.value) { + await this.#userPreferences.saveAddRedactionDefaultExtraOption(this.form.controls.addRedactionApplyToAll.value); + } + } else { + await this.#userPreferences.saveAddRedactionDefaultExtraOption('undefined'); + } + + if (this.displayExtraOptionAddHint) { + if (this.initialFormValue.addHintApplyToAll !== this.form.controls.addHintApplyToAll.value) { + await this.#userPreferences.saveAddHintDefaultExtraOption(this.form.controls.addHintApplyToAll.value); + } + } else { + await this.#userPreferences.saveAddHintDefaultExtraOption('undefined'); + } + + if (this.displayExtraOptionRemoveRedaction) { + if (this.initialFormValue.removeRedactionApplyToAll !== this.form.controls.removeRedactionApplyToAll.value) { + await this.#userPreferences.saveRemoveRedactionDefaultExtraOption(this.form.controls.removeRedactionApplyToAll.value); + } + } else { + await this.#userPreferences.saveRemoveRedactionDefaultExtraOption('undefined'); + } + + if (this.displayExtraOptionRemoveHint) { + if (this.initialFormValue.removeHintApplyToAll !== this.form.controls.removeHintApplyToAll.value) { + await this.#userPreferences.saveRemoveHintDefaultExtraOption(this.form.controls.removeHintApplyToAll.value); + } + } else { + await this.#userPreferences.saveRemoveHintDefaultExtraOption('undefined'); + } + + if (this.displayExtraOptionRemoveRecommendation) { + if (this.initialFormValue.removeRecommendationApplyToAll !== this.form.controls.removeRecommendationApplyToAll.value) { + await this.#userPreferences.saveRemoveRecommendationDefaultExtraOption( + this.form.controls.removeRecommendationApplyToAll.value, + ); + } + } else { + await this.#userPreferences.saveRemoveRecommendationDefaultExtraOption('undefined'); + } + + await this.#userPreferences.reload(); + this.#patchValues(); + this.initialFormValue = this.form.getRawValue(); + this.#changeDetectorRef.markForCheck(); + } + + #patchValues() { + this.form.patchValue({ + addRedaction: this.#userPreferences.getAddRedactionDefaultOption(), + addHint: this.#userPreferences.getAddHintDefaultOption(), + removeRedaction: this.#userPreferences.getRemoveRedactionDefaultOption(), + removeRecommendation: this.#userPreferences.getRemoveRecommendationDefaultOption(), + removeHint: this.#userPreferences.getRemoveHintDefaultOption(), + addRedactionApplyToAll: this.#userPreferences.getBool(PreferencesKeys.addRedactionDefaultExtraOption), + removeRedactionApplyToAll: this.#userPreferences.getBool(PreferencesKeys.removeRedactionDefaultExtraOption), + removeRecommendationApplyToAll: this.#userPreferences.getBool(PreferencesKeys.removeRecommendationDefaultExtraOption), + addHintApplyToAll: this.#userPreferences.getBool(PreferencesKeys.addHintDefaultExtraOption), + removeHintApplyToAll: this.#userPreferences.getBool(PreferencesKeys.removeHintDefaultExtraOption), + }); + } +} diff --git a/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.html b/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.html index cee25d2a8..1102780a9 100644 --- a/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.html +++ b/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.html @@ -1,6 +1,7 @@ + +
-
@@ -22,7 +23,7 @@ -

{{ 'preferences-screen.warnings-subtitle' | translate }}

+

{{ 'preferences-screen.warnings-subtitle' | translate }}

{{ 'preferences-screen.warnings-description' | translate }}

diff --git a/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.scss b/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.scss index 9fb4fef95..984c6af08 100644 --- a/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.scss +++ b/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.scss @@ -5,12 +5,6 @@ margin-bottom: 15px; } -.warnings-subtitle { - font-size: var(--iqser-font-size); - color: var(--iqser-text); - font-weight: 600; -} - .warnings-description { width: 105%; } diff --git a/apps/red-ui/src/app/modules/account/utils/dialog-defaults.ts b/apps/red-ui/src/app/modules/account/utils/dialog-defaults.ts new file mode 100644 index 000000000..e91793bff --- /dev/null +++ b/apps/red-ui/src/app/modules/account/utils/dialog-defaults.ts @@ -0,0 +1,84 @@ +import { redactTextTranslations } from '@translations/redact-text-translations'; +import { RedactOrHintOptions, RemoveRedactionOptions } from '../../file-preview/utils/dialog-options'; +import { removeRedactionTranslations } from '@translations/remove-redaction-translations'; +import { addHintTranslations } from '@translations/add-hint-translations'; +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; + +export const SystemDefaults = { + ADD_REDACTION_DEFAULT: RedactOrHintOptions.IN_DOSSIER, + ADD_HINT_DEFAULT: RedactOrHintOptions.IN_DOSSIER, + REMOVE_REDACTION_DEFAULT: RemoveRedactionOptions.ONLY_HERE, + REMOVE_HINT_DEFAULT: RemoveRedactionOptions.ONLY_HERE, + REMOVE_RECOMMENDATION_DEFAULT: RemoveRedactionOptions.DO_NOT_RECOMMEND, +} as const; + +export const SystemDefaultOption = { + SYSTEM_DEFAULT: 'SYSTEM_DEFAULT', + label: _('dialog-defaults-form.system-default'), +} as const; + +export type SystemDefaultType = typeof SystemDefaultOption.SYSTEM_DEFAULT; + +export const redactionAddOptions = [ + { + label: SystemDefaultOption.label, + value: SystemDefaultOption.SYSTEM_DEFAULT, + }, + { + label: redactTextTranslations.onlyHere.label, + value: RedactOrHintOptions.ONLY_HERE, + }, + { + label: redactTextTranslations.inDossier.label, + value: RedactOrHintOptions.IN_DOSSIER, + }, +]; + +export const hintAddOptions = [ + { + label: SystemDefaultOption.label, + value: SystemDefaultOption.SYSTEM_DEFAULT, + }, + { + label: addHintTranslations.onlyHere.label, + value: RedactOrHintOptions.ONLY_HERE, + }, + { + label: addHintTranslations.inDossier.label, + value: RedactOrHintOptions.IN_DOSSIER, + }, +]; + +export const removeOptions = [ + { + label: SystemDefaultOption.label, + value: SystemDefaultOption.SYSTEM_DEFAULT, + }, + { + label: removeRedactionTranslations.ONLY_HERE.label, + value: RemoveRedactionOptions.ONLY_HERE, + }, + { + label: removeRedactionTranslations.IN_DOSSIER.label, + value: RemoveRedactionOptions.IN_DOSSIER, + }, +]; + +export const redactionRemoveOptions = [ + ...removeOptions, + { + label: removeRedactionTranslations.FALSE_POSITIVE.label, + value: RemoveRedactionOptions.FALSE_POSITIVE, + }, +]; + +export const recommendationRemoveOptions = [ + { + label: SystemDefaultOption.label, + value: SystemDefaultOption.SYSTEM_DEFAULT, + }, + { + label: removeRedactionTranslations.DO_NOT_RECOMMEND.label, + value: RemoveRedactionOptions.DO_NOT_RECOMMEND, + }, +]; diff --git a/apps/red-ui/src/app/modules/file-preview/components/view-switch/view-switch.component.ts b/apps/red-ui/src/app/modules/file-preview/components/view-switch/view-switch.component.ts index ddc97b237..78efc6d3d 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/view-switch/view-switch.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/view-switch/view-switch.component.ts @@ -23,7 +23,7 @@ export class ViewSwitchComponent { }); protected readonly canSwitchToRedactedView = computed(() => { const file = this._state.file(); - return !file.analysisRequired && !file.excluded; + return !file.analysisRequired && !file.excluded && !file.isError; }); protected readonly canSwitchToEarmarksView = computed(() => { const file = this._state.file(); diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.ts index 2aeb8f9d3..d0015fa32 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.ts @@ -9,6 +9,9 @@ import { Roles } from '@users/roles'; import { tap } from 'rxjs/operators'; import { getRedactOrHintOptions, RedactOrHintOption, RedactOrHintOptions } from '../../utils/dialog-options'; import { AddHintData, AddHintResult } from '../../utils/dialog-types'; +import { UserPreferenceService } from '@users/user-preference.service'; +import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dialog-defaults'; +import { stringToBoolean } from '@utils/functions'; @Component({ templateUrl: './add-hint-dialog.component.html', @@ -30,10 +33,11 @@ export class AddHintDialogComponent extends IqserDialogComponent { + return this.options.find(o => o.value === option); + } } 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 index d825e2284..d9061c729 100644 --- 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 @@ -30,7 +30,7 @@ export class RemoveAnnotationDialogComponent extends IqserDialogComponent< constructor(private readonly _formBuilder: FormBuilder) { super(); - this.options = getRemoveRedactionOptions(this.data, true); + this.options = getRemoveRedactionOptions(this.data, this.data.applyToAllDossiers, true); this.redactedTexts = this.data.redactions.map(annotation => annotation.value); this.form = this.#getForm(); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.html index 25161a316..f2d6315d2 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.html @@ -25,16 +25,14 @@ [ngStyle]="{ width: maximumTextAreaWidth + 'px' }" formControlName="selectedText" iqserHasScrollbar - name="comment" + name="value" type="text" > diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss index 0b6f2896a..c774426d3 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss @@ -14,7 +14,11 @@ } iqser-circle-button { - padding-left: 8px; + padding-left: 10px; + + &.undo-button { + margin-left: 8px; + } } .w-full { @@ -25,8 +29,10 @@ iqser-circle-button { min-height: 36px; } -textarea { +textarea[name='value'] { margin-top: 0; + min-height: 0; + line-height: 1; } .table { 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 a55a7fb2b..445aa7d34 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 @@ -7,12 +7,14 @@ import { ActiveDossiersService } from '@services/dossiers/active-dossiers.servic import { DictionaryService } from '@services/entity-services/dictionary.service'; import { JustificationsService } from '@services/entity-services/justifications.service'; import { Roles } from '@users/roles'; -import { calcTextWidthInPixels } from '@utils/functions'; +import { calcTextWidthInPixels, stringToBoolean } from '@utils/functions'; import { firstValueFrom, Observable } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { getRedactOrHintOptions, RedactOrHintOption, RedactOrHintOptions } from '../../utils/dialog-options'; import { RedactTextData, RedactTextResult } from '../../utils/dialog-types'; import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component'; +import { UserPreferenceService } from '@users/user-preference.service'; +import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dialog-defaults'; const MAXIMUM_TEXT_AREA_WIDTH = 421; @@ -38,29 +40,41 @@ export class RedactTextDialogComponent readonly displayedDictionaryLabel$: Observable; readonly #dossier = inject(ActiveDossiersService).find(this.data.dossierId); readonly #manualRedactionTypeExists = inject(DictionaryService).hasManualType(this.#dossier.dossierTemplateId); - #applyToAllDossiers = this.data.applyToAllDossiers ?? true; + #applyToAllDossiers = this.applyToAll; readonly maximumTextAreaWidth = MAXIMUM_TEXT_AREA_WIDTH; readonly maximumSelectedTextWidth = 567; textWidth: number; + get isSystemDefault(): boolean { + return this._userPreferences.getAddRedactionDefaultOption() === SystemDefaultOption.SYSTEM_DEFAULT; + } + get defaultOption() { - const inDossierOption = this.options.find(option => option.value === RedactOrHintOptions.IN_DOSSIER); - this.dictionaryRequest = !!inDossierOption && !inDossierOption.disabled; + const defaultOption = this.isSystemDefault + ? this.#getOption(SystemDefaults.ADD_REDACTION_DEFAULT) + : this.#getOption(this._userPreferences.getAddRedactionDefaultOption() as RedactOrHintOption); + this.dictionaryRequest = defaultOption.value === RedactOrHintOptions.IN_DOSSIER; if (this.dictionaryRequest) { this.#setDictionaries(); - return inDossierOption; + return defaultOption; } - return this.options[0]; + return defaultOption ?? this.options[0]; + } + + get applyToAll() { + return this.isSystemDefault || this._userPreferences.getAddRedactionDefaultExtraOption() === 'undefined' + ? this.data.applyToAllDossiers ?? true + : stringToBoolean(this._userPreferences.getAddRedactionDefaultExtraOption()); } constructor( private readonly _justificationsService: JustificationsService, private readonly _dictionaryService: DictionaryService, private readonly _formBuilder: FormBuilder, + private readonly _userPreferences: UserPreferenceService, ) { super(); - this.options = getRedactOrHintOptions(this.#dossier, this.#applyToAllDossiers, this.data.isApprover, this.data.isPageExcluded); this.form = this.#getForm(); this.#setupValidators(this.dictionaryRequest ? RedactOrHintOptions.IN_DOSSIER : RedactOrHintOptions.ONLY_HERE); @@ -208,7 +222,7 @@ export class RedactTextDialogComponent } #resetValues() { - this.#applyToAllDossiers = this.data.applyToAllDossiers ?? true; + this.#applyToAllDossiers = this.applyToAll; this.options[1].extraOption.checked = this.#applyToAllDossiers; if (this.dictionaryRequest) { this.form.controls.reason.setValue(null); @@ -218,5 +232,7 @@ export class RedactTextDialogComponent this.form.controls.dictionary.setValue(this.#manualRedactionTypeExists ? SuperTypes.ManualRedaction : null); } - protected readonly window = window; + #getOption(option: RedactOrHintOption): DetailsRadioOption { + return this.options.find(o => o.value === option); + } } 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 42094db60..04d209710 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 @@ -8,6 +8,9 @@ import { DialogHelpModeKeys } from '../../utils/constants'; import { toSignal } from '@angular/core/rxjs-interop'; import { map } from 'rxjs/operators'; import { ValueColumn } from '../../components/selected-annotations-table/selected-annotations-table.component'; +import { UserPreferenceService } from '@users/user-preference.service'; +import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dialog-defaults'; +import { stringToBoolean } from '@utils/functions'; @Component({ templateUrl: './remove-redaction-dialog.component.html', @@ -19,9 +22,54 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< RemoveRedactionResult > { readonly iconButtonTypes = IconButtonTypes; - readonly options: DetailsRadioOption[] = getRemoveRedactionOptions(this.data); + readonly recommendation = this.data.redactions.every(redaction => redaction.isRecommendation); - readonly hint = this.data.redactions[0].HINT; + readonly hint = this.data.redactions.every(redaction => redaction.isHint); + readonly annotationsType = this.hint ? 'hint' : this.recommendation ? 'recommendation' : 'redaction'; + + readonly optionByType = { + recommendation: { + main: this._userPreferences.getRemoveRecommendationDefaultOption(), + extra: this._userPreferences.getRemoveRecommendationDefaultExtraOption(), + }, + hint: { + main: this._userPreferences.getRemoveHintDefaultOption(), + extra: this._userPreferences.getRemoveHintDefaultExtraOption(), + }, + redaction: { + main: this._userPreferences.getRemoveRedactionDefaultOption(), + extra: this._userPreferences.getRemoveRedactionDefaultExtraOption(), + }, + }; + + readonly systemDefaultByType = { + recommendation: { + main: SystemDefaults.REMOVE_RECOMMENDATION_DEFAULT, + extra: this.data.applyToAllDossiers, + }, + hint: { + main: SystemDefaults.REMOVE_HINT_DEFAULT, + extra: this.data.applyToAllDossiers, + }, + redaction: { + main: SystemDefaults.REMOVE_REDACTION_DEFAULT, + extra: false, + }, + }; + + readonly isSystemDefault = this.optionByType[this.annotationsType].main === SystemDefaultOption.SYSTEM_DEFAULT; + readonly isExtraOptionSystemDefault = this.optionByType[this.annotationsType].extra === 'undefined'; + readonly defaultOptionPreference = this.isSystemDefault + ? this.systemDefaultByType[this.annotationsType].main + : this.optionByType[this.annotationsType].main; + readonly extraOptionPreference = stringToBoolean(this.optionByType[this.annotationsType].extra); + + readonly #applyToAllDossiers = this.systemDefaultByType[this.annotationsType].extra; + + readonly options: DetailsRadioOption[] = getRemoveRedactionOptions( + this.data, + this.isSystemDefault || this.isExtraOptionSystemDefault ? this.#applyToAllDossiers : this.extraOptionPreference, + ); readonly skipped = this.data.redactions.some(annotation => annotation.isSkipped); readonly redactedTexts = this.data.redactions.map(annotation => annotation.value); @@ -56,7 +104,10 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< ]), ); - constructor(private readonly _formBuilder: FormBuilder) { + constructor( + private readonly _formBuilder: FormBuilder, + private readonly _userPreferences: UserPreferenceService, + ) { super(); } @@ -78,13 +129,13 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< } get defaultOption() { - const removeHereOption = this.options.find(option => option.value === RemoveRedactionOptions.ONLY_HERE); - if (!!removeHereOption && !removeHereOption.disabled) return removeHereOption; + const removeDefaultOption = this.#getOption(this.defaultOptionPreference as RemoveRedactionOption); + if (!!removeDefaultOption && !removeDefaultOption.disabled) return removeDefaultOption; return this.options[0]; } get typeTranslationArg() { - return { type: this.hint ? 'hint' : this.recommendation ? 'recommendation' : 'redaction' }; + return { type: this.annotationsType }; } get isBulk() { @@ -102,4 +153,8 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< save(): void { this.close(this.form.getRawValue()); } + + #getOption(option: RemoveRedactionOption): DetailsRadioOption { + return this.options.find(o => o.value === option); + } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-processing.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-processing.service.ts index b8fbb3aae..42d467dd9 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-processing.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-processing.service.ts @@ -79,7 +79,13 @@ export class AnnotationProcessingService { const filters: INestedFilter[] = []; this._fileDataService.all?.forEach(a => { - if (this.#isDocumine && !this.#devMode && a.isOCR) { + const dictionary = this._state.dictionaries.find(dictionary => dictionary.type === a.type); + const doesTypeExist = !!dictionary; + if ( + (this.#isDocumine && !this.#devMode && a.isOCR) || + (!this.#devMode && dictionary?.experimental) || + (!doesTypeExist && !this._state.isReadonly()) + ) { return; } const topLevelFilter = a.topLevelFilter; 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 704313e79..0906fb42d 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 @@ -217,6 +217,10 @@ export class FileDataService extends EntitiesService[] => { const translations = isDocumine ? removeAnnotationTranslations : removeRedactionTranslations; - const { permissions, redactions, applyToAllDossiers, isApprover, falsePositiveContext } = data; + const { permissions, redactions, isApprover, falsePositiveContext } = data; const isBulk = redactions.length > 1; const options: DetailsRadioOption[] = []; @@ -179,7 +180,7 @@ export const getRemoveRedactionOptions = ( extraOption: !isDocumine ? { label: translations.IN_DOSSIER.extraOptionLabel, - checked: redactions[0].isRecommendation && applyToAllDossiers, + checked: applyToAllDossiers, hidden: !isApprover, } : null, @@ -219,7 +220,7 @@ export const getRemoveRedactionOptions = ( extraOption: !isDocumine ? { label: translations.FALSE_POSITIVE.extraOptionLabel, - checked: false, + checked: applyToAllDossiers, hidden: !isApprover, description: translations.FALSE_POSITIVE.extraOptionDescription, } diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts index aa986bee6..2a66f256f 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts @@ -35,8 +35,6 @@ interface NavItem { providers: [dossiersServiceProvider], }) export class EditDossierDialogComponent extends BaseDialogComponent implements AfterViewInit { - readonly #currentUser = getCurrentUser(); - private _dossier: Dossier; readonly roles = Roles; navItems: NavItem[] = []; readonly iconButtonTypes = IconButtonTypes; @@ -47,6 +45,8 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A @ViewChild(EditDossierDictionaryComponent) dictionaryComponent: EditDossierDictionaryComponent; @ViewChild(EditDossierTeamComponent) membersComponent: EditDossierTeamComponent; @ViewChild(EditDossierAttributesComponent) attributesComponent: EditDossierAttributesComponent; + readonly #currentUser = getCurrentUser(); + #dossier: Dossier; constructor( readonly iqserPermissionsService: IqserPermissionsService, @@ -61,13 +61,13 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A readonly configService: ConfigService, ) { super(_dialogRef, true); - this.dossier$ = this._dossiersService.getEntityChanged$(_data.dossierId).pipe( + this.dossier$ = this._dossiersService.getEntityChanged$(this._data.dossierId).pipe( tap(dossier => { - this._dossier = dossier; + this.#dossier = dossier; this._initializeNavItems(); }), ); - this.activeNav = _data.section || 'dossierInfo'; + this.activeNav = this._data.section || 'dossierInfo'; } get activeNavItem(): NavItem { @@ -94,11 +94,11 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A get showActionButtons(): boolean { return ( - (['dossierDictionary'].includes(this.activeNav) && this._permissionsService.canEditDossierDictionary(this._dossier)) || + (['dossierDictionary'].includes(this.activeNav) && this._permissionsService.canEditDossierDictionary(this.#dossier)) || (['members'].includes(this.activeNav) && this.#currentUser.isManager && this.iqserPermissionsService.has(Roles.dossiers.edit)) || - this._permissionsService.canEditDossier(this._dossier) + this._permissionsService.canEditDossier(this.#dossier) ); } @@ -115,7 +115,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A } ngAfterViewInit() { - if (!this._dossier.ownerId) { + if (!this.#dossier.ownerId) { this._toaster.error(_('edit-dossier-dialog.missing-owner')); } } @@ -126,7 +126,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A this._loadingService.stop(); if (result.success) { - this._toaster.success(_('edit-dossier-dialog.change-successful'), { params: { dossierName: this._dossier.dossierName } }); + this._toaster.success(_('edit-dossier-dialog.change-successful'), { params: { dossierName: this.#dossier.dossierName } }); } if (result.success && options?.closeAfterSave) { @@ -159,21 +159,21 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A key: 'dossierInfo', title: _('edit-dossier-dialog.nav-items.general-info'), sideNavTitle: _('edit-dossier-dialog.nav-items.dossier-info'), - readonly: !this._dossier.isActive || !this._permissionsService.canEditDossier(this._dossier), + readonly: !this.#dossier.isActive || !this._permissionsService.canEditDossier(this.#dossier), helpModeKey: 'edit_dossier_dossier_info_DIALOG', }, { key: 'downloadPackage', title: _('edit-dossier-dialog.nav-items.choose-download'), sideNavTitle: _('edit-dossier-dialog.nav-items.download-package'), - readonly: !this._permissionsService.canEditDossier(this._dossier), + readonly: !this._permissionsService.canEditDossier(this.#dossier), helpModeKey: 'edit_dossier_download_package_DIALOG', }, { key: 'dossierDictionary', sideNavTitle: _('edit-dossier-dialog.nav-items.dictionary'), title: _('edit-dossier-dialog.nav-items.dossier-dictionary'), - readonly: !this._permissionsService.canEditDossierDictionary(this._dossier), + readonly: !this._permissionsService.canEditDossierDictionary(this.#dossier), helpModeKey: 'edit_dossier_dossier_dictionary_DIALOG', hide: this.configService.values.IS_DOCUMINE, }, @@ -181,13 +181,13 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A key: 'members', title: _('edit-dossier-dialog.nav-items.team-members'), sideNavTitle: _('edit-dossier-dialog.nav-items.members'), - readonly: !this._permissionsService.canEditTeamMembers(), + readonly: !this._permissionsService.canEditTeamMembers(this.#dossier), helpModeKey: 'edit_dossier_members_DIALOG', }, { key: 'dossierAttributes', title: _('edit-dossier-dialog.nav-items.dossier-attributes'), - readonly: !this._permissionsService.canEditDossierAttributes(this._dossier), + readonly: !this._permissionsService.canEditDossierAttributes(this.#dossier), helpModeKey: 'edit_dossier_dossier_attributes_DIALOG', }, ]; diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.html b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.html index 8eedc9815..b830dc2c3 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.html +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.html @@ -45,13 +45,12 @@
- +
@@ -64,7 +63,7 @@ > -
+
- +
diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.scss b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.scss index 919436a78..17e669f30 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.scss +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.scss @@ -11,10 +11,6 @@ form { flex-direction: column; } -.search-container { - margin-top: 16px; -} - redaction-team-members { margin-top: -4px; display: block; diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.ts index a8f2653b6..2d330d904 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component.ts @@ -19,26 +19,26 @@ import { EditDossierSaveResult, EditDossierSectionInterface } from '../edit-doss changeDetection: ChangeDetectionStrategy.OnPush, }) export class EditDossierTeamComponent implements EditDossierSectionInterface, OnChanges { - readonly #userService = inject(UserService); - readonly #dossiersService = inject(DossiersService); - readonly #permissionsService = inject(PermissionsService); - readonly #filesService = inject(FilesService); form = this.#getForm(); - readonly #formValue$ = this.form.valueChanges; searchQuery = ''; @Input() dossier: Dossier; membersSelectOptions: string[] = []; + readonly isDocumine = getConfig().IS_DOCUMINE; + readonly #userService = inject(UserService); readonly ownersSelectOptions = this.#userService.all.filter(u => u.isManager).map(m => m.id); + readonly #dossiersService = inject(DossiersService); + readonly #permissionsService = inject(PermissionsService); + readonly #filesService = inject(FilesService); + readonly #formValue$ = this.form.valueChanges; readonly selectedReviewers$ = this.#formValue$.pipe(map(v => v.members.filter(m => !v.approvers.includes(m)))); readonly selectedApprovers$ = this.#formValue$.pipe(map(v => v.approvers)); - readonly isDocumine = getConfig().IS_DOCUMINE; get valid(): boolean { return this.form.valid; } get disabled() { - return !this.#permissionsService.canEditTeamMembers() || !this.form.get('owner').value; + return !this.#permissionsService.canEditTeamMembers(this.dossier) || !this.form.get('owner').value; } get hasOwner() { @@ -175,7 +175,7 @@ export class EditDossierTeamComponent implements EditDossierSectionInterface, On #resetForm() { this.form.reset( { - owner: { value: this.dossier.ownerId, disabled: !this.#permissionsService.canEditTeamMembers() }, + owner: { value: this.dossier.ownerId, disabled: !this.#permissionsService.canEditTeamMembers(this.dossier) }, approvers: this.#sortByName([...this.dossier.approverIds]), members: this.#sortByName([...this.dossier.memberIds]), } as unknown, diff --git a/apps/red-ui/src/app/modules/shared/components/type-filter/type-filter.component.scss b/apps/red-ui/src/app/modules/shared/components/type-filter/type-filter.component.scss index 93aa005d7..9d3450c57 100644 --- a/apps/red-ui/src/app/modules/shared/components/type-filter/type-filter.component.scss +++ b/apps/red-ui/src/app/modules/shared/components/type-filter/type-filter.component.scss @@ -12,5 +12,6 @@ height: 16px; margin-right: 8px; opacity: 50%; + line-height: 16px; } } diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index 456ec57a5..05e98f73d 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -18,6 +18,7 @@ import { FilesMapService } from '@services/files/files-map.service'; import { Roles } from '@users/roles'; import { UserPreferenceService } from '@users/user-preference.service'; import { UserService } from '@users/user.service'; +import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; @Injectable({ providedIn: 'root' }) export class PermissionsService { @@ -29,6 +30,7 @@ export class PermissionsService { private readonly _featuresService: FeaturesService, private readonly _userPreferenceService: UserPreferenceService, private readonly _iqserPermissionsService: IqserPermissionsService, + private readonly _dossierTemplatesService: DossierTemplatesService, ) {} get #userId(): string { @@ -313,8 +315,9 @@ export class PermissionsService { return dossier.isActive && this.isOwner(dossier) && this._iqserPermissionsService.has(Roles.dossierAttributes.write); } - canEditTeamMembers(): boolean { - return this._iqserPermissionsService.has(Roles.dossiers.edit) && this.isManager(); + canEditTeamMembers(dossier: Dossier): boolean { + const dossierTemplate = this._dossierTemplatesService.find(dossier.dossierTemplateId); + return this._iqserPermissionsService.has(Roles.dossiers.edit) && this.isManager() && dossierTemplate.isActive; } isAdmin(): boolean { diff --git a/apps/red-ui/src/app/users/user-preference.service.ts b/apps/red-ui/src/app/users/user-preference.service.ts index 27f412574..6f2f85211 100644 --- a/apps/red-ui/src/app/users/user-preference.service.ts +++ b/apps/red-ui/src/app/users/user-preference.service.ts @@ -1,5 +1,7 @@ import { Injectable } from '@angular/core'; import { IqserUserPreferenceService, ListingMode } from '@iqser/common-ui'; +import { RedactOrHintOption, RemoveRedactionOption } from '../modules/file-preview/utils/dialog-options'; +import { SystemDefaultOption, SystemDefaultType } from '../modules/account/utils/dialog-defaults'; export const PreferencesKeys = { dossierRecent: 'Dossier-Recent', @@ -10,6 +12,16 @@ export const PreferencesKeys = { loadAllAnnotationsWarning: 'Load-All-Annotations-Warning', openScmDialogByDefault: 'Open-Structured-Component-Management-By-Default', tableExtractionType: 'Table-Extraction-Type', + addRedactionDefaultOption: 'Add-Redaction-Default', + addHintDefaultOption: 'Add-Hint-Default', + removeRedactionDefaultOption: 'Remove-Redaction-Default', + removeRecommendationDefaultOption: 'Remove-Recommendation-Default', + removeHintDefaultOption: 'Remove-Hint-Default', + addRedactionDefaultExtraOption: 'Add-Redaction-Default-Extra', + addHintDefaultExtraOption: 'Add-Hint-Default-Extra', + removeRedactionDefaultExtraOption: 'Remove-Redaction-Default-Extra', + removeRecommendationDefaultExtraOption: 'Remove-Recommendation-Default-Extra', + removeHintDefaultExtraOption: 'Remove-Hint-Default-Extra', } as const; @Injectable({ @@ -77,4 +89,94 @@ export class UserPreferenceService extends IqserUserPreferenceService { getTableExtractionType() { return this._getAttribute(PreferencesKeys.tableExtractionType, 'EXPERIMENTAL_IF_MISSING'); } + + getAddRedactionDefaultOption(): RedactOrHintOption | SystemDefaultType { + return this._getAttribute(PreferencesKeys.addRedactionDefaultOption, SystemDefaultOption.SYSTEM_DEFAULT) as + | RedactOrHintOption + | SystemDefaultType; + } + + async saveAddRedactionDefaultOption(defaultOption: RedactOrHintOption | SystemDefaultType): Promise { + await this.save(PreferencesKeys.addRedactionDefaultOption, defaultOption.toString()); + } + + getAddHintDefaultOption(): RedactOrHintOption | SystemDefaultType { + return this._getAttribute(PreferencesKeys.addHintDefaultOption, SystemDefaultOption.SYSTEM_DEFAULT) as + | RedactOrHintOption + | SystemDefaultType; + } + + async saveAddHintDefaultOption(defaultOption: RedactOrHintOption | SystemDefaultType): Promise { + await this.save(PreferencesKeys.addHintDefaultOption, defaultOption.toString()); + } + + getRemoveRedactionDefaultOption(): RemoveRedactionOption | SystemDefaultType { + return this._getAttribute(PreferencesKeys.removeRedactionDefaultOption, SystemDefaultOption.SYSTEM_DEFAULT) as + | RemoveRedactionOption + | SystemDefaultType; + } + + async saveRemoveRedactionDefaultOption(defaultOption: RemoveRedactionOption | SystemDefaultType): Promise { + await this.save(PreferencesKeys.removeRedactionDefaultOption, defaultOption.toString()); + } + + getRemoveRecommendationDefaultOption(): RemoveRedactionOption | SystemDefaultType { + return this._getAttribute(PreferencesKeys.removeRecommendationDefaultOption, SystemDefaultOption.SYSTEM_DEFAULT) as + | RemoveRedactionOption + | SystemDefaultType; + } + + async saveRemoveRecommendationDefaultOption(defaultOption: RemoveRedactionOption | SystemDefaultType): Promise { + await this.save(PreferencesKeys.removeRecommendationDefaultOption, defaultOption.toString()); + } + + getRemoveHintDefaultOption(): RemoveRedactionOption | SystemDefaultType { + return this._getAttribute(PreferencesKeys.removeHintDefaultOption, SystemDefaultOption.SYSTEM_DEFAULT) as + | RemoveRedactionOption + | SystemDefaultType; + } + + async saveRemoveHintDefaultOption(defaultOption: RemoveRedactionOption | SystemDefaultType): Promise { + await this.save(PreferencesKeys.removeHintDefaultOption, defaultOption.toString()); + } + + getAddRedactionDefaultExtraOption(): string { + return this._getAttribute(PreferencesKeys.addRedactionDefaultExtraOption, 'undefined'); + } + + async saveAddRedactionDefaultExtraOption(defaultOption: boolean | string): Promise { + await this.save(PreferencesKeys.addRedactionDefaultExtraOption, defaultOption.toString()); + } + + getAddHintDefaultExtraOption(): string { + return this._getAttribute(PreferencesKeys.addHintDefaultExtraOption, 'undefined'); + } + + async saveAddHintDefaultExtraOption(defaultOption: boolean | string): Promise { + await this.save(PreferencesKeys.addHintDefaultExtraOption, defaultOption.toString()); + } + + getRemoveRedactionDefaultExtraOption(): string { + return this._getAttribute(PreferencesKeys.removeRedactionDefaultExtraOption, 'undefined'); + } + + async saveRemoveRedactionDefaultExtraOption(defaultOption: boolean | string): Promise { + await this.save(PreferencesKeys.removeRedactionDefaultExtraOption, defaultOption.toString()); + } + + getRemoveHintDefaultExtraOption(): string { + return this._getAttribute(PreferencesKeys.removeHintDefaultExtraOption, 'undefined'); + } + + async saveRemoveHintDefaultExtraOption(defaultOption: boolean | string): Promise { + await this.save(PreferencesKeys.removeHintDefaultExtraOption, defaultOption.toString()); + } + + getRemoveRecommendationDefaultExtraOption(): string { + return this._getAttribute(PreferencesKeys.removeRecommendationDefaultExtraOption, 'undefined'); + } + + async saveRemoveRecommendationDefaultExtraOption(defaultOption: boolean | string): Promise { + await this.save(PreferencesKeys.removeRecommendationDefaultExtraOption, defaultOption.toString()); + } } diff --git a/apps/red-ui/src/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts index b6b086c2e..a50db47d8 100644 --- a/apps/red-ui/src/app/utils/functions.ts +++ b/apps/red-ui/src/app/utils/functions.ts @@ -134,7 +134,6 @@ export function calcTextWidthInPixels(text: string): number { return width; } -export function addPaddingToArray(array: T[], emptyElement: T) { - array.push(emptyElement); - array.splice(0, 0, emptyElement); +export function stringToBoolean(str: string): boolean { + return str === 'true'; } diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 2414c3a9f..ccb2c7e21 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -681,6 +681,25 @@ } }, "dev-mode": "DEV", + "dialog-defaults-form": { + "extra-option-label": "Apply to all active and future dossiers", + "hint": { + "add-dialog": "Add hint", + "remove-dialog": "Remove hint", + "title": "Hint" + }, + "recommendation": { + "remove-dialog": "Remove recommendation", + "title": "Recommendation" + }, + "redaction": { + "add-dialog": "Redact text", + "remove-dialog": "Remove redaction", + "title": "Redaction" + }, + "system-default": "Use system default", + "title": "Dialog defaults" + }, "dictionary": "Type", "dictionary-overview": { "compare": { diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 14f4539d3..f7cf520de 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -681,6 +681,25 @@ } }, "dev-mode": "DEV", + "dialog-defaults-form": { + "extra-option-label": "", + "hint": { + "add-dialog": "", + "remove-dialog": "", + "title": "" + }, + "recommendation": { + "remove-dialog": "", + "title": "" + }, + "redaction": { + "add-dialog": "", + "remove-dialog": "", + "title": "" + }, + "system-default": "", + "title": "" + }, "dictionary": "Type", "dictionary-overview": { "compare": { diff --git a/libs/red-domain/src/lib/dictionaries/dictionary.model.ts b/libs/red-domain/src/lib/dictionaries/dictionary.model.ts index f1d35940c..4c33e7840 100644 --- a/libs/red-domain/src/lib/dictionaries/dictionary.model.ts +++ b/libs/red-domain/src/lib/dictionaries/dictionary.model.ts @@ -19,6 +19,7 @@ export class Dictionary extends Entity implements IDictionary { readonly hasDictionary?: boolean; readonly systemManaged?: boolean; readonly dossierDictionaryOnly?: boolean; + readonly experimental?: boolean; entries: List; falsePositiveEntries: List; @@ -47,6 +48,7 @@ export class Dictionary extends Entity implements IDictionary { this.hasDictionary = entity.hasDictionary; this.systemManaged = entity.systemManaged; this.dossierDictionaryOnly = entity.dossierDictionaryOnly; + this.experimental = entity.experimental; } get id(): string { diff --git a/libs/red-domain/src/lib/dictionaries/dictionary.ts b/libs/red-domain/src/lib/dictionaries/dictionary.ts index d5bcfb254..d146393bf 100644 --- a/libs/red-domain/src/lib/dictionaries/dictionary.ts +++ b/libs/red-domain/src/lib/dictionaries/dictionary.ts @@ -60,4 +60,6 @@ export interface IDictionary { readonly systemManaged?: boolean; readonly dossierDictionaryOnly?: boolean; + + readonly experimental?: boolean; }