From 21c81b553f5dbb21c7193a550fa229720efb3318 Mon Sep 17 00:00:00 2001 From: Sven Carstensen Date: Thu, 14 Aug 2025 20:12:55 +0200 Subject: [PATCH] Erweiterungen --- .../java/de/assecutor/votianlt/model/Job.java | 2 - .../pages/service/AppUserService.java | 18 +- .../votianlt/pages/view/AddAppUserView.java | 195 ++++++++++++++++++ .../votianlt/pages/view/AppUserView.java | 153 +++----------- 4 files changed, 238 insertions(+), 130 deletions(-) create mode 100644 src/main/java/de/assecutor/votianlt/pages/view/AddAppUserView.java diff --git a/src/main/java/de/assecutor/votianlt/model/Job.java b/src/main/java/de/assecutor/votianlt/model/Job.java index 600ee93..551581c 100644 --- a/src/main/java/de/assecutor/votianlt/model/Job.java +++ b/src/main/java/de/assecutor/votianlt/model/Job.java @@ -5,11 +5,9 @@ import org.bson.types.ObjectId; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; -import org.springframework.data.annotation.Transient; import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.List; import java.math.BigDecimal; @Data diff --git a/src/main/java/de/assecutor/votianlt/pages/service/AppUserService.java b/src/main/java/de/assecutor/votianlt/pages/service/AppUserService.java index d2d6991..02f3dd0 100644 --- a/src/main/java/de/assecutor/votianlt/pages/service/AppUserService.java +++ b/src/main/java/de/assecutor/votianlt/pages/service/AppUserService.java @@ -3,10 +3,13 @@ package de.assecutor.votianlt.pages.service; import de.assecutor.votianlt.model.AppUser; import de.assecutor.votianlt.repository.AppUserRepository; import de.assecutor.votianlt.security.SecurityService; +import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + @Service @Transactional public class AppUserService { @@ -25,16 +28,17 @@ public class AppUserService { appUser.setErstelltAm(java.time.LocalDateTime.now()); appUser.setAktualisiertAm(java.time.LocalDateTime.now()); - // Set creator and updater if user is logged in - try { - appUser.setErstelltVon(securityService.getCurrentUserId()); - appUser.setAktualisiertVon(securityService.getCurrentUserId()); - } catch (Exception e) { - // User might not be logged in, continue without user ID - } + // Set creator and updater - current user ID is required + ObjectId currentUserId = securityService.getCurrentUserId(); + appUser.setErstelltVon(currentUserId); + appUser.setAktualisiertVon(currentUserId); return appUserRepository.save(appUser); } + public List findAll() { + return appUserRepository.findAll(); + } + } diff --git a/src/main/java/de/assecutor/votianlt/pages/view/AddAppUserView.java b/src/main/java/de/assecutor/votianlt/pages/view/AddAppUserView.java new file mode 100644 index 0000000..9f42aa1 --- /dev/null +++ b/src/main/java/de/assecutor/votianlt/pages/view/AddAppUserView.java @@ -0,0 +1,195 @@ +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.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.html.H2; +import com.vaadin.flow.component.icon.Icon; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.FlexComponent; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +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.PageTitle; +import com.vaadin.flow.router.Route; +import de.assecutor.votianlt.model.AppUser; +import de.assecutor.votianlt.pages.service.AppUserService; +import jakarta.annotation.security.RolesAllowed; +import org.springframework.beans.factory.annotation.Autowired; + +@PageTitle("Neuen App-Nutzer anlegen") +@Route(value = "add-app-user", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class) +@RolesAllowed({"USER","ADMIN"}) +public class AddAppUserView extends VerticalLayout { + + private final AppUserService appUserService; + private final Binder binder = new Binder<>(AppUser.class); + + // Form fields + private final TextField designationField = new TextField("Bezeichnung (HH H 000)"); + private final TextField firstnameField = new TextField("Vorname"); + private final TextField lastnameField = new TextField("Nachname"); + private final TextField phoneField = new TextField("Telefon (Mobil)"); + private final TextField appCodeField = new TextField("App-Code"); + private final TextField emailField = new TextField("E-Mail-Adresse"); + private final ComboBox deviceField = new ComboBox<>("kein Gerät"); + + @Autowired + public AddAppUserView(AppUserService appUserService) { + this.appUserService = appUserService; + 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("600px"); + 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 with title and back button + HorizontalLayout header = new HorizontalLayout(); + header.setAlignItems(FlexComponent.Alignment.CENTER); + header.setSpacing(true); + + H2 title = new H2("Neuen App-Nutzer anlegen"); + title.getStyle().set("margin", "0"); + + Button backButton = new Button("Zurück", new Icon(VaadinIcon.ARROW_LEFT)); + backButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + backButton.addClickListener(e -> navigateBack()); + + header.add(title, backButton); + header.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN); + contentContainer.add(header); + + // Form layout + FormLayout formLayout = new FormLayout(); + formLayout.setResponsiveSteps( + new FormLayout.ResponsiveStep("0", 1) + ); + + // Configure fields + designationField.setPlaceholder("(HH H 000)"); + designationField.setWidthFull(); + + firstnameField.setWidthFull(); + lastnameField.setWidthFull(); + + // Create horizontal layout for firstname and lastname + HorizontalLayout nameLayout = new HorizontalLayout(); + nameLayout.setWidthFull(); + nameLayout.setSpacing(true); + nameLayout.add(firstnameField, lastnameField); + + phoneField.setWidthFull(); + appCodeField.setWidthFull(); + emailField.setWidthFull(); + + // Configure device dropdown + deviceField.setItems("kein Gerät", "iPhone", "Android", "Tablet", "Desktop"); + deviceField.setValue("kein Gerät"); + deviceField.setWidthFull(); + + // Add fields to form + formLayout.add(designationField); + formLayout.add(nameLayout); + formLayout.add(phoneField); + formLayout.add(appCodeField); + formLayout.add(emailField); + formLayout.add(deviceField); + + contentContainer.add(formLayout); + + // Submit button + Button submitButton = new Button("App-Nutzer anlegen", e -> createAppUser()); + submitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + submitButton.setWidthFull(); + contentContainer.add(submitButton); + + // Add content container to main layout + add(contentContainer); + + // Setup binder + setupBinder(); + + // Fill with test data + populateTestData(); + } + + private void setupBinder() { + // Bind fields to AppUser properties + binder.forField(designationField).bind(AppUser::getBezeichnung, AppUser::setBezeichnung); + binder.forField(firstnameField).bind(AppUser::getVorname, AppUser::setVorname); + binder.forField(lastnameField).bind(AppUser::getNachname, AppUser::setNachname); + binder.forField(phoneField).bind(AppUser::getTelefon, AppUser::setTelefon); + binder.forField(appCodeField).bind(AppUser::getAppCode, AppUser::setAppCode); + binder.forField(emailField).bind(AppUser::getEmail, AppUser::setEmail); + binder.forField(deviceField).bind(AppUser::getGeraet, AppUser::setGeraet); + } + + private void createAppUser() { + try { + // Create new AppUser object + AppUser newAppUser = new AppUser(); + binder.writeBean(newAppUser); + + // Save to MongoDB collection + appUserService.createAppUser(newAppUser); + + // Show success message + Notification.show( + "App-Nutzer erfolgreich angelegt", + 3000, + Notification.Position.MIDDLE + ); + + // Navigate back to app user list + navigateBack(); + + } catch (ValidationException e) { + Notification.show( + "Bitte überprüfen Sie die Eingaben", + 3000, + Notification.Position.MIDDLE + ); + } + } + + private void populateTestData() { + // Fill designation field + designationField.setValue("HH H 001"); + + // Fill name fields + firstnameField.setValue("Max"); + lastnameField.setValue("Mustermann"); + + // Fill phone field + phoneField.setValue("+49 123 456789"); + + // Fill app code field + appCodeField.setValue("APP001"); + + // Fill email field + emailField.setValue("max.mustermann@example.com"); + + // Set device to iPhone + deviceField.setValue("iPhone"); + } + + private void navigateBack() { + getUI().ifPresent(ui -> ui.navigate("app-user")); + } +} diff --git a/src/main/java/de/assecutor/votianlt/pages/view/AppUserView.java b/src/main/java/de/assecutor/votianlt/pages/view/AppUserView.java index c82a446..8f53904 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/AppUserView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/AppUserView.java @@ -2,18 +2,13 @@ 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.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.html.H2; import com.vaadin.flow.component.icon.Icon; import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.orderedlayout.FlexComponent; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.component.notification.Notification; -import com.vaadin.flow.data.binder.Binder; -import com.vaadin.flow.data.binder.ValidationException; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import de.assecutor.votianlt.model.AppUser; @@ -21,147 +16,63 @@ import de.assecutor.votianlt.pages.service.AppUserService; import jakarta.annotation.security.RolesAllowed; import org.springframework.beans.factory.annotation.Autowired; -@PageTitle("Neuen App-Nutzer anlegen") +@PageTitle("App-Nutzer") @Route(value = "app-user", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class) @RolesAllowed({"USER","ADMIN"}) public class AppUserView extends VerticalLayout { - private final Binder binder = new Binder<>(AppUser.class); - - // Form fields - private final TextField designationField = new TextField("Bezeichnung (HH H 000)"); - private final TextField firstnameField = new TextField("Vorname"); - private final TextField lastnameField = new TextField("Nachname"); - private final TextField phoneField = new TextField("Telefon (Mobil)"); - private final TextField appCodeField = new TextField("App-Code"); - private final TextField emailField = new TextField("E-Mail-Adresse"); - private final ComboBox deviceField = new ComboBox<>("kein Gerät"); - private final AppUserService appUserService; + private final Grid appUserGrid; @Autowired public AppUserView(AppUserService appUserService) { this.appUserService = appUserService; + 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("600px"); - 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 with title and question mark icon + // Header mit Titel und Button HorizontalLayout header = new HorizontalLayout(); + header.setWidthFull(); header.setAlignItems(FlexComponent.Alignment.CENTER); - header.setSpacing(true); - H2 title = new H2("Neuen App-Nutzer anlegen"); + H2 title = new H2("App-Nutzer"); title.getStyle().set("margin", "0"); - Icon questionIcon = new Icon(VaadinIcon.QUESTION_CIRCLE); - questionIcon.getStyle().set("color", "var(--lumo-secondary-text-color)"); + Button addButton = new Button("Neuen App-Nutzer anlegen", new Icon(VaadinIcon.PLUS)); + addButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + addButton.addClickListener(e -> navigateToAddAppUser()); - header.add(title, questionIcon); - header.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); - contentContainer.add(header); + header.add(title, addButton); + header.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN); + add(header); - // Form layout - FormLayout formLayout = new FormLayout(); - formLayout.setResponsiveSteps( - new FormLayout.ResponsiveStep("0", 1) - ); - - // Configure fields - designationField.setPlaceholder("(HH H 000)"); - designationField.setWidthFull(); + // Grid für App-Nutzer + appUserGrid = new Grid<>(AppUser.class, false); + appUserGrid.setSizeFull(); - firstnameField.setWidthFull(); - lastnameField.setWidthFull(); + // Grid-Spalten konfigurieren + appUserGrid.addColumn(AppUser::getBezeichnung).setHeader("Bezeichnung").setAutoWidth(true); + appUserGrid.addColumn(AppUser::getVorname).setHeader("Vorname").setAutoWidth(true); + appUserGrid.addColumn(AppUser::getNachname).setHeader("Nachname").setAutoWidth(true); + appUserGrid.addColumn(AppUser::getTelefon).setHeader("Telefon").setAutoWidth(true); + appUserGrid.addColumn(AppUser::getAppCode).setHeader("App-Code").setAutoWidth(true); + appUserGrid.addColumn(AppUser::getEmail).setHeader("E-Mail").setAutoWidth(true); + appUserGrid.addColumn(AppUser::getGeraet).setHeader("Gerät").setAutoWidth(true); - // Create horizontal layout for firstname and lastname - HorizontalLayout nameLayout = new HorizontalLayout(); - nameLayout.setWidthFull(); - nameLayout.setSpacing(true); - nameLayout.add(firstnameField, lastnameField); - - phoneField.setWidthFull(); - appCodeField.setWidthFull(); - emailField.setWidthFull(); - - // Configure device dropdown - deviceField.setItems("kein Gerät", "iPhone", "Android", "Tablet", "Desktop"); - deviceField.setValue("kein Gerät"); - deviceField.setWidthFull(); + add(appUserGrid); - // Add fields to form - formLayout.add(designationField); - formLayout.add(nameLayout); - formLayout.add(phoneField); - formLayout.add(appCodeField); - formLayout.add(emailField); - formLayout.add(deviceField); - - contentContainer.add(formLayout); - - // Submit button - Button submitButton = new Button("App-Nutzer anlegen", e -> createAppUser()); - submitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - submitButton.setWidthFull(); - contentContainer.add(submitButton); - - // Add content container to main layout - add(contentContainer); - - // Setup binder - setupBinder(); + // Daten laden + loadAppUsers(); } - private void setupBinder() { - // Bind fields to AppUser properties - binder.forField(designationField).bind(AppUser::getBezeichnung, AppUser::setBezeichnung); - binder.forField(firstnameField).bind(AppUser::getVorname, AppUser::setVorname); - binder.forField(lastnameField).bind(AppUser::getNachname, AppUser::setNachname); - binder.forField(phoneField).bind(AppUser::getTelefon, AppUser::setTelefon); - binder.forField(appCodeField).bind(AppUser::getAppCode, AppUser::setAppCode); - binder.forField(emailField).bind(AppUser::getEmail, AppUser::setEmail); - binder.forField(deviceField).bind(AppUser::getGeraet, AppUser::setGeraet); + private void loadAppUsers() { + var appUsers = appUserService.findAll(); + appUserGrid.setItems(appUsers); } - private void createAppUser() { - try { - // Create new AppUser object - AppUser newAppUser = new AppUser(); - binder.writeBean(newAppUser); - - // Save to MongoDB collection - appUserService.createAppUser(newAppUser); - - // Show success message - Notification.show( - "App-Nutzer erfolgreich angelegt", - 3000, - Notification.Position.MIDDLE - ); - - // Clear form - binder.readBean(new AppUser()); - - } catch (ValidationException e) { - Notification.show( - "Bitte überprüfen Sie die Eingaben", - 3000, - Notification.Position.MIDDLE - ); - } + private void navigateToAddAppUser() { + getUI().ifPresent(ui -> ui.navigate("add-app-user")); } }