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

Unified Diff: appengine/swarming/elements/build/elements.html

Issue 2258853002: Midway through extracting filters (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@tasklist
Patch Set: Revert gpu stuff and tidy up 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « appengine/swarming/elements/Makefile ('k') | appengine/swarming/elements/res/imp/botlist/bot-filters.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/swarming/elements/build/elements.html
diff --git a/appengine/swarming/elements/build/elements.html b/appengine/swarming/elements/build/elements.html
index 6e78d4ab734422b01902a968d9d8214283d5e8fd..54dcf0ef3fabedb130f98832e9e96ccb78e7b01d 100644
--- a/appengine/swarming/elements/build/elements.html
+++ b/appengine/swarming/elements/build/elements.html
@@ -23611,7 +23611,7 @@ the fleet.">
notify: true,
},
primary_map: {
- type:Object,
+ type: Object,
computed: "_primaryMap(_dimensions)",
notify: true,
},
@@ -24296,21 +24296,182 @@ the fleet.">
});
})();
</script>
-</dom-module><dom-module id="task-filters" assetpath="/res/imp/tasklist/">
+</dom-module><dom-module id="query-column-filter-style" assetpath="/res/imp/common/">
<template>
<style>
:host {
display: block;
+ font-family: sans-serif;
}
+ #filter {
+ margin:0 5px;
+ }
+
+ .container {
+ min-height: 120px;
+ width: 100%;
+ }
+
+ .item {
+ border-bottom: 1px solid #EEE;
+ max-width: 250px;
+ min-height: 1.0em;
+ min-width: 100px;
+ padding: 0.1em 0.2em;
+ line-height: 1.5em;
+ }
+
+ .header {
+ height: 2em;
+ padding: .25em;
+ line-height: 2em;
+ }
+
+ .selector {
+ border: 1px solid black;
+ margin: 0 5px;
+ max-height: 200px;
+ min-height: 130px;
+ min-width: 200px;
+ overflow-y: auto;
+ overflow-x: hidden;
+ }
+
+ .selectable {
+ cursor: pointer;
+ }
+
+ .selectable:hover {
+ /* See https://sites.google.com/a/google.com/skia-infrastructure/design-docs/general-design-guidance */
+ background-color: #A6CEE3;
+ }
+
+ .iron-selected {
+ /* See https://sites.google.com/a/google.com/skia-infrastructure/design-docs/general-design-guidance */
+ background-color: #1F78B4;
+ color: white;
+ }
+
+ .icons {
+ cursor:pointer;
+ height:20px;
+ margin:2px;
+ width:20px;
+ flex-shrink: 0;
+ }
+
+ .side-by-side {
+ display: inline-block;
+ vertical-align: top;
+ }
+
+ .bold {
+ font-weight: bold;
+ }
+
+ paper-checkbox {
+ max-height: 2em;
+ margin: 2px;
+ /* See https://sites.google.com/a/google.com/skia-infrastructure/design-docs/general-design-guidance */
+ --paper-checkbox-checked-color: black;
+ --paper-checkbox-checked-ink-color: black;
+ --paper-checkbox-unchecked-color: black;
+ --paper-checkbox-unchecked-ink-color: black;
+ --paper-checkbox-label-color: black;
+ }
+ </style>
+
+ </template>
+</dom-module>
+
+<script>
+ window.SwarmingBehaviors = window.SwarmingBehaviors || {};
+ (function(){
+ // This behavior wraps up all the shared swarming functionality.
+ SwarmingBehaviors.QueryColumnFilter = {
+
+ };
+ })();
+</script>
+<dom-module id="task-filters" assetpath="/res/imp/tasklist/">
+ <template>
+ <style is="custom-style" include="iron-flex iron-flex-alignment iron-positioning query-column-filter-style">
+
</style>
+ <div class="container horizontal layout">
+
+
+ <div class="narrow-down-selector">
+ <div>
+ <paper-input id="filter" label="Search columns and filters" placeholder="gpu nvidia" value="{{_query}}">
+ </paper-input>
+ </div>
+
+ <div class="selector side-by-side" title="This shows all bot dimension names and other interesting bot properties. Mark the check box to add as a column. Select the row to see filter options.">
+ <iron-selector attr-for-selected="label" selected="{{_primarySelected}}">
+ <template is="dom-repeat" items="[[_primaryItems]]" as="item">
+ <div class="selectable item horizontal layout" label="[[item]]">
+
+ <span>[[_beforeBold(item,_query)]]<span class="bold">[[_bold(item,_query)]]</span>[[_afterBold(item,_query)]]</span>
+ <span class="flex"></span>
+ <paper-checkbox noink="" disabled$="[[_cantToggleColumn(item)]]" checked="[[_columnState(item,columns.*)]]" on-change="_toggleColumn">
+ </paper-checkbox>
+ </div>
+ </template>
+ </iron-selector>
+ </div>
+
+ <div class="selector side-by-side" title="These are all options (if any) that the bot list can be filtered on.">
+ <template is="dom-repeat" id="secondaryList" items="[[_secondaryItems]]" as="item">
+ <div class="item horizontal layout" label="[[item]]">
+
+ <span>[[_beforeBold(item,_query)]]<span class="bold">[[_bold(item,_query)]]</span>[[_afterBold(item,_query)]]</span>
+ <span class="flex"></span>
+ <iron-icon class="icons" icon="icons:arrow-forward" hidden="[[_cantAddFilter(_primarySelected,item,_filters.*)]]" on-tap="_addFilter">
+ </iron-icon>
+ </div>
+ </template>
+ </div>
+
+ <div class="selector side-by-side" title="These filters are AND'd together and applied to all bots in
+the fleet.">
+ <template is="dom-repeat" items="[[_filters]]" as="fil">
+ <div class="item horizontal layout" label="[[fil]]">
+ <span>[[fil]]</span>
+ <span class="flex"></span>
+ <iron-icon class="icons" icon="icons:remove-circle-outline" hidden="[[_cantRemoveFilter(fil,_filters.*)]]" on-tap="_removeFilter">
+ </iron-icon>
+ </div>
+ </template>
+ </div>
+
+ <div class="side-by-side">
+ <paper-checkbox checked="{{verbose}}">Verbose Entries</paper-checkbox>
+ <paper-input id="limit" label="Limit Results" auto-validate="" min="0" max="1000" pattern="[0-9]+" value="{{limit}}">
+ </paper-input>
+ </div>
+ </div>
+
+ </div>
+
</template>
<script>
(function(){
Polymer({
is: 'task-filters',
+ behaviors: [SwarmingBehaviors.QueryColumnFilter],
+
properties: {
+ // input
+ primary_map: {
+ type: Object,
+ },
+ primary_arr: {
+ type: Array,
+ },
+
// output
columns: {
type: Array,
@@ -24337,7 +24498,91 @@ the fleet.">
value: true,
notify: true,
},
- }
+
+ // private
+ _filters: {
+ type:Array,
+ },
+ _limit: {
+ type: Number,
+ },
+ _primaryItems: {
+ type: Array,
+ computed: "_primary(_query, primary_map, primary_arr, columns.*)",
+ },
+ _primarySelected: {
+ type: String,
+ value: "",
+ },
+ // query is treated as a space separated list.
+ _query: {
+ type:String,
+ },
+ _secondaryItems: {
+ type: Array,
+ computed: "_secondary(_primarySelected, _query, primary_map)",
+ },
+ },
+
+
+ _primary: function(query, primary_map, primary_arr) {
+ // If the user has typed in a query, only show those primary keys that
+ // partially match the query or that have secondary values which
+ // partially match.
+ var arr = this.primary_arr.filter(function(s){
+ if (matchPartCaseInsensitive(s, query).idx !== -1) {
+ return true;
+ }
+ var opts = primary_map[s];
+ for (var i = 0; i < opts.length; i++) {
+ if (matchPartCaseInsensitive(opts[i], query).idx !== -1) {
+ return true;
+ }
+ }
+ return false;
+ });
+ // Update the selected to be the current one (if it is still with being
+ // shown) or the first match. This saves the user from having to click
+ // the first result before seeing results.
+ if (query && arr.length > 0 &&
+ arr.indexOf(this._primarySelected) === -1) {
+ this.set("_primarySelected", arr[0]);
+ }
+ return arr;
+ },
+
+ _secondary: function(primarySelected, query, primary_map) {
+ // Changing the secondary list doesn't always trigger a reorder of the
+ // secondary elements. So, we request it be done asynchronously.
+ requestAnimationFrame(function(){
+ this.$.secondaryList.render();
+ }.bind(this));
+
+ // Only show secondary options when a primary option has been selected.
+ // If the user has typed in a query, show all secondary elements if
+ // their primary element matches. If it doesn't match the primary
+ // element, only show those secondary elements that do.
+ if (!primarySelected) {
+ return [];
+ }
+ if (matchPartCaseInsensitive(primarySelected, query).idx !== -1) {
+ // Sort the secondaries alphabetically, but prioritize query matches.
+ return primary_map[primarySelected].sort(function(a, b){
+ var aMatch = matchPartCaseInsensitive(a, query).idx !== -1;
+ var bMatch = matchPartCaseInsensitive(b, query).idx !== -1;
+ if (aMatch === bMatch) {
+ return swarming.naturalCompare(a,b);
+ }
+ // true == 1 and false == 0. So, put the one that matches first.
+ return bMatch - aMatch;
+ });
+ }
+ // Otherwise, filter out those that do not match.
+ return primary_map[primarySelected].filter(function(s) {
+ return matchPartCaseInsensitive(s, query).idx !== -1;
+ });
+ },
+
});
})();
</script>
@@ -24345,7 +24590,9 @@ the fleet.">
<template>
<iron-ajax id="tasklist" url="/_ah/api/swarming/v1/tasks/list" headers="[[auth_headers]]" params="[[query_params]]" handle-as="json" last-response="{{_list}}" loading="{{_busy1}}">
</iron-ajax>
-
+
+ <iron-ajax id="tags" url="/_ah/api/swarming/v1/tasks/tags" headers="[[auth_headers]]" handle-as="json" last-response="{{_tags}}" loading="{{_busy2}}">
+ </iron-ajax>
</template>
<script>
@@ -24365,10 +24612,20 @@ the fleet.">
type: Object,
},
- //outputs
+ // outputs
busy: {
type: Boolean,
- computed: "_or(_busy1)",
+ computed: "_or(_busy1,_busy2)",
+ notify: true,
+ },
+ primary_map: {
+ type: Object,
+ computed: "_primaryMap(_tags)",
+ notify: true,
+ },
+ primary_arr: {
+ type: Array,
+ computed: "_primaryArr(_tags)",
notify: true,
},
tasks: {
@@ -24377,12 +24634,38 @@ the fleet.">
notify: true,
}
},
+
signIn: function(){
// Auto on iron-ajax means to automatically re-make the request if
// the url or the query params change. Auto does not trigger if the
// [auth] headers change, so we wait until the user is signed in
// before making any requests.
this.$.tasklist.auto = true;
+ this.$.tags.auto = true;
+ },
+
+ _primaryArr: function(tags) {
+ tags = tags.tasks_tags;
+
+ var arr = [];
+ tags.forEach(function(t) {
+ arr.push(t.key)
+ });
+
+ arr.sort();
+
+ return arr;
+ },
+
+ _primaryMap: function(tags) {
+ tags = tags.tasks_tags;
+
+ var pMap = {};
+ tags.forEach(function(t) {
+ pMap[t.key] = t.value;
+ });
+
+ return pMap;
},
_tasks: function() {
@@ -24414,12 +24697,12 @@ the fleet.">
<h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2>
<div hidden$="[[_not(_signed_in)]]">
- <task-list-data auth_headers="[[_auth_headers]]" query_params="[[_query_params]]" tasks="{{_items}}" busy="{{_busy}}">
+ <task-list-data auth_headers="[[_auth_headers]]" query_params="[[_query_params]]" tasks="{{_items}}" busy="{{_busy}}" primary_map="{{_primary_map}}" primary_arr="{{_primary_arr}}">
</task-list-data>
<div class="horizontal layout">
- <task-filters columns="{{_columns}}" query_params="{{_query_params}}" filter="{{_filter}}" verbose="{{_verbose}}">
+ <task-filters primary_map="[[_primary_map]]" primary_arr="[[_primary_arr]]" columns="{{_columns}}" query_params="{{_query_params}}" filter="{{_filter}}" verbose="{{_verbose}}">
</task-filters>
</div>
« no previous file with comments | « appengine/swarming/elements/Makefile ('k') | appengine/swarming/elements/res/imp/botlist/bot-filters.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698