Merge branch 'master' into VM/RED-8882

This commit is contained in:
Valentin Mihai 2024-05-16 18:49:00 +03:00
commit cd3ead7ac2
29 changed files with 666 additions and 75 deletions

View File

@ -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,

View File

@ -0,0 +1,77 @@
<form [formGroup]="form">
<div class="dialog-content">
<h1>{{ 'dialog-defaults-form.title' | translate }}</h1>
<h2>{{ 'dialog-defaults-form.redaction.title' | translate }}</h2>
<div class="iqser-input-group w-450">
<label translate="dialog-defaults-form.redaction.add-dialog"></label>
<mat-form-field>
<mat-select formControlName="addRedaction">
<mat-option *ngFor="let option of redactionAddOptions" [value]="option.value">{{
option.label | translate
}}</mat-option>
</mat-select>
</mat-form-field>
<mat-checkbox *ngIf="displayExtraOptionAddRedaction" formControlName="addRedactionApplyToAll">{{
'dialog-defaults-form.extra-option-label' | translate
}}</mat-checkbox>
</div>
<div class="iqser-input-group w-450">
<label translate="dialog-defaults-form.redaction.remove-dialog"></label>
<mat-form-field>
<mat-select formControlName="removeRedaction">
<mat-option *ngFor="let option of redactionRemoveOptions" [value]="option.value">{{
option.label | translate
}}</mat-option>
</mat-select>
</mat-form-field>
<mat-checkbox *ngIf="displayExtraOptionRemoveRedaction" formControlName="removeRedactionApplyToAll">{{
'dialog-defaults-form.extra-option-label' | translate
}}</mat-checkbox>
</div>
<h2>{{ 'dialog-defaults-form.recommendation.title' | translate }}</h2>
<div class="iqser-input-group w-450">
<label translate="dialog-defaults-form.recommendation.remove-dialog"></label>
<mat-form-field>
<mat-select formControlName="removeRecommendation">
<mat-option *ngFor="let option of recommendationRemoveOptions" [value]="option.value">{{
option.label | translate
}}</mat-option>
</mat-select>
</mat-form-field>
<mat-checkbox *ngIf="displayExtraOptionRemoveRecommendation" formControlName="removeRecommendationApplyToAll">{{
'dialog-defaults-form.extra-option-label' | translate
}}</mat-checkbox>
</div>
<h2>{{ 'dialog-defaults-form.hint.title' | translate }}</h2>
<div class="iqser-input-group w-450">
<label translate="dialog-defaults-form.hint.add-dialog"></label>
<mat-form-field>
<mat-select formControlName="addHint">
<mat-option *ngFor="let option of hintAddOptions" [value]="option.value">{{ option.label | translate }}</mat-option>
</mat-select>
</mat-form-field>
<mat-checkbox *ngIf="displayExtraOptionAddHint" formControlName="addHintApplyToAll">{{
'dialog-defaults-form.extra-option-label' | translate
}}</mat-checkbox>
</div>
<div class="iqser-input-group w-450">
<label translate="dialog-defaults-form.hint.remove-dialog"></label>
<mat-form-field>
<mat-select formControlName="removeHint">
<mat-option *ngFor="let option of removeOptions" [value]="option.value">{{ option.label | translate }}</mat-option>
</mat-select>
</mat-form-field>
<mat-checkbox *ngIf="displayExtraOptionRemoveHint" formControlName="removeHintApplyToAll">{{
'dialog-defaults-form.extra-option-label' | translate
}}</mat-checkbox>
</div>
</div>
<div class="dialog-actions">
<iqser-icon-button
(action)="save()"
[disabled]="!valid || !changed"
[label]="'preferences-screen.actions.save' | translate"
[type]="iconButtonTypes.primary"
></iqser-icon-button>
</div>
</form>

View File

@ -0,0 +1,3 @@
mat-checkbox {
margin: 8px 0 0 8px;
}

View File

@ -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<AsControl<DefaultOptionsForm>> = 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<any> {
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),
});
}
}

View File

@ -1,6 +1,7 @@
<redaction-dialog-defaults *ngIf="currentScreen === screens.WARNING_PREFERENCES && !config.IS_DOCUMINE"></redaction-dialog-defaults>
<form [formGroup]="form">
<div class="dialog-content">
<div *ngIf="currentScreen === screens.WARNING_PREFERENCES" class="content-delimiter"></div>
<div class="dialog-content-left">
<ng-container *ngIf="currentScreen === screens.PREFERENCES">
<div class="iqser-input-group">
@ -22,7 +23,7 @@
</ng-container>
<ng-container *ngIf="currentScreen === screens.WARNING_PREFERENCES">
<p class="warnings-subtitle">{{ 'preferences-screen.warnings-subtitle' | translate }}</p>
<h1>{{ 'preferences-screen.warnings-subtitle' | translate }}</h1>
<p class="warnings-description">{{ 'preferences-screen.warnings-description' | translate }}</p>
<div class="iqser-input-group">

View File

@ -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%;
}

View File

@ -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,
},
];

View File

@ -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();

View File

@ -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<AddHintDialogCo
private readonly _dictionaryService: DictionaryService,
private readonly _iqserPermissionsService: IqserPermissionsService,
private readonly _formBuilder: FormBuilder,
private readonly _userPreferences: UserPreferenceService,
) {
super();
this.#dossier = _activeDossiersService.find(this.data.dossierId);
this.#applyToAllDossiers = this.data.applyToAllDossiers ?? true;
this.#applyToAllDossiers = this.applyToAll;
this.options = getRedactOrHintOptions(
this.#dossier,
this.#applyToAllDossiers,
@ -67,6 +71,28 @@ export class AddHintDialogComponent extends IqserDialogComponent<AddHintDialogCo
return null;
}
get applyToAll() {
return this.isSystemDefault || this._userPreferences.getAddHintDefaultExtraOption() === 'undefined'
? this.data.applyToAllDossiers ?? true
: stringToBoolean(this._userPreferences.getAddHintDefaultExtraOption());
}
get isSystemDefault(): boolean {
return this._userPreferences.getAddHintDefaultOption() === SystemDefaultOption.SYSTEM_DEFAULT;
}
get defaultOption() {
const defaultOption = this.isSystemDefault
? this.#getOption(SystemDefaults.ADD_HINT_DEFAULT)
: this.#getOption(this._userPreferences.getAddHintDefaultOption() as RedactOrHintOption);
this.dictionaryRequest = defaultOption.value === RedactOrHintOptions.IN_DOSSIER;
if (this.dictionaryRequest) {
this.#setDictionaries();
return defaultOption;
}
return defaultOption ?? this.options[0];
}
get disabled() {
return this.#isRss || !this.form.get('dictionary').value;
}
@ -119,7 +145,7 @@ export class AddHintDialogComponent extends IqserDialogComponent<AddHintDialogCo
selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value,
comment: [null],
dictionary: [null],
option: [this.options[0]],
option: [this.defaultOption],
});
}
@ -138,10 +164,14 @@ export class AddHintDialogComponent extends IqserDialogComponent<AddHintDialogCo
}
#resetValues() {
this.#applyToAllDossiers = this.data.applyToAllDossiers ?? true;
this.#applyToAllDossiers = this.applyToAll;
if (!this.#isRss) {
this.options[1].extraOption.checked = this.#applyToAllDossiers;
}
this.form.get('dictionary').setValue(null);
}
#getOption(option: RedactOrHintOption): DetailsRadioOption<RedactOrHintOption> {
return this.options.find(o => o.value === option);
}
}

View File

@ -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();
}

View File

@ -25,16 +25,14 @@
[ngStyle]="{ width: maximumTextAreaWidth + 'px' }"
formControlName="selectedText"
iqserHasScrollbar
name="comment"
name="value"
type="text"
></textarea>
<iqser-circle-button
(action)="toggleEditingSelectedText()"
*ngIf="dictionaryRequest"
[showDot]="initialText !== form.get('selectedText').value && !isEditingSelectedText"
*ngIf="dictionaryRequest && !isEditingSelectedText"
[tooltip]="'redact-text.dialog.content.edit-text' | translate"
[type]="isEditingSelectedText ? 'dark' : 'default'"
[size]="18"
[iconSize]="13"
icon="iqser:edit"
@ -42,12 +40,13 @@
></iqser-circle-button>
<iqser-circle-button
(action)="undoTextChange()"
(action)="undoTextChange(); toggleEditingSelectedText()"
*ngIf="isEditingSelectedText"
[showDot]="initialText !== form.get('selectedText').value"
[tooltip]="'redact-text.dialog.content.revert-text' | translate"
[size]="18"
[iconSize]="13"
class="undo-button"
icon="red:undo"
tooltipPosition="below"
></iqser-circle-button>

View File

@ -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 {

View File

@ -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<string>;
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<RedactOrHintOption> {
return this.options.find(o => o.value === option);
}
}

View File

@ -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<RemoveRedactionOption>[] = 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<RemoveRedactionOption>[] = 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<RemoveRedactionOption> {
return this.options.find(o => o.value === option);
}
}

View File

@ -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;

View File

@ -217,6 +217,10 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
this.missingTypes.add(entry.type);
}
if (dictionary?.experimental && !this.#isIqserDevMode) {
continue;
}
const changeType = this.#getChangeLogType(entry, file);
if (entry.state === EntryStates.PENDING) {

View File

@ -150,10 +150,11 @@ export const getResizeRedactionOptions = (
export const getRemoveRedactionOptions = (
data: RemoveRedactionData,
applyToAllDossiers: boolean,
isDocumine: boolean = false,
): DetailsRadioOption<RemoveRedactionOption>[] => {
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<RemoveRedactionOption>[] = [];
@ -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,
}

View File

@ -35,8 +35,6 @@ interface NavItem {
providers: [dossiersServiceProvider],
})
export class EditDossierDialogComponent extends BaseDialogComponent implements AfterViewInit {
readonly #currentUser = getCurrentUser<User>();
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<User>();
#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',
},
];

View File

@ -45,13 +45,12 @@
</ng-container>
</div>
<ng-container *ngIf="hasOwner && !disabled">
<div *ngIf="hasOwner && !disabled" class="mt-16">
<iqser-input-with-action
(valueChange)="setMembersSelectOptions($event)"
[(value)]="searchQuery"
[placeholder]="'assign-dossier-owner.dialog.search' | translate"
[width]="560"
class="search-container"
></iqser-input-with-action>
<div class="members-list">
@ -64,7 +63,7 @@
>
<iqser-initials-avatar [user]="userId" [withName]="true" size="large"></iqser-initials-avatar>
<div class="actions" *ngIf="!isDocumine">
<div *ngIf="!isDocumine" class="actions">
<div
(click)="!disabled && toggleApprover(userId)"
*ngIf="!disabled || isApprover(userId)"
@ -86,5 +85,5 @@
</div>
</div>
</div>
</ng-container>
</div>
</form>

View File

@ -11,10 +11,6 @@ form {
flex-direction: column;
}
.search-container {
margin-top: 16px;
}
redaction-team-members {
margin-top: -4px;
display: block;

View File

@ -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,

View File

@ -12,5 +12,6 @@
height: 16px;
margin-right: 8px;
opacity: 50%;
line-height: 16px;
}
}

View File

@ -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 {

View File

@ -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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
await this.save(PreferencesKeys.removeHintDefaultOption, defaultOption.toString());
}
getAddRedactionDefaultExtraOption(): string {
return this._getAttribute(PreferencesKeys.addRedactionDefaultExtraOption, 'undefined');
}
async saveAddRedactionDefaultExtraOption(defaultOption: boolean | string): Promise<void> {
await this.save(PreferencesKeys.addRedactionDefaultExtraOption, defaultOption.toString());
}
getAddHintDefaultExtraOption(): string {
return this._getAttribute(PreferencesKeys.addHintDefaultExtraOption, 'undefined');
}
async saveAddHintDefaultExtraOption(defaultOption: boolean | string): Promise<void> {
await this.save(PreferencesKeys.addHintDefaultExtraOption, defaultOption.toString());
}
getRemoveRedactionDefaultExtraOption(): string {
return this._getAttribute(PreferencesKeys.removeRedactionDefaultExtraOption, 'undefined');
}
async saveRemoveRedactionDefaultExtraOption(defaultOption: boolean | string): Promise<void> {
await this.save(PreferencesKeys.removeRedactionDefaultExtraOption, defaultOption.toString());
}
getRemoveHintDefaultExtraOption(): string {
return this._getAttribute(PreferencesKeys.removeHintDefaultExtraOption, 'undefined');
}
async saveRemoveHintDefaultExtraOption(defaultOption: boolean | string): Promise<void> {
await this.save(PreferencesKeys.removeHintDefaultExtraOption, defaultOption.toString());
}
getRemoveRecommendationDefaultExtraOption(): string {
return this._getAttribute(PreferencesKeys.removeRecommendationDefaultExtraOption, 'undefined');
}
async saveRemoveRecommendationDefaultExtraOption(defaultOption: boolean | string): Promise<void> {
await this.save(PreferencesKeys.removeRecommendationDefaultExtraOption, defaultOption.toString());
}
}

View File

@ -134,7 +134,6 @@ export function calcTextWidthInPixels(text: string): number {
return width;
}
export function addPaddingToArray<T>(array: T[], emptyElement: T) {
array.push(emptyElement);
array.splice(0, 0, emptyElement);
export function stringToBoolean(str: string): boolean {
return str === 'true';
}

View File

@ -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": {

View File

@ -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": {

View File

@ -19,6 +19,7 @@ export class Dictionary extends Entity<IDictionary> 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<IDictionary> implements IDictionary {
this.hasDictionary = entity.hasDictionary;
this.systemManaged = entity.systemManaged;
this.dossierDictionaryOnly = entity.dossierDictionaryOnly;
this.experimental = entity.experimental;
}
get id(): string {

View File

@ -60,4 +60,6 @@ export interface IDictionary {
readonly systemManaged?: boolean;
readonly dossierDictionaryOnly?: boolean;
readonly experimental?: boolean;
}