Index: appengine_apps/chromium_cq_status/scripts/patchset.js |
diff --git a/appengine_apps/chromium_cq_status/scripts/patchset.js b/appengine_apps/chromium_cq_status/scripts/patchset.js |
index e359e6bf922479e860f8143909201ad81b813f46..fba30ab6feaaf67f3ad56031545e1bc668a5e5c9 100644 |
--- a/appengine_apps/chromium_cq_status/scripts/patchset.js |
+++ b/appengine_apps/chromium_cq_status/scripts/patchset.js |
@@ -72,7 +72,7 @@ tryjobStatus = [ |
function main() { |
- rows.textContent = 'Loading patch data...'; |
+ container.textContent = 'Loading patch data...'; |
loadPatchsetRecords(function(records) { |
displayRecords(records); |
scrollToHash(); |
@@ -104,10 +104,9 @@ function loadPatchsetRecords(callback) { |
} |
function displayRecords(records) { |
- rows.textContent = records.length ? '' : 'No records found.'; |
- var startTimestamp = null; |
- var openAttemptHeader = null; |
- var attempts = 0; |
+ container.textContent = ''; |
+ var currentAttempt = null; |
+ var attempts = []; |
records.forEach(function(record) { |
var action = record.fields.action; |
var info = actionInfo[action]; |
@@ -118,36 +117,56 @@ function displayRecords(records) { |
return; |
} |
if (info.startAttempt) { |
- startTimestamp = record.timestamp; |
- openAttemptHeader = addHeader(++attempts); |
+ currentAttempt = { |
+ start: record.timestamp, |
+ header: newHeader(attempts.length + 1), |
+ rows: [], |
+ } |
+ attempts.push(currentAttempt); |
+ } |
+ if (!currentAttempt) { |
+ console.warn('Unexpected record outside of start/end records:', record); |
} |
+ var duration = getDurationString(currentAttempt.start, record.timestamp); |
+ currentAttempt.rows.push(newRow(record.timestamp, duration, info.description, record.fields.message, info.cls)); |
if (info.stopAttempt) { |
- openAttemptHeader = null; |
+ currentAttempt.header.addText(' (' + duration + ')'); |
+ currentAttempt = null; |
} |
- addRow(startTimestamp, record.timestamp, info.description, record.fields.message, info.cls); |
}); |
- if (openAttemptHeader) { |
- openAttemptHeader.textContent += ' (in progress)'; |
+ if (currentAttempt) { |
+ currentAttempt.header.addText(' (in progress for ' + getDurationString(currentAttempt.start, Date.now() / 1000) + ')'); |
+ } |
+ if (attempts.length === 0) { |
+ container.textContent = 'No attempts found.'; |
+ return; |
} |
+ attempts.reverse(); |
+ attempts.forEach(function(attempt) { |
+ container.appendChild(attempt.header); |
+ attempt.rows.reverse(); |
+ attempt.rows.forEach(function(row) { |
+ container.appendChild(row); |
+ }); |
+ }); |
} |
-function addHeader(attempt) { |
- rows.appendChild(newElement('br')); |
- var anchor = newElement('a'); |
- anchor.name = attempt; |
- anchor.href = '#' + attempt; |
- var h3 = newElement('h3', 'Attempt #' + attempt); |
- anchor.appendChild(h3); |
- rows.appendChild(anchor); |
- return h3; |
+function newHeader(attemptNumber) { |
+ var header = newElement('h3'); |
+ var anchor = newElement('a', 'Attempt #' + attemptNumber); |
+ anchor.name = attemptNumber; |
+ anchor.href = '#' + attemptNumber; |
+ header.appendChild(anchor); |
+ header.addText = function(text) { |
+ anchor.textContent += text; |
+ }; |
+ return header; |
} |
-function addRow(startTimestamp, timestamp, description, message, cls) { |
+function newRow(timestamp, duration, description, message, cls) { |
var row = newElement('row', '', cls); |
row.appendChild(newElement('timestamp', getTimestampString(timestamp))); |
- if (startTimestamp !== null) { |
- row.appendChild(newElement('later', '(' + getLaterString(startTimestamp, timestamp) + ')')); |
- } |
+ row.appendChild(newElement('duration', '(' + duration + ')')); |
var descriptionNode = newElement('description') |
if (typeof description === 'string') { |
descriptionNode.textContent = description; |
@@ -158,7 +177,7 @@ function addRow(startTimestamp, timestamp, description, message, cls) { |
if (message) { |
row.appendChild(newElement('message', '(' + message + ')')); |
} |
- rows.appendChild(row); |
+ return row; |
} |
function newElement(tag, text, cls) { |
@@ -176,7 +195,7 @@ function getTimestampString(timestamp) { |
return new Date(timestamp * 1000).toISOString().replace('T', ' ').slice(0, 19); |
} |
-function getLaterString(startTimestamp, timestamp) { |
+function getDurationString(startTimestamp, timestamp) { |
var seconds = parseInt(timestamp - startTimestamp); |
if (seconds < 60) { |
return seconds + ' second' + plural(seconds); |
@@ -187,7 +206,7 @@ function getLaterString(startTimestamp, timestamp) { |
} |
var hours = parseInt(minutes / 60); |
minutes -= hours * 60; |
- return hours + ' hour' + plural(hours) + ' ' + minutes + ' minute' + plural(minutes); |
+ return hours + ' hour' + plural(hours) + (minutes ? ' ' + minutes + ' minute' + plural(minutes) : ''); |
} |
function plural(value) { |