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

Side by Side Diff: appengine/swarming/elements/res/imp/botlist/bot-list.html

Issue 2269643002: Extract shared filters and aliasing code (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@master
Patch Set: Address nit 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-list> 9 <bot-list>
10 10
11 bot-list creats a dynamic table for viewing swarming bots. Columns can be 11 bot-list creats a dynamic table for viewing swarming bots. Columns can be
12 dynamically filtered and it supports client-side filtering. 12 dynamically filtered and it supports client-side filtering.
13 13
14 This is a top-level element. 14 This is a top-level element.
15 15
16 Properties: 16 Properties:
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-flex-layout/iron-flex-la yout-classes.html"> 27 <link rel="import" href="/res/imp/bower_components/iron-flex-layout/iron-flex-la yout-classes.html">
28 <link rel="import" href="/res/imp/bower_components/polymer/polymer.html"> 28 <link rel="import" href="/res/imp/bower_components/polymer/polymer.html">
29 29
30 <link rel="import" href="/res/imp/common/dynamic-table.html"> 30 <link rel="import" href="/res/imp/common/dynamic-table-behavior.html">
31 <link rel="import" href="/res/imp/common/sort-toggle.html"> 31 <link rel="import" href="/res/imp/common/sort-toggle.html">
32 <link rel="import" href="/res/imp/common/swarming-app.html"> 32 <link rel="import" href="/res/imp/common/swarming-app.html">
33 <link rel="import" href="/res/imp/common/url-param.html"> 33 <link rel="import" href="/res/imp/common/url-param.html">
34 34
35 <link rel="import" href="bot-filters.html"> 35 <link rel="import" href="bot-filters.html">
36 <link rel="import" href="bot-list-data.html"> 36 <link rel="import" href="bot-list-data.html">
37 <link rel="import" href="bot-list-shared.html"> 37 <link rel="import" href="bot-list-shared-behavior.html">
38 <link rel="import" href="bot-list-summary.html"> 38 <link rel="import" href="bot-list-summary.html">
39 39
40 <dom-module id="bot-list"> 40 <dom-module id="bot-list">
41 <template> 41 <template>
42 <style include="iron-flex iron-flex-alignment iron-positioning swarming-app- style dynamic-table-style"> 42 <style include="iron-flex iron-flex-alignment iron-positioning swarming-app- style dynamic-table-style">
43 bot-filters, bot-list-summary { 43 bot-filters, bot-list-summary {
44 margin-bottom: 8px; 44 margin-bottom: 8px;
45 margin-right: 10px; 45 margin-right: 10px;
46 } 46 }
47 .quarantined, .bad-device { 47 .quarantined, .bad-device {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 "device_type": "Device Type", 227 "device_type": "Device Type",
228 "disk_space": "Free Space (MB)", 228 "disk_space": "Free Space (MB)",
229 "gpu": "GPU", 229 "gpu": "GPU",
230 "os": "OS", 230 "os": "OS",
231 "pool": "Pool", 231 "pool": "Pool",
232 "status": "Status", 232 "status": "Status",
233 "xcode_version": "XCode Version", 233 "xcode_version": "XCode Version",
234 }; 234 };
235 235
236 var columnMap = { 236 var columnMap = {
237 android_devices: function(bot) {
238 var devs = this._attribute(bot, "android_devices", "0");
239 if (this._verbose) {
240 return devs.join(" | ") + " devices available";
241 }
242 // max() works on strings as long as they can be coerced to Number.
243 return Math.max(...devs) + " devices available";
244 },
245 device_type: function(bot) {
246 var dt = this._attribute(bot, "device_type", "none");
247 dt = dt[0];
248 var alias = this._androidAlias(dt);
249 if (alias === "unknown") {
250 return dt;
251 }
252 return this._applyAlias(dt, alias);
253 },
254 disk_space: function(bot) { 237 disk_space: function(bot) {
255 var aliased = []; 238 var aliased = [];
256 bot.disks.forEach(function(disk){ 239 bot.disks.forEach(function(disk){
257 var alias = sk.human.bytes(disk.mb, swarming.MB); 240 var alias = sk.human.bytes(disk.mb, swarming.MB);
258 aliased.push(this._applyAlias(disk.mb, disk.id + " "+ alias)); 241 aliased.push(swarming.alias.apply(disk.mb, disk.id + " "+ alias));
259 }.bind(this)); 242 }.bind(this));
260 if (this._verbose) { 243 if (this._verbose) {
261 return aliased.join(" | "); 244 return aliased.join(" | ");
262 } 245 }
263 return aliased[0]; 246 return aliased[0];
264 }, 247 },
265 gpu: function(bot){
266 var gpus = this._attribute(bot, "gpu", "none")
267 var verbose = []
268 var named = [];
269 // non-verbose mode has only the top level GPU info "e.g. NVidia"
270 // which is found by looking for gpu ids w/o a colon.
271 gpus.forEach(function(g){
272 var alias = this._gpuAlias(g);
273 if (alias === "unknown") {
274 verbose.push(g);
275 if (g.indexOf(":") === -1) {
276 named.push(g);
277 }
278 return;
279 }
280 verbose.push(this._applyAlias(g, alias));
281 if (g.indexOf(":") === -1) {
282 named.push(this._applyAlias(g, alias));
283 }
284 }.bind(this))
285 if (this._verbose) {
286 return verbose.join(" | ");
287 }
288 return named.join(" | ");
289 },
290 id: function(bot) { 248 id: function(bot) {
291 return bot.bot_id; 249 return bot.bot_id;
292 }, 250 },
293 pool: function(bot) {
294 var pool = this._attribute(bot, "pool");
295 return pool.join(" | ");
296 },
297 status: function(bot) { 251 status: function(bot) {
298 // If a bot is both dead and quarantined, show the deadness over the 252 // If a bot is both dead and quarantined, show the deadness over the
299 // quarentinedness. 253 // quarentinedness.
300 if (bot.is_dead) { 254 if (bot.is_dead) {
301 return "Dead. Last seen " + sk.human.diffDate(bot.last_seen_ts) + 255 return "Dead. Last seen " + sk.human.diffDate(bot.last_seen_ts) +
302 " ago"; 256 " ago";
303 } 257 }
304 if (bot.quarantined) { 258 if (bot.quarantined) {
305 return "Quarantined: " + this._attribute(bot, "quarantined"); 259 var msg = this._state(bot, "quarantined")[0];
260 // Sometimes, the quarantined message is actually in "error". This
261 // happens when the bot code has thrown an exception.
262 if (msg === "unknown" || msg === "true" || msg === true) {
263 msg = this._attribute(bot, "error");
264 }
265 return "Quarantined: " + msg;
306 } 266 }
307 return "Alive"; 267 return "Alive";
308 }, 268 },
309 task: function(bot){ 269 task: function(bot){
310 return this._taskId(bot); 270 return this._taskId(bot);
311 }, 271 },
312 }; 272 };
313 273
314 var deviceColumnMap = { 274 var deviceColumnMap = {
315 android_devices: function(device) { 275 android_devices: function(device) {
316 var str = this._androidAliasDevice(device); 276 var str = this._androidAliasDevice(device);
317 if (device.okay) { 277 if (device.okay) {
318 str = this._applyAlias(this._deviceType(device), str); 278 str = swarming.alias.apply(this._deviceType(device), str);
319 } 279 }
320 str += " S/N:"; 280 str += " S/N:";
321 str += device.serial; 281 str += device.serial;
322 return str; 282 return str;
323 }, 283 },
324 device_os: function(device) { 284 device_os: function(device) {
325 if (device.build) { 285 if (device.build) {
326 return device.build["build.id"]; 286 return device.build["build.id"];
327 } 287 }
328 return "unknown"; 288 return "unknown";
(...skipping 16 matching lines...) Expand all
345 disk_space: function(dir, botA, botB) { 305 disk_space: function(dir, botA, botB) {
346 // We sort based on the raw number of MB of the first disk. 306 // We sort based on the raw number of MB of the first disk.
347 var botACol = botA.disks[0].mb; 307 var botACol = botA.disks[0].mb;
348 var botBCol = botB.disks[0].mb;; 308 var botBCol = botB.disks[0].mb;;
349 return dir * swarming.naturalCompare(botACol, botBCol); 309 return dir * swarming.naturalCompare(botACol, botBCol);
350 }, 310 },
351 }; 311 };
352 312
353 Polymer({ 313 Polymer({
354 is: 'bot-list', 314 is: 'bot-list',
355 behaviors: [SwarmingBehaviors.BotListBehavior, 315
356 SwarmingBehaviors.DynamicTableBehavior], 316 // The order behaviors are applied in matters - later ones overwrite
317 // attributes of earlier ones
318 behaviors: [
319 SwarmingBehaviors.BotListBehavior,
320 SwarmingBehaviors.DynamicTableBehavior,
321 ],
357 322
358 properties: { 323 properties: {
359 client_id: { 324 client_id: {
360 type: String, 325 type: String,
361 }, 326 },
362 327
363 // For dynamic table. 328 // For dynamic table.
364 _columnMap: { 329 _columnMap: {
365 type: Object, 330 type: Object,
366 value: columnMap, 331 value: function() {
332 var base = this._commonColumns();
333 for (var attr in columnMap) {
334 base[attr] = columnMap[attr];
335 }
336 return base;
337 },
367 }, 338 },
368 _headerMap: { 339 _headerMap: {
369 type: Object, 340 type: Object,
370 value: headerMap, 341 value: headerMap,
371 }, 342 },
372 _specialColumns: { 343 _specialColumns: {
373 type: Array, 344 type: Array,
374 value: specialColumns, 345 value: specialColumns,
375 }, 346 },
376 _specialSort: { 347 _specialSort: {
(...skipping 16 matching lines...) Expand all
393 _botLink: function(id) { 364 _botLink: function(id) {
394 // TODO(kjlubick) Make this point to /newui/ when appropriate. 365 // TODO(kjlubick) Make this point to /newui/ when appropriate.
395 return "/restricted/bot/"+id; 366 return "/restricted/bot/"+id;
396 }, 367 },
397 368
398 369
399 _androidAliasDevice: function(device) { 370 _androidAliasDevice: function(device) {
400 if (device.notReady) { 371 if (device.notReady) {
401 return UNAUTHENTICATED.toUpperCase(); 372 return UNAUTHENTICATED.toUpperCase();
402 } 373 }
403 return this._androidAlias(this._deviceType(device)); 374 return swarming.alias.android(this._deviceType(device));
404 }, 375 },
405 376
406 _deviceColumn: function(col, device) { 377 _deviceColumn: function(col, device) {
407 var f = deviceColumnMap[col]; 378 var f = deviceColumnMap[col];
408 if (!f || !device) { 379 if (!f || !device) {
409 return ""; 380 return "";
410 } 381 }
411 return f.bind(this)(device); 382 return f.bind(this)(device);
412 }, 383 },
413 384
414 _deviceClass: function(device) { 385 _deviceClass: function(device) {
415 if (!device.okay) { 386 if (!device.okay) {
416 return "bad-device"; 387 return "bad-device";
417 } 388 }
418 return ""; 389 return "";
419 }, 390 },
420 391
421 _taskLink: function(data) { 392 _taskLink: function(data) {
422 if (data && data.task_id) { 393 if (data && data.task_id) {
423 return "/user/task/" + data.task_id; 394 return "/user/task/" + data.task_id;
424 } 395 }
425 return undefined; 396 return undefined;
426 } 397 }
427 398
428 }); 399 });
429 })(); 400 })();
430 </script> 401 </script>
431 </dom-module> 402 </dom-module>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698