| 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 24 hours"> |
| 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 24 hours"> |
| 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 <!-- TODO(kjlubick) when user can update time, use the human readabl
e value instead of 12h--> |
| 101 <th class="header right" colspan=2>All Tasks in last 24h</th> |
| 102 </thead> |
| 103 <template is="dom-repeat" items="[[_all_summary]]" as="item" index-as=
"idx"> |
| 104 <tr title="By default, this is the last 24 hours"> |
| 105 <td class="right"> |
| 106 <a href$="[[_makeURL(item.name,'',columns.*,sort)]]">[[item.huma
n]]</a>: |
| 107 </td> |
| 108 <td class="left">[[_idx(_all_counts, idx, _all_counts.*)]]</td> |
| 109 </tr> |
| 110 </template> |
| 111 </table> |
| 112 </div> |
| 113 |
| 114 </div> |
| 115 |
| 116 </template> |
| 117 <script> |
| 118 (function(){ |
| 119 var ALL_TASKS_SUMMARY = [ |
| 120 {name:"ALL", human:"All"}, |
| 121 {name:"BOT_DIED", human:"Bot Died"}, |
| 122 {name:"CANCELED", human:"Canceled"}, |
| 123 {name:"COMPLETED_SUCCESS", human:"Completed (Success)"}, |
| 124 {name:"COMPLETED_FAILURE", human:"Completed (Failure)"}, |
| 125 {name:"DEDUPED", human:"Deduplicated"}, |
| 126 {name:"EXPIRED", human:"Expired"}, |
| 127 {name:"PENDING", human:"Pending"}, |
| 128 {name:"RUNNING", human:"Running"}, |
| 129 {name:"TIMED_OUT", human:"Timed Out"}, |
| 130 ]; |
| 131 var SELECTED_TASKS_SUMMARY = [ |
| 132 {name:"BOT_DIED", human:"Bot Died"}, |
| 133 {name:"CANCELED", human:"Canceled"}, |
| 134 {name:"COMPLETED_SUCCESS", human:"Completed (Success)"}, |
| 135 {name:"COMPLETED_FAILURE", human:"Completed (Failure)"}, |
| 136 {name:"DEDUPED", human:"Deduplicated"}, |
| 137 {name:"EXPIRED", human:"Expired"}, |
| 138 {name:"PENDING", human:"Pending"}, |
| 139 {name:"RUNNING", human:"Running"}, |
| 140 {name:"TIMED_OUT", human:"Timed Out"}, |
| 141 ]; |
| 142 Polymer({ |
| 143 is: 'task-list-summary', |
| 144 |
| 145 behaviors: [SwarmingBehaviors.CommonBehavior], |
| 146 |
| 147 properties: { |
| 148 auth_headers: { |
| 149 type: Object, |
| 150 }, |
| 151 busy: { |
| 152 type: Boolean, |
| 153 computed: "_anyBusy(_busyArr1.*,_busyArr2.*,_busy3)", |
| 154 notify: true, |
| 155 }, |
| 156 count_params: { |
| 157 type: Object, |
| 158 }, |
| 159 columns: { |
| 160 type: Array, |
| 161 }, |
| 162 num_tasks: { |
| 163 type: Number, |
| 164 }, |
| 165 sort: { |
| 166 type: String, |
| 167 }, |
| 168 |
| 169 _busyArr1: { |
| 170 type:Array, |
| 171 value: function() { |
| 172 return []; |
| 173 } |
| 174 }, |
| 175 _busyArr2: { |
| 176 type:Array, |
| 177 value: function() { |
| 178 return []; |
| 179 } |
| 180 }, |
| 181 _busy3: { |
| 182 type: Boolean, |
| 183 value: false, |
| 184 }, |
| 185 _all_counts: { |
| 186 type: Array, |
| 187 value: function() { |
| 188 return []; |
| 189 } |
| 190 }, |
| 191 _all_summary: { |
| 192 type: Array, |
| 193 value: function() { |
| 194 return ALL_TASKS_SUMMARY; |
| 195 } |
| 196 }, |
| 197 _selected_counts: { |
| 198 type: Array, |
| 199 value: function() { |
| 200 return []; |
| 201 } |
| 202 }, |
| 203 _selected_exact: { |
| 204 type: Object, |
| 205 }, |
| 206 _selected_summary: { |
| 207 type: Array, |
| 208 value: function() { |
| 209 return SELECTED_TASKS_SUMMARY; |
| 210 } |
| 211 }, |
| 212 |
| 213 }, |
| 214 |
| 215 observers: [ |
| 216 "_recountEverything(auth_headers.*,count_params.*)" |
| 217 ], |
| 218 |
| 219 // Returns true if any of the busy signals are true. |
| 220 _anyBusy: function() { |
| 221 for (var i = 0; i<this._busyArr1.length; i++) { |
| 222 if (this._busyArr1[i].status) { |
| 223 return true; |
| 224 } |
| 225 } |
| 226 for (var i = 0; i<this._busyArr2.length; i++) { |
| 227 if (this._busyArr2[i].status) { |
| 228 return true; |
| 229 } |
| 230 } |
| 231 return this._busy3; |
| 232 }, |
| 233 |
| 234 // Returns the idx'th count of obj. |
| 235 _idx: function(obj, idx) { |
| 236 return obj && obj[idx] && obj[idx].count; |
| 237 }, |
| 238 |
| 239 // Recount all the task counts. This will make use of _getJsonAsyncArr bec
ause |
| 240 // the results will be generated in a dom-repeat. |
| 241 _recountEverything: function() { |
| 242 if (!this.auth_headers || !this.count_params) { |
| 243 return; |
| 244 } |
| 245 // convert to seconds because API uses seconds. |
| 246 var now = (new Date()).getTime()/1000; |
| 247 var last2Days = now - 24 * 60 * 60; |
| 248 |
| 249 // TODO(kjlubick): Once users can specify their own times, respect those
limits here. |
| 250 |
| 251 var queryObj = { |
| 252 start: [last2Days], |
| 253 }; |
| 254 |
| 255 for (var i = 0; i < ALL_TASKS_SUMMARY.length; i++) { |
| 256 if (this._all_counts.length < ALL_TASKS_SUMMARY.length) { |
| 257 this.push("_all_counts", {}); |
| 258 } |
| 259 queryObj.state = [ALL_TASKS_SUMMARY[i].name]; |
| 260 this._getJsonAsyncArr(i, "_all_counts","/api/swarming/v1/tasks/count",
"_busyArr1", |
| 261 this.auth_headers, queryObj); |
| 262 } |
| 263 |
| 264 queryObj = JSON.parse(JSON.stringify(this.count_params)); |
| 265 queryObj.start = [last2Days]; |
| 266 this._getJsonAsync("_selected_exact","/api/swarming/v1/tasks/count","_bu
sy3", |
| 267 this.auth_headers, queryObj); |
| 268 |
| 269 for (var j = 0; j < SELECTED_TASKS_SUMMARY.length; j++) { |
| 270 if (this._selected_counts.length < SELECTED_TASKS_SUMMARY.length) { |
| 271 this.push("_selected_counts", {}); |
| 272 } |
| 273 queryObj.state = [SELECTED_TASKS_SUMMARY[j].name]; |
| 274 this._getJsonAsyncArr(j, "_selected_counts","/api/swarming/v1/tasks/co
unt","_busyArr2", |
| 275 this.auth_headers, queryObj); |
| 276 } |
| 277 }, |
| 278 |
| 279 // _makeURL creates a task-list url that keeps the columns and sort requir
ements the same |
| 280 // while changing which state is represented. The preserveOthers signifies
if other |
| 281 // filtering parameters (e.g. tags) should be kept as well. |
| 282 _makeURL: function(state, preserveOthers) { |
| 283 var fstr = "state:"+state; |
| 284 if (preserveOthers) { |
| 285 var fstr = encodeURIComponent(fstr); |
| 286 var url = window.location.href; |
| 287 if (url.indexOf(fstr+"&") !== -1) { |
| 288 // The state filter is already on the list. |
| 289 return undefined; |
| 290 } |
| 291 if (url.indexOf("f=state") === -1) { |
| 292 return url + "&f=" + fstr; |
| 293 } |
| 294 // Things can't be in multiple states at once - so replace it. |
| 295 // %3A is url encoded colon (:) |
| 296 return url.replace(/f=state%3A[A-Z_]+/, `f=state%3A${fstr}`); |
| 297 } |
| 298 var params = { |
| 299 s: [this.sort], |
| 300 c: this.columns, |
| 301 } |
| 302 if (state) { |
| 303 params["f"] = [fstr]; |
| 304 } |
| 305 |
| 306 return window.location.href.split('?')[0] + '?' + sk.query.fromParamSet(
params); |
| 307 }, |
| 308 |
| 309 }); |
| 310 })(); |
| 311 </script> |
| 312 </dom-module> |
| OLD | NEW |