Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 <!-- | |
| 2 This in an HTML Import-able file that contains the definition | |
| 3 of the following elements: | |
| 4 | |
| 5 <task-list-summary> | |
| 6 | |
| 7 Usage: | |
| 8 | |
| 9 <task-list-summary></task-list-summary> | |
| 10 | |
| 11 This element summarizes and displays the results of the current query. | |
| 12 It links to some global queries (e.g. all running tasks) and some | |
| 13 sub queries (e.g. all pending tasks that match the rest of the | |
| 14 specified tags.) | |
| 15 | |
| 16 Properties: | |
| 17 // inputs | |
| 18 auth_headers: Object, the OAuth2 header to include in the request. This | |
| 19 should come from swarming-app. | |
| 20 columns: Array<String>, the columns the user has selected. Used to create | |
| 21 the links. | |
| 22 count_params: Object, representing the query params sent to the server based | |
| 23 on all the filterable items (e.g. tags). See task-filters for the | |
| 24 schema. | |
| 25 num_tasks: Number, The number of tasks shown (after filtering). | |
| 26 sort: String, the user's current sort string. Used to create the links. | |
| 27 | |
| 28 // outputs | |
| 29 busy: Boolean, if there are any network requests pending. | |
| 30 | |
| 31 Methods: | |
| 32 None. | |
| 33 | |
| 34 Events: | |
| 35 None. | |
| 36 --> | |
| 37 | |
| 38 <link rel="import" href="/res/imp/bower_components/iron-flex-layout/iron-flex-la yout-classes.html"> | |
| 39 | |
| 40 <link rel="import" href="/res/imp/common/swarming-app.html"> | |
| 41 <link rel="import" href="/res/imp/common/common-behavior.html"> | |
| 42 | |
| 43 <dom-module id="task-list-summary"> | |
| 44 <template> | |
| 45 <style include="swarming-app-style iron-flex"> | |
| 46 :host { | |
| 47 display: block; | |
| 48 border-left: 1px solid black; | |
| 49 padding: 5px 5px; | |
| 50 font-family: sans-serif; | |
| 51 } | |
| 52 .header { | |
| 53 font-size: 1.2em; | |
| 54 font-weight: bold; | |
| 55 } | |
| 56 .column.left { | |
| 57 margin-left: 10px; | |
| 58 } | |
| 59 .right { | |
| 60 text-align: right; | |
| 61 } | |
| 62 .left { | |
| 63 text-align: left; | |
| 64 } | |
| 65 </style> | |
| 66 | |
| 67 <div class="horizontal layout"> | |
| 68 | |
| 69 <div class="column"> | |
| 70 <table> | |
| 71 <thead> | |
| 72 <th class="header right" colspan=2>Selected</th> | |
| 73 </thead> | |
| 74 <tr> | |
| 75 <td class="right"> | |
| 76 Displayed: | |
| 77 </td> | |
| 78 <td class="left">[[num_tasks]]</td> | |
| 79 </tr> | |
| 80 <tr title="By default, these counts are from the last 2 days"> | |
| 81 <td class="right" > | |
| 82 Total: | |
| 83 </td> | |
| 84 <td class="left">[[_selected_exact.count]]</td> | |
| 85 </tr> | |
| 86 <template is="dom-repeat" items="[[_selected_summary]]" as="item" inde x-as="idx"> | |
| 87 <tr title="By default, these counts are from the last 2 days"> | |
| 88 <td class="right"> | |
| 89 <a href$="[[_makeURL(item.name,'true',columns.*,sort)]]">[[item. human]]</a>: | |
| 90 </td> | |
| 91 <td class="left">[[_idx(_selected_counts, idx, _selected_counts.*) ]]</td> | |
| 92 </tr> | |
| 93 </template> | |
| 94 </table> | |
| 95 </div> | |
| 96 | |
| 97 <div class="left column"> | |
| 98 <table> | |
| 99 <thead> | |
| 100 <th class="header right" colspan=2>All Tasks in Time Range</th> | |
| 101 </thead> | |
| 102 <template is="dom-repeat" items="[[_all_summary]]" as="item" index-as= "idx"> | |
| 103 <tr title="By default, this is the last 2 days"> | |
| 104 <td class="right"> | |
| 105 <a href$="[[_makeURL(item.name,'',columns.*,sort)]]">[[item.huma n]]</a>: | |
| 106 </td> | |
| 107 <td class="left">[[_idx(_all_counts, idx, _all_counts.*)]]</td> | |
| 108 </tr> | |
| 109 </template> | |
| 110 </table> | |
| 111 </div> | |
| 112 | |
| 113 </div> | |
| 114 | |
| 115 </template> | |
| 116 <script> | |
| 117 (function(){ | |
| 118 var ALL_TASKS_SUMMARY = [ | |
| 119 {name:"ALL", human:"All"}, | |
| 120 {name:"BOT_DIED", human:"Bot Died"}, | |
| 121 {name:"CANCELED", human:"Canceled"}, | |
| 122 {name:"COMPLETED_SUCCESS", human:"Completed (Success)"}, | |
| 123 {name:"COMPLETED_FAILURE", human:"Completed (Failure)"}, | |
| 124 {name:"DEDUPED", human:"Deduplicated"}, | |
| 125 {name:"EXPIRED", human:"Expired"}, | |
| 126 {name:"PENDING", human:"Pending"}, | |
| 127 {name:"RUNNING", human:"Running"}, | |
| 128 {name:"TIMED_OUT", human:"Timed Out"}, | |
| 129 ]; | |
| 130 var SELECTED_TASKS_SUMMARY = [ | |
| 131 {name:"BOT_DIED", human:"Bot Died"}, | |
| 132 {name:"CANCELED", human:"Canceled"}, | |
| 133 {name:"COMPLETED_SUCCESS", human:"Completed (Success)"}, | |
| 134 {name:"COMPLETED_FAILURE", human:"Completed (Failure)"}, | |
| 135 {name:"DEDUPED", human:"Deduplicated"}, | |
| 136 {name:"EXPIRED", human:"Expired"}, | |
| 137 {name:"PENDING", human:"Pending"}, | |
| 138 {name:"RUNNING", human:"Running"}, | |
| 139 {name:"TIMED_OUT", human:"Timed Out"}, | |
| 140 ]; | |
| 141 Polymer({ | |
| 142 is: 'task-list-summary', | |
| 143 | |
| 144 behaviors: [SwarmingBehaviors.CommonBehavior], | |
| 145 | |
| 146 properties: { | |
| 147 auth_headers: { | |
| 148 type: Object, | |
| 149 }, | |
| 150 busy: { | |
| 151 type: Boolean, | |
| 152 computed: "_anyBusy(_busyArr1.*,_busyArr2.*,_busy3)", | |
| 153 notify: true, | |
| 154 }, | |
| 155 count_params: { | |
| 156 type: Object, | |
| 157 }, | |
| 158 columns: { | |
| 159 type: Array, | |
| 160 }, | |
| 161 num_tasks: { | |
| 162 type: Number, | |
| 163 }, | |
| 164 sort: { | |
| 165 type: String, | |
| 166 }, | |
| 167 | |
| 168 _busyArr1: { | |
| 169 type:Array, | |
| 170 value: function() { | |
| 171 return []; | |
| 172 } | |
| 173 }, | |
| 174 _busyArr2: { | |
| 175 type:Array, | |
| 176 value: function() { | |
| 177 return []; | |
| 178 } | |
| 179 }, | |
| 180 _busy3: { | |
| 181 type: Boolean, | |
| 182 value: false, | |
| 183 }, | |
| 184 _all_counts: { | |
| 185 type: Array, | |
| 186 value: function() { | |
| 187 return []; | |
| 188 } | |
| 189 }, | |
| 190 _all_summary: { | |
| 191 type: Array, | |
| 192 value: function() { | |
| 193 return ALL_TASKS_SUMMARY; | |
| 194 } | |
| 195 }, | |
| 196 _selected_counts: { | |
| 197 type: Array, | |
| 198 value: function() { | |
| 199 return []; | |
| 200 } | |
| 201 }, | |
| 202 _selected_exact: { | |
| 203 type: Object, | |
| 204 }, | |
| 205 _selected_summary: { | |
| 206 type: Array, | |
| 207 value: function() { | |
| 208 return SELECTED_TASKS_SUMMARY; | |
| 209 } | |
| 210 }, | |
| 211 | |
| 212 }, | |
| 213 | |
| 214 observers: [ | |
| 215 "_recountEverything(auth_headers.*,count_params.*)" | |
| 216 ], | |
| 217 | |
| 218 _anyBusy: function() { | |
| 219 for (var i = 0; i<this._busyArr1.length; i++) { | |
| 220 if (this._busyArr1[i].status) { | |
| 221 return true; | |
| 222 } | |
| 223 } | |
| 224 for (var i = 0; i<this._busyArr2.length; i++) { | |
| 225 if (this._busyArr2[i].status) { | |
| 226 return true; | |
| 227 } | |
| 228 } | |
| 229 return this._busy3; | |
| 230 }, | |
| 231 | |
| 232 _idx: function(obj, idx) { | |
| 233 return obj && obj[idx] && obj[idx].count; | |
| 234 }, | |
| 235 | |
| 236 _recountEverything: function() { | |
| 237 if (!this.auth_headers || !this.count_params) { | |
| 238 return; | |
| 239 } | |
| 240 // convert to seconds because API uses seconds. | |
| 241 var now = (new Date()).getTime()/1000; | |
| 242 var last2Days = now - 2 * 24 * 60 * 60; | |
|
M-A Ruel
2017/02/06 20:04:32
While this works great on the staging instance, th
kjlubick
2017/02/06 21:18:02
Backed it off to 12 hours. Testing on prod shows
| |
| 243 | |
| 244 // TODO(kjlubick): Once users can specify their own times, respect those limits here. | |
| 245 | |
| 246 var queryObj = { | |
| 247 start: [last2Days], | |
| 248 }; | |
| 249 | |
| 250 for (var i = 0; i < ALL_TASKS_SUMMARY.length; i++) { | |
| 251 if (this._all_counts.length < ALL_TASKS_SUMMARY.length) { | |
| 252 this.push("_all_counts", {}); | |
| 253 } | |
| 254 queryObj.state = [ALL_TASKS_SUMMARY[i].name]; | |
| 255 this._getJsonAsyncArr(i, "_all_counts","/api/swarming/v1/tasks/count", "_busyArr1", | |
| 256 this.auth_headers, queryObj); | |
| 257 } | |
| 258 | |
| 259 queryObj = JSON.parse(JSON.stringify(this.count_params)); | |
| 260 queryObj.start = [last2Days]; | |
| 261 this._getJsonAsync("_selected_exact","/api/swarming/v1/tasks/count","_bu sy3", | |
| 262 this.auth_headers, queryObj); | |
| 263 | |
| 264 for (var j = 0; j < SELECTED_TASKS_SUMMARY.length; j++) { | |
| 265 if (this._selected_counts.length < SELECTED_TASKS_SUMMARY.length) { | |
| 266 this.push("_selected_counts", {}); | |
| 267 } | |
| 268 queryObj.state = [SELECTED_TASKS_SUMMARY[j].name]; | |
| 269 this._getJsonAsyncArr(j, "_selected_counts","/api/swarming/v1/tasks/co unt","_busyArr2", | |
| 270 this.auth_headers, queryObj); | |
| 271 } | |
| 272 }, | |
| 273 | |
| 274 // _makeURL creates a task-list url that keeps the columns and sort requir ements the same | |
| 275 // while changing which state is represented. The preserveOthers signifies if other | |
| 276 // filtering parameters (e.g. tags) should be kept as well. | |
| 277 _makeURL: function(state, preserveOthers) { | |
| 278 var fstr = "state:"+state; | |
| 279 if (preserveOthers) { | |
| 280 var fstr = encodeURIComponent(fstr); | |
| 281 var url = window.location.href; | |
| 282 if (url.indexOf(fstr+"&") !== -1) { | |
| 283 // The state filter is already on the list. | |
| 284 return undefined; | |
| 285 } | |
| 286 if (url.indexOf("f=state") === -1) { | |
| 287 return url + "&f=" + fstr; | |
| 288 } | |
| 289 // Things can't be in multiple states at once - so replace it. | |
| 290 // %3A is url encoded colon (:) | |
| 291 return url.replace(/f=state%3A[A-Z_]+/, `f=state%3A${fstr}`); | |
| 292 } | |
| 293 var params = { | |
| 294 s: [this.sort], | |
| 295 c: this.columns, | |
| 296 } | |
| 297 if (state) { | |
| 298 params["f"] = [fstr]; | |
| 299 } | |
| 300 | |
| 301 return window.location.href.split('?')[0] + '?' + sk.query.fromParamSet( params); | |
| 302 }, | |
| 303 | |
| 304 }); | |
| 305 })(); | |
| 306 </script> | |
| 307 </dom-module> | |
| OLD | NEW |