diff --git a/src/main/java/nl/tudelft/submit/controller/AssignmentController.java b/src/main/java/nl/tudelft/submit/controller/AssignmentController.java index 92390a17e9e94b8836907f81c41b1f9838803247..ab5d26be63d5af84e82c85d87567851fe472686f 100644 --- a/src/main/java/nl/tudelft/submit/controller/AssignmentController.java +++ b/src/main/java/nl/tudelft/submit/controller/AssignmentController.java @@ -21,8 +21,9 @@ import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; -import java.util.Collections; import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; import javax.transaction.Transactional; import javax.validation.Valid; @@ -36,6 +37,7 @@ import nl.tudelft.submit.dto.create.note.AssignmentNoteCreateDTO; import nl.tudelft.submit.dto.patch.SubmitAssignmentPatchDTO; import nl.tudelft.submit.dto.patch.grading.AssignmentGradeImportDTO; import nl.tudelft.submit.dto.view.labracore.SubmitAssignmentDetailsDTO; +import nl.tudelft.submit.dto.view.labracore.SubmitSubmissionViewDTO; import nl.tudelft.submit.model.Signature; import nl.tudelft.submit.security.AuthorizationService; import nl.tudelft.submit.service.*; @@ -102,7 +104,7 @@ public class AssignmentController { //TODO: change SubmissionSummaryDTO to SubmissionDetailsDTO (include more info about submissions) model.addAttribute("id", id); - AssignmentModuleDetailsDTO assignment = assignmentService.getAssignmentDetails(id); + SubmitAssignmentDetailsDTO assignment = assignmentService.getSubmitAssignmentDetails(id); model.addAttribute("assignment", assignment); boolean isStaff = authorizationService.hasStaffRoleInAssignment(id); @@ -123,10 +125,12 @@ public class AssignmentController { model.addAttribute("group_version", versionService.getVersionOfAssignmentForGroup(id, groupId)); - List<SubmissionDetailsDTO> submissions = submissionService - .getSubmissionsOfAssignmentForGroup(id, groupId); - Collections.reverse(submissions); + List<SubmitSubmissionViewDTO> submissions = submissionService + .getSubmitSubmissionsForAssignmentAndGroup(id, groupId); model.addAttribute("submissions", submissions); + model.addAttribute("grades", submissions.stream() + .flatMap(s -> s.getGrades().stream()) + .collect(Collectors.toMap(GradeSummaryDTO::getId, Function.identity()))); model.addAttribute("canMakeSubmission", submissionService.canMakeSubmission(id, groupId)); diff --git a/src/main/java/nl/tudelft/submit/service/StudentGroupService.java b/src/main/java/nl/tudelft/submit/service/StudentGroupService.java index 096a2ade171a5f52b126288f1c4c32699b24bf2c..c8340e7ea68a60dfdf44a90c6daa044d0a359193 100644 --- a/src/main/java/nl/tudelft/submit/service/StudentGroupService.java +++ b/src/main/java/nl/tudelft/submit/service/StudentGroupService.java @@ -108,18 +108,7 @@ public class StudentGroupService { assignment.setScoreType(assignmentService.getOrCreateSubmitAssignment(a.getId()) .getScoreType()); return assignment; - }, - a -> submissionService.getSubmissionsOfAssignmentForGroup(a.getId(), id) - .stream() - .sorted(Comparator.comparing(SubmissionDetailsDTO::getSubmissionTime) - .reversed()) - .map(s -> { - SubmitSubmissionViewDTO view = mapper.map(s, - SubmitSubmissionViewDTO.class); - view.setFeedback( - feedbackService.getAllFeedbackPerSubmission(s.getId())); - return view; - }).collect(Collectors.toList())))); + }, a -> submissionService.getSubmitSubmissionsForAssignmentAndGroup(a.getId(), id)))); group.setSubmissionMap(assignments); if (isStaff) { diff --git a/src/main/java/nl/tudelft/submit/service/SubmissionService.java b/src/main/java/nl/tudelft/submit/service/SubmissionService.java index 9a33e9a9798ff8c3a613fbbf6811294a3dd71582..4a3ab0fa80d5fb5eb89dcff7c9245e37d14fef2b 100644 --- a/src/main/java/nl/tudelft/submit/service/SubmissionService.java +++ b/src/main/java/nl/tudelft/submit/service/SubmissionService.java @@ -18,18 +18,16 @@ package nl.tudelft.submit.service; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import nl.tudelft.labracore.api.SubmissionControllerApi; import nl.tudelft.labracore.api.dto.*; import nl.tudelft.submit.dto.create.SubmissionDownloadConfigCreateDTO; +import nl.tudelft.submit.dto.view.labracore.SubmitSubmissionViewDTO; import nl.tudelft.submit.enums.SubmissionDownloadPreference; +import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -44,9 +42,14 @@ public class SubmissionService { @Autowired private AssignmentService assignmentService; + @Autowired + private FeedbackService feedbackService; + @Autowired private GradeService gradeService; + private ModelMapper mapper = new ModelMapper(); + /** * Returns a SubmissionViewDTO of the Submission of the given ID. * @@ -195,6 +198,28 @@ public class SubmissionService { } + /** + * Gets the submissions for an assignment by a group, with information about feedback. + * + * @param assignmentId The id of the assignment + * @param groupId The id of the group + * @return The list of submissions + */ + public List<SubmitSubmissionViewDTO> getSubmitSubmissionsForAssignmentAndGroup(Long assignmentId, + Long groupId) { + return getSubmissionsOfAssignmentForGroup(assignmentId, groupId) + .stream() + .sorted(Comparator.comparing(SubmissionDetailsDTO::getSubmissionTime) + .reversed()) + .map(s -> { + SubmitSubmissionViewDTO view = mapper.map(s, + SubmitSubmissionViewDTO.class); + view.setFeedback( + feedbackService.getAllFeedbackPerSubmission(s.getId())); + return view; + }).collect(Collectors.toList()); + } + /** * Returns whether it is possible to make a submission. * diff --git a/src/main/resources/static/css/main.css b/src/main/resources/static/css/main.css index 8a897122cc36a5e4ba78618c2d6f8f3fceaa4eab..c54482ee4d877dae17cff66fb14e7efcfe5007e7 100644 --- a/src/main/resources/static/css/main.css +++ b/src/main/resources/static/css/main.css @@ -194,6 +194,21 @@ h1, h2, h3, h4, h5 { margin-bottom: 1em; } +.horizontal-separator { + margin: .5em 0; + position: relative; +} + +.horizontal-separator::before { + background-color: var(--gray-medium); + content: ''; + height: 1px; + left: 0; + position: absolute; + top: -.25em; + width: 100%; +} + /* * ================ * 2. Breadcrumbs diff --git a/src/main/resources/templates/assignment/student_view.html b/src/main/resources/templates/assignment/student_view.html index 57d3b7905d0cc4fea7011fafaf6e908e2e7f76b7..35c114fc33e261bc4d6a79c9553b8ed1f96e1d0f 100644 --- a/src/main/resources/templates/assignment/student_view.html +++ b/src/main/resources/templates/assignment/student_view.html @@ -23,33 +23,26 @@ <body> <div layout:fragment="top-content" th:unless="${isStaff}" class="horizontal-content"> - <div class="boxed-group"> - <div class="boxed-header"> - <div class="header-content-full"> - <h1 class="collapsible-title" th:text="${assignment.name}"></h1> + <div class="boxed-group article"> + <h1 class="section-title" th:text="${assignment.name}"></h1> + <div> + <div> + <span th:text="|#{assignment.deadline}:|"></span> + <span th:if="${group_version}" th:text="${#temporals.format(group_version.deadline, 'dd-MM-yyyy HH:mm')} ?: ${#temporals.format(assignment.deadline, 'dd-MM-yyyy HH:mm')}"></span> + <span th:unless="${group_version}" th:text="${#temporals.format(assignment.deadline, 'dd-MM-yyyy HH:mm')}"></span><br> + <span th:text="|#{assignment.submission_limit}:|"></span> + <span th:text="${assignment.submissionLimit} ?: #{generic.none}"></span><br> + <span th:text="|#{assignment.file_types}:|"></span> + <span th:text="${assignment.allowedFileTypes == null || assignment.allowedFileTypes.size() == 0} ? #{generic.all} : ${assignment.allowedFileTypes}"></span><br> </div> - </div> - <div class="boxed-content"> - <div class="sidebar"> - <div class="sidebar-body"> - - <p th:if="${group_version}" th:text="${group_version.description.text} ?: ${assignment.description.text}"></p> - <p th:unless="${group_version}" th:text="${assignment.description.text}"></p> - <a th:if="${group_version}" th:href="${group_version.description.fileDirectory} ?: ${assignment.description.fileDirectory}" - th:text="${group_version.description.fileDirectory} ?: ${assignment.description.fileDirectory}"></a> - <a th:unless="${group_version}" th:href="${assignment.description.fileDirectory}" - th:text="${assignment.description.fileDirectory}"></a> - - </div> - <div class="sidebar-right"> - <span th:text="|#{assignment.deadline}:|"></span><br> - <span th:if="${group_version}" th:text="${#temporals.format(group_version.deadline, 'dd-MM-yyyy HH:mm')} ?: ${#temporals.format(assignment.deadline, 'dd-MM-yyyy HH:mm')}"></span> - <span th:unless="${group_version}" th:text="${#temporals.format(assignment.deadline, 'dd-MM-yyyy HH:mm')}"></span><br><br> - <span th:text="|#{assignment.submission_limit}:|"></span><br> - <span th:text="${assignment.submissionLimit} ?: #{generic.none}"></span><br><br> - <span th:text="|#{assignment.file_types}:|"></span><br> - <span th:text="${assignment.allowedFileTypes == null || assignment.allowedFileTypes.size() == 0} ? #{generic.all} : ${assignment.allowedFileTypes}"></span><br> - </div> + <div class="horizontal-separator"></div> + <div> + <p th:if="${group_version}" th:utext="${#strings.replace(#strings.escapeXml(group_version.description.text ?: assignment.description.text), ' ', '<br>')}"></p> + <p th:unless="${group_version}" th:utext="${#strings.replace(#strings.escapeXml(assignment.description.text), ' ', '<br>')}"></p> + <a th:if="${group_version}" th:href="${group_version.description.fileDirectory} ?: ${assignment.description.fileDirectory}" + th:text="${group_version.description.fileDirectory} ?: ${assignment.description.fileDirectory}"></a> + <a th:unless="${group_version}" th:href="${assignment.description.fileDirectory}" + th:text="${assignment.description.fileDirectory}"></a> </div> </div> </div> @@ -65,56 +58,41 @@ </div> <div class="list-content"> - <div th:each="submission, iter : ${submissions}" class="list-row"> + <div th:if="${submissions.isEmpty()}" class="list-row"> + <div class="collapsible-row-content"> + <span th:text="#{assignment.no_submissions}"></span> + </div> + </div> + <div class="collapsible-row" th:each="submission, iter : ${submissions}"> <span th:text="#{submission.name(__${submissions.size() - iter.index}__)}"></span> <span th:text="${#temporals.format(submission.submissionTime, 'dd-MM-yyyy HH:mm')}"></span> - <span th:text="${submission.grade}"></span> - + <span th:text="${submission.getMaxGrade() == null} ? #{submission.no_grade} : ${@gradeService.getScoreDisplayString(submission.getMaxGrade())}"></span> <div class="list-row-buttons"> - <button class="button" th:onclick="|toggleOverlay('submission-${submission.id}-overlay')|" th:text="#{generic.view}"></button> - <div th:id="|submission-${submission.id}-overlay|" - th:class="${param.submission?.toString() == '__${submission.id}__'} ? 'visible overlay' : 'overlay'"> - <div class="boxed-group"> - <div class="boxed-header"> - <h1 class="collapsible-title" th:text="#{submission.text}"></h1> - <div class="float-right"> - <button type="button" class="overlay-close fas fa-times" aria-label="Close overlay" - th:onclick="|toggleOverlay('submission-${submission.id}-overlay')|"></button> - </div> + <a class="button" th:href="@{|/submission/${submission.id}/download|}" th:text="#{generic.download}"></a> + <button class="button" th:onclick="|toggleOverlay('submission-${submission.id}-overlay')|" + th:text="#{assignment.feedback}"></button> + </div> + + <div layout:fragment="submission-view" th:unless="${staff}" th:id="|submission-${submission.id}-overlay|" + th:class="${param.submission?.toString() == '__${submission.id}__'} ? 'visible overlay' : 'overlay'"> + <div class="boxed-group"> + <div class="boxed-header"> + <h1 class="collapsible-title" th:text="#{submission.text}"></h1> + <div class="float-right"> + <button type="button" class="overlay-close fas fa-times" aria-label="Close overlay" + th:onclick="|toggleOverlay('submission-${submission.id}-overlay')|"></button> </div> - <div class="boxed-content"> - <div class="sidebar"> - <div class="sidebar-left"> - <p th:text="#{submission.fin_grade}"></p> - <div> - <h2 th:text="${submission.getGrade() == null} ? #{submission.no_grade} : ${submission.getGrade()}" class="grade"></h2> - </div> - <br> - <p th:text="#{submission.date}"></p> - <h3 th:text="${#temporals.format(submission.submissionTime, 'dd-MM-yyyy HH:mm')}"></h3> - <br> -<!-- <p th:text="#{submission.by}"></p>--> -<!-- <h3 th:text="${submission.submitter?.displayName}"></h3>--> -<!-- <br>--> - <p th:text="#{submission.files}"></p> - <a th:href="@{|/submission/${submission.id}/download|}" th:text="#{submission.download_files}"></a> + </div> + <div class="boxed-content"> + <span th:if="${submission.feedback.isEmpty()}" th:text="#{submission.feedback.none}" class="feedback-text"></span> + <div th:unless="${submission.feedback.isEmpty()}" class="feedbacks"> + <div th:each="feedback : ${submission.feedback}" class="feedback"> + <div class="feedback-text"> + <p th:utext="${#strings.replace(#strings.escapeXml(feedback.textualFeedback), ' ', '<br>')}">Test</p> + <span th:if="${grades.containsKey(feedback.gradeId)}" class="feedback-grade" + th:text="${@gradeService.getScoreDisplayString(grades[feedback.gradeId])}"></span> </div> - <!-- TODO: include when changed to SubmitSubmissionViewDTOs --> - <!-- <div class="sidebar-body scroll-xl">--> - <!-- <h1 th:text="#{assignment.feedback}"></h1>--> - <!-- <div class="feedback-list">--> - <!-- <p th:if="${submission.feedback.isEmpty()}"--> - <!-- th:text="#{submission.feedback.none}"></p>--> - <!-- <div class="feedback-block"--> - <!-- th:each="feedback : ${submission.feedback}">--> - <!-- <span class="feedback-name" th:text="${feedback.author.id}"></span>--> - <!-- <!–TODO: Display pass/fail grade differeeently –>--> - <!-- <span class="feedback-grade" th:if="${T(nl.tudelft.submit.model.ScoreType).isScript(feedback)}" th:text="${feedback.score.score}"></span>--> - <!-- <span class="feedback-text"--> - <!-- th:text="${feedback.textualFeedback}"></span>--> - <!-- </div>--> - <!-- </div>--> - <!-- </div>--> + <span class="feedback-time" th:text="${#temporals.format(feedback.timestamp, 'dd-MM-yyyy HH:mm')}"></span> </div> </div> </div> @@ -127,9 +105,9 @@ <div layout:fragment="submission-create-overlay" th:unless="${isStaff}" class="overlay" id="submission-create-overlay"> <div class="form-group"> - <form id="submissionForm" class="dropzone" action="#" th:action="@{|/submission|}" + <form id="submission-form" class="dropzone" th:action="@{|/submission|}" th:object="${submissionCreate}" method="post" enctype="multipart/form-data"> - <h1 class="group-title" th:text="#{submission.new}"></h1> + <h1 class="group-title" style="display: flex;" th:text="#{submission.new}"></h1> <input type="hidden" th:name="group.id" th:value="${groupId}"> <input type="hidden" th:name="assignment.id" th:value="${assignment.id}"> <span th:if="${markSubmissionLate}" th:text="#{submission.late}"></span> diff --git a/src/main/resources/templates/assignment/teacher_view.html b/src/main/resources/templates/assignment/teacher_view.html index 8828f564c29d84fc0ec0c15921a9d4bd48d6583f..e00e5b5a4e14d649e1b419a34144290fcf907311 100644 --- a/src/main/resources/templates/assignment/teacher_view.html +++ b/src/main/resources/templates/assignment/teacher_view.html @@ -27,11 +27,14 @@ <button type="button" class="button" onclick="toggleOverlay('import-grades-overlay')" th:text="#{assignment.import_grades}"></button> <a class="button" th:href="@{|/assignment/${assignment.id}/statistics|}" th:text="#{statistics.text}"></a> + <a th:if="${canEdit}" th:href="@{|/assignment/edit/${id}|}" class="button" th:text="#{assignment.edit}"></a> </div> <div id="import-grades-overlay" class="overlay"> <div class="boxed-group"> - <form id="import-grades" class="form" th:object="${gradeImport}" th:action="@{|/assignment/${assignment.id}/import/grades|}" method="post" enctype="multipart/form-data"> + <form id="import-grades" class="form" th:object="${gradeImport}" + th:action="@{|/assignment/${assignment.id}/import/grades|}" method="post" + enctype="multipart/form-data"> <div class="form-grid"> <label class="center-label" for="file" th:text="#{generic.file}"></label> <div> @@ -48,13 +51,18 @@ </div> </div> <div class="form-group"> - <select id="id-column" th:name="idColumn" class="selectbox" aria-label="Identifier column" disabled></select> - <select id="id-column-data" th:name="idType" class="selectbox" aria-label="Identifier column data" disabled> - <option th:each="idType : ${T(nl.tudelft.submit.enums.GradeImportIdType).values()}" th:value="${idType}" th:text="#{|assignment.import_grades.${#strings.toLowerCase(idType.name())}|}"></option> + <select id="id-column" th:name="idColumn" class="selectbox" aria-label="Identifier column" + disabled></select> + <select id="id-column-data" th:name="idType" class="selectbox" + aria-label="Identifier column data" disabled> + <option th:each="idType : ${T(nl.tudelft.submit.enums.GradeImportIdType).values()}" + th:value="${idType}" + th:text="#{|assignment.import_grades.${#strings.toLowerCase(idType.name())}|}"></option> </select> </div> <div> - <label class="center-label" for="score-column" th:text="#{assignment.import_grades.grade_column}"></label> + <label class="center-label" for="score-column" + th:text="#{assignment.import_grades.grade_column}"></label> <div class="tooltip"> <i class="tooltip-icon fas fa-question-circle"></i> <p class="tooltip-text" th:text="#{assignment.import_grades.grade_help}"></p> @@ -74,7 +82,8 @@ </div> </div> <div class="form-buttons"> - <button id="import-button" type="submit" class="button" disabled th:text="#{generic.import}"></button> + <button id="import-button" type="submit" class="button" disabled + th:text="#{generic.import}"></button> <button type="button" class="button" onclick="toggleOverlay('import-grades-overlay')" th:text="#{generic.cancel}"></button> </div> @@ -84,35 +93,31 @@ </div> <div layout:fragment="top-content" th:if="${isStaff}" class="horizontal-content"> - <div class="boxed-group"> - <div class="boxed-header"> - <div class="header-content-full"> - <h1 class="collapsible-title" th:text="${assignment.name}"></h1> - <a th:if="${canEdit}" th:href="@{|/assignment/edit/${id}|}" class="button">Edit</a> - </div> - </div> - <div class="boxed-content"> - <div class="sidebar"> - <div class="sidebar-body"> - <p th:text="${assignment.description.text}"></p> - <a th:href="${assignment.description.fileDirectory}" - th:text="${assignment.description.fileDirectory}"></a> - <a th:href="${assignment.approveScript}" - th:text="${assignment.approveScript}"></a> - </div> - <div class="sidebar-right"> - <span th:text="|#{assignment.deadline}:|"></span> - <span th:text="${#temporals.format(assignment.deadline, 'dd-MM-yyyy HH:mm')}"></span><br> - <span th:text="|#{assignment.submission_limit}:|"></span> - <span th:text="${assignment.submissionLimit} ?: #{generic.none}"></span><br> - <span th:text="|#{assignment.file_types}:|"></span> - <span th:text="${assignment.allowedFileTypes == null || assignment.allowedFileTypes.size() == 0} ? #{generic.all} : ${assignment.allowedFileTypes}"></span><br> - <span th:text="|#{assignment.leniency}:|"></span> - <span th:text="${assignment.lateSubmissionLeniency == null || assignment.lateSubmissionLeniency == 0} ? #{assignment.leniency.none} : #{assignment.leniency.hours(__${assignment.lateSubmissionLeniency}__)}"></span><br> - <span th:text="|#{assignment.late_submissions}:|"></span> - <span th:text="${assignment.acceptLateSubmissions} ? #{generic.yes} : #{generic.no}"></span><br> + <div class="boxed-group article"> + <h1 class="section-title" th:text="${assignment.name}"></h1> + <div> + <div> + <span th:text="|#{assignment.deadline}:|"></span> + <span th:text="${#temporals.format(assignment.deadline, 'dd-MM-yyyy HH:mm')}"></span><br> + <span th:text="|#{assignment.submission_limit}:|"></span> + <span th:text="${assignment.submissionLimit} ?: #{generic.none}"></span><br> + <span th:text="|#{assignment.file_types}:|"></span> + <span th:text="${assignment.allowedFileTypes == null || assignment.allowedFileTypes.size() == 0} ? #{generic.all} : ${assignment.allowedFileTypes}"></span><br> + <span th:text="|#{assignment.leniency}:|"></span> + <span th:text="${assignment.lateSubmissionLeniency == null || assignment.lateSubmissionLeniency == 0} ? #{assignment.leniency.none} : #{assignment.leniency.hours(__${assignment.lateSubmissionLeniency}__)}"></span><br> + <span th:text="|#{assignment.late_submissions}:|"></span> + <span th:text="${assignment.acceptLateSubmissions} ? #{generic.yes} : #{generic.no}"></span><br> + <div th:if="${assignment.approveScript != null}" th:remove="tag"> + <span th:text="|#{assignment.approve_script}:|"></span> + <a th:href="${assignment.approveScript}" th:text="${assignment.approveScript}"></a> </div> </div> + <div class="horizontal-separator"></div> + <div> + <p th:utext="${#strings.replace(#strings.escapeXml(assignment.description.text), ' ', '<br>')}"></p> + <a th:href="${assignment.description.fileDirectory}" + th:text="${assignment.description.fileDirectory}"></a> + </div> </div> </div> </div> diff --git a/src/main/resources/templates/assignment/view.html b/src/main/resources/templates/assignment/view.html index 3922cb3e02d43ab39c22efab19b57beac148e7dc..25d941e431cbfcc7838d412f2657f70d21e773bc 100644 --- a/src/main/resources/templates/assignment/view.html +++ b/src/main/resources/templates/assignment/view.html @@ -46,8 +46,6 @@ <div layout:replace="~{assignment/student_view :: top-content}" th:remove="tag"></div> <div layout:replace="~{assignment/teacher_view :: versions}" th:remove="tag"></div> - - <div layout:replace="~{assignment/teacher_view :: submissions}" th:remove="tag"></div> <div layout:replace="~{assignment/student_view :: submissions}" th:remove="tag"></div> </div> diff --git a/src/main/resources/templates/submission/dropzone.html b/src/main/resources/templates/submission/dropzone.html index bcac372e0879f243ab78dad05f0214ff5dcaf18d..dbb3b13026adeb0cbeff157577da57f1c6e45412 100644 --- a/src/main/resources/templates/submission/dropzone.html +++ b/src/main/resources/templates/submission/dropzone.html @@ -21,7 +21,7 @@ <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"> <body> -<script th:inline="javascript" layout:fragment="submission-dropzone" th:with="fileTypes = ${assignment.allowedFileTypes.toString()}"> +<script th:inline="javascript" layout:fragment="submission-dropzone" th:with="fileTypes = ${assignment.allowedFileTypes?.toString()}"> /*<![CDATA[*/ new Dropzone("#sub-form-" + [[${assignment.id}]], { url: "/submission/", @@ -52,9 +52,9 @@ /*]]>*/ </script> -<script th:inline="javascript" layout:fragment="assignment-dropzone"> +<script th:inline="javascript" layout:fragment="assignment-dropzone" th:with="fileTypes = ${assignment.allowedFileTypes?.toString()}"> /*<![CDATA[*/ - new Dropzone("#sub-form-" + [[${assignment.id}]], { + new Dropzone("#submission-form", { url: "/submission/", autoProcessQueue: false, autoQueue: true, @@ -64,10 +64,10 @@ maxFiles : 5, addRemoveLinks : true, init: function() { - let button_id = "submit-button"; - let submitButton = document.getElementById(button_id); + var button_id = "submit-button"; + var submitButton = document.getElementById(button_id); - let dz = this; + var dz = this; submitButton.addEventListener("click", function() { dz.processQueue(); diff --git a/src/test/java/nl/tudelft/submit/controller/AssignmentControllerTest.java b/src/test/java/nl/tudelft/submit/controller/AssignmentControllerTest.java index 4fa4a8f87e906e68f6e874e062a22d881866819e..fd32f8f0ed54411b7f8b06a1eed74e2792ed5d8b 100644 --- a/src/test/java/nl/tudelft/submit/controller/AssignmentControllerTest.java +++ b/src/test/java/nl/tudelft/submit/controller/AssignmentControllerTest.java @@ -158,7 +158,7 @@ class AssignmentControllerTest { verify(authService).hasRoleInAssignment(ASSIGNMENT_ID); verify(authService, never()).hasStaffRoleInAssignment(anyLong()); verify(authService, never()).canEditAssignment(anyLong()); - verify(assignmentService, never()).getAssignmentDetails(anyLong()); + verify(assignmentService, never()).getSubmitAssignmentDetails(anyLong()); verify(versionService, never()).getVersionsPerAssignment(anyLong()); verify(studentGroupService, never()).getGroupForPersonInModule(anyLong(), anyLong()); verify(versionService, never()).getVersionOfAssignmentForGroup(anyLong(), anyLong()); @@ -169,7 +169,7 @@ class AssignmentControllerTest { void getAssignmentDetailsAllowsIfHasRoleInAssignmentEditionAndIsStaff() throws Exception { when(authService.hasRoleInAssignment(anyLong())).thenReturn(true); - when(assignmentService.getAssignmentDetails(anyLong())).thenReturn(ASSIGNMENT_DETAILS); + when(assignmentService.getSubmitAssignmentDetails(anyLong())).thenReturn(SUBMIT_ASSIGNMENT_DETAILS); when(authService.hasStaffRoleInAssignment(anyLong())).thenReturn(true); when(authService.canEditAssignment(anyLong())).thenReturn(true); when(versionService.getVersionsPerAssignment(anyLong())).thenReturn(List.of(VERSION_VIEW)); @@ -182,12 +182,11 @@ class AssignmentControllerTest { mockMvc.perform(get("/assignment/{id}", ASSIGNMENT_ID)) .andExpect(status().isOk()) .andExpect(model().attributeExists("assignment")) - .andExpect(model().attribute("assignment", ASSIGNMENT_DETAILS)) + .andExpect(model().attribute("assignment", SUBMIT_ASSIGNMENT_DETAILS)) .andExpect(model().attributeExists("id", "isStaff", "canEdit", "versions")); verify(authService).hasRoleInAssignment(ASSIGNMENT_ID); - verify(assignmentService).getAssignmentDetails(ASSIGNMENT_ID); - verify(assignmentService).getAssignmentDetails(ASSIGNMENT_ID); + verify(assignmentService).getSubmitAssignmentDetails(ASSIGNMENT_ID); verify(authService).hasStaffRoleInAssignment(ASSIGNMENT_ID); verify(authService).canEditAssignment(ASSIGNMENT_ID); verify(versionService).getVersionsPerAssignment(ASSIGNMENT_ID); @@ -200,7 +199,7 @@ class AssignmentControllerTest { @WithUserDetails("username") void getAssignmentDetailsAllowsIfHasRoleInAssignmentEditionAndIsNotStaff() throws Exception { when(authService.hasRoleInAssignment(anyLong())).thenReturn(true); - when(assignmentService.getAssignmentDetails(anyLong())).thenReturn(ASSIGNMENT_DETAILS); + when(assignmentService.getSubmitAssignmentDetails(anyLong())).thenReturn(SUBMIT_ASSIGNMENT_DETAILS); when(authService.hasStaffRoleInAssignment(anyLong())).thenReturn(false); when(authService.canEditAssignment(anyLong())).thenReturn(false); when(versionService.getVersionsPerAssignment(anyLong())).thenReturn(List.of(VERSION_VIEW)); @@ -218,19 +217,19 @@ class AssignmentControllerTest { mockMvc.perform(get("/assignment/{id}", ASSIGNMENT_ID)) .andExpect(status().isOk()) .andExpect(model().attributeExists("assignment")) - .andExpect(model().attribute("assignment", ASSIGNMENT_DETAILS)) + .andExpect(model().attribute("assignment", SUBMIT_ASSIGNMENT_DETAILS)) .andExpect(model().attributeExists("id", "isStaff", "canEdit", "versions", "group_version", "submissions", "groupId", "markSubmissionLate", "canMakeSubmission")); verify(authService).hasRoleInAssignment(ASSIGNMENT_ID); - verify(assignmentService).getAssignmentDetails(ASSIGNMENT_ID); + verify(assignmentService).getSubmitAssignmentDetails(ASSIGNMENT_ID); verify(authService).hasStaffRoleInAssignment(ASSIGNMENT_ID); verify(authService).canEditAssignment(ASSIGNMENT_ID); verify(versionService).getVersionsPerAssignment(ASSIGNMENT_ID); verify(studentGroupService).getGroupForPersonInModule(PERSON_ID, MODULE_ID); verify(versionService).getVersionOfAssignmentForGroup(ASSIGNMENT_ID, GROUP_ID); - verify(submissionService).getSubmissionsOfAssignmentForGroup(ASSIGNMENT_ID, GROUP_ID); + verify(submissionService).getSubmitSubmissionsForAssignmentAndGroup(ASSIGNMENT_ID, GROUP_ID); verify(submissionService).canMakeSubmission(ASSIGNMENT_ID, GROUP_ID); verify(submissionService).markSubmissionLate(ASSIGNMENT_ID, GROUP_ID); diff --git a/src/test/java/nl/tudelft/submit/service/StudentGroupServiceTest.java b/src/test/java/nl/tudelft/submit/service/StudentGroupServiceTest.java index 6d264cf25f0c185c7b4bfdf9be44ef517a238316..5b93bec2eae46a39c0c2a7953b65686833fc3926 100644 --- a/src/test/java/nl/tudelft/submit/service/StudentGroupServiceTest.java +++ b/src/test/java/nl/tudelft/submit/service/StudentGroupServiceTest.java @@ -123,6 +123,11 @@ class StudentGroupServiceTest { when(assignmentService.getOrCreateSubmitAssignment(ASSIGNMENT_ID)) .thenReturn(SubmitAssignment.builder() .scoreType(Grade.SchemeEnum.DUTCH_GRADE).build()); + when(submissionService.getSubmitSubmissionsForAssignmentAndGroup(anyLong(), anyLong())) + .thenReturn(List.of( + new SubmitSubmissionViewDTO(SUBMISSION_ID, time, null, null, null, null, null, + Collections.emptyList(), + null))); SubmitGroupDetailsDTO expected = new SubmitGroupDetailsDTO(GROUP_ID, "Test group", 5, Collections.emptyList(), null,