Merge branch '64-add-article-conf' into 'dev'

Resolve "Добавить новую статью к конференции"

Closes #64

See merge request romanov73/ng-tracker!70
This commit is contained in:
Anton Romanov 2019-04-24 09:35:08 +00:00
commit 1e6fbdc1fa
20 changed files with 211 additions and 80 deletions

View File

@ -6,7 +6,6 @@ import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors; import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute; 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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -68,6 +67,12 @@ public class ConferenceController {
} }
} }
@PostMapping(value = "/conferences", params = "deleteConference")
public String delete(@RequestParam("deleteConference") Integer conferenceId) throws IOException {
conferenceService.delete(conferenceId);
return String.format(REDIRECT_TO, CONFERENCES_PAGE);
}
@PostMapping(value = "/conference", params = "save") @PostMapping(value = "/conference", params = "save")
public String save(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException { public String save(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
filterEmptyDeadlines(conferenceDto); filterEmptyDeadlines(conferenceDto);
@ -76,17 +81,10 @@ public class ConferenceController {
} }
conferenceService.save(conferenceDto); conferenceService.save(conferenceDto);
return String.format(REDIRECT_TO, CONFERENCES_PAGE); return String.format(REDIRECT_TO, CONFERENCES_PAGE);
}
@GetMapping("/delete/{conference-id}")
public String delete(@PathVariable("conference-id") Integer conferenceId) throws IOException {
conferenceService.delete(conferenceId);
return String.format(REDIRECT_TO, CONFERENCES_PAGE);
} }
@PostMapping(value = "/conference", params = "addDeadline") @PostMapping(value = "/conference", params = "addDeadline")
public String addDeadline(@Valid ConferenceDto conferenceDto, Errors errors) { public String addDeadline(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
filterEmptyDeadlines(conferenceDto); filterEmptyDeadlines(conferenceDto);
if (errors.hasErrors()) { if (errors.hasErrors()) {
return CONFERENCE_PAGE; return CONFERENCE_PAGE;
@ -105,6 +103,16 @@ public class ConferenceController {
return CONFERENCE_PAGE; return CONFERENCE_PAGE;
} }
@PostMapping(value = "/conference", params = "addPaper")
public String addPaper(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.addPaper(conferenceDto);
return CONFERENCE_PAGE;
}
@PostMapping(value = "/conference", params = "removePaper") @PostMapping(value = "/conference", params = "removePaper")
public String removePaper(@Valid ConferenceDto conferenceDto, Errors errors, public String removePaper(@Valid ConferenceDto conferenceDto, Errors errors,
@RequestParam(value = "removePaper") Integer paperIndex) throws IOException { @RequestParam(value = "removePaper") Integer paperIndex) throws IOException {

View File

@ -53,7 +53,7 @@ public class Conference extends BaseEntity {
@OrderBy("date") @OrderBy("date")
private List<Deadline> deadlines = new ArrayList<>(); private List<Deadline> deadlines = new ArrayList<>();
@ManyToMany(fetch = FetchType.EAGER) @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
@JoinTable(name = "paper_conference", @JoinTable(name = "paper_conference",
joinColumns = {@JoinColumn(name = "conference_id")}, joinColumns = {@JoinColumn(name = "conference_id")},
inverseJoinColumns = {@JoinColumn(name = "paper_id")}) inverseJoinColumns = {@JoinColumn(name = "paper_id")})

View File

@ -11,14 +11,14 @@ public class ConferenceFilterDto {
public ConferenceFilterDto() { public ConferenceFilterDto() {
} }
public ConferenceFilterDto(List<ConferenceDto> conferenceDtos, Integer filterUserId, Integer year) { public ConferenceFilterDto(List<ConferenceDto> conferences, Integer filterUserId, Integer year) {
this.conferences = conferenceDtos; this.conferences = conferences;
this.filterUserId = filterUserId; this.filterUserId = filterUserId;
this.year = year; this.year = year;
} }
public ConferenceFilterDto(List<ConferenceDto> conferenceDtos) { public ConferenceFilterDto(List<ConferenceDto> conferences) {
this(conferenceDtos, null, null); this(conferences, null, null);
} }
public List<ConferenceDto> getConferences() { public List<ConferenceDto> getConferences() {

View File

@ -16,4 +16,7 @@ public interface ConferenceRepository extends JpaRepository<Conference, Integer>
@Query("SELECT c FROM Conference c WHERE c.beginDate > :date") @Query("SELECT c FROM Conference c WHERE c.beginDate > :date")
List<Conference> findAllActive(@Param("date") Date date); List<Conference> findAllActive(@Param("date") Date date);
@Query("SELECT case when count(c) > 0 then true else false end FROM Conference c JOIN c.papers p WHERE p.id = :paperId")
boolean isPaperAttached(@Param("paperId") Integer paperId);
} }

View File

@ -111,9 +111,19 @@ public class ConferenceService {
conferenceDto.getDeadlines().remove((int) deadlineIndex); conferenceDto.getDeadlines().remove((int) deadlineIndex);
} }
public void addPaper(ConferenceDto conferenceDto) {
Paper paper = new Paper();
paper.setTitle(userService.getCurrentUser().getLastName() + "_" + conferenceDto.getTitle() + "_" + (new Date()).getTime());
paper.setStatus(Paper.PaperStatus.DRAFT);
conferenceDto.getPapers().add(paper);
}
public void removePaper(ConferenceDto conferenceDto, Integer paperIndex) throws IOException { public void removePaper(ConferenceDto conferenceDto, Integer paperIndex) throws IOException {
Paper removedPaper = conferenceDto.getPapers().remove((int) paperIndex); Paper removedPaper = conferenceDto.getPapers().remove((int) paperIndex);
conferenceDto.getNotSelectedPapers().add(removedPaper); if (removedPaper.getId() != null) {
conferenceDto.getNotSelectedPapers().add(removedPaper);
}
} }
public void takePart(ConferenceDto conferenceDto) throws IOException { public void takePart(ConferenceDto conferenceDto) throws IOException {
@ -144,12 +154,13 @@ public class ConferenceService {
conference.setPing(0); conference.setPing(0);
conference.setBeginDate(conferenceDto.getBeginDate()); conference.setBeginDate(conferenceDto.getBeginDate());
conference.setEndDate(conferenceDto.getEndDate()); conference.setEndDate(conferenceDto.getEndDate());
conference.setPapers(conferenceDto.getPapers()); conference.getPapers().clear();
conferenceDto.getPapers().forEach(paper -> conference.getPapers().add(paper.getId() != null ? paperService.findPaperById(paper.getId()) : paperService.create(paper)));
conference.setDeadlines(deadlineService.saveOrCreate(conferenceDto.getDeadlines())); conference.setDeadlines(deadlineService.saveOrCreate(conferenceDto.getDeadlines()));
conference.setUsers(conferenceUserService.saveOrCreate(conferenceDto.getUsers())); conference.setUsers(conferenceUserService.saveOrCreate(conferenceDto.getUsers()));
if (conferenceDto.getPaperIds() != null && !conferenceDto.getPaperIds().isEmpty()) { if (conferenceDto.getPaperIds() != null && !conferenceDto.getPaperIds().isEmpty()) {
conferenceDto.getPaperIds().forEach(paperId -> conferenceDto.getPaperIds().forEach(paperId ->
conference.getPapers().add(paperService.findEntityById(paperId))); conference.getPapers().add(paperService.findPaperById(paperId)));
} }
return conference; return conference;
} }
@ -173,4 +184,8 @@ public class ConferenceService {
public List<Conference> findAllActive() { public List<Conference> findAllActive() {
return conferenceRepository.findAllActive(new Date()); return conferenceRepository.findAllActive(new Date());
} }
public boolean isAttachedToConference(Integer paperId) {
return conferenceRepository.isPaperAttached(paperId);
}
} }

View File

@ -39,6 +39,11 @@ public class AdviceController {
return userService.getCurrentUser().getUserAbbreviate(); return userService.getCurrentUser().getUserAbbreviate();
} }
@ModelAttribute("flashMessage")
public String getFlashMessage() {
return null;
}
private Response<Void> handleException(ErrorConstants error) { private Response<Void> handleException(ErrorConstants error) {
log.warn(error.toString()); log.warn(error.toString());
return new Response<>(error); return new Response<>(error);

View File

@ -8,14 +8,14 @@ import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors; import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute; 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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.model.PaperFilterDto; import ru.ulstu.paper.model.PaperListDto;
import ru.ulstu.paper.service.LatexService; import ru.ulstu.paper.service.LatexService;
import ru.ulstu.paper.service.PaperService; import ru.ulstu.paper.service.PaperService;
import ru.ulstu.user.model.User; import ru.ulstu.user.model.User;
@ -38,23 +38,34 @@ import static org.springframework.util.StringUtils.isEmpty;
@ApiIgnore @ApiIgnore
public class PaperController { public class PaperController {
private final PaperService paperService; private final PaperService paperService;
private final ConferenceService conferenceService;
private final LatexService latexService; private final LatexService latexService;
public PaperController(PaperService paperService, LatexService latexService) { public PaperController(PaperService paperService,
ConferenceService conferenceService,
LatexService latexService) {
this.paperService = paperService; this.paperService = paperService;
this.conferenceService = conferenceService;
this.latexService = latexService; this.latexService = latexService;
} }
@GetMapping("/papers") @GetMapping("/papers")
public void getPapers(ModelMap modelMap) { public void getPapers(ModelMap modelMap) {
modelMap.put("filteredPapers", new PaperFilterDto(paperService.findAllDto(), null, null)); modelMap.put("filteredPapers", new PaperListDto(paperService.findAllDto(), null, null));
} }
@PostMapping("/papers") @PostMapping("/papers")
public void filterPapers(@Valid PaperFilterDto paperFilterDto, ModelMap modelMap) { public void listPapers(@Valid PaperListDto paperListDto, ModelMap modelMap) {
modelMap.put("filteredPapers", new PaperFilterDto(paperService.filter(paperFilterDto), if (paperListDto.getPaperDeleteId() != null) {
paperFilterDto.getFilterAuthorId(), if (conferenceService.isAttachedToConference(paperListDto.getPaperDeleteId())) {
paperFilterDto.getYear())); modelMap.put("flashMessage", "Статью нельзя удалить, она прикреплена к конференции");
} else {
paperService.delete(paperListDto.getPaperDeleteId());
}
}
modelMap.put("filteredPapers", new PaperListDto(paperService.filter(paperListDto),
paperListDto.getFilterAuthorId(),
paperListDto.getYear()));
} }
@GetMapping("/dashboard") @GetMapping("/dashboard")
@ -94,12 +105,6 @@ public class PaperController {
return "/papers/paper"; return "/papers/paper";
} }
@GetMapping("/delete/{paper-id}")
public String delete(@PathVariable("paper-id") Integer paperId) throws IOException {
paperService.delete(paperId);
return "redirect:/papers/papers";
}
@ModelAttribute("allStatuses") @ModelAttribute("allStatuses")
public List<Paper.PaperStatus> getPaperStatuses() { public List<Paper.PaperStatus> getPaperStatuses() {
return paperService.getPaperStatuses(); return paperService.getPaperStatuses();

View File

@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
import ru.ulstu.configuration.Constants; import ru.ulstu.configuration.Constants;
import ru.ulstu.core.model.response.Response; import ru.ulstu.core.model.response.Response;
import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.model.PaperFilterDto; import ru.ulstu.paper.model.PaperListDto;
import ru.ulstu.paper.service.PaperService; import ru.ulstu.paper.service.PaperService;
import javax.validation.Valid; import javax.validation.Valid;
@ -58,8 +58,8 @@ public class PaperRestController {
} }
@PostMapping("/filter") @PostMapping("/filter")
public Response<List<PaperDto>> filter(@RequestBody @Valid PaperFilterDto paperFilterDto) throws IOException { public Response<List<PaperDto>> filter(@RequestBody @Valid PaperListDto paperListDto) throws IOException {
return new Response<>(paperService.filter(paperFilterDto)); return new Response<>(paperService.filter(paperListDto));
} }
@GetMapping("formatted-list") @GetMapping("formatted-list")

View File

@ -0,0 +1,7 @@
package ru.ulstu.paper.error;
public class PaperConferenceRelationExistException extends RuntimeException {
public PaperConferenceRelationExistException(String message) {
super(message);
}
}

View File

@ -2,15 +2,16 @@ package ru.ulstu.paper.model;
import java.util.List; import java.util.List;
public class PaperFilterDto { public class PaperListDto {
private List<PaperDto> papers; private List<PaperDto> papers;
private Integer filterAuthorId; private Integer filterAuthorId;
private Integer paperDeleteId;
private Integer year; private Integer year;
public PaperFilterDto() { public PaperListDto() {
} }
public PaperFilterDto(List<PaperDto> paperDtos, Integer filterAuthorId, Integer year) { public PaperListDto(List<PaperDto> paperDtos, Integer filterAuthorId, Integer year) {
this.papers = paperDtos; this.papers = paperDtos;
this.filterAuthorId = filterAuthorId; this.filterAuthorId = filterAuthorId;
this.year = year; this.year = year;
@ -39,4 +40,12 @@ public class PaperFilterDto {
public void setYear(Integer year) { public void setYear(Integer year) {
this.year = year; this.year = year;
} }
public Integer getPaperDeleteId() {
return paperDeleteId;
}
public void setPaperDeleteId(Integer paperDeleteId) {
this.paperDeleteId = paperDeleteId;
}
} }

View File

@ -9,7 +9,7 @@ import ru.ulstu.file.model.FileDataDto;
import ru.ulstu.file.service.FileService; import ru.ulstu.file.service.FileService;
import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.model.PaperFilterDto; import ru.ulstu.paper.model.PaperListDto;
import ru.ulstu.paper.repository.PaperRepository; import ru.ulstu.paper.repository.PaperRepository;
import ru.ulstu.timeline.service.EventService; import ru.ulstu.timeline.service.EventService;
import ru.ulstu.user.model.User; import ru.ulstu.user.model.User;
@ -93,6 +93,14 @@ public class PaperService {
return newPaper.getId(); return newPaper.getId();
} }
@Transactional
public Paper create(Paper paper) {
Paper newPaper = paperRepository.save(paper);
paperNotificationService.sendCreateNotification(newPaper);
eventService.createFromPaper(newPaper);
return newPaper;
}
private Paper copyFromDto(Paper paper, PaperDto paperDto) throws IOException { private Paper copyFromDto(Paper paper, PaperDto paperDto) throws IOException {
paper.setComment(paperDto.getComment()); paper.setComment(paperDto.getComment());
paper.setUrl(paperDto.getUrl()); paper.setUrl(paperDto.getUrl());
@ -173,7 +181,7 @@ public class PaperService {
return paper; return paper;
} }
public List<PaperDto> filter(PaperFilterDto filterDto) { public List<PaperDto> filter(PaperListDto filterDto) {
return convert(sortPapers(paperRepository.filter( return convert(sortPapers(paperRepository.filter(
filterDto.getFilterAuthorId() == null ? null : userService.findById(filterDto.getFilterAuthorId()), filterDto.getFilterAuthorId() == null ? null : userService.findById(filterDto.getFilterAuthorId()),
filterDto.getYear())), PaperDto::new); filterDto.getYear())), PaperDto::new);
@ -223,7 +231,7 @@ public class PaperService {
return new PaperDto(paperRepository.findOne(paperId)); return new PaperDto(paperRepository.findOne(paperId));
} }
public Paper findEntityById(Integer paperId) { public Paper findPaperById(Integer paperId) {
return paperRepository.findOne(paperId); return paperRepository.findOne(paperId);
} }

View File

@ -2,8 +2,8 @@ body {
min-width: 400px; min-width: 400px;
} }
.conference-row .col:hover { .conference-row .d-flex:hover {
background-color: #f3f3f3; background-color: #f1f1f1;
border-radius: .25rem; border-radius: .25rem;
} }
@ -15,10 +15,20 @@ body {
margin-bottom: 10px; margin-bottom: 10px;
} }
.conference-row .col .text-decoration { .conference-row .d-flex .text-decoration {
text-decoration: none; text-decoration: none;
} }
.conference-row .d-flex .text-decoration:nth-child(1) {
margin-left: 10px;
}
.conference-row .d-flex {
margin: 0 15px;
}
.form-group textarea { .form-group textarea {
min-height: 206px; min-height: 206px;
@ -61,13 +71,17 @@ body {
padding: 0.5rem 1.75em 0.5rem 0.5em; padding: 0.5rem 1.75em 0.5rem 0.5em;
display: inline-block; display: inline-block;
background: transparent url("https://cdn3.iconfinder.com/data/icons/faticons/32/arrow-down-01-16.png") no-repeat right 7px center; background: transparent url("https://cdn3.iconfinder.com/data/icons/faticons/32/arrow-down-01-16.png") no-repeat right 7px center;
cursor: pointer;
} }
.member select:nth-child(4) { .member select:nth-child(4) {
border-right: 1px solid #ced4da; border-right: 1px solid #ced4da;
} }
.member select:hover {
background-color: #f1f1f1;
}
.member-name { .member-name {
padding: .75rem 1.25rem; padding: .75rem 1.25rem;
@ -104,11 +118,22 @@ body {
flex: 1; flex: 1;
} }
.paper-name:hover {
background-color: #f1f1f1;
}
.paper-name span { .paper-name span {
margin: 6px 15px; margin: 7px 10px;
display: inline-block; display: inline-block;
} }
.paper-name span:nth-child(1) {
margin: 3px 0px 3px 10px;
float: left;
}
.icon { .icon {
width: 38px; width: 38px;
height: 38px; height: 38px;
@ -117,14 +142,14 @@ body {
} }
.icon-delete { .icon-delete {
background-color: #f44; background-color: #ff7272;
background-image: url(/img/conference/delete.png); background-image: url(/img/conference/delete.png);
background-repeat: round; background-repeat: round;
color: transparent !important; color: transparent !important;
} }
.icon-delete:hover { .icon-delete:hover {
background-color: #ff2929; background-color: #ff0000;
transition: background-color .15s ease-in-out; transition: background-color .15s ease-in-out;
} }

View File

@ -1,7 +1,6 @@
$(document).ready(function () { $(document).ready(function () {
$('input[data-confirm]').click(function(ev) {
$('a[data-confirm]').click(function(ev) { var value = $(this).attr('value');
var href = $(this).attr('href');
if (!$('#dataConfirmModal').length) { if (!$('#dataConfirmModal').length) {
$('#modalDelete').append('<div class="modal fade" id="dataConfirmModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"\n' + $('#modalDelete').append('<div class="modal fade" id="dataConfirmModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"\n' +
' >\n' + ' >\n' +
@ -14,7 +13,7 @@ $(document).ready(function () {
' </div>\n' + ' </div>\n' +
' <div class="modal-footer">\n' + ' <div class="modal-footer">\n' +
' <a class="btn btn-primary" id="dataConfirmOK">Да</a>'+ ' <button type="submit" name="deleteConference" class="btn btn-primary" id="deleteConference">Да</button>'+
' <button class="btn primary" data-dismiss="modal" aria-hidden="true">Нет</button>'+ ' <button class="btn primary" data-dismiss="modal" aria-hidden="true">Нет</button>'+
' </div>\n' + ' </div>\n' +
' </div>\n' + ' </div>\n' +
@ -22,7 +21,7 @@ $(document).ready(function () {
' </div>'); ' </div>');
} }
$('#dataConfirmModal').find('#myModalLabel').text($(this).attr('data-confirm')); $('#dataConfirmModal').find('#myModalLabel').text($(this).attr('data-confirm'));
$('#dataConfirmOK').attr('href', href); $('#deleteConference').attr('value', value);
$('#dataConfirmModal').modal({show:true}); $('#dataConfirmModal').modal({show:true});
return false; return false;
}); });

View File

@ -13,7 +13,8 @@ $(document).ready(function () {
}); });
$('a[data-confirm]').click(function(ev) { $('a[data-confirm]').click(function(ev) {
var href = $(this).attr('href'); var id = $(this).parent().parent().find('.id-class').val();
if (!$('#dataConfirmModal').length) { if (!$('#dataConfirmModal').length) {
$('#modalDelete').append('<div class="modal fade" id="dataConfirmModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"\n' + $('#modalDelete').append('<div class="modal fade" id="dataConfirmModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"\n' +
' >\n' + ' >\n' +
@ -34,7 +35,10 @@ $(document).ready(function () {
' </div>'); ' </div>');
} }
$('#dataConfirmModal').find('#myModalLabel').text($(this).attr('data-confirm')); $('#dataConfirmModal').find('#myModalLabel').text($(this).attr('data-confirm'));
$('#dataConfirmOK').attr('href', href); $('#dataConfirmOK').click(function () {
$("#paperDeleteId").val(id);
$('form').submit();
});
$('#dataConfirmModal').modal({show:true}); $('#dataConfirmModal').modal({show:true});
return false; return false;
}); });

View File

@ -131,11 +131,24 @@
<div class="form-group"> <div class="form-group">
<label for="papers">Статьи:</label> <label for="papers">Статьи:</label>
<div class="paper-list form-control list-group" id="papers"> <div class="paper-list form-control list-group" id="papers">
<input th:type="hidden" th:field="*{papers}"/> <!--<input th:type="hidden" th:field="*{papers}"/>-->
<div class="paper d-flex list-group-item p-0" <div class="paper d-flex list-group-item p-0"
th:each="paper, rowStat : *{papers}"> th:each="paper, rowStat : *{papers}">
<input type="hidden" th:field="*{papers[__${rowStat.index}__].id}"/>
<input type="hidden" th:field="*{papers[__${rowStat.index}__].title}"/>
<input type="hidden" th:field="*{papers[__${rowStat.index}__].status}"/>
<a class="paper-name" <a class="paper-name"
th:href="@{'/papers/paper?id=' + *{papers[__${rowStat.index}__].id} + ''}"> th:href="@{'/papers/paper?id=' + *{papers[__${rowStat.index}__].id} + ''}"
th:if="*{papers[__${rowStat.index}__].id !=null}">
<span th:replace="papers/fragments/paperStatusFragment :: paperStatus(paperStatus=*{papers[__${rowStat.index}__].status})"/>
<span th:text="*{papers[__${rowStat.index}__].title}">
Имя статьи
</span>
<!--<img class="icon-paper" src="/img/conference/paper.png"/>-->
</a>
<a class="paper-name"
th:unless="*{papers[__${rowStat.index}__].id !=null}">
<span th:text="*{papers[__${rowStat.index}__].title}"> <span th:text="*{papers[__${rowStat.index}__].title}">
Имя статьи Имя статьи
</span> </span>
@ -156,7 +169,7 @@
</option> </option>
</select> </select>
<button id="add-paper" class="btn btn-primary" <button id="add-paper" class="btn btn-primary"
type="button"> type="submit" name="addPaper">
Добавить статью Добавить статью
</button> </button>
</div> </div>

View File

@ -8,7 +8,9 @@
<body> <body>
<div layout:fragment="content"> <div layout:fragment="content">
<form id="conferences-form" method="post" th:action="@{'/conferences/conferences'}"> <form id="conferences-form" method="post" th:action="@{'/conferences/conferences'}"
th:object="${filteredConferences}">
<section id="conferences"> <section id="conferences">
<div class="container"> <div class="container">
<div class="row" id="conference-list"> <div class="row" id="conference-list">
@ -18,9 +20,12 @@
</div> </div>
</div> </div>
<hr/> <hr/>
<div class="alert alert-danger" th:if="${#fields.hasErrors('*')}">
<p th:each="err : ${#fields.errors('*')}" th:text="${err}"></p>
</div>
<div class="row"> <div class="row">
<div class="col-md-9 col-sm-12"> <div class="col-md-9 col-sm-12">
<th:block th:each="conference : ${filteredConferences.conferences}"> <th:block th:each="conference : *{conferences}">
<div th:replace="conferences/fragments/confLineFragment :: confLine(conference=${conference})"/> <div th:replace="conferences/fragments/confLineFragment :: confLine(conference=${conference})"/>
</th:block> </th:block>
</div> </div>

View File

@ -5,16 +5,19 @@
</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 d-flex justify-content-between"> <div class="d-flex justify-content-between w-100">
<a th:href="@{'conference?id='+${conference.id}}" class="w-100 text-decoration"> <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}"/> <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 m-auto" th:href="@{'/conferences/delete/'+${conference.id}}" <input type="submit" class="icon icon-delete grey-border"
data-confirm="Удалить конференцию?"> alt="Удалить" th:value="${conference.id}"
<i class="fa fa-trash" aria-hidden="true"></i> data-confirm="Удалить конференцию?"/>
</a> <!--<a class="remove-paper pull-right m-auto" th:href="@{'/conferences/delete/'+${conference.id}}"-->
<!--data-confirm="Удалить конференцию?">-->
<!--<i class="fa fa-trash" aria-hidden="true"></i>-->
<!--</a>-->
</div> </div>
</div> </div>

View File

@ -55,7 +55,8 @@
<a class="nav-link js-scroll-trigger" target="_blank" href="http://is.ulstu.ru">Сайт кафедры</a> <a class="nav-link js-scroll-trigger" target="_blank" href="http://is.ulstu.ru">Сайт кафедры</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link js-scroll-trigger" target="_blank" th:href="@{'http://timetable.athene.tech?filter='+${currentUser}}">Расписание</a> <a class="nav-link js-scroll-trigger" target="_blank"
th:href="@{'http://timetable.athene.tech?filter='+${currentUser}}">Расписание</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link js-scroll-trigger" target="_blank" href="https://kias.rfbr.ru/">КИАС РФФИ</a> <a class="nav-link js-scroll-trigger" target="_blank" href="https://kias.rfbr.ru/">КИАС РФФИ</a>
@ -97,36 +98,53 @@
<script src="/js/core.js"></script> <script src="/js/core.js"></script>
<script src="/js/config.js"></script> <script src="/js/config.js"></script>
<script src="/js/odin.js"></script> <script src="/js/odin.js"></script>
<script th:inline="javascript">
/*<![CDATA[*/
var message = /*[[${flashMessage}]]*/ "";
if (message && message.length > 0) {
showFeedbackMessage(message, MessageTypesEnum.DANGER);
}
/*]]>*/
</script>
<th:block layout:fragment="scripts"> <th:block layout:fragment="scripts">
</th:block> </th:block>
<!-- Yandex.Metrika counter --> <!-- Yandex.Metrika counter -->
<script type="text/javascript" > <script type="text/javascript">
(function (d, w, c) { (function (d, w, c) {
(w[c] = w[c] || []).push(function() { (w[c] = w[c] || []).push(function () {
try { try {
w.yaCounter49387279 = new Ya.Metrika2({ w.yaCounter49387279 = new Ya.Metrika2({
id:49387279, id: 49387279,
clickmap:true, clickmap: true,
trackLinks:true, trackLinks: true,
accurateTrackBounce:true, accurateTrackBounce: true,
webvisor:true webvisor: true
}); });
} catch(e) { } } catch (e) {
}
}); });
var n = d.getElementsByTagName("script")[0], var n = d.getElementsByTagName("script")[0],
s = d.createElement("script"), s = d.createElement("script"),
f = function () { n.parentNode.insertBefore(s, n); }; f = function () {
n.parentNode.insertBefore(s, n);
};
s.type = "text/javascript"; s.type = "text/javascript";
s.async = true; s.async = true;
s.src = "https://mc.yandex.ru/metrika/tag.js"; s.src = "https://mc.yandex.ru/metrika/tag.js";
if (w.opera == "[object Opera]") { if (w.opera == "[object Opera]") {
d.addEventListener("DOMContentLoaded", f, false); d.addEventListener("DOMContentLoaded", f, false);
} else { f(); } } else {
f();
}
})(document, window, "yandex_metrika_callbacks2"); })(document, window, "yandex_metrika_callbacks2");
</script> </script>
<noscript><div><img src="https://mc.yandex.ru/watch/49387279" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <noscript>
<div><img src="https://mc.yandex.ru/watch/49387279" style="position:absolute; left:-9999px;" alt=""/></div>
</noscript>
<!-- /Yandex.Metrika counter --> <!-- /Yandex.Metrika counter -->
</body> </body>
</html> </html>

View File

@ -12,8 +12,7 @@
<span class="text-muted" th:text="${paper.authorsString}"/> <span class="text-muted" th:text="${paper.authorsString}"/>
</a> </a>
<input class="id-class" type="hidden" th:value="${paper.id}"/> <input class="id-class" type="hidden" th:value="${paper.id}"/>
<a class="remove-paper pull-right d-none" th:href="@{'/papers/delete/'+${paper.id}}" <a class="remove-paper pull-right d-none" href="#" 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>

View File

@ -7,7 +7,8 @@
<body> <body>
<div class="container" layout:fragment="content"> <div class="container" layout:fragment="content">
<form id="papers-form" method="post" th:action="@{'/papers/papers'}"> <form id="papers-form" method="post" th:action="@{'/papers/papers'}"
th:object="${filteredPapers}">
<input th:type="hidden" name="paperDeleteId" id="paperDeleteId"/> <input th:type="hidden" name="paperDeleteId" id="paperDeleteId"/>
<section id="papers"> <section id="papers">
<div class="container"> <div class="container">
@ -17,7 +18,11 @@
<div th:replace="papers/fragments/paperNavigationFragment"/> <div th:replace="papers/fragments/paperNavigationFragment"/>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="alert alert-danger" th:if="${#fields.hasErrors('*')}">
<p th:each="err : ${#fields.errors('*')}" th:text="${err}"></p>
</div>
<div class="col-md-9 col-sm-12"> <div class="col-md-9 col-sm-12">
<th:block th:each="paper : ${filteredPapers.papers}"> <th:block th:each="paper : ${filteredPapers.papers}">
<div th:replace="papers/fragments/paperLineFragment :: paperLine(paper=${paper})"/> <div th:replace="papers/fragments/paperLineFragment :: paperLine(paper=${paper})"/>
@ -43,7 +48,7 @@
</div> </div>
</div> </div>
</div> </div>
<div th:replace="fragments/noRecordsFragment :: noRecords(entities=${filteredPapers.papers}, noRecordsMessage=' одной статьи', url='paper')"/> <!--<div th:replace="fragments/noRecordsFragment :: noRecords(entities=${filteredPapers.papers}, noRecordsMessage=' одной статьи', url='paper')"/>-->
</div> </div>
</section> </section>