Erweiterungen

This commit is contained in:
2025-08-13 12:52:22 +02:00
parent de72f44a4e
commit 60547ec442

View File

@@ -5,6 +5,8 @@ import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.checkbox.Checkbox; import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.timepicker.TimePicker;
import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.H3; import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Main; import com.vaadin.flow.component.html.Main;
@@ -17,6 +19,8 @@ import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.ClientCallable; import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.textfield.IntegerField;
import com.vaadin.flow.component.textfield.NumberField;
import com.vaadin.flow.component.UI; import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.dnd.DragSource; import com.vaadin.flow.component.dnd.DragSource;
import com.vaadin.flow.component.dnd.DropTarget; import com.vaadin.flow.component.dnd.DropTarget;
@@ -24,6 +28,7 @@ import com.vaadin.flow.component.dnd.EffectAllowed;
import com.vaadin.flow.data.binder.Binder; import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.ValidationException; import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.router.Menu; import com.vaadin.flow.router.Menu;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route; import com.vaadin.flow.router.Route;
import com.vaadin.flow.theme.lumo.LumoUtility; import com.vaadin.flow.theme.lumo.LumoUtility;
@@ -47,10 +52,10 @@ public class AddJobView extends Main {
// Customer selection // Customer selection
private ComboBox<String> customerSelection; private ComboBox<String> customerSelection;
private Button preloadAddressButton; private Button preloadAddressButton;
// Required fields notice // Required fields notice
private Span requiredFieldsNotice; private Span requiredFieldsNotice;
// Pickup address fields // Pickup address fields
private TextField pickupCompany; private TextField pickupCompany;
private ComboBox<String> pickupSalutation; private ComboBox<String> pickupSalutation;
@@ -63,7 +68,7 @@ public class AddJobView extends Main {
private TextField pickupZip; private TextField pickupZip;
private TextField pickupCity; private TextField pickupCity;
private Checkbox savePickupAddress; private Checkbox savePickupAddress;
// Delivery address fields // Delivery address fields
private TextField deliveryCompany; private TextField deliveryCompany;
private ComboBox<String> deliverySalutation; private ComboBox<String> deliverySalutation;
@@ -76,27 +81,25 @@ public class AddJobView extends Main {
private TextField deliveryZip; private TextField deliveryZip;
private TextField deliveryCity; private TextField deliveryCity;
private Checkbox saveDeliveryAddress; private Checkbox saveDeliveryAddress;
// Digital processing // Digital processing
private Checkbox digitalProcessing; private Checkbox digitalProcessing;
private ComboBox<String> appUser; private ComboBox<String> appUser;
// Submit button // Submit button
private Button submitButton; private Button submitButton;
// Stage sections for drag and drop // Stage sections for drag and drop
private VerticalLayout pickupSection; private VerticalLayout pickupSection;
private VerticalLayout deliverySection; private VerticalLayout deliverySection;
private HorizontalLayout mainLayout; private HorizontalLayout mainLayout;
// Drag sources for dynamic control // Drag sources for dynamic control
private DragSource<VerticalLayout> pickupDragSource; private DragSource<VerticalLayout> pickupDragSource;
private DragSource<VerticalLayout> deliveryDragSource; private DragSource<VerticalLayout> deliveryDragSource;
private final Binder<Job> binder = new Binder<>(Job.class); private final Binder<Job> binder = new Binder<>(Job.class);
public AddJobView(AddJobService addJobService) { public AddJobView(AddJobService addJobService) {
this.addJobService = addJobService; this.addJobService = addJobService;
initializeComponents(); initializeComponents();
@@ -111,11 +114,11 @@ public class AddJobView extends Main {
customerSelection.setItems("Kunde01 | KOTVor K01Nach"); customerSelection.setItems("Kunde01 | KOTVor K01Nach");
customerSelection.setPlaceholder("Wählen Sie einen Auftraggeber aus..."); customerSelection.setPlaceholder("Wählen Sie einen Auftraggeber aus...");
customerSelection.setWidthFull(); customerSelection.setWidthFull();
preloadAddressButton = new Button("Vorbelegte Adressfelder leeren"); preloadAddressButton = new Button("Vorbelegte Adressfelder leeren");
preloadAddressButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); preloadAddressButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
preloadAddressButton.addClickListener(event -> clearAllFields()); preloadAddressButton.addClickListener(event -> clearAllFields());
// Pickup address // Pickup address
pickupCompany = new TextField("Firma"); pickupCompany = new TextField("Firma");
pickupCompany.setPlaceholder("z.B. IKEA, McDonald's, DHL..."); pickupCompany.setPlaceholder("z.B. IKEA, McDonald's, DHL...");
@@ -146,7 +149,7 @@ public class AddJobView extends Main {
pickupCity.setPlaceholder("Hamburg"); pickupCity.setPlaceholder("Hamburg");
pickupCity.setRequiredIndicatorVisible(true); pickupCity.setRequiredIndicatorVisible(true);
savePickupAddress = new Checkbox("Die Adresse für zukünftige Aufträge speichern."); savePickupAddress = new Checkbox("Die Adresse für zukünftige Aufträge speichern.");
// Delivery address // Delivery address
deliveryCompany = new TextField("Firma"); deliveryCompany = new TextField("Firma");
deliveryCompany.setPlaceholder("z.B. EDEKA, Bauhaus, Amazon..."); deliveryCompany.setPlaceholder("z.B. EDEKA, Bauhaus, Amazon...");
@@ -191,12 +194,12 @@ public class AddJobView extends Main {
private void setupLayout() { private void setupLayout() {
setSizeFull(); setSizeFull();
addClassNames(LumoUtility.BoxSizing.BORDER, LumoUtility.Display.FLEX, addClassNames(LumoUtility.BoxSizing.BORDER, LumoUtility.Display.FLEX,
LumoUtility.FlexDirection.COLUMN, LumoUtility.Padding.MEDIUM, LumoUtility.FlexDirection.COLUMN, LumoUtility.Padding.MEDIUM,
LumoUtility.Gap.SMALL); LumoUtility.Gap.SMALL);
add(new ViewToolbar("Neuen Auftrag anlegen")); add(new ViewToolbar("Neuen Auftrag anlegen"));
// Customer selection section // Customer selection section
HorizontalLayout customerLayout = new HorizontalLayout(); HorizontalLayout customerLayout = new HorizontalLayout();
customerLayout.setWidthFull(); customerLayout.setWidthFull();
@@ -204,7 +207,7 @@ public class AddJobView extends Main {
customerLayout.add(customerSelection, preloadAddressButton); customerLayout.add(customerSelection, preloadAddressButton);
customerSelection.setWidth("70%"); customerSelection.setWidth("70%");
preloadAddressButton.setWidth("30%"); preloadAddressButton.setWidth("30%");
add(customerLayout); add(customerLayout);
// Main content layout with two equal columns (50% each) // Main content layout with two equal columns (50% each)
@@ -222,19 +225,70 @@ public class AddJobView extends Main {
deliverySection = createDeliverySection(); deliverySection = createDeliverySection();
deliverySection.setWidth("50%"); deliverySection.setWidth("50%");
deliveryDragSource = configureDragAndDrop(deliverySection, "delivery"); deliveryDragSource = configureDragAndDrop(deliverySection, "delivery");
// Setup focus listeners for input fields // Setup focus listeners for input fields
setupInputFieldFocusListeners(); setupInputFieldFocusListeners();
mainLayout.add(pickupSection, deliverySection); mainLayout.add(pickupSection, deliverySection);
add(mainLayout); add(mainLayout);
// Digital processing section // Section under the stages (centered)
VerticalLayout digitalSection = new VerticalLayout(); VerticalLayout belowSection = new VerticalLayout();
digitalSection.setSpacing(false); belowSection.setWidthFull();
digitalSection.add(digitalProcessing, appUser); belowSection.setPadding(false);
add(digitalSection); belowSection.setSpacing(true);
belowSection.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
// Container with fixed width to center content
VerticalLayout content = new VerticalLayout();
content.setPadding(false);
content.setSpacing(true);
content.setWidth("720px");
content.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);
// Row: Digital processing + App user
HorizontalLayout digitalRow = new HorizontalLayout();
digitalRow.setWidthFull();
digitalRow.setAlignItems(FlexComponent.Alignment.BASELINE);
digitalRow.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
digitalProcessing.getStyle().set("margin-right", "12px");
digitalRow.add(digitalProcessing);
// App user selector full width
appUser.setWidthFull();
content.add(digitalRow, appUser);
// Appointment (Pickup)
H3 pickupApptTitle = new H3("Termin (Abholung)");
pickupApptTitle.getStyle().set("margin", "0");
DatePicker pickupDate = new DatePicker("Datum");
pickupDate.setRequiredIndicatorVisible(true);
TimePicker pickupTime = new TimePicker("Uhrzeit");
HorizontalLayout pickupApptRow = new HorizontalLayout(pickupDate, pickupTime);
pickupApptRow.setWidthFull();
pickupApptRow.setSpacing(true);
pickupDate.setWidth("50%");
pickupTime.setWidth("50%");
content.add(pickupApptTitle, pickupApptRow);
// Appointment (Delivery)
H3 deliveryApptTitle = new H3("Termin (Lieferung)");
deliveryApptTitle.getStyle().set("margin", "0");
DatePicker deliveryDate = new DatePicker("Datum");
deliveryDate.setRequiredIndicatorVisible(true);
TimePicker deliveryTime = new TimePicker("Uhrzeit");
HorizontalLayout deliveryApptRow = new HorizontalLayout(deliveryDate, deliveryTime);
deliveryApptRow.setWidthFull();
deliveryApptRow.setSpacing(true);
deliveryDate.setWidth("50%");
deliveryTime.setWidth("50%");
content.add(deliveryApptTitle, deliveryApptRow);
belowSection.add(content);
add(belowSection);
// Ladung Bereich vor dem Button
add(createCargoSection());
// Submit button // Submit button
HorizontalLayout submitLayout = new HorizontalLayout(); HorizontalLayout submitLayout = new HorizontalLayout();
@@ -291,6 +345,7 @@ public class AddJobView extends Main {
section.add(pickupAddressAddition); section.add(pickupAddressAddition);
// zip/city row
HorizontalLayout zipCityLayout = new HorizontalLayout(); HorizontalLayout zipCityLayout = new HorizontalLayout();
zipCityLayout.setWidthFull(); zipCityLayout.setWidthFull();
zipCityLayout.setSpacing(true); zipCityLayout.setSpacing(true);
@@ -387,27 +442,27 @@ public class AddJobView extends Main {
binder.forField(deliveryFirstName) binder.forField(deliveryFirstName)
.asRequired("") .asRequired("")
.bind(Job::getDeliveryFirstName, Job::setDeliveryFirstName); .bind(Job::getDeliveryFirstName, Job::setDeliveryFirstName);
binder.forField(deliveryLastName) binder.forField(deliveryLastName)
.asRequired("") .asRequired("")
.bind(Job::getDeliveryLastName, Job::setDeliveryLastName); .bind(Job::getDeliveryLastName, Job::setDeliveryLastName);
binder.forField(deliveryStreet) binder.forField(deliveryStreet)
.asRequired("") .asRequired("")
.bind(Job::getDeliveryStreet, Job::setDeliveryStreet); .bind(Job::getDeliveryStreet, Job::setDeliveryStreet);
binder.forField(deliveryHouseNumber) binder.forField(deliveryHouseNumber)
.asRequired("") .asRequired("")
.bind(Job::getDeliveryHouseNumber, Job::setDeliveryHouseNumber); .bind(Job::getDeliveryHouseNumber, Job::setDeliveryHouseNumber);
binder.forField(deliveryZip) binder.forField(deliveryZip)
.asRequired("") .asRequired("")
.bind(Job::getDeliveryZip, Job::setDeliveryZip); .bind(Job::getDeliveryZip, Job::setDeliveryZip);
binder.forField(deliveryCity) binder.forField(deliveryCity)
.asRequired("") .asRequired("")
.bind(Job::getDeliveryCity, Job::setDeliveryCity); .bind(Job::getDeliveryCity, Job::setDeliveryCity);
// Bind optional fields without validation // Bind optional fields without validation
binder.bind(customerSelection, Job::getCustomerSelection, Job::setCustomerSelection); binder.bind(customerSelection, Job::getCustomerSelection, Job::setCustomerSelection);
binder.bind(pickupCompany, Job::getPickupCompany, Job::setPickupCompany); binder.bind(pickupCompany, Job::getPickupCompany, Job::setPickupCompany);
@@ -415,56 +470,56 @@ public class AddJobView extends Main {
binder.bind(pickupPhone, Job::getPickupPhone, Job::setPickupPhone); binder.bind(pickupPhone, Job::getPickupPhone, Job::setPickupPhone);
binder.bind(pickupAddressAddition, Job::getPickupAddressAddition, Job::setPickupAddressAddition); binder.bind(pickupAddressAddition, Job::getPickupAddressAddition, Job::setPickupAddressAddition);
binder.bind(savePickupAddress, Job::isSavePickupAddress, Job::setSavePickupAddress); binder.bind(savePickupAddress, Job::isSavePickupAddress, Job::setSavePickupAddress);
binder.bind(deliveryCompany, Job::getDeliveryCompany, Job::setDeliveryCompany); binder.bind(deliveryCompany, Job::getDeliveryCompany, Job::setDeliveryCompany);
binder.bind(deliverySalutation, Job::getDeliverySalutation, Job::setDeliverySalutation); binder.bind(deliverySalutation, Job::getDeliverySalutation, Job::setDeliverySalutation);
binder.bind(deliveryPhone, Job::getDeliveryPhone, Job::setDeliveryPhone); binder.bind(deliveryPhone, Job::getDeliveryPhone, Job::setDeliveryPhone);
binder.bind(deliveryAddressAddition, Job::getDeliveryAddressAddition, Job::setDeliveryAddressAddition); binder.bind(deliveryAddressAddition, Job::getDeliveryAddressAddition, Job::setDeliveryAddressAddition);
binder.bind(saveDeliveryAddress, Job::isSaveDeliveryAddress, Job::setSaveDeliveryAddress); binder.bind(saveDeliveryAddress, Job::isSaveDeliveryAddress, Job::setSaveDeliveryAddress);
binder.bind(digitalProcessing, Job::isDigitalProcessing, Job::setDigitalProcessing); binder.bind(digitalProcessing, Job::isDigitalProcessing, Job::setDigitalProcessing);
binder.bind(appUser, Job::getAppUser, Job::setAppUser); binder.bind(appUser, Job::getAppUser, Job::setAppUser);
// Set up validation triggers and visual styling // Set up validation triggers and visual styling
setupValidationTriggers(); setupValidationTriggers();
// Trigger initial validation when view is displayed // Trigger initial validation when view is displayed
triggerValidation(); triggerValidation();
} }
private void setupValidationTriggers() { private void setupValidationTriggers() {
// List of all required fields // List of all required fields
TextField[] requiredFields = { TextField[] requiredFields = {
pickupFirstName, pickupLastName, pickupStreet, pickupHouseNumber, pickupZip, pickupCity, pickupFirstName, pickupLastName, pickupStreet, pickupHouseNumber, pickupZip, pickupCity,
deliveryFirstName, deliveryLastName, deliveryStreet, deliveryHouseNumber, deliveryZip, deliveryCity deliveryFirstName, deliveryLastName, deliveryStreet, deliveryHouseNumber, deliveryZip, deliveryCity
}; };
// Add value change listeners to trigger validation on every change // Add value change listeners to trigger validation on every change
for (TextField field : requiredFields) { for (TextField field : requiredFields) {
field.addValueChangeListener(event -> { field.addValueChangeListener(event -> {
triggerValidation(); triggerValidation();
updateFieldStyling(field); updateFieldStyling(field);
}); });
// Add focus listeners for immediate visual feedback // Add focus listeners for immediate visual feedback
field.addFocusListener(event -> updateFieldStyling(field)); field.addFocusListener(event -> updateFieldStyling(field));
field.addBlurListener(event -> updateFieldStyling(field)); field.addBlurListener(event -> updateFieldStyling(field));
// Set initial styling // Set initial styling
updateFieldStyling(field); updateFieldStyling(field);
} }
} }
private void triggerValidation() { private void triggerValidation() {
// Create a temporary job object to trigger validation // Create a temporary job object to trigger validation
Job tempJob = new Job(); Job tempJob = new Job();
binder.validate(); binder.validate();
} }
private void updateFieldStyling(TextField field) { private void updateFieldStyling(TextField field) {
String value = field.getValue(); String value = field.getValue();
boolean isEmpty = value == null || value.trim().isEmpty(); boolean isEmpty = value == null || value.trim().isEmpty();
if (isEmpty) { if (isEmpty) {
// Apply transparent red background only to the input field, not the label // Apply transparent red background only to the input field, not the label
field.getStyle().set("--vaadin-input-field-background", "rgba(255, 0, 0, 0.1)"); field.getStyle().set("--vaadin-input-field-background", "rgba(255, 0, 0, 0.1)");
@@ -479,7 +534,7 @@ public class AddJobView extends Main {
private void submit() { private void submit() {
try { try {
Job job = new Job(); Job job = new Job();
// Validate all required fields using the binder // Validate all required fields using the binder
if (binder.writeBeanIfValid(job)) { if (binder.writeBeanIfValid(job)) {
// All validations passed, save the job // All validations passed, save the job
@@ -513,7 +568,7 @@ public class AddJobView extends Main {
private void clearForm() { private void clearForm() {
// Reset binder to clear validation state // Reset binder to clear validation state
binder.readBean(new Job()); binder.readBean(new Job());
// Customer selection // Customer selection
customerSelection.clear(); customerSelection.clear();
@@ -644,7 +699,72 @@ public class AddJobView extends Main {
if (job.getCustomerSelection() != null) { if (job.getCustomerSelection() != null) {
customerSelection.setValue(job.getCustomerSelection()); customerSelection.setValue(job.getCustomerSelection());
} }
}
private Component createCargoSection() {
VerticalLayout wrapper = new VerticalLayout();
wrapper.setWidthFull();
wrapper.setSpacing(true);
VerticalLayout cargoArea = new VerticalLayout();
cargoArea.setWidthFull();
cargoArea.setSpacing(true);
cargoArea.getStyle().set("background", "var(--lumo-base-color)");
cargoArea.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
cargoArea.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
cargoArea.getStyle().set("padding", "var(--lumo-space-m)");
VerticalLayout cargoList = new VerticalLayout();
cargoList.setPadding(false);
cargoList.setSpacing(true);
cargoArea.add(cargoList);
java.util.function.BiConsumer<String, java.util.function.Consumer<HorizontalLayout>> addCargoRow = (iconName, afterCreate) -> {
HorizontalLayout row = new HorizontalLayout();
row.setWidthFull();
row.setAlignItems(FlexComponent.Alignment.END);
TextField desc = new TextField("Beschreibung");
desc.setPlaceholder("z. B. Gitterboxpalette, Paket …");
desc.setWidth("40%");
IntegerField qty = new IntegerField("Anzahl");
qty.setMin(1);
qty.setValue(1);
qty.setWidth("10%");
NumberField weight = new NumberField("Gewicht");
weight.setSuffixComponent(new Span("kg"));
weight.setWidth("15%");
NumberField len = new NumberField("Länge");
len.setSuffixComponent(new Span("mm"));
len.setWidth("12%");
NumberField wid = new NumberField("Breite");
wid.setSuffixComponent(new Span("mm"));
wid.setWidth("12%");
NumberField hei = new NumberField("Höhe");
hei.setSuffixComponent(new Span("mm"));
hei.setWidth("12%");
Button remove = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
remove.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
remove.addClickListener(e -> cargoList.remove(row));
row.add(desc, qty, weight, len, wid, hei, remove);
cargoList.add(row);
if (afterCreate != null) afterCreate.accept(row);
};
addCargoRow.accept("gitterbox", r -> {});
addCargoRow.accept("paket", r -> {});
addCargoRow.accept("", r -> {});
wrapper.add(cargoArea);
return wrapper;
}
private void populateFromJob(Job job) {
// Pickup address // Pickup address
if (job.getPickupCompany() != null) pickupCompany.setValue(job.getPickupCompany()); if (job.getPickupCompany() != null) pickupCompany.setValue(job.getPickupCompany());
if (job.getPickupSalutation() != null) pickupSalutation.setValue(job.getPickupSalutation()); if (job.getPickupSalutation() != null) pickupSalutation.setValue(job.getPickupSalutation());
@@ -812,7 +932,7 @@ public class AddJobView extends Main {
// Customer selection // Customer selection
customerSelection.addFocusListener(e -> disableDragSources()); customerSelection.addFocusListener(e -> disableDragSources());
customerSelection.addBlurListener(e -> enableDragSources()); customerSelection.addBlurListener(e -> enableDragSources());
// Pickup fields // Pickup fields
pickupCompany.addFocusListener(e -> disableDragSources()); pickupCompany.addFocusListener(e -> disableDragSources());
pickupCompany.addBlurListener(e -> enableDragSources()); pickupCompany.addBlurListener(e -> enableDragSources());
@@ -834,7 +954,7 @@ public class AddJobView extends Main {
pickupZip.addBlurListener(e -> enableDragSources()); pickupZip.addBlurListener(e -> enableDragSources());
pickupCity.addFocusListener(e -> disableDragSources()); pickupCity.addFocusListener(e -> disableDragSources());
pickupCity.addBlurListener(e -> enableDragSources()); pickupCity.addBlurListener(e -> enableDragSources());
// Delivery fields // Delivery fields
deliveryCompany.addFocusListener(e -> disableDragSources()); deliveryCompany.addFocusListener(e -> disableDragSources());
deliveryCompany.addBlurListener(e -> enableDragSources()); deliveryCompany.addBlurListener(e -> enableDragSources());
@@ -856,12 +976,12 @@ public class AddJobView extends Main {
deliveryZip.addBlurListener(e -> enableDragSources()); deliveryZip.addBlurListener(e -> enableDragSources());
deliveryCity.addFocusListener(e -> disableDragSources()); deliveryCity.addFocusListener(e -> disableDragSources());
deliveryCity.addBlurListener(e -> enableDragSources()); deliveryCity.addBlurListener(e -> enableDragSources());
// Digital processing // Digital processing
appUser.addFocusListener(e -> disableDragSources()); appUser.addFocusListener(e -> disableDragSources());
appUser.addBlurListener(e -> enableDragSources()); appUser.addBlurListener(e -> enableDragSources());
} }
/** /**
* Deaktiviert alle Drag-Sources durch CSS * Deaktiviert alle Drag-Sources durch CSS
*/ */
@@ -875,7 +995,7 @@ public class AddJobView extends Main {
deliverySection.getElement().setAttribute("draggable", "false"); deliverySection.getElement().setAttribute("draggable", "false");
} }
} }
/** /**
* Aktiviert alle Drag-Sources durch CSS * Aktiviert alle Drag-Sources durch CSS
*/ */
@@ -898,13 +1018,13 @@ public class AddJobView extends Main {
DragSource<VerticalLayout> dragSource = DragSource.create(section); DragSource<VerticalLayout> dragSource = DragSource.create(section);
dragSource.setEffectAllowed(EffectAllowed.MOVE); dragSource.setEffectAllowed(EffectAllowed.MOVE);
dragSource.setDragData(sectionType); dragSource.setDragData(sectionType);
// Visual feedback beim Drag-Start // Visual feedback beim Drag-Start
dragSource.addDragStartListener(event -> { dragSource.addDragStartListener(event -> {
section.getStyle().set("opacity", "0.5"); section.getStyle().set("opacity", "0.5");
section.getStyle().set("border", "2px dashed var(--lumo-primary-color)"); section.getStyle().set("border", "2px dashed var(--lumo-primary-color)");
}); });
// Visual feedback beim Drag-Ende // Visual feedback beim Drag-Ende
dragSource.addDragEndListener(event -> { dragSource.addDragEndListener(event -> {
section.getStyle().remove("opacity"); section.getStyle().remove("opacity");
@@ -914,35 +1034,35 @@ public class AddJobView extends Main {
// Drop Target konfigurieren // Drop Target konfigurieren
DropTarget<VerticalLayout> dropTarget = DropTarget.create(section); DropTarget<VerticalLayout> dropTarget = DropTarget.create(section);
dropTarget.setActive(true); dropTarget.setActive(true);
// Drop Handler - Etappen tauschen // Drop Handler - Etappen tauschen
dropTarget.addDropListener(event -> { dropTarget.addDropListener(event -> {
Object draggedData = event.getDragData().orElse(null); Object draggedData = event.getDragData().orElse(null);
String draggedSectionType = draggedData != null ? draggedData.toString() : ""; String draggedSectionType = draggedData != null ? draggedData.toString() : "";
if (!sectionType.equals(draggedSectionType)) { if (!sectionType.equals(draggedSectionType)) {
swapStages(); swapStages();
} }
// Styles zurücksetzen // Styles zurücksetzen
section.getStyle().set("background-color", "var(--lumo-base-color)"); section.getStyle().set("background-color", "var(--lumo-base-color)");
section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)"); section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
}); });
// Visual feedback bei Dragover mit JavaScript // Visual feedback bei Dragover mit JavaScript
section.getElement().addEventListener("dragover", e -> { section.getElement().addEventListener("dragover", e -> {
section.getStyle().set("background-color", "var(--lumo-primary-color-10pct)"); section.getStyle().set("background-color", "var(--lumo-primary-color-10pct)");
section.getStyle().set("border", "2px solid var(--lumo-primary-color)"); section.getStyle().set("border", "2px solid var(--lumo-primary-color)");
}); });
section.getElement().addEventListener("dragleave", e -> { section.getElement().addEventListener("dragleave", e -> {
section.getStyle().set("background-color", "var(--lumo-base-color)"); section.getStyle().set("background-color", "var(--lumo-base-color)");
section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)"); section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
}); });
return dragSource; return dragSource;
} }
/** /**
* Tauscht die Inhalte der beiden Etappen (Pickup und Delivery) * Tauscht die Inhalte der beiden Etappen (Pickup und Delivery)
*/ */
@@ -959,7 +1079,7 @@ public class AddJobView extends Main {
String tempZip = pickupZip.getValue(); String tempZip = pickupZip.getValue();
String tempCity = pickupCity.getValue(); String tempCity = pickupCity.getValue();
Boolean tempSaveAddress = savePickupAddress.getValue(); Boolean tempSaveAddress = savePickupAddress.getValue();
// Pickup mit Delivery-Werten überschreiben // Pickup mit Delivery-Werten überschreiben
pickupCompany.setValue(deliveryCompany.getValue()); pickupCompany.setValue(deliveryCompany.getValue());
pickupSalutation.setValue(deliverySalutation.getValue()); pickupSalutation.setValue(deliverySalutation.getValue());
@@ -972,7 +1092,7 @@ public class AddJobView extends Main {
pickupZip.setValue(deliveryZip.getValue()); pickupZip.setValue(deliveryZip.getValue());
pickupCity.setValue(deliveryCity.getValue()); pickupCity.setValue(deliveryCity.getValue());
savePickupAddress.setValue(saveDeliveryAddress.getValue()); savePickupAddress.setValue(saveDeliveryAddress.getValue());
// Delivery mit zwischengespeicherten Pickup-Werten überschreiben // Delivery mit zwischengespeicherten Pickup-Werten überschreiben
deliveryCompany.setValue(tempCompany); deliveryCompany.setValue(tempCompany);
deliverySalutation.setValue(tempSalutation); deliverySalutation.setValue(tempSalutation);
@@ -985,7 +1105,7 @@ public class AddJobView extends Main {
deliveryZip.setValue(tempZip); deliveryZip.setValue(tempZip);
deliveryCity.setValue(tempCity); deliveryCity.setValue(tempCity);
saveDeliveryAddress.setValue(tempSaveAddress); saveDeliveryAddress.setValue(tempSaveAddress);
// Benutzer-Feedback // Benutzer-Feedback
Notification.show("Etappen wurden erfolgreich getauscht!", 3000, Notification.Position.BOTTOM_CENTER); Notification.show("Etappen wurden erfolgreich getauscht!", 3000, Notification.Position.BOTTOM_CENTER);
} }