Erweiterungen
This commit is contained in:
@@ -35,6 +35,9 @@ public abstract class BaseTask {
|
||||
@Field("task_order")
|
||||
private Integer taskOrder = 0;
|
||||
|
||||
@Field("description")
|
||||
private String description;
|
||||
|
||||
@Field("completed")
|
||||
private boolean completed = false;
|
||||
|
||||
|
||||
@@ -391,9 +391,10 @@ public class AddJobView extends Main {
|
||||
.setWeekdaysShort(java.util.Arrays.asList(
|
||||
"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa")));
|
||||
|
||||
// Submit button
|
||||
// Submit button - initially disabled until all required fields are valid
|
||||
submitButton = new Button("Auftrag anlegen", event -> submit());
|
||||
submitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||
submitButton.setEnabled(false);
|
||||
}
|
||||
|
||||
// Testdaten entfernt
|
||||
@@ -951,6 +952,16 @@ public class AddJobView extends Main {
|
||||
private void triggerValidation() {
|
||||
// Create a temporary job object to trigger validation
|
||||
binder.validate();
|
||||
|
||||
// Update submit button state based on all validation checks
|
||||
if (submitButton != null) {
|
||||
boolean hasErrors = hasAddressValidationErrors()
|
||||
|| hasAppointmentValidationErrors()
|
||||
|| hasCargoValidationErrors()
|
||||
|| hasPriceValidationErrors()
|
||||
|| hasTasksValidationErrors();
|
||||
submitButton.setEnabled(!hasErrors);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFieldStyling(TextField field) {
|
||||
@@ -992,6 +1003,9 @@ public class AddJobView extends Main {
|
||||
}
|
||||
|
||||
private void updateTabLabel(com.vaadin.flow.component.tabs.Tab tab, String baseLabel, boolean hasErrors) {
|
||||
if (tab == null) {
|
||||
return;
|
||||
}
|
||||
if (hasErrors) {
|
||||
tab.setLabel(baseLabel + " ⚠️");
|
||||
} else {
|
||||
@@ -1043,7 +1057,28 @@ public class AddJobView extends Main {
|
||||
}
|
||||
|
||||
private boolean hasTasksValidationErrors() {
|
||||
// Tasks are optional, so no validation errors for tasks
|
||||
for (BaseTask task : tasksState) {
|
||||
// Check if any ConfirmationTask has an empty description (required field)
|
||||
if (task instanceof ConfirmationTask) {
|
||||
String description = task.getDescription();
|
||||
if (description == null || description.trim().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Check if any TodoListTask has at least one non-empty todo item
|
||||
if (task instanceof TodoListTask todoListTask) {
|
||||
List<String> todoItems = todoListTask.getTodoItems();
|
||||
if (todoItems == null || todoItems.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
// Check if at least one todo item is non-empty
|
||||
boolean hasValidTodoItem = todoItems.stream()
|
||||
.anyMatch(item -> item != null && !item.trim().isEmpty());
|
||||
if (!hasValidTodoItem) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1275,7 +1310,8 @@ public class AddJobView extends Main {
|
||||
cargoItemsState.remove(idx);
|
||||
}
|
||||
cargoList.remove(row);
|
||||
updateTabLabels(); // Update tab validation when cargo item is removed
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
});
|
||||
|
||||
row.add(desc, qty, weight, len, wid, hei, remove);
|
||||
@@ -1317,32 +1353,38 @@ public class AddJobView extends Main {
|
||||
desc.addValueChangeListener(ev -> {
|
||||
item.setDescription(ev.getValue());
|
||||
validateField.accept(desc);
|
||||
updateTabLabels(); // Update tab validation when cargo description changes
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
});
|
||||
qty.addValueChangeListener(ev -> {
|
||||
item.setQuantity(ev.getValue());
|
||||
validateField.accept(qty);
|
||||
updateTabLabels(); // Update tab validation when cargo quantity changes
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
});
|
||||
weight.addValueChangeListener(ev -> {
|
||||
item.setWeightKg(ev.getValue());
|
||||
validateField.accept(weight);
|
||||
updateTabLabels(); // Update tab validation when cargo weight changes
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
});
|
||||
len.addValueChangeListener(ev -> {
|
||||
item.setLengthMm(ev.getValue());
|
||||
validateField.accept(len);
|
||||
updateTabLabels(); // Update tab validation when cargo length changes
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
});
|
||||
wid.addValueChangeListener(ev -> {
|
||||
item.setWidthMm(ev.getValue());
|
||||
validateField.accept(wid);
|
||||
updateTabLabels(); // Update tab validation when cargo width changes
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
});
|
||||
hei.addValueChangeListener(ev -> {
|
||||
item.setHeightMm(ev.getValue());
|
||||
validateField.accept(hei);
|
||||
updateTabLabels(); // Update tab validation when cargo height changes
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
});
|
||||
|
||||
// Initial validation
|
||||
@@ -1679,12 +1721,16 @@ public class AddJobView extends Main {
|
||||
}
|
||||
|
||||
updateTaskConfiguration(configContainer, newTask);
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
}
|
||||
});
|
||||
|
||||
// Set initial configuration
|
||||
taskTypeCombo.setValue(TaskType.CONFIRMATION);
|
||||
updateTaskConfiguration(configContainer, currentTask[0]);
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
|
||||
tasksList.add(taskContainer);
|
||||
}
|
||||
@@ -1717,6 +1763,33 @@ public class AddJobView extends Main {
|
||||
|
||||
switch (taskType) {
|
||||
case CONFIRMATION:
|
||||
// Description field (required)
|
||||
TextField descriptionField = new TextField("Beschreibung");
|
||||
descriptionField.setPlaceholder("Beschreibung der Aufgabe...");
|
||||
descriptionField.setWidthFull();
|
||||
descriptionField.setRequiredIndicatorVisible(true);
|
||||
descriptionField.setValue(task.getDescription() != null ? task.getDescription() : "");
|
||||
descriptionField.addValueChangeListener(ev -> {
|
||||
task.setDescription(ev.getValue());
|
||||
// Update field styling based on value
|
||||
boolean isEmpty = ev.getValue() == null || ev.getValue().trim().isEmpty();
|
||||
if (isEmpty) {
|
||||
descriptionField.getStyle().set("--vaadin-input-field-background", "rgba(255, 0, 0, 0.1)");
|
||||
descriptionField.getStyle().set("--vaadin-input-field-border-color", "rgba(255, 0, 0, 0.3)");
|
||||
} else {
|
||||
descriptionField.getStyle().remove("--vaadin-input-field-background");
|
||||
descriptionField.getStyle().remove("--vaadin-input-field-border-color");
|
||||
}
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
});
|
||||
// Initial styling for empty field
|
||||
if (task.getDescription() == null || task.getDescription().trim().isEmpty()) {
|
||||
descriptionField.getStyle().set("--vaadin-input-field-background", "rgba(255, 0, 0, 0.1)");
|
||||
descriptionField.getStyle().set("--vaadin-input-field-border-color", "rgba(255, 0, 0, 0.3)");
|
||||
}
|
||||
|
||||
// Button text field
|
||||
TextField buttonTextField = new TextField("Button-Text");
|
||||
buttonTextField.setPlaceholder("z.B. 'Bestätigen', 'Abgeschlossen'");
|
||||
buttonTextField.setWidthFull();
|
||||
@@ -1725,10 +1798,12 @@ public class AddJobView extends Main {
|
||||
buttonTextField.addValueChangeListener(ev -> {
|
||||
// Find the current ConfirmationTask in tasksState and update it
|
||||
for (BaseTask stateTask : tasksState) {
|
||||
if (stateTask instanceof ConfirmationTask) {
|
||||
((ConfirmationTask) stateTask).setButtonText(ev.getValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
configContainer.add(buttonTextField);
|
||||
configContainer.add(descriptionField, buttonTextField);
|
||||
break;
|
||||
|
||||
case SIGNATURE:
|
||||
@@ -1753,6 +1828,18 @@ public class AddJobView extends Main {
|
||||
todoList.setPadding(false);
|
||||
todoList.setSpacing(true);
|
||||
|
||||
// Helper to update todo field styling based on value
|
||||
java.util.function.Consumer<TextField> updateTodoFieldStyling = (field) -> {
|
||||
boolean isEmpty = field.getValue() == null || field.getValue().trim().isEmpty();
|
||||
if (isEmpty) {
|
||||
field.getStyle().set("--vaadin-input-field-background", "rgba(255, 0, 0, 0.1)");
|
||||
field.getStyle().set("--vaadin-input-field-border-color", "rgba(255, 0, 0, 0.3)");
|
||||
} else {
|
||||
field.getStyle().remove("--vaadin-input-field-background");
|
||||
field.getStyle().remove("--vaadin-input-field-border-color");
|
||||
}
|
||||
};
|
||||
|
||||
java.util.function.Consumer<Void> addTodoItem = (v) -> {
|
||||
HorizontalLayout todoRow = new HorizontalLayout();
|
||||
todoRow.setWidthFull();
|
||||
@@ -1761,6 +1848,9 @@ public class AddJobView extends Main {
|
||||
TextField todoField = new TextField();
|
||||
todoField.setPlaceholder("To-Do Punkt");
|
||||
todoField.setWidth("100%");
|
||||
todoField.setRequiredIndicatorVisible(true);
|
||||
// Initial red styling for empty field
|
||||
updateTodoFieldStyling.accept(todoField);
|
||||
|
||||
Button removeTodo = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
|
||||
removeTodo.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
|
||||
@@ -1773,7 +1863,10 @@ public class AddJobView extends Main {
|
||||
todoRow.setFlexGrow(1, todoField);
|
||||
todoList.add(todoRow);
|
||||
|
||||
todoField.addValueChangeListener(ev -> updateTodoItems(todoList, task));
|
||||
todoField.addValueChangeListener(ev -> {
|
||||
updateTodoFieldStyling.accept(todoField);
|
||||
updateTodoItems(todoList, task);
|
||||
});
|
||||
};
|
||||
|
||||
Button addTodoBtn = new Button("To-Do Punkt hinzufügen", new Icon(VaadinIcon.PLUS));
|
||||
@@ -1793,7 +1886,10 @@ public class AddJobView extends Main {
|
||||
TextField todoField = new TextField();
|
||||
todoField.setPlaceholder("To-Do Punkt");
|
||||
todoField.setWidth("100%");
|
||||
todoField.setRequiredIndicatorVisible(true);
|
||||
todoField.setValue(todoText != null ? todoText : ""); // Set the saved text
|
||||
// Apply styling based on value
|
||||
updateTodoFieldStyling.accept(todoField);
|
||||
|
||||
Button removeTodo = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
|
||||
removeTodo.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
|
||||
@@ -1806,7 +1902,10 @@ public class AddJobView extends Main {
|
||||
todoRow.setFlexGrow(1, todoField);
|
||||
todoList.add(todoRow);
|
||||
|
||||
todoField.addValueChangeListener(ev -> updateTodoItems(todoList, task));
|
||||
todoField.addValueChangeListener(ev -> {
|
||||
updateTodoFieldStyling.accept(todoField);
|
||||
updateTodoItems(todoList, task);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Add initial empty todo item if no existing items
|
||||
@@ -1894,6 +1993,10 @@ public class AddJobView extends Main {
|
||||
if (task instanceof TodoListTask) {
|
||||
((TodoListTask) task).setTodoItems(todoItems);
|
||||
}
|
||||
|
||||
// Trigger validation to update submit button state
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2193,6 +2296,8 @@ public class AddJobView extends Main {
|
||||
}
|
||||
|
||||
updateTaskConfiguration(configContainer, newTask);
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2201,6 +2306,8 @@ public class AddJobView extends Main {
|
||||
if (taskType != null) {
|
||||
taskTypeCombo.setValue(taskType);
|
||||
updateTaskConfiguration(configContainer, task);
|
||||
triggerValidation();
|
||||
updateTabLabels();
|
||||
}
|
||||
|
||||
tasksList.add(taskContainer);
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.vaadin.flow.router.Route;
|
||||
import de.assecutor.votianlt.security.SecurityService;
|
||||
import de.assecutor.votianlt.pages.base.ui.view.MainLayout;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import com.vaadin.flow.component.UI;
|
||||
|
||||
@Route(value = "dashboard", layout = MainLayout.class)
|
||||
@PageTitle("VotianLT - Dashboard")
|
||||
@@ -96,12 +95,13 @@ public class AuthenticatedStartView extends VerticalLayout {
|
||||
systemIntro.getStyle().set("max-width", "800px");
|
||||
systemIntro.getStyle().set("margin-bottom", "var(--lumo-space-xl)");
|
||||
|
||||
// Features Grid
|
||||
HorizontalLayout featuresGrid = new HorizontalLayout();
|
||||
featuresGrid.setSpacing(true);
|
||||
featuresGrid.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
|
||||
featuresGrid.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.START);
|
||||
// Features Grid - using Div with CSS flexbox for proper centering
|
||||
Div featuresGrid = new Div();
|
||||
featuresGrid.getStyle().set("display", "flex");
|
||||
featuresGrid.getStyle().set("flex-wrap", "wrap");
|
||||
featuresGrid.getStyle().set("justify-content", "center");
|
||||
featuresGrid.getStyle().set("align-items", "flex-start");
|
||||
featuresGrid.getStyle().set("gap", "var(--lumo-space-l)");
|
||||
featuresGrid.getStyle().set("width", "100%");
|
||||
|
||||
// Feature Cards
|
||||
@@ -126,6 +126,10 @@ public class AuthenticatedStartView extends VerticalLayout {
|
||||
card.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
|
||||
card.getStyle().set("box-shadow", "var(--lumo-box-shadow-s)");
|
||||
card.setWidth("300px");
|
||||
card.setMinWidth("300px");
|
||||
card.setMaxWidth("300px");
|
||||
card.getStyle().set("flex-grow", "0");
|
||||
card.getStyle().set("flex-shrink", "0");
|
||||
|
||||
Icon icon = iconType.create();
|
||||
icon.setSize("48px");
|
||||
@@ -177,6 +181,7 @@ public class AuthenticatedStartView extends VerticalLayout {
|
||||
footer.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||
footer.getStyle().set("background-color", "var(--lumo-contrast-10pct)");
|
||||
footer.getStyle().set("border-top", "1px solid var(--lumo-contrast-20pct)");
|
||||
footer.getStyle().set("margin-top", "auto");
|
||||
|
||||
HorizontalLayout footerContent = new HorizontalLayout();
|
||||
footerContent.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||
|
||||
@@ -221,6 +221,7 @@ public class StartView extends VerticalLayout implements BeforeEnterObserver {
|
||||
HorizontalLayout featuresGrid = new HorizontalLayout();
|
||||
featuresGrid.setWidthFull();
|
||||
featuresGrid.setSpacing(true);
|
||||
featuresGrid.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
|
||||
featuresGrid.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.START);
|
||||
|
||||
// Feature Cards
|
||||
|
||||
Reference in New Issue
Block a user