diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/FilterOption.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/FilterOption.java new file mode 100644 index 0000000..757d4ed --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/FilterOption.java @@ -0,0 +1,21 @@ +package de.thpeetz.kontor.common.views; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@ToString +public class FilterOption { + @Getter + @Setter + private String name; + + @Getter + @Setter + private Boolean value; + + public FilterOption(String name, Boolean value) { + this.name = name; + this.value = value; + } +} 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 new file mode 100644 index 0000000..17be822 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilter.java @@ -0,0 +1,27 @@ +package de.thpeetz.kontor.common.views; + +import java.util.LinkedList; +import java.util.List; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@ToString +public class SearchFilter { + + @Getter + @Setter + private String searchTerm; + + @Getter + private List filterOptions = new LinkedList<>(); + + public SearchFilter() { + + } + + public void addFilter(FilterOption option) { + filterOptions.add(option); + } +} 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 new file mode 100644 index 0000000..368ac52 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilterField.java @@ -0,0 +1,56 @@ +package de.thpeetz.kontor.common.views; + +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import com.vaadin.flow.component.combobox.MultiSelectComboBox; +import com.vaadin.flow.component.combobox.MultiSelectComboBox.AutoExpandMode; +import com.vaadin.flow.component.customfield.CustomField; +import com.vaadin.flow.component.textfield.TextField; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SearchFilterField extends CustomField { + + private final TextField searchField = new TextField(); + private final MultiSelectComboBox filterField = new MultiSelectComboBox<>(); + private final List filterOptions = new LinkedList<>(); + + public SearchFilterField() { + searchField.setPlaceholder("Search"); + searchField.setClearButtonVisible(true); + filterField.setPlaceholder("Filter"); + filterField.setClearButtonVisible(true); + filterField.setItemLabelGenerator(FilterOption::getName); + filterField.setAutoExpand(AutoExpandMode.BOTH); + add(searchField, filterField); + } + + @Override + protected SearchFilter generateModelValue() { + SearchFilter filter = new SearchFilter(); + if (searchField.getValue() != null) { + filter.setSearchTerm(searchField.getValue()); + } + Set filterOptions = filterField.getValue(); + for (FilterOption filterOption : filterOptions) { + filter.addFilter(filterOption); + } + log.info("use searchfilter: {}", filter); + return filter; + } + + @Override + protected void setPresentationValue(SearchFilter searchFilter) { + log.info("display filter: {}", searchFilter); + if (searchFilter == null) return; + searchField.setValue(searchFilter.getSearchTerm()); + } + + public void addFilter(String optionName) { + filterOptions.add(new FilterOption(optionName, true)); + filterField.setItems(filterOptions); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaFileRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaFileRepository.java deleted file mode 100644 index 7db70e1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaFileRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.thpeetz.kontor.media.data; - -import java.util.List; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface MediaFileRepository extends JpaRepository { - @Query("select m from MediaFile m " + - "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))") - List search(@Param("searchTerm") String searchTerm); - -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActorFileRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorFileRepository.java similarity index 61% rename from kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActorFileRepository.java rename to kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorFileRepository.java index 5f364b7..e680b32 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActorFileRepository.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorFileRepository.java @@ -1,6 +1,8 @@ -package de.thpeetz.kontor.media.data; +package de.thpeetz.kontor.media.repository; import org.springframework.data.jpa.repository.JpaRepository; +import de.thpeetz.kontor.media.data.MediaActorFile; + public interface MediaActorFileRepository extends JpaRepository { } diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorRepository.java similarity index 85% rename from kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActorRepository.java rename to kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorRepository.java index 973e00a..1cd5ff0 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActorRepository.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorRepository.java @@ -1,9 +1,11 @@ -package de.thpeetz.kontor.media.data; +package de.thpeetz.kontor.media.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import de.thpeetz.kontor.media.data.MediaActor; + import java.util.List; public interface MediaActorRepository extends JpaRepository { diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaArticleRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaArticleRepository.java similarity index 84% rename from kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaArticleRepository.java rename to kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaArticleRepository.java index a25702e..6486097 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaArticleRepository.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaArticleRepository.java @@ -1,9 +1,11 @@ -package de.thpeetz.kontor.media.data; +package de.thpeetz.kontor.media.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import de.thpeetz.kontor.media.data.MediaArticle; + import java.util.List; public interface MediaArticleRepository extends JpaRepository { diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaFileRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaFileRepository.java new file mode 100644 index 0000000..1fac388 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaFileRepository.java @@ -0,0 +1,29 @@ +package de.thpeetz.kontor.media.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.media.data.MediaFile; + +public interface MediaFileRepository extends JpaRepository { + @Query("select m from MediaFile m " + + "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))") + List search(@Param("searchTerm") String searchTerm); + + List findByShouldDownload(Boolean shouldDownload); + + List findByReview(Boolean review); + + List findByReviewAndShouldDownload(Boolean review, Boolean shouldDownload); + + @Query("select m from MediaFile m " + + "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%')) " + + "AND m.review=:review AND m.shouldDownload=:download") + List search( + @Param("searchTerm") String searchTerm, + @Param("review") boolean searchReview, + @Param("download") boolean searchDownload); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaVideoRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaVideoRepository.java similarity index 85% rename from kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaVideoRepository.java rename to kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaVideoRepository.java index d898186..25c72e8 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaVideoRepository.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaVideoRepository.java @@ -1,9 +1,11 @@ -package de.thpeetz.kontor.media.data; +package de.thpeetz.kontor.media.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import de.thpeetz.kontor.media.data.MediaVideo; + import java.util.List; public interface MediaVideoRepository extends JpaRepository { diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaArticleService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaArticleService.java index fc78d5d..5f6b994 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaArticleService.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaArticleService.java @@ -1,7 +1,7 @@ package de.thpeetz.kontor.media.services; import de.thpeetz.kontor.media.data.MediaArticle; -import de.thpeetz.kontor.media.data.MediaArticleRepository; +import de.thpeetz.kontor.media.repository.MediaArticleRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaFileService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaFileService.java index 20e6354..47bca10 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaFileService.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaFileService.java @@ -1,11 +1,19 @@ package de.thpeetz.kontor.media.services; -import de.thpeetz.kontor.media.data.*; +import de.thpeetz.kontor.common.views.SearchFilter; +import de.thpeetz.kontor.media.data.MediaActor; +import de.thpeetz.kontor.media.data.MediaActorFile; +import de.thpeetz.kontor.media.data.MediaFile; +import de.thpeetz.kontor.media.repository.MediaActorFileRepository; +import de.thpeetz.kontor.media.repository.MediaActorRepository; +import de.thpeetz.kontor.media.repository.MediaFileRepository; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; import java.util.List; +import org.springframework.stereotype.Service; + + @Slf4j @Service public class MediaFileService { @@ -20,7 +28,7 @@ public class MediaFileService { this.mediaActorFileRepository = mediaActorFileRepository; } - public List findAllMediaFiles(String stringFilter) { + public List findAllMediaFilesByString(String stringFilter) { List results; if (stringFilter == null || stringFilter.isEmpty()) { results = mediaFileRepository.findAll(); @@ -31,6 +39,42 @@ public class MediaFileService { return results; } + public List findAllMediaFiles(SearchFilter searchFilter) { + if (searchFilter == null) { + return mediaFileRepository.findAll(); + } else { + if (searchFilter.getSearchTerm() != null && searchFilter.getFilterOptions().isEmpty()) { + log.info("find MediaFiles by using searchTerm: {}", searchFilter.getSearchTerm()); + List results = mediaFileRepository.search(searchFilter.getSearchTerm()); + log.info("found {} entries", results.size()); + return results; + } + if (searchFilter.getFilterOptions().size() == 1) { + log.info("using searchFilter: {}", searchFilter); + String filter = searchFilter.getFilterOptions().get(0).getName(); + Boolean filterValue = searchFilter.getFilterOptions().get(0).getValue(); + if (filter == "Überprüfung") { + List results = mediaFileRepository.findByReview(filterValue); + log.info("found {} entries", results.size()); + return results; + } + if (filter == "Download") { + List results = mediaFileRepository.findByShouldDownload(filterValue); + log.info("found {} entries", results.size()); + return results; + } + } + if (searchFilter.getFilterOptions().size() == 2) { + log.info("using searchFilter: {}", searchFilter); + List results = mediaFileRepository.search(searchFilter.getSearchTerm(), searchFilter.getFilterOptions().get(0).getValue(), searchFilter.getFilterOptions().get(1).getValue()); + log.info("found {} entries", results.size()); + return results; + } + } + log.info("noch filter used"); + return mediaFileRepository.findAll(); + } + public void saveMediaFile(MediaFile mediaFile) { if (mediaFile == null) { log.warn("MediaFile is null. Are you sure you have connected your form to the application?"); diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaVideoService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaVideoService.java index 61299fd..aaff14a 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaVideoService.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaVideoService.java @@ -1,7 +1,7 @@ package de.thpeetz.kontor.media.services; import de.thpeetz.kontor.media.data.MediaVideo; -import de.thpeetz.kontor.media.data.MediaVideoRepository; +import de.thpeetz.kontor.media.repository.MediaVideoRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileView.java index a5c182c..54bc040 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileView.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileView.java @@ -3,21 +3,13 @@ package de.thpeetz.kontor.media.views; 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.contextmenu.ContextMenu; -import com.vaadin.flow.component.contextmenu.MenuItem; 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; -import de.thpeetz.kontor.common.views.ColumnToggleContextMenu; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.common.views.StatusIcon; +import de.thpeetz.kontor.common.views.*; import de.thpeetz.kontor.media.data.MediaFile; import de.thpeetz.kontor.media.services.MediaFileService; import jakarta.annotation.security.RolesAllowed; @@ -53,7 +45,7 @@ public class MediaFileView extends VerticalLayout { setHeader("Überprüfung").setWidth("6rem").setSortable(true); Grid.Column shouldDownloadColumn = grid.addComponentColumn(mediafile -> StatusIcon.create(mediafile.isShouldDownload())). setHeader("Download?").setWidth("6rem").setSortable(true); - TextField searchField = new TextField(); + SearchFilterField searchFilterField = new SearchFilterField(); @Getter MediaFileForm form; MediaFileService service; @@ -108,11 +100,9 @@ public class MediaFileView extends VerticalLayout { } private HorizontalLayout getToolbar() { - searchField.setPlaceholder("Search"); - searchField.setClearButtonVisible(true); - searchField.setPrefixComponent(new Icon(VaadinIcon.SEARCH)); - searchField.setValueChangeMode(ValueChangeMode.EAGER); - searchField.addValueChangeListener(e -> updateList()); + searchFilterField.addFilter("Überprüfung"); + searchFilterField.addFilter("Download"); + searchFilterField.addValueChangeListener(e -> updateList()); Button addMediaFileButton = new Button("Add MediaFile"); addMediaFileButton.addClickListener(click -> addMediaFile()); @@ -129,7 +119,7 @@ public class MediaFileView extends VerticalLayout { columnToggleContextMenu.addColumnToggleItem(cloudLinkColumn); columnToggleContextMenu.addColumnToggleItem(reviewColumn); columnToggleContextMenu.addColumnToggleItem(shouldDownloadColumn); - HorizontalLayout toolbar = new HorizontalLayout(searchField, addMediaFileButton, menuButton); + HorizontalLayout toolbar = new HorizontalLayout(searchFilterField, addMediaFileButton, menuButton); toolbar.addClassName("toolbar"); return toolbar; } @@ -162,6 +152,7 @@ public class MediaFileView extends VerticalLayout { } public void updateList() { - grid.setItems(service.findAllMediaFiles(searchField.getValue())); + log.info("searchFilterField: {}", searchFilterField.getValue()); + grid.setItems(service.findAllMediaFiles(searchFilterField.getValue())); } } diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaArticleTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaArticleTest.java index 2f2adc7..365968f 100644 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaArticleTest.java +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaArticleTest.java @@ -1,5 +1,6 @@ package de.thpeetz.kontor.media.data; +import de.thpeetz.kontor.media.repository.MediaArticleRepository; import de.thpeetz.kontor.media.services.MediaArticleService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaFileTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaFileTest.java index 6ca61ce..e1055ac 100644 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaFileTest.java +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaFileTest.java @@ -4,6 +4,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import de.thpeetz.kontor.media.repository.MediaFileRepository; + import java.util.List; import static org.junit.jupiter.api.Assertions.*; diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaVideoTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaVideoTest.java index 1a40335..73809d8 100644 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaVideoTest.java +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaVideoTest.java @@ -5,6 +5,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import de.thpeetz.kontor.media.repository.MediaVideoRepository; + import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertFalse;