| Index: tracing/tracing/ui/base/grouping_table_groupby_picker.html
|
| diff --git a/tracing/tracing/ui/base/grouping_table_groupby_picker.html b/tracing/tracing/ui/base/grouping_table_groupby_picker.html
|
| index ad24d1b6b7e7beea6e5fbb0ea8f1b2446e6a784e..e929448df387371858b9b2b8d99f625ca003b1d7 100644
|
| --- a/tracing/tracing/ui/base/grouping_table_groupby_picker.html
|
| +++ b/tracing/tracing/ui/base/grouping_table_groupby_picker.html
|
| @@ -12,33 +12,17 @@ found in the LICENSE file.
|
| <dom-module id='tr-ui-b-grouping-table-groupby-picker'>
|
| <template>
|
| <style>
|
| - :host {
|
| + #container {
|
| display: flex;
|
| - align-items: center;
|
| - }
|
| -
|
| - :host(:not([vertical])), :host(:not([vertical])) groups {
|
| - flex-direction: row;
|
| }
|
| -
|
| - :host([vertical]), :host([vertical]) groups {
|
| - flex-direction: column;
|
| - }
|
| -
|
| - groups {
|
| - -webkit-user-select: none;
|
| - display: flex;
|
| - }
|
| -
|
| - possible-group {
|
| - display: span;
|
| - padding-right: 10px;
|
| - padding-left: 10px;
|
| + #container *:not(:first-child) {
|
| + padding-left: 3px;
|
| + border-left: 1px solid black;
|
| + margin-left: 3px;
|
| }
|
| </style>
|
|
|
| - <groups id="groups"></groups>
|
| - <tr-ui-b-dropdown id="add_group"></tr-ui-b-dropdown>
|
| + <div id="container"></div>
|
| </template>
|
| </dom-module>
|
|
|
| @@ -47,56 +31,13 @@ found in the LICENSE file.
|
| <style>
|
| :host {
|
| white-space: nowrap;
|
| - border: 3px solid white;
|
| - background-color: #dddddd;
|
| - cursor: move;
|
| - }
|
| -
|
| - :host(:not([vertical])) {
|
| - display: inline;
|
| - }
|
| -
|
| - :host([vertical]) {
|
| - display: block;
|
| - }
|
| -
|
| - :host(:not([vertical]).drop-before) {
|
| - border-left: 3px solid black;
|
| - }
|
| -
|
| - :host([vertical].drop-before) {
|
| - border-top: 3px solid black;
|
| - }
|
| -
|
| - :host(:not([vertical]).drop-after) {
|
| - border-right: 3px solid black;
|
| - }
|
| -
|
| - :host([vertical].drop-after) {
|
| - border-bottom: 3px solid black;
|
| - }
|
| -
|
| - :host([dragging]) {
|
| - opacity: 0.5;
|
| - }
|
| -
|
| - #remove {
|
| - visibility: hidden;
|
| - padding-left: 3px;
|
| - width: 20px;
|
| - height: 20px;
|
| - cursor: auto;
|
| - }
|
| -
|
| - #key {
|
| - padding-right: 3px;
|
| }
|
| </style>
|
|
|
| - <!-- TODO(eakuefner): Use an iron-icon here once
|
| - https://github.com/catapult-project/catapult/issues/2772 is fixed. -->
|
| - <span id="remove" on-click="remove_">×</span>
|
| - <span id="key"></span>
|
| + <span id="left" on-click="moveLeft_">◀</span>
|
| + <input type="checkbox" id="enabled" on-change="onEnableChanged_">
|
| + <label for="enabled" id="label"></label>
|
| + <span id="right" on-click="moveRight_">▶</span>
|
| </template>
|
| </dom-module>
|
|
|
| @@ -114,78 +55,59 @@ tr.exportTo('tr.ui.b', function() {
|
| this.group_ = undefined;
|
| },
|
|
|
| - ready: function() {
|
| - this.setAttribute('draggable', true);
|
| - this.addEventListener('mouseover', this.onMouseOver_.bind(this));
|
| - this.addEventListener('mouseleave', this.onMouseLeave_.bind(this));
|
| - this.addEventListener('dragstart', this.onDragStart_.bind(this));
|
| - this.addEventListener('dragover', this.onDragOver_.bind(this));
|
| - },
|
| -
|
| - set group(g) {
|
| - this.group_ = g;
|
| - this.$.key.textContent = g.label;
|
| - },
|
| -
|
| - get key() {
|
| - return this.group_.key;
|
| - },
|
| -
|
| get picker() {
|
| return this.picker_;
|
| },
|
|
|
| set picker(picker) {
|
| this.picker_ = picker;
|
| - this.vertical = picker.vertical;
|
| },
|
|
|
| - // TODO(benjhayden): Use data-binding?
|
| - get vertical() {
|
| - return this.getAttribute('vertical');
|
| + get group() {
|
| + return this.group_;
|
| },
|
|
|
| - set vertical(vertical) {
|
| - if (vertical)
|
| - this.setAttribute('vertical', true);
|
| - else
|
| - this.removeAttribute('vertical');
|
| + set group(g) {
|
| + this.group_ = g;
|
| + this.$.label.textContent = g.label;
|
| },
|
|
|
| - onMouseOver_: function(event) {
|
| - this.$.remove.style.visibility = 'visible';
|
| + get enabled() {
|
| + return this.$.enabled.checked;
|
| },
|
|
|
| - onMouseLeave_: function(event) {
|
| - this.$.remove.style.visibility = 'hidden';
|
| + set enabled(enabled) {
|
| + this.$.enabled.checked = enabled;
|
| + if (!this.enabled) {
|
| + this.$.left.style.display = 'none';
|
| + this.$.right.style.display = 'none';
|
| + }
|
| },
|
|
|
| - onDragStart_: function(event) {
|
| - event.dataTransfer.effectAllowed = 'move';
|
| - this.setAttribute('dragging', true);
|
| + set isFirst(isFirst) {
|
| + this.$.left.style.display = (!this.enabled || isFirst) ? 'none' :
|
| + 'inline';
|
| },
|
|
|
| - onDragOver_: function(event) {
|
| - event.preventDefault(); // Allows us to drop.
|
| - event.dataTransfer.dropEffect = 'move';
|
| + set isLast(isLast) {
|
| + this.$.right.style.display = (!this.enabled || isLast) ? 'none' :
|
| + 'inline';
|
| + },
|
|
|
| - this.picker.clearDragIndicators_();
|
| - if (this.picker.shouldDropBefore_(this, event)) {
|
| - this.classList.add('drop-before');
|
| - if (this.previousElementSibling)
|
| - this.previousElementSibling.classList.add('drop-after');
|
| - } else {
|
| - this.classList.add('drop-after');
|
| - if (this.nextElementSibling)
|
| - this.nextElementSibling.classList.add('drop-before');
|
| - }
|
| - return false;
|
| + moveLeft_: function() {
|
| + this.picker.moveLeft_(this);
|
| + },
|
| +
|
| + moveRight_: function() {
|
| + this.picker.moveRight_(this);
|
| },
|
|
|
| - remove_: function(event) {
|
| - var newKeys = this.picker.currentGroupKeys.slice();
|
| - newKeys.splice(newKeys.indexOf(this.key), 1);
|
| - this.picker.currentGroupKeys = newKeys;
|
| + onEnableChanged_: function() {
|
| + if (!this.enabled) {
|
| + this.$.left.style.display = 'none';
|
| + this.$.right.style.display = 'none';
|
| + }
|
| + this.picker.onEnableChanged_(this);
|
| }
|
| });
|
|
|
| @@ -193,218 +115,133 @@ tr.exportTo('tr.ui.b', function() {
|
| is: 'tr-ui-b-grouping-table-groupby-picker',
|
|
|
| created: function() {
|
| - this.currentGroupKeys_ = undefined;
|
| - this.defaultGroupKeys_ = undefined;
|
| - this.possibleGroups_ = [];
|
| - this.settingsKey_ = [];
|
| - },
|
| -
|
| - ready: function() {
|
| - Polymer.dom(this.$.add_group.iconElement).textContent = 'Add another...';
|
| - this.addEventListener('dragend', this.onDragEnd_.bind(this));
|
| - this.addEventListener('drop', this.onDrop_.bind(this));
|
| + this.settingsKey_ = undefined;
|
| },
|
|
|
| - get defaultGroupKeys() {
|
| - return this.defaultGroupKeys_;
|
| - },
|
| -
|
| - set vertical(vertical) {
|
| - if (vertical)
|
| - this.setAttribute('vertical', true);
|
| - else
|
| - this.removeAttribute('vertical');
|
| -
|
| - for (var groupEl of this.$.groups.childNodes)
|
| - groupEl.vertical = vertical;
|
| + get settingsKey() {
|
| + return this.settingsKey_;
|
| },
|
|
|
| - get vertical() {
|
| - return this.getAttribute('vertical');
|
| + set settingsKey(settingsKey) {
|
| + this.settingsKey_ = settingsKey;
|
| + if (this.$.container.children.length) {
|
| + this.restoreSetting_();
|
| + }
|
| },
|
|
|
| - set defaultGroupKeys(defaultGroupKeys) {
|
| - this.defaultGroupKeys_ = defaultGroupKeys;
|
| - this.maybeInit_();
|
| + restoreSetting_: function() {
|
| + this.currentGroupKeys = tr.b.Settings.get(this.settingsKey_,
|
| + this.currentGroupKeys);
|
| },
|
|
|
| get possibleGroups() {
|
| - return this.possibleGroups_;
|
| + return [...this.$.container.children].map(groupEl => groupEl.group);
|
| },
|
|
|
| set possibleGroups(possibleGroups) {
|
| - this.possibleGroups_ = possibleGroups;
|
| - this.maybeInit_();
|
| - },
|
| -
|
| - get settingsKey() {
|
| - return this.settingsKey_;
|
| - },
|
| -
|
| - set settingsKey(settingsKey) {
|
| - this.settingsKey_ = settingsKey;
|
| - this.maybeInit_();
|
| + Polymer.dom(this.$.container).textContent = '';
|
| + for (var i = 0; i < possibleGroups.length; ++i) {
|
| + var groupEl = document.createElement(
|
| + 'tr-ui-b-grouping-table-groupby-picker-group');
|
| + groupEl.picker = this;
|
| + groupEl.group = possibleGroups[i];
|
| + Polymer.dom(this.$.container).appendChild(groupEl);
|
| + }
|
| + this.restoreSetting_();
|
| + this.updateFirstLast_();
|
| },
|
|
|
| - maybeInit_: function() {
|
| - if (!this.settingsKey_ ||
|
| - !this.defaultGroupKeys_ ||
|
| - !this.possibleGroups_) {
|
| - return;
|
| + updateFirstLast_: function() {
|
| + var groupEls = this.$.container.children;
|
| + var enabledGroupEls = [...groupEls].filter(el => el.enabled);
|
| + for (var i = 0; i < enabledGroupEls.length; ++i) {
|
| + enabledGroupEls[i].isFirst = i === 0;
|
| + enabledGroupEls[i].isLast = i === enabledGroupEls.length - 1;
|
| }
|
| -
|
| - this.currentGroupKeys = tr.b.Settings.get(
|
| - this.settingsKey_, this.defaultGroupKeys_);
|
| },
|
|
|
| get currentGroupKeys() {
|
| - return this.currentGroupKeys_;
|
| + return this.currentGroups.map(group => group.key);
|
| },
|
|
|
| get currentGroups() {
|
| - var groupsByKey = {};
|
| - for (var group of this.possibleGroups_)
|
| - groupsByKey[group.key] = group;
|
| - return this.currentGroupKeys.map(groupKey => groupsByKey[groupKey]);
|
| + var groups = [];
|
| + for (var groupEl of this.$.container.children) {
|
| + if (groupEl.enabled) {
|
| + groups.push(groupEl.group);
|
| + }
|
| + }
|
| + return groups;
|
| },
|
|
|
| - set currentGroupKeys(currentGroupKeys) {
|
| - if (this.currentGroupKeys_ === currentGroupKeys)
|
| + set currentGroupKeys(newKeys) {
|
| + if (!tr.b.compareArrays(this.currentGroupKeys, newKeys,
|
| + (x, y) => x.localeCompare(y))) {
|
| return;
|
| -
|
| - if (!(currentGroupKeys instanceof Array))
|
| - throw new Error('Must be array');
|
| -
|
| - var availableGroupKeys = new Set();
|
| - for (var group of this.possibleGroups_)
|
| - availableGroupKeys.add(group.key);
|
| - this.currentGroupKeys_ = currentGroupKeys.filter(
|
| - k => availableGroupKeys.has(k));
|
| - this.updateGroups_();
|
| -
|
| - tr.b.Settings.set(
|
| - this.settingsKey_, this.currentGroupKeys_);
|
| -
|
| - this.dispatchEvent(new tr.b.Event('current-groups-changed'));
|
| - },
|
| -
|
| - /**
|
| - * @return {undefined|Element}
|
| - */
|
| - get draggingGroupElement() {
|
| - for (var group of this.$.groups.children)
|
| - if (group.getAttribute('dragging'))
|
| - return group;
|
| - return undefined;
|
| - },
|
| -
|
| - shouldDropBefore_: function(groupEl, event) {
|
| - var dragBoxRect = this.draggingGroupElement.getBoundingClientRect();
|
| - var dropBoxRect = groupEl.getBoundingClientRect();
|
| - // compare horizontally if drag and drop overlap vertically
|
| - var dragVertRange = tr.b.Range.fromExplicitRange(
|
| - dragBoxRect.top, dragBoxRect.bottom);
|
| - var dropVertRange = tr.b.Range.fromExplicitRange(
|
| - dropBoxRect.top, dropBoxRect.bottom);
|
| - if (dragVertRange.intersectsRangeInclusive(dropVertRange))
|
| - return event.clientX < ((dropBoxRect.left + dropBoxRect.right) / 2);
|
| - return event.clientY < ((dropBoxRect.top + dropBoxRect.bottom) / 2);
|
| - },
|
| -
|
| - clearDragIndicators_: function() {
|
| - for (var groupEl of this.$.groups.children) {
|
| - groupEl.classList.remove('drop-before');
|
| - groupEl.classList.remove('drop-after');
|
| }
|
| - },
|
|
|
| - onDragEnd_: function(event) {
|
| - this.clearDragIndicators_();
|
| - for (var groupEl of this.$.groups.children)
|
| - groupEl.removeAttribute('dragging');
|
| - },
|
| + var possibleGroups = new Map();
|
| + for (var group of this.possibleGroups) {
|
| + possibleGroups.set(group.key, group);
|
| + }
|
|
|
| - onDrop_: function(event) {
|
| - event.stopPropagation(); // stops the browser from redirecting.
|
| + var groupEls = this.$.container.children;
|
|
|
| - var draggingGroupEl = this.draggingGroupElement;
|
| - var dropBeforeEl = undefined;
|
| - var dropAfterEl = undefined;
|
| - for (var groupEl of this.$.groups.children) {
|
| - if (groupEl.classList.contains('drop-before')) {
|
| - dropBeforeEl = groupEl;
|
| - break;
|
| - }
|
| - if (groupEl.classList.contains('drop-after')) {
|
| - dropAfterEl = groupEl;
|
| - break;
|
| + var i = 0;
|
| + for (i = 0; i < newKeys.length; ++i) {
|
| + var group = possibleGroups.get(newKeys[i]);
|
| + if (group === undefined) {
|
| + continue;
|
| }
|
| + groupEls[i].group = group;
|
| + groupEls[i].enabled = true;
|
| + possibleGroups.delete(newKeys[i]);
|
| }
|
|
|
| - if (!dropBeforeEl && !dropAfterEl)
|
| - return;
|
| + for (var group of possibleGroups.values()) {
|
| + groupEls[i].group = group;
|
| + groupEls[i].enabled = false;
|
| + ++i;
|
| + }
|
|
|
| - this.$.groups.removeChild(draggingGroupEl);
|
| - var lastGroupEl = this.$.groups.children[
|
| - this.$.groups.children.length - 1];
|
| -
|
| - if (dropBeforeEl)
|
| - this.$.groups.insertBefore(draggingGroupEl, dropBeforeEl);
|
| - else if (dropAfterEl === lastGroupEl)
|
| - this.$.groups.appendChild(draggingGroupEl);
|
| - else
|
| - this.$.groups.insertBefore(draggingGroupEl, dropAfterEl.nextSibling);
|
| -
|
| - var currentGroupKeys = [];
|
| - for (var group of this.$.groups.children)
|
| - currentGroupKeys.push(group.key);
|
| - this.currentGroupKeys = currentGroupKeys;
|
| - return false;
|
| + this.updateFirstLast_();
|
| + this.onCurrentGroupsChanged_();
|
| },
|
|
|
| - updateGroups_: function() {
|
| - Polymer.dom(this.$.groups).textContent = '';
|
| - Polymer.dom(this.$.add_group).textContent = '';
|
| + moveLeft_: function(groupEl) {
|
| + var reference = groupEl.previousSibling;
|
| + Polymer.dom(this.$.container).removeChild(groupEl);
|
| + Polymer.dom(this.$.container).insertBefore(groupEl, reference);
|
| + this.updateFirstLast_();
|
|
|
| - var unusedGroups = {};
|
| - var groupsByKey = {};
|
| - for (var group of this.possibleGroups_) {
|
| - unusedGroups[group.key] = group;
|
| - groupsByKey[group.key] = group;
|
| + if (groupEl.enabled) {
|
| + this.onCurrentGroupsChanged_();
|
| }
|
| + },
|
|
|
| - for (var key of this.currentGroupKeys_)
|
| - delete unusedGroups[key];
|
| -
|
| - // Create groups.
|
| - for (var key of this.currentGroupKeys_) {
|
| - var group = groupsByKey[key];
|
| - var groupEl = document.createElement(
|
| - 'tr-ui-b-grouping-table-groupby-picker-group');
|
| - groupEl.picker = this;
|
| - groupEl.group = group;
|
| - Polymer.dom(this.$.groups).appendChild(groupEl);
|
| + moveRight_: function(groupEl) {
|
| + var reference = groupEl.nextSibling.nextSibling;
|
| + Polymer.dom(this.$.container).removeChild(groupEl);
|
| + if (reference) {
|
| + Polymer.dom(this.$.container).insertBefore(groupEl, reference);
|
| + } else {
|
| + Polymer.dom(this.$.container).appendChild(groupEl);
|
| }
|
| + this.updateFirstLast_();
|
|
|
| - // Adjust dropdown.
|
| - tr.b.iterItems(unusedGroups, function(key, group) {
|
| - var groupEl = document.createElement('possible-group');
|
| - Polymer.dom(groupEl).textContent = group.label;
|
| - groupEl.addEventListener('click', function() {
|
| - var newKeys = this.currentGroupKeys.slice();
|
| - newKeys.push(key);
|
| - this.currentGroupKeys = newKeys;
|
| - this.$.add_group.close();
|
| - }.bind(this));
|
| - Polymer.dom(this.$.add_group).appendChild(groupEl);
|
| - }, this);
|
| -
|
| - // Hide dropdown if needed.
|
| - if (tr.b.dictionaryLength(unusedGroups) === 0) {
|
| - this.$.add_group.style.display = 'none';
|
| - } else {
|
| - this.$.add_group.style.display = '';
|
| + if (groupEl.enabled) {
|
| + this.onCurrentGroupsChanged_();
|
| }
|
| + },
|
| +
|
| + onCurrentGroupsChanged_: function() {
|
| + this.dispatchEvent(new tr.b.Event('current-groups-changed'));
|
| + tr.b.Settings.set(this.settingsKey_, this.currentGroupKeys);
|
| + },
|
| +
|
| + onEnableChanged_: function(groupEl) {
|
| + this.updateFirstLast_();
|
| + this.onCurrentGroupsChanged_();
|
| }
|
| });
|
|
|
|
|