diff --git a/app/model/Issue.scala b/app/model/Issue.scala new file mode 100644 index 0000000..de0cef1 --- /dev/null +++ b/app/model/Issue.scala @@ -0,0 +1,4 @@ +package model + +case class Issue(number: Int, url: String, labels: Seq[Label], comments: Int) +case class Label(name: String, color: String) \ No newline at end of file diff --git a/app/model/Json.scala b/app/model/Json.scala index 8e810cb..2d6bab7 100644 --- a/app/model/Json.scala +++ b/app/model/Json.scala @@ -10,7 +10,18 @@ object GitHubJsonReaders { implicit def pullRequestReads: Reads[PullRequest] = ( (__ \ "number").read[Int] and (__ \ "html_url").read[String] and - (__ \ "_links" \ "comments" \ "href").read[String])(PullRequest) + (__ \ "_links" \ "comments" \ "href").read[String]).apply(PullRequest) + + + implicit def labelReads: Reads[Label] = ( + (__ \ "name").read[String] and + (__ \ "color").read[String]) apply (Label) + + implicit def issueReads: Reads[Issue] = ( + (__ \ "number").read[Int] and + (__ \ "url").read[String] and + (__ \ "labels").read[Seq[Label]] and + (__ \ "comments").read[Int]).apply(Issue) } @@ -25,10 +36,19 @@ object WebAppJsonWriters { "url" -> pr.url) } } + + implicit def issueWrites = new Writes[Issue] { + def writes(i: Issue): JsValue = { + Json.obj( + "number" -> i.number, + "url" -> i.url) + } + } implicit def projectWrites: Writes[Project] = ( (__ \ "name").write[String] and (__ \ "category").write[String] and (__ \ "githubRepo").write[String] and - (__ \ "pullRequests").lazyWrite(list[PullRequest](pullRequestWrites)))(unlift(Project.unapply)) + (__ \ "pullRequests").lazyWrite(list[PullRequest](pullRequestWrites)) and + (__ \ "issues").lazyWrite(list[Issue](issueWrites)))(unlift(Project.unapply)) } \ No newline at end of file diff --git a/app/model/Project.scala b/app/model/Project.scala index 27b8cbb..be3f23f 100644 --- a/app/model/Project.scala +++ b/app/model/Project.scala @@ -25,6 +25,6 @@ object Project { } } -case class Project(name: String, category: String, githubRepo: String, val pullRequests: List[PullRequest] = Nil) { +case class Project(name: String, category: String, githubRepo: String, val pullRequests: List[PullRequest] = Nil, val issues: List[Issue] = Nil) { } \ No newline at end of file diff --git a/app/org/scalaide/dashboard/projects/DataProcessorActor.scala b/app/org/scalaide/dashboard/projects/DataProcessorActor.scala index e1b4828..8ffe4d2 100644 --- a/app/org/scalaide/dashboard/projects/DataProcessorActor.scala +++ b/app/org/scalaide/dashboard/projects/DataProcessorActor.scala @@ -39,22 +39,41 @@ object DataProcessorActor { private val RepoAPI = "repos/" private val PullRequestCommand = "/pulls?" + private val IssuesRequestCommand = "/issues?" private val AccessTokenParam = s"access_token=$OAuthToken" + private def fetchProjectPullRequests(p: model.Project): Future[List[model.PullRequest]] = { + WS.url(BaseGitHubURL + RepoAPI + p.githubRepo + PullRequestCommand + AccessTokenParam).get().map { response => + import model.GitHubJsonReaders._ + val pullRequestsa = (response.json).validate[List[PullRequest]] + pullRequestsa.recover { + case a => + println(a) + Nil + }.get + } + } + private def fetchProjectIssues(p: model.Project): Future[List[model.Issue]] = { + WS.url(BaseGitHubURL + RepoAPI + p.githubRepo + IssuesRequestCommand + AccessTokenParam).get().map { response => + import model.GitHubJsonReaders._ + val issuesA = (response.json).validate[List[model.Issue]] + issuesA.recover { + case a => + println(a) + Nil + }.get.filter(_.labels.isEmpty) // TODO - Filter here or later? + } + } + def fetchAllProjects(sender: ActorRef) { val f = Future.traverse(Project.allProjects) { p => - WS.url(BaseGitHubURL + RepoAPI + p.githubRepo + PullRequestCommand + AccessTokenParam).get().map { response => - import model.GitHubJsonReaders._ - - val pullRequestsa = (response.json).validate[List[PullRequest]] - val prs = pullRequestsa.recover { - case a => - println(a) - Nil - }.get - p.copy(pullRequests = prs.sortBy(_.number)) - } + val pulls = fetchProjectPullRequests(p) + val issues = fetchProjectIssues(p) + for { + ps <- pulls + is <- issues + } yield p.copy(pullRequests = ps.sortBy(_.number), issues = is) } f.map { diff --git a/public/javascripts/projects.js b/public/javascripts/projects.js index e976d1a..76450da 100644 --- a/public/javascripts/projects.js +++ b/public/javascripts/projects.js @@ -10,6 +10,15 @@ function createPullRequestDom(pullRequest) { return nPullRequest; } +function createIssueDom(issue) { + var nPullRequest = document.createElement("a"); + nPullRequest.className = "pr"; + nPullRequest.target = "_blank" + nPullRequest.href = issue.url + nPullRequest.appendChild(document.createTextNode(issue.number)) + return nPullRequest; +} + function projectId(project) { return project.githubRepo.replace("/", "_").replace(".", "-"); } @@ -48,6 +57,25 @@ function createProjectDom(project) { nPR.appendChild(createPullRequestDom(prs[i])); } } + + var nPI = document.createElement("div"); + nPI.className = "project-pr"; + nProject.appendChild(nPI); + + var nPRIssue = document.createElement("span"); + nPRIssue.className = "label"; + nPRIssue.appendChild(document.createTextNode("unlabeled Issues:")) + nPI.appendChild(nPRIssue); + + var issues = project.issues; + + if (issues.length == 0) { + nPI.appendChild(document.createTextNode(" -")); + } else { + for ( var i = 0; i < issues.length; i++) { + nPI.appendChild(createIssueDom(issues[i])); + } + } return nProject; }