Update file list to use functions from comment API
This also adds an intermediate string formatting object for comment string manipulation tasks that are going to be done in the patch range select and diff file dropdown as well. Change-Id: Idee3debd24c40bcc70a0ac27cf1218394d79b53c
This commit is contained in:
@@ -29,6 +29,7 @@ limitations under the License.
|
||||
<link rel="import" href="../../shared/gr-linked-text/gr-linked-text.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
<link rel="import" href="../../shared/gr-select/gr-select.html">
|
||||
<link rel="import" href="../../shared/gr-count-string-formatter/gr-count-string-formatter.html">
|
||||
<link rel="import" href="../../shared/gr-tooltip-content/gr-tooltip-content.html">
|
||||
<link rel="import" href="../gr-file-list-constants.html">
|
||||
|
||||
@@ -266,17 +267,16 @@ limitations under the License.
|
||||
</span>
|
||||
<div class="comments desktop">
|
||||
<span class="drafts">
|
||||
[[_computeDraftsString(changeComments.drafts, patchRange.patchNum, file.__path)]]
|
||||
[[_computeDraftsString(changeComments, patchRange.patchNum, file.__path)]]
|
||||
</span>
|
||||
[[_computeCommentsString(changeComments.comments, patchRange.patchNum, file.__path)]]
|
||||
[[_computeUnresolvedString(changeComments.comments, changeComments.drafts, patchRange.patchNum, file.__path)]]
|
||||
[[_computeCommentsString(changeComments, patchRange.patchNum, file.__path)]]
|
||||
</div>
|
||||
<div class="comments mobile">
|
||||
<span class="drafts">
|
||||
[[_computeDraftsStringMobile(changeComments.drafts, patchRange.patchNum,
|
||||
[[_computeDraftsStringMobile(changeComments, patchRange.patchNum,
|
||||
file.__path)]]
|
||||
</span>
|
||||
[[_computeCommentsStringMobile(changeComments.comments, patchRange.patchNum,
|
||||
[[_computeCommentsStringMobile(changeComments, patchRange.patchNum,
|
||||
file.__path)]]
|
||||
</div>
|
||||
<div class$="[[_computeClass('stats', file.__path)]]">
|
||||
|
||||
@@ -309,89 +309,67 @@
|
||||
this.$.diffCursor.handleDiffUpdate();
|
||||
},
|
||||
|
||||
_computeCommentsString(comments, patchNum, path) {
|
||||
return this._computeCountString(comments, patchNum, path, 'comment');
|
||||
},
|
||||
|
||||
_computeDraftsString(drafts, patchNum, path) {
|
||||
return this._computeCountString(drafts, patchNum, path, 'draft');
|
||||
},
|
||||
|
||||
_computeDraftsStringMobile(drafts, patchNum, path) {
|
||||
const draftCount = this._computeCountString(drafts, patchNum, path);
|
||||
return draftCount ? draftCount + 'd' : '';
|
||||
},
|
||||
|
||||
_computeCommentsStringMobile(comments, patchNum, path) {
|
||||
const commentCount = this._computeCountString(comments, patchNum, path);
|
||||
return commentCount ? commentCount + 'c' : '';
|
||||
},
|
||||
|
||||
getCommentsForPath(comments, patchNum, path) {
|
||||
return (comments[path] || []).filter(c => {
|
||||
return this.patchNumEquals(c.patch_set, patchNum);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {!Array} comments
|
||||
* @param {number} patchNum
|
||||
* @param {string} path
|
||||
* @param {string=} opt_noun
|
||||
*/
|
||||
_computeCountString(comments, patchNum, path, opt_noun) {
|
||||
if (!comments) { return ''; }
|
||||
|
||||
const patchComments = this.getCommentsForPath(comments, patchNum, path);
|
||||
const num = patchComments.length;
|
||||
if (num === 0) { return ''; }
|
||||
if (!opt_noun) { return num; }
|
||||
const output = num + ' ' + opt_noun + (num > 1 ? 's' : '');
|
||||
return output;
|
||||
},
|
||||
|
||||
/**
|
||||
* Computes a string counting the number of unresolved comment threads in a
|
||||
* given file and path.
|
||||
* Computes a string with the number of comments and unresolved comments.
|
||||
*
|
||||
* @param {!Object} comments
|
||||
* @param {!Object} drafts
|
||||
* @param {!Object} changeComments
|
||||
* @param {number} patchNum
|
||||
* @param {string} path
|
||||
* @return {string}
|
||||
*/
|
||||
_computeUnresolvedString(comments, drafts, patchNum, path) {
|
||||
const unresolvedNum = this.computeUnresolvedNum(
|
||||
comments, drafts, patchNum, path);
|
||||
return unresolvedNum === 0 ? '' : '(' + unresolvedNum + ' unresolved)';
|
||||
_computeCommentsString(changeComments, patchNum, path) {
|
||||
const unresolvedCount = changeComments.computeUnresolvedNum(patchNum,
|
||||
path);
|
||||
const commentCount = changeComments.computeCommentCount(patchNum, path);
|
||||
const commentString = GrCountStringFormatter.computePluralString(
|
||||
commentCount, 'comment');
|
||||
const unresolvedString = GrCountStringFormatter.computeString(
|
||||
unresolvedCount, 'unresolved');
|
||||
|
||||
return commentString +
|
||||
// Add a space if both comments and unresolved
|
||||
(commentString && unresolvedString ? ' ' : '') +
|
||||
// Add parentheses around unresolved if it exists.
|
||||
(unresolvedString ? `(${unresolvedString})` : '');
|
||||
},
|
||||
|
||||
computeUnresolvedNum(comments, drafts, patchNum, path) {
|
||||
comments = this.getCommentsForPath(comments, patchNum, path);
|
||||
drafts = this.getCommentsForPath(drafts, patchNum, path);
|
||||
comments = comments.concat(drafts);
|
||||
/**
|
||||
* Computes a string with the number of drafts.
|
||||
*
|
||||
* @param {!Object} changeComments
|
||||
* @param {number} patchNum
|
||||
* @param {string} path
|
||||
* @return {string}
|
||||
*/
|
||||
_computeDraftsString(changeComments, patchNum, path) {
|
||||
const draftCount = changeComments.computeDraftCount(patchNum, path);
|
||||
return GrCountStringFormatter.computePluralString(draftCount, 'draft');
|
||||
},
|
||||
|
||||
// Create an object where every comment ID is the key of an unresolved
|
||||
// comment.
|
||||
/**
|
||||
* Computes a shortened string with the number of drafts.
|
||||
*
|
||||
* @param {!Object} changeComments
|
||||
* @param {number} patchNum
|
||||
* @param {string} path
|
||||
* @return {string}
|
||||
*/
|
||||
_computeDraftsStringMobile(changeComments, patchNum, path) {
|
||||
const draftCount = changeComments.computeDraftCount(patchNum, path);
|
||||
return GrCountStringFormatter.computeShortString(draftCount, 'd');
|
||||
},
|
||||
|
||||
const idMap = comments.reduce((acc, comment) => {
|
||||
if (comment.unresolved) {
|
||||
acc[comment.id] = true;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// Set false for the comments that are marked as parents.
|
||||
for (const comment of comments) {
|
||||
idMap[comment.in_reply_to] = false;
|
||||
}
|
||||
|
||||
// The unresolved comments are the comments that still have true.
|
||||
const unresolvedLeaves = Object.keys(idMap).filter(key => {
|
||||
return idMap[key];
|
||||
});
|
||||
|
||||
return unresolvedLeaves.length;
|
||||
/**
|
||||
* Computes a shortened string with the number of comments.
|
||||
*
|
||||
* @param {!Object} changeComments
|
||||
* @param {number} patchNum
|
||||
* @param {string} path
|
||||
* @return {string}
|
||||
*/
|
||||
_computeCommentsStringMobile(changeComments, patchNum, path) {
|
||||
const commentCount = changeComments.computeCommentCount(patchNum, path);
|
||||
return GrCountStringFormatter.computeShortString(commentCount, 'c');
|
||||
},
|
||||
|
||||
_computeReviewed(file, _reviewed) {
|
||||
|
||||
@@ -348,6 +348,135 @@ limitations under the License.
|
||||
}
|
||||
});
|
||||
|
||||
test('comment filtering', () => {
|
||||
element.changeComments._comments = {
|
||||
'/COMMIT_MSG': [
|
||||
{patch_set: 1, message: 'Done', updated: '2017-02-08 16:40:49'},
|
||||
{patch_set: 1, message: 'oh hay', updated: '2017-02-09 16:40:49'},
|
||||
{patch_set: 2, message: 'hello', updated: '2017-02-10 16:40:49'},
|
||||
],
|
||||
'myfile.txt': [
|
||||
{patch_set: 1, message: 'good news!', updated: '2017-02-08 16:40:49'},
|
||||
{patch_set: 2, message: 'wat!?', updated: '2017-02-09 16:40:49'},
|
||||
{patch_set: 2, message: 'hi', updated: '2017-02-10 16:40:49'},
|
||||
],
|
||||
'unresolved.file': [
|
||||
{
|
||||
patch_set: 2,
|
||||
message: 'wat!?',
|
||||
updated: '2017-02-09 16:40:49',
|
||||
id: '1',
|
||||
unresolved: true,
|
||||
},
|
||||
{
|
||||
patch_set: 2,
|
||||
message: 'hi',
|
||||
updated: '2017-02-10 16:40:49',
|
||||
id: '2',
|
||||
in_reply_to: '1',
|
||||
unresolved: false,
|
||||
},
|
||||
{
|
||||
patch_set: 2,
|
||||
message: 'good news!',
|
||||
updated: '2017-02-08 16:40:49',
|
||||
id: '3',
|
||||
unresolved: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
element.changeComments._drafts = {
|
||||
'/COMMIT_MSG': [
|
||||
{
|
||||
patch_set: 1,
|
||||
message: 'hi',
|
||||
updated: '2017-02-15 16:40:49',
|
||||
id: '5',
|
||||
unresolved: true,
|
||||
},
|
||||
{
|
||||
patch_set: 1,
|
||||
message: 'fyi',
|
||||
updated: '2017-02-15 16:40:49',
|
||||
id: '6',
|
||||
unresolved: false,
|
||||
},
|
||||
],
|
||||
'unresolved.file': [
|
||||
{
|
||||
patch_set: 1,
|
||||
message: 'hi',
|
||||
updated: '2017-02-11 16:40:49',
|
||||
id: '4',
|
||||
unresolved: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
assert.equal(
|
||||
element._computeCommentsString(element.changeComments, '1',
|
||||
'/COMMIT_MSG', 'comment'), '2 comments (1 unresolved)');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(element.changeComments, '1'
|
||||
, '/COMMIT_MSG'), '2c');
|
||||
assert.equal(
|
||||
element._computeDraftsString(element.changeComments, '1',
|
||||
'unresolved.file'), '1 draft');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(element.changeComments, '1',
|
||||
'unresolved.file'), '1d');
|
||||
assert.equal(
|
||||
element._computeCommentsString(element.changeComments, '1',
|
||||
'myfile.txt', 'comment'), '1 comment');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(element.changeComments, '1',
|
||||
'myfile.txt'), '1c');
|
||||
assert.equal(
|
||||
element._computeDraftsString(element.changeComments, '1',
|
||||
'myfile.txt'), '');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(element.changeComments, '1',
|
||||
'myfile.txt'), '');
|
||||
assert.equal(
|
||||
element._computeCommentsString(element.changeComments, '1',
|
||||
'file_added_in_rev2.txt', 'comment'), '');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(element.changeComments, '1',
|
||||
'file_added_in_rev2.txt'), '');
|
||||
assert.equal(
|
||||
element._computeDraftsString(element.changeComments, '1',
|
||||
'file_added_in_rev2.txt'), '');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(element.changeComments, '1',
|
||||
'file_added_in_rev2.txt'), '');
|
||||
assert.equal(
|
||||
element._computeCommentsString(element.changeComments, '2',
|
||||
'/COMMIT_MSG', 'comment'), '1 comment');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(element.changeComments, '2',
|
||||
'/COMMIT_MSG'), '1c');
|
||||
assert.equal(
|
||||
element._computeDraftsString(element.changeComments, '1',
|
||||
'/COMMIT_MSG'), '2 drafts');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(element.changeComments, '1',
|
||||
'/COMMIT_MSG'), '2d');
|
||||
assert.equal(
|
||||
element._computeCommentsString(element.changeComments, '2',
|
||||
'myfile.txt', 'comment'), '2 comments');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(element.changeComments, '2',
|
||||
'myfile.txt'), '2c');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(element.changeComments, '2',
|
||||
'myfile.txt'), '');
|
||||
assert.equal(
|
||||
element._computeCommentsString(element.changeComments, '2',
|
||||
'file_added_in_rev2.txt', 'comment'), '');
|
||||
assert.equal(element._computeCommentsString(element.changeComments, '2',
|
||||
'unresolved.file', 'comment'), '3 comments (1 unresolved)');
|
||||
});
|
||||
|
||||
suite('keyboard shortcuts', () => {
|
||||
setup(() => {
|
||||
element._files = [
|
||||
@@ -526,119 +655,6 @@ limitations under the License.
|
||||
});
|
||||
});
|
||||
|
||||
test('comment filtering', () => {
|
||||
const comments = {
|
||||
'/COMMIT_MSG': [
|
||||
{patch_set: 1, message: 'Done', updated: '2017-02-08 16:40:49'},
|
||||
{patch_set: 1, message: 'oh hay', updated: '2017-02-09 16:40:49'},
|
||||
{patch_set: 2, message: 'hello', updated: '2017-02-10 16:40:49'},
|
||||
],
|
||||
'myfile.txt': [
|
||||
{patch_set: 1, message: 'good news!', updated: '2017-02-08 16:40:49'},
|
||||
{patch_set: 2, message: 'wat!?', updated: '2017-02-09 16:40:49'},
|
||||
{patch_set: 2, message: 'hi', updated: '2017-02-10 16:40:49'},
|
||||
],
|
||||
'unresolved.file': [
|
||||
{
|
||||
patch_set: 2,
|
||||
message: 'wat!?',
|
||||
updated: '2017-02-09 16:40:49',
|
||||
id: '1',
|
||||
unresolved: true,
|
||||
},
|
||||
{
|
||||
patch_set: 2,
|
||||
message: 'hi',
|
||||
updated: '2017-02-10 16:40:49',
|
||||
id: '2',
|
||||
in_reply_to: '1',
|
||||
unresolved: false,
|
||||
},
|
||||
{
|
||||
patch_set: 2,
|
||||
message: 'good news!',
|
||||
updated: '2017-02-08 16:40:49',
|
||||
id: '3',
|
||||
unresolved: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
const drafts = {
|
||||
'unresolved.file': [
|
||||
{
|
||||
patch_set: 2,
|
||||
message: 'hi',
|
||||
updated: '2017-02-11 16:40:49',
|
||||
id: '4',
|
||||
in_reply_to: '3',
|
||||
unresolved: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
assert.equal(
|
||||
element._computeCountString(comments, '1', '/COMMIT_MSG', 'comment'),
|
||||
'2 comments');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(comments, '1', '/COMMIT_MSG'),
|
||||
'2c');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(comments, '1', '/COMMIT_MSG'),
|
||||
'2d');
|
||||
assert.equal(
|
||||
element._computeCountString(comments, '1', 'myfile.txt', 'comment'),
|
||||
'1 comment');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(comments, '1', 'myfile.txt'),
|
||||
'1c');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(comments, '1', 'myfile.txt'),
|
||||
'1d');
|
||||
assert.equal(
|
||||
element._computeCountString(comments, '1',
|
||||
'file_added_in_rev2.txt', 'comment'), '');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(comments, '1',
|
||||
'file_added_in_rev2.txt'), '');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(comments, '1',
|
||||
'file_added_in_rev2.txt'), '');
|
||||
assert.equal(
|
||||
element._computeCountString(comments, '2', '/COMMIT_MSG', 'comment'),
|
||||
'1 comment');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(comments, '2', '/COMMIT_MSG'),
|
||||
'1c');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(comments, '2', '/COMMIT_MSG'),
|
||||
'1d');
|
||||
assert.equal(
|
||||
element._computeCountString(comments, '2', 'myfile.txt', 'comment'),
|
||||
'2 comments');
|
||||
assert.equal(
|
||||
element._computeCommentsStringMobile(comments, '2', 'myfile.txt'),
|
||||
'2c');
|
||||
assert.equal(
|
||||
element._computeDraftsStringMobile(comments, '2', 'myfile.txt'),
|
||||
'2d');
|
||||
assert.equal(
|
||||
element._computeCountString(comments, '2',
|
||||
'file_added_in_rev2.txt', 'comment'), '');
|
||||
assert.equal(element._computeCountString(comments, '2',
|
||||
'unresolved.file', 'comment'), '3 comments');
|
||||
assert.equal(
|
||||
element._computeUnresolvedString(comments, [], 2, 'myfile.txt'), '');
|
||||
assert.equal(
|
||||
element.computeUnresolvedNum(comments, [], 2, 'myfile.txt'), 0);
|
||||
assert.equal(
|
||||
element._computeUnresolvedString(comments, [], 2, 'unresolved.file'),
|
||||
'(1 unresolved)');
|
||||
assert.equal(
|
||||
element.computeUnresolvedNum(comments, [], 2, 'unresolved.file'), 1);
|
||||
assert.equal(
|
||||
element._computeUnresolvedString(comments, drafts, 2,
|
||||
'unresolved.file'), '');
|
||||
});
|
||||
|
||||
test('computed properties', () => {
|
||||
assert.equal(element._computeFileStatus('A'), 'A');
|
||||
assert.equal(element._computeFileStatus(undefined), 'M');
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<!--
|
||||
Copyright (C) 2017 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.
|
||||
-->
|
||||
<script>
|
||||
(function(window) {
|
||||
'use strict';
|
||||
const GrCountStringFormatter = window.GrCountStringFormatter || {};
|
||||
|
||||
/**
|
||||
* Returns a count plus string that is pluralized when necessary.
|
||||
*
|
||||
* @param {number} count
|
||||
* @param {string} noun
|
||||
* @return {string}
|
||||
*/
|
||||
GrCountStringFormatter.computePluralString = function(count, noun) {
|
||||
return this.computeString(count, noun) + (count > 1 ? 's' : '');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a count plus string that is not pluralized.
|
||||
*
|
||||
* @param {number} count
|
||||
* @param {string} noun
|
||||
* @return {string}
|
||||
*/
|
||||
GrCountStringFormatter.computeString = function(count, noun) {
|
||||
if (count === 0) { return ''; }
|
||||
return count + ' ' + noun;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a count plus arbitrary text.
|
||||
*
|
||||
* @param {number} count
|
||||
* @param {string} text
|
||||
* @return {string}
|
||||
*/
|
||||
GrCountStringFormatter.computeShortString = function(count, text) {
|
||||
if (count === 0) { return ''; }
|
||||
return count + text;
|
||||
};
|
||||
window.GrCountStringFormatter = GrCountStringFormatter;
|
||||
})(window);
|
||||
</script>
|
||||
@@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (C) 2017 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.
|
||||
-->
|
||||
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
|
||||
<title>gr-count-string-formatter</title>
|
||||
|
||||
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
||||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||
<link rel="import" href="../../../test/common-test-setup.html"/>
|
||||
<link rel="import" href="gr-count-string-formatter.html"/>
|
||||
|
||||
<script>
|
||||
suite('gr-count-string-formatter tests', () => {
|
||||
test('computeString', () => {
|
||||
const noun = 'unresolved';
|
||||
assert.equal(GrCountStringFormatter.computeString(0, noun), '');
|
||||
assert.equal(GrCountStringFormatter.computeString(1, noun),
|
||||
'1 unresolved');
|
||||
assert.equal(GrCountStringFormatter.computeString(2, noun),
|
||||
'2 unresolved');
|
||||
});
|
||||
|
||||
test('computeShortString', () => {
|
||||
const noun = 'c';
|
||||
assert.equal(GrCountStringFormatter.computeShortString(0, noun), '');
|
||||
assert.equal(GrCountStringFormatter.computeShortString(1, noun), '1c');
|
||||
assert.equal(GrCountStringFormatter.computeShortString(2, noun), '2c');
|
||||
});
|
||||
|
||||
test('computePluralString', () => {
|
||||
const noun = 'comment';
|
||||
assert.equal(GrCountStringFormatter.computePluralString(0, noun), '');
|
||||
assert.equal(GrCountStringFormatter.computePluralString(1, noun),
|
||||
'1 comment');
|
||||
assert.equal(GrCountStringFormatter.computePluralString(2, noun),
|
||||
'2 comments');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -33,6 +33,7 @@ const EXTERN_NAMES = [
|
||||
'GrRangeNormalizer',
|
||||
'GrReporting',
|
||||
'GrReviewerUpdatesParser',
|
||||
'GrCountStringFormatter',
|
||||
'GrThemeApi',
|
||||
'moment',
|
||||
'page',
|
||||
|
||||
Reference in New Issue
Block a user