Fix moving cursor across sections in dashboard

Change I7baad12a02e0e9e53b74537215ddbf21c7b2d006 introduced a regression
where the cursor indicator disappears when moved below the first section
containing results. This change fixes the root cause, refactors
slightly, and adds tests.

Bug: Issue 7118
Change-Id: Ide4f31af2af161dc1085167740b698c5507953ac
This commit is contained in:
Logan Hanks
2017-08-29 13:26:12 -07:00
parent a93303ec67
commit 2cc999ada5
3 changed files with 45 additions and 14 deletions

View File

@@ -94,7 +94,7 @@ limitations under the License.
</template>
<template is="dom-repeat" items="[[changeSection.results]]" as="change">
<gr-change-list-item
selected$="[[_computeItemSelected(index, sectionIndex, selectedIndex)]]"
selected$="[[_computeItemSelected(sectionIndex, index, selectedIndex)]]"
assigned$="[[_computeItemAssigned(account, change)]]"
needs-review$="[[_computeItemNeedsReview(account, change, showReviewedState)]]"
change="[[change]]"

View File

@@ -179,12 +179,24 @@
return `${this.getBaseUrl()}/q/${this.encodeURL(query, true)}`;
},
_computeItemSelected(index, sectionIndex, selectedIndex) {
/**
* Maps an index local to a particular section to the absolute index
* across all the changes on the page.
*
* @param sectionIndex {number} index of section
* @param localIndex {number} index of row within section
* @return {number} absolute index of row in the aggregate dashboard
*/
_computeItemAbsoluteIndex(sectionIndex, localIndex) {
let idx = 0;
for (let i = 0; i < sectionIndex; i++) {
idx += this.sections[i].length;
idx += this.sections[i].results.length;
}
idx += index;
return idx + localIndex;
},
_computeItemSelected(sectionIndex, index, selectedIndex) {
const idx = this._computeItemAbsoluteIndex(sectionIndex, index);
return idx == selectedIndex;
},
@@ -199,21 +211,13 @@
return account._account_id === change.assignee._account_id;
},
_getAggregatesectionsLen(sections) {
sections = sections || [];
let len = 0;
for (const section of this.sections) {
len += section.length;
}
return len;
},
_handleJKey(e) {
if (this.shouldSuppressKeyboardShortcut(e) ||
this.modifierPressed(e)) { return; }
e.preventDefault();
const len = this._getAggregatesectionsLen(this.sections);
// Compute absolute index of item that would come after final item.
const len = this._computeItemAbsoluteIndex(this.sections.length, 0);
if (this.selectedIndex === len - 1) { return; }
this.selectedIndex += 1;
},

View File

@@ -148,6 +148,11 @@ limitations under the License.
});
test('keyboard shortcuts', done => {
sandbox.stub(element, '_computeLabelNames');
element.sections = [
{results: new Array(1)},
{results: new Array(2)},
];
element.selectedIndex = 0;
element.changes = [
{_number: 0},
@@ -163,7 +168,10 @@ limitations under the License.
assert.isTrue(elementItems[0].hasAttribute('selected'));
MockInteractions.pressAndReleaseKeyOn(element, 74, null, 'j');
assert.equal(element.selectedIndex, 1);
assert.isTrue(elementItems[1].hasAttribute('selected'));
MockInteractions.pressAndReleaseKeyOn(element, 74, null, 'j');
assert.equal(element.selectedIndex, 2);
assert.isTrue(elementItems[2].hasAttribute('selected'));
const navStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
assert.equal(element.selectedIndex, 2);
@@ -484,5 +492,24 @@ limitations under the License.
'is:open ((reviewer:self -is:ignored) OR assignee:self)'),
'/q/is:open+((reviewer:self+-is:ignored)+OR+assignee:self)');
});
test('_computeItemAbsoluteIndex', () => {
sandbox.stub(element, '_computeLabelNames');
element.sections = [
{results: new Array(1)},
{results: new Array(2)},
{results: new Array(3)},
];
assert.equal(element._computeItemAbsoluteIndex(0, 0), 0);
// Out of range but no matter.
assert.equal(element._computeItemAbsoluteIndex(0, 1), 1);
assert.equal(element._computeItemAbsoluteIndex(1, 0), 1);
assert.equal(element._computeItemAbsoluteIndex(1, 1), 2);
assert.equal(element._computeItemAbsoluteIndex(1, 2), 3);
assert.equal(element._computeItemAbsoluteIndex(2, 0), 3);
assert.equal(element._computeItemAbsoluteIndex(3, 0), 6);
});
});
</script>