Merge branch 'jsf' into 'dev'

Jsf

See merge request romanov73/ng-tracker!119
This commit is contained in:
Anton Romanov 2020-04-25 16:52:19 +00:00
commit 37053d853b
109 changed files with 3076 additions and 4007 deletions

View File

@ -27,8 +27,8 @@ mainClassName = 'ru.ulstu.NgTrackerApplication'
build.dependsOn checkstyleMain
bootRun.dependsOn checkstyleMain
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 11
targetCompatibility = 11
bootRun {
systemProperties = System.properties
@ -88,13 +88,9 @@ compileJava {
repositories {
mavenLocal()
mavenCentral()
}
configurations {
compile.exclude module: "spring-boot-starter-tomcat"
compile.exclude module: "bcmail-jdk14"
compile.exclude module: "bcprov-jdk14"
compile.exclude module: "bctsp-jdk14"
maven {
url "https://repository.primefaces.org/"
}
}
dependencies {
@ -102,13 +98,15 @@ dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-security'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-aop'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
compile group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect'
compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-springsecurity5'
compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-afterburner'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate5'
compile group: 'org.springframework.security', name: 'spring-security-oauth2-client'
compile group: 'org.springframework.security', name: 'spring-security-oauth2-jose'
compile group: 'org.postgresql', name: 'postgresql', version: '42.2.5'
@ -117,19 +115,21 @@ dependencies {
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'
compile group: 'org.webjars', name: 'bootstrap', version: '4.1.0'
compile group: 'org.webjars', name: 'bootstrap-select', version: '1.13.3'
compile group: 'org.webjars', name: 'jquery', version: '3.3.1-1'
compile group: 'org.webjars.npm', name: 'jquery.easing', version: '1.4.1'
compile group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
//primefaces
compile group: 'org.primefaces', name: 'primefaces', version: '7.0'
compile group: 'net.bootsfaces', name: 'bootsfaces', version: '1.4.2'
compile group: 'org.joinfaces', name: 'jsf-spring-boot-starter', version: '4.1.2'
compile group: 'org.javassist', name: 'javassist', version: '3.25.0-GA'
compile group: 'org.primefaces.themes', name: 'all-themes', version: '1.0.10'
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: 'net.sourceforge.htmlunit', name: 'htmlunit', version: '2.35.0'
compile group: 'xalan', name: 'xalan', version: '2.7.2'
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.3.1'
testCompile group: 'org.seleniumhq.selenium', name: 'selenium-support', version: '3.3.1'
//compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.3.1'
//testCompile group: 'org.seleniumhq.selenium', name: 'selenium-support', version: '3.3.1'
//testCompile group: 'com.google.guava', name: 'guava', version: '21.0'
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
}
}

View File

@ -169,4 +169,4 @@
</module>
</module>
</module>

View File

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

View File

@ -1,30 +0,0 @@
package ru.ulstu.configuration;
import org.eclipse.jetty.server.ServerConnector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpListenerConfiguration implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> {
@Value("${server.http.port}")
private int httpPort;
private void configureJetty(JettyServletWebServerFactory jettyFactory) {
jettyFactory.addServerCustomizers((JettyServerCustomizer) server -> {
ServerConnector serverConnector = new ServerConnector(server);
serverConnector.setPort(httpPort);
server.addConnector(serverConnector);
});
}
@Override
public void customize(ConfigurableWebServerFactory factory) {
if (factory instanceof JettyServletWebServerFactory) {
configureJetty((JettyServletWebServerFactory) factory);
}
}
}

View File

@ -1,7 +1,10 @@
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.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -9,20 +12,14 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
public class MvcConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
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");
registry.addRedirectViewController("/", "/index.xhtml");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/");
@Bean
public ErrorPageRegistrar errorPageRegistrar() {
return registry -> {
registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404.xhtml"));
registry.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500.xhtml"));
};
}
}

View File

@ -5,27 +5,49 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import ru.ulstu.core.model.AuthFailureHandler;
import ru.ulstu.user.controller.UserController;
import ru.ulstu.core.navigation.Page;
import ru.ulstu.user.model.UserRoleConstants;
import ru.ulstu.user.service.UserService;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
private static List<String> clients = Arrays.asList("google");
private static final String CLIENT_PROPERTY_KEY
= "spring.security.oauth2.client.registration.";
@Autowired
private Environment env;
@Value("${server.http.port}")
private int httpPort;
@ -55,8 +77,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable();
http.csrf().disable();
if (applicationProperties.isDevMode()) {
log.debug("Security disabled");
http.authorizeRequests()
@ -66,32 +87,39 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.principal("admin")
.authorities(UserRoleConstants.ADMIN);
} else {
log.debug("Security enabled");
http.authorizeRequests()
.antMatchers(UserController.ACTIVATE_URL).permitAll()
.antMatchers(Constants.PASSWORD_RESET_REQUEST_PAGE).permitAll()
.antMatchers(Constants.PASSWORD_RESET_PAGE).permitAll()
.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("/login.xhtml", "/logout")
.permitAll()
.anyRequest()
.authenticated()
.antMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN)
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginPage("/login.xhtml")
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.permitAll()
.and()
.oauth2Login()
.loginPage("/login.xhtml")
.authorizationEndpoint()
.baseUri("/oauth2/authorize-client")
.authorizationRequestRepository(authorizationRequestRepository())
.and()
.tokenEndpoint()
.accessTokenResponseClient(accessTokenResponseClient())
.and()
.defaultSuccessUrl(Page.INDEX)
.failureUrl("/loginFailure")
.and()
.logout()
.logoutSuccessHandler(logoutSuccessHandler)
.logoutSuccessUrl(Constants.LOGOUT_URL)
.invalidateHttpSession(false)
.logoutSuccessUrl(Page.LOGOUT)
.invalidateHttpSession(true)
.clearAuthentication(true)
.deleteCookies(Constants.COOKIES_NAME)
.permitAll();
http.csrf().disable();
}
if (applicationProperties.isUseHttps()) {
http.portMapper()
@ -102,13 +130,51 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.anyRequest()
.requiresSecure();
}
}
@Bean
public AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository() {
return new HttpSessionOAuth2AuthorizationRequestRepository();
}
@Bean
public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient() {
DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();
return accessTokenResponseClient;
}
//@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
List<ClientRegistration> registrations = clients.stream()
.map(c -> getRegistration(c))
.filter(registration -> registration != null)
.collect(Collectors.toList());
return new InMemoryClientRegistrationRepository(registrations);
}
private ClientRegistration getRegistration(String client) {
String clientId = env.getProperty(CLIENT_PROPERTY_KEY + client + ".client-id");
if (clientId == null) {
return null;
}
String clientSecret = env.getProperty(CLIENT_PROPERTY_KEY + client + ".client-secret");
if (client.equals("google")) {
return CommonOAuth2Provider.GOOGLE.getBuilder(client)
.clientId(clientId)
.clientSecret(clientSecret)
.build();
}
return null;
}
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/css/**")
.antMatchers("/javax.faces.resource/**")
.antMatchers("/js/**")
.antMatchers("/templates/**")
.antMatchers("/webjars/**")

View File

@ -1,121 +0,0 @@
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.ControllerAdvice;
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("currentUser")
public String getCurrentUser() {
return userService.getCurrentUser().getUserAbbreviate();
}
@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

@ -0,0 +1,52 @@
package ru.ulstu.core.navigation;
import javax.inject.Named;
@Named
public class Page {
public static final String INDEX = "/index.xhtml";
public static final String PAPER = "/paper/paper.xhtml";
public static final String PAPER_LIST = "/paper/papers.xhtml";
public static final String PAPER_DASHBOARD = "/paper/dashboard.xhtml";
public static final String GRANT = "/grant/grant.xhtml";
public static final String GRANT_LIST = "/grant/grants.xhtml";
public static final String GRANT_DASHBOARD = "/grant/dashboard.xhtml";
public static final String USER_LIST = "/admin/users.xhtml";
public static final String LOGOUT = "/logout";
public String getIndex() {
return INDEX;
}
public String getPaperList() {
return PAPER_LIST;
}
public String getPaperDashboard() {
return PAPER_DASHBOARD;
}
public String getUserList() {
return USER_LIST;
}
public String getLogout() {
return LOGOUT;
}
public String getGrantList() {
return GRANT_LIST;
}
public String getGrantDashboard() {
return GRANT_DASHBOARD;
}
public String getPaper() {
return PAPER;
}
public String getGrant() {
return GRANT;
}
}

View File

@ -63,4 +63,10 @@ public class DateUtils {
cal.add(Calendar.YEAR, count);
return cal.getTime();
}
public static LocalDate convertToLocalDate(Date dateToConvert) {
return dateToConvert.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
}
}

View File

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

@ -2,9 +2,11 @@ package ru.ulstu.deadline.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.core.util.DateUtils;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.deadline.repository.DeadlineRepository;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@ -47,6 +49,19 @@ public class DeadlineService {
return newDeadline;
}
public Deadline create(Date date) {
Deadline deadline = new Deadline();
deadline.setDate(date);
return create(deadline);
}
public Deadline create(String description, Date date) {
Deadline deadline = new Deadline();
deadline.setDate(date);
deadline.setDescription(description);
return create(deadline);
}
@Transactional
public void remove(Integer deadlineId) {
deadlineRepository.deleteById(deadlineId);
@ -55,4 +70,12 @@ public class DeadlineService {
public Date findByGrantIdAndDate(Integer id, Date date) {
return deadlineRepository.findByGrantIdAndDate(id, date);
}
public Deadline createWithOffset(Date date, long value, ChronoUnit chronoUnit) {
return create(DateUtils.localDateToDate(DateUtils.convertToLocalDate(date).plus(value, chronoUnit)));
}
public void delete(List<Deadline> deadlines) {
deadlineRepository.deleteInBatch(deadlines);
}
}

View File

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

View File

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

View File

@ -0,0 +1,94 @@
package ru.ulstu.grant.controller;
import ru.ulstu.core.navigation.Page;
import ru.ulstu.core.util.FacesUtil;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.grant.service.GrantService;
import ru.ulstu.user.model.User;
import ru.ulstu.user.service.UserService;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@Named
@ViewScoped
public class GrantView implements Serializable {
@Inject
private GrantService grantService;
@Inject
private DeadlineService deadlineService;
@Inject
private UserService userService;
private Grant grant;
private Date newDeadlineDate;
private String newDeadlineDescription;
@PostConstruct
public void init() {
grant = grantService.findById(Integer.valueOf(FacesUtil.getRequestParams().get("id")));
newDeadlineDescription = "";
newDeadlineDate = new Date();
FacesUtil.showInfoMessage("Статья открыта", "");
}
public Grant getGrant() {
return grant;
}
public void setGrant(Grant grant) {
this.grant = grant;
}
public List<Grant.GrantStatus> getGrantStatuses() {
return Arrays.asList(Grant.GrantStatus.values());
}
public List<User> getAuthors() {
return userService.findAll();
}
public String save() {
grantService.save(grant);
FacesUtil.showInfoMessage("Грант сохранен", "");
return Page.GRANT_LIST + "?faces-redirect=true";
}
public Date getNewDeadlineDate() {
return newDeadlineDate;
}
public void setNewDeadlineDate(Date newDeadlineDate) {
this.newDeadlineDate = newDeadlineDate;
}
public String getNewDeadlineDescription() {
return newDeadlineDescription;
}
public void setNewDeadlineDescription(String newDeadlineDescription) {
this.newDeadlineDescription = newDeadlineDescription;
}
public void deleteDeadline(Deadline deadline) {
grant.getDeadlines().remove(deadline);
}
public void addDeadline() {
grant.getDeadlines().add(deadlineService.create(newDeadlineDescription, newDeadlineDate));
newDeadlineDescription = "";
newDeadlineDate = new Date();
}
}

View File

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

View File

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

View File

@ -52,4 +52,4 @@ public class KiasPage {
public boolean isTableRowGrantLine(DomNode grantElement) {
return !((HtmlTableRow) grantElement).getAttribute("class").contains("pagerSavedHeightSpacer");
}
}
}

View File

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

View File

@ -32,7 +32,7 @@ public class KiasService {
public List<GrantDto> getNewGrantsDto() throws ParseException, IOException {
Integer leaderId = userService.findOneByLoginIgnoreCase("admin").getId();
List<GrantDto> grants = new ArrayList<>();
try (final WebClient webClient = new WebClient()) {
try (WebClient webClient = new WebClient()) {
webClient.setJavaScriptTimeout(60 * 1000);
webClient.getOptions().setThrowExceptionOnScriptError(false);
for (Integer year : generateGrantYears()) {

View File

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

@ -0,0 +1,27 @@
package ru.ulstu.index.controller;
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("Статьи", "papers.jpg"));
sections.add(new Section("Конференции", "conf.jpg"));
sections.add(new Section("Гранты", "grants.jpg"));
sections.add(new Section("Проекты", "projects.jpg"));
}
public List<Section> getSections() {
return sections;
}
}

View File

@ -0,0 +1,27 @@
package ru.ulstu.index.model;
public class Section {
private String title;
private String image;
public Section(String title, String image) {
this.title = title;
this.image = image;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}

View File

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

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

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

@ -0,0 +1,98 @@
package ru.ulstu.paper.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.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 {
@Inject
private PaperService paperService;
@Inject
private DeadlineService deadlineService;
@Inject
private UserService userService;
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();
}
}

View File

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

@ -39,24 +39,30 @@ import java.util.Set;
@DiscriminatorValue("PAPER")
public class Paper extends BaseEntity implements UserActivity, EventSource {
public enum PaperStatus {
ATTENTION("Обратить внимание"),
ON_PREPARATION("На подготовке"),
ON_REVIEW("Отправлена на проверку"),
ACCEPTED("Принята"),
NOT_ACCEPTED("Не принята"),
COMPLETED("Завершена (опубликована)"),
DRAFT("Черновик"),
FAILED("Провалены сроки");
ATTENTION("Обратить внимание", "text-warning"),
ON_PREPARATION("На подготовке", "text-primary"),
ON_REVIEW("Отправлена на проверку", "text-review"),
ACCEPTED("Принята", "text-accepted"),
NOT_ACCEPTED("Не принята", "text-not-accepted"),
COMPLETED("Завершена (опубликована)", "text-success"),
DRAFT("Черновик", "text-draft"),
FAILED("Провалены сроки", "text-failed");
private final String statusName;
private final String elementClass;
PaperStatus(String name) {
PaperStatus(String name, String elementClass) {
this.statusName = name;
this.elementClass = elementClass;
}
public String getStatusName() {
return statusName;
}
public String getElementClass() {
return elementClass;
}
}
public enum PaperType {
@ -93,7 +99,7 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
@Temporal(TemporalType.TIMESTAMP)
private Date updateDate = new Date();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "paper_id", unique = true)
@Fetch(FetchMode.SUBSELECT)
@OrderBy("date")

View File

@ -22,6 +22,7 @@ import ru.ulstu.user.service.UserService;
import java.io.IOException;
import java.text.MessageFormat;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
@ -85,13 +86,20 @@ public class PaperService {
return papers;
}
private List<Paper> findAllActive() {
public List<Paper> findAllActive() {
return findAll()
.stream()
.filter(paper -> paper.getStatus() != COMPLETED && paper.getStatus() != FAILED)
.collect(toList());
}
public List<Paper> findAllActiveByCurrentUser() {
return findAllActive()
.stream()
.filter(paper -> paper.getAuthors().contains(userService.getCurrentUser()))
.collect(toList());
}
public List<PaperDto> findAllActiveDto() {
return convert(findAllActive(), PaperDto::new);
}
@ -103,17 +111,14 @@ public class PaperService {
@Transactional
public Integer create(PaperDto paperDto) throws IOException {
Paper newPaper = copyFromDto(new Paper(), paperDto);
newPaper = paperRepository.save(newPaper);
paperNotificationService.sendCreateNotification(newPaper);
eventService.createFromPaper(newPaper);
return newPaper.getId();
return create(newPaper).getId();
}
@Transactional
public Paper create(Paper paper) {
Paper newPaper = paperRepository.save(paper);
newPaper.setCreateDate(new Date());
paperNotificationService.sendCreateNotification(newPaper);
eventService.createFromPaper(newPaper);
return newPaper;
}
@ -206,10 +211,29 @@ public class PaperService {
return paper.getId();
}
@Transactional
public Integer update(Paper newPaper) {
Paper oldPaper = paperRepository.getOne(newPaper.getId());
Paper.PaperStatus oldStatus = oldPaper.getStatus();
Set<User> oldAuthors = new HashSet<>(oldPaper.getAuthors());
newPaper.setUpdateDate(new Date());
newPaper = paperRepository.save(newPaper);
for (User author : newPaper.getAuthors()) {
if (!oldAuthors.contains(author)) {
paperNotificationService.sendCreateNotification(newPaper);
}
}
if (newPaper.getStatus() != oldStatus) {
paperNotificationService.statusChangeNotification(newPaper, oldStatus);
}
return newPaper.getId();
}
@Transactional
public void delete(Integer paperId) {
Paper paper = paperRepository.getOne(paperId);
paperRepository.delete(paper);
delete(paperRepository.getOne(paperId));
}
public List<Paper.PaperStatus> getPaperStatuses() {
@ -292,6 +316,14 @@ public class PaperService {
}
}
public void save(Paper paper) {
if (isEmpty(paper.getId())) {
create(paper);
} else {
update(paper);
}
}
public PaperDto findById(Integer paperId) {
return new PaperDto(paperRepository.getOne(paperId));
}
@ -395,4 +427,22 @@ public class PaperService {
public void ping(int paperId) throws IOException {
pingService.addPing(findPaperById(paperId));
}
public void createByTitle(String newPaperTitle) {
Paper paper = new Paper();
paper.setTitle(newPaperTitle);
paper.setStatus(DRAFT);
paper.getAuthors().add(userService.getCurrentUser());
paper.getDeadlines().add(deadlineService.createWithOffset(new Date(), 1, ChronoUnit.WEEKS));
create(paper);
}
public void delete(List<Paper> papers) {
papers.forEach(paper -> delete(paper));
}
public void delete(Paper paper) {
deadlineService.delete(paper.getDeadlines());
paperRepository.delete(paper);
}
}

View File

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

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

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

@ -0,0 +1,29 @@
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,435 +1,442 @@
package ru.ulstu.user.service;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.mail.MailException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.configuration.ApplicationProperties;
import ru.ulstu.core.error.EntityIdIsNullException;
import ru.ulstu.core.jpa.OffsetablePageRequest;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.core.model.UserActivity;
import ru.ulstu.core.model.response.PageableItems;
import ru.ulstu.ping.model.Ping;
import ru.ulstu.ping.service.PingService;
import ru.ulstu.user.error.UserActivationError;
import ru.ulstu.user.error.UserBlockedException;
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.model.User;
import ru.ulstu.user.model.UserDto;
import ru.ulstu.user.model.UserInfoNow;
import ru.ulstu.user.model.UserListDto;
import ru.ulstu.user.model.UserResetPasswordDto;
import ru.ulstu.user.model.UserRole;
import ru.ulstu.user.model.UserRoleConstants;
import ru.ulstu.user.model.UserRoleDto;
import ru.ulstu.user.repository.UserRepository;
import ru.ulstu.user.repository.UserRoleRepository;
import ru.ulstu.user.util.UserUtils;
import ru.ulstu.utils.timetable.TimetableService;
import ru.ulstu.utils.timetable.errors.TimetableClientException;
import ru.ulstu.utils.timetable.model.Lesson;
import javax.mail.MessagingException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@Transactional
public class UserService implements UserDetailsService {
private static final String INVITE_USER_EXCEPTION = "Во время отправки приглашения произошла ошибка";
private final Logger log = LoggerFactory.getLogger(UserService.class);
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final UserRoleRepository userRoleRepository;
private final UserMapper userMapper;
private final MailService mailService;
private final ApplicationProperties applicationProperties;
private final TimetableService timetableService;
private final ConferenceService conferenceService;
private final UserSessionService userSessionService;
private final PingService pingService;
public UserService(UserRepository userRepository,
PasswordEncoder passwordEncoder,
UserRoleRepository userRoleRepository,
UserMapper userMapper,
MailService mailService,
ApplicationProperties applicationProperties,
@Lazy PingService pingService,
@Lazy ConferenceService conferenceRepository,
@Lazy UserSessionService userSessionService) throws ParseException {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.userRoleRepository = userRoleRepository;
this.userMapper = userMapper;
this.mailService = mailService;
this.applicationProperties = applicationProperties;
this.conferenceService = conferenceRepository;
this.timetableService = new TimetableService();
this.userSessionService = userSessionService;
this.pingService = pingService;
}
private User getUserByEmail(String email) {
return userRepository.findOneByEmailIgnoreCase(email);
}
private User getUserByActivationKey(String activationKey) {
return userRepository.findOneByActivationKey(activationKey);
}
public User getUserByLogin(String login) {
return userRepository.findOneByLoginIgnoreCase(login);
}
@Transactional(readOnly = true)
public UserDto getUserWithRolesById(Integer userId) {
final User userEntity = userRepository.findOneWithRolesById(userId);
if (userEntity == null) {
throw new UserNotFoundException(userId.toString());
}
return userMapper.userEntityToUserDto(userEntity);
}
@Transactional(readOnly = true)
public PageableItems<UserListDto> getAllUsers(int offset, int count) {
final Page<User> page = userRepository.findAll(new OffsetablePageRequest(offset, count, Sort.by("id")));
return new PageableItems<>(page.getTotalElements(), userMapper.userEntitiesToUserListDtos(page.getContent()));
}
// TODO: read only active users
public List<User> findAll() {
return userRepository.findAll();
}
@Transactional(readOnly = true)
public PageableItems<UserRoleDto> getUserRoles() {
final List<UserRoleDto> roles = userRoleRepository.findAll().stream()
.map(UserRoleDto::new)
.sorted(Comparator.comparing(UserRoleDto::getViewValue))
.collect(Collectors.toList());
return new PageableItems<>(roles.size(), roles);
}
public UserDto createUser(UserDto userDto) {
if (userDto.getId() != null) {
throw new UserIdExistsException();
}
if (getUserByLogin(userDto.getLogin()) != null) {
throw new UserLoginExistsException(userDto.getLogin());
}
if (getUserByEmail(userDto.getEmail()) != null) {
throw new UserEmailExistsException(userDto.getEmail());
}
if (userDto.isPasswordsValid()) {
throw new UserPasswordsNotValidOrNotMatchException("");
}
User user = userMapper.userDtoToUserEntity(userDto);
user.setActivated(false);
user.setActivationKey(UserUtils.generateActivationKey());
user.setRoles(Collections.singleton(new UserRole(UserRoleConstants.USER)));
user.setPassword(passwordEncoder.encode(userDto.getPassword()));
user = userRepository.save(user);
mailService.sendActivationEmail(user);
log.debug("Created Information for User: {}", user.getLogin());
return userMapper.userEntityToUserDto(user);
}
public UserDto activateUser(String activationKey) {
final User user = getUserByActivationKey(activationKey);
if (user == null) {
throw new UserActivationError(activationKey);
}
user.setActivated(true);
user.setActivationKey(null);
user.setActivationDate(null);
log.debug("Activated user: {}", user.getLogin());
return userMapper.userEntityToUserDto(userRepository.save(user));
}
public UserDto updateUser(UserDto userDto) {
if (userDto.getId() == null) {
throw new EntityIdIsNullException();
}
if (!Objects.equals(
Optional.ofNullable(getUserByEmail(userDto.getEmail()))
.map(BaseEntity::getId).orElse(userDto.getId()),
userDto.getId())) {
throw new UserEmailExistsException(userDto.getEmail());
}
if (!Objects.equals(
Optional.ofNullable(getUserByLogin(userDto.getLogin()))
.map(BaseEntity::getId).orElse(userDto.getId()),
userDto.getId())) {
throw new UserLoginExistsException(userDto.getLogin());
}
User user = userRepository.getOne(userDto.getId());
if (user == null) {
throw new UserNotFoundException(userDto.getId().toString());
}
if (applicationProperties.getUndeadUserLogin().equalsIgnoreCase(user.getLogin())) {
userDto.setLogin(applicationProperties.getUndeadUserLogin());
userDto.setActivated(true);
userDto.setRoles(Collections.singletonList(new UserRoleDto(UserRoleConstants.ADMIN)));
}
user.setLogin(userDto.getLogin());
user.setFirstName(userDto.getFirstName());
user.setLastName(userDto.getLastName());
user.setEmail(userDto.getEmail());
if (userDto.isActivated() != user.getActivated()) {
if (userDto.isActivated()) {
user.setActivationKey(null);
user.setActivationDate(null);
} else {
user.setActivationKey(UserUtils.generateActivationKey());
user.setActivationDate(new Date());
}
}
user.setActivated(userDto.isActivated());
final Set<UserRole> roles = userMapper.rolesFromDto(userDto.getRoles());
user.setRoles(roles.isEmpty()
? Collections.singleton(new UserRole(UserRoleConstants.USER))
: roles);
if (!StringUtils.isEmpty(userDto.getOldPassword())) {
if (userDto.isPasswordsValid() || !userDto.isOldPasswordValid()) {
throw new UserPasswordsNotValidOrNotMatchException("");
}
if (!passwordEncoder.matches(userDto.getOldPassword(), user.getPassword())) {
throw new UserPasswordsNotValidOrNotMatchException("");
}
user.setPassword(passwordEncoder.encode(userDto.getPassword()));
log.debug("Changed password for User: {}", user.getLogin());
}
user = userRepository.save(user);
log.debug("Changed Information for User: {}", user.getLogin());
return userMapper.userEntityToUserDto(user);
}
public UserDto updateUserInformation(User user, UserDto updateUser) {
user.setFirstName(updateUser.getFirstName());
user.setLastName(updateUser.getLastName());
user.setEmail(updateUser.getEmail());
user.setLogin(updateUser.getLogin());
user = userRepository.save(user);
log.debug("Updated Information for User: {}", user.getLogin());
return userMapper.userEntityToUserDto(user);
}
public void changeUserPassword(User user, Map<String, String> payload) {
if (!payload.get("password").equals(payload.get("confirmPassword"))) {
throw new UserPasswordsNotValidOrNotMatchException("");
}
if (!passwordEncoder.matches(payload.get("oldPassword"), user.getPassword())) {
throw new UserPasswordsNotValidOrNotMatchException("Старый пароль введен неправильно");
}
user.setPassword(passwordEncoder.encode(payload.get("password")));
log.debug("Changed password for User: {}", user.getLogin());
userRepository.save(user);
mailService.sendChangePasswordMail(user);
}
public boolean requestUserPasswordReset(String email) {
User user = userRepository.findOneByEmailIgnoreCase(email);
if (user == null) {
throw new UserNotFoundException(email);
}
if (!user.getActivated()) {
throw new UserNotActivatedException();
}
user.setResetKey(UserUtils.generateResetKey());
user.setResetDate(new Date());
user = userRepository.save(user);
try {
mailService.sendPasswordResetMail(user);
} catch (MessagingException | MailException e) {
throw new UserSendingMailException(email);
}
log.debug("Created Reset Password Request for User: {}", user.getLogin());
return true;
}
public boolean completeUserPasswordReset(UserResetPasswordDto userResetPasswordDto) {
if (!userResetPasswordDto.isPasswordsValid()) {
throw new UserPasswordsNotValidOrNotMatchException("Пароли не совпадают");
}
User user = userRepository.findOneByResetKey(userResetPasswordDto.getResetKey());
if (user == null) {
throw new UserResetKeyError(userResetPasswordDto.getResetKey());
}
user.setPassword(passwordEncoder.encode(userResetPasswordDto.getPassword()));
user.setResetKey(null);
user.setResetDate(null);
user = userRepository.save(user);
mailService.sendChangePasswordMail(user);
log.debug("Reset Password for User: {}", user.getLogin());
return true;
}
public UserDto deleteUser(Integer userId) {
final User user = userRepository.getOne(userId);
if (user == null) {
throw new UserNotFoundException(userId.toString());
}
if (applicationProperties.getUndeadUserLogin().equalsIgnoreCase(user.getLogin())) {
throw new UserIsUndeadException(user.getLogin());
}
userRepository.delete(user);
log.debug("Deleted User: {}", user.getLogin());
return userMapper.userEntityToUserDto(user);
}
@Override
public UserDetails loadUserByUsername(String username) {
final User user = userRepository.findOneByLoginIgnoreCase(username);
if (user == null) {
throw new UserNotFoundException(username);
}
if (!user.getActivated()) {
throw new UserNotActivatedException();
}
if (user.getBlocker() != null) {
throw new UserBlockedException(String.format("Вы заблокированы пользователем %s", user.getBlocker().getUserAbbreviate()));
}
return new org.springframework.security.core.userdetails.User(user.getLogin(),
user.getPassword(),
Optional.ofNullable(user.getRoles()).orElse(Collections.emptySet()).stream()
.map(role -> new SimpleGrantedAuthority(role.getName()))
.collect(Collectors.toList()));
}
public List<User> findByIds(List<Integer> ids) {
return userRepository.findAllById(ids);
}
public User findById(Integer id) {
return userRepository.getOne(id);
}
public User getCurrentUser() {
String login = UserUtils.getCurrentUserLogin(SecurityContextHolder.getContext());
User user = userRepository.findOneByLoginIgnoreCase(login);
if (user == null) {
throw new UserNotFoundException(login);
}
return user;
}
public List<User> filterByAgeAndDegree(boolean hasDegree, boolean hasAge) {
return userRepository.filterByAgeAndDegree(hasDegree, hasAge);
}
public void inviteUser(String email) throws UserSendingMailException {
if (userRepository.findOneByEmailIgnoreCase(email) != null) {
throw new UserEmailExistsException(email);
}
String password = UserUtils.generatePassword();
User user = new User();
user.setPassword(passwordEncoder.encode(password));
user.setLogin(email);
user.setEmail(email);
user.setFirstName("user");
user.setLastName("user");
user.setActivated(true);
userRepository.save(user);
Map<String, Object> variables = ImmutableMap.of("password", password, "email", email);
try {
mailService.sendInviteMail(variables, email);
} catch (MessagingException | MailException e) {
throw new UserSendingMailException(email);
}
}
public User findOneByLoginIgnoreCase(String login) {
return userRepository.findOneByLoginIgnoreCase(login);
}
public Map<String, Object> getUsersInfo() {
List<UserInfoNow> usersInfoNow = new ArrayList<>();
String err = "";
for (User user : userRepository.findAll()) {
Lesson lesson = null;
try {
lesson = timetableService.getCurrentLesson(user.getUserAbbreviate());
} catch (TimetableClientException e) {
err = "Не удалось загрузить расписание";
}
usersInfoNow.add(new UserInfoNow(
lesson,
conferenceService.getActiveConferenceByUser(user),
user,
userSessionService.isOnline(user))
);
}
return ImmutableMap.of("users", usersInfoNow, "error", err);
}
public Map<String, Integer> getActivitiesPings(Integer userId,
String activityName) {
User user = null;
if (userId != null) {
user = findById(userId);
}
Map<String, Integer> activitiesPings = new HashMap<>();
for (Ping ping : pingService.getPings(activityName)) {
UserActivity activity = ping.getActivity();
if (user != null && !activity.getActivityUsers().contains(user)) {
continue;
}
if (activitiesPings.containsKey(activity.getTitle())) {
activitiesPings.put(activity.getTitle(), activitiesPings.get(activity.getTitle()) + 1);
} else {
activitiesPings.put(activity.getTitle(), 1);
}
}
return activitiesPings;
}
public void blockUser(int userId) {
User userToBlock = findById(userId);
userToBlock.setBlocker(getCurrentUser());
userRepository.save(userToBlock);
}
}
package ru.ulstu.user.service;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.mail.MailException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.configuration.ApplicationProperties;
import ru.ulstu.core.error.EntityIdIsNullException;
import ru.ulstu.core.jpa.OffsetablePageRequest;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.core.model.UserActivity;
import ru.ulstu.core.model.response.PageableItems;
import ru.ulstu.ping.model.Ping;
import ru.ulstu.ping.service.PingService;
import ru.ulstu.user.error.UserActivationError;
import ru.ulstu.user.error.UserBlockedException;
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.model.User;
import ru.ulstu.user.model.UserDto;
import ru.ulstu.user.model.UserInfoNow;
import ru.ulstu.user.model.UserListDto;
import ru.ulstu.user.model.UserResetPasswordDto;
import ru.ulstu.user.model.UserRole;
import ru.ulstu.user.model.UserRoleConstants;
import ru.ulstu.user.model.UserRoleDto;
import ru.ulstu.user.repository.UserRepository;
import ru.ulstu.user.repository.UserRoleRepository;
import ru.ulstu.user.util.UserUtils;
import ru.ulstu.utils.timetable.TimetableService;
import ru.ulstu.utils.timetable.errors.TimetableClientException;
import ru.ulstu.utils.timetable.model.Lesson;
import javax.mail.MessagingException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@Transactional
public class UserService implements UserDetailsService {
private static final String INVITE_USER_EXCEPTION = "Во время отправки приглашения произошла ошибка";
private final Logger log = LoggerFactory.getLogger(UserService.class);
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final UserRoleRepository userRoleRepository;
private final UserMapper userMapper;
private final MailService mailService;
private final ApplicationProperties applicationProperties;
private final TimetableService timetableService;
private final ConferenceService conferenceService;
private final UserSessionService userSessionService;
private final PingService pingService;
public UserService(UserRepository userRepository,
PasswordEncoder passwordEncoder,
UserRoleRepository userRoleRepository,
UserMapper userMapper,
MailService mailService,
ApplicationProperties applicationProperties,
@Lazy PingService pingService,
@Lazy ConferenceService conferenceRepository,
@Lazy UserSessionService userSessionService) throws ParseException {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.userRoleRepository = userRoleRepository;
this.userMapper = userMapper;
this.mailService = mailService;
this.applicationProperties = applicationProperties;
this.conferenceService = conferenceRepository;
this.timetableService = new TimetableService();
this.userSessionService = userSessionService;
this.pingService = pingService;
}
private User getUserByEmail(String email) {
return userRepository.findOneByEmailIgnoreCase(email);
}
private User getUserByActivationKey(String activationKey) {
return userRepository.findOneByActivationKey(activationKey);
}
public User getUserByLogin(String login) {
return userRepository.findOneByLoginIgnoreCase(login);
}
@Transactional(readOnly = true)
public UserDto getUserWithRolesById(Integer userId) {
final User userEntity = userRepository.findOneWithRolesById(userId);
if (userEntity == null) {
throw new UserNotFoundException(userId.toString());
}
return userMapper.userEntityToUserDto(userEntity);
}
@Transactional(readOnly = true)
public PageableItems<UserListDto> getAllUsers(int offset, int count) {
final Page<User> page = userRepository.findAll(new OffsetablePageRequest(offset, count, Sort.by("id")));
return new PageableItems<>(page.getTotalElements(), userMapper.userEntitiesToUserListDtos(page.getContent()));
}
// TODO: read only active users
public List<User> findAll() {
return userRepository.findAll();
}
@Transactional(readOnly = true)
public PageableItems<UserRoleDto> getUserRoles() {
final List<UserRoleDto> roles = userRoleRepository.findAll().stream()
.map(UserRoleDto::new)
.sorted(Comparator.comparing(UserRoleDto::getViewValue))
.collect(Collectors.toList());
return new PageableItems<>(roles.size(), roles);
}
public UserDto createUser(UserDto userDto) {
if (userDto.getId() != null) {
throw new UserIdExistsException();
}
if (getUserByLogin(userDto.getLogin()) != null) {
throw new UserLoginExistsException(userDto.getLogin());
}
if (getUserByEmail(userDto.getEmail()) != null) {
throw new UserEmailExistsException(userDto.getEmail());
}
if (userDto.isPasswordsValid()) {
throw new UserPasswordsNotValidOrNotMatchException("");
}
User user = userMapper.userDtoToUserEntity(userDto);
user.setActivated(false);
user.setActivationKey(UserUtils.generateActivationKey());
user.setRoles(Collections.singleton(new UserRole(UserRoleConstants.USER)));
user.setPassword(passwordEncoder.encode(userDto.getPassword()));
user = userRepository.save(user);
mailService.sendActivationEmail(user);
log.debug("Created Information for User: {}", user.getLogin());
return userMapper.userEntityToUserDto(user);
}
public UserDto activateUser(String activationKey) {
final User user = getUserByActivationKey(activationKey);
if (user == null) {
throw new UserActivationError(activationKey);
}
user.setActivated(true);
user.setActivationKey(null);
user.setActivationDate(null);
log.debug("Activated user: {}", user.getLogin());
return userMapper.userEntityToUserDto(userRepository.save(user));
}
public UserDto updateUser(UserDto userDto) {
if (userDto.getId() == null) {
throw new EntityIdIsNullException();
}
if (!Objects.equals(
Optional.ofNullable(getUserByEmail(userDto.getEmail()))
.map(BaseEntity::getId).orElse(userDto.getId()),
userDto.getId())) {
throw new UserEmailExistsException(userDto.getEmail());
}
if (!Objects.equals(
Optional.ofNullable(getUserByLogin(userDto.getLogin()))
.map(BaseEntity::getId).orElse(userDto.getId()),
userDto.getId())) {
throw new UserLoginExistsException(userDto.getLogin());
}
User user = userRepository.getOne(userDto.getId());
if (user == null) {
throw new UserNotFoundException(userDto.getId().toString());
}
if (applicationProperties.getUndeadUserLogin().equalsIgnoreCase(user.getLogin())) {
userDto.setLogin(applicationProperties.getUndeadUserLogin());
userDto.setActivated(true);
userDto.setRoles(Collections.singletonList(new UserRoleDto(UserRoleConstants.ADMIN)));
}
user.setLogin(userDto.getLogin());
user.setFirstName(userDto.getFirstName());
user.setLastName(userDto.getLastName());
user.setEmail(userDto.getEmail());
if (userDto.isActivated() != user.getActivated()) {
if (userDto.isActivated()) {
user.setActivationKey(null);
user.setActivationDate(null);
} else {
user.setActivationKey(UserUtils.generateActivationKey());
user.setActivationDate(new Date());
}
}
user.setActivated(userDto.isActivated());
final Set<UserRole> roles = userMapper.rolesFromDto(userDto.getRoles());
user.setRoles(roles.isEmpty()
? Collections.singleton(new UserRole(UserRoleConstants.USER))
: roles);
if (!StringUtils.isEmpty(userDto.getOldPassword())) {
if (userDto.isPasswordsValid() || !userDto.isOldPasswordValid()) {
throw new UserPasswordsNotValidOrNotMatchException("");
}
if (!passwordEncoder.matches(userDto.getOldPassword(), user.getPassword())) {
throw new UserPasswordsNotValidOrNotMatchException("");
}
user.setPassword(passwordEncoder.encode(userDto.getPassword()));
log.debug("Changed password for User: {}", user.getLogin());
}
user = userRepository.save(user);
log.debug("Changed Information for User: {}", user.getLogin());
return userMapper.userEntityToUserDto(user);
}
public User updateUserInformation(User user) {
return userRepository.save(user);
}
public UserDto updateUserInformation(User user, UserDto updateUser) {
user.setFirstName(updateUser.getFirstName());
user.setLastName(updateUser.getLastName());
user.setEmail(updateUser.getEmail());
user.setLogin(updateUser.getLogin());
user = updateUserInformation(user);
log.debug("Updated Information for User: {}", user.getLogin());
return userMapper.userEntityToUserDto(user);
}
public void changeUserPassword(User user, Map<String, String> payload) {
if (!payload.get("password").equals(payload.get("confirmPassword"))) {
throw new UserPasswordsNotValidOrNotMatchException("");
}
if (!passwordEncoder.matches(payload.get("oldPassword"), user.getPassword())) {
throw new UserPasswordsNotValidOrNotMatchException("Старый пароль введен неправильно");
}
user.setPassword(passwordEncoder.encode(payload.get("password")));
log.debug("Changed password for User: {}", user.getLogin());
userRepository.save(user);
mailService.sendChangePasswordMail(user);
}
public boolean requestUserPasswordReset(String email) {
User user = userRepository.findOneByEmailIgnoreCase(email);
if (user == null) {
throw new UserNotFoundException(email);
}
if (!user.getActivated()) {
throw new UserNotActivatedException();
}
user.setResetKey(UserUtils.generateResetKey());
user.setResetDate(new Date());
user = userRepository.save(user);
try {
mailService.sendPasswordResetMail(user);
} catch (MessagingException | MailException e) {
throw new UserSendingMailException(email);
}
log.debug("Created Reset Password Request for User: {}", user.getLogin());
return true;
}
public boolean completeUserPasswordReset(UserResetPasswordDto userResetPasswordDto) {
if (!userResetPasswordDto.isPasswordsValid()) {
throw new UserPasswordsNotValidOrNotMatchException("Пароли не совпадают");
}
User user = userRepository.findOneByResetKey(userResetPasswordDto.getResetKey());
if (user == null) {
throw new UserResetKeyError(userResetPasswordDto.getResetKey());
}
user.setPassword(passwordEncoder.encode(userResetPasswordDto.getPassword()));
user.setResetKey(null);
user.setResetDate(null);
user = userRepository.save(user);
mailService.sendChangePasswordMail(user);
log.debug("Reset Password for User: {}", user.getLogin());
return true;
}
public UserDto deleteUser(Integer userId) {
final User user = userRepository.getOne(userId);
if (user == null) {
throw new UserNotFoundException(userId.toString());
}
if (applicationProperties.getUndeadUserLogin().equalsIgnoreCase(user.getLogin())) {
throw new UserIsUndeadException(user.getLogin());
}
userRepository.delete(user);
log.debug("Deleted User: {}", user.getLogin());
return userMapper.userEntityToUserDto(user);
}
@Override
public UserDetails loadUserByUsername(String username) {
final User user = userRepository.findOneByLoginIgnoreCase(username);
if (user == null) {
throw new UserNotFoundException(username);
}
if (!user.getActivated()) {
throw new UserNotActivatedException();
}
if (user.getBlocker() != null) {
throw new UserBlockedException(String.format("Вы заблокированы пользователем %s", user.getBlocker().getUserAbbreviate()));
}
return new org.springframework.security.core.userdetails.User(user.getLogin(),
user.getPassword(),
Optional.ofNullable(user.getRoles()).orElse(Collections.emptySet()).stream()
.map(role -> new SimpleGrantedAuthority(role.getName()))
.collect(Collectors.toList()));
}
public List<User> findByIds(List<Integer> ids) {
return userRepository.findAllById(ids);
}
public User findById(Integer id) {
return userRepository.getOne(id);
}
public User getCurrentUser() {
String loginOrEmail = UserUtils.getCurrentUserLoginOrEmail(SecurityContextHolder.getContext());
User user = userRepository.findOneByLoginIgnoreCase(loginOrEmail);
if (user == null) {
user = userRepository.findOneByEmailIgnoreCase(loginOrEmail);
}
if (user == null) {
throw new UserNotFoundException(loginOrEmail);
}
return user;
}
public List<User> filterByAgeAndDegree(boolean hasDegree, boolean hasAge) {
return userRepository.filterByAgeAndDegree(hasDegree, hasAge);
}
public void inviteUser(String email) throws UserSendingMailException {
if (userRepository.findOneByEmailIgnoreCase(email) != null) {
throw new UserEmailExistsException(email);
}
String password = UserUtils.generatePassword();
User user = new User();
user.setPassword(passwordEncoder.encode(password));
user.setLogin(email);
user.setEmail(email);
user.setFirstName("user");
user.setLastName("user");
user.setActivated(true);
userRepository.save(user);
Map<String, Object> variables = ImmutableMap.of("password", password, "email", email);
try {
mailService.sendInviteMail(variables, email);
} catch (MessagingException | MailException e) {
throw new UserSendingMailException(email);
}
}
public User findOneByLoginIgnoreCase(String login) {
return userRepository.findOneByLoginIgnoreCase(login);
}
public Map<String, Object> getUsersInfo() {
List<UserInfoNow> usersInfoNow = new ArrayList<>();
String err = "";
for (User user : userRepository.findAll()) {
Lesson lesson = null;
try {
lesson = timetableService.getCurrentLesson(user.getUserAbbreviate());
} catch (TimetableClientException e) {
err = "Не удалось загрузить расписание";
}
usersInfoNow.add(new UserInfoNow(
lesson,
conferenceService.getActiveConferenceByUser(user),
user,
userSessionService.isOnline(user))
);
}
return ImmutableMap.of("users", usersInfoNow, "error", err);
}
public Map<String, Integer> getActivitiesPings(Integer userId,
String activityName) {
User user = null;
if (userId != null) {
user = findById(userId);
}
Map<String, Integer> activitiesPings = new HashMap<>();
for (Ping ping : pingService.getPings(activityName)) {
UserActivity activity = ping.getActivity();
if (user != null && !activity.getActivityUsers().contains(user)) {
continue;
}
if (activitiesPings.containsKey(activity.getTitle())) {
activitiesPings.put(activity.getTitle(), activitiesPings.get(activity.getTitle()) + 1);
} else {
activitiesPings.put(activity.getTitle(), 1);
}
}
return activitiesPings;
}
public void blockUser(int userId) {
User userToBlock = findById(userId);
userToBlock.setBlocker(getCurrentUser());
userRepository.save(userToBlock);
}
}

View File

@ -4,6 +4,7 @@ import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import ru.ulstu.configuration.Constants;
public class UserUtils {
@ -17,7 +18,7 @@ public class UserUtils {
return RandomStringUtils.randomNumeric(DEF_COUNT);
}
public static String getCurrentUserLogin(SecurityContext securityContext) {
public static String getCurrentUserLoginOrEmail(SecurityContext securityContext) {
if (securityContext == null) {
return null;
}
@ -27,6 +28,10 @@ public class UserUtils {
final UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
return springSecurityUser.getUsername();
}
if (authentication.getPrincipal() instanceof DefaultOidcUser) {
final DefaultOidcUser oauth2User = (DefaultOidcUser) authentication.getPrincipal();
return oauth2User.getEmail();
}
if (authentication.getPrincipal() instanceof String) {
return (String) authentication.getPrincipal();
}

View File

@ -0,0 +1,113 @@
<!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:calendar id="bDate" required="true" value="#{userView.user.birthDate}"/>
<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

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

@ -0,0 +1,51 @@
<?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: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

@ -0,0 +1,35 @@
/* 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

@ -0,0 +1,17 @@
/* 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

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

@ -0,0 +1,251 @@
/* 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

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

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

@ -0,0 +1,23 @@
<!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/styles.css"/>
</h:head>
<h:body>
<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

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

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

View File

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

View File

@ -0,0 +1,20 @@
<!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="/paper/papers.xhtml">
<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

@ -0,0 +1,61 @@
<?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>
</tr>
</tbody>
</table>
</p:panel>
</form>
</div>
<div class="ui-g-5"></div>
</div>
</h:body>
</html>

View File

@ -0,0 +1,91 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition template="/basicTemplate.xhtml">
<ui:define name="content">
<style>
.ui-datatable .ui-datatable-header {
text-align: right !important;
}
</style>
<p:panel id="panel" header="Активные статьи пользователя #{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: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

@ -0,0 +1,165 @@
<!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:link href="/conference/conferenceList.xhtml?id=paperView.paper.conferences[0].id"
value="Статья участвует в конференции"
rendered="#{not empty paperView.paper.conferences}"/>
<p:commandButton value="Привязать к конференции"
rendered="#{empty paperView.paper.conferences}"
disabled="true"/>
</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-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

@ -0,0 +1,10 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://java.sun.com/jsf/html">
<span class="fa-stack fa-1x big-icon" title="#{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

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition template="/basicTemplate.xhtml">
<ui:define name="content">
<style>
.ui-datatable .ui-datatable-header {
text-align: right !important;
}
</style>
<p:panel id="panel" header="Все статьи" style="margin-bottom:10px;">
<div class="ui-fluid">
<div class="ui-g">
<div class="ui-md-5 ui-g-12">
<p:inputText placeholder="Создать новую статью" id="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: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

@ -1,7 +1,8 @@
# Server Settings
spring.main.banner-mode=off
server.port=8443
server.http.port=8080
server.port=8080
server.http.port=8443
server.ssl.enabled=false
multipart.maxFileSize=20MB
multipart.maxRequestSize=20MB
# Thymeleaf Settings
@ -14,6 +15,11 @@ server.ssl.key-password=password
logging.level.ru.ulstu=DEBUG
#HtmlUnit
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
spring.mail.host=smtp.yandex.ru
spring.mail.port=465
@ -35,8 +41,10 @@ spring.liquibase.enabled=true
# Application Settings
ng-tracker.base-url=http://127.0.0.1:8080
ng-tracker.undead-user-login=admin
ng-tracker.dev-mode=true
ng-tracker.debug_email=
ng-tracker.dev-mode=false
ng-tracker.debug_email=romanov73@gmail.com
ng-tracker.use-https=false
ng-tracker.check-run=false
ng-tracker.driver-path=
spring.security.oauth2.client.registration.google.client-id=128435862215-4ltm7dr6enb6sfll0qhkt6a1op9juve6.apps.googleusercontent.com
spring.security.oauth2.client.registration.google.client-secret=W_B-KMpqsSdKahqFxpuK4OoT

View File

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{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

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{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

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{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,14 @@
</div>
</fieldset>
</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>
</section>
</div>
</body>
</html>
</html>

View File

@ -1,230 +0,0 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import conference.ConferencePage;
import conference.ConferencesDashboardPage;
import conference.ConferencesPage;
import core.PageObject;
import core.TestTemplate;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import ru.ulstu.NgTrackerApplication;
import ru.ulstu.configuration.ApplicationProperties;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@SpringBootTest(classes = NgTrackerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class ConferenceTest extends TestTemplate {
private final Map<PageObject, List<String>> navigationHolder = ImmutableMap.of(
new ConferencesPage(), Arrays.asList("КОНФЕРЕНЦИИ", "/conferences/conferences"),
new ConferencePage(), Arrays.asList("РЕДАКТИРОВАНИЕ КОНФЕРЕНЦИИ", "/conferences/conference?id=0"),
new ConferencesDashboardPage(), Arrays.asList("АКТУАЛЬНЫЕ КОНФЕРЕНЦИИ", "/conferences/dashboard")
);
@Autowired
private ApplicationProperties applicationProperties;
@Test
public void testACreateNewConference() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 1);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencePage conferencePage = (ConferencePage) getContext().initPage(page.getKey());
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 0).getKey());
String newConferenceName = "test " + (new Date()).getTime();
conferencePage.setName(newConferenceName);
conferencePage.clickSaveBut();
Assert.assertTrue(conferencesPage.checkNameInList(newConferenceName));
}
@Test
public void testBChangeConferenceNameAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String newConferenceName = "test " + (new Date()).getTime();
conferencePage.clearName();
conferencePage.setName(newConferenceName);
conferencePage.clickSaveBut();
Assert.assertTrue(conferencesPage.checkNameInList(newConferenceName));
}
@Test
public void testCAddDeadlineAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer deadlineCount = conferencePage.getDeadlineCount();
String description = "test";
String date = "09.09.2019";
String dateValue = "2019-09-09";
conferencePage.clickAddDeadlineBut();
conferencePage.setDeadlineDescription(description, deadlineCount);
conferencePage.setDeadlineDate(date, deadlineCount);
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertTrue(conferencePage.checkDeadline(description, dateValue));
}
@Test
public void testDTakePartAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer membersCount = conferencePage.getMemberCount();
conferencePage.clickTakePartBut();
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertTrue(membersCount + 1 == conferencePage.getMemberCount()
&& conferencePage.isTakePartButDisabledValueTrue());
}
@Test
public void testEDeleteDeadlineAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer deadlineCount = conferencePage.getDeadlineCount();
conferencePage.clickDeleteDeadlineBut();
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertEquals(deadlineCount - 1, (int) conferencePage.getDeadlineCount());
}
@Test
public void testFAttachArticle() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer paperCount = conferencePage.getArticlesCount();
conferencePage.showAllowToAttachArticles();
WebElement paper = conferencePage.selectArticle();
String paperName = paper.findElement(By.className("text")).getText();
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertTrue(paperCount + 1 == conferencePage.getArticlesCount()
&& conferencePage.checkArticle(paperName));
}
@Test
public void testGAddArticle() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer paperCount = conferencePage.getArticlesCount();
conferencePage.clickAddPaperBut();
List<WebElement> webElements = conferencePage.getArticles();
String paperName = webElements.get(webElements.size() - 1).findElements(By.tagName("input")).get(1).getAttribute("value");
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertTrue(paperCount + 1 == conferencePage.getArticlesCount()
&& conferencePage.checkArticle(paperName));
}
@Test
public void testHUndockArticle() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer paperCount = conferencePage.getArticlesCount();
conferencePage.clickUndockArticleBut();
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertEquals(paperCount - 1, (int) conferencePage.getArticlesCount());
}
@Test
public void testISortAndFilterConferenceList() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
conferencesPage.selectMember();
conferencesPage.selectYear();
Assert.assertEquals(1, conferencesPage.getConferencesList().size());
}
@Test
public void testJDeleteConf() throws InterruptedException {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
Integer size = conferencesPage.getConferencesList().size();
conferencesPage.deleteFirst();
Thread.sleep(3000);
conferencesPage.clickConfirm();
Assert.assertEquals(size - 1, conferencesPage.getConferencesList().size());
}
}

View File

@ -1,225 +0,0 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import core.PageObject;
import core.TestTemplate;
import grant.GrantPage;
import grant.GrantsDashboardPage;
import grant.GrantsPage;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.openqa.selenium.WebElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import ru.ulstu.NgTrackerApplication;
import ru.ulstu.configuration.ApplicationProperties;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@SpringBootTest(classes = NgTrackerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class GrantTest extends TestTemplate {
private final Map<PageObject, List<String>> navigationHolder = ImmutableMap.of(
new GrantsPage(), Arrays.asList("ГРАНТЫ", "/grants/grants"),
new GrantPage(), Arrays.asList("РЕДАКТИРОВАНИЕ ГРАНТА", "/grants/grant?id=0"),
new GrantsDashboardPage(), Arrays.asList("Гранты", "/grants/dashboard")
);
@Autowired
private ApplicationProperties applicationProperties;
@Test
public void aCreateNewGrant() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 1);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantPage grantPage = (GrantPage) getContext().initPage(page.getKey());
GrantsPage grantsPage = (GrantsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 0).getKey());
String newGrantName = "test grant" + (new Date());
grantPage.setTitle(newGrantName);
String deadlineDate = new Date().toString();
String deadlineDescription = "test deadline description";
grantPage.setDeadline(deadlineDate, 0, deadlineDescription);
grantPage.setLeader();
grantPage.saveGrant();
Assert.assertTrue(grantsPage.findGrantByTitle(newGrantName));
}
@Test
public void bCreateBlankGrant() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 1);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantPage grantPage = (GrantPage) getContext().initPage(page.getKey());
grantPage.saveGrant();
Assert.assertTrue(grantPage.checkBlankFields());
}
@Test
public void cUpdateGrantTitle() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantsPage grantsPage = (GrantsPage) getContext().initPage(page.getKey());
GrantPage grantPage = (GrantPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
grantsPage.getFirstGrant();
String newGrantTitle = "test " + (new Date());
grantPage.setTitle(newGrantTitle);
grantPage.saveGrant();
Assert.assertTrue(grantsPage.findGrantByTitle(newGrantTitle));
}
@Test
public void dAttachPaper() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantsPage grantsPage = (GrantsPage) getContext().initPage(page.getKey());
GrantPage grantPage = (GrantPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
grantsPage.getFirstGrant();
Integer countPapers = grantPage.getAttachedPapers().size();
Assert.assertEquals(countPapers + 1, grantPage.attachPaper().size());
}
@Test
public void eDeletePaper() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantsPage grantsPage = (GrantsPage) getContext().initPage(page.getKey());
GrantPage grantPage = (GrantPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
grantsPage.getFirstGrant();
Integer oldCountPapers = grantPage.getAttachedPapers().size();
if (oldCountPapers == 0) {
oldCountPapers = grantPage.attachPaper().size();
}
Assert.assertEquals(oldCountPapers - 1, grantPage.deletePaper().size());
}
@Test
public void fAddDeadline() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantsPage grantsPage = (GrantsPage) getContext().initPage(page.getKey());
GrantPage grantPage = (GrantPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
grantsPage.getFirstGrant();
String grantId = grantPage.getId();
Integer deadlineCount = grantPage.getDeadlineCount();
String description = "deadline test";
String date = "08.08.2019";
String dateValue = "2019-08-08";
grantPage.addDeadline();
grantPage.setDeadline(date, deadlineCount, description);
grantPage.saveGrant();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/grants/grant?id=%s", grantId));
Assert.assertTrue(grantPage.checkDeadline(description, dateValue));
}
@Test
public void gDeleteDeadline() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantsPage grantsPage = (GrantsPage) getContext().initPage(page.getKey());
GrantPage grantPage = (GrantPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
grantsPage.getFirstGrant();
String grantId = grantPage.getId();
Integer deadlineCount = grantPage.getDeadlineCount();
grantPage.deleteDeadline();
grantPage.saveGrant();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/grants/grant?id=%s", grantId));
Integer newDeadlineCount = grantPage.getDeadlineCount();
Assert.assertEquals(deadlineCount - 1, (int) newDeadlineCount);
}
@Test
public void hAddAuthor() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantsPage grantsPage = (GrantsPage) getContext().initPage(page.getKey());
GrantPage grantPage = (GrantPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
WebElement grant = grantsPage.getFirstGrantWithoutClick();
String grantTitle = grantsPage.getGrantTitle(grant);
Integer authorsCount = grantsPage.getAuthorsCount(grant);
grantsPage.getFirstGrant();
grantPage.addAuthor();
grantPage.saveGrant();
grant = grantsPage.getGrantByTitle(grantTitle);
Integer newAuthorsCount = grantsPage.getAuthorsCount(grant);
Assert.assertEquals(authorsCount + 1, (int) newAuthorsCount);
}
@Test
public void iDeleteAuthor() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantsPage grantsPage = (GrantsPage) getContext().initPage(page.getKey());
GrantPage grantPage = (GrantPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
WebElement grant = grantsPage.getFirstGrantWithoutClick();
String grantTitle = grantsPage.getGrantTitle(grant);
Integer authorsCount = grantsPage.getAuthorsCount(grant);
grantsPage.getFirstGrant();
grantPage.deleteAuthor();
grantPage.saveGrant();
grant = grantsPage.getGrantByTitle(grantTitle);
Integer newAuthorsCount = grantsPage.getAuthorsCount(grant);
authorsCount = (authorsCount == 0) ? 0 : authorsCount - 1;
Assert.assertEquals((int) authorsCount, (int) newAuthorsCount);
}
@Test
public void jUpdateGrantDescription() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantsPage grantsPage = (GrantsPage) getContext().initPage(page.getKey());
GrantPage grantPage = (GrantPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
String description = "newDescriptionForGrant";
grantsPage.getFirstGrant();
String grantId = grantPage.getId();
grantPage.setDescription(description);
grantPage.saveGrant();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/grants/grant?id=%s", grantId));
Assert.assertTrue(description.equals(grantPage.getDescription()));
}
@Test
public void kDeleteGrant() throws InterruptedException {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
GrantsPage grantsPage = (GrantsPage) getContext().initPage(page.getKey());
Integer size = grantsPage.getGrantsList().size();
grantsPage.deleteFirst();
Assert.assertEquals(size - 1, grantsPage.getGrantsList().size());
}
}

View File

@ -1,52 +0,0 @@
import com.google.common.collect.ImmutableMap;
import core.PageObject;
import core.TestTemplate;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import paper.PaperPage;
import paper.PapersDashboardPage;
import paper.PapersPage;
import ru.ulstu.NgTrackerApplication;
import ru.ulstu.configuration.ApplicationProperties;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = NgTrackerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class IndexPageTest extends TestTemplate {
private final Map<PageObject, List<String>> navigationHolder = ImmutableMap.of(
new PapersPage(), Arrays.asList("СТАТЬИ", "/papers/papers"),
new PaperPage(), Arrays.asList("РЕДАКТИРОВАНИЕ СТАТЬИ", "/papers/paper?id=0"),
new PapersDashboardPage(), Arrays.asList("СТАТЬИ", "/papers/dashboard")
);
@Autowired
private ApplicationProperties applicationProperties;
@Test
public void testStartApplication() {
getContext().goTo(applicationProperties.getBaseUrl());
Assertions
.assertThat(getContext().getTitle())
.isEqualTo("NG-Tracker");
}
@Test
public void testModulesNavigation() {
navigationHolder.entrySet()
.stream()
.forEach(navigationEntry -> {
getContext().goTo(applicationProperties.getBaseUrl() + navigationEntry.getValue().get(1));
PageObject pageObject = getContext().initPage(navigationEntry.getKey());
Assertions
.assertThat(pageObject.getSubTitle())
.isEqualToIgnoringCase(navigationEntry.getValue().get(0));
});
}
}

View File

@ -1,247 +0,0 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import core.PageObject;
import core.TestTemplate;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import paper.PaperPage;
import paper.PapersDashboardPage;
import paper.PapersPage;
import ru.ulstu.NgTrackerApplication;
import ru.ulstu.configuration.ApplicationProperties;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@SpringBootTest(classes = NgTrackerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class PaperTest extends TestTemplate {
private final Map<PageObject, List<String>> navigationHolder = ImmutableMap.of(
new PapersPage(), Arrays.asList("СТАТЬИ", "/papers/papers"),
new PaperPage(), Arrays.asList("РЕДАКТИРОВАНИЕ СТАТЬИ", "/papers/paper?id=0"),
new PapersDashboardPage(), Arrays.asList("СТАТЬИ", "/papers/dashboard")
);
@Autowired
private ApplicationProperties applicationProperties;
private String getPaperPageUrl() {
return Iterables.get(navigationHolder.entrySet(), 1).getValue().get(1);
}
private PaperPage getPaperPage() {
PaperPage paperPage = (PaperPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
paperPage.initElements();
return paperPage;
}
private String getPapersPageUrl() {
return Iterables.get(navigationHolder.entrySet(), 0).getValue().get(1);
}
private PapersPage getPapersPage() {
PapersPage papersPage = (PapersPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 0).getKey());
papersPage.initElements();
return papersPage;
}
private String getPapersDashboardPageUrl() {
return Iterables.get(navigationHolder.entrySet(), 2).getValue().get(1);
}
private PapersDashboardPage getPapersDashboardPage() {
PapersDashboardPage papersDashboardPage = (PapersDashboardPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 2).getKey());
papersDashboardPage.initElements();
return papersDashboardPage;
}
@Test
public void createNewPaperTest() {
getContext().goTo(applicationProperties.getBaseUrl() + getPaperPageUrl());
PaperPage paperPage = getPaperPage();
String testTitle = "test " + System.currentTimeMillis();
fillRequiredFields(paperPage, testTitle);
paperPage.clickSaveBtn();
PapersPage papersPage = getPapersPage();
Assert.assertTrue(papersPage.havePaperWithTitle(testTitle));
}
@Test
public void editPaperTest() {
createNewPaper();
getContext().goTo(applicationProperties.getBaseUrl() + getPapersPageUrl());
PapersPage papersPage = getPapersPage();
papersPage.clickFirstPaper();
PaperPage paperPage = getPaperPage();
String testTitle = "test " + System.currentTimeMillis();
paperPage.setTitle(testTitle);
paperPage.clickSaveBtn();
Assert.assertTrue(papersPage.havePaperWithTitle(testTitle));
}
private void createNewPaper() {
getContext().goTo(applicationProperties.getBaseUrl() + getPaperPageUrl());
PaperPage paperPage = getPaperPage();
String testTitle = "test " + System.currentTimeMillis();
fillRequiredFields(paperPage, testTitle);
paperPage.clickSaveBtn();
}
@Test
public void addDeadlineTest() {
createNewPaper();
getContext().goTo(applicationProperties.getBaseUrl() + getPapersPageUrl());
PapersPage papersPage = getPapersPage();
papersPage.clickFirstPaper();
PaperPage paperPage = getPaperPage();
papersPage.clickAddDeadline();
String testDate = "01.01.2019";
String testDateResult = "2019-01-01";
String testDesc = "desc";
Integer deadlineNumber = 2;
paperPage.setDeadlineDate(deadlineNumber, testDate);
paperPage.setDeadlineDescription(deadlineNumber, testDesc);
String paperId = paperPage.getId();
paperPage.clickSaveBtn();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/papers/paper?id=%s", paperId));
Assert.assertTrue(paperPage.deadlineExist(testDesc, testDateResult));
}
@Test
public void noDeadlinesValidationTest() {
getContext().goTo(applicationProperties.getBaseUrl() + getPaperPageUrl());
PaperPage paperPage = getPaperPage();
String testTitle = "test " + System.currentTimeMillis();
paperPage.setTitle(testTitle);
paperPage.clickSaveBtn();
Assert.assertTrue(paperPage.hasAlert("Не может быть пустым"));
}
private void fillRequiredFields(PaperPage paperPage, String title) {
paperPage.setTitle(title);
String testDate = "01.01.2019";
String testDesc = "desc";
Integer deadlineNumber = 1;
paperPage.setDeadlineDate(deadlineNumber, testDate);
paperPage.setDeadlineDescription(deadlineNumber, testDesc);
}
@Test
public void addReferenceTest() {
createNewPaper();
getContext().goTo(applicationProperties.getBaseUrl() + getPapersPageUrl());
PapersPage papersPage = getPapersPage();
papersPage.clickFirstPaper();
PaperPage paperPage = getPaperPage();
fillRequiredFields(paperPage, "test " + System.currentTimeMillis());
paperPage.clickReferenceTab();
paperPage.clickAddReferenceButton();
paperPage.clickReferenceTab();
paperPage.showFirstReference();
String authors = "testAuthors";
paperPage.setFirstReferenceAuthors(authors);
String paperId = paperPage.getId();
paperPage.clickSaveBtn();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/papers/paper?id=%s", paperId));
Assert.assertTrue(paperPage.authorsExists(authors));
}
@Test
public void referencesFormatTest() {
getContext().goTo(applicationProperties.getBaseUrl() + getPaperPageUrl());
PaperPage paperPage = getPaperPage();
paperPage.setTitle("test");
paperPage.clickReferenceTab();
paperPage.clickAddReferenceButton();
paperPage.clickReferenceTab();
paperPage.showFirstReference();
paperPage.setFirstReferenceAuthors("authors");
paperPage.setFirstReferencePublicationTitle("title");
paperPage.setFirstReferencePublicationYear("2010");
paperPage.setFirstReferencePublisher("publisher");
paperPage.setFirstReferencePages("200");
paperPage.setFirstReferenceJournalOrCollectionTitle("journal");
paperPage.setFormatStandardSpringer();
paperPage.clickFormatButton();
Assert.assertEquals("authors (2010) title. journal, publisher, pp 200", paperPage.getFormatString());
}
@Test
public void dashboardLinkTest() {
getContext().goTo(applicationProperties.getBaseUrl() + getPaperPageUrl());
PaperPage paperPage = getPaperPage();
fillRequiredFields(paperPage, "test " + System.currentTimeMillis());
String testLink = "http://test.com/";
paperPage.setUrl(testLink);
paperPage.clickSaveBtn();
getContext().goTo(applicationProperties.getBaseUrl() + getPapersDashboardPageUrl());
PapersDashboardPage papersDashboardPage = getPapersDashboardPage();
Assert.assertTrue(papersDashboardPage.externalLinkExists(testLink));
}
@Test
public void deletePaperTest() {
createNewPaper();
getContext().goTo(applicationProperties.getBaseUrl() + getPapersPageUrl());
PapersPage papersPage = getPapersPage();
int size = papersPage.getPapersCount();
papersPage.clickRemoveFirstPaperButton();
papersPage.clickConfirmDeleteButton();
Assert.assertEquals(size - 1, papersPage.getPapersCount());
}
@Test
public void latexValidationTest() {
getContext().goTo(applicationProperties.getBaseUrl() + getPaperPageUrl());
PaperPage paperPage = getPaperPage();
paperPage.setTitle("test");
paperPage.clickLatexTab();
paperPage.setLatexText("test");
paperPage.clickPdfButton();
Assert.assertTrue(paperPage.dangerMessageExist("Ошибка при создании PDF"));
}
@Test
public void titleValidationTest() {
getContext().goTo(applicationProperties.getBaseUrl() + getPaperPageUrl());
PaperPage paperPage = getPaperPage();
paperPage.clickSaveBtn();
Assert.assertTrue(paperPage.hasAlert("не может быть пусто"));
}
}

View File

@ -1,174 +0,0 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import core.PageObject;
import core.TestTemplate;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import project.ProjectDashboard;
import project.ProjectPage;
import project.ProjectsPage;
import ru.ulstu.NgTrackerApplication;
import ru.ulstu.configuration.ApplicationProperties;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@SpringBootTest(classes = NgTrackerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class ProjectTest extends TestTemplate {
private final Map<PageObject, List<String>> navigationHolder = ImmutableMap.of(
new ProjectPage(), Arrays.asList("ПРОЕКТЫ", "/projects/projects"),
new ProjectsPage(), Arrays.asList("РЕДАКТИРОВАНИЕ ПРОЕКТА", "/projects/project?id=0"),
new ProjectDashboard(), Arrays.asList("ПРОЕКТЫ", "/projects/dashboard")
);
@Autowired
private ApplicationProperties applicationProperties;
@Test
public void testACreateNewProject() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 1);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(page.getKey());
ProjectPage projectPage = (ProjectPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 0).getKey());
String name = "Project " + (new Date()).getTime();
String date = "01.01.2019";
Integer deadNum = projectPage.getDeadlineCount();
projectPage.setName(name);
projectPage.clickAddDeadline();
projectPage.addDeadlineDate(date, deadNum);
projectPage.clickSave();
Assert.assertTrue(projectsPage.checkNameInList(name));
}
@Test
public void testBChangeNameAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectPage projectPage = (ProjectPage) getContext().initPage(page.getKey());
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
projectsPage.getFirstProject();
String name = "Project " + (new Date()).getTime();
projectPage.clearName();
projectPage.setName(name);
projectPage.clickSave();
Assert.assertTrue(projectsPage.checkNameInList(name));
}
@Test
public void testCChangeDeadlineAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectPage projectPage = (ProjectPage) getContext().initPage(page.getKey());
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
projectsPage.getFirstProject();
String name = projectPage.getName();
String date = "01.01.2019";
Integer deadNum = projectPage.getDeadlineCount();
projectPage.addDeadlineDate(date, deadNum);
projectPage.clickSave();
Assert.assertTrue(projectsPage.checkNameInList(name));
}
@Test
public void testDSetStatusAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectPage projectPage = (ProjectPage) getContext().initPage(page.getKey());
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
projectsPage.getFirstProject();
String name = projectPage.getName();
projectPage.setStatus();
projectPage.clickSave();
Assert.assertTrue(projectsPage.checkNameInList(name));
}
@Test
public void testEAddDescriptionAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectPage projectPage = (ProjectPage) getContext().initPage(page.getKey());
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
projectsPage.getFirstProject();
String name = projectPage.getName();
String description = "Description " + (new Date()).getTime();
projectPage.addDescription(description);
projectPage.clickSave();
Assert.assertTrue(projectsPage.checkNameInList(name));
}
@Test
public void testFAddLinkAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectPage projectPage = (ProjectPage) getContext().initPage(page.getKey());
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
projectsPage.getFirstProject();
String name = projectPage.getName();
String link = "Link " + (new Date()).getTime();
projectPage.addLink(link);
projectPage.clickSave();
Assert.assertTrue(projectsPage.checkNameInList(name));
}
@Test
public void testGAddDeadlineDescriptionAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectPage projectPage = (ProjectPage) getContext().initPage(page.getKey());
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
projectsPage.getFirstProject();
String name = projectPage.getName();
String deadDesc = "Description " + (new Date()).getTime();
projectPage.addDeadlineDescription(deadDesc);
projectPage.clickSave();
Assert.assertTrue(projectsPage.checkNameInList(name));
}
@Test
public void testHSetDeadlineCompletionAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectPage projectPage = (ProjectPage) getContext().initPage(page.getKey());
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
projectsPage.getFirstProject();
String name = projectPage.getName();
projectPage.setDeadlineCompletion();
projectPage.clickSave();
Assert.assertTrue(projectsPage.checkNameInList(name));
}
@Test
public void testIDeleteDeadline() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectPage projectPage = (ProjectPage) getContext().initPage(page.getKey());
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
projectsPage.getFirstProject();
projectPage.clickDeleteDeadline();
Assert.assertTrue(projectPage.getDeadlineCount() == 0);
}
@Test
public void testJDeleteProject() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ProjectPage projectPage = (ProjectPage) getContext().initPage(page.getKey());
ProjectsPage projectsPage = (ProjectsPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
projectsPage.getFirstProject();
String name = projectPage.getName();
projectPage.clickSave();
projectsPage.deleteFirst();
projectsPage.clickConfirm();
Assert.assertFalse(projectsPage.checkNameInList(name));
}
}

View File

@ -1,214 +0,0 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import core.PageObject;
import core.TestTemplate;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import ru.ulstu.NgTrackerApplication;
import ru.ulstu.configuration.ApplicationProperties;
import students.TaskPage;
import students.TasksDashboardPage;
import students.TasksPage;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@SpringBootTest(classes = NgTrackerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class StudentTaskTest extends TestTemplate {
private final Map<PageObject, List<String>> navigationHolder = ImmutableMap.of(
new TasksPage(), Arrays.asList("Список задач", "/students/tasks"),
new TasksDashboardPage(), Arrays.asList("Панель управления", "/students/dashboard"),
new TaskPage(), Arrays.asList("Создать задачу", "/students/task?id=0")
);
private final String tag = "ATag";
@Autowired
private ApplicationProperties applicationProperties;
@Test
public void testACreateTask() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 2);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TaskPage taskPage = (TaskPage) getContext().initPage(page.getKey());
TasksPage tasksPage = (TasksPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 0).getKey());
String taskName = "Task " + (new Date()).getTime();
taskPage.setName(taskName);
taskPage.addDeadlineDate("01.01.2020", 0);
taskPage.addDeadlineDescription("Description", 0);
taskPage.save();
Assert.assertTrue(tasksPage.findTask(taskName));
}
@Test
public void testBEditTaskName() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TasksPage tasksPage = (TasksPage) getContext().initPage(page.getKey());
TaskPage taskPage = (TaskPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 2).getKey());
String taskNewName = "Task " + (new Date()).getTime();
tasksPage.goToFirstTask();
taskPage.removeName();
taskPage.setName(taskNewName);
taskPage.save();
Assert.assertTrue(tasksPage.findTask(taskNewName));
}
@Test
public void testCDeleteTask() throws InterruptedException {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TasksPage tasksPage = (TasksPage) getContext().initPage(page.getKey());
Integer size = tasksPage.getTasks().size();
tasksPage.deleteFirstTask();
Thread.sleep(3000);
tasksPage.submit();
Assert.assertEquals(size - 1, tasksPage.getTasks().size());
}
@Test
public void testDAddDeadline() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TasksPage tasksPage = (TasksPage) getContext().initPage(page.getKey());
TaskPage taskPage = (TaskPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 2).getKey());
tasksPage.goToFirstTask();
String taskId = taskPage.getId();
Integer deadnum = taskPage.getDeadNum();
String descr = "Description";
String date = "06.06.2019";
String dateValue = "2019-06-06";
taskPage.clickAddDeadline();
taskPage.addDeadlineDescription(descr, deadnum);
taskPage.addDeadlineDate(date, deadnum);
taskPage.save();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/students/task?id=%s", taskId));
Assert.assertTrue(taskPage.hasDeadline(descr, dateValue));
}
@Test
public void testEEditDeadline() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TasksPage tasksPage = (TasksPage) getContext().initPage(page.getKey());
TaskPage taskPage = (TaskPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 2).getKey());
tasksPage.goToFirstTask();
String taskId = taskPage.getId();
String descr = "DescriptionTwo";
String date = "12.12.2019";
String dateValue = "2019-12-12";
taskPage.clearDeadlineDate(0);
taskPage.clearDeadlineDescription(0);
taskPage.addDeadlineDescription(descr, 0);
taskPage.addDeadlineDate(date, 0);
taskPage.save();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/students/task?id=%s", taskId));
Assert.assertTrue(taskPage.hasDeadline(descr, dateValue));
}
@Test
public void testFDeleteDeadline() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TasksPage tasksPage = (TasksPage) getContext().initPage(page.getKey());
TaskPage taskPage = (TaskPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 2).getKey());
tasksPage.goToFirstTask();
String taskId = taskPage.getId();
Integer deadNum = taskPage.getDeadNum();
taskPage.deleteDeadline();
taskPage.save();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/students/task?id=%s", taskId));
Assert.assertEquals(deadNum - 1, (int) taskPage.getDeadNum());
}
@Test
public void testGCreateTaskWithTag() throws InterruptedException {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 2);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TaskPage taskPage = (TaskPage) getContext().initPage(page.getKey());
TasksPage tasksPage = (TasksPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 0).getKey());
String taskName = "Task " + (new Date()).getTime();
taskPage.setName(taskName);
taskPage.setTag(tag);
Thread.sleep(1000);
taskPage.addDeadlineDate("01.01.2020", 0);
taskPage.addDeadlineDescription("Description", 0);
taskPage.save();
Assert.assertTrue(tasksPage.findTaskByTag(taskName, tag));
}
@Test
public void testHFindTagInFilter() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TasksPage tasksPage = (TasksPage) getContext().initPage(page.getKey());
Assert.assertTrue(tasksPage.findTag(tag));
}
@Test
public void testIFilterByTag() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TasksPage tasksPage = (TasksPage) getContext().initPage(page.getKey());
tasksPage.selectTag(tag);
Assert.assertTrue(tasksPage.findTasksByTag(tag));
}
@Test
public void testJFilterByStatus() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
TasksPage tasksPage = (TasksPage) getContext().initPage(page.getKey());
tasksPage.selectStatus();
Assert.assertTrue(tasksPage.findAllStatus());
}
}

View File

@ -1,116 +0,0 @@
package conference;
import core.PageObject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.List;
public class ConferencePage extends PageObject {
public String getSubTitle() {
return driver.findElement(By.tagName("h3")).getText();
}
public String getId() {
return driver.findElement(By.id("id")).getAttribute("value");
}
public void setName(String name) {
driver.findElement(By.id("title")).sendKeys(name);
}
public String getName() {
return driver.findElement(By.id("title")).getAttribute("value");
}
public void clearName() {
driver.findElement(By.id("title")).clear();
}
public void clickSaveBut() {
driver.findElement(By.id("send-message-button")).click();
}
public void clickAddDeadlineBut() {
driver.findElement(By.id("addDeadline")).click();
}
private List<WebElement> getDeadlineList() {
return driver.findElements(By.className("deadline"));
}
public Integer getDeadlineCount() {
return driver.findElements(By.className("deadline")).size();
}
public void setDeadlineDescription(String description, Integer i) {
driver.findElement(By.id(String.format("deadlines%d.description", i))).sendKeys(description);
}
public void setDeadlineDate(String date, Integer i) {
driver.findElement(By.id(String.format("deadlines%d.date", i))).sendKeys(date);
}
public void clickTakePartBut() {
driver.findElement(By.id("take-part")).click();
}
public Boolean isTakePartButDisabledValueTrue() {
return driver.findElement(By.id("take-part")).getAttribute("disabled").equals("true");
}
public Integer getMemberCount() {
return driver.findElements(By.className("member")).size();
}
public void clickDeleteDeadlineBut() {
driver.findElement(By.xpath("//*[@id=\"deadlines\"]/div/input[4]")).click();
}
public void showAllowToAttachArticles() {
driver.findElement(By.cssSelector("button[data-id=\"paperIds\"]")).click();
}
public void clickAddPaperBut() {
driver.findElement(By.id("add-paper")).click();
}
public List<WebElement> getArticles() {
return driver.findElements(By.className("paper"));
}
public Integer getArticlesCount() {
return driver.findElements(By.className("paper")).size();
}
public WebElement selectArticle() {
WebElement webElement = driver.findElement(By.xpath("//*[@id=\"conference-form\"]/div/div[2]/div[5]/div/div/div[2]/ul/li[1]/a"));
webElement.click();
return webElement;
}
public void clickUndockArticleBut() {
driver.findElement(By.name("removePaper")).click();
}
public boolean checkDeadline(String description, String dateValue) {
return getDeadlineList()
.stream()
.anyMatch(webElement -> {
return webElement.findElement(By.className("deadline-text")).getAttribute("value").equals(description)
&& webElement.findElement(By.cssSelector("input[type=\"date\"]")).getAttribute("value").equals(dateValue);
});
}
public boolean checkArticle(String paperName) {
return getArticles()
.stream()
.anyMatch(webElement -> webElement
.findElements(By.tagName("input"))
.get(1).getAttribute("value")
.equals(paperName));
}
}

View File

@ -1,11 +0,0 @@
package conference;
import core.PageObject;
import org.openqa.selenium.By;
public class ConferencesDashboardPage extends PageObject {
public String getSubTitle() {
return driver.findElement(By.tagName("h2")).getText();
}
}

View File

@ -1,47 +0,0 @@
package conference;
import core.PageObject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.List;
public class ConferencesPage extends PageObject {
public String getSubTitle() {
return driver.findElement(By.tagName("h3")).getText();
}
public List<WebElement> getConferencesList() {
return driver.findElements(By.cssSelector("span.h6.float-left.m-2"));
}
public void getFirstConference() {
driver.findElement(By.xpath("//*[@id=\"conferences\"]/div/div[2]/div[1]/div[1]/div/a")).click();
}
public void selectMember() {
driver.findElements(By.className("bootstrap-select")).get(0).findElement(By.className("btn")).click();
driver.findElements(By.className("bootstrap-select")).get(0).findElements(By.className("dropdown-item")).get(1).click();
}
public void selectYear() {
driver.findElements(By.className("bootstrap-select")).get(1).findElement(By.className("btn")).click();
driver.findElements(By.className("bootstrap-select")).get(1).findElements(By.className("dropdown-item")).get(1).click();
}
public void deleteFirst() {
js.executeScript("$('input[data-confirm]').click();");
}
public void clickConfirm() {
driver.findElement(By.id("deleteConference")).click();
}
public boolean checkNameInList(String newConferenceName) {
return getConferencesList()
.stream()
.anyMatch(webElement -> webElement.getText().equals(newConferenceName));
}
}

View File

@ -1,27 +0,0 @@
package context;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class ChromeContext extends Context {
private final static String WINDOWS_DRIVER = "chromedriver.exe";
private final static String LINUX_DRIVER = "chromedriver";
private final static String DRIVER_TYPE = "webdriver.chrome.driver";
@Override
protected void createDriver() {
final ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--headless");
driver = new ChromeDriver(chromeOptions);
}
@Override
protected String getDriverExecutable(boolean isWindows) {
return isWindows ? WINDOWS_DRIVER : LINUX_DRIVER;
}
@Override
protected String getDriverType() {
return DRIVER_TYPE;
}
}

View File

@ -1,65 +0,0 @@
package context;
import core.PageObject;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import java.util.concurrent.TimeUnit;
public abstract class Context {
private final static String DRIVER_LOCATION = "drivers/%s";
WebDriver driver;
private WebDriver getDriver() {
if (driver != null) {
return driver;
}
throw new IllegalStateException("WebDriver is not initialized");
}
public void start() {
System.setProperty(getDriverType(), getDriverExecutablePath());
createDriver();
// это плохая инструкция для автотестов, т.к. лучше задавать для конкретного элемента или кейса
getDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
public void close() {
if (driver != null) {
driver.quit();
}
}
public void goTo(String url) {
getDriver().get(url);
}
public String getTitle() {
return getDriver().getTitle();
}
public <T extends PageObject> PageObject initPage(T pageObject) {
return pageObject.setDriver(getDriver());
}
protected abstract void createDriver();
protected abstract String getDriverType();
protected abstract String getDriverExecutable(boolean windows);
private String getDriverExecutablePath() {
return Context.class.getClassLoader().getResource(
String.format(DRIVER_LOCATION, getDriverExecutable(isWindows()))).getFile();
}
private boolean isWindows() {
return System.getProperty("os.name").toLowerCase().contains("windows");
}
public void setSize(Dimension dimension) {
driver.manage().window().setSize(dimension);
}
}

View File

@ -1,24 +0,0 @@
package context;
import org.openqa.selenium.firefox.FirefoxDriver;
public class FirefoxContext extends Context {
private final static String WINDOWS_DRIVER = "geckodriver.exe";
private final static String LINUX_DRIVER = "geckodriver";
private final static String DRIVER_TYPE = "webdriver.gecko.driver";
@Override
protected void createDriver() {
driver = new FirefoxDriver();
}
@Override
protected String getDriverExecutable(boolean isWindows) {
return isWindows ? WINDOWS_DRIVER : LINUX_DRIVER;
}
@Override
protected String getDriverType() {
return DRIVER_TYPE;
}
}

View File

@ -1,25 +0,0 @@
package core;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.WebDriverWait;
public abstract class PageObject {
protected WebDriver driver;
protected JavascriptExecutor js;
protected WebDriverWait waiter;
public abstract String getSubTitle();
public PageObject setDriver(WebDriver driver) {
this.driver = driver;
js = (JavascriptExecutor) driver;
waiter = new WebDriverWait(driver, 10);
return this;
}
public void initElements() {
PageFactory.initElements(driver, this);
}
}

View File

@ -1,29 +0,0 @@
package core;
import context.ChromeContext;
import context.Context;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.openqa.selenium.Dimension;
public abstract class TestTemplate {
private static Context context;
protected static Context getContext() {
return context;
}
@BeforeClass
public static void setup() {
context = new ChromeContext();
context.start();
context.setSize(new Dimension(1600, 900));
}
@AfterClass
public static void quit() {
if (context != null) {
context.close();
}
}
}

View File

@ -1,149 +0,0 @@
package grant;
import core.PageObject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;
import java.util.List;
public class GrantPage extends PageObject {
@Override
public String getSubTitle() {
return driver.findElement(By.tagName("h2")).getText();
}
public String getId() {
return driver.findElement(By.id("grantId")).getAttribute("value");
}
public void setTitle(String name) {
driver.findElement(By.id("title")).clear();
driver.findElement(By.id("title")).sendKeys(name);
}
public String getTitle() {
return driver.findElement(By.id("title")).getAttribute("value");
}
public void setDeadline(String date, Integer i, String description) {
driver.findElement(By.id(String.format("deadlines%d.date", i))).sendKeys(date);
driver.findElement(By.id(String.format("deadlines%d.description", i))).sendKeys(description);
}
public void setLeader() {
WebElement webElement = driver.findElement(By.id("leaderId"));
Select selectLeader = new Select(webElement);
selectLeader.selectByVisibleText("Романов");
}
public void saveGrant() {
driver.findElement(By.id("sendMessageButton")).click();
}
public boolean checkBlankFields() {
return driver.findElements(By.className("alert-danger")).size() > 0;
}
public List<WebElement> getAttachedPapers() {
try {
return driver.findElement(By.className("div-selected-papers")).findElements(By.tagName("div"));
} catch (Exception ex) {
return null;
}
}
public List<WebElement> attachPaper() {
WebElement selectPapers = driver.findElement(By.id("allPapers"));
Select select = new Select(selectPapers);
List<WebElement> selectedOptions = select.getAllSelectedOptions();
List<WebElement> allOptions = select.getOptions();
if (selectedOptions.size() >= allOptions.size()) {
for (int i = 0; i < allOptions.size(); i++) {
if (!allOptions.get(i).equals(selectedOptions.get(i))) {
select.selectByVisibleText(allOptions.get(i).getText());
selectedOptions.add(allOptions.get(i));
return selectedOptions;
}
}
} else {
select.selectByVisibleText(allOptions.get(0).getText());
selectedOptions.add(allOptions.get(0));
return selectedOptions;
}
return null;
}
public List<WebElement> deletePaper() {
WebElement selectPapers = driver.findElement(By.id("allPapers"));
Select select = new Select(selectPapers);
select.deselectByVisibleText(select.getFirstSelectedOption().getText());
return select.getAllSelectedOptions();
}
private List<WebElement> getDeadlineList() {
return driver.findElements(By.id("deadlines"));
}
public Integer getDeadlineCount() {
return getDeadlineList().size();
}
public void addDeadline() {
driver.findElement(By.id("addDeadline")).click();
}
public boolean checkDeadline(String description, String dateValue) {
return getDeadlineList()
.stream()
.anyMatch(webElement -> {
return webElement.findElement(By.className("div-deadline-description")).findElement(
By.tagName("input")).getAttribute("value").equals(description)
&& webElement.findElement(By.className("form-deadline-date")).getAttribute("value").equals(dateValue);
});
}
public void deleteDeadline() {
driver.findElements(By.className("btn-delete-deadline")).get(0).click();
}
public List<WebElement> addAuthor() {
WebElement selectAuthors = driver.findElement(By.id("authors"));
Select select = new Select(selectAuthors);
List<WebElement> selectedOptions = select.getAllSelectedOptions();
List<WebElement> allOptions = select.getOptions();
int i = 0;
while (i < selectedOptions.size()) {
if (!allOptions.get(i).equals(selectedOptions.get(i))) {
select.selectByVisibleText(allOptions.get(i).getText());
selectedOptions.add(allOptions.get(i));
return selectedOptions;
} else {
i++;
}
}
if (selectedOptions.size() != allOptions.size()) {
select.selectByVisibleText(allOptions.get(i).getText());
selectedOptions.add(allOptions.get(i));
}
return selectedOptions;
}
public void deleteAuthor() {
WebElement selectAuthors = driver.findElement(By.id("authors"));
Select select = new Select(selectAuthors);
List<WebElement> selectedOptions = select.getAllSelectedOptions();
if (selectedOptions.size() != 0) {
select.deselectByVisibleText(selectedOptions.get(0).getText());
}
}
public void setDescription(String description) {
driver.findElement(By.id("comment")).clear();
driver.findElement(By.id("comment")).sendKeys(description);
}
public String getDescription() {
return driver.findElement(By.id("comment")).getText();
}
}

View File

@ -1,11 +0,0 @@
package grant;
import core.PageObject;
import org.openqa.selenium.By;
public class GrantsDashboardPage extends PageObject {
@Override
public String getSubTitle() {
return driver.findElement(By.tagName("h2")).getText();
}
}

View File

@ -1,66 +0,0 @@
package grant;
import core.PageObject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.List;
public class GrantsPage extends PageObject {
@Override
public String getSubTitle() {
return driver.findElement(By.tagName("h2")).getText();
}
public List<WebElement> getGrantsList() {
return driver.findElements(By.className("grant-row"));
}
public boolean findGrantByTitle(String grantTitle) {
return getGrantsList()
.stream()
.map(el -> el.findElement(By.cssSelector("span.h6")))
.anyMatch(webElement -> webElement.getText().equals(grantTitle));
}
public void deleteFirst() throws InterruptedException {
WebElement findDeleteButton = driver.findElement(By.xpath("//*[@id=\"grants\"]/div/div[2]/div[1]/div[1]/div"));
findDeleteButton.click();
Thread.sleep(3000);
WebElement grant = driver.findElement(By.xpath("//*[@id=\"grants\"]/div/div[2]/div[1]/div[1]/div/a[2]"));
grant.click();
WebElement ok = driver.findElement(By.id("dataConfirmOK"));
ok.click();
}
public void getFirstGrant() {
driver.findElement(By.xpath("//*[@id=\"grants\"]/div/div[2]/div[1]/div[1]/div/a[1]")).click();
}
public WebElement getFirstGrantWithoutClick() {
return driver.findElement(By.xpath("//*[@id=\"grants\"]/div/div[2]/div[1]/div[1]"));
}
public String getGrantTitle(WebElement webElement) {
return webElement.findElement(By.cssSelector("span.h6")).getText();
}
public WebElement getGrantByTitle(String title) {
List<WebElement> list = getGrantsList();
for (int i = 0; i < list.size(); i++) {
if (getGrantTitle(list.get(i)).equals(title)) {
return list.get(i);
}
}
return null;
}
public Integer getAuthorsCount(WebElement webElement) {
String authors = webElement.findElement(By.className("text-muted")).getText();
if (!authors.equals("")) {
String[] mas = authors.split(",");
return mas.length;
}
return 0;
}
}

View File

@ -1,11 +0,0 @@
package grant;
import core.PageObject;
import org.openqa.selenium.By;
public class KiasPage extends PageObject {
@Override
public String getSubTitle() {
return driver.findElement(By.tagName("h1")).getText();
}
}

View File

@ -1,217 +0,0 @@
package paper;
import core.PageObject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import java.util.List;
public class PaperPage extends PageObject {
@FindBy(id = "title")
private WebElement titleInput;
@FindBy(id = "sendMessageButton")
private WebElement sendMessageButton;
@FindBy(id = "id")
private WebElement idInput;
@FindBy(css = "#messages .alert-danger span")
private WebElement dangerMessage;
@FindBy(className = "deadline")
private List<WebElement> deadlines;
@FindBy(className = "deadline-date")
private List<WebElement> deadlineDates;
@FindBy(className = "deadline-desc")
private List<WebElement> deadlineDescs;
@FindBy(css = ".alert.alert-danger")
private List<WebElement> dangerAlerts;
@FindBy(className = "collapse-heading")
private WebElement firstCollapsedLink;
@FindBy(id = "nav-references-tab")
private WebElement referenceTab;
@FindBy(id = "nav-latex-tab")
private WebElement latexTab;
@FindBy(id = "latex-text")
private WebElement latexTextarea;
@FindBy(id = "addReference")
private WebElement addReferenceButton;
@FindBy(css = "input.author ")
private WebElement firstAuthorInput;
@FindBy(css = "input.publicationTitle")
private WebElement firstPublicationTitleInput;
@FindBy(css = "input.publicationYear")
private WebElement firstPublicationYearInput;
@FindBy(css = "input.publisher")
private WebElement firstPublisherInput;
@FindBy(css = "input.pages")
private WebElement firstPagesInput;
@FindBy(css = "input.journalOrCollectionTitle")
private WebElement firstJournalOrCollectionTitleInput;
@FindBy(id = "formatBtn")
private WebElement formatButton;
@FindBy(id = "formattedReferencesArea")
private WebElement formatArea;
@FindBy(id = "url")
private WebElement urlInput;
@FindBy(id = "pdfBtn")
private WebElement pdfButton;
@FindBy(css = "input.author ")
private List<WebElement> authorInputs;
public String getSubTitle() {
return driver.findElement(By.tagName("h2")).getText();
}
public void clickReferenceTab() {
js.executeScript("document.getElementById('nav-references-tab').scrollIntoView(false);");
referenceTab.click();
}
public void clickLatexTab() {
latexTab.click();
}
public void showFirstReference() {
waiter.until(ExpectedConditions.elementToBeClickable(firstCollapsedLink));
firstCollapsedLink.click();
}
public void clickAddReferenceButton() {
js.executeScript("arguments[0].click()", addReferenceButton);
}
public void clickFormatButton() {
formatButton.click();
}
public void clickPdfButton() {
pdfButton.click();
}
public void setTitle(String title) {
titleInput.clear();
titleInput.sendKeys(title);
}
public void setLatexText(String text) {
waiter.until(ExpectedConditions.visibilityOf(latexTextarea));
latexTextarea.clear();
latexTextarea.sendKeys(text);
}
public void setFirstReferenceAuthors(String authors) {
waiter.until(ExpectedConditions.visibilityOf(firstAuthorInput));
firstAuthorInput.clear();
firstAuthorInput.sendKeys(authors);
}
public void setFirstReferencePublicationTitle(String title) {
firstPublicationTitleInput.clear();
firstPublicationTitleInput.sendKeys(title);
}
public void setFirstReferencePublicationYear(String year) {
firstPublicationYearInput.clear();
firstPublicationYearInput.sendKeys(year);
}
public void setFirstReferencePublisher(String publisher) {
firstPublisherInput.clear();
firstPublisherInput.sendKeys(publisher);
}
public void setFirstReferencePages(String pages) {
firstPagesInput.clear();
firstPagesInput.sendKeys(pages);
}
public void setFirstReferenceJournalOrCollectionTitle(String journal) {
firstJournalOrCollectionTitleInput.clear();
firstJournalOrCollectionTitleInput.sendKeys(journal);
}
public void setUrl(String url) {
urlInput.clear();
urlInput.sendKeys(url);
}
public void setFormatStandardSpringer() {
Select standards = new Select(driver.findElement(By.id("formatStandard")));
standards.selectByValue("SPRINGER");
}
public void setDeadlineDate(Integer deadlineNumber, String date) {
deadlineDates.get(deadlineNumber - 1).sendKeys(date);
}
public void setDeadlineDescription(Integer deadlineNumber, String desc) {
deadlineDescs.get(deadlineNumber - 1).clear();
deadlineDescs.get(deadlineNumber - 1).sendKeys(desc);
}
public boolean hasAlert(String alertMessage) {
return dangerAlerts
.stream()
.anyMatch(
webElement -> webElement.getText().contains(alertMessage));
}
public void clickSaveBtn() {
sendMessageButton.click();
}
public String getId() {
return idInput.getAttribute("value");
}
public String getFormatString() {
waiter.until(ExpectedConditions.attributeToBeNotEmpty(formatArea, "value"));
return formatArea.getAttribute("value");
}
public boolean deadlineExist(String desc, String date) {
return deadlines
.stream()
.anyMatch(
webElement -> webElement.findElement(By.className("deadline-desc")).getAttribute("value").equals(desc)
&& webElement.findElement(By.className("deadline-date")).getAttribute("value").equals(date));
}
public boolean authorsExists(String authors) {
return authorInputs
.stream()
.anyMatch(
webElement -> webElement.getAttribute("value").equals(authors));
}
public boolean dangerMessageExist(String message) {
waiter.until(ExpectedConditions.visibilityOf(dangerMessage));
return dangerMessage.getText().equals(message);
}
}

View File

@ -1,24 +0,0 @@
package paper;
import core.PageObject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import java.util.List;
public class PapersDashboardPage extends PageObject {
@FindBy(className = "externalLink")
private List<WebElement> externalLinks;
public String getSubTitle() {
return driver.findElement(By.tagName("h2")).getText();
}
public boolean externalLinkExists(String link) {
return externalLinks
.stream()
.anyMatch(
webElement -> webElement.getAttribute("href").equals(link));
}
}

View File

@ -1,61 +0,0 @@
package paper;
import core.PageObject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.util.List;
public class PapersPage extends PageObject {
@FindBy(css = ".paper-row .h6")
private List<WebElement> paperTitles;
@FindBy(className = "paper-row")
private List<WebElement> paperItems;
@FindBy(className = "remove-paper")
private WebElement removeFirstPaperButton;
@FindBy(id = "dataConfirmOK")
private WebElement confirmDeleteButton;
@FindBy(id = "addDeadline")
private WebElement addDeadlineButton;
@FindBy(css = ".paper-row a:nth-child(2)")
private WebElement firstPaper;
public String getSubTitle() {
return driver.findElement(By.tagName("h2")).getText();
}
public void clickFirstPaper() {
firstPaper.click();
}
public void clickAddDeadline() {
addDeadlineButton.click();
}
public void clickRemoveFirstPaperButton() {
js.executeScript("arguments[0].click()", removeFirstPaperButton);
}
public void clickConfirmDeleteButton() {
waiter.until(ExpectedConditions.visibilityOf(confirmDeleteButton));
confirmDeleteButton.click();
}
public boolean havePaperWithTitle(String title) {
return paperTitles
.stream()
.anyMatch(webElement -> webElement.getText().equals(title));
}
public int getPapersCount() {
return paperItems.size();
}
}

View File

@ -1,11 +0,0 @@
package project;
import core.PageObject;
import org.openqa.selenium.By;
public class ProjectDashboard extends PageObject {
public String getSubTitle() {
return driver.findElement(By.tagName("h2")).getText();
}
}

Some files were not shown because too many files have changed in this diff Show More