Improves zuul-status design * This redesigns it so that it's more spread out and uses icons where necessary. This design is based on @guillaum design and so all credits go to him for the design. Change-Id: I8015dce97af43b3ba5f75d4122f82c7be06f9ec7
diff --git a/src/main/resources/static/zuul-status-view.html b/src/main/resources/static/zuul-status-view.html index a6063b9..e50beab 100644 --- a/src/main/resources/static/zuul-status-view.html +++ b/src/main/resources/static/zuul-status-view.html
@@ -14,7 +14,7 @@ <dom-module id="zuul-status-view"> <template> - <style> + <style include="shared-styles"> #view-container { display: block; } @@ -41,8 +41,8 @@ overflow: hidden; height: 20px; margin-bottom: 20px; - background-color: #f5f5f5; - border-radius: 4px; + background-color: #ededed; + border-radius: 1px; -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); box-shadow: inset 0 1px 2px rgba(0,0,0,.1); } @@ -50,87 +50,86 @@ float: left; width: 0; height: 100%; - font-size: 12px; + font-size: 11px; line-height: 20px; color: #fff; text-align: center; - background-color: #428bca; + background-color: #39a5dc; -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.15); box-shadow: inset 0 -1px 0 rgba(0,0,0,.15); -webkit-transition: width .6s ease; + -o-transition: width .6s ease; transition: width .6s ease; } - .zuul-job-result { - float: right; - width: 70px; - height: 15px; - margin: 2px 0 0 0; - } #progressBar { width: var(--progress-bar-width, 0%); } - .genericList th { - white-space: nowrap; - } - .genericList th, - .genericList td { - padding-right: 1rem; - } - .genericList tr th:first-of-type, - .genericList tr td:first-of-type { - padding-left: 1rem; - } - .genericList td { - flex-shrink: 0; - } - .genericList .topHeader { - color: var(--primary-text-color); - font-weight: var(--font-weight-bold); - text-align: left; - vertical-align: middle - } - .genericList a { - color: var(--primary-text-color); - text-decoration: none; - } - .genericList a:hover { - text-decoration: underline; - } #list { padding-bottom: 1em; } - .zuul-job-result { - float: right; - width: 70px; - height: 15px; - margin: 2px 0 0 0; - } - .label { + .labels { display: inline; padding: .2em .6em .3em; - font-size: 75%; - font-weight: 700; + font-size: 100%; + font-weight: 600; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; - border-radius: .25em; + border-radius: 0; } .label-danger { - background-color: #d9534f; + background-color: #c00; } .label-default { - background-color: #999; + background-color: #9c9c9c; } .label-info { - background-color: #5bc0de; + background-color: #00659c; } .label-success { - background-color: #5cb85c; + background-color: #3f9c35; } .label-warning { - background-color: #f0ad4e; + background-color: #ec7a08; + } + .zuul-job-result { + float: right; + width: 90px; + height: 20px; + margin: 2px 5px 0; + padding: 4px; + } + a { + color: var(--primary-text-color); + cursor: pointer; + display: inline-block; + text-decoration: none; + } + a:hover { + text-decoration: underline; + } + .time, { + align-items: center; + color: #757575; + display: flex; + } + #icon { + margin-right: 0.5em; + } + </style> + <style include="gr-change-list-styles"> + :host { + font-size: var(--font-size-normal); + } + .padding { + width: var(--default-horizontal-margin); + padding: 0.5em; + } + #changeList { + border-collapse: collapse; + width: 100%; } </style> <template is="dom-if" if="[[zuulUrl]]"> @@ -150,51 +149,86 @@ </div> <template is="dom-if" if="[[!zuulDisable]]" restamp="true"> <div class="bottom container"> - <table id="list" class="genericList"> - <tr class="headerRow"> - <th class="pipeline topHeader">Pipeline</th> - <th class="jobName topHeader">Job Name</th> - <th class="progressName topHeader">Progress</th> - </tr> - <tbody> - <template is="dom-repeat" items=[[_response]] as="response"> - <template is="dom-repeat" items=[[response.jobs]] as="jobs"> - <tr class="table"> - <td class="pipeline"> - [[jobs.pipeline]] - </td> - <td class="jobName"> - <a href="[[_computeReportURL(jobs)]]" target="_blank" - hidden$="[[!jobs.name]]"> - [[jobs.name]] - </a> - </td> - <td class="progressName"> - <template is="dom-if" if="[[_getResults(jobs, 'true', 'in progress')]]"> - <div class="progress zuul-job-result"> - <div class="progress-bar" - id="progressBar" - role="progressbar" - aria-valuenow$="[[_progressPercent(jobs)]]" - aria-valuemin="0" - aria-valuemax="100"></div> - </div> - </template> - <template is="dom-if" if="[[!_getResults(jobs, 'true', 'in progress')]]"> - <span class$="zuul-job-result label [[_renderJobStatusLabel(jobs)]]"> - [[_getResults(jobs)]] - </span> - </template> - </td> - </tr> - </template> + <table id="changeList"> + <template is="dom-repeat" items=[[_response]] as="response"> + <tr class="groupHeader"> + <td class="padding"> + <template is="dom-if" if="[[!_isFailing(response)]]" restamp="true"> + <span class="fullStatus success"> + <iron-icon id="icon" icon="gr-icons:check" style="color: #388E3C;"></iron-icon> + </span> + </template> + <template is="dom-if" if="[[_isFailing(response)]]" restamp="true"> + <span class="fullStatus failed"> + <iron-icon id="icon" icon="gr-icons:close" style="color: #D32F2F;"></iron-icon> + </span> + </template> + </td> + <td class="cell" colspan="15">[[response.name]]</td> + </tr> + <template is="dom-repeat" items=[[response.results.jobs]] as="jobs"> + <tr class="table"> + <td class="padding"></td> + <td class="cell jobName"> + <iron-icon id="icon" icon="zuul-icons:code"></iron-icon> + <a href="[[_computeReportURL(jobs)]]" target="_blank" + hidden$="[[!jobs.name]]"> + [[jobs.name]] + </a> + </td> + <td class="cell"> + <div class="time"> + <iron-icon id="icon" icon="zuul-icons:query-builder"></iron-icon> + <div class="remainingTime"> + [[_getRemainingTime(response.results.remaining_time)]] + </div> + </div> + </td> + <td class="cell"> + <div class="time"> + <iron-icon id="icon" icon="zuul-icons:today"></iron-icon> + <div class="enqueueTime"> + [[_getEnqueueTime(response.results.enqueue_time)]] + </div> + </div> + </td> + <td class="cell progressName"> + <template is="dom-if" if="[[_getResults(jobs, 'true', 'in progress')]]" restamp="true"> + <div class="progress zuul-job-result"> + <div class="progress-bar" + id="progressBar" + role="progressbar" + aria-valuenow$="[[_progressPercent(jobs)]]" + aria-valuemin="0" + aria-valuemax="100"></div> + </div> + </template> + <template is="dom-if" if="[[!_getResults(jobs, 'true', 'in progress')]]" restamp="true"> + <span class$="zuul-job-result labels [[_renderJobStatusLabel(jobs)]]"> + [[_getResults(jobs)]] + </span> + </template> + </td> + </tr> </template> - </tbody> + </template> </table> </div> </template> </div> </template> + <iron-iconset-svg name="zuul-icons" size="24"> + <svg> + <defs> + <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js --> + <g id="code"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path></g> + <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js --> + <g id="query-builder"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"></path></g> + <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js --> + <g id="today"><path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z"></path></g> + </defs> + </svg> + </iron-iconset-svg> </template> <script src="zuul-status-view.js"></script> </dom-module>
diff --git a/src/main/resources/static/zuul-status-view.js b/src/main/resources/static/zuul-status-view.js index 34475fa..105ebfe 100644 --- a/src/main/resources/static/zuul-status-view.js +++ b/src/main/resources/static/zuul-status-view.js
@@ -17,6 +17,9 @@ (function() { 'use strict'; + const DEFAULT_UPDATE_INTERVAL_MS = 1000 * 2; + const MAX_UPDATE_INTERVAL_MS = 1000 * 30 * 2; + /** * Wrapper around localStorage to prevent using it if you have it disabled. * @@ -55,9 +58,6 @@ } } - const DEFAULT_UPDATE_INTERVAL_MS = 1000 * 2; - const MAX_UPDATE_INTERVAL_MS = 1000 * 30 * 2; - Polymer({ is: 'zuul-status-view', properties: { @@ -156,18 +156,15 @@ /** * Fetch current progress state and update properties. * - * If not all Tricium analyzers are finished yet, this will - * set a timeout to update again later. - * - * It is assumed that this will only be called if the Tricium - * host is configured. - * * @return {Promise} Resolves upon completion. */ async _update() { try { const response = await this.getZuulStatus(this.change, this.revision); - this._response = response; + this._response = response.map((results, i) => ({ + name: results.jobs[i].pipeline, + results, + })); this._updateIntervalMs = DEFAULT_UPDATE_INTERVAL_MS; } catch (err) { this._updateIntervalMs = Math.min( @@ -352,5 +349,61 @@ this.reload(); }, + + _isFailing(results) { + if (results && results.results && + results.results.failing_reasons.length !== 0) { + return true; + } + + return false; + }, + + _getTime(ms, words) { + if (typeof (words) === 'undefined') { + words = false; + } + let seconds = (+ms) / 1000; + let minutes = Math.floor(seconds / 60); + let hours = Math.floor(minutes / 60); + seconds = Math.floor(seconds % 60); + minutes = Math.floor(minutes % 60); + let r = ''; + if (words) { + if (hours) { + r += hours + ' hr '; + } + r += minutes + ' min'; + } else { + if (hours < 10) { + r += '0'; + } + r += hours + ':'; + if (minutes < 10) { + r += '0'; + } + r += minutes + ':'; + if (seconds < 10) { + r += '0'; + } + r += seconds; + } + + return r; + }, + + _getRemainingTime(time) { + return time === null ? + 'unknown' : this._getTime(time, true); + }, + + _getEnqueueTime(ms) { + // Special format case for enqueue time to add style + let hours = 60 * 60 * 1000; + let now = Date.now(); + let delta = now - ms; + + return this._getTime(delta, true); + }, }); })();