diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityDashboardController.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityController.java similarity index 64% rename from server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityDashboardController.java rename to server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityController.java index 0abb8f0f..9d65bfe1 100644 --- a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityDashboardController.java +++ b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityController.java @@ -9,13 +9,14 @@ @RestController @RequestMapping("/activity") -public class ActivityDashboardController { +public class ActivityController { @Autowired - private ActivityDashboardService activityDashboardService; + private ActivityService activityService; @GetMapping("/{login}") - public ResponseEntity getActivitiesByUser(@PathVariable String login) { - return ResponseEntity.ok(activityDashboardService.getActivities(login)); + public ResponseEntity getActivityByUser(@PathVariable String login) { + ActivityDTO activity = activityService.getActivity(login); + return ResponseEntity.ok(activity); } } diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivitiesDTO.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityDTO.java similarity index 67% rename from server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivitiesDTO.java rename to server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityDTO.java index 44427e46..f934c528 100644 --- a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivitiesDTO.java +++ b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityDTO.java @@ -2,13 +2,12 @@ import de.tum.in.www1.hephaestus.gitprovider.issue.IssueInfoDTO; import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequestInfoDTO; -import de.tum.in.www1.hephaestus.gitprovider.pullrequestreview.PullRequestReviewInfoDTO; import io.micrometer.common.lang.NonNull; import java.util.List; -public record ActivitiesDTO( +public record ActivityDTO( @NonNull List pullRequests, @NonNull List issues, - @NonNull List reviews) { + @NonNull List reviews) { } diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityDashboardService.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityDashboardService.java deleted file mode 100644 index 5132fdb0..00000000 --- a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityDashboardService.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.tum.in.www1.hephaestus.activitydashboard; - -import de.tum.in.www1.hephaestus.gitprovider.issue.Issue; -import de.tum.in.www1.hephaestus.gitprovider.issue.IssueInfoDTO; -import de.tum.in.www1.hephaestus.gitprovider.issue.IssueRepository; -import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequest; -import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequestInfoDTO; -import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequestRepository; -import de.tum.in.www1.hephaestus.gitprovider.pullrequestreview.PullRequestReview; -import de.tum.in.www1.hephaestus.gitprovider.pullrequestreview.PullRequestReviewInfoDTO; -import de.tum.in.www1.hephaestus.gitprovider.pullrequestreview.PullRequestReviewRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Set; - -@Service -public class ActivityDashboardService { - - @Autowired - private PullRequestRepository pullRequestRepository; - - @Autowired - private IssueRepository issueRepository; - - @Autowired - private PullRequestReviewRepository pullRequestReviewRepository; - - public ActivitiesDTO getActivities(String login) { - - List pullRequests = pullRequestRepository.findAssignedByLoginAndStates(login, Set.of(PullRequest.State.OPEN)); - List issues = List.of();//issueRepository.findAssignedByLoginAndStates(login, Set.of(Issue.State.OPEN)); - List reviews = List.of(); //TODO: which reviews to return here: all reviews of open PRs of others? what about where review is requested? - return new ActivitiesDTO( - pullRequests.stream().map(PullRequestInfoDTO::fromPullRequest).toList(), - issues.stream().map(IssueInfoDTO::fromIssue).toList(), - reviews.stream().map(PullRequestReviewInfoDTO::fromPullRequestReview).toList() - ); - } -} diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityService.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityService.java new file mode 100644 index 00000000..efb703fe --- /dev/null +++ b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ActivityService.java @@ -0,0 +1,70 @@ +package de.tum.in.www1.hephaestus.activitydashboard; + +import de.tum.in.www1.hephaestus.gitprovider.issue.Issue; +import de.tum.in.www1.hephaestus.gitprovider.issue.IssueInfoDTO; +import de.tum.in.www1.hephaestus.gitprovider.issue.IssueRepository; +import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequest; +import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequestInfoDTO; +import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequestRepository; +import de.tum.in.www1.hephaestus.gitprovider.pullrequestreview.PullRequestReview; +import de.tum.in.www1.hephaestus.gitprovider.pullrequestreview.PullRequestReviewInfoDTO; +import de.tum.in.www1.hephaestus.gitprovider.pullrequestreview.PullRequestReviewRepository; +import jakarta.transaction.Transactional; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Set; + +@Service +public class ActivityService { + + private PullRequestRepository pullRequestRepository; + + private IssueRepository issueRepository; + + private PullRequestReviewRepository pullRequestReviewRepository; + + public ActivityService(PullRequestRepository pullRequestRepository, IssueRepository issueRepository, PullRequestReviewRepository pullRequestReviewRepository) { + this.pullRequestRepository = pullRequestRepository; + this.issueRepository = issueRepository; + this.pullRequestReviewRepository = pullRequestReviewRepository; + } + + @Transactional + public ActivityDTO getActivity(String login) { + + List openPullRequests = pullRequestRepository + .findAssignedByLoginAndStates(login, Set.of(Issue.State.OPEN)) + .stream() + .map(PullRequestInfoDTO::fromPullRequest) + .toList(); + + List openIssues = issueRepository.findAssignedByLoginAndStates(login, Set.of(Issue.State.OPEN)) + .stream() + .map(IssueInfoDTO::fromIssue) + .toList(); + + List reviews = getReviewedOrRequestedPullRequests(login); + + return new ActivityDTO( + openPullRequests, + openIssues, + reviews + ); + } + + private List getReviewedOrRequestedPullRequests(String login) { + List reviews = pullRequestReviewRepository.findAllOpenReviewsByAuthorLogin(login) + .stream() + .map(ReviewActivityDto::fromPullRequestReview) + .toList(); + + List requestedReviews = pullRequestRepository.findReviewRequestedByLogin(login) + .stream() + .map(ReviewActivityDto::fromPullRequest) + .toList(); + + requestedReviews.addAll(reviews); + return requestedReviews; + } +} diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ReviewActivityDto.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ReviewActivityDto.java new file mode 100644 index 00000000..95571923 --- /dev/null +++ b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/activitydashboard/ReviewActivityDto.java @@ -0,0 +1,59 @@ +package de.tum.in.www1.hephaestus.activitydashboard; + +import java.time.OffsetDateTime; +import org.springframework.lang.NonNull; +import com.fasterxml.jackson.annotation.JsonInclude; + +import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequest; +import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequestInfoDTO; +import de.tum.in.www1.hephaestus.gitprovider.pullrequestreview.PullRequestReview; +import de.tum.in.www1.hephaestus.gitprovider.user.UserInfoDTO; + +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public record ReviewActivityDto( + @NonNull Long id, + @NonNull Boolean isDismissed, + @NonNull ReviewActivityState state, + @NonNull Integer codeComments, + UserInfoDTO author, + PullRequestInfoDTO pullRequest) { + + public static ReviewActivityDto fromPullRequestReview(PullRequestReview pullRequestReview) { + return new ReviewActivityDto( + pullRequestReview.getId(), + pullRequestReview.isDismissed(), + ReviewActivityDto.fromPullRequestReviewState(pullRequestReview.getState()), + pullRequestReview.getComments().size(), + UserInfoDTO.fromUser(pullRequestReview.getAuthor()), + PullRequestInfoDTO.fromPullRequest(pullRequestReview.getPullRequest()) + ); + } + + public static ReviewActivityDto fromPullRequest(PullRequest pullRequest) { + return new ReviewActivityDto( + pullRequest.getId(), + false, + ReviewActivityState.REVIEW_REQUESTED, + 0, + UserInfoDTO.fromUser(pullRequest.getAuthor()), + PullRequestInfoDTO.fromPullRequest(pullRequest) + ); + } + + public enum ReviewActivityState { + COMMENTED, + APPROVED, + CHANGES_REQUESTED, + REVIEW_REQUESTED, + UNKNOWN; + } + + public static ReviewActivityState fromPullRequestReviewState(PullRequestReview.State state) { + return switch (state) { + case COMMENTED -> ReviewActivityState.COMMENTED; + case APPROVED -> ReviewActivityState.APPROVED; + case CHANGES_REQUESTED -> ReviewActivityState.CHANGES_REQUESTED; + default -> ReviewActivityState.UNKNOWN; + }; + } +} \ No newline at end of file diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/issue/IssueRepository.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/issue/IssueRepository.java index 2df1cf45..d3db900d 100644 --- a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/issue/IssueRepository.java +++ b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/issue/IssueRepository.java @@ -16,7 +16,7 @@ public interface IssueRepository extends JpaRepository { JOIN FETCH i.author LEFT JOIN FETCH i.assignees LEFT JOIN FETCH i.repository - WHERE (i.author.login ILIKE :assigneeLogin OR LOWER(:assigneeLogin) IN (SELECT LOWER(u.login) FROM i.assignees u)) AND i.state IN :states + WHERE LOWER(:assigneeLogin) IN (SELECT LOWER(u.login) FROM i.assignees u) AND i.state IN :states AND TYPE(i) <> PullRequest ORDER BY i.createdAt DESC """) List findAssignedByLoginAndStates( diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/pullrequest/PullRequestRepository.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/pullrequest/PullRequestRepository.java index 324d1e13..472e7cab 100644 --- a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/pullrequest/PullRequestRepository.java +++ b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/pullrequest/PullRequestRepository.java @@ -33,4 +33,17 @@ SELECT MIN(p.createdAt) List findAssignedByLoginAndStates( @Param("assigneeLogin") String assigneeLogin, @Param("states") Set states); + + @Query(""" + SELECT p + FROM PullRequest p + LEFT JOIN FETCH p.labels + LEFT JOIN FETCH p.requestedReviewers + JOIN FETCH p.author + LEFT JOIN FETCH p.assignees + LEFT JOIN FETCH p.repository + WHERE LOWER(:reviewerLogin) IN (SELECT LOWER(u.login) FROM p.requestedReviewers u) + ORDER BY p.createdAt DESC + """) + List findReviewRequestedByLogin(@Param("reviewerLogin") String reviewerLogin); } \ No newline at end of file diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/pullrequestreview/PullRequestReviewRepository.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/pullrequestreview/PullRequestReviewRepository.java index 8a670813..1792faf1 100644 --- a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/pullrequestreview/PullRequestReviewRepository.java +++ b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/gitprovider/pullrequestreview/PullRequestReviewRepository.java @@ -44,4 +44,21 @@ List findAllInTimeframe( @Param("before") OffsetDateTime before, @Param("repository") Optional repository); +@Query(""" +SELECT prr +FROM PullRequestReview prr +LEFT JOIN FETCH prr.author +LEFT JOIN FETCH prr.pullRequest +LEFT JOIN FETCH prr.pullRequest.repository +LEFT JOIN FETCH prr.comments +WHERE prr.author.login ILIKE :authorLogin AND prr.pullRequest.state = 'OPEN' +AND prr.submittedAt = ( + SELECT MAX(subPrr.submittedAt) + FROM PullRequestReview subPrr + WHERE subPrr.pullRequest.id = prr.pullRequest.id +) +ORDER BY prr.submittedAt DESC +""") + List findAllOpenReviewsByAuthorLogin(@Param("authorLogin") String authorLogin); + }