diff --git a/src/main/java/org/example/untitled/s3/S3Controller.java b/src/main/java/org/example/untitled/s3/S3Controller.java deleted file mode 100644 index 0e84cba..0000000 --- a/src/main/java/org/example/untitled/s3/S3Controller.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.example.untitled.s3; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; - - -@Controller -public class S3Controller { - - private static final Logger log = LoggerFactory.getLogger(S3Controller.class); - - private final S3Service s3Service; - - public S3Controller(S3Service s3s){this.s3Service = s3s; } - - @GetMapping("/tickets/upload") - public String home(Model model){ - log.info("welcome page"); - model.addAttribute("files", s3Service.listFiles()); - return "upload"; - } - - -} diff --git a/src/main/java/org/example/untitled/s3/S3Service.java b/src/main/java/org/example/untitled/s3/S3Service.java index abf4471..8cb6009 100644 --- a/src/main/java/org/example/untitled/s3/S3Service.java +++ b/src/main/java/org/example/untitled/s3/S3Service.java @@ -99,7 +99,7 @@ public void deleteFile(String filename){ .key(filename)); } - public List createFile(CaseEntity caseEntity, String s3Key) { + public UploadedFile createFile(CaseEntity caseEntity, String s3Key) { UploadedFile uploadedFile = new UploadedFile(); uploadedFile.setUploadedBy(caseEntity.getOwner()); uploadedFile.setAssociatedCase(caseEntity); @@ -107,7 +107,6 @@ public List createFile(CaseEntity caseEntity, String s3Key) { int indexOfSlash = s3Key.lastIndexOf('/'); String fileName = s3Key.substring(indexOfSlash + 1); uploadedFile.setFilename(fileName); - - return List.of(uploadedFile); + return uploadedFile; } } diff --git a/src/main/java/org/example/untitled/user/controller/UserController.java b/src/main/java/org/example/untitled/user/controller/UserController.java index 786656c..889ac1d 100644 --- a/src/main/java/org/example/untitled/user/controller/UserController.java +++ b/src/main/java/org/example/untitled/user/controller/UserController.java @@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; + @Controller public class UserController { @@ -84,4 +85,10 @@ public String processRegister( } return "redirect:/login"; } + + @GetMapping("/tickets/upload") + public String getUserTickets(Model model, @AuthenticationPrincipal UserDetails userDetails){ + model.addAttribute("files", caseService.getUserFiles(userDetails.getUsername())); + return "upload"; + } } diff --git a/src/main/java/org/example/untitled/usercase/UploadedFile.java b/src/main/java/org/example/untitled/usercase/UploadedFile.java index 25dd26e..4861ae3 100644 --- a/src/main/java/org/example/untitled/usercase/UploadedFile.java +++ b/src/main/java/org/example/untitled/usercase/UploadedFile.java @@ -15,7 +15,7 @@ public class UploadedFile { @Column(nullable = false) private String filename; - @Column(nullable = true) + @Column(name = "s3key") private String s3Key; @Column(nullable = false, updatable = false) diff --git a/src/main/java/org/example/untitled/usercase/controller/CaseController.java b/src/main/java/org/example/untitled/usercase/controller/CaseController.java index 9d9737d..f12ec3b 100644 --- a/src/main/java/org/example/untitled/usercase/controller/CaseController.java +++ b/src/main/java/org/example/untitled/usercase/controller/CaseController.java @@ -5,6 +5,7 @@ import org.example.untitled.user.service.UserService; import org.example.untitled.usercase.AuditLog; import org.example.untitled.usercase.CaseStatus; +import org.example.untitled.usercase.UploadedFile; import org.example.untitled.usercase.dto.CaseEntityDto; import org.example.untitled.usercase.dto.CommentDto; import org.example.untitled.usercase.dto.CreateCaseRequest; @@ -43,8 +44,7 @@ public class CaseController { private final UserService userService; private static final Logger log = LoggerFactory.getLogger(CaseController.class); - public CaseController(CaseService caseService, CommentService commentService, - AuditLogService auditLogService, UserService userService) { + public CaseController(CaseService caseService, CommentService commentService, AuditLogService auditLogService, UserService userService) { this.caseService = caseService; this.commentService = commentService; this.auditLogService = auditLogService; @@ -101,6 +101,7 @@ public String showTicketDetails( throw new ResponseStatusException(HttpStatus.FORBIDDEN, "You do not own this ticket"); List comments = commentService.getCommentsByTicketId(id); + List files = caseService.getTicketFiles(id); List auditLogs = auditLogService.getLogsForCase(id); Map auditUserMap = buildAuditUserMap(auditLogs); @@ -111,6 +112,7 @@ public String showTicketDetails( model.addAttribute("canComment", perms.canComment()); model.addAttribute("auditLogs", auditLogs); model.addAttribute("auditUserMap", auditUserMap); + model.addAttribute("files", files); return "ticket"; } diff --git a/src/main/java/org/example/untitled/usercase/repository/UploadedFileRepository.java b/src/main/java/org/example/untitled/usercase/repository/UploadedFileRepository.java new file mode 100644 index 0000000..adfdb63 --- /dev/null +++ b/src/main/java/org/example/untitled/usercase/repository/UploadedFileRepository.java @@ -0,0 +1,18 @@ +package org.example.untitled.usercase.repository; + +import org.example.untitled.user.User; +import org.example.untitled.usercase.CaseEntity; +import org.example.untitled.usercase.UploadedFile; +import org.springframework.data.repository.ListCrudRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface UploadedFileRepository extends ListCrudRepository { + + List associatedCaseEntity(CaseEntity caseEntity); + UploadedFile getUploadedFilesByFilename(String filename); + + List getUploadedFilesByUploadedBy(User uploadedBy); +} diff --git a/src/main/java/org/example/untitled/usercase/service/CaseService.java b/src/main/java/org/example/untitled/usercase/service/CaseService.java index 4918792..59a5e08 100644 --- a/src/main/java/org/example/untitled/usercase/service/CaseService.java +++ b/src/main/java/org/example/untitled/usercase/service/CaseService.java @@ -17,6 +17,8 @@ import org.example.untitled.usercase.dto.CreateCommentRequest; import org.example.untitled.usercase.mapper.CaseMapper; import org.example.untitled.usercase.repository.CaseRepository; +import org.example.untitled.usercase.repository.UploadedFileRepository; +import org.jspecify.annotations.Nullable; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,6 +36,7 @@ public class CaseService { private final UserRepository userRepository; private final AuditLogService auditLogService; private final CommentService commentService; + private final UploadedFileRepository uploadedFileRepository; private final S3Service s3Service; public CaseService( @@ -41,12 +44,14 @@ public CaseService( UserRepository userRepository, CommentService commentService, S3Service s3Service, - AuditLogService auditLogService) { + AuditLogService auditLogService, + UploadedFileRepository fileRepository) { this.caseRepository = caseRepository; this.userRepository = userRepository; this.commentService = commentService; this.auditLogService = auditLogService; this.s3Service = s3Service; + this.uploadedFileRepository = fileRepository; } @Transactional @@ -64,7 +69,9 @@ public CaseEntityDto createTicket(CreateCaseRequest request, String username) { if (request.getFileNames() != null) { for (String fName : request.getFileNames()) { if (fName == null || fName.isBlank()) continue; - caseEntity.getFiles().addAll(s3Service.createFile(caseEntity, fName)); + UploadedFile uploadFile = s3Service.createFile(caseEntity, fName); + uploadedFileRepository.save(uploadFile); + caseEntity.getFiles().add(uploadFile); } } CaseEntity saved = caseRepository.save(caseEntity); @@ -102,7 +109,9 @@ public CaseEntityDto updateTicket(Long id, CreateCaseRequest request, String use .collect(Collectors.toSet()); for (String fName : request.getFileNames()) { if (fName == null || fName.isBlank() || existing.contains(fName)) continue; - caseEntity.getFiles().addAll(s3Service.createFile(caseEntity, fName)); + UploadedFile uploadFile = s3Service.createFile(caseEntity, fName); + uploadedFileRepository.save(uploadFile); + caseEntity.getFiles().add(uploadFile); } } CaseEntity saved = caseRepository.save(caseEntity); @@ -171,6 +180,14 @@ public CaseEntityDto getTicketByID(long id) { return CaseMapper.toDto(caseEntity); } + public List getTicketFiles(long id) { + CaseEntity caseEntity = caseRepository.findById(id) + .orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Ticket not found: " + id)); + + return uploadedFileRepository.associatedCaseEntity(caseEntity).stream() + .toList(); + } public User findOwnerById(long id) { return caseRepository.findOwnerById(id); } @@ -178,4 +195,10 @@ public User findOwnerById(long id) { public boolean isNotOwner(CaseEntityDto ticket, String username) { return !ticket.ownerUsername().equals(username); } + + public @Nullable List getUserFiles(String username) { + User actor = userRepository.findByUsername(username) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found")); + return uploadedFileRepository.getUploadedFilesByUploadedBy(actor); + } } diff --git a/src/main/resources/static/js/script.js b/src/main/resources/static/js/script.js index 4dcbb85..336e2dc 100644 --- a/src/main/resources/static/js/script.js +++ b/src/main/resources/static/js/script.js @@ -83,14 +83,13 @@ async function uploadNewFile(){ } async function deleteFile(fileName){ - const status = document.getElementById('status'); if (window.confirm(fileName + " will be deleted! Are you sure?")) { const res = await apiReq(`/tickets/upload/api/files/delete-url?fileName=${encodeURIComponent(fileName)}`, {method: 'DELETE'}); if (!res) return; if (res.ok) { await fetchAFile(); } else { - status.innerText= 'Error: ' + res.status; + console.error('Error: ' + res.status); } } } diff --git a/src/main/resources/templates/edit_ticket.html b/src/main/resources/templates/edit_ticket.html index f02320b..b44c818 100644 --- a/src/main/resources/templates/edit_ticket.html +++ b/src/main/resources/templates/edit_ticket.html @@ -10,7 +10,7 @@

Edit Ticket

-
+
@@ -23,12 +23,13 @@

Edit Ticket

- +

+
- + Cancel
diff --git a/src/main/resources/templates/ticket.html b/src/main/resources/templates/ticket.html index b7ce774..3184f5a 100644 --- a/src/main/resources/templates/ticket.html +++ b/src/main/resources/templates/ticket.html @@ -5,6 +5,8 @@ Ticket + + @@ -58,8 +60,14 @@

Add Comment

th:errors="*{text}" class="field-error">
+
+ + +

+
+
- +
@@ -77,6 +85,17 @@

Activity Log

+
+ + + + + + + +