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

Side by Side Diff: appengine/swarming/elements/build/elements.html

Issue 2249143002: Make TaskList use Dynamic List (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@master
Patch Set: Address comments Created 4 years, 4 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
« no previous file with comments | « appengine/swarming/elements/Makefile ('k') | appengine/swarming/elements/elements.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 <!DOCTYPE html><html><head><!-- 1 <!DOCTYPE html><html><head><!--
2 @license 2 @license
3 Copyright (c) 2016 The Polymer Project Authors. All rights reserved. 3 Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE.txt 4 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE.txt
5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS.txt 6 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS.txt
7 Code distributed by Google as part of the polymer project is also 7 Code distributed by Google as part of the polymer project is also
8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt 8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
9 --><!-- 9 --><!--
10 @license 10 @license
(...skipping 14564 matching lines...) Expand 10 before | Expand all | Expand 10 after
14575 } 14575 }
14576 </style> 14576 </style>
14577 <app-header-layout> 14577 <app-header-layout>
14578 <app-header fixed=""> 14578 <app-header fixed="">
14579 <app-toolbar> 14579 <app-toolbar>
14580 <div class="title left">[[name]]</div> 14580 <div class="title left">[[name]]</div>
14581 <paper-spinner-lite class="left" active="[[busy]]"></paper-spinner-lit e> 14581 <paper-spinner-lite class="left" active="[[busy]]"></paper-spinner-lit e>
14582 14582
14583 <a class="left" href="/newui/">Home</a> 14583 <a class="left" href="/newui/">Home</a>
14584 <a class="left" href="/newui/botlist">Bot List</a> 14584 <a class="left" href="/newui/botlist">Bot List</a>
14585 <a class="left" href="/newui/tasklist">Task List</a>
14585 <div class="flex"></div> 14586 <div class="flex"></div>
14586 <auth-signin class="right" client-id="[[client_id]]" auth-headers="{{a uth_headers}}" signed-in="{{signed_in}}"> 14587 <auth-signin class="right" client-id="[[client_id]]" auth-headers="{{a uth_headers}}" signed-in="{{signed_in}}">
14587 </auth-signin> 14588 </auth-signin>
14588 </app-toolbar> 14589 </app-toolbar>
14589 </app-header> 14590 </app-header>
14590 <div class="main-content"> 14591 <div class="main-content">
14591 <content></content> 14592 <content></content>
14592 </div> 14593 </div>
14593 </app-header-layout> 14594 </app-header-layout>
14594 14595
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
14639 (function(){ 14640 (function(){
14640 // This behavior wraps up all the shared swarming functionality. 14641 // This behavior wraps up all the shared swarming functionality.
14641 SwarmingBehaviors.SwarmingBehavior = { 14642 SwarmingBehaviors.SwarmingBehavior = {
14642 14643
14643 _not: function(a) { 14644 _not: function(a) {
14644 return !a; 14645 return !a;
14645 }, 14646 },
14646 14647
14647 _or: function() { 14648 _or: function() {
14648 var result = false; 14649 var result = false;
14649 // can't use .foreach, as arguments isn't really a function. 14650 // can't use .foreach, as arguments isn't really an Array.
14650 for (var i = 0; i < arguments.length; i++) { 14651 for (var i = 0; i < arguments.length; i++) {
14651 result = result || arguments[i]; 14652 result = result || arguments[i];
14652 } 14653 }
14653 return result; 14654 return result;
14654 }, 14655 },
14655 }; 14656 };
14656 })(); 14657 })();
14657 </script> 14658 </script>
14658 <dom-module id="swarming-index" assetpath="/res/imp/index/"> 14659 <dom-module id="swarming-index" assetpath="/res/imp/index/">
14659 <template> 14660 <template>
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
14836 } 14837 }
14837 }, 14838 },
14838 14839
14839 _sortChange: function(e) { 14840 _sortChange: function(e) {
14840 // The event we get from sort-toggle tells us the name of what needs 14841 // The event we get from sort-toggle tells us the name of what needs
14841 // to be sorting and how to sort it. 14842 // to be sorting and how to sort it.
14842 if (!(e && e.detail && e.detail.name)) { 14843 if (!(e && e.detail && e.detail.name)) {
14843 return; 14844 return;
14844 } 14845 }
14845 // should trigger the computation of _sort and __filterAndSort 14846 // should trigger the computation of _sort and __filterAndSort
14846 this.set("_sortstr", e.detail.name +":"+e.detail.direction); 14847 this.set("_sortstr", e.detail.name + ":" + e.detail.direction);
14847 }, 14848 },
14848 // _stripSpecial removes the special columns and sorts the remaining 14849 // _stripSpecial removes the special columns and sorts the remaining
14849 // columns so they always appear in the same order, regardless of 14850 // columns so they always appear in the same order, regardless of
14850 // the order they are added. 14851 // the order they are added.
14851 _stripSpecial: function(){ 14852 _stripSpecial: function(){
14852 return this._columns.filter(function(c){ 14853 return this._columns.filter(function(c) {
14853 return this._specialColumns.indexOf(c) === -1; 14854 return this._specialColumns.indexOf(c) === -1;
14854 }.bind(this)).sort(); 14855 }.bind(this)).sort();
14855 }, 14856 },
14856 14857
14857 }; 14858 };
14858 })(); 14859 })();
14859 </script> 14860 </script>
14860 14861
14861 <script> 14862 <script>
14862 14863
(...skipping 8781 matching lines...) Expand 10 before | Expand all | Expand 10 after
23644 }, 23645 },
23645 23646
23646 _bots: function(){ 23647 _bots: function(){
23647 if (!this._list || !this._list.items) { 23648 if (!this._list || !this._list.items) {
23648 return []; 23649 return [];
23649 } 23650 }
23650 // Do any preprocessing here 23651 // Do any preprocessing here
23651 this._list.items.forEach(function(bot){ 23652 this._list.items.forEach(function(bot){
23652 // Parse the state, which is a JSON string. This contains a lot of 23653 // Parse the state, which is a JSON string. This contains a lot of
23653 // interesting information like details about the devices attached. 23654 // interesting information like details about the devices attached.
23655 bot.state = bot.state || "{}";
23654 bot.state = JSON.parse(bot.state); 23656 bot.state = JSON.parse(bot.state);
23655 // get the disks in an easier to deal with format, sorted by size. 23657 // get the disks in an easier to deal with format, sorted by size.
23656 var disks = bot.state["disks"]; 23658 var disks = bot.state.disks || {};
23657 var keys = Object.keys(disks); 23659 var keys = Object.keys(disks);
23658 if (!keys || !keys.length) { 23660 if (!keys.length) {
23659 bot.disks = [{"id": "unknown", "mb": 0}]; 23661 bot.disks = [{"id": "unknown", "mb": 0}];
23660 } else { 23662 } else {
23661 bot.disks = []; 23663 bot.disks = [];
23662 for (var i = 0; i < keys.length; i++) { 23664 for (var i = 0; i < keys.length; i++) {
23663 bot.disks.push({"id":keys[i], "mb":disks[keys[i]].free_mb}); 23665 bot.disks.push({"id":keys[i], "mb":disks[keys[i]].free_mb});
23664 } 23666 }
23665 // Sort these so the biggest disk comes first. 23667 // Sort these so the biggest disk comes first.
23666 bot.disks.sort(function(a, b) { 23668 bot.disks.sort(function(a, b) {
23667 return b.mb - a.mb; 23669 return b.mb - a.mb;
23668 }); 23670 });
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
24036 </th> 24038 </th>
24037 </template> 24039 </template>
24038 </tr> 24040 </tr>
24039 </thead> 24041 </thead>
24040 <tbody> 24042 <tbody>
24041 <template id="bot_table" is="dom-repeat" items="[[_filteredSortedIte ms]]" as="bot" initial-count="50"> 24043 <template id="bot_table" is="dom-repeat" items="[[_filteredSortedIte ms]]" as="bot" initial-count="50">
24042 24044
24043 <tr class$="[[_botClass(bot)]]"> 24045 <tr class$="[[_botClass(bot)]]">
24044 <td> 24046 <td>
24045 <a class="center" href$="[[_botLink(bot.bot_id)]]" target="_bl ank"> 24047 <a class="center" href$="[[_botLink(bot.bot_id)]]" target="_bl ank">
24046 [[bot.bot_id]] 24048 [[bot.bot_id]]
24047 </a> 24049 </a>
24048 </td> 24050 </td>
24049 <td hidden$="[[_hide('task', _columns.*)]]"> 24051 <td hidden$="[[_hide('task', _columns.*)]]">
24050 <a href$="[[_taskLink(bot)]]">[[_taskId(bot)]]</a> 24052 <a href$="[[_taskLink(bot)]]">[[_taskId(bot)]]</a>
24051 </td> 24053 </td>
24052 24054
24053 <template is="dom-repeat" items="[[_plainColumns]]" as="c"> 24055 <template is="dom-repeat" items="[[_plainColumns]]" as="c">
24054 <td hidden$="[[_hide(c)]]"> 24056 <td hidden$="[[_hide(c)]]">
24055 [[_column(c, bot, _verbose)]] 24057 [[_column(c, bot, _verbose)]]
24056 </td> 24058 </td>
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
24215 return dir * swarming.naturalCompare(botACol, botBCol); 24217 return dir * swarming.naturalCompare(botACol, botBCol);
24216 }, 24218 },
24217 }; 24219 };
24218 24220
24219 Polymer({ 24221 Polymer({
24220 is: 'bot-list', 24222 is: 'bot-list',
24221 behaviors: [SwarmingBehaviors.BotListBehavior, 24223 behaviors: [SwarmingBehaviors.BotListBehavior,
24222 SwarmingBehaviors.DynamicTableBehavior], 24224 SwarmingBehaviors.DynamicTableBehavior],
24223 24225
24224 properties: { 24226 properties: {
24225
24226 client_id: { 24227 client_id: {
24227 type: String, 24228 type: String,
24228 }, 24229 },
24229 24230
24230 // for dynamic table 24231 // For dynamic table.
24231 _columnMap: { 24232 _columnMap: {
24232 type: Object, 24233 type: Object,
24233 value: function() { 24234 value: columnMap,
24234 return columnMap;
24235 }
24236 }, 24235 },
24237 _headerMap: { 24236 _headerMap: {
24238 type: Object, 24237 type: Object,
24239 value: function() { 24238 value: headerMap,
24240 return headerMap;
24241 },
24242 }, 24239 },
24243 // special columns contain html. non-special (i.e. normal colunns) just
24244 // contain text.
24245 _specialColumns: { 24240 _specialColumns: {
24246 type: Array, 24241 type: Array,
24247 value: function() { 24242 value: specialColumns,
24248 return specialColumns;
24249 }
24250 }, 24243 },
24251 _specialSort: { 24244 _specialSort: {
24252 type: Object, 24245 type: Object,
24253 value: function() { 24246 value: specialSort,
24254 return specialSort;
24255 }
24256 }, 24247 },
24257 24248
24258 }, 24249 },
24259 24250
24260 _botClass: function(bot) { 24251 _botClass: function(bot) {
24261 if (bot.is_dead) { 24252 if (bot.is_dead) {
24262 return "dead"; 24253 return "dead";
24263 } 24254 }
24264 if (bot.quarantined) { 24255 if (bot.quarantined) {
24265 return "quarantined"; 24256 return "quarantined";
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
24298 _taskLink: function(data) { 24289 _taskLink: function(data) {
24299 if (data && data.task_id) { 24290 if (data && data.task_id) {
24300 return "/user/task/" + data.task_id; 24291 return "/user/task/" + data.task_id;
24301 } 24292 }
24302 return undefined; 24293 return undefined;
24303 } 24294 }
24304 24295
24305 }); 24296 });
24306 })(); 24297 })();
24307 </script> 24298 </script>
24299 </dom-module><dom-module id="task-filters" assetpath="/res/imp/tasklist/">
24300 <template>
24301 <style>
24302 :host {
24303 display: block;
24304 }
24305 </style>
24306
24307 </template>
24308 <script>
24309 (function(){
24310 Polymer({
24311 is: 'task-filters',
24312
24313 properties: {
24314 // output
24315 columns: {
24316 type: Array,
24317 value: function() {
24318 return ["name", "state", "user"];
24319 },
24320 notify: true,
24321 },
24322 filter: {
24323 type: Function,
24324 value: function() {
24325 return function(){
24326 return true;
24327 };
24328 },
24329 notify: true,
24330 },
24331 query_params: {
24332 type: Object,
24333 notify: true,
24334 },
24335 verbose: {
24336 type: Boolean,
24337 value: true,
24338 notify: true,
24339 },
24340 }
24341 });
24342 })();
24343 </script>
24344 </dom-module><dom-module id="task-list-data" assetpath="/res/imp/tasklist/">
24345 <template>
24346 <iron-ajax id="tasklist" url="/_ah/api/swarming/v1/tasks/list" headers="[[au th_headers]]" params="[[query_params]]" handle-as="json" last-response="{{_list} }" loading="{{_busy1}}">
24347 </iron-ajax>
24348
24349
24350 </template>
24351 <script>
24352 (function(){
24353 Polymer({
24354 is: 'task-list-data',
24355
24356 behaviors: [SwarmingBehaviors.SwarmingBehavior],
24357
24358 properties: {
24359 // inputs
24360 auth_headers: {
24361 type: Object,
24362 observer: "signIn",
24363 },
24364 query_params: {
24365 type: Object,
24366 },
24367
24368 //outputs
24369 busy: {
24370 type: Boolean,
24371 computed: "_or(_busy1)",
24372 notify: true,
24373 },
24374 tasks: {
24375 type: Array,
24376 computed: "_tasks(_list)",
24377 notify: true,
24378 }
24379 },
24380 signIn: function(){
24381 // Auto on iron-ajax means to automatically re-make the request if
24382 // the url or the query params change. Auto does not trigger if the
24383 // [auth] headers change, so we wait until the user is signed in
24384 // before making any requests.
24385 this.$.tasklist.auto = true;
24386 },
24387
24388 _tasks: function() {
24389 if (!this._list || !this._list.items) {
24390 return [];
24391 }
24392 // Do any preprocessing here
24393 return this._list.items;
24394 }
24395 });
24396 })();
24397 </script>
24398 </dom-module>
24399 <dom-module id="task-list" assetpath="/res/imp/tasklist/">
24400 <template>
24401 <style include="iron-flex iron-flex-alignment iron-positioning swarming-app- style dynamic-table-style">
24402
24403 .task-list th > span {
24404 /* Leave space for sort-toggle*/
24405 padding-right: 30px;
24406 }
24407 </style>
24408
24409 <url-param name="sort" value="{{_sortstr}}" default_value="id:asc">
24410 </url-param>
24411
24412 <swarming-app client_id="[[client_id]]" auth_headers="{{_auth_headers}}" sig ned_in="{{_signed_in}}" busy="[[_busy]]" name="Swarming Task List">
24413
24414 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2>
24415
24416 <div hidden$="[[_not(_signed_in)]]">
24417 <task-list-data auth_headers="[[_auth_headers]]" query_params="[[_query_ params]]" tasks="{{_items}}" busy="{{_busy}}">
24418 </task-list-data>
24419
24420 <div class="horizontal layout">
24421
24422 <task-filters columns="{{_columns}}" query_params="{{_query_params}}" filter="{{_filter}}" verbose="{{_verbose}}">
24423 </task-filters>
24424
24425 </div>
24426
24427 <table class="task-list">
24428 <thead on-sort_change="_sortChange">
24429
24430 <tr>
24431 <th>
24432 <span>Task Name</span>
24433 <sort-toggle name="name" current="[[_sort]]">
24434 </sort-toggle>
24435 </th>
24436
24437 <th hidden$="[[_hide('state', _columns.*)]]">
24438 <span>Status</span>
24439 <sort-toggle name="state" current="[[_sort]]">
24440 </sort-toggle>
24441 </th>
24442
24443 <template is="dom-repeat" items="[[_plainColumns]]" as="c">
24444 <th hidden$="[[_hide(c)]]">
24445 <span>[[_header(c)]]</span>
24446 <sort-toggle name="[[c]]" current="[[_sort]]">
24447 </sort-toggle>
24448 </th>
24449 </template>
24450 </tr>
24451 </thead>
24452 <tbody>
24453 <template id="tasks_table" is="dom-repeat" items="[[_filteredSortedI tems]]" as="task" initial-count="50">
24454
24455 <tr class$="[[_taskClass(task)]]">
24456 <td>
24457 <a class="center" href$="[[_taskLink(task)]]" target="_blank">
24458 [[task.name]]
24459 </a>
24460 </td>
24461 <td hidden$="[[_hide('state', _columns.*)]]">
24462 [[_column('state', task, _verbose)]]
24463
24464 </td>
24465
24466 <template is="dom-repeat" items="[[_plainColumns]]" as="c">
24467 <td hidden$="[[_hide(c)]]">
24468 [[_column(c, task, _verbose)]]
24469 </td>
24470 </template>
24471
24472 </tr>
24473 </template>
24474 </tbody>
24475 </table>
24476 </div>
24477
24478 </swarming-app>
24479
24480 </template>
24481 <script>
24482 (function(){
24483 var specialColumns = ["name", "state"];
24484 var columnMap = {};
24485 var headerMap = {
24486 "user": "Requesting User",
24487 };
24488 var specialSort = {};
24489
24490 Polymer({
24491 is: 'task-list',
24492 behaviors: [
24493 SwarmingBehaviors.SwarmingBehavior,
24494 SwarmingBehaviors.DynamicTableBehavior,
24495 ],
24496
24497 properties: {
24498 client_id: {
24499 type: String,
24500 },
24501
24502 // For dynamic table.
24503 _columnMap: {
24504 type: Object,
24505 value: columnMap,
24506 },
24507 _headerMap: {
24508 type: Object,
24509 value: headerMap,
24510 },
24511 _specialColumns: {
24512 type: Array,
24513 value: specialColumns,
24514 },
24515 _specialSort: {
24516 type: Object,
24517 value: specialSort,
24518 },
24519 },
24520
24521 _attribute: function(task, col, def) {
24522 var retVal = task[col] || [def];
24523 if (!Array.isArray(retVal)) {
24524 return [retVal];
24525 }
24526 return retVal;
24527 },
24528
24529 _taskLink: function(task) {
24530 // TODO(kjlubick) Make this point to /newui/ when appropriate.
24531 return "/restricted/task/"+task.task_id;
24532 },
24533
24534 _taskClass: function(task) {
24535 // TODO(kjlubick): Color tasks?
24536 return "";
24537 }
24538
24539 });
24540 })();
24541 </script>
24308 </dom-module></div></body></html> 24542 </dom-module></div></body></html>
OLDNEW
« no previous file with comments | « appengine/swarming/elements/Makefile ('k') | appengine/swarming/elements/elements.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698