Included-In dialog polish
Add a filter textbox and behavior to the Included-In dialog and align the padding with other dialogs. To accommodate filtering, empty groups are hidden. Change-Id: I481f266ce8cc67de07f1dc8dfb9129b7d36e081b
This commit is contained in:
committed by
Paladox none
parent
3810c5e7c4
commit
8e32422334
@@ -205,7 +205,6 @@ limitations under the License.
|
||||
overflow: auto;
|
||||
}
|
||||
#includedInOverlay {
|
||||
padding: 2em;
|
||||
width: 65em;
|
||||
}
|
||||
@media screen and (min-width: 80em) {
|
||||
|
||||
@@ -23,22 +23,35 @@ limitations under the License.
|
||||
<style include="shared-styles">
|
||||
:host {
|
||||
display: block;
|
||||
padding: 1em;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
padding: 4.5em 1em 1em 1em;
|
||||
}
|
||||
h1 {
|
||||
header {
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #cdcdcd;
|
||||
left: 0;
|
||||
padding: 1em;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
#title {
|
||||
display: inline-block;
|
||||
font-size: 1.2rem;
|
||||
margin-top: .2em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.closeButtonContainer {
|
||||
position: absolute;
|
||||
right: 2em;
|
||||
top: 2em;
|
||||
#filterInput {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin: 0 1em;
|
||||
padding: .2em;
|
||||
}
|
||||
.container {
|
||||
max-height: 80vh;
|
||||
overflow-y: scroll;
|
||||
.closeButtonContainer {
|
||||
float: right;
|
||||
}
|
||||
ul {
|
||||
margin-bottom: 1em;
|
||||
@@ -55,29 +68,32 @@ limitations under the License.
|
||||
}
|
||||
</style>
|
||||
<header>
|
||||
<h1>Included In:</h1>
|
||||
<h1 id="title">Included In:</h1>
|
||||
<span class="closeButtonContainer">
|
||||
<gr-button id="closeButton"
|
||||
link
|
||||
on-tap="_handleCloseTap">Close</gr-button>
|
||||
</span>
|
||||
<input
|
||||
id="filterInput"
|
||||
is="iron-input"
|
||||
placeholder="Filter"
|
||||
on-bind-value-changed="_onFilterChanged">
|
||||
</header>
|
||||
<div class$="[[_computeLoadingClass(_loaded)]]">Loading...</div>
|
||||
<div class="container">
|
||||
<template
|
||||
is="dom-repeat"
|
||||
items="[[_computeGroups(_includedIn)]]"
|
||||
as="group">
|
||||
<div>
|
||||
<h2>[[group.title]]:</h2>
|
||||
<ul>
|
||||
<template is="dom-repeat" items="[[group.items]]">
|
||||
<li>[[item]]</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<template
|
||||
is="dom-repeat"
|
||||
items="[[_computeGroups(_includedIn, _filterText)]]"
|
||||
as="group">
|
||||
<div>
|
||||
<h2>[[group.title]]:</h2>
|
||||
<ul>
|
||||
<template is="dom-repeat" items="[[group.items]]">
|
||||
<li>[[item]]</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
</template>
|
||||
<script src="gr-included-in-dialog.js"></script>
|
||||
|
||||
@@ -35,10 +35,15 @@
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
_filterText: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
|
||||
loadData() {
|
||||
if (!this.changeNum) { return; }
|
||||
this._filterText = '';
|
||||
return this.$.restAPI.getChangeIncludedIn(this.changeNum).then(
|
||||
configs => {
|
||||
if (!configs) { return; }
|
||||
@@ -52,22 +57,25 @@
|
||||
this._loaded = false;
|
||||
},
|
||||
|
||||
_computeGroups(includedIn) {
|
||||
_computeGroups(includedIn, filterText) {
|
||||
if (!includedIn) { return []; }
|
||||
|
||||
const filter = item => !filterText.length ||
|
||||
item.toLowerCase().indexOf(filterText.toLowerCase()) !== -1;
|
||||
|
||||
const groups = [
|
||||
{title: 'Branches', items: includedIn.branches},
|
||||
{title: 'Tags', items: includedIn.tags},
|
||||
{title: 'Branches', items: includedIn.branches.filter(filter)},
|
||||
{title: 'Tags', items: includedIn.tags.filter(filter)},
|
||||
];
|
||||
if (includedIn.external) {
|
||||
for (const externalKey of Object.keys(includedIn.external)) {
|
||||
groups.push({
|
||||
title: externalKey,
|
||||
items: includedIn.external[externalKey],
|
||||
items: includedIn.external[externalKey].filter(filter),
|
||||
});
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
return groups.filter(g => g.items.length);
|
||||
},
|
||||
|
||||
_handleCloseTap(e) {
|
||||
@@ -78,5 +86,11 @@
|
||||
_computeLoadingClass(loaded) {
|
||||
return loaded ? 'loading loaded' : 'loading';
|
||||
},
|
||||
|
||||
_onFilterChanged() {
|
||||
this.debounce('filter-change', () => {
|
||||
this._filterText = this.$.filterInput.bindValue;
|
||||
}, 100);
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -45,30 +45,39 @@ limitations under the License.
|
||||
|
||||
test('_computeGroups', () => {
|
||||
const includedIn = {branches: [], tags: []};
|
||||
assert.deepEqual(element._computeGroups(includedIn), [
|
||||
{title: 'Branches', items: []},
|
||||
{title: 'Tags', items: []},
|
||||
]);
|
||||
let filterText = '';
|
||||
assert.deepEqual(element._computeGroups(includedIn, filterText), []);
|
||||
|
||||
includedIn.branches.push('master', 'development', 'stable-2.0');
|
||||
includedIn.tags.push('v1.9', 'v2.0', 'v2.1');
|
||||
assert.deepEqual(element._computeGroups(includedIn), [
|
||||
assert.deepEqual(element._computeGroups(includedIn, filterText), [
|
||||
{title: 'Branches', items: ['master', 'development', 'stable-2.0']},
|
||||
{title: 'Tags', items: ['v1.9', 'v2.0', 'v2.1']},
|
||||
]);
|
||||
|
||||
includedIn.external = {};
|
||||
assert.deepEqual(element._computeGroups(includedIn), [
|
||||
assert.deepEqual(element._computeGroups(includedIn, filterText), [
|
||||
{title: 'Branches', items: ['master', 'development', 'stable-2.0']},
|
||||
{title: 'Tags', items: ['v1.9', 'v2.0', 'v2.1']},
|
||||
]);
|
||||
|
||||
includedIn.external.foo = ['abc', 'def', 'ghi'];
|
||||
assert.deepEqual(element._computeGroups(includedIn), [
|
||||
assert.deepEqual(element._computeGroups(includedIn, filterText), [
|
||||
{title: 'Branches', items: ['master', 'development', 'stable-2.0']},
|
||||
{title: 'Tags', items: ['v1.9', 'v2.0', 'v2.1']},
|
||||
{title: 'foo', items: ['abc', 'def', 'ghi']},
|
||||
]);
|
||||
|
||||
filterText = 'v2';
|
||||
assert.deepEqual(element._computeGroups(includedIn, filterText), [
|
||||
{title: 'Tags', items: ['v2.0', 'v2.1']},
|
||||
]);
|
||||
|
||||
// Filtering is case-insensitive.
|
||||
filterText = 'V2';
|
||||
assert.deepEqual(element._computeGroups(includedIn, filterText), [
|
||||
{title: 'Tags', items: ['v2.0', 'v2.1']},
|
||||
]);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user