From 6ca9747180b2dfc5172fe4e9f0a10c94406e25d4 Mon Sep 17 00:00:00 2001 From: filippo-ferrari Date: Tue, 10 Sep 2024 19:34:04 +0200 Subject: [PATCH] feat: validation & improvements --- .../munera/views/settings/SettingsView.java | 90 +++++++++++++------ 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/application/munera/views/settings/SettingsView.java b/src/main/java/com/application/munera/views/settings/SettingsView.java index 063cc1c..de58130 100644 --- a/src/main/java/com/application/munera/views/settings/SettingsView.java +++ b/src/main/java/com/application/munera/views/settings/SettingsView.java @@ -1,5 +1,6 @@ package com.application.munera.views.settings; +import com.application.munera.data.User; import com.application.munera.services.UserService; import com.application.munera.views.MainLayout; import com.vaadin.flow.component.button.Button; @@ -7,16 +8,20 @@ import com.vaadin.flow.component.dependency.Uses; import com.vaadin.flow.component.formlayout.FormLayout; import com.vaadin.flow.component.icon.Icon; import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.notification.NotificationVariant; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.textfield.EmailField; import com.vaadin.flow.component.textfield.PasswordField; import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.ValidationException; import com.vaadin.flow.router.BeforeEnterEvent; import com.vaadin.flow.router.BeforeEnterObserver; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import jakarta.annotation.security.PermitAll; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.orm.ObjectOptimisticLockingFailureException; import org.springframework.security.core.userdetails.UsernameNotFoundException; @PageTitle("Settings") @@ -27,59 +32,88 @@ public class SettingsView extends VerticalLayout implements BeforeEnterObserver private final UserService userService; - private TextField firstNameField; - private TextField lastNameField; - private PasswordField passwordField; - private TextField monthlyIncomeField; - private EmailField emailField; + private TextField firstName; + private TextField lastName; + private PasswordField password; + private TextField monthlyIncome; + private EmailField email; + private final BeanValidationBinder binder; + private final Button save = new Button("Save"); + private final User loggedInUser; @Autowired public SettingsView(UserService userService) { this.userService = userService; createForm(); + + loggedInUser = userService.getLoggedInUser().orElseThrow(() -> new UsernameNotFoundException("User not found")); + + binder = new BeanValidationBinder<>(User.class); + // Bind fields. This is where you'd define e.g. validation rules + binder.bindInstanceFields(this); + binder.forField(firstName) + .asRequired("First name is required") + .bind(User::getFirstName, User::setFirstName); + + binder.forField(lastName) + .asRequired("Last name is required") + .bind(User::getLastName, User::setLastName); + + binder.forField(password) + .asRequired("Password is required") + .bind(User::getPassword, User::setPassword); + + save.addClickListener(e -> { + try { + binder.writeBean(this.loggedInUser); + this.saveUserData(); + Notification.show("User details updated successfully"); + } catch (ObjectOptimisticLockingFailureException exception) { + Notification n = Notification.show( + "Error updating the data. Somebody else has updated the record while you were making changes."); + n.setPosition(Notification.Position.MIDDLE); + n.addThemeVariants(NotificationVariant.LUMO_ERROR); + } catch (ValidationException validationException) { + Notification.show("Failed to update the user. Check again that all values are valid"); + } + }); } private void createForm() { FormLayout formLayout = new FormLayout(); - firstNameField = new TextField("First Name"); - lastNameField = new TextField("Last Name"); - passwordField = new PasswordField("Password"); - emailField = new EmailField("Email"); - monthlyIncomeField = new TextField("Monthly Income"); + firstName = new TextField("First Name"); + lastName = new TextField("Last Name"); + password = new PasswordField("Password"); + email = new EmailField("Email"); + monthlyIncome = new TextField("Monthly Income"); - formLayout.add(firstNameField, lastNameField, passwordField, emailField, monthlyIncomeField); + formLayout.add(firstName, lastName, password, email, monthlyIncome); - Button saveButton = new Button("Save", click -> saveUserData()); - - add(formLayout, saveButton); + add(formLayout, this.save); } private void saveUserData() { - final var loggedInUser = userService.getLoggedInUser().orElseThrow(() -> new UsernameNotFoundException("User not found")); - loggedInUser.setFirstName(firstNameField.getValue()); - loggedInUser.setLastName(lastNameField.getValue()); - loggedInUser.setEmail(emailField.getValue()); - - // Only update the password if it's not empty - if (!passwordField.isEmpty()) { - loggedInUser.setPassword(passwordField.getValue()); - } + loggedInUser.setFirstName(firstName.getValue()); + loggedInUser.setLastName(lastName.getValue()); + loggedInUser.setEmail(email.getValue()); + loggedInUser.setPassword(password.getValue()); // TODO: implement - String monthlyIncome = monthlyIncomeField.getValue(); + String monthlyIncome = this.monthlyIncome.getValue(); userService.updateUserAndConnectedPerson(loggedInUser); - Notification.show("User details updated successfully"); } @Override public void beforeEnter(BeforeEnterEvent event) { final var loggedInUser = userService.getLoggedInUser().orElseThrow(() -> new UsernameNotFoundException("User not found")); - firstNameField.setValue(loggedInUser.getFirstName()); - lastNameField.setValue(loggedInUser.getLastName()); - monthlyIncomeField.setValue(""); + firstName.setValue(loggedInUser.getFirstName()); + lastName.setValue(loggedInUser.getLastName()); + password.setValue(loggedInUser.getPassword()); + email.setValue(loggedInUser.getEmail()); + monthlyIncome.setValue(""); } }