Implement user dashboard view
This changes the way the change list view is layed out (flexbox instead of tables) for a couple reasons: + Table elements (td, tr, etc.) cannot be arbitrarily appended to just any DOM node, which caused breakage when I originally attempted to use a <content> tag to bring in the header or group title content into gr-change-list-item. + The flexibility of flexbox allows us to style the change list much easier on smaller screens, so it was probably going to happen anyway. + Full-width (colspan="<total number of columns in the table>") rows for the headers is much more difficult when using elements outside of the gr-change-list-item brought in via <content> as described above. + gr-change-list-item was doing too much anyway. Feature: Issue 3700 Change-Id: I6536bf7d18adfa460507f8050a15d83e84af82a7
This commit is contained in:
committed by
Dave Borowitz
parent
a75837c6b5
commit
7aa52d3d0a
@@ -15,25 +15,22 @@ limitations under the License.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../styles/gr-change-list-styles.html">
|
||||||
<link rel="import" href="gr-date-formatter.html">
|
<link rel="import" href="gr-date-formatter.html">
|
||||||
|
|
||||||
<dom-module id="gr-change-list-item">
|
<dom-module id="gr-change-list-item">
|
||||||
<template>
|
<template>
|
||||||
<style>
|
<style>
|
||||||
:host {
|
:host {
|
||||||
display: table-row;
|
display: flex;
|
||||||
}
|
}
|
||||||
:host([selected]) {
|
:host([selected]) {
|
||||||
background-color: #d8EdF9;
|
background-color: #d8EdF9;
|
||||||
}
|
}
|
||||||
th, td {
|
.cell {
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
|
flex-shrink: 0;
|
||||||
padding: .3em .5em;
|
padding: .3em .5em;
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
th {
|
|
||||||
background: #ddd;
|
|
||||||
text-align: left;
|
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
color: var(--default-text-color);
|
color: var(--default-text-color);
|
||||||
@@ -64,48 +61,29 @@ limitations under the License.
|
|||||||
color: #D32F2F;
|
color: #D32F2F;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<template is="dom-if" if="[[header]]">
|
<style include="gr-change-list-styles"></style>
|
||||||
<th></th> <!-- keyboard position indicator -->
|
<span class="cell keyboard">
|
||||||
<th>Subject</th>
|
<span class="positionIndicator">▶</span>
|
||||||
<th>Status</th>
|
</span>
|
||||||
<th>Owner</th>
|
<a class="cell subject" href$="[[changeURL]]">[[change.subject]]</a>
|
||||||
<th>Project</th>
|
<span class="cell status">[[_computeChangeStatusString(change)]]</span>
|
||||||
<th>Branch</th>
|
<span class="cell owner">
|
||||||
<th>Updated</th>
|
<template is="dom-if" if="[[showAvatar]]">
|
||||||
<th>Size</th>
|
<img class="avatarImage" src$="[[_computeAvatarURL(change.owner)]]">
|
||||||
<th title="Code-Review">CR</th>
|
</template>
|
||||||
<th title="Verified">V</th>
|
<a href$="[[_computeOwnerLink(change.owner.email)]]"
|
||||||
</template>
|
title$="[[_computeOwnerTitle(change.owner)]]">[[change.owner.name]]</a>
|
||||||
<template is="dom-if" if="[[!header]]">
|
</span>
|
||||||
<td>
|
<a class="cell project" href$="[[_computeProjectURL(change.project)]]">[[change.project]]</a>
|
||||||
<span class="positionIndicator">▶</span>
|
<a class="cell branch" href$="[[_computeProjectBranchURL(change.project, change.branch)]]">[[change.branch]]</a>
|
||||||
</td>
|
<gr-date-formatter class="cell updated" date-str="[[change.updated]]"></gr-date-formatter>
|
||||||
<td>
|
<span class="cell size u-monospace">
|
||||||
<a href$="[[changeURL]]">[[change.subject]]</a>
|
<span class="u-green"><span>+</span>[[change.insertions]]</span>,
|
||||||
</td>
|
<span class="u-red"><span>-</span>[[change.deletions]]</span>
|
||||||
<td>[[_computeChangeStatusString(change)]]</td>
|
</span>
|
||||||
<td>
|
<span title="Code-Review"
|
||||||
<template is="dom-if" if="[[showAvatar]]">
|
class$="[[_computeCodeReviewClass(change.labels.Code-Review)]]">[[_computeCodeReviewLabel(change.labels.Code-Review)]]</span>
|
||||||
<img class="avatarImage" src$="[[_computeAvatarURL(change.owner)]]">
|
<span class="cell verified u-green" title="Verified">[[_computeVerifiedLabel(change.labels.Verified)]]</span>
|
||||||
</template>
|
|
||||||
<a href$="[[_computeOwnerLink(change.owner.email)]]"
|
|
||||||
title$="[[_computeOwnerTitle(change.owner)]]">[[change.owner.name]]</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href$="[[_computeProjectURL(change.project)]]">[[change.project]]</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href$="[[_computeProjectBranchURL(change.project, change.branch)]]">[[change.branch]]</a>
|
|
||||||
</td>
|
|
||||||
<td><gr-date-formatter date-str="[[change.updated]]"></gr-date-formatter></td>
|
|
||||||
<td class="u-monospace">
|
|
||||||
<span class="u-green"><span>+</span>[[change.insertions]]</span>,
|
|
||||||
<span class="u-red"><span>-</span>[[change.deletions]]</span>
|
|
||||||
</td>
|
|
||||||
<td title="Code-Review"
|
|
||||||
class$="[[_computeCodeReviewClass(change.labels.Code-Review)]]">[[_computeCodeReviewLabel(change.labels.Code-Review)]]</td>
|
|
||||||
<td title="Verified" class="u-green">[[_computeVerifiedLabel(change.labels.Verified)]]</td>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
@@ -115,11 +93,6 @@ limitations under the License.
|
|||||||
is: 'gr-change-list-item',
|
is: 'gr-change-list-item',
|
||||||
|
|
||||||
properties: {
|
properties: {
|
||||||
header: {
|
|
||||||
type: Boolean,
|
|
||||||
reflectToAttribute: true,
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
selected: {
|
selected: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
reflectToAttribute: true,
|
reflectToAttribute: true,
|
||||||
@@ -147,24 +120,40 @@ limitations under the License.
|
|||||||
},
|
},
|
||||||
|
|
||||||
_computeChangeStatusString: function(change) {
|
_computeChangeStatusString: function(change) {
|
||||||
if (!change.mergeable) {
|
if (change.mergeable != null && change.mergeable == false) {
|
||||||
return 'Merge Conflict';
|
return 'Merge Conflict';
|
||||||
}
|
}
|
||||||
|
if (change.status == Changes.Status.MERGED) {
|
||||||
|
return 'Merged';
|
||||||
|
}
|
||||||
|
if (change.status == Changes.Status.DRAFT) {
|
||||||
|
return 'Draft';
|
||||||
|
}
|
||||||
|
if (change.status == Changes.Status.ABANDONED) {
|
||||||
|
return 'Abandoned';
|
||||||
|
}
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
_computeCodeReviewClass: function(codeReview) {
|
_computeCodeReviewClass: function(codeReview) {
|
||||||
if (!codeReview) { return ''; }
|
// Mimic a Set.
|
||||||
if (codeReview.approved) {
|
var classes = {
|
||||||
return 'u-green';
|
'cell': true,
|
||||||
|
'codeReview': true,
|
||||||
|
};
|
||||||
|
if (codeReview) {
|
||||||
|
if (codeReview.approved) {
|
||||||
|
classes['u-green'] = true;
|
||||||
|
}
|
||||||
|
if (codeReview.value == 1) {
|
||||||
|
classes['u-monospace'] = true;
|
||||||
|
classes['u-green'] = true;
|
||||||
|
} else if (codeReview.value == -1) {
|
||||||
|
classes['u-monospace'] = true;
|
||||||
|
classes['u-red'] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (codeReview.value == 1) {
|
return Object.keys(classes).sort().join(' ');
|
||||||
return 'u-monospace u-green';
|
|
||||||
}
|
|
||||||
if (codeReview.value == -1) {
|
|
||||||
return 'u-monospace u-red';
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_computeCodeReviewLabel: function(codeReview) {
|
_computeCodeReviewLabel: function(codeReview) {
|
||||||
|
|||||||
@@ -16,20 +16,51 @@ limitations under the License.
|
|||||||
|
|
||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
<link rel="import" href="../bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
|
<link rel="import" href="../bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
|
||||||
|
<link rel="import" href="../styles/gr-change-list-styles.html">
|
||||||
<link rel="import" href="gr-change-list-item.html">
|
<link rel="import" href="gr-change-list-item.html">
|
||||||
|
|
||||||
<dom-module id="gr-change-list">
|
<dom-module id="gr-change-list">
|
||||||
<template>
|
<template>
|
||||||
<style>
|
<style>
|
||||||
:host {
|
:host {
|
||||||
display: table;
|
display: flex;
|
||||||
border-collapse: collapse;
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.headerRow {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.topHeader,
|
||||||
|
.groupHeader {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: .3em .5em;
|
||||||
|
}
|
||||||
|
.topHeader {
|
||||||
|
background-color: #ddd;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<gr-change-list-item header></gr-change-list-item>
|
<style include="gr-change-list-styles"></style>
|
||||||
<template is="dom-repeat" items="{{changes}}" as="change">
|
<div class="headerRow">
|
||||||
<gr-change-list-item change="[[change]]"
|
<span class="topHeader keyboard"></span> <!-- keyboard position indicator -->
|
||||||
selected="[[_isSelected(index)]]"></gr-change-list-item>
|
<span class="topHeader subject">Subject</span>
|
||||||
|
<span class="topHeader status">Status</span>
|
||||||
|
<span class="topHeader owner">Owner</span>
|
||||||
|
<span class="topHeader project">Project</span>
|
||||||
|
<span class="topHeader branch">Branch</span>
|
||||||
|
<span class="topHeader updated">Updated</span>
|
||||||
|
<span class="topHeader size">Size</span>
|
||||||
|
<span class="topHeader codeReview" title="Code-Review">CR</span>
|
||||||
|
<span class="topHeader verified" title="Verified">V</span>
|
||||||
|
</div>
|
||||||
|
<template is="dom-repeat" items="{{groups}}" as="changeGroup" index-as="groupIndex">
|
||||||
|
<template is="dom-if" if="[[_groupTitle(groupIndex)]]">
|
||||||
|
<div class="groupHeader">[[_groupTitle(groupIndex)]]</div>
|
||||||
|
</template>
|
||||||
|
<template is="dom-repeat" items="[[changeGroup]]" as="change">
|
||||||
|
<gr-change-list-item change="[[change]]"
|
||||||
|
selected="[[_isSelected(groupIndex, index)]]"></gr-change-list-item>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -53,13 +84,25 @@ limitations under the License.
|
|||||||
* An array of ChangeInfo objects to render.
|
* An array of ChangeInfo objects to render.
|
||||||
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-info
|
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-info
|
||||||
*/
|
*/
|
||||||
changes: Array,
|
changes: {
|
||||||
|
type: Array,
|
||||||
|
observer: '_changesChanged',
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ChangeInfo objects grouped into arrays. The groups and changes
|
||||||
|
* properties should not be used together.
|
||||||
|
*/
|
||||||
|
groups: Array,
|
||||||
keyEventTarget: {
|
keyEventTarget: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: function() {
|
value: function() {
|
||||||
return document.body;
|
return document.body;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
groupTitles: {
|
||||||
|
type: Array,
|
||||||
|
value: [],
|
||||||
|
},
|
||||||
selectedIndex: {
|
selectedIndex: {
|
||||||
type: Number,
|
type: Number,
|
||||||
value: 0,
|
value: 0,
|
||||||
@@ -71,13 +114,22 @@ limitations under the License.
|
|||||||
'j k o enter': '_handleKey',
|
'j k o enter': '_handleKey',
|
||||||
},
|
},
|
||||||
|
|
||||||
_isSelected: function(index) {
|
_isSelected: function(groupIndex, index) {
|
||||||
return index == this.selectedIndex;
|
return index == this.selectedIndex;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_changesChanged: function(changes) {
|
||||||
|
this.groups = [changes];
|
||||||
|
},
|
||||||
|
|
||||||
|
_groupTitle: function(groupIndex) {
|
||||||
|
if (groupIndex > this.groupTitles.length - 1) { return null; }
|
||||||
|
return this.groupTitles[groupIndex];
|
||||||
|
},
|
||||||
|
|
||||||
_selectedIndexChanged: function(value) {
|
_selectedIndexChanged: function(value) {
|
||||||
// Don't re-render the entire list.
|
// Don't re-render the entire list.
|
||||||
var changeEls = this._getNonHeaderListItems();
|
var changeEls = this._getListItems();
|
||||||
for (var i = 0; i < changeEls.length; i++) {
|
for (var i = 0; i < changeEls.length; i++) {
|
||||||
changeEls[i].toggleAttribute('selected', i == value);
|
changeEls[i].toggleAttribute('selected', i == value);
|
||||||
}
|
}
|
||||||
@@ -86,7 +138,11 @@ limitations under the License.
|
|||||||
_handleKey: function(e) {
|
_handleKey: function(e) {
|
||||||
if (util.shouldSupressKeyboardShortcut(e)) { return; }
|
if (util.shouldSupressKeyboardShortcut(e)) { return; }
|
||||||
|
|
||||||
var len = (this.changes && this.changes.length) || 0;
|
if (this.groups == null) { return; }
|
||||||
|
var len = 0;
|
||||||
|
this.groups.forEach(function(group) {
|
||||||
|
len += group.length;
|
||||||
|
});
|
||||||
switch(e.detail.combo) {
|
switch(e.detail.combo) {
|
||||||
case 'j':
|
case 'j':
|
||||||
if (this.selectedIndex == len - 1) { return; }
|
if (this.selectedIndex == len - 1) { return; }
|
||||||
@@ -104,16 +160,15 @@ limitations under the License.
|
|||||||
},
|
},
|
||||||
|
|
||||||
_changeURLForIndex: function(index) {
|
_changeURLForIndex: function(index) {
|
||||||
var changeEls = this._getNonHeaderListItems();
|
var changeEls = this._getListItems();
|
||||||
if (index < changeEls.length && changeEls[index]) {
|
if (index < changeEls.length && changeEls[index]) {
|
||||||
return changeEls[index].changeURL;
|
return changeEls[index].changeURL;
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
_getNonHeaderListItems: function() {
|
_getListItems: function() {
|
||||||
return Polymer.dom(this.root).querySelectorAll(
|
return Polymer.dom(this.root).querySelectorAll('gr-change-list-item');
|
||||||
'gr-change-list-item:not([header])');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,6 +18,17 @@ limitations under the License.
|
|||||||
|
|
||||||
<dom-module id="gr-dashboard-view">
|
<dom-module id="gr-dashboard-view">
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
background-color: var(--view-background-color);
|
||||||
|
display: block;
|
||||||
|
margin: 0 1.25rem;
|
||||||
|
}
|
||||||
|
gr-change-list {
|
||||||
|
margin-top: 1em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<iron-ajax id="xhr"
|
<iron-ajax id="xhr"
|
||||||
auto
|
auto
|
||||||
url="/changes/"
|
url="/changes/"
|
||||||
@@ -25,6 +36,8 @@ limitations under the License.
|
|||||||
last-response="{{_results}}"
|
last-response="{{_results}}"
|
||||||
json-prefix=")]}'"
|
json-prefix=")]}'"
|
||||||
debounce-duration="300"></iron-ajax>
|
debounce-duration="300"></iron-ajax>
|
||||||
|
<gr-change-list groups="{{_results}}"
|
||||||
|
group-titles="[[_groupTitles]]"></gr-change-list>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
@@ -35,6 +48,14 @@ limitations under the License.
|
|||||||
|
|
||||||
properties: {
|
properties: {
|
||||||
_results: Array,
|
_results: Array,
|
||||||
|
_groupTitles: {
|
||||||
|
type: Array,
|
||||||
|
value: [
|
||||||
|
'Outgoing reviews',
|
||||||
|
'Incoming reviews',
|
||||||
|
'Recently closed',
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
_computeQueryParams: function() {
|
_computeQueryParams: function() {
|
||||||
|
|||||||
@@ -25,6 +25,13 @@ Changes.DiffType = {
|
|||||||
REWRITE: 'REWRITE',
|
REWRITE: 'REWRITE',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Changes.Status = {
|
||||||
|
NEW: 'NEW',
|
||||||
|
MERGED: 'MERGED',
|
||||||
|
ABANDONED: 'ABANDONED',
|
||||||
|
DRAFT: 'DRAFT',
|
||||||
|
};
|
||||||
|
|
||||||
// Must be kept in sync with the ListChangesOption enum and protobuf.
|
// Must be kept in sync with the ListChangesOption enum and protobuf.
|
||||||
Changes.ListChangesOption = {
|
Changes.ListChangesOption = {
|
||||||
LABELS: 0,
|
LABELS: 0,
|
||||||
|
|||||||
63
polygerrit-ui/app/styles/gr-change-list-styles.html
Normal file
63
polygerrit-ui/app/styles/gr-change-list-styles.html
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2015 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<dom-module id="gr-change-list-styles">
|
||||||
|
<template>
|
||||||
|
<style>
|
||||||
|
.keyboard {
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
.subject {
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
.status {
|
||||||
|
width: 9em;
|
||||||
|
}
|
||||||
|
.owner {
|
||||||
|
width: 15em;
|
||||||
|
}
|
||||||
|
.project,
|
||||||
|
.branch {
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.project {
|
||||||
|
width: 10em;
|
||||||
|
}
|
||||||
|
.branch {
|
||||||
|
width: 7em;
|
||||||
|
}
|
||||||
|
.updated {
|
||||||
|
width: 6em;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.size {
|
||||||
|
width: 9em;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.codeReview {
|
||||||
|
width: 2.6em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.verified {
|
||||||
|
width: 2em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</template>
|
||||||
|
</dom-module>
|
||||||
@@ -20,6 +20,7 @@ limitations under the License.
|
|||||||
|
|
||||||
<script src="../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
<script src="../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
||||||
<script src="../../bower_components/web-component-tester/browser.js"></script>
|
<script src="../../bower_components/web-component-tester/browser.js"></script>
|
||||||
|
<script src="../scripts/changes.js"></script>
|
||||||
<script src="../scripts/fake-app.js"></script>
|
<script src="../scripts/fake-app.js"></script>
|
||||||
|
|
||||||
<link rel="import" href="../elements/gr-change-list-item.html">
|
<link rel="import" href="../elements/gr-change-list-item.html">
|
||||||
@@ -42,15 +43,22 @@ limitations under the License.
|
|||||||
assert.equal(element._computeChangeStatusString({mergeable: true}), '');
|
assert.equal(element._computeChangeStatusString({mergeable: true}), '');
|
||||||
assert.equal(element._computeChangeStatusString({mergeable: false}),
|
assert.equal(element._computeChangeStatusString({mergeable: false}),
|
||||||
'Merge Conflict');
|
'Merge Conflict');
|
||||||
|
assert.equal(element._computeChangeStatusString({status: 'NEW'}), '');
|
||||||
|
assert.equal(element._computeChangeStatusString({status: 'MERGED'}),
|
||||||
|
'Merged');
|
||||||
|
assert.equal(element._computeChangeStatusString({status: 'ABANDONED'}),
|
||||||
|
'Abandoned');
|
||||||
|
assert.equal(element._computeChangeStatusString({status: 'DRAFT'}),
|
||||||
|
'Draft');
|
||||||
|
|
||||||
assert.equal(element._computeCodeReviewClass(), '');
|
assert.equal(element._computeCodeReviewClass(), 'cell codeReview');
|
||||||
assert.equal(element._computeCodeReviewClass({}), '');
|
assert.equal(element._computeCodeReviewClass({}), 'cell codeReview');
|
||||||
assert.equal(element._computeCodeReviewClass({approved: true, value: 1}),
|
assert.equal(element._computeCodeReviewClass({approved: true, value: 1}),
|
||||||
'u-green');
|
'cell codeReview u-green u-monospace');
|
||||||
assert.equal(element._computeCodeReviewClass({value: 1}),
|
assert.equal(element._computeCodeReviewClass({value: 1}),
|
||||||
'u-monospace u-green');
|
'cell codeReview u-green u-monospace');
|
||||||
assert.equal(element._computeCodeReviewClass({value: -1}),
|
assert.equal(element._computeCodeReviewClass({value: -1}),
|
||||||
'u-monospace u-red');
|
'cell codeReview u-monospace u-red');
|
||||||
|
|
||||||
assert.equal(element._computeCodeReviewLabel(), '');
|
assert.equal(element._computeCodeReviewLabel(), '');
|
||||||
assert.equal(element._computeCodeReviewLabel({}), '');
|
assert.equal(element._computeCodeReviewLabel({}), '');
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ limitations under the License.
|
|||||||
<script src="../../bower_components/web-component-tester/browser.js"></script>
|
<script src="../../bower_components/web-component-tester/browser.js"></script>
|
||||||
<script src="../../bower_components/page/page.js"></script>
|
<script src="../../bower_components/page/page.js"></script>
|
||||||
<script src="../scripts/fake-app.js"></script>
|
<script src="../scripts/fake-app.js"></script>
|
||||||
|
<script src="../scripts/changes.js"></script>
|
||||||
<script src="../scripts/util.js"></script>
|
<script src="../scripts/util.js"></script>
|
||||||
|
|
||||||
<link rel="import" href="../../bower_components/iron-test-helpers/iron-test-helpers.html">
|
<link rel="import" href="../../bower_components/iron-test-helpers/iron-test-helpers.html">
|
||||||
@@ -33,49 +34,115 @@ limitations under the License.
|
|||||||
</template>
|
</template>
|
||||||
</test-fixture>
|
</test-fixture>
|
||||||
|
|
||||||
|
<test-fixture id="grouped">
|
||||||
|
<template>
|
||||||
|
<gr-change-list></gr-change-list>
|
||||||
|
</template>
|
||||||
|
</test-fixture>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
suite('gr-change-list tests', function() {
|
suite('gr-change-list basic tests', function() {
|
||||||
var changeList;
|
var element;
|
||||||
|
|
||||||
setup(function() {
|
setup(function() {
|
||||||
changeList = fixture('basic');
|
element = fixture('basic');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('keyboard shortcuts', function() {
|
test('keyboard shortcuts', function() {
|
||||||
changeList.changes = [
|
element.changes = [
|
||||||
{_number: 0},
|
{_number: 0},
|
||||||
{_number: 1},
|
{_number: 1},
|
||||||
{_number: 2},
|
{_number: 2},
|
||||||
];
|
];
|
||||||
flushAsynchronousOperations();
|
flushAsynchronousOperations();
|
||||||
var changeListItems = Polymer.dom(changeList.root).querySelectorAll(
|
var elementItems = Polymer.dom(element.root).querySelectorAll(
|
||||||
'gr-change-list-item:not([header])');
|
'gr-change-list-item');
|
||||||
assert.equal(changeListItems.length, 3);
|
assert.equal(elementItems.length, 3);
|
||||||
assert.equal(changeList.selectedIndex, 0);
|
assert.equal(element.selectedIndex, 0);
|
||||||
|
|
||||||
MockInteractions.pressAndReleaseKeyOn(changeList, 74); // 'j'
|
MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
|
||||||
assert.equal(changeList.selectedIndex, 1);
|
assert.equal(element.selectedIndex, 1);
|
||||||
MockInteractions.pressAndReleaseKeyOn(changeList, 74); // 'j'
|
MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
|
||||||
|
|
||||||
var showStub = sinon.stub(page, 'show');
|
var showStub = sinon.stub(page, 'show');
|
||||||
assert.equal(changeList.selectedIndex, 2);
|
assert.equal(element.selectedIndex, 2);
|
||||||
MockInteractions.pressAndReleaseKeyOn(changeList, 13); // 'enter'
|
MockInteractions.pressAndReleaseKeyOn(element, 13); // 'enter'
|
||||||
assert(showStub.lastCall.calledWithExactly('/c/2/'),
|
assert(showStub.lastCall.calledWithExactly('/c/2/'),
|
||||||
'Should navigate to /c/2/');
|
'Should navigate to /c/2/');
|
||||||
|
|
||||||
MockInteractions.pressAndReleaseKeyOn(changeList, 75); // 'k'
|
MockInteractions.pressAndReleaseKeyOn(element, 75); // 'k'
|
||||||
assert.equal(changeList.selectedIndex, 1);
|
assert.equal(element.selectedIndex, 1);
|
||||||
MockInteractions.pressAndReleaseKeyOn(changeList, 13); // 'enter'
|
MockInteractions.pressAndReleaseKeyOn(element, 13); // 'enter'
|
||||||
assert(showStub.lastCall.calledWithExactly('/c/1/'),
|
assert(showStub.lastCall.calledWithExactly('/c/1/'),
|
||||||
'Should navigate to /c/1/');
|
'Should navigate to /c/1/');
|
||||||
|
|
||||||
MockInteractions.pressAndReleaseKeyOn(changeList, 75); // 'k'
|
MockInteractions.pressAndReleaseKeyOn(element, 75); // 'k'
|
||||||
MockInteractions.pressAndReleaseKeyOn(changeList, 75); // 'k'
|
MockInteractions.pressAndReleaseKeyOn(element, 75); // 'k'
|
||||||
MockInteractions.pressAndReleaseKeyOn(changeList, 75); // 'k'
|
MockInteractions.pressAndReleaseKeyOn(element, 75); // 'k'
|
||||||
assert.equal(changeList.selectedIndex, 0);
|
assert.equal(element.selectedIndex, 0);
|
||||||
|
|
||||||
showStub.restore();
|
showStub.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
suite('gr-change-list groups', function() {
|
||||||
|
var element;
|
||||||
|
|
||||||
|
setup(function() {
|
||||||
|
element = fixture('basic');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('keyboard shortcuts', function() {
|
||||||
|
element.groups = [
|
||||||
|
[
|
||||||
|
{_number: 0},
|
||||||
|
{_number: 1},
|
||||||
|
{_number: 2},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{_number: 3},
|
||||||
|
{_number: 4},
|
||||||
|
{_number: 5},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{_number: 6},
|
||||||
|
{_number: 7},
|
||||||
|
{_number: 8},
|
||||||
|
]
|
||||||
|
];
|
||||||
|
element.groupTitles = ['Group 1', 'Group 2', 'Group 3'];
|
||||||
|
flushAsynchronousOperations();
|
||||||
|
var elementItems = Polymer.dom(element.root).querySelectorAll(
|
||||||
|
'gr-change-list-item');
|
||||||
|
assert.equal(elementItems.length, 9);
|
||||||
|
assert.equal(element.selectedIndex, 0);
|
||||||
|
|
||||||
|
MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
|
||||||
|
assert.equal(element.selectedIndex, 1);
|
||||||
|
MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
|
||||||
|
|
||||||
|
var showStub = sinon.stub(page, 'show');
|
||||||
|
assert.equal(element.selectedIndex, 2);
|
||||||
|
MockInteractions.pressAndReleaseKeyOn(element, 13); // 'enter'
|
||||||
|
assert(showStub.lastCall.calledWithExactly('/c/2/'),
|
||||||
|
'Should navigate to /c/2/');
|
||||||
|
|
||||||
|
MockInteractions.pressAndReleaseKeyOn(element, 75); // 'k'
|
||||||
|
assert.equal(element.selectedIndex, 1);
|
||||||
|
MockInteractions.pressAndReleaseKeyOn(element, 13); // 'enter'
|
||||||
|
assert(showStub.lastCall.calledWithExactly('/c/1/'),
|
||||||
|
'Should navigate to /c/1/');
|
||||||
|
|
||||||
|
MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
|
||||||
|
MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
|
||||||
|
MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
|
||||||
|
assert.equal(element.selectedIndex, 4);
|
||||||
|
MockInteractions.pressAndReleaseKeyOn(element, 13); // 'enter'
|
||||||
|
assert(showStub.lastCall.calledWithExactly('/c/4/'),
|
||||||
|
'Should navigate to /c/4/');
|
||||||
|
showStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user