Erweiterungen
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user