Merge branch '46-mvc' into 'master'
Resolve "Перевести на MVC контроллеры" Closes #46 See merge request romanov73/ng-tracker!22
This commit is contained in:
commit
503f7f68bc
@ -116,6 +116,7 @@ dependencies {
|
||||
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'
|
||||
|
||||
compile group: 'org.webjars', name: 'bootstrap', version: '4.1.0'
|
||||
compile group: 'org.webjars', name: 'bootstrap-select', version: '1.13.3'
|
||||
compile group: 'org.webjars', name: 'jquery', version: '3.3.1-1'
|
||||
compile group: 'org.webjars.npm', name: 'jquery.easing', version: '1.4.1'
|
||||
compile group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
|
||||
|
@ -97,10 +97,4 @@ public class AdviceController {
|
||||
public ResponseExtended<String> handleUserIsUndeadException(Throwable e) {
|
||||
return handleException(ErrorConstants.USER_UNDEAD_ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseExtended<String> handleUnknownException(Throwable e) {
|
||||
e.printStackTrace();
|
||||
return handleException(ErrorConstants.UNKNOWN, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,20 @@ package ru.ulstu.deadline.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class DeadlineDto {
|
||||
private final Integer id;
|
||||
private Integer id;
|
||||
|
||||
private final String description;
|
||||
private String description;
|
||||
|
||||
private final Date date;
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date date;
|
||||
|
||||
public DeadlineDto() {
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public DeadlineDto(@JsonProperty("id") Integer id,
|
||||
@ -38,4 +43,16 @@ public class DeadlineDto {
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static ru.ulstu.paper.controller.PaperController.URL;
|
||||
import static ru.ulstu.file.FileController.URL;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(URL)
|
||||
|
@ -1,70 +1,117 @@
|
||||
package ru.ulstu.paper.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.ulstu.configuration.Constants;
|
||||
import ru.ulstu.core.model.response.Response;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import ru.ulstu.deadline.model.DeadlineDto;
|
||||
import ru.ulstu.paper.model.Paper;
|
||||
import ru.ulstu.paper.model.PaperDto;
|
||||
import ru.ulstu.paper.model.PaperFilterDto;
|
||||
import ru.ulstu.paper.model.PaperStatusDto;
|
||||
import ru.ulstu.paper.service.PaperService;
|
||||
import ru.ulstu.user.model.User;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ru.ulstu.paper.controller.PaperController.URL;
|
||||
import static org.springframework.util.StringUtils.isEmpty;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(URL)
|
||||
|
||||
@Controller()
|
||||
@RequestMapping(value = "/papers")
|
||||
public class PaperController {
|
||||
public static final String URL = Constants.API_1_0 + "papers";
|
||||
|
||||
private final PaperService paperService;
|
||||
|
||||
public PaperController(PaperService paperService) {
|
||||
this.paperService = paperService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Response<List<PaperDto>> getPapers() {
|
||||
return new Response<>(paperService.findAllDto());
|
||||
@GetMapping("/papers")
|
||||
public void getPapers(ModelMap modelMap) {
|
||||
modelMap.put("filteredPapers", new PaperFilterDto(paperService.findAllDto(), null, null));
|
||||
}
|
||||
|
||||
@GetMapping("/{paper-id}")
|
||||
public Response<PaperDto> getPaper(@PathVariable("paper-id") Integer paperId){
|
||||
return new Response(paperService.findPaper(paperId));
|
||||
@PostMapping("/papers")
|
||||
public void filterPapers(@Valid PaperFilterDto paperFilterDto, ModelMap modelMap) {
|
||||
modelMap.put("filteredPapers", new PaperFilterDto(paperService.filter(paperFilterDto),
|
||||
paperFilterDto.getFilterAuthorId(),
|
||||
paperFilterDto.getYear()));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Response<Integer> createPaper(@RequestBody @Valid PaperDto paperDto) throws IOException {
|
||||
return new Response<>(paperService.create(paperDto));
|
||||
@GetMapping("/dashboard")
|
||||
public void getDashboard(ModelMap modelMap) {
|
||||
modelMap.put("papers", paperService.findAllDto());
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public Response<Integer> updatePaper(@RequestBody @Valid PaperDto paperDto) throws IOException {
|
||||
return new Response<>(paperService.update(paperDto));
|
||||
@GetMapping("/paper")
|
||||
public void getPapers(ModelMap modelMap, @RequestParam(value = "id") Integer id) {
|
||||
if (id != null && id > 0) {
|
||||
modelMap.put("paperDto", paperService.findOneDto(id));
|
||||
} else {
|
||||
modelMap.put("paperDto", new PaperDto());
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/{paper-id}")
|
||||
public Response<Boolean> delete(@PathVariable("paper-id") Integer paperId) throws IOException {
|
||||
@PostMapping(value = "/paper", params = "save")
|
||||
public String save(@Valid PaperDto paperDto, Errors errors) throws IOException {
|
||||
filterEmptyDeadlines(paperDto);
|
||||
if (paperDto.getDeadlines().isEmpty()) {
|
||||
errors.rejectValue("deadlines", "errorCode","Не может быть пустым");
|
||||
}
|
||||
if (errors.hasErrors()) {
|
||||
return "/papers/paper";
|
||||
}
|
||||
paperService.save(paperDto);
|
||||
return "redirect:/papers/papers";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/paper", params = "addDeadline")
|
||||
public String addDeadline(@Valid PaperDto paperDto, Errors errors) {
|
||||
filterEmptyDeadlines(paperDto);
|
||||
if (errors.hasErrors()) {
|
||||
return "/papers/paper";
|
||||
}
|
||||
paperDto.getDeadlines().add(new DeadlineDto());
|
||||
return "/papers/paper";
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{paper-id}")
|
||||
public String delete(@PathVariable("paper-id") Integer paperId) throws IOException {
|
||||
paperService.delete(paperId);
|
||||
return new Response<>(true);
|
||||
return "redirect:/papers/papers";
|
||||
}
|
||||
|
||||
@GetMapping("/statuses")
|
||||
public Response<List<PaperStatusDto>> getPaperStatuses() {
|
||||
return new Response<>(paperService.getPaperStatuses());
|
||||
@ModelAttribute("allStatuses")
|
||||
public List<Paper.PaperStatus> getPaperStatuses() {
|
||||
return paperService.getPaperStatuses();
|
||||
}
|
||||
|
||||
@PostMapping("/filter")
|
||||
public Response<List<PaperDto>> filter(@RequestBody @Valid PaperFilterDto paperFilterDto) throws IOException {
|
||||
return new Response<>(paperService.filter(paperFilterDto));
|
||||
@ModelAttribute("allAuthors")
|
||||
public List<User> getAllAuthors() {
|
||||
return paperService.getPaperAuthors();
|
||||
}
|
||||
|
||||
@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(PaperDto paperDto) {
|
||||
paperDto.setDeadlines(paperDto.getDeadlines().stream()
|
||||
.filter(dto -> dto.getDate() != null || !isEmpty(dto.getDescription()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
package ru.ulstu.paper.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.ulstu.configuration.Constants;
|
||||
import ru.ulstu.core.model.response.Response;
|
||||
import ru.ulstu.paper.model.PaperDto;
|
||||
import ru.ulstu.paper.model.PaperFilterDto;
|
||||
import ru.ulstu.paper.service.PaperService;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static ru.ulstu.paper.controller.PaperRestController.URL;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(URL)
|
||||
public class PaperRestController {
|
||||
public static final String URL = Constants.API_1_0 + "papers";
|
||||
|
||||
private final PaperService paperService;
|
||||
|
||||
public PaperRestController(PaperService paperService) {
|
||||
this.paperService = paperService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Response<List<PaperDto>> getPapers() {
|
||||
return new Response<>(paperService.findAllDto());
|
||||
}
|
||||
|
||||
@GetMapping("/{paper-id}")
|
||||
public Response<PaperDto> getPaper(@PathVariable("paper-id") Integer paperId){
|
||||
return new Response(paperService.findById(paperId));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Response<Integer> createPaper(@RequestBody @Valid PaperDto paperDto) throws IOException {
|
||||
return new Response<>(paperService.create(paperDto));
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public Response<Integer> updatePaper(@RequestBody @Valid PaperDto paperDto) throws IOException {
|
||||
return new Response<>(paperService.update(paperDto));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{paper-id}")
|
||||
public Response<Boolean> delete(@PathVariable("paper-id") Integer paperId) throws IOException {
|
||||
paperService.delete(paperId);
|
||||
return new Response<>(true);
|
||||
}
|
||||
|
||||
@PostMapping("/filter")
|
||||
public Response<List<PaperDto>> filter(@RequestBody @Valid PaperFilterDto paperFilterDto) throws IOException {
|
||||
return new Response<>(paperService.filter(paperFilterDto));
|
||||
}
|
||||
}
|
@ -16,6 +16,8 @@ import javax.persistence.FetchType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
@ -36,14 +38,14 @@ public class Paper extends BaseEntity implements UserContainer {
|
||||
COMPLETED("Завершена"),
|
||||
FAILED("Провалены сроки");
|
||||
|
||||
private String name;
|
||||
private String statusName;
|
||||
|
||||
PaperStatus(String name) {
|
||||
this.name = name;
|
||||
this.statusName = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
public String getStatusName() {
|
||||
return statusName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,12 +56,14 @@ public class Paper extends BaseEntity implements UserContainer {
|
||||
private PaperStatus status = PaperStatus.DRAFT;
|
||||
|
||||
@Column(name = "create_date")
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date createDate = new Date();
|
||||
|
||||
@Column(name = "update_date")
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date updateDate = new Date();
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "paper_id")
|
||||
private List<Deadline> deadlines = new ArrayList<>();
|
||||
|
||||
@ -154,6 +158,7 @@ public class Paper extends BaseEntity implements UserContainer {
|
||||
public Optional<Deadline> getNextDeadline() {
|
||||
return deadlines
|
||||
.stream()
|
||||
.filter(deadline -> deadline.getDate() != null)
|
||||
.sorted(Comparator.comparing(Deadline::getDate))
|
||||
.filter(d -> d.getDate().after(new Date()))
|
||||
.findFirst();
|
||||
|
@ -6,7 +6,8 @@ import org.hibernate.validator.constraints.NotEmpty;
|
||||
import ru.ulstu.deadline.model.DeadlineDto;
|
||||
import ru.ulstu.user.model.UserDto;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -15,20 +16,28 @@ import java.util.stream.Collectors;
|
||||
import static ru.ulstu.core.util.StreamApiUtils.convert;
|
||||
|
||||
public class PaperDto {
|
||||
private final Integer id;
|
||||
private Integer id;
|
||||
@NotEmpty
|
||||
private final String title;
|
||||
private final Paper.PaperStatus status;
|
||||
private final Date createDate;
|
||||
private final Date updateDate;
|
||||
private final List<DeadlineDto> deadlines;
|
||||
private final String comment;
|
||||
private final Boolean locked;
|
||||
private final String tmpFileName;
|
||||
private final Integer fileId;
|
||||
private final String fileName;
|
||||
private final Date fileCreateDate;
|
||||
private final Set<UserDto> authors;
|
||||
@Size(min = 3, max = 100)
|
||||
private String title;
|
||||
private Paper.PaperStatus status;
|
||||
private Date createDate;
|
||||
private Date updateDate;
|
||||
@NotEmpty
|
||||
private List<DeadlineDto> deadlines = new ArrayList<>();
|
||||
private String comment;
|
||||
private Boolean locked;
|
||||
private String tmpFileName;
|
||||
private Integer fileId;
|
||||
private String fileName;
|
||||
private Date fileCreateDate;
|
||||
private Set<Integer> authorIds;
|
||||
private Set<UserDto> authors;
|
||||
private Integer filterAuthorId;
|
||||
|
||||
public PaperDto() {
|
||||
deadlines.add(new DeadlineDto());
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public PaperDto(@JsonProperty("id") Integer id,
|
||||
@ -40,6 +49,7 @@ public class PaperDto {
|
||||
@JsonProperty("comment") String comment,
|
||||
@JsonProperty("locked") Boolean locked,
|
||||
@JsonProperty("tmpFileName") String tmpFileName,
|
||||
@JsonProperty("authorIds") Set<Integer> authorIds,
|
||||
@JsonProperty("authors") Set<UserDto> authors) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
@ -69,6 +79,7 @@ public class PaperDto {
|
||||
this.fileId = paper.getFileData() == null ? null : paper.getFileData().getId();
|
||||
this.fileName = paper.getFileData() == null ? null : paper.getFileData().getName();
|
||||
this.fileCreateDate = paper.getFileData() == null ? null : paper.getFileData().getCreateDate();
|
||||
this.authorIds = convert(paper.getAuthors(), user -> user.getId());
|
||||
this.authors = convert(paper.getAuthors(), UserDto::new);
|
||||
}
|
||||
|
||||
@ -76,58 +87,126 @@ public class PaperDto {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Paper.PaperStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Paper.PaperStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Date getCreateDate() {
|
||||
return createDate;
|
||||
}
|
||||
|
||||
public void setCreateDate(Date createDate) {
|
||||
this.createDate = createDate;
|
||||
}
|
||||
|
||||
public Date getUpdateDate() {
|
||||
return updateDate;
|
||||
}
|
||||
|
||||
public void setUpdateDate(Date updateDate) {
|
||||
this.updateDate = updateDate;
|
||||
}
|
||||
|
||||
public List<DeadlineDto> getDeadlines() {
|
||||
return deadlines;
|
||||
}
|
||||
|
||||
public void setDeadlines(List<DeadlineDto> deadlines) {
|
||||
this.deadlines = deadlines;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public Boolean getLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(Boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
public String getTmpFileName() {
|
||||
return tmpFileName;
|
||||
}
|
||||
|
||||
public void setTmpFileName(String tmpFileName) {
|
||||
this.tmpFileName = tmpFileName;
|
||||
}
|
||||
|
||||
public Integer getFileId() {
|
||||
return fileId;
|
||||
}
|
||||
|
||||
public void setFileId(Integer fileId) {
|
||||
this.fileId = fileId;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public Date getFileCreateDate() {
|
||||
return fileCreateDate;
|
||||
}
|
||||
|
||||
public void setFileCreateDate(Date fileCreateDate) {
|
||||
this.fileCreateDate = fileCreateDate;
|
||||
}
|
||||
|
||||
public Set<UserDto> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public void setAuthors(Set<UserDto> authors) {
|
||||
this.authors = authors;
|
||||
}
|
||||
|
||||
public Set<Integer> getAuthorIds() {
|
||||
return authorIds;
|
||||
}
|
||||
|
||||
public void setAuthorIds(Set<Integer> authorIds) {
|
||||
this.authorIds = authorIds;
|
||||
}
|
||||
|
||||
public String getAuthorsString() {
|
||||
return authors
|
||||
.stream()
|
||||
.map(author -> author.getLastName() + author.getFirstName())
|
||||
.map(author -> author.getLastName())
|
||||
.collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
public Integer getFilterAuthorId() {
|
||||
return filterAuthorId;
|
||||
}
|
||||
|
||||
public void setFilterAuthorId(Integer filterAuthorId) {
|
||||
this.filterAuthorId = filterAuthorId;
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,42 @@
|
||||
package ru.ulstu.paper.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.List;
|
||||
|
||||
public class PaperFilterDto {
|
||||
private final Integer authorId;
|
||||
private final Integer year;
|
||||
private List<PaperDto> papers;
|
||||
private Integer filterAuthorId;
|
||||
private Integer year;
|
||||
|
||||
@JsonCreator
|
||||
public PaperFilterDto(@JsonProperty("authorId") Integer authorId,
|
||||
@JsonProperty("year") Integer year) {
|
||||
this.authorId = authorId;
|
||||
public PaperFilterDto() {
|
||||
}
|
||||
|
||||
public PaperFilterDto(List<PaperDto> paperDtos, Integer filterAuthorId, Integer year) {
|
||||
this.papers = paperDtos;
|
||||
this.filterAuthorId = filterAuthorId;
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public Integer getAuthorId() {
|
||||
return authorId;
|
||||
public List<PaperDto> getPapers() {
|
||||
return papers;
|
||||
}
|
||||
|
||||
public void setPapers(List<PaperDto> papers) {
|
||||
this.papers = papers;
|
||||
}
|
||||
|
||||
public Integer getFilterAuthorId() {
|
||||
return filterAuthorId;
|
||||
}
|
||||
|
||||
public void setFilterAuthorId(Integer filterAuthorId) {
|
||||
this.filterAuthorId = filterAuthorId;
|
||||
}
|
||||
|
||||
public Integer getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(Integer year) {
|
||||
this.year = year;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
package ru.ulstu.paper.model;
|
||||
|
||||
public class PaperStatusDto {
|
||||
private final String id;
|
||||
private final String name;
|
||||
|
||||
public PaperStatusDto(Paper.PaperStatus status) {
|
||||
this.id = status.name();
|
||||
this.name = status.getName();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
@ -10,6 +10,6 @@ import java.util.List;
|
||||
|
||||
public interface PaperRepository extends JpaRepository<Paper, Integer> {
|
||||
|
||||
@Query("SELECT p FROM Paper p WHERE (:author IS NULL OR :author MEMBER OF p.authors) AND YEAR(p.createDate) = :year OR :year IS NULL")
|
||||
@Query("SELECT p FROM Paper p WHERE (:author IS NULL OR :author MEMBER OF p.authors) AND (YEAR(p.createDate) = :year OR :year IS NULL)")
|
||||
List<Paper> filter(@Param("author") User author, @Param("year") Integer year);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PaperScheduler {
|
||||
private final static boolean IS_DEADLINE_NOTIFICATION_BEFORE_WEEK = true;
|
||||
private final static boolean IS_DEADLINE_NOTIFICATION_AFTER_WEEK = true;
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(PaperScheduler.class);
|
||||
|
||||
@ -24,14 +24,14 @@ public class PaperScheduler {
|
||||
@Scheduled(cron = "0 0 8 * 1 ?")
|
||||
public void checkDeadlineBeforeWeek() {
|
||||
log.debug("PaperScheduler.checkDeadlineBeforeWeek started");
|
||||
paperNotificationService.sendDeadlineNotifications(paperService.findAll(), !IS_DEADLINE_NOTIFICATION_BEFORE_WEEK);
|
||||
paperNotificationService.sendDeadlineNotifications(paperService.findAll(), !IS_DEADLINE_NOTIFICATION_AFTER_WEEK);
|
||||
log.debug("PaperScheduler.checkDeadlineBeforeWeek finished");
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0 8 * * ?")
|
||||
public void checkDeadlineAfterWeek() {
|
||||
log.debug("PaperScheduler.checkDeadlineAfterWeek started");
|
||||
paperNotificationService.sendDeadlineNotifications(paperService.findAll(), IS_DEADLINE_NOTIFICATION_BEFORE_WEEK);
|
||||
paperNotificationService.sendDeadlineNotifications(paperService.findAll(), IS_DEADLINE_NOTIFICATION_AFTER_WEEK);
|
||||
log.debug("PaperScheduler.checkDeadlineAfterWeek finished");
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import ru.ulstu.file.service.FileService;
|
||||
import ru.ulstu.paper.model.Paper;
|
||||
import ru.ulstu.paper.model.PaperDto;
|
||||
import ru.ulstu.paper.model.PaperFilterDto;
|
||||
import ru.ulstu.paper.model.PaperStatusDto;
|
||||
import ru.ulstu.paper.repository.PaperRepository;
|
||||
import ru.ulstu.user.model.User;
|
||||
import ru.ulstu.user.service.UserService;
|
||||
@ -16,9 +15,12 @@ import ru.ulstu.user.service.UserService;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
import static ru.ulstu.core.util.StreamApiUtils.convert;
|
||||
import static ru.ulstu.paper.model.Paper.PaperStatus.ATTENTION;
|
||||
import static ru.ulstu.paper.model.Paper.PaperStatus.DRAFT;
|
||||
@ -60,6 +62,10 @@ public class PaperService {
|
||||
return convert(findAll(), PaperDto::new);
|
||||
}
|
||||
|
||||
public PaperDto findOneDto(Integer id) {
|
||||
return new PaperDto(paperRepository.findOne(id));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Integer create(PaperDto paperDto) throws IOException {
|
||||
Paper newPaper = copyFromDto(new Paper(), paperDto);
|
||||
@ -79,8 +85,9 @@ public class PaperService {
|
||||
if (paperDto.getTmpFileName() != null) {
|
||||
paper.setFileData(fileService.createFileFromTmp(paperDto.getTmpFileName()));
|
||||
}
|
||||
if (paperDto.getAuthors() != null && !paperDto.getAuthors().isEmpty()) {
|
||||
paperDto.getAuthors().forEach(authorIds -> paper.getAuthors().add(userService.findById(authorIds.getId())));
|
||||
paper.getAuthors().clear();
|
||||
if (paperDto.getAuthorIds() != null && !paperDto.getAuthorIds().isEmpty()) {
|
||||
paperDto.getAuthorIds().forEach(authorIds -> paper.getAuthors().add(userService.findById(authorIds)));
|
||||
}
|
||||
return paper;
|
||||
}
|
||||
@ -89,11 +96,18 @@ public class PaperService {
|
||||
public Integer update(PaperDto paperDto) throws IOException {
|
||||
Paper paper = paperRepository.findOne(paperDto.getId());
|
||||
Paper.PaperStatus oldStatus = paper.getStatus();
|
||||
Set<User> oldAuthors = new HashSet<>(paper.getAuthors());
|
||||
if (paperDto.getTmpFileName() != null && paper.getFileData() != null) {
|
||||
fileService.deleteFile(paper.getFileData());
|
||||
}
|
||||
paperRepository.save(copyFromDto(paper, paperDto));
|
||||
|
||||
paper.getAuthors().forEach(author -> {
|
||||
if (!oldAuthors.contains(author)) {
|
||||
paperNotificationService.sendCreateNotification(paper);
|
||||
}
|
||||
});
|
||||
|
||||
if (paper.getStatus() != oldStatus) {
|
||||
paperNotificationService.statusChangeNotification(paper, oldStatus);
|
||||
}
|
||||
@ -110,8 +124,8 @@ public class PaperService {
|
||||
paperRepository.delete(paper);
|
||||
}
|
||||
|
||||
public List<PaperStatusDto> getPaperStatuses() {
|
||||
return convert(Arrays.asList(Paper.PaperStatus.values()), PaperStatusDto::new);
|
||||
public List<Paper.PaperStatus> getPaperStatuses() {
|
||||
return Arrays.asList(Paper.PaperStatus.values());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@ -131,10 +145,12 @@ public class PaperService {
|
||||
}
|
||||
|
||||
public List<PaperDto> filter(PaperFilterDto filterDto) {
|
||||
return convert(paperRepository.filter(userService.findById(filterDto.getAuthorId()), filterDto.getYear()), PaperDto::new);
|
||||
return convert(paperRepository.filter(
|
||||
filterDto.getFilterAuthorId() == null ? null : userService.findById(filterDto.getFilterAuthorId()),
|
||||
filterDto.getYear()), PaperDto::new);
|
||||
}
|
||||
|
||||
public PaperDto findPaper(int id){
|
||||
public PaperDto findPaper(int id) {
|
||||
return new PaperDto(paperRepository.getOne(id));
|
||||
}
|
||||
|
||||
@ -154,4 +170,20 @@ public class PaperService {
|
||||
paperNotificationService.sendFailedNotification(paper, oldStatus);
|
||||
});
|
||||
}
|
||||
|
||||
public void save(PaperDto paperDto) throws IOException {
|
||||
if (isEmpty(paperDto.getId())) {
|
||||
create(paperDto);
|
||||
} else {
|
||||
update(paperDto);
|
||||
}
|
||||
}
|
||||
|
||||
public PaperDto findById(Integer paperId) {
|
||||
return new PaperDto(paperRepository.findOne(paperId));
|
||||
}
|
||||
|
||||
public List<User> getPaperAuthors() {
|
||||
return userService.findAll();
|
||||
}
|
||||
}
|
||||
|
@ -23,4 +23,10 @@
|
||||
constraintName="fk_event_child_event" referencedTableName="event"
|
||||
referencedColumnNames="id"/>
|
||||
</changeSet>
|
||||
<changeSet author="orion" id="20181126_000000-4">
|
||||
<modifyDataType
|
||||
columnName="deadline_date"
|
||||
newDataType="date"
|
||||
tableName="paper"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
@ -11,7 +11,7 @@
|
||||
</p>
|
||||
<p>
|
||||
Статус статьи "<span th:text="${paper.title}">Title</span>" сменился с
|
||||
"<span th:text="${oldStatus.name}">oldStatus</span>" на "<span th:text="${paper.status.name}">newStatus</span>".
|
||||
"<span th:text="${oldStatus.statusName}">oldStatus</span>" на "<span th:text="${paper.status.statusName}">newStatus</span>".
|
||||
</p>
|
||||
<p>
|
||||
Regards,
|
||||
|
@ -50,7 +50,7 @@ section {
|
||||
}
|
||||
|
||||
section h2.section-heading {
|
||||
font-size: 40px;
|
||||
font-size: 3.5vw;
|
||||
margin-top: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
@ -1,144 +1,42 @@
|
||||
var urlPapers = "/api/1.0/papers";
|
||||
var urlPaperStatuses = "/api/1.0/papers/statuses";
|
||||
var urlDeletePaper = "/api/1.0/papers/";
|
||||
var urlFilterPaper = "/api/1.0/papers/filter"
|
||||
/*<![CDATA[*/
|
||||
$(document).ready(function () {
|
||||
$(".paper-row").mouseenter(function (event) {
|
||||
var paperRow = $(event.target).closest(".paper-row");
|
||||
$(paperRow).css("background-color", "#f8f9fa");
|
||||
$(paperRow).find(".remove-paper").removeClass("d-none");
|
||||
|
||||
function showPapers(papersElement, paperRowClass) {
|
||||
getFromRest(urlPapers, function (paperList) {
|
||||
paperList.forEach(function (paper, index) {
|
||||
$(papersElement).parent().append("<div class='row text-left paper-row'>" +
|
||||
" <div class='col'>" +
|
||||
" <span class='fa-stack fa-1x'>\n" +
|
||||
" <i class='fa fa-circle fa-stack-2x " + getPaperStatusClass(paper.status) + "'></i>" +
|
||||
" <i class='fa fa-file-text-o fa-stack-1x fa-inverse'></i>" +
|
||||
" </span>" +
|
||||
" <a href='paper?id=" + paper.id + "" +
|
||||
"'><span>" + (index + 1) + ". " + paper.title + "</span></a>" +
|
||||
"<span class='remove-paper d-none pull-right' onclick=\"deletePaper(" + paper.id + ",'" + papersElement + "', '" + paperRowClass + "')\">" +
|
||||
"<i class=\"fa fa-trash\" aria-hidden=\"true\"></i></span>" +
|
||||
"</div></div>");
|
||||
});
|
||||
|
||||
$(paperRowClass).mouseenter(function (event) {
|
||||
var paperRow = $(event.target).closest(paperRowClass);
|
||||
$(paperRow).css("background-color", "#f8f9fa");
|
||||
$(paperRow).find(".remove-paper").removeClass("d-none");
|
||||
|
||||
});
|
||||
$(paperRowClass).mouseleave(function (event) {
|
||||
var paperRow = $(event.target).closest(paperRowClass);
|
||||
$(paperRow).css("background-color", "white");
|
||||
$(paperRow).closest(paperRowClass).find(".remove-paper").addClass("d-none");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function filterPapers(papersElement, paperRowClass, authorId, year) {
|
||||
var paperData = JSON.stringify({
|
||||
"authorId": authorId,
|
||||
"year": year
|
||||
});
|
||||
postToRest(urlFilterPaper, paperData, function (data) {
|
||||
$(paperRowClass).remove();
|
||||
if(data.length > 0){
|
||||
data.forEach(function (paper, index) {
|
||||
$(papersElement).parent().append("<div class='row text-left paper-row'>" +
|
||||
" <div class='col-md-11'>" +
|
||||
" <span class='fa-stack fa-1x'>\n" +
|
||||
" <i class='fa fa-circle fa-stack-2x " + getPaperStatusClass(paper.status) + "'></i>" +
|
||||
" <i class='fa fa-file-text-o fa-stack-1x fa-inverse'></i>" +
|
||||
" </span>" +
|
||||
" <a href='paper?id=" + paper.id + "" +
|
||||
"'><span>" + paper.title + "</span></a></div>" +
|
||||
"<div class='col-md-1'>" +
|
||||
"<span class='remove-paper d-none' onclick=\"deletePaper(" + paper.id + ",'" + papersElement + "', '" + paperRowClass + "')\">" +
|
||||
"<i class=\"fa fa-trash\" aria-hidden=\"true\"></i></span>" +
|
||||
" </div></div>");
|
||||
});
|
||||
|
||||
|
||||
$(paperRowClass).mouseenter(function (event) {
|
||||
var paperRow = $(event.target).closest(paperRowClass);
|
||||
$(paperRow).css("background-color", "#f8f9fa");
|
||||
$(paperRow).find(".remove-paper").removeClass("d-none");
|
||||
|
||||
});
|
||||
$(paperRowClass).mouseleave(function (event) {
|
||||
var paperRow = $(event.target).closest(paperRowClass);
|
||||
$(paperRow).css("background-color", "white");
|
||||
$(paperRow).closest(paperRowClass).find(".remove-paper").addClass("d-none");
|
||||
});
|
||||
}
|
||||
$(".paper-row").mouseleave(function (event) {
|
||||
var paperRow = $(event.target).closest(".paper-row");
|
||||
$(paperRow).css("background-color", "white");
|
||||
$(paperRow).closest(".paper-row").find(".remove-paper").addClass("d-none");
|
||||
});
|
||||
|
||||
$('a[data-confirm]').click(function(ev) {
|
||||
var href = $(this).attr('href');
|
||||
if (!$('#dataConfirmModal').length) {
|
||||
$('#modalDelete').append('<div class="modal fade" id="dataConfirmModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"\n' +
|
||||
' >\n' +
|
||||
' <div class="modal-dialog modal-sm">\n' +
|
||||
' <div class="modal-content">\n' +
|
||||
' <div class="modal-header">\n' +
|
||||
' <h8 class="modal-title" id="myModalLabel">Удалить статью?</h8>\n' +
|
||||
' <button type="button" class="close" data-dismiss="modal" aria-label="Закрыть"><span\n' +
|
||||
' aria-hidden="true">×</span></button>\n' +
|
||||
' </div>\n' +
|
||||
|
||||
}
|
||||
|
||||
function deletePaper(id, papersElement, paperRowClass) {
|
||||
$("#remove-paper-modal").modal('show');
|
||||
|
||||
$("#modal-btn-yes").on("click", function () {
|
||||
deleteFromRest(urlDeletePaper + id, function () {
|
||||
showFeedbackMessage("Статья удалена");
|
||||
$(paperRowClass).remove();
|
||||
showPapers(papersElement, paperRowClass);
|
||||
});
|
||||
$("#remove-paper-modal").modal('hide');
|
||||
' <div class="modal-footer">\n' +
|
||||
' <a class="btn btn-primary" id="dataConfirmOK">Да</a>'+
|
||||
' <button class="btn primary" data-dismiss="modal" aria-hidden="true">Нет</button>'+
|
||||
' </div>\n' +
|
||||
' </div>\n' +
|
||||
' </div>\n' +
|
||||
' </div>');
|
||||
}
|
||||
$('#dataConfirmModal').find('#myModalLabel').text($(this).attr('data-confirm'));
|
||||
$('#dataConfirmOK').attr('href', href);
|
||||
$('#dataConfirmModal').modal({show:true});
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#modal-btn-no").on("click", function () {
|
||||
$("#remove-paper-modal").modal('hide');
|
||||
});
|
||||
}
|
||||
|
||||
function addPaper(title, status, datePublish, dateUpdate, deadline, comment, locked, tmpFileName, authors) {
|
||||
var paperData = JSON.stringify({
|
||||
"title": title,
|
||||
"status": status,
|
||||
"deadlineDate":deadline,
|
||||
"comment": comment
|
||||
});
|
||||
postToRest(urlPapers, paperData, function (data) {
|
||||
alert(data);
|
||||
});
|
||||
}
|
||||
|
||||
function getPaperStatusClass(status) {
|
||||
switch (status) {
|
||||
case 'DRAFT':
|
||||
return "text-draft"
|
||||
case 'ON_PREPARATION':
|
||||
return "text-primary";
|
||||
case 'ON_REVIEW':
|
||||
return "text-primary";
|
||||
case 'COMPLETED':
|
||||
return "text-success";
|
||||
case 'ATTENTION':
|
||||
return "text-warning";
|
||||
case 'FAILED':
|
||||
return "text-failed";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function showPaperDashboard(dashboardElement) {
|
||||
getFromRest(urlPapers, function (paperList) {
|
||||
paperList.forEach(function (paper, index) {
|
||||
$(dashboardElement).append("<div class=\"col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 dashboard-card\">" +
|
||||
"<div class=\"row\">" +
|
||||
"<div class=\"col-2\">" +
|
||||
"<span class=\"fa-stack fa-1x\">" +
|
||||
"<i class=\"fa fa-circle fa-stack-2x " + getPaperStatusClass(paper.status) + "\"></i>" +
|
||||
"<i class=\"fa fa-file-text-o fa-stack-1x fa-inverse\"></i>" +
|
||||
"</span>" +
|
||||
"</div>" +
|
||||
"<div class=\"col col-10 text-right\">" +
|
||||
"<h7 class=\"service-heading\">" + paper.title + "</h7>" +
|
||||
"<p class=\"text-muted\">" + paper.authorsString + "</p>" +
|
||||
"</div>" +
|
||||
"</div>" +
|
||||
"</div>");
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
/*]]>*/
|
@ -12,6 +12,7 @@
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link rel="stylesheet" href="/webjars/bootstrap/4.1.0/css/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/bootstrap-select/1.13.3/css/bootstrap-select.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
||||
|
||||
<!-- Custom fonts for this template -->
|
||||
@ -25,6 +26,7 @@
|
||||
<!-- Bootstrap core JavaScript -->
|
||||
<script src="/webjars/jquery/3.3.1-1/jquery.min.js"></script>
|
||||
<script src="/webjars/bootstrap/4.1.0/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="/webjars/bootstrap-select/1.13.3/js/bootstrap-select.min.js"></script>
|
||||
|
||||
<!-- Plugin JavaScript -->
|
||||
<script src="/webjars/jquery.easing/1.4.1/jquery.easing.js"></script>
|
||||
@ -88,8 +90,6 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Custom scripts for this template -->
|
||||
<script src="/js/agency.js"></script>
|
||||
<script src="/js/core.js"></script>
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
|
@ -175,7 +175,6 @@
|
||||
</div>
|
||||
</section>
|
||||
<script type="text/javascript" src="/js/file-loader.js"></script>
|
||||
<script src="/js/papers.js"></script>
|
||||
<script>
|
||||
/*<![CDATA[*/
|
||||
$(document).ready(function () {
|
||||
|
@ -1,45 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorator="default">
|
||||
layout:decorator="default" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container" layout:fragment="content">
|
||||
<!-- Services -->
|
||||
<section id="services">
|
||||
<div class="container">
|
||||
<div class="col-lg-12 text-center">
|
||||
<h2 class="section-heading text-uppercase">Статьи</h2>
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
|
||||
<a href="./papers" class="btn btn-light toolbar-button"><i class="fa fa-list-alt"></i>
|
||||
Список</a>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
|
||||
<a href="./dashboard" class="btn btn-light toolbar-button"><i class="fa fa-newspaper-o"
|
||||
aria-hidden="true"></i> Панель управления</a>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
|
||||
<a href="./paper" class="btn btn-light toolbar-button"><i class="fa fa-plus-circle" aria-hidden="true"></i>
|
||||
Добавить статью</a>
|
||||
</div>
|
||||
</div>
|
||||
<div th:replace="papers/fragments/paperNavigationFragment"/>
|
||||
</div>
|
||||
<div class="row justify-content-center" id="dashboard">
|
||||
|
||||
<th:block th:each="paper : ${papers}">
|
||||
<div th:replace="papers/fragments/paperDashboardFragment :: titleLine(paper=${paper})"/>
|
||||
</th:block>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<script src="/js/papers.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
showPaperDashboard("#dashboard");
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:fragment="headerfiles">
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<div th:fragment="titleLine (paper)" class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 dashboard-card">
|
||||
<div class="row">
|
||||
<div class="col-2">
|
||||
<span class="fa-stack fa-1x">
|
||||
<th:block th:switch="${paper.status.name()}">
|
||||
<div th:case="'ATTENTION'">
|
||||
<i class="fa fa-circle fa-stack-2x text-warning"></i>
|
||||
</div>
|
||||
<div th:case="'DRAFT'">
|
||||
<i class="fa fa-circle fa-stack-2x text-draft"></i>
|
||||
</div>
|
||||
<div th:case="'ON_PREPARATION'">
|
||||
<i class="fa fa-circle fa-stack-2x text-primary"></i>
|
||||
</div>
|
||||
<div th:case="'ON_REVIEW'">
|
||||
<i class="fa fa-circle fa-stack-2x text-primary"></i>
|
||||
</div>
|
||||
<div th:case="'COMPLETED'">
|
||||
<i class="fa fa-circle fa-stack-2x text-success"></i>
|
||||
</div>
|
||||
<div th:case="'FAILED'">
|
||||
<i class="fa fa-circle fa-stack-2x text-failed"></i>
|
||||
</div>
|
||||
</th:block>
|
||||
<i class="fa fa-file-text-o fa-stack-1x fa-inverse"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col col-10 text-right">
|
||||
<h7 class="service-heading" th:text="${paper.title}"> title</h7>
|
||||
<p class="text-muted" th:text="${paper.authorsString}">authors</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:fragment="headerfiles">
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<div th:fragment="titleLine (paper)" class="row text-left paper-row" style="background-color: white;">
|
||||
<div class="col">
|
||||
<span class="fa-stack fa-1x">
|
||||
<th:block th:switch="${paper.status.name()}">
|
||||
<div th:case="'ATTENTION'">
|
||||
<i class="fa fa-circle fa-stack-2x text-warning"></i>
|
||||
</div>
|
||||
<div th:case="'DRAFT'">
|
||||
<i class="fa fa-circle fa-stack-2x text-draft"></i>
|
||||
</div>
|
||||
<div th:case="'ON_PREPARATION'">
|
||||
<i class="fa fa-circle fa-stack-2x text-primary"></i>
|
||||
</div>
|
||||
<div th:case="'ON_REVIEW'">
|
||||
<i class="fa fa-circle fa-stack-2x text-primary"></i>
|
||||
</div>
|
||||
<div th:case="'COMPLETED'">
|
||||
<i class="fa fa-circle fa-stack-2x text-success"></i>
|
||||
</div>
|
||||
<div th:case="'FAILED'">
|
||||
<i class="fa fa-circle fa-stack-2x text-failed"></i>
|
||||
</div>
|
||||
</th:block>
|
||||
<i class="fa fa-file-text-o fa-stack-1x fa-inverse"></i>
|
||||
</span>
|
||||
<a th:href="@{'paper?id='+${paper.id}}">
|
||||
<span class="h6" th:text="${paper.title}"/>
|
||||
<span class="text-muted" th:text="${paper.authorsString}"/>
|
||||
</a>
|
||||
<input class="id-class" type="hidden" th:value="${paper.id}"/>
|
||||
<a class="remove-paper pull-right d-none" th:href="@{'/papers/delete/'+${paper.id}}"
|
||||
data-confirm="Удалить статью?">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:fragment="headerfiles">
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
|
||||
<a href="./papers" class="btn btn-light toolbar-button"><i class="fa fa-list-alt"></i>
|
||||
Список</a>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
|
||||
<a href="./dashboard" class="btn btn-light toolbar-button"><i class="fa fa-newspaper-o"
|
||||
aria-hidden="true"></i> Панель
|
||||
управления</a>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
|
||||
<a href="./paper?id=0" class="btn btn-light toolbar-button"><i class="fa fa-plus-circle"
|
||||
aria-hidden="true"></i>
|
||||
Добавить статью</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorator="default">
|
||||
layout:decorator="default" xmlns:th="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/html">
|
||||
<head>
|
||||
|
||||
</head>
|
||||
@ -14,127 +14,100 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<h2 class="section-heading text-uppercase">Редактирование статьи</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-10 text-center">
|
||||
</div>
|
||||
<div class="col-lg-2 text-center">
|
||||
|
||||
<div th:replace="papers/fragments/paperNavigationFragment"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<form id="contactForm" name="sentMessage" novalidate="">
|
||||
<form id="paper-form" method="post" th:action="@{'/papers/paper?id='+ *{id == null ? '' : id} + ''}"
|
||||
th:object="${paperDto}">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<input type="hidden" name="id" th:field="*{id}"/>
|
||||
<div class="form-group">
|
||||
<label for="name">Название:</label>
|
||||
<input class="form-control" id="name" type="text" placeholder="Название статьи"
|
||||
required="" data-validation-required-message="Введите название статьи"/>
|
||||
<label for="title">Название:</label>
|
||||
<input class="form-control" id="title" type="text"
|
||||
placeholder="Название статьи"
|
||||
th:field="*{title}"/>
|
||||
<p th:if="${#fields.hasErrors('title')}" th:errors="*{title}"
|
||||
class="alert alert-danger">Incorrect title</p>
|
||||
<p class="help-block text-danger"></p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="status">Статус:</label>
|
||||
<select class="form-control" id="status">
|
||||
|
||||
<select class="form-control" th:field="*{status}" id="status">
|
||||
<option th:each="status : ${allStatuses}" th:value="${status}"
|
||||
th:text="${status.statusName}">Status
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="comment">Комментарий:</label>
|
||||
<textarea class="form-control" rows="5" id="comment"></textarea>
|
||||
<textarea class="form-control" rows="5" id="comment"
|
||||
th:field="*{comment}"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Дедлайн:</label>
|
||||
<input type="date" class="form-control" name="deadline" id="deadline"/>
|
||||
<label>Дедлайны:</label>
|
||||
<div class="row" th:each="deadline, rowStat : *{deadlines}">
|
||||
<input type="hidden" th:field="*{deadlines[__${rowStat.index}__].id}"/>
|
||||
<div class="col-6">
|
||||
<input type="date" class="form-control" name="deadline"
|
||||
th:field="*{deadlines[__${rowStat.index}__].date}"/>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<input class="form-control" type="text" placeholder="Описание"
|
||||
th:field="*{deadlines[__${rowStat.index}__].description}"/>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<a class="btn btn-danger float-right"
|
||||
th:onclick="|$('#deadlines${rowStat.index}\\.description').val('');
|
||||
$('#deadlines${rowStat.index}\\.date').val('');
|
||||
$('#addDeadline').click();|"><span
|
||||
aria-hidden="true"><i class="fa fa-times"/></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p th:if="${#fields.hasErrors('deadlines')}" th:errors="*{deadlines}"
|
||||
class="alert alert-danger">Incorrect title</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" id="addDeadline" name="addDeadline" class="btn btn-primary" value="Добавить
|
||||
дедлайн"/>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="locked"/>
|
||||
<input type="checkbox" class="form-check-input" id="locked"
|
||||
th:field="*{locked}"/>
|
||||
<label class="form-check-label" for="locked">Заблокирована</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="loader" id="loader">Загрузить статью:</label>
|
||||
<!--<div id="loader">
|
||||
<label for="loader">Загрузить статью:</label>
|
||||
<div id="loader">
|
||||
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Дата публикации:</label>
|
||||
<input type="date" class="form-control" name="date-publish" id="date-publish"/>
|
||||
<label>Дата создания:</label>
|
||||
<span th:text="${paperDto.createDate == null ? '' : #dates.format(paperDto.createDate, 'dd.MM.yyyy HH:mm')}">text</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Последнее изменение:</label>
|
||||
<input type="date" class="form-control" name="date-update" id="date-update"/>
|
||||
<span th:text="${paperDto.updateDate == null ? '' : #dates.format(paperDto.updateDate, 'dd.MM.yyyy HH:mm')}">text</span>
|
||||
</div>
|
||||
<p><a href="#myModal1" class="btn btn-primary" data-toggle="modal">Редактировать авторов
|
||||
статьи</a></p>
|
||||
<div id="myModal1" class="modal fade">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
aria-hidden="true">×
|
||||
</button>
|
||||
<h4 class="modal-title">Авторы статьи</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Фамилия</th>
|
||||
<th>Имя</th>
|
||||
<th>Отчество</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Иванов</td>
|
||||
<td>Иван</td>
|
||||
<td>Иванович</td>
|
||||
<td>
|
||||
<span class="table-remove"><button type="button"
|
||||
class="btn btn-danger btn-rounded btn-sm my-0">Remove</button></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>text</td>
|
||||
<td>text</td>
|
||||
<td>text</td>
|
||||
<td>
|
||||
<span class="table-remove"><button type="button"
|
||||
class="btn btn-danger btn-rounded btn-sm my-0">Remove</button></span>
|
||||
</td>
|
||||
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle"
|
||||
type="button" data-toggle="dropdown">Выберите автора
|
||||
<span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<input class="form-control" id="myInput" type="text"
|
||||
placeholder="Search.."/>
|
||||
<li><a href="#">Иванов</a></li>
|
||||
<li><a href="#">Смирнов</a></li>
|
||||
<li><a href="#">Кузнецов</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary">Сохранить изменения
|
||||
</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">
|
||||
Отмена
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Редактировать авторов статьи:</label>
|
||||
<select class="selectpicker form-control" multiple="true" data-live-search="true"
|
||||
title="-- Выберите авторов --"
|
||||
th:field="*{authorIds}">
|
||||
<option th:each="author: ${allAuthors}" th:value="${author.id}"
|
||||
th:text="${author.lastName}">Status
|
||||
</option>
|
||||
</select>
|
||||
<p th:if="${#fields.hasErrors('authorIds')}" th:errors="*{authorIds}"
|
||||
class="alert alert-danger">Incorrect title</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 offset-md-3 col-sm-12 offset-sm-0">
|
||||
@ -148,14 +121,15 @@
|
||||
<div class="clearfix"></div>
|
||||
<div class="col-lg-12">
|
||||
<div class="form-group">
|
||||
<button id="sendMessageButton" class="btn btn-success text-uppercase"
|
||||
type="button" onclick="savePaper();" >
|
||||
<button id="sendMessageButton" name="save" class="btn btn-success text-uppercase"
|
||||
type="submit">
|
||||
Сохранить
|
||||
</button>
|
||||
<button id="cancelButton" class="btn btn-default text-uppercase" type="button">
|
||||
<a id="cancelButton" class="btn btn-default text-uppercase" href="/papers/papers">
|
||||
Отмена
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -164,7 +138,6 @@
|
||||
</div>
|
||||
</section>
|
||||
<script type="text/javascript" src="/js/file-loader.js"></script>
|
||||
<script src="/js/papers.js"></script>
|
||||
<script>
|
||||
/*<![CDATA[*/
|
||||
$(document).ready(function () {
|
||||
@ -178,25 +151,8 @@
|
||||
console.debug(response);
|
||||
}
|
||||
});
|
||||
|
||||
getFromRest(urlPaperStatuses, function (response) {
|
||||
fillSelect($("#status"), response);
|
||||
});
|
||||
|
||||
$('.selectpicker').selectpicker();
|
||||
});
|
||||
function savePaper(){
|
||||
var title = document.getElementById("name").value;
|
||||
var status = document.getElementById("status").value;
|
||||
var datePublish = document.getElementById("date-publish").value;
|
||||
var dateUpdate = document.getElementById("date-update").value;
|
||||
var deadline = document.getElementById("deadline").value;
|
||||
var comment = document.getElementById("comment").value;
|
||||
var locked = document.getElementById("locked").value;
|
||||
var tmpFileName = document.getElementById("loader").value;
|
||||
var authors = document.getElementById("myInput").value;
|
||||
|
||||
addPaper(title,status,datePublish,dateUpdate,deadline,comment,locked,tmpFileName,authors);
|
||||
}
|
||||
/*]]>*/
|
||||
</script>
|
||||
</div>
|
||||
|
@ -1,82 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorator="default">
|
||||
layout:decorator="default" xmlns:th="">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container" layout:fragment="content">
|
||||
<section id="papers">
|
||||
<div class="container">
|
||||
<div class="row" id="paper-list">
|
||||
<div class="col-lg-12 text-center">
|
||||
<h2 class="section-heading text-uppercase">Статьи</h2>
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
|
||||
<a href="./papers" class="btn btn-light toolbar-button"><i class="fa fa-list-alt"></i>
|
||||
Список</a>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
|
||||
<a href="./dashboard" class="btn btn-light toolbar-button"><i class="fa fa-newspaper-o"
|
||||
aria-hidden="true"></i> Панель управления</a>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
|
||||
<a href="./paper" class="btn btn-light toolbar-button"><i class="fa fa-plus-circle" aria-hidden="true"></i>
|
||||
Добавить статью</a>
|
||||
|
||||
</div>
|
||||
|
||||
<form id="papers-form" method="post" th:action="@{'/papers/papers'}">
|
||||
<input th:type="hidden" name="paperDeleteId" id="paperDeleteId"/>
|
||||
<section id="papers">
|
||||
<div class="container">
|
||||
<div class="row" id="paper-list">
|
||||
<div class="col-lg-12 text-center">
|
||||
<h2 class="section-heading text-uppercase">Статьи</h2>
|
||||
<div th:replace="papers/fragments/paperNavigationFragment"/>
|
||||
</div>
|
||||
<div class = "filter">
|
||||
<h5>Фильтровать по:</h5>
|
||||
<select id = "author">
|
||||
<option value = "1">Алёна</option>
|
||||
<option value = "2">Маша</option>
|
||||
<option value = "3">Петя</option>
|
||||
</select>
|
||||
<select id = "index score">
|
||||
<option >РИНЦ</option>
|
||||
<option>Scopus</option>
|
||||
<option>Web of science</option>
|
||||
</select>
|
||||
<select id = "year">
|
||||
<option>2018</option>
|
||||
<option>2017</option>
|
||||
<option>2016</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-9 col-sm-12">
|
||||
<th:block th:each="paper : ${filteredPapers.papers}">
|
||||
<div th:replace="papers/fragments/paperLineFragment :: titleLine(paper=${paper})"/>
|
||||
</th:block>
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-12">
|
||||
<div class="filter">
|
||||
<h5>Фильтр:</h5>
|
||||
<select class="form-control" th:field="${filteredPapers.filterAuthorId}" id="author"
|
||||
onchange="this.form.submit();">
|
||||
<option value="">Все авторы </option>
|
||||
<option th:each="author: ${allAuthors}" th:value="${author.id}"
|
||||
th:text="${author.lastName}">lastName
|
||||
</option>
|
||||
</select>
|
||||
<select class="form-control" id="year" th:field="${filteredPapers.year}" onchange="this.form.submit();">
|
||||
<option value="">Все годы</option>
|
||||
<option th:each="year: ${allYears}" th:value="${year}"
|
||||
th:text="${year}">year
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true" id="remove-paper-modal">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h8 class="modal-title" id="myModalLabel">Удалить статью?</h8>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Закрыть"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" id="modal-btn-yes">Да</button>
|
||||
<button type="button" class="btn btn-primary" id="modal-btn-no">Нет</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modalDelete"/>
|
||||
</form>
|
||||
<script src="/js/papers.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
showPapers("#paper-list", ".paper-row");
|
||||
jQuery('.filter').on('change','#year',function(){
|
||||
|
||||
filterPapers("#paper-list", ".paper-row",'1','2018');
|
||||
});
|
||||
});
|
||||
<script type="text/javascript">
|
||||
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user