Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@ public interface IGroupSyncJob {
void setFinishedOn(OffsetDateTime finishedOn);

OffsetDateTime getFinishedOn();

String getGroupName();

void setGroupName(String groupName);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.time.OffsetDateTime;

import javax.persistence.Entity;
import javax.persistence.Transient;

import edu.asu.diging.citesphere.core.model.jobs.IGroupSyncJob;

Expand All @@ -13,6 +14,8 @@ public class GroupSyncJob extends Job implements IGroupSyncJob {
private long total;
private long current;
private OffsetDateTime finishedOn;
@Transient
private String groupName;

/* (non-Javadoc)
* @see edu.asu.diging.citesphere.core.model.jobs.impl.IGroupSyncJob#getGroupId()
Expand Down Expand Up @@ -64,4 +67,14 @@ public OffsetDateTime getFinishedOn() {
public void setFinishedOn(OffsetDateTime finishedOn) {
this.finishedOn = finishedOn;
}

@Override
public String getGroupName() {
return groupName;
}

@Override
public void setGroupName(String groupName) {
this.groupName = groupName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;

import edu.asu.diging.citesphere.core.model.jobs.JobStatus;
import edu.asu.diging.citesphere.core.model.jobs.impl.GroupSyncJob;

public interface GroupSyncJobRepository extends PagingAndSortingRepository<GroupSyncJob, String> {
Expand All @@ -15,4 +16,8 @@ public interface GroupSyncJobRepository extends PagingAndSortingRepository<Group
public List<GroupSyncJob> findByGroupIdIn(List<String> groupIds, Pageable page);

public long countByGroupIdIn(List<String> groupIds);

public List<GroupSyncJob> findByGroupIdInAndStatus(List<String> groupIds, JobStatus status, Pageable page);

public long countByGroupIdInAndStatus(List<String> groupIds, JobStatus status);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public interface ISyncJobManager {

GroupSyncJob getMostRecentJob(String groupId);

List<GroupSyncJob> getJobs(IUser user, Pageable page);
List<GroupSyncJob> getJobs(IUser user, Pageable page, String groupId, String status);

long getJobsCount(IUser user);
long getJobsCount(IUser user, String groupId, String status);

void cancelJob(String jobId);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.asu.diging.citesphere.core.service.jobs.impl;

import java.time.OffsetDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -12,8 +13,8 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

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;
Expand Down Expand Up @@ -62,18 +63,57 @@ public GroupSyncJob getMostRecentJob(String groupId) {
}

@Override
public List<GroupSyncJob> getJobs(IUser user, Pageable page) {
public List<GroupSyncJob> getJobs(IUser user, Pageable page, String groupId, String status) {
List<ICitationGroup> groups = citationManager.getGroups(user);
return jobRepo.findByGroupIdIn(groups.stream().map(g -> g.getGroupId() + "").collect(Collectors.toList()), page);
if (groups == null || groups.isEmpty()) {
return Collections.emptyList();
}
Map<String, String> groupNames = groups.stream().collect(
Collectors.toMap(g -> g.getGroupId() + "", ICitationGroup::getName, (existing, replacement) -> existing));
List<String> groupIds = groups.stream().map(g -> g.getGroupId() + "").collect(Collectors.toList());
if (StringUtils.hasText(groupId)) {
if (!groupIds.contains(groupId)) {
return Collections.emptyList();
}
groupIds = Collections.singletonList(groupId);
}
List<GroupSyncJob> jobs;
if (StringUtils.hasText(status)) {
try {
JobStatus jobStatus = JobStatus.valueOf(status.toUpperCase());
jobs = jobRepo.findByGroupIdInAndStatus(groupIds, jobStatus, page);
} catch (IllegalArgumentException e) {
return Collections.emptyList();
}
} else {
jobs = jobRepo.findByGroupIdIn(groupIds, page);
}
jobs.forEach(job -> job.setGroupName(groupNames.get(job.getGroupId())));
return jobs;
}

@Override
public long getJobsCount(IUser user) {
public long getJobsCount(IUser user, String groupId, String status) {
List<ICitationGroup> groups = citationManager.getGroups(user);
if (groups == null) {
return -1;
}
return jobRepo.countByGroupIdIn(groups.stream().map(g -> g.getGroupId() + "").collect(Collectors.toList()));
List<String> groupIds = groups.stream().map(g -> g.getGroupId() + "").collect(Collectors.toList());
if (StringUtils.hasText(groupId)) {
if (!groupIds.contains(groupId)) {
return 0;
}
groupIds = Collections.singletonList(groupId);
}
if (StringUtils.hasText(status)) {
try {
JobStatus jobStatus = JobStatus.valueOf(status.toUpperCase());
return jobRepo.countByGroupIdInAndStatus(groupIds, jobStatus);
} catch (IllegalArgumentException e) {
return 0;
}
}
return jobRepo.countByGroupIdIn(groupIds);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,72 @@
package edu.asu.diging.citesphere.web.user.jobs;

import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import edu.asu.diging.citesphere.core.model.jobs.JobStatus;
import edu.asu.diging.citesphere.core.service.ICitationManager;
import edu.asu.diging.citesphere.core.service.jobs.ISyncJobManager;
import edu.asu.diging.citesphere.model.bib.ICitationGroup;
import edu.asu.diging.citesphere.user.IUser;

@Controller
public class SyncJobsController {

@Autowired
private ISyncJobManager jobManager;

@Autowired
private ICitationManager citationManager;

@RequestMapping("/auth/jobs/sync/list")
public String list(Model model, @PageableDefault(sort = { "createdOn" }, direction = Direction.DESC) Pageable page,
Authentication authentication) {
long total = jobManager.getJobsCount((IUser) authentication.getPrincipal());
Authentication authentication, @RequestParam(name = "groupId", required = false) String groupId,
@RequestParam(name = "status", required = false) String status) {
IUser user = (IUser) authentication.getPrincipal();
List<ICitationGroup> groups = citationManager.getGroups(user);
model.addAttribute("groups", groups);
model.addAttribute("statuses", Arrays.asList(JobStatus.values()));
String selectedGroupId = StringUtils.hasText(groupId) ? groupId : "";
model.addAttribute("selectedGroupId", selectedGroupId);
String selectedGroupName = "Group";
if (StringUtils.hasText(groupId) && groups != null) {
selectedGroupName = groups.stream()
.filter(g -> g != null && groupId.equals(g.getGroupId() + ""))
.findFirst()
.map(g -> StringUtils.hasText(g.getName()) ? g.getName() : groupId)
.orElse("Group");
}
model.addAttribute("selectedGroupName", selectedGroupName);
String selectedStatus = StringUtils.hasText(status) ? status : "";
model.addAttribute("selectedStatus", selectedStatus);
String selectedStatusName = "Status";
if (StringUtils.hasText(status)) {
try {
JobStatus jobStatus = JobStatus.valueOf(status.toUpperCase());
selectedStatusName = jobStatus.name();
} catch (IllegalArgumentException e) {
selectedStatusName = "Status";
}
}
model.addAttribute("selectedStatusName", selectedStatusName);
long total = jobManager.getJobsCount(user, groupId, status);
if (total == -1) {
return "redirect:/";
}
model.addAttribute("jobs", jobManager.getJobs((IUser) authentication.getPrincipal(), page));
model.addAttribute("total", Math.ceil(total/page.getPageSize()));
model.addAttribute("jobs", jobManager.getJobs(user, page, groupId, status));
double pageCount = Math.ceil((double) total / page.getPageSize());
model.addAttribute("total", pageCount < 1 ? 1 : pageCount);
model.addAttribute("page", page.getPageNumber() + 1);
return "auth/jobs/list";
}
Expand Down
63 changes: 58 additions & 5 deletions citesphere/src/main/webapp/WEB-INF/views/auth/jobs/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,34 @@
<script th:inline="javascript">
//# sourceURL=page.js
$(function() {
var selectedGroup = /*[[${selectedGroupId}]]*/ "";
var selectedStatus = /*[[${selectedStatus}]]*/ "";
var totalPages = Number(/*[[${total}]]*/ 1) || 1;
var currentPage = Number(/*[[${page}]]*/ 1) || 1;
var baseUrl = /*[[@{/auth/jobs/sync/list}]]*/ "";
if (currentPage > totalPages) {
currentPage = totalPages;
}
if (currentPage < 1) {
currentPage = 1;
}
$('#pagination-top').twbsPagination({
totalPages: [(${total})],
startPage: [(${page})],
totalPages: totalPages,
startPage: currentPage,
prev: "«",
next: "»",
visiblePages: 10,
initiateStartPageClick: false,
onPageClick: function (event, page) {
window.location.href = "[(@{|/auth/jobs/sync/list|})]?page=" + (page - 1);
var params = [];
params.push("page=" + (page - 1));
if (selectedGroup && selectedGroup.trim().length > 0) {
params.push("groupId=" + encodeURIComponent(selectedGroup));
}
if (selectedStatus && selectedStatus.trim().length > 0) {
params.push("status=" + encodeURIComponent(selectedStatus));
}
window.location.href = baseUrl + "?" + params.join("&");
}
});
});
Expand All @@ -23,6 +42,38 @@
<div layout:fragment="content">
<h1>Jobs</h1>

<div style="margin-bottom: 15px;">
<div class="dropdown pull-left">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span th:text="${selectedGroupName}">Group</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a th:href="@{|/auth/jobs/sync/list${selectedStatus != null and selectedStatus != '' ? '?status=' + selectedStatus : ''}|}">All groups</a></li>
<li role="separator" class="divider"></li>
<li th:each="group : ${groups}">
<a th:href="@{|/auth/jobs/sync/list?groupId=${group.groupId}${selectedStatus != null and selectedStatus != '' ? '&status=' + selectedStatus : ''}|}"
th:text="${#strings.isEmpty(group.name) ? group.groupId : group.name}">Group Name</a>
</li>
</ul>
</div>
<div class="dropdown pull-left" style="margin-left: 10px;">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span th:text="${selectedStatusName}">Status</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
<li><a th:href="@{|/auth/jobs/sync/list${selectedGroupId != null and selectedGroupId != '' ? '?groupId=' + selectedGroupId : ''}|}">All statuses</a></li>
<li role="separator" class="divider"></li>
<li th:each="status : ${statuses}">
<a th:href="@{|/auth/jobs/sync/list?status=${status}${selectedGroupId != null and selectedGroupId != '' ? '&groupId=' + selectedGroupId : ''}|}"
th:text="${status}">Status</a>
</li>
</ul>
</div>
<div class="clearfix"></div>
</div>

<ul id="pagination-top" class="pagination-sm"></ul>

<table class="table table-striped">
Expand All @@ -37,8 +88,10 @@ <h1>Jobs</h1>
</tr>
<tr th:each="job:${jobs}">
<td>[[${job.id}]]</td>
<td><span class="label label-default">
<a th:href="@{|/auth/group/${job.groupId}/items|}" style="color: #ffffff">[[${job.groupId}]] </a>
<td>
<span class="label label-default">
<a th:href="@{|/auth/group/${job.groupId}/items|}" style="color: #ffffff"
th:text="${job.groupName} ?: ${job.groupId}">[[${job.groupId}]]</a>
</span>
</td>
<td>[[${job.status}]]</td>
Expand Down