add conferences

This commit is contained in:
Anton Romanov 2020-04-27 18:34:22 +04:00
parent 5ae17fbe83
commit b662437afe
33 changed files with 651 additions and 52 deletions

View File

@ -0,0 +1,71 @@
package ru.ulstu.conference.controller;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.core.util.FacesUtil;
import ru.ulstu.user.service.UserService;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.List;
@Named
@ViewScoped
public class ConferenceDashboardView {
@Inject
private ConferenceService conferenceService;
@Inject
private UserService userService;
private List<Conference> conferences;
private List<Conference> selectedConferences = new ArrayList<>();
private String newConferenceTitle;
@PostConstruct
public void init() {
conferences = conferenceService.findAllActiveByCurrentUser();
}
public List<Conference> getConferences() {
return conferences;
}
public void create() {
conferenceService.createByTitle(newConferenceTitle);
FacesUtil.showInfoMessage("Статья создана", newConferenceTitle);
newConferenceTitle = "";
conferences = conferenceService.findAllActiveByCurrentUser();
}
public void deleteSelected() {
conferenceService.delete(selectedConferences);
conferences = conferenceService.findAllActiveByCurrentUser();
FacesUtil.showInfoMessage("Было удалено статей: " + selectedConferences.size(), "");
}
public String getNewConferenceTitle() {
return newConferenceTitle;
}
public void setNewConferenceTitle(String newConferenceTitle) {
this.newConferenceTitle = newConferenceTitle;
}
public List<Conference> getSelectedConferences() {
return selectedConferences;
}
public void setSelectedConferences(List<Conference> selectedConferences) {
this.selectedConferences = selectedConferences;
}
public String getCurrentUser() {
return userService.getCurrentUser().getUserAbbreviate();
}
}

View File

@ -0,0 +1,89 @@
package ru.ulstu.conference.controller;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.core.navigation.Page;
import ru.ulstu.core.util.FacesUtil;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.user.model.User;
import ru.ulstu.user.service.UserService;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@Named
@ViewScoped
public class ConferenceView implements Serializable {
@Inject
private ConferenceService conferenceService;
@Inject
private DeadlineService deadlineService;
@Inject
private UserService userService;
private Conference conference;
private Date newDeadlineDate;
private String newDeadlineDescription;
@PostConstruct
public void init() {
conference = conferenceService.findOne(Integer.valueOf(FacesUtil.getRequestParams().get("id")));
newDeadlineDescription = "";
newDeadlineDate = new Date();
FacesUtil.showInfoMessage("Статья открыта", "");
}
public Conference getConference() {
return conference;
}
public void setConference(Conference conference) {
this.conference = conference;
}
public List<User> getAuthors() {
return userService.findAll();
}
public String save() {
conferenceService.save(conference);
FacesUtil.showInfoMessage("Статья сохранена", "");
return Page.CONFERENCE_LIST + "?faces-redirect=true";
}
public Date getNewDeadlineDate() {
return newDeadlineDate;
}
public void setNewDeadlineDate(Date newDeadlineDate) {
this.newDeadlineDate = newDeadlineDate;
}
public String getNewDeadlineDescription() {
return newDeadlineDescription;
}
public void setNewDeadlineDescription(String newDeadlineDescription) {
this.newDeadlineDescription = newDeadlineDescription;
}
public void deleteDeadline(Deadline deadline) {
conference.getDeadlines().remove(deadline);
}
public void addDeadline() {
conference.getDeadlines().add(deadlineService.create(newDeadlineDescription, newDeadlineDate));
newDeadlineDescription = "";
newDeadlineDate = new Date();
}
}

View File

@ -0,0 +1,63 @@
package ru.ulstu.conference.controller;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.core.util.FacesUtil;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.List;
@Named
@ViewScoped
public class ConferencesView {
@Inject
private ConferenceService conferenceService;
private List<Conference> conferences;
private List<Conference> selectedConferences = new ArrayList<>();
private String newConferenceTitle;
@PostConstruct
public void init() {
conferences = conferenceService.findAll();
}
public void create() {
conferenceService.createByTitle(newConferenceTitle);
FacesUtil.showInfoMessage("Конференция создана", newConferenceTitle);
newConferenceTitle = "";
conferences = conferenceService.findAll();
}
public void deleteSelected() {
conferenceService.delete(selectedConferences);
conferences = conferenceService.findAll();
FacesUtil.showInfoMessage("Было удалено конференций: " + selectedConferences.size(), "");
}
public List<Conference> getConferences() {
return conferences;
}
public String getNewConferenceTitle() {
return newConferenceTitle;
}
public void setNewConferenceTitle(String newConferenceTitle) {
this.newConferenceTitle = newConferenceTitle;
}
public List<Conference> getSelectedConferences() {
return selectedConferences;
}
public void setSelectedConferences(List<Conference> selectedConferences) {
this.selectedConferences = selectedConferences;
}
}

View File

@ -17,8 +17,6 @@ import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.FetchType; import javax.persistence.FetchType;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.OrderBy; import javax.persistence.OrderBy;
import javax.persistence.Table; import javax.persistence.Table;
@ -63,18 +61,21 @@ public class Conference extends BaseEntity implements UserActivity, EventSource
@OrderBy("date") @OrderBy("date")
private List<Deadline> deadlines = new ArrayList<>(); private List<Deadline> deadlines = new ArrayList<>();
@ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER) @OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
@JoinTable(name = "paper_conference", @JoinColumn(name = "conference_id")
joinColumns = {@JoinColumn(name = "conference_id")},
inverseJoinColumns = {@JoinColumn(name = "paper_id")})
@Fetch(FetchMode.SUBSELECT)
private List<Paper> papers = new ArrayList<>(); private List<Paper> papers = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "conference_id", unique = true) @JoinColumn(name = "conference_id", unique = true)
@Fetch(FetchMode.SUBSELECT)
private List<ConferenceUser> users = new ArrayList<>(); private List<ConferenceUser> users = new ArrayList<>();
public Conference() {
}
public Conference(@NotBlank String title) {
this.title = title;
}
public String getTitle() { public String getTitle() {
return title; return title;
} }

View File

@ -69,6 +69,8 @@ public class ConferenceUser extends BaseEntity {
public ConferenceUser(User user) { public ConferenceUser(User user) {
this.user = user; this.user = user;
this.deposit = Deposit.REPORT;
this.participation = Participation.INTRAMURAL;
} }
@JsonCreator @JsonCreator

View File

@ -22,13 +22,14 @@ 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;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
import static org.springframework.util.ObjectUtils.isEmpty; import static org.springframework.util.ObjectUtils.isEmpty;
import static ru.ulstu.core.util.StreamApiUtils.convert; import static ru.ulstu.core.util.StreamApiUtils.convert;
@ -110,30 +111,44 @@ public class ConferenceService extends BaseService {
return true; return true;
} }
public Conference save(Conference conference) {
if (isEmpty(conference.getId())) {
return create(conference);
} else {
return update(conference);
}
}
@Transactional @Transactional
public Conference create(ConferenceDto conferenceDto) throws IOException { public Conference create(ConferenceDto conferenceDto) throws IOException {
Conference newConference = copyFromDto(new Conference(), conferenceDto); return create(copyFromDto(new Conference(), conferenceDto));
newConference = conferenceRepository.save(newConference); }
conferenceNotificationService.sendCreateNotification(newConference);
eventService.createFromObject(newConference, Collections.emptyList(), false, "конференции"); @Transactional
return newConference; public Conference create(Conference conference) {
conference = conferenceRepository.save(conference);
conferenceNotificationService.sendCreateNotification(conference);
return conference;
} }
@Transactional @Transactional
private Conference update(ConferenceDto conferenceDto) throws IOException { private Conference update(ConferenceDto conferenceDto) throws IOException {
Conference conference = conferenceRepository.getOne(conferenceDto.getId()); return update(copyFromDto(conferenceRepository.getOne(conferenceDto.getId()), conferenceDto));
List<Deadline> oldDeadlines = conference.getDeadlines().stream() }
@Transactional
private Conference update(Conference conference) {
Conference oldConference = conferenceRepository.getOne(conference.getId());
List<Deadline> oldDeadlines = oldConference.getDeadlines().stream()
.map(this::copyDeadline) .map(this::copyDeadline)
.collect(Collectors.toList()); .collect(Collectors.toList());
Date oldBeginDate = conference.getBeginDate(); Date oldBeginDate = conference.getBeginDate();
Date oldEndDate = conference.getEndDate(); Date oldEndDate = conference.getEndDate();
conferenceRepository.save(copyFromDto(conference, conferenceDto)); conferenceRepository.save(conference);
eventService.updateConferenceDeadlines(conference);
sendNotificationAfterUpdateDeadlines(conference, oldDeadlines); sendNotificationAfterUpdateDeadlines(conference, oldDeadlines);
if (!conference.getBeginDate().equals(oldBeginDate) || !conference.getEndDate().equals(oldEndDate)) { if (!conference.getBeginDate().equals(oldBeginDate) || !conference.getEndDate().equals(oldEndDate)) {
conferenceNotificationService.updateConferencesDatesNotification(conference, oldBeginDate, oldEndDate); conferenceNotificationService.updateConferencesDatesNotification(conference, oldBeginDate, oldEndDate);
} }
conferenceDto.getRemovedDeadlineIds().forEach(deadlineService::remove);
return conference; return conference;
} }
@ -147,6 +162,12 @@ public class ConferenceService extends BaseService {
return false; return false;
} }
@Transactional
public boolean delete(List<Conference> conferences) {
conferences.forEach(conference -> delete(conference.getId()));
return true;
}
public ConferenceDto addDeadline(ConferenceDto conferenceDto) { public ConferenceDto addDeadline(ConferenceDto conferenceDto) {
conferenceDto.getDeadlines().add(new Deadline()); conferenceDto.getDeadlines().add(new Deadline());
return conferenceDto; return conferenceDto;
@ -246,7 +267,7 @@ public class ConferenceService extends BaseService {
conferenceRepository.updatePingConference(conferenceDto.getId()); conferenceRepository.updatePingConference(conferenceDto.getId());
} }
private Conference findOne(Integer conferenceId) { public Conference findOne(Integer conferenceId) {
return conferenceRepository.getOne(conferenceId); return conferenceRepository.getOne(conferenceId);
} }
@ -315,4 +336,20 @@ public class ConferenceService extends BaseService {
public Conference getActiveConferenceByUser(User user) { public Conference getActiveConferenceByUser(User user) {
return conferenceRepository.findActiveByUser(user); return conferenceRepository.findActiveByUser(user);
} }
public Conference createByTitle(String newConferenceTitle) {
Conference conference = new Conference(newConferenceTitle);
conference.getUsers().add(new ConferenceUser(userService.getCurrentUser()));
conference.getDeadlines().add(deadlineService.createWithOffset(new Date(), 1, ChronoUnit.WEEKS));
return save(conference);
}
public List<Conference> findAllActiveByCurrentUser() {
return findAllActive()
.stream()
.filter(conference -> conference.getUsers()
.stream()
.anyMatch(user -> user.getUser().equals(userService.getCurrentUser())))
.collect(toList());
}
} }

View File

@ -13,7 +13,9 @@ public class Page {
public static final String GRANT_DASHBOARD = "/grant/dashboard.xhtml"; public static final String GRANT_DASHBOARD = "/grant/dashboard.xhtml";
public static final String USER_LIST = "/admin/users.xhtml"; public static final String USER_LIST = "/admin/users.xhtml";
public static final String LOGOUT = "/logout"; public static final String LOGOUT = "/logout";
public static final String CONFERENCE = "/conference/conference.xhtml";
public static final String CONFERENCE_DASHBOARD = "/conference/dashboard.xhtml"; public static final String CONFERENCE_DASHBOARD = "/conference/dashboard.xhtml";
public static final String CONFERENCE_LIST = "/conference/conferences.xhtml";
public static final String PROJECT_DASHBOARD = "/conference/dashboard.xhtml"; public static final String PROJECT_DASHBOARD = "/conference/dashboard.xhtml";
public String getIndex() { public String getIndex() {
@ -59,4 +61,12 @@ public class Page {
public String getProjectDashboard() { public String getProjectDashboard() {
return PROJECT_DASHBOARD; return PROJECT_DASHBOARD;
} }
public String getConference() {
return CONFERENCE;
}
public String getConferenceList() {
return CONFERENCE_LIST;
}
} }

View File

@ -21,6 +21,7 @@ import javax.persistence.Enumerated;
import javax.persistence.FetchType; import javax.persistence.FetchType;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany; import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.OrderBy; import javax.persistence.OrderBy;
import javax.persistence.Temporal; import javax.persistence.Temporal;
@ -126,8 +127,9 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
@Column(name = "latex_text") @Column(name = "latex_text")
private String latexText; private String latexText;
@ManyToMany(mappedBy = "papers") @ManyToOne()
private List<Conference> conferences; @JoinColumn(name = "conference_id")
private Conference conference;
@ManyToMany(mappedBy = "papers") @ManyToMany(mappedBy = "papers")
private List<Grant> grants; private List<Grant> grants;
@ -251,12 +253,12 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
this.latexText = latexText; this.latexText = latexText;
} }
public List<Conference> getConferences() { public Conference getConference() {
return conferences; return conference;
} }
public void setConferences(List<Conference> conferences) { public void setConference(Conference conference) {
this.conferences = conferences; this.conference = conference;
} }
public List<Grant> getGrants() { public List<Grant> getGrants() {
@ -321,12 +323,12 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
Objects.equals(files, paper.files) && Objects.equals(files, paper.files) &&
Objects.equals(authors, paper.authors) && Objects.equals(authors, paper.authors) &&
Objects.equals(latexText, paper.latexText) && Objects.equals(latexText, paper.latexText) &&
Objects.equals(conferences, paper.conferences) && Objects.equals(conference, paper.conference) &&
Objects.equals(grants, paper.grants); Objects.equals(grants, paper.grants);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(super.hashCode(), title, status, type, createDate, updateDate, deadlines, comment, url, locked, events, files, authors, latexText, conferences, grants); return Objects.hash(super.hashCode(), title, status, type, createDate, updateDate, deadlines, comment, url, locked, events, files, authors, latexText, conference, grants);
} }
} }

View File

@ -21,7 +21,7 @@ public interface PaperRepository extends JpaRepository<Paper, Integer> {
List<Paper> findByStatusNot(Paper.PaperStatus status); List<Paper> findByStatusNot(Paper.PaperStatus status);
List<Paper> findByConferencesIsNullAndStatusNot(Paper.PaperStatus status); List<Paper> findByConferenceIsNullAndStatusNot(Paper.PaperStatus status);
List<Paper> findByIdNotInAndConferencesIsNullAndStatusNot(List<Integer> paperIds, Paper.PaperStatus status); List<Paper> findByIdNotInAndConferenceIsNullAndStatusNot(List<Integer> paperIds, Paper.PaperStatus status);
} }

View File

@ -334,9 +334,9 @@ public class PaperService {
public List<Paper> findAllNotSelect(List<Integer> paperIds) { public List<Paper> findAllNotSelect(List<Integer> paperIds) {
if (!paperIds.isEmpty()) { if (!paperIds.isEmpty()) {
return sortPapers(paperRepository.findByIdNotInAndConferencesIsNullAndStatusNot(paperIds, COMPLETED)); return sortPapers(paperRepository.findByIdNotInAndConferenceIsNullAndStatusNot(paperIds, COMPLETED));
} else { } else {
return sortPapers(paperRepository.findByConferencesIsNullAndStatusNot(COMPLETED)); return sortPapers(paperRepository.findByConferenceIsNullAndStatusNot(COMPLETED));
} }
} }

View File

@ -34,6 +34,10 @@
<p:menuitem value="Мои гранты" icon="fa fa-calendar" url="#{page.grantDashboard}"/> <p:menuitem value="Мои гранты" icon="fa fa-calendar" url="#{page.grantDashboard}"/>
<p:menuitem value="Все гранты" icon="fa fa-file-o" url="#{page.grantList}"/> <p:menuitem value="Все гранты" icon="fa fa-file-o" url="#{page.grantList}"/>
</p:submenu> </p:submenu>
<p:submenu label="Конференции" icon="fa fa-file-text-o">
<p:menuitem value="Мои конференции" icon="fa fa-calendar" url="#{page.conferenceDashboard}"/>
<p:menuitem value="Все конференции" icon="fa fa-file-o" url="#{page.conferenceList}"/>
</p:submenu>
<p:menuitem value="Пользователи" icon="fa fa-calendar" url="#{page.userList}"/> <p:menuitem value="Пользователи" icon="fa fa-calendar" url="#{page.userList}"/>
<f:facet name="options"> <f:facet name="options">

View File

@ -0,0 +1,124 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html"
>
<ui:composition template="/basicTemplate.xhtml">
<ui:define name="header">
Редактирование конференции
</ui:define>
<ui:define name="content">
<style>
#mainForm\:conferencePanel > tbody > tr {
border: none;
}
#mainForm\:conferencePanel > tbody > tr > td {
border: none;
}
.ui-editor.ui-widget-content {
background: white !important;
}
</style>
<p:panel id="panel" header="Редактирование конференции: #{conferenceView.conference.title}"
style="margin-bottom:10px;">
<div class="ui-fluid">
<div class="ui-g">
<div class="ui-md-3 ui-g-12">
<h:outputLabel value="Название:"/>
</div>
<div class="ui-md-7 ui-g-12">
<p:inputText id="name" required="true" value="#{conferenceView.conference.title}"/>
<p:message for="name"/>
</div>
<div class="ui-md-3 ui-g-12">
<h:outputLabel value="Ссылка:"/>
</div>
<div class="ui-md-7 ui-g-12">
<p:inputText id="url" required="true" value="#{conferenceView.conference.url}"/>
<p:message for="url"/>
</div>
<div class="ui-md-2 ui-g-12">
</div>
<div class="ui-md-3 ui-g-12">
<!-- <p:outputLabel for="authors" value="Авторы:"/>-->
</div>
<div class="ui-md-7 ui-g-12">
<!-- <p:selectCheckboxMenu id="authors" value="#{conferenceView.conference.users}" multiple="true"-->
<!-- converter="#{conferenceUserConverter}">-->
<!-- <f:attribute name="collectionType" value="java.util.HashSet"/>-->
<!-- <f:selectItems value="#{conferenceView.authors}"-->
<!-- var="author"-->
<!-- itemLabel="#{author.userAbbreviate}"-->
<!-- itemValue="#{author}"/>-->
<!-- </p:selectCheckboxMenu>-->
</div>
<div class="ui-md-3 ui-g-12">
<!-- <p:outputLabel for="authors" value="Ключевые даты:"/>-->
</div>
<div class="ui-md-7 ui-g-12">
<div class="ui-fluid">
<div class="ui-g">
<ui:repeat value="#{conferenceView.conference.deadlines}" var="deadline">
<div class="ui-md-5 ui-g-12">
<p:datePicker value="#{deadline.date}" pattern="dd.MM.yyyy"/>
</div>
<div class="ui-md-5 ui-g-12">
<p:inputText value="#{deadline.description}"/>
</div>
<div class="ui-md-1 ui-g-12">
<p:commandButton icon="pi pi-times">
<p:ajax update="mainForm" process="@this"
listener="#{conferenceView.deleteDeadline(deadline)}"/>
</p:commandButton>
</div>
</ui:repeat>
<div class="ui-md-5 ui-g-12">
<p:datePicker value="#{conferenceView.newDeadlineDate}" placeholder="Введите дату"
pattern="dd.MM.yyyy"/>
</div>
<div class="ui-md-5 ui-g-12">
<p:inputText value="#{conferenceView.newDeadlineDescription}"
placeholder="Описание ключевой даты"/>
</div>
<div class="ui-md-1 ui-g-12">
<p:commandButton icon="pi pi-check">
<p:ajax update="mainForm" process="@this"
listener="#{conferenceView.addDeadline()}"/>
</p:commandButton>
</div>
</div>
</div>
</div>
<div class="ui-md-3 ui-g-12">
<p:outputLabel for="comment" value="Комментарий:"/>
</div>
<div class="ui-md-7 ui-g-12">
<p:editor id="comment" widgetVar="editor2" value="#{conferenceView.conference.description}"
height="300"
style="margin-bottom:10px" placeholder="Комментарий"/>
</div>
<div class="ui-md-2 ui-g-12">
<p>
Конференция создана
</p>
<p>
Конференция обновлена
</p>
</div>
<div class="ui-md-5 ui-g-12">
<p:commandButton action="#{conferenceView.save}" value="Сохранить" ajax="true" process="@form"
update="messages @form"/>
</div>
</div>
</div>
</p:panel>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,10 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://java.sun.com/jsf/html">
<span class="fa-stack fa-1x big-icon" title="#{conference.status.statusName}">
<i class="fa fa-circle #{conference.status.elementClass} fa-stack-2x"></i>
<i class="fa fa-file-text-o fa-stack-1x fa-inverse"></i>
</span>
<ui:fragment rendered="#{shortMode != true}">
<p:outputText value="#{conference.status.statusName}"/>
</ui:fragment>
</ui:composition>

View File

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition template="/basicTemplate.xhtml">
<ui:define name="content">
<style>
.ui-datatable .ui-datatable-header {
text-align: right !important;
}
</style>
<p:panel id="panel" header="Все конференции" style="margin-bottom:10px;">
<div class="ui-fluid">
<div class="ui-g">
<div class="ui-md-5 ui-g-12">
<p:inputText placeholder="Создать новую коференцию" id="newConferenceName"
value="#{conferencesView.newConferenceTitle}" required="true"
requiredMessage="Введите название новой конференции"/>
<p:message for="newConferenceName"/>
</div>
<div class="ui-md-2 ui-g-12">
<p:commandButton action="#{conferencesView.create}" value="Создать" ajax="true" process="@form"
update="messages @form mainForm:conferencesTable"/>
</div>
<div class="ui-md-3 ui-g-12">
<p:commandButton value="Удалить выделенные" id="conferencesRemoveButton"
disabled="#{conferencesView.selectedConferences.isEmpty()}"
action="#{conferencesView.deleteSelected}" ajax="true"
process="mainForm:conferencesRemoveButton"
update="messages mainForm:conferencesTable">
<p:confirm header="Подтверждение" message="Удалить выделенные конференции?"
icon="pi pi-exclamation-triangle"/>
</p:commandButton>
</div>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Да" type="button" styleClass="ui-confirmdialog-yes" icon="pi pi-check"/>
<p:commandButton value="Нет" type="button" styleClass="ui-confirmdialog-no" icon="pi pi-times"/>
</p:confirmDialog>
</div>
<p:dataTable value="#{conferencesView.conferences}" var="conference" paginator="true"
paginatorPosition="bottom"
rows="10" id="conferencesTable"
widgetVar="conferencesTable" emptyMessage="Не найдено подходящих конференций"
selection="#{conferencesView.selectedConferences}" rowKey="#{conference.id}">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Поиск:"/>
<p:inputText id="globalFilter" onkeyup="PF('conferencesTable').filter()" style="width:150px"
placeholder="Строка поиска..."/>
</p:outputPanel>
</f:facet>
<p:ajax event="rowSelect" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"/>
<p:ajax event="rowSelectCheckbox" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"/>
<p:ajax event="rowUnselectCheckbox" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"/>
<p:ajax event="rowUnselect" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"/>
<p:ajax event="toggleSelect" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"
partialSubmit="true"/>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Название" filterBy="#{conference.title}" filterMatchMode="contains">
<h:outputLink value="#{page.conference}">
#{conference.title}
<f:param name="id" value="#{conference.id}"/>
</h:outputLink>
</p:column>
</p:dataTable>
</div>
</p:panel>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition template="/basicTemplate.xhtml">
<ui:define name="content">
<style>
.ui-datatable .ui-datatable-header {
text-align: right !important;
}
</style>
<p:panel id="panel" header="Активные конференции пользователя #{conferenceDashboardView.currentUser}"
style="margin-bottom:10px;">
<div class="ui-fluid">
<div class="ui-g">
<div class="ui-md-5 ui-g-12">
<p:inputText placeholder="Создать новую конференцию" id="newConferenceName"
value="#{conferenceDashboardView.newConferenceTitle}" required="true"
requiredMessage="Введите название новой конференции"/>
<p:message for="newConferenceName"/>
</div>
<div class="ui-md-2 ui-g-12">
<p:commandButton action="#{conferenceDashboardView.create}" value="Создать" ajax="true"
process="@form"
update="messages @form mainForm:conferencesTable"/>
</div>
<div class="ui-md-3 ui-g-12">
<p:commandButton value="Удалить выделенные" id="conferencesRemoveButton"
disabled="#{conferenceDashboardView.selectedConferences.isEmpty()}"
action="#{conferenceDashboardView.deleteSelected}" ajax="true"
process="mainForm:conferencesRemoveButton"
update="messages mainForm:conferencesTable">
<p:confirm header="Подтверждение" message="Удалить выделенные конференции?"
icon="pi pi-exclamation-triangle"/>
</p:commandButton>
</div>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Да" type="button" styleClass="ui-confirmdialog-yes" icon="pi pi-check"/>
<p:commandButton value="Нет" type="button" styleClass="ui-confirmdialog-no" icon="pi pi-times"/>
</p:confirmDialog>
</div>
<p:dataTable value="#{conferenceDashboardView.conferences}" var="conference" paginator="true"
paginatorPosition="bottom"
rows="10" id="conferencesTable"
widgetVar="conferencesTable" emptyMessage="Не найдено подходящих конференций"
selection="#{conferenceDashboardView.selectedConferences}" rowKey="#{conference.id}">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Поиск:"/>
<p:inputText id="globalFilter" onkeyup="PF('conferencesTable').filter()" style="width:150px"
placeholder="Строка поиска..."/>
</p:outputPanel>
</f:facet>
<p:ajax event="rowSelect" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"/>
<p:ajax event="rowSelectCheckbox" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"/>
<p:ajax event="rowUnselectCheckbox" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"/>
<p:ajax event="rowUnselect" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"/>
<p:ajax event="toggleSelect" update="mainForm:conferencesRemoveButton"
process="mainForm:conferencesTable"
partialSubmit="true"/>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Название" filterBy="#{conference.title}" filterMatchMode="contains">
<h:outputLink value="#{page.conference}">
#{conference.title}
<f:param name="id" value="#{conference.id}"/>
</h:outputLink>
</p:column>
</p:dataTable>
</div>
</p:panel>
</ui:define>
</ui:composition>
</html>

View File

@ -6,14 +6,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Страница не найдена</title> <title>Страница не найдена</title>
<h:outputStylesheet name="css/styles.css"/> <h:outputStylesheet name="css/style.css"/>
</h:head> </h:head>
<h:body> <h:body styleClass="black">
<div class="ui-g"> <div class="ui-g">
<div class="ui-g-5"></div> <div class="ui-g-5"></div>
<div class="ui-g-2"> <div class="ui-g-2">
<p:panel header="Страница не найдена" style="margin-bottom:20px"> <p:panel header="Страница не найдена" style="margin-bottom:20px">
<h:link outcome="#{page.INDEX}" styleClass="btn btn-primary"> <h:link outcome="#{page.index}" styleClass="btn btn-primary">
<i class="fa fa-home fa-4"></i> Вернуться на главную <i class="fa fa-home fa-4"></i> Вернуться на главную
</h:link> </h:link>
</p:panel> </p:panel>

View File

@ -33,7 +33,7 @@
action="#{grantDashboardView.deleteSelected}" ajax="true" action="#{grantDashboardView.deleteSelected}" ajax="true"
process="mainForm:grantsRemoveButton" process="mainForm:grantsRemoveButton"
update="messages mainForm:grantsTable"> update="messages mainForm:grantsTable">
<p:confirm header="Подтверждение" message="Удалить выделенные статьи?" <p:confirm header="Подтверждение" message="Удалить выделенные гранты?"
icon="pi pi-exclamation-triangle"/> icon="pi pi-exclamation-triangle"/>
</p:commandButton> </p:commandButton>
</div> </div>

View File

@ -0,0 +1,13 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="orion" id="20200427_164000-1">
<addColumn tableName="paper">
<column name="conference_id" type="integer"/>
</addColumn>
<addForeignKeyConstraint baseTableName="paper" baseColumnNames="conference_id" constraintName="fk_conference"
referencedTableName="conference" referencedColumnNames="id"/>
<dropTable tableName="paper_conference"/>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<include file="db/0.1.0/changelog-20200427_164000-schema.xml"/>
</databaseChangeLog>

View File

@ -55,4 +55,5 @@
<include file="db/changelog-20190601_000001-schema.xml"/> <include file="db/changelog-20190601_000001-schema.xml"/>
<include file="db/changelog-20190605_000000-schema.xml"/> <include file="db/changelog-20190605_000000-schema.xml"/>
<include file="db/changelog-20190607_000002-schema.xml"/> <include file="db/changelog-20190607_000002-schema.xml"/>
<include file="db/0.1.0/changelog.xml"/>
</databaseChangeLog> </databaseChangeLog>

View File

@ -10,7 +10,7 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Была создана новая конференция: "<a th:href="@{|${baseUrl}/conferences/conference?id=${conference.id}|}"> Была создана новая конференция: "<a th:href="@{|${baseUrl}/conference/conference.xhtml?id=${conference.id}|}">
<span th:text="${conference.title}">Title</span></a>". <span th:text="${conference.title}">Title</span></a>".
<br/> <br/>
Спешите принять участие! Спешите принять участие!

View File

@ -10,7 +10,7 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Приближается дедлайн конференции "<a th:href="@{|${baseUrl}/conferences/conference?id=${conference.id}|}"> Приближается дедлайн конференции "<a th:href="@{|${baseUrl}/conference/conference.xhtml?id=${conference.id}|}">
<span th:text="${conference.title}">Title</span></a>". <span th:text="${conference.title}">Title</span></a>".
</p> </p>
<p> <p>

View File

@ -10,7 +10,7 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Конференция "<a th:href="@{|${baseUrl}/conferences/conference?id=${conference.id}|}"> Конференция "<a th:href="@{|${baseUrl}/conference/conference.xhtml?id=${conference.id}|}">
<span th:text="${conference.title}">Title</span></a>" была пропингована <span th:text="${conference.title}">Title</span></a>" была пропингована
<b><span th:text="${conference.ping}"></span></b> раз. <b><span th:text="${conference.ping}"></span></b> раз.
<br/> <br/>

View File

@ -10,7 +10,7 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Даты проведения конференции "<a th:href="@{|${baseUrl}/conferences/conference?id=${conference.id}|}"> Даты проведения конференции "<a th:href="@{|${baseUrl}/conference/conference.xhtml?id=${conference.id}|}">
<span th:text="${conference.title}">Title</span></a>" изменились с <br/> <span th:text="${conference.title}">Title</span></a>" изменились с <br/>
"<span th:text="${#dates.format(oldBeginDate, 'dd.MM.yyyy')}">oldBeginDate</span>" "<span th:text="${#dates.format(oldBeginDate, 'dd.MM.yyyy')}">oldBeginDate</span>"
- -

View File

@ -10,7 +10,7 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Дедлайны конференции "<a th:href="@{|${baseUrl}/conferences/conference?id=${conference.id}|}"> Дедлайны конференции "<a th:href="@{|${baseUrl}/conference /conference.xhtml?id=${conference.id}|}">
<span th:text="${conference.title}">Title</span></a>" притерпели изменения. <span th:text="${conference.title}">Title</span></a>" притерпели изменения.
<br/> <br/>
Ознакомтесь с изменениями. Ознакомтесь с изменениями.

View File

@ -10,7 +10,7 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Состав рабочей группы гранта "<a th:href="@{|${baseUrl}/grants/grant?id=${grant.id}|}"><span Состав рабочей группы гранта "<a th:href="@{|${baseUrl}/grants/grant.xhtml?id=${grant.id}|}"><span
th:text="${grant.title}">Title</span></a>" сменился с th:text="${grant.title}">Title</span></a>" сменился с
" <span th:each="author : ${oldAuthors}" th:text="${author.lastName + ' '}">oldAuthors</span>" " <span th:each="author : ${oldAuthors}" th:text="${author.lastName + ' '}">oldAuthors</span>"
на " <span th:each="author : ${grant.authors}" th:text="${author.lastName + ' '}">newAuthors</span>". на " <span th:each="author : ${grant.authors}" th:text="${author.lastName + ' '}">newAuthors</span>".

View File

@ -10,7 +10,7 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Был добавлен новый грант: "<a th:href="@{|${baseUrl}/grants/grant?id=${grant.id}|}"> Был добавлен новый грант: "<a th:href="@{|${baseUrl}/grants/grant.xhtml?id=${grant.id}|}">
<span th:text="${grant.title}">Title</span></a>". <span th:text="${grant.title}">Title</span></a>".
<br/> <br/>
</p> </p>

View File

@ -10,7 +10,7 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Приближается дедлайн гранта "<a th:href="@{|${baseUrl}/grants/grant?id=${grant.id}|}"><span Приближается дедлайн гранта "<a th:href="@{|${baseUrl}/grants/grant.xhtml?id=${grant.id}|}"><span
th:text="${grant.title}">Title</span></a>". th:text="${grant.title}">Title</span></a>".
</p> </p>
<p> <p>

View File

@ -10,7 +10,7 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Руководитель гранта "<a th:href="@{|${baseUrl}/grants/grant?id=${grant.id}|}"><span Руководитель гранта "<a th:href="@{|${baseUrl}/grants/grant.xhtml?id=${grant.id}|}"><span
th:text="${grant.title}">Title</span></a>" сменился с th:text="${grant.title}">Title</span></a>" сменился с
"<span th:text="${oldLeader.lastName} ">oldLeader</span>" "<span th:text="${oldLeader.lastName} ">oldLeader</span>"
на "<span th:text="${grant.leader.lastName}">newLeader</span>". на "<span th:text="${grant.leader.lastName}">newLeader</span>".

View File

@ -10,7 +10,8 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Вам нужно поработать над статьей "<a th:href="@{|${baseUrl}/papers/paper?id=${paper.id}|}"><span th:text="${paper.title}">Title</span></a>". Вам нужно поработать над статьей "<a th:href="@{|${baseUrl}/papers/paper.xhtml?id=${paper.id}|}"><span
th:text="${paper.title}">Title</span></a>".
</p> </p>
<div th:with="nextDeadline=${paper.nextDeadline}" th:remove="tag"> <div th:with="nextDeadline=${paper.nextDeadline}" th:remove="tag">
<p th:if="${nextDeadline.isPresent()}"> <p th:if="${nextDeadline.isPresent()}">

View File

@ -10,7 +10,8 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Приближается дедлайн статьи "<a th:href="@{|${baseUrl}/papers/paper?id=${paper.id}|}"><span th:text="${paper.title}">Title</span></a>". Приближается дедлайн статьи "<a th:href="@{|${baseUrl}/papers/paper.xhtml?id=${paper.id}|}"><span
th:text="${paper.title}">Title</span></a>".
</p> </p>
<p> <p>
Срок исполнения: <b><span th:text="${#dates.format(paper.nextDeadline.get().date, 'dd.MM.yyyy')}"></span></b>. Срок исполнения: <b><span th:text="${#dates.format(paper.nextDeadline.get().date, 'dd.MM.yyyy')}"></span></b>.

View File

@ -10,7 +10,8 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Статья "<a th:href="@{|${baseUrl}/papers/paper?id=${paper.id}|}"><span th:text="${paper.title}">Title</span></a>" провалена. Статья "<a th:href="@{|${baseUrl}/papers/paper.xhtml?id=${paper.id}|}"><span
th:text="${paper.title}">Title</span></a>" провалена.
Предыдущий статус - "<span th:text="${oldStatus.statusName}">oldStatus</span>". Предыдущий статус - "<span th:text="${oldStatus.statusName}">oldStatus</span>".
</p> </p>
<p> <p>

View File

@ -10,8 +10,10 @@
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span> Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
</p> </p>
<p> <p>
Статус статьи "<a th:href="@{|${baseUrl}/papers/paper?id=${paper.id}|}"><span th:text="${paper.title}">Title</span></a>" сменился с Статус статьи "<a th:href="@{|${baseUrl}/papers/paper.xhtml?id=${paper.id}|}"><span
"<span th:text="${oldStatus.statusName}">oldStatus</span>" на "<span th:text="${paper.status.statusName}">newStatus</span>". th:text="${paper.title}">Title</span></a>" сменился с
"<span th:text="${oldStatus.statusName}">oldStatus</span>" на "<span
th:text="${paper.status.statusName}">newStatus</span>".
</p> </p>
<p> <p>
Regards, Regards,