diff --git a/app/assets/css/main.css b/app/assets/css/main.css
index 7f94457..cddaead 100644
--- a/app/assets/css/main.css
+++ b/app/assets/css/main.css
@@ -238,4 +238,8 @@ h3.library-identification{
padding-left: 1em;
font-family: 'Glyphicons Halflings';
content: "\e209";
+}
+
+.sublist{
+ padding-left: 23px;
}
\ No newline at end of file
diff --git a/app/controllers/Statistics.scala b/app/controllers/Statistics.scala
index 5faa382..59f7733 100644
--- a/app/controllers/Statistics.scala
+++ b/app/controllers/Statistics.scala
@@ -312,6 +312,16 @@ class Statistics @Inject()(
}
}
+ def affectedProjects(depId: Hashes) = ReadAction.async { implicit req =>
+ val (lastRefreshTime, resultsFuture) = projectReportsProvider.resultsForVersions(versions)
+ resultsFuture flatMap { case (successfulResults, failedResults) =>
+ val selection = dependencyCheckReportsParser.parseReports(successfulResults, failedResults)
+ Future.successful(Ok(views.html.affectedProjects(
+ dep = selection.groupedDependenciesByHashes(depId)
+ )).withHeaders("Content-type" -> "text/plain; charset=utf-8"))
+ }
+ }
+
def allFiles(selectorOption: Option[String]) = ReadAction.async { implicit req =>
val (lastRefreshTime, resultsFuture) = projectReportsProvider.resultsForVersions(versions)
resultsFuture flatMap { allResults =>
diff --git a/app/views/affectedProjects.scala.html b/app/views/affectedProjects.scala.html
new file mode 100644
index 0000000..20f7dea
--- /dev/null
+++ b/app/views/affectedProjects.scala.html
@@ -0,0 +1,6 @@
+@(dep: GroupedDependency)
+
+ @for(p <- dep.projects.toIndexedSeq.sorted){
+ - @friendlyProjectName(p)
+ }
+
diff --git a/app/views/dependencyDetailsInner.scala.html b/app/views/dependencyDetailsInner.scala.html
index 118bd1b..38f1948 100644
--- a/app/views/dependencyDetailsInner.scala.html
+++ b/app/views/dependencyDetailsInner.scala.html
@@ -63,7 +63,19 @@
Affected projects (@dep.projects.size)
-@for(p <- dep.projects.toIndexedSeq.sorted){- @friendlyProjectName(p)
}
+
+
+ @for(p <- dep.projects.toIndexedSeq.sorted){
+ - @friendlyProjectName(p)
+ }
+
+ @if(selectorOption.isDefined){
+
All affected projects (including those that aren't included by the filter)
+
+ }
+
Vulnerabilities (@dep.vulnerabilities.size)
@for(vuln <- dep.vulnerabilities.toSeq.sortBy(_.cvssScore.map(-_)); vulnPrefix = s"$depPrefix-vulnerabilities-details-${vuln.name}"){
diff --git a/conf/routes b/conf/routes
index 41ac2e3..72806b5 100644
--- a/conf/routes
+++ b/conf/routes
@@ -23,6 +23,7 @@ GET /https-test/with-redirect controllers.Application.testHttps(
GET /https-test controllers.Application.testHttps(allowRedirect: Boolean = false)
GET /stats/dependency-details.htmlf controllers.Statistics.dependencyDetails(selectorOption: Option[String], depPrefix: String, depId: com.ysoft.odc.Hashes)
+GET /stats/affected-projects.htmlf controllers.Statistics.affectedProjects(depId: com.ysoft.odc.Hashes)
GET /stats/basic controllers.Statistics.basic(selector: Option[String] = None)
GET /stats/basic/*selector controllers.Statistics.basic(selector: Option[String])
GET /stats/details controllers.Statistics.vulnerabilities(selector: Option[String], tagId: Option[Int])