Align apartment core validation errors (#43)
This commit is contained in:
1 parent
878da155bd
commit
b9f5540394
13 files changed
+454
-56
No files matched your search
@@ -13,9 +13,17 @@ import {
|
||||
} from '../../services/apartment.service';
|
||||
import { ApartmentLegalProfileForm } from '../apartment-legal-profile-form/apartment-legal-profile-form';
|
||||
import { PrivateAreaEditor } from '../private-area-editor/private-area-editor';
|
||||
import { FieldValidationError } from '../../services/http-error-message';
|
||||
|
||||
const requiredFieldsError =
|
||||
'Veuillez remplir tous les champs obligatoires (Nom, Adresse, Prix > 0).';
|
||||
const nameRequiredError = 'Le nom de l’appartement est obligatoire.';
|
||||
const addressRequiredError = 'L’adresse complète est obligatoire.';
|
||||
const purchasePriceError = 'Le prix d’acquisition doit être strictement positif.';
|
||||
type CoreField = 'name' | 'address' | 'purchasePrice';
|
||||
const serverErrorCodes: Record<CoreField, ReadonlySet<string>> = {
|
||||
name: new Set(['not_blank']),
|
||||
address: new Set(['not_blank']),
|
||||
purchasePrice: new Set(['positive']),
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'app-apartment-form',
|
||||
@@ -37,8 +45,10 @@ export class ApartmentForm {
|
||||
readonly apartment = input<Apartment | null>(null);
|
||||
readonly saving = input(false);
|
||||
readonly saveError = input('');
|
||||
readonly saveFieldErrors = input<FieldValidationError[]>([]);
|
||||
readonly closed = output<void>();
|
||||
readonly saved = output<Apartment>();
|
||||
readonly fieldChanged = output<string>();
|
||||
|
||||
readonly apartmentModel = signal<Apartment>({
|
||||
name: '',
|
||||
@@ -50,10 +60,10 @@ export class ApartmentForm {
|
||||
});
|
||||
|
||||
readonly apartmentForm = form(this.apartmentModel, (f) => {
|
||||
required(f.name, { message: requiredFieldsError });
|
||||
required(f.address, { message: requiredFieldsError });
|
||||
required(f.purchasePrice, { message: requiredFieldsError });
|
||||
min(f.purchasePrice, 1, { message: requiredFieldsError });
|
||||
required(f.name, { message: nameRequiredError });
|
||||
required(f.address, { message: addressRequiredError });
|
||||
required(f.purchasePrice, { message: purchasePriceError });
|
||||
min(f.purchasePrice, Number.MIN_VALUE, { message: purchasePriceError });
|
||||
min(f.legalProfile.habitableSurface, 0, {
|
||||
message: 'La surface habitable doit être positive ou nulle.',
|
||||
});
|
||||
@@ -87,7 +97,7 @@ export class ApartmentForm {
|
||||
!this.apartmentModel().address.trim()
|
||||
) {
|
||||
const firstError = this.apartmentForm().errorSummary()[0];
|
||||
this.error.set(firstError?.message ?? requiredFieldsError);
|
||||
this.error.set(firstError?.message ?? this.coreFieldError() ?? nameRequiredError);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,6 +116,48 @@ export class ApartmentForm {
|
||||
this.apartmentModel.update((apartment) => ({ ...apartment, privateAreas }));
|
||||
}
|
||||
|
||||
nameError(): string {
|
||||
return this.fieldError('name', nameRequiredError, this.apartmentForm.name().touched());
|
||||
}
|
||||
|
||||
addressError(): string {
|
||||
return this.fieldError(
|
||||
'address',
|
||||
addressRequiredError,
|
||||
this.apartmentForm.address().touched(),
|
||||
);
|
||||
}
|
||||
|
||||
purchasePriceError(): string {
|
||||
return this.fieldError(
|
||||
'purchasePrice',
|
||||
purchasePriceError,
|
||||
this.apartmentForm.purchasePrice().touched(),
|
||||
);
|
||||
}
|
||||
|
||||
private coreFieldError(): string | null {
|
||||
return this.nameError() || this.addressError() || this.purchasePriceError() || null;
|
||||
}
|
||||
|
||||
private fieldError(path: CoreField, clientMessage: string, touched: boolean): string {
|
||||
if (
|
||||
touched &&
|
||||
((path === 'name' && !this.apartmentModel().name.trim()) ||
|
||||
(path === 'address' && !this.apartmentModel().address.trim()) ||
|
||||
(path === 'purchasePrice' && this.apartmentModel().purchasePrice <= 0))
|
||||
) {
|
||||
return clientMessage;
|
||||
}
|
||||
return this.hasKnownServerError(path) ? clientMessage : '';
|
||||
}
|
||||
|
||||
private hasKnownServerError(field: CoreField): boolean {
|
||||
return this.saveFieldErrors().some(
|
||||
(error) => error.field === field && serverErrorCodes[field].has(error.code),
|
||||
);
|
||||
}
|
||||
|
||||
private resetForm(apartment: Apartment | null): void {
|
||||
this.apartmentModel.set({
|
||||
id: apartment?.id,
|
||||
|
||||
Reference in new issue
Block a user