diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/repository/jobs/GroupSyncJobRepository.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/repository/jobs/GroupSyncJobRepository.java index 77f266f21..6e2b60ebe 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/repository/jobs/GroupSyncJobRepository.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/repository/jobs/GroupSyncJobRepository.java @@ -15,4 +15,6 @@ public interface GroupSyncJobRepository extends PagingAndSortingRepository findByGroupIdIn(List groupIds, Pageable page); public long countByGroupIdIn(List groupIds); + + public long deleteByGroupIdInAndCreatedOnBefore(List groupIds, java.time.OffsetDateTime threshold); } diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/ISyncJobManager.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/ISyncJobManager.java index bb245da6c..8fdf15790 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/ISyncJobManager.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/ISyncJobManager.java @@ -1,6 +1,7 @@ package edu.asu.diging.citesphere.core.service.jobs; import java.util.List; +import java.time.OffsetDateTime; import org.springframework.data.domain.Pageable; @@ -18,5 +19,7 @@ public interface ISyncJobManager { long getJobsCount(IUser user); void cancelJob(String jobId); + + long pruneJobs(IUser user, OffsetDateTime before); } \ No newline at end of file diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/impl/SyncJobManager.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/impl/SyncJobManager.java index fa4fb77df..4d4c7681a 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/impl/SyncJobManager.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/impl/SyncJobManager.java @@ -8,12 +8,12 @@ import java.util.stream.Collectors; import javax.annotation.PostConstruct; +import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; -import edu.asu.diging.citesphere.core.model.jobs.IJob; import edu.asu.diging.citesphere.core.model.jobs.JobStatus; import edu.asu.diging.citesphere.core.model.jobs.impl.GroupSyncJob; import edu.asu.diging.citesphere.core.repository.jobs.GroupSyncJobRepository; @@ -89,4 +89,15 @@ public void cancelJob(String jobId) { jobRepo.save(job); } } + + @Override + @Transactional + public long pruneJobs(IUser user, OffsetDateTime before) { + List groups = citationManager.getGroups(user); + if (groups == null || groups.isEmpty()) { + return 0; + } + List groupIds = groups.stream().map(g -> g.getGroupId() + "").collect(Collectors.toList()); + return jobRepo.deleteByGroupIdInAndCreatedOnBefore(groupIds, before); + } } diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/web/user/jobs/SyncJobsController.java b/citesphere/src/main/java/edu/asu/diging/citesphere/web/user/jobs/SyncJobsController.java index cf13e4dfd..c1dbc70d2 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/web/user/jobs/SyncJobsController.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/web/user/jobs/SyncJobsController.java @@ -1,5 +1,9 @@ package edu.asu.diging.citesphere.web.user.jobs; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort.Direction; @@ -8,6 +12,10 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import org.springframework.format.annotation.DateTimeFormat; import edu.asu.diging.citesphere.core.service.jobs.ISyncJobManager; import edu.asu.diging.citesphere.user.IUser; @@ -26,8 +34,23 @@ public String list(Model model, @PageableDefault(sort = { "createdOn" }, directi return "redirect:/"; } model.addAttribute("jobs", jobManager.getJobs((IUser) authentication.getPrincipal(), page)); - model.addAttribute("total", Math.ceil(total/page.getPageSize())); - model.addAttribute("page", page.getPageNumber() + 1); + long totalPages = total > 0 ? (long) Math.ceil((double) total / page.getPageSize()) : 1; + model.addAttribute("total", totalPages); + model.addAttribute("page", Math.max(1, Math.min(page.getPageNumber() + 1, totalPages))); return "auth/jobs/list"; } + + @RequestMapping(value = "/auth/jobs/sync/prune", method = RequestMethod.POST) + public String prune(@RequestParam("pruneDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate pruneDate, Authentication authentication, + RedirectAttributes redirectAttributes) { + OffsetDateTime pruneBefore = pruneDate.plusDays(1).atStartOfDay().atOffset(ZoneOffset.UTC); + long deleted = jobManager.pruneJobs((IUser) authentication.getPrincipal(), pruneBefore); + + redirectAttributes.addFlashAttribute("show_alert", true); + redirectAttributes.addFlashAttribute("alert_type", "success"); + redirectAttributes.addFlashAttribute("alert_msg", + String.format("%d job(s) deleted up to and including %s.", deleted, pruneDate)); + + return "redirect:/auth/jobs/sync/list"; + } } diff --git a/citesphere/src/main/webapp/WEB-INF/views/auth/jobs/list.html b/citesphere/src/main/webapp/WEB-INF/views/auth/jobs/list.html index bad98d32e..43a9f8329 100644 --- a/citesphere/src/main/webapp/WEB-INF/views/auth/jobs/list.html +++ b/citesphere/src/main/webapp/WEB-INF/views/auth/jobs/list.html @@ -4,16 +4,46 @@ @@ -21,7 +51,63 @@
-

Jobs

+
+
+

Jobs

+
+
+ +
+
+ + + +