blob: ef39e1f67326267b246bd87d4612c4e5fd884757 [file] [log] [blame]
// 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.
(function() {
'use strict';
const PARENT = 'PARENT';
Polymer({
is: 'gr-comment-api',
properties: {
/** @type {number} */
_changeNum: Number,
/** @type {!Object|undefined} */
_comments: Object,
/** @type {!Object|undefined} */
_drafts: Object,
/** @type {!Object|undefined} */
_robotComments: Object,
},
behaviors: [
Gerrit.PatchSetBehavior,
],
/**
* Load all comments (with drafts and robot comments) for the given change
* number. The returned promise resolves when the comments have loaded, but
* does not yield the comment data.
*
* @param {number} changeNum
* @return {!Promise}
*/
loadAll(changeNum) {
this._changeNum = changeNum;
// Reset comment arrays.
this._comments = undefined;
this._drafts = undefined;
this._robotComments = undefined;
const promises = [];
promises.push(this.$.restAPI.getDiffComments(changeNum)
.then(comments => { this._comments = comments; }));
promises.push(this.$.restAPI.getDiffRobotComments(changeNum)
.then(robotComments => { this._robotComments = robotComments; }));
promises.push(this.$.restAPI.getDiffDrafts(changeNum)
.then(drafts => { this._drafts = drafts; }));
return Promise.all(promises);
},
/**
* Get an object mapping file paths to a boolean representing whether that
* path contains diff comments in the given patch set (including drafts and
* robot comments).
*
* Paths with comments are mapped to true, whereas paths without comments
* are not mapped.
*
* @param {!Object} patchRange The patch-range object containing patchNum
* and basePatchNum properties to represent the range.
* @return {Object}
*/
getPaths(patchRange) {
const responses = [this._comments, this._drafts, this._robotComments];
const commentMap = {};
for (const response of responses) {
for (const path in response) {
if (response.hasOwnProperty(path) &&
response[path].some(c => this._isInPatchRange(c, patchRange))) {
commentMap[path] = true;
}
}
}
return commentMap;
},
/**
* Get the comments (with drafts and robot comments) for a path and
* patch-range. Returns an object with left and right properties mapping to
* arrays of comments in on either side of the patch range for that path.
*
* @param {!string} path
* @param {!Object} patchRange The patch-range object containing patchNum
* and basePatchNum properties to represent the range.
* @param {Object=} opt_projectConfig Optional project config object to
* include in the meta sub-object.
* @return {Object}
*/
getCommentsForPath(path, patchRange, opt_projectConfig) {
const comments = this._comments[path] || [];
const drafts = this._drafts[path] || [];
const robotComments = this._robotComments[path] || [];
drafts.forEach(d => { d.__draft = true; });
const all = comments.concat(drafts).concat(robotComments);
const baseComments = all.filter(c =>
this._isInBaseOfPatchRange(c, patchRange));
const revisionComments = all.filter(c =>
this._isInRevisionOfPatchRange(c, patchRange));
return {
meta: {
changeNum: this._changeNum,
path,
patchRange,
projectConfig: opt_projectConfig,
},
left: baseComments,
right: revisionComments,
};
},
/**
* Whether the given comment should be included in the base side of the
* given patch range.
* @param {!Object} comment
* @param {!Object} range
* @return {boolean}
*/
_isInBaseOfPatchRange(comment, range) {
// If the base of the range is the parent of the patch:
if (range.basePatchNum === PARENT &&
comment.side === PARENT &&
this.patchNumEquals(comment.patch_set, range.patchNum)) {
return true;
}
// If the base of the range is not the parent of the patch:
if (range.basePatchNum !== PARENT &&
comment.side !== PARENT &&
this.patchNumEquals(comment.patch_set, range.basePatchNum)) {
return true;
}
return false;
},
/**
* Whether the given comment should be included in the revision side of the
* given patch range.
* @param {!Object} comment
* @param {!Object} range
* @return {boolean}
*/
_isInRevisionOfPatchRange(comment, range) {
return comment.side !== PARENT &&
this.patchNumEquals(comment.patch_set, range.patchNum);
},
/**
* Whether the given comment should be included in the given patch range.
* @param {!Object} comment
* @param {!Object} range
* @return {boolean|undefined}
*/
_isInPatchRange(comment, range) {
return this._isInBaseOfPatchRange(comment, range) ||
this._isInRevisionOfPatchRange(comment, range);
},
});
})();