зеркало из https://github.com/mozilla/treeherder.git
links to revisions working. better resultstatus handling.
This commit is contained in:
Родитель
ed9f67d099
Коммит
7d4b6a8330
|
@ -75,13 +75,13 @@ body {
|
|||
}
|
||||
|
||||
.revision {
|
||||
font-size: 10px;
|
||||
font-size: 12px;
|
||||
padding-top: 2px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.platform {
|
||||
font-size: 11px;
|
||||
font-size: 12px;
|
||||
padding-left: 0;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
@ -96,7 +96,17 @@ body {
|
|||
padding-left: 0;
|
||||
}
|
||||
|
||||
.result-set .job-list {
|
||||
.revision-list {
|
||||
overflow: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.result-set .job-list-pad-left {
|
||||
padding-left: 8;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.result-set .job-list-nopad {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
@ -123,10 +133,127 @@ body {
|
|||
}
|
||||
|
||||
/* Custom Job buttons*/
|
||||
.btn-orange {
|
||||
background-color: rgba(221, 102, 2, 0.56);
|
||||
border-color: #dd6602;
|
||||
color: white;
|
||||
}
|
||||
.btn-orange:hover,
|
||||
.btn-orange:focus,
|
||||
.btn-orange:active,
|
||||
.btn-orange.active {
|
||||
background-color: #c45a02;
|
||||
border-color: #aa4f02;
|
||||
color: white;
|
||||
}
|
||||
.btn-orange.disabled:hover,
|
||||
.btn-orange.disabled:focus,
|
||||
.btn-orange.disabled:active,
|
||||
.btn-orange.disabled.active,
|
||||
.btn-orange[disabled]:hover,
|
||||
.btn-orange[disabled]:focus,
|
||||
.btn-orange[disabled]:active,
|
||||
.btn-orange[disabled].active,
|
||||
fieldset[disabled] .btn-orange:hover,
|
||||
fieldset[disabled] .btn-orange:focus,
|
||||
fieldset[disabled] .btn-orange:active,
|
||||
fieldset[disabled] .btn-orange.active {
|
||||
background-color: #dd6602;
|
||||
border-color: #dd6602;
|
||||
}
|
||||
|
||||
.btn-red {
|
||||
background-color: rgba(144, 0, 0, 0.60);
|
||||
border-color: #a1020e;
|
||||
color: white;
|
||||
}
|
||||
.btn-red:hover,
|
||||
.btn-red:focus,
|
||||
.btn-red:active,
|
||||
.btn-red.active {
|
||||
background-color: #a9020c;
|
||||
border-color: #90010a;
|
||||
color: white;
|
||||
}
|
||||
.btn-red.disabled:hover,
|
||||
.btn-red.disabled:focus,
|
||||
.btn-red.disabled:active,
|
||||
.btn-red.disabled.active,
|
||||
.btn-red[disabled]:hover,
|
||||
.btn-red[disabled]:focus,
|
||||
.btn-red[disabled]:active,
|
||||
.btn-red[disabled].active,
|
||||
fieldset[disabled] .btn-red:hover,
|
||||
fieldset[disabled] .btn-red:focus,
|
||||
fieldset[disabled] .btn-red:active,
|
||||
fieldset[disabled] .btn-red.active {
|
||||
background-color: #c2020e;
|
||||
border-color: #c2020e;
|
||||
}
|
||||
|
||||
.btn-dkblue {
|
||||
background-color: rgba(44, 71, 174, 0.57);
|
||||
border-color: #283aa2;
|
||||
color: white;
|
||||
}
|
||||
.btn-dkblue:hover,
|
||||
.btn-dkblue:focus,
|
||||
.btn-dkblue:active,
|
||||
.btn-dkblue.active {
|
||||
background-color: #263fc3;
|
||||
border-color: #2238ae;
|
||||
color: white;
|
||||
}
|
||||
.btn-dkblue.disabled:hover,
|
||||
.btn-dkblue.disabled:focus,
|
||||
.btn-dkblue.disabled:active,
|
||||
.btn-dkblue.disabled.active,
|
||||
.btn-dkblue[disabled]:hover,
|
||||
.btn-dkblue[disabled]:focus,
|
||||
.btn-dkblue[disabled]:active,
|
||||
.btn-dkblue[disabled].active,
|
||||
fieldset[disabled] .btn-dkblue:hover,
|
||||
fieldset[disabled] .btn-dkblue:focus,
|
||||
fieldset[disabled] .btn-dkblue:active,
|
||||
fieldset[disabled] .btn-dkblue.active {
|
||||
background-color: #2d48d6;
|
||||
border-color: #2d48d6;
|
||||
}
|
||||
|
||||
|
||||
.btn-green {
|
||||
background-color: rgba(2, 151, 42, 0.47);
|
||||
border-color: #028233;
|
||||
color: white;
|
||||
}
|
||||
.btn-green:hover,
|
||||
.btn-green:focus,
|
||||
.btn-green:active,
|
||||
.btn-green.active {
|
||||
background-color: #02a931;
|
||||
border-color: #019029;
|
||||
color: white;
|
||||
}
|
||||
.btn-green.disabled:hover,
|
||||
.btn-green.disabled:focus,
|
||||
.btn-green.disabled:active,
|
||||
.btn-green.disabled.active,
|
||||
.btn-green[disabled]:hover,
|
||||
.btn-green[disabled]:focus,
|
||||
.btn-green[disabled]:active,
|
||||
.btn-green[disabled].active,
|
||||
fieldset[disabled] .btn-green:hover,
|
||||
fieldset[disabled] .btn-green:focus,
|
||||
fieldset[disabled] .btn-green:active,
|
||||
fieldset[disabled] .btn-green.active {
|
||||
background-color: #02c238;
|
||||
border-color: #02c238;
|
||||
}
|
||||
|
||||
|
||||
.btn-purple {
|
||||
background-color: #9002c2;
|
||||
border-color: #9002c2;
|
||||
background-color: rgba(61, 2, 85, 0.50);
|
||||
border-color: #6f0296;
|
||||
color: white;
|
||||
}
|
||||
.btn-purple:hover,
|
||||
|
@ -239,8 +366,9 @@ fieldset[disabled] .btn-dkgray.active {
|
|||
}
|
||||
|
||||
.btn-black {
|
||||
background-color: #000000;
|
||||
background-color: rgba(0, 0, 0, 0.71);
|
||||
border-color: #000000;
|
||||
color: white;
|
||||
}
|
||||
.btn-black:hover,
|
||||
.btn-black:focus,
|
||||
|
@ -248,6 +376,7 @@ fieldset[disabled] .btn-dkgray.active {
|
|||
.btn-black.active {
|
||||
background-color: #000000;
|
||||
border-color: #000000;
|
||||
color: white;
|
||||
}
|
||||
.btn-black.disabled:hover,
|
||||
.btn-black.disabled:focus,
|
||||
|
@ -266,8 +395,9 @@ fieldset[disabled] .btn-black.active {
|
|||
}
|
||||
|
||||
.btn-pink {
|
||||
background-color: #fa73ac;
|
||||
background-color: rgba(250, 115, 172, 0.63);
|
||||
border-color: #fa73ac;
|
||||
color: white;
|
||||
}
|
||||
.btn-pink:hover,
|
||||
.btn-pink:focus,
|
||||
|
@ -275,6 +405,7 @@ fieldset[disabled] .btn-black.active {
|
|||
.btn-pink.active {
|
||||
background-color: #f95a9d;
|
||||
border-color: #f8428f;
|
||||
color: white;
|
||||
}
|
||||
.btn-pink.disabled:hover,
|
||||
.btn-pink.disabled:focus,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html ng-app="treeherder">
|
||||
<head>
|
||||
<title>Treeherder: {{ repo }}</title>
|
||||
<title>Treeherder: {{ repoName }}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<!-- Bootstrap -->
|
||||
|
@ -19,14 +19,16 @@
|
|||
<li class="dropdown" ng-controller="RepoDropDownCtrl">
|
||||
<a href="" class="dropdown-toggle" data-toggle="dropdown">Repos<b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="item in repos"><a href="" ng-click="changeRepo(item.name)">{{item.name}}</a></li>
|
||||
<li ng-repeat="item in repos">
|
||||
<a href="" ng-click="changeRepo(item)" ng-bind="item.name"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="divider-vertical"></li>
|
||||
<li><a href="">Help</a></li>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<span class="label label-info">{{ repo }}</span>
|
||||
<span class="label label-info">{{ repoName }}</span>
|
||||
<span class="label label-info">0 unstarred</span>
|
||||
</span>
|
||||
<p class="navbar-text pull-right">
|
||||
|
|
|
@ -2,16 +2,18 @@
|
|||
|
||||
treeherder.controller('JobsCtrl',
|
||||
function JobsCtrl($scope, $http, $rootScope, $routeParams, $log,
|
||||
thUrl, thResultSets) {
|
||||
thUrl, thResultSets, thRepos) {
|
||||
|
||||
// set the default repo to mozilla-central if not specified
|
||||
// set the default repo to mozilla-inbound if not specified
|
||||
if ($routeParams.hasOwnProperty("repo") &&
|
||||
$routeParams.repo !== "") {
|
||||
$rootScope.repo = $routeParams.repo;
|
||||
$rootScope.repoName = $routeParams.repo;
|
||||
} else {
|
||||
$rootScope.repo = "mozilla-inbound";
|
||||
$rootScope.repoName = "mozilla-central";
|
||||
}
|
||||
|
||||
thRepos.load($scope.repoName);
|
||||
|
||||
$scope.offset = 0;
|
||||
$scope.result_sets = [];
|
||||
$scope.isLoadingRsBatch = false;
|
||||
|
@ -40,72 +42,31 @@ treeherder.controller('JobsCtrl',
|
|||
|
||||
treeherder.controller('ResultSetCtrl',
|
||||
function ResultSetCtrl($scope, $rootScope, $http, $log,
|
||||
thUrl, thServiceDomain) {
|
||||
|
||||
var SEVERITY = {
|
||||
"busted": {
|
||||
level: 1,
|
||||
isCollapsedResults: false
|
||||
},
|
||||
"exception": {
|
||||
level: 2,
|
||||
isCollapsedResults: false
|
||||
},
|
||||
"testfailed": {
|
||||
level: 3,
|
||||
isCollapsedResults: false
|
||||
},
|
||||
"unknown": { // completed, unknown error
|
||||
level: 4,
|
||||
isCollapsedResults: true
|
||||
},
|
||||
"usercancel": {
|
||||
level: 5,
|
||||
isCollapsedResults: false
|
||||
},
|
||||
"retry": {
|
||||
level: 6,
|
||||
isCollapsedResults: true
|
||||
},
|
||||
"success": {
|
||||
level: 7,
|
||||
isCollapsedResults: true
|
||||
},
|
||||
"running": {
|
||||
level: 8,
|
||||
isCollapsedResults: true
|
||||
},
|
||||
"pending": {
|
||||
level: 100,
|
||||
isCollapsedResults: true
|
||||
}
|
||||
};
|
||||
thUrl, thServiceDomain, thResultStatusInfo) {
|
||||
|
||||
// determine the greatest severity this resultset contains
|
||||
// so that the UI can show depict that
|
||||
var getSeverity = function(result_types) {
|
||||
// so that the UI can depict that
|
||||
var getMostSevereResultStatus = function(result_types) {
|
||||
|
||||
var severity = "unknown",
|
||||
highest = SEVERITY.unknown;
|
||||
var status = "pending",
|
||||
rsInfo = thResultStatusInfo(status);
|
||||
|
||||
for (var i = 0; i < result_types.length; i++) {
|
||||
if (SEVERITY[result_types[i]]) {
|
||||
if (SEVERITY[result_types[i]].level < highest.level) {
|
||||
severity = result_types[i];
|
||||
highest = SEVERITY[severity];
|
||||
}
|
||||
} else {
|
||||
console.warn("WARNING: Unidentified result_type: " + result_types[i]);
|
||||
var res = thResultStatusInfo(result_types[i]);
|
||||
if (res.severity < rsInfo.severity) {
|
||||
status = result_types[i];
|
||||
rsInfo = res;
|
||||
}
|
||||
}
|
||||
return severity;
|
||||
return {status: status, isCollapsedResults: rsInfo.isCollapsedResults};
|
||||
};
|
||||
|
||||
$scope.resultSeverity = getSeverity($scope.resultset.result_types);
|
||||
var severeResultStatus = getMostSevereResultStatus($scope.resultset.result_types);
|
||||
$scope.resultSeverity = severeResultStatus.status;
|
||||
$scope.isCollapsedResults = severeResultStatus.isCollapsedResults;
|
||||
|
||||
// whether or not revision list for a resultset is collapsed
|
||||
$scope.isCollapsedRevisions = true;
|
||||
$scope.isCollapsedResults = SEVERITY[$scope.resultSeverity].isCollapsedResults;
|
||||
|
||||
// convert the platform names to human-readable using the TBPL
|
||||
// Config.js file
|
||||
|
@ -122,9 +83,6 @@ treeherder.controller('ResultSetCtrl',
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$scope.viewJob = function(job) {
|
||||
// set the selected job
|
||||
$rootScope.selectedJob = job;
|
||||
|
|
|
@ -21,10 +21,10 @@ treeherder.controller('MainCtrl',
|
|||
|
||||
|
||||
treeherder.controller('RepoDropDownCtrl',
|
||||
function RepoDropDownCtrl($scope, $http, $location, thRepos) {
|
||||
function RepoDropDownCtrl($scope, $rootScope, $http, $location, thRepos) {
|
||||
$scope.changeRepo = function(repo) {
|
||||
$location.search({repo: repo});
|
||||
thRepos.setCurrent(repo.name);
|
||||
$location.search({repo: repo.name});
|
||||
};
|
||||
thRepos.getRepos($scope);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -67,7 +67,7 @@ treeherder.directive('thStar', function ($parse, thStarTypes) {
|
|||
},
|
||||
link: function(scope, element, attrs) {
|
||||
scope.$watch('starId', function(newVal) {
|
||||
if (newVal) {
|
||||
if (newVal !== undefined) {
|
||||
scope.starType = thStarTypes[newVal];
|
||||
scope.badgeColorClass=scope.starType.star;
|
||||
scope.hoverText=scope.starType.name;
|
||||
|
@ -99,3 +99,14 @@ treeherder.directive('thShowJobs', function ($parse, thResultStatusInfo) {
|
|||
'{{ \' jobs\' | showOrHide:isCollapsedResults }}</a>'
|
||||
};
|
||||
});
|
||||
|
||||
treeherder.directive('thRevision', function($parse) {
|
||||
|
||||
return {
|
||||
restrict: "E",
|
||||
link: function(scope, element, attrs) {
|
||||
scope.revisionUrl = scope.currentRepo.url + "/rev/" + scope.revision.revision;
|
||||
},
|
||||
templateUrl: 'partials/thRevision.html'
|
||||
};
|
||||
});
|
||||
|
|
|
@ -29,7 +29,7 @@ treeherder.provider('thStarTypes', function() {
|
|||
},
|
||||
4: {
|
||||
name: "intermittent needs filing",
|
||||
star: "label-important"
|
||||
star: "label-danger"
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -40,6 +40,8 @@ treeherder.provider('thResultStatusInfo', function() {
|
|||
return function(resultState) {
|
||||
// default if there is no match, used for pending
|
||||
var resultStatusInfo = {
|
||||
severity: 100,
|
||||
isCollapsedResults: true,
|
||||
btnClass: "btn-default",
|
||||
showButtonIcon: "glyphicon glyphicon-time",
|
||||
jobButtonIcon: ""
|
||||
|
@ -48,56 +50,81 @@ treeherder.provider('thResultStatusInfo', function() {
|
|||
switch (resultState) {
|
||||
case "busted":
|
||||
resultStatusInfo = {
|
||||
btnClass: "btn-danger",
|
||||
severity: 1,
|
||||
isCollapsedResults: false,
|
||||
btnClass: "btn-red",
|
||||
showButtonIcon: "glyphicon glyphicon-fire",
|
||||
jobButtonIcon: "glyphicon glyphicon-fire"
|
||||
};
|
||||
break;
|
||||
case "exception":
|
||||
resultStatusInfo = {
|
||||
severity: 2,
|
||||
isCollapsedResults: false,
|
||||
btnClass: "btn-purple",
|
||||
showButtonIcon: "glyphicon glyphicon-fire",
|
||||
jobButtonIcon: "glyphicon glyphicon-fire"
|
||||
};
|
||||
break;
|
||||
case "running":
|
||||
case "testfailed":
|
||||
resultStatusInfo = {
|
||||
btnClass: "btn-ltgray",
|
||||
showButtonIcon: "glyphicon glyphicon-time",
|
||||
severity: 3,
|
||||
isCollapsedResults: false,
|
||||
btnClass: "btn-orange",
|
||||
showButtonIcon: "glyphicon glyphicon-warning-sign",
|
||||
jobButtonIcon: "glyphicon glyphicon-warning-sign"
|
||||
};
|
||||
break;
|
||||
case "unknown":
|
||||
resultStatusInfo = {
|
||||
severity: 4,
|
||||
isCollapsedResults: false,
|
||||
btnClass: "btn-black",
|
||||
showButtonIcon: "glyphicon glyphicon-warning-sign",
|
||||
jobButtonIcon: ""
|
||||
};
|
||||
break;
|
||||
case "usercancel":
|
||||
resultStatusInfo = {
|
||||
severity: 5,
|
||||
isCollapsedResults: true,
|
||||
btnClass: "btn-pink",
|
||||
showButtonIcon: "glyphicon glyphicon-stop",
|
||||
jobButtonIcon: ""
|
||||
};
|
||||
break;
|
||||
case "retry":
|
||||
resultStatusInfo = {
|
||||
btnClass: "btn-primary",
|
||||
severity: 6,
|
||||
isCollapsedResults: true,
|
||||
btnClass: "btn-dkblue",
|
||||
showButtonIcon: "glyphicon glyphicon-time",
|
||||
jobButtonIcon: ""
|
||||
};
|
||||
break;
|
||||
case "success":
|
||||
resultStatusInfo = {
|
||||
btnClass: "btn-success",
|
||||
severity: 7,
|
||||
isCollapsedResults: true,
|
||||
btnClass: "btn-green",
|
||||
showButtonIcon: "glyphicon glyphicon-ok",
|
||||
jobButtonIcon: ""
|
||||
};
|
||||
break;
|
||||
case "testfailed":
|
||||
case "running":
|
||||
resultStatusInfo = {
|
||||
btnClass: "btn-warning",
|
||||
showButtonIcon: "glyphicon glyphicon-warning-sign",
|
||||
jobButtonIcon: "glyphicon glyphicon-warning-sign"
|
||||
};
|
||||
break;
|
||||
case "usercancel":
|
||||
resultStatusInfo = {
|
||||
btnClass: "btn-pink",
|
||||
showButtonIcon: "glyphicon glyphicon-stop",
|
||||
severity: 8,
|
||||
isCollapsedResults: true,
|
||||
btnClass: "btn-ltgray",
|
||||
showButtonIcon: "glyphicon glyphicon-time",
|
||||
jobButtonIcon: ""
|
||||
};
|
||||
break;
|
||||
case "unknown":
|
||||
case "pending":
|
||||
resultStatusInfo = {
|
||||
btnClass: "btn-black",
|
||||
severity: 100,
|
||||
isCollapsedResults: true,
|
||||
btnClass: "btn-default",
|
||||
showButtonIcon: "glyphicon glyphicon-time",
|
||||
jobButtonIcon: ""
|
||||
};
|
||||
|
|
|
@ -9,10 +9,10 @@ treeherder.factory('thUrl',
|
|||
return thServiceDomain + "/api" + uri;
|
||||
},
|
||||
getProjectUrl: function(uri) {
|
||||
return thServiceDomain + "/api/project/" + $rootScope.repo + uri;
|
||||
return thServiceDomain + "/api/project/" + $rootScope.repoName + uri;
|
||||
},
|
||||
getLogViewerUrl: function(artifactId) {
|
||||
return "logviewer.html#?id=" + artifactId + "&repo=" + $rootScope.repo;
|
||||
return "logviewer.html#?id=" + artifactId + "&repo=" + $rootScope.repoName;
|
||||
}
|
||||
};
|
||||
return thUrl;
|
||||
|
@ -55,17 +55,48 @@ treeherder.factory('thResultSets',
|
|||
}]);
|
||||
|
||||
treeherder.factory('thRepos',
|
||||
['$http', 'thUrl', '$rootScope',
|
||||
function($http, thUrl, $rootScope) {
|
||||
['$http', 'thUrl', '$rootScope', '$log',
|
||||
function($http, thUrl, $rootScope, $log) {
|
||||
|
||||
// get the repositories (aka trees)
|
||||
// sample: 'resources/menu.json'
|
||||
var byName = function(name) {
|
||||
if ($rootScope.repos != undefined) {
|
||||
for (var i = 0; i < $rootScope.repos.length; i++) {
|
||||
var repo = $rootScope.repos[i];
|
||||
if (repo.name === name) {
|
||||
return repo;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
$log.warn("Repos list has not been loaded.")
|
||||
}
|
||||
$log.warn("'" + name + "' not found in repos list.")
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
getRepos: function($rootScope) {
|
||||
$http.get(thUrl.getRootUrl("/repository/")).
|
||||
// load the list of repos into $rootScope, and set the current repo.
|
||||
load: function(name) {
|
||||
return $http.get(thUrl.getRootUrl("/repository/")).
|
||||
success(function(data) {
|
||||
$rootScope.repos = data;
|
||||
if (name) {
|
||||
$rootScope.currentRepo = byName(name)
|
||||
}
|
||||
});
|
||||
},
|
||||
// return the currently selected repo
|
||||
getCurrent: function() {
|
||||
return $rootScope.currentRepo;
|
||||
},
|
||||
// set the current repo to one in the repos list
|
||||
setCurrent: function(name) {
|
||||
$rootScope.currentRepo = byName(name)
|
||||
},
|
||||
// get a repo object without setting anything
|
||||
getRepo: function(name) {
|
||||
return byName(name);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
|
||||
<span th-show-jobs severity="resultSeverity"></span>
|
||||
<a class="text-left btn btn-info th-revision-btn"
|
||||
ng-click="isCollapsedRevisions = !isCollapsedRevisions"
|
||||
>
|
||||
ng-click="isCollapsedRevisions = !isCollapsedRevisions">
|
||||
<div class="text-left">{{resultset.push_timestamp*1000|date:'medium'}} - {{resultset.author}} - {{resultset.revision}}</div>
|
||||
</a>
|
||||
|
||||
|
@ -42,15 +41,13 @@
|
|||
ng-class="{'col-md-4': (isCollapsedResults==false)}"
|
||||
class="revision-list">
|
||||
<ul class="list-unstyled">
|
||||
<li ng-repeat="revision in resultset.revision_list"
|
||||
class="revision">
|
||||
<span class="label label-default">{{revision.revision}}</span> {{revision.author}} <span ng-show="revision.comment" class="italic">"{{revision.comments}}"</span>
|
||||
<li ng-repeat="revision in resultset.revision_list">
|
||||
<th-revision></th-revision>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
<span ng-hide="isCollapsedResults"
|
||||
ng-class="{'col-md-8': (isCollapsedRevisions==false), 'col-md-12': (isCollapsedRevisions)}"
|
||||
class="job-list">
|
||||
ng-class="{'col-md-8 job-list-pad-left': (isCollapsedRevisions==false), 'col-md-12 job-list-nopad': (isCollapsedRevisions)}">
|
||||
<table class="table-hover">
|
||||
<tr ng-repeat="platform in resultset.platforms | filter:query">
|
||||
<td class="col-md-2 platform"><span>{{ platform.name }}</span></td>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<span class="revision">
|
||||
<a href="{{revisionUrl}}" target="_blank">{{revision.revision}}</a> {{revision.author}} <span ng-show="revision.comments"><em>"{{revision.comments}}"</em></span>
|
||||
</span>
|
Загрузка…
Ссылка в новой задаче