PaginationAdvice was removed. Added search for order page and translations. Improved pagination fragment. Small enhancements.

This commit is contained in:
Alexey Zinchenko 2019-05-07 01:13:33 +03:00
parent b7ae78d54d
commit ff43965e1f
15 changed files with 128 additions and 46 deletions

View File

@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.github.prominence</groupId>
@ -50,6 +50,7 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
<scope>runtime</scope>
</dependency>
<dependency>

View File

@ -4,6 +4,7 @@ import com.github.prominence.carrepair.model.Client;
import com.github.prominence.carrepair.service.ClientService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@ -25,8 +26,8 @@ public class ClientController {
}
@GetMapping
public String index(ModelMap modelMap) {
Page<Client> clientList = clientService.findAll((Pageable) modelMap.get("pagination"));
public String index(@PageableDefault Pageable pageable, ModelMap modelMap) {
Page<Client> clientList = clientService.findAll(pageable);
modelMap.addAttribute("clientList", clientList.getContent());
modelMap.addAttribute("totalPages", clientList.getTotalPages());

View File

@ -5,6 +5,7 @@ import com.github.prominence.carrepair.model.Mechanic;
import com.github.prominence.carrepair.service.MechanicService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@ -27,8 +28,8 @@ public class MechanicController {
}
@GetMapping
public String index(ModelMap modelMap) {
Page<Mechanic> clientList = mechanicService.findAll((Pageable) modelMap.get("pagination"));
public String index(@PageableDefault Pageable pageable, ModelMap modelMap) {
Page<Mechanic> clientList = mechanicService.findAll(pageable);
modelMap.addAttribute("mechanicList", clientList.getContent());
modelMap.addAttribute("totalPages", clientList.getTotalPages());

View File

@ -2,11 +2,13 @@ package com.github.prominence.carrepair.controller;
import com.github.prominence.carrepair.enums.OrderStatus;
import com.github.prominence.carrepair.model.Order;
import com.github.prominence.carrepair.repository.spec.OrderSpecifications;
import com.github.prominence.carrepair.service.ClientService;
import com.github.prominence.carrepair.service.MechanicService;
import com.github.prominence.carrepair.service.OrderService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@ -32,11 +34,14 @@ public class OrderController {
}
@GetMapping
public String index(ModelMap modelMap) {
Page<Order> orderList = orderService.findAll((Pageable) modelMap.get("pagination"));
public String index(@PageableDefault Pageable pageable, @RequestParam(required = false) String client, @RequestParam(required = false) String description,
@RequestParam(required = false) OrderStatus orderStatus, ModelMap modelMap) {
Page<Order> orderList = orderService.findAll(OrderSpecifications.search(client, description, orderStatus), pageable);
modelMap.addAttribute("orderList", orderList.getContent());
modelMap.addAttribute("totalPages", orderList.getTotalPages());
modelMap.addAttribute("orderStatuses", OrderStatus.values());
return "order/index";
}

View File

@ -1,24 +0,0 @@
package com.github.prominence.carrepair.controller.advice;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestParam;
@ControllerAdvice
public class PaginationAdvice {
private static final int DEFAULT_PAGE_SIZE = 10;
@ModelAttribute("pagination")
public void addPagination(@RequestParam(required = false) Integer size, @RequestParam(required = false) Integer page, Model model) {
final int pageValue = page == null ? 0 : page;
final int sizeValue = size == null ? DEFAULT_PAGE_SIZE : size;
Pageable pagination = PageRequest.of(pageValue, sizeValue);
model.addAttribute("pagination", pagination);
model.addAttribute("page", pageValue);
}
}

View File

@ -2,12 +2,13 @@ package com.github.prominence.carrepair.repository;
import com.github.prominence.carrepair.model.Order;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
public interface OrderRepository extends JpaRepository<Order, Long>, JpaSpecificationExecutor<Order> {
public List<Order> findAllByMechanic_Id(Long id);
}

View File

@ -0,0 +1,39 @@
package com.github.prominence.carrepair.repository.spec;
import com.github.prominence.carrepair.enums.OrderStatus;
import com.github.prominence.carrepair.model.Client;
import com.github.prominence.carrepair.model.Order;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
public class OrderSpecifications {
public static Specification<Order> search(@Nullable String clientQuery, @Nullable String orderDescriptionQuery, @Nullable OrderStatus orderStatusQuery) {
return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (!StringUtils.isEmpty(clientQuery)) {
Join<Order, Client> clientJoin = root.join("client");
predicates.add(
criteriaBuilder.or(
criteriaBuilder.like(clientJoin.get("firstName"), "%" + clientQuery + "%"),
criteriaBuilder.like(clientJoin.get("middleName"), "%" + clientQuery + "%"),
criteriaBuilder.like(clientJoin.get("lastName"), "%" + clientQuery + "%")
)
);
}
if (!StringUtils.isEmpty(orderDescriptionQuery)) {
predicates.add(criteriaBuilder.like(root.get("description"), "%" + orderDescriptionQuery + "%"));
}
if (orderStatusQuery != null) {
predicates.add(criteriaBuilder.equal(root.get("orderStatus"), orderStatusQuery.toString()));
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
}

View File

@ -4,6 +4,7 @@ import com.github.prominence.carrepair.model.Order;
import com.github.prominence.carrepair.repository.OrderRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import java.util.Optional;
@ -21,6 +22,10 @@ public class OrderService {
return orderRepository.findAll(pageable);
}
public Page<Order> findAll(Specification<Order> specification, Pageable pageable) {
return orderRepository.findAll(specification, pageable);
}
public Optional<Order> findById(Long id) {
return orderRepository.findById(id);
}

View File

@ -35,3 +35,7 @@ common.delete.button = Delete
common.save.button = Save
common.edit.button = Edit
common.back.button = Back
common.search.button = Search
common.nothingFound.label = Nothing was found.
common.deleteConfirmation.label = Are you sure to delete?

View File

@ -35,3 +35,7 @@ common.delete.button = Delete
common.save.button = Save
common.edit.button = Edit
common.back.button = Back
common.search.button = Search
common.nothingFound.label = Nothing was found.
common.deleteConfirmation.label = Are you sure to delete?

View File

@ -35,3 +35,7 @@ common.delete.button = Удалить
common.save.button = Сохранить
common.edit.button = Редактировать
common.back.button = Назад
common.search.button = Поиск
common.nothingFound.label = Ничего не найдено.
common.deleteConfirmation.label = Вы действительно хотите удалить?

View File

@ -6,7 +6,7 @@
<script th:inline="javascript">
function deleteClientById(id) {
const confirmationResult = confirm("Are you sure to delete?");
const confirmationResult = confirm(/*[[#{common.deleteConfirmation.label}]]*/);
if (confirmationResult) {
const url = /*[[@{/client/delete/}]]*/;
@ -29,7 +29,7 @@
<a class="btn btn-success" th:href="@{/client/create}" th:text="#{common.create.button}"></a>
</div>
<table class="table table-striped table-hover">
<table class="table table-striped table-hover" th:unless="${clientList.isEmpty()}">
<thead>
<tr>
<th th:text="#{firstName.label}"></th>
@ -54,7 +54,9 @@
</tr>
</tbody>
</table>
<div th:replace="common::pagination(@{/client/}, ${page}, ${totalPages})"></div>
<div th:if="${clientList.isEmpty()}" th:text="#{common.nothingFound.label}"></div>
<div th:replace="common::pagination(${totalPages})"></div>
</div>
</body>

View File

@ -2,11 +2,15 @@
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="pagination(baseUrl, currentPage, totalPages)">
<ul class="pagination pagination-small" th:if="${totalPages > 1}">
<div th:fragment="pagination(totalPages)" th:with="currentPage=${T(Integer).parseInt(#request.getParameter('page') ?: 0)}">
<ul class="pagination pagination-small" th:if="${totalPages > 1}" th:with="urlBuilder=${T(org.springframework.web.servlet.support.ServletUriComponentsBuilder).fromCurrentRequest()}">
<th:block th:each="page : ${#numbers.sequence(0, totalPages - 1, 1)}" th:if="${page == 0 || page == totalPages - 1 || (page >= currentPage - 2 && page <= currentPage + 2)}">
<li class="disabled" th:if="${(page == currentPage - 2 && currentPage > 3) || (page == totalPages - 1 && currentPage < totalPages - 3)}"><a href="javascript:void(0);">...</a></li>
<li th:classappend="${currentPage == page ? 'active' : ''}"><a th:href="${page == 0 ? baseUrl : '?page=' + page}" th:text="${page + 1}"></a></li>
<li class="disabled" th:if="${(page == currentPage - 2 && currentPage > 3) || (page == totalPages - 1 && currentPage < totalPages - 3)}">
<a href="javascript:void(0);">...</a>
</li>
<li th:classappend="${currentPage == page ? 'active' : ''}">
<a th:href="${urlBuilder.replaceQueryParam('page', page).toUriString()}" th:text="${page + 1}"></a>
</li>
</th:block>
</ul>
</div>

View File

@ -6,7 +6,7 @@
<script th:inline="javascript">
function deleteMechanicById(id) {
const confirmationResult = confirm("Are you sure to delete?");
const confirmationResult = confirm(/*[[#{common.deleteConfirmation.label}]]*/);
if (confirmationResult) {
const url = /*[[@{/mechanic/delete/}]]*/;
@ -29,7 +29,7 @@
<a class="btn btn-success" th:href="@{/mechanic/create}" th:text="#{common.create.button}"></a>
</div>
<table class="table table-striped table-hover">
<table class="table table-striped table-hover" th:unless="${mechanicList.isEmpty()}">
<thead>
<tr>
<th th:text="#{firstName.label}"></th>
@ -55,7 +55,9 @@
</tr>
</tbody>
</table>
<div th:replace="common::pagination(@{/mechanic/}, ${page}, ${totalPages})"></div>
<div th:if="${mechanicList.isEmpty()}" th:text="#{common.nothingFound.label}"></div>
<div th:replace="common::pagination(${totalPages})"></div>
</div>
</body>

View File

@ -6,7 +6,7 @@
<script th:inline="javascript">
function deleteOrderById(id) {
const confirmationResult = confirm("Are you sure to delete?");
const confirmationResult = confirm(/*[[#{common.deleteConfirmation.label}]]*/);
if (confirmationResult) {
const url = /*[[@{/order/delete/}]]*/;
@ -25,11 +25,42 @@
<div layout:fragment="content">
<h1 th:text="#{order.title}"></h1>
<div class="row">
<form>
<div class="form-row">
<div class="col-md-4">
<label for="clientSearchInput" th:text="#{client.label}"></label>
<input type="text" class="form-control" name="client" id="clientSearchInput" th:value="${#request.getParameter('client')}" />
</div>
<div class="col-md-4">
<label for="descriptionSearchInput" th:text="#{description.label}"></label>
<input type="text" class="form-control" name="description" id="descriptionSearchInput" th:value="${#request.getParameter('description')}" />
</div>
<div class="col-md-4">
<label for="statusSearchInput" th:text="#{status.label}"></label>
<select class="form-control" th:name="orderStatus" id="statusSearchInput">
<option value=""></option>
<option th:each="orderStatus : ${orderStatuses}" th:value="${orderStatus.toString()}" th:text="${{orderStatus}}"
th:selected="${#request.getParameter('orderStatus') == orderStatus.toString()}"></option>
</select>
</div>
</div>
<div class="form-row pull-right">
<br/>
<div class="col-md-3">
<button type="submit" class="btn btn-primary" th:text="#{common.search.button}"></button>
</div>
</div>
</form>
</div>
<hr/>
<div class="pull-right">
<a class="btn btn-success" th:href="@{/order/create}" th:text="#{common.create.button}"></a>
</div>
<table class="table table-striped table-hover">
<table class="table table-striped table-hover" th:unless="${orderList.isEmpty()}">
<thead>
<tr>
<th th:text="#{client.label}"></th>
@ -60,7 +91,9 @@
</tr>
</tbody>
</table>
<div th:replace="common::pagination(@{/order/}, ${page}, ${totalPages})"></div>
<div th:if="${orderList.isEmpty()}" th:text="#{common.nothingFound.label}"></div>
<div th:replace="common::pagination(${totalPages})"></div>
</div>
</body>