Merge branch 'jsf' into 'dev'
Jsf See merge request romanov73/ng-tracker!119
36
build.gradle
@ -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'
|
||||
}
|
||||
}
|
||||
|
@ -169,4 +169,4 @@
|
||||
|
||||
</module>
|
||||
|
||||
</module>
|
||||
</module>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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"));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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/**")
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
52
src/main/java/ru/ulstu/core/navigation/Page.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
47
src/main/java/ru/ulstu/core/util/FacesUtil.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
94
src/main/java/ru/ulstu/grant/controller/GrantView.java
Normal 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();
|
||||
}
|
||||
}
|
68
src/main/java/ru/ulstu/grant/controller/GrantsView.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -52,4 +52,4 @@ public class KiasPage {
|
||||
public boolean isTableRowGrantLine(DomNode grantElement) {
|
||||
return !((HtmlTableRow) grantElement).getAttribute("class").contains("pagerSavedHeightSpacer");
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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()) {
|
||||
|
@ -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) {
|
||||
//нужен здесь для добавления параметров на стартовой странице
|
||||
}
|
||||
}
|
27
src/main/java/ru/ulstu/index/controller/IndexView.java
Normal 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;
|
||||
}
|
||||
}
|
27
src/main/java/ru/ulstu/index/model/Section.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
98
src/main/java/ru/ulstu/paper/controller/PaperView.java
Normal 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();
|
||||
}
|
||||
}
|
68
src/main/java/ru/ulstu/paper/controller/PapersView.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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")
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
26
src/main/java/ru/ulstu/user/controller/UserConverter.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
46
src/main/java/ru/ulstu/user/controller/UserView.java
Normal 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";
|
||||
}
|
||||
}
|
29
src/main/java/ru/ulstu/user/controller/UsersView.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
113
src/main/resources/META-INF/resources/admin/user.xhtml
Normal 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>
|
34
src/main/resources/META-INF/resources/admin/users.xhtml
Normal 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>
|
51
src/main/resources/META-INF/resources/basicTemplate.xhtml
Normal 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>
|
35
src/main/resources/META-INF/resources/css/google/droid.css
Normal 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;
|
||||
}
|
17
src/main/resources/META-INF/resources/css/google/kaushan.css
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
251
src/main/resources/META-INF/resources/css/google/roboto.css
Normal 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;
|
||||
}
|
49
src/main/resources/META-INF/resources/css/style.css
Normal 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;
|
||||
}
|
27
src/main/resources/META-INF/resources/error/403.xhtml
Normal 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>
|
23
src/main/resources/META-INF/resources/error/404.xhtml
Normal 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>
|
42
src/main/resources/META-INF/resources/error/500.xhtml
Normal 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>
|
91
src/main/resources/META-INF/resources/grant/dashboard.xhtml
Normal 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>
|
142
src/main/resources/META-INF/resources/grant/grant.xhtml
Normal 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>
|
@ -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>
|
88
src/main/resources/META-INF/resources/grant/grants.xhtml
Normal 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>
|
BIN
src/main/resources/META-INF/resources/img/conference/back.png
Normal file
After Width: | Height: | Size: 307 B |
BIN
src/main/resources/META-INF/resources/img/conference/delete.png
Normal file
After Width: | Height: | Size: 174 B |
BIN
src/main/resources/META-INF/resources/img/conference/edit.png
Normal file
After Width: | Height: | Size: 254 B |
BIN
src/main/resources/META-INF/resources/img/conference/paper.png
Normal file
After Width: | Height: | Size: 597 B |
BIN
src/main/resources/META-INF/resources/img/header-bg.jpg
Normal file
After Width: | Height: | Size: 539 KiB |
BIN
src/main/resources/META-INF/resources/img/logo.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
src/main/resources/META-INF/resources/img/main/ajax-loader.gif
Normal file
After Width: | Height: | Size: 673 B |
BIN
src/main/resources/META-INF/resources/img/main/career.jpg
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
src/main/resources/META-INF/resources/img/main/conf.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
src/main/resources/META-INF/resources/img/main/grants.jpg
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
src/main/resources/META-INF/resources/img/main/papers.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
src/main/resources/META-INF/resources/img/main/projects.jpg
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
src/main/resources/META-INF/resources/img/main/students.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
src/main/resources/META-INF/resources/img/main/tasks.jpg
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
src/main/resources/META-INF/resources/img/main/team.jpg
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
src/main/resources/META-INF/resources/img/main/templates.jpg
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
src/main/resources/META-INF/resources/img/map-image.png
Normal file
After Width: | Height: | Size: 356 KiB |
20
src/main/resources/META-INF/resources/index.xhtml
Normal 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>
|
61
src/main/resources/META-INF/resources/login.xhtml
Normal 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>
|
91
src/main/resources/META-INF/resources/paper/dashboard.xhtml
Normal 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>
|
165
src/main/resources/META-INF/resources/paper/paper.xhtml
Normal 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>
|
@ -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>
|
88
src/main/resources/META-INF/resources/paper/papers.xhtml
Normal 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>
|
@ -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
|
||||
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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));
|
||||
});
|
||||
}
|
||||
}
|
@ -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("не может быть пусто"));
|
||||
}
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|