diff --git a/src/main/java/ru/ulstu/students/controller/Navigation.java b/src/main/java/ru/ulstu/students/controller/Navigation.java new file mode 100644 index 0000000..3804a8b --- /dev/null +++ b/src/main/java/ru/ulstu/students/controller/Navigation.java @@ -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; + } +} diff --git a/src/main/java/ru/ulstu/students/controller/TaskController.java b/src/main/java/ru/ulstu/students/controller/TaskController.java new file mode 100644 index 0000000..76b2f2b --- /dev/null +++ b/src/main/java/ru/ulstu/students/controller/TaskController.java @@ -0,0 +1,85 @@ +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.tags.model.Tag; +import springfox.documentation.annotations.ApiIgnore; +import ru.ulstu.students.service.TaskService; +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 grantService) { + this.taskService = grantService; + } + + @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", "Не может быть пустым"); + } + hasErrors(errors, TASK_PAGE); + taskService.save(taskDto); + return String.format(REDIRECT_TO, TASK_PAGE); + } + + @PostMapping(value = "/task", params = "addDeadline") + public String addDeadline(@Valid TaskDto taskDto, Errors errors) { + filterEmptyDeadlines(taskDto); + hasErrors(errors, TASK_PAGE); + taskDto.getDeadlines().add(new Deadline()); + return TASK_PAGE; + } + + @ModelAttribute("allStatuses") + public List getTaskStatuses() { + return taskService.getTaskStatuses(); + } + + @ModelAttribute("allTags") + public List getAllTags() { + return taskService.getTaskTags(); + } + + private void filterEmptyDeadlines(TaskDto taskDto) { + taskDto.setDeadlines(taskDto.getDeadlines().stream() + .filter(dto -> dto.getDate() != null || !isEmpty(dto.getDescription())) + .collect(Collectors.toList())); + } +} diff --git a/src/main/java/ru/ulstu/students/model/Task.java b/src/main/java/ru/ulstu/students/model/Task.java new file mode 100644 index 0000000..296ddcb --- /dev/null +++ b/src/main/java/ru/ulstu/students/model/Task.java @@ -0,0 +1,113 @@ +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.*; + +@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 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) + private Set tags = new HashSet<>(); + + 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 getDeadlines() { + return deadlines; + } + + public void setDeadlines(List 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 getTags() { + return tags; + } + + public void setTags(Set tags) { + this.tags = tags; + } +} diff --git a/src/main/java/ru/ulstu/students/model/TaskDto.java b/src/main/java/ru/ulstu/students/model/TaskDto.java new file mode 100644 index 0000000..62e73b4 --- /dev/null +++ b/src/main/java/ru/ulstu/students/model/TaskDto.java @@ -0,0 +1,147 @@ +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.TagDto; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static ru.ulstu.core.util.StreamApiUtils.convert; + +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 deadlines = new ArrayList<>(); + private Date createDate; + private Date updateDate; + private Set tagIds; + private Set 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 deadlines, + @JsonProperty("tagIds") Set tagIds, + @JsonProperty("tagIds") Set 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.tagIds = convert(task.getTags(), tag -> tag.getId()); + this.tags = convert(task.getTags(), TagDto::new); + } + + 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 getDeadlines() { + return deadlines; + } + + public void setDeadlines(List 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 getTagIds() { + return tagIds; + } + + public void setTagIds(Set tagIds) { + this.tagIds = tagIds; + } + + public Set getTags() { + return tags; + } + + public void setTags(Set tags) { + this.tags = tags; + } + + public String getTagsString() { + return StringUtils.abbreviate(tags + .stream() + .map(tag -> tag.getTagName()) + .collect(Collectors.joining(", ")), MAX_TAGS_LENGTH ); + } +} diff --git a/src/main/java/ru/ulstu/students/repository/TaskRepository.java b/src/main/java/ru/ulstu/students/repository/TaskRepository.java new file mode 100644 index 0000000..6f48d1f --- /dev/null +++ b/src/main/java/ru/ulstu/students/repository/TaskRepository.java @@ -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 { +} diff --git a/src/main/java/ru/ulstu/students/service/TaskService.java b/src/main/java/ru/ulstu/students/service/TaskService.java new file mode 100644 index 0000000..c3ac558 --- /dev/null +++ b/src/main/java/ru/ulstu/students/service/TaskService.java @@ -0,0 +1,98 @@ +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.model.Tag; +import ru.ulstu.tags.service.TagService; + +import java.io.IOException; +import java.util.*; + +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 findAll() { + return taskRepository.findAll(); + } + + public List findAllDto() { + List 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(); + if (taskDto.getTagIds() != null && !taskDto.getTagIds().isEmpty()) { + taskDto.getTagIds().forEach(tagIds -> task.getTags().add(tagService.findById(tagIds))); + } + 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 getTaskStatuses() { + return Arrays.asList(Task.TaskStatus.values()); + } + public List getTaskTags() { + return tagService.findAll(); + } +} diff --git a/src/main/java/ru/ulstu/tags/model/Tag.java b/src/main/java/ru/ulstu/tags/model/Tag.java new file mode 100644 index 0000000..78a6274 --- /dev/null +++ b/src/main/java/ru/ulstu/tags/model/Tag.java @@ -0,0 +1,23 @@ +package ru.ulstu.tags.model; + +import org.hibernate.validator.constraints.NotBlank; +import ru.ulstu.core.model.BaseEntity; + +import javax.persistence.Entity; +import javax.persistence.Table; + +@Entity +@Table(name = "tag") +public class Tag extends BaseEntity { + + @NotBlank + private String tagName; + + public String getTagName() { + return tagName; + } + + public void setTagName(String tagName) { + this.tagName = tagName; + } +} diff --git a/src/main/java/ru/ulstu/tags/model/TagDto.java b/src/main/java/ru/ulstu/tags/model/TagDto.java new file mode 100644 index 0000000..80ce085 --- /dev/null +++ b/src/main/java/ru/ulstu/tags/model/TagDto.java @@ -0,0 +1,43 @@ +package ru.ulstu.tags.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.hibernate.validator.constraints.NotEmpty; + +import javax.validation.constraints.Size; + +public class TagDto { + + private Integer id; + @NotEmpty + @Size(max = 50) + private String tagName; + + @JsonCreator + public TagDto(@JsonProperty("id") Integer id, + @JsonProperty("tagName") String tagName) { + this.id = id; + this.tagName = tagName; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTagName() { + return tagName; + } + + public void setTagName(String tagName) { + this.tagName = tagName; + } + + public TagDto(Tag tag) { + this.id = tag.getId(); + this.tagName = tag.getTagName(); + } +} diff --git a/src/main/java/ru/ulstu/tags/repository/TagRepository.java b/src/main/java/ru/ulstu/tags/repository/TagRepository.java new file mode 100644 index 0000000..c0a014e --- /dev/null +++ b/src/main/java/ru/ulstu/tags/repository/TagRepository.java @@ -0,0 +1,8 @@ +package ru.ulstu.tags.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.ulstu.tags.model.Tag; + +public interface TagRepository extends JpaRepository { + +} diff --git a/src/main/java/ru/ulstu/tags/service/TagService.java b/src/main/java/ru/ulstu/tags/service/TagService.java new file mode 100644 index 0000000..45c10f2 --- /dev/null +++ b/src/main/java/ru/ulstu/tags/service/TagService.java @@ -0,0 +1,46 @@ +package ru.ulstu.tags.service; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import ru.ulstu.tags.model.Tag; +import ru.ulstu.tags.model.TagDto; +import ru.ulstu.tags.repository.TagRepository; + +import java.util.List; + +import static ru.ulstu.core.util.StreamApiUtils.convert; + +@Service +public class TagService { + + private final TagRepository tagRepository; + + + public TagService(TagRepository tagRepository) { + + this.tagRepository = tagRepository; + } + + public List findAll() { + return tagRepository.findAll(); + } + +// public List findAllDto() { +// List tag = convert(findAll(), TagDto::new); +// tags.forEach(tagDto -> tagDto.setTitle(StringUtils.abbreviate(tagDto.getTitle(), MAX_DISPLAY_SIZE))); +// return tags; +// } +// +// public TagDto findOneDto(Integer id) { +// return new TagDto(tagRepository.findOne(id)); +// } + + + public List findByIds(List ids) { + return tagRepository.findAll(ids); + } + public Tag findById(Integer id) { + return tagRepository.findOne(id); + } + +} diff --git a/src/main/resources/templates/students/fragments/taskDashboardFragment.html b/src/main/resources/templates/students/fragments/taskDashboardFragment.html index 0daea58..3779ef8 100644 --- a/src/main/resources/templates/students/fragments/taskDashboardFragment.html +++ b/src/main/resources/templates/students/fragments/taskDashboardFragment.html @@ -7,14 +7,14 @@
- - + +
- - - title -

type

+ title +

status

+ +
diff --git a/src/main/resources/templates/students/fragments/taskLineFragment.html b/src/main/resources/templates/students/fragments/taskLineFragment.html index 79ad5d7..44c2d03 100644 --- a/src/main/resources/templates/students/fragments/taskLineFragment.html +++ b/src/main/resources/templates/students/fragments/taskLineFragment.html @@ -4,15 +4,15 @@ -
+
- - - Первая хадач - Курсовая работа + + + + - - + diff --git a/src/main/resources/templates/students/fragments/taskStatusFragment.html b/src/main/resources/templates/students/fragments/taskStatusFragment.html index 8f3d800..ea9a3e9 100644 --- a/src/main/resources/templates/students/fragments/taskStatusFragment.html +++ b/src/main/resources/templates/students/fragments/taskStatusFragment.html @@ -5,18 +5,14 @@ - - -
- -
-
- -
-
+ + + + +
-
+
@@ -25,12 +21,6 @@
-
- -
-
- -
diff --git a/src/main/resources/templates/students/task.html b/src/main/resources/templates/students/task.html index 533c8f6..98c4147 100644 --- a/src/main/resources/templates/students/task.html +++ b/src/main/resources/templates/students/task.html @@ -21,47 +21,60 @@
-
+
- +
- + +

Incorrect title

- +
- +
-
+
-
- +
+
- +
- +
-
+

Incorrect title

Дата создания:
- - + text
@@ -98,8 +111,8 @@
Дата изменения:
- - + text
diff --git a/src/main/resources/templates/students/tasks.html b/src/main/resources/templates/students/tasks.html index 076f7ba..37ade14 100644 --- a/src/main/resources/templates/students/tasks.html +++ b/src/main/resources/templates/students/tasks.html @@ -20,8 +20,8 @@
- -
+ +
@@ -37,16 +37,6 @@