| Index: appengine/swarming/elements/polymer05/stats-dimension-filter.html
|
| diff --git a/appengine/swarming/elements/polymer05/stats-dimension-filter.html b/appengine/swarming/elements/polymer05/stats-dimension-filter.html
|
| deleted file mode 100644
|
| index 62163cf64bc07c94760ebd79c8762f9144b7b2eb..0000000000000000000000000000000000000000
|
| --- a/appengine/swarming/elements/polymer05/stats-dimension-filter.html
|
| +++ /dev/null
|
| @@ -1,268 +0,0 @@
|
| -<!--
|
| -# Copyright 2015 The LUCI Authors. All rights reserved.
|
| -# Use of this source code is governed under the Apache License, Version 2.0
|
| -# that can be found in the LICENSE file.
|
| -
|
| --->
|
| -
|
| -<!--
|
| -@group Swarming Elements
|
| -
|
| -`stats-dimension-filter' is a control that filters dimension list. It takes a
|
| -list of available dimension objects as its `dimensions` attribute.
|
| -dimensions = [
|
| - {"cpu":"x86-64","gpu":"none","os":"Mac","pool":"Chrome"},
|
| - {"cpu":"x86-64","gpu":"none","os":"Windows","pool":"Chrome"},
|
| - {"os":"Linux"},
|
| - {"os":"Mac"},
|
| - {"os":"Windows"}
|
| -]
|
| -A dimension object may have a number of properties such as `cpu` and `gpu`. For
|
| -each unique property this control will create a dropdown menu for user to filter
|
| -by that property.
|
| -
|
| -When more than one dimensions are available after applying a filter, one is
|
| -picked to shown while other field menus are shrinked.
|
| -
|
| -This control exposes a `value` attribute denotes the current dimension selected.
|
| -A null `value` indicates no dimension is selected.
|
| -
|
| -Example:
|
| - <stats-dimension-filter
|
| - dimensions='[{"cpu":"x86-64", "os":"Mac"}, {"os":"Linux"}]'>
|
| - </stats-dimension-filter>
|
| -
|
| -@element stats-dimension-filter
|
| --->
|
| -
|
| -<link rel="import" href="bower_components/polymer/polymer.html">
|
| -<link rel="import" href="bower_components/core-label/core-label.html">
|
| -<link rel="import" href="bower_components/core-menu/core-menu.html">
|
| -<link rel="import" href="bower_components/paper-button/paper-button.html">
|
| -<link rel="import" href="bower_components/core-dropdown/core-dropdown.html">
|
| -<link rel="import" href="bower_components/core-dropdown-menu/core-dropdown-menu.html">
|
| -<link rel="import" href="bower_components/core-item/core-item.html">
|
| -<link rel="import" href="bower_components/core-selector/core-selector.html">
|
| -
|
| -<polymer-element name="stats-dimension-filter" attributes="dimensions value" layout vertical>
|
| - <template>
|
| - <style>
|
| - core-dropdown {
|
| - background-color: #fff;
|
| - border: 1px solid #ccc;
|
| - border-radius: 4px;
|
| - box-shadow: 0 6px 12px rgba(0,0,0,.175);
|
| - margin: 2px 0 0;
|
| - min-width: 160px;
|
| - padding: 5px 0;
|
| - top: 100%;
|
| - }
|
| -
|
| - core-dropdown-menu {
|
| - background-color: #fff;
|
| - border: 1px solid transparent;
|
| - border-color: #ccc;
|
| - border-radius: 4px;
|
| - color: #333;
|
| - cursor: pointer;
|
| - padding: 6px 12px;
|
| - }
|
| -
|
| - core-dropdown-menu:hover {
|
| - background-color: #eee;
|
| - }
|
| -
|
| - core-item {
|
| - color: #333;
|
| - padding: 3px 20px;
|
| - white-space: nowrap;
|
| - }
|
| -
|
| - h4 {
|
| - margin: 5px 0px;
|
| - }
|
| -
|
| - paper-button {
|
| - text-transform: none;
|
| - font-size: 14px;
|
| - }
|
| -
|
| - .dimension-selector a {
|
| - color: blue;
|
| - cursor: pointer;
|
| - }
|
| -
|
| - .dimension-selector li {
|
| - list-style-type: none;
|
| - }
|
| - </style>
|
| - <div layout horizontal center>
|
| - <h4>Filters:</h4>
|
| - <template repeat="{{f in filters | filtersArray(filters, count)}}">
|
| - <paper-button class="custom" on-tap="{{onFilterUnchecked}}" prop="{{f.prop}}">
|
| - <core-icon icon="clear"></core-icon>
|
| - {{f.prop}}: {{f.value}}
|
| - </paper-button>
|
| - </template>
|
| - </div>
|
| - <div>
|
| - <template repeat="{{prop in props | propPickerFilter(filters, count)}}">
|
| - <core-dropdown-menu label="{{prop}}" on-core-select="{{propSelected}}">
|
| - <core-dropdown class="dropdown">
|
| - <core-selector class="menu">
|
| - <template repeat="{{v in values[prop] | propValueFilter(dimensions, filters, prop, count)}}">
|
| - <core-item name="{{v}}">{{v}}</core-item>
|
| - </template>
|
| - </core-selector>
|
| - </core-dropdown>
|
| - </core-dropdown-menu>
|
| - </template>
|
| - </div>
|
| - <h4>Resolved Dimension:</h4>
|
| - <div>
|
| - <template if="{{value}}">
|
| - <paper-button class="custom" on-tap="{{onClearDimension}}">
|
| - <core-icon icon="clear"></core-icon>
|
| - {{stringify(value)}}
|
| - </paper-button>
|
| - </template>
|
| - <template if="{{!value}}">
|
| - No dimension selected
|
| - </template>
|
| - <h4>Dimensions:</h4>
|
| - <ul class="dimension-selector">
|
| - <template repeat="{{d in dimensions | dimensionFilter(filters, count)}}">
|
| - <li><a on-tap="{{selectDimension}}">{{stringify(d)}}</a></li>
|
| - </template>
|
| - </ul>
|
| - </template>
|
| - <script>
|
| - Polymer('stats-dimension-filter', {
|
| - count: 0,
|
| - dimensions: [],
|
| - filters: {},
|
| - props: [],
|
| - value: null,
|
| - values: {},
|
| -
|
| - stringify: function(d) {
|
| - return JSON.stringify(d);
|
| - },
|
| -
|
| - // Update this.props and this.values
|
| - dimensionsChanged: function() {
|
| - var ds = this.dimensions;
|
| - var attrs = {}, values = {};
|
| - var props = [];
|
| - for (var i = 0; i < ds.length; ++i) {
|
| - var d = ds[i];
|
| - if (typeof d === "object") {
|
| - for (var attr in d) {
|
| - if (!attrs[attr]) {
|
| - attrs[attr] = {};
|
| - }
|
| - attrs[attr][d[attr]] = true;
|
| - }
|
| - } else {
|
| - console.error('dimension should be an object');
|
| - }
|
| - }
|
| - for (var attr in attrs) {
|
| - props.push(attr);
|
| - if (!values[attr]) {
|
| - values[attr] = [];
|
| - }
|
| - for (var i in attrs[attr]) {
|
| - values[attr].push(i);
|
| - }
|
| - }
|
| - this.props = props;
|
| - this.values = values;
|
| - },
|
| -
|
| - dimensionFilter: function(dimensions, filters, count) {
|
| - var hasFilter = false;
|
| - var arr = dimensions.filter(function(d) {
|
| - for (var prop in filters) {
|
| - hasFilter = true;
|
| - if (d[prop] !== filters[prop]) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - });
|
| - if (hasFilter) {
|
| - this.value = JSON.stringify(arr[0]);
|
| - }
|
| - return arr;
|
| - },
|
| -
|
| - propPickerFilter: function(props, filters, count) {
|
| - return props.filter(function(prop) {
|
| - for (var p in filters) {
|
| - if (prop === p) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - });
|
| - },
|
| -
|
| - filtersArray: function(filters, count) {
|
| - var arr = [];
|
| - for (var prop in filters) {
|
| - arr.push({
|
| - prop: prop,
|
| - value: filters[prop]
|
| - });
|
| - }
|
| - return arr;
|
| - },
|
| -
|
| - // HACK: this is to trigger the dimensionFilter due to a bug in Polymer
|
| - // https://github.com/Polymer/polymer/issues/1082
|
| - filtersChanged: function() {
|
| - this.count++;
|
| - },
|
| -
|
| - propSelected: function(event, detail, sender) {
|
| - var prop = sender.label;
|
| - var v = sender.selectedItemLabel;
|
| - if (v) {
|
| - this.filters[prop] = v;
|
| - }
|
| - // TODO: use observer pattern
|
| - this.filtersChanged();
|
| - },
|
| -
|
| - propValueFilter: function(values, dimensions, filters, prop) {
|
| - var ds = this.dimensionFilter(dimensions, filters);
|
| - var selection = {};
|
| - for (var i = 0; i < ds.length; ++i) {
|
| - if (ds[i].hasOwnProperty(prop)) {
|
| - selection[ds[i][prop]] = true;
|
| - }
|
| - }
|
| - var ret = [];
|
| - for (var i in selection) {
|
| - ret.push(i);
|
| - }
|
| - return ret;
|
| - },
|
| -
|
| - onFilterUnchecked: function(event, detail, sender) {
|
| - delete this.filters[sender.getAttribute('prop')];
|
| - // TODO: use observer pattern
|
| - this.filtersChanged();
|
| - },
|
| -
|
| - selectDimension: function(event, detail, sender) {
|
| - this.value = sender.innerHTML;
|
| - },
|
| -
|
| - onClearDimension: function(event, detail, sender) {
|
| - this.value = null;
|
| - }
|
| - });
|
| - </script>
|
| -</polymer-element>
|
|
|