aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/io/trygvis/esper/testing/jenkins/JenkinsDao.java67
-rw-r--r--src/main/java/io/trygvis/esper/testing/web/resource/AbstractResource.java11
-rw-r--r--src/main/java/io/trygvis/esper/testing/web/resource/JenkinsResource.java130
-rw-r--r--src/main/webapp/apps/jenkinsApp/JenkinsResources.js8
-rw-r--r--src/main/webapp/apps/jenkinsApp/jenkinsApp.js41
-rw-r--r--src/main/webapp/apps/jenkinsApp/job.html59
-rw-r--r--src/main/webapp/apps/jenkinsApp/server-list.html52
-rw-r--r--src/main/webapp/apps/jenkinsApp/server.html1
8 files changed, 259 insertions, 110 deletions
diff --git a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsDao.java b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsDao.java
index 117d91d..e94c7fd 100644
--- a/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsDao.java
+++ b/src/main/java/io/trygvis/esper/testing/jenkins/JenkinsDao.java
@@ -12,6 +12,7 @@ import java.util.List;
import static fj.data.Option.*;
import static io.trygvis.esper.testing.Util.toList;
import static io.trygvis.esper.testing.Util.toUuidArray;
+import static io.trygvis.esper.testing.util.sql.ResultSetF.getInt;
import static io.trygvis.esper.testing.util.sql.SqlOption.fromRs;
import static java.lang.System.*;
@@ -29,22 +30,16 @@ public class JenkinsDao {
this.c = c;
}
- private JenkinsServerDto jenkinsServer(ResultSet rs) throws SQLException {
- int i = 1;
- return new JenkinsServerDto(
- UUID.fromString(rs.getString(i++)),
- new DateTime(rs.getTimestamp(i++).getTime()),
- URI.create(rs.getString(i++)),
- rs.getBoolean(i));
- }
-
- private List<JenkinsServerDto> toServerList(ResultSet rs) throws SQLException {
- List<JenkinsServerDto> list = new ArrayList<>();
- while (rs.next()) {
- list.add(jenkinsServer(rs));
+ private SqlF<ResultSet,JenkinsServerDto> jenkinsServer = new SqlF<ResultSet, JenkinsServerDto>() {
+ public JenkinsServerDto apply(ResultSet rs) throws SQLException {
+ int i = 1;
+ return new JenkinsServerDto(
+ UUID.fromString(rs.getString(i++)),
+ new DateTime(rs.getTimestamp(i++).getTime()),
+ URI.create(rs.getString(i++)),
+ rs.getBoolean(i));
}
- return list;
- }
+ };
public static final SqlF<ResultSet, JenkinsJobDto> jenkinsJob = new SqlF<ResultSet, JenkinsJobDto>() {
public JenkinsJobDto apply(ResultSet rs) throws SQLException {
@@ -58,14 +53,6 @@ public class JenkinsDao {
}
};
- public List<JenkinsJobDto> toJobList(ResultSet rs) throws SQLException {
- List<JenkinsJobDto> list = new ArrayList<>();
- while (rs.next()) {
- list.add(jenkinsJob.apply(rs));
- }
- return list;
- }
-
public static final String JENKINS_BUILD = "uuid, created_date, job, file, entry_id, url, result, number, duration, timestamp, users";
public static final SqlF<ResultSet, JenkinsBuildDto> jenkinsBuild = new SqlF<ResultSet, JenkinsBuildDto>() {
@@ -111,18 +98,14 @@ public class JenkinsDao {
sql += " ORDER BY url";
try (PreparedStatement s = c.prepareStatement(sql)) {
- return toServerList(s.executeQuery());
+ return toList(s, jenkinsServer);
}
}
- public Option<JenkinsServerDto> selectServer(UUID uuid) throws SQLException {
+ public SqlOption<JenkinsServerDto> selectServer(UUID uuid) throws SQLException {
try (PreparedStatement s = c.prepareStatement("SELECT " + JENKINS_SERVER + " FROM jenkins_server WHERE uuid=?")) {
s.setString(1, uuid.toString());
- ResultSet rs = s.executeQuery();
- if (!rs.next()) {
- return none();
- }
- return some(jenkinsServer(rs));
+ return fromRs(s.executeQuery()).map(jenkinsServer);
}
}
@@ -138,7 +121,7 @@ public class JenkinsDao {
}
public List<JenkinsJobDto> selectJobsByServer(UUID server, PageRequest page) throws SQLException {
- try (PreparedStatement s = c.prepareStatement("SELECT " + JENKINS_JOB + " FROM jenkins_job WHERE server=? ORDER BY created_date LIMIT ? OFFSET ?")) {
+ try (PreparedStatement s = c.prepareStatement("SELECT " + JENKINS_JOB + " FROM jenkins_job WHERE server=? ORDER BY created_date DESC LIMIT ? OFFSET ?")) {
int i = 1;
s.setString(i++, server.toString());
s.setInt(i++, page.count.orSome(10));
@@ -157,9 +140,7 @@ public class JenkinsDao {
public int selectJobCountForServer(UUID uuid) throws SQLException {
try (PreparedStatement s = c.prepareStatement("SELECT count(1) FROM jenkins_job WHERE server=?")) {
s.setString(1, uuid.toString());
- ResultSet rs = s.executeQuery();
- rs.next();
- return rs.getInt(1);
+ return fromRs(s.executeQuery()).map(getInt).get();
}
}
@@ -192,6 +173,24 @@ public class JenkinsDao {
}
}
+ public List<JenkinsBuildDto> selectBuildByJob(UUID job, PageRequest page) throws SQLException {
+ try (PreparedStatement s = c.prepareStatement("SELECT " + JENKINS_BUILD + " FROM jenkins_build WHERE job=? ORDER BY created_date DESC LIMIT ? OFFSET ?")) {
+ int i = 1;
+ s.setString(i++, job.toString());
+ s.setInt(i++, page.count.orSome(10));
+ s.setInt(i, page.startIndex.orSome(0));
+ return toList(s, jenkinsBuild);
+ }
+ }
+
+ public int selectBuildCountByJob(UUID job) throws SQLException {
+ try (PreparedStatement s = c.prepareStatement("SELECT count(1) FROM jenkins_build WHERE job=?")) {
+ int i = 1;
+ s.setString(i, job.toString());
+ return fromRs(s.executeQuery()).map(getInt).get();
+ }
+ }
+
public UUID insertBuild(UUID job, UUID file, String entryId, URI url, String result, int number, int duration, long timestamp, UUID[] users) throws SQLException {
try (PreparedStatement s = c.prepareStatement("INSERT INTO jenkins_build(" + JENKINS_BUILD + ") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
UUID uuid = UUID.randomUUID();
diff --git a/src/main/java/io/trygvis/esper/testing/web/resource/AbstractResource.java b/src/main/java/io/trygvis/esper/testing/web/resource/AbstractResource.java
index cddec2c..929a48a 100644
--- a/src/main/java/io/trygvis/esper/testing/web/resource/AbstractResource.java
+++ b/src/main/java/io/trygvis/esper/testing/web/resource/AbstractResource.java
@@ -2,6 +2,7 @@ package io.trygvis.esper.testing.web.resource;
import fj.data.*;
import io.trygvis.esper.testing.*;
+import io.trygvis.esper.testing.util.sql.*;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
@@ -23,4 +24,14 @@ public class AbstractResource {
return server.some();
}
+
+ public <T> T sql(DatabaseAccess.DaosCallback<SqlOption<T>> callback) throws SQLException {
+ SqlOption<T> server = da.inTransaction(callback);
+
+ if(server.isNone()) {
+ throw new WebApplicationException(Response.Status.NOT_FOUND);
+ }
+
+ return server.get();
+ }
}
diff --git a/src/main/java/io/trygvis/esper/testing/web/resource/JenkinsResource.java b/src/main/java/io/trygvis/esper/testing/web/resource/JenkinsResource.java
index 33b3f88..292be71 100644
--- a/src/main/java/io/trygvis/esper/testing/web/resource/JenkinsResource.java
+++ b/src/main/java/io/trygvis/esper/testing/web/resource/JenkinsResource.java
@@ -1,6 +1,5 @@
package io.trygvis.esper.testing.web.resource;
-import fj.data.*;
import io.trygvis.esper.testing.*;
import io.trygvis.esper.testing.jenkins.*;
import io.trygvis.esper.testing.util.sql.*;
@@ -14,8 +13,6 @@ import java.sql.*;
import java.util.*;
import java.util.List;
-import static fj.data.Option.*;
-
@Path("/resource/jenkins")
public class JenkinsResource extends AbstractResource {
@@ -27,11 +24,11 @@ public class JenkinsResource extends AbstractResource {
@Path("/server")
@Produces(MediaType.APPLICATION_JSON)
public List<JenkinsServerJson> getServers() throws Exception {
- return da.inTransaction(new DatabaseAccess.DaosCallback<List<JenkinsServerJson>>() {
- public List<JenkinsServerJson> run(Daos daos) throws SQLException {
+ return da.inTransaction(new JenkinsDaosCallback<List<JenkinsServerJson>>() {
+ protected List<JenkinsServerJson> run() throws SQLException {
List<JenkinsServerJson> list = new ArrayList<>();
for (JenkinsServerDto server : daos.jenkinsDao.selectServers(false)) {
- list.add(getJenkinsServerJson(daos, server));
+ list.add(getJenkinsServerJson.apply(server));
}
return list;
}
@@ -44,15 +41,9 @@ public class JenkinsResource extends AbstractResource {
public JenkinsServerJson getServer(@PathParam("uuid") String s) throws Exception {
final UUID uuid = parseUuid(s);
- return get(new DatabaseAccess.DaosCallback<Option<JenkinsServerJson>>() {
- public Option<JenkinsServerJson> run(final Daos daos) throws SQLException {
- Option<JenkinsServerDto> o = daos.jenkinsDao.selectServer(uuid);
-
- if (o.isNone()) {
- return Option.none();
- }
-
- return some(getJenkinsServerJson(daos, o.some()));
+ return sql(new JenkinsDaosCallback<SqlOption<JenkinsServerJson>>() {
+ protected SqlOption<JenkinsServerJson> run() throws SQLException {
+ return daos.jenkinsDao.selectServer(uuid).map(getJenkinsServerJson);
}
});
}
@@ -61,30 +52,41 @@ public class JenkinsResource extends AbstractResource {
@Path("/job")
@Produces(MediaType.APPLICATION_JSON)
public List<JenkinsJobJson> getJobs(@MagicParam(query = "server") final UUID server, @MagicParam final PageRequest page) throws Exception {
- return da.inTransaction(new DatabaseAccess.DaosCallback<List<JenkinsJobJson>>() {
- public List<JenkinsJobJson> run(final Daos daos) throws SQLException {
+ return da.inTransaction(new JenkinsDaosCallback<List<JenkinsJobJson>>() {
+ protected List<JenkinsJobJson> run() throws SQLException {
List<JenkinsJobJson> jobs = new ArrayList<>();
for (JenkinsJobDto job : daos.jenkinsDao.selectJobsByServer(server, page)) {
- jobs.add(getJenkinsJobJson(job));
+ jobs.add(getJenkinsJobJson.apply(job));
}
return jobs;
}
});
}
- private JenkinsServerJson getJenkinsServerJson(Daos daos, JenkinsServerDto server) throws SQLException {
- int count = daos.jenkinsDao.selectJobCountForServer(server.uuid);
-
- List<JenkinsJobJson> jobs = new ArrayList<>();
- for (JenkinsJobDto jobDto : daos.jenkinsDao.selectJobsByServer(server.uuid, PageRequest.FIRST_PAGE)) {
- jobs.add(getJenkinsJobJson(jobDto));
- }
-
- return new JenkinsServerJson(server.uuid, server.createdDate, server.url, server.enabled, count, jobs);
+ @GET
+ @Path("/job/{uuid}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public JenkinsJobJson getJob(@MagicParam final UUID uuid) throws Exception {
+ return sql(new JenkinsDaosCallback<SqlOption<JenkinsJobJson>>() {
+ protected SqlOption<JenkinsJobJson> run() throws SQLException {
+ return daos.jenkinsDao.selectJob(uuid).map(getJenkinsJobJsonDetail);
+ }
+ });
}
- private JenkinsJobJson getJenkinsJobJson(JenkinsJobDto job) {
- return new JenkinsJobJson(job.uuid, job.createdDate, job.displayName.toNull());
+ @GET
+ @Path("/build")
+ @Produces(MediaType.APPLICATION_JSON)
+ public List<JenkinsBuildJson> getBuilds(@MagicParam(query = "job") final UUID job, @MagicParam final PageRequest page) throws Exception {
+ return da.inTransaction(new JenkinsDaosCallback<List<JenkinsBuildJson>>() {
+ protected List<JenkinsBuildJson> run() throws SQLException {
+ List<JenkinsBuildJson> builds = new ArrayList<>();
+ for (JenkinsBuildDto dto : daos.jenkinsDao.selectBuildByJob(job, page)) {
+ builds.add(getJenkinsBuildJson.apply(dto));
+ }
+ return builds;
+ }
+ });
}
public static UUID parseUuid(String s) {
@@ -94,6 +96,49 @@ public class JenkinsResource extends AbstractResource {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
}
+
+ abstract class JenkinsDaosCallback<T> implements DatabaseAccess.DaosCallback<T> {
+ protected Daos daos;
+
+ protected abstract T run() throws SQLException;
+
+ public T run(Daos daos) throws SQLException {
+ this.daos = daos;
+ return run();
+ }
+
+ protected SqlF<JenkinsServerDto, JenkinsServerJson> getJenkinsServerJson = new SqlF<JenkinsServerDto, JenkinsServerJson>() {
+ public JenkinsServerJson apply(JenkinsServerDto server) throws SQLException {
+ int count = daos.jenkinsDao.selectJobCountForServer(server.uuid);
+
+ List<JenkinsJobJson> jobs = new ArrayList<>();
+ for (JenkinsJobDto jobDto : daos.jenkinsDao.selectJobsByServer(server.uuid, PageRequest.FIRST_PAGE)) {
+ jobs.add(getJenkinsJobJson.apply(jobDto));
+ }
+
+ return new JenkinsServerJson(server.uuid, server.createdDate, server.url, server.enabled, count, jobs);
+ }
+ };
+
+ protected SqlF<JenkinsJobDto,JenkinsJobJson> getJenkinsJobJson = new SqlF<JenkinsJobDto, JenkinsJobJson>() {
+ public JenkinsJobJson apply(JenkinsJobDto job) throws SQLException {
+ return new JenkinsJobJson(job.uuid, job.createdDate, job.server, job.displayName.toNull());
+ }
+ };
+
+ protected SqlF<JenkinsJobDto,JenkinsJobJson> getJenkinsJobJsonDetail = new SqlF<JenkinsJobDto, JenkinsJobJson>() {
+ public JenkinsJobJson apply(JenkinsJobDto job) throws SQLException {
+ int buildCount = daos.jenkinsDao.selectBuildCountByJob(job.uuid);
+ return new JenkinsJobJson(job.uuid, job.createdDate, job.server, job.displayName.toNull(), buildCount);
+ }
+ };
+
+ protected SqlF<JenkinsBuildDto,JenkinsBuildJson> getJenkinsBuildJson = new SqlF<JenkinsBuildDto, JenkinsBuildJson>() {
+ public JenkinsBuildJson apply(JenkinsBuildDto dto) throws SQLException {
+ return new JenkinsBuildJson(dto.uuid, dto.createdDate, dto.result);
+ }
+ };
+ }
}
class JenkinsServerJson {
@@ -117,11 +162,36 @@ class JenkinsServerJson {
class JenkinsJobJson {
public final UUID uuid;
public final DateTime createdDate;
+ public final UUID server;
public final String displayName;
- JenkinsJobJson(UUID uuid, DateTime createdDate, String displayName) {
+ public final Integer buildCount;
+
+ JenkinsJobJson(UUID uuid, DateTime createdDate, UUID server, String displayName) {
this.uuid = uuid;
this.createdDate = createdDate;
+ this.server = server;
this.displayName = displayName;
+ this.buildCount = null;
+ }
+
+ JenkinsJobJson(UUID uuid, DateTime createdDate, UUID server, String displayName, int buildCount) {
+ this.uuid = uuid;
+ this.createdDate = createdDate;
+ this.server = server;
+ this.displayName = displayName;
+ this.buildCount = buildCount;
+ }
+}
+
+class JenkinsBuildJson {
+ public final UUID uuid;
+ public final DateTime createdDate;
+ public final String result;
+
+ JenkinsBuildJson(UUID uuid, DateTime createdDate, String result) {
+ this.uuid = uuid;
+ this.createdDate = createdDate;
+ this.result = result;
}
}
diff --git a/src/main/webapp/apps/jenkinsApp/JenkinsResources.js b/src/main/webapp/apps/jenkinsApp/JenkinsResources.js
index 0026932..89f3139 100644
--- a/src/main/webapp/apps/jenkinsApp/JenkinsResources.js
+++ b/src/main/webapp/apps/jenkinsApp/JenkinsResources.js
@@ -15,3 +15,11 @@ function JenkinsJob($resource) {
angular.
module('jenkinsJob', ['ngResource']).
factory('JenkinsJob', JenkinsJob);
+
+function JenkinsBuild($resource) {
+ return $resource('/resource/jenkins/build/:uuid', {uuid: '@uuid'});
+}
+
+angular.
+ module('jenkinsBuild', ['ngResource']).
+ factory('JenkinsBuild', JenkinsBuild);
diff --git a/src/main/webapp/apps/jenkinsApp/jenkinsApp.js b/src/main/webapp/apps/jenkinsApp/jenkinsApp.js
index e51c9f3..19d107d 100644
--- a/src/main/webapp/apps/jenkinsApp/jenkinsApp.js
+++ b/src/main/webapp/apps/jenkinsApp/jenkinsApp.js
@@ -1,14 +1,10 @@
'use strict';
-var jenkinsApp = angular.module('jenkinsApp', ['jenkinsServer', 'jenkinsJob', 'pagingTableService']).config(function ($routeProvider) {
+var jenkinsApp = angular.module('jenkinsApp', ['jenkinsServer', 'jenkinsJob', 'jenkinsBuild', 'pagingTableService']).config(function ($routeProvider) {
$routeProvider.
- when('/', {controller: ServerListCtrl, templateUrl: '/apps/jenkinsApp/server-list.html?noCache=' + noCache});
- $routeProvider.
- when('/server/:uuid', {controller: ServerCtrl, templateUrl: '/apps/jenkinsApp/server.html?noCache=' + noCache});
-// $routeProvider.otherwise({ redirectTo: '/' });
-
- // This fucks shit up
-// $locationProvider.html5Mode(true);
+ when('/', {controller: ServerListCtrl, templateUrl: '/apps/jenkinsApp/server-list.html?noCache=' + noCache}).
+ when('/server/:uuid', {controller: ServerCtrl, templateUrl: '/apps/jenkinsApp/server.html?noCache=' + noCache}).
+ when('/job/:uuid', {controller: JobCtrl, templateUrl: '/apps/jenkinsApp/job.html?noCache=' + noCache});
});
function ServerListCtrl($scope, $location, JenkinsServer) {
@@ -16,13 +12,8 @@ function ServerListCtrl($scope, $location, JenkinsServer) {
$scope.servers = servers;
});
- $scope.showServers = function () {
- $location.path('/');
- };
-
- $scope.showServer = function (uuid) {
- $location.path('/server/' + uuid);
- };
+ $scope.showServers = function () { $location.path('/'); };
+ $scope.showServer = function (uuid) { $location.path('/server/' + uuid); };
}
function ServerCtrl($scope, $location, $routeParams, JenkinsServer, JenkinsJob, PagingTableService) {
@@ -34,11 +25,19 @@ function ServerCtrl($scope, $location, $routeParams, JenkinsServer, JenkinsJob,
$scope.jobs = PagingTableService.create($scope, PagingTableService.defaultCallback(JenkinsJob, {server: serverUuid}));
- $scope.showServers = function () {
- $location.path('/');
- };
+ $scope.showServers = function () { $location.path('/'); };
+ $scope.showJob = function (uuid) { $location.path('/job/' + uuid); };
+}
+
+function JobCtrl($scope, $location, $routeParams, JenkinsJob, JenkinsBuild, PagingTableService) {
+ var jobUuid = $routeParams.uuid;
+
+ JenkinsJob.get({uuid: jobUuid}, function (job) {
+ $scope.job = job;
+ });
+
+ $scope.builds = PagingTableService.create($scope, PagingTableService.defaultCallback(JenkinsBuild, {job: jobUuid}));
- $scope.showServer = function (uuid) {
- $location.path('/server/' + uuid);
- };
+ $scope.showServers = function () { $location.path('/'); };
+ $scope.showServer = function (uuid) { $location.path('/server/' + $scope.job.server); };
}
diff --git a/src/main/webapp/apps/jenkinsApp/job.html b/src/main/webapp/apps/jenkinsApp/job.html
new file mode 100644
index 0000000..5113d2e
--- /dev/null
+++ b/src/main/webapp/apps/jenkinsApp/job.html
@@ -0,0 +1,59 @@
+<div class="container">
+
+ <div class="page-header">
+ <h1>Jenkins Job</h1>
+ </div>
+
+ <ul class="breadcrumb">
+ <li><a ng-click="showServers()">All Servers</a> <span class="divider">/</span></li>
+ <li><a ng-click="showServer()">Servers</a> <span class="divider">/</span></li>
+ <li class="active">Job</li>
+ </ul>
+
+ <h3>Overview</h3>
+
+ <table class="table">
+ <tbody>
+ <tr>
+ <th>URL</th>
+ <td><a href="{{job.displayName}}">{{job.displayName}}</a></td>
+ </tr>
+ <tr>
+ <th>Build count</th>
+ <td>{{job.buildCount}}</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h3>Recent Builds</h3>
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Build</th>
+ <th>Result</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="build in builds.rows" class="{{{true: 'success', false: 'error'}[build.success]}}">
+ <td>{{build.createdDate | date:'medium'}}</td>
+ <td>{{build.result}}</td>
+ <td><a class="btn" ng-click="showBuild(build.uuid)"><i class="icon-chevron-right"></i></a></td>
+ </tr>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td colspan="3">
+ <ul class="pager">
+ <li class="previous" ng-class="{disabled: builds.startIndex == 0}">
+ <a ng-click="builds.prev()">&larr; Older</a>
+ </li>
+ <li class="next">
+ <a ng-click="builds.next()">Newer &rarr;</a>
+ </li>
+ </ul>
+ </td>
+ </tr>
+ </tfoot>
+ </table>
+</div>
diff --git a/src/main/webapp/apps/jenkinsApp/server-list.html b/src/main/webapp/apps/jenkinsApp/server-list.html
index f335c1f..e488186 100644
--- a/src/main/webapp/apps/jenkinsApp/server-list.html
+++ b/src/main/webapp/apps/jenkinsApp/server-list.html
@@ -1,27 +1,29 @@
-<div class="page-header">
- <h1>Jenkins Servers</h1>
-</div>
+<div class="container">
+ <div class="page-header">
+ <h1>Jenkins Servers</h1>
+ </div>
-<ul class="breadcrumb">
- <li class="active">All Servers</li>
-</ul>
+ <ul class="breadcrumb">
+ <li class="active">All Servers</li>
+ </ul>
-<table class="table table-condensed">
- <thead>
- <tr>
- <th class="header">URL</th>
- <th class="header">Enabled</th>
- <th class=""></th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="server in servers">
- <td>{{server.url}}</td>
- <td>{{server.enabled}}</td>
- <td>
- <a href="{{server.url}}">Visit</a>
- <a ng-click="showServer(server.uuid)">Details</a>
- </td>
- </tr>
- </tbody>
-</table>
+ <table class="table table-condensed">
+ <thead>
+ <tr>
+ <th>URL</th>
+ <th>Enabled</th>
+ <th></th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="server in servers">
+ <td>{{server.url}}</td>
+ <td>{{server.enabled}}</td>
+ <td><a href="{{server.url}}">Visit</a></td>
+ <td><a class="btn" ng-click="showServer(server.uuid)"><i class="icon-chevron-right"></i></a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</div>
diff --git a/src/main/webapp/apps/jenkinsApp/server.html b/src/main/webapp/apps/jenkinsApp/server.html
index 8a784e8..03be57e 100644
--- a/src/main/webapp/apps/jenkinsApp/server.html
+++ b/src/main/webapp/apps/jenkinsApp/server.html
@@ -39,6 +39,7 @@
<td>{{job.createdDate | date:'medium'}}</td>
<td>{{job.displayName}}</td>
<td>{{job.uuid}}</td>
+ <td><a class="btn" ng-click="showJob(job.uuid)"><i class="icon-chevron-right"></i></a></td>
</tr>
</tbody>
<tfoot>