From 4871f56320a1cc23c3042784d7e38b131d7367c8 Mon Sep 17 00:00:00 2001 From: Thomas Peetz Date: Mon, 23 Jun 2025 22:17:45 +0200 Subject: [PATCH] use new SearchField for Comics --- .../comics/repository/ComicRepository.java | 19 +++++++++++ .../kontor/comics/services/ComicService.java | 34 +++++++++++++++++++ .../kontor/comics/views/ComicView.java | 25 ++++++-------- .../kontor/common/views/SearchFilter.java | 10 ++++++ .../common/views/SearchFilterField.java | 5 ++- 5 files changed, 77 insertions(+), 16 deletions(-) diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicRepository.java index 13a4fbc..2da13e1 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicRepository.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicRepository.java @@ -12,9 +12,28 @@ public interface ComicRepository extends JpaRepository { "where lower(c.title) like lower(concat('%', :searchTerm, '%')) ") List search(@Param("searchTerm") String searchTerm); + @Query("select c from Comic c " + + "where lower(c.title) like lower(concat('%', :searchTerm, '%')) " + + "AND c.currentOrder=:currentOrder AND c.completed=:completed") + List search(@Param("searchTerm") String searchTerm, Boolean currentOrder, Boolean completed); + Comic findByTitleAndPublisher(String title, Publisher publisher); List findByTitle(String title); List findByTitleIgnoreCase(String title); + + List findByCurrentOrderAndCompleted(Boolean currentOrder, Boolean completed); + + List findByCurrentOrder(Boolean currentOrder); + + List findByCompleted(Boolean completed); + + @Query("select c from Comic c " + + "where lower(c.title) like lower(concat('%', :searchTerm, '%')) AND c.currentOrder=:currentOrder") + List searchAndFilterByCurrentOrder(String searchTerm, Boolean currentOrder); + + @Query("select c from Comic c " + + "where lower(c.title) like lower(concat('%', :searchTerm, '%')) AND c.completed=:completed") + List searchAndFilterByCompleted(String searchTerm, Boolean completed); } diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/services/ComicService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/services/ComicService.java index e0a3abe..b3e5fc1 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/services/ComicService.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/services/ComicService.java @@ -4,6 +4,8 @@ import java.util.List; import de.thpeetz.kontor.comics.data.*; import de.thpeetz.kontor.comics.repository.*; +import de.thpeetz.kontor.common.views.FilterOption; +import de.thpeetz.kontor.common.views.SearchFilter; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; @@ -71,6 +73,38 @@ public class ComicService { return comicRepository.search(stringFilter); } } + public List findAllComicsByFilter(SearchFilter searchFilter) { + if (searchFilter == null) return comicRepository.findAll(); + if (searchFilter.getFilterOptions().isEmpty()) return comicRepository.search(searchFilter.getSearchTerm()); + if (searchFilter.getFilterOptions().size() == 1) { + FilterOption option = searchFilter.getFilterOptions().getFirst(); + if (searchFilter.getSearchTerm() != null && !searchFilter.getSearchTerm().isEmpty()) { + switch (option.getName()) { + case "Bestellung": + return comicRepository.searchAndFilterByCurrentOrder(searchFilter.getSearchTerm(), option.getValue()); + case "Abgeschlossen": + return comicRepository.searchAndFilterByCompleted(searchFilter.getSearchTerm(), option.getValue()); + } + } + switch (option.getName()) { + case "Bestellung": + return comicRepository.findByCurrentOrder(option.getValue()); + case "Abgeschlossen": + return comicRepository.findByCompleted(option.getValue()); + } + } + if (searchFilter.getFilterOptions().size() == 2) { + if (searchFilter.getSearchTerm() != null && !searchFilter.getSearchTerm().isEmpty()) { + return comicRepository.search(searchFilter.getSearchTerm(), + searchFilter.getFilter("Bestellung").getValue(), + searchFilter.getFilter("Abgeschlossen").getValue()); + } + return comicRepository.findByCurrentOrderAndCompleted(searchFilter.getFilter("Bestellung").getValue(), + searchFilter.getFilter("Abgeschlossen").getValue()); + } + return comicRepository.findAll(); + } + public Comic findComicByTitle(String title) { List comics = comicRepository.findByTitle(title); diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicView.java index 7732b72..7437193 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicView.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicView.java @@ -1,17 +1,17 @@ package de.thpeetz.kontor.comics.views; +import de.thpeetz.kontor.common.views.ColumnToggleContextMenu; +import de.thpeetz.kontor.common.views.MainLayout; +import de.thpeetz.kontor.common.views.SearchFilterField; +import de.thpeetz.kontor.common.views.StatusIcon; import org.springframework.context.annotation.Scope; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.icon.Icon; -import com.vaadin.flow.component.icon.VaadinIcon; 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.value.ValueChangeMode; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import com.vaadin.flow.spring.annotation.SpringComponent; @@ -19,9 +19,6 @@ import com.vaadin.flow.spring.annotation.SpringComponent; import de.thpeetz.kontor.comics.ComicConstants; import de.thpeetz.kontor.comics.data.Comic; import de.thpeetz.kontor.comics.services.ComicService; -import de.thpeetz.kontor.common.views.ColumnToggleContextMenu; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.common.views.StatusIcon; import jakarta.annotation.security.PermitAll; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -52,7 +49,7 @@ public class ComicView extends VerticalLayout { .setHeader("Abgeschlossen").setWidth("6rem").setSortable(true); Grid.Column weblinkColumn = grid.addColumn(Comic::getWeblink) .setHeader("Link").setResizable(true).setSortable(true); - TextField filterText = new TextField(); + SearchFilterField searchFilterField = new SearchFilterField(); @Getter ComicForm form; ComicService service; @@ -106,11 +103,9 @@ public class ComicView extends VerticalLayout { } private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setPrefixComponent(new Icon(VaadinIcon.SEARCH)); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); + searchFilterField.addFilter("Bestellung"); + searchFilterField.addFilter("Abgeschlossen"); + searchFilterField.addValueChangeListener(e -> updateList()); Button addComicButton = new Button("Add comic"); addComicButton.addClickListener(click -> addComic()); @@ -126,7 +121,7 @@ public class ComicView extends VerticalLayout { columnToggleContextMenu.addColumnToggleItem(currentOrderColumn); columnToggleContextMenu.addColumnToggleItem(completedColumn); columnToggleContextMenu.addColumnToggleItem(weblinkColumn); - HorizontalLayout toolbar = new HorizontalLayout(filterText, addComicButton, menuButton); + HorizontalLayout toolbar = new HorizontalLayout(searchFilterField, addComicButton, menuButton); toolbar.addClassName("toolbar"); return toolbar; } @@ -159,6 +154,6 @@ public class ComicView extends VerticalLayout { } public void updateList() { - grid.setItems(service.findAllComics(filterText.getValue())); + grid.setItems(service.findAllComicsByFilter(searchFilterField.getValue())); } } diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilter.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilter.java index 17be822..570564d 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilter.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilter.java @@ -1,8 +1,11 @@ package de.thpeetz.kontor.common.views; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import com.vaadin.flow.component.HasValue; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -17,11 +20,18 @@ public class SearchFilter { @Getter private List filterOptions = new LinkedList<>(); + private final Map filterMap = new HashMap<>(); + public SearchFilter() { } public void addFilter(FilterOption option) { filterOptions.add(option); + filterMap.put(option.getName(), option); + } + + public FilterOption getFilter(String optionName) { + return filterMap.get(optionName); } } diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilterField.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilterField.java index 368ac52..6d627b2 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilterField.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilterField.java @@ -1,7 +1,9 @@ package de.thpeetz.kontor.common.views; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; import com.vaadin.flow.component.combobox.MultiSelectComboBox; @@ -50,7 +52,8 @@ public class SearchFilterField extends CustomField { } public void addFilter(String optionName) { - filterOptions.add(new FilterOption(optionName, true)); + FilterOption filterOption = new FilterOption(optionName, true); + filterOptions.add(filterOption); filterField.setItems(filterOptions); } }