RED-7340 - When a user has entered an invalid page range string, display a read border around the input field

This commit is contained in:
Valentin Mihai 2024-10-21 18:06:01 +03:00
parent 733f811f9d
commit 965166a349
8 changed files with 36 additions and 10 deletions

View File

@ -6,7 +6,7 @@
class="dialog-header heading-l" class="dialog-header heading-l"
></div> ></div>
<div [class.fixed-height]="isRedacted && isImage" class="dialog-content redaction"> <div [class.image-dialog]="isRedacted && isImage" [class.rectangle-dialog]="allRectangles" class="dialog-content redaction">
<div *ngIf="!isImage && redactedTexts.length && !allRectangles" class="iqser-input-group"> <div *ngIf="!isImage && redactedTexts.length && !allRectangles" class="iqser-input-group">
<redaction-selected-annotations-table <redaction-selected-annotations-table
[columns]="tableColumns" [columns]="tableColumns"
@ -107,7 +107,7 @@
formControlName="comment" formControlName="comment"
iqserHasScrollbar iqserHasScrollbar
name="comment" name="comment"
rows="4" rows="2"
type="text" type="text"
></textarea> ></textarea>
</div> </div>

View File

@ -1,8 +1,16 @@
.dialog-content { .dialog-content {
padding-top: 8px; padding-top: 8px;
&.fixed-height { &.rectangle-dialog {
height: 386px; height: 600px;
}
&.image-dialog {
height: 346px;
}
.rectangle-dialog,
.image-dialog {
overflow-y: auto; overflow-y: auto;
} }
} }

View File

@ -263,7 +263,10 @@ export class EditRedactionDialogComponent
disabled: this.isImported, disabled: this.isImported,
}), }),
section: new FormControl<string>({ value: sameSection ? this.annotations[0].section : null, disabled: this.isImported }), section: new FormControl<string>({ value: sameSection ? this.annotations[0].section : null, disabled: this.isImported }),
option: new FormControl<DetailsRadioOption<EditRedactionOption | RectangleRedactOption>>(this.options[0], validatePageRange()), option: new FormControl<DetailsRadioOption<EditRedactionOption | RectangleRedactOption>>(
this.options[0],
validatePageRange(this.data.file.numberOfPages),
),
value: new FormControl<string>(this.allRectangles ? this.annotations[0].value : null), value: new FormControl<string>(this.allRectangles ? this.annotations[0].value : null),
}); });
} }

View File

@ -130,7 +130,7 @@ export class RectangleAnnotationDialog
reason: [null, Validators.required], reason: [null, Validators.required],
comment: [null], comment: [null],
classification: [NON_READABLE_CONTENT], classification: [NON_READABLE_CONTENT],
option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange()], option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange(this.data.file.numberOfPages)],
}); });
} }

View File

@ -112,7 +112,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
readonly redactedTexts = this.data.redactions.map(annotation => annotation.value); readonly redactedTexts = this.data.redactions.map(annotation => annotation.value);
form: UntypedFormGroup = this._formBuilder.group({ form: UntypedFormGroup = this._formBuilder.group({
comment: [null], comment: [null],
option: [this.defaultOption, validatePageRange(true)], option: [this.defaultOption, validatePageRange(this.data.file.numberOfPages, true)],
}); });
readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value))); readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value)));

View File

@ -118,6 +118,7 @@ export const getRectangleRedactOptions = (action: 'add' | 'edit' | 'remove' = 'a
description: translations.multiplePages.extraOptionDescription, description: translations.multiplePages.extraOptionDescription,
placeholder: translations.multiplePages.extraOptionPlaceholder, placeholder: translations.multiplePages.extraOptionPlaceholder,
value: '', value: '',
errorCode: 'invalidRange',
}, },
}, },
]; ];

View File

@ -1,12 +1,26 @@
import { AbstractControl, ValidatorFn } from '@angular/forms'; import { AbstractControl, ValidatorFn } from '@angular/forms';
export const validatePageRange = (allowEmpty = false): ValidatorFn => { export const validatePageRange = (numberOfPages: number, allowEmpty = false): ValidatorFn => {
return (control: AbstractControl): { [key: string]: any } | null => { return (control: AbstractControl): { [key: string]: any } | null => {
const option = control.value; const option = control.value;
if (option?.additionalInput) { if (option?.additionalInput) {
const value = option.additionalInput.value; const value = option.additionalInput.value;
const validRange = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/.test(value); const validRange = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/.test(value);
return validRange || (!value.length && allowEmpty) ? null : { invalidRange: true };
if (!validRange && !(value.length === 0 && allowEmpty)) {
return { invalidRange: true };
}
const ranges = value.split(',');
const isWithinRange = ranges.every(range => {
const [start, end] = range.split('-').map(Number);
if (end) {
return start >= 1 && end <= numberOfPages && start < end;
}
return start >= 1 && start <= numberOfPages;
});
return isWithinRange || (value.length === 0 && allowEmpty) ? null : { invalidRange: true };
} }
return null; return null;
}; };

@ -1 +1 @@
Subproject commit e92bd55cfc37342fec5a246d5cc5226b95fc427e Subproject commit a5d10ad1482a69f100f659bcf2b7f2072a6241c9