From bd975c53f338cdd2d58d5179b9270b4c98d3cea9 Mon Sep 17 00:00:00 2001 From: ASH Date: Mon, 11 Mar 2019 22:46:51 +0400 Subject: [PATCH 01/45] #71 adding pages and layout --- .../ulstu/configuration/MvcConfiguration.java | 1 + src/main/resources/public/css/tasks.css | 24 +++++ src/main/resources/public/js/tasks.js | 0 src/main/resources/templates/index.html | 2 +- .../templates/students/dashboard.html | 24 +++++ .../fragments/taskNavigationFragment.html | 25 +++++ .../resources/templates/students/task.html | 91 +++++++++++++++++++ .../resources/templates/students/tasks.html | 36 ++++++++ 8 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/public/css/tasks.css create mode 100644 src/main/resources/public/js/tasks.js create mode 100644 src/main/resources/templates/students/dashboard.html create mode 100644 src/main/resources/templates/students/fragments/taskNavigationFragment.html create mode 100644 src/main/resources/templates/students/task.html create mode 100644 src/main/resources/templates/students/tasks.html diff --git a/src/main/java/ru/ulstu/configuration/MvcConfiguration.java b/src/main/java/ru/ulstu/configuration/MvcConfiguration.java index 3e8d66f..81761d6 100644 --- a/src/main/java/ru/ulstu/configuration/MvcConfiguration.java +++ b/src/main/java/ru/ulstu/configuration/MvcConfiguration.java @@ -14,6 +14,7 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { 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"); } diff --git a/src/main/resources/public/css/tasks.css b/src/main/resources/public/css/tasks.css new file mode 100644 index 0000000..3b6f671 --- /dev/null +++ b/src/main/resources/public/css/tasks.css @@ -0,0 +1,24 @@ +.bootstrap-tagsinput{ + + width: 100%; + padding: .375rem .75rem; +} + +.bootstrap-tagsinput .label{ + + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + 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{ + + background-color: orange; +} \ No newline at end of file diff --git a/src/main/resources/public/js/tasks.js b/src/main/resources/public/js/tasks.js new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 40a1281..2d86945 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -88,7 +88,7 @@
- +
diff --git a/src/main/resources/templates/students/dashboard.html b/src/main/resources/templates/students/dashboard.html new file mode 100644 index 0000000..d9f6e8a --- /dev/null +++ b/src/main/resources/templates/students/dashboard.html @@ -0,0 +1,24 @@ + + + + + +
+
+
+
+

Работа со студентами

+
+
+
+ + + +
+
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/students/fragments/taskNavigationFragment.html b/src/main/resources/templates/students/fragments/taskNavigationFragment.html new file mode 100644 index 0000000..cf8a4cf --- /dev/null +++ b/src/main/resources/templates/students/fragments/taskNavigationFragment.html @@ -0,0 +1,25 @@ + + + + + +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/students/task.html b/src/main/resources/templates/students/task.html new file mode 100644 index 0000000..b348078 --- /dev/null +++ b/src/main/resources/templates/students/task.html @@ -0,0 +1,91 @@ + + + + + + + + +
+ +
+
+
+
+

Редактирование задачи

+
+
+
+
+
+
+
+
+ +
+ + +

+
+ +
+ + +
+
+ + +
+ +
+ + +
+ + +
+ +
+ +
+ +
+
+ +
+
+ + +
+
+
+
+ +
+ +
+
+ + +
+
+
+ +
+
+
+
+ +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/students/tasks.html b/src/main/resources/templates/students/tasks.html new file mode 100644 index 0000000..5f370a0 --- /dev/null +++ b/src/main/resources/templates/students/tasks.html @@ -0,0 +1,36 @@ + + + + + + +
+
+ +
+
+
+
+

Работа со студентами

+
+
+
+
+
+ + + +
+
+
+
+
+
+ +
+ + +
+ + \ No newline at end of file From a236fc50bc34047193c735fa03c8cb78ef2197d5 Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Sat, 16 Mar 2019 14:39:56 +0400 Subject: [PATCH 02/45] #53 added datatables lib support --- .../templates/conferences/conferences.html | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/main/resources/templates/conferences/conferences.html b/src/main/resources/templates/conferences/conferences.html index ab9fd31..d4c171b 100644 --- a/src/main/resources/templates/conferences/conferences.html +++ b/src/main/resources/templates/conferences/conferences.html @@ -3,18 +3,56 @@ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="default"> + + - + +
+
+
+
+

Редактирование конференции

+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + +
Column 1Column 2
Row 1 Data 1Row 1 Data 2
Row 2 Data 1Row 2 Data 2
+
+
+
+
+
+ +
\ No newline at end of file From 6296b661a9dc620a55cee520ee89aadf21b013ef Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Sat, 16 Mar 2019 14:44:34 +0400 Subject: [PATCH 03/45] #53 added conference js file --- src/main/resources/public/js/conference.js | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/main/resources/public/js/conference.js diff --git a/src/main/resources/public/js/conference.js b/src/main/resources/public/js/conference.js new file mode 100644 index 0000000..e21cb7a --- /dev/null +++ b/src/main/resources/public/js/conference.js @@ -0,0 +1,3 @@ +$(document).ready(function () { + $('#table_id').dataTable(); +}); From 7b601c744fb7b9802c3e053c7b0f5de124a117b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=9C?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F?= Date: Mon, 18 Mar 2019 11:07:30 +0400 Subject: [PATCH 04/45] #13 change model, schema --- src/main/java/ru/ulstu/paper/model/Paper.java | 38 ++++++------------- .../java/ru/ulstu/paper/model/PaperDto.java | 6 +-- .../ru/ulstu/paper/service/PaperService.java | 30 ++++++--------- .../db/changelog-20190318_000000-schema.xml | 23 +++++++++++ src/main/resources/db/changelog-master.xml | 1 + 5 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 src/main/resources/db/changelog-20190318_000000-schema.xml diff --git a/src/main/java/ru/ulstu/paper/model/Paper.java b/src/main/java/ru/ulstu/paper/model/Paper.java index c09fd28..f98b54b 100644 --- a/src/main/java/ru/ulstu/paper/model/Paper.java +++ b/src/main/java/ru/ulstu/paper/model/Paper.java @@ -9,26 +9,8 @@ import ru.ulstu.deadline.model.Deadline; import ru.ulstu.file.model.FileData; import ru.ulstu.user.model.User; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.OrderBy; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import javax.persistence.*; +import java.util.*; @Entity public class Paper extends BaseEntity implements UserContainer { @@ -77,9 +59,11 @@ public class Paper extends BaseEntity implements UserContainer { private Boolean locked = false; - @ManyToOne - @JoinColumn(name = "file_id") - private FileData fileData; + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "paper_id", unique = true) + @Fetch(FetchMode.SUBSELECT) + private List files = new ArrayList<>(); @ManyToMany(fetch = FetchType.EAGER) private Set authors = new HashSet<>(); @@ -132,12 +116,12 @@ public class Paper extends BaseEntity implements UserContainer { this.locked = locked; } - public FileData getFileData() { - return fileData; + public List getFiles() { + return files; } - public void setFileData(FileData fileData) { - this.fileData = fileData; + public void setFiles(List files) { + this.files = files; } public String getTitle() { diff --git a/src/main/java/ru/ulstu/paper/model/PaperDto.java b/src/main/java/ru/ulstu/paper/model/PaperDto.java index 545b432..f870dc3 100644 --- a/src/main/java/ru/ulstu/paper/model/PaperDto.java +++ b/src/main/java/ru/ulstu/paper/model/PaperDto.java @@ -79,9 +79,9 @@ public class PaperDto { this.comment = paper.getComment(); this.locked = paper.getLocked(); this.tmpFileName = null; - this.fileId = paper.getFileData() == null ? null : paper.getFileData().getId(); - this.fileName = paper.getFileData() == null ? null : paper.getFileData().getName(); - this.fileCreateDate = paper.getFileData() == null ? null : paper.getFileData().getCreateDate(); +// this.fileId = paper.getFileData() == null ? null : paper.getFileData().getId(); +// this.fileName = paper.getFileData() == null ? null : paper.getFileData().getName(); +// this.fileCreateDate = paper.getFileData() == null ? null : paper.getFileData().getCreateDate(); this.authorIds = convert(paper.getAuthors(), user -> user.getId()); this.authors = convert(paper.getAuthors(), UserDto::new); } diff --git a/src/main/java/ru/ulstu/paper/service/PaperService.java b/src/main/java/ru/ulstu/paper/service/PaperService.java index 9df8be2..39c2ace 100644 --- a/src/main/java/ru/ulstu/paper/service/PaperService.java +++ b/src/main/java/ru/ulstu/paper/service/PaperService.java @@ -14,20 +14,12 @@ import ru.ulstu.user.model.User; import ru.ulstu.user.service.UserService; import java.io.IOException; -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import static org.springframework.util.ObjectUtils.isEmpty; import static ru.ulstu.core.util.StreamApiUtils.convert; -import static ru.ulstu.paper.model.Paper.PaperStatus.ATTENTION; -import static ru.ulstu.paper.model.Paper.PaperStatus.COMPLETED; -import static ru.ulstu.paper.model.Paper.PaperStatus.DRAFT; -import static ru.ulstu.paper.model.Paper.PaperStatus.FAILED; -import static ru.ulstu.paper.model.Paper.PaperStatus.ON_PREPARATION; +import static ru.ulstu.paper.model.Paper.PaperStatus.*; @Service public class PaperService { @@ -88,9 +80,9 @@ public class PaperService { paper.setTitle(paperDto.getTitle()); paper.setUpdateDate(new Date()); paper.setDeadlines(deadlineService.saveOrCreate(paperDto.getDeadlines())); - if (paperDto.getTmpFileName() != null) { - paper.setFileData(fileService.createFileFromTmp(paperDto.getTmpFileName())); - } +// if (paperDto.getTmpFileName() != null) { +// paper.setFileData(fileService.createFileFromTmp(paperDto.getTmpFileName())); +// } paper.getAuthors().clear(); if (paperDto.getAuthorIds() != null && !paperDto.getAuthorIds().isEmpty()) { paperDto.getAuthorIds().forEach(authorIds -> paper.getAuthors().add(userService.findById(authorIds))); @@ -103,9 +95,9 @@ public class PaperService { Paper paper = paperRepository.findOne(paperDto.getId()); Paper.PaperStatus oldStatus = paper.getStatus(); Set oldAuthors = new HashSet<>(paper.getAuthors()); - if (paperDto.getTmpFileName() != null && paper.getFileData() != null) { - fileService.deleteFile(paper.getFileData()); - } +// if (paperDto.getTmpFileName() != null && paper.getFileData() != null) { +// fileService.deleteFile(paper.getFileData()); +// } paperRepository.save(copyFromDto(paper, paperDto)); paper.getAuthors().forEach(author -> { @@ -124,9 +116,9 @@ public class PaperService { @Transactional public void delete(Integer paperId) throws IOException { Paper paper = paperRepository.findOne(paperId); - if (paper.getFileData() != null) { - fileService.deleteFile(paper.getFileData()); - } +// if (paper.getFileData() != null) { +// fileService.deleteFile(paper.getFileData()); +// } paperRepository.delete(paper); } diff --git a/src/main/resources/db/changelog-20190318_000000-schema.xml b/src/main/resources/db/changelog-20190318_000000-schema.xml new file mode 100644 index 0000000..d1966b4 --- /dev/null +++ b/src/main/resources/db/changelog-20190318_000000-schema.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog-master.xml b/src/main/resources/db/changelog-master.xml index b8654ae..dcba122 100644 --- a/src/main/resources/db/changelog-master.xml +++ b/src/main/resources/db/changelog-master.xml @@ -18,5 +18,6 @@ + \ No newline at end of file From 0764d961fac6aff165f262f534ecb05d5012e6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=9C?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F?= Date: Mon, 18 Mar 2019 13:00:34 +0400 Subject: [PATCH 05/45] #13 add fileDataDto --- .../java/ru/ulstu/file/model/FileDataDto.java | 102 ++++++++++++++++++ .../ru/ulstu/file/service/FileService.java | 32 ++++++ .../java/ru/ulstu/paper/model/PaperDto.java | 54 +++------- .../ru/ulstu/paper/service/PaperService.java | 10 +- src/main/resources/public/js/core.js | 2 +- 5 files changed, 149 insertions(+), 51 deletions(-) create mode 100644 src/main/java/ru/ulstu/file/model/FileDataDto.java diff --git a/src/main/java/ru/ulstu/file/model/FileDataDto.java b/src/main/java/ru/ulstu/file/model/FileDataDto.java new file mode 100644 index 0000000..d59f75b --- /dev/null +++ b/src/main/java/ru/ulstu/file/model/FileDataDto.java @@ -0,0 +1,102 @@ +package ru.ulstu.file.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Date; + +public class FileDataDto { + private Integer id; + private String name; + private long size; + + private Date createDate; + private byte[] data; + private String fileName; + private String tmpFileName; + + public FileDataDto() { + } + + @JsonCreator + public FileDataDto(@JsonProperty("id") Integer id, + @JsonProperty("name") String name, + @JsonProperty("size") long size, + @JsonProperty("createDate") Date createDate, + @JsonProperty("data") byte[] data, + @JsonProperty("fileName") String fileName, + @JsonProperty("tmpFileName") String tmpFileName) { + this.id = id; + this.name = name; + this.size = size; + this.createDate = createDate; + this.data = data; + this.fileName = fileName; + this.tmpFileName = tmpFileName; + } + + public FileDataDto(FileData fileData) { + this.id = fileData.getId(); + this.name = fileData.getName(); + this.size = fileData.getSize(); + this.createDate = fileData.getCreateDate(); + this.data = fileData.getData(); + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getTmpFileName() { + return tmpFileName; + } + + public void setTmpFileName(String tmpFileName) { + this.tmpFileName = tmpFileName; + } + +} diff --git a/src/main/java/ru/ulstu/file/service/FileService.java b/src/main/java/ru/ulstu/file/service/FileService.java index 2f1fb6d..b15c342 100644 --- a/src/main/java/ru/ulstu/file/service/FileService.java +++ b/src/main/java/ru/ulstu/file/service/FileService.java @@ -1,8 +1,10 @@ package ru.ulstu.file.service; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import ru.ulstu.file.model.FileData; +import ru.ulstu.file.model.FileDataDto; import ru.ulstu.file.repostory.FileRepository; import java.io.IOException; @@ -10,6 +12,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; import static java.nio.charset.StandardCharsets.UTF_8; @@ -78,4 +82,32 @@ public class FileService { public void deleteFile(FileData fileData) { fileRepository.delete(fileData); } + + public List saveOrCreate(List files) { + return files.stream().map(fileDataDto -> { + return fileDataDto.getId() != null ? update(fileDataDto) : create(fileDataDto); + }).collect(Collectors.toList()); + } + + @Transactional + public FileData update(FileDataDto fileDataDto) { + FileData file = fileRepository.findOne(fileDataDto.getId()); + fileRepository.save(copyFromDto(file, fileDataDto)); + return file; + } + + @Transactional + public FileData create(FileDataDto fileDataDto) { + FileData newFile = copyFromDto(new FileData(), fileDataDto); + newFile = fileRepository.save(newFile); + return newFile; + } + + private FileData copyFromDto(FileData fileData, FileDataDto fileDataDto) { + fileData.setCreateDate(fileDataDto.getCreateDate()); + fileData.setData(fileDataDto.getData()); + fileData.setName(fileDataDto.getName()); + fileData.setSize(fileDataDto.getSize()); + return fileData; + } } diff --git a/src/main/java/ru/ulstu/paper/model/PaperDto.java b/src/main/java/ru/ulstu/paper/model/PaperDto.java index f870dc3..96d7654 100644 --- a/src/main/java/ru/ulstu/paper/model/PaperDto.java +++ b/src/main/java/ru/ulstu/paper/model/PaperDto.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.StringUtils; import org.hibernate.validator.constraints.NotEmpty; import ru.ulstu.deadline.model.DeadlineDto; +import ru.ulstu.file.model.FileDataDto; import ru.ulstu.user.model.UserDto; import javax.validation.constraints.Size; @@ -30,10 +31,9 @@ public class PaperDto { private List deadlines = new ArrayList<>(); private String comment; private Boolean locked; - private String tmpFileName; - private Integer fileId; - private String fileName; - private Date fileCreateDate; + + private List files = new ArrayList<>(); + private Set authorIds; private Set authors; private Integer filterAuthorId; @@ -51,7 +51,7 @@ public class PaperDto { @JsonProperty("deadlines") List deadlines, @JsonProperty("comment") String comment, @JsonProperty("locked") Boolean locked, - @JsonProperty("tmpFileName") String tmpFileName, + @JsonProperty("files") List files, @JsonProperty("authorIds") Set authorIds, @JsonProperty("authors") Set authors) { this.id = id; @@ -62,10 +62,7 @@ public class PaperDto { this.deadlines = deadlines; this.comment = comment; this.locked = locked; - this.tmpFileName = tmpFileName; - this.fileId = null; - this.fileName = null; - this.fileCreateDate = null; + this.files = files; this.authors = authors; } @@ -78,10 +75,9 @@ public class PaperDto { this.deadlines = convert(paper.getDeadlines(), DeadlineDto::new); this.comment = paper.getComment(); this.locked = paper.getLocked(); - this.tmpFileName = null; -// this.fileId = paper.getFileData() == null ? null : paper.getFileData().getId(); -// this.fileName = paper.getFileData() == null ? null : paper.getFileData().getName(); -// this.fileCreateDate = paper.getFileData() == null ? null : paper.getFileData().getCreateDate(); + + this.files = convert(paper.getFiles(), FileDataDto::new); + this.authorIds = convert(paper.getAuthors(), user -> user.getId()); this.authors = convert(paper.getAuthors(), UserDto::new); } @@ -150,36 +146,12 @@ public class PaperDto { this.locked = locked; } - public String getTmpFileName() { - return tmpFileName; - } - - public void setTmpFileName(String tmpFileName) { - this.tmpFileName = tmpFileName; - } - - public Integer getFileId() { - return fileId; - } - - public void setFileId(Integer fileId) { - this.fileId = fileId; - } - - public String getFileName() { - return fileName; - } - - public void setFileName(String fileName) { - this.fileName = fileName; - } - - public Date getFileCreateDate() { - return fileCreateDate; + public List getFiles() { + return files; } - public void setFileCreateDate(Date fileCreateDate) { - this.fileCreateDate = fileCreateDate; + public void setFiles(List files) { + this.files = files; } public Set getAuthors() { diff --git a/src/main/java/ru/ulstu/paper/service/PaperService.java b/src/main/java/ru/ulstu/paper/service/PaperService.java index 39c2ace..3f4028d 100644 --- a/src/main/java/ru/ulstu/paper/service/PaperService.java +++ b/src/main/java/ru/ulstu/paper/service/PaperService.java @@ -80,9 +80,7 @@ public class PaperService { paper.setTitle(paperDto.getTitle()); paper.setUpdateDate(new Date()); paper.setDeadlines(deadlineService.saveOrCreate(paperDto.getDeadlines())); -// if (paperDto.getTmpFileName() != null) { -// paper.setFileData(fileService.createFileFromTmp(paperDto.getTmpFileName())); -// } + paper.setFiles(fileService.saveOrCreate(paperDto.getFiles())); paper.getAuthors().clear(); if (paperDto.getAuthorIds() != null && !paperDto.getAuthorIds().isEmpty()) { paperDto.getAuthorIds().forEach(authorIds -> paper.getAuthors().add(userService.findById(authorIds))); @@ -95,9 +93,6 @@ public class PaperService { Paper paper = paperRepository.findOne(paperDto.getId()); Paper.PaperStatus oldStatus = paper.getStatus(); Set oldAuthors = new HashSet<>(paper.getAuthors()); -// if (paperDto.getTmpFileName() != null && paper.getFileData() != null) { -// fileService.deleteFile(paper.getFileData()); -// } paperRepository.save(copyFromDto(paper, paperDto)); paper.getAuthors().forEach(author -> { @@ -116,9 +111,6 @@ public class PaperService { @Transactional public void delete(Integer paperId) throws IOException { Paper paper = paperRepository.findOne(paperId); -// if (paper.getFileData() != null) { -// fileService.deleteFile(paper.getFileData()); -// } paperRepository.delete(paper); } diff --git a/src/main/resources/public/js/core.js b/src/main/resources/public/js/core.js index 5c9241c..31642f4 100644 --- a/src/main/resources/public/js/core.js +++ b/src/main/resources/public/js/core.js @@ -1,7 +1,7 @@ // from config.js /* global urlVersions */ -var urlFileUpload = "/api/1.0/papers/uploadTmpFile"; +var urlFileUpload = "/api/1.0/files/uploadTmpFile"; /* exported MessageTypesEnum */ var MessageTypesEnum = { From cb394edf907e66f35d70ce2103faae2e09b0f7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=9C?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F?= Date: Mon, 18 Mar 2019 16:02:55 +0400 Subject: [PATCH 06/45] #13 file list on paper page --- .../java/ru/ulstu/file/model/FileDataDto.java | 11 +++++++++- .../ru/ulstu/file/service/FileService.java | 6 +++++ .../ru/ulstu/paper/service/PaperService.java | 8 ++++++- .../db/changelog-20190318_000000-schema.xml | 11 ---------- .../resources/templates/papers/paper.html | 22 +++++++++++++++++++ 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/main/java/ru/ulstu/file/model/FileDataDto.java b/src/main/java/ru/ulstu/file/model/FileDataDto.java index d59f75b..fda3e81 100644 --- a/src/main/java/ru/ulstu/file/model/FileDataDto.java +++ b/src/main/java/ru/ulstu/file/model/FileDataDto.java @@ -9,12 +9,13 @@ public class FileDataDto { private Integer id; private String name; private long size; - private Date createDate; private byte[] data; private String fileName; private String tmpFileName; + private boolean deleteFlag; + public FileDataDto() { } @@ -99,4 +100,12 @@ public class FileDataDto { this.tmpFileName = tmpFileName; } + public boolean isDeleteFlag() { + return deleteFlag; + } + + public void setDeleteFlag(boolean deleteFlag) { + this.deleteFlag = deleteFlag; + } + } diff --git a/src/main/java/ru/ulstu/file/service/FileService.java b/src/main/java/ru/ulstu/file/service/FileService.java index b15c342..3f3dbca 100644 --- a/src/main/java/ru/ulstu/file/service/FileService.java +++ b/src/main/java/ru/ulstu/file/service/FileService.java @@ -110,4 +110,10 @@ public class FileService { fileData.setSize(fileDataDto.getSize()); return fileData; } + + @Transactional + public void delete(Integer fileId) throws IOException { + FileData file = fileRepository.findOne(fileId); + fileRepository.delete(file); + } } diff --git a/src/main/java/ru/ulstu/paper/service/PaperService.java b/src/main/java/ru/ulstu/paper/service/PaperService.java index 3f4028d..851a21b 100644 --- a/src/main/java/ru/ulstu/paper/service/PaperService.java +++ b/src/main/java/ru/ulstu/paper/service/PaperService.java @@ -5,6 +5,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.service.DeadlineService; +import ru.ulstu.file.model.FileDataDto; import ru.ulstu.file.service.FileService; import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.PaperDto; @@ -80,7 +81,7 @@ public class PaperService { paper.setTitle(paperDto.getTitle()); paper.setUpdateDate(new Date()); paper.setDeadlines(deadlineService.saveOrCreate(paperDto.getDeadlines())); - paper.setFiles(fileService.saveOrCreate(paperDto.getFiles())); + paper.setFiles(fileService.saveOrCreate(paperDto.getFiles().stream().filter(f -> f.isDeleteFlag() == false).collect(Collectors.toList()))); paper.getAuthors().clear(); if (paperDto.getAuthorIds() != null && !paperDto.getAuthorIds().isEmpty()) { paperDto.getAuthorIds().forEach(authorIds -> paper.getAuthors().add(userService.findById(authorIds))); @@ -93,6 +94,11 @@ public class PaperService { Paper paper = paperRepository.findOne(paperDto.getId()); Paper.PaperStatus oldStatus = paper.getStatus(); Set oldAuthors = new HashSet<>(paper.getAuthors()); + + for (FileDataDto file : paperDto.getFiles().stream().filter(f -> f.isDeleteFlag() == true && f.getId() != null).collect(Collectors.toList())) { + fileService.delete(file.getId()); + } + paperRepository.save(copyFromDto(paper, paperDto)); paper.getAuthors().forEach(author -> { diff --git a/src/main/resources/db/changelog-20190318_000000-schema.xml b/src/main/resources/db/changelog-20190318_000000-schema.xml index d1966b4..a4f7ec1 100644 --- a/src/main/resources/db/changelog-20190318_000000-schema.xml +++ b/src/main/resources/db/changelog-20190318_000000-schema.xml @@ -8,16 +8,5 @@ - - - - - - - diff --git a/src/main/resources/templates/papers/paper.html b/src/main/resources/templates/papers/paper.html index a5ff6b5..0f1a467 100644 --- a/src/main/resources/templates/papers/paper.html +++ b/src/main/resources/templates/papers/paper.html @@ -91,6 +91,28 @@

Incorrect title

+ +
+ + +
+ + + +
+ + + +
+
+
+
+
+
+
+
From 4fb8061653b47634219161aedd3be7fa139d4a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=9C?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F?= Date: Mon, 18 Mar 2019 18:39:15 +0400 Subject: [PATCH 07/45] #13 addNewFile js function --- .../java/ru/ulstu/file/FileController.java | 11 +--- .../ru/ulstu/file/service/FileService.java | 1 + .../resources/templates/papers/paper.html | 63 ++++++++++++++++++- 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/main/java/ru/ulstu/file/FileController.java b/src/main/java/ru/ulstu/file/FileController.java index e60626b..f68b820 100644 --- a/src/main/java/ru/ulstu/file/FileController.java +++ b/src/main/java/ru/ulstu/file/FileController.java @@ -3,12 +3,7 @@ package ru.ulstu.file; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -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 org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import ru.ulstu.configuration.Constants; import ru.ulstu.core.model.response.Response; @@ -51,7 +46,7 @@ public class FileController { } @PostMapping("/uploadTmpFile") - public Response upload(@RequestParam("file") MultipartFile multipartFile) throws IOException { - return new Response(fileService.uploadToTmpDir(multipartFile)); + public Response upload(@RequestParam("file") MultipartFile multipartFile) throws IOException { + return new Response(new Object[]{fileService.uploadToTmpDir(multipartFile), multipartFile.getOriginalFilename()}); } } diff --git a/src/main/java/ru/ulstu/file/service/FileService.java b/src/main/java/ru/ulstu/file/service/FileService.java index 3f3dbca..e0d9813 100644 --- a/src/main/java/ru/ulstu/file/service/FileService.java +++ b/src/main/java/ru/ulstu/file/service/FileService.java @@ -33,6 +33,7 @@ public class FileService { public FileData createFileFromTmp(String tmpFileName) throws IOException { FileData fileData = new FileData(); fileData.setData(getTmpFile(tmpFileName)); + fileData.setSize(getTmpFileSize(tmpFileName)); fileData.setName(getTmpFileName(tmpFileName)); fileData.setCreateDate(new Date()); return fileRepository.save(fileData); diff --git a/src/main/resources/templates/papers/paper.html b/src/main/resources/templates/papers/paper.html index 0f1a467..d758bb9 100644 --- a/src/main/resources/templates/papers/paper.html +++ b/src/main/resources/templates/papers/paper.html @@ -92,7 +92,7 @@ class="alert alert-danger">Incorrect title

-
+
@@ -189,15 +191,72 @@ div: "loader", url: urlFileUpload, maxSize: 1.5, - extensions: ["doc", "docx", "xls", "jpg", "pdf", "txt", "png"], + extensions: [], callback: function (response) { showFeedbackMessage("Файл успешно загружен"); console.debug(response); + + addNewFile(response); } }); $('.selectpicker').selectpicker(); }); /*]]>*/ + function addNewFile(fileNames) { + var filesList = $("#files-list"); + var fileNumber = $("#files-list div.row").length; + + var newFileRow = $("
") + .attr("id", 'files' + fileNumber) + .addClass("row"); + + var idInput = $("") + .attr("type", "hidden") + .attr("id", "files" + fileNumber + ".id") + .attr("value", '') + .attr("name", "files[" + fileNumber + "].id"); + newFileRow.append(idInput); + + var flagInput = $("") + .attr("type", "hidden") + .attr("id", "files" + fileNumber + ".deleteFlag") + .attr("value", "false") + .attr("name", "files[" + fileNumber + "].deleteFlag"); + newFileRow.append(flagInput); + + var nameInput = $("") + .attr("type", "hidden") + .attr("id", "files" + fileNumber + ".name") + .attr("value", tmpFileName[1]) + .attr("name", "files[" + fileNumber + "].name"); + newFileRow.append(nameInput); + + var tmpFileNameInput = $("") + .attr("type", "hidden") + .attr("id", "files" + fileNumber + ".tmpFileName") + .attr("value", tmpFileName[0]) + .attr("name", "files[" + fileNumber + "].tmpFileName"); + newFileRow.append(tmpFileNameInput); + + var nextDiv = $("
") + .addClass("col-2"); + + var nextA = $("") + .addClass("btn btn-danger float-right") + .attr("onclick", "$('#files" + fileNumber + "\\\\.deleteFlag').val('true'); $('#files" + fileNumber + "').hide();") + .append(($("").attr("aria-hidden", "true")).append($("").addClass("fa fa-times"))) + ; + nextDiv.append(nextA) + newFileRow.append(nextDiv); + + var nameDiv = $("
") + .addClass("col-10") + .append($("
").text(tmpFileName[1])); + newFileRow.append(nameDiv); + + $("#files-list").append(newFileRow); + + }
From fd22aecd22b340eab42c0947e2802889f6c802b7 Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Mon, 18 Mar 2019 18:41:59 +0400 Subject: [PATCH 08/45] #53 added supporting bootstrap style --- src/main/resources/public/css/conference.css | 47 +++++++++---------- src/main/resources/public/js/conference.js | 8 +++- .../templates/conferences/conferences.html | 28 ++++++----- 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/main/resources/public/css/conference.css b/src/main/resources/public/css/conference.css index 06d8041..630e31f 100644 --- a/src/main/resources/public/css/conference.css +++ b/src/main/resources/public/css/conference.css @@ -1,94 +1,93 @@ -.col-lg-12 a{ +.col-lg-12 a { position: absolute; font-size: smaller; } -.col-lg-12 a img{ +.col-lg-12 a img { width: 36px; height: 33px; } -.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; } -.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; } -.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; } -.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; + transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; } -#add-paper{ +#add-paper { margin-left: 10px; } -#cancel-button{ +#cancel-button { position: relative; font-size: 1rem; } - diff --git a/src/main/resources/public/js/conference.js b/src/main/resources/public/js/conference.js index e21cb7a..399cde9 100644 --- a/src/main/resources/public/js/conference.js +++ b/src/main/resources/public/js/conference.js @@ -1,3 +1,9 @@ $(document).ready(function () { - $('#table_id').dataTable(); + $('#table_id').dataTable({ + "pageLength": 10, + select: { + style: 'multi' + }, + "lengthChange": false + }); }); diff --git a/src/main/resources/templates/conferences/conferences.html b/src/main/resources/templates/conferences/conferences.html index d4c171b..1a024fe 100644 --- a/src/main/resources/templates/conferences/conferences.html +++ b/src/main/resources/templates/conferences/conferences.html @@ -3,8 +3,8 @@ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="default"> - - + + @@ -25,24 +25,30 @@
-
- - + +
- - + + + + - - + + + + - - + + + + +
Column 1Column 2Название:Описание:Начало:Конец:
Row 1 Data 1Row 1 Data 2Конференция 1Описание 101.01.200002.01.2000
Row 2 Data 1Row 2 Data 2Конференция 2Описание 201.02.200102.02.2001
From 8dc5eec35c36292374ca34c33def7660ed1852d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=9C?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F?= Date: Mon, 18 Mar 2019 19:17:28 +0400 Subject: [PATCH 09/45] #13 add files to db --- .../ru/ulstu/file/service/FileService.java | 11 +++---- src/main/resources/public/js/file-loader.js | 29 ++++++++++--------- .../resources/templates/papers/paper.html | 8 ++--- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/main/java/ru/ulstu/file/service/FileService.java b/src/main/java/ru/ulstu/file/service/FileService.java index e0d9813..3a68bb6 100644 --- a/src/main/java/ru/ulstu/file/service/FileService.java +++ b/src/main/java/ru/ulstu/file/service/FileService.java @@ -34,7 +34,6 @@ public class FileService { FileData fileData = new FileData(); fileData.setData(getTmpFile(tmpFileName)); fileData.setSize(getTmpFileSize(tmpFileName)); - fileData.setName(getTmpFileName(tmpFileName)); fileData.setCreateDate(new Date()); return fileRepository.save(fileData); } @@ -99,16 +98,18 @@ public class FileService { @Transactional public FileData create(FileDataDto fileDataDto) { - FileData newFile = copyFromDto(new FileData(), fileDataDto); + FileData newFile = new FileData(); + try { + newFile = createFileFromTmp(fileDataDto.getTmpFileName()); + } catch (IOException e) { + } + copyFromDto(newFile, fileDataDto); newFile = fileRepository.save(newFile); return newFile; } private FileData copyFromDto(FileData fileData, FileDataDto fileDataDto) { - fileData.setCreateDate(fileDataDto.getCreateDate()); - fileData.setData(fileDataDto.getData()); fileData.setName(fileDataDto.getName()); - fileData.setSize(fileDataDto.getSize()); return fileData; } diff --git a/src/main/resources/public/js/file-loader.js b/src/main/resources/public/js/file-loader.js index 9ee16a1..1ba467b 100644 --- a/src/main/resources/public/js/file-loader.js +++ b/src/main/resources/public/js/file-loader.js @@ -42,6 +42,7 @@ function FileLoader(args) { div.append(fileLabel); var fileInput = $("") .attr("type", "file") + .attr("multiple", '') .hide(); fileInput.change(function () { var files = $(this).prop("files"); @@ -75,20 +76,22 @@ function FileLoader(args) { showFeedbackMessage(ALERT_CHOOSE_FILE, MessageTypesEnum.DANGER); return; } - var currentFile = files[0]; - if (!isEmpty(fileExtensions) && fileExtensions.indexOf(getFileExt(currentFile)) === -1) { - showFeedbackMessage(ALERT_UNKNOWN_FILE_EXT, MessageTypesEnum.DANGER); - return; - } - if (currentFile.size === 0) { - showFeedbackMessage(ALERT_EMPTY_FILE, MessageTypesEnum.DANGER); - return; - } - if (currentFile.size / SIZE_TO_MB > MAX_FILE_SIZE_MB) { - showFeedbackMessage(ALERT_MAX_FILE + " " + MAX_FILE_SIZE_MB + "Mb", MessageTypesEnum.DANGER); - return; + for (var i = 0; i < files.length; i++) { + var currentFile = files[i]; + if (!isEmpty(fileExtensions) && fileExtensions.indexOf(getFileExt(currentFile)) === -1) { + showFeedbackMessage(ALERT_UNKNOWN_FILE_EXT, MessageTypesEnum.DANGER); + return; + } + if (currentFile.size === 0) { + showFeedbackMessage(ALERT_EMPTY_FILE, MessageTypesEnum.DANGER); + return; + } + if (MAX_FILE_SIZE_MB != -1 && currentFile.size / SIZE_TO_MB > MAX_FILE_SIZE_MB) { + showFeedbackMessage(ALERT_MAX_FILE + " " + MAX_FILE_SIZE_MB + "Mb", MessageTypesEnum.DANGER); + return; + } + upload(currentFile); } - upload(currentFile); }); buttonGroup.append(uploadButton); diff --git a/src/main/resources/templates/papers/paper.html b/src/main/resources/templates/papers/paper.html index d758bb9..996c991 100644 --- a/src/main/resources/templates/papers/paper.html +++ b/src/main/resources/templates/papers/paper.html @@ -190,7 +190,7 @@ new FileLoader({ div: "loader", url: urlFileUpload, - maxSize: 1.5, + maxSize: -1, extensions: [], callback: function (response) { showFeedbackMessage("Файл успешно загружен"); @@ -227,14 +227,14 @@ var nameInput = $("") .attr("type", "hidden") .attr("id", "files" + fileNumber + ".name") - .attr("value", tmpFileName[1]) + .attr("value", fileNames[1]) .attr("name", "files[" + fileNumber + "].name"); newFileRow.append(nameInput); var tmpFileNameInput = $("") .attr("type", "hidden") .attr("id", "files" + fileNumber + ".tmpFileName") - .attr("value", tmpFileName[0]) + .attr("value", fileNames[0]) .attr("name", "files[" + fileNumber + "].tmpFileName"); newFileRow.append(tmpFileNameInput); @@ -251,7 +251,7 @@ var nameDiv = $("
") .addClass("col-10") - .append($("
").text(tmpFileName[1])); + .append($("
").text(fileNames[1])); newFileRow.append(nameDiv); $("#files-list").append(newFileRow); From 1425cceb63189b4c4d6f28ae12654a51e08cd4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=9C?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F?= Date: Mon, 18 Mar 2019 21:02:26 +0400 Subject: [PATCH 10/45] #13 download files --- .../ru/ulstu/file/service/FileService.java | 3 +- src/main/resources/public/js/core.js | 2 + .../resources/templates/papers/paper.html | 46 +++++++++++++++++-- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/ulstu/file/service/FileService.java b/src/main/java/ru/ulstu/file/service/FileService.java index 3a68bb6..68d0b35 100644 --- a/src/main/java/ru/ulstu/file/service/FileService.java +++ b/src/main/java/ru/ulstu/file/service/FileService.java @@ -13,6 +13,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Date; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; import static java.nio.charset.StandardCharsets.UTF_8; @@ -39,7 +40,7 @@ public class FileService { } public String uploadToTmpDir(MultipartFile multipartFile) throws IOException { - String tmpFileName = String.valueOf(System.currentTimeMillis()); + String tmpFileName = String.valueOf(System.currentTimeMillis()) + UUID.randomUUID(); Files.write(getTmpFilePath(tmpFileName), multipartFile.getBytes()); String meta = multipartFile.getOriginalFilename() + "\n" + multipartFile.getSize(); Files.write(getTmpFileMetaPath(tmpFileName), meta.getBytes(UTF_8)); diff --git a/src/main/resources/public/js/core.js b/src/main/resources/public/js/core.js index 31642f4..216f411 100644 --- a/src/main/resources/public/js/core.js +++ b/src/main/resources/public/js/core.js @@ -2,6 +2,8 @@ /* global urlVersions */ var urlFileUpload = "/api/1.0/files/uploadTmpFile"; +var urlFileDownload = "/api/1.0/files/download/"; +var urlFileDownloadTmp = "/api/1.0/files/download-tmp/"; /* exported MessageTypesEnum */ var MessageTypesEnum = { diff --git a/src/main/resources/templates/papers/paper.html b/src/main/resources/templates/papers/paper.html index 996c991..cfba4bc 100644 --- a/src/main/resources/templates/papers/paper.html +++ b/src/main/resources/templates/papers/paper.html @@ -107,8 +107,17 @@
-
-
+
+ + +
+
+ +
@@ -251,12 +260,43 @@ var nameDiv = $("
") .addClass("col-10") - .append($("
").text(fileNames[1])); + .append($("").text(fileNames[1]) + .attr("href", 'javascript:void(0)') + .attr("onclick", "downloadFile('" + fileNames[0] + "',null,'" + fileNames[1] + "')")); newFileRow.append(nameDiv); $("#files-list").append(newFileRow); } + + function downloadFile(tmpName, fileId, downloadName) { + let xhr = new XMLHttpRequest(); + if (fileId != null) xhr.open('GET', urlFileDownload + fileId); + if (tmpName != null) xhr.open('GET', urlFileDownloadTmp + tmpName); + xhr.responseType = 'blob'; + + var formData = new FormData(); + if (fileId != null) formData.append("file-id", fileId); + if (tmpName != null) formData.append("tmp-file-name", tmpName); + + xhr.send(formData); + + xhr.onload = function () { + if (this.status == 200) { + console.debug(this.response); + var blob = new Blob([this.response], {type: '*'}); + let a = document.createElement("a"); + a.style = "display: none"; + document.body.appendChild(a); + let url = window.URL.createObjectURL(blob); + a.href = url; + a.download = downloadName; + a.click(); + window.URL.revokeObjectURL(url); + } else { + } + } + }
From e6bf603edc7245698f6d8359db3102b6df88ac2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=9C?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F?= Date: Mon, 18 Mar 2019 23:31:33 +0400 Subject: [PATCH 11/45] #33 url in paper --- src/main/java/ru/ulstu/paper/model/Paper.java | 32 +++++++------------ .../java/ru/ulstu/paper/model/PaperDto.java | 12 +++++++ .../ru/ulstu/paper/service/PaperService.java | 13 ++------ .../db/changelog-20190318_000001-schema.xml | 10 ++++++ src/main/resources/db/changelog-master.xml | 1 + .../fragments/paperDashboardFragment.html | 8 ++++- .../resources/templates/papers/paper.html | 7 ++++ 7 files changed, 52 insertions(+), 31 deletions(-) create mode 100644 src/main/resources/db/changelog-20190318_000001-schema.xml diff --git a/src/main/java/ru/ulstu/paper/model/Paper.java b/src/main/java/ru/ulstu/paper/model/Paper.java index c09fd28..fce6817 100644 --- a/src/main/java/ru/ulstu/paper/model/Paper.java +++ b/src/main/java/ru/ulstu/paper/model/Paper.java @@ -9,26 +9,8 @@ import ru.ulstu.deadline.model.Deadline; import ru.ulstu.file.model.FileData; import ru.ulstu.user.model.User; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.OrderBy; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import javax.persistence.*; +import java.util.*; @Entity public class Paper extends BaseEntity implements UserContainer { @@ -75,6 +57,8 @@ public class Paper extends BaseEntity implements UserContainer { private String comment; + private String url; + private Boolean locked = false; @ManyToOne @@ -156,6 +140,14 @@ public class Paper extends BaseEntity implements UserContainer { this.authors = authors; } + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + @Override public Set getUsers() { return getAuthors(); diff --git a/src/main/java/ru/ulstu/paper/model/PaperDto.java b/src/main/java/ru/ulstu/paper/model/PaperDto.java index 3405768..7c6eeb7 100644 --- a/src/main/java/ru/ulstu/paper/model/PaperDto.java +++ b/src/main/java/ru/ulstu/paper/model/PaperDto.java @@ -29,6 +29,7 @@ public class PaperDto { @NotEmpty private List deadlines = new ArrayList<>(); private String comment; + private String url; private Boolean locked; private String tmpFileName; private Integer fileId; @@ -50,6 +51,7 @@ public class PaperDto { @JsonProperty("updateDate") Date updateDate, @JsonProperty("deadlines") List deadlines, @JsonProperty("comment") String comment, + @JsonProperty("url") String url, @JsonProperty("locked") Boolean locked, @JsonProperty("tmpFileName") String tmpFileName, @JsonProperty("authorIds") Set authorIds, @@ -61,6 +63,7 @@ public class PaperDto { this.updateDate = updateDate; this.deadlines = deadlines; this.comment = comment; + this.url = url; this.locked = locked; this.tmpFileName = tmpFileName; this.fileId = null; @@ -77,6 +80,7 @@ public class PaperDto { this.updateDate = paper.getUpdateDate(); this.deadlines = paper.getDeadlines(); this.comment = paper.getComment(); + this.url = paper.getUrl(); this.locked = paper.getLocked(); this.tmpFileName = null; this.fileId = paper.getFileData() == null ? null : paper.getFileData().getId(); @@ -198,6 +202,14 @@ public class PaperDto { this.authorIds = authorIds; } + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + public String getAuthorsString() { return StringUtils.abbreviate(authors .stream() diff --git a/src/main/java/ru/ulstu/paper/service/PaperService.java b/src/main/java/ru/ulstu/paper/service/PaperService.java index 9df8be2..49102d6 100644 --- a/src/main/java/ru/ulstu/paper/service/PaperService.java +++ b/src/main/java/ru/ulstu/paper/service/PaperService.java @@ -14,20 +14,12 @@ import ru.ulstu.user.model.User; import ru.ulstu.user.service.UserService; import java.io.IOException; -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import static org.springframework.util.ObjectUtils.isEmpty; import static ru.ulstu.core.util.StreamApiUtils.convert; -import static ru.ulstu.paper.model.Paper.PaperStatus.ATTENTION; -import static ru.ulstu.paper.model.Paper.PaperStatus.COMPLETED; -import static ru.ulstu.paper.model.Paper.PaperStatus.DRAFT; -import static ru.ulstu.paper.model.Paper.PaperStatus.FAILED; -import static ru.ulstu.paper.model.Paper.PaperStatus.ON_PREPARATION; +import static ru.ulstu.paper.model.Paper.PaperStatus.*; @Service public class PaperService { @@ -82,6 +74,7 @@ public class PaperService { private Paper copyFromDto(Paper paper, PaperDto paperDto) throws IOException { paper.setComment(paperDto.getComment()); + paper.setUrl(paperDto.getUrl()); paper.setCreateDate(paper.getCreateDate() == null ? new Date() : paper.getCreateDate()); paper.setLocked(paperDto.getLocked()); paper.setStatus(paperDto.getStatus() == null ? DRAFT : paperDto.getStatus()); diff --git a/src/main/resources/db/changelog-20190318_000001-schema.xml b/src/main/resources/db/changelog-20190318_000001-schema.xml new file mode 100644 index 0000000..98ec657 --- /dev/null +++ b/src/main/resources/db/changelog-20190318_000001-schema.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/src/main/resources/db/changelog-master.xml b/src/main/resources/db/changelog-master.xml index b8654ae..1276108 100644 --- a/src/main/resources/db/changelog-master.xml +++ b/src/main/resources/db/changelog-master.xml @@ -18,5 +18,6 @@ + \ No newline at end of file diff --git a/src/main/resources/templates/papers/fragments/paperDashboardFragment.html b/src/main/resources/templates/papers/fragments/paperDashboardFragment.html index 122696e..f55d724 100644 --- a/src/main/resources/templates/papers/fragments/paperDashboardFragment.html +++ b/src/main/resources/templates/papers/fragments/paperDashboardFragment.html @@ -10,7 +10,13 @@
diff --git a/src/main/resources/templates/papers/paper.html b/src/main/resources/templates/papers/paper.html index a5ff6b5..a01e858 100644 --- a/src/main/resources/templates/papers/paper.html +++ b/src/main/resources/templates/papers/paper.html @@ -50,6 +50,13 @@ th:field="*{comment}">
+
+ + +
+
From 5dc54dda8b795f351956463af69d9d606c1f2c05 Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Tue, 19 Mar 2019 15:08:45 +0400 Subject: [PATCH 12/45] #53 added supporting russian language, added linkable row in table --- src/main/resources/public/js/conference.js | 28 ++++++++++++++++++- .../templates/conferences/conferences.html | 7 +++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/main/resources/public/js/conference.js b/src/main/resources/public/js/conference.js index 399cde9..35e3c42 100644 --- a/src/main/resources/public/js/conference.js +++ b/src/main/resources/public/js/conference.js @@ -4,6 +4,32 @@ $(document).ready(function () { select: { style: 'multi' }, - "lengthChange": false + "lengthChange": false, + language: { + "processing": "Подождите...", + "search": "Поиск:", + "lengthMenu": "Показать _MENU_ записей", + "info": "Записи с _START_ до _END_ из _TOTAL_ записей", + "infoEmpty": "Записи с 0 до 0 из 0 записей", + "infoFiltered": "(отфильтровано из _MAX_ записей)", + "infoPostFix": "", + "loadingRecords": "Загрузка записей...", + "zeroRecords": "Записи отсутствуют.", + "emptyTable": "В таблице отсутствуют данные", + "paginate": { + "first": "Первая", + "previous": "Предыдущая", + "next": "Следующая", + "last": "Последняя" + }, + "aria": { + "sortAscending": ": активировать для сортировки столбца по возрастанию", + "sortDescending": ": активировать для сортировки столбца по убыванию" + } + } + }); + + $('tbody tr[data-href]').addClass('clickable').click( function() { + window.location = $(this).attr('data-href'); }); }); diff --git a/src/main/resources/templates/conferences/conferences.html b/src/main/resources/templates/conferences/conferences.html index 1a024fe..999010f 100644 --- a/src/main/resources/templates/conferences/conferences.html +++ b/src/main/resources/templates/conferences/conferences.html @@ -19,7 +19,7 @@
-

Редактирование конференции

+

Список конференций


@@ -36,13 +36,14 @@ - + Конференция 1 Описание 1 01.01.2000 02.01.2000 + - + Конференция 2 Описание 2 01.02.2001 From 3c068df201d2c35b29ec12cf80e33106a1492c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=9C?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F?= Date: Tue, 19 Mar 2019 17:59:19 +0400 Subject: [PATCH 13/45] #13 some refactoring --- .../java/ru/ulstu/file/model/FileDataDto.java | 38 ------------------- src/main/resources/public/css/paper.css | 5 +++ .../resources/templates/papers/paper.html | 13 ++----- 3 files changed, 9 insertions(+), 47 deletions(-) create mode 100644 src/main/resources/public/css/paper.css diff --git a/src/main/java/ru/ulstu/file/model/FileDataDto.java b/src/main/java/ru/ulstu/file/model/FileDataDto.java index fda3e81..d117fe7 100644 --- a/src/main/java/ru/ulstu/file/model/FileDataDto.java +++ b/src/main/java/ru/ulstu/file/model/FileDataDto.java @@ -3,14 +3,9 @@ package ru.ulstu.file.model; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Date; - public class FileDataDto { private Integer id; private String name; - private long size; - private Date createDate; - private byte[] data; private String fileName; private String tmpFileName; @@ -22,16 +17,10 @@ public class FileDataDto { @JsonCreator public FileDataDto(@JsonProperty("id") Integer id, @JsonProperty("name") String name, - @JsonProperty("size") long size, - @JsonProperty("createDate") Date createDate, - @JsonProperty("data") byte[] data, @JsonProperty("fileName") String fileName, @JsonProperty("tmpFileName") String tmpFileName) { this.id = id; this.name = name; - this.size = size; - this.createDate = createDate; - this.data = data; this.fileName = fileName; this.tmpFileName = tmpFileName; } @@ -39,9 +28,6 @@ public class FileDataDto { public FileDataDto(FileData fileData) { this.id = fileData.getId(); this.name = fileData.getName(); - this.size = fileData.getSize(); - this.createDate = fileData.getCreateDate(); - this.data = fileData.getData(); } public Integer getId() { @@ -60,30 +46,6 @@ public class FileDataDto { this.name = name; } - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public Date getCreateDate() { - return createDate; - } - - public void setCreateDate(Date createDate) { - this.createDate = createDate; - } - - public byte[] getData() { - return data; - } - - public void setData(byte[] data) { - this.data = data; - } - public String getFileName() { return fileName; } diff --git a/src/main/resources/public/css/paper.css b/src/main/resources/public/css/paper.css new file mode 100644 index 0000000..6e61d0c --- /dev/null +++ b/src/main/resources/public/css/paper.css @@ -0,0 +1,5 @@ +#files-list .row > div:nth-child(6) { + display: flex; + justify-content: center; + flex-direction: column; +} \ No newline at end of file diff --git a/src/main/resources/templates/papers/paper.html b/src/main/resources/templates/papers/paper.html index cfba4bc..1daec46 100644 --- a/src/main/resources/templates/papers/paper.html +++ b/src/main/resources/templates/papers/paper.html @@ -3,7 +3,7 @@ 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"> - + @@ -107,14 +107,9 @@
-
- - -
-
- + From 1364e8e84d9c8276f14cd78db010c1d159d545e1 Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Wed, 20 Mar 2019 16:48:55 +0400 Subject: [PATCH 14/45] #53 added multi selection, added selection of all items --- src/main/resources/public/js/conference.js | 35 ++++++++++++++++--- .../templates/conferences/conferences.html | 16 ++++----- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/main/resources/public/js/conference.js b/src/main/resources/public/js/conference.js index 35e3c42..1b3b7f9 100644 --- a/src/main/resources/public/js/conference.js +++ b/src/main/resources/public/js/conference.js @@ -1,10 +1,15 @@ $(document).ready(function () { - $('#table_id').dataTable({ + $('#table_id').DataTable({ "pageLength": 10, select: { style: 'multi' }, "lengthChange": false, + dom: 'Bfrtip', + buttons: [ + 'selectAll', + 'selectNone' + ], language: { "processing": "Подождите...", "search": "Поиск:", @@ -25,11 +30,31 @@ $(document).ready(function () { "aria": { "sortAscending": ": активировать для сортировки столбца по возрастанию", "sortDescending": ": активировать для сортировки столбца по убыванию" - } - } + }, + "buttons": { + "selectAll": "Выбрать всё", + "selectNone": "Убрать выделение" + } + }, + columnDefs: [ { + orderable: false, + className: 'select-checkbox', + targets: 0 + } ], + select: { + style: 'multi' + }, + order: [[ 1, 'asc' ]] }); - $('tbody tr[data-href]').addClass('clickable').click( function() { - window.location = $(this).attr('data-href'); + var table = $('#table_id').DataTable(); + + $('#table_id tbody').on( 'click', 'tr', function () { + $(this).toggleClass('selected'); }); + + +// $('tbody tr[data-href]').addClass('clickable').click( function() { +// window.location = $(this).attr('data-href'); +// }); }); diff --git a/src/main/resources/templates/conferences/conferences.html b/src/main/resources/templates/conferences/conferences.html index 999010f..0ddbe5f 100644 --- a/src/main/resources/templates/conferences/conferences.html +++ b/src/main/resources/templates/conferences/conferences.html @@ -3,18 +3,15 @@ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="default"> - - + + +
- нажать
@@ -29,6 +26,7 @@ + @@ -37,6 +35,7 @@ + @@ -44,6 +43,7 @@ + From cb673d87829c3d66eb98386bd8c621b722a27cf8 Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Wed, 20 Mar 2019 18:33:15 +0400 Subject: [PATCH 15/45] #53 remake of conference list without table --- src/main/resources/public/css/conference.css | 19 ++++++ src/main/resources/public/js/conference.js | 58 +------------------ .../templates/conferences/conferences.html | 48 ++++----------- 3 files changed, 33 insertions(+), 92 deletions(-) diff --git a/src/main/resources/public/css/conference.css b/src/main/resources/public/css/conference.css index 630e31f..f9e9944 100644 --- a/src/main/resources/public/css/conference.css +++ b/src/main/resources/public/css/conference.css @@ -1,3 +1,22 @@ +.conference-list-body { + height: 500px; +} + +.conference-item { + align-items: center; + justify-content: center; +} + +.form-check { + padding: 0; +} + +.form-check input { + margin: 10px; +} + + + .col-lg-12 a { position: absolute; font-size: smaller; diff --git a/src/main/resources/public/js/conference.js b/src/main/resources/public/js/conference.js index 1b3b7f9..1056bec 100644 --- a/src/main/resources/public/js/conference.js +++ b/src/main/resources/public/js/conference.js @@ -1,60 +1,6 @@ $(document).ready(function () { - $('#table_id').DataTable({ - "pageLength": 10, - select: { - style: 'multi' - }, - "lengthChange": false, - dom: 'Bfrtip', - buttons: [ - 'selectAll', - 'selectNone' - ], - language: { - "processing": "Подождите...", - "search": "Поиск:", - "lengthMenu": "Показать _MENU_ записей", - "info": "Записи с _START_ до _END_ из _TOTAL_ записей", - "infoEmpty": "Записи с 0 до 0 из 0 записей", - "infoFiltered": "(отфильтровано из _MAX_ записей)", - "infoPostFix": "", - "loadingRecords": "Загрузка записей...", - "zeroRecords": "Записи отсутствуют.", - "emptyTable": "В таблице отсутствуют данные", - "paginate": { - "first": "Первая", - "previous": "Предыдущая", - "next": "Следующая", - "last": "Последняя" - }, - "aria": { - "sortAscending": ": активировать для сортировки столбца по возрастанию", - "sortDescending": ": активировать для сортировки столбца по убыванию" - }, - "buttons": { - "selectAll": "Выбрать всё", - "selectNone": "Убрать выделение" - } - }, - columnDefs: [ { - orderable: false, - className: 'select-checkbox', - targets: 0 - } ], - select: { - style: 'multi' - }, - order: [[ 1, 'asc' ]] - }); - - var table = $('#table_id').DataTable(); - $('#table_id tbody').on( 'click', 'tr', function () { - $(this).toggleClass('selected'); + $('tbody tr[data-href]').addClass('clickable').click( function() { + window.location = $(this).attr('data-href'); }); - - -// $('tbody tr[data-href]').addClass('clickable').click( function() { -// window.location = $(this).attr('data-href'); -// }); }); diff --git a/src/main/resources/templates/conferences/conferences.html b/src/main/resources/templates/conferences/conferences.html index 0ddbe5f..2d2c1c8 100644 --- a/src/main/resources/templates/conferences/conferences.html +++ b/src/main/resources/templates/conferences/conferences.html @@ -3,11 +3,7 @@ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="default"> - - - + @@ -22,37 +18,17 @@
-
-
Название: Описание: Начало:
Конференция 1 Описание 1 01.01.2000
Конференция 2 Описание 2 01.02.2001
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Название:Описание:Начало:Конец:
Конференция 1Описание 101.01.200002.01.2000
Конференция 2Описание 201.02.200102.02.2001
- +
+
+
+ +
+
+
Конференция 1
+
01.01.1990
+
+
+
From 89e0d1a291f8269891bc3c857702aa3623464ad7 Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Wed, 20 Mar 2019 21:15:45 +0400 Subject: [PATCH 16/45] #53 customization css styles --- src/main/resources/public/css/conference.css | 18 +++++++++++++++++- src/main/resources/public/js/conference.js | 2 +- .../templates/conferences/conferences.html | 5 ++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/main/resources/public/css/conference.css b/src/main/resources/public/css/conference.css index f9e9944..bfa1e73 100644 --- a/src/main/resources/public/css/conference.css +++ b/src/main/resources/public/css/conference.css @@ -7,12 +7,28 @@ justify-content: center; } +.conference-item:hover { + background-color: #eee; +} + .form-check { padding: 0; } .form-check input { - margin: 10px; + margin: 10px 5px; +} + +.conference-info:hover { + cursor: pointer; +} + +.conference-item:hover .form-check { + background-color: #ddd; +} + +.conference-item:hover .form-check:hover { + background-color: #ccc; } diff --git a/src/main/resources/public/js/conference.js b/src/main/resources/public/js/conference.js index 1056bec..04eba51 100644 --- a/src/main/resources/public/js/conference.js +++ b/src/main/resources/public/js/conference.js @@ -1,6 +1,6 @@ $(document).ready(function () { - $('tbody tr[data-href]').addClass('clickable').click( function() { + $('.conference-info').click( function() { window.location = $(this).attr('data-href'); }); }); diff --git a/src/main/resources/templates/conferences/conferences.html b/src/main/resources/templates/conferences/conferences.html index 2d2c1c8..ce322df 100644 --- a/src/main/resources/templates/conferences/conferences.html +++ b/src/main/resources/templates/conferences/conferences.html @@ -23,7 +23,10 @@
-
+
+ +
+
Конференция 1
01.01.1990
From d356c219449c9411c29713d5f1c015e05ecc7caf Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Thu, 21 Mar 2019 09:55:38 +0400 Subject: [PATCH 17/45] #53 added buttons, added bottom pagination --- src/main/resources/public/css/conference.css | 9 +++++++ .../templates/conferences/conferences.html | 25 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/resources/public/css/conference.css b/src/main/resources/public/css/conference.css index bfa1e73..af5b7aa 100644 --- a/src/main/resources/public/css/conference.css +++ b/src/main/resources/public/css/conference.css @@ -1,3 +1,11 @@ +.dashboard { + margin-bottom: 10px; +} + +.dashboard button{ + margin-left: 10px; +} + .conference-list-body { height: 500px; } @@ -5,6 +13,7 @@ .conference-item { align-items: center; justify-content: center; + padding: 0; } .conference-item:hover { diff --git a/src/main/resources/templates/conferences/conferences.html b/src/main/resources/templates/conferences/conferences.html index ce322df..2afc7d9 100644 --- a/src/main/resources/templates/conferences/conferences.html +++ b/src/main/resources/templates/conferences/conferences.html @@ -16,10 +16,22 @@

+
+
+
+
+ +
+ + + +
+
+
-
-
+
+
@@ -34,6 +46,15 @@
+
+ +
+
+ +
- \ No newline at end of file + + diff --git a/src/main/resources/templates/conferences/fragments/confDashboardFragment.html b/src/main/resources/templates/conferences/fragments/confDashboardFragment.html new file mode 100644 index 0000000..080946c --- /dev/null +++ b/src/main/resources/templates/conferences/fragments/confDashboardFragment.html @@ -0,0 +1,21 @@ + + + + + + +
+
+
+ +
+
+ title +

+
+
+
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/conferences/fragments/confLineFragment.html b/src/main/resources/templates/conferences/fragments/confLineFragment.html new file mode 100644 index 0000000..f54a777 --- /dev/null +++ b/src/main/resources/templates/conferences/fragments/confLineFragment.html @@ -0,0 +1,23 @@ + + + + + + +
+ +
+ + + + \ No newline at end of file From 2f0c461524ba349033c5b9f253e86844591c7794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=20=D0=9C?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F?= Date: Thu, 28 Mar 2019 12:40:10 +0400 Subject: [PATCH 36/45] #18 add paper events --- src/main/java/ru/ulstu/paper/model/Paper.java | 12 +++++ .../ru/ulstu/paper/service/PaperService.java | 11 ++++- .../java/ru/ulstu/timeline/model/Event.java | 13 ++++++ .../ru/ulstu/timeline/model/EventDto.java | 13 ++++++ .../ru/ulstu/timeline/model/Timeline.java | 3 +- .../timeline/repository/EventRepository.java | 3 ++ .../timeline/service/EventScheduler.java | 4 ++ .../ulstu/timeline/service/EventService.java | 45 +++++++++++++++++++ .../timeline/service/TimelineService.java | 11 ++++- .../db/changelog-20190327_000000-schema.xml | 13 ++++++ src/main/resources/db/changelog-master.xml | 1 + 11 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/db/changelog-20190327_000000-schema.xml diff --git a/src/main/java/ru/ulstu/paper/model/Paper.java b/src/main/java/ru/ulstu/paper/model/Paper.java index b2f8327..256e4de 100644 --- a/src/main/java/ru/ulstu/paper/model/Paper.java +++ b/src/main/java/ru/ulstu/paper/model/Paper.java @@ -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; @@ -77,6 +78,9 @@ public class Paper extends BaseEntity implements UserContainer { private Boolean locked = false; + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "paper_id") + private List events = new ArrayList<>(); @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "paper_id", unique = true) @@ -158,6 +162,14 @@ public class Paper extends BaseEntity implements UserContainer { this.authors = authors; } + public List getEvents() { + return events; + } + + public void setEvents(List events) { + this.events = events; + } + @Override public Set getUsers() { return getAuthors(); diff --git a/src/main/java/ru/ulstu/paper/service/PaperService.java b/src/main/java/ru/ulstu/paper/service/PaperService.java index a664d00..3e1fbe1 100644 --- a/src/main/java/ru/ulstu/paper/service/PaperService.java +++ b/src/main/java/ru/ulstu/paper/service/PaperService.java @@ -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; @@ -39,17 +40,20 @@ public class PaperService { 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 findAll() { @@ -78,6 +82,7 @@ public class PaperService { Paper newPaper = copyFromDto(new Paper(), paperDto); newPaper = paperRepository.save(newPaper); paperNotificationService.sendCreateNotification(newPaper); + eventService.createFromPaper(newPaper); return newPaper.getId(); } @@ -112,6 +117,7 @@ public class PaperService { } paperRepository.save(copyFromDto(paper, paperDto)); + eventService.updatePaperDeadlines(paper); paper.getAuthors().forEach(author -> { if (!oldAuthors.contains(author)) { @@ -127,7 +133,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); } @@ -148,6 +154,7 @@ public class PaperService { paper = paperRepository.save(paper); paperNotificationService.sendCreateNotification(paper); + eventService.createFromPaper(paper); return paper; } diff --git a/src/main/java/ru/ulstu/timeline/model/Event.java b/src/main/java/ru/ulstu/timeline/model/Event.java index 290f136..ef0a4b8 100644 --- a/src/main/java/ru/ulstu/timeline/model/Event.java +++ b/src/main/java/ru/ulstu/timeline/model/Event.java @@ -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 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 parents) { this.parents = parents; } + + public Paper getPaper() { + return paper; + } + + public void setPaper(Paper paper) { + this.paper = paper; + } } diff --git a/src/main/java/ru/ulstu/timeline/model/EventDto.java b/src/main/java/ru/ulstu/timeline/model/EventDto.java index 9e70a9d..6a4a90b 100644 --- a/src/main/java/ru/ulstu/timeline/model/EventDto.java +++ b/src/main/java/ru/ulstu/timeline/model/EventDto.java @@ -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 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 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; + } } diff --git a/src/main/java/ru/ulstu/timeline/model/Timeline.java b/src/main/java/ru/ulstu/timeline/model/Timeline.java index 8e588cb..06e04bc 100644 --- a/src/main/java/ru/ulstu/timeline/model/Timeline.java +++ b/src/main/java/ru/ulstu/timeline/model/Timeline.java @@ -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 events; + private List events = new ArrayList<>(); public List getEvents() { return events; diff --git a/src/main/java/ru/ulstu/timeline/repository/EventRepository.java b/src/main/java/ru/ulstu/timeline/repository/EventRepository.java index 4848e12..eb5c08b 100644 --- a/src/main/java/ru/ulstu/timeline/repository/EventRepository.java +++ b/src/main/java/ru/ulstu/timeline/repository/EventRepository.java @@ -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 { @Query("SELECT e FROM Event e WHERE e.executeDate > CURRENT_DATE ORDER BY e.executeDate") List findAllFuture(); + + List findAllByPaper(Paper paper); } diff --git a/src/main/java/ru/ulstu/timeline/service/EventScheduler.java b/src/main/java/ru/ulstu/timeline/service/EventScheduler.java index 6df7fcb..7899aca 100644 --- a/src/main/java/ru/ulstu/timeline/service/EventScheduler.java +++ b/src/main/java/ru/ulstu/timeline/service/EventScheduler.java @@ -34,6 +34,10 @@ public class EventScheduler { Map 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); + } }); } diff --git a/src/main/java/ru/ulstu/timeline/service/EventService.java b/src/main/java/ru/ulstu/timeline/service/EventService.java index ca95b9a..2d2b83d 100644 --- a/src/main/java/ru/ulstu/timeline/service/EventService.java +++ b/src/main/java/ru/ulstu/timeline/service/EventService.java @@ -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 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 findByCurrentDate() { return eventRepository.findByCurrentDate(); } diff --git a/src/main/java/ru/ulstu/timeline/service/TimelineService.java b/src/main/java/ru/ulstu/timeline/service/TimelineService.java index 94388ee..09f90c0 100644 --- a/src/main/java/ru/ulstu/timeline/service/TimelineService.java +++ b/src/main/java/ru/ulstu/timeline/service/TimelineService.java @@ -23,15 +23,24 @@ public class TimelineService { this.eventService = eventService; } - public List findAll() { + public List findAllDto() { return convert(timelineRepository.findAll(), TimelineDto::new); } + public List 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; diff --git a/src/main/resources/db/changelog-20190327_000000-schema.xml b/src/main/resources/db/changelog-20190327_000000-schema.xml new file mode 100644 index 0000000..4913072 --- /dev/null +++ b/src/main/resources/db/changelog-20190327_000000-schema.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/src/main/resources/db/changelog-master.xml b/src/main/resources/db/changelog-master.xml index dcba122..8601956 100644 --- a/src/main/resources/db/changelog-master.xml +++ b/src/main/resources/db/changelog-master.xml @@ -19,5 +19,6 @@ + \ No newline at end of file From c70c35f4f305a2be940907b4b7a0f0babae49fde Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Thu, 28 Mar 2019 14:36:58 +0400 Subject: [PATCH 37/45] #80 add no records message --- .../templates/fragments/noRecordsFragment.html | 17 +++++++++++++++++ .../resources/templates/grants/dashboard.html | 1 + src/main/resources/templates/grants/grants.html | 1 + .../resources/templates/papers/dashboard.html | 1 + src/main/resources/templates/papers/papers.html | 1 + 5 files changed, 21 insertions(+) create mode 100644 src/main/resources/templates/fragments/noRecordsFragment.html diff --git a/src/main/resources/templates/fragments/noRecordsFragment.html b/src/main/resources/templates/fragments/noRecordsFragment.html new file mode 100644 index 0000000..38970f0 --- /dev/null +++ b/src/main/resources/templates/fragments/noRecordsFragment.html @@ -0,0 +1,17 @@ + + + + + + +
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/grants/dashboard.html b/src/main/resources/templates/grants/dashboard.html index b469875..821ccd4 100644 --- a/src/main/resources/templates/grants/dashboard.html +++ b/src/main/resources/templates/grants/dashboard.html @@ -17,6 +17,7 @@
+
diff --git a/src/main/resources/templates/grants/grants.html b/src/main/resources/templates/grants/grants.html index 83083a0..d98f6d8 100644 --- a/src/main/resources/templates/grants/grants.html +++ b/src/main/resources/templates/grants/grants.html @@ -24,6 +24,7 @@
+
diff --git a/src/main/resources/templates/papers/dashboard.html b/src/main/resources/templates/papers/dashboard.html index b7849f7..5265e0b 100644 --- a/src/main/resources/templates/papers/dashboard.html +++ b/src/main/resources/templates/papers/dashboard.html @@ -18,6 +18,7 @@
+
diff --git a/src/main/resources/templates/papers/papers.html b/src/main/resources/templates/papers/papers.html index a797d26..7a033fe 100644 --- a/src/main/resources/templates/papers/papers.html +++ b/src/main/resources/templates/papers/papers.html @@ -43,6 +43,7 @@
+
From 7b0b7a041af65ebb089665cebb3b65eec4faedeb Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Thu, 28 Mar 2019 14:45:39 +0400 Subject: [PATCH 38/45] #80 hide mvc controllers from api --- src/main/java/ru/ulstu/grant/controller/GrantController.java | 2 ++ src/main/java/ru/ulstu/index/controller/IndexController.java | 2 ++ src/main/java/ru/ulstu/paper/controller/PaperController.java | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/main/java/ru/ulstu/grant/controller/GrantController.java b/src/main/java/ru/ulstu/grant/controller/GrantController.java index c786ffa..65b11dc 100644 --- a/src/main/java/ru/ulstu/grant/controller/GrantController.java +++ b/src/main/java/ru/ulstu/grant/controller/GrantController.java @@ -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; @@ -28,6 +29,7 @@ import static ru.ulstu.grant.controller.Navigation.hasErrors; @Controller() @RequestMapping(value = "/grants") +@ApiIgnore public class GrantController { private final GrantService grantService; diff --git a/src/main/java/ru/ulstu/index/controller/IndexController.java b/src/main/java/ru/ulstu/index/controller/IndexController.java index d964997..f6ab100 100644 --- a/src/main/java/ru/ulstu/index/controller/IndexController.java +++ b/src/main/java/ru/ulstu/index/controller/IndexController.java @@ -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); diff --git a/src/main/java/ru/ulstu/paper/controller/PaperController.java b/src/main/java/ru/ulstu/paper/controller/PaperController.java index 31df0e3..9169bd9 100644 --- a/src/main/java/ru/ulstu/paper/controller/PaperController.java +++ b/src/main/java/ru/ulstu/paper/controller/PaperController.java @@ -15,6 +15,7 @@ import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.model.PaperFilterDto; 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; @@ -28,6 +29,7 @@ import static org.springframework.util.StringUtils.isEmpty; @Controller() @RequestMapping(value = "/papers") +@ApiIgnore public class PaperController { private final PaperService paperService; From 539095c89e11ff79213f2f537c34ce812b06ce3f Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Thu, 28 Mar 2019 14:59:35 +0400 Subject: [PATCH 39/45] partially restored commits page --- .../ulstu/configuration/MvcConfiguration.java | 2 +- src/main/resources/public/css/odin.css | 226 +++ src/main/resources/public/js/config.js | 10 + src/main/resources/public/js/core.js | 6 +- src/main/resources/public/js/odin.js | 1512 +++++++++++++++++ src/main/resources/public/templates/odin.html | 165 ++ src/main/resources/templates/default.html | 5 + 7 files changed, 1922 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/public/css/odin.css create mode 100644 src/main/resources/public/js/config.js create mode 100644 src/main/resources/public/js/odin.js create mode 100644 src/main/resources/public/templates/odin.html diff --git a/src/main/java/ru/ulstu/configuration/MvcConfiguration.java b/src/main/java/ru/ulstu/configuration/MvcConfiguration.java index 3e8d66f..c704596 100644 --- a/src/main/java/ru/ulstu/configuration/MvcConfiguration.java +++ b/src/main/java/ru/ulstu/configuration/MvcConfiguration.java @@ -10,7 +10,7 @@ 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+}"); diff --git a/src/main/resources/public/css/odin.css b/src/main/resources/public/css/odin.css new file mode 100644 index 0000000..2bfeb75 --- /dev/null +++ b/src/main/resources/public/css/odin.css @@ -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%; + } +} \ No newline at end of file diff --git a/src/main/resources/public/js/config.js b/src/main/resources/public/js/config.js new file mode 100644 index 0000000..353180b --- /dev/null +++ b/src/main/resources/public/js/config.js @@ -0,0 +1,10 @@ +/* exported contextPath */ +var contextPath = ""; +var apiVersion = "/api/1.0"; + +var basePath = contextPath + apiVersion; + +/* exported urlVersions */ +var urlVersions = basePath + "/versions"; +/* exported urlCommits */ +var urlCommits = basePath + "/commits"; \ No newline at end of file diff --git a/src/main/resources/public/js/core.js b/src/main/resources/public/js/core.js index 216f411..2d6ff62 100644 --- a/src/main/resources/public/js/core.js +++ b/src/main/resources/public/js/core.js @@ -88,12 +88,12 @@ 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) { +function getFromRestWithParams(url, params, callBack, errorCallBack) { getCurrentVersion(function (version) { $.ajax({ url: url + "?versionId=" + version + params, diff --git a/src/main/resources/public/js/odin.js b/src/main/resources/public/js/odin.js new file mode 100644 index 0000000..384c496 --- /dev/null +++ b/src/main/resources/public/js/odin.js @@ -0,0 +1,1512 @@ +// form config.js +/* global uiLocale, urlVersions */ +// from core.js +/* global isEmpty, deleteFromRest, fillSelect, MessageTypesEnum, showFeedbackMessage, getCurrentVersionData */ +/* global getFromRestWithVersionAndParams, getFromRestWithVersion, getFromRest */ +/* global postToRestWithVersionAndParams, putToRestWithVersionAndParams */ + +// TODO: settings for table selection mode (single, multiple) + +var odinMetaList = "/meta/list"; +var odinMetaElement = "/meta/element"; +var odinCopy = "/copy-from-version"; + +/* exported OdinTableWithMeta */ +function OdinTableWithMeta(divId, dataUrl, disableCopy) { + return OdinTableWithMetaAndParams(divId, dataUrl, "", disableCopy, ""); +} + +/* exported OdinTableWithMetaAndGlobalCallback */ +function OdinTableWithMetaAndGlobalCallback(divId, dataUrl, disableCopy, globalSaveCallback, globalSelectCallback) { + return OdinTableWithMetaAndParams(divId, dataUrl, "", disableCopy, globalSaveCallback, globalSelectCallback); +} + +/* exported OdinTableWithMetaAndParams */ +function OdinTableWithMetaAndParams(divId, dataUrl, params, disableCopy, globalSaveCallback, globalSelectCallback) { + return new OdinTable(divId, dataUrl + odinMetaList, dataUrl + odinMetaElement, dataUrl, + params, disableCopy, globalSaveCallback, globalSelectCallback); +} + +function OdinTable(divId, listMetaDataUrl, elementMetaDataUrl, dataUrl, params, disableCopy, globalSaveCallback, globalSelectCallback) { + var CLICK_DELAY = 250; + var DATA_ATTR = "odin-data"; + var DATA_VIEW_ATTR = "odin-data-view"; + var TYPE_ATTR = "type"; + var ID_ATTR = "id"; + var DISABLED_ATTR = "disabled"; + var REQUIRED_ATTR = "required"; + var LABELS_SELECTOR = "label"; + var INPUTS_SELECTOR = ":input"; + var BUTTONS_SELECTOR = ":button"; + var CHECKED_ATTR = "checked"; + var NOT_CHECKED_ATTR = ""; + var PAGINATOR_ITEMS_PER_PAGE = 10; + var PAGINATOR_VISIBLE_BUTTONS_COUNT = 3; + var odinTable; + + var L10nEnum = { + VIEW: "Наименование", + COLLECTION: "Коллеция объектов", + GO_TO: "Перейти", + + BUTTON_ADD: "Добавить", + BUTTON_CREATE: "Создать", + BUTTON_EDIT: "Изменить", + BUTTON_DELETE: "Удалить", + + BUTTON_COPY: "Копировать", + + BUTTON_OK: "Продолжить", + BUTTON_CANCEL: "Отмена", + + BUTTON_SAVE: "Записать", + BUTTON_CLOSE: "Закрыть", + + CAPTION_CREATE_FORM: "Новый элемент", + CAPTION_EDIT_FORM: "(редактирование)", + CAPTION_CHOOSE_FORM: "Выбор объекта", + CAPTION_COPY_FORM: "Копирование данных", + CAPTION_DEFAULT_TAB: "Реквизиты", + CPATION_FORM_DEFAULT: "...", + + QUESTION_LOST_CHANGES: "Закрыть без сохранения?", + QUESTION_DELETE_ITEM: "Выполнить удаление?", + QUESTION_DEFAULT_CAPTION: "Продолжит?", + + ERROR_VERSIONS_MATCH: "Версии совпадают" + }; + Object.freeze(L10nEnum); + + var FieldTypesEnum = { + BOOLEAN: "boolean", + DATE: "date", + NUMERIC: "numeric", + STRING: "string", + COLLECTION: "collection", + OBJECT: "object" + }; + Object.freeze(FieldTypesEnum); + + var DateTypesEnum = { + DATETIME: "datetime", + DATE: "date", + TIME: "time" + }; + Object.freeze(DateTypesEnum); + + var StringTypesEnum = { + STRING: "string", + PASSWORD: "password", + TEXT: "text", + EMAIL: "email", + HREF: "href" + }; + Object.freeze(StringTypesEnum); + + var VisibleTypesEnum = { + ALL: "all", + ON_CREATE: "on_create", + ON_UPDATE: "on_update", + NONE: "none" + }; + Object.freeze(VisibleTypesEnum); + + var InputTypesEnum = { + CHECKBOX: "checkbox", + PASSWORD: "password", + TEXT: "text", + EMAIL: "email", + DATE: "date", + DATETIME: "datetime-local", + TIME: "time", + NUMBER: "number", + HIDDEN: "hidden", + SUBMIT: "submit" + }; + Object.freeze(InputTypesEnum); + + var FormTypesEnum = { + FORM: "form", + CONFIRM: "confirm", + SIMPLE: "simple" + }; + Object.freeze(FormTypesEnum); + + var NumberAttrEnum = { + MIN: "min", + MAX: "max", + STEP: "step" + }; + Object.freeze(NumberAttrEnum); + + var StringAttrEnum = { + MIN: "minlength", + MAX: "maxlength" + }; + Object.freeze(StringAttrEnum); + + $(document.body).append("
"); + $("#odinTemplates").load("/templates/odin.html", function () { + $("#" + divId).append("
" + + " " + + "
"); + odinTable = new OdinTableMain(divId, listMetaDataUrl, elementMetaDataUrl, dataUrl, params, disableCopy, globalSaveCallback, globalSelectCallback); + }); + + this.getSelectedItems = function () { + return odinTable.getSelectedItems(); + } + + function format(str, args) { + if (isEmpty(str) || isEmpty(args)) { + return str; + } + if (!Array.isArray(args)) { + throw "Odin: Format args is not array"; + } + return str.replace(/\{(\d+)\}/g, + function (match, number) { + return typeof args[number] !== "undefined" ? + args[number] : match; + }); + } + + function centerDiv(component) { + if (isEmpty(component)) { + return; + } + component.offset({ + top: ($(window).height() - component.height()) / 2, + left: ($(window).width() - component.width()) / 2 + }); + } + + function tmpl(id) { + var html = $("#odinTemplates").find("#" + id).html(); + if (isEmpty(html)) { + throw "Odin: Template load error"; + } + var template = format(html.trim(), Array.prototype.slice.call(arguments, 1)); + return $(template); + } + + function find(object, selector) { + var result = object.find(selector); + if (isEmpty(result)) { + throw "Can't find elements by selector " + selector; + } + return result; + } + + function findFiltered(object, selector, notSelector) { + var result = object.find(selector).not(notSelector); + if (isEmpty(result)) { + throw "Can't find elements by selector " + selector; + } + return result; + } + + function OdinFormCommon(type) { + var BUTTON_CLOSE_SELECTOR = "i.fa"; + var CAPTION_SELECTOR = "#caption"; + var PANEL_SELECTOR = ".panel"; + var FORM_INPUTS_SELECTOR = ":input"; + var DATA_CHANGED_ATTR = "changed"; + + var form; + var header; + var content; + var footer; + + var createForm = function () { + switch (type) { + case FormTypesEnum.FORM: + form = tmpl("form"); + break; + case FormTypesEnum.CONFIRM: + form = tmpl("formConfirm"); + break; + default: + form = tmpl("formSimple"); + } + if (isEmpty(form)) { + throw "Odin: Unknown form type"; + } + header = createFormHeader(); + content = createFormContent(); + footer = createFormFooter(); + var formPanel = tmpl("formPanel"); + formPanel.append(header); + formPanel.append(content); + formPanel.append(footer); + form.append(formPanel); + setCaption(L10nEnum.CPATION_FORM_DEFAULT); + $(document.body).append(form); + }; + + var createFormHeader = function () { + var fHeader = tmpl("formHeader"); + fHeader.find(BUTTON_CLOSE_SELECTOR).click(function () { + hideForm(); + }); + return fHeader; + }; + + var createFormContent = function () { + return tmpl("formContent"); + }; + + var createFormFooter = function () { + return tmpl("formFooter"); + }; + + var setCaption = function (caption) { + if (isEmpty(caption)) { + throw "Odin: Caption is not set"; + } + find(header, CAPTION_SELECTOR).text(caption); + }; + + var addFormClass = function (clazz) { + if (isEmpty(clazz)) { + throw "Odin: Additional class is not set"; + } + form.addClass(clazz); + }; + + var isModified = function () { + return form.data(DATA_CHANGED_ATTR); + }; + + var setFormSubmit = function (callBack) { + if (isEmpty(callBack)) { + throw "Odin: Callback is not set"; + } + form.submit(function () { + callBack(); + return false; + }); + }; + + var showForm = function () { + form.show(0, function () { + centerDiv(find(form, PANEL_SELECTOR)); + }); + if (type === FormTypesEnum.FORM) { + find(form, FORM_INPUTS_SELECTOR).change(function () { + form.data(DATA_CHANGED_ATTR, true); + }); + } + }; + + var hideForm = function () { + var callBack = function () { + form.hide(); + form.remove(); + }; + callBack(); + }; + + this._getHeader = function () { + return header; + }; + + this._getContent = function () { + return content; + }; + + this._getFooter = function () { + return footer; + }; + + this._setCaption = function (caption) { + setCaption(caption); + }; + + this._setFormSubmit = function (callBack) { + setFormSubmit(callBack); + }; + + this._addFormClass = function (clazz) { + addFormClass(clazz); + }; + + this._isModified = function () { + return isModified(); + }; + + this._show = function () { + showForm(); + }; + + this._hide = function () { + hideForm(); + }; + + createForm(); + } + + function OdinToolbar(tableDiv, createCallBack, editCallBack, deleteCallBack) { + var SELECTOR_ODIN_TABLE = ".odin-table"; + + var toolbar; + + var createButton; + var editButton; + var deleteButton; + + var initialize = function () { + if (isEmpty(tableDiv)) { + throw "Odin-Toolbar: Target div is not set"; + } + var table = find(tableDiv, SELECTOR_ODIN_TABLE); + toolbar = tmpl("toolbar"); + toolbar.insertBefore(table, null); + if (!isEmpty(createCallBack)) { + createButton = tmpl("createButton", L10nEnum.BUTTON_CREATE); + createButton.click(function () { + createCallBack(); + }); + toolbar.append(createButton); + } + if (!isEmpty(editCallBack)) { + editButton = tmpl("editButton", L10nEnum.BUTTON_EDIT); + editButton.click(function () { + editCallBack(); + }); + setEditButtonState(false); + toolbar.append(editButton); + } + if (!isEmpty(deleteCallBack)) { + deleteButton = tmpl("deleteButton", L10nEnum.BUTTON_DELETE); + deleteButton.click(function () { + deleteCallBack(); + }); + setDeleteButtonState(false); + toolbar.append(deleteButton); + } + }; + + var setEditButtonState = function (state) { + if (isEmpty(editButton)) { + return; + } + editButton.attr("disabled", !state); + }; + + var setDeleteButtonState = function (state) { + if (isEmpty(deleteButton)) { + return; + } + deleteButton.attr("disabled", !state); + }; + + this.addButton = function (caption, callBack) { + if (isEmpty(caption) || isEmpty(callBack)) { + throw "Odin-Toolbar: Caption or callback is not set"; + } + var button = tmpl("basicButton", caption); + button.click(function () { + callBack(); + }); + toolbar.append(button); + }; + + this.setEditButtonState = function (state) { + setEditButtonState(state); + }; + + this.setDeleteButtonState = function (state) { + setDeleteButtonState(state); + }; + + initialize(); + } + + function OdinPaginator(tableDiv, callBack) { + var SELECTOR_PAGINATOR_CONTENT = ".odin-paginator-content"; + var SELECTOR_PAGINATOR_BUTTON = "a"; + var PAGINATOR_BUTTON_PREFIX = "odin-paginator-"; + var PAGINATOR_SELECTED_BUTTON_CLASS = "active"; + + var initialize = function () { + if (isEmpty(tableDiv)) { + throw "Odin-Paginator: Target div is not set"; + } + if (isEmpty(callBack)) { + throw "Odin-Paginator: Callback is not set"; + } + tableDiv.append(tmpl("paginator")); + }; + + var drawPaginator = function (data, offset) { + var paginatorContentDiv = find(tableDiv, SELECTOR_PAGINATOR_CONTENT); + paginatorContentDiv.empty(); + if (isEmpty(data)) { + return; + } + $.each(data, function (index, value) { + if (value.name) { + paginatorContentDiv.append(tmpl("paginatorButton", value.offset, value.name)); + } else { + paginatorContentDiv.append(tmpl("paginatorSeparator")); + } + }); + var buttons = find(paginatorContentDiv, SELECTOR_PAGINATOR_BUTTON); + buttons.removeClass("active"); + buttons.click(function () { + $('#preloader').show(); + var offset = $(this).attr(ID_ATTR).replace(PAGINATOR_BUTTON_PREFIX, ""); + callBack(offset); + }); + find(paginatorContentDiv, "#" + PAGINATOR_BUTTON_PREFIX + offset) + .addClass(PAGINATOR_SELECTED_BUTTON_CLASS); + }; + + this.drawPaginator = function (offset, count) { + var currentOffset = parseInt(offset ? offset : "0"); + var buttonCount = Math.floor( + count <= PAGINATOR_ITEMS_PER_PAGE ? 0 : count / PAGINATOR_ITEMS_PER_PAGE) + + (count < PAGINATOR_ITEMS_PER_PAGE || + count % PAGINATOR_ITEMS_PER_PAGE === 0 ? 0 : 1); + var data = []; + Array.apply(0, Array(buttonCount)).forEach(function (element, index) { + if (index > 0 && index < buttonCount - 1 && + buttonCount > PAGINATOR_VISIBLE_BUTTONS_COUNT * 2) { + if (index === currentOffset - PAGINATOR_VISIBLE_BUTTONS_COUNT || + index === currentOffset + PAGINATOR_VISIBLE_BUTTONS_COUNT + 1) { + data.push({ + "offset": null, + "name": null + }); + } + if (index <= currentOffset - PAGINATOR_VISIBLE_BUTTONS_COUNT || + index > currentOffset + PAGINATOR_VISIBLE_BUTTONS_COUNT) { + return true; + } + } + data.push({ + "offset": index, + "name": index + 1 + }); + }); + drawPaginator(data, currentOffset); + }; + + initialize(); + } + + function OdinTableFormatter() { + var BOOLEAN_TRUE_CLASS = "fa-check"; + var BOOLEAN_FALSE_CLASS = "fa-times"; + + var formatBooleanValue = function (value) { + return tmpl("tableBoolean", (value ? BOOLEAN_TRUE_CLASS : BOOLEAN_FALSE_CLASS)); + }; + + var formatDateValue = function (value, dateType) { + var date = new Date(value); + var formatterSettings = {}; + switch (dateType) { + case DateTypesEnum.DATETIME: + formatterSettings = { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric" + }; + break; + case DateTypesEnum.TIME: + formatterSettings = { + hour: "numeric", + minute: "numeric", + second: "numeric" + }; + break; + } + var dateFormatter = new Intl.DateTimeFormat(uiLocale, formatterSettings); + return dateFormatter.format(date); + }; + + var formatNumericValue = function (value, positiveOnly, scale) { + var numberFormatter = new Intl.NumberFormat(uiLocale, { + useGrouping: false, + minimumFractionDigits: scale + }); + var formattedValue = numberFormatter.format(value); + if (positiveOnly && value < 0) { + return tmpl("tableNumericNegative", formattedValue); + } + return formattedValue; + }; + + var formatStringValue = function (value, maxLength, stringType) { + switch (stringType) { + case StringTypesEnum.HREF: + return tmpl("anchor", value, L10nEnum.GO_TO); + default: + if (isEmpty(maxLength) || maxLength === 0) { + return value; + } + return value.substring(0, Math.min(value.length, maxLength)); + } + }; + + this.formatValue = function (value, fieldParams) { + if (isEmpty(value) || isEmpty(fieldParams)) { + return ""; + } + if (fieldParams.hidden) { + return value; + } + switch (fieldParams.fieldType) { + case FieldTypesEnum.BOOLEAN: + return formatBooleanValue(value); + case FieldTypesEnum.DATE: + return formatDateValue(value, fieldParams.type); + case FieldTypesEnum.NUMERIC: + return formatNumericValue(value, fieldParams.positiveOnly, fieldParams.scale); + case FieldTypesEnum.STRING: + return formatStringValue(value, fieldParams.maxLength, fieldParams.type); + case FieldTypesEnum.COLLECTION: + return L10nEnum.COLLECTION; + case FieldTypesEnum.OBJECT: + return value.view; + default: + return value; + } + }; + } + + function OdinTableView(odinDiv, editCallback, globalSelectCallback) { + var TABLEVIEW_SELECTED_LINE_CLASS = "odin-table-selected-line"; + var TABLEVIEW_LINE_SELECTOR = "tr"; + var TABLEVIEW_SELECTED_LINE_SELECTOR = TABLEVIEW_LINE_SELECTOR + + "." + TABLEVIEW_SELECTED_LINE_CLASS; + var TABLEVIEW_LINE_DATA_SELECTOR = TABLEVIEW_LINE_SELECTOR + + "[" + DATA_ATTR + "=\"{0}\"]"; + var TABLEVIEW_CHOOSABLE_CLASS = "table-hover odin-unselectable"; + var TABLEVIEW_LINE_POINTED_CLASS = "odin-table-pointed-line"; + var TABLEVIEW_HEAD_COLUMN_SELECTOR = "th:nth-child({0})"; + var TABLEVIEW_BODY_COLUMN_SELECTOR = "td:nth-child({0})"; + + var tTable; + var tHead; + var tBody; + var choosable; + var formatter; + var toolbar; + + var createLine = function (idValue) { + var prevent = false; + var timer = 0; + var newLine = tmpl("tableLine"); + if (!isEmpty(idValue) && choosable) { + newLine.attr(DATA_ATTR, idValue); + newLine.click(function () { + var btn = $(this); + timer = setTimeout(function () { + if (!prevent) { + btn.toggleClass(TABLEVIEW_SELECTED_LINE_CLASS); + } + prevent = false; + if (!isEmpty(globalSelectCallback)) { + globalSelectCallback(getLines()); + } + if (!isEmpty(toolbar)) { + toolbar.setEditButtonState(!isEmpty(getLines())); + toolbar.setDeleteButtonState(!isEmpty(getLines())); + } + }, CLICK_DELAY); + }); + if (!isEmpty(editCallback)) { + newLine.dblclick(function () { + clearTimeout(timer); + prevent = true; + editCallback(idValue); + }); + } + newLine.addClass(TABLEVIEW_LINE_POINTED_CLASS); + } + return newLine; + }; + + var addLineToHead = function (line) { + tHead.append(line); + }; + + var addLineToBody = function (line) { + tBody.append(line); + }; + + var clearBody = function () { + tBody.empty(); + }; + + var initialize = function () { + if (isEmpty(odinDiv)) { + throw "Odin: Odin div is not set"; + } + odinDiv.append(tmpl("table")); + tTable = find(odinDiv, "table"); + tHead = find(odinDiv, "thead"); + tBody = find(odinDiv, "tbody"); + formatter = new OdinTableFormatter(); + }; + + var getLines = function (isAll) { + var selector = isAll ? TABLEVIEW_LINE_SELECTOR : TABLEVIEW_SELECTED_LINE_SELECTOR; + var selectedItems = []; + try { + find(tBody, selector).each(function () { + selectedItems.push({ + id: $(this).attr(DATA_ATTR), + view: $(this).attr(DATA_VIEW_ATTR) + }); + }); + } catch (e) { + // Ignore + } + return selectedItems; + }; + + var disableToolbar = function () { + if (isEmpty(toolbar)) { + return; + } + toolbar.setEditButtonState(false); + toolbar.setDeleteButtonState(false); + }; + + this.createHead = function (metaData, isOdinDto) { + if (isEmpty(metaData)) { + throw "Odin: Metadata is not set"; + } + choosable = isOdinDto; + if (choosable) { + tTable.addClass(TABLEVIEW_CHOOSABLE_CLASS); + } + var tHeadLine = createLine(); + $.each(metaData, function (index, value) { + tHeadLine.append(tmpl("tableHeadColumn", value.caption)); + }); + addLineToHead(tHeadLine); + $.each(metaData, function (columnIndex, columnParams) { + if (columnParams.visible === VisibleTypesEnum.NONE) { + var index = columnIndex + 1; + find(tHead, format(TABLEVIEW_HEAD_COLUMN_SELECTOR, [index])).hide(); + } + }); + }; + + this.fillBody = function (metaData, data) { + clearBody(); + $.each(data, function (index, value) { + var idValue = choosable ? value.id : null; + var line = createLine(idValue); + line.attr(DATA_VIEW_ATTR, value.view); + $.each(metaData, function (columnIndex, columnParams) { + var column = tmpl("tableBodyColumn"); + column.append( + formatter.formatValue(value[columnParams.fieldName], + columnParams)); + line.append(column); + }); + addLineToBody(line); + }); + if (!isEmpty(data)) { + $.each(metaData, function (columnIndex, columnParams) { + if (columnParams.visible === VisibleTypesEnum.NONE) { + var index = columnIndex + 1; + find(tBody, format(TABLEVIEW_BODY_COLUMN_SELECTOR, [index])).hide(); + } + }); + } + }; + + this.getSelectedItems = function () { + return getLines(false); + }; + + this.getItems = function () { + return getLines(true); + }; + + // Delete form view only! + this.deleteById = function (id) { + if (isEmpty(id)) { + return; + } + try { + find(tBody, format(TABLEVIEW_LINE_DATA_SELECTOR, [id])).remove(); + disableToolbar(); + } catch (e) { + // Ignore + } + }; + + this.setToolbar = function (toolbarVar) { + toolbar = toolbarVar; + }; + + this.disableToolbar = function () { + disableToolbar(); + }; + + initialize(); + } + + function OdinTableMain(divId, listMetaDataUrl, elementMetaDataUrl, dataUrl, args, disableCopy, globalSaveCallback, globalSelectCallback) { + if (isEmpty(divId) || isEmpty(listMetaDataUrl) || isEmpty(dataUrl)) { + throw "Odin: Not enough parameters"; + } + + var OFFSET_ARG = "&offset="; + var COUNT_ARG = "&count="; + + var odinDiv; + var tableView; + var paginator; + + var currentOffset; + + var listMetaData; + var elementMetaData; + + var params = isEmpty(args) ? "" : args; + + var drawBody = function (offset) { + if (isEmpty(listMetaData)) { + throw "Odin: Meta data is not defined"; + } + currentOffset = isEmpty(offset) ? 0 : parseInt(offset); + getFromRestWithVersionAndParams(dataUrl, + OFFSET_ARG + (currentOffset * PAGINATOR_ITEMS_PER_PAGE) + + COUNT_ARG + PAGINATOR_ITEMS_PER_PAGE + params, function (data) { + if (isEmpty(data)) { + throw "Odin: Response data is null"; + } + tableView.fillBody(listMetaData, data.items); + if (data.count > 0) { + paginator.drawPaginator(offset, data.count); + } + tableView.disableToolbar(); + $('#preloader').hide(); + }); + }; + + var initialize = function () { + odinDiv = find($(document.body), "#" + divId); + tableView = new OdinTableView(odinDiv, editItem, globalSelectCallback); + paginator = new OdinPaginator(odinDiv, drawBody); + getFromRest(listMetaDataUrl, function (data) { + if (isEmpty(data) || isEmpty(data.fields)) { + throw "Odin: Can't load list meta data"; + } + var isOdinDto = data.odinDto; + listMetaData = data.fields; + if (isOdinDto && !isEmpty(elementMetaDataUrl)) { + getFromRest(elementMetaDataUrl, function (data) { + if (isEmpty(data) || isEmpty(data.fields)) { + throw "Odin: Can't load element meta data"; + } + elementMetaData = data.fields; + var toolbar = new OdinToolbar(odinDiv, createItem, editItem, deleteItem, globalSaveCallback); + tableView.setToolbar(toolbar); + if (!disableCopy) { + toolbar.addButton(L10nEnum.BUTTON_COPY, function () { + new OdinCopyBox(dataUrl, drawBody); + }); + } + }); + } + tableView.createHead(listMetaData, isOdinDto); + drawBody(); + }); + }; + + var updateTable = function () { + // TODO: recalculate offset before redraw table + drawBody(currentOffset); + }; + + var createItem = function () { + new OdinForm(elementMetaData, dataUrl, updateTable, null, params); + }; + + var editItem = function (value) { + if (isEmpty(elementMetaDataUrl)) { + return; + } + var curValue = value; + if (isEmpty(value)) { + var selectedItems = tableView.getSelectedItems(); + if (!isEmpty(selectedItems)) { + curValue = selectedItems[0].id; + } + } + if (isEmpty(curValue)) { + return; + } + new OdinForm(elementMetaData, dataUrl, updateTable, curValue, params); + }; + + var deleteItem = function () { + var selectedItems = tableView.getSelectedItems(); + if (isEmpty(selectedItems)) { + return; + } + var callBack = function () { + $.each(selectedItems, function (index, value) { + deleteFromRest(dataUrl + "/" + value.id, null, function () { + if (index === selectedItems.length - 1) { + updateTable(); + } + }); + }); + }; + new OdinConfirmBox(callBack, L10nEnum.QUESTION_DELETE_ITEM); + }; + + this.getSelectedItems = function () { + return tableView.getSelectedItems(); + }; + + initialize(); + } + + function OdinFormControlGenerator() { + this.createInputGroup = function () { + return tmpl("formInputGroup"); + }; + + this.createLabel = function (id, caption) { + return tmpl("formLabel", id, caption); + }; + + var createInput = function (id, value, type) { + if (isEmpty(id)) { + throw "Odin: Input id is not set"; + } + if (isEmpty(type)) { + throw "Odin: Input type is not set"; + } + var curValue = isEmpty(value) ? "" : value; + var wrapper = tmpl("formInputWrapper"); + if (type === InputTypesEnum.CHECKBOX) { + wrapper.append(tmpl("formInputCheckbox", + id, (curValue ? CHECKED_ATTR : NOT_CHECKED_ATTR))); + } else { + wrapper.append(tmpl("formInput", + id, curValue, type)); + } + return wrapper; + }; + + this.createBooleanInput = function (id, value) { + return createInput(id, value, InputTypesEnum.CHECKBOX); + }; + + var fixDateUnit = function (dateUnitValue) { + return dateUnitValue < 10 ? "0" + dateUnitValue : dateUnitValue; + }; + + var dateToStr = function (value, type) { + if (isEmpty(value)) { + return ""; + } + var date = new Date(value); + var year = fixDateUnit(date.getFullYear()); + var month = fixDateUnit(date.getMonth() + 1); + var day = fixDateUnit(date.getDate()); + var hour = fixDateUnit(date.getHours()); + var minute = fixDateUnit(date.getMinutes()); + var formattedDate; + switch (type) { + case DateTypesEnum.DATETIME: + formattedDate = year + "-" + month + "-" + day + "T" + hour + ":" + minute; + break; + case DateTypesEnum.TIME: + formattedDate = hour + ":" + minute; + break; + default: + formattedDate = year + "-" + month + "-" + day; + } + return formattedDate; + }; + + this.createDateInput = function (id, value, type) { + var dateType; + switch (type) { + case DateTypesEnum.DATETIME: + dateType = InputTypesEnum.DATETIME; + break; + case DateTypesEnum.TIME: + dateType = InputTypesEnum.TIME; + break; + default: + dateType = InputTypesEnum.DATE; + } + return createInput(id, dateToStr(value, type), dateType); + }; + + this.createNumericInput = function (id, value) { + return createInput(id, value, InputTypesEnum.NUMBER); + }; + + this.createStringInput = function (id, value, type) { + var stringType; + switch (type) { + case StringTypesEnum.PASSWORD: + stringType = InputTypesEnum.PASSWORD; + break; + case StringTypesEnum.EMAIL: + stringType = InputTypesEnum.EMAIL; + break; + default: + stringType = InputTypesEnum.TEXT; + } + return createInput(id, value, stringType); + }; + + this.dateToStr = function (value, type) { + return dateToStr(value, type); + }; + } + + function OdinFormContentGenerator(createNavTabCallBack, isCreateOperation) { + var PRECISION_CHAR = "9"; + var SCALE_PREFIX = "0."; + var SCALE_CHAR = "0"; + var SCALE_POSTFIX = "1"; + var OBJECT_INPUT_CLASS = "input-group odin-input-group"; + var CREATE_BUTTON_TEXT_SELECTOR = ".btn-success > span"; + var CHOOSE_BTN_SELECTOR = ".odin-choose-btn"; + var CLEAR_BTN_SELECTOR = ".odin-clear-btn"; + var CLEARABLE_INPUT_SELECTOR = ".form-control"; + + var controlGenerator = new OdinFormControlGenerator(); + + var createBooleanControl = function (id, caption, value) { + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + group.append(controlGenerator.createBooleanInput(id, value)); + return group; + }; + + var createDateControl = function (id, caption, value, type) { + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + group.append(controlGenerator.createDateInput(id, value, type)); + return group; + }; + + var createNumericControl = function (id, caption, value, positiveOnly, precision, scale) { + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + var control = controlGenerator.createNumericInput(id, value); + find(control, INPUTS_SELECTOR).each(function () { + var currentControl = $(this); + if (positiveOnly) { + currentControl.attr(NumberAttrEnum.MIN, 0); + } + if (precision) { + currentControl + .attr(NumberAttrEnum.MAX, Array(precision + 1).join(PRECISION_CHAR)); + } + if (scale) { + var step = SCALE_PREFIX + Array(scale).join(SCALE_CHAR) + SCALE_POSTFIX; + currentControl.attr(NumberAttrEnum.STEP, step); + } + }); + group.append(control); + return group; + }; + + var createStringControl = function (id, caption, value, minLength, maxLength, type) { + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + var control = controlGenerator.createStringInput(id, value, type); + find(control, INPUTS_SELECTOR).each(function () { + var currentControl = $(this); + currentControl.attr(StringAttrEnum.MIN, minLength); + currentControl.attr(StringAttrEnum.MAX, maxLength); + }); + group.append(control); + return group; + }; + + var createCollectionControl = function (id, caption, values, path) { + // TODO: add required check if needed + var content = $(tmpl("emptyDiv")); + var tabView = new OdinTableView(content, null, null); + var createAction = function () { + new OdinChooseBox(path, function (selectedItems) { + if (isEmpty(selectedItems)) { + return; + } + var currentValues = tabView.getItems(); + $.merge(currentValues, selectedItems); + var existingIDs = []; + currentValues = $.grep(currentValues, function (v) { + if ($.inArray(v.id, existingIDs) !== -1) { + return false; + } else { + existingIDs.push(v.id); + return true; + } + }); + tabView.fillBody(metaData, currentValues); + }); + }; + var deleteAction = function () { + var callBack = function () { + $.each(tabView.getSelectedItems(), function (index, value) { + tabView.deleteById(value.id); + }); + }; + new OdinConfirmBox(callBack, L10nEnum.QUESTION_DELETE_ITEM); + }; + content.append(tabView); + var metaData = [ + { + "fieldType": "string", + "fieldName": "id", + "caption": "id", + "visible": "none" + }, + { + "fieldType": "string", + "fieldName": "view", + "caption": L10nEnum.VIEW, + "visible": "all" + } + ]; + tabView.createHead(metaData, true); + tabView.fillBody(metaData, values); + createNavTabCallBack(id, caption, content); + var toolbar = new OdinToolbar(content, createAction, null, deleteAction); + tabView.setToolbar(toolbar); + find(content, CREATE_BUTTON_TEXT_SELECTOR).text(L10nEnum.BUTTON_ADD); + return null; + }; + + var createObjectControl = function (id, caption, value, path) { + // TODO: add required check if needed + var chooseInput = controlGenerator.createStringInput( + id, isEmpty(value) ? "" : value.view, StringTypesEnum.TEXT); + chooseInput.addClass(OBJECT_INPUT_CLASS); + var buttonGroup = tmpl("buttonGroup"); + chooseInput.append(buttonGroup); + var chooseButton = tmpl("chooseButton"); + buttonGroup.append(chooseButton); + find(buttonGroup, CHOOSE_BTN_SELECTOR).click(function () { + new OdinChooseBox(path, function (selectedItems) { + if (isEmpty(selectedItems)) { + return; + } + find(chooseInput, CLEARABLE_INPUT_SELECTOR).each(function () { + $(this) + .val(selectedItems[0].view) + .attr(DATA_ATTR, selectedItems[0].id); + }); + }); + }); + var clearButton = tmpl("clearButton"); + buttonGroup.append(clearButton); + find(buttonGroup, CLEAR_BTN_SELECTOR).click(function () { + find(chooseInput, CLEARABLE_INPUT_SELECTOR).val(""); + }); + find(chooseInput, CLEARABLE_INPUT_SELECTOR).each(function () { + $(this) + .attr(DISABLED_ATTR, true) + .attr(DATA_ATTR, isEmpty(value) ? "" : value.id); + }); + var group = controlGenerator.createInputGroup(); + group.append(controlGenerator.createLabel(id, caption)); + group.append(chooseInput); + return group; + }; + + var configureControl = function (control, hidden, readonly, notempty) { + if (isEmpty(control)) { + return; + } + find(control, LABELS_SELECTOR).each(function () { + var currentControl = $(this); + if (hidden) { + currentControl.hide(); + } + }); + find(control, INPUTS_SELECTOR).each(function () { + var currentControl = $(this); + if (hidden) { + currentControl.hide(); + currentControl.attr(TYPE_ATTR, InputTypesEnum.HIDDEN); + } + if (readonly) { + currentControl.attr(DISABLED_ATTR, true); + } + if (notempty) { + currentControl.attr(REQUIRED_ATTR, true); + } + }); + return control; + }; + + this.createFormControl = function (value, fieldParams) { + if (isEmpty(fieldParams)) { + return null; + } + var control; + switch (fieldParams.fieldType) { + case FieldTypesEnum.BOOLEAN: + control = createBooleanControl(fieldParams.fieldName, + fieldParams.caption, value); + break; + case FieldTypesEnum.DATE: + control = createDateControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.type); + break; + case FieldTypesEnum.NUMERIC: + control = createNumericControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.positiveOnly, + fieldParams.precision, fieldParams.scale); + break; + case FieldTypesEnum.STRING: + control = createStringControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.minLength, + fieldParams.maxLength, fieldParams.type); + break; + case FieldTypesEnum.COLLECTION: + control = createCollectionControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.path); + break; + case FieldTypesEnum.OBJECT: + control = createObjectControl(fieldParams.fieldName, + fieldParams.caption, value, fieldParams.path); + break; + default: + return null; + } + var hidden; + switch (fieldParams.visible) { + case VisibleTypesEnum.NONE: + hidden = true; + break; + case VisibleTypesEnum.ON_CREATE: + case VisibleTypesEnum.ON_UPDATE: + hidden = isCreateOperation; + break; + default: + hidden = false; + } + return configureControl(control, hidden, fieldParams.readOnly, fieldParams.notEmpty); + }; + + this.getCurrentDateStr = function () { + return controlGenerator.dateToStr(new Date(), DateTypesEnum.DATE); + }; + } + + function OdinForm(metaData, dataUrl, tableCallBack, id, args) { + if (isEmpty(metaData) || isEmpty(dataUrl) || isEmpty(tableCallBack)) { + throw "Odin: Not enough parameters"; + } + + var DEFAULT_TAB_SELECTOR = "odin-values"; + var TABS_HEADER_SELECTOR = ".nav-tabs"; + var TABS_CONTENT_SELECTOR = ".tab-content"; + var TAB_SELECTOR = ".tab-pane"; + var COLLECTION_ITEM_SELECTOR = "tbody > tr"; + + OdinFormCommon.call(this, FormTypesEnum.FORM); + + var self = this; + + var generator; + + var params = isEmpty(args) ? "" : args; + + var isCreateForm = function () { + return isEmpty(id); + }; + + var formToJson = function () { + var formData = {}; + try { + findFiltered(self._getContent(), TAB_SELECTOR, "#" + DEFAULT_TAB_SELECTOR) + .each(function () { + var tabData = []; + try { + find($(this), COLLECTION_ITEM_SELECTOR) + .each(function () { + if ($(this).attr(DATA_ATTR)) { + tabData.push({ + id: $(this).attr(DATA_ATTR), + view: $(this).attr(DATA_VIEW_ATTR) + }); + return true; + } + }); + } catch (e) { + // Ignore + } + formData[$(this).attr(ID_ATTR)] = tabData; + }); + } catch (e) { + // Ignore + } + findFiltered(self._getContent(), INPUTS_SELECTOR, BUTTONS_SELECTOR) + .each(function () { + if (isEmpty($(this).val())) { + return true; + } + if ($(this).attr(DATA_ATTR)) { + formData[$(this).attr(ID_ATTR)] = { + id: $(this).attr(DATA_ATTR), + view: $(this).val() + }; + return true; + } + switch ($(this).attr(TYPE_ATTR)) { + case InputTypesEnum.CHECKBOX: + formData[$(this).attr(ID_ATTR)] = $(this).is(":" + CHECKED_ATTR); + break; + case InputTypesEnum.DATE: + case InputTypesEnum.DATETIME: + formData[$(this).attr(ID_ATTR)] = isEmpty($(this).val) ? + "" : Date.parse($(this).val()); + break; + case InputTypesEnum.TIME: + formData[$(this).attr(ID_ATTR)] = isEmpty($(this).val) ? + "" : Date.parse(generator.getCurrentDateStr() + + "T" + $(this).val()); + break; + case InputTypesEnum.NUMBER: + formData[$(this).attr(ID_ATTR)] = parseFloat($(this).val()); + break; + default: + formData[$(this).attr(ID_ATTR)] = $(this).val(); + } + }); + return JSON.stringify(formData); + }; + + var initialize = function () { + generator = new OdinFormContentGenerator(createNavTab, isCreateForm()); + self._getContent() + .append(tmpl("formTabs", DEFAULT_TAB_SELECTOR, L10nEnum.CAPTION_DEFAULT_TAB)); + var okBtn = tmpl("okButton", L10nEnum.BUTTON_SAVE); + okBtn.attr(TYPE_ATTR, InputTypesEnum.SUBMIT); + var closeBtn = tmpl("cancelButton", L10nEnum.BUTTON_CLOSE); + self._getFooter().append(closeBtn); + self._getFooter().append(okBtn); + if (isCreateForm()) { + configureAndShowForm(); + } else { + getFromRestWithVersion(dataUrl + "/" + id, function (data) { + if (isEmpty(data)) { + throw format("Odin: Can't load data by id {0} and url {1}", [id, dataUrl]); + } + configureAndShowForm(data); + }); + } + closeBtn.click(function () { + closeForm(); + }); + }; + + var configureAndShowForm = function (data) { + var saveCallBack = function () { + saveData(formToJson()); + }; + self._setCaption(isEmpty(data) ? + L10nEnum.CAPTION_CREATE_FORM : + data.view + " " + L10nEnum.CAPTION_EDIT_FORM); + self._setFormSubmit(saveCallBack); + $.each(metaData, function (fieldIndex, fieldParams) { + var value = isEmpty(data) ? + null : data[fieldParams.fieldName]; + find(self._getContent(), "#" + DEFAULT_TAB_SELECTOR) + .append(generator.createFormControl(value, fieldParams)); + }); + self._show(); + }; + + var createNavTab = function (id, caption, content) { + find(self._getContent(), TABS_HEADER_SELECTOR).append(tmpl("formTab", id, caption)); + var tab = tmpl("formTabContent", id); + tab.append(content); + find(self._getContent(), TABS_CONTENT_SELECTOR).append(tab); + }; + + var saveData = function (data) { + var saveCallback = function (responseData) { + if (isEmpty(responseData)) { + throw "Odin: Error on data save"; + } + self._hide(); + tableCallBack(); + if (!isEmpty(globalSaveCallback)) { + globalSaveCallback(); + } + }; + if (isCreateForm()) { + postToRestWithVersionAndParams(dataUrl, data, params, saveCallback); + } else { + putToRestWithVersionAndParams(dataUrl, data, params, saveCallback); + } + }; + + var closeForm = function () { + if (self._isModified()) { + new OdinConfirmBox(self._hide, L10nEnum.QUESTION_LOST_CHANGES); + return; + } + self._hide(); + }; + + initialize(); + } + + function OdinConfirmBox(callBack, questionText) { + if (isEmpty(callBack) || isEmpty(questionText)) { + throw "Odin: Not enough parameters"; + } + + OdinFormCommon.call(this, FormTypesEnum.CONFIRM); + + var self = this; + + var initialize = function () { + var yesBtn = tmpl("okButton", L10nEnum.BUTTON_OK); + var cancelBtn = tmpl("cancelButton", L10nEnum.BUTTON_CANCEL); + self._setCaption(L10nEnum.QUESTION_DEFAULT_CAPTION); + self._getContent().text(questionText); + self._getFooter().append(yesBtn); + self._getFooter().append(cancelBtn); + self._show(); + + yesBtn.click(function () { + self._hide(); + callBack(); + if (!isEmpty(globalSaveCallback)) { + globalSaveCallback(); + } + }); + cancelBtn.click(function () { + self._hide(); + }); + }; + + initialize(); + } + + function OdinChooseBox(path, callBack) { + if (isEmpty(path) || isEmpty(callBack)) { + throw "Odin: Not enough parameters"; + } + + var ADDITIONAL_FORM_CLASS = "odin-table-box"; + var ADDITIONAL_CONTENT_CLASS = "odin-kill-padding"; + var CONTENT_ID_VALUE = "table-block"; + + OdinFormCommon.call(this); + + var self = this; + + var initialize = function () { + self._addFormClass(ADDITIONAL_FORM_CLASS); + self._getContent().addClass(ADDITIONAL_CONTENT_CLASS); + self._getContent().attr(ID_ATTR, CONTENT_ID_VALUE); + var yesBtn = tmpl("okButton", L10nEnum.BUTTON_OK); + var cancelBtn = tmpl("cancelButton", L10nEnum.BUTTON_CANCEL); + self._getFooter().append(cancelBtn); + self._getFooter().append(yesBtn); + var table = new OdinTableMain("table-block", path + odinMetaList, null, path); + self._show(); + + yesBtn.click(function () { + self._hide(); + callBack(table.getSelectedItems()); + }); + cancelBtn.click(function () { + self._hide(); + }); + }; + + initialize(); + } + + function OdinCopyBox(dataUrl, tableRedrawCallback) { + if (isEmpty(dataUrl) || isEmpty(tableRedrawCallback)) { + throw "Odin: Not enough parameters"; + } + + var ADDITIONAL_FORM_CLASS = "odin-simple-form"; + var FROM_VERSION_SELECTOR = "#fromVersion"; + var VERSION_SELECTOR = "#version"; + + OdinFormCommon.call(this); + + var self = this; + + var initialize = function () { + self._setCaption(L10nEnum.CAPTION_COPY_FORM); + self._addFormClass(ADDITIONAL_FORM_CLASS); + self._getContent().append(tmpl("copyForm")); + var from = find(self._getContent(), FROM_VERSION_SELECTOR); + var to = find(self._getContent(), VERSION_SELECTOR); + var yesBtn = tmpl("okButton", L10nEnum.BUTTON_OK); + var cancelBtn = tmpl("cancelButton", L10nEnum.BUTTON_CANCEL); + self._getFooter().append(cancelBtn); + self._getFooter().append(yesBtn); + + getFromRest(urlVersions, function (versions) { + if (isEmpty(versions) || versions.count === 0) { + return; + } + var versionsData = []; + versions.items.forEach(function (version) { + versionsData.push({ + id: version.id, + name: version.name + " от " + + new Date(version.date).toLocaleDateString(uiLocale) + }); + }); + fillSelect(from, versionsData.sort(function (a, b) { + return a.id - b.id; + })); + var currentVersion = getCurrentVersionData(); + if (!isEmpty(currentVersion)) { + to.attr(DATA_ATTR, currentVersion.id); + to.val(currentVersion.name); + } + self._show(); + }); + + yesBtn.click(function () { + if (isEmpty(from.val()) || isEmpty(to.val())) { + return; + } + if (from.val() === to.attr(DATA_ATTR)) { + showFeedbackMessage(L10nEnum.ERROR_VERSIONS_MATCH, MessageTypesEnum.DANGER); + return; + } + postToRestWithVersionAndParams(dataUrl + odinCopy, null, + "&fromVersionId=" + from.val(), function () { + self._hide(); + tableRedrawCallback(); + }); + }); + cancelBtn.click(function () { + self._hide(); + }); + }; + + initialize(); + } +} diff --git a/src/main/resources/public/templates/odin.html b/src/main/resources/public/templates/odin.html new file mode 100644 index 0000000..1f9f9d9 --- /dev/null +++ b/src/main/resources/public/templates/odin.html @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/default.html b/src/main/resources/templates/default.html index 9aae873..00e2c0f 100644 --- a/src/main/resources/templates/default.html +++ b/src/main/resources/templates/default.html @@ -23,6 +23,7 @@ + @@ -94,6 +95,10 @@ + + + + - - + + + + + +
+
+
+
+ +
+
+
+
+ + + + \ No newline at end of file From e93f6187791b0a2c9aea9a99e03000be152e3de8 Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Sun, 31 Mar 2019 13:12:43 +0400 Subject: [PATCH 41/45] #56 added database schema --- .../db/changelog-20190331_000010-schema.xml | 57 +++++++++++++++++++ src/main/resources/db/changelog-master.xml | 1 + 2 files changed, 58 insertions(+) create mode 100644 src/main/resources/db/changelog-20190331_000010-schema.xml diff --git a/src/main/resources/db/changelog-20190331_000010-schema.xml b/src/main/resources/db/changelog-20190331_000010-schema.xml new file mode 100644 index 0000000..26a98df --- /dev/null +++ b/src/main/resources/db/changelog-20190331_000010-schema.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog-master.xml b/src/main/resources/db/changelog-master.xml index 132e510..2f0764a 100644 --- a/src/main/resources/db/changelog-master.xml +++ b/src/main/resources/db/changelog-master.xml @@ -21,5 +21,6 @@ + \ No newline at end of file From 2ad03a5689d9f2f6d87f2b8d45476443c1c1f118 Mon Sep 17 00:00:00 2001 From: ASH Date: Sun, 31 Mar 2019 13:47:15 +0400 Subject: [PATCH 42/45] #71 adding dashboard --- .../templates/students/dashboard.html | 2 ++ .../fragments/taskDashboardFragment.html | 24 +++++++++++++++++++ .../fragments/taskNavigationFragment.html | 2 +- .../fragments/taskStatusFragment.html | 1 + 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/templates/students/fragments/taskDashboardFragment.html diff --git a/src/main/resources/templates/students/dashboard.html b/src/main/resources/templates/students/dashboard.html index d9f6e8a..94ea121 100644 --- a/src/main/resources/templates/students/dashboard.html +++ b/src/main/resources/templates/students/dashboard.html @@ -12,7 +12,9 @@

Работа со студентами

+
+
diff --git a/src/main/resources/templates/students/fragments/taskDashboardFragment.html b/src/main/resources/templates/students/fragments/taskDashboardFragment.html new file mode 100644 index 0000000..0daea58 --- /dev/null +++ b/src/main/resources/templates/students/fragments/taskDashboardFragment.html @@ -0,0 +1,24 @@ + + + + + + +
+
+
+ + +
+
+ + + title +

type

+
+
+
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/students/fragments/taskNavigationFragment.html b/src/main/resources/templates/students/fragments/taskNavigationFragment.html index cf8a4cf..717930d 100644 --- a/src/main/resources/templates/students/fragments/taskNavigationFragment.html +++ b/src/main/resources/templates/students/fragments/taskNavigationFragment.html @@ -9,7 +9,7 @@ Список
diff --git a/src/main/resources/templates/students/fragments/taskStatusFragment.html b/src/main/resources/templates/students/fragments/taskStatusFragment.html index 9af7d50..8f3d800 100644 --- a/src/main/resources/templates/students/fragments/taskStatusFragment.html +++ b/src/main/resources/templates/students/fragments/taskStatusFragment.html @@ -5,6 +5,7 @@ +
From 4e89c65c22c8343ca3d5ec125b68999c690acc2a Mon Sep 17 00:00:00 2001 From: ASH Date: Sun, 31 Mar 2019 18:58:57 +0400 Subject: [PATCH 43/45] #81 adding main tables --- .../db/changelog-20190331_000000-schema.xml | 55 +++++++++++++++++++ src/main/resources/db/changelog-master.xml | 1 + 2 files changed, 56 insertions(+) create mode 100644 src/main/resources/db/changelog-20190331_000000-schema.xml diff --git a/src/main/resources/db/changelog-20190331_000000-schema.xml b/src/main/resources/db/changelog-20190331_000000-schema.xml new file mode 100644 index 0000000..76a7daa --- /dev/null +++ b/src/main/resources/db/changelog-20190331_000000-schema.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog-master.xml b/src/main/resources/db/changelog-master.xml index 132e510..91eeeff 100644 --- a/src/main/resources/db/changelog-master.xml +++ b/src/main/resources/db/changelog-master.xml @@ -21,5 +21,6 @@ + \ No newline at end of file From 0428bad04890da7335f82c9f68bb6f10706fa68e Mon Sep 17 00:00:00 2001 From: Nightblade73 Date: Tue, 2 Apr 2019 10:53:09 +0400 Subject: [PATCH 44/45] #57 created classes --- .../controller/ConferenceController.java | 19 +++++++++++++++++++ .../ru/ulstu/conference/model/Conference.java | 9 +++++++++ .../ulstu/conference/model/ConferenceDto.java | 4 ++++ .../conference/model/ConferenceFilterDto.java | 4 ++++ .../repository/ConferenceRepository.java | 7 +++++++ .../ConferenceNotificationService.java | 7 +++++++ .../conference/service/ConferenceService.java | 17 +++++++++++++++++ 7 files changed, 67 insertions(+) create mode 100644 src/main/java/ru/ulstu/conference/controller/ConferenceController.java create mode 100644 src/main/java/ru/ulstu/conference/model/Conference.java create mode 100644 src/main/java/ru/ulstu/conference/model/ConferenceDto.java create mode 100644 src/main/java/ru/ulstu/conference/model/ConferenceFilterDto.java create mode 100644 src/main/java/ru/ulstu/conference/repository/ConferenceRepository.java create mode 100644 src/main/java/ru/ulstu/conference/service/ConferenceNotificationService.java create mode 100644 src/main/java/ru/ulstu/conference/service/ConferenceService.java diff --git a/src/main/java/ru/ulstu/conference/controller/ConferenceController.java b/src/main/java/ru/ulstu/conference/controller/ConferenceController.java new file mode 100644 index 0000000..aa871ba --- /dev/null +++ b/src/main/java/ru/ulstu/conference/controller/ConferenceController.java @@ -0,0 +1,19 @@ +package ru.ulstu.conference.controller; + + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import ru.ulstu.conference.service.ConferenceService; +import springfox.documentation.annotations.ApiIgnore; + +@Controller() +@RequestMapping(value = "/conferences") +@ApiIgnore +public class ConferenceController { + + private final ConferenceService conferenceService; + + public ConferenceController(ConferenceService paperService) { + this.conferenceService = paperService; + } +} diff --git a/src/main/java/ru/ulstu/conference/model/Conference.java b/src/main/java/ru/ulstu/conference/model/Conference.java new file mode 100644 index 0000000..a65411c --- /dev/null +++ b/src/main/java/ru/ulstu/conference/model/Conference.java @@ -0,0 +1,9 @@ +package ru.ulstu.conference.model; + +import javax.persistence.Entity; +import javax.persistence.Table; + +@Entity +@Table(name = "conference") +public class Conference { +} diff --git a/src/main/java/ru/ulstu/conference/model/ConferenceDto.java b/src/main/java/ru/ulstu/conference/model/ConferenceDto.java new file mode 100644 index 0000000..e3f757e --- /dev/null +++ b/src/main/java/ru/ulstu/conference/model/ConferenceDto.java @@ -0,0 +1,4 @@ +package ru.ulstu.conference.model; + +public class ConferenceDto { +} diff --git a/src/main/java/ru/ulstu/conference/model/ConferenceFilterDto.java b/src/main/java/ru/ulstu/conference/model/ConferenceFilterDto.java new file mode 100644 index 0000000..379c8b6 --- /dev/null +++ b/src/main/java/ru/ulstu/conference/model/ConferenceFilterDto.java @@ -0,0 +1,4 @@ +package ru.ulstu.conference.model; + +public class ConferenceFilterDto { +} diff --git a/src/main/java/ru/ulstu/conference/repository/ConferenceRepository.java b/src/main/java/ru/ulstu/conference/repository/ConferenceRepository.java new file mode 100644 index 0000000..4325633 --- /dev/null +++ b/src/main/java/ru/ulstu/conference/repository/ConferenceRepository.java @@ -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 { +} diff --git a/src/main/java/ru/ulstu/conference/service/ConferenceNotificationService.java b/src/main/java/ru/ulstu/conference/service/ConferenceNotificationService.java new file mode 100644 index 0000000..ff9f69a --- /dev/null +++ b/src/main/java/ru/ulstu/conference/service/ConferenceNotificationService.java @@ -0,0 +1,7 @@ +package ru.ulstu.conference.service; + +import org.springframework.stereotype.Service; + +@Service +public class ConferenceNotificationService { +} diff --git a/src/main/java/ru/ulstu/conference/service/ConferenceService.java b/src/main/java/ru/ulstu/conference/service/ConferenceService.java new file mode 100644 index 0000000..a8147c9 --- /dev/null +++ b/src/main/java/ru/ulstu/conference/service/ConferenceService.java @@ -0,0 +1,17 @@ +package ru.ulstu.conference.service; + +import org.springframework.stereotype.Service; +import ru.ulstu.conference.repository.ConferenceRepository; +import ru.ulstu.deadline.service.DeadlineService; + +@Service +public class ConferenceService { + private final ConferenceRepository conferenceRepository; + private final DeadlineService deadlineService; + + public ConferenceService(ConferenceRepository conferenceRepository, + DeadlineService deadlineService) { + this.conferenceRepository = conferenceRepository; + this.deadlineService = deadlineService; + } +} From 4104aa04cd99a48eaaa60d38fa7136d095e15407 Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Wed, 3 Apr 2019 10:39:55 +0400 Subject: [PATCH 45/45] fixes for wrong build. entities always extends BaseEntity, tables must contains version column --- src/main/java/ru/ulstu/conference/model/Conference.java | 4 +++- src/main/resources/db/changelog-20190331_000010-schema.xml | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/ulstu/conference/model/Conference.java b/src/main/java/ru/ulstu/conference/model/Conference.java index a65411c..b2851ed 100644 --- a/src/main/java/ru/ulstu/conference/model/Conference.java +++ b/src/main/java/ru/ulstu/conference/model/Conference.java @@ -1,9 +1,11 @@ package ru.ulstu.conference.model; +import ru.ulstu.core.model.BaseEntity; + import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table(name = "conference") -public class Conference { +public class Conference extends BaseEntity { } diff --git a/src/main/resources/db/changelog-20190331_000010-schema.xml b/src/main/resources/db/changelog-20190331_000010-schema.xml index 26a98df..04bda75 100644 --- a/src/main/resources/db/changelog-20190331_000010-schema.xml +++ b/src/main/resources/db/changelog-20190331_000010-schema.xml @@ -54,4 +54,10 @@ constraintName=" fk_deadlines_conference" referencedTableName="conference" referencedColumnNames="id"/> + + + + + +