#247 -- Restore mvc

This commit is contained in:
Anton Romanov 2024-03-27 10:14:42 +04:00
parent 5371df1f50
commit 55a76daa5a
73 changed files with 248 additions and 2905 deletions

View File

@ -112,6 +112,12 @@ dependencies {
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'
compile group: 'org.webjars', name: 'bootstrap', version: '4.1.0'
compile group: 'org.webjars', name: 'bootstrap-select', version: '1.13.3'
compile group: 'org.webjars', name: 'jquery', version: '3.3.1-1'
compile group: 'org.webjars.npm', name: 'jquery.easing', version: '1.4.1'
compile group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
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'

View File

@ -1,29 +0,0 @@
package ru.ulstu.conference.controller;
import org.springframework.stereotype.Service;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.conference.service.ConferenceService;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.inject.Inject;
@Service
public class ConferenceConverter implements Converter {
@Inject
private ConferenceService conferenceService;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return value == null || value.equals("") ? null : conferenceService.findOne(Integer.valueOf(value));
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return value == null
? ""
: (value.getClass().equals(Conference.class) ? ((Conference) value).getId().toString() : null);
}
}

View File

@ -1,71 +0,0 @@
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

@ -1,89 +0,0 @@
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

@ -1,63 +0,0 @@
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

@ -14,7 +14,7 @@ public class Constants {
public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$"; public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$";
public static final String COOKIES_NAME = "JSESSIONID"; public static final String COOKIES_NAME = "JSESSIONID";
public static final String LOGOUT_URL = "/login.xhtml"; public static final String LOGOUT_URL = "/login?logout";
public static final String SESSION_ID_ATTR = "sessionId"; public static final String SESSION_ID_ATTR = "sessionId";
public static final int SESSION_TIMEOUT_SECONDS = 30 * 60; public static final int SESSION_TIMEOUT_SECONDS = 30 * 60;

View File

@ -1,10 +1,7 @@
package ru.ulstu.configuration; package ru.ulstu.configuration;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -12,14 +9,20 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
public class MvcConfiguration implements WebMvcConfigurer { public class MvcConfiguration implements WebMvcConfigurer {
@Override @Override
public void addViewControllers(ViewControllerRegistry registry) { public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/", "/index.xhtml"); registry.addViewController("/{articlename:\\w+}");
registry.addViewController("/admin/{articlename:\\w+}");
registry.addViewController("/papers/{articlename:\\w+}");
registry.addViewController("/grants/{articlename:\\w+}");
registry.addViewController("/conferences/{articlename:\\w+}");
registry.addViewController("/students/{articlename:\\w+}");
registry.addRedirectViewController("/", "/index");
registry.addRedirectViewController("/default", "/index");
} }
@Bean @Override
public ErrorPageRegistrar errorPageRegistrar() { public void addResourceHandlers(ResourceHandlerRegistry registry) {
return registry -> { registry
registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404.xhtml")); .addResourceHandler("/webjars/**")
registry.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500.xhtml")); .addResourceLocations("/webjars/");
};
} }
} }

View File

@ -29,7 +29,7 @@ import org.springframework.security.web.authentication.AuthenticationFailureHand
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import ru.ulstu.core.model.AuthFailureHandler; import ru.ulstu.core.model.AuthFailureHandler;
import ru.ulstu.core.navigation.Page; import ru.ulstu.user.controller.UserController;
import ru.ulstu.user.model.UserRoleConstants; import ru.ulstu.user.model.UserRoleConstants;
import ru.ulstu.user.service.UserService; import ru.ulstu.user.service.UserService;
@ -87,35 +87,29 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.principal("admin") .principal("admin")
.authorities(UserRoleConstants.ADMIN); .authorities(UserRoleConstants.ADMIN);
} else { } else {
log.debug("Security enabled");
http.authorizeRequests() http.authorizeRequests()
.antMatchers("/login.xhtml", "/logout") .antMatchers(UserController.ACTIVATE_URL).permitAll()
.permitAll() .antMatchers(Constants.PASSWORD_RESET_REQUEST_PAGE).permitAll()
.anyRequest() .antMatchers(Constants.PASSWORD_RESET_PAGE).permitAll()
.authenticated() .antMatchers("/users/block").permitAll()
.antMatchers(UserController.URL + UserController.REGISTER_URL).permitAll()
.antMatchers(UserController.URL + UserController.ACTIVATE_URL).permitAll()
.antMatchers(UserController.URL + UserController.PASSWORD_RESET_REQUEST_URL).permitAll()
.antMatchers(UserController.URL + UserController.PASSWORD_RESET_URL).permitAll()
.antMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN) .antMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN)
.anyRequest().authenticated()
.and() .and()
.formLogin() .formLogin()
.loginPage("/login.xhtml") .loginPage("/login")
.successHandler(authenticationSuccessHandler) .successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler) .failureHandler(authenticationFailureHandler)
.permitAll() .permitAll()
.and() .and()
.oauth2Login()
.loginPage("/login.xhtml")
.authorizationEndpoint()
.baseUri("/oauth2/authorize-client")
.authorizationRequestRepository(authorizationRequestRepository())
.and()
.tokenEndpoint()
.accessTokenResponseClient(accessTokenResponseClient())
.and()
.defaultSuccessUrl(Page.INDEX)
.failureUrl("/loginFailure")
.and()
.logout() .logout()
.logoutSuccessHandler(logoutSuccessHandler) .logoutSuccessHandler(logoutSuccessHandler)
.logoutSuccessUrl(Page.LOGOUT) .logoutSuccessUrl(Constants.LOGOUT_URL)
.invalidateHttpSession(true) .invalidateHttpSession(false)
.clearAuthentication(true) .clearAuthentication(true)
.deleteCookies(Constants.COOKIES_NAME) .deleteCookies(Constants.COOKIES_NAME)
.permitAll(); .permitAll();

View File

@ -0,0 +1,115 @@
package ru.ulstu.core.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import ru.ulstu.core.error.EntityIdIsNullException;
import ru.ulstu.core.model.ErrorConstants;
import ru.ulstu.core.model.response.Response;
import ru.ulstu.core.model.response.ResponseExtended;
import ru.ulstu.user.error.UserActivationError;
import ru.ulstu.user.error.UserEmailExistsException;
import ru.ulstu.user.error.UserIdExistsException;
import ru.ulstu.user.error.UserIsUndeadException;
import ru.ulstu.user.error.UserLoginExistsException;
import ru.ulstu.user.error.UserNotActivatedException;
import ru.ulstu.user.error.UserNotFoundException;
import ru.ulstu.user.error.UserPasswordsNotValidOrNotMatchException;
import ru.ulstu.user.error.UserResetKeyError;
import ru.ulstu.user.error.UserSendingMailException;
import ru.ulstu.user.service.UserService;
import java.util.Set;
import java.util.stream.Collectors;
//@ControllerAdvice
public class AdviceController {
private final Logger log = LoggerFactory.getLogger(AdviceController.class);
private final UserService userService;
public AdviceController(UserService userService) {
this.userService = userService;
}
@ModelAttribute("flashMessage")
public String getFlashMessage() {
return null;
}
private Response<Void> handleException(ErrorConstants error) {
log.warn(error.toString());
return new Response<>(error);
}
private <E> ResponseExtended<E> handleException(ErrorConstants error, E errorData) {
log.warn(error.toString());
return new ResponseExtended<>(error, errorData);
}
@ExceptionHandler(EntityIdIsNullException.class)
public Response<Void> handleEntityIdIsNullException(Throwable e) {
return handleException(ErrorConstants.ID_IS_NULL);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseExtended<Set<String>> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
final Set<String> errors = e.getBindingResult().getAllErrors().stream()
.filter(error -> error instanceof FieldError)
.map(error -> ((FieldError) error).getField())
.collect(Collectors.toSet());
return handleException(ErrorConstants.VALIDATION_ERROR, errors);
}
@ExceptionHandler(UserIdExistsException.class)
public Response<Void> handleUserIdExistsException(Throwable e) {
return handleException(ErrorConstants.USER_ID_EXISTS);
}
@ExceptionHandler(UserActivationError.class)
public ResponseExtended<String> handleUserActivationError(Throwable e) {
return handleException(ErrorConstants.USER_ACTIVATION_ERROR, e.getMessage());
}
@ExceptionHandler(UserLoginExistsException.class)
public ResponseExtended<String> handleUserLoginExistsException(Throwable e) {
return handleException(ErrorConstants.USER_LOGIN_EXISTS, e.getMessage());
}
@ExceptionHandler(UserEmailExistsException.class)
public ResponseExtended<String> handleUserEmailExistsException(Throwable e) {
return handleException(ErrorConstants.USER_EMAIL_EXISTS, e.getMessage());
}
@ExceptionHandler(UserPasswordsNotValidOrNotMatchException.class)
public Response<Void> handleUserPasswordsNotValidOrNotMatchException(Throwable e) {
return handleException(ErrorConstants.USER_PASSWORDS_NOT_VALID_OR_NOT_MATCH);
}
@ExceptionHandler(UserNotFoundException.class)
public ResponseExtended<String> handleUserNotFoundException(Throwable e) {
return handleException(ErrorConstants.USER_NOT_FOUND, e.getMessage());
}
@ExceptionHandler(UserNotActivatedException.class)
public Response<Void> handleUserNotActivatedException(Throwable e) {
return handleException(ErrorConstants.USER_NOT_ACTIVATED);
}
@ExceptionHandler(UserResetKeyError.class)
public ResponseExtended<String> handleUserResetKeyError(Throwable e) {
return handleException(ErrorConstants.USER_RESET_ERROR, e.getMessage());
}
@ExceptionHandler(UserIsUndeadException.class)
public ResponseExtended<String> handleUserIsUndeadException(Throwable e) {
return handleException(ErrorConstants.USER_UNDEAD_ERROR, e.getMessage());
}
@ExceptionHandler(UserSendingMailException.class)
public ResponseExtended<String> handleUserSendingMailException(Throwable e) {
return handleException(ErrorConstants.USER_SENDING_MAIL_EXCEPTION, e.getMessage());
}
}

View File

@ -1,22 +1,19 @@
package ru.ulstu.core.navigation; package ru.ulstu.core.navigation;
import javax.inject.Named;
@Named
public class Page { public class Page {
public static final String INDEX = "/index.xhtml"; public static final String INDEX = "/index.html";
public static final String PAPER = "/paper/paper.xhtml"; public static final String PAPER = "/paper/paper.html";
public static final String PAPER_LIST = "/paper/papers.xhtml"; public static final String PAPER_LIST = "/paper/papers.html";
public static final String PAPER_DASHBOARD = "/paper/dashboard.xhtml"; public static final String PAPER_DASHBOARD = "/paper/dashboard.html";
public static final String GRANT = "/grant/grant.xhtml"; public static final String GRANT = "/grant/grant.html";
public static final String GRANT_LIST = "/grant/grants.xhtml"; public static final String GRANT_LIST = "/grant/grants.html";
public static final String GRANT_DASHBOARD = "/grant/dashboard.xhtml"; public static final String GRANT_DASHBOARD = "/grant/dashboard.html";
public static final String USER_LIST = "/admin/users.xhtml"; public static final String USER_LIST = "/admin/users.html";
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 = "/conference/conference.html";
public static final String CONFERENCE_DASHBOARD = "/conference/dashboard.xhtml"; public static final String CONFERENCE_DASHBOARD = "/conference/dashboard.html";
public static final String CONFERENCE_LIST = "/conference/conferences.xhtml"; public static final String CONFERENCE_LIST = "/conference/conferences.html";
public static final String PROJECT_DASHBOARD = "/conference/dashboard.xhtml"; public static final String PROJECT_DASHBOARD = "/conference/dashboard.html";
public String getIndex() { public String getIndex() {
return INDEX; return INDEX;

View File

@ -1,47 +0,0 @@
package ru.ulstu.core.util;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import java.io.IOException;
import java.util.Map;
public class FacesUtil {
public static void redirectToPage(FacesContext context, String page, String params) {
ExternalContext extContext = context.getExternalContext();
String url = extContext.encodeActionURL(context.getApplication().getViewHandler().getActionURL(context, page)
+ params);
try {
extContext.redirect(url);
} catch (IOException e) {
throw new FacesException(e);
}
}
public static void redirectToPage(String page) {
redirectToPage(FacesContext.getCurrentInstance(), page, "");
}
public static void redirectToPage(String page, String params) {
redirectToPage(FacesContext.getCurrentInstance(), page, params);
}
public static Map<String, String> getRequestParams() {
return FacesContext.getCurrentInstance().
getExternalContext().getRequestParameterMap();
}
public static void showInfoMessage(String summary, String detail) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary, detail);
FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().getFlash().setKeepMessages(true);
fc.addMessage("messages", message);
}
public static void showDangerMessage(String summary, String detail) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, detail);
FacesContext.getCurrentInstance().addMessage(null, message);
}
}

View File

@ -1,76 +0,0 @@
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

@ -1,21 +0,0 @@
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

@ -1,94 +0,0 @@
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

@ -1,68 +0,0 @@
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

@ -0,0 +1,23 @@
package ru.ulstu.index.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import ru.ulstu.core.controller.AdviceController;
import ru.ulstu.user.service.UserService;
import springfox.documentation.annotations.ApiIgnore;
@Controller()
@RequestMapping(value = "/index")
@ApiIgnore
public class IndexController extends AdviceController {
public IndexController(UserService userService) {
super(userService);
}
@GetMapping
public void currentUser(ModelMap modelMap) {
//нужен здесь для добавления параметров на стартовой странице
}
}

View File

@ -1,28 +0,0 @@
package ru.ulstu.index.controller;
import ru.ulstu.core.navigation.Page;
import ru.ulstu.index.model.Section;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.List;
@Named
@ViewScoped
public class IndexView {
private List<Section> sections = new ArrayList<>();
@PostConstruct
public void init() {
sections.add(new Section("Статьи", Page.PAPER_DASHBOARD, "papers.jpg"));
sections.add(new Section("Конференции", Page.CONFERENCE_DASHBOARD, "conf.jpg"));
sections.add(new Section("Гранты", Page.GRANT_DASHBOARD, "grants.jpg"));
sections.add(new Section("Проекты", Page.PROJECT_DASHBOARD, "projects.jpg"));
}
public List<Section> getSections() {
return sections;
}
}

View File

@ -1,76 +0,0 @@
package ru.ulstu.paper.controller;
import ru.ulstu.core.util.FacesUtil;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.service.PaperService;
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 PaperDashboardView {
@Inject
private PaperService paperService;
@Inject
private UserService userService;
private List<Paper> papers;
private List<Paper> selectedPapers = new ArrayList<>();
private String newPaperTitle;
@PostConstruct
public void init() {
papers = paperService.findAllActiveByCurrentUser();
}
public List<Paper> getPapers() {
return papers;
}
public void create() {
paperService.createByTitle(newPaperTitle);
FacesUtil.showInfoMessage("Статья создана", newPaperTitle);
newPaperTitle = "";
papers = paperService.findAllActiveByCurrentUser();
}
public void deleteSelected() {
paperService.delete(selectedPapers);
papers = paperService.findAllActiveByCurrentUser();
FacesUtil.showInfoMessage("Было удалено статей: " + selectedPapers.size(), "");
}
public List<Paper.PaperStatus> getPaperStatuses() {
return Arrays.asList(Paper.PaperStatus.values());
}
public String getNewPaperTitle() {
return newPaperTitle;
}
public void setNewPaperTitle(String newPaperTitle) {
this.newPaperTitle = newPaperTitle;
}
public List<Paper> getSelectedPapers() {
return selectedPapers;
}
public void setSelectedPapers(List<Paper> selectedPapers) {
this.selectedPapers = selectedPapers;
}
public String getCurrentUser() {
return userService.getCurrentUser().getUserAbbreviate();
}
}

View File

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

View File

@ -1,21 +0,0 @@
package ru.ulstu.paper.controller;
import ru.ulstu.paper.model.Paper;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
@FacesConverter(value = "paperTypeConverter")
public class PaperTypeConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return Paper.PaperType.valueOf(value);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return ((Paper.PaperType) value).name();
}
}

View File

@ -1,120 +0,0 @@
package ru.ulstu.paper.controller;
import org.apache.commons.lang3.StringUtils;
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.paper.model.Paper;
import ru.ulstu.paper.service.PaperService;
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 PaperView implements Serializable {
private static final int MAX_CONFERENCE_TITLE_LENGTH = 20;
@Inject
private PaperService paperService;
@Inject
private DeadlineService deadlineService;
@Inject
private UserService userService;
@Inject
private ConferenceService conferenceService;
private Paper paper;
private Date newDeadlineDate;
private String newDeadlineDescription;
@PostConstruct
public void init() {
paper = paperService.findPaperById(Integer.valueOf(FacesUtil.getRequestParams().get("id")));
newDeadlineDescription = "";
newDeadlineDate = new Date();
FacesUtil.showInfoMessage("Статья открыта", "");
}
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public List<Paper.PaperStatus> getPaperStatuses() {
return Arrays.asList(Paper.PaperStatus.values());
}
public List<Paper.PaperType> getPaperTypes() {
return Arrays.asList(Paper.PaperType.values());
}
public List<User> getAuthors() {
return userService.findAll();
}
public String save() {
paperService.save(paper);
FacesUtil.showInfoMessage("Статья сохранена", "");
return Page.PAPER_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) {
paper.getDeadlines().remove(deadline);
}
public void addDeadline() {
paper.getDeadlines().add(deadlineService.create(newDeadlineDescription, newDeadlineDate));
newDeadlineDescription = "";
newDeadlineDate = new Date();
}
public List<Conference> getConferences() {
return conferenceService.findAllActive();
}
public String getConferenceTitle(Conference conference) {
if (conference == null) {
return null;
}
if (conference.getTitle().length() > MAX_CONFERENCE_TITLE_LENGTH) {
return StringUtils.truncate(conference.getTitle(), MAX_CONFERENCE_TITLE_LENGTH) + "...";
}
return conference.getTitle();
}
}

View File

@ -1,68 +0,0 @@
package ru.ulstu.paper.controller;
import ru.ulstu.core.util.FacesUtil;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.service.PaperService;
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 PapersView {
@Inject
private PaperService paperService;
private List<Paper> papers;
private List<Paper> selectedPapers = new ArrayList<>();
private String newPaperTitle;
@PostConstruct
public void init() {
papers = paperService.findAll();
}
public void create() {
paperService.createByTitle(newPaperTitle);
FacesUtil.showInfoMessage("Статья создана", newPaperTitle);
newPaperTitle = "";
papers = paperService.findAll();
}
public void deleteSelected() {
paperService.delete(selectedPapers);
papers = paperService.findAll();
FacesUtil.showInfoMessage("Было удалено статей: " + selectedPapers.size(), "");
}
public List<Paper.PaperStatus> getPaperStatuses() {
return Arrays.asList(Paper.PaperStatus.values());
}
public List<Paper> getPapers() {
return papers;
}
public String getNewPaperTitle() {
return newPaperTitle;
}
public void setNewPaperTitle(String newPaperTitle) {
this.newPaperTitle = newPaperTitle;
}
public List<Paper> getSelectedPapers() {
return selectedPapers;
}
public void setSelectedPapers(List<Paper> selectedPapers) {
this.selectedPapers = selectedPapers;
}
}

View File

@ -1,26 +0,0 @@
package ru.ulstu.user.controller;
import org.springframework.stereotype.Service;
import ru.ulstu.user.model.User;
import ru.ulstu.user.service.UserService;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.inject.Inject;
@Service
public class UserConverter implements Converter {
@Inject
private UserService userService;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return value == null ? null : userService.findById(Integer.valueOf(value));
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return ((User) value).getId().toString();
}
}

View File

@ -1,21 +0,0 @@
package ru.ulstu.user.controller;
import ru.ulstu.user.model.User;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
@FacesConverter(value = "userDegreeConverter")
public class UserDegreeConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return User.UserDegree.valueOf(value);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return ((User.UserDegree) value).name();
}
}

View File

@ -1,46 +0,0 @@
package ru.ulstu.user.controller;
import ru.ulstu.core.navigation.Page;
import ru.ulstu.core.util.FacesUtil;
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.List;
@Named
@ViewScoped
public class UserView implements Serializable {
@Inject
private UserService userService;
private User user;
@PostConstruct
public void init() {
user = userService.findById(Integer.valueOf(FacesUtil.getRequestParams().get("id")));
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<User.UserDegree> getDegrees() {
return Arrays.asList(User.UserDegree.values());
}
public String save() {
userService.updateUserInformation(user);
FacesUtil.showInfoMessage("Данные пользователя сохранены", user.getUserAbbreviate());
return Page.USER_LIST + "?faces-redirect=true";
}
}

View File

@ -1,29 +0,0 @@
package ru.ulstu.user.controller;
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.List;
@Named
@ViewScoped
public class UsersView implements Serializable {
@Inject
private UserService userService;
private List<User> users;
@PostConstruct
public void init() {
users = userService.findAll();
}
public List<User> getUsers() {
return users;
}
}

View File

@ -1,115 +0,0 @@
<!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\:paperStatus > tbody > tr {
border: none;
}
#mainForm\:paperStatus > tbody > tr > td {
border: none;
padding: 0px;
}
#mainForm\:paperPanel > tbody > tr {
border: none;
}
#mainForm\:paperPanel > tbody > tr > td {
border: none;
}
.ui-editor.ui-widget-content {
background: white !important;
}
</style>
<p:panel id="panel" header="Редактирование пользователя" style="margin-bottom:10px;">
<p:panelGrid cellpadding="5" id="userPanel">
<p:row>
<p:column>
<h:outputLabel value="Имя"/>
</p:column>
<p:column>
<p:inputText id="firstName" required="true" value="#{userView.user.firstName}"/>
<p:message for="firstName"/>
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputLabel value="Отчество"/>
</p:column>
<p:column>
<p:inputText id="patr" value="#{userView.user.patronymic}"/>
<p:message for="patr"/>
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputLabel value="Фамилия"/>
</p:column>
<p:column>
<p:inputText id="lastName" required="true" value="#{userView.user.lastName}"/>
<p:message for="lastName"/>
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputLabel value="Email"/>
</p:column>
<p:column>
<p:outputLabel value="#{userView.user.email}"/>
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputLabel value="Логин"/>
</p:column>
<p:column>
<p:outputLabel value="#{userView.user.login}"/>
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputLabel value="Дата рождения"/>
</p:column>
<p:column>
<p:datePicker id="bDate" required="true" value="#{userView.user.birthDate}"
placeholder="Введите дату"
pattern="dd.MM.yyyy"/>
<p:message for="bDate"/>
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputLabel value="Ученая степень"/>
</p:column>
<p:column>
<p:selectOneMenu id="degree" value="#{userView.user.degree}"
converter="#{userDegreeConverter}">
<f:attribute name="collectionType" value="java.util.HashSet"/>
<f:selectItem itemLabel="Нет" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{userView.degrees}"
var="degree"
itemLabel="#{degree.degreeName}"
itemValue="#{degree}"/>
</p:selectOneMenu>
</p:column>
</p:row>
<p:row>
<p:column>
<p:commandButton action="#{userView.save}" value="Сохранить" ajax="true" process="@form"
update="messages @form"/>
</p:column>
</p:row>
</p:panelGrid>
</p:panel>
</ui:define>
</ui:composition>
</html>

View File

@ -1,34 +0,0 @@
<!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:dataTable value="#{usersView.users}" var="user" paginator="true" rows="10" id="usersTable"
widgetVar="usersTable" emptyMessage="Не найдено пользователей">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Поиск:"/>
<p:inputText id="globalFilter" onkeyup="PF('usersTable').filter()" style="width:150px"
placeholder="Строка поиска..."/>
</p:outputPanel>
</f:facet>
<p:column headerText="Имя" filterBy="#{user.userAbbreviate}" filterMatchMode="contains">
<h:outputLink value="/admin/user.xhtml">
#{user.userAbbreviate}
<f:param name="id" value="#{user.id}"/>
</h:outputLink>
</p:column>
<p:column headerText="Email" filterBy="#{user.email}" filterMatchMode="contains">
<p:outputLabel value="#{user.email}"/>
</p:column>
</p:dataTable>
</ui:define>
</ui:composition>
</html>

View File

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title><ui:insert name="header">NG-Tracker</ui:insert></title>
<h:outputStylesheet name="css/style.css"/>
<h:outputStylesheet name="css/google/kaushan.css"/>
<h:outputStylesheet name="primeicons/primeicons.css" library="primefaces"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
</h:head>
<h:body class="black">
<style type="text/css">
body {
font-size: 11px;
}
</style>
<h:form id="mainForm">
<div class="ui-g">
<div class="ui-g-12 ui-md-2"></div>
<div class="ui-g-12 ui-md-8">
<p:menubar>
<p:menuitem class="navbar-brand" value="NG-Tracker" url="#{page.index}"/>
<p:submenu label="Статьи" icon="fa fa-file-text-o">
<p:menuitem value="Мои статьи" icon="fa fa-calendar" url="#{page.paperDashboard}"/>
<p:menuitem value="Все статьи" icon="fa fa-file-o" url="#{page.paperList}"/>
</p:submenu>
<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: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}"/>
<f:facet name="options">
<p:link href="#{page.logout}" value="Выход"/>
</f:facet>
</p:menubar>
<div class="ui-fluid">
<p:growl id="messages" for="messages" showDetail="true"/>
<ui:insert name="content">Content</ui:insert>
</div>
</div>
</div>
</h:form>
</h:body>
</html>

View File

@ -1,139 +0,0 @@
<!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-3 ui-g-12">
<h:outputLabel value="Дата начала:"/>
</div>
<div class="ui-md-7 ui-g-12">
<p:datePicker value="#{conferenceView.conference.beginDate}" placeholder="Введите дату"
pattern="dd.MM.yyyy"/>
</div>
<div class="ui-md-3 ui-g-12">
<h:outputLabel value="Дата окончания:"/>
</div>
<div class="ui-md-7 ui-g-12">
<p:datePicker value="#{conferenceView.conference.endDate}" placeholder="Введите дату"
pattern="dd.MM.yyyy"/>
</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

@ -1,10 +0,0 @@
<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

@ -1,79 +0,0 @@
<!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

@ -1,81 +0,0 @@
<!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

@ -1,35 +0,0 @@
/* latin */
@font-face {
font-family: 'Droid Serif';
font-style: italic;
font-weight: 400;
src: local('Droid Serif Italic'), local('DroidSerif-Italic'), url(https://fonts.gstatic.com/s/droidserif/v8/tDbK2oqRg1oM3QBjjcaDkOr4nAfcHg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Droid Serif';
font-style: italic;
font-weight: 700;
src: local('Droid Serif Bold Italic'), local('DroidSerif-BoldItalic'), url(https://fonts.gstatic.com/s/droidserif/v8/tDbX2oqRg1oM3QBjjcaDkOr4lLz5CwOnSA.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Droid Serif';
font-style: normal;
font-weight: 400;
src: local('Droid Serif Regular'), local('DroidSerif-Regular'), url(https://fonts.gstatic.com/s/droidserif/v8/tDbI2oqRg1oM3QBjjcaDkOr9rAU.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Droid Serif';
font-style: normal;
font-weight: 700;
src: local('Droid Serif Bold'), local('DroidSerif-Bold'), url(https://fonts.gstatic.com/s/droidserif/v8/tDbV2oqRg1oM3QBjjcaDkOJGiRD7OwE.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

View File

@ -1,17 +0,0 @@
/* latin-ext */
@font-face {
font-family: 'Kaushan Script';
font-style: normal;
font-weight: 400;
src: local('Kaushan Script'), local('KaushanScript-Regular'), url(https://fonts.gstatic.com/s/kaushanscript/v6/vm8vdRfvXFLG3OLnsO15WYS5DG72wNJHMw.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Kaushan Script';
font-style: normal;
font-weight: 400;
src: local('Kaushan Script'), local('KaushanScript-Regular'), url(https://fonts.gstatic.com/s/kaushanscript/v6/vm8vdRfvXFLG3OLnsO15WYS5DG74wNI.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

View File

@ -1,89 +0,0 @@
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), local('Montserrat-Regular'), url(https://fonts.gstatic.com/s/montserrat/v12/JTUSjIg1_i6t8kCHKm459WRhyzbi.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), local('Montserrat-Regular'), url(https://fonts.gstatic.com/s/montserrat/v12/JTUSjIg1_i6t8kCHKm459W1hyzbi.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), local('Montserrat-Regular'), url(https://fonts.gstatic.com/s/montserrat/v12/JTUSjIg1_i6t8kCHKm459WZhyzbi.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), local('Montserrat-Regular'), url(https://fonts.gstatic.com/s/montserrat/v12/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), local('Montserrat-Regular'), url(https://fonts.gstatic.com/s/montserrat/v12/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: local('Montserrat Bold'), local('Montserrat-Bold'), url(https://fonts.gstatic.com/s/montserrat/v12/JTURjIg1_i6t8kCHKm45_dJE3gTD_u50.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: local('Montserrat Bold'), local('Montserrat-Bold'), url(https://fonts.gstatic.com/s/montserrat/v12/JTURjIg1_i6t8kCHKm45_dJE3g3D_u50.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: local('Montserrat Bold'), local('Montserrat-Bold'), url(https://fonts.gstatic.com/s/montserrat/v12/JTURjIg1_i6t8kCHKm45_dJE3gbD_u50.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: local('Montserrat Bold'), local('Montserrat-Bold'), url(https://fonts.gstatic.com/s/montserrat/v12/JTURjIg1_i6t8kCHKm45_dJE3gfD_u50.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: local('Montserrat Bold'), local('Montserrat-Bold'), url(https://fonts.gstatic.com/s/montserrat/v12/JTURjIg1_i6t8kCHKm45_dJE3gnD_g.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

View File

@ -1,251 +0,0 @@
/* cyrillic-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 100;
src: local('Roboto Slab Thin'), local('RobotoSlab-Thin'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngOUXZYTXPIvIBgJJSb6u-u1qqh5CCD.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 100;
src: local('Roboto Slab Thin'), local('RobotoSlab-Thin'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngOUXZYTXPIvIBgJJSb6u-u1qOh5CCD.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 100;
src: local('Roboto Slab Thin'), local('RobotoSlab-Thin'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngOUXZYTXPIvIBgJJSb6u-u1quh5CCD.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 100;
src: local('Roboto Slab Thin'), local('RobotoSlab-Thin'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngOUXZYTXPIvIBgJJSb6u-u1qSh5CCD.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 100;
src: local('Roboto Slab Thin'), local('RobotoSlab-Thin'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngOUXZYTXPIvIBgJJSb6u-u1qih5CCD.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 100;
src: local('Roboto Slab Thin'), local('RobotoSlab-Thin'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngOUXZYTXPIvIBgJJSb6u-u1qmh5CCD.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 100;
src: local('Roboto Slab Thin'), local('RobotoSlab-Thin'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngOUXZYTXPIvIBgJJSb6u-u1qeh5A.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 300;
src: local('Roboto Slab Light'), local('RobotoSlab-Light'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u9mxLCLwR26eg.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 300;
src: local('Roboto Slab Light'), local('RobotoSlab-Light'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u9mxLCCwR26eg.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 300;
src: local('Roboto Slab Light'), local('RobotoSlab-Light'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u9mxLCKwR26eg.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 300;
src: local('Roboto Slab Light'), local('RobotoSlab-Light'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u9mxLCFwR26eg.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 300;
src: local('Roboto Slab Light'), local('RobotoSlab-Light'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u9mxLCJwR26eg.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 300;
src: local('Roboto Slab Light'), local('RobotoSlab-Light'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u9mxLCIwR26eg.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 300;
src: local('Roboto Slab Light'), local('RobotoSlab-Light'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u9mxLCGwR0.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 400;
src: local('Roboto Slab Regular'), local('RobotoSlab-Regular'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngMUXZYTXPIvIBgJJSb6ufA5qW54A.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 400;
src: local('Roboto Slab Regular'), local('RobotoSlab-Regular'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngMUXZYTXPIvIBgJJSb6ufJ5qW54A.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 400;
src: local('Roboto Slab Regular'), local('RobotoSlab-Regular'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngMUXZYTXPIvIBgJJSb6ufB5qW54A.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 400;
src: local('Roboto Slab Regular'), local('RobotoSlab-Regular'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngMUXZYTXPIvIBgJJSb6ufO5qW54A.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 400;
src: local('Roboto Slab Regular'), local('RobotoSlab-Regular'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngMUXZYTXPIvIBgJJSb6ufC5qW54A.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 400;
src: local('Roboto Slab Regular'), local('RobotoSlab-Regular'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngMUXZYTXPIvIBgJJSb6ufD5qW54A.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 400;
src: local('Roboto Slab Regular'), local('RobotoSlab-Regular'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngMUXZYTXPIvIBgJJSb6ufN5qU.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 700;
src: local('Roboto Slab Bold'), local('RobotoSlab-Bold'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u92w7CLwR26eg.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 700;
src: local('Roboto Slab Bold'), local('RobotoSlab-Bold'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u92w7CCwR26eg.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 700;
src: local('Roboto Slab Bold'), local('RobotoSlab-Bold'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u92w7CKwR26eg.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 700;
src: local('Roboto Slab Bold'), local('RobotoSlab-Bold'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u92w7CFwR26eg.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 700;
src: local('Roboto Slab Bold'), local('RobotoSlab-Bold'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u92w7CJwR26eg.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 700;
src: local('Roboto Slab Bold'), local('RobotoSlab-Bold'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u92w7CIwR26eg.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 700;
src: local('Roboto Slab Bold'), local('RobotoSlab-Bold'), url(https://fonts.gstatic.com/s/robotoslab/v7/BngRUXZYTXPIvIBgJJSb6u92w7CGwR0.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

View File

@ -1,49 +0,0 @@
.black {
background-color: #383838 !important;
}
.ui-picklist-list-wrapper {
width: 50% !important;
}
.ui-picklist-list {
width: 100% !important;
}
.text-draft {
color: rgba(0, 0, 0, 0.48) !important;
}
.text-primary {
color: #228bba !important;
}
.text-warning {
color: #940000 !important;
}
.text-review {
color: #94028d !important;
}
.text-success {
color: #007741 !important;
}
.text-accepted {
color: #fec503 !important;
}
.text-not-accepted {
color: #A38831 !important;
}
.text-failed {
color: #A38831 !important;
}
.navbar-brand {
color: #fed136 !important;
font-family: 'Kaushan Script', 'Helvetica Neue', Helvetica, Arial, cursive;
}

View File

@ -1,27 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
>
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Доступ запрещен</title>
<h:outputStylesheet name="css/styles.css"/>
<h:outputScript name="js/jquery-2.2.4.min.js"/>
<link rel="stylesheet" href="/resources/css/font-awesome.css"/>
</h:head>
<h:body>
<div class="container">
<div class="row">
<div class="center-block" style="width:400px;">
<div class="content">
<h3><b>Доступ запрещен</b></h3>
<h:link outcome="#{page.MAIN}" styleClass="btn btn-primary">
<i class="fa fa-home fa-4"></i> Вернуться на главную
</h:link>
</div>
</div>
</div>
</div> <!-- /container -->
</h:body>
</html>

View File

@ -1,23 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Страница не найдена</title>
<h:outputStylesheet name="css/style.css"/>
</h:head>
<h:body styleClass="black">
<div class="ui-g">
<div class="ui-g-5"></div>
<div class="ui-g-2">
<p:panel header="Страница не найдена" style="margin-bottom:20px">
<h:link outcome="#{page.index}" styleClass="btn btn-primary">
<i class="fa fa-home fa-4"></i> Вернуться на главную
</h:link>
</p:panel>
</div>
</div>
</h:body>
</html>

View File

@ -1,42 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
>
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Ошибка сервера</title>
</h:head>
<h:body>
<div class="ui-g">
<div class="ui-g-2"></div>
<div class="ui-g-8">
<p:panel header="Ошибка" style="margin-bottom:20px">
<h:link outcome="#{page.index}" styleClass="btn btn-primary">
<i class="fa fa-home fa-4"></i> Вернуться на главную
</h:link>
<p:panel id="toggleable" header="Подробности" toggleable="true" toggleSpeed="500" closeSpeed="500"
widgetVar="panel" style="margin-bottom:20px" collapsed="true">
<h:panelGrid columns="2" cellpadding="10">
<h:outputText value="User agent:"/> <h:outputText value="#{header['user-agent']}"/>
<h:outputText value="User IP:"/> <h:outputText
value="#{empty header['x-forwarded-for'] ? request.remoteAddr : header['x-forwarded-for']}"/>
<h:outputText value="Status code:"/> <h:outputText
value="#{requestScope['javax.servlet.error.status_code']}"/>
<h:outputText value="Stack trace:"/>
<p:fragment>
<pre style="font-size: 10px">
#{requestScope['javax.servlet.error.exception']}
</pre>
</p:fragment>
</h:panelGrid>
</p:panel>
</p:panel>
</div>
</div>
</h:body>
</html>

View File

@ -1,93 +0,0 @@
<!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:ajax event="toggleSelect" update="mainForm:grantsRemoveButton" process="mainForm:grantsTable"
partialSubmit="true"/>
<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

@ -1,142 +0,0 @@
<!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

@ -1,10 +0,0 @@
<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

@ -1,90 +0,0 @@
<!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:ajax event="toggleSelect" update="mainForm:grantsRemoveButton" process="mainForm:grantsTable"
partialSubmit="true"/>
<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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 KiB

View File

@ -1,20 +0,0 @@
<!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="content">
<p:dataGrid id="sections" var="section" value="#{indexView.sections}" columns="3" layout="grid"
style="text-align:center">
<p:panel id="pnl" header="#{section.title}" style="text-align:center;">
<h:panelGrid columns="1" style="width:100%;">
<h:outputLink value="#{section.href}">
<p:graphicImage style="width:100%" name="img/main/#{section.image}"/>
</h:outputLink>
</h:panelGrid>
</p:panel>
</p:dataGrid>
</ui:define>
</ui:composition>
</html>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<h:outputStylesheet name="css/style.css"/>
<title>Вход в систему</title>
</h:head>
<h:body class="black">
<div class="ui-g">
<div class="ui-md-4 ui-g-12"></div>
<div class="ui-md-4 ui-g-12">
<form method="post" action="/login.xhtml">
<p:panel header="Вход в систему" style="margin-bottom:20px">
<table cellpadding="10" style="width: 100%">
<tbody>
<tr>
<td>
<div></div>
</td>
</tr>
<tr>
<td><input id="username" name="username" type="text" placeholder="Логин"
class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all form-control"
style="width: 100%"/>
</td>
</tr>
<tr>
<td>
<input id="password" name="password" type="password" placeholder="Пароль"
class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all form-control"
style="width: 100%"/>
</td>
</tr>
<tr>
<td>
<button id="j_idt15" name="j_idt15"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only btn btn-default"
type="submit">
<span class="ui-button-text ui-c">Войти</span>
</button>
</td>
</tr>
<tr>
<td>
<a href="oauth2/authorize-client/google"
class="list-group-item active">Войти с учетной записью Google</a>
</td>
<td>
<a class="list-group-item active" target="_blank"
href="http://timetable.athene.tech/timetable?source=ng-tracker">Расписание УлГТУ</a>
</td>
</tr>
</tbody>
</table>
</p:panel>
</form>
</div>
<div class="ui-g-5"></div>
</div>
</h:body>
</html>

View File

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

View File

@ -1,176 +0,0 @@
<!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\:paperStatus > tbody > tr {
border: none;
}
#mainForm\:paperStatus > tbody > tr > td {
border: none;
padding: 0px;
}
#mainForm\:paperPanel > tbody > tr {
border: none;
}
#mainForm\:paperPanel > tbody > tr > td {
border: none;
}
.ui-editor.ui-widget-content {
background: white !important;
}
</style>
<p:panel id="panel" header="Редактирование статьи: #{paperView.paper.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="#{paperView.paper.title}"/>
<p:message for="name"/>
</div>
<div class="ui-md-2 ui-g-12">
<p:selectOneMenu id="conference" value="#{paperView.paper.conference}"
converter="#{conferenceConverter}">
<p:ajax update="mainForm:conferenceId" process="@this"/>
<f:selectItem itemValue="#{null}" itemLabel="Конференция для статьи"/>
<f:selectItems value="#{paperView.conferences}"
var="conference"
itemDescription="#{conference.title}"
itemLabel="#{paperView.getConferenceTitle(conference)}"
itemValue="#{conference}"/>
</p:selectOneMenu>
</div>
<div class="ui-md-3 ui-g-12">
<p:outputLabel for="paperStatus" value="Статус:"/>
</div>
<div class="ui-md-7 ui-g-12">
<p:panelGrid columns="2" id="paperStatus">
<p:selectOneMenu id="status" required="true" value="#{paperView.paper.status}"
converter="paperStatusConverter">
<p:ajax update="mainForm:paperStatus" process="@this"/>
<f:selectItems value="#{paperView.paperStatuses}"
var="status"
itemLabel="#{status.statusName}"
itemValue="#{status}"/>
</p:selectOneMenu>
<ui:include src="paperStatusFragment.xhtml">
<ui:param name="paper" value="#{paperView.paper}"/>
<ui:param name="shortMode" value="true"/>
</ui:include>
</p:panelGrid>
</div>
<div class="ui-md-2 ui-g-12">
<h:outputLink value="#{page.conference}" id="conferenceId"
title="#{paperView.paper.conference.title}"
target="_blank">
#{paperView.getConferenceTitle(paperView.paper.conference)}
<f:param name="id" value="#{paperView.paper.conference.id}"/>
</h:outputLink>
</div>
<div class="ui-md-3 ui-g-12">
<p:outputLabel for="type" value="Тип:"/>
</div>
<div class="ui-md-7 ui-g-12">
<p:selectOneMenu id="type" value="#{paperView.paper.type}"
converter="paperTypeConverter">
<f:selectItems value="#{paperView.paperTypes}"
var="type"
itemLabel="#{type.typeName}"
itemValue="#{type}"/>
</p:selectOneMenu>
</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="#{paperView.paper.authors}" multiple="true"
converter="#{userConverter}">
<f:attribute name="collectionType" value="java.util.HashSet"/>
<f:selectItems value="#{paperView.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="#{paperView.paper.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="#{paperView.deleteDeadline(deadline)}"/>
</p:commandButton>
</div>
</ui:repeat>
<div class="ui-md-5 ui-g-12">
<p:datePicker value="#{paperView.newDeadlineDate}" placeholder="Введите дату"
pattern="dd.MM.yyyy"/>
</div>
<div class="ui-md-5 ui-g-12">
<p:inputText value="#{paperView.newDeadlineDescription}"
placeholder="Описание ключевой даты"/>
</div>
<div class="ui-md-1 ui-g-12">
<p:commandButton icon="pi pi-check">
<p:ajax update="mainForm" process="@this"
listener="#{paperView.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="#{paperView.paper.comment}" height="300"
style="margin-bottom:10px" placeholder="Комментарий"/>
</div>
<div class="ui-md-2 ui-g-12">
<p>
Статья создана
<h:outputText value="#{paperView.paper.createDate}">
<f:convertDateTime pattern="dd.MM.yyyy HH:mm"/>
</h:outputText>
</p>
<p>
Статья обновлена
<h:outputText value="#{paperView.paper.updateDate}">
<f:convertDateTime pattern="dd.MM.yyyy HH:mm"/>
</h:outputText>
</p>
</div>
<div class="ui-md-5 ui-g-12">
<p:commandButton action="#{paperView.save}" value="Сохранить" ajax="true" process="@form"
update="messages @form"/>
</div>
</div>
</div>
</p:panel>
</ui:define>
</ui:composition>
</html>

View File

@ -1,10 +0,0 @@
<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="#{paper.status.statusName}">
<i class="fa fa-circle #{paper.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="#{paper.status.statusName}"/>
</ui:fragment>
</ui:composition>

View File

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

View File

@ -15,11 +15,6 @@ server.ssl.key-password=password
logging.level.ru.ulstu=DEBUG logging.level.ru.ulstu=DEBUG
#HtmlUnit #HtmlUnit
logging.level.com.gargoylesoftware.htmlunit=ERROR logging.level.com.gargoylesoftware.htmlunit=ERROR
#jsf
#joinfaces.primefaces.theme=casablanca
joinfaces.primefaces.theme=afterdark
joinfaces.primefaces.font-awesome=true
joinfaces.mojarra.enable-restore-view11-compatibility=true
# Mail Settings # Mail Settings
spring.mail.host=smtp.yandex.ru spring.mail.host=smtp.yandex.ru
spring.mail.port=465 spring.mail.port=465

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
<head>
</head>
<body>
<div class="container" layout:fragment="content">
<section id="services">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading text-uppercase">Доступ запрещен</h2>
<a href="/"><h3>Вернуться на главную</h3></a>
</div>
</div>
</div>
</section>
</div>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
<head>
</head>
<body>
<div class="container" layout:fragment="content">
<section id="services">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading text-uppercase">Страница не найдена</h2>
<a href="/"><h3>Вернуться на главную</h3></a>
</div>
</div>
</div>
</section>
</div>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
<head>
</head>
<body>
<div class="container" layout:fragment="content">
<section id="services">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading text-uppercase">Ошибка сервера</h2>
<a href="/"><h3>Вернуться на главную</h3></a>
</div>
</div>
</div>
</section>
</div>
</body>
</html>

View File

@ -34,10 +34,6 @@
</div> </div>
</fieldset> </fieldset>
</form> </form>
<h3>Login with:</h3>
<p th:each="url : ${urls}">
<a th:text="${url.key}" th:href="${url.value}">Client</a>
</p>
</div> </div>
</div> </div>
</div> </div>