Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(434)

Side by Side Diff: appengine/swarming/elements/res/imp/botpage/bot-page.html

Issue 2372323002: Add pageable data widget (Closed) Base URL: git@github.com:luci/luci-py@master
Patch Set: rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 <!-- 1 <!--
2 Copyright 2016 The LUCI Authors. All rights reserved. 2 Copyright 2016 The LUCI Authors. All rights reserved.
3 Use of this source code is governed under the Apache License, Version 2.0 3 Use of this source code is governed under the Apache License, Version 2.0
4 that can be found in the LICENSE file. 4 that can be found in the LICENSE file.
5 5
6 This in an HTML Import-able file that contains the definition 6 This in an HTML Import-able file that contains the definition
7 of the following elements: 7 of the following elements:
8 8
9 <bot-page> 9 <bot-page>
10 10
(...skipping 17 matching lines...) Expand all
28 <link rel="import" href="/res/imp/bower_components/iron-icon/iron-icon.html"> 28 <link rel="import" href="/res/imp/bower_components/iron-icon/iron-icon.html">
29 <link rel="import" href="/res/imp/bower_components/iron-icons/iron-icons.html"> 29 <link rel="import" href="/res/imp/bower_components/iron-icons/iron-icons.html">
30 <link rel="import" href="/res/imp/bower_components/paper-button/paper-button.htm l"> 30 <link rel="import" href="/res/imp/bower_components/paper-button/paper-button.htm l">
31 <link rel="import" href="/res/imp/bower_components/paper-checkbox/paper-checkbox .html"> 31 <link rel="import" href="/res/imp/bower_components/paper-checkbox/paper-checkbox .html">
32 <link rel="import" href="/res/imp/bower_components/paper-dialog/paper-dialog.htm l"> 32 <link rel="import" href="/res/imp/bower_components/paper-dialog/paper-dialog.htm l">
33 <link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html" > 33 <link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html" >
34 <link rel="import" href="/res/imp/bower_components/paper-tabs/paper-tabs.html"> 34 <link rel="import" href="/res/imp/bower_components/paper-tabs/paper-tabs.html">
35 <link rel="import" href="/res/imp/bower_components/polymer/polymer.html"> 35 <link rel="import" href="/res/imp/bower_components/polymer/polymer.html">
36 36
37 <link rel="import" href="/res/imp/common/error-toast.html"> 37 <link rel="import" href="/res/imp/common/error-toast.html">
38 <link rel="import" href="/res/imp/common/pageable-data.html">
38 <link rel="import" href="/res/imp/common/single-page-style.html"> 39 <link rel="import" href="/res/imp/common/single-page-style.html">
39 <link rel="import" href="/res/imp/common/swarming-app.html"> 40 <link rel="import" href="/res/imp/common/swarming-app.html">
40 <link rel="import" href="/res/imp/common/task-behavior.html"> 41 <link rel="import" href="/res/imp/common/task-behavior.html">
41 <link rel="import" href="/res/imp/common/url-param.html"> 42 <link rel="import" href="/res/imp/common/url-param.html">
42 43
43 <link rel="import" href="bot-page-data.html"> 44 <link rel="import" href="bot-page-data.html">
44 <link rel="import" href="bot-page-shared-behavior.html"> 45 <link rel="import" href="bot-page-shared-behavior.html">
45 46
46 47
47 <dom-module id="bot-page"> 48 <dom-module id="bot-page">
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 value="{{_show_state}}"> 94 value="{{_show_state}}">
94 </url-param> 95 </url-param>
95 96
96 <swarming-app 97 <swarming-app
97 client_id="[[client_id]]" 98 client_id="[[client_id]]"
98 auth_headers="{{_auth_headers}}" 99 auth_headers="{{_auth_headers}}"
99 permissions="{{_permissions}}" 100 permissions="{{_permissions}}"
100 server_version="{{_server_version}}" 101 server_version="{{_server_version}}"
101 signed_in="{{_signed_in}}" 102 signed_in="{{_signed_in}}"
102 103
103 busy="[[_busy]]" 104 busy="[[_or(_busy1,_busy2,_busy3)]]"
104 name="Swarming Bot Page"> 105 name="Swarming Bot Page">
105 106
106 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> 107 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2>
107 108
108 <div hidden$="[[_not(_signed_in)]]"> 109 <div hidden$="[[_not(_signed_in)]]">
109 110
110 <bot-page-data 111 <bot-page-data
111 id="data" 112 id="data"
112 auth_headers="[[_auth_headers]]" 113 auth_headers="[[_auth_headers]]"
113 bot_id="[[bot_id]]" 114 bot_id="[[bot_id]]"
114 115
115 bot="{{_bot}}" 116 bot="{{_bot}}"
116 busy="{{_busy}}" 117 busy="{{_busy1}}"
117 events="{{_events}}" 118 events="{{_events}}"
118 tasks="{{_tasks}}"> 119 tasks="{{_tasks}}"
120 on-reload="_clearAndReload">
119 </bot-page-data> 121 </bot-page-data>
120 122
121 <div class="header horizontal layout"> 123 <div class="header horizontal layout">
122 <paper-input class="id_input" label="Bot id" value="{{bot_id}}"></pape r-input> 124 <paper-input class="id_input" label="Bot id" value="{{bot_id}}"></pape r-input>
123 <button on-click="_refresh"> 125 <button on-click="_refresh">
124 <iron-icon class="refresh" icon="icons:refresh"></iron-icon> 126 <iron-icon class="refresh" icon="icons:refresh"></iron-icon>
125 </button> 127 </button>
126 </div> 128 </div>
127 129
128 <div> 130 <div>
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 <div class="bot_state">[[_prettyPrint(_bot.state)]]</div> 230 <div class="bot_state">[[_prettyPrint(_bot.state)]]</div>
229 </iron-collapse> 231 </iron-collapse>
230 </div> 232 </div>
231 233
232 <div class="tabs"> 234 <div class="tabs">
233 <paper-tabs selected="{{_selected}}" no-bar> 235 <paper-tabs selected="{{_selected}}" no-bar>
234 <paper-tab>Tasks</paper-tab> 236 <paper-tab>Tasks</paper-tab>
235 <paper-tab>Events</paper-tab> 237 <paper-tab>Events</paper-tab>
236 </paper-tabs> 238 </paper-tabs>
237 239
238 <template is="dom-if" if="[[_selected]]"> 240 <template is="dom-if" if="[[_showEvents]]">
239 <paper-checkbox checked="{{_show_all}}"> 241 <paper-checkbox checked="{{_show_all}}">
240 Show all events 242 Show all events
241 </paper-checkbox> 243 </paper-checkbox>
242 </template> 244 </template>
243 </div> 245 </div>
244 246
245 <template is="dom-if" if="[[_not(_selected)]]"> 247 <template is="dom-if" if="[[_not(_showEvents)]]">
246 <table class="tasks_table"> 248 <table class="tasks_table">
247 <thead> 249 <thead>
248 <tr> 250 <tr>
249 <th>Task</th> 251 <th>Task</th>
250 <th>Started</th> 252 <th>Started</th>
251 <th>Duration</th> 253 <th>Duration</th>
252 <th>Result</th> 254 <th>Result</th>
253 </tr> 255 </tr>
254 </thead> 256 </thead>
255 <tbody> 257 <tbody>
256 <template is="dom-repeat" items="{{_tasks}}" as="task"> 258 <template is="dom-repeat" items="{{_tasks}}" as="task">
257 <tr class$="[[_taskClass(task)]]"> 259 <tr class$="[[_taskClass(task)]]">
258 <td><a target="_blank" href$="[[_taskLink(task.task_id)]]">[[t ask.name]]</a></td> 260 <td><a target="_blank" href$="[[_taskLink(task.task_id)]]">[[t ask.name]]</a></td>
259 <td>[[task.human_started_ts]]</td> 261 <td>[[task.human_started_ts]]</td>
260 <td title="[[task.human_completed_ts]]">[[task.human_duration] ]</td> 262 <td title="[[task.human_completed_ts]]">[[task.human_duration] ]</td>
261 <td>[[task.state]]</td> 263 <td>[[task.state]]</td>
262 </tr> 264 </tr>
263 </template> 265 </template>
264 </tbody> 266 </tbody>
265 </table> 267 </table>
266 </template> 268 </template>
267 269
268 <template is="dom-if" if="[[_selected]]"> 270 <template is="dom-if" if="[[_showEvents]]">
269 <table class="events_table"> 271 <table class="events_table">
270 <thead> 272 <thead>
271 <tr> 273 <tr>
272 <th>Message</th> 274 <th>Message</th>
273 <th>Type</th> 275 <th>Type</th>
274 <th>Timestamp</th> 276 <th>Timestamp</th>
275 <th>Task ID</th> 277 <th>Task ID</th>
276 <th>Version</th> 278 <th>Version</th>
277 </tr> 279 </tr>
278 </thead> 280 </thead>
279 <tbody> 281 <tbody>
280 <template is="dom-repeat" items="{{_eventList(_events,_show_all)}} " as="event"> 282 <template is="dom-repeat" items="{{_eventList(_show_all,_events.*) }}" as="event">
281 <tr> 283 <tr>
282 <td class="message">[[event.message]]</a></td> 284 <td class="message">[[event.message]]</a></td>
283 <td>[[event.event_type]]</td> 285 <td>[[event.event_type]]</td>
284 <td>[[event.human_ts]]</td> 286 <td>[[event.human_ts]]</td>
285 <td><a target="_blank" href$="[[_taskLink(event.task_id)]]">[[ event.task_id]]</a></td> 287 <td><a target="_blank" href$="[[_taskLink(event.task_id)]]">[[ event.task_id]]</a></td>
286 <td class$="[[_classVersion(_server_version.bot_version,event. version)]]"> 288 <td class$="[[_classVersion(_server_version.bot_version,event. version)]]">
287 <a target="_blank" href$="[[_luciLink(event.version)]]">[[_s horten(event.version,'8')]]</a> 289 <a target="_blank" href$="[[_luciLink(event.version)]]">[[_s horten(event.version,'8')]]</a>
288 </td> 290 </td>
289 </tr> 291 </tr>
290 </template> 292 </template>
291 </tbody> 293 </tbody>
292 </table> 294 </table>
293 </template> 295 </template>
296 <!-- https://github.com/Polymer/polymer/issues/3669 hidden$ doesn't
297 respect truthiness, only booleanness, so we have _showEvents
298 instead of using _selected directly.-->
299 <pageable-data
300 id="page_tasks"
301 hidden$="[[_showEvents]]"
302 busy="{{_busy2}}"
303 label="Show more tasks"
304 output="{{_tasks}}"
305 parse="[[_parseTasks]]">
306 </pageable-data>
307 <pageable-data
308 id="page_events"
309 hidden$="[[_not(_showEvents)]]"
310 busy="{{_busy3}}"
311 label="Show more events"
312 output="{{_events}}"
313 parse="[[_parseEvents]]">
314 </pageable-data>
294 </div> 315 </div>
295 </swarming-app> 316 </swarming-app>
296 317
297 <paper-dialog id="prompt" modal on-iron-overlay-closed="_promptClosed"> 318 <paper-dialog id="prompt" modal on-iron-overlay-closed="_promptClosed">
298 <h2>Are you sure?</h2> 319 <h2>Are you sure?</h2>
299 <div>Are you sure you want to [[_dialogPrompt]]?</div> 320 <div>Are you sure you want to [[_dialogPrompt]]?</div>
300 <div class="buttons"> 321 <div class="buttons">
301 <paper-button dialog-dismiss autofocus>No</paper-button> 322 <paper-button dialog-dismiss autofocus>No</paper-button>
302 <paper-button dialog-confirm>Yes</paper-button> 323 <paper-button dialog-confirm>Yes</paper-button>
303 </div> 324 </div>
(...skipping 15 matching lines...) Expand all
319 properties: { 340 properties: {
320 bot_id: { 341 bot_id: {
321 type: String, 342 type: String,
322 }, 343 },
323 client_id: { 344 client_id: {
324 type: String, 345 type: String,
325 }, 346 },
326 347
327 _auth_headers: { 348 _auth_headers: {
328 type: Object, 349 type: Object,
350 observer: "_reload",
329 }, 351 },
330 _bot: { 352 _bot: {
331 type: Object, 353 type: Object,
332 }, 354 },
333 _dialogPrompt: { 355 _dialogPrompt: {
334 type: String, 356 type: String,
335 value: "", 357 value: "",
336 }, 358 },
337 _selected: { 359 _selected: {
338 type: Number, 360 type: Number,
339 }, 361 },
340 _show_all: { 362 _show_all: {
341 type: Boolean, 363 type: Boolean,
342 }, 364 },
365 _showEvents: {
366 type: Boolean,
367 computed: "_truthy(_selected)"
368 },
343 _show_state: { 369 _show_state: {
344 type: Boolean, 370 type: Boolean,
371 },
372
373 _parseEvents: {
374 type: Function,
375 value: function() {
376 return this.$.data.parseEvents.bind(this);
377 }
378 },
379 _parseTasks: {
380 type: Function,
381 value: function() {
382 return this.$.data.parseTasks.bind(this);
383 }
345 } 384 }
346 }, 385 },
347 386
348 _canCancel: function(bot, permissions) { 387 _canCancel: function(bot, permissions) {
349 return bot && bot.task_id && permissions.cancel_task; 388 return bot && bot.task_id && permissions.cancel_task;
350 }, 389 },
351 390
352 _canDelete: function(bot, permissions) { 391 _canDelete: function(bot, permissions) {
353 return bot && bot.is_dead && permissions.delete_bot; 392 return bot && bot.is_dead && permissions.delete_bot;
354 }, 393 },
355 394
356 _canShutdown: function(bot, permissions){ 395 _canShutdown: function(bot, permissions){
357 return bot && !bot.is_dead && permissions.terminate_bot; 396 return bot && !bot.is_dead && permissions.terminate_bot;
358 }, 397 },
359 398
360 _classVersion: function(serverVersion, otherVersion) { 399 _classVersion: function(serverVersion, otherVersion) {
361 if (serverVersion !== otherVersion) { 400 if (serverVersion !== otherVersion) {
362 return "old_version"; 401 return "old_version";
363 } 402 }
364 return ""; 403 return "";
365 }, 404 },
366 405
406 _clearAndReload: function(botID) {
407 this.$.page_tasks.clear();
408 this.$.page_events.clear();
409 this._reload();
410 },
411
367 _concat: function(arr) { 412 _concat: function(arr) {
368 if (!arr) { 413 if (!arr) {
369 return ""; 414 return "";
370 } 415 }
371 return arr.join(" | "); 416 return arr.join(" | ");
372 }, 417 },
373 418
374 _deleteBot: function() { 419 _deleteBot: function() {
375 swarming.postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/delete" , 420 swarming.postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/delete" ,
376 "Deleting "+this.bot_id, this._auth_headers); 421 "Deleting "+this.bot_id, this._auth_headers);
377 }, 422 },
378 423
379 _eventList(events, showAll) { 424 _eventList(showAll) {
380 if (!events) { 425 if (!this._events) {
381 return []; 426 return [];
382 } 427 }
383 return events.filter(function(e){ 428 return this._events.filter(function(e){
384 return showAll || e.message; 429 return showAll || e.message;
385 }); 430 });
386 }, 431 },
387 432
388 _isDead(bot){ 433 _isDead(bot){
389 if (bot && bot.is_dead) { 434 if (bot && bot.is_dead) {
390 return "dead"; 435 return "dead";
391 } 436 }
392 return ""; 437 return "";
393 }, 438 },
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 } 487 }
443 return msg || "True"; 488 return msg || "True";
444 } 489 }
445 return ""; 490 return "";
446 }, 491 },
447 492
448 _refresh: function() { 493 _refresh: function() {
449 this.$.data.request(); 494 this.$.data.request();
450 }, 495 },
451 496
497 _reload: function() {
498 if (!this._auth_headers) {
499 return;
500 }
501 var baseUrl = "/_ah/api/swarming/v1/bot/"+this.bot_id;
502 // We limit the fields on these two queries to make them faster.
503 this.$.page_tasks.load(baseUrl + "/tasks?fields=cursor%2Citems(abandoned _ts%2Cbot_version%2Ccompleted_ts%2Cduration%2Cexit_code%2Cfailure%2Cinternal_fai lure%2Cmodified_ts%2Cname%2Cstarted_ts%2Cstate%2Ctask_id%2Ctry_number)",
504 this._auth_headers, 30);
505 this.$.page_events.load(baseUrl + "/events?fields=cursor%2Citems(event_t ype%2Cmessage%2Cquarantined%2Ctask_id%2Cts%2Cversion)",
506 this._auth_headers, 50);
507 },
508
452 _shorten: function(str, length) { 509 _shorten: function(str, length) {
453 if (!str || ! length) { 510 if (!str || ! length) {
454 return ""; 511 return "";
455 } 512 }
456 return str.substring(0, length); 513 return str.substring(0, length);
457 }, 514 },
458 515
459 _shutdownBot: function() { 516 _shutdownBot: function() {
460 swarming.postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/termina te", 517 swarming.postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/termina te",
461 "Shutting down "+this.bot_id, this._auth_headers); 518 "Shutting down "+this.bot_id, this._auth_headers);
(...skipping 14 matching lines...) Expand all
476 }, 533 },
477 534
478 _toggleState: function() { 535 _toggleState: function() {
479 this.set("_show_state", !this._show_state); 536 this.set("_show_state", !this._show_state);
480 } 537 }
481 538
482 }); 539 });
483 })(); 540 })();
484 </script> 541 </script>
485 </dom-module> 542 </dom-module>
OLDNEW
« no previous file with comments | « appengine/swarming/elements/build/elements.html ('k') | appengine/swarming/elements/res/imp/botpage/bot-page-data.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698