Erweiterungen

This commit is contained in:
2025-08-14 17:30:45 +02:00
parent b94921cec0
commit 1b152d3b84
4 changed files with 234 additions and 3 deletions

View File

@@ -32,9 +32,14 @@ public final class MainLayout extends AppLayout {
public MainLayout(SecurityService securityService) { public MainLayout(SecurityService securityService) {
this.securityService = securityService; this.securityService = securityService;
setPrimarySection(Section.DRAWER); setPrimarySection(Section.DRAWER);
addToDrawer(createHeader(), new Scroller(createSideNav()), createUserMenu());
// Only show navigation drawer if user is logged in
//setDrawerOpened(false); if (securityService.isUserLoggedIn()) {
addToDrawer(createHeader(), new Scroller(createSideNav()), createUserMenu());
} else {
// Hide drawer completely for anonymous users
setDrawerOpened(false);
}
} }
private Div createHeader() { private Div createHeader() {

View File

@@ -11,6 +11,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.Clock; import java.time.Clock;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
import org.bson.types.ObjectId;
@Service @Service
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRES_NEW)
@@ -41,4 +42,12 @@ public class CustomerService {
return todoRepository.findAll(); return todoRepository.findAll();
} }
public Customer save(Customer customer) {
return todoRepository.save(customer);
}
public Customer findById(ObjectId id) {
return todoRepository.findById(id).orElse(null);
}
} }

View File

@@ -0,0 +1,198 @@
package de.assecutor.votianlt.pages.view;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.EmailField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.router.BeforeEvent;
import com.vaadin.flow.router.HasUrlParameter;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import de.assecutor.votianlt.model.Customer;
import de.assecutor.votianlt.pages.service.CustomerService;
import jakarta.annotation.security.RolesAllowed;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
@PageTitle("Kunde bearbeiten")
@Route(value = "edit-customer", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@RolesAllowed({"USER","ADMIN"})
public class EditCustomerView extends VerticalLayout implements HasUrlParameter<String> {
private final CustomerService customerService;
private Customer customer;
private final Binder<Customer> binder = new Binder<>(Customer.class);
// Form fields
private final TextField titleField = new TextField("Titel");
private final TextField companyNameField = new TextField("Firmenname");
private final TextField firstnameField = new TextField("Vorname");
private final TextField lastNameField = new TextField("Nachname");
private final TextField telephoneField = new TextField("Telefon");
private final TextField faxField = new TextField("Fax");
private final EmailField mailField = new EmailField("E-Mail");
private final TextField streetField = new TextField("Straße");
private final TextField houseNumberField = new TextField("Hausnummer");
private final TextField addressAdditionField = new TextField("Adresszusatz");
private final TextField zipField = new TextField("PLZ");
private final TextField cityField = new TextField("Stadt");
@Autowired
public EditCustomerView(CustomerService customerService) {
this.customerService = customerService;
setSizeFull();
setPadding(true);
setSpacing(true);
// Center content vertically
setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
// Create main content container
VerticalLayout contentContainer = new VerticalLayout();
contentContainer.setWidth("800px");
contentContainer.setMaxWidth("90%");
contentContainer.setSpacing(true);
contentContainer.setPadding(true);
contentContainer.getStyle().set("background", "var(--lumo-contrast-5pct)");
contentContainer.getStyle().set("border-radius", "var(--lumo-border-radius)");
contentContainer.getStyle().set("box-shadow", "var(--lumo-box-shadow-s)");
// Header
H2 header = new H2("Kunde bearbeiten");
header.getStyle().set("text-align", "center");
header.getStyle().set("margin", "0");
contentContainer.add(header);
// Form layout
FormLayout formLayout = new FormLayout();
formLayout.setResponsiveSteps(
new FormLayout.ResponsiveStep("0", 1)
);
// Add fields to form - all fields in single column
formLayout.add(titleField);
formLayout.add(companyNameField);
formLayout.add(firstnameField);
formLayout.add(lastNameField);
formLayout.add(telephoneField);
formLayout.add(faxField);
formLayout.add(mailField);
formLayout.add(streetField);
formLayout.add(houseNumberField);
formLayout.add(addressAdditionField);
formLayout.add(zipField);
formLayout.add(cityField);
contentContainer.add(formLayout);
// Buttons
HorizontalLayout buttonLayout = new HorizontalLayout();
buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
buttonLayout.setWidthFull();
Button saveButton = new Button("Speichern", e -> saveCustomer());
saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
Button cancelButton = new Button("Abbrechen", e -> navigateBack());
Button deleteButton = new Button("Löschen", e -> deleteCustomer());
deleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR);
buttonLayout.add(saveButton, cancelButton, deleteButton);
buttonLayout.setSpacing(true);
contentContainer.add(buttonLayout);
// Add content container to main layout
add(contentContainer);
// Bind fields to customer properties
setupBinder();
}
private void setupBinder() {
binder.forField(titleField).bind(Customer::getTitle, Customer::setTitle);
binder.forField(companyNameField).bind(Customer::getCompanyName, Customer::setCompanyName);
binder.forField(firstnameField).bind(Customer::getFirstname, Customer::setFirstname);
binder.forField(lastNameField).bind(Customer::getLastName, Customer::setLastName);
binder.forField(telephoneField).bind(Customer::getTelephone, Customer::setTelephone);
binder.forField(faxField).bind(Customer::getFax, Customer::setFax);
binder.forField(mailField).bind(Customer::getMail, Customer::setMail);
binder.forField(streetField).bind(Customer::getStreet, Customer::setStreet);
binder.forField(houseNumberField).bind(Customer::getHouseNumber, Customer::setHouseNumber);
binder.forField(addressAdditionField).bind(Customer::getAddressAddition, Customer::setAddressAddition);
binder.forField(zipField).bind(Customer::getZip, Customer::setZip);
binder.forField(cityField).bind(Customer::getCity, Customer::setCity);
}
@Override
public void setParameter(BeforeEvent event, String parameter) {
try {
ObjectId customerId = new ObjectId(parameter);
customer = customerService.findById(customerId);
if (customer == null) {
Notification.show("Kunde nicht gefunden", 3000, Notification.Position.MIDDLE);
navigateBack();
return;
}
// Load customer data into form
binder.readBean(customer);
} catch (IllegalArgumentException e) {
Notification.show("Ungültige Kunden-ID", 3000, Notification.Position.MIDDLE);
navigateBack();
}
}
private void saveCustomer() {
try {
binder.writeBean(customer);
customerService.save(customer);
Notification.show("Kunde erfolgreich gespeichert", 3000, Notification.Position.MIDDLE);
navigateBack();
} catch (ValidationException e) {
Notification.show("Bitte überprüfen Sie die Eingaben", 3000, Notification.Position.MIDDLE);
}
}
private void deleteCustomer() {
// Show confirmation dialog
Dialog confirmDialog = new Dialog();
confirmDialog.add("Möchten Sie diesen Kunden wirklich löschen?");
HorizontalLayout buttonLayout = new HorizontalLayout();
Button confirmDeleteButton = new Button("Ja, löschen", e -> {
if (customer != null && customer.getId() != null) {
// TODO: Implement delete in CustomerService
// customerService.deleteById(customer.getId());
Notification.show("Kunde erfolgreich gelöscht", 3000, Notification.Position.MIDDLE);
confirmDialog.close();
navigateBack();
}
});
confirmDeleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR);
Button cancelDeleteButton = new Button("Abbrechen", e -> confirmDialog.close());
buttonLayout.add(confirmDeleteButton, cancelDeleteButton);
buttonLayout.setSpacing(true);
confirmDialog.add(buttonLayout);
confirmDialog.open();
}
private void navigateBack() {
getUI().ifPresent(ui -> ui.navigate("customers"));
}
}

View File

@@ -39,6 +39,12 @@ public class ShowCustomersView extends VerticalLayout {
header.setAlignItems(Alignment.CENTER); header.setAlignItems(Alignment.CENTER);
add(header); add(header);
// Add hint text
var hintText = new com.vaadin.flow.component.html.Paragraph("Klicken Sie auf einen Eintrag, um ihn zu bearbeiten.");
hintText.getStyle().set("color", "var(--lumo-secondary-text-color)");
hintText.getStyle().set("font-size", "var(--lumo-font-size-s)");
add(hintText);
// Configure grid columns // Configure grid columns
grid.addColumn(Customer::getCompanyName).setHeader("Firma").setAutoWidth(true).setFlexGrow(1).setSortable(true); grid.addColumn(Customer::getCompanyName).setHeader("Firma").setAutoWidth(true).setFlexGrow(1).setSortable(true);
grid.addColumn(customer -> (customer.getFirstname() != null ? customer.getFirstname() : "") + " " + grid.addColumn(customer -> (customer.getFirstname() != null ? customer.getFirstname() : "") + " " +
@@ -55,6 +61,19 @@ public class ShowCustomersView extends VerticalLayout {
grid.setMultiSort(true); grid.setMultiSort(true);
grid.setSizeFull(); grid.setSizeFull();
// Make grid rows clickable
grid.setSelectionMode(Grid.SelectionMode.SINGLE);
grid.getStyle().set("cursor", "pointer");
// Add click listener to navigate to edit view
grid.addItemClickListener(event -> {
Customer customer = event.getItem();
if (customer != null && customer.getId() != null) {
getUI().ifPresent(ui -> ui.navigate("edit-customer/" + customer.getId().toHexString()));
}
});
add(grid); add(grid);
// Button action // Button action