Merge branch '59-filter-conference' into 'dev'

Resolve "Фильтрация списка конференции"

Closes #59

See merge request romanov73/ng-tracker!65
This commit is contained in:
Anton Romanov 2019-04-19 14:46:23 +00:00
commit bc98785be9
9 changed files with 80 additions and 31 deletions

View File

@ -15,10 +15,13 @@ import ru.ulstu.conference.model.ConferenceFilterDto;
import ru.ulstu.conference.model.ConferenceUser; import ru.ulstu.conference.model.ConferenceUser;
import ru.ulstu.conference.service.ConferenceService; import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.user.model.User;
import springfox.documentation.annotations.ApiIgnore; import springfox.documentation.annotations.ApiIgnore;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -44,6 +47,13 @@ public class ConferenceController {
modelMap.put("filteredConferences", new ConferenceFilterDto(conferenceService.findAllDto())); modelMap.put("filteredConferences", new ConferenceFilterDto(conferenceService.findAllDto()));
} }
@PostMapping("/conferences")
public void filterConferences(@Valid ConferenceFilterDto conferenceFilterDto, ModelMap modelMap) {
modelMap.put("filteredConferences", new ConferenceFilterDto(conferenceService.filter(conferenceFilterDto),
conferenceFilterDto.getFilterUserId(),
conferenceFilterDto.getYear()));
}
@GetMapping("/conference") @GetMapping("/conference")
public void getConference(ModelMap modelMap, @RequestParam(value = "id") Integer id) { public void getConference(ModelMap modelMap, @RequestParam(value = "id") Integer id) {
if (id != null && id > 0) { if (id != null && id > 0) {
@ -119,6 +129,20 @@ public class ConferenceController {
return conferenceService.getAllDeposit(); return conferenceService.getAllDeposit();
} }
@ModelAttribute("allUsers")
public List<User> getAllUsers() {
return conferenceService.getAllUsers();
}
@ModelAttribute("allYears")
public List<Integer> getAllYears() {
List<Integer> years = new ArrayList<>();
for (int i = Calendar.getInstance().get(Calendar.YEAR); i > 2010; i--) {
years.add(i);
}
return years;
}
private void filterEmptyDeadlines(ConferenceDto conferenceDto) { private void filterEmptyDeadlines(ConferenceDto conferenceDto) {
conferenceDto.setDeadlines(conferenceDto.getDeadlines().stream() conferenceDto.setDeadlines(conferenceDto.getDeadlines().stream()
.filter(dto -> dto.getDate() != null || !isEmpty(dto.getDescription())) .filter(dto -> dto.getDate() != null || !isEmpty(dto.getDescription()))

View File

@ -18,6 +18,9 @@ import static ru.ulstu.core.util.StreamApiUtils.convert;
public class ConferenceDto { public class ConferenceDto {
private final static String BEGIN_DATE = "Начало: ";
private final static String END_DATE = "Конец: ";
private Integer id; private Integer id;
@NotEmpty @NotEmpty
@Size(min = 2, max = 400) @Size(min = 2, max = 400)
@ -211,4 +214,8 @@ public class ConferenceDto {
this.notSelectedPapers = notSelectedPapers; this.notSelectedPapers = notSelectedPapers;
} }
public String getDatesString() {
return BEGIN_DATE + beginDate.toString().split(" ")[0] + " " + END_DATE + endDate.toString().split(" ")[0];
}
} }

View File

@ -5,15 +5,15 @@ import java.util.List;
public class ConferenceFilterDto { public class ConferenceFilterDto {
private List<ConferenceDto> conferences; private List<ConferenceDto> conferences;
private Integer filterAuthorId; private Integer filterUserId;
private Integer year; private Integer year;
public ConferenceFilterDto() { public ConferenceFilterDto() {
} }
public ConferenceFilterDto(List<ConferenceDto> conferenceDtos, Integer filterAuthorId, Integer year) { public ConferenceFilterDto(List<ConferenceDto> conferenceDtos, Integer filterUserId, Integer year) {
this.conferences = conferenceDtos; this.conferences = conferenceDtos;
this.filterAuthorId = filterAuthorId; this.filterUserId = filterUserId;
this.year = year; this.year = year;
} }
@ -29,12 +29,12 @@ public class ConferenceFilterDto {
this.conferences = conferences; this.conferences = conferences;
} }
public Integer getFilterAuthorId() { public Integer getFilterUserId() {
return filterAuthorId; return filterUserId;
} }
public void setFilterAuthorId(Integer filterAuthorId) { public void setFilterUserId(Integer filterUserId) {
this.filterAuthorId = filterAuthorId; this.filterUserId = filterUserId;
} }
public Integer getYear() { public Integer getYear() {

View File

@ -1,7 +1,14 @@
package ru.ulstu.conference.repository; package ru.ulstu.conference.repository;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.conference.model.Conference; import ru.ulstu.conference.model.Conference;
import ru.ulstu.user.model.User;
import java.util.List;
public interface ConferenceRepository extends JpaRepository<Conference, Integer> { public interface ConferenceRepository extends JpaRepository<Conference, Integer> {
@Query("SELECT c FROM Conference c LEFT JOIN c.users u WHERE (:user IS NULL OR u.user = :user) AND (YEAR(c.beginDate) = :year OR :year IS NULL)")
List<Conference> filter(@Param("user") User user, @Param("year") Integer year);
} }

View File

@ -5,11 +5,13 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.conference.model.Conference; import ru.ulstu.conference.model.Conference;
import ru.ulstu.conference.model.ConferenceDto; import ru.ulstu.conference.model.ConferenceDto;
import ru.ulstu.conference.model.ConferenceFilterDto;
import ru.ulstu.conference.model.ConferenceUser; import ru.ulstu.conference.model.ConferenceUser;
import ru.ulstu.conference.repository.ConferenceRepository; import ru.ulstu.conference.repository.ConferenceRepository;
import ru.ulstu.deadline.service.DeadlineService; import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.service.PaperService; import ru.ulstu.paper.service.PaperService;
import ru.ulstu.user.model.User;
import ru.ulstu.user.service.UserService; import ru.ulstu.user.service.UserService;
import java.io.IOException; import java.io.IOException;
@ -121,6 +123,10 @@ public class ConferenceService {
return paperService.findAllNotSelect(paperIds); return paperService.findAllNotSelect(paperIds);
} }
public List<User> getAllUsers() {
return userService.findAll();
}
public List<ConferenceUser.Participation> getAllParticipations() { public List<ConferenceUser.Participation> getAllParticipations() {
return Arrays.asList(ConferenceUser.Participation.values()); return Arrays.asList(ConferenceUser.Participation.values());
} }
@ -150,4 +156,11 @@ public class ConferenceService {
public boolean isCurrentUserParticipant(List<ConferenceUser> conferenceUsers) { public boolean isCurrentUserParticipant(List<ConferenceUser> conferenceUsers) {
return conferenceUsers.stream().anyMatch(participant -> participant.getUser().equals(userService.getCurrentUser())); return conferenceUsers.stream().anyMatch(participant -> participant.getUser().equals(userService.getCurrentUser()));
} }
public List<ConferenceDto> filter(ConferenceFilterDto conferenceFilterDto) {
return convert(conferenceRepository.filter(
conferenceFilterDto.getFilterUserId() == null ? null : userService.findById(conferenceFilterDto.getFilterUserId()),
conferenceFilterDto.getYear()), ConferenceDto::new);
}
} }

View File

@ -3,7 +3,7 @@ body {
} }
.conference-row .col:hover { .conference-row .col:hover {
background-color: #eaeaea; background-color: #f3f3f3;
border-radius: .25rem; border-radius: .25rem;
} }
@ -11,7 +11,13 @@ body {
color: white; color: white;
} }
.filter .dropdown {
margin-bottom: 10px;
}
.conference-row .col .text-decoration {
text-decoration: none;
}
.form-group textarea { .form-group textarea {

View File

@ -1,17 +1,5 @@
$(document).ready(function () { $(document).ready(function () {
$(".conference-row").mouseenter(function (event) {
var conferenceRow = $(event.target).closest(".conference-row");
$(conferenceRow).css("background-color", "#f8f9fa");
$(conferenceRow).find(".remove-conference").removeClass("d-none");
});
$(".conference-row").mouseleave(function (event) {
var conferenceRow = $(event.target).closest(".conference-row");
$(conferenceRow).css("background-color", "white");
$(conferenceRow).closest(".conference-row").find(".remove-conference").addClass("d-none");
});
$('a[data-confirm]').click(function(ev) { $('a[data-confirm]').click(function(ev) {
var href = $(this).attr('href'); var href = $(this).attr('href');
if (!$('#dataConfirmModal').length) { if (!$('#dataConfirmModal').length) {

View File

@ -27,16 +27,19 @@
<div class="col-md-3 col-sm-12"> <div class="col-md-3 col-sm-12">
<div class="filter"> <div class="filter">
<h5>Фильтр:</h5> <h5>Фильтр:</h5>
<select class="form-control" id="author" <select class="selectpicker form-control" id="user"
onchange="this.form.submit();"> th:field="${filteredConferences.filterUserId}"
<option value="">Все авторы</option> onchange="this.form.submit();" data-style="btn-primary" data-size="5">
<option>lastName <option value="">Все участники</option>
<option th:each="user: ${allUsers}" th:value="${user.id}"
th:text="${user.lastName}">lastName
</option> </option>
</select> </select>
<select class="form-control" id="year" <select class="selectpicker form-control" id="year" th:field="${filteredConferences.year}"
onchange="this.form.submit();"> onchange="this.form.submit();" data-style="btn-primary" data-size="5">
<option value="">Все годы</option> <option value="">Все годы</option>
<option>year <option th:each="year: ${allYears}" th:value="${year}"
th:text="${year}">year
</option> </option>
</select> </select>
</div> </div>

View File

@ -5,13 +5,14 @@
</head> </head>
<body> <body>
<div th:fragment="confLine (conference)" class="row text-left conference-row h3" style="background-color: white;"> <div th:fragment="confLine (conference)" class="row text-left conference-row h3" style="background-color: white;">
<div class="col"> <div class="col d-flex justify-content-between">
<a th:href="@{'conference?id='+${conference.id}}"> <a th:href="@{'conference?id='+${conference.id}}" class="w-100 text-decoration">
<span class="h5" th:text="${conference.title}"/> <span class="h5" th:text="${conference.title}"/>
<span class="text-muted h6 float-right m-2" th:text="${conference.datesString}"/>
</a> </a>
<input class="id-class" type="hidden" th:value="${conference.id}"/> <input class="id-class" type="hidden" th:value="${conference.id}"/>
<a class="remove-paper pull-right" th:href="@{'/conferences/delete/'+${conference.id}}" <a class="remove-paper pull-right m-auto" th:href="@{'/conferences/delete/'+${conference.id}}"
data-confirm="Удалить статью?"> data-confirm="Удалить конференцию?">
<i class="fa fa-trash" aria-hidden="true"></i> <i class="fa fa-trash" aria-hidden="true"></i>
</a> </a>
</div> </div>