diff --git a/src/main/java/de/assecutor/votianlt/pages/base/ui/view/MainLayout.java b/src/main/java/de/assecutor/votianlt/pages/base/ui/view/MainLayout.java index 849e015..d5ea2cc 100644 --- a/src/main/java/de/assecutor/votianlt/pages/base/ui/view/MainLayout.java +++ b/src/main/java/de/assecutor/votianlt/pages/base/ui/view/MainLayout.java @@ -16,11 +16,13 @@ import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.sidenav.SideNav; import com.vaadin.flow.component.sidenav.SideNavItem; import com.vaadin.flow.router.Layout; +import com.vaadin.flow.server.auth.AnonymousAllowed; import com.vaadin.flow.server.menu.MenuConfiguration; import com.vaadin.flow.server.menu.MenuEntry; import de.assecutor.votianlt.security.SecurityService; import static com.vaadin.flow.theme.lumo.LumoUtility.*; +@AnonymousAllowed @Layout public final class MainLayout extends AppLayout { @@ -51,7 +53,7 @@ public final class MainLayout extends AppLayout { private Component createSideNav() { var nav = new SideNav(); nav.addClassNames(Margin.Horizontal.MEDIUM); - + MenuConfiguration.getMenuEntries().forEach(entry -> { // Skip "Verwaltung" entry as we'll handle it separately with Details component if (!"Verwaltung".equals(entry.title())) { @@ -59,7 +61,7 @@ public final class MainLayout extends AppLayout { nav.addItem(item); } }); - + // Create Details component for "Verwaltung" with collapsible list Details verwaltungDetails = new Details(); verwaltungDetails.setSummaryText("Verwaltung"); @@ -69,9 +71,9 @@ public final class MainLayout extends AppLayout { VerticalLayout verwaltungContent = new VerticalLayout(); verwaltungContent.setPadding(false); verwaltungContent.setSpacing(true); - + // Create navigation items for the collapsible list - SideNavItem jobs = new SideNavItem("Aufträge", "1", new Icon(VaadinIcon.COG)); + SideNavItem jobs = new SideNavItem("Aufträge", "jobs", new Icon(VaadinIcon.LIST)); SideNavItem customers = new SideNavItem("Kunden", "2", new Icon(VaadinIcon.COG)); SideNavItem appUsers = new SideNavItem("App-Nutzer", "3", new Icon(VaadinIcon.COG)); SideNavItem devices = new SideNavItem("Endgeräte", "4", new Icon(VaadinIcon.COG)); diff --git a/src/main/java/de/assecutor/votianlt/pages/jobs/ui/view/ShowJobsView.java b/src/main/java/de/assecutor/votianlt/pages/jobs/ui/view/ShowJobsView.java new file mode 100644 index 0000000..943c7e5 --- /dev/null +++ b/src/main/java/de/assecutor/votianlt/pages/jobs/ui/view/ShowJobsView.java @@ -0,0 +1,78 @@ +package de.assecutor.votianlt.pages.jobs.ui.view; + +import com.vaadin.flow.component.datepicker.DatePicker; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.html.H2; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import de.assecutor.votianlt.model.Job; +import de.assecutor.votianlt.model.JobStatus; +import de.assecutor.votianlt.repository.JobRepository; +import jakarta.annotation.security.RolesAllowed; +import org.springframework.beans.factory.annotation.Autowired; + +@PageTitle("Aufträge") +@Route(value = "jobs", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class) +@RolesAllowed({"USER"}) +public class ShowJobsView extends VerticalLayout { + + private final DatePicker startDate = new DatePicker("Startdatum"); + private final DatePicker endDate = new DatePicker("Enddatum"); + private final Button applyFilter = new Button("Anwenden"); + private final JobRepository jobRepository; + private final Grid grid = new Grid<>(Job.class, false); + + @Autowired + public ShowJobsView(JobRepository jobRepository) { + this.jobRepository = jobRepository; + setSizeFull(); + setPadding(true); + setSpacing(true); + // Filterleiste + HorizontalLayout filterBar = new HorizontalLayout(startDate, endDate, applyFilter); + filterBar.setAlignItems(Alignment.END); + add(filterBar); + + + add(new H2("Offene Aufträge")); + // Init default period: last 30 days + java.time.LocalDate today = java.time.LocalDate.now(); + startDate.setValue(today.minusDays(30)); + endDate.setValue(today); + applyFilter.addClickListener(e -> loadData()); + + + // Configure grid columns: Kunde, Auftragsnummer, Auftragsdatum, Zielort + grid.addColumn(Job::getDeliveryCompany).setHeader("Kunde").setAutoWidth(true).setFlexGrow(1); + grid.addColumn(Job::getJobNumber).setHeader("Auftragsnummer").setAutoWidth(true); + grid.addColumn(Job::getCreatedAt).setHeader("Auftragsdatum").setAutoWidth(true); + grid.addColumn(Job::getDeliveryCity).setHeader("Zielort").setAutoWidth(true).setFlexGrow(1); + + grid.setSizeFull(); + add(grid); + + loadData(); + } + + private void loadData() { + var start = startDate.getValue(); + var end = endDate.getValue(); + java.time.LocalDateTime startDt = start != null ? start.atStartOfDay() : java.time.LocalDate.now().minusDays(30).atStartOfDay(); + java.time.LocalDateTime endDt = end != null ? end.atTime(23,59,59) : java.time.LocalDate.now().atTime(23,59,59); + + // Hole Aufträge im Zeitraum und filtere auf offene Stati + var inRange = jobRepository.findByCreatedAtBetween(startDt, endDt); + var open = inRange.stream() + .filter(j -> j.getStatus() == JobStatus.CREATED + || j.getStatus() == JobStatus.IN_PROGRESS + || j.getStatus() == JobStatus.PICKUP_SCHEDULED + || j.getStatus() == JobStatus.PICKED_UP + || j.getStatus() == JobStatus.IN_TRANSIT) + .toList(); + grid.setItems(open); + } +} +