spring-petclinic / spring-petclinic-angular

Angular 16 version of the Spring Petclinic sample application (frontend)
205 stars 499 forks source link

Update input validation rules and messages in HTML templates to be aligned with the openAPI definition #142

Closed Holger-Mayer closed 2 months ago

Holger-Mayer commented 2 months ago

Align validation rules of add and edit forms to Rest OpenAPI validation rules

The pet clinic rest api defines validation rules for component properties (see here).

The pet clinic angular application defines validation rules for fields (bound to the previously cited component properties) within the angular components \-add.component.html and \-edit.component.html files.

Currently, there is a lack of alignment among these. Some definitions in the angular application are different, and some are not defined at all.

Overview

The following tables document the situation before this change

Field is the name of the openAPI component property Rule is the kind of rule enforced openAPI is the validation rule value openAPI enforces Angular Add is the validation rule the Angluar front end enforces in add functionality Angular Edit is the validation rule then Angular front end enforces in the edit functionality

Specialty

Field Rule openAPI Angular Add Angular Edit
name minLength 1
name maxLength 80
name required + +

Owner

Field Rule openAPI Angular Add Angular Edit
firstName minLength 1 2 2
firstName maxLength 30
firstName pattern \^[a-zA-Z]*$
firstName required + + +
lastName minLength 1 2 2
lastName maxLength 30
lastName pattern \^[a-zA-Z]*$
lastName required + + + +
address minLength 1
address maxLength 255
address required + +
city minLength 1
city maxLength 80
city required + + +
telephone minLength 1
telephone maxLength 20 10 10
telephone pattern \^[0-9]*$ \^[0-9]{0,10}$ \^[0-9]{0,10}$
telephone required + + +

Pet

Field Rule openAPI Angular Add Angular Edit
name maxLength 30
name required + +
birthDate required + + +

Vet

Field Rule openAPI Angular Add Angular Edit
firstName minLength 1 2
firstName maxLength 30
firstName pattern \^[a-zA-Z]*$
firstName required + +
lastName minLength 1 2
lastName maxLength 30
lastName required + +
lastName pattern \^[a-zA-Z]*$
specialties - -
specialties required +

Visit

Field Rule openAPI Angular Add Angular Edit
date - -
description minLength 1
description maxLength 255
description required + + +

PetType

Field Rule openAPI Angular Add Angular Edit
name minLength 1
name maxLength 80
name required +

User

User is currently not implemented in the angular front end.

Field Rule openAPI Angular Add Angular Edit
username minLength 1 NA NA
username maxLength 80 NA NA
username required + NA NA
password minLength 1 NA NA
pasword maxLength 80 NA NA

NA - not applicable

Role

Role is currently not implemented in the angular front end.

Field Rule openAPI Angular Add Angular Edit
name minLength 1 NA NA
name maxLength 80 NA NA
name required + NA NA

NA - not applicable

Note

An anomaly is defined within the openAPI validation.

We define some fields with a minimal length but we do not have a pattern validation rule defined. This enables the user of the api to define i.e. names with all blank characters. Here in the future, the openApi description should define pattern validation rules.

In the meantime, it is assumed, that any required name field with a length > 0 may not start with a character other than [A-za-z]. This is implemented in this pull request.

What did change?

The input field requirement rules are adjusted in the add-component.html or edit.component.html files so that they follow the openAPI rules with one exception.

Where names are defined the leading character must be a letter or digit so that all spaces names are not allowed. The rule used here is pattern="\^[A-Za-z0-9].{0,N}$ with N the maxlength - 1;

Example

From

 <input type="text" class="form-control" id="firstName" [(ngModel)]="vet.firstName" minlength="2" required name="firstName" #firstName="ngModel"/>

to

 <input type="text" class="form-control" id="firstName" [(ngModel)]="vet.firstName"  minlength="1" maxlength="30" pattern="^[A-Za-z].{0,29}$"  required name="firstName" #firstName="ngModel"/>

Then the help block for the fields are adjusted

Example From

     <span class="help-block" *ngIf="(vetForm.submitted && firstName.hasError('required')) || (firstName.dirty && firstName.hasError('required'))">First name is required</span>
          <span class="help-block" *ngIf="firstName.dirty && firstName.hasError('minlength')">First name must be at least 2 characters long</span>

To

         <span class="help-block" *ngIf="firstName.dirty && firstName.hasError('maxlength')">First Name may be only 30 characters long</span>
            <span class="help-block" *ngIf="firstName.dirty && firstName.hasError('minlength')">First Name must be at least 1 characters long</span>
             <span class="help-block" *ngIf="firstName.dirty && firstName.hasError('pattern')">First Name may not start with a space character</span>

And finally, the validation state enables the add/save button.

Example

From

  <button class="btn btn-default" type="submit">Save Vet</button>

To

 <button class="btn btn-default" type="submit"  [disabled]="!vetForm.valid">Save Vet</button>

Extra

The specialty add function displayed error messages in the wrong color (grey insted of red).The reason was a missing definition.

[class.has-success]="specialityName.dirty && specialityName.valid" [class.has-error]="specialityName.dirty && !specialityName.valid"

This was corrected in the file specialty-add.component.html too.

arey commented 2 months ago

Thank you @Holger-Mayer for this precise comparison between the backend and the frontend. And the fix. This is a great job. I'm aware to add some missing pattern rules to the OpenAPI specification. With @alexandre-touret we could create an issue.

arey commented 2 months ago

Thanks again @Holger-Mayer for your PR. Don't hesitate to submit other enhancements. You are most welcome