Merge "Redesign Change Log"
diff --git a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.html b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.html
index a7e65a3..d9786c1 100644
--- a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.html
+++ b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.html
@@ -36,18 +36,15 @@
word-wrap: break-word;
}
.file {
- border-top: 1px solid var(--border-color);
- font-weight: var(--font-weight-bold);
- margin: 10px 0 3px;
- padding: 10px 0 5px;
+ padding: var(--spacing-s) 0;
}
.container {
display: flex;
- margin: var(--spacing-m) 0;
+ padding: var(--spacing-s) 0;
}
.lineNum {
- margin-right: var(--spacing-m);
- min-width: 10em;
+ margin-right: var(--spacing-s);
+ min-width: 135px;
text-align: right;
}
.message {
@@ -66,7 +63,7 @@
}
</style>
<template is="dom-repeat" items="[[_computeFilesFromComments(comments)]]" as="file">
- <div class="file">[[computeDisplayPath(file)]]:</div>
+ <div class="file"><a class="fileLink" href="[[_computeDiffURL(file, changeNum, comments)]]">[[computeDisplayPath(file)]]</a></div>
<template is="dom-repeat"
items="[[_computeCommentsForFile(comments, file)]]" as="comment">
<div class="container">
@@ -74,7 +71,7 @@
href$="[[_computeDiffLineURL(file, changeNum, comment.patch_set, comment)]]">
<span hidden$="[[!comment.line]]">
<span>[[_computePatchDisplayName(comment)]]</span>
- Line <span>[[comment.line]]</span>:
+ Line <span>[[comment.line]]</span>
</span>
<span hidden$="[[comment.line]]">
File comment:
diff --git a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js
index 58bdbbc..16c55cd 100644
--- a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js
+++ b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js
@@ -52,18 +52,29 @@
return comment.side === 'PARENT';
}
- _computeDiffLineURL(file, changeNum, patchNum, comment) {
+ _computeDiffURL(filePath, changeNum, allComments) {
+ if ([filePath, changeNum, allComments].some(arg => arg === undefined)) {
+ return;
+ }
+ const fileComments = this._computeCommentsForFile(allComments, filePath);
+ // This can happen for files that don't exist anymore in the current ps.
+ if (fileComments.length === 0) return;
+ return Gerrit.Nav.getUrlForDiffById(changeNum, this.projectName,
+ filePath, fileComments[0].patch_set);
+ }
+
+ _computeDiffLineURL(filePath, changeNum, patchNum, comment) {
const basePatchNum = comment.hasOwnProperty('parent') ?
-comment.parent : null;
- return Gerrit.Nav.getUrlForDiffById(this.changeNum, this.projectName,
- file, patchNum, basePatchNum, comment.line,
+ return Gerrit.Nav.getUrlForDiffById(changeNum, this.projectName,
+ filePath, patchNum, basePatchNum, comment.line,
this._isOnParent(comment));
}
- _computeCommentsForFile(comments, file) {
+ _computeCommentsForFile(comments, filePath) {
// Changes are not picked up by the dom-repeat due to the array instance
// identity not changing even when it has elements added/removed from it.
- return (comments[file] || []).slice();
+ return (comments[filePath] || []).slice();
}
_computePatchDisplayName(comment) {
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.html b/polygerrit-ui/app/elements/change/gr-message/gr-message.html
index fbd5d68d..5dbc1b8 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.html
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.html
@@ -45,44 +45,19 @@
:host(.expanded) {
cursor: auto;
}
- :host > div {
- padding: 0 var(--spacing-l);
- }
- gr-avatar {
- position: absolute;
- left: var(--spacing-l);
- }
.collapsed .contentContainer {
- align-items: baseline;
+ align-items: center;
color: var(--deemphasized-text-color);
display: flex;
white-space: nowrap;
}
.contentContainer {
- margin-left: calc(var(--spacing-l) + 2.5em);
- padding: var(--spacing-m) 0;
+ padding: var(--spacing-m) var(--spacing-l);
}
- .showAvatar.collapsed .contentContainer {
- margin-left: calc(var(--spacing-l) + 1.75em);
- }
- .hideAvatar.collapsed .contentContainer,
- .hideAvatar.expanded .contentContainer {
- margin-left: 0;
- }
- .showAvatar.collapsed .contentContainer,
- .hideAvatar.collapsed .contentContainer,
- .hideAvatar.expanded .contentContainer {
- padding: var(--spacing-m) 0;
- }
- .collapsed gr-avatar {
- top: var(--spacing-m);
- height: var(--line-height-normal);
- width: var(--line-height-normal);
- }
- .expanded gr-avatar {
- top: var(--spacing-l);
- height: var(--line-height-h1);
- width: var(--line-height-h1);
+ .collapsed .contentContainer {
+ /* For expanded state we inherit the alternating background color
+ that is set in gr-messages-list. */
+ background-color: var(--background-color-primary);
}
.name {
font-weight: var(--font-weight-bold);
@@ -129,15 +104,26 @@
color: var(--primary-text-color);
margin-right: var(--spacing-s);
}
+ .authorLabel {
+ min-width: 160px;
+ display: inline-block;
+ }
.expanded .author {
cursor: pointer;
margin-bottom: var(--spacing-s);
}
+ .expanded .content {
+ padding-left: 40px;
+ }
.dateContainer {
position: absolute;
right: var(--spacing-l);
top: 10px;
}
+ .dateContainer .patchset {
+ margin-right: var(--spacing-m);
+ color: var(--deemphasized-text-color);
+ }
span.date {
color: var(--deemphasized-text-color);
}
@@ -148,16 +134,23 @@
cursor: pointer;
vertical-align: top;
}
- .replyContainer {
- padding: var(--spacing-m) 0 0 0;
- }
.score {
- border: 1px solid rgba(0,0,0,.12);
border-radius: var(--border-radius);
color: var(--primary-text-color);
display: inline-block;
- margin: -1px 0;
- padding: 0 var(--spacing-xxs);
+ padding: 0 var(--spacing-s);
+ text-align: center;
+ }
+ .score,
+ .commentsSummary {
+ margin-right: var(--spacing-s);
+ min-width: 115px;
+ }
+ .expanded .commentsSummary {
+ display: none;
+ }
+ .commentsIcon {
+ vertical-align: top;
}
.score.negative {
background-color: var(--vote-color-disliked);
@@ -177,34 +170,39 @@
};
}
</style>
- <div class$="[[_computeClass(_expanded, showAvatar, message)]]">
- <gr-avatar account="[[author]]" image-size="100"></gr-avatar>
+ <div class$="[[_computeClass(_expanded)]]">
<div class="contentContainer">
<div class="author" on-click="_handleAuthorClick">
<span hidden$="[[!showOnBehalfOf]]">
<span class="name">[[message.real_author.name]]</span>
on behalf of
</span>
- <gr-account-label
- account="[[author]]"
- hide-avatar></gr-account-label>
+ <gr-account-label account="[[author]]" class="authorLabel"></gr-account-label>
<template is="dom-repeat" items="[[_getScores(message)]]" as="score">
<span class$="score [[_computeScoreClass(score, labelExtremes)]]">
[[score.label]] [[score.value]]
</span>
</template>
</div>
+ <template is="dom-if" if="[[_commentCountText]]">
+ <div class="commentsSummary">
+ <iron-icon icon="gr-icons:comment" class="commentsIcon"></iron-icon>
+ <span class="numberOfComments">[[_commentCountText]]</span>
+ </div>
+ </template>
<template is="dom-if" if="[[message.message]]">
<div class="content">
- <div class="message hideOnOpen">[[message.message]]</div>
+ <div class="message hideOnOpen">[[_messageContentCollapsed]]</div>
<gr-formatted-text
no-trailing-margin
class="message hideOnCollapsed"
- content="[[message.message]]"
+ content="[[_messageContentExpanded]]"
config="[[_projectConfig.commentlinks]]"></gr-formatted-text>
- <div class="replyContainer" hidden$="[[!showReplyButton]]" hidden>
- <gr-button link small on-click="_handleReplyTap">Reply</gr-button>
- </div>
+ <template is="dom-if" if="[[!_isMessageContentEmpty(message.message)]]">
+ <div class="replyContainer" hidden$="[[!showReplyButton]]" hidden>
+ <gr-button link small on-click="_handleReplyTap">Reply</gr-button>
+ </div>
+ </template>
<gr-comment-list
comments="[[comments]]"
change-num="[[changeNum]]"
@@ -228,6 +226,9 @@
</div>
</template>
<span class="dateContainer">
+ <template is="dom-if" if="[[message._revision_number]]">
+ <span class="patchset">Patchset [[message._revision_number]]</span>
+ </template>
<template is="dom-if" if="[[!message.id]]">
<span class="date">
<gr-date-formatter
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.js b/polygerrit-ui/app/elements/change/gr-message/gr-message.js
index 59f12f5..95109bb 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.js
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.js
@@ -69,10 +69,6 @@
type: Boolean,
computed: '_computeIsAutomated(message)',
},
- showAvatar: {
- type: Boolean,
- computed: '_computeShowAvatar(author, config)',
- },
showOnBehalfOf: {
type: Boolean,
computed: '_computeShowOnBehalfOf(message)',
@@ -101,6 +97,18 @@
type: Object,
computed: '_computeExpanded(message.expanded)',
},
+ _messageContentExpanded: {
+ type: String,
+ computed: '_computeMessageContentExpanded(message.message)',
+ },
+ _messageContentCollapsed: {
+ type: String,
+ computed: '_computeMessageContentCollapsed(message.message)',
+ },
+ _commentCountText: {
+ type: Number,
+ computed: '_computeCommentCountText(comments)',
+ },
_loggedIn: {
type: Boolean,
value: false,
@@ -140,12 +148,51 @@
}
}
- _computeAuthor(message) {
- return message.author || message.updated_by;
+ _computeCommentCountText(comments) {
+ if (!comments) return undefined;
+ let count = 0;
+ for (const file in comments) {
+ if (comments.hasOwnProperty(file)) {
+ const commentArray = comments[file] || [];
+ count += commentArray.length;
+ }
+ }
+ if (count === 0) {
+ return undefined;
+ } else if (count === 1) {
+ return '1 comment';
+ } else {
+ return `${count} comments`;
+ }
}
- _computeShowAvatar(author, config) {
- return !!(author && config && config.plugin && config.plugin.has_avatars);
+ _computeMessageContentExpanded(content) {
+ return this._computeMessageContent(content, true);
+ }
+
+ _computeMessageContentCollapsed(content) {
+ return this._computeMessageContent(content, false);
+ }
+
+ _computeMessageContent(content, isExpanded) {
+ if (!content) return '';
+ const lines = content.split('\n');
+ const filteredLines = lines.filter(line => {
+ if (!isExpanded && line.startsWith('>')) return false;
+ if (line.startsWith('Patch Set ')) return false;
+ if (line.startsWith('(') && line.endsWith(' comment)')) return false;
+ if (line.startsWith('(') && line.endsWith(' comments)')) return false;
+ return true;
+ });
+ return filteredLines.join('\n').trim();
+ }
+
+ _isMessageContentEmpty(content) {
+ return this._computeMessageContent(content).trim().length === 0;
+ }
+
+ _computeAuthor(message) {
+ return message.author || message.updated_by;
}
_computeShowOnBehalfOf(message) {
@@ -236,10 +283,9 @@
return classes.join(' ');
}
- _computeClass(expanded, showAvatar, message) {
+ _computeClass(expanded) {
const classes = [];
classes.push(expanded ? 'expanded' : 'collapsed');
- classes.push(showAvatar ? 'showAvatar' : 'hideAvatar');
return classes.join(' ');
}
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html
index d71beb4..8d76510 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html
@@ -64,6 +64,12 @@
align-items: center;
display: flex;
}
+ gr-message:nth-child(2n) {
+ background-color: var(--background-color-secondary);
+ }
+ gr-message:nth-child(2n+1) {
+ background-color: var(--background-color-tertiary);
+ }
</style>
<div class="header">
<span
diff --git a/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html b/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html
index 5ecae00..75ab77a 100644
--- a/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html
+++ b/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html
@@ -54,6 +54,8 @@
<g id="info"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"></path></g>
<!-- This SVG is a copy from material.io https://material.io/icons/#ic_hourglass_full-->
<g id="hourglass"><path d="M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6z"/><path d="M0 0h24v24H0V0z" fill="none"/></g>
+ <!-- This SVG is a copy from material.io https://material.io/icons/#mode_comment-->
+ <g id="comment"><path d="M21.99 4c0-1.1-.89-2-1.99-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4-.01-18z"/><path d="M0 0h24v24H0z" fill="none"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="error"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"></path></g>
<!-- This is a custom PolyGerrit SVG -->
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser.js
index 1c62ca3..d599563 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser.js
@@ -147,15 +147,16 @@
*/
GrReviewerUpdatesParser.prototype._getUpdateMessage = function(prev, state) {
if (prev === 'REMOVED' || !prev) {
- return 'added to ' + state + ': ';
+ return 'Added to ' + state.toLowerCase() + ': ';
} else if (state === 'REMOVED') {
if (prev) {
- return 'removed from ' + prev + ': ';
+ return 'Removed from ' + prev.toLowerCase() + ': ';
} else {
- return 'removed : ';
+ return 'Removed : ';
}
} else {
- return 'moved from ' + prev + ' to ' + state + ': ';
+ return 'Moved from ' + prev.toLowerCase() + ' to ' + state.toLowerCase() +
+ ': ';
}
};
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.html
index 818bfa9..593fcec 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.html
@@ -239,15 +239,15 @@
assert.equal(change.reviewer_updates[1].updates.length, 3);
let items = change.reviewer_updates[0].updates;
- assert.equal(items[0].message, 'added to CC: ');
+ assert.equal(items[0].message, 'Added to cc: ');
assert.deepEqual(items[0].reviewers, [reviewer1, reviewer2]);
items = change.reviewer_updates[1].updates;
- assert.equal(items[0].message, 'moved from CC to REVIEWER: ');
+ assert.equal(items[0].message, 'Moved from cc to reviewer: ');
assert.deepEqual(items[0].reviewers, [reviewer1]);
- assert.equal(items[1].message, 'removed from REVIEWER: ');
+ assert.equal(items[1].message, 'Removed from reviewer: ');
assert.deepEqual(items[1].reviewers, [reviewer1]);
- assert.equal(items[2].message, 'added to REVIEWER: ');
+ assert.equal(items[2].message, 'Added to reviewer: ');
assert.deepEqual(items[2].reviewers, [reviewer1, reviewer2]);
});