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

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

Issue 2306103002: Add aliases to bot-page and refactor duplicated code (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@fix-buttons
Patch Set: rebase again Created 4 years, 3 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
11 bot-page shows the tasks, events, and dimensions of a bot. 11 bot-page shows the tasks, events, and dimensions of a bot.
12 12
13 This is a top-level element. 13 This is a top-level element.
14 14
15 Properties: 15 Properties:
16 bot_id: String, Used in testing to specify a bot_id 16 bot_id: String, Used in testing to specify a bot_id
17 client_id: String, Oauth 2.0 client id. It will be set by server-side 17 client_id: String, Oauth 2.0 client id. It will be set by server-side
18 template evaluation. 18 template evaluation.
19 19
20 Methods: 20 Methods:
21 None. 21 None.
22 22
23 Events: 23 Events:
24 None. 24 None.
25 --> 25 -->
26 26
27 <link rel="import" href="/res/imp/bower_components/iron-collapse/iron-collapse.h tml"> 27 <link rel="import" href="/res/imp/bower_components/iron-collapse/iron-collapse.h tml">
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-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">
31 <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" >
32 <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">
33 <link rel="import" href="/res/imp/bower_components/paper-icon-button/paper-icon- button.html">
34 <link rel="import" href="/res/imp/bower_components/polymer/polymer.html"> 35 <link rel="import" href="/res/imp/bower_components/polymer/polymer.html">
35 36
36 <link rel="import" href="/res/imp/common/swarming-app.html"> 37 <link rel="import" href="/res/imp/common/swarming-app.html">
37 <link rel="import" href="/res/imp/common/url-param.html"> 38 <link rel="import" href="/res/imp/common/url-param.html">
39 <link rel="import" href="/res/imp/common/error-toast.html">
38 40
39 <link rel="import" href="bot-page-data.html"> 41 <link rel="import" href="bot-page-data.html">
40 <link rel="import" href="bot-page-shared-behavior.html"> 42 <link rel="import" href="bot-page-shared-behavior.html">
41 43
42 44
43 <dom-module id="bot-page"> 45 <dom-module id="bot-page">
44 <template> 46 <template>
45 <style include="iron-flex iron-flex-alignment iron-positioning swarming-app- style"> 47 <style include="iron-flex iron-flex-alignment iron-positioning swarming-app- style">
46 48
47 .header { 49 .header {
(...skipping 15 matching lines...) Expand all
63 max-height: 50px; 65 max-height: 50px;
64 width: initial; 66 width: initial;
65 height: initial; 67 height: initial;
66 } 68 }
67 69
68 table { 70 table {
69 border-collapse: collapse; 71 border-collapse: collapse;
70 margin-left: 5px; 72 margin-left: 5px;
71 margin-bottom: 5px; 73 margin-bottom: 5px;
72 } 74 }
73 td, th { 75 td,
76 th {
74 border: 1px solid #BBB; 77 border: 1px solid #BBB;
75 padding: 5px; 78 padding: 5px;
76 } 79 }
77 80
78 .quarantined, .failed_task { 81 .quarantined,
82 .failed_task {
79 background-color: #ffdddd; 83 background-color: #ffdddd;
80 } 84 }
81 .dead { 85 .dead,
86 .bot_died {
82 background-color: #cccccc; 87 background-color: #cccccc;
83 } 88 }
84 89
85 .message { 90 .message {
86 white-space: pre-line; 91 white-space: pre-line;
87 font-family: monospace; 92 font-family: monospace;
88 } 93 }
89 94
90 .bot_state { 95 .bot_state {
91 white-space: pre; 96 white-space: pre;
92 font-family: monospace; 97 font-family: monospace;
93 margin-bottom: 10px; 98 margin-bottom: 10px;
94 } 99 }
95 100
96 .tabs { 101 .tabs {
97 background-color: #1F78B4; 102 background-color: #1F78B4;
98 color: #fff; 103 color: #fff;
99 max-width: 600px; 104 max-width: 600px;
100 --paper-checkbox-label-color: #fff; 105 --paper-checkbox-label-color: #fff;
101 margin-left: 5px; 106 margin-left: 5px;
102 } 107 }
103 108
104 .tasks_table, .events_table { 109 .tasks_table,
110 .events_table {
105 border: 3px solid #1F78B4; 111 border: 3px solid #1F78B4;
106 } 112 }
107 113
108 paper-checkbox { 114 paper-checkbox {
109 --paper-checkbox-label-color: #fff; 115 --paper-checkbox-label-color: #fff;
110 --paper-checkbox-checked-color: #fff; 116 --paper-checkbox-checked-color: #fff;
111 --paper-checkbox-checkmark-color: #000; 117 --paper-checkbox-checkmark-color: #000;
112 --paper-checkbox-unchecked-color: #fff; 118 --paper-checkbox-unchecked-color: #fff;
113 padding: 3px; 119 padding: 3px;
114 } 120 }
115 121
116 paper-tab.iron-selected { 122 paper-tab.iron-selected {
117 background-color: #A6CEE3; 123 background-color: #A6CEE3;
118 border: 3px solid #1F78B4; 124 border: 3px solid #1F78B4;
119 color: #000; 125 color: #000;
120 font-weight: bold; 126 font-weight: bold;
121 text-decoration: underline; 127 text-decoration: underline;
122 } 128 }
123 129
130 paper-dialog {
131 border-radius: 6px;
132 }
133
124 </style> 134 </style>
125 135
126 <url-param name="id" 136 <url-param name="id"
127 value="{{bot_id}}"> 137 value="{{bot_id}}">
128 </url-param> 138 </url-param>
129 <url-param name="show_all_events" 139 <url-param name="show_all_events"
130 value="{{_show_all}}"> 140 value="{{_show_all}}">
131 </url-param> 141 </url-param>
132 <url-param name="selected" 142 <url-param name="selected"
133 value="{{_selected}}"> 143 value="{{_selected}}">
134 </url-param> 144 </url-param>
135 <url-param name="show_state" 145 <url-param name="show_state"
136 value="{{_show_state}}"> 146 value="{{_show_state}}">
137 </url-param> 147 </url-param>
138 148
139 <swarming-app 149 <swarming-app
140 client_id="[[client_id]]" 150 client_id="[[client_id]]"
141 auth_headers="{{_auth_headers}}" 151 auth_headers="{{_auth_headers}}"
142 permissions="{{_permissions}}" 152 permissions="{{_permissions}}"
143 signed_in="{{_signed_in}}" 153 signed_in="{{_signed_in}}"
144 154
145 busy="[[_busy]]" 155 busy="[[_busy]]"
146 name="Swarming Bot Page"> 156 name="Swarming Bot Page">
147 157
148 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> 158 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2>
149 159
150 <div hidden$="[[_not(_signed_in)]]"> 160 <div hidden$="[[_not(_signed_in)]]">
151 161
152 <bot-page-data 162 <bot-page-data
163 id="data"
153 auth_headers="[[_auth_headers]]" 164 auth_headers="[[_auth_headers]]"
154 bot_id="[[bot_id]]" 165 bot_id="[[bot_id]]"
155 166
156 bot="{{_bot}}" 167 bot="{{_bot}}"
157 busy="{{_busy}}" 168 busy="{{_busy}}"
158 events="{{_events}}" 169 events="{{_events}}"
159 tasks="{{_tasks}}"> 170 tasks="{{_tasks}}">
160 </bot-page-data> 171 </bot-page-data>
161 172
162 <div class="header horizontal layout"> 173 <div class="header horizontal layout">
163 <paper-input class="id_input" label="Bot id" value="{{bot_id}}"></pape r-input> 174 <paper-input class="id_input" label="Bot id" value="{{bot_id}}"></pape r-input>
164 <button> 175 <button on-click="_refresh">
165 <iron-icon class="refresh" icon="icons:refresh"></iron-icon> 176 <iron-icon class="refresh" icon="icons:refresh"></iron-icon>
166 </button> 177 </button>
167 </div> 178 </div>
168 179
169 <div> 180 <div>
170 <table> 181 <table>
171 <tr class$="[[_isDead(_bot)]]"> 182 <tr class$="[[_isDead(_bot)]]">
172 <td>Last Seen</td> 183 <td>Last Seen</td>
173 <td title="[[_bot.human_last_seen_ts]]"> 184 <td title="[[_bot.human_last_seen_ts]]">
174 [[_timeDiffExact(_bot.last_seen_ts)]] ago</td> 185 [[_timeDiffExact(_bot.last_seen_ts)]] ago</td>
175 <td> 186 <td>
176 <!-- dom-ifs are slightly less performant than hidden$=, but 187 <!-- dom-ifs are slightly less performant than hidden$=, but
177 prevent things from first drawing and then hiding. We prefer to 188 prevent things from first drawing and then hiding. We prefer to
178 not flash buttons or quarantined messages --> 189 not flash buttons or quarantined messages -->
179 <template is="dom-if" if="[[_canShutdown(_bot,_permissions)]]"> 190 <template is="dom-if" if="[[_canShutdown(_bot,_permissions)]]">
180 <button class="raised"> 191 <button class="raised" on-click="_promptShutdown">
181 Shut Down Gracefully 192 Shut Down Gracefully
182 </button> 193 </button>
183 </template> 194 </template>
184 <template is="dom-if" if="[[_canDelete(_bot,_permissions)]]"> 195 <template is="dom-if" if="[[_canDelete(_bot,_permissions)]]">
185 <button class="raised"> 196 <button class="raised" on-click="_promptDelete">
186 Delete 197 Delete
187 </button> 198 </button>
188 </template> 199 </template>
189 </td> 200 </td>
190 </tr> 201 </tr>
191 <template is="dom-if" if="[[_bot.quarantined]]"> 202 <template is="dom-if" if="[[_bot.quarantined]]">
192 <tr class="quarantined"> 203 <tr class="quarantined">
193 <td>Quarantined</td> 204 <td>Quarantined</td>
194 <td colspan="2">[[_quarantineMessage(_bot)]]</td> 205 <td colspan="2">[[_quarantineMessage(_bot)]]</td>
195 </tr> 206 </tr>
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 <thead> 293 <thead>
283 <tr> 294 <tr>
284 <th>Task</th> 295 <th>Task</th>
285 <th>Started</th> 296 <th>Started</th>
286 <th>Duration</th> 297 <th>Duration</th>
287 <th>Result</th> 298 <th>Result</th>
288 </tr> 299 </tr>
289 </thead> 300 </thead>
290 <tbody> 301 <tbody>
291 <template is="dom-repeat" items="{{_tasks}}" as="task"> 302 <template is="dom-repeat" items="{{_tasks}}" as="task">
292 <tr> 303 <tr class$="[[_taskClass(task)]]">
293 <td><a target="_blank" href$="[[_taskLink(task.task_id)]]">[[t ask.name]]</a></td> 304 <td><a target="_blank" href$="[[_taskLink(task.task_id)]]">[[t ask.name]]</a></td>
294 <td>[[task.human_started_ts]]</td> 305 <td>[[task.human_started_ts]]</td>
295 <td title="[[task.human_completed_ts]]">[[task.human_duration] ]</td> 306 <td title="[[task.human_completed_ts]]">[[task.human_duration] ]</td>
296 <td>[[task.state]]</td> 307 <td>[[task.state]]</td>
297 </tr> 308 </tr>
298 </template> 309 </template>
299 </tbody> 310 </tbody>
300 </table> 311 </table>
301 </template> 312 </template>
302 313
(...skipping 18 matching lines...) Expand all
321 <td> 332 <td>
322 <a target="_blank" href$="[[_luciLink(_bot.version)]]">[[_sh orten(_bot.version,'8')]]</a> 333 <a target="_blank" href$="[[_luciLink(_bot.version)]]">[[_sh orten(_bot.version,'8')]]</a>
323 </td> 334 </td>
324 </tr> 335 </tr>
325 </template> 336 </template>
326 </tbody> 337 </tbody>
327 </table> 338 </table>
328 </template> 339 </template>
329 </div> 340 </div>
330 </div> 341 </div>
342 </swarming-app>
331 343
332 </swarming-app> 344 <paper-dialog id="prompt" modal on-iron-overlay-closed="_promptClosed">
345 <h2>Are you sure?</h2>
346 <div>Are you sure you want to [[_dialogPrompt]]?</div>
347 <div class="buttons">
348 <paper-button dialog-dismiss autofocus>No</paper-button>
349 <paper-button dialog-confirm>Yes</paper-button>
350 </div>
351 </paper-dialog>
352
353 <error-toast></error-toast>
333 354
334 </template> 355 </template>
335 <script> 356 <script>
336 (function(){ 357 (function(){
337 358
338 359
339 Polymer({ 360 Polymer({
340 is: 'bot-page', 361 is: 'bot-page',
341 362
342 behaviors: [ 363 behaviors: [
343 SwarmingBehaviors.BotPageBehavior, 364 SwarmingBehaviors.BotPageBehavior,
344 ], 365 ],
345 366
346 properties: { 367 properties: {
347 bot_id: { 368 bot_id: {
348 type: String, 369 type: String,
349 }, 370 },
350 client_id: { 371 client_id: {
351 type: String, 372 type: String,
352 }, 373 },
353 374
375 _auth_headers: {
376 type: Object,
377 },
354 _bot: { 378 _bot: {
355 type: Object, 379 type: Object,
356 }, 380 },
381 _dialogPrompt: {
382 type: String,
383 value: "",
384 },
357 _selected: { 385 _selected: {
358 type: Number, 386 type: Number,
359 }, 387 },
360 _show_all: { 388 _show_all: {
361 type: Boolean, 389 type: Boolean,
362 }, 390 },
363 _show_state: { 391 _show_state: {
364 type: Boolean, 392 type: Boolean,
365 } 393 }
366 }, 394 },
(...skipping 10 matching lines...) Expand all
377 return bot && !bot.is_dead && permissions.terminate_bot; 405 return bot && !bot.is_dead && permissions.terminate_bot;
378 }, 406 },
379 407
380 _concat: function(arr) { 408 _concat: function(arr) {
381 if (!arr) { 409 if (!arr) {
382 return ""; 410 return "";
383 } 411 }
384 return arr.join(" | "); 412 return arr.join(" | ");
385 }, 413 },
386 414
415 _deleteBot: function() {
416 swarming.postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/delete" ,
417 "Deleting "+this.bot_id, this._auth_headers);
418 },
419
387 _eventList(events, showAll) { 420 _eventList(events, showAll) {
388 if (!events) { 421 if (!events) {
389 return []; 422 return [];
390 } 423 }
391 return events.filter(function(e){ 424 return events.filter(function(e){
392 return showAll || e.message; 425 return showAll || e.message;
393 }); 426 });
394 }, 427 },
395 428
396 _isDead(bot){ 429 _isDead(bot){
(...skipping 16 matching lines...) Expand all
413 return 1; 446 return 1;
414 } 447 }
415 return 1 + arr.length; 448 return 1 + arr.length;
416 }, 449 },
417 450
418 _prettyPrint: function(obj) { 451 _prettyPrint: function(obj) {
419 obj = obj || {}; 452 obj = obj || {};
420 return JSON.stringify(obj, null, 2); 453 return JSON.stringify(obj, null, 2);
421 }, 454 },
422 455
456 _promptClosed: function(e) {
457 if (e.detail.confirmed) {
458 if (this._dialogPrompt.startsWith("shut down")) {
459 this._shutdownBot();
460 } else {
461 this._deleteBot();
462 }
463 }
464 },
465
466 _promptDelete: function() {
467 this.set("_dialogPrompt", "delete "+this.bot_id);
468 this.$.prompt.open();
469 },
470
471 _promptShutdown: function() {
472 this.set("_dialogPrompt", "shut down "+this.bot_id);
473 this.$.prompt.open();
474 },
475
423 _quarantineMessage: function(bot) { 476 _quarantineMessage: function(bot) {
424 if (bot && bot.quarantined) { 477 if (bot && bot.quarantined) {
425 var msg = bot.state.quarantined; 478 var msg = bot.state.quarantined;
426 // Sometimes, the quarantined message is actually in "error". This 479 // Sometimes, the quarantined message is actually in "error". This
427 // happens when the bot code has thrown an exception. 480 // happens when the bot code has thrown an exception.
428 if (msg === undefined || msg === "true" || msg === true) { 481 if (msg === undefined || msg === "true" || msg === true) {
429 msg = this._attribute(bot, "error"); 482 msg = this._attribute(bot, "error");
430 } 483 }
431 return msg || "True"; 484 return msg || "True";
432 } 485 }
433 return ""; 486 return "";
434 }, 487 },
435 488
489 _refresh: function() {
490 this.$.data.request();
491 },
492
436 _shorten: function(str, length) { 493 _shorten: function(str, length) {
437 if (!str || ! length) { 494 if (!str || ! length) {
438 return ""; 495 return "";
439 } 496 }
440 return str.substring(0, length); 497 return str.substring(0, length);
441 }, 498 },
442 499
500 _shutdownBot: function() {
501 swarming.postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/termina te",
502 "Shutting down "+this.bot_id, this._auth_headers);
503 },
504
443 _task: function(bot) { 505 _task: function(bot) {
444 return (bot && bot.task_id) || "idle"; 506 return (bot && bot.task_id) || "idle";
445 }, 507 },
446 508
509 _taskClass: function(task) {
510 if (task && task.internal_failure) {
511 return "bot_died";
512 }
513 if (task && task.failure) {
514 return "failed_task";
515 }
516 return "";
517 },
518
447 _taskLink: function(task_id) { 519 _taskLink: function(task_id) {
448 // TODO(kjlubick): Migrate this to /newui/ when ready 520 // TODO(kjlubick): Migrate this to /newui/ when ready
449 if (task_id) { 521 if (task_id) {
450 return "/user/task/" + task_id; 522 return "/user/task/" + task_id;
451 } 523 }
452 return undefined; 524 return undefined;
453 }, 525 },
454 526
455 _toggleState: function() { 527 _toggleState: function() {
456 this.set("_show_state", !this._show_state); 528 this.set("_show_state", !this._show_state);
457 } 529 }
458 530
459 }); 531 });
460 })(); 532 })();
461 </script> 533 </script>
462 </dom-module> 534 </dom-module>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698