mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merged PR 1860: #5157 Return Input Ean Validation
- feat(oms-return-review): implement return review feature - Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop - Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop - feat(oms-return-process, ui-input-controls): improve error feedback for EAN input and adjust text field container spacing Refs: #5157
This commit is contained in:
committed by
Lorenz Hilpert
parent
0134f8dbf5
commit
6f80159281
@@ -8,12 +8,15 @@
|
||||
<ui-text-field-container>
|
||||
<ui-text-field size="small" class="min-w-[22.875rem]">
|
||||
<input
|
||||
#inputRef
|
||||
uiInputControl
|
||||
class="isa-text-body-2-bold placeholder:isa-text-body-2-bold"
|
||||
placeholder="EAN eingeben / scannen"
|
||||
type="text"
|
||||
[formControl]="control"
|
||||
(cleared)="resetProduct()"
|
||||
(blur)="control.updateValueAndValidity()"
|
||||
(keydown.enter)="check()"
|
||||
/>
|
||||
@if (!p) {
|
||||
<button
|
||||
@@ -32,17 +35,18 @@
|
||||
</ui-text-field>
|
||||
|
||||
<ui-text-field-errors>
|
||||
@if (!p && status().hasResult === false) {
|
||||
@if (!p && status().hasResult === false && !control.invalid) {
|
||||
<span>Kein Artikel gefunden</span>
|
||||
}
|
||||
|
||||
@if (control.invalid && control.touched && !control.dirty) {
|
||||
@if (control.invalid && control.touched) {
|
||||
<span>Die eingegebene EAN ist ungültig</span>
|
||||
}
|
||||
</ui-text-field-errors>
|
||||
</ui-text-field-container>
|
||||
|
||||
<shared-scanner-button
|
||||
class="self-start"
|
||||
[disabled]="!!control?.value"
|
||||
(scan)="onScan($event)"
|
||||
>
|
||||
|
||||
@@ -2,9 +2,11 @@ import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
effect,
|
||||
ElementRef,
|
||||
inject,
|
||||
input,
|
||||
signal,
|
||||
viewChild,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
AbstractControl,
|
||||
@@ -19,7 +21,7 @@ import {
|
||||
ReturnProcessProductQuestion,
|
||||
ReturnProcessStore,
|
||||
} from '@isa/oms/data-access';
|
||||
import { IconButtonComponent, TextButtonComponent } from '@isa/ui/buttons';
|
||||
import { TextButtonComponent } from '@isa/ui/buttons';
|
||||
import {
|
||||
InputControlDirective,
|
||||
TextFieldClearComponent,
|
||||
@@ -36,6 +38,7 @@ import { provideIcons } from '@ng-icons/core';
|
||||
import { isaActionScanner } from '@isa/icons';
|
||||
import { ScannerButtonComponent } from '@isa/shared/scanner';
|
||||
import { ProductRouterLinkDirective } from '@isa/shared/product-router-link';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
const eanValidator: ValidatorFn = (
|
||||
control: AbstractControl,
|
||||
@@ -61,7 +64,6 @@ const eanValidator: ValidatorFn = (
|
||||
TextFieldComponent,
|
||||
TextFieldClearComponent,
|
||||
ProductImageDirective,
|
||||
IconButtonComponent,
|
||||
ScannerButtonComponent,
|
||||
ProductRouterLinkDirective,
|
||||
],
|
||||
@@ -71,11 +73,14 @@ export class ReturnProcessProductQuestionComponent {
|
||||
#returnProcessStore = inject(ReturnProcessStore);
|
||||
#catalogueSearchService = inject(CatalougeSearchService);
|
||||
|
||||
inputElement = viewChild<ElementRef<HTMLInputElement>>('inputRef');
|
||||
|
||||
returnProcessId = input.required<number>();
|
||||
|
||||
question = input.required<ReturnProcessProductQuestion>();
|
||||
|
||||
control = new FormControl<string>('', [Validators.required, eanValidator]);
|
||||
valueChanges = toSignal(this.control.valueChanges);
|
||||
|
||||
product = signal<Product | undefined>(undefined);
|
||||
status = signal<{ fetching: boolean; hasResult?: boolean }>({
|
||||
@@ -83,6 +88,14 @@ export class ReturnProcessProductQuestionComponent {
|
||||
});
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
const valueChanged = this.valueChanges();
|
||||
if (valueChanged) {
|
||||
this.control.setErrors(null);
|
||||
this.status.set({ fetching: false, hasResult: undefined });
|
||||
}
|
||||
});
|
||||
|
||||
effect(() => {
|
||||
const product = this.#returnProcessStore.entityMap()[
|
||||
this.returnProcessId()
|
||||
@@ -91,6 +104,8 @@ export class ReturnProcessProductQuestionComponent {
|
||||
if (product) {
|
||||
this.control.setValue(product.ean);
|
||||
this.product.set(product);
|
||||
} else {
|
||||
this.inputElement()?.nativeElement?.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -101,6 +116,7 @@ export class ReturnProcessProductQuestionComponent {
|
||||
this.returnProcessId(),
|
||||
this.question().key,
|
||||
);
|
||||
this.inputElement()?.nativeElement?.focus();
|
||||
}
|
||||
|
||||
onScan(value: string | null) {
|
||||
@@ -114,6 +130,7 @@ export class ReturnProcessProductQuestionComponent {
|
||||
pipe(
|
||||
filter(() => this.control.valid),
|
||||
tap(() => {
|
||||
this.control.updateValueAndValidity();
|
||||
this.status.set({ fetching: true, hasResult: undefined });
|
||||
}),
|
||||
switchMap(() =>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
.ui-text-field-container {
|
||||
@apply flex flex-col gap-1 items-start justify-center;
|
||||
@apply flex flex-col items-start justify-center;
|
||||
|
||||
&:has(.ui-text-field-errors > *) {
|
||||
@apply gap-1;
|
||||
|
||||
.ui-text-field {
|
||||
@apply border-isa-accent-red;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user