Merge branch 'dev' into paper-latex-editing

# Conflicts:
#	src/main/java/ru/ulstu/paper/model/Paper.java
#	src/main/java/ru/ulstu/paper/model/PaperDto.java
#	src/main/java/ru/ulstu/paper/service/PaperService.java
#	src/main/resources/db/changelog-master.xml
#	src/main/resources/templates/papers/paper.html
merge-requests/60/head
Семенова Мария 5 years ago
commit a2dca6b7c6

@ -1,30 +1,28 @@
image: ubuntu:18.04
cache:
key: "$CI_PROJECT_ID"
paths:
- .gradle/
image: romanov73/is:ng-tracker-container
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- apt-get install openjdk-8-jdk git -y
- service postgresql stop
- service postgresql start
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- git log --pretty="%cn;%cd;%s" > src/main/resources/commits.log
build:
stage: build
script: ./gradlew assemble
cache:
key: "$CI_PROJECT_ID"
policy: push
paths:
- build
- .gradle
checkRun:
stage: test
script: ./gradlew bootRun -Dng-tracker.check-run=true
checkStyle:
stage: test
script: ./gradlew check -x test
deploy:
stage: deploy
@ -32,12 +30,6 @@ deploy:
- sh deploy/gdccloud/deploy.sh
only:
- dev
cache:
key: "$CI_PROJECT_ID"
policy: pull
paths:
- build
- .gradle
environment:
name: staging
url: http://193.110.3.124:8080

@ -0,0 +1,46 @@
## Краткое описание задачи
Что требуется сделать
## `Опционально` Список верстаемых страниц
Будут затронуты страницы:
* page1.html
* page2.html
* page3.html
## `Опционально` Список затрагиваемых модулей
При реализации задачи потребуется также реализовать методы контроллера
## `Опционально` Список реализуемых функций
После выполнения задачи станет доступным:
* просмотр `entity_name`
* редактирование `entity_name`
* валидация `entity_name`
## `Опционально` Сценарии работы
Сценарий просмотра:
1. Зайти на главную страницу приложения
2. Перейти в раздел `section_name`
3. Перейти к списку `entity_name`
4. Выбрать нужную `entity_name` и нажать на нее
Сценарий редактирования:
1. Зайти на главную страницу приложения
2. Перейти в раздел `section_name`
3. Перейти к списку `entity_name`
4. Выбрать нужную `entity_name` и нажать на нее
5. Внести нужные правки в поля и сохранить
## Описание конечного результата, дающего возможность проверки выполнения задачи: компоненты проекта, сценарии работы
* Сверстаны страницы page1.hml, page2.hml, page3.hml
* Реализован контроллер для обслуживания страниц
* Сохранение в БД еще не реализовано
* Валидация происходит по полям `field1, field2`
* Сценарий просмотра проверяется при ручном внечении записей в БД

@ -7,6 +7,7 @@
2. Создать новую функцию автоматизированной системы управления задчами - интеллектуальную постановку задач исполнителям.
3. Получить платформу для обкатки научных проектов магистрантов по созданию интеллектуальны систем.
4. Получить проект для обучения бакалавров современым технологиям разработки.
5. Создать систему хранения и трансляции опыта между участниками научной группы.
[Демо версия доступна здесь](http://193.110.3.124:8080)

@ -30,6 +30,10 @@ bootRun.dependsOn checkstyleMain
sourceCompatibility = 1.8
targetCompatibility = 1.8
bootRun {
systemProperties = System.properties
}
checkstyle {
project.ext.checkstyleVersion = '8.8'
@ -110,9 +114,6 @@ dependencies {
compile group: 'org.liquibase', name: 'liquibase-core', version: '3.5.3'
compile group: 'com.mattbertolini', name: 'liquibase-slf4j', version: '2.0.0'
compile group: 'org.apache.poi', name: 'poi', version: '3.9'
compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.9'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'
compile group: 'org.webjars', name: 'bootstrap', version: '4.1.0'
@ -121,8 +122,10 @@ dependencies {
compile group: 'org.webjars.npm', name: 'jquery.easing', version: '1.4.1'
compile group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.5.0'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.5.0'
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.6.0'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.6.0'
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
testCompile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.3.1'
}

@ -2,13 +2,30 @@ package ru.ulstu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import ru.ulstu.configuration.ApplicationProperties;
import ru.ulstu.core.repository.JpaDetachableRepositoryImpl;
@SpringBootApplication
@EnableJpaRepositories(repositoryBaseClass = JpaDetachableRepositoryImpl.class)
public class NgTrackerApplication {
private final ApplicationProperties applicationProperties;
public NgTrackerApplication(ApplicationProperties applicationProperties) {
this.applicationProperties = applicationProperties;
}
public static void main(String[] args) {
SpringApplication.run(NgTrackerApplication.class, args);
}
@EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
System.out.println("hello world, I have just started up");
if (applicationProperties.isCheckRun()) {
System.exit(0);
}
}
}

@ -0,0 +1,116 @@
package ru.ulstu.conference.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import ru.ulstu.conference.model.ConferenceDto;
import ru.ulstu.conference.model.ConferenceFilterDto;
import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.paper.model.Paper;
import springfox.documentation.annotations.ApiIgnore;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static org.springframework.util.StringUtils.isEmpty;
import static ru.ulstu.core.controller.Navigation.CONFERENCES_PAGE;
import static ru.ulstu.core.controller.Navigation.CONFERENCE_PAGE;
import static ru.ulstu.core.controller.Navigation.REDIRECT_TO;
@Controller()
@RequestMapping(value = "/conferences")
@ApiIgnore
public class ConferenceController {
private final ConferenceService conferenceService;
public ConferenceController(ConferenceService conferenceService) {
this.conferenceService = conferenceService;
}
@GetMapping("/conferences")
public void getConferences(ModelMap modelMap) {
modelMap.put("filteredConferences", new ConferenceFilterDto(conferenceService.findAllDto()));
}
@GetMapping("/conference")
public void getConference(ModelMap modelMap, @RequestParam(value = "id") Integer id) {
if (id != null && id > 0) {
ConferenceDto conferenceDto = conferenceService.findOneDto(id);
conferenceDto.setNotSelectedPapers(getNotSelectPapers(conferenceDto.getPaperIds()));
modelMap.put("conferenceDto", conferenceDto);
} else {
ConferenceDto conferenceDto = new ConferenceDto();
conferenceDto.setNotSelectedPapers(getNotSelectPapers(new ArrayList<Integer>()));
modelMap.put("conferenceDto", conferenceDto);
}
}
@PostMapping(value = "/conference", params = "save")
public String save(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
filterEmptyDeadlines(conferenceDto);
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.save(conferenceDto);
return String.format(REDIRECT_TO, CONFERENCES_PAGE);
}
@GetMapping("/delete/{conference-id}")
public String delete(@PathVariable("conference-id") Integer conferenceId) throws IOException {
conferenceService.delete(conferenceId);
return String.format(REDIRECT_TO, CONFERENCES_PAGE);
}
@PostMapping(value = "/conference", params = "addDeadline")
public String addDeadline(@Valid ConferenceDto conferenceDto, Errors errors) {
filterEmptyDeadlines(conferenceDto);
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceDto.getDeadlines().add(new Deadline());
return CONFERENCE_PAGE;
}
@PostMapping(value = "/conference", params = "removeDeadline")
public String removeDeadline(@Valid ConferenceDto conferenceDto, Errors errors,
@RequestParam(value = "removeDeadline") Integer deadlineIndex) throws IOException {
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.removeDeadline(conferenceDto, deadlineIndex);
return CONFERENCE_PAGE;
}
@PostMapping(value = "/conference", params = "removePaper")
public String removePaper(@Valid ConferenceDto conferenceDto, Errors errors,
@RequestParam(value = "removePaper") Integer paperIndex) throws IOException {
if (errors.hasErrors()) {
return CONFERENCE_PAGE;
}
conferenceService.removePaper(conferenceDto, paperIndex);
return CONFERENCE_PAGE;
}
public List<Paper> getNotSelectPapers(List<Integer> paperIds) {
return conferenceService.getConferencePapers(paperIds);
}
private void filterEmptyDeadlines(ConferenceDto conferenceDto) {
conferenceDto.setDeadlines(conferenceDto.getDeadlines().stream()
.filter(dto -> dto.getDate() != null || !isEmpty(dto.getDescription()))
.collect(Collectors.toList()));
}
}

@ -0,0 +1,142 @@
package ru.ulstu.conference.model;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.format.annotation.DateTimeFormat;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.user.model.User;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Entity
@Table(name = "conference")
public class Conference extends BaseEntity {
@NotBlank
private String title;
private String description;
private String url;
private int ping;
@Column(name = "begin_date")
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date beginDate;
@Column(name = "end_date")
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endDate;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "conference_id", unique = true)
@Fetch(FetchMode.SUBSELECT)
@OrderBy("date")
private List<Deadline> deadlines = new ArrayList<>();
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "paper_conference",
joinColumns = {@JoinColumn(name = "conference_id")},
inverseJoinColumns = {@JoinColumn(name = "paper_id")})
private List<Paper> papers = new ArrayList<>();
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "users_conference",
joinColumns = {@JoinColumn(name = "conference_id")},
inverseJoinColumns = {@JoinColumn(name = "users_id")})
private Set<User> users = new HashSet<>();
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getPing() {
return ping;
}
public void setPing(int ping) {
this.ping = ping;
}
public Date getBeginDate() {
return beginDate;
}
public void setBeginDate(Date beginDate) {
this.beginDate = beginDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public List<Deadline> getDeadlines() {
return deadlines;
}
public void setDeadlines(List<Deadline> deadlines) {
this.deadlines = deadlines;
}
public List<Paper> getPapers() {
return papers;
}
public void setPapers(List<Paper> papers) {
this.papers = papers;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}

@ -0,0 +1,218 @@
package ru.ulstu.conference.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.user.model.UserDto;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static ru.ulstu.core.util.StreamApiUtils.convert;
public class ConferenceDto {
private Integer id;
@NotEmpty
@Size(min = 2, max = 400)
private String title;
@Size(max = 500)
private String description = "";
@Size(max = 255)
private String url = "";
private int ping = 0;
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date beginDate = new Date();
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endDate = new Date();
private List<Deadline> deadlines = new ArrayList<>();
private List<Integer> removedDeadlineIds = new ArrayList<>();
private Set<Integer> userIds = new HashSet<>();
private List<Integer> paperIds = new ArrayList<>();
private List<Paper> papers = new ArrayList<>();
private List<Paper> notSelectedPapers = new ArrayList<>();
private Set<UserDto> users = new HashSet<>();
private Integer filterUserId;
public ConferenceDto() {
}
@JsonCreator
public ConferenceDto(@JsonProperty("id") Integer id,
@JsonProperty("title") String title,
@JsonProperty("description") String description,
@JsonProperty("url") String url,
@JsonProperty("ping") Integer ping,
@JsonProperty("beginDate") Date beginDate,
@JsonProperty("endDate") Date endDate,
@JsonProperty("deadlines") List<Deadline> deadlines,
@JsonProperty("userIds") Set<Integer> userIds,
@JsonProperty("paperIds") List<Integer> paperIds,
@JsonProperty("users") Set<UserDto> users,
@JsonProperty("papers") List<Paper> papers,
@JsonProperty("notSelectedPapers") List<Paper> notSelectedPapers) {
this.id = id;
this.title = title;
this.description = description;
this.url = url;
this.ping = ping;
this.beginDate = beginDate;
this.endDate = endDate;
this.deadlines = deadlines;
this.userIds = userIds;
this.paperIds = paperIds;
this.users = users;
this.papers = papers;
this.notSelectedPapers = notSelectedPapers;
}
public ConferenceDto(Conference conference) {
this.id = conference.getId();
this.title = conference.getTitle();
this.description = conference.getDescription();
this.url = conference.getUrl();
this.ping = conference.getPing();
this.beginDate = conference.getBeginDate();
this.endDate = conference.getEndDate();
this.deadlines = conference.getDeadlines();
this.userIds = convert(conference.getUsers(), user -> user.getId());
this.paperIds = convert(conference.getPapers(), paper -> paper.getId());
this.users = convert(conference.getUsers(), UserDto::new);
this.papers = conference.getPapers();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getPing() {
return ping;
}
public void setPing(int ping) {
this.ping = ping;
}
public Date getBeginDate() {
return beginDate;
}
public void setBeginDate(Date beginDate) {
this.beginDate = beginDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public List<Deadline> getDeadlines() {
return deadlines;
}
public void setDeadlines(List<Deadline> deadlines) {
this.deadlines = deadlines;
}
public Set<Integer> getUserIds() {
return userIds;
}
public void setUserIds(Set<Integer> userIds) {
this.userIds = userIds;
}
public List<Integer> getPaperIds() {
return paperIds;
}
public void setPaperIds(List<Integer> paperIds) {
this.paperIds = paperIds;
}
public List<Paper> getPapers() {
return papers;
}
public void setPapers(List<Paper> papers) {
this.papers = papers;
}
public Set<UserDto> getUsers() {
return users;
}
public void setUsers(Set<UserDto> users) {
this.users = users;
}
public Integer getFilterUserId() {
return filterUserId;
}
public void setFilterUserId(Integer filterUserId) {
this.filterUserId = filterUserId;
}
public List<Integer> getRemovedDeadlineIds() {
return removedDeadlineIds;
}
public void setRemovedDeadlineIds(List<Integer> removedDeadlineIds) {
this.removedDeadlineIds = removedDeadlineIds;
}
public List<Paper> getNotSelectedPapers() {
return notSelectedPapers;
}
public void setNotSelectedPapers(List<Paper> notSelectedPapers) {
this.notSelectedPapers = notSelectedPapers;
}
}

@ -0,0 +1,47 @@
package ru.ulstu.conference.model;
import java.util.List;
public class ConferenceFilterDto {
private List<ConferenceDto> conferences;
private Integer filterAuthorId;
private Integer year;
public ConferenceFilterDto() {
}
public ConferenceFilterDto(List<ConferenceDto> conferenceDtos, Integer filterAuthorId, Integer year) {
this.conferences = conferenceDtos;
this.filterAuthorId = filterAuthorId;
this.year = year;
}
public ConferenceFilterDto(List<ConferenceDto> conferenceDtos) {
this(conferenceDtos, null, null);
}
public List<ConferenceDto> getConferences() {
return conferences;
}
public void setConferences(List<ConferenceDto> conferences) {
this.conferences = conferences;
}
public Integer getFilterAuthorId() {
return filterAuthorId;
}
public void setFilterAuthorId(Integer filterAuthorId) {
this.filterAuthorId = filterAuthorId;
}
public Integer getYear() {
return year;
}
public void setYear(Integer year) {
this.year = year;
}
}

@ -0,0 +1,7 @@
package ru.ulstu.conference.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.conference.model.Conference;
public interface ConferenceRepository extends JpaRepository<Conference, Integer> {
}

@ -0,0 +1,7 @@
package ru.ulstu.conference.service;
import org.springframework.stereotype.Service;
@Service
public class ConferenceNotificationService {
}

@ -0,0 +1,112 @@
package ru.ulstu.conference.service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.conference.model.ConferenceDto;
import ru.ulstu.conference.repository.ConferenceRepository;
import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.service.PaperService;
import java.io.IOException;
import java.util.List;
import static org.springframework.util.ObjectUtils.isEmpty;
import static ru.ulstu.core.util.StreamApiUtils.convert;
@Service
public class ConferenceService {
private final static int MAX_DISPLAY_SIZE = 40;
private final ConferenceRepository conferenceRepository;
private final DeadlineService deadlineService;
private final PaperService paperService;
public ConferenceService(ConferenceRepository conferenceRepository,
DeadlineService deadlineService,
PaperService paperService) {
this.conferenceRepository = conferenceRepository;
this.deadlineService = deadlineService;
this.paperService = paperService;
}
public List<Conference> findAll() {
return conferenceRepository.findAll();
}
public List<ConferenceDto> findAllDto() {
List<ConferenceDto> conferences = convert(findAll(), ConferenceDto::new);
conferences.forEach(conferenceDto -> conferenceDto.setTitle(StringUtils.abbreviate(conferenceDto.getTitle(), MAX_DISPLAY_SIZE)));
return conferences;
}
public ConferenceDto findOneDto(Integer id) {
return new ConferenceDto(conferenceRepository.findOne(id));
}
public void save(ConferenceDto conferenceDto) throws IOException {
if (isEmpty(conferenceDto.getId())) {
create(conferenceDto);
} else {
update(conferenceDto);
}
}
@Transactional
public Integer create(ConferenceDto conferenceDto) throws IOException {
Conference newConference = copyFromDto(new Conference(), conferenceDto);
newConference = conferenceRepository.save(newConference);
return newConference.getId();
}
@Transactional
public Integer update(ConferenceDto conferenceDto) throws IOException {
Conference conference = conferenceRepository.findOne(conferenceDto.getId());
conferenceRepository.save(copyFromDto(conference, conferenceDto));
conferenceDto.getRemovedDeadlineIds().forEach(deadlineService::remove);
return conference.getId();
}
@Transactional
public void delete(Integer conferenceId) {
if (conferenceRepository.exists(conferenceId)) {
conferenceRepository.delete(conferenceId);
}
}
public void removeDeadline(ConferenceDto conferenceDto, Integer deadlineIndex) throws IOException {
if (conferenceDto.getDeadlines().get(deadlineIndex).getId() != null) {
conferenceDto.getRemovedDeadlineIds().add(conferenceDto.getDeadlines().get(deadlineIndex).getId());
}
conferenceDto.getDeadlines().remove((int) deadlineIndex);
}
public void removePaper(ConferenceDto conferenceDto, Integer paperIndex) throws IOException {
Paper removedPaper = conferenceDto.getPapers().remove((int) paperIndex);
conferenceDto.getNotSelectedPapers().add(removedPaper);
}
public List<Paper> getConferencePapers(List<Integer> paperIds) {
return paperService.findAllNotSelect(paperIds);
}
private Conference copyFromDto(Conference conference, ConferenceDto conferenceDto) throws IOException {
conference.setTitle(conferenceDto.getTitle());
conference.setDescription(conferenceDto.getDescription());
conference.setUrl(conferenceDto.getUrl());
conference.setPing(0);
conference.setBeginDate(conferenceDto.getBeginDate());
conference.setEndDate(conferenceDto.getEndDate());
conference.setPapers(conferenceDto.getPapers());
conference.setDeadlines(deadlineService.saveOrCreate(conferenceDto.getDeadlines()));
if (conferenceDto.getPaperIds() != null && !conferenceDto.getPaperIds().isEmpty()) {
conferenceDto.getPaperIds().forEach(paperId ->
conference.getPapers().add(paperService.findEntityById(paperId)));
}
return conference;
}
}

@ -11,12 +11,16 @@ import org.springframework.validation.annotation.Validated;
public class ApplicationProperties {
@NotBlank
private String baseUrl;
@NotBlank
private String undeadUserLogin;
private boolean devMode;
private boolean useHttps;
private boolean checkRun;
public boolean isUseHttps() {
return useHttps;
}
@ -48,4 +52,12 @@ public class ApplicationProperties {
public void setDevMode(boolean devMode) {
this.devMode = devMode;
}
public boolean isCheckRun() {
return checkRun;
}
public void setCheckRun(boolean checkRun) {
this.checkRun = checkRun;
}
}

@ -10,10 +10,11 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{articlename:\\w+}");
//registry.addViewController("/admin/{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");
}

@ -20,7 +20,6 @@ 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.model.User;
import ru.ulstu.user.service.UserService;
import java.util.Set;
@ -28,7 +27,6 @@ import java.util.stream.Collectors;
@ControllerAdvice
public class AdviceController {
private final static String USER_NAME_TEMPLATE = "%s %s %s";
private final Logger log = LoggerFactory.getLogger(AdviceController.class);
private final UserService userService;
@ -38,11 +36,7 @@ public class AdviceController {
@ModelAttribute("currentUser")
public String getCurrentUser() {
User user = userService.getCurrentUser();
return String.format(USER_NAME_TEMPLATE,
user.getLastName(),
user.getFirstName().substring(0, 1),
user.getPatronymic().substring(0, 1));
return userService.getCurrentUser().getUserAbbreviate();
}
private Response<Void> handleException(ErrorConstants error) {

@ -1,4 +1,4 @@
package ru.ulstu.grant.controller;
package ru.ulstu.core.controller;
import org.springframework.validation.Errors;
@ -7,6 +7,9 @@ public class Navigation {
public static final String GRANTS_PAGE = "/grants/grants";
public static final String GRANT_PAGE = "/grants/grant";
public static final String CONFERENCES_PAGE = "/conferences/conferences";
public static final String CONFERENCE_PAGE = "/conferences/conference";
public static String hasErrors(Errors errors, String page) {
if (errors.hasErrors()) {
return page;

@ -1,7 +0,0 @@
package ru.ulstu.core.error;
public class XlsLoadException extends Exception {
public XlsLoadException(String s) {
super(s);
}
}

@ -1,7 +0,0 @@
package ru.ulstu.core.error;
public class XlsParseException extends Exception {
public XlsParseException(String s) {
super(s);
}
}

@ -1,31 +0,0 @@
package ru.ulstu.core.service;
import org.springframework.stereotype.Service;
import ru.ulstu.core.model.TreeDto;
import ru.ulstu.core.model.TreeEntity;
import java.util.List;
import java.util.function.Predicate;
@Service
public class TreeService<T extends TreeEntity> {
public TreeDto getTree(String rootName, List<T> rootItems) {
return addChildNode(new TreeDto(rootName), rootItems, element -> true);
}
public TreeDto getTree(String rootName, List<T> rootItems, Predicate<T> filterPredicate) {
return addChildNode(new TreeDto(rootName), rootItems, filterPredicate);
}
private TreeDto addChildNode(TreeDto currentRoot, List<T> children, Predicate<T> filterPredicate) {
if (children != null) {
children.stream()
.filter(filterPredicate)
.forEach(item -> {
TreeDto newNode = new TreeDto(item);
currentRoot.getChildren().add(addChildNode(newNode, item.getChildren(), filterPredicate));
});
}
return currentRoot;
}
}

@ -1,207 +0,0 @@
package ru.ulstu.core.service;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import ru.ulstu.core.error.XlsParseException;
import java.io.*;
public class XlsDocumentBuilder {
private static final int DEFAULT_SHEET_NUM = 0;
private File documentFile;
private Workbook workBook;
private Sheet currentSheet;
/**
* Constructor for reading and writing data from/to *.[xls|xlsx] document
*
* @param file contains existing document for reading or new document to save
*/
public XlsDocumentBuilder(File file) throws IOException, XlsParseException {
this.documentFile = file;
if (file.exists()) {
workBook = getWorkBook(file);
currentSheet = workBook.getSheetAt(DEFAULT_SHEET_NUM);
} else {
workBook = new XSSFWorkbook();
currentSheet = workBook.createSheet();
}
}
private Workbook getWorkBook(File file) throws XlsParseException, IOException {
InputStream inputStream = new PushbackInputStream(new FileInputStream(file), 4096);
if (isXlsx(inputStream)) {
return new XSSFWorkbook(inputStream);
} else if (isExcel(inputStream)) {
return new HSSFWorkbook(inputStream);
}
throw new XlsParseException("Wrong document format");
}
/**
* Change active sheet to write or read data
*
* @param index index of sheet to activate
*/
public XlsDocumentBuilder setActiveSheet(int index) {
workBook.setActiveSheet(index);
currentSheet = workBook.getSheetAt(index);
return this;
}
/**
* Create new sheet in document and set it active
*
* @param sheetName
*/
public XlsDocumentBuilder insertNewSheet(String sheetName) {
currentSheet = workBook.createSheet(sheetName);
workBook.setActiveSheet(getSheetCount() - 1);
return this;
}
public XlsDocumentBuilder insertNewSheet(String sheetName, int order) {
insertNewSheet(sheetName);
workBook.setSheetOrder(sheetName, order);
return this;
}
/**
* Returns number of sheet in document
*
* @return sheets count
*/
public int getSheetCount() {
return workBook.getNumberOfSheets();
}
/**
* Returns number of rows in sheet
*
* @return rows count
*/
public int getRowCount() {
return currentSheet.getLastRowNum();
}
/**
* Returns number of columns in sheet
*
* @return columns count
*/
public int getColumnCount() {
Row row = currentSheet.getRow(getRowCount());
if (row == null) {
return 0;
}
return row.getLastCellNum() - 1;
}
/**
* Returns converted to string representation of cell value
*
* @param rowIndex row index of current sheet
* @param colIndex column index of current sheet
* @return string value of cell
*/
public String getCellAsString(int rowIndex, int colIndex) {
Cell cell = currentSheet.getRow(rowIndex).getCell(colIndex);
cell.setCellType(Cell.CELL_TYPE_STRING);
return cell.getStringCellValue();
}
/**
* Sets string cell value
*
* @param rowIndex row index of current sheet
* @param colIndex column index of current sheet
*/
public XlsDocumentBuilder setCellValue(int rowIndex, int colIndex, String value) {
if (currentSheet.getRow(rowIndex) == null) {
currentSheet.createRow(rowIndex);
}
if (currentSheet.getRow(rowIndex).getCell(colIndex) == null) {
currentSheet.getRow(rowIndex).createCell(colIndex);
}
Cell cell = currentSheet.getRow(rowIndex).getCell(colIndex);
cell.setCellValue(value);
setColumnAutosize(colIndex, colIndex);
return this;
}
public XlsDocumentBuilder setCellValue(int rowIndex, int colIndex, int value) {
return setCellValue(rowIndex, colIndex, String.valueOf(value));
}
public XlsDocumentBuilder setCellValue(int rowIndex, int colIndex, long value) {
return setCellValue(rowIndex, colIndex, String.valueOf(value));
}
/**
* Save current file
*/
public XlsDocumentBuilder save() throws IOException {
OutputStream out = new FileOutputStream(documentFile);
workBook.write(out);
return this;
}
private boolean isExcel(InputStream i) throws IOException {
return (POIFSFileSystem.hasPOIFSHeader(i) || POIXMLDocument.hasOOXMLHeader(i));
}
private boolean isXlsx(InputStream i) throws IOException {
return POIXMLDocument.hasOOXMLHeader(i);
}
public int getActiveSheetIndex() {
return workBook.getActiveSheetIndex();
}
public XlsDocumentBuilder mergeCells(int rowFrom, int rowTo, int colFrom, int colTo) {
currentSheet.addMergedRegion(new CellRangeAddress(rowFrom, rowTo, colFrom, colTo));
return this;
}
public void setRegionBorderWithMedium(int rowFrom, int rowTo, int colFrom, int colTo) {
for (int row = rowFrom; row < rowTo; row++) {
for (int col = colFrom; col <= colTo; col++) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(row, row, col, col);
RegionUtil.setBorderBottom(CellStyle.BORDER_THIN, cellRangeAddress, currentSheet, workBook);
RegionUtil.setBorderLeft(CellStyle.BORDER_THIN, cellRangeAddress, currentSheet, workBook);
RegionUtil.setBorderRight(CellStyle.BORDER_THIN, cellRangeAddress, currentSheet, workBook);
RegionUtil.setBorderTop(CellStyle.BORDER_THIN, cellRangeAddress, currentSheet, workBook);
}
}
}
public XlsDocumentBuilder setColumnAutosize(int from, int to) {
for (int col = from; col <= to; col++) {
currentSheet.autoSizeColumn(col, true);
}
return this;
}
public XlsDocumentBuilder setRowAutosize(int from, int to) {
CellStyle style = workBook.createCellStyle();
style.setWrapText(true);
for (int row = from; row <= to; row++) {
for (int col = 0; col <= currentSheet.getRow(row).getLastCellNum(); col++) {
if (currentSheet.getRow(row).getCell(col) != null) {
currentSheet.getRow(row).getCell(col).setCellStyle(style);
}
}
}
return this;
}
public XlsDocumentBuilder deleteSheet(int index) {
workBook.removeSheetAt(index);
return this;
}
}

@ -41,4 +41,9 @@ public class DeadlineService {
newDeadline = deadlineRepository.save(newDeadline);
return newDeadline;
}
@Transactional
public void remove(Integer deadlineId) {
deadlineRepository.delete(deadlineId);
}
}

@ -13,6 +13,7 @@ import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.grant.model.GrantDto;
import ru.ulstu.grant.service.GrantService;
import springfox.documentation.annotations.ApiIgnore;
import javax.validation.Valid;
import java.io.IOException;
@ -20,14 +21,15 @@ import java.util.List;
import java.util.stream.Collectors;
import static org.springframework.util.StringUtils.isEmpty;
import static ru.ulstu.grant.controller.Navigation.GRANTS_PAGE;
import static ru.ulstu.grant.controller.Navigation.GRANT_PAGE;
import static ru.ulstu.grant.controller.Navigation.REDIRECT_TO;
import static ru.ulstu.grant.controller.Navigation.hasErrors;
import static ru.ulstu.core.controller.Navigation.GRANTS_PAGE;
import static ru.ulstu.core.controller.Navigation.GRANT_PAGE;
import static ru.ulstu.core.controller.Navigation.REDIRECT_TO;
import static ru.ulstu.core.controller.Navigation.hasErrors;
@Controller()
@RequestMapping(value = "/grants")
@ApiIgnore
public class GrantController {
private final GrantService grantService;

@ -6,9 +6,11 @@ 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);

@ -19,6 +19,7 @@ import ru.ulstu.paper.model.PaperFilterDto;
import ru.ulstu.paper.service.LatexService;
import ru.ulstu.paper.service.PaperService;
import ru.ulstu.user.model.User;
import springfox.documentation.annotations.ApiIgnore;
import javax.validation.Valid;
import java.io.IOException;
@ -34,6 +35,7 @@ import static org.springframework.util.StringUtils.isEmpty;
@Controller()
@RequestMapping(value = "/papers")
@ApiIgnore
public class PaperController {
private final PaperService paperService;
private final LatexService latexService;
@ -57,7 +59,7 @@ public class PaperController {
@GetMapping("/dashboard")
public void getDashboard(ModelMap modelMap) {
modelMap.put("papers", paperService.findAllActive());
modelMap.put("papers", paperService.findAllActiveDto());
}
@GetMapping("/paper")

@ -61,4 +61,9 @@ public class PaperRestController {
public Response<List<PaperDto>> filter(@RequestBody @Valid PaperFilterDto paperFilterDto) throws IOException {
return new Response<>(paperService.filter(paperFilterDto));
}
@GetMapping("formatted-list")
public Response<List<String>> getFormattedPaperList() {
return new Response<>(paperService.getFormattedPaperList());
}
}

@ -7,6 +7,7 @@ import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.core.model.UserContainer;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.file.model.FileData;
import ru.ulstu.timeline.model.Event;
import ru.ulstu.user.model.User;
import javax.persistence.CascadeType;
@ -29,7 +30,6 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
@Entity
public class Paper extends BaseEntity implements UserContainer {
public enum PaperStatus {
@ -75,8 +75,14 @@ public class Paper extends BaseEntity implements UserContainer {
private String comment;
private String url;
private Boolean locked = false;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "paper_id")
private List<Event> events = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "paper_id", unique = true)
@Fetch(FetchMode.SUBSELECT)
@ -160,6 +166,22 @@ public class Paper extends BaseEntity implements UserContainer {
this.authors = authors;
}
public List<Event> getEvents() {
return events;
}
public void setEvents(List<Event> events) {
this.events = events;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getLatexText() {
return latexText;
}

@ -30,6 +30,7 @@ public class PaperDto {
@NotEmpty
private List<Deadline> deadlines = new ArrayList<>();
private String comment;
private String url;
private Boolean locked;
private List<FileDataDto> files = new ArrayList<>();
private Set<Integer> authorIds;
@ -50,6 +51,7 @@ public class PaperDto {
@JsonProperty("deadlines") List<Deadline> deadlines,
@JsonProperty("comment") String comment,
@JsonProperty("latex_text") String latexText,
@JsonProperty("url") String url,
@JsonProperty("locked") Boolean locked,
@JsonProperty("files") List<FileDataDto> files,
@JsonProperty("authorIds") Set<Integer> authorIds,
@ -61,6 +63,7 @@ public class PaperDto {
this.updateDate = updateDate;
this.deadlines = deadlines;
this.comment = comment;
this.url = url;
this.latexText = latexText;
this.locked = locked;
this.files = files;
@ -75,6 +78,7 @@ public class PaperDto {
this.updateDate = paper.getUpdateDate();
this.deadlines = paper.getDeadlines();
this.comment = paper.getComment();
this.url = paper.getUrl();
this.latexText = paper.getLatexText();
this.locked = paper.getLocked();
this.files = convert(paper.getFiles(), FileDataDto::new);
@ -170,6 +174,14 @@ public class PaperDto {
this.authorIds = authorIds;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getLatexText() {
return latexText;
}

@ -12,4 +12,6 @@ public interface PaperRepository extends JpaRepository<Paper, Integer> {
@Query("SELECT p FROM Paper p WHERE (:author IS NULL OR :author MEMBER OF p.authors) AND (YEAR(p.createDate) = :year OR :year IS NULL)")
List<Paper> filter(@Param("author") User author, @Param("year") Integer year);
List<Paper> findByIdNotIn(List<Integer> paperIds);
}

@ -11,6 +11,7 @@ import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.model.PaperFilterDto;
import ru.ulstu.paper.repository.PaperRepository;
import ru.ulstu.timeline.service.EventService;
import ru.ulstu.user.model.User;
import ru.ulstu.user.service.UserService;
@ -20,6 +21,7 @@ import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
import static org.springframework.util.ObjectUtils.isEmpty;
@ -33,23 +35,27 @@ import static ru.ulstu.paper.model.Paper.PaperStatus.ON_PREPARATION;
@Service
public class PaperService {
private final static int MAX_DISPLAY_SIZE = 40;
private final static String PAPER_FORMATTED_TEMPLATE = "%s %s";
private final PaperNotificationService paperNotificationService;
private final PaperRepository paperRepository;
private final UserService userService;
private final DeadlineService deadlineService;
private final FileService fileService;
private final EventService eventService;
public PaperService(PaperRepository paperRepository,
FileService fileService,
PaperNotificationService paperNotificationService,
UserService userService,
DeadlineService deadlineService) {
DeadlineService deadlineService,
EventService eventService) {
this.paperRepository = paperRepository;
this.fileService = fileService;
this.paperNotificationService = paperNotificationService;
this.userService = userService;
this.deadlineService = deadlineService;
this.eventService = eventService;
}
public List<Paper> findAll() {
@ -62,13 +68,17 @@ public class PaperService {
return papers;
}
public List<PaperDto> findAllActive() {
return findAllDto()
public List<Paper> findAllActive() {
return findAll()
.stream()
.filter(paper -> paper.getStatus() != COMPLETED && paper.getStatus() != FAILED)
.collect(toList());
}
public List<PaperDto> findAllActiveDto() {
return convert(findAllActive(), PaperDto::new);
}
public PaperDto findOneDto(Integer id) {
return new PaperDto(paperRepository.findOne(id));
}
@ -78,11 +88,13 @@ public class PaperService {
Paper newPaper = copyFromDto(new Paper(), paperDto);
newPaper = paperRepository.save(newPaper);
paperNotificationService.sendCreateNotification(newPaper);
eventService.createFromPaper(newPaper);
return newPaper.getId();
}
private Paper copyFromDto(Paper paper, PaperDto paperDto) throws IOException {
paper.setComment(paperDto.getComment());
paper.setUrl(paperDto.getUrl());
paper.setLatexText(paperDto.getLatexText());
paper.setCreateDate(paper.getCreateDate() == null ? new Date() : paper.getCreateDate());
paper.setLocked(paperDto.getLocked());
@ -111,8 +123,8 @@ public class PaperService {
.collect(toList())) {
fileService.delete(file.getId());
}
paperRepository.save(copyFromDto(paper, paperDto));
eventService.updatePaperDeadlines(paper);
paper.getAuthors().forEach(author -> {
if (!oldAuthors.contains(author)) {
@ -128,7 +140,7 @@ public class PaperService {
}
@Transactional
public void delete(Integer paperId) throws IOException {
public void delete(Integer paperId) {
Paper paper = paperRepository.findOne(paperId);
paperRepository.delete(paper);
}
@ -149,6 +161,7 @@ public class PaperService {
paper = paperRepository.save(paper);
paperNotificationService.sendCreateNotification(paper);
eventService.createFromPaper(paper);
return paper;
}
@ -203,7 +216,41 @@ public class PaperService {
return new PaperDto(paperRepository.findOne(paperId));
}
public Paper findEntityById(Integer paperId) {
return paperRepository.findOne(paperId);
}
public List<Paper> findAllNotSelect(List<Integer> paperIds) {
if (!paperIds.isEmpty()) {
return sortPapers(paperRepository.findByIdNotIn(paperIds));
} else {
return sortPapers(paperRepository.findAll());
}
}
public List<User> getPaperAuthors() {
return userService.findAll();
}
public List<String> getFormattedPaperList() {
return findAllCompleted()
.stream()
.map(paper -> String.format(PAPER_FORMATTED_TEMPLATE, paper.getTitle(), getAuthors(paper)))
.collect(toList());
}
private List<Paper> findAllCompleted() {
return findAll()
.stream()
.filter(paper -> paper.getStatus() == COMPLETED)
.collect(toList());
}
private String getAuthors(Paper paper) {
return paper.getAuthors()
.stream()
.map(User::getUserAbbreviate)
.collect(Collectors.joining(", "));
}
}

@ -0,0 +1,49 @@
package ru.ulstu.project.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import ru.ulstu.project.model.Project;
import ru.ulstu.project.model.ProjectDto;
import ru.ulstu.project.service.ProjectService;
import springfox.documentation.annotations.ApiIgnore;
import java.util.List;
@Controller()
@RequestMapping(value = "/projects")
@ApiIgnore
public class ProjectController {
private final ProjectService projectService;
public ProjectController(ProjectService projectService) {
this.projectService = projectService;
}
@GetMapping("/dashboard")
public void getDashboard(ModelMap modelMap) {
modelMap.put("projects", projectService.findAllDto());
}
@GetMapping("/projects")
public void getProjects(ModelMap modelMap) {
modelMap.put("projects", projectService.findAllDto());
}
@GetMapping("/project")
public void getProject(ModelMap modelMap, @RequestParam(value = "id") Integer id) {
if (id != null && id > 0) {
modelMap.put("projectDto", projectService.findOneDto(id));
} else {
modelMap.put("projectDto", new ProjectDto());
}
}
@ModelAttribute("allStatuses")
public List<Project.ProjectStatus> getProjectStatuses() {
return projectService.getProjectStatuses();
}
}

@ -3,24 +3,60 @@ package ru.ulstu.project.model;
import org.hibernate.validator.constraints.NotBlank;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.grant.model.Grant;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Project extends BaseEntity {
public enum ProjectStatus {
APPLICATION("Заявка"),
ON_COMPETITION("Отправлен на конкурс"),
SUCCESSFUL_PASSAGE("Успешное прохождение"),
IN_WORK("В работе"),
COMPLETED("Завершен"),
FAILED("Провалены сроки");
private String statusName;
ProjectStatus(String statusName) {
this.statusName = statusName;
}
public String getStatusName() {
return statusName;
}
}
@NotBlank
private String title;
@Enumerated(value = EnumType.STRING)
private ProjectStatus status = ProjectStatus.APPLICATION;
@NotNull
private String description;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "project_id")
private List<Deadline> deadlines = new ArrayList<>();
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "grant_id")
private Grant grant;
@NotNull
private String repository;
public String getTitle() {
return title;
}
@ -29,6 +65,38 @@ public class Project extends BaseEntity {
this.title = title;
}
public ProjectStatus getStatus() {
return status;
}
public void setStatus(ProjectStatus status) {
this.status = status;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Grant getGrant() {
return grant;
}
public void setGrant(Grant grant) {
this.grant = grant;
}
public String getRepository() {
return repository;
}
public void setRepository(String repository) {
this.repository = repository;
}
public List<Deadline> getDeadlines() {
return deadlines;
}

@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.NotEmpty;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.grant.model.GrantDto;
import java.util.ArrayList;
import java.util.List;
@ -13,8 +14,11 @@ public class ProjectDto {
@NotEmpty
private String title;
private Project.ProjectStatus status;
private String description;
private List<Deadline> deadlines = new ArrayList<>();
private GrantDto grant;
private String repository;
public ProjectDto() {
}
@ -26,9 +30,17 @@ public class ProjectDto {
@JsonCreator
public ProjectDto(@JsonProperty("id") Integer id,
@JsonProperty("title") String title,
@JsonProperty("status") Project.ProjectStatus status,
@JsonProperty("description") String description,
@JsonProperty("grant") GrantDto grant,
@JsonProperty("repository") String repository,
@JsonProperty("deadlines") List<Deadline> deadlines) {
this.id = id;
this.title = title;
this.status = status;
this.description = description;
this.grant = grant;
this.repository = repository;
this.deadlines = deadlines;
}
@ -36,6 +48,10 @@ public class ProjectDto {
public ProjectDto(Project project) {
this.id = project.getId();
this.title = project.getTitle();
this.status = project.getStatus();
this.description = project.getDescription();
this.grant = project.getGrant() == null ? null : new GrantDto(project.getGrant());
this.repository = project.getRepository();
this.deadlines = project.getDeadlines();
}
@ -55,6 +71,38 @@ public class ProjectDto {
this.title = title;
}
public Project.ProjectStatus getStatus() {
return status;
}
public void setStatus(Project.ProjectStatus status) {
this.status = status;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public GrantDto getGrant() {
return grant;
}
public void setGrant(GrantDto grant) {
this.grant = grant;
}
public String getRepository() {
return repository;
}
public void setRepository(String repository) {
this.repository = repository;
}
public List<Deadline> getDeadlines() {
return deadlines;
}

@ -2,17 +2,21 @@ package ru.ulstu.project.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;
import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.project.model.Project;
import ru.ulstu.project.model.ProjectDto;
import ru.ulstu.project.repository.ProjectRepository;
import java.util.Arrays;
import java.util.List;
import static org.springframework.util.ObjectUtils.isEmpty;
import static ru.ulstu.core.util.StreamApiUtils.convert;
@Service
public class ProjectService {
private final static int MAX_DISPLAY_SIZE = 40;
private final ProjectRepository projectRepository;
private final DeadlineService deadlineService;
@ -27,6 +31,20 @@ public class ProjectService {
return projectRepository.findAll();
}
public List<ProjectDto> findAllDto() {
List<ProjectDto> projects = convert(findAll(), ProjectDto::new);
projects.forEach(projectDto -> projectDto.setTitle(StringUtils.abbreviate(projectDto.getTitle(), MAX_DISPLAY_SIZE)));
return projects;
}
public ProjectDto findOneDto(Integer id) {
return new ProjectDto(projectRepository.findOne(id));
}
public List<Project.ProjectStatus> getProjectStatuses() {
return Arrays.asList(Project.ProjectStatus.values());
}
@Transactional
public Project create(ProjectDto projectDto) {
Project newProject = copyFromDto(new Project(), projectDto);

@ -0,0 +1,16 @@
package ru.ulstu.students.controller;
import org.springframework.validation.Errors;
public class Navigation {
public static final String REDIRECT_TO = "redirect:%s";
public static final String TASKS_PAGE = "/students/tasks";
public static final String TASK_PAGE = "/students/task";
public static String hasErrors(Errors errors, String page) {
if (errors.hasErrors()) {
return page;
}
return null;
}
}

@ -0,0 +1,84 @@
package ru.ulstu.students.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.students.model.Task;
import ru.ulstu.students.model.TaskDto;
import ru.ulstu.students.service.TaskService;
import springfox.documentation.annotations.ApiIgnore;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import static org.springframework.util.StringUtils.isEmpty;
import static ru.ulstu.students.controller.Navigation.*;
@Controller()
@RequestMapping(value = "/students")
@ApiIgnore
public class TaskController {
private final TaskService taskService;
public TaskController(TaskService taskService) {
this.taskService = taskService;
}
@GetMapping("/tasks")
public void getTasks(ModelMap modelMap) {
modelMap.put("tasks", taskService.findAllDto());
}
@GetMapping("/dashboard")
public void getDashboard(ModelMap modelMap) {
modelMap.put("tasks", taskService.findAllDto());
}
@GetMapping("/task")
public void getTask(ModelMap modelMap, @RequestParam(value = "id") Integer id) {
if (id != null && id > 0) {
modelMap.put("taskDto", taskService.findOneDto(id));
} else {
modelMap.put("taskDto", new TaskDto());
}
}
@PostMapping(value = "/task", params = "save")
public String save(@Valid TaskDto taskDto, Errors errors) throws IOException {
filterEmptyDeadlines(taskDto);
if (taskDto.getDeadlines().isEmpty()) {
errors.rejectValue("deadlines", "errorCode", "Не может быть пустым");
}
if (errors.hasErrors()) {
return TASK_PAGE;
}
taskService.save(taskDto);
return String.format(REDIRECT_TO, TASKS_PAGE);
}
@PostMapping(value = "/task", params = "addDeadline")
public String addDeadline(@Valid TaskDto taskDto, Errors errors) {
filterEmptyDeadlines(taskDto);
if (errors.hasErrors()) {
return TASK_PAGE;
}
taskDto.getDeadlines().add(new Deadline());
return TASK_PAGE;
}
@ModelAttribute("allStatuses")
public List<Task.TaskStatus> getTaskStatuses() {
return taskService.getTaskStatuses();
}
private void filterEmptyDeadlines(TaskDto taskDto) {
taskDto.setDeadlines(taskDto.getDeadlines().stream()
.filter(dto -> dto.getDate() != null || !isEmpty(dto.getDescription()))
.collect(Collectors.toList()));
}
}

@ -0,0 +1,118 @@
package ru.ulstu.students.model;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.validator.constraints.NotBlank;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.tags.model.Tag;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Entity
public class Task extends BaseEntity {
public enum TaskStatus {
IN_WORK("В работе"),
COMPLETED("Завершен"),
FAILED("Провалены сроки"),
LOADED_FROM_KIAS("Загружен автоматически");
private String statusName;
TaskStatus(String name) {
this.statusName = name;
}
public String getStatusName() {
return statusName;
}
}
@NotBlank
private String title;
private String description;
@Enumerated(value = EnumType.STRING)
private ru.ulstu.students.model.Task.TaskStatus status = TaskStatus.IN_WORK;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "task_id", unique = true)
@Fetch(FetchMode.SUBSELECT)
@OrderBy("date")
private List<Deadline> deadlines = new ArrayList<>();
@Column(name = "create_date")
@Temporal(TemporalType.TIMESTAMP)
private Date createDate = new Date();
@Column(name = "update_date")
@Temporal(TemporalType.TIMESTAMP)
private Date updateDate = new Date();
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "task_tags",
joinColumns = {@JoinColumn(name = "task_id")},
inverseJoinColumns = {@JoinColumn(name = "tag_id")})
private List<Tag> tags = new ArrayList<>();
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public TaskStatus getStatus() {
return status;
}
public void setStatus(TaskStatus status) {
this.status = status;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<Deadline> getDeadlines() {
return deadlines;
}
public void setDeadlines(List<Deadline> deadlines) {
this.deadlines = deadlines;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
}

@ -0,0 +1,144 @@
package ru.ulstu.students.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.NotEmpty;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.tags.model.Tag;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class TaskDto {
private final static int MAX_TAGS_LENGTH = 50;
private Integer id;
@NotEmpty
private String title;
private String description;
private Task.TaskStatus status;
private List<Deadline> deadlines = new ArrayList<>();
private Date createDate;
private Date updateDate;
private Set<Integer> tagIds;
private List<Tag> tags;
public TaskDto() {
deadlines.add(new Deadline());
}
@JsonCreator
public TaskDto(@JsonProperty("id") Integer id,
@JsonProperty("title") String title,
@JsonProperty("description") String description,
@JsonProperty("createDate") Date createDate,
@JsonProperty("updateDate") Date updateDate,
@JsonProperty("status") Task.TaskStatus status,
@JsonProperty("deadlines") List<Deadline> deadlines,
@JsonProperty("tagIds") Set<Integer> tagIds,
@JsonProperty("tags") List<Tag> tags) {
this.id = id;
this.title = title;
this.status = status;
this.deadlines = deadlines;
this.createDate = createDate;
this.updateDate = updateDate;
this.description = description;
this.tags = tags;
}
public TaskDto(Task task) {
this.id = task.getId();
this.title = task.getTitle();
this.status = task.getStatus();
this.deadlines = task.getDeadlines();
this.createDate = task.getCreateDate();
this.updateDate = task.getUpdateDate();
this.description = task.getDescription();
this.tags = task.getTags();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Task.TaskStatus getStatus() {
return status;
}
public void setStatus(Task.TaskStatus status) {
this.status = status;
}
public List<Deadline> getDeadlines() {
return deadlines;
}
public void setDeadlines(List<Deadline> deadlines) {
this.deadlines = deadlines;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public Set<Integer> getTagIds() {
return tagIds;
}
public void setTagIds(Set<Integer> tagIds) {
this.tagIds = tagIds;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
public String getTagsString() {
return StringUtils.abbreviate(tags
.stream()
.map(tag -> tag.getTagName())
.collect(Collectors.joining(", ")), MAX_TAGS_LENGTH);
}
}

@ -0,0 +1,7 @@
package ru.ulstu.students.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.students.model.Task;
public interface TaskRepository extends JpaRepository<Task, Integer> {
}

@ -0,0 +1,95 @@
package ru.ulstu.students.service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.students.model.Task;
import ru.ulstu.students.model.TaskDto;
import ru.ulstu.students.repository.TaskRepository;
import ru.ulstu.tags.service.TagService;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import static org.springframework.util.ObjectUtils.isEmpty;
import static ru.ulstu.core.util.StreamApiUtils.convert;
import static ru.ulstu.students.model.Task.TaskStatus.IN_WORK;
@Service
public class TaskService {
private final static int MAX_DISPLAY_SIZE = 40;
private final TaskRepository taskRepository;
private final DeadlineService deadlineService;
private final TagService tagService;
public TaskService(TaskRepository grantRepository,
DeadlineService deadlineService, TagService tagService) {
this.taskRepository = grantRepository;
this.deadlineService = deadlineService;
this.tagService = tagService;
}
public List<Task> findAll() {
return taskRepository.findAll();
}
public List<TaskDto> findAllDto() {
List<TaskDto> tasks = convert(findAll(), TaskDto::new);
tasks.forEach(taskDto -> taskDto.setTitle(StringUtils.abbreviate(taskDto.getTitle(), MAX_DISPLAY_SIZE)));
return tasks;
}
public TaskDto findOneDto(Integer id) {
return new TaskDto(taskRepository.findOne(id));
}
@Transactional
public Integer create(TaskDto taskDto) throws IOException {
Task newTask = copyFromDto(new Task(), taskDto);
newTask = taskRepository.save(newTask);
return newTask.getId();
}
private Task copyFromDto(Task task, TaskDto taskDto) throws IOException {
task.setTitle(taskDto.getTitle());
task.setDescription(taskDto.getDescription());
task.setStatus(taskDto.getStatus() == null ? IN_WORK : taskDto.getStatus());
task.setDeadlines(deadlineService.saveOrCreate(taskDto.getDeadlines()));
task.setCreateDate(task.getCreateDate() == null ? new Date() : task.getCreateDate());
task.setUpdateDate(new Date());
task.getTags().clear();
task.setTags(tagService.saveOrCreate(taskDto.getTags()));
return task;
}
@Transactional
public Integer update(TaskDto taskDto) throws IOException {
Task task = taskRepository.findOne(taskDto.getId());
taskRepository.save(copyFromDto(task, taskDto));
return task.getId();
}
@Transactional
public void delete(Integer taskId) throws IOException {
Task task = taskRepository.findOne(taskId);
taskRepository.delete(task);
}
public void save(TaskDto taskDto) throws IOException {
if (isEmpty(taskDto.getId())) {
create(taskDto);
} else {
update(taskDto);
}
}
public List<Task.TaskStatus> getTaskStatuses() {
return Arrays.asList(Task.TaskStatus.values());
}
}

@ -0,0 +1,44 @@
package ru.ulstu.tags.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.NotEmpty;
import ru.ulstu.core.model.BaseEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.Size;
@Entity
@Table(name = "tag")
public class Tag extends BaseEntity {
@NotEmpty
@Size(max = 50)
@Column(name = "tag_name")
private String tagName;
public Tag() {
}
@JsonCreator
public Tag(@JsonProperty("id") Integer id,
@JsonProperty("tag_name") String tagName) {
this.setId(id);
this.tagName = tagName;
}
public Tag(String name) {
this.tagName = name;
}
public String getTagName() {
return tagName;
}
public void setTagName(String tagName) {
this.tagName = tagName;
}
}

@ -0,0 +1,12 @@
package ru.ulstu.tags.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.tags.model.Tag;
public interface TagRepository extends JpaRepository<Tag, Integer> {
@Query("SELECT t FROM Tag t WHERE (t.tagName = :tagName)")
Tag findByName(@Param("tagName") String tagName);
}

@ -0,0 +1,53 @@
package ru.ulstu.tags.service;
import org.springframework.stereotype.Service;
import ru.ulstu.tags.model.Tag;
import ru.ulstu.tags.repository.TagRepository;
import javax.transaction.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class TagService {
private final TagRepository tagRepository;
public TagService(TagRepository tagRepository) {
this.tagRepository = tagRepository;
}
public List<Tag> saveOrCreate(List<Tag> tags) {
return tags
.stream()
.map(tag -> {
if (tag.getId() != null) {
return getExistById(tag);
} else {
Tag existTag = isExistByName(tag.getTagName());
return existTag != null ? existTag : create(tag);
}
}).collect(Collectors.toList());
}
@Transactional
public Tag getExistById(Tag tag) {
return tagRepository.findOne(tag.getId());
}
@Transactional
public Tag isExistByName(String tagName) {
return tagRepository.findByName(tagName);
}
@Transactional
public Tag create(Tag tag) {
Tag newTag = new Tag();
newTag.setTagName(tag.getTagName());
newTag = tagRepository.save(newTag);
return newTag;
}
}

@ -2,6 +2,7 @@ package ru.ulstu.timeline.model;
import org.hibernate.validator.constraints.NotBlank;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.user.model.User;
import javax.persistence.CascadeType;
@ -71,6 +72,10 @@ public class Event extends BaseEntity {
@JoinColumn(name = "child_id")
private List<Event> parents;
@ManyToOne
@JoinColumn(name = "paper_id")
private Paper paper;
public String getTitle() {
return title;
}
@ -150,4 +155,12 @@ public class Event extends BaseEntity {
public void setParents(List<Event> parents) {
this.parents = parents;
}
public Paper getPaper() {
return paper;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
}

@ -3,6 +3,7 @@ package ru.ulstu.timeline.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.NotBlank;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.user.model.UserDto;
import javax.validation.constraints.NotNull;
@ -23,6 +24,7 @@ public class EventDto {
private final Date updateDate;
private final String description;
private final List<UserDto> recipients;
private PaperDto paperDto;
@JsonCreator
public EventDto(@JsonProperty("id") Integer id,
@ -33,6 +35,7 @@ public class EventDto {
@JsonProperty("createDate") Date createDate,
@JsonProperty("updateDate") Date updateDate,
@JsonProperty("description") String description,
@JsonProperty("paperDto") PaperDto paperDto,
@JsonProperty("recipients") List<UserDto> recipients) {
this.id = id;
this.title = title;
@ -43,6 +46,7 @@ public class EventDto {
this.updateDate = updateDate;
this.description = description;
this.recipients = recipients;
this.paperDto = paperDto;
}
public EventDto(Event event) {
@ -54,6 +58,7 @@ public class EventDto {
this.createDate = event.getCreateDate();
this.updateDate = event.getUpdateDate();
this.description = event.getDescription();
this.paperDto = new PaperDto(event.getPaper());
this.recipients = convert(event.getRecipients(), UserDto::new);
}
@ -92,4 +97,12 @@ public class EventDto {
public Date getExecuteDate() {
return executeDate;
}
public PaperDto getPaperDto() {
return paperDto;
}
public void setPaperDto(PaperDto paperDto) {
this.paperDto = paperDto;
}
}

@ -6,6 +6,7 @@ import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
@Entity
@ -13,7 +14,7 @@ public class Timeline extends BaseEntity {
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "timeline_id")
private List<Event> events;
private List<Event> events = new ArrayList<>();
public List<Event> getEvents() {
return events;

@ -2,6 +2,7 @@ package ru.ulstu.timeline.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.timeline.model.Event;
import java.util.List;
@ -12,4 +13,6 @@ public interface EventRepository extends JpaRepository<Event, Integer> {
@Query("SELECT e FROM Event e WHERE e.executeDate > CURRENT_DATE ORDER BY e.executeDate")
List<Event> findAllFuture();
List<Event> findAllByPaper(Paper paper);
}

@ -34,6 +34,10 @@ public class EventScheduler {
Map<String, Object> variables = ImmutableMap.of("description", event.getDescription());
event.getRecipients()
.forEach(recipient -> mailService.sendEmailFromTemplate(variables, recipient, "eventNotification", event.getTitle()));
if (event.getPeriod() == null) {
event.setStatus(Event.EventStatus.COMPLETED);
eventService.save(event);
}
});
}

@ -1,15 +1,22 @@
package ru.ulstu.timeline.service;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.timeline.model.Event;
import ru.ulstu.timeline.model.EventDto;
import ru.ulstu.timeline.model.Timeline;
import ru.ulstu.timeline.repository.EventRepository;
import ru.ulstu.user.model.UserDto;
import ru.ulstu.user.service.UserService;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import static ru.ulstu.core.util.StreamApiUtils.convert;
@ -17,11 +24,14 @@ import static ru.ulstu.core.util.StreamApiUtils.convert;
public class EventService {
private final EventRepository eventRepository;
private final TimelineService timelineService;
private final UserService userService;
public EventService(EventRepository eventRepository,
@Lazy TimelineService timelineService,
UserService userService) {
this.eventRepository = eventRepository;
this.timelineService = timelineService;
this.userService = userService;
}
@ -56,6 +66,11 @@ public class EventService {
return eventRepository.save(copyFromDto(event, eventDto)).getId();
}
@Transactional
public Event save(Event event) {
return eventRepository.save(event);
}
@Transactional
public void delete(Integer eventId) {
Event event = eventRepository.findOne(eventId);
@ -84,6 +99,36 @@ public class EventService {
eventRepository.save(parentEvent);
}
public void createFromPaper(Paper newPaper) {
List<Timeline> timelines = timelineService.findAll();
Timeline timeline = timelines.isEmpty() ? new Timeline() : timelines.get(0);
for (Deadline deadline : newPaper.getDeadlines()
.stream()
.filter(d -> d.getDate().after(new Date()) || DateUtils.isSameDay(d.getDate(), new Date()))
.collect(Collectors.toList())) {
Event newEvent = new Event();
newEvent.setTitle("Дедлайн статьи");
newEvent.setStatus(Event.EventStatus.NEW);
newEvent.setExecuteDate(deadline.getDate());
newEvent.setCreateDate(new Date());
newEvent.setUpdateDate(new Date());
newEvent.setDescription("Дедлайн '" + deadline.getDescription() + "' cтатьи '" + newPaper.getTitle() + "'");
newEvent.setRecipients(new ArrayList(newPaper.getAuthors()));
newEvent.setPaper(newPaper);
eventRepository.save(newEvent);
timeline.getEvents().add(newEvent);
timelineService.save(timeline);
}
}
public void updatePaperDeadlines(Paper paper) {
eventRepository.delete(eventRepository.findAllByPaper(paper));
createFromPaper(paper);
}
public List<Event> findByCurrentDate() {
return eventRepository.findByCurrentDate();
}

@ -23,15 +23,24 @@ public class TimelineService {
this.eventService = eventService;
}
public List<TimelineDto> findAll() {
public List<TimelineDto> findAllDto() {
return convert(timelineRepository.findAll(), TimelineDto::new);
}
public List<Timeline> findAll() {
return timelineRepository.findAll();
}
@Transactional
public int create(TimelineDto timelineDto) {
return timelineRepository.save(copyFromDto(new Timeline(), timelineDto)).getId();
}
@Transactional
public Timeline save(Timeline timeline) {
return timelineRepository.save(timeline);
}
private Timeline copyFromDto(Timeline timeline, TimelineDto timelineDto) {
timeline.setEvents(eventService.findByIds(convert(timelineDto.getEvents(), EventDto::getId)));
return timeline;

@ -24,6 +24,8 @@ import java.util.Set;
@Entity
@Table(name = "users")
public class User extends BaseEntity {
private final static String USER_ABBREVIATE_TEMPLATE = "%s %s%s";
@NotNull
@Pattern(regexp = Constants.LOGIN_REGEX)
@Size(min = 1, max = 50)
@ -186,4 +188,11 @@ public class User extends BaseEntity {
public void setPatronymic(String patronymic) {
this.patronymic = patronymic;
}
public String getUserAbbreviate() {
return String.format(USER_ABBREVIATE_TEMPLATE,
lastName == null ? "" : lastName,
firstName == null ? "" : firstName.substring(0, 1) + ".",
patronymic == null ? "" : patronymic.substring(0, 1) + ".");
}
}

@ -35,4 +35,5 @@ liquibase.change-log=classpath:db/changelog-master.xml
ng-tracker.base-url=http://127.0.0.1:8080
ng-tracker.undead-user-login=admin
ng-tracker.dev-mode=true
ng-tracker.use-https=false
ng-tracker.use-https=false
ng-tracker.check-run=false

@ -1,489 +1,298 @@
Anton Romanov;Thu Mar 15 11:10:34 2018 +0400;change to date time
romanov73;Thu Mar 15 11:03:19 2018 +0400;read commits in constructor
romanov73;Thu Mar 15 09:12:07 2018 +0400;add commits page
Romanov Anton;Wed Mar 14 20:26:54 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 20:16:53 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 20:08:09 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 20:00:58 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 19:50:22 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 19:34:17 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 19:20:42 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 18:59:18 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 18:47:17 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 18:35:37 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 18:33:54 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 18:29:27 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 18:21:18 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 18:19:27 2018 +0000;Update README.md
Romanov Anton;Wed Mar 14 18:16:06 2018 +0000;Update README.md
romanov73;Wed Mar 14 21:28:10 2018 +0400;fix using constant
Aleksey Filippov;Wed Mar 14 20:07:25 2018 +0400;some fixes after merge
Aleksey Filippov;Wed Mar 14 19:52:45 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into odin-ui
Aleksey Filippov;Wed Mar 14 19:48:45 2018 +0400;refactoring of odin paginator
romanov73;Wed Mar 14 18:43:16 2018 +0400;Merge branch 'develop' into 36-rest
romanov73;Wed Mar 14 18:17:02 2018 +0400;Merge branch 'develop' into 36-rest
Aleksey Filippov;Wed Mar 14 18:11:00 2018 +0400;fix null value check in formatter
Aleksey Filippov;Wed Mar 14 18:06:16 2018 +0400;fix odin paginator style, fix odin negative file
romanov73;Wed Mar 14 18:04:47 2018 +0400;rename entities
Aleksey Filippov;Wed Mar 14 17:58:59 2018 +0400;improve odin table look
romanov73;Wed Mar 14 17:47:45 2018 +0400;fix db changelogs
romanov73;Wed Mar 14 17:47:20 2018 +0400;fix db changelogs
Gleb;Wed Mar 14 08:50:23 2018 +0000;Merge branch '48-' into 'develop'
funny73;Wed Mar 14 12:28:55 2018 +0400;Поправил отображение подразделения при редактировании смены
Aleksey Filippov;Wed Mar 14 00:02:24 2018 +0400;move navbar to the left, move odin css to separate file
Aleksey Filippov;Tue Mar 13 23:26:33 2018 +0400;some style fixes
Aleksey Filippov;Tue Mar 13 23:22:37 2018 +0400;move version panel to navbar
funny73;Tue Mar 13 20:41:41 2018 +0400;Поправил валидацию сменности
romanov73;Tue Mar 13 17:26:54 2018 +0400;fix offsetable page request
romanov73;Tue Mar 13 17:26:02 2018 +0400;fix table constructor
romanov73;Tue Mar 13 17:24:56 2018 +0400;fix checking empty value
Romanov Anton;Tue Mar 13 13:09:41 2018 +0000;Merge branch 'odin-ui' into '36-rest'
Aleksey Filippov;Tue Mar 13 16:59:27 2018 +0400;notes updated
Aleksey Filippov;Tue Mar 13 16:56:00 2018 +0400;odin refactoring
Aleksey Filippov;Tue Mar 13 16:53:38 2018 +0400;odin refactoring
romanov73;Tue Mar 13 15:27:17 2018 +0400;fix tool load calc
romanov73;Tue Mar 13 14:46:46 2018 +0400;fix area load calc
Aleksey Filippov;Tue Mar 13 13:38:23 2018 +0400;some fixes
romanov73;Tue Mar 13 13:33:25 2018 +0400;Merge remote-tracking branch 'origin/develop' into develop
romanov73;Tue Mar 13 13:33:07 2018 +0400;fix tools count calc
Aleksey Filippov;Tue Mar 13 13:12:09 2018 +0400;some odin refactoring
Aleksey Filippov;Tue Mar 13 13:11:41 2018 +0400;some offsetablepagerequest fix
Aleksey Filippov;Tue Mar 13 13:06:48 2018 +0400;add offsetablepagerequest
Aleksey Filippov;Tue Mar 13 07:27:12 2018 +0000;Merge branch '51-rest-points' into '36-rest'
romanov73;Tue Mar 13 11:22:02 2018 +0400;fix by comment: remove default version id
romanov73;Tue Mar 13 00:04:50 2018 +0400;fix path
romanov73;Mon Mar 12 23:55:05 2018 +0400;add tool square dictionary
romanov73;Mon Mar 12 23:36:49 2018 +0400;add dictionary pages
romanov73;Mon Mar 12 23:18:01 2018 +0400;sort second level menu items by name
romanov73;Mon Mar 12 23:11:22 2018 +0400;fix menu
romanov73;Mon Mar 12 22:52:15 2018 +0400;add stream api utils and converter for "map ... collect"
funny73;Mon Mar 12 20:01:47 2018 +0400;Добавил свойство базового изделия для изделия
romanov73;Mon Mar 12 19:46:52 2018 +0400;refactor units
romanov73;Mon Mar 12 19:36:57 2018 +0400;refactor tool types and work types
romanov73;Mon Mar 12 19:20:23 2018 +0400;refactor tools
romanov73;Mon Mar 12 19:07:09 2018 +0400;refactor stages
romanov73;Mon Mar 12 18:53:26 2018 +0400;refactor positions
romanov73;Mon Mar 12 18:27:36 2018 +0400;refactor employees
romanov73;Mon Mar 12 18:26:49 2018 +0400;refactor employees
romanov73;Mon Mar 12 18:09:38 2018 +0400;refactor categories
Aleksey Filippov;Mon Mar 12 17:32:06 2018 +0400;todo added
Aleksey Filippov;Mon Mar 12 17:29:51 2018 +0400;paginator added to odin
Aleksey Filippov;Mon Mar 12 17:29:06 2018 +0400;notes updated
funny73;Mon Mar 12 16:29:13 2018 +0400;Добавил сущность изделие без привязки к производственной программе
funny73;Mon Mar 12 15:16:35 2018 +0400;Переименовал сущность Product на ProductOnProgram Ещё немного переименования
funny73;Mon Mar 12 14:39:52 2018 +0400;Переименовал сущность Product на ProductOnProgram
Aleksey Filippov;Mon Mar 12 13:44:42 2018 +0400;add formatters and initial form support to odin
Aleksey Filippov;Mon Mar 12 13:44:16 2018 +0400;userlistdto refactoring
Aleksey Filippov;Mon Mar 12 13:43:59 2018 +0400;dateutils improvements
Aleksey Filippov;Mon Mar 12 13:43:43 2018 +0400;add support of localdatetime type to odin
Aleksey Filippov;Mon Mar 12 13:42:54 2018 +0400;odin backend example added
Aleksey Filippov;Mon Mar 12 13:42:12 2018 +0400;notes updated
funny73;Mon Mar 12 12:16:02 2018 +0400;Поправил всплывающие сообщения при работе с "Категориями"
Aleksey Filippov;Mon Mar 12 11:25:51 2018 +0400;some refactoring
Aleksey Filippov;Mon Mar 12 11:25:30 2018 +0400;odinid annotation added
Aleksey Filippov;Sun Mar 11 15:23:49 2018 +0400;notes updated
Aleksey Filippov;Sun Mar 11 15:18:45 2018 +0400;some fixes
Aleksey Filippov;Sun Mar 11 15:09:57 2018 +0400;simple table draw support added, some refactoring
Aleksey Filippov;Sun Mar 11 15:08:22 2018 +0400;add user id field to userlistdto
Aleksey Filippov;Sun Mar 11 14:32:50 2018 +0400;add jsonproperty annotation support
Aleksey Filippov;Sun Mar 11 13:38:45 2018 +0400;some template fixes
Aleksey Filippov;Sun Mar 11 13:33:09 2018 +0400;some balance page fixes
Aleksey Filippov;Sun Mar 11 13:25:58 2018 +0400;add jsonignore annotation support
Aleksey Filippov;Thu Mar 8 14:16:20 2018 +0400;some odin improvements
Aleksey Filippov;Wed Mar 7 16:03:04 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
Aleksey Filippov;Wed Mar 7 16:01:21 2018 +0400;odin submodule for basic types added, some refactoring
romanov73;Tue Mar 6 22:52:02 2018 +0400;remove old packages
romanov73;Tue Mar 6 19:12:27 2018 +0400;add tool type crud
romanov73;Tue Mar 6 13:09:51 2018 +0400;add version crud
romanov73;Tue Mar 6 10:48:36 2018 +0400;add unit crud
romanov73;Mon Mar 5 16:58:37 2018 +0400;fix tree
romanov73;Mon Mar 5 16:38:37 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
romanov73;Mon Mar 5 16:38:21 2018 +0400;employee crud
Aleksey Filippov;Mon Mar 5 15:43:49 2018 +0400;some fixes
Aleksey Filippov;Mon Mar 5 15:39:53 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
Aleksey Filippov;Mon Mar 5 15:39:33 2018 +0400;user reset password function added, some refactoring
romanov73;Mon Mar 5 15:29:16 2018 +0400;fix delete category
Aleksey Filippov;Mon Mar 5 15:08:27 2018 +0400;user change password function added, some refactoring
romanov73;Mon Mar 5 15:08:17 2018 +0400;add category crud
romanov73;Mon Mar 5 14:07:10 2018 +0400;add tree component
Aleksey Filippov;Mon Mar 5 11:30:22 2018 +0400;user delete function added, some refactoring
Aleksey Filippov;Mon Mar 5 11:18:23 2018 +0400;user update function added
Aleksey Filippov;Mon Mar 5 11:18:06 2018 +0400;some refactoring
Aleksey Filippov;Mon Mar 5 10:06:04 2018 +0400;add user activation function
Aleksey Filippov;Mon Mar 5 09:48:22 2018 +0400;add scheduler for users
Aleksey Filippov;Mon Mar 5 09:48:07 2018 +0400;add activateddate field to userentity
Aleksey Filippov;Mon Mar 5 09:47:25 2018 +0400;notes file updated
Aleksey Filippov;Mon Mar 5 09:47:11 2018 +0400;some refactoring
Aleksey Filippov;Mon Mar 5 09:21:49 2018 +0400;thymeleaf cache settings added
Aleksey Filippov;Mon Mar 5 09:21:11 2018 +0400;notes file added
Aleksey Filippov;Mon Mar 5 09:20:57 2018 +0400;some refactoring
Aleksey Filippov;Mon Mar 5 08:37:01 2018 +0400;some refactoring
romanov73;Mon Mar 5 00:08:02 2018 +0400;add callbacks on version getters
romanov73;Mon Mar 5 00:07:34 2018 +0400;fix npe
romanov73;Sun Mar 4 01:13:57 2018 +0400;fix column style
romanov73;Sun Mar 4 01:06:38 2018 +0400;fix table style
romanov73;Sun Mar 4 00:27:14 2018 +0400;add balance dto + draw employee balance
romanov73;Sat Mar 3 22:43:06 2018 +0400;add balance services
romanov73;Sat Mar 3 16:31:19 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
romanov73;Sat Mar 3 16:31:04 2018 +0400;add employee balance table
Aleksey Filippov;Sat Mar 3 15:54:23 2018 +0400;some user support improvements
Aleksey Filippov;Sat Mar 3 15:53:20 2018 +0400;edit migration files, need manual fix of databasechangelog table
Aleksey Filippov;Sat Mar 3 15:51:58 2018 +0400;add application properties handler
Aleksey Filippov;Sat Mar 3 15:51:19 2018 +0400;disable tests
Aleksey Filippov;Sat Mar 3 13:49:32 2018 +0400;some refactoring
romanov73;Fri Mar 2 18:10:23 2018 +0400;add balance page
Aleksey Filippov;Fri Mar 2 18:04:39 2018 +0400;some refactoring
Aleksey Filippov;Fri Mar 2 17:51:41 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
Aleksey Filippov;Fri Mar 2 17:50:59 2018 +0400;advicecontroller improvements
Aleksey Filippov;Fri Mar 2 17:50:39 2018 +0400;some mvc improvements
romanov73;Fri Mar 2 15:15:46 2018 +0400;add dtos
romanov73;Fri Mar 2 15:02:38 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
Aleksey Filippov;Fri Mar 2 14:54:33 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
Aleksey Filippov;Fri Mar 2 14:53:39 2018 +0400;add migrations
Aleksey Filippov;Fri Mar 2 14:53:30 2018 +0400;some core improvements
Aleksey Filippov;Fri Mar 2 14:53:13 2018 +0400;some users improvements
romanov73;Fri Mar 2 12:42:54 2018 +0400;add category service
romanov73;Fri Mar 2 12:37:51 2018 +0400;fix unit service
romanov73;Fri Mar 2 11:24:11 2018 +0400;add unit controller
romanov73;Thu Mar 1 23:19:42 2018 +0400;fix versions panel
romanov73;Thu Mar 1 22:50:57 2018 +0400;Merge branch 'develop' into 36-rest
romanov73;Thu Mar 1 22:50:37 2018 +0400;Merge branch 'develop' into 36-rest
Romanov Anton;Thu Mar 1 18:31:03 2018 +0000;Merge branch '29-' into 'develop'
romanov73;Thu Mar 1 22:25:49 2018 +0400;change versions
romanov73;Thu Mar 1 20:14:22 2018 +0400;show version select
romanov73;Thu Mar 1 19:56:24 2018 +0400;add old models, add versions controller
romanov73;Thu Mar 1 19:55:59 2018 +0400;add old models, add versions controller
romanov73;Thu Mar 1 19:04:47 2018 +0400;save menu to session
romanov73;Thu Mar 1 18:50:00 2018 +0400;add favicon
funny73;Thu Mar 1 18:01:43 2018 +0400;1) Поправил имена колонок и таблицы для смен под постгрес 2) Исправил ошибку в имени переменной thidShift ->thirdShift
romanov73;Thu Mar 1 16:03:03 2018 +0400;add menu and restore changelogs
funny73;Thu Mar 1 15:33:36 2018 +0400;Добавил распорядок смен для каждого подразделения. Смена назначается на месяц. Есть возможность сохранить любой вариант комбинирования 1,2 и 3 смены. Например (1,3); (2); ()... Добавлен интерфейс для просмотра и редактирования распорядка смен по каждому подразделению. Добавлена валидация - для каждого месяца может быть только один распорядок смен.
Aleksey Filippov;Thu Mar 1 15:23:06 2018 +0400;migrate to webjars
Aleksey Filippov;Thu Mar 1 13:31:16 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
Aleksey Filippov;Thu Mar 1 13:30:55 2018 +0400;create migrations for user models
Aleksey Filippov;Thu Mar 1 13:30:09 2018 +0400;old code refactoring
romanov73;Thu Mar 1 12:51:14 2018 +0400;add basic menu from rest
romanov73;Thu Mar 1 11:51:17 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
romanov73;Thu Mar 1 11:50:59 2018 +0400;try to fix ci: 3 remove tests
Aleksey Filippov;Thu Mar 1 11:50:25 2018 +0400;Merge remote-tracking branch 'origin/36-rest' into 36-rest
Aleksey Filippov;Thu Mar 1 11:49:59 2018 +0400;moved to new database
romanov73;Thu Mar 1 11:45:40 2018 +0400;try to fix ci: 2 change image
romanov73;Thu Mar 1 11:44:42 2018 +0400;try to fix ci: 1
romanov73;Thu Mar 1 11:15:52 2018 +0400;fix csrf tokens
Aleksey Filippov;Thu Mar 1 00:25:43 2018 +0400;initial user management support added
romanov73;Wed Feb 28 22:26:00 2018 +0400;save current version in local storage
romanov73;Wed Feb 28 18:40:57 2018 +0400;add ajax datatable
romanov73;Wed Feb 28 18:01:23 2018 +0400;add static index page with menu
Romanov Anton;Tue Feb 27 16:53:04 2018 +0000;Merge branch '33-' into 'develop'
romanov73;Tue Feb 27 20:50:44 2018 +0400;calc area balance
romanov73;Tue Feb 27 17:36:31 2018 +0400;remove unused panel
Romanov Anton;Tue Feb 27 13:06:02 2018 +0000;Merge branch '32-' into 'develop'
romanov73;Tue Feb 27 17:02:35 2018 +0400;calc tool balance
romanov73;Tue Feb 27 15:45:39 2018 +0400;calc tool balance
romanov73;Tue Feb 27 12:16:41 2018 +0400;calc tool power
romanov73;Tue Feb 27 11:40:59 2018 +0400;use tool types in dto
romanov73;Tue Feb 27 11:29:05 2018 +0400;fix dtos
romanov73;Mon Feb 26 23:50:53 2018 +0400;inherit dtos
romanov73;Mon Feb 26 15:38:00 2018 +0400;fix services for balance calculation
Aleksey Filippov;Mon Feb 26 15:00:48 2018 +0400;move from maven to gradle, move from javaee to spring boot
romanov73;Thu Feb 22 18:03:35 2018 +0400;Add menu resource
Romanov Anton;Tue Feb 20 18:12:55 2018 +0000;Merge branch 'balance-different-dto' into 'develop'
romanov73;Tue Feb 20 22:09:33 2018 +0400;restore tests
romanov73;Tue Feb 20 21:46:45 2018 +0400;filter employees by stage
romanov73;Tue Feb 20 21:21:27 2018 +0400;filter employees by workload
romanov73;Tue Feb 20 20:58:23 2018 +0400;Merge branch 'develop' into balance-different-dto
funny73;Tue Feb 20 19:52:24 2018 +0400;Add shift unit model Add link to unit view
romanov73;Tue Feb 20 16:14:09 2018 +0400;Important fix using coefficient
romanov73;Mon Feb 19 19:00:07 2018 +0400;partially fix ajustment
romanov73;Mon Feb 19 18:24:10 2018 +0400;Modify dto for using with different periods and work types
Romanov Anton;Mon Feb 19 08:11:39 2018 +0000;Merge branch '30-' into 'develop'
romanov73;Mon Feb 19 12:09:05 2018 +0400;Add work type to position
Romanov Anton;Wed Feb 14 20:57:35 2018 +0000;Merge branch '34-' into 'develop'
romanov73;Thu Feb 15 00:51:24 2018 +0400;fixes by comments
romanov73;Thu Feb 15 00:47:21 2018 +0400;merge fields
romanov73;Wed Feb 14 23:42:35 2018 +0400;Merge branch 'develop' into 34-gleb
romanov73;Wed Feb 14 21:05:51 2018 +0400;add clock
Romanov Anton;Wed Feb 14 16:49:29 2018 +0000;Merge branch '45-balance-employee-recomendations' into 'develop'
romanov73;Wed Feb 14 20:46:59 2018 +0400;cleanup code
romanov73;Wed Feb 14 18:25:42 2018 +0400;reduce code
romanov73;Wed Feb 14 18:24:59 2018 +0400;adjust additional employees
romanov73;Wed Feb 14 17:22:10 2018 +0400;move employees from other units
romanov73;Tue Feb 13 23:59:09 2018 +0400;fix save product name
romanov73;Tue Feb 13 23:28:30 2018 +0400;add converter, fix UI and backing for add complex object
romanov73;Tue Feb 13 22:10:59 2018 +0400;Merge branch 'develop' into 34-gleb
funny73;Tue Feb 13 18:07:25 2018 +0400;Add stage to workload
funny73;Tue Feb 13 16:05:45 2018 +0400;Add stage to category
romanov73;Tue Feb 13 13:20:16 2018 +0400;add map of all units balances
romanov73;Tue Feb 13 11:24:50 2018 +0400;move method
romanov73;Tue Feb 13 00:35:30 2018 +0400;add dialog
romanov73;Mon Feb 12 22:59:49 2018 +0400;filter only workshops and manufactures
romanov73;Mon Feb 12 22:04:55 2018 +0400;rename employees
romanov73;Mon Feb 12 17:34:37 2018 +0400;fix font size
romanov73;Mon Feb 12 16:59:16 2018 +0400;fix versions panel width
Romanov Anton;Mon Feb 12 12:47:04 2018 +0000;Merge branch '41-' into 'develop'
romanov73;Mon Feb 12 16:43:06 2018 +0400;change to working hours
romanov73;Mon Feb 12 14:05:36 2018 +0400;remove constructor
romanov73;Mon Feb 12 14:05:13 2018 +0400;Merge remote-tracking branch 'origin/develop' into develop
romanov73;Mon Feb 12 14:04:57 2018 +0400;fix selects
Romanov Anton;Mon Feb 12 09:20:05 2018 +0000;Merge branch '39-work-type-code' into 'develop'
Aleksey Filippov;Mon Feb 12 13:16:36 2018 +0400;add migration for work type code
Aleksey Filippov;Mon Feb 12 13:16:28 2018 +0400;add work type code support to xhtml
Aleksey Filippov;Mon Feb 12 13:16:12 2018 +0400;add work type code
Romanov Anton;Mon Feb 12 08:25:47 2018 +0000;Update README.md
Romanov Anton;Mon Feb 12 08:25:35 2018 +0000;Update README.md
Romanov Anton;Mon Feb 12 08:07:30 2018 +0000;Update README.md
Romanov Anton;Mon Feb 12 07:10:38 2018 +0000;Merge branch '40-' into 'develop'
Aleksey Filippov;Mon Feb 12 11:08:13 2018 +0400;add migration for position type
Aleksey Filippov;Mon Feb 12 11:07:45 2018 +0400;add position type support to xhtml
Aleksey Filippov;Mon Feb 12 11:07:23 2018 +0400;move position converter from boundary to view
Aleksey Filippov;Mon Feb 12 11:06:55 2018 +0400;add position type converter
Aleksey Filippov;Mon Feb 12 11:06:35 2018 +0400;add position type to backing
Aleksey Filippov;Mon Feb 12 11:06:00 2018 +0400;add position type support to service
Aleksey Filippov;Mon Feb 12 11:05:44 2018 +0400;add position type to model
Romanov Anton;Mon Feb 12 07:02:32 2018 +0000;Merge branch '33-' into 'develop'
romanov73;Mon Feb 12 14:58:51 2018 +0400;refactor
romanov73;Mon Feb 12 14:58:33 2018 +0400;add human hours coefficient
romanov73;Mon Feb 12 14:56:43 2018 +0400;fix api name
romanov73;Mon Feb 12 00:58:15 2018 +0400;add balance button
romanov73;Sun Feb 11 01:36:15 2018 +0400;add tools balance prototype
romanov73;Sat Feb 10 23:09:33 2018 +0400;move enum
romanov73;Sat Feb 10 23:02:36 2018 +0400;refactor
romanov73;Sat Feb 10 22:54:28 2018 +0400;add quarter
romanov73;Sat Feb 10 22:42:14 2018 +0400;refactor
romanov73;Sat Feb 10 20:52:46 2018 +0400;Merge branch 'develop' into 33-balance-area
romanov73;Sat Feb 10 20:52:32 2018 +0400;Merge branch 'develop' into 33-balance-area
Romanov Anton;Sat Feb 10 16:14:26 2018 +0000;Merge branch '31-map-2-dto' into 'develop'
romanov73;Sat Feb 10 19:35:17 2018 +0400;fixes after Almaz consultation
romanov73;Sat Feb 10 14:25:00 2018 +0400;fix npe
romanov73;Sat Feb 10 13:50:21 2018 +0400;add filter by work type
romanov73;Sat Feb 10 13:08:56 2018 +0400;rename field
romanov73;Sat Feb 10 13:08:38 2018 +0400;filter by all children
Aleksey Filippov;Sat Feb 10 11:26:17 2018 +0400;some fixes
Aleksey Filippov;Sat Feb 10 11:26:06 2018 +0400;add dto for total balance
Aleksey Filippov;Sat Feb 10 11:11:58 2018 +0400;add dto for employee load by unit
Aleksey Filippov;Sat Feb 10 10:30:11 2018 +0400;getEmployeesByUnit method refactoring
romanov73;Sat Feb 10 00:22:37 2018 +0400;add other type of balance area
romanov73;Fri Feb 9 22:03:39 2018 +0400;add tools balance
romanov73;Fri Feb 9 19:50:21 2018 +0400;divide balance page
Aleksey Filippov;Fri Feb 9 16:37:18 2018 +0400;adapt backing and view to areas and employee experience dtos
Aleksey Filippov;Fri Feb 9 16:36:18 2018 +0400;add dto for employee experience
Aleksey Filippov;Fri Feb 9 16:35:51 2018 +0400;add dto for areas
Aleksey Filippov;Fri Feb 9 14:57:01 2018 +0400;some ui fixes
Aleksey Filippov;Fri Feb 9 14:55:36 2018 +0400;move db methods from getters to init
romanov73;Thu Feb 8 01:20:12 2018 +0400;add areas panel
romanov73;Thu Feb 8 01:19:13 2018 +0400;add areas panel
romanov73;Thu Feb 8 01:02:39 2018 +0400;add global preloader
romanov73;Thu Feb 8 00:57:46 2018 +0400;select default unit
romanov73;Thu Feb 8 00:57:23 2018 +0400;add preloader
romanov73;Wed Feb 7 22:46:44 2018 +0400;change id
Romanov Anton;Wed Feb 7 13:53:35 2018 +0000;Merge branch '23-' into 'develop'
Romanov Anton;Wed Feb 7 13:49:27 2018 +0000;Merge branch 'deploy-fixes' into 'develop'
funny73;Wed Feb 7 17:34:41 2018 +0400;UDP modify AirplaneKitCounter to double
Aleksey Filippov;Wed Feb 7 17:33:23 2018 +0400;some wildfly deploy fixes
funny73;Wed Feb 7 17:19:22 2018 +0400;Modify AirplaneKitCounter to double -> Workload.java
funny73;Wed Feb 7 17:00:10 2018 +0400;Add AirplaneKitCounter to balance view -> BalanceEmployeeService.java Modify Worckload total Value (Value * AirplaneKitCounter) -> BalanceService.java
funny73;Wed Feb 7 14:13:35 2018 +0400;Add AirplaneKitCounter to view
funny73;Wed Feb 7 14:13:15 2018 +0400;Add AirplaneKitCounter to model Workload
funny73;Wed Feb 7 14:12:15 2018 +0400;Changelog for airplainetKitCounter
Romanov Anton;Wed Feb 7 06:54:55 2018 +0000;Merge branch '22-' into 'develop'
romanov73;Wed Feb 7 14:47:34 2018 +0400;add unit types
Romanov Anton;Tue Feb 6 22:43:40 2018 +0000;Merge branch '25-' into 'develop'
romanov73;Wed Feb 7 02:41:34 2018 +0400;filter balance by unit
romanov73;Wed Feb 7 02:06:46 2018 +0400;filter balance by unit
romanov73;Wed Feb 7 02:05:10 2018 +0400;filter balance by unit
romanov73;Wed Feb 7 00:41:01 2018 +0400;add method get all unit children
romanov73;Tue Feb 6 23:26:18 2018 +0400;add filter by unit in balance results
romanov73;Tue Feb 6 21:26:45 2018 +0400;refactor work with tree of menu items
romanov73;Tue Feb 6 21:08:01 2018 +0400;refactor work with tree
romanov73;Tue Feb 6 21:07:22 2018 +0400;fix update after remove enum key
romanov73;Tue Feb 6 20:03:31 2018 +0400;rename method
Gleb;Tue Feb 6 15:07:04 2018 +0000;Merge branch '17-' into 'develop'
romanov73;Tue Feb 6 21:15:12 2018 +0400;fix inf.
funny73;Tue Feb 6 19:02:36 2018 +0400;Add changelog for units with unit_type == 'Корпус', unit_type='Цех'
funny73;Tue Feb 6 18:19:50 2018 +0400;Remove "Korpus" from "Tip podrazdeleniya"
Romanov Anton;Tue Feb 6 11:31:43 2018 +0000;Merge branch '24-' into 'develop'
romanov73;Tue Feb 6 19:01:21 2018 +0400;add user
Romanov Anton;Thu Feb 1 19:45:21 2018 +0000;Merge branch 'wildfly-deploy' into 'develop'
Aleksey Filippov;Thu Feb 1 23:24:34 2018 +0400;add wildfly-maven-plugin, remove maven-glassfish-plugin
romanov73;Thu Feb 1 19:51:24 2018 +0400;add todos
Romanov Anton;Wed Jan 31 15:03:39 2018 +0000;Merge branch 'master' into 'develop'
romanov73;Wed Jan 31 18:53:27 2018 +0400;fix round
romanov73;Wed Jan 31 18:43:33 2018 +0400;fix round
romanov73;Wed Jan 31 18:38:33 2018 +0400;add balance by employees
romanov73;Wed Jan 31 18:30:18 2018 +0400;add balance by employees
Romanov Anton;Wed Jan 31 13:02:52 2018 +0000;Merge branch 'develop' into 'master'
Romanov Anton;Wed Jan 31 12:58:00 2018 +0000;Merge branch '4-' into 'develop'
romanov73;Wed Jan 31 16:47:51 2018 +0400;add balance by employees
romanov73;Wed Jan 31 00:47:39 2018 +0400;add calculation employee loads
romanov73;Wed Jan 31 00:47:25 2018 +0400;add calculation employee loads
romanov73;Wed Jan 31 00:47:08 2018 +0400;add calculation employee loads
romanov73;Wed Jan 31 00:46:53 2018 +0400;add calculation employee loads
romanov73;Wed Jan 31 00:45:59 2018 +0400;add interface for edit additional fields
romanov73;Wed Jan 31 00:45:04 2018 +0400;add comparable for using in tree map
romanov73;Wed Jan 31 00:44:33 2018 +0400;add fields for production program
romanov73;Wed Jan 31 00:43:56 2018 +0400;move interface to base entity
romanov73;Wed Jan 31 00:43:21 2018 +0400;add database fields for production program
romanov73;Wed Jan 31 00:42:55 2018 +0400;add dynamic columns
romanov73;Tue Jan 30 15:11:12 2018 +0400;add work type for workload
romanov73;Tue Jan 30 14:55:56 2018 +0400;add comments
romanov73;Tue Jan 30 03:00:28 2018 +0400;show by production program
romanov73;Tue Jan 30 00:07:31 2018 +0400;add employee available capacity
romanov73;Mon Jan 29 23:42:06 2018 +0400;fix units hierarchy bypass
romanov73;Mon Jan 29 23:28:28 2018 +0400;divide logic
romanov73;Mon Jan 29 22:59:45 2018 +0400;add employee experience table
romanov73;Mon Jan 29 22:15:29 2018 +0400;fix calc areas
romanov73;Mon Jan 29 21:57:23 2018 +0400;fix calc employee experience
romanov73;Mon Jan 29 21:12:52 2018 +0400;calc employee experience by units
romanov73;Mon Jan 29 14:01:36 2018 +0400;add employee experience
Romanov Anton;Mon Jan 29 06:04:01 2018 +0000;Update README.md
Romanov Anton;Sun Jan 28 16:16:56 2018 +0000;Merge branch 'develop' into 'master'
Romanov Anton;Sun Jan 28 16:06:14 2018 +0000;Merge branch '3-' into 'develop'
romanov73;Sun Jan 28 19:53:21 2018 +0400;remove product work types edit
romanov73;Sun Jan 28 19:41:31 2018 +0400;fix months select
romanov73;Sun Jan 28 19:06:10 2018 +0400;fix year select
romanov73;Sun Jan 28 04:28:21 2018 +0400;fix program edit
romanov73;Sun Jan 28 04:27:55 2018 +0400;add product backend
romanov73;Sun Jan 28 04:26:53 2018 +0400;add table and fields
Romanov Anton;Sat Jan 27 08:11:15 2018 +0000;Merge branch '9-' into 'develop'
romanov73;Sat Jan 27 15:28:22 2018 +0400;sort menu items, change logo
Romanov Anton;Sat Jan 27 05:55:52 2018 +0000;Update README.md
romanov73;Sat Jan 20 00:12:44 2018 +0400;fix versions select
Romanov Anton;Fri Jan 19 04:27:48 2018 +0000;Merge branch 'tool-square-catalog' into 'master'
Aleksey Filippov;Fri Jan 19 01:11:50 2018 +0400;add tool square catalog migration
Aleksey Filippov;Thu Jan 18 02:20:48 2018 +0400;add tool square catalog
romanov73;Thu Jan 11 21:22:14 2018 +0400;fix rest path
romanov73;Tue Jan 9 03:44:10 2018 +0400;fixes
romanov73;Tue Jan 9 00:09:27 2018 +0400;fix unit name
romanov73;Tue Jan 9 00:07:47 2018 +0400;fix year
romanov73;Mon Jan 8 19:16:28 2018 +0400;add short view
romanov73;Mon Jan 8 11:55:30 2018 +0400;fix
romanov73;Mon Jan 8 01:24:37 2018 +0400;fill work type by tool name
romanov73;Mon Jan 8 00:23:00 2018 +0400;ui fixes
romanov73;Sun Jan 7 23:54:40 2018 +0400;fix units hierarchy, add unit type, calc areas balance
romanov73;Sat Jan 6 22:51:11 2018 +0400;remove versions
romanov73;Sat Jan 6 22:06:03 2018 +0400;fix edit program
romanov73;Sat Jan 6 21:40:11 2018 +0400;add title image
romanov73;Sat Jan 6 18:04:27 2018 +0400;add production program input
romanov73;Wed Jan 3 21:05:48 2018 +0400;change wizard to tabs
romanov73;Wed Jan 3 01:03:05 2018 +0400;add wizard
romanov73;Sat Dec 30 02:02:42 2017 +0400;fix tools loading
romanov73;Sat Dec 30 01:46:01 2017 +0400;fix tools loading
romanov73;Sat Dec 30 01:32:33 2017 +0400;fix tools loading
romanov73;Sat Dec 30 01:28:24 2017 +0400;fix tools loading
romanov73;Sat Dec 30 00:54:26 2017 +0400;fix employee loading
romanov73;Fri Dec 29 19:04:14 2017 +0400;fix unit select
romanov73;Fri Dec 29 17:19:10 2017 +0400;fix unit select
romanov73;Fri Dec 29 01:40:38 2017 +0400;add cache
romanov73;Fri Dec 29 01:27:18 2017 +0400;add cache
romanov73;Fri Dec 29 01:14:09 2017 +0400;add cache
romanov73;Fri Dec 29 01:12:17 2017 +0400;change color
romanov73;Fri Dec 29 00:50:57 2017 +0400;add ci
romanov73;Fri Dec 29 00:48:10 2017 +0400;add ci
romanov73;Fri Dec 29 00:34:36 2017 +0400;add ci
romanov73;Fri Dec 29 00:31:22 2017 +0400;add ci
romanov73;Fri Dec 29 00:18:51 2017 +0400;add ci
romanov73;Fri Dec 29 00:16:44 2017 +0400;add ci
romanov73;Fri Dec 29 00:13:33 2017 +0400;add ci
romanov73;Fri Dec 29 00:09:51 2017 +0400;fix menus
Romanov Anton;Thu Dec 28 19:47:02 2017 +0000;Merge branch 'balance-example' into 'master'
romanov73;Thu Dec 28 23:44:52 2017 +0400;add other dictionaries
romanov73;Sat Dec 23 10:40:41 2017 +0400;add tool and work types
romanov73;Sat Dec 23 09:12:38 2017 +0400;fix menu item
romanov73;Sat Dec 23 09:12:23 2017 +0400;fix employee load
romanov73;Sat Dec 23 08:51:18 2017 +0400;add employee category
romanov73;Sat Dec 23 08:22:10 2017 +0400;add categories dictionary
romanov73;Fri Dec 22 12:38:08 2017 +0400;add menu item
romanov73;Fri Dec 22 12:31:26 2017 +0400;add employee category
romanov73;Fri Dec 22 09:55:31 2017 +0400;fix calendar
romanov73;Fri Dec 22 09:33:56 2017 +0400;fix date
romanov73;Thu Dec 21 16:38:20 2017 +0400;fix for context path change
romanov73;Thu Dec 21 13:58:02 2017 +0400;fluid panel
romanov73;Wed Dec 20 20:50:17 2017 +0400;fix context path
romanov73;Wed Dec 20 17:12:19 2017 +0400;fix displaying position
romanov73;Wed Dec 20 17:10:14 2017 +0400;load employees from file
romanov73;Wed Dec 20 15:09:54 2017 +0400;fix tool loading
romanov73;Mon Dec 18 18:18:04 2017 +0400;add resource versions
romanov73;Mon Dec 18 17:36:50 2017 +0400;add resource
romanov73;Mon Dec 18 17:07:47 2017 +0400;add swagger
romanov73;Sat Dec 16 09:42:46 2017 +0400;add new version
romanov73;Fri Dec 15 19:50:46 2017 +0400;fix title
romanov73;Fri Dec 15 19:24:13 2017 +0400;fix title
romanov73;Fri Dec 15 11:57:18 2017 +0400;add menu items
romanov73;Fri Dec 15 11:52:01 2017 +0400;add positions dictionary
romanov73;Fri Dec 15 11:29:02 2017 +0400;fix select for employee
romanov73;Fri Dec 15 10:35:12 2017 +0400;add employee backing
romanov73;Fri Dec 15 09:36:33 2017 +0400;fix 500 error page
romanov73;Thu Dec 14 22:26:45 2017 +0400;fix mapping
romanov73;Thu Dec 14 22:49:44 2017 +0400;add employee
romanov73;Thu Dec 14 22:37:30 2017 +0400;add employee
romanov73;Thu Dec 14 14:12:03 2017 +0400;fix crud service
romanov73;Thu Dec 14 12:51:59 2017 +0400;fix table style
romanov73;Thu Dec 14 12:22:48 2017 +0400;remove border for grid
romanov73;Thu Dec 14 12:20:14 2017 +0400;add version_id for units
romanov73;Thu Dec 14 11:49:53 2017 +0400;fix font size
romanov73;Thu Dec 14 11:08:46 2017 +0400;add unit fields
romanov73;Thu Dec 14 10:23:01 2017 +0400;KISS units hierarchy
romanov73;Wed Dec 13 19:04:05 2017 +0400;refresh page
romanov73;Wed Dec 13 17:43:54 2017 +0400;add version
romanov73;Wed Dec 13 01:46:05 2017 +0400;body width
romanov73;Wed Dec 13 01:45:17 2017 +0400;add menu item
romanov73;Tue Dec 12 22:20:07 2017 +0400;fix tree
romanov73;Tue Dec 12 20:02:20 2017 +0400;fix login
romanov73;Tue Dec 12 19:29:03 2017 +0400;add unit tree
romanov73;Tue Dec 12 18:23:38 2017 +0400;add unit dictionary
romanov73;Tue Dec 12 16:18:03 2017 +0400;add filter
romanov73;Tue Dec 12 14:13:31 2017 +0400;fix menu session
romanov73;Tue Dec 12 00:10:47 2017 +0400;remove bootstrap
romanov73;Mon Dec 11 21:53:18 2017 +0400;add unit select
romanov73;Mon Dec 11 19:49:15 2017 +0400;add menu item and role
romanov73;Mon Dec 11 19:37:38 2017 +0400;fix permissions
romanov73;Mon Dec 11 17:08:39 2017 +0400;refactor and add tools dictionary backing
romanov73;Mon Dec 11 17:08:04 2017 +0400;refactor and add tools dictionary backing
romanov73;Mon Dec 11 17:07:27 2017 +0400;refactor and add tools dictionary backing
romanov73;Mon Dec 11 14:12:24 2017 +0400;add tools dictionary page
romanov73;Sat Dec 9 09:54:45 2017 +0400;add global exception hadler
romanov73;Sat Nov 25 13:52:33 2017 +0400;add monitoring
romanov73;Sat Nov 25 13:21:18 2017 +0400;fix xls and xlsx
romanov73;Sat Nov 25 12:39:45 2017 +0400;upload tools
romanov73;Fri Nov 24 22:16:27 2017 +0400;save tools
romanov73;Fri Nov 24 13:06:21 2017 +0400;fix message
romanov73;Fri Nov 24 12:11:43 2017 +0400;add loading from xlsx
romanov73;Fri Nov 17 19:43:35 2017 +0400;add message
romanov73;Fri Nov 17 15:11:22 2017 +0400;fix button
romanov73;Fri Nov 17 10:15:42 2017 +0400;add registration service
romanov73;Thu Nov 16 21:35:04 2017 +0400;add push script
romanov73;Thu Nov 16 20:54:49 2017 +0400;fix named query execution
romanov73;Sun Nov 12 22:19:03 2017 +0400;sort menu items
romanov73;Sat Nov 11 15:09:35 2017 +0400;fix title
romanov73;Sat Nov 11 14:54:25 2017 +0400;fix table
romanov73;Sat Nov 11 14:35:38 2017 +0400;fix style attribute
romanov73;Sat Nov 11 14:08:56 2017 +0400;show user sessions
romanov73;Sat Nov 11 13:51:34 2017 +0400;rename service
romanov73;Fri Nov 10 22:03:25 2017 +0400;fix update tree
romanov73;Fri Nov 10 14:29:25 2017 +0400;edit menu items
romanov73;Fri Nov 10 12:17:24 2017 +0400;set bootstrap theme for primefaces
romanov73;Thu Nov 9 23:40:40 2017 +0400;fix saving entitites
romanov73;Thu Nov 9 23:27:42 2017 +0400;fix saving entitites
romanov73;Thu Nov 9 20:51:19 2017 +0400;fix titles
romanov73;Thu Nov 9 18:00:45 2017 +0400;fix login page title
romanov73;Thu Nov 9 13:36:21 2017 +0400;commit log
romanov73;Thu Nov 9 07:31:37 2017 +0400;reverse sort commits
romanov73;Thu Nov 9 00:27:48 2017 +0400;sort commits
romanov73;Wed Nov 8 23:16:07 2017 +0400;extend commits log
romanov73;Wed Nov 8 21:42:16 2017 +0400;fix styles
romanov73;Wed Nov 8 19:17:08 2017 +0400;add logout
romanov73;Wed Nov 8 19:13:17 2017 +0400;add logout
romanov73;Wed Nov 8 20:18:35 2017 +0400;Merge branch 'master' of gitlab.com:romanov73/balance
romanov73;Wed Nov 8 20:17:55 2017 +0400;add database diagramm
Romanov Anton;Wed Nov 8 04:13:39 2017 +0000;Update README.md
Romanov Anton;Wed Nov 8 04:11:33 2017 +0000;Update README.md
romanov73;Wed Nov 8 07:48:13 2017 +0400;Merge remote-tracking branch 'origin/master'
Romanov Anton;Tue Nov 7 18:05:04 2017 +0000;Update README.md
romanov73;Tue Nov 7 22:01:50 2017 +0400;add example of permissions validation
romanov73;Tue Nov 7 20:56:31 2017 +0400;rename project
romanov73;Wed Oct 11 21:37:49 2017 +0400;reverse sort commits
romanov73;Wed Oct 11 21:32:19 2017 +0400;fix read resource as file
romanov73;Wed Oct 11 20:23:10 2017 +0400;Merge remote-tracking branch 'origin/master'
romanov73;Wed Oct 11 20:22:52 2017 +0400;add commits log
Romanov Anton;Tue Oct 10 20:47:29 2017 +0000;Update README.md
romanov73;Fri Oct 6 01:55:57 2017 +0400;add menu to platform
Anton Romanov;Thu Mar 28 14:59:35 2019 +0400;partially restored commits page
Anton Romanov;Wed Mar 27 13:27:49 2019 +0400;#33 small external link
Anton Romanov;Wed Mar 27 09:07:02 2019 +0000;Update README.md
Anton Romanov;Wed Mar 27 07:58:58 2019 +0000;Merge branch '33-paper-url' into 'dev'
Семенова Мария;Sat Mar 23 12:23:30 2019 +0400;#33 link in new tab
Семенова Мария;Sat Mar 23 12:04:51 2019 +0400;Merge branch 'dev' into 33-paper-url
Anton Romanov;Fri Mar 22 10:36:09 2019 +0000;Merge branch '13-paper-files' into 'dev'
Anton Romanov;Fri Mar 22 13:58:03 2019 +0400;#13 reduce of code
Anton Romanov;Fri Mar 22 13:52:06 2019 +0400;#13 fix condition
Семенова Мария;Fri Mar 22 13:21:32 2019 +0400;#13 streams refactoring
Семенова Мария;Fri Mar 22 09:32:21 2019 +0400;#13 rename 'deleted', move creating fileDto to service
Семенова Мария;Thu Mar 21 18:26:28 2019 +0400;#13 fileDataDto instead of Object[]
Семенова Мария;Tue Mar 19 17:59:19 2019 +0400;#13 some refactoring
Семенова Мария;Tue Mar 19 17:41:02 2019 +0400;Merge branch 'dev' into 13-paper-files
Семенова Мария;Mon Mar 18 23:31:33 2019 +0400;#33 url in paper
Anton Romanov;Mon Mar 18 22:35:01 2019 +0400;merge deploy environments
Anton Romanov;Mon Mar 18 22:25:28 2019 +0400;add environment
Семенова Мария;Mon Mar 18 21:02:26 2019 +0400;#13 download files
Семенова Мария;Mon Mar 18 19:17:28 2019 +0400;#13 add files to db
Семенова Мария;Mon Mar 18 18:39:15 2019 +0400;#13 addNewFile js function
Семенова Мария;Mon Mar 18 16:13:22 2019 +0400;Merge branch 'dev' into 13-paper-files
Семенова Мария;Mon Mar 18 16:02:55 2019 +0400;#13 file list on paper page
Anton Romanov;Mon Mar 18 11:08:15 2019 +0000;Merge branch '50-refactorForGrants' into 'dev'
T-Midnight;Mon Mar 18 14:27:54 2019 +0400;Delete DeadlineDTO and update usages
Семенова Мария;Mon Mar 18 13:00:34 2019 +0400;#13 add fileDataDto
Семенова Мария;Mon Mar 18 11:07:30 2019 +0400;#13 change model, schema
T-Midnight;Fri Mar 15 12:24:02 2019 +0400;Add new status for grant
T-Midnight;Fri Mar 15 12:19:25 2019 +0400;Rename title
T-Midnight;Fri Mar 15 12:19:01 2019 +0400;Create Navigation class to avoid "magic strings" and code duplication
Anton Romanov;Wed Mar 13 07:16:32 2019 +0000;Merge branch '72-link-to-timetable' into 'dev'
Anton Romanov;Tue Mar 12 14:44:11 2019 +0400;add patronymic
Anton Romanov;Tue Mar 12 13:40:48 2019 +0400;display user in filter
Anton Romanov;Tue Mar 12 12:51:59 2019 +0300;add service methods
Anton Romanov;Tue Mar 12 12:35:09 2019 +0300;add timetable link
Anton Romanov;Mon Mar 11 10:49:07 2019 +0000;Merge branch '54-view-conference' into 'dev'
Nightblade73;Mon Mar 11 14:43:32 2019 +0400;#54 deleted edit btn
Nightblade73;Mon Mar 11 12:58:40 2019 +0400;#54 add back link, css fixes
Nightblade73;Mon Mar 11 11:36:00 2019 +0400;#54 add custom paper-list
Nightblade73;Sun Mar 10 22:15:09 2019 +0400;#54 add custom deadline-list, add edit-button, add edit and delete icons
Nightblade73;Thu Mar 7 22:50:37 2019 +0400;#54 add member list
Nightblade73;Wed Mar 6 20:51:46 2019 +0400;#54 part of make-up
Nightblade73;Wed Mar 6 16:48:51 2019 +0400;#54 add transitions
Anton Romanov;Wed Mar 6 16:40:33 2019 +0400;fix login
Nightblade73;Wed Mar 6 16:27:25 2019 +0400;#50 creating html page, changing href
Anton Romanov;Wed Mar 6 12:25:34 2019 +0000;Merge branch '29-page-header' into 'dev'
Anton Romanov;Wed Mar 6 16:19:43 2019 +0400;fix css
Anton Romanov;Wed Mar 6 14:36:46 2019 +0300;fix props
Anton Romanov;Wed Mar 6 14:35:09 2019 +0300;fix props
user;Wed Mar 6 14:25:02 2019 +0300;header fix
Anton Romanov;Mon Mar 4 10:28:46 2019 +0400;fix code
Anton Romanov;Mon Mar 4 10:24:30 2019 +0400;fix code
Anton Romanov;Fri Mar 1 11:27:57 2019 +0400;fix branch
Anton Romanov;Fri Mar 1 11:22:25 2019 +0400;add links to papers
Anton Romanov;Fri Mar 1 11:21:25 2019 +0400;add links to papers
Anton Romanov;Sun Feb 3 14:54:02 2019 +0000;Update README.md
Anton Romanov;Thu Jan 17 01:01:26 2019 +0400;filter dashboard papers
Anton Romanov;Thu Jan 17 00:57:34 2019 +0400;fix failed conditions
Anton Romanov;Tue Jan 8 19:55:27 2019 +0000;Update README.md
Anton Romanov;Tue Jan 8 19:36:36 2019 +0000;Update README.md
Anton Romanov;Sat Jan 5 08:01:07 2019 +0400;fix notifications
Anton Romanov;Fri Jan 4 17:41:48 2019 +0400;fix notifications
Anton Romanov;Sun Dec 30 19:23:11 2018 +0400;some layout fix
Anton Romanov;Sun Dec 30 19:22:51 2018 +0400;sort deadlines
Anton Romanov;Sat Dec 29 09:58:37 2018 +0400;fix enum field name
Anton Romanov;Fri Dec 28 10:04:42 2018 +0000;Merge branch '35-' into 'master'
Anton Romanov;Fri Dec 28 14:00:09 2018 +0400;some refactor
Anton Romanov;Fri Dec 28 13:57:20 2018 +0400;some refactor
T-Midnight;Tue Dec 25 12:50:14 2018 +0400;Create model folder for grant
T-Midnight;Tue Dec 25 02:44:50 2018 +0400;Hide button "Add Project" when project already exists (not perfect)
T-Midnight;Tue Dec 25 00:14:38 2018 +0400;Made button "delete grant" visible
T-Midnight;Mon Dec 24 23:39:19 2018 +0400;Rename table grant to grants
T-Midnight;Mon Dec 24 15:20:57 2018 +0400;Update classes
T-Midnight;Mon Dec 24 15:18:52 2018 +0400;Add thymeleaf template
T-Midnight;Mon Dec 24 13:05:37 2018 +0400;Create service&repository for Project
T-Midnight;Mon Dec 24 11:07:02 2018 +0400;Create js for grants
T-Midnight;Mon Dec 24 11:03:03 2018 +0400;Create html fragments
T-Midnight;Sun Dec 23 02:22:41 2018 +0400;Create Controller&Service
T-Midnight;Sun Dec 23 02:22:31 2018 +0400;Update ProjectDto
T-Midnight;Sun Dec 23 02:22:24 2018 +0400;Add constructor
T-Midnight;Sun Dec 23 02:22:06 2018 +0400;Add function getNextDeadline()
T-Midnight;Sat Dec 22 18:03:18 2018 +0400;Create GrantRepository
T-Midnight;Sat Dec 22 03:31:43 2018 +0400;Create setters for GrantDto
Anton Romanov;Fri Dec 21 00:07:26 2018 +0400;fix display paper title
Anton Romanov;Thu Dec 20 23:30:25 2018 +0400;fix paper status template
Anton Romanov;Wed Dec 19 01:29:54 2018 +0400;try to fix template resolvers, step 4
Anton Romanov;Wed Dec 19 01:00:08 2018 +0400;try to fix template resolvers, step 3
Anton Romanov;Wed Dec 19 00:44:12 2018 +0400;try to fix template resolvers, step 2
Anton Romanov;Wed Dec 19 00:22:36 2018 +0400;try to fix template resolvers
Anton Romanov;Wed Dec 19 00:11:39 2018 +0400;Merge remote-tracking branch 'origin/master'
Anton Romanov;Wed Dec 19 00:09:07 2018 +0400;try to fix gradlew
Anton Romanov;Tue Dec 18 23:02:48 2018 +0400;sort filtered papers
Anton Romanov;Tue Dec 18 18:45:43 2018 +0000;Merge branch '47-statuses' into 'master'
Anton Romanov;Tue Dec 18 22:42:34 2018 +0400;add statuses
Anton Romanov;Tue Dec 18 18:18:25 2018 +0000;Merge branch '46-mvc' into 'master'
Anton Romanov;Tue Dec 18 22:15:21 2018 +0400;fix filer
Anton Romanov;Tue Dec 18 19:40:23 2018 +0400;fix scripts
Anton Romanov;Tue Dec 18 19:23:15 2018 +0400;show authors
Anton Romanov;Tue Dec 18 18:47:15 2018 +0400;confirm delete paper
Anton Romanov;Tue Dec 18 18:05:30 2018 +0400;add papers navigation
Anton Romanov;Mon Dec 17 17:56:48 2018 +0400;fix submit form
Anton Romanov;Mon Dec 17 17:29:06 2018 +0400;fix email notification
Anton Romanov;Mon Dec 17 17:28:52 2018 +0400;fix route
Anton Romanov;Mon Dec 17 13:46:08 2018 +0400;edit deadlines
Anton Romanov;Fri Dec 14 16:00:46 2018 +0400;Merge branch 'master' into 46-mvc
Anton Romanov;Fri Dec 14 16:00:33 2018 +0400;Merge branch 'master' into 46-mvc
Anton Romanov;Tue Dec 11 11:14:21 2018 +0000;Merge branch '36-' into 'master'
Anton Romanov;Tue Dec 11 15:08:35 2018 +0400;move classes, add deadline to entities, fix db changelogs
T-Midnight;Sat Dec 8 23:53:38 2018 +0400;Create model for grant, deadline and project
Anton Romanov;Wed Dec 5 18:08:47 2018 +0400;save authors
Anton Romanov;Wed Dec 5 17:36:53 2018 +0400;fix npe
Anton Romanov;Wed Dec 5 17:06:56 2018 +0400;format dates
Anton Romanov;Wed Dec 5 16:51:26 2018 +0400;fix create paper
Anton Romanov;Wed Dec 5 06:00:33 2018 +0000;add rest controller
Anton Romanov;Tue Dec 4 14:49:23 2018 +0400;fix js
Anton Romanov;Tue Dec 4 14:48:39 2018 +0400;show status
Anton Romanov;Tue Dec 4 14:13:01 2018 +0400;add validation
Anton Romanov;Tue Dec 4 11:35:51 2018 +0400;pass values for paper
Anton Romanov;Mon Nov 26 23:07:14 2018 +0400;load paper
Anton Romanov;Fri Nov 23 16:40:15 2018 +0000;Merge branch '14-filter-frontend' into 'master'
Anton Romanov;Fri Nov 23 20:37:24 2018 +0400;fix failed commit
Anton Romanov;Fri Nov 23 16:24:26 2018 +0000;Merge branch '10-savePaper' into 'master'
Anton Romanov;Fri Nov 23 16:45:40 2018 +0400;show paper list in mvc
Alyona;Fri Nov 23 14:17:16 2018 +0400;filter
Alyona;Fri Nov 23 14:12:37 2018 +0400;Merge branch 'master' into 14-filter-frontend
Alyona;Fri Nov 23 14:10:49 2018 +0400;Merge remote-tracking branch 'origin/master'
Alyona;Fri Nov 23 14:10:36 2018 +0400;Merge branch 'master' of C:\Users\катя\IdeaProjects\ng-tracker with conflicts.
Elena;Fri Nov 23 14:05:23 2018 +0400;задача 10(new)
Elena;Fri Nov 23 13:53:20 2018 +0400;задача 10
Elena;Fri Nov 23 12:39:36 2018 +0400;Merge branch 'master' into 10-savePaper
Anton Romanov;Thu Nov 22 21:48:36 2018 +0400;fix colors
Anton Romanov;Thu Nov 22 21:31:41 2018 +0400;fix colors
Anton Romanov;Thu Nov 22 21:06:58 2018 +0400;add paper status
Anton Romanov;Thu Nov 22 11:20:08 2018 +0400;Merge remote-tracking branch 'origin/master'
Anton Romanov;Thu Nov 22 11:19:50 2018 +0400;add mertica
Anton Romanov;Wed Nov 21 15:47:26 2018 +0400;remove empty page
Anton Romanov;Wed Nov 21 15:47:14 2018 +0400;add toolbar
Anton Romanov;Wed Nov 21 15:42:20 2018 +0400;Merge remote-tracking branch 'origin/master'
Anton Romanov;Wed Nov 21 11:42:47 2018 +0000;Merge branch '31-' into 'master'
Anton Romanov;Wed Nov 21 15:40:20 2018 +0400;close failed papers
T-Midnight;Wed Nov 21 15:28:41 2018 +0400;Create grant page
Anton Romanov;Wed Nov 21 08:51:11 2018 +0000;Merge branch '30-main-grants-page' into 'master'
Anton Romanov;Wed Nov 21 12:46:42 2018 +0400;Merge remote-tracking branch 'origin/master'
Anton Romanov;Wed Nov 21 12:46:27 2018 +0400;notify if paper deadline in future
T-Midnight;Mon Nov 19 12:16:39 2018 +0400;Update dashboard for grants
Anton Romanov;Mon Nov 19 08:21:22 2018 +0400;fix for remove event
Anton Romanov;Mon Nov 19 07:46:02 2018 +0400;fix event create conditions
Anton Romanov;Sun Nov 18 14:29:41 2018 +0400;fix delete button
Anton Romanov;Sat Nov 17 12:31:22 2018 +0400;fix delete button
Anton Romanov;Sat Nov 17 11:56:52 2018 +0400;show events
Anton Romanov;Wed Nov 14 17:14:56 2018 +0400;fix build script for netbeans
Anton Romanov;Wed Nov 14 17:04:40 2018 +0400;show toolbar buttons
Anton Romanov;Wed Nov 14 17:04:29 2018 +0400;show toolbar buttons
Anton Romanov;Wed Nov 14 17:04:13 2018 +0400;show paper status
Anton Romanov;Wed Nov 14 17:03:22 2018 +0400;fix code
Anton Romanov;Wed Nov 14 15:18:22 2018 +0400;fix code
Anton Romanov;Wed Nov 14 15:15:23 2018 +0400;read dashboard
Alyona;Wed Nov 14 08:55:46 2018 +0400;filter
Anton Romanov;Tue Nov 13 11:46:25 2018 +0000;Merge branch '14-DB-filter' into 'master'
Anton Romanov;Tue Nov 13 15:41:18 2018 +0400;filter papers
Anton Romanov;Sun Nov 11 14:28:51 2018 +0400;Merge remote-tracking branch 'origin/master'
Anton Romanov;Sun Nov 11 12:43:27 2018 +0400;move class
Anton Romanov;Sat Nov 10 21:44:36 2018 +0000;Merge branch '20-' into 'master'
Anton Romanov;Sun Nov 11 01:31:27 2018 +0400;fix scheduler
Anton Romanov;Sun Nov 11 01:29:06 2018 +0400;refactor and db changes
Anton Romanov;Sat Nov 10 23:15:35 2018 +0400;delete paper
T-Midnight;Sat Nov 10 21:55:09 2018 +0400;Create dashboard for grants
Anton Romanov;Sat Nov 10 21:43:52 2018 +0400;add route
Alyona;Sat Nov 10 20:28:17 2018 +0400;fix
Alyona;Fri Nov 9 15:43:42 2018 +0400;fix
Elena;Fri Nov 9 15:43:25 2018 +0400;Задача №10
Anton Romanov;Fri Nov 9 15:37:58 2018 +0400;remove styles from email template
Alyona;Fri Nov 9 15:29:48 2018 +0400;Merge remote-tracking branch 'origin/master'
Anton Romanov;Fri Nov 9 15:21:03 2018 +0400;move styles to body
Anton Romanov;Fri Nov 9 11:15:00 2018 +0000;Merge branch '21-Event-status' into 'master'
Anton Romanov;Fri Nov 9 15:08:10 2018 +0400;Merge branch 'master' into 21-Event-status
Anton Romanov;Fri Nov 9 15:05:39 2018 +0400;fix styles
Anton Romanov;Fri Nov 9 14:53:24 2018 +0400;add styles in email templates
Alyona;Fri Nov 9 14:51:19 2018 +0400;added period event
Alyona;Fri Nov 9 14:48:21 2018 +0400;added period event
Elena;Fri Nov 9 13:43:08 2018 +0400;Merge branch 'master' into 10-savePaper
Elena;Fri Nov 9 13:42:28 2018 +0400;Задача №10
Alyona;Fri Nov 9 13:30:31 2018 +0400;Merge remote-tracking branch 'origin/master'
Anton Romanov;Fri Nov 9 10:04:50 2018 +0400;add notification templates
Anton Romanov;Fri Nov 9 09:16:24 2018 +0400;move to notification service
Anton Romanov;Fri Nov 9 08:39:00 2018 +0400;fix scheduler code to use service
Anton Romanov;Thu Nov 8 21:58:10 2018 +0400;add toolbar
Anton Romanov;Thu Nov 8 20:34:09 2018 +0400;fix paths
Anton Romanov;Thu Nov 8 20:08:26 2018 +0400;add config parameter
Anton Romanov;Thu Nov 8 19:39:22 2018 +0400;Merge remote-tracking branch 'origin/master'
Anton Romanov;Thu Nov 8 19:36:50 2018 +0400;add paper create strategy
Anton Romanov;Tue Nov 6 10:39:25 2018 +0000;Update README.md
Anton Romanov;Tue Nov 6 14:10:00 2018 +0400;fix ci
Anton Romanov;Thu Nov 1 12:53:19 2018 +0400;fix imports
Alyona;Wed Oct 31 20:06:27 2018 +0400;changelog
Alyona;Wed Oct 31 19:35:23 2018 +0400;Merge branch 'master' into 21-Event-status
Alyona;Wed Oct 31 19:33:21 2018 +0400;Merge branch 'master' of C:\Users\катя\IdeaProjects\ng-tracker with conflicts.
Alyona;Tue Oct 30 23:59:42 2018 +0400;added event status
Anton Romanov;Tue Oct 30 19:32:00 2018 +0000;Merge branch '4-show-time-line' into 'master'
Anton Romanov;Tue Oct 30 23:29:18 2018 +0400;Merge branch 'master' into 4-show-time-line
Anton Romanov;Tue Oct 30 23:26:55 2018 +0400;fix db
Anton Romanov;Tue Oct 30 23:07:01 2018 +0400;Revert "remove liquibase"
Anton Romanov;Tue Oct 30 23:04:49 2018 +0400;Merge remote-tracking branch 'origin/4-show-time-line' into 4-show-time-line
Anton Romanov;Tue Oct 30 23:04:21 2018 +0400;Revert "remove liquibase"
Anton Romanov;Sat Oct 27 21:00:43 2018 +0000;Merge branch '11-Message-about-deadlines' into 'master'
Anton Romanov;Sat Oct 27 21:00:01 2018 +0000;Merge branch '12-' into 'master'
Alyona;Sun Oct 28 00:33:00 2018 +0400;fix
Alyona;Sun Oct 28 00:26:09 2018 +0400;fix
Alyona;Sun Oct 28 00:17:16 2018 +0400;fix
Alyona;Sun Oct 28 00:15:42 2018 +0400;fix
Alyona;Sat Oct 27 23:50:12 2018 +0400;fix
Alyona;Sat Oct 27 23:46:49 2018 +0400;fix
Anton Romanov;Sat Oct 27 23:25:27 2018 +0400;- make scheduler as a service - reformat code - fix cyrillic letter
Anton Romanov;Sat Oct 27 23:16:14 2018 +0400;add database column
Alyona;Sat Oct 27 23:11:07 2018 +0400;class for send messages about update paper
Alyona;Sat Oct 27 22:32:51 2018 +0400;add deadlineSсheduler
Alyona;Sat Oct 27 22:24:10 2018 +0400;add deadlineDate to models
Anton Romanov;Thu Oct 25 10:27:57 2018 +0400;some fix
Anton Romanov;Thu Oct 25 04:59:51 2018 +0000;Merge branch '8-' into 'master'
Alyona;Thu Oct 25 08:53:48 2018 +0400;finish deadline
Alyona;Thu Oct 25 08:53:29 2018 +0400;finish deadline
Alyona;Thu Oct 25 08:44:25 2018 +0400;Merge branch 'master' into 8-Deadline
Alyona;Thu Oct 25 08:41:37 2018 +0400;partially add deadline
Anton Romanov;Thu Oct 18 07:25:58 2018 +0000;Merge branch '7-dates-Matveeva' into 'master'
Anton Romanov;Thu Oct 18 11:21:26 2018 +0400;use html5 datetime pickers
Elena;Thu Oct 18 10:38:04 2018 +0400;Задача №7
Anton Romanov;Thu Oct 18 04:49:10 2018 +0000;Merge branch '6-authors-list-Matveeva' into 'master'
Anton Romanov;Thu Oct 11 19:49:16 2018 +0400;fix buttons size
Anton Romanov;Thu Oct 11 15:39:57 2018 +0400;fix styles
Anton Romanov;Thu Oct 11 10:03:44 2018 +0400;load paper statuses
Anton Romanov;Thu Oct 11 09:05:41 2018 +0400;fix progress background
Elena;Wed Oct 10 23:09:45 2018 +0400;Задача №6
Anton Romanov;Wed Oct 10 13:18:24 2018 +0000;Merge branch '5-' into 'master'
Anton Romanov;Wed Oct 10 17:05:54 2018 +0400;fix paper view
Elena;Wed Oct 10 15:30:47 2018 +0400;Задача №5 new
Elena;Wed Oct 10 10:09:07 2018 +0400;Merge branch 'master' into 5-Matveeva-Page
Elena;Thu Oct 4 10:39:27 2018 +0400;Задача №5
Anton Romanov;Tue Oct 2 07:46:40 2018 +0000;Merge branch '27-file-upload' into 'master'
Anton Romanov;Tue Oct 2 11:11:13 2018 +0400;Merge branch 'master' into 27-file-upload
Anton Romanov;Tue Oct 2 10:58:41 2018 +0400;add messages
Anton Romanov;Mon Oct 1 13:54:11 2018 +0400;add example for file uploading
Anton Romanov;Sat Sep 29 09:22:48 2018 +0400;minimize scripts
Anton Romanov;Thu Sep 27 21:32:16 2018 +0400;fix error pages
Anton Romanov;Thu Sep 27 16:01:02 2018 +0000;Merge branch 'refactor-ui' into 'master'
Anton Romanov;Thu Sep 27 12:11:25 2018 +0400;move pages
Anton Romanov;Thu Sep 27 10:35:22 2018 +0400;some refactor
Anton Romanov;Thu Sep 27 06:08:53 2018 +0000;Merge branch '3-ui' into 'master'
Anton Romanov;Thu Sep 27 10:03:00 2018 +0400;Merge branch 'master' into 3-ui
Anton Romanov;Thu Sep 27 10:02:49 2018 +0400;Merge branch 'master' into 3-ui
Alyona;Wed Sep 26 16:44:36 2018 +0400;Merge branch 'master' into 5-Page-of-paper
Alyona;Wed Sep 26 16:41:33 2018 +0400;Merge branch 'master' into 23-dashboard
Anton Romanov;Wed Sep 26 12:22:38 2018 +0000;Merge branch '23-dashboard' into 'master'
Alyona;Wed Sep 26 16:11:43 2018 +0400;Merge branch 'master' into 23-dashboard
Alyona;Wed Sep 26 16:11:19 2018 +0400;Merge branch 'master' into 23-dashboard
Alyona;Wed Sep 26 16:04:31 2018 +0400;add paper page
Anton Romanov;Wed Sep 26 11:55:20 2018 +0000;Merge branch '24-paper-page' into 'master'
Alyona;Tue Sep 25 17:13:01 2018 +0400;Alyona-Test
Elena;Tue Sep 25 16:45:01 2018 +0400;Тестовое задание
Anton Romanov;Sat Sep 22 06:56:33 2018 +0000;Update README.md
Anton Romanov;Sat Sep 8 10:19:21 2018 +0400;change ports
Anton Romanov;Sat Sep 8 10:07:21 2018 +0400;Merge remote-tracking branch 'origin/4-show-time-line' into 4-show-time-line
Anton Romanov;Sat Sep 8 09:54:14 2018 +0400;Merge branch 'master' into 4-show-time-line
Anton Romanov;Sat Sep 8 09:53:34 2018 +0400;path to timeline
Anton Romanov;Sat Sep 8 09:50:13 2018 +0400;fix papers font
Anton Romanov;Thu Sep 6 19:14:04 2018 +0000;Update README.md
Anton Romanov;Thu Sep 6 23:01:39 2018 +0400;add variable
Anton Romanov;Thu Sep 6 22:50:34 2018 +0400;deploy on vps
Anton Romanov;Wed Sep 5 21:58:04 2018 +0400;add timeline page
Anton Romanov;Wed Sep 5 14:50:49 2018 +0400;sort papers
Anton Romanov;Wed Sep 5 13:45:20 2018 +0400;fix paper colors
Anton Romanov;Wed Sep 5 13:31:51 2018 +0400;add method for create paper
Anton Romanov;Wed Sep 5 11:27:22 2018 +0400;get paper list
Anton Romanov;Sun Jun 10 13:43:40 2018 +0400;add timeline page
Anton Romanov;Sun Jun 10 01:53:32 2018 +0400;fix time
Anton Romanov;Sun Jun 10 01:49:38 2018 +0400;send notification
Anton Romanov;Sun Jun 10 01:12:28 2018 +0400;add event controller
Anton Romanov;Sat Jun 9 22:58:32 2018 +0400;remove liquibase
Anton Romanov;Sat Jun 9 22:41:00 2018 +0400;fix ports
Aleksey Filippov;Sun May 20 08:05:21 2018 +0200;delete orphaned files, migrate to webjars, some fixes and refactoring
Anton Romanov;Sat May 5 14:49:34 2018 +0400;add paper authors
Anton Romanov;Sat May 5 11:17:13 2018 +0400;add paper status
Anton Romanov;Sat May 5 11:14:37 2018 +0400;fix papers delete
Anton Romanov;Sat May 5 10:57:02 2018 +0400;fix papers crud
Anton Romanov;Sat May 5 00:39:18 2018 +0400;fix paper controller
Anton Romanov;Sat May 5 00:24:48 2018 +0400;add file uploading
Anton Romanov;Fri May 4 18:09:29 2018 +0400;add big logo
Anton Romanov;Fri May 4 18:04:09 2018 +0400;add paper controller
Anton Romanov;Fri May 4 17:54:46 2018 +0400;add ci
Anton Romanov;Fri May 4 17:23:22 2018 +0400;gitignore
Anton Romanov;Fri May 4 17:08:20 2018 +0400;add java code
Anton Romanov;Mon Apr 30 00:47:50 2018 +0400;add works
Anton Romanov;Sun Apr 29 20:48:05 2018 +0400;add paper page
Anton Romanov;Sun Apr 29 20:46:54 2018 +0400;add paper page
Anton Romanov;Sun Apr 29 20:44:47 2018 +0400;add paper page
Anton Romanov;Sun Apr 29 18:24:42 2018 +0400;add papers page
Anton Romanov;Sun Apr 29 17:09:58 2018 +0400;fix menu and sources
Anton Romanov;Sun Apr 29 00:49:37 2018 +0400;fix title page
Anton Romanov;Sat Apr 28 23:30:38 2018 +0400;fix title page
Anton Romanov;Sat Apr 28 22:50:26 2018 +0400;copy from landing

@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="masha" id="20190319_000001-1">
<addColumn tableName="paper">
<column name="url" type="varchar(255)"></column>
</addColumn>
</changeSet>
</databaseChangeLog>

@ -0,0 +1,13 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="masha" id="20190327_000000-1">
<addColumn tableName="event">
<column name="paper_id" type="integer"/>
</addColumn>
<addForeignKeyConstraint baseTableName="event" baseColumnNames="paper_id"
constraintName="fk_event_paper_id" referencedTableName="paper"
referencedColumnNames="id"/>
</changeSet>
</databaseChangeLog>

@ -0,0 +1,55 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="nastya" id="20190331_000000-1">
<createTable tableName="tag">
<column name="id" type="integer">
<constraints nullable="false"/>
</column>
<column name="tagname" type="varchar(255)"/>
</createTable>
<addPrimaryKey columnNames="id" constraintName="pk_tag" tableName="tag"/>
</changeSet>
<changeSet author="nastya" id="20190331_000000-2">
<createTable tableName="task">
<column name="id" type="integer">
<constraints nullable="false"/>
</column>
<column name="user_id" type="integer"/>
<column name="title" type="varchar(255)"/>
<column name="description" type="varchar(255)"/>
<column name="status" type="varchar(255)"/>
<column name="deadline_date" type="timestamp"/>
<column name="create_date" type="timestamp"/>
<column name="update_date" type="timestamp"/>
</createTable>
<addPrimaryKey columnNames="id" constraintName="pk_task" tableName="task"/>
<addForeignKeyConstraint baseTableName="task" baseColumnNames="user_id"
constraintName="fk_user_task_id" referencedTableName="users"
referencedColumnNames="id"/>
</changeSet>
<changeSet author="nastya" id="20190331_000000-3">
<createTable tableName="task_tags">
<column name="task_id" type="integer"/>
<column name="tag_id" type="integer"/>
</createTable>
<addForeignKeyConstraint baseTableName="task_tags" baseColumnNames="task_id"
constraintName="fk_task_id" referencedTableName="task"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="task_tags" baseColumnNames="tag_id"
constraintName="fk_tag_id" referencedTableName="tag"
referencedColumnNames="id"/>
</changeSet>
<changeSet author="nastya" id="20190331_000000-4">
<addColumn tableName="deadline">
<column name="task_id" type="integer"/>
</addColumn>
<addForeignKeyConstraint baseTableName="deadline" baseColumnNames="task_id"
constraintName="fk_deadlines_task" referencedTableName="task"
referencedColumnNames="id"/>
</changeSet>
</databaseChangeLog>

@ -0,0 +1,63 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="vova" id="20190331_000010-1">
<createTable tableName="conference">
<column name="id" type="integer">
<constraints nullable="false"/>
</column>
<column name="title" type="varchar(300)"/>
<column name="description" type="varchar(500)"/>
<column name="url" type="varchar(255)"/>
<column name="ping" type="integer"/>
<column name="begin_date" type="timestamp"/>
<column name="end_date" type="timestamp"/>
</createTable>
<addPrimaryKey columnNames="id" constraintName="pk_conference" tableName="conference"/>
</changeSet>
<changeSet author="vova" id="20190331_000010-2">
<createTable tableName="paper_conference">
<column name="conference_id" type="integer"/>
<column name="paper_id" type="integer"/>
</createTable>
<addForeignKeyConstraint baseTableName="paper_conference" baseColumnNames="conference_id"
constraintName=" fk_paper_conference_conference" referencedTableName="conference"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="paper_conference" baseColumnNames="paper_id"
constraintName="fk_paper_conference_paper" referencedTableName="paper"
referencedColumnNames="id"/>
</changeSet>
<changeSet author="vova" id="20190331_000010-3">
<createTable tableName="users_conference">
<column name="conference_id" type="integer"/>
<column name="users_id" type="integer"/>
<column name="participation" type="boolean"/>
<column name="deposit" type="varchar(255)"/>
</createTable>
<addForeignKeyConstraint baseTableName="users_conference" baseColumnNames="conference_id"
constraintName=" fk_users_conference_conference" referencedTableName="conference"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="users_conference" baseColumnNames="users_id"
constraintName="fk_users_conference_users" referencedTableName="users"
referencedColumnNames="id"/>
</changeSet>
<changeSet author="vova" id="20190331_000010-4">
<addColumn tableName="deadline">
<column name="conference_id" type="integer"/>
</addColumn>
<addForeignKeyConstraint baseTableName="deadline" baseColumnNames="conference_id"
constraintName=" fk_deadlines_conference" referencedTableName="conference"
referencedColumnNames="id"/>
</changeSet>
<changeSet author="orion" id="20190331_000010-5">
<addColumn tableName="conference">
<column name="version" type="integer"/>
</addColumn>
</changeSet>
</databaseChangeLog>

@ -0,0 +1,17 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="nastya" id="20190410_000000-1">
<addColumn tableName="tag">
<column name="version" type="integer"/>
</addColumn>
<renameColumn tableName="tag" oldColumnName="tagname" newColumnName="tag_name"/>
</changeSet>
<changeSet author="nastya" id="20190410_000000-2">
<addColumn tableName="task">
<column name="version" type="integer"/>
</addColumn>
</changeSet>
</databaseChangeLog>

@ -0,0 +1,22 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="anton" id="20190418_000000-1">
<addColumn tableName="project">
<column name="status" type="varchar(255)"/>
</addColumn>
<addColumn tableName="project">
<column name="description" type="varchar(255)"/>
</addColumn>
<addColumn tableName="project">
<column name="grant_id" type="integer"/>
</addColumn>
<addForeignKeyConstraint baseTableName="project" baseColumnNames="grant_id"
constraintName="fk_project_grant_id" referencedTableName="grants"
referencedColumnNames="id"/>
<addColumn tableName="project">
<column name="repository" type="varchar(255)"/>
</addColumn>
</changeSet>
</databaseChangeLog>

@ -19,6 +19,12 @@
<include file="db/changelog-20181208_000000-schema.xml"/>
<include file="db/changelog-20181224_000000-schema.xml"/>
<include file="db/changelog-20190318_000000-schema.xml"/>
<include file="db/changelog-20190318_000001-schema.xml"/>
<include file="db/changelog-20190327_000000-schema.xml"/>
<include file="db/changelog-20190331_000000-schema.xml"/>
<include file="db/changelog-20190331_000010-schema.xml"/>
<include file="db/changelog-20190410_000000-schema.xml"/>
<include file="db/changelog-20190418_000000-schema.xml"/>
<include file="db/changelog-20190323_000001-schema.xml"/>
<include file="db/common/changelog-20190312_130000-schema.xml"/>
</databaseChangeLog>

File diff suppressed because it is too large Load Diff

@ -1,94 +1,138 @@
.col-lg-12 a{
position: absolute;
font-size: smaller;
body {
min-width: 400px;
}
.col-lg-12 a img{
width: 36px;
height: 33px;
.conference-row .col:hover {
background-color: #eaeaea;
border-radius: .25rem;
}
.filter-option-inner-inner {
color: white;
}
.form-group textarea{
.form-group textarea {
min-height: 206px;
max-height: 463px;
}
.deadline-list{
.deadline-list {
height: 200px;
padding: 0px;
overflow-y: scroll;
}
.deadline{
.deadline {
margin: 0;
height: 40px;
min-height: 40px;
}
.deadline-text{
.deadline-text {
flex: 1;
}
.member-list{
.member-list {
height: 200px;
padding: 0px;
overflow-y: scroll;
}
.member{
.member {
margin: 0;
}
.paper-list{
.paper-list {
height: 200px;
padding: 0px;
overflow-y: scroll;
}
.paper{
.paper {
margin: 0;
min-height: 40px;
height: 40px;
}
.paper-name{
.paper-name {
flex: 1;
}
.paper-name span{
.paper-name span {
margin: 6px 15px;
display: inline-block;
}
.icon{
.icon {
width: 38px;
height: 38px;
padding: 2px;
cursor: pointer;
}
.icon-delete{
.icon-delete {
background-color: #f44;
background-image: url(/img/conference/delete.png);
background-repeat: round;
color: transparent !important;
}
.icon-delete:hover {
background-color: #ff2929;
transition: background-color .15s ease-in-out;
}
.icon-paper{
height: 26px;
width: 26px;
float: right;
margin: 5px;
.icon-paper {
height: 26px;
width: 26px;
float: right;
margin: 5px;
}
.grey-border{
.grey-border {
color: #495057;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: .25rem;
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
#add-paper{
margin-left: 10px;
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
#cancel-button{
#cancel-button {
position: relative;
font-size: 1rem;
}
.paper-control button {
margin: 0 0 10px 10px;
float: right;
}
@media (max-width: 1199px) and (min-width: 768px){
.paper-control {
display: block!important;
}
}
@media (max-width: 991px) {
.dates-panel {
display: block!important;
}
.date {
margin-bottom: 10px;
}
}
@media (max-width: 768px) {
.dashboard-elements {
display: block!important;
}
.dashboard-right {
margin-bottom: 10px;
}
}

@ -0,0 +1,226 @@
.odin-unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.odin-kill-padding {
padding: 0;
}
.odin-input-group {
padding-left: 15px !important;
padding-right: 15px !important;
}
.odin-closable .fa {
font-size: 1.5em;
margin-top: -1px;
}
.odin-closable .fa:hover:before {
content: "\f057";
}
/*
Odin Toolbar
*/
.odin-toolbar {
padding-left: 1px;
padding-bottom: 4px;
}
.odin-toolbar .odin-btn {
float: none !important;
}
.odin-btn {
min-width: 112px;
margin-right: 3px;
}
@media (min-width: 768px) {
.odin-btn {
min-width: 150px;
}
}
/*
Odin Paginator
*/
.odin-paginator {
margin: 0;
margin-top: 5px;
text-align: center;
}
.odin-paginator-content {
display: inline-block;
}
.odin-paginator-content a {
cursor: pointer;
color: black;
float: left;
padding: 6px 16px;
text-decoration: none;
transition: background-color .3s;
border-radius: 4px;
}
.odin-paginator-content i {
color: black;
float: left;
padding: 6px 16px;
}
.odin-paginator-content a.active {
background-color: #4CAF50;
color: white;
}
.odin-paginator-content a:hover:not(.active) {
background-color: #ddd;
}
/*
Odin Formatters
*/
.odin-negative {
color: red;
font-weight: bold;
}
/*
Odin Table
*/
.odin-table {
min-height: 324px;
border: 1px solid #ddd;
padding: 0;
margin: 0 0 0 1px;
background-color: #f8f8f8;
}
.odin-table > table {
margin-bottom: 0;
}
.odin-table > table > tbody > tr {
background-color: #fff;
}
.odin-table-pointed-line {
cursor: pointer;
}
.odin-table-selected-line {
background-color: #5bc0de !important;
}
.odin-table-selected-line:hover {
background-color: #6bd0ee !important;
}
/*
Odin Form
*/
.odin-form {
display: none;
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1500;
background: rgba(0, 0, 0, 0.5);
}
.odin-form .panel {
position: relative;
max-height: 95%;
max-width: 95%;
overflow: auto;
}
@media (min-width: 768px) {
.odin-form .panel {
max-width: 55%;
}
}
.odin-form .panel-footer {
padding: 5px 7px;
}
.odin-form .odin-btn {
float: right;
}
.odin-checkbox {
width: 20px;
height: 20px;
}
.odin-form .tab-pane {
padding-top: 5px;
}
/*
Odin Confirm Box
*/
.odin-confirm-box {
display: none;
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 2000;
background: rgba(0, 0, 0, 0.5);
}
.odin-confirm-box .panel {
position: relative;
max-width: 95%;
}
.odin-confirm-box .panel-footer {
text-align: center;
}
@media (min-width: 768px) {
.odin-confirm-box .panel {
max-width: 25%;
}
}
.odin-confirm-box .panel-body {
text-align: center;
}
/*
Odin Table Box
*/
.odin-table-box {
z-index: 2500;
}
/*
Odin Simple Box
*/
@media (min-width: 768px) {
.odin-simple-form .panel {
max-width: 35%;
}
}

@ -0,0 +1,65 @@
.tags-container {
width: 100%;
padding: .375rem .75rem;
background-color: #fff;
border: 1px solid #ccc;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
display: inline-block;
color: #555;
vertical-align: middle;
border-radius: 4px;
max-width: 100%;
line-height: 22px;
cursor: text;
}
.input-tag-name {
border: none;
box-shadow: none;
outline: none;
background-color: transparent;
padding: 0 6px;
margin: 0;
width: auto;
max-width: inherit;
}
.tag {
display: inline-block;
padding: .2em .6em .3em;
background-color: orange;
border-radius: .25em;
margin-right: 4px;
margin-bottom: 4px;
font-size: 75%;
font-weight: 700;
line-height: 1.5;
color: #fff;
}
.tag-name span[data-role="remove"] {
margin-left: 8px;
cursor: pointer;
}
.tag-name span[data-role="remove"]:after {
content: "x";
padding: 0px 2px;
}
.tag-name input[type="text"] {
background: transparent;
border: none;
display: inline-flex;
font-size: 100%;
font-weight: 700;
line-height: 1.5;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
outline: none;
cursor: default;
}

@ -0,0 +1,41 @@
$(document).ready(function () {
$(".conference-row").mouseenter(function (event) {
var conferenceRow = $(event.target).closest(".conference-row");
$(conferenceRow).css("background-color", "#f8f9fa");
$(conferenceRow).find(".remove-conference").removeClass("d-none");
});
$(".conference-row").mouseleave(function (event) {
var conferenceRow = $(event.target).closest(".conference-row");
$(conferenceRow).css("background-color", "white");
$(conferenceRow).closest(".conference-row").find(".remove-conference").addClass("d-none");
});
$('a[data-confirm]').click(function(ev) {
var href = $(this).attr('href');
if (!$('#dataConfirmModal').length) {
$('#modalDelete').append('<div class="modal fade" id="dataConfirmModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"\n' +
' >\n' +
' <div class="modal-dialog modal-sm">\n' +
' <div class="modal-content">\n' +
' <div class="modal-header">\n' +
' <h8 class="modal-title" id="myModalLabel">Удалить конференцию?</h8>\n' +
' <button type="button" class="close" data-dismiss="modal" aria-label="Закрыть"><span\n' +
' aria-hidden="true">&times;</span></button>\n' +
' </div>\n' +
' <div class="modal-footer">\n' +
' <a class="btn btn-primary" id="dataConfirmOK">Да</a>'+
' <button class="btn primary" data-dismiss="modal" aria-hidden="true">Нет</button>'+
' </div>\n' +
' </div>\n' +
' </div>\n' +
' </div>');
}
$('#dataConfirmModal').find('#myModalLabel').text($(this).attr('data-confirm'));
$('#dataConfirmOK').attr('href', href);
$('#dataConfirmModal').modal({show:true});
return false;
});
});

@ -0,0 +1,13 @@
/* exported contextPath */
var contextPath = "";
var apiVersion = "/api/1.0";
var basePath = contextPath + apiVersion;
/* exported uiLocale */
var uiLocale = "ru";
/* exported urlVersions */
var urlVersions = basePath + "/versions";
/* exported urlCommits */
var urlCommits = basePath + "/commits";

@ -89,20 +89,18 @@ function getFromRest(url, callBack, errorCallBack) {
}
/* exported getFromRestWithVersion */
function getFromRestWithVersion(url, callBack, errorCallBack) {
getFromRestWithVersionAndParams(url, "", callBack, errorCallBack);
function getFromRest(url, callBack, errorCallBack) {
getFromRestWithParams(url, "", callBack, errorCallBack);
}
/* exported getFromRestWithVersionAndParams */
function getFromRestWithVersionAndParams(url, params, callBack, errorCallBack) {
getCurrentVersion(function (version) {
$.ajax({
url: url + "?versionId=" + version + params,
cache: false,
success: function (response) {
errorHandler(response, callBack, errorCallBack);
}
});
function getFromRestWithParams(url, params, callBack, errorCallBack) {
$.ajax({
url: url + "?" + params,
cache: false,
success: function (response) {
errorHandler(response, callBack, errorCallBack);
}
});
}
@ -192,32 +190,6 @@ function deleteFromRest(url, callBack, completeCallback, errorCallBack) {
});
}
/* exported getCurrentVersion */
function getCurrentVersion(callBack, errorCallBack) {
var version = localStorage.getItem("currentVersion");
if (($("#select-versions")[0].options.length > 0)
&& ($("#select-versions option[value='" + version + "']").length === 0)) {
localStorage.removeItem("currentVersion");
version = "";
}
if (isEmpty(version)) {
getFromRest(urlVersions,
function (versions) {
if (isEmpty(versions) || versions.count === 0) {
return;
}
var currentVersion = versions.items[0];
localStorage.setItem("currentVersion", currentVersion.id);
callBack(currentVersion.id);
},
errorCallBack);
} else {
callBack(version);
}
}
/* exported fillSelect */
function fillSelect(selectElement, values) {
$(selectElement).html("");

File diff suppressed because it is too large Load Diff

@ -0,0 +1,113 @@
/*<![CDATA[*/
$(document).ready(function () {
$("#tags .tag .tag-name input[type=text]").each(function() {
$(this).attr("size", $(this).val().length)
});
$("#task-form").keydown(function(event){
if(event.keyCode == 13) {
event.preventDefault();
return false;
}
});
function removeTag () {
$(this).parent().parent().remove();
}
$("#input-tag").keyup(function (event) {
if(event.keyCode == 13 || event.keyCode == 188) {
var tagNumber = $("#tags .tag").length;
var tagName = $.trim($(this).val());
var addTag = true;
// проверка, добавлен ли этот тег
$("#tags .tag .tag-name input[type=text]").each(function() {
if(tagName === $(this).val()) {
addTag = false;
return;
}
});
// если тег не добавлен
if(addTag) {
// контейнер тега
var newTagRow = $("<div/>")
.attr("id", 'tags' + tagNumber)
.addClass("tag");
// контейнер id
var idInput = $("<input/>")
.attr("type", "hidden")
.attr("id", "tags" + tagNumber + ".id")
.attr("name", "tags[" + tagNumber + "].id")
.attr("value", '');
// контейнер текста
var conDiv = $("<div/>")
.addClass("tag-name");
// текст тега
var nameInput = $("<input/>")
.attr("type", "text")
.attr("id", "tags" + tagNumber + ".tagName")
.attr("name", "tags[" + tagNumber + "].tagName")
.attr("value", tagName)
.attr("readonly", "true")
.attr("size", tagName.length);
// кнопка удалить тег
var removeSpan = $("<span/>")
.attr("data-role", "remove")
.bind("click", removeTag);
conDiv.append(nameInput);
conDiv.append(removeSpan);
newTagRow.append(idInput);
newTagRow.append(conDiv);
$(this).before(newTagRow);
}
$(this).val('');
}
});
$("span[data-role=remove]").click(removeTag);
$(".task-row").mouseenter(function (event) {
var taskRow = $(event.target).closest(".task-row");
$(taskRow).css("background-color", "#f8f9fa");
$(taskRow).find(".remove-task").removeClass("d-none");
});
$(".task-row").mouseleave(function (event) {
var taskRow = $(event.target).closest(".task-row");
$(taskRow).css("background-color", "white");
$(taskRow).closest(".task-row").find(".remove-task").addClass("d-none");
});
$('a[data-confirm]').click(function(ev) {
var href = $(this).attr('href');
if (!$('#dataConfirmModal').length) {
$('#modalDelete').append('<div class="modal fade" id="dataConfirmModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"\n' +
' >\n' +
' <div class="modal-dialog modal-sm">\n' +
' <div class="modal-content">\n' +
' <div class="modal-header">\n' +
' <h8 class="modal-title" id="myModalLabel">Удалить статью?</h8>\n' +
' <button type="button" class="close" data-dismiss="modal" aria-label="Закрыть"><span\n' +
' aria-hidden="true">&times;</span></button>\n' +
' </div>\n' +
' <div class="modal-footer">\n' +
' <a class="btn btn-primary" id="dataConfirmOK">Да</a>'+
' <button class="btn primary" data-dismiss="modal" aria-hidden="true">Нет</button>'+
' </div>\n' +
' </div>\n' +
' </div>\n' +
' </div>');
}
$('#dataConfirmModal').find('#myModalLabel').text($(this).attr('data-confirm'));
$('#dataConfirmOK').attr('href', href);
$('#dataConfirmModal').modal({show:true});
return false;
});
});
/*]]>*/

@ -0,0 +1,165 @@
<script type="text/template" id="createButton">
<button type="button" class="btn btn-success odin-btn"><i class="fa fa-plus-square-o"></i> <span>{0}</span></button>
</script>
<script type="text/template" id="editButton">
<button type="button" class="btn btn-info odin-btn"><i class="fa fa-pencil-square-o"></i> <span>{0}</span></button>
</script>
<script type="text/template" id="deleteButton">
<button type="button" class="btn btn-danger odin-btn"><i class="fa fa-trash-o"></i> <span>{0}</span></button>
</script>
<script type="text/template" id="okButton">
<button type="button" class="btn btn-success odin-btn"><span>{0}</span></button>
</script>
<script type="text/template" id="cancelButton">
<button type="button" class="btn btn-danger odin-btn"><span>{0}</span></button>
</script>
<script type="text/template" id="basicButton">
<button type="button" class="btn btn-basic odin-btn"><span>{0}</span></button>
</script>
<script type="text/template" id="buttonGroup">
<div class="input-group-btn">
</div>
</script>
<script type="text/template" id="chooseButton">
<button type="button" class="btn btn-default odin-choose-btn">
<i class="fa fa-ellipsis-h"></i>
</button>
</script>
<script type="text/template" id="clearButton">
<button type="button" class="btn btn-default odin-clear-btn">
<i class="fa fa-close"></i>
</button>
</script>
<script type="text/template" id="emptyDiv">
<div>
</div>
</script>
<script type="text/template" id="anchor">
<a href="{0}">{1}</a>
</script>
<script type="text/template" id="toolbar">
<div class="odin-toolbar">
</div>
</script>
<script type="text/template" id="paginator">
<div class="odin-paginator">
<div class="odin-paginator-content">
</div>
</div>
</script>
<script type="text/template" id="paginatorButton">
<a id="odin-paginator-{0}">{1}</a>
</script>
<script type="text/template" id="paginatorSeparator">
<i class="fa fa-ellipsis-h"></i>
</script>
<script type="text/template" id="tableBoolean">
<i class="fa {0}"></i>
</script>
<script type="text/template" id="tableNumericNegative">
<span class="odin-negative">{0}</span>
</script>
<script type="text/template" id="table">
<div class="table-responsive odin-table">
<table class="table table-bordered table-condensed">
<thead>
</thead>
<tbody>
</tbody>
</table>
</div>
</script>
<script type="text/template" id="tableLine">
<tr></tr>
</script>
<script type="text/template" id="tableHeadColumn">
<th class="col-xs-1">{0}</th>
</script>
<script type="text/template" id="tableBodyColumn">
<td></td>
</script>
<script type="text/template" id="formInputGroup">
<div class="form-group clearfix">
</div>
</script>
<script type="text/template" id="formLabel">
<label class="col-lg-2 control-label" for="{0}">{1}</label>
</script>
<script type="text/template" id="formInputWrapper">
<div class="col-lg-10">
</div>
</script>
<script type="text/template" id="formInputCheckbox">
<input type="checkbox" class="odin-checkbox" id="{0}" {1}>
</script>
<script type="text/template" id="formInput">
<input class="form-control" id="{0}" value="{1}" type="{2}">
</script>
<script type="text/template" id="form">
<form class="odin-form">
</form>
</script>
<script type="text/template" id="formConfirm">
<div class="odin-confirm-box">
</div>
</script>
<script type="text/template" id="formSimple">
<div class="odin-form">
</div>
</script>
<script type="text/template" id="formPanel">
<div class="panel panel-default">
</div>
</script>
<script type="text/template" id="formHeader">
<div class="panel-heading odin-unselectable odin-closable">
<span id="caption"></span>
<i class="fa fa-times-circle-o fa-pull-right"></i>
</div>
</script>
<script type="text/template" id="formContent">
<div class="panel-body">
</div>
</script>
<script type="text/template" id="formFooter">
<div class="panel-footer clearfix">
</div>
</script>
<script type="text/template" id="choseTable">
<div id="table-block" class=\"panel-body odin-kill-padding\"></div>
</script>
<script type="text/template" id="formTabs">
<ul class="nav nav-tabs">
<li class="active">
<a data-toggle="tab" href="#{0}">{1}</a>
</li>
</ul>
<div class="tab-content">
<div id="{0}" class="tab-pane active">
</div>
</div>
</script>
<script type="text/template" id="formTab">
<li>
<a data-toggle="tab" href="#{0}">{1}</a>
</li>
</script>
<script type="text/template" id="formTabContent">
<div id="{0}" class="tab-pane">
</div>
</script>
<script type="text/template" id="copyForm">
<div class="form-group clearfix">
<label class="col-lg-2 control-label" for="fromVersion">Из версии</label>
<div class="col-lg-10">
<select class="form-control" id="fromVersion" required="required">
</select>
</div>
</div>
<div class="form-group clearfix">
<label class="col-lg-2 control-label" for="version">В версию</label>
<div class="col-lg-10">
<input class="form-control" id="version" disabled="disabled">
</div>
</div>
</script>

@ -1,24 +1,28 @@
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
<head>
</head>
<body>
<div class="container" layout:fragment="content">
<div id="commits-tab">
</div>
</div>
<th:block layout:fragment="scripts">
<script th:inline="javascript">
/*<![CDATA[*/
$(document).ready(function () {
new OdinTableWithMeta("commits-tab", urlCommits);
});
/*]]>*/
</script>
</th:block>
</body>
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
<head>
</head>
<body>
<div class="container" layout:fragment="content">
<section id="commits">
<div class="container">
<div id="commits-tab">
</div>
</div>
</section>
</div>
<th:block layout:fragment="scripts">
<script th:inline="javascript">
/*<![CDATA[*/
$(document).ready(function () {
new OdinTableWithMeta("commits-tab", urlCommits);
});
/*]]>*/
</script>
</th:block>
</body>
</html>

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default" xmlns:th="">
<head>
<link rel="stylesheet" type="text/css" href="../css/conference.css"/>
</head>
<body>
<div layout:fragment="content">
<section id="conference">
<div class="container">
<div class="row">
<div class="col-lg-12">
<h3 class="section-heading text-uppercase text-center">Актуальные конференции</h3>
<div th:replace="conferences/fragments/confNavigationFragment"/>
</div>
</div>
<hr/>
<div class="row">
<div class="col-lg-12">
</div>
</div>
</div>
</section>
</div>
</body>
</html>

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
layout:decorator="default" xmlns:th="">
<head>
<link rel="stylesheet" type="text/css" href="../css/conference.css"/>
</head>
@ -11,55 +11,66 @@
<div class="container">
<div class="row">
<div class="col-lg-12">
<a class="d-flex align-items-center" href="/conferences/conferences">
<img class="icon" src="/img/conference/back.png"/>
Назад к списку конференций
</a>
<h3 class="section-heading text-uppercase text-center">Редактирование конференции</h3>
<div th:replace="conferences/fragments/confNavigationFragment"/>
</div>
</div>
<hr/>
<div class="row">
<div class="col-lg-12">
<form id="paper-form" method="post">
<div class="row">
<form id="conference-form" method="post"
th:action="@{'/conferences/conference?id='+ *{id == null ? '' : id} + ''}"
th:object="${conferenceDto}">
<div class="row">
<div class="col-md-7 col-sm-12">
<input type="hidden" name="id"/>
<input type="hidden" name="id" th:field="*{id}"/>
<div class="form-group">
<label for="title">Название:</label>
<input class="form-control" id="title" type="text"
<input class="form-control" th:field="*{title}" id="title" type="text"
placeholder="Название конференции"/>
<p th:if="${#fields.hasErrors('title')}" th:errors="*{title}"
class="alert alert-danger">Incorrect title</p>
<p class="help-block text-danger"></p>
</div>
<div class="form-group">
<label for="url">URL:</label>
<input class="form-control" id="url" type="text"
<input class="form-control" th:field="*{url}" id="url" type="text"
placeholder="URL адрес"/>
</div>
<div class="form-group">
<label for="description">Описание:</label>
<textarea class="form-control" rows="8" id="description">
<textarea class="form-control" rows="8" th:field="*{description}" id="description">
</textarea>
</div>
<div class="form-group">
<label for="deadlines">Дедлайны:</label>
<div class="deadline-list form-control" id="deadlines">
<div class="row deadline grey-border">
<input class="form-control deadline-text" type="text"
placeholder="Текст дедлайна"/>
<input type="date"/>
<img class="icon grey-border icon-delete" src="/img/conference/delete.png"
alt="Удалить"/>
<div class="deadline-list form-control list-group" id="deadlines">
<input type="hidden" th:field="*{removedDeadlineIds}"/>
<div class="deadline d-flex p-0 list-group-item list-group-horizontal"
th:each="deadline, rowStat : *{deadlines}">
<input type="hidden" th:field="*{deadlines[__${rowStat.index}__].id}"/>
<input class="deadline-text col-md list-group-item" type="text"
placeholder="Описание"
th:field="*{deadlines[__${rowStat.index}__].description}"/>
<input class="list-group-item" type="date" name="deadline"
th:field="*{deadlines[__${rowStat.index}__].date}"/>
<input type="submit" class="icon icon-delete grey-border"
alt="Удалить" name="removeDeadline" th:value="${rowStat.index}"/>
</div>
</div>
</div>
<p th:if="${#fields.hasErrors('deadlines')}" th:errors="*{deadlines}"
class="alert alert-danger">Incorrect title</p>
<p class="help-block text-danger"></p>
<div class="form-group d-flex justify-content-end">
<input type="submit" id="add-deadline" name="add-deadline"
<input type="submit" id="addDeadline" name="addDeadline"
class="btn btn-primary"
value="Добавить дедлайн"/>
</div>
@ -69,39 +80,47 @@
<div class="form-group">
<label for="dates">Дата проведения:</label>
<div class="row" id="dates">
<div class="col">
<input type="date" id="date-begin"/>
-
<input type="date" id="date-end"/>
<div class="d-flex col justify-content-between dates-panel">
<div class="date">
<input class="grey-border form-control" type="date"
th:field="*{beginDate}" id="begin-date"/>
</div>
<div class="date">
<input class="grey-border form-control" type="date"
th:field="*{endDate}" id="end-date"/>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="members">Участники:</label>
<div class="member-list form-control" id="members">
<div class="row member grey-border">
<div class="col-5 member-name">
<div class="member-list form-control list-group" id="members">
<div class="member d-flex list-group-item justify-content-between p-1">
<div class="member-name">
Пользователь 1
</div>
<div class="col-3 member-participation">
<div class="member-participation">
очная
</div>
<div class="col member-deposit">
<div class="member-deposit">
статья
</div>
</div>
<div class="row member grey-border">
<div class="col-5 member-name">
Пользователь 2
<div class="member d-flex list-group-item justify-content-between p-1">
<div class="member-name">
Пользователь 1
</div>
<div class="col-3 member-participation">
заочная
<div class="member-participation">
очная
</div>
<div class="col member-deposit">
<div class="member-deposit">
доклад
</div>
</div>
</div>
</div>
@ -114,24 +133,31 @@
<div class="form-group">
<label for="papers">Статьи:</label>
<div class="paper-list form-control" id="papers">
<div class="row paper grey-border">
<div class="paper-name grey-border">
<span>
<div class="paper-list form-control list-group" id="papers">
<input th:type="hidden" th:field="*{papers}"/>
<div class="paper d-flex list-group-item p-0"
th:each="paper, rowStat : *{papers}">
<a class="paper-name"
th:href="@{'/papers/paper?id=' + *{papers[__${rowStat.index}__].id} + ''}">
<span th:text="*{papers[__${rowStat.index}__].title}">
Имя статьи
</span>
<img class="icon-paper" src="/img/conference/paper.png"/>
</div>
<img class="icon grey-border icon-delete" src="/img/conference/delete.png"
alt="Удалить"/>
</a>
<input type="submit" class="icon icon-delete grey-border"
alt="Удалить" name="removePaper" th:value="${rowStat.index}"/>
</div>
</div>
</div>
<div class="form-group d-flex justify-content-end">
<button id="attach-paper" class="btn btn-primary"
type="button">
Прикрепить статью
</button>
<div class="paper-control form-group d-flex justify-content-end">
<input th:type="hidden" th:field="*{notSelectedPapers}"/>
<select class="selectpicker form-control" multiple="true" data-live-search="true"
title="Прикрепить статью" data-style="btn-primary" data-size="5"
th:field="*{paperIds}">
<option th:each="paper: *{notSelectedPapers}" th:value="${paper.id}"
th:text="${paper.title}">Status
</option>
</select>
<button id="add-paper" class="btn btn-primary"
type="button">
Добавить статью

@ -1,20 +1,54 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
layout:decorator="default" xmlns:th="">
<head>
<link rel="stylesheet" type="text/css" href="../css/conference.css"/>
</head>
<body>
<div layout:fragment="content">
<form id="conferences-form" method="post" th:action="@{'/conferences/conferences'}">
<section id="conferences">
<div class="container">
<div class="row" id="conference-list">
<div class="col-lg-12 text-center">
<h3 class="section-heading text-uppercase">Конференции</h3>
<div th:replace="conferences/fragments/confNavigationFragment"/>
</div>
</div>
<hr/>
<div class="row">
<div class="col-md-9 col-sm-12">
<th:block th:each="conference : ${filteredConferences.conferences}">
<div th:replace="conferences/fragments/confLineFragment :: confLine(conference=${conference})"/>
</th:block>
</div>
<div class="col-md-3 col-sm-12">
<div class="filter">
<h5>Фильтр:</h5>
<select class="form-control" id="author"
onchange="this.form.submit();">
<option value="">Все авторы</option>
<option>lastName
</option>
</select>
<select class="form-control" id="year"
onchange="this.form.submit();">
<option value="">Все годы</option>
<option>year
</option>
</select>
</div>
</div>
</div>
</div>
</section>
<a href="./conference" style="
top: 100px;
position: absolute;
width: 100px;
height: 50px;
">нажать</a>
<div id="modalDelete"/>
</form>
<script src="../js/conference.js"></script>
</div>
</body>
</html>
</html>

@ -0,0 +1,21 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<div th:fragment="confDashboard (conference)" class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 dashboard-card">
<div class="row">
<div class="col-2">
</div>
<div class="col col-10 text-right">
<h7 class="service-heading"> title</h7>
<p class="text-muted"></p>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,22 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<div th:fragment="confLine (conference)" class="row text-left conference-row h3" style="background-color: white;">
<div class="col">
<a th:href="@{'conference?id='+${conference.id}}">
<span class="h5" th:text="${conference.title}"/>
</a>
<input class="id-class" type="hidden" th:value="${conference.id}"/>
<a class="remove-paper pull-right" th:href="@{'/conferences/delete/'+${conference.id}}"
data-confirm="Удалить статью?">
<i class="fa fa-trash" aria-hidden="true"></i>
</a>
</div>
</div>
</body>
</html>

@ -0,0 +1,29 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<div class="row justify-content-center control-panel">
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
<a href="./conferences" class="btn btn-light toolbar-button">
<i class="fa fa-list-alt"></i>
Весь список</a>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
<a href="./actual" class="btn btn-light toolbar-button">
<i class="fa fa-newspaper-o" aria-hidden="true"></i>
Актуальное</a>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
<a href="./conference?id=0" class="btn btn-light toolbar-button">
<i class="fa fa-plus-circle" aria-hidden="true"></i>
Новая конференцию</a>
</div>
</div>
</body>
</html>

@ -23,6 +23,7 @@
<!-- Custom styles for this template -->
<link rel="stylesheet" href="/css/agency.css"/>
<link rel="stylesheet" href="/css/odin.css"/>
<!-- Bootstrap core JavaScript -->
<script src="/webjars/jquery/3.3.1-1/jquery.min.js"></script>
<script src="/webjars/bootstrap/4.1.0/js/bootstrap.bundle.min.js"></script>
@ -94,6 +95,10 @@
</footer>
<script src="/js/core.js"></script>
<script src="/js/config.js"></script>
<script src="/js/odin.js"></script>
<th:block layout:fragment="scripts">
</th:block>
<!-- Yandex.Metrika counter -->
<script type="text/javascript" >
(function (d, w, c) {

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<div th:fragment="noRecords(entities, noRecordsMessage, url)" class="col-12 text-center"
style="background-color: white;">
<div th:if="*{#lists.isEmpty(entities)}">
<div th:text="'Еще не создано ни'+${noRecordsMessage}"/>
<a th:href="@{${url}+'?id=0'}">
Перейдите по ссылке, чтобы добавить
</a>
</div>
</div>
</body>
</html>

@ -17,6 +17,7 @@
<div th:replace="grants/fragments/grantDashboardFragment :: grantDashboard(grant=${grant})"/>
</th:block>
</div>
<div th:replace="fragments/noRecordsFragment :: noRecords(entities=${grants}, noRecordsMessage=' одного гранта', url='grant')"/>
</div>
</section>
</div>

@ -24,6 +24,7 @@
</div>
<div class="col-md-3 col-sm-12">
</div>
<div th:replace="fragments/noRecordsFragment :: noRecords(entities=${grants}, noRecordsMessage=' одного гранта', url='grant')"/>
</div>
</div>
</section>

@ -10,12 +10,6 @@
<!-- Portfolio Grid -->
<section class="bg-light" id="portfolio">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading text-uppercase">Work hard</h2>
<h3 class="section-subheading text-muted">sometimes</h3>
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-6 portfolio-item">
<a class="portfolio-link" href="./papers/papers">
@ -46,7 +40,7 @@
</div>
</div>
<div class="col-md-4 col-sm-6 portfolio-item">
<a class="portfolio-link" data-toggle="modal" href="/projects">
<a class="portfolio-link" href="./projects/dashboard">
<div class="portfolio-hover">
<div class="portfolio-hover-content">
<i class="fa fa-arrow-right fa-3x"></i>
@ -88,7 +82,7 @@
</div>
</div>
<div class="col-md-4 col-sm-6 portfolio-item">
<a class="portfolio-link" data-toggle="modal" href="/students">
<a class="portfolio-link" href="./students/tasks">
<div class="portfolio-hover">
<div class="portfolio-hover-content">
<i class="fa fa-arrow-right fa-3x"></i>

@ -18,6 +18,7 @@
<div th:replace="papers/fragments/paperDashboardFragment :: paperDashboard(paper=${paper})"/>
</th:block>
</div>
<div th:replace="fragments/noRecordsFragment :: noRecords(entities=${papers}, noRecordsMessage=' одной статьи', url='paper')"/>
</div>
</section>
</div>

@ -10,7 +10,13 @@
<span th:replace="papers/fragments/paperStatusFragment :: paperStatus(paperStatus=${paper.status})"/>
</div>
<div class="col col-10 text-right">
<h7 class="service-heading" th:text="${paper.title}"> title</h7>
<p th:if="${paper.url!=null and paper.url!=''}"><a target="_blank" th:href="${paper.url}"><i
class="fa fa-external-link fa-1x"
aria-hidden="true"></i></a></p>
<p th:unless="${paper.url!=null and paper.url!=''}"><i class="fa fa-fw fa-2x" aria-hidden="true"></i></p>
<a th:href="'paper?id='+${paper.id}">
<h7 class="service-heading" th:text="${paper.title}"> title</h7>
</a>
<p class="text-muted" th:text="${paper.authorsString}">authors</p>
</div>
</div>

@ -24,7 +24,6 @@
th:action="@{'/papers/paper?id='+ *{id == null ? '' : id} + ''}"
th:object="${paperDto}">
<div class="row">
<div class="col-md-7 col-sm-12">
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
@ -63,49 +62,54 @@
th:field="*{comment}"></textarea>
</div>
<div class="form-group">
<label>Дедлайны:</label>
<div class="row" th:each="deadline, rowStat : *{deadlines}">
<input type="hidden" th:field="*{deadlines[__${rowStat.index}__].id}"/>
<div class="col-6">
<input type="date" class="form-control" name="deadline"
th:field="*{deadlines[__${rowStat.index}__].date}"/>
</div>
<div class="col-4">
<input class="form-control" type="text" placeholder="Описание"
th:field="*{deadlines[__${rowStat.index}__].description}"/>
</div>
<div class="col-2">
<a class="btn btn-danger float-right"
th:onclick="|$('#deadlines${rowStat.index}\\.description').val('');
$('#deadlines${rowStat.index}\\.date').val('');
$('#addDeadline').click();|"><span
aria-hidden="true"><i class="fa fa-times"/></span>
</a>
</div>
</div>
<p th:if="${#fields.hasErrors('deadlines')}" th:errors="*{deadlines}"
class="alert alert-danger">Incorrect title</p>
<div class="form-group">
<label for="title">Ссылка на сайт конференции:</label>
<input class="form-control" id="url" type="text"
placeholder="Url"
th:field="*{url}"/>
</div>
<div class="form-group">
<label>Дедлайны:</label>
<div class="row" th:each="deadline, rowStat : *{deadlines}">
<input type="hidden" th:field="*{deadlines[__${rowStat.index}__].id}"/>
<div class="col-6">
<input type="date" class="form-control" name="deadline"
th:field="*{deadlines[__${rowStat.index}__].date}"/>
</div>
<div class="form-group">
<input type="submit" id="addDeadline" name="addDeadline"
class="btn btn-primary"
value="Добавить
дедлайн"/>
<div class="col-4">
<input class="form-control" type="text" placeholder="Описание"
th:field="*{deadlines[__${rowStat.index}__].description}"/>
</div>
<div class="form-group">
<label>Авторы:</label>
<select class="selectpicker form-control" multiple="true"
data-live-search="true"
title="-- Выберите авторов --"
th:field="*{authorIds}">
<option th:each="author: ${allAuthors}" th:value="${author.id}"
th:text="${author.lastName}">Status
</option>
</select>
<p th:if="${#fields.hasErrors('authorIds')}" th:errors="*{authorIds}"
class="alert alert-danger">Incorrect title</p>
<div class="col-2">
<a class="btn btn-danger float-right"
th:onclick="|$('#deadlines${rowStat.index}\\.description').val('');
$('#deadlines${rowStat.index}\\.date').val('');
$('#addDeadline').click();|"><span
aria-hidden="true"><i class="fa fa-times"/></span>
</a>
</div>
</div>
<p th:if="${#fields.hasErrors('deadlines')}" th:errors="*{deadlines}"
class="alert alert-danger">Incorrect title</p>
</div>
<div class="form-group">
<input type="submit" id="addDeadline" name="addDeadline" class="btn btn-primary"
value="Добавить
дедлайн"/>
</div>
<div class="form-group">
<label>Авторы:</label>
<select class="selectpicker form-control" multiple="true" data-live-search="true"
title="-- Выберите авторов --"
th:field="*{authorIds}">
<option th:each="author: ${allAuthors}" th:value="${author.id}"
th:text="${author.lastName}">Status
</option>
</select>
<p th:if="${#fields.hasErrors('authorIds')}" th:errors="*{authorIds}"
class="alert alert-danger">Incorrect title</p>
</div>
<div class="form-group files-list" id="files-list">
<label>Файлы:</label>

@ -43,6 +43,7 @@
</div>
</div>
</div>
<div th:replace="fragments/noRecordsFragment :: noRecords(entities=${filteredPapers.papers}, noRecordsMessage=' одной статьи', url='paper')"/>
</div>
</section>

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div class="container" layout:fragment="content">
<section id="services">
<div class="container">
<div class="col-lg-12 text-center">
<h2 class="section-heading text-uppercase">Проекты</h2>
<div th:replace="projects/fragments/projectNavigationFragment"/>
</div>
<div class="row justify-content-center" id="dashboard">
<th:block>
<div/>
</th:block>
</div>
</div>
</section>
</div>
</body>
</html>

@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<div th:fragment="projectLine (project)" class="row text-left project-row" style="background-color: white;">
<div class="col">
<span th:replace="projects/fragments/projectStatusFragment :: projectStatus(projectStatus=${project.status})"/>
<a th:href="@{'project?id='+${project.id}}">
<span class="h6" th:text="${project.title}"/>
<span class="text-muted" th:text="${project.description}"/>
</a>
<input class="id-class" type="hidden" th:value="${project.id}"/>
</div>
</div>
</body>
</html>

@ -0,0 +1,26 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<div class="row justify-content-center">
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
<a href="./projects" class="btn btn-light toolbar-button"><i class="fa fa-list-alt"></i>
Список</a>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
<a href="./dashboard" class="btn btn-light toolbar-button"><i class="fa fa-newspaper-o"
aria-hidden="true"></i> Панель
управления</a>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
<a href="./project?id=0" class="btn btn-light toolbar-button"><i class="fa fa-plus-circle"
aria-hidden="true"></i>
Добавить проект</a>
</div>
</div>
</body>
</html>

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<span th:fragment="paperStatus (paperStatus)" class="fa-stack fa-1x">
<th:block th:switch="${projectStatus.name()}">
<div th:case="'APPLICATION'">
<i class="fa fa-circle fa-stack-2x text-draft"></i>
</div>
<div th:case="'ON_COMPETITION'">
<i class="fa fa-circle fa-stack-2x text-review"></i>
</div>
<div th:case="'SUCCESSFUL_PASSAGE'">
<i class="fa fa-circle fa-stack-2x text-accepted"></i>
</div>
<div th:case="'IN_WORK'">
<i class="fa fa-circle fa-stack-2x text-primary"></i>
</div>
<div th:case="'COMPLETED'">
<i class="fa fa-circle fa-stack-2x text-success"></i>
</div>
<div th:case="'FAILED'">
<i class="fa fa-circle fa-stack-2x text-failed"></i>
</div>
</th:block>
<i class="fa fa-file-text-o fa-stack-1x fa-inverse"></i>
</span>
</body>
</html>

@ -0,0 +1,141 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default" xmlns:th="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/html">
<head>
</head>
<body>
<div class="container" layout:fragment="content">
<section id="paper">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading text-uppercase">Редактирование проекта</h2>
<div th:replace="projects/fragments/projectNavigationFragment"/>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<form id="project-form" method="post" th:action="@{'/projects/project?id='+ *{id == null ? '' : id} + ''}"
th:object="${projectDto}">
<div class="row">
<div class="col-md-6 col-sm-12">
<input type="hidden" name="id" th:field="*{id}"/>
<div class="form-group">
<label for="title">Название:</label>
<input class="form-control" id="title" type="text"
placeholder="Название проекта"
th:field="*{title}"/>
<p th:if="${#fields.hasErrors('title')}" th:errors="*{title}"
class="alert alert-danger">Incorrect title</p>
<p class="help-block text-danger"></p>
</div>
<div class="form-group">
<label for="status">Статус:</label>
<select class="form-control" th:field="*{status}" id="status">
<option th:each="status : ${allStatuses}" th:value="${status}"
th:text="${status.statusName}">Status
</option>
</select>
</div>
<div class="form-group">
<label for="description">Описание:</label>
<textarea class="form-control" rows="3" id="description"
th:field="*{description}"></textarea>
</div>
<div class="form-group">
<label for="createGrant">Добавить грант:</label>
<div th:if="*{grant} == null">
<input type="submit" id="createGrant" name="createGrant" class="btn btn-primary"
value="Добавить грант"/>
</div>
<input type = "hidden" th:field="*{grant.id}"/>
</div>
<div class="form-group">
<label for="repository">Ссылка на репозиторий:</label>
<input class="form-control" id="repository" type="text"
placeholder="http://"
th:field="*{repository}"/>
<p th:if="${#fields.hasErrors('repository')}" th:errors="*{repository}"
class="alert alert-danger">Incorrect repository link</p>
<p class="help-block text-danger"></p>
</div>
<div class="form-group">
<label>Дедлайны показателей:</label>
<div class="row">
<input type="hidden"/>
<div class="col-6">
<input type="date" class="form-control" name="deadline"/>
</div>
<div class="col-4">
<input class="form-control" type="text" placeholder="Описание"/>
</div>
<div class="col-2">
<a class="btn btn-danger float-right"><span
aria-hidden="true"><i class="fa fa-times"/></span>
</a>
</div>
</div>
<p th:if="${#fields.hasErrors('deadlines')}" th:errors="*{deadlines}"
class="alert alert-danger">Incorrect title</p>
</div>
<div class="form-group">
<input type="submit" id="addDeadline" name="addDeadline" class="btn btn-primary" value="Добавить
дедлайн"/>
</div>
<div class="form-group">
<label for="loader">Загрузить файл:</label>
<div id="loader">
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="col-lg-12">
<div class="form-group">
<button id="sendMessageButton" name="save" class="btn btn-success text-uppercase"
type="submit">
Сохранить
</button>
<button id="cancelButton" class="btn btn-default text-uppercase" href="/projects/projects">
Отмена
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script type="text/javascript" src="/js/file-loader.js"></script>
<script>
/*<![CDATA[*/
$(document).ready(function () {
new FileLoader({
div: "loader",
url: urlFileUpload,
maxSize: 2,
extensions: ["doc", "docx", "xls", "jpg", "png", "pdf", "txt"],
callback: function (response) {
showFeedbackMessage("Файл успешно загружен");
console.debug(response);
}
});
$('.selectpicker').selectpicker();
});
/*]]>*/
</script>
</div>
</body>
</html>

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default" xmlns:th="">
<head>
</head>
<body>
<div class="container" layout:fragment="content">
<form id="projects-form" method="post" th:action="@{'/projects/projects'}">
<input th:type="hidden" name="projectDeleteId" id="projectDeleteId"/>
<section id="projects">
<div class="container">
<div class="row" id="project-list">
<div class="col-lg-12 text-center">
<h2 class="section-heading text-uppercase">Проекты</h2>
<div th:replace="projects/fragments/projectNavigationFragment"/>
</div>
</div>
<div class="row">
<div class="col-md-9 col-sm-12">
<th:block th:each="project : ${projects}">
<div th:replace="projects/fragments/projectLineFragment :: projectLine(project=${project})"/>
</th:block>
</div>
<div class="col-md-3 col-sm-12">
</div>
</div>
</div>
</section>
</form>
</div>
</body>
</html>

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div class="container" layout:fragment="content">
<section id="services">
<div class="container">
<div class="col-lg-12 text-center">
<h2 class="section-heading text-uppercase">Работа со студентами</h2>
<div th:replace="students/fragments/taskNavigationFragment"/>
</div>
<hr/>
<div class="row justify-content-center" id="dashboard">
<div th:replace="students/fragments/taskDashboardFragment"/>
<!--<th:block th:each="task : ${tasks}">-->
<!--<div th:replace="students/fragments/taskDashboardFragment :: taskDashboard(task=${task})"/>-->
<!--</th:block>-->
</div>
</div>
</section>
</div>
</body>
</html>

@ -0,0 +1,24 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<div th:fragment="taskDashboard (task)" class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 dashboard-card">
<div class="row">
<div class="col-2">
<span th:replace="students/fragments/taskStatusFragment :: taskStatus(taskStatus=${task.status})"/>
<!--<span th:replace="students/fragments/taskStatusFragment"/>-->
</div>
<div class="col col-10 text-right">
<h7 class="service-heading" th:text="${task.title}"> title</h7>
<p class="text-muted" th:text="${task.status.statusName}"> status</p>
<!--<h7 class="service-heading" th:text="Title"> title</h7>-->
<!--<p class="text-muted" th:text="Type">type</p>-->
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,22 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<div th:fragment="taskLine (task)" class="row text-left task-row" style="background-color: white;">
<div class="col">
<span th:replace="students/fragments/taskStatusFragment :: taskStatus(taskStatus=${task.status})"/>
<a th:href="@{'task?id='+${task.id}}">
<span class="h6" th:text="${task.title}"></span>
<span class="text-muted" th:text="${task.tagsString}"/>
</a>
<input class="id-class" type="hidden" th:value="${task.id}"/>
<a class="remove-task pull-right d-none" th:href="@{'/students/delete/'+${task.id}}"
data-confirm="Удалить задачу?">
<i class="fa fa-trash" aria-hidden="true"></i>
</a>
</div>
</div>
</body>
</html>

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
</head>
<body>
<div class="row justify-content-center">
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
<a href="./tasks" class="btn btn-light toolbar-button"><i class="fa fa-list-alt"></i>
Список</a>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
<a href="./dashboard" class="btn btn-light toolbar-button"><i class="fa fa-newspaper-o"
aria-hidden="true"></i> Панель
управления</a>
</div>
<div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3">
<a href="./task?id=0" class="btn btn-light toolbar-button"><i class="fa fa-plus-circle"
aria-hidden="true"></i>
Добавить задачу</a>
</div>
</div>
</body>
</html>

@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
</head>
<body>
<span th:fragment="taskStatus (taskStatus)" class="fa-stack fa-1x">
<th:block th:switch="${taskStatus.name()}">
<!--<div th:case="'ATTENTION'">-->
<!--<i class="fa fa-circle fa-stack-2x text-warning"></i>-->
<!--</div>-->
<div th:case="'IN_WORK'">
<i class="fa fa-circle fa-stack-2x text-primary"></i>
</div>
<div th:case="'LOADED_FROM_KIAS'">
<i class="fa fa-circle fa-stack-2x text-review"></i>
</div>
<div th:case="'COMPLETED'">
<i class="fa fa-circle fa-stack-2x text-success"></i>
</div>
<div th:case="'FAILED'">
<i class="fa fa-circle fa-stack-2x text-failed"></i>
</div>
</th:block>
<i class="fa fa-check fa-stack-1x fa-inverse"></i>
</span>
</body>
</html>

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

Loading…
Cancel
Save