Merge branch 'dev' of https://gitlab.com/romanov73/ng-tracker into dev
commit
92a0674b95
@ -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,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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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>
|
@ -1,24 +1,65 @@
|
|||||||
.bootstrap-tagsinput{
|
.tags-container {
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: .375rem .75rem;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bootstrap-tagsinput .label{
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
display: inline;
|
.tag-name span[data-role="remove"]:after {
|
||||||
padding: .2em .6em .3em;
|
content: "x";
|
||||||
font-size: 75%;
|
padding: 0px 2px;
|
||||||
font-weight: 700;
|
|
||||||
line-height: 2.5;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: baseline;
|
|
||||||
border-radius: .25em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bootstrap-tagsinput .label-info{
|
.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;
|
||||||
|
|
||||||
background-color: orange;
|
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,41 @@
|
|||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
||||||
$('.data-href-js').click( function() {
|
$(".conference-row").mouseenter(function (event) {
|
||||||
window.location = $(this).attr('data-href');
|
var conferenceRow = $(event.target).closest(".conference-row");
|
||||||
});
|
$(conferenceRow).css("background-color", "#f8f9fa");
|
||||||
|
$(conferenceRow).find(".remove-conference").removeClass("d-none");
|
||||||
|
|
||||||
$('.circle').parent().click( function() {
|
|
||||||
$(this).children('.circle').toggleClass('circle-active');
|
|
||||||
});
|
});
|
||||||
|
$(".conference-row").mouseleave(function (event) {
|
||||||
$('.checkbox-js').parent().click( function() {
|
var conferenceRow = $(event.target).closest(".conference-row");
|
||||||
$(this).children('.checkbox').toggleClass('selected');
|
$(conferenceRow).css("background-color", "white");
|
||||||
|
$(conferenceRow).closest(".conference-row").find(".remove-conference").addClass("d-none");
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#select-all-js').click( function() {
|
$('a[data-confirm]').click(function(ev) {
|
||||||
$(this).toggleClass('selected');
|
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">×</span></button>\n' +
|
||||||
|
' </div>\n' +
|
||||||
|
|
||||||
var childNodes = $('.conference-item .form-check .checkbox')
|
' <div class="modal-footer">\n' +
|
||||||
.each(function(i, elem) {
|
' <a class="btn btn-primary" id="dataConfirmOK">Да</a>'+
|
||||||
if ($(this).hasClass('selected') && !$('#select-all-js').hasClass('selected')) {
|
' <button class="btn primary" data-dismiss="modal" aria-hidden="true">Нет</button>'+
|
||||||
$(this).toggleClass('selected');
|
' </div>\n' +
|
||||||
} else if (!$(this).hasClass('selected') && $('#select-all-js').hasClass('selected')){
|
' </div>\n' +
|
||||||
$(this).toggleClass('selected');
|
' </div>\n' +
|
||||||
}
|
' </div>');
|
||||||
});
|
}
|
||||||
|
$('#dataConfirmModal').find('#myModalLabel').text($(this).attr('data-confirm'));
|
||||||
|
$('#dataConfirmOK').attr('href', href);
|
||||||
|
$('#dataConfirmModal').modal({show:true});
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue