show grants

This commit is contained in:
Anton Romanov 2020-04-25 20:34:35 +04:00
parent 2cc3008dc5
commit 5520f19357
19 changed files with 754 additions and 54 deletions

View File

@ -27,8 +27,8 @@ mainClassName = 'ru.ulstu.NgTrackerApplication'
build.dependsOn checkstyleMain build.dependsOn checkstyleMain
bootRun.dependsOn checkstyleMain bootRun.dependsOn checkstyleMain
sourceCompatibility = 1.8 sourceCompatibility = 11
targetCompatibility = 1.8 targetCompatibility = 11
bootRun { bootRun {
systemProperties = System.properties systemProperties = System.properties
@ -124,7 +124,8 @@ dependencies {
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.6.0' compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.6.0'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.6.0' compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.6.0'
//compile group: 'net.sourceforge.htmlunit', name: 'htmlunit', version: '2.35.0' compile group: 'net.sourceforge.htmlunit', name: 'htmlunit', version: '2.35.0'
compile group: 'xalan', name: 'xalan', version: '2.7.2'
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test' testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
//compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.3.1' //compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.3.1'

View File

@ -5,28 +5,48 @@ import javax.inject.Named;
@Named @Named
public class Page { public class Page {
public static final String INDEX = "/index.xhtml"; public static final String INDEX = "/index.xhtml";
public static final String PAPER = "/paper/paper.xhtml";
public static final String PAPER_LIST = "/paper/papers.xhtml"; public static final String PAPER_LIST = "/paper/papers.xhtml";
public static final String DASHBOARD = "/paper/dashboard.xhtml"; public static final String PAPER_DASHBOARD = "/paper/dashboard.xhtml";
public static final String GRANT = "/grant/grant.xhtml";
public static final String GRANT_LIST = "/grant/grants.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 String getPAPER_LIST() { public String getIndex() {
return PAPER_LIST;
}
public String getINDEX() {
return INDEX; return INDEX;
} }
public String getDASHBOARD() { public String getPaperList() {
return DASHBOARD; return PAPER_LIST;
} }
public String getUSER_LIST() { public String getPaperDashboard() {
return PAPER_DASHBOARD;
}
public String getUserList() {
return USER_LIST; return USER_LIST;
} }
public String getLOGOUT() { public String getLogout() {
return LOGOUT; return LOGOUT;
} }
public String getGrantList() {
return GRANT_LIST;
}
public String getGrantDashboard() {
return GRANT_DASHBOARD;
}
public String getPaper() {
return PAPER;
}
public String getGrant() {
return GRANT;
}
} }

View File

@ -0,0 +1,76 @@
package ru.ulstu.grant.controller;
import ru.ulstu.core.util.FacesUtil;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.grant.service.GrantService;
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.Arrays;
import java.util.List;
@Named
@ViewScoped
public class GrantDashboardView {
@Inject
private GrantService grantService;
@Inject
private UserService userService;
private List<Grant> grants;
private List<Grant> selectedGrants = new ArrayList<>();
private String newGrantTitle;
@PostConstruct
public void init() {
grants = grantService.findAllActiveByCurrentUser();
}
public List<Grant> getGrants() {
return grants;
}
public void create() {
grantService.createByTitle(newGrantTitle);
FacesUtil.showInfoMessage("Статья создана", newGrantTitle);
newGrantTitle = "";
grants = grantService.findAllActiveByCurrentUser();
}
public void deleteSelected() {
grantService.delete(selectedGrants);
grants = grantService.findAllActiveByCurrentUser();
FacesUtil.showInfoMessage("Было удалено грантов: " + selectedGrants.size(), "");
}
public List<Grant.GrantStatus> getGrantStatuses() {
return Arrays.asList(Grant.GrantStatus.values());
}
public String getNewGrantTitle() {
return newGrantTitle;
}
public void setNewGrantTitle(String newGrantTitle) {
this.newGrantTitle = newGrantTitle;
}
public List<Grant> getSelectedGrants() {
return selectedGrants;
}
public void setSelectedGrants(List<Grant> selectedGrants) {
this.selectedGrants = selectedGrants;
}
public String getCurrentUser() {
return userService.getCurrentUser().getUserAbbreviate();
}
}

View File

@ -0,0 +1,21 @@
package ru.ulstu.grant.controller;
import ru.ulstu.grant.model.Grant;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
@FacesConverter(value = "grantStatusConverter")
public class GrantStatusConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return Grant.GrantStatus.valueOf(value);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return value == null ? "" : ((Grant.GrantStatus) value).name();
}
}

View File

@ -0,0 +1,94 @@
package ru.ulstu.grant.controller;
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.grant.model.Grant;
import ru.ulstu.grant.service.GrantService;
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.Arrays;
import java.util.Date;
import java.util.List;
@Named
@ViewScoped
public class GrantView implements Serializable {
@Inject
private GrantService grantService;
@Inject
private DeadlineService deadlineService;
@Inject
private UserService userService;
private Grant grant;
private Date newDeadlineDate;
private String newDeadlineDescription;
@PostConstruct
public void init() {
grant = grantService.findById(Integer.valueOf(FacesUtil.getRequestParams().get("id")));
newDeadlineDescription = "";
newDeadlineDate = new Date();
FacesUtil.showInfoMessage("Статья открыта", "");
}
public Grant getGrant() {
return grant;
}
public void setGrant(Grant grant) {
this.grant = grant;
}
public List<Grant.GrantStatus> getGrantStatuses() {
return Arrays.asList(Grant.GrantStatus.values());
}
public List<User> getAuthors() {
return userService.findAll();
}
public String save() {
grantService.save(grant);
FacesUtil.showInfoMessage("Грант сохранен", "");
return Page.GRANT_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) {
grant.getDeadlines().remove(deadline);
}
public void addDeadline() {
grant.getDeadlines().add(deadlineService.create(newDeadlineDescription, newDeadlineDate));
newDeadlineDescription = "";
newDeadlineDate = new Date();
}
}

View File

@ -0,0 +1,68 @@
package ru.ulstu.grant.controller;
import ru.ulstu.core.util.FacesUtil;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.grant.service.GrantService;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Named
@ViewScoped
public class GrantsView {
@Inject
private GrantService grantService;
private List<Grant> grants;
private List<Grant> selectedGrants = new ArrayList<>();
private String newGrantTitle;
@PostConstruct
public void init() {
grants = grantService.findAll();
}
public void create() {
grantService.createByTitle(newGrantTitle);
FacesUtil.showInfoMessage("Статья создана", newGrantTitle);
newGrantTitle = "";
grants = grantService.findAll();
}
public void deleteSelected() {
grantService.delete(selectedGrants);
grants = grantService.findAll();
FacesUtil.showInfoMessage("Было удалено грантов: " + selectedGrants.size(), "");
}
public List<Grant.GrantStatus> getGrantStatuses() {
return Arrays.asList(Grant.GrantStatus.values());
}
public List<Grant> getGrants() {
return grants;
}
public String getNewGrantTitle() {
return newGrantTitle;
}
public void setNewGrantTitle(String newGrantTitle) {
this.newGrantTitle = newGrantTitle;
}
public List<Grant> getSelectedGrants() {
return selectedGrants;
}
public void setSelectedGrants(List<Grant> selectedGrants) {
this.selectedGrants = selectedGrants;
}
}

View File

@ -41,24 +41,30 @@ import java.util.Set;
@DiscriminatorValue("GRANT") @DiscriminatorValue("GRANT")
public class Grant extends BaseEntity implements UserActivity, EventSource { public class Grant extends BaseEntity implements UserActivity, EventSource {
public enum GrantStatus { public enum GrantStatus {
APPLICATION("Заявка"), APPLICATION("Заявка", "text-draft"),
ON_COMPETITION("Отправлен на конкурс"), ON_COMPETITION("Отправлен на конкурс", "text-review"),
SUCCESSFUL_PASSAGE("Успешное прохождение"), SUCCESSFUL_PASSAGE("Успешное прохождение", "text-accepted"),
IN_WORK("В работе"), IN_WORK("В работе", "text-primary"),
COMPLETED("Завершен"), COMPLETED("Завершен", "text-success"),
FAILED("Провалены сроки"), FAILED("Провалены сроки", "text-failed"),
LOADED_FROM_KIAS("Загружен автоматически"), LOADED_FROM_KIAS("Загружен автоматически", "text-warning"),
SKIPPED("Не интересует"); SKIPPED("Не интересует", "text-not-accepted");
private final String statusName; private final String statusName;
private final String elementClass;
GrantStatus(String statusName) { GrantStatus(String statusName, String elementClass) {
this.statusName = statusName; this.statusName = statusName;
this.elementClass = elementClass;
} }
public String getStatusName() { public String getStatusName() {
return statusName; return statusName;
} }
public String getElementClass() {
return elementClass;
}
} }
@NotBlank @NotBlank

View File

@ -1,12 +1,17 @@
package ru.ulstu.grant.page; package ru.ulstu.grant.page;
//import com.gargoylesoftware.htmlunit.html.DomNode; import com.gargoylesoftware.htmlunit.html.DomNode;
//import com.gargoylesoftware.htmlunit.html.HtmlElement; import com.gargoylesoftware.htmlunit.html.HtmlElement;
//import com.gargoylesoftware.htmlunit.html.HtmlPage; import com.gargoylesoftware.htmlunit.html.HtmlPage;
//import com.gargoylesoftware.htmlunit.html.HtmlTableRow; import com.gargoylesoftware.htmlunit.html.HtmlTableRow;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class KiasPage { public class KiasPage {
/* private final static String KIAS_GRANT_DATE_FORMAT = "dd.MM.yyyy HH:mm"; private final static String KIAS_GRANT_DATE_FORMAT = "dd.MM.yyyy HH:mm";
private final HtmlPage page; private final HtmlPage page;
public KiasPage(HtmlPage page) { public KiasPage(HtmlPage page) {
@ -46,5 +51,5 @@ public class KiasPage {
public boolean isTableRowGrantLine(DomNode grantElement) { public boolean isTableRowGrantLine(DomNode grantElement) {
return !((HtmlTableRow) grantElement).getAttribute("class").contains("pagerSavedHeightSpacer"); return !((HtmlTableRow) grantElement).getAttribute("class").contains("pagerSavedHeightSpacer");
}*/ }
} }

View File

@ -27,6 +27,7 @@ import ru.ulstu.user.service.UserService;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException; import java.text.ParseException;
import java.time.temporal.ChronoUnit;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
@ -313,13 +314,13 @@ public class GrantService extends BaseService {
@Transactional @Transactional
public void createFromKias() throws IOException, ParseException { public void createFromKias() throws IOException, ParseException {
/* for (GrantDto grantDto : kiasService.getNewGrantsDto()) { for (GrantDto grantDto : kiasService.getNewGrantsDto()) {
if (saveFromKias(grantDto)) { if (saveFromKias(grantDto)) {
log.debug("GrantScheduler.loadGrantsFromKias new grant was loaded"); log.debug("GrantScheduler.loadGrantsFromKias new grant was loaded");
} else { } else {
log.debug("GrantScheduler.loadGrantsFromKias grant wasn't loaded, cause it's already exists"); log.debug("GrantScheduler.loadGrantsFromKias grant wasn't loaded, cause it's already exists");
} }
}*/ }
} }
public List<GrantDto> findAllActiveDto() { public List<GrantDto> findAllActiveDto() {
@ -338,4 +339,65 @@ public class GrantService extends BaseService {
public void ping(int grantId) throws IOException { public void ping(int grantId) throws IOException {
pingService.addPing(findById(grantId)); pingService.addPing(findById(grantId));
} }
public void save(Grant grant) {
if (isEmpty(grant.getId())) {
create(grant);
} else {
update(grant);
}
}
@Transactional
public Grant create(Grant grant) {
Grant newGrant = grantRepository.save(grant);
grantNotificationService.sendCreateNotification(newGrant);
return newGrant;
}
@Transactional
public Integer update(Grant newGrant) {
Grant oldGrant = grantRepository.getOne(newGrant.getId());
Grant.GrantStatus oldStatus = oldGrant.getStatus();
Set<User> oldAuthors = new HashSet<>(oldGrant.getAuthors());
newGrant = grantRepository.save(newGrant);
for (User author : newGrant.getAuthors()) {
if (!oldAuthors.contains(author)) {
grantNotificationService.sendCreateNotification(newGrant);
}
}
if (newGrant.getStatus() != oldStatus) {
//grantNotificationService.statusChangeNotification(newPaper, oldStatus);
}
return newGrant.getId();
}
public void createByTitle(String newGrantTitle) {
Grant grant = new Grant();
grant.setTitle(newGrantTitle);
grant.setStatus(APPLICATION);
grant.getAuthors().add(userService.getCurrentUser());
grant.setLeader(userService.getCurrentUser());
grant.getDeadlines().add(deadlineService.createWithOffset(new Date(), 1, ChronoUnit.WEEKS));
create(grant);
}
public List<Grant> findAllActiveByCurrentUser() {
return findAllActive()
.stream()
.filter(grant -> grant.getAuthors().contains(userService.getCurrentUser()) ||
grant.getLeader().equals(userService.getCurrentUser()))
.collect(toList());
}
public void delete(List<Grant> grants) {
grants.forEach(grant -> delete(grant));
}
public void delete(Grant grant) {
deadlineService.delete(grant.getDeadlines());
grantRepository.delete(grant);
}
} }

View File

@ -1,14 +1,24 @@
package ru.ulstu.grant.service; package ru.ulstu.grant.service;
//import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.WebClient;
//mport com.gargoylesoftware.htmlunit.html.DomNode; import com.gargoylesoftware.htmlunit.html.DomNode;
//import com.gargoylesoftware.htmlunit.html.HtmlPage; import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.ulstu.configuration.ApplicationProperties;
import ru.ulstu.grant.model.GrantDto;
import ru.ulstu.grant.page.KiasPage;
import ru.ulstu.user.service.UserService;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
@Service @Service
public class KiasService { public class KiasService {
/* private final static String BASE_URL = "https://www.rfbr.ru/rffi/ru/contest_search?CONTEST_STATUS_ID=%s&CONTEST_TYPE=%s&CONTEST_YEAR=%s"; private final static String BASE_URL = "https://www.rfbr.ru/rffi/ru/contest_search?CONTEST_STATUS_ID=%s&CONTEST_TYPE=%s&CONTEST_YEAR=%s";
private final static String CONTEST_STATUS_ID = "1"; private final static String CONTEST_STATUS_ID = "1";
private final static String CONTEST_TYPE = "-1"; private final static String CONTEST_TYPE = "-1";
@ -59,5 +69,5 @@ public class KiasService {
private List<Integer> generateGrantYears() { private List<Integer> generateGrantYears() {
return Arrays.asList(Calendar.getInstance().get(Calendar.YEAR), return Arrays.asList(Calendar.getInstance().get(Calendar.YEAR),
Calendar.getInstance().get(Calendar.YEAR) + 1); Calendar.getInstance().get(Calendar.YEAR) + 1);
}*/ }
} }

View File

@ -15,7 +15,7 @@ import java.util.List;
@Named @Named
@ViewScoped @ViewScoped
public class DashboardView { public class PaperDashboardView {
@Inject @Inject
private PaperService paperService; private PaperService paperService;

View File

@ -25,15 +25,19 @@
<div class="ui-g-12 ui-md-2"></div> <div class="ui-g-12 ui-md-2"></div>
<div class="ui-g-12 ui-md-8"> <div class="ui-g-12 ui-md-8">
<p:menubar> <p:menubar>
<p:menuitem class="navbar-brand" value="NG-Tracker" url="#{page.INDEX}"/> <p:menuitem class="navbar-brand" value="NG-Tracker" url="#{page.index}"/>
<p:submenu label="Статьи" icon="fa fa-file-text-o"> <p:submenu label="Статьи" icon="fa fa-file-text-o">
<p:menuitem value="Мои статьи" icon="fa fa-calendar" url="#{page.DASHBOARD}"/> <p:menuitem value="Мои статьи" icon="fa fa-calendar" url="#{page.paperDashboard}"/>
<p:menuitem value="Все статьи" icon="fa fa-file-o" url="#{page.PAPER_LIST}"/> <p:menuitem value="Все статьи" icon="fa fa-file-o" url="#{page.paperList}"/>
</p:submenu> </p:submenu>
<p:menuitem value="Пользователи" icon="fa fa-calendar" url="#{page.USER_LIST}"/> <p:submenu label="Гранты" icon="fa fa-file-text-o">
<p:menuitem value="Мои гранты" icon="fa fa-calendar" url="#{page.grantDashboard}"/>
<p:menuitem value="Все гранты" icon="fa fa-file-o" url="#{page.grantList}"/>
</p:submenu>
<p:menuitem value="Пользователи" icon="fa fa-calendar" url="#{page.userList}"/>
<f:facet name="options"> <f:facet name="options">
<p:link href="#{page.LOGOUT}" value="Выход"/> <p:link href="#{page.logout}" value="Выход"/>
</f:facet> </f:facet>
</p:menubar> </p:menubar>
<div class="ui-fluid"> <div class="ui-fluid">

View File

@ -13,7 +13,7 @@
<div class="ui-g-2"></div> <div class="ui-g-2"></div>
<div class="ui-g-8"> <div class="ui-g-8">
<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 id="toggleable" header="Подробности" toggleable="true" toggleSpeed="500" closeSpeed="500" <p:panel id="toggleable" header="Подробности" toggleable="true" toggleSpeed="500" closeSpeed="500"

View File

@ -0,0 +1,91 @@
<!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="Активные гранты пользователя #{grantDashboardView.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="newGrantName"
value="#{grantDashboardView.newGrantTitle}" required="true"
requiredMessage="Введите название нового гранта"/>
<p:message for="newGrantName"/>
</div>
<div class="ui-md-2 ui-g-12">
<p:commandButton action="#{grantDashboardView.create}" value="Создать" ajax="true"
process="@form"
update="messages @form mainForm:grantsTable"/>
</div>
<div class="ui-md-3 ui-g-12">
<p:commandButton value="Удалить выделенные" id="grantsRemoveButton"
disabled="#{grantDashboardView.selectedGrants.isEmpty()}"
action="#{grantDashboardView.deleteSelected}" ajax="true"
process="mainForm:grantsRemoveButton"
update="messages mainForm:grantsTable">
<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="#{grantDashboardView.grants}" var="grant" paginator="true"
paginatorPosition="bottom"
rows="10" id="grantsTable"
widgetVar="grantsTable" emptyMessage="Не найдено подходящих статей"
selection="#{grantDashboardView.selectedGrants}" rowKey="#{grant.id}">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Поиск:"/>
<p:inputText id="globalFilter" onkeyup="PF('grantsTable').filter()" style="width:150px"
placeholder="Строка поиска..."/>
</p:outputPanel>
</f:facet>
<p:ajax event="rowSelect" update="mainForm:grantsRemoveButton" process="mainForm:grantsTable"/>
<p:ajax event="rowSelectCheckbox" update="mainForm:grantsRemoveButton"
process="mainForm:grantsTable"/>
<p:ajax event="rowUnselectCheckbox" update="mainForm:grantsRemoveButton"
process="mainForm:grantsTable"/>
<p:ajax event="rowUnselect" update="mainForm:grantsRemoveButton" process="mainForm:grantsTable"/>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Название" filterBy="#{grant.title}" filterMatchMode="contains">
<h:outputLink value="#{page.grant}">
#{grant.title}
<f:param name="id" value="#{grant.id}"/>
</h:outputLink>
</p:column>
<p:column headerText="Статус" filterBy="#{grant.status} #{grant.status.statusName}"
filterMatchMode="contains">
<f:facet name="filter">
<p:selectOneMenu onchange="PF('grantsTable').filter()" styleClass="custom-filter"
converter="grantStatusConverter">
<f:selectItem itemLabel="Статус" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{grantDashboardView.grantStatuses}" var="status"
itemLabel="#{status.statusName}"
itemValue="#{status}"/>
</p:selectOneMenu>
</f:facet>
<ui:include src="grantStatusFragment.xhtml">
<ui:param name="grant" value="#{grant}"/>
</ui:include>
</p:column>
</p:dataTable>
</div>
</p:panel>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,142 @@
<!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://java.sun.com/jsf/core"
>
<ui:composition template="/basicTemplate.xhtml">
<ui:define name="header">
Редактирование гранта
</ui:define>
<ui:define name="content">
<style>
#mainForm\:grantStatus > tbody > tr {
border: none;
}
#mainForm\:grantStatus > tbody > tr > td {
border: none;
padding: 0px;
}
#mainForm\:grantPanel > tbody > tr {
border: none;
}
#mainForm\:grantPanel > tbody > tr > td {
border: none;
}
.ui-editor.ui-widget-content {
background: white !important;
}
</style>
<p:panel id="panel" header="Редактирование гранта: #{grantView.grant.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="#{grantView.grant.title}"/>
<p:message for="name"/>
</div>
<div class="ui-md-2 ui-g-12">
</div>
<div class="ui-md-3 ui-g-12">
<p:outputLabel for="grantStatus" value="Статус:"/>
</div>
<div class="ui-md-7 ui-g-12">
<p:panelGrid columns="2" id="grantStatus">
<p:selectOneMenu id="status" required="true" value="#{grantView.grant.status}"
converter="grantStatusConverter">
<p:ajax update="mainForm:grantStatus" process="@this"/>
<f:selectItems value="#{grantView.grantStatuses}"
var="status"
itemLabel="#{status.statusName}"
itemValue="#{status}"/>
</p:selectOneMenu>
<ui:include src="grantStatusFragment.xhtml">
<ui:param name="grant" value="#{grantView.grant}"/>
<ui:param name="shortMode" value="true"/>
</ui:include>
</p:panelGrid>
</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="#{grantView.grant.authors}" multiple="true"
converter="#{userConverter}">
<f:attribute name="collectionType" value="java.util.HashSet"/>
<f:selectItems value="#{grantView.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="#{grantView.grant.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="#{grantView.deleteDeadline(deadline)}"/>
</p:commandButton>
</div>
</ui:repeat>
<div class="ui-md-5 ui-g-12">
<p:datePicker value="#{grantView.newDeadlineDate}" placeholder="Введите дату"
pattern="dd.MM.yyyy"/>
</div>
<div class="ui-md-5 ui-g-12">
<p:inputText value="#{grantView.newDeadlineDescription}"
placeholder="Описание ключевой даты"/>
</div>
<div class="ui-md-1 ui-g-12">
<p:commandButton icon="pi pi-check">
<p:ajax update="mainForm" process="@this"
listener="#{grantView.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="#{grantView.grant.comment}" 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="#{grantView.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="#{grant.status.statusName}">
<i class="fa fa-circle #{grant.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="#{grant.status.statusName}"/>
</ui:fragment>
</ui:composition>

View File

@ -0,0 +1,88 @@
<!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="newGrantName"
value="#{grantsView.newGrantTitle}" required="true"
requiredMessage="Введите название нового гранта"/>
<p:message for="newGrantName"/>
</div>
<div class="ui-md-2 ui-g-12">
<p:commandButton action="#{grantsView.create}" value="Создать" ajax="true" process="@form"
update="messages @form mainForm:grantsTable"/>
</div>
<div class="ui-md-3 ui-g-12">
<p:commandButton value="Удалить выделенные" id="grantsRemoveButton"
disabled="#{grantsView.selectedGrants.isEmpty()}"
action="#{grantsView.deleteSelected}" ajax="true"
process="mainForm:grantsRemoveButton"
update="messages mainForm:grantsTable">
<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="#{grantsView.grants}" var="grant" paginator="true" paginatorPosition="bottom"
rows="10" id="grantsTable"
widgetVar="grantsTable" emptyMessage="Не найдено подходящих грантов"
selection="#{grantsView.selectedGrants}" rowKey="#{grant.id}">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Поиск:"/>
<p:inputText id="globalFilter" onkeyup="PF('grantsTable').filter()" style="width:150px"
placeholder="Строка поиска..."/>
</p:outputPanel>
</f:facet>
<p:ajax event="rowSelect" update="mainForm:grantsRemoveButton" process="mainForm:grantsTable"/>
<p:ajax event="rowSelectCheckbox" update="mainForm:grantsRemoveButton"
process="mainForm:grantsTable"/>
<p:ajax event="rowUnselectCheckbox" update="mainForm:grantsRemoveButton"
process="mainForm:grantsTable"/>
<p:ajax event="rowUnselect" update="mainForm:grantsRemoveButton" process="mainForm:grantsTable"/>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Название" filterBy="#{grant.title}" filterMatchMode="contains">
<h:outputLink value="#{page.grant}">
#{grant.title}
<f:param name="id" value="#{grant.id}"/>
</h:outputLink>
</p:column>
<p:column headerText="Статус" filterBy="#{grant.status} #{grant.status.statusName}"
filterMatchMode="contains">
<f:facet name="filter">
<p:selectOneMenu onchange="PF('grantsTable').filter()" styleClass="custom-filter"
converter="grantStatusConverter">
<f:selectItem itemLabel="Статус" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{grantsView.grantStatuses}" var="status"
itemLabel="#{status.statusName}"
itemValue="#{status}"/>
</p:selectOneMenu>
</f:facet>
<ui:include src="grantStatusFragment.xhtml">
<ui:param name="grant" value="#{grant}"/>
</ui:include>
</p:column>
</p:dataTable>
</div>
</p:panel>
</ui:define>
</ui:composition>
</html>

View File

@ -10,26 +10,27 @@
text-align: right !important; text-align: right !important;
} }
</style> </style>
<p:panel id="panel" header="Активные статьи пользователя #{dashboardView.currentUser}" <p:panel id="panel" header="Активные статьи пользователя #{paperDashboardView.currentUser}"
style="margin-bottom:10px;"> style="margin-bottom:10px;">
<div class="ui-fluid"> <div class="ui-fluid">
<div class="ui-g"> <div class="ui-g">
<div class="ui-md-5 ui-g-12"> <div class="ui-md-5 ui-g-12">
<p:inputText placeholder="Создать новую статью" id="newPaperName" <p:inputText placeholder="Создать новую статью" id="newPaperName"
value="#{dashboardView.newPaperTitle}" required="true" value="#{paperDashboardView.newPaperTitle}" required="true"
requiredMessage="Введите название новой статьи"/> requiredMessage="Введите название новой статьи"/>
<p:message for="newPaperName"/> <p:message for="newPaperName"/>
</div> </div>
<div class="ui-md-2 ui-g-12"> <div class="ui-md-2 ui-g-12">
<p:commandButton action="#{dashboardView.create}" value="Создать" ajax="true" process="@form" <p:commandButton action="#{paperDashboardView.create}" value="Создать" ajax="true"
process="@form"
update="messages @form mainForm:papersTable"/> update="messages @form mainForm:papersTable"/>
</div> </div>
<div class="ui-md-3 ui-g-12"> <div class="ui-md-3 ui-g-12">
<p:commandButton value="Удалить выделенные" id="papersRemoveButton" <p:commandButton value="Удалить выделенные" id="papersRemoveButton"
disabled="#{dashboardView.selectedPapers.isEmpty()}" disabled="#{paperDashboardView.selectedPapers.isEmpty()}"
action="#{dashboardView.deleteSelected}" ajax="true" action="#{paperDashboardView.deleteSelected}" ajax="true"
process="mainForm:papersRemoveButton" process="mainForm:papersRemoveButton"
update="messages mainForm:papersTable"> update="messages mainForm:papersTable">
<p:confirm header="Подтверждение" message="Удалить выделенные статьи?" <p:confirm header="Подтверждение" message="Удалить выделенные статьи?"
@ -42,10 +43,11 @@
</p:confirmDialog> </p:confirmDialog>
</div> </div>
<p:dataTable value="#{dashboardView.papers}" var="paper" paginator="true" paginatorPosition="bottom" <p:dataTable value="#{paperDashboardView.papers}" var="paper" paginator="true"
paginatorPosition="bottom"
rows="10" id="papersTable" rows="10" id="papersTable"
widgetVar="papersTable" emptyMessage="Не найдено подходящих статей" widgetVar="papersTable" emptyMessage="Не найдено подходящих статей"
selection="#{dashboardView.selectedPapers}" rowKey="#{paper.id}"> selection="#{paperDashboardView.selectedPapers}" rowKey="#{paper.id}">
<f:facet name="header"> <f:facet name="header">
<p:outputPanel> <p:outputPanel>
<h:outputText value="Поиск:"/> <h:outputText value="Поиск:"/>
@ -61,7 +63,7 @@
<p:ajax event="rowUnselect" update="mainForm:papersRemoveButton" process="mainForm:papersTable"/> <p:ajax event="rowUnselect" update="mainForm:papersRemoveButton" process="mainForm:papersTable"/>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/> <p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Название" filterBy="#{paper.title}" filterMatchMode="contains"> <p:column headerText="Название" filterBy="#{paper.title}" filterMatchMode="contains">
<h:outputLink value="/paper/paper.xhtml"> <h:outputLink value="#{page.paper}">
#{paper.title} #{paper.title}
<f:param name="id" value="#{paper.id}"/> <f:param name="id" value="#{paper.id}"/>
</h:outputLink> </h:outputLink>
@ -72,7 +74,7 @@
<p:selectOneMenu onchange="PF('papersTable').filter()" styleClass="custom-filter" <p:selectOneMenu onchange="PF('papersTable').filter()" styleClass="custom-filter"
converter="paperStatusConverter"> converter="paperStatusConverter">
<f:selectItem itemLabel="Статус" itemValue="#{null}" noSelectionOption="true"/> <f:selectItem itemLabel="Статус" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{dashboardView.paperStatuses}" var="status" <f:selectItems value="#{paperDashboardView.paperStatuses}" var="status"
itemLabel="#{status.statusName}" itemLabel="#{status.statusName}"
itemValue="#{status}"/> itemValue="#{status}"/>
</p:selectOneMenu> </p:selectOneMenu>

View File

@ -60,7 +60,7 @@
<p:ajax event="rowUnselect" update="mainForm:papersRemoveButton" process="mainForm:papersTable"/> <p:ajax event="rowUnselect" update="mainForm:papersRemoveButton" process="mainForm:papersTable"/>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/> <p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Название" filterBy="#{paper.title}" filterMatchMode="contains"> <p:column headerText="Название" filterBy="#{paper.title}" filterMatchMode="contains">
<h:outputLink value="/paper/paper.xhtml"> <h:outputLink value="#{page.paper}">
#{paper.title} #{paper.title}
<f:param name="id" value="#{paper.id}"/> <f:param name="id" value="#{paper.id}"/>
</h:outputLink> </h:outputLink>